xref: /haiku/src/add-ons/kernel/bus_managers/ata/ATAPrivate.h (revision 22805aae7f88e4a16627e5a8f97edf7501f44b64)
1 /*
2  * Copyright 2009, Michael Lotz, mmlr@mlotz.ch.
3  * Copyright 2008, Marcus Overhagen.
4  * Copyright 2004-2008, Axel Dörfler, axeld@pinc-software.de.
5  * Copyright 2002-2003, Thomas Kurschel.
6  *
7  * Distributed under the terms of the MIT License.
8  */
9 #ifndef ATA_PRIVATE_H
10 #define ATA_PRIVATE_H
11 
12 #include <ata_types.h>
13 #include <bus/ATA.h>
14 #include <bus/SCSI.h>
15 #include <device_manager.h>
16 #include <lock.h>
17 #include <new>
18 #include <safemode.h>
19 #include <scsi_cmds.h>
20 #include <stdio.h>
21 #include <string.h>
22 #include <util/AutoLock.h>
23 
24 #include "ATACommands.h"
25 #include "ATATracing.h"
26 #include "ata_device_infoblock.h"
27 
28 #define ATA_MAX_DMA_FAILURES		3
29 #define ATA_STANDARD_TIMEOUT		10 * 1000 * 1000
30 #define ATA_RELEASE_TIMEOUT			10 * 1000 * 1000
31 #define ATA_SIGNATURE_ATAPI			0xeb140101
32 #define ATA_SIM_MODULE_NAME			"bus_managers/ata/sim/driver_v1"
33 #define ATA_CHANNEL_ID_GENERATOR	"ata/channel_id"
34 #define ATA_CHANNEL_ID_ITEM			"ata/channel_id"
35 
36 enum {
37 	ATA_DEVICE_READY_REQUIRED	= 0x01,
38 	ATA_IS_WRITE				= 0x02,
39 	ATA_DMA_TRANSFER			= 0x04,
40 	ATA_CHECK_ERROR_BIT			= 0x08,
41 	ATA_WAIT_FINISH				= 0x10,
42 	ATA_WAIT_ANY_BIT			= 0x20
43 };
44 
45 
46 class ATADevice;
47 class ATARequest;
48 
49 extern scsi_for_sim_interface *gSCSIModule;
50 extern device_manager_info *gDeviceManager;
51 
52 bool copy_sg_data(scsi_ccb *ccb, uint offset, uint allocationLength,
53 	void *buffer, int size, bool toBuffer);
54 
55 class ATAChannel {
56 public:
57 									ATAChannel(device_node *node);
58 									~ATAChannel();
59 
60 		status_t					InitCheck();
61 		uint32						ChannelID() { return fChannelID; };
62 
63 		// SCSI stuff
64 		void						SetBus(scsi_bus bus);
65 		scsi_bus					Bus() { return fSCSIBus; };
66 		status_t					ScanBus();
67 
68 		void						PathInquiry(scsi_path_inquiry *info);
69 		void						GetRestrictions(uint8 targetID,
70 										bool *isATAPI, bool *noAutoSense,
71 										uint32 *maxBlocks);
72 		status_t					ExecuteIO(scsi_ccb *ccb);
73 
74 		// ATA stuff
75 		status_t					SelectDevice(uint8 index);
76 		bool						IsDevicePresent(uint8 index);
77 
78 		status_t					Reset(bool *presence, uint32 *signatures);
79 
80 		bool						UseDMA() { return fUseDMA; };
81 
82 		status_t					Wait(uint8 setBits, uint8 clearedBits,
83 										uint32 flags, bigtime_t timeout);
84 		status_t					WaitDataRequest(bool high);
85 		status_t					WaitDeviceReady();
86 		status_t					WaitForIdle();
87 
88 		void						PrepareWaitingForInterrupt();
89 		status_t					WaitForInterrupt(bigtime_t timeout);
90 
91 		// request handling
92 		status_t					SendRequest(ATARequest *request,
93 										uint32 flags);
94 		status_t					FinishRequest(ATARequest *request,
95 										uint32 flags, uint8 errorMask);
96 
97 		// data transfers
98 		status_t					PrepareDMA(ATARequest *request);
99 		status_t					StartDMA();
100 		status_t					FinishDMA();
101 
102 		status_t					ExecutePIOTransfer(ATARequest *request);
103 
104 		status_t					ReadRegs(ATADevice *device);
105 		uint8						AltStatus();
106 
107 		status_t					ReadPIO(uint8 *buffer, size_t length);
108 		status_t					WritePIO(uint8 *buffer, size_t length);
109 
110 		void						Interrupt(uint8 status);
111 
112 private:
113 		status_t					_ReadRegs(ata_task_file *taskFile,
114 										ata_reg_mask mask);
115 		status_t					_WriteRegs(ata_task_file *taskFile,
116 										ata_reg_mask mask);
117 		status_t					_WriteControl(uint8 value);
118 
119 		void						_FlushAndWait(bigtime_t waitTime);
120 
121 		status_t					_ReadPIOBlock(ATARequest *request,
122 										size_t length);
123 		status_t					_WritePIOBlock(ATARequest *request,
124 										size_t length);
125 		status_t					_TransferPIOBlock(ATARequest *request,
126 										size_t length, size_t *transferred);
127 		status_t					_TransferPIOPhysical(ATARequest *request,
128 										addr_t physicalAddress, size_t length,
129 										size_t *transferred);
130 		status_t					_TransferPIOVirtual(ATARequest *request,
131 										uint8 *virtualAddress, size_t length,
132 										size_t *transferred);
133 
134 		const char *				_DebugContext() { return fDebugContext; };
135 
136 		device_node *				fNode;
137 		uint32						fChannelID;
138 		ata_controller_interface *	fController;
139 		void *						fCookie;
140 
141 		mutex						fExecutionLock;
142 		spinlock					fInterruptLock;
143 		ConditionVariable			fInterruptCondition;
144 		ConditionVariableEntry		fInterruptConditionEntry;
145 		bool						fExpectsInterrupt;
146 
147 		status_t					fStatus;
148 		scsi_bus					fSCSIBus;
149 		uint8						fDeviceCount;
150 		ATADevice **				fDevices;
151 		bool						fUseDMA;
152 		ATARequest *				fRequest;
153 
154 		char						fDebugContext[16];
155 };
156 
157 
158 class ATADevice {
159 public:
160 									ATADevice(ATAChannel *channel,
161 										uint8 index);
162 virtual								~ATADevice();
163 
164 		// SCSI stuff
165 		status_t					ModeSense(ATARequest *request);
166 		status_t					TestUnitReady(ATARequest *request);
167 		status_t					SynchronizeCache(ATARequest *request);
168 		status_t					Eject(ATARequest *request);
169 		status_t					Inquiry(ATARequest *request);
170 		status_t					ReadCapacity(ATARequest *request);
171 virtual	status_t					ExecuteIO(ATARequest *request);
172 
173 		// ATA stuff
174 virtual	bool						IsATAPI() { return false; };
175 
176 		bool						UseDMA() { return fUseDMA; };
177 		bool						UseLBA() { return fUseLBA; };
178 		bool						Use48Bits() { return fUse48Bits; };
179 
180 		status_t					Select();
181 
182 		ata_task_file *				TaskFile() { return &fTaskFile; };
183 		ata_reg_mask				RegisterMask() { return fRegisterMask; };
184 
185 		status_t					SetFeature(int feature);
186 		status_t					DisableCommandQueueing();
187 		status_t					ConfigureDMA();
188 
189 virtual	status_t					Configure();
190 		status_t					Identify();
191 
192 		status_t					ExecuteReadWrite(ATARequest *request,
193 										uint64 address, uint32 sectorCount);
194 
195 protected:
196 		const char *				_DebugContext() { return fDebugContext; };
197 
198 		ATAChannel *				fChannel;
199 		ata_device_infoblock		fInfoBlock;
200 		ata_task_file				fTaskFile;
201 		ata_reg_mask				fRegisterMask;
202 
203 		bool						fUseDMA;
204 		uint8						fDMAMode;
205 		uint8						fDMAFailures;
206 
207 private:
208 		status_t					_FillTaskFile(ATARequest *request,
209 										uint64 address);
210 
211 		uint8						fIndex;
212 		bool						fUseLBA;
213 		bool						fUse48Bits;
214 		uint64						fTotalSectors;
215 
216 		char						fDebugContext[16];
217 };
218 
219 
220 class ATAPIDevice : public ATADevice {
221 public:
222 									ATAPIDevice(ATAChannel *channel,
223 										uint8 index);
224 virtual								~ATAPIDevice();
225 
226 		status_t					SendPacket(ATARequest *request);
227 virtual	status_t					ExecuteIO(ATARequest *request);
228 
229 virtual	bool						IsATAPI() { return true; };
230 
231 virtual	status_t					Configure();
232 
233 private:
234 		status_t					_FillTaskFilePacket(ATARequest *request);
235 
236 		bool						fInterruptsForPacket;
237 		uint8						fPacket[12];
238 };
239 
240 
241 class ATARequest {
242 public:
243 									ATARequest();
244 
245 		void						SetStatus(uint8 status);
246 		uint8						Status() { return fStatus; };
247 
248 		void						ClearSense();
249 		void						SetSense(uint8 key, uint16 codeQualifier);
250 		uint8						SenseKey() { return fSenseKey; };
251 		uint8						SenseCode() { return fSenseCode; };
252 		uint8						SenseQualifier() { return fSenseQualifier; };
253 
254 		void						SetDevice(ATADevice *device);
255 		ATADevice *					Device() { return fDevice; };
256 
257 		void						SetTimeout(bigtime_t timeout);
258 		bigtime_t					Timeout() { return fTimeout; };
259 
260 		void						SetIsWrite(bool isWrite);
261 		bool						IsWrite() { return fIsWrite; };
262 
263 		void						SetUseDMA(bool useDMA);
264 		bool						UseDMA() { return fUseDMA; };
265 
266 		void						SetBlocksLeft(uint32 blocksLeft);
267 		uint32 *					BlocksLeft() { return &fBlocksLeft; };
268 
269 		status_t					Finish(bool resubmit);
270 
271 		// SCSI stuff
272 		void						SetCCB(scsi_ccb *ccb);
273 		scsi_ccb *					CCB() { return fCCB; };
274 
275 		void						PrepareSGInfo();
276 		void						AdvanceSG(uint32 bytes);
277 
278 		uint32						SGElementsLeft()
279 										{ return fSGElementsLeft; };
280 		const physical_entry *		CurrentSGElement()
281 										{ return fCurrentSGElement; };
282 		uint32						CurrentSGOffset()
283 										{ return fCurrentSGOffset; };
284 
285 		void						SetOddByte(uint8 byte);
286 		bool						GetOddByte(uint8 *byte);
287 
288 		void						RequestSense();
289 
290 private:
291 		void						_FillSense(scsi_sense *sense);
292 
293 		const char *				_DebugContext() { return " request"; };
294 
295 		uint8						fStatus;
296 		uint8						fSenseKey;
297 		uint8						fSenseCode;
298 		uint8						fSenseQualifier;
299 
300 		ATADevice *					fDevice;
301 		bigtime_t					fTimeout;
302 		uint32						fBlocksLeft;
303 		bool						fIsWrite;
304 		bool						fUseDMA;
305 		scsi_ccb *					fCCB;
306 
307 		uint32						fSGElementsLeft;
308 		const physical_entry *		fCurrentSGElement;
309 		uint32						fCurrentSGOffset;
310 		bool						fHasOddByte;
311 		uint8						fOddByte;
312 };
313 
314 #endif // ATA_PRIVATE_H
315