aboutsummaryrefslogtreecommitdiff
path: root/sys/cam
diff options
context:
space:
mode:
Diffstat (limited to 'sys/cam')
-rw-r--r--sys/cam/ata/ata_all.c24
-rw-r--r--sys/cam/mmc/mmc_da.c8
-rw-r--r--sys/cam/scsi/scsi_all.c112
-rw-r--r--sys/cam/scsi/scsi_all.h5
-rw-r--r--sys/cam/scsi/scsi_da.c30
-rw-r--r--sys/cam/scsi/scsi_pass.c2
-rw-r--r--sys/cam/scsi/scsi_sg.c2
7 files changed, 110 insertions, 73 deletions
diff --git a/sys/cam/ata/ata_all.c b/sys/cam/ata/ata_all.c
index 1e5b5a8feed9..76d65ae5e405 100644
--- a/sys/cam/ata/ata_all.c
+++ b/sys/cam/ata/ata_all.c
@@ -89,8 +89,14 @@ ata_op_string(struct ata_cmd *cmd)
case 0x01: return ("DSM TRIM");
}
return "DSM";
+ case 0x07:
+ switch (cmd->features) {
+ case 0x01: return ("DSM_XL TRIM");
+ }
+ return "DSM_XL";
case 0x08: return ("DEVICE_RESET");
case 0x0b: return ("REQUEST_SENSE_DATA_EXT");
+ case 0x12: return ("GET_PHYSICAL_ELEMENT_STATUS");
case 0x20: return ("READ");
case 0x24: return ("READ48");
case 0x25: return ("READ_DMA48");
@@ -113,7 +119,11 @@ ata_op_string(struct ata_cmd *cmd)
case 0x3f: return ("WRITE_LOG_EXT");
case 0x40: return ("READ_VERIFY");
case 0x42: return ("READ_VERIFY48");
- case 0x44: return ("ZERO_EXT");
+ case 0x44:
+ switch (cmd->features) {
+ case 0x01: return ("ZERO_EXT TRIM");
+ }
+ return "ZERO_EXT";
case 0x45:
switch (cmd->features) {
case 0x55: return ("WRITE_UNCORRECTABLE48 PSEUDO");
@@ -135,6 +145,9 @@ ata_op_string(struct ata_cmd *cmd)
switch (cmd->features & 0xf) {
case 0x00: return ("NCQ_NON_DATA ABORT NCQ QUEUE");
case 0x01: return ("NCQ_NON_DATA DEADLINE HANDLING");
+ case 0x02: return ("NCQ_NON_DATA HYBRID DEMOTE BY SIZE");
+ case 0x03: return ("NCQ_NON_DATA HYBRID CHANGE BY LBA RANGE");
+ case 0x04: return ("NCQ_NON_DATA HYBRID CONTROL");
case 0x05: return ("NCQ_NON_DATA SET FEATURES");
/*
* XXX KDM need common decoding between NCQ and non-NCQ
@@ -147,6 +160,7 @@ ata_op_string(struct ata_cmd *cmd)
case 0x64:
switch (cmd->sector_count_exp & 0xf) {
case 0x00: return ("SEND_FPDMA_QUEUED DATA SET MANAGEMENT");
+ case 0x01: return ("SEND_FPDMA_QUEUED HYBRID EVICT");
case 0x02: return ("SEND_FPDMA_QUEUED WRITE LOG DMA EXT");
case 0x03: return ("SEND_FPDMA_QUEUED ZAC MANAGEMENT OUT");
case 0x04: return ("SEND_FPDMA_QUEUED DATA SET MANAGEMENT XL");
@@ -171,6 +185,7 @@ ata_op_string(struct ata_cmd *cmd)
case 0x70: return ("SEEK");
case 0x77: return ("SET_DATE_TIME_EXT");
case 0x78: return ("ACCESSIBLE_MAX_ADDRESS_CONFIGURATION");
+ case 0x7C: return ("REMOVE_ELEMENT_AND_TRUNCATE");
case 0x87: return ("CFA_TRANSLATE_SECTOR");
case 0x90: return ("EXECUTE_DEVICE_DIAGNOSTIC");
case 0x92: return ("DOWNLOAD_MICROCODE");
@@ -185,13 +200,15 @@ ata_op_string(struct ata_cmd *cmd)
case 0xd1: return ("SMART READ ATTR THRESHOLDS");
case 0xd3: return ("SMART SAVE ATTR VALUES");
case 0xd4: return ("SMART EXECUTE OFFLINE IMMEDIATE");
- case 0xd5: return ("SMART READ LOG DATA");
+ case 0xd5: return ("SMART READ LOG");
+ case 0xd6: return ("SMART WRITE LOG");
case 0xd8: return ("SMART ENABLE OPERATION");
case 0xd9: return ("SMART DISABLE OPERATION");
case 0xda: return ("SMART RETURN STATUS");
}
return ("SMART");
case 0xb1: return ("DEVICE CONFIGURATION");
+ case 0xb2: return ("SET_SECTOR_CONFIGURATION_EXT");
case 0xb4: return ("SANITIZE_DEVICE");
case 0xc0: return ("CFA_ERASE");
case 0xc4: return ("READ_MUL");
@@ -229,7 +246,7 @@ ata_op_string(struct ata_cmd *cmd)
switch (cmd->features) {
case 0x02: return ("SETFEATURES ENABLE WCACHE");
case 0x03: return ("SETFEATURES SET TRANSFER MODE");
- case 0x04: return ("SETFEATURES ENABLE APM");
+ case 0x05: return ("SETFEATURES ENABLE APM");
case 0x06: return ("SETFEATURES ENABLE PUIS");
case 0x07: return ("SETFEATURES SPIN-UP");
case 0x0b: return ("SETFEATURES ENABLE WRITE READ VERIFY");
@@ -239,6 +256,7 @@ ata_op_string(struct ata_cmd *cmd)
case 0x43: return ("SETFEATURES SET MAX HOST INT SECT TIMES");
case 0x45: return ("SETFEATURES SET RATE BASIS");
case 0x4a: return ("SETFEATURES EXTENDED POWER CONDITIONS");
+ case 0x50: return ("SETFEATURES ADVANCED BACKGROUD OPERATION");
case 0x55: return ("SETFEATURES DISABLE RCACHE");
case 0x5d: return ("SETFEATURES ENABLE RELIRQ");
case 0x5e: return ("SETFEATURES ENABLE SRVIRQ");
diff --git a/sys/cam/mmc/mmc_da.c b/sys/cam/mmc/mmc_da.c
index 4b18a82a1da9..18cfcd290efb 100644
--- a/sys/cam/mmc/mmc_da.c
+++ b/sys/cam/mmc/mmc_da.c
@@ -791,6 +791,11 @@ sddaregister(struct cam_periph *periph, void *arg)
softc->state = SDDA_STATE_INIT;
softc->mmcdata =
(struct mmc_data *)malloc(sizeof(struct mmc_data), M_DEVBUF, M_NOWAIT|M_ZERO);
+ if (softc->mmcdata == NULL) {
+ printf("sddaregister: Unable to probe new device. "
+ "Unable to allocate mmcdata\n");
+ return (CAM_REQ_CMP_ERR);
+ }
periph->softc = softc;
softc->periph = periph;
@@ -889,6 +894,7 @@ mmc_send_ext_csd(struct cam_periph *periph, union ccb *ccb,
struct mmc_data d;
KASSERT(buf_len == 512, ("Buffer for ext csd must be 512 bytes"));
+ memset(&d, 0, sizeof(d));
d.data = rawextcsd;
d.len = buf_len;
d.flags = MMC_DATA_READ;
@@ -1013,6 +1019,7 @@ mmc_sd_switch(struct cam_periph *periph, union ccb *ccb,
int err;
memset(res, 0, 64);
+ memset(&mmc_d, 0, sizeof(mmc_d));
mmc_d.len = 64;
mmc_d.data = res;
mmc_d.flags = MMC_DATA_READ;
@@ -1804,6 +1811,7 @@ sddastart(struct cam_periph *periph, union ccb *start_ccb)
mmcio->cmd.flags = MMC_RSP_R1 | MMC_CMD_ADTC;
mmcio->cmd.data = softc->mmcdata;
+ memset(mmcio->cmd.data, 0, sizeof(struct mmc_data));
mmcio->cmd.data->data = bp->bio_data;
mmcio->cmd.data->len = 512 * count;
mmcio->cmd.data->flags = (bp->bio_cmd == BIO_READ ? MMC_DATA_READ : MMC_DATA_WRITE);
diff --git a/sys/cam/scsi/scsi_all.c b/sys/cam/scsi/scsi_all.c
index a78963ce8769..3ac7d07724b2 100644
--- a/sys/cam/scsi/scsi_all.c
+++ b/sys/cam/scsi/scsi_all.c
@@ -4061,6 +4061,10 @@ scsi_get_sense_info(struct scsi_sense_data *sense_data, u_int sense_len,
struct scsi_sense_info *info_desc;
info_desc = (struct scsi_sense_info *)desc;
+
+ if ((info_desc->byte2 & SSD_INFO_VALID) == 0)
+ goto bailout;
+
*info = scsi_8btou64(info_desc->info);
if (signed_info != NULL)
*signed_info = *info;
@@ -4081,6 +4085,9 @@ scsi_get_sense_info(struct scsi_sense_data *sense_data, u_int sense_len,
fru_desc = (struct scsi_sense_fru *)desc;
+ if (fru_desc->fru == 0)
+ goto bailout;
+
*info = fru_desc->fru;
if (signed_info != NULL)
*signed_info = (int8_t)fru_desc->fru;
@@ -4181,10 +4188,9 @@ scsi_get_sks(struct scsi_sense_data *sense_data, u_int sense_len, uint8_t *sks)
if (desc == NULL)
goto bailout;
- /*
- * No need to check the SKS valid bit for descriptor sense.
- * If the descriptor is present, it is valid.
- */
+ if ((desc->sense_key_spec[0] & SSD_SKS_VALID) == 0)
+ goto bailout;
+
bcopy(desc->sense_key_spec, sks, sizeof(desc->sense_key_spec));
break;
}
@@ -4261,9 +4267,6 @@ scsi_get_block_info(struct scsi_sense_data *sense_data, u_int sense_len,
if (SSD_FIXED_IS_PRESENT(sense, sense_len, flags) == 0)
goto bailout;
- if ((sense->flags & SSD_ILI) == 0)
- goto bailout;
-
*block_bits = sense->flags & SSD_ILI;
break;
}
@@ -4317,9 +4320,6 @@ scsi_get_stream_info(struct scsi_sense_data *sense_data, u_int sense_len,
if (SSD_FIXED_IS_PRESENT(sense, sense_len, flags) == 0)
goto bailout;
- if ((sense->flags & (SSD_ILI|SSD_EOM|SSD_FILEMARK)) == 0)
- goto bailout;
-
*stream_bits = sense->flags & (SSD_ILI|SSD_EOM|SSD_FILEMARK);
break;
}
@@ -4361,8 +4361,6 @@ scsi_progress_sbuf(struct sbuf *sb, uint16_t progress)
int
scsi_sks_sbuf(struct sbuf *sb, int sense_key, uint8_t *sks)
{
- if ((sks[0] & SSD_SKS_VALID) == 0)
- return (1);
switch (sense_key) {
case SSD_KEY_ILLEGAL_REQUEST: {
@@ -4459,7 +4457,7 @@ scsi_fru_sbuf(struct sbuf *sb, uint64_t fru)
}
void
-scsi_stream_sbuf(struct sbuf *sb, uint8_t stream_bits, uint64_t info)
+scsi_stream_sbuf(struct sbuf *sb, uint8_t stream_bits)
{
int need_comma;
@@ -4467,6 +4465,7 @@ scsi_stream_sbuf(struct sbuf *sb, uint8_t stream_bits, uint64_t info)
/*
* XXX KDM this needs more descriptive decoding.
*/
+ sbuf_printf(sb, "Stream Command Sense Data: ");
if (stream_bits & SSD_DESC_STREAM_FM) {
sbuf_printf(sb, "Filemark");
need_comma = 1;
@@ -4479,15 +4478,15 @@ scsi_stream_sbuf(struct sbuf *sb, uint8_t stream_bits, uint64_t info)
if (stream_bits & SSD_DESC_STREAM_ILI)
sbuf_printf(sb, "%sILI", (need_comma) ? "," : "");
-
- sbuf_printf(sb, ": Info: %#jx", (uintmax_t) info);
}
void
-scsi_block_sbuf(struct sbuf *sb, uint8_t block_bits, uint64_t info)
+scsi_block_sbuf(struct sbuf *sb, uint8_t block_bits)
{
+
+ sbuf_printf(sb, "Block Command Sense Data: ");
if (block_bits & SSD_DESC_BLOCK_ILI)
- sbuf_printf(sb, "ILI: residue %#jx", (uintmax_t) info);
+ sbuf_printf(sb, "ILI");
}
void
@@ -4500,6 +4499,9 @@ scsi_sense_info_sbuf(struct sbuf *sb, struct scsi_sense_data *sense,
info = (struct scsi_sense_info *)header;
+ if ((info->byte2 & SSD_INFO_VALID) == 0)
+ return;
+
scsi_info_sbuf(sb, cdb, cdb_len, inq_data, scsi_8btou64(info->info));
}
@@ -4528,6 +4530,9 @@ scsi_sense_sks_sbuf(struct sbuf *sb, struct scsi_sense_data *sense,
sks = (struct scsi_sense_sks *)header;
+ if ((sks->sense_key_spec[0] & SSD_SKS_VALID) == 0)
+ return;
+
scsi_extract_sense_len(sense, sense_len, &error_code, &sense_key,
&asc, &ascq, /*show_errors*/ 1);
@@ -4544,6 +4549,9 @@ scsi_sense_fru_sbuf(struct sbuf *sb, struct scsi_sense_data *sense,
fru = (struct scsi_sense_fru *)header;
+ if (fru->fru == 0)
+ return;
+
scsi_fru_sbuf(sb, (uint64_t)fru->fru);
}
@@ -4554,14 +4562,9 @@ scsi_sense_stream_sbuf(struct sbuf *sb, struct scsi_sense_data *sense,
struct scsi_sense_desc_header *header)
{
struct scsi_sense_stream *stream;
- uint64_t info;
stream = (struct scsi_sense_stream *)header;
- info = 0;
-
- scsi_get_sense_info(sense, sense_len, SSD_DESC_INFO, &info, NULL);
-
- scsi_stream_sbuf(sb, stream->byte3, info);
+ scsi_stream_sbuf(sb, stream->byte3);
}
void
@@ -4571,14 +4574,9 @@ scsi_sense_block_sbuf(struct sbuf *sb, struct scsi_sense_data *sense,
struct scsi_sense_desc_header *header)
{
struct scsi_sense_block *block;
- uint64_t info;
block = (struct scsi_sense_block *)header;
- info = 0;
-
- scsi_get_sense_info(sense, sense_len, SSD_DESC_INFO, &info, NULL);
-
- scsi_block_sbuf(sb, block->byte3, info);
+ scsi_block_sbuf(sb, block->byte3);
}
void
@@ -4863,7 +4861,7 @@ scsi_sense_only_sbuf(struct scsi_sense_data *sense, u_int sense_len,
const char *asc_desc;
uint8_t sks[3];
uint64_t val;
- int info_valid;
+ uint8_t bits;
/*
* Get descriptions for the sense key, ASC, and ASCQ. If
@@ -4882,42 +4880,28 @@ scsi_sense_only_sbuf(struct scsi_sense_data *sense, u_int sense_len,
sbuf_printf(sb, " asc:%x,%x (%s)\n", asc, ascq, asc_desc);
/*
- * Get the info field if it is valid.
+ * Print any block or stream device-specific information.
*/
- if (scsi_get_sense_info(sense, sense_len, SSD_DESC_INFO,
- &val, NULL) == 0)
- info_valid = 1;
- else
- info_valid = 0;
-
- if (info_valid != 0) {
- uint8_t bits;
+ if (scsi_get_block_info(sense, sense_len, inq_data,
+ &bits) == 0 && bits != 0) {
+ sbuf_cat(sb, path_str);
+ scsi_block_sbuf(sb, bits);
+ sbuf_printf(sb, "\n");
+ } else if (scsi_get_stream_info(sense, sense_len, inq_data,
+ &bits) == 0 && bits != 0) {
+ sbuf_cat(sb, path_str);
+ scsi_stream_sbuf(sb, bits);
+ sbuf_printf(sb, "\n");
+ }
- /*
- * Determine whether we have any block or stream
- * device-specific information.
- */
- if (scsi_get_block_info(sense, sense_len, inq_data,
- &bits) == 0) {
- sbuf_cat(sb, path_str);
- scsi_block_sbuf(sb, bits, val);
- sbuf_printf(sb, "\n");
- } else if (scsi_get_stream_info(sense, sense_len,
- inq_data, &bits) == 0) {
- sbuf_cat(sb, path_str);
- scsi_stream_sbuf(sb, bits, val);
- sbuf_printf(sb, "\n");
- } else if (val != 0) {
- /*
- * The information field can be valid but 0.
- * If the block or stream bits aren't set,
- * and this is 0, it isn't terribly useful
- * to print it out.
- */
- sbuf_cat(sb, path_str);
- scsi_info_sbuf(sb, cdb, cdb_len, inq_data, val);
- sbuf_printf(sb, "\n");
- }
+ /*
+ * Print the info field.
+ */
+ if (scsi_get_sense_info(sense, sense_len, SSD_DESC_INFO,
+ &val, NULL) == 0) {
+ sbuf_cat(sb, path_str);
+ scsi_info_sbuf(sb, cdb, cdb_len, inq_data, val);
+ sbuf_printf(sb, "\n");
}
/*
diff --git a/sys/cam/scsi/scsi_all.h b/sys/cam/scsi/scsi_all.h
index b5c45bc02a42..4434ef2fa647 100644
--- a/sys/cam/scsi/scsi_all.h
+++ b/sys/cam/scsi/scsi_all.h
@@ -2931,6 +2931,7 @@ struct scsi_read_capacity_data_long
uint8_t length[4];
#define SRC16_PROT_EN 0x01
#define SRC16_P_TYPE 0x0e
+#define SRC16_P_TYPE_SHIFT 1
#define SRC16_PTYPE_1 0x00
#define SRC16_PTYPE_2 0x02
#define SRC16_PTYPE_3 0x04
@@ -3749,8 +3750,8 @@ void scsi_command_sbuf(struct sbuf *sb, uint8_t *cdb, int cdb_len,
void scsi_progress_sbuf(struct sbuf *sb, uint16_t progress);
int scsi_sks_sbuf(struct sbuf *sb, int sense_key, uint8_t *sks);
void scsi_fru_sbuf(struct sbuf *sb, uint64_t fru);
-void scsi_stream_sbuf(struct sbuf *sb, uint8_t stream_bits, uint64_t info);
-void scsi_block_sbuf(struct sbuf *sb, uint8_t block_bits, uint64_t info);
+void scsi_stream_sbuf(struct sbuf *sb, uint8_t stream_bits);
+void scsi_block_sbuf(struct sbuf *sb, uint8_t block_bits);
void scsi_sense_info_sbuf(struct sbuf *sb, struct scsi_sense_data *sense,
u_int sense_len, uint8_t *cdb, int cdb_len,
struct scsi_inquiry_data *inq_data,
diff --git a/sys/cam/scsi/scsi_da.c b/sys/cam/scsi/scsi_da.c
index c566ffbc4aad..a89c40e19a7b 100644
--- a/sys/cam/scsi/scsi_da.c
+++ b/sys/cam/scsi/scsi_da.c
@@ -344,6 +344,7 @@ struct da_softc {
da_delete_func_t *delete_func;
int unmappedio;
int rotating;
+ int p_type;
struct disk_params params;
struct disk *disk;
union ccb saved_ccb;
@@ -2292,7 +2293,7 @@ dasysctlinit(void *context, int pending)
CTLFLAG_RD,
&softc->unmappedio,
0,
- "Unmapped I/O leaf");
+ "Unmapped I/O support");
SYSCTL_ADD_INT(&softc->sysctl_ctx,
SYSCTL_CHILDREN(softc->sysctl_tree),
@@ -2303,6 +2304,15 @@ dasysctlinit(void *context, int pending)
0,
"Rotating media");
+ SYSCTL_ADD_INT(&softc->sysctl_ctx,
+ SYSCTL_CHILDREN(softc->sysctl_tree),
+ OID_AUTO,
+ "p_type",
+ CTLFLAG_RD,
+ &softc->p_type,
+ 0,
+ "DIF protection type");
+
#ifdef CAM_TEST_FAILURE
SYSCTL_ADD_PROC(&softc->sysctl_ctx, SYSCTL_CHILDREN(softc->sysctl_tree),
OID_AUTO, "invalidate", CTLTYPE_U64 | CTLFLAG_RW | CTLFLAG_MPSAFE,
@@ -4649,7 +4659,7 @@ dadone_proberc(struct cam_periph *periph, union ccb *done_ccb)
da_ccb_state state;
char *announce_buf;
u_int32_t priority;
- int lbp;
+ int lbp, n;
CAM_DEBUG(periph->path, CAM_DEBUG_TRACE, ("dadone_proberc\n"));
@@ -4731,11 +4741,17 @@ dadone_proberc(struct cam_periph *periph, union ccb *done_ccb)
rcaplong, sizeof(*rcaplong));
lbp = (lalba & SRC16_LBPME_A);
dp = &softc->params;
- snprintf(announce_buf, DA_ANNOUNCETMP_SZ,
- "%juMB (%ju %u byte sectors)",
+ n = snprintf(announce_buf, DA_ANNOUNCETMP_SZ,
+ "%juMB (%ju %u byte sectors",
((uintmax_t)dp->secsize * dp->sectors) /
(1024 * 1024),
(uintmax_t)dp->sectors, dp->secsize);
+ if (softc->p_type != 0) {
+ n += snprintf(announce_buf + n,
+ DA_ANNOUNCETMP_SZ - n,
+ ", DIF type %d", softc->p_type);
+ }
+ snprintf(announce_buf + n, DA_ANNOUNCETMP_SZ - n, ")");
}
} else {
int error;
@@ -5983,9 +5999,15 @@ dasetgeom(struct cam_periph *periph, uint32_t block_len, uint64_t maxsector,
lbppbe = rcaplong->prot_lbppbe & SRC16_LBPPBE;
lalba = scsi_2btoul(rcaplong->lalba_lbp);
lalba &= SRC16_LALBA_A;
+ if (rcaplong->prot & SRC16_PROT_EN)
+ softc->p_type = ((rcaplong->prot & SRC16_P_TYPE) >>
+ SRC16_P_TYPE_SHIFT) + 1;
+ else
+ softc->p_type = 0;
} else {
lbppbe = 0;
lalba = 0;
+ softc->p_type = 0;
}
if (lbppbe > 0) {
diff --git a/sys/cam/scsi/scsi_pass.c b/sys/cam/scsi/scsi_pass.c
index c2133814eaab..b91b0556f10b 100644
--- a/sys/cam/scsi/scsi_pass.c
+++ b/sys/cam/scsi/scsi_pass.c
@@ -2261,7 +2261,9 @@ passsendccb(struct cam_periph *periph, union ccb *ccb, union ccb *inccb)
/* sense_flags */ SF_RETRY_UA | SF_NO_PRINT,
softc->device_stats);
+ cam_periph_unlock(periph);
cam_periph_unmapmem(ccb, &mapinfo);
+ cam_periph_lock(periph);
ccb->ccb_h.cbfcnp = NULL;
ccb->ccb_h.periph_priv = inccb->ccb_h.periph_priv;
diff --git a/sys/cam/scsi/scsi_sg.c b/sys/cam/scsi/scsi_sg.c
index caa6c7c34314..c4812f247cd9 100644
--- a/sys/cam/scsi/scsi_sg.c
+++ b/sys/cam/scsi/scsi_sg.c
@@ -915,7 +915,9 @@ sgsendccb(struct cam_periph *periph, union ccb *ccb)
SF_RETRY_UA,
softc->device_stats);
+ cam_periph_unlock(periph);
cam_periph_unmapmem(ccb, &mapinfo);
+ cam_periph_lock(periph);
return (error);
}