diff options
Diffstat (limited to 'firmware/usb.c')
-rw-r--r-- | firmware/usb.c | 151 |
1 files changed, 64 insertions, 87 deletions
diff --git a/firmware/usb.c b/firmware/usb.c index c7326c548b..ec81ba6f58 100644 --- a/firmware/usb.c +++ b/firmware/usb.c | |||
@@ -110,29 +110,46 @@ static void try_reboot(void) | |||
110 | } | 110 | } |
111 | #endif /* USB_FIRWIRE_HANDLING || (HAVE_USBSTACK && !USE_ROCKBOX_USB) */ | 111 | #endif /* USB_FIRWIRE_HANDLING || (HAVE_USBSTACK && !USE_ROCKBOX_USB) */ |
112 | 112 | ||
113 | 113 | /* Screen dump */ | |
114 | #ifdef HAVE_LCD_BITMAP | ||
115 | static inline bool usb_do_screendump(void) | 114 | static inline bool usb_do_screendump(void) |
116 | { | 115 | { |
116 | #ifdef HAVE_LCD_BITMAP | ||
117 | if(do_screendump_instead_of_usb) | 117 | if(do_screendump_instead_of_usb) |
118 | { | 118 | { |
119 | usb_state = USB_SCREENDUMP; | 119 | usb_state = USB_SCREENDUMP; |
120 | screen_dump(); | 120 | screen_dump(); |
121 | #ifdef HAVE_REMOTE_LCD | 121 | #ifdef HAVE_REMOTE_LCD |
122 | remote_screen_dump(); | 122 | remote_screen_dump(); |
123 | #endif | 123 | #endif /* HAVE_REMOTE_LCD */ |
124 | return true; | 124 | return true; |
125 | } | 125 | } |
126 | #endif /* HAVE_LCD_BITMAP */ | ||
127 | return false; | ||
128 | } | ||
126 | 129 | ||
130 | /* Power (charging-only) button */ | ||
131 | static inline bool usb_power_button(void) | ||
132 | { | ||
133 | #ifdef HAVE_USB_POWER | ||
134 | return (button_status() & ~USBPOWER_BTN_IGNORE); | ||
135 | #else | ||
127 | return false; | 136 | return false; |
137 | #endif | ||
128 | } | 138 | } |
129 | #else /* !HAVE_LCD_BITMAP */ | 139 | |
130 | static inline bool usb_do_screendump(void) | 140 | #ifdef USB_FIREWIRE_HANDLING |
141 | static inline bool usb_reboot_button(void) | ||
131 | { | 142 | { |
143 | #ifdef HAVE_USB_POWER | ||
144 | return (button_status() & ~USBPOWER_BTN_IGNORE); | ||
145 | #else | ||
132 | return false; | 146 | return false; |
147 | #endif | ||
133 | } | 148 | } |
134 | #endif /* HAVE_LCD_BITMAP */ | 149 | #endif /* USB_FIREWIRE_HANDLING */ |
150 | |||
135 | 151 | ||
152 | /*--- Routines that differ depending upon the presence of a USB stack ---*/ | ||
136 | 153 | ||
137 | #ifdef HAVE_USBSTACK | 154 | #ifdef HAVE_USBSTACK |
138 | /* Enable / disable USB when the stack is enabled - otherwise a noop */ | 155 | /* Enable / disable USB when the stack is enabled - otherwise a noop */ |
@@ -241,12 +258,10 @@ static inline void usb_slave_mode(bool on) | |||
241 | #else /* !USE_ROCKBOX_USB */ | 258 | #else /* !USE_ROCKBOX_USB */ |
242 | static inline void usb_slave_mode(bool on) | 259 | static inline void usb_slave_mode(bool on) |
243 | { | 260 | { |
261 | /* Until we have native mass-storage mode, we want to reboot on USB host | ||
262 | * connect */ | ||
244 | if(on) | 263 | if(on) |
245 | { | ||
246 | /* until we have native mass-storage mode, we want to reboot on | ||
247 | usb host connect */ | ||
248 | try_reboot(); | 264 | try_reboot(); |
249 | } | ||
250 | } | 265 | } |
251 | #endif /* USE_ROCKBOX_USB */ | 266 | #endif /* USE_ROCKBOX_USB */ |
252 | 267 | ||
@@ -343,68 +358,34 @@ static inline void usb_slave_mode(bool on) | |||
343 | } | 358 | } |
344 | #endif /* HAVE_USBSTACK */ | 359 | #endif /* HAVE_USBSTACK */ |
345 | 360 | ||
346 | #ifdef HAVE_USB_POWER | ||
347 | static inline bool usb_power_button(void) | ||
348 | { | ||
349 | return (button_status() & ~USBPOWER_BTN_IGNORE); | ||
350 | } | ||
351 | 361 | ||
352 | #ifdef USB_FIREWIRE_HANDLING | 362 | /*--- General driver code ---*/ |
353 | static inline bool usb_reboot_button(void) | 363 | static void NORETURN_ATTR usb_thread(void) |
354 | { | 364 | { |
355 | return (button_status() & ~USBPOWER_BTN_IGNORE); | ||
356 | } | ||
357 | #endif | ||
358 | #else /* !HAVE_USB_POWER */ | ||
359 | static inline bool usb_power_button(void) | ||
360 | { | ||
361 | return false; | ||
362 | } | ||
363 | |||
364 | #ifdef USB_FIREWIRE_HANDLING | ||
365 | static inline bool usb_reboot_button(void) | ||
366 | { | ||
367 | return false; | ||
368 | } | ||
369 | #endif | ||
370 | #endif /* HAVE_USB_POWER */ | ||
371 | |||
372 | #ifndef USB_DRIVER_CLOSE | ||
373 | static void usb_thread(void) NORETURN_ATTR; | ||
374 | #endif | ||
375 | static void usb_thread(void) | ||
376 | { | ||
377 | #ifdef USB_DETECT_BY_CORE | ||
378 | bool host_detected = false; | ||
379 | #endif | ||
380 | int num_acks_to_expect = 0; | 365 | int num_acks_to_expect = 0; |
381 | long last_broadcast_tick = current_tick; | 366 | long last_broadcast_tick = current_tick; |
367 | bool host_detected = false; | ||
382 | struct queue_event ev; | 368 | struct queue_event ev; |
383 | 369 | ||
384 | while(1) | 370 | while(1) |
385 | { | 371 | { |
386 | queue_wait(&usb_queue, &ev); | 372 | queue_wait(&usb_queue, &ev); |
373 | |||
387 | switch(ev.id) | 374 | switch(ev.id) |
388 | { | 375 | { |
389 | /*** Main USB thread duties ***/ | 376 | /*** Main USB thread duties ***/ |
390 | 377 | ||
391 | #ifdef HAVE_USBSTACK | 378 | #ifdef HAVE_USBSTACK |
392 | case USB_TRANSFER_COMPLETION: | 379 | case USB_TRANSFER_COMPLETION: |
380 | if(usb_state <= USB_EXTRACTED) | ||
381 | break; | ||
382 | |||
393 | usb_core_handle_transfer_completion( | 383 | usb_core_handle_transfer_completion( |
394 | (struct usb_transfer_completion_event_data*)ev.data); | 384 | (struct usb_transfer_completion_event_data*)ev.data); |
395 | break; | 385 | break; |
396 | #endif /* HAVE_USBSTACK */ | 386 | #endif /* HAVE_USBSTACK */ |
397 | 387 | ||
398 | case USB_INSERTED: | 388 | case USB_INSERTED: |
399 | #ifdef USB_DETECT_BY_CORE | ||
400 | if(usb_state != USB_POWERED) | ||
401 | break; | ||
402 | |||
403 | if (host_detected) | ||
404 | break; /* Drivers configured but we're still USB_POWERED */ | ||
405 | |||
406 | host_detected = true; | ||
407 | #else /* !USB_DETECT_BY_CORE */ | ||
408 | if(usb_state != USB_EXTRACTED) | 389 | if(usb_state != USB_EXTRACTED) |
409 | break; | 390 | break; |
410 | 391 | ||
@@ -413,8 +394,21 @@ static void usb_thread(void) | |||
413 | 394 | ||
414 | usb_state = USB_POWERED; | 395 | usb_state = USB_POWERED; |
415 | usb_stack_enable(true); | 396 | usb_stack_enable(true); |
397 | |||
398 | #ifdef USB_DETECT_BY_CORE | ||
399 | /* Wait for USB core to detect the host */ | ||
400 | break; | ||
401 | |||
402 | case USB_HOSTED: | ||
403 | if(usb_state != USB_POWERED) | ||
404 | break; | ||
416 | #endif /* USB_DETECT_BY_CORE */ | 405 | #endif /* USB_DETECT_BY_CORE */ |
417 | 406 | ||
407 | if(host_detected) | ||
408 | break; | ||
409 | |||
410 | host_detected = true; | ||
411 | |||
418 | if(usb_power_button()) | 412 | if(usb_power_button()) |
419 | { | 413 | { |
420 | /* Only charging is desired */ | 414 | /* Only charging is desired */ |
@@ -440,19 +434,18 @@ static void usb_thread(void) | |||
440 | } | 434 | } |
441 | 435 | ||
442 | num_acks_to_expect += queue_broadcast(SYS_USB_CONNECTED, 0) - 1; | 436 | num_acks_to_expect += queue_broadcast(SYS_USB_CONNECTED, 0) - 1; |
443 | DEBUGF("USB inserted. Waiting for %d acks...\n", | 437 | DEBUGF("usb: waiting for %d acks...\n", num_acks_to_expect); |
444 | num_acks_to_expect); | ||
445 | 438 | ||
446 | /* Leave the state as USB_POWERED until the expected number of | 439 | /* Leave the state as USB_POWERED until the expected number of |
447 | ACKS are received. */ | 440 | ACKS are received. */ |
448 | break; | 441 | break; |
449 | /* USB_INSERTED: */ | 442 | /* USB_INSERTED: or USB_HOSTED: */ |
450 | 443 | ||
451 | case SYS_USB_CONNECTED_ACK: | 444 | case SYS_USB_CONNECTED_ACK: |
452 | if(num_acks_to_expect > 0 && --num_acks_to_expect == 0) | 445 | if(num_acks_to_expect > 0 && --num_acks_to_expect == 0) |
453 | { | 446 | { |
454 | DEBUGF("All threads have acknowledged the connect.\n"); | 447 | DEBUGF("usb: all threads have acknowledged the connect.\n"); |
455 | if(usb_state == USB_POWERED) | 448 | if(host_detected) |
456 | { | 449 | { |
457 | usb_slave_mode(true); | 450 | usb_slave_mode(true); |
458 | usb_state = USB_INSERTED; | 451 | usb_state = USB_INSERTED; |
@@ -460,29 +453,11 @@ static void usb_thread(void) | |||
460 | } | 453 | } |
461 | else | 454 | else |
462 | { | 455 | { |
463 | DEBUGF("usb: got ack, %d to go...\n", | 456 | DEBUGF("usb: got ack, %d to go...\n", num_acks_to_expect); |
464 | num_acks_to_expect); | ||
465 | } | 457 | } |
466 | break; | 458 | break; |
467 | /* SYS_USB_CONNECTED_ACK */ | 459 | /* SYS_USB_CONNECTED_ACK */ |
468 | 460 | ||
469 | #ifdef USB_DETECT_BY_CORE | ||
470 | /* In this case, these events handle cable insertion. USB driver or | ||
471 | core determines USB_INSERTED. */ | ||
472 | case USB_POWERED: | ||
473 | if(usb_state != USB_EXTRACTED) | ||
474 | break; | ||
475 | |||
476 | if(usb_do_screendump()) | ||
477 | break; | ||
478 | |||
479 | usb_state = USB_POWERED; | ||
480 | usb_stack_enable(true); | ||
481 | break; | ||
482 | /* USB_POWERED: */ | ||
483 | |||
484 | case USB_UNPOWERED: | ||
485 | #endif /* USB_DETECT_BY_CORE */ | ||
486 | case USB_EXTRACTED: | 461 | case USB_EXTRACTED: |
487 | if(usb_state == USB_EXTRACTED) | 462 | if(usb_state == USB_EXTRACTED) |
488 | break; | 463 | break; |
@@ -497,13 +472,15 @@ static void usb_thread(void) | |||
497 | 472 | ||
498 | usb_state = USB_EXTRACTED; | 473 | usb_state = USB_EXTRACTED; |
499 | 474 | ||
500 | /* Ok to broadcast disconnect now */ | 475 | if(host_detected) |
501 | usb_configure_drivers(USB_EXTRACTED); | 476 | { |
502 | #ifdef USB_DETECT_BY_CORE | 477 | /* Ok to broadcast disconnect now */ |
503 | host_detected = false; | 478 | usb_configure_drivers(USB_EXTRACTED); |
504 | #endif | 479 | host_detected = false; |
480 | } | ||
481 | |||
505 | break; | 482 | break; |
506 | /* USB_UNPOWERED: USB_EXTRACTED: */ | 483 | /* USB_EXTRACTED: */ |
507 | 484 | ||
508 | /*** Miscellaneous USB thread duties ***/ | 485 | /*** Miscellaneous USB thread duties ***/ |
509 | 486 | ||
@@ -536,7 +513,8 @@ static void usb_thread(void) | |||
536 | /* CLOSE */ | 513 | /* CLOSE */ |
537 | #ifdef USB_DRIVER_CLOSE | 514 | #ifdef USB_DRIVER_CLOSE |
538 | case USB_QUIT: | 515 | case USB_QUIT: |
539 | return; | 516 | thread_exit(); |
517 | break; | ||
540 | #endif | 518 | #endif |
541 | } /* switch */ | 519 | } /* switch */ |
542 | } /* while */ | 520 | } /* while */ |
@@ -554,9 +532,8 @@ void usb_status_event(int current_status) | |||
554 | { | 532 | { |
555 | /* Caller isn't expected to filter for changes in status. | 533 | /* Caller isn't expected to filter for changes in status. |
556 | * current_status: | 534 | * current_status: |
557 | * USB_DETECT_BY_CORE: USB_POWERED, USB_UNPOWERED, | 535 | * all: USB_INSERTED, USB_EXTRACTED |
558 | USB_INSERTED (core) | 536 | * USB_DETECT_BY_CORE: USB_HOSTED (from core) |
559 | * else: USB_INSERTED, USB_EXTRACTED | ||
560 | */ | 537 | */ |
561 | if(usb_monitor_enabled) | 538 | if(usb_monitor_enabled) |
562 | { | 539 | { |
@@ -578,8 +555,8 @@ void usb_start_monitoring(void) | |||
578 | * was enabled due to the connector already having been inserted before | 555 | * was enabled due to the connector already having been inserted before |
579 | * before or during boot. */ | 556 | * before or during boot. */ |
580 | #ifdef USB_DETECT_BY_CORE | 557 | #ifdef USB_DETECT_BY_CORE |
581 | /* Filter the status - USB_INSERTED may happen later */ | 558 | /* Filter the status - USB_HOSTED may happen later */ |
582 | status = (status == USB_EXTRACTED) ? USB_UNPOWERED : USB_POWERED; | 559 | status = (status == USB_INSERTED) ? : USB_EXTRACTED; |
583 | #endif | 560 | #endif |
584 | usb_status_event(status); | 561 | usb_status_event(status); |
585 | 562 | ||