diff options
author | Linus Torvalds <torvalds@g5.osdl.org> | 2006-03-21 12:25:47 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-03-21 12:25:47 -0500 |
commit | 2bf2154c6bb5599e3ec3f73c34861a0b12aa839e (patch) | |
tree | 62691bd915e2e3c2e6648306d3fb893f7a1dc57e /drivers/usb/host/uhci-hcd.c | |
parent | 08a4ecee986dd98e86090ff5faac4782b6765aed (diff) | |
parent | 71a8924bee63d891f6256d560e32416a458440b3 (diff) |
Merge master.kernel.org:/pub/scm/linux/kernel/git/gregkh/usb-2.6
* master.kernel.org:/pub/scm/linux/kernel/git/gregkh/usb-2.6: (81 commits)
[PATCH] USB: omninet: fix up debugging comments
[PATCH] USB serial: add navman driver
[PATCH] USB: Fix irda-usb use after use
[PATCH] USB: rtl8150 small fix
[PATCH] USB: ftdi_sio: add Icom ID1 USB product and vendor ids
[PATCH] USB: cp2101: add new device IDs
[PATCH] USB: fix check_ctrlrecip to allow control transfers in state ADDRESS
[PATCH] USB: vicam.c: fix a NULL pointer dereference
[PATCH] USB: ZC0301 driver bugfix
[PATCH] USB: add support for Creativelabs Silvercrest USB keyboard
[PATCH] USB: storage: new unusual_devs.h entry: Mitsumi 7in1 Card Reader
[PATCH] USB: storage: unusual_devs.h entry 0420:0001
[PATCH] USB: storage: another unusual_devs.h entry
[PATCH] USB: storage: sandisk unusual_devices entry
[PATCH] USB: fix initdata issue in isp116x-hcd
[PATCH] USB: usbcore: usb_set_configuration oops (NULL ptr dereference)
[PATCH] USB: usbcore: Don't assume a USB configuration includes any interfaces
[PATCH] USB: ub 03 drop stall clearing
[PATCH] USB: ub 02 remove diag
[PATCH] USB: ub 01 remove first_open
...
Diffstat (limited to 'drivers/usb/host/uhci-hcd.c')
-rw-r--r-- | drivers/usb/host/uhci-hcd.c | 127 |
1 files changed, 80 insertions, 47 deletions
diff --git a/drivers/usb/host/uhci-hcd.c b/drivers/usb/host/uhci-hcd.c index dfe121d35887..4edb8330c440 100644 --- a/drivers/usb/host/uhci-hcd.c +++ b/drivers/usb/host/uhci-hcd.c | |||
@@ -54,7 +54,7 @@ | |||
54 | /* | 54 | /* |
55 | * Version Information | 55 | * Version Information |
56 | */ | 56 | */ |
57 | #define DRIVER_VERSION "v2.3" | 57 | #define DRIVER_VERSION "v3.0" |
58 | #define DRIVER_AUTHOR "Linus 'Frodo Rabbit' Torvalds, Johannes Erdfelt, \ | 58 | #define DRIVER_AUTHOR "Linus 'Frodo Rabbit' Torvalds, Johannes Erdfelt, \ |
59 | Randy Dunlap, Georg Acher, Deti Fliegl, Thomas Sailer, Roman Weissgaerber, \ | 59 | Randy Dunlap, Georg Acher, Deti Fliegl, Thomas Sailer, Roman Weissgaerber, \ |
60 | Alan Stern" | 60 | Alan Stern" |
@@ -68,12 +68,16 @@ Alan Stern" | |||
68 | * debug = 3, show all TDs in URBs when dumping | 68 | * debug = 3, show all TDs in URBs when dumping |
69 | */ | 69 | */ |
70 | #ifdef DEBUG | 70 | #ifdef DEBUG |
71 | #define DEBUG_CONFIGURED 1 | ||
71 | static int debug = 1; | 72 | static int debug = 1; |
72 | #else | ||
73 | static int debug = 0; | ||
74 | #endif | ||
75 | module_param(debug, int, S_IRUGO | S_IWUSR); | 73 | module_param(debug, int, S_IRUGO | S_IWUSR); |
76 | MODULE_PARM_DESC(debug, "Debug level"); | 74 | MODULE_PARM_DESC(debug, "Debug level"); |
75 | |||
76 | #else | ||
77 | #define DEBUG_CONFIGURED 0 | ||
78 | #define debug 0 | ||
79 | #endif | ||
80 | |||
77 | static char *errbuf; | 81 | static char *errbuf; |
78 | #define ERRBUF_LEN (32 * 1024) | 82 | #define ERRBUF_LEN (32 * 1024) |
79 | 83 | ||
@@ -338,6 +342,12 @@ static irqreturn_t uhci_irq(struct usb_hcd *hcd, struct pt_regs *regs) | |||
338 | dev_err(uhci_dev(uhci), | 342 | dev_err(uhci_dev(uhci), |
339 | "host controller halted, " | 343 | "host controller halted, " |
340 | "very bad!\n"); | 344 | "very bad!\n"); |
345 | if (debug > 1 && errbuf) { | ||
346 | /* Print the schedule for debugging */ | ||
347 | uhci_sprint_schedule(uhci, | ||
348 | errbuf, ERRBUF_LEN); | ||
349 | lprintk(errbuf); | ||
350 | } | ||
341 | hc_died(uhci); | 351 | hc_died(uhci); |
342 | 352 | ||
343 | /* Force a callback in case there are | 353 | /* Force a callback in case there are |
@@ -376,6 +386,14 @@ static void release_uhci(struct uhci_hcd *uhci) | |||
376 | { | 386 | { |
377 | int i; | 387 | int i; |
378 | 388 | ||
389 | if (DEBUG_CONFIGURED) { | ||
390 | spin_lock_irq(&uhci->lock); | ||
391 | uhci->is_initialized = 0; | ||
392 | spin_unlock_irq(&uhci->lock); | ||
393 | |||
394 | debugfs_remove(uhci->dentry); | ||
395 | } | ||
396 | |||
379 | for (i = 0; i < UHCI_NUM_SKELQH; i++) | 397 | for (i = 0; i < UHCI_NUM_SKELQH; i++) |
380 | uhci_free_qh(uhci, uhci->skelqh[i]); | 398 | uhci_free_qh(uhci, uhci->skelqh[i]); |
381 | 399 | ||
@@ -390,8 +408,6 @@ static void release_uhci(struct uhci_hcd *uhci) | |||
390 | dma_free_coherent(uhci_dev(uhci), | 408 | dma_free_coherent(uhci_dev(uhci), |
391 | UHCI_NUMFRAMES * sizeof(*uhci->frame), | 409 | UHCI_NUMFRAMES * sizeof(*uhci->frame), |
392 | uhci->frame, uhci->frame_dma_handle); | 410 | uhci->frame, uhci->frame_dma_handle); |
393 | |||
394 | debugfs_remove(uhci->dentry); | ||
395 | } | 411 | } |
396 | 412 | ||
397 | static int uhci_reset(struct usb_hcd *hcd) | 413 | static int uhci_reset(struct usb_hcd *hcd) |
@@ -474,33 +490,29 @@ static int uhci_start(struct usb_hcd *hcd) | |||
474 | 490 | ||
475 | hcd->uses_new_polling = 1; | 491 | hcd->uses_new_polling = 1; |
476 | 492 | ||
477 | dentry = debugfs_create_file(hcd->self.bus_name, | ||
478 | S_IFREG|S_IRUGO|S_IWUSR, uhci_debugfs_root, uhci, | ||
479 | &uhci_debug_operations); | ||
480 | if (!dentry) { | ||
481 | dev_err(uhci_dev(uhci), | ||
482 | "couldn't create uhci debugfs entry\n"); | ||
483 | retval = -ENOMEM; | ||
484 | goto err_create_debug_entry; | ||
485 | } | ||
486 | uhci->dentry = dentry; | ||
487 | |||
488 | uhci->fsbr = 0; | 493 | uhci->fsbr = 0; |
489 | uhci->fsbrtimeout = 0; | 494 | uhci->fsbrtimeout = 0; |
490 | 495 | ||
491 | spin_lock_init(&uhci->lock); | 496 | spin_lock_init(&uhci->lock); |
492 | INIT_LIST_HEAD(&uhci->qh_remove_list); | ||
493 | 497 | ||
494 | INIT_LIST_HEAD(&uhci->td_remove_list); | 498 | INIT_LIST_HEAD(&uhci->td_remove_list); |
495 | 499 | INIT_LIST_HEAD(&uhci->idle_qh_list); | |
496 | INIT_LIST_HEAD(&uhci->urb_remove_list); | ||
497 | |||
498 | INIT_LIST_HEAD(&uhci->urb_list); | ||
499 | |||
500 | INIT_LIST_HEAD(&uhci->complete_list); | ||
501 | 500 | ||
502 | init_waitqueue_head(&uhci->waitqh); | 501 | init_waitqueue_head(&uhci->waitqh); |
503 | 502 | ||
503 | if (DEBUG_CONFIGURED) { | ||
504 | dentry = debugfs_create_file(hcd->self.bus_name, | ||
505 | S_IFREG|S_IRUGO|S_IWUSR, uhci_debugfs_root, | ||
506 | uhci, &uhci_debug_operations); | ||
507 | if (!dentry) { | ||
508 | dev_err(uhci_dev(uhci), "couldn't create uhci " | ||
509 | "debugfs entry\n"); | ||
510 | retval = -ENOMEM; | ||
511 | goto err_create_debug_entry; | ||
512 | } | ||
513 | uhci->dentry = dentry; | ||
514 | } | ||
515 | |||
504 | uhci->frame = dma_alloc_coherent(uhci_dev(uhci), | 516 | uhci->frame = dma_alloc_coherent(uhci_dev(uhci), |
505 | UHCI_NUMFRAMES * sizeof(*uhci->frame), | 517 | UHCI_NUMFRAMES * sizeof(*uhci->frame), |
506 | &uhci->frame_dma_handle, 0); | 518 | &uhci->frame_dma_handle, 0); |
@@ -540,7 +552,7 @@ static int uhci_start(struct usb_hcd *hcd) | |||
540 | } | 552 | } |
541 | 553 | ||
542 | for (i = 0; i < UHCI_NUM_SKELQH; i++) { | 554 | for (i = 0; i < UHCI_NUM_SKELQH; i++) { |
543 | uhci->skelqh[i] = uhci_alloc_qh(uhci); | 555 | uhci->skelqh[i] = uhci_alloc_qh(uhci, NULL, NULL); |
544 | if (!uhci->skelqh[i]) { | 556 | if (!uhci->skelqh[i]) { |
545 | dev_err(uhci_dev(uhci), "unable to allocate QH\n"); | 557 | dev_err(uhci_dev(uhci), "unable to allocate QH\n"); |
546 | goto err_alloc_skelqh; | 558 | goto err_alloc_skelqh; |
@@ -557,13 +569,17 @@ static int uhci_start(struct usb_hcd *hcd) | |||
557 | uhci->skel_int16_qh->link = | 569 | uhci->skel_int16_qh->link = |
558 | uhci->skel_int8_qh->link = | 570 | uhci->skel_int8_qh->link = |
559 | uhci->skel_int4_qh->link = | 571 | uhci->skel_int4_qh->link = |
560 | uhci->skel_int2_qh->link = | 572 | uhci->skel_int2_qh->link = UHCI_PTR_QH | |
561 | cpu_to_le32(uhci->skel_int1_qh->dma_handle) | UHCI_PTR_QH; | 573 | cpu_to_le32(uhci->skel_int1_qh->dma_handle); |
562 | uhci->skel_int1_qh->link = cpu_to_le32(uhci->skel_ls_control_qh->dma_handle) | UHCI_PTR_QH; | 574 | |
563 | 575 | uhci->skel_int1_qh->link = UHCI_PTR_QH | | |
564 | uhci->skel_ls_control_qh->link = cpu_to_le32(uhci->skel_fs_control_qh->dma_handle) | UHCI_PTR_QH; | 576 | cpu_to_le32(uhci->skel_ls_control_qh->dma_handle); |
565 | uhci->skel_fs_control_qh->link = cpu_to_le32(uhci->skel_bulk_qh->dma_handle) | UHCI_PTR_QH; | 577 | uhci->skel_ls_control_qh->link = UHCI_PTR_QH | |
566 | uhci->skel_bulk_qh->link = cpu_to_le32(uhci->skel_term_qh->dma_handle) | UHCI_PTR_QH; | 578 | cpu_to_le32(uhci->skel_fs_control_qh->dma_handle); |
579 | uhci->skel_fs_control_qh->link = UHCI_PTR_QH | | ||
580 | cpu_to_le32(uhci->skel_bulk_qh->dma_handle); | ||
581 | uhci->skel_bulk_qh->link = UHCI_PTR_QH | | ||
582 | cpu_to_le32(uhci->skel_term_qh->dma_handle); | ||
567 | 583 | ||
568 | /* This dummy TD is to work around a bug in Intel PIIX controllers */ | 584 | /* This dummy TD is to work around a bug in Intel PIIX controllers */ |
569 | uhci_fill_td(uhci->term_td, 0, uhci_explen(0) | | 585 | uhci_fill_td(uhci->term_td, 0, uhci_explen(0) | |
@@ -589,15 +605,15 @@ static int uhci_start(struct usb_hcd *hcd) | |||
589 | 605 | ||
590 | /* | 606 | /* |
591 | * ffs (Find First bit Set) does exactly what we need: | 607 | * ffs (Find First bit Set) does exactly what we need: |
592 | * 1,3,5,... => ffs = 0 => use skel_int2_qh = skelqh[6], | 608 | * 1,3,5,... => ffs = 0 => use skel_int2_qh = skelqh[8], |
593 | * 2,6,10,... => ffs = 1 => use skel_int4_qh = skelqh[5], etc. | 609 | * 2,6,10,... => ffs = 1 => use skel_int4_qh = skelqh[7], etc. |
594 | * ffs > 6 => not on any high-period queue, so use | 610 | * ffs >= 7 => not on any high-period queue, so use |
595 | * skel_int1_qh = skelqh[7]. | 611 | * skel_int1_qh = skelqh[9]. |
596 | * Add UHCI_NUMFRAMES to insure at least one bit is set. | 612 | * Add UHCI_NUMFRAMES to insure at least one bit is set. |
597 | */ | 613 | */ |
598 | irq = 6 - (int) __ffs(i + UHCI_NUMFRAMES); | 614 | irq = 8 - (int) __ffs(i + UHCI_NUMFRAMES); |
599 | if (irq < 0) | 615 | if (irq <= 1) |
600 | irq = 7; | 616 | irq = 9; |
601 | 617 | ||
602 | /* Only place we don't use the frame list routines */ | 618 | /* Only place we don't use the frame list routines */ |
603 | uhci->frame[i] = UHCI_PTR_QH | | 619 | uhci->frame[i] = UHCI_PTR_QH | |
@@ -611,6 +627,7 @@ static int uhci_start(struct usb_hcd *hcd) | |||
611 | mb(); | 627 | mb(); |
612 | 628 | ||
613 | configure_hc(uhci); | 629 | configure_hc(uhci); |
630 | uhci->is_initialized = 1; | ||
614 | start_rh(uhci); | 631 | start_rh(uhci); |
615 | return 0; | 632 | return 0; |
616 | 633 | ||
@@ -767,13 +784,30 @@ static int uhci_resume(struct usb_hcd *hcd) | |||
767 | } | 784 | } |
768 | #endif | 785 | #endif |
769 | 786 | ||
770 | /* Wait until all the URBs for a particular device/endpoint are gone */ | 787 | /* Wait until a particular device/endpoint's QH is idle, and free it */ |
771 | static void uhci_hcd_endpoint_disable(struct usb_hcd *hcd, | 788 | static void uhci_hcd_endpoint_disable(struct usb_hcd *hcd, |
772 | struct usb_host_endpoint *ep) | 789 | struct usb_host_endpoint *hep) |
773 | { | 790 | { |
774 | struct uhci_hcd *uhci = hcd_to_uhci(hcd); | 791 | struct uhci_hcd *uhci = hcd_to_uhci(hcd); |
792 | struct uhci_qh *qh; | ||
793 | |||
794 | spin_lock_irq(&uhci->lock); | ||
795 | qh = (struct uhci_qh *) hep->hcpriv; | ||
796 | if (qh == NULL) | ||
797 | goto done; | ||
798 | |||
799 | while (qh->state != QH_STATE_IDLE) { | ||
800 | ++uhci->num_waiting; | ||
801 | spin_unlock_irq(&uhci->lock); | ||
802 | wait_event_interruptible(uhci->waitqh, | ||
803 | qh->state == QH_STATE_IDLE); | ||
804 | spin_lock_irq(&uhci->lock); | ||
805 | --uhci->num_waiting; | ||
806 | } | ||
775 | 807 | ||
776 | wait_event_interruptible(uhci->waitqh, list_empty(&ep->urb_list)); | 808 | uhci_free_qh(uhci, qh); |
809 | done: | ||
810 | spin_unlock_irq(&uhci->lock); | ||
777 | } | 811 | } |
778 | 812 | ||
779 | static int uhci_hcd_get_frame_number(struct usb_hcd *hcd) | 813 | static int uhci_hcd_get_frame_number(struct usb_hcd *hcd) |
@@ -857,16 +891,15 @@ static int __init uhci_hcd_init(void) | |||
857 | if (usb_disabled()) | 891 | if (usb_disabled()) |
858 | return -ENODEV; | 892 | return -ENODEV; |
859 | 893 | ||
860 | if (debug) { | 894 | if (DEBUG_CONFIGURED) { |
861 | errbuf = kmalloc(ERRBUF_LEN, GFP_KERNEL); | 895 | errbuf = kmalloc(ERRBUF_LEN, GFP_KERNEL); |
862 | if (!errbuf) | 896 | if (!errbuf) |
863 | goto errbuf_failed; | 897 | goto errbuf_failed; |
898 | uhci_debugfs_root = debugfs_create_dir("uhci", NULL); | ||
899 | if (!uhci_debugfs_root) | ||
900 | goto debug_failed; | ||
864 | } | 901 | } |
865 | 902 | ||
866 | uhci_debugfs_root = debugfs_create_dir("uhci", NULL); | ||
867 | if (!uhci_debugfs_root) | ||
868 | goto debug_failed; | ||
869 | |||
870 | uhci_up_cachep = kmem_cache_create("uhci_urb_priv", | 903 | uhci_up_cachep = kmem_cache_create("uhci_urb_priv", |
871 | sizeof(struct urb_priv), 0, 0, NULL, NULL); | 904 | sizeof(struct urb_priv), 0, 0, NULL, NULL); |
872 | if (!uhci_up_cachep) | 905 | if (!uhci_up_cachep) |