aboutsummaryrefslogtreecommitdiffstats
path: root/block
diff options
context:
space:
mode:
authorFUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>2007-03-28 07:29:24 -0400
committerJens Axboe <jens.axboe@oracle.com>2007-07-16 02:52:46 -0400
commit4e2872d6b0252d33f28ea67f33704208ca781978 (patch)
treef65f01929d9a262d57e779705ff3cc643ad0ffd0 /block
parentd351af01b9307566135cb0f355ca65d0952c10b5 (diff)
bind bsg to all SCSI devices
This patch binds bsg to all SCSI devices (their request queues) like the current sg driver does. We can send SCSI commands to non disk and cdrom scsi devices like OSD via bsg. This patch removes bsg_register_queue from blk_register_queue so bsg devices aren't bound to non SCSI block devices. If they want bsg, I'll send a patch to do that. Signed-off-by: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp> Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
Diffstat (limited to 'block')
-rw-r--r--block/bsg.c59
-rw-r--r--block/ll_rw_blk.c8
2 files changed, 52 insertions, 15 deletions
diff --git a/block/bsg.c b/block/bsg.c
index 4ea4bedb413f..cd0221c61bfe 100644
--- a/block/bsg.c
+++ b/block/bsg.c
@@ -29,6 +29,8 @@
29#include <scsi/scsi.h> 29#include <scsi/scsi.h>
30#include <scsi/scsi_ioctl.h> 30#include <scsi/scsi_ioctl.h>
31#include <scsi/scsi_cmnd.h> 31#include <scsi/scsi_cmnd.h>
32#include <scsi/scsi_device.h>
33#include <scsi/scsi_driver.h>
32#include <scsi/sg.h> 34#include <scsi/sg.h>
33 35
34static char bsg_version[] = "block layer sg (bsg) 0.4"; 36static char bsg_version[] = "block layer sg (bsg) 0.4";
@@ -962,6 +964,8 @@ int bsg_register_queue(struct request_queue *q, char *name)
962{ 964{
963 struct bsg_class_device *bcd; 965 struct bsg_class_device *bcd;
964 dev_t dev; 966 dev_t dev;
967 int ret;
968 struct class_device *class_dev = NULL;
965 969
966 /* 970 /*
967 * we need a proper transport to send commands, not a stacked device 971 * we need a proper transport to send commands, not a stacked device
@@ -978,22 +982,54 @@ int bsg_register_queue(struct request_queue *q, char *name)
978 bcd->minor = bsg_device_nr; 982 bcd->minor = bsg_device_nr;
979 bsg_device_nr++; 983 bsg_device_nr++;
980 bcd->queue = q; 984 bcd->queue = q;
981 bcd->class_dev = class_device_create(bsg_class, NULL, dev, bcd->dev, "%s", name); 985 class_dev = class_device_create(bsg_class, NULL, dev, bcd->dev, "%s", name);
982 if (!bcd->class_dev) 986 if (IS_ERR(class_dev)) {
987 ret = PTR_ERR(class_dev);
983 goto err; 988 goto err;
989 }
990 bcd->class_dev = class_dev;
991
992 if (q->kobj.dentry) {
993 ret = sysfs_create_link(&q->kobj, &bcd->class_dev->kobj, "bsg");
994 if (ret)
995 goto err;
996 }
997
984 list_add_tail(&bcd->list, &bsg_class_list); 998 list_add_tail(&bcd->list, &bsg_class_list);
985 if (sysfs_create_link(&q->kobj, &bcd->class_dev->kobj, "bsg")) 999
986 goto err;
987 mutex_unlock(&bsg_mutex); 1000 mutex_unlock(&bsg_mutex);
988 return 0; 1001 return 0;
989err: 1002err:
990 bsg_device_nr--; 1003 bsg_device_nr--;
991 if (bcd->class_dev) 1004 if (class_dev)
992 class_device_destroy(bsg_class, MKDEV(BSG_MAJOR, bcd->minor)); 1005 class_device_destroy(bsg_class, MKDEV(BSG_MAJOR, bcd->minor));
993 mutex_unlock(&bsg_mutex); 1006 mutex_unlock(&bsg_mutex);
994 return -ENOMEM; 1007 return ret;
1008}
1009
1010static int bsg_add(struct class_device *cl_dev, struct class_interface *cl_intf)
1011{
1012 int ret;
1013 struct scsi_device *sdp = to_scsi_device(cl_dev->dev);
1014 struct request_queue *rq = sdp->request_queue;
1015
1016 if (rq->kobj.parent)
1017 ret = bsg_register_queue(rq, kobject_name(rq->kobj.parent));
1018 else
1019 ret = bsg_register_queue(rq, kobject_name(&sdp->sdev_gendev.kobj));
1020 return ret;
995} 1021}
996 1022
1023static void bsg_remove(struct class_device *cl_dev, struct class_interface *cl_intf)
1024{
1025 bsg_unregister_queue(to_scsi_device(cl_dev->dev)->request_queue);
1026}
1027
1028static struct class_interface bsg_intf = {
1029 .add = bsg_add,
1030 .remove = bsg_remove,
1031};
1032
997static int __init bsg_init(void) 1033static int __init bsg_init(void)
998{ 1034{
999 int ret, i; 1035 int ret, i;
@@ -1021,6 +1057,15 @@ static int __init bsg_init(void)
1021 return ret; 1057 return ret;
1022 } 1058 }
1023 1059
1060 ret = scsi_register_interface(&bsg_intf);
1061 if (ret) {
1062 printk(KERN_ERR "bsg: failed register scsi interface %d\n", ret);
1063 kmem_cache_destroy(bsg_cmd_cachep);
1064 class_destroy(bsg_class);
1065 unregister_chrdev(BSG_MAJOR, "bsg");
1066 return ret;
1067 }
1068
1024 printk(KERN_INFO "%s loaded\n", bsg_version); 1069 printk(KERN_INFO "%s loaded\n", bsg_version);
1025 return 0; 1070 return 0;
1026} 1071}
@@ -1029,4 +1074,4 @@ MODULE_AUTHOR("Jens Axboe");
1029MODULE_DESCRIPTION("Block layer SGSI generic (sg) driver"); 1074MODULE_DESCRIPTION("Block layer SGSI generic (sg) driver");
1030MODULE_LICENSE("GPL"); 1075MODULE_LICENSE("GPL");
1031 1076
1032subsys_initcall(bsg_init); 1077device_initcall(bsg_init);
diff --git a/block/ll_rw_blk.c b/block/ll_rw_blk.c
index 74a5498c29a1..ef42bb2b12b6 100644
--- a/block/ll_rw_blk.c
+++ b/block/ll_rw_blk.c
@@ -4091,13 +4091,6 @@ int blk_register_queue(struct gendisk *disk)
4091 return ret; 4091 return ret;
4092 } 4092 }
4093 4093
4094 ret = bsg_register_queue(q, disk->disk_name);
4095 if (ret) {
4096 elv_unregister_queue(q);
4097 kobject_unregister(&q->kobj);
4098 return ret;
4099 }
4100
4101 return 0; 4094 return 0;
4102} 4095}
4103 4096
@@ -4106,7 +4099,6 @@ void blk_unregister_queue(struct gendisk *disk)
4106 request_queue_t *q = disk->queue; 4099 request_queue_t *q = disk->queue;
4107 4100
4108 if (q && q->request_fn) { 4101 if (q && q->request_fn) {
4109 bsg_unregister_queue(q);
4110 elv_unregister_queue(q); 4102 elv_unregister_queue(q);
4111 4103
4112 kobject_uevent(&q->kobj, KOBJ_REMOVE); 4104 kobject_uevent(&q->kobj, KOBJ_REMOVE);