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 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 * 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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