diff options
Diffstat (limited to 'drivers/usb/host/ehci-hcd.c')
-rw-r--r-- | drivers/usb/host/ehci-hcd.c | 58 |
1 files changed, 14 insertions, 44 deletions
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index bc69bd7acebe..35248a37b717 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c | |||
@@ -304,30 +304,31 @@ static void ehci_watchdog (unsigned long param) | |||
304 | */ | 304 | */ |
305 | static int bios_handoff (struct ehci_hcd *ehci, int where, u32 cap) | 305 | static int bios_handoff (struct ehci_hcd *ehci, int where, u32 cap) |
306 | { | 306 | { |
307 | struct pci_dev *pdev = to_pci_dev(ehci_to_hcd(ehci)->self.controller); | ||
308 | |||
309 | /* always say Linux will own the hardware */ | ||
310 | pci_write_config_byte(pdev, where + 3, 1); | ||
311 | |||
312 | /* maybe wait a while for BIOS to respond */ | ||
307 | if (cap & (1 << 16)) { | 313 | if (cap & (1 << 16)) { |
308 | int msec = 5000; | 314 | int msec = 5000; |
309 | struct pci_dev *pdev = | ||
310 | to_pci_dev(ehci_to_hcd(ehci)->self.controller); | ||
311 | 315 | ||
312 | /* request handoff to OS */ | ||
313 | cap |= 1 << 24; | ||
314 | pci_write_config_dword(pdev, where, cap); | ||
315 | |||
316 | /* and wait a while for it to happen */ | ||
317 | do { | 316 | do { |
318 | msleep(10); | 317 | msleep(10); |
319 | msec -= 10; | 318 | msec -= 10; |
320 | pci_read_config_dword(pdev, where, &cap); | 319 | pci_read_config_dword(pdev, where, &cap); |
321 | } while ((cap & (1 << 16)) && msec); | 320 | } while ((cap & (1 << 16)) && msec); |
322 | if (cap & (1 << 16)) { | 321 | if (cap & (1 << 16)) { |
323 | ehci_err (ehci, "BIOS handoff failed (%d, %04x)\n", | 322 | ehci_err(ehci, "BIOS handoff failed (%d, %08x)\n", |
324 | where, cap); | 323 | where, cap); |
325 | // some BIOS versions seem buggy... | 324 | // some BIOS versions seem buggy... |
326 | // return 1; | 325 | // return 1; |
327 | ehci_warn (ehci, "continuing after BIOS bug...\n"); | 326 | ehci_warn (ehci, "continuing after BIOS bug...\n"); |
328 | return 0; | 327 | /* disable all SMIs, and clear "BIOS owns" flag */ |
329 | } | 328 | pci_write_config_dword(pdev, where + 4, 0); |
330 | ehci_dbg (ehci, "BIOS handoff succeeded\n"); | 329 | pci_write_config_byte(pdev, where + 2, 0); |
330 | } else | ||
331 | ehci_dbg(ehci, "BIOS handoff succeeded\n"); | ||
331 | } | 332 | } |
332 | return 0; | 333 | return 0; |
333 | } | 334 | } |
@@ -492,8 +493,6 @@ static int ehci_start (struct usb_hcd *hcd) | |||
492 | { | 493 | { |
493 | struct ehci_hcd *ehci = hcd_to_ehci (hcd); | 494 | struct ehci_hcd *ehci = hcd_to_ehci (hcd); |
494 | u32 temp; | 495 | u32 temp; |
495 | struct usb_device *udev; | ||
496 | struct usb_bus *bus; | ||
497 | int retval; | 496 | int retval; |
498 | u32 hcc_params; | 497 | u32 hcc_params; |
499 | u8 sbrn = 0; | 498 | u8 sbrn = 0; |
@@ -588,8 +587,8 @@ static int ehci_start (struct usb_hcd *hcd) | |||
588 | writel (0, &ehci->regs->segment); | 587 | writel (0, &ehci->regs->segment); |
589 | #if 0 | 588 | #if 0 |
590 | // this is deeply broken on almost all architectures | 589 | // this is deeply broken on almost all architectures |
591 | if (!pci_set_dma_mask (to_pci_dev(hcd->self.controller), 0xffffffffffffffffULL)) | 590 | if (!dma_set_mask (hcd->self.controller, DMA_64BIT_MASK)) |
592 | ehci_info (ehci, "enabled 64bit PCI DMA\n"); | 591 | ehci_info (ehci, "enabled 64bit DMA\n"); |
593 | #endif | 592 | #endif |
594 | } | 593 | } |
595 | 594 | ||
@@ -631,17 +630,6 @@ static int ehci_start (struct usb_hcd *hcd) | |||
631 | 630 | ||
632 | /* set async sleep time = 10 us ... ? */ | 631 | /* set async sleep time = 10 us ... ? */ |
633 | 632 | ||
634 | /* wire up the root hub */ | ||
635 | bus = hcd_to_bus (hcd); | ||
636 | udev = first ? usb_alloc_dev (NULL, bus, 0) : bus->root_hub; | ||
637 | if (!udev) { | ||
638 | done2: | ||
639 | ehci_mem_cleanup (ehci); | ||
640 | return -ENOMEM; | ||
641 | } | ||
642 | udev->speed = USB_SPEED_HIGH; | ||
643 | udev->state = first ? USB_STATE_ATTACHED : USB_STATE_CONFIGURED; | ||
644 | |||
645 | /* | 633 | /* |
646 | * Start, enabling full USB 2.0 functionality ... usb 1.1 devices | 634 | * Start, enabling full USB 2.0 functionality ... usb 1.1 devices |
647 | * are explicitly handed to companion controller(s), so no TT is | 635 | * are explicitly handed to companion controller(s), so no TT is |
@@ -664,24 +652,6 @@ done2: | |||
664 | first ? "initialized" : "restarted", | 652 | first ? "initialized" : "restarted", |
665 | temp >> 8, temp & 0xff, DRIVER_VERSION); | 653 | temp >> 8, temp & 0xff, DRIVER_VERSION); |
666 | 654 | ||
667 | /* | ||
668 | * From here on, khubd concurrently accesses the root | ||
669 | * hub; drivers will be talking to enumerated devices. | ||
670 | * (On restart paths, khubd already knows about the root | ||
671 | * hub and could find work as soon as we wrote FLAG_CF.) | ||
672 | * | ||
673 | * Before this point the HC was idle/ready. After, khubd | ||
674 | * and device drivers may start it running. | ||
675 | */ | ||
676 | if (first && usb_hcd_register_root_hub (udev, hcd) != 0) { | ||
677 | if (hcd->state == HC_STATE_RUNNING) | ||
678 | ehci_quiesce (ehci); | ||
679 | ehci_reset (ehci); | ||
680 | usb_put_dev (udev); | ||
681 | retval = -ENODEV; | ||
682 | goto done2; | ||
683 | } | ||
684 | |||
685 | writel (INTR_MASK, &ehci->regs->intr_enable); /* Turn On Interrupts */ | 655 | writel (INTR_MASK, &ehci->regs->intr_enable); /* Turn On Interrupts */ |
686 | 656 | ||
687 | if (first) | 657 | if (first) |