Emulex Logo
OneCoreā„¢ Storage SDK Release 11.2
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
elxu_common.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 #include <stdio.h>
34 #include <stdint.h>
35 #include <stdlib.h>
36 #include <stdarg.h>
37 #include <sys/types.h>
38 #include <sys/stat.h>
39 #include <assert.h>
40 #include <string.h>
41 #include <sys/types.h>
42 #include <sys/ioctl.h>
43 #include <fcntl.h>
44 #include <dirent.h>
45 #include <unistd.h>
46 #include <ctype.h>
47 
48 #include <ocs_ioctl.h>
49 
50 #include "elxu_common.h"
51 #include "elxu_mgmt.h"
52 
53 static void hba_list_info_ocs(elxu_device_t *device_p);
54 static void hba_list_info_pt(elxu_device_t *device_p);
55 
56 /**
57  * @brief Allocates and zeroes memory to be used.
58  *
59  * @param len The amount of memory to be zeroed and allocated.
60  * @return Returns a pointer to the allocated memory or NULL on failure.
61  *
62  */
63 void *zmalloc (uint32_t len)
64 {
65  void *ret = malloc (len);
66  if (ret != NULL)
67  memset (ret, 0, len);
68  return ret;
69 }
70 
71 /**
72  * @brief Frees memory that has been allocated.
73  *
74  * @par Description
75  * Free memory that was allocated with malloc or zmalloc.
76  * If the pointer is NULL no action is taken.
77  *
78  * @param p The pointer to the memory to be freed.
79  */
80 void zfree (void *p)
81 {
82  if (p != NULL) {
83  free (p);
84  }
85 }
86 
87 /**
88  * @brief Print a buffer in hexadecimal and ASCII
89  *
90  * @par Description
91  * This function prints out a buffer of data in both
92  * hexadecimal and ASCII.
93  *
94  * @param label Label to be printed above the output.
95  * @param buffer Buffer of binary data to be printed.
96  * @param bufferLength Length of buffer.
97  *
98  * @return Returns nothing.
99  */
100 void dump8 (const char *label, void *buffer, uint32_t bufferLength)
101 {
102  uint32_t i;
103  uint8_t *pbuf = (uint8_t*) buffer;
104  const uint32_t columns = 16;
105  uint32_t nremaining;
106  uint32_t n;
107 
108  if (label != 0) {
109  printf ("%s\n", label);
110  }
111 
112  nremaining = bufferLength;
113  while (nremaining > 0) {
114  n = min(columns, nremaining);
115 
116  printf (" ");
117  for (i = 0; i < n; i ++) {
118  printf ("%02X ", pbuf[i]);
119  }
120 
121  for (; i < columns; i ++) {
122  printf (" ");
123  }
124 
125  for (i = 0; i < n; i ++) {
126  printf ("%c", isprint (pbuf[i]) ? pbuf[i] : '.');
127  }
128 
129  for (; i < columns; i ++) {
130  printf (" ");
131  }
132  printf ("\n");
133  pbuf += n;
134  nremaining -= n;
135  }
136 }
137 
138 /**
139  * @brief Display the list of available devices.
140  *
141  * @par Description
142  * This function displays the list of available devices. It iterates
143  * over devices, starting with index 0. For each index it attempts
144  * to open the device. If the device is opened successfully then
145  * the information about that device is displayed. The loop terminates
146  * when any open fails.
147  *
148  * @param hostname hostname in the case of the user space driver.
149  *
150  * @return Returns nothing.
151  */
152 void elxu_display_device_list(char *hostname)
153 {
154  elxu_device_t *device_p;
155  elxu_device_name_t devname;
156  int index;
157 
158  index = 0;
159 
160  device_p = elxu_device_by_index(index);
161 
162  while (device_p) {
163  devname.devidx = device_p->deviceIndex;
164  devname.hostname = hostname;
165  if (elxu_open_device(&devname) != NULL) {
166  printf("[%d] ", devname.devidx);
167  elxu_hba_list_info(device_p);
168  elxu_close_device(device_p);
169  }
170 
171  device_p = elxu_device_by_index(++index);
172  }
173 }
174 
175 /**
176  * @brief Displays HBA List information.
177  *
178  * @par Description
179  * Given an open device pointer, this function retrieves and displays
180  * information about the device. The actual handler is different
181  * depending on the driver.
182  *
183  * @param device_p A pointer to an elxu_device_t. The device should
184  * already have been opened with elxu_open_device.
185  *
186  * @return Returns nothing.
187  */
189 {
190  if (device_p->driver == DEVICE_DRIVER_OCS) {
191  return hba_list_info_ocs(device_p);
192  } else if (device_p->driver == DEVICE_DRIVER_PT) {
193  return hba_list_info_pt(device_p);
194  } else {
195  return;
196  }
197 }
198 
199 static void hba_list_info_ocs(elxu_device_t *device_p)
200 {
201  char* modeldesc;
202  char* fwrev;
203  char* ipl;
204  char* serialnum;
205  char* numamap;
206  char* physnuma;
207  char* fmtwwn;
208  int i;
209  char buf[80];
210  int num_sports;
211  uint32_t fabemu_enable, phy_port;
212 
213  printf("%s/%s\n", elxu_get_vendor_name(device_p), elxu_get_device_name(device_p));
214 
215  modeldesc = elxu_get_modeldesc(device_p);
216  printf(" modeldesc: %s\n", modeldesc);
217 
218  printf(" subsystem_vendor: %s\n", elxu_get_subsystem_vendor(device_p));
219  printf(" subsystem_device: %s\n", elxu_get_subsystem_device(device_p));
220  printf(" PCI bus address: %s\n", elxu_device_get_value(device_p, "/ocs/businfo"));
221 
222  if(is_lancer(device_p)) {
223  printf(" ASIC ID: %s\n", elxu_device_get_value(device_p, "/ocs/asic_id_reg"));
224  }
225  printf(" Chip Type: %s\n", elxu_device_get_value(device_p, "/ocs/chip_type"));
226 
227  phy_port = elxu_get_phy_port_num(device_p);
228  printf(" Physical Port number: %d\n", phy_port);
229 
230  fwrev = elxu_get_fwrev(device_p);
231  printf(" fwrev: %s\n", fwrev);
232 
233  ipl = elxu_get_ipl(device_p);
234  printf(" IPL: %s\n ", ipl);
235 
236  serialnum = elxu_get_serialnumber(device_p);
237  printf(" s/n: %s\n", serialnum);
238 
239  physnuma = get_physical_numa_node( elxu_device_get_value(device_p, "/ocs/businfo"));
240  printf(" Physical NUMA Node: %s\n", physnuma);
241 
242  numamap = get_numa_node_map(device_p->deviceIndex);
243  printf(" NUMA Map: %s", numamap);
244 
245  fabemu_enable = strtol( elxu_device_get_value(device_p, "/ocs/driver/ctrlmask"), NULL, 0);
246  printf(" Fabric Emul:%s Enabled\n", (fabemu_enable & 0x100) ? "" : " Not");
247 
248  if (is_iscsi(device_p)) {
249  printf(" mac addr: %s\n", hex_dump(device_p->mac_addr, 6));
250  } else {
251  printf(" wwnn: %s\n", hex_dump(device_p->wwnn, 8));
252  printf(" wwpn: %s\n", hex_dump(device_p->wwpn, 8));
253  }
254 
255  num_sports = strtol( elxu_device_get_value(device_p, "/ocs/domain[0]/num_sports"), NULL, 0);
256  if (num_sports > 1) {
257  printf(" Additional vports:\n");
258  for (i = 1; i <= num_sports; i++) {
259  char *nn;
260  uint64_t wwn;
261 
262  sprintf(buf, "/ocs/domain[0]/sport[%d]/wwnn", i);
263  nn = elxu_device_get_value(device_p, buf);
264  if (strlen(nn) > 0) {
265  wwn = strtoull(nn, NULL, 0);
266  fmtwwn = format_wwn(wwn);
267  printf(" wwnn: %s\n", fmtwwn);
268  free(fmtwwn);
269  }
270  sprintf(buf, "/ocs/domain[0]/sport[%d]/wwpn", i);
271  nn = elxu_device_get_value(device_p, buf);
272  if (strlen(nn) > 0) {
273  wwn = strtoull(nn, NULL, 0);
274  fmtwwn = format_wwn(wwn);
275  printf(" wwpn: %s\n", fmtwwn);
276  free(fmtwwn);
277  }
278  }
279  }
280 
281  free(serialnum);
282  free(modeldesc);
283  free(numamap);
284  free(physnuma);
285 }
286 
287 static void hba_list_info_pt(elxu_device_t *device_p)
288 {
289  static char* family_names[] = {
290  "BE2", "Unknown", "Unknown", "BE3-R",
291  "Skyhawk-R", "Corsair", "Talon", "Unknown",
292  "Unknown", "Unknown", "Unknown", "Lancer",
293  "Lancer G6", "Unknown", "Unknown", "See ASIC_ID",
294  };
295  int sli_family;
296 
297  printf("%s/%s (via elx_pt driver)\n", elxu_get_vendor_name(device_p), elxu_get_device_name(device_p));
298  printf(" PCI bus address: %s\n", device_p->bus_addr);
299  printf(" ASIC ID: 0x%04x\n", device_p->asic_id);
300  printf(" SLI_INTF: 0x%08x\n", device_p->sli_intf);
301  sli_family = ((device_p->sli_intf & 0xf00) >> 8);
302  printf(" SLI_FAMILY: 0x%02x (%s)\n", sli_family, family_names[sli_family]);
303  printf(" fwrev: %s\n", device_p->fwrev);
304  printf(" s/n: %s\n", device_p->serialnum);
305  if (is_iscsi(device_p) || is_nic(device_p)) {
306  printf(" MAC address: %s\n", hex_dump(device_p->mac_addr, 6));
307  }
308  if (is_fc(device_p)) {
309  printf(" WWNN: %s\n", hex_dump(device_p->wwnn, 8));
310  printf(" WWPN: %s\n", hex_dump(device_p->wwpn, 8));
311  }
312 
313 }
314 
315 /**
316  * @brief Parse a WWN from a string into a 64-bit value.
317  *
318  * @par Description
319  * Given a pointer to a string, parse the string into a 64-bit
320  * WWN value. The format of the string must be xx:xx:xx:xx:xx:xx:xx:xx
321  *
322  * @param wwn_in Pointer to the string to be parsed.
323  * @param wwn_out Pointer to uint64_t in which to put the parsed result.
324  *
325  * @return Returns 0 if successful; non-zero if the WWN is malformed and couldn't be parsed
326  */
327 int parse_wwn(char *wwn_in, uint64_t *wwn_out)
328 {
329  uint8_t byte0;
330  uint8_t byte1;
331  uint8_t byte2;
332  uint8_t byte3;
333  uint8_t byte4;
334  uint8_t byte5;
335  uint8_t byte6;
336  uint8_t byte7;
337  int rc;
338 
339  rc = sscanf(wwn_in, "%2hhx:%2hhx:%2hhx:%2hhx:%2hhx:%2hhx:%2hhx:%2hhx",
340  &byte0, &byte1, &byte2, &byte3,
341  &byte4, &byte5, &byte6, &byte7);
342 
343  if (rc == 8) {
344  *wwn_out = ((uint64_t)byte0 << 56) |
345  ((uint64_t)byte1 << 48) |
346  ((uint64_t)byte2 << 40) |
347  ((uint64_t)byte3 << 32) |
348  ((uint64_t)byte4 << 24) |
349  ((uint64_t)byte5 << 16) |
350  ((uint64_t)byte6 << 8) |
351  ((uint64_t)byte7);
352  return 0;
353  } else {
354  return -1;
355  }
356 }
357 
358 /**
359  * @brief Format a 64-bit WWN for printing.
360  *
361  * @par Description
362  * Given a 64-bit WWN value, return a string in the format xx:xx:xx:xx:xx:xx:xx:xx
363  *
364  * @param wwn_in uint64_t containing the WWN
365  *
366  * @return Returns a pointer to the formatted string
367  */
368 char * format_wwn(uint64_t wwn_in)
369 {
370  char result[24];
371 
372  sprintf(result, "%02llx:%02llx:%02llx:%02llx:%02llx:%02llx:%02llx:%02llx",
373  ((wwn_in & 0xff00000000000000ll) >> 56),
374  ((wwn_in & 0x00ff000000000000ll) >> 48),
375  ((wwn_in & 0x0000ff0000000000ll) >> 40),
376  ((wwn_in & 0x000000ff00000000ll) >> 32),
377  ((wwn_in & 0x00000000ff000000ll) >> 24),
378  ((wwn_in & 0x0000000000ff0000ll) >> 16),
379  ((wwn_in & 0x000000000000ff00ll) >> 8),
380  ((wwn_in & 0x00000000000000ffll)));
381 
382  return strdup(result);
383 }
384 
385 /**
386  * @brief Display a buffer in hexadecimal.
387  *
388  * @par Description
389  * The buffer pointed to by value is displayed in hexadecimal.
390  * The bytes are displayed as two digit hexadecimal values separated
391  * by spaces. The result is termintated with a NULL.
392  *
393  * @param value A pointer to an array of bytes to be printed.
394  * @param size The size of the array. The maximum size that can be
395  * handled is 25 bytes. Values larger than 25 will result
396  * in only the first 25 bytes being printed.
397  *
398  * @return Returns a pointer to a static character string with the
399  * hexadecimal values.
400  */
401 char *hex_dump(uint8_t *value, int size)
402 {
403  static char result[80];
404  char buf[4];
405  int i;
406 
407  if (size > 25) {
408  size = 25;
409  }
410 
411  result[0] = '\0';
412  for (i = 0; i < size; i++) {
413  sprintf(buf, "%02x ", value[i]);
414  strcat(result, buf);
415  }
416 
417  return result;
418 }
419 
420 /**
421  * @brief Trim trailing non-printable characters from a string.
422  *
423  * @par Description
424  * Given a pointer to a string, this function returns a copy of
425  * the string up to the first non-printable character found.
426  * The largest string that can be returned is 2047 characters
427  * plus the terminating NULL.
428  *
429  *
430  * @param string A pointer to the string to be trimmed.
431  *
432  * @return Returns a pointer to a static copy of the input string
433  * up to the first non-printable character, or the first
434  * 2047 characters if no non-printable character is found
435  * in that range.
436  */
437 char *trimmed_string(uint8_t *string)
438 {
439  static char result[2048];
440  uint8_t *s;
441  char *d;
442 
443  s = string;
444  d = result;
445 
446  while (isprint(*s)) {
447  *d = *s;
448  ++s;
449  ++d;
450  if ((d-result) >= 2048) {
451  break;
452  }
453  }
454 
455  *d = '\0';
456 
457  return result;
458 }
459 
460 /**
461  * @brief Return the name of a UFI entry type.
462  *
463  * @par Description
464  * Given an integer that represents an entry type in a UFI directory,
465  * this function returns a pointer to a constant string containing
466  * the name of that entry type.
467  *
468  * @param entry_type The type of the entry to lookup.
469  *
470  * @return Returns a pointer to a constant string which is the name
471  * of the given entry type. If the entry type is not recognized
472  * the string "Unknown" will be returned.
473  */
474 char *decode_entry_type(uint32_t entry_type)
475 {
476  switch(entry_type) {
477  case 0x20:
478  return "PXE BIOS";
479  case 0x21:
480  return "FCoE BIOS";
481  case 0x22:
482  return "iSCSI BIOS";
483  case 0xA0:
484  return "iSCSI/NIC ARM Firmware";
485  case 0xA2:
486  return "FCoE/NIC ARM Firmware";
487  case 0xA1:
488  return "Compressed iSCSI/NIC Firmware";
489  case 0xA3:
490  return "Compressed FCoE/NIC Firmware";
491  case 0xB0:
492  return "Backup iSCSI/NIC Firmware";
493  case 0xB2:
494  return "Backup FCoE/NIC Firmware";
495  case 0xB1:
496  return "Backup Compressed iSCSI/NIC Firmware";
497  case 0xB3:
498  return "Backup Compressed FCoE/NIC Firmware";
499  case 0xE0:
500  return "Boot Code";
501  case 0x10:
502  return "Binary NCSI Firmware";
503  case 0x30:
504  return "ISM and Jump Vectors";
505  case 0x31:
506  return "ISM code";
507  case 0x32:
508  return "Jump Vectors";
509  case 0xC0:
510  return "PHY Firmware";
511  case 0xD0:
512  return "Redboot Directory";
513  case 0xD1:
514  return "Redboot Configuration";
515  case 0xD2:
516  return "UFI Directory";
517  default:
518  return "Unknown";
519  }
520 }
521 
522 /**
523  * @brief Return a string of cpu to numa node mapping .
524  *
525  * @par Description
526  * Given the port index for the ocs port,
527  * this function returns a pointer to a string containing
528  * the cpu to numa node mapping for that port
529  *
530  * @param device_port The type of the port to list the cpu to numa node map.
531  *
532  * @return Returns a pointer to a string which lists the cpu to numa node map
533  * for the given port. If the port is not recognized
534  * no value is returned.
535  *
536  */
537 char *get_numa_node_map(uint32_t device_port)
538 {
539  #define NUMNODE 256
540  #define NODERESULT 40
541  #define NUMCPU 36
542  #define CPULIST 16
543  #define NNODELIST 16
544  #define NODELEN 12
545 
546  static const char *cmd = "cat /sys/devices/system/node";
547  static const char *port_cmd = "for i in $(pgrep ocs:); do ps -mo psr -p $i --no-heading | grep -v '-'; done ";
548  static const char *nnode_cmd = "ls /sys/devices/system/node/ 2> /dev/null | grep node";
549  char buf[BUFSIZ];
550  char nnode_list[NUMNODE];
551  char result[NODERESULT];
552  FILE *ptr;
553  int i;
554  int k = 0;
555  int ret_val = 0;
556  int cpu_cnt = 0;
557  int cpu_list[NUMCPU];
558  int cpu_val = 0;
559  int nnode_cnt = 0;
560  int port_cpu_list[CPULIST];
561  char numa_node_list[NNODELIST][NODELEN + 1];
562  int port_cpu_cnt = 0;
563  int loop_node = 0;
564 
565  if ((ptr = popen(nnode_cmd, "r")) != NULL) {
566  while (fgets(buf, BUFSIZ, ptr) != NULL) {
567  strncpy(numa_node_list[nnode_cnt], buf, NODELEN);
568 
569  nnode_cnt++;
570  }
571  (void) pclose(ptr);
572  }
573 
574  if (nnode_cnt == 0 ) {
575  snprintf(result, 6, "n/a");
576  return strdup(result);
577  }
578 
579  for (loop_node = 0; loop_node < nnode_cnt; loop_node++) {
580  ret_val = snprintf(nnode_list, sizeof nnode_list, "%s/%s%d/%s",cmd, "node", loop_node, "cpulist");
581  if (ret_val < 0) {
582  return NULL;
583  }
584 
585  if ((ptr = popen(nnode_list, "r")) != NULL) {
586  while (fgets(buf, BUFSIZ, ptr) != NULL){
587  }
588  (void) pclose(ptr);
589  }
590 
591  cpu_cnt = 0;
592  cpu_val = 0;
593 
594  for (i = 0; buf[i] != '\0'; i++) {
595  if (buf[i] == '-') {
596  cpu_cnt++;
597  while (cpu_val < atoi(&buf[i+1])) {
598  cpu_list[cpu_cnt] = ++cpu_val;
599  cpu_cnt++;
600  }
601 
602  i++;
603  } else if (buf[i] == ',') {
604  continue;
605  } else {
606  if (isalnum(buf[i])) {
607  cpu_list[cpu_cnt] = atoi(&buf[i]);
608  cpu_val = cpu_list[cpu_cnt];
609  if (cpu_val > 10) {
610  i++;
611  }
612  }
613  }
614  }
615 
616  if ((ptr = popen(port_cmd, "r")) != NULL) {
617  port_cpu_cnt = 0;
618  while (fgets(buf, BUFSIZ, ptr) != NULL) {
619  port_cpu_list[port_cpu_cnt] = atoi(buf);
620  port_cpu_cnt++;
621  }
622  (void) pclose(ptr);
623  }
624 
625  i = 0;
626 
627  port_cpu_cnt = device_port;
628 
629  for (k = 0; k < cpu_cnt; k++) {
630  if (cpu_list[k] == port_cpu_list[port_cpu_cnt]) {
631  snprintf(result, 20, "cpu%d:%s", port_cpu_list[port_cpu_cnt],
632  numa_node_list[loop_node]);
633  }
634  }
635 
636  i++;
637 
638  } /* end for */
639 
640  return strdup(result);
641 }
642 
643 /**
644  * @brief Return the physical Numa Node location for an OCS port .
645  *
646  * @par Description
647  * Given the port index for the ocs port,
648  * this function returns a pointer to a string containing
649  * the value of the physical numa node the OCS port is associated with
650  *
651  * @param bus_addr The bus address for the current OCS port
652  *
653  * @return Returns a pointer to a string listing the Physical Numa Node port
654  * for the given port. If the bus address is not found
655  * a value of 'n/a' is listed.
656  *
657  */
658 char *get_physical_numa_node(char *bus_addr)
659 {
660  #define NPATHLEN 65
661  #define NUMDEVID 10
662  #define DEVBUFF 8
663  FILE *fp;
664  int device_inst = 0;
665  int path_id = 0;
666  static char device_buff[DEVBUFF];
667  char node_path[NPATHLEN];
668  char device_id[NUMDEVID];
669  int res;
670 
671  for (device_inst = 0; bus_addr[device_inst] != '\0'; device_inst++) {
672  if (path_id != 1 || (bus_addr[device_inst] != ':')) {
673  device_id[device_inst] = bus_addr[device_inst];
674  if(bus_addr[device_inst] == ':') {
675  path_id++;
676  }
677  }
678  }
679 
680  snprintf(node_path, sizeof(node_path)-1, "/sys/class/pci_bus/%s/device/%s/numa_node", device_id, bus_addr);
681 
682  fp = fopen(node_path, "r");
683  if(fp != NULL) {
684  res = fscanf(fp, "%7s", device_buff);
685  if (res != 1) {
686  snprintf(device_buff, DEVBUFF, "n/a");
687  }
688  fclose(fp);
689  } else {
690  snprintf(device_buff, DEVBUFF, "n/a");
691  }
692 
693  return strdup(device_buff);
694 }
695 
696 /**
697 * @page dev_enum Device Enumeration (Using "list")
698 *
699 * Device enumeration uses the List Adapters CLI command (@ref cmd_list "list") to discover the
700 * Emulex adapters installed in the host system. It is executed by the
701 * elxu_display_device_list() function in the elxu_common.c module.
702 *
703 * The function tries to open each device in order, starting with device 0. If a
704 * device is successfully opened, its information is displayed, and then
705 * the device is closed. The process continues until an attempt to open a device fails.
706 */
#define NODELEN
const char * elxu_get_vendor_name(elxu_device_t *device)
Return the vendor name for a device.
Definition: elxu_device.c:576
char * elxu_get_modeldesc(elxu_device_t *device)
Return the model description for a device.
Definition: elxu_device.c:363
uint8_t wwpn[8]
Definition: elxu_device.h:99
char * trimmed_string(uint8_t *string)
Trim trailing non-printable characters from a string.
Definition: elxu_common.c:437
#define NPATHLEN
char fwrev[32]
Definition: elxu_device.h:92
#define NNODELIST
int is_fc(elxu_device_t *device_p)
Return true IFF the HBA is a FC HBA.
Definition: elxu_device.c:1185
int parse_wwn(char *wwn_in, uint64_t *wwn_out)
Parse a WWN from a string into a 64-bit value.
Definition: elxu_common.c:327
void elxu_display_device_list(char *hostname)
Display the list of available devices.
Definition: elxu_common.c:152
char * get_physical_numa_node(char *bus_addr)
Return the physical Numa Node location for an OCS port .
Definition: elxu_common.c:658
uint32_t sli_intf
Definition: elxu_device.h:86
char * elxu_get_ipl(elxu_device_t *device)
Return the IPL version for a device.
Definition: elxu_device.c:404
device name specifier This structure is used to describe the type and name of the device ioctl connec...
Definition: elxu_device.h:113
void * zmalloc(uint32_t len)
Allocates and zeroes memory to be used.
Definition: elxu_common.c:63
char * format_wwn(uint64_t wwn_in)
Format a 64-bit WWN for printing.
Definition: elxu_common.c:368
void zfree(void *p)
Frees memory that has been allocated.
Definition: elxu_common.c:80
int is_lancer(elxu_device_t *device_p)
Return true IFF the HBA is a Lancer.
Definition: elxu_device.c:1236
const char * elxu_get_subsystem_vendor(elxu_device_t *device)
Return the PCI subsystem vendor value for a device.
Definition: elxu_device.c:664
#define min(x, y)
Definition: elxu_mbox.h:39
uint32_t asic_id
Definition: elxu_device.h:87
#define NODERESULT
#define CPULIST
uint32_t deviceIndex
Definition: elxu_device.h:85
char * elxu_get_serialnumber(elxu_device_t *device)
Return the serial number for a device.
Definition: elxu_device.c:425
const char * elxu_get_device_name(elxu_device_t *device)
Return the device name for a device.
Definition: elxu_device.c:602
char * serialnum
Definition: elxu_device.h:95
char * decode_entry_type(uint32_t entry_type)
Return the name of a UFI entry type.
Definition: elxu_common.c:474
uint32_t elxu_get_phy_port_num(elxu_device_t *device)
Return the physical port number for a device.
Definition: elxu_device.c:446
elxu_device_t * elxu_device_by_index(int index)
Return a pointer to a device given an index.
Definition: elxu_device.c:730
int is_nic(elxu_device_t *device_p)
Return true IFF the HBA is a NIC HBA.
Definition: elxu_device.c:1168
char * elxu_device_get_value(elxu_device_t *device, char *key)
Return a property value for a device.
Definition: elxu_device.c:765
#define NUMCPU
static void hba_list_info_pt(elxu_device_t *device_p)
Definition: elxu_common.c:287
#define DEVBUFF
elxu_device_t * elxu_open_device(elxu_device_name_t *devname)
Open a device file.
Definition: elxu_device.c:212
int is_iscsi(elxu_device_t *device_p)
Return true IFF the HBA is an iSCSI HBA.
Definition: elxu_device.c:1151
void elxu_close_device(elxu_device_t *device)
Close a device.
Definition: elxu_device.c:340
static void hba_list_info_ocs(elxu_device_t *device_p)
Definition: elxu_common.c:199
char * elxu_get_fwrev(elxu_device_t *device)
Return the firmware revision for a device.
Definition: elxu_device.c:384
#define NUMNODE
#define NUMDEVID
void dump8(const char *label, void *buffer, uint32_t bufferLength)
Print a buffer in hexadecimal and ASCII.
Definition: elxu_common.c:100
elxu_device_driver_e driver
Definition: elxu_device.h:90
char * hex_dump(uint8_t *value, int size)
Display a buffer in hexadecimal.
Definition: elxu_common.c:401
const char * elxu_get_subsystem_device(elxu_device_t *device)
Return the PCI subsystem device value for a device.
Definition: elxu_device.c:642
char bus_addr[256]
Definition: elxu_device.h:80
uint8_t mac_addr[6]
Definition: elxu_device.h:100
uint8_t wwnn[8]
Definition: elxu_device.h:98
char * get_numa_node_map(uint32_t device_port)
Return a string of cpu to numa node mapping .
Definition: elxu_common.c:537
void elxu_hba_list_info(elxu_device_t *device_p)
Displays HBA List information.
Definition: elxu_common.c:188