Update to FreeBSD head 2016-08-23

Git mirror commit 9fe7c416e6abb28b1398fd3e5687099846800cfd.
This commit is contained in:
Sebastian Huber
2016-10-07 15:10:20 +02:00
parent 8c0eebac7d
commit c40e45b75e
1040 changed files with 156866 additions and 67039 deletions

View File

@@ -103,10 +103,11 @@ int ata_version(int ver);
char * ata_op_string(struct ata_cmd *cmd);
char * ata_cmd_string(struct ata_cmd *cmd, char *cmd_string, size_t len);
void ata_cmd_sbuf(struct ata_cmd *cmd, struct sbuf *sb);
char * ata_res_string(struct ata_res *res, char *res_string, size_t len);
int ata_command_sbuf(struct ccb_ataio *ataio, struct sbuf *sb);
int ata_status_sbuf(struct ccb_ataio *ataio, struct sbuf *sb);
int ata_res_sbuf(struct ccb_ataio *ataio, struct sbuf *sb);
int ata_res_sbuf(struct ata_res *res, struct sbuf *sb);
void ata_print_ident(struct ata_params *ident_data);
void ata_print_ident_short(struct ata_params *ident_data);
@@ -124,6 +125,11 @@ void ata_ncq_cmd(struct ccb_ataio *ataio, uint8_t cmd,
void ata_reset_cmd(struct ccb_ataio *ataio);
void ata_pm_read_cmd(struct ccb_ataio *ataio, int reg, int port);
void ata_pm_write_cmd(struct ccb_ataio *ataio, int reg, int port, uint32_t val);
void ata_read_log(struct ccb_ataio *ataio, uint32_t retries,
void (*cbfcnp)(struct cam_periph *, union ccb *),
uint32_t log_address, uint32_t page_number,
uint16_t block_count, uint32_t protocol,
uint8_t *data_ptr, uint32_t dxfer_len, uint32_t timeout);
void ata_bswap(int8_t *buf, int len);
void ata_btrim(int8_t *buf, int len);
@@ -166,4 +172,16 @@ void semb_write_buffer(struct ccb_ataio *ataio,
uint8_t tag_action, uint8_t *data_ptr, uint16_t param_list_length,
uint32_t timeout);
void ata_zac_mgmt_out(struct ccb_ataio *ataio, uint32_t retries,
void (*cbfcnp)(struct cam_periph *, union ccb *),
int use_ncq __unused, uint8_t zm_action, uint64_t zone_id,
uint8_t zone_flags, uint16_t sector_count, uint8_t *data_ptr,
uint32_t dxfer_len, uint32_t timeout);
void ata_zac_mgmt_in(struct ccb_ataio *ataio, uint32_t retries,
void (*cbfcnp)(struct cam_periph *, union ccb *),
int use_ncq __unused, uint8_t zm_action, uint64_t zone_id,
uint8_t zone_flags, uint8_t *data_ptr, uint32_t dxfer_len,
uint32_t timeout);
#endif

View File

@@ -107,9 +107,6 @@ const struct cam_status_entry cam_status_table[] = {
{ CAM_SCSI_BUSY, "SCSI Bus Busy" },
};
const int num_cam_status_entries =
sizeof(cam_status_table)/sizeof(*cam_status_table);
#ifdef _KERNEL
SYSCTL_NODE(_kern, OID_AUTO, cam, CTLFLAG_RD, 0, "CAM Subsystem");
@@ -118,7 +115,6 @@ SYSCTL_NODE(_kern, OID_AUTO, cam, CTLFLAG_RD, 0, "CAM Subsystem");
#endif
int cam_sort_io_queues = CAM_DEFAULT_SORT_IO_QUEUES;
TUNABLE_INT("kern.cam.sort_io_queues", &cam_sort_io_queues);
SYSCTL_INT(_kern_cam, OID_AUTO, sort_io_queues, CTLFLAG_RWTUN,
&cam_sort_io_queues, 0, "Sort IO queues to try and optimise disk access patterns");
#endif
@@ -160,35 +156,125 @@ cam_strvis(u_int8_t *dst, const u_int8_t *src, int srclen, int dstlen)
*dst = '\0';
}
void
cam_strvis_sbuf(struct sbuf *sb, const u_int8_t *src, int srclen,
uint32_t flags)
{
/* Trim leading/trailing spaces, nulls. */
while (srclen > 0 && src[0] == ' ')
src++, srclen--;
while (srclen > 0
&& (src[srclen-1] == ' ' || src[srclen-1] == '\0'))
srclen--;
while (srclen > 0) {
if (*src < 0x20 || *src >= 0x80) {
/* SCSI-II Specifies that these should never occur. */
/* non-printable character */
switch (flags & CAM_STRVIS_FLAG_NONASCII_MASK) {
case CAM_STRVIS_FLAG_NONASCII_ESC:
sbuf_printf(sb, "\\%c%c%c",
((*src & 0300) >> 6) + '0',
((*src & 0070) >> 3) + '0',
((*src & 0007) >> 0) + '0');
break;
case CAM_STRVIS_FLAG_NONASCII_RAW:
/*
* If we run into a NUL, just transform it
* into a space.
*/
if (*src != 0x00)
sbuf_putc(sb, *src);
else
sbuf_putc(sb, ' ');
break;
case CAM_STRVIS_FLAG_NONASCII_SPC:
sbuf_putc(sb, ' ');
break;
case CAM_STRVIS_FLAG_NONASCII_TRIM:
default:
break;
}
} else {
/* normal character */
sbuf_putc(sb, *src);
}
src++;
srclen--;
}
}
/*
* Compare string with pattern, returning 0 on match.
* Short pattern matches trailing blanks in name,
* wildcard '*' in pattern matches rest of name,
* wildcard '?' matches a single non-space character.
* Shell globbing rules apply: * matches 0 or more characters,
* ? matchces one character, [...] denotes a set to match one char,
* [^...] denotes a complimented set to match one character.
* Spaces in str used to match anything in the pattern string
* but was removed because it's a bug. No current patterns require
* it, as far as I know, but it's impossible to know what drives
* returned.
*
* Each '*' generates recursion, so keep the number of * in check.
*/
int
cam_strmatch(const u_int8_t *str, const u_int8_t *pattern, int str_len)
{
while (*pattern != '\0'&& str_len > 0) {
while (*pattern != '\0' && str_len > 0) {
if (*pattern == '*') {
return (0);
}
if ((*pattern != *str)
&& (*pattern != '?' || *str == ' ')) {
pattern++;
if (*pattern == '\0')
return (0);
do {
if (cam_strmatch(str, pattern, str_len) == 0)
return (0);
str++;
str_len--;
} while (str_len > 0);
return (1);
} else if (*pattern == '[') {
int negate_range, ok;
uint8_t pc, sc;
ok = 0;
sc = *str++;
str_len--;
if ((negate_range = (*pattern == '^')) != 0)
pattern++;
while (((pc = *pattern) != ']') && *pattern != '\0') {
pattern++;
if (*pattern == '-') {
if (pattern[1] == '\0') /* Bad pattern */
return (1);
if (sc >= pc && sc <= pattern[1])
ok = 1;
pattern += 2;
} else if (pc == sc)
ok = 1;
}
if (ok == negate_range)
return (1);
} else if (*pattern == '?') {
/* NB: || *str == ' ' of the old code is a bug and was removed */
/* if you add it back, keep this the last if before the naked else */
pattern++;
str++;
str_len--;
} else {
if (*str != *pattern)
return (1);
pattern++;
str++;
str_len--;
}
pattern++;
str++;
str_len--;
}
while (str_len > 0 && *str == ' ') {
str++;
str_len--;
}
if (str_len > 0 && *str == 0)
str_len = 0;
return (str_len);
}
@@ -209,7 +295,7 @@ cam_fetch_status_entry(cam_status status)
{
status &= CAM_STATUS_MASK;
return (bsearch(&status, &cam_status_table,
num_cam_status_entries,
nitems(cam_status_table),
sizeof(*cam_status_table),
camstatusentrycomp));
}
@@ -366,7 +452,8 @@ cam_error_string(struct cam_device *device, union ccb *ccb, char *str,
}
if (proto_flags & CAM_EAF_PRINT_RESULT) {
sbuf_cat(&sb, path_str);
ata_res_sbuf(&ccb->ataio, &sb);
sbuf_printf(&sb, "RES: ");
ata_res_sbuf(&ccb->ataio.res, &sb);
sbuf_printf(&sb, "\n");
}

View File

@@ -43,12 +43,18 @@
typedef u_int path_id_t;
typedef u_int target_id_t;
typedef u_int lun_id_t;
typedef u_int64_t lun_id_t;
#define CAM_XPT_PATH_ID ((path_id_t)~0)
#define CAM_BUS_WILDCARD ((path_id_t)~0)
#define CAM_TARGET_WILDCARD ((target_id_t)~0)
#define CAM_LUN_WILDCARD ((lun_id_t)~0)
#define CAM_LUN_WILDCARD (~(u_int)0)
#define CAM_EXTLUN_BYTE_SWIZZLE(lun) ( \
((((u_int64_t)lun) & 0xffff000000000000L) >> 48) | \
((((u_int64_t)lun) & 0x0000ffff00000000L) >> 16) | \
((((u_int64_t)lun) & 0x00000000ffff0000L) << 16) | \
((((u_int64_t)lun) & 0x000000000000ffffL) << 48))
/*
* Maximum length for a CAM CDB.
@@ -75,7 +81,7 @@ typedef enum {
CAM_RL_VALUES
} cam_rl;
/*
* The generation number is incremented everytime a new entry is entered into
* The generation number is incremented every time a new entry is entered into
* the queue giving round robin per priority level scheduling.
*/
typedef struct {
@@ -116,7 +122,7 @@ typedef enum {
enum {
SF_RETRY_UA = 0x01, /* Retry UNIT ATTENTION conditions. */
SF_NO_PRINT = 0x02, /* Never print error status. */
SF_QUIET_IR = 0x04, /* Be quiet about Illegal Request reponses */
SF_QUIET_IR = 0x04, /* Be quiet about Illegal Request responses */
SF_PRINT_ALWAYS = 0x08, /* Always print error status. */
SF_NO_RECOVERY = 0x10, /* Don't do active error recovery. */
SF_NO_RETRY = 0x20, /* Don't do any retries. */
@@ -125,69 +131,184 @@ enum {
/* CAM Status field values */
typedef enum {
CAM_REQ_INPROG, /* CCB request is in progress */
CAM_REQ_CMP, /* CCB request completed without error */
CAM_REQ_ABORTED, /* CCB request aborted by the host */
CAM_UA_ABORT, /* Unable to abort CCB request */
CAM_REQ_CMP_ERR, /* CCB request completed with an error */
CAM_BUSY, /* CAM subsystem is busy */
CAM_REQ_INVALID, /* CCB request was invalid */
CAM_PATH_INVALID, /* Supplied Path ID is invalid */
CAM_DEV_NOT_THERE, /* SCSI Device Not Installed/there */
CAM_UA_TERMIO, /* Unable to terminate I/O CCB request */
CAM_SEL_TIMEOUT, /* Target Selection Timeout */
CAM_CMD_TIMEOUT, /* Command timeout */
CAM_SCSI_STATUS_ERROR, /* SCSI error, look at error code in CCB */
CAM_MSG_REJECT_REC, /* Message Reject Received */
CAM_SCSI_BUS_RESET, /* SCSI Bus Reset Sent/Received */
CAM_UNCOR_PARITY, /* Uncorrectable parity error occurred */
CAM_AUTOSENSE_FAIL = 0x10,/* Autosense: request sense cmd fail */
CAM_NO_HBA, /* No HBA Detected error */
CAM_DATA_RUN_ERR, /* Data Overrun error */
CAM_UNEXP_BUSFREE, /* Unexpected Bus Free */
CAM_SEQUENCE_FAIL, /* Target Bus Phase Sequence Failure */
CAM_CCB_LEN_ERR, /* CCB length supplied is inadequate */
CAM_PROVIDE_FAIL, /* Unable to provide requested capability */
CAM_BDR_SENT, /* A SCSI BDR msg was sent to target */
CAM_REQ_TERMIO, /* CCB request terminated by the host */
CAM_UNREC_HBA_ERROR, /* Unrecoverable Host Bus Adapter Error */
CAM_REQ_TOO_BIG, /* The request was too large for this host */
CAM_REQUEUE_REQ, /*
* This request should be requeued to preserve
* transaction ordering. This typically occurs
* when the SIM recognizes an error that should
* freeze the queue and must place additional
* requests for the target at the sim level
* back into the XPT queue.
*/
CAM_ATA_STATUS_ERROR, /* ATA error, look at error code in CCB */
CAM_SCSI_IT_NEXUS_LOST, /* Initiator/Target Nexus lost. */
CAM_SMP_STATUS_ERROR, /* SMP error, look at error code in CCB */
CAM_IDE = 0x33, /* Initiator Detected Error */
CAM_RESRC_UNAVAIL, /* Resource Unavailable */
CAM_UNACKED_EVENT, /* Unacknowledged Event by Host */
CAM_MESSAGE_RECV, /* Message Received in Host Target Mode */
CAM_INVALID_CDB, /* Invalid CDB received in Host Target Mode */
CAM_LUN_INVALID, /* Lun supplied is invalid */
CAM_TID_INVALID, /* Target ID supplied is invalid */
CAM_FUNC_NOTAVAIL, /* The requested function is not available */
CAM_NO_NEXUS, /* Nexus is not established */
CAM_IID_INVALID, /* The initiator ID is invalid */
CAM_CDB_RECVD, /* The SCSI CDB has been received */
CAM_LUN_ALRDY_ENA, /* The LUN is already enabled for target mode */
CAM_SCSI_BUSY, /* SCSI Bus Busy */
/* CCB request is in progress */
CAM_REQ_INPROG = 0x00,
CAM_DEV_QFRZN = 0x40, /* The DEV queue is frozen w/this err */
/* CCB request completed without error */
CAM_REQ_CMP = 0x01,
/* Autosense data valid for target */
CAM_AUTOSNS_VALID = 0x80,
CAM_RELEASE_SIMQ = 0x100,/* SIM ready to take more commands */
CAM_SIM_QUEUED = 0x200,/* SIM has this command in it's queue */
/* CCB request aborted by the host */
CAM_REQ_ABORTED = 0x02,
CAM_STATUS_MASK = 0x3F, /* Mask bits for just the status # */
/* Unable to abort CCB request */
CAM_UA_ABORT = 0x03,
/* Target Specific Adjunct Status */
CAM_SENT_SENSE = 0x40000000 /* sent sense with status */
/* CCB request completed with an error */
CAM_REQ_CMP_ERR = 0x04,
/* CAM subsystem is busy */
CAM_BUSY = 0x05,
/* CCB request was invalid */
CAM_REQ_INVALID = 0x06,
/* Supplied Path ID is invalid */
CAM_PATH_INVALID = 0x07,
/* SCSI Device Not Installed/there */
CAM_DEV_NOT_THERE = 0x08,
/* Unable to terminate I/O CCB request */
CAM_UA_TERMIO = 0x09,
/* Target Selection Timeout */
CAM_SEL_TIMEOUT = 0x0a,
/* Command timeout */
CAM_CMD_TIMEOUT = 0x0b,
/* SCSI error, look at error code in CCB */
CAM_SCSI_STATUS_ERROR = 0x0c,
/* Message Reject Received */
CAM_MSG_REJECT_REC = 0x0d,
/* SCSI Bus Reset Sent/Received */
CAM_SCSI_BUS_RESET = 0x0e,
/* Uncorrectable parity error occurred */
CAM_UNCOR_PARITY = 0x0f,
/* Autosense: request sense cmd fail */
CAM_AUTOSENSE_FAIL = 0x10,
/* No HBA Detected error */
CAM_NO_HBA = 0x11,
/* Data Overrun error */
CAM_DATA_RUN_ERR = 0x12,
/* Unexpected Bus Free */
CAM_UNEXP_BUSFREE = 0x13,
/* Target Bus Phase Sequence Failure */
CAM_SEQUENCE_FAIL = 0x14,
/* CCB length supplied is inadequate */
CAM_CCB_LEN_ERR = 0x15,
/* Unable to provide requested capability*/
CAM_PROVIDE_FAIL = 0x16,
/* A SCSI BDR msg was sent to target */
CAM_BDR_SENT = 0x17,
/* CCB request terminated by the host */
CAM_REQ_TERMIO = 0x18,
/* Unrecoverable Host Bus Adapter Error */
CAM_UNREC_HBA_ERROR = 0x19,
/* Request was too large for this host */
CAM_REQ_TOO_BIG = 0x1a,
/*
* This request should be requeued to preserve
* transaction ordering. This typically occurs
* when the SIM recognizes an error that should
* freeze the queue and must place additional
* requests for the target at the sim level
* back into the XPT queue.
*/
CAM_REQUEUE_REQ = 0x1b,
/* ATA error, look at error code in CCB */
CAM_ATA_STATUS_ERROR = 0x1c,
/* Initiator/Target Nexus lost. */
CAM_SCSI_IT_NEXUS_LOST = 0x1d,
/* SMP error, look at error code in CCB */
CAM_SMP_STATUS_ERROR = 0x1e,
/*
* Command completed without error but exceeded the soft
* timeout threshold.
*/
CAM_REQ_SOFTTIMEOUT = 0x1f,
/*
* 0x20 - 0x32 are unassigned
*/
/* Initiator Detected Error */
CAM_IDE = 0x33,
/* Resource Unavailable */
CAM_RESRC_UNAVAIL = 0x34,
/* Unacknowledged Event by Host */
CAM_UNACKED_EVENT = 0x35,
/* Message Received in Host Target Mode */
CAM_MESSAGE_RECV = 0x36,
/* Invalid CDB received in Host Target Mode */
CAM_INVALID_CDB = 0x37,
/* Lun supplied is invalid */
CAM_LUN_INVALID = 0x38,
/* Target ID supplied is invalid */
CAM_TID_INVALID = 0x39,
/* The requested function is not available */
CAM_FUNC_NOTAVAIL = 0x3a,
/* Nexus is not established */
CAM_NO_NEXUS = 0x3b,
/* The initiator ID is invalid */
CAM_IID_INVALID = 0x3c,
/* The SCSI CDB has been received */
CAM_CDB_RECVD = 0x3d,
/* The LUN is already enabled for target mode */
CAM_LUN_ALRDY_ENA = 0x3e,
/* SCSI Bus Busy */
CAM_SCSI_BUSY = 0x3f,
/*
* Flags
*/
/* The DEV queue is frozen w/this err */
CAM_DEV_QFRZN = 0x40,
/* Autosense data valid for target */
CAM_AUTOSNS_VALID = 0x80,
/* SIM ready to take more commands */
CAM_RELEASE_SIMQ = 0x100,
/* SIM has this command in it's queue */
CAM_SIM_QUEUED = 0x200,
/* Quality of service data is valid */
CAM_QOS_VALID = 0x400,
/* Mask bits for just the status # */
CAM_STATUS_MASK = 0x3F,
/*
* Target Specific Adjunct Status
*/
/* sent sense with status */
CAM_SENT_SENSE = 0x40000000
} cam_status;
typedef enum {
@@ -225,6 +346,15 @@ typedef enum {
CAM_EAF_PRINT_RESULT = 0x20
} cam_error_ata_flags;
typedef enum {
CAM_STRVIS_FLAG_NONE = 0x00,
CAM_STRVIS_FLAG_NONASCII_MASK = 0x03,
CAM_STRVIS_FLAG_NONASCII_TRIM = 0x00,
CAM_STRVIS_FLAG_NONASCII_RAW = 0x01,
CAM_STRVIS_FLAG_NONASCII_SPC = 0x02,
CAM_STRVIS_FLAG_NONASCII_ESC = 0x03
} cam_strvis_flags;
struct cam_status_entry
{
cam_status status_code;
@@ -237,6 +367,7 @@ extern const int num_cam_status_entries;
extern int cam_sort_io_queues;
#endif
union ccb;
struct sbuf;
#ifdef SYSCTL_DECL /* from sysctl.h */
SYSCTL_DECL(_kern_cam);
@@ -249,6 +380,8 @@ caddr_t cam_quirkmatch(caddr_t target, caddr_t quirk_table, int num_entries,
int entry_size, cam_quirkmatch_t *comp_func);
void cam_strvis(u_int8_t *dst, const u_int8_t *src, int srclen, int dstlen);
void cam_strvis_sbuf(struct sbuf *sb, const u_int8_t *src, int srclen,
uint32_t flags);
int cam_strmatch(const u_int8_t *str, const u_int8_t *pattern, int str_len);
const struct cam_status_entry*

View File

@@ -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 {
@@ -778,6 +813,19 @@ struct ccb_relsim {
u_int32_t qfrozen_cnt;
};
/*
* 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.
*/
@@ -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,12 +1239,23 @@ 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 */
uint8_t *buf; /* IN/OUT: Buffer for requested data */
};
/*
* 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
@@ -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,
@@ -1222,6 +1312,12 @@ cam_fill_csio(struct ccb_scsiio *csio, u_int32_t retries,
u_int8_t sense_len, u_int8_t cdb_len,
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 *),
@@ -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 */

View File

@@ -35,6 +35,7 @@
#include <cam/cam_sim.h>
#ifdef _KERNEL
#include <sys/taskqueue.h>
#include <cam/cam_xpt.h>
@@ -90,7 +91,7 @@ typedef enum {
CAM_PERIPH_BIO
} cam_periph_type;
/* Generically usefull offsets into the peripheral private area */
/* Generically useful offsets into the peripheral private area */
#define ppriv_ptr0 periph_priv.entries[0].ptr
#define ppriv_ptr1 periph_priv.entries[1].ptr
#define ppriv_field0 periph_priv.entries[0].field
@@ -103,7 +104,6 @@ typedef cam_status periph_ctor_t (struct cam_periph *periph,
typedef void periph_oninv_t (struct cam_periph *periph);
typedef void periph_dtor_t (struct cam_periph *periph);
struct cam_periph {
cam_pinfo pinfo;
periph_start_t *periph_start;
periph_oninv_t *periph_oninval;
periph_dtor_t *periph_dtor;
@@ -120,15 +120,20 @@ struct cam_periph {
#define CAM_PERIPH_INVALID 0x08
#define CAM_PERIPH_NEW_DEV_FOUND 0x10
#define CAM_PERIPH_RECOVERY_INPROG 0x20
#define CAM_PERIPH_RUN_TASK 0x40
#define CAM_PERIPH_FREE 0x80
#define CAM_PERIPH_ANNOUNCED 0x100
u_int32_t immediate_priority;
uint32_t scheduled_priority;
uint32_t immediate_priority;
int periph_allocating;
int periph_allocated;
u_int32_t refcount;
SLIST_HEAD(, ccb_hdr) ccb_list; /* For "immediate" requests */
SLIST_ENTRY(cam_periph) periph_links;
TAILQ_ENTRY(cam_periph) unit_links;
ac_callback_t *deferred_callback;
ac_code deferred_ac;
struct task periph_run_task;
};
#define CAM_PERIPH_MAXMAPS 2
@@ -147,6 +152,7 @@ cam_status cam_periph_alloc(periph_ctor_t *periph_ctor,
struct cam_periph *cam_periph_find(struct cam_path *path, char *name);
int cam_periph_list(struct cam_path *, struct sbuf *);
cam_status cam_periph_acquire(struct cam_periph *periph);
void cam_periph_doacquire(struct cam_periph *periph);
void cam_periph_release(struct cam_periph *periph);
void cam_periph_release_locked(struct cam_periph *periph);
void cam_periph_release_locked_buses(struct cam_periph *periph);
@@ -154,7 +160,8 @@ int cam_periph_hold(struct cam_periph *periph, int priority);
void cam_periph_unhold(struct cam_periph *periph);
void cam_periph_invalidate(struct cam_periph *periph);
int cam_periph_mapmem(union ccb *ccb,
struct cam_periph_map_info *mapinfo);
struct cam_periph_map_info *mapinfo,
u_int maxmap);
void cam_periph_unmapmem(union ccb *ccb,
struct cam_periph_map_info *mapinfo);
union ccb *cam_periph_getccb(struct cam_periph *periph,
@@ -185,30 +192,26 @@ void cam_periph_freeze_after_event(struct cam_periph *periph,
int cam_periph_error(union ccb *ccb, cam_flags camflags,
u_int32_t sense_flags, union ccb *save_ccb);
static __inline void
cam_periph_lock(struct cam_periph *periph)
static __inline struct mtx *
cam_periph_mtx(struct cam_periph *periph)
{
mtx_lock(periph->sim->mtx);
return (xpt_path_mtx(periph->path));
}
static __inline void
cam_periph_unlock(struct cam_periph *periph)
{
mtx_unlock(periph->sim->mtx);
}
#define cam_periph_owned(periph) \
mtx_owned(xpt_path_mtx((periph)->path))
static __inline int
cam_periph_owned(struct cam_periph *periph)
{
return (mtx_owned(periph->sim->mtx));
}
#define cam_periph_lock(periph) \
mtx_lock(xpt_path_mtx((periph)->path))
static __inline int
cam_periph_sleep(struct cam_periph *periph, void *chan, int priority,
const char *wmesg, int timo)
{
return (msleep(chan, periph->sim->mtx, priority, wmesg, timo));
}
#define cam_periph_unlock(periph) \
mtx_unlock(xpt_path_mtx((periph)->path))
#define cam_periph_assert(periph, what) \
mtx_assert(xpt_path_mtx((periph)->path), (what))
#define cam_periph_sleep(periph, chan, priority, wmesg, timo) \
xpt_path_sleep((periph)->path, (chan), (priority), (wmesg), (timo))
static inline struct cam_periph *
cam_periph_acquire_first(struct periph_driver *driver)
@@ -230,7 +233,7 @@ cam_periph_acquire_next(struct cam_periph *pperiph)
{
struct cam_periph *periph = pperiph;
mtx_assert(pperiph->sim->mtx, MA_NOTOWNED);
cam_periph_assert(pperiph, MA_NOTOWNED);
xpt_lock_buses();
do {
periph = TAILQ_NEXT(periph, unit_links);

View File

@@ -145,24 +145,10 @@ struct cam_sim {
u_int32_t flags;
#define CAM_SIM_REL_TIMEOUT_PENDING 0x01
#define CAM_SIM_MPSAFE 0x02
#define CAM_SIM_ON_DONEQ 0x04
#define CAM_SIM_POLLED 0x08
#define CAM_SIM_BATCH 0x10
struct callout callout;
struct cam_devq *devq; /* Device Queue to use for this SIM */
int refcount; /* References to the SIM. */
/* "Pool" of inactive ccbs managed by xpt_get_ccb and xpt_release_ccb */
SLIST_HEAD(,ccb_hdr) ccb_freeq;
/*
* Maximum size of ccb pool. Modified as devices are added/removed
* or have their * opening counts changed.
*/
u_int max_ccbs;
/* Current count of allocated ccbs */
u_int ccb_count;
#endif /* __rtems__ */
};
#define CAM_SIM_LOCK(sim) mtx_lock((sim)->mtx)

View File

@@ -56,6 +56,7 @@ struct cam_path;
struct async_node {
SLIST_ENTRY(async_node) links;
u_int32_t event_enable; /* Async Event enables */
u_int32_t event_lock; /* Take SIM lock for handlers. */
void (*callback)(void *arg, u_int32_t code,
struct cam_path *path, void *args);
void *callback_arg;
@@ -69,6 +70,10 @@ void xpt_action_default(union ccb *new_ccb);
union ccb *xpt_alloc_ccb(void);
union ccb *xpt_alloc_ccb_nowait(void);
void xpt_free_ccb(union ccb *free_ccb);
void xpt_setup_ccb_flags(struct ccb_hdr *ccb_h,
struct cam_path *path,
u_int32_t priority,
u_int32_t flags);
void xpt_setup_ccb(struct ccb_hdr *ccb_h,
struct cam_path *path,
u_int32_t priority);
@@ -100,7 +105,6 @@ int xpt_path_string(struct cam_path *path, char *str,
path_id_t xpt_path_path_id(struct cam_path *path);
target_id_t xpt_path_target_id(struct cam_path *path);
lun_id_t xpt_path_lun_id(struct cam_path *path);
int xpt_path_legacy_ata_id(struct cam_path *path);
struct cam_sim *xpt_path_sim(struct cam_path *path);
struct cam_periph *xpt_path_periph(struct cam_path *path);
void xpt_async(u_int32_t async_code, struct cam_path *path,
@@ -110,6 +114,13 @@ void xpt_hold_boot(void);
void xpt_release_boot(void);
void xpt_lock_buses(void);
void xpt_unlock_buses(void);
struct mtx * xpt_path_mtx(struct cam_path *path);
#define xpt_path_lock(path) mtx_lock(xpt_path_mtx(path))
#define xpt_path_unlock(path) mtx_unlock(xpt_path_mtx(path))
#define xpt_path_assert(path, what) mtx_assert(xpt_path_mtx(path), (what))
#define xpt_path_owned(path) mtx_owned(xpt_path_mtx(path))
#define xpt_path_sleep(path, chan, priority, wmesg, timo) \
msleep((chan), xpt_path_mtx(path), (priority), (wmesg), (timo))
cam_status xpt_register_async(int event, ac_callback_t *cbfunc,
void *cbarg, struct cam_path *path);
cam_status xpt_compile_path(struct cam_path *new_path,
@@ -117,6 +128,10 @@ cam_status xpt_compile_path(struct cam_path *new_path,
path_id_t path_id,
target_id_t target_id,
lun_id_t lun_id);
cam_status xpt_clone_path(struct cam_path **new_path,
struct cam_path *path);
void xpt_copy_path(struct cam_path *new_path,
struct cam_path *path);
void xpt_release_path(struct cam_path *path);

View File

@@ -49,10 +49,8 @@ u_int32_t xpt_freeze_devq(struct cam_path *path, u_int count);
#endif /* __rtems__ */
void xpt_release_devq(struct cam_path *path,
u_int count, int run_queue);
int xpt_sim_opened(struct cam_sim *sim);
void xpt_done(union ccb *done_ccb);
void xpt_batch_start(struct cam_sim *sim);
void xpt_batch_done(struct cam_sim *sim);
void xpt_done_direct(union ccb *done_ccb);
#endif
#endif /* _CAM_CAM_XPT_SIM_H */

View File

@@ -0,0 +1,48 @@
/*-
* Copyright (c) 2015 Netflix, Inc
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer,
* without modification, immediately at the beginning of the file.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* $FreeBSD$
*/
#ifndef CAM_NVME_NVME_ALL_H
#define CAM_NVME_NVME_ALL_H 1
#include <dev/nvme/nvme.h>
struct ccb_nvmeio;
#define NVME_REV_1 1 /* Supports NVMe 1.2 or earlier */
void nvme_ns_cmd(struct ccb_nvmeio *nvmeio, uint8_t cmd, uint32_t nsid,
uint32_t cdw10, uint32_t cdw11, uint32_t cdw12, uint32_t cdw13,
uint32_t cdw14, uint32_t cdw15);
int nvme_identify_match(caddr_t identbuffer, caddr_t table_entry);
void nvme_print_ident(const struct nvme_controller_data *, const struct nvme_namespace_data *);
const char *nvme_op_string(const struct nvme_command *);
const char *nvme_cmd_string(const struct nvme_command *, char *, size_t);
#endif /* CAM_NVME_NVME_ALL_H */

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -92,28 +92,23 @@ struct scsi_reassign_blocks
struct scsi_read_defect_data_10
{
u_int8_t opcode;
/*
* The most significant 3 bits are the LUN, the other 5 are
* reserved.
*/
#define SRDD10_LUN_MASK 0xE0
u_int8_t byte2;
uint8_t opcode;
uint8_t byte2;
#define SRDD10_GLIST 0x08
#define SRDD10_PLIST 0x10
#define SRDD10_DLIST_FORMAT_MASK 0x07
#define SRDD10_BLOCK_FORMAT 0x00
#define SRDD10_EXT_BFI_FORMAT 0x01
#define SRDD10_EXT_PHYS_FORMAT 0x02
#define SRDD10_LONG_BLOCK_FORMAT 0x03
#define SRDD10_BYTES_FROM_INDEX_FORMAT 0x04
#define SRDD10_PHYSICAL_SECTOR_FORMAT 0x05
u_int8_t format;
u_int8_t reserved[4];
u_int8_t alloc_length[2];
#define SRDD10_VENDOR_FORMAT 0x06
uint8_t format;
uint8_t reserved[4];
uint8_t alloc_length[2];
#define SRDD10_MAX_LENGTH 0xffff
u_int8_t control;
uint8_t control;
};
struct scsi_sanitize
@@ -143,31 +138,99 @@ struct scsi_sanitize_parameter_list
struct scsi_read_defect_data_12
{
u_int8_t opcode;
/*
* The most significant 3 bits are the LUN, the other 5 are
* reserved.
*/
#define SRDD12_LUN_MASK 0xE0
u_int8_t byte2;
uint8_t opcode;
#define SRDD12_GLIST 0x08
#define SRDD12_PLIST 0x10
#define SRDD12_DLIST_FORMAT_MASK 0x07
#define SRDD12_BLOCK_FORMAT 0x00
#define SRDD12_BYTES_FROM_INDEX_FORMAT 0x04
#define SRDD12_PHYSICAL_SECTOR_FORMAT 0x05
u_int8_t format;
u_int8_t reserved[4];
u_int8_t alloc_length[4];
u_int8_t control;
#define SRDD12_BLOCK_FORMAT SRDD10_BLOCK_FORMAT
#define SRDD12_BYTES_FROM_INDEX_FORMAT SRDD10_BYTES_FROM_INDEX_FORMAT
#define SRDD12_PHYSICAL_SECTOR_FORMAT SRDD10_PHYSICAL_SECTOR_FORMAT
uint8_t format;
uint8_t address_descriptor_index[4];
uint8_t alloc_length[4];
#define SRDD12_MAX_LENGTH 0xffffffff
uint8_t reserved;
uint8_t control;
};
struct scsi_zbc_out
{
uint8_t opcode;
uint8_t service_action;
#define ZBC_OUT_SA_CLOSE 0x01
#define ZBC_OUT_SA_FINISH 0x02
#define ZBC_OUT_SA_OPEN 0x03
#define ZBC_OUT_SA_RWP 0x04
uint8_t zone_id[8];
uint8_t reserved[4];
uint8_t zone_flags;
#define ZBC_OUT_ALL 0x01
uint8_t control;
};
struct scsi_zbc_in
{
uint8_t opcode;
uint8_t service_action;
#define ZBC_IN_SA_REPORT_ZONES 0x00
uint8_t zone_start_lba[8];
uint8_t length[4];
uint8_t zone_options;
#define ZBC_IN_PARTIAL 0x80
#define ZBC_IN_REP_ALL_ZONES 0x00
#define ZBC_IN_REP_EMPTY 0x01
#define ZBC_IN_REP_IMP_OPEN 0x02
#define ZBC_IN_REP_EXP_OPEN 0x03
#define ZBC_IN_REP_CLOSED 0x04
#define ZBC_IN_REP_FULL 0x05
#define ZBC_IN_REP_READONLY 0x06
#define ZBC_IN_REP_OFFLINE 0x07
#define ZBC_IN_REP_RESET 0x10
#define ZBC_IN_REP_NON_SEQ 0x11
#define ZBC_IN_REP_NON_WP 0x3f
#define ZBC_IN_REP_MASK 0x3f
uint8_t control;
};
struct scsi_report_zones_desc {
uint8_t zone_type;
#define SRZ_TYPE_CONVENTIONAL 0x01
#define SRZ_TYPE_SEQ_REQUIRED 0x02
#define SRZ_TYPE_SEQ_PREFERRED 0x03
#define SRZ_TYPE_MASK 0x0f
uint8_t zone_flags;
#define SRZ_ZONE_COND_SHIFT 4
#define SRZ_ZONE_COND_MASK 0xf0
#define SRZ_ZONE_COND_NWP 0x00
#define SRZ_ZONE_COND_EMPTY 0x10
#define SRZ_ZONE_COND_IMP_OPEN 0x20
#define SRZ_ZONE_COND_EXP_OPEN 0x30
#define SRZ_ZONE_COND_CLOSED 0x40
#define SRZ_ZONE_COND_READONLY 0xd0
#define SRZ_ZONE_COND_FULL 0xe0
#define SRZ_ZONE_COND_OFFLINE 0xf0
#define SRZ_ZONE_NON_SEQ 0x02
#define SRZ_ZONE_RESET 0x01
uint8_t reserved[6];
uint8_t zone_length[8];
uint8_t zone_start_lba[8];
uint8_t write_pointer_lba[8];
uint8_t reserved2[32];
};
struct scsi_report_zones_hdr {
uint8_t length[4];
uint8_t byte4;
#define SRZ_SAME_ALL_DIFFERENT 0x00 /* Lengths and types vary */
#define SRZ_SAME_ALL_SAME 0x01 /* Lengths and types the same */
#define SRZ_SAME_LAST_DIFFERENT 0x02 /* Types same, last length varies */
#define SRZ_SAME_TYPES_DIFFERENT 0x03 /* Types vary, length the same */
#define SRZ_SAME_MASK 0x0f
uint8_t reserved[3];
uint8_t maximum_lba[8];
uint8_t reserved2[48];
struct scsi_report_zones_desc desc_list[];
};
/*
* Opcodes
@@ -182,6 +245,8 @@ struct scsi_read_defect_data_12
#define VERIFY 0x2f
#define READ_DEFECT_DATA_10 0x37
#define SANITIZE 0x48
#define ZBC_OUT 0x94
#define ZBC_IN 0x95
#define READ_DEFECT_DATA_12 0xb7
struct format_defect_list_header
@@ -222,18 +287,49 @@ struct scsi_read_format_capacities
uint8_t reserved1[3];
};
struct scsi_verify
struct scsi_verify_10
{
uint8_t opcode; /* VERIFY */
uint8_t opcode; /* VERIFY(10) */
uint8_t byte2;
#define SVFY_LUN_MASK 0xE0
#define SVFY_RELADR 0x01
#define SVFY_BYTECHK 0x02
#define SVFY_BYTCHK 0x02
#define SVFY_DPO 0x10
uint8_t addr[4]; /* LBA to begin verification at */
uint8_t reserved0[1];
uint8_t len[2]; /* number of blocks to verify */
uint8_t reserved1[3];
uint8_t group;
uint8_t length[2]; /* number of blocks to verify */
uint8_t control;
};
struct scsi_verify_12
{
uint8_t opcode; /* VERIFY(12) */
uint8_t byte2;
uint8_t addr[4]; /* LBA to begin verification at */
uint8_t length[4]; /* number of blocks to verify */
uint8_t group;
uint8_t control;
};
struct scsi_verify_16
{
uint8_t opcode; /* VERIFY(16) */
uint8_t byte2;
uint8_t addr[8]; /* LBA to begin verification at */
uint8_t length[4]; /* number of blocks to verify */
uint8_t group;
uint8_t control;
};
struct scsi_compare_and_write
{
uint8_t opcode; /* COMPARE AND WRITE */
uint8_t byte2;
uint8_t addr[8]; /* LBA to begin verification at */
uint8_t reserved[3];
uint8_t length; /* number of blocks */
uint8_t group;
uint8_t control;
};
struct scsi_write_and_verify
@@ -314,6 +410,8 @@ struct scsi_read_defect_data_hdr_10
#define SRDDH10_PHYSICAL_SECTOR_FORMAT 0x05
u_int8_t format;
u_int8_t length[2];
#define SRDDH10_MAX_LENGTH SRDD10_MAX_LENGTH - \
sizeof(struct scsi_read_defect_data_hdr_10)
};
struct scsi_defect_desc_block
@@ -321,10 +419,18 @@ struct scsi_defect_desc_block
u_int8_t address[4];
};
struct scsi_defect_desc_long_block
{
u_int8_t address[8];
};
struct scsi_defect_desc_bytes_from_index
{
u_int8_t cylinder[3];
u_int8_t head;
#define SDD_EXT_BFI_MADS 0x80000000
#define SDD_EXT_BFI_FLAG_MASK 0xf0000000
#define SDD_EXT_BFI_ENTIRE_TRACK 0x0fffffff
u_int8_t bytes_from_index[4];
};
@@ -332,6 +438,9 @@ struct scsi_defect_desc_phys_sector
{
u_int8_t cylinder[3];
u_int8_t head;
#define SDD_EXT_PHYS_MADS 0x80000000
#define SDD_EXT_PHYS_FLAG_MASK 0xf0000000
#define SDD_EXT_PHYS_ENTIRE_TRACK 0x0fffffff
u_int8_t sector[4];
};
@@ -345,7 +454,10 @@ struct scsi_read_defect_data_hdr_12
#define SRDDH12_BYTES_FROM_INDEX_FORMAT 0x04
#define SRDDH12_PHYSICAL_SECTOR_FORMAT 0x05
u_int8_t format;
u_int8_t generation[2];
u_int8_t length[4];
#define SRDDH12_MAX_LENGTH SRDD12_MAX_LENGTH - \
sizeof(struct scsi_read_defect_data_hdr_12)
};
union disk_pages /* this is the structure copied from osf */
@@ -515,7 +627,8 @@ struct scsi_da_rw_recovery_page {
u_int8_t correction_span;
u_int8_t head_offset_count;
u_int8_t data_strobe_offset_cnt;
u_int8_t reserved;
u_int8_t byte8;
#define SMS_RWER_LBPERE 0x80
u_int8_t write_retry_count;
u_int8_t reserved2;
u_int8_t recovery_time_limit[2];
@@ -523,9 +636,9 @@ struct scsi_da_rw_recovery_page {
__BEGIN_DECLS
/*
* XXX This is only left out of the kernel build to silence warnings. If,
* for some reason this function is used in the kernel, the ifdefs should
* be moved so it is included both in the kernel and userland.
* XXX These are only left out of the kernel build to silence warnings. If,
* for some reason these functions are used in the kernel, the ifdefs should
* be moved so they are included both in the kernel and userland.
*/
#ifndef _KERNEL
void scsi_format_unit(struct ccb_scsiio *csio, u_int32_t retries,
@@ -534,6 +647,13 @@ void scsi_format_unit(struct ccb_scsiio *csio, u_int32_t retries,
u_int8_t *data_ptr, u_int32_t dxfer_len,
u_int8_t sense_len, u_int32_t timeout);
void scsi_read_defects(struct ccb_scsiio *csio, uint32_t retries,
void (*cbfcnp)(struct cam_periph *, union ccb *),
uint8_t tag_action, uint8_t list_format,
uint32_t addr_desc_index, uint8_t *data_ptr,
uint32_t dxfer_len, int minimum_cmd_size,
uint8_t sense_len, uint32_t timeout);
void scsi_sanitize(struct ccb_scsiio *csio, u_int32_t retries,
void (*cbfcnp)(struct cam_periph *, union ccb *),
u_int8_t tag_action, u_int8_t byte2, u_int16_t control,
@@ -541,6 +661,38 @@ void scsi_sanitize(struct ccb_scsiio *csio, u_int32_t retries,
u_int32_t timeout);
#endif /* !_KERNEL */
void scsi_zbc_out(struct ccb_scsiio *csio, uint32_t retries,
void (*cbfcnp)(struct cam_periph *, union ccb *),
uint8_t tag_action, uint8_t service_action, uint64_t zone_id,
uint8_t zone_flags, uint8_t *data_ptr, uint32_t dxfer_len,
uint8_t sense_len, uint32_t timeout);
void scsi_zbc_in(struct ccb_scsiio *csio, uint32_t retries,
void (*cbfcnp)(struct cam_periph *, union ccb *),
uint8_t tag_action, uint8_t service_action,
uint64_t zone_start_lba, uint8_t zone_options,
uint8_t *data_ptr, uint32_t dxfer_len, uint8_t sense_len,
uint32_t timeout);
int scsi_ata_zac_mgmt_out(struct ccb_scsiio *csio, uint32_t retries,
void (*cbfcnp)(struct cam_periph *, union ccb *),
uint8_t tag_action, int use_ncq,
uint8_t zm_action, uint64_t zone_id,
uint8_t zone_flags, uint8_t *data_ptr,
uint32_t dxfer_len, uint8_t *cdb_storage,
size_t cdb_storage_len, uint8_t sense_len,
uint32_t timeout);
int scsi_ata_zac_mgmt_in(struct ccb_scsiio *csio, uint32_t retries,
void (*cbfcnp)(struct cam_periph *, union ccb *),
uint8_t tag_action, int use_ncq,
uint8_t zm_action, uint64_t zone_id,
uint8_t zone_flags, uint8_t *data_ptr,
uint32_t dxfer_len, uint8_t *cdb_storage,
size_t cdb_storage_len, uint8_t sense_len,
uint32_t timeout);
__END_DECLS
#endif /* _SCSI_SCSI_DA_H */