diff options
Diffstat (limited to 'drivers/scsi/mpi3mr/mpi3mr_os.c')
| -rw-r--r-- | drivers/scsi/mpi3mr/mpi3mr_os.c | 24 | 
1 files changed, 24 insertions, 0 deletions
diff --git a/drivers/scsi/mpi3mr/mpi3mr_os.c b/drivers/scsi/mpi3mr/mpi3mr_os.c index a794cc8a1c0b..6d55698ea4d1 100644 --- a/drivers/scsi/mpi3mr/mpi3mr_os.c +++ b/drivers/scsi/mpi3mr/mpi3mr_os.c @@ -5078,6 +5078,8 @@ static void mpi3mr_remove(struct pci_dev *pdev)  	struct workqueue_struct	*wq;  	unsigned long flags;  	struct mpi3mr_tgt_dev *tgtdev, *tgtdev_next; +	struct mpi3mr_hba_port *port, *hba_port_next; +	struct mpi3mr_sas_node *sas_expander, *sas_expander_next;  	if (!shost)  		return; @@ -5117,6 +5119,28 @@ static void mpi3mr_remove(struct pci_dev *pdev)  	mpi3mr_free_mem(mrioc);  	mpi3mr_cleanup_resources(mrioc); +	spin_lock_irqsave(&mrioc->sas_node_lock, flags); +	list_for_each_entry_safe_reverse(sas_expander, sas_expander_next, +	    &mrioc->sas_expander_list, list) { +		spin_unlock_irqrestore(&mrioc->sas_node_lock, flags); +		mpi3mr_expander_node_remove(mrioc, sas_expander); +		spin_lock_irqsave(&mrioc->sas_node_lock, flags); +	} +	list_for_each_entry_safe(port, hba_port_next, &mrioc->hba_port_table_list, list) { +		ioc_info(mrioc, +		    "removing hba_port entry: %p port: %d from hba_port list\n", +		    port, port->port_id); +		list_del(&port->list); +		kfree(port); +	} +	spin_unlock_irqrestore(&mrioc->sas_node_lock, flags); + +	if (mrioc->sas_hba.num_phys) { +		kfree(mrioc->sas_hba.phy); +		mrioc->sas_hba.phy = NULL; +		mrioc->sas_hba.num_phys = 0; +	} +  	spin_lock(&mrioc_list_lock);  	list_del(&mrioc->list);  	spin_unlock(&mrioc_list_lock);  | 
