Annotation of XNU/iokit/Families/IOATAPICDDrive/IOATAPICDDrive.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:  * IOATAPICDDrive.h - Generic ATAPI CD-ROM driver.
        !            26:  *
        !            27:  * HISTORY
        !            28:  * Sep 2, 1999 jliu - Ported from AppleATAPIDrive.
        !            29:  */
        !            30: 
        !            31: #include <IOKit/assert.h>
        !            32: #include <IOKit/storage/ata/IOATAPICDDrive.h>
        !            33: #include <IOKit/storage/ata/IOATAPICDDriveNub.h>
        !            34: 
        !            35: #define        super IOATAPIHDDrive
        !            36: OSDefineMetaClassAndStructors( IOATAPICDDrive, IOATAPIHDDrive )
        !            37: 
        !            38: // --------------------------------------------------------------------------
        !            39: // Looks for an ATAPI device which is a CD-ROM device.
        !            40: 
        !            41: bool
        !            42: IOATAPICDDrive::matchATAPIDeviceType(UInt8 type)
        !            43: {
        !            44:        if (type == kIOATAPIDeviceTypeCDROM)
        !            45:                return true;
        !            46:        return false;
        !            47: }
        !            48: 
        !            49: // --------------------------------------------------------------------------
        !            50: // Instantiate an ATAPI specific subclass of IOCDDriveNub.
        !            51: 
        !            52: IOService *
        !            53: IOATAPICDDrive::instantiateNub()
        !            54: {
        !            55:     IOService * nub = new IOATAPICDDriveNub;
        !            56:     return nub;
        !            57: }
        !            58: 
        !            59: // --------------------------------------------------------------------------
        !            60: // Report whether media is write-protected.
        !            61: 
        !            62: IOReturn
        !            63: IOATAPICDDrive::reportWriteProtection(bool * isWriteProtected)
        !            64: {
        !            65:        *isWriteProtected = true;
        !            66:        return kIOReturnSuccess;
        !            67: }
        !            68: 
        !            69: // --------------------------------------------------------------------------
        !            70: // Returns the device type.
        !            71: 
        !            72: const char *
        !            73: IOATAPICDDrive::getDeviceTypeName()
        !            74: {
        !            75:        return kDeviceTypeCDROM;
        !            76: }
        !            77: 
        !            78: // --------------------------------------------------------------------------
        !            79: // Read the Table of Contents.
        !            80: 
        !            81: IOReturn
        !            82: IOATAPICDDrive::readTOC(struct rawToc * buffer,
        !            83:                         UInt32          length,
        !            84:                         tocFormat       format)
        !            85: {
        !            86:        IOReturn             ret;
        !            87:        IOATACommand *       cmd;
        !            88:        IOMemoryDescriptor * tocDesc;
        !            89:        
        !            90:        assert(buffer);
        !            91:        
        !            92:     tocDesc = IOMemoryDescriptor::withAddress(buffer,
        !            93:                                            length,
        !            94:                                            kIODirectionIn);
        !            95:        if (!tocDesc)
        !            96:                return kIOReturnNoMemory;
        !            97:        
        !            98:        cmd = atapiCommandReadTOC(tocDesc, format, 0);
        !            99:        if (!cmd)
        !           100:                return kIOReturnNoMemory;
        !           101: 
        !           102:        // Execute the Read TOC command.
        !           103:        //
        !           104:        ret = getIOReturn(syncExecute(cmd));
        !           105: 
        !           106:        // Release the memory descriptor.
        !           107:        //
        !           108:        tocDesc->release();
        !           109:        
        !           110:        cmd->release();
        !           111: 
        !           112:        return ret;
        !           113: }
        !           114: 
        !           115: // --------------------------------------------------------------------------
        !           116: // Start analog audio play
        !           117: 
        !           118: IOReturn
        !           119: IOATAPICDDrive::setAudioStopAddress (positioningType addressType,
        !           120:                                      cdAddress address)
        !           121: {
        !           122:     if (addressType == kAbsoluteTime)
        !           123:         fMSFStopAddress = (UInt32)address;
        !           124:     if (addressType == kBlockAddress)
        !           125:         fLBAStopAddress = (UInt32)address;
        !           126:     return 0;
        !           127: }
        !           128: 
        !           129: IOReturn
        !           130: IOATAPICDDrive::audioPlay(positioningType addressType,
        !           131:                           cdAddress address,
        !           132:                           audioPlayMode mode)
        !           133: {
        !           134:     if (addressType == kBlockAddress) {
        !           135:         return playAudio((UInt32)address,0xfff);
        !           136:     }
        !           137:     if (addressType == kAbsoluteTime) {
        !           138:         return playAudioMSF((UInt32)address,(UInt32)fMSFStopAddress);
        !           139:     }
        !           140:     return 0;
        !           141: }
        !           142: 
        !           143: IOReturn
        !           144: IOATAPICDDrive::playAudioMSF (UInt32 start_msf,
        !           145:                               UInt32 end_msf)
        !           146: {
        !           147:        IOATACommand *       cmd;
        !           148:        IOReturn             ret;
        !           149: 
        !           150:         // IOLog("IOATAPICDDrive::playAudioMSF %x %x\n",start_msf,end_msf);
        !           151:        cmd = atapiCommandPlayAudioMSF(start_msf, end_msf);
        !           152:        if (!cmd)
        !           153:                return kIOReturnNoMemory;
        !           154: 
        !           155:        // Execute the audio play command.
        !           156:        //
        !           157:        ret = getIOReturn(syncExecute(cmd));
        !           158: 
        !           159:        cmd->release();
        !           160: 
        !           161:        return ret;
        !           162: }
        !           163: 
        !           164: IOReturn
        !           165: IOATAPICDDrive::playAudio (UInt32 start_lba,
        !           166:                            UInt32 len_lba)
        !           167: {
        !           168:        IOATACommand *       cmd;
        !           169:        IOReturn             ret;
        !           170: 
        !           171:         // IOLog("IOATAPICDDrive::playAudio\n");
        !           172:        cmd = atapiCommandPlayAudio(start_lba, len_lba);
        !           173:        if (!cmd)
        !           174:                return kIOReturnNoMemory;
        !           175: 
        !           176:        // Execute the audio play command.
        !           177:        //
        !           178:        ret = getIOReturn(syncExecute(cmd));
        !           179: 
        !           180:        cmd->release();
        !           181: 
        !           182:        return ret;
        !           183: }
        !           184: 
        !           185: IOReturn
        !           186: IOATAPICDDrive::audioPause(bool pause)
        !           187: {
        !           188:        IOATACommand *       cmd;
        !           189:        IOReturn             ret;
        !           190: 
        !           191:         // IOLog("IOATAPICDDrive::audioPause\n");
        !           192:        cmd = atapiCommandPauseResume(!pause);
        !           193:        if (!cmd)
        !           194:                return kIOReturnNoMemory;
        !           195: 
        !           196:        // Execute the audio pause/resume command.
        !           197:        //
        !           198:        ret = getIOReturn(syncExecute(cmd));
        !           199: 
        !           200:        cmd->release();
        !           201: 
        !           202:        return ret;
        !           203: }
        !           204: 
        !           205: IOReturn
        !           206: IOATAPICDDrive::readAudioVolume(UInt8 * leftVolume, UInt8 * rightVolume)
        !           207: {
        !           208:     UInt8 *audio_control;
        !           209:     IOReturn status = -1;
        !           210: 
        !           211:     audio_control = (UInt8 *)IOMalloc(144);
        !           212:     if (!audio_control) return kIOReturnNoMemory;
        !           213: 
        !           214:     status = readModeSense(audio_control,(UInt32)144,(UInt32)0xe);
        !           215:     *leftVolume = audio_control[21] & 0xff;
        !           216:     *rightVolume = audio_control[17] & 0xff;
        !           217: 
        !           218:     // IOLog("IOATAPICDDrive::readAudioVolume left0=%d right0=%d left1=%d right1=%d\n", *leftVolume,*rightVolume, audio_control[23],audio_control[19]);
        !           219: 
        !           220:     // IOLog("IOATAPICDDrive::readAudioVolume p0=%d p1=%d p2=%d p3=%d\n", audio_control[8],audio_control[10], audio_control[12],audio_control[14]);
        !           221: 
        !           222:     IOFree(audio_control,144);
        !           223:     return status;
        !           224: }
        !           225: 
        !           226: IOReturn
        !           227: IOATAPICDDrive::setVolume(UInt8 leftVolume, UInt8 rightVolume)
        !           228: {
        !           229:     UInt8 *audio_control;
        !           230:     IOReturn status = -1;
        !           231:     UInt32 len;
        !           232: 
        !           233:     // IOLog("IOATAPICDDrive::setVolume %d %d\n",leftVolume,rightVolume);
        !           234: 
        !           235:     // init
        !           236:     audio_control = (UInt8 *)IOMalloc(144);
        !           237:     if (!audio_control) return kIOReturnNoMemory;
        !           238: 
        !           239:     // get current values
        !           240:     status = readModeSense(audio_control,(UInt32)144,(UInt32)0xe);
        !           241:     len = (UInt32)audio_control[1] + 2;
        !           242: 
        !           243:     // set new values
        !           244:     // audio_control[ 9] = audio_control[11] = 0xff;
        !           245:     // audio_control[23] = audio_control[21] = leftVolume & 0xff;
        !           246:     audio_control[19] = audio_control[17] = rightVolume & 0xff;
        !           247: 
        !           248:     // get current values
        !           249:     status = writeModeSelect(audio_control,(UInt32)len,(UInt32)0xe);
        !           250: 
        !           251:     // cleanup and exit
        !           252:     IOFree(audio_control,144);
        !           253:     return status;
        !           254: }
        !           255: 
        !           256: IOReturn
        !           257: IOATAPICDDrive::readModeSense(UInt8 * buffer, UInt32 length, UInt32 pageCode)
        !           258: {
        !           259:     IOReturn             ret;
        !           260:     IOATACommand *       cmd;
        !           261:     IOMemoryDescriptor * senseDesc;
        !           262:        
        !           263:     assert(buffer);
        !           264: 
        !           265:     // IOLog("IOATAPICDDrive::readModeSense len=%d page=%d\n",length,pageCode);
        !           266: 
        !           267:     senseDesc = IOMemoryDescriptor::withAddress(buffer,
        !           268:                                      length,
        !           269:                                      kIODirectionIn);
        !           270:     if (!senseDesc)
        !           271:         return kIOReturnNoMemory;
        !           272: 
        !           273:     cmd = atapiCommandModeSense(senseDesc, pageCode);
        !           274:     if (!cmd)
        !           275:         return kIOReturnNoMemory;
        !           276: 
        !           277:     // Execute the Mode Sense command.
        !           278:     //
        !           279:     ret = getIOReturn(syncExecute(cmd));
        !           280: 
        !           281:     // Release the memory descriptor.
        !           282:     //
        !           283:     senseDesc->release();
        !           284: 
        !           285:     cmd->release();
        !           286: 
        !           287:     return ret;
        !           288: }
        !           289: 
        !           290: IOReturn
        !           291: IOATAPICDDrive::writeModeSelect(UInt8 * buffer, UInt32 length, UInt32 pageCode)
        !           292: {
        !           293:     IOReturn             ret;
        !           294:     IOATACommand *       cmd;
        !           295:     IOMemoryDescriptor * selectDesc;
        !           296:        
        !           297:     // IOLog("IOATAPICDDrive::writeModeSelect %d %d\n",length,pageCode);
        !           298:     assert(buffer);
        !           299: 
        !           300:     selectDesc = IOMemoryDescriptor::withAddress(buffer,
        !           301:                                      length,
        !           302:                                      kIODirectionOut);
        !           303:     if (!selectDesc)
        !           304:         return kIOReturnNoMemory;
        !           305: 
        !           306:     cmd = atapiCommandModeSelect(selectDesc, pageCode);
        !           307:     if (!cmd)
        !           308:         return kIOReturnNoMemory;
        !           309: 
        !           310:     // Execute the Mode Select command.
        !           311:     //
        !           312:     ret = getIOReturn(syncExecute(cmd));
        !           313: 
        !           314:     // Release the memory descriptor.
        !           315:     //
        !           316:     selectDesc->release();
        !           317: 
        !           318:     cmd->release();
        !           319: 
        !           320:     return ret;
        !           321: }
        !           322: 
        !           323: IOReturn
        !           324: IOATAPICDDrive::readTheQSubcode(struct qSubcode *buffer)
        !           325: {
        !           326:     UInt8 * channel_data;
        !           327:     UInt32 address;
        !           328:     IOReturn ret;
        !           329: 
        !           330:     // init
        !           331:     channel_data = (UInt8 *)IOMalloc(16);
        !           332:     if (!channel_data) return kIOReturnNoMemory;
        !           333: 
        !           334:     // get audio status
        !           335:     ret = readSubChannel(channel_data,16,0x01,0x00,true);
        !           336: 
        !           337:     // get current absolute address
        !           338:     address = ((channel_data[ 8] & 0xff) << 24) |
        !           339:               ((channel_data[ 9] & 0xff) << 16) |
        !           340:               ((channel_data[10] & 0xff) <<  8) |
        !           341:               ((channel_data[11] & 0xff));
        !           342:     buffer->absAddress = (cdAddress)address;
        !           343: 
        !           344:     // get current track relative address
        !           345:     address = ((channel_data[12] & 0xff) << 24) |
        !           346:               ((channel_data[13] & 0xff) << 16) |
        !           347:               ((channel_data[14] & 0xff) <<  8) |
        !           348:               ((channel_data[15] & 0xff));
        !           349:     buffer->relAddress = (cdAddress)address;
        !           350: 
        !           351:     // get type, track, index
        !           352:     buffer->type  = channel_data[5] & 0x0f;
        !           353:     buffer->track = channel_data[6] & 0x0f;
        !           354:     buffer->index = channel_data[7] & 0x0f;
        !           355: 
        !           356:     // IOLog("IOATAPICDDrive::readTheQSubcode absAddr=0x%x relAddr=0x%xx\n", buffer->absAddress, buffer->relAddress);
        !           357: 
        !           358:     // cleanup
        !           359:     IOFree(channel_data,16);
        !           360:     return ret;
        !           361: }
        !           362: 
        !           363: IOReturn
        !           364: IOATAPICDDrive::getAudioStatus(struct audioStatus *status)
        !           365: {
        !           366:     UInt8 * channel_data;
        !           367:     UInt32 address;
        !           368:     IOReturn ret;
        !           369: 
        !           370:     // init
        !           371:     channel_data = (UInt8 *)IOMalloc(16);
        !           372:     if (!channel_data) return kIOReturnNoMemory;
        !           373: 
        !           374:     // get audio status
        !           375:     ret = readSubChannel(channel_data,16,0x01,0x00,true);
        !           376: 
        !           377:     // get current absolute address
        !           378:     address = ((channel_data[ 8] & 0xff) << 24) |
        !           379:               ((channel_data[ 9] & 0xff) << 16) |
        !           380:               ((channel_data[10] & 0xff) <<  8) |
        !           381:               ((channel_data[11] & 0xff));
        !           382:     status->address = (cdAddress)address;
        !           383: 
        !           384:     // get current status
        !           385:     if ((channel_data[1] & 0xff) == 0x00) status->status = kUnknown;
        !           386:     if ((channel_data[1] & 0xff) == 0x11) status->status = kAudioPlayInProgress;
        !           387:     if ((channel_data[1] & 0xff) == 0x12) status->status = kHoldTrackMode;
        !           388:     if ((channel_data[1] & 0xff) == 0x13) status->status = kAudioPlayCompleted;
        !           389:     if ((channel_data[1] & 0xff) == 0x14) status->status = kError;
        !           390:     if ((channel_data[1] & 0xff) == 0x15) status->status = fStatus;
        !           391:     fStatus = status->status;
        !           392: 
        !           393:     // get current track type
        !           394:     status->type = channel_data[5] & 0x0f;
        !           395: 
        !           396:     // IOLog("IOATAPICDDrive::getAudioStatus addr=0x%x status=0x%x type=0x%x\n", status->address, status->status, status->type);
        !           397: 
        !           398:     // cleanup
        !           399:     IOFree(channel_data,16);
        !           400:     return ret;
        !           401: }
        !           402: 
        !           403: IOReturn
        !           404: IOATAPICDDrive::readMCN(UInt8 * buffer, bool * found)
        !           405: {
        !           406:     UInt8 * channel_data;
        !           407:     UInt32 address;
        !           408:     IOReturn ret;
        !           409: 
        !           410:     // init
        !           411:     channel_data = (UInt8 *)IOMalloc(24);
        !           412:     if (!channel_data) return kIOReturnNoMemory;
        !           413: 
        !           414:     // get audio status
        !           415:     ret = readSubChannel(channel_data,24,0x02,0x00,true);
        !           416: 
        !           417:     // check if found
        !           418:     *found = (channel_data[8] & 0x80 == 0x80);
        !           419: 
        !           420:     // copy the data
        !           421:     if (*found) {
        !           422:         bcopy(&channel_data[9],buffer,15);
        !           423:     }
        !           424: 
        !           425:     // IOLog("IOATAPICDDrive::readMCN found=%d\n",*found);
        !           426: 
        !           427:     // cleanup
        !           428:     IOFree(channel_data,24);
        !           429:     return ret;
        !           430: }
        !           431: 
        !           432: IOReturn
        !           433: IOATAPICDDrive::readISRC(UInt32 track, UInt8 * buffer, bool * found)
        !           434: {
        !           435:     UInt8 * channel_data;
        !           436:     UInt32 address;
        !           437:     IOReturn ret;
        !           438: 
        !           439:     // init
        !           440:     channel_data = (UInt8 *)IOMalloc(24);
        !           441:     if (!channel_data) return kIOReturnNoMemory;
        !           442: 
        !           443:     // get audio status
        !           444:     ret = readSubChannel(channel_data,24,0x03,track,true);
        !           445: 
        !           446:     // check if found
        !           447:     *found = (channel_data[8] & 0x80 == 0x80);
        !           448: 
        !           449:     // copy the data
        !           450:     if (*found) {
        !           451:         bcopy(&channel_data[9],buffer,15);
        !           452:     }
        !           453: 
        !           454:     // IOLog("IOATAPICDDrive::readISRC found=%d\n",*found);
        !           455: 
        !           456:     // cleanup
        !           457:     IOFree(channel_data,24);
        !           458:     return ret;
        !           459: }
        !           460: 
        !           461: IOReturn
        !           462: IOATAPICDDrive::readHeader(UInt32 blockAddress,struct headerInfo *buffer)
        !           463: {
        !           464:     UInt8 * header_data;
        !           465:     IOReturn             ret;
        !           466:     IOATACommand *       cmd;
        !           467:     IOMemoryDescriptor * readDesc;
        !           468:        
        !           469:     // init
        !           470:     header_data = (UInt8 *)IOMalloc(8);
        !           471:     if (!header_data) return kIOReturnNoMemory;
        !           472: 
        !           473:     // IOLog("IOATAPICDDrive::readHeader addr=0x%x\n",blockAddress);
        !           474: 
        !           475:     readDesc = IOMemoryDescriptor::withAddress(header_data,
        !           476:                                      8,
        !           477:                                      kIODirectionIn);
        !           478:     if (!readDesc)
        !           479:         return kIOReturnNoMemory;
        !           480: 
        !           481:     cmd = atapiCommandReadHeader(readDesc, blockAddress);
        !           482:     if (!cmd)
        !           483:         return kIOReturnNoMemory;
        !           484: 
        !           485:     // Execute the Read Header command.
        !           486:     //
        !           487:     ret = getIOReturn(syncExecute(cmd));
        !           488: 
        !           489:     // Release the memory descriptor.
        !           490:     //
        !           491:     readDesc->release();
        !           492:     cmd->release();
        !           493: 
        !           494:     // save the data
        !           495:     buffer->address = ((header_data[4] & 0xff) << 24) |
        !           496:                       ((header_data[5] & 0xff) << 16) |
        !           497:                       ((header_data[6] & 0xff) <<  8) |
        !           498:                       ((header_data[7] & 0xff));
        !           499:     buffer->mode = header_data[0] & 0xff;
        !           500: 
        !           501:     IOFree(header_data,8);
        !           502: 
        !           503:     return ret;
        !           504: }
        !           505: 
        !           506: IOReturn
        !           507: IOATAPICDDrive::readSubChannel(UInt8 * buffer,
        !           508:                           UInt32 length,
        !           509:                           UInt8 dataFormat,
        !           510:                           UInt8 trackNumber,
        !           511:                           bool subQ)
        !           512: {
        !           513:     IOReturn             ret;
        !           514:     IOATACommand *       cmd;
        !           515:     IOMemoryDescriptor * readDesc;
        !           516:        
        !           517:     assert(buffer);
        !           518: 
        !           519:     // IOLog("IOATAPICDDrive::readSubChannel len=%d\n",length);
        !           520: 
        !           521:     readDesc = IOMemoryDescriptor::withAddress(buffer,
        !           522:                                      length,
        !           523:                                      kIODirectionIn);
        !           524:     if (!readDesc)
        !           525:         return kIOReturnNoMemory;
        !           526: 
        !           527:     cmd = atapiCommandReadSubChannel(readDesc, dataFormat, trackNumber, subQ);
        !           528:     if (!cmd)
        !           529:         return kIOReturnNoMemory;
        !           530: 
        !           531:     // Execute the Mode Sense command.
        !           532:     //
        !           533:     ret = getIOReturn(syncExecute(cmd));
        !           534: 
        !           535:     // Release the memory descriptor.
        !           536:     //
        !           537:     readDesc->release();
        !           538: 
        !           539:     cmd->release();
        !           540: 
        !           541:     return ret;
        !           542: }

unix.superglobalmegacorp.com

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