Annotation of XNU/iokit/Families/IOATAPICDDrive/IOATAPICDDrive.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:  * 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.