.. | .. |
---|
1 | 1 | /******************************************************************* |
---|
2 | 2 | * This file is part of the Emulex Linux Device Driver for * |
---|
3 | 3 | * Fibre Channel Host Bus Adapters. * |
---|
4 | | - * Copyright (C) 2017-2018 Broadcom. All Rights Reserved. The term * |
---|
| 4 | + * Copyright (C) 2017-2019 Broadcom. All Rights Reserved. The term * |
---|
5 | 5 | * “Broadcom” refers to Broadcom Inc. and/or its subsidiaries. * |
---|
6 | 6 | * Copyright (C) 2009-2015 Emulex. All rights reserved. * |
---|
7 | 7 | * EMULEX and SLI are trademarks of Emulex. * |
---|
.. | .. |
---|
27 | 27 | #include <linux/delay.h> |
---|
28 | 28 | #include <linux/list.h> |
---|
29 | 29 | #include <linux/bsg-lib.h> |
---|
| 30 | +#include <linux/vmalloc.h> |
---|
30 | 31 | |
---|
31 | 32 | #include <scsi/scsi.h> |
---|
32 | 33 | #include <scsi/scsi_host.h> |
---|
.. | .. |
---|
1039 | 1040 | if (!dmabuf) { |
---|
1040 | 1041 | lpfc_printf_log(phba, KERN_ERR, |
---|
1041 | 1042 | LOG_LIBDFC, "2616 No dmabuf " |
---|
1042 | | - "found for iocbq 0x%p\n", |
---|
| 1043 | + "found for iocbq x%px\n", |
---|
1043 | 1044 | iocbq); |
---|
1044 | 1045 | kfree(evt_dat->data); |
---|
1045 | 1046 | kfree(evt_dat); |
---|
.. | .. |
---|
1275 | 1276 | return 0; /* call job done later */ |
---|
1276 | 1277 | |
---|
1277 | 1278 | job_error: |
---|
1278 | | - if (dd_data != NULL) |
---|
1279 | | - kfree(dd_data); |
---|
1280 | | - |
---|
| 1279 | + kfree(dd_data); |
---|
1281 | 1280 | job->dd_data = NULL; |
---|
1282 | 1281 | return rc; |
---|
1283 | 1282 | } |
---|
.. | .. |
---|
1570 | 1569 | "2722 Xmit CT response on exchange x%x Data: x%x x%x x%x\n", |
---|
1571 | 1570 | icmd->ulpContext, icmd->ulpIoTag, tag, phba->link_state); |
---|
1572 | 1571 | |
---|
1573 | | - ctiocb->iocb_cmpl = NULL; |
---|
1574 | 1572 | ctiocb->iocb_flag |= LPFC_IO_LIBDFC; |
---|
1575 | 1573 | ctiocb->vport = phba->pport; |
---|
1576 | 1574 | ctiocb->context1 = dd_data; |
---|
.. | .. |
---|
1967 | 1965 | } |
---|
1968 | 1966 | |
---|
1969 | 1967 | /** |
---|
1970 | | - * lpfc_sli4_bsg_set_internal_loopback - set sli4 internal loopback diagnostic |
---|
| 1968 | + * lpfc_sli4_bsg_set_loopback_mode - set sli4 internal loopback diagnostic |
---|
1971 | 1969 | * @phba: Pointer to HBA context object. |
---|
| 1970 | + * @mode: loopback mode to set |
---|
| 1971 | + * @link_no: link number for loopback mode to set |
---|
1972 | 1972 | * |
---|
1973 | 1973 | * This function is responsible for issuing a sli4 mailbox command for setting |
---|
1974 | | - * up internal loopback diagnostic. |
---|
| 1974 | + * up loopback diagnostic for a link. |
---|
1975 | 1975 | */ |
---|
1976 | 1976 | static int |
---|
1977 | | -lpfc_sli4_bsg_set_internal_loopback(struct lpfc_hba *phba) |
---|
| 1977 | +lpfc_sli4_bsg_set_loopback_mode(struct lpfc_hba *phba, int mode, |
---|
| 1978 | + uint32_t link_no) |
---|
1978 | 1979 | { |
---|
1979 | 1980 | LPFC_MBOXQ_t *pmboxq; |
---|
1980 | 1981 | uint32_t req_len, alloc_len; |
---|
.. | .. |
---|
1995 | 1996 | } |
---|
1996 | 1997 | link_diag_loopback = &pmboxq->u.mqe.un.link_diag_loopback; |
---|
1997 | 1998 | bf_set(lpfc_mbx_set_diag_state_link_num, |
---|
1998 | | - &link_diag_loopback->u.req, phba->sli4_hba.lnk_info.lnk_no); |
---|
1999 | | - bf_set(lpfc_mbx_set_diag_state_link_type, |
---|
2000 | | - &link_diag_loopback->u.req, phba->sli4_hba.lnk_info.lnk_tp); |
---|
| 1999 | + &link_diag_loopback->u.req, link_no); |
---|
| 2000 | + |
---|
| 2001 | + if (phba->sli4_hba.conf_trunk & (1 << link_no)) { |
---|
| 2002 | + bf_set(lpfc_mbx_set_diag_state_link_type, |
---|
| 2003 | + &link_diag_loopback->u.req, LPFC_LNK_FC_TRUNKED); |
---|
| 2004 | + } else { |
---|
| 2005 | + bf_set(lpfc_mbx_set_diag_state_link_type, |
---|
| 2006 | + &link_diag_loopback->u.req, |
---|
| 2007 | + phba->sli4_hba.lnk_info.lnk_tp); |
---|
| 2008 | + } |
---|
| 2009 | + |
---|
2001 | 2010 | bf_set(lpfc_mbx_set_diag_lpbk_type, &link_diag_loopback->u.req, |
---|
2002 | | - LPFC_DIAG_LOOPBACK_TYPE_INTERNAL); |
---|
| 2011 | + mode); |
---|
2003 | 2012 | |
---|
2004 | 2013 | mbxstatus = lpfc_sli_issue_mbox_wait(phba, pmboxq, LPFC_MBOX_TMO); |
---|
2005 | 2014 | if ((mbxstatus != MBX_SUCCESS) || (pmboxq->u.mb.mbxStatus)) { |
---|
.. | .. |
---|
2053 | 2062 | struct fc_bsg_request *bsg_request = job->request; |
---|
2054 | 2063 | struct fc_bsg_reply *bsg_reply = job->reply; |
---|
2055 | 2064 | struct diag_mode_set *loopback_mode; |
---|
2056 | | - uint32_t link_flags, timeout; |
---|
| 2065 | + uint32_t link_flags, timeout, link_no; |
---|
2057 | 2066 | int i, rc = 0; |
---|
2058 | 2067 | |
---|
2059 | 2068 | /* no data to return just the return code */ |
---|
.. | .. |
---|
2068 | 2077 | (int)(sizeof(struct fc_bsg_request) + |
---|
2069 | 2078 | sizeof(struct diag_mode_set))); |
---|
2070 | 2079 | rc = -EINVAL; |
---|
2071 | | - goto job_error; |
---|
| 2080 | + goto job_done; |
---|
| 2081 | + } |
---|
| 2082 | + |
---|
| 2083 | + loopback_mode = (struct diag_mode_set *) |
---|
| 2084 | + bsg_request->rqst_data.h_vendor.vendor_cmd; |
---|
| 2085 | + link_flags = loopback_mode->type; |
---|
| 2086 | + timeout = loopback_mode->timeout * 100; |
---|
| 2087 | + |
---|
| 2088 | + if (loopback_mode->physical_link == -1) |
---|
| 2089 | + link_no = phba->sli4_hba.lnk_info.lnk_no; |
---|
| 2090 | + else |
---|
| 2091 | + link_no = loopback_mode->physical_link; |
---|
| 2092 | + |
---|
| 2093 | + if (link_flags == DISABLE_LOOP_BACK) { |
---|
| 2094 | + rc = lpfc_sli4_bsg_set_loopback_mode(phba, |
---|
| 2095 | + LPFC_DIAG_LOOPBACK_TYPE_DISABLE, |
---|
| 2096 | + link_no); |
---|
| 2097 | + if (!rc) { |
---|
| 2098 | + /* Unset the need disable bit */ |
---|
| 2099 | + phba->sli4_hba.conf_trunk &= ~((1 << link_no) << 4); |
---|
| 2100 | + } |
---|
| 2101 | + goto job_done; |
---|
| 2102 | + } else { |
---|
| 2103 | + /* Check if we need to disable the loopback state */ |
---|
| 2104 | + if (phba->sli4_hba.conf_trunk & ((1 << link_no) << 4)) { |
---|
| 2105 | + rc = -EPERM; |
---|
| 2106 | + goto job_done; |
---|
| 2107 | + } |
---|
2072 | 2108 | } |
---|
2073 | 2109 | |
---|
2074 | 2110 | rc = lpfc_bsg_diag_mode_enter(phba); |
---|
2075 | 2111 | if (rc) |
---|
2076 | | - goto job_error; |
---|
| 2112 | + goto job_done; |
---|
2077 | 2113 | |
---|
2078 | 2114 | /* indicate we are in loobpack diagnostic mode */ |
---|
2079 | 2115 | spin_lock_irq(&phba->hbalock); |
---|
.. | .. |
---|
2083 | 2119 | /* reset port to start frome scratch */ |
---|
2084 | 2120 | rc = lpfc_selective_reset(phba); |
---|
2085 | 2121 | if (rc) |
---|
2086 | | - goto job_error; |
---|
| 2122 | + goto job_done; |
---|
2087 | 2123 | |
---|
2088 | 2124 | /* bring the link to diagnostic mode */ |
---|
2089 | 2125 | lpfc_printf_log(phba, KERN_INFO, LOG_LIBDFC, |
---|
2090 | 2126 | "3129 Bring link to diagnostic state.\n"); |
---|
2091 | | - loopback_mode = (struct diag_mode_set *) |
---|
2092 | | - bsg_request->rqst_data.h_vendor.vendor_cmd; |
---|
2093 | | - link_flags = loopback_mode->type; |
---|
2094 | | - timeout = loopback_mode->timeout * 100; |
---|
2095 | 2127 | |
---|
2096 | 2128 | rc = lpfc_sli4_bsg_set_link_diag_state(phba, 1); |
---|
2097 | 2129 | if (rc) { |
---|
.. | .. |
---|
2119 | 2151 | lpfc_printf_log(phba, KERN_INFO, LOG_LIBDFC, |
---|
2120 | 2152 | "3132 Set up loopback mode:x%x\n", link_flags); |
---|
2121 | 2153 | |
---|
2122 | | - if (link_flags == INTERNAL_LOOP_BACK) |
---|
2123 | | - rc = lpfc_sli4_bsg_set_internal_loopback(phba); |
---|
2124 | | - else if (link_flags == EXTERNAL_LOOP_BACK) |
---|
2125 | | - rc = lpfc_hba_init_link_fc_topology(phba, |
---|
2126 | | - FLAGS_TOPOLOGY_MODE_PT_PT, |
---|
2127 | | - MBX_NOWAIT); |
---|
2128 | | - else { |
---|
| 2154 | + switch (link_flags) { |
---|
| 2155 | + case INTERNAL_LOOP_BACK: |
---|
| 2156 | + if (phba->sli4_hba.conf_trunk & (1 << link_no)) { |
---|
| 2157 | + rc = lpfc_sli4_bsg_set_loopback_mode(phba, |
---|
| 2158 | + LPFC_DIAG_LOOPBACK_TYPE_INTERNAL, |
---|
| 2159 | + link_no); |
---|
| 2160 | + } else { |
---|
| 2161 | + /* Trunk is configured, but link is not in this trunk */ |
---|
| 2162 | + if (phba->sli4_hba.conf_trunk) { |
---|
| 2163 | + rc = -ELNRNG; |
---|
| 2164 | + goto loopback_mode_exit; |
---|
| 2165 | + } |
---|
| 2166 | + |
---|
| 2167 | + rc = lpfc_sli4_bsg_set_loopback_mode(phba, |
---|
| 2168 | + LPFC_DIAG_LOOPBACK_TYPE_INTERNAL, |
---|
| 2169 | + link_no); |
---|
| 2170 | + } |
---|
| 2171 | + |
---|
| 2172 | + if (!rc) { |
---|
| 2173 | + /* Set the need disable bit */ |
---|
| 2174 | + phba->sli4_hba.conf_trunk |= (1 << link_no) << 4; |
---|
| 2175 | + } |
---|
| 2176 | + |
---|
| 2177 | + break; |
---|
| 2178 | + case EXTERNAL_LOOP_BACK: |
---|
| 2179 | + if (phba->sli4_hba.conf_trunk & (1 << link_no)) { |
---|
| 2180 | + rc = lpfc_sli4_bsg_set_loopback_mode(phba, |
---|
| 2181 | + LPFC_DIAG_LOOPBACK_TYPE_EXTERNAL_TRUNKED, |
---|
| 2182 | + link_no); |
---|
| 2183 | + } else { |
---|
| 2184 | + /* Trunk is configured, but link is not in this trunk */ |
---|
| 2185 | + if (phba->sli4_hba.conf_trunk) { |
---|
| 2186 | + rc = -ELNRNG; |
---|
| 2187 | + goto loopback_mode_exit; |
---|
| 2188 | + } |
---|
| 2189 | + |
---|
| 2190 | + rc = lpfc_sli4_bsg_set_loopback_mode(phba, |
---|
| 2191 | + LPFC_DIAG_LOOPBACK_TYPE_SERDES, |
---|
| 2192 | + link_no); |
---|
| 2193 | + } |
---|
| 2194 | + |
---|
| 2195 | + if (!rc) { |
---|
| 2196 | + /* Set the need disable bit */ |
---|
| 2197 | + phba->sli4_hba.conf_trunk |= (1 << link_no) << 4; |
---|
| 2198 | + } |
---|
| 2199 | + |
---|
| 2200 | + break; |
---|
| 2201 | + default: |
---|
2129 | 2202 | rc = -EINVAL; |
---|
2130 | 2203 | lpfc_printf_log(phba, KERN_ERR, LOG_LIBDFC, |
---|
2131 | 2204 | "3141 Loopback mode:x%x not supported\n", |
---|
.. | .. |
---|
2184 | 2257 | } |
---|
2185 | 2258 | lpfc_bsg_diag_mode_exit(phba); |
---|
2186 | 2259 | |
---|
2187 | | -job_error: |
---|
| 2260 | +job_done: |
---|
2188 | 2261 | /* make error code available to userspace */ |
---|
2189 | 2262 | bsg_reply->result = rc; |
---|
2190 | 2263 | /* complete the job back to userspace if no error */ |
---|
.. | .. |
---|
2331 | 2404 | union lpfc_sli4_cfg_shdr *shdr; |
---|
2332 | 2405 | uint32_t shdr_status, shdr_add_status; |
---|
2333 | 2406 | struct diag_status *diag_status_reply; |
---|
2334 | | - int mbxstatus, rc = 0; |
---|
| 2407 | + int mbxstatus, rc = -ENODEV, rc1 = 0; |
---|
2335 | 2408 | |
---|
2336 | 2409 | shost = fc_bsg_to_shost(job); |
---|
2337 | | - if (!shost) { |
---|
2338 | | - rc = -ENODEV; |
---|
| 2410 | + if (!shost) |
---|
2339 | 2411 | goto job_error; |
---|
2340 | | - } |
---|
2341 | | - vport = shost_priv(shost); |
---|
2342 | | - if (!vport) { |
---|
2343 | | - rc = -ENODEV; |
---|
2344 | | - goto job_error; |
---|
2345 | | - } |
---|
2346 | | - phba = vport->phba; |
---|
2347 | | - if (!phba) { |
---|
2348 | | - rc = -ENODEV; |
---|
2349 | | - goto job_error; |
---|
2350 | | - } |
---|
2351 | 2412 | |
---|
2352 | | - if (phba->sli_rev < LPFC_SLI_REV4) { |
---|
2353 | | - rc = -ENODEV; |
---|
| 2413 | + vport = shost_priv(shost); |
---|
| 2414 | + if (!vport) |
---|
2354 | 2415 | goto job_error; |
---|
2355 | | - } |
---|
| 2416 | + |
---|
| 2417 | + phba = vport->phba; |
---|
| 2418 | + if (!phba) |
---|
| 2419 | + goto job_error; |
---|
| 2420 | + |
---|
| 2421 | + |
---|
| 2422 | + if (phba->sli_rev < LPFC_SLI_REV4) |
---|
| 2423 | + goto job_error; |
---|
| 2424 | + |
---|
2356 | 2425 | if (bf_get(lpfc_sli_intf_if_type, &phba->sli4_hba.sli_intf) < |
---|
2357 | | - LPFC_SLI_INTF_IF_TYPE_2) { |
---|
2358 | | - rc = -ENODEV; |
---|
| 2426 | + LPFC_SLI_INTF_IF_TYPE_2) |
---|
2359 | 2427 | goto job_error; |
---|
2360 | | - } |
---|
2361 | 2428 | |
---|
2362 | 2429 | if (job->request_len < sizeof(struct fc_bsg_request) + |
---|
2363 | 2430 | sizeof(struct sli4_link_diag)) { |
---|
.. | .. |
---|
2392 | 2459 | alloc_len = lpfc_sli4_config(phba, pmboxq, LPFC_MBOX_SUBSYSTEM_FCOE, |
---|
2393 | 2460 | LPFC_MBOX_OPCODE_FCOE_LINK_DIAG_STATE, |
---|
2394 | 2461 | req_len, LPFC_SLI4_MBX_EMBED); |
---|
2395 | | - if (alloc_len != req_len) |
---|
| 2462 | + if (alloc_len != req_len) { |
---|
| 2463 | + rc = -ENOMEM; |
---|
2396 | 2464 | goto link_diag_test_exit; |
---|
| 2465 | + } |
---|
2397 | 2466 | |
---|
2398 | 2467 | run_link_diag_test = &pmboxq->u.mqe.un.link_diag_test; |
---|
2399 | 2468 | bf_set(lpfc_mbx_run_diag_test_link_num, &run_link_diag_test->u.req, |
---|
.. | .. |
---|
2425 | 2494 | diag_status_reply = (struct diag_status *) |
---|
2426 | 2495 | bsg_reply->reply_data.vendor_reply.vendor_rsp; |
---|
2427 | 2496 | |
---|
2428 | | - if (job->reply_len < |
---|
2429 | | - sizeof(struct fc_bsg_request) + sizeof(struct diag_status)) { |
---|
| 2497 | + if (job->reply_len < sizeof(*bsg_reply) + sizeof(*diag_status_reply)) { |
---|
2430 | 2498 | lpfc_printf_log(phba, KERN_WARNING, LOG_LIBDFC, |
---|
2431 | 2499 | "3012 Received Run link diag test reply " |
---|
2432 | 2500 | "below minimum size (%d): reply_len:%d\n", |
---|
2433 | | - (int)(sizeof(struct fc_bsg_request) + |
---|
2434 | | - sizeof(struct diag_status)), |
---|
| 2501 | + (int)(sizeof(*bsg_reply) + |
---|
| 2502 | + sizeof(*diag_status_reply)), |
---|
2435 | 2503 | job->reply_len); |
---|
2436 | 2504 | rc = -EINVAL; |
---|
2437 | 2505 | goto job_error; |
---|
.. | .. |
---|
2442 | 2510 | diag_status_reply->shdr_add_status = shdr_add_status; |
---|
2443 | 2511 | |
---|
2444 | 2512 | link_diag_test_exit: |
---|
2445 | | - rc = lpfc_sli4_bsg_set_link_diag_state(phba, 0); |
---|
| 2513 | + rc1 = lpfc_sli4_bsg_set_link_diag_state(phba, 0); |
---|
2446 | 2514 | |
---|
2447 | 2515 | if (pmboxq) |
---|
2448 | 2516 | mempool_free(pmboxq, phba->mbox_mem_pool); |
---|
.. | .. |
---|
2451 | 2519 | |
---|
2452 | 2520 | job_error: |
---|
2453 | 2521 | /* make error code available to userspace */ |
---|
| 2522 | + if (rc1 && !rc) |
---|
| 2523 | + rc = rc1; |
---|
2454 | 2524 | bsg_reply->result = rc; |
---|
2455 | 2525 | /* complete the job back to userspace if no error */ |
---|
2456 | 2526 | if (rc == 0) |
---|
.. | .. |
---|
2500 | 2570 | return -ENOMEM; |
---|
2501 | 2571 | } |
---|
2502 | 2572 | |
---|
2503 | | - dmabuff = (struct lpfc_dmabuf *) mbox->context1; |
---|
2504 | | - mbox->context1 = NULL; |
---|
2505 | | - mbox->context2 = NULL; |
---|
| 2573 | + dmabuff = (struct lpfc_dmabuf *)mbox->ctx_buf; |
---|
| 2574 | + mbox->ctx_buf = NULL; |
---|
| 2575 | + mbox->ctx_ndlp = NULL; |
---|
2506 | 2576 | status = lpfc_sli_issue_mbox_wait(phba, mbox, LPFC_MBOX_TMO); |
---|
2507 | 2577 | |
---|
2508 | 2578 | if ((status != MBX_SUCCESS) || (mbox->u.mb.mbxStatus)) { |
---|
.. | .. |
---|
2729 | 2799 | INIT_LIST_HEAD(&dmabuf->list); |
---|
2730 | 2800 | |
---|
2731 | 2801 | /* now, allocate dma buffer */ |
---|
2732 | | - dmabuf->virt = dma_zalloc_coherent(&pcidev->dev, BSG_MBOX_SIZE, |
---|
2733 | | - &(dmabuf->phys), GFP_KERNEL); |
---|
| 2802 | + dmabuf->virt = dma_alloc_coherent(&pcidev->dev, BSG_MBOX_SIZE, |
---|
| 2803 | + &(dmabuf->phys), GFP_KERNEL); |
---|
2734 | 2804 | |
---|
2735 | 2805 | if (!dmabuf->virt) { |
---|
2736 | 2806 | kfree(dmabuf); |
---|
.. | .. |
---|
2843 | 2913 | |
---|
2844 | 2914 | if (nocopydata) { |
---|
2845 | 2915 | bpl->tus.f.bdeFlags = 0; |
---|
2846 | | - pci_dma_sync_single_for_device(phba->pcidev, |
---|
2847 | | - dmp->dma.phys, LPFC_BPL_SIZE, PCI_DMA_TODEVICE); |
---|
2848 | | - |
---|
2849 | 2916 | } else { |
---|
2850 | 2917 | memset((uint8_t *)dmp->dma.virt, 0, cnt); |
---|
2851 | 2918 | bpl->tus.f.bdeFlags = BUFF_TYPE_BDE_64I; |
---|
.. | .. |
---|
2949 | 3016 | cmd->un.cont64[i].addrLow = putPaddrLow(mp[i]->phys); |
---|
2950 | 3017 | cmd->un.cont64[i].tus.f.bdeSize = |
---|
2951 | 3018 | ((struct lpfc_dmabufext *)mp[i])->size; |
---|
2952 | | - cmd->ulpBdeCount = ++i; |
---|
| 3019 | + cmd->ulpBdeCount = ++i; |
---|
2953 | 3020 | |
---|
2954 | 3021 | if ((--num_bde > 0) && (i < 2)) |
---|
2955 | 3022 | continue; |
---|
.. | .. |
---|
3350 | 3417 | event_reply = (struct get_mgmt_rev_reply *) |
---|
3351 | 3418 | bsg_reply->reply_data.vendor_reply.vendor_rsp; |
---|
3352 | 3419 | |
---|
3353 | | - if (job->reply_len < |
---|
3354 | | - sizeof(struct fc_bsg_request) + sizeof(struct get_mgmt_rev_reply)) { |
---|
| 3420 | + if (job->reply_len < sizeof(*bsg_reply) + sizeof(*event_reply)) { |
---|
3355 | 3421 | lpfc_printf_log(phba, KERN_WARNING, LOG_LIBDFC, |
---|
3356 | 3422 | "2741 Received GET_DFC_REV reply below " |
---|
3357 | 3423 | "minimum size\n"); |
---|
.. | .. |
---|
3390 | 3456 | unsigned long flags; |
---|
3391 | 3457 | uint8_t *pmb, *pmb_buf; |
---|
3392 | 3458 | |
---|
3393 | | - dd_data = pmboxq->context1; |
---|
| 3459 | + dd_data = pmboxq->ctx_ndlp; |
---|
3394 | 3460 | |
---|
3395 | 3461 | /* |
---|
3396 | 3462 | * The outgoing buffer is readily referred from the dma buffer, |
---|
.. | .. |
---|
3575 | 3641 | struct lpfc_sli_config_mbox *sli_cfg_mbx; |
---|
3576 | 3642 | uint8_t *pmbx; |
---|
3577 | 3643 | |
---|
3578 | | - dd_data = pmboxq->context1; |
---|
| 3644 | + dd_data = pmboxq->ctx_buf; |
---|
3579 | 3645 | |
---|
3580 | 3646 | /* Determine if job has been aborted */ |
---|
3581 | 3647 | spin_lock_irqsave(&phba->ct_ev_lock, flags); |
---|
.. | .. |
---|
3962 | 4028 | pmboxq->mbox_cmpl = lpfc_bsg_issue_read_mbox_ext_cmpl; |
---|
3963 | 4029 | |
---|
3964 | 4030 | /* context fields to callback function */ |
---|
3965 | | - pmboxq->context1 = dd_data; |
---|
| 4031 | + pmboxq->ctx_buf = dd_data; |
---|
3966 | 4032 | dd_data->type = TYPE_MBOX; |
---|
3967 | 4033 | dd_data->set_job = job; |
---|
3968 | 4034 | dd_data->context_un.mbox.pmboxq = pmboxq; |
---|
.. | .. |
---|
4133 | 4199 | pmboxq->mbox_cmpl = lpfc_bsg_issue_write_mbox_ext_cmpl; |
---|
4134 | 4200 | |
---|
4135 | 4201 | /* context fields to callback function */ |
---|
4136 | | - pmboxq->context1 = dd_data; |
---|
| 4202 | + pmboxq->ctx_buf = dd_data; |
---|
4137 | 4203 | dd_data->type = TYPE_MBOX; |
---|
4138 | 4204 | dd_data->set_job = job; |
---|
4139 | 4205 | dd_data->context_un.mbox.pmboxq = pmboxq; |
---|
.. | .. |
---|
4236 | 4302 | case COMN_OPCODE_GET_CNTL_ADDL_ATTRIBUTES: |
---|
4237 | 4303 | case COMN_OPCODE_GET_CNTL_ATTRIBUTES: |
---|
4238 | 4304 | case COMN_OPCODE_GET_PROFILE_CONFIG: |
---|
| 4305 | + case COMN_OPCODE_SET_FEATURES: |
---|
4239 | 4306 | lpfc_printf_log(phba, KERN_INFO, LOG_LIBDFC, |
---|
4240 | 4307 | "3106 Handled SLI_CONFIG " |
---|
4241 | 4308 | "subsys_comn, opcode:x%x\n", |
---|
.. | .. |
---|
4479 | 4546 | pmboxq->mbox_cmpl = lpfc_bsg_issue_write_mbox_ext_cmpl; |
---|
4480 | 4547 | |
---|
4481 | 4548 | /* context fields to callback function */ |
---|
4482 | | - pmboxq->context1 = dd_data; |
---|
| 4549 | + pmboxq->ctx_buf = dd_data; |
---|
4483 | 4550 | dd_data->type = TYPE_MBOX; |
---|
4484 | 4551 | dd_data->set_job = job; |
---|
4485 | 4552 | dd_data->context_un.mbox.pmboxq = pmboxq; |
---|
.. | .. |
---|
4687 | 4754 | * Don't allow mailbox commands to be sent when blocked or when in |
---|
4688 | 4755 | * the middle of discovery |
---|
4689 | 4756 | */ |
---|
4690 | | - if (phba->sli.sli_flag & LPFC_BLOCK_MGMT_IO) { |
---|
| 4757 | + if (phba->sli.sli_flag & LPFC_BLOCK_MGMT_IO) { |
---|
4691 | 4758 | rc = -EAGAIN; |
---|
4692 | 4759 | goto job_done; |
---|
4693 | 4760 | } |
---|
.. | .. |
---|
4766 | 4833 | if (mbox_req->inExtWLen || mbox_req->outExtWLen) { |
---|
4767 | 4834 | from = pmbx; |
---|
4768 | 4835 | ext = from + sizeof(MAILBOX_t); |
---|
4769 | | - pmboxq->context2 = ext; |
---|
| 4836 | + pmboxq->ctx_buf = ext; |
---|
4770 | 4837 | pmboxq->in_ext_byte_len = |
---|
4771 | 4838 | mbox_req->inExtWLen * sizeof(uint32_t); |
---|
4772 | 4839 | pmboxq->out_ext_byte_len = |
---|
.. | .. |
---|
4894 | 4961 | pmboxq->mbox_cmpl = lpfc_bsg_issue_mbox_cmpl; |
---|
4895 | 4962 | |
---|
4896 | 4963 | /* setup context field to pass wait_queue pointer to wake function */ |
---|
4897 | | - pmboxq->context1 = dd_data; |
---|
| 4964 | + pmboxq->ctx_ndlp = dd_data; |
---|
4898 | 4965 | dd_data->type = TYPE_MBOX; |
---|
4899 | 4966 | dd_data->set_job = job; |
---|
4900 | 4967 | dd_data->context_un.mbox.pmboxq = pmboxq; |
---|
.. | .. |
---|
5133 | 5200 | goto no_dd_data; |
---|
5134 | 5201 | } |
---|
5135 | 5202 | |
---|
5136 | | - if (job->reply_len < |
---|
5137 | | - sizeof(struct fc_bsg_request) + sizeof(struct menlo_response)) { |
---|
| 5203 | + if (job->reply_len < sizeof(*bsg_reply) + |
---|
| 5204 | + sizeof(struct menlo_response)) { |
---|
5138 | 5205 | lpfc_printf_log(phba, KERN_WARNING, LOG_LIBDFC, |
---|
5139 | 5206 | "2785 Received MENLO_CMD reply below " |
---|
5140 | 5207 | "minimum size\n"); |
---|
.. | .. |
---|
5290 | 5357 | forced_reply = (struct forced_link_speed_support_reply *) |
---|
5291 | 5358 | bsg_reply->reply_data.vendor_reply.vendor_rsp; |
---|
5292 | 5359 | |
---|
5293 | | - if (job->reply_len < |
---|
5294 | | - sizeof(struct fc_bsg_request) + |
---|
5295 | | - sizeof(struct forced_link_speed_support_reply)) { |
---|
| 5360 | + if (job->reply_len < sizeof(*bsg_reply) + sizeof(*forced_reply)) { |
---|
5296 | 5361 | lpfc_printf_log(phba, KERN_WARNING, LOG_LIBDFC, |
---|
5297 | 5362 | "0049 Received FORCED_LINK_SPEED reply below " |
---|
5298 | 5363 | "minimum size\n"); |
---|
.. | .. |
---|
5309 | 5374 | bsg_job_done(job, bsg_reply->result, |
---|
5310 | 5375 | bsg_reply->reply_payload_rcv_len); |
---|
5311 | 5376 | return rc; |
---|
| 5377 | +} |
---|
| 5378 | + |
---|
| 5379 | +/** |
---|
| 5380 | + * lpfc_check_fwlog_support: Check FW log support on the adapter |
---|
| 5381 | + * @phba: Pointer to HBA context object. |
---|
| 5382 | + * |
---|
| 5383 | + * Check if FW Logging support by the adapter |
---|
| 5384 | + **/ |
---|
| 5385 | +int |
---|
| 5386 | +lpfc_check_fwlog_support(struct lpfc_hba *phba) |
---|
| 5387 | +{ |
---|
| 5388 | + struct lpfc_ras_fwlog *ras_fwlog = NULL; |
---|
| 5389 | + |
---|
| 5390 | + ras_fwlog = &phba->ras_fwlog; |
---|
| 5391 | + |
---|
| 5392 | + if (ras_fwlog->ras_hwsupport == false) |
---|
| 5393 | + return -EACCES; |
---|
| 5394 | + else if (ras_fwlog->ras_enabled == false) |
---|
| 5395 | + return -EPERM; |
---|
| 5396 | + else |
---|
| 5397 | + return 0; |
---|
| 5398 | +} |
---|
| 5399 | + |
---|
| 5400 | +/** |
---|
| 5401 | + * lpfc_bsg_get_ras_config: Get RAS configuration settings |
---|
| 5402 | + * @job: fc_bsg_job to handle |
---|
| 5403 | + * |
---|
| 5404 | + * Get RAS configuration values set. |
---|
| 5405 | + **/ |
---|
| 5406 | +static int |
---|
| 5407 | +lpfc_bsg_get_ras_config(struct bsg_job *job) |
---|
| 5408 | +{ |
---|
| 5409 | + struct Scsi_Host *shost = fc_bsg_to_shost(job); |
---|
| 5410 | + struct lpfc_vport *vport = shost_priv(shost); |
---|
| 5411 | + struct fc_bsg_reply *bsg_reply = job->reply; |
---|
| 5412 | + struct lpfc_hba *phba = vport->phba; |
---|
| 5413 | + struct lpfc_bsg_get_ras_config_reply *ras_reply; |
---|
| 5414 | + struct lpfc_ras_fwlog *ras_fwlog = &phba->ras_fwlog; |
---|
| 5415 | + int rc = 0; |
---|
| 5416 | + |
---|
| 5417 | + if (job->request_len < |
---|
| 5418 | + sizeof(struct fc_bsg_request) + |
---|
| 5419 | + sizeof(struct lpfc_bsg_ras_req)) { |
---|
| 5420 | + lpfc_printf_log(phba, KERN_ERR, LOG_LIBDFC, |
---|
| 5421 | + "6192 FW_LOG request received " |
---|
| 5422 | + "below minimum size\n"); |
---|
| 5423 | + rc = -EINVAL; |
---|
| 5424 | + goto ras_job_error; |
---|
| 5425 | + } |
---|
| 5426 | + |
---|
| 5427 | + /* Check FW log status */ |
---|
| 5428 | + rc = lpfc_check_fwlog_support(phba); |
---|
| 5429 | + if (rc) |
---|
| 5430 | + goto ras_job_error; |
---|
| 5431 | + |
---|
| 5432 | + ras_reply = (struct lpfc_bsg_get_ras_config_reply *) |
---|
| 5433 | + bsg_reply->reply_data.vendor_reply.vendor_rsp; |
---|
| 5434 | + |
---|
| 5435 | + /* Current logging state */ |
---|
| 5436 | + spin_lock_irq(&phba->hbalock); |
---|
| 5437 | + if (ras_fwlog->state == ACTIVE) |
---|
| 5438 | + ras_reply->state = LPFC_RASLOG_STATE_RUNNING; |
---|
| 5439 | + else |
---|
| 5440 | + ras_reply->state = LPFC_RASLOG_STATE_STOPPED; |
---|
| 5441 | + spin_unlock_irq(&phba->hbalock); |
---|
| 5442 | + |
---|
| 5443 | + ras_reply->log_level = phba->ras_fwlog.fw_loglevel; |
---|
| 5444 | + ras_reply->log_buff_sz = phba->cfg_ras_fwlog_buffsize; |
---|
| 5445 | + |
---|
| 5446 | +ras_job_error: |
---|
| 5447 | + /* make error code available to userspace */ |
---|
| 5448 | + bsg_reply->result = rc; |
---|
| 5449 | + |
---|
| 5450 | + /* complete the job back to userspace */ |
---|
| 5451 | + if (!rc) |
---|
| 5452 | + bsg_job_done(job, bsg_reply->result, |
---|
| 5453 | + bsg_reply->reply_payload_rcv_len); |
---|
| 5454 | + return rc; |
---|
| 5455 | +} |
---|
| 5456 | + |
---|
| 5457 | +/** |
---|
| 5458 | + * lpfc_bsg_set_ras_config: Set FW logging parameters |
---|
| 5459 | + * @job: fc_bsg_job to handle |
---|
| 5460 | + * |
---|
| 5461 | + * Set log-level parameters for FW-logging in host memory |
---|
| 5462 | + **/ |
---|
| 5463 | +static int |
---|
| 5464 | +lpfc_bsg_set_ras_config(struct bsg_job *job) |
---|
| 5465 | +{ |
---|
| 5466 | + struct Scsi_Host *shost = fc_bsg_to_shost(job); |
---|
| 5467 | + struct lpfc_vport *vport = shost_priv(shost); |
---|
| 5468 | + struct lpfc_hba *phba = vport->phba; |
---|
| 5469 | + struct lpfc_bsg_set_ras_config_req *ras_req; |
---|
| 5470 | + struct fc_bsg_request *bsg_request = job->request; |
---|
| 5471 | + struct lpfc_ras_fwlog *ras_fwlog = &phba->ras_fwlog; |
---|
| 5472 | + struct fc_bsg_reply *bsg_reply = job->reply; |
---|
| 5473 | + uint8_t action = 0, log_level = 0; |
---|
| 5474 | + int rc = 0, action_status = 0; |
---|
| 5475 | + |
---|
| 5476 | + if (job->request_len < |
---|
| 5477 | + sizeof(struct fc_bsg_request) + |
---|
| 5478 | + sizeof(struct lpfc_bsg_set_ras_config_req)) { |
---|
| 5479 | + lpfc_printf_log(phba, KERN_ERR, LOG_LIBDFC, |
---|
| 5480 | + "6182 Received RAS_LOG request " |
---|
| 5481 | + "below minimum size\n"); |
---|
| 5482 | + rc = -EINVAL; |
---|
| 5483 | + goto ras_job_error; |
---|
| 5484 | + } |
---|
| 5485 | + |
---|
| 5486 | + /* Check FW log status */ |
---|
| 5487 | + rc = lpfc_check_fwlog_support(phba); |
---|
| 5488 | + if (rc) |
---|
| 5489 | + goto ras_job_error; |
---|
| 5490 | + |
---|
| 5491 | + ras_req = (struct lpfc_bsg_set_ras_config_req *) |
---|
| 5492 | + bsg_request->rqst_data.h_vendor.vendor_cmd; |
---|
| 5493 | + action = ras_req->action; |
---|
| 5494 | + log_level = ras_req->log_level; |
---|
| 5495 | + |
---|
| 5496 | + if (action == LPFC_RASACTION_STOP_LOGGING) { |
---|
| 5497 | + /* Check if already disabled */ |
---|
| 5498 | + spin_lock_irq(&phba->hbalock); |
---|
| 5499 | + if (ras_fwlog->state != ACTIVE) { |
---|
| 5500 | + spin_unlock_irq(&phba->hbalock); |
---|
| 5501 | + rc = -ESRCH; |
---|
| 5502 | + goto ras_job_error; |
---|
| 5503 | + } |
---|
| 5504 | + spin_unlock_irq(&phba->hbalock); |
---|
| 5505 | + |
---|
| 5506 | + /* Disable logging */ |
---|
| 5507 | + lpfc_ras_stop_fwlog(phba); |
---|
| 5508 | + } else { |
---|
| 5509 | + /*action = LPFC_RASACTION_START_LOGGING*/ |
---|
| 5510 | + |
---|
| 5511 | + /* Even though FW-logging is active re-initialize |
---|
| 5512 | + * FW-logging with new log-level. Return status |
---|
| 5513 | + * "Logging already Running" to caller. |
---|
| 5514 | + **/ |
---|
| 5515 | + spin_lock_irq(&phba->hbalock); |
---|
| 5516 | + if (ras_fwlog->state != INACTIVE) |
---|
| 5517 | + action_status = -EINPROGRESS; |
---|
| 5518 | + spin_unlock_irq(&phba->hbalock); |
---|
| 5519 | + |
---|
| 5520 | + /* Enable logging */ |
---|
| 5521 | + rc = lpfc_sli4_ras_fwlog_init(phba, log_level, |
---|
| 5522 | + LPFC_RAS_ENABLE_LOGGING); |
---|
| 5523 | + if (rc) { |
---|
| 5524 | + rc = -EINVAL; |
---|
| 5525 | + goto ras_job_error; |
---|
| 5526 | + } |
---|
| 5527 | + |
---|
| 5528 | + /* Check if FW-logging is re-initialized */ |
---|
| 5529 | + if (action_status == -EINPROGRESS) |
---|
| 5530 | + rc = action_status; |
---|
| 5531 | + } |
---|
| 5532 | +ras_job_error: |
---|
| 5533 | + /* make error code available to userspace */ |
---|
| 5534 | + bsg_reply->result = rc; |
---|
| 5535 | + |
---|
| 5536 | + /* complete the job back to userspace */ |
---|
| 5537 | + if (!rc) |
---|
| 5538 | + bsg_job_done(job, bsg_reply->result, |
---|
| 5539 | + bsg_reply->reply_payload_rcv_len); |
---|
| 5540 | + |
---|
| 5541 | + return rc; |
---|
| 5542 | +} |
---|
| 5543 | + |
---|
| 5544 | +/** |
---|
| 5545 | + * lpfc_bsg_get_ras_lwpd: Get log write position data |
---|
| 5546 | + * @job: fc_bsg_job to handle |
---|
| 5547 | + * |
---|
| 5548 | + * Get Offset/Wrap count of the log message written |
---|
| 5549 | + * in host memory |
---|
| 5550 | + **/ |
---|
| 5551 | +static int |
---|
| 5552 | +lpfc_bsg_get_ras_lwpd(struct bsg_job *job) |
---|
| 5553 | +{ |
---|
| 5554 | + struct Scsi_Host *shost = fc_bsg_to_shost(job); |
---|
| 5555 | + struct lpfc_vport *vport = shost_priv(shost); |
---|
| 5556 | + struct lpfc_bsg_get_ras_lwpd *ras_reply; |
---|
| 5557 | + struct lpfc_hba *phba = vport->phba; |
---|
| 5558 | + struct lpfc_ras_fwlog *ras_fwlog = &phba->ras_fwlog; |
---|
| 5559 | + struct fc_bsg_reply *bsg_reply = job->reply; |
---|
| 5560 | + u32 *lwpd_ptr = NULL; |
---|
| 5561 | + int rc = 0; |
---|
| 5562 | + |
---|
| 5563 | + rc = lpfc_check_fwlog_support(phba); |
---|
| 5564 | + if (rc) |
---|
| 5565 | + goto ras_job_error; |
---|
| 5566 | + |
---|
| 5567 | + if (job->request_len < |
---|
| 5568 | + sizeof(struct fc_bsg_request) + |
---|
| 5569 | + sizeof(struct lpfc_bsg_ras_req)) { |
---|
| 5570 | + lpfc_printf_log(phba, KERN_ERR, LOG_LIBDFC, |
---|
| 5571 | + "6183 Received RAS_LOG request " |
---|
| 5572 | + "below minimum size\n"); |
---|
| 5573 | + rc = -EINVAL; |
---|
| 5574 | + goto ras_job_error; |
---|
| 5575 | + } |
---|
| 5576 | + |
---|
| 5577 | + ras_reply = (struct lpfc_bsg_get_ras_lwpd *) |
---|
| 5578 | + bsg_reply->reply_data.vendor_reply.vendor_rsp; |
---|
| 5579 | + |
---|
| 5580 | + if (!ras_fwlog->lwpd.virt) { |
---|
| 5581 | + lpfc_printf_log(phba, KERN_ERR, LOG_LIBDFC, |
---|
| 5582 | + "6193 Restart FW Logging\n"); |
---|
| 5583 | + rc = -EINVAL; |
---|
| 5584 | + goto ras_job_error; |
---|
| 5585 | + } |
---|
| 5586 | + |
---|
| 5587 | + /* Get lwpd offset */ |
---|
| 5588 | + lwpd_ptr = (uint32_t *)(ras_fwlog->lwpd.virt); |
---|
| 5589 | + ras_reply->offset = be32_to_cpu(*lwpd_ptr & 0xffffffff); |
---|
| 5590 | + |
---|
| 5591 | + /* Get wrap count */ |
---|
| 5592 | + ras_reply->wrap_count = be32_to_cpu(*(++lwpd_ptr) & 0xffffffff); |
---|
| 5593 | + |
---|
| 5594 | +ras_job_error: |
---|
| 5595 | + /* make error code available to userspace */ |
---|
| 5596 | + bsg_reply->result = rc; |
---|
| 5597 | + |
---|
| 5598 | + /* complete the job back to userspace */ |
---|
| 5599 | + if (!rc) |
---|
| 5600 | + bsg_job_done(job, bsg_reply->result, |
---|
| 5601 | + bsg_reply->reply_payload_rcv_len); |
---|
| 5602 | + |
---|
| 5603 | + return rc; |
---|
| 5604 | +} |
---|
| 5605 | + |
---|
| 5606 | +/** |
---|
| 5607 | + * lpfc_bsg_get_ras_fwlog: Read FW log |
---|
| 5608 | + * @job: fc_bsg_job to handle |
---|
| 5609 | + * |
---|
| 5610 | + * Copy the FW log into the passed buffer. |
---|
| 5611 | + **/ |
---|
| 5612 | +static int |
---|
| 5613 | +lpfc_bsg_get_ras_fwlog(struct bsg_job *job) |
---|
| 5614 | +{ |
---|
| 5615 | + struct Scsi_Host *shost = fc_bsg_to_shost(job); |
---|
| 5616 | + struct lpfc_vport *vport = shost_priv(shost); |
---|
| 5617 | + struct lpfc_hba *phba = vport->phba; |
---|
| 5618 | + struct fc_bsg_request *bsg_request = job->request; |
---|
| 5619 | + struct fc_bsg_reply *bsg_reply = job->reply; |
---|
| 5620 | + struct lpfc_bsg_get_fwlog_req *ras_req; |
---|
| 5621 | + u32 rd_offset, rd_index, offset; |
---|
| 5622 | + void *src, *fwlog_buff; |
---|
| 5623 | + struct lpfc_ras_fwlog *ras_fwlog = NULL; |
---|
| 5624 | + struct lpfc_dmabuf *dmabuf, *next; |
---|
| 5625 | + int rc = 0; |
---|
| 5626 | + |
---|
| 5627 | + ras_fwlog = &phba->ras_fwlog; |
---|
| 5628 | + |
---|
| 5629 | + rc = lpfc_check_fwlog_support(phba); |
---|
| 5630 | + if (rc) |
---|
| 5631 | + goto ras_job_error; |
---|
| 5632 | + |
---|
| 5633 | + /* Logging to be stopped before reading */ |
---|
| 5634 | + spin_lock_irq(&phba->hbalock); |
---|
| 5635 | + if (ras_fwlog->state == ACTIVE) { |
---|
| 5636 | + spin_unlock_irq(&phba->hbalock); |
---|
| 5637 | + rc = -EINPROGRESS; |
---|
| 5638 | + goto ras_job_error; |
---|
| 5639 | + } |
---|
| 5640 | + spin_unlock_irq(&phba->hbalock); |
---|
| 5641 | + |
---|
| 5642 | + if (job->request_len < |
---|
| 5643 | + sizeof(struct fc_bsg_request) + |
---|
| 5644 | + sizeof(struct lpfc_bsg_get_fwlog_req)) { |
---|
| 5645 | + lpfc_printf_log(phba, KERN_ERR, LOG_LIBDFC, |
---|
| 5646 | + "6184 Received RAS_LOG request " |
---|
| 5647 | + "below minimum size\n"); |
---|
| 5648 | + rc = -EINVAL; |
---|
| 5649 | + goto ras_job_error; |
---|
| 5650 | + } |
---|
| 5651 | + |
---|
| 5652 | + ras_req = (struct lpfc_bsg_get_fwlog_req *) |
---|
| 5653 | + bsg_request->rqst_data.h_vendor.vendor_cmd; |
---|
| 5654 | + rd_offset = ras_req->read_offset; |
---|
| 5655 | + |
---|
| 5656 | + /* Allocate memory to read fw log*/ |
---|
| 5657 | + fwlog_buff = vmalloc(ras_req->read_size); |
---|
| 5658 | + if (!fwlog_buff) { |
---|
| 5659 | + rc = -ENOMEM; |
---|
| 5660 | + goto ras_job_error; |
---|
| 5661 | + } |
---|
| 5662 | + |
---|
| 5663 | + rd_index = (rd_offset / LPFC_RAS_MAX_ENTRY_SIZE); |
---|
| 5664 | + offset = (rd_offset % LPFC_RAS_MAX_ENTRY_SIZE); |
---|
| 5665 | + |
---|
| 5666 | + list_for_each_entry_safe(dmabuf, next, |
---|
| 5667 | + &ras_fwlog->fwlog_buff_list, list) { |
---|
| 5668 | + |
---|
| 5669 | + if (dmabuf->buffer_tag < rd_index) |
---|
| 5670 | + continue; |
---|
| 5671 | + |
---|
| 5672 | + src = dmabuf->virt + offset; |
---|
| 5673 | + memcpy(fwlog_buff, src, ras_req->read_size); |
---|
| 5674 | + break; |
---|
| 5675 | + } |
---|
| 5676 | + |
---|
| 5677 | + bsg_reply->reply_payload_rcv_len = |
---|
| 5678 | + sg_copy_from_buffer(job->reply_payload.sg_list, |
---|
| 5679 | + job->reply_payload.sg_cnt, |
---|
| 5680 | + fwlog_buff, ras_req->read_size); |
---|
| 5681 | + |
---|
| 5682 | + vfree(fwlog_buff); |
---|
| 5683 | + |
---|
| 5684 | +ras_job_error: |
---|
| 5685 | + bsg_reply->result = rc; |
---|
| 5686 | + if (!rc) |
---|
| 5687 | + bsg_job_done(job, bsg_reply->result, |
---|
| 5688 | + bsg_reply->reply_payload_rcv_len); |
---|
| 5689 | + |
---|
| 5690 | + return rc; |
---|
| 5691 | +} |
---|
| 5692 | + |
---|
| 5693 | +static int |
---|
| 5694 | +lpfc_get_trunk_info(struct bsg_job *job) |
---|
| 5695 | +{ |
---|
| 5696 | + struct lpfc_vport *vport = shost_priv(fc_bsg_to_shost(job)); |
---|
| 5697 | + struct lpfc_hba *phba = vport->phba; |
---|
| 5698 | + struct fc_bsg_reply *bsg_reply = job->reply; |
---|
| 5699 | + struct lpfc_trunk_info *event_reply; |
---|
| 5700 | + int rc = 0; |
---|
| 5701 | + |
---|
| 5702 | + if (job->request_len < |
---|
| 5703 | + sizeof(struct fc_bsg_request) + sizeof(struct get_trunk_info_req)) { |
---|
| 5704 | + lpfc_printf_log(phba, KERN_ERR, LOG_LIBDFC, |
---|
| 5705 | + "2744 Received GET TRUNK _INFO request below " |
---|
| 5706 | + "minimum size\n"); |
---|
| 5707 | + rc = -EINVAL; |
---|
| 5708 | + goto job_error; |
---|
| 5709 | + } |
---|
| 5710 | + |
---|
| 5711 | + event_reply = (struct lpfc_trunk_info *) |
---|
| 5712 | + bsg_reply->reply_data.vendor_reply.vendor_rsp; |
---|
| 5713 | + |
---|
| 5714 | + if (job->reply_len < sizeof(*bsg_reply) + sizeof(*event_reply)) { |
---|
| 5715 | + lpfc_printf_log(phba, KERN_WARNING, LOG_LIBDFC, |
---|
| 5716 | + "2728 Received GET TRUNK _INFO reply below " |
---|
| 5717 | + "minimum size\n"); |
---|
| 5718 | + rc = -EINVAL; |
---|
| 5719 | + goto job_error; |
---|
| 5720 | + } |
---|
| 5721 | + if (event_reply == NULL) { |
---|
| 5722 | + rc = -EINVAL; |
---|
| 5723 | + goto job_error; |
---|
| 5724 | + } |
---|
| 5725 | + |
---|
| 5726 | + bsg_bf_set(lpfc_trunk_info_link_status, event_reply, |
---|
| 5727 | + (phba->link_state >= LPFC_LINK_UP) ? 1 : 0); |
---|
| 5728 | + |
---|
| 5729 | + bsg_bf_set(lpfc_trunk_info_trunk_active0, event_reply, |
---|
| 5730 | + (phba->trunk_link.link0.state == LPFC_LINK_UP) ? 1 : 0); |
---|
| 5731 | + |
---|
| 5732 | + bsg_bf_set(lpfc_trunk_info_trunk_active1, event_reply, |
---|
| 5733 | + (phba->trunk_link.link1.state == LPFC_LINK_UP) ? 1 : 0); |
---|
| 5734 | + |
---|
| 5735 | + bsg_bf_set(lpfc_trunk_info_trunk_active2, event_reply, |
---|
| 5736 | + (phba->trunk_link.link2.state == LPFC_LINK_UP) ? 1 : 0); |
---|
| 5737 | + |
---|
| 5738 | + bsg_bf_set(lpfc_trunk_info_trunk_active3, event_reply, |
---|
| 5739 | + (phba->trunk_link.link3.state == LPFC_LINK_UP) ? 1 : 0); |
---|
| 5740 | + |
---|
| 5741 | + bsg_bf_set(lpfc_trunk_info_trunk_config0, event_reply, |
---|
| 5742 | + bf_get(lpfc_conf_trunk_port0, &phba->sli4_hba)); |
---|
| 5743 | + |
---|
| 5744 | + bsg_bf_set(lpfc_trunk_info_trunk_config1, event_reply, |
---|
| 5745 | + bf_get(lpfc_conf_trunk_port1, &phba->sli4_hba)); |
---|
| 5746 | + |
---|
| 5747 | + bsg_bf_set(lpfc_trunk_info_trunk_config2, event_reply, |
---|
| 5748 | + bf_get(lpfc_conf_trunk_port2, &phba->sli4_hba)); |
---|
| 5749 | + |
---|
| 5750 | + bsg_bf_set(lpfc_trunk_info_trunk_config3, event_reply, |
---|
| 5751 | + bf_get(lpfc_conf_trunk_port3, &phba->sli4_hba)); |
---|
| 5752 | + |
---|
| 5753 | + event_reply->port_speed = phba->sli4_hba.link_state.speed / 1000; |
---|
| 5754 | + event_reply->logical_speed = |
---|
| 5755 | + phba->sli4_hba.link_state.logical_speed / 1000; |
---|
| 5756 | +job_error: |
---|
| 5757 | + bsg_reply->result = rc; |
---|
| 5758 | + if (!rc) |
---|
| 5759 | + bsg_job_done(job, bsg_reply->result, |
---|
| 5760 | + bsg_reply->reply_payload_rcv_len); |
---|
| 5761 | + return rc; |
---|
| 5762 | + |
---|
5312 | 5763 | } |
---|
5313 | 5764 | |
---|
5314 | 5765 | /** |
---|
.. | .. |
---|
5358 | 5809 | case LPFC_BSG_VENDOR_FORCED_LINK_SPEED: |
---|
5359 | 5810 | rc = lpfc_forced_link_speed(job); |
---|
5360 | 5811 | break; |
---|
| 5812 | + case LPFC_BSG_VENDOR_RAS_GET_LWPD: |
---|
| 5813 | + rc = lpfc_bsg_get_ras_lwpd(job); |
---|
| 5814 | + break; |
---|
| 5815 | + case LPFC_BSG_VENDOR_RAS_GET_FWLOG: |
---|
| 5816 | + rc = lpfc_bsg_get_ras_fwlog(job); |
---|
| 5817 | + break; |
---|
| 5818 | + case LPFC_BSG_VENDOR_RAS_GET_CONFIG: |
---|
| 5819 | + rc = lpfc_bsg_get_ras_config(job); |
---|
| 5820 | + break; |
---|
| 5821 | + case LPFC_BSG_VENDOR_RAS_SET_CONFIG: |
---|
| 5822 | + rc = lpfc_bsg_set_ras_config(job); |
---|
| 5823 | + break; |
---|
| 5824 | + case LPFC_BSG_VENDOR_GET_TRUNK_INFO: |
---|
| 5825 | + rc = lpfc_get_trunk_info(job); |
---|
| 5826 | + break; |
---|
5361 | 5827 | default: |
---|
5362 | 5828 | rc = -EINVAL; |
---|
5363 | 5829 | bsg_reply->reply_payload_rcv_len = 0; |
---|
.. | .. |
---|
5371 | 5837 | |
---|
5372 | 5838 | /** |
---|
5373 | 5839 | * lpfc_bsg_request - handle a bsg request from the FC transport |
---|
5374 | | - * @job: fc_bsg_job to handle |
---|
| 5840 | + * @job: bsg_job to handle |
---|
5375 | 5841 | **/ |
---|
5376 | 5842 | int |
---|
5377 | 5843 | lpfc_bsg_request(struct bsg_job *job) |
---|
.. | .. |
---|
5405 | 5871 | |
---|
5406 | 5872 | /** |
---|
5407 | 5873 | * lpfc_bsg_timeout - handle timeout of a bsg request from the FC transport |
---|
5408 | | - * @job: fc_bsg_job that has timed out |
---|
| 5874 | + * @job: bsg_job that has timed out |
---|
5409 | 5875 | * |
---|
5410 | 5876 | * This function just aborts the job's IOCB. The aborted IOCB will return to |
---|
5411 | 5877 | * the waiting function which will handle passing the error back to userspace |
---|