diff options
Diffstat (limited to 'include/linux')
-rw-r--r-- | include/linux/blkdev.h | 26 | ||||
-rw-r--r-- | include/linux/bsg.h | 70 |
2 files changed, 95 insertions, 1 deletions
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index fae138bd220..b32564a1e10 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h @@ -14,6 +14,7 @@ #include <linux/bio.h> #include <linux/module.h> #include <linux/stringify.h> +#include <linux/bsg.h> #include <asm/scatterlist.h> @@ -41,6 +42,8 @@ struct elevator_queue; typedef struct elevator_queue elevator_t; struct request_pm_state; struct blk_trace; +struct request; +struct sg_io_hdr; #define BLKDEV_MIN_RQ 4 #define BLKDEV_MAX_RQ 128 /* Default maximum */ @@ -314,6 +317,9 @@ struct request { */ rq_end_io_fn *end_io; void *end_io_data; + + /* for bidi */ + struct request *next_rq; }; /* @@ -468,6 +474,10 @@ struct request_queue unsigned int bi_size; struct mutex sysfs_lock; + +#if defined(CONFIG_BLK_DEV_BSG) + struct bsg_class_device bsg_dev; +#endif }; #define QUEUE_FLAG_CLUSTER 0 /* cluster several segments into 1 */ @@ -479,6 +489,7 @@ struct request_queue #define QUEUE_FLAG_REENTER 6 /* Re-entrancy avoidance */ #define QUEUE_FLAG_PLUGGED 7 /* queue is plugged */ #define QUEUE_FLAG_ELVSWITCH 8 /* don't use elevator, just do FIFO */ +#define QUEUE_FLAG_BIDI 9 /* queue supports bidi requests */ enum { /* @@ -543,6 +554,7 @@ enum { #define blk_sorted_rq(rq) ((rq)->cmd_flags & REQ_SORTED) #define blk_barrier_rq(rq) ((rq)->cmd_flags & REQ_HARDBARRIER) #define blk_fua_rq(rq) ((rq)->cmd_flags & REQ_FUA) +#define blk_bidi_rq(rq) ((rq)->next_rq != NULL) #define list_entry_rq(ptr) list_entry((ptr), struct request, queuelist) @@ -607,6 +619,11 @@ extern unsigned long blk_max_low_pfn, blk_max_pfn; #define BLK_BOUNCE_ANY ((u64)blk_max_pfn << PAGE_SHIFT) #define BLK_BOUNCE_ISA (ISA_DMA_THRESHOLD) +/* + * default timeout for SG_IO if none specified + */ +#define BLK_DEFAULT_SG_TIMEOUT (60 * HZ) + #ifdef CONFIG_MMU extern int init_emergency_isa_pool(void); extern void blk_queue_bounce(request_queue_t *q, struct bio **bio); @@ -637,7 +654,8 @@ extern void blk_requeue_request(request_queue_t *, struct request *); extern void blk_plug_device(request_queue_t *); extern int blk_remove_plug(request_queue_t *); extern void blk_recount_segments(request_queue_t *, struct bio *); -extern int scsi_cmd_ioctl(struct file *, struct gendisk *, unsigned int, void __user *); +extern int scsi_cmd_ioctl(struct file *, struct request_queue *, + struct gendisk *, unsigned int, void __user *); extern int sg_scsi_ioctl(struct file *, struct request_queue *, struct gendisk *, struct scsi_ioctl_command __user *); @@ -680,6 +698,12 @@ extern int blk_execute_rq(request_queue_t *, struct gendisk *, struct request *, int); extern void blk_execute_rq_nowait(request_queue_t *, struct gendisk *, struct request *, int, rq_end_io_fn *); +extern int blk_fill_sghdr_rq(request_queue_t *, struct request *, + struct sg_io_hdr *, int); +extern int blk_unmap_sghdr_rq(struct request *, struct sg_io_hdr *); +extern int blk_complete_sghdr_rq(struct request *, struct sg_io_hdr *, + struct bio *); +extern int blk_verify_command(unsigned char *, int); static inline request_queue_t *bdev_get_queue(struct block_device *bdev) { diff --git a/include/linux/bsg.h b/include/linux/bsg.h new file mode 100644 index 00000000000..bd998ca6cb2 --- /dev/null +++ b/include/linux/bsg.h @@ -0,0 +1,70 @@ +#ifndef BSG_H +#define BSG_H + +#define BSG_PROTOCOL_SCSI 0 + +#define BSG_SUB_PROTOCOL_SCSI_CMD 0 +#define BSG_SUB_PROTOCOL_SCSI_TMF 1 +#define BSG_SUB_PROTOCOL_SCSI_TRANSPORT 2 + +struct sg_io_v4 { + __s32 guard; /* [i] 'Q' to differentiate from v3 */ + __u32 protocol; /* [i] 0 -> SCSI , .... */ + __u32 subprotocol; /* [i] 0 -> SCSI command, 1 -> SCSI task + management function, .... */ + + __u32 request_len; /* [i] in bytes */ + __u64 request; /* [i], [*i] {SCSI: cdb} */ + __u32 request_attr; /* [i] {SCSI: task attribute} */ + __u32 request_tag; /* [i] {SCSI: task tag (only if flagged)} */ + __u32 request_priority; /* [i] {SCSI: task priority} */ + __u32 max_response_len; /* [i] in bytes */ + __u64 response; /* [i], [*o] {SCSI: (auto)sense data} */ + + /* "din_" for data in (from device); "dout_" for data out (to device) */ + __u32 dout_xfer_len; /* [i] bytes to be transferred to device */ + __u32 din_xfer_len; /* [i] bytes to be transferred from device */ + __u64 dout_xferp; /* [i], [*i] */ + __u64 din_xferp; /* [i], [*o] */ + + __u32 timeout; /* [i] units: millisecond */ + __u32 flags; /* [i] bit mask */ + __u64 usr_ptr; /* [i->o] unused internally */ + __u32 spare_in; /* [i] */ + + __u32 driver_status; /* [o] 0 -> ok */ + __u32 transport_status; /* [o] 0 -> ok */ + __u32 device_status; /* [o] {SCSI: command completion status} */ + __u32 retry_delay; /* [o] {SCSI: status auxiliary information} */ + __u32 info; /* [o] additional information */ + __u32 duration; /* [o] time to complete, in milliseconds */ + __u32 response_len; /* [o] bytes of response actually written */ + __s32 din_resid; /* [o] actual_din_xfer_len - din_xfer_len */ + __u32 generated_tag; /* [o] {SCSI: task tag that transport chose} */ + __u32 spare_out; /* [o] */ + + __u32 padding; +}; + +#ifdef __KERNEL__ + +#if defined(CONFIG_BLK_DEV_BSG) +struct bsg_class_device { + struct class_device *class_dev; + struct device *dev; + int minor; + struct list_head list; + struct request_queue *queue; +}; + +extern int bsg_register_queue(struct request_queue *, const char *); +extern void bsg_unregister_queue(struct request_queue *); +#else +struct bsg_class_device { }; +#define bsg_register_queue(disk, name) (0) +#define bsg_unregister_queue(disk) do { } while (0) +#endif + +#endif /* __KERNEL__ */ + +#endif |