diff options
author | Michael Sevakis <jethead71@rockbox.org> | 2011-01-17 12:24:41 +0000 |
---|---|---|
committer | Michael Sevakis <jethead71@rockbox.org> | 2011-01-17 12:24:41 +0000 |
commit | 05f6f3419aec991307e7c81e0738e0496a21d89b (patch) | |
tree | 4bad4a187bc2a2bdd714e086ac9910a9b3de6357 | |
parent | bcc0f88372fd2be986a5e279dd7e3bd556d6c984 (diff) | |
download | rockbox-05f6f3419aec991307e7c81e0738e0496a21d89b.tar.gz rockbox-05f6f3419aec991307e7c81e0738e0496a21d89b.zip |
Add a higher level USB detection that prevents fraudulent bus resets from causing USB mode to be entered. Enable for SA9200 only at this time. Also, for SA9200, use the bus power GPIO rather than the 'connector inserted' GPIO to detect the cable.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@29068 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r-- | firmware/export/config.h | 6 | ||||
-rw-r--r-- | firmware/export/usb.h | 5 | ||||
-rw-r--r-- | firmware/target/arm/system-pp502x.c | 4 | ||||
-rw-r--r-- | firmware/target/arm/usb-drv-arc.c | 8 | ||||
-rw-r--r-- | firmware/target/arm/usb-fw-pp502x.c | 14 | ||||
-rw-r--r-- | firmware/usb.c | 19 | ||||
-rw-r--r-- | firmware/usbstack/usb_core.c | 5 |
7 files changed, 43 insertions, 18 deletions
diff --git a/firmware/export/config.h b/firmware/export/config.h index 95f38c5995..f5ee003308 100644 --- a/firmware/export/config.h +++ b/firmware/export/config.h | |||
@@ -733,6 +733,12 @@ Lyre prototype 1 */ | |||
733 | 733 | ||
734 | #endif /* BOOTLOADER */ | 734 | #endif /* BOOTLOADER */ |
735 | 735 | ||
736 | #ifdef PHILIPS_SA9200 | ||
737 | /* Instead use the request for a device descriptor to detect a host */ | ||
738 | #undef USB_DETECT_BY_DRV | ||
739 | #define USB_DETECT_BY_CORE | ||
740 | #endif | ||
741 | |||
736 | #if defined(HAVE_USBSTACK) || (CONFIG_CPU == JZ4732) \ | 742 | #if defined(HAVE_USBSTACK) || (CONFIG_CPU == JZ4732) \ |
737 | || (CONFIG_CPU == AS3525) || (CONFIG_CPU == AS3525v2) \ | 743 | || (CONFIG_CPU == AS3525) || (CONFIG_CPU == AS3525v2) \ |
738 | || defined(CPU_S5L870X) || (CONFIG_CPU == S3C2440) \ | 744 | || defined(CPU_S5L870X) || (CONFIG_CPU == S3C2440) \ |
diff --git a/firmware/export/usb.h b/firmware/export/usb.h index e192748e4d..aceecb55ae 100644 --- a/firmware/export/usb.h +++ b/firmware/export/usb.h | |||
@@ -33,10 +33,11 @@ | |||
33 | enum { | 33 | enum { |
34 | USB_EXTRACTED = 0, /* Event+State */ | 34 | USB_EXTRACTED = 0, /* Event+State */ |
35 | USB_INSERTED, /* Event+State */ | 35 | USB_INSERTED, /* Event+State */ |
36 | #if defined(HAVE_USB_POWER) || defined(USB_DETECT_BY_DRV) | 36 | #if defined(HAVE_USB_POWER) || defined(USB_DETECT_BY_DRV) || \ |
37 | defined(USB_DETECT_BY_CORE) | ||
37 | USB_POWERED, /* Event+State */ | 38 | USB_POWERED, /* Event+State */ |
38 | #endif | 39 | #endif |
39 | #ifdef USB_DETECT_BY_DRV | 40 | #if defined(USB_DETECT_BY_DRV) || defined(USB_DETECT_BY_CORE) |
40 | USB_UNPOWERED, /* Event */ | 41 | USB_UNPOWERED, /* Event */ |
41 | #endif | 42 | #endif |
42 | #ifdef HAVE_LCD_BITMAP | 43 | #ifdef HAVE_LCD_BITMAP |
diff --git a/firmware/target/arm/system-pp502x.c b/firmware/target/arm/system-pp502x.c index bd71d28417..0422ea7d9c 100644 --- a/firmware/target/arm/system-pp502x.c +++ b/firmware/target/arm/system-pp502x.c | |||
@@ -141,9 +141,7 @@ void __attribute__((interrupt("IRQ"))) irq_handler(void) | |||
141 | else if (CPU_HI_INT_STAT & GPIO0_MASK) { | 141 | else if (CPU_HI_INT_STAT & GPIO0_MASK) { |
142 | if (GPIOD_INT_STAT & 0x02) | 142 | if (GPIOD_INT_STAT & 0x02) |
143 | button_int(); | 143 | button_int(); |
144 | } | 144 | if (GPIOB_INT_STAT & 0x40) |
145 | else if (CPU_HI_INT_STAT & GPIO1_MASK) { | ||
146 | if (GPIOF_INT_STAT & 0x80) | ||
147 | usb_insert_int(); | 145 | usb_insert_int(); |
148 | } | 146 | } |
149 | /* end PHILIPS_SA9200 */ | 147 | /* end PHILIPS_SA9200 */ |
diff --git a/firmware/target/arm/usb-drv-arc.c b/firmware/target/arm/usb-drv-arc.c index 86a1637bc8..fc74ce5bf0 100644 --- a/firmware/target/arm/usb-drv-arc.c +++ b/firmware/target/arm/usb-drv-arc.c | |||
@@ -498,15 +498,23 @@ static void log_ep(int ep_num, int ep_dir, char* prefix) | |||
498 | 498 | ||
499 | void usb_drv_init(void) | 499 | void usb_drv_init(void) |
500 | { | 500 | { |
501 | #ifdef USB_DETECT_BY_CORE | ||
502 | /* USB core decides */ | ||
503 | _usb_drv_init(true); | ||
504 | #else | ||
505 | /* Use bus reset condition */ | ||
501 | _usb_drv_init(false); | 506 | _usb_drv_init(false); |
507 | #endif | ||
502 | } | 508 | } |
503 | 509 | ||
504 | /* fully enable driver */ | 510 | /* fully enable driver */ |
505 | void usb_drv_attach(void) | 511 | void usb_drv_attach(void) |
506 | { | 512 | { |
507 | logf("usb_drv_attach"); | 513 | logf("usb_drv_attach"); |
514 | #ifndef USB_DETECT_BY_CORE | ||
508 | sleep(HZ/10); | 515 | sleep(HZ/10); |
509 | _usb_drv_init(true); | 516 | _usb_drv_init(true); |
517 | #endif | ||
510 | } | 518 | } |
511 | 519 | ||
512 | void usb_drv_exit(void) | 520 | void usb_drv_exit(void) |
diff --git a/firmware/target/arm/usb-fw-pp502x.c b/firmware/target/arm/usb-fw-pp502x.c index 8f754fd04b..536535e059 100644 --- a/firmware/target/arm/usb-fw-pp502x.c +++ b/firmware/target/arm/usb-fw-pp502x.c | |||
@@ -65,10 +65,10 @@ | |||
65 | #define USB_GPIO_VAL 0x04 | 65 | #define USB_GPIO_VAL 0x04 |
66 | 66 | ||
67 | #elif defined(PHILIPS_SA9200) | 67 | #elif defined(PHILIPS_SA9200) |
68 | /* GPIO F bit 7 (low) is usb detect */ | 68 | /* GPIO B bit 6 (high) is usb bus power detect */ |
69 | #define USB_GPIO GPIOF | 69 | #define USB_GPIO GPIOB |
70 | #define USB_GPIO_MASK 0x80 | 70 | #define USB_GPIO_MASK 0x40 |
71 | #define USB_GPIO_VAL 0x00 | 71 | #define USB_GPIO_VAL 0x40 |
72 | 72 | ||
73 | #elif defined(PHILIPS_HDD1630) || defined(PHILIPS_HDD6330) | 73 | #elif defined(PHILIPS_HDD1630) || defined(PHILIPS_HDD6330) |
74 | /* GPIO E bit 2 is usb detect */ | 74 | /* GPIO E bit 2 is usb detect */ |
@@ -225,10 +225,12 @@ void usb_insert_int(void) | |||
225 | timeout_register(&usb_oneshot, usb_timeout_event, HZ/5, val); | 225 | timeout_register(&usb_oneshot, usb_timeout_event, HZ/5, val); |
226 | } | 226 | } |
227 | 227 | ||
228 | /* Called during the bus reset interrupt when in detect mode - filter for | 228 | /* USB_DETECT_BY_DRV: Called during the bus reset interrupt when in detect mode |
229 | * invalid bus reset when unplugging by checking the pin state. */ | 229 | * USB_DETECT_BY_CORE: Called when device descriptor is requested |
230 | */ | ||
230 | void usb_drv_usb_detect_event(void) | 231 | void usb_drv_usb_detect_event(void) |
231 | { | 232 | { |
233 | /* Filter for invalid bus reset when unplugging by checking the pin state. */ | ||
232 | if(usb_plugged()) { | 234 | if(usb_plugged()) { |
233 | usb_status_event(USB_INSERTED); | 235 | usb_status_event(USB_INSERTED); |
234 | } | 236 | } |
diff --git a/firmware/usb.c b/firmware/usb.c index c8f0118730..ca0e86b478 100644 --- a/firmware/usb.c +++ b/firmware/usb.c | |||
@@ -136,7 +136,7 @@ static inline void usb_slave_mode(bool on) | |||
136 | } | 136 | } |
137 | else /* usb_state == USB_INSERTED (only!) */ | 137 | else /* usb_state == USB_INSERTED (only!) */ |
138 | { | 138 | { |
139 | #ifndef USB_DETECT_BY_DRV | 139 | #if !defined(USB_DETECT_BY_DRV) && !defined(USB_DETECT_BY_CORE) |
140 | usb_enable(false); | 140 | usb_enable(false); |
141 | #endif | 141 | #endif |
142 | #ifdef HAVE_PRIORITY_SCHEDULING | 142 | #ifdef HAVE_PRIORITY_SCHEDULING |
@@ -244,7 +244,7 @@ static void usb_thread(void) | |||
244 | (struct usb_transfer_completion_event_data*)ev.data); | 244 | (struct usb_transfer_completion_event_data*)ev.data); |
245 | break; | 245 | break; |
246 | #endif | 246 | #endif |
247 | #ifdef USB_DETECT_BY_DRV | 247 | #if defined(USB_DETECT_BY_DRV) || defined(USB_DETECT_BY_CORE) |
248 | /* In this case, these events the handle cable insertion USB | 248 | /* In this case, these events the handle cable insertion USB |
249 | * driver determines INSERTED/EXTRACTED state. */ | 249 | * driver determines INSERTED/EXTRACTED state. */ |
250 | case USB_POWERED: | 250 | case USB_POWERED: |
@@ -263,7 +263,7 @@ static void usb_thread(void) | |||
263 | * available. */ | 263 | * available. */ |
264 | queue_post(&usb_queue, USB_EXTRACTED, 0); | 264 | queue_post(&usb_queue, USB_EXTRACTED, 0); |
265 | break; | 265 | break; |
266 | #endif /* USB_DETECT_BY_DRV */ | 266 | #endif /* USB_DETECT_BY_DRV || USB_DETECT_BY_CORE */ |
267 | case USB_INSERTED: | 267 | case USB_INSERTED: |
268 | #ifdef HAVE_LCD_BITMAP | 268 | #ifdef HAVE_LCD_BITMAP |
269 | if(do_screendump_instead_of_usb) | 269 | if(do_screendump_instead_of_usb) |
@@ -379,7 +379,8 @@ static void usb_thread(void) | |||
379 | #ifdef HAVE_USBSTACK | 379 | #ifdef HAVE_USBSTACK |
380 | if(!exclusive_storage_access) | 380 | if(!exclusive_storage_access) |
381 | { | 381 | { |
382 | #ifndef USB_DETECT_BY_DRV /* Disabled handling USB_UNPOWERED */ | 382 | #if !defined(USB_DETECT_BY_DRV) && !defined(USB_DETECT_BY_CORE) |
383 | /* Disabled handling USB_UNPOWERED */ | ||
383 | usb_enable(false); | 384 | usb_enable(false); |
384 | #endif | 385 | #endif |
385 | break; | 386 | break; |
@@ -457,7 +458,8 @@ void usb_status_event(int current_status) | |||
457 | { | 458 | { |
458 | /* Caller isn't expected to filter for changes in status. | 459 | /* Caller isn't expected to filter for changes in status. |
459 | * current_status: | 460 | * current_status: |
460 | * USB_DETECT_BY_DRV: USB_POWERED, USB_UNPOWERED, USB_INSERTED (driver) | 461 | * USB_DETECT_BY_DRV/CORE: USB_POWERED, USB_UNPOWERED, |
462 | USB_INSERTED (driver/core) | ||
461 | * else: USB_INSERTED, USB_EXTRACTED | 463 | * else: USB_INSERTED, USB_EXTRACTED |
462 | */ | 464 | */ |
463 | if(usb_monitor_enabled) | 465 | if(usb_monitor_enabled) |
@@ -481,7 +483,10 @@ void usb_start_monitoring(void) | |||
481 | 483 | ||
482 | usb_monitor_enabled = true; | 484 | usb_monitor_enabled = true; |
483 | 485 | ||
484 | #ifdef USB_DETECT_BY_DRV | 486 | #ifdef USB_STATUS_BY_EVENT |
487 | /* Filter the status - an event may have been missed because it was | ||
488 | * sent before monitoring was enabled due to the connector already | ||
489 | * having been inserted before before or during boot. */ | ||
485 | status = (status == USB_INSERTED) ? USB_POWERED : USB_UNPOWERED; | 490 | status = (status == USB_INSERTED) ? USB_POWERED : USB_UNPOWERED; |
486 | #endif | 491 | #endif |
487 | usb_status_event(status); | 492 | usb_status_event(status); |
@@ -577,7 +582,7 @@ void usb_init(void) | |||
577 | { | 582 | { |
578 | /* We assume that the USB cable is extracted */ | 583 | /* We assume that the USB cable is extracted */ |
579 | usb_state = USB_EXTRACTED; | 584 | usb_state = USB_EXTRACTED; |
580 | #ifdef USB_DETECT_BY_DRV | 585 | #if defined(USB_DETECT_BY_DRV) || defined(USB_DETECT_BY_CORE) |
581 | last_usb_status = USB_UNPOWERED; | 586 | last_usb_status = USB_UNPOWERED; |
582 | #else | 587 | #else |
583 | last_usb_status = USB_EXTRACTED; | 588 | last_usb_status = USB_EXTRACTED; |
diff --git a/firmware/usbstack/usb_core.c b/firmware/usbstack/usb_core.c index 2ff3f325a2..aa96fff17f 100644 --- a/firmware/usbstack/usb_core.c +++ b/firmware/usbstack/usb_core.c | |||
@@ -559,6 +559,11 @@ static void request_handler_device_get_descriptor(struct usb_ctrlrequest* req) | |||
559 | case USB_DT_DEVICE: | 559 | case USB_DT_DEVICE: |
560 | ptr = &device_descriptor; | 560 | ptr = &device_descriptor; |
561 | size = sizeof(struct usb_device_descriptor); | 561 | size = sizeof(struct usb_device_descriptor); |
562 | #ifdef USB_DETECT_BY_CORE | ||
563 | /* Something requested a device descriptor; consider this a legit | ||
564 | connection */ | ||
565 | usb_drv_usb_detect_event(); | ||
566 | #endif | ||
562 | break; | 567 | break; |
563 | 568 | ||
564 | case USB_DT_OTHER_SPEED_CONFIG: | 569 | case USB_DT_OTHER_SPEED_CONFIG: |