aboutsummaryrefslogtreecommitdiffstats
path: root/block/bsg.c
diff options
context:
space:
mode:
Diffstat (limited to 'block/bsg.c')
-rw-r--r--block/bsg.c61
1 files changed, 23 insertions, 38 deletions
diff --git a/block/bsg.c b/block/bsg.c
index f2992e72b841..b571869928a8 100644
--- a/block/bsg.c
+++ b/block/bsg.c
@@ -932,24 +932,34 @@ void bsg_unregister_queue(struct request_queue *q)
932{ 932{
933 struct bsg_class_device *bcd = &q->bsg_dev; 933 struct bsg_class_device *bcd = &q->bsg_dev;
934 934
935 WARN_ON(!bcd->class_dev); 935 if (!bcd->class_dev)
936 return;
936 937
937 mutex_lock(&bsg_mutex); 938 mutex_lock(&bsg_mutex);
938 sysfs_remove_link(&q->kobj, "bsg"); 939 sysfs_remove_link(&q->kobj, "bsg");
939 class_device_destroy(bsg_class, MKDEV(bsg_major, bcd->minor)); 940 class_device_unregister(bcd->class_dev);
941 put_device(bcd->dev);
940 bcd->class_dev = NULL; 942 bcd->class_dev = NULL;
943 bcd->dev = NULL;
941 list_del_init(&bcd->list); 944 list_del_init(&bcd->list);
942 bsg_device_nr--; 945 bsg_device_nr--;
943 mutex_unlock(&bsg_mutex); 946 mutex_unlock(&bsg_mutex);
944} 947}
945EXPORT_SYMBOL_GPL(bsg_unregister_queue); 948EXPORT_SYMBOL_GPL(bsg_unregister_queue);
946 949
947int bsg_register_queue(struct request_queue *q, const char *name) 950int bsg_register_queue(struct request_queue *q, struct device *gdev,
951 const char *name)
948{ 952{
949 struct bsg_class_device *bcd, *__bcd; 953 struct bsg_class_device *bcd, *__bcd;
950 dev_t dev; 954 dev_t dev;
951 int ret = -EMFILE; 955 int ret = -EMFILE;
952 struct class_device *class_dev = NULL; 956 struct class_device *class_dev = NULL;
957 const char *devname;
958
959 if (name)
960 devname = name;
961 else
962 devname = gdev->bus_id;
953 963
954 /* 964 /*
955 * we need a proper transport to send commands, not a stacked device 965 * we need a proper transport to send commands, not a stacked device
@@ -982,18 +992,20 @@ retry:
982 bsg_minor_idx = 0; 992 bsg_minor_idx = 0;
983 993
984 bcd->queue = q; 994 bcd->queue = q;
995 bcd->dev = get_device(gdev);
985 dev = MKDEV(bsg_major, bcd->minor); 996 dev = MKDEV(bsg_major, bcd->minor);
986 class_dev = class_device_create(bsg_class, NULL, dev, bcd->dev, "%s", name); 997 class_dev = class_device_create(bsg_class, NULL, dev, gdev, "%s",
998 devname);
987 if (IS_ERR(class_dev)) { 999 if (IS_ERR(class_dev)) {
988 ret = PTR_ERR(class_dev); 1000 ret = PTR_ERR(class_dev);
989 goto err; 1001 goto err_put;
990 } 1002 }
991 bcd->class_dev = class_dev; 1003 bcd->class_dev = class_dev;
992 1004
993 if (q->kobj.sd) { 1005 if (q->kobj.sd) {
994 ret = sysfs_create_link(&q->kobj, &bcd->class_dev->kobj, "bsg"); 1006 ret = sysfs_create_link(&q->kobj, &bcd->class_dev->kobj, "bsg");
995 if (ret) 1007 if (ret)
996 goto err; 1008 goto err_unregister;
997 } 1009 }
998 1010
999 list_add_tail(&bcd->list, &bsg_class_list); 1011 list_add_tail(&bcd->list, &bsg_class_list);
@@ -1001,37 +1013,17 @@ retry:
1001 1013
1002 mutex_unlock(&bsg_mutex); 1014 mutex_unlock(&bsg_mutex);
1003 return 0; 1015 return 0;
1016
1017err_unregister:
1018 class_device_unregister(class_dev);
1019err_put:
1020 put_device(gdev);
1004err: 1021err:
1005 if (class_dev)
1006 class_device_destroy(bsg_class, MKDEV(bsg_major, bcd->minor));
1007 mutex_unlock(&bsg_mutex); 1022 mutex_unlock(&bsg_mutex);
1008 return ret; 1023 return ret;
1009} 1024}
1010EXPORT_SYMBOL_GPL(bsg_register_queue); 1025EXPORT_SYMBOL_GPL(bsg_register_queue);
1011 1026
1012static int bsg_add(struct class_device *cl_dev, struct class_interface *cl_intf)
1013{
1014 int ret;
1015 struct scsi_device *sdp = to_scsi_device(cl_dev->dev);
1016 struct request_queue *rq = sdp->request_queue;
1017
1018 if (rq->kobj.parent)
1019 ret = bsg_register_queue(rq, kobject_name(rq->kobj.parent));
1020 else
1021 ret = bsg_register_queue(rq, kobject_name(&sdp->sdev_gendev.kobj));
1022 return ret;
1023}
1024
1025static void bsg_remove(struct class_device *cl_dev, struct class_interface *cl_intf)
1026{
1027 bsg_unregister_queue(to_scsi_device(cl_dev->dev)->request_queue);
1028}
1029
1030static struct class_interface bsg_intf = {
1031 .add = bsg_add,
1032 .remove = bsg_remove,
1033};
1034
1035static struct cdev bsg_cdev = { 1027static struct cdev bsg_cdev = {
1036 .kobj = {.name = "bsg", }, 1028 .kobj = {.name = "bsg", },
1037 .owner = THIS_MODULE, 1029 .owner = THIS_MODULE,
@@ -1069,16 +1061,9 @@ static int __init bsg_init(void)
1069 if (ret) 1061 if (ret)
1070 goto unregister_chrdev; 1062 goto unregister_chrdev;
1071 1063
1072 ret = scsi_register_interface(&bsg_intf);
1073 if (ret)
1074 goto remove_cdev;
1075
1076 printk(KERN_INFO BSG_DESCRIPTION " version " BSG_VERSION 1064 printk(KERN_INFO BSG_DESCRIPTION " version " BSG_VERSION
1077 " loaded (major %d)\n", bsg_major); 1065 " loaded (major %d)\n", bsg_major);
1078 return 0; 1066 return 0;
1079remove_cdev:
1080 printk(KERN_ERR "bsg: failed register scsi interface %d\n", ret);
1081 cdev_del(&bsg_cdev);
1082unregister_chrdev: 1067unregister_chrdev:
1083 unregister_chrdev_region(MKDEV(bsg_major, 0), BSG_MAX_DEVS); 1068 unregister_chrdev_region(MKDEV(bsg_major, 0), BSG_MAX_DEVS);
1084destroy_bsg_class: 1069destroy_bsg_class: