Annotation of XNU/iokit/Families/IOATAHDDrive/IOATAHDCommand.cpp, revision 1.1

1.1     ! root        1: /*
        !             2:  * Copyright (c) 1998-2000 Apple Computer, Inc. All rights reserved.
        !             3:  *
        !             4:  * @APPLE_LICENSE_HEADER_START@
        !             5:  * 
        !             6:  * The contents of this file constitute Original Code as defined in and
        !             7:  * are subject to the Apple Public Source License Version 1.1 (the
        !             8:  * "License").  You may not use this file except in compliance with the
        !             9:  * License.  Please obtain a copy of the License at
        !            10:  * http://www.apple.com/publicsource and read it before using this file.
        !            11:  * 
        !            12:  * This Original Code and all software distributed under the License are
        !            13:  * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
        !            14:  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
        !            15:  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
        !            16:  * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
        !            17:  * License for the specific language governing rights and limitations
        !            18:  * under the License.
        !            19:  * 
        !            20:  * @APPLE_LICENSE_HEADER_END@
        !            21:  */
        !            22: /*
        !            23:  * Copyright (c) 1999 Apple Computer, Inc.  All rights reserved. 
        !            24:  *
        !            25:  * IOATAHDCommand.cpp - Performs ATA command processing.
        !            26:  *
        !            27:  * HISTORY
        !            28:  * Aug 27, 1999        jliu - Ported from AppleATADrive.
        !            29:  */
        !            30: 
        !            31: #include <IOKit/assert.h>
        !            32: #include <IOKit/IOSyncer.h>
        !            33: #include <IOKit/storage/ata/IOATAHDDrive.h>
        !            34: 
        !            35: // Enable this define to generate debugging messages.
        !            36: // #define DEBUG_LOG 1
        !            37: 
        !            38: // --------------------------------------------------------------------------
        !            39: // Set the device timings.
        !            40: 
        !            41: bool
        !            42: IOATAHDDrive::selectTimingProtocol(ATATimingProtocol protocol)
        !            43: {
        !            44:        bool                            ret;
        !            45:        UInt8                           ataReadCmd;
        !            46:        UInt8                           ataWriteCmd;
        !            47:        
        !            48:        if (protocol >= ataMaxTimings)
        !            49:        {
        !            50:                // If protocol override is invalid, get the list of supported timing
        !            51:                // protocols from the device, and use the 'best' one. If the device
        !            52:                // cannot report the available protocols, default to PIO mode.
        !            53:        
        !            54:                ret = _ataDevice->getTimingsSupported(&protocol);
        !            55:                if (!ret)
        !            56:                {
        !            57:                        IOLog("%s: getTimingsSupported() error\n", getName());
        !            58:                        protocol = ataTimingPIO;
        !            59:                }
        !            60:        }
        !            61: 
        !            62:        // IOLog("%s: timing protocols: %08x\n", getName(), protocol);
        !            63:        
        !            64:        if (protocol & (ataTimingUltraDMA66 | ataTimingUltraDMA33 | ataTimingDMA)) 
        !            65:        {
        !            66:                if (protocol & ataTimingUltraDMA66)
        !            67:                {
        !            68:                        IOLog("%s: Using U-DMA/66 transfers\n", getName());
        !            69:                        protocol = ataTimingUltraDMA66;
        !            70:                }
        !            71:                else if (protocol & ataTimingUltraDMA33)
        !            72:                {
        !            73:                        IOLog("%s: Using U-DMA/33 transfers\n", getName());
        !            74:                        protocol = ataTimingUltraDMA33;
        !            75:                }
        !            76:                else
        !            77:                {
        !            78:                        IOLog("%s: Using DMA transfers\n", getName());
        !            79:                        protocol = ataTimingDMA;
        !            80:                }
        !            81: 
        !            82:                ataReadCmd  = kIOATACommandReadDMA;
        !            83:                ataWriteCmd = kIOATACommandWriteDMA;            
        !            84:                selectCommandProtocol(true);
        !            85:        }
        !            86:        else
        !            87:        {
        !            88:                IOLog("%s: Using PIO transfers\n", getName());
        !            89:                protocol    = ataTimingPIO;
        !            90:                ataReadCmd  = kIOATACommandReadPIO;
        !            91:                ataWriteCmd = kIOATACommandWritePIO;
        !            92:                selectCommandProtocol(false);
        !            93:        }
        !            94: 
        !            95:        ret = _ataDevice->selectTiming(protocol);
        !            96:        if (!ret) {
        !            97:                IOLog("%s: selectTiming() failed\n", getName());
        !            98:        }
        !            99:        else {
        !           100:                _timingProtocol = protocol;
        !           101:                _ataReadCmd     = ataReadCmd;
        !           102:                _ataWriteCmd    = ataWriteCmd;
        !           103:        }
        !           104: 
        !           105:        return ret;
        !           106: }
        !           107: 
        !           108: // --------------------------------------------------------------------------
        !           109: // Returns the Command protocol to use (e.g. ataProtocolPIO, ataProtocolDMA).
        !           110: 
        !           111: void
        !           112: IOATAHDDrive::selectCommandProtocol(bool useDMA)
        !           113: {
        !           114:        if (useDMA)
        !           115:                _ataProtocol = ataProtocolDMA;
        !           116:        else
        !           117:                _ataProtocol = ataProtocolPIO;
        !           118: }
        !           119: 
        !           120: // --------------------------------------------------------------------------
        !           121: // Setup an ATATaskFile from the parameters given, and write the taskfile
        !           122: // to the ATATaskfile structure pointer provided.
        !           123: //
        !           124: // taskfile - pointer to a taskfile structure.
        !           125: // protocol - An ATA transfer protocol (ataProtocolPIO, ataProtocolDMA, etc)
        !           126: // command  - ATA command byte.
        !           127: // block    - Initial transfer block.
        !           128: // nblks    - Number of blocks to transfer.
        !           129: 
        !           130: void
        !           131: IOATAHDDrive::setupReadWriteTaskFile(ATATaskfile * taskfile,
        !           132:                                      ATAProtocol   protocol,
        !           133:                                      UInt8         command,
        !           134:                                      UInt32        block,
        !           135:                                      UInt32        nblks)
        !           136: {
        !           137:        taskfile->protocol = protocol;
        !           138: 
        !           139:        // Mask of all taskfile registers that shall contain valid
        !           140:        // data and should be written to the hardware registers.
        !           141:        //
        !           142:        taskfile->regmask  = ATARegtoMask(ataRegSectorNumber)   |
        !           143:                          ATARegtoMask(ataRegCylinderLow)       |
        !           144:                          ATARegtoMask(ataRegCylinderHigh)      |
        !           145:                                                 ATARegtoMask(ataRegDriveHead)          |
        !           146:                                                 ATARegtoMask(ataRegSectorCount)        |
        !           147:                                                 ATARegtoMask(ataRegCommand);
        !           148: 
        !           149:        taskfile->resultmask = 0;
        !           150: 
        !           151:        taskfile->ataRegs[ataRegSectorNumber] = block & 0x0ff;
        !           152:        taskfile->ataRegs[ataRegCylinderLow]  = (block >> 8) & 0xff;
        !           153:        taskfile->ataRegs[ataRegCylinderHigh] = (block >> 16) & 0xff;
        !           154:        taskfile->ataRegs[ataRegDriveHead]    = ((block >> 24) & 0x0f) |
        !           155:                                             ataModeLBA | (_unit << 4);  
        !           156:        taskfile->ataRegs[ataRegSectorCount]  = (nblks == kIOATAMaxBlocksPerXfer) ? 
        !           157:                                             0 : nblks;
        !           158:     taskfile->ataRegs[ataRegCommand]      = command;
        !           159: }
        !           160: 
        !           161: // --------------------------------------------------------------------------
        !           162: // Allocate and return an IOATACommand that is initialized to perform
        !           163: // a read/write operation.
        !           164: //
        !           165: // buffer   - IOMemoryDescriptor object describing this transfer.
        !           166: // block    - Initial transfer block.
        !           167: // nblks    - Number of blocks to transfer.
        !           168: 
        !           169: IOATACommand *
        !           170: IOATAHDDrive::ataCommandReadWrite(IOMemoryDescriptor * buffer,
        !           171:                                   UInt32               block,
        !           172:                                   UInt32               nblks)
        !           173: {
        !           174:        ATATaskfile taskfile;
        !           175:        bool        isWrite;
        !           176: 
        !           177:        assert(buffer);
        !           178: 
        !           179:        IOATACommand * cmd = allocateCommand();
        !           180:        if (!cmd) return 0;             // error, command allocation failed.
        !           181: 
        !           182:        isWrite = (buffer->getDirection() == kIODirectionOut) ?
        !           183:                  true : false;
        !           184: 
        !           185: #ifdef DEBUG_LOG
        !           186:        IOLog("%s: ataCommandReadWrite %08x (%d) %s %d %d\n",
        !           187:                getName(),
        !           188:                buffer,
        !           189:                buffer->getLength(),
        !           190:                isWrite ? "WR" : "RD",
        !           191:                block,
        !           192:                nblks);
        !           193: #endif
        !           194: 
        !           195: #if 0  // used for testing - force PIO mode
        !           196:        setupReadWriteTaskFile(&taskfile,
        !           197:                               ataProtocolPIO,
        !           198:                               isWrite ? kIOATACommandWritePIO : 
        !           199:                                                   kIOATACommandReadPIO,
        !           200:                               block,
        !           201:                               nblks);
        !           202: #else
        !           203: 
        !           204:        // Setup the taskfile structure with the size and direction of the
        !           205:        // transfer. This structure will be written to the actual taskfile
        !           206:        // registers when this command is processed.
        !           207:        //
        !           208:        setupReadWriteTaskFile(&taskfile,
        !           209:                               _ataProtocol,
        !           210:                               isWrite ? _ataWriteCmd : _ataReadCmd,
        !           211:                               block,
        !           212:                               nblks);
        !           213: #endif
        !           214: 
        !           215:        // Get a pointer to the client data buffer, and record parameters
        !           216:        // which shall be later used by the completion routine.
        !           217:        //
        !           218:        IOATAClientData * clientData = ATA_CLIENT_DATA(cmd);
        !           219:        assert(clientData);
        !           220: 
        !           221:        clientData->buffer  = buffer;
        !           222: 
        !           223:        cmd->setTaskfile(&taskfile);
        !           224: 
        !           225:        cmd->setPointers(buffer,                /* (IOMemoryDescriptor *) */
        !           226:                      buffer->getLength(),   /* transferCount (bytes) */
        !           227:                      isWrite);              /* isWrite */
        !           228: 
        !           229:        return cmd;
        !           230: }
        !           231: 
        !           232: // --------------------------------------------------------------------------
        !           233: // Allocate and return a ATA SetFeatures command.
        !           234: 
        !           235: IOATACommand *
        !           236: IOATAHDDrive::ataCommandSetFeatures(UInt8 features,
        !           237:                                     UInt8 SectorCount,
        !           238:                                     UInt8 SectorNumber,
        !           239:                                     UInt8 CylinderLow,
        !           240:                                     UInt8 CyclinderHigh)
        !           241: {
        !           242:        ATATaskfile  taskfile;
        !           243: 
        !           244:        IOATACommand * cmd = allocateCommand();
        !           245:        if (!cmd) return 0;             // error, command allocation failed.
        !           246: 
        !           247:        taskfile.protocol   = ataProtocolSetRegs;
        !           248: 
        !           249:        taskfile.regmask    = ATARegtoMask(ataRegSectorNumber)  |
        !           250:                           ATARegtoMask(ataRegCylinderLow)   |
        !           251:                           ATARegtoMask(ataRegCylinderHigh)  |
        !           252:                           ATARegtoMask(ataRegDriveHead)     |
        !           253:                           ATARegtoMask(ataRegSectorCount)   |
        !           254:                           ATARegtoMask(ataRegCommand);
        !           255: 
        !           256:        taskfile.resultmask = ATARegtoMask(ataRegError) |
        !           257:                           ATARegtoMask(ataRegStatus);
        !           258: 
        !           259:        taskfile.ataRegs[ataRegFeatures]     = features;
        !           260:        taskfile.ataRegs[ataRegSectorNumber] = SectorNumber;
        !           261:        taskfile.ataRegs[ataRegCylinderLow]  = CylinderLow;
        !           262:        taskfile.ataRegs[ataRegCylinderHigh] = CyclinderHigh;
        !           263:     taskfile.ataRegs[ataRegDriveHead]    = ataModeLBA | (_unit << 4);
        !           264:        taskfile.ataRegs[ataRegSectorCount]  = SectorCount;
        !           265:     taskfile.ataRegs[ataRegCommand]      = kIOATACommandSetFeatures;
        !           266: 
        !           267:        cmd->setTaskfile(&taskfile);
        !           268: 
        !           269:        return cmd;
        !           270: }
        !           271: 
        !           272: // --------------------------------------------------------------------------
        !           273: // This method is responsible for calling the client's completion routine
        !           274: // for an async command.
        !           275: 
        !           276: void
        !           277: IOATAHDDrive::completionCallback(IOService *          target,
        !           278:                                  gdCompletionFunction action,
        !           279:                                  void *               param,
        !           280:                                  UInt32               bytesTransferred,
        !           281:                                  IOReturn             status)
        !           282: {
        !           283:        (*action)(target, param, bytesTransferred, status);
        !           284: }
        !           285: 
        !           286: // --------------------------------------------------------------------------
        !           287: // This routine is called by our provider when a command processing has
        !           288: // completed. We currently do not use the 'refcon' argument.
        !           289: 
        !           290: void
        !           291: IOATAHDDrive::completionHandler(IOService *     device,
        !           292:                                 IOATACommand *  cmd,
        !           293:                                 void *          refcon)
        !           294: {
        !           295:        assert(cmd && device);
        !           296: 
        !           297:        ATAResults        results;
        !           298:        IOATAClientData * clientData = ATA_CLIENT_DATA(cmd);
        !           299: 
        !           300:        assert(clientData);
        !           301: 
        !           302:        if ((cmd->getResults(&results) != ataReturnNoError) &&
        !           303:                (clientData->maxRetries-- > 0) &&
        !           304:                enqueueCommand(cmd))
        !           305:                return;
        !           306: 
        !           307: #if 0
        !           308:        // Force command retry to test retry logic.
        !           309:        // Controller will reset the IOMemoryDescriptor's position, right?
        !           310:        //
        !           311:        cmd->getResults(&results);
        !           312:        if (clientData->maxRetries-- > 2) {             
        !           313:                enqueueCommand(cmd);
        !           314:                return;
        !           315:        }
        !           316: #endif
        !           317: 
        !           318: #ifdef DEBUG_LOG
        !           319:        IOLog("%s: completionHandler %08x %08x %08x %08x %d\n",
        !           320:                getName(), device, cmd, refcon, getIOReturn(&results),
        !           321:                results.bytesTransferred);
        !           322: #endif
        !           323: 
        !           324:        // Return ATAReturnCode for sync commands.
        !           325:        //
        !           326:        clientData->returnCode = results.returnCode;
        !           327: 
        !           328:        if (clientData->isSync) {
        !           329:                // For sync commands, unblock the client thread.
        !           330:                //
        !           331:                assert(clientData->completion.syncLock);
        !           332:                clientData->completion.syncLock->signal();      // unblock the client.
        !           333:        }
        !           334:        else {
        !           335:                // The TAP fields must be set for an async command.
        !           336:                // Signal the completion routine that the request has been completed.
        !           337:                //
        !           338:                assert(clientData->completion.async.action &&
        !           339:                           clientData->completion.async.target);
        !           340: 
        !           341:                completionCallback(clientData->completion.async.target,
        !           342:                            clientData->completion.async.action,
        !           343:                            clientData->completion.async.param,
        !           344:                            results.bytesTransferred,
        !           345:                            getIOReturn(&results));
        !           346:        }
        !           347: 
        !           348:        // Release the IOMemoryDescriptor.
        !           349:        //
        !           350:        if (clientData->buffer)
        !           351:                clientData->buffer->release();
        !           352: 
        !           353:        // Command processing is complete, release the command object.
        !           354:        //
        !           355:        cmd->release();
        !           356: }
        !           357: 
        !           358: // --------------------------------------------------------------------------
        !           359: // Issue a synchronous ATA command.
        !           360: 
        !           361: ATAReturnCode
        !           362: IOATAHDDrive::syncExecute(IOATACommand *  cmd,       /* command object */
        !           363:                           UInt32          timeout,   /* timeout in ms */
        !           364:                           UInt            retries)   /* max retries */
        !           365: {
        !           366:        IOATAClientData * clientData = ATA_CLIENT_DATA(cmd);
        !           367: 
        !           368:        // Bump the retain count on the command. The completion handler
        !           369:        // will decrement the retain count.
        !           370:        //
        !           371:        cmd->retain();
        !           372: 
        !           373:        // Set timeout and register the completion handler.
        !           374:        //
        !           375:        cmd->setTimeout(timeout);
        !           376:         cmd->setCallback(this,
        !           377:                          (ATACallback) &IOATAHDDrive::completionHandler,
        !           378:                          (void *) 0);
        !           379: 
        !           380:        // Increment the retain count on the IOMemoryDescriptor.
        !           381:        // Release when the completion routine gets called.
        !           382:        //
        !           383:        if (clientData->buffer)
        !           384:                clientData->buffer->retain();
        !           385: 
        !           386:        // Set the max retry count. If retry count is 0, then the command shall
        !           387:        // not be retried if an error occurs.
        !           388:        //
        !           389:        clientData->maxRetries = retries;
        !           390:        clientData->completion.syncLock = IOSyncer::create();
        !           391:        clientData->isSync = true;
        !           392: 
        !           393:        cmd->execute();
        !           394: //     enqueueCommand(cmd);    // queue command and kick off workloop.
        !           395: 
        !           396:        // Block client thread on lock until the completion handler
        !           397:        // receives an indication that the processing is complete.
        !           398:        //
        !           399:         clientData->completion.syncLock->wait();
        !           400: 
        !           401:        return clientData->returnCode;
        !           402: }
        !           403: 
        !           404: // --------------------------------------------------------------------------
        !           405: // Issue an asynchronous ATA command.
        !           406: 
        !           407: ATAReturnCode
        !           408: IOATAHDDrive::asyncExecute(IOATACommand *       cmd,      /* command object */
        !           409:                            IOService *          target,
        !           410:                            gdCompletionFunction action,
        !           411:                            void *               param,
        !           412:                            UInt32               timeout,  /* timeout in ms */
        !           413:                            UInt                 retries)  /* max retries */
        !           414: {
        !           415:        IOATAClientData * clientData = ATA_CLIENT_DATA(cmd);
        !           416: 
        !           417:        // For async commands, the completion target/action must have
        !           418:        // not be 0.
        !           419:        //
        !           420:        if ((target && action) == 0)
        !           421:                return ataReturnNotSupported;
        !           422: 
        !           423:        // Bump the retain count on the command. The completion handler
        !           424:        // will decrement the retain count.
        !           425:        //
        !           426:        cmd->retain();
        !           427: 
        !           428:        // Set timeout and register the completion handler.
        !           429:        //
        !           430:        cmd->setTimeout(timeout);
        !           431:         cmd->setCallback(this,
        !           432:                          (ATACallback) &IOATAHDDrive::completionHandler,
        !           433:                          (void *) 0);
        !           434: 
        !           435:        // Increment the retain count on the IOMemoryDescriptor.
        !           436:        // Release when the completion routine gets called.
        !           437:        //
        !           438:        if (clientData->buffer)
        !           439:                clientData->buffer->retain();
        !           440: 
        !           441:        // Set the max retry count. If retry count is 0, then the command shall
        !           442:        // not be retried if an error occurs.
        !           443:        //
        !           444:        clientData->maxRetries = retries;
        !           445:        clientData->isSync     = false;
        !           446:        
        !           447:        clientData->completion.async.target = target;
        !           448:        clientData->completion.async.action = action;
        !           449:        clientData->completion.async.param  = param;
        !           450: 
        !           451:        return (cmd->execute() ? ataReturnNoError : ataReturnNoResource);
        !           452: }
        !           453: 
        !           454: // --------------------------------------------------------------------------
        !           455: // Add a command to the retry/sync queue.
        !           456: 
        !           457: bool
        !           458: IOATAHDDrive::enqueueCommand(IOATACommand * cmd)
        !           459: {
        !           460:        // Add command to the queue.
        !           461:        //
        !           462:        _retryQueue->enqueueCommand(cmd);
        !           463: 
        !           464:        // wake up the workloop.
        !           465:        //
        !           466:        _evSource->interruptOccurred(0, 0, 0);
        !           467: 
        !           468:        return true;
        !           469: }
        !           470: 
        !           471: // --------------------------------------------------------------------------
        !           472: // Dequeues commands from the queue and executes them.
        !           473: 
        !           474: void
        !           475: IOATAHDDrive::dequeueCommands(IOInterruptEventSource * /*source*/,
        !           476:                               int /*count*/)
        !           477: {
        !           478:        _retryQueue->executeCommands();
        !           479: }
        !           480: 
        !           481: // --------------------------------------------------------------------------
        !           482: // Allocate an IOATACommand object.
        !           483: 
        !           484: IOATACommand *
        !           485: IOATAHDDrive::allocateCommand()
        !           486: {
        !           487:        IOATACommand * cmd;
        !           488: 
        !           489:        cmd = _ataDevice->allocCommand(sizeof(IOATAClientData));
        !           490:        return cmd;
        !           491: }
        !           492: 
        !           493: // ==========================================================================
        !           494: // IOATACommandQueue
        !           495: // ==========================================================================
        !           496: 
        !           497: #define        super OSObject
        !           498: OSDefineMetaClassAndStructors(IOATACommandQueue, OSObject)
        !           499: 
        !           500: // --------------------------------------------------------------------------
        !           501: // Static member function which allocates and returns a queue object.
        !           502: 
        !           503: IOATACommandQueue * IOATACommandQueue::commmandQueue()
        !           504: {
        !           505:        IOATACommandQueue * queue = new IOATACommandQueue;
        !           506:        
        !           507:        if (queue && !queue->init()) {
        !           508:                queue->release();
        !           509:                queue = 0;
        !           510:        }
        !           511:        
        !           512:        return queue;
        !           513: }
        !           514: 
        !           515: // --------------------------------------------------------------------------
        !           516: // Initializes the queue object.
        !           517: 
        !           518: bool IOATACommandQueue::init()
        !           519: {
        !           520:        _enabled = false;
        !           521:        _cmdLock = 0;
        !           522:        _qLock   = 0;
        !           523: 
        !           524:        if (!super::init())
        !           525:                return false;
        !           526: 
        !           527:        // Initialize the queue.
        !           528:        //
        !           529:        queue_init(&_queue);
        !           530: 
        !           531:        _cmdLock = IORecursiveLockAlloc();
        !           532:        if (!_cmdLock)
        !           533:                return false;
        !           534: 
        !           535:        // Queue access is protected by a spinlock.
        !           536:        //
        !           537:        _qLock = IOSimpleLockAlloc();
        !           538:        if (!_qLock)
        !           539:                return false;
        !           540:        
        !           541:        return true;
        !           542: }
        !           543: 
        !           544: // --------------------------------------------------------------------------
        !           545: // Frees the queue object.
        !           546: 
        !           547: void IOATACommandQueue::free()
        !           548: {
        !           549:        if (_qLock) {
        !           550:                IOSimpleLockFree(_qLock);
        !           551:                _qLock = 0;
        !           552:        }
        !           553: 
        !           554:        if (_cmdLock) {
        !           555:                IORecursiveLockFree(_cmdLock);
        !           556:                _cmdLock = 0;
        !           557:        }
        !           558:        
        !           559:        //
        !           560:        // What about IOATACommand objects in the queue?
        !           561:        //
        !           562:        
        !           563:        super::free();
        !           564: }
        !           565: 
        !           566: // --------------------------------------------------------------------------
        !           567: // Dequeues and executes all IOATACommand objects in the queue.
        !           568: 
        !           569: void IOATACommandQueue::executeCommands()
        !           570: {
        !           571:        IOATAClientData * clientData;
        !           572:        IOATACommand *    cmd;
        !           573: 
        !           574:         IORecursiveLockLock(_cmdLock);
        !           575: 
        !           576:        while (_enabled && !queue_empty(&_queue)) {
        !           577:                IOSimpleLockLock(_qLock);
        !           578:                queue_remove_first(&_queue, clientData, IOATAClientData *, link);
        !           579:                IOSimpleLockUnlock(_qLock);
        !           580:                
        !           581:                assert(clientData);
        !           582: 
        !           583:                cmd = clientData->command;
        !           584: 
        !           585: #ifdef DEBUG_LOG
        !           586:                IOLog("cmd:%08x clientData:%08x ATA_CLIENT_DATA(cmd):%08x\n",
        !           587:                        cmd, clientData, ATA_CLIENT_DATA(cmd));
        !           588: #endif
        !           589: 
        !           590:                assert(cmd && (ATA_CLIENT_DATA(cmd) == clientData));
        !           591: 
        !           592:                cmd->execute();
        !           593:        }
        !           594: 
        !           595:         IORecursiveLockUnlock(_cmdLock);
        !           596: }
        !           597: 
        !           598: // --------------------------------------------------------------------------
        !           599: // Enqueues an IOATACommand object to the queue.
        !           600: // Returns true if the command specifed was enqueued.
        !           601: 
        !           602: bool IOATACommandQueue::enqueueCommand(IOATACommand * cmd)
        !           603: {
        !           604:        assert(cmd);
        !           605: 
        !           606:        IOATAClientData * clientData = ATA_CLIENT_DATA(cmd);
        !           607: 
        !           608:        // Make sure the clientData to IOATACommand linkage is correct.
        !           609:        //
        !           610:        clientData->command = cmd;
        !           611: 
        !           612: #ifdef DEBUG_LOG
        !           613:        IOLog("enqueueCommand: %08x\n", (UInt) cmd);
        !           614: #endif
        !           615: 
        !           616:        IOSimpleLockLock(_qLock);
        !           617:        queue_enter(&_queue, clientData, IOATAClientData *, link);
        !           618:        IOSimpleLockUnlock(_qLock);
        !           619: 
        !           620:        return true;
        !           621: }
        !           622: 
        !           623: // --------------------------------------------------------------------------
        !           624: // Enable/disable the queue.
        !           625: 
        !           626: void IOATACommandQueue::setEnabled(bool enable)
        !           627: {
        !           628:         IORecursiveLockLock(_cmdLock);
        !           629:        _enabled = enable;
        !           630:         IORecursiveLockUnlock(_cmdLock);
        !           631: }

unix.superglobalmegacorp.com

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