diff --git a/bootloader/common.c b/bootloader/common.c index 67b5816694..362c3b4d11 100644 --- a/bootloader/common.c +++ b/bootloader/common.c @@ -118,7 +118,7 @@ char *strerror(int error) } } -void error(int errortype, int error) +void error(int errortype, int error, bool shutdown) { switch(errortype) { @@ -137,7 +137,8 @@ void error(int errortype, int error) lcd_update(); sleep(5*HZ); - power_off(); + if(shutdown) + power_off(); } /* Load firmware image in a format created by tools/scramble */ diff --git a/bootloader/common.h b/bootloader/common.h index 2cdf5865b2..6713585ad8 100644 --- a/bootloader/common.h +++ b/bootloader/common.h @@ -43,7 +43,7 @@ extern bool verbose; void reset_screen(void); void printf(const char *format, ...); char *strerror(int error); -void error(int errortype, int error); +void error(int errortype, int error, bool shutdown); int load_firmware(unsigned char* buf, char* firmware, int buffer_size); int load_raw_firmware(unsigned char* buf, char* firmware, int buffer_size); #ifdef ROCKBOX_HAS_LOGF diff --git a/bootloader/creativezvm.c b/bootloader/creativezvm.c index 73968c3b3f..7dcbac7dcc 100644 --- a/bootloader/creativezvm.c +++ b/bootloader/creativezvm.c @@ -96,7 +96,7 @@ void main(void) ret = disk_mount_all(); if (ret <= 0) - error(EDISK, ret); + error(EDISK, ret, true); printf("Loading Rockbox firmware..."); @@ -105,7 +105,7 @@ void main(void) ret = load_firmware(loadbuffer, BOOTFILE, buffer_size); if(ret < 0) - error(EBOOTFILE, ret); + error(EBOOTFILE, ret, true); else if(ret == EOK) { diff --git a/bootloader/gigabeat-s.c b/bootloader/gigabeat-s.c index dcff26c4de..b6db9e633f 100644 --- a/bootloader/gigabeat-s.c +++ b/bootloader/gigabeat-s.c @@ -302,7 +302,7 @@ static void __attribute__((noreturn)) handle_firmware_load(void) load_buf_size); if(rc < 0) - error(EBOOTFILE, rc); + error(EBOOTFILE, rc, true); /* Pause to look at messages */ pause_if_button_pressed(false); @@ -359,7 +359,7 @@ void main(void) if(rc) { reset_screen(); - error(EATA, rc); + error(EATA, rc, true); } disk_init(); @@ -367,7 +367,7 @@ void main(void) rc = disk_mount_all(); if (rc<=0) { - error(EDISK,rc); + error(EDISK, rc, true); } printf("Init complete"); diff --git a/bootloader/gigabeat.c b/bootloader/gigabeat.c index 7a634b329c..cfba4bb38d 100644 --- a/bootloader/gigabeat.c +++ b/bootloader/gigabeat.c @@ -181,7 +181,7 @@ void main(void) if(rc) { reset_screen(); - error(EATA, rc); + error(EATA, rc, true); } disk_init(); @@ -189,7 +189,7 @@ void main(void) rc = disk_mount_all(); if (rc<=0) { - error(EDISK,rc); + error(EDISK, rc, true); } printf("Loading firmware"); @@ -202,7 +202,7 @@ void main(void) rc = load_firmware(loadbuffer, BOOTFILE, buffer_size); if(rc < 0) - error(EBOOTFILE, rc); + error(EBOOTFILE, rc, true); storage_close(); system_prepare_fw_start(); diff --git a/bootloader/main-e200r-installer.c b/bootloader/main-e200r-installer.c index defdea4574..178a03b42e 100644 --- a/bootloader/main-e200r-installer.c +++ b/bootloader/main-e200r-installer.c @@ -124,7 +124,7 @@ void* main(void) if (num_partitions<=0) { - error(EDISK,num_partitions); + error(EDISK, num_partitions, true); } pinfo = disk_partinfo(1); diff --git a/bootloader/main-pp.c b/bootloader/main-pp.c index 37f42eda43..f0e9e7cdf3 100644 --- a/bootloader/main-pp.c +++ b/bootloader/main-pp.c @@ -540,7 +540,7 @@ void* main(void) } printf(buf); } else { - error(EATA, i); + error(EATA, i, true); } #endif @@ -548,7 +548,7 @@ void* main(void) num_partitions = disk_mount_all(); if (num_partitions<=0) { - error(EDISK,num_partitions); + error(EDISK,num_partitions, true); } /* Just list the first 2 partitions since we don't have any devices yet @@ -643,7 +643,7 @@ void* main(void) return (void*)loadbuffer; } - error(0, 0); + error(0, 0, true); } return (void*)loadbuffer; } diff --git a/bootloader/mini2440.c b/bootloader/mini2440.c index f4441c3730..23f135cb1a 100644 --- a/bootloader/mini2440.c +++ b/bootloader/mini2440.c @@ -85,14 +85,14 @@ int main(void) if(rc) { reset_screen(); - error(EATA, rc); + error(EATA, rc, true); } disk_init(IF_MD(0)); rc = disk_mount_all(); if (rc<=0) { - error(EDISK,rc); + error(EDISK,rc, true); } printf("Loading firmware"); @@ -105,7 +105,7 @@ int main(void) rc = load_firmware(loadbuffer, BOOTFILE, buffer_size); if(rc < 0) - error(EBOOTFILE, rc); + error(EBOOTFILE, rc, true); printf("Loaded firmware %d\n", rc); diff --git a/bootloader/mrobe500.c b/bootloader/mrobe500.c index d6ca58e009..39e898b4c0 100644 --- a/bootloader/mrobe500.c +++ b/bootloader/mrobe500.c @@ -119,7 +119,7 @@ void main(void) if(rc) { reset_screen(); - error(EATA, rc); + error(EATA, rc, true); } printf("disk"); @@ -129,7 +129,7 @@ void main(void) rc = disk_mount_all(); if (rc<=0) { - error(EDISK,rc); + error(EDISK,rc, true); } printf("Loading firmware"); @@ -139,7 +139,7 @@ void main(void) rc = load_firmware(loadbuffer, BOOTFILE, buffer_size); if(rc < 0) - error(EBOOTFILE, rc); + error(EBOOTFILE, rc, true); if (rc == EOK) { diff --git a/bootloader/ondavx747.c b/bootloader/ondavx747.c index 4dfc78d58c..2903b04252 100644 --- a/bootloader/ondavx747.c +++ b/bootloader/ondavx747.c @@ -94,7 +94,7 @@ static int boot_of(void) printf("Mounting disk..."); rc = disk_mount_all(); if (rc <= 0) - error(EDISK,rc); + error(EDISK, rc, true); /* TODO: get this from the NAND flash instead of SD */ fd = open("/ccpmp.bin", O_RDONLY); @@ -147,7 +147,7 @@ static int boot_rockbox(void) printf("Mounting disk..."); rc = disk_mount_all(); if (rc <= 0) - error(EDISK,rc); + error(EDISK,rc, true); printf("Loading firmware..."); rc = load_firmware((unsigned char *)CONFIG_SDRAM_START, BOOTFILE, 0x400000); @@ -172,7 +172,7 @@ static void reset_configuration(void) rc = disk_mount_all(); if (rc <= 0) - error(EDISK,rc); + error(EDISK,rc, true); if(rename(ROCKBOX_DIR "/config.cfg", ROCKBOX_DIR "/config.old") == 0) show_splash(HZ/2, "Configuration reset successfully!"); @@ -271,7 +271,7 @@ int main(void) rc = storage_init(); if(rc) - error(EATA, rc); + error(EATA, rc, true); /* Don't mount the disks yet, there could be file system/partition errors which are fixable in USB mode */ diff --git a/bootloader/sansa_as3525.c b/bootloader/sansa_as3525.c index 3eb6159800..4219038d9a 100644 --- a/bootloader/sansa_as3525.c +++ b/bootloader/sansa_as3525.c @@ -27,10 +27,8 @@ #include #include "config.h" #include "lcd.h" -#ifdef USE_ROCKBOX_USB #include "usb.h" #include "sysfont.h" -#endif /* USE_ROCKBOX_USB */ #include "backlight.h" #include "button-target.h" #include "common.h" @@ -41,6 +39,33 @@ int show_logo(void); +static void usb_mode(void) +{ + if(usb_detect() != USB_INSERTED) + { + const char msg[] = "Plug USB cable"; + reset_screen(); + lcd_putsxy( (LCD_WIDTH - (SYSFONT_WIDTH * sizeof(msg))) / 2, + (LCD_HEIGHT - SYSFONT_HEIGHT) / 2, msg); + lcd_update(); + + /* wait until USB is plugged */ + while(usb_detect() != USB_INSERTED) ; + } + + const char msg[] = "Bootloader USB mode"; + reset_screen(); + lcd_putsxy( (LCD_WIDTH - (SYSFONT_WIDTH * sizeof(msg))) / 2, + (LCD_HEIGHT - SYSFONT_HEIGHT) / 2, msg); + lcd_update(); + + while(usb_detect() == USB_INSERTED) + sleep(HZ); + + reset_screen(); + lcd_update(); +} + void main(void) __attribute__((noreturn)); void main(void) { @@ -84,53 +109,41 @@ void main(void) ret = storage_init(); if(ret < 0) - error(EATA,ret); + error(EATA, ret, true); -#ifdef USE_ROCKBOX_USB usb_init(); usb_start_monitoring(); - if(usb_detect() == USB_INSERTED) + + /* Enter USB mode if USB is plugged and SELECT button is pressed */ + if(btn & BUTTON_SELECT && usb_detect() == USB_INSERTED) + usb_mode(); + + while(!disk_init(IF_MV(0))) + usb_mode(); + + while((ret = disk_mount_all()) <= 0) { - const char msg[] = "Bootloader USB mode"; - reset_screen(); - lcd_putsxy( (LCD_WIDTH - (SYSFONT_WIDTH * sizeof(msg))) / 2, - (LCD_HEIGHT - SYSFONT_HEIGHT) / 2, msg); - lcd_update(); - - while(usb_detect() == USB_INSERTED) - sleep(HZ); - - reset_screen(); - lcd_update(); + error(EDISK, ret, false); + usb_mode(); } -#endif /* USE_ROCKBOX_USB */ - - if(!disk_init(IF_MV(0))) - panicf("disk_init failed!"); - - ret = disk_mount_all(); - - if(ret <= 0) - error(EDISK, ret); printf("Loading firmware"); loadbuffer = (unsigned char*)DRAM_ORIG; /* DRAM */ buffer_size = (int)(loadbuffer + (DRAM_SIZE) - TTB_SIZE); - ret = load_firmware(loadbuffer, BOOTFILE, buffer_size); - if(ret < 0) - error(EBOOTFILE, ret); - - if (ret == EOK) + while((ret = load_firmware(loadbuffer, BOOTFILE, buffer_size)) < 0) { - kernel_entry = (void*) loadbuffer; - cpucache_invalidate(); - printf("Executing"); - kernel_entry(); - printf("ERR: Failed to boot"); + error(EBOOTFILE, ret, false); + usb_mode(); } + kernel_entry = (void*) loadbuffer; + cpucache_invalidate(); + printf("Executing"); + kernel_entry(); + printf("ERR: Failed to boot"); + /* never returns */ while(1) ; } diff --git a/bootloader/telechips.c b/bootloader/telechips.c index 9e9e75c183..adf3e63483 100644 --- a/bootloader/telechips.c +++ b/bootloader/telechips.c @@ -158,21 +158,21 @@ void* main(void) if(rc) { reset_screen(); - error(EATA, rc); + error(EATA, rc, true); } printf("mount"); rc = disk_mount_all(); if (rc<=0) { - error(EDISK,rc); + error(EDISK,rc, true); } rc = load_firmware(loadbuffer, BOOTFILE, MAX_LOAD_SIZE); if (rc < 0) { - error(EBOOTFILE,rc); + error(EBOOTFILE,rc, true); } else if (rc == EOK) {