Annotation of XNU/iokit/Families/IOSCSICDDrive/IOSCSICDDrive.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: #include <IOKit/IOLib.h>
        !            24: #include <IOKit/IOReturn.h>
        !            25: #include <IOKit/IOMemoryDescriptor.h>
        !            26: #include <IOKit/scsi/IOSCSIDeviceInterface.h>
        !            27: #include <IOKit/storage/scsi/IOSCSICDDrive.h>
        !            28: #include <IOKit/storage/scsi/IOSCSICDDriveNub.h>
        !            29: 
        !            30: /* Device types that we intend to handle. */
        !            31: 
        !            32: const UInt8    DT_CDROM        = 0x05;         /* CD-ROM */
        !            33: 
        !            34: #define        super   IOSCSIHDDrive
        !            35: OSDefineMetaClassAndStructors(IOSCSICDDrive,IOSCSIHDDrive)
        !            36: 
        !            37: IOReturn
        !            38: IOSCSICDDrive::audioPlay(positioningType addressType,cdAddress address,audioPlayMode mode)
        !            39: {
        !            40:     return(doAudioPlayCommand(addressType,address,
        !            41:                               _audioStopAddress.type,_audioStopAddress.address));
        !            42: }
        !            43: 
        !            44: IOReturn
        !            45: IOSCSICDDrive::audioPause(bool pause)
        !            46: {
        !            47:     //xxxx
        !            48:     return(kIOReturnUnsupported);
        !            49: }
        !            50: 
        !            51: IOReturn
        !            52: IOSCSICDDrive::audioScan(positioningType addressType,cdAddress address,bool reverse)
        !            53: {
        !            54:     struct context *cx;
        !            55:     struct IOAudioScancdb *c;
        !            56:     IOSCSICommand *req;
        !            57:     SCSICDBInfo scsiCDB;
        !            58:     IOReturn result;
        !            59: 
        !            60:     cx = allocateContext();
        !            61:     if (cx == NULL) {
        !            62:         return(kIOReturnNoMemory);
        !            63:     }
        !            64:     
        !            65:     req = cx->scsireq;
        !            66: 
        !            67:     bzero( &scsiCDB, sizeof(scsiCDB) );
        !            68: 
        !            69:     c = (struct IOAudioScancdb *)&scsiCDB.cdb;
        !            70: 
        !            71:     c->opcode = SOP_AUDIOSCAN;
        !            72:     c->lunbits = 0;
        !            73:     if (!reverse) {
        !            74:         c->lunbits |= IOAudioScancdb::kForward;
        !            75:     }
        !            76: 
        !            77:     switch (addressType) {
        !            78: 
        !            79:         case kBlockAddress     :
        !            80:                                        c->start3 = address >> 24;
        !            81:                                         c->start2 = address >> 16;
        !            82:                                         c->start1 = address >>  8;
        !            83:                                        c->start0 = address & 0xff;
        !            84:                                         c->ctlbyte = IOAudioScancdb::kType_lba;
        !            85:                                         break;
        !            86:             
        !            87:         case kAbsoluteTime     :
        !            88:                                        c->start3 = address >> 24;
        !            89:                                         c->start2 = address >> 16;
        !            90:                                         c->start1 = address >>  8;
        !            91:                                        c->start0 = address & 0xff;
        !            92:                                         c->ctlbyte = IOAudioScancdb::kType_msf;
        !            93:                                         break;
        !            94:             
        !            95:         case kTrackNumber      :
        !            96:                                        c->start3 = 0;
        !            97:                                         c->start2 = 0;
        !            98:                                         c->start1 = 0;
        !            99:                                        c->start0 = address & 0xff;
        !           100:                                         c->ctlbyte = IOAudioScancdb::kType_track;
        !           101:                                        break;
        !           102:             
        !           103:         default                        :
        !           104:                                         deleteContext(cx);
        !           105:                                        return(kIOReturnBadArgument);
        !           106:     };
        !           107: 
        !           108:     scsiCDB.cdbLength = 6;
        !           109:     scsiCDB.cdbFlags = 0;
        !           110:     req->setCDB( &scsiCDB );
        !           111:     req->setPointers(cx->senseDataDesc, 255, false, true);    
        !           112:     req->setPointers( cx->memory, 0, false );
        !           113:     req->setTimeout(1 * 1000);
        !           114: 
        !           115:     result = simpleSynchIO(cx);
        !           116: 
        !           117:     deleteContext(cx);
        !           118: 
        !           119:     return(result);
        !           120: }
        !           121: 
        !           122: IOReturn
        !           123: IOSCSICDDrive::audioTrackSearch(positioningType addressType,cdAddress address,
        !           124:                                                bool startPlay,audioPlayMode mode)
        !           125: {
        !           126:     IOReturn result;
        !           127:     UInt32 lba;
        !           128:     
        !           129:     result = convertMSFToLba(&lba,address);
        !           130:     if (result != kIOReturnSuccess) {
        !           131:         return(result);
        !           132:     }
        !           133: 
        !           134:     result = seek(lba);
        !           135:     if (result != kIOReturnSuccess) {
        !           136:         return(result);
        !           137:     }
        !           138:     
        !           139:     if (startPlay) {
        !           140:         return(audioPlay(addressType,address,mode));
        !           141:     } else {
        !           142:         return(result);
        !           143:     }
        !           144: }
        !           145: 
        !           146: IOReturn
        !           147: IOSCSICDDrive::convertMSFToLba(UInt32 *lba,cdAddress address)
        !           148: {
        !           149:     //xxx wrong! incoming msf values are bcd!
        !           150:     *lba =     ((address >> 16) * 75 * 60)     +       /* min */
        !           151:                 ((address >>  8) * 75)         +       /* sec */
        !           152:                 (address & 0xff);                      /* frames */
        !           153: 
        !           154:     return(kIOReturnSuccess);
        !           155: }
        !           156: 
        !           157: bool
        !           158: IOSCSICDDrive::deviceTypeMatches(UInt8 inqBuf[],UInt32 inqLen)
        !           159: {
        !           160:     if ((inqBuf[0] & 0x1f) == DT_CDROM) {
        !           161: //        IOLog("%s[IOSCSICDDrive]::deviceTypeMatches, returning TRUE\n",getName());  
        !           162:         return(true);
        !           163:     } else {
        !           164: //        IOLog("%s[IOSCSICDDrive]::deviceTypeMatches, returning FALSE\n",getName());  
        !           165:         return(false);                 /* we don't handle other devices */        
        !           166:     }
        !           167: }
        !           168: 
        !           169: IOReturn
        !           170: IOSCSICDDrive::doAudioPlayCommand(positioningType startType,cdAddress startAddress,
        !           171:                                             positioningType endType,cdAddress endAddress)
        !           172: {
        !           173:     struct context *cx;
        !           174:     struct IOAudioPlaycdb *c;
        !           175:     struct IOAudioPlayMSFcdb *p;
        !           176:     IOSCSICommand *req;
        !           177:     SCSICDBInfo scsiCDB;
        !           178:     IOReturn result;
        !           179:     UInt32 length;
        !           180: 
        !           181:     /* Can we return an error here, or must we ensure that start and stop are always
        !           182:      * locally converted to the same units before we use them?
        !           183:      */
        !           184:     if (startType != endType) {
        !           185:         return(kIOReturnBadArgument);
        !           186:     }
        !           187: 
        !           188:     if (startType != kAbsoluteTime || startType != kBlockAddress) {
        !           189:         return(kIOReturnBadArgument);
        !           190:     }
        !           191: 
        !           192:     cx = allocateContext();
        !           193:     if (cx == NULL) {
        !           194:         return(kIOReturnNoMemory);
        !           195:     }
        !           196:     
        !           197:     req = cx->scsireq;
        !           198: 
        !           199:     bzero( &scsiCDB, sizeof(scsiCDB) );
        !           200: 
        !           201:     if (startType == kBlockAddress) {          /* use PlayAudio command */
        !           202:         c = (struct IOAudioPlaycdb *)scsiCDB.cdb;
        !           203: 
        !           204:         c->opcode      = SOP_PLAYAUDIO;
        !           205:         c->lunbits     = 0;
        !           206:         c->lba_3       = startAddress >> 24;
        !           207:         c->lba_2       = startAddress >> 16;
        !           208:         c->lba_1       = startAddress >>  8;
        !           209:         c->lba_0       = startAddress & 0xff;
        !           210:         c->reserved1   = 0;        
        !           211:         length = endAddress - startAddress;
        !           212:         c->len_hi      = length >> 8;
        !           213:         c->len_lo      = length & 0xff;
        !           214:         c->ctlbyte     = 0;
        !           215:         
        !           216:     } else {                                   /* absolute time: use PlayAudioMSF */
        !           217:         
        !           218:         p = (struct IOAudioPlayMSFcdb *)scsiCDB.cdb;
        !           219: 
        !           220:         p->opcode      = SOP_PLAYAUDIOMSF;
        !           221:         p->lunbits     = 0;
        !           222:         p->reserved1   = 0;
        !           223:         p->start_m     = startAddress >> 16;
        !           224:         p->start_s     = startAddress >>  8;
        !           225:         p->start_f     = startAddress & 0xff;
        !           226:         p->end_m       = endAddress >> 16;
        !           227:         p->end_s       = endAddress >>  8;
        !           228:         p->end_f       = endAddress & 0xff;
        !           229:         p->ctlbyte     = 0;
        !           230:     }
        !           231: 
        !           232:     scsiCDB.cdbLength = 10;
        !           233:     req->setCDB( &scsiCDB );
        !           234:     req->setPointers(cx->senseDataDesc, 255, false, true);    
        !           235: 
        !           236:     req->setPointers( cx->memory, 0, false );
        !           237:     req->setTimeout( 1000 );
        !           238: 
        !           239:     result = simpleSynchIO(cx);
        !           240: 
        !           241:     deleteContext(cx);
        !           242: 
        !           243:     return(result);
        !           244: }
        !           245: 
        !           246: IOReturn
        !           247: IOSCSICDDrive::getAudioStatus(struct audioStatus *status)
        !           248: {
        !           249: const UInt8 qBufLen = 16;
        !           250:     IOReturn result;
        !           251:     UInt8 *tempBuf;
        !           252: 
        !           253:     /* Get a buffer for the returned data: */
        !           254:     
        !           255:     result = allocateTempBuffer(&tempBuf,qBufLen);
        !           256:     if (result != kIOReturnSuccess) {
        !           257:         return(kIOReturnNoMemory);
        !           258:     }
        !           259: 
        !           260:     result = readSubchannel(tempBuf,qBufLen,0,IORSCcdb::kCurrentPosition);
        !           261: 
        !           262:     if ((result == kIOReturnSuccess) && ((tempBuf[5] & 0xf0) == 0x10)) {       /* we got the data */
        !           263:         status->playMode       = _audioPlayMode;
        !           264:         status->type           = (trackType)(tempBuf[5] & 0xff);
        !           265:         status->address                =   tempBuf[ 9] << 16 |
        !           266:                                     tempBuf[10] <<  8 |
        !           267:                                     tempBuf[11];
        !           268:         switch (tempBuf[1]) {                  /* convert audio status */
        !           269: 
        !           270: 
        !           271:             case 0x11:
        !           272:                             status->status = kAudioPlayInProgress;
        !           273:                             break;
        !           274: 
        !           275:             case 0x12:
        !           276:                             status->status = kHoldTrackMode;
        !           277:                             break;
        !           278: 
        !           279:             case 0x13:
        !           280:                             status->status = kAudioPlayCompleted;
        !           281:                             break;
        !           282: 
        !           283:             case 0x14:
        !           284:                             status->status = kError;
        !           285:                             break;
        !           286: 
        !           287:             case 0x15:
        !           288:                             status->status = kAudioPlayNotRequested;
        !           289:                             break;
        !           290: 
        !           291:             case 0x00:
        !           292:             default:
        !           293:                             status->status = kUnknown;
        !           294:                             break;
        !           295:         }
        !           296:     }
        !           297:     deleteTempBuffer(tempBuf,qBufLen);
        !           298: 
        !           299:     return(result);
        !           300: }
        !           301: 
        !           302: const char *
        !           303: IOSCSICDDrive::getDeviceTypeName(void)
        !           304: {
        !           305:     return(kDeviceTypeCDROM);
        !           306: }
        !           307: 
        !           308: bool
        !           309: IOSCSICDDrive::init(OSDictionary * properties)
        !           310: {
        !           311:     initAudioModes();
        !           312: 
        !           313:     _audioStopAddress.address  = 0L;
        !           314:     _audioStopAddress.type     = kBlockAddress;
        !           315: 
        !           316:     return(super::init(properties));
        !           317: }
        !           318: 
        !           319: void
        !           320: IOSCSICDDrive::initAudioModes(void)
        !           321: {
        !           322:     _audioPlayMode = stereo;
        !           323:     _leftVolume = 0xff;
        !           324:     _leftPortChannel = playModeToDriveBits(_audioPlayMode,kLeft);
        !           325:     _rightVolume = 0xff;
        !           326:     _rightPortChannel = playModeToDriveBits(_audioPlayMode,kRight);
        !           327: }
        !           328: 
        !           329: IOService *
        !           330: IOSCSICDDrive::instantiateNub(void)
        !           331: {
        !           332:     IOService *nub;
        !           333: 
        !           334:     /* Instantiate a generic CDROM nub so a generic driver can match above us. */
        !           335:     
        !           336:     nub = new IOSCSICDDriveNub;
        !           337:     return(nub);
        !           338: }
        !           339: 
        !           340: void
        !           341: IOSCSICDDrive::mediaGone(void)
        !           342: {
        !           343: }
        !           344: 
        !           345: /* Convert the audioPlayMode signal routing bits to the drive's bits. */
        !           346: 
        !           347: UInt8
        !           348: IOSCSICDDrive::playModeToDriveBits(audioPlayMode mode,channel chan)
        !           349: {
        !           350:     UInt8 bits;
        !           351:     int shift;
        !           352: 
        !           353:     bits = 0;
        !           354: 
        !           355:     switch (chan) {
        !           356: 
        !           357:         case kLeft     :       shift = shift_Left_Channel; break;
        !           358:         case kRight    :       shift = shift_Right_Channel; break;
        !           359: 
        !           360:         default                :       return(bits);
        !           361:     }
        !           362: 
        !           363:     if (mode & (signal_Left << shift)) {
        !           364:         bits |= drive_left_signal;
        !           365:     }
        !           366:     if (mode & (signal_Right << shift)) {
        !           367:         bits |= drive_right_signal;
        !           368:     }
        !           369: 
        !           370:     return(bits);
        !           371: }
        !           372: 
        !           373: IOReturn
        !           374: IOSCSICDDrive::readAudioData(positioningType addressType,cdAddress address,
        !           375:                                        UInt8 blockCount,UInt8 *buffer)
        !           376: {
        !           377:     /* what about buffer vs. IOMemoryDescriptor? */
        !           378:     
        !           379:     //xxxx
        !           380:     return(kIOReturnUnsupported);
        !           381: }
        !           382: 
        !           383: IOReturn
        !           384: IOSCSICDDrive::readAudioSubcodes(positioningType addressType,cdAddress address,
        !           385:                                        UInt8 blockCount,UInt8 *buffer)
        !           386: {
        !           387:     /* what about buffer vs. IOMemoryDescriptor? */
        !           388:     
        !           389:    // xxxx
        !           390:     return(kIOReturnUnsupported);
        !           391: }
        !           392: 
        !           393: IOReturn
        !           394: IOSCSICDDrive::readAudioVolume(UInt8 *leftVolume,UInt8 *rightVolume)
        !           395: {
        !           396:     /* Return the cached values. */
        !           397:     
        !           398:     *leftVolume                = _leftVolume;
        !           399:     *rightVolume       = _rightVolume;
        !           400: 
        !           401:     return(kIOReturnSuccess);
        !           402: }
        !           403: 
        !           404: IOReturn
        !           405: IOSCSICDDrive::readAudioWithQSubcode(positioningType addressType,cdAddress address,
        !           406:                                           UInt8 blockCount,UInt8 *buffer)
        !           407: {
        !           408:     /* what about buffer vs. IOMemoryDescriptor? */
        !           409:     
        !           410:     //xxxx
        !           411:     return(kIOReturnUnsupported);
        !           412: }
        !           413: 
        !           414: IOReturn
        !           415: IOSCSICDDrive::readAudioWithAllSubcodes(positioningType addressType,cdAddress address,
        !           416:                                           UInt8 blockCount,UInt8 *buffer)
        !           417: {
        !           418:     /* what about buffer vs. IOMemoryDescriptor? */
        !           419:     
        !           420:     //xxxx
        !           421:     return(kIOReturnUnsupported);
        !           422: }
        !           423: 
        !           424: IOReturn
        !           425: IOSCSICDDrive::readHeader(UInt32 blockAddress,struct headerInfo *buffer)
        !           426: {
        !           427: const UInt8 hdrBufLen = 24;
        !           428:     struct context *cx;
        !           429:     struct IOReadHeadercdb *c;
        !           430:     IOSCSICommand *req;
        !           431:     SCSICDBInfo scsiCDB;
        !           432:     IOReturn result;
        !           433:     UInt8 *tempBuf;
        !           434: 
        !           435:     bzero(buffer,sizeof(struct headerInfo));
        !           436: 
        !           437:     /* Get a buffer for the returned data: */
        !           438:     
        !           439:     result = allocateTempBuffer(&tempBuf,hdrBufLen);
        !           440:     if (result != kIOReturnSuccess) {
        !           441:         return(kIOReturnNoMemory);
        !           442:     }
        !           443:     
        !           444:     cx = allocateContext();
        !           445:     if (cx == NULL) {
        !           446:         return(kIOReturnNoMemory);
        !           447:     }
        !           448:     
        !           449:     req = cx->scsireq;
        !           450: 
        !           451:     bzero( &scsiCDB, sizeof(scsiCDB) );
        !           452: 
        !           453:     c = (struct IOReadHeadercdb *)scsiCDB.cdb;
        !           454: 
        !           455:     c->opcode = SOP_READHEADER;
        !           456:     c->lunbits = 0;
        !           457:     c->lunbits |= IOReadHeadercdb::kMSF;               /* return results in M:S:F format */
        !           458:     c->lba_3 = blockAddress >> 24;
        !           459:     c->lba_2 = blockAddress >> 18;
        !           460:     c->lba_1 = blockAddress >>  8;
        !           461:     c->lba_0 = blockAddress & 0xff;        
        !           462:     c->reserved1 = 0;
        !           463:     c->len_hi = 0;
        !           464:     c->len_lo = hdrBufLen;
        !           465:     c->ctlbyte = 0;
        !           466:     
        !           467:     scsiCDB.cdbLength = 10;
        !           468:     req->setCDB( &scsiCDB );
        !           469:     req->setPointers(cx->senseDataDesc, 255, false, true);    
        !           470: 
        !           471:     cx->memory = IOMemoryDescriptor::withAddress((void *)tempBuf,
        !           472:                                                  hdrBufLen,
        !           473:                                                  kIODirectionIn);
        !           474:     req->setPointers( cx->memory, hdrBufLen, false );
        !           475: 
        !           476:     req->setTimeout( 1000 );
        !           477:     
        !           478:     result = simpleSynchIO(cx);
        !           479: 
        !           480:     deleteContext(cx);
        !           481: 
        !           482:     if (result == kIOReturnSuccess) {          /* return the header info */
        !           483:         buffer->mode = (dataMode)(tempBuf[0]);
        !           484:         buffer->address =      tempBuf[4] << 24 ||
        !           485:                                 tempBuf[5] << 16 ||
        !           486:                                 tempBuf[6] <<  8 ||
        !           487:                                 tempBuf[7];
        !           488:     }
        !           489:     
        !           490:     deleteTempBuffer(tempBuf,hdrBufLen);
        !           491: 
        !           492:     return(result);
        !           493: }
        !           494: 
        !           495: IOReturn
        !           496: IOSCSICDDrive::readISRC(UInt32 track,UInt8 *buffer,bool *found)
        !           497: {
        !           498:     return(readISRCMCN(IORSCcdb::kISRC,track,buffer,found));
        !           499: }
        !           500: 
        !           501: /* Since the ISRC and MCN are the same size and behave the same, we use common code. */
        !           502: IOReturn
        !           503: IOSCSICDDrive::readISRCMCN(UInt8 dataformat,UInt32 track,UInt8 *buffer,bool *found)
        !           504: {
        !           505: const UInt8 mcnISRCBufLen = 24;
        !           506:     IOReturn result;
        !           507:     UInt8 *tempBuf;
        !           508: 
        !           509:     *found = false;                    /* assume no ISRC/MCN will be found */
        !           510:     bzero(buffer,mcnISRCBufLen);
        !           511:     
        !           512:     /* Get a buffer for the returned data: */
        !           513:     
        !           514:     result = allocateTempBuffer(&tempBuf,mcnISRCBufLen);
        !           515:     if (result != kIOReturnSuccess) {
        !           516:         return(kIOReturnNoMemory);
        !           517:     }
        !           518: 
        !           519:     result = readSubchannel(tempBuf,mcnISRCBufLen,track,dataformat);
        !           520: 
        !           521:     if ((result == kIOReturnSuccess) && (tempBuf[8] & 0x80)) { /* return the ISRC/MCN */
        !           522:         bcopy(buffer,&tempBuf[9],15);
        !           523:         *found = true;
        !           524:     }
        !           525:     
        !           526:     deleteTempBuffer(tempBuf,mcnISRCBufLen);
        !           527: 
        !           528:     return(result);
        !           529: }
        !           530: 
        !           531: IOReturn
        !           532: IOSCSICDDrive::readMCN(UInt8 *buffer,bool *found)
        !           533: {
        !           534:     return(readISRCMCN(IORSCcdb::kMCN,0,buffer,found));                /* any track will do */
        !           535: }
        !           536: 
        !           537: 
        !           538: IOReturn
        !           539: IOSCSICDDrive::readQSubcodes(struct qSubcodeTocInfo *buffer,UInt32 bufSize)
        !           540: {
        !           541:     /* what about buffer vs. IOMemoryDescriptor? */
        !           542:     
        !           543:     //xxxx
        !           544:     return(kIOReturnUnsupported);
        !           545: }
        !           546: 
        !           547: IOReturn
        !           548: IOSCSICDDrive::readSubcodeBuffer(UInt8 *buffer,bool purge,UInt32 entryCount)
        !           549: {
        !           550:     /* what about buffer vs. IOMemoryDescriptor? */
        !           551:     
        !           552:     //xxxx
        !           553:     return(kIOReturnUnsupported);
        !           554: }
        !           555: 
        !           556: IOReturn
        !           557: IOSCSICDDrive::readSubchannel(UInt8 *buffer,UInt32 length,UInt8 track,UInt8 dataFormat)
        !           558: {
        !           559:     struct context *cx;
        !           560:     struct IORSCcdb *c;
        !           561:     IOSCSICommand *req;
        !           562:     SCSICDBInfo scsiCDB;
        !           563:     IOReturn result;
        !           564: 
        !           565:     cx = allocateContext();
        !           566:     if (cx == NULL) {
        !           567:         return(kIOReturnNoMemory);
        !           568:     }
        !           569:     
        !           570:     req = cx->scsireq;
        !           571: 
        !           572:     bzero( &scsiCDB, sizeof(scsiCDB) );
        !           573: 
        !           574:     bzero(buffer,length);
        !           575:     
        !           576:     c = (struct IORSCcdb *)(scsiCDB.cdb);
        !           577: 
        !           578:     c->opcode = SOP_READSUBCHANNEL;
        !           579:     c->lunbits = 0;
        !           580:     c->lunbits |= IORSCcdb::kMSF;
        !           581:     c->subq = IORSCcdb::kSubq;
        !           582:     c->dataformat = dataFormat;
        !           583:     c->track = track;                  /* any valid track will do */
        !           584:     c->reserved1 = 0;
        !           585:     c->reserved2 = 0;
        !           586:     c->len_hi = length >> 8;
        !           587:     c->len_lo = length & 0xff;
        !           588:     c->ctlbyte = 0;
        !           589:     
        !           590:     scsiCDB.cdbLength = 10;
        !           591:     req->setCDB( &scsiCDB );
        !           592:     req->setPointers(cx->senseDataDesc, 255, false, true);    
        !           593: 
        !           594:     cx->memory = IOMemoryDescriptor::withAddress((void *)buffer,
        !           595:                                                  length,
        !           596:                                                  kIODirectionIn);
        !           597:     req->setPointers( cx->memory, length, false );
        !           598: 
        !           599:     req->setTimeout( 1000 );
        !           600:     
        !           601:     result = simpleSynchIO(cx);
        !           602: 
        !           603:     deleteContext(cx);
        !           604: 
        !           605:     return(result);
        !           606: }
        !           607: 
        !           608: IOReturn
        !           609: IOSCSICDDrive::readTheQSubcode(struct qSubcode *buffer)
        !           610: {
        !           611: const UInt8 qBufLen = 16;
        !           612:     IOReturn result;
        !           613:     UInt8 *tempBuf;
        !           614: 
        !           615:     bzero(buffer,sizeof(struct qSubcode));
        !           616:     
        !           617:     /* Get a buffer for the returned data: */
        !           618:     
        !           619:     result = allocateTempBuffer(&tempBuf,qBufLen);
        !           620:     if (result != kIOReturnSuccess) {
        !           621:         return(kIOReturnNoMemory);
        !           622:     }
        !           623: 
        !           624:     result = readSubchannel(tempBuf,qBufLen,0, IORSCcdb::kCurrentPosition);
        !           625: 
        !           626:     if ((result == kIOReturnSuccess) && ((tempBuf[5] & 0xf0) == 0x10)) {       /* we got the data */
        !           627:         buffer->type           = (trackType)(tempBuf[ 5] & 0x0f);
        !           628:         buffer->track          = tempBuf[ 6];
        !           629:         buffer->index          = tempBuf[ 7];
        !           630:         buffer->absAddress     =   tempBuf[ 9] << 16 |
        !           631:                                     tempBuf[10] <<  8 |
        !           632:                                     tempBuf[11];
        !           633:         buffer->relAddress     =   tempBuf[13] << 16 |
        !           634:                                     tempBuf[14] <<  8 |
        !           635:                                     tempBuf[15];
        !           636:     }
        !           637:     
        !           638:     deleteTempBuffer(tempBuf,qBufLen);
        !           639: 
        !           640:     return(result);
        !           641: }
        !           642: 
        !           643: IOReturn
        !           644: IOSCSICDDrive::readTOC(struct rawToc *buffer,UInt32 length,tocFormat format)
        !           645: {
        !           646:     struct context *cx;
        !           647:     struct IOReadToccdb *c;
        !           648:     IOSCSICommand *req;
        !           649:     SCSICDBInfo scsiCDB;
        !           650:     IOReturn result;
        !           651: 
        !           652:     cx = allocateContext();
        !           653:     if (cx == NULL) {
        !           654:         return(kIOReturnNoMemory);
        !           655:     }
        !           656:     
        !           657:     req = cx->scsireq;
        !           658: 
        !           659:     bzero( &scsiCDB, sizeof(scsiCDB) );
        !           660: 
        !           661:     c = (struct IOReadToccdb *)scsiCDB.cdb;
        !           662: 
        !           663:     c->opcode = SOP_READTOC;
        !           664:     c->lunbits = 0;
        !           665:     if (format == ktocSCSI2MSF) {
        !           666:         c->lunbits |= IOReadToccdb::kMSF;
        !           667:     }
        !           668:     c->reserved1 = 0;
        !           669:     c->reserved2 = 0;
        !           670:     c->reserved3 = 0;
        !           671:     c->reserved4 = 0;
        !           672:     c->len_hi = length >> 8;
        !           673:     c->len_lo = length & 0xff;
        !           674:     c->ctlbyte = 0;
        !           675:     
        !           676:     switch (format) {
        !           677:         case ktocSCSI2MSF :
        !           678:         case ktocSCSI2LBA :
        !           679:                                 c->ctlbyte |= IOReadToccdb::kSCSI2;
        !           680:                                 break;
        !           681: 
        !           682:         case ktocSessionInfo :
        !           683:                                 c->ctlbyte |= IOReadToccdb::kSessionInfo;
        !           684:                                 break;
        !           685: 
        !           686:         case ktocQLeadin :
        !           687:                                 c->ctlbyte |= IOReadToccdb::kQLeadIn;
        !           688:                                 break;
        !           689:     }
        !           690:     
        !           691:     scsiCDB.cdbLength = 10;
        !           692:     req->setCDB( &scsiCDB );
        !           693:     req->setPointers(cx->senseDataDesc, 255, false, true);    
        !           694: 
        !           695:     cx->memory = IOMemoryDescriptor::withAddress((void *)buffer,
        !           696:                                                  length,
        !           697:                                                  kIODirectionIn);
        !           698:     req->setPointers( cx->memory, length, false );
        !           699: 
        !           700:     req->setTimeout( 1000 );    
        !           701: 
        !           702:     result = simpleSynchIO(cx);
        !           703: 
        !           704:     if ( result == kIOReturnUnderrun ) result = kIOReturnSuccess; 
        !           705: 
        !           706:     deleteContext(cx);
        !           707: 
        !           708:     return(result);
        !           709: }
        !           710: 
        !           711: /* We track media changes so we can:
        !           712:  *  - set default audio playMode and volume
        !           713:  */
        !           714: 
        !           715: IOReturn
        !           716: IOSCSICDDrive::reportMediaState(bool *mediaPresent,bool *changed)
        !           717: {
        !           718:     IOReturn result;
        !           719:     IOReturn internalResult;
        !           720: 
        !           721:     result = super::reportMediaState(mediaPresent,changed);
        !           722: 
        !           723: /**
        !           724:     IOLog("%s[IOSCSICDDrive]::reportMediaState; result=%s, changed = %s, present = %s\n",
        !           725:                 getName(),stringFromReturn(result),*changed ? "Y" : "N", *mediaPresent ? "Y" : "N");
        !           726: **/
        !           727:     
        !           728:     if ((result == kIOReturnSuccess) && *changed) {            /* the media state changed */
        !           729:         if (*mediaPresent) {                           /* new media inserted */
        !           730:             internalResult = setDefaultAudioModes();
        !           731:         } else {                                       /* media went away */
        !           732:             mediaGone();
        !           733:         }
        !           734:     }
        !           735: 
        !           736:     /* We don't return the result of our internal operations. But since they
        !           737:      * indicate a problem, we probably should report some kind of problem,
        !           738:      * or maybe just ignore the media change.
        !           739:      */
        !           740: 
        !           741:     return(result);
        !           742: }
        !           743: 
        !           744: IOReturn
        !           745: IOSCSICDDrive::seek(UInt32 lba)
        !           746: {
        !           747:     struct context *cx;
        !           748:     struct IOSeekcdb *c;
        !           749:     IOSCSICommand *req;
        !           750:     SCSICDBInfo scsiCDB;
        !           751:     IOReturn result;
        !           752: 
        !           753:     cx = allocateContext();
        !           754:     if (cx == NULL) {
        !           755:         return(kIOReturnNoMemory);
        !           756:     }
        !           757:     
        !           758:     req = cx->scsireq;
        !           759: 
        !           760:     bzero( &scsiCDB, sizeof(scsiCDB) );
        !           761: 
        !           762:     c = (struct IOSeekcdb *)(scsiCDB.cdb);
        !           763: 
        !           764:     c->opcode = SOP_SEEK;
        !           765:     c->lunbits = 0;
        !           766:     c->lba_3 = lba >> 24;
        !           767:     c->lba_2 = lba >> 16;
        !           768:     c->lba_1 = lba >>  8;
        !           769:     c->lba_0 = lba & 0xff;
        !           770:     c->reserved1 = 0;
        !           771:     c->reserved2 = 0;
        !           772:     c->reserved3 = 0;
        !           773:     c->ctlbyte = 0;
        !           774: 
        !           775:     scsiCDB.cdbLength = 10;
        !           776:     req->setCDB( &scsiCDB );
        !           777:     req->setPointers(cx->senseDataDesc, 255, false, true);    
        !           778: 
        !           779:     req->setPointers( cx->memory, 0, false );
        !           780: 
        !           781:     req->setTimeout( 5000 );
        !           782: 
        !           783:     result = simpleSynchIO(cx);
        !           784: 
        !           785:     deleteContext(cx);
        !           786: 
        !           787:     return(result);
        !           788: }
        !           789: 
        !           790: IOReturn
        !           791: IOSCSICDDrive::setAudioStopAddress(positioningType addressType,cdAddress address)
        !           792: {
        !           793:     /* We have to stash the stop address locally, because the client often sets
        !           794:      * the stop address before providing the start address. We can't send the
        !           795:      * stop address to the drive without a valid start address, because the pickup
        !           796:      * could be currently over a data track, which would return an error.
        !           797:      */
        !           798: 
        !           799:     _audioStopAddress.type     = addressType;
        !           800:     _audioStopAddress.address  = address;
        !           801: 
        !           802:     /* If the address is for block=0, we must stop any audio play in progress. */
        !           803:     
        !           804:     if (addressType == kBlockAddress && address == 0L) {       /* stop play */
        !           805:         return(doAudioPlayCommand(kAbsoluteTime,0xffffff,kAbsoluteTime,0));
        !           806:     } else {                                                   /* set new stop addr */
        !           807:         return(doAudioPlayCommand(kAbsoluteTime,0xffffff,addressType,address));
        !           808:     }
        !           809: }
        !           810: 
        !           811: IOReturn
        !           812: IOSCSICDDrive::setDefaultAudioModes(void)
        !           813: {
        !           814:     initAudioModes();
        !           815:     return(setVolume(_leftVolume,_rightVolume));
        !           816: }
        !           817: 
        !           818: struct audioPage {
        !           819:     UInt8 pagecode;
        !           820:     UInt8 paramlen;
        !           821:     UInt8 immed;
        !           822:     UInt8 reserved[5];
        !           823:     UInt8 leftportchannel;
        !           824:     UInt8 leftvolume;
        !           825:     UInt8 rightportchannel;
        !           826:     UInt8 rightvolume;
        !           827:     UInt8 port2channel;
        !           828:     UInt8 port2volume;
        !           829:     UInt8 port3channel;
        !           830:     UInt8 port3volume;
        !           831: };
        !           832: 
        !           833: IOReturn
        !           834: IOSCSICDDrive::setVolume(UInt8 leftVolume,UInt8 rightVolume)
        !           835: {
        !           836:     struct context *cx;
        !           837:     struct IOModeSelectcdb *c;
        !           838:     IOSCSICommand *req;
        !           839:     SCSICDBInfo scsiCDB;
        !           840:     IOReturn result;
        !           841:     struct audioPage *page;
        !           842: 
        !           843:     cx = allocateContext();
        !           844:     if (cx == NULL) {
        !           845:         return(kIOReturnNoMemory);
        !           846:     }
        !           847:     
        !           848:     req = cx->scsireq;
        !           849: 
        !           850:     bzero( &scsiCDB, sizeof(scsiCDB) );
        !           851: 
        !           852:     /* Set up a Mode Select for page 0x0e. We set volume and audioPlay mode. */
        !           853:     
        !           854:     result = allocateTempBuffer((UInt8 **)(&page),sizeof(struct audioPage));
        !           855:     if (result != kIOReturnSuccess) {
        !           856:         deleteContext(cx);
        !           857:         return(kIOReturnNoMemory);
        !           858:     }
        !           859: 
        !           860:     bzero(page,sizeof(struct audioPage)),
        !           861:     page->pagecode = 0x0e;
        !           862:     page->paramlen = 0x0e;
        !           863: 
        !           864:     page->leftportchannel = playModeToDriveBits(_audioPlayMode,kLeft);
        !           865:     page->leftvolume = leftVolume;
        !           866:     page->rightportchannel = playModeToDriveBits(_audioPlayMode,kRight);
        !           867:     page->rightvolume = rightVolume;
        !           868:     
        !           869:     c = (struct IOModeSelectcdb *)(scsiCDB.cdb);
        !           870: 
        !           871:     c->opcode = SOP_MODESELECT;
        !           872:     c->lunbits = 0;
        !           873:     c->reserved1 = 0;
        !           874:     c->reserved2 = 0;
        !           875:     c->paramlen = sizeof(struct audioPage);   
        !           876:     c->ctlbyte = 0;
        !           877:     
        !           878: //    IOLog("%s[IOSCSICDDrive::setVolume\n",getName());
        !           879:     
        !           880:     scsiCDB.cdbLength = 6;
        !           881:     req->setCDB( &scsiCDB );
        !           882:     req->setPointers(cx->senseDataDesc, 255, false, true);    
        !           883: 
        !           884:     cx->memory = IOMemoryDescriptor::withAddress((void *)page,
        !           885:                                                  c->paramlen,
        !           886:                                                  kIODirectionOut);
        !           887:     req->setPointers( cx->memory, c->paramlen, true );
        !           888: 
        !           889:     req->setTimeout( 1000 );
        !           890: 
        !           891:     result = simpleSynchIO(cx);
        !           892: 
        !           893:     deleteTempBuffer((UInt8 *)page,sizeof(struct audioPage));
        !           894:     deleteContext(cx);
        !           895: 
        !           896:     if (result == kIOReturnSuccess) {  /* only remember settings if they worked */
        !           897:         _leftVolume = leftVolume;
        !           898:         _rightVolume = rightVolume;
        !           899:     }
        !           900:     
        !           901:     return(result);
        !           902: }
        !           903: 

unix.superglobalmegacorp.com

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