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