Root/
Source at commit 1165 created 13 years 11 days ago. By slice, new targets: make image and make pkg, Russian localization | |
---|---|
1 | /*␊ |
2 | * Copyright (c) 1998-2009 Apple Inc. All rights reserved.␊ |
3 | *␊ |
4 | * @APPLE_LICENSE_HEADER_START@␊ |
5 | * ␊ |
6 | * This file contains Original Code and/or Modifications of Original Code␊ |
7 | * as defined in and that are subject to the Apple Public Source License␊ |
8 | * Version 2.0 (the 'License'). You may not use this file except in␊ |
9 | * compliance with the License. Please obtain a copy of the License at␊ |
10 | * http://www.opensource.apple.com/apsl/ and read it before using this␊ |
11 | * file.␊ |
12 | * ␊ |
13 | * The Original Code and all software distributed under the License are␊ |
14 | * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER␊ |
15 | * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,␊ |
16 | * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,␊ |
17 | * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.␊ |
18 | * Please see the License for the specific language governing rights and␊ |
19 | * limitations under the License.␊ |
20 | * ␊ |
21 | * @APPLE_LICENSE_HEADER_END@␊ |
22 | */␊ |
23 | ␊ |
24 | ␊ |
25 | #ifndef _IOKIT_IO_SCSI_PROTOCOL_SERVICES_H_␊ |
26 | #define _IOKIT_IO_SCSI_PROTOCOL_SERVICES_H_␊ |
27 | ␊ |
28 | #if defined(KERNEL) && defined(__cplusplus)␊ |
29 | ␊ |
30 | ␊ |
31 | //-----------------------------------------------------------------------------␊ |
32 | //␉Includes␊ |
33 | //-----------------------------------------------------------------------------␊ |
34 | ␊ |
35 | // Mach includes␊ |
36 | #include <kern/queue.h>␊ |
37 | ␊ |
38 | // General IOKit headers␊ |
39 | #include <IOKit/IOLib.h>␊ |
40 | #include <IOKit/IOCommandGate.h>␊ |
41 | ␊ |
42 | // SCSI Architecture Model Family includes␊ |
43 | #include <IOKit/scsi/SCSITask.h>␊ |
44 | #include <IOKit/scsi/IOSCSIProtocolInterface.h>␊ |
45 | #include <IOKit/scsi/SCSICmds_REQUEST_SENSE_Defs.h>␊ |
46 | ␊ |
47 | ␊ |
48 | //-----------------------------------------------------------------------------␊ |
49 | //␉Constants␊ |
50 | //-----------------------------------------------------------------------------␊ |
51 | ␊ |
52 | // Power Management values␊ |
53 | enum␊ |
54 | {␊ |
55 | ␉kSCSIProtocolLayerPowerStateOff␉␉␉␉= 0,␊ |
56 | ␉kSCSIProtocolLayerPowerStateOn␉␉␉␉= 1,␊ |
57 | ␉kSCSIProtocolLayerNumDefaultStates␉␉␉= 2␊ |
58 | };␊ |
59 | ␊ |
60 | // Forward definitions of internal use only classes␊ |
61 | class SCSITask;␊ |
62 | ␊ |
63 | //-----------------------------------------------------------------------------␊ |
64 | //␉Class Declaration␊ |
65 | //-----------------------------------------------------------------------------␊ |
66 | ␊ |
67 | class IOSCSIProtocolServices : public IOSCSIProtocolInterface␊ |
68 | {␊ |
69 | ␉␊ |
70 | ␉OSDeclareAbstractStructors ( IOSCSIProtocolServices )␊ |
71 | ␉␊ |
72 | private:␊ |
73 | ␉␊ |
74 | ␉// The head pointer for the queue of waiting SCSI Tasks.␊ |
75 | ␉SCSITask *␉␉fSCSITaskQueueHead;␉␉/* OBSOLETE */␊ |
76 | ␉␊ |
77 | ␉// This is the lock for preventing multiple access while␊ |
78 | ␉// manipulating the SCSI Task queue.␊ |
79 | ␉IOSimpleLock *␉fQueueLock;␊ |
80 | ␉␊ |
81 | ␉// The internal flag to indicate whether service requests should be␊ |
82 | ␉// executed or immediately errored, such as when a device is removed.␊ |
83 | ␉bool␉␉␉fAllowServiceRequests;␊ |
84 | ␉␊ |
85 | protected:␊ |
86 | ␉␊ |
87 | ␉// Reserve space for future expansion.␊ |
88 | ␉struct IOSCSIProtocolServicesExpansionData␊ |
89 | ␉{␊ |
90 | ␉␉// For internal use only. Do not use.␊ |
91 | ␉␉UInt32␉␉␉␉fSemaphore;␊ |
92 | ␉␉bool␉␉␉␉fRequiresAutosenseDescriptor;␊ |
93 | ␉␉SCSITaskCompletion␉fCompletionRoutine;␊ |
94 | ␉␉queue_head_t␉␉fTaskQueueHead;␊ |
95 | ␉␉queue_head_t␉␉fAutoSenseQueueHead;␊ |
96 | ␉};␊ |
97 | ␉IOSCSIProtocolServicesExpansionData * fIOSCSIProtocolServicesReserved;␊ |
98 | ␉␊ |
99 | ␉// ---- Protocol transport methods overridden by each subclass ----␊ |
100 | ␉␊ |
101 | ␉// Send a SCSI Command to the device. If the command was sent to the␊ |
102 | ␉// device and is pending completion, the subclass should return true and␊ |
103 | ␉// return back the kSCSIServiceResponse_Request_In_Process response. ␊ |
104 | ␉// If the command completes immediately with an error, the subclass will␊ |
105 | ␉// return true and return back the appropriate status.␊ |
106 | ␉// if the subclass is currently processing all the commands it can, the␊ |
107 | ␉// subclass will return false and the command will be resent next time␊ |
108 | ␉// CommandCompleted is called. ␊ |
109 | ␉virtual bool␉␉SendSCSICommand ( ␉SCSITaskIdentifier ␉␉request, ␊ |
110 | ␉␉␉␉␉␉␉␉␉␉␉SCSIServiceResponse *␉serviceResponse,␊ |
111 | ␉␉␉␉␉␉␉␉␉␉␉SCSITaskStatus *␉␉taskStatus ) = 0;␊ |
112 | ␉␊ |
113 | ␉virtual SCSIServiceResponse␉AbortSCSICommand ( SCSITaskIdentifier request ) = 0;␊ |
114 | ␉␊ |
115 | ␉// ---- Command completion notification method ---------␊ |
116 | ␉// Subclasses will call this inherited method when the command␊ |
117 | ␉// executed by SendSCSICommand has completed.␊ |
118 | ␉// The subclasses will return a service response that is derived␊ |
119 | ␉// from protocol specific status information and as specified in ␊ |
120 | ␉// the specification for that protocol.␊ |
121 | ␉// If the service response is kSCSIServiceResponse_TASK_COMPLETE,␊ |
122 | ␉// the subclass will also return a SCSI status value.␊ |
123 | ␉void␉CommandCompleted ( ␉SCSITaskIdentifier ␉request, ␊ |
124 | ␉␉␉␉␉␉␉␉SCSIServiceResponse serviceResponse,␊ |
125 | ␉␉␉␉␉␉␉␉SCSITaskStatus␉␉taskStatus );␊ |
126 | ␉␊ |
127 | ␉// ---- Utility methods for accessing SCSITask attributes ----␊ |
128 | ␉// Method for retreiving the attribute for a task.␊ |
129 | ␉SCSITaskAttribute␉GetTaskAttribute ( SCSITaskIdentifier request );␊ |
130 | ␉␊ |
131 | ␉bool␉␉␉SetTaskState ( ␉SCSITaskIdentifier request, ␊ |
132 | ␉␉␉␉␉␉␉␉␉SCSITaskState newTaskState );␊ |
133 | ␉SCSITaskState␉GetTaskState ( ␉SCSITaskIdentifier request );␊ |
134 | ␉␊ |
135 | ␉UInt8␉␉␉GetLogicalUnitNumber ( SCSITaskIdentifier request );␊ |
136 | ␉␊ |
137 | ␉// Method to determine the size of the command descriptor block.␊ |
138 | ␉UInt8␉GetCommandDescriptorBlockSize ( SCSITaskIdentifier request );␊ |
139 | ␉␊ |
140 | ␉// This will always return the define max CDB size. If the Protocol Layer␊ |
141 | ␉// driver only supports a smaller size CDB, it will have to create a local␊ |
142 | ␉// SCSICommandDescriptorBlock variable to get the CDB data and then ␊ |
143 | ␉// transfer the needed bytes from there.␊ |
144 | ␉bool␉GetCommandDescriptorBlock ( SCSITaskIdentifier ␉␉␉␉request, ␊ |
145 | ␉␉␉␉␉␉␉␉␉␉SCSICommandDescriptorBlock * ␉cdbData );␊ |
146 | ␉␊ |
147 | ␉// Get the transfer direction for the request.␊ |
148 | ␉UInt8␉GetDataTransferDirection ( SCSITaskIdentifier request );␊ |
149 | ␉␊ |
150 | ␉UInt64␉GetRequestedDataTransferCount ( SCSITaskIdentifier request );␊ |
151 | ␉␊ |
152 | ␉bool␉SetRealizedDataTransferCount ( SCSITaskIdentifier request,␊ |
153 | ␉␉␉␉␉␉␉␉␉␉ UInt64 newRealizedDataCount );␊ |
154 | ␉␊ |
155 | ␉UInt64␉GetRealizedDataTransferCount ( SCSITaskIdentifier request );␊ |
156 | ␉␊ |
157 | ␉IOMemoryDescriptor *␉GetDataBuffer ( SCSITaskIdentifier request );␊ |
158 | ␉␊ |
159 | ␉UInt64␉GetDataBufferOffset ( SCSITaskIdentifier request );␊ |
160 | ␉␊ |
161 | ␉UInt32␉GetTimeoutDuration ( SCSITaskIdentifier request );␊ |
162 | ␉␊ |
163 | ␉UInt64␉GetAutosenseRequestedDataTransferCount ( SCSITaskIdentifier␉request );␊ |
164 | ␉␊ |
165 | ␉// Set the auto sense data that was returned for the SCSI Task.␊ |
166 | ␉// A return value of true indicates that the data was copied to the member ␊ |
167 | ␉// sense data structure, false indicates that the data could not be copied.␊ |
168 | ␉bool␉SetAutoSenseData ( SCSITaskIdentifier␉request,␊ |
169 | ␉␉␉␉␉␉␉ SCSI_Sense_Data *␉senseData ); // DEPRECATED, use the one on the line below.␊ |
170 | ␉␊ |
171 | ␉bool␉SetAutoSenseData ( SCSITaskIdentifier␉request,␊ |
172 | ␉␉␉␉␉␉␉ SCSI_Sense_Data *␉senseData,␊ |
173 | ␉␉␉␉␉␉␉ UInt8␉␉␉␉senseDataSize );␊ |
174 | ␉␊ |
175 | ␉void␉EnsureAutosenseDescriptorExists ( SCSITaskIdentifier request );␊ |
176 | ␉␊ |
177 | ␉bool␉SetProtocolLayerReference ( ␊ |
178 | ␉␉␉␉SCSITaskIdentifier ␉␉request, ␊ |
179 | ␉␉␉␉void *␉␉␉␉␉newReferenceValue );␊ |
180 | ␉void *␉GetProtocolLayerReference ( SCSITaskIdentifier request );␊ |
181 | ␉␊ |
182 | ␉␊ |
183 | ␉bool␉SetTaskExecutionMode (␊ |
184 | ␉␉␉␉SCSITaskIdentifier ␉␉request, ␊ |
185 | ␉␉␉␉SCSITaskMode ␉␉␉newTaskMode );␊ |
186 | ␉SCSITaskMode␉GetTaskExecutionMode ( SCSITaskIdentifier request );␊ |
187 | ␉␊ |
188 | ␉// ---- Method calls for messaging device connectedness ----␊ |
189 | ␉void ␉SendNotification_DeviceRemoved ( void );␊ |
190 | ␉␊ |
191 | ␉void ␉SendNotification_VerifyDeviceState ( void ); ␊ |
192 | ␉␊ |
193 | ␉// -- SCSI Task Queue Management Methods --␊ |
194 | ␉// Following are the commands used to manipulate the queue of pending SCSI Tasks.␊ |
195 | ␉␊ |
196 | ␉// Add the SCSI Task to the queue. The Task's Attribute determines where in␊ |
197 | ␉// the queue the Task is placed.␊ |
198 | ␉void ␉AddSCSITaskToQueue ( SCSITaskIdentifier request );␊ |
199 | ␉␊ |
200 | ␉// Add the SCSI Task to the head of the queue. This is used when the task␊ |
201 | ␉// has been removed from the head of the queue, but the subclass indicates␊ |
202 | ␉// that it can not yet process this task.␊ |
203 | ␉void ␉AddSCSITaskToHeadOfQueue ( SCSITask * request );␊ |
204 | ␉␊ |
205 | ␉// Remove the next SCSI Task for the queue and return it.␊ |
206 | ␉SCSITask * RetrieveNextSCSITaskFromQueue ( void );␊ |
207 | ␉␊ |
208 | ␉// Check to see if the SCSI Task resides in the queue and abort it if it does.␊ |
209 | ␉bool ␉AbortSCSITaskFromQueue ( SCSITask * request );␊ |
210 | ␉␊ |
211 | ␉// Methods for sending and completing SCSI tasks␊ |
212 | ␉void␉SendSCSITasksFromQueue ( void );␊ |
213 | ␉␊ |
214 | ␉void␉RejectSCSITasksCurrentlyQueued ( void );␊ |
215 | ␉␊ |
216 | ␉void␉ProcessCompletedTask ( ␉SCSITaskIdentifier ␉request, ␊ |
217 | ␉␉␉␉␉␉␉␉␉SCSIServiceResponse serviceResponse,␊ |
218 | ␉␉␉␉␉␉␉␉␉SCSITaskStatus␉␉taskStatus );␊ |
219 | ␉void␉RejectTask ( SCSITaskIdentifier␉␉request );␊ |
220 | ␉␊ |
221 | ␉// ------ Power Management Support ------␊ |
222 | ␉␊ |
223 | ␉// The InitializePowerManagement method is called to initialize power management.␊ |
224 | ␉// In the protocol services layer, this method calls the protocol interface layer␊ |
225 | ␉// to initialize power management state variables and then registers the protocol␊ |
226 | ␉// layer driver with the power manager with two(2) states, ON and OFF.␉␊ |
227 | ␉virtual void␉␉InitializePowerManagement ( IOService * provider );␊ |
228 | ␉␊ |
229 | ␉// The GetInitialPowerState method is called once, right after InitializePowerManagement()␊ |
230 | ␉// in order to determine what state the device is initially in at startup time (usually␊ |
231 | ␉// the highest power mode).␊ |
232 | ␉virtual UInt32␉␉GetInitialPowerState ( void );␊ |
233 | ␉␊ |
234 | ␉// The HandlePowerChange method is pure virtual and is left to each protocol or␊ |
235 | ␉// application layer driver to implement. It is guaranteed to be called on its␊ |
236 | ␉// own thread of execution and can make synchronous or asynchronous calls.␊ |
237 | ␉virtual void␉␉HandlePowerChange ( void );␊ |
238 | ␉␊ |
239 | ␉// The HandleCheckPowerState (void) method is on the serialized side of the command␊ |
240 | ␉// gate and can change member variables safely without multi-threading issues.␊ |
241 | ␉// It's main purpose is to call the superclass' HandleCheckPowerState ( UInt32 maxPowerState )␊ |
242 | ␉// with the max power state the class registered with.␊ |
243 | ␉virtual void␉␉HandleCheckPowerState ( void );␊ |
244 | ␉␊ |
245 | ␉// The TicklePowerManager ( void ) method is called by CheckPowerState and␊ |
246 | ␉// sends an activity tickle to the power manager so that the idle timer is␊ |
247 | ␉// reset.␊ |
248 | ␉virtual void␉␉TicklePowerManager ( void );␊ |
249 | ␉␊ |
250 | ␉// The HandlePowerOff method is called to do any bus specific activity␊ |
251 | ␉// necessary before shutting down and going to sleep.␊ |
252 | ␉virtual IOReturn␉HandlePowerOff ( void );␊ |
253 | ␉␊ |
254 | ␉// The HandlePowerOn method is called to do any bus specific activity␊ |
255 | ␉// necessary to recover from power-on/wake from sleep (e.g. bus reset on ATAPI)␊ |
256 | ␉virtual IOReturn␉HandlePowerOn ( void );␊ |
257 | ␉␊ |
258 | public:␊ |
259 | ␉␊ |
260 | ␉virtual bool␉start␉( IOService * provider );␊ |
261 | ␉virtual void␉free␉( void );␊ |
262 | ␉␊ |
263 | ␉void RegisterSCSITaskCompletionRoutine ( SCSITaskCompletion completion );␊ |
264 | ␉␊ |
265 | ␉// ------- SCSI Architecture Model Task Management Functions ------␊ |
266 | ␉// The ExecuteCommand method will take a SCSI Task and transport␊ |
267 | ␉// it across the physical wire(s) to the device␊ |
268 | ␉void␉␉␉␉␉ExecuteCommand ( SCSITaskIdentifier␉request );␊ |
269 | ␉␊ |
270 | ␉// The Task Management function to allow the SCSI Application Layer client to request␊ |
271 | ␉// that a specific task be aborted.␊ |
272 | ␉SCSIServiceResponse␉␉AbortTask ( UInt8 theLogicalUnit, SCSITaggedTaskIdentifier theTag );␊ |
273 | ␊ |
274 | ␉// The Task Management function to allow the SCSI Application Layer client to request␊ |
275 | ␉// that a all tasks curerntly in the task set be aborted.␊ |
276 | ␉SCSIServiceResponse␉␉AbortTaskSet ( UInt8 theLogicalUnit );␊ |
277 | ␊ |
278 | ␉SCSIServiceResponse␉␉ClearACA ( UInt8 theLogicalUnit );␊ |
279 | ␊ |
280 | ␉SCSIServiceResponse␉␉ClearTaskSet ( UInt8 theLogicalUnit );␊ |
281 | ␊ |
282 | ␉SCSIServiceResponse␉␉LogicalUnitReset ( UInt8 theLogicalUnit );␊ |
283 | ␊ |
284 | ␉SCSIServiceResponse␉␉TargetReset ( void );␊ |
285 | ␉␊ |
286 | // ************* Obsoleted Member Routine ****************␊ |
287 | // The AbortCommand method is replaced by the AbortTask Management function and␊ |
288 | // should no longer be called.␊ |
289 | ␉virtual SCSIServiceResponse␉␉AbortCommand ( SCSITaskIdentifier␉request );␊ |
290 | ␊ |
291 | ␉␊ |
292 | ␉// ---- Method used for determining protocol or physical interconnect characteristics. ----␊ |
293 | ␉// The IsProtocolServiceSupported will return true if the specified␊ |
294 | ␉// feature is supported by the protocol layer. If the service has a value that must be␊ |
295 | ␉// returned, it will be returned in the serviceValue output parameter.␊ |
296 | ␉virtual bool␉IsProtocolServiceSupported ( SCSIProtocolFeature feature, void * serviceValue ) = 0;␊ |
297 | ␊ |
298 | ␉// The HandleProtocolServiceFeature instructs the Protocol Services driver to perform the necessary ␊ |
299 | ␉// tasks for the indicated feature.␊ |
300 | ␉virtual bool␉HandleProtocolServiceFeature ( SCSIProtocolFeature feature, void * serviceValue ) = 0;␊ |
301 | ␊ |
302 | protected:␊ |
303 | ␉␊ |
304 | ␉// ----- Protocol Services Driver request handlers for Task Management functions -----␊ |
305 | ␉// These should be abstract so that every Protocol Services Driver would have to␊ |
306 | ␉// override them, but since they are new member routines, this class will provide␊ |
307 | ␉// a default implementation.␊ |
308 | OSMetaClassDeclareReservedUsed ( IOSCSIProtocolServices, 1 );␊ |
309 | ␉virtual SCSIServiceResponse␉␉HandleAbortTask ( ␊ |
310 | ␉␉␉␉␉␉␉␉␉␉␉UInt8 ␉␉␉␉␉␉theLogicalUnit, ␊ |
311 | ␉␉␉␉␉␉␉␉␉␉␉SCSITaggedTaskIdentifier ␉theTag );␊ |
312 | ␊ |
313 | OSMetaClassDeclareReservedUsed ( IOSCSIProtocolServices, 2 );␊ |
314 | ␉virtual SCSIServiceResponse␉␉HandleAbortTaskSet ( ␊ |
315 | ␉␉␉␉␉␉␉␉␉␉␉UInt8 ␉␉␉␉␉␉theLogicalUnit );␊ |
316 | ␉␊ |
317 | OSMetaClassDeclareReservedUsed ( IOSCSIProtocolServices, 3 );␊ |
318 | ␉virtual SCSIServiceResponse␉␉HandleClearACA ( ␊ |
319 | ␉␉␉␉␉␉␉␉␉␉␉UInt8 ␉␉␉␉␉␉theLogicalUnit );␊ |
320 | ␉␊ |
321 | OSMetaClassDeclareReservedUsed ( IOSCSIProtocolServices, 4 );␊ |
322 | ␉virtual SCSIServiceResponse␉␉HandleClearTaskSet (␊ |
323 | ␉␉␉␉␉␉␉␉␉␉␉UInt8 ␉␉␉␉␉␉theLogicalUnit );␊ |
324 | ␉␊ |
325 | OSMetaClassDeclareReservedUsed ( IOSCSIProtocolServices, 5 );␊ |
326 | ␉virtual SCSIServiceResponse␉␉HandleLogicalUnitReset (␊ |
327 | ␉␉␉␉␉␉␉␉␉␉␉UInt8 ␉␉␉␉␉␉theLogicalUnit );␊ |
328 | ␉␉␉␉␉␉␉␉␉␉␉␊ |
329 | OSMetaClassDeclareReservedUsed ( IOSCSIProtocolServices, 6 );␊ |
330 | // The HandleTargetReset member routine requests that the Protocol Services Driver␊ |
331 | // perform the necessary steps detailed in the specification that defines the ␊ |
332 | // protocol the driver represents for the TargetReset management function.␊ |
333 | ␉virtual SCSIServiceResponse␉␉HandleTargetReset ( void );␊ |
334 | ␊ |
335 | ␊ |
336 | OSMetaClassDeclareReservedUsed ( IOSCSIProtocolServices, 7 );␊ |
337 | // The CreateSCSITargetDevice member routine will create the appropriate object␊ |
338 | // to represent the Target portion of a SCSI Device. This object is responsible␊ |
339 | // for managing the Target functions of the SCSI Device including the Task Manager and␊ |
340 | // Logical Units.␊ |
341 | // If the SCSITargetDevice object was successfully created, a true value will be␊ |
342 | // returned, otherwisw, this will return false.␊ |
343 | ␉virtual bool␉␉␉␉␉CreateSCSITargetDevice ( void );␊ |
344 | ␉␊ |
345 | private:␊ |
346 | ␉␊ |
347 | ␉// Space reserved for future expansion.␊ |
348 | OSMetaClassDeclareReservedUnused ( IOSCSIProtocolServices, 8 );␊ |
349 | OSMetaClassDeclareReservedUnused ( IOSCSIProtocolServices, ␉9 );␊ |
350 | OSMetaClassDeclareReservedUnused ( IOSCSIProtocolServices, 10 );␊ |
351 | OSMetaClassDeclareReservedUnused ( IOSCSIProtocolServices, 11 );␊ |
352 | OSMetaClassDeclareReservedUnused ( IOSCSIProtocolServices, 12 );␊ |
353 | OSMetaClassDeclareReservedUnused ( IOSCSIProtocolServices, 13 );␊ |
354 | OSMetaClassDeclareReservedUnused ( IOSCSIProtocolServices, 14 );␊ |
355 | OSMetaClassDeclareReservedUnused ( IOSCSIProtocolServices, 15 );␊ |
356 | OSMetaClassDeclareReservedUnused ( IOSCSIProtocolServices, 16 );␊ |
357 | ␊ |
358 | };␊ |
359 | ␊ |
360 | #endif␉/* defined(KERNEL) && defined(__cplusplus) */␊ |
361 | ␊ |
362 | #endif␉/* _IOKIT_IO_SCSI_PROTOCOL_SERVICES_H_ */␊ |
363 |