To add wlun during probe, call sdebug_register_w_lun(WLUN);
prior to setting max luns

hpnt->max_lun = sdebug_max_luns();

Cc: Douglas Gilbert <dgilb...@interlog.com>
Signed-off-by: Tomas Winkler <tomas.wink...@intel.com>
---
 drivers/scsi/scsi_debug.c | 105 ++++++++++++++++++++++++++++++++++++----------
 1 file changed, 82 insertions(+), 23 deletions(-)

diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c
index 0825c0a62a33..5d1bb12adc43 100644
--- a/drivers/scsi/scsi_debug.c
+++ b/drivers/scsi/scsi_debug.c
@@ -683,6 +683,51 @@ static struct sd_dif_tuple *dif_store(sector_t sector)
        return dif_storep + sector;
 }
 
+#define  SCSI_W_LUN_MAX 10
+static u8 scsi_debug_w_luns[SCSI_W_LUN_MAX];
+static int scsi_debug_w_luns_count;
+
+static void sdebug_register_w_lun(u8 w_lun_idx)
+{
+       if (WARN_ON(scsi_debug_w_luns_count >= SCSI_W_LUN_MAX))
+               return;
+
+       scsi_debug_w_luns[scsi_debug_w_luns_count++] = w_lun_idx;
+}
+
+static int sdebug_add_w_luns(struct Scsi_Host *hpnt)
+{
+       u64 lun;
+       int i;
+       int ret = 0;
+
+       /* i = 1 skip REPORT LUNS */
+       for (i = 1; i < scsi_debug_w_luns_count; i++) {
+               lun = SCSI_W_LUN_BASE | scsi_debug_w_luns[i];
+               ret = scsi_add_device(hpnt, 0, 0, lun);
+               if (ret)
+                       break;
+       }
+
+       return ret;
+}
+
+static u64 sdebug_max_luns(void)
+{
+       u64 max_w_lun;
+       int i;
+
+       max_w_lun = scsi_debug_w_luns[0];
+
+       for (i = 1; i < scsi_debug_w_luns_count; i++) {
+               if (scsi_debug_w_luns[i] > max_w_lun)
+                       max_w_lun = scsi_debug_w_luns[i];
+       }
+
+       return SCSI_W_LUN_BASE + max_w_lun + 1;
+}
+
+
 static int sdebug_add_adapter(void);
 static void sdebug_remove_adapter(void);
 
@@ -699,8 +744,8 @@ static void sdebug_max_tgts_luns(void)
                        hpnt->max_id = scsi_debug_num_tgts + 1;
                else
                        hpnt->max_id = scsi_debug_num_tgts;
-               /* scsi_debug_max_luns; */
-               hpnt->max_lun = SCSI_W_LUN_REPORT_LUNS + 1;
+
+               hpnt->max_lun = sdebug_max_luns();
        }
        spin_unlock(&sdebug_host_list_lock);
 }
@@ -1284,20 +1329,22 @@ static int resp_inquiry(struct scsi_cmnd *scp, struct 
sdebug_dev_info *devip)
        unsigned char * arr;
        unsigned char *cmd = scp->cmnd;
        int alloc_len, n, ret;
-       bool have_wlun;
+       bool is_wlun;
 
        alloc_len = (cmd[3] << 8) + cmd[4];
        arr = kzalloc(SDEBUG_MAX_INQ_ARR_SZ, GFP_ATOMIC);
        if (! arr)
                return DID_REQUEUE << 16;
-       have_wlun = (scp->device->lun == SCSI_W_LUN_REPORT_LUNS);
-       if (have_wlun)
-               pq_pdt = 0x1e;  /* present, wlun */
+
+       is_wlun = scsi_is_wlun(scp->device->lun);
+       if (is_wlun)
+               pq_pdt = TYPE_WLUN;
        else if (scsi_debug_no_lun_0 && (0 == devip->lun))
-               pq_pdt = 0x7f;  /* not present, no device type */
+               pq_pdt = TYPE_NO_LUN;   /* not present, no device type */
        else
                pq_pdt = (scsi_debug_ptype & 0x1f);
        arr[0] = pq_pdt;
+
        if (0x2 & cmd[1]) {  /* CMDDT bit set */
                mk_sense_invalid_fld(scp, SDEB_IN_CDB, 1, 1);
                kfree(arr);
@@ -1311,7 +1358,7 @@ static int resp_inquiry(struct scsi_cmnd *scp, struct 
sdebug_dev_info *devip)
                    (devip->channel & 0x7f);
                if (0 == scsi_debug_vpd_use_hostno)
                        host_no = 0;
-               lu_id_num = have_wlun ? -1 : (((host_no + 1) * 2000) +
+               lu_id_num = is_wlun ? -1 : (((host_no + 1) * 2000) +
                            (devip->target * 1000) + devip->lun);
                target_dev_id = ((host_no + 1) * 2000) +
                                 (devip->target * 1000) - 3;
@@ -3369,7 +3416,7 @@ static int resp_report_luns(struct scsi_cmnd *scp,
 
        /* report w_lun */
        if (select_report == 0x01 || select_report == 0x02)
-               wlun_cnt = 1;
+               wlun_cnt = scsi_debug_w_luns_count;
 
        rlun_cnt = lun_cnt + wlun_cnt;
 
@@ -3401,9 +3448,11 @@ static int resp_report_luns(struct scsi_cmnd *scp,
        for (i = 0; i < lun_cnt; i++)
                int_to_scsilun(lun++, one_lun++);
 
-       /* report SCSI_W_LUN_REPORT_LUN */
-       if (wlun_cnt)
-               int_to_scsilun(SCSI_W_LUN_REPORT_LUNS, one_lun++);
+       /* report WLUNs*/
+       for (i = 0; i < wlun_cnt; i++) {
+               lun = SCSI_W_LUN_BASE | scsi_debug_w_luns[i];
+               int_to_scsilun(lun, one_lun++);
+       }
 
        rlen = rlun_cnt * sizeof(struct scsi_lun);
 
@@ -5183,7 +5232,7 @@ scsi_debug_queuecommand(struct scsi_cmnd *scp)
        u32 flags;
        u16 sa;
        u8 opcode = cmd[0];
-       bool has_wlun_rl;
+       bool is_wlun;
        bool debug = !!(SCSI_DEBUG_OPT_NOISE & scsi_debug_opts);
 
        scsi_set_resid(scp, 0);
@@ -5202,8 +5251,8 @@ scsi_debug_queuecommand(struct scsi_cmnd *scp)
                }
                sdev_printk(KERN_INFO, sdp, "%s: cmd %s\n", my_name, b);
        }
-       has_wlun_rl = (sdp->lun == SCSI_W_LUN_REPORT_LUNS);
-       if ((sdp->lun >= scsi_debug_max_luns) && !has_wlun_rl)
+       is_wlun = scsi_is_wlun(sdp->lun);
+       if ((sdp->lun >= scsi_debug_max_luns) && !is_wlun)
                return schedule_resp(scp, NULL, errsts_no_connect, 0);
 
        sdeb_i = opcode_ind_arr[opcode];        /* fully mapped */
@@ -5248,7 +5297,7 @@ scsi_debug_queuecommand(struct scsi_cmnd *scp)
                mk_sense_invalid_opcode(scp);
                goto check_cond;
        }
-       if (has_wlun_rl && !(F_RL_WLUN_OK & flags)) {
+       if (is_wlun && !(F_RL_WLUN_OK & flags)) {
                if (debug)
                        sdev_printk(KERN_INFO, sdp, "scsi_debug: Opcode: "
                                    "0x%x not supported for wlun\n", opcode);
@@ -5356,7 +5405,6 @@ static int sdebug_driver_probe(struct device * dev)
        int host_prot;
 
        sdbg_host = to_sdebug_host(dev);
-
        sdebug_driver_template.can_queue = scsi_debug_max_queue;
        if (scsi_debug_clustering)
                sdebug_driver_template.use_clustering = ENABLE_CLUSTERING;
@@ -5367,14 +5415,18 @@ static int sdebug_driver_probe(struct device * dev)
                return error;
        }
 
+
         sdbg_host->shost = hpnt;
        *((struct sdebug_host_info **)hpnt->hostdata) = sdbg_host;
        if ((hpnt->this_id >= 0) && (scsi_debug_num_tgts > hpnt->this_id))
                hpnt->max_id = scsi_debug_num_tgts + 1;
        else
                hpnt->max_id = scsi_debug_num_tgts;
-       /* = scsi_debug_max_luns; */
-       hpnt->max_lun = SCSI_W_LUN_REPORT_LUNS + 1;
+
+       /* REPORT LUNS */
+       sdebug_register_w_lun(0x01);
+
+       hpnt->max_lun = sdebug_max_luns();
 
        host_prot = 0;
 
@@ -5435,11 +5487,18 @@ static int sdebug_driver_probe(struct device * dev)
         error = scsi_add_host(hpnt, &sdbg_host->dev);
         if (error) {
                pr_err("scsi_add_host failed\n");
-                error = -ENODEV;
-               scsi_host_put(hpnt);
-        } else
-               scsi_scan_host(hpnt);
+               error = -ENODEV;
+               goto err;
+       }
+
+       scsi_scan_host(hpnt);
+
+       error = sdebug_add_w_luns(hpnt);
+       if (error)
+               scsi_remove_host(hpnt);
 
+err:
+       scsi_host_put(hpnt);
        return error;
 }
 
-- 
1.9.3

--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to