scsi_debug: use likely hints on fast path
The most common commands in normal use are the READ and WRITE SCSI commands. Use likely and unlikely hints along the path taken by these commands. Rename check_readiness() to make_ua() and remove associated dead code. Rename devInfoReg() to find_build_dev_info(). Signed-off-by: Douglas Gilbert <dgilbert@interlog.com> Reviewed-by: Hannes Reinicke <hare@suse.de> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
This commit is contained in:
parent
fd32119b0d
commit
f46eb0e9fc
|
@ -190,10 +190,6 @@ static const char *sdebug_version_date = "20160422";
|
||||||
#define SDEBUG_UA_MICROCODE_CHANGED_WO_RESET 6
|
#define SDEBUG_UA_MICROCODE_CHANGED_WO_RESET 6
|
||||||
#define SDEBUG_NUM_UAS 7
|
#define SDEBUG_NUM_UAS 7
|
||||||
|
|
||||||
/* for check_readiness() */
|
|
||||||
#define UAS_ONLY 1 /* check for UAs only */
|
|
||||||
#define UAS_TUR 0 /* if no UAs then check if media access possible */
|
|
||||||
|
|
||||||
/* when 1==SDEBUG_OPT_MEDIUM_ERR, a medium error is simulated at this
|
/* when 1==SDEBUG_OPT_MEDIUM_ERR, a medium error is simulated at this
|
||||||
* sector on read commands: */
|
* sector on read commands: */
|
||||||
#define OPT_MEDIUM_ERR_ADDR 0x1234 /* that's sector 4660 in decimal */
|
#define OPT_MEDIUM_ERR_ADDR 0x1234 /* that's sector 4660 in decimal */
|
||||||
|
@ -595,6 +591,7 @@ static bool sdebug_host_lock = DEF_HOST_LOCK;
|
||||||
static bool sdebug_strict = DEF_STRICT;
|
static bool sdebug_strict = DEF_STRICT;
|
||||||
static bool sdebug_any_injecting_opt;
|
static bool sdebug_any_injecting_opt;
|
||||||
static bool sdebug_verbose;
|
static bool sdebug_verbose;
|
||||||
|
static bool have_dif_prot;
|
||||||
|
|
||||||
static atomic_t sdebug_cmnd_count;
|
static atomic_t sdebug_cmnd_count;
|
||||||
static atomic_t sdebug_completions;
|
static atomic_t sdebug_completions;
|
||||||
|
@ -793,8 +790,7 @@ static void clear_luns_changed_on_target(struct sdebug_dev_info *devip)
|
||||||
spin_unlock(&sdebug_host_list_lock);
|
spin_unlock(&sdebug_host_list_lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int check_readiness(struct scsi_cmnd *SCpnt, int uas_only,
|
static int make_ua(struct scsi_cmnd *scp, struct sdebug_dev_info *devip)
|
||||||
struct sdebug_dev_info * devip)
|
|
||||||
{
|
{
|
||||||
int k;
|
int k;
|
||||||
|
|
||||||
|
@ -804,37 +800,37 @@ static int check_readiness(struct scsi_cmnd *SCpnt, int uas_only,
|
||||||
|
|
||||||
switch (k) {
|
switch (k) {
|
||||||
case SDEBUG_UA_POR:
|
case SDEBUG_UA_POR:
|
||||||
mk_sense_buffer(SCpnt, UNIT_ATTENTION,
|
mk_sense_buffer(scp, UNIT_ATTENTION, UA_RESET_ASC,
|
||||||
UA_RESET_ASC, POWER_ON_RESET_ASCQ);
|
POWER_ON_RESET_ASCQ);
|
||||||
if (sdebug_verbose)
|
if (sdebug_verbose)
|
||||||
cp = "power on reset";
|
cp = "power on reset";
|
||||||
break;
|
break;
|
||||||
case SDEBUG_UA_BUS_RESET:
|
case SDEBUG_UA_BUS_RESET:
|
||||||
mk_sense_buffer(SCpnt, UNIT_ATTENTION,
|
mk_sense_buffer(scp, UNIT_ATTENTION, UA_RESET_ASC,
|
||||||
UA_RESET_ASC, BUS_RESET_ASCQ);
|
BUS_RESET_ASCQ);
|
||||||
if (sdebug_verbose)
|
if (sdebug_verbose)
|
||||||
cp = "bus reset";
|
cp = "bus reset";
|
||||||
break;
|
break;
|
||||||
case SDEBUG_UA_MODE_CHANGED:
|
case SDEBUG_UA_MODE_CHANGED:
|
||||||
mk_sense_buffer(SCpnt, UNIT_ATTENTION,
|
mk_sense_buffer(scp, UNIT_ATTENTION, UA_CHANGED_ASC,
|
||||||
UA_CHANGED_ASC, MODE_CHANGED_ASCQ);
|
MODE_CHANGED_ASCQ);
|
||||||
if (sdebug_verbose)
|
if (sdebug_verbose)
|
||||||
cp = "mode parameters changed";
|
cp = "mode parameters changed";
|
||||||
break;
|
break;
|
||||||
case SDEBUG_UA_CAPACITY_CHANGED:
|
case SDEBUG_UA_CAPACITY_CHANGED:
|
||||||
mk_sense_buffer(SCpnt, UNIT_ATTENTION,
|
mk_sense_buffer(scp, UNIT_ATTENTION, UA_CHANGED_ASC,
|
||||||
UA_CHANGED_ASC, CAPACITY_CHANGED_ASCQ);
|
CAPACITY_CHANGED_ASCQ);
|
||||||
if (sdebug_verbose)
|
if (sdebug_verbose)
|
||||||
cp = "capacity data changed";
|
cp = "capacity data changed";
|
||||||
break;
|
break;
|
||||||
case SDEBUG_UA_MICROCODE_CHANGED:
|
case SDEBUG_UA_MICROCODE_CHANGED:
|
||||||
mk_sense_buffer(SCpnt, UNIT_ATTENTION,
|
mk_sense_buffer(scp, UNIT_ATTENTION,
|
||||||
TARGET_CHANGED_ASC, MICROCODE_CHANGED_ASCQ);
|
TARGET_CHANGED_ASC, MICROCODE_CHANGED_ASCQ);
|
||||||
if (sdebug_verbose)
|
if (sdebug_verbose)
|
||||||
cp = "microcode has been changed";
|
cp = "microcode has been changed";
|
||||||
break;
|
break;
|
||||||
case SDEBUG_UA_MICROCODE_CHANGED_WO_RESET:
|
case SDEBUG_UA_MICROCODE_CHANGED_WO_RESET:
|
||||||
mk_sense_buffer(SCpnt, UNIT_ATTENTION,
|
mk_sense_buffer(scp, UNIT_ATTENTION,
|
||||||
TARGET_CHANGED_ASC,
|
TARGET_CHANGED_ASC,
|
||||||
MICROCODE_CHANGED_WO_RESET_ASCQ);
|
MICROCODE_CHANGED_WO_RESET_ASCQ);
|
||||||
if (sdebug_verbose)
|
if (sdebug_verbose)
|
||||||
|
@ -851,7 +847,7 @@ static int check_readiness(struct scsi_cmnd *SCpnt, int uas_only,
|
||||||
*/
|
*/
|
||||||
if (sdebug_scsi_level >= 6) /* SPC-4 and above */
|
if (sdebug_scsi_level >= 6) /* SPC-4 and above */
|
||||||
clear_luns_changed_on_target(devip);
|
clear_luns_changed_on_target(devip);
|
||||||
mk_sense_buffer(SCpnt, UNIT_ATTENTION,
|
mk_sense_buffer(scp, UNIT_ATTENTION,
|
||||||
TARGET_CHANGED_ASC,
|
TARGET_CHANGED_ASC,
|
||||||
LUNS_CHANGED_ASCQ);
|
LUNS_CHANGED_ASCQ);
|
||||||
if (sdebug_verbose)
|
if (sdebug_verbose)
|
||||||
|
@ -865,20 +861,11 @@ static int check_readiness(struct scsi_cmnd *SCpnt, int uas_only,
|
||||||
}
|
}
|
||||||
clear_bit(k, devip->uas_bm);
|
clear_bit(k, devip->uas_bm);
|
||||||
if (sdebug_verbose)
|
if (sdebug_verbose)
|
||||||
sdev_printk(KERN_INFO, SCpnt->device,
|
sdev_printk(KERN_INFO, scp->device,
|
||||||
"%s reports: Unit attention: %s\n",
|
"%s reports: Unit attention: %s\n",
|
||||||
my_name, cp);
|
my_name, cp);
|
||||||
return check_condition_result;
|
return check_condition_result;
|
||||||
}
|
}
|
||||||
if ((UAS_TUR == uas_only) && devip->stopped) {
|
|
||||||
mk_sense_buffer(SCpnt, NOT_READY, LOGICAL_UNIT_NOT_READY,
|
|
||||||
0x2);
|
|
||||||
if (sdebug_verbose)
|
|
||||||
sdev_printk(KERN_INFO, SCpnt->device,
|
|
||||||
"%s reports: Not ready: %s\n", my_name,
|
|
||||||
"initializing command required");
|
|
||||||
return check_condition_result;
|
|
||||||
}
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1345,7 +1332,7 @@ static int resp_inquiry(struct scsi_cmnd *scp, struct sdebug_dev_info *devip)
|
||||||
arr[2] = sdebug_scsi_level;
|
arr[2] = sdebug_scsi_level;
|
||||||
arr[3] = 2; /* response_data_format==2 */
|
arr[3] = 2; /* response_data_format==2 */
|
||||||
arr[4] = SDEBUG_LONG_INQ_SZ - 5;
|
arr[4] = SDEBUG_LONG_INQ_SZ - 5;
|
||||||
arr[5] = sdebug_dif ? 1 : 0; /* PROTECT bit */
|
arr[5] = (int)have_dif_prot; /* PROTECT bit */
|
||||||
if (0 == sdebug_vpd_use_hostno)
|
if (0 == sdebug_vpd_use_hostno)
|
||||||
arr[5] = 0x10; /* claim: implicit TGPS */
|
arr[5] = 0x10; /* claim: implicit TGPS */
|
||||||
arr[6] = 0x10; /* claim: MultiP */
|
arr[6] = 0x10; /* claim: MultiP */
|
||||||
|
@ -2506,7 +2493,7 @@ static int resp_read_dt0(struct scsi_cmnd *scp, struct sdebug_dev_info *devip)
|
||||||
check_prot = false;
|
check_prot = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (check_prot) {
|
if (unlikely(have_dif_prot && check_prot)) {
|
||||||
if (sdebug_dif == SD_DIF_TYPE2_PROTECTION &&
|
if (sdebug_dif == SD_DIF_TYPE2_PROTECTION &&
|
||||||
(cmd[1] & 0xe0)) {
|
(cmd[1] & 0xe0)) {
|
||||||
mk_sense_invalid_opcode(scp);
|
mk_sense_invalid_opcode(scp);
|
||||||
|
@ -2518,7 +2505,7 @@ static int resp_read_dt0(struct scsi_cmnd *scp, struct sdebug_dev_info *devip)
|
||||||
sdev_printk(KERN_ERR, scp->device, "Unprotected RD "
|
sdev_printk(KERN_ERR, scp->device, "Unprotected RD "
|
||||||
"to DIF device\n");
|
"to DIF device\n");
|
||||||
}
|
}
|
||||||
if (sdebug_any_injecting_opt) {
|
if (unlikely(sdebug_any_injecting_opt)) {
|
||||||
struct sdebug_scmd_extra_t *ep = scsi_cmd_priv(scp);
|
struct sdebug_scmd_extra_t *ep = scsi_cmd_priv(scp);
|
||||||
|
|
||||||
if (ep->inj_short)
|
if (ep->inj_short)
|
||||||
|
@ -2526,20 +2513,20 @@ static int resp_read_dt0(struct scsi_cmnd *scp, struct sdebug_dev_info *devip)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* inline check_device_access_params() */
|
/* inline check_device_access_params() */
|
||||||
if (lba + num > sdebug_capacity) {
|
if (unlikely(lba + num > sdebug_capacity)) {
|
||||||
mk_sense_buffer(scp, ILLEGAL_REQUEST, LBA_OUT_OF_RANGE, 0);
|
mk_sense_buffer(scp, ILLEGAL_REQUEST, LBA_OUT_OF_RANGE, 0);
|
||||||
return check_condition_result;
|
return check_condition_result;
|
||||||
}
|
}
|
||||||
/* transfer length excessive (tie in to block limits VPD page) */
|
/* transfer length excessive (tie in to block limits VPD page) */
|
||||||
if (num > sdebug_store_sectors) {
|
if (unlikely(num > sdebug_store_sectors)) {
|
||||||
/* needs work to find which cdb byte 'num' comes from */
|
/* needs work to find which cdb byte 'num' comes from */
|
||||||
mk_sense_buffer(scp, ILLEGAL_REQUEST, INVALID_FIELD_IN_CDB, 0);
|
mk_sense_buffer(scp, ILLEGAL_REQUEST, INVALID_FIELD_IN_CDB, 0);
|
||||||
return check_condition_result;
|
return check_condition_result;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((SDEBUG_OPT_MEDIUM_ERR & sdebug_opts) &&
|
if (unlikely((SDEBUG_OPT_MEDIUM_ERR & sdebug_opts) &&
|
||||||
(lba <= (OPT_MEDIUM_ERR_ADDR + OPT_MEDIUM_ERR_NUM - 1)) &&
|
(lba <= (OPT_MEDIUM_ERR_ADDR + OPT_MEDIUM_ERR_NUM - 1)) &&
|
||||||
((lba + num) > OPT_MEDIUM_ERR_ADDR)) {
|
((lba + num) > OPT_MEDIUM_ERR_ADDR))) {
|
||||||
/* claim unrecoverable read error */
|
/* claim unrecoverable read error */
|
||||||
mk_sense_buffer(scp, MEDIUM_ERROR, UNRECOVERED_READ_ERR, 0);
|
mk_sense_buffer(scp, MEDIUM_ERROR, UNRECOVERED_READ_ERR, 0);
|
||||||
/* set info field and valid bit for fixed descriptor */
|
/* set info field and valid bit for fixed descriptor */
|
||||||
|
@ -2556,7 +2543,7 @@ static int resp_read_dt0(struct scsi_cmnd *scp, struct sdebug_dev_info *devip)
|
||||||
read_lock_irqsave(&atomic_rw, iflags);
|
read_lock_irqsave(&atomic_rw, iflags);
|
||||||
|
|
||||||
/* DIX + T10 DIF */
|
/* DIX + T10 DIF */
|
||||||
if (sdebug_dix && scsi_prot_sg_count(scp)) {
|
if (unlikely(sdebug_dix && scsi_prot_sg_count(scp))) {
|
||||||
int prot_ret = prot_verify_read(scp, lba, num, ei_lba);
|
int prot_ret = prot_verify_read(scp, lba, num, ei_lba);
|
||||||
|
|
||||||
if (prot_ret) {
|
if (prot_ret) {
|
||||||
|
@ -2568,12 +2555,12 @@ static int resp_read_dt0(struct scsi_cmnd *scp, struct sdebug_dev_info *devip)
|
||||||
|
|
||||||
ret = do_device_access(scp, lba, num, false);
|
ret = do_device_access(scp, lba, num, false);
|
||||||
read_unlock_irqrestore(&atomic_rw, iflags);
|
read_unlock_irqrestore(&atomic_rw, iflags);
|
||||||
if (ret == -1)
|
if (unlikely(ret == -1))
|
||||||
return DID_ERROR << 16;
|
return DID_ERROR << 16;
|
||||||
|
|
||||||
scsi_in(scp)->resid = scsi_bufflen(scp) - ret;
|
scsi_in(scp)->resid = scsi_bufflen(scp) - ret;
|
||||||
|
|
||||||
if (sdebug_any_injecting_opt) {
|
if (unlikely(sdebug_any_injecting_opt)) {
|
||||||
struct sdebug_scmd_extra_t *ep = scsi_cmd_priv(scp);
|
struct sdebug_scmd_extra_t *ep = scsi_cmd_priv(scp);
|
||||||
|
|
||||||
if (ep->inj_recovered) {
|
if (ep->inj_recovered) {
|
||||||
|
@ -2817,7 +2804,7 @@ static int resp_write_dt0(struct scsi_cmnd *scp, struct sdebug_dev_info *devip)
|
||||||
check_prot = false;
|
check_prot = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (check_prot) {
|
if (unlikely(have_dif_prot && check_prot)) {
|
||||||
if (sdebug_dif == SD_DIF_TYPE2_PROTECTION &&
|
if (sdebug_dif == SD_DIF_TYPE2_PROTECTION &&
|
||||||
(cmd[1] & 0xe0)) {
|
(cmd[1] & 0xe0)) {
|
||||||
mk_sense_invalid_opcode(scp);
|
mk_sense_invalid_opcode(scp);
|
||||||
|
@ -2831,12 +2818,12 @@ static int resp_write_dt0(struct scsi_cmnd *scp, struct sdebug_dev_info *devip)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* inline check_device_access_params() */
|
/* inline check_device_access_params() */
|
||||||
if (lba + num > sdebug_capacity) {
|
if (unlikely(lba + num > sdebug_capacity)) {
|
||||||
mk_sense_buffer(scp, ILLEGAL_REQUEST, LBA_OUT_OF_RANGE, 0);
|
mk_sense_buffer(scp, ILLEGAL_REQUEST, LBA_OUT_OF_RANGE, 0);
|
||||||
return check_condition_result;
|
return check_condition_result;
|
||||||
}
|
}
|
||||||
/* transfer length excessive (tie in to block limits VPD page) */
|
/* transfer length excessive (tie in to block limits VPD page) */
|
||||||
if (num > sdebug_store_sectors) {
|
if (unlikely(num > sdebug_store_sectors)) {
|
||||||
/* needs work to find which cdb byte 'num' comes from */
|
/* needs work to find which cdb byte 'num' comes from */
|
||||||
mk_sense_buffer(scp, ILLEGAL_REQUEST, INVALID_FIELD_IN_CDB, 0);
|
mk_sense_buffer(scp, ILLEGAL_REQUEST, INVALID_FIELD_IN_CDB, 0);
|
||||||
return check_condition_result;
|
return check_condition_result;
|
||||||
|
@ -2845,7 +2832,7 @@ static int resp_write_dt0(struct scsi_cmnd *scp, struct sdebug_dev_info *devip)
|
||||||
write_lock_irqsave(&atomic_rw, iflags);
|
write_lock_irqsave(&atomic_rw, iflags);
|
||||||
|
|
||||||
/* DIX + T10 DIF */
|
/* DIX + T10 DIF */
|
||||||
if (sdebug_dix && scsi_prot_sg_count(scp)) {
|
if (unlikely(sdebug_dix && scsi_prot_sg_count(scp))) {
|
||||||
int prot_ret = prot_verify_write(scp, lba, num, ei_lba);
|
int prot_ret = prot_verify_write(scp, lba, num, ei_lba);
|
||||||
|
|
||||||
if (prot_ret) {
|
if (prot_ret) {
|
||||||
|
@ -2856,17 +2843,17 @@ static int resp_write_dt0(struct scsi_cmnd *scp, struct sdebug_dev_info *devip)
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = do_device_access(scp, lba, num, true);
|
ret = do_device_access(scp, lba, num, true);
|
||||||
if (scsi_debug_lbp())
|
if (unlikely(scsi_debug_lbp()))
|
||||||
map_region(lba, num);
|
map_region(lba, num);
|
||||||
write_unlock_irqrestore(&atomic_rw, iflags);
|
write_unlock_irqrestore(&atomic_rw, iflags);
|
||||||
if (-1 == ret)
|
if (unlikely(-1 == ret))
|
||||||
return DID_ERROR << 16;
|
return DID_ERROR << 16;
|
||||||
else if (sdebug_verbose && (ret < (num * sdebug_sector_size)))
|
else if (sdebug_verbose && (ret < (num * sdebug_sector_size)))
|
||||||
sdev_printk(KERN_INFO, scp->device,
|
sdev_printk(KERN_INFO, scp->device,
|
||||||
"%s: write: cdb indicated=%u, IO sent=%d bytes\n",
|
"%s: write: cdb indicated=%u, IO sent=%d bytes\n",
|
||||||
my_name, num * sdebug_sector_size, ret);
|
my_name, num * sdebug_sector_size, ret);
|
||||||
|
|
||||||
if (sdebug_any_injecting_opt) {
|
if (unlikely(sdebug_any_injecting_opt)) {
|
||||||
struct sdebug_scmd_extra_t *ep = scsi_cmd_priv(scp);
|
struct sdebug_scmd_extra_t *ep = scsi_cmd_priv(scp);
|
||||||
|
|
||||||
if (ep->inj_recovered) {
|
if (ep->inj_recovered) {
|
||||||
|
@ -3351,28 +3338,28 @@ static void sdebug_q_cmd_complete(struct sdebug_defer *sd_dp)
|
||||||
|
|
||||||
atomic_inc(&sdebug_completions);
|
atomic_inc(&sdebug_completions);
|
||||||
qa_indx = sd_dp->qa_indx;
|
qa_indx = sd_dp->qa_indx;
|
||||||
if ((qa_indx < 0) || (qa_indx >= SCSI_DEBUG_CANQUEUE)) {
|
if (unlikely((qa_indx < 0) || (qa_indx >= SCSI_DEBUG_CANQUEUE))) {
|
||||||
pr_err("wild qa_indx=%d\n", qa_indx);
|
pr_err("wild qa_indx=%d\n", qa_indx);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
spin_lock_irqsave(&queued_arr_lock, iflags);
|
spin_lock_irqsave(&queued_arr_lock, iflags);
|
||||||
sqcp = &queued_arr[qa_indx];
|
sqcp = &queued_arr[qa_indx];
|
||||||
scp = sqcp->a_cmnd;
|
scp = sqcp->a_cmnd;
|
||||||
if (NULL == scp) {
|
if (unlikely(NULL == scp)) {
|
||||||
spin_unlock_irqrestore(&queued_arr_lock, iflags);
|
spin_unlock_irqrestore(&queued_arr_lock, iflags);
|
||||||
pr_err("scp is NULL\n");
|
pr_err("scp is NULL\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
devip = (struct sdebug_dev_info *)scp->device->hostdata;
|
devip = (struct sdebug_dev_info *)scp->device->hostdata;
|
||||||
if (devip)
|
if (likely(devip))
|
||||||
atomic_dec(&devip->num_in_q);
|
atomic_dec(&devip->num_in_q);
|
||||||
else
|
else
|
||||||
pr_err("devip=NULL\n");
|
pr_err("devip=NULL\n");
|
||||||
if (atomic_read(&retired_max_queue) > 0)
|
if (unlikely(atomic_read(&retired_max_queue) > 0))
|
||||||
retiring = 1;
|
retiring = 1;
|
||||||
|
|
||||||
sqcp->a_cmnd = NULL;
|
sqcp->a_cmnd = NULL;
|
||||||
if (!test_and_clear_bit(qa_indx, queued_in_use_bm)) {
|
if (unlikely(!test_and_clear_bit(qa_indx, queued_in_use_bm))) {
|
||||||
spin_unlock_irqrestore(&queued_arr_lock, iflags);
|
spin_unlock_irqrestore(&queued_arr_lock, iflags);
|
||||||
pr_err("Unexpected completion\n");
|
pr_err("Unexpected completion\n");
|
||||||
return;
|
return;
|
||||||
|
@ -3427,15 +3414,12 @@ static struct sdebug_dev_info *sdebug_device_create(
|
||||||
return devip;
|
return devip;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct sdebug_dev_info * devInfoReg(struct scsi_device * sdev)
|
static struct sdebug_dev_info *find_build_dev_info(struct scsi_device *sdev)
|
||||||
{
|
{
|
||||||
struct sdebug_host_info * sdbg_host;
|
struct sdebug_host_info *sdbg_host;
|
||||||
struct sdebug_dev_info * open_devip = NULL;
|
struct sdebug_dev_info *open_devip = NULL;
|
||||||
struct sdebug_dev_info * devip =
|
struct sdebug_dev_info *devip;
|
||||||
(struct sdebug_dev_info *)sdev->hostdata;
|
|
||||||
|
|
||||||
if (devip)
|
|
||||||
return devip;
|
|
||||||
sdbg_host = *(struct sdebug_host_info **)shost_priv(sdev->host);
|
sdbg_host = *(struct sdebug_host_info **)shost_priv(sdev->host);
|
||||||
if (!sdbg_host) {
|
if (!sdbg_host) {
|
||||||
pr_err("Host info NULL\n");
|
pr_err("Host info NULL\n");
|
||||||
|
@ -3480,16 +3464,19 @@ static int scsi_debug_slave_alloc(struct scsi_device *sdp)
|
||||||
|
|
||||||
static int scsi_debug_slave_configure(struct scsi_device *sdp)
|
static int scsi_debug_slave_configure(struct scsi_device *sdp)
|
||||||
{
|
{
|
||||||
struct sdebug_dev_info *devip;
|
struct sdebug_dev_info *devip =
|
||||||
|
(struct sdebug_dev_info *)sdp->hostdata;
|
||||||
|
|
||||||
if (sdebug_verbose)
|
if (sdebug_verbose)
|
||||||
pr_info("slave_configure <%u %u %u %llu>\n",
|
pr_info("slave_configure <%u %u %u %llu>\n",
|
||||||
sdp->host->host_no, sdp->channel, sdp->id, sdp->lun);
|
sdp->host->host_no, sdp->channel, sdp->id, sdp->lun);
|
||||||
if (sdp->host->max_cmd_len != SCSI_DEBUG_MAX_CMD_LEN)
|
if (sdp->host->max_cmd_len != SCSI_DEBUG_MAX_CMD_LEN)
|
||||||
sdp->host->max_cmd_len = SCSI_DEBUG_MAX_CMD_LEN;
|
sdp->host->max_cmd_len = SCSI_DEBUG_MAX_CMD_LEN;
|
||||||
devip = devInfoReg(sdp);
|
if (NULL == devip) {
|
||||||
if (NULL == devip)
|
devip = find_build_dev_info(sdp);
|
||||||
return 1; /* no resources, will be marked offline */
|
if (NULL == devip)
|
||||||
|
return 1; /* no resources, will be marked offline */
|
||||||
|
}
|
||||||
sdp->hostdata = devip;
|
sdp->hostdata = devip;
|
||||||
blk_queue_max_segment_size(sdp->request_queue, -1U);
|
blk_queue_max_segment_size(sdp->request_queue, -1U);
|
||||||
if (sdebug_no_uld)
|
if (sdebug_no_uld)
|
||||||
|
@ -3622,15 +3609,14 @@ static int scsi_debug_abort(struct scsi_cmnd *SCpnt)
|
||||||
|
|
||||||
static int scsi_debug_device_reset(struct scsi_cmnd * SCpnt)
|
static int scsi_debug_device_reset(struct scsi_cmnd * SCpnt)
|
||||||
{
|
{
|
||||||
struct sdebug_dev_info * devip;
|
|
||||||
|
|
||||||
++num_dev_resets;
|
++num_dev_resets;
|
||||||
if (SCpnt && SCpnt->device) {
|
if (SCpnt && SCpnt->device) {
|
||||||
struct scsi_device *sdp = SCpnt->device;
|
struct scsi_device *sdp = SCpnt->device;
|
||||||
|
struct sdebug_dev_info *devip =
|
||||||
|
(struct sdebug_dev_info *)sdp->hostdata;
|
||||||
|
|
||||||
if (SDEBUG_OPT_ALL_NOISE & sdebug_opts)
|
if (SDEBUG_OPT_ALL_NOISE & sdebug_opts)
|
||||||
sdev_printk(KERN_INFO, sdp, "%s\n", __func__);
|
sdev_printk(KERN_INFO, sdp, "%s\n", __func__);
|
||||||
devip = devInfoReg(sdp);
|
|
||||||
if (devip)
|
if (devip)
|
||||||
set_bit(SDEBUG_UA_POR, devip->uas_bm);
|
set_bit(SDEBUG_UA_POR, devip->uas_bm);
|
||||||
}
|
}
|
||||||
|
@ -3790,19 +3776,18 @@ static int schedule_resp(struct scsi_cmnd *cmnd, struct sdebug_dev_info *devip,
|
||||||
struct scsi_device *sdp;
|
struct scsi_device *sdp;
|
||||||
struct sdebug_defer *sd_dp;
|
struct sdebug_defer *sd_dp;
|
||||||
|
|
||||||
/* this should never happen */
|
if (unlikely(WARN_ON(!cmnd)))
|
||||||
if (WARN_ON(!cmnd))
|
|
||||||
return SCSI_MLQUEUE_HOST_BUSY;
|
return SCSI_MLQUEUE_HOST_BUSY;
|
||||||
|
|
||||||
if (NULL == devip) {
|
if (unlikely(NULL == devip)) {
|
||||||
pr_warn("called devip == NULL\n");
|
if (0 == scsi_result)
|
||||||
/* no particularly good error to report back */
|
scsi_result = DID_NO_CONNECT << 16;
|
||||||
return SCSI_MLQUEUE_HOST_BUSY;
|
goto respond_in_thread;
|
||||||
}
|
}
|
||||||
|
|
||||||
sdp = cmnd->device;
|
sdp = cmnd->device;
|
||||||
|
|
||||||
if (sdebug_verbose && scsi_result)
|
if (unlikely(sdebug_verbose && scsi_result))
|
||||||
sdev_printk(KERN_INFO, sdp, "%s: non-zero result=0x%x\n",
|
sdev_printk(KERN_INFO, sdp, "%s: non-zero result=0x%x\n",
|
||||||
__func__, scsi_result);
|
__func__, scsi_result);
|
||||||
if (delta_jiff == 0)
|
if (delta_jiff == 0)
|
||||||
|
@ -3813,15 +3798,15 @@ static int schedule_resp(struct scsi_cmnd *cmnd, struct sdebug_dev_info *devip,
|
||||||
num_in_q = atomic_read(&devip->num_in_q);
|
num_in_q = atomic_read(&devip->num_in_q);
|
||||||
qdepth = cmnd->device->queue_depth;
|
qdepth = cmnd->device->queue_depth;
|
||||||
inject = 0;
|
inject = 0;
|
||||||
if ((qdepth > 0) && (num_in_q >= qdepth)) {
|
if (unlikely((qdepth > 0) && (num_in_q >= qdepth))) {
|
||||||
if (scsi_result) {
|
if (scsi_result) {
|
||||||
spin_unlock_irqrestore(&queued_arr_lock, iflags);
|
spin_unlock_irqrestore(&queued_arr_lock, iflags);
|
||||||
goto respond_in_thread;
|
goto respond_in_thread;
|
||||||
} else
|
} else
|
||||||
scsi_result = device_qfull_result;
|
scsi_result = device_qfull_result;
|
||||||
} else if ((sdebug_every_nth != 0) &&
|
} else if (unlikely((sdebug_every_nth != 0) &&
|
||||||
(SDEBUG_OPT_RARE_TSF & sdebug_opts) &&
|
(SDEBUG_OPT_RARE_TSF & sdebug_opts) &&
|
||||||
(scsi_result == 0)) {
|
(scsi_result == 0))) {
|
||||||
if ((num_in_q == (qdepth - 1)) &&
|
if ((num_in_q == (qdepth - 1)) &&
|
||||||
(atomic_inc_return(&sdebug_a_tsf) >=
|
(atomic_inc_return(&sdebug_a_tsf) >=
|
||||||
abs(sdebug_every_nth))) {
|
abs(sdebug_every_nth))) {
|
||||||
|
@ -3832,7 +3817,7 @@ static int schedule_resp(struct scsi_cmnd *cmnd, struct sdebug_dev_info *devip,
|
||||||
}
|
}
|
||||||
|
|
||||||
k = find_first_zero_bit(queued_in_use_bm, sdebug_max_queue);
|
k = find_first_zero_bit(queued_in_use_bm, sdebug_max_queue);
|
||||||
if (k >= sdebug_max_queue) {
|
if (unlikely(k >= sdebug_max_queue)) {
|
||||||
spin_unlock_irqrestore(&queued_arr_lock, iflags);
|
spin_unlock_irqrestore(&queued_arr_lock, iflags);
|
||||||
if (scsi_result)
|
if (scsi_result)
|
||||||
goto respond_in_thread;
|
goto respond_in_thread;
|
||||||
|
@ -3888,8 +3873,8 @@ static int schedule_resp(struct scsi_cmnd *cmnd, struct sdebug_dev_info *devip,
|
||||||
}
|
}
|
||||||
schedule_work(&sd_dp->ew.work);
|
schedule_work(&sd_dp->ew.work);
|
||||||
}
|
}
|
||||||
if ((SDEBUG_OPT_Q_NOISE & sdebug_opts) &&
|
if (unlikely((SDEBUG_OPT_Q_NOISE & sdebug_opts) &&
|
||||||
(scsi_result == device_qfull_result))
|
(scsi_result == device_qfull_result)))
|
||||||
sdev_printk(KERN_INFO, sdp,
|
sdev_printk(KERN_INFO, sdp,
|
||||||
"%s: num_in_q=%d +1, %s%s\n", __func__,
|
"%s: num_in_q=%d +1, %s%s\n", __func__,
|
||||||
num_in_q, (inject ? "<inject> " : ""),
|
num_in_q, (inject ? "<inject> " : ""),
|
||||||
|
@ -4632,9 +4617,11 @@ static int __init scsi_debug_init(void)
|
||||||
switch (sdebug_dif) {
|
switch (sdebug_dif) {
|
||||||
|
|
||||||
case SD_DIF_TYPE0_PROTECTION:
|
case SD_DIF_TYPE0_PROTECTION:
|
||||||
|
break;
|
||||||
case SD_DIF_TYPE1_PROTECTION:
|
case SD_DIF_TYPE1_PROTECTION:
|
||||||
case SD_DIF_TYPE2_PROTECTION:
|
case SD_DIF_TYPE2_PROTECTION:
|
||||||
case SD_DIF_TYPE3_PROTECTION:
|
case SD_DIF_TYPE3_PROTECTION:
|
||||||
|
have_dif_prot = true;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
@ -4971,7 +4958,8 @@ static int scsi_debug_queuecommand(struct Scsi_Host *shost,
|
||||||
bool has_wlun_rl;
|
bool has_wlun_rl;
|
||||||
|
|
||||||
scsi_set_resid(scp, 0);
|
scsi_set_resid(scp, 0);
|
||||||
if (sdebug_verbose && !(SDEBUG_OPT_NO_CDB_NOISE & sdebug_opts)) {
|
if (unlikely(sdebug_verbose &&
|
||||||
|
!(SDEBUG_OPT_NO_CDB_NOISE & sdebug_opts))) {
|
||||||
char b[120];
|
char b[120];
|
||||||
int n, len, sb;
|
int n, len, sb;
|
||||||
|
|
||||||
|
@ -4987,17 +4975,16 @@ static int scsi_debug_queuecommand(struct Scsi_Host *shost,
|
||||||
sdev_printk(KERN_INFO, sdp, "%s: cmd %s\n", my_name, b);
|
sdev_printk(KERN_INFO, sdp, "%s: cmd %s\n", my_name, b);
|
||||||
}
|
}
|
||||||
has_wlun_rl = (sdp->lun == SCSI_W_LUN_REPORT_LUNS);
|
has_wlun_rl = (sdp->lun == SCSI_W_LUN_REPORT_LUNS);
|
||||||
if ((sdp->lun >= sdebug_max_luns) && !has_wlun_rl)
|
if (unlikely((sdp->lun >= sdebug_max_luns) && !has_wlun_rl))
|
||||||
return schedule_resp(scp, NULL, DID_NO_CONNECT << 16, 0);
|
goto err_out;
|
||||||
|
|
||||||
sdeb_i = opcode_ind_arr[opcode]; /* fully mapped */
|
sdeb_i = opcode_ind_arr[opcode]; /* fully mapped */
|
||||||
oip = &opcode_info_arr[sdeb_i]; /* safe if table consistent */
|
oip = &opcode_info_arr[sdeb_i]; /* safe if table consistent */
|
||||||
devip = (struct sdebug_dev_info *)sdp->hostdata;
|
devip = (struct sdebug_dev_info *)sdp->hostdata;
|
||||||
if (!devip) {
|
if (unlikely(!devip)) {
|
||||||
devip = devInfoReg(sdp);
|
devip = find_build_dev_info(sdp);
|
||||||
if (NULL == devip)
|
if (NULL == devip)
|
||||||
return schedule_resp(scp, NULL, DID_NO_CONNECT << 16,
|
goto err_out;
|
||||||
0);
|
|
||||||
}
|
}
|
||||||
na = oip->num_attached;
|
na = oip->num_attached;
|
||||||
r_pfp = oip->pfp;
|
r_pfp = oip->pfp;
|
||||||
|
@ -5029,18 +5016,18 @@ static int scsi_debug_queuecommand(struct Scsi_Host *shost,
|
||||||
}
|
}
|
||||||
} /* else (when na==0) we assume the oip is a match */
|
} /* else (when na==0) we assume the oip is a match */
|
||||||
flags = oip->flags;
|
flags = oip->flags;
|
||||||
if (F_INV_OP & flags) {
|
if (unlikely(F_INV_OP & flags)) {
|
||||||
mk_sense_invalid_opcode(scp);
|
mk_sense_invalid_opcode(scp);
|
||||||
goto check_cond;
|
goto check_cond;
|
||||||
}
|
}
|
||||||
if (has_wlun_rl && !(F_RL_WLUN_OK & flags)) {
|
if (unlikely(has_wlun_rl && !(F_RL_WLUN_OK & flags))) {
|
||||||
if (sdebug_verbose)
|
if (sdebug_verbose)
|
||||||
sdev_printk(KERN_INFO, sdp, "%s: Opcode 0x%x not%s\n",
|
sdev_printk(KERN_INFO, sdp, "%s: Opcode 0x%x not%s\n",
|
||||||
my_name, opcode, " supported for wlun");
|
my_name, opcode, " supported for wlun");
|
||||||
mk_sense_invalid_opcode(scp);
|
mk_sense_invalid_opcode(scp);
|
||||||
goto check_cond;
|
goto check_cond;
|
||||||
}
|
}
|
||||||
if (sdebug_strict) { /* check cdb against mask */
|
if (unlikely(sdebug_strict)) { /* check cdb against mask */
|
||||||
u8 rem;
|
u8 rem;
|
||||||
int j;
|
int j;
|
||||||
|
|
||||||
|
@ -5056,13 +5043,14 @@ static int scsi_debug_queuecommand(struct Scsi_Host *shost,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!(F_SKIP_UA & flags) &&
|
if (unlikely(!(F_SKIP_UA & flags) &&
|
||||||
SDEBUG_NUM_UAS != find_first_bit(devip->uas_bm, SDEBUG_NUM_UAS)) {
|
SDEBUG_NUM_UAS != find_first_bit(devip->uas_bm,
|
||||||
errsts = check_readiness(scp, UAS_ONLY, devip);
|
SDEBUG_NUM_UAS))) {
|
||||||
|
errsts = make_ua(scp, devip);
|
||||||
if (errsts)
|
if (errsts)
|
||||||
goto check_cond;
|
goto check_cond;
|
||||||
}
|
}
|
||||||
if ((F_M_ACCESS & flags) && devip->stopped) {
|
if (unlikely((F_M_ACCESS & flags) && devip->stopped)) {
|
||||||
mk_sense_buffer(scp, NOT_READY, LOGICAL_UNIT_NOT_READY, 0x2);
|
mk_sense_buffer(scp, NOT_READY, LOGICAL_UNIT_NOT_READY, 0x2);
|
||||||
if (sdebug_verbose)
|
if (sdebug_verbose)
|
||||||
sdev_printk(KERN_INFO, sdp, "%s reports: Not ready: "
|
sdev_printk(KERN_INFO, sdp, "%s reports: Not ready: "
|
||||||
|
@ -5073,12 +5061,12 @@ static int scsi_debug_queuecommand(struct Scsi_Host *shost,
|
||||||
}
|
}
|
||||||
if (sdebug_fake_rw && (F_FAKE_RW & flags))
|
if (sdebug_fake_rw && (F_FAKE_RW & flags))
|
||||||
goto fini;
|
goto fini;
|
||||||
if (sdebug_every_nth) {
|
if (unlikely(sdebug_every_nth)) {
|
||||||
if (check_inject(scp))
|
if (check_inject(scp))
|
||||||
return 0; /* ignore command: make trouble */
|
return 0; /* ignore command: make trouble */
|
||||||
}
|
}
|
||||||
if (oip->pfp) /* if this command has a resp_* function, call it */
|
if (likely(oip->pfp))
|
||||||
errsts = oip->pfp(scp, devip);
|
errsts = oip->pfp(scp, devip); /* calls a resp_* function */
|
||||||
else if (r_pfp) /* if leaf function ptr NULL, try the root's */
|
else if (r_pfp) /* if leaf function ptr NULL, try the root's */
|
||||||
errsts = r_pfp(scp, devip);
|
errsts = r_pfp(scp, devip);
|
||||||
|
|
||||||
|
@ -5087,6 +5075,8 @@ fini:
|
||||||
((F_DELAY_OVERR & flags) ? 0 : sdebug_jdelay));
|
((F_DELAY_OVERR & flags) ? 0 : sdebug_jdelay));
|
||||||
check_cond:
|
check_cond:
|
||||||
return schedule_resp(scp, devip, check_condition_result, 0);
|
return schedule_resp(scp, devip, check_condition_result, 0);
|
||||||
|
err_out:
|
||||||
|
return schedule_resp(scp, NULL, DID_NO_CONNECT << 16, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct scsi_host_template sdebug_driver_template = {
|
static struct scsi_host_template sdebug_driver_template = {
|
||||||
|
@ -5122,7 +5112,7 @@ static int sdebug_driver_probe(struct device * dev)
|
||||||
int error = 0;
|
int error = 0;
|
||||||
struct sdebug_host_info *sdbg_host;
|
struct sdebug_host_info *sdbg_host;
|
||||||
struct Scsi_Host *hpnt;
|
struct Scsi_Host *hpnt;
|
||||||
int host_prot;
|
int hprot;
|
||||||
|
|
||||||
sdbg_host = to_sdebug_host(dev);
|
sdbg_host = to_sdebug_host(dev);
|
||||||
|
|
||||||
|
@ -5145,44 +5135,45 @@ static int sdebug_driver_probe(struct device * dev)
|
||||||
/* = sdebug_max_luns; */
|
/* = sdebug_max_luns; */
|
||||||
hpnt->max_lun = SCSI_W_LUN_REPORT_LUNS + 1;
|
hpnt->max_lun = SCSI_W_LUN_REPORT_LUNS + 1;
|
||||||
|
|
||||||
host_prot = 0;
|
hprot = 0;
|
||||||
|
|
||||||
switch (sdebug_dif) {
|
switch (sdebug_dif) {
|
||||||
|
|
||||||
case SD_DIF_TYPE1_PROTECTION:
|
case SD_DIF_TYPE1_PROTECTION:
|
||||||
host_prot = SHOST_DIF_TYPE1_PROTECTION;
|
hprot = SHOST_DIF_TYPE1_PROTECTION;
|
||||||
if (sdebug_dix)
|
if (sdebug_dix)
|
||||||
host_prot |= SHOST_DIX_TYPE1_PROTECTION;
|
hprot |= SHOST_DIX_TYPE1_PROTECTION;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SD_DIF_TYPE2_PROTECTION:
|
case SD_DIF_TYPE2_PROTECTION:
|
||||||
host_prot = SHOST_DIF_TYPE2_PROTECTION;
|
hprot = SHOST_DIF_TYPE2_PROTECTION;
|
||||||
if (sdebug_dix)
|
if (sdebug_dix)
|
||||||
host_prot |= SHOST_DIX_TYPE2_PROTECTION;
|
hprot |= SHOST_DIX_TYPE2_PROTECTION;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SD_DIF_TYPE3_PROTECTION:
|
case SD_DIF_TYPE3_PROTECTION:
|
||||||
host_prot = SHOST_DIF_TYPE3_PROTECTION;
|
hprot = SHOST_DIF_TYPE3_PROTECTION;
|
||||||
if (sdebug_dix)
|
if (sdebug_dix)
|
||||||
host_prot |= SHOST_DIX_TYPE3_PROTECTION;
|
hprot |= SHOST_DIX_TYPE3_PROTECTION;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
if (sdebug_dix)
|
if (sdebug_dix)
|
||||||
host_prot |= SHOST_DIX_TYPE0_PROTECTION;
|
hprot |= SHOST_DIX_TYPE0_PROTECTION;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
scsi_host_set_prot(hpnt, host_prot);
|
scsi_host_set_prot(hpnt, hprot);
|
||||||
|
|
||||||
pr_info("host protection%s%s%s%s%s%s%s\n",
|
if (have_dif_prot || sdebug_dix)
|
||||||
(host_prot & SHOST_DIF_TYPE1_PROTECTION) ? " DIF1" : "",
|
pr_info("host protection%s%s%s%s%s%s%s\n",
|
||||||
(host_prot & SHOST_DIF_TYPE2_PROTECTION) ? " DIF2" : "",
|
(hprot & SHOST_DIF_TYPE1_PROTECTION) ? " DIF1" : "",
|
||||||
(host_prot & SHOST_DIF_TYPE3_PROTECTION) ? " DIF3" : "",
|
(hprot & SHOST_DIF_TYPE2_PROTECTION) ? " DIF2" : "",
|
||||||
(host_prot & SHOST_DIX_TYPE0_PROTECTION) ? " DIX0" : "",
|
(hprot & SHOST_DIF_TYPE3_PROTECTION) ? " DIF3" : "",
|
||||||
(host_prot & SHOST_DIX_TYPE1_PROTECTION) ? " DIX1" : "",
|
(hprot & SHOST_DIX_TYPE0_PROTECTION) ? " DIX0" : "",
|
||||||
(host_prot & SHOST_DIX_TYPE2_PROTECTION) ? " DIX2" : "",
|
(hprot & SHOST_DIX_TYPE1_PROTECTION) ? " DIX1" : "",
|
||||||
(host_prot & SHOST_DIX_TYPE3_PROTECTION) ? " DIX3" : "");
|
(hprot & SHOST_DIX_TYPE2_PROTECTION) ? " DIX2" : "",
|
||||||
|
(hprot & SHOST_DIX_TYPE3_PROTECTION) ? " DIX3" : "");
|
||||||
|
|
||||||
if (sdebug_guard == 1)
|
if (sdebug_guard == 1)
|
||||||
scsi_host_set_guard(hpnt, SHOST_DIX_GUARD_IP);
|
scsi_host_set_guard(hpnt, SHOST_DIX_GUARD_IP);
|
||||||
|
|
Loading…
Reference in New Issue