Emulex Logo
OneCoreā„¢ Storage SDK Release 11.2
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
ocs_elxu.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2011-2015, Emulex
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are met:
7  *
8  * 1. Redistributions of source code must retain the above copyright notice,
9  * this list of conditions and the following disclaimer.
10  *
11  * 2. Redistributions in binary form must reproduce the above copyright notice,
12  * this list of conditions and the following disclaimer in the documentation
13  * and/or other materials provided with the distribution.
14  *
15  * 3. Neither the name of the copyright holder nor the names of its contributors
16  * may be used to endorse or promote products derived from this software
17  * without specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
23  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29  * POSSIBILITY OF SUCH DAMAGE.
30  *
31  */
32 
33 /**
34  * @file
35  * Elxutility interface code
36  */
37 
38 
39 #include "ocs.h"
40 #include "ocs_ioctl.h"
41 #include "ocs_elxu.h"
42 
43 static int32_t __ocs_ioctl_mbox_cb(ocs_hal_t *hal, int32_t status, uint8_t *mqe, void *arg);
44 
45 int32_t
46 ocs_process_sli_config(ocs_t *ocs, ocs_ioctl_elxu_mbox_t *mcmd, ocs_dma_t *dma)
47 {
49 
50  if (sli_config->emb) {
51  sli4_req_hdr_t *req = (sli4_req_hdr_t *)sli_config->payload.embed;
52 
53  switch (req->opcode) {
55  if (mcmd->out_bytes) {
58 
59  if (ocs_dma_alloc(ocs, dma, mcmd->out_bytes, 4096)) {
60  ocs_log_err(ocs, "COMMON_READ_OBJECT - %" PRIX64 " allocation failed\n",
61  mcmd->out_bytes);
62  return ENXIO;
63  }
64 
65  memset(dma->virt, 0, mcmd->out_bytes);
66 
69  rdobj->host_buffer_descriptor[0].u.data.buffer_address_low = ocs_addr32_lo(dma->phys);
70  rdobj->host_buffer_descriptor[0].u.data.buffer_address_high = ocs_addr32_hi(dma->phys);
71 
72 #if !defined(OCSU_FC_RAMD) && !defined(OCSU_FC_WORKLOAD) && !defined(OCS_USPACE_SPDK)
73  if (ocs->fw_dump.type == FW_DUMP_TYPE_FLASH) {
74  if (0 == ocs_strncmp(rdobj->object_name, READ_OBJECT_NAME_DUMP,
75  sizeof(rdobj->object_name))) {
76  /*
77  * Reset FW dump flags here when the first readobject for dump
78  * was requested.
79  */
81  }
82  }
83 #endif
84  }
85  break;
87  {
90 
91  if (ocs_dma_alloc(ocs, dma, wrobj->desired_write_length, 4096)) {
92  ocs_log_err(ocs, "COMMON_WRITE_OBJECT - %d allocation failed\n",
93  wrobj->desired_write_length);
94  return ENXIO;
95  }
96  // setup the descriptor
99  wrobj->host_buffer_descriptor[0].u.data.buffer_address_low = ocs_addr32_lo(dma->phys);
100  wrobj->host_buffer_descriptor[0].u.data.buffer_address_high = ocs_addr32_hi(dma->phys);
101 
102  // copy the data into the DMA buffer
103  if (ocs_copy_from_user(dma->virt, (void *)mcmd->in_addr, mcmd->in_bytes)) {
104  ocs_log_warn(ocs, "copy_from_user() failed\n");
105  return EFAULT;
106  }
107 
108  }
109  break;
111  break;
113  if (mcmd->out_bytes) {
116  if (ocs_dma_alloc(ocs, dma, mcmd->out_bytes, 4096)) {
117  ocs_log_err(ocs, "COMMON_READ_OBJECT_LIST - %" PRIX64 " allocation failed\n",
118  mcmd->out_bytes);
119  return ENXIO;
120  }
121 
122  ocs_memset(dma->virt, 0, mcmd->out_bytes);
123 
126  rdobj->host_buffer_descriptor[0].u.data.buffer_address_low = ocs_addr32_lo(dma->phys);
127  rdobj->host_buffer_descriptor[0].u.data.buffer_address_high = ocs_addr32_hi(dma->phys);
128 
129  }
130  break;
132  break;
136  break;
137 
138  default:
139  ocs_log_info(ocs, "in=%p (%" PRIX64 ") out=%p (%" PRIX64 ")\n",
140  (void *)mcmd->in_addr, mcmd->in_bytes,
141  (void *)mcmd->out_addr, mcmd->out_bytes);
142  ocs_log_info(ocs, "unknown (opc=%#x)\n",
143  req->opcode);
144  break;
145  }
146  } else {
147  uint32_t max_bytes = max(mcmd->in_bytes, mcmd->out_bytes);
148  if (ocs_dma_alloc(ocs, dma, max_bytes, 4096)) {
149  ocs_log_err(ocs, "non-embedded - %u allocation failed\n", max_bytes);
150  return ENXIO;
151  }
152 
153  if (ocs_copy_from_user(dma->virt, (void *)mcmd->in_addr, mcmd->in_bytes)) {
154  ocs_log_warn(ocs, "copy_from_user failed\n");
155  return ENXIO;
156  }
157 
158  sli_config->payload.mem.address_low = ocs_addr32_lo(dma->phys);
159  sli_config->payload.mem.address_high = ocs_addr32_hi(dma->phys);
160  sli_config->payload.mem.length = max_bytes;
161  }
162 
163  return 0;
164 }
165 
166 int32_t
167 ocs_elxu(ocs_t *ocs, ocs_ioctl_elxu_mbox_t *mcmd)
168 {
169  int32_t rc = 0;
170  ocs_dma_t dma = { 0 };
171  ocs_sem_t waitsem;
172 
173  // sanity checks
174  if ((ELXU_BSD_MAGIC != mcmd->magic) ||
175  (sizeof(*mcmd) != mcmd->size)) {
176  ocs_log_debug(ocs, "malformed command m=%08x s=%08x\n",
177  mcmd->magic, mcmd->size);
178  return EINVAL;
179  }
180 
181  switch(((sli4_mbox_command_header_t *)mcmd->payload)->command)
182  {
184  if (ENXIO == ocs_process_sli_config(ocs, mcmd, &dma))
185  return ENXIO;
186  break;
187 
193  break;
194 
195  default:
196  ocs_log_debug(NULL, "command %d\n",((sli4_mbox_command_header_t *)mcmd->payload)->command);
197  ocs_log_debug(NULL, "command not support\n");
198  goto no_support;
199  break;
200 
201  } // end for switch( ... -> command )
202 
203  ocs_sem_init(&waitsem, 0, "elxu_mbox");
204 
205  rc = ocs_hal_command(&ocs->hal, mcmd->payload, OCS_CMD_NOWAIT, __ocs_ioctl_mbox_cb, &waitsem);
206  if (rc)
207  goto dma_free;
208 
209  if (ocs_sem_p(&waitsem, OCS_SEM_FOREVER) == 0) {
211  mcmd->out_bytes && dma.virt) {
212  if (ocs_copy_to_user((void *)mcmd->out_addr, dma.virt, mcmd->out_bytes)) {
213  ocs_log_warn(ocs, "copy_to_user failed\n");
214  rc = -ENXIO;
215  }
216  }
217  } else {
218  ocs_log_warn(ocs, "hal command was interrupted\n");
219  rc = -ENXIO;
220  }
221 
222 dma_free:
223  ocs_dma_free(ocs, &dma);
224 
225 no_support:
226  return rc;
227 }
228 
229 static int32_t
230 __ocs_ioctl_mbox_cb(ocs_hal_t *hal, int32_t status, uint8_t *mqe, void *arg)
231 {
232  ocs_sem_t *sem = arg;
233 
234  ocs_sem_v(sem);
235 
236  return 0;
237 
238 }
union sli4_cmd_sli_config_t::@36 payload
union sli4_bde_t::@27 u
sli4_bde_t host_buffer_descriptor[0]
Definition: sli4.h:2681
int32_t ocs_process_sli_config(ocs_t *ocs, ocs_ioctl_elxu_mbox_t *mcmd, ocs_dma_t *dma)
Definition: ocs_elxu.c:46
uint32_t buffer_length
Definition: sli4.h:469
sli4_sli_config_pmd_t mem
Definition: sli4.h:1266
#define SLI4_MBOX_COMMAND_DUMP
Definition: sli4.h:429
int32_t ocs_elxu(ocs_t *ocs, ocs_ioctl_elxu_mbox_t *mcmd)
Definition: ocs_elxu.c:167
struct sli4_bde_t::@27::@28 data
sli4_bde_t host_buffer_descriptor[0]
Definition: sli4.h:2609
IOCTL_CMD_IOCTL_ELXU_MBOX ioctl structure.
Definition: ocs_ioctl.h:89
#define SLI4_MBOX_COMMAND_SLI_CONFIG
Definition: sli4.h:450
#define READ_OBJECT_NAME_DUMP
Definition: ocs_elxu.h:45
uint32_t length
Definition: sli4.h:1249
COMMON_READ_OBJECT.
Definition: sli4.h:2601
#define SLI4_MBOX_COMMAND_READ_STATUS
Definition: sli4.h:437
uint32_t opcode
Definition: sli4.h:1668
#define SLI4_OPC_COMMON_WRITE_OBJECT
Definition: sli4.h:1643
uint32_t address_low
Definition: sli4.h:1247
#define SLI4_OPC_FCOE_SET_DPORT_MODE
Definition: sli4.h:1653
uint8_t payload[256]
Definition: ocs_ioctl.h:92
#define SLI4_OPC_FCOE_GET_DPORT_RESULTS
Definition: sli4.h:1654
COMMON_READ_OBJECT_LIST.
Definition: sli4.h:2673
sli4_bde_t host_buffer_descriptor[0]
Definition: sli4.h:2639
uint8_t object_name[104]
Definition: sli4.h:2607
#define SLI4_OPC_COMMON_RUN_BIU_DIAG
Definition: sli4.h:1635
#define SLI4_OPC_COMMON_READ_OBJECT
Definition: sli4.h:1642
uint32_t address_high
Definition: sli4.h:1248
#define SLI4_MBOX_COMMAND_READ_LNK_STAT
Definition: sli4.h:440
#define SLI4_OPC_FCOE_SET_LINK_DIAG_STATE
Definition: sli4.h:1651
#define SLI4_OPC_COMMON_READ_OBJECT_LIST
Definition: sli4.h:1645
static int32_t __ocs_ioctl_mbox_cb(ocs_hal_t *hal, int32_t status, uint8_t *mqe, void *arg)
Definition: ocs_elxu.c:230
#define ELXU_BSD_MAGIC
Definition: ocs_ioctl.h:80
void ocs_fw_dump_state_set(ocs_t *ocs, uint32_t state)
Set fW dump state.
Definition: ocs_recovery.c:231
#define SLI4_MBOX_COMMAND_READ_REV
Definition: sli4.h:439
COMMON_WRITE_OBJECT.
Definition: sli4.h:2629
uint8_t embed[58 *sizeof(uint32_t)]
Definition: sli4.h:1265
uint32_t bde_type
Definition: sli4.h:469
ocs_hal_rtn_e ocs_hal_command(ocs_hal_t *hal, uint8_t *cmd, uint32_t opts, void *cb, void *arg)
Issue a SLI command.
Definition: ocs_hal.c:2731
#define SLI4_BDE_TYPE_BDE_64
Definition: sli4.h:490
#define FW_DUMP_STATE_NONE
Definition: ocs_gendump.h:59
Generic Command Request header.
Definition: sli4.h:1666
#define SLI4_OPC_COMMON_DELETE_OBJECT
Definition: sli4.h:1644
#define FW_DUMP_TYPE_FLASH
Definition: ocs_gendump.h:65
#define SLI4_OPC_COMMON_READ_TRANSCEIVER_DATA
Definition: sli4.h:1628