[SCSI] Update documentation
The documentation has gone out-of-sync, so update it to the current status. Signed-off-by: Hannes Reinecke <hare@suse.de> Signed-off-by: James Bottomley <JBottomley@Parallels.com>
This commit is contained in:
parent
bb3b621a33
commit
6ad55502c6
|
@ -42,20 +42,14 @@ discussion.
|
||||||
|
|
||||||
Once LLDD gets hold of a scmd, either the LLDD will complete the
|
Once LLDD gets hold of a scmd, either the LLDD will complete the
|
||||||
command by calling scsi_done callback passed from midlayer when
|
command by calling scsi_done callback passed from midlayer when
|
||||||
invoking hostt->queuecommand() or SCSI midlayer will time it out.
|
invoking hostt->queuecommand() or the block layer will time it out.
|
||||||
|
|
||||||
|
|
||||||
[1-2-1] Completing a scmd w/ scsi_done
|
[1-2-1] Completing a scmd w/ scsi_done
|
||||||
|
|
||||||
For all non-EH commands, scsi_done() is the completion callback. It
|
For all non-EH commands, scsi_done() is the completion callback. It
|
||||||
does the following.
|
just calls blk_complete_request() to delete the block layer timer and
|
||||||
|
raise SCSI_SOFTIRQ
|
||||||
1. Delete timeout timer. If it fails, it means that timeout timer
|
|
||||||
has expired and is going to finish the command. Just return.
|
|
||||||
|
|
||||||
2. Link scmd to per-cpu scsi_done_q using scmd->en_entry
|
|
||||||
|
|
||||||
3. Raise SCSI_SOFTIRQ
|
|
||||||
|
|
||||||
SCSI_SOFTIRQ handler scsi_softirq calls scsi_decide_disposition() to
|
SCSI_SOFTIRQ handler scsi_softirq calls scsi_decide_disposition() to
|
||||||
determine what to do with the command. scsi_decide_disposition()
|
determine what to do with the command. scsi_decide_disposition()
|
||||||
|
@ -64,10 +58,12 @@ with the command.
|
||||||
|
|
||||||
- SUCCESS
|
- SUCCESS
|
||||||
scsi_finish_command() is invoked for the command. The
|
scsi_finish_command() is invoked for the command. The
|
||||||
function does some maintenance choirs and notify completion by
|
function does some maintenance chores and then calls
|
||||||
calling scmd->done() callback, which, for fs requests, would
|
scsi_io_completion() to finish the I/O.
|
||||||
be HLD completion callback - sd:sd_rw_intr, sr:rw_intr,
|
scsi_io_completion() then notifies the block layer on
|
||||||
st:st_intr.
|
the completed request by calling blk_end_request and
|
||||||
|
friends or figures out what to do with the remainder
|
||||||
|
of the data in case of an error.
|
||||||
|
|
||||||
- NEEDS_RETRY
|
- NEEDS_RETRY
|
||||||
- ADD_TO_MLQUEUE
|
- ADD_TO_MLQUEUE
|
||||||
|
@ -86,33 +82,45 @@ function
|
||||||
1. invokes optional hostt->eh_timed_out() callback. Return value can
|
1. invokes optional hostt->eh_timed_out() callback. Return value can
|
||||||
be one of
|
be one of
|
||||||
|
|
||||||
- EH_HANDLED
|
- BLK_EH_HANDLED
|
||||||
This indicates that eh_timed_out() dealt with the timeout. The
|
This indicates that eh_timed_out() dealt with the timeout.
|
||||||
scmd is passed to __scsi_done() and thus linked into per-cpu
|
The command is passed back to the block layer and completed
|
||||||
scsi_done_q. Normal command completion described in [1-2-1]
|
via __blk_complete_requests().
|
||||||
follows.
|
|
||||||
|
|
||||||
- EH_RESET_TIMER
|
*NOTE* After returning BLK_EH_HANDLED the SCSI layer is
|
||||||
|
assumed to be finished with the command, and no other
|
||||||
|
functions from the SCSI layer will be called. So this
|
||||||
|
should typically only be returned if the eh_timed_out()
|
||||||
|
handler raced with normal completion.
|
||||||
|
|
||||||
|
- BLK_EH_RESET_TIMER
|
||||||
This indicates that more time is required to finish the
|
This indicates that more time is required to finish the
|
||||||
command. Timer is restarted. This action is counted as a
|
command. Timer is restarted. This action is counted as a
|
||||||
retry and only allowed scmd->allowed + 1(!) times. Once the
|
retry and only allowed scmd->allowed + 1(!) times. Once the
|
||||||
limit is reached, action for EH_NOT_HANDLED is taken instead.
|
limit is reached, action for BLK_EH_NOT_HANDLED is taken instead.
|
||||||
|
|
||||||
*NOTE* This action is racy as the LLDD could finish the scmd
|
- BLK_EH_NOT_HANDLED
|
||||||
after the timeout has expired but before it's added back. In
|
eh_timed_out() callback did not handle the command.
|
||||||
such cases, scsi_done() would think that timeout has occurred
|
|
||||||
and return without doing anything. We lose completion and the
|
|
||||||
command will time out again.
|
|
||||||
|
|
||||||
- EH_NOT_HANDLED
|
|
||||||
This is the same as when eh_timed_out() callback doesn't exist.
|
|
||||||
Step #2 is taken.
|
Step #2 is taken.
|
||||||
|
|
||||||
|
2. If the host supports asynchronous completion (as indicated by the
|
||||||
|
no_async_abort setting in the host template) scsi_abort_command()
|
||||||
|
is invoked to schedule an asynchrous abort. If that fails
|
||||||
|
Step #3 is taken.
|
||||||
|
|
||||||
2. scsi_eh_scmd_add(scmd, SCSI_EH_CANCEL_CMD) is invoked for the
|
2. scsi_eh_scmd_add(scmd, SCSI_EH_CANCEL_CMD) is invoked for the
|
||||||
command. See [1-3] for more information.
|
command. See [1-3] for more information.
|
||||||
|
|
||||||
|
[1-3] Asynchronous command aborts
|
||||||
|
|
||||||
[1-3] How EH takes over
|
After a timeout occurs a command abort is scheduled from
|
||||||
|
scsi_abort_command(). If the abort is successful the command
|
||||||
|
will either be retried (if the number of retries is not exhausted)
|
||||||
|
or terminated with DID_TIME_OUT.
|
||||||
|
Otherwise scsi_eh_scmd_add() is invoked for the command.
|
||||||
|
See [1-4] for more information.
|
||||||
|
|
||||||
|
[1-4] How EH takes over
|
||||||
|
|
||||||
scmds enter EH via scsi_eh_scmd_add(), which does the following.
|
scmds enter EH via scsi_eh_scmd_add(), which does the following.
|
||||||
|
|
||||||
|
@ -320,7 +328,8 @@ scmd->allowed.
|
||||||
|
|
||||||
<<scsi_eh_abort_cmds>>
|
<<scsi_eh_abort_cmds>>
|
||||||
|
|
||||||
This action is taken for each timed out command.
|
This action is taken for each timed out command when
|
||||||
|
no_async_abort is enabled in the host template.
|
||||||
hostt->eh_abort_handler() is invoked for each scmd. The
|
hostt->eh_abort_handler() is invoked for each scmd. The
|
||||||
handler returns SUCCESS if it has succeeded to make LLDD and
|
handler returns SUCCESS if it has succeeded to make LLDD and
|
||||||
all related hardware forget about the scmd.
|
all related hardware forget about the scmd.
|
||||||
|
|
|
@ -882,8 +882,11 @@ Details:
|
||||||
*
|
*
|
||||||
* Calling context: kernel thread
|
* Calling context: kernel thread
|
||||||
*
|
*
|
||||||
* Notes: Invoked from scsi_eh thread. No other commands will be
|
* Notes: If 'no_async_abort' is defined this callback
|
||||||
* queued on current host during eh.
|
* will be invoked from scsi_eh thread. No other commands
|
||||||
|
* will then be queued on current host during eh.
|
||||||
|
* Otherwise it will be called whenever scsi_times_out()
|
||||||
|
* is called due to a command timeout.
|
||||||
*
|
*
|
||||||
* Optionally defined in: LLD
|
* Optionally defined in: LLD
|
||||||
**/
|
**/
|
||||||
|
@ -1257,6 +1260,8 @@ of interest:
|
||||||
address space
|
address space
|
||||||
use_clustering - 1=>SCSI commands in mid level's queue can be merged,
|
use_clustering - 1=>SCSI commands in mid level's queue can be merged,
|
||||||
0=>disallow SCSI command merging
|
0=>disallow SCSI command merging
|
||||||
|
no_async_abort - 1=>Asynchronous aborts are not supported
|
||||||
|
0=>Timed-out commands will be aborted asynchronously
|
||||||
hostt - pointer to driver's struct scsi_host_template from which
|
hostt - pointer to driver's struct scsi_host_template from which
|
||||||
this struct Scsi_Host instance was spawned
|
this struct Scsi_Host instance was spawned
|
||||||
hostt->proc_name - name of LLD. This is the driver name that sysfs uses
|
hostt->proc_name - name of LLD. This is the driver name that sysfs uses
|
||||||
|
|
|
@ -745,15 +745,13 @@ int scsi_dispatch_cmd(struct scsi_cmnd *cmd)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* scsi_done - Enqueue the finished SCSI command into the done queue.
|
* scsi_done - Invoke completion on finished SCSI command.
|
||||||
* @cmd: The SCSI Command for which a low-level device driver (LLDD) gives
|
* @cmd: The SCSI Command for which a low-level device driver (LLDD) gives
|
||||||
* ownership back to SCSI Core -- i.e. the LLDD has finished with it.
|
* ownership back to SCSI Core -- i.e. the LLDD has finished with it.
|
||||||
*
|
*
|
||||||
* Description: This function is the mid-level's (SCSI Core) interrupt routine,
|
* Description: This function is the mid-level's (SCSI Core) interrupt routine,
|
||||||
* which regains ownership of the SCSI command (de facto) from a LLDD, and
|
* which regains ownership of the SCSI command (de facto) from a LLDD, and
|
||||||
* enqueues the command to the done queue for further processing.
|
* calls blk_complete_request() for further processing.
|
||||||
*
|
|
||||||
* This is the producer of the done queue who enqueues at the tail.
|
|
||||||
*
|
*
|
||||||
* This function is interrupt context safe.
|
* This function is interrupt context safe.
|
||||||
*/
|
*/
|
||||||
|
|
Loading…
Reference in a new issue