Annotation of XNU/iokit/Families/IOATAPIHDDrive/IOATAPIHDDrive.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:  * IOATAPIHDDrive.h - Generic ATAPI Direct-Access driver.
        !            26:  *
        !            27:  * HISTORY
        !            28:  * Sep 2, 1999 jliu - Ported from AppleATAPIDrive.
        !            29:  */
        !            30: 
        !            31: #include <IOKit/assert.h>
        !            32: #include <IOKit/storage/ata/IOATAPIHDDrive.h>
        !            33: #include <IOKit/storage/ata/IOATAPIHDDriveNub.h>
        !            34: 
        !            35: #define        super IOATAHDDrive
        !            36: OSDefineMetaClassAndStructors( IOATAPIHDDrive, IOATAHDDrive )
        !            37: 
        !            38: // --------------------------------------------------------------------------
        !            39: // Override the init() method in IOATAHDDrive.
        !            40: 
        !            41: bool
        !            42: IOATAPIHDDrive::init(OSDictionary * properties)
        !            43: {
        !            44:        _mediaPresent = false;
        !            45:        _isRemovable  = false;
        !            46: 
        !            47:     return (super::init(properties));
        !            48: }
        !            49: 
        !            50: // --------------------------------------------------------------------------
        !            51: // Override probe() method inherited from IOATAHDDrive. We need to
        !            52: // perform additional matching on ATAPI device type from the Inquiry data.
        !            53: 
        !            54: IOService * 
        !            55: IOATAPIHDDrive::probe(IOService * provider, SInt32 * score)
        !            56: {
        !            57:        UInt8   deviceType;
        !            58: 
        !            59:        // Our provider must be a IOATADevice nub, most likely created
        !            60:        // by an IOATAController instance.
        !            61:        //
        !            62:        IOATADevice * device = OSDynamicCast(IOATADevice, provider);
        !            63:        if (!device)
        !            64:                return 0;       // IOATADevice nub not found.
        !            65: 
        !            66:        // Let superclass have a go at probe first.
        !            67:        //
        !            68:     if (!super::probe(provider, score))
        !            69:         return 0;
        !            70: 
        !            71:        // Perform ATAPI type matching, CD-ROM, Direct-Access, Tape, etc.
        !            72:        //
        !            73:        if (!device->getInquiryData(1, (ATAPIInquiry *) &deviceType) ||
        !            74:                !matchATAPIDeviceType(deviceType & 0x1f))
        !            75:                return 0;
        !            76: 
        !            77:        return this;    // probe successful.
        !            78: }
        !            79: 
        !            80: // --------------------------------------------------------------------------
        !            81: // Report as an ATAPI device.
        !            82: 
        !            83: ATADeviceType
        !            84: IOATAPIHDDrive::reportATADeviceType() const
        !            85: {
        !            86:        return ataDeviceATAPI;
        !            87: }
        !            88: 
        !            89: // --------------------------------------------------------------------------
        !            90: // Looks for an ATAPI device which is a direct-access device.
        !            91: 
        !            92: bool
        !            93: IOATAPIHDDrive::matchATAPIDeviceType(UInt8 type)
        !            94: {
        !            95:        if (type == kIOATAPIDeviceTypeDirectAccess)
        !            96:                return true;
        !            97:        return false;
        !            98: }
        !            99: 
        !           100: // --------------------------------------------------------------------------
        !           101: // Gather information about the ATAPI device nub.
        !           102: 
        !           103: void
        !           104: IOATAPIHDDrive::inspectDevice(IOService * provider)
        !           105: {
        !           106:        OSString *    string;
        !           107:        IOATADevice * ataDevice = OSDynamicCast(IOATADevice, provider);
        !           108:        if (!ataDevice)
        !           109:                return;
        !           110: 
        !           111:        // Fetch ATAPI device information from the nub.
        !           112:        //
        !           113:        string = OSDynamicCast(OSString,
        !           114:                            ataDevice->getProperty(ATAPropertyVendorName));
        !           115:        if (string) {
        !           116:                strncpy(_vendor, string->getCStringNoCopy(), 8);
        !           117:                _vendor[8] = '\0';
        !           118:        }
        !           119: 
        !           120:        string = OSDynamicCast(OSString,
        !           121:                            ataDevice->getProperty(ATAPropertyProductName));
        !           122:        if (string) {
        !           123:                strncpy(_product, string->getCStringNoCopy(), 16);
        !           124:                _product[16] = '\0';
        !           125:        }
        !           126: 
        !           127:        string = OSDynamicCast(OSString,
        !           128:                            ataDevice->getProperty(ATAPropertyProductRevision));
        !           129:        if (string) {
        !           130:                strncpy(_revision, string->getCStringNoCopy(), 4);
        !           131:                _revision[4] = '\0';
        !           132:        }
        !           133: }
        !           134: 
        !           135: // --------------------------------------------------------------------------
        !           136: // Handles read/write requests.
        !           137: 
        !           138: IOReturn IOATAPIHDDrive::doAsyncReadWrite(IOMemoryDescriptor * buffer,
        !           139:                                           UInt32               block,
        !           140:                                           UInt32               nblks,
        !           141:                                           gdCompletionFunction action,
        !           142:                                           IOService *          target,
        !           143:                                           void *               param)
        !           144: {
        !           145:        IOReturn       ret;
        !           146:        IOATACommand * cmd = atapiCommandReadWrite(buffer, block, nblks);
        !           147:        if (!cmd)
        !           148:                return kIOReturnNoMemory;
        !           149: 
        !           150:        ret = getIOReturn(asyncExecute(cmd, target, action, param));
        !           151: 
        !           152:        cmd->release();
        !           153: 
        !           154:        return ret;
        !           155: }
        !           156: 
        !           157: // --------------------------------------------------------------------------
        !           158: // Eject the media in the removable drive.
        !           159: 
        !           160: IOReturn
        !           161: IOATAPIHDDrive::doEjectMedia()
        !           162: {
        !           163:        IOReturn       ret;
        !           164:        IOATACommand * cmd = atapiCommandStartStopUnit(0,        /* senseData */
        !           165:                                                    false,    /* start unit */
        !           166:                                                    true,     /* Load/Eject */
        !           167:                                                    false);   /* Immediate */   
        !           168: 
        !           169:        if (!cmd)
        !           170:                return kIOReturnNoMemory;
        !           171: 
        !           172:        ret = getIOReturn(syncExecute(cmd));
        !           173: 
        !           174:        cmd->release();
        !           175: 
        !           176:        return ret;
        !           177: }
        !           178: 
        !           179: // --------------------------------------------------------------------------
        !           180: // Format the media in the drive.
        !           181: 
        !           182: IOReturn
        !           183: IOATAPIHDDrive::doFormatMedia(UInt64 /* byteCapacity */)
        !           184: {
        !           185:        return kIOReturnUnsupported;
        !           186: }
        !           187: 
        !           188: // --------------------------------------------------------------------------
        !           189: // Lock/unlock the media in the removable drive.
        !           190: 
        !           191: IOReturn
        !           192: IOATAPIHDDrive::doLockUnlockMedia(bool doLock)
        !           193: {
        !           194:        IOReturn       ret;
        !           195:        IOATACommand * cmd = atapiCommandPreventAllowRemoval(doLock);
        !           196:        if (!cmd)
        !           197:                return kIOReturnNoMemory;
        !           198:        
        !           199:        ret = getIOReturn(syncExecute(cmd));
        !           200: 
        !           201:        cmd->release();
        !           202:        
        !           203:        return ret;
        !           204: }
        !           205: 
        !           206: // --------------------------------------------------------------------------
        !           207: // Sync the write cache.
        !           208: 
        !           209: IOReturn
        !           210: IOATAPIHDDrive::doSynchronizeCache()
        !           211: {
        !           212:        return kIOReturnSuccess;
        !           213: }
        !           214: 
        !           215: // --------------------------------------------------------------------------
        !           216: // Start up the drive.
        !           217: 
        !           218: IOReturn
        !           219: IOATAPIHDDrive::doStart()
        !           220: {
        !           221:        return doStartStop(true);
        !           222: }
        !           223: 
        !           224: // --------------------------------------------------------------------------
        !           225: // Stop the drive.
        !           226: 
        !           227: IOReturn
        !           228: IOATAPIHDDrive::doStop()
        !           229: {
        !           230:        return doStartStop(false);
        !           231: }
        !           232: 
        !           233: // --------------------------------------------------------------------------
        !           234: // Issue a START/STOP Unit command.
        !           235: 
        !           236: IOReturn
        !           237: IOATAPIHDDrive::doStartStop(bool doStart)
        !           238: {
        !           239:        IOReturn       ret;
        !           240:        IOATACommand * cmd;
        !           241: 
        !           242:        cmd = atapiCommandStartStopUnit(0,          /* senseData */
        !           243:                                     doStart,    /* start unit */
        !           244:                                     false,      /* Load/Eject */
        !           245:                                     false);     /* Immediate operation */
        !           246: 
        !           247:        if (!cmd) return kIOReturnNoMemory;
        !           248: 
        !           249:        ret = getIOReturn(syncExecute(cmd));
        !           250: 
        !           251:        cmd->release();
        !           252: 
        !           253:        return ret;
        !           254: }
        !           255: 
        !           256: // --------------------------------------------------------------------------
        !           257: // Return device identification strings
        !           258: 
        !           259: char * IOATAPIHDDrive::getVendorString()
        !           260: {
        !           261:     return _vendor;
        !           262: }
        !           263: 
        !           264: char * IOATAPIHDDrive::getProductString()
        !           265: {
        !           266:     return _product;
        !           267: }
        !           268: 
        !           269: char * IOATAPIHDDrive::getRevisionString()
        !           270: {
        !           271:     return _revision;
        !           272: }
        !           273: 
        !           274: char * IOATAPIHDDrive::getAdditionalDeviceInfoString()
        !           275: {
        !           276:     return ("[ATAPI]");
        !           277: }
        !           278: 
        !           279: // --------------------------------------------------------------------------
        !           280: // Report whether the media in the drive is ejectable.
        !           281: 
        !           282: IOReturn
        !           283: IOATAPIHDDrive::reportEjectability(bool * isEjectable)
        !           284: {
        !           285:        *isEjectable = true;    /* default: if it's removable, it's ejectable */
        !           286:        return kIOReturnSuccess;
        !           287: }
        !           288: 
        !           289: // --------------------------------------------------------------------------
        !           290: // Report whether the drive can prevent user-initiated ejects by locking
        !           291: // the media in the drive.
        !           292: 
        !           293: IOReturn
        !           294: IOATAPIHDDrive::reportLockability(bool * isLockable)
        !           295: {
        !           296:     *isLockable = true;                /* default: if it's removable, it's lockable */
        !           297:        return kIOReturnSuccess;
        !           298: }
        !           299: 
        !           300: // --------------------------------------------------------------------------
        !           301: // Report our polling requirments.
        !           302: 
        !           303: IOReturn
        !           304: IOATAPIHDDrive::reportPollRequirements(bool * pollRequired,
        !           305:                                        bool * pollIsExpensive)
        !           306: {
        !           307:     *pollIsExpensive = false;
        !           308:     *pollRequired    = _isRemovable;
        !           309:     return kIOReturnSuccess;
        !           310: }
        !           311: 
        !           312: // --------------------------------------------------------------------------
        !           313: // Report the current state of the media.
        !           314: 
        !           315: IOReturn
        !           316: IOATAPIHDDrive::reportMediaState(bool * mediaPresent, 
        !           317:                                  bool * changed)
        !           318: {
        !           319:        IOATACommand *       cmd;
        !           320:        ATAResults               results;
        !           321:        IOReturn                         ret = kIOReturnSuccess;
        !           322:        UInt8                            senseData[18];
        !           323:        IOMemoryDescriptor * senseDesc;
        !           324: 
        !           325:        assert(mediaPresent && changed);
        !           326: 
        !           327:     senseDesc = IOMemoryDescriptor::withAddress(senseData,
        !           328:                                            sizeof(senseData),
        !           329:                                            kIODirectionIn);
        !           330:     if (!senseDesc)
        !           331:         return kIOReturnNoMemory;
        !           332: 
        !           333:        cmd = atapiCommandTestUnitReady(senseDesc);
        !           334:        if (!cmd)
        !           335:                return kIOReturnNoMemory;
        !           336: 
        !           337:        // Execute the Test Unit Ready command with no retries.
        !           338:        //
        !           339:        syncExecute(cmd, ATADefaultTimeout, 0);
        !           340: 
        !           341:        // Release the memory descriptor.
        !           342:        //
        !           343:        senseDesc->release();
        !           344: 
        !           345:        if (cmd->getResults(&results) == ataReturnNoError)
        !           346:        {
        !           347:                *mediaPresent = true;
        !           348:                *changed = (*mediaPresent != _mediaPresent);
        !           349:                _mediaPresent = true;
        !           350:        }
        !           351:        else
        !           352:        {
        !           353:                UInt8 errorCode      = senseData[0];
        !           354:                UInt8 senseKey       = senseData[2];
        !           355: 
        !           356: #ifdef DEBUG_LOG
        !           357:                UInt8 senseCode      = senseData[12];
        !           358:                UInt8 senseQualifier = senseData[13];
        !           359: 
        !           360:                IOLog("-- reportMediaState --\n");
        !           361:                IOLog("Error code: %02x\n", errorCode);
        !           362:                IOLog("Sense Key : %02x\n", senseKey);
        !           363:                IOLog("ASC       : %02x\n", senseCode);
        !           364:                IOLog("ASCQ      : %02x\n", senseQualifier);
        !           365: #endif
        !           366: 
        !           367:                *mediaPresent = false;
        !           368:                *changed = (*mediaPresent != _mediaPresent);
        !           369:                _mediaPresent = false;
        !           370: 
        !           371:                // The error code field for ATAPI request sense should always
        !           372:                // be 0x70 or 0x71. Otherwise ignore the sense data.
        !           373:                //
        !           374:                if ((errorCode == 0x70) || (errorCode == 0x71))
        !           375:                {
        !           376:                        switch (senseKey) {     
        !           377:                                case 5:         /* Invalid ATAPI command */
        !           378:                                        ret = kIOReturnIOError;
        !           379:                                        break;
        !           380: 
        !           381:                                case 2:         /* Not ready */
        !           382:                                        break;
        !           383: 
        !           384:                                default:
        !           385:                                        break;
        !           386:                        }
        !           387:                }
        !           388:        }
        !           389: 
        !           390:        cmd->release();
        !           391: 
        !           392: #if 0
        !           393:        IOLog("%s: media present %s, changed %s\n", getName(),
        !           394:                *mediaPresent ? "Y" : "N",
        !           395:                *changed ? "Y" : "N"
        !           396:        );
        !           397: #endif
        !           398: 
        !           399: #ifndef DISKPM
        !           400:        if (*changed && *mediaPresent)
        !           401:                doStart();
        !           402: #endif
        !           403: 
        !           404:        return ret;
        !           405: }
        !           406: 
        !           407: // --------------------------------------------------------------------------
        !           408: // Report media removability.
        !           409: 
        !           410: IOReturn
        !           411: IOATAPIHDDrive::reportRemovability(bool * isRemovable)
        !           412: {
        !           413:        UInt8   inqBuf[2];
        !           414:        
        !           415:        *isRemovable = false;
        !           416:        
        !           417:        if (_ataDevice->getInquiryData(sizeof(inqBuf), (ATAPIInquiry *) inqBuf))
        !           418:        {
        !           419:                if (inqBuf[1] & 0x80)
        !           420:                        *isRemovable = _isRemovable = true;
        !           421:                else
        !           422:                        *isRemovable = _isRemovable = false;
        !           423:        }
        !           424: 
        !           425:        return kIOReturnSuccess;
        !           426: }
        !           427: 
        !           428: // --------------------------------------------------------------------------
        !           429: // Report whether media is write-protected.
        !           430: 
        !           431: IOReturn
        !           432: IOATAPIHDDrive::reportWriteProtection(bool * isWriteProtected)
        !           433: {
        !           434:        *isWriteProtected = false;              // defaults to read-write
        !           435:        return kIOReturnSuccess;
        !           436: }
        !           437: 
        !           438: // --------------------------------------------------------------------------
        !           439: // Instantiate an ATAPI specific subclass of IOHDDriveNub.
        !           440: 
        !           441: IOService *
        !           442: IOATAPIHDDrive::instantiateNub()
        !           443: {
        !           444:     IOService * nub = new IOATAPIHDDriveNub;
        !           445:     return nub;
        !           446: }

unix.superglobalmegacorp.com

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