Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!
View | Details | Raw Unified | Return to bug 122661 | Differences between
and this patch

Collapse All | Expand All

(-)file_not_specified_in_diff (-101 / +73 lines)
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

Return to bug 122661