1/*
2 * Copyright 2009, Haiku, Inc. All rights reserved.
3 * Distributed under the terms of the MIT License.
4 *
5 *
6 * Definitions for the SCSI Common Access Method as implemented in Haiku.
7 *
8 * See also "Draft Proposed American National Standard, SCSI-2 Common
9 * Access Method Transport and SCSI Interface Module", Revision 12,
10 * ANSI refernce number X3.232-199x.
11 *
12*/
13
14#ifndef _CAM_H
15#define _CAM_H
16
17#include <bus_manager.h>
18
19#include <sys/types.h>
20
21
22#ifdef __cplusplus
23extern "C" {
24#endif
25
26#ifndef U32
27typedef uint32 U32;
28#endif
29
30#ifndef I32
31typedef int32 I32;
32#endif
33
34#ifndef U16
35typedef uint16 U16;
36#endif
37
38/* Haiku specific additions */
39
40typedef struct {
41	uint32	serial;		/* operation serial number                    */
42	uint32	micros;		/* operation time in microseconds (4294s max) */
43	uint32	bytes;		/* number of bytes to transfer                */
44	uchar	path;		/* target SIM ID                              */
45	uchar	target;		/* target device ID                           */
46	uchar	sgcount;	/* # of sg segments (0 if non-sg operation)   */
47	uchar	scsi_op;	/* scsi operation byte                        */
48} cam_iostat;
49
50/* End of Haiku specific additions */
51
52/* Defines for the XPT function codes, Table 8-2 in the CAM spec. */
53
54/* Common function commands, 0x00 - 0x0F */
55#define XPT_NOOP		0x00	/* Execute Nothing */
56#define XPT_SCSI_IO		0x01	/* Execute the requested SCSI IO */
57#define XPT_GDEV_TYPE	0x02	/* Get the device type information */
58#define XPT_PATH_INQ	0x03	/* Path Inquiry */
59#define XPT_REL_SIMQ	0x04	/* Release the SIM queue that is frozen */
60#define XPT_SASYNC_CB	0x05	/* Set Async callback parameters */
61#define XPT_SDEV_TYPE	0x06	/* Set the device type information */
62#define XPT_SCAN_BUS	0x07	/* Scan the Scsi Bus */
63
64/* XPT SCSI control functions, 0x10 - 0x1F */
65#define XPT_ABORT		0x10	/* Abort the selected CCB */
66#define XPT_RESET_BUS	0x11	/* Reset the SCSI bus */
67#define XPT_RESET_DEV	0x12	/* Reset the SCSI device, BDR */
68#define XPT_TERM_IO		0x13	/* Terminate the I/O process */
69
70/* HBA engine commands, 0x20 - 0x2F */
71#define XPT_ENG_INQ		0x20	/* HBA engine inquiry */
72#define XPT_ENG_EXEC	0x21	/* HBA execute engine request */
73
74/* Target mode commands, 0x30 - 0x3F */
75#define XPT_EN_LUN		0x30	/* Enable LUN, Target mode support */
76#define XPT_TARGET_IO	0x31	/* Execute the target IO request */
77#define XPT_ACCEPT_TARG 0x32	/* Accept Host Target Mode CDB */
78#define XPT_CONT_TARG	0x33	/* Cont. Host Target I/O Connection */
79#define XPT_IMMED_NOTIFY 0x34	/* Notify Host Target driver of event*/
80#define XPT_NOTIFY_ACK	0x35	/* Acknowledgement of event */
81
82#define XPT_FUNC		0x7F	/* TEMPLATE */
83#define XPT_VUNIQUE		0x80	/* All the rest are vendor unique commands */
84
85/* General allocation length defines for the CCB structures. */
86
87#define IOCDBLEN	12	/* Space for the CDB bytes/pointer */
88#define VUHBA		14	/* Vendor Unique HBA length */
89#define SIM_ID		16	/* ASCII string len for SIM ID */
90#define HBA_ID		16	/* ASCII string len for HBA ID */
91
92#define BE_SIM_CCB_SIZE		1536	/* we want to allocate 1.5k chunks */
93#define BE_SIM_SCSIIO_SIZE	88		/* sizeof(CAM_CCB_SCSIIO) - SIM_PRIV */
94#define SIM_PRIV	(BE_SIM_CCB_SIZE - BE_SIM_SCSIIO_SIZE) /* Length of SIM private data area */
95
96/* SIM_PRIV (sim private data area)  Terms and Conditions:
97
98 - the size of SIM_PRIV shall be such that sizeof(CCB_SIZE_UNION) = 1.5k
99 - all CCB's shall be allocated from locked, contiguous memory
100 - CCB's shall be aligned on 512 byte boundaries
101 - SIM_PRIV will be >= 1408 bytes
102 - this provides 128  8byte sg entries (512mb worth of pages, worstcase fragmentation)
103 - and 256 bytes for sense data and 128 bytes for whatever else the SIM needs
104
105 - These conditions are NULL and (void) where prohibited by law.
106 - All sales are final.
107 - Do not use near open flame.
108*/
109
110/* Structure definitions for the CAM control blocks, CCB's for the
111subsystem. */
112
113/* Common CCB header definition. */
114typedef struct ccb_header
115{
116	uint32		phys_addr;		/* physical address of this CCB */
117	uint16		cam_ccb_len;	/* Length of the entire CCB */
118	uchar		cam_func_code;	/* XPT function code */
119	uchar		cam_status;		/* Returned CAM subsystem status */
120	uchar		cam_hrsvd0;		/* Reserved field, for alignment */
121	uchar		cam_path_id;	/* Path ID for the request */
122	uchar		cam_target_id;	/* Target device ID */
123	uchar		cam_target_lun;	/* Target LUN number */
124	uint32		cam_flags;		/* Flags for operation of the subsystem */
125} CCB_HEADER;
126
127/* Common SCSI functions. */
128
129/* Union definition for the CDB space in the SCSI I/O request CCB */
130typedef union cdb_un
131{
132	uchar*	cam_cdb_ptr;				/* Pointer to the CDB bytes to send */
133	uchar	cam_cdb_bytes[IOCDBLEN];	/* Area for the CDB to send */
134} CDB_UN;
135
136/* Get device type CCB */
137typedef struct ccb_getdev
138{
139	CCB_HEADER	cam_ch;			/* Header information fields */
140	char*		cam_inq_data;	/* Ptr to the inquiry data space */
141	uchar		cam_pd_type;	/* Periph device type from the TLUN */
142} CCB_GETDEV;
143
144/* Path inquiry CCB */
145typedef struct ccb_pathinq
146{
147	CCB_HEADER	cam_ch;						/* Header information fields */
148	uchar		cam_version_num;			/* Version number for the SIM/HBA */
149	uchar		cam_hba_inquiry;			/* Mimic of INQ byte 7 for the HBA */
150	uchar		cam_target_sprt;			/* Flags for target mode support */
151	uchar		cam_hba_misc;				/* Misc HBA feature flags */
152	uint16		cam_hba_eng_cnt;			/* HBA engine count */
153	uchar		cam_vuhba_flags[VUHBA];		/* Vendor unique capabilities */
154	uint32		cam_sim_priv;				/* Size of SIM private data area */
155	uint32		cam_async_flags;			/* Event cap. for Async Callback */
156	uchar		cam_hpath_id;				/* Highest path ID in the subsystem */
157	uchar		cam_initiator_id;			/* ID of the HBA on the SCSI bus */
158	uchar		cam_prsvd0;					/* Reserved field, for alignment */
159	uchar		cam_prsvd1;					/* Reserved field, for alignment */
160	char		cam_sim_vid[SIM_ID];		/* Vendor ID of the SIM */
161	char		cam_hba_vid[HBA_ID];		/* Vendor ID of the HBA */
162	uchar*		cam_osd_usage;				/* Ptr for the OSD specific area */
163} CCB_PATHINQ;
164
165/* Release SIM Queue CCB */
166typedef struct ccb_relsim
167{
168	CCB_HEADER	cam_ch;				/* Header information fields */
169} CCB_RELSIM;
170
171/* SCSI I/O Request CCB */
172typedef struct ccb_scsiio
173{
174	CCB_HEADER	cam_ch;				/* Header information fields */
175	uchar*		cam_pdrv_ptr;		/* Ptr used by the Peripheral driver */
176	CCB_HEADER*	cam_next_ccb;		/* Ptr to the next CCB for action */
177	uchar*		cam_req_map;		/* Ptr for mapping info on the Req. */
178	void		(*cam_cbfcnp)(struct ccb_scsiio*);
179									/* Callback on completion function */
180	uchar*		cam_data_ptr;		/* Pointer to the data buf/SG list */
181	uint32		cam_dxfer_len;		/* Data xfer length */
182	uchar*		cam_sense_ptr;		/* Pointer to the sense data buffer */
183	uchar		cam_sense_len;		/* Num of bytes in the Autosense buf */
184	uchar		cam_cdb_len;		/* Number of bytes for the CDB */
185	uint16		cam_sglist_cnt;		/* Num of scatter gather list entries */
186	uint32		cam_sort;			/* Value used by SIM to sort on */
187	uchar		cam_scsi_status;	/* Returned scsi device status */
188	uchar		cam_sense_resid;	/* Autosense resid length: 2's comp */
189	uchar		cam_osd_rsvd1[2];	/* OSD Reserved field, for alignment */
190	int32		cam_resid;			/* Transfer residual length: 2's comp */
191	CDB_UN		cam_cdb_io;			/* Union for CDB bytes/pointer */
192	uint32		cam_timeout;		/* Timeout value */
193	uchar*		cam_msg_ptr;		/* Pointer to the message buffer */
194	uint16		cam_msgb_len;		/* Num of bytes in the message buf */
195	uint16		cam_vu_flags;		/* Vendor unique flags */
196	uchar		cam_tag_action;		/* What to do for tag queuing */
197	uchar		cam_iorsvd0[3];		/* Reserved field, for alignment */
198	uchar		cam_sim_priv[SIM_PRIV];	/* SIM private data area */
199} CCB_SCSIIO;
200
201/* Set Async Callback CCB */
202typedef struct ccb_setasync
203{
204	CCB_HEADER	cam_ch;					/* Header information fields */
205	uint32		cam_async_flags;		/* Event enables for Callback resp */
206	void		(*cam_async_func)();	/* Async Callback function address */
207	uchar*		pdrv_buf;				/* Buffer set aside by the Per. drv */
208	uchar		pdrv_buf_len;			/* The size of the buffer */
209} CCB_SETASYNC;
210
211/* Set device type CCB */
212typedef struct ccb_setdev
213{
214	CCB_HEADER	cam_ch;				/* Header information fields */
215	uchar		cam_dev_type;		/* Val for the dev type field in EDT */
216} CCB_SETDEV;
217
218/* SCSI Control Functions. */
219
220/* Abort XPT Request CCB */
221typedef struct ccb_abort
222{
223	CCB_HEADER	cam_ch;					/* Header information fields */
224	CCB_HEADER*	cam_abort_ch;			/* Pointer to the CCB to abort */
225} CCB_ABORT;
226
227/* Reset SCSI Bus CCB */
228typedef struct ccb_resetbus
229{
230	CCB_HEADER	cam_ch;					/* Header information fields */
231} CCB_RESETBUS;
232
233/* Reset SCSI Device CCB */
234typedef struct ccb_resetdev
235{
236	CCB_HEADER	cam_ch;					/* Header information fields */
237} CCB_RESETDEV;
238
239/* Terminate I/O Process Request CCB */
240typedef struct ccb_termio
241{
242	CCB_HEADER	cam_ch;					/* Header information fields */
243	CCB_HEADER*	cam_termio_ch;			/* Pointer to the CCB to terminate */
244} CCB_TERMIO;
245
246/* Target mode structures. */
247
248/* Host Target Mode Version 1 Enable LUN CCB */
249typedef struct ccb_en_lun
250{
251	CCB_HEADER	cam_ch;					/* Header information fields */
252	uint16		cam_grp6_len;			/* Group 6 VU CDB length */
253	uint16		cam_grp7_len;			/* Group 7 VU CDB length */
254	uchar*		cam_ccb_listptr;		/* Pointer to the target CCB list */
255	uint16		cam_ccb_listcnt;		/* Count of Target CCBs in the list */
256} CCB_EN_LUN;
257
258/* Enable LUN CCB (HTM V2) */
259typedef struct ccb_enable_lun
260{
261	CCB_HEADER	cam_ch;					/* Header information fields */
262	uint16		cam_grp6_length;		/* Group 6 Vendor Unique CDB Lengths */
263	uint16		cam_grp7_length;		/* Group 7 Vendor Unique CDB Lengths */
264	uchar*		cam_immed_notify_list;	/* Ptr to Immediate Notify CCB list */
265	uint32		cam_immed_notify_cnt;	/* Number of Immediate Notify CCBs */
266	uchar*		cam_accept_targ_list;	/* Ptr to Accept Target I/O CCB list */
267	uint32		cam_accept_targ_cnt;	/* Number of Accept Target I/O CCBs */
268	uchar		cam_sim_priv[SIM_PRIV];	/* SIM private data area */
269} CCB_ENABLE_LUN;
270
271/* Immediate Notify CCB */
272typedef struct ccb_immed_notify
273{
274	CCB_HEADER	cam_ch;					/* Header information fields */
275	uchar*		cam_pdrv_ptr;			/* Ptr used by the Peripheral driver */
276	void		(*cam_cbfnot)();		/* Callback on notification function */
277	uchar*		cam_sense_ptr;			/* Pointer to the sense data buffer */
278	uchar		cam_sense_len;			/* Num of bytes in the Autosense buf */
279	uchar		cam_init_id;			/* ID of Initiator that selected */
280	uint16		cam_seq_id;				/* Sequence Identifier */
281	uchar		cam_msg_code;			/* Message Code */
282	uchar		cam_msg_args[7];		/* Message Arguments */
283} CCB_IMMED_NOTIFY;
284
285/* Notify Acknowledge CCB */
286typedef struct ccb_notify_ack
287{
288	CCB_HEADER	cam_ch;					/* Header information fields */
289	uint16		cam_seq_id;				/* Sequence Identifier */
290	uchar		cam_event;				/* Event */
291	uchar		cam_rsvd;
292} CCB_NOTIFY_ACK;
293
294/* Accept Target I/O CCB */
295typedef struct ccb_accept_targ
296{
297	CCB_HEADER	cam_ch;					/* Header information fields */
298	uchar*		cam_pdrv_ptr;			/* Ptr used by the Peripheral driver */
299	CCB_HEADER*	cam_next_ccb;			/* Ptr to the next CCB for action */
300	uchar*		cam_req_map;			/* Ptr for mapping info on the Req. */
301	void		(*cam_cbfcnot)();		/* Callback on completion function */
302	uchar*		cam_data_ptr;			/* Pointer to the data buf/SG list */
303	uint32		cam_dxfer_len;			/* Data xfer length */
304	uchar*		cam_sense_ptr;			/* Pointer to the sense data buffer */
305	uchar		cam_sense_len;			/* Num of bytes in the Autosense buf */
306	uchar		cam_cdb_len;			/* Number of bytes for the CDB */
307	uint16		cam_sglist_cnt;			/* Num of scatter gather list entries */
308	uint32  	cam_sort;				/* Value used by SIM to sort on */
309	uchar		cam_scsi_status;		/* Returned scsi device status */
310	uchar		cam_sense_resid;		/* Autosense resid length: 2's comp */
311	uchar		cam_osd_rsvd1[2];		/* OSD Reserved field, for alignment */
312	int32		cam_resid;				/* Transfer residual length: 2's comp */
313	CDB_UN		cam_cdb_io;				/* Union for CDB bytes/pointer */
314	uint32		cam_timeout;			/* Timeout value */
315	uchar*		cam_msg_ptr;			/* Pointer to the message buffer */
316	uint16		cam_msgb_len;			/* Num of bytes in the message buf */
317	uint16		cam_vu_flags;			/* Vendor unique flags */
318	uchar		cam_tag_action;			/* What to do for tag queuing */
319	uchar		cam_tag_id;				/* Tag ID */
320	uchar		cam_initiator_id;		/* Initiator ID */
321	uchar		cam_iorsvd0[1];			/* Reserved field, for alignment */
322	uchar		cam_sim_priv[SIM_PRIV];	/* SIM private data area */
323} CCB_ACCEPT_TARG;
324
325/* Continue Target I/O CCB */
326typedef CCB_ACCEPT_TARG CCB_CONT_TARG;
327
328/* HBA engine structures. */
329
330typedef struct ccb_eng_inq
331{
332	CCB_HEADER	cam_ch;					/* Header information fields */
333	uint16		cam_eng_num;			/* The number for this inquiry */
334	uchar		cam_eng_type;			/* Returned engine type */
335	uchar		cam_eng_algo;			/* Returned algorithm type */
336	uint32		cam_eng_memory;			/* Returned engine memory size */
337} CCB_ENG_INQ;
338
339typedef struct ccb_eng_exec	/* NOTE: must match SCSIIO size */
340{
341	CCB_HEADER	cam_ch;					/* Header information fields */
342	uchar*		cam_pdrv_ptr;			/* Ptr used by the Peripheral driver */
343	uint32		cam_engrsvd0;			/* Reserved field, for alignment */
344	uchar*		cam_req_map;			/* Ptr for mapping info on the Req. */
345	void		(*cam_cbfcnp)();		/* Callback on completion function */
346	uchar*		cam_data_ptr;			/* Pointer to the data buf/SG list */
347	uint32		cam_dxfer_len;			/* Data xfer length */
348	uchar*		cam_engdata_ptr;		/* Pointer to the engine buffer data */
349	uchar		cam_engrsvd1;			/* Reserved field, for alignment */
350	uchar		cam_engrsvd2;			/* Reserved field, for alignment */
351	uint16		cam_sglist_cnt;			/* Num of scatter gather list entries */
352	uint32		cam_dmax_len;			/* Destination data maximum length */
353	uint32		cam_dest_len;			/* Destination data length */
354	int32		cam_src_resid;			/* Source residual length: 2's comp */
355	uchar		cam_engrsvd3[12];		/* Reserved field, for alignment */
356	uint32		cam_timeout;			/* Timeout value */
357	uint32		cam_engrsvd4;			/* Reserved field, for alignment */
358	uint16		cam_eng_num;			/* Engine number for this request */
359	uint16		cam_vu_flags;			/* Vendor unique flags */
360	uchar		cam_engrsvd5;			/* Reserved field, for alignment */
361	uchar		cam_engrsvd6[3];		/* Reserved field, for alignment */
362	uchar		cam_sim_priv[SIM_PRIV]; /* SIM private data area */
363} CCB_ENG_EXEC;
364
365/* The sim_module_info definition is used to define the entry points for
366the SIMs contained in the SCSI CAM subsystem.	Each SIM file will
367contain a declaration for it's entry.	The address for this entry will
368be stored in the cam_conftbl[] array along will all the other SIM
369entries. */
370
371typedef struct sim_module_info sim_module_info;
372
373struct sim_module_info {
374	module_info	minfo;
375};
376
377typedef struct CAM_SIM_ENTRY CAM_SIM_ENTRY;
378
379struct CAM_SIM_ENTRY {
380	status_t	(*sim_init)();
381	int32		(*sim_action)();
382};
383
384/* ---------------------------------------------------------------------- */
385
386/* Defines for the CAM status field in the CCB header. */
387
388#define	CAM_REQ_INPROG			0x00	/* CCB request is in progress */
389#define CAM_REQ_CMP 			0x01	/* CCB request completed w/out error */
390#define CAM_REQ_ABORTED			0x02	/* CCB request aborted by the host */
391#define CAM_UA_ABORT			0x03	/* Unable to Abort CCB request */
392#define CAM_REQ_CMP_ERR			0x04	/* CCB request completed with an err */
393#define CAM_BUSY				0x05	/* CAM subsystem is busy */
394#define CAM_REQ_INVALID			0x06	/* CCB request is invalid */
395#define CAM_PATH_INVALID		0x07	/* Path ID supplied is invalid */
396#define CAM_DEV_NOT_THERE		0x08	/* SCSI device not installed/there */
397#define CAM_UA_TERMIO			0x09	/* Unable to Terminate I/O CCB req */
398#define CAM_SEL_TIMEOUT			0x0A	/* Target selection timeout */
399#define CAM_CMD_TIMEOUT			0x0B	/* Command timeout */
400#define CAM_MSG_REJECT_REC		0x0D	/* Message reject received */
401#define CAM_SCSI_BUS_RESET		0x0E	/* SCSI bus reset sent/received */
402#define CAM_UNCOR_PARITY		0x0F	/* Uncorrectable parity err occurred */
403#define CAM_AUTOSENSE_FAIL		0x10	/* Autosense: Request sense cmd fail */
404#define CAM_NO_HBA				0x11	/* No HBA detected Error */
405#define CAM_DATA_RUN_ERR		0x12	/* Data overrun/underrun error */
406#define CAM_UNEXP_BUSFREE		0x13	/* Unexpected BUS free */
407#define CAM_SEQUENCE_FAIL		0x14	/* Target bus phase sequence failure */
408#define CAM_CCB_LEN_ERR			0x15	/* CCB length supplied is inadequate */
409#define CAM_PROVIDE_FAIL		0x16	/* Unable to provide requ. capability */
410#define CAM_BDR_SENT			0x17	/* A SCSI BDR msg was sent to target */
411#define CAM_REQ_TERMIO			0x18	/* CCB request terminated by the host */
412#define CAM_HBA_ERR				0x19	/* Unrecoverable host bus adaptor err*/
413#define CAM_BUS_RESET_DENIED	0x1A	/* SCSI bus reset denied */
414
415#define CAM_IDE					0x33	/* Initiator Detected Error Received */
416#define CAM_RESRC_UNAVAIL		0x34	/* Resource unavailable */
417#define CAM_UNACKED_EVENT		0x35	/* Unacknowledged event by host */
418#define CAM_MESSAGE_RECV		0x36	/* Msg received in Host Target Mode */
419#define CAM_INVALID_CDB			0x37	/* Invalid CDB recvd in HT Mode */
420#define CAM_LUN_INVALID			0x38	/* LUN supplied is invalid */
421#define CAM_TID_INVALID			0x39	/* Target ID supplied is invalid */
422#define CAM_FUNC_NOTAVAIL		0x3A	/* The requ. func is not available */
423#define CAM_NO_NEXUS			0x3B	/* Nexus is not established */
424#define CAM_IID_INVALID			0x3C	/* The initiator ID is invalid */
425#define CAM_CDB_RECVD			0x3D	/* The SCSI CDB has been received */
426#define CAM_LUN_ALLREADY_ENAB	0x3E	/* LUN already enabled */
427#define CAM_SCSI_BUSY			0x3F	/* SCSI bus busy */
428
429#define CAM_SIM_QFRZN			0x40	/* The SIM queue is frozen w/this err */
430#define CAM_AUTOSNS_VALID		0x80	/* Autosense data valid for target */
431
432#define CAM_STATUS_MASK			0x3F	/* Mask bits for just the status # */
433
434/* ---------------------------------------------------------------------- */
435
436/* Defines for the CAM flags field in the CCB header. */
437
438#define CAM_DIR_RESV			0x00000000	/* Data direction (00: reserved) */
439#define CAM_DIR_IN				0x00000040	/* Data direction (01: DATA IN) */
440#define CAM_DIR_OUT				0x00000080	/* Data direction (10: DATA OUT) */
441#define CAM_DIR_NONE			0x000000C0	/* Data direction (11: no data) */
442#define CAM_DIS_AUTOSENSE		0x00000020	/* Disable autosense feature */
443#define CAM_SCATTER_VALID		0x00000010	/* Scatter/gather list is valid */
444#define CAM_DIS_CALLBACK		0x00000008	/* Disable callback feature */
445#define CAM_CDB_LINKED			0x00000004	/* The CCB contains a linked CDB */
446#define CAM_QUEUE_ENABLE		0x00000002	/* SIM queue actions are enabled */
447#define CAM_CDB_POINTER			0x00000001	/* The CDB field contains a pointer */
448
449#define CAM_DIS_DISCONNECT 		0x00008000	/* Disable disconnect */
450#define CAM_INITIATE_SYNC		0x00004000	/* Attempt Sync data xfer, and SDTR */
451#define CAM_DIS_SYNC			0x00002000	/* Disable sync, go to async */
452#define CAM_SIM_QHEAD			0x00001000	/* Place CCB at the head of SIM Q */
453#define CAM_SIM_QFREEZE			0x00000800	/* Return the SIM Q to frozen state */
454#define CAM_SIM_QFRZDIS			0x00000400	/* Disable the SIM Q frozen state */
455#define CAM_ENG_SYNC			0x00000200	/* Flush resid bytes before cmplt */
456
457#define CAM_ENG_SGLIST			0x00800000	/* The SG list is for the HBA engine */
458#define CAM_CDB_PHYS			0x00400000	/* CDB pointer is physical */
459#define CAM_DATA_PHYS			0x00200000	/* SG/Buffer data ptrs are physical */
460#define CAM_SNS_BUF_PHYS		0x00100000	/* Autosense data ptr is physical */
461#define CAM_MSG_BUF_PHYS		0x00080000	/* Message buffer ptr is physical */
462#define CAM_NXT_CCB_PHYS		0x00040000	/* Next CCB pointer is physical */
463#define CAM_CALLBCK_PHYS		0x00020000	/* Callback func ptr is physical */
464
465#define CAM_SEND_STATUS			0x80000000	/* Send status after date phase */
466#define CAM_DISCONNECT			0x40000000	/* Disc. mandatory after cdb recv */
467#define CAM_TERM_IO				0x20000000	/* Terminate I/O Message supported */
468
469#define CAM_DATAB_VALID			0x80000000	/* Data buffer valid */
470#define CAM_STATUS_VALID		0x40000000	/* Status buffer valid */
471#define CAM_MSGB_VALID			0x20000000	/* Message buffer valid */
472#define CAM_TGT_PHASE_MODE 		0x08000000	/* The SIM will run in phase mode */
473#define CAM_TGT_CCB_AVAIL		0x04000000	/* Target CCB available */
474#define CAM_DIS_AUTODISC		0x02000000	/* Disable autodisconnect */
475#define CAM_DIS_AUTOSRP			0x01000000	/* Disable autosave/restore ptrs */
476
477/* ---------------------------------------------------------------------- */
478
479/* Defines for the SIM/HBA queue actions.	These value are used in the
480SCSI I/O CCB, for the queue action field. [These values should match the
481defines from some other include file for the SCSI message phases.	We may
482not need these definitions here. ] */
483
484#define CAM_SIMPLE_QTAG			0x20		/* Tag for a simple queue */
485#define CAM_HEAD_QTAG			0x21		/* Tag for head of queue */
486#define CAM_ORDERED_QTAG		0x22		/* Tag for ordered queue */
487
488/* ---------------------------------------------------------------------- */
489
490/* Defines for the timeout field in the SCSI I/O CCB.	At this time a value
491of 0xF-F indicates a infinite timeout.	A value of 0x0-0 indicates that the
492SIM's default timeout can take effect. */
493
494#define CAM_TIME_DEFAULT		0x00000000	/* Use SIM default value */
495#define CAM_TIME_INFINITY		0xFFFFFFFF	/* Infinite timeout for I/O */
496
497/* ---------------------------------------------------------------------- */
498
499/* Defines for the Path Inquiry CCB fields. */
500
501#define	CAM_VERSION				0x25	/* Binary value for the current ver */
502
503#define PI_MDP_ABLE				0x80	/* Supports MDP message */
504#define PI_WIDE_32				0x40	/* Supports 32 bit wide SCSI */
505#define PI_WIDE_16				0x20	/* Supports 16 bit wide SCSI */
506#define PI_SDTR_ABLE			0x10	/* Supports SDTR message */
507#define PI_LINKED_CDB			0x08	/* Supports linked CDBs */
508#define PI_TAG_ABLE				0x02	/* Supports tag queue message */
509#define PI_SOFT_RST				0x01	/* Supports soft reset */
510
511#define PIT_PROCESSOR			0x80	/* Target mode processor mode */
512#define PIT_PHASE				0x40	/* Target mode phase cog. mode */
513
514#define PIM_SCANHILO			0x80	/* Bus scans from ID 7 to ID 0 */
515#define PIM_NOREMOVE			0x40	/* Removable dev not included in scan */
516#define PIM_NOINQUIRY			0x20	/* Inquiry data not kept by XPT */
517
518/* ---------------------------------------------------------------------- */
519
520/* Defines for Asynchronous Callback CCB fields. */
521
522#define AC_FOUND_DEVICES		0x80	/* During a rescan new device found */
523#define AC_SIM_DEREGISTER		0x40	/* A loaded SIM has de-registered */
524#define AC_SIM_REGISTER			0x20	/* A loaded SIM has registered */
525#define AC_SENT_BDR				0x10	/* A BDR message was sent to target */
526#define AC_SCSI_AEN				0x08	/* A SCSI AEN has been received */
527#define AC_UNSOL_RESEL			0x02	/* A unsolicited reselection occurred */
528#define AC_BUS_RESET			0x01	/* A SCSI bus RESET occurred */
529
530/* ---------------------------------------------------------------------- */
531
532/* Typedef for a scatter/gather list element. */
533
534typedef struct sg_elem
535{
536	uchar*		cam_sg_address;		/* Scatter/Gather address */
537	uint32		cam_sg_count;			/* Scatter/Gather count */
538} SG_ELEM;
539
540/* ---------------------------------------------------------------------- */
541
542/* Defines for the "event" field in the CCB_NOTIFY_ACK */
543#define CAM_RESET_CLEARED		0x80	/* Reset Cleared */
544
545/* ---------------------------------------------------------------------- */
546
547/* Defines for the HBA engine inquiry CCB fields. */
548
549#define EIT_BUFFER				0x00	/* Engine type: Buffer memory */
550#define EIT_LOSSLESS			0x01	/* Engine type: Lossless compression */
551#define EIT_LOSSLY				0x02	/* Engine type: Lossly compression */
552#define EIT_ENCRYPT				0x03	/* Engine type: Encryption */
553
554#define EAD_VUNIQUE				0x00	/* Eng algorithm ID: vendor unique */
555#define EAD_LZ1V1				0x00	/* Eng algorithm ID: LZ1 var. 1*/
556#define EAD_LZ2V1				0x00	/* Eng algorithm ID: LZ2 var. 1*/
557#define EAD_LZ2V2				0x00	/* Eng algorithm ID: LZ2 var. 2*/
558
559/* ---------------------------------------------------------------------- */
560/* ---------------------------------------------------------------------- */
561
562/* Unix OSD defines and data structures. */
563
564#define INQLEN	36		/* Inquiry string length to store. */
565
566#define CAM_SUCCESS	0	/* For signaling general success */
567#define CAM_FAILURE	1	/* For signaling general failure */
568
569#define CAM_FALSE	0	/* General purpose flag value */
570#define CAM_TRUE	1	/* General purpose flag value */
571
572#define XPT_CCB_INVALID	-1	/* for signaling a bad CCB to free */
573
574/* The typedef for the Async callback information.	This structure is used to
575store the supplied info from the Set Async Callback CCB, in the EDT table
576in a linked list structure. */
577
578typedef struct async_info
579{
580	struct async_info*	cam_async_next;			/* pointer to the next structure */
581	uint32				cam_event_enable;		/* Event enables for Callback resp */
582	void				(*cam_async_func)();	/* Async Callback function address */
583	uint32				cam_async_blen;			/* Length of "information" buffer */
584	uchar*				cam_async_ptr;			/* Address for the "information */
585} ASYNC_INFO;
586
587/* The CAM EDT table contains the device information for all the
588devices, SCSI ID and LUN, for all the SCSI busses in the system.	The
589table contains a CAM_EDT_ENTRY structure for each device on the bus.
590*/
591
592typedef struct cam_edt_entry
593{
594	int32		cam_tlun_found;			/* Flag for the existence of the target/LUN */
595	ASYNC_INFO*	cam_ainfo;				/* Async callback list info for this B/T/L */
596	uint32		cam_owner_tag;			/* Tag for the peripheral driver's ownership */
597	char		cam_inq_data[INQLEN];	/* storage for the inquiry data */
598} CAM_EDT_ENTRY;
599
600
601/* ============================================================================== */
602/* ----------------------------- VENDOR UNIQUE DATA ----------------------------- */
603/* ============================================================================== */
604
605/* ---
606	Vendor unique XPT function codes
607--- */
608
609#define XPT_EXTENDED_PATH_INQ	(XPT_VUNIQUE + 1)		/* Extended Path Inquiry */
610
611/* Extended path inquiry CCB */
612
613#define FAM_ID		16						/* ASCII string len for FAMILY ID */
614#define TYPE_ID		16						/* ASCII string len for TYPE ID */
615#define VERS		 8						/* ASCII string len for SIM & HBA vers */
616
617typedef struct ccb_extended_pathinq
618{
619	CCB_PATHINQ	cam_path;					/* Default path inquiry */
620	char		cam_sim_version[VERS];		/* SIM version number */
621	char		cam_hba_version[VERS];		/* HBA version number */
622	char		cam_controller_family[FAM_ID]; /* Controller family */
623	char		cam_controller_type[TYPE_ID]; /* Controller type */
624} CCB_EXTENDED_PATHINQ;
625
626
627/* ---
628	Vendor unique flags supported by Haiku (cam_vu_flags)
629--- */
630
631enum {
632	VU_RESERVED_0			=	0x0001,
633	VU_RESERVED_1			=	0x0002,
634	VU_DISABLE_SEL_W_ATN	=	0x0004,
635	VU_RESERVED_4			=	0x0008
636};
637
638
639/* ---
640	XPT interface used by SCSI drivers
641--- */
642
643typedef struct cam_for_driver_module_info cam_for_driver_module_info;
644
645struct cam_for_driver_module_info {
646	bus_manager_info	minfo;
647	CCB_HEADER*			(*xpt_ccb_alloc)(void);
648	void				(*xpt_ccb_free)(void* ccb);
649	long				(*xpt_action)(CCB_HEADER* ccbh);
650};
651
652#define	B_CAM_FOR_DRIVER_MODULE_NAME	"bus_managers/scsi/driver/v1"
653
654/* ---
655	XPT interface used by SCSI SIMs
656--- */
657
658typedef struct cam_for_sim_module_info cam_for_sim_module_info;
659
660struct cam_for_sim_module_info {
661	bus_manager_info	minfo;
662	long				(*xpt_bus_register)(CAM_SIM_ENTRY* sim);
663	long				(*xpt_bus_deregister)(long path);
664};
665
666#define	B_CAM_FOR_SIM_MODULE_NAME		"bus_managers/scsi/sim/v1"
667
668
669/* General Union for Kernel Space allocation.	Contains all the possible CCB
670structures.	This union should never be used for manipulating CCB's its only
671use is for the allocation and deallocation of raw CCB space. */
672
673typedef union ccb_size_union
674{
675	CCB_SCSIIO			csio;	/* Please keep this first, for debug/print */
676	CCB_GETDEV			cgd;
677	CCB_PATHINQ			cpi;
678	CCB_RELSIM			crs;
679	CCB_SETASYNC		csa;
680	CCB_SETDEV			csd;
681	CCB_ABORT			cab;
682	CCB_RESETBUS		crb;
683	CCB_RESETDEV		crd;
684	CCB_TERMIO			ctio;
685	CCB_EN_LUN			cel;
686	CCB_ENABLE_LUN		cel2;
687	CCB_IMMED_NOTIFY	cin;
688	CCB_NOTIFY_ACK		cna;
689	CCB_ACCEPT_TARG		cat;
690	CCB_ENG_INQ			cei;
691	CCB_ENG_EXEC		cee;
692	CCB_EXTENDED_PATHINQ	cdpi;
693} CCB_SIZE_UNION;
694
695
696#ifdef __cplusplus
697}
698#endif
699
700#endif
701