Annotation of XNU/iokit/IOKit/storage/scsi/IOBasicSCSI.h, revision 1.1.1.1

1.1       root        1: /*
                      2:  * Copyright (c) 1998-2000 Apple Computer, Inc. All rights reserved.
                      3:  *
                      4:  * @APPLE_LICENSE_HEADER_START@
                      5:  * 
                      6:  * The contents of this file constitute Original Code as defined in and
                      7:  * are subject to the Apple Public Source License Version 1.1 (the
                      8:  * "License").  You may not use this file except in compliance with the
                      9:  * License.  Please obtain a copy of the License at
                     10:  * http://www.apple.com/publicsource and read it before using this file.
                     11:  * 
                     12:  * This Original Code and all software distributed under the License are
                     13:  * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
                     14:  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
                     15:  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
                     16:  * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
                     17:  * License for the specific language governing rights and limitations
                     18:  * under the License.
                     19:  * 
                     20:  * @APPLE_LICENSE_HEADER_END@
                     21:  */
                     22: /* =============================================================================
                     23:  * Copyright (c) 1999 Apple Computer, Inc.  All rights reserved. 
                     24:  *
                     25:  * IOBasicSCSI.h
                     26:  *
                     27:  * This class implements generic SCSI functionality.
                     28:  */
                     29: 
                     30: #ifndef        _IOBASICSCSI_H
                     31: #define        _IOBASICSCSI_H
                     32: 
                     33: #include <IOKit/IOTypes.h>
                     34: #include <IOKit/IOService.h>
                     35: #include <IOKit/IOSyncer.h>
                     36: #include <IOKit/scsi/IOSCSIDeviceInterface.h>
                     37: #include <IOKit/storage/IOHDTypes.h>
                     38: 
                     39: const int kMinInqSize          = 5;    /* minimal, supported by all devs */
                     40: const int kReadCapSize         = 8;
                     41: const int kModeSenseSize       = 64;
                     42: const int kMaxInqSize          = 256;
                     43: 
                     44: const int kCheckCondition = 0x02;
                     45: const int kUnitAttention = 0x06;
                     46: 
                     47: /* SCSI operation codes: */
                     48: 
                     49: const UInt8    SOP_TUR         = 0x00;         /* test unit ready */
                     50: const UInt8    SOP_INQUIRY     = 0x12;         /* inquiry */
                     51: const UInt8    SOP_MODESELECT  = 0x15;         /* mode select */
                     52: const UInt8    SOP_MODESENSE   = 0x1a;         /* mode sense */
                     53: const UInt8    SOP_READCAP     = 0x25;         /* read capacity */
                     54: const UInt8    SOP_READ10      = 0x28;         /* read  (10-byte) */
                     55: const UInt8    SOP_WRITE10     = 0x2a;         /* write (10-byte) */
                     56: 
                     57: struct IOTURcdb {
                     58:     UInt8      opcode;
                     59:     UInt8      lunbits;
                     60:     UInt8      reserved1;
                     61:     UInt8      reserved2;
                     62:     UInt8      reserved3;
                     63:     UInt8      ctlbyte;
                     64: };
                     65: 
                     66: struct IORWcdb {                       /* CDB for read and write */
                     67:     UInt8      opcode;                 /* read=0x28, write=0x2a */
                     68:     UInt8      lunbits;                /* lun and control bits */
                     69:     UInt8      lba_3;                  /* logical block address: msb */
                     70:     UInt8      lba_2;
                     71:     UInt8      lba_1;
                     72:     UInt8      lba_0;                  /* logical block address: lsb */
                     73:     UInt8      reserved;
                     74:     UInt8      count_msb;              /* block count: msb */
                     75:     UInt8      count_lsb;              /* block count: lsb */
                     76:     UInt8      ctlbyte;
                     77: };
                     78: 
                     79: struct IOInquirycdb {                  /* inquiry */
                     80:     UInt8      opcode;                 /* 0x12 */
                     81:     UInt8      lunbits;                /* lun and control bits */
                     82:     UInt8      pagecode;               /* page code/op code */
                     83:     UInt8      reserved;
                     84:     UInt8      len;                    /* allocation length */
                     85:     UInt8      ctlbyte;
                     86: };
                     87: 
                     88: struct IOReadCapcdb {
                     89:     UInt8      opcode;
                     90:     UInt8      lunbits;
                     91:     UInt8      lba_3;
                     92:     UInt8      lba_2;
                     93:     UInt8      lba_1;
                     94:     UInt8      lba_0;
                     95:     UInt8      reserved1;
                     96:     UInt8      reserved2;
                     97:     UInt8      reserved3;
                     98:     UInt8      ctlbyte;
                     99: };
                    100: 
                    101: struct IOModeSensecdb {
                    102:     UInt8      opcode;
                    103:     UInt8      lunbits;                /* lun and control bits */
                    104:     UInt8      pagecode;
                    105:     UInt8      reserved;
                    106:     UInt8      len;                    /* allocation length */
                    107:     UInt8      ctlbyte;
                    108: };
                    109: 
                    110: struct IOModeSelectcdb {
                    111:     UInt8      opcode;
                    112:     UInt8      lunbits;
                    113:     UInt8      reserved1;
                    114:     UInt8      reserved2;
                    115:     UInt8      paramlen;
                    116:     UInt8      ctlbyte;
                    117: };
                    118: 
                    119: /*!
                    120:  * @enum stateValues
                    121:  * @discussion
                    122:  * These state values are used to determin the state of an IO operation.
                    123:  * Some are simply for debugging use.
                    124:  * @constant kNone
                    125:  * Nothing happening.
                    126:  * @constant kAsyncReadWrite
                    127:  * Doing an asynchronous IO operation.
                    128:  * @constant kSimpleSynchIO
                    129:  * Doing a simple synchronous IO operation.
                    130:  * @constant kHandlingUnitAttention
                    131:  * Currently handling a Unit-Attention condition.
                    132:  * @constant kDoneHandlingUnitAttention
                    133:  * Done handling Unit Attention; command should be reissued.
                    134:  * @constant kAwaitingPower
                    135:  * Awaiting power.
                    136:  * @constant kMaxValidState
                    137:  * The maximum valid state value.
                    138:  * @constant kMaxStateValue
                    139:  * The maximum state value possible.
                    140:  */
                    141: enum stateValues {
                    142:     kNone                      = 0,
                    143:     kAsyncReadWrite            = 1,
                    144:     kSimpleSynchIO             = 2,
                    145:     kHandlingUnitAttention     = 3,
                    146:     kDoneHandlingUnitAttention         = 4,
                    147:     kAwaitingPower             = 5,
                    148: 
                    149:     kMaxValidState             = kAwaitingPower,
                    150: 
                    151:     kMaxStateValue             = 255
                    152: };
                    153: /*!
                    154:  * @typedef statevalue
                    155:  * @discussion
                    156:  * Shorthand for enum StateValues.
                    157:  */
                    158: typedef enum stateValues stateValue;
                    159: 
                    160: const bool kSync = true;               /* type info for requests awaiting power */
                    161: const bool kAsync = false;
                    162: 
                    163: /*!
                    164:  * @class
                    165:  * IOBasicSCSI : public IOService
                    166:  * @abstract
                    167:  * Basic SCSI support functions.
                    168:  * @discussion
                    169:  * IOBasicSCSI provides a set of basic SCSI functions and support
                    170:  * utilities. It is intended to be the base class for a SCSI Transport
                    171:  * Driver.
                    172:  */
                    173: 
                    174: class IOBasicSCSI : public IOService {
                    175: 
                    176:     OSDeclareAbstractStructors(IOBasicSCSI)
                    177: 
                    178: public:
                    179: 
                    180:     /*!
                    181:      * @struct completion
                    182:      * @field action
                    183:      * The C function called upon completion of the operation.
                    184:      * @field target
                    185:      * The C++ class pointer, passed to tha action function.
                    186:      * @field param
                    187:      * A value passed to the action function. This value is not touched.
                    188:      */
                    189:     /*!
                    190:      * @struct context
                    191:      * @discussion
                    192:      * The context structure contains all persistent information needed for a
                    193:      * synchronous or asynchronous IO operation.
                    194:      * @field completion
                    195:      * The completion information for an asynchronous read or write operation.
                    196:      * @field state
                    197:      * The current state of the operation.
                    198:      * @field step
                    199:      * The current step value, if we are handling a Unit Attention.
                    200:      * @field originalContext
                    201:      * A pointer to the context for the command that caused the Unit Attention
                    202:      * condition.
                    203:      * @field scsireq
                    204:      * A pointer to the IOSCSIRequest object.
                    205:      * @field memory
                    206:      * The data buffer for the operation. A pointer to an IOMemoryDescriptor.
                    207:      * @field scsiresult
                    208:      * A pointer to the IOSCSIResult object.
                    209:      * @field desiredPower
                    210:      * The desired power level for the operation to execute.
                    211:      * @field isSync
                    212:      * True if synchronous; False if asynchronous.
                    213:      * @field next
                    214:      * A pointer to a context structure, used as a queue forward-link.
                    215:      * @field sync
                    216:      * A syncer used to block a thread awaiting a power level, or for completion
                    217:      * of a synchronous operation.
                    218:      */
                    219:     struct context {
                    220: 
                    221:         /* Completion information for our client, used only for async operations.
                    222:          * Typically this information will only be used by subclasses.
                    223:          */
                    224: 
                    225:         struct {
                    226:             gdCompletionFunction       action;         /* function to call */
                    227:             IOService          *target;        /* client object ("this") */
                    228:             void                       *param;         /* client's parameter */
                    229:         } completion;
                    230: 
                    231:         /* Parameters used during an IO retry: */
                    232: 
                    233:         stateValue                     state;                  /* what state we're in */
                    234:         UInt32                 step;
                    235:         struct context         *originalIOContext;     /* original SCSI IO if doing a retry */
                    236: 
                    237:         IOMemoryDescriptor             *memory;
                    238: 
                    239:         UInt32                 desiredPower;           /* desired power level state */
                    240:         bool                   isSync;                 /* true if sync, false if async */
                    241:         struct context         *next;                  /* for queue of requests pending power */
                    242:         /* Parameters to hand off to the SCSI provider: */
                    243:     
                    244:         IOSCSICommand          *scsireq;
                    245:         SCSISenseData          *senseData;  
                    246:         IOMemoryDescriptor             *senseDataDesc;  
                    247: 
                    248:         IOSyncer               *sync;          /* to wait for completion */
                    249:     };
                    250: 
                    251:     /* Overrides from IOService: */
                    252: 
                    253:     virtual void       free(void);
                    254: 
                    255:     virtual bool       init(OSDictionary * properties);
                    256: 
                    257:     /*!
                    258:      * @function probe
                    259:      * @abstract
                    260:      * Determine if device matches expected type.
                    261:      * @discussion
                    262:      * This method is responsible for matching the device type. It calls
                    263:      * doInquiry to issue a SCSI Inquiry command to the device, then calls
                    264:      * deviceTypeMatches to ensure that the device type matches the expected
                    265:      * type. If the device type matches, then the Vendor, Product, and
                    266:      * Revision strings are copied from the inquiry data, and "this" is
                    267:      * returned. If the device type does not match, NULL is returned.
                    268:      * 
                    269:      * The default implementation ignores the score parameter, though that
                    270:      * parameter is passed to the superclass probe method.
                    271:      */
                    272:     virtual IOService * probe(IOService * provider,SInt32 * score);
                    273:     
                    274:     /* --- end of IOService overrides --- */
                    275: 
                    276:     /*!
                    277:      * @function deviceTypeMatches
                    278:      * @abstract
                    279:      * Determine if device type matches expected type.
                    280:      * @discussion
                    281:      * This method must be implemented by a device-specific subclass.
                    282:      * @param inqBuf
                    283:      * A pointer to the SCSI inquiry data for the device.
                    284:      * @param inqLen
                    285:      * The size of the data in the inquiry buffer.
                    286:      * @result
                    287:      * True indicates a match; False indicates a failure.
                    288:      */
                    289:     virtual bool       deviceTypeMatches(UInt8 inqBuf[],UInt32 inqLen)                 = 0;
                    290: 
                    291:     /*!
                    292:      * @function executeCdb
                    293:      * Issue the client's cdb as a pass-through.
                    294:      * @discussion This method is provided to allow developers to issue arbitrary commands
                    295:      * to the device (via the Transport Driver). Expected uses might include vendor-specific
                    296:      * commands to support device-based password-protection, or for other vendor features.
                    297:      * 
                    298:      * This method may not be supported by all Transport Drivers. For example, ATA devices
                    299:      * do not have a CDB concept; those Transport Drivers will return kIOReturnUnsupported.
                    300:      * @param params
                    301:      * See IOHDTypes.h for the layout of this data structure.
                    302:      */
                    303:     virtual IOReturn   executeCdb(struct cdbParams *params);
                    304: 
                    305:     /*!
                    306:      * @function getAdditionalDeviceInfoString
                    307:      * @abstract
                    308:      * Return additional informational string for the device.
                    309:      * @result
                    310:      * A pointer to a static character string. The default implementation
                    311:      * returns "[SCSI]" .
                    312:      */
                    313:     virtual char *     getAdditionalDeviceInfoString(void);
                    314: 
                    315:     /*!
                    316:      * @function getVendorString
                    317:      * @abstract
                    318:      * Return Vendor Name string
                    319:      * @result
                    320:      * A pointer to a static character string, copied from the inquiry data.
                    321:      */
                    322:     virtual char *     getVendorString(void);
                    323: 
                    324:     /*!
                    325:      * @function getProductString
                    326:      * @abstract
                    327:      * Return Product Name string for the device.
                    328:      * @result
                    329:     A pointer to a static character string, copied from the inquiry data.
                    330:      */
                    331:     virtual char *     getProductString(void);
                    332: 
                    333:     /*!
                    334:      * @function getRevisionString
                    335:      * @abstract
                    336:      * Return Product Revision string for the device.
                    337:      * @result
                    338:      * A pointer to a static character string, copied from the inquiry data.
                    339:      */
                    340:     virtual char *     getRevisionString(void);
                    341: 
                    342:     /*!
                    343:      * @function reportBlockSize
                    344:      * @abstract
                    345:      * Report the block size for the device, in bytes.
                    346:      * @discussion
                    347:      * This method returns the block size for the media. The default
                    348:      * implementation obtains the block size from the SCSI Read Capacity
                    349:      * command. Since the result of the Read Capacity is used by this
                    350:      * method and reportMaxValidBlock, this method either returns a cached
                    351:      * value or calls doReadCapacity to issue the command and cache both
                    352:      * values.
                    353:      * @param blockSize
                    354:      * Pointer to returned block size value.
                    355:      */
                    356:     virtual IOReturn   reportBlockSize(UInt64 *blockSize);
                    357:     
                    358:     /*!
                    359:      * @function reportEjectability
                    360:      * @abstract
                    361:      * Report if the media is ejectable under software control.
                    362:      * @discussion
                    363:      * This method reports whether the media is ejectable under software
                    364:      * control. The default implementation always reports that removable
                    365:      * media is ejectable.
                    366:      * 
                    367:      * This method should only be called if the media is known to be removable.
                    368:      * @param isEjectable
                    369:      * Pointer to returned result. True indicates the media is ejectable, False indicates
                    370:      * the media cannot be ejected under software control.
                    371:      */
                    372:     virtual IOReturn   reportEjectability(bool *isEjectable);
                    373:     
                    374:     /*!
                    375:      * @function reportLockability
                    376:      * @abstract
                    377:      * Report if the media is lockable under software control.
                    378:      * @discussion
                    379:      * This method reports whether the media can be locked under software
                    380:      * control, to prevent the user from removing the media manually, e.g.
                    381:      * by pressing a button on the drive. This method is only called by
                    382:      * the generic driver when the media is known to be removable. The
                    383:      * default implementation always returns true.
                    384:      *  
                    385:      * This method should only be called if the media is known to be removable.
                    386:      * @param isLockable
                    387:      * Pointer to returned result. True indicates the media can be locked in place; False
                    388:      * indicates the media cannot be locked by software.
                    389:      */
                    390:     virtual IOReturn   reportLockability(bool *isLockable);
                    391:     
                    392:     /*!
                    393:      * @function reportMaxReadTransfer
                    394:      * @abstract
                    395:      * Report the maximum allowed byte transfer for read operations.
                    396:      * @discussion
                    397:      * Some devices impose a maximum data transfer size. Because this limit
                    398:      * may be determined by the size of a block-count field in a command, the limit may
                    399:      * depend on the block size of the transfer.
                    400:      * The default implementation reports blocksize * 65536, which is the maximum
                    401:      * number of bytes that can be transferred
                    402:      * in a SCSI command with a standard 16-bit block count field.
                    403:      * @param blockSize
                    404:      * The block size desired for the transfer.
                    405:      * @param max
                    406:      * Pointer to returned result.
                    407:      */
                    408:     virtual IOReturn   reportMaxReadTransfer (UInt64 blocksize,UInt64 *max);
                    409: 
                    410:     /*!
                    411:      * @function reportMaxValidBlock
                    412:      * @abstract
                    413:      * Report the highest valid block for the device.
                    414:      * @discussion
                    415:      * This method reports the maximum allowable block number. The default
                    416:      * implementation obtains the block number from the SCSI Read Capacity
                    417:      * command. Since the result of the Read Capacity is used by this
                    418:      * method and reportBlockSize, this method either returns a cached
                    419:      * value or calls doReadCapacity to issue the command and cache both
                    420:      * values.
                    421:      * @param maxBlock
                    422:      * Pointer to returned result
                    423:      */
                    424:     virtual IOReturn   reportMaxValidBlock(UInt64 *maxBlock);
                    425: 
                    426:     /*!
                    427:      * @function reportMaxWriteTransfer
                    428:      * @abstract
                    429:      * Report the maximum allowed byte transfer for write operations.
                    430:      * @discussion
                    431:      * Some devices impose a maximum data transfer size. Because this limit
                    432:      * may be determined by the size of a block-count field in a command, the limit may
                    433:      * depend on the block size of the transfer.
                    434:      * The default implementation reports blocksize * 65536, which is the maximum
                    435:      * number of bytes that can be transferred
                    436:      * in a SCSI command with a standard 16-bit block count field.
                    437:      * @param blockSize
                    438:      * The block size desired for the transfer.
                    439:      * @param max
                    440:      * Pointer to returned result.
                    441:      */
                    442:     virtual IOReturn   reportMaxWriteTransfer(UInt64 blocksize,UInt64 *max);
                    443:     
                    444:     /*!
                    445:      * @function reportPollRequirements
                    446:      * @abstract
                    447:      * Report if it's necessary to poll for media insertion, and if polling is expensive.
                    448:      * @discussion
                    449:      * This method reports whether the device must be polled to detect media
                    450:      * insertion, and whether a poll is expensive to perform.
                    451:      * 
                    452:      * The term "expensive" typically implies a device that must be spun-up to detect media,
                    453:      * as on a PC floppy. Most devices can detect media inexpensively.
                    454:      * 
                    455:      * The default implementation of this method always reports an
                    456:      * inexpensive poll (pollIsExpensive = false), and that all removable
                    457:      * media must be polled.
                    458:      * @param pollRequired
                    459:      * Pointer to returned result. True indicates that polling is required; False indicates
                    460:      * that polling is not required to detect media.
                    461:      * @param pollIsExpensive
                    462:      * Pointer to returned result. True indicates that the polling operation is expensive;
                    463:      * False indicates that the polling operation is cheap.
                    464:      */
                    465:     virtual IOReturn   reportPollRequirements(bool *pollRequired,bool *pollIsExpensive);
                    466:     
                    467:     /*!
                    468:      * @function reportRemovability
                    469:      * @abstract
                    470:      * Report whether the media is removable or not.
                    471:      * @discussion
                    472:      * This method reports whether the media is removable, but it does not
                    473:      * provide detailed information regarding software eject or lock/unlock capability.
                    474:      * 
                    475:      * The default implementation of this method examines the cached
                    476:      * Inquiry data to determine if media is removable.  If the RMB bit
                    477:      * (0x80 of Inquiry data byte 1) is set, the media is removable. If
                    478:      * there is no Inquiry data, the media is reported to be nonremovable.
                    479:      * 
                    480:      * This method also sets the instance variable _removable.
                    481:      * @param isRemovable
                    482:      * Pointer to returned result. True indicates that the media is removable; False
                    483:      * indicates the media is not removable.
                    484:      */
                    485:     virtual IOReturn   reportRemovability(bool *isRemovable);
                    486: 
                    487:     /*!
                    488:      * @function reportWriteProtection
                    489:      * @abstract
                    490:      * Report whether the media is write-protected or not.
                    491:      * @discussion
                    492:      * The default implementation of this method issues a SCSI Mode Sense
                    493:      * command to test the WP bit( 0x80 of byte 2 of the Mode Sense Header
                    494:      * data). A request is made for Mode Sense Page 1, though any  valid
                    495:      * page will return a header. If the bit is set, the media is considered
                    496:      * write-protected.
                    497:      * @param isWriteProtected
                    498:      * Pointer to returned result. True indicates that the media is write-protected (it
                    499:      * cannot be written); False indicates that the media is not write-protected (it
                    500:      * is permissible to write).
                    501:      */
                    502:     virtual IOReturn   reportWriteProtection(bool *isWriteProtected);
                    503: 
                    504: protected:
                    505: 
                    506:     /*!
                    507:      * @function createReadCdb
                    508:      * @abstract
                    509:      * Create a SCSI CDB for a read operation.
                    510:      * @discussion
                    511:      * Override this to control the cdb created for a read operation.
                    512:      * The default implementation creates a 10-byte read command with
                    513:      * disconnect allowed, 8-byte autosense, and a 2-second timeout.
                    514:      * @param cdb
                    515:      * A pointer to the CDB bytes.
                    516:      * @param cdbLength
                    517:      * The length of the CDB in bytes.
                    518:      * @param block
                    519:      * The device block to be read.
                    520:      * @param nblks
                    521:      *  The number of blocks to be transferred.
                    522:      * @param maxAutoSenseLength
                    523:      * The maximum size of the autosense data, in bytes. A value of zero
                    524:      * will disable autosense.
                    525:      * @param timeoutSeconds
                    526:      * The command timeout in seconds.
                    527:      * @result
                    528:      * The IOSCSICommandOptions returned will be used to issue the command.
                    529:      */
                    530:     virtual UInt32     createReadCdb(
                    531:                             UInt8 *cdb,                        /* in  */
                    532:                             UInt32 *cdbLength,         /* out */
                    533:                             UInt32 block,              /* in  */
                    534:                             UInt32 nblks,              /* in  */
                    535:                             UInt32 *maxAutoSenseLength,        /* out */
                    536:                             UInt32 *timeoutSeconds);   /* out */
                    537: 
                    538:     /*!
                    539:      * @function createWriteCdb
                    540:      * @abstract
                    541:      * Create a SCSI CDB for a write operation.
                    542:      * @discussion
                    543:      * Override this to control the cdb created for a write operation.
                    544:      * The default implementation creates a 10-byte write command with
                    545:      * disconnect allowed, 8-byte autosense, and a 2-second timeout.
                    546:      * @param cdb
                    547:      * A pointer to the CDB bytes.
                    548:      * @param cdbLength
                    549:      * The length of the CDB in bytes.
                    550:      * @param block
                    551:      * The device block to be written.
                    552:      * @param nblks
                    553:      * The number of blocks to be transferred.
                    554:      * @param maxAutoSenseLength
                    555:      * The maximum size of the autosense data, in bytes. A value of zero
                    556:      * will disable autosense.
                    557:      * @param timeoutSeconds
                    558:      * The command timeout in seconds.
                    559:      * @result
                    560:      * The IOSCSICommandOptions returned will be used to issue the command.
                    561:      */
                    562:     virtual UInt32     createWriteCdb(
                    563:                             UInt8 *cdb,                        /* in  */
                    564:                             UInt32 *cdbLength,         /* out */
                    565:                             UInt32 block,              /* in  */
                    566:                             UInt32 nblks,              /* in  */
                    567:                             UInt32 *maxAutoSenseLength,        /* out */
                    568:                             UInt32 *timeoutSeconds);   /* out */
                    569: 
                    570: 
                    571:     /*!
                    572:      * @function doInquiry
                    573:      * @abstract
                    574:      * Obtain SCSI Inquiry data from the device.
                    575:      * @discussion
                    576:      * This method issues a SCSI Inquiry command to the device, to obtain
                    577:      * the result in the supplied buffer. The method first issues an
                    578:      * inquiry with a 5-byte length, to obtain the full length of the
                    579:      * devices inquiry data. The second Inquiry command is issued to get
                    580:      * the full inquiry data (limited to maxLen, of course).
                    581:      * @param inqBuf
                    582:      * A pointer to the buffer.
                    583:      * @param maxLen
                    584:      * The maximum number of bytes the buffer can contain.
                    585:      * @param actualLen
                    586:      * A pointer to the returned byte count actually transferred.
                    587:      */
                    588:     virtual IOReturn   doInquiry(UInt8 *inqBuf,UInt32 maxLen,UInt32 *actualLen);
                    589: 
                    590:     /*!
                    591:      * @function handleUnitAttention
                    592:      * @abstract
                    593:      * @discussion
                    594:      * Override this to perform any special processing required when
                    595:      * a Unit-Attention condition is detected. The cx->step value starts at 1 and
                    596:      * is incremented as each subsequent command is executed. HandleUnitAttention
                    597:      * is then called again duirng the command completion, until cx->state is
                    598:      * changed to kDoneHandlingUnitAttention. This repeated calling behavior allows
                    599:      * handleUnitAttention to issue several commands to the device to recover from
                    600:      * the Unit-Attention condition. Note that since handleUnitAttention is called
                    601:      * on the SCSI completion thread, it must not issue blocking operations, but
                    602:      * should instead call simpleAsyncIO.
                    603:      * 
                    604:      * The default implementation merely sets the state to
                    605:      * kDoneHandlingUnitAttention, to allow the original command to be
                    606:      * reissued.
                    607:      * @param cx
                    608:      * Pointer to context for the current command.
                    609:      */
                    610:     virtual void       handleUnitAttention(struct context *cx);
                    611: 
                    612:     /* Internally used methods. */
                    613: 
                    614:     /*
                    615:      * @group
                    616:      * Internally Used Methods
                    617:      * @discussion
                    618:      * These methods are used internally, and will not generally be modified.
                    619:      */
                    620: 
                    621:     /*!
                    622:      * @function allocateContext
                    623:      * @abstract
                    624:      * Allocate a context structure for use with the current IO operation.
                    625:      */
                    626:     virtual struct context * allocateContext(void);
                    627: 
                    628:     /*!
                    629:      * @function allocateInquiryBuffer
                    630:      * @abstract
                    631:      * Allocate an inquiry buffer.
                    632:      * @param buf
                    633:      * A pointer for the returned buffer pointer.
                    634:      * @param size
                    635:      * The requested size of the buffer, in bytes.
                    636:      */
                    637:     virtual IOReturn   allocateInquiryBuffer(UInt8 **buf,UInt32 size);
                    638: 
                    639:     /*!
                    640:      * @function allocateTempBuffer
                    641:      * @abstract
                    642:      * Allocate a buffer for temporary use.
                    643:      * @param buf
                    644:      * A pointer for the returned buffer pointer.
                    645:      * @param size
                    646:      * The requested size of the buffer, in bytes.
                    647:      */
                    648:     virtual IOReturn   allocateTempBuffer(UInt8 **buf,UInt32 size);
                    649: 
                    650:     /*!
                    651:      * @function allocateReadCapacityBuffer
                    652:      * @abstract
                    653:      * Allocate a buffer for Read-Capacity data.
                    654:      * @param buf
                    655:      * A pointer for the returned buffer pointer.
                    656:      * @param size
                    657:      * The requested size of the buffer, in bytes.
                    658:      */
                    659:     virtual IOReturn   allocateReadCapacityBuffer(UInt8 **buf,UInt8 size);
                    660: 
                    661:     /*!
                    662:      * @function deleteContext
                    663:      * @abstract
                    664:      * Delete a context structure.
                    665:      * @discussion
                    666:      * This method also issues a "release" for the IO buffer and/or lock, if any.
                    667:      * @param cx
                    668:      * A pointer to the context structure to be deleted.
                    669:      */
                    670:     virtual void       deleteContext(struct context *cx);
                    671: 
                    672:     /*!
                    673:      * @function deleteInquiryBuffer
                    674:      * @abstract
                    675:      * Delete an inquiry data buffer.
                    676:      * @param buf
                    677:      * A pointer to the buffer.
                    678:      * @param size
                    679:      * The requested size of the buffer, in bytes.
                    680:      */
                    681:     virtual void       deleteInquiryBuffer(UInt8 *buf,UInt32 size);
                    682: 
                    683:     /*!
                    684:      * @function deleteTempBuffer
                    685:      * @abstract
                    686:      * Delete a temporary data buffer.
                    687:      * @param buf
                    688:      * A pointer to the buffer.
                    689:      * @param len
                    690:      * The requested size of the buffer, in bytes.
                    691:      */
                    692:     virtual void       deleteTempBuffer(UInt8 *buf,UInt32 len);
                    693: 
                    694:     /*!
                    695:      * @function deleteReadCapacityBuffer
                    696:      * @abstract
                    697:      * Delete a Read-Capacity data buffer.
                    698:      * @param buf
                    699:      * A pointer to the buffer.
                    700:      * @param len
                    701:      * The requested size of the buffer, in bytes.
                    702:      */
                    703:     virtual void       deleteReadCapacityBuffer(UInt8 *buf,UInt32 len);
                    704: 
                    705:     /*!
                    706:      * @function doReadCapacity
                    707:      * @abstract
                    708:      * @discussion
                    709:      * The default implementation of this method issues a standard SCSI
                    710:      * Read Capacity command. The block size and maximum valid block are
                    711:      * extracted from the returned data in an endian-neutral way.
                    712:      * @param blockSize
                    713:      * A pointer to the returned block size value.
                    714:      * @param maxBlock
                    715:      * A pointer to the returned maximum block number.
                    716:      */
                    717:     virtual IOReturn   doReadCapacity(UInt64 *blockSize,UInt64 *maxBlock);
                    718: 
                    719:     /*!
                    720:      * @function getBlockSize
                    721:      * @abstract
                    722:      * Return the device block size.
                    723:      * @discussion
                    724:      * This method obtains the block size from the Read-Capacity data. If RC data is
                    725:      * not yet cached, a call is made to doReadCapacity to obtain the data.
                    726:      */
                    727:     virtual UInt64     getBlockSize(void);
                    728: 
                    729: 
                    730:     /*!
                    731:      * @function dequeueCommands
                    732:      * @abstract
                    733:      * Dequeue commands previously enqueued awaiting the proper device power level.
                    734:      * @discussion
                    735:      * This method is called when a command is queued (from queueCommand), when a call
                    736:      * completes (from RWCompletion), and when the device power level changes. All commands
                    737:      * for which the device power level is proper are immediately dequeued.
                    738:      * 
                    739:      * Queued synchronous commands are simply "awakened" by unlocking a lock. The originating
                    740:      * thread then continues and issues the command. Asynchronous commands are immediately
                    741:      * dispatched via a call to standardAsyncReadWriteExecute.
                    742:      */
                    743:     virtual void       dequeueCommands(void);
                    744: 
                    745:     /*!
                    746:      * @function queueCommand
                    747:      * @abstract
                    748:      * Queue commands awaiting the proper device power level.
                    749:      * @discussion
                    750:      * This method is called prior to issuing any IO command, so that each command can
                    751:      * be enqueued awaiting its desired device power level. After queuing the command, a
                    752:      * call is made to dequeueCommands to attempt to dequeue any available command that can
                    753:      * be executed (including the one just queued). Putting commands into the queue ensures
                    754:      * that the proper sequence is maintained.
                    755:      * @param cx
                    756:      * The context for the command being queued.
                    757:      * @param isSync
                    758:      * True if the command is synchronous; False if the command is asynchronous.
                    759:      * @param desiredPower
                    760:      * The device power level needed before the command can execute.
                    761:      */
                    762:     virtual void       queueCommand(struct context *cx,bool isSync,UInt32 desiredPower);
                    763: 
                    764:     /*!
                    765:      * @function RWCompletion
                    766:      * @abstract
                    767:      * Asynchronous read/write completion routine.
                    768:      * @discussion
                    769:      * A subclass must implement the read-write completion, called upon completion
                    770:      * of an IO started by doAsyncReadWrite.
                    771:      * @param cx
                    772:      * A pointer to the context structure for the completing command.
                    773:      */
                    774:     virtual void       RWCompletion(struct context *cx)                                = 0;
                    775: 
                    776:     /*!
                    777:      * @function simpleSynchIO
                    778:      * @abstract
                    779:      * Issue a simple synchronous SCSI command.
                    780:      * @discussion
                    781:      * This method issues a single SCSI command and waits for the command
                    782:      * to complete. The SCSI command must already be set up in the context
                    783:      * structure.
                    784:      * @param cx
                    785:      * A pointer to the context structure for the command.
                    786:      */
                    787:     virtual IOReturn   simpleSynchIO(struct context *cx);
                    788: 
                    789:     /*!
                    790:      * @function standardAsyncReadWrite
                    791:      * @abstract
                    792:      * Start an asynchronous read or write operation.
                    793:      * @discussion
                    794:      * This method starts an asynchronous read or write operation. No
                    795:      * incoming parameters are validated. The default implementation
                    796:      * calls createReadCdb or createWriteCdb,
                    797:      * then issues a SCSI command to IOSCSIDevice. If the command is
                    798:      * accepted, then the completion will be called at some future time.
                    799:      * @result
                    800:      * The only possible returns from this method are:
                    801:      * 
                    802:      * kIOReturnSuccess, meaning that the IO was accepted by the transport
                    803:      * drivers provider (e.g.  IOSCSIDevice), and that the completion
                    804:      * function will be called when the IO completes, i.e.  target->action(param).
                    805:      *  
                    806:      * kIOReturnNoMemory, meaning that memory allocation failed.
                    807:      * 
                    808:      * Other kIOReturn codes from the provider which occurred
                    809:      * because the IO was not accepted in that provider's queue. This
                    810:      * might indicate a full queue or bad parameter.
                    811:      * @param buffer
                    812:      * An IOMemoryDescriptor describing the data-transfer buffer. The data direction
                    813:      * is contained in the IOMemoryDescriptor. Responsiblity for releasing the descriptor
                    814:      * rests with the caller.
                    815:      * @param block
                    816:      * The starting block number of the data transfer.
                    817:      * @param nblks
                    818:      * The integral number of blocks to be transferred.
                    819:      * @param action
                    820:      * The C function called upon completion of the data transfer.
                    821:      * @param target
                    822:      * The C++ class "this" pointer, passed as an argument to "action."
                    823:      * @param param
                    824:      * This value is passed as an argument to "action." It is not validated or modified.
                    825:      */
                    826:     virtual IOReturn   standardAsyncReadWrite(IOMemoryDescriptor *buffer,
                    827:                                             UInt32 block,UInt32 nblks,
                    828:                                             gdCompletionFunction action,
                    829:                                             IOService *target,void *param);
                    830: 
                    831:     /*!
                    832:      * @function standardAsyncReadWriteExecute
                    833:      * @abstract
                    834:      * Issue an asynchronous read/write operation after dequeuing.
                    835:      * @param cx
                    836:      * A pointer to the context structure for the command.
                    837:      */
                    838:     virtual IOReturn   standardAsyncReadWriteExecute(struct context *cx);
                    839: 
                    840:     /*!
                    841:      * @function standardSyncReadWrite
                    842:      * Perform a synchronous read or write operation.
                    843:      * @param buffer
                    844:      * An IOMemoryDescriptor describing the data-transfer buffer. The data direction
                    845:      * is contained in the IOMemoryDescriptor. Responsiblity for releasing the descriptor
                    846:      * rests with the caller.
                    847:      * @param block
                    848:      * The starting block number of the data transfer.
                    849:      * @param nblks
                    850:      * The integral number of blocks to be transferred.
                    851:      */
                    852:     virtual IOReturn   standardSyncReadWrite(IOMemoryDescriptor *buffer,UInt32 block,UInt32 nblks);
                    853: 
                    854:     /*!
                    855:      * @function stringFromState
                    856:      * @abstract
                    857:      * Return a string description of a state value.
                    858:      * @discussion
                    859:      * Used for debugging.
                    860:      * @param state
                    861:      * The state to be converted to a string description.
                    862:      */
                    863:     virtual char *     stringFromState(stateValue state);
                    864: 
                    865: public:
                    866: 
                    867:     /*!
                    868:      * @function genericCompletion
                    869:      * @abstract
                    870:      * Generic IO completion function.
                    871:      * @discussion
                    872:      * This method handles completion of a SCSI command. It implements a
                    873:      * simple state machine to handle a Unit Attention condition on a
                    874:      * command.
                    875:      * 
                    876:      * This method must be public so we can reach it from
                    877:      * the C-language callback "glue" routine. It should not be called
                    878:      * from outside this class.
                    879:      *
                    880:      * 
                    881:      *
                    882:      * If a Unit Attention condition occurs, we set the state to
                    883:      * kHandlingUnitAttention and call handleUnitAttention to do whatever
                    884:      * is necessary to clear the condition. Eventually, handleUnitAttention
                    885:      * resets the state to kDoneHandlingUnitAttention, which will allow
                    886:      * the state machine to reissue the original command.
                    887:      * 
                    888:      * If we are already processing a Unit Attention, then genericCompletion
                    889:      * increments a step counter and calls handleUnitAttention.  The step
                    890:      * counter allows handleUnitAttention to issue multiple SCSI commands
                    891:      * to clear the condition. The handleUnitAttention method is called
                    892:      * repeatedly, until the state is set to kDoneHandlingUnitAttention.
                    893:      * 
                    894:      * If this operation is a normal asynchronous read or write (usually
                    895:      * started by standardAsyncReadWrite, though this is not required),
                    896:      * then a call is made to RWCompletion, followed by deletion of the
                    897:      * context structure for the command. RWCompletion is  implemented by
                    898:      * the subclass of IOBasicSCSI, for example in IOSCSIHDDrive.
                    899:      * @param cx
                    900:      * A pointer to the context structure for the command.
                    901:      */
                    902:     virtual void       genericCompletion(struct context *cx);
                    903: 
                    904:     /*
                    905:      * @endgroup
                    906:      */
                    907: 
                    908: protected:
                    909: 
                    910:     /*
                    911:      * @group
                    912:      * Power Management Methods
                    913:      * @discussion
                    914:      * A subclass must implement these to report the power level required to do various commands.
                    915:      */
                    916: 
                    917:     /*!
                    918:      * @function getExecuteCDBPowerState
                    919:      * @abstract
                    920:      * Return the required device power level to execute a client CDB.
                    921:      */
                    922:     virtual UInt32     getExecuteCDBPowerState(void)                                   = 0;
                    923: 
                    924:     /*!
                    925:      * @function getInquiryPowerState
                    926:      * @abstract
                    927:      * Return the required device power level to issue an Inquiry command.
                    928:      */
                    929:     virtual UInt32     getInquiryPowerState(void)                                      = 0;
                    930: 
                    931:     /*!
                    932:      * @function getReadCapacityPowerState
                    933:      * @abstract
                    934:      * Return the required device power level to issue a Read Capacity command.
                    935:      */
                    936:     virtual UInt32     getReadCapacityPowerState(void)                                 = 0;
                    937: 
                    938:     /*!
                    939:      * @function getReadWritePowerState
                    940:      * @abstract
                    941:      * Return the required device power level to issue a data read or write.
                    942:      */
                    943:     virtual UInt32     getReadWritePowerState(void)                                    = 0;
                    944: 
                    945:     /*!
                    946:      * @function getReportWriteProtectionPowerState
                    947:      * @abstract
                    948:      * Return the required device power level to determine media write protection.
                    949:      */
                    950:     virtual UInt32     getReportWriteProtectionPowerState(void)                        = 0;
                    951: 
                    952:     /*!
                    953:      * @function powerTickle
                    954:      * @abstract
                    955:      * Check for the device power state currently being in the desired state.
                    956:      * @discussion
                    957:      * A subclass must implement powerTickle, which is called when we desire power to
                    958:      * execute a command. PowerTickle may handle generic or a subclass-expanded set of
                    959:      * power states. The implementation will usually relay the call to the Power Management
                    960:      * subsystem function activityTickle. For a device without power management capability,
                    961:      * the implementation should always return True.
                    962:      * @param desiredState
                    963:      * The desired device power level.
                    964:      * @result
                    965:      * True if power is in the desired state (or better); False if the caller must wait
                    966:      * until power is available.
                    967:      */
                    968:     virtual bool       powerTickle(UInt32 desiredState)                                = 0;
                    969: 
                    970:     /*
                    971:      * @endgroup
                    972:      */
                    973:     
                    974:     /*!
                    975:      * @var _provider
                    976:      * A pointer to our provider.
                    977:      */
                    978:     IOSCSIDevice *     _provider;
                    979: 
                    980:     /* Device information : */
                    981:     
                    982:     /*!
                    983:      * @var _inqBuf
                    984:      * A pointer to the allocate Inquiry Data buffer.
                    985:      */
                    986:     UInt8 *            _inqBuf;                /* the Inquiry data buffer */
                    987: 
                    988:     /*!
                    989:      * @var _inqBufSize
                    990:      * The size of the inquiry data buffer, in bytes.
                    991:      */
                    992:     UInt32             _inqBufSize;            /* size of the buffer */
                    993: 
                    994:     /*!
                    995:      * @var _inqLen
                    996:      * The number of valid bytes of inquiry data.
                    997:      */
                    998:     UInt32             _inqLen;                /* valid bytes in buffer */
                    999:     
                   1000:     /*!
                   1001:      * @var _vendor
                   1002:      * The Vendor Name string from the inquiry data, null-terminated.
                   1003:      */
                   1004:     char               _vendor[9];             /* info from Inquiry data */
                   1005: 
                   1006:     /*!
                   1007:      * @var _product
                   1008:      * The Product Name string from the inquiry data, null-terminated.
                   1009:      */
                   1010:     char               _product[17];
                   1011: 
                   1012:     /*!
                   1013:      * @var _rev
                   1014:      * The Product Revision string from the inquiry data, null-terminated.
                   1015:      */
                   1016:     char               _rev[5];
                   1017: 
                   1018:     /* Since we get both of these items from the same command, we
                   1019:      * just cache both values if we get either call, so we only
                   1020:      * have to issue the command once.
                   1021:      */
                   1022: 
                   1023:     /*!
                   1024:      * @var _readCapDone
                   1025:      * True if we have issued a Read-Capacity command to obtain the
                   1026:      * values for _maxBlock and _blockSize.
                   1027:      */
                   1028:     bool               _readCapDone;
                   1029: 
                   1030:     /*!
                   1031:      * @var _removable
                   1032:      * True if the media is removable; False if the media is fixed.
                   1033:      */
                   1034:     bool               _removable;
                   1035: 
                   1036:     /*!
                   1037:      * @var _maxBlock
                   1038:      * The highest valid block on the media, relative to zero.
                   1039:      */
                   1040:     UInt64             _maxBlock;
                   1041: 
                   1042:     /*!
                   1043:      * @var _blockSize
                   1044:      * The block size of the media in bytes.
                   1045:      */
                   1046:     UInt64             _blockSize;
                   1047: 
                   1048:     /* The queue of pending requests awaiting power: */
                   1049: 
                   1050:     /*!
                   1051:      * @struct queue
                   1052:      * @discussion
                   1053:      * A data structure for a queue.
                   1054:      * @field head
                   1055:      * A pointer to the head item.
                   1056:      * @field tail
                   1057:      * A pointer to the tail item.
                   1058:      * @field lock
                   1059:      * A lock used to protect the queue during changes.
                   1060:      */
                   1061:     /*!
                   1062:      * @var _powerQueue
                   1063:      * A queue structure containing operations queued awaiting power level.
                   1064:      */
                   1065:     struct queue {
                   1066:         struct context * head;
                   1067:         struct context * tail;
                   1068:         IOLock *        lock;
                   1069:     }                  _powerQueue;
                   1070:     
                   1071: };
                   1072: #endif

unix.superglobalmegacorp.com

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