|
|
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
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.