diff options
author | smh <smh@FreeBSD.org> | 2013-04-26 15:53:22 +0000 |
---|---|---|
committer | smh <smh@FreeBSD.org> | 2013-04-26 15:53:22 +0000 |
commit | 7cdb7369d5f2bb9b05dcb29e6e5d251fb3f8ed41 (patch) | |
tree | b36e26c86e9796903f087e62b744e690b1a6e5d7 /sys/cam | |
parent | f3c66bac10d050369bb01a14e0a4f1a61e9e2791 (diff) | |
download | FreeBSD-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.c | 51 | ||||
-rw-r--r-- | sys/cam/scsi/scsi_all.h | 67 |
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, |