Annotation of XNU/iokit/Drivers/ata/drvAppleATA/AppleATAPIIX.cpp, revision 1.1.1.1

1.1       root        1: /*
                      2:  * Copyright (c) 2000 Apple Computer, Inc.  All rights reserved. 
                      3:  *
                      4:  * AppleATAPIIX.cpp - ATA controller driver for Intel PIIX/PIIX3/PIIX4.
                      5:  *
                      6:  * HISTORY
                      7:  *
                      8:  */
                      9: 
                     10: #include <architecture/i386/pio.h>
                     11: #include <IOKit/IOService.h>
                     12: #include <IOKit/assert.h>
                     13: #include "AppleATAPIIX.h"
                     14: #include "AppleATAPIIXTiming.h"
                     15: 
                     16: extern pmap_t                      kernel_pmap;        // for pmap_extract()
                     17: 
                     18: // Resources shared between the two IDE channels are protected
                     19: // by this mutex.
                     20: //
                     21: static IOLock *            gPIIXLock = 0;
                     22: #define PIIX_LOCK                  IOLockLock(gPIIXLock)
                     23: #define PIIX_UNLOCK                IOLockUnlock(gPIIXLock)
                     24: 
                     25: #define IOREG(x)                   (ioBMRange + PIIX_IO_ ## x)
                     26: 
                     27: #define CHECK_UNIT(drv)            assert(drv < 2)
                     28: 
                     29: #ifdef  DEBUG_XXX
                     30: #define DLOG(fmt, args...)     IOLog(fmt, ## args)
                     31: #else
                     32: #define DLOG(fmt, args...)
                     33: #endif
                     34: 
                     35: //--------------------------------------------------------------------------
                     36: // Metaclass macro.
                     37: //
                     38: #undef  super
                     39: #define super AppleATA
                     40: 
                     41: OSDefineMetaClassAndStructorsWithInit( AppleATAPIIX, AppleATA,
                     42:                                        AppleATAPIIX::initialize() )
                     43: 
                     44: //--------------------------------------------------------------------------
                     45: // PIIX class initializer.
                     46: //
                     47: void AppleATAPIIX::initialize()
                     48: {
                     49:        gPIIXLock = IOLockAlloc();
                     50:        assert(gPIIXLock);
                     51: }
                     52: 
                     53: //--------------------------------------------------------------------------
                     54: // Defines a table of supported PIIX device types, listing their
                     55: // PCI ID, and a name string. Also supply some utility functions
                     56: // to locate a table entry based on an arbitrary PCI ID.
                     57: //
                     58: static struct {
                     59:        UInt32        CFID;
                     60:        const char *  name;
                     61: } piixDeviceTable[] = {{ PCI_ID_PIIX,  "PIIX"  },
                     62:                        { PCI_ID_PIIX3, "PIIX3" },
                     63:                        { PCI_ID_PIIX4, "PIIX4" },
                     64:                        { PCI_ID_NONE,   NULL   }};
                     65: 
                     66: static const char *
                     67: PIIXGetName(UInt32 pciID)
                     68: {
                     69:        for (int i = 0; piixDeviceTable[i].name; i++) {
                     70:                if (piixDeviceTable[i].CFID == pciID)
                     71:                        return piixDeviceTable[i].name;
                     72:        }
                     73:        return 0;
                     74: }
                     75: 
                     76: static bool
                     77: PIIXVerifyID(UInt32 pciID)
                     78: {
                     79:        return (PIIXGetName(pciID) == 0) ? false : true;
                     80: }
                     81: 
                     82: //--------------------------------------------------------------------------
                     83: // A hack to modify our PCI nub to have two interrupts.
                     84: // This code was borrowed from the setupIntelPIC() function
                     85: // in iokit/Families/IOPCIBus/IOPCIBridge.cpp.
                     86: //
                     87: static void setupProviderInterrupts(IOPCIDevice * nub, long irq_p, long irq_s)
                     88: {
                     89:        OSArray *         controller;
                     90:        OSArray *         specifier;
                     91:        OSData *          tmpData;
                     92:        extern OSSymbol * gIntelPICName;
                     93: 
                     94:        do {
                     95:                // Create the interrupt specifer array.
                     96:                specifier = OSArray::withCapacity(2);
                     97:                if (!specifier)
                     98:                        break;
                     99: 
                    100:         tmpData = OSData::withBytes(&irq_p, sizeof(irq_p));
                    101:         if (tmpData) {
                    102:             specifier->setObject(tmpData);
                    103:             tmpData->release();
                    104:         }
                    105:         tmpData = OSData::withBytes(&irq_s, sizeof(irq_s));
                    106:         if (tmpData) {
                    107:             specifier->setObject(tmpData);
                    108:             tmpData->release();
                    109:         }
                    110: 
                    111:         controller = OSArray::withCapacity(2);
                    112:         if (controller) {
                    113:                        controller->setObject(gIntelPICName);
                    114:                        controller->setObject(gIntelPICName);
                    115: 
                    116:             // Put the two arrays into the property table.
                    117:                        nub->setProperty(gIOInterruptControllersKey, controller);
                    118:             controller->release();
                    119:         }
                    120:         nub->setProperty(gIOInterruptSpecifiersKey, specifier);
                    121:         specifier->release();
                    122: 
                    123:     } while( false );
                    124: }
                    125: 
                    126: //--------------------------------------------------------------------------
                    127: // A static member function that returns the IDE channel for the
                    128: // current driver instance, and also registers the interrupts in
                    129: // the IOPCIDevice nub.
                    130: //
                    131: int AppleATAPIIX::PIIXGetChannel(IOPCIDevice * provider)
                    132: {
                    133:        static bool       primaryRegistered = false;
                    134:        int               rc;
                    135:        extern OSSymbol * gIntelPICName;
                    136: 
                    137:        PIIX_LOCK;
                    138:        
                    139:        if (primaryRegistered == false) {
                    140:                rc = PIIX_CHANNEL_PRIMARY;
                    141:                primaryRegistered = true;
                    142: 
                    143:                // Is this necessary?
                    144:                waitForService(resourceMatching(gIntelPICName));
                    145: 
                    146:                setupProviderInterrupts(provider, PIIX_P_IRQ, PIIX_S_IRQ);
                    147:        }
                    148:        else {
                    149:                rc = PIIX_CHANNEL_SECONDARY;
                    150:        }
                    151: 
                    152:        PIIX_UNLOCK;
                    153: 
                    154:        if (rc == PIIX_CHANNEL_SECONDARY) IOSleep(20);
                    155: 
                    156:        return rc;
                    157: }
                    158: 
                    159: //--------------------------------------------------------------------------
                    160: // Private function: _getIDERanges
                    161: //
                    162: // Setup the variables that stores the start of the Command and Control
                    163: // block in I/O space. The variable 'channel' must have been previously
                    164: // set. These ISA I/O ranges are implicit and does not show up in PCI
                    165: // config space.
                    166: //
                    167: bool AppleATAPIIX::_getIDERanges(IOPCIDevice * provider)
                    168: {
                    169:        ioCmdRange = (channel == PIIX_CHANNEL_PRIMARY) ?
                    170:                  PIIX_P_CMD_ADDR : PIIX_S_CMD_ADDR;
                    171:        
                    172:        ioCtlRange = (channel == PIIX_CHANNEL_PRIMARY) ?
                    173:                  PIIX_P_CTL_ADDR : PIIX_S_CTL_ADDR;
                    174: 
                    175:        DLOG("%s: ioCmdRange - %04x\n", getName(), ioCmdRange);
                    176:        DLOG("%s: ioCtlRange - %04x\n", getName(), ioCtlRange);
                    177: 
                    178:        return true;
                    179: }
                    180: 
                    181: //--------------------------------------------------------------------------
                    182: // Private function: _getBMRange
                    183: //
                    184: // Determine the start of the I/O mapped Bus-Master registers.
                    185: // This range is defined by PCI config space register PIIX_PCI_BMIBA.
                    186: //
                    187: bool AppleATAPIIX::_getBMRange(IOPCIDevice * provider)
                    188: {
                    189:        UInt32 bmiba;
                    190: 
                    191:        bmiba = provider->configRead32(PIIX_PCI_BMIBA);
                    192:        if ((bmiba & PIIX_PCI_BMIBA_RTE) == 0) {
                    193:                IOLog("%s: PCI memory range 0x%02x (0x%08lx) is not an I/O range\n",
                    194:                        getName(), PIIX_PCI_BMIBA, bmiba);
                    195:                return false;
                    196:        }
                    197:        
                    198:        bmiba &= PIIX_PCI_BMIBA_MASK;   // get the address portion
                    199: 
                    200:        // If bmiba is zero, it is likely that the user has elected to
                    201:        // turn off PCI IDE support in the BIOS.
                    202:        //
                    203:        if (bmiba == 0)
                    204:                return false;
                    205: 
                    206:        if (channel == PIIX_CHANNEL_SECONDARY)
                    207:                bmiba += PIIX_IO_BM_OFFSET;
                    208: 
                    209:        ioBMRange = (UInt16) bmiba;
                    210:        
                    211:        DLOG("%s: ioBMRange - %04x\n", getName(), ioBMRange);
                    212: 
                    213:        return true;
                    214: }
                    215: 
                    216: //--------------------------------------------------------------------------
                    217: // Private function: _resetTimings()
                    218: //
                    219: // Reset all timing registers to the slowest (most compatible) timing.
                    220: // UDMA modes are disabled. We take a lock to prevent the other IDE
                    221: // channel from modifying the shared PCI config space.
                    222: //
                    223: bool AppleATAPIIX::_resetTimings()
                    224: {
                    225:        union {
                    226:                UInt32 b32;
                    227:                struct {
                    228:                        UInt16 pri;
                    229:                        UInt16 sec;
                    230:                } b16;
                    231:        } timing;
                    232: 
                    233:        UInt32  udmaControl;
                    234: 
                    235:        PIIX_LOCK;
                    236: 
                    237:        timing.b32 = provider->configRead32(PIIX_PCI_IDETIM);
                    238:        udmaControl = provider->configRead32(PIIX_PCI_UDMACTL);
                    239: 
                    240:        // Set slowest timing, and disable UDMA. Only modify the flags
                    241:        // associated with the local channel.
                    242:        //
                    243:        switch (channel) {
                    244:                case PIIX_CHANNEL_PRIMARY:
                    245:                        timing.b16.pri &= PIIX_PCI_IDETIM_IDE;                  
                    246:                        udmaControl &= ~(PIIX_PCI_UDMACTL_PSDE0 | PIIX_PCI_UDMACTL_PSDE1);
                    247:                        break;
                    248:                
                    249:                case PIIX_CHANNEL_SECONDARY:
                    250:                        timing.b16.sec &= PIIX_PCI_IDETIM_IDE;
                    251:                        udmaControl &= ~(PIIX_PCI_UDMACTL_SSDE0 | PIIX_PCI_UDMACTL_SSDE1);
                    252:                        break;
                    253:        }
                    254: 
                    255:        provider->configWrite32(PIIX_PCI_UDMACTL, udmaControl);
                    256:        provider->configWrite32(PIIX_PCI_IDETIM,  timing.b32);
                    257: 
                    258:        PIIX_UNLOCK;
                    259: 
                    260:        return true;
                    261: }
                    262: 
                    263: //--------------------------------------------------------------------------
                    264: // Private function: _allocatePRDTable()
                    265: //
                    266: // Allocate the physical region descriptor (PRD) table. The physical
                    267: // address of this table is stored in 'prdTablePhys'. Look at Intel
                    268: // documentation for the alignment requirements.
                    269: //
                    270: bool AppleATAPIIX::_allocatePRDTable()
                    271: {
                    272:        prdTable = (prdEntry_t *) IOMallocAligned(PRD_TABLE_SIZE, PAGE_SIZE);
                    273:        if (!prdTable)
                    274:                return false;
                    275: 
                    276:        prdTablePhys = (UInt32) pmap_extract(kernel_pmap, (vm_offset_t) prdTable);
                    277: 
                    278:        bzero(prdTable, PRD_TABLE_SIZE);
                    279: 
                    280:        return true;
                    281: }
                    282: 
                    283: //--------------------------------------------------------------------------
                    284: // Private function: _deallocatePRDTable()
                    285: //
                    286: void AppleATAPIIX::_deallocatePRDTable()
                    287: {
                    288:        IOFreeAligned(prdTable, PRD_TABLE_SIZE);
                    289:        prdTable = NULL;
                    290:        prdTablePhys = 0;
                    291: }
                    292: 
                    293: //--------------------------------------------------------------------------
                    294: // Function inherited from IOATAController.
                    295: //
                    296: // Configure the driver/controller. This is the first function called by
                    297: // our superclass, in its start() function, to initialize the controller
                    298: // hardware.
                    299: //
                    300: bool
                    301: AppleATAPIIX::configure(IOService * forProvider,
                    302:                         UInt32 *    controllerDataSize)
                    303: {
                    304:        UInt32  reg;
                    305: 
                    306: //     IOSleep(1000);
                    307: 
                    308:     *controllerDataSize = 0;
                    309: 
                    310:     provider = OSDynamicCast(IOPCIDevice, forProvider);
                    311:        if (!provider)
                    312:                return false;
                    313:        
                    314:        // Superclass performs an exclusive open on the provider, we close
                    315:        // it to allow more than one instance of this driver to attach to
                    316:        // the same PCI nub. We should maintain an non-exclusive open on
                    317:        // the provider.
                    318:        //
                    319:        provider->close(this);
                    320: 
                    321:        // Determine the type of PIIX controller. Save the controller's
                    322:        // PCI ID in pciCFID.
                    323:        //
                    324:        pciCFID = provider->configRead32(PIIX_PCI_CFID);
                    325:        if (PIIXVerifyID(pciCFID) == false) {
                    326:                IOLog("%s: Unknown PCI IDE controller (0x%08lx)\n",
                    327:               getName(),
                    328:               pciCFID);
                    329:                return false;
                    330:        }
                    331: 
                    332:        // Determine our IDE channel, primary or secondary.
                    333:        //
                    334:        channel = PIIXGetChannel(provider);
                    335: 
                    336:        _getIDERanges(provider);
                    337: 
                    338:        IOLog("%s: %s %s IDE controller, 0x%x, irq %d\n",
                    339:                getName(),
                    340:                (channel == PIIX_CHANNEL_PRIMARY) ? "Primary" : "Secondary",
                    341:                PIIXGetName(pciCFID),
                    342:                ioCmdRange,
                    343:                (channel == PIIX_CHANNEL_PRIMARY) ? PIIX_P_IRQ : PIIX_S_IRQ);
                    344: 
                    345:        // Check the I/O Space Enable bit in the PCI command register.
                    346:        // This is the master enable bit for the PIIX controller.
                    347:        // Each IDE channel also has its own enable bit, which is
                    348:        // checked later.
                    349:        //
                    350:        reg = provider->configRead32(PIIX_PCI_PCICMD);
                    351:        if ((reg & PIIX_PCI_PCICMD_IOSE) == 0) {
                    352:                IOLog("%s: PCI IDE controller is not enabled\n", getName());
                    353:                return false;
                    354:        }
                    355: 
                    356:        // Set BME bit to enable bus-master.
                    357:        //
                    358:        if ((reg & PIIX_PCI_PCICMD_BME) == 0) {
                    359:                reg |= PIIX_PCI_PCICMD_BME;
                    360:                PIIX_LOCK;
                    361:                provider->configWrite32(PIIX_PCI_PCICMD, reg);
                    362:                PIIX_UNLOCK;
                    363:        }
                    364: 
                    365:        // Fetch the corresponding primary/secondary IDETIM register and
                    366:        // check the individual channel enable bit.
                    367:        //
                    368:        reg = provider->configRead32(PIIX_PCI_IDETIM);
                    369:        if (channel == PIIX_CHANNEL_SECONDARY)
                    370:                reg >>= 16;             // PIIX_PCI_IDETIM + 2 for secondary channel
                    371: 
                    372:        if ((reg & PIIX_PCI_IDETIM_IDE) == 0) {
                    373:                IOLog("%s: %s PCI IDE channel is not enabled\n",
                    374:                        getName(),
                    375:                        (channel == PIIX_CHANNEL_PRIMARY) ? "Primary" : "Secondary");
                    376:                return false;
                    377:        }
                    378: 
                    379:        // Locate and add the I/O mapped bus-master registers to
                    380:        // ioRange[] array.
                    381:        //
                    382:        if (_getBMRange(provider) == false) {
                    383:                IOLog("%s: Bus master I/O range is invalid\n", getName());
                    384:                return false;
                    385:        }
                    386: 
                    387:        // Allocate page-aligned memory for the PRD table.
                    388:        //
                    389:        if (_allocatePRDTable() == false) {
                    390:                IOLog("%s: unable to allocate descriptor table\n", getName());
                    391:                return false;
                    392:        }
                    393: 
                    394:        // Allocate a cursor object to generate the scatter-gather list
                    395:        // for each transfer request. Maximum segment size is set to 64K.
                    396:        // However, there is no way to indicate our requirement that each
                    397:        // memory segment cannot cross a 64K boundary. We have to do this
                    398:        // manually.
                    399:        //
                    400:     prdCursor = IOLittleMemoryCursor::withSpecification(64 * 1024, 0xffffffff);
                    401:     if (prdCursor == 0)
                    402:         return false;
                    403: 
                    404:        // Revert to default (compatible) timing.
                    405:        //
                    406:        _resetTimings();
                    407: 
                    408:        DLOG("AppleATAPIIX::%s() completed successfully\n", __FUNCTION__);
                    409: 
                    410:     return true;
                    411: }
                    412: 
                    413: //--------------------------------------------------------------------------
                    414: // Function inherited from IOATAController.
                    415: //
                    416: // Create a workloop and attach various event sources to the newly created 
                    417: // workloop.
                    418: //
                    419: bool AppleATAPIIX::createWorkLoop(IOWorkLoop ** workLoop)
                    420: {
                    421:     if (super::createWorkLoop(workLoop) != true)
                    422:         return false;
                    423: 
                    424:     interruptEventSource = IOInterruptEventSource::interruptEventSource(
                    425:                      (OSObject *)             this,
                    426:                      (IOInterruptEventAction) &AppleATAPIIX::interruptOccurred,
                    427:                      (IOService *)            provider,
                    428:                      (channel == PIIX_CHANNEL_PRIMARY) ? 0 : 1);
                    429:     if (interruptEventSource == 0) {
                    430:                IOLog("%s: unable to create an IOInterruptEventSource object\n",
                    431:                          getName());
                    432:         return false;
                    433:        }
                    434: 
                    435:        disableControllerInterrupts();
                    436: 
                    437:     (*workLoop)->addEventSource(interruptEventSource); 
                    438: 
                    439:     timerEventSource = IOTimerEventSource::timerEventSource(
                    440:                           this,
                    441:                           (IOTimerEventSource::Action) &AppleATAPIIX::ataTimer);
                    442:     if (timerEventSource == 0)
                    443:         return false;
                    444: 
                    445:     (*workLoop)->addEventSource(timerEventSource); 
                    446:  
                    447:        ataTimer(timerEventSource); 
                    448: 
                    449:        DLOG("AppleATAPIIX::%s() completed successfully\n", __FUNCTION__);
                    450: 
                    451:     return true;
                    452: }
                    453: 
                    454: //--------------------------------------------------------------------------
                    455: //
                    456: //
                    457: bool AppleATAPIIX::provideProtocols(enum ATAProtocol * protocolsSupported)
                    458: {
                    459:     return false;
                    460: }
                    461: 
                    462: //--------------------------------------------------------------------------
                    463: //
                    464: //
                    465: bool AppleATAPIIX::provideTimings(UInt32 *    numTimings,
                    466:                                   ATATiming * timingsSupported)
                    467: {
                    468:     return false;
                    469: }
                    470: 
                    471: //--------------------------------------------------------------------------
                    472: // Determine the timing selection based on the ATATiming structure given.
                    473: //
                    474: bool AppleATAPIIX::calculateTiming(UInt32 unit, ATATiming * pTiming)
                    475: {
                    476:        int           i;
                    477:        PIIXProtocol  protocol = ataToPIIXProtocol(pTiming->timingProtocol);
                    478: 
                    479:        DLOG("AppleATAPIIX::%s() - unit:%ld protocol:%d minCycles:%ld\n",
                    480:                 __FUNCTION__, unit, protocol, pTiming->minDataCycle);
                    481: 
                    482:        CHECK_UNIT(unit);
                    483: 
                    484:        timings[unit].validTimings[protocol] = 0;
                    485: 
                    486:        switch (protocol) {
                    487: 
                    488:                case kPIIXProtocolPIO:
                    489: 
                    490:                        for (i = 0; i < PIIXPIOTimingTableSize; i++)
                    491:                        {
                    492:                                if (PIIXPIOTimingTable[i].pioMode == _NVM_)
                    493:                                        continue;
                    494: 
                    495:                                if (PIIXPIOTimingTable[i].cycle < pTiming->minDataCycle)
                    496:                                        break;
                    497: 
                    498:                                timings[unit].validTimings[protocol] = i;
                    499:                        }
                    500:                        break;
                    501: 
                    502:                case kPIIXProtocolDMA:
                    503: 
                    504:                        for (i = 0; i < PIIXPIOTimingTableSize; i++)
                    505:                        {
                    506:                                if (PIIXPIOTimingTable[i].mwDMAMode == _NVM_)
                    507:                                        continue;
                    508: 
                    509:                                if (PIIXPIOTimingTable[i].cycle < pTiming->minDataCycle)
                    510:                                        break;
                    511: 
                    512:                                timings[unit].validTimings[protocol] = i;
                    513:                        }
                    514:                        break;
                    515:                
                    516:                case kPIIXProtocolUDMA33:
                    517:                        
                    518:                        for (i = 0; i < PIIXUDMATimingTableSize; i++)
                    519:                        {
                    520:                                if (PIIXUDMATimingTable[i].strobe < pTiming->minDataCycle)
                    521:                                        break;
                    522:                        
                    523:                                timings[unit].validTimings[protocol] = i;
                    524:                        }
                    525:                        break;
                    526:                
                    527:                default:
                    528:                        return false;
                    529:        }
                    530: 
                    531:        timings[unit].validFlag |= (1 << protocol);
                    532: 
                    533:        return true;
                    534: }
                    535: 
                    536: //--------------------------------------------------------------------------
                    537: // Setup the timing register for the given timing protocol.
                    538: //
                    539: bool AppleATAPIIX::selectTiming(UInt32            unit,
                    540:                                 ATATimingProtocol timingProtocol)
                    541: {
                    542:        bool          ret = false;
                    543:        UInt8         pciConfig[256];
                    544:        PIIXProtocol  protocol = ataToPIIXProtocol(timingProtocol);
                    545: 
                    546:        DLOG("AppleATAPIIX::%s() - unit:%ld protocol:%d\n",
                    547:                 __FUNCTION__, unit, protocol);
                    548: 
                    549:        CHECK_UNIT(unit);
                    550: 
                    551:        PIIX_LOCK;
                    552: 
                    553:        do {
                    554:                if (protocol >= kPIIXProtocolLast)
                    555:                        break;
                    556:                
                    557:                if (PIIX_PROTOCOL_IS_VALID(protocol) == 0) {
                    558:                        
                    559:                        // superclass error, calculateTiming() was not called
                    560:                        // before calling selectTiming().
                    561:                        
                    562:                        IOLog("%s: timing protocol selected is invalid\n", getName());
                    563:                        break;
                    564:                }
                    565: 
                    566:                if (!_readPCIConfigSpace(pciConfig) ||
                    567:                        !_selectTiming(unit, protocol, pciConfig) ||
                    568:                        !_writePCIConfigSpace(pciConfig))
                    569:                        break;
                    570: 
                    571:                ret = true;
                    572:        }
                    573:        while (0);
                    574: 
                    575:        PIIX_UNLOCK;
                    576: 
                    577:        return ret;
                    578: }
                    579: 
                    580: //--------------------------------------------------------------------------
                    581: // Setup the timing registers.
                    582: //
                    583: bool AppleATAPIIX::_selectTiming(UInt32         unit,
                    584:                                  PIIXProtocol   protocol,
                    585:                                                                 UInt8 *        pciConfig)
                    586: {
                    587:        UInt8     isp, rtc;
                    588:        UInt8     index, dma, pio;
                    589:        bool      dmaActive;
                    590:        bool      pioActive;
                    591:        bool      useCompatiblePIOTiming = false;
                    592:        bool      ret = true;
                    593:        UInt16 *  idetim;
                    594:        UInt8 *   sidetim = (UInt8 *)  &pciConfig[PIIX_PCI_SIDETIM];
                    595:        UInt8 *   udmactl = (UInt8 *)  &pciConfig[PIIX_PCI_UDMACTL];
                    596:        UInt16 *  udmatim = (UInt16 *) &pciConfig[PIIX_PCI_UDMATIM];
                    597: 
                    598:        idetim = (channel == PIIX_CHANNEL_PRIMARY) ? 
                    599:              (UInt16 *) &pciConfig[PIIX_PCI_IDETIM] :
                    600:                         (UInt16 *) &pciConfig[PIIX_PCI_IDETIM_S];
                    601: 
                    602:        switch (protocol) {
                    603:                case kPIIXProtocolUDMA66:
                    604:                        // Not yet!
                    605:                        return false;
                    606: 
                    607:                case kPIIXProtocolUDMA33:
                    608:                        if ((pciCFID == PCI_ID_PIIX) || (pciCFID == PCI_ID_PIIX3)) {
                    609:                                // Only PIIX4 (and newer devices) supports UDMA.
                    610:                                return false;
                    611:                        }
                    612:                        PIIX_DEACTIVATE_PROTOCOL(kPIIXProtocolDMA);
                    613:                        break;
                    614: 
                    615:                case kPIIXProtocolDMA:
                    616:                        PIIX_DEACTIVATE_PROTOCOL(kPIIXProtocolUDMA33);
                    617:                        break;
                    618: 
                    619:                case kPIIXProtocolPIO:
                    620:                        break;
                    621: 
                    622:                default:
                    623:                        IOLog("%s: PIIX protocol not handled (%d)\n", getName(),
                    624:                                  protocol);
                    625:                        return false;
                    626:        }
                    627:        PIIX_ACTIVATE_PROTOCOL(protocol);
                    628: 
                    629: 
                    630:        if (PIIX_PROTOCOL_IS_ACTIVE(kPIIXProtocolUDMA33)) {
                    631: 
                    632:                index = PIIX_GET_ACTIVE_TIMING(kPIIXProtocolUDMA33);
                    633: 
                    634:                if (unit == 0) {
                    635:                        if (channel == PIIX_CHANNEL_PRIMARY) {
                    636:                                *udmactl |= PIIX_PCI_UDMACTL_PSDE0;
                    637:                                SET_REG_FIELD(*udmatim, PIIX_PCI_UDMATIM_PCT0,
                    638:                                                                PIIXUDMATimingTable[index].bits);
                    639:                        }
                    640:                        else {
                    641:                                *udmactl |= PIIX_PCI_UDMACTL_SSDE0;
                    642:                                SET_REG_FIELD(*udmatim, PIIX_PCI_UDMATIM_SCT0,
                    643:                                                                PIIXUDMATimingTable[index].bits);
                    644:                        }
                    645:                }
                    646:                else {
                    647:                        if (channel == PIIX_CHANNEL_PRIMARY) {
                    648:                                *udmactl |= PIIX_PCI_UDMACTL_PSDE1;
                    649:                                SET_REG_FIELD(*udmatim, PIIX_PCI_UDMATIM_PCT1,
                    650:                                                                PIIXUDMATimingTable[index].bits);
                    651:                        }
                    652:                        else {
                    653:                                *udmactl |= PIIX_PCI_UDMACTL_SSDE1;
                    654:                                SET_REG_FIELD(*udmatim, PIIX_PCI_UDMATIM_SCT1,
                    655:                                                                PIIXUDMATimingTable[index].bits);
                    656:                        }
                    657:                }
                    658:        }
                    659:        else {
                    660:                if (unit == 0) {
                    661:                        if (channel == PIIX_CHANNEL_PRIMARY) {
                    662:                                *udmactl &= ~PIIX_PCI_UDMACTL_PSDE0;
                    663:                        }
                    664:                        else {
                    665:                                *udmactl &= ~PIIX_PCI_UDMACTL_SSDE0;
                    666:                        }
                    667:                }
                    668:                else {
                    669:                        if (channel == PIIX_CHANNEL_PRIMARY) {
                    670:                                *udmactl &= ~PIIX_PCI_UDMACTL_PSDE1;
                    671:                        }
                    672:                        else {
                    673:                                *udmactl &= ~PIIX_PCI_UDMACTL_SSDE1;
                    674:                        }
                    675:                }
                    676:        }
                    677: 
                    678:        dmaActive = PIIX_PROTOCOL_IS_ACTIVE(kPIIXProtocolDMA);
                    679:        pioActive = PIIX_PROTOCOL_IS_ACTIVE(kPIIXProtocolPIO);
                    680:                
                    681:        if (dmaActive || pioActive) {
                    682: 
                    683:                dma = PIIX_GET_ACTIVE_TIMING(kPIIXProtocolDMA);
                    684:                pio = PIIX_GET_ACTIVE_TIMING(kPIIXProtocolPIO);
                    685: 
                    686:                // Early PIIX devices does not have a slave timing register.
                    687:                // Rather than switching timing registers whenever a new
                    688:                // drive was selected, We program in a (slower) timing that
                    689:                // is acceptable for both drive0 and drive1.
                    690: 
                    691:                if (pciCFID == PCI_ID_PIIX) {
                    692: 
                    693:                        unit = (unit ^ 1) & 1;          // unit <- other drive unit
                    694: 
                    695:                        if (PIIX_PROTOCOL_IS_ACTIVE(kPIIXProtocolPIO)) {
                    696:                                if (!pioActive || 
                    697:                                        (PIIX_GET_ACTIVE_TIMING(kPIIXProtocolPIO) < pio)) {
                    698:                                        pio = PIIX_GET_ACTIVE_TIMING(kPIIXProtocolPIO);
                    699:                                }
                    700:                                pioActive = true;
                    701:                        }
                    702: 
                    703:                        if (PIIX_PROTOCOL_IS_ACTIVE(kPIIXProtocolDMA)) {
                    704:                                if (!dmaActive ||
                    705:                                        (PIIX_GET_ACTIVE_TIMING(kPIIXProtocolDMA) < dma)) {
                    706:                                        dma = PIIX_GET_ACTIVE_TIMING(kPIIXProtocolDMA);
                    707:                                }
                    708:                                dmaActive = true;
                    709:                        }
                    710: 
                    711:                        *idetim &= ~PIIX_PCI_IDETIM_SITRE;      // disable slave timing
                    712:                        unit = 0;
                    713:                }
                    714:                else {
                    715:                        *idetim |= PIIX_PCI_IDETIM_SITRE;       // enable slave timing
                    716:                }
                    717: 
                    718:                // Pick an index to the PIIXPIOTimingTable[] for the new
                    719:                // timing selection.
                    720:                //
                    721:                if (dmaActive && pioActive) {
                    722: 
                    723:                        // Both PIO and DMA are active, select DMA timing to
                    724:                        // optimize DMA transfer.
                    725: 
                    726:                        index = dma;            // pick DMA timing
                    727: 
                    728:                        if (pio < dma)
                    729:                                useCompatiblePIOTiming = true;
                    730:                }
                    731:                else if (dmaActive) {
                    732:                        index = dma;
                    733:                }
                    734:                else {
                    735:                        index = pio;
                    736:                }
                    737: 
                    738:                isp = PIIX_CLK_TO_ISP(PIIXPIOTimingTable[index].isp);
                    739:                rtc = PIIX_CLK_TO_RTC(PIIXPIOTimingTable[index].rtc);
                    740: 
                    741:                if (unit == 0) {
                    742:                        SET_REG_FIELD(*idetim, PIIX_PCI_IDETIM_ISP, isp);
                    743:                        SET_REG_FIELD(*idetim, PIIX_PCI_IDETIM_RTC, rtc);
                    744:                        if (useCompatiblePIOTiming)
                    745:                                *idetim |= PIIX_PCI_IDETIM_DTE0;
                    746:                        else
                    747:                                *idetim &= ~PIIX_PCI_IDETIM_DTE0;
                    748:                        
                    749:                        if (pciCFID == PCI_ID_PIIX) {
                    750:                                if (useCompatiblePIOTiming)
                    751:                                        *idetim |= PIIX_PCI_IDETIM_DTE1;
                    752:                                else
                    753:                                        *idetim &= ~PIIX_PCI_IDETIM_DTE1;
                    754:                        }
                    755:                }
                    756:                else {
                    757:                        if (channel == PIIX_CHANNEL_PRIMARY) {
                    758:                                SET_REG_FIELD(*sidetim, PIIX_PCI_SIDETIM_PISP1, isp);
                    759:                                SET_REG_FIELD(*sidetim, PIIX_PCI_SIDETIM_PRTC1, rtc);
                    760:                        }
                    761:                        else {
                    762:                                SET_REG_FIELD(*sidetim, PIIX_PCI_SIDETIM_SISP1, isp);
                    763:                                SET_REG_FIELD(*sidetim, PIIX_PCI_SIDETIM_SRTC1, rtc);
                    764:                        }
                    765:                        if (useCompatiblePIOTiming)
                    766:                                *idetim |= PIIX_PCI_IDETIM_DTE1;
                    767:                        else
                    768:                                *idetim &= ~PIIX_PCI_IDETIM_DTE1;
                    769:                }
                    770: 
                    771:                *idetim |= (PIIX_PCI_IDETIM_TIME0 |
                    772:                                        PIIX_PCI_IDETIM_PPE0  | 
                    773:                                        PIIX_PCI_IDETIM_IE0   |
                    774:                                        PIIX_PCI_IDETIM_TIME1 |
                    775:                                        PIIX_PCI_IDETIM_PPE1  | 
                    776:                                        PIIX_PCI_IDETIM_IE1);
                    777:        }
                    778: 
                    779: #ifdef DEBUG_XXX
                    780:        IOLog("\n%s: %s channel\n", getName(), 
                    781:                  (channel == PIIX_CHANNEL_PRIMARY) ? "Primary" : "Secondary");
                    782:        IOLog("%s: IDETIM : %04x\n", getName(), *idetim);
                    783:        IOLog("%s: SIDETIM: %02x\n", getName(), *sidetim);
                    784:        IOLog("%s: UDMACTL: %02x\n", getName(), *udmactl);
                    785:        IOLog("%s: UDMATIM: %04x\n", getName(), *udmatim);
                    786:        IOLog("%s: Active : %04lx\n", getName(), timings[unit].activeFlag);
                    787:        IOLog("%s: Valid  : %04lx\n", getName(), timings[unit].validFlag);
                    788:        IOLog("%s: PIO:%d DMA:%d UDMA:%d\n\n", getName(),
                    789:                timings[unit].activeTimings[kPIIXProtocolPIO],
                    790:                timings[unit].activeTimings[kPIIXProtocolDMA],
                    791:                timings[unit].activeTimings[kPIIXProtocolUDMA33]);
                    792: #endif /* DEBUG */
                    793: 
                    794:        return ret;
                    795: }
                    796: 
                    797: //--------------------------------------------------------------------------
                    798: // Setup the descriptor table to perform the transfer indicated by the
                    799: // IOMemoryDescriptor in the IOATACommand object provided.
                    800: //
                    801: bool AppleATAPIIX::programDma(IOATACommand * cmd)
                    802: {
                    803:     IOPhysicalSegment       physSeg;
                    804:     IOByteCount                                offset = 0;
                    805:     IOMemoryDescriptor *       memDesc;
                    806:        prdEntry_t *            prd = prdTable;
                    807:     UInt32                                     startSeg;
                    808:        UInt32                  endSeg;
                    809:        UInt32                  partialCount;
                    810:     UInt32                                     bytesLeft;
                    811: 
                    812:     cmd->getPointers(&memDesc, &dmaReqLength, &dmaIsWrite);
                    813: 
                    814:     if (dmaReqLength == 0)
                    815:         return true;
                    816: 
                    817:        bytesLeft = dmaReqLength;
                    818: 
                    819:        // Setup the PRD entries in the descriptor table in memory.
                    820:        //
                    821:     for (UInt32 i = 0; i < (PRD_ENTRIES - 1); i++, prd++)
                    822:        {
                    823:                if (prdCursor->getPhysicalSegments(memDesc, offset, &physSeg, 1) != 1)
                    824:                        break;
                    825:                
                    826:                startSeg = (physSeg.location & ~0xffff);
                    827:                endSeg   = (physSeg.location + physSeg.length - 1) & ~0xffff;
                    828:                
                    829:                prd->base  = physSeg.location;
                    830:                prd->flags = 0;
                    831:                
                    832:                if (startSeg == endSeg) {                       
                    833:                        prd->count = PRD_COUNT(physSeg.length);
                    834:                }
                    835:                else {
                    836:                        partialCount = (-physSeg.location & 0xffff);
                    837:                        prd->count = PRD_COUNT(partialCount);
                    838:                        prd++;
                    839:                        i++;
                    840:                        prd->base  = physSeg.location + partialCount;
                    841:                        prd->count = physSeg.length - partialCount;
                    842:                        prd->flags = 0;
                    843:                }
                    844:                
                    845:                bytesLeft -= physSeg.length;
                    846:                offset += physSeg.length;
                    847:        }
                    848:        if (bytesLeft != 0)
                    849:                return false;
                    850:        
                    851:        // Set the 'end-of-table' bit on the last PRD entry.
                    852:        //
                    853:        prd--;
                    854:        prd->flags = PRD_FLAG_EOT;
                    855: 
                    856:        /*
                    857:         * Provide the starting address of the PRD table by loading the
                    858:         * PRD Table Pointer Register.
                    859:         */
                    860:        outl(IOREG(BMIDTPX), prdTablePhys);
                    861: 
                    862:        return true;
                    863: }
                    864: 
                    865: //--------------------------------------------------------------------------
                    866: // Start the DMA engine.
                    867: //
                    868: bool AppleATAPIIX::startDma(IOATACommand * cmd)
                    869: {
                    870:        /*
                    871:         * Clear interrupt and error bits in the Status Register.
                    872:         */
                    873:        outb(IOREG(BMISX), PIIX_IO_BMISX_ERROR   |
                    874:                        PIIX_IO_BMISX_IDEINTS |
                    875:                                           PIIX_IO_BMISX_DMA0CAP |
                    876:                                           PIIX_IO_BMISX_DMA1CAP);
                    877: 
                    878:        /*
                    879:         * Engage the bus master by writing 1 to the start bit in the
                    880:         * Command Register. Also set the RWCON bit for the direction
                    881:         * of the data transfer.
                    882:         */
                    883:        outb(IOREG(BMICX), (dmaIsWrite ? 0 : PIIX_IO_BMICX_RWCON) | 
                    884:                           PIIX_IO_BMICX_SSBM);
                    885: 
                    886:        return true;
                    887: }
                    888: 
                    889: //--------------------------------------------------------------------------
                    890: // Stop the DMA engine.
                    891: //
                    892: bool AppleATAPIIX::stopDma(IOATACommand * cmd, UInt32 * transferCount)
                    893: {
                    894:        UInt8  bmisx;
                    895: 
                    896:        *transferCount = 0;
                    897:        
                    898:     if (dmaReqLength == 0)
                    899:         return true;
                    900: 
                    901:        outb(IOREG(BMICX), 0);  // stop the bus-master
                    902: 
                    903:        bmisx = inb(IOREG(BMISX));
                    904: 
                    905:        if ((bmisx & PIIX_IO_BMISX_STATUS) != PIIX_IO_BMISX_IDEINTS) {
                    906:                IOLog("AppleATAPIIX::%s() DMA error (0x%02x)\n", __FUNCTION__, bmisx);
                    907:                return false;
                    908:        }
                    909: 
                    910:        *transferCount = dmaReqLength;
                    911: 
                    912:        return true;
                    913: }
                    914: 
                    915: //--------------------------------------------------------------------------
                    916: //
                    917: //
                    918: void AppleATAPIIX::ataTimer( IOTimerEventSource * /* sender */ )
                    919: {
                    920:     UInt32             transferCount;
                    921: 
                    922:     if ( xferCmdTimer != 0 )
                    923:     {
                    924:         if ( --xferCmdTimer == 0 )
                    925:         {
                    926:             IOLog("AppleATAPIIX::%s() - Timeout occurred\n\r", __FUNCTION__ );
                    927:            
                    928:             stopDma( xferCmd, &transferCount ); 
                    929: 
                    930:             resetBusRequest();
                    931: 
                    932:             if ( xferCmdSave != NULL )
                    933:             {
                    934:                 xferCmd     = xferCmdSave;
                    935:                 xferCmdSave = NULL;
                    936:             }
                    937:             completeCmd( xferCmd, ataReturnErrorInterruptTimeout );
                    938:         }
                    939:     }
                    940: 
                    941:     timerEventSource->setTimeoutMS(ATATimerIntervalmS);
                    942: }
                    943: 
                    944: //--------------------------------------------------------------------------
                    945: // Perform a write to the ATA block registers.
                    946: //
                    947: void AppleATAPIIX::writeATAReg(UInt32 regIndex, UInt32 regValue)
                    948: {
                    949:     if (regIndex == 0) {
                    950:                outw(ioCmdRange, (UInt16) regValue);
                    951:     }
                    952:     else if (regIndex < ataRegDeviceControl) {
                    953:                outb(ioCmdRange + regIndex, (UInt8) regValue);
                    954:     }     
                    955:     else {
                    956:                outb(ioCtlRange + regIndex - ataRegDeviceControl + 2, 
                    957:                     (UInt8) regValue);
                    958:     }
                    959: }
                    960: 
                    961: //--------------------------------------------------------------------------
                    962: // Perform a read from the ATA block registers.
                    963: //
                    964: UInt32 AppleATAPIIX::readATAReg( UInt32 regIndex )
                    965: {
                    966:     if (regIndex == 0) {
                    967:                return inw(ioCmdRange);
                    968:     }
                    969:     else if (regIndex < ataRegDeviceControl) {
                    970:                return inb(ioCmdRange + regIndex);
                    971:     }
                    972:        return inb(ioCtlRange + regIndex - ataRegDeviceControl + 2);
                    973: }
                    974: 
                    975: //--------------------------------------------------------------------------
                    976: // Frees the drivers instance. Make sure all objects allocated during
                    977: // our initialization are freed.
                    978: //
                    979: void AppleATAPIIX::free()
                    980: {
                    981:     if (interruptEventSource) {
                    982:         interruptEventSource->disable();
                    983:         interruptEventSource->release();
                    984:     }
                    985:   
                    986:     if (timerEventSource)
                    987:         timerEventSource->release();
                    988:        
                    989:        if (prdCursor)
                    990:                prdCursor->release();
                    991:  
                    992:     if (prdTable != 0)
                    993:                _deallocatePRDTable();
                    994:        
                    995:        return super::free();
                    996: }
                    997: 
                    998: //--------------------------------------------------------------------------
                    999: // This function is called when our interruptEventSource receives an
                   1000: // interrupt. Simply pass the action to our superclass to advance its
                   1001: // state machine.
                   1002: //
                   1003: void AppleATAPIIX::interruptOccurred()
                   1004: {
                   1005:     super::interruptOccurred();
                   1006: }
                   1007: 
                   1008: //--------------------------------------------------------------------------
                   1009: // This function is called by our superclass to disable controller
                   1010: // interrupts.
                   1011: //
                   1012: void AppleATAPIIX::disableControllerInterrupts()
                   1013: {
                   1014:     interruptEventSource->disable();
                   1015: }
                   1016: 
                   1017: //--------------------------------------------------------------------------
                   1018: // This function is called by our superclass to enable controller
                   1019: // interrupts.
                   1020: //
                   1021: void AppleATAPIIX::enableControllerInterrupts()
                   1022: {
                   1023:     interruptEventSource->enable();
                   1024: }
                   1025: 
                   1026: //--------------------------------------------------------------------------
                   1027: // Private function: _readPCIConfigSpace
                   1028: //
                   1029: // Read the entire PCI config space and stores it to the buffer
                   1030: // pointed by 'configSpace'.
                   1031: //
                   1032: bool AppleATAPIIX::_readPCIConfigSpace(UInt8 * configSpace)
                   1033: {
                   1034:        UInt32 * dwordPtr = (UInt32 *) configSpace;
                   1035: 
                   1036:        for (int i = 0; i < 64; i++, dwordPtr++)
                   1037:                *dwordPtr = provider->configRead32(i * 4);
                   1038: 
                   1039:        return true;
                   1040: }
                   1041: 
                   1042: //--------------------------------------------------------------------------
                   1043: // Private function: _writePCIConfigSpace
                   1044: //
                   1045: // Write the entire PCI config space from the buffer pointed
                   1046: // by 'configSpace'.
                   1047: //
                   1048: bool AppleATAPIIX::_writePCIConfigSpace(UInt8 * configSpace)
                   1049: {
                   1050:        UInt32 * dwordPtr = (UInt32 *) configSpace;
                   1051: 
                   1052:        for (int i = 0; i < 64; i++, dwordPtr++)
                   1053:                provider->configWrite32(i * 4, *dwordPtr);
                   1054: 
                   1055:        return true;
                   1056: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.