diff options
Diffstat (limited to 'include/scsi')
-rw-r--r-- | include/scsi/scsi.h | 20 | ||||
-rw-r--r-- | include/scsi/scsi_cmnd.h | 60 | ||||
-rw-r--r-- | include/scsi/scsi_eh.h | 9 | ||||
-rw-r--r-- | include/scsi/scsi_host.h | 17 |
4 files changed, 68 insertions, 38 deletions
diff --git a/include/scsi/scsi.h b/include/scsi/scsi.h index 702fcfeb37f1..82251575a9b4 100644 --- a/include/scsi/scsi.h +++ b/include/scsi/scsi.h @@ -11,6 +11,25 @@ #include <linux/types.h> /* + * The maximum number of SG segments that we will put inside a + * scatterlist (unless chaining is used). Should ideally fit inside a + * single page, to avoid a higher order allocation. We could define this + * to SG_MAX_SINGLE_ALLOC to pack correctly at the highest order. The + * minimum value is 32 + */ +#define SCSI_MAX_SG_SEGMENTS 128 + +/* + * Like SCSI_MAX_SG_SEGMENTS, but for archs that have sg chaining. This limit + * is totally arbitrary, a setting of 2048 will get you at least 8mb ios. + */ +#ifdef ARCH_HAS_SG_CHAIN +#define SCSI_MAX_SG_CHAIN_SEGMENTS 2048 +#else +#define SCSI_MAX_SG_CHAIN_SEGMENTS SCSI_MAX_SG_SEGMENTS +#endif + +/* * SCSI command lengths */ @@ -83,6 +102,7 @@ extern const unsigned char scsi_command_size[8]; #define READ_TOC 0x43 #define LOG_SELECT 0x4c #define LOG_SENSE 0x4d +#define XDWRITEREAD_10 0x53 #define MODE_SELECT_10 0x55 #define RESERVE_10 0x56 #define RELEASE_10 0x57 diff --git a/include/scsi/scsi_cmnd.h b/include/scsi/scsi_cmnd.h index abd7479ff452..de28aab820b0 100644 --- a/include/scsi/scsi_cmnd.h +++ b/include/scsi/scsi_cmnd.h @@ -2,16 +2,20 @@ #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 scatterlist; struct Scsi_Host; struct scsi_device; +struct scsi_data_buffer { + struct sg_table table; + unsigned length; + int resid; +}; /* embedded in scsi_cmnd */ struct scsi_pointer { @@ -62,15 +66,11 @@ struct scsi_cmnd { /* These elements define the operation we are about to perform */ #define MAX_COMMAND_SIZE 16 unsigned char cmnd[MAX_COMMAND_SIZE]; - unsigned request_bufflen; /* Actual request size */ struct timer_list eh_timeout; /* Used to time out the command. */ - void *request_buffer; /* Actual requested buffer */ /* These elements define the operation we ultimately want to perform */ - unsigned short use_sg; /* Number of pieces of scatter-gather */ - unsigned short __use_sg; - + struct scsi_data_buffer sdb; unsigned underflow; /* Return error if less than this amount is transferred */ @@ -80,10 +80,6 @@ struct scsi_cmnd { reconnects. Probably == sector size */ - int resid; /* Number of bytes requested to be - transferred less actual number - transferred (0 if not supported) */ - struct request *request; /* The command we are working on */ @@ -128,27 +124,55 @@ extern void *scsi_kmap_atomic_sg(struct scatterlist *sg, int sg_count, size_t *offset, size_t *len); extern void scsi_kunmap_atomic_sg(void *virt); -extern struct scatterlist *scsi_alloc_sgtable(struct scsi_cmnd *, gfp_t); -extern void scsi_free_sgtable(struct scsi_cmnd *); +extern int scsi_init_io(struct scsi_cmnd *cmd, gfp_t gfp_mask); +extern void scsi_release_buffers(struct scsi_cmnd *cmd); extern int scsi_dma_map(struct scsi_cmnd *cmd); extern void scsi_dma_unmap(struct scsi_cmnd *cmd); -#define scsi_sg_count(cmd) ((cmd)->use_sg) -#define scsi_sglist(cmd) ((struct scatterlist *)(cmd)->request_buffer) -#define scsi_bufflen(cmd) ((cmd)->request_bufflen) +static inline unsigned scsi_sg_count(struct scsi_cmnd *cmd) +{ + return cmd->sdb.table.nents; +} + +static inline struct scatterlist *scsi_sglist(struct scsi_cmnd *cmd) +{ + return cmd->sdb.table.sgl; +} + +static inline unsigned scsi_bufflen(struct scsi_cmnd *cmd) +{ + return cmd->sdb.length; +} static inline void scsi_set_resid(struct scsi_cmnd *cmd, int resid) { - cmd->resid = resid; + cmd->sdb.resid = resid; } static inline int scsi_get_resid(struct scsi_cmnd *cmd) { - return cmd->resid; + return cmd->sdb.resid; } #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 d21b8913ceb3..25071d5d9bf8 100644 --- a/include/scsi/scsi_eh.h +++ b/include/scsi/scsi_eh.h @@ -68,16 +68,15 @@ extern int scsi_get_sense_info_fld(const u8 * sense_buffer, int sb_len, extern int scsi_reset_provider(struct scsi_device *, int); struct scsi_eh_save { + /* saved state */ int result; enum dma_data_direction data_direction; unsigned char cmd_len; unsigned char cmnd[MAX_COMMAND_SIZE]; + struct scsi_data_buffer sdb; + struct request *next_rq; - void *buffer; - unsigned bufflen; - unsigned short use_sg; - int resid; - + /* new command support */ struct scatterlist sense_sgl; }; diff --git a/include/scsi/scsi_host.h b/include/scsi/scsi_host.h index 0fd4746ee39d..5c58d594126a 100644 --- a/include/scsi/scsi_host.h +++ b/include/scsi/scsi_host.h @@ -39,9 +39,6 @@ struct blk_queue_tags; #define DISABLE_CLUSTERING 0 #define ENABLE_CLUSTERING 1 -#define DISABLE_SG_CHAINING 0 -#define ENABLE_SG_CHAINING 1 - enum scsi_eh_timer_return { EH_NOT_HANDLED, EH_HANDLED, @@ -136,9 +133,9 @@ struct scsi_host_template { * the done callback is invoked. * * This is called to inform the LLD to transfer - * cmd->request_bufflen bytes. The cmd->use_sg speciefies the + * scsi_bufflen(cmd) bytes. scsi_sg_count(cmd) speciefies the * number of scatterlist entried in the command and - * cmd->request_buffer contains the scatterlist. + * scsi_sglist(cmd) returns the scatterlist. * * return values: see queuecommand * @@ -446,15 +443,6 @@ struct scsi_host_template { unsigned ordered_tag:1; /* - * true if the low-level driver can support sg chaining. this - * will be removed eventually when all the drivers are - * converted to support sg chaining. - * - * Status: OBSOLETE - */ - unsigned use_sg_chaining:1; - - /* * Countdown for host blocking with no commands outstanding */ unsigned int max_host_blocked; @@ -598,7 +586,6 @@ struct Scsi_Host { unsigned unchecked_isa_dma:1; unsigned use_clustering:1; unsigned use_blk_tcq:1; - unsigned use_sg_chaining:1; /* * Host has requested that no further requests come through for the |