Support for descriptor sense format added
authorvlnb <vlnb@d57e44dd-8a1f-0410-8b47-8ef2f437770f>
Fri, 20 Mar 2009 12:07:48 +0000 (12:07 +0000)
committervlnb <vlnb@d57e44dd-8a1f-0410-8b47-8ef2f437770f>
Fri, 20 Mar 2009 12:07:48 +0000 (12:07 +0000)
git-svn-id: https://scst.svn.sourceforge.net/svnroot/scst/trunk@705 d57e44dd-8a1f-0410-8b47-8ef2f437770f

12 files changed:
iscsi-scst/kernel/iscsi.c
scst/include/scst.h
scst/include/scst_const.h
scst/include/scst_user.h
scst/src/dev_handlers/scst_cdrom.c
scst/src/dev_handlers/scst_disk.c
scst/src/dev_handlers/scst_modisk.c
scst/src/dev_handlers/scst_user.c
scst/src/dev_handlers/scst_vdisk.c
scst/src/scst_lib.c
scst/src/scst_targ.c
usr/fileio/fileio.c

index 5ee6771..6aed6bd 100644 (file)
@@ -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) {
index 495c566..603cf97 100644 (file)
@@ -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
index 3e880e0..aed2c2c 100644 (file)
@@ -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
  *************************************************************/
index 1386367..8dba41a 100644 (file)
@@ -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;
 };
index c3043b9..cc5e2a5 100644 (file)
@@ -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) {
index 3228def..b12b888 100644 (file)
@@ -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",
index 80d17f0..793743b 100644 (file)
@@ -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) {
index 42781d3..505b6b5 100644 (file)
@@ -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, "
index c815558..9d0dee7 100644 (file)
@@ -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
index d201a18..0f5b244 100644 (file)
@@ -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))
+                       goto out;
+       } else if ((sense[0] == 0x72) || (sense[0] == 0x73)) {
+               /* Descriptor format */
 
-       /* ASCQ */
-       if ((valid_mask & SCST_SENSE_ASCQ_VALID) && (sense[13] != ascq))
+               /* 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));
        }
index 89deb71..b83bbc4 100644 (file)
@@ -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,
index a902d6c..c6ba350 100644 (file)
@@ -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) {