aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMike Miller <mike.miller@hp.com>2006-12-06 23:35:12 -0500
committerLinus Torvalds <torvalds@woody.osdl.org>2006-12-07 11:39:30 -0500
commit799202cbd0ef6a201446d99fcbd78b9f0bda6ae5 (patch)
treecfc6a988170f4e65b810ee6a523e6d858ee01ce2
parent3833a748aa75dd39494bb861ab018216b0a2c14e (diff)
[PATCH] cciss: add support for 1024 logical volumes
Add the support for a large number of logical volumes. We will soon have hardware that support up to 1024 logical volumes. Signed-off-by: Mike Miller <mike.miller@hp.com> Cc: Jens Axboe <jens.axboe@oracle.com> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
-rw-r--r--drivers/block/cciss.c114
-rw-r--r--drivers/block/cciss.h3
-rw-r--r--drivers/block/cciss_cmd.h2
-rw-r--r--include/linux/cciss_ioctl.h2
4 files changed, 80 insertions, 41 deletions
diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c
index 70cf9321ef54..c99cb7ed57f7 100644
--- a/drivers/block/cciss.c
+++ b/drivers/block/cciss.c
@@ -1315,6 +1315,11 @@ static void cciss_update_drive_info(int ctlr, int drv_index)
1315 /* if it's the controller it's already added */ 1315 /* if it's the controller it's already added */
1316 if (drv_index) { 1316 if (drv_index) {
1317 disk->queue = blk_init_queue(do_cciss_request, &h->lock); 1317 disk->queue = blk_init_queue(do_cciss_request, &h->lock);
1318 sprintf(disk->disk_name, "cciss/c%dd%d", ctlr, drv_index);
1319 disk->major = h->major;
1320 disk->first_minor = drv_index << NWD_SHIFT;
1321 disk->fops = &cciss_fops;
1322 disk->private_data = &h->drv[drv_index];
1318 1323
1319 /* Set up queue information */ 1324 /* Set up queue information */
1320 disk->queue->backing_dev_info.ra_pages = READ_AHEAD; 1325 disk->queue->backing_dev_info.ra_pages = READ_AHEAD;
@@ -1393,11 +1398,6 @@ static int rebuild_lun_table(ctlr_info_t *h, struct gendisk *del_disk)
1393 1398
1394 /* Set busy_configuring flag for this operation */ 1399 /* Set busy_configuring flag for this operation */
1395 spin_lock_irqsave(CCISS_LOCK(h->ctlr), flags); 1400 spin_lock_irqsave(CCISS_LOCK(h->ctlr), flags);
1396 if (h->num_luns >= CISS_MAX_LUN) {
1397 spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags);
1398 return -EINVAL;
1399 }
1400
1401 if (h->busy_configuring) { 1401 if (h->busy_configuring) {
1402 spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags); 1402 spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags);
1403 return -EBUSY; 1403 return -EBUSY;
@@ -1430,17 +1430,8 @@ static int rebuild_lun_table(ctlr_info_t *h, struct gendisk *del_disk)
1430 0, 0, TYPE_CMD); 1430 0, 0, TYPE_CMD);
1431 1431
1432 if (return_code == IO_OK) { 1432 if (return_code == IO_OK) {
1433 listlength |= 1433 listlength =
1434 (0xff & (unsigned int)(ld_buff->LUNListLength[0])) 1434 be32_to_cpu(*(__u32 *) ld_buff->LUNListLength);
1435 << 24;
1436 listlength |=
1437 (0xff & (unsigned int)(ld_buff->LUNListLength[1]))
1438 << 16;
1439 listlength |=
1440 (0xff & (unsigned int)(ld_buff->LUNListLength[2]))
1441 << 8;
1442 listlength |=
1443 0xff & (unsigned int)(ld_buff->LUNListLength[3]);
1444 } else { /* reading number of logical volumes failed */ 1435 } else { /* reading number of logical volumes failed */
1445 printk(KERN_WARNING "cciss: report logical volume" 1436 printk(KERN_WARNING "cciss: report logical volume"
1446 " command failed\n"); 1437 " command failed\n");
@@ -1491,6 +1482,14 @@ static int rebuild_lun_table(ctlr_info_t *h, struct gendisk *del_disk)
1491 if (drv_index == -1) 1482 if (drv_index == -1)
1492 goto freeret; 1483 goto freeret;
1493 1484
1485 /*Check if the gendisk needs to be allocated */
1486 if (!h->gendisk[drv_index]){
1487 h->gendisk[drv_index] = alloc_disk(1 << NWD_SHIFT);
1488 if (!h->gendisk[drv_index]){
1489 printk(KERN_ERR "cciss: could not allocate new disk %d\n", drv_index);
1490 goto mem_msg;
1491 }
1492 }
1494 } 1493 }
1495 h->drv[drv_index].LunID = lunid; 1494 h->drv[drv_index].LunID = lunid;
1496 cciss_update_drive_info(ctlr, drv_index); 1495 cciss_update_drive_info(ctlr, drv_index);
@@ -1528,6 +1527,7 @@ static int rebuild_lun_table(ctlr_info_t *h, struct gendisk *del_disk)
1528static int deregister_disk(struct gendisk *disk, drive_info_struct *drv, 1527static int deregister_disk(struct gendisk *disk, drive_info_struct *drv,
1529 int clear_all) 1528 int clear_all)
1530{ 1529{
1530 int i;
1531 ctlr_info_t *h = get_host(disk); 1531 ctlr_info_t *h = get_host(disk);
1532 1532
1533 if (!capable(CAP_SYS_RAWIO)) 1533 if (!capable(CAP_SYS_RAWIO))
@@ -1551,9 +1551,35 @@ static int deregister_disk(struct gendisk *disk, drive_info_struct *drv,
1551 del_gendisk(disk); 1551 del_gendisk(disk);
1552 if (q) { 1552 if (q) {
1553 blk_cleanup_queue(q); 1553 blk_cleanup_queue(q);
1554 /* Set drv->queue to NULL so that we do not try
1555 * to call blk_start_queue on this queue in the
1556 * interrupt handler
1557 */
1554 drv->queue = NULL; 1558 drv->queue = NULL;
1555 } 1559 }
1560 /* If clear_all is set then we are deleting the logical
1561 * drive, not just refreshing its info. For drives
1562 * other than disk 0 we will call put_disk. We do not
1563 * do this for disk 0 as we need it to be able to
1564 * configure the controller.
1565 */
1566 if (clear_all){
1567 /* This isn't pretty, but we need to find the
1568 * disk in our array and NULL our the pointer.
1569 * This is so that we will call alloc_disk if
1570 * this index is used again later.
1571 */
1572 for (i=0; i < CISS_MAX_LUN; i++){
1573 if(h->gendisk[i] == disk){
1574 h->gendisk[i] = NULL;
1575 break;
1576 }
1577 }
1578 put_disk(disk);
1579 }
1556 } 1580 }
1581 } else {
1582 set_capacity(disk, 0);
1557 } 1583 }
1558 1584
1559 --h->num_luns; 1585 --h->num_luns;
@@ -3119,13 +3145,7 @@ geo_inq:
3119/* Returns -1 if no free entries are left. */ 3145/* Returns -1 if no free entries are left. */
3120static int alloc_cciss_hba(void) 3146static int alloc_cciss_hba(void)
3121{ 3147{
3122 struct gendisk *disk[NWD]; 3148 int i;
3123 int i, n;
3124 for (n = 0; n < NWD; n++) {
3125 disk[n] = alloc_disk(1 << NWD_SHIFT);
3126 if (!disk[n])
3127 goto out;
3128 }
3129 3149
3130 for (i = 0; i < MAX_CTLR; i++) { 3150 for (i = 0; i < MAX_CTLR; i++) {
3131 if (!hba[i]) { 3151 if (!hba[i]) {
@@ -3133,20 +3153,18 @@ static int alloc_cciss_hba(void)
3133 p = kzalloc(sizeof(ctlr_info_t), GFP_KERNEL); 3153 p = kzalloc(sizeof(ctlr_info_t), GFP_KERNEL);
3134 if (!p) 3154 if (!p)
3135 goto Enomem; 3155 goto Enomem;
3136 for (n = 0; n < NWD; n++) 3156 p->gendisk[0] = alloc_disk(1 << NWD_SHIFT);
3137 p->gendisk[n] = disk[n]; 3157 if (!p->gendisk[0])
3158 goto Enomem;
3138 hba[i] = p; 3159 hba[i] = p;
3139 return i; 3160 return i;
3140 } 3161 }
3141 } 3162 }
3142 printk(KERN_WARNING "cciss: This driver supports a maximum" 3163 printk(KERN_WARNING "cciss: This driver supports a maximum"
3143 " of %d controllers.\n", MAX_CTLR); 3164 " of %d controllers.\n", MAX_CTLR);
3144 goto out; 3165 return -1;
3145 Enomem: 3166Enomem:
3146 printk(KERN_ERR "cciss: out of memory.\n"); 3167 printk(KERN_ERR "cciss: out of memory.\n");
3147 out:
3148 while (n--)
3149 put_disk(disk[n]);
3150 return -1; 3168 return -1;
3151} 3169}
3152 3170
@@ -3156,7 +3174,7 @@ static void free_hba(int i)
3156 int n; 3174 int n;
3157 3175
3158 hba[i] = NULL; 3176 hba[i] = NULL;
3159 for (n = 0; n < NWD; n++) 3177 for (n = 0; n < CISS_MAX_LUN; n++)
3160 put_disk(p->gendisk[n]); 3178 put_disk(p->gendisk[n]);
3161 kfree(p); 3179 kfree(p);
3162} 3180}
@@ -3169,9 +3187,8 @@ static void free_hba(int i)
3169static int __devinit cciss_init_one(struct pci_dev *pdev, 3187static int __devinit cciss_init_one(struct pci_dev *pdev,
3170 const struct pci_device_id *ent) 3188 const struct pci_device_id *ent)
3171{ 3189{
3172 request_queue_t *q;
3173 int i; 3190 int i;
3174 int j; 3191 int j = 0;
3175 int rc; 3192 int rc;
3176 int dac; 3193 int dac;
3177 3194
@@ -3283,16 +3300,29 @@ static int __devinit cciss_init_one(struct pci_dev *pdev,
3283 3300
3284 hba[i]->busy_initializing = 0; 3301 hba[i]->busy_initializing = 0;
3285 3302
3286 for (j = 0; j < NWD; j++) { /* mfm */ 3303 do {
3287 drive_info_struct *drv = &(hba[i]->drv[j]); 3304 drive_info_struct *drv = &(hba[i]->drv[j]);
3288 struct gendisk *disk = hba[i]->gendisk[j]; 3305 struct gendisk *disk = hba[i]->gendisk[j];
3306 request_queue_t *q;
3307
3308 /* Check if the disk was allocated already */
3309 if (!disk){
3310 hba[i]->gendisk[j] = alloc_disk(1 << NWD_SHIFT);
3311 disk = hba[i]->gendisk[j];
3312 }
3313
3314 /* Check that the disk was able to be allocated */
3315 if (!disk) {
3316 printk(KERN_ERR "cciss: unable to allocate memory for disk %d\n", j);
3317 goto clean4;
3318 }
3289 3319
3290 q = blk_init_queue(do_cciss_request, &hba[i]->lock); 3320 q = blk_init_queue(do_cciss_request, &hba[i]->lock);
3291 if (!q) { 3321 if (!q) {
3292 printk(KERN_ERR 3322 printk(KERN_ERR
3293 "cciss: unable to allocate queue for disk %d\n", 3323 "cciss: unable to allocate queue for disk %d\n",
3294 j); 3324 j);
3295 break; 3325 goto clean4;
3296 } 3326 }
3297 drv->queue = q; 3327 drv->queue = q;
3298 3328
@@ -3324,7 +3354,8 @@ static int __devinit cciss_init_one(struct pci_dev *pdev,
3324 blk_queue_hardsect_size(q, drv->block_size); 3354 blk_queue_hardsect_size(q, drv->block_size);
3325 set_capacity(disk, drv->nr_blocks); 3355 set_capacity(disk, drv->nr_blocks);
3326 add_disk(disk); 3356 add_disk(disk);
3327 } 3357 j++;
3358 } while (j <= hba[i]->highest_lun);
3328 3359
3329 return 1; 3360 return 1;
3330 3361
@@ -3347,6 +3378,15 @@ static int __devinit cciss_init_one(struct pci_dev *pdev,
3347 unregister_blkdev(hba[i]->major, hba[i]->devname); 3378 unregister_blkdev(hba[i]->major, hba[i]->devname);
3348 clean1: 3379 clean1:
3349 hba[i]->busy_initializing = 0; 3380 hba[i]->busy_initializing = 0;
3381 /* cleanup any queues that may have been initialized */
3382 for (j=0; j <= hba[i]->highest_lun; j++){
3383 drive_info_struct *drv = &(hba[i]->drv[j]);
3384 if (drv->queue)
3385 blk_cleanup_queue(drv->queue);
3386 }
3387 pci_release_regions(pdev);
3388 pci_disable_device(pdev);
3389 pci_set_drvdata(pdev, NULL);
3350 free_hba(i); 3390 free_hba(i);
3351 return -1; 3391 return -1;
3352} 3392}
@@ -3394,7 +3434,7 @@ static void __devexit cciss_remove_one(struct pci_dev *pdev)
3394 remove_proc_entry(hba[i]->devname, proc_cciss); 3434 remove_proc_entry(hba[i]->devname, proc_cciss);
3395 3435
3396 /* remove it from the disk list */ 3436 /* remove it from the disk list */
3397 for (j = 0; j < NWD; j++) { 3437 for (j = 0; j < CISS_MAX_LUN; j++) {
3398 struct gendisk *disk = hba[i]->gendisk[j]; 3438 struct gendisk *disk = hba[i]->gendisk[j];
3399 if (disk) { 3439 if (disk) {
3400 request_queue_t *q = disk->queue; 3440 request_queue_t *q = disk->queue;
diff --git a/drivers/block/cciss.h b/drivers/block/cciss.h
index c3df673f860b..b70988dd33ec 100644
--- a/drivers/block/cciss.h
+++ b/drivers/block/cciss.h
@@ -6,7 +6,6 @@
6#include "cciss_cmd.h" 6#include "cciss_cmd.h"
7 7
8 8
9#define NWD 16
10#define NWD_SHIFT 4 9#define NWD_SHIFT 4
11#define MAX_PART (1 << NWD_SHIFT) 10#define MAX_PART (1 << NWD_SHIFT)
12 11
@@ -112,7 +111,7 @@ struct ctlr_info
112 int next_to_run; 111 int next_to_run;
113 112
114 // Disk structures we need to pass back 113 // Disk structures we need to pass back
115 struct gendisk *gendisk[NWD]; 114 struct gendisk *gendisk[CISS_MAX_LUN];
116#ifdef CONFIG_CISS_SCSI_TAPE 115#ifdef CONFIG_CISS_SCSI_TAPE
117 void *scsi_ctlr; /* ptr to structure containing scsi related stuff */ 116 void *scsi_ctlr; /* ptr to structure containing scsi related stuff */
118 /* list of block side commands the scsi error handling sucked up */ 117 /* list of block side commands the scsi error handling sucked up */
diff --git a/drivers/block/cciss_cmd.h b/drivers/block/cciss_cmd.h
index b2147cca5acd..43bf5593b59b 100644
--- a/drivers/block/cciss_cmd.h
+++ b/drivers/block/cciss_cmd.h
@@ -89,7 +89,7 @@ typedef union _u64bit
89//########################################################################### 89//###########################################################################
90//STRUCTURES 90//STRUCTURES
91//########################################################################### 91//###########################################################################
92#define CISS_MAX_LUN 16 92#define CISS_MAX_LUN 1024
93#define CISS_MAX_PHYS_LUN 1024 93#define CISS_MAX_PHYS_LUN 1024
94// SCSI-3 Cmmands 94// SCSI-3 Cmmands
95 95
diff --git a/include/linux/cciss_ioctl.h b/include/linux/cciss_ioctl.h
index 6e27f42e3a57..cb57c30081a8 100644
--- a/include/linux/cciss_ioctl.h
+++ b/include/linux/cciss_ioctl.h
@@ -80,7 +80,7 @@ typedef __u32 DriverVer_type;
80#define HWORD __u16 80#define HWORD __u16
81#define DWORD __u32 81#define DWORD __u32
82 82
83#define CISS_MAX_LUN 16 83#define CISS_MAX_LUN 1024
84 84
85#define LEVEL2LUN 1 // index into Target(x) structure, due to byte swapping 85#define LEVEL2LUN 1 // index into Target(x) structure, due to byte swapping
86#define LEVEL3LUN 0 86#define LEVEL3LUN 0