Commit 9cef0d2f4f68a5a2c6ea0495f958a074d21fbd07

Authored by Stephen M. Cameron
Committed by Jens Axboe
1 parent e272afecaf

cciss: Dynamically allocate the drive_info_struct for each logical drive.

cciss: Dynamically allocate the drive_info_struct for each logical drive.
This reduces the size of the per-hba ctlr_info structure from 106936
bytes to 8132 bytes.  That's on 32-bit systems.  On 64-bit systems, the
improvement is even bigger.  Without this, the ctlr_info struct is so big
that the driver won't even load on a 64 bit system if CISS_MAX_LUN was
at it's current setting of 1024 logical drives.

Signed-off-by: Stephen M. Cameron <scameron@beardog.cce.hp.com>
Signed-off-by: Jens Axboe <jens.axboe@oracle.com>

Showing 2 changed files with 168 additions and 130 deletions Side-by-side Diff

drivers/block/cciss.c
... ... @@ -201,6 +201,7 @@
201 201 static void cciss_hba_release(struct device *dev);
202 202 static void cciss_device_release(struct device *dev);
203 203 static void cciss_free_gendisk(ctlr_info_t *h, int drv_index);
  204 +static void cciss_free_drive_info(ctlr_info_t *h, int drv_index);
204 205  
205 206 #ifdef CONFIG_PROC_FS
206 207 static void cciss_procinit(int i);
... ... @@ -327,7 +328,7 @@
327 328 ctlr_info_t *h = seq->private;
328 329 unsigned ctlr = h->ctlr;
329 330 loff_t *pos = v;
330   - drive_info_struct *drv = &h->drv[*pos];
  331 + drive_info_struct *drv = h->drv[*pos];
331 332  
332 333 if (*pos > h->highest_lun)
333 334 return 0;
... ... @@ -461,6 +462,7 @@
461 462 #define MAX_PRODUCT_NAME_LEN 19
462 463  
463 464 #define to_hba(n) container_of(n, struct ctlr_info, dev)
  465 +#define to_drv(n) container_of(n, drive_info_struct, dev)
464 466  
465 467 static ssize_t host_store_rescan(struct device *dev,
466 468 struct device_attribute *attr,
... ... @@ -480,8 +482,8 @@
480 482 struct device_attribute *attr,
481 483 char *buf)
482 484 {
483   - drive_info_struct *drv = dev_get_drvdata(dev);
484   - struct ctlr_info *h = to_hba(drv->dev->parent);
  485 + drive_info_struct *drv = to_drv(dev);
  486 + struct ctlr_info *h = to_hba(drv->dev.parent);
485 487 __u8 sn[16];
486 488 unsigned long flags;
487 489 int ret = 0;
... ... @@ -510,8 +512,8 @@
510 512 struct device_attribute *attr,
511 513 char *buf)
512 514 {
513   - drive_info_struct *drv = dev_get_drvdata(dev);
514   - struct ctlr_info *h = to_hba(drv->dev->parent);
  515 + drive_info_struct *drv = to_drv(dev);
  516 + struct ctlr_info *h = to_hba(drv->dev.parent);
515 517 char vendor[VENDOR_LEN + 1];
516 518 unsigned long flags;
517 519 int ret = 0;
... ... @@ -534,8 +536,8 @@
534 536 struct device_attribute *attr,
535 537 char *buf)
536 538 {
537   - drive_info_struct *drv = dev_get_drvdata(dev);
538   - struct ctlr_info *h = to_hba(drv->dev->parent);
  539 + drive_info_struct *drv = to_drv(dev);
  540 + struct ctlr_info *h = to_hba(drv->dev.parent);
539 541 char model[MODEL_LEN + 1];
540 542 unsigned long flags;
541 543 int ret = 0;
... ... @@ -558,8 +560,8 @@
558 560 struct device_attribute *attr,
559 561 char *buf)
560 562 {
561   - drive_info_struct *drv = dev_get_drvdata(dev);
562   - struct ctlr_info *h = to_hba(drv->dev->parent);
  563 + drive_info_struct *drv = to_drv(dev);
  564 + struct ctlr_info *h = to_hba(drv->dev.parent);
563 565 char rev[REV_LEN + 1];
564 566 unsigned long flags;
565 567 int ret = 0;
... ... @@ -581,8 +583,8 @@
581 583 static ssize_t cciss_show_lunid(struct device *dev,
582 584 struct device_attribute *attr, char *buf)
583 585 {
584   - drive_info_struct *drv = dev_get_drvdata(dev);
585   - struct ctlr_info *h = to_hba(drv->dev->parent);
  586 + drive_info_struct *drv = to_drv(dev);
  587 + struct ctlr_info *h = to_hba(drv->dev.parent);
586 588 unsigned long flags;
587 589 unsigned char lunid[8];
588 590  
... ... @@ -606,8 +608,8 @@
606 608 static ssize_t cciss_show_raid_level(struct device *dev,
607 609 struct device_attribute *attr, char *buf)
608 610 {
609   - drive_info_struct *drv = dev_get_drvdata(dev);
610   - struct ctlr_info *h = to_hba(drv->dev->parent);
  611 + drive_info_struct *drv = to_drv(dev);
  612 + struct ctlr_info *h = to_hba(drv->dev.parent);
611 613 int raid;
612 614 unsigned long flags;
613 615  
... ... @@ -629,8 +631,8 @@
629 631 static ssize_t cciss_show_usage_count(struct device *dev,
630 632 struct device_attribute *attr, char *buf)
631 633 {
632   - drive_info_struct *drv = dev_get_drvdata(dev);
633   - struct ctlr_info *h = to_hba(drv->dev->parent);
  634 + drive_info_struct *drv = to_drv(dev);
  635 + struct ctlr_info *h = to_hba(drv->dev.parent);
634 636 unsigned long flags;
635 637 int count;
636 638  
637 639  
... ... @@ -733,11 +735,12 @@
733 735 }
734 736  
735 737 /* cciss_device_release is called when the reference count
736   - * of h->drv[x].dev goes to zero.
  738 + * of h->drv[x]dev goes to zero.
737 739 */
738 740 static void cciss_device_release(struct device *dev)
739 741 {
740   - kfree(dev);
  742 + drive_info_struct *drv = to_drv(dev);
  743 + kfree(drv);
741 744 }
742 745  
743 746 /*
744 747  
745 748  
... ... @@ -751,20 +754,16 @@
751 754 {
752 755 struct device *dev;
753 756  
754   - /* Special case for c*d0, we only create it once. */
755   - if (drv_index == 0 && h->drv[drv_index].dev != NULL)
  757 + if (h->drv[drv_index]->device_initialized)
756 758 return 0;
757 759  
758   - dev = kzalloc(sizeof(*dev), GFP_KERNEL);
759   - if (!dev)
760   - return -ENOMEM;
  760 + dev = &h->drv[drv_index]->dev;
761 761 device_initialize(dev);
762 762 dev->type = &cciss_dev_type;
763 763 dev->bus = &cciss_bus_type;
764 764 dev_set_name(dev, "c%dd%d", h->ctlr, drv_index);
765 765 dev->parent = &h->dev;
766   - h->drv[drv_index].dev = dev;
767   - dev_set_drvdata(dev, &h->drv[drv_index]);
  766 + h->drv[drv_index]->device_initialized = 1;
768 767 return device_add(dev);
769 768 }
770 769  
... ... @@ -774,7 +773,7 @@
774 773 static void cciss_destroy_ld_sysfs_entry(struct ctlr_info *h, int drv_index,
775 774 int ctlr_exiting)
776 775 {
777   - struct device *dev = h->drv[drv_index].dev;
  776 + struct device *dev = &h->drv[drv_index]->dev;
778 777  
779 778 /* special case for c*d0, we only destroy it on controller exit */
780 779 if (drv_index == 0 && !ctlr_exiting)
... ... @@ -782,7 +781,7 @@
782 781  
783 782 device_del(dev);
784 783 put_device(dev); /* the "final" put. */
785   - h->drv[drv_index].dev = NULL;
  784 + h->drv[drv_index] = NULL;
786 785 }
787 786  
788 787 /*
789 788  
... ... @@ -1625,8 +1624,11 @@
1625 1624 /* make sure the disk has been added and the drive is real
1626 1625 * because this can be called from the middle of init_one.
1627 1626 */
1628   - if (!(h->drv[curr_queue].queue) || !(h->drv[curr_queue].heads))
  1627 + if (!h->drv[curr_queue])
1629 1628 continue;
  1629 + if (!(h->drv[curr_queue]->queue) ||
  1630 + !(h->drv[curr_queue]->heads))
  1631 + continue;
1630 1632 blk_start_queue(h->gendisk[curr_queue]->queue);
1631 1633  
1632 1634 /* check to see if we have maxed out the number of commands
... ... @@ -1685,8 +1687,8 @@
1685 1687 static inline void log_unit_to_scsi3addr(ctlr_info_t *h,
1686 1688 unsigned char scsi3addr[], uint32_t log_unit)
1687 1689 {
1688   - memcpy(scsi3addr, h->drv[log_unit].LunID,
1689   - sizeof(h->drv[log_unit].LunID));
  1690 + memcpy(scsi3addr, h->drv[log_unit]->LunID,
  1691 + sizeof(h->drv[log_unit]->LunID));
1690 1692 }
1691 1693  
1692 1694 /* This function gets the SCSI vendor, model, and revision of a logical drive
... ... @@ -1776,12 +1778,10 @@
1776 1778 disk->major = h->major;
1777 1779 disk->first_minor = drv_index << NWD_SHIFT;
1778 1780 disk->fops = &cciss_fops;
1779   - if (h->drv[drv_index].dev == NULL) {
1780   - if (cciss_create_ld_sysfs_entry(h, drv_index))
1781   - goto cleanup_queue;
1782   - }
1783   - disk->private_data = &h->drv[drv_index];
1784   - disk->driverfs_dev = h->drv[drv_index].dev;
  1781 + if (cciss_create_ld_sysfs_entry(h, drv_index))
  1782 + goto cleanup_queue;
  1783 + disk->private_data = h->drv[drv_index];
  1784 + disk->driverfs_dev = &h->drv[drv_index]->dev;
1785 1785  
1786 1786 /* Set up queue information */
1787 1787 blk_queue_bounce_limit(disk->queue, h->pdev->dma_mask);
1788 1788  
1789 1789  
... ... @@ -1799,13 +1799,13 @@
1799 1799 disk->queue->queuedata = h;
1800 1800  
1801 1801 blk_queue_logical_block_size(disk->queue,
1802   - h->drv[drv_index].block_size);
  1802 + h->drv[drv_index]->block_size);
1803 1803  
1804 1804 /* Make sure all queue data is written out before */
1805   - /* setting h->drv[drv_index].queue, as setting this */
  1805 + /* setting h->drv[drv_index]->queue, as setting this */
1806 1806 /* allows the interrupt handler to start the queue */
1807 1807 wmb();
1808   - h->drv[drv_index].queue = disk->queue;
  1808 + h->drv[drv_index]->queue = disk->queue;
1809 1809 add_disk(disk);
1810 1810 return 0;
1811 1811  
... ... @@ -1840,7 +1840,7 @@
1840 1840  
1841 1841 /* Get information about the disk and modify the driver structure */
1842 1842 inq_buff = kmalloc(sizeof(InquiryData_struct), GFP_KERNEL);
1843   - drvinfo = kmalloc(sizeof(*drvinfo), GFP_KERNEL);
  1843 + drvinfo = kzalloc(sizeof(*drvinfo), GFP_KERNEL);
1844 1844 if (inq_buff == NULL || drvinfo == NULL)
1845 1845 goto mem_msg;
1846 1846  
1847 1847  
1848 1848  
... ... @@ -1876,16 +1876,19 @@
1876 1876 drvinfo->model, drvinfo->rev);
1877 1877 cciss_get_serial_no(ctlr, drv_index, 1, drvinfo->serial_no,
1878 1878 sizeof(drvinfo->serial_no));
  1879 + /* Save the lunid in case we deregister the disk, below. */
  1880 + memcpy(drvinfo->LunID, h->drv[drv_index]->LunID,
  1881 + sizeof(drvinfo->LunID));
1879 1882  
1880 1883 /* Is it the same disk we already know, and nothing's changed? */
1881   - if (h->drv[drv_index].raid_level != -1 &&
  1884 + if (h->drv[drv_index]->raid_level != -1 &&
1882 1885 ((memcmp(drvinfo->serial_no,
1883   - h->drv[drv_index].serial_no, 16) == 0) &&
1884   - drvinfo->block_size == h->drv[drv_index].block_size &&
1885   - drvinfo->nr_blocks == h->drv[drv_index].nr_blocks &&
1886   - drvinfo->heads == h->drv[drv_index].heads &&
1887   - drvinfo->sectors == h->drv[drv_index].sectors &&
1888   - drvinfo->cylinders == h->drv[drv_index].cylinders))
  1886 + h->drv[drv_index]->serial_no, 16) == 0) &&
  1887 + drvinfo->block_size == h->drv[drv_index]->block_size &&
  1888 + drvinfo->nr_blocks == h->drv[drv_index]->nr_blocks &&
  1889 + drvinfo->heads == h->drv[drv_index]->heads &&
  1890 + drvinfo->sectors == h->drv[drv_index]->sectors &&
  1891 + drvinfo->cylinders == h->drv[drv_index]->cylinders))
1889 1892 /* The disk is unchanged, nothing to update */
1890 1893 goto freeret;
1891 1894  
1892 1895  
1893 1896  
1894 1897  
... ... @@ -1895,18 +1898,17 @@
1895 1898 * If the disk already exists then deregister it before proceeding
1896 1899 * (unless it's the first disk (for the controller node).
1897 1900 */
1898   - if (h->drv[drv_index].raid_level != -1 && drv_index != 0) {
  1901 + if (h->drv[drv_index]->raid_level != -1 && drv_index != 0) {
1899 1902 printk(KERN_WARNING "disk %d has changed.\n", drv_index);
1900 1903 spin_lock_irqsave(CCISS_LOCK(h->ctlr), flags);
1901   - h->drv[drv_index].busy_configuring = 1;
  1904 + h->drv[drv_index]->busy_configuring = 1;
1902 1905 spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags);
1903 1906  
1904   - /* deregister_disk sets h->drv[drv_index].queue = NULL
  1907 + /* deregister_disk sets h->drv[drv_index]->queue = NULL
1905 1908 * which keeps the interrupt handler from starting
1906 1909 * the queue.
1907 1910 */
1908 1911 ret = deregister_disk(h, drv_index, 0, via_ioctl);
1909   - h->drv[drv_index].busy_configuring = 0;
1910 1912 }
1911 1913  
1912 1914 /* If the disk is in use return */
1913 1915  
1914 1916  
... ... @@ -1914,22 +1916,31 @@
1914 1916 goto freeret;
1915 1917  
1916 1918 /* Save the new information from cciss_geometry_inquiry
1917   - * and serial number inquiry.
  1919 + * and serial number inquiry. If the disk was deregistered
  1920 + * above, then h->drv[drv_index] will be NULL.
1918 1921 */
1919   - h->drv[drv_index].block_size = drvinfo->block_size;
1920   - h->drv[drv_index].nr_blocks = drvinfo->nr_blocks;
1921   - h->drv[drv_index].heads = drvinfo->heads;
1922   - h->drv[drv_index].sectors = drvinfo->sectors;
1923   - h->drv[drv_index].cylinders = drvinfo->cylinders;
1924   - h->drv[drv_index].raid_level = drvinfo->raid_level;
1925   - memcpy(h->drv[drv_index].serial_no, drvinfo->serial_no, 16);
1926   - memcpy(h->drv[drv_index].vendor, drvinfo->vendor, VENDOR_LEN + 1);
1927   - memcpy(h->drv[drv_index].model, drvinfo->model, MODEL_LEN + 1);
1928   - memcpy(h->drv[drv_index].rev, drvinfo->rev, REV_LEN + 1);
  1922 + if (h->drv[drv_index] == NULL) {
  1923 + drvinfo->device_initialized = 0;
  1924 + h->drv[drv_index] = drvinfo;
  1925 + drvinfo = NULL; /* so it won't be freed below. */
  1926 + } else {
  1927 + /* special case for cxd0 */
  1928 + h->drv[drv_index]->block_size = drvinfo->block_size;
  1929 + h->drv[drv_index]->nr_blocks = drvinfo->nr_blocks;
  1930 + h->drv[drv_index]->heads = drvinfo->heads;
  1931 + h->drv[drv_index]->sectors = drvinfo->sectors;
  1932 + h->drv[drv_index]->cylinders = drvinfo->cylinders;
  1933 + h->drv[drv_index]->raid_level = drvinfo->raid_level;
  1934 + memcpy(h->drv[drv_index]->serial_no, drvinfo->serial_no, 16);
  1935 + memcpy(h->drv[drv_index]->vendor, drvinfo->vendor,
  1936 + VENDOR_LEN + 1);
  1937 + memcpy(h->drv[drv_index]->model, drvinfo->model, MODEL_LEN + 1);
  1938 + memcpy(h->drv[drv_index]->rev, drvinfo->rev, REV_LEN + 1);
  1939 + }
1929 1940  
1930 1941 ++h->num_luns;
1931 1942 disk = h->gendisk[drv_index];
1932   - set_capacity(disk, h->drv[drv_index].nr_blocks);
  1943 + set_capacity(disk, h->drv[drv_index]->nr_blocks);
1933 1944  
1934 1945 /* If it's not disk 0 (drv_index != 0)
1935 1946 * or if it was disk 0, but there was previously
... ... @@ -1940,6 +1951,7 @@
1940 1951 if (drv_index || first_time) {
1941 1952 if (cciss_add_disk(h, disk, drv_index) != 0) {
1942 1953 cciss_free_gendisk(h, drv_index);
  1954 + cciss_free_drive_info(h, drv_index);
1943 1955 printk(KERN_WARNING "cciss:%d could not update "
1944 1956 "disk %d\n", h->ctlr, drv_index);
1945 1957 --h->num_luns;
1946 1958  
1947 1959  
1948 1960  
1949 1961  
1950 1962  
1951 1963  
... ... @@ -1956,28 +1968,64 @@
1956 1968 }
1957 1969  
1958 1970 /* This function will find the first index of the controllers drive array
1959   - * that has a -1 for the raid_level and will return that index. This is
1960   - * where new drives will be added. If the index to be returned is greater
1961   - * than the highest_lun index for the controller then highest_lun is set
1962   - * to this new index. If there are no available indexes then -1 is returned.
1963   - * "controller_node" is used to know if this is a real logical drive, or just
1964   - * the controller node, which determines if this counts towards highest_lun.
  1971 + * that has a null drv pointer and allocate the drive info struct and
  1972 + * will return that index This is where new drives will be added.
  1973 + * If the index to be returned is greater than the highest_lun index for
  1974 + * the controller then highest_lun is set * to this new index.
  1975 + * If there are no available indexes or if tha allocation fails, then -1
  1976 + * is returned. * "controller_node" is used to know if this is a real
  1977 + * logical drive, or just the controller node, which determines if this
  1978 + * counts towards highest_lun.
1965 1979 */
1966   -static int cciss_find_free_drive_index(int ctlr, int controller_node)
  1980 +static int cciss_alloc_drive_info(ctlr_info_t *h, int controller_node)
1967 1981 {
1968 1982 int i;
  1983 + drive_info_struct *drv;
1969 1984  
  1985 + /* Search for an empty slot for our drive info */
1970 1986 for (i = 0; i < CISS_MAX_LUN; i++) {
1971   - if (hba[ctlr]->drv[i].raid_level == -1) {
1972   - if (i > hba[ctlr]->highest_lun)
1973   - if (!controller_node)
1974   - hba[ctlr]->highest_lun = i;
  1987 +
  1988 + /* if not cxd0 case, and it's occupied, skip it. */
  1989 + if (h->drv[i] && i != 0)
  1990 + continue;
  1991 + /*
  1992 + * If it's cxd0 case, and drv is alloc'ed already, and a
  1993 + * disk is configured there, skip it.
  1994 + */
  1995 + if (i == 0 && h->drv[i] && h->drv[i]->raid_level != -1)
  1996 + continue;
  1997 +
  1998 + /*
  1999 + * We've found an empty slot. Update highest_lun
  2000 + * provided this isn't just the fake cxd0 controller node.
  2001 + */
  2002 + if (i > h->highest_lun && !controller_node)
  2003 + h->highest_lun = i;
  2004 +
  2005 + /* If adding a real disk at cxd0, and it's already alloc'ed */
  2006 + if (i == 0 && h->drv[i] != NULL)
1975 2007 return i;
1976   - }
  2008 +
  2009 + /*
  2010 + * Found an empty slot, not already alloc'ed. Allocate it.
  2011 + * Mark it with raid_level == -1, so we know it's new later on.
  2012 + */
  2013 + drv = kzalloc(sizeof(*drv), GFP_KERNEL);
  2014 + if (!drv)
  2015 + return -1;
  2016 + drv->raid_level = -1; /* so we know it's new */
  2017 + h->drv[i] = drv;
  2018 + return i;
1977 2019 }
1978 2020 return -1;
1979 2021 }
1980 2022  
  2023 +static void cciss_free_drive_info(ctlr_info_t *h, int drv_index)
  2024 +{
  2025 + kfree(h->drv[drv_index]);
  2026 + h->drv[drv_index] = NULL;
  2027 +}
  2028 +
1981 2029 static void cciss_free_gendisk(ctlr_info_t *h, int drv_index)
1982 2030 {
1983 2031 put_disk(h->gendisk[drv_index]);
... ... @@ -1998,7 +2046,7 @@
1998 2046 {
1999 2047 int drv_index;
2000 2048  
2001   - drv_index = cciss_find_free_drive_index(h->ctlr, controller_node);
  2049 + drv_index = cciss_alloc_drive_info(h, controller_node);
2002 2050 if (drv_index == -1)
2003 2051 return -1;
2004 2052  
2005 2053  
2006 2054  
2007 2055  
... ... @@ -2010,24 +2058,24 @@
2010 2058 printk(KERN_ERR "cciss%d: could not "
2011 2059 "allocate a new disk %d\n",
2012 2060 h->ctlr, drv_index);
2013   - return -1;
  2061 + goto err_free_drive_info;
2014 2062 }
2015 2063 }
2016   - memcpy(h->drv[drv_index].LunID, lunid,
2017   - sizeof(h->drv[drv_index].LunID));
2018   - if (h->drv[drv_index].dev == NULL) {
2019   - if (cciss_create_ld_sysfs_entry(h, drv_index))
2020   - goto err_free_disk;
2021   - }
  2064 + memcpy(h->drv[drv_index]->LunID, lunid,
  2065 + sizeof(h->drv[drv_index]->LunID));
  2066 + if (cciss_create_ld_sysfs_entry(h, drv_index))
  2067 + goto err_free_disk;
2022 2068 /* Don't need to mark this busy because nobody */
2023 2069 /* else knows about this disk yet to contend */
2024 2070 /* for access to it. */
2025   - h->drv[drv_index].busy_configuring = 0;
  2071 + h->drv[drv_index]->busy_configuring = 0;
2026 2072 wmb();
2027 2073 return drv_index;
2028 2074  
2029 2075 err_free_disk:
2030 2076 cciss_free_gendisk(h, drv_index);
  2077 +err_free_drive_info:
  2078 + cciss_free_drive_info(h, drv_index);
2031 2079 return -1;
2032 2080 }
2033 2081  
2034 2082  
... ... @@ -2047,17 +2095,18 @@
2047 2095 drv_index = cciss_add_gendisk(h, CTLR_LUNID, 1);
2048 2096 if (drv_index == -1)
2049 2097 goto error;
2050   - h->drv[drv_index].block_size = 512;
2051   - h->drv[drv_index].nr_blocks = 0;
2052   - h->drv[drv_index].heads = 0;
2053   - h->drv[drv_index].sectors = 0;
2054   - h->drv[drv_index].cylinders = 0;
2055   - h->drv[drv_index].raid_level = -1;
2056   - memset(h->drv[drv_index].serial_no, 0, 16);
  2098 + h->drv[drv_index]->block_size = 512;
  2099 + h->drv[drv_index]->nr_blocks = 0;
  2100 + h->drv[drv_index]->heads = 0;
  2101 + h->drv[drv_index]->sectors = 0;
  2102 + h->drv[drv_index]->cylinders = 0;
  2103 + h->drv[drv_index]->raid_level = -1;
  2104 + memset(h->drv[drv_index]->serial_no, 0, 16);
2057 2105 disk = h->gendisk[drv_index];
2058 2106 if (cciss_add_disk(h, disk, drv_index) == 0)
2059 2107 return;
2060 2108 cciss_free_gendisk(h, drv_index);
  2109 + cciss_free_drive_info(h, drv_index);
2061 2110 error:
2062 2111 printk(KERN_WARNING "cciss%d: could not "
2063 2112 "add disk 0.\n", h->ctlr);
2064 2113  
... ... @@ -2136,12 +2185,12 @@
2136 2185 drv_found = 0;
2137 2186  
2138 2187 /* skip holes in the array from already deleted drives */
2139   - if (h->drv[i].raid_level == -1)
  2188 + if (h->drv[i] == NULL)
2140 2189 continue;
2141 2190  
2142 2191 for (j = 0; j < num_luns; j++) {
2143 2192 memcpy(lunid, &ld_buff->LUN[j][0], sizeof(lunid));
2144   - if (memcmp(h->drv[i].LunID, lunid,
  2193 + if (memcmp(h->drv[i]->LunID, lunid,
2145 2194 sizeof(lunid)) == 0) {
2146 2195 drv_found = 1;
2147 2196 break;
2148 2197  
... ... @@ -2150,10 +2199,11 @@
2150 2199 if (!drv_found) {
2151 2200 /* Deregister it from the OS, it's gone. */
2152 2201 spin_lock_irqsave(CCISS_LOCK(h->ctlr), flags);
2153   - h->drv[i].busy_configuring = 1;
  2202 + h->drv[i]->busy_configuring = 1;
2154 2203 spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags);
2155 2204 return_code = deregister_disk(h, i, 1, via_ioctl);
2156   - h->drv[i].busy_configuring = 0;
  2205 + if (h->drv[i] != NULL)
  2206 + h->drv[i]->busy_configuring = 0;
2157 2207 }
2158 2208 }
2159 2209  
... ... @@ -2174,9 +2224,9 @@
2174 2224 * the first free index and add it.
2175 2225 */
2176 2226 for (j = 0; j <= h->highest_lun; j++) {
2177   - if (h->drv[j].raid_level != -1 &&
2178   - memcmp(h->drv[j].LunID, lunid,
2179   - sizeof(h->drv[j].LunID)) == 0) {
  2227 + if (h->drv[j] != NULL &&
  2228 + memcmp(h->drv[j]->LunID, lunid,
  2229 + sizeof(h->drv[j]->LunID)) == 0) {
2180 2230 drv_index = j;
2181 2231 drv_found = 1;
2182 2232 break;
2183 2233  
... ... @@ -2253,11 +2303,12 @@
2253 2303 int i;
2254 2304 struct gendisk *disk;
2255 2305 drive_info_struct *drv;
  2306 + int recalculate_highest_lun;
2256 2307  
2257 2308 if (!capable(CAP_SYS_RAWIO))
2258 2309 return -EPERM;
2259 2310  
2260   - drv = &h->drv[drv_index];
  2311 + drv = h->drv[drv_index];
2261 2312 disk = h->gendisk[drv_index];
2262 2313  
2263 2314 /* make sure logical volume is NOT is use */
... ... @@ -2267,6 +2318,8 @@
2267 2318 } else if (drv->usage_count > 0)
2268 2319 return -EBUSY;
2269 2320  
  2321 + recalculate_highest_lun = (drv == h->drv[h->highest_lun]);
  2322 +
2270 2323 /* invalidate the devices and deregister the disk. If it is disk
2271 2324 * zero do not deregister it but just zero out it's values. This
2272 2325 * allows us to delete disk zero but keep the controller registered.
2273 2326  
... ... @@ -2277,14 +2330,8 @@
2277 2330 cciss_destroy_ld_sysfs_entry(h, drv_index, 0);
2278 2331 del_gendisk(disk);
2279 2332 }
2280   - if (q) {
  2333 + if (q)
2281 2334 blk_cleanup_queue(q);
2282   - /* Set drv->queue to NULL so that we do not try
2283   - * to call blk_start_queue on this queue in the
2284   - * interrupt handler
2285   - */
2286   - drv->queue = NULL;
2287   - }
2288 2335 /* If clear_all is set then we are deleting the logical
2289 2336 * drive, not just refreshing its info. For drives
2290 2337 * other than disk 0 we will call put_disk. We do not
2291 2338  
2292 2339  
2293 2340  
... ... @@ -2307,24 +2354,20 @@
2307 2354 }
2308 2355 } else {
2309 2356 set_capacity(disk, 0);
  2357 + cciss_clear_drive_info(drv);
2310 2358 }
2311 2359  
2312 2360 --h->num_luns;
2313   - cciss_clear_drive_info(drv);
2314 2361  
2315   - if (clear_all) {
2316   - /* check to see if it was the last disk */
2317   - if (drv == h->drv + h->highest_lun) {
2318   - /* if so, find the new hightest lun */
2319   - int i, newhighest = -1;
2320   - for (i = 0; i <= h->highest_lun; i++) {
2321   - /* if the disk has size > 0, it is available */
2322   - if (h->drv[i].heads)
2323   - newhighest = i;
2324   - }
2325   - h->highest_lun = newhighest;
  2362 + /* if it was the last disk, find the new hightest lun */
  2363 + if (clear_all && recalculate_highest_lun) {
  2364 + int i, newhighest = -1;
  2365 + for (i = 0; i <= h->highest_lun; i++) {
  2366 + /* if the disk has size > 0, it is available */
  2367 + if (h->drv[i] && h->drv[i]->heads)
  2368 + newhighest = i;
2326 2369 }
2327   - memset(drv->LunID, 0, sizeof(drv->LunID));
  2370 + h->highest_lun = newhighest;
2328 2371 }
2329 2372 return 0;
2330 2373 }
... ... @@ -2755,7 +2798,7 @@
2755 2798 InquiryData_struct *inq_buff = NULL;
2756 2799  
2757 2800 for (logvol = 0; logvol < CISS_MAX_LUN; logvol++) {
2758   - if (memcmp(h->drv[logvol].LunID, drv->LunID,
  2801 + if (memcmp(h->drv[logvol]->LunID, drv->LunID,
2759 2802 sizeof(drv->LunID)) == 0) {
2760 2803 FOUND = 1;
2761 2804 break;
... ... @@ -4293,8 +4336,7 @@
4293 4336 hba[i]->num_luns = 0;
4294 4337 hba[i]->highest_lun = -1;
4295 4338 for (j = 0; j < CISS_MAX_LUN; j++) {
4296   - hba[i]->drv[j].raid_level = -1;
4297   - hba[i]->drv[j].queue = NULL;
  4339 + hba[i]->drv[j] = NULL;
4298 4340 hba[i]->gendisk[j] = NULL;
4299 4341 }
4300 4342  
... ... @@ -4349,12 +4391,7 @@
4349 4391 cciss_destroy_hba_sysfs_entry(hba[i]);
4350 4392 clean0:
4351 4393 hba[i]->busy_initializing = 0;
4352   - /* cleanup any queues that may have been initialized */
4353   - for (j=0; j <= hba[i]->highest_lun; j++){
4354   - drive_info_struct *drv = &(hba[i]->drv[j]);
4355   - if (drv->queue)
4356   - blk_cleanup_queue(drv->queue);
4357   - }
  4394 +
4358 4395 /*
4359 4396 * Deliberately omit pci_disable_device(): it does something nasty to
4360 4397 * Smart Array controllers that pci_enable_device does not undo
drivers/block/cciss.h
... ... @@ -45,13 +45,14 @@
45 45 * to prevent it from being opened or it's
46 46 * queue from being started.
47 47 */
48   - struct device *dev;
  48 + struct device dev;
49 49 __u8 serial_no[16]; /* from inquiry page 0x83,
50 50 * not necc. null terminated.
51 51 */
52 52 char vendor[VENDOR_LEN + 1]; /* SCSI vendor string */
53 53 char model[MODEL_LEN + 1]; /* SCSI model string */
54 54 char rev[REV_LEN + 1]; /* SCSI revision string */
  55 + char device_initialized; /* indicates whether dev is initialized */
55 56 } drive_info_struct;
56 57  
57 58 struct ctlr_info
... ... @@ -87,7 +88,7 @@
87 88 BYTE cciss_read_capacity;
88 89  
89 90 // information about each logical volume
90   - drive_info_struct drv[CISS_MAX_LUN];
  91 + drive_info_struct *drv[CISS_MAX_LUN];
91 92  
92 93 struct access_method access;
93 94