]> git.saurik.com Git - apple/xnu.git/blob - iokit/IOKit/storage/scsi/IOBasicSCSI.h
xnu-124.13.tar.gz
[apple/xnu.git] / iokit / IOKit / storage / scsi / IOBasicSCSI.h
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/IOStorage.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 kHandlingRecoveryAfterBusReset = 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 const UInt32 kMaxRetries = 3;
164
165 /*!
166 * @class
167 * IOBasicSCSI : public IOService
168 * @abstract
169 * Basic SCSI support functions.
170 * @discussion
171 * IOBasicSCSI provides a set of basic SCSI functions and support
172 * utilities. It is intended to be the base class for a SCSI Transport
173 * Driver.
174 */
175
176 class IOBasicSCSI : public IOService {
177
178 OSDeclareAbstractStructors(IOBasicSCSI)
179
180 public:
181
182 /*!
183 * @struct completion
184 * @field action
185 * The C function called upon completion of the operation.
186 * @field target
187 * The C++ class pointer, passed to tha action function.
188 * @field param
189 * A value passed to the action function. This value is not touched.
190 */
191 /*!
192 * @struct context
193 * @discussion
194 * The context structure contains all persistent information needed for a
195 * synchronous or asynchronous IO operation.
196 * @field completion
197 * The completion information for an asynchronous read or write operation.
198 * @field state
199 * The current state of the operation.
200 * @field step
201 * The current step value, if we are handling a Unit Attention.
202 * @field originalContext
203 * A pointer to the context for the command that caused the Unit Attention
204 * condition.
205 * @field scsireq
206 * A pointer to the IOSCSIRequest object.
207 * @field memory
208 * The data buffer for the operation. A pointer to an IOMemoryDescriptor.
209 * @field scsiresult
210 * A pointer to the IOSCSIResult object.
211 * @field desiredPower
212 * The desired power level for the operation to execute.
213 * @field isSync
214 * True if synchronous; False if asynchronous.
215 * @field next
216 * A pointer to a context structure, used as a queue forward-link.
217 * @field sync
218 * A syncer used to block a thread awaiting a power level, or for completion
219 * of a synchronous operation.
220 */
221 struct context {
222
223 /* Completion information for our client, used only for async operations.
224 * Typically this information will only be used by subclasses.
225 */
226 IOStorageCompletion completion; /* function to call */
227
228 /* Parameters used during an IO retry: */
229
230 stateValue state; /* what state we're in */
231 UInt32 step;
232 struct context *originalIOContext; /* original SCSI IO if doing a retry */
233 bool retryInProgress;
234 UInt32 retryCount;
235
236 IOMemoryDescriptor *memory;
237
238 UInt32 desiredPower; /* desired power level state */
239 bool isSync; /* true if sync, false if async */
240 struct context *next; /* for queue of requests pending power */
241 /* Parameters to hand off to the SCSI provider: */
242
243 IOSCSICommand *scsireq;
244 SCSISenseData *senseData;
245 IOMemoryDescriptor *senseDataDesc;
246
247 IOSyncer *sync; /* to wait for completion */
248 };
249
250 /* Overrides from IOService: */
251
252 virtual void free(void);
253
254 virtual bool init(OSDictionary * properties);
255
256 /*!
257 * @function message
258 * @discussion
259 * This override allows us to receive notification of Bus Reset events from
260 * the SCSI Device.
261 */
262 virtual IOReturn message(UInt32 type,IOService * provider,void * argument);
263
264 /*!
265 * @function probe
266 * @abstract
267 * Determine if device matches expected type.
268 * @discussion
269 * This method is responsible for matching the device type. It calls
270 * doInquiry to issue a SCSI Inquiry command to the device, then calls
271 * deviceTypeMatches to ensure that the device type matches the expected
272 * type. (The Vendor, Product, and Revision strings are unconditionally
273 * copied from the inquiry data). If deviceTypeMatches returns true, "this" is
274 * returned. If the device type does not match, NULL is returned.
275 *
276 * The default implementation passes the score parameter to deviceTypeMatches
277 * so that method may alter the match score.
278 */
279 virtual IOService * probe(IOService * provider,SInt32 * score);
280
281 virtual bool start(IOService *provider);
282
283 /* --- end of IOService overrides --- */
284
285 /*!
286 * @function deviceTypeMatches
287 * @abstract
288 * Determine if device type matches expected type.
289 * @discussion
290 * This method must be implemented by a device-specific subclass.
291 * @param inqBuf
292 * A pointer to the SCSI inquiry data for the device.
293 * @param inqLen
294 * The size of the data in the inquiry buffer.
295 * @param score
296 * A pointer to the match score, which will be returned by probe.
297 * @result
298 * True indicates a match; False indicates a failure.
299 */
300 virtual bool deviceTypeMatches(UInt8 inqBuf[],UInt32 inqLen,SInt32 *score) = 0;
301
302 /*!
303 * @function getAdditionalDeviceInfoString
304 * @abstract
305 * Return additional informational string for the device.
306 * @result
307 * A pointer to a static character string. The default implementation
308 * returns "[SCSI]" .
309 */
310 virtual char * getAdditionalDeviceInfoString(void);
311
312 /*!
313 * @function getVendorString
314 * @abstract
315 * Return Vendor Name string
316 * @result
317 * A pointer to a static character string, copied from the inquiry data.
318 */
319 virtual char * getVendorString(void);
320
321 /*!
322 * @function getProductString
323 * @abstract
324 * Return Product Name string for the device.
325 * @result
326 A pointer to a static character string, copied from the inquiry data.
327 */
328 virtual char * getProductString(void);
329
330 /*!
331 * @function getRevisionString
332 * @abstract
333 * Return Product Revision string for the device.
334 * @result
335 * A pointer to a static character string, copied from the inquiry data.
336 */
337 virtual char * getRevisionString(void);
338
339 /*!
340 * @function reportBlockSize
341 * @abstract
342 * Report the block size for the device, in bytes.
343 * @discussion
344 * This method returns the block size for the media. The default
345 * implementation obtains the block size from the SCSI Read Capacity
346 * command. Since the result of the Read Capacity is used by this
347 * method and reportMaxValidBlock, this method either returns a cached
348 * value or calls doReadCapacity to issue the command and cache both
349 * values.
350 * @param blockSize
351 * Pointer to returned block size value.
352 */
353 virtual IOReturn reportBlockSize(UInt64 *blockSize);
354
355 /*!
356 * @function reportEjectability
357 * @abstract
358 * Report if the media is ejectable under software control.
359 * @discussion
360 * This method reports whether the media is ejectable under software
361 * control. The default implementation always reports that removable
362 * media is ejectable.
363 *
364 * This method should only be called if the media is known to be removable.
365 * @param isEjectable
366 * Pointer to returned result. True indicates the media is ejectable, False indicates
367 * the media cannot be ejected under software control.
368 */
369 virtual IOReturn reportEjectability(bool *isEjectable);
370
371 /*!
372 * @function reportLockability
373 * @abstract
374 * Report if the media is lockable under software control.
375 * @discussion
376 * This method reports whether the media can be locked under software
377 * control, to prevent the user from removing the media manually, e.g.
378 * by pressing a button on the drive. This method is only called by
379 * the generic driver when the media is known to be removable. The
380 * default implementation always returns true.
381 *
382 * This method should only be called if the media is known to be removable.
383 * @param isLockable
384 * Pointer to returned result. True indicates the media can be locked in place; False
385 * indicates the media cannot be locked by software.
386 */
387 virtual IOReturn reportLockability(bool *isLockable);
388
389 /*!
390 * @function reportMaxReadTransfer
391 * @abstract
392 * Report the maximum allowed byte transfer for read operations.
393 * @discussion
394 * Some devices impose a maximum data transfer size. Because this limit
395 * may be determined by the size of a block-count field in a command, the limit may
396 * depend on the block size of the transfer.
397 * The default implementation reports blocksize * 65536, which is the maximum
398 * number of bytes that can be transferred
399 * in a SCSI command with a standard 16-bit block count field.
400 * @param blockSize
401 * The block size desired for the transfer.
402 * @param max
403 * Pointer to returned result.
404 */
405 virtual IOReturn reportMaxReadTransfer (UInt64 blocksize,UInt64 *max);
406
407 /*!
408 * @function reportMaxValidBlock
409 * @abstract
410 * Report the highest valid block for the device.
411 * @discussion
412 * This method reports the maximum allowable block number. The default
413 * implementation obtains the block number from the SCSI Read Capacity
414 * command. Since the result of the Read Capacity is used by this
415 * method and reportBlockSize, this method either returns a cached
416 * value or calls doReadCapacity to issue the command and cache both
417 * values.
418 * @param maxBlock
419 * Pointer to returned result
420 */
421 virtual IOReturn reportMaxValidBlock(UInt64 *maxBlock);
422
423 /*!
424 * @function reportMaxWriteTransfer
425 * @abstract
426 * Report the maximum allowed byte transfer for write operations.
427 * @discussion
428 * Some devices impose a maximum data transfer size. Because this limit
429 * may be determined by the size of a block-count field in a command, the limit may
430 * depend on the block size of the transfer.
431 * The default implementation reports blocksize * 65536, which is the maximum
432 * number of bytes that can be transferred
433 * in a SCSI command with a standard 16-bit block count field.
434 * @param blockSize
435 * The block size desired for the transfer.
436 * @param max
437 * Pointer to returned result.
438 */
439 virtual IOReturn reportMaxWriteTransfer(UInt64 blocksize,UInt64 *max);
440
441 /*!
442 * @function reportPollRequirements
443 * @abstract
444 * Report if it's necessary to poll for media insertion, and if polling is expensive.
445 * @discussion
446 * This method reports whether the device must be polled to detect media
447 * insertion, and whether a poll is expensive to perform.
448 *
449 * The term "expensive" typically implies a device that must be spun-up to detect media,
450 * as on a PC floppy. Most devices can detect media inexpensively.
451 *
452 * The default implementation of this method always reports an
453 * inexpensive poll (pollIsExpensive = false), and that all removable
454 * media must be polled.
455 * @param pollRequired
456 * Pointer to returned result. True indicates that polling is required; False indicates
457 * that polling is not required to detect media.
458 * @param pollIsExpensive
459 * Pointer to returned result. True indicates that the polling operation is expensive;
460 * False indicates that the polling operation is cheap.
461 */
462 virtual IOReturn reportPollRequirements(bool *pollRequired,bool *pollIsExpensive);
463
464 /*!
465 * @function reportRemovability
466 * @abstract
467 * Report whether the media is removable or not.
468 * @discussion
469 * This method reports whether the media is removable, but it does not
470 * provide detailed information regarding software eject or lock/unlock capability.
471 *
472 * The default implementation of this method examines the cached
473 * Inquiry data to determine if media is removable. If the RMB bit
474 * (0x80 of Inquiry data byte 1) is set, the media is removable. If
475 * there is no Inquiry data, the media is reported to be nonremovable.
476 *
477 * This method also sets the instance variable _removable.
478 * @param isRemovable
479 * Pointer to returned result. True indicates that the media is removable; False
480 * indicates the media is not removable.
481 */
482 virtual IOReturn reportRemovability(bool *isRemovable);
483
484 /*!
485 * @function reportWriteProtection
486 * @abstract
487 * Report whether the media is write-protected or not.
488 * @discussion
489 * The default implementation of this method issues a SCSI Mode Sense
490 * command to test the WP bit( 0x80 of byte 2 of the Mode Sense Header
491 * data). A request is made for Mode Sense Page 1, though any valid
492 * page will return a header. If the bit is set, the media is considered
493 * write-protected.
494 * @param isWriteProtected
495 * Pointer to returned result. True indicates that the media is write-protected (it
496 * cannot be written); False indicates that the media is not write-protected (it
497 * is permissible to write).
498 */
499 virtual IOReturn reportWriteProtection(bool *isWriteProtected);
500
501 protected:
502
503 /*!
504 * @function createReadCdb
505 * @abstract
506 * Create a SCSI CDB for a read operation.
507 * @discussion
508 * Override this to control the cdb created for a read operation.
509 * The default implementation creates a 10-byte read command with
510 * disconnect allowed, 8-byte autosense, and a 2-second timeout.
511 * @param cdb
512 * A pointer to the CDB bytes.
513 * @param cdbLength
514 * The length of the CDB in bytes.
515 * @param block
516 * The device block to be read.
517 * @param nblks
518 * The number of blocks to be transferred.
519 * @param maxAutoSenseLength
520 * The maximum size of the autosense data, in bytes. A value of zero
521 * will disable autosense.
522 * @param timeoutSeconds
523 * The command timeout in seconds.
524 * @result
525 * The IOSCSICommandOptions returned will be used to issue the command.
526 */
527 virtual UInt32 createReadCdb(
528 UInt8 *cdb, /* in */
529 UInt32 *cdbLength, /* out */
530 UInt32 block, /* in */
531 UInt32 nblks, /* in */
532 UInt32 *maxAutoSenseLength, /* out */
533 UInt32 *timeoutSeconds); /* out */
534
535 /*!
536 * @function createWriteCdb
537 * @abstract
538 * Create a SCSI CDB for a write operation.
539 * @discussion
540 * Override this to control the cdb created for a write operation.
541 * The default implementation creates a 10-byte write command with
542 * disconnect allowed, 8-byte autosense, and a 2-second timeout.
543 * @param cdb
544 * A pointer to the CDB bytes.
545 * @param cdbLength
546 * The length of the CDB in bytes.
547 * @param block
548 * The device block to be written.
549 * @param nblks
550 * The number of blocks to be transferred.
551 * @param maxAutoSenseLength
552 * The maximum size of the autosense data, in bytes. A value of zero
553 * will disable autosense.
554 * @param timeoutSeconds
555 * The command timeout in seconds.
556 * @result
557 * The IOSCSICommandOptions returned will be used to issue the command.
558 */
559 virtual UInt32 createWriteCdb(
560 UInt8 *cdb, /* in */
561 UInt32 *cdbLength, /* out */
562 UInt32 block, /* in */
563 UInt32 nblks, /* in */
564 UInt32 *maxAutoSenseLength, /* out */
565 UInt32 *timeoutSeconds); /* out */
566
567
568 /*!
569 * @function doInquiry
570 * @abstract
571 * Obtain SCSI Inquiry data from the device.
572 * @discussion
573 * This method issues a SCSI Inquiry command to the device, to obtain
574 * the result in the supplied buffer. The method first issues an
575 * inquiry with a 5-byte length, to obtain the full length of the
576 * devices inquiry data. The second Inquiry command is issued to get
577 * the full inquiry data (limited to maxLen, of course).
578 * @param inqBuf
579 * A pointer to the buffer.
580 * @param maxLen
581 * The maximum number of bytes the buffer can contain.
582 * @param actualLen
583 * A pointer to the returned byte count actually transferred.
584 */
585 virtual IOReturn doInquiry(UInt8 *inqBuf,UInt32 maxLen,UInt32 *actualLen);
586
587 /* ---------------- Internally used methods. ---------------- */
588
589 /*
590 * @group
591 * Internally Used Methods
592 * @discussion
593 * These methods are used internally, and will not generally be modified.
594 */
595
596 /*!
597 * @function allocateContext
598 * @abstract
599 * Allocate a context structure for use with the current IO operation.
600 */
601 virtual struct context * allocateContext(void);
602
603 /*!
604 * @function allocateInquiryBuffer
605 * @abstract
606 * Allocate an inquiry buffer.
607 * @param buf
608 * A pointer for the returned buffer pointer.
609 * @param size
610 * The requested size of the buffer, in bytes.
611 */
612 virtual IOReturn allocateInquiryBuffer(UInt8 **buf,UInt32 size);
613
614 /*!
615 * @function allocateTempBuffer
616 * @abstract
617 * Allocate a buffer for temporary use.
618 * @param buf
619 * A pointer for the returned buffer pointer.
620 * @param size
621 * The requested size of the buffer, in bytes.
622 */
623 virtual IOReturn allocateTempBuffer(UInt8 **buf,UInt32 size);
624
625 /*!
626 * @function allocateReadCapacityBuffer
627 * @abstract
628 * Allocate a buffer for Read-Capacity data.
629 * @param buf
630 * A pointer for the returned buffer pointer.
631 * @param size
632 * The requested size of the buffer, in bytes.
633 */
634 virtual IOReturn allocateReadCapacityBuffer(UInt8 **buf,UInt8 size);
635
636 /*!
637 * @function automaticRetry
638 * @abstract
639 * Return TRUE if we should automatically retry the command just completed.
640 * @discussion
641 * The default implementation of this method reacts to Unit Attention and
642 * Bus Reset conditions, possibly starting the recovery processes for those
643 * conditions and arranging that the subject command is retried after
644 * the recovery procedure finishes.
645 * @param cx
646 * A pointer to the context for the command just completed.
647 */
648 virtual bool automaticRetry(struct context *cx);
649
650 /*!
651 * @function beginBusResetRecovery
652 * @abstract
653 * Begin the Bus Reset recovery process.
654 * @discussion
655 * This method can be overridden to issue the first command necessary
656 * to perform the Bus Reset recovery process for the device.
657 *
658 * The default implementation does nothing and simply calls finishBusResetRecovery.
659 */
660 virtual void beginBusResetRecovery(void);
661
662 /*!
663 * @function beginUnitAttentionRecovery
664 * @abstract
665 * Begin the Unit Attention recovery process.
666 * @discussion
667 * This method can be overridden to issue the first command necessary
668 * to perform the Bus Reset recovery process for the device.
669 *
670 * The default implementation does nothing and simply calls finishUnitAttentionRecovery.
671 */
672 virtual void beginUnitAttentionRecovery(void);
673
674 /*!
675 * @function busResetRecoveryCommandComplete
676 * @abstract
677 * Handle a command completion during the Bus Reset recovery process.
678 * @discussion
679 * This method can be overridden to check the result of each command issued
680 * during the Bus Reset recovery process for the device. Typically it would
681 * bump the "step" value and issue the next command, calling finishBusResetRecovery
682 * when the process is complete.
683 *
684 * The default implementation does nothing.
685 */
686 virtual void busResetRecoveryCommandComplete(struct context *cx);
687
688 /*!
689 * @function customAutomaticRetry
690 * @abstract
691 * Return TRUE if we should automatically retry the command just completed.
692 * @discussion
693 * This method should be overridden to allow checking for, and causing, an
694 * automatic retry of a command.
695 *
696 * The default implementation of this method does nothing except return FALSE.
697 * @param cx
698 * A pointer to the context for the command just completed.
699 */
700 virtual bool customAutomaticRetry(struct context *cx);
701
702 /*!
703 * @function deleteContext
704 * @abstract
705 * Delete a context structure.
706 * @discussion
707 * This method also issues a "release" for the IO buffer and/or lock, if any.
708 * @param cx
709 * A pointer to the context structure to be deleted.
710 */
711 virtual void deleteContext(struct context *cx);
712
713 /*!
714 * @function deleteInquiryBuffer
715 * @abstract
716 * Delete an inquiry data buffer.
717 * @param buf
718 * A pointer to the buffer.
719 * @param size
720 * The requested size of the buffer, in bytes.
721 */
722 virtual void deleteInquiryBuffer(UInt8 *buf,UInt32 size);
723
724 /*!
725 * @function deleteTempBuffer
726 * @abstract
727 * Delete a temporary data buffer.
728 * @param buf
729 * A pointer to the buffer.
730 * @param len
731 * The requested size of the buffer, in bytes.
732 */
733 virtual void deleteTempBuffer(UInt8 *buf,UInt32 len);
734
735 /*!
736 * @function deleteReadCapacityBuffer
737 * @abstract
738 * Delete a Read-Capacity data buffer.
739 * @param buf
740 * A pointer to the buffer.
741 * @param len
742 * The requested size of the buffer, in bytes.
743 */
744 virtual void deleteReadCapacityBuffer(UInt8 *buf,UInt32 len);
745
746 /*!
747 * @function doReadCapacity
748 * @abstract
749 * @discussion
750 * The default implementation of this method issues a standard SCSI
751 * Read Capacity command. The block size and maximum valid block are
752 * extracted from the returned data in an endian-neutral way.
753 * @param blockSize
754 * A pointer to the returned block size value.
755 * @param maxBlock
756 * A pointer to the returned maximum block number.
757 */
758 virtual IOReturn doReadCapacity(UInt64 *blockSize,UInt64 *maxBlock);
759
760 /*!
761 * @function finishBusResetRecovery
762 * @abstract
763 * Finish up after the Bus Reset recovery process is complete.
764 * @discussion
765 * This method would usually not require an override.
766 */
767 virtual void finishBusResetRecovery(void);
768
769 /*!
770 * @function finishUnitAttentionRecovery
771 * @abstract
772 * Finish up after the Unit Attention recovery process is complete.
773 * @discussion
774 * This method would usually not require an override.
775 */
776 virtual void finishUnitAttentionRecovery(void);
777
778 /*!
779 * @function getBlockSize
780 * @abstract
781 * Return the device block size.
782 * @discussion
783 * This method obtains the block size from the Read-Capacity data. If RC data is
784 * not yet cached, a call is made to doReadCapacity to obtain the data.
785 */
786 virtual UInt64 getBlockSize(void);
787
788
789 /*!
790 * @function dequeueCommands
791 * @abstract
792 * Dequeue commands previously enqueued awaiting the proper device power level.
793 * @discussion
794 * This method is called when a command is queued (from queueCommand), when a call
795 * completes (from RWCompletion), and when the device power level changes. All commands
796 * for which the device power level is proper are immediately dequeued.
797 *
798 * Queued synchronous commands are simply "awakened" by unlocking a lock. The originating
799 * thread then continues and issues the command. Asynchronous commands are immediately
800 * dispatched via a call to standardAsyncReadWriteExecute.
801 */
802 virtual void dequeueCommands(void);
803
804 /*!
805 * @function queueCommand
806 * @abstract
807 * Queue commands awaiting the proper device power level.
808 * @discussion
809 * This method is called prior to issuing any IO command, so that each command can
810 * be enqueued awaiting its desired device power level. After queuing the command, a
811 * call is made to dequeueCommands to attempt to dequeue any available command that can
812 * be executed (including the one just queued). Putting commands into the queue ensures
813 * that the proper sequence is maintained.
814 * @param cx
815 * The context for the command being queued.
816 * @param isSync
817 * True if the command is synchronous; False if the command is asynchronous.
818 * @param desiredPower
819 * The device power level needed before the command can execute.
820 */
821 virtual void queueCommand(struct context *cx,bool isSync,UInt32 desiredPower);
822
823 /*!
824 * @function RWCompletion
825 * @abstract
826 * Asynchronous read/write completion routine.
827 * @discussion
828 * A subclass must implement the read-write completion, called upon completion
829 * of an IO started by doAsyncReadWrite.
830 * @param cx
831 * A pointer to the context structure for the completing command.
832 */
833 virtual void RWCompletion(struct context *cx) = 0;
834
835 /*!
836 * @function setupBusResetRecovery
837 * @abstract
838 * Set up to begin Bus Reset recovery.
839 * @discussion
840 * This method would usually not require an override.
841 */
842 virtual void setupBusResetRecovery(void);
843
844 /*!
845 * @function setupUnitAttentionRecovery
846 * @abstract
847 * Set up to begin Unit Attention recovery.
848 * @discussion
849 * This method would usually not require an override.
850 */
851 virtual void setupUnitAttentionRecovery(struct context *cx);
852
853 /*!
854 * @function simpleAsynchIO
855 * @abstract
856 * Issue a simple asynchronous SCSI command.
857 * @discussion
858 * This method issues a single SCSI command.
859 * The SCSI command must already be set up in the context structure.
860 * @param cx
861 * A pointer to the context structure for the command.
862 */
863 virtual IOReturn simpleAsynchIO(struct context *cx);
864
865 /*!
866 * @function simpleSynchIO
867 * @abstract
868 * Issue a simple synchronous SCSI command.
869 * @discussion
870 * This method issues a single SCSI command and waits for the command
871 * to complete. The SCSI command must already be set up in the context
872 * structure.
873 * @param cx
874 * A pointer to the context structure for the command.
875 */
876 virtual IOReturn simpleSynchIO(struct context *cx);
877
878 /*!
879 * @function standardAsyncReadWrite
880 * @abstract
881 * Start an asynchronous read or write operation.
882 * @discussion
883 * This method starts an asynchronous read or write operation. No
884 * incoming parameters are validated. The default implementation
885 * calls createReadCdb or createWriteCdb,
886 * then issues a SCSI command to IOSCSIDevice. If the command is
887 * accepted, then the completion will be called at some future time.
888 * @result
889 * The only possible returns from this method are:
890 *
891 * kIOReturnSuccess, meaning that the IO was accepted by the transport
892 * drivers provider (e.g. IOSCSIDevice), and that the completion
893 * function will be called when the IO completes, i.e. target->action(param).
894 *
895 * kIOReturnNoMemory, meaning that memory allocation failed.
896 *
897 * Other kIOReturn codes from the provider which occurred
898 * because the IO was not accepted in that provider's queue. This
899 * might indicate a full queue or bad parameter.
900 * @param buffer
901 * An IOMemoryDescriptor describing the data-transfer buffer. The data direction
902 * is contained in the IOMemoryDescriptor. Responsiblity for releasing the descriptor
903 * rests with the caller.
904 * @param block
905 * The starting block number of the data transfer.
906 * @param nblks
907 * The integral number of blocks to be transferred.
908 * @param action
909 * The C function called upon completion of the data transfer.
910 * @param target
911 * The C++ class "this" pointer, passed as an argument to "action."
912 * @param param
913 * This value is passed as an argument to "action." It is not validated or modified.
914 */
915 virtual IOReturn standardAsyncReadWrite(IOMemoryDescriptor *buffer,
916 UInt32 block,UInt32 nblks,
917 IOStorageCompletion completion);
918
919 /*!
920 * @function standardAsyncReadWriteExecute
921 * @abstract
922 * Issue an asynchronous read/write operation after dequeuing.
923 * @param cx
924 * A pointer to the context structure for the command.
925 */
926 virtual IOReturn standardAsyncReadWriteExecute(struct context *cx);
927
928 /*!
929 * @function standardSyncReadWrite
930 * Perform a synchronous read or write operation.
931 * @param buffer
932 * An IOMemoryDescriptor describing the data-transfer buffer. The data direction
933 * is contained in the IOMemoryDescriptor. Responsiblity for releasing the descriptor
934 * rests with the caller.
935 * @param block
936 * The starting block number of the data transfer.
937 * @param nblks
938 * The integral number of blocks to be transferred.
939 */
940 virtual IOReturn standardSyncReadWrite(IOMemoryDescriptor *buffer,UInt32 block,UInt32 nblks);
941
942 /*!
943 * @function stringFromState
944 * @abstract
945 * Return a string description of a state value.
946 * @discussion
947 * Used for debugging.
948 * @param state
949 * The state to be converted to a string description.
950 */
951 virtual char * stringFromState(stateValue state);
952
953 /*!
954 * @function unitAttentionRecoveryCommandComplete
955 * @abstract
956 * Handle a command completion during the Unit Attention recovery process.
957 * @discussion
958 * This method can be overridden to check the result of each command issued
959 * during the Unit Attention recovery process for the device. Typically it would
960 * bump the "step" value and issue the next command, calling finishUnitAttentionRecovery
961 * when the process is complete.
962 *
963 * The default implementation does nothing.
964 */
965 virtual void unitAttentionRecoveryCommandComplete(struct context *cx);
966
967 /*!
968 * @function unitAttentionDetected
969 * @abstract
970 * Determine if a Unit Attention condition occurred.
971 * @param cx
972 * A pointer to the context structure for the command just executed.
973 */
974 virtual bool unitAttentionDetected(struct context *cx);
975
976 public:
977
978 /*!
979 * @function genericCompletion
980 * @abstract
981 * Generic IO completion function.
982 * @discussion
983 * This method handles completion of a SCSI command. It implements a
984 * simple state machine to handle a Unit Attention condition on a
985 * command.
986 *
987 * This method must be public so we can reach it from
988 * the C-language callback "glue" routine. It should not be called
989 * from outside this class.
990 *
991 *
992 *
993 * If a Unit Attention condition occurs, we set the state to
994 * kHandlingUnitAttention and call handleUnitAttention to do whatever
995 * is necessary to clear the condition. Eventually, handleUnitAttention
996 * resets the state to kDoneHandlingUnitAttention, which will allow
997 * the state machine to reissue the original command.
998 *
999 * If we are already processing a Unit Attention, then genericCompletion
1000 * increments a step counter and calls handleUnitAttention. The step
1001 * counter allows handleUnitAttention to issue multiple SCSI commands
1002 * to clear the condition. The handleUnitAttention method is called
1003 * repeatedly, until the state is set to kDoneHandlingUnitAttention.
1004 *
1005 * If this operation is a normal asynchronous read or write (usually
1006 * started by standardAsyncReadWrite, though this is not required),
1007 * then a call is made to RWCompletion, followed by deletion of the
1008 * context structure for the command. RWCompletion is implemented by
1009 * the subclass of IOBasicSCSI, for example in IOSCSIHDDrive.
1010 * @param cx
1011 * A pointer to the context structure for the command.
1012 */
1013 virtual void genericCompletion(struct context *cx);
1014
1015 /*
1016 * @endgroup
1017 */
1018
1019 protected:
1020
1021 /*
1022 * @group
1023 * Power Management Methods
1024 * @discussion
1025 * A subclass must implement these to report the power level required to do various commands.
1026 */
1027
1028 /*!
1029 * @function getExecuteCDBPowerState
1030 * @abstract
1031 * Return the required device power level to execute a client CDB.
1032 */
1033 virtual UInt32 getExecuteCDBPowerState(void) = 0;
1034
1035 /*!
1036 * @function getInquiryPowerState
1037 * @abstract
1038 * Return the required device power level to issue an Inquiry command.
1039 */
1040 virtual UInt32 getInquiryPowerState(void) = 0;
1041
1042 /*!
1043 * @function getReadCapacityPowerState
1044 * @abstract
1045 * Return the required device power level to issue a Read Capacity command.
1046 */
1047 virtual UInt32 getReadCapacityPowerState(void) = 0;
1048
1049 /*!
1050 * @function getReadWritePowerState
1051 * @abstract
1052 * Return the required device power level to issue a data read or write.
1053 */
1054 virtual UInt32 getReadWritePowerState(void) = 0;
1055
1056 /*!
1057 * @function getReportWriteProtectionPowerState
1058 * @abstract
1059 * Return the required device power level to determine media write protection.
1060 */
1061 virtual UInt32 getReportWriteProtectionPowerState(void) = 0;
1062
1063 /*!
1064 * @function powerTickle
1065 * @abstract
1066 * Check for the device power state currently being in the desired state.
1067 * @discussion
1068 * A subclass must implement powerTickle, which is called when we desire power to
1069 * execute a command. PowerTickle may handle generic or a subclass-expanded set of
1070 * power states. The implementation will usually relay the call to the Power Management
1071 * subsystem function activityTickle. For a device without power management capability,
1072 * the implementation should always return True.
1073 * @param desiredState
1074 * The desired device power level.
1075 * @result
1076 * True if power is in the desired state (or better); False if the caller must wait
1077 * until power is available.
1078 */
1079 virtual bool powerTickle(UInt32 desiredState) = 0;
1080
1081 /*
1082 * @endgroup
1083 */
1084
1085 /*!
1086 * @var _provider
1087 * A pointer to our provider.
1088 */
1089 IOSCSIDevice * _provider;
1090
1091 /*!
1092 * @var _busResetContext
1093 * A pointer to a context struct to be used by recoverAfterBusReset.
1094 */
1095 struct context * _busResetContext;
1096
1097 /*!
1098 * @var _unitAttentionContext
1099 * A pointer to a context struct to be used by handleUnitAttention.
1100 */
1101 struct context * _unitAttentionContext;
1102
1103 /*!
1104 * @var _busResetRecoveryInProgress
1105 * True if recovery from Bus Reset is in progress.
1106 */
1107 bool _busResetRecoveryInProgress;
1108
1109 /*!
1110 * @var _unitAttentionRecoveryInProgress
1111 * True if recovery from Unit Attention is in progress.
1112 */
1113 bool _unitAttentionRecoveryInProgress;
1114
1115 /* Device information : */
1116
1117 /*!
1118 * @var _inqBuf
1119 * A pointer to the allocate Inquiry Data buffer.
1120 */
1121 UInt8 * _inqBuf; /* the Inquiry data buffer */
1122
1123 /*!
1124 * @var _inqBufSize
1125 * The size of the inquiry data buffer, in bytes.
1126 */
1127 UInt32 _inqBufSize; /* size of the buffer */
1128
1129 /*!
1130 * @var _inqLen
1131 * The number of valid bytes of inquiry data.
1132 */
1133 UInt32 _inqLen; /* valid bytes in buffer */
1134
1135 /*!
1136 * @var _vendor
1137 * The Vendor Name string from the inquiry data, null-terminated.
1138 */
1139 char _vendor[9]; /* info from Inquiry data */
1140
1141 /*!
1142 * @var _product
1143 * The Product Name string from the inquiry data, null-terminated.
1144 */
1145 char _product[17];
1146
1147 /*!
1148 * @var _rev
1149 * The Product Revision string from the inquiry data, null-terminated.
1150 */
1151 char _rev[5];
1152
1153 /* Since we get both of these items from the same command, we
1154 * just cache both values if we get either call, so we only
1155 * have to issue the command once.
1156 */
1157
1158 /*!
1159 * @var _readCapDone
1160 * True if we have issued a Read-Capacity command to obtain the
1161 * values for _maxBlock and _blockSize.
1162 */
1163 bool _readCapDone;
1164
1165 /*!
1166 * @var _removable
1167 * True if the media is removable; False if the media is fixed.
1168 */
1169 bool _removable;
1170
1171 /*!
1172 * @var _maxBlock
1173 * The highest valid block on the media, relative to zero.
1174 */
1175 UInt64 _maxBlock;
1176
1177 /*!
1178 * @var _blockSize
1179 * The block size of the media in bytes.
1180 */
1181 UInt64 _blockSize;
1182
1183 /* The queue of pending requests awaiting power: */
1184
1185 /*!
1186 * @struct queue
1187 * @discussion
1188 * A data structure for a queue.
1189 * @field head
1190 * A pointer to the head item.
1191 * @field tail
1192 * A pointer to the tail item.
1193 * @field lock
1194 * A lock used to protect the queue during changes.
1195 */
1196 /*!
1197 * @var _powerQueue
1198 * A queue structure containing operations queued awaiting power level.
1199 */
1200 struct queue {
1201 struct context * head;
1202 struct context * tail;
1203 IOLock * lock;
1204 } _powerQueue;
1205
1206 };
1207 #endif