From 53b8c995218647321e0e6d6a421af1ae9fa24710 Mon Sep 17 00:00:00 2001 From: Linus Nielsen Feltzing Date: Mon, 1 Jul 2002 11:02:54 +0000 Subject: [PATCH] Better handling of non-responding threads git-svn-id: svn://svn.rockbox.org/rockbox/trunk@1281 a1c6a512-1295-4272-9138-f99709370657 --- firmware/usb.c | 210 ++++++++++++++++++++++++++----------------------- 1 file changed, 111 insertions(+), 99 deletions(-) diff --git a/firmware/usb.c b/firmware/usb.c index 763dd53e99..c748094396 100644 --- a/firmware/usb.c +++ b/firmware/usb.c @@ -38,6 +38,8 @@ #define USB_INSERTED 1 #define USB_EXTRACTED 2 +static int usb_state; + static char usb_stack[0x100]; static struct event_queue usb_queue; static bool last_usb_status; @@ -63,30 +65,30 @@ static void usb_slave_mode(bool on) if(on) { - DEBUGF("Entering USB slave mode\n"); - ata_enable(false); - usb_enable(true); + DEBUGF("Entering USB slave mode\n"); + ata_enable(false); + usb_enable(true); } else { - DEBUGF("Leaving USB slave mode\n"); + DEBUGF("Leaving USB slave mode\n"); + + /* Let the ISDx00 settle */ + sleep(HZ*1); + + usb_enable(false); - /* Let the ISDx00 settle */ - sleep(HZ*1); - - usb_enable(false); - - rc = ata_init(); - if(rc) - panicf("ata: %d",rc); - - pinfo = disk_init(); - if (!pinfo) - panicf("disk: NULL"); - - rc = fat_mount(pinfo[0].start); - if(rc) - panicf("mount: %d",rc); + rc = ata_init(); + if(rc) + panicf("ata: %d",rc); + + pinfo = disk_init(); + if (!pinfo) + panicf("disk: NULL"); + + rc = fat_mount(pinfo[0].start); + if(rc) + panicf("mount: %d",rc); } } @@ -100,70 +102,79 @@ static void usb_thread(void) while(1) { - queue_wait(&usb_queue, &ev); - switch(ev.id) - { - case USB_INSERTED: - /* Tell all threads that they have to back off the ATA. - We subtract one for our own thread. */ - num_acks_to_expect = queue_broadcast(SYS_USB_CONNECTED, NULL) - 1; - waiting_for_ack = true; - DEBUGF("USB inserted. Waiting for ack from %d threads...\n", - num_acks_to_expect); - break; - - case SYS_USB_CONNECTED_ACK: - if(waiting_for_ack) - { - num_acks_to_expect--; - if(num_acks_to_expect == 0) - { - /* This is where we are supposed to be cool and keep - the Rockbox firmware running while the USB is enabled, - maybe even play some games and stuff. However, the - current firmware isn't quite ready for this yet. - Let's just chicken out and reboot. */ - DEBUGF("All threads have acknowledged. Continuing...\n"); + queue_wait(&usb_queue, &ev); + switch(ev.id) + { + case USB_INSERTED: + /* Tell all threads that they have to back off the ATA. + We subtract one for our own thread. */ + num_acks_to_expect = queue_broadcast(SYS_USB_CONNECTED, NULL) - 1; + waiting_for_ack = true; + DEBUGF("USB inserted. Waiting for ack from %d threads...\n", + num_acks_to_expect); + break; + + case SYS_USB_CONNECTED_ACK: + if(waiting_for_ack) + { + num_acks_to_expect--; + if(num_acks_to_expect == 0) + { + /* This is where we are supposed to be cool and keep + the Rockbox firmware running while the USB is enabled, + maybe even play some games and stuff. However, the + current firmware isn't quite ready for this yet. + Let's just chicken out and reboot. */ + DEBUGF("All threads have acknowledged. Continuing...\n"); #ifdef USB_REALLY_BRAVE - usb_slave_mode(true); + usb_slave_mode(true); + usb_state = USB_INSERTED; + usb_display_info(); #else - system_reboot(); + system_reboot(); #endif - } - else - { - DEBUGF("usb: got ack, %d to go...\n", num_acks_to_expect); - } - } - break; + } + else + { + DEBUGF("usb: got ack, %d to go...\n", num_acks_to_expect); + } + } + break; - case USB_EXTRACTED: - /* First disable the USB mode */ - usb_slave_mode(false); - - /* Tell all threads that we are back in business */ - num_acks_to_expect = - queue_broadcast(SYS_USB_DISCONNECTED, NULL) - 1; - waiting_for_ack = true; - DEBUGF("USB extracted. Waiting for ack from %d threads...\n", - num_acks_to_expect); - break; - - case SYS_USB_DISCONNECTED_ACK: - if(waiting_for_ack) - { - num_acks_to_expect--; - if(num_acks_to_expect == 0) - { - DEBUGF("All threads have acknowledged. We're in business.\n"); - } - else - { - DEBUGF("usb: got ack, %d to go...\n", num_acks_to_expect); - } - } - break; - } + case USB_EXTRACTED: + if(usb_state == USB_INSERTED) + { + /* Only disable the USB mode if we really have enabled it + some threads might not have acknowledged the + insertion */ + usb_slave_mode(false); + } + + usb_state = USB_EXTRACTED; + + /* Tell all threads that we are back in business */ + num_acks_to_expect = + queue_broadcast(SYS_USB_DISCONNECTED, NULL) - 1; + waiting_for_ack = true; + DEBUGF("USB extracted. Waiting for ack from %d threads...\n", + num_acks_to_expect); + break; + + case SYS_USB_DISCONNECTED_ACK: + if(waiting_for_ack) + { + num_acks_to_expect--; + if(num_acks_to_expect == 0) + { + DEBUGF("All threads have acknowledged. We're in business.\n"); + } + else + { + DEBUGF("usb: got ack, %d to go...\n", num_acks_to_expect); + } + } + break; + } } } @@ -174,21 +185,21 @@ static void usb_tick(void) if(usb_monitor_enabled) { #ifdef ARCHOS_RECORDER - /* If AN2 reads more than about 500, the USB is inserted */ - current_status = (adc_read(2) > 500); + /* If AN2 reads more than about 500, the USB is inserted */ + current_status = (adc_read(2) > 500); #else - current_status = (PADR & 0x8000)?false:true; + current_status = (PADR & 0x8000)?false:true; #endif - - /* Only report when the status has changed */ - if(current_status != last_usb_status) - { - last_usb_status = current_status; - if(current_status) - queue_post(&usb_queue, USB_INSERTED, NULL); - else - queue_post(&usb_queue, USB_EXTRACTED, NULL); - } + + /* Only report when the status has changed */ + if(current_status != last_usb_status) + { + last_usb_status = current_status; + if(current_status) + queue_post(&usb_queue, USB_INSERTED, NULL); + else + queue_post(&usb_queue, USB_EXTRACTED, NULL); + } } } @@ -199,6 +210,7 @@ void usb_acknowledge(int id) void usb_init(void) { + usb_state = USB_EXTRACTED; usb_monitor_enabled = false; usb_enable(false); @@ -219,12 +231,12 @@ void usb_wait_for_disconnect(struct event_queue *q) /* Don't return until we get SYS_USB_DISCONNECTED */ while(1) { - queue_wait(q, &ev); - if(ev.id == SYS_USB_DISCONNECTED) - { - usb_acknowledge(SYS_USB_DISCONNECTED_ACK); - return; - } + queue_wait(q, &ev); + if(ev.id == SYS_USB_DISCONNECTED) + { + usb_acknowledge(SYS_USB_DISCONNECTED_ACK); + return; + } } }