1/*
2 * Copyright 2004-2008, 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_count>. 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_STATUS_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
106typedef struct scsi_bus_info *scsi_bus;
107typedef struct scsi_device_info *scsi_device;
108
109
110// structure of one scsi i/o CCB (command control block)
111typedef struct scsi_ccb {
112	struct scsi_ccb *next, *prev;	// internal
113
114	uchar		subsys_status;		// Returned subsystem status
115	uchar		device_status;		// Returned scsi device status
116
117	uchar		path_id;			// Path ID for the request
118	uchar		target_id;			// Target device ID
119	uchar		target_lun;			// Target LUN number
120	uint32		flags;				// Flags for operation of the subsystem
121
122	// released once after asynchronous execution of request;
123	// initialised by alloc_ccb, can be replaced for action but
124	// must be restored before returning via free_ccb
125	sem_id		completion_sem;
126
127	uint8		cdb[SCSI_MAX_CDB_SIZE];  // command data block
128	uchar		cdb_length;			// length of command in bytes
129	int64		sort;				// value of command to sort on (<0 means n/a)
130	bigtime_t	timeout;			// timeout - 0 = use default
131
132	uchar		*data;				// pointer to data
133	const physical_entry *sg_list;	// scatter/gather list
134	uint16		sg_count;			// number of S/G entries
135	uint32		data_length;		// length of data
136	int32		data_resid;			// data transfer residual length: 2's comp
137	void		*io_operation;
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_length;
155	const physical_entry *orig_sg_list;
156	uint16		orig_sg_count;
157	uint32		orig_data_length;
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
252typedef struct {
253	uchar		version_num;			/* Version number for the SIM/HBA */
254	uchar		hba_inquiry;			/* Mimic of INQ byte 7 for the HBA */
255	uchar		hba_misc;				/* Misc HBA feature flags */
256	uint32		sim_priv;				/* Size of SIM private data area */
257	uchar		vuhba_flags[SCSI_VUHBA];/* Vendor unique capabilities */
258	uchar		initiator_id;			/* ID of the HBA on the SCSI bus */
259	uint32		hba_queue_size;			// size of adapters command queue
260	char		sim_vid[SCSI_SIM_ID];	/* Vendor ID of the SIM */
261	char		hba_vid[SCSI_HBA_ID];	/* Vendor ID of the HBA */
262
263	char		sim_version[SCSI_VERS];	/* SIM version number */
264	char		hba_version[SCSI_VERS];	/* HBA version number */
265	char		controller_family[SCSI_FAM_ID]; /* Controller family */
266	char		controller_type[SCSI_TYPE_ID]; /* Controller type */
267} scsi_path_inquiry;
268
269
270// Device node
271
272// target (uint8)
273#define SCSI_DEVICE_TARGET_ID_ITEM "scsi/target_id"
274// lun (uint8)
275#define SCSI_DEVICE_TARGET_LUN_ITEM "scsi/target_lun"
276// node type
277#define SCSI_DEVICE_TYPE_NAME "scsi/device/v1"
278// device inquiry data (raw scsi_res_inquiry)
279#define SCSI_DEVICE_INQUIRY_ITEM "scsi/device_inquiry"
280// device type (uint8)
281#define SCSI_DEVICE_TYPE_ITEM "scsi/type"
282// vendor name (string)
283#define SCSI_DEVICE_VENDOR_ITEM "scsi/vendor"
284// product name (string)
285#define SCSI_DEVICE_PRODUCT_ITEM "scsi/product"
286// revision (string)
287#define SCSI_DEVICE_REVISION_ITEM "scsi/revision"
288
289// maximum targets on scsi bus
290#define SCSI_DEVICE_MAX_TARGET_COUNT "scsi/max_target_count"
291// maximum luns on scsi bus
292#define SCSI_DEVICE_MAX_LUN_COUNT "scsi/max_lun_count"
293
294// directory containing links to peripheral drivers
295#define SCSI_PERIPHERAL_DRIVERS_DIR "scsi"
296
297// bus manager device interface for peripheral driver
298typedef struct scsi_device_interface {
299	driver_module_info info;
300
301	// get CCB
302	// warning: if pool of CCBs is exhausted, this call is delayed until a
303	// CCB is freed, so don't try to allocate more then one CCB at once!
304	scsi_ccb *(*alloc_ccb)(scsi_device device);
305	// free CCB
306	void (*free_ccb)(scsi_ccb *ccb);
307
308	// execute command asynchronously
309	// when it's finished, the semaphore of the ccb is released
310	// you must provide a S/G list if data_len != 0
311	void (*async_io)(scsi_ccb *ccb);
312	// execute command synchronously
313	// you don't need to provide a S/G list nor have to lock data
314	void (*sync_io)(scsi_ccb *ccb);
315
316	// abort request
317	uchar (*abort)(scsi_ccb *ccb_to_abort);
318	// reset device
319	uchar (*reset_device)(scsi_device device);
320	// terminate request
321	uchar (*term_io)(scsi_ccb *ccb_to_terminate);
322
323	status_t (*ioctl)(scsi_device device, uint32 op, void *buffer, size_t length);
324} scsi_device_interface;
325
326#define SCSI_DEVICE_MODULE_NAME "bus_managers/scsi/device/driver_v1"
327
328
329// Bus node
330
331// attributes:
332
333// path (uint8)
334#define SCSI_BUS_PATH_ID_ITEM "scsi/path_id"
335// node type
336#define SCSI_BUS_TYPE_NAME "scsi/bus"
337
338// SCSI bus node driver.
339// This interface can be used by peripheral drivers to access the
340// bus directly.
341typedef struct scsi_bus_interface {
342	driver_module_info info;
343
344	// get information about host controller
345	uchar (*path_inquiry)(scsi_bus bus, scsi_path_inquiry *inquiry_data);
346	// reset SCSI bus
347	uchar (*reset_bus)(scsi_bus bus);
348} scsi_bus_interface;
349
350// name of SCSI bus node driver
351#define SCSI_BUS_MODULE_NAME "bus_managers/scsi/bus/driver_v1"
352
353
354// Interface for SIM
355
356// cookie for dpc
357typedef struct scsi_dpc_info *scsi_dpc_cookie;
358
359// Bus manager interface used by SCSI controller drivers.
360// SCSI controller drivers get this interface passed via their init_device
361// method. Further, they must specify this driver as their fixed consumer.
362typedef struct scsi_for_sim_interface {
363	driver_module_info info;
364
365	// put request into wait queue because of overflow
366	// bus_overflow: true - too many bus requests
367	//               false - too many device requests
368	// bus/device won't receive requests until cont_sent_bus/cont_send_device
369	// is called or a request is finished via finished();
370	// to avoid race conditions (reporting a full and a available bus at once)
371	// the SIM should synchronize calls to requeue, resubmit and finished
372	void (*requeue)(scsi_ccb *ccb, bool bus_overflow);
373	// resubmit request ASAP
374	// to be used if execution of request went wrong and must be retried
375	void (*resubmit)(scsi_ccb *ccb);
376	// mark request as being finished
377	// num_requests: number of requests that were handled by device
378	//               when the request was sent (read: how full was the device
379	//               queue); needed to find out how large the device queue is;
380	//               e.g. if three were already running plus this request makes
381	//               num_requests=4
382	void (*finished)(scsi_ccb *ccb, uint num_requests);
383
384	// following functions return error on invalid arguments only
385	status_t (*alloc_dpc)(scsi_dpc_cookie *dpc);
386	status_t (*free_dpc)(scsi_dpc_cookie dpc);
387	status_t (*schedule_dpc)(scsi_bus cookie, scsi_dpc_cookie dpc, /*int flags,*/
388		void (*func)( void * ), void *arg);
389
390	// block entire bus (can be nested)
391	// no more request will be submitted to this bus
392	void (*block_bus)(scsi_bus bus);
393	// unblock entire bus
394	// requests will be submitted to bus ASAP
395	void (*unblock_bus)(scsi_bus bus);
396	// block one device
397	// no more requests will be submitted to this device
398	void (*block_device)(scsi_device device);
399	// unblock device
400	// requests for this device will be submitted ASAP
401	void (*unblock_device)(scsi_device device);
402
403	// terminate bus overflow condition (see "requeue")
404	void (*cont_send_bus)(scsi_bus bus);
405	// terminate device overflow condition (see "requeue")
406	void (*cont_send_device)(scsi_device device);
407} scsi_for_sim_interface;
408
409
410#define SCSI_FOR_SIM_MODULE_NAME "bus_managers/scsi/sim/driver_v1"
411
412
413// SIM Node
414
415// attributes:
416
417// node type
418#define SCSI_SIM_TYPE_NAME "bus/scsi/v1"
419// controller name (required, string)
420#define SCSI_DESCRIPTION_CONTROLLER_NAME "controller_name"
421
422typedef void *scsi_sim_cookie;
423
424// SIM interface
425// SCSI controller drivers must provide this interface
426typedef struct scsi_sim_interface {
427	driver_module_info info;
428
429	void (*set_scsi_bus)(scsi_sim_cookie cookie, scsi_bus bus);
430
431	// execute request
432	void (*scsi_io)(scsi_sim_cookie cookie, scsi_ccb *ccb);
433	// abort request
434	uchar (*abort)(scsi_sim_cookie cookie, scsi_ccb *ccb_to_abort);
435	// reset device
436	uchar (*reset_device)(scsi_sim_cookie cookie, uchar target_id, uchar target_lun);
437	// terminate request
438	uchar (*term_io)(scsi_sim_cookie cookie, scsi_ccb *ccb_to_terminate);
439
440	// get information about bus
441	uchar (*path_inquiry)(scsi_sim_cookie cookie, scsi_path_inquiry *inquiry_data);
442	// scan bus
443	// this is called immediately before the SCSI bus manager scans the bus
444	uchar (*scan_bus)(scsi_sim_cookie cookie);
445	// reset bus
446	uchar (*reset_bus)(scsi_sim_cookie cookie);
447
448	// get restrictions of one device
449	// (used for non-SCSI transport protocols and bug fixes)
450	void (*get_restrictions)(scsi_sim_cookie 	cookie,
451		uchar				target_id,		// target id
452		bool				*is_atapi, 		// set to true if this is an ATAPI device that
453											// needs some commands emulated
454		bool				*no_autosense,	// set to true if there is no autosense;
455											// the SCSI bus manager will request sense on
456											// SCSI_REQ_CMP_ERR/SCSI_STATUS_CHECK_CONDITION
457		uint32 				*max_blocks );	// maximum number of blocks per transfer if > 0;
458											// used for buggy devices that cannot handle
459											// large transfers (read: ATAPI ZIP drives)
460
461	status_t (*ioctl)(scsi_sim_cookie, uint8 targetID, uint32 op, void *buffer, size_t length);
462} scsi_sim_interface;
463
464
465#endif	/* _SCSI_BUSMANAGER_H */
466