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