git: 29e2dbd42c3e - main - ocs_fc: Add gendump and dump_to_host ioctl command support.
Ram Kishore Vegesna
ram at FreeBSD.org
Tue Jul 6 15:48:02 UTC 2021
The branch main has been updated by ram:
URL: https://cgit.FreeBSD.org/src/commit/?id=29e2dbd42c3e2e10e606b3414f4d0c53021d4e86
commit 29e2dbd42c3e2e10e606b3414f4d0c53021d4e86
Author: Ram Kishore Vegesna <ram at FreeBSD.org>
AuthorDate: 2021-06-24 07:05:00 +0000
Commit: Ram Kishore Vegesna <ram at 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
More information about the dev-commits-src-main
mailing list