Gitweb:     
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=4e2872d6b0252d33f28ea67f33704208ca781978
Commit:     4e2872d6b0252d33f28ea67f33704208ca781978
Parent:     d351af01b9307566135cb0f355ca65d0952c10b5
Author:     FUJITA Tomonori <[EMAIL PROTECTED]>
AuthorDate: Wed Mar 28 13:29:24 2007 +0200
Committer:  Jens Axboe <[EMAIL PROTECTED]>
CommitDate: Mon Jul 16 08:52:46 2007 +0200

    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 <[EMAIL PROTECTED]>
    Signed-off-by: Jens Axboe <[EMAIL PROTECTED]>
---
 block/bsg.c       |   59 ++++++++++++++++++++++++++++++++++++++++++++++------
 block/ll_rw_blk.c |    8 -------
 2 files changed, 52 insertions(+), 15 deletions(-)

diff --git a/block/bsg.c b/block/bsg.c
index 4ea4bed..cd0221c 100644
--- a/block/bsg.c
+++ b/block/bsg.c
@@ -29,6 +29,8 @@
 #include <scsi/scsi.h>
 #include <scsi/scsi_ioctl.h>
 #include <scsi/scsi_cmnd.h>
+#include <scsi/scsi_device.h>
+#include <scsi/scsi_driver.h>
 #include <scsi/sg.h>
 
 static char bsg_version[] = "block layer sg (bsg) 0.4";
@@ -962,6 +964,8 @@ int bsg_register_queue(struct request_queue *q, char *name)
 {
        struct bsg_class_device *bcd;
        dev_t dev;
+       int ret;
+       struct class_device *class_dev = NULL;
 
        /*
         * 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)
        bcd->minor = bsg_device_nr;
        bsg_device_nr++;
        bcd->queue = q;
-       bcd->class_dev = class_device_create(bsg_class, NULL, dev, bcd->dev, 
"%s", name);
-       if (!bcd->class_dev)
+       class_dev = class_device_create(bsg_class, NULL, dev, bcd->dev, "%s", 
name);
+       if (IS_ERR(class_dev)) {
+               ret = PTR_ERR(class_dev);
                goto err;
+       }
+       bcd->class_dev = class_dev;
+
+       if (q->kobj.dentry) {
+               ret = sysfs_create_link(&q->kobj, &bcd->class_dev->kobj, "bsg");
+               if (ret)
+                       goto err;
+       }
+
        list_add_tail(&bcd->list, &bsg_class_list);
-       if (sysfs_create_link(&q->kobj, &bcd->class_dev->kobj, "bsg"))
-               goto err;
+
        mutex_unlock(&bsg_mutex);
        return 0;
 err:
        bsg_device_nr--;
-       if (bcd->class_dev)
+       if (class_dev)
                class_device_destroy(bsg_class, MKDEV(BSG_MAJOR, bcd->minor));
        mutex_unlock(&bsg_mutex);
-       return -ENOMEM;
+       return ret;
+}
+
+static int bsg_add(struct class_device *cl_dev, struct class_interface 
*cl_intf)
+{
+       int ret;
+       struct scsi_device *sdp = to_scsi_device(cl_dev->dev);
+       struct request_queue *rq = sdp->request_queue;
+
+       if (rq->kobj.parent)
+               ret = bsg_register_queue(rq, kobject_name(rq->kobj.parent));
+       else
+               ret = bsg_register_queue(rq, 
kobject_name(&sdp->sdev_gendev.kobj));
+       return ret;
 }
 
+static void bsg_remove(struct class_device *cl_dev, struct class_interface 
*cl_intf)
+{
+       bsg_unregister_queue(to_scsi_device(cl_dev->dev)->request_queue);
+}
+
+static struct class_interface bsg_intf = {
+       .add    = bsg_add,
+       .remove = bsg_remove,
+};
+
 static int __init bsg_init(void)
 {
        int ret, i;
@@ -1021,6 +1057,15 @@ static int __init bsg_init(void)
                return ret;
        }
 
+       ret = scsi_register_interface(&bsg_intf);
+       if (ret) {
+               printk(KERN_ERR "bsg: failed register scsi interface %d\n", 
ret);
+               kmem_cache_destroy(bsg_cmd_cachep);
+               class_destroy(bsg_class);
+               unregister_chrdev(BSG_MAJOR, "bsg");
+               return ret;
+       }
+
        printk(KERN_INFO "%s loaded\n", bsg_version);
        return 0;
 }
@@ -1029,4 +1074,4 @@ MODULE_AUTHOR("Jens Axboe");
 MODULE_DESCRIPTION("Block layer SGSI generic (sg) driver");
 MODULE_LICENSE("GPL");
 
-subsys_initcall(bsg_init);
+device_initcall(bsg_init);
diff --git a/block/ll_rw_blk.c b/block/ll_rw_blk.c
index 74a5498..ef42bb2 100644
--- a/block/ll_rw_blk.c
+++ b/block/ll_rw_blk.c
@@ -4091,13 +4091,6 @@ int blk_register_queue(struct gendisk *disk)
                return ret;
        }
 
-       ret = bsg_register_queue(q, disk->disk_name);
-       if (ret) {
-               elv_unregister_queue(q);
-               kobject_unregister(&q->kobj);
-               return ret;
-       }
-
        return 0;
 }
 
@@ -4106,7 +4099,6 @@ void blk_unregister_queue(struct gendisk *disk)
        request_queue_t *q = disk->queue;
 
        if (q && q->request_fn) {
-               bsg_unregister_queue(q);
                elv_unregister_queue(q);
 
                kobject_uevent(&q->kobj, KOBJ_REMOVE);
-
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to