[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:
Hannes Reinecke 2013-11-11 13:44:57 +01:00 committed by James Bottomley
parent bb3b621a33
commit 6ad55502c6
3 changed files with 48 additions and 36 deletions

View file

@ -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.

View file

@ -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

View file

@ -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.
*/ */