Simplify and neaten-up usb.c a bit. USB_INSERTED and USB_EXTRACTED are always used as events to indicate cable state. USB_HOSTED is posted to indicated that a host was detected.

git-svn-id: svn://svn.rockbox.org/rockbox/trunk@31263 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
Michael Sevakis 2011-12-15 00:14:36 +00:00
parent 911a355d76
commit 47bade1437
6 changed files with 88 additions and 109 deletions

View file

@ -30,15 +30,16 @@
#endif #endif
/* Messages from usb_tick and thread states */ /* Messages from usb_tick and thread states */
enum { enum
{
#ifdef HAVE_LCD_BITMAP
USB_SCREENDUMP = -1, /* State */
#endif
USB_EXTRACTED = 0, /* Event+State */ USB_EXTRACTED = 0, /* Event+State */
USB_INSERTED, /* Event+State */ USB_INSERTED, /* Event+State */
USB_POWERED, /* Event+State - transitional indicator if no power */ USB_POWERED, /* State - transitional indicator if no power */
#ifdef USB_DETECT_BY_CORE #ifdef USB_DETECT_BY_CORE
USB_UNPOWERED, /* Event */ USB_HOSTED, /* Event - host presence was detected */
#endif
#ifdef HAVE_LCD_BITMAP
USB_SCREENDUMP, /* State */
#endif #endif
#if (CONFIG_STORAGE & STORAGE_MMC) #if (CONFIG_STORAGE & STORAGE_MMC)
USB_REENABLE, /* Event */ USB_REENABLE, /* Event */
@ -57,6 +58,7 @@ enum {
USB_HANDLED, /* Bootloader status code */ USB_HANDLED, /* Bootloader status code */
#endif #endif
}; };
#ifdef HAVE_USB_POWER #ifdef HAVE_USB_POWER
#if CONFIG_KEYPAD == RECORDER_PAD #if CONFIG_KEYPAD == RECORDER_PAD
#define USBPOWER_BUTTON BUTTON_F1 #define USBPOWER_BUTTON BUTTON_F1

View file

@ -46,7 +46,7 @@ void usb_insert_int(void)
{ {
usb_status = USB_INSERTED; usb_status = USB_INSERTED;
#ifdef USB_STATUS_BY_EVENT #ifdef USB_STATUS_BY_EVENT
usb_status_event(USB_POWERED); usb_status_event(USB_INSERTED);
#endif #endif
} }
@ -54,7 +54,7 @@ void usb_remove_int(void)
{ {
usb_status = USB_EXTRACTED; usb_status = USB_EXTRACTED;
#ifdef USB_STATUS_BY_EVENT #ifdef USB_STATUS_BY_EVENT
usb_status_event(USB_UNPOWERED); usb_status_event(USB_EXTRACTED);
#endif #endif
} }
@ -68,7 +68,7 @@ void usb_drv_usb_detect_event(void)
int oldstatus = disable_irq_save(); /* May come via USB thread */ int oldstatus = disable_irq_save(); /* May come via USB thread */
if (usb_status == USB_INSERTED) if (usb_status == USB_INSERTED)
usb_status_event(USB_INSERTED); usb_status_event(USB_HOSTED);
restore_irq(oldstatus); restore_irq(oldstatus);
#endif #endif

View file

@ -33,17 +33,17 @@
void usb_insert_int(void) void usb_insert_int(void)
{ {
usb_status_event(USB_POWERED); usb_status_event(USB_INSERTED);
} }
void usb_remove_int(void) void usb_remove_int(void)
{ {
usb_status_event(USB_UNPOWERED); usb_status_event(USB_EXTRACTED);
} }
void usb_drv_usb_detect_event() void usb_drv_usb_detect_event()
{ {
usb_status_event(USB_INSERTED); usb_status_event(USB_HOSTED);
} }
void usb_attach(void) void usb_attach(void)

View file

@ -66,7 +66,7 @@ void usb_connect_event(void)
usb_status = status; usb_status = status;
/* Notify power that USB charging is potentially available */ /* Notify power that USB charging is potentially available */
charger_usb_detect_event(status); charger_usb_detect_event(status);
usb_status_event((status == USB_INSERTED) ? USB_POWERED : USB_UNPOWERED); usb_status_event(status);
} }
int usb_detect(void) int usb_detect(void)
@ -138,11 +138,11 @@ void usb_drv_int_enable(bool enable)
} }
} }
/* Called during the bus reset interrupt when in detect mode */ /* Called during the setup packet request by the host */
void usb_drv_usb_detect_event(void) void usb_drv_usb_detect_event(void)
{ {
if (usb_drv_powered()) if (usb_drv_powered())
usb_status_event(USB_INSERTED); usb_status_event(USB_HOSTED);
} }
/* Called when reading the MBR */ /* Called when reading the MBR */

View file

@ -212,7 +212,7 @@ static int usb_status = USB_EXTRACTED;
static int usb_timeout_event(struct timeout *tmo) static int usb_timeout_event(struct timeout *tmo)
{ {
usb_status_event(tmo->data == USB_GPIO_VAL ? USB_POWERED : USB_UNPOWERED); usb_status_event(tmo->data == USB_GPIO_VAL ? USB_INSERTED : USB_EXTRACTED);
return 0; return 0;
} }
@ -231,7 +231,7 @@ void usb_drv_usb_detect_event(void)
{ {
/* Filter for invalid bus reset when unplugging by checking the pin state. */ /* Filter for invalid bus reset when unplugging by checking the pin state. */
if(usb_plugged()) { if(usb_plugged()) {
usb_status_event(USB_INSERTED); usb_status_event(USB_HOSTED);
} }
} }
#endif /* USB_STATUS_BY_EVENT */ #endif /* USB_STATUS_BY_EVENT */

View file

@ -110,29 +110,46 @@ static void try_reboot(void)
} }
#endif /* USB_FIRWIRE_HANDLING || (HAVE_USBSTACK && !USE_ROCKBOX_USB) */ #endif /* USB_FIRWIRE_HANDLING || (HAVE_USBSTACK && !USE_ROCKBOX_USB) */
/* Screen dump */
#ifdef HAVE_LCD_BITMAP
static inline bool usb_do_screendump(void) static inline bool usb_do_screendump(void)
{ {
#ifdef HAVE_LCD_BITMAP
if(do_screendump_instead_of_usb) if(do_screendump_instead_of_usb)
{ {
usb_state = USB_SCREENDUMP; usb_state = USB_SCREENDUMP;
screen_dump(); screen_dump();
#ifdef HAVE_REMOTE_LCD #ifdef HAVE_REMOTE_LCD
remote_screen_dump(); remote_screen_dump();
#endif #endif /* HAVE_REMOTE_LCD */
return true; return true;
} }
return false;
}
#else /* !HAVE_LCD_BITMAP */
static inline bool usb_do_screendump(void)
{
return false;
}
#endif /* HAVE_LCD_BITMAP */ #endif /* HAVE_LCD_BITMAP */
return false;
}
/* Power (charging-only) button */
static inline bool usb_power_button(void)
{
#ifdef HAVE_USB_POWER
return (button_status() & ~USBPOWER_BTN_IGNORE);
#else
return false;
#endif
}
#ifdef USB_FIREWIRE_HANDLING
static inline bool usb_reboot_button(void)
{
#ifdef HAVE_USB_POWER
return (button_status() & ~USBPOWER_BTN_IGNORE);
#else
return false;
#endif
}
#endif /* USB_FIREWIRE_HANDLING */
/*--- Routines that differ depending upon the presence of a USB stack ---*/
#ifdef HAVE_USBSTACK #ifdef HAVE_USBSTACK
/* Enable / disable USB when the stack is enabled - otherwise a noop */ /* Enable / disable USB when the stack is enabled - otherwise a noop */
@ -241,12 +258,10 @@ static inline void usb_slave_mode(bool on)
#else /* !USE_ROCKBOX_USB */ #else /* !USE_ROCKBOX_USB */
static inline void usb_slave_mode(bool on) static inline void usb_slave_mode(bool on)
{ {
/* Until we have native mass-storage mode, we want to reboot on USB host
* connect */
if(on) if(on)
{
/* until we have native mass-storage mode, we want to reboot on
usb host connect */
try_reboot(); try_reboot();
}
} }
#endif /* USE_ROCKBOX_USB */ #endif /* USE_ROCKBOX_USB */
@ -343,68 +358,34 @@ static inline void usb_slave_mode(bool on)
} }
#endif /* HAVE_USBSTACK */ #endif /* HAVE_USBSTACK */
#ifdef HAVE_USB_POWER
static inline bool usb_power_button(void)
{
return (button_status() & ~USBPOWER_BTN_IGNORE);
}
#ifdef USB_FIREWIRE_HANDLING /*--- General driver code ---*/
static inline bool usb_reboot_button(void) static void NORETURN_ATTR usb_thread(void)
{ {
return (button_status() & ~USBPOWER_BTN_IGNORE);
}
#endif
#else /* !HAVE_USB_POWER */
static inline bool usb_power_button(void)
{
return false;
}
#ifdef USB_FIREWIRE_HANDLING
static inline bool usb_reboot_button(void)
{
return false;
}
#endif
#endif /* HAVE_USB_POWER */
#ifndef USB_DRIVER_CLOSE
static void usb_thread(void) NORETURN_ATTR;
#endif
static void usb_thread(void)
{
#ifdef USB_DETECT_BY_CORE
bool host_detected = false;
#endif
int num_acks_to_expect = 0; int num_acks_to_expect = 0;
long last_broadcast_tick = current_tick; long last_broadcast_tick = current_tick;
bool host_detected = false;
struct queue_event ev; struct queue_event ev;
while(1) while(1)
{ {
queue_wait(&usb_queue, &ev); queue_wait(&usb_queue, &ev);
switch(ev.id) switch(ev.id)
{ {
/*** Main USB thread duties ***/ /*** Main USB thread duties ***/
#ifdef HAVE_USBSTACK #ifdef HAVE_USBSTACK
case USB_TRANSFER_COMPLETION: case USB_TRANSFER_COMPLETION:
if(usb_state <= USB_EXTRACTED)
break;
usb_core_handle_transfer_completion( usb_core_handle_transfer_completion(
(struct usb_transfer_completion_event_data*)ev.data); (struct usb_transfer_completion_event_data*)ev.data);
break; break;
#endif /* HAVE_USBSTACK */ #endif /* HAVE_USBSTACK */
case USB_INSERTED: case USB_INSERTED:
#ifdef USB_DETECT_BY_CORE
if(usb_state != USB_POWERED)
break;
if (host_detected)
break; /* Drivers configured but we're still USB_POWERED */
host_detected = true;
#else /* !USB_DETECT_BY_CORE */
if(usb_state != USB_EXTRACTED) if(usb_state != USB_EXTRACTED)
break; break;
@ -413,8 +394,21 @@ static void usb_thread(void)
usb_state = USB_POWERED; usb_state = USB_POWERED;
usb_stack_enable(true); usb_stack_enable(true);
#ifdef USB_DETECT_BY_CORE
/* Wait for USB core to detect the host */
break;
case USB_HOSTED:
if(usb_state != USB_POWERED)
break;
#endif /* USB_DETECT_BY_CORE */ #endif /* USB_DETECT_BY_CORE */
if(host_detected)
break;
host_detected = true;
if(usb_power_button()) if(usb_power_button())
{ {
/* Only charging is desired */ /* Only charging is desired */
@ -440,19 +434,18 @@ static void usb_thread(void)
} }
num_acks_to_expect += queue_broadcast(SYS_USB_CONNECTED, 0) - 1; num_acks_to_expect += queue_broadcast(SYS_USB_CONNECTED, 0) - 1;
DEBUGF("USB inserted. Waiting for %d acks...\n", DEBUGF("usb: waiting for %d acks...\n", num_acks_to_expect);
num_acks_to_expect);
/* Leave the state as USB_POWERED until the expected number of /* Leave the state as USB_POWERED until the expected number of
ACKS are received. */ ACKS are received. */
break; break;
/* USB_INSERTED: */ /* USB_INSERTED: or USB_HOSTED: */
case SYS_USB_CONNECTED_ACK: case SYS_USB_CONNECTED_ACK:
if(num_acks_to_expect > 0 && --num_acks_to_expect == 0) if(num_acks_to_expect > 0 && --num_acks_to_expect == 0)
{ {
DEBUGF("All threads have acknowledged the connect.\n"); DEBUGF("usb: all threads have acknowledged the connect.\n");
if(usb_state == USB_POWERED) if(host_detected)
{ {
usb_slave_mode(true); usb_slave_mode(true);
usb_state = USB_INSERTED; usb_state = USB_INSERTED;
@ -460,29 +453,11 @@ static void usb_thread(void)
} }
else else
{ {
DEBUGF("usb: got ack, %d to go...\n", DEBUGF("usb: got ack, %d to go...\n", num_acks_to_expect);
num_acks_to_expect);
} }
break; break;
/* SYS_USB_CONNECTED_ACK */ /* SYS_USB_CONNECTED_ACK */
#ifdef USB_DETECT_BY_CORE
/* In this case, these events handle cable insertion. USB driver or
core determines USB_INSERTED. */
case USB_POWERED:
if(usb_state != USB_EXTRACTED)
break;
if(usb_do_screendump())
break;
usb_state = USB_POWERED;
usb_stack_enable(true);
break;
/* USB_POWERED: */
case USB_UNPOWERED:
#endif /* USB_DETECT_BY_CORE */
case USB_EXTRACTED: case USB_EXTRACTED:
if(usb_state == USB_EXTRACTED) if(usb_state == USB_EXTRACTED)
break; break;
@ -497,13 +472,15 @@ static void usb_thread(void)
usb_state = USB_EXTRACTED; usb_state = USB_EXTRACTED;
/* Ok to broadcast disconnect now */ if(host_detected)
usb_configure_drivers(USB_EXTRACTED); {
#ifdef USB_DETECT_BY_CORE /* Ok to broadcast disconnect now */
host_detected = false; usb_configure_drivers(USB_EXTRACTED);
#endif host_detected = false;
}
break; break;
/* USB_UNPOWERED: USB_EXTRACTED: */ /* USB_EXTRACTED: */
/*** Miscellaneous USB thread duties ***/ /*** Miscellaneous USB thread duties ***/
@ -536,7 +513,8 @@ static void usb_thread(void)
/* CLOSE */ /* CLOSE */
#ifdef USB_DRIVER_CLOSE #ifdef USB_DRIVER_CLOSE
case USB_QUIT: case USB_QUIT:
return; thread_exit();
break;
#endif #endif
} /* switch */ } /* switch */
} /* while */ } /* while */
@ -554,9 +532,8 @@ void usb_status_event(int current_status)
{ {
/* Caller isn't expected to filter for changes in status. /* Caller isn't expected to filter for changes in status.
* current_status: * current_status:
* USB_DETECT_BY_CORE: USB_POWERED, USB_UNPOWERED, * all: USB_INSERTED, USB_EXTRACTED
USB_INSERTED (core) * USB_DETECT_BY_CORE: USB_HOSTED (from core)
* else: USB_INSERTED, USB_EXTRACTED
*/ */
if(usb_monitor_enabled) if(usb_monitor_enabled)
{ {
@ -578,8 +555,8 @@ void usb_start_monitoring(void)
* was enabled due to the connector already having been inserted before * was enabled due to the connector already having been inserted before
* before or during boot. */ * before or during boot. */
#ifdef USB_DETECT_BY_CORE #ifdef USB_DETECT_BY_CORE
/* Filter the status - USB_INSERTED may happen later */ /* Filter the status - USB_HOSTED may happen later */
status = (status == USB_EXTRACTED) ? USB_UNPOWERED : USB_POWERED; status = (status == USB_INSERTED) ? : USB_EXTRACTED;
#endif #endif
usb_status_event(status); usb_status_event(status);