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