xref: /freebsd/sys/cam/ctl/ctl_io.h (revision 59657816)
1130f4520SKenneth D. Merry /*-
24d846d26SWarner Losh  * SPDX-License-Identifier: BSD-2-Clause
3bec9534dSPedro F. Giffuni  *
4130f4520SKenneth D. Merry  * Copyright (c) 2003 Silicon Graphics International Corp.
5648dfc1aSAlexander Motin  * Copyright (c) 2014-2015 Alexander Motin <mav@FreeBSD.org>
6130f4520SKenneth D. Merry  * All rights reserved.
7130f4520SKenneth D. Merry  *
8130f4520SKenneth D. Merry  * Redistribution and use in source and binary forms, with or without
9130f4520SKenneth D. Merry  * modification, are permitted provided that the following conditions
10130f4520SKenneth D. Merry  * are met:
11130f4520SKenneth D. Merry  * 1. Redistributions of source code must retain the above copyright
12130f4520SKenneth D. Merry  *    notice, this list of conditions, and the following disclaimer,
13130f4520SKenneth D. Merry  *    without modification.
14130f4520SKenneth D. Merry  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
15130f4520SKenneth D. Merry  *    substantially similar to the "NO WARRANTY" disclaimer below
16130f4520SKenneth D. Merry  *    ("Disclaimer") and any redistribution must be conditioned upon
17130f4520SKenneth D. Merry  *    including a substantially similar Disclaimer requirement for further
18130f4520SKenneth D. Merry  *    binary redistribution.
19130f4520SKenneth D. Merry  *
20130f4520SKenneth D. Merry  * NO WARRANTY
21130f4520SKenneth D. Merry  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22130f4520SKenneth D. Merry  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23130f4520SKenneth D. Merry  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
24130f4520SKenneth D. Merry  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25130f4520SKenneth D. Merry  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26130f4520SKenneth D. Merry  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27130f4520SKenneth D. Merry  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28130f4520SKenneth D. Merry  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
29130f4520SKenneth D. Merry  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
30130f4520SKenneth D. Merry  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31130f4520SKenneth D. Merry  * POSSIBILITY OF SUCH DAMAGES.
32130f4520SKenneth D. Merry  *
33130f4520SKenneth D. Merry  * $Id: //depot/users/kenm/FreeBSD-test2/sys/cam/ctl/ctl_io.h#5 $
34130f4520SKenneth D. Merry  */
35130f4520SKenneth D. Merry /*
36130f4520SKenneth D. Merry  * CAM Target Layer data movement structures/interface.
37130f4520SKenneth D. Merry  *
38130f4520SKenneth D. Merry  * Author: Ken Merry <ken@FreeBSD.org>
39130f4520SKenneth D. Merry  */
40130f4520SKenneth D. Merry 
41130f4520SKenneth D. Merry #ifndef	_CTL_IO_H_
42130f4520SKenneth D. Merry #define	_CTL_IO_H_
43130f4520SKenneth D. Merry 
44c02a2875SAlexander Motin #ifndef _KERNEL
45c02a2875SAlexander Motin #include <stdbool.h>
46c02a2875SAlexander Motin #endif
47c02a2875SAlexander Motin 
484efebb3dSJohn Baldwin #include <sys/queue.h>
494efebb3dSJohn Baldwin #include <cam/scsi/scsi_all.h>
50*59657816SJohn Baldwin #include <dev/nvme/nvme.h>
514efebb3dSJohn Baldwin 
52130f4520SKenneth D. Merry #define	CTL_MAX_CDBLEN	32
53130f4520SKenneth D. Merry /*
54130f4520SKenneth D. Merry  * Uncomment this next line to enable printing out times for I/Os
55130f4520SKenneth D. Merry  * that take longer than CTL_TIME_IO_SECS seconds to get to the datamove
56130f4520SKenneth D. Merry  * and/or done stage.
57130f4520SKenneth D. Merry  */
58130f4520SKenneth D. Merry #define	CTL_TIME_IO
59130f4520SKenneth D. Merry #ifdef  CTL_TIME_IO
60130f4520SKenneth D. Merry #define	CTL_TIME_IO_DEFAULT_SECS	90
61130f4520SKenneth D. Merry #endif
62130f4520SKenneth D. Merry 
63130f4520SKenneth D. Merry /*
643f326305SAlexander Motin  * Uncomment this next line to enable the CTL I/O delay feature.  You
65130f4520SKenneth D. Merry  * can delay I/O at two different points -- datamove and done.  This is
66130f4520SKenneth D. Merry  * useful for diagnosing abort conditions (for hosts that send an abort on a
67130f4520SKenneth D. Merry  * timeout), and for determining how long a host's timeout is.
68130f4520SKenneth D. Merry  */
693f326305SAlexander Motin //#define	CTL_IO_DELAY
70130f4520SKenneth D. Merry 
71130f4520SKenneth D. Merry typedef enum {
72130f4520SKenneth D. Merry 	CTL_STATUS_NONE,	/* No status */
73130f4520SKenneth D. Merry 	CTL_SUCCESS,		/* Transaction completed successfully */
74130f4520SKenneth D. Merry 	CTL_CMD_TIMEOUT,	/* Command timed out, shouldn't happen here */
75130f4520SKenneth D. Merry 	CTL_SEL_TIMEOUT,	/* Selection timeout, shouldn't happen here */
76130f4520SKenneth D. Merry 	CTL_ERROR,		/* General CTL error XXX expand on this? */
77130f4520SKenneth D. Merry 	CTL_SCSI_ERROR,		/* SCSI error, look at status byte/sense data */
78*59657816SJohn Baldwin 	CTL_NVME_ERROR,		/* NVMe error, look at NVMe completion */
79130f4520SKenneth D. Merry 	CTL_CMD_ABORTED,	/* Command aborted, don't return status */
80130f4520SKenneth D. Merry 	CTL_STATUS_MASK = 0xfff,/* Mask off any status flags */
81130f4520SKenneth D. Merry 	CTL_AUTOSENSE = 0x1000	/* Autosense performed */
82130f4520SKenneth D. Merry } ctl_io_status;
83130f4520SKenneth D. Merry 
84130f4520SKenneth D. Merry /*
85130f4520SKenneth D. Merry  * WARNING:  Keep the data in/out/none flags where they are.  They're used
861ffe5851SPedro F. Giffuni  * in conjunction with ctl_cmd_flags.  See comment above ctl_cmd_flags
87130f4520SKenneth D. Merry  * definition in ctl_private.h.
88130f4520SKenneth D. Merry  */
89130f4520SKenneth D. Merry typedef enum {
90130f4520SKenneth D. Merry 	CTL_FLAG_NONE		= 0x00000000,	/* no flags */
91130f4520SKenneth D. Merry 	CTL_FLAG_DATA_IN	= 0x00000001,	/* DATA IN */
92130f4520SKenneth D. Merry 	CTL_FLAG_DATA_OUT	= 0x00000002,	/* DATA OUT */
93130f4520SKenneth D. Merry 	CTL_FLAG_DATA_NONE	= 0x00000003,	/* no data */
94130f4520SKenneth D. Merry 	CTL_FLAG_DATA_MASK	= 0x00000003,
957467a695SAlexander Motin 	CTL_FLAG_USER_TAG	= 0x00000020,	/* userland provides tag */
96130f4520SKenneth D. Merry 	CTL_FLAG_USER_REQ	= 0x00000040,	/* request came from userland */
97130f4520SKenneth D. Merry 	CTL_FLAG_ALLOCATED	= 0x00000100,	/* data space allocated */
98b33b96e3SAlexander Motin 	CTL_FLAG_ABORT_STATUS	= 0x00000400,	/* return TASK ABORTED status */
99130f4520SKenneth D. Merry 	CTL_FLAG_ABORT		= 0x00000800,	/* this I/O should be aborted */
100130f4520SKenneth D. Merry 	CTL_FLAG_DMA_INPROG	= 0x00001000,	/* DMA in progress */
101130f4520SKenneth D. Merry 	CTL_FLAG_DELAY_DONE	= 0x00004000,	/* delay injection done */
102130f4520SKenneth D. Merry 	CTL_FLAG_INT_COPY	= 0x00008000,	/* internal copy, no done call*/
103130f4520SKenneth D. Merry 	CTL_FLAG_SENT_2OTHER_SC	= 0x00010000,
104130f4520SKenneth D. Merry 	CTL_FLAG_FROM_OTHER_SC	= 0x00020000,
105130f4520SKenneth D. Merry 	CTL_FLAG_IS_WAS_ON_RTR  = 0x00040000,	/* Don't rerun cmd on failover*/
106130f4520SKenneth D. Merry 	CTL_FLAG_BUS_ADDR	= 0x00080000,	/* ctl_sglist contains BUS
107130f4520SKenneth D. Merry 						   addresses, not virtual ones*/
108130f4520SKenneth D. Merry 	CTL_FLAG_IO_CONT	= 0x00100000,	/* Continue I/O instead of
109130f4520SKenneth D. Merry 						   completing */
110130f4520SKenneth D. Merry #if 0
111105eee97SJohn Baldwin 	CTL_FLAG_ALREADY_DONE	= 0x00200000,	/* I/O already completed */
112130f4520SKenneth D. Merry #endif
113130f4520SKenneth D. Merry 	CTL_FLAG_NO_DATAMOVE	= 0x00400000,
114130f4520SKenneth D. Merry 	CTL_FLAG_DMA_QUEUED	= 0x00800000,	/* DMA queued but not started*/
115130f4520SKenneth D. Merry 	CTL_FLAG_STATUS_QUEUED	= 0x01000000,	/* Status queued but not sent*/
116130f4520SKenneth D. Merry 
117130f4520SKenneth D. Merry 	CTL_FLAG_FAILOVER	= 0x04000000,	/* Killed by a failover */
118130f4520SKenneth D. Merry 	CTL_FLAG_IO_ACTIVE	= 0x08000000,	/* I/O active on this SC */
11975a3108eSAlexander Motin 	CTL_FLAG_STATUS_SENT	= 0x10000000,	/* Status sent by datamove */
12075a3108eSAlexander Motin 	CTL_FLAG_SERSEQ_DONE	= 0x20000000	/* All storage I/O started */
121130f4520SKenneth D. Merry } ctl_io_flags;
122130f4520SKenneth D. Merry 
123130f4520SKenneth D. Merry struct ctl_lba_len {
124130f4520SKenneth D. Merry 	uint64_t lba;
125130f4520SKenneth D. Merry 	uint32_t len;
126130f4520SKenneth D. Merry };
127130f4520SKenneth D. Merry 
128ee7f31c0SAlexander Motin struct ctl_lba_len_flags {
129ee7f31c0SAlexander Motin 	uint64_t lba;
130ee7f31c0SAlexander Motin 	uint32_t len;
131ee7f31c0SAlexander Motin 	uint32_t flags;
13255551d05SAlexander Motin #define CTL_LLF_FUA	0x04000000
13355551d05SAlexander Motin #define CTL_LLF_DPO	0x08000000
13411b569f7SAlexander Motin #define CTL_LLF_READ	0x10000000
13511b569f7SAlexander Motin #define CTL_LLF_WRITE	0x20000000
13611b569f7SAlexander Motin #define CTL_LLF_VERIFY	0x40000000
13711b569f7SAlexander Motin #define CTL_LLF_COMPARE	0x80000000
138ee7f31c0SAlexander Motin };
139ee7f31c0SAlexander Motin 
140ee7f31c0SAlexander Motin struct ctl_ptr_len_flags {
141ee7f31c0SAlexander Motin 	uint8_t		*ptr;
142ee7f31c0SAlexander Motin 	uint32_t	len;
143ee7f31c0SAlexander Motin 	uint32_t	flags;
144ee7f31c0SAlexander Motin };
145ee7f31c0SAlexander Motin 
146130f4520SKenneth D. Merry union ctl_priv {
147130f4520SKenneth D. Merry 	uint8_t		bytes[sizeof(uint64_t) * 2];
148130f4520SKenneth D. Merry 	uint64_t	integer;
149e67ac203SAlexander Motin 	uint64_t	integers[2];
150130f4520SKenneth D. Merry 	void		*ptr;
151e67ac203SAlexander Motin 	void		*ptrs[2];
152130f4520SKenneth D. Merry };
153130f4520SKenneth D. Merry 
154130f4520SKenneth D. Merry /*
155130f4520SKenneth D. Merry  * Number of CTL private areas.
156130f4520SKenneth D. Merry  */
157130f4520SKenneth D. Merry #define	CTL_NUM_PRIV	6
158130f4520SKenneth D. Merry 
159130f4520SKenneth D. Merry /*
160130f4520SKenneth D. Merry  * Which private area are we using for a particular piece of data?
161130f4520SKenneth D. Merry  */
162130f4520SKenneth D. Merry #define	CTL_PRIV_LUN		0	/* CTL LUN pointer goes here */
163130f4520SKenneth D. Merry #define	CTL_PRIV_LBA_LEN	1	/* Decoded LBA/len for read/write*/
164130f4520SKenneth D. Merry #define	CTL_PRIV_MODEPAGE	1	/* Modepage info for config write */
165130f4520SKenneth D. Merry #define	CTL_PRIV_BACKEND	2	/* Reserved for block, RAIDCore */
166130f4520SKenneth D. Merry #define	CTL_PRIV_BACKEND_LUN	3	/* Backend LUN pointer */
1677278725bSAlexander Motin #define	CTL_PRIV_FRONTEND	4	/* Frontend storage */
1687278725bSAlexander Motin #define	CTL_PRIV_FRONTEND2	5	/* Another frontend storage */
169130f4520SKenneth D. Merry 
1709cbbfd2fSAlexander Motin #define CTL_LUN(io)	((io)->io_hdr.ctl_private[CTL_PRIV_LUN].ptrs[0])
1719cbbfd2fSAlexander Motin #define CTL_SOFTC(io)	((io)->io_hdr.ctl_private[CTL_PRIV_LUN].ptrs[1])
1729cbbfd2fSAlexander Motin #define CTL_BACKEND_LUN(io)	((io)->io_hdr.ctl_private[CTL_PRIV_BACKEND_LUN].ptrs[0])
1739cbbfd2fSAlexander Motin #define CTL_PORT(io)	(((struct ctl_softc *)CTL_SOFTC(io))->	\
1749cbbfd2fSAlexander Motin     ctl_ports[(io)->io_hdr.nexus.targ_port])
1759cbbfd2fSAlexander Motin 
17662e802cfSAlexander Motin /*
17762e802cfSAlexander Motin  * These are used only on Originating SC in XFER mode, where requests don't
17862e802cfSAlexander Motin  * ever reach backends, so we can reuse backend's private storage.
17962e802cfSAlexander Motin  */
18062e802cfSAlexander Motin #define CTL_RSGL(io)	((io)->io_hdr.ctl_private[CTL_PRIV_BACKEND].ptrs[0])
18162e802cfSAlexander Motin #define CTL_LSGL(io)	((io)->io_hdr.ctl_private[CTL_PRIV_BACKEND].ptrs[1])
18262e802cfSAlexander Motin #define CTL_RSGLT(io)	((struct ctl_sg_entry *)CTL_RSGL(io))
18362e802cfSAlexander Motin #define CTL_LSGLT(io)	((struct ctl_sg_entry *)CTL_LSGL(io))
18462e802cfSAlexander Motin 
185130f4520SKenneth D. Merry #define CTL_INVALID_PORTNAME 0xFF
186130f4520SKenneth D. Merry #define CTL_UNMAPPED_IID     0xFF
187130f4520SKenneth D. Merry 
188130f4520SKenneth D. Merry struct ctl_sg_entry {
189130f4520SKenneth D. Merry 	void	*addr;
190130f4520SKenneth D. Merry 	size_t	len;
191130f4520SKenneth D. Merry };
192130f4520SKenneth D. Merry 
193130f4520SKenneth D. Merry typedef enum {
194130f4520SKenneth D. Merry 	CTL_IO_NONE,
195130f4520SKenneth D. Merry 	CTL_IO_SCSI,
196130f4520SKenneth D. Merry 	CTL_IO_TASK,
197*59657816SJohn Baldwin 	CTL_IO_NVME,
198*59657816SJohn Baldwin 	CTL_IO_NVME_ADMIN,
199130f4520SKenneth D. Merry } ctl_io_type;
200130f4520SKenneth D. Merry 
201130f4520SKenneth D. Merry struct ctl_nexus {
202fb606ebaSAlexander Motin 	uint32_t initid;		/* Initiator ID */
203130f4520SKenneth D. Merry 	uint32_t targ_port;		/* Target port, filled in by PORT */
204130f4520SKenneth D. Merry 	uint32_t targ_lun;		/* Destination lun */
2053a8ce4a3SAlexander Motin 	uint32_t targ_mapped_lun;	/* Destination lun CTL-wide */
206130f4520SKenneth D. Merry };
207130f4520SKenneth D. Merry 
208130f4520SKenneth D. Merry typedef enum {
209130f4520SKenneth D. Merry 	CTL_MSG_SERIALIZE,
210130f4520SKenneth D. Merry 	CTL_MSG_R2R,
211130f4520SKenneth D. Merry 	CTL_MSG_FINISH_IO,
212130f4520SKenneth D. Merry 	CTL_MSG_BAD_JUJU,
213130f4520SKenneth D. Merry 	CTL_MSG_MANAGE_TASKS,
214130f4520SKenneth D. Merry 	CTL_MSG_PERS_ACTION,
215130f4520SKenneth D. Merry 	CTL_MSG_DATAMOVE,
2167ac58230SAlexander Motin 	CTL_MSG_DATAMOVE_DONE,
2177ac58230SAlexander Motin 	CTL_MSG_UA,			/* Set/clear UA on secondary. */
2187ac58230SAlexander Motin 	CTL_MSG_PORT_SYNC,		/* Information about port. */
2197ac58230SAlexander Motin 	CTL_MSG_LUN_SYNC,		/* Information about LUN. */
2200c05f0dcSAlexander Motin 	CTL_MSG_IID_SYNC,		/* Information about initiator. */
221a85700a9SAlexander Motin 	CTL_MSG_LOGIN,			/* Information about HA peer. */
222ca85b7c4SAlexander Motin 	CTL_MSG_MODE_SYNC,		/* Mode page current content. */
2237ac58230SAlexander Motin 	CTL_MSG_FAILOVER		/* Fake, never sent though the wire */
224130f4520SKenneth D. Merry } ctl_msg_type;
225130f4520SKenneth D. Merry 
226130f4520SKenneth D. Merry struct ctl_scsiio;
227130f4520SKenneth D. Merry 
228130f4520SKenneth D. Merry struct ctl_io_hdr {
229130f4520SKenneth D. Merry 	uint32_t	  version;	/* interface version XXX */
230130f4520SKenneth D. Merry 	ctl_io_type	  io_type;	/* task I/O, SCSI I/O, etc. */
231130f4520SKenneth D. Merry 	ctl_msg_type	  msg_type;
232130f4520SKenneth D. Merry 	struct ctl_nexus  nexus;	/* Initiator, port, target, lun */
233130f4520SKenneth D. Merry 	uint32_t	  iid_indx;	/* the index into the iid mapping */
234130f4520SKenneth D. Merry 	uint32_t	  flags;	/* transaction flags */
235130f4520SKenneth D. Merry 	uint32_t	  status;	/* transaction status */
236130f4520SKenneth D. Merry 	uint32_t	  port_status;	/* trans status, set by PORT, 0 = good*/
237130f4520SKenneth D. Merry 	uint32_t	  timeout;	/* timeout in ms */
238130f4520SKenneth D. Merry 	uint32_t	  retries;	/* retry count */
239130f4520SKenneth D. Merry #ifdef CTL_IO_DELAY
2403f326305SAlexander Motin 	struct callout	  delay_callout;
241130f4520SKenneth D. Merry #endif /* CTL_IO_DELAY */
242130f4520SKenneth D. Merry #ifdef CTL_TIME_IO
243130f4520SKenneth D. Merry 	time_t		  start_time;	/* I/O start time */
244130f4520SKenneth D. Merry 	struct bintime	  start_bt;	/* Timer start ticks */
245130f4520SKenneth D. Merry 	struct bintime	  dma_start_bt;	/* DMA start ticks */
246130f4520SKenneth D. Merry 	struct bintime	  dma_bt;	/* DMA total ticks */
247130f4520SKenneth D. Merry #endif /* CTL_TIME_IO */
248e675024aSAlexander Motin 	uint32_t	  num_dmas;	/* Number of DMAs */
24962e802cfSAlexander Motin 	union ctl_io	  *remote_io;	/* I/O counterpart on remote HA side */
250321f819bSAlexander Motin 	union ctl_io	  *blocker;	/* I/O blocking this one */
251130f4520SKenneth D. Merry 	void		  *pool;	/* I/O pool */
252130f4520SKenneth D. Merry 	union ctl_priv	  ctl_private[CTL_NUM_PRIV];/* CTL private area */
253321f819bSAlexander Motin 	TAILQ_HEAD(, ctl_io_hdr) blocked_queue;	/* I/Os blocked by this one */
254130f4520SKenneth D. Merry 	STAILQ_ENTRY(ctl_io_hdr) links;	/* linked list pointer */
25505d882b7SAlexander Motin 	LIST_ENTRY(ctl_io_hdr) ooa_links;	/* ooa_queue links */
256321f819bSAlexander Motin 	TAILQ_ENTRY(ctl_io_hdr) blocked_links;	/* blocked_queue links */
257130f4520SKenneth D. Merry };
258130f4520SKenneth D. Merry 
259130f4520SKenneth D. Merry typedef enum {
260130f4520SKenneth D. Merry 	CTL_TAG_UNTAGGED,
261130f4520SKenneth D. Merry 	CTL_TAG_SIMPLE,
262130f4520SKenneth D. Merry 	CTL_TAG_ORDERED,
263130f4520SKenneth D. Merry 	CTL_TAG_HEAD_OF_QUEUE,
264130f4520SKenneth D. Merry 	CTL_TAG_ACA
265130f4520SKenneth D. Merry } ctl_tag_type;
266130f4520SKenneth D. Merry 
267130f4520SKenneth D. Merry union ctl_io;
268130f4520SKenneth D. Merry 
2699a4510acSAlexander Motin typedef void (*ctl_ref)(void *arg, int diff);
270*59657816SJohn Baldwin typedef int (*ctl_be_move_done_t)(union ctl_io *io, bool samethr);
271*59657816SJohn Baldwin typedef int (*ctl_io_cont)(union ctl_io *io);
2729a4510acSAlexander Motin 
273130f4520SKenneth D. Merry /*
274130f4520SKenneth D. Merry  * SCSI passthrough I/O structure for the CAM Target Layer.  Note
275130f4520SKenneth D. Merry  * that some of these fields are here for completeness, but they aren't
276130f4520SKenneth D. Merry  * used in the CTL implementation.  e.g., timeout and retries won't be
277130f4520SKenneth D. Merry  * used.
278130f4520SKenneth D. Merry  *
279130f4520SKenneth D. Merry  * Note:  Make sure the io_hdr is *always* the first element in this
280130f4520SKenneth D. Merry  * structure.
281130f4520SKenneth D. Merry  */
282130f4520SKenneth D. Merry struct ctl_scsiio {
283130f4520SKenneth D. Merry 	struct ctl_io_hdr io_hdr;	/* common to all I/O types */
2848cd22f5eSEdward Tomasz Napierala 
2858cd22f5eSEdward Tomasz Napierala 	/*
2868cd22f5eSEdward Tomasz Napierala 	 * The ext_* fields are generally intended for frontend use; CTL itself
2878cd22f5eSEdward Tomasz Napierala 	 * doesn't modify or use them.
2888cd22f5eSEdward Tomasz Napierala 	 */
289130f4520SKenneth D. Merry 	uint32_t   ext_sg_entries;	/* 0 = no S/G list, > 0 = num entries */
290130f4520SKenneth D. Merry 	uint8_t	   *ext_data_ptr;	/* data buffer or S/G list */
291130f4520SKenneth D. Merry 	uint32_t   ext_data_len;	/* Data transfer length */
292130f4520SKenneth D. Merry 	uint32_t   ext_data_filled;	/* Amount of data filled so far */
2938cd22f5eSEdward Tomasz Napierala 
2948cd22f5eSEdward Tomasz Napierala 	/*
2958cd22f5eSEdward Tomasz Napierala 	 * The number of scatter/gather entries in the list pointed to
2968cd22f5eSEdward Tomasz Napierala 	 * by kern_data_ptr.  0 means there is no list, just a data pointer.
2978cd22f5eSEdward Tomasz Napierala 	 */
2988cd22f5eSEdward Tomasz Napierala 	uint32_t   kern_sg_entries;
2998cd22f5eSEdward Tomasz Napierala 
3008cd22f5eSEdward Tomasz Napierala 	uint32_t   rem_sg_entries;	/* Unused. */
3018cd22f5eSEdward Tomasz Napierala 
3028cd22f5eSEdward Tomasz Napierala 	/*
3038cd22f5eSEdward Tomasz Napierala 	 * The data pointer or a pointer to the scatter/gather list.
3048cd22f5eSEdward Tomasz Napierala 	 */
3058cd22f5eSEdward Tomasz Napierala 	uint8_t    *kern_data_ptr;
3068cd22f5eSEdward Tomasz Napierala 
3078cd22f5eSEdward Tomasz Napierala 	/*
3088cd22f5eSEdward Tomasz Napierala 	 * Length of the data buffer or scatter/gather list.  It's also
3098cd22f5eSEdward Tomasz Napierala 	 * the length of this particular piece of the data transfer,
3108cd22f5eSEdward Tomasz Napierala 	 * ie. number of bytes expected to be transferred by the current
3118cd22f5eSEdward Tomasz Napierala 	 * invocation of frontend's datamove() callback.  It's always
3128cd22f5eSEdward Tomasz Napierala 	 * less than or equal to kern_total_len.
3138cd22f5eSEdward Tomasz Napierala 	 */
3148cd22f5eSEdward Tomasz Napierala 	uint32_t   kern_data_len;
3158cd22f5eSEdward Tomasz Napierala 
3168cd22f5eSEdward Tomasz Napierala 	/*
3178cd22f5eSEdward Tomasz Napierala 	 * Total length of data to be transferred during this particular
3188cd22f5eSEdward Tomasz Napierala 	 * SCSI command, as decoded from SCSI CDB.
3198cd22f5eSEdward Tomasz Napierala 	 */
3208cd22f5eSEdward Tomasz Napierala 	uint32_t   kern_total_len;
3218cd22f5eSEdward Tomasz Napierala 
3228cd22f5eSEdward Tomasz Napierala 	/*
3238cd22f5eSEdward Tomasz Napierala 	 * Amount of data left after the current data transfer.
3248cd22f5eSEdward Tomasz Napierala 	 */
3258cd22f5eSEdward Tomasz Napierala 	uint32_t   kern_data_resid;
3268cd22f5eSEdward Tomasz Napierala 
3278cd22f5eSEdward Tomasz Napierala 	/*
3288cd22f5eSEdward Tomasz Napierala 	 * Byte offset of this transfer, equal to the amount of data
3298cd22f5eSEdward Tomasz Napierala 	 * already transferred for this SCSI command during previous
3308cd22f5eSEdward Tomasz Napierala 	 * datamove() invocations.
3318cd22f5eSEdward Tomasz Napierala 	 */
3328cd22f5eSEdward Tomasz Napierala 	uint32_t   kern_rel_offset;
3338cd22f5eSEdward Tomasz Napierala 
334130f4520SKenneth D. Merry 	struct     scsi_sense_data sense_data;	/* sense data */
335130f4520SKenneth D. Merry 	uint8_t	   sense_len;		/* Returned sense length */
336130f4520SKenneth D. Merry 	uint8_t	   scsi_status;		/* SCSI status byte */
3379d9fd8b7SAlexander Motin 	uint8_t	   seridx;		/* Serialization index. */
33888364968SAlexander Motin 	uint8_t	   priority;		/* Command priority */
3390acc026dSAlexander Motin 	uint64_t   tag_num;		/* tag number */
340130f4520SKenneth D. Merry 	ctl_tag_type tag_type;		/* simple, ordered, head of queue,etc.*/
341130f4520SKenneth D. Merry 	uint8_t    cdb_len;		/* CDB length */
342130f4520SKenneth D. Merry 	uint8_t	   cdb[CTL_MAX_CDBLEN];	/* CDB */
343*59657816SJohn Baldwin 	ctl_be_move_done_t be_move_done;	/* called by fe */
344*59657816SJohn Baldwin 	ctl_io_cont io_cont;		/* to continue processing */
3459a4510acSAlexander Motin 	ctl_ref	    kern_data_ref;	/* Method to reference/release data */
3469a4510acSAlexander Motin 	void	   *kern_data_arg;	/* Opaque argument for kern_data_ref() */
347130f4520SKenneth D. Merry };
348130f4520SKenneth D. Merry 
349130f4520SKenneth D. Merry typedef enum {
350130f4520SKenneth D. Merry 	CTL_TASK_ABORT_TASK,
351130f4520SKenneth D. Merry 	CTL_TASK_ABORT_TASK_SET,
352130f4520SKenneth D. Merry 	CTL_TASK_CLEAR_ACA,
353130f4520SKenneth D. Merry 	CTL_TASK_CLEAR_TASK_SET,
3540020682bSAlexander Motin 	CTL_TASK_I_T_NEXUS_RESET,
355130f4520SKenneth D. Merry 	CTL_TASK_LUN_RESET,
356130f4520SKenneth D. Merry 	CTL_TASK_TARGET_RESET,
357130f4520SKenneth D. Merry 	CTL_TASK_BUS_RESET,
358130f4520SKenneth D. Merry 	CTL_TASK_PORT_LOGIN,
359ceff31dcSAlexander Motin 	CTL_TASK_PORT_LOGOUT,
360ceff31dcSAlexander Motin 	CTL_TASK_QUERY_TASK,
361ceff31dcSAlexander Motin 	CTL_TASK_QUERY_TASK_SET,
362ceff31dcSAlexander Motin 	CTL_TASK_QUERY_ASYNC_EVENT
363130f4520SKenneth D. Merry } ctl_task_type;
364130f4520SKenneth D. Merry 
365ceff31dcSAlexander Motin typedef enum {
366ceff31dcSAlexander Motin 	CTL_TASK_FUNCTION_COMPLETE,
367ceff31dcSAlexander Motin 	CTL_TASK_FUNCTION_SUCCEEDED,
368ceff31dcSAlexander Motin 	CTL_TASK_FUNCTION_REJECTED,
369ceff31dcSAlexander Motin 	CTL_TASK_LUN_DOES_NOT_EXIST,
370ceff31dcSAlexander Motin 	CTL_TASK_FUNCTION_NOT_SUPPORTED
371ceff31dcSAlexander Motin } ctl_task_status;
372ceff31dcSAlexander Motin 
373130f4520SKenneth D. Merry /*
374130f4520SKenneth D. Merry  * Task management I/O structure.  Aborts, bus resets, etc., are sent using
375130f4520SKenneth D. Merry  * this structure.
376130f4520SKenneth D. Merry  *
377130f4520SKenneth D. Merry  * Note:  Make sure the io_hdr is *always* the first element in this
378130f4520SKenneth D. Merry  * structure.
379130f4520SKenneth D. Merry  */
380130f4520SKenneth D. Merry struct ctl_taskio {
381130f4520SKenneth D. Merry 	struct ctl_io_hdr	io_hdr;      /* common to all I/O types */
382130f4520SKenneth D. Merry 	ctl_task_type		task_action; /* Target Reset, Abort, etc.  */
3830acc026dSAlexander Motin 	uint64_t		tag_num;     /* tag number */
384130f4520SKenneth D. Merry 	ctl_tag_type		tag_type;    /* simple, ordered, etc. */
385ceff31dcSAlexander Motin 	uint8_t			task_status; /* Complete, Succeeded, etc. */
386ceff31dcSAlexander Motin 	uint8_t			task_resp[3];/* Response information */
387130f4520SKenneth D. Merry };
388130f4520SKenneth D. Merry 
389a85700a9SAlexander Motin /*
390*59657816SJohn Baldwin  * NVME passthrough I/O structure for the CAM Target Layer.  Note that
391*59657816SJohn Baldwin  * this structure is used for both I/O and admin commands.
392*59657816SJohn Baldwin  *
393*59657816SJohn Baldwin  * Note:  Make sure the io_hdr is *always* the first element in this
394*59657816SJohn Baldwin  * structure.
395*59657816SJohn Baldwin  */
396*59657816SJohn Baldwin struct ctl_nvmeio {
397*59657816SJohn Baldwin 	struct ctl_io_hdr io_hdr;	/* common to all I/O types */
398*59657816SJohn Baldwin 
399*59657816SJohn Baldwin 	/*
400*59657816SJohn Baldwin 	 * The ext_* fields are generally intended for frontend use; CTL itself
401*59657816SJohn Baldwin 	 * doesn't modify or use them.
402*59657816SJohn Baldwin 	 */
403*59657816SJohn Baldwin 	uint32_t   ext_sg_entries;	/* 0 = no S/G list, > 0 = num entries */
404*59657816SJohn Baldwin 	uint8_t	   *ext_data_ptr;	/* data buffer or S/G list */
405*59657816SJohn Baldwin 	uint32_t   ext_data_len;	/* Data transfer length */
406*59657816SJohn Baldwin 	uint32_t   ext_data_filled;	/* Amount of data filled so far */
407*59657816SJohn Baldwin 
408*59657816SJohn Baldwin 	/*
409*59657816SJohn Baldwin 	 * The number of scatter/gather entries in the list pointed to
410*59657816SJohn Baldwin 	 * by kern_data_ptr.  0 means there is no list, just a data pointer.
411*59657816SJohn Baldwin 	 */
412*59657816SJohn Baldwin 	uint32_t   kern_sg_entries;
413*59657816SJohn Baldwin 
414*59657816SJohn Baldwin 	/*
415*59657816SJohn Baldwin 	 * The data pointer or a pointer to the scatter/gather list.
416*59657816SJohn Baldwin 	 */
417*59657816SJohn Baldwin 	uint8_t    *kern_data_ptr;
418*59657816SJohn Baldwin 
419*59657816SJohn Baldwin 	/*
420*59657816SJohn Baldwin 	 * Length of the data buffer or scatter/gather list.  It's also
421*59657816SJohn Baldwin 	 * the length of this particular piece of the data transfer,
422*59657816SJohn Baldwin 	 * ie. number of bytes expected to be transferred by the current
423*59657816SJohn Baldwin 	 * invocation of frontend's datamove() callback.  It's always
424*59657816SJohn Baldwin 	 * less than or equal to kern_total_len.
425*59657816SJohn Baldwin 	 */
426*59657816SJohn Baldwin 	uint32_t   kern_data_len;
427*59657816SJohn Baldwin 
428*59657816SJohn Baldwin 	/*
429*59657816SJohn Baldwin 	 * Total length of data to be transferred during this particular
430*59657816SJohn Baldwin 	 * NVMe command, as decoded from the NVMe SQE.
431*59657816SJohn Baldwin 	 */
432*59657816SJohn Baldwin 	uint32_t   kern_total_len;
433*59657816SJohn Baldwin 
434*59657816SJohn Baldwin 	/*
435*59657816SJohn Baldwin 	 * Amount of data left after the current data transfer.
436*59657816SJohn Baldwin 	 */
437*59657816SJohn Baldwin 	uint32_t   kern_data_resid;
438*59657816SJohn Baldwin 
439*59657816SJohn Baldwin 	/*
440*59657816SJohn Baldwin 	 * Byte offset of this transfer, equal to the amount of data
441*59657816SJohn Baldwin 	 * already transferred for this NVMe command during previous
442*59657816SJohn Baldwin 	 * datamove() invocations.
443*59657816SJohn Baldwin 	 */
444*59657816SJohn Baldwin 	uint32_t   kern_rel_offset;
445*59657816SJohn Baldwin 
446*59657816SJohn Baldwin 	struct nvme_command cmd;	/* SQE */
447*59657816SJohn Baldwin 	struct nvme_completion cpl;	/* CQE */
448*59657816SJohn Baldwin 	bool       success_sent;	/* datamove already sent CQE */
449*59657816SJohn Baldwin 	ctl_be_move_done_t be_move_done;	/* called by fe */
450*59657816SJohn Baldwin 	ctl_io_cont io_cont;		/* to continue processing */
451*59657816SJohn Baldwin 	ctl_ref	    kern_data_ref;	/* Method to reference/release data */
452*59657816SJohn Baldwin 	void	   *kern_data_arg;	/* Opaque argument for kern_data_ref() */
453*59657816SJohn Baldwin };
454*59657816SJohn Baldwin 
455*59657816SJohn Baldwin /*
456a85700a9SAlexander Motin  * HA link messages.
457a85700a9SAlexander Motin  */
4580acc026dSAlexander Motin #define	CTL_HA_VERSION		4
459a85700a9SAlexander Motin 
460a85700a9SAlexander Motin /*
461a85700a9SAlexander Motin  * Used for CTL_MSG_LOGIN.
462a85700a9SAlexander Motin  */
463a85700a9SAlexander Motin struct ctl_ha_msg_login {
464a85700a9SAlexander Motin 	ctl_msg_type		msg_type;
465a85700a9SAlexander Motin 	int			version;
466a85700a9SAlexander Motin 	int			ha_mode;
467a85700a9SAlexander Motin 	int			ha_id;
468a85700a9SAlexander Motin 	int			max_luns;
469a85700a9SAlexander Motin 	int			max_ports;
470a85700a9SAlexander Motin 	int			max_init_per_port;
471a85700a9SAlexander Motin };
472a85700a9SAlexander Motin 
473130f4520SKenneth D. Merry typedef enum {
474130f4520SKenneth D. Merry 	CTL_PR_REG_KEY,
475130f4520SKenneth D. Merry 	CTL_PR_UNREG_KEY,
476130f4520SKenneth D. Merry 	CTL_PR_PREEMPT,
477130f4520SKenneth D. Merry 	CTL_PR_CLEAR,
478130f4520SKenneth D. Merry 	CTL_PR_RESERVE,
479130f4520SKenneth D. Merry 	CTL_PR_RELEASE
480130f4520SKenneth D. Merry } ctl_pr_action;
481130f4520SKenneth D. Merry 
482130f4520SKenneth D. Merry /*
483130f4520SKenneth D. Merry  * The PR info is specifically for sending Persistent Reserve actions
484130f4520SKenneth D. Merry  * to the other SC which it must also act on.
485130f4520SKenneth D. Merry  *
486130f4520SKenneth D. Merry  * Note:  Make sure the io_hdr is *always* the first element in this
487130f4520SKenneth D. Merry  * structure.
488130f4520SKenneth D. Merry  */
489130f4520SKenneth D. Merry struct ctl_pr_info {
490130f4520SKenneth D. Merry 	ctl_pr_action		action;
491130f4520SKenneth D. Merry 	uint8_t			sa_res_key[8];
492130f4520SKenneth D. Merry 	uint8_t			res_type;
4938cbf9eaeSAlexander Motin 	uint32_t		residx;
494130f4520SKenneth D. Merry };
495130f4520SKenneth D. Merry 
496130f4520SKenneth D. Merry struct ctl_ha_msg_hdr {
497130f4520SKenneth D. Merry 	ctl_msg_type		msg_type;
498027dd0cfSAlexander Motin 	uint32_t		status;	     /* transaction status */
499130f4520SKenneth D. Merry 	union ctl_io		*original_sc;
500130f4520SKenneth D. Merry 	union ctl_io		*serializing_sc;
501130f4520SKenneth D. Merry 	struct ctl_nexus	nexus;	     /* Initiator, port, target, lun */
502130f4520SKenneth D. Merry };
503130f4520SKenneth D. Merry 
504130f4520SKenneth D. Merry #define	CTL_HA_MAX_SG_ENTRIES	16
5057ac58230SAlexander Motin #define	CTL_HA_DATAMOVE_SEGMENT	131072
506130f4520SKenneth D. Merry 
507130f4520SKenneth D. Merry /*
508130f4520SKenneth D. Merry  * Used for CTL_MSG_PERS_ACTION.
509130f4520SKenneth D. Merry  */
510130f4520SKenneth D. Merry struct ctl_ha_msg_pr {
511130f4520SKenneth D. Merry 	struct ctl_ha_msg_hdr	hdr;
512130f4520SKenneth D. Merry 	struct ctl_pr_info	pr_info;
513130f4520SKenneth D. Merry };
514130f4520SKenneth D. Merry 
515130f4520SKenneth D. Merry /*
5167ac58230SAlexander Motin  * Used for CTL_MSG_UA.
5177ac58230SAlexander Motin  */
5187ac58230SAlexander Motin struct ctl_ha_msg_ua {
5197ac58230SAlexander Motin 	struct ctl_ha_msg_hdr	hdr;
5207ac58230SAlexander Motin 	int			ua_all;
5217ac58230SAlexander Motin 	int			ua_set;
5227ac58230SAlexander Motin 	int			ua_type;
52362138827SAlexander Motin 	uint8_t			ua_info[8];
5247ac58230SAlexander Motin };
5257ac58230SAlexander Motin 
5267ac58230SAlexander Motin /*
527130f4520SKenneth D. Merry  * The S/G handling here is a little different than the standard ctl_scsiio
528130f4520SKenneth D. Merry  * structure, because we can't pass data by reference in between controllers.
529130f4520SKenneth D. Merry  * The S/G list in the ctl_scsiio struct is normally passed in the
530130f4520SKenneth D. Merry  * kern_data_ptr field.  So kern_sg_entries here will always be non-zero,
531130f4520SKenneth D. Merry  * even if there is only one entry.
532130f4520SKenneth D. Merry  *
533130f4520SKenneth D. Merry  * Used for CTL_MSG_DATAMOVE.
534130f4520SKenneth D. Merry  */
535130f4520SKenneth D. Merry struct ctl_ha_msg_dt {
536130f4520SKenneth D. Merry 	struct ctl_ha_msg_hdr	hdr;
537130f4520SKenneth D. Merry 	ctl_io_flags		flags;  /* Only I/O flags are used here */
538130f4520SKenneth D. Merry 	uint32_t		sg_sequence;     /* S/G portion number  */
539130f4520SKenneth D. Merry 	uint8_t			sg_last;         /* last S/G batch = 1 */
540130f4520SKenneth D. Merry 	uint32_t		sent_sg_entries; /* previous S/G count */
541130f4520SKenneth D. Merry 	uint32_t		cur_sg_entries;  /* current S/G entries */
542130f4520SKenneth D. Merry 	uint32_t		kern_sg_entries; /* total S/G entries */
543130f4520SKenneth D. Merry 	uint32_t		kern_data_len;   /* Length of this S/G list */
544130f4520SKenneth D. Merry 	uint32_t		kern_total_len;  /* Total length of this
545130f4520SKenneth D. Merry 						    transaction */
546130f4520SKenneth D. Merry 	uint32_t		kern_data_resid; /* Length left to transfer
547130f4520SKenneth D. Merry 						    after this*/
548130f4520SKenneth D. Merry 	uint32_t		kern_rel_offset; /* Byte Offset of this
549130f4520SKenneth D. Merry 						    transfer */
550130f4520SKenneth D. Merry 	struct ctl_sg_entry	sg_list[CTL_HA_MAX_SG_ENTRIES];
551130f4520SKenneth D. Merry };
552130f4520SKenneth D. Merry 
553130f4520SKenneth D. Merry /*
554640603fbSAlexander Motin  * Used for CTL_MSG_SERIALIZE, CTL_MSG_FINISH_IO, CTL_MSG_BAD_JUJU,
555640603fbSAlexander Motin  * and CTL_MSG_DATAMOVE_DONE.
556130f4520SKenneth D. Merry  */
557130f4520SKenneth D. Merry struct ctl_ha_msg_scsi {
558130f4520SKenneth D. Merry 	struct ctl_ha_msg_hdr	hdr;
5590acc026dSAlexander Motin 	uint64_t		tag_num;     /* tag number */
560130f4520SKenneth D. Merry 	ctl_tag_type		tag_type;    /* simple, ordered, etc. */
5617ac58230SAlexander Motin 	uint8_t			cdb[CTL_MAX_CDBLEN];	/* CDB */
5627ac58230SAlexander Motin 	uint8_t			cdb_len;	/* CDB length */
563130f4520SKenneth D. Merry 	uint8_t			scsi_status; /* SCSI status byte */
564130f4520SKenneth D. Merry 	uint8_t			sense_len;   /* Returned sense length */
56588364968SAlexander Motin 	uint8_t			priority;    /* Command priority */
566640603fbSAlexander Motin 	uint32_t		port_status; /* trans status, set by FETD,
567130f4520SKenneth D. Merry 						0 = good*/
568640603fbSAlexander Motin 	uint32_t		kern_data_resid; /* for DATAMOVE_DONE */
5697ac58230SAlexander Motin 	struct scsi_sense_data	sense_data;  /* sense data */
570130f4520SKenneth D. Merry };
571130f4520SKenneth D. Merry 
572130f4520SKenneth D. Merry /*
573130f4520SKenneth D. Merry  * Used for CTL_MSG_MANAGE_TASKS.
574130f4520SKenneth D. Merry  */
575130f4520SKenneth D. Merry struct ctl_ha_msg_task {
576130f4520SKenneth D. Merry 	struct ctl_ha_msg_hdr	hdr;
577130f4520SKenneth D. Merry 	ctl_task_type		task_action; /* Target Reset, Abort, etc.  */
5780acc026dSAlexander Motin 	uint64_t		tag_num;     /* tag number */
579130f4520SKenneth D. Merry 	ctl_tag_type		tag_type;    /* simple, ordered, etc. */
580130f4520SKenneth D. Merry };
581130f4520SKenneth D. Merry 
5827ac58230SAlexander Motin /*
5837ac58230SAlexander Motin  * Used for CTL_MSG_PORT_SYNC.
5847ac58230SAlexander Motin  */
5857ac58230SAlexander Motin struct ctl_ha_msg_port {
5867ac58230SAlexander Motin 	struct ctl_ha_msg_hdr	hdr;
5877ac58230SAlexander Motin 	int			port_type;
5887ac58230SAlexander Motin 	int			physical_port;
5897ac58230SAlexander Motin 	int			virtual_port;
5907ac58230SAlexander Motin 	int			status;
5917ac58230SAlexander Motin 	int			name_len;
5927ac58230SAlexander Motin 	int			lun_map_len;
5937ac58230SAlexander Motin 	int			port_devid_len;
5947ac58230SAlexander Motin 	int			target_devid_len;
59554713bceSAlexander Motin 	int			init_devid_len;
5967ac58230SAlexander Motin 	uint8_t			data[];
5977ac58230SAlexander Motin };
5987ac58230SAlexander Motin 
5997ac58230SAlexander Motin /*
6007ac58230SAlexander Motin  * Used for CTL_MSG_LUN_SYNC.
6017ac58230SAlexander Motin  */
6027ac58230SAlexander Motin struct ctl_ha_msg_lun {
6037ac58230SAlexander Motin 	struct ctl_ha_msg_hdr	hdr;
6047ac58230SAlexander Motin 	int			flags;
6057ac58230SAlexander Motin 	unsigned int		pr_generation;
6067ac58230SAlexander Motin 	uint32_t		pr_res_idx;
6077ac58230SAlexander Motin 	uint8_t			pr_res_type;
6087ac58230SAlexander Motin 	int			lun_devid_len;
6097ac58230SAlexander Motin 	int			pr_key_count;
6107ac58230SAlexander Motin 	uint8_t			data[];
6117ac58230SAlexander Motin };
6127ac58230SAlexander Motin 
6137ac58230SAlexander Motin struct ctl_ha_msg_lun_pr_key {
6147ac58230SAlexander Motin 	uint32_t		pr_iid;
6157ac58230SAlexander Motin 	uint64_t		pr_key;
6167ac58230SAlexander Motin };
6177ac58230SAlexander Motin 
6180c05f0dcSAlexander Motin /*
6190c05f0dcSAlexander Motin  * Used for CTL_MSG_IID_SYNC.
6200c05f0dcSAlexander Motin  */
6210c05f0dcSAlexander Motin struct ctl_ha_msg_iid {
6220c05f0dcSAlexander Motin 	struct ctl_ha_msg_hdr	hdr;
6230c05f0dcSAlexander Motin 	int			in_use;
6240c05f0dcSAlexander Motin 	int			name_len;
6250c05f0dcSAlexander Motin 	uint64_t		wwpn;
6260c05f0dcSAlexander Motin 	uint8_t			data[];
6270c05f0dcSAlexander Motin };
6280c05f0dcSAlexander Motin 
629ca85b7c4SAlexander Motin /*
630ca85b7c4SAlexander Motin  * Used for CTL_MSG_MODE_SYNC.
631ca85b7c4SAlexander Motin  */
632ca85b7c4SAlexander Motin struct ctl_ha_msg_mode {
633ca85b7c4SAlexander Motin 	struct ctl_ha_msg_hdr	hdr;
634ca85b7c4SAlexander Motin 	uint8_t			page_code;
635ca85b7c4SAlexander Motin 	uint8_t			subpage;
636ca85b7c4SAlexander Motin 	uint16_t		page_len;
637ca85b7c4SAlexander Motin 	uint8_t			data[];
638ca85b7c4SAlexander Motin };
639ca85b7c4SAlexander Motin 
640130f4520SKenneth D. Merry union ctl_ha_msg {
641130f4520SKenneth D. Merry 	struct ctl_ha_msg_hdr	hdr;
642130f4520SKenneth D. Merry 	struct ctl_ha_msg_task	task;
643130f4520SKenneth D. Merry 	struct ctl_ha_msg_scsi	scsi;
644130f4520SKenneth D. Merry 	struct ctl_ha_msg_dt	dt;
645130f4520SKenneth D. Merry 	struct ctl_ha_msg_pr	pr;
6467ac58230SAlexander Motin 	struct ctl_ha_msg_ua	ua;
6477ac58230SAlexander Motin 	struct ctl_ha_msg_port	port;
6487ac58230SAlexander Motin 	struct ctl_ha_msg_lun	lun;
6490c05f0dcSAlexander Motin 	struct ctl_ha_msg_iid	iid;
650a85700a9SAlexander Motin 	struct ctl_ha_msg_login	login;
651ca85b7c4SAlexander Motin 	struct ctl_ha_msg_mode	mode;
652130f4520SKenneth D. Merry };
653130f4520SKenneth D. Merry 
654130f4520SKenneth D. Merry struct ctl_prio {
655130f4520SKenneth D. Merry 	struct ctl_io_hdr	io_hdr;
656130f4520SKenneth D. Merry 	struct ctl_ha_msg_pr	pr_msg;
657130f4520SKenneth D. Merry };
658130f4520SKenneth D. Merry 
659130f4520SKenneth D. Merry union ctl_io {
660130f4520SKenneth D. Merry 	struct ctl_io_hdr	io_hdr;	/* common to all I/O types */
661130f4520SKenneth D. Merry 	struct ctl_scsiio	scsiio;	/* Normal SCSI commands */
662130f4520SKenneth D. Merry 	struct ctl_taskio	taskio;	/* SCSI task management/reset */
663*59657816SJohn Baldwin 	struct ctl_nvmeio	nvmeio;	/* Normal and admin NVMe commands */
664130f4520SKenneth D. Merry 	struct ctl_prio		presio;	/* update per. res info on other SC */
665130f4520SKenneth D. Merry };
666130f4520SKenneth D. Merry 
667130f4520SKenneth D. Merry #ifdef _KERNEL
668ac7a514eSJohn Baldwin #define	_CTL_IO_ASSERT_1(io, _1)					\
669ac7a514eSJohn Baldwin 	KASSERT((io)->io_hdr.io_type == CTL_IO_##_1,			\
670ac7a514eSJohn Baldwin 	    ("%s: unexpected I/O type %x", __func__, (io)->io_hdr.io_type))
671ac7a514eSJohn Baldwin 
672ac7a514eSJohn Baldwin #define	_CTL_IO_ASSERT_2(io, _1, _2)					\
673ac7a514eSJohn Baldwin 	KASSERT((io)->io_hdr.io_type == CTL_IO_##_1 ||			\
674ac7a514eSJohn Baldwin 	    (io)->io_hdr.io_type == CTL_IO_##_2,			\
675ac7a514eSJohn Baldwin 	    ("%s: unexpected I/O type %x", __func__, (io)->io_hdr.io_type))
676ac7a514eSJohn Baldwin 
677ac7a514eSJohn Baldwin #define	_CTL_IO_ASSERT_MACRO(io, _1, _2, NAME, ...)			\
678ac7a514eSJohn Baldwin 	NAME
679ac7a514eSJohn Baldwin 
680ac7a514eSJohn Baldwin #define	CTL_IO_ASSERT(...)						\
681ac7a514eSJohn Baldwin 	_CTL_IO_ASSERT_MACRO(__VA_ARGS__, _CTL_IO_ASSERT_2,		\
682ac7a514eSJohn Baldwin 	    _CTL_IO_ASSERT_1)(__VA_ARGS__)
683130f4520SKenneth D. Merry 
684*59657816SJohn Baldwin static __inline uint32_t
ctl_kern_sg_entries(union ctl_io * io)685*59657816SJohn Baldwin ctl_kern_sg_entries(union ctl_io *io)
686*59657816SJohn Baldwin {
687*59657816SJohn Baldwin 	switch (io->io_hdr.io_type) {
688*59657816SJohn Baldwin 	case CTL_IO_SCSI:
689*59657816SJohn Baldwin 		return (io->scsiio.kern_sg_entries);
690*59657816SJohn Baldwin 	case CTL_IO_NVME:
691*59657816SJohn Baldwin 	case CTL_IO_NVME_ADMIN:
692*59657816SJohn Baldwin 		return (io->nvmeio.kern_sg_entries);
693*59657816SJohn Baldwin 	default:
694*59657816SJohn Baldwin 		__assert_unreachable();
695*59657816SJohn Baldwin 	}
696*59657816SJohn Baldwin }
697*59657816SJohn Baldwin 
698*59657816SJohn Baldwin static __inline uint8_t *
ctl_kern_data_ptr(union ctl_io * io)699*59657816SJohn Baldwin ctl_kern_data_ptr(union ctl_io *io)
700*59657816SJohn Baldwin {
701*59657816SJohn Baldwin 	switch (io->io_hdr.io_type) {
702*59657816SJohn Baldwin 	case CTL_IO_SCSI:
703*59657816SJohn Baldwin 		return (io->scsiio.kern_data_ptr);
704*59657816SJohn Baldwin 	case CTL_IO_NVME:
705*59657816SJohn Baldwin 	case CTL_IO_NVME_ADMIN:
706*59657816SJohn Baldwin 		return (io->nvmeio.kern_data_ptr);
707*59657816SJohn Baldwin 	default:
708*59657816SJohn Baldwin 		__assert_unreachable();
709*59657816SJohn Baldwin 	}
710*59657816SJohn Baldwin }
711*59657816SJohn Baldwin 
712*59657816SJohn Baldwin static __inline uint32_t
ctl_kern_data_len(union ctl_io * io)713*59657816SJohn Baldwin ctl_kern_data_len(union ctl_io *io)
714*59657816SJohn Baldwin {
715*59657816SJohn Baldwin 	switch (io->io_hdr.io_type) {
716*59657816SJohn Baldwin 	case CTL_IO_SCSI:
717*59657816SJohn Baldwin 		return (io->scsiio.kern_data_len);
718*59657816SJohn Baldwin 	case CTL_IO_NVME:
719*59657816SJohn Baldwin 	case CTL_IO_NVME_ADMIN:
720*59657816SJohn Baldwin 		return (io->nvmeio.kern_data_len);
721*59657816SJohn Baldwin 	default:
722*59657816SJohn Baldwin 		__assert_unreachable();
723*59657816SJohn Baldwin 	}
724*59657816SJohn Baldwin }
725*59657816SJohn Baldwin 
726*59657816SJohn Baldwin static __inline uint32_t
ctl_kern_total_len(union ctl_io * io)727*59657816SJohn Baldwin ctl_kern_total_len(union ctl_io *io)
728*59657816SJohn Baldwin {
729*59657816SJohn Baldwin 	switch (io->io_hdr.io_type) {
730*59657816SJohn Baldwin 	case CTL_IO_SCSI:
731*59657816SJohn Baldwin 		return (io->scsiio.kern_total_len);
732*59657816SJohn Baldwin 	case CTL_IO_NVME:
733*59657816SJohn Baldwin 	case CTL_IO_NVME_ADMIN:
734*59657816SJohn Baldwin 		return (io->nvmeio.kern_total_len);
735*59657816SJohn Baldwin 	default:
736*59657816SJohn Baldwin 		__assert_unreachable();
737*59657816SJohn Baldwin 	}
738*59657816SJohn Baldwin }
739*59657816SJohn Baldwin 
740*59657816SJohn Baldwin static __inline uint32_t
ctl_kern_data_resid(union ctl_io * io)741*59657816SJohn Baldwin ctl_kern_data_resid(union ctl_io *io)
742*59657816SJohn Baldwin {
743*59657816SJohn Baldwin 	switch (io->io_hdr.io_type) {
744*59657816SJohn Baldwin 	case CTL_IO_SCSI:
745*59657816SJohn Baldwin 		return (io->scsiio.kern_data_resid);
746*59657816SJohn Baldwin 	case CTL_IO_NVME:
747*59657816SJohn Baldwin 	case CTL_IO_NVME_ADMIN:
748*59657816SJohn Baldwin 		return (io->nvmeio.kern_data_resid);
749*59657816SJohn Baldwin 	default:
750*59657816SJohn Baldwin 		__assert_unreachable();
751*59657816SJohn Baldwin 	}
752*59657816SJohn Baldwin }
753*59657816SJohn Baldwin 
754*59657816SJohn Baldwin static __inline uint32_t
ctl_kern_rel_offset(union ctl_io * io)755*59657816SJohn Baldwin ctl_kern_rel_offset(union ctl_io *io)
756*59657816SJohn Baldwin {
757*59657816SJohn Baldwin 	switch (io->io_hdr.io_type) {
758*59657816SJohn Baldwin 	case CTL_IO_SCSI:
759*59657816SJohn Baldwin 		return (io->scsiio.kern_rel_offset);
760*59657816SJohn Baldwin 	case CTL_IO_NVME:
761*59657816SJohn Baldwin 	case CTL_IO_NVME_ADMIN:
762*59657816SJohn Baldwin 		return (io->nvmeio.kern_rel_offset);
763*59657816SJohn Baldwin 	default:
764*59657816SJohn Baldwin 		__assert_unreachable();
765*59657816SJohn Baldwin 	}
766*59657816SJohn Baldwin }
767*59657816SJohn Baldwin 
768*59657816SJohn Baldwin static __inline void
ctl_add_kern_rel_offset(union ctl_io * io,uint32_t offset)769*59657816SJohn Baldwin ctl_add_kern_rel_offset(union ctl_io *io, uint32_t offset)
770*59657816SJohn Baldwin {
771*59657816SJohn Baldwin 	switch (io->io_hdr.io_type) {
772*59657816SJohn Baldwin 	case CTL_IO_SCSI:
773*59657816SJohn Baldwin 		io->scsiio.kern_rel_offset += offset;
774*59657816SJohn Baldwin 		break;
775*59657816SJohn Baldwin 	case CTL_IO_NVME:
776*59657816SJohn Baldwin 	case CTL_IO_NVME_ADMIN:
777*59657816SJohn Baldwin 		io->nvmeio.kern_rel_offset += offset;
778*59657816SJohn Baldwin 		break;
779*59657816SJohn Baldwin 	default:
780*59657816SJohn Baldwin 		__assert_unreachable();
781*59657816SJohn Baldwin 	}
782*59657816SJohn Baldwin }
783*59657816SJohn Baldwin 
784*59657816SJohn Baldwin static __inline void
ctl_set_kern_sg_entries(union ctl_io * io,uint32_t kern_sg_entries)785*59657816SJohn Baldwin ctl_set_kern_sg_entries(union ctl_io *io, uint32_t kern_sg_entries)
786*59657816SJohn Baldwin {
787*59657816SJohn Baldwin 	switch (io->io_hdr.io_type) {
788*59657816SJohn Baldwin 	case CTL_IO_SCSI:
789*59657816SJohn Baldwin 		io->scsiio.kern_sg_entries = kern_sg_entries;
790*59657816SJohn Baldwin 		break;
791*59657816SJohn Baldwin 	case CTL_IO_NVME:
792*59657816SJohn Baldwin 	case CTL_IO_NVME_ADMIN:
793*59657816SJohn Baldwin 		io->nvmeio.kern_sg_entries = kern_sg_entries;
794*59657816SJohn Baldwin 		break;
795*59657816SJohn Baldwin 	default:
796*59657816SJohn Baldwin 		__assert_unreachable();
797*59657816SJohn Baldwin 	}
798*59657816SJohn Baldwin }
799*59657816SJohn Baldwin 
800*59657816SJohn Baldwin static __inline void
ctl_set_kern_data_ptr(union ctl_io * io,void * kern_data_ptr)801*59657816SJohn Baldwin ctl_set_kern_data_ptr(union ctl_io *io, void *kern_data_ptr)
802*59657816SJohn Baldwin {
803*59657816SJohn Baldwin 	switch (io->io_hdr.io_type) {
804*59657816SJohn Baldwin 	case CTL_IO_SCSI:
805*59657816SJohn Baldwin 		io->scsiio.kern_data_ptr = kern_data_ptr;
806*59657816SJohn Baldwin 		break;
807*59657816SJohn Baldwin 	case CTL_IO_NVME:
808*59657816SJohn Baldwin 	case CTL_IO_NVME_ADMIN:
809*59657816SJohn Baldwin 		io->nvmeio.kern_data_ptr = kern_data_ptr;
810*59657816SJohn Baldwin 		break;
811*59657816SJohn Baldwin 	default:
812*59657816SJohn Baldwin 		__assert_unreachable();
813*59657816SJohn Baldwin 	}
814*59657816SJohn Baldwin }
815*59657816SJohn Baldwin 
816*59657816SJohn Baldwin static __inline void
ctl_set_kern_data_len(union ctl_io * io,uint32_t kern_data_len)817*59657816SJohn Baldwin ctl_set_kern_data_len(union ctl_io *io, uint32_t kern_data_len)
818*59657816SJohn Baldwin {
819*59657816SJohn Baldwin 	switch (io->io_hdr.io_type) {
820*59657816SJohn Baldwin 	case CTL_IO_SCSI:
821*59657816SJohn Baldwin 		io->scsiio.kern_data_len = kern_data_len;
822*59657816SJohn Baldwin 		break;
823*59657816SJohn Baldwin 	case CTL_IO_NVME:
824*59657816SJohn Baldwin 	case CTL_IO_NVME_ADMIN:
825*59657816SJohn Baldwin 		io->nvmeio.kern_data_len = kern_data_len;
826*59657816SJohn Baldwin 		break;
827*59657816SJohn Baldwin 	default:
828*59657816SJohn Baldwin 		__assert_unreachable();
829*59657816SJohn Baldwin 	}
830*59657816SJohn Baldwin }
831*59657816SJohn Baldwin 
832*59657816SJohn Baldwin static __inline void
ctl_set_kern_total_len(union ctl_io * io,uint32_t kern_total_len)833*59657816SJohn Baldwin ctl_set_kern_total_len(union ctl_io *io, uint32_t kern_total_len)
834*59657816SJohn Baldwin {
835*59657816SJohn Baldwin 	switch (io->io_hdr.io_type) {
836*59657816SJohn Baldwin 	case CTL_IO_SCSI:
837*59657816SJohn Baldwin 		io->scsiio.kern_total_len = kern_total_len;
838*59657816SJohn Baldwin 		break;
839*59657816SJohn Baldwin 	case CTL_IO_NVME:
840*59657816SJohn Baldwin 	case CTL_IO_NVME_ADMIN:
841*59657816SJohn Baldwin 		io->nvmeio.kern_total_len = kern_total_len;
842*59657816SJohn Baldwin 		break;
843*59657816SJohn Baldwin 	default:
844*59657816SJohn Baldwin 		__assert_unreachable();
845*59657816SJohn Baldwin 	}
846*59657816SJohn Baldwin }
847*59657816SJohn Baldwin 
848*59657816SJohn Baldwin static __inline void
ctl_set_kern_data_resid(union ctl_io * io,uint32_t kern_data_resid)849*59657816SJohn Baldwin ctl_set_kern_data_resid(union ctl_io *io, uint32_t kern_data_resid)
850*59657816SJohn Baldwin {
851*59657816SJohn Baldwin 	switch (io->io_hdr.io_type) {
852*59657816SJohn Baldwin 	case CTL_IO_SCSI:
853*59657816SJohn Baldwin 		io->scsiio.kern_data_resid = kern_data_resid;
854*59657816SJohn Baldwin 		break;
855*59657816SJohn Baldwin 	case CTL_IO_NVME:
856*59657816SJohn Baldwin 	case CTL_IO_NVME_ADMIN:
857*59657816SJohn Baldwin 		io->nvmeio.kern_data_resid = kern_data_resid;
858*59657816SJohn Baldwin 		break;
859*59657816SJohn Baldwin 	default:
860*59657816SJohn Baldwin 		__assert_unreachable();
861*59657816SJohn Baldwin 	}
862*59657816SJohn Baldwin }
863*59657816SJohn Baldwin 
864*59657816SJohn Baldwin static __inline void
ctl_set_kern_rel_offset(union ctl_io * io,uint32_t kern_rel_offset)865*59657816SJohn Baldwin ctl_set_kern_rel_offset(union ctl_io *io, uint32_t kern_rel_offset)
866*59657816SJohn Baldwin {
867*59657816SJohn Baldwin 	switch (io->io_hdr.io_type) {
868*59657816SJohn Baldwin 	case CTL_IO_SCSI:
869*59657816SJohn Baldwin 		io->scsiio.kern_rel_offset = kern_rel_offset;
870*59657816SJohn Baldwin 		break;
871*59657816SJohn Baldwin 	case CTL_IO_NVME:
872*59657816SJohn Baldwin 	case CTL_IO_NVME_ADMIN:
873*59657816SJohn Baldwin 		io->nvmeio.kern_rel_offset = kern_rel_offset;
874*59657816SJohn Baldwin 		break;
875*59657816SJohn Baldwin 	default:
876*59657816SJohn Baldwin 		__assert_unreachable();
877*59657816SJohn Baldwin 	}
878*59657816SJohn Baldwin }
879*59657816SJohn Baldwin 
880*59657816SJohn Baldwin static __inline void
ctl_set_be_move_done(union ctl_io * io,ctl_be_move_done_t be_move_done)881*59657816SJohn Baldwin ctl_set_be_move_done(union ctl_io *io, ctl_be_move_done_t be_move_done)
882*59657816SJohn Baldwin {
883*59657816SJohn Baldwin 	switch (io->io_hdr.io_type) {
884*59657816SJohn Baldwin 	case CTL_IO_SCSI:
885*59657816SJohn Baldwin 		io->scsiio.be_move_done = be_move_done;
886*59657816SJohn Baldwin 		break;
887*59657816SJohn Baldwin 	case CTL_IO_NVME:
888*59657816SJohn Baldwin 	case CTL_IO_NVME_ADMIN:
889*59657816SJohn Baldwin 		io->nvmeio.be_move_done = be_move_done;
890*59657816SJohn Baldwin 		break;
891*59657816SJohn Baldwin 	default:
892*59657816SJohn Baldwin 		__assert_unreachable();
893*59657816SJohn Baldwin 	}
894*59657816SJohn Baldwin }
895*59657816SJohn Baldwin 
896*59657816SJohn Baldwin static __inline void
ctl_set_io_cont(union ctl_io * io,ctl_io_cont io_cont)897*59657816SJohn Baldwin ctl_set_io_cont(union ctl_io *io, ctl_io_cont io_cont)
898*59657816SJohn Baldwin {
899*59657816SJohn Baldwin 	switch (io->io_hdr.io_type) {
900*59657816SJohn Baldwin 	case CTL_IO_SCSI:
901*59657816SJohn Baldwin 		io->scsiio.io_cont = io_cont;
902*59657816SJohn Baldwin 		break;
903*59657816SJohn Baldwin 	case CTL_IO_NVME:
904*59657816SJohn Baldwin 	case CTL_IO_NVME_ADMIN:
905*59657816SJohn Baldwin 		io->nvmeio.io_cont = io_cont;
906*59657816SJohn Baldwin 		break;
907*59657816SJohn Baldwin 	default:
908*59657816SJohn Baldwin 		__assert_unreachable();
909*59657816SJohn Baldwin 	}
910*59657816SJohn Baldwin }
911*59657816SJohn Baldwin 
912*59657816SJohn Baldwin static __inline void
ctl_set_kern_data_ref(union ctl_io * io,ctl_ref kern_data_ref)913*59657816SJohn Baldwin ctl_set_kern_data_ref(union ctl_io *io, ctl_ref kern_data_ref)
914*59657816SJohn Baldwin {
915*59657816SJohn Baldwin 	switch (io->io_hdr.io_type) {
916*59657816SJohn Baldwin 	case CTL_IO_SCSI:
917*59657816SJohn Baldwin 		io->scsiio.kern_data_ref = kern_data_ref;
918*59657816SJohn Baldwin 		break;
919*59657816SJohn Baldwin 	case CTL_IO_NVME:
920*59657816SJohn Baldwin 	case CTL_IO_NVME_ADMIN:
921*59657816SJohn Baldwin 		io->nvmeio.kern_data_ref = kern_data_ref;
922*59657816SJohn Baldwin 		break;
923*59657816SJohn Baldwin 	default:
924*59657816SJohn Baldwin 		__assert_unreachable();
925*59657816SJohn Baldwin 	}
926*59657816SJohn Baldwin }
927*59657816SJohn Baldwin 
928*59657816SJohn Baldwin static __inline void
ctl_set_kern_data_arg(union ctl_io * io,void * kern_data_arg)929*59657816SJohn Baldwin ctl_set_kern_data_arg(union ctl_io *io, void *kern_data_arg)
930*59657816SJohn Baldwin {
931*59657816SJohn Baldwin 	switch (io->io_hdr.io_type) {
932*59657816SJohn Baldwin 	case CTL_IO_SCSI:
933*59657816SJohn Baldwin 		io->scsiio.kern_data_arg = kern_data_arg;
934*59657816SJohn Baldwin 		break;
935*59657816SJohn Baldwin 	case CTL_IO_NVME:
936*59657816SJohn Baldwin 	case CTL_IO_NVME_ADMIN:
937*59657816SJohn Baldwin 		io->nvmeio.kern_data_arg = kern_data_arg;
938*59657816SJohn Baldwin 		break;
939*59657816SJohn Baldwin 	default:
940*59657816SJohn Baldwin 		__assert_unreachable();
941*59657816SJohn Baldwin 	}
942*59657816SJohn Baldwin }
943*59657816SJohn Baldwin 
944130f4520SKenneth D. Merry union ctl_io *ctl_alloc_io(void *pool_ref);
9451251a76bSAlexander Motin union ctl_io *ctl_alloc_io_nowait(void *pool_ref);
946130f4520SKenneth D. Merry void ctl_free_io(union ctl_io *io);
947130f4520SKenneth D. Merry void ctl_zero_io(union ctl_io *io);
948130f4520SKenneth D. Merry 
949130f4520SKenneth D. Merry #endif /* _KERNEL */
950130f4520SKenneth D. Merry 
951130f4520SKenneth D. Merry #endif	/* _CTL_IO_H_ */
952130f4520SKenneth D. Merry 
953130f4520SKenneth D. Merry /*
954130f4520SKenneth D. Merry  * vim: ts=8
955130f4520SKenneth D. Merry  */
956