]>
Commit | Line | Data |
---|---|---|
1c79356b A |
1 | /* |
2 | * Copyright (c) 1998-2000 Apple Computer, Inc. All rights reserved. | |
3 | * | |
4 | * @APPLE_LICENSE_HEADER_START@ | |
5 | * | |
6 | * The contents of this file constitute Original Code as defined in and | |
7 | * are subject to the Apple Public Source License Version 1.1 (the | |
8 | * "License"). You may not use this file except in compliance with the | |
9 | * License. Please obtain a copy of the License at | |
10 | * http://www.apple.com/publicsource and read it before using this file. | |
11 | * | |
12 | * This Original Code and all software distributed under the License are | |
13 | * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER | |
14 | * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, | |
15 | * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, | |
16 | * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the | |
17 | * License for the specific language governing rights and limitations | |
18 | * under the License. | |
19 | * | |
20 | * @APPLE_LICENSE_HEADER_END@ | |
21 | */ | |
22 | ||
23 | ||
24 | /*! | |
25 | @header IOSCSICommand_Reference.h | |
26 | ||
27 | This header defines the IOSCSICommand class. | |
28 | ||
29 | This class encapsulates a SCSI Command. The client driver allocates a | |
30 | command using IOSCSIDevice::allocCommand() and initializes it using | |
31 | functions of this class. The client can then submit the command to | |
32 | the SCSI stack by invoking the execute() function. | |
33 | */ | |
34 | ||
35 | ||
36 | /*! | |
37 | @enum SCSICDBFlags | |
38 | Defines values for the cdbFlags field in the SCSICDBInfo structure. | |
39 | @constant kCDBFNoDisconnect | |
40 | Set by the IOSCSIDevice client to indicate the target may not disconnect | |
41 | during the execution of this IOSCSICommand. | |
42 | @constant kCDBFlagsDisableParity | |
43 | Set by the IOSCSIController class to tell the host adapter driver to disable | |
44 | parity checking during the execution of this CDB. | |
45 | @constant kCDBFlagsNoDisconnect | |
46 | Set by the IOSCSIController class to tell the host adapter driver that the | |
47 | target may not disconnect during the execution of this IOSCSICommand. | |
48 | @constant kCDBFlagsNegotiateSDTR | |
49 | Set by the IOSCSIController class to tell the host adapter driver that it | |
50 | should initiate synchronous data transfer negotiation during this IOSCSICommand. | |
51 | @constant kCDBFlagsNegotiateWDTR | |
52 | Set by the IOSCSIController class to tell the host adapter driver that it | |
53 | should initiate wide data transfer negotiation during this IOSCSICommand. | |
54 | */ | |
55 | enum SCSICDBFlags { | |
56 | kCDBFNoDisconnect = 0x00000001, | |
57 | ||
58 | /* | |
59 | * Note: These flags are for IOSCSIController subclasses only | |
60 | */ | |
61 | kCDBFlagsDisableParity = 0x08000000, | |
62 | kCDBFlagsNoDisconnect = 0x10000000, | |
63 | kCDBFlagsNegotiateSDTR = 0x20000000, | |
64 | kCDBFlagsNegotiateWDTR = 0x40000000, | |
65 | }; | |
66 | ||
67 | ||
68 | /*! | |
69 | @enum SCSIAdapterStatus | |
70 | Defines the values of the adapterStatus field of the SCSIResults structure. | |
71 | @constant kSCSIAdapterStatusSuccess | |
72 | Request completed with no adapter reported errors. | |
73 | @constant kSCSIAdapterStatusProtocolError | |
74 | Violation of SCSI protocol detected by host adapter. | |
75 | @constant kSCSIAdapterStatusSelectionTimeout | |
76 | Target device did not respond to selection. | |
77 | @constant kSCSIAdapterStatusMsgReject | |
78 | Adapter received a msg reject from the target device. | |
79 | @constant kSCSIAdapterStatusParityError | |
80 | Adapter detected, or target reported a parity error during the | |
81 | IOSCSICommand. | |
82 | @constant kSCSIAdapterStatusOverrun | |
83 | Target device requested more data than supplied by host. | |
84 | */ | |
85 | enum SCSIAdapterStatus { | |
86 | kSCSIAdapterStatusSuccess = 0, | |
87 | kSCSIAdapterStatusProtocolError, | |
88 | kSCSIAdapterStatusSelectionTimeout, | |
89 | kSCSIAdapterStatusMsgReject, | |
90 | kSCSIAdapterStatusParityError, | |
91 | kSCSIAdapterStatusOverrun, | |
92 | }; | |
93 | ||
94 | ||
95 | /*! | |
96 | @typedef SCSICDBInfo | |
97 | @discussion | |
98 | Fields specified here are set by IOSCSIDevice client, while others | |
99 | are set by the IOSCSIController class for use by the host adapter | |
100 | driver. The client should zero all fields of the structure prior | |
101 | to use. | |
102 | @field cdbFlags | |
103 | See enum SCSICDBFlags for flag definitions. | |
104 | @field cdbTagMsg | |
105 | This field should be set to zero by the IOSCSIDevice client. If the | |
106 | SCSI device supports tag queuing then the IOSCSIController class | |
107 | will set this field to select simple (unordered) tags. | |
108 | @field cdbTag | |
109 | This field is set by the IOSCSIController class to tell the host | |
110 | adapter driver the SCSI tag value to assign to this IOSCSICommand. | |
111 | @field cdbLength | |
112 | Set by the IOSCSIDevice client to the length of the Command Descriptor | |
113 | Block (CDB). | |
114 | @field cdb | |
115 | Set by the IOSCSIDevice client to command descriptor block the client | |
116 | wishes the target to execute. | |
117 | */ | |
118 | typedef struct SCSICDBInfo { | |
119 | ||
120 | UInt32 cdbFlags; | |
121 | ||
122 | UInt32 cdbTagMsg; | |
123 | UInt32 cdbTag; | |
124 | ||
125 | UInt32 cdbAbortMsg; | |
126 | ||
127 | UInt32 cdbLength; | |
128 | UInt8 cdb[16]; | |
129 | ||
130 | UInt32 reserved[16]; | |
131 | } SCSICDBInfo; | |
132 | ||
133 | ||
134 | /*! | |
135 | @typedef SCSIResults | |
136 | @field returnCode | |
137 | The overall return code for the command. See iokit/iokit/IOReturn.h. | |
138 | This value is also returned as the getResults() return value. | |
139 | ||
140 | Note: The SCSI Family will automatically generate standard return codes | |
141 | based on the values in the adapterStatus and scsiStatus fields. Unless | |
142 | the IOSCSIController subclass needs set a specific return code, it should | |
143 | leave this field set to zero. | |
144 | @field bytesTransferred | |
145 | The total number of bytes transferred to/from the target device. | |
146 | @field adapterStatus | |
147 | The IOSCSIController subclass must fill-in this field as appropriate. | |
148 | See enum SCSIAdapterStatus. | |
149 | @field scsiStatus | |
150 | The SCSI Status byte returned from the target device. | |
151 | @field requestSenseDone | |
152 | A boolean indicating whether sense data was obtained from the target | |
153 | device. | |
154 | @field requestSenseLength | |
155 | The number of sense data bytes returned from the target device. | |
156 | */ | |
157 | typedef struct SCSIResults { | |
158 | IOReturn returnCode; | |
159 | ||
160 | UInt32 bytesTransferred; | |
161 | ||
162 | enum SCSIAdapterStatus adapterStatus; | |
163 | UInt8 scsiStatus; | |
164 | ||
165 | bool requestSenseDone; | |
166 | UInt32 requestSenseLength; | |
167 | } SCSIResults; | |
168 | ||
169 | ||
170 | /*! | |
171 | @enum SCSIQueueType | |
172 | Each IOSCSIDevice has two queues, a normal Q and a bypass Q. The treatment of the | |
173 | queues is essentially identical except that the bypass Q is given preference whenever | |
174 | it has commands available. | |
175 | ||
176 | Usually, the client will use the normal Q for regular I/O commands and the bypass Q | |
177 | to send error recovery commands to the device. | |
178 | @constant kQTypeNormalQ | |
179 | Indicates command applies to the normal IOSCSIDevice queue. | |
180 | @constant kQTypeBypassQ | |
181 | Indicates command applies to the bypass IOSCSIDevice queue. | |
182 | */ | |
183 | enum SCSIQueueType { | |
184 | kQTypeNormalQ = 0, | |
185 | kQTypeBypassQ = 1, | |
186 | }; | |
187 | ||
188 | ||
189 | /*! | |
190 | @enum SCSIQueuePosition | |
191 | Indicates whether a IOSCSICommand should be added to the head or tail | |
192 | of the queue selected. | |
193 | @constant kQPositionTail | |
194 | Queue request at the tail (end) of the selected queue. | |
195 | @constant kQPositionHead | |
196 | Queue request at the head (front) of the selected queue. | |
197 | */ | |
198 | enum SCSIQueuePosition { | |
199 | kQPositionTail = 0, | |
200 | kQPositionHead = 1, | |
201 | }; | |
202 | ||
203 | ||
204 | /*! | |
205 | @struct SCSITargetLun | |
206 | @field target | |
207 | The SCSI Id for the SCSI device being selected. | |
208 | @field lun | |
209 | The SCSI Lun for the SCSI device being selected. | |
210 | */ | |
211 | typedef struct SCSITargetLun { | |
212 | UInt8 target; | |
213 | UInt8 lun; | |
214 | UInt8 reserved[2]; | |
215 | } SCSITargetLun; | |
216 | ||
217 | /*! | |
218 | @class IOSCSICommand : public IOCDBCommand | |
219 | @abstract | |
220 | Class that describes a SCSI device (target/lun pair). | |
221 | @discussion | |
222 | This class encapsulates a SCSI Command. The client driver allocates a | |
223 | command using IOSCSIDevice::allocCommand() and initializes it using | |
224 | functions of this class. The client can then submit the command to | |
225 | the SCSI stack by invoking the execute() function. | |
226 | */ | |
227 | class IOSCSICommand : public IOCDBCommand | |
228 | { | |
229 | public: | |
230 | ||
231 | ||
232 | /*! | |
233 | @function setPointers | |
234 | @abstract | |
235 | Sets the data buffer component of a SCSI Command. | |
236 | @discussion | |
237 | The client provides an IOMemoryDescriptor object to corresponding | |
238 | to the client's data or request sense buffer, the maximum data transfer count | |
239 | and data transfer direction. | |
240 | @param desc | |
241 | Pointer to a IOMemoryDescriptor describing the client's I/O buffer. | |
242 | @param transferCount | |
243 | Maximum data transfer count in bytes. | |
244 | @param isWrite | |
245 | Data transfer direction. (Defined with respect to the device, i.e. isWrite = true | |
246 | indicates the host is writing to the device. | |
247 | @param isSense | |
248 | If isSense is set to false, the IOSCSICommand's data buffer information is set. Otherwise, | |
249 | the IOSCSICommand's request sense buffer information is set | |
250 | */ | |
251 | void setPointers( IOMemoryDescriptor *desc, UInt32 transferCount, bool isWrite, bool isSense=false ); | |
252 | ||
253 | ||
254 | /*! | |
255 | @function getPointers | |
256 | @abstract | |
257 | Gets the data buffer component of a SCSI Command. | |
258 | @discussion | |
259 | The client provides a set of pointers to fields to receive the IOSCSICommand's | |
260 | data/request sense buffer pointers. | |
261 | @param desc | |
262 | Pointer to a field (IOMemoryDescriptor *) to receive the IOSCSICommand's IOMemoryDescriptor pointer. | |
263 | @param transferCount | |
264 | Pointer to a field (UInt32) to receive the IOSCSICommand's maximum transfer count. | |
265 | @param isWrite | |
266 | Pointer to a field (bool) to receive the IOSCSICommand's transfer direction. | |
267 | @param isSense | |
268 | If isSense is set to true, the IOSCSICommand's data buffer information is returned. Otherwise, | |
269 | the IOSCSICommand's request sense buffer information is returned. | |
270 | */ | |
271 | void getPointers( IOMemoryDescriptor **desc, UInt32 *transferCount, bool *isWrite, bool isSense = false ); | |
272 | ||
273 | /*! | |
274 | @function setTimeout | |
275 | @abstract | |
276 | Sets the timeout for the command in milliseconds. | |
277 | @discussion | |
278 | The IOSCSIController class will abort a command which does not | |
279 | complete with in the time interval specified. The client should | |
280 | set the timeout parameter to zero if they want to suppress | |
281 | timing. | |
282 | @param timeout | |
283 | Command timeout in milliseconds. | |
284 | */ | |
285 | void setTimeout( UInt32 timeoutmS ); | |
286 | ||
287 | /*! | |
288 | @function getTimeout | |
289 | @abstract | |
290 | Gets the timeout for the command in milliseconds. | |
291 | @discussion | |
292 | This function returns the command timeout previously set by setTimeout(). | |
293 | @param timeout | |
294 | Command timeout in milliseconds. | |
295 | */ | |
296 | UInt32 getTimeout(); | |
297 | ||
298 | ||
299 | /*! | |
300 | @function setCallback | |
301 | @abstract | |
302 | Sets the callback routine to be invoked when the SCSI Command completes. | |
303 | @param target | |
304 | Pointer to the object to be passed to the callback routine. This would usually | |
305 | be the client's (this) pointer. | |
306 | @param callback | |
307 | Pointer to the client's function to process the completed command | |
308 | @param refcon | |
309 | Pointer to the information required by the client's callback routine to process | |
310 | the completed command. | |
311 | */ | |
312 | void setCallback( void *target = 0, CallbackFn callback = 0, void *refcon = 0 ); | |
313 | ||
314 | ||
315 | /*! | |
316 | @function getClientData | |
317 | @abstract | |
318 | Returns a pointer to the SCSI Command's client data area. | |
319 | @discussion | |
320 | The client may allocate storage in the SCSI Command for its own use. | |
321 | See IOSCSIDevice::allocateCmd(). | |
322 | */ | |
323 | void *getClientData(); | |
324 | ||
325 | /* | |
326 | @function getCommandData | |
327 | @abstract | |
328 | Returns a pointer to the SCSI Command's controller data area | |
329 | @discussion | |
330 | This area is allocated for use by the IOSCSIController subclass (host adapter | |
331 | driver). The client should not normally access this area. | |
332 | */ | |
333 | void *getCommandData(); | |
334 | ||
335 | ||
336 | /*! | |
337 | @function setCDB | |
338 | @abstract | |
339 | Sets the CDB component of a SCSI Command. | |
340 | @param scsiCDB | |
341 | Pointer to a SCSICDBInfo structure. | |
342 | */ | |
343 | void setCDB( SCSICDBInfo *scsiCmd ); | |
344 | ||
345 | ||
346 | /*! | |
347 | @function getCDB | |
348 | @abstract | |
349 | Gets the CDB component of a SCSI Command. | |
350 | @param scsiCDB | |
351 | Pointer to a SCSICDBInfo structure to receive the SCSI Command's cdb information. | |
352 | */ | |
353 | void getCDB( SCSICDBInfo *scsiCmd ); | |
354 | ||
355 | ||
356 | /*! | |
357 | @function getResults | |
358 | @abstract | |
359 | Gets results from a completed SCSI Command. | |
360 | @discussion | |
361 | The getResults() function returns the value of the returnCode field of the command results. If | |
362 | the client is only interested in a pass/fail indication for the command, the client | |
363 | can pass (SCSIResult *)0 as a parameter. | |
364 | @param results | |
365 | Pointer to a SCSIResults structure to receive the SCSI Commands completion information. | |
366 | */ | |
367 | IOReturn getResults( SCSIResults *results ); | |
368 | ||
369 | /*! | |
370 | @function setResults | |
371 | @abstract | |
372 | Sets the results component of a SCSI Command. | |
373 | @discussion | |
374 | The setResults() function is used by the IOSCSIController subclass (host | |
375 | adapter driver) return results for a SCSI Command about to be completed. | |
376 | @param scsiResults Pointer to a SCSIResults structure containing | |
377 | completion information for the SCSI Command. | |
378 | ||
379 | Completion information is copied into the command, so the caller may | |
380 | release the SCSIResults structure provided when this function returns. | |
381 | */ | |
382 | void setResults( SCSIResults *results ); | |
383 | ||
384 | ||
385 | /*! | |
386 | @function getDevice | |
387 | @abstract | |
388 | Returns the IOSCSIDevice this command is targeted to. | |
389 | @param deviceType | |
390 | The caller should use value kIOSCSIDeviceType. | |
391 | @discussion | |
392 | In some cases a IOSCSICommand is not associated with a specific target/lun. This | |
393 | would be the case for a SCSI Bus Reset. In this case getDevice() returns 0. | |
394 | */ | |
395 | IOSCSIDevice *getDevice( IOSCSIDevice *deviceType ); | |
396 | ||
397 | ||
398 | /*! | |
399 | @function getTargetLun | |
400 | @abstract | |
401 | Returns the target/lun for the IOSCSIDevice this command is associated with. | |
402 | @param targetLun | |
403 | Pointer to a SCSITargetLun structure to receive the target/lun information. | |
404 | */ | |
405 | void getTargetLun( SCSITargetLun *targetLun ); | |
406 | ||
407 | ||
408 | /*! | |
409 | @function execute | |
410 | @abstract | |
411 | Submits a SCSI command to be executed. | |
412 | @discussion | |
413 | Once the execute() function is called, the client should not | |
414 | invoke any further functions on the SCSI Command with the | |
415 | exception of abort(). | |
416 | ||
417 | The execute() function optionally returns sets a unique sequence | |
418 | number token for the command. If the client intends to use the abort() | |
419 | method they must retain this sequence number token. | |
420 | @param sequenceNumber | |
421 | Pointer to field (UInt32) to receive the sequence number assigned to the SCSI | |
422 | Command. | |
423 | */ | |
424 | bool execute( UInt32 *sequenceNumber = 0 ); | |
425 | ||
426 | /*! | |
427 | @function abort | |
428 | @abstract | |
429 | Aborts an executing SCSI Command. | |
430 | @discussion | |
431 | The client may invoke the abort() method to force the completion of an | |
432 | executing SCSI Command. The client must pass the sequence number | |
433 | provided when the execute() function was invoked. | |
434 | ||
435 | Note: The abort function provides no status on whether or not a | |
436 | command has been successfully aborted. The client should wait for the | |
437 | command to actually complete to determine whether the abort completed | |
438 | successfully. | |
439 | @param sequenceNumber | |
440 | The client must pass the sequence number assigned to the command when | |
441 | the client called the execute() function. | |
442 | */ | |
443 | void abort( UInt32 sequenceNumber ); | |
444 | ||
445 | /*! | |
446 | @function complete | |
447 | @abstract | |
448 | Indicates the IOSCSIController subclass (host adapter driver) has completed a SCSI command. | |
449 | @discussion | |
450 | Once the complete() function is called, the controller | |
451 | subclass should make no further accesses to the IOSCSICommand | |
452 | being completed. | |
453 | ||
454 | A IOSCSIDevice client would not normally call this function. | |
455 | */ | |
456 | void complete(); | |
457 | ||
458 | ||
459 | /*! | |
460 | @function getSequenceNumber | |
461 | @abstract | |
462 | Returns the sequence number assigned to an executing command. | |
463 | @discussion | |
464 | The caller should check the sequence number for 0. This indicates that | |
465 | the command has completed or has not been processed to the point where | |
466 | a sequence number has been assigned. | |
467 | */ | |
468 | UInt32 getSequenceNumber(); | |
469 | ||
470 | ||
471 | /*! | |
472 | @function setQueueInfo | |
473 | @abstract | |
474 | Sets queuing information for the SCSI Command. | |
475 | @discussion | |
476 | Each IOSCSIDevice has two queues, a normal Q and a bypass Q. The treatment of the | |
477 | queues is esentially identical except that the bypass Q is given preference whenever | |
478 | it has commands available. | |
479 | ||
480 | Usually, the client will use the normal Q for regular I/O commands and the bypass Q | |
481 | to send error recovery commands to the device. | |
482 | @param queueType | |
483 | Set to kQTypeNormalQ or kQTypeBypassQ to indicate which IOSCSIDevice queue the | |
484 | SCSI Command should be routed to. | |
485 | @param queuePosition | |
486 | Set to kQPositionTail or kQPositionHead to indicate whether the SCSI Command should | |
487 | be added to the head to tail for the selected IOSCSIDevice queue. | |
488 | */ | |
489 | void setQueueInfo( UInt32 queueType = kQTypeNormalQ, UInt32 queuePosition = kQPositionTail ); | |
490 | ||
491 | ||
492 | /*! | |
493 | @function getQueueInfo | |
494 | @abstract | |
495 | Gets queuing information for the SCSI Command. | |
496 | @param queueType | |
497 | Pointer to a field (UInt32) to receive the queue type previously set for this SCSI Command. | |
498 | @param queuePosition | |
499 | Pointer to a field (UInt32) to receive the queue position previously set for this SCSI Command. | |
500 | */ | |
501 | void getQueueInfo( UInt32 *queueType, UInt32 *queuePosition = 0 ); | |
502 | ||
503 | ||
504 | /*! | |
505 | @function getCmdType | |
506 | @abstract | |
507 | Obtains the underlying 'intent' of a SCSI Command. | |
508 | @discussion | |
509 | This function provides information on the intent of a SCSI | |
510 | Command. For example, since Aborts, Request Sense and normal Execute commands are | |
511 | all sent to the executeCommand() function, invoking getCmdType() | |
512 | will indicate whether a Request Sense, Abort or Normal I/O request is | |
513 | being processed. | |
514 | ||
515 | It this information is not normally meaningful to IOSCSIDevice clients. | |
516 | */ | |
517 | UInt32 getCmdType(); | |
518 | ||
519 | ||
520 | /*! | |
521 | @function getOriginalCmd | |
522 | @abstract | |
523 | Obtains a 'related' SCSI Command. | |
524 | @discussion | |
525 | In cases where a SCSI command is related to a previous command, this | |
526 | function will return the original command. For example, if a | |
527 | Request Sense command (CmdType = kSCSICommandReqSense)is processed, | |
528 | then this function can be used to obtain the original command that | |
529 | caused the check condition. If an Abort command (CmdType = | |
530 | kSCSICommandAbort) then this function can be used to obtain the original | |
531 | command the abort was issued against. | |
532 | ||
533 | ||
534 | It this information is not normally meaningful to IOSCSIDevice clients. | |
535 | */ | |
536 | IOSCSICommand *getOriginalCmd(); | |
537 | ||
538 | }; |