]>
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 IOSCSIController_Reference.h | |
26 | ||
27 | This header defines the IOSCSIController class. | |
28 | ||
29 | IOSCSIController provides the superclass for SCSI host | |
30 | adapter drivers. | |
31 | ||
32 | Drivers are instantiated based on their 'personality' entry matching | |
33 | their adapter's OpenFirmware device tree entry. When a match occurs, | |
34 | the driver's class is instantiated. Since the driver is written as a | |
35 | subclass of IOSCSIController, an instance of the SCSI Family is automatically | |
36 | instantiated. | |
37 | */ | |
38 | ||
39 | ||
40 | /*! | |
41 | @typedef SCSIControllerInfo | |
42 | Parameter structure passed for configure() function. | |
43 | @field initiatorId | |
44 | The SCSI address of your host adapter. Usually 7 (decimal). | |
45 | @field maxTargetsSupported | |
46 | The number of targets you controller supports. Typically 8 or 16. | |
47 | @field maxLunsSupported | |
48 | The number of logical units per target your controller supports. | |
49 | Typically 8. | |
50 | @field minTransferPeriodpS | |
51 | The minimum synchronous data transfer period in picoseconds your | |
52 | controller supports. | |
53 | @field maxTransferOffset | |
54 | The maximum synchronous data offset your controller supports in bytes. | |
55 | @field maxTransferWidth | |
56 | The maximum data SCSI bus width your controller supports in bytes. Must | |
57 | be a power of 2. | |
58 | @field maxCommandsPerController | |
59 | The maximum number of outstanding commands your controller supports | |
60 | across all targets and luns. Set to 0 if there is no controller limit in | |
61 | this category. | |
62 | @field maxCommandsPerTarget | |
63 | The maximum number of outstanding commands your controller supports on a | |
64 | given target. Set to 0 if there is no controller limit in this category. | |
65 | @field maxCommandsPerLun | |
66 | The maximum number of outstanding commands your controller supports on a | |
67 | given lun. Set to 0 if there is no controller limit in this category. | |
68 | @field tagAllocationMethod | |
69 | Controls whether tags are allocated on a per Lun, per Target or per | |
70 | Controller basis. See enum SCSITagAllocation. | |
71 | @field maxTags | |
72 | The maximum number of tags allocated to each Lun, Target or Controller | |
73 | depending on the tagAllocationMethod setting. | |
74 | @field targetPrivateDataSize | |
75 | IOSCSIController will optionally allocate per-target storage for your | |
76 | driver based on the setting of this field. The amount of storage needed | |
77 | is specified in bytes. | |
78 | @field lunPrivateDataSize | |
79 | IOSCSIController will optionally allocate per-lun storage for your | |
80 | driver based on the setting of this field. The amount of storage needed | |
81 | is specified in bytes. | |
82 | @field commandPrivateDataSize | |
83 | IOSCSIController will optionally allocate per-command storage for your | |
84 | driver based on the setting of this field. The amount of storage needed | |
85 | is specified in bytes. | |
86 | ||
87 | Note: The amount of per-command storage allowed is under review. We | |
88 | anticipate that typical SCSI controllers will need not more than 1024 | |
89 | bytes per command. | |
90 | @field disableCancelCommands | |
91 | Subclasses of IOSCSIController which do their own management of | |
92 | aborts/resets can set this field to true to avoid receiving | |
93 | cancelCommand() requests. | |
94 | */ | |
95 | typedef struct SCSIControllerInfo { | |
96 | UInt32 initiatorId; | |
97 | ||
98 | UInt32 maxTargetsSupported; | |
99 | UInt32 maxLunsSupported; | |
100 | ||
101 | UInt32 minTransferPeriodpS; | |
102 | UInt32 maxTransferOffset; | |
103 | UInt32 maxTransferWidth; | |
104 | ||
105 | UInt32 maxCommandsPerController; | |
106 | UInt32 maxCommandsPerTarget; | |
107 | UInt32 maxCommandsPerLun; | |
108 | ||
109 | UInt32 tagAllocationMethod; | |
110 | UInt32 maxTags; | |
111 | ||
112 | UInt32 targetPrivateDataSize; | |
113 | UInt32 lunPrivateDataSize; | |
114 | UInt32 commandPrivateDataSize; | |
115 | ||
116 | bool disableCancelCommands; | |
117 | ||
118 | UInt32 reserved[64]; | |
119 | ||
120 | } SCSIControllerInfo; | |
121 | ||
122 | ||
123 | /*! | |
124 | @enum SCSITagAllocation | |
125 | @discussion | |
126 | This enum defines how SCSI tags are allocated. | |
127 | @constant kTagAllocationNone | |
128 | This controller does not support tag queuing. | |
129 | @constant kTagAllocationPerLun | |
130 | Each SCSI Lun has its own private tag pool containing | |
131 | (maxTags) SCSI tags. | |
132 | @constant kTagAllocationPerTarget | |
133 | Each SCSI Target has its own private tag pool contain | |
134 | (maxTags) SCSI tags. Luns connected to this target | |
135 | allocate tags from this pool. | |
136 | @constant kTagAllocationPerController | |
137 | The controller has a global tag pool containing (maxTags) | |
138 | SCSI tags. This pool is shared by all Luns connected to | |
139 | this controller. | |
140 | */ | |
141 | enum { | |
142 | kTagAllocationNone = 0, | |
143 | kTagAllocationPerLun, | |
144 | kTagAllocationPerTarget, | |
145 | kTagAllocationPerController, | |
146 | }; | |
147 | ||
148 | ||
149 | /*! | |
150 | @class IOSCSIController : public IOService | |
151 | @abstract | |
152 | Superclass for SCSI host adapter drivers | |
153 | @discussion | |
154 | The IOSCSIController class provides a number of services to simplify | |
155 | writing a driver for your host adapter. | |
156 | ||
157 | Specifically, the class provides the following features: | |
158 | ||
159 | 1. Complete request scheduling semantics. | |
160 | ||
161 | The IOSCSIController class manages request queues on behalf of its | |
162 | subclasses. It tracks all requests submitted to its subclasses, | |
163 | including managing timeouts, aborts and request cancellations. | |
164 | ||
165 | 2. Request Sense scheduling | |
166 | ||
167 | Subclasses of IOSCSIController do not need to implement | |
168 | auto-request-sense functionality. Your driver can use the default | |
169 | handling in the super class. | |
170 | ||
171 | 3. Storage management. | |
172 | ||
173 | The IOSCSIController subclass provides per-request private storage areas | |
174 | for your subclass. | |
175 | ||
176 | 4. Resource management. | |
177 | ||
178 | The IOSCSIController subclass will manage the number of outstanding | |
179 | commands submitted to your subclass on a per-controller and per-lun | |
180 | basis. | |
181 | */ | |
182 | @class IOSCSIController : public IOService | |
183 | { | |
184 | public: | |
185 | ||
186 | ||
187 | /*! | |
188 | @function configure | |
189 | @abstract | |
190 | Driver configuration/initialization request. | |
191 | @discussion | |
192 | The configure() member function is the first call your subclass will | |
193 | receive. You should provide the information requested in the | |
194 | SCSIControllerInfo structure and enable your hardware for operation. | |
195 | If your driver initialized successfully, you should return true, otherwise, | |
196 | your driver should return false. | |
197 | @param provider | |
198 | Pointer to an object (usually IOPCIDevice) which represents the bus of | |
199 | your device is attached to . Typically your driver will use functions | |
200 | supplied by this object to access PCI space on your hardware. See | |
201 | IOPCIDevice for a description of PCI services. | |
202 | @param controllerInfo | |
203 | Pointer to a SCSIControllerInfo structure. Your driver should provide | |
204 | the information requested in this structure prior to returning from | |
205 | the configure() call. | |
206 | */ | |
207 | bool configure( IOService *provider, SCSIControllerInfo *controllerInfo ); | |
208 | ||
209 | ||
210 | /*! | |
211 | @function executeCommand | |
212 | @abstract | |
213 | Execute a IOSCSICommand. | |
214 | @discussion | |
215 | The executeCommand() function is called for all 'routine' I/O requests | |
216 | including abort requests. The driver is passed a pointer to an | |
217 | IOSCSICommand object. The driver obtains information about the I/O | |
218 | request by using function calls provided by the IOSCSICommand | |
219 | class. | |
220 | @param scsiCommand | |
221 | Pointer to a IOSCSICommand. See IOSCSICommand for more information. | |
222 | */ | |
223 | void executeCommand( IOSCSICommand *scsiCommand ); | |
224 | ||
225 | ||
226 | /*! | |
227 | @function cancelCommand | |
228 | @abstract | |
229 | Cancels a IOSCSICommand previously submitted to the driver. | |
230 | @discussion | |
231 | The cancelCommand() function is called to inform your subclass to force | |
232 | completion of a SCSI command. | |
233 | ||
234 | Your subclass should call the getOriginalCmd() to determine the command | |
235 | to complete. | |
236 | ||
237 | After calling complete() on the original command, you should complete | |
238 | the IOSCSICommand passed to the cancelCommand() function | |
239 | ||
240 | Note: When a cancelCommand is issued, your subclass may presume that any | |
241 | activity to remove an active command from the SCSI Target, i.e. (abort | |
242 | tag/abort) has already occurred. | |
243 | @param scsiCommand | |
244 | Pointer to a IOSCSICommand. See IOSCSICommand for more information. | |
245 | */ | |
246 | void cancelCommand( IOSCSICommand *scsiCommand ); | |
247 | ||
248 | ||
249 | /*! | |
250 | @function resetCommand | |
251 | @abstract | |
252 | Request the driver issue a SCSI Bus reset. | |
253 | @discussion | |
254 | The resetCommand() function indicates you should do a SCSI Bus Reset. | |
255 | After issuing the reset you should complete to IOSCSICommand passed. | |
256 | ||
257 | Note: After you report the IOSCSICommand Reset complete, you will | |
258 | receive cancelCommand() requests for all outstanding commands. | |
259 | @param scsiCommand | |
260 | Pointer to a IOSCSICommand. See IOSCSICommand for more information. | |
261 | */ | |
262 | void resetCommand( IOSCSICommand *scsiCommand ); | |
263 | ||
264 | ||
265 | /*! | |
266 | @function resetOccurred | |
267 | @abstract | |
268 | Inform the IOSCSIController class of an unsolicited SCSI Bus reset. | |
269 | @discussion | |
270 | Your subclass should call this function if | |
271 | you detect a target initiated bus reset, or need to do an unplanned SCSI | |
272 | Bus Reset as part of adapter error recovery. | |
273 | ||
274 | Note: After you call the resetOccurred() function, you will receive | |
275 | cancelCommand() requests for all outstanding IOSCSICommand(s). | |
276 | */ | |
277 | void resetOccurred(); | |
278 | ||
279 | /*! | |
280 | @function rescheduleCommand | |
281 | @abstract | |
282 | Return a IOSCSICommand for rescheduling. | |
283 | @discussion | |
284 | If your subclass function cannot start processing an otherwise | |
285 | acceptable IOSCSICommand due to resource constraints, i.e. MailBox full, | |
286 | lost SCSI Bus arbitration, you may have the IOSCSICommand rescheduled by | |
287 | calling rescheduleCommand(). A IOSCSICommand passed to this function | |
288 | should be treated as 'complete', i.e. you should make no further | |
289 | accesses to it. | |
290 | ||
291 | Note: If you cannot process further commands, you should call the | |
292 | disableCommands() function to prevent receiving additional commands | |
293 | until you are ready to accept them. | |
294 | @param scsiCommand | |
295 | Pointer to IOSCSICommand your driver needs to reschedule. | |
296 | */ | |
297 | void rescheduleCommand( IOSCSICommand *scsiCommand ); | |
298 | ||
299 | ||
300 | /*! | |
301 | @function disableCommands | |
302 | @abstract | |
303 | Suspend sending I/O commands to your driver. | |
304 | @discussion | |
305 | In cases where your executeCommand() member function cannot accept | |
306 | commands, you may disable further calls by invoking disableCommands(). | |
307 | Use enableCommands() to resume receiving commands. | |
308 | ||
309 | Note: The resetCommand() and cancelCommands() entry points are not | |
310 | affected by the use of this function. | |
311 | ||
312 | Note: The default timeout for disableCommands() is 5s. If this timeout | |
313 | is exceeded the IOSCSIController class will call your driver's | |
314 | disableTimeoutOccurred() function. The default action of this function | |
315 | is to issue a SCSI Bus Reset by calling your driver's resetCommand() | |
316 | function. | |
317 | @param timeoutmS | |
318 | Your driver may override the default timeout | |
319 | by specifying a timeout value in milliseconds. | |
320 | */ | |
321 | void disableCommands( UInt32 timeoutmS ); | |
322 | ||
323 | ||
324 | /*! | |
325 | @function enableCommands | |
326 | @abstract | |
327 | Resume sending I/O commands to your driver. | |
328 | @discussion | |
329 | Resumes sending I/O commands to your driver that were previously suspended | |
330 | by calling disableCommands(). | |
331 | */ | |
332 | void enableCommands(); | |
333 | ||
334 | /*! | |
335 | @function disableTimeoutOccurred | |
336 | @abstract | |
337 | Indicates your driver has suspended commands too long. | |
338 | @discussion | |
339 | The IOSCSIController superclass will timeout disableCommand() requests | |
340 | to preclude the possibility of a hung SCSI bus. If a timeout occurs, | |
341 | then disableTimeoutOccurred() will be called. The default action of this | |
342 | routine is to do a SCSI Bus Reset by calling resetCommand(). Your | |
343 | subclass may choose to modify the default behavior of this routine to do | |
344 | additional adapter specific error recovery. | |
345 | */ | |
346 | void disableTimeoutOccurred(); | |
347 | ||
348 | ||
349 | /*! | |
350 | @function findCommandWithNexus | |
351 | @abstract | |
352 | Locate an active IOSCSICommand using target/lun/tag values. | |
353 | @discussion | |
354 | Your subclass can use this function to search for an active | |
355 | IOSCSICommand by providing the target/lun/tag values for the command. In | |
356 | the case of a non-tagged command the second parameter must either be | |
357 | omitted or set to -1. | |
358 | ||
359 | An unsuccessful search will return 0. | |
360 | @param targetLun | |
361 | Structure of type SCSITargetLun, initialized to the target/lun value you | |
362 | wish to search for. | |
363 | @param tagValue | |
364 | Optional tag value you wish to search for. | |
365 | */ | |
366 | IOSCSICommand *findCommandWithNexus( SCSITargetLun targetLun, UInt32 tagValue = (UInt32) -1 ); | |
367 | ||
368 | /*! | |
369 | @function allocateTarget | |
370 | @abstract | |
371 | Notifies driver of allocation of per-Target resources. | |
372 | @discussion | |
373 | Your driver will be called at its allocateTarget() function when a target is about | |
374 | to be probed. The your driver should initialize its per-target data at this time. | |
375 | If the subclass wishes to prevent probing of this target, it should return false | |
376 | as the result of this function call. | |
377 | ||
378 | This is an optional function. Your driver is not required to implement it. | |
379 | @param targetLun | |
380 | SCSITargetLun structure containing the SCSI Id of the target that is about to be | |
381 | allocated. | |
382 | */ | |
383 | bool allocateTarget( SCSITargetLun targetLun ); | |
384 | ||
385 | ||
386 | /*! | |
387 | @function deallocateTarget | |
388 | @abstract | |
389 | Notifies driver that target resources will be deallocated. | |
390 | @discussion | |
391 | Your driver will be called at its deallocateTarget() function when a target is about | |
392 | deallocated. The your driver must insure that there will be no further access to | |
393 | the per-target data allocated to this target. | |
394 | ||
395 | This is an optional function. Your driver is not required to implement it. | |
396 | @param targetLun | |
397 | SCSITargetLun structure containing the SCSI Id of the target that is about to be | |
398 | deallocated. | |
399 | */ | |
400 | bool deallocateTarget( SCSITargetLun targetLun ); | |
401 | ||
402 | ||
403 | /*! | |
404 | @function allocateLun | |
405 | @abstract | |
406 | Notifies driver of allocation of per-Lun resources. | |
407 | @discussion | |
408 | Your driver will be called at its allocateLun() function when a Lun is about | |
409 | to be probed. The your driver should initialize its per-lun data at this time. | |
410 | If the subclass wishes to prevent probing of this lun, it should return false | |
411 | as the result of this function call. | |
412 | ||
413 | This is an optional function. Your driver is not required to implement it. | |
414 | @param targetLun | |
415 | SCSITargetLun structure containing the SCSI Id of the target/lun that is about to be | |
416 | allocated. | |
417 | */ | |
418 | bool allocateLun( SCSITargetLun targetLun ); | |
419 | ||
420 | ||
421 | /*! | |
422 | @function deallocateLun | |
423 | @abstract | |
424 | Notifies driver of deallocation of per-Lun resources. | |
425 | @discussion | |
426 | Your driver will be called at its deallocateLun() function when a Lun is about | |
427 | deallocated. The your driver must insure that there will be no further access to | |
428 | the per-lun data allocated to this lun. | |
429 | ||
430 | This is an optional function. Your driver is not required to implement it. | |
431 | @param targetLun | |
432 | SCSITargetLun structure containing the SCSI Id of the target/lun that is about to be | |
433 | deallocated. | |
434 | */ | |
435 | bool allocateLun( SCSITargetLun targetLun ); | |
436 | ||
437 | ||
438 | /*! | |
439 | @function getTargetData | |
440 | @abstract | |
441 | Obtains a pointer to per-Target data allocated by IOSCSIController. | |
442 | @discussion | |
443 | This function returns a pointer to per-Target workarea allocated for | |
444 | your driver's use. The size of this area must be specified in the | |
445 | during the configure() function. See struct SCSIControllerInfo, | |
446 | field targetDataSize. | |
447 | @param targetLun | |
448 | SCSITargetLun structure containing the SCSI Id of the target who's | |
449 | workarea you are requesting a pointer to. | |
450 | */ | |
451 | void *getTargetData( SCSITargetLun targetLun ); | |
452 | ||
453 | ||
454 | /*! | |
455 | @function getLunData | |
456 | @abstract | |
457 | Obtains a pointer to per-Lun data allocated by IOSCSIController. | |
458 | @discussion | |
459 | This function returns a pointer to per-Lun workarea allocated for | |
460 | your driver's use. The size of this area must be specified | |
461 | during the configure() function. See struct SCSIControllerInfo, | |
462 | field lunDataSize. | |
463 | */ | |
464 | void *getLunData( SCSITargetLun targetLun ); | |
465 | ||
466 | ||
467 | /*! | |
468 | @function getWorkLoop | |
469 | @abstract | |
470 | Returns the IOWorkLoop object that services your driver. | |
471 | */ | |
472 | IOWorkloop *getWorkLoop(); | |
473 | ||
474 | ||
475 | } |