summaryrefslogtreecommitdiffstats
path: root/freebsd/sys/cam/cam_ccb.h
diff options
context:
space:
mode:
Diffstat (limited to 'freebsd/sys/cam/cam_ccb.h')
-rw-r--r--freebsd/sys/cam/cam_ccb.h194
1 files changed, 153 insertions, 41 deletions
diff --git a/freebsd/sys/cam/cam_ccb.h b/freebsd/sys/cam/cam_ccb.h
index 359064b6..e00b5bd3 100644
--- a/freebsd/sys/cam/cam_ccb.h
+++ b/freebsd/sys/cam/cam_ccb.h
@@ -41,7 +41,7 @@
#include <cam/cam_debug.h>
#include <cam/scsi/scsi_all.h>
#include <cam/ata/ata_all.h>
-
+#include <cam/nvme/nvme_all.h>
#ifdef __rtems__
#include <rtems/blkdev.h>
#endif /* __rtems__ */
@@ -67,7 +67,7 @@ typedef enum {
* Perform transport negotiation
* with this command.
*/
- CAM_DATA_ISPHYS = 0x00200000,/* Data type with physical addrs */
+ CAM_DATA_ISPHYS = 0x00000010,/* Data type with physical addrs */
CAM_DIS_AUTOSENSE = 0x00000020,/* Disable autosense feature */
CAM_DIR_BOTH = 0x00000000,/* Data direction (00:IN/OUT) */
CAM_DIR_IN = 0x00000040,/* Data direction (01:DATA IN) */
@@ -75,10 +75,10 @@ typedef enum {
CAM_DIR_NONE = 0x000000C0,/* Data direction (11:no data) */
CAM_DIR_MASK = 0x000000C0,/* Data direction Mask */
CAM_DATA_VADDR = 0x00000000,/* Data type (000:Virtual) */
- CAM_DATA_PADDR = 0x00200000,/* Data type (001:Physical) */
- CAM_DATA_SG = 0x00000010,/* Data type (010:sglist) */
- CAM_DATA_SG_PADDR = 0x00200010,/* Data type (011:sglist phys) */
- CAM_DATA_BIO = 0x00040000,/* Data type (100:bio) */
+ CAM_DATA_PADDR = 0x00000010,/* Data type (001:Physical) */
+ CAM_DATA_SG = 0x00040000,/* Data type (010:sglist) */
+ CAM_DATA_SG_PADDR = 0x00040010,/* Data type (011:sglist phys) */
+ CAM_DATA_BIO = 0x00200000,/* Data type (100:bio) */
CAM_DATA_MASK = 0x00240010,/* Data type mask */
CAM_SOFT_RST_OP = 0x00000100,/* Use Soft reset alternative */
CAM_ENG_SYNC = 0x00000200,/* Flush resid bytes on complete */
@@ -95,11 +95,6 @@ typedef enum {
CAM_CDB_PHYS = 0x00400000,/* CDB poiner is physical */
CAM_ENG_SGLIST = 0x00800000,/* SG list is for the HBA engine */
-/* Compatibility for FreeBSD 9.x*/
- CAM_SCATTER_VALID = 0x00000010,/* These exist for src compat for*/
- CAM_SG_LIST_PHYS = 0x00200010,/* old drivers. Hardly anything */
- CAM_DATA_PHYS = 0x00200000,/* uses them. */
-
/* Phase cognizant mode flags */
CAM_DIS_AUTOSRP = 0x01000000,/* Disable autosave/restore ptrs */
CAM_DIS_AUTODISC = 0x02000000,/* Disable auto disconnect */
@@ -113,9 +108,17 @@ typedef enum {
CAM_SEND_SENSE = 0x08000000,/* Send sense data with status */
CAM_TERM_IO = 0x10000000,/* Terminate I/O Message sup. */
CAM_DISCONNECT = 0x20000000,/* Disconnects are mandatory */
- CAM_SEND_STATUS = 0x40000000 /* Send status after data phase */
+ CAM_SEND_STATUS = 0x40000000,/* Send status after data phase */
+
+ CAM_UNLOCKED = 0x80000000 /* Call callback without lock. */
} ccb_flags;
+typedef enum {
+ CAM_USER_DATA_ADDR = 0x00000002,/* Userspace data pointers */
+ CAM_SG_FORMAT_IOVEC = 0x00000004,/* iovec instead of busdma S/G*/
+ CAM_UNMAPPED_BUF = 0x00000008 /* use unmapped I/O */
+} ccb_xflags;
+
/* XPT Opcodes for xpt_action */
typedef enum {
/* Function code flags are bits greater than 0xff */
@@ -156,6 +159,9 @@ typedef enum {
/* Device statistics (error counts, etc.) */
XPT_DEV_ADVINFO = 0x0e,
/* Get/Set Device advanced information */
+ XPT_ASYNC = 0x0f | XPT_FC_QUEUED | XPT_FC_USER_CCB
+ | XPT_FC_XPT_ONLY,
+ /* Asynchronous event */
/* SCSI Control Functions: 0x10->0x1F */
XPT_ABORT = 0x10,
/* Abort the specified CCB */
@@ -187,19 +193,27 @@ typedef enum {
XPT_ATA_IO = 0x18 | XPT_FC_DEV_QUEUED,
/* Execute the requested ATA I/O operation */
- XPT_GET_SIM_KNOB = 0x18,
- /*
- * Get SIM specific knob values.
- */
+ XPT_GET_SIM_KNOB_OLD = 0x18, /* Compat only */
XPT_SET_SIM_KNOB = 0x19,
/*
* Set SIM specific knob values.
*/
+ XPT_GET_SIM_KNOB = 0x1a,
+ /*
+ * Get SIM specific knob values.
+ */
+
XPT_SMP_IO = 0x1b | XPT_FC_DEV_QUEUED,
/* Serial Management Protocol */
+ XPT_NVME_IO = 0x1c | XPT_FC_DEV_QUEUED,
+ /* Execiute the requestred NVMe I/O operation */
+
+ XPT_MMCSD_IO = 0x1d | XPT_FC_DEV_QUEUED,
+ /* Placeholder for MMC / SD / SDIO I/O stuff */
+
XPT_SCAN_TGT = 0x1E | XPT_FC_QUEUED | XPT_FC_USER_CCB
| XPT_FC_XPT_ONLY,
/* Scan Target */
@@ -227,6 +241,8 @@ typedef enum {
/* Notify Host Target driver of event */
XPT_NOTIFY_ACKNOWLEDGE = 0x37 | XPT_FC_QUEUED | XPT_FC_USER_CCB,
/* Acknowledgement of event */
+ XPT_REPROBE_LUN = 0x38 | XPT_FC_QUEUED | XPT_FC_USER_CCB,
+ /* Query device capacity and notify GEOM */
/* Vendor Unique codes: 0x80->0x8F */
XPT_VUNIQUE = 0x80
@@ -253,6 +269,7 @@ typedef enum {
PROTO_ATAPI, /* AT Attachment Packetized Interface */
PROTO_SATAPM, /* SATA Port Multiplier */
PROTO_SEMB, /* SATA Enclosure Management Bridge */
+ PROTO_NVME, /* NVME */
} cam_proto;
typedef enum {
@@ -267,12 +284,15 @@ typedef enum {
XPORT_SAS, /* Serial Attached SCSI */
XPORT_SATA, /* Serial AT Attachment */
XPORT_ISCSI, /* iSCSI */
+ XPORT_SRP, /* SCSI RDMA Protocol */
+ XPORT_NVME, /* NVMe over PCIe */
} cam_xport;
+#define XPORT_IS_NVME(t) ((t) == XPORT_NVME)
#define XPORT_IS_ATA(t) ((t) == XPORT_ATA || (t) == XPORT_SATA)
#define XPORT_IS_SCSI(t) ((t) != XPORT_UNKNOWN && \
(t) != XPORT_UNSPECIFIED && \
- !XPORT_IS_ATA(t))
+ !XPORT_IS_ATA(t) && !XPORT_IS_NVME(t))
#define XPORT_DEVSTAT_TYPE(t) (XPORT_IS_ATA(t) ? DEVSTAT_TYPE_IF_IDE : \
XPORT_IS_SCSI(t) ? DEVSTAT_TYPE_IF_SCSI : \
DEVSTAT_TYPE_IF_OTHER)
@@ -305,6 +325,12 @@ typedef union {
u_int8_t bytes[CCB_SIM_PRIV_SIZE * sizeof(ccb_priv_entry)];
} ccb_spriv_area;
+typedef struct {
+ struct timeval *etime;
+ uintptr_t sim_data;
+ uintptr_t periph_data;
+} ccb_qos_area;
+
struct ccb_hdr {
#ifndef __rtems__
cam_pinfo pinfo; /* Info for priority scheduling */
@@ -326,18 +352,15 @@ struct ccb_hdr {
target_id_t target_id; /* Target device ID */
lun_id_t target_lun; /* Target LUN number */
u_int32_t flags; /* ccb_flags */
+ u_int32_t xflags; /* Extended flags */
#ifndef __rtems__
ccb_ppriv_area periph_priv;
ccb_spriv_area sim_priv;
+ ccb_qos_area qos;
#endif /* __rtems__ */
- u_int32_t timeout; /* Timeout value */
-
+ u_int32_t timeout; /* Hard timeout value in mseconds */
#ifndef __rtems__
- /*
- * Deprecated, only for use by non-MPSAFE SIMs. All others must
- * allocate and initialize their own callout storage.
- */
- struct callout_handle timeout_ch;
+ struct timeval softtimeout; /* Soft timeout value in sec + usec */
#endif /* __rtems__ */
};
@@ -350,6 +373,8 @@ struct ccb_getdev {
u_int8_t serial_num[252];
u_int8_t inq_flags;
u_int8_t serial_num_len;
+ const struct nvme_controller_data *nvme_cdata;
+ const struct nvme_namespace_data *nvme_data;
};
/* Device Statistics CCB */
@@ -357,8 +382,8 @@ struct ccb_getdevstats {
struct ccb_hdr ccb_h;
int dev_openings; /* Space left for more work on device*/
int dev_active; /* Transactions running on the device */
- int devq_openings; /* Space left for more queued work */
- int devq_queued; /* Transactions queued to be sent */
+ int allocated; /* CCBs allocated for the device */
+ int queued; /* CCBs queued to be sent to the device */
int held; /*
* CCBs held by peripheral drivers
* for this device
@@ -560,7 +585,7 @@ struct ccb_dev_match {
/*
* Definitions for the path inquiry CCB fields.
*/
-#define CAM_VERSION 0x17 /* Hex value for current version */
+#define CAM_VERSION 0x19 /* Hex value for current version */
typedef enum {
PI_MDP_ABLE = 0x80, /* Supports MDP message */
@@ -583,6 +608,8 @@ typedef enum {
} pi_tmflag;
typedef enum {
+ PIM_ATA_EXT = 0x200,/* ATA requests can understand ata_ext requests */
+ PIM_EXTLUNS = 0x100,/* 64bit extended LUNs supported */
PIM_SCANHILO = 0x80, /* Bus scans from high ID to low ID */
PIM_NOREMOVE = 0x40, /* Removeable devices not included in scan */
PIM_NOINITIATOR = 0x20, /* Initiator role not supported. */
@@ -608,14 +635,19 @@ struct ccb_pathinq_settings_fc {
struct ccb_pathinq_settings_sas {
u_int32_t bitrate; /* Mbps */
};
+
+struct ccb_pathinq_settings_nvme {
+ uint16_t nsid; /* Namespace ID for this path */
+};
+
#define PATHINQ_SETTINGS_SIZE 128
struct ccb_pathinq {
struct ccb_hdr ccb_h;
u_int8_t version_num; /* Version number for the SIM/HBA */
u_int8_t hba_inquiry; /* Mimic of INQ byte 7 for the HBA */
- u_int8_t target_sprt; /* Flags for target mode support */
- u_int8_t hba_misc; /* Misc HBA features */
+ u_int16_t target_sprt; /* Flags for target mode support */
+ u_int32_t hba_misc; /* Misc HBA features */
u_int16_t hba_eng_cnt; /* HBA engine count */
/* Vendor Unique capabilities */
u_int8_t vuhba_flags[VUHBALEN];
@@ -638,6 +670,7 @@ struct ccb_pathinq {
struct ccb_pathinq_settings_spi spi;
struct ccb_pathinq_settings_fc fc;
struct ccb_pathinq_settings_sas sas;
+ struct ccb_pathinq_settings_nvme nvme;
char ccb_pathinq_settings_opaque[PATHINQ_SETTINGS_SIZE];
} xport_specific;
u_int maxio; /* Max supported I/O size, in bytes. */
@@ -732,6 +765,13 @@ struct ccb_scsiio {
#endif /* __rtems__ */
};
+static __inline uint8_t *
+scsiio_cdb_ptr(struct ccb_scsiio *ccb)
+{
+ return ((ccb->ccb_h.flags & CAM_CDB_POINTER) ?
+ ccb->cdb_io.cdb_ptr : ccb->cdb_io.cdb_bytes);
+}
+
/*
* ATA I/O Request CCB used for the XPT_ATA_IO function code.
*/
@@ -743,15 +783,10 @@ struct ccb_ataio {
u_int8_t *data_ptr; /* Ptr to the data buf/SG list */
u_int32_t dxfer_len; /* Data transfer length */
u_int32_t resid; /* Transfer residual length: 2's comp */
- u_int8_t tag_action; /* What to do for tag queueing */
- /*
- * The tag action should be either the define below (to send a
- * non-tagged transaction) or one of the defined scsi tag messages
- * from scsi_message.h.
- */
-#define CAM_TAG_ACTION_NONE 0x00
- u_int tag_id; /* tag id from initator (target mode) */
- u_int init_id; /* initiator id of who selected */
+ u_int8_t ata_flags; /* Flags for the rest of the buffer */
+#define ATA_FLAG_AUX 0x1
+ uint32_t aux;
+ uint32_t unused;
};
struct ccb_accept_tio {
@@ -779,6 +814,19 @@ struct ccb_relsim {
};
/*
+ * NVMe I/O Request CCB used for the XPT_NVME_IO function code.
+ */
+struct ccb_nvmeio {
+ struct ccb_hdr ccb_h;
+ union ccb *next_ccb; /* Ptr for next CCB for action */
+ struct nvme_command cmd; /* NVME command, per NVME standard */
+ struct nvme_completion cpl; /* NVME completion, per NVME standard */
+ uint8_t *data_ptr; /* Ptr to the data buf/SG list */
+ uint32_t dxfer_len; /* Data transfer length */
+ uint32_t resid; /* Transfer residual length: 2's comp unused ?*/
+};
+
+/*
* Definitions for the asynchronous callback CCB fields.
*/
typedef enum {
@@ -959,6 +1007,18 @@ struct ccb_trans_settings_sata {
#define CTS_SATA_CAPS_D_APST 0x00020000
};
+struct ccb_trans_settings_nvme
+{
+ u_int valid; /* Which fields to honor */
+#define CTS_NVME_VALID_SPEC 0x01
+#define CTS_NVME_VALID_CAPS 0x02
+ u_int spec_major; /* Major version of spec supported */
+ u_int spec_minor; /* Minor verison of spec supported */
+ u_int spec_tiny; /* Tiny version of spec supported */
+ u_int max_xfer; /* Max transfer size (0 -> unlimited */
+ u_int caps;
+};
+
/* Get/Set transfer rate/width/disconnection/tag queueing settings */
struct ccb_trans_settings {
struct ccb_hdr ccb_h;
@@ -971,6 +1031,7 @@ struct ccb_trans_settings {
u_int valid; /* Which fields to honor */
struct ccb_trans_settings_ata ata;
struct ccb_trans_settings_scsi scsi;
+ struct ccb_trans_settings_nvme nvme;
} proto_specific;
union {
u_int valid; /* Which fields to honor */
@@ -979,6 +1040,7 @@ struct ccb_trans_settings {
struct ccb_trans_settings_sas sas;
struct ccb_trans_settings_pata ata;
struct ccb_trans_settings_sata sata;
+ struct ccb_trans_settings_nvme nvme;
} xport_specific;
};
@@ -1093,7 +1155,17 @@ struct ccb_notify_acknowledge {
u_int tag_id; /* Tag for immediate notify */
u_int seq_id; /* Tar for target of notify */
u_int initiator_id; /* Initiator Identifier */
- u_int arg; /* Function specific */
+ u_int arg; /* Response information */
+ /*
+ * Lower byte of arg is one of RESPONSE CODE values defined below
+ * (subset of response codes from SPL-4 and FCP-4 specifications),
+ * upper 3 bytes is code-specific ADDITIONAL RESPONSE INFORMATION.
+ */
+#define CAM_RSP_TMF_COMPLETE 0x00
+#define CAM_RSP_TMF_REJECTED 0x04
+#define CAM_RSP_TMF_FAILED 0x05
+#define CAM_RSP_TMF_SUCCEEDED 0x08
+#define CAM_RSP_TMF_INCORRECT_LUN 0x09
};
/* HBA engine structures. */
@@ -1159,6 +1231,7 @@ struct ccb_eng_exec { /* This structure must match SCSIIO size */
struct ccb_dev_advinfo {
struct ccb_hdr ccb_h;
uint32_t flags;
+#define CDAI_FLAG_NONE 0x0 /* No flags set */
#define CDAI_FLAG_STORE 0x1 /* If set, action becomes store */
uint32_t buftype; /* IN: Type of data being requested */
/* NB: buftype is interpreted on a per-transport basis */
@@ -1166,6 +1239,7 @@ struct ccb_dev_advinfo {
#define CDAI_TYPE_SERIAL_NUM 2
#define CDAI_TYPE_PHYS_PATH 3
#define CDAI_TYPE_RCAPLONG 4
+#define CDAI_TYPE_EXT_INQ 5
off_t bufsiz; /* IN: Size of external buffer */
#define CAM_SCSI_DEVID_MAXLEN 65536 /* length in buffer is an uint16_t */
off_t provsiz; /* OUT: Size required/used */
@@ -1173,6 +1247,16 @@ struct ccb_dev_advinfo {
};
/*
+ * CCB for sending async events
+ */
+struct ccb_async {
+ struct ccb_hdr ccb_h;
+ uint32_t async_code;
+ off_t async_arg_size;
+ void *async_arg_ptr;
+};
+
+/*
* Union of all CCB types for kernel space allocation. This union should
* never be used for manipulating CCBs - its only use is for the allocation
* and deallocation of raw CCB space and is the return type of xpt_ccb_alloc
@@ -1211,8 +1295,14 @@ union ccb {
struct ccb_debug cdbg;
struct ccb_ataio ataio;
struct ccb_dev_advinfo cdai;
+ struct ccb_async casync;
+ struct ccb_nvmeio nvmeio;
};
+#define CCB_CLEAR_ALL_EXCEPT_HDR(ccbp) \
+ bzero((char *)(ccbp) + sizeof((ccbp)->ccb_h), \
+ sizeof(*(ccbp)) - sizeof((ccbp)->ccb_h))
+
__BEGIN_DECLS
static __inline void
cam_fill_csio(struct ccb_scsiio *csio, u_int32_t retries,
@@ -1223,6 +1313,12 @@ cam_fill_csio(struct ccb_scsiio *csio, u_int32_t retries,
u_int32_t timeout);
static __inline void
+cam_fill_nvmeio(struct ccb_nvmeio *nvmeio, u_int32_t retries,
+ void (*cbfcnp)(struct cam_periph *, union ccb *),
+ u_int32_t flags, u_int8_t *data_ptr, u_int32_t dxfer_len,
+ u_int32_t timeout);
+
+static __inline void
cam_fill_ctio(struct ccb_scsiio *csio, u_int32_t retries,
void (*cbfcnp)(struct cam_periph *, union ccb *),
u_int32_t flags, u_int tag_action, u_int tag_id,
@@ -1253,6 +1349,7 @@ cam_fill_csio(struct ccb_scsiio *csio, u_int32_t retries,
{
csio->ccb_h.func_code = XPT_SCSI_IO;
csio->ccb_h.flags = flags;
+ csio->ccb_h.xflags = 0;
csio->ccb_h.retry_count = retries;
csio->ccb_h.cbfcnp = cbfcnp;
csio->ccb_h.timeout = timeout;
@@ -1272,6 +1369,7 @@ cam_fill_ctio(struct ccb_scsiio *csio, u_int32_t retries,
{
csio->ccb_h.func_code = XPT_CONT_TARGET_IO;
csio->ccb_h.flags = flags;
+ csio->ccb_h.xflags = 0;
csio->ccb_h.retry_count = retries;
csio->ccb_h.cbfcnp = cbfcnp;
csio->ccb_h.timeout = timeout;
@@ -1286,7 +1384,7 @@ cam_fill_ctio(struct ccb_scsiio *csio, u_int32_t retries,
static __inline void
cam_fill_ataio(struct ccb_ataio *ataio, u_int32_t retries,
void (*cbfcnp)(struct cam_periph *, union ccb *),
- u_int32_t flags, u_int tag_action,
+ u_int32_t flags, u_int tag_action __unused,
u_int8_t *data_ptr, u_int32_t dxfer_len,
u_int32_t timeout)
{
@@ -1297,7 +1395,7 @@ cam_fill_ataio(struct ccb_ataio *ataio, u_int32_t retries,
ataio->ccb_h.timeout = timeout;
ataio->data_ptr = data_ptr;
ataio->dxfer_len = dxfer_len;
- ataio->tag_action = tag_action;
+ ataio->ata_flags = 0;
}
static __inline void
@@ -1341,6 +1439,20 @@ cam_ccb_status(union ccb *ccb)
void cam_calc_geometry(struct ccb_calc_geometry *ccg, int extended);
+static __inline void
+cam_fill_nvmeio(struct ccb_nvmeio *nvmeio, u_int32_t retries,
+ void (*cbfcnp)(struct cam_periph *, union ccb *),
+ u_int32_t flags, u_int8_t *data_ptr, u_int32_t dxfer_len,
+ u_int32_t timeout)
+{
+ nvmeio->ccb_h.func_code = XPT_NVME_IO;
+ nvmeio->ccb_h.flags = flags;
+ nvmeio->ccb_h.retry_count = retries;
+ nvmeio->ccb_h.cbfcnp = cbfcnp;
+ nvmeio->ccb_h.timeout = timeout;
+ nvmeio->data_ptr = data_ptr;
+ nvmeio->dxfer_len = dxfer_len;
+}
__END_DECLS
#endif /* _CAM_CAM_CCB_H */