diff --git a/iscsi-scst/kernel/iscsi.c b/iscsi-scst/kernel/iscsi.c index 5ee6771cb..6aed6bd13 100644 --- a/iscsi-scst/kernel/iscsi.c +++ b/iscsi-scst/kernel/iscsi.c @@ -54,7 +54,8 @@ DECLARE_WAIT_QUEUE_HEAD(iscsi_wr_waitQ); static struct page *dummy_page; static struct scatterlist dummy_sg; -static uint8_t sense_unexpected_unsolicited_data[SCST_STANDARD_SENSE_LEN]; +static uint8_t sense_fixed_unexpected_unsolicited_data[SCST_STANDARD_SENSE_LEN]; +static uint8_t sense_descr_unexpected_unsolicited_data[SCST_STANDARD_SENSE_LEN]; struct iscsi_thread_t { struct task_struct *thr; @@ -1414,9 +1415,14 @@ static int scsi_cmnd_start(struct iscsi_cmnd *req) req->pdu.datasize)) { PRINT_ERROR("Unexpected unsolicited data (ITT %x " "CDB %x", cmnd_itt(req), req_hdr->scb[0]); - create_status_rsp(req, SAM_STAT_CHECK_CONDITION, - sense_unexpected_unsolicited_data, - sizeof(sense_unexpected_unsolicited_data)); + if (scst_get_cmd_dev_d_sense(scst_cmd)) + create_status_rsp(req, SAM_STAT_CHECK_CONDITION, + sense_descr_unexpected_unsolicited_data, + sizeof(sense_descr_unexpected_unsolicited_data)); + else + create_status_rsp(req, SAM_STAT_CHECK_CONDITION, + sense_fixed_unexpected_unsolicited_data, + sizeof(sense_fixed_unexpected_unsolicited_data)); cmnd_reject_scsi_cmd(req); goto out; } @@ -1467,9 +1473,14 @@ static int scsi_cmnd_start(struct iscsi_cmnd *req) if (unlikely(dir != SCST_DATA_WRITE)) { PRINT_ERROR("pdu.datasize(%d) >0, but dir(%x) isn't " "WRITE", req->pdu.datasize, dir); - create_status_rsp(req, SAM_STAT_CHECK_CONDITION, - sense_unexpected_unsolicited_data, - sizeof(sense_unexpected_unsolicited_data)); + if (scst_get_cmd_dev_d_sense(scst_cmd)) + create_status_rsp(req, SAM_STAT_CHECK_CONDITION, + sense_descr_unexpected_unsolicited_data, + sizeof(sense_descr_unexpected_unsolicited_data)); + else + create_status_rsp(req, SAM_STAT_CHECK_CONDITION, + sense_fixed_unexpected_unsolicited_data, + sizeof(sense_fixed_unexpected_unsolicited_data)); cmnd_reject_scsi_cmd(req); } else res = cmnd_prepare_recv_pdu(conn, req, 0, @@ -3084,11 +3095,16 @@ static int __init iscsi_init(void) PRINT_INFO("iSCSI SCST Target - version %s", ISCSI_VERSION_STRING); - sense_unexpected_unsolicited_data[0] = 0x70; - sense_unexpected_unsolicited_data[2] = ABORTED_COMMAND; - sense_unexpected_unsolicited_data[7] = 6; - sense_unexpected_unsolicited_data[12] = 0xc; - sense_unexpected_unsolicited_data[13] = 0xc; + sense_fixed_unexpected_unsolicited_data[0] = 0x70; + sense_fixed_unexpected_unsolicited_data[2] = ABORTED_COMMAND; + sense_fixed_unexpected_unsolicited_data[7] = 6; + sense_fixed_unexpected_unsolicited_data[12] = 0xc; + sense_fixed_unexpected_unsolicited_data[13] = 0xc; + + sense_descr_unexpected_unsolicited_data[0] = 0x72; + sense_descr_unexpected_unsolicited_data[1] = ABORTED_COMMAND; + sense_descr_unexpected_unsolicited_data[2] = 0xc; + sense_descr_unexpected_unsolicited_data[3] = 0xc; dummy_page = alloc_pages(GFP_KERNEL, 0); if (dummy_page == NULL) { diff --git a/scst/include/scst.h b/scst/include/scst.h index 495c5666a..603cf9703 100644 --- a/scst/include/scst.h +++ b/scst/include/scst.h @@ -1434,6 +1434,7 @@ struct scst_device { unsigned long tst:3; unsigned long tas:1; unsigned long swp:1; + unsigned long d_sense:1; /* * Set if device implements own ordered commands management. If not set @@ -2403,6 +2404,12 @@ static inline int scst_cmd_aborted(struct scst_cmd *cmd) !test_bit(SCST_CMD_ABORTED_OTHER, &cmd->cmd_flags); } +/* Returns sense data format for cmd's dev */ +static inline bool scst_get_cmd_dev_d_sense(struct scst_cmd *cmd) +{ + return cmd->dev->d_sense; +} + /* * Get/Set functions for expected data direction, transfer length * and its validity flag @@ -2773,15 +2780,16 @@ int scst_alloc_sense(struct scst_cmd *cmd, int atomic); int scst_alloc_set_sense(struct scst_cmd *cmd, int atomic, const uint8_t *sense, unsigned int len); -void scst_set_sense(uint8_t *buffer, int len, int key, int asc, int ascq); +void scst_set_sense(uint8_t *buffer, int len, bool d_sense, + int key, int asc, int ascq); /* * Returnes true if sense matches to (key, asc, ascq) and false otherwise. * Valid_mask is one or several SCST_SENSE_*_VALID constants setting valid * (key, asc, ascq) values. */ -bool scst_analyze_sense(const uint8_t *sense, int len, unsigned int valid_mask, - int key, int asc, int ascq); +bool scst_analyze_sense(const uint8_t *sense, int len, + unsigned int valid_mask, int key, int asc, int ascq); /* * Returnes a pseudo-random number for debugging purposes. Available only in diff --git a/scst/include/scst_const.h b/scst/include/scst_const.h index 3e880e0e3..aed2c2c9f 100644 --- a/scst/include/scst_const.h +++ b/scst/include/scst_const.h @@ -281,6 +281,12 @@ static inline int scst_is_ua_sense(const uint8_t *sense) #define SCST_CONTR_MODE_QUEUE_ALG_RESTRICTED_REORDER 0 #define SCST_CONTR_MODE_QUEUE_ALG_UNRESTRICTED_REORDER 1 +/************************************************************* + ** Values for the control mode page D_SENSE field + *************************************************************/ +#define SCST_CONTR_MODE_FIXED_SENSE 0 +#define SCST_CONTR_MODE_DESCR_SENSE 1 + /************************************************************* ** Misc SCSI constants *************************************************************/ diff --git a/scst/include/scst_user.h b/scst/include/scst_user.h index 1386367ef..8dba41a3d 100644 --- a/scst/include/scst_user.h +++ b/scst/include/scst_user.h @@ -82,6 +82,7 @@ struct scst_user_opt { uint8_t queue_alg; uint8_t tas; uint8_t swp; + uint8_t d_sense; uint8_t has_own_order_mgmt; }; diff --git a/scst/src/dev_handlers/scst_cdrom.c b/scst/src/dev_handlers/scst_cdrom.c index c3043b984..cc5e2a58a 100644 --- a/scst/src/dev_handlers/scst_cdrom.c +++ b/scst/src/dev_handlers/scst_cdrom.c @@ -113,7 +113,9 @@ static int cdrom_attach(struct scst_device *dev) TRACE_DBG("READ_CAPACITY done: %x", res); - if ((res == 0) || (sense_buffer[2] != UNIT_ATTENTION)) + if ((res == 0) || !scst_analyze_sense(sense_buffer, + sizeof(sense_buffer), SCST_SENSE_KEY_VALID, + UNIT_ATTENTION, 0, 0)) break; if (!--retries) { diff --git a/scst/src/dev_handlers/scst_disk.c b/scst/src/dev_handlers/scst_disk.c index 3228def31..b12b88805 100644 --- a/scst/src/dev_handlers/scst_disk.c +++ b/scst/src/dev_handlers/scst_disk.c @@ -189,8 +189,12 @@ static int disk_attach(struct scst_device *dev) TRACE_DBG("READ_CAPACITY done: %x", res); - if (!res || (sense_buffer[12] != 0x28 && - sense_buffer[12] != 0x29)) + if ((res == 0) || !scst_analyze_sense(sense_buffer, + sizeof(sense_buffer), SCST_SENSE_ALL_VALID, + SCST_LOAD_SENSE(scst_sense_medium_changed_UA)) || + !scst_analyze_sense(sense_buffer, sizeof(sense_buffer), + SCST_SENSE_KEY_VALID | SCST_SENSE_ASC_VALID, + UNIT_ATTENTION, 0x29, 0)) break; if (!--retries) { PRINT_ERROR("UA not clear after %d retries", diff --git a/scst/src/dev_handlers/scst_modisk.c b/scst/src/dev_handlers/scst_modisk.c index 80d17f03d..793743b91 100644 --- a/scst/src/dev_handlers/scst_modisk.c +++ b/scst/src/dev_handlers/scst_modisk.c @@ -203,7 +203,9 @@ static int modisk_attach(struct scst_device *dev) TRACE_DBG("READ_CAPACITY done: %x", res); - if (!res || (sense_buffer[2] != UNIT_ATTENTION)) + if (!res || !scst_analyze_sense(sense_buffer, + sizeof(sense_buffer), SCST_SENSE_KEY_VALID, + UNIT_ATTENTION, 0, 0)) break; if (!--retries) { diff --git a/scst/src/dev_handlers/scst_user.c b/scst/src/dev_handlers/scst_user.c index 42781d334..505b6b5ee 100644 --- a/scst/src/dev_handlers/scst_user.c +++ b/scst/src/dev_handlers/scst_user.c @@ -72,6 +72,7 @@ struct scst_user_dev { unsigned int queue_alg:4; unsigned int tas:1; unsigned int swp:1; + unsigned int d_sense:1; unsigned int has_own_order_mgmt:1; int (*generic_parse)(struct scst_cmd *cmd, @@ -2359,6 +2360,7 @@ static int dev_user_attach(struct scst_device *sdev) sdev->queue_alg = dev->queue_alg; sdev->swp = dev->swp; sdev->tas = dev->tas; + sdev->d_sense = dev->d_sense; sdev->has_own_order_mgmt = dev->has_own_order_mgmt; dev->sdev = sdev; @@ -2913,10 +2915,11 @@ static int __dev_user_set_opt(struct scst_user_dev *dev, (opt->tst != SCST_CONTR_MODE_SEP_TASK_SETS)) || ((opt->queue_alg != SCST_CONTR_MODE_QUEUE_ALG_RESTRICTED_REORDER) && (opt->queue_alg != SCST_CONTR_MODE_QUEUE_ALG_UNRESTRICTED_REORDER)) || - (opt->swp > 1) || (opt->tas > 1) || (opt->has_own_order_mgmt > 1)) { + (opt->swp > 1) || (opt->tas > 1) || (opt->has_own_order_mgmt > 1) || + (opt->d_sense > 1)) { PRINT_ERROR("Invalid SCSI option (tst %x, queue_alg %x, swp %x," - " tas %x, has_own_order_mgmt %x)", opt->tst, - opt->queue_alg, opt->swp, opt->tas, + " tas %x, d_sense %d, has_own_order_mgmt %x)", opt->tst, + opt->queue_alg, opt->swp, opt->tas, opt->d_sense, opt->has_own_order_mgmt); res = -EINVAL; goto out; @@ -2932,12 +2935,15 @@ static int __dev_user_set_opt(struct scst_user_dev *dev, dev->queue_alg = opt->queue_alg; dev->swp = opt->swp; dev->tas = opt->tas; + dev->tst = opt->tst; + dev->d_sense = opt->d_sense; dev->has_own_order_mgmt = opt->has_own_order_mgmt; if (dev->sdev != NULL) { dev->sdev->tst = opt->tst; dev->sdev->queue_alg = opt->queue_alg; dev->sdev->swp = opt->swp; dev->sdev->tas = opt->tas; + dev->sdev->d_sense = opt->d_sense; dev->sdev->has_own_order_mgmt = opt->has_own_order_mgmt; } @@ -3007,6 +3013,7 @@ static int dev_user_get_opt(struct file *file, void __user *arg) opt.queue_alg = dev->queue_alg; opt.tas = dev->tas; opt.swp = dev->swp; + opt.d_sense = dev->d_sense; opt.has_own_order_mgmt = dev->has_own_order_mgmt; TRACE_DBG("dev %s, parse_type %x, on_free_cmd_type %x, " diff --git a/scst/src/dev_handlers/scst_vdisk.c b/scst/src/dev_handlers/scst_vdisk.c index c8155585f..9d0dee7ff 100644 --- a/scst/src/dev_handlers/scst_vdisk.c +++ b/scst/src/dev_handlers/scst_vdisk.c @@ -105,6 +105,8 @@ static struct scst_proc_log vdisk_proc_local_trace_tbl[] = #define DEF_SWP 0 #define DEF_TAS 0 +#define DEF_DSENSE SCST_CONTR_MODE_FIXED_SENSE + #define VDISK_PROC_HELP "help" static unsigned int random_values[256] = { @@ -574,6 +576,7 @@ static int vdisk_attach(struct scst_device *dev) dev->dh_priv = virt_dev; dev->tst = DEF_TST; + dev->d_sense = DEF_DSENSE; if (virt_dev->wt_flag && !virt_dev->nv_cache) dev->queue_alg = DEF_QUEUE_ALG_WT; else @@ -1362,7 +1365,8 @@ static void vdisk_exec_request_sense(struct scst_cmd *cmd) goto out; } - scst_set_sense(address, length, SCST_LOAD_SENSE(scst_sense_no_sense)); + scst_set_sense(address, length, cmd->dev->d_sense, + SCST_LOAD_SENSE(scst_sense_no_sense)); out_put: scst_put_buf(cmd, address); @@ -1468,6 +1472,7 @@ static int vdisk_ctrl_m_pg(unsigned char *p, int pcontrol, switch (pcontrol) { case 0: p[2] |= virt_dev->dev->tst << 5; + p[2] |= virt_dev->dev->d_sense << 2; p[3] |= virt_dev->dev->queue_alg << 4; p[4] |= virt_dev->dev->swp << 3; p[5] |= virt_dev->dev->tas << 6; @@ -1481,11 +1486,13 @@ static int vdisk_ctrl_m_pg(unsigned char *p, int pcontrol, p[2] |= 7 << 5; /* TST */ p[3] |= 0xF << 4; /* QUEUE ALGORITHM MODIFIER */ #endif + p[2] |= 1 << 2; /* D_SENSE */ p[4] |= 1 << 3; /* SWP */ p[5] |= 1 << 6; /* TAS */ break; case 2: p[2] |= DEF_TST << 5; + p[2] |= DEF_DSENSE << 2; if (virt_dev->wt_flag || virt_dev->nv_cache) p[3] |= DEF_QUEUE_ALG_WT << 4; else @@ -1693,7 +1700,7 @@ static void vdisk_ctrl_m_pg_select(unsigned char *p, struct scst_vdisk_dev *virt_dev) { struct scst_device *dev = virt_dev->dev; - int old_swp = dev->swp, old_tas = dev->tas; + int old_swp = dev->swp, old_tas = dev->tas, old_dsense = dev->d_sense; #if 0 /* Not implemented yet, see comment in vdisk_ctrl_m_pg() */ @@ -1702,10 +1709,12 @@ static void vdisk_ctrl_m_pg_select(unsigned char *p, #endif dev->swp = (p[4] & 0x8) >> 3; dev->tas = (p[5] & 0x40) >> 6; + dev->d_sense = (p[2] & 0x4) >> 2; PRINT_INFO("Device %s: new control mode page parameters: SWP %x " - "(was %x), TAS %x (was %x)", virt_dev->name, dev->swp, - old_swp, dev->tas, old_tas); + "(was %x), TAS %x (was %x), D_SENSE %d (was %d)", + virt_dev->name, dev->swp, old_swp, dev->tas, old_tas, + dev->d_sense, old_dsense); return; } @@ -2683,6 +2692,7 @@ static int vdisk_task_mgmt_fn(struct scst_mgmt_cmd *mcmd, struct scst_vdisk_dev *virt_dev = (struct scst_vdisk_dev *)dev->dh_priv; dev->tst = DEF_TST; + dev->d_sense = DEF_DSENSE; if (virt_dev->wt_flag && !virt_dev->nv_cache) dev->queue_alg = DEF_QUEUE_ALG_WT; else diff --git a/scst/src/scst_lib.c b/scst/src/scst_lib.c index d201a18f5..0f5b2446a 100644 --- a/scst/src/scst_lib.c +++ b/scst/src/scst_lib.c @@ -141,7 +141,8 @@ void scst_set_cmd_error(struct scst_cmd *cmd, int key, int asc, int ascq) goto out; } - scst_set_sense(cmd->sense, SCST_SENSE_BUFFERSIZE, key, asc, ascq); + scst_set_sense(cmd->sense, SCST_SENSE_BUFFERSIZE, cmd->dev->d_sense, + key, asc, ascq); TRACE_BUFFER("Sense set", cmd->sense, SCST_SENSE_BUFFERSIZE); out: @@ -150,17 +151,27 @@ out: } EXPORT_SYMBOL(scst_set_cmd_error); -void scst_set_sense(uint8_t *buffer, int len, int key, int asc, int ascq) +void scst_set_sense(uint8_t *buffer, int len, bool d_sense, + int key, int asc, int ascq) { sBUG_ON(len < SCST_STANDARD_SENSE_LEN); memset(buffer, 0, len); - buffer[0] = 0x70; /* Error Code */ - buffer[2] = key; /* Sense Key */ - buffer[7] = 0x0a; /* Additional Sense Length */ - buffer[12] = asc; /* ASC */ - buffer[13] = ascq; /* ASCQ */ + if (d_sense) { + /* Descriptor format */ + buffer[0] = 0x72; /* Response Code */ + buffer[1] = key; /* Sense Key */ + buffer[2] = asc; /* ASC */ + buffer[3] = ascq; /* ASCQ */ + } else { + /* Fixed format */ + buffer[0] = 0x70; /* Response Code */ + buffer[2] = key; /* Sense Key */ + buffer[7] = 0x0a; /* Additional Sense Length */ + buffer[12] = asc; /* ASC */ + buffer[13] = ascq; /* ASCQ */ + } TRACE_BUFFER("Sense set", buffer, len); return; @@ -175,20 +186,36 @@ bool scst_analyze_sense(const uint8_t *sense, int len, unsigned int valid_mask, if (len < 14) goto out; - /* Error Code */ - if (sense[0] != 0x70) - goto out; + /* Response Code */ + if ((sense[0] == 0x70) || (sense[0] == 0x71)) { + /* Fixed format */ - /* Sense Key */ - if ((valid_mask & SCST_SENSE_KEY_VALID) && (sense[2] != key)) - goto out; + /* Sense Key */ + if ((valid_mask & SCST_SENSE_KEY_VALID) && (sense[2] != key)) + goto out; - /* ASC */ - if ((valid_mask & SCST_SENSE_ASC_VALID) && (sense[12] != asc)) - goto out; + /* ASC */ + if ((valid_mask & SCST_SENSE_ASC_VALID) && (sense[12] != asc)) + goto out; - /* ASCQ */ - if ((valid_mask & SCST_SENSE_ASCQ_VALID) && (sense[13] != ascq)) + /* ASCQ */ + if ((valid_mask & SCST_SENSE_ASCQ_VALID) && (sense[13] != ascq)) + goto out; + } else if ((sense[0] == 0x72) || (sense[0] == 0x73)) { + /* Descriptor format */ + + /* Sense Key */ + if ((valid_mask & SCST_SENSE_KEY_VALID) && (sense[1] != key)) + goto out; + + /* ASC */ + if ((valid_mask & SCST_SENSE_ASC_VALID) && (sense[2] != asc)) + goto out; + + /* ASCQ */ + if ((valid_mask & SCST_SENSE_ASCQ_VALID) && (sense[3] != ascq)) + goto out; + } else goto out; res = true; @@ -267,6 +294,7 @@ void scst_set_initial_UA(struct scst_session *sess, int key, int asc, int ascq) SCST_LOAD_SENSE(scst_sense_reset_UA))) { scst_set_sense(ua->UA_sense_buffer, sizeof(ua->UA_sense_buffer), + tgt_dev->dev->d_sense, key, asc, ascq); } else PRINT_ERROR("%s", @@ -337,9 +365,6 @@ void scst_capacity_data_changed(struct scst_device *dev) TRACE_MGMT_DBG("CAPACITY DATA CHANGED (dev %p)", dev); - scst_set_sense(sense_buffer, sizeof(sense_buffer), - SCST_LOAD_SENSE(scst_sense_capacity_data_changed)); - mutex_lock(&scst_mutex); list_for_each_entry(tgt_dev, &dev->dev_tgt_dev_list, @@ -357,6 +382,7 @@ void scst_capacity_data_changed(struct scst_device *dev) aen->event_fn = SCST_AEN_SCSI; aen->aen_sense_len = SCST_STANDARD_SENSE_LEN; scst_set_sense(aen->aen_sense, aen->aen_sense_len, + tgt_dev->dev->d_sense, SCST_LOAD_SENSE(scst_sense_capacity_data_changed)); TRACE_DBG("Calling target's %s report_aen(%p)", @@ -372,6 +398,9 @@ void scst_capacity_data_changed(struct scst_device *dev) queue_ua: TRACE_MGMT_DBG("Queuing CAPACITY DATA CHANGED UA (tgt_dev %p)", tgt_dev); + scst_set_sense(sense_buffer, sizeof(sense_buffer), + tgt_dev->dev->d_sense, + SCST_LOAD_SENSE(scst_sense_capacity_data_changed)); scst_check_set_UA(tgt_dev, sense_buffer, sizeof(sense_buffer), 0); } @@ -414,9 +443,6 @@ void scst_queue_report_luns_changed_UA(struct scst_session *sess, int flags) TRACE_ENTRY(); - scst_set_sense(sense_buffer, sizeof(sense_buffer), - SCST_LOAD_SENSE(scst_sense_reported_luns_data_changed)); - TRACE_MGMT_DBG("Queuing REPORTED LUNS DATA CHANGED UA " "(sess %p)", sess); @@ -438,6 +464,10 @@ void scst_queue_report_luns_changed_UA(struct scst_session *sess, int flags) tgt_dev->dev->type)) continue; + scst_set_sense(sense_buffer, sizeof(sense_buffer), + tgt_dev->dev->d_sense, + SCST_LOAD_SENSE(scst_sense_reported_luns_data_changed)); + __scst_check_set_UA(tgt_dev, sense_buffer, sizeof(sense_buffer), flags | SCST_SET_UA_FLAG_GLOBAL); @@ -497,6 +527,7 @@ found: aen->event_fn = SCST_AEN_SCSI; aen->aen_sense_len = SCST_STANDARD_SENSE_LEN; scst_set_sense(aen->aen_sense, aen->aen_sense_len, + tgt_dev->dev->d_sense, SCST_LOAD_SENSE(scst_sense_reported_luns_data_changed)); TRACE_DBG("Calling target's %s report_aen(%p)", @@ -535,8 +566,7 @@ void scst_aen_done(struct scst_aen *aen) aen->sess->initiator_name); if (scst_analyze_sense(aen->aen_sense, aen->aen_sense_len, - SCST_SENSE_ALL_VALID, - SCST_LOAD_SENSE( + SCST_SENSE_ALL_VALID, SCST_LOAD_SENSE( scst_sense_reported_luns_data_changed))) { mutex_lock(&scst_mutex); scst_queue_report_luns_changed_UA(aen->sess, @@ -989,7 +1019,7 @@ static struct scst_tgt_dev *scst_alloc_add_tgt_dev(struct scst_session *sess, } scst_set_sense(sense_buffer, sizeof(sense_buffer), - SCST_LOAD_SENSE(scst_sense_reset_UA)); + dev->d_sense, SCST_LOAD_SENSE(scst_sense_reset_UA)); scst_alloc_set_UA(tgt_dev, sense_buffer, sizeof(sense_buffer), 0); tm_dbg_init_tgt_dev(tgt_dev, acg_dev); @@ -1062,6 +1092,7 @@ void scst_nexus_loss(struct scst_tgt_dev *tgt_dev, bool queue_UA) if (queue_UA) { uint8_t sense_buffer[SCST_STANDARD_SENSE_LEN]; scst_set_sense(sense_buffer, sizeof(sense_buffer), + tgt_dev->dev->d_sense, SCST_LOAD_SENSE(scst_sense_nexus_loss_UA)); scst_check_set_UA(tgt_dev, sense_buffer, sizeof(sense_buffer), 0); @@ -2994,7 +3025,7 @@ static void scst_check_internal_sense(struct scst_device *dev, int result, if (host_byte(result) == DID_RESET) { TRACE(TRACE_MGMT_MINOR, "%s", "DID_RESET received, triggering " "reset UA"); - scst_set_sense(sense, sense_len, + scst_set_sense(sense, sense_len, dev->d_sense, SCST_LOAD_SENSE(scst_sense_reset_UA)); scst_dev_check_set_UA(dev, NULL, sense, sense_len); } else if ((status_byte(result) == CHECK_CONDITION) && @@ -3052,6 +3083,7 @@ int scst_obtain_device_parameters(struct scst_device *dev) dev->queue_alg = q; dev->swp = (buffer[4+4] & 0x8) >> 3; dev->tas = (buffer[4+5] & 0x40) >> 6; + dev->d_sense = (buffer[4+2] & 0x4) >> 2; /* * Unfortunately, SCSI ML doesn't provide a way to @@ -3062,12 +3094,13 @@ int scst_obtain_device_parameters(struct scst_device *dev) TRACE(TRACE_SCSI|TRACE_MGMT_MINOR, "Device %d:%d:%d:%d: TST %x, " - "QUEUE ALG %x, SWP %x, TAS %x, " + "QUEUE ALG %x, SWP %x, TAS %x, D_SENSE %d" "has_own_order_mgmt %d", dev->scsi_dev->host->host_no, dev->scsi_dev->channel, dev->scsi_dev->id, dev->scsi_dev->lun, dev->tst, dev->queue_alg, - dev->swp, dev->tas, dev->has_own_order_mgmt); + dev->swp, dev->tas, dev->d_sense, + dev->has_own_order_mgmt); goto out; } else { @@ -3086,19 +3119,19 @@ int scst_obtain_device_parameters(struct scst_device *dev) SCST_SENSE_KEY_VALID, ILLEGAL_REQUEST, 0, 0)) { TRACE(TRACE_SCSI|TRACE_MGMT_MINOR, - "Device %d:%d:%d:%d doesn't" - " support control mode page," - " using defaults: TST %x," - " QUEUE ALG %x, SWP %x, TAS %x," - " has_own_order_mgmt %d", + "Device %d:%d:%d:%d doesn't " + "support control mode page, " + "using defaults: TST %x, " + "QUEUE ALG %x, SWP %x, " + "TAS %x, D_SENSE %d, " + "has_own_order_mgmt %d ", dev->scsi_dev->host->host_no, dev->scsi_dev->channel, dev->scsi_dev->id, dev->scsi_dev->lun, - dev->tst, - dev->queue_alg, - dev->swp, - dev->tas, + dev->tst, dev->queue_alg, + dev->swp, dev->tas, + dev->d_sense, dev->has_own_order_mgmt); res = 0; goto out; @@ -3211,7 +3244,7 @@ void scst_process_reset(struct scst_device *dev, if (setUA) { uint8_t sense_buffer[SCST_STANDARD_SENSE_LEN]; scst_set_sense(sense_buffer, sizeof(sense_buffer), - SCST_LOAD_SENSE(scst_sense_reset_UA)); + dev->d_sense, SCST_LOAD_SENSE(scst_sense_reset_UA)); scst_dev_check_set_local_UA(dev, exclude_cmd, sense_buffer, sizeof(sense_buffer)); } diff --git a/scst/src/scst_targ.c b/scst/src/scst_targ.c index 89deb7186..b83bbc466 100644 --- a/scst/src/scst_targ.c +++ b/scst/src/scst_targ.c @@ -2580,10 +2580,12 @@ static int scst_mode_select_checks(struct scst_cmd *cmd) if (cmd->cdb[0] == LOG_SELECT) { scst_set_sense(sense_buffer, sizeof(sense_buffer), + dev->d_sense, UNIT_ATTENTION, 0x2a, 0x02); } else { scst_set_sense(sense_buffer, sizeof(sense_buffer), + dev->d_sense, UNIT_ATTENTION, 0x2a, 0x01); } scst_dev_check_set_local_UA(dev, cmd, sense_buffer, @@ -4238,7 +4240,7 @@ static int scst_clear_task_set(struct scst_mgmt_cmd *mcmd) if (!dev->tas) { uint8_t sense_buffer[SCST_STANDARD_SENSE_LEN]; - scst_set_sense(sense_buffer, sizeof(sense_buffer), + scst_set_sense(sense_buffer, sizeof(sense_buffer), dev->d_sense, SCST_LOAD_SENSE(scst_sense_cleared_by_another_ini_UA)); list_for_each_entry(tgt_dev, &UA_tgt_devs, diff --git a/usr/fileio/fileio.c b/usr/fileio/fileio.c index a902d6c01..c6ba350dd 100644 --- a/usr/fileio/fileio.c +++ b/usr/fileio/fileio.c @@ -458,6 +458,7 @@ int main(int argc, char **argv) desc.opt.tst = SCST_CONTR_MODE_SEP_TASK_SETS; desc.opt.queue_alg = SCST_CONTR_MODE_QUEUE_ALG_UNRESTRICTED_REORDER; + desc.opt.d_sense = SCST_CONTR_MODE_FIXED_SENSE; res = ioctl(dev.scst_usr_fd, SCST_USER_REGISTER_DEVICE, &desc); if (res != 0) {