summaryrefslogtreecommitdiffstats
path: root/drivers/scsi/lpfc/lpfc_hbadisc.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/lpfc/lpfc_hbadisc.c')
-rw-r--r--drivers/scsi/lpfc/lpfc_hbadisc.c1245
1 files changed, 680 insertions, 565 deletions
diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c
index 61caa8d379e2..dee875ee6165 100644
--- a/drivers/scsi/lpfc/lpfc_hbadisc.c
+++ b/drivers/scsi/lpfc/lpfc_hbadisc.c
@@ -54,7 +54,7 @@ static uint8_t lpfcAlpaArray[] = {
0x10, 0x0F, 0x08, 0x04, 0x02, 0x01
};
-static void lpfc_disc_timeout_handler(struct lpfc_hba *);
+static void lpfc_disc_timeout_handler(struct lpfc_vport *);
void
lpfc_terminate_rport_io(struct fc_rport *rport)
@@ -74,14 +74,12 @@ lpfc_terminate_rport_io(struct fc_rport *rport)
return;
}
- phba = ndlp->nlp_phba;
+ phba = ndlp->vport->phba;
- spin_lock_irq(phba->host->host_lock);
if (ndlp->nlp_sid != NLP_NO_SID) {
lpfc_sli_abort_iocb(phba, &phba->sli.ring[phba->sli.fcp_ring],
ndlp->nlp_sid, 0, 0, LPFC_CTX_TGT);
}
- spin_unlock_irq(phba->host->host_lock);
return;
}
@@ -97,6 +95,7 @@ lpfc_dev_loss_tmo_callbk(struct fc_rport *rport)
uint8_t *name;
int warn_on = 0;
struct lpfc_hba *phba;
+ struct lpfc_vport *vport;
rdata = rport->dd_data;
ndlp = rdata->pnode;
@@ -113,9 +112,8 @@ lpfc_dev_loss_tmo_callbk(struct fc_rport *rport)
return;
name = (uint8_t *)&ndlp->nlp_portname;
- phba = ndlp->nlp_phba;
-
- spin_lock_irq(phba->host->host_lock);
+ vport = ndlp->vport;
+ phba = vport->phba;
if (ndlp->nlp_sid != NLP_NO_SID) {
warn_on = 1;
@@ -123,11 +121,9 @@ lpfc_dev_loss_tmo_callbk(struct fc_rport *rport)
lpfc_sli_abort_iocb(phba, &phba->sli.ring[phba->sli.fcp_ring],
ndlp->nlp_sid, 0, 0, LPFC_CTX_TGT);
}
- if (phba->fc_flag & FC_UNLOADING)
+ if (vport->load_flag & FC_UNLOADING)
warn_on = 0;
- spin_unlock_irq(phba->host->host_lock);
-
if (warn_on) {
lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY,
"%d:0203 Devloss timeout on "
@@ -150,11 +146,11 @@ lpfc_dev_loss_tmo_callbk(struct fc_rport *rport)
ndlp->nlp_state, ndlp->nlp_rpi);
}
- if (!(phba->fc_flag & FC_UNLOADING) &&
+ if (!(vport->load_flag & FC_UNLOADING) &&
!(ndlp->nlp_flag & NLP_DELAY_TMO) &&
!(ndlp->nlp_flag & NLP_NPR_2B_DISC) &&
(ndlp->nlp_state != NLP_STE_UNMAPPED_NODE))
- lpfc_disc_state_machine(phba, ndlp, NULL, NLP_EVT_DEVICE_RM);
+ lpfc_disc_state_machine(vport, ndlp, NULL, NLP_EVT_DEVICE_RM);
else {
rdata->pnode = NULL;
ndlp->rport = NULL;
@@ -166,33 +162,33 @@ lpfc_dev_loss_tmo_callbk(struct fc_rport *rport)
}
static void
-lpfc_work_list_done(struct lpfc_hba * phba)
+lpfc_work_list_done(struct lpfc_hba *phba)
{
struct lpfc_work_evt *evtp = NULL;
struct lpfc_nodelist *ndlp;
int free_evt;
- spin_lock_irq(phba->host->host_lock);
- while(!list_empty(&phba->work_list)) {
+ spin_lock_irq(&phba->hbalock);
+ while (!list_empty(&phba->work_list)) {
list_remove_head((&phba->work_list), evtp, typeof(*evtp),
evt_listp);
- spin_unlock_irq(phba->host->host_lock);
+ spin_unlock_irq(&phba->hbalock);
free_evt = 1;
switch (evtp->evt) {
case LPFC_EVT_ELS_RETRY:
- ndlp = (struct lpfc_nodelist *)(evtp->evt_arg1);
+ ndlp = (struct lpfc_nodelist *) (evtp->evt_arg1);
lpfc_els_retry_delay_handler(ndlp);
free_evt = 0;
break;
case LPFC_EVT_ONLINE:
- if (phba->hba_state < LPFC_LINK_DOWN)
- *(int *)(evtp->evt_arg1) = lpfc_online(phba);
+ if (phba->link_state < LPFC_LINK_DOWN)
+ *(int *) (evtp->evt_arg1) = lpfc_online(phba);
else
- *(int *)(evtp->evt_arg1) = 0;
+ *(int *) (evtp->evt_arg1) = 0;
complete((struct completion *)(evtp->evt_arg2));
break;
case LPFC_EVT_OFFLINE_PREP:
- if (phba->hba_state >= LPFC_LINK_DOWN)
+ if (phba->link_state >= LPFC_LINK_DOWN)
lpfc_offline_prep(phba);
*(int *)(evtp->evt_arg1) = 0;
complete((struct completion *)(evtp->evt_arg2));
@@ -218,33 +214,32 @@ lpfc_work_list_done(struct lpfc_hba * phba)
case LPFC_EVT_KILL:
lpfc_offline(phba);
*(int *)(evtp->evt_arg1)
- = (phba->stopped) ? 0 : lpfc_sli_brdkill(phba);
+ = (phba->pport->stopped)
+ ? 0 : lpfc_sli_brdkill(phba);
lpfc_unblock_mgmt_io(phba);
complete((struct completion *)(evtp->evt_arg2));
break;
}
if (free_evt)
kfree(evtp);
- spin_lock_irq(phba->host->host_lock);
+ spin_lock_irq(&phba->hbalock);
}
- spin_unlock_irq(phba->host->host_lock);
+ spin_unlock_irq(&phba->hbalock);
}
static void
-lpfc_work_done(struct lpfc_hba * phba)
+lpfc_work_done(struct lpfc_hba *phba)
{
struct lpfc_sli_ring *pring;
int i;
- uint32_t ha_copy;
- uint32_t control;
- uint32_t work_hba_events;
+ uint32_t ha_copy, control, work_port_events;
+ struct lpfc_vport *vport;
- spin_lock_irq(phba->host->host_lock);
+ spin_lock_irq(&phba->hbalock);
ha_copy = phba->work_ha;
phba->work_ha = 0;
- work_hba_events=phba->work_hba_events;
- spin_unlock_irq(phba->host->host_lock);
+ spin_unlock_irq(&phba->hbalock);
if (ha_copy & HA_ERATT)
lpfc_handle_eratt(phba);
@@ -255,21 +250,25 @@ lpfc_work_done(struct lpfc_hba * phba)
if (ha_copy & HA_LATT)
lpfc_handle_latt(phba);
- if (work_hba_events & WORKER_DISC_TMO)
- lpfc_disc_timeout_handler(phba);
+ vport = phba->pport;
- if (work_hba_events & WORKER_ELS_TMO)
- lpfc_els_timeout_handler(phba);
+ work_port_events = vport->work_port_events;
- if (work_hba_events & WORKER_MBOX_TMO)
+ if (work_port_events & WORKER_DISC_TMO)
+ lpfc_disc_timeout_handler(vport);
+
+ if (work_port_events & WORKER_ELS_TMO)
+ lpfc_els_timeout_handler(vport);
+
+ if (work_port_events & WORKER_MBOX_TMO)
lpfc_mbox_timeout_handler(phba);
- if (work_hba_events & WORKER_FDMI_TMO)
- lpfc_fdmi_tmo_handler(phba);
+ if (work_port_events & WORKER_FDMI_TMO)
+ lpfc_fdmi_timeout_handler(vport);
- spin_lock_irq(phba->host->host_lock);
- phba->work_hba_events &= ~work_hba_events;
- spin_unlock_irq(phba->host->host_lock);
+ spin_lock_irq(&phba->hbalock);
+ vport->work_port_events &= ~work_port_events;
+ spin_unlock_irq(&phba->hbalock);
for (i = 0; i < phba->sli.num_rings; i++, ha_copy >>= 4) {
pring = &phba->sli.ring[i];
@@ -286,33 +285,37 @@ lpfc_work_done(struct lpfc_hba * phba)
/*
* Turn on Ring interrupts
*/
- spin_lock_irq(phba->host->host_lock);
+ spin_lock_irq(&phba->hbalock);
control = readl(phba->HCregaddr);
control |= (HC_R0INT_ENA << i);
writel(control, phba->HCregaddr);
readl(phba->HCregaddr); /* flush */
- spin_unlock_irq(phba->host->host_lock);
+ spin_unlock_irq(&phba->hbalock);
}
}
- lpfc_work_list_done (phba);
-
+ lpfc_work_list_done(phba);
}
static int
-check_work_wait_done(struct lpfc_hba *phba) {
+check_work_wait_done(struct lpfc_hba *phba)
+{
+ struct lpfc_vport *vport = phba->pport;
+ int rc = 0;
+
+
+ if (!vport)
+ return 0;
+ spin_lock_irq(&phba->hbalock);
- spin_lock_irq(phba->host->host_lock);
if (phba->work_ha ||
- phba->work_hba_events ||
+ vport->work_port_events ||
(!list_empty(&phba->work_list)) ||
- kthread_should_stop()) {
- spin_unlock_irq(phba->host->host_lock);
- return 1;
- } else {
- spin_unlock_irq(phba->host->host_lock);
- return 0;
- }
+ kthread_should_stop())
+ rc = 1;
+
+ spin_unlock_irq(&phba->hbalock);
+ return rc;
}
int
@@ -347,7 +350,7 @@ lpfc_do_work(void *p)
* embedding it in the IOCB.
*/
int
-lpfc_workq_post_event(struct lpfc_hba * phba, void *arg1, void *arg2,
+lpfc_workq_post_event(struct lpfc_hba *phba, void *arg1, void *arg2,
uint32_t evt)
{
struct lpfc_work_evt *evtp;
@@ -364,11 +367,11 @@ lpfc_workq_post_event(struct lpfc_hba * phba, void *arg1, void *arg2,
evtp->evt_arg2 = arg2;
evtp->evt = evt;
- spin_lock_irq(phba->host->host_lock);
+ spin_lock_irq(&phba->hbalock);
list_add_tail(&evtp->evt_listp, &phba->work_list);
if (phba->work_wait)
wake_up(phba->work_wait);
- spin_unlock_irq(phba->host->host_lock);
+ spin_unlock_irq(&phba->hbalock);
return 1;
}
@@ -376,75 +379,77 @@ lpfc_workq_post_event(struct lpfc_hba * phba, void *arg1, void *arg2,
int
lpfc_linkdown(struct lpfc_hba *phba)
{
- struct lpfc_sli *psli;
+ struct lpfc_vport *vport = phba->pport;
+ struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
+ struct lpfc_sli *psli;
struct lpfc_nodelist *ndlp, *next_ndlp;
LPFC_MBOXQ_t *mb;
int rc;
psli = &phba->sli;
- /* sysfs or selective reset may call this routine to clean up */
- if (phba->hba_state >= LPFC_LINK_DOWN) {
- if (phba->hba_state == LPFC_LINK_DOWN)
- return 0;
-
- spin_lock_irq(phba->host->host_lock);
- phba->hba_state = LPFC_LINK_DOWN;
- spin_unlock_irq(phba->host->host_lock);
+ if (phba->link_state == LPFC_LINK_DOWN) {
+ return 0;
}
+ spin_lock_irq(&phba->hbalock);
+ if (phba->link_state > LPFC_LINK_DOWN)
+ phba->link_state = LPFC_LINK_DOWN;
+ spin_unlock_irq(&phba->hbalock);
- fc_host_post_event(phba->host, fc_get_event_number(),
- FCH_EVT_LINKDOWN, 0);
+ fc_host_post_event(shost, fc_get_event_number(), FCH_EVT_LINKDOWN, 0);
/* Clean up any firmware default rpi's */
- if ((mb = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL))) {
+ mb = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
+ if (mb) {
lpfc_unreg_did(phba, 0xffffffff, mb);
- mb->mbox_cmpl=lpfc_sli_def_mbox_cmpl;
+ mb->mbox_cmpl = lpfc_sli_def_mbox_cmpl;
if (lpfc_sli_issue_mbox(phba, mb, (MBX_NOWAIT | MBX_STOP_IOCB))
== MBX_NOT_FINISHED) {
- mempool_free( mb, phba->mbox_mem_pool);
+ mempool_free(mb, phba->mbox_mem_pool);
}
}
/* Cleanup any outstanding RSCN activity */
- lpfc_els_flush_rscn(phba);
+ lpfc_els_flush_rscn(vport);
/* Cleanup any outstanding ELS commands */
- lpfc_els_flush_cmd(phba);
+ lpfc_els_flush_cmd(vport);
/*
* Issue a LINK DOWN event to all nodes.
*/
- list_for_each_entry_safe(ndlp, next_ndlp, &phba->fc_nodes, nlp_listp) {
- /* free any ndlp's on unused list */
+ list_for_each_entry_safe(ndlp, next_ndlp, &vport->fc_nodes, nlp_listp) {
+ /* free any ndlp's on unused state */
if (ndlp->nlp_state == NLP_STE_UNUSED_NODE)
- lpfc_drop_node(phba, ndlp);
+ lpfc_drop_node(vport, ndlp);
else /* otherwise, force node recovery. */
- rc = lpfc_disc_state_machine(phba, ndlp, NULL,
+ rc = lpfc_disc_state_machine(vport, ndlp, NULL,
NLP_EVT_DEVICE_RECOVERY);
}
/* Setup myDID for link up if we are in pt2pt mode */
- if (phba->fc_flag & FC_PT2PT) {
- phba->fc_myDID = 0;
- if ((mb = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL))) {
+ if (vport->fc_flag & FC_PT2PT) {
+ vport->fc_myDID = 0;
+ mb = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
+ if (mb) {
lpfc_config_link(phba, mb);
mb->mbox_cmpl=lpfc_sli_def_mbox_cmpl;
- if (lpfc_sli_issue_mbox
- (phba, mb, (MBX_NOWAIT | MBX_STOP_IOCB))
+ if (lpfc_sli_issue_mbox(phba, mb,
+ (MBX_NOWAIT | MBX_STOP_IOCB))
== MBX_NOT_FINISHED) {
- mempool_free( mb, phba->mbox_mem_pool);
+ mempool_free(mb, phba->mbox_mem_pool);
}
}
- spin_lock_irq(phba->host->host_lock);
- phba->fc_flag &= ~(FC_PT2PT | FC_PT2PT_PLOGI);
- spin_unlock_irq(phba->host->host_lock);
+ spin_lock_irq(shost->host_lock);
+ vport->fc_flag &= ~(FC_PT2PT | FC_PT2PT_PLOGI);
+ spin_unlock_irq(shost->host_lock);
}
- spin_lock_irq(phba->host->host_lock);
- phba->fc_flag &= ~FC_LBIT;
- spin_unlock_irq(phba->host->host_lock);
+
+ spin_lock_irq(shost->host_lock);
+ vport->fc_flag &= ~FC_LBIT;
+ spin_unlock_irq(shost->host_lock);
/* Turn off discovery timer if its running */
- lpfc_can_disctmo(phba);
+ lpfc_can_disctmo(vport);
/* Must process IOCBs on all rings to handle ABORTed I/Os */
return 0;
@@ -453,46 +458,47 @@ lpfc_linkdown(struct lpfc_hba *phba)
static int
lpfc_linkup(struct lpfc_hba *phba)
{
+ struct lpfc_vport *vport = phba->pport;
+ struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
struct lpfc_nodelist *ndlp, *next_ndlp;
- fc_host_post_event(phba->host, fc_get_event_number(),
- FCH_EVT_LINKUP, 0);
+ fc_host_post_event(shost, fc_get_event_number(), FCH_EVT_LINKUP, 0);
- spin_lock_irq(phba->host->host_lock);
- phba->hba_state = LPFC_LINK_UP;
- phba->fc_flag &= ~(FC_PT2PT | FC_PT2PT_PLOGI | FC_ABORT_DISCOVERY |
- FC_RSCN_MODE | FC_NLP_MORE | FC_RSCN_DISCOVERY);
- phba->fc_flag |= FC_NDISC_ACTIVE;
- phba->fc_ns_retry = 0;
- spin_unlock_irq(phba->host->host_lock);
+ spin_lock_irq(shost->host_lock);
+ phba->link_state = LPFC_LINK_UP;
+ vport->fc_flag &= ~(FC_PT2PT | FC_PT2PT_PLOGI | FC_ABORT_DISCOVERY |
+ FC_RSCN_MODE | FC_NLP_MORE | FC_RSCN_DISCOVERY);
+ vport->fc_flag |= FC_NDISC_ACTIVE;
+ vport->fc_ns_retry = 0;
+ spin_unlock_irq(shost->host_lock);
- if (phba->fc_flag & FC_LBIT) {
- list_for_each_entry(ndlp, &phba->fc_nodes, nlp_listp) {
+ if (vport->fc_flag & FC_LBIT) {
+ list_for_each_entry(ndlp, &vport->fc_nodes, nlp_listp) {
if (ndlp->nlp_state != NLP_STE_UNUSED_NODE) {
if (ndlp->nlp_type & NLP_FABRIC) {
/*
* On Linkup its safe to clean up the
* ndlp from Fabric connections.
*/
- lpfc_nlp_set_state(phba, ndlp,
+ lpfc_nlp_set_state(vport, ndlp,
NLP_STE_UNUSED_NODE);
} else if (!(ndlp->nlp_flag & NLP_NPR_ADISC)) {
/*
* Fail outstanding IO now since
* device is marked for PLOGI.
*/
- lpfc_unreg_rpi(phba, ndlp);
+ lpfc_unreg_rpi(vport, ndlp);
}
}
}
}
- /* free any ndlp's on unused list */
- list_for_each_entry_safe(ndlp, next_ndlp, &phba->fc_nodes,
+ /* free any ndlp's in unused state */
+ list_for_each_entry_safe(ndlp, next_ndlp, &vport->fc_nodes,
nlp_listp) {
if (ndlp->nlp_state == NLP_STE_UNUSED_NODE)
- lpfc_drop_node(phba, ndlp);
+ lpfc_drop_node(vport, ndlp);
}
return 0;
@@ -505,14 +511,14 @@ lpfc_linkup(struct lpfc_hba *phba)
* handed off to the SLI layer.
*/
void
-lpfc_mbx_cmpl_clear_la(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb)
+lpfc_mbx_cmpl_clear_la(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
{
- struct lpfc_sli *psli;
- MAILBOX_t *mb;
+ struct lpfc_vport *vport = pmb->vport;
+ struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
+ struct lpfc_sli *psli = &phba->sli;
+ MAILBOX_t *mb = &pmb->mb;
uint32_t control;
- psli = &phba->sli;
- mb = &pmb->mb;
/* Since we don't do discovery right now, turn these off here */
psli->ring[psli->extra_ring].flag &= ~LPFC_STOP_IOCB_EVENT;
psli->ring[psli->fcp_ring].flag &= ~LPFC_STOP_IOCB_EVENT;
@@ -520,32 +526,33 @@ lpfc_mbx_cmpl_clear_la(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb)
/* Check for error */
if ((mb->mbxStatus) && (mb->mbxStatus != 0x1601)) {
- /* CLEAR_LA mbox error <mbxStatus> state <hba_state> */
+ /* CLEAR_LA mbox error <mbxStatus> state <port_state> */
lpfc_printf_log(phba, KERN_ERR, LOG_MBOX,
"%d:0320 CLEAR_LA mbxStatus error x%x hba "
"state x%x\n",
- phba->brd_no, mb->mbxStatus, phba->hba_state);
+ phba->brd_no, mb->mbxStatus, vport->port_state);
- phba->hba_state = LPFC_HBA_ERROR;
+ phba->link_state = LPFC_HBA_ERROR;
goto out;
}
- if (phba->fc_flag & FC_ABORT_DISCOVERY)
+ if (vport->fc_flag & FC_ABORT_DISCOVERY)
goto out;
- phba->num_disc_nodes = 0;
- /* go thru NPR list and issue ELS PLOGIs */
- if (phba->fc_npr_cnt) {
- lpfc_els_disc_plogi(phba);
- }
+ vport->num_disc_nodes = 0;
+ /* go thru NPR nodes and issue ELS PLOGIs */
+ if (vport->fc_npr_cnt)
+ lpfc_els_disc_plogi(vport);
- if (!phba->num_disc_nodes) {
- spin_lock_irq(phba->host->host_lock);
- phba->fc_flag &= ~FC_NDISC_ACTIVE;
- spin_unlock_irq(phba->host->host_lock);
+ if (!vport->num_disc_nodes) {
+ spin_lock_irq(shost->host_lock);
+ vport->fc_flag &= ~FC_NDISC_ACTIVE;
+ spin_unlock_irq(shost->host_lock);
}
- phba->hba_state = LPFC_HBA_READY;
+ printk(KERN_ERR "%s (%d): vport ready\n",
+ __FUNCTION__, __LINE__);
+ vport->port_state = LPFC_VPORT_READY;
out:
/* Device Discovery completes */
@@ -555,34 +562,34 @@ out:
"%d:0225 Device Discovery completes\n",
phba->brd_no);
- mempool_free( pmb, phba->mbox_mem_pool);
+ mempool_free(pmb, phba->mbox_mem_pool);
- spin_lock_irq(phba->host->host_lock);
- phba->fc_flag &= ~FC_ABORT_DISCOVERY;
- if (phba->fc_flag & FC_ESTABLISH_LINK) {
- phba->fc_flag &= ~FC_ESTABLISH_LINK;
- }
- spin_unlock_irq(phba->host->host_lock);
+ spin_lock_irq(shost->host_lock);
+ vport->fc_flag &= ~(FC_ABORT_DISCOVERY | FC_ESTABLISH_LINK);
+ spin_unlock_irq(shost->host_lock);
del_timer_sync(&phba->fc_estabtmo);
- lpfc_can_disctmo(phba);
+ lpfc_can_disctmo(vport);
/* turn on Link Attention interrupts */
- spin_lock_irq(phba->host->host_lock);
+
+ spin_lock_irq(&phba->hbalock);
psli->sli_flag |= LPFC_PROCESS_LA;
control = readl(phba->HCregaddr);
control |= HC_LAINT_ENA;
writel(control, phba->HCregaddr);
readl(phba->HCregaddr); /* flush */
- spin_unlock_irq(phba->host->host_lock);
+ spin_unlock_irq(&phba->hbalock);
return;
}
+
static void
lpfc_mbx_cmpl_local_config_link(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
{
+ struct lpfc_vport *vport = pmb->vport;
struct lpfc_sli *psli = &phba->sli;
int rc;
@@ -592,58 +599,64 @@ lpfc_mbx_cmpl_local_config_link(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
mempool_free(pmb, phba->mbox_mem_pool);
if (phba->fc_topology == TOPOLOGY_LOOP &&
- phba->fc_flag & FC_PUBLIC_LOOP &&
- !(phba->fc_flag & FC_LBIT)) {
+ vport->fc_flag & FC_PUBLIC_LOOP &&
+ !(vport->fc_flag & FC_LBIT)) {
/* Need to wait for FAN - use discovery timer
- * for timeout. hba_state is identically
+ * for timeout. port_state is identically
* LPFC_LOCAL_CFG_LINK while waiting for FAN
*/
- lpfc_set_disctmo(phba);
+ lpfc_set_disctmo(vport);
return;
}
- /* Start discovery by sending a FLOGI. hba_state is identically
+ /* Start discovery by sending a FLOGI. port_state is identically
* LPFC_FLOGI while waiting for FLOGI cmpl
*/
- phba->hba_state = LPFC_FLOGI;
- lpfc_set_disctmo(phba);
- lpfc_initial_flogi(phba);
+ vport->port_state = LPFC_FLOGI;
+ lpfc_set_disctmo(vport);
+ lpfc_initial_flogi(vport);
return;
out:
lpfc_printf_log(phba, KERN_ERR, LOG_MBOX,
"%d:0306 CONFIG_LINK mbxStatus error x%x "
"HBA state x%x\n",
- phba->brd_no, pmb->mb.mbxStatus, phba->hba_state);
+ phba->brd_no, pmb->mb.mbxStatus, vport->port_state);
lpfc_linkdown(phba);
- phba->hba_state = LPFC_HBA_ERROR;
+ phba->link_state = LPFC_HBA_ERROR;
lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY,
"%d:0200 CONFIG_LINK bad hba state x%x\n",
- phba->brd_no, phba->hba_state);
+ phba->brd_no, vport->port_state);
lpfc_clear_la(phba, pmb);
+ printk(KERN_ERR "%s (%d): do clear_la\n",
+ __FUNCTION__, __LINE__);
pmb->mbox_cmpl = lpfc_mbx_cmpl_clear_la;
+ pmb->vport = vport;
rc = lpfc_sli_issue_mbox(phba, pmb, (MBX_NOWAIT | MBX_STOP_IOCB));
if (rc == MBX_NOT_FINISHED) {
mempool_free(pmb, phba->mbox_mem_pool);
- lpfc_disc_flush_list(phba);
+ lpfc_disc_flush_list(vport);
psli->ring[(psli->extra_ring)].flag &= ~LPFC_STOP_IOCB_EVENT;
psli->ring[(psli->fcp_ring)].flag &= ~LPFC_STOP_IOCB_EVENT;
psli->ring[(psli->next_ring)].flag &= ~LPFC_STOP_IOCB_EVENT;
- phba->hba_state = LPFC_HBA_READY;
+ printk(KERN_ERR "%s (%d): vport ready\n",
+ __FUNCTION__, __LINE__);
+ vport->port_state = LPFC_VPORT_READY;
}
return;
}
static void
-lpfc_mbx_cmpl_read_sparam(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb)
+lpfc_mbx_cmpl_read_sparam(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
{
struct lpfc_sli *psli = &phba->sli;
MAILBOX_t *mb = &pmb->mb;
struct lpfc_dmabuf *mp = (struct lpfc_dmabuf *) pmb->context1;
+ struct lpfc_vport *vport = pmb->vport;
/* Check for error */
@@ -652,67 +665,78 @@ lpfc_mbx_cmpl_read_sparam(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb)
lpfc_printf_log(phba, KERN_ERR, LOG_MBOX,
"%d:0319 READ_SPARAM mbxStatus error x%x "
"hba state x%x>\n",
- phba->brd_no, mb->mbxStatus, phba->hba_state);
+ phba->brd_no, mb->mbxStatus, vport->port_state);
lpfc_linkdown(phba);
- phba->hba_state = LPFC_HBA_ERROR;
+ phba->link_state = LPFC_HBA_ERROR;
goto out;
}
- memcpy((uint8_t *) & phba->fc_sparam, (uint8_t *) mp->virt,
+ memcpy((uint8_t *) &vport->fc_sparam, (uint8_t *) mp->virt,
sizeof (struct serv_parm));
if (phba->cfg_soft_wwnn)
- u64_to_wwn(phba->cfg_soft_wwnn, phba->fc_sparam.nodeName.u.wwn);
+ u64_to_wwn(phba->cfg_soft_wwnn,
+ vport->fc_sparam.nodeName.u.wwn);
if (phba->cfg_soft_wwpn)
- u64_to_wwn(phba->cfg_soft_wwpn, phba->fc_sparam.portName.u.wwn);
- memcpy((uint8_t *) & phba->fc_nodename,
- (uint8_t *) & phba->fc_sparam.nodeName,
+ u64_to_wwn(phba->cfg_soft_wwpn,
+ vport->fc_sparam.portName.u.wwn);
+ memcpy((uint8_t *) &vport->fc_nodename,
+ (uint8_t *) &vport->fc_sparam.nodeName,
sizeof (struct lpfc_name));
- memcpy((uint8_t *) & phba->fc_portname,
- (uint8_t *) & phba->fc_sparam.portName,
+ memcpy((uint8_t *) &vport->fc_portname,
+ (uint8_t *) &vport->fc_sparam.portName,
sizeof (struct lpfc_name));
lpfc_mbuf_free(phba, mp->virt, mp->phys);
kfree(mp);
- mempool_free( pmb, phba->mbox_mem_pool);
+ mempool_free(pmb, phba->mbox_mem_pool);
return;
out:
pmb->context1 = NULL;
lpfc_mbuf_free(phba, mp->virt, mp->phys);
kfree(mp);
- if (phba->hba_state != LPFC_CLEAR_LA) {
+ if (phba->link_state != LPFC_CLEAR_LA) {
+ struct lpfc_sli_ring *extra_ring =
+ &psli->ring[psli->extra_ring];
+ struct lpfc_sli_ring *fcp_ring = &psli->ring[psli->fcp_ring];
+ struct lpfc_sli_ring *next_ring = &psli->ring[psli->next_ring];
+
lpfc_clear_la(phba, pmb);
+ printk(KERN_ERR "%s (%d): do clear_la\n",
+ __FUNCTION__, __LINE__);
pmb->mbox_cmpl = lpfc_mbx_cmpl_clear_la;
+ pmb->vport = vport;
if (lpfc_sli_issue_mbox(phba, pmb, (MBX_NOWAIT | MBX_STOP_IOCB))
== MBX_NOT_FINISHED) {
- mempool_free( pmb, phba->mbox_mem_pool);
- lpfc_disc_flush_list(phba);
- psli->ring[(psli->extra_ring)].flag &=
- ~LPFC_STOP_IOCB_EVENT;
- psli->ring[(psli->fcp_ring)].flag &=
- ~LPFC_STOP_IOCB_EVENT;
- psli->ring[(psli->next_ring)].flag &=
- ~LPFC_STOP_IOCB_EVENT;
- phba->hba_state = LPFC_HBA_READY;
+ mempool_free(pmb, phba->mbox_mem_pool);
+ lpfc_disc_flush_list(vport);
+ extra_ring->flag &= ~LPFC_STOP_IOCB_EVENT;
+ fcp_ring->flag &= ~LPFC_STOP_IOCB_EVENT;
+ next_ring->flag &= ~LPFC_STOP_IOCB_EVENT;
+ printk(KERN_ERR "%s (%d): vport ready\n",
+ __FUNCTION__, __LINE__);
+ vport->port_state = LPFC_VPORT_READY;
}
} else {
- mempool_free( pmb, phba->mbox_mem_pool);
+ mempool_free(pmb, phba->mbox_mem_pool);
}
return;
}
static void
-lpfc_mbx_process_link_up(struct lpfc_hba *phba, READ_LA_VAR *la)
+lpfc_mbx_process_link_up(struct lpfc_vport *vport, READ_LA_VAR *la)
{
- int i;
+ struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
+ struct lpfc_hba *phba = vport->phba;
LPFC_MBOXQ_t *sparam_mbox, *cfglink_mbox;
+ int i;
struct lpfc_dmabuf *mp;
int rc;
sparam_mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
cfglink_mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
- spin_lock_irq(phba->host->host_lock);
+ spin_lock_irq(shost->host_lock);
switch (la->UlnkSpeed) {
case LA_1GHZ_LINK:
phba->fc_linkspeed = LA_1GHZ_LINK;
@@ -737,9 +761,9 @@ lpfc_mbx_process_link_up(struct lpfc_hba *phba, READ_LA_VAR *la)
/* Get Loop Map information */
if (la->il)
- phba->fc_flag |= FC_LBIT;
+ vport->fc_flag |= FC_LBIT;
- phba->fc_myDID = la->granted_AL_PA;
+ vport->fc_myDID = la->granted_AL_PA;
i = la->un.lilpBde64.tus.f.bdeSize;
if (i == 0) {
@@ -781,14 +805,15 @@ lpfc_mbx_process_link_up(struct lpfc_hba *phba, READ_LA_VAR *la)
}
}
} else {
- phba->fc_myDID = phba->fc_pref_DID;
- phba->fc_flag |= FC_LBIT;
+ vport->fc_myDID = phba->fc_pref_DID;
+ vport->fc_flag |= FC_LBIT;
}
- spin_unlock_irq(phba->host->host_lock);
+ spin_unlock_irq(shost->host_lock);
lpfc_linkup(phba);
if (sparam_mbox) {
lpfc_read_sparam(phba, sparam_mbox);
+ sparam_mbox->vport = vport;
sparam_mbox->mbox_cmpl = lpfc_mbx_cmpl_read_sparam;
rc = lpfc_sli_issue_mbox(phba, sparam_mbox,
(MBX_NOWAIT | MBX_STOP_IOCB));
@@ -804,8 +829,9 @@ lpfc_mbx_process_link_up(struct lpfc_hba *phba, READ_LA_VAR *la)
}
if (cfglink_mbox) {
- phba->hba_state = LPFC_LOCAL_CFG_LINK;
+ vport->port_state = LPFC_LOCAL_CFG_LINK;
lpfc_config_link(phba, cfglink_mbox);
+ cfglink_mbox->vport = vport;
cfglink_mbox->mbox_cmpl = lpfc_mbx_cmpl_local_config_link;
rc = lpfc_sli_issue_mbox(phba, cfglink_mbox,
(MBX_NOWAIT | MBX_STOP_IOCB));
@@ -815,20 +841,21 @@ lpfc_mbx_process_link_up(struct lpfc_hba *phba, READ_LA_VAR *la)
}
static void
-lpfc_mbx_issue_link_down(struct lpfc_hba *phba) {
+lpfc_mbx_issue_link_down(struct lpfc_hba *phba)
+{
uint32_t control;
struct lpfc_sli *psli = &phba->sli;
lpfc_linkdown(phba);
/* turn on Link Attention interrupts - no CLEAR_LA needed */
- spin_lock_irq(phba->host->host_lock);
+ spin_lock_irq(&phba->hbalock);
psli->sli_flag |= LPFC_PROCESS_LA;
control = readl(phba->HCregaddr);
control |= HC_LAINT_ENA;
writel(control, phba->HCregaddr);
readl(phba->HCregaddr); /* flush */
- spin_unlock_irq(phba->host->host_lock);
+ spin_unlock_irq(&phba->hbalock);
}
/*
@@ -838,8 +865,10 @@ lpfc_mbx_issue_link_down(struct lpfc_hba *phba) {
* handed off to the SLI layer.
*/
void
-lpfc_mbx_cmpl_read_la(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb)
+lpfc_mbx_cmpl_read_la(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
{
+ struct lpfc_vport *vport = pmb->vport;
+ struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
READ_LA_VAR *la;
MAILBOX_t *mb = &pmb->mb;
struct lpfc_dmabuf *mp = (struct lpfc_dmabuf *) (pmb->context1);
@@ -851,9 +880,9 @@ lpfc_mbx_cmpl_read_la(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb)
LOG_LINK_EVENT,
"%d:1307 READ_LA mbox error x%x state x%x\n",
phba->brd_no,
- mb->mbxStatus, phba->hba_state);
+ mb->mbxStatus, vport->port_state);
lpfc_mbx_issue_link_down(phba);
- phba->hba_state = LPFC_HBA_ERROR;
+ phba->link_state = LPFC_HBA_ERROR;
goto lpfc_mbx_cmpl_read_la_free_mbuf;
}
@@ -861,27 +890,26 @@ lpfc_mbx_cmpl_read_la(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb)
memcpy(&phba->alpa_map[0], mp->virt, 128);
- spin_lock_irq(phba->host->host_lock);
+ spin_lock_irq(shost->host_lock);
if (la->pb)
- phba->fc_flag |= FC_BYPASSED_MODE;
+ vport->fc_flag |= FC_BYPASSED_MODE;
else
- phba->fc_flag &= ~FC_BYPASSED_MODE;
- spin_unlock_irq(phba->host->host_lock);
+ vport->fc_flag &= ~FC_BYPASSED_MODE;
+ spin_unlock_irq(shost->host_lock);
if (((phba->fc_eventTag + 1) < la->eventTag) ||
(phba->fc_eventTag == la->eventTag)) {
phba->fc_stat.LinkMultiEvent++;
- if (la->attType == AT_LINK_UP) {
+ if (la->attType == AT_LINK_UP)
if (phba->fc_eventTag != 0)
lpfc_linkdown(phba);
}
- }
phba->fc_eventTag = la->eventTag;
if (la->attType == AT_LINK_UP) {
phba->fc_stat.LinkUp++;
- if (phba->fc_flag & FC_LOOPBACK_MODE) {
+ if (phba->link_flag & LS_LOOPBACK_MODE) {
lpfc_printf_log(phba, KERN_INFO, LOG_LINK_EVENT,
"%d:1306 Link Up Event in loop back mode "
"x%x received Data: x%x x%x x%x x%x\n",
@@ -896,14 +924,14 @@ lpfc_mbx_cmpl_read_la(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb)
la->granted_AL_PA, la->UlnkSpeed,
phba->alpa_map[0]);
}
- lpfc_mbx_process_link_up(phba, la);
+ lpfc_mbx_process_link_up(vport, la);
} else {
phba->fc_stat.LinkDown++;
lpfc_printf_log(phba, KERN_ERR, LOG_LINK_EVENT,
"%d:1305 Link Down Event x%x received "
"Data: x%x x%x x%x\n",
phba->brd_no, la->eventTag, phba->fc_eventTag,
- phba->hba_state, phba->fc_flag);
+ phba->pport->port_state, vport->fc_flag);
lpfc_mbx_issue_link_down(phba);
}
@@ -921,26 +949,20 @@ lpfc_mbx_cmpl_read_la_free_mbuf:
* handed off to the SLI layer.
*/
void
-lpfc_mbx_cmpl_reg_login(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb)
+lpfc_mbx_cmpl_reg_login(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
{
- struct lpfc_sli *psli;
- MAILBOX_t *mb;
- struct lpfc_dmabuf *mp;
- struct lpfc_nodelist *ndlp;
-
- psli = &phba->sli;
- mb = &pmb->mb;
+ struct lpfc_vport *vport = pmb->vport;
+ struct lpfc_dmabuf *mp = (struct lpfc_dmabuf *) pmb->context1;
+ struct lpfc_nodelist *ndlp = (struct lpfc_nodelist *) pmb->context2;
- ndlp = (struct lpfc_nodelist *) pmb->context2;
- mp = (struct lpfc_dmabuf *) (pmb->context1);
pmb->context1 = NULL;
/* Good status, call state machine */
- lpfc_disc_state_machine(phba, ndlp, pmb, NLP_EVT_CMPL_REG_LOGIN);
+ lpfc_disc_state_machine(vport, ndlp, pmb, NLP_EVT_CMPL_REG_LOGIN);
lpfc_mbuf_free(phba, mp->virt, mp->phys);
kfree(mp);
- mempool_free( pmb, phba->mbox_mem_pool);
+ mempool_free(pmb, phba->mbox_mem_pool);
lpfc_nlp_put(ndlp);
return;
@@ -953,20 +975,13 @@ lpfc_mbx_cmpl_reg_login(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb)
* handed off to the SLI layer.
*/
void
-lpfc_mbx_cmpl_fabric_reg_login(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb)
+lpfc_mbx_cmpl_fabric_reg_login(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
{
- struct lpfc_sli *psli;
- MAILBOX_t *mb;
- struct lpfc_dmabuf *mp;
- struct lpfc_nodelist *ndlp;
- struct lpfc_nodelist *ndlp_fdmi;
-
-
- psli = &phba->sli;
- mb = &pmb->mb;
-
+ struct lpfc_vport *vport = pmb->vport;
+ MAILBOX_t *mb = &pmb->mb;
+ struct lpfc_dmabuf *mp = (struct lpfc_dmabuf *) (pmb->context1);
+ struct lpfc_nodelist *ndlp, *ndlp_fdmi;
ndlp = (struct lpfc_nodelist *) pmb->context2;
- mp = (struct lpfc_dmabuf *) (pmb->context1);
pmb->context1 = NULL;
pmb->context2 = NULL;
@@ -978,57 +993,59 @@ lpfc_mbx_cmpl_fabric_reg_login(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb)
lpfc_nlp_put(ndlp);
/* FLOGI failed, so just use loop map to make discovery list */
- lpfc_disc_list_loopmap(phba);
+ lpfc_disc_list_loopmap(vport);
/* Start discovery */
- lpfc_disc_start(phba);
+ lpfc_disc_start(vport);
return;
}
ndlp->nlp_rpi = mb->un.varWords[0];
ndlp->nlp_type |= NLP_FABRIC;
- lpfc_nlp_set_state(phba, ndlp, NLP_STE_UNMAPPED_NODE);
+ lpfc_nlp_set_state(vport, ndlp, NLP_STE_UNMAPPED_NODE);
lpfc_nlp_put(ndlp); /* Drop the reference from the mbox */
- if (phba->hba_state == LPFC_FABRIC_CFG_LINK) {
+ if (vport->port_state == LPFC_FABRIC_CFG_LINK) {
/* This NPort has been assigned an NPort_ID by the fabric as a
* result of the completed fabric login. Issue a State Change
* Registration (SCR) ELS request to the fabric controller
* (SCR_DID) so that this NPort gets RSCN events from the
* fabric.
*/
- lpfc_issue_els_scr(phba, SCR_DID, 0);
+ lpfc_issue_els_scr(vport, SCR_DID, 0);
- ndlp = lpfc_findnode_did(phba, NameServer_DID);
+ ndlp = lpfc_findnode_did(vport, NameServer_DID);
if (!ndlp) {
- /* Allocate a new node instance. If the pool is empty,
+ /* Allocate a new node instance. If the pool is empty,
* start the discovery process and skip the Nameserver
* login process. This is attempted again later on.
- * Otherwise, issue a Port Login (PLOGI) to NameServer.
+ * Otherwise, issue a Port Login (PLOGI) to
+ * the NameServer
*/
- ndlp = mempool_alloc(phba->nlp_mem_pool, GFP_ATOMIC);
+ ndlp = mempool_alloc(phba->nlp_mem_pool, GFP_KERNEL);
if (!ndlp) {
- lpfc_disc_start(phba);
+ lpfc_disc_start(vport);
lpfc_mbuf_free(phba, mp->virt, mp->phys);
kfree(mp);
mempool_free(pmb, phba->mbox_mem_pool);
return;
} else {
- lpfc_nlp_init(phba, ndlp, NameServer_DID);
+ lpfc_nlp_init(vport, ndlp, NameServer_DID);
ndlp->nlp_type |= NLP_FABRIC;
}
}
- lpfc_nlp_set_state(phba, ndlp, NLP_STE_PLOGI_ISSUE);
- lpfc_issue_els_plogi(phba, NameServer_DID, 0);
+
+ lpfc_nlp_set_state(vport, ndlp, NLP_STE_PLOGI_ISSUE);
+ lpfc_issue_els_plogi(vport, NameServer_DID, 0);
if (phba->cfg_fdmi_on) {
ndlp_fdmi = mempool_alloc(phba->nlp_mem_pool,
- GFP_KERNEL);
+ GFP_KERNEL);
if (ndlp_fdmi) {
- lpfc_nlp_init(phba, ndlp_fdmi, FDMI_DID);
+ lpfc_nlp_init(vport, ndlp_fdmi, FDMI_DID);
ndlp_fdmi->nlp_type |= NLP_FABRIC;
ndlp_fdmi->nlp_state = NLP_STE_PLOGI_ISSUE;
- lpfc_issue_els_plogi(phba, FDMI_DID, 0);
+ lpfc_issue_els_plogi(vport, FDMI_DID, 0);
}
}
}
@@ -1046,32 +1063,28 @@ lpfc_mbx_cmpl_fabric_reg_login(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb)
* handed off to the SLI layer.
*/
void
-lpfc_mbx_cmpl_ns_reg_login(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb)
+lpfc_mbx_cmpl_ns_reg_login(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
{
- struct lpfc_sli *psli;
- MAILBOX_t *mb;
- struct lpfc_dmabuf *mp;
- struct lpfc_nodelist *ndlp;
-
- psli = &phba->sli;
- mb = &pmb->mb;
-
- ndlp = (struct lpfc_nodelist *) pmb->context2;
- mp = (struct lpfc_dmabuf *) (pmb->context1);
+ MAILBOX_t *mb = &pmb->mb;
+ struct lpfc_dmabuf *mp = (struct lpfc_dmabuf *) (pmb->context1);
+ struct lpfc_nodelist *ndlp = (struct lpfc_nodelist *) pmb->context2;
+ struct lpfc_vport *vport = pmb->vport;
if (mb->mbxStatus) {
lpfc_nlp_put(ndlp);
lpfc_mbuf_free(phba, mp->virt, mp->phys);
kfree(mp);
mempool_free(pmb, phba->mbox_mem_pool);
- lpfc_drop_node(phba, ndlp);
+ lpfc_drop_node(vport, ndlp);
- /* RegLogin failed, so just use loop map to make discovery
- list */
- lpfc_disc_list_loopmap(phba);
+ /*
+ * RegLogin failed, so just use loop map to make discovery
+ * list
+ */
+ lpfc_disc_list_loopmap(vport);
/* Start discovery */
- lpfc_disc_start(phba);
+ lpfc_disc_start(vport);
return;
}
@@ -1079,37 +1092,39 @@ lpfc_mbx_cmpl_ns_reg_login(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb)
ndlp->nlp_rpi = mb->un.varWords[0];
ndlp->nlp_type |= NLP_FABRIC;
- lpfc_nlp_set_state(phba, ndlp, NLP_STE_UNMAPPED_NODE);
+ lpfc_nlp_set_state(vport, ndlp, NLP_STE_UNMAPPED_NODE);
- if (phba->hba_state < LPFC_HBA_READY) {
- /* Link up discovery requires Fabrib registration. */
- lpfc_ns_cmd(phba, ndlp, SLI_CTNS_RNN_ID);
- lpfc_ns_cmd(phba, ndlp, SLI_CTNS_RSNN_NN);
- lpfc_ns_cmd(phba, ndlp, SLI_CTNS_RFT_ID);
- lpfc_ns_cmd(phba, ndlp, SLI_CTNS_RFF_ID);