mirror of
https://github.com/SCST-project/scst.git
synced 2026-05-28 17:30:18 +00:00
Support for descriptor sense format added
git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@705 d57e44dd-8a1f-0410-8b47-8ef2f437770f
This commit is contained in:
@@ -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) {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
*************************************************************/
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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, "
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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) {
|
||||
|
||||
Reference in New Issue
Block a user