xref: /haiku/src/add-ons/kernel/bus_managers/ata/ATAPrivate.h (revision dfc8a217db488098641462dfc334dcc0f7d62456)
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, bool *isATAPI,
77 									bool *noAutoSense, uint32 *maxBlocks);
78 			status_t			ExecuteIO(scsi_ccb *ccb);
79 
80 			// ATA stuff
81 			status_t			SelectDevice(uint8 index);
82 			uint8				SelectedDevice();
83 
84 			status_t			Reset();
85 
86 			bool				UseDMA() const { return fUseDMA; }
87 
88 			status_t			Wait(uint8 setBits, uint8 clearedBits,
89 									uint32 flags, bigtime_t timeout);
90 			status_t			WaitDataRequest(bool high);
91 			status_t			WaitDeviceReady();
92 			status_t			WaitForIdle();
93 
94 			void				PrepareWaitingForInterrupt();
95 			status_t			WaitForInterrupt(bigtime_t timeout);
96 			status_t			RecoverLostInterrupt();
97 
98 			// request handling
99 			status_t			SendRequest(ATARequest *request, uint32 flags);
100 			status_t			FinishRequest(ATARequest *request, uint32 flags,
101 									uint8 errorMask);
102 
103 			// data transfers
104 			status_t			PrepareDMA(ATARequest *request);
105 			status_t			StartDMA();
106 			status_t			FinishDMA();
107 
108 			status_t			ExecutePIOTransfer(ATARequest *request);
109 
110 			status_t			ReadRegs(ATADevice *device);
111 			uint8				AltStatus();
112 
113 			status_t			ReadPIO(uint8 *buffer, size_t length);
114 			status_t			WritePIO(uint8 *buffer, size_t length);
115 
116 			status_t			Interrupt(uint8 status);
117 
118 private:
119 			status_t			_ReadRegs(ata_task_file *taskFile,
120 									ata_reg_mask mask);
121 			status_t			_WriteRegs(ata_task_file *taskFile,
122 									ata_reg_mask mask);
123 			status_t			_WriteControl(uint8 value);
124 			uint8				_Status();
125 
126 			void				_FlushAndWait(bigtime_t waitTime);
127 
128 			bool				_DevicePresent(int device);
129 
130 			status_t			_ReadPIOBlock(ATARequest *request,
131 									size_t length);
132 			status_t			_WritePIOBlock(ATARequest *request,
133 									size_t length);
134 			status_t			_TransferPIOBlock(ATARequest *request,
135 									size_t length, size_t *transferred);
136 			status_t			_TransferPIOPhysical(ATARequest *request,
137 									addr_t physicalAddress, size_t length,
138 									size_t *transferred);
139 			status_t			_TransferPIOVirtual(ATARequest *request,
140 									uint8 *virtualAddress, size_t length,
141 									size_t *transferred);
142 
143 			const char *		_DebugContext() { return fDebugContext; }
144 
145 private:
146 			device_node *		fNode;
147 			uint32				fChannelID;
148 			ata_controller_interface *fController;
149 			void *				fCookie;
150 
151 			spinlock			fInterruptLock;
152 			ConditionVariable	fInterruptCondition;
153 			ConditionVariableEntry fInterruptConditionEntry;
154 			bool				fExpectsInterrupt;
155 
156 			status_t			fStatus;
157 			scsi_bus			fSCSIBus;
158 			uint8				fDeviceCount;
159 			ATADevice **		fDevices;
160 			bool				fUseDMA;
161 			ATARequest *		fRequest;
162 
163 			char				fDebugContext[16];
164 };
165 
166 
167 class ATADevice {
168 public:
169 								ATADevice(ATAChannel *channel, uint8 index);
170 	virtual						~ATADevice();
171 
172 	// SCSI stuff
173 			status_t			ModeSense(ATARequest *request);
174 			status_t			TestUnitReady(ATARequest *request);
175 			status_t			SynchronizeCache(ATARequest *request);
176 			status_t			Eject(ATARequest *request);
177 			status_t			Inquiry(ATARequest *request);
178 			status_t			ReadCapacity(ATARequest *request);
179 			status_t			ReadCapacity16(ATARequest *request);
180 	virtual	status_t			ExecuteIO(ATARequest *request);
181 
182 			void				GetRestrictions(bool *noAutoSense,
183 									uint32 *maxBlocks);
184 
185 	// ATA stuff
186 	virtual	bool				IsATAPI() const { return false; }
187 
188 			bool				UseDMA() const { return fUseDMA; }
189 			bool				Use48Bits() const { return fUse48Bits; }
190 			size_t				BlockSize() const { return fBlockSize; }
191 
192 			status_t			Select();
193 
194 			ata_task_file *		TaskFile() { return &fTaskFile; }
195 			ata_reg_mask		RegisterMask() const { return fRegisterMask; }
196 
197 			status_t			SetFeature(int feature);
198 			status_t			DisableCommandQueueing();
199 			status_t			ConfigureDMA();
200 
201 	virtual	status_t			Configure();
202 			status_t			Identify();
203 
204 			status_t			ExecuteReadWrite(ATARequest *request,
205 									uint64 address, uint32 sectorCount);
206 
207 	protected:
208 			const char *		_DebugContext() { return fDebugContext; }
209 
210 			ATAChannel *		fChannel;
211 			ata_device_infoblock fInfoBlock;
212 			ata_task_file		fTaskFile;
213 			ata_reg_mask		fRegisterMask;
214 
215 			bool				fUseDMA;
216 			uint8				fDMAMode;
217 			uint8				fDMAFailures;
218 
219 	private:
220 			status_t			_FillTaskFile(ATARequest *request,
221 									uint64 address);
222 
223 			uint64				fTotalSectors;
224 			size_t				fBlockSize;
225 			size_t				fPhysicalBlockSize;
226 			size_t				fBlockOffset;
227 			uint8				fIndex;
228 			bool				fUse48Bits;
229 
230 			char				fDebugContext[16];
231 };
232 
233 
234 class ATAPIDevice : public ATADevice {
235 public:
236 								ATAPIDevice(ATAChannel *channel, uint8 index);
237 	virtual						~ATAPIDevice();
238 
239 			status_t			SendPacket(ATARequest *request);
240 	virtual	status_t			ExecuteIO(ATARequest *request);
241 
242 	virtual	bool				IsATAPI() const { return true; }
243 
244 	virtual	status_t			Configure();
245 
246 	private:
247 			status_t			_FillTaskFilePacket(ATARequest *request);
248 			status_t			_FinishRequest(ATARequest *request,
249 									uint32 flags);
250 
251 private:
252 			uint8				fPacket[12];
253 };
254 
255 
256 class ATARequest {
257 public:
258 								ATARequest(bool hasLock);
259 								~ATARequest();
260 
261 			void				SetStatus(uint8 status);
262 			uint8				Status() const { return fStatus; }
263 
264 			void				ClearSense();
265 			void				SetSense(uint8 key, uint16 codeQualifier);
266 			uint8				SenseKey() const { return fSenseKey; }
267 			uint8				SenseCode() const { return fSenseCode; }
268 			uint8				SenseQualifier() const
269 									{ return fSenseQualifier; }
270 
271 			void				SetDevice(ATADevice *device);
272 			ATADevice *			Device() const { return fDevice; }
273 
274 			void				SetTimeout(bigtime_t timeout);
275 			bigtime_t			Timeout() const { return fTimeout; }
276 
277 			void				SetIsWrite(bool isWrite);
278 			bool				IsWrite() const { return fIsWrite; }
279 
280 			void				SetUseDMA(bool useDMA);
281 			bool				UseDMA() const { return fUseDMA; }
282 
283 			void				SetBytesLeft(uint32 bytesLeft);
284 			size_t *			BytesLeft() { return &fBytesLeft; }
285 
286 			bool				HasData() const
287 									{ return fCCB->data_length > 0; }
288 			bool				HasSense() const { return fSenseKey != 0; }
289 
290 			status_t			Finish(bool resubmit);
291 
292 			// SCSI stuff
293 			status_t			Start(scsi_ccb *ccb);
294 			scsi_ccb *			CCB() { return fCCB; }
295 
296 			void				PrepareSGInfo();
297 			void				AdvanceSG(uint32 bytes);
298 
299 			uint32				SGElementsLeft() const
300 									{ return fSGElementsLeft; }
301 			const physical_entry *CurrentSGElement() const
302 									{ return fCurrentSGElement; }
303 			uint32				CurrentSGOffset() const
304 									{ return fCurrentSGOffset; }
305 
306 			void				SetOddByte(uint8 byte);
307 			bool				GetOddByte(uint8 *byte);
308 
309 			void				RequestSense();
310 
311 private:
312 			void				_FillSense(scsi_sense *sense);
313 
314 			const char *		_DebugContext() { return " request"; };
315 
316 			mutex				fLock;
317 			bool				fHasLock;
318 
319 			uint8				fStatus;
320 			uint8				fSenseKey;
321 			uint8				fSenseCode;
322 			uint8				fSenseQualifier;
323 
324 			ATADevice *			fDevice;
325 			bigtime_t			fTimeout;
326 			size_t				fBytesLeft;
327 			bool				fIsWrite;
328 			bool				fUseDMA;
329 			scsi_ccb *			fCCB;
330 
331 			uint32				fSGElementsLeft;
332 			const physical_entry *fCurrentSGElement;
333 			uint32				fCurrentSGOffset;
334 			bool				fHasOddByte;
335 			uint8				fOddByte;
336 };
337 
338 #endif // ATA_PRIVATE_H
339