Commit d7c255b2 authored by James Smart's avatar James Smart Committed by James Bottomley

[SCSI] lpfc 8.2.8 : Miscellaneous Bug Fixes

Miscellaneous Fixes:
- Fix the wrong variable name used for checking node active usage status
- Fix numerous duplicate log message numbers
- Fix change KERN_WARNING messages to KERN_INFO.
- Stop sending erroneous LOGO to fabric after vport is already terminated
- Fix HBQ allocates that were kalloc'ing w/ GFP_KERNEL while holding a lock.
- Fix gcc 4.3.2 compiler warnings and a sparse warning
- Fix bugs in handling unsolicited ct event queue
- Reorder some of the initial link up checks, to remove odd VPI states.
- Correct poor VPI handling
- Add debug messages
- Expand Update_CFG mailbox definition
- Fix handling of VPD data offsets
- Reorder loopback flags
- convert to use offsetof()
Signed-off-by: default avatarJames Smart <james.smart@emulex.com>
Signed-off-by: default avatarJames Bottomley <James.Bottomley@HansenPartnership.com>
parent 34b02dcd
...@@ -499,7 +499,7 @@ struct lpfc_hba { ...@@ -499,7 +499,7 @@ struct lpfc_hba {
wait_queue_head_t work_waitq; wait_queue_head_t work_waitq;
struct task_struct *worker_thread; struct task_struct *worker_thread;
long data_flags; unsigned long data_flags;
uint32_t hbq_in_use; /* HBQs in use flag */ uint32_t hbq_in_use; /* HBQs in use flag */
struct list_head hbqbuf_in_list; /* in-fly hbq buffer list */ struct list_head hbqbuf_in_list; /* in-fly hbq buffer list */
......
...@@ -1302,7 +1302,7 @@ lpfc_##attr##_init(struct lpfc_vport *vport, int val) \ ...@@ -1302,7 +1302,7 @@ lpfc_##attr##_init(struct lpfc_vport *vport, int val) \
return 0;\ return 0;\
}\ }\
lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT, \ lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT, \
"0449 lpfc_"#attr" attribute cannot be set to %d, "\ "0423 lpfc_"#attr" attribute cannot be set to %d, "\
"allowed range is ["#minval", "#maxval"]\n", val); \ "allowed range is ["#minval", "#maxval"]\n", val); \
vport->cfg_##attr = default;\ vport->cfg_##attr = default;\
return -EINVAL;\ return -EINVAL;\
...@@ -1334,7 +1334,7 @@ lpfc_##attr##_set(struct lpfc_vport *vport, int val) \ ...@@ -1334,7 +1334,7 @@ lpfc_##attr##_set(struct lpfc_vport *vport, int val) \
return 0;\ return 0;\
}\ }\
lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT, \ lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT, \
"0450 lpfc_"#attr" attribute cannot be set to %d, "\ "0424 lpfc_"#attr" attribute cannot be set to %d, "\
"allowed range is ["#minval", "#maxval"]\n", val); \ "allowed range is ["#minval", "#maxval"]\n", val); \
return -EINVAL;\ return -EINVAL;\
} }
...@@ -1803,7 +1803,7 @@ lpfc_nodev_tmo_init(struct lpfc_vport *vport, int val) ...@@ -1803,7 +1803,7 @@ lpfc_nodev_tmo_init(struct lpfc_vport *vport, int val)
vport->cfg_nodev_tmo = vport->cfg_devloss_tmo; vport->cfg_nodev_tmo = vport->cfg_devloss_tmo;
if (val != LPFC_DEF_DEVLOSS_TMO) if (val != LPFC_DEF_DEVLOSS_TMO)
lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT, lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
"0402 Ignoring nodev_tmo module " "0407 Ignoring nodev_tmo module "
"parameter because devloss_tmo is " "parameter because devloss_tmo is "
"set.\n"); "set.\n");
return 0; return 0;
...@@ -2030,7 +2030,7 @@ lpfc_restrict_login_init(struct lpfc_vport *vport, int val) ...@@ -2030,7 +2030,7 @@ lpfc_restrict_login_init(struct lpfc_vport *vport, int val)
{ {
if (val < 0 || val > 1) { if (val < 0 || val > 1) {
lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT, lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
"0449 lpfc_restrict_login attribute cannot " "0422 lpfc_restrict_login attribute cannot "
"be set to %d, allowed range is [0, 1]\n", "be set to %d, allowed range is [0, 1]\n",
val); val);
vport->cfg_restrict_login = 1; vport->cfg_restrict_login = 1;
...@@ -2065,7 +2065,7 @@ lpfc_restrict_login_set(struct lpfc_vport *vport, int val) ...@@ -2065,7 +2065,7 @@ lpfc_restrict_login_set(struct lpfc_vport *vport, int val)
{ {
if (val < 0 || val > 1) { if (val < 0 || val > 1) {
lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT, lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
"0450 lpfc_restrict_login attribute cannot " "0425 lpfc_restrict_login attribute cannot "
"be set to %d, allowed range is [0, 1]\n", "be set to %d, allowed range is [0, 1]\n",
val); val);
vport->cfg_restrict_login = 1; vport->cfg_restrict_login = 1;
...@@ -2249,7 +2249,7 @@ lpfc_link_speed_init(struct lpfc_hba *phba, int val) ...@@ -2249,7 +2249,7 @@ lpfc_link_speed_init(struct lpfc_hba *phba, int val)
return 0; return 0;
} }
lpfc_printf_log(phba, KERN_ERR, LOG_INIT, lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
"0454 lpfc_link_speed attribute cannot " "0405 lpfc_link_speed attribute cannot "
"be set to %d, allowed values are " "be set to %d, allowed values are "
"["LPFC_LINK_SPEED_STRING"]\n", val); "["LPFC_LINK_SPEED_STRING"]\n", val);
phba->cfg_link_speed = 0; phba->cfg_link_speed = 0;
...@@ -2787,17 +2787,15 @@ sysfs_mbox_read(struct kobject *kobj, struct bin_attribute *bin_attr, ...@@ -2787,17 +2787,15 @@ sysfs_mbox_read(struct kobject *kobj, struct bin_attribute *bin_attr,
/* If HBA encountered an error attention, allow only DUMP /* If HBA encountered an error attention, allow only DUMP
* or RESTART mailbox commands until the HBA is restarted. * or RESTART mailbox commands until the HBA is restarted.
*/ */
if ((phba->pport->stopped) && if (phba->pport->stopped &&
(phba->sysfs_mbox.mbox->mb.mbxCommand != phba->sysfs_mbox.mbox->mb.mbxCommand != MBX_DUMP_MEMORY &&
MBX_DUMP_MEMORY && phba->sysfs_mbox.mbox->mb.mbxCommand != MBX_RESTART &&
phba->sysfs_mbox.mbox->mb.mbxCommand != phba->sysfs_mbox.mbox->mb.mbxCommand != MBX_WRITE_VPARMS &&
MBX_RESTART && phba->sysfs_mbox.mbox->mb.mbxCommand != MBX_WRITE_WWN)
phba->sysfs_mbox.mbox->mb.mbxCommand != lpfc_printf_log(phba, KERN_WARNING, LOG_MBOX,
MBX_WRITE_VPARMS)) { "1259 mbox: Issued mailbox cmd "
sysfs_mbox_idle(phba); "0x%x while in stopped state.\n",
spin_unlock_irq(&phba->hbalock); phba->sysfs_mbox.mbox->mb.mbxCommand);
return -EPERM;
}
phba->sysfs_mbox.mbox->vport = vport; phba->sysfs_mbox.mbox->vport = vport;
......
...@@ -269,7 +269,7 @@ void lpfc_dev_loss_tmo_callbk(struct fc_rport *rport); ...@@ -269,7 +269,7 @@ void lpfc_dev_loss_tmo_callbk(struct fc_rport *rport);
struct lpfc_vport *lpfc_create_port(struct lpfc_hba *, int, struct device *); struct lpfc_vport *lpfc_create_port(struct lpfc_hba *, int, struct device *);
int lpfc_vport_disable(struct fc_vport *fc_vport, bool disable); int lpfc_vport_disable(struct fc_vport *fc_vport, bool disable);
void lpfc_mbx_unreg_vpi(struct lpfc_vport *); int lpfc_mbx_unreg_vpi(struct lpfc_vport *);
void destroy_port(struct lpfc_vport *); void destroy_port(struct lpfc_vport *);
int lpfc_get_instance(void); int lpfc_get_instance(void);
void lpfc_host_attrib_init(struct Scsi_Host *); void lpfc_host_attrib_init(struct Scsi_Host *);
......
...@@ -134,25 +134,24 @@ lpfc_ct_unsol_event(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, ...@@ -134,25 +134,24 @@ lpfc_ct_unsol_event(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
} }
list_del(&head); list_del(&head);
} else { } else {
struct lpfc_iocbq *next; INIT_LIST_HEAD(&head);
list_add_tail(&head, &piocbq->list);
list_for_each_entry_safe(iocbq, next, &piocbq->list, list) { list_for_each_entry(iocbq, &head, list) {
icmd = &iocbq->iocb; icmd = &iocbq->iocb;
if (icmd->ulpBdeCount == 0) if (icmd->ulpBdeCount == 0)
lpfc_ct_unsol_buffer(phba, piocbq, NULL, 0); lpfc_ct_unsol_buffer(phba, iocbq, NULL, 0);
for (i = 0; i < icmd->ulpBdeCount; i++) { for (i = 0; i < icmd->ulpBdeCount; i++) {
paddr = getPaddr(icmd->un.cont64[i].addrHigh, paddr = getPaddr(icmd->un.cont64[i].addrHigh,
icmd->un.cont64[i].addrLow); icmd->un.cont64[i].addrLow);
mp = lpfc_sli_ringpostbuf_get(phba, pring, mp = lpfc_sli_ringpostbuf_get(phba, pring,
paddr); paddr);
size = icmd->un.cont64[i].tus.f.bdeSize; size = icmd->un.cont64[i].tus.f.bdeSize;
lpfc_ct_unsol_buffer(phba, piocbq, mp, size); lpfc_ct_unsol_buffer(phba, iocbq, mp, size);
lpfc_in_buf_free(phba, mp); lpfc_in_buf_free(phba, mp);
} }
list_del(&iocbq->list);
lpfc_sli_release_iocbq(phba, iocbq);
lpfc_post_buffer(phba, pring, i); lpfc_post_buffer(phba, pring, i);
} }
list_del(&head);
} }
} }
...@@ -861,7 +860,7 @@ lpfc_cmpl_ct(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, ...@@ -861,7 +860,7 @@ lpfc_cmpl_ct(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
retry++; retry++;
lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY, lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,
"0216 Retrying NS cmd %x\n", cmdcode); "0250 Retrying NS cmd %x\n", cmdcode);
rc = lpfc_ns_cmd(vport, cmdcode, retry, 0); rc = lpfc_ns_cmd(vport, cmdcode, retry, 0);
if (rc == 0) if (rc == 0)
goto out; goto out;
......
...@@ -1119,7 +1119,7 @@ lpfc_debugfs_initialize(struct lpfc_vport *vport) ...@@ -1119,7 +1119,7 @@ lpfc_debugfs_initialize(struct lpfc_vport *vport)
atomic_set(&lpfc_debugfs_hba_count, 0); atomic_set(&lpfc_debugfs_hba_count, 0);
if (!lpfc_debugfs_root) { if (!lpfc_debugfs_root) {
lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT, lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
"0409 Cannot create debugfs root\n"); "0408 Cannot create debugfs root\n");
goto debug_failed; goto debug_failed;
} }
} }
...@@ -1133,7 +1133,7 @@ lpfc_debugfs_initialize(struct lpfc_vport *vport) ...@@ -1133,7 +1133,7 @@ lpfc_debugfs_initialize(struct lpfc_vport *vport)
debugfs_create_dir(name, lpfc_debugfs_root); debugfs_create_dir(name, lpfc_debugfs_root);
if (!phba->hba_debugfs_root) { if (!phba->hba_debugfs_root) {
lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT, lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
"0409 Cannot create debugfs hba\n"); "0412 Cannot create debugfs hba\n");
goto debug_failed; goto debug_failed;
} }
atomic_inc(&lpfc_debugfs_hba_count); atomic_inc(&lpfc_debugfs_hba_count);
...@@ -1147,7 +1147,7 @@ lpfc_debugfs_initialize(struct lpfc_vport *vport) ...@@ -1147,7 +1147,7 @@ lpfc_debugfs_initialize(struct lpfc_vport *vport)
phba, &lpfc_debugfs_op_hbqinfo); phba, &lpfc_debugfs_op_hbqinfo);
if (!phba->debug_hbqinfo) { if (!phba->debug_hbqinfo) {
lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT, lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
"0409 Cannot create debugfs hbqinfo\n"); "0411 Cannot create debugfs hbqinfo\n");
goto debug_failed; goto debug_failed;
} }
...@@ -1159,7 +1159,7 @@ lpfc_debugfs_initialize(struct lpfc_vport *vport) ...@@ -1159,7 +1159,7 @@ lpfc_debugfs_initialize(struct lpfc_vport *vport)
phba, &lpfc_debugfs_op_dumpHBASlim); phba, &lpfc_debugfs_op_dumpHBASlim);
if (!phba->debug_dumpHBASlim) { if (!phba->debug_dumpHBASlim) {
lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT, lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
"0409 Cannot create debugfs dumpHBASlim\n"); "0413 Cannot create debugfs dumpHBASlim\n");
goto debug_failed; goto debug_failed;
} }
...@@ -1171,7 +1171,7 @@ lpfc_debugfs_initialize(struct lpfc_vport *vport) ...@@ -1171,7 +1171,7 @@ lpfc_debugfs_initialize(struct lpfc_vport *vport)
phba, &lpfc_debugfs_op_dumpHostSlim); phba, &lpfc_debugfs_op_dumpHostSlim);
if (!phba->debug_dumpHostSlim) { if (!phba->debug_dumpHostSlim) {
lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT, lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
"0409 Cannot create debugfs dumpHostSlim\n"); "0414 Cannot create debugfs dumpHostSlim\n");
goto debug_failed; goto debug_failed;
} }
...@@ -1201,7 +1201,7 @@ lpfc_debugfs_initialize(struct lpfc_vport *vport) ...@@ -1201,7 +1201,7 @@ lpfc_debugfs_initialize(struct lpfc_vport *vport)
phba, &lpfc_debugfs_op_slow_ring_trc); phba, &lpfc_debugfs_op_slow_ring_trc);
if (!phba->debug_slow_ring_trc) { if (!phba->debug_slow_ring_trc) {
lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT, lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
"0409 Cannot create debugfs " "0415 Cannot create debugfs "
"slow_ring_trace\n"); "slow_ring_trace\n");
goto debug_failed; goto debug_failed;
} }
...@@ -1212,7 +1212,7 @@ lpfc_debugfs_initialize(struct lpfc_vport *vport) ...@@ -1212,7 +1212,7 @@ lpfc_debugfs_initialize(struct lpfc_vport *vport)
GFP_KERNEL); GFP_KERNEL);
if (!phba->slow_ring_trc) { if (!phba->slow_ring_trc) {
lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT, lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
"0409 Cannot create debugfs " "0416 Cannot create debugfs "
"slow_ring buffer\n"); "slow_ring buffer\n");
goto debug_failed; goto debug_failed;
} }
...@@ -1229,7 +1229,7 @@ lpfc_debugfs_initialize(struct lpfc_vport *vport) ...@@ -1229,7 +1229,7 @@ lpfc_debugfs_initialize(struct lpfc_vport *vport)
debugfs_create_dir(name, phba->hba_debugfs_root); debugfs_create_dir(name, phba->hba_debugfs_root);
if (!vport->vport_debugfs_root) { if (!vport->vport_debugfs_root) {
lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT, lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
"0409 Cant create debugfs"); "0417 Cant create debugfs");
goto debug_failed; goto debug_failed;
} }
atomic_inc(&phba->debugfs_vport_count); atomic_inc(&phba->debugfs_vport_count);
...@@ -1258,7 +1258,7 @@ lpfc_debugfs_initialize(struct lpfc_vport *vport) ...@@ -1258,7 +1258,7 @@ lpfc_debugfs_initialize(struct lpfc_vport *vport)
if (!vport->disc_trc) { if (!vport->disc_trc) {
lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT, lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
"0409 Cannot create debugfs disc trace " "0418 Cannot create debugfs disc trace "
"buffer\n"); "buffer\n");
goto debug_failed; goto debug_failed;
} }
...@@ -1271,7 +1271,7 @@ lpfc_debugfs_initialize(struct lpfc_vport *vport) ...@@ -1271,7 +1271,7 @@ lpfc_debugfs_initialize(struct lpfc_vport *vport)
vport, &lpfc_debugfs_op_disc_trc); vport, &lpfc_debugfs_op_disc_trc);
if (!vport->debug_disc_trc) { if (!vport->debug_disc_trc) {
lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT, lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
"0409 Cannot create debugfs " "0419 Cannot create debugfs "
"discovery_trace\n"); "discovery_trace\n");
goto debug_failed; goto debug_failed;
} }
......
...@@ -473,7 +473,7 @@ lpfc_cmpl_els_flogi_fabric(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, ...@@ -473,7 +473,7 @@ lpfc_cmpl_els_flogi_fabric(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
*/ */
list_for_each_entry_safe(np, next_np, list_for_each_entry_safe(np, next_np,
&vport->fc_nodes, nlp_listp) { &vport->fc_nodes, nlp_listp) {
if (!NLP_CHK_NODE_ACT(ndlp)) if (!NLP_CHK_NODE_ACT(np))
continue; continue;
if ((np->nlp_state != NLP_STE_NPR_NODE) || if ((np->nlp_state != NLP_STE_NPR_NODE) ||
!(np->nlp_flag & NLP_NPR_ADISC)) !(np->nlp_flag & NLP_NPR_ADISC))
...@@ -2585,7 +2585,7 @@ lpfc_els_retry(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, ...@@ -2585,7 +2585,7 @@ lpfc_els_retry(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
(stat.un.b.lsRjtRsnCodeExp == LSEXP_INVALID_NPORT_ID)) (stat.un.b.lsRjtRsnCodeExp == LSEXP_INVALID_NPORT_ID))
) { ) {
lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS, lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS,
"0123 FDISC Failed (x%x). " "0122 FDISC Failed (x%x). "
"Fabric Detected Bad WWN\n", "Fabric Detected Bad WWN\n",
stat.un.lsRjtError); stat.un.lsRjtError);
lpfc_vport_set_state(vport, lpfc_vport_set_state(vport,
...@@ -3966,7 +3966,7 @@ lpfc_els_rcv_rscn(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb, ...@@ -3966,7 +3966,7 @@ lpfc_els_rcv_rscn(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
if (rscn_id == hba_id) { if (rscn_id == hba_id) {
/* ALL NPortIDs in RSCN are on HBA */ /* ALL NPortIDs in RSCN are on HBA */
lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY, lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,
"0214 Ignore RSCN " "0219 Ignore RSCN "
"Data: x%x x%x x%x x%x\n", "Data: x%x x%x x%x x%x\n",
vport->fc_flag, payload_len, vport->fc_flag, payload_len,
*lp, vport->fc_rscn_id_cnt); *lp, vport->fc_rscn_id_cnt);
...@@ -5165,8 +5165,6 @@ lpfc_els_unsol_buffer(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, ...@@ -5165,8 +5165,6 @@ lpfc_els_unsol_buffer(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
} }
phba->fc_stat.elsRcvFrame++; phba->fc_stat.elsRcvFrame++;
if (elsiocb->context1)
lpfc_nlp_put(elsiocb->context1);
elsiocb->context1 = lpfc_nlp_get(ndlp); elsiocb->context1 = lpfc_nlp_get(ndlp);
elsiocb->vport = vport; elsiocb->vport = vport;
...@@ -5376,6 +5374,8 @@ lpfc_els_unsol_buffer(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, ...@@ -5376,6 +5374,8 @@ lpfc_els_unsol_buffer(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
NULL); NULL);
} }
lpfc_nlp_put(elsiocb->context1);
elsiocb->context1 = NULL;
return; return;
dropit: dropit:
...@@ -5440,6 +5440,7 @@ lpfc_els_unsol_event(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, ...@@ -5440,6 +5440,7 @@ lpfc_els_unsol_event(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
struct lpfc_dmabuf *bdeBuf1 = elsiocb->context2; struct lpfc_dmabuf *bdeBuf1 = elsiocb->context2;
struct lpfc_dmabuf *bdeBuf2 = elsiocb->context3; struct lpfc_dmabuf *bdeBuf2 = elsiocb->context3;
elsiocb->context1 = NULL;
elsiocb->context2 = NULL; elsiocb->context2 = NULL;
elsiocb->context3 = NULL; elsiocb->context3 = NULL;
...@@ -5487,8 +5488,6 @@ lpfc_els_unsol_event(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, ...@@ -5487,8 +5488,6 @@ lpfc_els_unsol_event(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
* The different unsolicited event handlers would tell us * The different unsolicited event handlers would tell us
* if they are done with "mp" by setting context2 to NULL. * if they are done with "mp" by setting context2 to NULL.
*/ */
lpfc_nlp_put(elsiocb->context1);
elsiocb->context1 = NULL;
if (elsiocb->context2) { if (elsiocb->context2) {
lpfc_in_buf_free(phba, (struct lpfc_dmabuf *)elsiocb->context2); lpfc_in_buf_free(phba, (struct lpfc_dmabuf *)elsiocb->context2);
elsiocb->context2 = NULL; elsiocb->context2 = NULL;
...@@ -5750,54 +5749,56 @@ lpfc_cmpl_els_fdisc(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, ...@@ -5750,54 +5749,56 @@ lpfc_cmpl_els_fdisc(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
goto out; goto out;
/* FDISC failed */ /* FDISC failed */
lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS, lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS,
"0124 FDISC failed. (%d/%d)\n", "0126 FDISC failed. (%d/%d)\n",
irsp->ulpStatus, irsp->un.ulpWord[4]); irsp->ulpStatus, irsp->un.ulpWord[4]);
goto fdisc_failed;
}
if (vport->fc_vport->vport_state == FC_VPORT_INITIALIZING) if (vport->fc_vport->vport_state == FC_VPORT_INITIALIZING)
lpfc_vport_set_state(vport, FC_VPORT_FAILED); lpfc_vport_set_state(vport, FC_VPORT_FAILED);
lpfc_nlp_put(ndlp); lpfc_nlp_put(ndlp);
/* giving up on FDISC. Cancel discovery timer */ /* giving up on FDISC. Cancel discovery timer */
lpfc_can_disctmo(vport); lpfc_can_disctmo(vport);
} else { spin_lock_irq(shost->host_lock);
spin_lock_irq(shost->host_lock); vport->fc_flag |= FC_FABRIC;
vport->fc_flag |= FC_FABRIC; if (vport->phba->fc_topology == TOPOLOGY_LOOP)
if (vport->phba->fc_topology == TOPOLOGY_LOOP) vport->fc_flag |= FC_PUBLIC_LOOP;
vport->fc_flag |= FC_PUBLIC_LOOP; spin_unlock_irq(shost->host_lock);
spin_unlock_irq(shost->host_lock);
vport->fc_myDID = irsp->un.ulpWord[4] & Mask_DID; vport->fc_myDID = irsp->un.ulpWord[4] & Mask_DID;
lpfc_vport_set_state(vport, FC_VPORT_ACTIVE); lpfc_vport_set_state(vport, FC_VPORT_ACTIVE);
if ((vport->fc_prevDID != vport->fc_myDID) && if ((vport->fc_prevDID != vport->fc_myDID) &&
!(vport->fc_flag & FC_VPORT_NEEDS_REG_VPI)) { !(vport->fc_flag & FC_VPORT_NEEDS_REG_VPI)) {
/* If our NportID changed, we need to ensure all /* If our NportID changed, we need to ensure all
* remaining NPORTs get unreg_login'ed so we can * remaining NPORTs get unreg_login'ed so we can
* issue unreg_vpi. * issue unreg_vpi.
*/ */
list_for_each_entry_safe(np, next_np, list_for_each_entry_safe(np, next_np,
&vport->fc_nodes, nlp_listp) { &vport->fc_nodes, nlp_listp) {
if (!NLP_CHK_NODE_ACT(ndlp) || if (!NLP_CHK_NODE_ACT(ndlp) ||
(np->nlp_state != NLP_STE_NPR_NODE) || (np->nlp_state != NLP_STE_NPR_NODE) ||
!(np->nlp_flag & NLP_NPR_ADISC)) !(np->nlp_flag & NLP_NPR_ADISC))
continue; continue;
spin_lock_irq(shost->host_lock);
np->nlp_flag &= ~NLP_NPR_ADISC;
spin_unlock_irq(shost->host_lock);
lpfc_unreg_rpi(vport, np);
}
lpfc_mbx_unreg_vpi(vport);
spin_lock_irq(shost->host_lock); spin_lock_irq(shost->host_lock);
vport->fc_flag |= FC_VPORT_NEEDS_REG_VPI; np->nlp_flag &= ~NLP_NPR_ADISC;
spin_unlock_irq(shost->host_lock); spin_unlock_irq(shost->host_lock);
lpfc_unreg_rpi(vport, np);
} }
lpfc_mbx_unreg_vpi(vport);
if (vport->fc_flag & FC_VPORT_NEEDS_REG_VPI) spin_lock_irq(shost->host_lock);
lpfc_register_new_vport(phba, vport, ndlp); vport->fc_flag |= FC_VPORT_NEEDS_REG_VPI;
else spin_unlock_irq(shost->host_lock);
lpfc_do_scr_ns_plogi(phba, vport);
/* Unconditionaly kick off releasing fabric node for vports */
lpfc_nlp_put(ndlp);
} }
if (vport->fc_flag & FC_VPORT_NEEDS_REG_VPI)
lpfc_register_new_vport(phba, vport, ndlp);
else
lpfc_do_scr_ns_plogi(phba, vport);
goto out;
fdisc_failed:
lpfc_vport_set_state(vport, FC_VPORT_FAILED);
/* Cancel discovery timer */
lpfc_can_disctmo(vport);
lpfc_nlp_put(ndlp);
out: out:
lpfc_els_free_iocb(phba, cmdiocb); lpfc_els_free_iocb(phba, cmdiocb);
} }
......
...@@ -207,8 +207,16 @@ lpfc_dev_loss_tmo_handler(struct lpfc_nodelist *ndlp) ...@@ -207,8 +207,16 @@ lpfc_dev_loss_tmo_handler(struct lpfc_nodelist *ndlp)
return; return;
} }
if (ndlp->nlp_state == NLP_STE_MAPPED_NODE) if (ndlp->nlp_state == NLP_STE_MAPPED_NODE) {
lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,
"0284 Devloss timeout Ignored on "
"WWPN %x:%x:%x:%x:%x:%x:%x:%x "
"NPort x%x\n",
*name, *(name+1), *(name+2), *(name+3),
*(name+4), *(name+5), *(name+6), *(name+7),
ndlp->nlp_DID);
return; return;
}
if (ndlp->nlp_type & NLP_FABRIC) { if (ndlp->nlp_type & NLP_FABRIC) {
/* We will clean up these Nodes in linkup */ /* We will clean up these Nodes in linkup */
...@@ -1169,7 +1177,7 @@ lpfc_mbx_cmpl_unreg_vpi(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) ...@@ -1169,7 +1177,7 @@ lpfc_mbx_cmpl_unreg_vpi(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
scsi_host_put(shost); scsi_host_put(shost);
} }
void int
lpfc_mbx_unreg_vpi(struct lpfc_vport *vport) lpfc_mbx_unreg_vpi(struct lpfc_vport *vport)
{ {
struct lpfc_hba *phba = vport->phba; struct lpfc_hba *phba = vport->phba;
...@@ -1178,7 +1186,7 @@ lpfc_mbx_unreg_vpi(struct lpfc_vport *vport) ...@@ -1178,7 +1186,7 @@ lpfc_mbx_unreg_vpi(struct lpfc_vport *vport)
mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
if (!mbox) if (!mbox)
return; return 1;
lpfc_unreg_vpi(phba, vport->vpi, mbox); lpfc_unreg_vpi(phba, vport->vpi, mbox);
mbox->vport = vport; mbox->vport = vport;
...@@ -1189,7 +1197,9 @@ lpfc_mbx_unreg_vpi(struct lpfc_vport *vport) ...@@ -1189,7 +1197,9 @@ lpfc_mbx_unreg_vpi(struct lpfc_vport *vport)
"1800 Could not issue unreg_vpi\n"); "1800 Could not issue unreg_vpi\n");
mempool_free(mbox, phba->mbox_mem_pool); mempool_free(mbox, phba->mbox_mem_pool);
vport->unreg_vpi_cmpl = VPORT_ERROR; vport->unreg_vpi_cmpl = VPORT_ERROR;
return rc;
} }
return 0;
} }
static void static void
...@@ -2778,7 +2788,7 @@ lpfc_disc_timeout_handler(struct lpfc_vport *vport) ...@@ -2778,7 +2788,7 @@ lpfc_disc_timeout_handler(struct lpfc_vport *vport)
default: default:
lpfc_printf_vlog(vport, KERN_ERR, LOG_DISCOVERY, lpfc_printf_vlog(vport, KERN_ERR, LOG_DISCOVERY,
"0229 Unexpected discovery timeout, " "0273 Unexpected discovery timeout, "
"vport State x%x\n", vport->port_state); "vport State x%x\n", vport->port_state);
break; break;
} }
......
...@@ -2318,6 +2318,36 @@ typedef struct { ...@@ -2318,6 +2318,36 @@ typedef struct {
#define DMP_RSP_OFFSET 0x14 /* word 5 contains first word of rsp */ #define DMP_RSP_OFFSET 0x14 /* word 5 contains first word of rsp */
#define DMP_RSP_SIZE 0x6C /* maximum of 27 words of rsp data */ #define DMP_RSP_SIZE 0x6C /* maximum of 27 words of rsp data */
/* Structure for MB Command UPDATE_CFG (0x1B) */
struct update_cfg_var {
#ifdef __BIG_ENDIAN_BITFIELD
uint32_t rsvd2:16;
uint32_t type:8;
uint32_t rsvd:1;
uint32_t ra:1;
uint32_t co:1;
uint32_t cv:1;
uint32_t req:4;
uint32_t entry_length:16;
uint32_t region_id:16;
#else /* __LITTLE_ENDIAN_BITFIELD */
uint32_t req:4;
uint32_t cv:1;
uint32_t co:1;
uint32_t ra:1;
uint32_t rsvd:1;
uint32_t type:8;
uint32_t rsvd2:16;
uint32_t region_id:16;
uint32_t entry_length:16;
#endif
uint32_t resp_info;
uint32_t byte_cnt;
uint32_t data_offset;
};
struct hbq_mask { struct hbq_mask {
#ifdef __BIG_ENDIAN_BITFIELD #ifdef __BIG_ENDIAN_BITFIELD
uint8_t tmatch; uint8_t tmatch;
...@@ -2672,6 +2702,7 @@ typedef union { ...@@ -2672,6 +2702,7 @@ typedef union {
* NEW_FEATURE * NEW_FEATURE
*/ */
struct config_hbq_var varCfgHbq;/* cmd = 0x7c (CONFIG_HBQ) */ struct config_hbq_var varCfgHbq;/* cmd = 0x7c (CONFIG_HBQ) */
struct update_cfg_var varUpdateCfg; /* cmd = 0x1B (UPDATE_CFG)*/
CONFIG_PORT_VAR varCfgPort; /* cmd = 0x88 (CONFIG_PORT) */ CONFIG_PORT_VAR varCfgPort; /* cmd = 0x88 (CONFIG_PORT) */
REG_VPI_VAR varRegVpi; /* cmd = 0x96 (REG_VPI) */ REG_VPI_VAR varRegVpi; /* cmd = 0x96 (REG_VPI) */
UNREG_VPI_VAR varUnregVpi; /* cmd = 0x97 (UNREG_VPI) */ UNREG_VPI_VAR varUnregVpi; /* cmd = 0x97 (UNREG_VPI) */
......
...@@ -183,12 +183,9 @@ lpfc_config_port_prep(struct lpfc_hba *phba) ...@@ -183,12 +183,9 @@ lpfc_config_port_prep(struct lpfc_hba *phba)
sizeof (phba->RandomData)); sizeof (phba->RandomData));
/* Get adapter VPD information */ /* Get adapter VPD information */
pmb->context2 = kmalloc(DMP_RSP_SIZE, GFP_KERNEL);
if (!pmb->context2)
goto out_free_mbox;
lpfc_vpd_data = kmalloc(DMP_VPD_SIZE, GFP_KERNEL); lpfc_vpd_data = kmalloc(DMP_VPD_SIZE, GFP_KERNEL);
if (!lpfc_vpd_data) if (!lpfc_vpd_data)
goto out_free_context2; goto out_free_mbox;
do { do {
lpfc_dump_mem(phba, pmb, offset); lpfc_dump_mem(phba, pmb, offset);
...@@ -203,15 +200,14 @@ lpfc_config_port_prep(struct lpfc_hba *phba) ...@@ -203,15 +200,14 @@ lpfc_config_port_prep(struct lpfc_hba *phba)
} }
if (mb->un.varDmp.word_cnt > DMP_VPD_SIZE - offset) if (mb->un.varDmp.word_cnt > DMP_VPD_SIZE - offset)
mb->un.varDmp.word_cnt = DMP_VPD_SIZE - offset; mb->un.varDmp.word_cnt = DMP_VPD_SIZE - offset;
lpfc_sli_pcimem_bcopy(pmb->context2, lpfc_vpd_data + offset, lpfc_sli_pcimem_bcopy(((uint8_t *)mb) + DMP_RSP_OFFSET,
lpfc_vpd_data + offset,
mb->un.varDmp.word_cnt); mb->un.varDmp.word_cnt);
offset += mb->un.varDmp.word_cnt; offset += mb->un.varDmp.word_cnt;
} while (mb->un.varDmp.word_cnt && offset < DMP_VPD_SIZE); } while (mb->un.varDmp.word_cnt && offset < DMP_VPD_SIZE);
lpfc_parse_vpd(phba, lpfc_vpd_data, offset); lpfc_parse_vpd(phba, lpfc_vpd_data, offset);
kfree(lpfc_vpd_data); kfree(lpfc_vpd_data);
out_free_context2:
kfree(pmb->context2);
out_free_mbox: out_free_mbox:
mempool_free(pmb, phba->mbox_mem_pool); mempool_free(pmb, phba->mbox_mem_pool);
return 0; return 0;
...@@ -425,9 +421,8 @@ lpfc_config_port_post(struct lpfc_hba *phba) ...@@ -425,9 +421,8 @@ lpfc_config_port_post(struct lpfc_hba *phba)
lpfc_init_link(phba, pmb, phba->cfg_topology, phba->cfg_link_speed); lpfc_init_link(phba, pmb, phba->cfg_topology, phba->cfg_link_speed);
pmb->mbox_cmpl = lpfc_sli_def_mbox_cmpl; pmb->mbox_cmpl = lpfc_sli_def_mbox_cmpl;
pmb->vport = vport;
rc = lpfc_sli_issue_mbox(phba, pmb, MBX_NOWAIT);
lpfc_set_loopback_flag(phba); lpfc_set_loopback_flag(phba);
rc = lpfc_sli_issue_mbox(phba, pmb, MBX_NOWAIT);
if (rc != MBX_SUCCESS) { if (rc != MBX_SUCCESS) {
lpfc_printf_log(phba, KERN_ERR, LOG_INIT, lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
"0454 Adapter failed to init, mbxCmd x%x " "0454 Adapter failed to init, mbxCmd x%x "
...@@ -462,7 +457,7 @@ lpfc_config_port_post(struct lpfc_hba *phba) ...@@ -462,7 +457,7 @@ lpfc_config_port_post(struct lpfc_hba *phba)
rc); rc);
mempool_free(pmb, phba->mbox_mem_pool); mempool_free(pmb, phba->mbox_mem_pool);
} }
return (0); return 0;
} }
/** /**
...@@ -841,7 +836,7 @@ lpfc_handle_eratt(struct lpfc_hba *phba) ...@@ -841,7 +836,7 @@ lpfc_handle_eratt(struct lpfc_hba *phba)
temp_event_data.data = (uint32_t)temperature; temp_event_data.data = (uint32_t)temperature;
lpfc_printf_log(phba, KERN_ERR, LOG_INIT, lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
"0459 Adapter maximum temperature exceeded " "0406 Adapter maximum temperature exceeded "
"(%ld), taking this port offline " "(%ld), taking this port offline "
"Data: x%x x%x x%x\n", "Data: x%x x%x x%x\n",
temperature, phba->work_hs, temperature, phba->work_hs,
...@@ -1595,7 +1590,7 @@ lpfc_cleanup(struct lpfc_vport *vport) ...@@ -1595,7 +1590,7 @@ lpfc_cleanup(struct lpfc_vport *vport)
&vport->fc_nodes, nlp_listp) { &vport->fc_nodes, nlp_listp) {
lpfc_printf_vlog(ndlp->vport, KERN_ERR, lpfc_printf_vlog(ndlp->vport, KERN_ERR,
LOG_NODE, LOG_NODE,
"0282: did:x%x ndlp:x%p " "0282 did:x%x ndlp:x%p "
"usgmap:x%x refcnt:%d\n", "usgmap:x%x refcnt:%d\n",
ndlp->nlp_DID, (void *)ndlp, ndlp->nlp_DID, (void *)ndlp,
ndlp->nlp_usg_map, ndlp->nlp_usg_map,
...@@ -2320,10 +2315,10 @@ lpfc_pci_probe_one(struct pci_dev *pdev, const struct pci_device_id *pid) ...@@ -2320,10 +2315,10 @@ lpfc_pci_probe_one(struct pci_dev *pdev, const struct pci_device_id *pid)
goto out_iounmap; goto out_iounmap;
memset(phba->slim2p.virt, 0, SLI2_SLIM_SIZE); memset(phba->slim2p.virt, 0, SLI2_SLIM_SIZE);
phba->mbox = phba->slim2p.virt; phba->mbox = phba->slim2p.virt + offsetof(struct lpfc_sli2_slim, mbx);
phba->pcb = (phba->slim2p.virt + sizeof(MAILBOX_t)); phba->pcb = (phba->slim2p.virt + offsetof(struct lpfc_sli2_slim, pcb));
phba->IOCBs = (phba->slim2p.virt + sizeof(MAILBOX_t) + phba->IOCBs = (phba->slim2p.virt +
sizeof(struct _PCB)); offsetof(struct lpfc_sli2_slim, IOCBs));
phba->hbqslimp.virt = dma_alloc_coherent(&phba->pcidev->dev, phba->hbqslimp.virt = dma_alloc_coherent(&phba->pcidev->dev,
lpfc_sli_hbq_size(), lpfc_sli_hbq_size(),
...@@ -2889,7 +2884,8 @@ lpfc_init(void) ...@@ -2889,7 +2884,8 @@ lpfc_init(void)
error = pci_register_driver(&lpfc_driver); error = pci_register_driver(&lpfc_driver);
if (error) { if (error) {
fc_release_transport(lpfc_transport_template); fc_release_transport(lpfc_transport_template);
fc_release_transport(lpfc_vport_transport_template); if (lpfc_enable_npiv)
fc_release_transport(lpfc_vport_transport_template);
} }
return error; return error;
......
...@@ -1853,8 +1853,13 @@ static uint32_t ...@@ -1853,8 +1853,13 @@ static uint32_t
lpfc_cmpl_logo_npr_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, lpfc_cmpl_logo_npr_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
void *arg, uint32_t evt) void *arg, uint32_t evt)
{ {
struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
if (ndlp->nlp_DID == Fabric_DID) {
spin_lock_irq(shost->host_lock);
vport->fc_flag &= ~(FC_FABRIC | FC_PUBLIC_LOOP);
spin_unlock_irq(shost->host_lock);
}
lpfc_unreg_rpi(vport, ndlp); lpfc_unreg_rpi(vport, ndlp);
/* This routine does nothing, just return the current state */
return ndlp->nlp_state; return ndlp->nlp_state;
} }
...@@ -2143,7 +2148,7 @@ lpfc_disc_state_machine(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, ...@@ -2143,7 +2148,7 @@ lpfc_disc_state_machine(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
lpfc_nlp_put(ndlp); lpfc_nlp_put(ndlp);
} else { } else {
lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY, lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,
"0212 DSM out state %d on NPort free\n", rc); "0213 DSM out state %d on NPort free\n", rc);
lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_DSM, lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_DSM,
"DSM out: ste:%d did:x%x flg:x%x", "DSM out: ste:%d did:x%x flg:x%x",
......
...@@ -627,9 +627,9 @@ lpfc_scsi_cmd_iocb_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *pIocbIn, ...@@ -627,9 +627,9 @@ lpfc_scsi_cmd_iocb_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *pIocbIn,
cmd->result = ScsiResult(DID_BUS_BUSY, 0); cmd->result = ScsiResult(DID_BUS_BUSY, 0);
break; break;
case IOSTAT_LOCAL_REJECT: case IOSTAT_LOCAL_REJECT:
if (lpfc_cmd->result == RJT_UNAVAIL_PERM || if (lpfc_cmd->result == IOERR_INVALID_RPI ||
lpfc_cmd->result == IOERR_NO_RESOURCES || lpfc_cmd->result == IOERR_NO_RESOURCES ||
lpfc_cmd->result == RJT_LOGIN_REQUIRED) { lpfc_cmd->result == IOERR_ABORT_REQUESTED) {
cmd->result = ScsiResult(DID_REQUEUE, 0); cmd->result = ScsiResult(DID_REQUEUE, 0);
break; break;
} /* else: fall through */ } /* else: fall through */
...@@ -1318,7 +1318,7 @@ lpfc_bus_reset_handler(struct scsi_cmnd *cmnd) ...@@ -1318,7 +1318,7 @@ lpfc_bus_reset_handler(struct scsi_cmnd *cmnd)
struct lpfc_hba *phba = vport->phba; struct lpfc_hba *phba = vport->phba;
struct lpfc_nodelist *ndlp = NULL; struct lpfc_nodelist *ndlp = NULL;
int match; int match;
int ret = SUCCESS, status, i; int ret = SUCCESS, status = SUCCESS, i;
int cnt; int cnt;
struct lpfc_scsi_buf * lpfc_cmd; struct lpfc_scsi_buf * lpfc_cmd;
unsigned long later; unsigned long later;
......
...@@ -844,48 +844,58 @@ struct lpfc_hbq_init *lpfc_hbq_defs[] = { ...@@ -844,48 +844,58 @@ struct lpfc_hbq_init *lpfc_hbq_defs[] = {
* @hbqno: HBQ number. * @hbqno: HBQ number.
* @count: Number of HBQ buffers to be posted. * @count: Number of HBQ buffers to be posted.
* *
* This function is called with no lock held to post more * This function is called with no lock held to post more hbq buffers to the
* hbq buffers to the given HBQ. The function returns 0 * given HBQ. The function returns the number of HBQ buffers successfully
* when successful and returns 1 other wise. * posted.
**/ **/
static int static int
lpfc_sli_hbqbuf_fill_hbqs(struct lpfc_hba *phba, uint32_t hbqno, uint32_t count) lpfc_sli_hbqbuf_fill_hbqs(struct lpfc_hba *phba, uint32_t hbqno, uint32_t count)
{ {
uint32_t i, start, end; uint32_t i, posted = 0;
unsigned long flags; unsigned long flags;
struct hbq_dmabuf *hbq_buffer; struct hbq_dmabuf *hbq_buffer;
LIST_HEAD(hbq_buf_list);
if (!phba->hbqs[hbqno].hbq_alloc_buffer) if (!phba->hbqs[hbqno].hbq_alloc_buffer)
return 0; return 0;
start = phba->hbqs[hbqno].buffer_count; if ((phba->hbqs[hbqno].buffer_count + count) >
end = count + start; lpfc_hbq_defs[hbqno]->entry_count)
if (end > lpfc_hbq_defs[hbqno]->entry_count) count = lpfc_hbq_defs[hbqno]->entry_count -
end = lpfc_hbq_defs[hbqno]->entry_count; phba->hbqs[hbqno].buffer_count;
if (!count)
return 0;
/* Allocate HBQ entries */
for (i = 0; i < count; i++) {
hbq_buffer = (phba->hbqs[hbqno].hbq_alloc_buffer)(phba);
if (!hbq_buffer)
break;
list_add_tail(&hbq_buffer->dbuf.list, &hbq_buf_list);
}
/* Check whether HBQ is still in use */ /* Check whether HBQ is still in use */
spin_lock_irqsave(&phba->hbalock, flags); spin_lock_irqsave(&phba->hbalock, flags);
if (!phba->hbq_in_use) if (!phba->hbq_in_use)
goto out; goto err;
while (!list_empty(&hbq_buf_list)) {
/* Populate HBQ entries */ list_remove_head(&hbq_buf_list, hbq_buffer, struct hbq_dmabuf,
for (i = start; i < end; i++) { dbuf.list);
hbq_buffer = (phba->hbqs[hbqno].hbq_alloc_buffer)(phba); hbq_buffer->tag = (phba->hbqs[hbqno].buffer_count |
if (!hbq_buffer) (hbqno << 16));
goto err; if (lpfc_sli_hbq_to_firmware(phba, hbqno, hbq_buffer)) {
hbq_buffer->tag = (i | (hbqno << 16));
if (lpfc_sli_hbq_to_firmware(phba, hbqno, hbq_buffer))
phba->hbqs[hbqno].buffer_count++; phba->hbqs[hbqno].buffer_count++;
else posted++;
} else
(phba->hbqs[hbqno].hbq_free_buffer)(phba, hbq_buffer); (phba->hbqs[hbqno].hbq_free_buffer)(phba, hbq_buffer);
} }
out:
spin_unlock_irqrestore(&phba->hbalock, flags); spin_unlock_irqrestore(&phba->hbalock, flags);
return 0; return posted;
err: err:
spin_unlock_irqrestore(&phba->hbalock, flags); spin_unlock_irqrestore(&phba->hbalock, flags);
return 1; while (!list_empty(&hbq_buf_list)) {
list_remove_head(&hbq_buf_list, hbq_buffer, struct hbq_dmabuf,
dbuf.list);
(phba->hbqs[hbqno].hbq_free_buffer)(phba, hbq_buffer);
}
return 0;
} }
/** /**
...@@ -894,8 +904,8 @@ lpfc_sli_hbqbuf_fill_hbqs(struct lpfc_hba *phba, uint32_t hbqno, uint32_t count) ...@@ -894,8 +904,8 @@ lpfc_sli_hbqbuf_fill_hbqs(struct lpfc_hba *phba, uint32_t hbqno, uint32_t count)
* @qno: HBQ number. * @qno: HBQ number.
* *
* This function posts more buffers to the HBQ. This function * This function posts more buffers to the HBQ. This function
* is called with no lock held. The function returns 0 when * is called with no lock held. The function returns the number of HBQ entries
* successful and returns 1 otherwise. * successfully allocated.
**/ **/
int int
lpfc_sli_hbqbuf_add_hbqs(struct lpfc_hba *phba, uint32_t qno) lpfc_sli_hbqbuf_add_hbqs(struct lpfc_hba *phba, uint32_t qno)
...@@ -911,7 +921,7 @@ lpfc_sli_hbqbuf_add_hbqs(struct lpfc_hba *phba, uint32_t qno) ...@@ -911,7 +921,7 @@ lpfc_sli_hbqbuf_add_hbqs(struct lpfc_hba *phba, uint32_t qno)
* *
* This function is called from SLI initialization code path with * This function is called from SLI initialization code path with
* no lock held to post initial HBQ buffers to firmware. The * no lock held to post initial HBQ buffers to firmware. The
* function returns 0 when successful and returns 1 otherwise. * function returns the number of HBQ entries successfully allocated.
**/ **/
static int static int
lpfc_sli_hbqbuf_init_hbqs(struct lpfc_hba *phba, uint32_t qno) lpfc_sli_hbqbuf_init_hbqs(struct lpfc_hba *phba, uint32_t qno)
...@@ -1253,7 +1263,9 @@ lpfc_sli_handle_mb_event(struct lpfc_hba *phba) ...@@ -1253,7 +1263,9 @@ lpfc_sli_handle_mb_event(struct lpfc_hba *phba)
* This function is called from unsolicited event handler code path to get the * This function is called from unsolicited event handler code path to get the
* HBQ buffer associated with an unsolicited iocb. This function is called with * HBQ buffer associated with an unsolicited iocb. This function is called with
* no lock held. It returns the buffer associated with the given tag and posts * no lock held. It returns the buffer associated with the given tag and posts
* another buffer to the firmware. * another buffer to the firmware. Note that the new buffer must be allocated
* before taking the hbalock and that the hba lock must be held until it is
* finished with the hbq entry swap.
**/ **/
static struct lpfc_dmabuf * static struct lpfc_dmabuf *
lpfc_sli_replace_hbqbuff(struct lpfc_hba *phba, uint32_t tag) lpfc_sli_replace_hbqbuff(struct lpfc_hba *phba, uint32_t tag)
...@@ -1264,22 +1276,28 @@ lpfc_sli_replace_hbqbuff(struct lpfc_hba *phba, uint32_t tag) ...@@ -1264,22 +1276,28 @@ lpfc_sli_replace_hbqbuff(struct lpfc_hba *phba, uint32_t tag)
dma_addr_t phys; /* mapped address */ dma_addr_t phys; /* mapped address */
unsigned long flags; unsigned long flags;
hbqno = tag >> 16;
new_hbq_entry = (phba->hbqs[hbqno].hbq_alloc_buffer)(phba);
/* Check whether HBQ is still in use */ /* Check whether HBQ is still in use */
spin_lock_irqsave(&phba->hbalock, flags); spin_lock_irqsave(&phba->hbalock, flags);
if (!phba->hbq_in_use) { if (!phba->hbq_in_use) {
if (new_hbq_entry)
(phba->hbqs[hbqno].hbq_free_buffer)(phba,
new_hbq_entry);
spin_unlock_irqrestore(&phba->hbalock, flags); spin_unlock_irqrestore(&phba->hbalock, flags);
return NULL; return NULL;
} }
hbq_entry = lpfc_sli_hbqbuf_find(phba, tag); hbq_entry = lpfc_sli_hbqbuf_find(phba, tag);
if (hbq_entry == NULL) { if (hbq_entry == NULL) {
if (new_hbq_entry)
(phba->hbqs[hbqno].hbq_free_buffer)(phba,
new_hbq_entry);
spin_unlock_irqrestore(&phba->hbalock, flags); spin_unlock_irqrestore(&phba->hbalock, flags);
return NULL; return NULL;
} }
list_del(&hbq_entry->dbuf.list); list_del(&hbq_entry->dbuf.list);
hbqno = tag >> 16;
new_hbq_entry = (phba->hbqs[hbqno].hbq_alloc_buffer)(phba);
if (new_hbq_entry == NULL) { if (new_hbq_entry == NULL) {
list_add_tail(&hbq_entry->dbuf.list, &phba->hbqbuf_in_list); list_add_tail(&hbq_entry->dbuf.list, &phba->hbqbuf_in_list);
spin_unlock_irqrestore(&phba->hbalock, flags); spin_unlock_irqrestore(&phba->hbalock, flags);
...@@ -1748,8 +1766,8 @@ void lpfc_sli_poll_fcp_ring(struct lpfc_hba *phba) ...@@ -1748,8 +1766,8 @@ void lpfc_sli_poll_fcp_ring(struct lpfc_hba *phba)
irsp->un.ulpWord[3], irsp->un.ulpWord[3],
irsp->un.ulpWord[4], irsp->un.ulpWord[4],
irsp->un.ulpWord[5], irsp->un.ulpWord[5],
*(((uint32_t *) irsp) + 6), *(uint32_t *)&irsp->un1,
*(((uint32_t *) irsp) + 7)); *((uint32_t *)&irsp->un1 + 1));
} }
switch (type) { switch (type) {
...@@ -1935,8 +1953,8 @@ lpfc_sli_handle_fast_ring_event(struct lpfc_hba *phba, ...@@ -1935,8 +1953,8 @@ lpfc_sli_handle_fast_ring_event(struct lpfc_hba *phba,
irsp->un.ulpWord[3], irsp->un.ulpWord[3],
irsp->un.ulpWord[4], irsp->un.ulpWord[4],
irsp->un.ulpWord[5], irsp->un.ulpWord[5],
*(((uint32_t *) irsp) + 6), *(uint32_t *)&irsp->un1,
*(((uint32_t *) irsp) + 7)); *((uint32_t *)&irsp->un1 + 1));
} }
switch (type) { switch (type) {
...@@ -2921,10 +2939,8 @@ lpfc_sli_hbq_setup(struct lpfc_hba *phba) ...@@ -2921,10 +2939,8 @@ lpfc_sli_hbq_setup(struct lpfc_hba *phba)
mempool_free(pmb, phba->mbox_mem_pool); mempool_free(pmb, phba->mbox_mem_pool);
/* Initially populate or replenish the HBQs */ /* Initially populate or replenish the HBQs */
for (hbqno = 0; hbqno < hbq_count; ++hbqno) { for (hbqno = 0; hbqno < hbq_count; ++hbqno)
if (lpfc_sli_hbqbuf_init_hbqs(phba, hbqno)) lpfc_sli_hbqbuf_init_hbqs(phba, hbqno);
return -ENOMEM;
}
return 0; return 0;
} }
...@@ -3034,6 +3050,7 @@ lpfc_do_config_port(struct lpfc_hba *phba, int sli_mode) ...@@ -3034,6 +3050,7 @@ lpfc_do_config_port(struct lpfc_hba *phba, int sli_mode)
phba->port_gp = phba->mbox->us.s2.port; phba->port_gp = phba->mbox->us.s2.port;
phba->inb_ha_copy = NULL; phba->inb_ha_copy = NULL;
phba->inb_counter = NULL; phba->inb_counter = NULL;
phba->max_vpi = 0;
} }
do_prep_failed: do_prep_failed:
mempool_free(pmb, phba->mbox_mem_pool); mempool_free(pmb, phba->mbox_mem_pool);
...@@ -4335,7 +4352,7 @@ lpfc_sli_ring_taggedbuf_get(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, ...@@ -4335,7 +4352,7 @@ lpfc_sli_ring_taggedbuf_get(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
spin_unlock_irq(&phba->hbalock); spin_unlock_irq(&phba->hbalock);
lpfc_printf_log(phba, KERN_ERR, LOG_INIT, lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
"0410 Cannot find virtual addr for buffer tag on " "0402 Cannot find virtual addr for buffer tag on "
"ring %d Data x%lx x%p x%p x%x\n", "ring %d Data x%lx x%p x%p x%x\n",
pring->ringno, (unsigned long) tag, pring->ringno, (unsigned long) tag,
slp->next, slp->prev, pring->postbufq_cnt); slp->next, slp->prev, pring->postbufq_cnt);
...@@ -4482,7 +4499,7 @@ lpfc_ignore_els_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, ...@@ -4482,7 +4499,7 @@ lpfc_ignore_els_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
/* ELS cmd tag <ulpIoTag> completes */ /* ELS cmd tag <ulpIoTag> completes */
lpfc_printf_log(phba, KERN_INFO, LOG_ELS, lpfc_printf_log(phba, KERN_INFO, LOG_ELS,
"0133 Ignoring ELS cmd tag x%x completion Data: " "0139 Ignoring ELS cmd tag x%x completion Data: "
"x%x x%x x%x\n", "x%x x%x x%x\n",
irsp->ulpIoTag, irsp->ulpStatus, irsp->ulpIoTag, irsp->ulpStatus,
irsp->un.ulpWord[4], irsp->ulpTimeout); irsp->un.ulpWord[4], irsp->ulpTimeout);
...@@ -4568,6 +4585,8 @@ lpfc_sli_issue_abort_iotag(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, ...@@ -4568,6 +4585,8 @@ lpfc_sli_issue_abort_iotag(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
iabt->un.acxri.abortIoTag, abtsiocbp->iotag); iabt->un.acxri.abortIoTag, abtsiocbp->iotag);
retval = __lpfc_sli_issue_iocb(phba, pring, abtsiocbp, 0); retval = __lpfc_sli_issue_iocb(phba, pring, abtsiocbp, 0);
if (retval)
__lpfc_sli_release_iocbq(phba, abtsiocbp);
abort_iotag_exit: abort_iotag_exit:
/* /*
* Caller to this routine should check for IOCB_ERROR * Caller to this routine should check for IOCB_ERROR
...@@ -4899,7 +4918,7 @@ lpfc_sli_issue_iocb_wait(struct lpfc_hba *phba, ...@@ -4899,7 +4918,7 @@ lpfc_sli_issue_iocb_wait(struct lpfc_hba *phba,
} }
} else { } else {
lpfc_printf_log(phba, KERN_INFO, LOG_SLI, lpfc_printf_log(phba, KERN_INFO, LOG_SLI,
":0332 IOCB wait issue failed, Data x%x\n", "0332 IOCB wait issue failed, Data x%x\n",
retval); retval);
retval = IOCB_ERROR; retval = IOCB_ERROR;
} }
...@@ -5271,7 +5290,7 @@ lpfc_intr_handler(int irq, void *dev_id) ...@@ -5271,7 +5290,7 @@ lpfc_intr_handler(int irq, void *dev_id)
lpfc_printf_log(phba, lpfc_printf_log(phba,
KERN_ERR, KERN_ERR,
LOG_MBOX | LOG_SLI, LOG_MBOX | LOG_SLI,
"0306 rc should have" "0350 rc should have"
"been MBX_BUSY"); "been MBX_BUSY");
goto send_current_mbox; goto send_current_mbox;
} }
......
...@@ -577,8 +577,12 @@ lpfc_vport_delete(struct fc_vport *fc_vport) ...@@ -577,8 +577,12 @@ lpfc_vport_delete(struct fc_vport *fc_vport)
* initiated after we've disposed of all other resources associated * initiated after we've disposed of all other resources associated
* with the port. * with the port.
*/ */
if (!scsi_host_get(shost) || !scsi_host_get(shost)) if (!scsi_host_get(shost))
return VPORT_INVAL; return VPORT_INVAL;
if (!scsi_host_get(shost)) {
scsi_host_put(shost);
return VPORT_INVAL;
}
spin_lock_irq(&phba->hbalock); spin_lock_irq(&phba->hbalock);
vport->load_flag |= FC_UNLOADING; vport->load_flag |= FC_UNLOADING;
spin_unlock_irq(&phba->hbalock); spin_unlock_irq(&phba->hbalock);
...@@ -668,6 +672,8 @@ lpfc_vport_delete(struct fc_vport *fc_vport) ...@@ -668,6 +672,8 @@ lpfc_vport_delete(struct fc_vport *fc_vport)
} }
vport->unreg_vpi_cmpl = VPORT_INVAL; vport->unreg_vpi_cmpl = VPORT_INVAL;
timeout = msecs_to_jiffies(phba->fc_ratov * 2000); timeout = msecs_to_jiffies(phba->fc_ratov * 2000);
if (ndlp->nlp_state == NLP_STE_UNUSED_NODE)
goto skip_logo;
if (!lpfc_issue_els_npiv_logo(vport, ndlp)) if (!lpfc_issue_els_npiv_logo(vport, ndlp))
while (vport->unreg_vpi_cmpl == VPORT_INVAL && timeout) while (vport->unreg_vpi_cmpl == VPORT_INVAL && timeout)
timeout = schedule_timeout(timeout); timeout = schedule_timeout(timeout);
...@@ -689,8 +695,10 @@ lpfc_vport_delete(struct fc_vport *fc_vport) ...@@ -689,8 +695,10 @@ lpfc_vport_delete(struct fc_vport *fc_vport)
* Completion of unreg_vpi (lpfc_mbx_cmpl_unreg_vpi) * Completion of unreg_vpi (lpfc_mbx_cmpl_unreg_vpi)
* does the scsi_host_put() to release the vport. * does the scsi_host_put() to release the vport.
*/ */
lpfc_mbx_unreg_vpi(vport); if (lpfc_mbx_unreg_vpi(vport))
} scsi_host_put(shost);
} else
scsi_host_put(shost);
lpfc_free_vpi(phba, vport->vpi); lpfc_free_vpi(phba, vport->vpi);
vport->work_port_events = 0; vport->work_port_events = 0;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment