Subversion Repositories Kolibri OS

Rev

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