summaryrefslogtreecommitdiffstats
path: root/sys/cam
diff options
context:
space:
mode:
authorsmh <smh@FreeBSD.org>2013-04-26 15:53:22 +0000
committersmh <smh@FreeBSD.org>2013-04-26 15:53:22 +0000
commit7cdb7369d5f2bb9b05dcb29e6e5d251fb3f8ed41 (patch)
treeb36e26c86e9796903f087e62b744e690b1a6e5d7 /sys/cam
parentf3c66bac10d050369bb01a14e0a4f1a61e9e2791 (diff)
downloadFreeBSD-src-7cdb7369d5f2bb9b05dcb29e6e5d251fb3f8ed41.zip
FreeBSD-src-7cdb7369d5f2bb9b05dcb29e6e5d251fb3f8ed41.tar.gz
Added the ability to send ATA identify and Data Set Management (DSM) TRIM
commands to an ATA device attached via a SCSI control. sys/cam/scsi/scsi_all.c: - Added scsi_ata_identify, scsi_ata_trim Which use ATA Pass-Through to send commands to the attached disk. sys/cam/scsi/scsi_all.h: - Added defines for all missing ATA Pass-Through commands values. - Added scsi_ata_identify, scsi_ata_trim methods used in ATA TRIM support. - Added scsi_vpd_logical_block_prov structure used when querying for the supported sizes UNMAP commands. - Added scsi_vpd_block_limits structure used when querying for the supported sizes of the UNMAP command. Reviewed by: mav Approved by: pjd (mentor) MFC after: 2 weeks
Diffstat (limited to 'sys/cam')
-rw-r--r--sys/cam/scsi/scsi_all.c51
-rw-r--r--sys/cam/scsi/scsi_all.h67
2 files changed, 118 insertions, 0 deletions
diff --git a/sys/cam/scsi/scsi_all.c b/sys/cam/scsi/scsi_all.c
index b28c29d..e206edf 100644
--- a/sys/cam/scsi/scsi_all.c
+++ b/sys/cam/scsi/scsi_all.c
@@ -5853,6 +5853,57 @@ scsi_write_same(struct ccb_scsiio *csio, u_int32_t retries,
}
void
+scsi_ata_identify(struct ccb_scsiio *csio, u_int32_t retries,
+ void (*cbfcnp)(struct cam_periph *, union ccb *),
+ u_int8_t tag_action, u_int8_t *data_ptr,
+ u_int16_t dxfer_len, u_int8_t sense_len,
+ u_int32_t timeout)
+{
+ scsi_ata_pass_16(csio,
+ retries,
+ cbfcnp,
+ /*flags*/CAM_DIR_IN,
+ tag_action,
+ /*protocol*/AP_PROTO_PIO_IN,
+ /*ata_flags*/AP_FLAG_TDIR_FROM_DEV|
+ AP_FLAG_BYT_BLOK_BYTES|AP_FLAG_TLEN_SECT_CNT,
+ /*features*/0,
+ /*sector_count*/dxfer_len,
+ /*lba*/0,
+ /*command*/ATA_ATA_IDENTIFY,
+ /*control*/0,
+ data_ptr,
+ dxfer_len,
+ sense_len,
+ timeout);
+}
+
+void
+scsi_ata_trim(struct ccb_scsiio *csio, u_int32_t retries,
+ void (*cbfcnp)(struct cam_periph *, union ccb *),
+ u_int8_t tag_action, u_int16_t block_count,
+ u_int8_t *data_ptr, u_int16_t dxfer_len, u_int8_t sense_len,
+ u_int32_t timeout)
+{
+ scsi_ata_pass_16(csio,
+ retries,
+ cbfcnp,
+ /*flags*/CAM_DIR_OUT,
+ tag_action,
+ /*protocol*/AP_EXTEND|AP_PROTO_DMA,
+ /*ata_flags*/AP_FLAG_TLEN_SECT_CNT|AP_FLAG_BYT_BLOK_BLOCKS,
+ /*features*/ATA_DSM_TRIM,
+ /*sector_count*/block_count,
+ /*lba*/0,
+ /*command*/ATA_DATA_SET_MANAGEMENT,
+ /*control*/0,
+ data_ptr,
+ dxfer_len,
+ sense_len,
+ timeout);
+}
+
+void
scsi_ata_pass_16(struct ccb_scsiio *csio, u_int32_t retries,
void (*cbfcnp)(struct cam_periph *, union ccb *),
u_int32_t flags, u_int8_t tag_action,
diff --git a/sys/cam/scsi/scsi_all.h b/sys/cam/scsi/scsi_all.h
index 0b108ca..d2872a0 100644
--- a/sys/cam/scsi/scsi_all.h
+++ b/sys/cam/scsi/scsi_all.h
@@ -1429,6 +1429,61 @@ struct scsi_diag_page {
uint8_t params[0];
};
+/*
+ * Logical Block Provisioning VPD Page based on
+ * T10/1799-D Revision 31
+ */
+struct scsi_vpd_logical_block_prov
+{
+ u_int8_t device;
+ u_int8_t page_code;
+#define SVPD_LBP 0xB2
+ u_int8_t page_length[2];
+#define SVPD_LBP_PL_BASIC 0x04
+ u_int8_t threshold_exponent;
+ u_int8_t flags;
+#define SVPD_LBP_UNMAP 0x80
+#define SVPD_LBP_WS16 0x40
+#define SVPD_LBP_WS10 0x20
+#define SVPD_LBP_RZ 0x04
+#define SVPD_LBP_ANC_SUP 0x02
+#define SVPD_LBP_DP 0x01
+ u_int8_t prov_type;
+#define SVPD_LBP_RESOURCE 0x01
+#define SVPD_LBP_THIN 0x02
+ u_int8_t reserved;
+ /*
+ * Provisioning Group Descriptor can be here if SVPD_LBP_DP is set
+ * Its size can be determined from page_length - 4
+ */
+};
+
+/*
+ * Block Limits VDP Page based on
+ * T10/1799-D Revision 31
+ */
+struct scsi_vpd_block_limits
+{
+ u_int8_t device;
+ u_int8_t page_code;
+#define SVPD_BLOCK_LIMITS 0xB0
+ u_int8_t page_length[2];
+#define SVPD_BL_PL_BASIC 0x10
+#define SVPD_BL_PL_TP 0x3C
+ u_int8_t reserved1;
+ u_int8_t max_cmp_write_len;
+ u_int8_t opt_txfer_len_grain[2];
+ u_int8_t max_txfer_len[4];
+ u_int8_t opt_txfer_len[4];
+ u_int8_t max_prefetch[4];
+ u_int8_t max_unmap_lba_cnt[4];
+ u_int8_t max_unmap_blk_cnt[4];
+ u_int8_t opt_unmap_grain[4];
+ u_int8_t unmap_grain_align[4];
+ u_int8_t max_write_same_length[8];
+ u_int8_t reserved2[20];
+};
+
struct scsi_read_capacity
{
u_int8_t opcode;
@@ -2396,6 +2451,18 @@ void scsi_write_same(struct ccb_scsiio *csio, u_int32_t retries,
u_int32_t dxfer_len, u_int8_t sense_len,
u_int32_t timeout);
+void scsi_ata_identify(struct ccb_scsiio *csio, u_int32_t retries,
+ void (*cbfcnp)(struct cam_periph *, union ccb *),
+ u_int8_t tag_action, u_int8_t *data_ptr,
+ u_int16_t dxfer_len, u_int8_t sense_len,
+ u_int32_t timeout);
+
+void scsi_ata_trim(struct ccb_scsiio *csio, u_int32_t retries,
+ void (*cbfcnp)(struct cam_periph *, union ccb *),
+ u_int8_t tag_action, u_int16_t block_count,
+ u_int8_t *data_ptr, u_int16_t dxfer_len,
+ u_int8_t sense_len, u_int32_t timeout);
+
void scsi_ata_pass_16(struct ccb_scsiio *csio, u_int32_t retries,
void (*cbfcnp)(struct cam_periph *, union ccb *),
u_int32_t flags, u_int8_t tag_action,
OpenPOWER on IntegriCloud