1/* 2 * Copyright (c) 1998-2008 Apple Inc. All rights reserved. 3 * 4 * @APPLE_LICENSE_HEADER_START@ 5 * 6 * The contents of this file constitute Original Code as defined in and 7 * are subject to the Apple Public Source License Version 1.1 (the 8 * "License"). You may not use this file except in compliance with the 9 * License. Please obtain a copy of the License at 10 * http://www.apple.com/publicsource and read it before using this file. 11 * 12 * This Original Code and all software distributed under the License are 13 * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER 14 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 15 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 16 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the 17 * License for the specific language governing rights and limitations 18 * under the License. 19 * 20 * @APPLE_LICENSE_HEADER_END@ 21 */ 22 23 24#ifndef _IOATACONTROLLER_H 25#define _IOATACONTROLLER_H 26 27#include <IOKit/IOTypes.h> 28#include <IOKit/IOBufferMemoryDescriptor.h> 29#include <IOKit/IOCommandGate.h> 30#include <IOKit/IOService.h> 31#include <IOKit/IOWorkLoop.h> 32#include "ATATimerEventSource.h" 33 34class IOATADevice; 35class IOATABusCommand; 36class IOATABusInfo; 37class IOATADevConfig; 38 39/*! @class IOATAController 40 @abstract The base class for ata controller family. Provides the interface common to all ata bus controllers. 41 @discussion Subclasses of IOATAController implement drivers for specific bus hardware. Disk devices are clients of 42 IOATAController and communicate via the IOATABusNub instantiated for each device discovered by the specific IOATAController 43 subclass when it probes hardware. Via the nub, the ATA Controller provides standard information about bus capability, accepts 44 requests for transfer mode configuration (timing), accepts requests for IO and bus operations, notifies the device driver about 45 bus events which may affect the device, such as soft-resets or device removal (ie, media-bay and PC-card) and removal of queued 46 IO requests which have not been dispatched into the hardware. 47 48 @discussion The header doc for this class is incomplete. The source however is heavily commented and should be consulted until 49 such time as complete header doc is available. 50*/ 51 52 53 54class IOATAController : public IOService 55{ 56 OSDeclareDefaultStructors(IOATAController); 57 58public: 59 60 61 /*--- Common ATA Controller Interface ---*/ 62 // find out bus capability 63 virtual IOReturn provideBusInfo( IOATABusInfo* infoOut); 64 65 // set and get bus timing configuration for a specific unit 66 virtual IOReturn selectConfig( IOATADevConfig* configRequest, UInt32 unitNumber); 67 virtual IOReturn getConfig( IOATADevConfig* configRequest, UInt32 unitNumber); 68 69 // The main call puts something on the work loop 70 virtual IOReturn executeCommand( IOATADevice* nub, IOATABusCommand* cmd); 71 72 73 74 /*-- Power Management ---*/ 75 76 // TBD 77 78 79 /*--- Overrides from IOService ---*/ 80 virtual bool init(OSDictionary * properties); 81 82 virtual IOService* probe( IOService* provider, SInt32* score ); 83 virtual bool start( IOService* provider ); 84 85 86protected: 87 88 enum { 89 kBusFree = 'free', // bus is available 90 kBusBusy = 'busy', // bus is busy with request 91 kQueueOpen = '!lck', // queue is not locked 92 kQueueLocked = 'LOCK', // queue is frozen and not 93 kImmediateLocked = '!Imd', // immediate commands may not be processed 94 kImmediateOK = 'Immd' // immediate commands allowed. 95 }; 96 97 /* Transaction State indicator definition - indicates what action is next*/ 98 enum transState { 99 kATAInitial = 0x00, // in queue 100 kATAStarted = 0x01, // issue taskfile 101 kATAPICmd = 0x02, // issue packet 102 kATADataTx = 0x03, // data transfer phase 103 kATAStatus = 0x04, // read status 104 kATAComplete = 0x05, // io complete 105 kATADone = 0x06 // completion callout called 106 }; 107 108 struct ataDevInfo { 109 ataDeviceType type; // ata, atapi, unknown 110 atapiConfig packetSend; // slow DRQ, IRQ, or fast DRQ for packet 111 }; 112 113 114 struct ataDoubleBuffer 115 { 116 IOPhysicalAddress physicalBuffer; 117 IOLogicalAddress logicalBuffer; 118 IOByteCount bufferSize; 119 120 }; 121 122 123 IOService* _provider; 124 IOWorkLoop* _workLoop; 125 IOCommandGate* _cmdGate; 126 ATATimerEventSource* _timer; 127 queue_head_t _commandQueue; 128 IOATABusCommand* _currentCommand; 129 UInt32 _busState; 130 UInt32 _queueState; 131 UInt32 _immediateGate; 132 ataUnitID _selectedUnit; 133 ataDevInfo _devInfo[2]; 134 IOATADevice* _nub[2]; 135 ataDoubleBuffer _doubleBuffer; 136 137 IOATARegPtr8 _tfFeatureReg; 138 IOATARegPtr8 _tfSCountReg; 139 IOATARegPtr8 _tfSectorNReg; 140 IOATARegPtr8 _tfCylLoReg; 141 IOATARegPtr8 _tfCylHiReg; 142 IOATARegPtr8 _tfSDHReg; 143 IOATARegPtr8 _tfStatusCmdReg; 144 IOATARegPtr16 _tfDataReg; 145 IOATARegPtr8 _tfAltSDevCReg; 146 147 148 // false if couldn't allocate the per-bus double buffer. 149 // controllers should provide implementation where needed 150 // for DMA hardware compatibility. The default method provides 151 // a 4K buffer for PIO since MemoryDescriptors do not by default have 152 // logical addresses in the kernel space. 153 virtual bool allocateDoubleBuffer( void ); 154 155 // perform 2-byte endian swap. Only useful on PIO transfers and identify data 156 virtual void swapBytes16( UInt8* dataBuffer, IOByteCount length); 157 158/*! @function handleCommand 159 @abstract Called by executeCommand() to handle the client command 160 from the workloop context. 161 @param command The command code. 162 @param param1 Command parameter. 163 @param param2 Command parameter. 164 @param param3 Command parameter. 165 @result kIOReturnSuccess on success, or an error code otherwise. */ 166 167 virtual IOReturn handleCommand( void * command, 168 void * param1 = 0, 169 void * param2 = 0, 170 void * param3 = 0); 171 172 173/*! @function busCanDispatch 174 @abstract answers whether the bus is in state such that the next command 175 can be dispatched. 176 @result true - bus is free to issue commands. false - bus cannot issue 177 commands at this time. */ 178 virtual bool busCanDispatch( void ); 179 180 181/*! @function dispatchNext 182 @abstract Causes the command at the front of the queue to dequeue, made the 183 current command and begin execution. 184 @result noErr indicates successful dispatch. */ 185 virtual IOReturn dispatchNext( void ); 186 187 // sets the result code, free's the bus state, dispatch next command and execute completion 188 virtual void completeIO( IOReturn commandResult ); 189 190 // Command queue handlers. 191 virtual IOReturn enqueueCommand( IOATABusCommand* command); 192 virtual IOATABusCommand* dequeueFirstCommand( void ); 193 194 // event notifier for clients 195 virtual void executeEventCallouts( ataEventCode event, ataUnitID unit); 196 197 // default handler for device interrupts. 198 virtual IOReturn handleDeviceInterrupt( void ); 199 200 201 // timer functions 202 // starts the timeout on the current command 203 virtual IOReturn startTimer( UInt32 inMS); 204 //disable and clear a running timer. 205 virtual void stopTimer( void ); 206 // called when a timeout occurs. 207 virtual void handleTimeout( void ); 208 // true if the timer has expired 209 virtual bool checkTimeout( void ); 210 211 // handle IO opcodes 212 virtual IOReturn handleExecIO( void ); 213 virtual IOReturn handleRegAccess( void ); 214 virtual IOReturn handleBusReset(void); 215 virtual IOReturn handleQueueFlush( void ); 216 217 // various protocol phases 218 virtual IOReturn asyncData(void); 219 virtual IOReturn asyncStatus(void); 220 virtual IOReturn asyncIO(void); 221 virtual IOReturn asyncCommand(void); 222 virtual IOReturn synchronousIO(void); 223 224 // hardware access 225 virtual IOReturn selectDevice( ataUnitID unit ); 226 virtual IOReturn issueCommand( void ); 227 virtual IOReturn writePacket( void ); 228 virtual IOReturn softResetBus( bool doATAPI = false ); 229 230 virtual IOReturn startDMA( void ); 231 virtual IOReturn stopDMA( void ); 232 233 virtual bool ATAPISlaveExists( void ); 234 virtual UInt32 scanForDrives( void ); 235 236 virtual bool waitForU8Status (UInt8 mask, UInt8 value); 237 238 virtual IOByteCount readATAPIByteCount( void ); 239 virtual void handleOverrun( IOByteCount length); 240 virtual IOReturn registerAccess(bool isWrite); 241 242 // PIO data transfers 243 virtual IOReturn txDataIn (IOLogicalAddress buf, IOByteCount length); 244 virtual IOReturn txDataOut (IOLogicalAddress buf, IOByteCount length); 245 246 virtual IOATAController::transState determineATAPIState(void); 247 248 // device should set the controller to the config for this device 249 virtual void selectIOTiming( ataUnitID unit ); 250 251 // subclasses MUST implement this function in order to initialize 252 // the pointers to the ATA task file registers during start() time. 253 virtual bool configureTFPointers(void); 254 255 // convert a bit-significant indicator to a numeric value. 256 virtual UInt16 bitSigToNumeric( UInt16 binary); 257 258 // for 48 bit register reading and writing 259 UInt16 readExtRegister( IOATARegPtr8 inRegister ); 260 void writeExtRegister( IOATARegPtr8 inRegister, UInt16 inValue ); 261 262 // overrides 263 virtual void free(); 264 265private: 266 267 // used called by the commandgate in executeCommand. 268 static void executeCommandAction(OSObject * owner, 269 void * arg0, 270 void * arg1, 271 void * arg2, 272 void * arg3); 273 274 // callout used by the timer to indicate the timeout failure. 275 static void timeoutOccured( OSObject *owner, 276 IOTimerEventSource *sender); 277 278protected: 279/*! @struct ExpansionData 280 @discussion This structure will be used to expand the capablilties of the IOATAController in the future. 281 */ 282 typedef struct ExpansionData 283 { 284 IOBufferMemoryDescriptor* _doubleBufferDesc; 285 } ExpansionData; 286 287/*! @var reserved 288 Reserved for future use. (Internal use only) */ 289 ExpansionData *reserved; 290 291private: 292 OSMetaClassDeclareReservedUnused(IOATAController, 0); 293 OSMetaClassDeclareReservedUnused(IOATAController, 1); 294 OSMetaClassDeclareReservedUnused(IOATAController, 2); 295 OSMetaClassDeclareReservedUnused(IOATAController, 3); 296 OSMetaClassDeclareReservedUnused(IOATAController, 4); 297 OSMetaClassDeclareReservedUnused(IOATAController, 5); 298 OSMetaClassDeclareReservedUnused(IOATAController, 6); 299 OSMetaClassDeclareReservedUnused(IOATAController, 7); 300 OSMetaClassDeclareReservedUnused(IOATAController, 8); 301 OSMetaClassDeclareReservedUnused(IOATAController, 9); 302 OSMetaClassDeclareReservedUnused(IOATAController, 10); 303 OSMetaClassDeclareReservedUnused(IOATAController, 11); 304 OSMetaClassDeclareReservedUnused(IOATAController, 12); 305 OSMetaClassDeclareReservedUnused(IOATAController, 13); 306 OSMetaClassDeclareReservedUnused(IOATAController, 14); 307 OSMetaClassDeclareReservedUnused(IOATAController, 15); 308 OSMetaClassDeclareReservedUnused(IOATAController, 16); 309 OSMetaClassDeclareReservedUnused(IOATAController, 17); 310 OSMetaClassDeclareReservedUnused(IOATAController, 18); 311 OSMetaClassDeclareReservedUnused(IOATAController, 19); 312 OSMetaClassDeclareReservedUnused(IOATAController, 20); 313}; 314#endif /* !_IOATACONTROLLER_H */ 315