aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/host
diff options
context:
space:
mode:
authorAdrian Bunk <bunk@stusta.de>2006-02-03 17:49:49 -0500
committerAdrian Bunk <bunk@r063144.stusta.swh.mhn.de>2006-02-03 17:49:49 -0500
commit01d206a7c1167639f6ca6dac22140fbdca017558 (patch)
treebc3ccf1a8140a7f787c4728cfa4c30e65ad56eb2 /drivers/usb/host
parent9c4b562abc9005e4b413de02c85d3d29da707cba (diff)
parentd6c8f6aaa1d7f68c1e6471ab0839d9047cdd159f (diff)
Merge with git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6.git
Diffstat (limited to 'drivers/usb/host')
-rw-r--r--drivers/usb/host/ehci-pci.c64
-rw-r--r--drivers/usb/host/ehci-sched.c4
-rw-r--r--drivers/usb/host/isp116x-hcd.c21
-rw-r--r--drivers/usb/host/ohci-au1xxx.c2
-rw-r--r--drivers/usb/host/pci-quirks.c106
-rw-r--r--drivers/usb/host/uhci-q.c4
6 files changed, 87 insertions, 114 deletions
diff --git a/drivers/usb/host/ehci-pci.c b/drivers/usb/host/ehci-pci.c
index 08ca0f849dab..3a6687df5594 100644
--- a/drivers/usb/host/ehci-pci.c
+++ b/drivers/usb/host/ehci-pci.c
@@ -24,46 +24,11 @@
24 24
25/*-------------------------------------------------------------------------*/ 25/*-------------------------------------------------------------------------*/
26 26
27/* EHCI 0.96 (and later) section 5.1 says how to kick BIOS/SMM/...
28 * off the controller (maybe it can boot from highspeed USB disks).
29 */
30static int bios_handoff(struct ehci_hcd *ehci, int where, u32 cap)
31{
32 struct pci_dev *pdev = to_pci_dev(ehci_to_hcd(ehci)->self.controller);
33
34 /* always say Linux will own the hardware */
35 pci_write_config_byte(pdev, where + 3, 1);
36
37 /* maybe wait a while for BIOS to respond */
38 if (cap & (1 << 16)) {
39 int msec = 5000;
40
41 do {
42 msleep(10);
43 msec -= 10;
44 pci_read_config_dword(pdev, where, &cap);
45 } while ((cap & (1 << 16)) && msec);
46 if (cap & (1 << 16)) {
47 ehci_err(ehci, "BIOS handoff failed (%d, %08x)\n",
48 where, cap);
49 // some BIOS versions seem buggy...
50 // return 1;
51 ehci_warn(ehci, "continuing after BIOS bug...\n");
52 /* disable all SMIs, and clear "BIOS owns" flag */
53 pci_write_config_dword(pdev, where + 4, 0);
54 pci_write_config_byte(pdev, where + 2, 0);
55 } else
56 ehci_dbg(ehci, "BIOS handoff succeeded\n");
57 }
58 return 0;
59}
60
61/* called after powerup, by probe or system-pm "wakeup" */ 27/* called after powerup, by probe or system-pm "wakeup" */
62static int ehci_pci_reinit(struct ehci_hcd *ehci, struct pci_dev *pdev) 28static int ehci_pci_reinit(struct ehci_hcd *ehci, struct pci_dev *pdev)
63{ 29{
64 u32 temp; 30 u32 temp;
65 int retval; 31 int retval;
66 unsigned count = 256/4;
67 32
68 /* optional debug port, normally in the first BAR */ 33 /* optional debug port, normally in the first BAR */
69 temp = pci_find_capability(pdev, 0x0a); 34 temp = pci_find_capability(pdev, 0x0a);
@@ -84,32 +49,9 @@ static int ehci_pci_reinit(struct ehci_hcd *ehci, struct pci_dev *pdev)
84 } 49 }
85 } 50 }
86 51
87 temp = HCC_EXT_CAPS(readl(&ehci->caps->hcc_params)); 52 /* we expect static quirk code to handle the "extended capabilities"
88 53 * (currently just BIOS handoff) allowed starting with EHCI 0.96
89 /* EHCI 0.96 and later may have "extended capabilities" */ 54 */
90 while (temp && count--) {
91 u32 cap;
92
93 pci_read_config_dword(pdev, temp, &cap);
94 ehci_dbg(ehci, "capability %04x at %02x\n", cap, temp);
95 switch (cap & 0xff) {
96 case 1: /* BIOS/SMM/... handoff */
97 if (bios_handoff(ehci, temp, cap) != 0)
98 return -EOPNOTSUPP;
99 break;
100 case 0: /* illegal reserved capability */
101 ehci_dbg(ehci, "illegal capability!\n");
102 cap = 0;
103 /* FALLTHROUGH */
104 default: /* unknown */
105 break;
106 }
107 temp = (cap >> 8) & 0xff;
108 }
109 if (!count) {
110 ehci_err(ehci, "bogus capabilities ... PCI problems!\n");
111 return -EIO;
112 }
113 55
114 /* PCI Memory-Write-Invalidate cycle support is optional (uncommon) */ 56 /* PCI Memory-Write-Invalidate cycle support is optional (uncommon) */
115 retval = pci_set_mwi(pdev); 57 retval = pci_set_mwi(pdev);
diff --git a/drivers/usb/host/ehci-sched.c b/drivers/usb/host/ehci-sched.c
index 57e77374d228..ebcca9700671 100644
--- a/drivers/usb/host/ehci-sched.c
+++ b/drivers/usb/host/ehci-sched.c
@@ -1063,6 +1063,7 @@ sitd_slot_ok (
1063 1063
1064 /* for IN, check CSPLIT */ 1064 /* for IN, check CSPLIT */
1065 if (stream->c_usecs) { 1065 if (stream->c_usecs) {
1066 uf = uframe & 7;
1066 max_used = 100 - stream->c_usecs; 1067 max_used = 100 - stream->c_usecs;
1067 do { 1068 do {
1068 tmp = 1 << uf; 1069 tmp = 1 << uf;
@@ -1843,8 +1844,7 @@ done:
1843#else 1844#else
1844 1845
1845static inline int 1846static inline int
1846sitd_submit (struct ehci_hcd *ehci, struct urb *urb, 1847sitd_submit (struct ehci_hcd *ehci, struct urb *urb, gfp_t mem_flags)
1847 unsigned mem_flags)
1848{ 1848{
1849 ehci_dbg (ehci, "split iso support is disabled\n"); 1849 ehci_dbg (ehci, "split iso support is disabled\n");
1850 return -ENOSYS; 1850 return -ENOSYS;
diff --git a/drivers/usb/host/isp116x-hcd.c b/drivers/usb/host/isp116x-hcd.c
index 584b8dc65119..972ce04889f8 100644
--- a/drivers/usb/host/isp116x-hcd.c
+++ b/drivers/usb/host/isp116x-hcd.c
@@ -1420,20 +1420,22 @@ static int isp116x_bus_suspend(struct usb_hcd *hcd)
1420 int ret = 0; 1420 int ret = 0;
1421 1421
1422 spin_lock_irqsave(&isp116x->lock, flags); 1422 spin_lock_irqsave(&isp116x->lock, flags);
1423
1424 val = isp116x_read_reg32(isp116x, HCCONTROL); 1423 val = isp116x_read_reg32(isp116x, HCCONTROL);
1424
1425 switch (val & HCCONTROL_HCFS) { 1425 switch (val & HCCONTROL_HCFS) {
1426 case HCCONTROL_USB_OPER: 1426 case HCCONTROL_USB_OPER:
1427 spin_unlock_irqrestore(&isp116x->lock, flags);
1427 val &= (~HCCONTROL_HCFS & ~HCCONTROL_RWE); 1428 val &= (~HCCONTROL_HCFS & ~HCCONTROL_RWE);
1428 val |= HCCONTROL_USB_SUSPEND; 1429 val |= HCCONTROL_USB_SUSPEND;
1429 if (device_may_wakeup(&hcd->self.root_hub->dev)) 1430 if (device_may_wakeup(&hcd->self.root_hub->dev))
1430 val |= HCCONTROL_RWE; 1431 val |= HCCONTROL_RWE;
1431 /* Wait for usb transfers to finish */ 1432 /* Wait for usb transfers to finish */
1432 mdelay(2); 1433 msleep(2);
1434 spin_lock_irqsave(&isp116x->lock, flags);
1433 isp116x_write_reg32(isp116x, HCCONTROL, val); 1435 isp116x_write_reg32(isp116x, HCCONTROL, val);
1436 spin_unlock_irqrestore(&isp116x->lock, flags);
1434 /* Wait for devices to suspend */ 1437 /* Wait for devices to suspend */
1435 mdelay(5); 1438 msleep(5);
1436 case HCCONTROL_USB_SUSPEND:
1437 break; 1439 break;
1438 case HCCONTROL_USB_RESUME: 1440 case HCCONTROL_USB_RESUME:
1439 isp116x_write_reg32(isp116x, HCCONTROL, 1441 isp116x_write_reg32(isp116x, HCCONTROL,
@@ -1441,12 +1443,11 @@ static int isp116x_bus_suspend(struct usb_hcd *hcd)
1441 HCCONTROL_USB_RESET); 1443 HCCONTROL_USB_RESET);
1442 case HCCONTROL_USB_RESET: 1444 case HCCONTROL_USB_RESET:
1443 ret = -EBUSY; 1445 ret = -EBUSY;
1446 default: /* HCCONTROL_USB_SUSPEND */
1447 spin_unlock_irqrestore(&isp116x->lock, flags);
1444 break; 1448 break;
1445 default:
1446 ret = -EINVAL;
1447 } 1449 }
1448 1450
1449 spin_unlock_irqrestore(&isp116x->lock, flags);
1450 return ret; 1451 return ret;
1451} 1452}
1452 1453
@@ -1715,9 +1716,9 @@ static struct platform_driver isp116x_driver = {
1715 .remove = isp116x_remove, 1716 .remove = isp116x_remove,
1716 .suspend = isp116x_suspend, 1717 .suspend = isp116x_suspend,
1717 .resume = isp116x_resume, 1718 .resume = isp116x_resume,
1718 .driver = { 1719 .driver = {
1719 .name = (char *)hcd_name, 1720 .name = (char *)hcd_name,
1720 }, 1721 },
1721}; 1722};
1722 1723
1723/*-----------------------------------------------------------------*/ 1724/*-----------------------------------------------------------------*/
diff --git a/drivers/usb/host/ohci-au1xxx.c b/drivers/usb/host/ohci-au1xxx.c
index 77cd6ac07e3c..db280ca7b7a0 100644
--- a/drivers/usb/host/ohci-au1xxx.c
+++ b/drivers/usb/host/ohci-au1xxx.c
@@ -67,7 +67,7 @@ static void au1xxx_stop_hc(struct platform_device *dev)
67 ": stopping Au1xxx OHCI USB Controller\n"); 67 ": stopping Au1xxx OHCI USB Controller\n");
68 68
69 /* Disable clock */ 69 /* Disable clock */
70 au_writel(readl((void *)USB_HOST_CONFIG) & ~USBH_ENABLE_CE, USB_HOST_CONFIG); 70 au_writel(au_readl(USB_HOST_CONFIG) & ~USBH_ENABLE_CE, USB_HOST_CONFIG);
71} 71}
72 72
73 73
diff --git a/drivers/usb/host/pci-quirks.c b/drivers/usb/host/pci-quirks.c
index 3ef2c0cdf1db..e9e5bc178cef 100644
--- a/drivers/usb/host/pci-quirks.c
+++ b/drivers/usb/host/pci-quirks.c
@@ -190,7 +190,7 @@ static void __devinit quirk_usb_handoff_ohci(struct pci_dev *pdev)
190 msleep(10); 190 msleep(10);
191 } 191 }
192 if (wait_time <= 0) 192 if (wait_time <= 0)
193 printk(KERN_WARNING "%s %s: early BIOS handoff " 193 printk(KERN_WARNING "%s %s: BIOS handoff "
194 "failed (BIOS bug ?)\n", 194 "failed (BIOS bug ?)\n",
195 pdev->dev.bus_id, "OHCI"); 195 pdev->dev.bus_id, "OHCI");
196 196
@@ -212,8 +212,9 @@ static void __devinit quirk_usb_disable_ehci(struct pci_dev *pdev)
212{ 212{
213 int wait_time, delta; 213 int wait_time, delta;
214 void __iomem *base, *op_reg_base; 214 void __iomem *base, *op_reg_base;
215 u32 hcc_params, val, temp; 215 u32 hcc_params, val;
216 u8 cap_length; 216 u8 offset, cap_length;
217 int count = 256/4;
217 218
218 if (!mmio_resource_enabled(pdev, 0)) 219 if (!mmio_resource_enabled(pdev, 0))
219 return; 220 return;
@@ -224,51 +225,80 @@ static void __devinit quirk_usb_disable_ehci(struct pci_dev *pdev)
224 225
225 cap_length = readb(base); 226 cap_length = readb(base);
226 op_reg_base = base + cap_length; 227 op_reg_base = base + cap_length;
228
229 /* EHCI 0.96 and later may have "extended capabilities"
230 * spec section 5.1 explains the bios handoff, e.g. for
231 * booting from USB disk or using a usb keyboard
232 */
227 hcc_params = readl(base + EHCI_HCC_PARAMS); 233 hcc_params = readl(base + EHCI_HCC_PARAMS);
228 hcc_params = (hcc_params >> 8) & 0xff; 234 offset = (hcc_params >> 8) & 0xff;
229 if (hcc_params) { 235 while (offset && count--) {
230 pci_read_config_dword(pdev, 236 u32 cap;
231 hcc_params + EHCI_USBLEGSUP, 237 int msec;
232 &val); 238
233 if (((val & 0xff) == 1) && (val & EHCI_USBLEGSUP_BIOS)) { 239 pci_read_config_dword(pdev, offset, &cap);
234 /* 240 switch (cap & 0xff) {
235 * Ok, BIOS is in smm mode, try to hand off... 241 case 1: /* BIOS/SMM/... handoff support */
242 if ((cap & EHCI_USBLEGSUP_BIOS)) {
243 pr_debug("%s %s: BIOS handoff\n",
244 pdev->dev.bus_id, "EHCI");
245
246 /* BIOS workaround (?): be sure the
247 * pre-Linux code receives the SMI
248 */
249 pci_read_config_dword(pdev,
250 offset + EHCI_USBLEGCTLSTS,
251 &val);
252 pci_write_config_dword(pdev,
253 offset + EHCI_USBLEGCTLSTS,
254 val | EHCI_USBLEGCTLSTS_SOOE);
255 }
256
257 /* always say Linux will own the hardware
258 * by setting EHCI_USBLEGSUP_OS.
236 */ 259 */
237 pci_read_config_dword(pdev, 260 pci_write_config_byte(pdev, offset + 3, 1);
238 hcc_params + EHCI_USBLEGCTLSTS,
239 &temp);
240 pci_write_config_dword(pdev,
241 hcc_params + EHCI_USBLEGCTLSTS,
242 temp | EHCI_USBLEGCTLSTS_SOOE);
243 val |= EHCI_USBLEGSUP_OS;
244 pci_write_config_dword(pdev,
245 hcc_params + EHCI_USBLEGSUP,
246 val);
247 261
248 wait_time = 500; 262 /* if boot firmware now owns EHCI, spin till
249 do { 263 * it hands it over.
264 */
265 msec = 5000;
266 while ((cap & EHCI_USBLEGSUP_BIOS) && (msec > 0)) {
250 msleep(10); 267 msleep(10);
251 wait_time -= 10; 268 msec -= 10;
252 pci_read_config_dword(pdev, 269 pci_read_config_dword(pdev, offset, &cap);
253 hcc_params + EHCI_USBLEGSUP, 270 }
254 &val); 271
255 } while (wait_time && (val & EHCI_USBLEGSUP_BIOS)); 272 if (cap & EHCI_USBLEGSUP_BIOS) {
256 if (!wait_time) { 273 /* well, possibly buggy BIOS... try to shut
257 /* 274 * it down, and hope nothing goes too wrong
258 * well, possibly buggy BIOS...
259 */ 275 */
260 printk(KERN_WARNING "%s %s: early BIOS handoff " 276 printk(KERN_WARNING "%s %s: BIOS handoff "
261 "failed (BIOS bug ?)\n", 277 "failed (BIOS bug ?)\n",
262 pdev->dev.bus_id, "EHCI"); 278 pdev->dev.bus_id, "EHCI");
263 pci_write_config_dword(pdev, 279 pci_write_config_byte(pdev, offset + 2, 0);
264 hcc_params + EHCI_USBLEGSUP,
265 EHCI_USBLEGSUP_OS);
266 pci_write_config_dword(pdev,
267 hcc_params + EHCI_USBLEGCTLSTS,
268 0);
269 } 280 }
281
282 /* just in case, always disable EHCI SMIs */
283 pci_write_config_dword(pdev,
284 offset + EHCI_USBLEGCTLSTS,
285 0);
286 break;
287 case 0: /* illegal reserved capability */
288 cap = 0;
289 /* FALLTHROUGH */
290 default:
291 printk(KERN_WARNING "%s %s: unrecognized "
292 "capability %02x\n",
293 pdev->dev.bus_id, "EHCI",
294 cap & 0xff);
295 break;
270 } 296 }
297 offset = (cap >> 8) & 0xff;
271 } 298 }
299 if (!count)
300 printk(KERN_DEBUG "%s %s: capability loop?\n",
301 pdev->dev.bus_id, "EHCI");
272 302
273 /* 303 /*
274 * halt EHCI & disable its interrupts in any case 304 * halt EHCI & disable its interrupts in any case
diff --git a/drivers/usb/host/uhci-q.c b/drivers/usb/host/uhci-q.c
index b6076004a437..782398045f9f 100644
--- a/drivers/usb/host/uhci-q.c
+++ b/drivers/usb/host/uhci-q.c
@@ -672,9 +672,9 @@ static int uhci_submit_control(struct uhci_hcd *uhci, struct urb *urb, struct ur
672 /* Low-speed transfers get a different queue, and won't hog the bus. 672 /* Low-speed transfers get a different queue, and won't hog the bus.
673 * Also, some devices enumerate better without FSBR; the easiest way 673 * Also, some devices enumerate better without FSBR; the easiest way
674 * to do that is to put URBs on the low-speed queue while the device 674 * to do that is to put URBs on the low-speed queue while the device
675 * is in the DEFAULT state. */ 675 * isn't in the CONFIGURED state. */
676 if (urb->dev->speed == USB_SPEED_LOW || 676 if (urb->dev->speed == USB_SPEED_LOW ||
677 urb->dev->state == USB_STATE_DEFAULT) 677 urb->dev->state != USB_STATE_CONFIGURED)
678 skelqh = uhci->skel_ls_control_qh; 678 skelqh = uhci->skel_ls_control_qh;
679 else { 679 else {
680 skelqh = uhci->skel_fs_control_qh; 680 skelqh = uhci->skel_fs_control_qh;