patch-2.4.0-test2 linux/drivers/block/cpqarray.c
Next file: linux/drivers/block/elevator.c
Previous file: linux/drivers/block/amiflop.c
Back to the patch index
Back to the overall index
- Lines: 881
- Date:
Fri Jun 23 21:13:43 2000
- Orig file:
v2.4.0-test1/linux/drivers/block/cpqarray.c
- Orig date:
Thu May 11 15:30:06 2000
diff -u --recursive --new-file v2.4.0-test1/linux/drivers/block/cpqarray.c linux/drivers/block/cpqarray.c
@@ -22,7 +22,7 @@
* driver, you'll probably need the Compaq Array Controller Interface
* Specificiation (Document number ECG086/1198)
*/
-#include <linux/config.h>
+#include <linux/config.h> /* CONFIG_PROC_FS */
#include <linux/module.h>
#include <linux/version.h>
#include <linux/types.h>
@@ -44,8 +44,8 @@
#define SMART2_DRIVER_VERSION(maj,min,submin) ((maj<<16)|(min<<8)|(submin))
-#define DRIVER_NAME "Compaq SMART2 Driver (v 1.0.4)"
-#define DRIVER_VERSION SMART2_DRIVER_VERSION(1,0,4)
+#define DRIVER_NAME "Compaq SMART2 Driver (v 2.4.0)"
+#define DRIVER_VERSION SMART2_DRIVER_VERSION(2,4,0)
#define MAJOR_NR COMPAQ_SMART2_MAJOR
#include <linux/blk.h>
#include <linux/blkdev.h>
@@ -73,7 +73,7 @@
* product = Marketing Name for the board
* access = Address of the struct of function pointers
*/
-struct board_type products[] = {
+static struct board_type products[] = {
{ 0x0040110E, "IDA", &smart1_access },
{ 0x0140110E, "IDA-2", &smart1_access },
{ 0x1040110E, "IAES", &smart1_access },
@@ -87,6 +87,7 @@
{ 0x40400E11, "Integrated Array", &smart4_access },
{ 0x40500E11, "Smart Array 4200", &smart4_access },
{ 0x40510E11, "Smart Array 4250ES", &smart4_access },
+ { 0x40580E11, "Smart Array 431", &smart4_access },
};
static struct hd_struct * ida;
@@ -95,7 +96,7 @@
static int * ida_hardsizes;
static struct gendisk ida_gendisk[MAX_CTLR];
-struct proc_dir_entry *proc_array = NULL;
+static struct proc_dir_entry *proc_array = NULL;
/* Debug... */
#define DBG(s) do { s } while(0)
@@ -106,7 +107,7 @@
/* Debug Extra Paranoid... */
#define DBGPX(s) do { } while(0)
-void cpqarray_init(void);
+int cpqarray_init(void);
static int cpqarray_pci_detect(void);
static int cpqarray_pci_init(ctlr_info_t *c, unchar bus, unchar device_fn);
static ulong remap_pci_mem(ulong base, ulong size);
@@ -312,9 +313,8 @@
/* This is a bit of a hack... */
int __init init_module(void)
{
- cpqarray_init();
- if (nr_ctlr == 0)
- return -EIO;
+ if (cpqarray_init() == 0) /* all the block dev numbers already used */
+ return -EIO; /* or no controllers were found */
return 0;
}
@@ -357,8 +357,9 @@
/*
* This is it. Find all the controllers and register them. I really hate
* stealing all these major device numbers.
+ * returns the number of block devices registered.
*/
-void __init cpqarray_init(void)
+int __init cpqarray_init(void)
{
void (*request_fns[MAX_CTLR])(request_queue_t *) = {
do_ida_request0, do_ida_request1,
@@ -367,31 +368,52 @@
do_ida_request6, do_ida_request7,
};
int i,j;
+ int num_cntlrs_reg = 0;
/* detect controllers */
cpqarray_pci_detect();
cpqarray_eisa_detect();
if (nr_ctlr == 0)
- return;
+ return(num_cntlrs_reg);
printk(DRIVER_NAME "\n");
printk("Found %d controller(s)\n", nr_ctlr);
/* allocate space for disk structs */
ida = kmalloc(sizeof(struct hd_struct)*nr_ctlr*NWD*16, GFP_KERNEL);
-
if(ida==NULL)
- goto bail;
- ida_sizes = kmalloc(sizeof(int)*nr_ctlr*NWD*16, GFP_KERNEL);
+ {
+ printk( KERN_ERR "cpqarray: out of memory");
+ return(num_cntlrs_reg);
+ }
+
+ ida_sizes = kmalloc(sizeof(int)*nr_ctlr*NWD*16, GFP_KERNEL);
if(ida_sizes==NULL)
- goto bail2;
+ {
+ kfree(ida);
+ printk( KERN_ERR "cpqarray: out of memory");
+ return(num_cntlrs_reg);
+ }
+
ida_blocksizes = kmalloc(sizeof(int)*nr_ctlr*NWD*16, GFP_KERNEL);
if(ida_blocksizes==NULL)
- goto bail3;
- ida_hardsizes = kmalloc(sizeof(int)*nr_ctlr*NWD*16, GFP_KERNEL);
+ {
+ kfree(ida);
+ kfree(ida_sizes);
+ printk( KERN_ERR "cpqarray: out of memory");
+ return(num_cntlrs_reg);
+ }
+
+ ida_hardsizes = kmalloc(sizeof(int)*nr_ctlr*NWD*16, GFP_KERNEL);
if(ida_hardsizes==NULL)
- goto bail4;
+ {
+ kfree(ida);
+ kfree(ida_sizes);
+ kfree(ida_blocksizes);
+ printk( KERN_ERR "cpqarray: out of memory");
+ return(num_cntlrs_reg);
+ }
memset(ida, 0, sizeof(struct hd_struct)*nr_ctlr*NWD*16);
memset(ida_sizes, 0, sizeof(int)*nr_ctlr*NWD*16);
@@ -399,74 +421,90 @@
memset(ida_hardsizes, 0, sizeof(int)*nr_ctlr*NWD*16);
memset(ida_gendisk, 0, sizeof(struct gendisk)*MAX_CTLR);
- /*
+ /*
* register block devices
* Find disks and fill in structs
* Get an interrupt, set the Q depth and get into /proc
*/
for(i=0; i< nr_ctlr; i++) {
+ /* If this successful it should insure that we are the only */
+ /* instance of the driver */
+ if (register_blkdev(MAJOR_NR+i, hba[i]->devname, &ida_fops)) {
+ printk(KERN_ERR "cpqarray: Unable to get major number %d for ida\n",
+ MAJOR_NR+i);
+ continue;
+ }
+
+
hba[i]->access.set_intr_mask(hba[i], 0);
if (request_irq(hba[i]->intr, do_ida_intr,
SA_INTERRUPT|SA_SHIRQ, hba[i]->devname, hba[i])) {
- printk("Unable to get irq %d for %s\n",
+ printk(KERN_ERR "cpqarray: Unable to get irq %d for %s\n",
hba[i]->intr, hba[i]->devname);
+ unregister_blkdev(MAJOR_NR+i, hba[i]->devname);
continue;
}
- if (register_blkdev(MAJOR_NR+i, hba[i]->devname, &ida_fops)) {
- printk("Unable to get major number %d for ida\n",
- MAJOR_NR+i);
- continue;
- }
-
+ num_cntlrs_reg++;
hba[i]->cmd_pool = (cmdlist_t *)kmalloc(
NR_CMDS * sizeof(cmdlist_t), GFP_KERNEL);
hba[i]->cmd_pool_bits = (__u32*)kmalloc(
((NR_CMDS+31)/32)*sizeof(__u32), GFP_KERNEL);
- if(hba[i]->cmd_pool_bits == NULL || hba[i]->cmd_pool == NULL)
+ if(hba[i]->cmd_pool_bits == NULL || hba[i]->cmd_pool == NULL)
{
- int j;
+ nr_ctlr = i;
if(hba[i]->cmd_pool_bits)
kfree(hba[i]->cmd_pool_bits);
if(hba[i]->cmd_pool)
kfree(hba[i]->cmd_pool);
- for(j=0;i<i;j++)
- {
- free_irq(hba[j]->intr, hba[j]);
- unregister_blkdev(MAJOR_NR+j, hba[j]->devname);
- kfree(hba[j]->cmd_pool_bits);
- kfree(hba[j]->cmd_pool);
- }
free_irq(hba[i]->intr, hba[i]);
unregister_blkdev(MAJOR_NR+i, hba[i]->devname);
- goto bail5;
+ num_cntlrs_reg--;
+ printk( KERN_ERR "cpqarray: out of memory");
+
+ /* If num_cntlrs_reg == 0, no controllers worked.
+ * init_module will fail, so clean up global
+ * memory that clean_module would do.
+ */
+
+ if (num_cntlrs_reg == 0)
+ {
+ kfree(ida);
+ kfree(ida_sizes);
+ kfree(ida_hardsizes);
+ kfree(ida_blocksizes);
+ }
+ return(num_cntlrs_reg);
+
}
memset(hba[i]->cmd_pool, 0, NR_CMDS * sizeof(cmdlist_t));
memset(hba[i]->cmd_pool_bits, 0, ((NR_CMDS+31)/32)*sizeof(__u32));
- printk("Finding drives on %s", hba[i]->devname);
+ printk(KERN_INFO "cpqarray: Finding drives on %s",
+ hba[i]->devname);
getgeometry(i);
start_fwbk(i);
hba[i]->access.set_intr_mask(hba[i], FIFO_NOT_EMPTY);
+
ida_procinit(i);
-
- blk_init_queue(BLK_DEFAULT_QUEUE(MAJOR_NR + i), request_fns[i]);
- blk_queue_headactive(BLK_DEFAULT_QUEUE(MAJOR_NR + i), 0);
+ blk_init_queue(BLK_DEFAULT_QUEUE(MAJOR_NR + i),
+ request_fns[i]);
+ blk_queue_headactive(BLK_DEFAULT_QUEUE(MAJOR_NR + i), 0);
blksize_size[MAJOR_NR+i] = ida_blocksizes + (i*256);
hardsect_size[MAJOR_NR+i] = ida_hardsizes + (i*256);
-
read_ahead[MAJOR_NR+i] = READ_AHEAD;
+
ida_gendisk[i].major = MAJOR_NR + i;
ida_gendisk[i].major_name = "ida";
ida_gendisk[i].minor_shift = NWD_SHIFT;
ida_gendisk[i].max_p = 16;
ida_gendisk[i].part = ida + (i*256);
ida_gendisk[i].sizes = ida_sizes + (i*256);
- /* ida_gendisk[i].nr_real is handled by getgeometry */
-
+ ida_gendisk[i].nr_real = 0;
+
/* Get on the disk list */
ida_gendisk[i].next = gendisk_head;
gendisk_head = &ida_gendisk[i];
@@ -479,21 +517,13 @@
ida_geninit(i);
for(j=0; j<NWD; j++)
- register_disk(&ida_gendisk[i], MKDEV(MAJOR_NR+i,j<<4),
- 16, &ida_fops, hba[i]->drv[j].nr_blks);
+ register_disk(&ida_gendisk[i],
+ MKDEV(MAJOR_NR+i,j<<4),
+ 16, &ida_fops, hba[i]->drv[j].nr_blks);
+
}
/* done ! */
- return;
-bail5:
- kfree(ida_hardsizes);
-bail4:
- kfree(ida_blocksizes);
-bail3:
- kfree(ida_sizes);
-bail2:
- kfree(ida);
-bail:
- printk(KERN_ERR "cpqarray: out of memory.\n");
+ return(num_cntlrs_reg);
}
/*
@@ -506,103 +536,68 @@
{
int index;
unchar bus=0, dev_fn=0;
-
- /* This seems dumb, surely we could use an array of types to match ?? */
- for(index=0; ; index++) {
- if (pcibios_find_device(PCI_VENDOR_ID_DEC,
- PCI_DEVICE_ID_COMPAQ_42XX, index, &bus, &dev_fn))
- break;
- printk(KERN_DEBUG "42XX Device has been found at %x %x\n",
- bus, dev_fn);
- if (index == 1000000) break;
- if (nr_ctlr == 8) {
- printk("This driver supports a maximum of "
- "8 controllers.\n");
- break;
- }
-
- hba[nr_ctlr] = kmalloc(sizeof(ctlr_info_t), GFP_KERNEL);
- if(hba[nr_ctlr]==NULL)
- {
- printk(KERN_ERR "cpqarray: out of memory.\n");
- continue;
- }
- memset(hba[nr_ctlr], 0, sizeof(ctlr_info_t));
- if (cpqarray_pci_init(hba[nr_ctlr], bus, dev_fn) != 0)
- continue;
- sprintf(hba[nr_ctlr]->devname, "ida%d", nr_ctlr);
- hba[nr_ctlr]->ctlr = nr_ctlr;
- nr_ctlr++;
- }
-
- for(index=0; ; index++) {
- unsigned short subvendor=0;
+#define IDA_BOARD_TYPES 3
+ static int ida_vendor_id[IDA_BOARD_TYPES] = { PCI_VENDOR_ID_DEC,
+ PCI_VENDOR_ID_NCR, PCI_VENDOR_ID_COMPAQ };
+ static int ida_device_id[IDA_BOARD_TYPES] = { PCI_DEVICE_ID_COMPAQ_42XX, PCI_DEVICE_ID_NCR_53C1510, PCI_DEVICE_ID_COMPAQ_SMART2P };
+ int brdtype;
+
+ /* search for all PCI board types that could be for this driver */
+ for(brdtype=0; brdtype<IDA_BOARD_TYPES; brdtype++)
+ {
+ for(index=0; ; index++) {
+ if (pcibios_find_device(ida_vendor_id[brdtype],
+ ida_device_id[brdtype], index, &bus, &dev_fn))
+ break;
+ printk(KERN_DEBUG "cpqarray: Device %x has been found at %x %x\n",
+ ida_vendor_id[brdtype], bus, dev_fn);
+ if (index == 1000000) break;
+ if (nr_ctlr == 8) {
+ printk(KERN_WARNING "cpqarray: This driver"
+ " supports a maximum of 8 controllers.\n");
+ break;
+ }
- if (pcibios_find_device(PCI_VENDOR_ID_NCR,
- PCI_DEVICE_ID_NCR_53C1510, index, &bus, &dev_fn))
- break;
- printk(KERN_DEBUG "Integrated RAID Chip has been found at %x %x\n",
- bus, dev_fn);
- if(pcibios_read_config_word(bus, dev_fn,
- PCI_SUBSYSTEM_VENDOR_ID, &subvendor))
- {
- printk(KERN_DEBUG "cpqarray failed to read subvendor\n");
- break;
- }
- if(subvendor != PCI_VENDOR_ID_COMPAQ)
- break;
- printk(KERN_DEBUG "Its a compaq RAID Chip\n");
- if (index == 1000000) break;
- if (nr_ctlr == 8) {
- printk("This driver supports a maximum of "
- "8 controllers.\n");
- break;
- }
+/* if it is a PCI_DEVICE_ID_NCR_53C1510, make sure it's the Compaq version of the chip */
- hba[nr_ctlr] = kmalloc(sizeof(ctlr_info_t), GFP_KERNEL);
- if(hba[nr_ctlr]==NULL)
- {
- printk(KERN_ERR "cpqarray: out of memory.\n");
- continue;
- }
- memset(hba[nr_ctlr], 0, sizeof(ctlr_info_t));
- /* DOESNT THIS LEAK MEMORY ?????? - AC */
- if (cpqarray_pci_init(hba[nr_ctlr], bus, dev_fn) != 0)
- continue;
- sprintf(hba[nr_ctlr]->devname, "ida%d", nr_ctlr);
- hba[nr_ctlr]->ctlr = nr_ctlr;
- nr_ctlr++;
- }
+ if (ida_device_id[brdtype] == PCI_DEVICE_ID_NCR_53C1510) {
+ unsigned short subvendor=0;
+ if(pcibios_read_config_word(bus, dev_fn,
+ PCI_SUBSYSTEM_VENDOR_ID, &subvendor))
+ {
+ printk(KERN_DEBUG "cpqarray: failed to read subvendor\n");
+ continue;
+ }
+ if(subvendor != PCI_VENDOR_ID_COMPAQ)
+ {
+ printk(KERN_DEBUG
+ "cpqarray: not a Compaq integrated array controller\n");
+ continue;
+ }
+ }
- for(index=0; ; index++) {
- if (pcibios_find_device(PCI_VENDOR_ID_COMPAQ,
- PCI_DEVICE_ID_COMPAQ_SMART2P, index, &bus, &dev_fn))
- break;
+ hba[nr_ctlr] = kmalloc(sizeof(ctlr_info_t), GFP_KERNEL); if(hba[nr_ctlr]==NULL)
+ {
+ printk(KERN_ERR "cpqarray: out of memory.\n");
+ continue;
+ }
+ memset(hba[nr_ctlr], 0, sizeof(ctlr_info_t));
+ if (cpqarray_pci_init(hba[nr_ctlr], bus, dev_fn) != 0)
+ {
+ kfree(hba[nr_ctlr]);
+ continue;
+ }
+ sprintf(hba[nr_ctlr]->devname, "ida%d", nr_ctlr);
+ hba[nr_ctlr]->ctlr = nr_ctlr;
+ nr_ctlr++;
- if (index == 1000000) break;
- if (nr_ctlr == 8) {
- printk("This driver supports a maximum of "
- "8 controllers.\n");
- break;
}
-
- hba[nr_ctlr] = kmalloc(sizeof(ctlr_info_t), GFP_KERNEL);
- if(hba[nr_ctlr]==NULL)
- {
- printk(KERN_ERR "cpqarray: out of memory.\n");
- continue;
- }
- memset(hba[nr_ctlr], 0, sizeof(ctlr_info_t));
- if (cpqarray_pci_init(hba[nr_ctlr], bus, dev_fn) != 0)
- continue;
- sprintf(hba[nr_ctlr]->devname, "ida%d", nr_ctlr);
- hba[nr_ctlr]->ctlr = nr_ctlr;
- nr_ctlr++;
}
return nr_ctlr;
}
+
/*
* Find the IO address of the controller, its IRQ and so forth. Fill
* in some basic stuff into the ctlr_info_t structure.
@@ -671,8 +666,9 @@
}
}
if (i == NR_PRODUCTS) {
- printk("Sorry, I don't know how to access the SMART Array"
- " controller %08lx\n", (unsigned long)board_id);
+ printk(KERN_WARNING "cpqarray: Sorry, I don't know how"
+ " to access the SMART Array controller %08lx\n",
+ (unsigned long)board_id);
return -1;
}
@@ -734,8 +730,8 @@
while(i<8 && eisa[i]) {
if (nr_ctlr == 8) {
- printk("This driver supports a maximum of "
- "8 controllers.\n");
+ printk(KERN_WARNING "cpqarray: This driver supports"
+ " a maximum of 8 controllers.\n");
break;
}
board_id = inl(eisa[i]+0xC80);
@@ -744,11 +740,11 @@
break;
if (j == NR_PRODUCTS) {
- printk("Sorry, I don't know how to access the SMART"
- " Array controller %08lx\n", (unsigned long)board_id);
+ printk(KERN_WARNING "cpqarray: Sorry, I don't know how"
+ " to access the SMART Array controller %08lx\n", (unsigned long)board_id);
continue;
}
- hba[nr_ctlr] = kmalloc(sizeof(ctlr_info_t), GFP_KERNEL);
+ hba[nr_ctlr] = (ctlr_info_t *) kmalloc(sizeof(ctlr_info_t), GFP_KERNEL);
if(hba[nr_ctlr]==NULL)
{
printk(KERN_ERR "cpqarray: out of memory.\n");
@@ -885,21 +881,34 @@
queue_head = &blk_dev[MAJOR_NR+ctlr].request_queue.queue_head;
if (list_empty(queue_head))
- goto doreq_done;
+ {
+ start_io(h);
+ return;
+ }
+
creq = blkdev_entry_next_request(queue_head);
if (creq->rq_status == RQ_INACTIVE)
- goto doreq_done;
+ {
+ start_io(h);
+ return;
+ }
+
if (ctlr != MAJOR(creq->rq_dev)-MAJOR_NR ||
- ctlr > nr_ctlr || h == NULL) {
+ ctlr > nr_ctlr || h == NULL)
+ {
printk("doreq cmd for %d, %x at %p\n",
ctlr, creq->rq_dev, creq);
complete_buffers(creq->bh, 0);
- goto doreq_done;
+ start_io(h);
+ return;
}
if ((c = cmd_alloc(h)) == NULL)
- goto doreq_done;
+ {
+ start_io(h);
+ return;
+ }
bh = creq->bh;
@@ -972,9 +981,9 @@
/* Put the request on the tail of the request queue */
addQ(&h->reqQ, c);
h->Qdepth++;
- if (h->Qdepth > h->maxQsinceinit) h->maxQsinceinit = h->Qdepth;
+ if (h->Qdepth > h->maxQsinceinit)
+ h->maxQsinceinit = h->Qdepth;
-doreq_done:
start_io(h);
}
@@ -1022,28 +1031,24 @@
*/
static inline void complete_command(cmdlist_t *cmd, int timeout)
{
- char buf[80];
int ok=1;
if (cmd->req.hdr.rcode & RCODE_NONFATAL &&
(hba[cmd->ctlr]->misc_tflags & MISC_NONFATAL_WARN) == 0) {
- sprintf(buf, "Non Fatal error on ida/c%dd%d\n",
+ printk(KERN_WARNING "Non Fatal error on ida/c%dd%d\n",
cmd->ctlr, cmd->hdr.unit);
- console_print(buf);
hba[cmd->ctlr]->misc_tflags |= MISC_NONFATAL_WARN;
}
if (cmd->req.hdr.rcode & RCODE_FATAL) {
- sprintf(buf, "Fatal error on ida/c%dd%d\n",
+ printk(KERN_WARNING "Fatal error on ida/c%dd%d\n",
cmd->ctlr, cmd->hdr.unit);
- console_print(buf);
ok = 0;
}
if (cmd->req.hdr.rcode & RCODE_INVREQ) {
- sprintf(buf, "Invalid request on ida/c%dd%d = (cmd=%x sect=%d cnt=%d sg=%d ret=%x)\n",
+ printk(KERN_WARNING "Invalid request on ida/c%dd%d = (cmd=%x sect=%d cnt=%d sg=%d ret=%x)\n",
cmd->ctlr, cmd->hdr.unit, cmd->req.hdr.cmd,
cmd->req.hdr.blk, cmd->req.hdr.blk_cnt,
cmd->req.hdr.sg_cnt, cmd->req.hdr.rcode);
- console_print(buf);
ok = 0;
}
if (timeout) ok = 0;
@@ -1077,10 +1082,15 @@
if (istat & FIFO_NOT_EMPTY) {
while((a = h->access.command_completed(h))) {
a1 = a; a &= ~3;
- if ((c = h->cmpQ) == NULL) goto bad_completion;
+ if ((c = h->cmpQ) == NULL)
+ {
+ printk(KERN_WARNING "cpqarray: Completion of %08lx ignored\n", (unsigned long)a1);
+ continue;
+ }
while(c->busaddr != a) {
c = c->next;
- if (c == h->cmpQ) break;
+ if (c == h->cmpQ)
+ break;
}
/*
* If we've found the command, take it off the
@@ -1096,8 +1106,6 @@
}
continue;
}
-bad_completion:
- printk("Completion of %08lx ignored\n", (unsigned long)a1);
}
}
@@ -1227,16 +1235,27 @@
switch(io->cmd) {
case PASSTHRU_A:
p = kmalloc(io->sg[0].size, GFP_KERNEL);
- if (!p) { error = -ENOMEM; goto ioctl_err_exit; }
+ if (!p)
+ {
+ error = -ENOMEM;
+ cmd_free(NULL, c);
+ return(error);
+ }
copy_from_user(p, (void*)io->sg[0].addr, io->sg[0].size);
- c->req.bp = virt_to_bus(&(io->c));
+ c->req.hdr.blk = virt_to_bus(&(io->c));
c->req.sg[0].size = io->sg[0].size;
c->req.sg[0].addr = virt_to_bus(p);
c->req.hdr.sg_cnt = 1;
break;
case IDA_READ:
p = kmalloc(io->sg[0].size, GFP_KERNEL);
- if (!p) { error = -ENOMEM; goto ioctl_err_exit; }
+ if (!p)
+ {
+ error = -ENOMEM;
+ cmd_free(NULL, c);
+ return(error);
+ }
+
c->req.sg[0].size = io->sg[0].size;
c->req.sg[0].addr = virt_to_bus(p);
c->req.hdr.sg_cnt = 1;
@@ -1245,7 +1264,12 @@
case IDA_WRITE_MEDIA:
case DIAG_PASS_THRU:
p = kmalloc(io->sg[0].size, GFP_KERNEL);
- if (!p) { error = -ENOMEM; goto ioctl_err_exit; }
+ if (!p)
+ {
+ error = -ENOMEM;
+ cmd_free(NULL, c);
+ return(error);
+ }
copy_from_user(p, (void*)io->sg[0].addr, io->sg[0].size);
c->req.sg[0].size = io->sg[0].size;
c->req.sg[0].addr = virt_to_bus(p);
@@ -1284,10 +1308,8 @@
}
io->rcode = c->req.hdr.rcode;
- error = 0;
-ioctl_err_exit:
cmd_free(NULL, c);
- return error;
+ return(0);
}
/*
@@ -1390,8 +1412,8 @@
}
udelay(10);
DBG(
- printk("ida%d: idaSendPciCmd FIFO full, waiting!\n",
- ctlr);
+ printk(KERN_WARNING "cpqarray ida%d: idaSendPciCmd FIFO full,"
+ " waiting!\n", ctlr);
);
}
/*
@@ -1401,16 +1423,16 @@
complete = pollcomplete(ctlr);
if (complete != 1) {
if (complete != c->busaddr) {
- printk(
- "ida%d: idaSendPciCmd "
+ printk( KERN_WARNING
+ "cpqarray ida%d: idaSendPciCmd "
"Invalid command list address returned! (%08lx)\n",
ctlr, (unsigned long)complete);
cmd_free(info_p, c);
return (IO_ERROR);
}
} else {
- printk(
- "ida%d: idaSendPciCmd Timeout out, "
+ printk( KERN_WARNING
+ "cpqarray ida%d: idaSendPciCmd Timeout out, "
"No command list address returned!\n",
ctlr);
cmd_free(info_p, c);
@@ -1419,9 +1441,9 @@
if (c->req.hdr.rcode & 0x00FE) {
if (!(c->req.hdr.rcode & BIG_PROBLEM)) {
- printk(
- "ida%d: idaSendPciCmd, error: Controller failed "
- "at init time "
+ printk( KERN_WARNING
+ "cpqarray ida%d: idaSendPciCmd, error: "
+ "Controller failed at init time "
"cmd: 0x%x, return code = 0x%x\n",
ctlr, c->req.hdr.cmd, c->req.hdr.rcode);
@@ -1461,8 +1483,8 @@
spin_lock_irqsave(&io_request_lock, flags);
if (hba[ctlr]->usage_count > 1) {
spin_unlock_irqrestore(&io_request_lock, flags);
- printk("Device busy for volume revalidation (usage=%d)\n",
- hba[ctlr]->usage_count);
+ printk(KERN_WARNING "cpqarray: Device busy for volume"
+ " revalidation (usage=%d)\n", hba[ctlr]->usage_count);
return -EBUSY;
}
spin_unlock_irqrestore(&io_request_lock, flags);
@@ -1514,8 +1536,9 @@
spin_lock_irqsave(&io_request_lock, flags);
if (hba[ctlr]->drv[target].usage_count > maxusage) {
spin_unlock_irqrestore(&io_request_lock, flags);
- printk("Device busy for revalidation (usage=%d)\n",
- hba[ctlr]->drv[target].usage_count);
+ printk(KERN_WARNING "cpqarray: Device busy for "
+ "revalidation (usage=%d)\n",
+ hba[ctlr]->drv[target].usage_count);
return -EBUSY;
}
@@ -1581,22 +1604,28 @@
id_ctlr_t *id_ctlr_buf;
int ret_code;
- if( hba[ctlr]->board_id != 0x40400E11)
+ if( (hba[ctlr]->board_id != 0x40400E11)
+ && (hba[ctlr]->board_id != 0x40480E11) )
+
/* Not a Integrated Raid, so there is nothing for us to do */
return;
- printk(KERN_DEBUG "Starting firmware's background processing\n");
+ printk(KERN_DEBUG "cpqarray: Starting firmware's background"
+ " processing\n");
/* Command does not return anything, but idasend command needs a
buffer */
id_ctlr_buf = (id_ctlr_t *)kmalloc(sizeof(id_ctlr_t), GFP_KERNEL);
if(id_ctlr_buf==NULL)
{
- printk(KERN_WARNING "Out of memory. Unable to start background processing.\n");
+ printk(KERN_WARNING "cpqarray: Out of memory. "
+ "Unable to start background processing.\n");
return;
}
ret_code = sendcmd(RESUME_BACKGROUND_ACTIVITY, ctlr,
id_ctlr_buf, 0, 0, 0, 0);
if(ret_code != IO_OK)
- printk(KERN_WARNING "Unable to start background processing\n");
+ printk(KERN_WARNING "cpqarray: Unable to start"
+ " background processing\n");
+
kfree(id_ctlr_buf);
}
/*****************************************************************
@@ -1620,16 +1649,38 @@
id_ldrive = (id_log_drv_t *)kmalloc(sizeof(id_log_drv_t), GFP_KERNEL);
if(id_ldrive == NULL)
+ {
+ printk( KERN_ERR "cpqarray: out of memory.\n");
return;
+ }
+
id_ctlr_buf = (id_ctlr_t *)kmalloc(sizeof(id_ctlr_t), GFP_KERNEL);
if(id_ctlr_buf == NULL)
- goto bail2;
+ {
+ kfree(id_ldrive);
+ printk( KERN_ERR "cpqarray: out of memory.\n");
+ return;
+ }
+
id_lstatus_buf = (sense_log_drv_stat_t *)kmalloc(sizeof(sense_log_drv_stat_t), GFP_KERNEL);
if(id_lstatus_buf == NULL)
- goto bail3;
+ {
+ kfree(id_ctlr_buf);
+ kfree(id_ldrive);
+ printk( KERN_ERR "cpqarray: out of memory.\n");
+ return;
+ }
+
sense_config_buf = (config_t *)kmalloc(sizeof(config_t), GFP_KERNEL);
if(sense_config_buf == NULL)
- goto bail4;
+ {
+ kfree(id_lstatus_buf);
+ kfree(id_ctlr_buf);
+ kfree(id_ldrive);
+ printk( KERN_ERR "cpqarray: out of memory.\n");
+ return;
+ }
+
memset(id_ldrive, 0, sizeof(id_log_drv_t));
memset(id_ctlr_buf, 0, sizeof(id_ctlr_t));
memset(id_lstatus_buf, 0, sizeof(sense_log_drv_stat_t));
@@ -1648,8 +1699,15 @@
* so the idastubopen will fail on all logical drives
* on the controller.
*/
- goto geo_ret; /* release the buf and return */
- }
+ /* Free all the buffers and return */
+ printk(KERN_ERR "cpqarray: error sending ID controller\n");
+ kfree(sense_config_buf);
+ kfree(id_lstatus_buf);
+ kfree(id_ctlr_buf);
+ kfree(id_ldrive);
+ return;
+ }
+
info_p->log_drives = id_ctlr_buf->nr_drvs;;
*(__u32*)(info_p->firm_rev) = *(__u32*)(id_ctlr_buf->firm_rev);
info_p->ctlr_sig = id_ctlr_buf->cfg_sig;
@@ -1663,8 +1721,9 @@
* Get drive geometry for all logical drives
*/
if (id_ctlr_buf->nr_drvs > 16)
- printk("ida%d: This driver supports 16 logical drives "
- "per controller.\n. Additional drives will not be "
+ printk(KERN_WARNING "cpqarray ida%d: This driver supports "
+ "16 logical drives per controller.\n. "
+ " Additional drives will not be "
"detected\n", ctlr);
for (log_unit = 0;
@@ -1687,13 +1746,17 @@
on the controller.
*/
info_p->log_drv_map = 0;
- printk(
- "ida%d: idaGetGeometry - Controller failed "
- "to report status of logical drive %d\n"
+ printk( KERN_WARNING
+ "cpqarray ida%d: idaGetGeometry - Controller"
+ " failed to report status of logical drive %d\n"
"Access to this controller has been disabled\n",
ctlr, log_unit);
- goto geo_ret; /* release the buf and return */
-
+ /* Free all the buffers and return */
+ kfree(sense_config_buf);
+ kfree(id_lstatus_buf);
+ kfree(id_ctlr_buf);
+ kfree(id_ldrive);
+ return;
}
/*
Make sure the logical drive is configured
@@ -1715,14 +1778,21 @@
drv->sectors = id_ldrive->drv.sect_per_track;
info_p->log_drv_map |= (1 << log_unit);
- printk("ida/c%dd%d: blksz=%d nr_blks=%d\n",
+ printk(KERN_INFO "cpqarray ida/c%dd%d: blksz=%d nr_blks=%d\n",
ctlr, log_unit, drv->blk_size, drv->nr_blks);
ret_code = sendcmd(SENSE_CONFIG,
ctlr, sense_config_buf,
sizeof(config_t), 0, 0, log_unit);
if (ret_code == IO_ERROR) {
info_p->log_drv_map = 0;
- goto geo_ret; /* release the buf and return */
+ /* Free all the buffers and return */
+ printk(KERN_ERR "cpqarray: error sending sense config\n");
+ kfree(sense_config_buf);
+ kfree(id_lstatus_buf);
+ kfree(id_ctlr_buf);
+ kfree(id_ldrive);
+ return;
+
}
info_p->phys_drives =
sense_config_buf->ctlr_phys_drv;
@@ -1736,12 +1806,10 @@
log_index = log_index + 1;
} /* end of if logical drive configured */
} /* end of for log_unit */
-geo_ret:
kfree(sense_config_buf);
-bail4:
- kfree(id_ldrive);
-bail3:
- kfree(id_lstatus_buf);
-bail2:
+ kfree(id_ldrive);
+ kfree(id_lstatus_buf);
kfree(id_ctlr_buf);
+ return;
+
}
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)