diff options
author | Matthew Wilcox <matthew@wil.cx> | 2007-08-15 14:56:55 -0400 |
---|---|---|
committer | James Bottomley <jejb@mulgrave.localdomain> | 2007-10-12 14:51:33 -0400 |
commit | f01abb362f878b8e2de69c03662d8e7f3ae1d6f8 (patch) | |
tree | c1cd3eedd0919db831175e2da28e8c494848058f /drivers/scsi/aic94xx | |
parent | a60ebc52cbfafc291c6b0b89e41ecaf3685c8e2a (diff) |
[SCSI] aic94xx: Free scsi host on error
If an error occurred during initialisation, we would sometimes fail to
call scsi_host_put() and thus end up with a leaked scsi_host. It was
also possible to miss calling scsi_remove_host().
Signed-off-by: Matthew Wilcox <matthew@wil.cx>
Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
Diffstat (limited to 'drivers/scsi/aic94xx')
-rw-r--r-- | drivers/scsi/aic94xx/aic94xx_init.c | 17 |
1 files changed, 9 insertions, 8 deletions
diff --git a/drivers/scsi/aic94xx/aic94xx_init.c b/drivers/scsi/aic94xx/aic94xx_init.c index 63d104578a77..b70d6e7f96e9 100644 --- a/drivers/scsi/aic94xx/aic94xx_init.c +++ b/drivers/scsi/aic94xx/aic94xx_init.c | |||
@@ -583,7 +583,7 @@ static int __devinit asd_pci_probe(struct pci_dev *dev, | |||
583 | asd_ha = kzalloc(sizeof(*asd_ha), GFP_KERNEL); | 583 | asd_ha = kzalloc(sizeof(*asd_ha), GFP_KERNEL); |
584 | if (!asd_ha) { | 584 | if (!asd_ha) { |
585 | asd_printk("out of memory\n"); | 585 | asd_printk("out of memory\n"); |
586 | goto Err; | 586 | goto Err_put; |
587 | } | 587 | } |
588 | asd_ha->pcidev = dev; | 588 | asd_ha->pcidev = dev; |
589 | asd_ha->sas_ha.dev = &asd_ha->pcidev->dev; | 589 | asd_ha->sas_ha.dev = &asd_ha->pcidev->dev; |
@@ -600,14 +600,12 @@ static int __devinit asd_pci_probe(struct pci_dev *dev, | |||
600 | shost->max_cmd_len = 16; | 600 | shost->max_cmd_len = 16; |
601 | 601 | ||
602 | err = scsi_add_host(shost, &dev->dev); | 602 | err = scsi_add_host(shost, &dev->dev); |
603 | if (err) { | 603 | if (err) |
604 | scsi_host_put(shost); | ||
605 | goto Err_free; | 604 | goto Err_free; |
606 | } | ||
607 | 605 | ||
608 | err = asd_dev->setup(asd_ha); | 606 | err = asd_dev->setup(asd_ha); |
609 | if (err) | 607 | if (err) |
610 | goto Err_free; | 608 | goto Err_remove; |
611 | 609 | ||
612 | err = -ENODEV; | 610 | err = -ENODEV; |
613 | if (!pci_set_dma_mask(dev, DMA_64BIT_MASK) | 611 | if (!pci_set_dma_mask(dev, DMA_64BIT_MASK) |
@@ -618,14 +616,14 @@ static int __devinit asd_pci_probe(struct pci_dev *dev, | |||
618 | ; | 616 | ; |
619 | else { | 617 | else { |
620 | asd_printk("no suitable DMA mask for %s\n", pci_name(dev)); | 618 | asd_printk("no suitable DMA mask for %s\n", pci_name(dev)); |
621 | goto Err_free; | 619 | goto Err_remove; |
622 | } | 620 | } |
623 | 621 | ||
624 | pci_set_drvdata(dev, asd_ha); | 622 | pci_set_drvdata(dev, asd_ha); |
625 | 623 | ||
626 | err = asd_map_ha(asd_ha); | 624 | err = asd_map_ha(asd_ha); |
627 | if (err) | 625 | if (err) |
628 | goto Err_free; | 626 | goto Err_remove; |
629 | 627 | ||
630 | err = asd_create_ha_caches(asd_ha); | 628 | err = asd_create_ha_caches(asd_ha); |
631 | if (err) | 629 | if (err) |
@@ -692,9 +690,12 @@ Err_free_cache: | |||
692 | asd_destroy_ha_caches(asd_ha); | 690 | asd_destroy_ha_caches(asd_ha); |
693 | Err_unmap: | 691 | Err_unmap: |
694 | asd_unmap_ha(asd_ha); | 692 | asd_unmap_ha(asd_ha); |
693 | Err_remove: | ||
694 | scsi_remove_host(shost); | ||
695 | Err_free: | 695 | Err_free: |
696 | kfree(asd_ha); | 696 | kfree(asd_ha); |
697 | scsi_remove_host(shost); | 697 | Err_put: |
698 | scsi_host_put(shost); | ||
698 | Err: | 699 | Err: |
699 | pci_disable_device(dev); | 700 | pci_disable_device(dev); |
700 | return err; | 701 | return err; |