Line
Link Here
|
0 |
-- |
0 |
++ b/drivers/usb/host/ehci-pci.c |
1 |
-- a/drivers/usb/host/ehci-pci.c |
|
|
Lines 24-63
Link Here
|
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 |
*/ |
30 |
static 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" */ |
62 |
static int ehci_pci_reinit(struct ehci_hcd *ehci, struct pci_dev *pdev) |
28 |
static int ehci_pci_reinit(struct ehci_hcd *ehci, struct pci_dev *pdev) |
63 |
{ |
29 |
{ |
Lines 84-115
static int ehci_pci_reinit(struct ehci_h
Link Here
|
84 |
} |
50 |
} |
85 |
} |
51 |
} |
86 |
|
52 |
|
87 |
temp = HCC_EXT_CAPS(readl(&ehci->caps->hcc_params)); |
53 |
/* we expect static quirk code to handle the "extended capabilities" |
88 |
|
54 |
* (currently just BIOS handoff) allowed starting with EHCI 0.96 |
89 |
/* EHCI 0.96 and later may have "extended capabilities" */ |
55 |
*/ |
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 |
|
56 |
|
114 |
/* PCI Memory-Write-Invalidate cycle support is optional (uncommon) */ |
57 |
/* PCI Memory-Write-Invalidate cycle support is optional (uncommon) */ |
115 |
retval = pci_set_mwi(pdev); |
58 |
retval = pci_set_mwi(pdev); |
116 |
-- a/drivers/usb/host/pci-quirks.c |
59 |
++ b/drivers/usb/host/pci-quirks.c |
Lines 190-196
static void __devinit quirk_usb_handoff_
Link Here
|
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 |
|
Lines 212-219
static void __devinit quirk_usb_disable_
Link Here
|
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; |
Lines 224-274
static void __devinit quirk_usb_disable_
Link Here
|
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 */ |
236 |
*/ |
242 |
if ((cap & EHCI_USBLEGSUP_BIOS)) { |
237 |
pci_read_config_dword(pdev, |
243 |
pr_debug("%s %s: BIOS handoff\n", |
238 |
hcc_params + EHCI_USBLEGCTLSTS, |
244 |
pdev->dev.bus_id, "EHCI"); |
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 |
|
245 |
|
248 |
wait_time = 500; |
246 |
/* BIOS workaround (?): be sure the |
249 |
do { |
247 |
* pre-Linux code receives the SMI |
250 |
msleep(10); |
248 |
*/ |
251 |
wait_time -= 10; |
|
|
252 |
pci_read_config_dword(pdev, |
249 |
pci_read_config_dword(pdev, |
253 |
hcc_params + EHCI_USBLEGSUP, |
250 |
offset + EHCI_USBLEGCTLSTS, |
254 |
&val); |
251 |
&val); |
255 |
} while (wait_time && (val & EHCI_USBLEGSUP_BIOS)); |
252 |
pci_write_config_dword(pdev, |
256 |
if (!wait_time) { |
253 |
offset + EHCI_USBLEGCTLSTS, |
257 |
/* |
254 |
val | EHCI_USBLEGCTLSTS_SOOE); |
258 |
* well, possibly buggy BIOS... |
255 |
} |
|
|
256 |
|
257 |
/* always say Linux will own the hardware |
258 |
* by setting EHCI_USBLEGSUP_OS. |
259 |
*/ |
260 |
pci_write_config_byte(pdev, offset + 3, 1); |
261 |
|
262 |
/* if boot firmware now owns EHCI, spin till |
263 |
* it hands it over. |
264 |
*/ |
265 |
msec = 5000; |
266 |
while ((cap & EHCI_USBLEGSUP_BIOS) && (msec > 0)) { |
267 |
msleep(10); |
268 |
msec -= 10; |
269 |
pci_read_config_dword(pdev, offset, &cap); |
270 |
} |
271 |
|
272 |
if (cap & EHCI_USBLEGSUP_BIOS) { |
273 |
/* well, possibly buggy BIOS... try to shut |
274 |
* it down, and hope nothing goes too wrong |
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 |