diff options
author | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2016-12-09 14:19:03 +0100 |
---|---|---|
committer | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2017-01-10 09:53:34 +0100 |
commit | 75b706fde4cbf82bcd41a1cec319778aa0f8eb2d (patch) | |
tree | ea39a351a1f6337b5a5dd6036314693adef5ffe6 /freebsd/sys/cam | |
parent | VMSTAT(8): Port to RTEMS (diff) | |
download | rtems-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.h | 2 | ||||
-rw-r--r-- | freebsd/sys/cam/cam_ccb.h | 6 | ||||
-rw-r--r-- | freebsd/sys/cam/cam_periph.h | 1 | ||||
-rw-r--r-- | freebsd/sys/cam/scsi/scsi_all.c | 123 | ||||
-rw-r--r-- | freebsd/sys/cam/scsi/scsi_all.h | 48 |
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 *, |