aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorJames Smart <james.smart@emulex.com>2010-04-06 15:05:28 -0400
committerJames Bottomley <James.Bottomley@suse.de>2010-04-11 14:45:38 -0400
commitc74959370369cd870560777b7db7ec940565bb85 (patch)
treefebf7febd3fce3ba160a405f91bc1c42858c8ee8 /drivers
parent49198b371e2da20548d1408a7d3a8dea2f91263c (diff)
[SCSI] lpfc 8.3.12: BSG Fixes and enhancements
- Add memcpy to mailbox completion to transfer reply correctly. - Add support for BSG mailbox commands (dump, update_cfg, and event_log_status). - Add warning message and refuse mailbox command while mgmt is blocked. - Add checks for memory allocation failure. - Add check for sli4 dump zero BDE size. - Only copy data if mailbox commands succeed. - Add support for Read Event Log mailbox command. Signed-off-by: Alex Iannicelli <alex.iannicelli@emulex.com> Signed-off-by: James Smart <james.smart@emulex.com> Signed-off-by: James Bottomley <James.Bottomley@suse.de>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/scsi/lpfc/lpfc_bsg.c274
-rw-r--r--drivers/scsi/lpfc/lpfc_bsg.h2
-rw-r--r--drivers/scsi/lpfc/lpfc_hw.h14
-rw-r--r--drivers/scsi/lpfc/lpfc_sli.c2
4 files changed, 253 insertions, 39 deletions
diff --git a/drivers/scsi/lpfc/lpfc_bsg.c b/drivers/scsi/lpfc/lpfc_bsg.c
index 141a1ce9b742..dcf088262b20 100644
--- a/drivers/scsi/lpfc/lpfc_bsg.c
+++ b/drivers/scsi/lpfc/lpfc_bsg.c
@@ -84,7 +84,7 @@ struct lpfc_bsg_mbox {
84 uint8_t *ext; /* extended mailbox data */ 84 uint8_t *ext; /* extended mailbox data */
85 uint32_t mbOffset; /* from app */ 85 uint32_t mbOffset; /* from app */
86 uint32_t inExtWLen; /* from app */ 86 uint32_t inExtWLen; /* from app */
87 uint32_t outWxtWLen; /* from app */ 87 uint32_t outExtWLen; /* from app */
88 88
89 /* job waiting for this mbox command to finish */ 89 /* job waiting for this mbox command to finish */
90 struct fc_bsg_job *set_job; 90 struct fc_bsg_job *set_job;
@@ -1714,21 +1714,26 @@ static int lpfcdiag_loop_get_xri(struct lpfc_hba *phba, uint16_t rpi,
1714 dmabuf = kmalloc(sizeof(struct lpfc_dmabuf), GFP_KERNEL); 1714 dmabuf = kmalloc(sizeof(struct lpfc_dmabuf), GFP_KERNEL);
1715 if (dmabuf) { 1715 if (dmabuf) {
1716 dmabuf->virt = lpfc_mbuf_alloc(phba, 0, &dmabuf->phys); 1716 dmabuf->virt = lpfc_mbuf_alloc(phba, 0, &dmabuf->phys);
1717 INIT_LIST_HEAD(&dmabuf->list); 1717 if (dmabuf->virt) {
1718 bpl = (struct ulp_bde64 *) dmabuf->virt; 1718 INIT_LIST_HEAD(&dmabuf->list);
1719 memset(bpl, 0, sizeof(*bpl)); 1719 bpl = (struct ulp_bde64 *) dmabuf->virt;
1720 ctreq = (struct lpfc_sli_ct_request *)(bpl + 1); 1720 memset(bpl, 0, sizeof(*bpl));
1721 bpl->addrHigh = 1721 ctreq = (struct lpfc_sli_ct_request *)(bpl + 1);
1722 le32_to_cpu(putPaddrHigh(dmabuf->phys + sizeof(*bpl))); 1722 bpl->addrHigh =
1723 bpl->addrLow = 1723 le32_to_cpu(putPaddrHigh(dmabuf->phys +
1724 le32_to_cpu(putPaddrLow(dmabuf->phys + sizeof(*bpl))); 1724 sizeof(*bpl)));
1725 bpl->tus.f.bdeFlags = 0; 1725 bpl->addrLow =
1726 bpl->tus.f.bdeSize = ELX_LOOPBACK_HEADER_SZ; 1726 le32_to_cpu(putPaddrLow(dmabuf->phys +
1727 bpl->tus.w = le32_to_cpu(bpl->tus.w); 1727 sizeof(*bpl)));
1728 bpl->tus.f.bdeFlags = 0;
1729 bpl->tus.f.bdeSize = ELX_LOOPBACK_HEADER_SZ;
1730 bpl->tus.w = le32_to_cpu(bpl->tus.w);
1731 }
1728 } 1732 }
1729 1733
1730 if (cmdiocbq == NULL || rspiocbq == NULL || 1734 if (cmdiocbq == NULL || rspiocbq == NULL ||
1731 dmabuf == NULL || bpl == NULL || ctreq == NULL) { 1735 dmabuf == NULL || bpl == NULL || ctreq == NULL ||
1736 dmabuf->virt == NULL) {
1732 ret_val = ENOMEM; 1737 ret_val = ENOMEM;
1733 goto err_get_xri_exit; 1738 goto err_get_xri_exit;
1734 } 1739 }
@@ -1924,9 +1929,11 @@ static int lpfcdiag_loop_post_rxbufs(struct lpfc_hba *phba, uint16_t rxxri,
1924 rxbmp = kmalloc(sizeof(struct lpfc_dmabuf), GFP_KERNEL); 1929 rxbmp = kmalloc(sizeof(struct lpfc_dmabuf), GFP_KERNEL);
1925 if (rxbmp != NULL) { 1930 if (rxbmp != NULL) {
1926 rxbmp->virt = lpfc_mbuf_alloc(phba, 0, &rxbmp->phys); 1931 rxbmp->virt = lpfc_mbuf_alloc(phba, 0, &rxbmp->phys);
1927 INIT_LIST_HEAD(&rxbmp->list); 1932 if (rxbmp->virt) {
1928 rxbpl = (struct ulp_bde64 *) rxbmp->virt; 1933 INIT_LIST_HEAD(&rxbmp->list);
1929 rxbuffer = diag_cmd_data_alloc(phba, rxbpl, len, 0); 1934 rxbpl = (struct ulp_bde64 *) rxbmp->virt;
1935 rxbuffer = diag_cmd_data_alloc(phba, rxbpl, len, 0);
1936 }
1930 } 1937 }
1931 1938
1932 if (!cmdiocbq || !rxbmp || !rxbpl || !rxbuffer) { 1939 if (!cmdiocbq || !rxbmp || !rxbpl || !rxbuffer) {
@@ -2180,14 +2187,16 @@ lpfc_bsg_diag_test(struct fc_bsg_job *job)
2180 2187
2181 if (txbmp) { 2188 if (txbmp) {
2182 txbmp->virt = lpfc_mbuf_alloc(phba, 0, &txbmp->phys); 2189 txbmp->virt = lpfc_mbuf_alloc(phba, 0, &txbmp->phys);
2183 INIT_LIST_HEAD(&txbmp->list); 2190 if (txbmp->virt) {
2184 txbpl = (struct ulp_bde64 *) txbmp->virt; 2191 INIT_LIST_HEAD(&txbmp->list);
2185 if (txbpl) 2192 txbpl = (struct ulp_bde64 *) txbmp->virt;
2186 txbuffer = diag_cmd_data_alloc(phba, 2193 txbuffer = diag_cmd_data_alloc(phba,
2187 txbpl, full_size, 0); 2194 txbpl, full_size, 0);
2195 }
2188 } 2196 }
2189 2197
2190 if (!cmdiocbq || !rspiocbq || !txbmp || !txbpl || !txbuffer) { 2198 if (!cmdiocbq || !rspiocbq || !txbmp || !txbpl || !txbuffer ||
2199 !txbmp->virt) {
2191 rc = -ENOMEM; 2200 rc = -ENOMEM;
2192 goto err_loopback_test_exit; 2201 goto err_loopback_test_exit;
2193 } 2202 }
@@ -2404,12 +2413,34 @@ lpfc_bsg_wake_mbox_wait(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmboxq)
2404 from = (uint8_t *)&pmboxq->u.mb; 2413 from = (uint8_t *)&pmboxq->u.mb;
2405 to = (uint8_t *)dd_data->context_un.mbox.mb; 2414 to = (uint8_t *)dd_data->context_un.mbox.mb;
2406 memcpy(to, from, sizeof(MAILBOX_t)); 2415 memcpy(to, from, sizeof(MAILBOX_t));
2407 /* copy the extended data if any, count is in words */ 2416 if (pmboxq->u.mb.mbxStatus == MBX_SUCCESS) {
2408 if (dd_data->context_un.mbox.outWxtWLen) { 2417 /* copy the extended data if any, count is in words */
2409 from = (uint8_t *)dd_data->context_un.mbox.ext; 2418 if (dd_data->context_un.mbox.outExtWLen) {
2410 to += sizeof(MAILBOX_t); 2419 from = (uint8_t *)dd_data->context_un.mbox.ext;
2411 memcpy(to, from, 2420 to += sizeof(MAILBOX_t);
2412 dd_data->context_un.mbox.outWxtWLen * sizeof(uint32_t)); 2421 size = dd_data->context_un.mbox.outExtWLen *
2422 sizeof(uint32_t);
2423 memcpy(to, from, size);
2424 } else if (pmboxq->u.mb.mbxCommand == MBX_RUN_BIU_DIAG64) {
2425 from = (uint8_t *)dd_data->context_un.mbox.
2426 dmp->dma.virt;
2427 to += sizeof(MAILBOX_t);
2428 size = dd_data->context_un.mbox.dmp->size;
2429 memcpy(to, from, size);
2430 } else if ((phba->sli_rev == LPFC_SLI_REV4) &&
2431 (pmboxq->u.mb.mbxCommand == MBX_DUMP_MEMORY)) {
2432 from = (uint8_t *)dd_data->context_un.mbox.dmp->dma.
2433 virt;
2434 to += sizeof(MAILBOX_t);
2435 size = pmboxq->u.mb.un.varWords[5];
2436 memcpy(to, from, size);
2437 } else if (pmboxq->u.mb.mbxCommand == MBX_READ_EVENT_LOG) {
2438 from = (uint8_t *)dd_data->context_un.
2439 mbox.dmp->dma.virt;
2440 to += sizeof(MAILBOX_t);
2441 size = dd_data->context_un.mbox.dmp->size;
2442 memcpy(to, from, size);
2443 }
2413 } 2444 }
2414 2445
2415 from = (uint8_t *)dd_data->context_un.mbox.mb; 2446 from = (uint8_t *)dd_data->context_un.mbox.mb;
@@ -2503,6 +2534,7 @@ static int lpfc_bsg_check_cmd_access(struct lpfc_hba *phba,
2503 case MBX_SET_DEBUG: 2534 case MBX_SET_DEBUG:
2504 case MBX_WRITE_WWN: 2535 case MBX_WRITE_WWN:
2505 case MBX_SLI4_CONFIG: 2536 case MBX_SLI4_CONFIG:
2537 case MBX_READ_EVENT_LOG:
2506 case MBX_READ_EVENT_LOG_STATUS: 2538 case MBX_READ_EVENT_LOG_STATUS:
2507 case MBX_WRITE_EVENT_LOG: 2539 case MBX_WRITE_EVENT_LOG:
2508 case MBX_PORT_CAPABILITIES: 2540 case MBX_PORT_CAPABILITIES:
@@ -2522,7 +2554,6 @@ static int lpfc_bsg_check_cmd_access(struct lpfc_hba *phba,
2522 phba->fc_topology = TOPOLOGY_PT_PT; 2554 phba->fc_topology = TOPOLOGY_PT_PT;
2523 } 2555 }
2524 break; 2556 break;
2525 case MBX_READ_EVENT_LOG:
2526 case MBX_READ_SPARM64: 2557 case MBX_READ_SPARM64:
2527 case MBX_READ_LA: 2558 case MBX_READ_LA:
2528 case MBX_READ_LA64: 2559 case MBX_READ_LA64:
@@ -2577,7 +2608,7 @@ lpfc_bsg_issue_mbox(struct lpfc_hba *phba, struct fc_bsg_job *job,
2577 2608
2578 /* check if requested extended data lengths are valid */ 2609 /* check if requested extended data lengths are valid */
2579 if ((mbox_req->inExtWLen > MAILBOX_EXT_SIZE) || 2610 if ((mbox_req->inExtWLen > MAILBOX_EXT_SIZE) ||
2580 (mbox_req->outWxtWLen > MAILBOX_EXT_SIZE)) { 2611 (mbox_req->outExtWLen > MAILBOX_EXT_SIZE)) {
2581 rc = -ERANGE; 2612 rc = -ERANGE;
2582 goto job_done; 2613 goto job_done;
2583 } 2614 }
@@ -2618,8 +2649,29 @@ lpfc_bsg_issue_mbox(struct lpfc_hba *phba, struct fc_bsg_job *job,
2618 pmb->mbxOwner = OWN_HOST; 2649 pmb->mbxOwner = OWN_HOST;
2619 pmboxq->vport = vport; 2650 pmboxq->vport = vport;
2620 2651
2652 /* If HBA encountered an error attention, allow only DUMP
2653 * or RESTART mailbox commands until the HBA is restarted.
2654 */
2655 if (phba->pport->stopped &&
2656 pmb->mbxCommand != MBX_DUMP_MEMORY &&
2657 pmb->mbxCommand != MBX_RESTART &&
2658 pmb->mbxCommand != MBX_WRITE_VPARMS &&
2659 pmb->mbxCommand != MBX_WRITE_WWN)
2660 lpfc_printf_log(phba, KERN_WARNING, LOG_MBOX,
2661 "2797 mbox: Issued mailbox cmd "
2662 "0x%x while in stopped state.\n",
2663 pmb->mbxCommand);
2664
2665 /* Don't allow mailbox commands to be sent when blocked
2666 * or when in the middle of discovery
2667 */
2668 if (phba->sli.sli_flag & LPFC_BLOCK_MGMT_IO) {
2669 rc = -EAGAIN;
2670 goto job_done;
2671 }
2672
2621 /* extended mailbox commands will need an extended buffer */ 2673 /* extended mailbox commands will need an extended buffer */
2622 if (mbox_req->inExtWLen || mbox_req->outWxtWLen) { 2674 if (mbox_req->inExtWLen || mbox_req->outExtWLen) {
2623 ext = kzalloc(MAILBOX_EXT_SIZE, GFP_KERNEL); 2675 ext = kzalloc(MAILBOX_EXT_SIZE, GFP_KERNEL);
2624 if (!ext) { 2676 if (!ext) {
2625 rc = -ENOMEM; 2677 rc = -ENOMEM;
@@ -2639,7 +2691,7 @@ lpfc_bsg_issue_mbox(struct lpfc_hba *phba, struct fc_bsg_job *job,
2639 mbox_req->inExtWLen * 2691 mbox_req->inExtWLen *
2640 sizeof(uint32_t); 2692 sizeof(uint32_t);
2641 pmboxq->out_ext_byte_len = 2693 pmboxq->out_ext_byte_len =
2642 mbox_req->outWxtWLen * 2694 mbox_req->outExtWLen *
2643 sizeof(uint32_t); 2695 sizeof(uint32_t);
2644 pmboxq->mbox_offset_word = 2696 pmboxq->mbox_offset_word =
2645 mbox_req->mbOffset; 2697 mbox_req->mbOffset;
@@ -2647,7 +2699,7 @@ lpfc_bsg_issue_mbox(struct lpfc_hba *phba, struct fc_bsg_job *job,
2647 pmboxq->in_ext_byte_len = 2699 pmboxq->in_ext_byte_len =
2648 mbox_req->inExtWLen * sizeof(uint32_t); 2700 mbox_req->inExtWLen * sizeof(uint32_t);
2649 pmboxq->out_ext_byte_len = 2701 pmboxq->out_ext_byte_len =
2650 mbox_req->outWxtWLen * sizeof(uint32_t); 2702 mbox_req->outExtWLen * sizeof(uint32_t);
2651 pmboxq->mbox_offset_word = mbox_req->mbOffset; 2703 pmboxq->mbox_offset_word = mbox_req->mbOffset;
2652 } 2704 }
2653 2705
@@ -2656,6 +2708,17 @@ lpfc_bsg_issue_mbox(struct lpfc_hba *phba, struct fc_bsg_job *job,
2656 * use ours 2708 * use ours
2657 */ 2709 */
2658 if (pmb->mbxCommand == MBX_RUN_BIU_DIAG64) { 2710 if (pmb->mbxCommand == MBX_RUN_BIU_DIAG64) {
2711 uint32_t transmit_length = pmb->un.varWords[1];
2712 uint32_t receive_length = pmb->un.varWords[4];
2713 /* transmit length cannot be greater than receive length or
2714 * mailbox extension size
2715 */
2716 if ((transmit_length > receive_length) ||
2717 (transmit_length > MAILBOX_EXT_SIZE)) {
2718 rc = -ERANGE;
2719 goto job_done;
2720 }
2721
2659 rxbmp = kmalloc(sizeof(struct lpfc_dmabuf), GFP_KERNEL); 2722 rxbmp = kmalloc(sizeof(struct lpfc_dmabuf), GFP_KERNEL);
2660 if (!rxbmp) { 2723 if (!rxbmp) {
2661 rc = -ENOMEM; 2724 rc = -ENOMEM;
@@ -2663,9 +2726,14 @@ lpfc_bsg_issue_mbox(struct lpfc_hba *phba, struct fc_bsg_job *job,
2663 } 2726 }
2664 2727
2665 rxbmp->virt = lpfc_mbuf_alloc(phba, 0, &rxbmp->phys); 2728 rxbmp->virt = lpfc_mbuf_alloc(phba, 0, &rxbmp->phys);
2729 if (!rxbmp->virt) {
2730 rc = -ENOMEM;
2731 goto job_done;
2732 }
2733
2666 INIT_LIST_HEAD(&rxbmp->list); 2734 INIT_LIST_HEAD(&rxbmp->list);
2667 rxbpl = (struct ulp_bde64 *) rxbmp->virt; 2735 rxbpl = (struct ulp_bde64 *) rxbmp->virt;
2668 dmp = diag_cmd_data_alloc(phba, rxbpl, BSG_MBOX_SIZE, 0); 2736 dmp = diag_cmd_data_alloc(phba, rxbpl, transmit_length, 0);
2669 if (!dmp) { 2737 if (!dmp) {
2670 rc = -ENOMEM; 2738 rc = -ENOMEM;
2671 goto job_done; 2739 goto job_done;
@@ -2685,13 +2753,143 @@ lpfc_bsg_issue_mbox(struct lpfc_hba *phba, struct fc_bsg_job *job,
2685 putPaddrLow(dmp->dma.phys + 2753 putPaddrLow(dmp->dma.phys +
2686 pmb->un.varBIUdiag.un.s2. 2754 pmb->un.varBIUdiag.un.s2.
2687 xmit_bde64.tus.f.bdeSize); 2755 xmit_bde64.tus.f.bdeSize);
2688 dd_data->context_un.mbox.rxbmp = rxbmp; 2756
2689 dd_data->context_un.mbox.dmp = dmp; 2757 /* copy the transmit data found in the mailbox extension area */
2690 } else { 2758 from = (uint8_t *)mb;
2691 dd_data->context_un.mbox.rxbmp = NULL; 2759 from += sizeof(MAILBOX_t);
2692 dd_data->context_un.mbox.dmp = NULL; 2760 memcpy((uint8_t *)dmp->dma.virt, from, transmit_length);
2761 } else if (pmb->mbxCommand == MBX_READ_EVENT_LOG) {
2762 struct READ_EVENT_LOG_VAR *rdEventLog =
2763 &pmb->un.varRdEventLog ;
2764 uint32_t receive_length = rdEventLog->rcv_bde64.tus.f.bdeSize;
2765 uint32_t mode = bf_get(lpfc_event_log, rdEventLog);
2766
2767 /* receive length cannot be greater than mailbox
2768 * extension size
2769 */
2770 if (receive_length > MAILBOX_EXT_SIZE) {
2771 rc = -ERANGE;
2772 goto job_done;
2773 }
2774
2775 /* mode zero uses a bde like biu diags command */
2776 if (mode == 0) {
2777
2778 /* rebuild the command for sli4 using our own buffers
2779 * like we do for biu diags
2780 */
2781
2782 rxbmp = kmalloc(sizeof(struct lpfc_dmabuf), GFP_KERNEL);
2783 if (!rxbmp) {
2784 rc = -ENOMEM;
2785 goto job_done;
2786 }
2787
2788 rxbmp->virt = lpfc_mbuf_alloc(phba, 0, &rxbmp->phys);
2789 rxbpl = (struct ulp_bde64 *) rxbmp->virt;
2790 if (rxbpl) {
2791 INIT_LIST_HEAD(&rxbmp->list);
2792 dmp = diag_cmd_data_alloc(phba, rxbpl,
2793 receive_length, 0);
2794 }
2795
2796 if (!dmp) {
2797 rc = -ENOMEM;
2798 goto job_done;
2799 }
2800
2801 INIT_LIST_HEAD(&dmp->dma.list);
2802 pmb->un.varWords[3] = putPaddrLow(dmp->dma.phys);
2803 pmb->un.varWords[4] = putPaddrHigh(dmp->dma.phys);
2804 }
2805 } else if (phba->sli_rev == LPFC_SLI_REV4) {
2806 if (pmb->mbxCommand == MBX_DUMP_MEMORY) {
2807 /* rebuild the command for sli4 using our own buffers
2808 * like we do for biu diags
2809 */
2810 uint32_t receive_length = pmb->un.varWords[2];
2811 /* receive length cannot be greater than mailbox
2812 * extension size
2813 */
2814 if ((receive_length == 0) ||
2815 (receive_length > MAILBOX_EXT_SIZE)) {
2816 rc = -ERANGE;
2817 goto job_done;
2818 }
2819
2820 rxbmp = kmalloc(sizeof(struct lpfc_dmabuf), GFP_KERNEL);
2821 if (!rxbmp) {
2822 rc = -ENOMEM;
2823 goto job_done;
2824 }
2825
2826 rxbmp->virt = lpfc_mbuf_alloc(phba, 0, &rxbmp->phys);
2827 if (!rxbmp->virt) {
2828 rc = -ENOMEM;
2829 goto job_done;
2830 }
2831
2832 INIT_LIST_HEAD(&rxbmp->list);
2833 rxbpl = (struct ulp_bde64 *) rxbmp->virt;
2834 dmp = diag_cmd_data_alloc(phba, rxbpl, receive_length,
2835 0);
2836 if (!dmp) {
2837 rc = -ENOMEM;
2838 goto job_done;
2839 }
2840
2841 INIT_LIST_HEAD(&dmp->dma.list);
2842 pmb->un.varWords[3] = putPaddrLow(dmp->dma.phys);
2843 pmb->un.varWords[4] = putPaddrHigh(dmp->dma.phys);
2844 } else if ((pmb->mbxCommand == MBX_UPDATE_CFG) &&
2845 pmb->un.varUpdateCfg.co) {
2846 struct ulp_bde64 *bde =
2847 (struct ulp_bde64 *)&pmb->un.varWords[4];
2848
2849 /* bde size cannot be greater than mailbox ext size */
2850 if (bde->tus.f.bdeSize > MAILBOX_EXT_SIZE) {
2851 rc = -ERANGE;
2852 goto job_done;
2853 }
2854
2855 rxbmp = kmalloc(sizeof(struct lpfc_dmabuf), GFP_KERNEL);
2856 if (!rxbmp) {
2857 rc = -ENOMEM;
2858 goto job_done;
2859 }
2860
2861 rxbmp->virt = lpfc_mbuf_alloc(phba, 0, &rxbmp->phys);
2862 if (!rxbmp->virt) {
2863 rc = -ENOMEM;
2864 goto job_done;
2865 }
2866
2867 INIT_LIST_HEAD(&rxbmp->list);
2868 rxbpl = (struct ulp_bde64 *) rxbmp->virt;
2869 dmp = diag_cmd_data_alloc(phba, rxbpl,
2870 bde->tus.f.bdeSize, 0);
2871 if (!dmp) {
2872 rc = -ENOMEM;
2873 goto job_done;
2874 }
2875
2876 INIT_LIST_HEAD(&dmp->dma.list);
2877 bde->addrHigh = putPaddrHigh(dmp->dma.phys);
2878 bde->addrLow = putPaddrLow(dmp->dma.phys);
2879
2880 /* copy the transmit data found in the mailbox
2881 * extension area
2882 */
2883 from = (uint8_t *)mb;
2884 from += sizeof(MAILBOX_t);
2885 memcpy((uint8_t *)dmp->dma.virt, from,
2886 bde->tus.f.bdeSize);
2887 }
2693 } 2888 }
2694 2889
2890 dd_data->context_un.mbox.rxbmp = rxbmp;
2891 dd_data->context_un.mbox.dmp = dmp;
2892
2695 /* setup wake call as IOCB callback */ 2893 /* setup wake call as IOCB callback */
2696 pmboxq->mbox_cmpl = lpfc_bsg_wake_mbox_wait; 2894 pmboxq->mbox_cmpl = lpfc_bsg_wake_mbox_wait;
2697 2895
@@ -2704,7 +2902,7 @@ lpfc_bsg_issue_mbox(struct lpfc_hba *phba, struct fc_bsg_job *job,
2704 dd_data->context_un.mbox.ext = ext; 2902 dd_data->context_un.mbox.ext = ext;
2705 dd_data->context_un.mbox.mbOffset = mbox_req->mbOffset; 2903 dd_data->context_un.mbox.mbOffset = mbox_req->mbOffset;
2706 dd_data->context_un.mbox.inExtWLen = mbox_req->inExtWLen; 2904 dd_data->context_un.mbox.inExtWLen = mbox_req->inExtWLen;
2707 dd_data->context_un.mbox.outWxtWLen = mbox_req->outWxtWLen; 2905 dd_data->context_un.mbox.outExtWLen = mbox_req->outExtWLen;
2708 job->dd_data = dd_data; 2906 job->dd_data = dd_data;
2709 2907
2710 if ((vport->fc_flag & FC_OFFLINE_MODE) || 2908 if ((vport->fc_flag & FC_OFFLINE_MODE) ||
diff --git a/drivers/scsi/lpfc/lpfc_bsg.h b/drivers/scsi/lpfc/lpfc_bsg.h
index 2d98689dd693..a2c33e7c9152 100644
--- a/drivers/scsi/lpfc/lpfc_bsg.h
+++ b/drivers/scsi/lpfc/lpfc_bsg.h
@@ -96,7 +96,7 @@ struct dfc_mbox_req {
96 uint32_t command; 96 uint32_t command;
97 uint32_t mbOffset; 97 uint32_t mbOffset;
98 uint32_t inExtWLen; 98 uint32_t inExtWLen;
99 uint32_t outWxtWLen; 99 uint32_t outExtWLen;
100}; 100};
101 101
102/* Used for menlo command or menlo data. The xri is only used for menlo data */ 102/* Used for menlo command or menlo data. The xri is only used for menlo data */
diff --git a/drivers/scsi/lpfc/lpfc_hw.h b/drivers/scsi/lpfc/lpfc_hw.h
index 0cf9a2bd3469..e654d01dad24 100644
--- a/drivers/scsi/lpfc/lpfc_hw.h
+++ b/drivers/scsi/lpfc/lpfc_hw.h
@@ -1732,6 +1732,17 @@ typedef struct {
1732 } un; 1732 } un;
1733} BIU_DIAG_VAR; 1733} BIU_DIAG_VAR;
1734 1734
1735/* Structure for MB command READ_EVENT_LOG (0x38) */
1736struct READ_EVENT_LOG_VAR {
1737 uint32_t word1;
1738#define lpfc_event_log_SHIFT 29
1739#define lpfc_event_log_MASK 0x00000001
1740#define lpfc_event_log_WORD word1
1741#define USE_MAILBOX_RESPONSE 1
1742 uint32_t offset;
1743 struct ulp_bde64 rcv_bde64;
1744};
1745
1735/* Structure for MB Command INIT_LINK (05) */ 1746/* Structure for MB Command INIT_LINK (05) */
1736 1747
1737typedef struct { 1748typedef struct {
@@ -2966,6 +2977,9 @@ typedef union {
2966 REG_VPI_VAR varRegVpi; /* cmd = 0x96 (REG_VPI) */ 2977 REG_VPI_VAR varRegVpi; /* cmd = 0x96 (REG_VPI) */
2967 UNREG_VPI_VAR varUnregVpi; /* cmd = 0x97 (UNREG_VPI) */ 2978 UNREG_VPI_VAR varUnregVpi; /* cmd = 0x97 (UNREG_VPI) */
2968 ASYNCEVT_ENABLE_VAR varCfgAsyncEvent; /*cmd = x33 (CONFIG_ASYNC) */ 2979 ASYNCEVT_ENABLE_VAR varCfgAsyncEvent; /*cmd = x33 (CONFIG_ASYNC) */
2980 struct READ_EVENT_LOG_VAR varRdEventLog; /* cmd = 0x38
2981 * (READ_EVENT_LOG)
2982 */
2969 struct config_msi_var varCfgMSI;/* cmd = x30 (CONFIG_MSI) */ 2983 struct config_msi_var varCfgMSI;/* cmd = x30 (CONFIG_MSI) */
2970} MAILVARIANTS; 2984} MAILVARIANTS;
2971 2985
diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c
index 73259bca1d14..1ab7937097a4 100644
--- a/drivers/scsi/lpfc/lpfc_sli.c
+++ b/drivers/scsi/lpfc/lpfc_sli.c
@@ -1659,6 +1659,8 @@ lpfc_sli_chk_mbx_command(uint8_t mbxCommand)
1659 case MBX_INIT_VPI: 1659 case MBX_INIT_VPI:
1660 case MBX_INIT_VFI: 1660 case MBX_INIT_VFI:
1661 case MBX_RESUME_RPI: 1661 case MBX_RESUME_RPI:
1662 case MBX_READ_EVENT_LOG_STATUS:
1663 case MBX_READ_EVENT_LOG:
1662 ret = mbxCommand; 1664 ret = mbxCommand;
1663 break; 1665 break;
1664 default: 1666 default: