Emulex Logo
OneCoreā„¢ Storage SDK Release 11.2
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
ecdtest.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 ECD library test progrem
35  *
36  * This is a user space test program that uses the elxcdul library to retrieve coreDump
37  * information from Emulex HBA's that support the capability.
38  *
39  * In this example, the helper functions run on top of Emulex OCS driver, using an
40  * ioctl() interface.
41  */
42 
43 #include <stdio.h>
44 #include <stdlib.h>
45 #include <stdint.h>
46 #include <string.h>
47 #include <stdarg.h>
48 #include <ctype.h>
49 #include <sys/ioctl.h>
50 #include <sys/stat.h>
51 #include <fcntl.h>
52 #include <unistd.h>
53 #include <sys/utsname.h>
54 
55 #include <ecd_api.h>
56 
57 #define DEFAULT_OFNAME "out.core"
58 #define DEVNAME_TEMPLATE "/dev/ocs_%d"
59 
60 /**
61  * @brief user provided context passed to the helper functions
62  */
63 typedef struct {
64  int fd;
66 
67 /****************************************************************************************************
68  * OCS IOCTL declarations
69  *
70  * Warning: these ioctl() structures need to be in sync with OCS driver declarations
71  */
72 
73 typedef struct {
74  uint16_t pci_vendor;
75  uint16_t pci_device;
76  char businfo[16];
77  uint32_t sli_intf;
78  char desc[64];
79  char fw_rev[32];
80  uint8_t wwnn[8];
81  uint8_t wwpn[8];
82  char serialnum[32];
84 
85 typedef enum {
99 
100 typedef struct {
102  uint32_t bar;
103  uint32_t offset;
104  uint32_t data;
105  int status;
107 
108 #define OCS_IOCTL_CMD_BASE 'o'
109 #define OCS_IOCTL_CMD_DRIVER_INFO _IOWR(OCS_IOCTL_CMD_BASE, 4, ocs_ioctl_driver_info_t)
110 #define OCS_IOCTL_CMD_ECD_HELPER _IOWR(OCS_IOCTL_CMD_BASE, 5, ocs_ioctl_ecd_helper_t)
111 
112 #if !defined(ARRAY_SIZE)
113 #define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0]))
114 #endif
115 
116 static int enable_helper_trace = 0;
117 
118 #define helper_trace(fmt, ...) \
119  do { \
120  if (enable_helper_trace) \
121  printf(fmt, ##__VA_ARGS__); \
122  } while(0)
123 
124 static void usage(void);
125 
126 int main(int argc, char *argv[])
127 {
128  int i;
129  int rc;
130  ecdtest_context_t ctx;
131  uint8_t *buffer;
132  uint32_t bufferLength;
133  char *test_template_ecdargs[] = {"dead", "testtemplate"};
134  char *be3_template_ecdargs[] = {"dead", "be3template"};
135  char **ecdargs = be3_template_ecdargs;
136  uint32_t ecdargs_count = ARRAY_SIZE(be3_template_ecdargs);
137  struct utsname utsname;
138  ecd_fwState_t fwState = 0;
139  ecd_get_params_t params;
140  char *ofname = DEFAULT_OFNAME;
141  int devNum = 0;
142  char devname[FILENAME_MAX];
144  int major;
145  int minor;
146  int release;
147 
148  for (i = 1; i < argc; i ++)
149  if (*argv[i] == '-')
150  switch (*(argv[i]+1)) {
151  case 'o':
152  if (++i < argc)
153  ofname = argv[i];
154  break;
155  case 'd':
156  if (++i < argc)
157  devNum = atoi(argv[i]);
158  break;
159  case 't':
161  break;
162  case '-':
163  if (strcmp(argv[i], "--test") == 0) {
164  ecdargs = test_template_ecdargs;
165  ecdargs_count = ARRAY_SIZE(test_template_ecdargs);
166  }
167  else if (strcmp(argv[i], "--be3") == 0) {
168  ecdargs = be3_template_ecdargs;
169  ecdargs_count = ARRAY_SIZE(be3_template_ecdargs);
170  }
171  else
172  usage();
173  // no return
174  break;
175 
176  default:
177  usage();
178  // no return
179  }
180 
181 
182  /* Initialize user context */
183  memset(&ctx, 0, sizeof(ctx));
184 
185  snprintf(devname, sizeof(devname), DEVNAME_TEMPLATE, devNum);
186 
187  ctx.fd = open(devname, O_RDWR);
188  if (ctx.fd < 0) {
189  printf("Error: can't open %s\n", devname);
190  return -1;
191  }
192 
193  /* Allocate a buffer */
194  bufferLength = 32*1024*1024;
195  buffer = malloc(bufferLength);
196  if (buffer == NULL) {
197  printf("Error: buffer malloc %d failed\n", bufferLength);
198  return -1;
199  }
200 
201  fwState = ECD_FW_STATE_UE;
202 
203  /* Build parameters */
204  memset(&params, 0, sizeof(params));
205  params.instance = devNum;
206 
207  /* Using uname() system call fetch required parameter information */
208  rc = uname(&utsname);
209 
210  if (rc != 0) {
211  strncpy(params.system_name, "unknown", sizeof(params.system_name));
212  strncpy(params.os_name, "unknown", sizeof(params.os_name));
213  } else {
214  strncpy(params.os_name, utsname.release, sizeof(params.os_name));
215  strncpy(params.system_name, utsname.nodename, sizeof(params.system_name));
216  }
217  params.ioctl_high_version = 1;
218  params.ioctl_low_version = 0;
219 
220  /* Parse out the linux version, pass in 2.6.32 as 26.32 */
221  sscanf(utsname.release, "%d.%d.%d", &major, &minor, &release);
222  params.os_major = major*10 + minor;
223  params.os_minor = release;
224 
225  /* We need to get the SLI_INTF register value for this device using a driver ioctl */
226  rc = ioctl(ctx.fd, OCS_IOCTL_CMD_DRIVER_INFO, &info);
227  if (rc) {
228  printf("Error: OCS_IOCTL_CMD_DRIVER_INFO failed: %d\n", rc);
229  return -1;
230  }
231  else
232  params.sli_intf = info.sli_intf;
233 
234  /* Get the core dump data */
235  rc = ecd_GetCoreDumpData(&ctx, fwState, &params, buffer, bufferLength, ecdargs_count, ecdargs);
236 
237  /* A return value >= 0 means that there is data in the buffer */
238  if ((rc > 0) && (ofname != NULL)) {
239  FILE *out;
240  uint32_t len = rc;
241 
242  out = fopen(ofname, "wb");
243  if (out == NULL)
244  printf("Error: can't create %s\n", ofname);
245  else {
246  rc = fwrite(buffer, 1, len, out);
247  if (rc != len)
248  printf("Error: fwrite failed: %d\n", rc);
249  fclose(out);
250  }
251  }
252 
253  free(buffer);
254 
255  return 0;
256 }
257 
258 static void usage(void)
259 {
260  printf("Usage: ecdtest options\n");
261  printf(" -o output-file # default out.core\n");
262  printf(" -d device-instance # default 0\n");
263  printf(" -t # enable helper funtion trace\n");
264  printf(" --test # use test template\n");
265  printf(" --be3 # use BE3 template (default)\n");
266  exit(0);
267 }
268 
269 /****************************************************************************************************
270  * Helper functions
271  *
272  * These helper functions implement an interface to the Emulex OCS driver using the ioctl() interface.
273  *
274  * The customer implementation would replace these with functions that interface to their particular
275  * driver.
276  */
277 
278 void ecd_log(char *fmt, ...)
279 {
280  va_list ap;
281 
282  va_start(ap, fmt);
283  vprintf(fmt, ap);
284 }
285 
286 void os_assert(char *message, uint32_t Line, char *File)
287 {
288  ecd_log("%s(%d) %s\n", File, Line, message);
289  exit(0);
290 }
291 
292 void os_stall(void *ctx, uint32_t usecTime)
293 {
294  usleep(usecTime);
295 }
296 
297 void os_cfg_read8 (void *ctx, uint32_t offset, uint32_t *pdata)
298 {
299  int32_t rc;
300  ecdtest_context_t *ecd = ctx;
302 
303  helper_trace("%-16s: offset x%x\n", __func__, offset);
304 
305  memset(&cmd, 0, sizeof(cmd));
307  cmd.offset = offset;
308 
309  rc = ioctl(ecd->fd, OCS_IOCTL_CMD_ECD_HELPER, &cmd);
310  if (rc == 0)
311  *pdata = cmd.data;
312 }
313 
314 void os_cfg_read16(void *ctx, uint32_t offset, uint32_t *pdata)
315 {
316  int32_t rc;
317  ecdtest_context_t *ecd = ctx;
319 
320  helper_trace("%-16s: offset x%x\n", __func__, offset);
321 
322  memset(&cmd, 0, sizeof(cmd));
324  cmd.offset = offset;
325 
326  rc = ioctl(ecd->fd, OCS_IOCTL_CMD_ECD_HELPER, &cmd);
327  if (rc == 0)
328  *pdata = cmd.data;
329 }
330 void os_cfg_read32(void *ctx, uint32_t offset, uint32_t *pdata)
331 {
332  int32_t rc;
333  ecdtest_context_t *ecd = ctx;
335 
336  helper_trace("%-16s: offset x%x\n", __func__, offset);
337 
338  memset(&cmd, 0, sizeof(cmd));
340  cmd.offset = offset;
341 
342  rc = ioctl(ecd->fd, OCS_IOCTL_CMD_ECD_HELPER, &cmd);
343  if (rc == 0)
344  *pdata = cmd.data;
345 }
346 void os_cfg_write8 (void *ctx, uint32_t offset, uint32_t data)
347 {
348  ecdtest_context_t *ecd = ctx;
350 
351  helper_trace("%-16s: offset x%x\n", __func__, offset);
352 
353  memset(&cmd, 0, sizeof(cmd));
355  cmd.offset = offset;
356  cmd.data = data;
357 
358  ioctl(ecd->fd, OCS_IOCTL_CMD_ECD_HELPER, &cmd);
359 }
360 void os_cfg_write16(void *ctx, uint32_t offset, uint32_t data)
361 {
362  ecdtest_context_t *ecd = ctx;
364 
365  helper_trace("%-16s: offset x%x\n", __func__, offset);
366 
367  memset(&cmd, 0, sizeof(cmd));
369  cmd.offset = offset;
370  cmd.data = data;
371 
372  ioctl(ecd->fd, OCS_IOCTL_CMD_ECD_HELPER, &cmd);
373 }
374 void os_cfg_write32(void *ctx, uint32_t offset, uint32_t data)
375 {
376  ecdtest_context_t *ecd = ctx;
378 
379  helper_trace("%-16s: offset x%x\n", __func__, offset);
380 
381  memset(&cmd, 0, sizeof(cmd));
383  cmd.offset = offset;
384  cmd.data = data;
385 
386  ioctl(ecd->fd, OCS_IOCTL_CMD_ECD_HELPER, &cmd);
387 }
388 void os_bar_read8 (void *ctx, uint32_t bar, uint32_t offset, uint32_t *pdata)
389 {
390  int32_t rc;
391  ecdtest_context_t *ecd = ctx;
393 
394  helper_trace("%-16s: bar %d offset x%x\n", __func__, bar, offset);
395 
396  memset(&cmd, 0, sizeof(cmd));
398  cmd.bar = bar;
399  cmd.offset = offset;
400 
401  rc = ioctl(ecd->fd, OCS_IOCTL_CMD_ECD_HELPER, &cmd);
402  if (rc == 0)
403  *pdata = cmd.data;
404 }
405 void os_bar_read16(void *ctx, uint32_t bar, uint32_t offset, uint32_t *pdata)
406 {
407  int32_t rc;
408  ecdtest_context_t *ecd = ctx;
410 
411  helper_trace("%-16s: bar %d offset x%x\n", __func__, bar, offset);
412 
413  memset(&cmd, 0, sizeof(cmd));
415  cmd.bar = bar;
416  cmd.offset = offset;
417 
418  rc = ioctl(ecd->fd, OCS_IOCTL_CMD_ECD_HELPER, &cmd);
419  if (rc == 0)
420  *pdata = cmd.data;
421 }
422 void os_bar_read32(void *ctx, uint32_t bar, uint32_t offset, uint32_t *pdata)
423 {
424  int32_t rc;
425  ecdtest_context_t *ecd = ctx;
427 
428  helper_trace("%-16s: bar %d offset x%x\n", __func__, bar, offset);
429 
430  memset(&cmd, 0, sizeof(cmd));
432  cmd.bar = bar;
433  cmd.offset = offset;
434 
435  rc = ioctl(ecd->fd, OCS_IOCTL_CMD_ECD_HELPER, &cmd);
436  if (rc == 0)
437  *pdata = cmd.data;
438 }
439 void os_bar_write8 (void *ctx, uint32_t bar, uint32_t offset, uint32_t data)
440 {
441  ecdtest_context_t *ecd = ctx;
443 
444  helper_trace("%-16s: bar %d offset x%x\n", __func__, bar, offset);
445 
446  memset(&cmd, 0, sizeof(cmd));
448  cmd.bar = bar;
449  cmd.offset = offset;
450  cmd.data = data;
451 
452  ioctl(ecd->fd, OCS_IOCTL_CMD_ECD_HELPER, &cmd);
453 }
454 void os_bar_write16(void *ctx, uint32_t bar, uint32_t offset, uint32_t data)
455 {
456  ecdtest_context_t *ecd = ctx;
458 
459  helper_trace("%-16s: bar %d offset x%x\n", __func__, bar, offset);
460 
461  memset(&cmd, 0, sizeof(cmd));
463  cmd.bar = bar;
464  cmd.offset = offset;
465  cmd.data = data;
466 
467  ioctl(ecd->fd, OCS_IOCTL_CMD_ECD_HELPER, &cmd);
468 }
469 
470 void os_bar_write32(void *ctx, uint32_t bar, uint32_t offset, uint32_t data)
471 {
472  ecdtest_context_t *ecd = ctx;
474 
475  helper_trace("%-16s: bar %d offset x%x\n", __func__, bar, offset);
476 
477  memset(&cmd, 0, sizeof(cmd));
479  cmd.bar = bar;
480  cmd.offset = offset;
481  cmd.data = data;
482 
483  ioctl(ecd->fd, OCS_IOCTL_CMD_ECD_HELPER, &cmd);
484 }
485 
486 void *os_malloc(void *ctx, uint32_t size)
487 {
488  return malloc(size);
489 }
490 void os_free(void *ctx, void *ptr)
491 {
492  return free(ptr);
493 }
494 
#define DEVNAME_TEMPLATE
Definition: ecdtest.c:58
ocs_ecd_helper_cmd_t cmd
Definition: ecdtest.c:101
void os_bar_write8(void *ctx, uint32_t bar, uint32_t offset, uint32_t data)
Definition: elxu_dump.c:1271
void os_assert(char *message, uint32_t Line, char *File)
Definition: elxu_dump.c:978
void os_cfg_read16(void *ctx, uint32_t offset, uint32_t *pdata)
Definition: elxu_dump.c:1019
void os_bar_read16(void *ctx, uint32_t bar, uint32_t offset, uint32_t *pdata)
Definition: elxu_dump.c:1203
static int enable_helper_trace
Definition: ecdtest.c:116
#define DEFAULT_OFNAME
Definition: ecdtest.c:57
void os_bar_read8(void *ctx, uint32_t bar, uint32_t offset, uint32_t *pdata)
Definition: elxu_dump.c:1169
#define OCS_IOCTL_CMD_ECD_HELPER
Definition: ecdtest.c:110
void os_cfg_write16(void *ctx, uint32_t offset, uint32_t data)
Definition: elxu_dump.c:1112
#define OCS_IOCTL_CMD_DRIVER_INFO
Definition: ecdtest.c:109
void os_bar_read32(void *ctx, uint32_t bar, uint32_t offset, uint32_t *pdata)
Definition: elxu_dump.c:1237
uint32_t ioctl_high_version
Definition: ecd_api.h:58
void os_stall(void *ctx, uint32_t usecTime)
Definition: elxu_dump.c:984
void os_cfg_read32(void *ctx, uint32_t offset, uint32_t *pdata)
Definition: elxu_dump.c:1050
ecd_fwState_t
Definition: ecd_api.h:36
uint32_t ioctl_low_version
Definition: ecd_api.h:57
void os_bar_write16(void *ctx, uint32_t bar, uint32_t offset, uint32_t data)
Definition: elxu_dump.c:1302
void os_cfg_write32(void *ctx, uint32_t offset, uint32_t data)
Definition: elxu_dump.c:1140
uint32_t sli_intf
Definition: ecd_api.h:59
ocs_ecd_helper_cmd_t
Definition: ecdtest.c:85
#define helper_trace(fmt,...)
Definition: ecdtest.c:118
char system_name[128]
Definition: ecd_api.h:56
void os_free(void *ctx, void *ptr)
Definition: elxu_dump.c:1369
int main(int argc, char *argv[])
main elxsdkutil CLI functionality
Definition: elxu_main.c:80
user provided context passed to the helper functions
Definition: ecdtest.c:63
uint32_t os_minor
Definition: ecd_api.h:54
void os_bar_write32(void *ctx, uint32_t bar, uint32_t offset, uint32_t data)
Definition: elxu_dump.c:1333
uint32_t instance
Definition: ecd_api.h:52
#define ARRAY_SIZE(x)
Definition: ecdtest.c:113
DRIVER_INFO ioctl structure.
Definition: ecdtest.c:73
void usage()
Show program usage.
int ecd_GetCoreDumpData(void *dumpCtx, ecd_fwState_t fwState, ecd_get_params_t *params, void *dumpBuffer, int dumpBufferSize, int argc, char *argv[])
Fetch coreDump data.
void ecd_log(char *fmt,...)
Definition: elxu_dump.c:969
OCS_IOCTL_CMD_ECD_HELPER ioctl structure.
Definition: ecdtest.c:100
void * os_malloc(void *ctx, uint32_t size)
Definition: elxu_dump.c:1365
char os_name[128]
Definition: ecd_api.h:55
void os_cfg_read8(void *ctx, uint32_t offset, uint32_t *pdata)
Definition: elxu_dump.c:989
uint32_t os_major
Definition: ecd_api.h:53
void os_cfg_write8(void *ctx, uint32_t offset, uint32_t data)
Definition: elxu_dump.c:1083