summaryrefslogtreecommitdiffstats
path: root/drivers/scsi/lpfc/lpfc_init.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/lpfc/lpfc_init.c')
-rw-r--r--drivers/scsi/lpfc/lpfc_init.c516
1 files changed, 247 insertions, 269 deletions
diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c
index dcf6106..dcb4ba0 100644
--- a/drivers/scsi/lpfc/lpfc_init.c
+++ b/drivers/scsi/lpfc/lpfc_init.c
@@ -1,7 +1,7 @@
/*******************************************************************
* This file is part of the Emulex Linux Device Driver for *
* Fibre Channel Host Bus Adapters. *
- * Copyright (C) 2004-2006 Emulex. All rights reserved. *
+ * Copyright (C) 2004-2007 Emulex. All rights reserved. *
* EMULEX and SLI are trademarks of Emulex. *
* www.emulex.com *
* Portions Copyright (C) 2004-2005 Christoph Hellwig *
@@ -386,12 +386,12 @@ lpfc_config_port_post(struct lpfc_hba * phba)
* Setup the ring 0 (els) timeout handler
*/
timeout = phba->fc_ratov << 1;
- phba->els_tmofunc.expires = jiffies + HZ * timeout;
- add_timer(&phba->els_tmofunc);
+ mod_timer(&phba->els_tmofunc, jiffies + HZ * timeout);
lpfc_init_link(phba, pmb, phba->cfg_topology, phba->cfg_link_speed);
pmb->mbox_cmpl = lpfc_sli_def_mbox_cmpl;
rc = lpfc_sli_issue_mbox(phba, pmb, MBX_NOWAIT);
+ lpfc_set_loopback_flag(phba);
if (rc != MBX_SUCCESS) {
lpfc_printf_log(phba,
KERN_ERR,
@@ -418,33 +418,6 @@ lpfc_config_port_post(struct lpfc_hba * phba)
return (0);
}
-static int
-lpfc_discovery_wait(struct lpfc_hba *phba)
-{
- int i = 0;
-
- while ((phba->hba_state != LPFC_HBA_READY) ||
- (phba->num_disc_nodes) || (phba->fc_prli_sent) ||
- ((phba->fc_map_cnt == 0) && (i<2)) ||
- (phba->sli.sli_flag & LPFC_SLI_MBOX_ACTIVE)) {
- /* Check every second for 30 retries. */
- i++;
- if (i > 30) {
- return -ETIMEDOUT;
- }
- if ((i >= 15) && (phba->hba_state <= LPFC_LINK_DOWN)) {
- /* The link is down. Set linkdown timeout */
- return -ETIMEDOUT;
- }
-
- /* Delay for 1 second to give discovery time to complete. */
- msleep(1000);
-
- }
-
- return 0;
-}
-
/************************************************************************/
/* */
/* lpfc_hba_down_prep */
@@ -550,12 +523,15 @@ lpfc_handle_eratt(struct lpfc_hba * phba)
* There was a firmware error. Take the hba offline and then
* attempt to restart it.
*/
+ lpfc_offline_prep(phba);
lpfc_offline(phba);
lpfc_sli_brdrestart(phba);
if (lpfc_online(phba) == 0) { /* Initialize the HBA */
mod_timer(&phba->fc_estabtmo, jiffies + HZ * 60);
+ lpfc_unblock_mgmt_io(phba);
return;
}
+ lpfc_unblock_mgmt_io(phba);
} else {
/* The if clause above forces this code path when the status
* failure is a value other than FFER6. Do not call the offline
@@ -573,7 +549,9 @@ lpfc_handle_eratt(struct lpfc_hba * phba)
SCSI_NL_VID_TYPE_PCI | PCI_VENDOR_ID_EMULEX);
psli->sli_flag &= ~LPFC_SLI2_ACTIVE;
+ lpfc_offline_prep(phba);
lpfc_offline(phba);
+ lpfc_unblock_mgmt_io(phba);
phba->hba_state = LPFC_HBA_ERROR;
lpfc_hba_down_post(phba);
}
@@ -633,7 +611,7 @@ lpfc_handle_latt_free_mbuf:
lpfc_handle_latt_free_mp:
kfree(mp);
lpfc_handle_latt_free_pmb:
- kfree(pmb);
+ mempool_free(pmb, phba->mbox_mem_pool);
lpfc_handle_latt_err_exit:
/* Enable Link attention interrupts */
spin_lock_irq(phba->host->host_lock);
@@ -925,6 +903,24 @@ lpfc_get_hba_model_desc(struct lpfc_hba * phba, uint8_t * mdp, uint8_t * descp)
m = (typeof(m)){"LPe11000-S", max_speed,
"PCIe"};
break;
+ case PCI_DEVICE_ID_SAT:
+ m = (typeof(m)){"LPe12000", max_speed, "PCIe"};
+ break;
+ case PCI_DEVICE_ID_SAT_MID:
+ m = (typeof(m)){"LPe1250", max_speed, "PCIe"};
+ break;
+ case PCI_DEVICE_ID_SAT_SMB:
+ m = (typeof(m)){"LPe121", max_speed, "PCIe"};
+ break;
+ case PCI_DEVICE_ID_SAT_DCSP:
+ m = (typeof(m)){"LPe12002-SP", max_speed, "PCIe"};
+ break;
+ case PCI_DEVICE_ID_SAT_SCSP:
+ m = (typeof(m)){"LPe12000-SP", max_speed, "PCIe"};
+ break;
+ case PCI_DEVICE_ID_SAT_S:
+ m = (typeof(m)){"LPe12000-S", max_speed, "PCIe"};
+ break;
default:
m = (typeof(m)){ NULL };
break;
@@ -1174,69 +1170,17 @@ lpfc_hba_init(struct lpfc_hba *phba, uint32_t *hbainit)
}
static void
-lpfc_cleanup(struct lpfc_hba * phba, uint32_t save_bind)
+lpfc_cleanup(struct lpfc_hba * phba)
{
struct lpfc_nodelist *ndlp, *next_ndlp;
/* clean up phba - lpfc specific */
lpfc_can_disctmo(phba);
- list_for_each_entry_safe(ndlp, next_ndlp, &phba->fc_nlpunmap_list,
- nlp_listp) {
- lpfc_nlp_remove(phba, ndlp);
- }
+ list_for_each_entry_safe(ndlp, next_ndlp, &phba->fc_nodes, nlp_listp)
+ lpfc_nlp_put(ndlp);
- list_for_each_entry_safe(ndlp, next_ndlp, &phba->fc_nlpmap_list,
- nlp_listp) {
- lpfc_nlp_remove(phba, ndlp);
- }
-
- list_for_each_entry_safe(ndlp, next_ndlp, &phba->fc_unused_list,
- nlp_listp) {
- lpfc_nlp_list(phba, ndlp, NLP_NO_LIST);
- }
-
- list_for_each_entry_safe(ndlp, next_ndlp, &phba->fc_plogi_list,
- nlp_listp) {
- lpfc_nlp_remove(phba, ndlp);
- }
-
- list_for_each_entry_safe(ndlp, next_ndlp, &phba->fc_adisc_list,
- nlp_listp) {
- lpfc_nlp_remove(phba, ndlp);
- }
-
- list_for_each_entry_safe(ndlp, next_ndlp, &phba->fc_reglogin_list,
- nlp_listp) {
- lpfc_nlp_remove(phba, ndlp);
- }
+ INIT_LIST_HEAD(&phba->fc_nodes);
- list_for_each_entry_safe(ndlp, next_ndlp, &phba->fc_prli_list,
- nlp_listp) {
- lpfc_nlp_remove(phba, ndlp);
- }
-
- list_for_each_entry_safe(ndlp, next_ndlp, &phba->fc_npr_list,
- nlp_listp) {
- lpfc_nlp_remove(phba, ndlp);
- }
-
- INIT_LIST_HEAD(&phba->fc_nlpmap_list);
- INIT_LIST_HEAD(&phba->fc_nlpunmap_list);
- INIT_LIST_HEAD(&phba->fc_unused_list);
- INIT_LIST_HEAD(&phba->fc_plogi_list);
- INIT_LIST_HEAD(&phba->fc_adisc_list);
- INIT_LIST_HEAD(&phba->fc_reglogin_list);
- INIT_LIST_HEAD(&phba->fc_prli_list);
- INIT_LIST_HEAD(&phba->fc_npr_list);
-
- phba->fc_map_cnt = 0;
- phba->fc_unmap_cnt = 0;
- phba->fc_plogi_cnt = 0;
- phba->fc_adisc_cnt = 0;
- phba->fc_reglogin_cnt = 0;
- phba->fc_prli_cnt = 0;
- phba->fc_npr_cnt = 0;
- phba->fc_unused_cnt= 0;
return;
}
@@ -1262,21 +1206,6 @@ lpfc_stop_timer(struct lpfc_hba * phba)
{
struct lpfc_sli *psli = &phba->sli;
- /* Instead of a timer, this has been converted to a
- * deferred procedding list.
- */
- while (!list_empty(&phba->freebufList)) {
-
- struct lpfc_dmabuf *mp = NULL;
-
- list_remove_head((&phba->freebufList), mp,
- struct lpfc_dmabuf, list);
- if (mp) {
- lpfc_mbuf_free(phba, mp->virt, mp->phys);
- kfree(mp);
- }
- }
-
del_timer_sync(&phba->fcp_poll_timer);
del_timer_sync(&phba->fc_estabtmo);
del_timer_sync(&phba->fc_disctmo);
@@ -1302,60 +1231,76 @@ lpfc_online(struct lpfc_hba * phba)
"%d:0458 Bring Adapter online\n",
phba->brd_no);
- if (!lpfc_sli_queue_setup(phba))
+ lpfc_block_mgmt_io(phba);
+
+ if (!lpfc_sli_queue_setup(phba)) {
+ lpfc_unblock_mgmt_io(phba);
return 1;
+ }
- if (lpfc_sli_hba_setup(phba)) /* Initialize the HBA */
+ if (lpfc_sli_hba_setup(phba)) { /* Initialize the HBA */
+ lpfc_unblock_mgmt_io(phba);
return 1;
+ }
spin_lock_irq(phba->host->host_lock);
phba->fc_flag &= ~FC_OFFLINE_MODE;
spin_unlock_irq(phba->host->host_lock);
+ lpfc_unblock_mgmt_io(phba);
return 0;
}
-int
-lpfc_offline(struct lpfc_hba * phba)
+void
+lpfc_block_mgmt_io(struct lpfc_hba * phba)
{
- struct lpfc_sli_ring *pring;
- struct lpfc_sli *psli;
unsigned long iflag;
- int i;
- int cnt = 0;
- if (!phba)
- return 0;
+ spin_lock_irqsave(phba->host->host_lock, iflag);
+ phba->fc_flag |= FC_BLOCK_MGMT_IO;
+ spin_unlock_irqrestore(phba->host->host_lock, iflag);
+}
+
+void
+lpfc_unblock_mgmt_io(struct lpfc_hba * phba)
+{
+ unsigned long iflag;
+
+ spin_lock_irqsave(phba->host->host_lock, iflag);
+ phba->fc_flag &= ~FC_BLOCK_MGMT_IO;
+ spin_unlock_irqrestore(phba->host->host_lock, iflag);
+}
+
+void
+lpfc_offline_prep(struct lpfc_hba * phba)
+{
+ struct lpfc_nodelist *ndlp, *next_ndlp;
if (phba->fc_flag & FC_OFFLINE_MODE)
- return 0;
+ return;
- psli = &phba->sli;
+ lpfc_block_mgmt_io(phba);
lpfc_linkdown(phba);
+
+ /* Issue an unreg_login to all nodes */
+ list_for_each_entry_safe(ndlp, next_ndlp, &phba->fc_nodes, nlp_listp)
+ if (ndlp->nlp_state != NLP_STE_UNUSED_NODE)
+ lpfc_unreg_rpi(phba, ndlp);
+
lpfc_sli_flush_mbox_queue(phba);
+}
- for (i = 0; i < psli->num_rings; i++) {
- pring = &psli->ring[i];
- /* The linkdown event takes 30 seconds to timeout. */
- while (pring->txcmplq_cnt) {
- mdelay(10);
- if (cnt++ > 3000) {
- lpfc_printf_log(phba,
- KERN_WARNING, LOG_INIT,
- "%d:0466 Outstanding IO when "
- "bringing Adapter offline\n",
- phba->brd_no);
- break;
- }
- }
- }
+void
+lpfc_offline(struct lpfc_hba * phba)
+{
+ unsigned long iflag;
+ if (phba->fc_flag & FC_OFFLINE_MODE)
+ return;
/* stop all timers associated with this hba */
lpfc_stop_timer(phba);
- phba->work_hba_events = 0;
- phba->work_ha = 0;
lpfc_printf_log(phba,
KERN_WARNING,
@@ -1366,11 +1311,12 @@ lpfc_offline(struct lpfc_hba * phba)
/* Bring down the SLI Layer and cleanup. The HBA is offline
now. */
lpfc_sli_hba_down(phba);
- lpfc_cleanup(phba, 1);
+ lpfc_cleanup(phba);
spin_lock_irqsave(phba->host->host_lock, iflag);
+ phba->work_hba_events = 0;
+ phba->work_ha = 0;
phba->fc_flag |= FC_OFFLINE_MODE;
spin_unlock_irqrestore(phba->host->host_lock, iflag);
- return 0;
}
/******************************************************************************
@@ -1407,6 +1353,156 @@ lpfc_scsi_free(struct lpfc_hba * phba)
return 0;
}
+void lpfc_remove_device(struct lpfc_hba *phba)
+{
+ unsigned long iflag;
+
+ lpfc_free_sysfs_attr(phba);
+
+ spin_lock_irqsave(phba->host->host_lock, iflag);
+ phba->fc_flag |= FC_UNLOADING;
+
+ spin_unlock_irqrestore(phba->host->host_lock, iflag);
+
+ fc_remove_host(phba->host);
+ scsi_remove_host(phba->host);
+
+ kthread_stop(phba->worker_thread);
+
+ /*
+ * Bring down the SLI Layer. This step disable all interrupts,
+ * clears the rings, discards all mailbox commands, and resets
+ * the HBA.
+ */
+ lpfc_sli_hba_down(phba);
+ lpfc_sli_brdrestart(phba);
+
+ /* Release the irq reservation */
+ free_irq(phba->pcidev->irq, phba);
+ pci_disable_msi(phba->pcidev);
+
+ lpfc_cleanup(phba);
+ lpfc_stop_timer(phba);
+ phba->work_hba_events = 0;
+
+ /*
+ * Call scsi_free before mem_free since scsi bufs are released to their
+ * corresponding pools here.
+ */
+ lpfc_scsi_free(phba);
+ lpfc_mem_free(phba);
+
+ /* Free resources associated with SLI2 interface */
+ dma_free_coherent(&phba->pcidev->dev, SLI2_SLIM_SIZE,
+ phba->slim2p, phba->slim2p_mapping);
+
+ /* unmap adapter SLIM and Control Registers */
+ iounmap(phba->ctrl_regs_memmap_p);
+ iounmap(phba->slim_memmap_p);
+
+ pci_release_regions(phba->pcidev);
+ pci_disable_device(phba->pcidev);
+
+ idr_remove(&lpfc_hba_index, phba->brd_no);
+ scsi_host_put(phba->host);
+}
+
+void lpfc_scan_start(struct Scsi_Host *host)
+{
+ struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata;
+
+ if (lpfc_alloc_sysfs_attr(phba))
+ goto error;
+
+ phba->MBslimaddr = phba->slim_memmap_p;
+ phba->HAregaddr = phba->ctrl_regs_memmap_p + HA_REG_OFFSET;
+ phba->CAregaddr = phba->ctrl_regs_memmap_p + CA_REG_OFFSET;
+ phba->HSregaddr = phba->ctrl_regs_memmap_p + HS_REG_OFFSET;
+ phba->HCregaddr = phba->ctrl_regs_memmap_p + HC_REG_OFFSET;
+
+ if (lpfc_sli_hba_setup(phba))
+ goto error;
+
+ /*
+ * hba setup may have changed the hba_queue_depth so we need to adjust
+ * the value of can_queue.
+ */
+ host->can_queue = phba->cfg_hba_queue_depth - 10;
+ return;
+
+error:
+ lpfc_remove_device(phba);
+}
+
+int lpfc_scan_finished(struct Scsi_Host *shost, unsigned long time)
+{
+ struct lpfc_hba *phba = (struct lpfc_hba *)shost->hostdata;
+
+ if (!phba->host)
+ return 1;
+ if (time >= 30 * HZ)
+ goto finished;
+
+ if (phba->hba_state != LPFC_HBA_READY)
+ return 0;
+ if (phba->num_disc_nodes || phba->fc_prli_sent)
+ return 0;
+ if ((phba->fc_map_cnt == 0) && (time < 2 * HZ))
+ return 0;
+ if (phba->sli.sli_flag & LPFC_SLI_MBOX_ACTIVE)
+ return 0;
+ if ((phba->hba_state > LPFC_LINK_DOWN) || (time < 15 * HZ))
+ return 0;
+
+finished:
+ if (phba->cfg_poll & DISABLE_FCP_RING_INT) {
+ spin_lock_irq(shost->host_lock);
+ lpfc_poll_start_timer(phba);
+ spin_unlock_irq(shost->host_lock);
+ }
+
+ /*
+ * set fixed host attributes
+ * Must done after lpfc_sli_hba_setup()
+ */
+
+ fc_host_node_name(shost) = wwn_to_u64(phba->fc_nodename.u.wwn);
+ fc_host_port_name(shost) = wwn_to_u64(phba->fc_portname.u.wwn);
+ fc_host_supported_classes(shost) = FC_COS_CLASS3;
+
+ memset(fc_host_supported_fc4s(shost), 0,
+ sizeof(fc_host_supported_fc4s(shost)));
+ fc_host_supported_fc4s(shost)[2] = 1;
+ fc_host_supported_fc4s(shost)[7] = 1;
+
+ lpfc_get_hba_sym_node_name(phba, fc_host_symbolic_name(shost));
+
+ fc_host_supported_speeds(shost) = 0;
+ if (phba->lmt & LMT_10Gb)
+ fc_host_supported_speeds(shost) |= FC_PORTSPEED_10GBIT;
+ if (phba->lmt & LMT_4Gb)
+ fc_host_supported_speeds(shost) |= FC_PORTSPEED_4GBIT;
+ if (phba->lmt & LMT_2Gb)
+ fc_host_supported_speeds(shost) |= FC_PORTSPEED_2GBIT;
+ if (phba->lmt & LMT_1Gb)
+ fc_host_supported_speeds(shost) |= FC_PORTSPEED_1GBIT;
+
+ fc_host_maxframe_size(shost) =
+ ((((uint32_t) phba->fc_sparam.cmn.bbRcvSizeMsb & 0x0F) << 8) |
+ (uint32_t) phba->fc_sparam.cmn.bbRcvSizeLsb);
+
+ /* This value is also unchanging */
+ memset(fc_host_active_fc4s(shost), 0,
+ sizeof(fc_host_active_fc4s(shost)));
+ fc_host_active_fc4s(shost)[2] = 1;
+ fc_host_active_fc4s(shost)[7] = 1;
+
+ spin_lock_irq(shost->host_lock);
+ phba->fc_flag &= ~FC_LOADING;
+ spin_unlock_irq(shost->host_lock);
+
+ return 1;
+}
static int __devinit
lpfc_pci_probe_one(struct pci_dev *pdev, const struct pci_device_id *pid)
@@ -1445,9 +1541,6 @@ lpfc_pci_probe_one(struct pci_dev *pdev, const struct pci_device_id *pid)
goto out_put_host;
host->unique_id = phba->brd_no;
- INIT_LIST_HEAD(&phba->ctrspbuflist);
- INIT_LIST_HEAD(&phba->rnidrspbuflist);
- INIT_LIST_HEAD(&phba->freebufList);
/* Initialize timers used by driver */
init_timer(&phba->fc_estabtmo);
@@ -1482,16 +1575,7 @@ lpfc_pci_probe_one(struct pci_dev *pdev, const struct pci_device_id *pid)
host->max_lun = phba->cfg_max_luns;
host->this_id = -1;
- /* Initialize all internally managed lists. */
- INIT_LIST_HEAD(&phba->fc_nlpmap_list);
- INIT_LIST_HEAD(&phba->fc_nlpunmap_list);
- INIT_LIST_HEAD(&phba->fc_unused_list);
- INIT_LIST_HEAD(&phba->fc_plogi_list);
- INIT_LIST_HEAD(&phba->fc_adisc_list);
- INIT_LIST_HEAD(&phba->fc_reglogin_list);
- INIT_LIST_HEAD(&phba->fc_prli_list);
- INIT_LIST_HEAD(&phba->fc_npr_list);
-
+ INIT_LIST_HEAD(&phba->fc_nodes);
pci_set_master(pdev);
retval = pci_set_mwi(pdev);
@@ -1609,13 +1693,6 @@ lpfc_pci_probe_one(struct pci_dev *pdev, const struct pci_device_id *pid)
host->transportt = lpfc_transport_template;
pci_set_drvdata(pdev, host);
- error = scsi_add_host(host, &pdev->dev);
- if (error)
- goto out_kthread_stop;
-
- error = lpfc_alloc_sysfs_attr(phba);
- if (error)
- goto out_remove_host;
if (phba->cfg_use_msi) {
error = pci_enable_msi(phba->pcidev);
@@ -1631,73 +1708,15 @@ lpfc_pci_probe_one(struct pci_dev *pdev, const struct pci_device_id *pid)
lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
"%d:0451 Enable interrupt handler failed\n",
phba->brd_no);
- goto out_free_sysfs_attr;
+ goto out_kthread_stop;
}
- phba->MBslimaddr = phba->slim_memmap_p;
- phba->HAregaddr = phba->ctrl_regs_memmap_p + HA_REG_OFFSET;
- phba->CAregaddr = phba->ctrl_regs_memmap_p + CA_REG_OFFSET;
- phba->HSregaddr = phba->ctrl_regs_memmap_p + HS_REG_OFFSET;
- phba->HCregaddr = phba->ctrl_regs_memmap_p + HC_REG_OFFSET;
- error = lpfc_sli_hba_setup(phba);
- if (error) {
- error = -ENODEV;
+ error = scsi_add_host(host, &pdev->dev);
+ if (error)
goto out_free_irq;
- }
-
- /*
- * hba setup may have changed the hba_queue_depth so we need to adjust
- * the value of can_queue.
- */
- host->can_queue = phba->cfg_hba_queue_depth - 10;
-
- lpfc_discovery_wait(phba);
- if (phba->cfg_poll & DISABLE_FCP_RING_INT) {
- spin_lock_irq(phba->host->host_lock);
- lpfc_poll_start_timer(phba);
- spin_unlock_irq(phba->host->host_lock);
- }
+ scsi_scan_host(host);
- /*
- * set fixed host attributes
- * Must done after lpfc_sli_hba_setup()
- */
-
- fc_host_node_name(host) = wwn_to_u64(phba->fc_nodename.u.wwn);
- fc_host_port_name(host) = wwn_to_u64(phba->fc_portname.u.wwn);
- fc_host_supported_classes(host) = FC_COS_CLASS3;
-
- memset(fc_host_supported_fc4s(host), 0,
- sizeof(fc_host_supported_fc4s(host)));
- fc_host_supported_fc4s(host)[2] = 1;
- fc_host_supported_fc4s(host)[7] = 1;
-
- lpfc_get_hba_sym_node_name(phba, fc_host_symbolic_name(host));
-
- fc_host_supported_speeds(host) = 0;
- if (phba->lmt & LMT_10Gb)
- fc_host_supported_speeds(host) |= FC_PORTSPEED_10GBIT;
- if (phba->lmt & LMT_4Gb)
- fc_host_supported_speeds(host) |= FC_PORTSPEED_4GBIT;
- if (phba->lmt & LMT_2Gb)
- fc_host_supported_speeds(host) |= FC_PORTSPEED_2GBIT;
- if (phba->lmt & LMT_1Gb)
- fc_host_supported_speeds(host) |= FC_PORTSPEED_1GBIT;
-
- fc_host_maxframe_size(host) =
- ((((uint32_t) phba->fc_sparam.cmn.bbRcvSizeMsb & 0x0F) << 8) |
- (uint32_t) phba->fc_sparam.cmn.bbRcvSizeLsb);
-
- /* This value is also unchanging */
- memset(fc_host_active_fc4s(host), 0,
- sizeof(fc_host_active_fc4s(host)));
- fc_host_active_fc4s(host)[2] = 1;
- fc_host_active_fc4s(host)[7] = 1;
-
- spin_lock_irq(phba->host->host_lock);
- phba->fc_flag &= ~FC_LOADING;
- spin_unlock_irq(phba->host->host_lock);
return 0;
out_free_irq:
@@ -1705,11 +1724,6 @@ out_free_irq:
phba->work_hba_events = 0;
free_irq(phba->pcidev->irq, phba);
pci_disable_msi(phba->pcidev);
-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:
@@ -1747,56 +1761,8 @@ 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;
- unsigned long iflag;
-
- lpfc_free_sysfs_attr(phba);
-
- spin_lock_irqsave(phba->host->host_lock, iflag);
- phba->fc_flag |= FC_UNLOADING;
-
- spin_unlock_irqrestore(phba->host->host_lock, iflag);
- fc_remove_host(phba->host);
- scsi_remove_host(phba->host);
-
- kthread_stop(phba->worker_thread);
-
- /*
- * Bring down the SLI Layer. This step disable all interrupts,
- * clears the rings, discards all mailbox commands, and resets
- * the HBA.
- */
- lpfc_sli_hba_down(phba);
- lpfc_sli_brdrestart(phba);
-
- /* Release the irq reservation */
- free_irq(phba->pcidev->irq, phba);
- pci_disable_msi(phba->pcidev);
-
- lpfc_cleanup(phba, 0);
- lpfc_stop_timer(phba);
- phba->work_hba_events = 0;
-
- /*
- * Call scsi_free before mem_free since scsi bufs are released to their
- * corresponding pools here.
- */
- lpfc_scsi_free(phba);
- lpfc_mem_free(phba);
-
- /* Free resources associated with SLI2 interface */
- dma_free_coherent(&pdev->dev, SLI2_SLIM_SIZE,
- phba->slim2p, phba->slim2p_mapping);
-
- /* unmap adapter SLIM and Control Registers */
- iounmap(phba->ctrl_regs_memmap_p);
- iounmap(phba->slim_memmap_p);
-
- pci_release_regions(phba->pcidev);
- pci_disable_device(phba->pcidev);
-
- idr_remove(&lpfc_hba_index, phba->brd_no);
- scsi_host_put(phba->host);
+ lpfc_remove_device(phba);
pci_set_drvdata(pdev, NULL);
}
@@ -1941,6 +1907,18 @@ static struct pci_device_id lpfc_id_table[] = {
PCI_ANY_ID, PCI_ANY_ID, },
{PCI_VENDOR_ID_EMULEX, PCI_DEVICE_ID_LPE11000S,
PCI_ANY_ID, PCI_ANY_ID, },
+ {PCI_VENDOR_ID_EMULEX, PCI_DEVICE_ID_SAT,
+ PCI_ANY_ID, PCI_ANY_ID, },
+ {PCI_VENDOR_ID_EMULEX, PCI_DEVICE_ID_SAT_MID,
+ PCI_ANY_ID, PCI_ANY_ID, },
+ {PCI_VENDOR_ID_EMULEX, PCI_DEVICE_ID_SAT_SMB,
+ PCI_ANY_ID, PCI_ANY_ID, },
+ {PCI_VENDOR_ID_EMULEX, PCI_DEVICE_ID_SAT_DCSP,
+ PCI_ANY_ID, PCI_ANY_ID, },
+ {PCI_VENDOR_ID_EMULEX, PCI_DEVICE_ID_SAT_SCSP,
+ PCI_ANY_ID, PCI_ANY_ID, },
+ {PCI_VENDOR_ID_EMULEX, PCI_DEVICE_ID_SAT_S,
+ PCI_ANY_ID, PCI_ANY_ID, },
{ 0 }
};
OpenPOWER on IntegriCloud