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