Skip to contentSkip to conversation

lpfc 8.1.5 : Fix cleanup code in the lpfc_pci_probe_one() error code path

PATCH In review James Smart 2 participants 3 messages Apr 15, 2006 – Apr 16, 2006

Subsystems (2)
lore
Share & tools
lore
#0 lore raw

PATCH 4/7 lpfc 8.1.5 : Fix cleanup code in the lpfc_pci_probe_one() error code path

Fix cleanup code in the lpfc_pci_probe_one() error code path.

drivers/scsi/lpfc/lpfc_init.c +12 -2
@@ -1618,7 +1618,7 @@ lpfc_pci_probe_one(struct pci_dev *pdev,
 
 	error = lpfc_alloc_sysfs_attr(phba);
 	if (error)
-		goto out_kthread_stop;
+		goto out_remove_host;
 
 	error =	request_irq(phba->pcidev->irq, lpfc_intr_handler, SA_SHIRQ,
 							LPFC_DRIVER_NAME, phba);
@@ -1691,6 +1691,9 @@ out_free_irq:
 	free_irq(phba->pcidev->irq, phba);
 out_free_sysfs_attr:
 	lpfc_free_sysfs_attr(phba);
+out_remove_host:
+	fc_remove_host(phba->host);
+	scsi_remove_host(phba->host);
 out_kthread_stop:
 	kthread_stop(phba->worker_thread);
 out_free_iocbq:
@@ -1712,12 +1715,14 @@ out_iounmap_slim:
 out_idr_remove:
 	idr_remove(&lpfc_hba_index, phba->brd_no);
 out_put_host:
+	phba->host = NULL;
 	scsi_host_put(host);
 out_release_regions:
 	pci_release_regions(pdev);
 out_disable_device:
 	pci_disable_device(pdev);
 out:
+	pci_set_drvdata(pdev, NULL);
 	return error;
 }
 
@@ -1725,9 +1730,14 @@ static void __devexit
 lpfc_pci_remove_one(struct pci_dev *pdev)
 {
 	struct Scsi_Host   *host = pci_get_drvdata(pdev);
-	struct lpfc_hba    *phba = (struct lpfc_hba *)host->hostdata;
+	struct lpfc_hba    *phba;
 	unsigned long iflag;
 
+	if (host == NULL)
+		return;
+
+	phba = (struct lpfc_hba *)host->hostdata;
+
 	lpfc_free_sysfs_attr(phba);
 
 	spin_lock_irqsave(phba->host->host_lock, iflag);
#1 lore raw

drivers/scsi/lpfc/lpfc_init.c static void __devexit · line 1739

Quoted 12 lines · James Smart
drivers/scsi/lpfc/lpfc_init.c +5 -1
@@ -1725,9 +1730,14 @@ static void __devexit
 lpfc_pci_remove_one(struct pci_dev *pdev)
 {
 	struct Scsi_Host   *host = pci_get_drvdata(pdev);
-	struct lpfc_hba    *phba = (struct lpfc_hba *)host->hostdata;
+	struct lpfc_hba    *phba;
 	unsigned long iflag;
 
+	if (host == NULL)
+		return;
+
+	phba = (struct lpfc_hba *)host->hostdata;

If this ever happen there's something really badly wrong in lpfc_pci_probe_one, so please don't put this check in.

#2 lore raw

Ok - so what's going on here is that the pci subsystem treated any positive (not just zero) return value as success. We returned error codes, but not negative error codes. Thus, the pci subsystem was calling our remove function even though we returned an error status in our probe function.

the updated patch will be posted shortly.

-- james

Quoted 17 lines · Christoph Hellwig

drivers/scsi/lpfc/lpfc_init.c static void __devexit · line 1739

Quoted 12 lines · James Smart
drivers/scsi/lpfc/lpfc_init.c +5 -1
@@ -1725,9 +1730,14 @@ static void __devexit
 lpfc_pci_remove_one(struct pci_dev *pdev)
 {
 	struct Scsi_Host   *host = pci_get_drvdata(pdev);
-	struct lpfc_hba    *phba = (struct lpfc_hba *)host->hostdata;
+	struct lpfc_hba    *phba;
 	unsigned long iflag;
 
+	if (host == NULL)
+		return;
+
+	phba = (struct lpfc_hba *)host->hostdata;

If this ever happen there's something really badly wrong in lpfc_pci_probe_one, so please don't put this check in.