1/* 2 * Copyright (c) 2000-2006 Apple Computer, Inc. All rights reserved. 3 * 4 * @APPLE_LICENSE_HEADER_START@ 5 * 6 * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. 7 * 8 * This file contains Original Code and/or Modifications of Original Code 9 * as defined in and that are subject to the Apple Public Source License 10 * Version 2.0 (the 'License'). You may not use this file except in 11 * compliance with the License. Please obtain a copy of the License at 12 * http://www.opensource.apple.com/apsl/ and read it before using this 13 * file. 14 * 15 * The Original Code and all software distributed under the License are 16 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 17 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 18 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 19 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 20 * Please see the License for the specific language governing rights and 21 * limitations under the License. 22 * 23 * @APPLE_LICENSE_HEADER_END@ 24 */ 25 26/*! 27 @header IOATAPIProtocolTransport 28 Contains the class definition for IOATAPIProtocolTransport. 29*/ 30 31 32#ifndef _IOKIT_IO_ATAPI_PROTOCOL_TRANSPORT_H_ 33#define _IOKIT_IO_ATAPI_PROTOCOL_TRANSPORT_H_ 34 35#define kIOPropertyATAPIMassStorageCharacteristics "ATAPI Mass Storage Characteristics" 36 37#if defined(KERNEL) && defined(__cplusplus) 38 39/* General IOKit includes */ 40#include <IOKit/IOLib.h> 41#include <IOKit/IOMessage.h> 42#include <IOKit/IOService.h> 43#include <IOKit/IOCommandPool.h> 44 45/* IOKit ATA Family includes */ 46#include <IOKit/ata/IOATADevice.h> 47#include <IOKit/ata/IOATATypes.h> 48 49/* IOKit ATA Storage includes */ 50#include <IOKit/storage/ata/IOATAStorageDefines.h> 51 52/* SCSI Architecture Model Family includes */ 53#include <IOKit/scsi/IOSCSIProtocolServices.h> 54 55// Forward class declaration 56class IOATAPIProtocolTransport; 57 58/*! 59 @typedef ATAPIClientData 60 @param cmd IOATACommand for request. 61 @param self Pointer to the object. 62 @param scsiTask SCSITaskIdentifier of request. 63 @discussion This structure is stuffed into the refcon so we can associate which 64 IOATACommand and SCSITaskIdentifier is completing. 65*/ 66 67struct ATAPIClientData 68{ 69 IOATACommand * cmd; 70 IOATAPIProtocolTransport * self; 71 SCSITaskIdentifier scsiTask; 72}; 73typedef struct ATAPIClientData ATAPIClientData; 74 75 76/*! 77 @class IOATAPIProtocolTransport 78 @abstract SCSI Protocol Driver Family for ATAPI Devices. 79 @discussion IOATAPIProtocolTransport contains all the bus specific support for ATAPI compliant devices. 80 To add vendor specific features or workarounds you will sub-class the appropriate 81 methods of this family. 82*/ 83 84class IOATAPIProtocolTransport : public IOSCSIProtocolServices 85{ 86 87 OSDeclareDefaultStructors ( IOATAPIProtocolTransport ) 88 89public: 90 91 // ---- IOService methods overridden ---- 92 93 bool init ( OSDictionary * propTable ); 94 95 // The start method is called to start our services. If the device 96 // can be controlled by this object, then we return true, else we 97 // return false. start() is usually used to allocate resources once 98 // it is determined that the device can be controlled by this object. 99 virtual bool start ( IOService * provider ); 100 101 // The stop method is called to stop our services. It is primarily 102 // called for deallocation of resources. 103 virtual void stop ( IOService * provider ); 104 105 // This method is our last chance to free all resources allocated. 106 virtual void free ( void ); 107 108 109protected: 110 111 // ---- member variables ---- 112 113 IOATADevice * fATADevice; 114 ataUnitID fATAUnitID; 115 ataDeviceType fATADeviceType; 116 ataSocketType fATASocketType; 117 atapiConfig fATAPIPacketConfig; 118 UInt8 fPIOMode; 119 UInt8 fDMAMode; 120 UInt8 fUltraDMAMode; 121 IOCommandGate * fCommandGate; 122 IOCommandPool * fCommandPool; 123 IOATACommand * fResetCommand; 124 IOATACommand * fConfigCommand; 125 IOATACommand * fIdentifyCommand; 126 char fRevision[kSizeOfATARevisionString + 1]; 127 char fModel[kSizeOfATAModelString + 1]; 128 bool fWakeUpResetOccurred; 129 bool fPhysicallyConnected; 130 131 // Used for low-power polling support 132 thread_call_t fPollingThread; 133 134 UInt16 fDeviceIdentifyData[256]; 135 IOMemoryDescriptor * fDeviceIdentifyBuffer; 136 bool fResetInProgress; 137 138 // Binary Compatibility instance variable expansion 139 struct ExpansionData 140 { 141 UInt32 fSemaphore; 142 UInt32 fMediaNotifyValue; 143 }; 144 ExpansionData * reserved; 145 146 // ---- IOService methods overridden ---- 147 148 // The message method is used to listen to messages from our provider, the ATA controller. 149 // It sends messages for bus reset notifications and for device removal (such as MediaBay, 150 // PC card, etc.) 151 virtual IOReturn message ( UInt32 type, IOService * provider, void * argument = 0 ); 152 153 // ---- Protocol transport methods overridden ---- 154 155 // Send a SCSI Command to the device. If the command was sent to the 156 // device and is pending completion, the subclass should return true and 157 // return back the kSCSIServiceResponse_Request_In_Process response. 158 // If the command completes immediately with an error, the subclass will 159 // return true and return back the appropriate status. 160 // if the subclass is currently processing all the commands it can, the 161 // subclass will return false and the command will be resent next time 162 // CommandCompleted is called. 163 virtual bool SendSCSICommand ( SCSITaskIdentifier request, 164 SCSIServiceResponse * serviceResponse, 165 SCSITaskStatus * taskStatus ); 166 167 // This is a stub - not implemented in upper layer yet. Eventually, there 168 // will be a way to abort a task or task set and this method will be called. 169 // It will abort any commands which have not been executed by the ATA controller 170 virtual SCSIServiceResponse AbortSCSICommand ( SCSITaskIdentifier request ); 171 172 // The IsProtocolServiceSupported method will return true if the protocol 173 // layer supports the specified feature. 174 virtual bool IsProtocolServiceSupported ( SCSIProtocolFeature feature, void * serviceValue ); 175 176 // The HandleProtocolServiceFeature method will return true if the protocol 177 // layer properly handled the specified feature. 178 virtual bool HandleProtocolServiceFeature ( SCSIProtocolFeature feature, void * serviceValue ); 179 180 // ------ Power Management Support ------ 181 182 // The HandlePowerOff method is called to do any bus specific activity 183 // necessary before shutting down and going to sleep. 184 virtual IOReturn HandlePowerOff ( void ); 185 186 // The HandlePowerOn method is called to do any bus specific activity 187 // necessary to recover from power-on/wake from sleep (e.g. device reset on ATAPI) 188 virtual IOReturn HandlePowerOn ( void ); 189 190 191 // ---- Methods defined by this class ---- 192 193 // Static callback proc for all SCSITask objects, it calls through to 194 // SCSITaskCallbackFunction. 195 static void sSCSITaskCallbackProc ( IOATACommand * cmd ); 196 197 // Callback proc for synchronous ATA only type commands. 198 static void sATACallbackSync ( IOATACommand * cmd ); 199 200 // Callback proc for asynchronous ATAPI resets. 201 static void sATAPIResetCallback ( IOATACommand * cmd ); 202 203 // Callback proc that does nothing. 204 static void sATAPIVoidCallback ( IOATACommand * cmd ); 205 206 // State machine for device configuration. 207 static void sATAPIConfigStateMachine ( IOATACommand * cmd ); 208 209 // Used for low-power polling. 210 static void sPollStatusRegister ( void * xptDriver, void * refCon ); 211 212 // Static callback for low-power polling. 213 static void sPollStatusRegisterCallback ( IOATACommand * cmd ); 214 215 // This method is called by the SCSITaskCallbackFunction and it calls the 216 // inherited CommandCompleted message with the results of the task. 217 virtual void CompleteSCSITask ( SCSITaskIdentifier scsiTask, 218 SCSIServiceResponse serviceResponse, 219 SCSITaskStatus taskStatus ); 220 221 // The SCSITaskCallbackFunction method is called by the static callback procedure 222 // to complete SCSITask operations. This method may be subclassed if a device 223 // workaround is necessary. 224 virtual void SCSITaskCallbackFunction ( IOATACommand * cmd, 225 SCSITaskIdentifier scsiTask ); 226 227 // The ReportATAPIDeviceType method returns the ataDeviceType for ATAPI 228 virtual ataDeviceType ReportATAPIDeviceType ( void ) const; 229 230 // The InspectDevice method is called to inspect the ATA device and verify 231 // that it is a device which can be controlled by this object 232 virtual bool InspectDevice ( IOATADevice * ataDevice ); 233 234 // The AllocateATACommandObjects method is called to allocate a pool of 235 // IOATACommands for general purpose I/O usage. 236 virtual void AllocateATACommandObjects ( void ); 237 238 // The DeallocateATACommandObjects method is called to deallocate a pool of 239 // IOATACommands for general purpose I/O usage. 240 virtual void DeallocateATACommandObjects ( void ); 241 242 // The GetATACommandObject method is called to retrieve a command from 243 // the pool. Pass true to allow the method to sleep waiting for a command, 244 // else pass false. If false is passed, there is NO guarantee that a valid 245 // command will be returned. If true is passed, it IS guaranteed that a 246 // valid command will be returned, but the thread may be slept waiting for 247 // those resources. 248 virtual IOATACommand * GetATACommandObject ( bool okToSleep = true ); 249 250 // The ReturnATACommandObject method is called to return a command to 251 // the pool. 252 virtual void ReturnATACommandObject ( IOATACommand * cmd ); 253 254 // The sSwapBytes16 method is used to word-swap the Device Identify data 255 // on big endian systems. Since all identify data is returned in little endian 256 // values, it must be word-swapped before inspected. 257 static void sSwapBytes16 ( UInt8 * buffer, IOByteCount numBytesToSwap ); 258 259 // The sConvertHighestBitToNumber method is used to find the highest bit in a 260 // word and return a numeric value. This is used to find the highest possible 261 // values for PIO, DMA, and UltraDMA transfer modes. 262 static UInt8 sConvertHighestBitToNumber ( UInt16 bitField ); 263 264 // The sSetWakeupResetOccurred method is used to safely set member variables 265 // behind the command gate. 266 static void sSetWakeupResetOccurred ( IOATAPIProtocolTransport * driver, 267 bool resetOccurred ); 268 269 // The sCheckWakeupResetOccur method is used to safely check member variables 270 // behind the command gate. 271 static void sCheckWakeupResetOccurred ( IOATAPIProtocolTransport * driver, 272 bool * resetOccurred ); 273 274 // The DidWakeupResetOccur method is used to safely find out if a reset 275 // occurred while we were asleep. 276 virtual bool CheckWakeupResetOccurred ( void ); 277 278 // The WakeupResetOccurred method is used to safely set/clear the reset flag. 279 virtual void SetWakeupResetOccurred ( bool resetOccurred ); 280 281 // The SetPIOTransferMode method is used to set the programmed input-output (PIO) 282 // transfer mode. The highest value reported by the device is used. 283 virtual IOReturn SetPIOTransferMode ( IOATACommand * cmd, bool forceSync ); 284 285 // The SetDMATransferMode method is used to set the direct memory access (DMA) 286 // transfer mode. The highest value reported by the device is used. 287 virtual IOReturn SetDMATransferMode ( IOATACommand * cmd, bool forceSync ); 288 289 // The IdentifyAndConfigureATAPIDevice method is called to correctly identify 290 // and configure an ATAPI device. 291 virtual IOReturn IdentifyAndConfigureATAPIDevice ( void ); 292 293 // The ConfigureATAPIDevice method is called to correctly configure the ATAPI 294 // device. It currently configures any PIO/DMA/UDMA transfer modes but may be 295 // expanded in the future. 296 virtual IOReturn ConfigureATAPIDevice ( void ); 297 298 // The ReconfigureATAPIDevice method is called to correctly reconfigure the ATAPI 299 // device after a reset event has occurred (bus reset or device reset). It 300 // currently reconfigures any PIO/DMA/UDMA transfer modes but may be expanded in 301 // the future. 302 virtual IOReturn ReconfigureATAPIDevice ( void ); 303 304 // The IdentifyATAPIDevice method is called to correctly identify the ATAPI 305 // device. It currently issues the Identify ATAPI Device packet command and 306 // uses the data to correctly configure the device. 307 virtual IOReturn IdentifyATAPIDevice ( void ); 308 309 // The ResetATAPIDevice method is called to issue a Device Reset (also known 310 // as a SOFT RESET). This method will only reset the specified device on the 311 // bus. 312 virtual IOReturn ResetATAPIDevice ( void ); 313 314 // The SendATASleepCommand method is called to put an ATAPI drive in sleep 315 // mode. 316 virtual IOReturn SendATASleepCommand ( void ); 317 318 // The EnablePollingOfStatusRegister method is called to set up a timer for 319 // the call to PollStatusRegister. It is called when the SCSI Application Layer 320 // driver wants to enable low-power polling and after a poll which does not 321 // see a change in the register status. 322 virtual void EnablePollingOfStatusRegister ( void ); 323 324 // The DisablePollingOfStatusRegister method is called to cancel any thread 325 // call which is doing a poll and drop the retain count on the object. 326 virtual void DisablePollingOfStatusRegister ( void ); 327 328 // The PollStatusRegister method is used to do low-power polling on drives which 329 // support it. This feature is enabled by the SCSI Application Layer driver. 330 virtual void PollStatusRegister ( void * refCon ); 331 332 // Callback method for the polling of the status register. 333 virtual void PollStatusRegisterCallback ( IOATACommand * cmd ); 334 335 // The TurnDrivePowerOff method is called to turn power to the drive OFF 336 IOReturn TurnDrivePowerOff ( void ); 337 338 IOReturn SendCommand ( IOATACommand * cmd ); 339 IOReturn GatedWaitForRequest ( void * data ); 340 341private: 342 343 // Binary Compatibility reserved method space 344 OSMetaClassDeclareReservedUnused ( IOATAPIProtocolTransport, 1 ); 345 OSMetaClassDeclareReservedUnused ( IOATAPIProtocolTransport, 2 ); 346 OSMetaClassDeclareReservedUnused ( IOATAPIProtocolTransport, 3 ); 347 OSMetaClassDeclareReservedUnused ( IOATAPIProtocolTransport, 4 ); 348 OSMetaClassDeclareReservedUnused ( IOATAPIProtocolTransport, 5 ); 349 OSMetaClassDeclareReservedUnused ( IOATAPIProtocolTransport, 6 ); 350 OSMetaClassDeclareReservedUnused ( IOATAPIProtocolTransport, 7 ); 351 OSMetaClassDeclareReservedUnused ( IOATAPIProtocolTransport, 8 ); 352 OSMetaClassDeclareReservedUnused ( IOATAPIProtocolTransport, 9 ); 353 OSMetaClassDeclareReservedUnused ( IOATAPIProtocolTransport, 10 ); 354 OSMetaClassDeclareReservedUnused ( IOATAPIProtocolTransport, 11 ); 355 OSMetaClassDeclareReservedUnused ( IOATAPIProtocolTransport, 12 ); 356 OSMetaClassDeclareReservedUnused ( IOATAPIProtocolTransport, 13 ); 357 OSMetaClassDeclareReservedUnused ( IOATAPIProtocolTransport, 14 ); 358 OSMetaClassDeclareReservedUnused ( IOATAPIProtocolTransport, 15 ); 359 OSMetaClassDeclareReservedUnused ( IOATAPIProtocolTransport, 16 ); 360 361}; 362 363#endif /* defined(KERNEL) && defined(__cplusplus) */ 364 365#endif /* _IOKIT_IO_ATAPI_PROTOCOL_TRANSPORT_H_ */