Annotation of XNU/iokit/Drivers/ata/drvAppleATA/AppleATAPio.cpp, revision 1.1.1.1

1.1       root        1: /*
                      2:  * Copyright (c) 1998-2000 Apple Computer, Inc. All rights reserved.
                      3:  *
                      4:  * @APPLE_LICENSE_HEADER_START@
                      5:  * 
                      6:  * The contents of this file constitute Original Code as defined in and
                      7:  * are subject to the Apple Public Source License Version 1.1 (the
                      8:  * "License").  You may not use this file except in compliance with the
                      9:  * License.  Please obtain a copy of the License at
                     10:  * http://www.apple.com/publicsource and read it before using this file.
                     11:  * 
                     12:  * This Original Code and all software distributed under the License are
                     13:  * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
                     14:  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
                     15:  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
                     16:  * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
                     17:  * License for the specific language governing rights and limitations
                     18:  * under the License.
                     19:  * 
                     20:  * @APPLE_LICENSE_HEADER_END@
                     21:  */
                     22: /*
                     23:  *
                     24:  *    AppleATAPio.cpp
                     25:  *
                     26:  */
                     27: #include "AppleATA.h"
                     28: 
                     29: /*----------------------------------- ATA SetRegs Protocol ------------------------------*/
                     30: 
                     31: /*
                     32:  *
                     33:  *
                     34:  */
                     35: void AppleATA::doProtocolSetRegs( IOATACommand *cmd )
                     36: {    
                     37:     ATATaskfile                taskfile;
                     38:     UInt32             regmask;
                     39:     UInt32             i;
                     40: 
                     41:     cmd->getTaskfile( &taskfile );
                     42: 
                     43:     regmask = taskfile.regmask;
                     44: 
                     45:     if ( regmask & ATARegtoMask(ataRegDriveHead) )
                     46:     {
                     47:         regmask &= ~ATARegtoMask(ataRegDriveHead);
                     48:         if ( selectDrive( taskfile.ataRegs[ataRegDriveHead] ) == false )
                     49:         {
                     50:             completeCmd( cmd, ataReturnErrorBusy );
                     51:             return;
                     52:         }          
                     53:     }
                     54: 
                     55:     for ( i = 0; regmask; i++ )
                     56:     {
                     57:         if ( regmask & 1 )
                     58:         {
                     59:             writeATAReg( i, taskfile.ataRegs[i] );
                     60:         }
                     61:         regmask >>= 1;
                     62:     }
                     63: 
                     64:     IODelay( 100 );
                     65: 
                     66:     completeCmd( cmd, ataReturnNoError );
                     67: }
                     68: 
                     69: /*----------------------------------- ATA PIO Protocol ------------------------------*/
                     70: 
                     71: /*
                     72:  *
                     73:  *
                     74:  */
                     75: void AppleATA::doATAProtocolPio( IOATACommand *cmd )
                     76: {    
                     77:     ATATaskfile                taskfile;
                     78:     UInt32             regmask;
                     79:     UInt32             i;
                     80:     UInt32             status = 0;
                     81: 
                     82:     cmd->getTaskfile( &taskfile );
                     83: 
                     84:     regmask = taskfile.regmask;
                     85: 
                     86:     if ( regmask & ATARegtoMask(ataRegDriveHead) )
                     87:     {
                     88:         regmask &= ~ATARegtoMask(ataRegDriveHead);
                     89:         if ( selectDrive( taskfile.ataRegs[ataRegDriveHead] ) == false )
                     90:         {
                     91:             completeCmd( cmd, ataReturnErrorBusy );
                     92:             return;
                     93:         }          
                     94:     }
                     95: 
                     96:     xferCount = 0;
                     97:     cmd->getPointers( &xferDesc, &xferRemaining, &xferIsWrite );
                     98:     
                     99:     xferInts = ( xferRemaining ) ? xferRemaining / 512 : 1;
                    100:     
                    101:     if ( cmd->getTimeout() != 0 )
                    102:     {
                    103:         xferCmdTimer = cmd->getTimeout() / ATATimerIntervalmS + 1;
                    104:     }
                    105: 
                    106:     for ( i = 0; regmask; i++ )
                    107:     {
                    108:         if ( regmask & 1 )
                    109:         {
                    110:             writeATAReg( i, taskfile.ataRegs[i] );
                    111:         }
                    112:         regmask >>= 1;
                    113:     }
                    114: 
                    115:     if ( xferIsWrite )
                    116:     {
                    117:         do
                    118:         {
                    119:             status = readATAReg( ataRegStatus );
                    120:         }
                    121:         while ( !(status & ataStatusDRQ) );
                    122:      
                    123:         xferInts++;   
                    124:         interruptOccurred();
                    125:     }     
                    126: }
                    127: 
                    128: 
                    129: /*
                    130:  *
                    131:  * 
                    132:  */
                    133: void AppleATA::processATAPioInt()
                    134: {    
                    135:     UInt16             tmpBuffer[256];
                    136:     UInt32             status;
                    137:     UInt32             i;
                    138:     ATAReturnCode      rc = ataReturnNoError;
                    139:     UInt32             reqCount;
                    140: 
                    141:     if ( waitForStatus( 0, ataStatusBSY, ataBusyTimeoutmS ) == false )
                    142:     {
                    143:         completeCmd( xferCmd, ataReturnErrorBusy, xferCount );
                    144:         return;
                    145:     }
                    146: 
                    147:     status = readATAReg( ataRegStatus );
                    148: 
                    149:     if ( status & ataStatusDRQ )
                    150:     {
                    151:         if ( xferIsWrite == true )
                    152:         {
                    153:             xferDesc->readBytes( xferCount, tmpBuffer, 512 );
                    154: 
                    155:             for ( i=0; i < 256; i++ )
                    156:             {
                    157:                 writeATAReg( ataRegData, tmpBuffer[i] );
                    158:             }
                    159:         }
                    160:         else
                    161:         {
                    162:             for ( i=0; i < 256; i++ )
                    163:             {
                    164:                 tmpBuffer[i] = readATAReg( ataRegData );
                    165:             }
                    166:             xferDesc->writeBytes( xferCount, tmpBuffer, 512 );
                    167:         }
                    168: 
                    169:         xferCount     += 512;
                    170:         xferRemaining -= 512;
                    171:     }
                    172: 
                    173:     if ( status & ataStatusERR )
                    174:     {
                    175:         completeCmd( xferCmd, ataReturnErrorStatus, xferCount );
                    176:     }
                    177:     else if ( !--xferInts )
                    178:     {
                    179:         xferCmd->getPointers( 0, &reqCount, 0 );
                    180:         if ( xferCount != reqCount )
                    181:         {
                    182:             rc = ataReturnErrorProtocol;
                    183:         }
                    184: 
                    185:         completeCmd( xferCmd, rc, xferCount );
                    186:     }
                    187: } 
                    188: 
                    189: /*----------------------------------- ATAPI PIO Protocols ------------------------------*/
                    190: 
                    191: /*
                    192:  *
                    193:  *
                    194:  *
                    195:  */
                    196: void AppleATA::doATAPIProtocolPio( IOATACommand *cmd )
                    197: {    
                    198:     ATATaskfile                taskfile;
                    199:     ATAPICmd           atapiCmd;
                    200:     UInt16             *pCDB = NULL;
                    201:     UInt32             regmask;
                    202:     UInt32             status;
                    203:     UInt32             i;
                    204: 
                    205:     xferCount  = 0;
                    206: 
                    207:     cmd->getTaskfile( &taskfile );
                    208:     cmd->getATAPICmd( &atapiCmd );
                    209: 
                    210: 
                    211:     regmask = taskfile.regmask;
                    212: 
                    213:     if ( regmask & ATARegtoMask(ataRegDriveHead) )
                    214:     {
                    215:         regmask &= ~ATARegtoMask(ataRegDriveHead);
                    216:         if ( selectDrive( taskfile.ataRegs[ataRegDriveHead] ) == false )
                    217:         {
                    218:             completeCmd( cmd, ataReturnErrorBusy );
                    219:             return;
                    220:         }          
                    221:     }
                    222: 
                    223:     xferInts = 1;
                    224: 
                    225:     if ( cmd->getTimeout() != 0 )
                    226:     {
                    227:         xferCmdTimer = cmd->getTimeout() / ATATimerIntervalmS + 1;
                    228:     }
                    229: 
                    230:     for ( i = 0; regmask; i++ )
                    231:     {
                    232:         if ( regmask & 1 )
                    233:         {
                    234:             writeATAReg( i, taskfile.ataRegs[i] );
                    235:         }
                    236:         regmask >>= 1;
                    237:     }
                    238: 
                    239:     xferCount = 0;
                    240:     cmd->getPointers( &xferDesc, &xferRemaining, &xferIsWrite );
                    241: 
                    242:     if ( cmd->getDevice()->getATAPIPktInt() == false )
                    243:     {
                    244:         do
                    245:         {
                    246:             status = readATAReg( ataRegStatus );
                    247:         }
                    248:         while ( (status & atapiStatusBSY) || !(status & atapiStatusDRQ) );
                    249:  
                    250:         pCDB = (UInt16 *)atapiCmd.cdb;
                    251:         for ( i = 0; i < atapiCmd.cdbLength >> 1; i++ )
                    252:         {
                    253:             writeATAReg( ataRegData, *pCDB++ );
                    254:         }
                    255:     }
                    256: }
                    257: 
                    258: /*
                    259:  *
                    260:  * 
                    261:  */
                    262: void AppleATA::processATAPIPioInt()
                    263: {
                    264:     ATAReturnCode      rc = ataReturnErrorProtocol;    
                    265:     UInt32             status;
                    266:     UInt32             intReason;
                    267:     UInt32             n;
                    268: 
                    269:     if ( waitForStatus( 0, ataStatusBSY, ataBusyTimeoutmS ) == false )
                    270:     {
                    271:         completeCmd( xferCmd, ataReturnErrorBusy, xferCount );
                    272:         return;
                    273:     }
                    274: 
                    275:     status    = readATAReg( atapiRegStatus );
                    276:     intReason = readATAReg( atapiRegIntReason );
                    277: 
                    278:     if ( !xferInts ) return;
                    279: 
                    280:     if ( status & atapiStatusDRQ )
                    281:     {
                    282:         if ( intReason & atapiIntReasonCD ) 
                    283:         {
                    284:             if ( !(intReason & atapiIntReasonIO) )
                    285:             {
                    286:                 rc = sendATAPIPacket();
                    287:              }
                    288:         }
                    289:         else
                    290:         {
                    291:             n  = readATAReg( atapiRegByteCountLow ) | (readATAReg( atapiRegByteCountHigh ) << 8);
                    292:             n = (n+1) & ~0x01;
                    293: 
                    294:             if ( !(intReason & atapiIntReasonIO) && (xferIsWrite == true) )
                    295:             {
                    296:                 rc = writeATAPIDevice( n );
                    297:             }
                    298:             else if ( (intReason & atapiIntReasonIO) && (xferIsWrite == false) )
                    299:             {
                    300:                 rc = readATAPIDevice( n );
                    301:             }
                    302:         } 
                    303:     }
                    304:     else if ( (intReason & atapiIntReasonCD) && (intReason & atapiIntReasonIO) )    
                    305:     {  
                    306:         xferInts = 0;
                    307:         rc = (status & atapiStatusCHK) ? ataReturnErrorStatus : ataReturnNoError; 
                    308: 
                    309:         if ( rc == ataReturnErrorStatus )
                    310:         { 
                    311:             updateCmdStatus( xferCmd, rc, xferCount );
                    312: 
                    313:             if ( doRequestSense( xferCmd ) == false )
                    314:             {
                    315:                 completeCmd( xferCmd );
                    316:             }        
                    317:         }
                    318:         else
                    319:         {
                    320:             completeCmd( xferCmd, rc, xferCount ); 
                    321:         }  
                    322:     }
                    323: }
                    324: 
                    325: /*
                    326:  *
                    327:  *
                    328:  */
                    329: ATAReturnCode AppleATA::sendATAPIPacket()
                    330: {
                    331:     UInt32             i;
                    332:     ATAPICmd           atapiCmd;
                    333:     UInt16             *pCDB;
                    334: 
                    335:     xferCmd->getATAPICmd( &atapiCmd );
                    336: 
                    337:     pCDB = (UInt16 *)atapiCmd.cdb;
                    338:     for ( i=0; i < atapiCmd.cdbLength >> 1; i++ )
                    339:     {
                    340:         writeATAReg( ataRegData, *pCDB++ );
                    341:     }
                    342:     return ataReturnNoError;
                    343: }    
                    344: 
                    345: 
                    346: /*
                    347:  *
                    348:  *
                    349:  */
                    350: ATAReturnCode AppleATA::readATAPIDevice( UInt32 n )
                    351: {
                    352:     UInt16      tmpBuffer[256];
                    353:     UInt32     i,j,k;
                    354: 
                    355:     while ( n )
                    356:     {
                    357:         j = (n < 512) ? n : 512;
                    358: 
                    359:         j >>= 1;
                    360:         for ( i=0; i < j; i++ )
                    361:         {
                    362:             tmpBuffer[i] = readATAReg( ataRegData );
                    363:         }
                    364:         j <<= 1;
                    365:         n  -= j;
                    366: 
                    367:         k = (j > xferRemaining ) ? xferRemaining : j;
                    368:       
                    369:         xferDesc->writeBytes( xferCount, tmpBuffer, k );
                    370:         
                    371:         xferCount     += k;
                    372:         xferRemaining -= k;
                    373:     }
                    374: 
                    375:     return ataReturnNoError;
                    376: }    
                    377: 
                    378: /*
                    379:  *
                    380:  *
                    381:  */
                    382: ATAReturnCode AppleATA::writeATAPIDevice( UInt32 n )
                    383: {
                    384:     UInt16      tmpBuffer[256];
                    385:     UInt32     i,j,k;
                    386: 
                    387: 
                    388:     while ( n )
                    389:     {
                    390:         j = (n < 512) ? n : 512;
                    391: 
                    392:         k = (j > xferRemaining ) ? xferRemaining : j;
                    393: 
                    394:         xferDesc->readBytes( xferCount, tmpBuffer, k );
                    395: 
                    396:         j >>= 1;
                    397:         for ( i=0; i < j; i++ )
                    398:         {
                    399:             writeATAReg( ataRegData, tmpBuffer[i] );
                    400:         }            
                    401:         j <<= 1;
                    402:         n  -= j;
                    403: 
                    404:         xferCount     += k;
                    405:         xferRemaining -= k;
                    406:     }
                    407: 
                    408:     return ataReturnNoError;
                    409: }               
                    410: 
                    411: 
                    412: /*
                    413:  *
                    414:  *
                    415:  */
                    416: bool AppleATA::selectDrive( UInt32 driveHeadReg )
                    417: {
                    418:     bool               isBusy = true;
                    419:     UInt32             i;
                    420:     UInt32             status;
                    421: 
                    422:     writeATAReg( ataRegDriveHead, driveHeadReg );
                    423: 
                    424:     for ( i=0; i < 10; i++ )
                    425:     {
                    426:         status = readATAReg( ataRegStatus );
                    427:         isBusy = ((status & ataStatusBSY) != 0);
                    428:         if ( isBusy == false )
                    429:         {
                    430:             break;
                    431:         }
                    432:         IODelay( 10 );
                    433:     }
                    434: 
                    435:     return !isBusy;     
                    436: }

unix.superglobalmegacorp.com

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