* SCSI_MLQUEUE_HOST_BUSY if temporarily out of resources.
*/
static int schedule_resp(struct scsi_cmnd *cmnd, struct sdebug_dev_info *devip,
- int scsi_result, int delta_jiff, int ndelay)
+ int scsi_result,
+ int (*pfp)(struct scsi_cmnd *,
+ struct sdebug_dev_info *),
+ int delta_jiff, int ndelay)
{
unsigned long iflags;
int k, num_in_q, qdepth, inject;
}
sdp = cmnd->device;
- if (unlikely(sdebug_verbose && scsi_result))
- sdev_printk(KERN_INFO, sdp, "%s: non-zero result=0x%x\n",
- __func__, scsi_result);
if (delta_jiff == 0)
goto respond_in_thread;
sqcp = &sqp->qc_arr[k];
sqcp->a_cmnd = cmnd;
cmnd->host_scribble = (unsigned char *)sqcp;
- cmnd->result = scsi_result;
sd_dp = sqcp->sd_dp;
spin_unlock_irqrestore(&sqp->qc_lock, iflags);
if (unlikely(sdebug_every_nth && sdebug_any_injecting_opt))
if (sd_dp == NULL)
return SCSI_MLQUEUE_HOST_BUSY;
}
+
+ cmnd->result = pfp != NULL ? pfp(cmnd, devip) : 0;
+ if (cmnd->result & SDEG_RES_IMMED_MASK) {
+ /*
+ * This is the F_DELAY_OVERR case. No delay.
+ */
+ cmnd->result &= ~SDEG_RES_IMMED_MASK;
+ delta_jiff = ndelay = 0;
+ }
+ if (cmnd->result == 0 && scsi_result != 0)
+ cmnd->result = scsi_result;
+
+ if (unlikely(sdebug_verbose && cmnd->result))
+ sdev_printk(KERN_INFO, sdp, "%s: non-zero result=0x%x\n",
+ __func__, cmnd->result);
+
if (delta_jiff > 0 || ndelay > 0) {
ktime_t kt;
return 0;
respond_in_thread: /* call back to mid-layer using invocation thread */
- cmnd->result = scsi_result;
+ cmnd->result = pfp != NULL ? pfp(cmnd, devip) : 0;
+ cmnd->result &= ~SDEG_RES_IMMED_MASK;
+ if (cmnd->result == 0 && scsi_result != 0)
+ cmnd->result = scsi_result;
cmnd->scsi_done(cmnd);
return 0;
}
struct sdebug_dev_info *devip;
u8 *cmd = scp->cmnd;
int (*r_pfp)(struct scsi_cmnd *, struct sdebug_dev_info *);
+ int (*pfp)(struct scsi_cmnd *, struct sdebug_dev_info *) = NULL;
int k, na;
int errsts = 0;
u32 flags;
return 0; /* ignore command: make trouble */
}
if (likely(oip->pfp))
- errsts = oip->pfp(scp, devip); /* calls a resp_* function */
- else if (r_pfp) /* if leaf function ptr NULL, try the root's */
- errsts = r_pfp(scp, devip);
- if (errsts & SDEG_RES_IMMED_MASK) {
- errsts &= ~SDEG_RES_IMMED_MASK;
- flags |= F_DELAY_OVERR;
- flags &= ~F_LONG_DELAY;
- }
-
+ pfp = oip->pfp; /* calls a resp_* function */
+ else
+ pfp = r_pfp; /* if leaf function ptr NULL, try the root's */
fini:
if (F_DELAY_OVERR & flags)
- return schedule_resp(scp, devip, errsts, 0, 0);
+ return schedule_resp(scp, devip, errsts, pfp, 0, 0);
else if ((sdebug_jdelay || sdebug_ndelay) && (flags & F_LONG_DELAY)) {
/*
* If any delay is active, want F_LONG_DELAY to be at least 1
int jdelay = (sdebug_jdelay < 2) ? 1 : sdebug_jdelay;
jdelay = mult_frac(USER_HZ * jdelay, HZ, USER_HZ);
- return schedule_resp(scp, devip, errsts, jdelay, 0);
+ return schedule_resp(scp, devip, errsts, pfp, jdelay, 0);
} else
- return schedule_resp(scp, devip, errsts, sdebug_jdelay,
+ return schedule_resp(scp, devip, errsts, pfp, sdebug_jdelay,
sdebug_ndelay);
check_cond:
- return schedule_resp(scp, devip, check_condition_result, 0, 0);
+ return schedule_resp(scp, devip, check_condition_result, NULL, 0, 0);
err_out:
- return schedule_resp(scp, NULL, DID_NO_CONNECT << 16, 0, 0);
+ return schedule_resp(scp, NULL, DID_NO_CONNECT << 16, NULL, 0, 0);
}
static struct scsi_host_template sdebug_driver_template = {