Subversion Repositories Kolibri OS

Rev

Rev 1605 | Blame | Last modification | View Log | Download | RSS feed

  1.  
  2.  
  3. bool FindUSBControllers()
  4. {
  5.     bool retval = false;
  6.     u32_t bus, last_bus;
  7.     PCITAG tag;
  8.  
  9.     if( (last_bus = PciApi(1))==-1)
  10.         return retval;
  11.  
  12.     dbgprintf("last bus %x\n", last_bus);
  13.  
  14.     for(bus=0;bus<=last_bus;bus++)
  15.     {
  16.         u32_t devfn;
  17.  
  18.         for(devfn=0;devfn<256;devfn++)
  19.         {
  20.             hc_t *hc;
  21.  
  22.             u32_t id;
  23.             u16_t pcicmd;
  24.             u16_t devclass;
  25.             u8_t  interface;
  26.             int i;
  27.  
  28.             interface = PciRead8(bus,devfn, 0x09);
  29.             devclass = PciRead16(bus,devfn, 0x0A);
  30.             if( devclass != 0x0C03)
  31.                 continue;
  32.  
  33.             if( interface != 0)
  34.                 continue;
  35.  
  36.             pcicmd = PciRead16(bus,devfn, PCI_COMMAND);
  37.             if (! pcicmd & PCI_COMMAND_IO)
  38.                 continue;
  39.  
  40.             hc = (hc_t*)kmalloc(sizeof(hc_t), 0);
  41.             INIT_LIST_HEAD(&hc->list);
  42.             INIT_LIST_HEAD(&hc->rq_list);
  43.  
  44.             hc->pciId  = PciRead32(bus,devfn, 0);
  45.             hc->PciTag = pciTag(bus,(devfn>>3)&0x1F,devfn&0x7);
  46.  
  47.             hc->irq_line = PciRead32(bus,devfn, 0x3C) & 0xFF;
  48.  
  49.             for (i = 0; i < 6; i++)
  50.             {
  51.                 u32_t base;
  52.                 bool validSize;
  53.  
  54.                 base = PciRead32(bus,devfn, PCI_MAP_REG_START + (i << 2));
  55.                 if(base)
  56.                 {
  57.                     if (base & PCI_MAP_IO) {
  58.                         hc->ioBase[i] = (addr_t)PCIGETIO(base);
  59.                         hc->memType[i]   = base & PCI_MAP_IO_ATTR_MASK;
  60.                     } else {
  61.                         hc->memBase[i] = (u32_t)PCIGETMEMORY(base);
  62.                         hc->memType[i] = base & PCI_MAP_MEMORY_ATTR_MASK;
  63.                     }
  64.                 }
  65.             };
  66.             dbgprintf("host controller %x bus %x devfn %x, IRQ %d\n",
  67.                        hc->pciId, bus, devfn, hc->irq_line);
  68.  
  69.             list_add_tail(&hc->list, &hc_list);
  70.             retval = true;
  71.         };
  72.     };
  73.     return retval;
  74. };
  75.  
  76.  
  77. #if 0
  78.  
  79. /* these helpers provide future and backwards compatibility
  80.  * for accessing popular PCI BAR info */
  81. #define pci_resource_start(dev, bar)    ((dev)->resource[(bar)].start)
  82. #define pci_resource_end(dev, bar)  ((dev)->resource[(bar)].end)
  83. #define pci_resource_flags(dev, bar)    ((dev)->resource[(bar)].flags)
  84. #define pci_resource_len(dev,bar) \
  85.     ((pci_resource_start((dev), (bar)) == 0 &&  \
  86.       pci_resource_end((dev), (bar)) ==     \
  87.       pci_resource_start((dev), (bar))) ? 0 :   \
  88.                             \
  89.      (pci_resource_end((dev), (bar)) -      \
  90.       pci_resource_start((dev), (bar)) + 1))
  91.  
  92. static int __devinit mmio_resource_enabled(struct pci_dev *pdev, int idx)
  93. {
  94.     return pci_resource_start(pdev, idx) && mmio_enabled(pdev);
  95. }
  96.  
  97. static void __devinit quirk_usb_disable_ehci(struct pci_dev *pdev)
  98. {
  99.     int wait_time, delta;
  100.     void __iomem *base, *op_reg_base;
  101.     u32 hcc_params, val;
  102.     u8  offset, cap_length;
  103.     int count = 256/4;
  104.     int tried_handoff = 0;
  105.  
  106.     if (!mmio_resource_enabled(pdev, 0))
  107.         return;
  108.  
  109.     base = pci_ioremap_bar(pdev, 0);
  110.     if (base == NULL)
  111.         return;
  112.  
  113.     cap_length = readb(base);
  114.     op_reg_base = base + cap_length;
  115.  
  116.     /* EHCI 0.96 and later may have "extended capabilities"
  117.      * spec section 5.1 explains the bios handoff, e.g. for
  118.      * booting from USB disk or using a usb keyboard
  119.      */
  120.     hcc_params = readl(base + EHCI_HCC_PARAMS);
  121.     offset = (hcc_params >> 8) & 0xff;
  122.     while (offset && --count) {
  123.         u32     cap;
  124.         int     msec;
  125.  
  126.         pci_read_config_dword(pdev, offset, &cap);
  127.         switch (cap & 0xff) {
  128.         case 1:         /* BIOS/SMM/... handoff support */
  129.             if ((cap & EHCI_USBLEGSUP_BIOS)) {
  130.                 dev_dbg(&pdev->dev, "EHCI: BIOS handoff\n");
  131.  
  132. #if 0
  133. /* aleksey_gorelov@phoenix.com reports that some systems need SMI forced on,
  134.  * but that seems dubious in general (the BIOS left it off intentionally)
  135.  * and is known to prevent some systems from booting.  so we won't do this
  136. * unless maybe we can determine when we're on a system that needs SMI forced.
  137.  */
  138.                 /* BIOS workaround (?): be sure the
  139.                  * pre-Linux code receives the SMI
  140.                  */
  141.                 pci_read_config_dword(pdev,
  142.                         offset + EHCI_USBLEGCTLSTS,
  143.                         &val);
  144.                 pci_write_config_dword(pdev,
  145.                         offset + EHCI_USBLEGCTLSTS,
  146.                         val | EHCI_USBLEGCTLSTS_SOOE);
  147. #endif
  148.  
  149.                 /* some systems get upset if this semaphore is
  150.                  * set for any other reason than forcing a BIOS
  151.                  * handoff..
  152.                  */
  153.                 pci_write_config_byte(pdev, offset + 3, 1);
  154.             }
  155.  
  156.             /* if boot firmware now owns EHCI, spin till
  157.              * it hands it over.
  158.              */
  159.             msec = 1000;
  160.             while ((cap & EHCI_USBLEGSUP_BIOS) && (msec > 0)) {
  161.                 tried_handoff = 1;
  162.                 msleep(10);
  163.                 msec -= 10;
  164.                 pci_read_config_dword(pdev, offset, &cap);
  165.             }
  166.  
  167.             if (cap & EHCI_USBLEGSUP_BIOS) {
  168.                 /* well, possibly buggy BIOS... try to shut
  169.                  * it down, and hope nothing goes too wrong
  170.                  */
  171.                 dev_warn(&pdev->dev, "EHCI: BIOS handoff failed"
  172.                         " (BIOS bug?) %08x\n", cap);
  173.                 pci_write_config_byte(pdev, offset + 2, 0);
  174.             }
  175.  
  176.             /* just in case, always disable EHCI SMIs */
  177.             pci_write_config_dword(pdev,
  178.                     offset + EHCI_USBLEGCTLSTS,
  179.                     0);
  180.  
  181.             /* If the BIOS ever owned the controller then we
  182.              * can't expect any power sessions to remain intact.
  183.             */
  184.            if (tried_handoff)
  185.                writel(0, op_reg_base + EHCI_CONFIGFLAG);
  186.            break;
  187.        case 0:         /* illegal reserved capability */
  188.            cap = 0;
  189.            /* FALLTHROUGH */
  190.        default:
  191.            dev_warn(&pdev->dev, "EHCI: unrecognized capability "
  192.                    "%02x\n", cap & 0xff);
  193.            break;
  194.        }
  195.        offset = (cap >> 8) & 0xff;
  196.    }
  197.    if (!count)
  198.        dev_printk(KERN_DEBUG, &pdev->dev, "EHCI: capability loop?\n");
  199.  
  200.    /*
  201.     * halt EHCI & disable its interrupts in any case
  202.     */
  203.    val = readl(op_reg_base + EHCI_USBSTS);
  204.    if ((val & EHCI_USBSTS_HALTED) == 0) {
  205.        val = readl(op_reg_base + EHCI_USBCMD);
  206.        val &= ~EHCI_USBCMD_RUN;
  207.        writel(val, op_reg_base + EHCI_USBCMD);
  208.  
  209.        wait_time = 2000;
  210.        delta = 100;
  211.        do {
  212.            writel(0x3f, op_reg_base + EHCI_USBSTS);
  213.            udelay(delta);
  214.            wait_time -= delta;
  215.            val = readl(op_reg_base + EHCI_USBSTS);
  216.            if ((val == ~(u32)0) || (val & EHCI_USBSTS_HALTED)) {
  217.                break;
  218.            }
  219.        } while (wait_time > 0);
  220.    }
  221.    writel(0, op_reg_base + EHCI_USBINTR);
  222.    writel(0x3f, op_reg_base + EHCI_USBSTS);
  223.  
  224.    iounmap(base);
  225.  
  226.    return;
  227. }
  228.  
  229. #endif
  230.