Annotation of XNU/iokit/Families/IOCDDrive/IOCDDrive.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: #include <IOKit/IOLib.h>
                     23: #include <IOKit/storage/IOCDDrive.h>
                     24: #include <IOKit/storage/IOCDMedia.h>
                     25: #include "IOCDAudioNub.h"
                     26: #include <IOKit/storage/IOCDDriveNub.h>
                     27: 
                     28: #define        super   IOHDDrive
                     29: OSDefineMetaClassAndStructors(IOCDDrive,IOHDDrive)
                     30: 
                     31: /* Accept a new piece of media, doing whatever's necessary to make it
                     32:  * show up properly to the system.
                     33:  */
                     34: IOReturn
                     35: IOCDDrive::acceptNewMedia(void)
                     36: {
                     37:     IOReturn result;
                     38:     bool ok;
                     39:     int i;
                     40:     UInt32 nblocks;
                     41:     UInt64 nbytes;
                     42:     int nDataTracks;
                     43:     int nAudioTracks;
                     44:     char name[128];
                     45:     bool nameSep;
                     46: 
                     47: //    IOLog("%s[IOCDDrive]::acceptNewMedia\n",getName());
                     48: 
                     49:     /* First, we cache information about the tracks on the disc: */
                     50:     
                     51:     result = cacheTocInfo();
                     52:     if (result != kIOReturnSuccess) {
                     53:         IOLog("%s[IOCDDrive]::acceptNewMedia; err '%s' from cacheTocInfo\n",
                     54:             getName(),stringFromReturn(result));
                     55:         return(result);
                     56:     }
                     57: 
                     58:     /* Scan thru the track list, counting up the number of Data and Audio tracks.
                     59:      * We also total up the number of blocks (bytes) for all data tracks.
                     60:      */
                     61:     
                     62:     nDataTracks = 0;
                     63:     nAudioTracks = 0;
                     64:     nblocks = 0;
                     65:     
                     66:     for (i = 1; i <= 99; i++) {                /* only tracks 1-99, not leadout or points */
                     67:         if (trackExists(i)) {
                     68:             if (trackIsData(i)) {
                     69:                 nDataTracks++;
                     70:                 nblocks += getTrackBlocks(i);
                     71:             } else {
                     72:                 nAudioTracks++;
                     73:             }
                     74:         }
                     75:     }
                     76: 
                     77:     nbytes = nblocks * 2048;
                     78: 
                     79:     /* Instantiate a CD Media nub above ourselves. */
                     80: 
                     81:     name[0] = 0;
                     82:     nameSep = false;
                     83:     if (_provider->getVendorString()) {
                     84:         strcat(name, _provider->getVendorString());
                     85:         nameSep = true;
                     86:     }
                     87:     if (_provider->getProductString()) {
                     88:         if (nameSep == true)  strcat(name, " ");
                     89:         strcat(name, _provider->getProductString());
                     90:         nameSep = true;
                     91:     }
                     92:     if (nameSep == true)  strcat(name, " ");
                     93:     strcat(name, "Media");
                     94: 
                     95:     result = instantiateMediaObject((IOMedia **)&_mediaNub,0,nbytes,2048,true,name);
                     96: 
                     97:     if (_mediaNub) {
                     98:         ok = _mediaNub->attach(this);
                     99:     } else {
                    100:         IOLog("%s[IOCDDrive]::acceptNewMedia; can't instantiate CD media nub.\n",getName());
                    101:         return(result);                        /* give up now */
                    102:     }
                    103:     if (!ok) {
                    104:         IOLog("%s[IOCDDrive]::acceptNewMedia; can't attach CD media nub.\n",getName());
                    105:         _mediaNub->release();
                    106:         _mediaNub = NULL;
                    107:         return(kIOReturnNoMemory);     /* give up now */
                    108:     }
                    109:         
                    110:     /* Instantiate an audio control nub for the audio portion of the media. */
                    111: 
                    112:     _acNub = new IOCDAudioNub;
                    113:     if (_acNub) {
                    114:         _acNub->init();
                    115:         ok = _acNub->attach(this);
                    116:         if (!ok) {
                    117:             IOLog("%s[IOCDDrive]::acceptNewMedia; can't attach audio control nub.\n",getName());
                    118:             _acNub->release();
                    119:             _acNub = NULL;
                    120:         }
                    121:     } else {
                    122:         IOLog("%s[IOCDDrive]::acceptNewMedia; can't instantiate audio control nub.\n",
                    123:               getName());
                    124:     }
                    125: 
                    126:     IOLog("%s media: %ld blocks, %ld bytes each, %d data tracks, %d audio tracks.\n",
                    127:             getName(),nblocks,2048L,nDataTracks,nAudioTracks);
                    128: 
                    129:     /* Now that the nubs are attached, register them. */
                    130: 
                    131:     _mediaNub->setProperty("audio tracks",nAudioTracks,32);
                    132:     _mediaNub->setProperty("data tracks",nDataTracks,32);
                    133:     _mediaNub->registerService();
                    134: 
                    135:     if (_acNub) {
                    136:         _acNub->registerService();
                    137:     }
                    138: 
                    139:     _mediaPresent = true;
                    140: 
                    141:     return(result);
                    142: }
                    143: 
                    144: IOReturn
                    145: IOCDDrive::audioPlay(positioningType addressType,cdAddress address,audioPlayMode mode)
                    146: {
                    147:     return(_CDprovider->audioPlay(addressType,address,mode));
                    148: }
                    149: 
                    150: IOReturn
                    151: IOCDDrive::audioPause(bool pause)
                    152: {
                    153:     return(_CDprovider->audioPause(pause));
                    154: }
                    155: 
                    156: IOReturn
                    157: IOCDDrive::audioScan(positioningType addressType,cdAddress address,bool reverse)
                    158: {
                    159:     return(_CDprovider->audioScan(addressType,address,reverse));
                    160: }
                    161: 
                    162: IOReturn
                    163: IOCDDrive::audioTrackSearch(positioningType addressType,cdAddress address,
                    164:                                                bool startPlay,audioPlayMode mode)
                    165: {
                    166:     return(_CDprovider->audioTrackSearch(addressType,address,startPlay,mode));
                    167: }
                    168: 
                    169: IOReturn
                    170: IOCDDrive::cacheTocInfo(void)
                    171: {
                    172:     IOReturn result;
                    173:     struct rawToc *toc;
                    174:     struct tocTrackDescriptor *d;
                    175:     struct tocTrackDescriptor *end;
                    176:     int length;
                    177:     struct trackInfo *t;
                    178:     struct trackInfo *priorTrack = 0;          /* =0 avoids "uninitialized" warning */
                    179:     int i;
                    180: 
                    181:     for (i = 0; i < kTrackEntries; i++) {              /* max 99 tracks plus leadout */
                    182:         bzero((void *)&_trackInfo[i],sizeof(struct trackInfo));
                    183:     }
                    184: 
                    185:     toc = IONew(struct rawToc,1);
                    186:     if (toc == NULL) {
                    187:         return(kIOReturnNoMemory);
                    188:     }
                    189: 
                    190:     /* Read the TOC in Lba format to get most of the info we need: */
                    191: 
                    192:     result = _CDprovider->readTOC(toc,sizeof(struct rawToc),ktocSCSI2LBA);
                    193: 
                    194: //    IOLog("raw toc in LBA format:\n");
                    195: //    dump((char *)toc,sizeof(struct rawToc));
                    196:          
                    197:     if (result != kIOReturnSuccess) {
                    198:         IODelete(toc,struct rawToc,1);
                    199:         return(result);
                    200:     }
                    201: 
                    202:     /* Scan all the tracks in the TOC, setting up our track info.*/
                    203: 
                    204:     d = &toc->descriptors[0];
                    205:     length = toc->header.len_hi << 8 | toc->header.len_lo - 2; /* bytes used for descriptors */
                    206:     end = &toc->descriptors[length / sizeof(struct tocTrackDescriptor)];
                    207: 
                    208:     while (d < end) {
                    209:         t = &_trackInfo[d->track];
                    210:         setTrackInfoEntry(d,t);
                    211:         t->lba = d->lba_3 << 24 | d->lba_2 << 16 | d->lba_1 <<  8 | d->lba_0;
                    212: 
                    213:         /* Compute the number of blocks in the prior track, now that we
                    214:          * know the starting LBA of this track.
                    215:          */
                    216:         if (d->track > 1) {
                    217:             priorTrack->nblocks = t->lba - priorTrack->lba;
                    218:         }
                    219:         priorTrack = t;
                    220:         d++;
                    221:     }
                    222: 
                    223:     /* Read the TOC again, this time in MSF format, and grab the MSF info. */
                    224: 
                    225:     result = _CDprovider->readTOC(toc,sizeof(struct rawToc),ktocSCSI2MSF);
                    226:     if (result != kIOReturnSuccess) {
                    227:         IODelete(toc,struct rawToc,1);
                    228:         return(result);
                    229:     }
                    230: 
                    231:     d = &toc->descriptors[0];
                    232:     length = toc->header.len_hi << 8 | toc->header.len_lo - 2; /* bytes used for descriptors */
                    233:     end = &toc->descriptors[length / sizeof(struct tocTrackDescriptor)];
                    234: 
                    235:     while (d < end) {
                    236:         t = &_trackInfo[d->track];
                    237: //        setTrackInfoEntry(d,t);
                    238:         t->msf = d->lba_3 << 24 | d->lba_2 << 16 | d->lba_1 <<  8 | d->lba_0;
                    239:         d++;
                    240:     }
                    241: 
                    242:     IODelete(toc,struct rawToc,1);
                    243: 
                    244:     _tocInfoCached = true;
                    245: 
                    246:     IOLog("-CD track ctl isdata    lba10   lba16    M:S:F    nblks10 nblks16\n");
                    247: 
                    248: #define SHOWTOC
                    249: #ifdef SHOWTOC
                    250:     for (i = 1; i < kTrackEntries; i++) {
                    251:         if (_trackInfo[i].track != 0) {
                    252:             IOLog("     %02x   %02x    %s     %8d %08x %02d:%02d:%02d %8d %08x\n",
                    253:                 _trackInfo[i].track,
                    254:                 _trackInfo[i].control,
                    255:                 _trackInfo[i].isData ? "Y" : "N",
                    256:                 (int)_trackInfo[i].lba,
                    257:                 (int)_trackInfo[i].lba,
                    258:                 (int)_trackInfo[i].msf >> 16 & 0xff,
                    259:                 (int)_trackInfo[i].msf >>  8 & 0xff,
                    260:                 (int)_trackInfo[i].msf       & 0xff,
                    261:                 (int)_trackInfo[i].nblocks,
                    262:                 (int)_trackInfo[i].nblocks);
                    263:         }
                    264:     }
                    265: #endif
                    266: 
                    267:     return(result);
                    268: }
                    269: 
                    270: /* Decommission all nubs. */
                    271: IOReturn
                    272: IOCDDrive::decommissionMedia(bool forcible)
                    273: {
                    274:     IOReturn result;
                    275: 
                    276:     result = kIOReturnSuccess;
                    277: 
                    278:     lockForArbitration();
                    279: 
                    280:     if (_mediaNub) {
                    281:         result = tearDown(_mediaNub);
                    282:         if (forcible || (result == kIOReturnSuccess)) {
                    283:             _mediaNub = 0;
                    284:         }
                    285:     }
                    286: 
                    287:     /* If it's not a forcible teardown, we only attempt to decommission the
                    288:      * audio portion of the CD if all the data tracks decommissioned successfully.
                    289:      */
                    290: 
                    291:     if (forcible || (result == kIOReturnSuccess)) {
                    292:         if (_acNub) {
                    293:             result = tearDown(_acNub);
                    294:             if (forcible || (result == kIOReturnSuccess)) {
                    295:                 _acNub = 0;
                    296:             }
                    297:         }
                    298:     }
                    299: 
                    300:     if (forcible || (result == kIOReturnSuccess)) {
                    301:         initMediaStates();                     /* deny existence of any media */
                    302:         _tocInfoCached = false;
                    303:     }
                    304: 
                    305:     unlockForArbitration();
                    306: 
                    307:     return(result);
                    308: }
                    309: 
                    310: /* We should check with other clients using the other nubs before we allow
                    311:  * the client of the IOCDMediaNub to eject the media.
                    312:  */
                    313: IOReturn
                    314: IOCDDrive::ejectMedia(void)
                    315: {
                    316:     /* For now, we don't check with the other clients. */
                    317:     
                    318:     return(super::ejectMedia());
                    319: }
                    320: 
                    321: IOReturn
                    322: IOCDDrive::getAudioStatus(struct audioStatus *status)
                    323: {
                    324:     return(_CDprovider->getAudioStatus(status));
                    325: }
                    326: 
                    327: const char *
                    328: IOCDDrive::getDeviceTypeName(void)
                    329: {
                    330:     return(kDeviceTypeCDROM);
                    331: }
                    332: 
                    333: UInt32
                    334: IOCDDrive::getTrackBlocks(UInt32 track)
                    335: {
                    336:     if (trackExists(track)) {
                    337:         return(_trackInfo[track].nblocks);
                    338:     } else {
                    339:         return(0);
                    340:     }
                    341: }
                    342: 
                    343: UInt32
                    344: IOCDDrive::getTrackStartBlock(UInt32 track)
                    345: {
                    346:     if (trackExists(track)) {
                    347:         return(_trackInfo[track].lba);
                    348:     } else {
                    349:         return(0);
                    350:     }
                    351: }
                    352: 
                    353: bool
                    354: IOCDDrive::init(OSDictionary * properties)
                    355: {
                    356:     int i;
                    357: 
                    358:     for (i = 0; i < kTrackEntries; i++) {
                    359:         bzero((void *)&_trackInfo[i],sizeof(struct trackInfo));
                    360:     }
                    361: 
                    362:     _acNub = NULL;
                    363:     _mediaNub = NULL;
                    364: 
                    365:     _tocInfoCached = false;
                    366:     
                    367:     return(super::init(properties));
                    368: }
                    369: 
                    370: IOMedia *
                    371: IOCDDrive::instantiateDesiredMediaObject(void)
                    372: {
                    373:     return(new IOCDMedia);
                    374: }
                    375: 
                    376: IOReturn
                    377: IOCDDrive::readAudioData(positioningType addressType,cdAddress address,
                    378:                                        UInt8 blockCount,UInt8 *buffer)
                    379: {
                    380:     return(_CDprovider->readAudioData(addressType,address,blockCount,buffer));
                    381: }
                    382: 
                    383: IOReturn
                    384: IOCDDrive::readAudioSubcodes(positioningType addressType,cdAddress address,
                    385:                                        UInt8 blockCount,UInt8 *buffer)
                    386: {
                    387:     return(_CDprovider->readAudioSubcodes(addressType,address,blockCount,buffer));
                    388: }
                    389: 
                    390: IOReturn
                    391: IOCDDrive::readAudioVolume(UInt8 *leftVolume,UInt8 *rightVolume)
                    392: {
                    393:     return(_CDprovider->readAudioVolume(leftVolume,rightVolume));
                    394: }
                    395: 
                    396: IOReturn
                    397: IOCDDrive::readAudioWithQSubcode(positioningType addressType,cdAddress address,
                    398:                                           UInt8 blockCount,UInt8 *buffer)
                    399: {
                    400:     return(_CDprovider->readAudioWithQSubcode(addressType,address,blockCount,buffer));
                    401: }
                    402: 
                    403: IOReturn
                    404: IOCDDrive::readAudioWithAllSubcodes(positioningType addressType,cdAddress address,
                    405:                                           UInt8 blockCount,UInt8 *buffer)
                    406: {
                    407:     return(_CDprovider->readAudioWithAllSubcodes(addressType,address,blockCount,buffer));
                    408: }
                    409: 
                    410: IOReturn
                    411: IOCDDrive::readEntireTOC(struct macEntireToc *buffer)
                    412: {
                    413:     /* Return our cached TOC info. */
                    414:     
                    415:     int i;
                    416:     int out;
                    417: 
                    418:     bzero(buffer,sizeof(struct macEntireToc));
                    419: 
                    420:     out = 0;
                    421:     
                    422:     /* Copy A0, A1, A2: */
                    423: 
                    424:     for (i = 0xa0; i <= 0xa2; i++) {
                    425:         if (_trackInfo[i].track != 0) {                /* then the track exists */
                    426:             buffer->entries[out].trackPoint    = _trackInfo[i].track;
                    427:             buffer->entries[out].type          = (trackType)_trackInfo[i].control;
                    428:             buffer->entries[out].pMin          = _trackInfo[i].msf >> 16;
                    429:             buffer->entries[out].pSec          = _trackInfo[i].msf >>  8;
                    430:             buffer->entries[out].pFrame        = _trackInfo[i].msf & 0xff;
                    431:             
                    432:             out++;
                    433:         }
                    434:     }
                    435: 
                    436:     /* Copy tracks: */
                    437:     
                    438:     for (i = 1; i <= 99; i++) {
                    439:         if (_trackInfo[i].track != 0) {                /* then the track exists */
                    440:             buffer->entries[out].trackPoint    = _trackInfo[i].track;
                    441:             buffer->entries[out].type          = (trackType)_trackInfo[i].control;
                    442:             buffer->entries[out].pMin          = _trackInfo[i].msf >> 16;
                    443:             buffer->entries[out].pSec          = _trackInfo[i].msf >>  8;
                    444:             buffer->entries[out].pFrame        = _trackInfo[i].msf & 0xff;
                    445: 
                    446:             out++;
                    447:         }
                    448:     }
                    449:     return(kIOReturnSuccess);
                    450: }
                    451: 
                    452: IOReturn
                    453: IOCDDrive::readHeader(UInt32 blockAddress,struct headerInfo *buffer)
                    454: {
                    455:     return(_CDprovider->readHeader(blockAddress,buffer));
                    456: }
                    457: 
                    458: IOReturn
                    459: IOCDDrive::readISRC(UInt32 track,UInt8 *buffer,bool *found)
                    460: {
                    461:     return(_CDprovider->readISRC(track,buffer,found));
                    462: }
                    463: 
                    464: IOReturn
                    465: IOCDDrive::readLeadOutAddress(cdAddress *buffer)
                    466: {
                    467:     if (!_tocInfoCached) {
                    468:         return(kIOReturnNotReady);
                    469:     }
                    470:         
                    471:     *buffer = (cdAddress)_trackInfo[0xaa].msf;
                    472:     return(kIOReturnSuccess);
                    473: }
                    474: 
                    475: IOReturn
                    476: IOCDDrive::readMCN(UInt8 *buffer,bool *found)
                    477: {
                    478:     return(_CDprovider->readMCN(buffer,found));
                    479: }
                    480: 
                    481: IOReturn
                    482: IOCDDrive::readQSubcodes(struct qSubcodeTocInfo *buffer,UInt32 bufSize)
                    483: {
                    484:     return(_CDprovider->readQSubcodes(buffer,bufSize));
                    485: }
                    486: 
                    487: IOReturn
                    488: IOCDDrive::readSessionInfo(struct sessionInfo *info)
                    489: {
                    490:     IOReturn result;
                    491:     struct rawToc *toc;
                    492:     struct tocTrackDescriptor *d;
                    493: 
                    494:     toc = IONew(struct rawToc,1);
                    495:     if (toc == NULL) {
                    496:         return(kIOReturnNoMemory);
                    497:     }
                    498: 
                    499:     result = _CDprovider->readTOC(toc,sizeof(struct rawToc),ktocSessionInfo);
                    500: 
                    501:     if (result == kIOReturnSuccess) {
                    502:         info->firstSessionNumber       = toc->header.firstTrack;
                    503:         info->lastSessionNumber        = toc->header.lastTrack;
                    504:         d = &toc->descriptors[0];
                    505:         info->trackNumber              = d->track;
                    506:         info->info.type                        = (trackType)(d->adrControl);
                    507:         info->info.address             = (cdAddress)(  d->lba_3 << 24 |
                    508:                                                     d->lba_2 << 16 |
                    509:                                                     d->lba_1 <<  8 |
                    510:                                                     d->lba_0);
                    511:     }
                    512:     
                    513:     IODelete(toc,struct rawToc,1);
                    514: 
                    515:     return(result);
                    516: }
                    517: 
                    518: IOReturn
                    519: IOCDDrive::readSubcodeBuffer(UInt8 *buffer,bool purge,UInt32 entryCount)
                    520: {
                    521:     return(_CDprovider->readSubcodeBuffer(buffer,purge,entryCount));
                    522: }
                    523: 
                    524: IOReturn
                    525: IOCDDrive::readTheQSubcode(struct qSubcode *buffer)
                    526: {
                    527:     return(_CDprovider->readTheQSubcode(buffer));
                    528: }
                    529: 
                    530: IOReturn
                    531: IOCDDrive::readTrackInfo(UInt32 startingTrack,struct trackTypeInfo *buf,UInt32 bufSize)
                    532: {
                    533:     struct trackTypeInfo *end;
                    534: 
                    535:     if (!_tocInfoCached) {
                    536:         return(kIOReturnNotReady);
                    537:     }
                    538:         
                    539:     end = &buf[bufSize / sizeof(struct trackTypeInfo)];
                    540: 
                    541:     /* Copy till we run past track 99 or the buffer runs out. */
                    542:     
                    543:     while (startingTrack <= 99) {
                    544:         if (buf >= end) {
                    545:             return(kIOReturnSuccess);
                    546:         }
                    547:         if (_trackInfo[startingTrack].track != 0) {    /* then the track exists */
                    548:             buf->type = (trackType)_trackInfo[startingTrack].control;
                    549:             buf->address = _trackInfo[startingTrack].msf;
                    550:             
                    551:             buf++;
                    552:         }
                    553:         
                    554:         startingTrack++;
                    555:     }
                    556: 
                    557:     return(kIOReturnSuccess);
                    558: }
                    559: 
                    560: IOReturn
                    561: IOCDDrive::readTrackLimits(UInt32 *first,UInt32 *last)
                    562: {
                    563:     int i;
                    564:     bool gotFirst;
                    565: 
                    566:     if (!_tocInfoCached) {
                    567:         return(kIOReturnNotReady);
                    568:     }
                    569: 
                    570:     gotFirst = false;
                    571: 
                    572:     for (i = 1; i < 99; i++) {
                    573:         if (_trackInfo[i].track == 0) {                /* track doesn't exist; skip it */
                    574:             continue;
                    575:         }
                    576: 
                    577:         if (!gotFirst) {
                    578:             *first = _trackInfo[i].track;
                    579:             gotFirst = true;
                    580:         }
                    581: 
                    582:         /* Last will keep changing till we end the loop and will end up right. */
                    583:         
                    584:         *last = _trackInfo[i].track;
                    585:     }
                    586:     
                    587:     return(kIOReturnSuccess);
                    588: }
                    589: 
                    590: IOReturn
                    591: IOCDDrive::setAudioStopAddress(positioningType addressType,cdAddress address)
                    592: {
                    593:     return(_CDprovider->setAudioStopAddress(addressType,address));
                    594: }
                    595: 
                    596: bool
                    597: IOCDDrive::setProvider(IOService * provider)
                    598: {
                    599:     _CDprovider = OSDynamicCast(IOCDDriveNub,provider);
                    600: 
                    601:     if (_CDprovider == NULL) {
                    602:         return(false);
                    603:     } else {
                    604:         super::setProvider(provider);
                    605:         return(true);
                    606:     }
                    607: }
                    608: 
                    609: void
                    610: IOCDDrive::setTrackInfoEntry(struct tocTrackDescriptor *d,struct trackInfo *t)
                    611: {
                    612:     t->track = d->track;
                    613:     t->control = d->adrControl & 0xff;
                    614:     if ((d->adrControl & 0xf0) == 0x10) {      /* then Qsub info is present */
                    615:         t->control = d->adrControl & 0xff;
                    616:         if (d->adrControl & tt_data) {         /* it's a data track */
                    617:             t->isData = true;
                    618:         } else {
                    619:             t->isData = false;
                    620:         }
                    621:     }
                    622: }
                    623: 
                    624: IOReturn
                    625: IOCDDrive::setVolume(UInt8 leftVolume,UInt8 rightVolume)
                    626: {
                    627:     return(_CDprovider->setVolume(leftVolume,rightVolume));
                    628: }
                    629: 
                    630: bool
                    631: IOCDDrive::showStats(void)
                    632: {
                    633:     return(false);
                    634: }
                    635: 
                    636: bool
                    637: IOCDDrive::trackExists(UInt32 track)
                    638: {
                    639:     if (_trackInfo[track].track != 0) {
                    640:         return(true);
                    641:     } else {
                    642:         return(false);
                    643:     }
                    644: }
                    645: 
                    646: bool
                    647: IOCDDrive::trackIsAudio(UInt32 track)
                    648: {
                    649:     if (trackExists(track)) {
                    650:         return(!_trackInfo[track].isData);
                    651:     } else {
                    652:         return(false);
                    653:     }
                    654: }
                    655: 
                    656: bool
                    657: IOCDDrive::trackIsData(UInt32 track)
                    658: {
                    659:     if (trackExists(track)) {
                    660:         return(_trackInfo[track].isData);
                    661:     } else {
                    662:         return(false);
                    663:     }
                    664: }
                    665: 
                    666: void
                    667: IOCDDrive::dump(char *buf,int count)
                    668: {
                    669:     static char string[17] = "xxxxxxxxxxxxxxxx";
                    670:     
                    671:     short i;
                    672:     char  c;
                    673:     char *cp;  
                    674: 
                    675:     if (!count) return;
                    676: 
                    677:     i = 0;
                    678:     cp = buf;
                    679:     do {
                    680:        c = *cp;
                    681:        IOLog("%02x ",(c & 0xff));
                    682:        c &= 0x7f;
                    683:        string[i % 16] = /* (isprint(c) || (c == ' ')) ? c : */ '.';
                    684:        if ((i % 16)==15)
                    685:            IOLog("%s\n",string);
                    686:        cp++; i++;
                    687:     } while (--count);
                    688: 
                    689:     /* pad out for last line */
                    690:     if (i % 16) {          /* then a shortie left */
                    691:        string[i % 16] = '\0';
                    692:        while (i % 16) {
                    693:            IOLog("   ");
                    694:            i++;    
                    695:        }
                    696:        IOLog("%s\n",string);   
                    697:     }
                    698: }

unix.superglobalmegacorp.com

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