1/*
2 * Copyright (c) 2002-2008 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#ifndef __IOKIT_IO_SCSI_PARALLEL_INTERFACE_CONTROLLER_H__
25#define __IOKIT_IO_SCSI_PARALLEL_INTERFACE_CONTROLLER_H__
26
27
28 /*!
29  @header IOSCSIParallelInterfaceController
30	The IOSCSIParallelInterfaceController class and the associated HBA child
31	class is responsible for the management of all related hardware. This
32	includes the onboard HBA controller chip and the physical state of the
33	bus. These classes are not responsible for any of the management of
34	the SCSI Devices on the bus with the exception of maintaining the queue that
35	holds the objects representing those SCSI Devices.
36*/
37
38
39//-----------------------------------------------------------------------------
40//	Includes
41//-----------------------------------------------------------------------------
42
43// General IOKit includes
44#include <IOKit/IOService.h>
45#include <IOKit/IOWorkLoop.h>
46#include <IOKit/IOCommandGate.h>
47#include <IOKit/IODMACommand.h>
48#include <IOKit/IOInterruptEventSource.h>
49#include <IOKit/IOFilterInterruptEventSource.h>
50#include <IOKit/IOTimerEventSource.h>
51#include <IOKit/IOCommandPool.h>
52
53// IOKit SCSI ArchitectureModel Family includes
54#include <IOKit/scsi/SCSITask.h>
55#include <IOKit/scsi/SCSICmds_REQUEST_SENSE_Defs.h>
56#include <IOKit/scsi/SCSIPort.h>
57
58//-----------------------------------------------------------------------------
59//	Constants
60//-----------------------------------------------------------------------------
61
62
63#define kIOPropertySCSIDeviceFeaturesKey			"SCSI Device Features"
64#define kIOPropertySCSI_I_T_NexusFeaturesKey		"SCSI I_T Nexus Features"
65
66// Set this key with a value of true in ReportHBAConstraints() to indicate support
67// for full 8-byte LUN addressing and use GetLogicalUnitBytes() to obtain the
68// full 8-byte LUN when processing commands in ProcessParallelTask().
69#define kIOHierarchicalLogicalUnitSupportKey		"SCSI Hierarchical Logical Unit Support"
70
71// This is the alignment mask used when allocating per-task HBA data. It allows
72// the HBA to declare whether or not it supports 64-bit addressability and what the
73// minimum byte alignment is for the data. E.g. By specifying 0x0000FFFFFFFFFFFEULL,
74// the controller would be indicating that it supports 48-bits of addressability, but
75// at a minimum of being 2-byte aligned.
76#define kIOMinimumHBADataAlignmentMaskKey			"HBA Data Alignment"
77
78// The Feature Selectors used to identify features of the SCSI Parallel
79// Interface.  These are used by the DoesHBASupportSCSIParallelFeature
80// to report whether the HBA supports a given SCSI Parallel Interface
81// feature and are used for requesting negotiation and reporting negotiation
82// results between the controller and the device.
83
84// When the DoesHBASupportSCSIParallelFeature() member routine of the controller
85// child class is called, it will return true if the HBA that it controls
86// supports the specified SCSIParallelFeature or false if it does not.
87typedef enum SCSIParallelFeature
88{
89	// The selector for support of Wide Data Transfers.  Only Wide16 is supported
90	// as Wide32 has been obsoleted by the SPI-3 specification.
91	kSCSIParallelFeature_WideDataTransfer 					= 0,
92
93	// The selector for support of Synchronous Data Transfers.
94	kSCSIParallelFeature_SynchronousDataTransfer 			= 1,
95
96	// The selector for support of Quick Arbitration and Selection (QAS).
97	kSCSIParallelFeature_QuickArbitrationAndSelection 		= 2,
98
99	// The selector for support of Double Transition (DT) data transfers.
100	kSCSIParallelFeature_DoubleTransitionDataTransfers 		= 3,
101
102	// The selector for SPI Information Unit (IU) transfers.
103	kSCSIParallelFeature_InformationUnitTransfers 			= 4,
104
105	// Since the Feature selectors are zero base, this will always have the
106	// correct total.
107	kSCSIParallelFeature_TotalFeatureCount
108} SCSIParallelFeature;
109
110
111typedef enum SCSIParallelFeatureRequest
112{
113	// This selector indicates that current negotiation
114	// should be used.
115	kSCSIParallelFeature_NoNegotiation 			= 0,
116
117	// This selector indicates that the controller
118	// should attempt negotiation for the feature
119	kSCSIParallelFeature_AttemptNegotiation 	= 1,
120
121	// This selector indicates that the controller
122	// should clear any negotiation for the feature
123	kSCSIParallelFeature_ClearNegotiation 		= 2
124} SCSIParallelFeatureRequest;
125
126typedef enum SCSIParallelFeatureResult
127{
128	kSCSIParallelFeature_NegotitiationUnchanged	= 0,
129	kSCSIParallelFeature_NegotitiationCleared	= 1,
130	kSCSIParallelFeature_NegotitiationSuccess	= 2
131} SCSIParallelFeatureResult;
132
133
134// The SCSI Message Codes used for MESSAGE IN and MESSAGE OUT phases.
135enum SCSIParallelMessages
136{
137	// Link Control Messages
138	kSCSIParallelMessage_TASK_COMPLETE						= 0x00,
139	kSCSIParallelMessage_EXTENDED_MESSAGE					= 0x01,
140	kSCSIParallelMessage_SAVE_DATA_POINTER	 				= 0x02,
141	kSCSIParallelMessage_RESTORE_POINTERS					= 0x03,
142	kSCSIParallelMessage_DISCONNECT							= 0x04,
143	kSCSIParallelMessage_INITIATOR_DETECTED_ERROR 			= 0x05,
144	kSCSIParallelMessage_MESSAGE_REJECT		 				= 0x07,
145	kSCSIParallelMessage_NO_OPERATION		 				= 0x08,
146	kSCSIParallelMessage_MESSAGE_PARITY_ERROR 				= 0x09,
147	kSCSIParallelMessage_IGNORE_WIDE_RESIDUE				= 0x23,
148	kSCSIParallelMessage_QAS_REQUEST		 				= 0x55,
149	kSCSIParallelMessage_IDENTIFY							= 0x80,
150
151	// The Message Codes used in the EXTENDED_MESSAGE message.
152	kSCSIParallelMessage_MODIFY_DATA_POINTER				= 0x00,
153	kSCSIParallelMessage_SYNCHONOUS_DATA_TRANSFER_REQUEST	= 0x01,
154	// Reserved												= 0x02
155	kSCSIParallelMessage_WIDE_DATA_TRANSFER_REQUEST			= 0x03,
156	kSCSIParallelMessage_PARALLEL_PROTOCOL_REQUEST			= 0x04,
157	// Reserved												= 0x05 through 0xFF
158
159	// Task Attribute Message Codes
160	kSCSIParallelMessage_ACA								= 0x24,
161	kSCSIParallelMessage_HEAD_OF_QUEUE						= 0x21,
162	kSCSIParallelMessage_LINKED_COMMAND_COMPLETE			= 0x0A,
163	kSCSIParallelMessage_ORDERED							= 0x22,
164	kSCSIParallelMessage_SIMPLE								= 0x20,
165
166	// Task Management Message Codes
167	kSCSIParallelMessage_ABORT_TASK							= 0x0D,
168	kSCSIParallelMessage_ABORT_TASK_SET						= 0x06,
169	kSCSIParallelMessage_CLEAR_ACA							= 0x16,
170	kSCSIParallelMessage_CLEAR_TASK_SET						= 0x0E,
171	kSCSIParallelMessage_LOGICAL_UNIT_RESET					= 0x17,
172	kSCSIParallelMessage_TARGET_RESET						= 0x0C
173};
174
175enum
176{
177	kSCSIParallelTaskControllerIDQueueHead 		= 0
178};
179
180// Notifications
181enum
182{
183	kSCSIControllerNotificationBusReset			= 0x68000000
184};
185
186// Forward declaration for the internally used Parallel Device object.
187class IOSCSIParallelInterfaceDevice;
188
189// This is the identifier that is used to specify a given parallel Task.
190typedef OSObject *	SCSIParallelTaskIdentifier;
191
192
193//-----------------------------------------------------------------------------
194//	Class Declarations
195//-----------------------------------------------------------------------------
196
197/*! @class IOSCSIParallelInterfaceController
198	@abstract Class that represents a SCSI Host Bus Adapter.
199	@discussion Class that represents a SCSI Host Bus Adapter.
200*/
201class IOSCSIParallelInterfaceController : public IOService
202{
203
204	OSDeclareAbstractStructors ( IOSCSIParallelInterfaceController )
205
206#if 0
207#pragma mark -
208#pragma mark Client API
209#endif
210
211
212public:
213
214	/*!
215		@function GetSCSIParallelTask
216		@abstract Method to allow the client to get a SCSIParallelTask
217		@discussion Get a SCSIParallelTask from the controller so that a request
218		can be issued to the HBA driver.
219		@param blockForCommand If the blockForCommand parameter is set to false
220		and there are no free SCSIParallelTasks, this method will return NULL,
221		otherwise it will wait for one to become available before returning.
222		@result If there is a SCSI Parallel Task available, a reference to it
223		will be returned.
224	*/
225
226	SCSIParallelTaskIdentifier	GetSCSIParallelTask ( bool blockForCommand );
227
228	/*!
229		@function FreeSCSIParallelTask
230		@abstract Method to allow the client to release a SCSIParallelTask
231		@discussion	The FreeSCSIParallelTask method is called by the client when
232		a SCSIParallelTask has been completed and the associated returnTask
233		needs to be returned to the pool.
234		@param returnTask is a reference to the SCSIParallelTaskIdentifier to be
235		returned.
236	*/
237
238	void FreeSCSIParallelTask ( SCSIParallelTaskIdentifier returnTask );
239
240	/*!
241		@function FindTaskForAddress
242		@abstract Find a task for a given Task Address, if one exists.
243		@discussion If a valid Tagged Task Identifier is specified, this method
244		will return the task specified by the Tagged Task Address if one is
245		found, or else NULL will be returned.  If zero is used as the Tagged
246		Task Identifier, then this routine will search for an outstanding task
247		based on the Untagged Task Address and return the task or else, if one
248		is not found, return NULL.
249		@param theT is the Target component of the I_T_L or I_T_L_Q nexus.
250		@param theL is the Logical Unit component of the I_T_L or I_T_L_Q nexus.
251		@param theQ is the Queue Tag component of the I_T_L_Q nexus.  If this is
252		an I_T_L nexus, then the kSCSIUntaggedTaskIdentifier constant should be
253		used for theQ.
254		@result returns a valid SCSIParallelTaskIdentifier or NULL if none
255		found.
256	*/
257
258	SCSIParallelTaskIdentifier	FindTaskForAddress (
259							SCSIDeviceIdentifier 		theT,
260							SCSILogicalUnitNumber		theL,
261							SCSITaggedTaskIdentifier	theQ );
262
263
264	/*!
265		@function FindTaskForControllerIdentifier
266		@abstract Find a task for a given Target and Controller Task Identifier
267		@discussion Allows the controller child class to find an outstanding task
268		for a specified target and controller task identifier
269		@param theTarget is the Target that the task .
270		@param theIdentifier is the controller task identifier set using the SCSI
271		Parallel Task's SetControllerTaskIdentifier() method.
272		@result returns a valid SCSIParallelTaskIdentifier or NULL if none
273		found.
274	*/
275
276	SCSIParallelTaskIdentifier	FindTaskForControllerIdentifier (
277							SCSIDeviceIdentifier 		theTarget,
278							UInt64						theIdentifier );
279
280
281	/*!
282		@function ExecuteParallelTask
283		@abstract Submit a SCSIParallelTask for execution.
284		@discussion	The ExecuteParallelTask call is made by the client to submit
285		a SCSIParallelTask for execution.
286		@param parallelRequest is a reference to the SCSIParallelTaskIdentifier
287		to be executed.
288		@result is an appropriate SCSIServiceResponse which are defined in the
289		file <IOKit/scsi/SCSITask.h>.
290	*/
291
292	SCSIServiceResponse ExecuteParallelTask (
293							SCSIParallelTaskIdentifier	parallelRequest );
294
295	// --- Public API methods provided by HBA child classes ----
296
297	/*!
298		@function ReportHBAHighestLogicalUnitNumber
299		@abstract Gets the Highest Logical Unit Number.
300		@discussion	This method is used to query the HBA child class to
301		determine what the highest Logical Unit Number that the controller can
302		address.
303		@result returns a valid 64-bit logical unit number.
304	*/
305
306	virtual SCSILogicalUnitNumber	ReportHBAHighestLogicalUnitNumber ( void ) = 0;
307
308	/*!
309		@function DoesHBASupportSCSIParallelFeature
310		@abstract Queries the HBA child class to determine if it supports a
311		specific SPI feature.
312		@discussion	Queries the HBA child class to determine if it supports the
313		specified feature as defined by the SCSI Parallel Interconnect
314		specifications.
315		@result Returns true if requested feature is supported.
316	*/
317
318	virtual bool	DoesHBASupportSCSIParallelFeature (
319							SCSIParallelFeature 		theFeature ) = 0;
320
321	/*!
322		@function InitializeTargetForID
323		@abstract Called to initialize a target device.
324		@discussion	This method will be called to initialize a target device in
325		a single-threaded manner.  The HBA can use this method to probe the
326		target or do anything else necessary before the device object is
327		registered with IOKit for matching.
328		@result Returns true if the target was successfully initialized.
329	*/
330
331	virtual bool	InitializeTargetForID (
332							SCSITargetIdentifier 		targetID ) = 0;
333
334	// The SCSI Task Management Functions as defined in the SCSI Architecture
335	// Model - 2 (SAM-2) specification.  These are used by the client to request
336	// the specified function.  The controller can complete these immmediately
337	// by returning the appropriate SCSIServiceResponse, or these can be completed
338	// asyncronously by the controller returning a SCSIServiceResponse of
339	// kSCSIServiceResponse_Request_In_Process and then calling the appropriate
340	// function complete member routine listed in the child class API section.
341
342	virtual SCSIServiceResponse	AbortTaskRequest (
343							SCSITargetIdentifier 		theT,
344							SCSILogicalUnitNumber		theL,
345							SCSITaggedTaskIdentifier	theQ ) = 0;
346
347	virtual	SCSIServiceResponse AbortTaskSetRequest (
348							SCSITargetIdentifier 		theT,
349							SCSILogicalUnitNumber		theL ) = 0;
350
351	virtual	SCSIServiceResponse ClearACARequest (
352							SCSITargetIdentifier 		theT,
353							SCSILogicalUnitNumber		theL ) = 0;
354
355	virtual	SCSIServiceResponse ClearTaskSetRequest (
356							SCSITargetIdentifier 		theT,
357							SCSILogicalUnitNumber		theL ) = 0;
358
359	virtual	SCSIServiceResponse LogicalUnitResetRequest (
360							SCSITargetIdentifier 		theT,
361							SCSILogicalUnitNumber		theL ) = 0;
362
363	virtual	SCSIServiceResponse TargetResetRequest (
364							SCSITargetIdentifier 		theT ) = 0;
365
366
367
368	/*!
369		@function DoesHBAPerformAutoSense
370		@abstract Queries the HBA child class to determine if it automatically
371		performs AutoSense and provides AutoSense data for each I/O. If the HBA
372		allocates space for AutoSense in its HBA specific data region on a per
373		task basis, the HBA should respond true.
374		@discussion	Queries the HBA child class to determine if it automatically
375		performs AutoSense and provides AutoSense data for each I/O. If the HBA
376		allocates space for AutoSense in its HBA specific data region on a per
377		task basis, the HBA should respond true.
378		@result Return true if HBA performs AutoSense into its own private data
379		buffer.
380	*/
381
382	OSMetaClassDeclareReservedUsed ( IOSCSIParallelInterfaceController, 1 );
383
384	virtual bool	DoesHBAPerformAutoSense ( void );
385
386	/*!
387		@function ReportHBAConstraints
388		@abstract Called to report the I/O constraints for this controller.
389		A list of valid keys includes:
390			kIOMaximumSegmentCountReadKey, (required)
391			kIOMaximumSegmentCountWriteKey, (required)
392			kIOMaximumSegmentByteCountReadKey, (required)
393			kIOMaximumSegmentByteCountWriteKey, (required)
394			kIOMinimumSegmentAlignmentByteCountKey, (required)
395			kIOMaximumSegmentAddressableBitCountKey, (required)
396			kIOMinimumHBADataAlignmentMaskKey (required)
397			kIOHierarchicalLogicalUnitSupportKey (optional).
398		NB: These keys and their values are described in this header and <IOKit/IOKitKeys.h>
399		@param constraints. An OSDictionary object used to aggregate the key/value pairs.
400		Subclasses must set the required keys if they override this method. If a subclass does
401		not provide the required keys, the system will panic.
402	*/
403	OSMetaClassDeclareReservedUsed ( IOSCSIParallelInterfaceController, 2 );
404
405	virtual void	ReportHBAConstraints ( OSDictionary * constraints );
406
407	/*!
408		@function DoesHBASupportMultiPathing
409		@abstract Queries the HBA child class to determine if it supports
410		Multi-Pathing.
411		@discussion	Queries the HBA child class to determine if it supports
412		Multi-Pathing.
413		@result Returns true if requested feature is supported.
414	*/
415	OSMetaClassDeclareReservedUsed ( IOSCSIParallelInterfaceController, 3 );
416
417	virtual bool	DoesHBASupportMultiPathing ( void );
418
419
420	// Padding for the Client API
421	OSMetaClassDeclareReservedUnused ( IOSCSIParallelInterfaceController, 4 );
422	OSMetaClassDeclareReservedUnused ( IOSCSIParallelInterfaceController, 5 );
423	OSMetaClassDeclareReservedUnused ( IOSCSIParallelInterfaceController, 6 );
424	OSMetaClassDeclareReservedUnused ( IOSCSIParallelInterfaceController, 7 );
425	OSMetaClassDeclareReservedUnused ( IOSCSIParallelInterfaceController, 8 );
426
427
428#if 0
429#pragma mark -
430#pragma mark Child Class API
431#endif
432
433
434protected:
435
436	// ---- Target Creation and Destruction methods ---
437
438	/*!
439		@function CreateTargetForID
440		@abstract Method to perform device creation.
441		@discussion	For HBA child classes that report true to the
442		DoesHBAPerformDeviceManagement() method, the child class will be
443		responsible for all device management by using these methods;
444		otherwise, the superclass will be responsible for all device management.
445		This method must be used to perform SCSI Parallel Device creation and
446		cannot be overridden.
447		@param  targetID SCSIDeviceIdentifier of desired targetID.
448		@result returns true if successful.
449	*/
450
451	bool	CreateTargetForID ( SCSIDeviceIdentifier targetID );
452
453	 /*!
454		@function CreateTargetForID
455		@abstract Method to perform device creation.
456		@discussion	For HBA child classes that report true to the
457		DoesHBAPerformDeviceManagement() method, the child class will be
458		responsible for all device management by using these methods;
459		otherwise, the superclass will be responsible for all device management.
460		This method must be used to perform SCSI Parallel Device creation and
461		cannot be overridden.
462		@param  targetID SCSIDeviceIdentifier of desired targetID.
463		@param	properties A dictionary of properties to associate with the device
464				upon creation. The list of valid property keys is as follows:
465				kIOPropertySASAddressKey,
466				kIOPropertyFibreChannelNodeWorldWideNameKey,
467				kIOPropertyFibreChannelPortWorldWideNameKey,
468				kIOPropertyFibreChannelAddressIdentifierKey,
469				kIOPropertyFibreChannelALPAKey, and
470				kIOPropertyRetryCountKey
471				These keys are defined in
472				<IOKit/storage/IOStorageProtocolCharacteristics.h> and the values
473				associated with these keys must be of the proper type/size,
474				or the target creation will not succeed.
475		@result returns true if successful.
476	*/
477
478	bool	CreateTargetForID ( SCSIDeviceIdentifier 	targetID,
479								OSDictionary * 			properties );
480
481	 /*!
482		@function DestroyTargetForID
483		@abstract Method to perform device destruction.
484		@discussion	For HBA child classes that report true to the
485		DoesHBAPerformDeviceManagement() method, the child class will be
486		responsible for all device management by using these methods; otherwise,
487		the superclass will be responsible for all device management.
488		This method must be used to perform SCSI Parallel Device destruction and
489		cannot be overridden.
490		@param  targetID SCSIDeviceIdentifier of desired targetID.
491	*/
492
493	void	DestroyTargetForID ( SCSIDeviceIdentifier targetID );
494
495	/*!
496		@function GetTargetForID
497		@abstract Accessor for getting pointer to IOSCSIParallelInterfaceDevice.
498		@param targetID SCSIDeviceIdentifier of desired targetID.
499		@result returns pointer to IOSCSIParallelInterfaceDevice or NULL if not
500		found.
501	*/
502
503	IOSCSIParallelInterfaceDevice *	GetTargetForID (
504							SCSIDeviceIdentifier 		targetID );
505
506	/*!
507		@function SetTargetProperty
508		@abstract Accessor for setting a property for a specific target.
509		@param device A pointer to a valid IOSCSIParallelInterfaceDevice.
510		@param key A pointer to a valid OSString object which represents the key.
511		A list of valid keys includes:
512			kIOPropertySASAddressKey,
513			kIOPropertyFibreChannelNodeWorldWideNameKey,
514			kIOPropertyFibreChannelPortWorldWideNameKey,
515			kIOPropertyFibreChannelAddressIdentifierKey, and
516			kIOPropertyFibreChannelALPAKey.
517		NB: These keys and their values are described in <IOKit/storage/IOStorageProtocolCharacteristics.h>
518		@param value Pointer to an OSObject (one of type OSData, OSString, etc.)
519		which represents the value for the property. The value must be of the proper type
520		and size for the specified key.
521		@result returns true if identifier was properly set, otherwise false.
522	*/
523
524	bool	SetTargetProperty ( SCSIDeviceIdentifier 		targetID,
525								const char *		 		key,
526								OSObject *					value );
527
528	/*!
529		@function RemoveTargetProperty
530		@abstract Accessor for removing a property from a specific target.
531		@param device A pointer to a valid IOSCSIParallelInterfaceDevice.
532		@param key A pointer to a valid OSString object which represents the key.
533	*/
534
535	void	RemoveTargetProperty ( SCSIDeviceIdentifier 		targetID,
536								   const char *		 			key );
537
538	// ---- Methods for HBA specifics. ----
539
540	/*!
541		@function SetHBAProperty
542		@abstract Accessor for setting a property for this object.
543		@param key A pointer to a valid OSString object which represents the key.
544		A list of valid keys includes:
545			kIOPropertyVendorNameKey,
546			kIOPropertyProductNameKey,
547			kIOPropertyProductRevisionLevelKey,
548			kIOPropertyPortDescriptionKey,
549			kIOPropertyPortSpeedKey,
550			kIOPropertyPortTopologyKey,
551			kIOPropertySCSIParallelSignalingTypeKey,
552			kIOPropertyFibreChannelCableDescriptionKey,
553			kIOPropertyFibreChannelNodeWorldWideNameKey,
554			kIOPropertyFibreChannelPortWorldWideNameKey,
555			kIOPropertyFibreChannelAddressIdentifierKey,
556			kIOPropertyFibreChannelALPAKey, and
557			kIOPropertySASAddressKey.
558		NB: These keys and their values are described in <IOKit/storage/IOStorageDeviceCharacteristics.h>
559		and <IOKit/storage/IOStorageProtocolCharacteristics.h>
560		@param value Pointer to an OSObject (one of type OSData, OSString, etc.)
561		which represents the value for the property. The value must be of the proper type,
562		and/or size for the specified key.
563		@result returns true if identifier was properly set, otherwise false.
564	*/
565
566	bool	SetHBAProperty ( const char *	key,
567							 OSObject *	 	value );
568
569	/*!
570		@function RemoveHBAProperty
571		@abstract Accessor for removing a property for this object.
572		@param key A pointer to a valid OSString object which represents the key.
573		See the SetHBAProperty() method for a list of valid keys.
574	*/
575
576	void	RemoveHBAProperty ( const char * key );
577
578	// These methods will not be called before the InitializeController() call,
579	// and will not be called after the TerminateController() call.  But in the
580	// interval between those calls, they shall report the correct requested
581	// information. They are implemented as seperate pure virtual methods
582	// instead of a selector driven method because the HBA child class is
583	// required to report this information.
584
585	/*!
586		@function ReportInitiatorIdentifier
587		@abstract Get the SCSI Device Identifier for the HBA.
588		@discussion This method will be called to determine the SCSI Device
589		Identifier that the Initiator has assigned for this HBA.
590		@result returns SCSIInitiatorIdentifier.
591	*/
592
593	virtual SCSIInitiatorIdentifier	ReportInitiatorIdentifier ( void ) = 0;
594
595	/*!
596		@function ReportHighestSupportedDeviceID
597		@abstract Get the highest supported SCSI Device Identifier.
598		@discussion This method will be called to determine the value of the
599		highest SCSI Device Identifier supported by the HBA. This value will be
600		used to determine the last ID to process.
601		@result returns highest SCSIDeviceIdentifier
602	*/
603
604	virtual SCSIDeviceIdentifier	ReportHighestSupportedDeviceID ( void ) = 0;
605
606	/*!
607		@function ReportMaximumTaskCount
608		@abstract Report Maximum Task Count
609		@discussion This method will be called to retrieve the maximum number of
610		outstanding tasks the HBA can process. This number must be greater than
611		zero or the controller driver will fail to match and load.
612		@result returns maximum (non-zero) task count.
613	*/
614
615	virtual UInt32		ReportMaximumTaskCount ( void ) = 0;
616
617  	/*!
618		@function ReportHBASpecificTaskDataSize
619		@abstract Determine memory needed for HBA Task specific use.
620		@discussion This method is used to retrieve the amount of memory that
621		will be allocated in the SCSI Parallel Task for HBA specific use.
622		@result returns memory required in bytes
623	*/
624
625	virtual UInt32		ReportHBASpecificTaskDataSize ( void ) = 0;
626
627  	/*!
628		@function ReportHBASpecificDeviceDataSize
629		@abstract  Determine memory needed for HBA Device specific use.
630		@discussion This method is used to retrieve the amount of memory that
631		will be allocated in the SCSI Parallel Device for HBA specific use.
632		@result  returns memory required in bytes
633	*/
634
635	virtual UInt32		ReportHBASpecificDeviceDataSize ( void ) = 0;
636
637  	/*!
638		@function DoesHBAPerformDeviceManagement
639		@abstract  Determine if HBA will manage devices.
640		@discussion This method is used to determine if the HBA will manage
641		target device creation and destruction.
642		@result return true means objects for target devices will only be
643		created when the child class calls the CreateTargetForID method.
644	*/
645
646	virtual bool		DoesHBAPerformDeviceManagement ( void ) = 0;
647
648	// ---- Initialize and Terminate methods for the subclass to implement -----
649	// The subclass shall not override the IOKit init and terminate methods,
650	// but shall instead rely on these methods for initialization and
651	// termination.
652
653	// This is done to allow for this superclass to manage all IOKit specifics
654	// and to require only a Family specific API to be implemented by the
655	// subclass drivers.
656
657  	/*!
658		@function InitializeController
659		@abstract  Called to initialize the controller
660		@discussion It is guaranteed that the InitializeController() will only be
661		called once per instantiation.  The InitializeController() methods allows
662		the subclass driver to do all the necessary initialization required by
663		the hardware before it is able to accept requests to execute. All
664		necessary allocation of resources should be made during this method
665		call. This is the first method that will be called in the subclass.
666		@result return true means that initialization was successful.
667	*/
668
669	virtual bool	InitializeController ( void ) = 0;
670
671  	/*!
672		@function TerminateController
673		@abstract  Called to terminate the controller
674		@discussion It is guaranteed that the TerminateController() will only be
675		called once and only after the InitializeController() method and only if
676		true was returned in response to the InitializeController() method.
677		The TerminateController() method allows the subclass to release all
678		resources that were acquired for operation of the hardware and shutdown
679		all hardware services.
680		This is the last method of the subclass that will be called before the
681		class is destroyed.
682	*/
683
684	virtual void	TerminateController ( void ) = 0;
685
686	// ---- Start and Stop methods for the subclass ----
687
688	/*!
689		@function StartController
690		@abstract Called to start the controller
691		@discussion The StartController will always be called before any
692		requests are sent to the driver for execution. This method is called
693		after an initialize to start the services provided by the specific HBA
694		driver or called after a StopController call to restart those services.
695		After this call completes, all services provided by the HBA driver are
696		available to the client.
697		@result return true means that start was successful.
698	*/
699
700	virtual bool	StartController ( void ) = 0;
701
702	/*!
703		@function StopController
704		@abstract Called to stop the controller
705		@discussion The StopController method will be called any time that the
706		system wants the card to stop accepting requests. ( See StartController
707		discussion ). The subclass should disable the hardware interrupt for
708		the particular controller (if possible) in this method.
709	*/
710
711	virtual void	StopController ( void ) = 0;
712
713	// ---- Suspend and Resume Methods for the subclass ----
714
715	/*!
716		@function SuspendServices
717		@abstract Called to suspend controller services
718		@discussion Method will be called when the system wants to suspend the
719		services that are provided by the HBA driver. This call is not a reset
720		and the driver shall retain all state data between this so that if a
721		ResumeServices call is received, the driver can continue providing
722		services without a visible difference to the client. The driver may
723		receive multiple SuspendServices calls without receiving a
724		ResumeServices call and should ignore any after the first until a
725		ResumeServices call is received.
726	*/
727
728	virtual void	SuspendServices ( void );
729
730	/*!
731		@function ResumeServices
732		@abstract Called to resume controller services
733		@discussion Method that will be called to resume services
734		provided by the driver. ( See SuspendServices discussion )
735	*/
736
737	virtual void	ResumeServices ( void );
738
739	/*!
740		@function HandleInterruptRequest
741		@abstract Handle Interrupt Request
742		@discussion The HandleInterruptRequest is used to notify an HBA
743		specific subclass that an interrupt request needs to be serviced. It is
744		called on the workloop (it holds the gate) at secondary interrupt level.
745	*/
746
747	virtual void	HandleInterruptRequest ( void ) = 0;
748
749	/*!
750		@function EnableInterrupt
751		@abstract Enable Interrupt
752		@discussion Method that the HBA child class can call to enable
753		the associated IOInterruptEventSource.
754	*/
755
756	void	EnableInterrupt ( void );
757
758	/*!
759		@function DisableInterrupt
760		@abstract Disable Interrupt
761		@discussion Method that the HBA child class can call to disable
762		the associated IOInterruptEventSource.
763	*/
764
765	void	DisableInterrupt ( void );
766
767	/*!
768		@function SignalInterrupt
769		@abstract Signals that an interrupt has occurred.
770		@discussion Subclasses of IOSCSIParallelInterfaceController
771		should call this method in order to get the secondary interrupt
772		thread scheduled if and only if they will be returning false from
773		their overriden FilterInterruptRequest() method. See the
774		discussion for the FilterInterruptRequest() method for more
775		details.
776
777		NOTE: This method should only be called from within the
778		FilterInterruptRequest() method and at no other time.
779
780		Available in 10.3.3 or later.
781
782	*/
783
784	void	SignalInterrupt ( void );
785
786	/*!
787		@function ProcessParallelTask
788		@abstract Called by client to process a parallel task.
789		@discussion This method is called to process a parallel task (i.e. put
790		the command on the bus). The HBA specific sublcass must implement this
791		method.
792		@param parallelRequest A valid SCSIParallelTaskIdentifier.
793		@result serviceResponse (see <IOKit/scsi/SCSITask.h>)
794	*/
795
796	virtual SCSIServiceResponse ProcessParallelTask (
797							SCSIParallelTaskIdentifier parallelRequest ) = 0;
798
799	/*!
800		@function CompleteParallelTask
801		@abstract Parallel Task Completion
802		@discussion The HBA specific sublcass inherits the CompleteParallelTask()
803		method which shall be called when the HBA has completed the processing
804		of a parallel task.
805		@param parallelTask A valid SCSIParallelTaskIdentifier.
806		@param completionStatus The status of the SCSI bus.
807		@param serviceResponse (see <IOKit/scsi/SCSITask.h>)
808	*/
809
810	void	CompleteParallelTask (
811						SCSIParallelTaskIdentifier	parallelRequest,
812						SCSITaskStatus 				completionStatus,
813						SCSIServiceResponse 		serviceResponse );
814
815
816	// Completion routines for the SCSI Task Management functions as described
817	// in the SCSI ArchitectureModel - 2 (SAM-2) specification.  Each of these
818	// correspond to a client request for the specific Task Management functions.
819	// If the Controller Child Class completed the request by returning a
820	// SCSIServiceResponse of anything other than kSCSIServiceResponse_Request_In_Process,
821	// then the controller class does not need to call the completion member routine.
822	// If the controller did not complete the request immediately, then it will
823	// need to call the appropriate completion member routine listed here.
824	void	CompleteAbortTask (
825						SCSITargetIdentifier 		theT,
826						SCSILogicalUnitNumber		theL,
827						SCSITaggedTaskIdentifier	theQ,
828						SCSIServiceResponse 		serviceResponse );
829
830	void 	CompleteAbortTaskSet (
831						SCSITargetIdentifier 		theT,
832						SCSILogicalUnitNumber		theL,
833						SCSIServiceResponse 		serviceResponse );
834
835	void 	CompleteClearACA (
836						SCSITargetIdentifier 		theT,
837						SCSILogicalUnitNumber		theL,
838						SCSIServiceResponse 		serviceResponse );
839
840	void 	CompleteClearTaskSet (
841						SCSITargetIdentifier 		theT,
842						SCSILogicalUnitNumber		theL,
843						SCSIServiceResponse 		serviceResponse );
844
845	void 	CompleteLogicalUnitReset (
846						SCSITargetIdentifier 		theT,
847						SCSILogicalUnitNumber		theL,
848						SCSIServiceResponse 		serviceResponse );
849
850	void 	CompleteTargetReset (
851						SCSITargetIdentifier 		theT,
852						SCSIServiceResponse 		serviceResponse );
853
854	/*!
855		@function NotifyClientsOfBusReset
856		@abstract Method called to notify clients that a bus reset has occurred.
857		@discussion This method is used by the HBA child class to inform the
858		parent class and any clients that a bus reset has occurred.
859	*/
860
861	void	NotifyClientsOfBusReset ( void );
862
863	/*!
864		@function NotifyClientsOfPortStatusChange
865		@abstract Method called to notify clients of port status change events.
866		@discussion This method is used by the HBA child class to inform the
867		parent class and any clients that a port has changed status.
868	*/
869
870	void	NotifyClientsOfPortStatusChange ( SCSIPortStatus newStatus );
871
872	/*!
873		@function GetSCSIDomainIdentifier
874		@abstract Accessor method to get the SCSI Domain Identifier.
875		@discussion Accessor method to get the SCSI Domain Identifier.
876		@result returns SCSI Domain Identifier.
877	*/
878
879	SInt32	GetSCSIDomainIdentifier ( void );
880
881	/*!
882		@function GetProvider
883		@abstract Accessor method to get the IOService which is the controller's
884		provider.
885		@discussion Accessor method to get the IOService which is the
886		controller's provider.
887		@result returns pointer to IOService.
888	*/
889
890	IOService *		GetProvider ( void );
891
892	/*!
893		@function GetWorkLoop
894		@abstract Accessor method to get the IOWorkLoop associated with this
895		HBA.
896		@discussion Accessor method to get the IOWorkLoop associated with this
897		HBA.
898		@result returns pointer to IOWorkLoop.
899	*/
900
901	IOWorkLoop *	GetWorkLoop ( void ) const;
902
903	/*!
904		@function GetCommandGate
905		@abstract Accessor to get an IOCommandGate associated with the workloop.
906		@discussion Accessor to get an IOCommandGate associated with the
907		workloop.
908		@result returns pointer to IOCommandGate.
909	*/
910
911	IOCommandGate *		GetCommandGate ( void );
912
913	// ---- SCSI Parallel Task Object Accessors ----
914
915	/*!
916		@function GetSCSITaskIdentifier
917		@abstract Method to retrieve a SCSITaskIdentifier from a valid
918		SCSIParallelTaskIdentifier.
919		@discussion Method to retrieve a SCSITaskIdentifier from a valid
920		SCSIParallelTaskIdentifier.
921		@param parallelTask A valid SCSIParallelTaskIdentifier.
922		@result returns SCSITaskIdentifier that represents the original request
923		from the SCSI Application Layer client.
924	*/
925
926	SCSITaskIdentifier	GetSCSITaskIdentifier (
927							SCSIParallelTaskIdentifier 	parallelTask );
928
929	/*!
930		@function GetTargetIdentifier
931		@abstract Method to get the SCSITargetIdentifier associated with a
932		request.
933		@discussion	Method to get the SCSITargetIdentifier associated with a
934		request.
935		@param parallelTask A valid SCSIParallelTaskIdentifier.
936		@result returns SCSITargetIdentifier
937	*/
938
939	SCSITargetIdentifier	GetTargetIdentifier (
940							SCSIParallelTaskIdentifier 	parallelTask );
941
942	// ---- Methods for Accessing data in the client's SCSI Task Object ----
943	// Method to retrieve the LUN that identifies the Logical Unit whose Task
944	// Set to which this task is to be added.
945
946	/*!
947		@function GetLogicalUnitNumber
948		@abstract Method to get the logical unit number associated with a
949		request.
950		@discussion Method to get the logical unit number associated with a
951		request.
952		@param parallelTask A valid SCSIParallelTaskIdentifier.
953		@result returns a valid 64-bit logical unit number.
954	*/
955
956	SCSILogicalUnitNumber	GetLogicalUnitNumber (
957							SCSIParallelTaskIdentifier 	parallelTask ); // DEPRECATED, use GetLogicalUnitBytes instead.
958
959	/*!
960		@function GetLogicalUnitBytes
961		@abstract Method to get the logical unit bytes associated with a
962		request.
963		@discussion Method to get the logical unit bytes associated with a
964		request.
965		@param parallelTask A valid SCSIParallelTaskIdentifier.
966		@result returns a valid 8-byte logical unit address.
967	*/
968
969    void    GetLogicalUnitBytes (
970                            SCSIParallelTaskIdentifier  parallelTask,
971                            SCSILogicalUnitBytes *      logicalUnitBytes );
972
973	/*!
974		@function GetTaggedTaskIdentifier
975		@abstract Method to retrieve the SCSI Tagged Task Identifier of the
976		task.  If the returned value is equal to kSCSIUntaggedTaskIdentifier,
977		then this task is untagged.
978		@param parallelTask A valid SCSIParallelTaskIdentifier.
979		@result an SCSITaskAttribute value.
980	*/
981
982	SCSITaggedTaskIdentifier GetTaggedTaskIdentifier (
983							SCSIParallelTaskIdentifier	parallelTask );
984
985	/*!
986		@function GetTaskAttribute
987		@abstract Method to retrieve the SCSI Task Attribute of the task
988		@param parallelTask A valid SCSIParallelTaskIdentifier.
989		@result an SCSITaskAttribute value.
990	*/
991
992	SCSITaskAttribute		GetTaskAttribute (
993							SCSIParallelTaskIdentifier	parallelTask );
994
995	/*!
996		@function GetCommandDescriptorBlockSize
997		@abstract Method to retrieve the size of the SCSI Command Descriptor
998		Block (CDB).
999		@param parallelTask A valid SCSIParallelTaskIdentifier.
1000		@result returns the size of the SCSI Command Descriptor Block in bytes.
1001	*/
1002
1003	UInt8	GetCommandDescriptorBlockSize (
1004							SCSIParallelTaskIdentifier 	parallelTask );
1005
1006	/*!
1007		@function GetCommandDescriptorBlock
1008		@abstract Method to retrieve the SCSI Command Descriptor Block (CDB).
1009		@discussion This will always return a 16 Byte CDB. If the Protocol Layer
1010		driver does not support 16 Byte CDBs, it will have to create a local
1011		SCSICommandDescriptorBlock variable to get the CDB data and then
1012		transfer the needed bytes from there.
1013		@param parallelTask A valid SCSIParallelTaskIdentifier.
1014		@param cdbData is a SCSICommandDescriptorBlock pointer to 16 byte CDB
1015		@result returns true if data was copied to cdbData pointer
1016	*/
1017
1018	bool	GetCommandDescriptorBlock (
1019							SCSIParallelTaskIdentifier 		parallelTask,
1020							SCSICommandDescriptorBlock * 	cdbData );
1021
1022	/*!
1023		@function GetDataTransferDirection
1024		@abstract Retrieves the data transfer direction for any data associated
1025		with the request.
1026		@param parallelTask A valid SCSIParallelTaskIdentifier.
1027		@result One of the valid data transfer directions described in
1028		<IOKit/scsi/SCSITask.h>
1029	*/
1030
1031	UInt8	GetDataTransferDirection ( SCSIParallelTaskIdentifier parallelTask );
1032
1033	/*!
1034		@function GetRequestedDataTransferCount
1035		@abstract Retrieves the requested data transfer count for any data
1036		associated with the request.
1037		@param parallelTask A valid SCSIParallelTaskIdentifier.
1038		@result The requested data transfer count in bytes.
1039	*/
1040
1041	UInt64	GetRequestedDataTransferCount (
1042							SCSIParallelTaskIdentifier 	parallelTask );
1043
1044	/*!
1045		@function GetRealizedDataTransferCount
1046		@abstract Retrieves the realized data transfer count for any data
1047		associated with the request.
1048		@param parallelTask A valid SCSIParallelTaskIdentifier.
1049		@result The realized data transfer count in bytes.
1050	*/
1051
1052	UInt64	GetRealizedDataTransferCount (
1053							SCSIParallelTaskIdentifier 	parallelTask );
1054
1055	/*!
1056		@function SetRealizedDataTransferCount
1057		@abstract Sets the realized data transfer count in bytes.
1058		@param parallelTask A valid SCSIParallelTaskIdentifier.
1059		@param realizedTransferCountInBytes is the number of bytes actually
1060		transferred.
1061		@result true means the data transfer count was successfully set.
1062	*/
1063
1064	bool	SetRealizedDataTransferCount (
1065							SCSIParallelTaskIdentifier 	parallelTask,
1066							UInt64 		realizedTransferCountInBytes );
1067
1068	/*!
1069		@function IncrementRealizedDataTransferCount
1070		@abstract Increments the realized data transfer count. This method is
1071		helpful for when the HBA has to do multiple passes of DMA because there
1072		are more scatter-gather elements than it can process in one pass.
1073		@param parallelTask A valid SCSIParallelTaskIdentifier.
1074		@param realizedTransferCountInBytes is the number of bytes to add to the
1075		realized data count for the task.
1076	*/
1077
1078	void	IncrementRealizedDataTransferCount (
1079							SCSIParallelTaskIdentifier 	parallelTask,
1080							UInt64 		realizedTransferCountInBytes );
1081
1082	/*!
1083		@function GetDataBuffer
1084		@abstract Method to retrieve client buffer from the request.
1085		@param parallelTask A valid SCSIParallelTaskIdentifier.
1086		@result returns pointer to an IOMemoryDescriptor which represents the
1087		buffer.
1088	*/
1089
1090	IOMemoryDescriptor * GetDataBuffer (
1091							SCSIParallelTaskIdentifier 	parallelTask );
1092
1093	/*!
1094		@function GetDataBufferOffset
1095		@abstract Method to retrieve offset into client buffer at which to start
1096		processing.
1097		@param parallelTask A valid SCSIParallelTaskIdentifier.
1098		@result returns offset in bytes
1099	*/
1100
1101	UInt64	GetDataBufferOffset ( SCSIParallelTaskIdentifier parallelTask );
1102
1103	/*!
1104		@function GetDMACommand
1105		@abstract Method to retrieve a pointer to an IODMACommand from the request.
1106		@discussion For devices utilizing DMA, the IODMACommand object should be
1107		obtained via GetDMACommand(). The subclass is responsible for calling prepare()
1108		on the IODMACommand object using the proper offset obtained via GetDataBufferOffset()
1109		and correct size obtained via GetRequestedDataTransferCount(). The subclass
1110		is further responsible for calling complete() on the IODMACommand object once
1111		all DMA operations have finished.
1112		NB: Subclasses should not call IODMACommand::setMemoryDescriptor().
1113		@param parallelTask A valid SCSIParallelTaskIdentifier.
1114		@result returns pointer to an IODMACommand which is used in conjunction
1115		with the task.
1116	*/
1117
1118	IODMACommand * GetDMACommand (
1119							SCSIParallelTaskIdentifier 	parallelTask );
1120
1121	/*!
1122		@function GetTimeoutDuration
1123		@abstract Method to retrieve the timeout duration in milliseconds for a
1124		request.
1125		@discussion Method to retrieve the timeout duration in milliseconds for
1126		a request. A value of zero represents an infinite timeout, or on
1127		hardware where infinite timeouts are not possible, substitute the
1128		longest timeout possible.
1129		@param parallelTask A valid SCSIParallelTaskIdentifier.
1130		@result returns timeout duration in milliseconds
1131	*/
1132
1133	UInt32	GetTimeoutDuration ( SCSIParallelTaskIdentifier parallelTask );
1134
1135	/*!
1136		@function SetAutoSenseData
1137		@abstract Method to set the auto sense data buffer associated with a
1138		request.
1139		@param parallelTask A valid SCSIParallelTaskIdentifier.
1140		@param newSensedata pointer to auto sense data buffer
1141		@result returns true if data in newSenseData was succesfully into the
1142		task object
1143	*/
1144
1145	bool	SetAutoSenseData (
1146							SCSIParallelTaskIdentifier 	parallelTask,
1147							SCSI_Sense_Data * 			newSenseData,
1148							UInt8						senseDataSize );
1149
1150	/*!
1151		@function GetAutoSenseData
1152		@abstract Method to retrieve auto sense data buffer associated with a
1153		request.
1154		@param parallelTask A valid SCSIParallelTaskIdentifier.
1155		@param receivingBuffer pointer to auto sense data buffer
1156		@result returns true if successfully copied data into receivingBuffer
1157	*/
1158
1159 	bool	GetAutoSenseData (
1160 							SCSIParallelTaskIdentifier 	parallelTask,
1161 							SCSI_Sense_Data * 			receivingBuffer,
1162 							UInt8						senseDataSize );
1163
1164	/*!
1165		@function GetAutoSenseDataSize
1166		@abstract Method to retrieve auto sense data buffer size associated with a
1167		request.
1168		@param parallelTask A valid SCSIParallelTaskIdentifier.
1169		@result returns Size of auto sense data buffer.
1170	*/
1171
1172 	UInt8	GetAutoSenseDataSize (
1173 							SCSIParallelTaskIdentifier 	parallelTask );
1174
1175
1176	/*!
1177		@function GetSCSIParallelFeatureNegotiation
1178		@abstract Method to retrieve the requested value for negotiation of the.
1179		@discussion Query as to whether the SCSI Parallel Device object has
1180		negotiated wide data transfers.
1181		@param parallelTask A valid SCSIParallelTaskIdentifier.
1182		@result A valid SCSIParallelFeatureControl.
1183	*/
1184
1185	SCSIParallelFeatureRequest		GetSCSIParallelFeatureNegotiation (
1186							SCSIParallelTaskIdentifier 	parallelTask,
1187							SCSIParallelFeature 		requestedFeature );
1188
1189	/*!
1190		@function GetSCSIParallelFeatureNegotiationCount
1191		@abstract Method to retrieve the number of requested negotiations.
1192		@discussion Query as to the number of SCSI Parallel Features that are
1193		requested to either be negotitated or cleared.  These are all features
1194		that are set to either kSCSIParallelFeature_AttemptNegotiation or
1195		kSCSIParallelFeature_ClearNegotiation.  If the return value is zero,
1196		then all features are set to kSCSIParallelFeature_NoNegotiation
1197		and all feature negotiations are to remain as they currently exist.
1198		@param parallelTask A valid SCSIParallelTaskIdentifier.
1199		@result an unsigned integer up to 64 bits in size.
1200	*/
1201
1202	UInt64		GetSCSIParallelFeatureNegotiationCount (
1203							SCSIParallelTaskIdentifier 	parallelTask);
1204
1205	/*!
1206		@function SetSCSIParallelFeatureNegotiationResult
1207		@abstract Method to set the wide data transfer negotiation result.
1208		@discussion Method to set the wide data transfer negotiation result.
1209		@param parallelTask A valid SCSIParallelTaskIdentifier.
1210		@param requestedFeature The SCSIParallelFeature that the has been set to
1211		newResult.
1212		@param newResult A valid SCSIParallelFeatureResult value.
1213	*/
1214
1215	void		SetSCSIParallelFeatureNegotiationResult (
1216							SCSIParallelTaskIdentifier 	parallelTask,
1217							SCSIParallelFeature 		requestedFeature,
1218							SCSIParallelFeatureResult 	newResult );
1219
1220	/*!
1221		@function GetSCSIParallelFeatureNegotiationResult
1222		@abstract Method to retrieve the result of any wide transfer
1223		negotiations.
1224		@discussion Query as to whether the SCSI Parallel Controller object has
1225		negotiated wide data transfers.
1226		@param parallelTask A valid SCSIParallelTaskIdentifier.
1227		@result A valid SCSIParallelFeatureResult.
1228	*/
1229
1230	SCSIParallelFeatureResult		GetSCSIParallelFeatureNegotiationResult (
1231							SCSIParallelTaskIdentifier 	parallelTask,
1232							SCSIParallelFeature 		requestedFeature );
1233
1234	/*!
1235		@function GetSCSIParallelFeatureNegotiationResultCount
1236		@abstract Method to retrieve the number of changed negotiations.
1237		@discussion Query as to the number of SCSI Parallel Features that have
1238		been changed to either negotitated or cleared.  These are all features
1239		that are set to either kSCSIParallelFeature_NegotitiationCleared or
1240		kSCSIParallelFeature_NegotitiationSuccess.  If the return value is zero,
1241		then all features are set to kSCSIParallelFeature_NegotitiationUnchanged.
1242		@param parallelTask A valid SCSIParallelTaskIdentifier.
1243		@result an unsigned integer up to 64 bits in size.
1244	*/
1245
1246	UInt64		GetSCSIParallelFeatureNegotiationResultCount (
1247							SCSIParallelTaskIdentifier 	parallelTask);
1248
1249	// Controller Task Identifier related member routines
1250
1251	/*!
1252		@function SetControllerTaskIdentifier
1253		@abstract Method to set the Controller Task Identifier.
1254		@discussion This method allows the Controller Child Class
1255		driver to set a unique identifier to associate with the specified
1256		SCSI Parallel Task.  This identifier is designed to be used by
1257		controllers that do not have access to the LUN and Tag information
1258		when notified by the HBA that a request has completed.
1259		If the kSCSIParallelTaskControllerIDQueueHead is used, this
1260		member routine will return the first Task on the queue.
1261		@param parallelTask A valid SCSIParallelTaskIdentifier.
1262		@param newIdentifier unsigned 64 bit integer token.
1263		@result none
1264	*/
1265
1266	void	SetControllerTaskIdentifier (
1267							SCSIParallelTaskIdentifier 	parallelTask,
1268							UInt64 						newIdentifier );
1269
1270	UInt64	GetControllerTaskIdentifier (
1271							SCSIParallelTaskIdentifier 	parallelTask);
1272
1273
1274	// The HBA Data related fields
1275
1276	/*!
1277		@function GetHBADataSize
1278		@abstract Method to retrieve the HBA Data Size in bytes.
1279		@discussion Method to retrieve the HBA Data Size in bytes.
1280		@param parallelTask A valid SCSIParallelTaskIdentifier.
1281		@result returns HBA Data size in bytes.
1282	*/
1283
1284	UInt32	GetHBADataSize ( SCSIParallelTaskIdentifier 	parallelTask );
1285
1286	/*!
1287		@function GetHBADataPointer
1288		@abstract Method to retrieve the HBA Data pointer.
1289		@discussion Method to retrieve the HBA Data pointer.
1290		@param parallelTask A valid SCSIParallelTaskIdentifier.
1291		@result returns pointer to buffer for HBA specific data, NULL if
1292		none found or GetHBADataSize() returns zero.
1293	*/
1294
1295	void *	GetHBADataPointer ( SCSIParallelTaskIdentifier 	parallelTask );
1296
1297	/*!
1298		@function GetHBADataDescriptor
1299		@abstract Method to retrieve the IOMemoryDescriptor associated with
1300		the HBA Data.
1301		@discussion Method to retrieve the IOMemoryDescriptor associated with
1302		the HBA Data.
1303		@param parallelTask A valid SCSIParallelTaskIdentifier.
1304		@result returns pointer to an IOMemoryDescriptor that wraps the HBA
1305		specific data buffer, NULL if none found or GetHBADataSize() returns zero.
1306	*/
1307
1308	IOMemoryDescriptor *	GetHBADataDescriptor (
1309							SCSIParallelTaskIdentifier 	parallelTask );
1310
1311	// ---- SCSI Parallel Device Object Accessors ----
1312
1313	// The HBA Data related fields
1314
1315	/*!
1316		@function GetHBATargetDataSize
1317		@abstract Method to retrieve the HBA Data Size in bytes.
1318		@discussion Method to retrieve the HBA Data Size in bytes.
1319		@param targetDevice A valid SCSITargetIdentifier.
1320		@result returns HBA Data size in bytes.
1321	*/
1322
1323	UInt32	GetHBATargetDataSize ( SCSITargetIdentifier 	targetID );
1324
1325	/*!
1326		@function GetHBATargetDataPointer
1327		@abstract Method to retrieve the HBA Data pointer.
1328		@discussion Method to retrieve the HBA Data pointer.
1329		@param targetDevice A valid SCSITargetIdentifier.
1330		@result returns pointer to buffer for HBA specific data, NULL if
1331		none found or GetHBADataSize is zero.
1332	*/
1333
1334	void *	GetHBATargetDataPointer ( SCSITargetIdentifier 	targetID );
1335
1336
1337#if 0
1338#pragma mark -
1339#pragma mark Additional Child Class APIs
1340#endif
1341
1342
1343	// ---- Timeout Related Methods ----
1344
1345	/*!
1346		@function SetTimeoutForTask
1347		@abstract Method to set the timeout duration in milliseconds for a
1348		request.
1349		@discussion Method to set the timeout duration in milliseconds for a
1350		request.
1351		@param parallelTask A valid SCSIParallelTaskIdentifier.
1352		@param timeoutOverride A timeout value in milliseconds in case the
1353		HBA driver wishes to override the default value provided in the
1354		parallelTask.
1355	*/
1356
1357	void	SetTimeoutForTask ( SCSIParallelTaskIdentifier 	parallelTask,
1358								UInt32						timeoutOverride = 0 );
1359
1360	/*!
1361		@function HandleTimeout
1362		@abstract Method to handle command timeouts.
1363		@discussion Method to handle command timeouts. This should
1364		be overridden by the child class in order to clean up HBA
1365		specific structures after a timeout has occurred. This method
1366		is called on the workloop (it holds the gate).
1367		@param parallelRequest A valid SCSIParallelTaskIdentifier.
1368	*/
1369
1370	OSMetaClassDeclareReservedUsed ( IOSCSIParallelInterfaceController, 9 );
1371
1372	virtual void		HandleTimeout (
1373							SCSIParallelTaskIdentifier parallelRequest );
1374
1375
1376	// ---- Filter Interrupt ----
1377
1378	/*!
1379		@function FilterInterruptRequest
1380		@abstract Filter method called at primary interrupt time.
1381		@discussion Filter method called at primary interrupt time.
1382		This should only be overridden by the child class in order
1383		to determine if an interrupt occurred for this controller instance.
1384		Since all work occurs at primary interrupt time, this routine
1385		should be quick and efficient and defer as much processing as
1386		possible to the HandleInterruptRequest() method.
1387
1388		NOTE: Unlike the HandleInterruptRequest() and HandleTimeout()
1389		methods, FilterInterruptRequest() is NOT called with the
1390		workloop lock held.
1391
1392		If the value returned by FilterInterruptRequest() is true, the
1393		secondary interrupt thread will be scheduled and the hardware
1394		interrupt line will be disabled. If the controller instance shares
1395		that interrupt line with other devices, it can cause large
1396		interrupt latencies. If the controller instance can disable the
1397		interrupt in the chip itself, the following can be done to reduce
1398		interrupt latencies:
1399
1400		- Interrupt occurs
1401		- FilterInterruptRequest() method is called.
1402			- If the interrupt is not for this controller, return false
1403			  immediately.
1404			- If the interrupt is for this controller, and the controller
1405			  can disable interrupts for this chip, the controller should
1406			  disable the interrupts for this chip, call SignalInterrupt(),
1407			  and return false. This causes the secondary interrupt thread
1408			  to get scheduled, yet does not disable the interrupt line for
1409			  all devices tied to that interrupt. This effectively allows
1410			  other devices to process their interrrupts, thus reducing
1411			  interrupt latency for those devices.
1412		- HandleInterruptRequest() method is called.
1413			- Controller processes interrupt and completes I/O requests.
1414			- Controller re-enables interrupts for the device.
1415
1416		NOTE: If you use this approach, the interrupting condition MUST be
1417		cleared from the hardware, otherwise an infinite process interrupt
1418		loop will occur.
1419
1420		If the controller cannot disable interrupts on the chip, it should
1421		simply return true if an interrupt has occurred for its device.
1422
1423		@result True if the hardware interrupt line should be disabled,
1424		otherwise false.
1425	*/
1426
1427	OSMetaClassDeclareReservedUsed ( IOSCSIParallelInterfaceController, 10 );
1428
1429	virtual bool		FilterInterruptRequest ( void );
1430
1431	/*!
1432		@function InitializeDMASpecification
1433		@abstract Called to initialize an IODMACommand with a DMA specification.
1434		@param command A pointer to a valid IODMACommand object. Subclasses
1435		should override this method and call IODMACommand::initWithSpecification()
1436		supplying the proper arguments to that method based on the DMA strategy.
1437		@result boolean value indicating success or failure.
1438	*/
1439	OSMetaClassDeclareReservedUsed ( IOSCSIParallelInterfaceController, 11 );
1440
1441	virtual bool	InitializeDMASpecification ( IODMACommand * command );
1442
1443	/*!
1444		@function CreateDeviceInterrupt
1445		@abstract Called to create an IOInterruptEventSource for the device. Subclasses
1446		may wish to use a different interrupt index than 0 (e.g. for using PCI Message
1447		Signaled Interrupts) or might not need an interrupt at all (virtual HBA).
1448		@param action A pointer to the action routine that should be passed to either
1449		IOInterruptEventSource::interruptEventSource() or
1450		IOFilterInterruptEventSource::filterInterruptEventSource as the method to call
1451		when an interrupt occurs for the device (sometimes called the "deferred procedure call"
1452		or the "secondary context method". By passing this routine along, it will
1453		properly wire up the HandleInterruptRequest() method you should override to handle
1454		interrupts.
1455		@param filter A pointer to the filter routine that should be passed to
1456		IOFilterInterruptEventSource::filterInterruptEventSource as the method to call
1457		at primary interrupt time when an interrupt occurs for the device.
1458		By passing this routine along, it will properly wire up the
1459		FilterInterruptRequest() method you may override to handle primary interrupts.
1460		@result IOInterruptEventSource. May return NULL if and only if there is no
1461		hardware interrupt associated with this device.
1462	*/
1463	OSMetaClassDeclareReservedUsed ( IOSCSIParallelInterfaceController, 12 );
1464
1465	virtual IOInterruptEventSource *	CreateDeviceInterrupt (
1466											IOInterruptEventSource::Action			action,
1467											IOFilterInterruptEventSource::Filter	filter,
1468											IOService *								provider );
1469
1470	// Padding for the Child Class API
1471	OSMetaClassDeclareReservedUnused ( IOSCSIParallelInterfaceController, 13 );
1472	OSMetaClassDeclareReservedUnused ( IOSCSIParallelInterfaceController, 14 );
1473	OSMetaClassDeclareReservedUnused ( IOSCSIParallelInterfaceController, 15 );
1474	OSMetaClassDeclareReservedUnused ( IOSCSIParallelInterfaceController, 16 );
1475
1476
1477#if 0
1478#pragma mark -
1479#pragma mark Internal Use Only
1480#endif
1481
1482private:
1483
1484	// binary compatibility instance variable expansion
1485	struct ExpansionData { };
1486	ExpansionData * fIOSCSIParallelInterfaceControllerExpansionData;
1487
1488	IOService *					fProvider;
1489	OSSet *						fClients;
1490
1491	static SInt32				fSCSIParallelDomainCount;
1492	SInt32						fSCSIDomainIdentifier;
1493
1494	// The HBA attributes
1495	SCSIInitiatorIdentifier		fInitiatorIdentifier;
1496
1497	// The maximum SCSI Device Identifier support by the HBA
1498	// This is retreived from the child class via the
1499	SCSIDeviceIdentifier		fHighestSupportedDeviceID;
1500
1501	// The total number of tasks that the HBA can proccess at a time.
1502	// This is retrieved from the child class via ReportMaximumTaskCount
1503	UInt32						fSupportedTaskCount;
1504
1505	// The Number of requests that are currently outstanding for the current
1506	// instantiation.
1507	UInt16						fOutstandingRequests;
1508
1509	// The member variable to indicate if the current instantiation has been
1510	// succesfully intialized.
1511	bool						fHBAHasBeenInitialized;
1512
1513	// The member variable to indicate if the current instantiation is running.
1514	// A true means that the last or only Start call made was successful.  A
1515	// false value means that either a successful Start has not been made or a
1516	// Stop call has been made.
1517	bool						fHBACanAcceptClientRequests;
1518
1519	// The pool for the available SCSI Parallel Task objects
1520	IOCommandPool *				fParallelTaskPool;
1521
1522	// WorkLoop variables
1523	IOWorkLoop *				fWorkLoop;
1524	IOTimerEventSource *		fTimerEvent;
1525	IOInterruptEventSource *	fDispatchEvent;
1526
1527	IOCommandGate *				fControllerGate;
1528
1529	bool						AllocateSCSIParallelTasks ( void );
1530	void						DeallocateSCSIParallelTasks ( void );
1531
1532	IOWorkLoop *				getWorkLoop ( void ) const;
1533	bool 						CreateWorkLoop ( IOService * provider );
1534	void 						ReleaseWorkLoop ( void );
1535
1536	// SCSI Parallel Device List
1537	// The SCSI Parallel Device List will consist of 16 elements to represent
1538	// identifiers that end in 0h through Fh.  Each array element will point
1539	// to a device object that represents the beginning of a linked list of
1540	// device objects.  By using an array of linked lists, the traversal time
1541	// to find an object on a bus that supports a large number of devices, such
1542	// as Fibre Channel, will be significantly lower than having to walk a list
1543	// that is comprised of all devices on the bus.  For parallel wide and
1544	// narrow busses, which support 16 and 8 devices respectively, this will act
1545	// like a simple array of device objects.
1546	enum
1547	{
1548		kSCSIParallelDeviceListArrayCount 	= 16,
1549		kSCSIParallelDeviceListIndexMask	= 0x0F
1550	};
1551
1552	IOSimpleLock * 					fDeviceLock;
1553	IOSCSIParallelInterfaceDevice *
1554					fParallelDeviceList[kSCSIParallelDeviceListArrayCount];
1555
1556	void			InitializeDeviceList ( void );
1557	void			AddDeviceToTargetList (
1558							IOSCSIParallelInterfaceDevice *	newDevice );
1559	void			RemoveDeviceFromTargetList (
1560							IOSCSIParallelInterfaceDevice * victimDevice );
1561
1562	// The Interrupt Service Routine for the controller.
1563	static void		ServiceInterrupt (
1564							OSObject *					theObject,
1565							IOInterruptEventSource *	theSource,
1566							int							count );
1567
1568	static void		TimeoutOccurred ( OSObject * owner, IOTimerEventSource * sender );
1569
1570	static bool		FilterInterrupt (
1571							OSObject *						theObject,
1572							IOFilterInterruptEventSource *	theSource );
1573
1574	// IOService support methods
1575	// These shall not be overridden by the HBA child classes.
1576	bool			start ( IOService * 				provider );
1577	void			stop ( 	IOService *  				provider );
1578
1579
1580protected:
1581
1582	// These may be overriden by the HBA child classes if necessary, but should
1583	// call the superclass implementation.
1584	virtual bool	handleOpen (
1585							IOService * 				client,
1586							IOOptionBits 				options,
1587							void * 						arg );
1588
1589	virtual void	handleClose (
1590							IOService * 				client,
1591							IOOptionBits 				options );
1592
1593	virtual bool	handleIsOpen (
1594							const IOService * 			client ) const;
1595
1596	virtual bool	willTerminate ( IOService * provider, IOOptionBits options );
1597	virtual bool	didTerminate ( IOService * provider, IOOptionBits options, bool * defer );
1598    virtual void	free ( void );
1599
1600
1601};
1602
1603
1604#endif	/* __IOKIT_IO_SCSI_PARALLEL_INTERFACE_CONTROLLER_H__ */