pci: remove unnecessary ioctl() call and improve logging in vfio_set_irqs

Type: improvement
Change-Id: Ic8e2785bf375882defe5a1d299948d522cdd4895
Signed-off-by: Damjan Marion <damarion@cisco.com>
diff --git a/src/vlib/linux/pci.c b/src/vlib/linux/pci.c
index 62db820..0435d56 100644
--- a/src/vlib/linux/pci.c
+++ b/src/vlib/linux/pci.c
@@ -648,33 +648,14 @@
 {
   int data_len = efds ? count * sizeof (int) : 0;
   u8 buf[sizeof (struct vfio_irq_set) + data_len];
-  struct vfio_irq_info ii = { 0 };
   struct vfio_irq_set *irq_set = (struct vfio_irq_set *) buf;
 
-
-  ii.argsz = sizeof (struct vfio_irq_info);
-  ii.index = index;
-
-  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);
-
-  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 "
-				   "'%U'", format_vlib_pci_addr, &p->addr);
-
-
   if (efds)
     {
+      int *data = (int *) irq_set->data;
       flags |= VFIO_IRQ_SET_DATA_EVENTFD;
-      clib_memcpy_fast (&irq_set->data, efds, data_len);
+      for (u32 i = 0; i < count; i++)
+	data[i] = efds[i];
     }
   else
     flags |= VFIO_IRQ_SET_DATA_NONE;
@@ -689,11 +670,11 @@
   irq_set->flags = flags;
 
   if (ioctl (p->fd, VFIO_DEVICE_SET_IRQS, irq_set) < 0)
-    return clib_error_return_unix (0, "%U:ioctl(VFIO_DEVICE_SET_IRQS) "
-				   "[index = %u, start = %u, count = %u, "
-				   "flags = 0x%x]",
+    return clib_error_return_unix (0, "%U:ioctl(VFIO_DEVICE_SET_IRQS)\n%U",
 				   format_vlib_pci_addr, &p->addr,
-				   index, start, count, flags);
+				   format_vfio_irq_set, irq_set);
+
+  log_debug (p, "%s:\n%U", __func__, format_vfio_irq_set, irq_set);
   return 0;
 }
 
diff --git a/src/vlib/linux/vfio.c b/src/vlib/linux/vfio.c
index ee04081..1462cc6 100644
--- a/src/vlib/linux/vfio.c
+++ b/src/vlib/linux/vfio.c
@@ -301,10 +301,44 @@
   return s;
 }
 
-/*
- * fd.io coding-style-patch-verification: ON
- *
- * Local Variables:
- * eval: (c-set-style "gnu")
- * End:
- */
+u8 *
+format_vfio_irq_set (u8 *s, va_list *args)
+{
+  struct vfio_irq_set *is = va_arg (*args, struct vfio_irq_set *);
+  u32 indent = format_get_indent (s);
+
+  s = format (s, "index:%u start:%u count:%u flags: 0x%x", is->index,
+	      is->start, is->count, is->flags);
+
+  s = format (s, " (data:");
+  if (is->flags & VFIO_IRQ_SET_DATA_NONE)
+    s = format (s, " none");
+  if (is->flags & VFIO_IRQ_SET_DATA_BOOL)
+    s = format (s, " bool");
+  if (is->flags & VFIO_IRQ_SET_DATA_EVENTFD)
+    s = format (s, " eventfd");
+
+  s = format (s, ", action:");
+  if (is->flags & VFIO_IRQ_SET_ACTION_MASK)
+    s = format (s, " mask");
+  if (is->flags & VFIO_IRQ_SET_ACTION_UNMASK)
+    s = format (s, " unmask");
+  if (is->flags & VFIO_IRQ_SET_ACTION_TRIGGER)
+    s = format (s, " trigger");
+  vec_add1 (s, ')');
+
+  if (is->flags & VFIO_IRQ_SET_DATA_EVENTFD)
+    {
+      s = format (s, "\n%U  eventfd data:", format_white_space, indent);
+      for (u32 i = 0; i < is->count; i++)
+	s = format (s, " %d", ((int *) (is->data))[i]);
+    }
+  if (is->flags & VFIO_IRQ_SET_DATA_BOOL)
+    {
+      s = format (s, "\n%U  bool data:", format_white_space, indent);
+      for (u32 i = 0; i < is->count; i++)
+	s = format (s, " %u", is->data);
+    }
+
+  return s;
+}
diff --git a/src/vlib/linux/vfio.h b/src/vlib/linux/vfio.h
index fe4f0f7..c2bb2e9 100644
--- a/src/vlib/linux/vfio.h
+++ b/src/vlib/linux/vfio.h
@@ -50,7 +50,7 @@
 					      int *fd, int *is_noiommu);
 
 format_function_t format_vfio_region_info;
-
+format_function_t format_vfio_irq_set;
 
 #endif /* included_vlib_linux_vfio_h */