summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--vlib/vlib/pci/pci.c96
-rw-r--r--vlib/vlib/pci/pci.h2
2 files changed, 93 insertions, 5 deletions
diff --git a/vlib/vlib/pci/pci.c b/vlib/vlib/pci/pci.c
index 07d89fda233..7100064df42 100644
--- a/vlib/vlib/pci/pci.c
+++ b/vlib/vlib/pci/pci.c
@@ -52,6 +52,19 @@
vlib_pci_main_t pci_main;
+vlib_pci_device_t *
+vlib_get_pci_device (vlib_pci_addr_t * addr)
+{
+ vlib_pci_main_t *pm = &pci_main;
+ uword *p;
+ p = hash_get (pm->pci_dev_index_by_pci_addr, addr->as_u32);
+
+ if (p == 0)
+ return 0;
+
+ return vec_elt_at_index (pm->pci_devs, p[0]);
+}
+
static clib_error_t *
show_pci_fn (vlib_main_t * vm,
unformat_input_t * input, vlib_cli_command_t * cmd)
@@ -70,9 +83,9 @@ show_pci_fn (vlib_main_t * vm,
format_unformat_error, input);
}
- vlib_cli_output (vm, "%-13s%-7s%-12s%-15s%-20s%-40s",
- "Address", "Socket", "VID:PID", "Link Speed", "Driver",
- "Product Name");
+ vlib_cli_output (vm, "%-13s%-5s%-12s%-13s%-16s%-32s%s",
+ "Address", "Sock", "VID:PID", "Link Speed", "Driver",
+ "Product Name", "Vital Product Data");
/* *INDENT-OFF* */
pool_foreach (d, pm->pci_devs, ({
@@ -85,12 +98,13 @@ show_pci_fn (vlib_main_t * vm,
if (d->numa_node >= 0)
s = format (s, " %d", d->numa_node);
- vlib_cli_output (vm, "%-13U%-7v%04x:%04x %-15U%-20s%-40v",
+ vlib_cli_output (vm, "%-13U%-5v%04x:%04x %-13U%-16s%-32v%U",
format_vlib_pci_addr, &d->bus_address, s,
d->vendor_id, d->device_id,
format_vlib_pci_link_speed, d,
d->driver_name ? (char *) d->driver_name : "",
- d->product_name);
+ d->product_name,
+ format_vlib_pci_vpd, d->vpd_r, 0);
}));
/* *INDENT-ON* */
@@ -152,6 +166,78 @@ format_vlib_pci_link_speed (u8 * s, va_list * va)
return format (s, "unknown");
}
+u8 *
+format_vlib_pci_vpd (u8 * s, va_list * args)
+{
+ u8 *data = va_arg (*args, u8 *);
+ u8 *id = va_arg (*args, u8 *);
+ uword indent = format_get_indent (s);
+ char *string_types[] = { "PN", "EC", "SN", "MN", 0 };
+ uword p = 0;
+ int first_line = 1;
+
+ if (vec_len (data) < 3)
+ return s;
+
+ while (p + 3 < vec_len (data))
+ {
+
+ if (data[p] == 0 && data[p + 1] == 0)
+ return s;
+
+ if (p + data[p + 2] > vec_len (data))
+ return s;
+
+ if (id == 0)
+ {
+ int is_string = 0;
+ char **c = string_types;
+
+ while (c[0])
+ {
+ if (*(u16 *) & data[p] == *(u16 *) c[0])
+ is_string = 1;
+ c++;
+ }
+
+ if (data[p + 2])
+ {
+ if (!first_line)
+ s = format (s, "\n%U", format_white_space, indent);
+ else
+ {
+ first_line = 0;
+ s = format (s, " ");
+ }
+
+ s = format (s, "%c%c: ", data[p], data[p + 1]);
+ if (is_string)
+ vec_add (s, data + p + 3, data[p + 2]);
+ else
+ {
+ int i;
+ const int max_bytes = 8;
+ s = format (s, "0x");
+ for (i = 0; i < clib_min (data[p + 2], max_bytes); i++)
+ s = format (s, " %02x", data[p + 3 + i]);
+
+ if (data[p + 2] > max_bytes)
+ s = format (s, " ...");
+ }
+ }
+ }
+ else if (*(u16 *) & data[p] == *(u16 *) id)
+ {
+ vec_add (s, data + p + 3, data[p + 2]);
+ return s;
+ }
+
+ p += 3 + data[p + 2];
+ }
+
+ return s;
+}
+
/* *INDENT-OFF* */
VLIB_CLI_COMMAND (show_pci_command, static) = {
diff --git a/vlib/vlib/pci/pci.h b/vlib/vlib/pci/pci.h
index 3b83b89208b..811a6ff2336 100644
--- a/vlib/vlib/pci/pci.h
+++ b/vlib/vlib/pci/pci.h
@@ -230,6 +230,7 @@ clib_error_t *vlib_pci_map_resource_fixed (vlib_pci_device_t * dev,
u32 resource, u8 * addr,
void **result);
+vlib_pci_device_t *vlib_get_pci_device (vlib_pci_addr_t * addr);
/* Free's device. */
void vlib_pci_free_device (vlib_pci_device_t * dev);
@@ -237,6 +238,7 @@ unformat_function_t unformat_vlib_pci_addr;
format_function_t format_vlib_pci_addr;
format_function_t format_vlib_pci_handle;
format_function_t format_vlib_pci_link_speed;
+format_function_t format_vlib_pci_vpd;
#endif /* included_vlib_pci_h */