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