Commit 71d2385e authored by Mike Miller's avatar Mike Miller Committed by Linus Torvalds

[PATCH] cciss: support for more than 8 controllers

This patch adds support for more than 8 controllers.  If we run out of
preallocated major numbers we dynamically allocate more.
Signed-off-by: default avatarMike Miller <mike.miller@hp.com>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent feb46ab0
...@@ -120,7 +120,11 @@ static struct board_type products[] = { ...@@ -120,7 +120,11 @@ static struct board_type products[] = {
#define READ_AHEAD 1024 #define READ_AHEAD 1024
#define NR_CMDS 384 /* #commands that can be outstanding */ #define NR_CMDS 384 /* #commands that can be outstanding */
#define MAX_CTLR 8 #define MAX_CTLR 32
/* Originally cciss driver only supports 8 major numbers */
#define MAX_CTLR_ORIG 8
#define CCISS_DMA_MASK 0xFFFFFFFF /* 32 bit DMA */ #define CCISS_DMA_MASK 0xFFFFFFFF /* 32 bit DMA */
...@@ -2650,7 +2654,7 @@ static int alloc_cciss_hba(void) ...@@ -2650,7 +2654,7 @@ static int alloc_cciss_hba(void)
} }
} }
printk(KERN_WARNING "cciss: This driver supports a maximum" printk(KERN_WARNING "cciss: This driver supports a maximum"
" of 8 controllers.\n"); " of %d controllers.\n", MAX_CTLR);
goto out; goto out;
Enomem: Enomem:
printk(KERN_ERR "cciss: out of memory.\n"); printk(KERN_ERR "cciss: out of memory.\n");
...@@ -2682,13 +2686,14 @@ static int __devinit cciss_init_one(struct pci_dev *pdev, ...@@ -2682,13 +2686,14 @@ static int __devinit cciss_init_one(struct pci_dev *pdev,
request_queue_t *q; request_queue_t *q;
int i; int i;
int j; int j;
int rc;
printk(KERN_DEBUG "cciss: Device 0x%x has been found at" printk(KERN_DEBUG "cciss: Device 0x%x has been found at"
" bus %d dev %d func %d\n", " bus %d dev %d func %d\n",
pdev->device, pdev->bus->number, PCI_SLOT(pdev->devfn), pdev->device, pdev->bus->number, PCI_SLOT(pdev->devfn),
PCI_FUNC(pdev->devfn)); PCI_FUNC(pdev->devfn));
i = alloc_cciss_hba(); i = alloc_cciss_hba();
if( i < 0 ) if(i < 0)
return (-1); return (-1);
if (cciss_pci_init(hba[i], pdev) != 0) if (cciss_pci_init(hba[i], pdev) != 0)
goto clean1; goto clean1;
...@@ -2707,11 +2712,24 @@ static int __devinit cciss_init_one(struct pci_dev *pdev, ...@@ -2707,11 +2712,24 @@ static int __devinit cciss_init_one(struct pci_dev *pdev,
goto clean1; goto clean1;
} }
if (register_blkdev(COMPAQ_CISS_MAJOR+i, hba[i]->devname)) { /*
printk(KERN_ERR "cciss: Unable to register device %s\n", * register with the major number, or get a dynamic major number
hba[i]->devname); * by passing 0 as argument. This is done for greater than
* 8 controller support.
*/
if (i < MAX_CTLR_ORIG)
hba[i]->major = MAJOR_NR + i;
rc = register_blkdev(hba[i]->major, hba[i]->devname);
if(rc == -EBUSY || rc == -EINVAL) {
printk(KERN_ERR
"cciss: Unable to get major number %d for %s "
"on hba %d\n", hba[i]->major, hba[i]->devname, i);
goto clean1; goto clean1;
} }
else {
if (i >= MAX_CTLR_ORIG)
hba[i]->major = rc;
}
/* make sure the board interrupts are off */ /* make sure the board interrupts are off */
hba[i]->access.set_intr_mask(hba[i], CCISS_INTR_OFF); hba[i]->access.set_intr_mask(hba[i], CCISS_INTR_OFF);
...@@ -2782,7 +2800,7 @@ static int __devinit cciss_init_one(struct pci_dev *pdev, ...@@ -2782,7 +2800,7 @@ static int __devinit cciss_init_one(struct pci_dev *pdev,
sprintf(disk->disk_name, "cciss/c%dd%d", i, j); sprintf(disk->disk_name, "cciss/c%dd%d", i, j);
sprintf(disk->devfs_name, "cciss/host%d/target%d", i, j); sprintf(disk->devfs_name, "cciss/host%d/target%d", i, j);
disk->major = COMPAQ_CISS_MAJOR + i; disk->major = hba[i]->major;
disk->first_minor = j << NWD_SHIFT; disk->first_minor = j << NWD_SHIFT;
disk->fops = &cciss_fops; disk->fops = &cciss_fops;
disk->queue = hba[i]->queue; disk->queue = hba[i]->queue;
...@@ -2811,7 +2829,7 @@ static int __devinit cciss_init_one(struct pci_dev *pdev, ...@@ -2811,7 +2829,7 @@ static int __devinit cciss_init_one(struct pci_dev *pdev,
hba[i]->errinfo_pool_dhandle); hba[i]->errinfo_pool_dhandle);
free_irq(hba[i]->intr, hba[i]); free_irq(hba[i]->intr, hba[i]);
clean2: clean2:
unregister_blkdev(COMPAQ_CISS_MAJOR+i, hba[i]->devname); unregister_blkdev(hba[i]->major, hba[i]->devname);
clean1: clean1:
release_io_mem(hba[i]); release_io_mem(hba[i]);
free_hba(i); free_hba(i);
...@@ -2853,7 +2871,7 @@ static void __devexit cciss_remove_one (struct pci_dev *pdev) ...@@ -2853,7 +2871,7 @@ static void __devexit cciss_remove_one (struct pci_dev *pdev)
pci_set_drvdata(pdev, NULL); pci_set_drvdata(pdev, NULL);
iounmap(hba[i]->vaddr); iounmap(hba[i]->vaddr);
cciss_unregister_scsi(i); /* unhook from SCSI subsystem */ cciss_unregister_scsi(i); /* unhook from SCSI subsystem */
unregister_blkdev(COMPAQ_CISS_MAJOR+i, hba[i]->devname); unregister_blkdev(hba[i]->major, hba[i]->devname);
remove_proc_entry(hba[i]->devname, proc_cciss); remove_proc_entry(hba[i]->devname, proc_cciss);
/* remove it from the disk list */ /* remove it from the disk list */
......
...@@ -13,6 +13,8 @@ ...@@ -13,6 +13,8 @@
#define IO_OK 0 #define IO_OK 0
#define IO_ERROR 1 #define IO_ERROR 1
#define MAJOR_NR COMPAQ_CISS_MAJOR
struct ctlr_info; struct ctlr_info;
typedef struct ctlr_info ctlr_info_t; typedef struct ctlr_info ctlr_info_t;
...@@ -50,6 +52,7 @@ struct ctlr_info ...@@ -50,6 +52,7 @@ struct ctlr_info
CfgTable_struct __iomem *cfgtable; CfgTable_struct __iomem *cfgtable;
unsigned int intr; unsigned int intr;
int interrupts_enabled; int interrupts_enabled;
int major;
int max_commands; int max_commands;
int commands_outstanding; int commands_outstanding;
int max_outstanding; /* Debug */ int max_outstanding; /* Debug */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment