[PATCH] 2.4.21 cpqarray, bigioctl memory leak

From: Wiran, Francis (francis.wiran@hp.com)
Date: Wed Jul 09 2003 - 14:04:11 EST


Changes:
  1. Bumped version to 2.4.26
  2. memory leak fix in ida_ctlr_big_ioctl()
  3. removed some pci_read_config calls due to values
     already available in pdev (per Tom Coughlan, RedHat, Apr 2003)

 drivers/block/cpqarray.c | 59
+++++++++++++++--------------------------------
 1 files changed, 19 insertions(+), 40 deletions(-)

---
linux-2.4.21-2/drivers/block/cpqarray.c~cpqarray_2.4.26_from_2.4.25_for_
RH80	Wed Jul  9 11:48:48 2003
+++ linux-2.4.21-2-root/drivers/block/cpqarray.c	Wed Jul  9
13:55:05 2003
@@ -41,13 +41,13 @@
 
 #define SMART2_DRIVER_VERSION(maj,min,submin)
((maj<<16)|(min<<8)|(submin))
 
-#define DRIVER_NAME "Compaq SMART2 Driver (v 2.4.25)"
-#define DRIVER_VERSION SMART2_DRIVER_VERSION(2,4,25)
+#define DRIVER_NAME "Compaq SMART2 Driver (v 2.4.26)"
+#define DRIVER_VERSION SMART2_DRIVER_VERSION(2,4,26)
 
 /* Embedded module documentation macros - see modules.h */
 /* Original author Chris Frantz - Compaq Computer Corporation */
 MODULE_AUTHOR("Compaq Computer Corporation");
-MODULE_DESCRIPTION("Driver for Compaq Smart2 Array Controllers version
2.4.25");
+MODULE_DESCRIPTION("Driver for Compaq Smart2 Array Controllers version
2.4.26");
 MODULE_LICENSE("GPL");
 
 #define MAJOR_NR COMPAQ_SMART2_MAJOR
@@ -657,9 +657,8 @@ static void free_hba(int i)
  */
 static int cpqarray_pci_init(ctlr_info_t *c, struct pci_dev *pdev)
 {
-	ushort vendor_id, device_id, command;
-	unchar cache_line_size, latency_timer;
-	unchar irq, revision;
+	ushort subsystem_vendor_id, subsystem_device_id, command;
+	unchar irq;
 	unsigned long addr[6];
 	__u32 board_id;
 
@@ -673,10 +672,13 @@ static int cpqarray_pci_init(ctlr_info_t
 	}
 	
 	c->pci_dev = pdev;
-	vendor_id = pdev->vendor;
-	device_id = pdev->device;
+	subsystem_vendor_id = pdev->subsystem_vendor;
+	subsystem_device_id = pdev->subsystem_device;
 	irq = pdev->irq;
 
+	board_id = (((__u32) (subsystem_device_id) << 16) & 0xffff0000)
|
+			(__u32) (subsystem_vendor_id);
+
 	for(i=0; i<6; i++)
 		addr[i] = pci_resource_start(pdev, i);
 
@@ -689,25 +691,6 @@ static int cpqarray_pci_init(ctlr_info_t
 		return -1;
 	}
 
-	pci_read_config_byte(pdev, PCI_CLASS_REVISION, &revision);
-	pci_read_config_byte(pdev, PCI_CACHE_LINE_SIZE,
&cache_line_size);
-	pci_read_config_byte(pdev, PCI_LATENCY_TIMER, &latency_timer);
-
-	pci_read_config_dword(pdev, 0x2c, &board_id);
-
-DBGINFO(
-	printk("vendor_id = %x\n", vendor_id);
-	printk("device_id = %x\n", device_id);
-	printk("command = %x\n", command);
-	for(i=0; i<6; i++)
-		printk("addr[%d] = %lx\n", i, addr[i]);
-	printk("revision = %x\n", revision);
-	printk("irq = %x\n", irq);
-	printk("cache_line_size = %x\n", cache_line_size);
-	printk("latency_timer = %x\n", latency_timer);
-	printk("board_id = %x\n", board_id);
-);
-
 	c->intr = irq;
 	for(i=0; i<6; i++) {
 		if (pci_resource_flags(pdev, i) &
PCI_BASE_ADDRESS_SPACE_IO) { 
@@ -1654,6 +1637,7 @@ static int ida_ctlr_big_ioctl(int ctlr, 
 	for(i=0; i<c->req.hdr.sg_cnt; i++) {
 		pci_unmap_single(h->pci_dev, c->req.sg[i].addr, 
 				c->req.sg[i].size,
PCI_DMA_BIDIRECTIONAL);
+		c->reg.sg[i].addr = 0;
 	}
 
 	/* if we are reading data from the hardware copy it back to user
*/
@@ -1674,31 +1658,26 @@ static int ida_ctlr_big_ioctl(int ctlr, 
 
 	io->rcode = c->req.hdr.rcode;
 
+ida_alloc_cleanup:
 	if(scsi_param) {
 		pci_unmap_single(h->pci_dev, c->req.hdr.blk,
 			sizeof(scsi_param_t), PCI_DMA_BIDIRECTIONAL);
 		/* copy the scsi_params back to the user */ 
-		if( copy_to_user(io->scsi_param, scsi_param, 
+		if(error == 0 &&
+			copy_to_user(io->scsi_param, scsi_param, 
 					sizeof(scsi_param_t))) {
 			error = -EFAULT;	
 		}
 		kfree(scsi_param);
 	}
-	cmd_free(h, c, 0);
-	return(error);
 	
-ida_alloc_cleanup:
-	if(scsi_param) {
-		pci_unmap_single(h->pci_dev, c->req.hdr.blk,
-			sizeof(scsi_param_t), PCI_DMA_BIDIRECTIONAL);
-		kfree(scsi_param);
-	}
 	for (i=0; i<sg_used; i++) {
-		if(buff[sg_used] != NULL) {	
+		if(c->req.sg[i].addr != NULL)
 			pci_unmap_single(h->pci_dev, c->req.sg[i].addr, 
-				buff_size[sg_used],
PCI_DMA_BIDIRECTIONAL);
-			kfree(buff[sg_used]);
-		}
+				buff_size[i], PCI_DMA_BIDIRECTIONAL);
+		if(buff[i]!=NULL)
+			kfree(buff[i]);
+
 	}	
 	cmd_free(h, c, 0);
 	return(error);

_ - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/



This archive was generated by hypermail 2b29 : Tue Jul 15 2003 - 22:00:32 EST