aboutsummaryrefslogtreecommitdiffstats
path: root/block
diff options
context:
space:
mode:
authorFUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>2007-03-28 07:29:58 -0400
committerJens Axboe <jens.axboe@oracle.com>2007-07-16 02:52:46 -0400
commit292b7f27129272c9ec0ee5fa56abb6f9061b1d83 (patch)
tree58cfad3604e271fa40e23640170c4737c217c28b /block
parent4e2872d6b0252d33f28ea67f33704208ca781978 (diff)
improve bsg device allocation
This patch addresses on two issues on bsg device allocation. - the current maxium number of bsg devices is 256. It's too small if we allocate bsg devices to all SCSI devices, transport entities, etc. This increses the maxium number to 32768 (taken from the sg driver). - SCSI devices are dynamically added and removed. Currently, bsg can't handle it well since bsd_device->minor is simply increased. This is dependent on the patchset that I posted yesterday: http://marc.info/?l=linux-scsi&m=117440208726755&w=2 Signed-off-by: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp> Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
Diffstat (limited to 'block')
-rw-r--r--block/bsg.c49
1 files changed, 41 insertions, 8 deletions
diff --git a/block/bsg.c b/block/bsg.c
index cd0221c61bfe..4ef3cc550244 100644
--- a/block/bsg.c
+++ b/block/bsg.c
@@ -58,6 +58,7 @@ enum {
58}; 58};
59 59
60#define BSG_DEFAULT_CMDS 64 60#define BSG_DEFAULT_CMDS 64
61#define BSG_MAX_DEVS 32768
61 62
62#undef BSG_DEBUG 63#undef BSG_DEBUG
63 64
@@ -75,7 +76,7 @@ enum {
75#define BSG_MAJOR (240) 76#define BSG_MAJOR (240)
76 77
77static DEFINE_MUTEX(bsg_mutex); 78static DEFINE_MUTEX(bsg_mutex);
78static int bsg_device_nr; 79static int bsg_device_nr, bsg_minor_idx;
79 80
80#define BSG_LIST_SIZE (8) 81#define BSG_LIST_SIZE (8)
81#define bsg_list_idx(minor) ((minor) & (BSG_LIST_SIZE - 1)) 82#define bsg_list_idx(minor) ((minor) & (BSG_LIST_SIZE - 1))
@@ -957,14 +958,15 @@ void bsg_unregister_queue(struct request_queue *q)
957 class_device_destroy(bsg_class, MKDEV(BSG_MAJOR, bcd->minor)); 958 class_device_destroy(bsg_class, MKDEV(BSG_MAJOR, bcd->minor));
958 bcd->class_dev = NULL; 959 bcd->class_dev = NULL;
959 list_del_init(&bcd->list); 960 list_del_init(&bcd->list);
961 bsg_device_nr--;
960 mutex_unlock(&bsg_mutex); 962 mutex_unlock(&bsg_mutex);
961} 963}
962 964
963int bsg_register_queue(struct request_queue *q, char *name) 965int bsg_register_queue(struct request_queue *q, char *name)
964{ 966{
965 struct bsg_class_device *bcd; 967 struct bsg_class_device *bcd, *__bcd;
966 dev_t dev; 968 dev_t dev;
967 int ret; 969 int ret = -EMFILE;
968 struct class_device *class_dev = NULL; 970 struct class_device *class_dev = NULL;
969 971
970 /* 972 /*
@@ -978,10 +980,27 @@ int bsg_register_queue(struct request_queue *q, char *name)
978 INIT_LIST_HEAD(&bcd->list); 980 INIT_LIST_HEAD(&bcd->list);
979 981
980 mutex_lock(&bsg_mutex); 982 mutex_lock(&bsg_mutex);
981 dev = MKDEV(BSG_MAJOR, bsg_device_nr); 983 if (bsg_device_nr == BSG_MAX_DEVS) {
982 bcd->minor = bsg_device_nr; 984 printk(KERN_ERR "bsg: too many bsg devices\n");
983 bsg_device_nr++; 985 goto err;
986 }
987
988retry:
989 list_for_each_entry(__bcd, &bsg_class_list, list) {
990 if (__bcd->minor == bsg_minor_idx) {
991 bsg_minor_idx++;
992 if (bsg_minor_idx == BSG_MAX_DEVS)
993 bsg_minor_idx = 0;
994 goto retry;
995 }
996 }
997
998 bcd->minor = bsg_minor_idx++;
999 if (bsg_minor_idx == BSG_MAX_DEVS)
1000 bsg_minor_idx = 0;
1001
984 bcd->queue = q; 1002 bcd->queue = q;
1003 dev = MKDEV(BSG_MAJOR, bcd->minor);
985 class_dev = class_device_create(bsg_class, NULL, dev, bcd->dev, "%s", name); 1004 class_dev = class_device_create(bsg_class, NULL, dev, bcd->dev, "%s", name);
986 if (IS_ERR(class_dev)) { 1005 if (IS_ERR(class_dev)) {
987 ret = PTR_ERR(class_dev); 1006 ret = PTR_ERR(class_dev);
@@ -996,11 +1015,11 @@ int bsg_register_queue(struct request_queue *q, char *name)
996 } 1015 }
997 1016
998 list_add_tail(&bcd->list, &bsg_class_list); 1017 list_add_tail(&bcd->list, &bsg_class_list);
1018 bsg_device_nr++;
999 1019
1000 mutex_unlock(&bsg_mutex); 1020 mutex_unlock(&bsg_mutex);
1001 return 0; 1021 return 0;
1002err: 1022err:
1003 bsg_device_nr--;
1004 if (class_dev) 1023 if (class_dev)
1005 class_device_destroy(bsg_class, MKDEV(BSG_MAJOR, bcd->minor)); 1024 class_device_destroy(bsg_class, MKDEV(BSG_MAJOR, bcd->minor));
1006 mutex_unlock(&bsg_mutex); 1025 mutex_unlock(&bsg_mutex);
@@ -1030,6 +1049,11 @@ static struct class_interface bsg_intf = {
1030 .remove = bsg_remove, 1049 .remove = bsg_remove,
1031}; 1050};
1032 1051
1052static struct cdev bsg_cdev = {
1053 .kobj = {.name = "bsg", },
1054 .owner = THIS_MODULE,
1055};
1056
1033static int __init bsg_init(void) 1057static int __init bsg_init(void)
1034{ 1058{
1035 int ret, i; 1059 int ret, i;
@@ -1050,10 +1074,19 @@ static int __init bsg_init(void)
1050 return PTR_ERR(bsg_class); 1074 return PTR_ERR(bsg_class);
1051 } 1075 }
1052 1076
1053 ret = register_chrdev(BSG_MAJOR, "bsg", &bsg_fops); 1077 ret = register_chrdev_region(MKDEV(BSG_MAJOR, 0), BSG_MAX_DEVS, "bsg");
1078 if (ret) {
1079 kmem_cache_destroy(bsg_cmd_cachep);
1080 class_destroy(bsg_class);
1081 return ret;
1082 }
1083
1084 cdev_init(&bsg_cdev, &bsg_fops);
1085 ret = cdev_add(&bsg_cdev, MKDEV(BSG_MAJOR, 0), BSG_MAX_DEVS);
1054 if (ret) { 1086 if (ret) {
1055 kmem_cache_destroy(bsg_cmd_cachep); 1087 kmem_cache_destroy(bsg_cmd_cachep);
1056 class_destroy(bsg_class); 1088 class_destroy(bsg_class);
1089 unregister_chrdev_region(MKDEV(BSG_MAJOR, 0), BSG_MAX_DEVS);
1057 return ret; 1090 return ret;
1058 } 1091 }
1059 1092