diff options
Diffstat (limited to 'include/scsi/scsi_cmnd.h')
| -rw-r--r-- | include/scsi/scsi_cmnd.h | 46 |
1 files changed, 38 insertions, 8 deletions
diff --git a/include/scsi/scsi_cmnd.h b/include/scsi/scsi_cmnd.h index a5e885a111d..e0ae7109814 100644 --- a/include/scsi/scsi_cmnd.h +++ b/include/scsi/scsi_cmnd.h @@ -7,9 +7,11 @@ #include <linux/types.h> #include <linux/timer.h> #include <linux/scatterlist.h> +#include <scsi/scsi_device.h> struct Scsi_Host; struct scsi_device; +struct scsi_driver; /* * MAX_COMMAND_SIZE is: @@ -54,6 +56,7 @@ struct scsi_cmnd { struct scsi_device *device; struct list_head list; /* scsi_cmnd participates in queue lists */ struct list_head eh_entry; /* entry for the host eh_cmd_q */ + struct delayed_work abort_work; int eh_eflags; /* Used by error handlr */ /* @@ -131,11 +134,25 @@ struct scsi_cmnd { unsigned char tag; /* SCSI-II queued command tag */ }; +/* + * Return the driver private allocation behind the command. + * Only works if cmd_size is set in the host template. + */ +static inline void *scsi_cmd_priv(struct scsi_cmnd *cmd) +{ + return cmd + 1; +} + +/* make sure not to use it with REQ_TYPE_BLOCK_PC commands */ +static inline struct scsi_driver *scsi_cmd_to_driver(struct scsi_cmnd *cmd) +{ + return *(struct scsi_driver **)cmd->request->rq_disk->private_data; +} + extern struct scsi_cmnd *scsi_get_command(struct scsi_device *, gfp_t); extern struct scsi_cmnd *__scsi_get_command(struct Scsi_Host *, gfp_t); extern void scsi_put_command(struct scsi_cmnd *); -extern void __scsi_put_command(struct Scsi_Host *, struct scsi_cmnd *, - struct device *); +extern void __scsi_put_command(struct Scsi_Host *, struct scsi_cmnd *); extern void scsi_finish_command(struct scsi_cmnd *cmd); extern void *scsi_kmap_atomic_sg(struct scatterlist *sg, int sg_count, @@ -148,9 +165,6 @@ 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); -struct scsi_cmnd *scsi_allocate_command(gfp_t gfp_mask); -void scsi_free_command(gfp_t gfp_mask, struct scsi_cmnd *cmd); - static inline unsigned scsi_sg_count(struct scsi_cmnd *cmd) { return cmd->sdb.table.nents; @@ -289,17 +303,33 @@ static inline struct scsi_data_buffer *scsi_prot(struct scsi_cmnd *cmd) static inline void set_msg_byte(struct scsi_cmnd *cmd, char status) { - cmd->result |= status << 8; + cmd->result = (cmd->result & 0xffff00ff) | (status << 8); } static inline void set_host_byte(struct scsi_cmnd *cmd, char status) { - cmd->result |= status << 16; + cmd->result = (cmd->result & 0xff00ffff) | (status << 16); } static inline void set_driver_byte(struct scsi_cmnd *cmd, char status) { - cmd->result |= status << 24; + cmd->result = (cmd->result & 0x00ffffff) | (status << 24); +} + +static inline unsigned scsi_transfer_length(struct scsi_cmnd *scmd) +{ + unsigned int xfer_len = scsi_out(scmd)->length; + unsigned int prot_op = scsi_get_prot_op(scmd); + unsigned int sector_size = scmd->device->sector_size; + + switch (prot_op) { + case SCSI_PROT_NORMAL: + case SCSI_PROT_WRITE_STRIP: + case SCSI_PROT_READ_INSERT: + return xfer_len; + } + + return xfer_len + (xfer_len >> ilog2(sector_size)) * 8; } #endif /* _SCSI_SCSI_CMND_H */ |
