diff options
author | mcneal <none@none> | 2006-09-06 11:48:01 -0700 |
---|---|---|
committer | mcneal <none@none> | 2006-09-06 11:48:01 -0700 |
commit | 8a16ae8f6efb5a6c02ab0aec860e229706335bb9 (patch) | |
tree | 257b3a9c1e0de2468606f25fc9e3aa1976b7fcec /usr/src | |
parent | 433eca90d1a0238667eea28ab4fda24793afcdc6 (diff) | |
download | illumos-joyent-8a16ae8f6efb5a6c02ab0aec860e229706335bb9.tar.gz |
6456456 target doesn't handle SCSI commands to invalid LU correctly.
6456465 Need to support optional SCSI command VERIFY for Microsoft
Diffstat (limited to 'usr/src')
-rw-r--r-- | usr/src/cmd/iscsi/iscsitgtd/iscsi_sess.c | 10 | ||||
-rw-r--r-- | usr/src/cmd/iscsi/iscsitgtd/t10_sam.c | 44 | ||||
-rw-r--r-- | usr/src/cmd/iscsi/iscsitgtd/t10_sbc.c | 256 | ||||
-rw-r--r-- | usr/src/cmd/iscsi/iscsitgtd/t10_sbc.h | 11 | ||||
-rw-r--r-- | usr/src/cmd/iscsi/iscsitgtd/t10_spc.h | 8 | ||||
-rw-r--r-- | usr/src/uts/common/sys/scsi/generic/commands.h | 3 | ||||
-rw-r--r-- | usr/src/uts/common/sys/scsi/impl/commands.h | 5 |
7 files changed, 302 insertions, 35 deletions
diff --git a/usr/src/cmd/iscsi/iscsitgtd/iscsi_sess.c b/usr/src/cmd/iscsi/iscsitgtd/iscsi_sess.c index a2d119886a..f18c872074 100644 --- a/usr/src/cmd/iscsi/iscsitgtd/iscsi_sess.c +++ b/usr/src/cmd/iscsi/iscsitgtd/iscsi_sess.c @@ -327,8 +327,6 @@ sess_process(void *v) cmd->c_scb_len, (transport_t)cmd, &t10_cmd) == False) { - queue_prt(s->s_mgmtq, Q_SESS_ERRS, - "SES%x FAILED to create cmd", s->s_num); /* * If the command create failed, the T10 layer * will attempt to create a sense buffer @@ -337,12 +335,16 @@ sess_process(void *v) * things are really bad and we need to just * close the connection. */ - if (cmd->c_t10_cmd != NULL) { + if (t10_cmd != NULL) { queue_message_set( cmd->c_allegiance->c_dataq, 0, msg_cmd_cmplt, t10_cmd); - } else + } else { + queue_prt(s->s_mgmtq, Q_SESS_ERRS, + "SES%x FAILED to create cmd", + s->s_num); conn_state(cmd->c_allegiance, T11); + } } else { (void) pthread_mutex_lock( &cmd->c_allegiance->c_mutex); diff --git a/usr/src/cmd/iscsi/iscsitgtd/t10_sam.c b/usr/src/cmd/iscsi/iscsitgtd/t10_sam.c index 24f2f52f2c..2f07b921d5 100644 --- a/usr/src/cmd/iscsi/iscsitgtd/t10_sam.c +++ b/usr/src/cmd/iscsi/iscsitgtd/t10_sam.c @@ -71,7 +71,7 @@ /* * Forward declarations */ -static t10_lu_impl_t *t10_find_lun(t10_targ_impl_t *t, int lun); +static Boolean_t t10_find_lun(t10_targ_impl_t *t, int lun, t10_cmd_t *); static void *lu_runner(void *v); static Boolean_t t10_lu_initialize(t10_lu_common_t *lu, char *basedir); static void *t10_aio_done(void *v); @@ -353,11 +353,8 @@ t10_cmd_create(t10_targ_handle_t t, int lun_number, uint8_t *cdb, cmd->c_trans_id = trans_id; *cmdp = cmd; - if ((cmd->c_lu = t10_find_lun((t10_targ_impl_t *)t, lun_number)) == - NULL) { - spc_sense_create(cmd, KEY_HARDWARE_ERROR, 0); + if (t10_find_lun((t10_targ_impl_t *)t, lun_number, cmd) == False) goto error; - } (void) pthread_mutex_lock(&cmd->c_lu->l_cmd_mutex); avl_add(&cmd->c_lu->l_cmds, (void *)cmd); @@ -1095,8 +1092,8 @@ trans_params_area(t10_cmd_t *cmd) * []---- */ /*ARGSUSED*/ -static t10_lu_impl_t * -t10_find_lun(t10_targ_impl_t *t, int lun) +static Boolean_t +t10_find_lun(t10_targ_impl_t *t, int lun, t10_cmd_t *cmd) { t10_lu_impl_t *l = NULL, search; @@ -1128,14 +1125,17 @@ t10_find_lun(t10_targ_impl_t *t, int lun) * and there's fewer than 64 an array of pointers would be * even faster than an AVL tree and not take up to much space. */ - return (l); + cmd->c_lu = l; + return (True); } /* * First access for this I_T_L so we need to allocate space for it. */ - if ((l = calloc(1, sizeof (*l))) == NULL) - return (NULL); + if ((l = calloc(1, sizeof (*l))) == NULL) { + spc_sense_create(cmd, KEY_HARDWARE_ERROR, 0); + return (False); + } /* * Initialize the various local fields. Certain fields will not be @@ -1163,6 +1163,9 @@ t10_find_lun(t10_targ_impl_t *t, int lun) (void) pthread_mutex_lock(&lu_list_mutex); if ((xml_fd = open(path, O_RDONLY)) < 0) { (void) pthread_mutex_unlock(&lu_list_mutex); + spc_sense_create(cmd, KEY_ILLEGAL_REQUEST, 0); + /* ---- ACCESS DENIED - INVALID LU IDENTIFIER ---- */ + spc_sense_ascq(cmd, 0x20, 0x9); goto error; } if ((r = (xmlTextReaderPtr)xmlReaderForFd(xml_fd, NULL, NULL, @@ -1172,16 +1175,25 @@ t10_find_lun(t10_targ_impl_t *t, int lun) break; } else { (void) pthread_mutex_unlock(&lu_list_mutex); + spc_sense_create(cmd, KEY_HARDWARE_ERROR, 0); goto error; } (void) close(xml_fd); + /* + * Set xml_fd back to -1 so that if an error occurs later we don't + * attempt to close a file descriptor that another thread might have + * opened. + */ + xml_fd = -1; + xmlTextReaderClose(r); xmlFreeTextReader(r); r = NULL; if (xml_find_value_str(n, XML_ELEMENT_GUID, &guid) == False) { (void) pthread_mutex_unlock(&lu_list_mutex); + spc_sense_create(cmd, KEY_HARDWARE_ERROR, 0); goto error; } @@ -1189,24 +1201,29 @@ t10_find_lun(t10_targ_impl_t *t, int lun) free(guid); if (util_create_guid(&guid) == False) { (void) pthread_mutex_unlock(&lu_list_mutex); + spc_sense_create(cmd, KEY_HARDWARE_ERROR, 0); goto error; } if ((n1 = xml_find_child(n, XML_ELEMENT_GUID)) == NULL) { (void) pthread_mutex_unlock(&lu_list_mutex); + spc_sense_create(cmd, KEY_HARDWARE_ERROR, 0); goto error; } if (xml_update_value_str(n1, XML_ELEMENT_GUID, guid) == False) { (void) pthread_mutex_unlock(&lu_list_mutex); + spc_sense_create(cmd, KEY_HARDWARE_ERROR, 0); goto error; } if (xml_dump2file(n, path) == False) { (void) pthread_mutex_unlock(&lu_list_mutex); + spc_sense_create(cmd, KEY_HARDWARE_ERROR, 0); goto error; } } if (xml_decode_bytes(guid, &lc.l_guid, &lc.l_guid_len) == False) { (void) pthread_mutex_unlock(&lu_list_mutex); + spc_sense_create(cmd, KEY_HARDWARE_ERROR, 0); goto error; } @@ -1222,6 +1239,7 @@ t10_find_lun(t10_targ_impl_t *t, int lun) */ if ((common = calloc(1, sizeof (*common))) == NULL) { (void) pthread_mutex_unlock(&lu_list_mutex); + spc_sense_create(cmd, KEY_HARDWARE_ERROR, 0); goto error; } @@ -1242,6 +1260,7 @@ t10_find_lun(t10_targ_impl_t *t, int lun) "SAM%x FAILED to initialize LU %d", t->s_targ_num, lun); (void) pthread_mutex_unlock(&lu_list_mutex); + spc_sense_create(cmd, KEY_HARDWARE_ERROR, 0); goto error; } @@ -1300,7 +1319,8 @@ t10_find_lun(t10_targ_impl_t *t, int lun) free(guid); xml_tree_free(n); - return (l); + cmd->c_lu = l; + return (True); error: if (guid) @@ -1319,7 +1339,7 @@ error: free(lc.l_guid); if (common) free(common); - return (NULL); + return (False); } static Boolean_t diff --git a/usr/src/cmd/iscsi/iscsitgtd/t10_sbc.c b/usr/src/cmd/iscsi/iscsitgtd/t10_sbc.c index 5fc39376d1..14c5d1dc5d 100644 --- a/usr/src/cmd/iscsi/iscsitgtd/t10_sbc.c +++ b/usr/src/cmd/iscsi/iscsitgtd/t10_sbc.c @@ -163,7 +163,6 @@ sbc_init_per(t10_lu_impl_t *itl) itl->l_cmd = spc_cmd_offline; itl->l_data = sbc_data; itl->l_cmd_table = lba_table; - } void @@ -301,8 +300,10 @@ sbc_read(t10_cmd_t *cmd, uint8_t *cdb, size_t cdb_len) disk_params_t *d; uchar_t addl_sense_len; - if ((d = (disk_params_t *)T10_PARAMS_AREA(cmd)) == NULL) + if ((d = (disk_params_t *)T10_PARAMS_AREA(cmd)) == NULL) { + trans_send_complete(cmd, STATUS_BUSY); return; + } switch (u->scc_cmd) { case SCMD_READ: @@ -377,11 +378,6 @@ sbc_read(t10_cmd_t *cmd, uint8_t *cdb, size_t cdb_len) else err_blkno = d->d_size; - /* - * XXX: What's SBC-2 say about ASC/ASCQ here. Solaris - * doesn't care about these values when key is set - * to KEY_ILLEGAL_REQUEST. - */ if (err_blkno > FIXED_SENSE_ADDL_INFO_LEN) addl_sense_len = INFORMATION_SENSE_DESCR; else @@ -389,7 +385,7 @@ sbc_read(t10_cmd_t *cmd, uint8_t *cdb, size_t cdb_len) spc_sense_create(cmd, KEY_ILLEGAL_REQUEST, addl_sense_len); spc_sense_info(cmd, err_blkno); - spc_sense_ascq(cmd, 0x21, 0x00); + spc_sense_ascq(cmd, SPC_ASC_BLOCK_RANGE, SPC_ASCQ_BLOCK_RANGE); trans_send_complete(cmd, STATUS_CHECK); queue_prt(mgmtq, Q_STE_ERRS, @@ -503,8 +499,10 @@ sbc_write(t10_cmd_t *cmd, uint8_t *cdb, size_t cdb_len) size_t max_out; void *mmap_area; - if ((d = (disk_params_t *)T10_PARAMS_AREA(cmd)) == NULL) + if ((d = (disk_params_t *)T10_PARAMS_AREA(cmd)) == NULL) { + trans_send_complete(cmd, STATUS_BUSY); return; + } /*LINTED*/ u = (union scsi_cdb *)cdb; @@ -580,11 +578,6 @@ sbc_write(t10_cmd_t *cmd, uint8_t *cdb, size_t cdb_len) else err_blkno = d->d_size; - /* - * XXX: What's SBC-2 say about ASC/ASCQ here. Solaris - * doesn't care about these values when key is set - * to KEY_ILLEGAL_REQUEST. - */ if (err_blkno > FIXED_SENSE_ADDL_INFO_LEN) addl_sense_len = INFORMATION_SENSE_DESCR; else @@ -592,7 +585,7 @@ sbc_write(t10_cmd_t *cmd, uint8_t *cdb, size_t cdb_len) spc_sense_create(cmd, KEY_ILLEGAL_REQUEST, addl_sense_len); spc_sense_info(cmd, err_blkno); - spc_sense_ascq(cmd, 0x21, 0x00); + spc_sense_ascq(cmd, SPC_ASC_BLOCK_RANGE, SPC_ASCQ_BLOCK_RANGE); trans_send_complete(cmd, STATUS_CHECK); queue_prt(mgmtq, Q_STE_ERRS, @@ -1288,6 +1281,233 @@ sbc_release(t10_cmd_t *cmd, uint8_t *cdb, size_t cdb_len) trans_send_complete(cmd, STATUS_GOOD); } +/*ARGSUSED*/ +static void +sbc_verify(t10_cmd_t *cmd, uint8_t *cdb, size_t cdb_len) +{ + /*LINTED*/ + union scsi_cdb *u = (union scsi_cdb *)cdb; + diskaddr_t addr; + uint32_t cnt, + chk_size; + uint64_t sz, + err_blkno; + Boolean_t bytchk; + char *chk_block; + disk_io_t *io; + disk_params_t *d; + uchar_t addl_sense_len; + + if ((d = (disk_params_t *)T10_PARAMS_AREA(cmd)) == NULL) { + trans_send_complete(cmd, STATUS_BUSY); + return; + } + + /* + * Check the common reserved bits here and check the CONTROL byte + * in each specific section for the different CDB sizes. + * NOTE: If the VRPROTECT is non-zero we're required by SBC-3 + * to return an error since our emulation code doesn't have + * any protection information stored on the media that we can + * access. + */ + if ((cdb[1] & ~(SBC_VRPROTECT_MASK|SBC_DPO|SBC_BYTCHK)) || + (cdb[1] & SBC_VRPROTECT_MASK)) { + spc_sense_create(cmd, KEY_ILLEGAL_REQUEST, 0); + spc_sense_ascq(cmd, SPC_ASC_INVALID_CDB, 0x00); + trans_send_complete(cmd, STATUS_CHECK); + return; + } + + bytchk = cdb[1] & SBC_BYTCHK ? True : False; + + switch (u->scc_cmd) { + case SCMD_VERIFY: + /* + * BYTE 6 of the VERIFY(10) contains bits: + * 0-4: Group number -- not supported must be zero + * 5-6: Reserved + * 7 : Restricted for MMC-4 + */ + if (cdb[6] || SAM_CONTROL_BYTE_RESERVED(cdb[9])) { + spc_sense_create(cmd, KEY_ILLEGAL_REQUEST, 0); + spc_sense_ascq(cmd, SPC_ASC_INVALID_CDB, 0x00); + trans_send_complete(cmd, STATUS_CHECK); + return; + } + addr = (diskaddr_t)(uint32_t)GETG1ADDR(u); + cnt = GETG1COUNT(u); + break; + + case SCMD_VERIFY_G4: + /* + * See VERIFY(10) above for definitions of what byte 14 + * contains. + */ + if (cdb[14] || SAM_CONTROL_BYTE_RESERVED(cdb[15])) { + spc_sense_create(cmd, KEY_ILLEGAL_REQUEST, 0); + spc_sense_ascq(cmd, SPC_ASC_INVALID_CDB, 0x00); + trans_send_complete(cmd, STATUS_CHECK); + return; + } + addr = GETG4LONGADDR(u); + cnt = GETG4COUNT(u); + break; + + case SCMD_VERIFY_G5: + /* + * See VERIFY(10) above for definitions of what byte 10 + * contains. + */ + if (cdb[10] || SAM_CONTROL_BYTE_RESERVED(cdb[11])) { + spc_sense_create(cmd, KEY_ILLEGAL_REQUEST, 0); + spc_sense_ascq(cmd, SPC_ASC_INVALID_CDB, 0x00); + trans_send_complete(cmd, STATUS_CHECK); + return; + } + addr = (diskaddr_t)GETG5ADDR(u); + cnt = GETG5COUNT(u); + break; + + default: + spc_sense_create(cmd, KEY_ILLEGAL_REQUEST, 0); + spc_sense_ascq(cmd, SPC_ASC_INVALID_CDB, 0x00); + trans_send_complete(cmd, STATUS_CHECK); + return; + } + + if ((addr + cnt) > d->d_size) { + + if (addr > d->d_size) + err_blkno = addr; + else + err_blkno = d->d_size; + + if (err_blkno > FIXED_SENSE_ADDL_INFO_LEN) + addl_sense_len = INFORMATION_SENSE_DESCR; + else + addl_sense_len = 0; + + spc_sense_create(cmd, KEY_ILLEGAL_REQUEST, addl_sense_len); + spc_sense_info(cmd, err_blkno); + spc_sense_ascq(cmd, SPC_ASC_BLOCK_RANGE, SPC_ASCQ_BLOCK_RANGE); + trans_send_complete(cmd, STATUS_CHECK); + + queue_prt(mgmtq, Q_STE_ERRS, + "SBC%x LUN%d WRITE Illegal sector " + "(0x%llx + 0x%x) > 0x%ullx", cmd->c_lu->l_targ->s_targ_num, + cmd->c_lu->l_common->l_num, addr, cnt, d->d_size); + return; + } + + if (bytchk == False) { + /* + * With Byte Check being false all we need to do + * is make sure that we can read the data off of the + * media. + */ + chk_size = 1024 * 1024; + if ((chk_block = malloc(chk_size)) == NULL) { + trans_send_complete(cmd, STATUS_BUSY); + return; + } + while (cnt) { + sz = MIN(chk_size, cnt * 512); + /* + * Even if the device is mmap'd in use pread. This + * way we know directly if a read of the data has + * failed. + */ + if (pread(cmd->c_lu->l_common->l_fd, chk_block, sz, + addr * 512LL) != sz) { + spc_sense_create(cmd, KEY_MEDIUM_ERROR, 0); + spc_sense_ascq(cmd, SPC_ASC_DATA_PATH, + SPC_ASCQ_DATA_PATH); + trans_send_complete(cmd, STATUS_CHECK); + free(chk_block); + return; + } + addr += sz / 512LL; + cnt -= sz / 512; + } + free(chk_block); + trans_send_complete(cmd, STATUS_GOOD); + } else { + + io = cmd->c_emul_id; + if (io == NULL) { + io = sbc_io_alloc(cmd); + io->da_lba = addr; + io->da_lba_cnt = cnt; + io->da_clear_overlap = False; + io->da_aio.a_aio_cmplt = sbc_write_cmplt; + io->da_aio.a_id = io; + } + + sz = cmd->c_lu->l_targ->s_maxout; + io->da_data_alloc = True; + io->da_data_len = sz ? MIN(sz, (cnt * 512) - io->da_offset) : + (cnt * 512); + + /* + * Since we're going to just check the data we don't wish + * to possibly change the on disk data. Therefore, even if + * the backing store is mmap'd in we allocate space for the + * data out buffer. + */ + if ((io->da_data = malloc(io->da_data_len)) == NULL) { + trans_send_complete(cmd, STATUS_BUSY); + return; + } + + if (trans_rqst_dataout(cmd, io->da_data, io->da_data_len, + io->da_offset, io) == False) + trans_send_complete(cmd, STATUS_BUSY); + } +} + +/*ARGSUSED*/ +static void +sbc_verify_data(t10_cmd_t *cmd, emul_handle_t id, size_t offset, char *data, + size_t data_len) +{ + disk_io_t *io = (disk_io_t *)id; + char *on_disk_buf; + + if ((on_disk_buf = malloc(io->da_data_len)) == NULL) { + sbc_io_free(io); + trans_send_complete(cmd, STATUS_BUSY); + } + + if (pread(cmd->c_lu->l_common->l_fd, on_disk_buf, io->da_data_len, + io->da_offset + (io->da_lba * 512LL)) != io->da_data_len) { + spc_sense_create(cmd, KEY_MISCOMPARE, 0); + spc_sense_ascq(cmd, SPC_ASC_DATA_PATH, SPC_ASCQ_DATA_PATH); + trans_send_complete(cmd, STATUS_CHECK); + sbc_io_free(io); + return; + } + if (bcmp(on_disk_buf, io->da_data, io->da_data_len) != 0) { + spc_sense_create(cmd, KEY_MISCOMPARE, 0); + spc_sense_ascq(cmd, SPC_ASC_MISCOMPARE, SPC_ASCQ_MISCOMPARE); + trans_send_complete(cmd, STATUS_CHECK); + sbc_io_free(io); + return; + } + free(on_disk_buf); + io->da_offset += io->da_data_len; + if (io->da_offset < (io->da_lba_cnt * 512)) { + if (io->da_data_alloc == True) { + io->da_data_alloc = False; + free(io->da_data); + } + sbc_verify(cmd, cmd->c_cdb, cmd->c_cdb_len); + return; + } + sbc_io_free(io); + trans_send_complete(cmd, STATUS_GOOD); +} + /* * []------------------------------------------------------------------[] * | Support related functions for SBC-2 | @@ -1620,7 +1840,7 @@ static scsi_cmd_table_t lba_table[] = { { spc_unsupported, NULL, NULL, NULL }, { spc_unsupported, NULL, NULL, NULL }, { spc_unsupported, NULL, NULL, NULL }, - { spc_unsupported, NULL, NULL, NULL }, + { sbc_verify, sbc_verify_data, NULL, "VERIFY_G1" }, /* 0x30 -- 0x3f */ { spc_unsupported, NULL, NULL, NULL }, @@ -1728,7 +1948,7 @@ static scsi_cmd_table_t lba_table[] = { { spc_unsupported, NULL, NULL, NULL }, { spc_unsupported, NULL, NULL, NULL }, { spc_unsupported, NULL, NULL, NULL }, - { spc_unsupported, NULL, NULL, NULL }, + { sbc_verify, sbc_verify_data, NULL, "VERIFY_G4" }, /* 0x90 -- 0x9f */ { spc_unsupported, NULL, NULL, NULL }, @@ -1764,7 +1984,7 @@ static scsi_cmd_table_t lba_table[] = { { spc_unsupported, NULL, NULL, NULL }, { spc_unsupported, NULL, NULL, NULL }, { spc_unsupported, NULL, NULL, NULL }, - { spc_unsupported, NULL, NULL, NULL }, + { sbc_verify, sbc_verify_data, NULL, "VERIFY_G5" }, /* 0xb0 -- 0xbf */ { spc_unsupported, NULL, NULL, NULL }, diff --git a/usr/src/cmd/iscsi/iscsitgtd/t10_sbc.h b/usr/src/cmd/iscsi/iscsitgtd/t10_sbc.h index af1404d3c4..4e79c88f29 100644 --- a/usr/src/cmd/iscsi/iscsitgtd/t10_sbc.h +++ b/usr/src/cmd/iscsi/iscsitgtd/t10_sbc.h @@ -43,6 +43,17 @@ extern "C" { #define SBC_SYNC_CACHE_NV 0x04 /* + * SBC-2 revision 16, section 5.20 - VERIFY command. + * Bits found in the CDB. + */ +/* --- Bits found in byte 1 --- */ +#define SBC_VRPROTECT_MASK 0xe0 +#define SBC_DPO 0x10 +#define SBC_BYTCHK 0x02 +/* --- Bits found in byte 6 --- */ +#define SBC_GROUP_MASK 0x1f + +/* * SBC-2 revision 16, section 5.17 START_STOP * Table 49 -- POWER CONDITION field */ diff --git a/usr/src/cmd/iscsi/iscsitgtd/t10_spc.h b/usr/src/cmd/iscsi/iscsitgtd/t10_spc.h index 90ec0ac9f1..68bff91e9d 100644 --- a/usr/src/cmd/iscsi/iscsitgtd/t10_spc.h +++ b/usr/src/cmd/iscsi/iscsitgtd/t10_spc.h @@ -115,6 +115,14 @@ Boolean_t spc_encode_lu_addr(uint8_t *buf, int select_field, uint32_t lun); #define SPC_ASCQ_CAP_CHANGE 0x09 #define SPC_ASC_IN_PROG 0x04 #define SPC_ASCQ_IN_PROG 0x07 +#define SPC_ASC_DATA_PATH 0x41 +#define SPC_ASCQ_DATA_PATH 0x00 +#define SPC_ASC_MISCOMPARE 0x1d +#define SPC_ASCQ_MISCOMPARE 0x00 +#define SPC_ASC_INVALID_LU 0x20 +#define SPC_ASCQ_INVALID_LU 0x09 +#define SPC_ASC_BLOCK_RANGE 0x21 +#define SPC_ASCQ_BLOCK_RANGE 0x00 /* * []------------------------------------------------------------------[] diff --git a/usr/src/uts/common/sys/scsi/generic/commands.h b/usr/src/uts/common/sys/scsi/generic/commands.h index d4b17c18da..66218064c2 100644 --- a/usr/src/uts/common/sys/scsi/generic/commands.h +++ b/usr/src/uts/common/sys/scsi/generic/commands.h @@ -298,6 +298,7 @@ extern "C" { */ #define SCMD_GROUP4 0x80 #define SCMD_EXTENDED_COPY 0x83 +#define SCMD_VERIFY_G4 0x8f /* * Group 4 Commands, Direct Access Devices @@ -334,7 +335,7 @@ extern "C" { #define SCMD_WRITE_G5 0xAA #define SCMD_READ_MEDIA_SERIAL 0xAB #define SCMD_GET_PERFORMANCE 0xAC - +#define SCMD_VERIFY_G5 0xAF /* diff --git a/usr/src/uts/common/sys/scsi/impl/commands.h b/usr/src/uts/common/sys/scsi/impl/commands.h index 059f6b90b6..227e2da724 100644 --- a/usr/src/uts/common/sys/scsi/impl/commands.h +++ b/usr/src/uts/common/sys/scsi/impl/commands.h @@ -444,6 +444,11 @@ union scsi_cdb { /* scsi command description block */ ((cdb)->scc5_addr1 << 8) + \ ((cdb)->scc5_addr0) +#define GETG5COUNT(cdb) ((cdb)->scc5_count3 << 24) + \ + ((cdb)->scc5_count2 << 16) + \ + ((cdb)->scc5_count1 << 8) + \ + ((cdb)->scc5_count0) + #define GETG5TAG(cdb) (cdb)->scc5_reladdr |