1/*-
2 * Data structures and definitions for CAM Control Blocks (CCBs).
3 *
4 * Copyright (c) 1997, 1998 Justin T. Gibbs.
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 *    notice, this list of conditions, and the following disclaimer,
12 *    without modification, immediately at the beginning of the file.
13 * 2. The name of the author may not be used to endorse or promote products
14 *    derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
20 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 * SUCH DAMAGE.
27 *
28 * $FreeBSD: stable/11/sys/cam/cam_ccb.h 335166 2018-06-14 18:18:55Z mav $
29 */
30
31#ifndef _CAM_CAM_CCB_H
32#define _CAM_CAM_CCB_H 1
33
34#include <sys/queue.h>
35#include <sys/cdefs.h>
36#include <sys/time.h>
37#include <sys/limits.h>
38#ifndef _KERNEL
39#include <sys/callout.h>
40#endif
41#include <cam/cam_debug.h>
42#include <cam/scsi/scsi_all.h>
43#include <cam/ata/ata_all.h>
44#include <cam/nvme/nvme_all.h>
45
46/* General allocation length definitions for CCB structures */
47#define	IOCDBLEN	CAM_MAX_CDBLEN	/* Space for CDB bytes/pointer */
48#define	VUHBALEN	14		/* Vendor Unique HBA length */
49#define	SIM_IDLEN	16		/* ASCII string len for SIM ID */
50#define	HBA_IDLEN	16		/* ASCII string len for HBA ID */
51#define	DEV_IDLEN	16		/* ASCII string len for device names */
52#define CCB_PERIPH_PRIV_SIZE 	2	/* size of peripheral private area */
53#define CCB_SIM_PRIV_SIZE 	2	/* size of sim private area */
54
55/* Struct definitions for CAM control blocks */
56
57/* Common CCB header */
58/* CAM CCB flags */
59typedef enum {
60	CAM_CDB_POINTER		= 0x00000001,/* The CDB field is a pointer    */
61	CAM_QUEUE_ENABLE	= 0x00000002,/* SIM queue actions are enabled */
62	CAM_CDB_LINKED		= 0x00000004,/* CCB contains a linked CDB     */
63	CAM_NEGOTIATE		= 0x00000008,/*
64					      * Perform transport negotiation
65					      * with this command.
66					      */
67	CAM_DATA_ISPHYS		= 0x00000010,/* Data type with physical addrs */
68	CAM_DIS_AUTOSENSE	= 0x00000020,/* Disable autosense feature     */
69	CAM_DIR_BOTH		= 0x00000000,/* Data direction (00:IN/OUT)    */
70	CAM_DIR_IN		= 0x00000040,/* Data direction (01:DATA IN)   */
71	CAM_DIR_OUT		= 0x00000080,/* Data direction (10:DATA OUT)  */
72	CAM_DIR_NONE		= 0x000000C0,/* Data direction (11:no data)   */
73	CAM_DIR_MASK		= 0x000000C0,/* Data direction Mask	      */
74	CAM_DATA_VADDR		= 0x00000000,/* Data type (000:Virtual)       */
75	CAM_DATA_PADDR		= 0x00000010,/* Data type (001:Physical)      */
76	CAM_DATA_SG		= 0x00040000,/* Data type (010:sglist)        */
77	CAM_DATA_SG_PADDR	= 0x00040010,/* Data type (011:sglist phys)   */
78	CAM_DATA_BIO		= 0x00200000,/* Data type (100:bio)           */
79	CAM_DATA_MASK		= 0x00240010,/* Data type mask                */
80	CAM_SOFT_RST_OP		= 0x00000100,/* Use Soft reset alternative    */
81	CAM_ENG_SYNC		= 0x00000200,/* Flush resid bytes on complete */
82	CAM_DEV_QFRZDIS		= 0x00000400,/* Disable DEV Q freezing	      */
83	CAM_DEV_QFREEZE		= 0x00000800,/* Freeze DEV Q on execution     */
84	CAM_HIGH_POWER		= 0x00001000,/* Command takes a lot of power  */
85	CAM_SENSE_PTR		= 0x00002000,/* Sense data is a pointer	      */
86	CAM_SENSE_PHYS		= 0x00004000,/* Sense pointer is physical addr*/
87	CAM_TAG_ACTION_VALID	= 0x00008000,/* Use the tag action in this ccb*/
88	CAM_PASS_ERR_RECOVER	= 0x00010000,/* Pass driver does err. recovery*/
89	CAM_DIS_DISCONNECT	= 0x00020000,/* Disable disconnect	      */
90	CAM_MSG_BUF_PHYS	= 0x00080000,/* Message buffer ptr is physical*/
91	CAM_SNS_BUF_PHYS	= 0x00100000,/* Autosense data ptr is physical*/
92	CAM_CDB_PHYS		= 0x00400000,/* CDB poiner is physical	      */
93	CAM_ENG_SGLIST		= 0x00800000,/* SG list is for the HBA engine */
94
95/* Phase cognizant mode flags */
96	CAM_DIS_AUTOSRP		= 0x01000000,/* Disable autosave/restore ptrs */
97	CAM_DIS_AUTODISC	= 0x02000000,/* Disable auto disconnect	      */
98	CAM_TGT_CCB_AVAIL	= 0x04000000,/* Target CCB available	      */
99	CAM_TGT_PHASE_MODE	= 0x08000000,/* The SIM runs in phase mode    */
100	CAM_MSGB_VALID		= 0x10000000,/* Message buffer valid	      */
101	CAM_STATUS_VALID	= 0x20000000,/* Status buffer valid	      */
102	CAM_DATAB_VALID		= 0x40000000,/* Data buffer valid	      */
103
104/* Host target Mode flags */
105	CAM_SEND_SENSE		= 0x08000000,/* Send sense data with status   */
106	CAM_TERM_IO		= 0x10000000,/* Terminate I/O Message sup.    */
107	CAM_DISCONNECT		= 0x20000000,/* Disconnects are mandatory     */
108	CAM_SEND_STATUS		= 0x40000000,/* Send status after data phase  */
109
110	CAM_UNLOCKED		= 0x80000000 /* Call callback without lock.   */
111} ccb_flags;
112
113typedef enum {
114	CAM_USER_DATA_ADDR	= 0x00000002,/* Userspace data pointers */
115	CAM_SG_FORMAT_IOVEC	= 0x00000004,/* iovec instead of busdma S/G*/
116	CAM_UNMAPPED_BUF	= 0x00000008 /* use unmapped I/O */
117} ccb_xflags;
118
119/* XPT Opcodes for xpt_action */
120typedef enum {
121/* Function code flags are bits greater than 0xff */
122	XPT_FC_QUEUED		= 0x100,
123				/* Non-immediate function code */
124	XPT_FC_USER_CCB		= 0x200,
125	XPT_FC_XPT_ONLY		= 0x400,
126				/* Only for the transport layer device */
127	XPT_FC_DEV_QUEUED	= 0x800 | XPT_FC_QUEUED,
128				/* Passes through the device queues */
129/* Common function commands: 0x00->0x0F */
130	XPT_NOOP 		= 0x00,
131				/* Execute Nothing */
132	XPT_SCSI_IO		= 0x01 | XPT_FC_DEV_QUEUED,
133				/* Execute the requested I/O operation */
134	XPT_GDEV_TYPE		= 0x02,
135				/* Get type information for specified device */
136	XPT_GDEVLIST		= 0x03,
137				/* Get a list of peripheral devices */
138	XPT_PATH_INQ		= 0x04,
139				/* Path routing inquiry */
140	XPT_REL_SIMQ		= 0x05,
141				/* Release a frozen device queue */
142	XPT_SASYNC_CB		= 0x06,
143				/* Set Asynchronous Callback Parameters */
144	XPT_SDEV_TYPE		= 0x07,
145				/* Set device type information */
146	XPT_SCAN_BUS		= 0x08 | XPT_FC_QUEUED | XPT_FC_USER_CCB
147				       | XPT_FC_XPT_ONLY,
148				/* (Re)Scan the SCSI Bus */
149	XPT_DEV_MATCH		= 0x09 | XPT_FC_XPT_ONLY,
150				/* Get EDT entries matching the given pattern */
151	XPT_DEBUG		= 0x0a,
152				/* Turn on debugging for a bus, target or lun */
153	XPT_PATH_STATS		= 0x0b,
154				/* Path statistics (error counts, etc.) */
155	XPT_GDEV_STATS		= 0x0c,
156				/* Device statistics (error counts, etc.) */
157	XPT_DEV_ADVINFO		= 0x0e,
158				/* Get/Set Device advanced information */
159	XPT_ASYNC		= 0x0f | XPT_FC_QUEUED | XPT_FC_USER_CCB
160				       | XPT_FC_XPT_ONLY,
161				/* Asynchronous event */
162/* SCSI Control Functions: 0x10->0x1F */
163	XPT_ABORT		= 0x10,
164				/* Abort the specified CCB */
165	XPT_RESET_BUS		= 0x11 | XPT_FC_XPT_ONLY,
166				/* Reset the specified SCSI bus */
167	XPT_RESET_DEV		= 0x12 | XPT_FC_DEV_QUEUED,
168				/* Bus Device Reset the specified SCSI device */
169	XPT_TERM_IO		= 0x13,
170				/* Terminate the I/O process */
171	XPT_SCAN_LUN		= 0x14 | XPT_FC_QUEUED | XPT_FC_USER_CCB
172				       | XPT_FC_XPT_ONLY,
173				/* Scan Logical Unit */
174	XPT_GET_TRAN_SETTINGS	= 0x15,
175				/*
176				 * Get default/user transfer settings
177				 * for the target
178				 */
179	XPT_SET_TRAN_SETTINGS	= 0x16,
180				/*
181				 * Set transfer rate/width
182				 * negotiation settings
183				 */
184	XPT_CALC_GEOMETRY	= 0x17,
185				/*
186				 * Calculate the geometry parameters for
187				 * a device give the sector size and
188				 * volume size.
189				 */
190	XPT_ATA_IO		= 0x18 | XPT_FC_DEV_QUEUED,
191				/* Execute the requested ATA I/O operation */
192
193	XPT_GET_SIM_KNOB_OLD	= 0x18, /* Compat only */
194
195	XPT_SET_SIM_KNOB	= 0x19,
196				/*
197				 * Set SIM specific knob values.
198				 */
199
200	XPT_GET_SIM_KNOB	= 0x1a,
201				/*
202				 * Get SIM specific knob values.
203				 */
204
205	XPT_SMP_IO		= 0x1b | XPT_FC_DEV_QUEUED,
206				/* Serial Management Protocol */
207
208	XPT_NVME_IO		= 0x1c | XPT_FC_DEV_QUEUED,
209				/* Execute the requested NVMe I/O operation */
210
211	XPT_MMCSD_IO		= 0x1d | XPT_FC_DEV_QUEUED,
212				/* Placeholder for MMC / SD / SDIO I/O stuff */
213
214	XPT_SCAN_TGT		= 0x1E | XPT_FC_QUEUED | XPT_FC_USER_CCB
215				       | XPT_FC_XPT_ONLY,
216				/* Scan Target */
217
218	XPT_NVME_ADMIN		= 0x1f | XPT_FC_DEV_QUEUED,
219				/* Execute the requested NVMe Admin operation */
220
221/* HBA engine commands 0x20->0x2F */
222	XPT_ENG_INQ		= 0x20 | XPT_FC_XPT_ONLY,
223				/* HBA engine feature inquiry */
224	XPT_ENG_EXEC		= 0x21 | XPT_FC_DEV_QUEUED,
225				/* HBA execute engine request */
226
227/* Target mode commands: 0x30->0x3F */
228	XPT_EN_LUN		= 0x30,
229				/* Enable LUN as a target */
230	XPT_TARGET_IO		= 0x31 | XPT_FC_DEV_QUEUED,
231				/* Execute target I/O request */
232	XPT_ACCEPT_TARGET_IO	= 0x32 | XPT_FC_QUEUED | XPT_FC_USER_CCB,
233				/* Accept Host Target Mode CDB */
234	XPT_CONT_TARGET_IO	= 0x33 | XPT_FC_DEV_QUEUED,
235				/* Continue Host Target I/O Connection */
236	XPT_IMMED_NOTIFY	= 0x34 | XPT_FC_QUEUED | XPT_FC_USER_CCB,
237				/* Notify Host Target driver of event (obsolete) */
238	XPT_NOTIFY_ACK		= 0x35,
239				/* Acknowledgement of event (obsolete) */
240	XPT_IMMEDIATE_NOTIFY	= 0x36 | XPT_FC_QUEUED | XPT_FC_USER_CCB,
241				/* Notify Host Target driver of event */
242	XPT_NOTIFY_ACKNOWLEDGE	= 0x37 | XPT_FC_QUEUED | XPT_FC_USER_CCB,
243				/* Acknowledgement of event */
244	XPT_REPROBE_LUN		= 0x38 | XPT_FC_QUEUED | XPT_FC_USER_CCB,
245				/* Query device capacity and notify GEOM */
246
247/* Vendor Unique codes: 0x80->0x8F */
248	XPT_VUNIQUE		= 0x80
249} xpt_opcode;
250
251#define XPT_FC_GROUP_MASK		0xF0
252#define XPT_FC_GROUP(op) ((op) & XPT_FC_GROUP_MASK)
253#define XPT_FC_GROUP_COMMON		0x00
254#define XPT_FC_GROUP_SCSI_CONTROL	0x10
255#define XPT_FC_GROUP_HBA_ENGINE		0x20
256#define XPT_FC_GROUP_TMODE		0x30
257#define XPT_FC_GROUP_VENDOR_UNIQUE	0x80
258
259#define XPT_FC_IS_DEV_QUEUED(ccb) 	\
260    (((ccb)->ccb_h.func_code & XPT_FC_DEV_QUEUED) == XPT_FC_DEV_QUEUED)
261#define XPT_FC_IS_QUEUED(ccb) 	\
262    (((ccb)->ccb_h.func_code & XPT_FC_QUEUED) != 0)
263
264typedef enum {
265	PROTO_UNKNOWN,
266	PROTO_UNSPECIFIED,
267	PROTO_SCSI,	/* Small Computer System Interface */
268	PROTO_ATA,	/* AT Attachment */
269	PROTO_ATAPI,	/* AT Attachment Packetized Interface */
270	PROTO_SATAPM,	/* SATA Port Multiplier */
271	PROTO_SEMB,	/* SATA Enclosure Management Bridge */
272	PROTO_NVME,	/* NVME */
273} cam_proto;
274
275typedef enum {
276	XPORT_UNKNOWN,
277	XPORT_UNSPECIFIED,
278	XPORT_SPI,	/* SCSI Parallel Interface */
279	XPORT_FC,	/* Fiber Channel */
280	XPORT_SSA,	/* Serial Storage Architecture */
281	XPORT_USB,	/* Universal Serial Bus */
282	XPORT_PPB,	/* Parallel Port Bus */
283	XPORT_ATA,	/* AT Attachment */
284	XPORT_SAS,	/* Serial Attached SCSI */
285	XPORT_SATA,	/* Serial AT Attachment */
286	XPORT_ISCSI,	/* iSCSI */
287	XPORT_SRP,	/* SCSI RDMA Protocol */
288	XPORT_NVME,	/* NVMe over PCIe */
289} cam_xport;
290
291#define XPORT_IS_ATA(t)		((t) == XPORT_ATA || (t) == XPORT_SATA)
292#define XPORT_IS_SCSI(t)	((t) != XPORT_UNKNOWN && \
293				 (t) != XPORT_UNSPECIFIED && \
294				 !XPORT_IS_ATA(t))
295#define XPORT_DEVSTAT_TYPE(t)	(XPORT_IS_ATA(t) ? DEVSTAT_TYPE_IF_IDE : \
296				 XPORT_IS_SCSI(t) ? DEVSTAT_TYPE_IF_SCSI : \
297				 DEVSTAT_TYPE_IF_OTHER)
298
299#define PROTO_VERSION_UNKNOWN (UINT_MAX - 1)
300#define PROTO_VERSION_UNSPECIFIED UINT_MAX
301#define XPORT_VERSION_UNKNOWN (UINT_MAX - 1)
302#define XPORT_VERSION_UNSPECIFIED UINT_MAX
303
304typedef union {
305	LIST_ENTRY(ccb_hdr) le;
306	SLIST_ENTRY(ccb_hdr) sle;
307	TAILQ_ENTRY(ccb_hdr) tqe;
308	STAILQ_ENTRY(ccb_hdr) stqe;
309} camq_entry;
310
311typedef union {
312	void		*ptr;
313	u_long		field;
314	u_int8_t	bytes[sizeof(uintptr_t)];
315} ccb_priv_entry;
316
317typedef union {
318	ccb_priv_entry	entries[CCB_PERIPH_PRIV_SIZE];
319	u_int8_t	bytes[CCB_PERIPH_PRIV_SIZE * sizeof(ccb_priv_entry)];
320} ccb_ppriv_area;
321
322typedef union {
323	ccb_priv_entry	entries[CCB_SIM_PRIV_SIZE];
324	u_int8_t	bytes[CCB_SIM_PRIV_SIZE * sizeof(ccb_priv_entry)];
325} ccb_spriv_area;
326
327typedef struct {
328	struct timeval	*etime;
329	uintptr_t	sim_data;
330	uintptr_t	periph_data;
331} ccb_qos_area;
332
333struct ccb_hdr {
334	cam_pinfo	pinfo;		/* Info for priority scheduling */
335	camq_entry	xpt_links;	/* For chaining in the XPT layer */
336	camq_entry	sim_links;	/* For chaining in the SIM layer */
337	camq_entry	periph_links;	/* For chaining in the type driver */
338	u_int32_t	retry_count;
339	void		(*cbfcnp)(struct cam_periph *, union ccb *);
340					/* Callback on completion function */
341	xpt_opcode	func_code;	/* XPT function code */
342	u_int32_t	status;		/* Status returned by CAM subsystem */
343	struct		cam_path *path;	/* Compiled path for this ccb */
344	path_id_t	path_id;	/* Path ID for the request */
345	target_id_t	target_id;	/* Target device ID */
346	lun_id_t	target_lun;	/* Target LUN number */
347	u_int32_t	flags;		/* ccb_flags */
348	u_int32_t	xflags;		/* Extended flags */
349	ccb_ppriv_area	periph_priv;
350	ccb_spriv_area	sim_priv;
351	ccb_qos_area	qos;
352	u_int32_t	timeout;	/* Hard timeout value in mseconds */
353	struct timeval	softtimeout;	/* Soft timeout value in sec + usec */
354};
355
356/* Get Device Information CCB */
357struct ccb_getdev {
358	struct	  ccb_hdr ccb_h;
359	cam_proto protocol;
360	struct scsi_inquiry_data inq_data;
361	struct ata_params ident_data;
362	u_int8_t  serial_num[252];
363	u_int8_t  inq_flags;
364	u_int8_t  serial_num_len;
365	void *padding[2];
366};
367
368/* Device Statistics CCB */
369struct ccb_getdevstats {
370	struct	ccb_hdr	ccb_h;
371	int	dev_openings;	/* Space left for more work on device*/
372	int	dev_active;	/* Transactions running on the device */
373	int	allocated;	/* CCBs allocated for the device */
374	int	queued;		/* CCBs queued to be sent to the device */
375	int	held;		/*
376				 * CCBs held by peripheral drivers
377				 * for this device
378				 */
379	int	maxtags;	/*
380				 * Boundary conditions for number of
381				 * tagged operations
382				 */
383	int	mintags;
384	struct	timeval last_reset;	/* Time of last bus reset/loop init */
385};
386
387typedef enum {
388	CAM_GDEVLIST_LAST_DEVICE,
389	CAM_GDEVLIST_LIST_CHANGED,
390	CAM_GDEVLIST_MORE_DEVS,
391	CAM_GDEVLIST_ERROR
392} ccb_getdevlist_status_e;
393
394struct ccb_getdevlist {
395	struct ccb_hdr		ccb_h;
396	char 			periph_name[DEV_IDLEN];
397	u_int32_t		unit_number;
398	unsigned int		generation;
399	u_int32_t		index;
400	ccb_getdevlist_status_e	status;
401};
402
403typedef enum {
404	PERIPH_MATCH_NONE	= 0x000,
405	PERIPH_MATCH_PATH	= 0x001,
406	PERIPH_MATCH_TARGET	= 0x002,
407	PERIPH_MATCH_LUN	= 0x004,
408	PERIPH_MATCH_NAME	= 0x008,
409	PERIPH_MATCH_UNIT	= 0x010,
410	PERIPH_MATCH_ANY	= 0x01f
411} periph_pattern_flags;
412
413struct periph_match_pattern {
414	char			periph_name[DEV_IDLEN];
415	u_int32_t		unit_number;
416	path_id_t		path_id;
417	target_id_t		target_id;
418	lun_id_t		target_lun;
419	periph_pattern_flags	flags;
420};
421
422typedef enum {
423	DEV_MATCH_NONE		= 0x000,
424	DEV_MATCH_PATH		= 0x001,
425	DEV_MATCH_TARGET	= 0x002,
426	DEV_MATCH_LUN		= 0x004,
427	DEV_MATCH_INQUIRY	= 0x008,
428	DEV_MATCH_DEVID		= 0x010,
429	DEV_MATCH_ANY		= 0x00f
430} dev_pattern_flags;
431
432struct device_id_match_pattern {
433	uint8_t id_len;
434	uint8_t id[256];
435};
436
437struct device_match_pattern {
438	path_id_t					path_id;
439	target_id_t					target_id;
440	lun_id_t					target_lun;
441	dev_pattern_flags				flags;
442	union {
443		struct scsi_static_inquiry_pattern	inq_pat;
444		struct device_id_match_pattern		devid_pat;
445	} data;
446};
447
448typedef enum {
449	BUS_MATCH_NONE		= 0x000,
450	BUS_MATCH_PATH		= 0x001,
451	BUS_MATCH_NAME		= 0x002,
452	BUS_MATCH_UNIT		= 0x004,
453	BUS_MATCH_BUS_ID	= 0x008,
454	BUS_MATCH_ANY		= 0x00f
455} bus_pattern_flags;
456
457struct bus_match_pattern {
458	path_id_t		path_id;
459	char			dev_name[DEV_IDLEN];
460	u_int32_t		unit_number;
461	u_int32_t		bus_id;
462	bus_pattern_flags	flags;
463};
464
465union match_pattern {
466	struct periph_match_pattern	periph_pattern;
467	struct device_match_pattern	device_pattern;
468	struct bus_match_pattern	bus_pattern;
469};
470
471typedef enum {
472	DEV_MATCH_PERIPH,
473	DEV_MATCH_DEVICE,
474	DEV_MATCH_BUS
475} dev_match_type;
476
477struct dev_match_pattern {
478	dev_match_type		type;
479	union match_pattern	pattern;
480};
481
482struct periph_match_result {
483	char			periph_name[DEV_IDLEN];
484	u_int32_t		unit_number;
485	path_id_t		path_id;
486	target_id_t		target_id;
487	lun_id_t		target_lun;
488};
489
490typedef enum {
491	DEV_RESULT_NOFLAG		= 0x00,
492	DEV_RESULT_UNCONFIGURED		= 0x01
493} dev_result_flags;
494
495struct device_match_result {
496	path_id_t			path_id;
497	target_id_t			target_id;
498	lun_id_t			target_lun;
499	cam_proto			protocol;
500	struct scsi_inquiry_data	inq_data;
501	struct ata_params		ident_data;
502	dev_result_flags		flags;
503};
504
505struct bus_match_result {
506	path_id_t	path_id;
507	char		dev_name[DEV_IDLEN];
508	u_int32_t	unit_number;
509	u_int32_t	bus_id;
510};
511
512union match_result {
513	struct periph_match_result	periph_result;
514	struct device_match_result	device_result;
515	struct bus_match_result		bus_result;
516};
517
518struct dev_match_result {
519	dev_match_type		type;
520	union match_result	result;
521};
522
523typedef enum {
524	CAM_DEV_MATCH_LAST,
525	CAM_DEV_MATCH_MORE,
526	CAM_DEV_MATCH_LIST_CHANGED,
527	CAM_DEV_MATCH_SIZE_ERROR,
528	CAM_DEV_MATCH_ERROR
529} ccb_dev_match_status;
530
531typedef enum {
532	CAM_DEV_POS_NONE	= 0x000,
533	CAM_DEV_POS_BUS		= 0x001,
534	CAM_DEV_POS_TARGET	= 0x002,
535	CAM_DEV_POS_DEVICE	= 0x004,
536	CAM_DEV_POS_PERIPH	= 0x008,
537	CAM_DEV_POS_PDPTR	= 0x010,
538	CAM_DEV_POS_TYPEMASK	= 0xf00,
539	CAM_DEV_POS_EDT		= 0x100,
540	CAM_DEV_POS_PDRV	= 0x200
541} dev_pos_type;
542
543struct ccb_dm_cookie {
544	void 	*bus;
545	void	*target;
546	void	*device;
547	void	*periph;
548	void	*pdrv;
549};
550
551struct ccb_dev_position {
552	u_int			generations[4];
553#define	CAM_BUS_GENERATION	0x00
554#define CAM_TARGET_GENERATION	0x01
555#define CAM_DEV_GENERATION	0x02
556#define CAM_PERIPH_GENERATION	0x03
557	dev_pos_type		position_type;
558	struct ccb_dm_cookie	cookie;
559};
560
561struct ccb_dev_match {
562	struct ccb_hdr			ccb_h;
563	ccb_dev_match_status		status;
564	u_int32_t			num_patterns;
565	u_int32_t			pattern_buf_len;
566	struct dev_match_pattern	*patterns;
567	u_int32_t			num_matches;
568	u_int32_t			match_buf_len;
569	struct dev_match_result		*matches;
570	struct ccb_dev_position		pos;
571};
572
573/*
574 * Definitions for the path inquiry CCB fields.
575 */
576#define CAM_VERSION	0x19	/* Hex value for current version */
577
578typedef enum {
579	PI_MDP_ABLE	= 0x80,	/* Supports MDP message */
580	PI_WIDE_32	= 0x40,	/* Supports 32 bit wide SCSI */
581	PI_WIDE_16	= 0x20, /* Supports 16 bit wide SCSI */
582	PI_SDTR_ABLE	= 0x10,	/* Supports SDTR message */
583	PI_LINKED_CDB	= 0x08, /* Supports linked CDBs */
584	PI_SATAPM	= 0x04,	/* Supports SATA PM */
585	PI_TAG_ABLE	= 0x02,	/* Supports tag queue messages */
586	PI_SOFT_RST	= 0x01	/* Supports soft reset alternative */
587} pi_inqflag;
588
589typedef enum {
590	PIT_PROCESSOR	= 0x80,	/* Target mode processor mode */
591	PIT_PHASE	= 0x40,	/* Target mode phase cog. mode */
592	PIT_DISCONNECT	= 0x20,	/* Disconnects supported in target mode */
593	PIT_TERM_IO	= 0x10,	/* Terminate I/O message supported in TM */
594	PIT_GRP_6	= 0x08,	/* Group 6 commands supported */
595	PIT_GRP_7	= 0x04	/* Group 7 commands supported */
596} pi_tmflag;
597
598typedef enum {
599	PIM_ATA_EXT	= 0x200,/* ATA requests can understand ata_ext requests */
600	PIM_EXTLUNS	= 0x100,/* 64bit extended LUNs supported */
601	PIM_SCANHILO	= 0x80,	/* Bus scans from high ID to low ID */
602	PIM_NOREMOVE	= 0x40,	/* Removeable devices not included in scan */
603	PIM_NOINITIATOR	= 0x20,	/* Initiator role not supported. */
604	PIM_NOBUSRESET	= 0x10,	/* User has disabled initial BUS RESET */
605	PIM_NO_6_BYTE	= 0x08,	/* Do not send 6-byte commands */
606	PIM_SEQSCAN	= 0x04,	/* Do bus scans sequentially, not in parallel */
607	PIM_UNMAPPED	= 0x02,
608	PIM_NOSCAN	= 0x01	/* SIM does its own scanning */
609} pi_miscflag;
610
611/* Path Inquiry CCB */
612struct ccb_pathinq_settings_spi {
613	u_int8_t ppr_options;
614};
615
616struct ccb_pathinq_settings_fc {
617	u_int64_t wwnn;		/* world wide node name */
618	u_int64_t wwpn;		/* world wide port name */
619	u_int32_t port;		/* 24 bit port id, if known */
620	u_int32_t bitrate;	/* Mbps */
621};
622
623struct ccb_pathinq_settings_sas {
624	u_int32_t bitrate;	/* Mbps */
625};
626
627struct ccb_pathinq_settings_nvme {
628	uint32_t nsid;		/* Namespace ID for this path */
629	uint32_t domain;
630	uint8_t  bus;
631	uint8_t  slot;
632	uint8_t  function;
633	uint8_t  extra;
634};
635
636#define	PATHINQ_SETTINGS_SIZE	128
637
638struct ccb_pathinq {
639	struct 	    ccb_hdr ccb_h;
640	u_int8_t    version_num;	/* Version number for the SIM/HBA */
641	u_int8_t    hba_inquiry;	/* Mimic of INQ byte 7 for the HBA */
642	u_int16_t   target_sprt;	/* Flags for target mode support */
643	u_int32_t   hba_misc;		/* Misc HBA features */
644	u_int16_t   hba_eng_cnt;	/* HBA engine count */
645					/* Vendor Unique capabilities */
646	u_int8_t    vuhba_flags[VUHBALEN];
647	u_int32_t   max_target;		/* Maximum supported Target */
648	u_int32_t   max_lun;		/* Maximum supported Lun */
649	u_int32_t   async_flags;	/* Installed Async handlers */
650	path_id_t   hpath_id;		/* Highest Path ID in the subsystem */
651	target_id_t initiator_id;	/* ID of the HBA on the SCSI bus */
652	char	    sim_vid[SIM_IDLEN];	/* Vendor ID of the SIM */
653	char	    hba_vid[HBA_IDLEN];	/* Vendor ID of the HBA */
654	char 	    dev_name[DEV_IDLEN];/* Device name for SIM */
655	u_int32_t   unit_number;	/* Unit number for SIM */
656	u_int32_t   bus_id;		/* Bus ID for SIM */
657	u_int32_t   base_transfer_speed;/* Base bus speed in KB/sec */
658	cam_proto   protocol;
659	u_int	    protocol_version;
660	cam_xport   transport;
661	u_int	    transport_version;
662	union {
663		struct ccb_pathinq_settings_spi spi;
664		struct ccb_pathinq_settings_fc fc;
665		struct ccb_pathinq_settings_sas sas;
666		struct ccb_pathinq_settings_nvme nvme;
667		char ccb_pathinq_settings_opaque[PATHINQ_SETTINGS_SIZE];
668	} xport_specific;
669	u_int		maxio;		/* Max supported I/O size, in bytes. */
670	u_int16_t	hba_vendor;	/* HBA vendor ID */
671	u_int16_t	hba_device;	/* HBA device ID */
672	u_int16_t	hba_subvendor;	/* HBA subvendor ID */
673	u_int16_t	hba_subdevice;	/* HBA subdevice ID */
674};
675
676/* Path Statistics CCB */
677struct ccb_pathstats {
678	struct	ccb_hdr	ccb_h;
679	struct	timeval last_reset;	/* Time of last bus reset/loop init */
680};
681
682typedef enum {
683	SMP_FLAG_NONE		= 0x00,
684	SMP_FLAG_REQ_SG		= 0x01,
685	SMP_FLAG_RSP_SG		= 0x02
686} ccb_smp_pass_flags;
687
688/*
689 * Serial Management Protocol CCB
690 * XXX Currently the semantics for this CCB are that it is executed either
691 * by the addressed device, or that device's parent (i.e. an expander for
692 * any device on an expander) if the addressed device doesn't support SMP.
693 * Later, once we have the ability to probe SMP-only devices and put them
694 * in CAM's topology, the CCB will only be executed by the addressed device
695 * if possible.
696 */
697struct ccb_smpio {
698	struct ccb_hdr		ccb_h;
699	uint8_t			*smp_request;
700	int			smp_request_len;
701	uint16_t		smp_request_sglist_cnt;
702	uint8_t			*smp_response;
703	int			smp_response_len;
704	uint16_t		smp_response_sglist_cnt;
705	ccb_smp_pass_flags	flags;
706};
707
708typedef union {
709	u_int8_t *sense_ptr;		/*
710					 * Pointer to storage
711					 * for sense information
712					 */
713	                                /* Storage Area for sense information */
714	struct	 scsi_sense_data sense_buf;
715} sense_t;
716
717typedef union {
718	u_int8_t  *cdb_ptr;		/* Pointer to the CDB bytes to send */
719					/* Area for the CDB send */
720	u_int8_t  cdb_bytes[IOCDBLEN];
721} cdb_t;
722
723/*
724 * SCSI I/O Request CCB used for the XPT_SCSI_IO and XPT_CONT_TARGET_IO
725 * function codes.
726 */
727struct ccb_scsiio {
728	struct	   ccb_hdr ccb_h;
729	union	   ccb *next_ccb;	/* Ptr for next CCB for action */
730	u_int8_t   *req_map;		/* Ptr to mapping info */
731	u_int8_t   *data_ptr;		/* Ptr to the data buf/SG list */
732	u_int32_t  dxfer_len;		/* Data transfer length */
733					/* Autosense storage */
734	struct     scsi_sense_data sense_data;
735	u_int8_t   sense_len;		/* Number of bytes to autosense */
736	u_int8_t   cdb_len;		/* Number of bytes for the CDB */
737	u_int16_t  sglist_cnt;		/* Number of SG list entries */
738	u_int8_t   scsi_status;		/* Returned SCSI status */
739	u_int8_t   sense_resid;		/* Autosense resid length: 2's comp */
740	u_int32_t  resid;		/* Transfer residual length: 2's comp */
741	cdb_t	   cdb_io;		/* Union for CDB bytes/pointer */
742	u_int8_t   *msg_ptr;		/* Pointer to the message buffer */
743	u_int16_t  msg_len;		/* Number of bytes for the Message */
744	u_int8_t   tag_action;		/* What to do for tag queueing */
745	/*
746	 * The tag action should be either the define below (to send a
747	 * non-tagged transaction) or one of the defined scsi tag messages
748	 * from scsi_message.h.
749	 */
750#define		CAM_TAG_ACTION_NONE	0x00
751	u_int	   tag_id;		/* tag id from initator (target mode) */
752	u_int	   init_id;		/* initiator id of who selected */
753};
754
755static __inline uint8_t *
756scsiio_cdb_ptr(struct ccb_scsiio *ccb)
757{
758	return ((ccb->ccb_h.flags & CAM_CDB_POINTER) ?
759	    ccb->cdb_io.cdb_ptr : ccb->cdb_io.cdb_bytes);
760}
761
762/*
763 * ATA I/O Request CCB used for the XPT_ATA_IO function code.
764 */
765struct ccb_ataio {
766	struct	   ccb_hdr ccb_h;
767	union	   ccb *next_ccb;	/* Ptr for next CCB for action */
768	struct ata_cmd	cmd;		/* ATA command register set */
769	struct ata_res	res;		/* ATA result register set */
770	u_int8_t   *data_ptr;		/* Ptr to the data buf/SG list */
771	u_int32_t  dxfer_len;		/* Data transfer length */
772	u_int32_t  resid;		/* Transfer residual length: 2's comp */
773	u_int8_t   ata_flags;		/* Flags for the rest of the buffer */
774#define ATA_FLAG_AUX 0x1
775	uint32_t   aux;
776	uint32_t   unused;
777};
778
779struct ccb_accept_tio {
780	struct	   ccb_hdr ccb_h;
781	cdb_t	   cdb_io;		/* Union for CDB bytes/pointer */
782	u_int8_t   cdb_len;		/* Number of bytes for the CDB */
783	u_int8_t   tag_action;		/* What to do for tag queueing */
784	u_int8_t   sense_len;		/* Number of bytes of Sense Data */
785	u_int      tag_id;		/* tag id from initator (target mode) */
786	u_int      init_id;		/* initiator id of who selected */
787	struct     scsi_sense_data sense_data;
788};
789
790static __inline uint8_t *
791atio_cdb_ptr(struct ccb_accept_tio *ccb)
792{
793	return ((ccb->ccb_h.flags & CAM_CDB_POINTER) ?
794	    ccb->cdb_io.cdb_ptr : ccb->cdb_io.cdb_bytes);
795}
796
797/* Release SIM Queue */
798struct ccb_relsim {
799	struct ccb_hdr ccb_h;
800	u_int32_t      release_flags;
801#define RELSIM_ADJUST_OPENINGS		0x01
802#define RELSIM_RELEASE_AFTER_TIMEOUT	0x02
803#define RELSIM_RELEASE_AFTER_CMDCMPLT	0x04
804#define RELSIM_RELEASE_AFTER_QEMPTY	0x08
805	u_int32_t      openings;
806	u_int32_t      release_timeout;	/* Abstract argument. */
807	u_int32_t      qfrozen_cnt;
808};
809
810/*
811 * NVMe I/O Request CCB used for the XPT_NVME_IO and XPT_NVME_ADMIN function codes.
812 */
813struct ccb_nvmeio {
814	struct	   ccb_hdr ccb_h;
815	union	   ccb *next_ccb;	/* Ptr for next CCB for action */
816	struct nvme_command cmd;	/* NVME command, per NVME standard */
817	struct nvme_completion cpl;	/* NVME completion, per NVME standard */
818	uint8_t   *data_ptr;		/* Ptr to the data buf/SG list */
819	uint32_t  dxfer_len;		/* Data transfer length */
820	uint16_t  sglist_cnt;		/* Number of SG list entries */
821	uint16_t  unused;		/* padding for removed uint32_t */
822};
823
824/*
825 * Definitions for the asynchronous callback CCB fields.
826 */
827typedef enum {
828	AC_UNIT_ATTENTION	= 0x4000,/* Device reported UNIT ATTENTION */
829	AC_ADVINFO_CHANGED	= 0x2000,/* Advance info might have changes */
830	AC_CONTRACT		= 0x1000,/* A contractual callback */
831	AC_GETDEV_CHANGED	= 0x800,/* Getdev info might have changed */
832	AC_INQ_CHANGED		= 0x400,/* Inquiry info might have changed */
833	AC_TRANSFER_NEG		= 0x200,/* New transfer settings in effect */
834	AC_LOST_DEVICE		= 0x100,/* A device went away */
835	AC_FOUND_DEVICE		= 0x080,/* A new device was found */
836	AC_PATH_DEREGISTERED	= 0x040,/* A path has de-registered */
837	AC_PATH_REGISTERED	= 0x020,/* A new path has been registered */
838	AC_SENT_BDR		= 0x010,/* A BDR message was sent to target */
839	AC_SCSI_AEN		= 0x008,/* A SCSI AEN has been received */
840	AC_UNSOL_RESEL		= 0x002,/* Unsolicited reselection occurred */
841	AC_BUS_RESET		= 0x001	/* A SCSI bus reset occurred */
842} ac_code;
843
844typedef void ac_callback_t (void *softc, u_int32_t code,
845			    struct cam_path *path, void *args);
846
847/*
848 * Generic Asynchronous callbacks.
849 *
850 * Generic arguments passed bac which are then interpreted between a per-system
851 * contract number.
852 */
853#define	AC_CONTRACT_DATA_MAX (128 - sizeof (u_int64_t))
854struct ac_contract {
855	u_int64_t	contract_number;
856	u_int8_t	contract_data[AC_CONTRACT_DATA_MAX];
857};
858
859#define	AC_CONTRACT_DEV_CHG	1
860struct ac_device_changed {
861	u_int64_t	wwpn;
862	u_int32_t	port;
863	target_id_t	target;
864	u_int8_t	arrived;
865};
866
867/* Set Asynchronous Callback CCB */
868struct ccb_setasync {
869	struct ccb_hdr	 ccb_h;
870	u_int32_t	 event_enable;	/* Async Event enables */
871	ac_callback_t	*callback;
872	void		*callback_arg;
873};
874
875/* Set Device Type CCB */
876struct ccb_setdev {
877	struct	   ccb_hdr ccb_h;
878	u_int8_t   dev_type;	/* Value for dev type field in EDT */
879};
880
881/* SCSI Control Functions */
882
883/* Abort XPT request CCB */
884struct ccb_abort {
885	struct 	ccb_hdr ccb_h;
886	union	ccb *abort_ccb;	/* Pointer to CCB to abort */
887};
888
889/* Reset SCSI Bus CCB */
890struct ccb_resetbus {
891	struct	ccb_hdr ccb_h;
892};
893
894/* Reset SCSI Device CCB */
895struct ccb_resetdev {
896	struct	ccb_hdr ccb_h;
897};
898
899/* Terminate I/O Process Request CCB */
900struct ccb_termio {
901	struct	ccb_hdr ccb_h;
902	union	ccb *termio_ccb;	/* Pointer to CCB to terminate */
903};
904
905typedef enum {
906	CTS_TYPE_CURRENT_SETTINGS,
907	CTS_TYPE_USER_SETTINGS
908} cts_type;
909
910struct ccb_trans_settings_scsi
911{
912	u_int	valid;	/* Which fields to honor */
913#define	CTS_SCSI_VALID_TQ		0x01
914	u_int	flags;
915#define	CTS_SCSI_FLAGS_TAG_ENB		0x01
916};
917
918struct ccb_trans_settings_ata
919{
920	u_int	valid;	/* Which fields to honor */
921#define	CTS_ATA_VALID_TQ		0x01
922	u_int	flags;
923#define	CTS_ATA_FLAGS_TAG_ENB		0x01
924};
925
926struct ccb_trans_settings_spi
927{
928	u_int	  valid;	/* Which fields to honor */
929#define	CTS_SPI_VALID_SYNC_RATE		0x01
930#define	CTS_SPI_VALID_SYNC_OFFSET	0x02
931#define	CTS_SPI_VALID_BUS_WIDTH		0x04
932#define	CTS_SPI_VALID_DISC		0x08
933#define CTS_SPI_VALID_PPR_OPTIONS	0x10
934	u_int	flags;
935#define	CTS_SPI_FLAGS_DISC_ENB		0x01
936	u_int	sync_period;
937	u_int	sync_offset;
938	u_int	bus_width;
939	u_int	ppr_options;
940};
941
942struct ccb_trans_settings_fc {
943	u_int     	valid;		/* Which fields to honor */
944#define	CTS_FC_VALID_WWNN		0x8000
945#define	CTS_FC_VALID_WWPN		0x4000
946#define	CTS_FC_VALID_PORT		0x2000
947#define	CTS_FC_VALID_SPEED		0x1000
948	u_int64_t	wwnn;		/* world wide node name */
949	u_int64_t 	wwpn;		/* world wide port name */
950	u_int32_t 	port;		/* 24 bit port id, if known */
951	u_int32_t 	bitrate;	/* Mbps */
952};
953
954struct ccb_trans_settings_sas {
955	u_int     	valid;		/* Which fields to honor */
956#define	CTS_SAS_VALID_SPEED		0x1000
957	u_int32_t 	bitrate;	/* Mbps */
958};
959
960struct ccb_trans_settings_pata {
961	u_int     	valid;		/* Which fields to honor */
962#define	CTS_ATA_VALID_MODE		0x01
963#define	CTS_ATA_VALID_BYTECOUNT		0x02
964#define	CTS_ATA_VALID_ATAPI		0x20
965#define	CTS_ATA_VALID_CAPS		0x40
966	int		mode;		/* Mode */
967	u_int 		bytecount;	/* Length of PIO transaction */
968	u_int 		atapi;		/* Length of ATAPI CDB */
969	u_int 		caps;		/* Device and host SATA caps. */
970#define	CTS_ATA_CAPS_H			0x0000ffff
971#define	CTS_ATA_CAPS_H_DMA48		0x00000001 /* 48-bit DMA */
972#define	CTS_ATA_CAPS_D			0xffff0000
973};
974
975struct ccb_trans_settings_sata {
976	u_int     	valid;		/* Which fields to honor */
977#define	CTS_SATA_VALID_MODE		0x01
978#define	CTS_SATA_VALID_BYTECOUNT	0x02
979#define	CTS_SATA_VALID_REVISION		0x04
980#define	CTS_SATA_VALID_PM		0x08
981#define	CTS_SATA_VALID_TAGS		0x10
982#define	CTS_SATA_VALID_ATAPI		0x20
983#define	CTS_SATA_VALID_CAPS		0x40
984	int		mode;		/* Legacy PATA mode */
985	u_int 		bytecount;	/* Length of PIO transaction */
986	int		revision;	/* SATA revision */
987	u_int 		pm_present;	/* PM is present (XPT->SIM) */
988	u_int 		tags;		/* Number of allowed tags */
989	u_int 		atapi;		/* Length of ATAPI CDB */
990	u_int 		caps;		/* Device and host SATA caps. */
991#define	CTS_SATA_CAPS_H			0x0000ffff
992#define	CTS_SATA_CAPS_H_PMREQ		0x00000001
993#define	CTS_SATA_CAPS_H_APST		0x00000002
994#define	CTS_SATA_CAPS_H_DMAAA		0x00000010 /* Auto-activation */
995#define	CTS_SATA_CAPS_H_AN		0x00000020 /* Async. notification */
996#define	CTS_SATA_CAPS_D			0xffff0000
997#define	CTS_SATA_CAPS_D_PMREQ		0x00010000
998#define	CTS_SATA_CAPS_D_APST		0x00020000
999};
1000
1001struct ccb_trans_settings_nvme
1002{
1003	u_int     	valid;		/* Which fields to honor */
1004#define CTS_NVME_VALID_SPEC	0x01
1005#define CTS_NVME_VALID_CAPS	0x02
1006#define CTS_NVME_VALID_LINK	0x04
1007	uint32_t	spec;		/* NVMe spec implemented -- same as vs register */
1008	uint32_t	max_xfer;	/* Max transfer size (0 -> unlimited */
1009	uint32_t	caps;
1010	uint8_t		lanes;		/* Number of PCIe lanes */
1011	uint8_t		speed;		/* PCIe generation for each lane */
1012	uint8_t		max_lanes;	/* Number of PCIe lanes */
1013	uint8_t		max_speed;	/* PCIe generation for each lane */
1014	u_int		pad;		/* Padding to keep ABI */
1015};
1016
1017/* Get/Set transfer rate/width/disconnection/tag queueing settings */
1018struct ccb_trans_settings {
1019	struct	  ccb_hdr ccb_h;
1020	cts_type  type;		/* Current or User settings */
1021	cam_proto protocol;
1022	u_int	  protocol_version;
1023	cam_xport transport;
1024	u_int	  transport_version;
1025	union {
1026		u_int  valid;	/* Which fields to honor */
1027		struct ccb_trans_settings_ata ata;
1028		struct ccb_trans_settings_scsi scsi;
1029		struct ccb_trans_settings_nvme nvme;
1030	} proto_specific;
1031	union {
1032		u_int  valid;	/* Which fields to honor */
1033		struct ccb_trans_settings_spi spi;
1034		struct ccb_trans_settings_fc fc;
1035		struct ccb_trans_settings_sas sas;
1036		struct ccb_trans_settings_pata ata;
1037		struct ccb_trans_settings_sata sata;
1038		struct ccb_trans_settings_nvme nvme;
1039	} xport_specific;
1040};
1041
1042
1043/*
1044 * Calculate the geometry parameters for a device
1045 * give the block size and volume size in blocks.
1046 */
1047struct ccb_calc_geometry {
1048	struct	  ccb_hdr ccb_h;
1049	u_int32_t block_size;
1050	u_int64_t volume_size;
1051	u_int32_t cylinders;
1052	u_int8_t  heads;
1053	u_int8_t  secs_per_track;
1054};
1055
1056/*
1057 * Set or get SIM (and transport) specific knobs
1058 */
1059
1060#define	KNOB_VALID_ADDRESS	0x1
1061#define	KNOB_VALID_ROLE		0x2
1062
1063
1064#define	KNOB_ROLE_NONE		0x0
1065#define	KNOB_ROLE_INITIATOR	0x1
1066#define	KNOB_ROLE_TARGET	0x2
1067#define	KNOB_ROLE_BOTH		0x3
1068
1069struct ccb_sim_knob_settings_spi {
1070	u_int		valid;
1071	u_int		initiator_id;
1072	u_int		role;
1073};
1074
1075struct ccb_sim_knob_settings_fc {
1076	u_int		valid;
1077	u_int64_t	wwnn;		/* world wide node name */
1078	u_int64_t 	wwpn;		/* world wide port name */
1079	u_int		role;
1080};
1081
1082struct ccb_sim_knob_settings_sas {
1083	u_int		valid;
1084	u_int64_t	wwnn;		/* world wide node name */
1085	u_int		role;
1086};
1087#define	KNOB_SETTINGS_SIZE	128
1088
1089struct ccb_sim_knob {
1090	struct	  ccb_hdr ccb_h;
1091	union {
1092		u_int  valid;	/* Which fields to honor */
1093		struct ccb_sim_knob_settings_spi spi;
1094		struct ccb_sim_knob_settings_fc fc;
1095		struct ccb_sim_knob_settings_sas sas;
1096		char pad[KNOB_SETTINGS_SIZE];
1097	} xport_specific;
1098};
1099
1100/*
1101 * Rescan the given bus, or bus/target/lun
1102 */
1103struct ccb_rescan {
1104	struct	ccb_hdr ccb_h;
1105	cam_flags	flags;
1106};
1107
1108/*
1109 * Turn on debugging for the given bus, bus/target, or bus/target/lun.
1110 */
1111struct ccb_debug {
1112	struct	ccb_hdr ccb_h;
1113	cam_debug_flags flags;
1114};
1115
1116/* Target mode structures. */
1117
1118struct ccb_en_lun {
1119	struct	  ccb_hdr ccb_h;
1120	u_int16_t grp6_len;		/* Group 6 VU CDB length */
1121	u_int16_t grp7_len;		/* Group 7 VU CDB length */
1122	u_int8_t  enable;
1123};
1124
1125/* old, barely used immediate notify, binary compatibility */
1126struct ccb_immed_notify {
1127	struct	  ccb_hdr ccb_h;
1128	struct    scsi_sense_data sense_data;
1129	u_int8_t  sense_len;		/* Number of bytes in sense buffer */
1130	u_int8_t  initiator_id;		/* Id of initiator that selected */
1131	u_int8_t  message_args[7];	/* Message Arguments */
1132};
1133
1134struct ccb_notify_ack {
1135	struct	  ccb_hdr ccb_h;
1136	u_int16_t seq_id;		/* Sequence identifier */
1137	u_int8_t  event;		/* Event flags */
1138};
1139
1140struct ccb_immediate_notify {
1141	struct    ccb_hdr ccb_h;
1142	u_int     tag_id;		/* Tag for immediate notify */
1143	u_int     seq_id;		/* Tag for target of notify */
1144	u_int     initiator_id;		/* Initiator Identifier */
1145	u_int     arg;			/* Function specific */
1146};
1147
1148struct ccb_notify_acknowledge {
1149	struct    ccb_hdr ccb_h;
1150	u_int     tag_id;		/* Tag for immediate notify */
1151	u_int     seq_id;		/* Tar for target of notify */
1152	u_int     initiator_id;		/* Initiator Identifier */
1153	u_int     arg;			/* Response information */
1154	/*
1155	 * Lower byte of arg is one of RESPONSE CODE values defined below
1156	 * (subset of response codes from SPL-4 and FCP-4 specifications),
1157	 * upper 3 bytes is code-specific ADDITIONAL RESPONSE INFORMATION.
1158	 */
1159#define	CAM_RSP_TMF_COMPLETE		0x00
1160#define	CAM_RSP_TMF_REJECTED		0x04
1161#define	CAM_RSP_TMF_FAILED		0x05
1162#define	CAM_RSP_TMF_SUCCEEDED		0x08
1163#define	CAM_RSP_TMF_INCORRECT_LUN	0x09
1164};
1165
1166/* HBA engine structures. */
1167
1168typedef enum {
1169	EIT_BUFFER,	/* Engine type: buffer memory */
1170	EIT_LOSSLESS,	/* Engine type: lossless compression */
1171	EIT_LOSSY,	/* Engine type: lossy compression */
1172	EIT_ENCRYPT	/* Engine type: encryption */
1173} ei_type;
1174
1175typedef enum {
1176	EAD_VUNIQUE,	/* Engine algorithm ID: vendor unique */
1177	EAD_LZ1V1,	/* Engine algorithm ID: LZ1 var.1 */
1178	EAD_LZ2V1,	/* Engine algorithm ID: LZ2 var.1 */
1179	EAD_LZ2V2	/* Engine algorithm ID: LZ2 var.2 */
1180} ei_algo;
1181
1182struct ccb_eng_inq {
1183	struct	  ccb_hdr ccb_h;
1184	u_int16_t eng_num;	/* The engine number for this inquiry */
1185	ei_type   eng_type;	/* Returned engine type */
1186	ei_algo   eng_algo;	/* Returned engine algorithm type */
1187	u_int32_t eng_memeory;	/* Returned engine memory size */
1188};
1189
1190struct ccb_eng_exec {	/* This structure must match SCSIIO size */
1191	struct	  ccb_hdr ccb_h;
1192	u_int8_t  *pdrv_ptr;	/* Ptr used by the peripheral driver */
1193	u_int8_t  *req_map;	/* Ptr for mapping info on the req. */
1194	u_int8_t  *data_ptr;	/* Pointer to the data buf/SG list */
1195	u_int32_t dxfer_len;	/* Data transfer length */
1196	u_int8_t  *engdata_ptr;	/* Pointer to the engine buffer data */
1197	u_int16_t sglist_cnt;	/* Num of scatter gather list entries */
1198	u_int32_t dmax_len;	/* Destination data maximum length */
1199	u_int32_t dest_len;	/* Destination data length */
1200	int32_t	  src_resid;	/* Source residual length: 2's comp */
1201	u_int32_t timeout;	/* Timeout value */
1202	u_int16_t eng_num;	/* Engine number for this request */
1203	u_int16_t vu_flags;	/* Vendor Unique flags */
1204};
1205
1206/*
1207 * Definitions for the timeout field in the SCSI I/O CCB.
1208 */
1209#define	CAM_TIME_DEFAULT	0x00000000	/* Use SIM default value */
1210#define	CAM_TIME_INFINITY	0xFFFFFFFF	/* Infinite timeout */
1211
1212#define	CAM_SUCCESS	0	/* For signaling general success */
1213#define	CAM_FAILURE	1	/* For signaling general failure */
1214
1215#define CAM_FALSE	0
1216#define CAM_TRUE	1
1217
1218#define XPT_CCB_INVALID	-1	/* for signaling a bad CCB to free */
1219
1220/*
1221 * CCB for working with advanced device information.  This operates in a fashion
1222 * similar to XPT_GDEV_TYPE.  Specify the target in ccb_h, the buffer
1223 * type requested, and provide a buffer size/buffer to write to.  If the
1224 * buffer is too small, provsiz will be larger than bufsiz.
1225 */
1226struct ccb_dev_advinfo {
1227	struct ccb_hdr ccb_h;
1228	uint32_t flags;
1229#define	CDAI_FLAG_NONE		0x0	/* No flags set */
1230#define	CDAI_FLAG_STORE		0x1	/* If set, action becomes store */
1231	uint32_t buftype;		/* IN: Type of data being requested */
1232	/* NB: buftype is interpreted on a per-transport basis */
1233#define	CDAI_TYPE_SCSI_DEVID	1
1234#define	CDAI_TYPE_SERIAL_NUM	2
1235#define	CDAI_TYPE_PHYS_PATH	3
1236#define	CDAI_TYPE_RCAPLONG	4
1237#define	CDAI_TYPE_EXT_INQ	5
1238#define	CDAI_TYPE_NVME_CNTRL	6	/* NVMe Identify Controller data */
1239#define	CDAI_TYPE_NVME_NS	7	/* NVMe Identify Namespace data */
1240	off_t bufsiz;			/* IN: Size of external buffer */
1241#define	CAM_SCSI_DEVID_MAXLEN	65536	/* length in buffer is an uint16_t */
1242	off_t provsiz;			/* OUT: Size required/used */
1243	uint8_t *buf;			/* IN/OUT: Buffer for requested data */
1244};
1245
1246/*
1247 * CCB for sending async events
1248 */
1249struct ccb_async {
1250	struct ccb_hdr ccb_h;
1251	uint32_t async_code;
1252	off_t async_arg_size;
1253	void *async_arg_ptr;
1254};
1255
1256/*
1257 * Union of all CCB types for kernel space allocation.  This union should
1258 * never be used for manipulating CCBs - its only use is for the allocation
1259 * and deallocation of raw CCB space and is the return type of xpt_ccb_alloc
1260 * and the argument to xpt_ccb_free.
1261 */
1262union ccb {
1263	struct	ccb_hdr			ccb_h;	/* For convenience */
1264	struct	ccb_scsiio		csio;
1265	struct	ccb_getdev		cgd;
1266	struct	ccb_getdevlist		cgdl;
1267	struct	ccb_pathinq		cpi;
1268	struct	ccb_relsim		crs;
1269	struct	ccb_setasync		csa;
1270	struct	ccb_setdev		csd;
1271	struct	ccb_pathstats		cpis;
1272	struct	ccb_getdevstats		cgds;
1273	struct	ccb_dev_match		cdm;
1274	struct	ccb_trans_settings	cts;
1275	struct	ccb_calc_geometry	ccg;
1276	struct	ccb_sim_knob		knob;
1277	struct	ccb_abort		cab;
1278	struct	ccb_resetbus		crb;
1279	struct	ccb_resetdev		crd;
1280	struct	ccb_termio		tio;
1281	struct	ccb_accept_tio		atio;
1282	struct	ccb_scsiio		ctio;
1283	struct	ccb_en_lun		cel;
1284	struct	ccb_immed_notify	cin;
1285	struct	ccb_notify_ack		cna;
1286	struct	ccb_immediate_notify	cin1;
1287	struct	ccb_notify_acknowledge	cna2;
1288	struct	ccb_eng_inq		cei;
1289	struct	ccb_eng_exec		cee;
1290	struct	ccb_smpio		smpio;
1291	struct 	ccb_rescan		crcn;
1292	struct  ccb_debug		cdbg;
1293	struct	ccb_ataio		ataio;
1294	struct	ccb_dev_advinfo		cdai;
1295	struct	ccb_async		casync;
1296	struct	ccb_nvmeio		nvmeio;
1297};
1298
1299#define CCB_CLEAR_ALL_EXCEPT_HDR(ccbp)			\
1300	bzero((char *)(ccbp) + sizeof((ccbp)->ccb_h),	\
1301	    sizeof(*(ccbp)) - sizeof((ccbp)->ccb_h))
1302
1303__BEGIN_DECLS
1304static __inline void
1305cam_fill_csio(struct ccb_scsiio *csio, u_int32_t retries,
1306	      void (*cbfcnp)(struct cam_periph *, union ccb *),
1307	      u_int32_t flags, u_int8_t tag_action,
1308	      u_int8_t *data_ptr, u_int32_t dxfer_len,
1309	      u_int8_t sense_len, u_int8_t cdb_len,
1310	      u_int32_t timeout);
1311
1312static __inline void
1313cam_fill_nvmeio(struct ccb_nvmeio *nvmeio, u_int32_t retries,
1314	      void (*cbfcnp)(struct cam_periph *, union ccb *),
1315	      u_int32_t flags, u_int8_t *data_ptr, u_int32_t dxfer_len,
1316	      u_int32_t timeout);
1317
1318static __inline void
1319cam_fill_ctio(struct ccb_scsiio *csio, u_int32_t retries,
1320	      void (*cbfcnp)(struct cam_periph *, union ccb *),
1321	      u_int32_t flags, u_int tag_action, u_int tag_id,
1322	      u_int init_id, u_int scsi_status, u_int8_t *data_ptr,
1323	      u_int32_t dxfer_len, u_int32_t timeout);
1324
1325static __inline void
1326cam_fill_ataio(struct ccb_ataio *ataio, u_int32_t retries,
1327	      void (*cbfcnp)(struct cam_periph *, union ccb *),
1328	      u_int32_t flags, u_int tag_action,
1329	      u_int8_t *data_ptr, u_int32_t dxfer_len,
1330	      u_int32_t timeout);
1331
1332static __inline void
1333cam_fill_smpio(struct ccb_smpio *smpio, uint32_t retries,
1334	       void (*cbfcnp)(struct cam_periph *, union ccb *), uint32_t flags,
1335	       uint8_t *smp_request, int smp_request_len,
1336	       uint8_t *smp_response, int smp_response_len,
1337	       uint32_t timeout);
1338
1339static __inline void
1340cam_fill_csio(struct ccb_scsiio *csio, u_int32_t retries,
1341	      void (*cbfcnp)(struct cam_periph *, union ccb *),
1342	      u_int32_t flags, u_int8_t tag_action,
1343	      u_int8_t *data_ptr, u_int32_t dxfer_len,
1344	      u_int8_t sense_len, u_int8_t cdb_len,
1345	      u_int32_t timeout)
1346{
1347	csio->ccb_h.func_code = XPT_SCSI_IO;
1348	csio->ccb_h.flags = flags;
1349	csio->ccb_h.xflags = 0;
1350	csio->ccb_h.retry_count = retries;
1351	csio->ccb_h.cbfcnp = cbfcnp;
1352	csio->ccb_h.timeout = timeout;
1353	csio->data_ptr = data_ptr;
1354	csio->dxfer_len = dxfer_len;
1355	csio->sense_len = sense_len;
1356	csio->cdb_len = cdb_len;
1357	csio->tag_action = tag_action;
1358}
1359
1360static __inline void
1361cam_fill_ctio(struct ccb_scsiio *csio, u_int32_t retries,
1362	      void (*cbfcnp)(struct cam_periph *, union ccb *),
1363	      u_int32_t flags, u_int tag_action, u_int tag_id,
1364	      u_int init_id, u_int scsi_status, u_int8_t *data_ptr,
1365	      u_int32_t dxfer_len, u_int32_t timeout)
1366{
1367	csio->ccb_h.func_code = XPT_CONT_TARGET_IO;
1368	csio->ccb_h.flags = flags;
1369	csio->ccb_h.xflags = 0;
1370	csio->ccb_h.retry_count = retries;
1371	csio->ccb_h.cbfcnp = cbfcnp;
1372	csio->ccb_h.timeout = timeout;
1373	csio->data_ptr = data_ptr;
1374	csio->dxfer_len = dxfer_len;
1375	csio->scsi_status = scsi_status;
1376	csio->tag_action = tag_action;
1377	csio->tag_id = tag_id;
1378	csio->init_id = init_id;
1379}
1380
1381static __inline void
1382cam_fill_ataio(struct ccb_ataio *ataio, u_int32_t retries,
1383	      void (*cbfcnp)(struct cam_periph *, union ccb *),
1384	      u_int32_t flags, u_int tag_action __unused,
1385	      u_int8_t *data_ptr, u_int32_t dxfer_len,
1386	      u_int32_t timeout)
1387{
1388	ataio->ccb_h.func_code = XPT_ATA_IO;
1389	ataio->ccb_h.flags = flags;
1390	ataio->ccb_h.retry_count = retries;
1391	ataio->ccb_h.cbfcnp = cbfcnp;
1392	ataio->ccb_h.timeout = timeout;
1393	ataio->data_ptr = data_ptr;
1394	ataio->dxfer_len = dxfer_len;
1395	ataio->ata_flags = 0;
1396}
1397
1398static __inline void
1399cam_fill_smpio(struct ccb_smpio *smpio, uint32_t retries,
1400	       void (*cbfcnp)(struct cam_periph *, union ccb *), uint32_t flags,
1401	       uint8_t *smp_request, int smp_request_len,
1402	       uint8_t *smp_response, int smp_response_len,
1403	       uint32_t timeout)
1404{
1405#ifdef _KERNEL
1406	KASSERT((flags & CAM_DIR_MASK) == CAM_DIR_BOTH,
1407		("direction != CAM_DIR_BOTH"));
1408	KASSERT((smp_request != NULL) && (smp_response != NULL),
1409		("need valid request and response buffers"));
1410	KASSERT((smp_request_len != 0) && (smp_response_len != 0),
1411		("need non-zero request and response lengths"));
1412#endif /*_KERNEL*/
1413	smpio->ccb_h.func_code = XPT_SMP_IO;
1414	smpio->ccb_h.flags = flags;
1415	smpio->ccb_h.retry_count = retries;
1416	smpio->ccb_h.cbfcnp = cbfcnp;
1417	smpio->ccb_h.timeout = timeout;
1418	smpio->smp_request = smp_request;
1419	smpio->smp_request_len = smp_request_len;
1420	smpio->smp_response = smp_response;
1421	smpio->smp_response_len = smp_response_len;
1422}
1423
1424static __inline void
1425cam_set_ccbstatus(union ccb *ccb, cam_status status)
1426{
1427	ccb->ccb_h.status &= ~CAM_STATUS_MASK;
1428	ccb->ccb_h.status |= status;
1429}
1430
1431static __inline cam_status
1432cam_ccb_status(union ccb *ccb)
1433{
1434	return ((cam_status)(ccb->ccb_h.status & CAM_STATUS_MASK));
1435}
1436
1437void cam_calc_geometry(struct ccb_calc_geometry *ccg, int extended);
1438
1439static __inline void
1440cam_fill_nvmeio(struct ccb_nvmeio *nvmeio, u_int32_t retries,
1441	      void (*cbfcnp)(struct cam_periph *, union ccb *),
1442	      u_int32_t flags, u_int8_t *data_ptr, u_int32_t dxfer_len,
1443	      u_int32_t timeout)
1444{
1445	nvmeio->ccb_h.func_code = XPT_NVME_IO;
1446	nvmeio->ccb_h.flags = flags;
1447	nvmeio->ccb_h.retry_count = retries;
1448	nvmeio->ccb_h.cbfcnp = cbfcnp;
1449	nvmeio->ccb_h.timeout = timeout;
1450	nvmeio->data_ptr = data_ptr;
1451	nvmeio->dxfer_len = dxfer_len;
1452}
1453
1454static __inline void
1455cam_fill_nvmeadmin(struct ccb_nvmeio *nvmeio, u_int32_t retries,
1456	      void (*cbfcnp)(struct cam_periph *, union ccb *),
1457	      u_int32_t flags, u_int8_t *data_ptr, u_int32_t dxfer_len,
1458	      u_int32_t timeout)
1459{
1460	nvmeio->ccb_h.func_code = XPT_NVME_ADMIN;
1461	nvmeio->ccb_h.flags = flags;
1462	nvmeio->ccb_h.retry_count = retries;
1463	nvmeio->ccb_h.cbfcnp = cbfcnp;
1464	nvmeio->ccb_h.timeout = timeout;
1465	nvmeio->data_ptr = data_ptr;
1466	nvmeio->dxfer_len = dxfer_len;
1467}
1468__END_DECLS
1469
1470#endif /* _CAM_CAM_CCB_H */
1471