aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJames Bottomley <James.Bottomley@steeleye.com>2007-07-20 19:22:17 -0400
committerJames Bottomley <jejb@mulgrave.localdomain>2007-07-21 09:58:23 -0400
commit39dca558a5b52b63e49bc234a7e887be092aa690 (patch)
tree31c3c412458e657fdbedc73f50b7de26c7ed0c4a
parent0e78d158b67fba3977f577f293c323359d80dd0e (diff)
[SCSI] bsg: make class backlinks
Currently, bsg doesn't make class backlinks (a process whereby you'd get a link to bsg in the device directory in the same way you get one for sg). This is because the bsg device is uninitialised, so the class device has nothing it can attach to. The fix is to make the bsg device point to the cdevice of the entity creating the bsg, necessitating changing the bsg_register_queue() prototype into a form that takes the generic device. Acked-by: FUJITA Tomonori <tomof@acm.org> Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
-rw-r--r--block/bsg.c21
-rw-r--r--drivers/scsi/scsi_sysfs.c2
-rw-r--r--drivers/scsi/scsi_transport_sas.c32
-rw-r--r--include/linux/bsg.h4
4 files changed, 38 insertions, 21 deletions
diff --git a/block/bsg.c b/block/bsg.c
index 0e3d5d490d2..4eebcd5c731 100644
--- a/block/bsg.c
+++ b/block/bsg.c
@@ -936,20 +936,29 @@ void bsg_unregister_queue(struct request_queue *q)
936 936
937 mutex_lock(&bsg_mutex); 937 mutex_lock(&bsg_mutex);
938 sysfs_remove_link(&q->kobj, "bsg"); 938 sysfs_remove_link(&q->kobj, "bsg");
939 class_device_destroy(bsg_class, MKDEV(bsg_major, bcd->minor)); 939 class_device_unregister(bcd->class_dev);
940 put_device(bcd->dev);
940 bcd->class_dev = NULL; 941 bcd->class_dev = NULL;
942 bcd->dev = NULL;
941 list_del_init(&bcd->list); 943 list_del_init(&bcd->list);
942 bsg_device_nr--; 944 bsg_device_nr--;
943 mutex_unlock(&bsg_mutex); 945 mutex_unlock(&bsg_mutex);
944} 946}
945EXPORT_SYMBOL_GPL(bsg_unregister_queue); 947EXPORT_SYMBOL_GPL(bsg_unregister_queue);
946 948
947int bsg_register_queue(struct request_queue *q, const char *name) 949int bsg_register_queue(struct request_queue *q, struct device *gdev,
950 const char *name)
948{ 951{
949 struct bsg_class_device *bcd, *__bcd; 952 struct bsg_class_device *bcd, *__bcd;
950 dev_t dev; 953 dev_t dev;
951 int ret = -EMFILE; 954 int ret = -EMFILE;
952 struct class_device *class_dev = NULL; 955 struct class_device *class_dev = NULL;
956 const char *devname;
957
958 if (name)
959 devname = name;
960 else
961 devname = gdev->bus_id;
953 962
954 /* 963 /*
955 * we need a proper transport to send commands, not a stacked device 964 * we need a proper transport to send commands, not a stacked device
@@ -982,11 +991,13 @@ retry:
982 bsg_minor_idx = 0; 991 bsg_minor_idx = 0;
983 992
984 bcd->queue = q; 993 bcd->queue = q;
994 bcd->dev = get_device(gdev);
985 dev = MKDEV(bsg_major, bcd->minor); 995 dev = MKDEV(bsg_major, bcd->minor);
986 class_dev = class_device_create(bsg_class, NULL, dev, bcd->dev, "%s", name); 996 class_dev = class_device_create(bsg_class, NULL, dev, gdev, "%s",
997 devname);
987 if (IS_ERR(class_dev)) { 998 if (IS_ERR(class_dev)) {
988 ret = PTR_ERR(class_dev); 999 ret = PTR_ERR(class_dev);
989 goto err; 1000 goto err_put;
990 } 1001 }
991 bcd->class_dev = class_dev; 1002 bcd->class_dev = class_dev;
992 1003
@@ -1004,6 +1015,8 @@ retry:
1004 1015
1005err_unregister: 1016err_unregister:
1006 class_device_unregister(class_dev); 1017 class_device_unregister(class_dev);
1018err_put:
1019 put_device(gdev);
1007err: 1020err:
1008 mutex_unlock(&bsg_mutex); 1021 mutex_unlock(&bsg_mutex);
1009 return ret; 1022 return ret;
diff --git a/drivers/scsi/scsi_sysfs.c b/drivers/scsi/scsi_sysfs.c
index ad5f21fd5d4..34cdce6738a 100644
--- a/drivers/scsi/scsi_sysfs.c
+++ b/drivers/scsi/scsi_sysfs.c
@@ -736,7 +736,7 @@ int scsi_sysfs_add_sdev(struct scsi_device *sdev)
736 * released by the sdev_class .release */ 736 * released by the sdev_class .release */
737 get_device(&sdev->sdev_gendev); 737 get_device(&sdev->sdev_gendev);
738 738
739 error = bsg_register_queue(rq, sdev->sdev_gendev.bus_id); 739 error = bsg_register_queue(rq, &sdev->sdev_gendev, NULL);
740 740
741 if (error) 741 if (error)
742 sdev_printk(KERN_INFO, sdev, 742 sdev_printk(KERN_INFO, sdev,
diff --git a/drivers/scsi/scsi_transport_sas.c b/drivers/scsi/scsi_transport_sas.c
index 573f588154d..3120f4b3a11 100644
--- a/drivers/scsi/scsi_transport_sas.c
+++ b/drivers/scsi/scsi_transport_sas.c
@@ -191,25 +191,34 @@ static void sas_non_host_smp_request(struct request_queue *q)
191 sas_smp_request(q, rphy_to_shost(rphy), rphy); 191 sas_smp_request(q, rphy_to_shost(rphy), rphy);
192} 192}
193 193
194static int sas_bsg_initialize(struct Scsi_Host *shost, struct sas_rphy *rphy, 194static int sas_bsg_initialize(struct Scsi_Host *shost, struct sas_rphy *rphy)
195 char *name)
196{ 195{
197 struct request_queue *q; 196 struct request_queue *q;
198 int error; 197 int error;
198 struct device *dev;
199 char namebuf[BUS_ID_SIZE];
200 const char *name;
199 201
200 if (!to_sas_internal(shost->transportt)->f->smp_handler) { 202 if (!to_sas_internal(shost->transportt)->f->smp_handler) {
201 printk("%s can't handle SMP requests\n", shost->hostt->name); 203 printk("%s can't handle SMP requests\n", shost->hostt->name);
202 return 0; 204 return 0;
203 } 205 }
204 206
205 if (rphy) 207 if (rphy) {
206 q = blk_init_queue(sas_non_host_smp_request, NULL); 208 q = blk_init_queue(sas_non_host_smp_request, NULL);
207 else 209 dev = &rphy->dev;
210 name = dev->bus_id;
211 } else {
208 q = blk_init_queue(sas_host_smp_request, NULL); 212 q = blk_init_queue(sas_host_smp_request, NULL);
213 dev = &shost->shost_gendev;
214 snprintf(namebuf, sizeof(namebuf),
215 "sas_host%d", shost->host_no);
216 name = namebuf;
217 }
209 if (!q) 218 if (!q)
210 return -ENOMEM; 219 return -ENOMEM;
211 220
212 error = bsg_register_queue(q, name); 221 error = bsg_register_queue(q, dev, name);
213 if (error) { 222 if (error) {
214 blk_cleanup_queue(q); 223 blk_cleanup_queue(q);
215 return -ENOMEM; 224 return -ENOMEM;
@@ -255,7 +264,6 @@ static int sas_host_setup(struct transport_container *tc, struct device *dev,
255{ 264{
256 struct Scsi_Host *shost = dev_to_shost(dev); 265 struct Scsi_Host *shost = dev_to_shost(dev);
257 struct sas_host_attrs *sas_host = to_sas_host_attrs(shost); 266 struct sas_host_attrs *sas_host = to_sas_host_attrs(shost);
258 char name[BUS_ID_SIZE];
259 267
260 INIT_LIST_HEAD(&sas_host->rphy_list); 268 INIT_LIST_HEAD(&sas_host->rphy_list);
261 mutex_init(&sas_host->lock); 269 mutex_init(&sas_host->lock);
@@ -263,8 +271,7 @@ static int sas_host_setup(struct transport_container *tc, struct device *dev,
263 sas_host->next_expander_id = 0; 271 sas_host->next_expander_id = 0;
264 sas_host->next_port_id = 0; 272 sas_host->next_port_id = 0;
265 273
266 snprintf(name, sizeof(name), "sas_host%d", shost->host_no); 274 if (sas_bsg_initialize(shost, NULL))
267 if (sas_bsg_initialize(shost, NULL, name))
268 dev_printk(KERN_ERR, dev, "fail to a bsg device %d\n", 275 dev_printk(KERN_ERR, dev, "fail to a bsg device %d\n",
269 shost->host_no); 276 shost->host_no);
270 277
@@ -1332,9 +1339,6 @@ struct sas_rphy *sas_end_device_alloc(struct sas_port *parent)
1332 sas_rphy_initialize(&rdev->rphy); 1339 sas_rphy_initialize(&rdev->rphy);
1333 transport_setup_device(&rdev->rphy.dev); 1340 transport_setup_device(&rdev->rphy.dev);
1334 1341
1335 if (sas_bsg_initialize(shost, &rdev->rphy, rdev->rphy.dev.bus_id))
1336 printk("fail to a bsg device %s\n", rdev->rphy.dev.bus_id);
1337
1338 return &rdev->rphy; 1342 return &rdev->rphy;
1339} 1343}
1340EXPORT_SYMBOL(sas_end_device_alloc); 1344EXPORT_SYMBOL(sas_end_device_alloc);
@@ -1374,9 +1378,6 @@ struct sas_rphy *sas_expander_alloc(struct sas_port *parent,
1374 sas_rphy_initialize(&rdev->rphy); 1378 sas_rphy_initialize(&rdev->rphy);
1375 transport_setup_device(&rdev->rphy.dev); 1379 transport_setup_device(&rdev->rphy.dev);
1376 1380
1377 if (sas_bsg_initialize(shost, &rdev->rphy, rdev->rphy.dev.bus_id))
1378 printk("fail to a bsg device %s\n", rdev->rphy.dev.bus_id);
1379
1380 return &rdev->rphy; 1381 return &rdev->rphy;
1381} 1382}
1382EXPORT_SYMBOL(sas_expander_alloc); 1383EXPORT_SYMBOL(sas_expander_alloc);
@@ -1404,6 +1405,9 @@ int sas_rphy_add(struct sas_rphy *rphy)
1404 return error; 1405 return error;
1405 transport_add_device(&rphy->dev); 1406 transport_add_device(&rphy->dev);
1406 transport_configure_device(&rphy->dev); 1407 transport_configure_device(&rphy->dev);
1408 if (sas_bsg_initialize(shost, rphy))
1409 printk("fail to a bsg device %s\n", rphy->dev.bus_id);
1410
1407 1411
1408 mutex_lock(&sas_host->lock); 1412 mutex_lock(&sas_host->lock);
1409 list_add_tail(&rphy->list, &sas_host->rphy_list); 1413 list_add_tail(&rphy->list, &sas_host->rphy_list);
diff --git a/include/linux/bsg.h b/include/linux/bsg.h
index 8547b10c388..f415f89e0ac 100644
--- a/include/linux/bsg.h
+++ b/include/linux/bsg.h
@@ -57,10 +57,10 @@ struct bsg_class_device {
57 struct request_queue *queue; 57 struct request_queue *queue;
58}; 58};
59 59
60extern int bsg_register_queue(struct request_queue *, const char *); 60extern int bsg_register_queue(struct request_queue *, struct device *, const char *);
61extern void bsg_unregister_queue(struct request_queue *); 61extern void bsg_unregister_queue(struct request_queue *);
62#else 62#else
63#define bsg_register_queue(disk, name) (0) 63#define bsg_register_queue(disk, dev, name) (0)
64#define bsg_unregister_queue(disk) do { } while (0) 64#define bsg_unregister_queue(disk) do { } while (0)
65#endif 65#endif
66 66