aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorStephen M. Cameron <scameron@beardog.cce.hp.com>2009-09-17 14:47:14 -0400
committerJens Axboe <jens.axboe@oracle.com>2009-10-01 15:15:41 -0400
commit617e1344229d22ea9ecb6538e50808541618ed2b (patch)
tree8e6020a20ccb2c74b1547a6563e989be0c0eb133 /drivers
parent21d9db0b6231ef908fcdbfacefa392352776857f (diff)
cciss: Dynamically allocate struct device for each logical drive as needed.
Dynamically allocate struct device for each logical drive as needed instead of allocating the maximum we would ever need at driver init time. Signed-off-by: Stephen M. Cameron <scameron@beardog.cce.hp.com> Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/block/cciss.c98
-rw-r--r--drivers/block/cciss.h2
2 files changed, 73 insertions, 27 deletions
diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c
index e15f4acf08a2..30b328aefe7d 100644
--- a/drivers/block/cciss.c
+++ b/drivers/block/cciss.c
@@ -198,6 +198,8 @@ static void fail_all_cmds(unsigned long ctlr);
198static int add_to_scan_list(struct ctlr_info *h); 198static int add_to_scan_list(struct ctlr_info *h);
199static int scan_thread(void *data); 199static int scan_thread(void *data);
200static int check_for_unit_attention(ctlr_info_t *h, CommandList_struct *c); 200static int check_for_unit_attention(ctlr_info_t *h, CommandList_struct *c);
201static void cciss_hba_release(struct device *dev);
202static void cciss_device_release(struct device *dev);
201 203
202#ifdef CONFIG_PROC_FS 204#ifdef CONFIG_PROC_FS
203static void cciss_procinit(int i); 205static void cciss_procinit(int i);
@@ -459,7 +461,6 @@ static void __devinit cciss_procinit(int i)
459#define MAX_PRODUCT_NAME_LEN 19 461#define MAX_PRODUCT_NAME_LEN 19
460 462
461#define to_hba(n) container_of(n, struct ctlr_info, dev) 463#define to_hba(n) container_of(n, struct ctlr_info, dev)
462#define to_drv(n) container_of(n, drive_info_struct, dev)
463 464
464static ssize_t host_store_rescan(struct device *dev, 465static ssize_t host_store_rescan(struct device *dev,
465 struct device_attribute *attr, 466 struct device_attribute *attr,
@@ -479,8 +480,8 @@ static ssize_t dev_show_unique_id(struct device *dev,
479 struct device_attribute *attr, 480 struct device_attribute *attr,
480 char *buf) 481 char *buf)
481{ 482{
482 drive_info_struct *drv = to_drv(dev); 483 drive_info_struct *drv = dev_get_drvdata(dev);
483 struct ctlr_info *h = to_hba(drv->dev.parent); 484 struct ctlr_info *h = to_hba(drv->dev->parent);
484 __u8 sn[16]; 485 __u8 sn[16];
485 unsigned long flags; 486 unsigned long flags;
486 int ret = 0; 487 int ret = 0;
@@ -509,8 +510,8 @@ static ssize_t dev_show_vendor(struct device *dev,
509 struct device_attribute *attr, 510 struct device_attribute *attr,
510 char *buf) 511 char *buf)
511{ 512{
512 drive_info_struct *drv = to_drv(dev); 513 drive_info_struct *drv = dev_get_drvdata(dev);
513 struct ctlr_info *h = to_hba(drv->dev.parent); 514 struct ctlr_info *h = to_hba(drv->dev->parent);
514 char vendor[VENDOR_LEN + 1]; 515 char vendor[VENDOR_LEN + 1];
515 unsigned long flags; 516 unsigned long flags;
516 int ret = 0; 517 int ret = 0;
@@ -533,8 +534,8 @@ static ssize_t dev_show_model(struct device *dev,
533 struct device_attribute *attr, 534 struct device_attribute *attr,
534 char *buf) 535 char *buf)
535{ 536{
536 drive_info_struct *drv = to_drv(dev); 537 drive_info_struct *drv = dev_get_drvdata(dev);
537 struct ctlr_info *h = to_hba(drv->dev.parent); 538 struct ctlr_info *h = to_hba(drv->dev->parent);
538 char model[MODEL_LEN + 1]; 539 char model[MODEL_LEN + 1];
539 unsigned long flags; 540 unsigned long flags;
540 int ret = 0; 541 int ret = 0;
@@ -557,8 +558,8 @@ static ssize_t dev_show_rev(struct device *dev,
557 struct device_attribute *attr, 558 struct device_attribute *attr,
558 char *buf) 559 char *buf)
559{ 560{
560 drive_info_struct *drv = to_drv(dev); 561 drive_info_struct *drv = dev_get_drvdata(dev);
561 struct ctlr_info *h = to_hba(drv->dev.parent); 562 struct ctlr_info *h = to_hba(drv->dev->parent);
562 char rev[REV_LEN + 1]; 563 char rev[REV_LEN + 1];
563 unsigned long flags; 564 unsigned long flags;
564 int ret = 0; 565 int ret = 0;
@@ -594,6 +595,7 @@ static struct attribute_group *cciss_host_attr_groups[] = {
594static struct device_type cciss_host_type = { 595static struct device_type cciss_host_type = {
595 .name = "cciss_host", 596 .name = "cciss_host",
596 .groups = cciss_host_attr_groups, 597 .groups = cciss_host_attr_groups,
598 .release = cciss_hba_release,
597}; 599};
598 600
599static struct attribute *cciss_dev_attrs[] = { 601static struct attribute *cciss_dev_attrs[] = {
@@ -616,12 +618,24 @@ static const struct attribute_group *cciss_dev_attr_groups[] = {
616static struct device_type cciss_dev_type = { 618static struct device_type cciss_dev_type = {
617 .name = "cciss_device", 619 .name = "cciss_device",
618 .groups = cciss_dev_attr_groups, 620 .groups = cciss_dev_attr_groups,
621 .release = cciss_device_release,
619}; 622};
620 623
621static struct bus_type cciss_bus_type = { 624static struct bus_type cciss_bus_type = {
622 .name = "cciss", 625 .name = "cciss",
623}; 626};
624 627
628/*
629 * cciss_hba_release is called when the reference count
630 * of h->dev goes to zero.
631 */
632static void cciss_hba_release(struct device *dev)
633{
634 /*
635 * nothing to do, but need this to avoid a warning
636 * about not having a release handler from lib/kref.c.
637 */
638}
625 639
626/* 640/*
627 * Initialize sysfs entry for each controller. This sets up and registers 641 * Initialize sysfs entry for each controller. This sets up and registers
@@ -645,6 +659,15 @@ static int cciss_create_hba_sysfs_entry(struct ctlr_info *h)
645static void cciss_destroy_hba_sysfs_entry(struct ctlr_info *h) 659static void cciss_destroy_hba_sysfs_entry(struct ctlr_info *h)
646{ 660{
647 device_del(&h->dev); 661 device_del(&h->dev);
662 put_device(&h->dev); /* final put. */
663}
664
665/* cciss_device_release is called when the reference count
666 * of h->drv[x].dev goes to zero.
667 */
668static void cciss_device_release(struct device *dev)
669{
670 kfree(dev);
648} 671}
649 672
650/* 673/*
@@ -653,24 +676,33 @@ static void cciss_destroy_hba_sysfs_entry(struct ctlr_info *h)
653 * /sys/bus/pci/devices/<dev/ccis#/. We also create a link from 676 * /sys/bus/pci/devices/<dev/ccis#/. We also create a link from
654 * /sys/block/cciss!c#d# to this entry. 677 * /sys/block/cciss!c#d# to this entry.
655 */ 678 */
656static int cciss_create_ld_sysfs_entry(struct ctlr_info *h, 679static long cciss_create_ld_sysfs_entry(struct ctlr_info *h,
657 drive_info_struct *drv,
658 int drv_index) 680 int drv_index)
659{ 681{
660 device_initialize(&drv->dev); 682 struct device *dev;
661 drv->dev.type = &cciss_dev_type; 683
662 drv->dev.bus = &cciss_bus_type; 684 dev = kzalloc(sizeof(*dev), GFP_KERNEL);
663 dev_set_name(&drv->dev, "c%dd%d", h->ctlr, drv_index); 685 if (!dev)
664 drv->dev.parent = &h->dev; 686 return -ENOMEM;
665 return device_add(&drv->dev); 687 device_initialize(dev);
688 dev->type = &cciss_dev_type;
689 dev->bus = &cciss_bus_type;
690 dev_set_name(dev, "c%dd%d", h->ctlr, drv_index);
691 dev->parent = &h->dev;
692 h->drv[drv_index].dev = dev;
693 dev_set_drvdata(dev, &h->drv[drv_index]);
694 return device_add(dev);
666} 695}
667 696
668/* 697/*
669 * Remove sysfs entries for a logical drive. 698 * Remove sysfs entries for a logical drive.
670 */ 699 */
671static void cciss_destroy_ld_sysfs_entry(drive_info_struct *drv) 700static void cciss_destroy_ld_sysfs_entry(struct ctlr_info *h, int drv_index)
672{ 701{
673 device_del(&drv->dev); 702 struct device *dev = h->drv[drv_index].dev;
703 device_del(dev);
704 put_device(dev); /* the "final" put. */
705 h->drv[drv_index].dev = NULL;
674} 706}
675 707
676/* 708/*
@@ -1651,7 +1683,10 @@ static void cciss_get_serial_no(int ctlr, int logvol, int withirq,
1651 return; 1683 return;
1652} 1684}
1653 1685
1654static void cciss_add_disk(ctlr_info_t *h, struct gendisk *disk, 1686/*
1687 * cciss_add_disk sets up the block device queue for a logical drive
1688 */
1689static int cciss_add_disk(ctlr_info_t *h, struct gendisk *disk,
1655 int drv_index) 1690 int drv_index)
1656{ 1691{
1657 disk->queue = blk_init_queue(do_cciss_request, &h->lock); 1692 disk->queue = blk_init_queue(do_cciss_request, &h->lock);
@@ -1659,8 +1694,12 @@ static void cciss_add_disk(ctlr_info_t *h, struct gendisk *disk,
1659 disk->major = h->major; 1694 disk->major = h->major;
1660 disk->first_minor = drv_index << NWD_SHIFT; 1695 disk->first_minor = drv_index << NWD_SHIFT;
1661 disk->fops = &cciss_fops; 1696 disk->fops = &cciss_fops;
1697 if (h->drv[drv_index].dev == NULL) {
1698 if (cciss_create_ld_sysfs_entry(h, drv_index))
1699 goto cleanup_queue;
1700 }
1662 disk->private_data = &h->drv[drv_index]; 1701 disk->private_data = &h->drv[drv_index];
1663 disk->driverfs_dev = &h->drv[drv_index].dev; 1702 disk->driverfs_dev = h->drv[drv_index].dev;
1664 1703
1665 /* Set up queue information */ 1704 /* Set up queue information */
1666 blk_queue_bounce_limit(disk->queue, h->pdev->dma_mask); 1705 blk_queue_bounce_limit(disk->queue, h->pdev->dma_mask);
@@ -1686,6 +1725,12 @@ static void cciss_add_disk(ctlr_info_t *h, struct gendisk *disk,
1686 wmb(); 1725 wmb();
1687 h->drv[drv_index].queue = disk->queue; 1726 h->drv[drv_index].queue = disk->queue;
1688 add_disk(disk); 1727 add_disk(disk);
1728 return 0;
1729
1730cleanup_queue:
1731 blk_cleanup_queue(disk->queue);
1732 disk->queue = NULL;
1733 return -1;
1689} 1734}
1690 1735
1691/* This function will check the usage_count of the drive to be updated/added. 1736/* This function will check the usage_count of the drive to be updated/added.
@@ -1871,7 +1916,7 @@ static int cciss_add_gendisk(ctlr_info_t *h, __u32 lunid, int controller_node)
1871 } 1916 }
1872 } 1917 }
1873 h->drv[drv_index].LunID = lunid; 1918 h->drv[drv_index].LunID = lunid;
1874 if (cciss_create_ld_sysfs_entry(h, &h->drv[drv_index], drv_index)) 1919 if (cciss_create_ld_sysfs_entry(h, drv_index))
1875 goto err_free_disk; 1920 goto err_free_disk;
1876 1921
1877 /* Don't need to mark this busy because nobody */ 1922 /* Don't need to mark this busy because nobody */
@@ -2145,7 +2190,7 @@ static int deregister_disk(ctlr_info_t *h, int drv_index,
2145 * indicate that this element of the drive 2190 * indicate that this element of the drive
2146 * array is free. 2191 * array is free.
2147 */ 2192 */
2148 cciss_destroy_ld_sysfs_entry(drv); 2193 cciss_destroy_ld_sysfs_entry(h, drv_index);
2149 2194
2150 if (clear_all) { 2195 if (clear_all) {
2151 /* check to see if it was the last disk */ 2196 /* check to see if it was the last disk */
@@ -4268,8 +4313,9 @@ static void __devexit cciss_remove_one(struct pci_dev *pdev)
4268 if (q) 4313 if (q)
4269 blk_cleanup_queue(q); 4314 blk_cleanup_queue(q);
4270 } 4315 }
4271 if (hba[i]->drv[j].raid_level != -1) 4316 if (hba[i]->drv[j].dev != NULL &&
4272 cciss_destroy_ld_sysfs_entry(&hba[i]->drv[j]); 4317 (j == 0 || hba[i]->drv[j].raid_level != -1))
4318 cciss_destroy_ld_sysfs_entry(hba[i], j);
4273 4319
4274 } 4320 }
4275 4321
@@ -4345,7 +4391,7 @@ static int __init cciss_init(void)
4345 if (err) 4391 if (err)
4346 goto err_thread_stop; 4392 goto err_thread_stop;
4347 4393
4348 return 0; 4394 return err;
4349 4395
4350err_thread_stop: 4396err_thread_stop:
4351 kthread_stop(cciss_scan_thread); 4397 kthread_stop(cciss_scan_thread);
diff --git a/drivers/block/cciss.h b/drivers/block/cciss.h
index 4fb3639b6cff..96793425688e 100644
--- a/drivers/block/cciss.h
+++ b/drivers/block/cciss.h
@@ -45,7 +45,7 @@ typedef struct _drive_info_struct
45 * to prevent it from being opened or it's 45 * to prevent it from being opened or it's
46 * queue from being started. 46 * queue from being started.
47 */ 47 */
48 struct device dev; 48 struct device *dev;
49 __u8 serial_no[16]; /* from inquiry page 0x83, 49 __u8 serial_no[16]; /* from inquiry page 0x83,
50 * not necc. null terminated. 50 * not necc. null terminated.
51 */ 51 */