mirror of
https://github.com/SCST-project/scst.git
synced 2026-08-22 07:06:22 +00:00
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:
+36
-14
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user