Coding style cleanup
[platform/kernel/u-boot.git] / board / cm1_qp1 / fwupdate.c
1 /*
2  * (C) Copyright 2007 Schindler Lift Inc.
3  * (C) Copyright 2007 Semihalf
4  *
5  * Author: Michel Marti <mma@objectxp.com>
6  * Adapted for U-Boot 1.2 by Piotr Kruszynski <ppk@semihalf.com>:
7  * - code clean-up
8  * - bugfix for overwriting bootargs by user
9  *
10  * See file CREDITS for list of people who contributed to this
11  * project.
12  *
13  * This program is free software; you can redistribute it and/or
14  * modify it under the terms of the GNU General Public License as
15  * published by the Free Software Foundation; either version 2 of
16  * the License, or (at your option) any later version.
17  *
18  * This program is distributed in the hope that it will be useful,
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21  * GNU General Public License for more details.
22  *
23  * You should have received a copy of the GNU General Public License
24  * along with this program; if not, write to the Free Software
25  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
26  * MA 02111-1307 USA
27  */
28
29 #include <common.h>
30 #include <command.h>
31 #include <malloc.h>
32 #include <image.h>
33 #include <usb.h>
34 #include <fat.h>
35
36 #include "fwupdate.h"
37
38 extern int do_bootm(cmd_tbl_t *, int, int, char *[]);
39 extern long do_fat_read(const char *, void *, unsigned long, int);
40 extern int do_fat_fsload(cmd_tbl_t *, int, int, char *[]);
41
42 static int load_rescue_image(ulong);
43
44 void cm1_fwupdate(void)
45 {
46         cmd_tbl_t *bcmd;
47         char *rsargs;
48         char *tmp = NULL;
49         char ka[16];
50         char *argv[3] = { "bootm", ka, NULL };
51
52         /* Check if rescue system is disabled... */
53         if (getenv("norescue")) {
54                 printf(LOG_PREFIX "Rescue System disabled.\n");
55                 return;
56         }
57
58         /* Check if we have a USB storage device and load image */
59         if (load_rescue_image(LOAD_ADDR))
60                 return;
61
62         bcmd = find_cmd("bootm");
63         if (!bcmd)
64                 return;
65
66         sprintf(ka, "%lx", LOAD_ADDR);
67
68         /* prepare our bootargs */
69         rsargs = getenv("rs-args");
70         if (!rsargs)
71                 rsargs = RS_BOOTARGS;
72         else {
73                 tmp = malloc(strlen(rsargs+1));
74                 if (!tmp) {
75                         printf(LOG_PREFIX "Memory allocation failed\n");
76                         return;
77                 }
78                 strcpy(tmp, rsargs);
79                 rsargs = tmp;
80         }
81
82         setenv("bootargs", rsargs);
83
84         if (rsargs == tmp)
85                 free(rsargs);
86
87         printf(LOG_PREFIX "Starting update system (bootargs=%s)...\n", rsargs);
88         do_bootm(bcmd, 0, 2, argv);
89 }
90
91 static int load_rescue_image(ulong addr)
92 {
93         disk_partition_t info;
94         int devno;
95         int partno;
96         int i;
97         char fwdir[64];
98         char nxri[128];
99         char *tmp;
100         char dev[7];
101         char addr_str[16];
102         char *argv[6] = { "fatload", "usb", dev, addr_str, nxri, NULL };
103         block_dev_desc_t *stor_dev = NULL;
104         cmd_tbl_t *bcmd;
105
106         /* Get name of firmware directory */
107         tmp = getenv("fw-dir");
108
109         /* Copy it into fwdir */
110         strncpy(fwdir, tmp ? tmp : FW_DIR, sizeof(fwdir));
111         fwdir[sizeof(fwdir) - 1] = 0; /* Terminate string */
112
113         printf(LOG_PREFIX "Checking for firmware image directory '%s' on USB"
114                 " storage...\n", fwdir);
115         usb_stop();
116         if (usb_init() != 0)
117                 return 1;
118
119         /* Check for storage device */
120         if (usb_stor_scan(1) != 0) {
121                 usb_stop();
122                 return 1;
123         }
124
125         /* Detect storage device */
126         for (devno = 0; devno < USB_MAX_STOR_DEV; devno++) {
127                 stor_dev = usb_stor_get_dev(devno);
128                 if (stor_dev->type != DEV_TYPE_UNKNOWN)
129                         break;
130         }
131         if (!stor_dev || stor_dev->type == DEV_TYPE_UNKNOWN) {
132                 printf(LOG_PREFIX "No valid storage device found...\n");
133                 usb_stop();
134                 return 1;
135         }
136
137         /* Detect partition */
138         for (partno = -1, i = 0; i < 6; i++) {
139                 if (get_partition_info(stor_dev, i, &info) == 0) {
140                         if (fat_register_device(stor_dev, i) == 0) {
141                                 /* Check if rescue image is present */
142                                 FW_DEBUG("Looking for firmware directory '%s'"
143                                         " on partition %d\n", fwdir, i);
144                                 if (do_fat_read(fwdir, NULL, 0, LS_NO) == -1) {
145                                         FW_DEBUG("No NX rescue image on "
146                                                 "partition %d.\n", i);
147                                 } else {
148                                         partno = i;
149                                         FW_DEBUG("Partition %d contains "
150                                                 "firmware directory\n", partno);
151                                         break;
152                                 }
153                         }
154                 }
155         }
156
157         if (partno == -1) {
158                 printf(LOG_PREFIX "Error: No valid (FAT) partition detected\n");
159                 usb_stop();
160                 return 1;
161         }
162
163         /* Load the rescue image */
164         bcmd = find_cmd("fatload");
165         if (!bcmd) {
166                 printf(LOG_PREFIX "Error - 'fatload' command not present.\n");
167                 usb_stop();
168                 return 1;
169         }
170
171         tmp = getenv("nx-rescue-image");
172         sprintf(nxri, "%s/%s", fwdir, tmp ? tmp : RESCUE_IMAGE);
173         sprintf(dev, "%d:%d", devno, partno);
174         sprintf(addr_str, "%lx", addr);
175
176         FW_DEBUG("fat_fsload device='%s', addr='%s', file: %s\n",
177                 dev, addr_str, nxri);
178
179         if (do_fat_fsload(bcmd, 0, 5, argv) != 0) {
180                 usb_stop();
181                 return 1;
182         }
183
184         /* Stop USB */
185         usb_stop();
186         return 0;
187 }