linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* cciss error handling patch for kernel 2.6.0, pass 2
@ 2003-09-05 21:45 mike.miller
  0 siblings, 0 replies; only message in thread
From: mike.miller @ 2003-09-05 21:45 UTC (permalink / raw)
  To: axboe, akpm; +Cc: linux-kernel

This is a fixed error handling patch for the cciss driver v2.5.0. It fixes a bug where the I/O memory may not be released in case of an error. Thanks to Andrew Morton for pointing this out.
Also made the label names more descriptive.
Built, tested against 2.6.0-test4.
Please consider this for inclusion in the 2.6.0 kernel.

Thanks,
mikem
-------------------------------------------------------------------------------

diff -burN lx260test4-p1/drivers/block/cciss.c lx260test4/drivers/block/cciss.c
--- lx260test4-p1/drivers/block/cciss.c	2003-08-26 13:09:45.000000000 -0500
+++ lx260test4/drivers/block/cciss.c	2003-09-05 16:10:04.000000000 -0500
@@ -2447,11 +2447,8 @@
 	if( i < 0 ) 
 		return (-1);
 	if (cciss_pci_init(hba[i], pdev) != 0)
-	{
-		release_io_mem(hba[i]);
-		free_hba(i);
-		return (-1);
-	}
+		goto free_hba;
+	
 	sprintf(hba[i]->devname, "cciss%d", i);
 	hba[i]->ctlr = i;
 	hba[i]->pdev = pdev;
@@ -2463,28 +2460,23 @@
 		printk("cciss: not using DAC cycles\n");
 	else {
 		printk("cciss: no suitable DMA available\n");
-		free_hba(i);
-		return -ENODEV;
+		goto free_hba;
 	}
 
 	if (register_blkdev(COMPAQ_CISS_MAJOR+i, hba[i]->devname)) {
-		release_io_mem(hba[i]);
-		free_hba(i);
-		return -1;
+		printk(KERN_ERR "cciss: Unable to register device %s\n",
+				hba[i]->devname);
+		goto free_hba;
 	}
 
 	/* make sure the board interrupts are off */
 	hba[i]->access.set_intr_mask(hba[i], CCISS_INTR_OFF);
 	if( request_irq(hba[i]->intr, do_cciss_intr, 
 		SA_INTERRUPT | SA_SHIRQ | SA_SAMPLE_RANDOM, 
-			hba[i]->devname, hba[i]))
-	{
-		printk(KERN_ERR "ciss: Unable to get irq %d for %s\n",
+			hba[i]->devname, hba[i])) {
+		printk(KERN_ERR "cciss: Unable to get irq %d for %s\n",
 			hba[i]->intr, hba[i]->devname);
-		unregister_blkdev( COMPAQ_CISS_MAJOR+i, hba[i]->devname);
-		release_io_mem(hba[i]);
-		free_hba(i);
-		return(-1);
+		goto free_blkdev;	
 	}
 	hba[i]->cmd_pool_bits = kmalloc(((NR_CMDS+BITS_PER_LONG-1)/BITS_PER_LONG)*sizeof(unsigned long), GFP_KERNEL);
 	hba[i]->cmd_pool = (CommandList_struct *)pci_alloc_consistent(
@@ -2495,35 +2487,15 @@
 		&(hba[i]->errinfo_pool_dhandle));
 	if((hba[i]->cmd_pool_bits == NULL) 
 		|| (hba[i]->cmd_pool == NULL)
-		|| (hba[i]->errinfo_pool == NULL))
-        {
-err_all:
-		if(hba[i]->cmd_pool_bits)
-                	kfree(hba[i]->cmd_pool_bits);
-                if(hba[i]->cmd_pool)
-                	pci_free_consistent(hba[i]->pdev,  
-				NR_CMDS * sizeof(CommandList_struct), 
-				hba[i]->cmd_pool, hba[i]->cmd_pool_dhandle);	
-		if(hba[i]->errinfo_pool)
-			pci_free_consistent(hba[i]->pdev,
-				NR_CMDS * sizeof( ErrorInfo_struct),
-				hba[i]->errinfo_pool, 
-				hba[i]->errinfo_pool_dhandle);
-                free_irq(hba[i]->intr, hba[i]);
-                unregister_blkdev(COMPAQ_CISS_MAJOR+i, hba[i]->devname);
-		release_io_mem(hba[i]);
-		free_hba(i);
+		|| (hba[i]->errinfo_pool == NULL)) {
                 printk( KERN_ERR "cciss: out of memory");
-		return(-1);
+		goto free_pool;	
 	}
 
-	/*
-	 * someone needs to clean up this failure handling mess
-	 */
 	spin_lock_init(&hba[i]->lock);
 	q = blk_init_queue(do_cciss_request, &hba[i]->lock);
 	if (!q)
-		goto err_all;
+		goto free_pool;
 
 	hba[i]->queue = q;
 
@@ -2576,6 +2548,26 @@
 		add_disk(disk);
 	}
 	return(1);
+
+free_pool:
+	if(hba[i]->cmd_pool_bits)
+               	kfree(hba[i]->cmd_pool_bits);
+	if(hba[i]->cmd_pool)
+		pci_free_consistent(hba[i]->pdev,  
+		NR_CMDS * sizeof(CommandList_struct), 
+		hba[i]->cmd_pool, hba[i]->cmd_pool_dhandle);	
+	if(hba[i]->errinfo_pool)
+		pci_free_consistent(hba[i]->pdev,
+		NR_CMDS * sizeof( ErrorInfo_struct),
+		hba[i]->errinfo_pool, 
+		hba[i]->errinfo_pool_dhandle);
+	free_irq(hba[i]->intr, hba[i]);
+free_blkdev:
+	unregister_blkdev(COMPAQ_CISS_MAJOR+i, hba[i]->devname);
+free_hba:
+	release_io_mem(hba[i]);
+	free_hba(i);
+	return(-1);
 }
 
 static void __devexit cciss_remove_one (struct pci_dev *pdev)

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2003-09-05 21:40 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2003-09-05 21:45 cciss error handling patch for kernel 2.6.0, pass 2 mike.miller

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).