Annotation of XNU/iokit/Families/IOATAPIHDDrive/IOATAPIHDDrive.cpp, revision 1.1.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.