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