aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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 */