Annotation of XNU/iokit/Families/IOATAHDDrive/IOATAHDDrive.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:  * IOATAHDDrive.cpp - Generic ATA disk driver.
        !            26:  *
        !            27:  * HISTORY
        !            28:  * Aug 27, 1999        jliu - Ported from AppleATADrive.
        !            29:  */
        !            30: 
        !            31: #include <IOKit/assert.h>
        !            32: #include <IOKit/storage/ata/IOATAHDDrive.h>
        !            33: #include <IOKit/storage/ata/IOATAHDDriveNub.h>
        !            34: 
        !            35: #define        super IOService
        !            36: OSDefineMetaClassAndStructors( IOATAHDDrive, IOService )
        !            37: 
        !            38: // --------------------------------------------------------------------------
        !            39: // init() method.
        !            40: 
        !            41: bool
        !            42: IOATAHDDrive::init(OSDictionary * properties)
        !            43: {
        !            44:        _ataDevice  = 0;        // provider (nub).
        !            45:        _workloop   = 0;        // workloop to service command retries.
        !            46:        _evSource   = 0;        // signals workloop that work is available.
        !            47:        _retryQueue = 0;        // queue object to store retry commands.
        !            48: 
        !            49:     return (super::init(properties));
        !            50: }
        !            51: 
        !            52: // --------------------------------------------------------------------------
        !            53: // Override probe() method inherited from IOService.
        !            54: 
        !            55: IOService * 
        !            56: IOATAHDDrive::probe(IOService * provider, SInt32 * score)
        !            57: {
        !            58:     if (!super::probe(provider, score))
        !            59:         return 0;
        !            60: 
        !            61:        // Our provider must be a IOATADevice nub, most likely created
        !            62:        // by an IOATAController instance.
        !            63:        //
        !            64:        IOATADevice * device = OSDynamicCast(IOATADevice, provider);
        !            65:        if (!device)
        !            66:                return 0;       // IOATADevice nub not found.
        !            67: 
        !            68:        // Do ATA device type matching.
        !            69:        //
        !            70:        if (device->getDeviceType() != reportATADeviceType())
        !            71:                return 0;       // error, type mismatch.
        !            72: 
        !            73:        return this;    // probe successful.
        !            74: }
        !            75: 
        !            76: // --------------------------------------------------------------------------
        !            77: // Starts up the driver and spawn a nub.
        !            78: 
        !            79: bool
        !            80: IOATAHDDrive::start(IOService * provider)
        !            81: {
        !            82:        // First call start() in our superclass.
        !            83:        //
        !            84:        if (!super::start(provider))
        !            85:                return false;
        !            86: 
        !            87:        // Cache our provider.
        !            88:        //
        !            89:        _ataDevice = OSDynamicCast(IOATADevice, provider);
        !            90:        if (!_ataDevice)
        !            91:                return false;
        !            92: 
        !            93:        // Open our provider.
        !            94:        //
        !            95:        _ataDevice->retain();
        !            96:        _ataDevice->open(this);
        !            97: 
        !            98:        // Inspect the provider.
        !            99:        //
        !           100:        inspectDevice(_ataDevice);
        !           101: 
        !           102:        // Cache the drive unit number (master/slave assignment).
        !           103:        //
        !           104:        _unit = _ataDevice->getUnit();
        !           105: 
        !           106:        // Allocate a workloop which is solely responsible for performing
        !           107:        // command retries. It is otherwise not involved in the data path.
        !           108:        //
        !           109:        _workloop = IOWorkLoop::workLoop();
        !           110:        if (!_workloop)
        !           111:                return false;
        !           112: 
        !           113:        // Create an event source to trigger the workloop when a command
        !           114:        // needs to be retried.
        !           115:        //
        !           116:        _evSource = IOInterruptEventSource::interruptEventSource(
        !           117:                     this,
        !           118:                     (IOInterruptEventAction) &IOATAHDDrive::dequeueCommands,
        !           119:                     0);
        !           120: 
        !           121:        if (!_evSource ||
        !           122:                (_workloop->addEventSource(_evSource) != kIOReturnSuccess))
        !           123:                return false;
        !           124: 
        !           125:        // Initialize _retryQueue to store sync and retry command objects.
        !           126:        //
        !           127:        _retryQueue = IOATACommandQueue::commmandQueue();
        !           128:        if (!_retryQueue)
        !           129:                return false;
        !           130: 
        !           131:        // Select ATA timing.
        !           132:        //
        !           133:        if (!selectTimingProtocol())
        !           134:                return false;
        !           135: 
        !           136:        // Enable retry queue.
        !           137:        //
        !           138:        _retryQueue->setEnabled(true);
        !           139: 
        !           140:        return (createNub(provider));
        !           141: }
        !           142: 
        !           143: // --------------------------------------------------------------------------
        !           144: // Release allocated resources.
        !           145: 
        !           146: void
        !           147: IOATAHDDrive::free()
        !           148: {
        !           149:        if (_evSource)
        !           150:                _evSource->release();
        !           151:        if (_workloop)
        !           152:                _workloop->release();
        !           153:        if (_ataDevice)
        !           154:                _ataDevice->release();
        !           155:        if (_retryQueue)
        !           156:                _retryQueue->release();
        !           157:        
        !           158:        super::free();
        !           159: }
        !           160: 
        !           161: // --------------------------------------------------------------------------
        !           162: // Fetch information about the ATA device nub.
        !           163: 
        !           164: void
        !           165: IOATAHDDrive::inspectDevice(IOService * provider)
        !           166: {
        !           167:        OSString *    string;
        !           168:        IOATADevice * ataDevice = OSDynamicCast(IOATADevice, provider);
        !           169:        if (!ataDevice)
        !           170:                return;
        !           171: 
        !           172:        // Fetch ATA device information from the nub.
        !           173:        //
        !           174:        string = OSDynamicCast(OSString,
        !           175:                            ataDevice->getProperty(ATAPropertyModelNumber));
        !           176:        if (string) {           
        !           177:                strncpy(_model, string->getCStringNoCopy(), 40);
        !           178:                _model[40] = '\0';
        !           179:        }
        !           180: 
        !           181:        string = OSDynamicCast(OSString,
        !           182:                            ataDevice->getProperty(ATAPropertyFirmwareRev));
        !           183:        if (string) {
        !           184:                strncpy(_revision, string->getCStringNoCopy(), 8);
        !           185:                _revision[8] = '\0';
        !           186:        }
        !           187: }
        !           188: 
        !           189: // --------------------------------------------------------------------------
        !           190: // Report the type of ATA device (ATA vs. ATAPI).
        !           191: 
        !           192: ATADeviceType
        !           193: IOATAHDDrive::reportATADeviceType() const
        !           194: {
        !           195:        return ataDeviceATA;
        !           196: }
        !           197: 
        !           198: // --------------------------------------------------------------------------
        !           199: // Returns the device type.
        !           200: 
        !           201: const char *
        !           202: IOATAHDDrive::getDeviceTypeName()
        !           203: {
        !           204:        return kDeviceTypeHardDisk;
        !           205: }
        !           206: 
        !           207: // --------------------------------------------------------------------------
        !           208: // Instantiate an ATA specific subclass of IOHDDriveNub.
        !           209: 
        !           210: IOService * IOATAHDDrive::instantiateNub()
        !           211: {
        !           212:     IOService * nub = new IOATAHDDriveNub;
        !           213:     return nub;
        !           214: }
        !           215: 
        !           216: // --------------------------------------------------------------------------
        !           217: // Returns an IOATAHDDriveNub.
        !           218: 
        !           219: bool IOATAHDDrive::createNub(IOService * provider)
        !           220: {
        !           221:     IOService * nub;
        !           222: 
        !           223:        // Instantiate a generic hard disk nub so a generic driver
        !           224:        // can match above us.
        !           225:        //
        !           226:     nub = instantiateNub();
        !           227: 
        !           228:     if (nub == 0) {
        !           229:         IOLog("%s: instantiateNub() failed\n", getName());
        !           230:         return false;
        !           231:     }
        !           232: 
        !           233:     nub->init();
        !           234:     
        !           235:     if (!nub->attach(this))
        !           236:         IOPanic("IOATAHDDrive::createNub; couldn't attach IOATAHDDriveNub");
        !           237: 
        !           238:     nub->registerService();
        !           239: 
        !           240:     return true;
        !           241: }
        !           242: 
        !           243: // --------------------------------------------------------------------------
        !           244: // Handles read/write requests.
        !           245: 
        !           246: IOReturn IOATAHDDrive::doAsyncReadWrite(IOMemoryDescriptor * buffer,
        !           247:                                         UInt32               block,
        !           248:                                         UInt32               nblks,
        !           249:                                         gdCompletionFunction action,
        !           250:                                         IOService *          target,
        !           251:                                         void *               param)
        !           252: {
        !           253:        IOReturn       ret;
        !           254:        IOATACommand * cmd = ataCommandReadWrite(buffer, block, nblks);
        !           255:        if (!cmd)
        !           256:                return kIOReturnNoMemory;
        !           257: 
        !           258:        ret = getIOReturn(asyncExecute(cmd, target, action, param));
        !           259: 
        !           260:        cmd->release();
        !           261: 
        !           262:        return ret;
        !           263: }
        !           264: 
        !           265: // --------------------------------------------------------------------------
        !           266: // Eject the media in the drive.
        !           267: 
        !           268: IOReturn IOATAHDDrive::doEjectMedia()
        !           269: {
        !           270:        return kIOReturnUnsupported;    // No support for removable ATA devices.
        !           271: }
        !           272: 
        !           273: // --------------------------------------------------------------------------
        !           274: // Format the media in the drive.
        !           275: // ATA devices does not support low level formatting.
        !           276: 
        !           277: IOReturn IOATAHDDrive::doFormatMedia(UInt64 byteCapacity)
        !           278: {
        !           279:        return kIOReturnUnsupported;
        !           280: }
        !           281: 
        !           282: // --------------------------------------------------------------------------
        !           283: // Returns disk capacity.
        !           284: 
        !           285: UInt32 IOATAHDDrive::doGetFormatCapacities(UInt64 * capacities,
        !           286:                                            UInt32   capacitiesMaxCount) const
        !           287: {
        !           288:        UInt32          blockCount = 0;
        !           289:        UInt32          blockSize  = 0;
        !           290: 
        !           291:        assert(_ataDevice);
        !           292: 
        !           293:        if (_ataDevice->getDeviceCapacity(&blockCount, &blockSize) &&
        !           294:                (capacities != NULL) && (capacitiesMaxCount > 0)) {
        !           295:                UInt64 count = blockCount;
        !           296:                UInt64 size  = blockSize;
        !           297: 
        !           298:                *capacities = size * (count + 1);
        !           299:                
        !           300:                return 1;
        !           301:        }
        !           302:        
        !           303:        return 0;
        !           304: }
        !           305: 
        !           306: // --------------------------------------------------------------------------
        !           307: // Lock the media and prevent a user-initiated eject.
        !           308: 
        !           309: IOReturn IOATAHDDrive::doLockUnlockMedia(bool doLock)
        !           310: {
        !           311:        return kIOReturnUnsupported;    // No removable ATA device support.
        !           312: }
        !           313: 
        !           314: // --------------------------------------------------------------------------
        !           315: // Flush the write-cache to the physical media.
        !           316: 
        !           317: IOReturn IOATAHDDrive::doSynchronizeCache()
        !           318: {
        !           319:        // FIXME - A lie, need implementation.
        !           320:        //
        !           321:        return kIOReturnSuccess;
        !           322: }
        !           323: 
        !           324: // --------------------------------------------------------------------------
        !           325: // Handle a Start Unit command.
        !           326: 
        !           327: IOReturn
        !           328: IOATAHDDrive::doStart()
        !           329: {
        !           330:        return kIOReturnSuccess;
        !           331: }
        !           332: 
        !           333: // --------------------------------------------------------------------------
        !           334: // Handle a Stop Unit command.
        !           335: 
        !           336: IOReturn
        !           337: IOATAHDDrive::doStop()
        !           338: {
        !           339:        return kIOReturnSuccess;
        !           340: }
        !           341: 
        !           342: // --------------------------------------------------------------------------
        !           343: // Return device identification strings.
        !           344: 
        !           345: char * IOATAHDDrive::getAdditionalDeviceInfoString()
        !           346: {
        !           347:     return ("[ATA]");
        !           348: }
        !           349: 
        !           350: char * IOATAHDDrive::getProductString()
        !           351: {
        !           352:     return _model;
        !           353: }
        !           354: 
        !           355: char * IOATAHDDrive::getRevisionString()
        !           356: {
        !           357:     return _revision;
        !           358: }
        !           359: 
        !           360: char * IOATAHDDrive::getVendorString()
        !           361: {
        !           362:     return NULL;
        !           363: }
        !           364: 
        !           365: // --------------------------------------------------------------------------
        !           366: // Report the device block size in bytes. We ask the device nub for the
        !           367: // block size. We expect this to be 512-bytes.
        !           368: 
        !           369: IOReturn IOATAHDDrive::reportBlockSize(UInt64 * blockSize)
        !           370: {
        !           371:        UInt32  blkCount = 0;
        !           372:        UInt32  blkSize  = 0;
        !           373: 
        !           374:        assert(_ataDevice);
        !           375: 
        !           376:        if (!_ataDevice->getDeviceCapacity(&blkCount, &blkSize))
        !           377:                return kIOReturnNoDevice;
        !           378: 
        !           379:        *blockSize = blkSize;
        !           380:     return kIOReturnSuccess;
        !           381: }
        !           382: 
        !           383: // --------------------------------------------------------------------------
        !           384: // Report the media in the ATA device as non-ejectable.
        !           385: 
        !           386: IOReturn IOATAHDDrive::reportEjectability(bool * isEjectable)
        !           387: {
        !           388:        *isEjectable = false;
        !           389:        return kIOReturnSuccess;
        !           390: }
        !           391: 
        !           392: // --------------------------------------------------------------------------
        !           393: // Fixed media, locking is invalid.
        !           394: 
        !           395: IOReturn IOATAHDDrive::reportLockability(bool * isLockable)
        !           396: {
        !           397:     *isLockable = false;
        !           398:        return kIOReturnSuccess;
        !           399: }
        !           400: 
        !           401: // --------------------------------------------------------------------------
        !           402: // Report the polling requirements for a removable media.
        !           403: 
        !           404: IOReturn IOATAHDDrive::reportPollRequirements(bool * pollRequired,
        !           405:                                               bool * pollIsExpensive)
        !           406: {
        !           407:     *pollIsExpensive = false;
        !           408:     *pollRequired    = false;
        !           409: 
        !           410:     return kIOReturnSuccess;
        !           411: }
        !           412: 
        !           413: // --------------------------------------------------------------------------
        !           414: // Report the max number of bytes transferred for an ATA read command.
        !           415: 
        !           416: IOReturn IOATAHDDrive::reportMaxReadTransfer(UInt64 blocksize, UInt64 * max)
        !           417: {
        !           418:     *max = blocksize * kIOATAMaxBlocksPerXfer;
        !           419:     return kIOReturnSuccess;
        !           420: }
        !           421: 
        !           422: // --------------------------------------------------------------------------
        !           423: // Report the max number of bytes transferred for an ATA write command.
        !           424: 
        !           425: IOReturn IOATAHDDrive::reportMaxWriteTransfer(UInt64 blocksize, UInt64 * max)
        !           426: {
        !           427:        // Same as read transfer limits.
        !           428:        //
        !           429:     return reportMaxReadTransfer(blocksize, max);
        !           430: }
        !           431: 
        !           432: // --------------------------------------------------------------------------
        !           433: // Returns the maximum addressable sector number.
        !           434: 
        !           435: IOReturn IOATAHDDrive::reportMaxValidBlock(UInt64 * maxBlock)
        !           436: {
        !           437:        UInt32          blockCount = 0;
        !           438:        UInt32          blockSize  = 0;
        !           439: 
        !           440:        assert(_ataDevice && maxBlock);
        !           441: 
        !           442:        if (!_ataDevice->getDeviceCapacity(&blockCount, &blockSize))
        !           443:                return kIOReturnNoDevice;
        !           444: 
        !           445:     *maxBlock = blockCount;
        !           446: 
        !           447:     return kIOReturnSuccess;
        !           448: }
        !           449: 
        !           450: // --------------------------------------------------------------------------
        !           451: // Report whether the media is currently present, and whether a media
        !           452: // change has been registered since the last reporting.
        !           453: 
        !           454: IOReturn IOATAHDDrive::reportMediaState(bool * mediaPresent, bool * changed)
        !           455: {
        !           456:        *mediaPresent = true;
        !           457:        *changed      = true;
        !           458:        
        !           459:        return kIOReturnSuccess;
        !           460: }
        !           461: 
        !           462: // --------------------------------------------------------------------------
        !           463: // Report whether the media is removable.
        !           464: 
        !           465: IOReturn IOATAHDDrive::reportRemovability(bool * isRemovable)
        !           466: {
        !           467:        *isRemovable = false;
        !           468:        return kIOReturnSuccess;
        !           469: }
        !           470: 
        !           471: // --------------------------------------------------------------------------
        !           472: // Report if the media is write-protected.
        !           473: 
        !           474: IOReturn IOATAHDDrive::reportWriteProtection(bool * isWriteProtected)
        !           475: {
        !           476:        *isWriteProtected = false;
        !           477:        return kIOReturnSuccess;
        !           478: }
        !           479: 
        !           480: // --------------------------------------------------------------------------
        !           481: // Handles messages from our provider.
        !           482: 
        !           483: IOReturn
        !           484: IOATAHDDrive::message(UInt32 type, IOService * provider, void * argument)
        !           485: {
        !           486:        IOReturn ret = kIOReturnSuccess;
        !           487: 
        !           488:        switch (type)
        !           489:        {
        !           490:                case ataMessageInitDevice:
        !           491:                        if (!selectTimingProtocol(_timingProtocol))
        !           492:                                ret = kIOReturnIOError;
        !           493:                        break;
        !           494: 
        !           495:                case ataMessageResetStarted:
        !           496:                        //
        !           497:                        // Freeze the sync/retry queue.
        !           498:                        // What about async commands?
        !           499:                        //
        !           500:                        _retryQueue->setEnabled(false);
        !           501:                        break;
        !           502: 
        !           503:                case ataMessageResetComplete:
        !           504:                        //
        !           505:                        // Re-enable the sync/retry queue.
        !           506:                        //
        !           507:                        _retryQueue->setEnabled(true);
        !           508:                        _evSource->interruptOccurred(0, 0, 0);
        !           509:                        break;
        !           510: 
        !           511:                default:
        !           512:                        ret = super::message(type, provider, argument);
        !           513:                        break;
        !           514:        }
        !           515: 
        !           516:        return ret;
        !           517: }
        !           518: 
        !           519: // --------------------------------------------------------------------------
        !           520: // Perform translation from ATAReturnCode to IOReturn codes.
        !           521: 
        !           522: static inline IOReturn
        !           523: getIOReturnFunc(ATAReturnCode code)
        !           524: {
        !           525:        switch (code) {
        !           526:                case ataReturnNoError:
        !           527:                        return kIOReturnSuccess;
        !           528: 
        !           529:                case ataReturnNotSupported:
        !           530:                        return kIOReturnUnsupported;
        !           531: 
        !           532:                case ataReturnNoResource:
        !           533:                        return kIOReturnNoResources;
        !           534: 
        !           535:                case ataReturnErrorBusy:
        !           536:                        return kIOReturnBusy;
        !           537: 
        !           538:                case ataReturnErrorInterruptTimeout:
        !           539:                        return kIOReturnTimeout;
        !           540: 
        !           541:                case ataReturnErrorRetryPIO:
        !           542:                case ataReturnErrorStatus:
        !           543:                case ataReturnErrorProtocol:
        !           544:                default:
        !           545:                        return kIOReturnIOError;
        !           546:        }
        !           547: }
        !           548: 
        !           549: IOReturn
        !           550: IOATAHDDrive::getIOReturn(ATAResults * result)
        !           551: {
        !           552:        // Translate the return code in an ATAResult structure.
        !           553:        //
        !           554:        return getIOReturnFunc(result->returnCode);
        !           555: }
        !           556: 
        !           557: IOReturn
        !           558: IOATAHDDrive::getIOReturn(ATAReturnCode code)
        !           559: {
        !           560:        return getIOReturnFunc(code);
        !           561: }

unix.superglobalmegacorp.com

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