arcmsr: call scsi_scan_host at the end of host initialization
authorChing Huang <ching2048@areca.com.tw>
Tue, 19 Aug 2014 07:28:36 +0000 (15:28 +0800)
committerChristoph Hellwig <hch@lst.de>
Tue, 16 Sep 2014 16:40:11 +0000 (09:40 -0700)
Call scsi_scan_host at the end of host initialization and fix and error path
to free allocated resource.

Signed-off-by: Ching Huang <ching2048@areca.com.tw>
Reviewed-by: Tomas Henzl <thenzl@redhat.com>
Signed-off-by: Christoph Hellwig <hch@lst.de>
drivers/scsi/arcmsr/arcmsr_hba.c

index b3cb969c72d50c8452ec240983693e56f92e5b4c..3d3cdfe07089df4692a959585d0b43523b6a87fb 100644 (file)
@@ -112,6 +112,7 @@ static void arcmsr_hbaD_message_isr(struct AdapterControlBlock *acb);
 static void arcmsr_hardware_reset(struct AdapterControlBlock *acb);
 static const char *arcmsr_info(struct Scsi_Host *);
 static irqreturn_t arcmsr_interrupt(struct AdapterControlBlock *acb);
+static void arcmsr_free_irq(struct pci_dev *, struct AdapterControlBlock *);
 static int arcmsr_adjust_disk_queue_depth(struct scsi_device *sdev,
                                          int queue_depth, int reason)
 {
@@ -755,12 +756,11 @@ static int arcmsr_probe(struct pci_dev *pdev, const struct pci_device_id *id)
        }
        error = scsi_add_host(host, &pdev->dev);
        if(error){
-               goto RAID_controller_stop;
+               goto free_ccb_pool;
        }
        if (arcmsr_request_irq(pdev, acb) == FAILED)
                goto scsi_host_remove;
        arcmsr_iop_init(acb);
-       scsi_scan_host(host);
        INIT_WORK(&acb->arcmsr_do_message_isr_bh, arcmsr_message_isr_bh_fn);
        atomic_set(&acb->rq_map_token, 16);
        atomic_set(&acb->ante_token_value, 16);
@@ -772,13 +772,17 @@ static int arcmsr_probe(struct pci_dev *pdev, const struct pci_device_id *id)
        add_timer(&acb->eternal_timer);
        if(arcmsr_alloc_sysfs_attr(acb))
                goto out_free_sysfs;
+       scsi_scan_host(host);
        return 0;
 out_free_sysfs:
-scsi_host_remove:
-       scsi_remove_host(host);
-RAID_controller_stop:
+       del_timer_sync(&acb->eternal_timer);
+       flush_work(&acb->arcmsr_do_message_isr_bh);
        arcmsr_stop_adapter_bgrb(acb);
        arcmsr_flush_adapter_cache(acb);
+       arcmsr_free_irq(pdev, acb);
+scsi_host_remove:
+       scsi_remove_host(host);
+free_ccb_pool:
        arcmsr_free_ccb_pool(acb);
 free_hbb_mu:
        arcmsr_free_mu(acb);