diff options
Diffstat (limited to 'block/bsg.c')
-rw-r--r-- | block/bsg.c | 59 |
1 files changed, 52 insertions, 7 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 | ||
34 | static char bsg_version[] = "block layer sg (bsg) 0.4"; | 36 | static 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; |
989 | err: | 1002 | err: |
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 | |||
1010 | static 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 | ||
1023 | static 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 | |||
1028 | static struct class_interface bsg_intf = { | ||
1029 | .add = bsg_add, | ||
1030 | .remove = bsg_remove, | ||
1031 | }; | ||
1032 | |||
997 | static int __init bsg_init(void) | 1033 | static 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"); | |||
1029 | MODULE_DESCRIPTION("Block layer SGSI generic (sg) driver"); | 1074 | MODULE_DESCRIPTION("Block layer SGSI generic (sg) driver"); |
1030 | MODULE_LICENSE("GPL"); | 1075 | MODULE_LICENSE("GPL"); |
1031 | 1076 | ||
1032 | subsys_initcall(bsg_init); | 1077 | device_initcall(bsg_init); |