Subversion Repositories Kolibri OS

Rev

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