Commit d351af01 authored by FUJITA Tomonori's avatar FUJITA Tomonori Committed by Jens Axboe

bsg: bind bsg to request_queue instead of gendisk

This patch binds bsg devices to request_queue instead of gendisk. Any
objects (like transport entities) can define own request_handler and
create own bsg device.
Signed-off-by: default avatarFUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>
Signed-off-by: default avatarJens Axboe <jens.axboe@oracle.com>
parent 45e79a3a
...@@ -34,7 +34,6 @@ ...@@ -34,7 +34,6 @@
static char bsg_version[] = "block layer sg (bsg) 0.4"; static char bsg_version[] = "block layer sg (bsg) 0.4";
struct bsg_device { struct bsg_device {
struct gendisk *disk;
request_queue_t *queue; request_queue_t *queue;
spinlock_t lock; spinlock_t lock;
struct list_head busy_list; struct list_head busy_list;
...@@ -46,7 +45,7 @@ struct bsg_device { ...@@ -46,7 +45,7 @@ struct bsg_device {
int done_cmds; int done_cmds;
wait_queue_head_t wq_done; wait_queue_head_t wq_done;
wait_queue_head_t wq_free; wait_queue_head_t wq_free;
char name[BDEVNAME_SIZE]; char name[BUS_ID_SIZE];
int max_queue; int max_queue;
unsigned long flags; unsigned long flags;
}; };
...@@ -375,7 +374,7 @@ static void bsg_add_command(struct bsg_device *bd, request_queue_t *q, ...@@ -375,7 +374,7 @@ static void bsg_add_command(struct bsg_device *bd, request_queue_t *q,
dprintk("%s: queueing rq %p, bc %p\n", bd->name, rq, bc); dprintk("%s: queueing rq %p, bc %p\n", bd->name, rq, bc);
rq->end_io_data = bc; rq->end_io_data = bc;
blk_execute_rq_nowait(q, bd->disk, rq, 1, bsg_rq_end_io); blk_execute_rq_nowait(q, NULL, rq, 1, bsg_rq_end_io);
} }
static inline struct bsg_command *bsg_next_done_cmd(struct bsg_device *bd) static inline struct bsg_command *bsg_next_done_cmd(struct bsg_device *bd)
...@@ -741,7 +740,7 @@ static int bsg_put_device(struct bsg_device *bd) ...@@ -741,7 +740,7 @@ static int bsg_put_device(struct bsg_device *bd)
} }
static struct bsg_device *bsg_add_device(struct inode *inode, static struct bsg_device *bsg_add_device(struct inode *inode,
struct gendisk *disk, struct request_queue *rq,
struct file *file) struct file *file)
{ {
struct bsg_device *bd = NULL; struct bsg_device *bd = NULL;
...@@ -753,17 +752,16 @@ static struct bsg_device *bsg_add_device(struct inode *inode, ...@@ -753,17 +752,16 @@ static struct bsg_device *bsg_add_device(struct inode *inode,
if (!bd) if (!bd)
return ERR_PTR(-ENOMEM); return ERR_PTR(-ENOMEM);
bd->disk = disk; bd->queue = rq;
bd->queue = disk->queue; kobject_get(&rq->kobj);
kobject_get(&disk->queue->kobj);
bsg_set_block(bd, file); bsg_set_block(bd, file);
atomic_set(&bd->ref_count, 1); atomic_set(&bd->ref_count, 1);
bd->minor = iminor(inode); bd->minor = iminor(inode);
mutex_lock(&bsg_mutex); mutex_lock(&bsg_mutex);
hlist_add_head(&bd->dev_list,&bsg_device_list[bsg_list_idx(bd->minor)]); hlist_add_head(&bd->dev_list, &bsg_device_list[bsg_list_idx(bd->minor)]);
strncpy(bd->name, disk->disk_name, sizeof(bd->name) - 1); strncpy(bd->name, rq->bsg_dev.class_dev->class_id, sizeof(bd->name) - 1);
dprintk("bound to <%s>, max queue %d\n", dprintk("bound to <%s>, max queue %d\n",
format_dev_t(buf, inode->i_rdev), bd->max_queue); format_dev_t(buf, inode->i_rdev), bd->max_queue);
...@@ -817,7 +815,7 @@ static struct bsg_device *bsg_get_device(struct inode *inode, struct file *file) ...@@ -817,7 +815,7 @@ static struct bsg_device *bsg_get_device(struct inode *inode, struct file *file)
if (!bcd) if (!bcd)
return ERR_PTR(-ENODEV); return ERR_PTR(-ENODEV);
return bsg_add_device(inode, bcd->disk, file); return bsg_add_device(inode, bcd->queue, file);
} }
static int bsg_open(struct inode *inode, struct file *file) static int bsg_open(struct inode *inode, struct file *file)
...@@ -900,7 +898,7 @@ bsg_ioctl(struct inode *inode, struct file *file, unsigned int cmd, ...@@ -900,7 +898,7 @@ bsg_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
case SG_EMULATED_HOST: case SG_EMULATED_HOST:
case SCSI_IOCTL_SEND_COMMAND: { case SCSI_IOCTL_SEND_COMMAND: {
void __user *uarg = (void __user *) arg; void __user *uarg = (void __user *) arg;
return scsi_cmd_ioctl(file, bd->queue, bd->disk, cmd, uarg); return scsi_cmd_ioctl(file, bd->queue, NULL, cmd, uarg);
} }
case SG_IO: { case SG_IO: {
struct request *rq; struct request *rq;
...@@ -915,7 +913,7 @@ bsg_ioctl(struct inode *inode, struct file *file, unsigned int cmd, ...@@ -915,7 +913,7 @@ bsg_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
return PTR_ERR(rq); return PTR_ERR(rq);
bio = rq->bio; bio = rq->bio;
blk_execute_rq(bd->queue, bd->disk, rq, 0); blk_execute_rq(bd->queue, NULL, rq, 0);
blk_complete_sgv4_hdr_rq(rq, &hdr, bio); blk_complete_sgv4_hdr_rq(rq, &hdr, bio);
if (copy_to_user(uarg, &hdr, sizeof(hdr))) if (copy_to_user(uarg, &hdr, sizeof(hdr)))
...@@ -945,24 +943,23 @@ static struct file_operations bsg_fops = { ...@@ -945,24 +943,23 @@ static struct file_operations bsg_fops = {
.owner = THIS_MODULE, .owner = THIS_MODULE,
}; };
void bsg_unregister_disk(struct gendisk *disk) void bsg_unregister_queue(struct request_queue *q)
{ {
struct bsg_class_device *bcd = &disk->bsg_dev; struct bsg_class_device *bcd = &q->bsg_dev;
if (!bcd->class_dev) if (!bcd->class_dev)
return; return;
mutex_lock(&bsg_mutex); mutex_lock(&bsg_mutex);
sysfs_remove_link(&bcd->disk->queue->kobj, "bsg"); sysfs_remove_link(&q->kobj, "bsg");
class_device_destroy(bsg_class, MKDEV(BSG_MAJOR, bcd->minor)); class_device_destroy(bsg_class, MKDEV(BSG_MAJOR, bcd->minor));
bcd->class_dev = NULL; bcd->class_dev = NULL;
list_del_init(&bcd->list); list_del_init(&bcd->list);
mutex_unlock(&bsg_mutex); mutex_unlock(&bsg_mutex);
} }
int bsg_register_disk(struct gendisk *disk) int bsg_register_queue(struct request_queue *q, char *name)
{ {
request_queue_t *q = disk->queue;
struct bsg_class_device *bcd; struct bsg_class_device *bcd;
dev_t dev; dev_t dev;
...@@ -972,7 +969,7 @@ int bsg_register_disk(struct gendisk *disk) ...@@ -972,7 +969,7 @@ int bsg_register_disk(struct gendisk *disk)
if (!q->request_fn) if (!q->request_fn)
return 0; return 0;
bcd = &disk->bsg_dev; bcd = &q->bsg_dev;
memset(bcd, 0, sizeof(*bcd)); memset(bcd, 0, sizeof(*bcd));
INIT_LIST_HEAD(&bcd->list); INIT_LIST_HEAD(&bcd->list);
...@@ -980,8 +977,8 @@ int bsg_register_disk(struct gendisk *disk) ...@@ -980,8 +977,8 @@ int bsg_register_disk(struct gendisk *disk)
dev = MKDEV(BSG_MAJOR, bsg_device_nr); dev = MKDEV(BSG_MAJOR, bsg_device_nr);
bcd->minor = bsg_device_nr; bcd->minor = bsg_device_nr;
bsg_device_nr++; bsg_device_nr++;
bcd->disk = disk; bcd->queue = q;
bcd->class_dev = class_device_create(bsg_class, NULL, dev, bcd->dev, "%s", disk->disk_name); bcd->class_dev = class_device_create(bsg_class, NULL, dev, bcd->dev, "%s", name);
if (!bcd->class_dev) if (!bcd->class_dev)
goto err; goto err;
list_add_tail(&bcd->list, &bsg_class_list); list_add_tail(&bcd->list, &bsg_class_list);
......
...@@ -4091,7 +4091,7 @@ int blk_register_queue(struct gendisk *disk) ...@@ -4091,7 +4091,7 @@ int blk_register_queue(struct gendisk *disk)
return ret; return ret;
} }
ret = bsg_register_disk(disk); ret = bsg_register_queue(q, disk->disk_name);
if (ret) { if (ret) {
elv_unregister_queue(q); elv_unregister_queue(q);
kobject_unregister(&q->kobj); kobject_unregister(&q->kobj);
...@@ -4106,7 +4106,7 @@ void blk_unregister_queue(struct gendisk *disk) ...@@ -4106,7 +4106,7 @@ void blk_unregister_queue(struct gendisk *disk)
request_queue_t *q = disk->queue; request_queue_t *q = disk->queue;
if (q && q->request_fn) { if (q && q->request_fn) {
bsg_unregister_disk(disk); bsg_unregister_queue(q);
elv_unregister_queue(q); elv_unregister_queue(q);
kobject_uevent(&q->kobj, KOBJ_REMOVE); kobject_uevent(&q->kobj, KOBJ_REMOVE);
......
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
#include <linux/bio.h> #include <linux/bio.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/stringify.h> #include <linux/stringify.h>
#include <linux/bsg.h>
#include <asm/scatterlist.h> #include <asm/scatterlist.h>
...@@ -470,6 +471,10 @@ struct request_queue ...@@ -470,6 +471,10 @@ struct request_queue
unsigned int bi_size; unsigned int bi_size;
struct mutex sysfs_lock; 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 */ #define QUEUE_FLAG_CLUSTER 0 /* cluster several segments into 1 */
......
...@@ -47,16 +47,16 @@ struct bsg_class_device { ...@@ -47,16 +47,16 @@ struct bsg_class_device {
struct class_device *class_dev; struct class_device *class_dev;
struct device *dev; struct device *dev;
int minor; int minor;
struct gendisk *disk;
struct list_head list; struct list_head list;
struct request_queue *queue;
}; };
extern int bsg_register_disk(struct gendisk *); extern int bsg_register_queue(struct request_queue *, char *);
extern void bsg_unregister_disk(struct gendisk *); extern void bsg_unregister_queue(struct request_queue *);
#else #else
struct bsg_class_device { }; struct bsg_class_device { };
#define bsg_register_disk(disk) (0) #define bsg_register_queue(disk, name) (0)
#define bsg_unregister_disk(disk) do { } while (0) #define bsg_unregister_queue(disk) do { } while (0)
#endif #endif
#endif /* __KERNEL__ */ #endif /* __KERNEL__ */
......
...@@ -67,7 +67,6 @@ struct partition { ...@@ -67,7 +67,6 @@ struct partition {
#include <linux/string.h> #include <linux/string.h>
#include <linux/fs.h> #include <linux/fs.h>
#include <linux/workqueue.h> #include <linux/workqueue.h>
#include <linux/bsg.h>
struct partition { struct partition {
unsigned char boot_ind; /* 0x80 - active */ unsigned char boot_ind; /* 0x80 - active */
...@@ -92,7 +91,6 @@ struct hd_struct { ...@@ -92,7 +91,6 @@ struct hd_struct {
#ifdef CONFIG_FAIL_MAKE_REQUEST #ifdef CONFIG_FAIL_MAKE_REQUEST
int make_it_fail; int make_it_fail;
#endif #endif
struct bsg_class_device bsg_dev;
}; };
#define GENHD_FL_REMOVABLE 1 #define GENHD_FL_REMOVABLE 1
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment