The branch main has been updated by ram:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=29e2dbd42c3e2e10e606b3414f4d0c53021d4e86

commit 29e2dbd42c3e2e10e606b3414f4d0c53021d4e86
Author:     Ram Kishore Vegesna <r...@freebsd.org>
AuthorDate: 2021-06-24 07:05:00 +0000
Commit:     Ram Kishore Vegesna <r...@freebsd.org>
CommitDate: 2021-07-06 15:38:11 +0000

    ocs_fc: Add gendump and dump_to_host ioctl command support.
    
    Support to generate firmware dump.
    
    Approved by: mav(mentor)
---
 sys/dev/ocs_fc/ocs_gendump.c | 388 +++++++++++++++++++++++++++++++++++++++++++
 sys/dev/ocs_fc/ocs_gendump.h |  42 +++++
 sys/dev/ocs_fc/ocs_ioctl.c   |  13 +-
 sys/dev/ocs_fc/ocs_ioctl.h   |   3 +
 sys/dev/ocs_fc/ocs_mgmt.c    | 152 ++---------------
 sys/dev/ocs_fc/ocs_os.c      |   3 +-
 sys/dev/ocs_fc/ocs_os.h      |   3 +-
 sys/modules/ocs_fc/Makefile  |   3 +-
 8 files changed, 449 insertions(+), 158 deletions(-)

diff --git a/sys/dev/ocs_fc/ocs_gendump.c b/sys/dev/ocs_fc/ocs_gendump.c
new file mode 100644
index 000000000000..d24870f39668
--- /dev/null
+++ b/sys/dev/ocs_fc/ocs_gendump.c
@@ -0,0 +1,388 @@
+/*
+ * Copyright (c) 2021 Broadcom. All rights reserved.
+ * The term "Broadcom" refers to Broadcom Limited and/or its subsidiaries.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its 
contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "ocs.h"
+#include "ocs_gendump.h"
+
+/* Reset all the functions associated with a bus/dev */
+static int
+ocs_gen_dump_reset(uint8_t bus, uint8_t dev)
+{
+       uint32_t index = 0;
+       ocs_t *ocs;
+       int rc = 0;
+
+       while ((ocs = ocs_get_instance(index++)) != NULL) {
+               uint8_t ocs_bus, ocs_dev, ocs_func;
+               ocs_domain_t *domain;
+
+               ocs_get_bus_dev_func(ocs, &ocs_bus, &ocs_dev, &ocs_func);
+
+               if (!(ocs_bus == bus && ocs_dev == dev))
+                       continue;
+
+               if (ocs_hw_reset(&ocs->hw, OCS_HW_RESET_FUNCTION)) {
+                       ocs_log_test(ocs, "failed to reset port\n");
+                       rc = -1;
+                       continue;
+               }
+
+               ocs_log_debug(ocs, "successfully reset port\n");
+               while ((domain = ocs_list_get_head(&ocs->domain_list)) != NULL) 
{
+                       ocs_log_debug(ocs, "free domain %p\n", domain);
+                       ocs_domain_force_free(domain);
+               }
+               /* now initialize hw so user can read the dump in */
+               if (ocs_hw_init(&ocs->hw)) {
+                       ocs_log_err(ocs, "failed to initialize hw\n");
+                       rc = -1;
+               } else {
+                       ocs_log_debug(ocs, "successfully initialized hw\n");
+               }
+       }
+       return rc;
+}
+
+int
+ocs_gen_dump(ocs_t *ocs)
+{
+       uint32_t reset_required;
+       uint32_t dump_ready;
+       uint32_t ms_waited;
+       uint8_t bus, dev, func;
+       int rc = 0;
+       int index = 0, port_index = 0;
+       ocs_t *nxt_ocs;
+       uint8_t nxt_bus, nxt_dev, nxt_func;
+       uint8_t prev_port_state[OCS_MAX_HBA_PORTS] = {0,};
+       ocs_xport_stats_t link_status;
+
+       ocs_get_bus_dev_func(ocs, &bus, &dev, &func);
+
+       /* Drop link on all ports belongs to this HBA*/
+       while ((nxt_ocs = ocs_get_instance(index++)) != NULL) {
+               ocs_get_bus_dev_func(nxt_ocs, &nxt_bus, &nxt_dev, &nxt_func);
+
+               if (!(bus == nxt_bus && dev == nxt_dev))
+                       continue;
+
+               if ((port_index >= OCS_MAX_HBA_PORTS))
+                       continue;
+
+               /* Check current link status and save for future use */
+               if (ocs_xport_status(nxt_ocs->xport, OCS_XPORT_PORT_STATUS,
+                  &link_status) == 0) {
+                       if (link_status.value == OCS_XPORT_PORT_ONLINE) {
+                               prev_port_state[port_index] = 1;
+                               ocs_xport_control(nxt_ocs->xport,
+                                                 OCS_XPORT_PORT_OFFLINE);
+                       } else {
+                               prev_port_state[port_index] = 0;
+                       }
+               }
+               port_index++;
+       }
+
+       /* Wait until all ports have quiesced */
+       for (index = 0; (nxt_ocs = ocs_get_instance(index++)) != NULL; ) {
+               ms_waited = 0;
+               for (;;) {
+                       ocs_xport_stats_t status;
+
+                       ocs_xport_status(nxt_ocs->xport, OCS_XPORT_IS_QUIESCED,
+                                        &status);
+                       if (status.value) {
+                               ocs_log_debug(nxt_ocs, "port quiesced\n");
+                               break;
+                       }
+
+                       ocs_msleep(10);
+                       ms_waited += 10;
+                       if (ms_waited > 60000) {
+                               ocs_log_test(nxt_ocs,
+                                   "timed out waiting for port to quiesce\n");
+                               break;
+                       }
+               }
+       }
+
+       /* Initiate dump */
+       if (ocs_hw_raise_ue(&ocs->hw, 1) == OCS_HW_RTN_SUCCESS) {
+
+               /* Wait for dump to complete */
+               ocs_log_debug(ocs, "Dump requested, wait for completion.\n");
+
+               dump_ready = 0;
+               ms_waited = 0;
+               while ((!dump_ready) && (ms_waited < 30000)) {
+                       ocs_hw_get(&ocs->hw, OCS_HW_DUMP_READY, &dump_ready);
+                       ocs_udelay(10000);
+                       ms_waited += 10;
+               }
+
+               if (!dump_ready) {
+                       ocs_log_test(ocs, "Failed to see dump after 30 secs\n");
+                       rc = -1;
+               } else {
+                       ocs_log_debug(ocs, "sucessfully generated dump\n");
+               }
+
+               /* now reset port */
+               ocs_hw_get(&ocs->hw, OCS_HW_RESET_REQUIRED, &reset_required);
+               ocs_log_debug(ocs, "reset required=%d\n", reset_required);
+               if (reset_required) {
+                       if (ocs_gen_dump_reset(bus, dev) == 0) {
+                               ocs_log_debug(ocs, "all devices reset\n");
+                       } else {
+                               ocs_log_test(ocs, "all devices NOT reset\n");
+                       }
+               }
+       } else {
+               ocs_log_test(ocs, "dump request to hw failed\n");
+               rc = -1;
+       }
+
+       index = port_index = 0;
+       nxt_ocs = NULL;
+       /* Bring links on each HBA port to previous state*/
+       while ((nxt_ocs = ocs_get_instance(index++)) != NULL) {
+               ocs_get_bus_dev_func(nxt_ocs, &nxt_bus, &nxt_dev, &nxt_func);
+               if (port_index > OCS_MAX_HBA_PORTS) {
+                       ocs_log_err(NULL, "port index(%d) out of boundary\n",
+                                   port_index);
+                       rc = -1;
+                       break;
+               }
+               if ((bus == nxt_bus) && (dev == nxt_dev) &&
+                   prev_port_state[port_index++]) {
+                       ocs_xport_control(nxt_ocs->xport, 
OCS_XPORT_PORT_ONLINE);
+               }
+       }
+
+       return rc;
+}
+
+int
+ocs_fdb_dump(ocs_t *ocs)
+{
+       uint32_t dump_ready;
+       uint32_t ms_waited;
+       int rc = 0;
+
+#define FDB 2
+
+       /* Initiate dump */
+       if (ocs_hw_raise_ue(&ocs->hw, FDB) == OCS_HW_RTN_SUCCESS) {
+
+               /* Wait for dump to complete */
+               ocs_log_debug(ocs, "Dump requested, wait for completion.\n");
+
+               dump_ready = 0;
+               ms_waited = 0;
+               while ((!(dump_ready == FDB)) && (ms_waited < 10000)) {
+                       ocs_hw_get(&ocs->hw, OCS_HW_DUMP_READY, &dump_ready);
+                       ocs_udelay(10000);
+                       ms_waited += 10;
+               }
+
+               if (!dump_ready) {
+                       ocs_log_err(ocs, "Failed to see dump after 10 secs\n");
+                       return -1;
+               }
+
+               ocs_log_debug(ocs, "sucessfully generated dump\n");
+
+       } else {
+               ocs_log_err(ocs, "dump request to hw failed\n");
+               rc = -1;
+       }
+
+       return rc;
+}
+
+/**
+ * @brief Create a Lancer dump into a memory buffer
+ * @par Description
+ * This function creates a DMA buffer to hold a Lancer dump,
+ * sets the dump location to point to that buffer, then calls
+ * ocs_gen_dump to cause a dump to be transfered to the buffer.
+ * After the dump is complete it copies the dump to the provided
+ * user space buffer.
+ *
+ * @param ocs Pointer to ocs structure
+ * @param buf User space buffer in which to store the dump
+ * @param buflen Length of the user buffer in bytes
+ *
+ * @return Returns 0 on success, non-zero on error.
+ */
+int
+ocs_dump_to_host(ocs_t *ocs, void *buf, uint32_t buflen)
+{
+       int rc;
+       uint32_t i, num_buffers;
+       ocs_dma_t *dump_buffers;
+       uint32_t rem_bytes, offset;
+
+       if (buflen == 0) {
+               ocs_log_test(ocs, "zero buffer length is invalid\n");
+               return -1;
+       }
+
+       num_buffers = ((buflen + OCS_MAX_DMA_ALLOC - 1) / OCS_MAX_DMA_ALLOC);
+
+       dump_buffers = ocs_malloc(ocs, sizeof(ocs_dma_t) * num_buffers,
+                                 OCS_M_ZERO | OCS_M_NOWAIT);
+       if (dump_buffers == NULL) {
+               ocs_log_err(ocs, "Failed to dump buffers\n");
+               return -1;
+       }
+
+       /* Allocate a DMA buffers to hold the dump */
+       rem_bytes = buflen;
+       for (i = 0; i < num_buffers; i++) {
+               uint32_t num_bytes = MIN(rem_bytes, OCS_MAX_DMA_ALLOC);
+
+               rc = ocs_dma_alloc(ocs, &dump_buffers[i], num_bytes,
+                                  OCS_MIN_DMA_ALIGNMENT);
+               if (rc) {
+                       ocs_log_err(ocs, "Failed to allocate dump buffer\n");
+
+                       /* Free any previously allocated buffers */
+                       goto free_and_return;
+               }
+               rem_bytes -= num_bytes;
+       }
+
+       rc = ocs_hw_set_dump_location(&ocs->hw, num_buffers, dump_buffers, 0);
+       if (rc) {
+               ocs_log_test(ocs, "ocs_hw_set_dump_location failed\n");
+               goto free_and_return;
+       }
+
+       /* Generate the dump */
+       rc = ocs_gen_dump(ocs);
+       if (rc) {
+               ocs_log_test(ocs, "ocs_gen_dump failed\n");
+               goto free_and_return;
+       }
+
+       /* Copy the dump from the DMA buffer into the user buffer */
+       offset = 0;
+       for (i = 0; i < num_buffers; i++) {
+               if (ocs_copy_to_user((uint8_t*)buf + offset,
+                   dump_buffers[i].virt, dump_buffers[i].size)) {
+                       ocs_log_test(ocs, "ocs_copy_to_user failed\n");
+                       rc = -1;
+               }
+               offset += dump_buffers[i].size;
+       }
+
+free_and_return:
+       /* Free the DMA buffer and return */
+       for (i = 0; i < num_buffers; i++) {
+               ocs_dma_free(ocs, &dump_buffers[i]);
+       }
+       ocs_free(ocs, dump_buffers, sizeof(ocs_dma_t) * num_buffers);
+       return rc;
+}
+
+int
+ocs_function_speciic_dump(ocs_t *ocs, void *buf, uint32_t buflen)
+{
+       int rc;
+       uint32_t i, num_buffers;
+       ocs_dma_t *dump_buffers;
+       uint32_t rem_bytes, offset;
+
+       if (buflen == 0) {
+               ocs_log_err(ocs, "zero buffer length is invalid\n");
+               return -1;
+       }
+
+       num_buffers = ((buflen + OCS_MAX_DMA_ALLOC - 1) / OCS_MAX_DMA_ALLOC);
+
+       dump_buffers = ocs_malloc(ocs, sizeof(ocs_dma_t) * num_buffers,
+                                 OCS_M_ZERO | OCS_M_NOWAIT);
+       if (dump_buffers == NULL) {
+               ocs_log_err(ocs, "Failed to allocate dump buffers\n");
+               return -1;
+       }
+
+       /* Allocate a DMA buffers to hold the dump */
+       rem_bytes = buflen;
+       for (i = 0; i < num_buffers; i++) {
+               uint32_t num_bytes = MIN(rem_bytes, OCS_MAX_DMA_ALLOC);
+               rc = ocs_dma_alloc(ocs, &dump_buffers[i], num_bytes,
+                                  OCS_MIN_DMA_ALIGNMENT);
+               if (rc) {
+                       ocs_log_err(ocs, "Failed to allocate dma buffer\n");
+
+                       /* Free any previously allocated buffers */
+                       goto free_and_return;
+               }
+               rem_bytes -= num_bytes;
+       }
+
+       /* register buffers for function spcific dump */
+       rc = ocs_hw_set_dump_location(&ocs->hw, num_buffers, dump_buffers, 1);
+       if (rc) {
+               ocs_log_err(ocs, "ocs_hw_set_dump_location failed\n");
+               goto free_and_return;
+       }
+
+       /* Invoke dump by setting fdd=1 and ip=1 in sliport_control register */
+       rc = ocs_fdb_dump(ocs);
+       if (rc) {
+               ocs_log_err(ocs, "ocs_gen_dump failed\n");
+               goto free_and_return;
+       }
+
+       /* Copy the dump from the DMA buffer into the user buffer */
+       offset = 0;
+       for (i = 0; i < num_buffers; i++) {
+               if (ocs_copy_to_user((uint8_t*)buf + offset,
+                   dump_buffers[i].virt, dump_buffers[i].size)) {
+                       ocs_log_err(ocs, "ocs_copy_to_user failed\n");
+                       rc = -1;
+               }
+               offset += dump_buffers[i].size;
+       }
+
+free_and_return:
+       /* Free the DMA buffer and return */
+       for (i = 0; i < num_buffers; i++) {
+               ocs_dma_free(ocs, &dump_buffers[i]);
+       }
+       ocs_free(ocs, dump_buffers, sizeof(ocs_dma_t) * num_buffers);
+       return rc;
+
+}
diff --git a/sys/dev/ocs_fc/ocs_gendump.h b/sys/dev/ocs_fc/ocs_gendump.h
new file mode 100644
index 000000000000..2343003feef6
--- /dev/null
+++ b/sys/dev/ocs_fc/ocs_gendump.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2021 Broadcom. All rights reserved.
+ * The term "Broadcom" refers to Broadcom Limited and/or its subsidiaries.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its 
contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#if !defined(__OCS_GENDUMP_H__)
+#define __OCS_GENDUMP_H__
+extern int ocs_gen_dump(ocs_t *ocs);
+extern int ocs_fdb_dump(ocs_t *ocs);
+extern int ocs_dump_to_host(ocs_t *ocs, void *buf, uint32_t buflen);
+extern int ocs_function_speciic_dump(ocs_t *ocs, void *buf, uint32_t buflen);
+
+#define OCS_MAX_HBA_PORTS      4
+
+#endif // __OCS_GENDUMP_H__
diff --git a/sys/dev/ocs_fc/ocs_ioctl.c b/sys/dev/ocs_fc/ocs_ioctl.c
index 13d80bd3edde..c0576bd6600f 100644
--- a/sys/dev/ocs_fc/ocs_ioctl.c
+++ b/sys/dev/ocs_fc/ocs_ioctl.c
@@ -60,22 +60,12 @@ ocs_firmware_write(ocs_t *ocs, const uint8_t *buf, size_t 
buf_len, uint8_t *chan
 static int
 ocs_open(struct cdev *cdev, int flags, int fmt, struct thread *td)
 {
-#if 0
-       struct ocs_softc *ocs = cdev->si_drv1;
-
-       device_printf(ocs->dev, "%s\n", __func__);
-#endif
        return 0;
 }
 
 static int
 ocs_close(struct cdev *cdev, int flag, int fmt, struct thread *td)
 {
-#if 0
-       struct ocs_softc *ocs = cdev->si_drv1;
-
-       device_printf(ocs->dev, "%s\n", __func__);
-#endif
        return 0;
 }
 
@@ -95,7 +85,8 @@ __ocs_ioctl_mbox_cb(ocs_hw_t *hw, int32_t status, uint8_t 
*mqe, void *arg)
 }
 
 static int
-ocs_process_sli_config (ocs_t *ocs, ocs_ioctl_elxu_mbox_t *mcmd, ocs_dma_t 
*dma){
+ocs_process_sli_config (ocs_t *ocs, ocs_ioctl_elxu_mbox_t *mcmd, ocs_dma_t 
*dma)
+{
        sli4_cmd_sli_config_t *sli_config = (sli4_cmd_sli_config_t 
*)mcmd->payload;
 
        if (sli_config->emb) {
diff --git a/sys/dev/ocs_fc/ocs_ioctl.h b/sys/dev/ocs_fc/ocs_ioctl.h
index ad2460d09b87..f2a291843d5a 100644
--- a/sys/dev/ocs_fc/ocs_ioctl.h
+++ b/sys/dev/ocs_fc/ocs_ioctl.h
@@ -303,18 +303,21 @@ typedef struct {
 
 typedef struct {
        uint8_t         *name;                  /*<< Input: name of property to 
retrieve */
+       uint16_t        name_len;               /*<< Input: Length of name */
        uint8_t         *value;                 /*<< Output: user space buffer 
in which to place the response */
        uint32_t        value_length;           /*<< Input: size of the user 
space buffer */
 } ocs_ioctl_cmd_get_t;
 
 typedef struct {
        uint8_t         *name;                  /*<< Input: name of property to 
set */
+       uint16_t        name_len;               /*<< Input: Length of name */
        uint8_t         *value;                 /*<< Input: user space buffer 
which contains the new value */
        int32_t         result;                 /*<< Output: result */
 } ocs_ioctl_cmd_set_t;
 
 typedef struct {
        uint8_t         *name;                  /*<< Input: name of action to 
execute */
+       uint16_t        name_len;               /*<< Input: Length of name */
        void            *arg_in;                /*<< Input: pointer to argument 
in user space */
        uint32_t        arg_in_length;          /*<< Input: size of arg_in in 
bytes */
        void            *arg_out;               /*<< Output: pointer to 
argument from kernel to user */
diff --git a/sys/dev/ocs_fc/ocs_mgmt.c b/sys/dev/ocs_fc/ocs_mgmt.c
index 1f22a0316791..ff0e028caea2 100644
--- a/sys/dev/ocs_fc/ocs_mgmt.c
+++ b/sys/dev/ocs_fc/ocs_mgmt.c
@@ -42,6 +42,7 @@
 
 #include "ocs.h"
 #include "ocs_mgmt.h"
+#include "ocs_gendump.h"
 #include "ocs_vpd.h"
 
 #define SFP_PAGE_SIZE 128
@@ -55,11 +56,6 @@ static int ocs_mgmt_function_reset(ocs_t *ocs, char *, void 
*buf, uint32_t buf_l
 static void ocs_mgmt_fw_write_cb(int32_t status, uint32_t actual_write_length, 
uint32_t change_status, void *arg);
 static int ocs_mgmt_force_assert(ocs_t *ocs, char *, void *buf, uint32_t 
buf_len, void*, uint32_t);
 
-#if defined(OCS_INCLUDE_RAMD)
-static int32_t
-ocs_mgmt_read_phys(ocs_t *ocs, char *, void *, uint32_t , void *, uint32_t);
-#endif
-
 /* Getters */
 
 static void get_nodes_count(ocs_t *, char *, ocs_textbuf_t*);
@@ -141,9 +137,6 @@ static int set_nv_wwn(ocs_t*, char*, char*);
 static int set_loglevel(ocs_t*, char*, char*);
 
 static void ocs_mgmt_linkcfg_cb(int32_t status, uintptr_t value, void *arg);
-#if defined(OCS_INCLUDE_RAMD)
-static void* find_address_in_target(ocs_ramdisc_t **ramdisc_array, uint32_t 
ramdisc_count, uintptr_t target_addr);
-#endif
 
 ocs_mgmt_table_entry_t mgmt_table[] = {
                {"nodes_count", get_nodes_count, NULL, NULL},
@@ -193,9 +186,6 @@ ocs_mgmt_table_entry_t mgmt_table[] = {
                {"firmware_write", NULL, NULL, ocs_mgmt_firmware_write},
                {"firmware_reset", NULL, NULL, ocs_mgmt_firmware_reset},
                {"function_reset", NULL, NULL, ocs_mgmt_function_reset},
-#if defined(OCS_INCLUDE_RAMD)
-               {"read_phys", NULL, NULL, ocs_mgmt_read_phys},
-#endif
                {"force_assert", NULL, NULL, ocs_mgmt_force_assert},
 
                {"tgt_rscn_delay", get_tgt_rscn_delay, set_tgt_rscn_delay, 
NULL},
@@ -490,6 +480,15 @@ ocs_mgmt_exec(ocs_t *ocs, char *action, void *arg_in,
                        }
                }
 
+               /* See if it's a value I can supply */
+               if (ocs_strcmp(unqualified_name, "driver/gendump") == 0) {
+                       return ocs_gen_dump(ocs);
+               }
+
+               if (ocs_strcmp(unqualified_name, "driver/dump_to_host") == 0) {
+                       return ocs_dump_to_host(ocs, arg_out, arg_out_length);
+               }
+
                if ((ocs->mgmt_functions) && 
(ocs->mgmt_functions->exec_handler)) {
                        result = ocs->mgmt_functions->exec_handler(qualifier, 
action, arg_in, arg_in_length,
                                                                   arg_out, 
arg_out_length, ocs);
@@ -559,137 +558,6 @@ ocs_mgmt_get_all(ocs_t *ocs, ocs_textbuf_t *textbuf)
        ocs_mgmt_end_unnumbered_section(textbuf, "ocs");
 }
 
-#if defined(OCS_INCLUDE_RAMD)
-static int32_t
-ocs_mgmt_read_phys(ocs_t *ocs, char *name, void *arg_in, uint32_t 
arg_in_length, void *arg_out, uint32_t arg_out_length)
-{
-        uint32_t length;
-        char addr_str[80];
-        uintptr_t target_addr;
-        void* vaddr = NULL;
-        ocs_ramdisc_t **ramdisc_array;
-        uint32_t ramdisc_count;
-
-        if ((arg_in == NULL) ||
-            (arg_in_length == 0) ||
-            (arg_out == NULL) ||
-            (arg_out_length == 0)) {
-                return -1;
-        }
-
-        if (arg_in_length > 80) {
-                arg_in_length = 80;
-        }
-
-        if (ocs_copy_from_user(addr_str, arg_in, arg_in_length)) {
-                ocs_log_test(ocs, "Failed to copy addr from user\n");
-                return -EFAULT;
-        }
-
-        target_addr = (uintptr_t)ocs_strtoul(addr_str, NULL, 0);
-        /* addr_str must be the physical address of a buffer that was reported
-         * in an SGL.  Search ramdiscs looking for a segment that contains that
-         * physical address
-         */
-
-        if (ocs->tgt_ocs.use_global_ramd) {
-                /* Only one target */
-                ramdisc_count = ocs->tgt_ocs.rdisc_count;
-                ramdisc_array = ocs->tgt_ocs.rdisc;
-                vaddr = find_address_in_target(ramdisc_array, ramdisc_count, 
target_addr);
-        } else {
-                /* Multiple targets.  Each target is on a sport */
-               uint32_t domain_idx;
-
-               for (domain_idx=0; domain_idx<ocs->domain_instance_count; 
domain_idx++) {
-                       ocs_domain_t *domain;
-                       uint32_t sport_idx;
-
-                       domain = ocs_domain_get_instance(ocs, domain_idx);
-                       for (sport_idx=0; sport_idx < 
domain->sport_instance_count; sport_idx++) {
-                               ocs_sport_t *sport;
-
-                               sport = ocs_sport_get_instance(domain, 
sport_idx);
-                               ramdisc_count = sport->tgt_sport.rdisc_count;
-                               ramdisc_array = sport->tgt_sport.rdisc;
-                               vaddr = find_address_in_target(ramdisc_array, 
ramdisc_count, target_addr);
-
-                               if (vaddr != NULL) {
-                                       break;
-                               }
-                       }
-                }
-        }
-
-        length = arg_out_length;
-
-        if (vaddr != NULL) {
-                if (ocs_copy_to_user(arg_out, vaddr, length)) {
-                        ocs_log_test(ocs, "Failed to copy buffer to user\n");
-                        return -EFAULT;
-                }
-
-                return 0;
-        } else {
-                return -EFAULT;
-       }
-
-}
-
-/*
- * This function searches a target for a given physical address.
- * The target is made up of a number of LUNs, each represented by
- * a ocs_ramdisc_t.
- */
-static void* find_address_in_target(ocs_ramdisc_t **ramdisc_array, uint32_t 
ramdisc_count, uintptr_t target_addr)
-{
-       void *vaddr = NULL;
-       uint32_t ramdisc_idx;
-
-       /* Check each ramdisc */
-       for (ramdisc_idx=0; ramdisc_idx<ramdisc_count; ramdisc_idx++) {
-               uint32_t segment_idx;
-               ocs_ramdisc_t *rdisc;
-               rdisc = ramdisc_array[ramdisc_idx];
-               /* Check each segment in the ramdisc */
-               for (segment_idx=0; segment_idx<rdisc->segment_count; 
segment_idx++) {
-                       ramdisc_segment_t *segment = 
rdisc->segments[segment_idx];
-                       uintptr_t segment_start;
-                       uintptr_t segment_end;
-                       uint32_t offset;
-
-                       segment_start = segment->data_segment.phys;
-                       segment_end = segment->data_segment.phys + 
segment->data_segment.size - 1;
-                       if ((target_addr >= segment_start) && (target_addr <= 
segment_end)) {
-                               /* Found the target address */
-                               offset = target_addr - segment_start;
-                               vaddr = (uint32_t*)segment->data_segment.virt + 
offset;
-                       }
-
-                       if (rdisc->dif_separate) {
-                               segment_start = segment->dif_segment.phys;
-                               segment_end = segment->data_segment.phys + 
segment->dif_segment.size - 1;
-                               if ((target_addr >= segment_start) && 
(target_addr <= segment_end)) {
-                                       /* Found the target address */
-                                       offset = target_addr - segment_start;
-                                       vaddr = 
(uint32_t*)segment->dif_segment.virt + offset;
-                               }
-                       }
-
-                       if (vaddr != NULL) {
-                               break;
-                       }
-               }
-
-               if (vaddr != NULL) {
-                       break;
-               }
-       }
-
-       return vaddr;
-}
-#endif
-
 static int32_t
 ocs_mgmt_firmware_reset(ocs_t *ocs, char *name, void *buf, uint32_t buf_len, 
void *arg_out, uint32_t arg_out_length)
 {
diff --git a/sys/dev/ocs_fc/ocs_os.c b/sys/dev/ocs_fc/ocs_os.c
index 985a611ba91e..4e4edea2e63f 100644
--- a/sys/dev/ocs_fc/ocs_os.c
+++ b/sys/dev/ocs_fc/ocs_os.c
@@ -883,13 +883,12 @@ ocs_pci_model(uint16_t vendor, uint16_t device)
        return "unknown";
 }
 
-int32_t
+void
 ocs_get_bus_dev_func(ocs_t *ocs, uint8_t* bus, uint8_t* dev, uint8_t* func)
 {
        *bus = pci_get_bus(ocs->dev);
        *dev = pci_get_slot(ocs->dev);
        *func= pci_get_function(ocs->dev);
-       return 0;
 }
 
 /**
diff --git a/sys/dev/ocs_fc/ocs_os.h b/sys/dev/ocs_fc/ocs_os.h
index acc1a9b1cc19..5e36cca3b829 100644
--- a/sys/dev/ocs_fc/ocs_os.h
+++ b/sys/dev/ocs_fc/ocs_os.h
@@ -1050,9 +1050,8 @@ typedef struct ocs_pci_reg_s {
  * @param dev Pointer to location to store the device number.
  * @param func Pointer to location to store the function number.
  *
- * @return Returns 0.
  */
-extern int32_t
+extern void
 ocs_get_bus_dev_func(ocs_t *ocs, uint8_t* bus, uint8_t* dev, uint8_t* func);
 
 extern ocs_t *ocs_get_instance(uint32_t index);
diff --git a/sys/modules/ocs_fc/Makefile b/sys/modules/ocs_fc/Makefile
index 9bab50eba5bc..8d546f9eabfd 100644
--- a/sys/modules/ocs_fc/Makefile
+++ b/sys/modules/ocs_fc/Makefile
@@ -33,7 +33,8 @@ SRCS += \
        ocs_scsi.c \
        ocs_unsol.c \
        ocs_ddump.c \
-       ocs_mgmt.c 
+       ocs_mgmt.c \
+       ocs_gendump.c
 
 
 # CAM initiator/target
_______________________________________________
dev-commits-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/dev-commits-src-all
To unsubscribe, send any mail to "dev-commits-src-all-unsubscr...@freebsd.org"

Reply via email to