Author: mav Date: Mon Oct 20 07:33:41 2014 New Revision: 273311 URL: https://svnweb.freebsd.org/changeset/base/273311
Log: MFC r272734: Add support for WRITE ATOMIC (16) command and report SBC-4 compliance. Atomic writes are only supported for ZVOLs in "dev" mode. In other cases atomicity can not be guarantied and so the command is blocked. Modified: stable/10/sys/cam/ctl/ctl.c stable/10/sys/cam/ctl/ctl_backend.h stable/10/sys/cam/ctl/ctl_backend_block.c stable/10/sys/cam/ctl/ctl_backend_ramdisk.c stable/10/sys/cam/ctl/ctl_cmd_table.c stable/10/sys/cam/ctl/scsi_ctl.c stable/10/sys/cam/scsi/scsi_all.h Directory Properties: stable/10/ (props changed) Modified: stable/10/sys/cam/ctl/ctl.c ============================================================================== --- stable/10/sys/cam/ctl/ctl.c Mon Oct 20 07:32:33 2014 (r273310) +++ stable/10/sys/cam/ctl/ctl.c Mon Oct 20 07:33:41 2014 (r273311) @@ -9128,6 +9128,31 @@ ctl_read_write(struct ctl_scsiio *ctsio) num_blocks = scsi_4btoul(cdb->length); break; } + case WRITE_ATOMIC_16: { + struct scsi_rw_16 *cdb; + + if (lun->be_lun->atomicblock == 0) { + ctl_set_invalid_opcode(ctsio); + ctl_done((union ctl_io *)ctsio); + return (CTL_RETVAL_COMPLETE); + } + + cdb = (struct scsi_rw_16 *)ctsio->cdb; + if (cdb->byte2 & SRW12_FUA) + flags |= CTL_LLF_FUA; + if (cdb->byte2 & SRW12_DPO) + flags |= CTL_LLF_DPO; + lba = scsi_8btou64(cdb->addr); + num_blocks = scsi_4btoul(cdb->length); + if (num_blocks > lun->be_lun->atomicblock) { + ctl_set_invalid_field(ctsio, /*sks_valid*/ 1, + /*command*/ 1, /*field*/ 12, /*bit_valid*/ 0, + /*bit*/ 0); + ctl_done((union ctl_io *)ctsio); + return (CTL_RETVAL_COMPLETE); + } + break; + } case WRITE_VERIFY_16: { struct scsi_write_verify_16 *cdb; @@ -10301,6 +10326,10 @@ ctl_inquiry_evpd_block_limits(struct ctl bl_ptr->unmap_grain_align); } } + scsi_ulto4b(lun->be_lun->atomicblock, + bl_ptr->max_atomic_transfer_length); + scsi_ulto4b(0, bl_ptr->atomic_alignment); + scsi_ulto4b(0, bl_ptr->atomic_transfer_length_granularity); } scsi_u64to8b(UINT64_MAX, bl_ptr->max_write_same_length); @@ -10696,13 +10725,13 @@ ctl_inquiry_std(struct ctl_scsiio *ctsio } if (lun == NULL) { - /* SBC-3 (no version claimed) */ - scsi_ulto2b(0x04C0, inq_ptr->version4); + /* SBC-4 (no version claimed) */ + scsi_ulto2b(0x0600, inq_ptr->version4); } else { switch (lun->be_lun->lun_type) { case T_DIRECT: - /* SBC-3 (no version claimed) */ - scsi_ulto2b(0x04C0, inq_ptr->version4); + /* SBC-4 (no version claimed) */ + scsi_ulto2b(0x0600, inq_ptr->version4); break; case T_PROCESSOR: default: @@ -10820,7 +10849,8 @@ ctl_get_lba_len(union ctl_io *io, uint64 break; } case READ_16: - case WRITE_16: { + case WRITE_16: + case WRITE_ATOMIC_16: { struct scsi_rw_16 *cdb; cdb = (struct scsi_rw_16 *)io->scsiio.cdb; @@ -10834,7 +10864,6 @@ ctl_get_lba_len(union ctl_io *io, uint64 cdb = (struct scsi_write_verify_16 *)io->scsiio.cdb; - *lba = scsi_8btou64(cdb->addr); *len = scsi_4btoul(cdb->length); break; Modified: stable/10/sys/cam/ctl/ctl_backend.h ============================================================================== --- stable/10/sys/cam/ctl/ctl_backend.h Mon Oct 20 07:32:33 2014 (r273310) +++ stable/10/sys/cam/ctl/ctl_backend.h Mon Oct 20 07:33:41 2014 (r273311) @@ -144,6 +144,8 @@ typedef void (*be_lun_config_t)(void *be * * pblockoff is the lowest LBA on the LUN aligned ot physical sector. * + * atomicblock is the number of blocks that can be written atomically. + * * req_lun_id is the requested LUN ID. CTL only pays attention to this * field if the CTL_LUN_FLAG_ID_REQ flag is set. If the requested LUN ID is * not available, the LUN addition will fail. If a particular LUN ID isn't @@ -188,6 +190,7 @@ struct ctl_be_lun { uint32_t blocksize; /* passed to CTL */ uint16_t pblockexp; /* passed to CTL */ uint16_t pblockoff; /* passed to CTL */ + uint32_t atomicblock; /* passed to CTL */ uint32_t req_lun_id; /* passed to CTL */ uint32_t lun_id; /* returned from CTL */ uint8_t serial_num[CTL_SN_LEN]; /* passed to CTL */ Modified: stable/10/sys/cam/ctl/ctl_backend_block.c ============================================================================== --- stable/10/sys/cam/ctl/ctl_backend_block.c Mon Oct 20 07:32:33 2014 (r273310) +++ stable/10/sys/cam/ctl/ctl_backend_block.c Mon Oct 20 07:33:41 2014 (r273311) @@ -2006,6 +2006,9 @@ ctl_be_block_create(struct ctl_be_block_ be_lun->ctl_be_lun.flags = CTL_LUN_FLAG_PRIMARY; if (unmap) be_lun->ctl_be_lun.flags |= CTL_LUN_FLAG_UNMAP; + if (be_lun->dispatch == ctl_be_block_dispatch_zvol) + be_lun->ctl_be_lun.atomicblock = CTLBLK_MAX_IO_SIZE / + be_lun->blocksize; be_lun->ctl_be_lun.be_lun = be_lun; be_lun->ctl_be_lun.blocksize = be_lun->blocksize; be_lun->ctl_be_lun.pblockexp = be_lun->pblockexp; Modified: stable/10/sys/cam/ctl/ctl_backend_ramdisk.c ============================================================================== --- stable/10/sys/cam/ctl/ctl_backend_ramdisk.c Mon Oct 20 07:32:33 2014 (r273310) +++ stable/10/sys/cam/ctl/ctl_backend_ramdisk.c Mon Oct 20 07:33:41 2014 (r273311) @@ -595,6 +595,7 @@ ctl_backend_ramdisk_create(struct ctl_be be_lun->ctl_be_lun.flags = CTL_LUN_FLAG_PRIMARY; if (unmap) be_lun->ctl_be_lun.flags |= CTL_LUN_FLAG_UNMAP; + be_lun->ctl_be_lun.atomicblock = UINT32_MAX; be_lun->ctl_be_lun.be_lun = be_lun; if (params->flags & CTL_LUN_FLAG_ID_REQ) { Modified: stable/10/sys/cam/ctl/ctl_cmd_table.c ============================================================================== --- stable/10/sys/cam/ctl/ctl_cmd_table.c Mon Oct 20 07:32:33 2014 (r273310) +++ stable/10/sys/cam/ctl/ctl_cmd_table.c Mon Oct 20 07:33:41 2014 (r273311) @@ -1117,8 +1117,11 @@ const struct ctl_cmd_entry ctl_cmd_table /* 9B */ {NULL, CTL_SERIDX_INVLD, CTL_CMD_FLAG_NONE, CTL_LUN_PAT_NONE}, -/* 9C */ -{NULL, CTL_SERIDX_INVLD, CTL_CMD_FLAG_NONE, CTL_LUN_PAT_NONE}, +/* 9C WRITE ATOMIC (16) */ +{ctl_read_write, CTL_SERIDX_WRITE, CTL_CMD_FLAG_OK_ON_SLUN| CTL_FLAG_DATA_OUT, + CTL_LUN_PAT_WRITE | CTL_LUN_PAT_RANGE, + 16, {0x18, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0, 0, 0xff, 0xff, 0, 0x07}}, /* 9D */ {NULL, CTL_SERIDX_INVLD, CTL_CMD_FLAG_NONE, CTL_LUN_PAT_NONE}, Modified: stable/10/sys/cam/ctl/scsi_ctl.c ============================================================================== --- stable/10/sys/cam/ctl/scsi_ctl.c Mon Oct 20 07:32:33 2014 (r273310) +++ stable/10/sys/cam/ctl/scsi_ctl.c Mon Oct 20 07:33:41 2014 (r273311) @@ -1115,6 +1115,7 @@ ctlfe_adjust_cdb(struct ccb_accept_tio * } case READ_16: case WRITE_16: + case WRITE_ATOMIC_16: { struct scsi_rw_16 *cdb = (struct scsi_rw_16 *)cmdbyt; lba = scsi_8btou64(cdb->addr); Modified: stable/10/sys/cam/scsi/scsi_all.h ============================================================================== --- stable/10/sys/cam/scsi/scsi_all.h Mon Oct 20 07:32:33 2014 (r273310) +++ stable/10/sys/cam/scsi/scsi_all.h Mon Oct 20 07:33:41 2014 (r273311) @@ -1720,6 +1720,7 @@ struct ata_pass_16 { #define VERIFY_16 0x8F #define SYNCHRONIZE_CACHE_16 0x91 #define WRITE_SAME_16 0x93 +#define WRITE_ATOMIC_16 0x9C #define SERVICE_ACTION_IN 0x9E #define REPORT_LUNS 0xA0 #define ATA_PASS_12 0xA1 @@ -2437,8 +2438,7 @@ struct scsi_vpd_logical_block_prov }; /* - * Block Limits VDP Page based on - * T10/1799-D Revision 31 + * Block Limits VDP Page based on SBC-4 Revision 2 */ struct scsi_vpd_block_limits { @@ -2459,7 +2459,10 @@ struct scsi_vpd_block_limits 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]; + u_int8_t max_atomic_transfer_length[4]; + u_int8_t atomic_alignment[4]; + u_int8_t atomic_transfer_length_granularity[4]; + u_int8_t reserved2[8]; }; struct scsi_read_capacity _______________________________________________ svn-src-all@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/svn-src-all To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"