fwupdate.c 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199
  1. /*
  2. * (C) Copyright 2007 Schindler Lift Inc.
  3. * (C) Copyright 2007 DENX Software Engineering
  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. #include <common.h>
  29. #include <command.h>
  30. #include <malloc.h>
  31. #include <image.h>
  32. #include <usb.h>
  33. #include <fat.h>
  34. #include "fwupdate.h"
  35. extern long do_fat_read(const char *, void *, unsigned long, int);
  36. extern int do_fat_fsload(cmd_tbl_t *, int, int, char * const []);
  37. static int load_rescue_image(ulong);
  38. void cm5200_fwupdate(void)
  39. {
  40. cmd_tbl_t *bcmd;
  41. char *rsargs;
  42. char *tmp = NULL;
  43. char ka[16];
  44. char * const argv[3] = { "bootm", ka, NULL };
  45. /* Check if rescue system is disabled... */
  46. if (getenv("norescue")) {
  47. printf(LOG_PREFIX "Rescue System disabled.\n");
  48. return;
  49. }
  50. /* Check if we have a USB storage device and load image */
  51. if (load_rescue_image(LOAD_ADDR))
  52. return;
  53. bcmd = find_cmd("bootm");
  54. if (!bcmd)
  55. return;
  56. sprintf(ka, "%lx", (ulong)LOAD_ADDR);
  57. /* prepare our bootargs */
  58. rsargs = getenv("rs-args");
  59. if (!rsargs)
  60. rsargs = RS_BOOTARGS;
  61. else {
  62. tmp = malloc(strlen(rsargs+1));
  63. if (!tmp) {
  64. printf(LOG_PREFIX "Memory allocation failed\n");
  65. return;
  66. }
  67. strcpy(tmp, rsargs);
  68. rsargs = tmp;
  69. }
  70. setenv("bootargs", rsargs);
  71. if (rsargs == tmp)
  72. free(rsargs);
  73. printf(LOG_PREFIX "Starting update system (bootargs=%s)...\n", rsargs);
  74. do_bootm(bcmd, 0, 2, argv);
  75. }
  76. static int load_rescue_image(ulong addr)
  77. {
  78. disk_partition_t info;
  79. int devno;
  80. int partno;
  81. int i;
  82. char fwdir[64];
  83. char nxri[128];
  84. char *tmp;
  85. char dev[7];
  86. char addr_str[16];
  87. char * const argv[6] = { "fatload", "usb", dev, addr_str, nxri, NULL };
  88. block_dev_desc_t *stor_dev = NULL;
  89. cmd_tbl_t *bcmd;
  90. /* Get name of firmware directory */
  91. tmp = getenv("fw-dir");
  92. /* Copy it into fwdir */
  93. strncpy(fwdir, tmp ? tmp : FW_DIR, sizeof(fwdir));
  94. fwdir[sizeof(fwdir) - 1] = 0; /* Terminate string */
  95. printf(LOG_PREFIX "Checking for firmware image directory '%s' on USB"
  96. " storage...\n", fwdir);
  97. usb_stop();
  98. if (usb_init() != 0)
  99. return 1;
  100. /* Check for storage device */
  101. if (usb_stor_scan(1) != 0) {
  102. usb_stop();
  103. return 1;
  104. }
  105. /* Detect storage device */
  106. for (devno = 0; devno < USB_MAX_STOR_DEV; devno++) {
  107. stor_dev = usb_stor_get_dev(devno);
  108. if (stor_dev->type != DEV_TYPE_UNKNOWN)
  109. break;
  110. }
  111. if (!stor_dev || stor_dev->type == DEV_TYPE_UNKNOWN) {
  112. printf(LOG_PREFIX "No valid storage device found...\n");
  113. usb_stop();
  114. return 1;
  115. }
  116. /* Detect partition */
  117. for (partno = -1, i = 0; i < 6; i++) {
  118. if (get_partition_info(stor_dev, i, &info) == 0) {
  119. if (fat_register_device(stor_dev, i) == 0) {
  120. /* Check if rescue image is present */
  121. FW_DEBUG("Looking for firmware directory '%s'"
  122. " on partition %d\n", fwdir, i);
  123. if (do_fat_read(fwdir, NULL, 0, LS_NO) == -1) {
  124. FW_DEBUG("No NX rescue image on "
  125. "partition %d.\n", i);
  126. partno = -2;
  127. } else {
  128. partno = i;
  129. FW_DEBUG("Partition %d contains "
  130. "firmware directory\n", partno);
  131. break;
  132. }
  133. }
  134. }
  135. }
  136. if (partno < 0) {
  137. switch (partno) {
  138. case -1:
  139. printf(LOG_PREFIX "Error: No valid (FAT) partition "
  140. "detected\n");
  141. break;
  142. case -2:
  143. printf(LOG_PREFIX "Error: No NX rescue image on FAT "
  144. "partition\n");
  145. break;
  146. default:
  147. printf(LOG_PREFIX "Error: Failed with code %d\n",
  148. partno);
  149. }
  150. usb_stop();
  151. return 1;
  152. }
  153. /* Load the rescue image */
  154. bcmd = find_cmd("fatload");
  155. if (!bcmd) {
  156. printf(LOG_PREFIX "Error - 'fatload' command not present.\n");
  157. usb_stop();
  158. return 1;
  159. }
  160. tmp = getenv("nx-rescue-image");
  161. sprintf(nxri, "%s/%s", fwdir, tmp ? tmp : RESCUE_IMAGE);
  162. sprintf(dev, "%d:%d", devno, partno);
  163. sprintf(addr_str, "%lx", addr);
  164. FW_DEBUG("fat_fsload device='%s', addr='%s', file: %s\n",
  165. dev, addr_str, nxri);
  166. if (do_fat_fsload(bcmd, 0, 5, argv) != 0) {
  167. usb_stop();
  168. return 1;
  169. }
  170. /* Stop USB */
  171. usb_stop();
  172. return 0;
  173. }