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#ifndef _DRV_PCI_ATA_H
24#define _DRV_PCI_ATA_H
25
26#include <libkern/c++/OSObject.h>
27#include <IOKit/IOTypes.h>
28#include "IOATAController.h"
29#include <IOKit/IOMemoryCursor.h>
30#include <IOKit/IOBufferMemoryDescriptor.h>
31
32#include <IOKit/IOInterruptEventSource.h>
33
34/*! @class IOPCIATA
35    @abstract The base class for  PCI-IDE ata controller family.
36    @discussion class defining the common elements of bus-mastering PCI ATA controllers which meet or at least loosely follow the pci bus mastering pci-ide controller spec. Header doc is incomplete, but source is heavily commented.
37
38*/
39
40
41
42class IOPCIATA : public IOATAController
43{
44    OSDeclareDefaultStructors(IOPCIATA);
45
46public:
47
48	/*--- Overrides from IOATAController ---*/
49	virtual bool init(OSDictionary * properties);
50    virtual bool start( IOService* provider );
51
52protected:
53
54	// The DMA states: not in use, in use and running with additional passes needed,
55	// in use on final pass, transfer complete, and failure
56	enum ATADMAState
57	{
58		// DMA state flags
59		kATADMAInactive,
60		kATADMAStarting,
61		kATADMAActive,
62		kATADMAStatus,
63		kATADMAComplete,
64		kATADMAError,
65
66	};
67
68	enum {
69		// PRD flags
70		kLast_PRD =	0x8000,
71		kContinue_PRD = 0,
72
73	};
74
75
76	enum {
77		mBMCmdStartOutput = 0x01,  						// start engine to transfer from memory to device.
78		mBMCmdStartInput = (1 << 3 ) | 0x01,  	// start engine to transfer from device to memory
79		mBMCmdStop = 0x00,								// halt engine.
80	};
81
82	enum {
83		// bus master status register definitions.
84		bBMStatusSimplex = 7,  	// 0 = simultaneous transactions allowed. 1 = primary and secondary busses may not be active at same time.
85		bBMStatusDrv1 = 6,     	// 1 = device 1 and bus are already configured by some other software/firmware
86		bBMStatusDrv0 = 5,     	// 1 = device 0 and bus are already configured by some other software/firmware
87		bBMStatusInt = 2,		// 1 = device has asserted INTRQ and all data is flushed to/from memory.
88		bBMStatusError = 1,		// 1 = an error in the DMA has occured. Software clears by writing 1 to this bit.
89		bBMStatusActive = 0,	// 1 = DMA engine is active.
90	};
91
92	enum{
93
94		mBMStatusSimplex = 	1 << 7,
95		mBMStatusDrv1 = 	1 << 6,
96		mBMStatusDrv0 = 	1 << 5,
97		mBMStatusInt = 		1 << 2,
98		mBMStatusError = 	1 << 1,
99		mBMStatusActive = 	1
100	};
101
102	// the physical region descriptor used for the dma engine.
103	struct PRD
104	{
105		UInt32	bufferPtr;		// address
106		UInt16	byteCount;		// 16 bit byte count where 0x0000 = 64K
107		UInt16	flags;			// 0 in flags means contine, 0x80 means stop
108	};
109
110
111	// descendants of this class MUST initialize these values
112	// prior to activating any DMA command.
113	IOATARegPtr8 _bmCommandReg;
114	IOATARegPtr8 _bmStatusReg;
115	IOATARegPtr32 _bmPRDAddresReg;
116
117	// semaphore for DMA state
118	UInt32	_dmaState;
119
120	// table of PRD descriptors
121	PRD*	_prdTable;
122	IOPhysicalAddress _prdTablePhysical;
123
124	IONaturalMemoryCursor*	_DMACursor;
125
126	// override from IOATAController
127	// activate the DMA engine as per the current command
128	virtual IOReturn startDMA( void );
129
130	// override from IOATAController
131	// safely halt the DMA engine  regardless of state
132	virtual IOReturn stopDMA( void );
133
134	// allocate memory for the PRD descriptors.
135	virtual bool allocDMAChannel(void);
136
137	// fill CC with stop commands.
138	virtual void initATADMAChains (PRD* descPtr);
139
140	// fill out a PRD, respecting endianess
141	virtual void setPRD(UInt8 *bffr, UInt16 count, PRD *tableElement, UInt16 end);
142
143	// setup the CC with IO commands
144	virtual IOReturn createChannelCommands(void);
145
146	// deallocate memory for the DMA engine
147	virtual bool freeDMAChannel(void);
148
149	// clean up on device interrupt
150	virtual IOReturn handleDeviceInterrupt(void);
151
152	// activate the DMA engine
153	virtual void activateDMAEngine(void);
154
155	// shutdown the DMA engine
156	virtual void stopDMAEngine(void);
157
158	// safely suspend the DMA engine
159	virtual void shutDownATADMA (void);
160
161	// overrides
162	virtual void free();
163protected:
164/*! @struct ExpansionData
165    @discussion This structure will be used to expand the capablilties of the IOPCIATA class in the future.
166    */
167    typedef struct ExpansionData
168    {
169    	IOBufferMemoryDescriptor*	_prdBuffer;
170    } ExpansionData;
171
172/*! @var reserved
173    Reserved for future use.  (Internal use only)  */
174    ExpansionData *reserved;
175
176private:
177    OSMetaClassDeclareReservedUnused(IOPCIATA, 0);
178    OSMetaClassDeclareReservedUnused(IOPCIATA, 1);
179    OSMetaClassDeclareReservedUnused(IOPCIATA, 2);
180    OSMetaClassDeclareReservedUnused(IOPCIATA, 3);
181    OSMetaClassDeclareReservedUnused(IOPCIATA, 4);
182    OSMetaClassDeclareReservedUnused(IOPCIATA, 5);
183    OSMetaClassDeclareReservedUnused(IOPCIATA, 6);
184    OSMetaClassDeclareReservedUnused(IOPCIATA, 7);
185    OSMetaClassDeclareReservedUnused(IOPCIATA, 8);
186    OSMetaClassDeclareReservedUnused(IOPCIATA, 9);
187    OSMetaClassDeclareReservedUnused(IOPCIATA, 10);
188    OSMetaClassDeclareReservedUnused(IOPCIATA, 11);
189    OSMetaClassDeclareReservedUnused(IOPCIATA, 12);
190    OSMetaClassDeclareReservedUnused(IOPCIATA, 13);
191    OSMetaClassDeclareReservedUnused(IOPCIATA, 14);
192    OSMetaClassDeclareReservedUnused(IOPCIATA, 15);
193    OSMetaClassDeclareReservedUnused(IOPCIATA, 16);
194    OSMetaClassDeclareReservedUnused(IOPCIATA, 17);
195    OSMetaClassDeclareReservedUnused(IOPCIATA, 18);
196    OSMetaClassDeclareReservedUnused(IOPCIATA, 19);
197    OSMetaClassDeclareReservedUnused(IOPCIATA, 20);
198};
199
200#endif // _DRV_PCI_ATA_H
201