summaryrefslogtreecommitdiffstats
path: root/freebsd/sys/cam
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2016-12-09 14:19:03 +0100
committerSebastian Huber <sebastian.huber@embedded-brains.de>2017-01-10 09:53:34 +0100
commit75b706fde4cbf82bcd41a1cec319778aa0f8eb2d (patch)
treeea39a351a1f6337b5a5dd6036314693adef5ffe6 /freebsd/sys/cam
parentVMSTAT(8): Port to RTEMS (diff)
downloadrtems-libbsd-75b706fde4cbf82bcd41a1cec319778aa0f8eb2d.tar.bz2
Update to FreeBSD head 2016-12-10
Git mirror commit 80c55f08a05ab3b26a73b226ccb56adc3122a55c.
Diffstat (limited to 'freebsd/sys/cam')
-rw-r--r--freebsd/sys/cam/cam.h2
-rw-r--r--freebsd/sys/cam/cam_ccb.h6
-rw-r--r--freebsd/sys/cam/cam_periph.h1
-rw-r--r--freebsd/sys/cam/scsi/scsi_all.c123
-rw-r--r--freebsd/sys/cam/scsi/scsi_all.h48
5 files changed, 173 insertions, 7 deletions
diff --git a/freebsd/sys/cam/cam.h b/freebsd/sys/cam/cam.h
index 5eb0a776..23feb508 100644
--- a/freebsd/sys/cam/cam.h
+++ b/freebsd/sys/cam/cam.h
@@ -294,7 +294,7 @@ typedef enum {
/* SIM ready to take more commands */
CAM_RELEASE_SIMQ = 0x100,
- /* SIM has this command in it's queue */
+ /* SIM has this command in its queue */
CAM_SIM_QUEUED = 0x200,
/* Quality of service data is valid */
diff --git a/freebsd/sys/cam/cam_ccb.h b/freebsd/sys/cam/cam_ccb.h
index e00b5bd3..d9b91f8d 100644
--- a/freebsd/sys/cam/cam_ccb.h
+++ b/freebsd/sys/cam/cam_ccb.h
@@ -757,6 +757,9 @@ struct ccb_scsiio {
#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 */
+#if defined(BUF_TRACKING) || defined(FULL_BUF_TRACKING)
+ struct bio *bio; /* Associated bio */
+#endif
#ifdef __rtems__
int readop;
rtems_blkdev_sg_buffer *sg_current;
@@ -1358,6 +1361,9 @@ cam_fill_csio(struct ccb_scsiio *csio, u_int32_t retries,
csio->sense_len = sense_len;
csio->cdb_len = cdb_len;
csio->tag_action = tag_action;
+#if defined(BUF_TRACKING) || defined(FULL_BUF_TRACKING)
+ csio->bio = NULL;
+#endif
}
static __inline void
diff --git a/freebsd/sys/cam/cam_periph.h b/freebsd/sys/cam/cam_periph.h
index e28d5b11..d5a74a51 100644
--- a/freebsd/sys/cam/cam_periph.h
+++ b/freebsd/sys/cam/cam_periph.h
@@ -166,7 +166,6 @@ void cam_periph_unmapmem(union ccb *ccb,
struct cam_periph_map_info *mapinfo);
union ccb *cam_periph_getccb(struct cam_periph *periph,
u_int32_t priority);
-void cam_periph_ccbwait(union ccb *ccb);
int cam_periph_runccb(union ccb *ccb,
int (*error_routine)(union ccb *ccb,
cam_flags camflags,
diff --git a/freebsd/sys/cam/scsi/scsi_all.c b/freebsd/sys/cam/scsi/scsi_all.c
index 0cb7118a..9e8924c5 100644
--- a/freebsd/sys/cam/scsi/scsi_all.c
+++ b/freebsd/sys/cam/scsi/scsi_all.c
@@ -1063,7 +1063,7 @@ static struct asc_table_entry asc_table[] = {
{ SST(0x00, 0x1C, SS_RDEF, /* XXX TBD */
"Verify operation in progress") },
/* DT B */
- { SST(0x00, 0x1D, SS_RDEF, /* XXX TBD */
+ { SST(0x00, 0x1D, SS_NOP,
"ATA pass through information available") },
/* DT R MAEBKV */
{ SST(0x00, 0x1E, SS_RDEF, /* XXX TBD */
@@ -1072,7 +1072,7 @@ static struct asc_table_entry asc_table[] = {
{ SST(0x00, 0x1F, SS_RDEF, /* XXX TBD */
"Logical unit transitioning to another power condition") },
/* DT P B */
- { SST(0x00, 0x20, SS_RDEF, /* XXX TBD */
+ { SST(0x00, 0x20, SS_NOP,
"Extended copy information available") },
/* D */
{ SST(0x00, 0x21, SS_RDEF, /* XXX TBD */
@@ -2338,7 +2338,7 @@ static struct asc_table_entry asc_table[] = {
{ SST(0x43, 0x00, SS_RDEF,
"Message error") },
/* DTLPWROMAEBKVF */
- { SST(0x44, 0x00, SS_RDEF,
+ { SST(0x44, 0x00, SS_FATAL | EIO,
"Internal target failure") },
/* DT P MAEBKVF */
{ SST(0x44, 0x01, SS_RDEF, /* XXX TBD */
@@ -3199,10 +3199,10 @@ static struct asc_table_entry asc_table[] = {
{ SST(0x74, 0x6F, SS_RDEF, /* XXX TBD */
"External data encryption control error") },
/* DT R M E V */
- { SST(0x74, 0x71, SS_RDEF, /* XXX TBD */
+ { SST(0x74, 0x71, SS_FATAL | EACCES,
"Logical unit access not authorized") },
/* D */
- { SST(0x74, 0x79, SS_RDEF, /* XXX TBD */
+ { SST(0x74, 0x79, SS_FATAL | EACCES,
"Security conflict in translated device") }
};
@@ -4661,6 +4661,53 @@ scsi_sense_progress_sbuf(struct sbuf *sb, struct scsi_sense_data *sense,
scsi_progress_sbuf(sb, progress_val);
}
+void
+scsi_sense_ata_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,
+ struct scsi_sense_desc_header *header)
+{
+ struct scsi_sense_ata_ret_desc *res;
+
+ res = (struct scsi_sense_ata_ret_desc *)header;
+
+ sbuf_printf(sb, "ATA status: %02x (%s%s%s%s%s%s%s%s), ",
+ res->status,
+ (res->status & 0x80) ? "BSY " : "",
+ (res->status & 0x40) ? "DRDY " : "",
+ (res->status & 0x20) ? "DF " : "",
+ (res->status & 0x10) ? "SERV " : "",
+ (res->status & 0x08) ? "DRQ " : "",
+ (res->status & 0x04) ? "CORR " : "",
+ (res->status & 0x02) ? "IDX " : "",
+ (res->status & 0x01) ? "ERR" : "");
+ if (res->status & 1) {
+ sbuf_printf(sb, "error: %02x (%s%s%s%s%s%s%s%s), ",
+ res->error,
+ (res->error & 0x80) ? "ICRC " : "",
+ (res->error & 0x40) ? "UNC " : "",
+ (res->error & 0x20) ? "MC " : "",
+ (res->error & 0x10) ? "IDNF " : "",
+ (res->error & 0x08) ? "MCR " : "",
+ (res->error & 0x04) ? "ABRT " : "",
+ (res->error & 0x02) ? "NM " : "",
+ (res->error & 0x01) ? "ILI" : "");
+ }
+
+ if (res->flags & SSD_DESC_ATA_FLAG_EXTEND) {
+ sbuf_printf(sb, "count: %02x%02x, ",
+ res->count_15_8, res->count_7_0);
+ sbuf_printf(sb, "LBA: %02x%02x%02x%02x%02x%02x, ",
+ res->lba_47_40, res->lba_39_32, res->lba_31_24,
+ res->lba_23_16, res->lba_15_8, res->lba_7_0);
+ } else {
+ sbuf_printf(sb, "count: %02x, ", res->count_7_0);
+ sbuf_printf(sb, "LBA: %02x%02x%02x, ",
+ res->lba_23_16, res->lba_15_8, res->lba_7_0);
+ }
+ sbuf_printf(sb, "device: %02x, ", res->device);
+}
+
/*
* Generic sense descriptor printing routine. This is used when we have
* not yet implemented a specific printing routine for this descriptor.
@@ -4707,6 +4754,7 @@ struct scsi_sense_desc_printer {
{SSD_DESC_FRU, scsi_sense_fru_sbuf},
{SSD_DESC_STREAM, scsi_sense_stream_sbuf},
{SSD_DESC_BLOCK, scsi_sense_block_sbuf},
+ {SSD_DESC_ATA, scsi_sense_ata_sbuf},
{SSD_DESC_PROGRESS, scsi_sense_progress_sbuf}
};
@@ -7914,6 +7962,32 @@ scsi_report_target_group(struct ccb_scsiio *csio, u_int32_t retries,
}
void
+scsi_report_timestamp(struct ccb_scsiio *csio, u_int32_t retries,
+ void (*cbfcnp)(struct cam_periph *, union ccb *),
+ u_int8_t tag_action, u_int8_t pdf,
+ void *buf, u_int32_t alloc_len,
+ u_int8_t sense_len, u_int32_t timeout)
+{
+ struct scsi_timestamp *scsi_cmd;
+
+ cam_fill_csio(csio,
+ retries,
+ cbfcnp,
+ /*flags*/CAM_DIR_IN,
+ tag_action,
+ /*data_ptr*/(u_int8_t *)buf,
+ /*dxfer_len*/alloc_len,
+ sense_len,
+ sizeof(*scsi_cmd),
+ timeout);
+ scsi_cmd = (struct scsi_timestamp *)&csio->cdb_io.cdb_bytes;
+ bzero(scsi_cmd, sizeof(*scsi_cmd));
+ scsi_cmd->opcode = MAINTENANCE_IN;
+ scsi_cmd->service_action = REPORT_TIMESTAMP | pdf;
+ scsi_ulto4b(alloc_len, scsi_cmd->length);
+}
+
+void
scsi_set_target_group(struct ccb_scsiio *csio, u_int32_t retries,
void (*cbfcnp)(struct cam_periph *, union ccb *),
u_int8_t tag_action, void *buf, u_int32_t alloc_len,
@@ -7938,6 +8012,45 @@ scsi_set_target_group(struct ccb_scsiio *csio, u_int32_t retries,
scsi_ulto4b(alloc_len, scsi_cmd->length);
}
+void
+scsi_create_timestamp(uint8_t *timestamp_6b_buf,
+ uint64_t timestamp)
+{
+ uint8_t buf[8];
+ scsi_u64to8b(timestamp, buf);
+ /*
+ * Using memcopy starting at buf[2] because the set timestamp parameters
+ * only has six bytes for the timestamp to fit into, and we don't have a
+ * scsi_u64to6b function.
+ */
+ memcpy(timestamp_6b_buf, &buf[2], 6);
+}
+
+void
+scsi_set_timestamp(struct ccb_scsiio *csio, u_int32_t retries,
+ void (*cbfcnp)(struct cam_periph *, union ccb *),
+ u_int8_t tag_action, void *buf, u_int32_t alloc_len,
+ u_int8_t sense_len, u_int32_t timeout)
+{
+ struct scsi_timestamp *scsi_cmd;
+
+ cam_fill_csio(csio,
+ retries,
+ cbfcnp,
+ /*flags*/CAM_DIR_OUT,
+ tag_action,
+ /*data_ptr*/(u_int8_t *) buf,
+ /*dxfer_len*/alloc_len,
+ sense_len,
+ sizeof(*scsi_cmd),
+ timeout);
+ scsi_cmd = (struct scsi_timestamp *)&csio->cdb_io.cdb_bytes;
+ bzero(scsi_cmd, sizeof(*scsi_cmd));
+ scsi_cmd->opcode = MAINTENANCE_OUT;
+ scsi_cmd->service_action = SET_TIMESTAMP;
+ scsi_ulto4b(alloc_len, scsi_cmd->length);
+}
+
/*
* Syncronize the media to the contents of the cache for
* the given lba/count pair. Specifying 0/0 means sync
diff --git a/freebsd/sys/cam/scsi/scsi_all.h b/freebsd/sys/cam/scsi/scsi_all.h
index 1fd45405..9c1376cf 100644
--- a/freebsd/sys/cam/scsi/scsi_all.h
+++ b/freebsd/sys/cam/scsi/scsi_all.h
@@ -702,7 +702,9 @@ struct scsi_control_page {
struct scsi_control_ext_page {
uint8_t page_code;
+#define SCEP_PAGE_CODE 0x0a
uint8_t subpage_code;
+#define SCEP_SUBPAGE_CODE 0x01
uint8_t page_length[2];
uint8_t flags;
#define SCEP_TCMOS 0x04 /* Timestamp Changeable by */
@@ -2971,6 +2973,31 @@ struct scsi_target_group
uint8_t control;
};
+struct scsi_timestamp
+{
+ uint8_t opcode;
+ uint8_t service_action;
+ uint8_t reserved1[4];
+ uint8_t length[4];
+ uint8_t reserved2;
+ uint8_t control;
+};
+
+struct scsi_set_timestamp_parameters
+{
+ uint8_t reserved1[4];
+ uint8_t timestamp[6];
+ uint8_t reserved2[4];
+};
+
+struct scsi_report_timestamp_parameter_data
+{
+ uint8_t length[2];
+ uint8_t reserved1[2];
+ uint8_t timestamp[6];
+ uint8_t reserved2[2];
+};
+
struct scsi_target_port_descriptor {
uint8_t reserved[2];
uint8_t relative_target_port_identifier[2];
@@ -3682,6 +3709,10 @@ void scsi_sense_progress_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,
struct scsi_sense_desc_header *header);
+void scsi_sense_ata_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,
+ struct scsi_sense_desc_header *header);
void scsi_sense_generic_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,
@@ -3962,12 +3993,29 @@ void scsi_report_target_group(struct ccb_scsiio *csio, u_int32_t retries,
u_int32_t alloc_len, u_int8_t sense_len,
u_int32_t timeout);
+void scsi_report_timestamp(struct ccb_scsiio *csio, u_int32_t retries,
+ void (*cbfcnp)(struct cam_periph *,
+ union ccb *), u_int8_t tag_action,
+ u_int8_t pdf,
+ void *buf,
+ u_int32_t alloc_len, u_int8_t sense_len,
+ u_int32_t timeout);
+
void scsi_set_target_group(struct ccb_scsiio *csio, u_int32_t retries,
void (*cbfcnp)(struct cam_periph *,
union ccb *), u_int8_t tag_action, void *buf,
u_int32_t alloc_len, u_int8_t sense_len,
u_int32_t timeout);
+void scsi_create_timestamp(uint8_t *timestamp_6b_buf,
+ uint64_t timestamp);
+
+void scsi_set_timestamp(struct ccb_scsiio *csio, u_int32_t retries,
+ void (*cbfcnp)(struct cam_periph *,
+ union ccb *), u_int8_t tag_action,
+ void *buf, u_int32_t alloc_len,
+ u_int8_t sense_len, u_int32_t timeout);
+
void scsi_synchronize_cache(struct ccb_scsiio *csio,
u_int32_t retries,
void (*cbfcnp)(struct cam_periph *,