diff options
author | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-07-22 14:36:49 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-07-22 14:36:49 -0400 |
commit | e6f194d8f6f50da6837af637b2fd839c34185f7a (patch) | |
tree | f3c479a2bc24d49a150ff183e2614ee0f76cb366 /block/bsg.c | |
parent | 7578634990fb47cc30083fbd812689aa6deacfc0 (diff) | |
parent | b91421749a1840148d8c81637c03c0ace3f35269 (diff) |
Merge master.kernel.org:/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6
* master.kernel.org:/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6: (60 commits)
[SCSI] libsas: make ATA functions selectable by a config option
[SCSI] bsg: unexport sg v3 helper functions
[SCSI] bsg: fix bsg_unregister_queue
[SCSI] bsg: make class backlinks
[SCSI] 3w-9xxx: add support for 9690SA
[SCSI] bsg: fix bsg_register_queue error path
[SCSI] ESP: Increase ESP_BUS_TIMEOUT to 275.
[SCSI] libsas: fix scr_read/write users and update the libata documentation
[SCSI] mpt fusion: update Kconfig help
[SCSI] scsi_transport_sas: add destructor for bsg
[SCSI] iscsi_tcp: buggered kmalloc()
[SCSI] qla2xxx: Update version number to 8.02.00-k2.
[SCSI] qla2xxx: Add ISP25XX support.
[SCSI] qla2xxx: Use pci_try_set_mwi().
[SCSI] qla2xxx: Use PCI-X/PCI-Express read control interfaces.
[SCSI] qla2xxx: Re-factor isp_operations to static structures.
[SCSI] qla2xxx: Validate mid-layer 'underflow' during check-condition handling.
[SCSI] qla2xxx: Correct setting of 'current' and 'supported' speeds during FDMI registration.
[SCSI] qla2xxx: Generalize iIDMA support.
[SCSI] qla2xxx: Generalize FW-Interface-2 support.
...
Diffstat (limited to 'block/bsg.c')
-rw-r--r-- | block/bsg.c | 61 |
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 | } |
945 | EXPORT_SYMBOL_GPL(bsg_unregister_queue); | 948 | EXPORT_SYMBOL_GPL(bsg_unregister_queue); |
946 | 949 | ||
947 | int bsg_register_queue(struct request_queue *q, const char *name) | 950 | int 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 | |||
1017 | err_unregister: | ||
1018 | class_device_unregister(class_dev); | ||
1019 | err_put: | ||
1020 | put_device(gdev); | ||
1004 | err: | 1021 | err: |
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 | } |
1010 | EXPORT_SYMBOL_GPL(bsg_register_queue); | 1025 | EXPORT_SYMBOL_GPL(bsg_register_queue); |
1011 | 1026 | ||
1012 | static 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 | |||
1025 | static 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 | |||
1030 | static struct class_interface bsg_intf = { | ||
1031 | .add = bsg_add, | ||
1032 | .remove = bsg_remove, | ||
1033 | }; | ||
1034 | |||
1035 | static struct cdev bsg_cdev = { | 1027 | static 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; |
1079 | remove_cdev: | ||
1080 | printk(KERN_ERR "bsg: failed register scsi interface %d\n", ret); | ||
1081 | cdev_del(&bsg_cdev); | ||
1082 | unregister_chrdev: | 1067 | unregister_chrdev: |
1083 | unregister_chrdev_region(MKDEV(bsg_major, 0), BSG_MAX_DEVS); | 1068 | unregister_chrdev_region(MKDEV(bsg_major, 0), BSG_MAX_DEVS); |
1084 | destroy_bsg_class: | 1069 | destroy_bsg_class: |