diff options
author | Boaz Harrosh <bharrosh@panasas.com> | 2007-12-13 12:50:53 +0100 |
---|---|---|
committer | James Bottomley <James.Bottomley@HansenPartnership.com> | 2008-01-30 20:03:41 +0100 |
commit | 6f9a35e2dafa0f855ab051c11bdbf739745ff6f5 (patch) | |
tree | 5ca273c98b61a4d329653ef30faa2c0414eccd2b /include/scsi | |
parent | [SCSI] implement scsi_data_buffer (diff) | |
download | linux-6f9a35e2dafa0f855ab051c11bdbf739745ff6f5.tar.xz linux-6f9a35e2dafa0f855ab051c11bdbf739745ff6f5.zip |
[SCSI] bidirectional command support
At the block level bidi request uses req->next_rq pointer for a second
bidi_read request.
At Scsi-midlayer a second scsi_data_buffer structure is used for the
bidi_read part. This bidi scsi_data_buffer is put on
request->next_rq->special. Struct scsi_cmnd is not changed.
- Define scsi_bidi_cmnd() to return true if it is a bidi request and a
second sgtable was allocated.
- Define scsi_in()/scsi_out() to return the in or out scsi_data_buffer
from this command This API is to isolate users from the mechanics of
bidi.
- Define scsi_end_bidi_request() to do what scsi_end_request() does but
for a bidi request. This is necessary because bidi commands are a bit
tricky here. (See comments in body)
- scsi_release_buffers() will also release the bidi_read scsi_data_buffer
- scsi_io_completion() on bidi commands will now call
scsi_end_bidi_request() and return.
- The previous work done in scsi_init_io() is now done in a new
scsi_init_sgtable() (which is 99% identical to old scsi_init_io())
The new scsi_init_io() will call the above twice if needed also for
the bidi_read command. Only at this point is a command bidi.
- In scsi_error.c at scsi_eh_prep/restore_cmnd() make sure bidi-lld is not
confused by a get-sense command that looks like bidi. This is done
by puting NULL at request->next_rq, and restoring.
[jejb: update to sg_table and resolve conflicts
also update to blk-end-request and resolve conflicts]
Signed-off-by: Boaz Harrosh <bharrosh@panasas.com>
Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
Diffstat (limited to 'include/scsi')
-rw-r--r-- | include/scsi/scsi_cmnd.h | 19 | ||||
-rw-r--r-- | include/scsi/scsi_eh.h | 1 |
2 files changed, 19 insertions, 1 deletions
diff --git a/include/scsi/scsi_cmnd.h b/include/scsi/scsi_cmnd.h index c6478bb6f963..de28aab820b0 100644 --- a/include/scsi/scsi_cmnd.h +++ b/include/scsi/scsi_cmnd.h @@ -2,12 +2,12 @@ #define _SCSI_SCSI_CMND_H #include <linux/dma-mapping.h> +#include <linux/blkdev.h> #include <linux/list.h> #include <linux/types.h> #include <linux/timer.h> #include <linux/scatterlist.h> -struct request; struct Scsi_Host; struct scsi_device; @@ -158,4 +158,21 @@ static inline int scsi_get_resid(struct scsi_cmnd *cmd) #define scsi_for_each_sg(cmd, sg, nseg, __i) \ for_each_sg(scsi_sglist(cmd), sg, nseg, __i) +static inline int scsi_bidi_cmnd(struct scsi_cmnd *cmd) +{ + return blk_bidi_rq(cmd->request) && + (cmd->request->next_rq->special != NULL); +} + +static inline struct scsi_data_buffer *scsi_in(struct scsi_cmnd *cmd) +{ + return scsi_bidi_cmnd(cmd) ? + cmd->request->next_rq->special : &cmd->sdb; +} + +static inline struct scsi_data_buffer *scsi_out(struct scsi_cmnd *cmd) +{ + return &cmd->sdb; +} + #endif /* _SCSI_SCSI_CMND_H */ diff --git a/include/scsi/scsi_eh.h b/include/scsi/scsi_eh.h index 1e08be1466ee..25071d5d9bf8 100644 --- a/include/scsi/scsi_eh.h +++ b/include/scsi/scsi_eh.h @@ -74,6 +74,7 @@ struct scsi_eh_save { unsigned char cmd_len; unsigned char cmnd[MAX_COMMAND_SIZE]; struct scsi_data_buffer sdb; + struct request *next_rq; /* new command support */ struct scatterlist sense_sgl; |