diff options
Diffstat (limited to 'firmware/usb.c')
-rw-r--r-- | firmware/usb.c | 65 |
1 files changed, 52 insertions, 13 deletions
diff --git a/firmware/usb.c b/firmware/usb.c index 918d9802a3..10a7ae1bff 100644 --- a/firmware/usb.c +++ b/firmware/usb.c | |||
@@ -34,11 +34,11 @@ | |||
34 | #include "disk.h" | 34 | #include "disk.h" |
35 | #include "panic.h" | 35 | #include "panic.h" |
36 | #include "lcd.h" | 36 | #include "lcd.h" |
37 | #include "usb-target.h" | ||
37 | #include "usb.h" | 38 | #include "usb.h" |
38 | #include "button.h" | 39 | #include "button.h" |
39 | #include "sprintf.h" | 40 | #include "sprintf.h" |
40 | #include "string.h" | 41 | #include "string.h" |
41 | #include "usb-target.h" | ||
42 | #ifdef HAVE_USBSTACK | 42 | #ifdef HAVE_USBSTACK |
43 | #include "usb_core.h" | 43 | #include "usb_core.h" |
44 | #endif | 44 | #endif |
@@ -129,11 +129,13 @@ static inline void usb_slave_mode(bool on) | |||
129 | #ifdef HAVE_PRIORITY_SCHEDULING | 129 | #ifdef HAVE_PRIORITY_SCHEDULING |
130 | thread_set_priority(THREAD_ID_CURRENT, PRIORITY_REALTIME); | 130 | thread_set_priority(THREAD_ID_CURRENT, PRIORITY_REALTIME); |
131 | #endif | 131 | #endif |
132 | usb_enable(true); | 132 | usb_attach(); |
133 | } | 133 | } |
134 | else /* usb_state == USB_INSERTED (only!) */ | 134 | else /* usb_state == USB_INSERTED (only!) */ |
135 | { | 135 | { |
136 | #ifndef USB_DETECT_BY_DRV | ||
136 | usb_enable(false); | 137 | usb_enable(false); |
138 | #endif | ||
137 | #ifdef HAVE_PRIORITY_SCHEDULING | 139 | #ifdef HAVE_PRIORITY_SCHEDULING |
138 | thread_set_priority(THREAD_ID_CURRENT, PRIORITY_SYSTEM); | 140 | thread_set_priority(THREAD_ID_CURRENT, PRIORITY_SYSTEM); |
139 | #endif | 141 | #endif |
@@ -234,6 +236,26 @@ static void usb_thread(void) | |||
234 | (struct usb_transfer_completion_event_data*)ev.data); | 236 | (struct usb_transfer_completion_event_data*)ev.data); |
235 | break; | 237 | break; |
236 | #endif | 238 | #endif |
239 | #ifdef USB_DETECT_BY_DRV | ||
240 | /* In this case, these events the handle cable insertion USB | ||
241 | * driver determines INSERTED/EXTRACTED state. */ | ||
242 | case USB_POWERED: | ||
243 | /* Set the state to USB_POWERED for now and enable the driver | ||
244 | * to detect a bus reset only. If a bus reset is detected, | ||
245 | * USB_INSERTED will be received. */ | ||
246 | usb_state = USB_POWERED; | ||
247 | usb_enable(true); | ||
248 | break; | ||
249 | |||
250 | case USB_UNPOWERED: | ||
251 | usb_enable(false); | ||
252 | /* This part shouldn't be obligatory for anything that can | ||
253 | * reliably detect removal of the data lines. USB_EXTRACTED | ||
254 | * could be posted on that event while bus power remains | ||
255 | * available. */ | ||
256 | queue_post(&usb_queue, USB_EXTRACTED, 0); | ||
257 | break; | ||
258 | #endif /* USB_DETECT_BY_DRV */ | ||
237 | case USB_INSERTED: | 259 | case USB_INSERTED: |
238 | #ifdef HAVE_LCD_BITMAP | 260 | #ifdef HAVE_LCD_BITMAP |
239 | if(do_screendump_instead_of_usb) | 261 | if(do_screendump_instead_of_usb) |
@@ -244,14 +266,14 @@ static void usb_thread(void) | |||
244 | } | 266 | } |
245 | #endif | 267 | #endif |
246 | #ifdef HAVE_USB_POWER | 268 | #ifdef HAVE_USB_POWER |
247 | if (usb_power_button()) | 269 | if(usb_power_button()) |
248 | { | 270 | { |
249 | /* Only charging is desired */ | 271 | /* Only charging is desired */ |
250 | usb_state = USB_POWERED; | 272 | usb_state = USB_POWERED; |
251 | #ifdef HAVE_USBSTACK | 273 | #ifdef HAVE_USBSTACK |
252 | usb_core_enable_driver(USB_DRIVER_MASS_STORAGE, false); | 274 | usb_core_enable_driver(USB_DRIVER_MASS_STORAGE, false); |
253 | usb_core_enable_driver(USB_DRIVER_CHARGING_ONLY, true); | 275 | usb_core_enable_driver(USB_DRIVER_CHARGING_ONLY, true); |
254 | usb_enable(true); | 276 | usb_attach(); |
255 | #endif | 277 | #endif |
256 | break; | 278 | break; |
257 | } | 279 | } |
@@ -272,7 +294,7 @@ static void usb_thread(void) | |||
272 | 294 | ||
273 | if(!exclusive_storage_access) | 295 | if(!exclusive_storage_access) |
274 | { | 296 | { |
275 | usb_enable(true); | 297 | usb_attach(); |
276 | break; | 298 | break; |
277 | } | 299 | } |
278 | #endif /* HAVE_USBSTACK */ | 300 | #endif /* HAVE_USBSTACK */ |
@@ -304,7 +326,7 @@ static void usb_thread(void) | |||
304 | usb_state = USB_EXTRACTED; | 326 | usb_state = USB_EXTRACTED; |
305 | break; /* Connected for screendump only */ | 327 | break; /* Connected for screendump only */ |
306 | } | 328 | } |
307 | #endif /* HAVE_LCD_BITMAP */ | 329 | #endif |
308 | #ifndef HAVE_USBSTACK /* Stack must undo this if POWERED state was transitional */ | 330 | #ifndef HAVE_USBSTACK /* Stack must undo this if POWERED state was transitional */ |
309 | #ifdef HAVE_USB_POWER | 331 | #ifdef HAVE_USB_POWER |
310 | if(usb_state == USB_POWERED) | 332 | if(usb_state == USB_POWERED) |
@@ -312,7 +334,7 @@ static void usb_thread(void) | |||
312 | usb_state = USB_EXTRACTED; | 334 | usb_state = USB_EXTRACTED; |
313 | break; | 335 | break; |
314 | } | 336 | } |
315 | #endif /* HAVE_USB_POWER */ | 337 | #endif |
316 | #endif /* HAVE_USBSTACK */ | 338 | #endif /* HAVE_USBSTACK */ |
317 | if(usb_state == USB_INSERTED) | 339 | if(usb_state == USB_INSERTED) |
318 | { | 340 | { |
@@ -324,9 +346,11 @@ static void usb_thread(void) | |||
324 | 346 | ||
325 | usb_state = USB_EXTRACTED; | 347 | usb_state = USB_EXTRACTED; |
326 | #ifdef HAVE_USBSTACK | 348 | #ifdef HAVE_USBSTACK |
327 | if (!exclusive_storage_access) | 349 | if(!exclusive_storage_access) |
328 | { | 350 | { |
351 | #ifndef USB_DETECT_BY_DRV /* Disabled handling USB_UNPOWERED */ | ||
329 | usb_enable(false); | 352 | usb_enable(false); |
353 | #endif | ||
330 | break; | 354 | break; |
331 | } | 355 | } |
332 | 356 | ||
@@ -392,19 +416,34 @@ static void usb_thread(void) | |||
392 | #ifdef USB_STATUS_BY_EVENT | 416 | #ifdef USB_STATUS_BY_EVENT |
393 | void usb_status_event(int current_status) | 417 | void usb_status_event(int current_status) |
394 | { | 418 | { |
395 | /* Status should be USB_INSERTED or USB_EXTRACTED. | 419 | /* Status should be USB_POWERED, USB_UNPOWERED, USB_INSERTED or |
420 | * USB_EXTRACTED. | ||
396 | * Caller isn't expected to filter for changes in status. */ | 421 | * Caller isn't expected to filter for changes in status. */ |
397 | if (usb_monitor_enabled && last_usb_status != current_status) | 422 | if(usb_monitor_enabled) |
398 | { | 423 | { |
399 | last_usb_status = current_status; | 424 | int oldstatus = disable_irq_save(); /* Dual-use function */ |
400 | queue_post(&usb_queue, current_status, 0); | 425 | |
426 | if(last_usb_status != current_status) | ||
427 | { | ||
428 | last_usb_status = current_status; | ||
429 | queue_post(&usb_queue, current_status, 0); | ||
430 | } | ||
431 | |||
432 | restore_irq(oldstatus); | ||
401 | } | 433 | } |
402 | } | 434 | } |
403 | 435 | ||
404 | void usb_start_monitoring(void) | 436 | void usb_start_monitoring(void) |
405 | { | 437 | { |
438 | int status = usb_detect(); | ||
439 | #ifdef USB_DETECT_BY_DRV | ||
440 | /* USB detection begins by USB_POWERED, not USB_INSERTED. If it is | ||
441 | * USB_EXTRACTED, then nothing changes and post will be skipped. */ | ||
442 | if(USB_INSERTED == status) | ||
443 | status = USB_POWERED; | ||
444 | #endif | ||
406 | usb_monitor_enabled = true; | 445 | usb_monitor_enabled = true; |
407 | usb_status_event(usb_detect()); | 446 | usb_status_event(status); |
408 | } | 447 | } |
409 | #else /* !USB_STATUS_BY_EVENT */ | 448 | #else /* !USB_STATUS_BY_EVENT */ |
410 | static void usb_tick(void) | 449 | static void usb_tick(void) |