diff options
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) |
