diff options
author | Tony Battersby <tonyb@cybernetics.com> | 2009-01-08 18:54:45 +0100 |
---|---|---|
committer | James Bottomley <James.Bottomley@HansenPartnership.com> | 2009-03-12 18:58:16 +0100 |
commit | b409063a9b7a56c0d658feaffedeb74ad71edce7 (patch) | |
tree | 9cce185196e88f961e1cf5c24253ae84098b8822 | |
parent | [SCSI] sym53c8xx: fix NULL deref on error path (diff) | |
download | linux-b409063a9b7a56c0d658feaffedeb74ad71edce7.tar.xz linux-b409063a9b7a56c0d658feaffedeb74ad71edce7.zip |
[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>
-rw-r--r-- | drivers/scsi/sym53c8xx_2/sym_glue.c | 11 |
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, /* * Free controller resources. */ -static void sym_free_resources(struct sym_hcb *np, struct pci_dev *pdev) +static void sym_free_resources(struct sym_hcb *np, struct pci_dev *pdev, + int do_free_irq) { /* * Free O/S specific resources. */ - if (pdev->irq) + if (do_free_irq) free_irq(pdev->irq, np->s.host); if (np->s.ioaddr) pci_iounmap(pdev, np->s.ioaddr); @@ -1275,6 +1276,7 @@ static struct Scsi_Host * __devinit sym_attach(struct scsi_host_template *tpnt, struct pci_dev *pdev = dev->pdev; unsigned long flags; struct sym_fw *fw; + int do_free_irq = 0; printk(KERN_INFO "sym%d: <%s> rev 0x%x at pci %s irq %u\n", 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, sym_name(np), pdev->irq); goto attach_failed; } + do_free_irq = 1; /* * After SCSI devices have been opened, we cannot @@ -1420,7 +1423,7 @@ static struct Scsi_Host * __devinit sym_attach(struct scsi_host_template *tpnt, return NULL; printf_info("sym%d: giving up ...\n", unit); if (np) - sym_free_resources(np, pdev); + sym_free_resources(np, pdev, do_free_irq); scsi_host_put(shost); return NULL; @@ -1659,7 +1662,7 @@ static int sym_detach(struct Scsi_Host *shost, struct pci_dev *pdev) udelay(10); OUTB(np, nc_istat, 0); - sym_free_resources(np, pdev); + sym_free_resources(np, pdev, 1); scsi_host_put(shost); return 1; |