aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi
diff options
context:
space:
mode:
authorTony Battersby <tonyb@cybernetics.com>2009-01-08 12:54:45 -0500
committerJames Bottomley <James.Bottomley@HansenPartnership.com>2009-03-12 13:58:16 -0400
commitb409063a9b7a56c0d658feaffedeb74ad71edce7 (patch)
tree9cce185196e88f961e1cf5c24253ae84098b8822 /drivers/scsi
parent07b9d81e849f64b990e943de6ad75b63dafe5a4b (diff)
[SCSI] sym53c8xx: fix bogus free_irq() on error path
If sym_attach() gets an error at or before request_irq(), then sym_free_resources() will call free_irq() for an unregistered interrupt handler. Signed-off-by: Tony Battersby <tonyb@cybernetics.com> Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
Diffstat (limited to 'drivers/scsi')
-rw-r--r--drivers/scsi/sym53c8xx_2/sym_glue.c11
1 files changed, 7 insertions, 4 deletions
diff --git a/drivers/scsi/sym53c8xx_2/sym_glue.c b/drivers/scsi/sym53c8xx_2/sym_glue.c
index cef03e768367..a8ac60caadc0 100644
--- a/drivers/scsi/sym53c8xx_2/sym_glue.c
+++ b/drivers/scsi/sym53c8xx_2/sym_glue.c
@@ -1238,12 +1238,13 @@ static int sym53c8xx_proc_info(struct Scsi_Host *shost, char *buffer,
1238/* 1238/*
1239 * Free controller resources. 1239 * Free controller resources.
1240 */ 1240 */
1241static void sym_free_resources(struct sym_hcb *np, struct pci_dev *pdev) 1241static void sym_free_resources(struct sym_hcb *np, struct pci_dev *pdev,
1242 int do_free_irq)
1242{ 1243{
1243 /* 1244 /*
1244 * Free O/S specific resources. 1245 * Free O/S specific resources.
1245 */ 1246 */
1246 if (pdev->irq) 1247 if (do_free_irq)
1247 free_irq(pdev->irq, np->s.host); 1248 free_irq(pdev->irq, np->s.host);
1248 if (np->s.ioaddr) 1249 if (np->s.ioaddr)
1249 pci_iounmap(pdev, np->s.ioaddr); 1250 pci_iounmap(pdev, np->s.ioaddr);
@@ -1275,6 +1276,7 @@ static struct Scsi_Host * __devinit sym_attach(struct scsi_host_template *tpnt,
1275 struct pci_dev *pdev = dev->pdev; 1276 struct pci_dev *pdev = dev->pdev;
1276 unsigned long flags; 1277 unsigned long flags;
1277 struct sym_fw *fw; 1278 struct sym_fw *fw;
1279 int do_free_irq = 0;
1278 1280
1279 printk(KERN_INFO "sym%d: <%s> rev 0x%x at pci %s irq %u\n", 1281 printk(KERN_INFO "sym%d: <%s> rev 0x%x at pci %s irq %u\n",
1280 unit, dev->chip.name, pdev->revision, pci_name(pdev), 1282 unit, dev->chip.name, pdev->revision, pci_name(pdev),
@@ -1364,6 +1366,7 @@ static struct Scsi_Host * __devinit sym_attach(struct scsi_host_template *tpnt,
1364 sym_name(np), pdev->irq); 1366 sym_name(np), pdev->irq);
1365 goto attach_failed; 1367 goto attach_failed;
1366 } 1368 }
1369 do_free_irq = 1;
1367 1370
1368 /* 1371 /*
1369 * After SCSI devices have been opened, we cannot 1372 * After SCSI devices have been opened, we cannot
@@ -1420,7 +1423,7 @@ static struct Scsi_Host * __devinit sym_attach(struct scsi_host_template *tpnt,
1420 return NULL; 1423 return NULL;
1421 printf_info("sym%d: giving up ...\n", unit); 1424 printf_info("sym%d: giving up ...\n", unit);
1422 if (np) 1425 if (np)
1423 sym_free_resources(np, pdev); 1426 sym_free_resources(np, pdev, do_free_irq);
1424 scsi_host_put(shost); 1427 scsi_host_put(shost);
1425 1428
1426 return NULL; 1429 return NULL;
@@ -1659,7 +1662,7 @@ static int sym_detach(struct Scsi_Host *shost, struct pci_dev *pdev)
1659 udelay(10); 1662 udelay(10);
1660 OUTB(np, nc_istat, 0); 1663 OUTB(np, nc_istat, 0);
1661 1664
1662 sym_free_resources(np, pdev); 1665 sym_free_resources(np, pdev, 1);
1663 scsi_host_put(shost); 1666 scsi_host_put(shost);
1664 1667
1665 return 1; 1668 return 1;