Ticket #5551: ehci_sb600.diff

File ehci_sb600.diff, 1.8 KB (added by mmlr, 9 years ago)
  • src/add-ons/kernel/busses/usb/ehci.cpp

     
    134134    TRACE("constructing new EHCI host controller driver\n");
    135135    fInitOK = false;
    136136
     137    // ATI/AMD SB600/SB700 freeze workaround kindly borrowed from NetBSD PR40056
     138    if (fPCIInfo->vendor_id == 0x1002 /* ATI/AMD */) {
     139        bool applyWorkaround = false;
     140
     141        if (fPCIInfo->device_id == 0x4386 /* SB600 EHCI controller */) {
     142            // always apply on SB600
     143            applyWorkaround = true;
     144        } else if (fPCIInfo->device_id == 0x4396 /* SB700/SB800 EHCI */) {
     145            // only apply on certain chipsets, determined by SMBus revision
     146            pci_info smbus;
     147            int32 index = 0;
     148            while (sPCIModule->get_nth_pci_info(index++, &smbus) >= B_OK) {
     149                if (smbus.vendor_id == 0x1002 && smbus.device_id == 0x4385) {
     150                    /* SB600/SB700/SB800 SMBus controller */
     151                    if (smbus.revision == 0x3a || smbus.revision == 0x3b)
     152                        applyWorkaround = true;
     153
     154                    break;
     155                }
     156            }
     157        }
     158
     159        if (applyWorkaround) {
     160            // "reserved" as far as documentation is concerned apparently,
     161            // no real idea who figured that out how, but it's in the NetBSD
     162            // patch concerning this...
     163
     164            TRACE_ALWAYS("applying SB600/SB700 freeze workaround\n");
     165            uint32 workaround = sPCIModule->read_pci_config(fPCIInfo->bus,
     166                fPCIInfo->device, fPCIInfo->function, 0x50, 4);
     167
     168            sPCIModule->write_pci_config(fPCIInfo->bus, fPCIInfo->device,
     169                fPCIInfo->function, 0x50, 4, workaround | (1 << 27));
     170        }
     171    }
     172
    137173    // enable busmaster and memory mapped access
    138174    uint16 command = sPCIModule->read_pci_config(fPCIInfo->bus,
    139175        fPCIInfo->device, fPCIInfo->function, PCI_command, 2);