Partially merged r3194 and r3203 from the trunk.

git-svn-id: http://svn.code.sf.net/p/scst/svn/branches/2.0.0.x@3366 d57e44dd-8a1f-0410-8b47-8ef2f437770f
This commit is contained in:
Bart Van Assche
2011-04-07 19:45:38 +00:00
parent 36ddc9df2a
commit 8619defedc
+36 -14
View File
@@ -86,9 +86,6 @@ static unsigned long scst_local_trace_flag = SCST_LOCAL_DEFAULT_LOG_FLAGS;
#define scsi_bufflen(cmd) ((cmd)->request_bufflen)
#endif
#define TRUE 1
#define FALSE 0
#define SCST_LOCAL_VERSION "1.0.0"
static const char *scst_local_version_date = "20100910";
@@ -781,7 +778,7 @@ static int scst_local_abort(struct scsi_cmnd *SCpnt)
sess = to_scst_lcl_sess(scsi_get_device(SCpnt->device->host));
ret = scst_rx_mgmt_fn_tag(sess->scst_sess, SCST_ABORT_TASK, SCpnt->tag,
FALSE, &dev_reset_completion);
false, &dev_reset_completion);
/* Now wait for the completion ... */
wait_for_completion_interruptible(&dev_reset_completion);
@@ -810,7 +807,7 @@ static int scst_local_device_reset(struct scsi_cmnd *SCpnt)
lun = cpu_to_be16(lun);
ret = scst_rx_mgmt_fn_lun(sess->scst_sess, SCST_LUN_RESET,
(const uint8_t *)&lun, sizeof(lun), FALSE,
(const uint8_t *)&lun, sizeof(lun), false,
&dev_reset_completion);
/* Now wait for the completion ... */
@@ -841,7 +838,7 @@ static int scst_local_target_reset(struct scsi_cmnd *SCpnt)
lun = cpu_to_be16(lun);
ret = scst_rx_mgmt_fn_lun(sess->scst_sess, SCST_TARGET_RESET,
(const uint8_t *)&lun, sizeof(lun), FALSE,
(const uint8_t *)&lun, sizeof(lun), false,
&dev_reset_completion);
/* Now wait for the completion ... */
@@ -908,8 +905,8 @@ static int scst_local_send_resp(struct scsi_cmnd *cmnd,
* This does the heavy lifting ... we pass all the commands on to the
* target driver and have it do its magic ...
*/
static int scst_local_queuecommand(struct scsi_cmnd *SCpnt,
void (*done)(struct scsi_cmnd *))
static int scst_local_queuecommand_lck(struct scsi_cmnd *SCpnt,
void (*done)(struct scsi_cmnd *))
__acquires(&h->host_lock)
__releases(&h->host_lock)
{
@@ -940,11 +937,11 @@ static int scst_local_queuecommand(struct scsi_cmnd *SCpnt,
if (!tgt_specific) {
PRINT_ERROR("Unable to create tgt_specific (size %zu)",
sizeof(*tgt_specific));
return -ENOMEM;
return SCSI_MLQUEUE_HOST_BUSY;
}
tgt_specific->cmnd = SCpnt;
tgt_specific->done = done;
#else
#elif LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 37)
/*
* We save a pointer to the done routine in SCpnt->scsi_done and
* we save that as tgt specific stuff below.
@@ -955,14 +952,18 @@ static int scst_local_queuecommand(struct scsi_cmnd *SCpnt,
/*
* Tell the target that we have a command ... but first we need
* to get the LUN into a format that SCST understand
*
* NOTE! We need to call it with atomic parameter true to not
* get into mem alloc deadlock when mounting file systems over
* our devices.
*/
lun = SCpnt->device->lun;
lun = cpu_to_be16(lun);
scst_cmd = scst_rx_cmd(sess->scst_sess, (const uint8_t *)&lun,
sizeof(lun), SCpnt->cmnd, SCpnt->cmd_len, TRUE);
sizeof(lun), SCpnt->cmnd, SCpnt->cmd_len, true);
if (!scst_cmd) {
PRINT_ERROR("%s", "scst_rx_cmd() failed");
return -ENOMEM;
return SCSI_MLQUEUE_HOST_BUSY;
}
scst_cmd_set_tag(scst_cmd, SCpnt->tag);
@@ -1054,6 +1055,15 @@ static int scst_local_queuecommand(struct scsi_cmnd *SCpnt,
scst_cmd_set_tgt_priv(scst_cmd, SCpnt);
#endif
/*
* Although starting from 2.6.37 queuecommand() called with no host_lock
* held, in reality without DEF_SCSI_QCMD() this doesn't work and leading
* to various problems like commands lost under highload. So, until that fixed
* we have to go ahead under host_lock, although absolutely don't need it.
*
* NOTE! At the moment in scst_estimate_context*() returning DIRECT contexts
* disabled, so this option doesn't have any real effect.
*/
#ifdef CONFIG_SCST_LOCAL_FORCE_DIRECT_PROCESSING
{
struct Scsi_Host *h = SCpnt->device->host;
@@ -1073,6 +1083,14 @@ static int scst_local_queuecommand(struct scsi_cmnd *SCpnt,
return 0;
}
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37)
/*
* See comment in scst_local_queuecommand_lck() near
* CONFIG_SCST_LOCAL_FORCE_DIRECT_PROCESSING
*/
static DEF_SCSI_QCMD(scst_local_queuecommand)
#endif
static int scst_local_targ_pre_exec(struct scst_cmd *scst_cmd)
{
int res = SCST_PREPROCESS_STATUS_SUCCESS;
@@ -1372,7 +1390,11 @@ static struct scsi_host_template scst_lcl_ini_driver_template = {
.info = scst_local_info,
#endif
.name = SCST_LOCAL_NAME,
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 37)
.queuecommand = scst_local_queuecommand_lck,
#else
.queuecommand = scst_local_queuecommand,
#endif
.eh_abort_handler = scst_local_abort,
.eh_device_reset_handler = scst_local_device_reset,
#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 25))
@@ -1534,7 +1556,7 @@ static void scst_local_release_adapter(struct device *dev)
cancel_work_sync(&sess->aen_work);
#endif
scst_unregister_session(sess->scst_sess, TRUE, NULL);
scst_unregister_session(sess->scst_sess, true, NULL);
kfree(sess);
@@ -1635,7 +1657,7 @@ unregister_dev:
#endif
unregister_session:
scst_unregister_session(sess->scst_sess, TRUE, NULL);
scst_unregister_session(sess->scst_sess, true, NULL);
out_free:
kfree(sess);