vlib: pci cleanup and improvements
[vpp.git] / src / vlib / linux / pci.c
index 75d9edf..e94fee1 100644 (file)
@@ -61,12 +61,17 @@ static const char *sysfs_pci_drv_path = "/sys/bus/pci/drivers";
 static char *sysfs_mod_vfio_noiommu =
   "/sys/module/vfio/parameters/enable_unsafe_noiommu_mode";
 
-#define pci_log_debug(vm, dev, f, ...) \
-  vlib_log(VLIB_LOG_LEVEL_DEBUG, pci_main.log_default, "%U: " f, \
-           format_vlib_pci_addr, vlib_pci_get_addr(vm, dev->handle), ## __VA_ARGS__)
-#define pci_log_err(vm, dev, f, ...) \
-  vlib_log(VLIB_LOG_LEVEL_ERR, pci_main.log_default, "%U: " f, \
-           format_vlib_pci_addr, vlib_pci_get_addr(vm, dev->handle), ## __VA_ARGS__)
+VLIB_REGISTER_LOG_CLASS (pci_log, static) = {
+  .class_name = "pci",
+  .subclass_name = "linux",
+};
+
+#define log_debug(p, f, ...)                                                  \
+  vlib_log (VLIB_LOG_LEVEL_DEBUG, pci_log.class, "%U: " f,                    \
+           format_vlib_pci_log, p->handle, ##__VA_ARGS__)
+#define log_err(p, f, ...)                                                    \
+  vlib_log (VLIB_LOG_LEVEL_ERR, pci_log.class, "%U: " f, format_vlib_pci_log, \
+           p->handle, ##__VA_ARGS__)
 
 typedef struct
 {
@@ -233,32 +238,13 @@ vlib_pci_get_device_info (vlib_main_t * vm, vlib_pci_addr_t * addr,
 
   /* You can only read more that 64 bytes of config space as root; so we try to
      read the full space but fall back to just the first 64 bytes. */
-  if (read (fd, &di->config_data, sizeof (di->config_data)) <
-      sizeof (di->config0))
+  if (read (fd, &di->config, sizeof (di->config)) < sizeof (di->config))
     {
       err = clib_error_return_unix (0, "read `%s'", f);
       close (fd);
       goto error;
     }
 
-  {
-    static pci_config_header_t all_ones;
-    if (all_ones.vendor_id == 0)
-      clib_memset (&all_ones, ~0, sizeof (all_ones));
-
-    if (!memcmp (&di->config0.header, &all_ones, sizeof (all_ones)))
-      {
-       err = clib_error_return (0, "invalid PCI config for `%s'", f);
-       close (fd);
-       goto error;
-      }
-  }
-
-  if (di->config0.header.header_type == 0)
-    pci_config_type0_little_to_host (&di->config0);
-  else
-    pci_config_type1_little_to_host (&di->config1);
-
   di->numa_node = -1;
   vec_reset_length (f);
   f = format (f, "%v/numa_node%c", dev_dir_name, 0);
@@ -300,6 +286,13 @@ vlib_pci_get_device_info (vlib_main_t * vm, vlib_pci_addr_t * addr,
     goto error;
   di->device_id = tmp;
 
+  vec_reset_length (f);
+  f = format (f, "%v/revision%c", dev_dir_name, 0);
+  err = clib_sysfs_read ((char *) f, "0x%x", &tmp);
+  if (err)
+    goto error;
+  di->revision = tmp;
+
   vec_reset_length (f);
   f = format (f, "%v/driver%c", dev_dir_name, 0);
   di->driver_name = clib_sysfs_link_to_name ((char *) f);
@@ -670,13 +663,12 @@ vfio_set_irqs (vlib_main_t * vm, linux_pci_device_t * p, u32 index, u32 start,
     return clib_error_return_unix (0, "ioctl(VFIO_DEVICE_GET_IRQ_INFO) "
                                   "'%U'", format_vlib_pci_addr, &p->addr);
 
-  pci_log_debug (vm, p, "%s index:%u count:%u flags: %s%s%s%s(0x%x)",
-                __func__, ii.index, ii.count,
-                ii.flags & VFIO_IRQ_INFO_EVENTFD ? "eventfd " : "",
-                ii.flags & VFIO_IRQ_INFO_MASKABLE ? "maskable " : "",
-                ii.flags & VFIO_IRQ_INFO_AUTOMASKED ? "automasked " : "",
-                ii.flags & VFIO_IRQ_INFO_NORESIZE ? "noresize " : "",
-                ii.flags);
+  log_debug (p, "%s index:%u count:%u flags: %s%s%s%s(0x%x)", __func__,
+            ii.index, ii.count,
+            ii.flags & VFIO_IRQ_INFO_EVENTFD ? "eventfd " : "",
+            ii.flags & VFIO_IRQ_INFO_MASKABLE ? "maskable " : "",
+            ii.flags & VFIO_IRQ_INFO_AUTOMASKED ? "automasked " : "",
+            ii.flags & VFIO_IRQ_INFO_NORESIZE ? "noresize " : "", ii.flags);
 
   if (ii.count < start + count)
     return clib_error_return_unix (0, "vfio_set_irq: unexistng interrupt on "
@@ -864,13 +856,12 @@ vlib_pci_register_intx_handler (vlib_main_t * vm, vlib_pci_dev_handle_t h,
       if (ioctl (p->fd, VFIO_DEVICE_GET_IRQ_INFO, &ii) < 0)
        return clib_error_return_unix (0, "ioctl(VFIO_DEVICE_GET_IRQ_INFO) '"
                                       "%U'", format_vlib_pci_addr, &p->addr);
-      pci_log_debug (vm, p, "%s index:%u count:%u flags: %s%s%s%s(0x%x)",
-                    __func__, ii.index, ii.count,
-                    ii.flags & VFIO_IRQ_INFO_EVENTFD ? "eventfd " : "",
-                    ii.flags & VFIO_IRQ_INFO_MASKABLE ? "maskable " : "",
-                    ii.flags & VFIO_IRQ_INFO_AUTOMASKED ? "automasked " : "",
-                    ii.flags & VFIO_IRQ_INFO_NORESIZE ? "noresize " : "",
-                    ii.flags);
+      log_debug (
+       p, "%s index:%u count:%u flags: %s%s%s%s(0x%x)", __func__, ii.index,
+       ii.count, ii.flags & VFIO_IRQ_INFO_EVENTFD ? "eventfd " : "",
+       ii.flags & VFIO_IRQ_INFO_MASKABLE ? "maskable " : "",
+       ii.flags & VFIO_IRQ_INFO_AUTOMASKED ? "automasked " : "",
+       ii.flags & VFIO_IRQ_INFO_NORESIZE ? "noresize " : "", ii.flags);
       if (ii.count != 1)
        return clib_error_return (0, "INTx interrupt does not exist on device"
                                  "'%U'", format_vlib_pci_addr, &p->addr);
@@ -1042,7 +1033,7 @@ add_device_vfio (vlib_main_t * vm, linux_pci_device_t * p,
       goto error;
     }
 
-  pci_log_debug (vm, p, "%s %U", __func__, format_vfio_region_info, &reg);
+  log_debug (p, "%s %U", __func__, format_vfio_region_info, &reg);
 
   p->config_offset = reg.offset;
   p->config_fd = p->fd;
@@ -1177,7 +1168,7 @@ vlib_pci_region (vlib_main_t * vm, vlib_pci_dev_handle_t h, u32 bar, int *fd,
       _fd = p->fd;
       _size = r->size;
       _offset = r->offset;
-      pci_log_debug (vm, p, "%s %U", __func__, format_vfio_region_info, r);
+      log_debug (p, "%s %U", __func__, format_vfio_region_info, r);
       clib_mem_free (r);
     }
   else
@@ -1198,18 +1189,18 @@ vlib_pci_map_region_int (vlib_main_t * vm, vlib_pci_dev_handle_t h,
   int fd = -1;
   clib_error_t *error;
   u64 size = 0, offset = 0;
-  u16 command;
+  vlib_pci_config_reg_command_t command;
 
-  pci_log_debug (vm, p, "map region %u to va %p", bar, addr);
+  log_debug (p, "map region %u to va %p", bar, addr);
 
-  if ((error = vlib_pci_read_config_u16 (vm, h, 4, &command)))
+  if ((error = vlib_pci_read_config_u16 (vm, h, 4, &command.as_u16)))
     return error;
 
-  if (!(command & PCI_COMMAND_MEMORY))
+  if (!(command.mem_space))
     {
-      pci_log_debug (vm, p, "setting memory enable bit");
-      command |= PCI_COMMAND_MEMORY;
-      if ((error = vlib_pci_write_config_u16 (vm, h, 4, &command)))
+      log_debug (p, "setting memory enable bit");
+      command.mem_space = 1;
+      if ((error = vlib_pci_write_config_u16 (vm, h, 4, &command.as_u16)))
        return error;
     }
 
@@ -1321,12 +1312,19 @@ vlib_pci_device_open (vlib_main_t * vm, vlib_pci_addr_t * addr,
 
   if (err)
     return err;
-  for (i = ids; i->vendor_id != 0; i++)
-    if (i->vendor_id == di->vendor_id && i->device_id == di->device_id)
-      break;
 
-  if (i->vendor_id == 0)
-    return clib_error_return (0, "Wrong vendor or device id");
+  if (ids)
+    {
+      for (i = ids; i->vendor_id != 0; i++)
+       if (i->vendor_id == di->vendor_id && i->device_id == di->device_id)
+         break;
+
+      if (i->vendor_id == 0)
+       {
+         vlib_pci_free_device_info (di);
+         return clib_error_return (0, "Wrong vendor or device id");
+       }
+    }
 
   pool_get (lpm->linux_pci_devices, p);
   p->handle = p - lpm->linux_pci_devices;
@@ -1339,9 +1337,8 @@ vlib_pci_device_open (vlib_main_t * vm, vlib_pci_addr_t * addr,
    */
   p->io_fd = -1;
 
-  pci_log_debug (vm, p, "open vid:0x%04x did:0x%04x driver:%s iommu_group:%d",
-                di->vendor_id, di->device_id, di->driver_name,
-                di->iommu_group);
+  log_debug (p, "open vid:0x%04x did:0x%04x driver:%s iommu_group:%d",
+            di->vendor_id, di->device_id, di->driver_name, di->iommu_group);
 
   if (clib_strncmp ("vfio-pci", (char *) di->driver_name, 8) == 0)
     err = add_device_vfio (vm, p, di, 0);
@@ -1359,7 +1356,7 @@ error:
   vlib_pci_free_device_info (di);
   if (err)
     {
-      pci_log_err (vm, p, "%U", format_clib_error, err);
+      log_err (p, "%U", format_clib_error, err);
       clib_memset (p, 0, sizeof (linux_pci_device_t));
       pool_put (lpm->linux_pci_devices, p);
     }