+ ofs = parts[part_id]->offset;
+#ifdef CONFIG_RECOVERY
+ {
+ /* block is fixed:
+ 1m = ipl(16k)+recovery(240k)+bootloader(768k)*/
+ u32 *buf = (long *)down_ram_addr;
+ u32 ofst;
+ u32 bootloader_edge = parts[part_id]->size;
+ u32 bootloader_addr = bootloader_edge >> 2;
+ u32 recovery_edge = bootloader_addr;
+ u32 recovery_addr = recovery_edge >> 4;
+ u32 ipl_edge = recovery_addr;
+ u32 ipl_addr = 0;
+ int ret, retlen;
+
+ if (len > bootloader_addr) {
+ ofst = bootloader_addr/sizeof(buf);
+ if (*(buf + ofst) == 0xea000012) {
+ /* case: ipl + recovery + bootloader */
+ printf("target: ipl + recovery + loader\n");
+ ofs = ipl_addr;
+ } else {
+ /* case: unknown format */
+ printf("target: unknown\n");
+ *((ulong *) usbd->tx_data) = STATUS_ERROR;
+ usbd->send_data(usbd->tx_data, usbd->tx_len);
+ return 0;
+ }
+ } else {
+ ofst = recovery_addr/sizeof(buf);
+ if (*(buf + ofst) == 0xea000012 &&
+ *(buf + ofst - 1) == 0x00000000) {
+ /* case: ipl + bootloader (old type) */
+ printf("target: ipl + bootloader\n");
+ ofs = ipl_addr;
+ } else {
+ /* case: bootloader only */
+ printf("target: bootloader\n");
+ ofs = bootloader_addr;
+
+ /* skip revision check */
+ down_mode = MODE_FORCE;
+ }
+ }
+
+ sprintf(offset, "%x", ofs);
+ sprintf(length, "%x", parts[part_id]->size);
+
+ /* check block is locked/locked-tight */
+ ret = nand_cmd(3, offset, length, NULL);
+ if (ret) {
+ printf("target is locked%s\n",
+ (ret == 1) ? "-tight" : "");
+ printf("-> try at recovery mode \
+ to update 'system'.\n");
+ printf(" how-to: reset \
+ while pressing volume up and down.\n");
+ *((ulong *) usbd->tx_data) = STATUS_ERROR;
+ usbd->send_data(usbd->tx_data, usbd->tx_len);
+ return 0;
+ }
+ }
+#endif