aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/lpfc/lpfc_init.c
diff options
context:
space:
mode:
authorJames Smart <james.smart@emulex.com>2011-05-24 11:40:48 -0400
committerJames Bottomley <jbottomley@parallels.com>2011-05-26 23:49:35 -0400
commit0558056c1ecd177f2621fc2a0484d565270f7ae1 (patch)
treec29b0ac1ddd56b94f15f6edf8c62bdddf6ae851e /drivers/scsi/lpfc/lpfc_init.c
parent1ca1e43e55f4cd068f997154ffaf5fa62b08b802 (diff)
[SCSI] lpfc 8.3.24: Miscellaneous Fixes and Corrections
Miscellaneous Fixes and Corrections - Remove the memset in the lpfc_sli4_remove_rpi_hdrs call. - Correct swapping of SGE word 2 relative to offset value - Reorganize CQ and EQ usage to comply with SLI4 Specification. - Expand the driver to check the rn bit. Only detect an error if the error bit is set and the RN bit is NOT set. - If mailbox completion code is not success AND the mailbox status is success, then and only then will the driver overwrite the mailbox status. - When driver initializing device, if the device is on a PCIe bus, set PCI's "needs fundamental reset" bit so that EEH uses fundamental reset instead of hot reset for recovery. - Prevent driver from using new WWN when changed in firmware (until driver reload) - When HBA reports maximum SGE size > 0xffffffff (infinite), override with 0x80000000. - Fixed potential missed SLI4 device initialization failure conditions. - Added 100ms delay before driver action following IF_TYPE_2 function reset. - Reverted patch to UNREG/REG on PLOGI to mapped/unmapped node. - Add a check for the CVL received flag in the fcf inuse routine to avoid unregistering the fcf if Devloss fires before Delay discover timer fires. Signed-off-by: Alex Iannicelli <alex.iannicelli@emulex.com> Signed-off-by: James Smart <james.smart@emulex.com> Signed-off-by: James Bottomley <jbottomley@parallels.com>
Diffstat (limited to 'drivers/scsi/lpfc/lpfc_init.c')
-rw-r--r--drivers/scsi/lpfc/lpfc_init.c146
1 files changed, 114 insertions, 32 deletions
diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c
index 7dda036a1af3..f297f9d027dc 100644
--- a/drivers/scsi/lpfc/lpfc_init.c
+++ b/drivers/scsi/lpfc/lpfc_init.c
@@ -309,6 +309,45 @@ lpfc_dump_wakeup_param_cmpl(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmboxq)
309} 309}
310 310
311/** 311/**
312 * lpfc_update_vport_wwn - Updates the fc_nodename, fc_portname,
313 * cfg_soft_wwnn, cfg_soft_wwpn
314 * @vport: pointer to lpfc vport data structure.
315 *
316 *
317 * Return codes
318 * None.
319 **/
320void
321lpfc_update_vport_wwn(struct lpfc_vport *vport)
322{
323 /* If the soft name exists then update it using the service params */
324 if (vport->phba->cfg_soft_wwnn)
325 u64_to_wwn(vport->phba->cfg_soft_wwnn,
326 vport->fc_sparam.nodeName.u.wwn);
327 if (vport->phba->cfg_soft_wwpn)
328 u64_to_wwn(vport->phba->cfg_soft_wwpn,
329 vport->fc_sparam.portName.u.wwn);
330
331 /*
332 * If the name is empty or there exists a soft name
333 * then copy the service params name, otherwise use the fc name
334 */
335 if (vport->fc_nodename.u.wwn[0] == 0 || vport->phba->cfg_soft_wwnn)
336 memcpy(&vport->fc_nodename, &vport->fc_sparam.nodeName,
337 sizeof(struct lpfc_name));
338 else
339 memcpy(&vport->fc_sparam.nodeName, &vport->fc_nodename,
340 sizeof(struct lpfc_name));
341
342 if (vport->fc_portname.u.wwn[0] == 0 || vport->phba->cfg_soft_wwpn)
343 memcpy(&vport->fc_portname, &vport->fc_sparam.portName,
344 sizeof(struct lpfc_name));
345 else
346 memcpy(&vport->fc_sparam.portName, &vport->fc_portname,
347 sizeof(struct lpfc_name));
348}
349
350/**
312 * lpfc_config_port_post - Perform lpfc initialization after config port 351 * lpfc_config_port_post - Perform lpfc initialization after config port
313 * @phba: pointer to lpfc hba data structure. 352 * @phba: pointer to lpfc hba data structure.
314 * 353 *
@@ -377,17 +416,7 @@ lpfc_config_port_post(struct lpfc_hba *phba)
377 lpfc_mbuf_free(phba, mp->virt, mp->phys); 416 lpfc_mbuf_free(phba, mp->virt, mp->phys);
378 kfree(mp); 417 kfree(mp);
379 pmb->context1 = NULL; 418 pmb->context1 = NULL;
380 419 lpfc_update_vport_wwn(vport);
381 if (phba->cfg_soft_wwnn)
382 u64_to_wwn(phba->cfg_soft_wwnn,
383 vport->fc_sparam.nodeName.u.wwn);
384 if (phba->cfg_soft_wwpn)
385 u64_to_wwn(phba->cfg_soft_wwpn,
386 vport->fc_sparam.portName.u.wwn);
387 memcpy(&vport->fc_nodename, &vport->fc_sparam.nodeName,
388 sizeof (struct lpfc_name));
389 memcpy(&vport->fc_portname, &vport->fc_sparam.portName,
390 sizeof (struct lpfc_name));
391 420
392 /* Update the fc_host data structures with new wwn. */ 421 /* Update the fc_host data structures with new wwn. */
393 fc_host_node_name(shost) = wwn_to_u64(vport->fc_nodename.u.wwn); 422 fc_host_node_name(shost) = wwn_to_u64(vport->fc_nodename.u.wwn);
@@ -3935,6 +3964,10 @@ lpfc_enable_pci_dev(struct lpfc_hba *phba)
3935 pci_try_set_mwi(pdev); 3964 pci_try_set_mwi(pdev);
3936 pci_save_state(pdev); 3965 pci_save_state(pdev);
3937 3966
3967 /* PCIe EEH recovery on powerpc platforms needs fundamental reset */
3968 if (pci_find_capability(pdev, PCI_CAP_ID_EXP))
3969 pdev->needs_freset = 1;
3970
3938 return 0; 3971 return 0;
3939 3972
3940out_disable_device: 3973out_disable_device:
@@ -4366,6 +4399,7 @@ lpfc_sli4_driver_resource_setup(struct lpfc_hba *phba)
4366 lpfc_printf_log(phba, KERN_ERR, LOG_INIT, 4399 lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
4367 "2759 Failed allocate memory for FCF round " 4400 "2759 Failed allocate memory for FCF round "
4368 "robin failover bmask\n"); 4401 "robin failover bmask\n");
4402 rc = -ENOMEM;
4369 goto out_remove_rpi_hdrs; 4403 goto out_remove_rpi_hdrs;
4370 } 4404 }
4371 4405
@@ -4375,6 +4409,7 @@ lpfc_sli4_driver_resource_setup(struct lpfc_hba *phba)
4375 lpfc_printf_log(phba, KERN_ERR, LOG_INIT, 4409 lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
4376 "2572 Failed allocate memory for fast-path " 4410 "2572 Failed allocate memory for fast-path "
4377 "per-EQ handle array\n"); 4411 "per-EQ handle array\n");
4412 rc = -ENOMEM;
4378 goto out_free_fcf_rr_bmask; 4413 goto out_free_fcf_rr_bmask;
4379 } 4414 }
4380 4415
@@ -4384,6 +4419,7 @@ lpfc_sli4_driver_resource_setup(struct lpfc_hba *phba)
4384 lpfc_printf_log(phba, KERN_ERR, LOG_INIT, 4419 lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
4385 "2573 Failed allocate memory for msi-x " 4420 "2573 Failed allocate memory for msi-x "
4386 "interrupt vector entries\n"); 4421 "interrupt vector entries\n");
4422 rc = -ENOMEM;
4387 goto out_free_fcp_eq_hdl; 4423 goto out_free_fcp_eq_hdl;
4388 } 4424 }
4389 4425
@@ -4998,9 +5034,7 @@ lpfc_sli4_remove_rpi_hdrs(struct lpfc_hba *phba)
4998 kfree(rpi_hdr->dmabuf); 5034 kfree(rpi_hdr->dmabuf);
4999 kfree(rpi_hdr); 5035 kfree(rpi_hdr);
5000 } 5036 }
5001
5002 phba->sli4_hba.next_rpi = phba->sli4_hba.max_cfg_param.rpi_base; 5037 phba->sli4_hba.next_rpi = phba->sli4_hba.max_cfg_param.rpi_base;
5003 memset(phba->sli4_hba.rpi_bmask, 0, sizeof(*phba->sli4_hba.rpi_bmask));
5004} 5038}
5005 5039
5006/** 5040/**
@@ -5487,7 +5521,8 @@ lpfc_sli4_post_status_check(struct lpfc_hba *phba)
5487 /* Final checks. The port status should be clean. */ 5521 /* Final checks. The port status should be clean. */
5488 if (lpfc_readl(phba->sli4_hba.u.if_type2.STATUSregaddr, 5522 if (lpfc_readl(phba->sli4_hba.u.if_type2.STATUSregaddr,
5489 &reg_data.word0) || 5523 &reg_data.word0) ||
5490 bf_get(lpfc_sliport_status_err, &reg_data)) { 5524 (bf_get(lpfc_sliport_status_err, &reg_data) &&
5525 !bf_get(lpfc_sliport_status_rn, &reg_data))) {
5491 phba->work_status[0] = 5526 phba->work_status[0] =
5492 readl(phba->sli4_hba.u.if_type2. 5527 readl(phba->sli4_hba.u.if_type2.
5493 ERR1regaddr); 5528 ERR1regaddr);
@@ -6229,8 +6264,10 @@ lpfc_sli4_queue_destroy(struct lpfc_hba *phba)
6229 phba->sli4_hba.mbx_cq = NULL; 6264 phba->sli4_hba.mbx_cq = NULL;
6230 6265
6231 /* Release FCP response complete queue */ 6266 /* Release FCP response complete queue */
6232 for (fcp_qidx = 0; fcp_qidx < phba->cfg_fcp_eq_count; fcp_qidx++) 6267 fcp_qidx = 0;
6268 do
6233 lpfc_sli4_queue_free(phba->sli4_hba.fcp_cq[fcp_qidx]); 6269 lpfc_sli4_queue_free(phba->sli4_hba.fcp_cq[fcp_qidx]);
6270 while (++fcp_qidx < phba->cfg_fcp_eq_count);
6234 kfree(phba->sli4_hba.fcp_cq); 6271 kfree(phba->sli4_hba.fcp_cq);
6235 phba->sli4_hba.fcp_cq = NULL; 6272 phba->sli4_hba.fcp_cq = NULL;
6236 6273
@@ -6353,16 +6390,24 @@ lpfc_sli4_queue_setup(struct lpfc_hba *phba)
6353 phba->sli4_hba.sp_eq->queue_id); 6390 phba->sli4_hba.sp_eq->queue_id);
6354 6391
6355 /* Set up fast-path FCP Response Complete Queue */ 6392 /* Set up fast-path FCP Response Complete Queue */
6356 for (fcp_cqidx = 0; fcp_cqidx < phba->cfg_fcp_eq_count; fcp_cqidx++) { 6393 fcp_cqidx = 0;
6394 do {
6357 if (!phba->sli4_hba.fcp_cq[fcp_cqidx]) { 6395 if (!phba->sli4_hba.fcp_cq[fcp_cqidx]) {
6358 lpfc_printf_log(phba, KERN_ERR, LOG_INIT, 6396 lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
6359 "0526 Fast-path FCP CQ (%d) not " 6397 "0526 Fast-path FCP CQ (%d) not "
6360 "allocated\n", fcp_cqidx); 6398 "allocated\n", fcp_cqidx);
6361 goto out_destroy_fcp_cq; 6399 goto out_destroy_fcp_cq;
6362 } 6400 }
6363 rc = lpfc_cq_create(phba, phba->sli4_hba.fcp_cq[fcp_cqidx], 6401 if (phba->cfg_fcp_eq_count)
6364 phba->sli4_hba.fp_eq[fcp_cqidx], 6402 rc = lpfc_cq_create(phba,
6365 LPFC_WCQ, LPFC_FCP); 6403 phba->sli4_hba.fcp_cq[fcp_cqidx],
6404 phba->sli4_hba.fp_eq[fcp_cqidx],
6405 LPFC_WCQ, LPFC_FCP);
6406 else
6407 rc = lpfc_cq_create(phba,
6408 phba->sli4_hba.fcp_cq[fcp_cqidx],
6409 phba->sli4_hba.sp_eq,
6410 LPFC_WCQ, LPFC_FCP);
6366 if (rc) { 6411 if (rc) {
6367 lpfc_printf_log(phba, KERN_ERR, LOG_INIT, 6412 lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
6368 "0527 Failed setup of fast-path FCP " 6413 "0527 Failed setup of fast-path FCP "
@@ -6371,12 +6416,15 @@ lpfc_sli4_queue_setup(struct lpfc_hba *phba)
6371 } 6416 }
6372 lpfc_printf_log(phba, KERN_INFO, LOG_INIT, 6417 lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
6373 "2588 FCP CQ setup: cq[%d]-id=%d, " 6418 "2588 FCP CQ setup: cq[%d]-id=%d, "
6374 "parent eq[%d]-id=%d\n", 6419 "parent %seq[%d]-id=%d\n",
6375 fcp_cqidx, 6420 fcp_cqidx,
6376 phba->sli4_hba.fcp_cq[fcp_cqidx]->queue_id, 6421 phba->sli4_hba.fcp_cq[fcp_cqidx]->queue_id,
6422 (phba->cfg_fcp_eq_count) ? "" : "sp_",
6377 fcp_cqidx, 6423 fcp_cqidx,
6378 phba->sli4_hba.fp_eq[fcp_cqidx]->queue_id); 6424 (phba->cfg_fcp_eq_count) ?
6379 } 6425 phba->sli4_hba.fp_eq[fcp_cqidx]->queue_id :
6426 phba->sli4_hba.sp_eq->queue_id);
6427 } while (++fcp_cqidx < phba->cfg_fcp_eq_count);
6380 6428
6381 /* 6429 /*
6382 * Set up all the Work Queues (WQs) 6430 * Set up all the Work Queues (WQs)
@@ -6445,7 +6493,9 @@ lpfc_sli4_queue_setup(struct lpfc_hba *phba)
6445 fcp_cq_index, 6493 fcp_cq_index,
6446 phba->sli4_hba.fcp_cq[fcp_cq_index]->queue_id); 6494 phba->sli4_hba.fcp_cq[fcp_cq_index]->queue_id);
6447 /* Round robin FCP Work Queue's Completion Queue assignment */ 6495 /* Round robin FCP Work Queue's Completion Queue assignment */
6448 fcp_cq_index = ((fcp_cq_index + 1) % phba->cfg_fcp_eq_count); 6496 if (phba->cfg_fcp_eq_count)
6497 fcp_cq_index = ((fcp_cq_index + 1) %
6498 phba->cfg_fcp_eq_count);
6449 } 6499 }
6450 6500
6451 /* 6501 /*
@@ -6827,6 +6877,8 @@ lpfc_pci_function_reset(struct lpfc_hba *phba)
6827 if (rdy_chk < 1000) 6877 if (rdy_chk < 1000)
6828 break; 6878 break;
6829 } 6879 }
6880 /* delay driver action following IF_TYPE_2 function reset */
6881 msleep(100);
6830 break; 6882 break;
6831 case LPFC_SLI_INTF_IF_TYPE_1: 6883 case LPFC_SLI_INTF_IF_TYPE_1:
6832 default: 6884 default:
@@ -7419,11 +7471,15 @@ enable_msix_vectors:
7419 /* 7471 /*
7420 * Assign MSI-X vectors to interrupt handlers 7472 * Assign MSI-X vectors to interrupt handlers
7421 */ 7473 */
7422 7474 if (vectors > 1)
7423 /* The first vector must associated to slow-path handler for MQ */ 7475 rc = request_irq(phba->sli4_hba.msix_entries[0].vector,
7424 rc = request_irq(phba->sli4_hba.msix_entries[0].vector, 7476 &lpfc_sli4_sp_intr_handler, IRQF_SHARED,
7425 &lpfc_sli4_sp_intr_handler, IRQF_SHARED, 7477 LPFC_SP_DRIVER_HANDLER_NAME, phba);
7426 LPFC_SP_DRIVER_HANDLER_NAME, phba); 7478 else
7479 /* All Interrupts need to be handled by one EQ */
7480 rc = request_irq(phba->sli4_hba.msix_entries[0].vector,
7481 &lpfc_sli4_intr_handler, IRQF_SHARED,
7482 LPFC_DRIVER_NAME, phba);
7427 if (rc) { 7483 if (rc) {
7428 lpfc_printf_log(phba, KERN_WARNING, LOG_INIT, 7484 lpfc_printf_log(phba, KERN_WARNING, LOG_INIT,
7429 "0485 MSI-X slow-path request_irq failed " 7485 "0485 MSI-X slow-path request_irq failed "
@@ -7878,6 +7934,11 @@ lpfc_pc_sli4_params_get(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq)
7878 sli4_params->hdr_pp_align = bf_get(hdr_pp_align, &mqe->un.sli4_params); 7934 sli4_params->hdr_pp_align = bf_get(hdr_pp_align, &mqe->un.sli4_params);
7879 sli4_params->sgl_pages_max = bf_get(sgl_pages, &mqe->un.sli4_params); 7935 sli4_params->sgl_pages_max = bf_get(sgl_pages, &mqe->un.sli4_params);
7880 sli4_params->sgl_pp_align = bf_get(sgl_pp_align, &mqe->un.sli4_params); 7936 sli4_params->sgl_pp_align = bf_get(sgl_pp_align, &mqe->un.sli4_params);
7937
7938 /* Make sure that sge_supp_len can be handled by the driver */
7939 if (sli4_params->sge_supp_len > LPFC_MAX_SGE_SIZE)
7940 sli4_params->sge_supp_len = LPFC_MAX_SGE_SIZE;
7941
7881 return rc; 7942 return rc;
7882} 7943}
7883 7944
@@ -7938,6 +7999,11 @@ lpfc_get_sli4_parameters(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq)
7938 mbx_sli4_parameters); 7999 mbx_sli4_parameters);
7939 sli4_params->sgl_pp_align = bf_get(cfg_sgl_pp_align, 8000 sli4_params->sgl_pp_align = bf_get(cfg_sgl_pp_align,
7940 mbx_sli4_parameters); 8001 mbx_sli4_parameters);
8002
8003 /* Make sure that sge_supp_len can be handled by the driver */
8004 if (sli4_params->sge_supp_len > LPFC_MAX_SGE_SIZE)
8005 sli4_params->sge_supp_len = LPFC_MAX_SGE_SIZE;
8006
7941 return 0; 8007 return 0;
7942} 8008}
7943 8009
@@ -8591,6 +8657,8 @@ lpfc_pci_probe_one_s4(struct pci_dev *pdev, const struct pci_device_id *pid)
8591 int error; 8657 int error;
8592 uint32_t cfg_mode, intr_mode; 8658 uint32_t cfg_mode, intr_mode;
8593 int mcnt; 8659 int mcnt;
8660 int adjusted_fcp_eq_count;
8661 int fcp_qidx;
8594 8662
8595 /* Allocate memory for HBA structure */ 8663 /* Allocate memory for HBA structure */
8596 phba = lpfc_hba_alloc(pdev); 8664 phba = lpfc_hba_alloc(pdev);
@@ -8688,11 +8756,25 @@ lpfc_pci_probe_one_s4(struct pci_dev *pdev, const struct pci_device_id *pid)
8688 error = -ENODEV; 8756 error = -ENODEV;
8689 goto out_free_sysfs_attr; 8757 goto out_free_sysfs_attr;
8690 } 8758 }
8691 /* Default to single FCP EQ for non-MSI-X */ 8759 /* Default to single EQ for non-MSI-X */
8692 if (phba->intr_type != MSIX) 8760 if (phba->intr_type != MSIX)
8693 phba->cfg_fcp_eq_count = 1; 8761 adjusted_fcp_eq_count = 0;
8694 else if (phba->sli4_hba.msix_vec_nr < phba->cfg_fcp_eq_count) 8762 else if (phba->sli4_hba.msix_vec_nr <
8695 phba->cfg_fcp_eq_count = phba->sli4_hba.msix_vec_nr - 1; 8763 phba->cfg_fcp_eq_count + 1)
8764 adjusted_fcp_eq_count = phba->sli4_hba.msix_vec_nr - 1;
8765 else
8766 adjusted_fcp_eq_count = phba->cfg_fcp_eq_count;
8767 /* Free unused EQs */
8768 for (fcp_qidx = adjusted_fcp_eq_count;
8769 fcp_qidx < phba->cfg_fcp_eq_count;
8770 fcp_qidx++) {
8771 lpfc_sli4_queue_free(phba->sli4_hba.fp_eq[fcp_qidx]);
8772 /* do not delete the first fcp_cq */
8773 if (fcp_qidx)
8774 lpfc_sli4_queue_free(
8775 phba->sli4_hba.fcp_cq[fcp_qidx]);
8776 }
8777 phba->cfg_fcp_eq_count = adjusted_fcp_eq_count;
8696 /* Set up SLI-4 HBA */ 8778 /* Set up SLI-4 HBA */
8697 if (lpfc_sli4_hba_setup(phba)) { 8779 if (lpfc_sli4_hba_setup(phba)) {
8698 lpfc_printf_log(phba, KERN_ERR, LOG_INIT, 8780 lpfc_printf_log(phba, KERN_ERR, LOG_INIT,