Annotation of XNU/iokit/Families/IOATAPIHDDrive/IOATAPIHDCommand.cpp, revision 1.1

1.1     ! root        1: /*
        !             2:  * Copyright (c) 1998-2000 Apple Computer, Inc. All rights reserved.
        !             3:  *
        !             4:  * @APPLE_LICENSE_HEADER_START@
        !             5:  * 
        !             6:  * The contents of this file constitute Original Code as defined in and
        !             7:  * are subject to the Apple Public Source License Version 1.1 (the
        !             8:  * "License").  You may not use this file except in compliance with the
        !             9:  * License.  Please obtain a copy of the License at
        !            10:  * http://www.apple.com/publicsource and read it before using this file.
        !            11:  * 
        !            12:  * This Original Code and all software distributed under the License are
        !            13:  * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
        !            14:  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
        !            15:  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
        !            16:  * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
        !            17:  * License for the specific language governing rights and limitations
        !            18:  * under the License.
        !            19:  * 
        !            20:  * @APPLE_LICENSE_HEADER_END@
        !            21:  */
        !            22: /*
        !            23:  * Copyright (c) 1999 Apple Computer, Inc.  All rights reserved. 
        !            24:  *
        !            25:  * IOATAPIHDCommand.cpp - Performs ATAPI command processing.
        !            26:  *
        !            27:  * HISTORY
        !            28:  * Sep 2, 1999 jliu - Ported from AppleATAPIDrive.
        !            29:  */
        !            30: 
        !            31: #include <IOKit/assert.h>
        !            32: #include <IOKit/storage/ata/IOATAPIHDDrive.h>
        !            33: 
        !            34: #define        super IOATAHDDrive
        !            35: 
        !            36: // Enable this define to generate debugging messages.
        !            37: // #define DEBUG_LOG 1
        !            38: 
        !            39: // --------------------------------------------------------------------------
        !            40: // Returns the Command protocol to use (e.g. ataProtocolPIO, ataProtocolDMA).
        !            41: 
        !            42: void
        !            43: IOATAPIHDDrive::selectCommandProtocol(bool useDMA)
        !            44: {
        !            45:        super::selectCommandProtocol(useDMA);
        !            46: 
        !            47:        if (useDMA)
        !            48:                _atapiProtocol = atapiProtocolDMA;
        !            49:        else
        !            50:                _atapiProtocol = atapiProtocolPIO;
        !            51: }
        !            52: 
        !            53: // --------------------------------------------------------------------------
        !            54: // Setup a ATATaskFile for an ATAPI packet command from the parameters given.
        !            55: 
        !            56: void
        !            57: IOATAPIHDDrive::setupPacketTaskFile(ATATaskfile * taskfile,
        !            58:                                     ATAProtocol   protocol,
        !            59:                                     UInt16        byteCount)
        !            60: {
        !            61:        taskfile->protocol = protocol;
        !            62: 
        !            63:        taskfile->regmask  = ATARegtoMask(atapiRegDeviceSelect) 
        !            64:                        | ATARegtoMask(atapiRegCommand)
        !            65:                        | ATARegtoMask(atapiRegByteCountLow)
        !            66:                        | ATARegtoMask(atapiRegByteCountHigh)
        !            67:                        | ATARegtoMask(atapiRegFeatures);
        !            68:                                        
        !            69:        taskfile->resultmask = ATARegtoMask(atapiRegError);
        !            70: 
        !            71:        taskfile->ataRegs[atapiRegDeviceSelect]  = ataModeLBA | (_unit << 4);
        !            72:        taskfile->ataRegs[atapiRegCommand]       = atapiCommandPacket;
        !            73:     taskfile->ataRegs[atapiRegByteCountLow]  = byteCount & 0xff;
        !            74:     taskfile->ataRegs[atapiRegByteCountHigh] = (byteCount >> 8) & 0xff;
        !            75:        taskfile->ataRegs[atapiRegFeatures]      = (protocol == atapiProtocolPIO) ?
        !            76:                                                0 : kIOATAPIFeaturesDMA;
        !            77: }
        !            78: 
        !            79: // --------------------------------------------------------------------------
        !            80: // Create a generic ATAPI command object.
        !            81: 
        !            82: IOATACommand *
        !            83: IOATAPIHDDrive::atapiCommand(ATAPICmd *           packetCommand,
        !            84:                              IOMemoryDescriptor * transferBuffer = 0,
        !            85:                              IOMemoryDescriptor * senseData = 0)
        !            86: {
        !            87:        ATATaskfile taskfile;
        !            88:        bool        isWrite;
        !            89:        UInt32      transferLength;
        !            90: 
        !            91:        IOATACommand * cmd = allocateCommand();
        !            92:        if (!cmd) return 0;             // error, command allocation failed.
        !            93:        
        !            94:        // Create ATA packet command.
        !            95:        //
        !            96:        setupPacketTaskFile(&taskfile, _atapiProtocol, kIOATAPIMaxTransfer);
        !            97: 
        !            98:        // Get a pointer to the client data buffer, and record parameters
        !            99:        // which shall be later used by the completion routine.
        !           100:        //
        !           101:        IOATAClientData * clientData = ATA_CLIENT_DATA(cmd);
        !           102:        assert(clientData);
        !           103: 
        !           104:        clientData->buffer  = transferBuffer;
        !           105: 
        !           106:        cmd->setTaskfile(&taskfile);
        !           107:        cmd->setATAPICmd(packetCommand, senseData,
        !           108:                      senseData ? senseData->getLength() : 0);
        !           109: 
        !           110:        if (transferBuffer) {
        !           111:                isWrite = (transferBuffer->getDirection() == kIODirectionOut);
        !           112:                transferLength = transferBuffer->getLength();
        !           113:        }
        !           114:        else {
        !           115:                isWrite = false;
        !           116:                transferLength = 0;
        !           117:        }
        !           118:        cmd->setPointers(transferBuffer, transferLength, isWrite);
        !           119: 
        !           120:        return cmd;
        !           121: }
        !           122: 
        !           123: // --------------------------------------------------------------------------
        !           124: // Allocates and return an IOATACommand to perform a read/write operation.
        !           125: 
        !           126: IOATACommand *
        !           127: IOATAPIHDDrive::atapiCommandReadWrite(IOMemoryDescriptor * buffer,
        !           128:                                       UInt32               block,
        !           129:                                       UInt32               nblks)
        !           130: {
        !           131:     ATAPICmd   atapiCmd;
        !           132: 
        !           133:        assert(buffer);
        !           134: 
        !           135: #ifdef DEBUG_LOG
        !           136:        IOLog("%s: atapiCommandReadWrite %08x (%d) %s %d %d\n",
        !           137:                getName(),
        !           138:                buffer,
        !           139:                buffer->getLength(),
        !           140:                (buffer->getDirection() == kIODirectionOut) ? "WR" :
        !           141:                "RD",
        !           142:                block,
        !           143:                nblks);
        !           144: #endif
        !           145: 
        !           146:        // Create the ATAPI packet (bytes 1, 10, 11 are reserved).
        !           147:        //
        !           148:     bzero(&atapiCmd, sizeof(atapiCmd));
        !           149: 
        !           150:     atapiCmd.cdbLength = 12;
        !           151:     atapiCmd.cdb[0]    = (buffer->getDirection() == kIODirectionOut) ? 
        !           152:                           kIOATAPICommandWrite : kIOATAPICommandRead;
        !           153:     atapiCmd.cdb[2]    = (block >> 24) & 0xff;
        !           154:        atapiCmd.cdb[3]    = (block >> 16) & 0xff;
        !           155:        atapiCmd.cdb[4]    = (block >>  8) & 0xff;
        !           156:        atapiCmd.cdb[5]    = (block & 0xff);
        !           157:     atapiCmd.cdb[6]    = (nblks >> 24) & 0xff;
        !           158:        atapiCmd.cdb[7]    = (nblks >> 16) & 0xff;
        !           159:        atapiCmd.cdb[8]    = (nblks >>  8) & 0xff;
        !           160:        atapiCmd.cdb[9]    = (nblks & 0xff);
        !           161: 
        !           162:        return atapiCommand(&atapiCmd, buffer);
        !           163: }
        !           164: 
        !           165: // --------------------------------------------------------------------------
        !           166: // ATAPI Start/Stop Unit command (1B).
        !           167: 
        !           168: IOATACommand *
        !           169: IOATAPIHDDrive::atapiCommandStartStopUnit(IOMemoryDescriptor * senseData,
        !           170:                                           bool                 doStart,
        !           171:                                           bool                 doLoadEject,
        !           172:                                           bool                 immediate)
        !           173: {
        !           174:     ATAPICmd   atapiCmd;
        !           175: 
        !           176: #ifdef DEBUG_LOG
        !           177:        IOLog("%s: atapiCommandStartStopUnit: %s\n", getName(),
        !           178:                doStart ? "start" : "stop");
        !           179: #endif
        !           180: 
        !           181:        // Create the ATAPI packet.
        !           182:        //
        !           183:     bzero(&atapiCmd, sizeof(atapiCmd));
        !           184: 
        !           185:     atapiCmd.cdbLength = 12;
        !           186:     atapiCmd.cdb[0]    = kIOATAPICommandStartStopUnit;
        !           187:        atapiCmd.cdb[1]    = immediate ?    0x01 : 0x00;
        !           188:        atapiCmd.cdb[4]    = (doStart     ? 0x01 : 0) |
        !           189:                          (doLoadEject ? 0x02 : 0);
        !           190: 
        !           191:        return atapiCommand(&atapiCmd, 0, senseData);
        !           192: }
        !           193: 
        !           194: // --------------------------------------------------------------------------
        !           195: // ATAPI Prevent/Allow medium removal command (1E).
        !           196: 
        !           197: IOATACommand *
        !           198: IOATAPIHDDrive::atapiCommandPreventAllowRemoval(bool doLock)
        !           199: {
        !           200:     ATAPICmd   atapiCmd;
        !           201: 
        !           202:        // Create the ATAPI packet.
        !           203:        //
        !           204:     bzero(&atapiCmd, sizeof(atapiCmd));
        !           205: 
        !           206:     atapiCmd.cdbLength = 12;
        !           207:     atapiCmd.cdb[0]    = kIOATAPICommandPreventAllow;
        !           208:        atapiCmd.cdb[4]    = doLock ? 0x01 : 0;
        !           209: 
        !           210:        return atapiCommand(&atapiCmd);
        !           211: }
        !           212: 
        !           213: // --------------------------------------------------------------------------
        !           214: // ATAPI Test Unit Ready command (00).
        !           215: 
        !           216: IOATACommand *
        !           217: IOATAPIHDDrive::atapiCommandTestUnitReady(IOMemoryDescriptor * senseData)
        !           218: {
        !           219:     ATAPICmd   atapiCmd;
        !           220: 
        !           221: #ifdef DEBUG_LOG
        !           222:        IOLog("%s: atapiCommandTestUnitReady\n", getName());
        !           223: #endif
        !           224: 
        !           225:        // Create the ATAPI packet.
        !           226:        //
        !           227:     bzero(&atapiCmd, sizeof(atapiCmd));
        !           228: 
        !           229:     atapiCmd.cdbLength = 12;
        !           230:     atapiCmd.cdb[0]    = kIOATAPICommandTestUnitReady;
        !           231: 
        !           232:        return atapiCommand(&atapiCmd, 0, senseData);
        !           233: }
        !           234: 
        !           235: // --------------------------------------------------------------------------
        !           236: // ATAPI Read TOC command (43).
        !           237: 
        !           238: IOATACommand *
        !           239: IOATAPIHDDrive::atapiCommandReadTOC(IOMemoryDescriptor * buffer,
        !           240:                                     tocFormat            format,
        !           241:                                     UInt8                startTrackSession)
        !           242: {
        !           243:     ATAPICmd   atapiCmd;
        !           244: 
        !           245:        assert(buffer);
        !           246: 
        !           247:        // Create the ATAPI packet.
        !           248:        //
        !           249:     bzero(&atapiCmd, sizeof(atapiCmd));
        !           250: 
        !           251:     atapiCmd.cdbLength = 12;
        !           252:     atapiCmd.cdb[0]    = kIOATAPICommandReadTOC;
        !           253:        atapiCmd.cdb[1]    = (format == ktocSCSI2MSF) ? 0x02 : 0x00;
        !           254:        atapiCmd.cdb[6]    = startTrackSession;
        !           255:        atapiCmd.cdb[7]    = (buffer->getLength() >> 8) & 0xff;
        !           256:        atapiCmd.cdb[8]    =  buffer->getLength() & 0xff;
        !           257:        
        !           258:        switch (format) {
        !           259:                case ktocSCSI2MSF:
        !           260:                case ktocSCSI2LBA:
        !           261:                        atapiCmd.cdb[9] = 0x00;
        !           262:                        break;
        !           263:                
        !           264:                case ktocSessionInfo:
        !           265:                        atapiCmd.cdb[9] = 0x40;
        !           266:                        break;
        !           267:                
        !           268:                case ktocQLeadin:
        !           269:                        atapiCmd.cdb[9] = 0x80;
        !           270:                        break;
        !           271:        }
        !           272: 
        !           273:        return atapiCommand(&atapiCmd, buffer);
        !           274: }
        !           275: 
        !           276: IOATACommand *
        !           277: IOATAPIHDDrive::atapiCommandPlayAudioMSF(UInt32 starting_msf,
        !           278:                                       UInt32 ending_msf)
        !           279: {
        !           280:     ATAPICmd   atapiCmd;
        !           281: 
        !           282:     // IOLog("IOATAPIHDDrive::atapiCommandPlayAudioMSF %x %x\n",starting_msf,ending_msf);
        !           283: 
        !           284:     bzero(&atapiCmd, sizeof(atapiCmd));
        !           285:     atapiCmd.cdbLength = 12;
        !           286: 
        !           287:     atapiCmd.cdb[0]    = kIOATAPICommandPlayAudioMSF;
        !           288: 
        !           289:     // starting MSF address
        !           290:     atapiCmd.cdb[3]    = (starting_msf >> 16) & 0xff;
        !           291:     atapiCmd.cdb[4]    = (starting_msf >>  8) & 0xff;
        !           292:     atapiCmd.cdb[5]    = (starting_msf & 0xff);
        !           293: 
        !           294:     // ending MSF address
        !           295:     atapiCmd.cdb[6]    = (ending_msf >> 16) & 0xff;
        !           296:     atapiCmd.cdb[7]    = (ending_msf >>  8) & 0xff;
        !           297:     atapiCmd.cdb[8]    = (ending_msf & 0xff);
        !           298: 
        !           299:     return atapiCommand(&atapiCmd);
        !           300: }
        !           301: 
        !           302: IOATACommand *
        !           303: IOATAPIHDDrive::atapiCommandPlayAudio(UInt32 starting_lba,
        !           304:                                          UInt32 length_lba)
        !           305: {
        !           306:     ATAPICmd   atapiCmd;
        !           307: 
        !           308:     // IOLog("IOATAPIHDDrive::atapiCommandPlayAudio\n");
        !           309: 
        !           310:     bzero(&atapiCmd, sizeof(atapiCmd));
        !           311:     atapiCmd.cdbLength = 12;
        !           312: 
        !           313:     atapiCmd.cdb[0]    = kIOATAPICommandPlayAudio;
        !           314: 
        !           315:     // starting LBA address
        !           316:     atapiCmd.cdb[2]    = (starting_lba >> 24) & 0xff;
        !           317:     atapiCmd.cdb[3]    = (starting_lba >> 16) & 0xff;
        !           318:     atapiCmd.cdb[4]    = (starting_lba >>  8) & 0xff;
        !           319:     atapiCmd.cdb[5]    = (starting_lba & 0xff);
        !           320: 
        !           321:     // length in blocks
        !           322:     atapiCmd.cdb[7]    = (length_lba >>  8) & 0xff;
        !           323:     atapiCmd.cdb[8]    = (length_lba & 0xff);
        !           324: 
        !           325:     return atapiCommand(&atapiCmd);
        !           326: }
        !           327: 
        !           328: IOATACommand *
        !           329: IOATAPIHDDrive::atapiCommandPauseResume(bool resume)
        !           330: {
        !           331:     ATAPICmd   atapiCmd;
        !           332: 
        !           333:     // IOLog("IOATAPIHDDrive::atapiCommandPauseResume\n");
        !           334: 
        !           335:     bzero(&atapiCmd, sizeof(atapiCmd));
        !           336:     atapiCmd.cdbLength = 12;
        !           337: 
        !           338:     atapiCmd.cdb[0]    = kIOATAPICommandPauseResume;
        !           339: 
        !           340:     // set resume bit
        !           341:     if (resume) atapiCmd.cdb[8]    = 0x01;
        !           342: 
        !           343:     return atapiCommand(&atapiCmd);
        !           344: }
        !           345: 
        !           346: IOATACommand *
        !           347: IOATAPIHDDrive::atapiCommandModeSense(IOMemoryDescriptor * buffer,
        !           348:                                       UInt8 pageCode)
        !           349: {
        !           350:     ATAPICmd atapiCmd;
        !           351: 
        !           352:     assert(buffer);
        !           353: 
        !           354:     bzero(&atapiCmd, sizeof(atapiCmd));
        !           355: 
        !           356:     atapiCmd.cdbLength = 12;
        !           357:     atapiCmd.cdb[0]    = kIOATAPICommandModeSense;
        !           358:     atapiCmd.cdb[2]    = pageCode;
        !           359:     atapiCmd.cdb[7]    = (buffer->getLength() >> 8) & 0xff;
        !           360:     atapiCmd.cdb[8]    =  buffer->getLength() & 0xff;
        !           361: 
        !           362:     return atapiCommand(&atapiCmd, buffer);
        !           363: }
        !           364: 
        !           365: IOATACommand *
        !           366: IOATAPIHDDrive::atapiCommandModeSelect(IOMemoryDescriptor * buffer,
        !           367:                                       UInt8 pageCode)
        !           368: {
        !           369:     ATAPICmd atapiCmd;
        !           370: 
        !           371:     assert(buffer);
        !           372: 
        !           373:     bzero(&atapiCmd, sizeof(atapiCmd));
        !           374: 
        !           375:     atapiCmd.cdbLength = 12;
        !           376:     atapiCmd.cdb[0]    = kIOATAPICommandModeSelect;
        !           377:     atapiCmd.cdb[1]    = 0x10;
        !           378:     atapiCmd.cdb[2]    = pageCode;
        !           379:     atapiCmd.cdb[7]    = (buffer->getLength() >> 8) & 0xff;
        !           380:     atapiCmd.cdb[8]    =  buffer->getLength() & 0xff;
        !           381: 
        !           382:     return atapiCommand(&atapiCmd, buffer);
        !           383: }
        !           384: 
        !           385: IOATACommand *
        !           386: IOATAPIHDDrive::atapiCommandReadSubChannel(IOMemoryDescriptor * buffer,
        !           387:                                       UInt8 dataFormat,
        !           388:                                       UInt8 trackNumber,
        !           389:                                       bool subQ)
        !           390: {
        !           391:     ATAPICmd atapiCmd;
        !           392: 
        !           393:     assert(buffer);
        !           394: 
        !           395:     bzero(&atapiCmd, sizeof(atapiCmd));
        !           396: 
        !           397:     atapiCmd.cdbLength = 12;
        !           398:     atapiCmd.cdb[0]    = kIOATAPICommandReadSubChannel;
        !           399:     atapiCmd.cdb[1]    = 0x02;
        !           400:     if (subQ) atapiCmd.cdb[2]    = 0x40;
        !           401:     atapiCmd.cdb[3]    = dataFormat;
        !           402:     atapiCmd.cdb[6]    = trackNumber;
        !           403:     atapiCmd.cdb[7]    = (buffer->getLength() >> 8) & 0xff;
        !           404:     atapiCmd.cdb[8]    =  buffer->getLength() & 0xff;
        !           405: 
        !           406:     return atapiCommand(&atapiCmd, buffer);
        !           407: }
        !           408: 
        !           409: IOATACommand *
        !           410: IOATAPIHDDrive::atapiCommandReadHeader(IOMemoryDescriptor * buffer,
        !           411:                                       UInt32 address)
        !           412: {
        !           413:     ATAPICmd atapiCmd;
        !           414: 
        !           415:     assert(buffer);
        !           416: 
        !           417:     bzero(&atapiCmd, sizeof(atapiCmd));
        !           418: 
        !           419:     atapiCmd.cdbLength = 12;
        !           420:     atapiCmd.cdb[0]    = kIOATAPICommandReadHeader;
        !           421:     atapiCmd.cdb[1]    = 0x02;  // MSF
        !           422: 
        !           423:     // starting LBA address
        !           424:     atapiCmd.cdb[2]    = (address >> 24) & 0xff;
        !           425:     atapiCmd.cdb[3]    = (address >> 16) & 0xff;
        !           426:     atapiCmd.cdb[4]    = (address >>  8) & 0xff;
        !           427:     atapiCmd.cdb[5]    = (address & 0xff);
        !           428: 
        !           429:     atapiCmd.cdb[7]    = (buffer->getLength() >> 8) & 0xff;
        !           430:     atapiCmd.cdb[8]    =  buffer->getLength() & 0xff;
        !           431: 
        !           432:     return atapiCommand(&atapiCmd, buffer);
        !           433: }
        !           434: 
        !           435: IOATACommand *
        !           436: IOATAPIHDDrive::atapiCommandReadCD(IOMemoryDescriptor * buffer,
        !           437:                   UInt32 address,
        !           438:                   UInt32 length,
        !           439:                   UInt8 sector,
        !           440:                   UInt8 header,
        !           441:                   UInt8 error,
        !           442:                   UInt8  data)
        !           443: {
        !           444: 
        !           445:     ATAPICmd atapiCmd;
        !           446: 
        !           447:     assert(buffer);
        !           448: 
        !           449:     bzero(&atapiCmd, sizeof(atapiCmd));
        !           450: 
        !           451:     atapiCmd.cdbLength = 12;
        !           452:     atapiCmd.cdb[0]    = kIOATAPICommandReadCD;
        !           453: 
        !           454:     // expected sector type
        !           455:     atapiCmd.cdb[1]    = (sector << 2) & 0xff;
        !           456: 
        !           457:     // starting LBA address
        !           458:     atapiCmd.cdb[2]    = (address >> 24) & 0xff;
        !           459:     atapiCmd.cdb[3]    = (address >> 16) & 0xff;
        !           460:     atapiCmd.cdb[4]    = (address >>  8) & 0xff;
        !           461:     atapiCmd.cdb[5]    = (address & 0xff);
        !           462: 
        !           463:     // transfer length
        !           464:     atapiCmd.cdb[6]    = (buffer->getLength() >> 16) & 0xff;
        !           465:     atapiCmd.cdb[7]    = (buffer->getLength() >>  8) & 0xff;
        !           466:     atapiCmd.cdb[8]    =  buffer->getLength() & 0xff;
        !           467: 
        !           468:     // flag bits
        !           469:     atapiCmd.cdb[9]    = ((header << 5) | (error << 1)) & 0xff;
        !           470: 
        !           471:     // sub-channel data selection
        !           472:     atapiCmd.cdb[10]    = (data) & 0xff;
        !           473: 
        !           474:     return atapiCommand(&atapiCmd, buffer);
        !           475: }

unix.superglobalmegacorp.com

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