xref: /haiku/src/add-ons/kernel/bus_managers/ata/ATAPrivate.h (revision 31794499331ff7359c7757b4a972030bb644eb13)
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 	virtual	status_t			ExecuteIO(ATARequest *request);
180 
181 			void				GetRestrictions(bool *noAutoSense,
182 									uint32 *maxBlocks);
183 
184 	// ATA stuff
185 	virtual	bool				IsATAPI() const { return false; }
186 
187 			bool				UseDMA() const { return fUseDMA; }
188 			bool				Use48Bits() const { return fUse48Bits; }
189 			size_t				BlockSize() const { return fBlockSize; }
190 
191 			status_t			Select();
192 
193 			ata_task_file *		TaskFile() { return &fTaskFile; }
194 			ata_reg_mask		RegisterMask() const { return fRegisterMask; }
195 
196 			status_t			SetFeature(int feature);
197 			status_t			DisableCommandQueueing();
198 			status_t			ConfigureDMA();
199 
200 	virtual	status_t			Configure();
201 			status_t			Identify();
202 
203 			status_t			ExecuteReadWrite(ATARequest *request,
204 									uint64 address, uint32 sectorCount);
205 
206 	protected:
207 			const char *		_DebugContext() { return fDebugContext; }
208 
209 			ATAChannel *		fChannel;
210 			ata_device_infoblock fInfoBlock;
211 			ata_task_file		fTaskFile;
212 			ata_reg_mask		fRegisterMask;
213 
214 			bool				fUseDMA;
215 			uint8				fDMAMode;
216 			uint8				fDMAFailures;
217 
218 	private:
219 			status_t			_FillTaskFile(ATARequest *request,
220 									uint64 address);
221 
222 			uint64				fTotalSectors;
223 			size_t				fBlockSize;
224 			size_t				fPhysicalBlockSize;
225 			size_t				fBlockOffset;
226 			uint8				fIndex;
227 			bool				fUse48Bits;
228 
229 			char				fDebugContext[16];
230 };
231 
232 
233 class ATAPIDevice : public ATADevice {
234 public:
235 								ATAPIDevice(ATAChannel *channel, uint8 index);
236 	virtual						~ATAPIDevice();
237 
238 			status_t			SendPacket(ATARequest *request);
239 	virtual	status_t			ExecuteIO(ATARequest *request);
240 
241 	virtual	bool				IsATAPI() const { return true; }
242 
243 	virtual	status_t			Configure();
244 
245 	private:
246 			status_t			_FillTaskFilePacket(ATARequest *request);
247 			status_t			_FinishRequest(ATARequest *request,
248 									uint32 flags);
249 
250 private:
251 			uint8				fPacket[12];
252 };
253 
254 
255 class ATARequest {
256 public:
257 								ATARequest(bool hasLock);
258 								~ATARequest();
259 
260 			void				SetStatus(uint8 status);
261 			uint8				Status() const { return fStatus; }
262 
263 			void				ClearSense();
264 			void				SetSense(uint8 key, uint16 codeQualifier);
265 			uint8				SenseKey() const { return fSenseKey; }
266 			uint8				SenseCode() const { return fSenseCode; }
267 			uint8				SenseQualifier() const
268 									{ return fSenseQualifier; }
269 
270 			void				SetDevice(ATADevice *device);
271 			ATADevice *			Device() const { return fDevice; }
272 
273 			void				SetTimeout(bigtime_t timeout);
274 			bigtime_t			Timeout() const { return fTimeout; }
275 
276 			void				SetIsWrite(bool isWrite);
277 			bool				IsWrite() const { return fIsWrite; }
278 
279 			void				SetUseDMA(bool useDMA);
280 			bool				UseDMA() const { return fUseDMA; }
281 
282 			void				SetBytesLeft(uint32 bytesLeft);
283 			size_t *			BytesLeft() { return &fBytesLeft; }
284 
285 			bool				HasData() const
286 									{ return fCCB->data_length > 0; }
287 			bool				HasSense() const { return fSenseKey != 0; }
288 
289 			status_t			Finish(bool resubmit);
290 
291 			// SCSI stuff
292 			status_t			Start(scsi_ccb *ccb);
293 			scsi_ccb *			CCB() { return fCCB; }
294 
295 			void				PrepareSGInfo();
296 			void				AdvanceSG(uint32 bytes);
297 
298 			uint32				SGElementsLeft() const
299 									{ return fSGElementsLeft; }
300 			const physical_entry *CurrentSGElement() const
301 									{ return fCurrentSGElement; }
302 			uint32				CurrentSGOffset() const
303 									{ return fCurrentSGOffset; }
304 
305 			void				SetOddByte(uint8 byte);
306 			bool				GetOddByte(uint8 *byte);
307 
308 			void				RequestSense();
309 
310 private:
311 			void				_FillSense(scsi_sense *sense);
312 
313 			const char *		_DebugContext() { return " request"; };
314 
315 			mutex				fLock;
316 			bool				fHasLock;
317 
318 			uint8				fStatus;
319 			uint8				fSenseKey;
320 			uint8				fSenseCode;
321 			uint8				fSenseQualifier;
322 
323 			ATADevice *			fDevice;
324 			bigtime_t			fTimeout;
325 			size_t				fBytesLeft;
326 			bool				fIsWrite;
327 			bool				fUseDMA;
328 			scsi_ccb *			fCCB;
329 
330 			uint32				fSGElementsLeft;
331 			const physical_entry *fCurrentSGElement;
332 			uint32				fCurrentSGOffset;
333 			bool				fHasOddByte;
334 			uint8				fOddByte;
335 };
336 
337 #endif // ATA_PRIVATE_H
338