diff options
author | Jeremy Erickson <jerickso@cs.unc.edu> | 2014-04-18 17:06:00 -0400 |
---|---|---|
committer | Jeremy Erickson <jerickso@cs.unc.edu> | 2014-04-18 17:06:00 -0400 |
commit | a215aa7b9ab3759c047201199fba64d3042d7f13 (patch) | |
tree | bca37493d9b2233450e6d3ffced1261d0e4f71fe /drivers/usb/host/ehci-hcd.c | |
parent | d31199a77ef606f1d06894385f1852181ba6136b (diff) |
Update 2.6.36 to 2.6.36.4wip-dissipation2-jerickso
Diffstat (limited to 'drivers/usb/host/ehci-hcd.c')
-rw-r--r-- | drivers/usb/host/ehci-hcd.c | 37 |
1 files changed, 25 insertions, 12 deletions
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index 34a928d3b7d2..597ed102d54f 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c | |||
@@ -114,6 +114,9 @@ MODULE_PARM_DESC(hird, "host initiated resume duration, +1 for each 75us\n"); | |||
114 | 114 | ||
115 | #define INTR_MASK (STS_IAA | STS_FATAL | STS_PCD | STS_ERR | STS_INT) | 115 | #define INTR_MASK (STS_IAA | STS_FATAL | STS_PCD | STS_ERR | STS_INT) |
116 | 116 | ||
117 | /* for ASPM quirk of ISOC on AMD SB800 */ | ||
118 | static struct pci_dev *amd_nb_dev; | ||
119 | |||
117 | /*-------------------------------------------------------------------------*/ | 120 | /*-------------------------------------------------------------------------*/ |
118 | 121 | ||
119 | #include "ehci.h" | 122 | #include "ehci.h" |
@@ -514,6 +517,11 @@ static void ehci_stop (struct usb_hcd *hcd) | |||
514 | spin_unlock_irq (&ehci->lock); | 517 | spin_unlock_irq (&ehci->lock); |
515 | ehci_mem_cleanup (ehci); | 518 | ehci_mem_cleanup (ehci); |
516 | 519 | ||
520 | if (amd_nb_dev) { | ||
521 | pci_dev_put(amd_nb_dev); | ||
522 | amd_nb_dev = NULL; | ||
523 | } | ||
524 | |||
517 | #ifdef EHCI_STATS | 525 | #ifdef EHCI_STATS |
518 | ehci_dbg (ehci, "irq normal %ld err %ld reclaim %ld (lost %ld)\n", | 526 | ehci_dbg (ehci, "irq normal %ld err %ld reclaim %ld (lost %ld)\n", |
519 | ehci->stats.normal, ehci->stats.error, ehci->stats.reclaim, | 527 | ehci->stats.normal, ehci->stats.error, ehci->stats.reclaim, |
@@ -549,6 +557,8 @@ static int ehci_init(struct usb_hcd *hcd) | |||
549 | ehci->iaa_watchdog.function = ehci_iaa_watchdog; | 557 | ehci->iaa_watchdog.function = ehci_iaa_watchdog; |
550 | ehci->iaa_watchdog.data = (unsigned long) ehci; | 558 | ehci->iaa_watchdog.data = (unsigned long) ehci; |
551 | 559 | ||
560 | hcc_params = ehci_readl(ehci, &ehci->caps->hcc_params); | ||
561 | |||
552 | /* | 562 | /* |
553 | * hw default: 1K periodic list heads, one per frame. | 563 | * hw default: 1K periodic list heads, one per frame. |
554 | * periodic_size can shrink by USBCMD update if hcc_params allows. | 564 | * periodic_size can shrink by USBCMD update if hcc_params allows. |
@@ -556,11 +566,20 @@ static int ehci_init(struct usb_hcd *hcd) | |||
556 | ehci->periodic_size = DEFAULT_I_TDPS; | 566 | ehci->periodic_size = DEFAULT_I_TDPS; |
557 | INIT_LIST_HEAD(&ehci->cached_itd_list); | 567 | INIT_LIST_HEAD(&ehci->cached_itd_list); |
558 | INIT_LIST_HEAD(&ehci->cached_sitd_list); | 568 | INIT_LIST_HEAD(&ehci->cached_sitd_list); |
569 | |||
570 | if (HCC_PGM_FRAMELISTLEN(hcc_params)) { | ||
571 | /* periodic schedule size can be smaller than default */ | ||
572 | switch (EHCI_TUNE_FLS) { | ||
573 | case 0: ehci->periodic_size = 1024; break; | ||
574 | case 1: ehci->periodic_size = 512; break; | ||
575 | case 2: ehci->periodic_size = 256; break; | ||
576 | default: BUG(); | ||
577 | } | ||
578 | } | ||
559 | if ((retval = ehci_mem_init(ehci, GFP_KERNEL)) < 0) | 579 | if ((retval = ehci_mem_init(ehci, GFP_KERNEL)) < 0) |
560 | return retval; | 580 | return retval; |
561 | 581 | ||
562 | /* controllers may cache some of the periodic schedule ... */ | 582 | /* controllers may cache some of the periodic schedule ... */ |
563 | hcc_params = ehci_readl(ehci, &ehci->caps->hcc_params); | ||
564 | if (HCC_ISOC_CACHE(hcc_params)) // full frame cache | 583 | if (HCC_ISOC_CACHE(hcc_params)) // full frame cache |
565 | ehci->i_thresh = 2 + 8; | 584 | ehci->i_thresh = 2 + 8; |
566 | else // N microframes cached | 585 | else // N microframes cached |
@@ -614,12 +633,6 @@ static int ehci_init(struct usb_hcd *hcd) | |||
614 | /* periodic schedule size can be smaller than default */ | 633 | /* periodic schedule size can be smaller than default */ |
615 | temp &= ~(3 << 2); | 634 | temp &= ~(3 << 2); |
616 | temp |= (EHCI_TUNE_FLS << 2); | 635 | temp |= (EHCI_TUNE_FLS << 2); |
617 | switch (EHCI_TUNE_FLS) { | ||
618 | case 0: ehci->periodic_size = 1024; break; | ||
619 | case 1: ehci->periodic_size = 512; break; | ||
620 | case 2: ehci->periodic_size = 256; break; | ||
621 | default: BUG(); | ||
622 | } | ||
623 | } | 636 | } |
624 | if (HCC_LPM(hcc_params)) { | 637 | if (HCC_LPM(hcc_params)) { |
625 | /* support link power management EHCI 1.1 addendum */ | 638 | /* support link power management EHCI 1.1 addendum */ |
@@ -1048,10 +1061,11 @@ rescan: | |||
1048 | tmp && tmp != qh; | 1061 | tmp && tmp != qh; |
1049 | tmp = tmp->qh_next.qh) | 1062 | tmp = tmp->qh_next.qh) |
1050 | continue; | 1063 | continue; |
1051 | /* periodic qh self-unlinks on empty */ | 1064 | /* periodic qh self-unlinks on empty, and a COMPLETING qh |
1052 | if (!tmp) | 1065 | * may already be unlinked. |
1053 | goto nogood; | 1066 | */ |
1054 | unlink_async (ehci, qh); | 1067 | if (tmp) |
1068 | unlink_async(ehci, qh); | ||
1055 | /* FALL THROUGH */ | 1069 | /* FALL THROUGH */ |
1056 | case QH_STATE_UNLINK: /* wait for hw to finish? */ | 1070 | case QH_STATE_UNLINK: /* wait for hw to finish? */ |
1057 | case QH_STATE_UNLINK_WAIT: | 1071 | case QH_STATE_UNLINK_WAIT: |
@@ -1068,7 +1082,6 @@ idle_timeout: | |||
1068 | } | 1082 | } |
1069 | /* else FALL THROUGH */ | 1083 | /* else FALL THROUGH */ |
1070 | default: | 1084 | default: |
1071 | nogood: | ||
1072 | /* caller was supposed to have unlinked any requests; | 1085 | /* caller was supposed to have unlinked any requests; |
1073 | * that's not our job. just leak this memory. | 1086 | * that's not our job. just leak this memory. |
1074 | */ | 1087 | */ |