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