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