Emulex Logo
OneCoreā„¢ Storage SDK Release 11.2
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
elxu_device.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 elxsdkutil device specific API
35  *
36  */
37 
38 #include <stdio.h>
39 #include <unistd.h>
40 #include <stdlib.h>
41 #include <string.h>
42 #include <stdint.h>
43 #include <stdarg.h>
44 #include <ctype.h>
45 #include <sys/ioctl.h>
46 
47 #include <ocs_ioctl.h>
48 #include <ocsu_io.h>
49 
50 #include "elxu_common.h"
51 #include "elxu_device.h"
52 #include "elxu_mgmt.h"
53 #include "elx_pt_ioctl.h"
54 
55 #define MIN(x, y) ((x) < (y) ? (x) : (y))
56 
57 static void dev_parse_wwn(char *, uint8_t *);
58 static void dev_parse_mac(char *, uint8_t *);
59 
61 
62 /**
63  * A table of information on device types
64  */
65 
66 typedef struct device_type_info_s {
68  char *name;
70 
72  {DEVICE_TYPE_LANCER, "Lancer"},
73  {DEVICE_TYPE_SKYHAWK, "Skyhawk"},
74  {DEVICE_TYPE_PRISM, "Prism"},
75  {DEVICE_TYPE_UNKNOWN, "Unknown"}
76 };
77 
78 /**
79  * A table of information on protocols
80  */
81 
82 typedef struct device_protocol_info_s {
84  char *name;
86 
88  {DEVICE_PROTOCOL_FC, "FC"},
89  {DEVICE_PROTOCOL_FCOE, "FCoE"},
90  {DEVICE_PROTOCOL_ISCSI, "iSCSI"},
91  {DEVICE_PROTOCOL_NIC, "NIC"},
92  {DEVICE_PROTOCOL_UNKNOWN, "Unknown"}
93 };
94 
95 /**
96  * A table mapping PCI Vendor/Device into device type
97  */
98 
99 typedef struct pci_device_map_s {
100  uint16_t vendor;
101  uint16_t device;
105 
117 };
118 
119 /**
120  * @ingroup dev_mgmt
121  * @brief Create a list of devices
122  *
123  * @par Description
124  * This function creates a global list of devices available to be managed.
125  *
126  * @param argc argc from command line
127  * @param argv argv from command line
128  *
129  * @return Returns nothing.
130  */
131 void elxu_build_device_list(int argc, char *argv[])
132 {
133  char *hostname;
134  char *path;
135  int i;
136 
137  device_list = NULL;
138  hostname = NULL;
139  path = NULL;
140 
141  for (i=0; i<argc; i++) {
142  if ((i >= (argc-1)) || (path && hostname))
143  break;
144  if (strcmp(argv[i], "--host") == 0){
145  hostname = argv[i+1];
146  }
147  if (strcmp(argv[i], "--path") == 0){
148  path = argv[i+1];
149  }
150 
151  }
152 
153  if (hostname != NULL) {
154  /* --host was specified, use user space driver */
155  device_list = os_build_device_list_uspace(hostname);
156  } else {
157  /* No --host option, direct kernel driver access */
158  device_list = os_build_device_list(path);
159  }
160 
161  return;
162 }
163 
165 {
166  elxu_device_t *current;
167  elxu_device_t *next;
168  int rc;
169 
170  current = device_list;
171  while (current) {
172  next = current->next;
173 
174  /* desc is non-null for uspace socket interface, which will be
175  closed by ocsu_close */
176  if (current->desc == NULL) {
177  rc = os_remove_device(current);
178  if (rc && (current->fd != -1)) {
179  printf("Failed to remove %s file\n", current->device_file_name);
180  }
181  }
182  free (current->modeldesc);
183  free (current->serialnum);
184 
185  free(current);
186 
187  current = next;
188  }
189 }
190 
191 /**
192  * @ingroup dev_mgmt
193  * @brief Open a device file.
194  *
195  * @par Description
196  * This function first calls the OS-specific function to open the
197  * device file. Then, if the open is successful, the function will
198  * retrieve a variety of information about the device and store it
199  * in the elxu_device_t structure.
200  *
201  * NOTE: This function requires that the global device list has
202  * already been built by elxu_build_device_list.
203  *
204  * @param devname A pointer to a device_name structure. This
205  * structure contains a device index and optionally a
206  * hostname if the device is accessed through the
207  * userspace driver.
208  *
209  * @return Returns a pointer to an elxu_device_t structure on success;
210  * NULL on failure.
211  */
213 {
214  elxu_device_t *device;
215 
216  device = os_open_device(devname);
217 
218  if (device != NULL) {
219  fill_device_details(device);
220  }
221 
222  return device;
223 }
224 
226 {
227  int i;
228 
229  device->type = DEVICE_TYPE_UNKNOWN;
230  for (i=0; i<ARRAY_SIZE(pci_device_map); i++) {
231  if ((device->vendor == pci_device_map[i].vendor) &&
232  (device->device == pci_device_map[i].device)) {
233  device->type = pci_device_map[i].type;
234  device->protocol = pci_device_map[i].protocol;
235  break;
236  }
237  }
238  if (device->driver == DEVICE_DRIVER_OCS) {
239  device->subsystem_vendor = strtoul(elxu_device_get_value(device, "/ocs/pci_subsystem_vendor"), NULL, 0);
240  device->subsystem_device = strtoul(elxu_device_get_value(device, "/ocs/pci_subsystem_device"), NULL, 0);
241  device->sli_intf = strtoul(elxu_device_get_value(device, "/ocs/sli4_intf_reg"), NULL, 0);
242  device->asic_id = strtoul(elxu_device_get_value(device, "/ocs/asic_id_reg"), NULL, 0);
243  strncpy(device->fwrev, elxu_device_get_value(device, "/ocs/fw_rev"), sizeof(device->fwrev) - 1);
244  strncpy(device->ipl, elxu_device_get_value(device, "/ocs/ipl"), sizeof(device->ipl) - 1);
245  device->modeldesc = strdup(elxu_device_get_value(device, "/ocs/desc"));
246  device->serialnum = strdup(elxu_device_get_value(device, "/ocs/sn"));
247  device->phy_port_num = strtoul(elxu_device_get_value(device, "/ocs/phy_port_num"), NULL, 0);
248 
249  // Format of WWNs is "0x20000090fa020d9e"
250  if (is_fc(device)) {
251  dev_parse_wwn(elxu_device_get_value(device, "/ocs/wwnn"), device->wwnn);
252  dev_parse_wwn(elxu_device_get_value(device, "/ocs/wwpn"), device->wwpn);
253  }
254 
255  // Format of MAC is "00:00:c9:ce:a9:50"
256  if (is_iscsi(device))
257  dev_parse_mac(elxu_device_get_value(device, "/ocs/mac_address"), device->mac_addr);
258  }
259 }
260 
261 static void dev_parse_wwn(char *input, uint8_t* output)
262 {
263  char buf[] = "0x..";
264  int i;
265  char *c;
266 
267  if (strlen(input) != 18) {
268  return;
269  }
270 
271  c = &(input[2]);
272  for (i=0; i<8; i++) {
273  buf[2] = *c;
274  ++c;
275  buf[3] = *c;
276  ++c;
277  output[i] = strtoul(buf, NULL, 0);
278  }
279 }
280 
281 /*
282  * Input: String in the form 01:02:03:04:05:06
283  * Output: Array of sixe uint8_t containing 1, 2, 3, etc.
284  */
285 static void dev_parse_mac(char *input, uint8_t* output)
286 {
287  char buf[] = "0x..";
288  int i;
289  char *c;
290 
291  if (strlen(input) != 17) {
292  return;
293  }
294 
295  c = &(input[0]);
296  for (i=0; i<6; i++) {
297  buf[2] = *c;
298  ++c;
299  buf[3] = *c;
300  ++c;
301  output[i] = strtoul(buf, NULL, 0);
302  ++c;
303  }
304 }
305 
306 /**
307  * @ingroup dev_mgmt
308  * @brief Send an ioctl to a device.
309  *
310  * @par Description
311  * This function calls the OS-specific function to send an ioctl
312  * to a device.
313  *
314  *
315  * @param device The elxu device structure of the device.
316  * @param req The ioctl request.
317  * @param arg The ioctl argument.
318  *
319  * @return Returns zero on success; a non-zero error code on
320  * failure.
321  */
322 int elxu_ioctl_device(elxu_device_t *device, int req, void *arg)
323 {
324  return os_ioctl_device(device, req, arg);
325 }
326 
327 /**
328  * @ingroup dev_mgmt
329  * @brief Close a device.
330  *
331  * @par Description
332  * This function calls the OS-specific function to close a
333  * device file, then frees any allocated memory associated with
334  * that device.
335  *
336  * @param device The elxu device structure of the device.
337  *
338  * @return Returns nothing.
339  */
341 {
342  if (device) {
343  os_close_device(device);
344  }
345 }
346 
347 /**
348  * @ingroup dev_mgmt
349  * @brief Return the model description for a device.
350  *
351  * @par Description
352  * This function returns the model description for a device.
353  * The description is placed into a newly allocated string. The
354  * caller is responsible for freeing the string when it is no
355  * longer needed.
356  *
357  *
358  * @param device The elxu device structure of the device.
359  *
360  * @return Returns a pointer to the allocated string containing
361  * the desription. Returns NULL on error.
362  */
364 {
365  return strdup(device->modeldesc);
366 }
367 
368 /**
369  * @ingroup dev_mgmt
370  * @brief Return the firmware revision for a device.
371  *
372  * @par Description
373  * This function returns the firmware revision for a device.
374  * The firmware revision is placed into a newly allocated
375  * string. The caller is responsible for freeing the string when
376  * it is no longer needed.
377  *
378  *
379  * @param device The elxu device structure of the device.
380  *
381  * @return Returns a pointer to the allocated string containing
382  * the firmware revision. Returns NULL on error.
383  */
385 {
386  return device->fwrev;
387 }
388 
389 /**
390  * @ingroup dev_mgmt
391  * @brief Return the IPL version for a device.
392  *
393  * @par Description
394  * This function returns the IPL version for a device.
395  * The IPL version is placed into a newly allocated
396  * string.
397  *
398  *
399  * @param device The elxu device structure of the device.
400  *
401  * @return Returns a pointer to the allocated string containing
402  * the IPL version. Returns NULL on error.
403  */
405 {
406  return device->ipl;
407 }
408 
409 /**
410  * @ingroup dev_mgmt
411  * @brief Return the serial number for a device.
412  *
413  * @par Description
414  * This function returns the serial number for a device. The
415  * serial number is placed into a newly allocated string. The
416  * caller is responsible for freeing the string when it is no
417  * longer needed.
418  *
419  *
420  * @param device The elxu device structure of the device.
421  *
422  * @return Returns a pointer to the allocated string containing
423  * the serial number. Returns NULL on error.
424  */
426 {
427  return strdup(device->serialnum);
428 }
429 
430 /**
431  * @ingroup dev_mgmt
432  * @brief Return the physical port number for a device.
433  *
434  * @par Description
435  * This function returns the physical port number for a device. The
436  * physical port number is placed into a newly allocated string. The
437  * caller is responsible for freeing the string when it is no
438  * longer needed.
439  *
440  *
441  * @param device The elxu device structure of the device.
442  *
443  * @return Returns a pointer to the allocated string containing
444  * the serial number. Returns NULL on error.
445  */
447 {
448  return device->phy_port_num;
449 }
450 
451 /**
452  * @ingroup dev_mgmt
453  * @brief Return the sli_intf value for a device.
454  *
455  * @par Description
456  * This function returns the sli_intf value for a device.
457  *
458  * @param device The elxu device structure of the device.
459  *
460  * @return Returns a uint32_t containing the sli_intf value.
461  */
463 {
464  return device->sli_intf;
465 }
466 
467 /**
468  * @ingroup dev_mgmt
469  * @brief Return the ASIC ID value for a device.
470  *
471  * @par Description
472  * This function returns the ASIC ID value for a device.
473  *
474  * @param device The elxu device structure of the device.
475  *
476  * @return Returns a uint32_t containing the ASIC ID value.
477  */
479 {
480  return device->asic_id;
481 }
482 
483 /**
484  * @ingroup dev_mgmt
485  * @brief Lookup a family name.
486  *
487  * @par Description
488  * Given a family number, this function returns a string
489  * containing the family name.
490  *
491  * @param family The family number.
492  *
493  * @return Returns a static string containing the family name.
494  */
495 char *elxu_decode_family(uint32_t family)
496 {
497  static char result[80];
498 
499  switch(family) {
500  case 0x0a:
501  strncpy(result, "Lancer A0", sizeof(result));
502  break;
503  case 0x0b:
504  strncpy(result, "Lancer B0", sizeof(result));
505  break;
506  default:
507  strncpy(result, "Unknown", sizeof(result));
508  break;
509  }
510 
511  return result;
512 }
513 
514 /**
515  * @ingroup dev_mgmt
516  * @brief Lookup an ASIC ID name.
517  *
518  * @par Description
519  * Given a family number, this function returns a string
520  * containing the ASIC ID name.
521  *
522  * @param asic_id The ASIC ID to lookup.
523  *
524  * @return Returns a static string containing the ASIC ID name.
525  */
526 char *elxu_decode_asic_id(uint32_t asic_id)
527 {
528  static char result[80];
529  char temp[10];
530 
531  /* Note:
532  Although there are ASIC_ID definitions for Lancer,
533  the ASIC_ID register only exists on chips with a SLI_Family of 0xF.
534  Currently only Skyhawk and Corsair have family 0x0F. So although
535  there is a case here for decoding the Lancer value we don't expect to
536  encounter it. Lancer will get decoded by elxu_decode_family */
537 
538  switch (asic_id & 0xff00) {
539  case 0x0400:
540  strncpy (result, "Skyhawk-R", sizeof(result));
541  break;
542  case 0x0500:
543  strncpy (result, "Corsair", sizeof(result));
544  break;
545  case 0x0b00:
546  strncpy (result, "Lancer", sizeof(result));
547  break;
548  default:
549  strncpy(result, "Unknown", sizeof(result));
550  return result;
551  }
552 
553  strncat(result, " ", 1);
554 
555  /* Ugly ASCII magic here. Converting 0, 1, 2... to A, B, C... */
556  sprintf(temp, "%c", (((asic_id & 0x00f0) >> 4) + 'A'));
557  strncat(result, temp, 1);
558 
559  sprintf(temp, "%d", (asic_id & 0x000f));
560  strncat(result, temp, 1);
561 
562  return result;
563 }
564 
565 /**
566  * @ingroup dev_mgmt
567  * @brief Return the vendor name for a device.
568  *
569  * @par Description
570  * This function returns the vendor name for a device.
571  *
572  * @param device The elxu device structure of the device.
573  *
574  * @return Returns the vendor name in a static string.
575  */
576 const char *elxu_get_vendor_name (elxu_device_t *device)
577 {
578  switch (device->vendor)
579  {
581  return "Emulex";
582  case PCI_VENDOR_ID_ATTO:
583  return "ATTO";
584  default:
585  return "Unknown";
586  }
587 }
588 
589 /**
590  * @ingroup dev_mgmt
591  * @brief Return the device name for a device.
592  *
593  * @par Description
594  * This function returns the device name for a device.
595  * This includes both the device name and the protocol.
596  * eg: "Lancer FCoE"
597  *
598  * @param device The elxu device structure of the device.
599  *
600  * @return Returns the device name in a static string.
601  */
603 {
604  char *device_type_string = "Unknown";
605  char *protocol_string = "Unknown";
606  static char result[80];
607  int i;
608 
609  for (i=0;i<ARRAY_SIZE(device_type_info);i++) {
610  if (device_type_info[i].type == device->type) {
611  device_type_string = device_type_info[i].name;
612  break;
613  }
614  }
615 
616  for (i=0;i<ARRAY_SIZE(device_protocol_info);i++) {
617  if (device_protocol_info[i].protocol == device->protocol) {
618  protocol_string = device_protocol_info[i].name;
619  break;
620  }
621  }
622 
623  sprintf(result, "%s %s", device_type_string, protocol_string);
624 
625  return result;
626 
627 }
628 
629 /**
630  * @ingroup dev_mgmt
631  * @brief Return the PCI subsystem device value for a device.
632  *
633  * @par Description
634  * This function returns the PCI subsystem device value for a
635  * device. The value returned is a static string containing the
636  * hex representation of the 16 bit subsystem device value.
637  *
638  * @param device The elxu device structure of the device.
639  *
640  * @return Returns the PCI subsystem device in a static string.
641  */
643 {
644  static char result[80];
645 
646  sprintf(result, "0x%04x", device->subsystem_device);
647 
648  return result;
649 }
650 
651 /**
652  * @ingroup dev_mgmt
653  * @brief Return the PCI subsystem vendor value for a device.
654  *
655  * @par Description
656  * This function returns the PCI subsystem vendor value for a
657  * device. The value returned is a static string containing the
658  * hex representation of the 16 bit subsystem vendor value.
659  *
660  * @param device The elxu device structure of the device.
661  *
662  * @return Returns the PCI subsystem vendor in a static string.
663  */
665 {
666  static char result[80];
667 
668  sprintf(result, "0x%04x", device->subsystem_vendor);
669 
670  return result;
671 }
672 
673 /**
674  * @ingroup dev_mgmt
675  * @brief Return a pointer to a device based on command line args.
676  *
677  * @par Description
678  * Given the command line arguments (argc and argv), determine which
679  * device should be operated on. Assumes that elxu_build_device_list
680  * has already been called.
681  *
682  * @param argc Argument count from the command line
683  * @param argv Arguments from the command line
684  *
685  * @return Returns a pointer to a device structure, or NULL if the
686  * device can't be determined.
687  */
688 elxu_device_t *elxu_device_from_args(int argc, char *argv[])
689 {
690  elxu_device_t *device;
691  int i;
692  int index = 0;
693 
694  for (i=0; i<argc; i++) {
695  if (strcmp(argv[i], "-d") == 0) {
696  /* Make sure there's an argument after the -d */
697  if (i != (argc-1)) {
698  index = strtoul(argv[i+1], NULL, 10);
699  }
700  break;
701  }
702  }
703 
704  device = device_list;
705  while (device != NULL) {
706  if (device->deviceIndex == index) {
707  break;
708  }
709  device = device->next;
710  }
711 
712  return device;
713 
714 }
715 
716 /**
717  * @ingroup dev_mgmt
718  * @brief Return a pointer to a device given an index
719  *
720  * @par Description
721  * Given a device index, determine which
722  * device should be operated on. Assumes that elxu_build_device_list
723  * has already been called.
724  *
725  * @param index Device index to find.
726  *
727  * @return Returns a pointer to a device structure, or NULL if the
728  * device can't be determined.
729  */
731 {
732  elxu_device_t *device;
733 
734  device = device_list;
735  while (device != NULL) {
736  if (device->deviceIndex == index) {
737  break;
738  }
739  device = device->next;
740  }
741 
742  return device;
743 }
744 
745 /**
746  * @ingroup dev_mgmt
747  * @brief Return a property value for a device
748  *
749  * @par Description
750  * Given a device and a key, return the value for that key.
751  * For the OCS driver this is just a wrapper around calls
752  * to mgmt_get_value. The driver's mgmt interface will
753  * supply the value.
754  *
755  * For the elx_pt driver we have to simulate the mgmt_get_value
756  * function because the driver doesn't have the mgmt interface.
757  * For a limited set of key this function will determine
758  * the correct value in other ways.
759  *
760  * @param device Device to access.
761  * @param key Name of the property to retrieve.
762  *
763  * @return Returns a pointer to a static char[] with the result.
764  */
765 char *elxu_device_get_value(elxu_device_t *device, char *key)
766 {
767  static char result[1024];
768 
769  if (device->driver == DEVICE_DRIVER_OCS) {
770  return mgmt_get_value(device, key);
771  }
772 
773  result[0] = '\0';
774  if (strcmp(key, "/ocs/businfo") == 0) {
775  strcpy(result, device->bus_addr);
776  }
777 
778  if (strlen(result) == 0) {
779  printf("*** elxu_device_get_value called for non-OCS driver for key \"%s\"\n", key);
780  }
781 
782  return result;
783 
784 }
785 int elxu_lancer_run_loopback(elxu_device_t *device_p, const char *fname, int type)
786 {
787  int rc = 0, i;
788  uint8_t *tx_buf = NULL;
789  uint8_t *rx_buf = NULL;
790 
791  tx_buf = malloc(LOOPBACK_BUF_SIZE);
792  if (tx_buf == NULL) {
793  printf("%s: failed to allocate TX buffer\n", __func__);
794  rc = -1;
795  goto exit_lancer_run_loopback;
796  }
797  memset(tx_buf, 0, LOOPBACK_BUF_SIZE);
798 
799  /*Fill TX buffer wih predefined pattren 0 1 2 3 4 .. */
800  for (i = 0; i < LOOPBACK_BUF_SIZE; i++)
801  tx_buf[i] = (char)i & 0xFF;
802 
803  rx_buf = malloc(LOOPBACK_BUF_SIZE);
804  if (rx_buf == NULL) {
805  printf("%s: failed to allocate RX buffer\n", __func__);
806  rc = -1;
807  goto exit_lancer_run_loopback;
808  }
809  memset(rx_buf, 0, LOOPBACK_BUF_SIZE);
810 
811  if ((type == INTERNAL_LOOPBACK) || (type == EXTERNAL_LOOPBACK)) {
812  rc = elxu_device_exec(device_p, "/ocs/driver/link_loopback", tx_buf, LOOPBACK_BUF_SIZE, rx_buf, LOOPBACK_BUF_SIZE);
813  } else if (type == PCI_LOOPBACK){
814  rc = elxu_device_exec(device_p, "/ocs/driver/pci_loopback",
815  tx_buf, LOOPBACK_BUF_SIZE, rx_buf, LOOPBACK_BUF_SIZE);
816  } else {
817  printf("Invalid loopback type\n");
818  rc = -1;
819  }
820 
821  printf("\n");
822 
823  if (!rc) {
824  /* Compare source and destination buffers only if rx frame was received,
825  * skip comparision in case of timeout.
826  */
827  rc = memcmp(tx_buf, rx_buf, LOOPBACK_BUF_SIZE);
828  if (rc) {
829  if (type != EXTERNAL_LOOPBACK)
830  printf("Data comparision b/w tx and rx buf is failed\n");
831  rc = -1;
832  }
833  }
834 
835 exit_lancer_run_loopback:
836  if (tx_buf)
837  free(tx_buf);
838  if (rx_buf)
839  free(rx_buf);
840  return rc;
841 }
842 
843 int elxu_lancer_set_loopback(elxu_device_t *device_p, const char *fname, int *type)
844 {
845  int rc = 0;
846 
847  if ((*type == INTERNAL_LOOPBACK) || (*type == EXTERNAL_LOOPBACK)) {
848  rc = elxu_device_exec(device_p, "/ocs/driver/set_loopback", type, 4, NULL, 0);
849  }
850  if (rc) {
851  printf("%s: failed to set loopback mode\n", __func__);
852  }
853 
854  return rc;
855 }
856 
857 int elxu_lancer_get_link_state(elxu_device_t *device_p, uint32_t *status)
858 {
859  int rc = 0;
860 
861  rc = elxu_device_exec(device_p, "/ocs/driver/get_link_state", NULL, 0, status, sizeof(uint32_t));
862  if (rc) {
863  printf("%s: Get link status mbox command failed\n", __func__);
864  }
865  return rc;
866 }
867 
868 int elxu_lancer_set_link_state(elxu_device_t *device_p, uint32_t *status)
869 {
870  int rc = 0;
871 
872  rc = elxu_device_exec(device_p, "/ocs/driver/set_link_state", status, sizeof(uint32_t), NULL, 0);
873  if (rc) {
874  printf("%s: Set link status mbox command failed\n", __func__);
875  }
876 
877  return rc;
878 }
879 
880 int elx_pt_set_dump_location(elxu_device_t *device, uint32_t num_buffers, memref_t **dump_buffers, uint8_t fdb)
881 {
883  elx_pt_ioctl_mbox_t mbox;
884  int rc;
885 
886  if (num_buffers > 1) {
887  uint32_t sge_size = num_buffers * sizeof(sli4_sge_t);
888  sli4_sge_t *sge;
889  uint32_t i;
890  memref_t *dma_sge = NULL;
891 
892  dma_sge = elx_pt_dma_alloc(device, sge_size);
893  if (dma_sge == NULL) {
894  printf("%s: failed to allocate dma memory\n", __func__);
895  goto fail;
896  }
897  memset(dma_sge->vaddr, 0, sge_size);
898  sge = dma_sge->vaddr;
899 
900  for (i = 0; i < num_buffers; i++) {
901  sge[i].buffer_address_high = addr32_hi(dump_buffers[i]->paddr);
902  sge[i].buffer_address_low = addr32_lo(dump_buffers[i]->paddr);
903  sge[i].last = (i == num_buffers - 1 ? 1 : 0);
904  sge[i].buffer_length = dump_buffers[i]->size;
905  }
906 
907  bzero(&req, sizeof(req));
910  req.request_length = sizeof(req) + sizeof(mbox_hbd_t);
911  req.buf_addr_low = addr32_lo(dma_sge->paddr);
912  req.blp = 1;
913  req.buf_addr_high = addr32_hi(dma_sge->paddr);
914  req.buffer_length = sge_size;
915 
916  mbox.words = (uint32_t *)&req;
917  mbox.num_words = (sizeof(req) + sizeof(mbox_hbd_t) + 3) / 4;
918  rc = ioctl(device->fd, IOCTL_CMD_ELX_PT_MBOX, &mbox);
919  if (rc) {
920  printf("%s: IOCTL is failed\n", __func__);
921  elx_pt_dma_free(dma_sge);
922  goto fail;
923  }
924  elx_pt_dma_free(dma_sge);
925  }
926 
927  return 0;
928 
929 fail:
930  return -1;
931 
932 }
933 /**
934  * @ingroup dev_mgmt
935  * @brief Execute a management function on a device
936  *
937  * @par Description
938  * For the OCS driver this is just a wrapper around calls
939  * to mgmt_exec. The driver's mgmt interface will
940  * execute the function.
941  *
942  * For the elx_pt driver we have to simulate the mgmt_exec
943  * function because the driver doesn't have the mgmt interface.
944  * For a limited set of key this function will perform the
945  * equivalent operation in other ways.
946  *
947  * @param device Device to access.
948  * @param key Name of the property to retrieve.
949  *
950  * @return Returns a pointer to a static char[] with the result.
951  */
952 int elxu_device_exec(elxu_device_t *device, char *name, void* arg_in, int arg_in_len,
953  void* arg_out, int arg_out_len)
954 {
955  int result;
956 
957  if (device->driver == DEVICE_DRIVER_OCS) {
958  return mgmt_exec(device, name, arg_in, arg_in_len,
959  arg_out, arg_out_len);
960  }
961 
962  result = -1;
963  if (strcmp(name, "/ocs/driver/gendump") == 0) {
964 
965  /*
966  * Dump is generated by doing a firmware reset with the DD
967  * bit set
968  */
969 
970  mbox_fw_reset_pt(device, 1);
971 
972  result = 0;
973  }
974  if (strcmp(name, "/ocs/driver/dump_to_host") == 0) {
975 
976 #define ELX_PT_MAX_DMA_ALLOC 64*1024
977  int32_t num_buffers = (arg_out_len + (ELX_PT_MAX_DMA_ALLOC) - 1 )/(ELX_PT_MAX_DMA_ALLOC);
978  memref_t **dma_buffers = NULL;
979  uint32_t rem_bytes, i, offset;
980 
981  /*
982  * Dump is generated by doing a firmware reset with the DD
983  * bit set
984  */
985  if ((arg_out_len == 0) || (arg_out == NULL)) {
986  printf("%s: Input buffer is invalid\n", __func__);
987  result = -1;
988  goto fail;
989  }
990  /* Allocate a DMA buffers to hold the dump */
991  dma_buffers = malloc(sizeof(memref_t *) * num_buffers);
992  if (dma_buffers == NULL) {
993  printf("%s: failed to allocate dma_buffers memory\n", __func__);
994  result = -1;
995  goto fail;
996  }
997 
998  rem_bytes = arg_out_len;
999  for (i = 0; i < num_buffers; i++) {
1000  uint32_t num_bytes = MIN(rem_bytes, ELX_PT_MAX_DMA_ALLOC);
1001  dma_buffers[i] = elx_pt_dma_alloc(device, ELX_PT_MAX_DMA_ALLOC);
1002  if (dma_buffers[i] == NULL) {
1003  printf("%s: failed to allocate dma memory %d\n", __func__,i);
1004  result = -1;
1005  goto free_and_return;
1006  }
1007  rem_bytes -= num_bytes;
1008  }
1009 
1010  elx_pt_set_dump_location(device, num_buffers, dma_buffers, 0);
1011 
1012  mbox_fw_reset_pt(device, 1);
1013  offset = 0;
1014 
1015  result = 0;
1016  for (i = 0; i < num_buffers; i++) {
1017  memcpy((uint8_t *)arg_out + offset, dma_buffers[i]->vaddr, dma_buffers[i]->size);
1018  offset += dma_buffers[i]->size;
1019  }
1020 
1021 free_and_return:
1022  for (i = 0; i < num_buffers; i++) {
1023  if (dma_buffers[i])
1024  elx_pt_dma_free(dma_buffers[i]);
1025  }
1026  free(dma_buffers);
1027  }
1028 
1029  if (strcmp(name, "/ocs/firmware_write") == 0) {
1030  memref_t *dma_buffer;
1031  int rc;
1032  uint8_t *chunk_p;
1033  size_t chunk_size;
1034  int remaining;
1037  elx_pt_ioctl_mbox_t mbox;
1038  int change_status = 0;
1039  int last;
1040 
1041 #define FW_BUFFER_SIZE 64*1024
1042  /*
1043  * The new firmware image is in memory at arg_in with a
1044  * length of arg_in_len. We need to send it in 64K chunks.
1045  */
1046 
1047  /* Create a DMA buffer */
1048  dma_buffer = elx_pt_dma_alloc(device, FW_BUFFER_SIZE);
1049  if (dma_buffer == NULL) {
1050  goto fail;
1051  }
1052 
1053  chunk_p = arg_in;
1054  remaining = arg_in_len;
1055  last = 0;
1056 
1057 
1058  rsp = (mbox_common_write_object_rsp_t *) &req;
1059 
1060  mbox.words = (uint32_t *)&req;
1061  mbox.num_words = (sizeof(req) + 3) / 4;
1062 
1063  result = 0;
1064  while (remaining > 0) {
1065  /* Copy the firmware to the DMA buffer */
1066  chunk_size = (remaining > FW_BUFFER_SIZE ? FW_BUFFER_SIZE : remaining);
1067  memcpy(dma_buffer->vaddr, chunk_p, chunk_size);
1068 
1069  /* Send a COMMON_WRITE_OBJECT that points to the DMA buffer */
1070  bzero(&req, sizeof(req));
1073  req.request_length = sizeof(req);
1074  strcpy((char *)req.object_name, "/prg/");
1078  if (remaining <= FW_BUFFER_SIZE) {
1079  /* Set the EOF bit */
1080  last = 1;
1081  }
1082  req.eof = last;
1083  req.desired_write_length = chunk_size;
1084  req.write_offset = chunk_p - (uint8_t *)arg_in;
1085  req.device_buffer_descriptor[0].buffer_length = chunk_size;
1086 
1087  rc = ioctl(device->fd, IOCTL_CMD_ELX_PT_MBOX, &mbox);
1088 
1089  if (rc != 0) {
1090  perror("ioctl");
1091  result = -1;
1092  break;
1093  }
1094 
1095  if (rsp->status != 0) {
1096  printf("WRITE_OBJECT returned status %d\n", rsp->status);
1097  result = -1;
1098  break;
1099  }
1100 
1101  chunk_p += chunk_size;
1102  remaining -= chunk_size;
1103 
1104  if (last) {
1105  change_status = rsp->change_status;
1106  }
1107 
1108  printf("."); fflush(stdout);
1109  }
1110 
1111  printf("\n");
1112 
1113  snprintf(arg_out, arg_out_len, "%d", change_status);
1114 
1115  /* Free the DMA buffer */
1116  elx_pt_dma_free(dma_buffer);
1117 
1118  }
1119 
1120  if (result == -1) {
1121  printf("*** elxu_device_exec called for non-OCS driver for function \"%s\"\n", name);
1122  }
1123 
1124 fail:
1125  return result;
1126 
1127 }
1128 
1130 {
1131  int i;
1132 
1133  for (i=0; i<ARRAY_SIZE(pci_device_map); i++) {
1134  if ((device->vendor == pci_device_map[i].vendor) &&
1135  (device->device == pci_device_map[i].device)) {
1136  device->type = pci_device_map[i].type;
1137  device->protocol = pci_device_map[i].protocol;
1138  break;
1139  }
1140  }
1141 }
1142 
1143 /**
1144  * @brief Return true IFF the HBA is an iSCSI HBA
1145  *
1146  * Given a pointer to a device structure, return 1 if the HBA is iSCSI
1147  * and 0 if it is not.
1148  *
1149  * @param device_p A pointer to HBA node
1150  */
1151 int is_iscsi(elxu_device_t *device_p)
1152 {
1153  if (device_p->protocol == DEVICE_PROTOCOL_ISCSI) {
1154  return 1;
1155  } else {
1156  return 0;
1157  }
1158 }
1159 
1160 /**
1161  * @brief Return true IFF the HBA is a NIC HBA
1162  *
1163  * Given a pointer to a device structure, return 1 if the HBA is NIC
1164  * and 0 if it is not.
1165  *
1166  * @param device_p A pointer to HBA node
1167  */
1168 int is_nic(elxu_device_t *device_p)
1169 {
1170  if (device_p->protocol == DEVICE_PROTOCOL_NIC) {
1171  return 1;
1172  } else {
1173  return 0;
1174  }
1175 }
1176 
1177 /**
1178  * @brief Return true IFF the HBA is a FC HBA
1179  *
1180  * Given a pointer to a device structure, return 1 if the HBA is FC
1181  * and 0 if it is not.
1182  *
1183  * @param device_p A pointer to HBA node
1184  */
1185 int is_fc(elxu_device_t *device_p)
1186 {
1187  if (device_p->protocol == DEVICE_PROTOCOL_FC) {
1188  return 1;
1189  } else {
1190  return 0;
1191  }
1192 }
1193 
1194 /**
1195  * @brief Return true IFF the HBA is a FCoE HBA
1196  *
1197  * Given a pointer to a device structure, return 1 if the HBA is FCoE
1198  * and 0 if it is not.
1199  *
1200  * @param device_p A pointer to HBA node
1201  */
1202 int is_fcoe(elxu_device_t *device_p)
1203 {
1204  if (device_p->protocol == DEVICE_PROTOCOL_FCOE) {
1205  return 1;
1206  } else {
1207  return 0;
1208  }
1209 }
1210 
1211 /**
1212  * @brief Return true IFF the HBA is a Skyhawk
1213  *
1214  * Given a pointer to a device structure, return 1 if the HBA is Skyhawk
1215  * and 0 if it is not.
1216  *
1217  * @param device_p A pointer to HBA node
1218  */
1220 {
1221  if (device_p->type == DEVICE_TYPE_SKYHAWK) {
1222  return 1;
1223  } else {
1224  return 0;
1225  }
1226 }
1227 
1228 /**
1229  * @brief Return true IFF the HBA is a Lancer
1230  *
1231  * Given a pointer to a device structure, return 1 if the HBA is Lancer
1232  * and 0 if it is not.
1233  *
1234  * @param device_p A pointer to HBA node
1235  */
1236 int is_lancer(elxu_device_t *device_p)
1237 {
1238  if (device_p->type == DEVICE_TYPE_LANCER) {
1239  return 1;
1240  } else {
1241  return 0;
1242  }
1243 }
1244 
1245 /**
1246  * @brief Return true IFF the HBA is a Lancer G5
1247  *
1248  * Given a pointer to a device structure, return 1 if the HBA is Lancer
1249  * and 0 if it is not.
1250  *
1251  * @param device_p A pointer to HBA node
1252  */
1254 {
1255  if (device_p->device == PCI_DEVICE_ID_LANCER_FC) {
1256  return 1;
1257  } else {
1258  return 0;
1259  }
1260 }
1261 
1262 /**
1263  * @brief Return true IFF the HBA is a Prism
1264  *
1265  * Given a pointer to a device structure, return 1 if the HBA is Prism
1266  * and 0 if it is not.
1267  *
1268  * @param device_p A pointer to HBA node
1269  */
1270 int is_prism(elxu_device_t *device_p)
1271 {
1272  if (device_p->type == DEVICE_TYPE_PRISM) {
1273  return 1;
1274  } else {
1275  return 0;
1276  }
1277 }
1278 
1279 /**
1280  * @brief Return true IFF the HBA is a Calypso
1281  *
1282  * Given a pointer to a device structure, return 1 if the HBA is
1283  * Calypso and 0 if it is not.
1284  *
1285  * @param device_p A pointer to HBA node
1286  */
1288 {
1289  if ((device_p->subsystem_device == 0xe20d) ||
1290  (device_p->subsystem_device == 0xe20f)) {
1291  return 1;
1292  } else {
1293  return 0;
1294  }
1295 }
1296 
1297 /**
1298  * @brief Return true IFF the device is managed by a user space driver
1299  *
1300  * Given a pointer to a device structure, return 1 if the driver is
1301  * user space and 0 if it is not.
1302  *
1303  * @param device_p A pointer to HBA node
1304  */
1305 int is_uspace(elxu_device_t *device_p)
1306 {
1307  if (device_p->driver == DEVICE_DRIVER_USPACE) {
1308  return 1;
1309  } else {
1310  return 0;
1311  }
1312 }
1313 
#define PCI_LOOPBACK
Definition: elxu_mbox.h:78
uint16_t subsystem_device
Definition: elxu_device.h:84
uint32_t object_name[OBJECT_NAME_LENGTH]
Definition: elxu_sli4.h:596
uint32_t buffer_address_low
Definition: elxu_sli4.h:137
const char * elxu_get_vendor_name(elxu_device_t *device)
Return the vendor name for a device.
Definition: elxu_device.c:576
memref_t * elx_pt_dma_alloc(elxu_device_t *device, int size)
Request a DMA allocation through elx_pt.
Definition: elxu_mbox.c:2549
char * modeldesc
Definition: elxu_device.h:94
#define PCI_DEVICE_ID_LANCER_FCOE
Definition: elxu_device.h:47
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 fwrev[32]
Definition: elxu_device.h:92
uint32_t elxu_get_asic_id(elxu_device_t *device)
Return the ASIC ID value for a device.
Definition: elxu_device.c:478
int is_fc(elxu_device_t *device_p)
Return true IFF the HBA is a FC HBA.
Definition: elxu_device.c:1185
static elxu_device_t * device_list
Definition: elxu_device.c:60
unsigned buffer_length
Definition: elxu_sli4.h:135
int elxu_device_exec(elxu_device_t *device, char *name, void *arg_in, int arg_in_len, void *arg_out, int arg_out_len)
Execute a management function on a device.
Definition: elxu_device.c:952
static uint32_t addr32_lo(uintptr_t addr)
Definition: elxu_common.h:50
uint32_t buffer_address_high
Definition: elxu_sli4.h:138
elxu_device_t * os_build_device_list(char *path)
Definition: elxu_bsd.c:71
elxu_device_protocol_e protocol
Definition: elxu_device.c:103
#define PCI_VENDOR_ID_EMULEX
Definition: elxu_device.h:39
int elx_pt_set_dump_location(elxu_device_t *device, uint32_t num_buffers, memref_t **dump_buffers, uint8_t fdb)
Definition: elxu_device.c:880
#define PCI_DEVICE_ID_PRISM
Definition: elxu_device.h:45
elxu_device_t * elxu_device_from_args(int argc, char *argv[])
Return a pointer to a device based on command line args.
Definition: elxu_device.c:688
int mgmt_exec(elxu_device_t *device, char *name, void *arg_in, int arg_in_len, void *arg_out, int arg_out_len)
Definition: elxu_mgmt.c:466
#define PCI_DEVICE_ID_SKYHAWK_FCOE
Definition: elxu_device.h:52
uint16_t device
Definition: elxu_device.h:82
uint32_t sli_intf
Definition: elxu_device.h:86
void os_close_device(elxu_device_t *device)
Close a device file.
Definition: elxu_bsd.c:187
#define PCI_DEVICE_ID_LANCER_G6
Definition: elxu_device.h:44
char ipl[16]
Definition: elxu_device.h:93
char * elxu_get_ipl(elxu_device_t *device)
Return the IPL version for a device.
Definition: elxu_device.c:404
int os_ioctl_device(elxu_device_t *device, int req, void *arg)
Send an ioctl to an open device.
Definition: elxu_bsd.c:211
int elxu_lancer_set_link_state(elxu_device_t *device_p, uint32_t *status)
Definition: elxu_device.c:868
uint16_t vendor
Definition: elxu_device.h:81
struct elxu_device_struct * next
Definition: elxu_device.h:79
elxu_device_type_e type
Definition: elxu_device.h:88
uint32_t device_buffer_descriptor_count
Definition: elxu_sli4.h:598
device name specifier This structure is used to describe the type and name of the device ioctl connec...
Definition: elxu_device.h:113
int is_lancer_g5(elxu_device_t *device_p)
Return true IFF the HBA is a Lancer G5.
Definition: elxu_device.c:1253
static void dev_parse_wwn(char *, uint8_t *)
Definition: elxu_device.c:261
elxu_device_type_e type
Definition: elxu_device.c:67
int elxu_lancer_set_loopback(elxu_device_t *device_p, const char *fname, int *type)
Definition: elxu_device.c:843
#define FW_BUFFER_SIZE
#define PCI_DEVICE_ID_SKYHAWK_ISCSI_TGT
Definition: elxu_device.h:51
int is_uspace(elxu_device_t *device_p)
Return true IFF the device is managed by a user space driver.
Definition: elxu_device.c:1305
int elxu_ioctl_device(elxu_device_t *device, int req, void *arg)
Send an ioctl to a device.
Definition: elxu_device.c:322
int is_lancer(elxu_device_t *device_p)
Return true IFF the HBA is a Lancer.
Definition: elxu_device.c:1236
#define PCI_DEVICE_ID_SKYHAWK_ISCSI_INI
Definition: elxu_device.h:50
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 INTERNAL_LOOPBACK
Definition: elxu_mbox.h:76
uint32_t asic_id
Definition: elxu_device.h:87
static device_protocol_info_t device_protocol_info[]
Definition: elxu_device.c:87
static device_type_info_t device_type_info[]
Definition: elxu_device.c:71
void fill_device_details(elxu_device_t *device)
Definition: elxu_device.c:225
mbox_hbd_t device_buffer_descriptor[1]
Definition: elxu_sli4.h:600
#define MBOX_SUBSYSTEM_COMMON
Definition: elxu_sli4.h:76
uint32_t deviceIndex
Definition: elxu_device.h:85
elxu_device_type_e type
Definition: elxu_device.c:102
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
#define OPCODE_COMMON_WRITE_OBJECT
Definition: elxu_sli4.h:101
char * serialnum
Definition: elxu_device.h:95
uint32_t elxu_get_phy_port_num(elxu_device_t *device)
Return the physical port number for a device.
Definition: elxu_device.c:446
#define PCI_VENDOR_ID_ATTO
Definition: elxu_device.h:40
int is_skyhawk(elxu_device_t *device_p)
Return true IFF the HBA is a Skyhawk.
Definition: elxu_device.c:1219
uint32_t phy_port_num
Definition: elxu_device.h:96
int is_fcoe(elxu_device_t *device_p)
Return true IFF the HBA is a FCoE HBA.
Definition: elxu_device.c:1202
elxu_device_t * elxu_device_by_index(int index)
Return a pointer to a device given an index.
Definition: elxu_device.c:730
#define PCI_DEVICE_ID_LANCER_FC
Definition: elxu_device.h:43
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 ARRAY_SIZE(x)
Definition: elxu_common.h:46
pci_device_map_t pci_device_map[]
Definition: elxu_device.c:106
elxu_device_protocol_e protocol
Definition: elxu_device.h:89
#define MIN(x, y)
Definition: elxu_device.c:55
uintptr_t paddr
Definition: elxu_mbox.h:45
void elxu_build_device_list(int argc, char *argv[])
Create a list of devices.
Definition: elxu_device.c:131
#define OPCODE_COMMON_SET_DUMP_LOCATION
Definition: elxu_sli4.h:106
#define ELX_PT_MAX_DMA_ALLOC
elxu_device_protocol_e
Definition: elxu_device.h:61
elxu_device_t * elxu_open_device(elxu_device_name_t *devname)
Open a device file.
Definition: elxu_device.c:212
uint32_t elxu_get_sliintf(elxu_device_t *device)
Return the sli_intf value for a device.
Definition: elxu_device.c:462
void elxu_close_device(elxu_device_t *device)
Close a device.
Definition: elxu_device.c:340
int is_iscsi(elxu_device_t *device_p)
Return true IFF the HBA is an iSCSI HBA.
Definition: elxu_device.c:1151
void set_protocol(elxu_device_t *device)
Definition: elxu_device.c:1129
elxu_device_type_e
Definition: elxu_device.h:54
void elxu_delete_device_list()
Definition: elxu_device.c:164
int mbox_fw_reset_pt(elxu_device_t *device, int dd)
Definition: elxu_mbox.c:2625
#define LOOPBACK_BUF_SIZE
Definition: elxu_mbox.h:80
int is_prism(elxu_device_t *device_p)
Return true IFF the HBA is a Prism.
Definition: elxu_device.c:1270
static uint32_t addr32_hi(uintptr_t addr)
Definition: elxu_common.h:59
elxu_device_t * os_open_device(elxu_device_name_t *devname)
Open a device file.
Definition: elxu_bsd.c:148
char * elxu_get_fwrev(elxu_device_t *device)
Return the firmware revision for a device.
Definition: elxu_device.c:384
char * elxu_decode_family(uint32_t family)
Lookup a family name.
Definition: elxu_device.c:495
#define PCI_DEVICE_ID_SKYHAWK_NIC
Definition: elxu_device.h:49
void * vaddr
Definition: elxu_mbox.h:44
void elx_pt_dma_free(memref_t *memref)
Free a DMA allocation through elx_pt.
Definition: elxu_mbox.c:2602
int elxu_lancer_run_loopback(elxu_device_t *device_p, const char *fname, int type)
Definition: elxu_device.c:785
elxu_device_protocol_e protocol
Definition: elxu_device.c:83
elxu_device_t * os_build_device_list_uspace(char *hostname)
Definition: elxu_bsd.c:123
static void dev_parse_mac(char *, uint8_t *)
Definition: elxu_device.c:285
int elxu_lancer_get_link_state(elxu_device_t *device_p, uint32_t *status)
Definition: elxu_device.c:857
size_t size
Definition: elxu_mbox.h:46
elxu_device_driver_e driver
Definition: elxu_device.h:90
#define EXTERNAL_LOOPBACK
Definition: elxu_mbox.h:77
char device_file_name[1024]
Definition: elxu_device.h:102
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
int is_calypso(elxu_device_t *device_p)
Return true IFF the HBA is a Calypso.
Definition: elxu_device.c:1287
char * elxu_decode_asic_id(uint32_t asic_id)
Lookup an ASIC ID name.
Definition: elxu_device.c:526
uint8_t mac_addr[6]
Definition: elxu_device.h:100
uint8_t wwnn[8]
Definition: elxu_device.h:98
uint16_t subsystem_vendor
Definition: elxu_device.h:83
#define PCI_DEVICE_ID_LANCER_G6_ATTO
Definition: elxu_device.h:46
#define PCI_DEVICE_ID_LANCER_NIC
Definition: elxu_device.h:48
int os_remove_device(elxu_device_t *device)
Definition: elxu_bsd.c:193
char * mgmt_get_value(elxu_device_t *device, char *name)
Definition: elxu_mgmt.c:354