xref: /haiku/headers/os/drivers/bus/SCSI.h (revision d3d8b26997fac34a84981e6d2b649521de2cc45a)
1 /*
2  * Copyright 2004-2006, Haiku, Inc. All RightsReserved.
3  * Copyright 2002/03, Thomas Kurschel. All rights reserved.
4  *
5  * Distributed under the terms of the MIT License.
6  */
7 #ifndef _SCSI_BUSMANAGER_H_
8 #define _SCSI_BUSMANAGER_H_
9 
10 /*
11 	SCSI bus manager interface
12 
13 	The bus manager interface is _based_ on CAM, but I've modified it because :-
14 	- HBA engine, target mode and queue freezing (and probably other features)
15 	  aren't supported (at least the first two aren't supported by linux too ;)
16 	- Asynchronous events aren't supported (no OS/driver I know uses them)
17 	- P/T/L was defined by number not by handle, requiring many redundant tests
18 	  and thus making adding/removing of devices/busses very hard, especially if
19 	  PnP is to be supported
20 	- single entry system as proposed by CAM involves extra tests and overhead
21 	  because of generalized data structure
22 
23 
24 	For peripheral driver writers:
25 
26 	Something about requests involving data transfer: you can either specify
27 	the virtual address in <data> of CCB (in which case it must be continuous),
28 	or store a pointer to a S/G list that contains physical addresses in
29 	<sg_list>/<sg_cnt>. If <sg_list> is non-Null, <data> is ignored.
30 	The S/G list must be in kernel space because the request can be executed
31 	in a different thread context. This is also the	reason why the S/G list has
32 	to contain physical addresses. For obvious reason, the data buffer specified
33 	by <sg_list> must be locked, but <data> doesn't need to be.
34 
35 	You can either execute the request synchronously ("sync_io") or
36 	asynchronously ("async_io"; you have to acquire <completion_sem> to find
37 	out when the request is finished). In the first case you can use either
38 	<data> or <sg_list>, in the latter <sg_list> only.
39 
40 	The SCSI bus manager takes care that the controller can access the data
41 	via DMA by copying it into a buffer if necessary. For the paging path,
42 	this can lead to problems (if the system writes a page to disk and the SCSI
43 	bus manager has to allocate a buffer during execution you are in trouble),
44 	therefore the blk_man takes care that is not necessary for reads/writes.
45 	To safe some microseconds, you should set the SCSI_DMA_SAFE flag for these
46 	requests, so the SCSI bus manager ommittes the test.
47 
48 	Effectively, using synchronous execution and specifying the address via
49 	<data> is a safe bet.
50 
51 
52 	For SIM writers:
53 
54 	Requests sent by peripheral drivers are forwarded to the <scsi_io> entry
55 	of the SIM. You should return as soon as some waiting is required.
56 	Usually, the controller raises an IRQ when a request can be continued
57 	or is finished. As interrupt handlers must be as fast as possible, you
58 	can schedule a DPC in the handler (<schedule_dpc>) which executed by a
59 	high priority service thread that is spawned by the SCSI bus manager
60 	for each bus. This service thread also takes care to submit waiting
61 	requests.
62 
63 	You can specify a maximum number of concurrent requests per bus via
64 	path_inquiry (<hba_queue_size>) for the bus. The device limit is
65 	determined via INQUIRY. If you need a lower/dynamic limit, you can refuse
66 	a request by <requeue>. If <bus_overflow> is true, no further requests
67 	to the bus will be sent, if <bus_overflow> is false, no further requests
68 	to the device will be sent. To terminate the overflow condition, call
69 	<cont_send_device>/<cont_send_bus>. It also terminated when a request
70 	for the bus/device is finished via <finished> or <resubmit>.
71 	Because of the asynchronous nature,	requests may still arrive after the
72 	overflow condition being signalled, so you should add a safety test to
73 	<scsi_io>.
74 
75 	If a problem occurs during execution, you can ask for a restart via
76 	<resubmit>. The request in question will be submitted as soon as possible.
77 
78 	If you want to be not disturbed, you can block further requests via
79 	<block_bus>/<block_device>. As said above, you must have a safety test
80 	at <scsi_io> though.
81 
82 	If the SIM uses a non-SCSI protocol, it can ask the SCSI bus manager
83 	to emulate unsupported SCSI commands by translating them other (supported)
84 	commands. The bus manager calls <get_restriction> during detection for
85 	each device, setting <is_atapi> on return makes the bus manager translate
86 	READ6/WRITE6 commands to READ10/WRITE10 commands, MODE REQUEST6/SENSE6
87 	to MODE REQUEST10/SENSE10 and fix the version fields of INQUIRY results,
88 	so ATAPI devices can be used like standard SCSI devices. Further, the
89 	SCSI bus manager can emulate auto-sense by executing a REQUEST SENSE
90 	if <subsys_status> is SCSI_REQ_CMP_ERR and <device_status> is
91 	SCSI_DEVICE_CHECK_CONDITION when a request is finished. This emulation
92 	may be enhanced/generalized in the future.
93 */
94 
95 
96 #include <KernelExport.h>
97 #include <device_manager.h>
98 
99 
100 #define SCSI_MAX_CDB_SIZE 16	// max size of cdb
101 #define SCSI_MAX_SENSE_SIZE	64	// max size of sense data
102 #define SCSI_SIM_PRIV	1536	// SIM private data; this may be a bit much but
103 								// we currently need that for the compatibility layer
104 
105 // bus/device handle
106 typedef struct scsi_bus_info *scsi_bus;
107 typedef struct scsi_device_info *scsi_device;
108 
109 
110 // structure of one scsi i/o CCB (command control block)
111 typedef struct scsi_ccb
112 {
113 	struct scsi_ccb *next, *prev;	// internal
114 
115 	uchar		subsys_status;		// Returned subsystem status
116 	uchar		device_status;		// Returned scsi device status
117 
118 	uchar		path_id;			// Path ID for the request
119 	uchar		target_id;			// Target device ID
120 	uchar		target_lun;			// Target LUN number
121 	uint32		flags;				// Flags for operation of the subsystem
122 
123 	// released once after asynchronous execution of request;
124 	// initialised by alloc_ccb, can be replaced for action but
125 	// must be restored before returning via free_ccb
126 	sem_id		completion_sem;
127 
128 	uint8		cdb[SCSI_MAX_CDB_SIZE];  // command data block
129 	uchar		cdb_len;			// length of command in bytes
130 	int64		sort;				// value of command to sort on (<0 means n/a)
131 	bigtime_t	timeout;			// timeout - 0 = use default
132 
133 	uchar		*data;				// pointer to data
134 	const physical_entry *sg_list;	// SG list
135 	uint16		sg_cnt;				// number of SG entries
136 	uint32		data_len;			// length of data
137 	int32		data_resid;			// data transfer residual length: 2's comp
138 
139 	uchar		sense[SCSI_MAX_SENSE_SIZE]; // autosense data
140 	uchar		sense_resid;		// autosense resid length: 2's comp
141 
142 	// private
143 	bool		ordered : 1;		// request cannot overtake/be overtaken by others
144 	bool		buffered : 1;		// data is buffered to make it DMA safe
145 	bool		emulated : 1;		// command is executed as part of emulation
146 
147 	scsi_bus	bus;				// associated bus
148 	scsi_device	device;				// associated device
149 	struct dma_buffer *dma_buffer;	// used dma buffer, or NULL
150 	uchar 		state;				// bus manager state
151 
152 	// original data before command emulation was applied
153 	uint8		orig_cdb[SCSI_MAX_CDB_SIZE];
154 	uchar		orig_cdb_len;
155 	const physical_entry	*orig_sg_list;
156 	uint16		orig_sg_cnt;
157 	uint32		orig_data_len;
158 
159 	// private SIM data
160 	uchar		sim_state;			// set to zero when request is submitted first time
161 	uchar		sim_priv[SCSI_SIM_PRIV];	/* SIM private data area */
162 } scsi_ccb;
163 
164 
165 // Defines for the subsystem status field
166 
167 #define	SCSI_REQ_INPROG			0x00	/* request is in progress */
168 #define SCSI_REQ_CMP 			0x01	/* request completed w/out error */
169 #define SCSI_REQ_ABORTED		0x02	/* request aborted by the host */
170 #define SCSI_UA_ABORT			0x03	/* Unable to Abort request */
171 #define SCSI_REQ_CMP_ERR		0x04	/* request completed with an err */
172 #define SCSI_BUSY				0x05	/* subsystem is busy */
173 #define SCSI_REQ_INVALID		0x06	/* request is invalid */
174 #define SCSI_PATH_INVALID		0x07	/* Path ID supplied is invalid */
175 #define SCSI_DEV_NOT_THERE		0x08	/* SCSI device not installed/there */
176 #define SCSI_UA_TERMIO			0x09	/* Unable to Terminate I/O req */
177 #define SCSI_SEL_TIMEOUT		0x0A	/* Target selection timeout */
178 #define SCSI_CMD_TIMEOUT		0x0B	/* Command timeout */
179 #define SCSI_MSG_REJECT_REC		0x0D	/* Message reject received */
180 #define SCSI_SCSI_BUS_RESET		0x0E	/* SCSI bus reset sent/received */
181 #define SCSI_UNCOR_PARITY		0x0F	/* Uncorrectable parity err occurred */
182 #define SCSI_AUTOSENSE_FAIL		0x10	/* Autosense: Request sense cmd fail */
183 #define SCSI_NO_HBA				0x11	/* No HBA detected Error */
184 #define SCSI_DATA_RUN_ERR		0x12	/* Data overrun/underrun error */
185 #define SCSI_UNEXP_BUSFREE		0x13	/* Unexpected BUS free */
186 #define SCSI_SEQUENCE_FAIL		0x14	/* Target bus phase sequence failure */
187 #define SCSI_PROVIDE_FAIL		0x16	/* Unable to provide requ. capability */
188 #define SCSI_BDR_SENT			0x17	/* A SCSI BDR msg was sent to target */
189 #define SCSI_REQ_TERMIO			0x18	/* request terminated by the host */
190 #define SCSI_HBA_ERR			0x19	/* Unrecoverable host bus adaptor err*/
191 #define SCSI_BUS_RESET_DENIED	0x1A	/* SCSI bus reset denied */
192 
193 #define SCSI_IDE				0x33	/* Initiator Detected Error Received */
194 #define SCSI_RESRC_UNAVAIL		0x34	/* Resource unavailable */
195 #define SCSI_UNACKED_EVENT		0x35	/* Unacknowledged event by host */
196 #define SCSI_LUN_INVALID		0x38	/* LUN supplied is invalid */
197 #define SCSI_TID_INVALID		0x39	/* Target ID supplied is invalid */
198 #define SCSI_FUNC_NOTAVAIL		0x3A	/* The requ. func is not available */
199 #define SCSI_NO_NEXUS			0x3B	/* Nexus is not established */
200 #define SCSI_IID_INVALID		0x3C	/* The initiator ID is invalid */
201 #define SCSI_CDB_RECVD			0x3D	/* The SCSI CDB has been received */
202 #define SCSI_LUN_ALLREADY_ENAB	0x3E	/* LUN already enabled */
203 #define SCSI_SCSI_BUSY			0x3F	/* SCSI bus busy */
204 
205 #define SCSI_AUTOSNS_VALID		0x80	/* Autosense data valid for target */
206 
207 #define SCSI_SUBSYS_STATUS_MASK 0x3F	/* Mask bits for just the status # */
208 
209 
210 // Defines for the flags field
211 
212 #define SCSI_DIR_RESV			0x00000000	/* Data direction (00: reserved) */
213 #define SCSI_DIR_IN				0x00000040	/* Data direction (01: DATA IN) */
214 #define SCSI_DIR_OUT			0x00000080	/* Data direction (10: DATA OUT) */
215 #define SCSI_DIR_NONE			0x000000C0	/* Data direction (11: no data) */
216 #define SCSI_DIR_MASK			0x000000C0
217 
218 #define SCSI_DIS_AUTOSENSE		0x00000020	/* Disable autosense feature */
219 #define SCSI_ORDERED_QTAG		0x00000010	// ordered queue (cannot overtake/be overtaken)
220 #define SCSI_DMA_SAFE			0x00000008	// set if data buffer is DMA approved
221 
222 #define SCSI_DIS_DISCONNECT		0x00008000	/* Disable disconnect */
223 #define SCSI_INITIATE_SYNC		0x00004000	/* Attempt Sync data xfer, and SDTR */
224 #define SCSI_DIS_SYNC			0x00002000	/* Disable sync, go to async */
225 #define SCSI_ENG_SYNC			0x00000200	/* Flush resid bytes before cmplt */
226 
227 
228 // Defines for the Path Inquiry CCB fields
229 
230 // flags in hba_inquiry
231 #define SCSI_PI_MDP_ABLE		0x80	/* Supports MDP message */
232 #define SCSI_PI_WIDE_32			0x40	/* Supports 32 bit wide SCSI */
233 #define SCSI_PI_WIDE_16			0x20	/* Supports 16 bit wide SCSI */
234 #define SCSI_PI_SDTR_ABLE		0x10	/* Supports SDTR message */
235 #define SCSI_PI_TAG_ABLE		0x02	/* Supports tag queue message */
236 #define SCSI_PI_SOFT_RST		0x01	/* Supports soft reset */
237 
238 // flags in hba_misc
239 #define SCSI_PIM_SCANHILO		0x80	/* Bus scans from ID 7 to ID 0 */
240 #define SCSI_PIM_NOREMOVE		0x40	/* Removable dev not included in scan */
241 
242 // sizes of inquiry fields
243 #define SCSI_VUHBA		14				/* Vendor Unique HBA length */
244 #define SCSI_SIM_ID		16				/* ASCII string len for SIM ID */
245 #define SCSI_HBA_ID		16				/* ASCII string len for HBA ID */
246 #define SCSI_FAM_ID		16				/* ASCII string len for FAMILY ID */
247 #define SCSI_TYPE_ID	16				/* ASCII string len for TYPE ID */
248 #define SCSI_VERS		 8				/* ASCII string len for SIM & HBA vers */
249 
250 
251 // Path inquiry, extended by BeOS XPT_EXTENDED_PATH_INQ parameters
252 typedef struct
253 {
254 	uchar		version_num;			/* Version number for the SIM/HBA */
255 	uchar		hba_inquiry;			/* Mimic of INQ byte 7 for the HBA */
256 	uchar		hba_misc;				/* Misc HBA feature flags */
257 	uint32		sim_priv;				/* Size of SIM private data area */
258 	uchar		vuhba_flags[SCSI_VUHBA];/* Vendor unique capabilities */
259 	uchar		initiator_id;			/* ID of the HBA on the SCSI bus */
260 	uint32		hba_queue_size;			// size of adapaters command queue
261 	char		sim_vid[SCSI_SIM_ID];	/* Vendor ID of the SIM */
262 	char		hba_vid[SCSI_HBA_ID];	/* Vendor ID of the HBA */
263 
264 	char		sim_version[SCSI_VERS];	/* SIM version number */
265 	char		hba_version[SCSI_VERS];	/* HBA version number */
266 	char		controller_family[SCSI_FAM_ID]; /* Controller family */
267 	char		controller_type[SCSI_TYPE_ID]; /* Controller type */
268 } scsi_path_inquiry;
269 
270 
271 // Device node
272 
273 // target (uint8)
274 #define SCSI_DEVICE_TARGET_ID_ITEM "scsi/target_id"
275 // lun (uint8)
276 #define SCSI_DEVICE_TARGET_LUN_ITEM "scsi/target_lun"
277 // node type
278 #define SCSI_DEVICE_TYPE_NAME "scsi/device/v1"
279 // device inquiry data (raw scsi_res_inquiry)
280 #define SCSI_DEVICE_INQUIRY_ITEM "scsi/device_inquiry"
281 // device type (uint8)
282 #define SCSI_DEVICE_TYPE_ITEM "scsi/type"
283 // vendor name (string)
284 #define SCSI_DEVICE_VENDOR_ITEM "scsi/vendor"
285 // product name (string)
286 #define SCSI_DEVICE_PRODUCT_ITEM "scsi/product"
287 // revision (string)
288 #define SCSI_DEVICE_REVISION_ITEM "scsi/revision"
289 
290 // directory containing links to peripheral drivers
291 #define SCSI_PERIPHERAL_DRIVERS_DIR "scsi"
292 
293 // bus manager device interface for peripheral driver
294 typedef struct scsi_device_interface {
295 	driver_module_info info;
296 
297 	// get CCB
298 	// warning: if pool of CCBs is exhausted, this call is delayed until a
299 	// CCB is freed, so don't try to allocate more then one CCB at once!
300 	scsi_ccb *(*alloc_ccb)(scsi_device device);
301 	// free CCB
302 	void (*free_ccb)(scsi_ccb *ccb);
303 
304 	// execute command asynchronously
305 	// when it's finished, the semaphore of the ccb is released
306 	// you must provide a S/G list if data_len != 0
307 	void (*async_io)(scsi_ccb *ccb);
308 	// execute command synchronously
309 	// you don't need to provide a S/G list nor have to lock data
310 	void (*sync_io)(scsi_ccb *ccb);
311 
312 	// abort request
313 	uchar (*abort)(scsi_ccb *ccb_to_abort);
314 	// reset device
315 	uchar (*reset_device)(scsi_device device);
316 	// terminate request
317 	uchar (*term_io)(scsi_ccb *ccb_to_terminate);
318 
319 	status_t (*ioctl)(scsi_device device, uint32 op, void *buffer, size_t length);
320 } scsi_device_interface;
321 
322 #define SCSI_DEVICE_MODULE_NAME "bus_managers/scsi/driver/v1"
323 
324 
325 // Bus node
326 
327 // attributes:
328 
329 // path (uint8)
330 #define SCSI_BUS_PATH_ID_ITEM "scsi/path_id"
331 // node type
332 #define SCSI_BUS_TYPE_NAME "scsi/bus"
333 
334 // SCSI bus node driver.
335 // This interface can be used by peripheral drivers to access the
336 // bus directly.
337 typedef struct scsi_bus_interface {
338 	bus_module_info info;
339 
340 	// get information about host controller
341 	uchar (*path_inquiry)(scsi_bus bus, scsi_path_inquiry *inquiry_data);
342 	// reset SCSI bus
343 	uchar (*reset_bus)(scsi_bus bus);
344 } scsi_bus_interface;
345 
346 // name of SCSI bus node driver
347 #define SCSI_BUS_MODULE_NAME "bus_managers/scsi/bus/v1"
348 
349 
350 // Interface for SIM
351 
352 // cookie for dpc
353 typedef struct scsi_dpc_info *scsi_dpc_cookie;
354 
355 // Bus manager interface used by SCSI controller drivers.
356 // SCSI controller drivers get this interface passed via their init_device
357 // method. Further, they must specify this driver as their fixed consumer.
358 typedef struct scsi_for_sim_interface {
359 	driver_module_info info;
360 
361 	// put request into wait queue because of overflow
362 	// bus_overflow: true - too many bus requests
363 	//               false - too many device requests
364 	// bus/device won't receive requests until cont_sent_bus/cont_send_device
365 	// is called or a request is finished via finished();
366 	// to avoid race conditions (reporting a full and a available bus at once)
367 	// the SIM should synchronize calls to requeue, resubmit and finished
368 	void (*requeue)(scsi_ccb *ccb, bool bus_overflow);
369 	// resubmit request ASAP
370 	// to be used if execution of request went wrong and must be retried
371 	void (*resubmit)(scsi_ccb *ccb);
372 	// mark request as being finished
373 	// num_requests: number of requests that were handled by device
374 	//               when the request was sent (read: how full was the device
375 	//               queue); needed to find out how large the device queue is;
376 	//               e.g. if three were already running plus this request makes
377 	//               num_requests=4
378 	void (*finished)(scsi_ccb *ccb, uint num_requests);
379 
380 	// following functions return error on invalid arguments only
381 	status_t (*alloc_dpc)(scsi_dpc_cookie *dpc);
382 	status_t (*free_dpc)(scsi_dpc_cookie dpc);
383 	status_t (*schedule_dpc)(scsi_bus cookie, scsi_dpc_cookie dpc, /*int flags,*/
384 		void (*func)( void * ), void *arg);
385 
386 	// block entire bus (can be nested)
387 	// no more request will be submitted to this bus
388 	void (*block_bus)(scsi_bus bus);
389 	// unblock entire bus
390 	// requests will be submitted to bus ASAP
391 	void (*unblock_bus)(scsi_bus bus);
392 	// block one device
393 	// no more requests will be submitted to this device
394 	void (*block_device)(scsi_device device);
395 	// unblock device
396 	// requests for this device will be submitted ASAP
397 	void (*unblock_device)(scsi_device device);
398 
399 	// terminate bus overflow condition (see "requeue")
400 	void (*cont_send_bus)(scsi_bus bus);
401 	// terminate device overflow condition (see "requeue")
402 	void (*cont_send_device)(scsi_device device);
403 } scsi_for_sim_interface;
404 
405 
406 #define SCSI_FOR_SIM_MODULE_NAME "bus_managers/scsi/sim/v1"
407 
408 
409 // SIM Node
410 
411 // attributes:
412 
413 // node type
414 #define SCSI_SIM_TYPE_NAME "bus/scsi/v1"
415 // controller name (required, string)
416 #define SCSI_DESCRIPTION_CONTROLLER_NAME "controller_name"
417 
418 typedef struct scsi_sim_cookie *scsi_sim_cookie;
419 
420 // SIM interface
421 // SCSI controller drivers must provide this interface
422 typedef struct scsi_sim_interface {
423 	driver_module_info info;
424 
425 	// execute request
426 	void (*scsi_io)( scsi_sim_cookie cookie, scsi_ccb *ccb );
427 	// abort request
428 	uchar (*abort)( scsi_sim_cookie cookie, scsi_ccb *ccb_to_abort );
429 	// reset device
430 	uchar (*reset_device)( scsi_sim_cookie cookie, uchar target_id, uchar target_lun );
431 	// terminate request
432 	uchar (*term_io)( scsi_sim_cookie cookie, scsi_ccb *ccb_to_terminate );
433 
434 	// get information about bus
435 	uchar (*path_inquiry)( scsi_sim_cookie cookie, scsi_path_inquiry *inquiry_data );
436 	// scan bus
437 	// this is called immediately before the SCSI bus manager scans the bus
438 	uchar (*scan_bus)( scsi_sim_cookie cookie );
439 	// reset bus
440 	uchar (*reset_bus)( scsi_sim_cookie cookie );
441 
442 	// get restrictions of one device
443 	// (used for non-SCSI transport protocols and bug fixes)
444 	void (*get_restrictions)(
445 		scsi_sim_cookie 	cookie,
446 		uchar				target_id,		// target id
447 		bool				*is_atapi, 		// set to true if this is an ATAPI device that
448 											// needs some commands emulated
449 		bool				*no_autosense,	// set to true if there is no autosense;
450 											// the SCSI bus manager will request sense on
451 											// SCSI_REQ_CMP_ERR/SCSI_DEVICE_CHECK_CONDITION
452 		uint32 				*max_blocks );	// maximum number of blocks per transfer if > 0;
453 											// used for buggy devices that cannot handle
454 											// large transfers (read: ATAPI ZIP drives)
455 
456 	status_t (*ioctl)(scsi_sim_cookie, uint8 targetID, uint32 op, void *buffer, size_t length);
457 } scsi_sim_interface;
458 
459 
460 #endif	/* _SCSI_BUSMANAGER_H_ */
461