FD.io VPP  v17.04-9-g99c0734
Vector Packet Processing
linux_pci.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2016 Cisco and/or its affiliates.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at:
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 /*
16  * pci.c: Linux user space PCI bus management.
17  *
18  * Copyright (c) 2008 Eliot Dresselhaus
19  *
20  * Permission is hereby granted, free of charge, to any person obtaining
21  * a copy of this software and associated documentation files (the
22  * "Software"), to deal in the Software without restriction, including
23  * without limitation the rights to use, copy, modify, merge, publish,
24  * distribute, sublicense, and/or sell copies of the Software, and to
25  * permit persons to whom the Software is furnished to do so, subject to
26  * the following conditions:
27  *
28  * The above copyright notice and this permission notice shall be
29  * included in all copies or substantial portions of the Software.
30  *
31  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
32  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
33  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
34  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
35  * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
36  * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
37  * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
38  */
39 
40 #include <vlib/vlib.h>
41 #include <vlib/pci/pci.h>
42 #include <vlib/unix/unix.h>
43 
44 #include <sys/types.h>
45 #include <sys/stat.h>
46 #include <fcntl.h>
47 #include <dirent.h>
48 #include <sys/ioctl.h>
49 #include <net/if.h>
50 #include <linux/ethtool.h>
51 #include <linux/sockios.h>
52 
53 typedef struct
54 {
55  /* /sys/bus/pci/devices/... directory name for this device. */
57 
58  /* Resource file descriptors. */
60 
61  /* File descriptor for config space read/write. */
62  int config_fd;
63 
64  /* File descriptor for /dev/uio%d */
65  int uio_fd;
66 
67  /* Minor device for uio device. */
69 
70  /* Index given by unix_file_add. */
72 
74 
75 /* Pool of PCI devices. */
76 typedef struct
77 {
81 
83 
84 /* Call to allocate/initialize the pci subsystem.
85  This is not an init function so that users can explicitly enable
86  pci only when it's needed. */
88 
90  char *uio_driver_name);
91 
93 
95 vlib_pci_bind_to_uio (vlib_pci_device_t * d, char *uio_driver_name)
96 {
97  clib_error_t *error = 0;
98  u8 *s = 0;
99  DIR *dir = 0;
100  struct dirent *e;
101  int fd;
102  u8 *dev_dir_name = format (0, "/sys/bus/pci/devices/%U",
104 
105  /* if uio sub-directory exists, we are fine, device is
106  already bound to UIO driver */
107  s = format (s, "%v/uio%c", dev_dir_name, 0);
108  if (access ((char *) s, F_OK) == 0)
109  goto done;
110  vec_reset_length (s);
111 
112  /* walk trough all linux interfaces and if interface belonging to
113  this device is founf check if interface is admin up */
114  dir = opendir ("/sys/class/net");
115  s = format (s, "%U%c", format_vlib_pci_addr, &d->bus_address, 0);
116 
117  if (!dir)
118  {
119  error = clib_error_return (0, "Skipping PCI device %U: failed to "
120  "read /sys/class/net",
122  goto done;
123  }
124 
125  fd = socket (PF_INET, SOCK_DGRAM, 0);
126  if (fd < 0)
127  {
128  error = clib_error_return_unix (0, "socket");
129  goto done;
130  }
131 
132  while ((e = readdir (dir)))
133  {
134  struct ifreq ifr;
135  struct ethtool_drvinfo drvinfo;
136 
137  if (e->d_name[0] == '.') /* skip . and .. */
138  continue;
139 
140  memset (&ifr, 0, sizeof ifr);
141  memset (&drvinfo, 0, sizeof drvinfo);
142  ifr.ifr_data = (char *) &drvinfo;
143  strncpy (ifr.ifr_name, e->d_name, IFNAMSIZ - 1);
144  drvinfo.cmd = ETHTOOL_GDRVINFO;
145  if (ioctl (fd, SIOCETHTOOL, &ifr) < 0)
146  {
147  /* Some interfaces (eg "lo") don't support this ioctl */
148  if ((errno != ENOTSUP) && (errno != ENODEV))
149  clib_unix_warning ("ioctl fetch intf %s bus info error",
150  e->d_name);
151  continue;
152  }
153 
154  if (strcmp ((char *) s, drvinfo.bus_info))
155  continue;
156 
157  memset (&ifr, 0, sizeof (ifr));
158  strncpy (ifr.ifr_name, e->d_name, IFNAMSIZ - 1);
159  if (ioctl (fd, SIOCGIFFLAGS, &ifr) < 0)
160  {
161  error = clib_error_return_unix (0, "ioctl fetch intf %s flags",
162  e->d_name);
163  close (fd);
164  goto done;
165  }
166 
167  if (ifr.ifr_flags & IFF_UP)
168  {
169  error = clib_error_return (0, "Skipping PCI device %U as host "
170  "interface %s is up",
172  e->d_name);
173  close (fd);
174  goto done;
175  }
176  }
177 
178  close (fd);
179  vec_reset_length (s);
180 
181  s = format (s, "%v/driver/unbind%c", dev_dir_name, 0);
182  vlib_sysfs_write ((char *) s, "%U", format_vlib_pci_addr, &d->bus_address);
183  vec_reset_length (s);
184 
185  s = format (s, "/sys/bus/pci/drivers/%s/new_id%c", uio_driver_name, 0);
186  vlib_sysfs_write ((char *) s, "0x%04x 0x%04x", d->vendor_id, d->device_id);
187  vec_reset_length (s);
188 
189  s = format (s, "/sys/bus/pci/drivers/%s/bind%c", uio_driver_name, 0);
190  vlib_sysfs_write ((char *) s, "%U", format_vlib_pci_addr, &d->bus_address);
191 
192 done:
193  closedir (dir);
194  vec_free (s);
195  vec_free (dev_dir_name);
196  return error;
197 }
198 
199 
200 static clib_error_t *
201 scan_uio_dir (void *arg, u8 * path_name, u8 * file_name)
202 {
203  linux_pci_device_t *l = arg;
204  unformat_input_t input;
205 
206  unformat_init_string (&input, (char *) file_name, vec_len (file_name));
207 
208  if (!unformat (&input, "uio%d", &l->uio_minor))
209  abort ();
210 
211  unformat_free (&input);
212  return 0;
213 }
214 
215 static clib_error_t *
217 {
218  vlib_pci_main_t *pm = &pci_main;
220  int __attribute__ ((unused)) rv;
221 
222  u32 icount;
223  rv = read (uf->file_descriptor, &icount, 4);
224 
225  d = pool_elt_at_index (pm->pci_devs, uf->private_data);
226 
227  if (d->interrupt_handler)
228  d->interrupt_handler (d);
229 
231 
232  return /* no error */ 0;
233 }
234 
235 static clib_error_t *
237 {
238  u32 error_index = (u32) uf->private_data;
239 
240  return clib_error_return (0, "pci device %d: error", error_index);
241 }
242 
243 static void
245 {
246  vlib_pci_main_t *pm = &pci_main;
249 
250  pool_get (lpm->linux_pci_devices, l);
251  l[0] = pdev[0];
252 
254 
255  dev->os_handle = l - lpm->linux_pci_devices;
256 
257  {
258  u8 *uio_dir = format (0, "%s/uio", l->dev_dir_name);
259  foreach_directory_file ((char *) uio_dir, scan_uio_dir, l, /* scan_dirs */
260  1);
261  vec_free (uio_dir);
262  }
263 
264  {
265  char *uio_name = (char *) format (0, "/dev/uio%d%c", l->uio_minor, 0);
266  l->uio_fd = open (uio_name, O_RDWR);
267  if (l->uio_fd < 0)
268  clib_unix_error ("open `%s'", uio_name);
269  vec_free (uio_name);
270  }
271 
272  {
273  unix_file_t template = { 0 };
274  unix_main_t *um = &unix_main;
275 
276  template.read_function = linux_pci_uio_read_ready;
277  template.file_descriptor = l->uio_fd;
278  template.error_function = linux_pci_uio_error_ready;
279  template.private_data = dev - pm->pci_devs;
280 
281  l->unix_file_index = unix_file_add (um, &template);
282  }
283 }
284 
285 static void
287 {
288  int i;
289  for (i = 0; i < vec_len (l->resource_fds); i++)
290  if (l->resource_fds[i] > 0)
291  close (l->resource_fds[i]);
292  if (l->config_fd > 0)
293  close (l->config_fd);
294  if (l->uio_fd > 0)
295  close (l->uio_fd);
296  vec_free (l->resource_fds);
297  vec_free (l->dev_dir_name);
298 }
299 
300 /* Configuration space read/write. */
301 clib_error_t *
303  vlib_read_or_write_t read_or_write,
304  uword address, void *data, u32 n_bytes)
305 {
308  int n;
309 
311 
312  if (read_or_write == VLIB_READ)
313  n = pread (p->config_fd, data, n_bytes, address);
314  else
315  n = pwrite (p->config_fd, data, n_bytes, address);
316 
317  if (n != n_bytes)
318  return clib_error_return_unix (0, "%s",
319  read_or_write == VLIB_READ
320  ? "read" : "write");
321 
322  return 0;
323 }
324 
325 static clib_error_t *
327  u32 resource, u8 * addr, void **result)
328 {
331  struct stat stat_buf;
332  u8 *file_name;
333  int fd;
334  clib_error_t *error;
335  int flags = MAP_SHARED;
336 
337  error = 0;
338  p = pool_elt_at_index (pm->linux_pci_devices, os_handle);
339 
340  file_name = format (0, "%v/resource%d%c", p->dev_dir_name, resource, 0);
341  fd = open ((char *) file_name, O_RDWR);
342  if (fd < 0)
343  {
344  error = clib_error_return_unix (0, "open `%s'", file_name);
345  goto done;
346  }
347 
348  if (fstat (fd, &stat_buf) < 0)
349  {
350  error = clib_error_return_unix (0, "fstat `%s'", file_name);
351  goto done;
352  }
353 
354  vec_validate (p->resource_fds, resource);
355  p->resource_fds[resource] = fd;
356  if (addr != 0)
357  flags |= MAP_FIXED;
358 
359  *result = mmap (addr,
360  /* size */ stat_buf.st_size,
361  PROT_READ | PROT_WRITE, flags,
362  /* file */ fd,
363  /* offset */ 0);
364  if (*result == (void *) -1)
365  {
366  error = clib_error_return_unix (0, "mmap `%s'", file_name);
367  goto done;
368  }
369 
370 done:
371  if (error)
372  {
373  if (fd >= 0)
374  close (fd);
375  }
376  vec_free (file_name);
377  return error;
378 }
379 
380 clib_error_t *
381 vlib_pci_map_resource (vlib_pci_device_t * dev, u32 resource, void **result)
382 {
384  (dev->os_handle, resource, 0 /* addr */ ,
385  result));
386 }
387 
388 clib_error_t *
390  u32 resource, u8 * addr, void **result)
391 {
393  (dev->os_handle, resource, addr, result));
394 }
395 
396 void
398 {
401 
404  pool_put (pm->linux_pci_devices, l);
405 }
406 
407 pci_device_registration_t * __attribute__ ((unused))
409 {
410  uword i;
411 
412  /* Null vendor id marks end of initialized list. */
413  for (i = 0; r->supported_devices[i].vendor_id != 0; i++)
414  ;
415 
416  return clib_elf_section_data_next (r, i * sizeof (r->supported_devices[0]));
417 }
418 
419 static clib_error_t *
421  vlib_pci_device_t * dev,
422  linux_pci_device_t * pdev)
423 {
424  vlib_pci_main_t *pm = &pci_main;
427  clib_error_t *error;
428 
429  r = pm->pci_device_registrations;
430 
431  while (r)
432  {
433  for (i = r->supported_devices; i->vendor_id != 0; i++)
434  if (i->vendor_id == dev->vendor_id && i->device_id == dev->device_id)
435  {
436  error = vlib_pci_bind_to_uio (dev, "uio_pci_generic");
437  if (error)
438  {
439  clib_error_report (error);
440  continue;
441  }
442 
443  add_device (dev, pdev);
444  dev->interrupt_handler = r->interrupt_handler;
445  return r->init_function (vm, dev);
446  }
447  r = r->next_registration;
448  }
449  /* No driver, close the PCI config-space FD */
450  close (pdev->config_fd);
451  return 0;
452 }
453 
454 static clib_error_t *
457 {
458  return init_device_from_registered (vm, dev, pdev);
459 }
460 
461 static clib_error_t *
462 scan_device (void *arg, u8 * dev_dir_name, u8 * ignored)
463 {
464  vlib_main_t *vm = arg;
465  vlib_pci_main_t *pm = &pci_main;
466  int fd;
467  u8 *f;
468  clib_error_t *error = 0;
469  vlib_pci_device_t *dev;
470  linux_pci_device_t pdev = { 0 };
471  u32 tmp;
472 
473  f = format (0, "%v/config%c", dev_dir_name, 0);
474  fd = open ((char *) f, O_RDWR);
475 
476  /* Try read-only access if write fails. */
477  if (fd < 0)
478  fd = open ((char *) f, O_RDONLY);
479 
480  if (fd < 0)
481  {
482  error = clib_error_return_unix (0, "open `%s'", f);
483  goto done;
484  }
485 
486  pool_get (pm->pci_devs, dev);
487 
488  /* You can only read more that 64 bytes of config space as root; so we try to
489  read the full space but fall back to just the first 64 bytes. */
490  if (read (fd, &dev->config_data, sizeof (dev->config_data)) !=
491  sizeof (dev->config_data)
492  && read (fd, &dev->config0,
493  sizeof (dev->config0)) != sizeof (dev->config0))
494  {
495  pool_put (pm->pci_devs, dev);
496  error = clib_error_return_unix (0, "read `%s'", f);
497  close (fd);
498  goto done;
499  }
500 
501  {
502  static pci_config_header_t all_ones;
503  if (all_ones.vendor_id == 0)
504  memset (&all_ones, ~0, sizeof (all_ones));
505 
506  if (!memcmp (&dev->config0.header, &all_ones, sizeof (all_ones)))
507  {
508  pool_put (pm->pci_devs, dev);
509  error = clib_error_return (0, "invalid PCI config for `%s'", f);
510  close (fd);
511  goto done;
512  }
513  }
514 
515  if (dev->config0.header.header_type == 0)
517  else
519 
520  /* Parse bus, dev, function from directory name. */
521  {
522  unformat_input_t input;
523 
524  unformat_init_string (&input, (char *) dev_dir_name,
525  vec_len (dev_dir_name));
526 
527  if (!unformat (&input, "/sys/bus/pci/devices/%U",
529  abort ();
530 
531  unformat_free (&input);
532 
533  }
534 
535 
536  pdev.config_fd = fd;
537  pdev.dev_dir_name = dev_dir_name;
538 
540  dev - pm->pci_devs);
541 
542  error = init_device (vm, dev, &pdev);
543 
544  vec_reset_length (f);
545  f = format (f, "%v/vpd%c", dev_dir_name, 0);
546  fd = open ((char *) f, O_RDONLY);
547  if (fd >= 0)
548  {
549  while (1)
550  {
551  u8 tag[3];
552  u8 *data = 0;
553  int len;
554 
555  if (read (fd, &tag, 3) != 3)
556  break;
557 
558  if (tag[0] != 0x82 && tag[0] != 0x90 && tag[0] != 0x91)
559  break;
560 
561  len = (tag[2] << 8) | tag[1];
562  vec_validate (data, len);
563 
564  if (read (fd, data, len) != len)
565  {
566  vec_free (data);
567  break;
568  }
569  if (tag[0] == 0x82)
570  dev->product_name = data;
571  else if (tag[0] == 0x90)
572  dev->vpd_r = data;
573  else if (tag[0] == 0x91)
574  dev->vpd_w = data;
575 
576  data = 0;
577  }
578  close (fd);
579  }
580 
581  vec_reset_length (f);
582  f = format (f, "%v/driver%c", dev_dir_name, 0);
583  dev->driver_name = vlib_sysfs_link_to_name ((char *) f);
584 
585  dev->numa_node = -1;
586  vec_reset_length (f);
587  f = format (f, "%v/numa_node%c", dev_dir_name, 0);
588  vlib_sysfs_read ((char *) f, "%u", &dev->numa_node);
589 
590  vec_reset_length (f);
591  f = format (f, "%v/class%c", dev_dir_name, 0);
592  vlib_sysfs_read ((char *) f, "0x%x", &tmp);
593  dev->device_class = tmp >> 8;
594 
595  vec_reset_length (f);
596  f = format (f, "%v/vendor%c", dev_dir_name, 0);
597  vlib_sysfs_read ((char *) f, "0x%x", &tmp);
598  dev->vendor_id = tmp;
599 
600  vec_reset_length (f);
601  f = format (f, "%v/device%c", dev_dir_name, 0);
602  vlib_sysfs_read ((char *) f, "0x%x", &tmp);
603  dev->device_id = tmp;
604 
605 done:
606  vec_free (f);
607  return error;
608 }
609 
610 clib_error_t *
612 {
613  vlib_pci_main_t *pm = &pci_main;
614  clib_error_t *error;
615 
616  pm->vlib_main = vm;
617 
618  if ((error = vlib_call_init_function (vm, unix_input_init)))
619  return error;
620 
621  ASSERT (sizeof (vlib_pci_addr_t) == sizeof (u32));
622  pm->pci_dev_index_by_pci_addr = hash_create (0, sizeof (uword));
623 
624  error = foreach_directory_file ("/sys/bus/pci/devices", scan_device, vm,
625  /* scan_dirs */ 0);
626 
627  /* Complain and continue. might not be root, etc. */
628  if (error)
629  clib_error_report (error);
630 
631  return error;
632 }
633 
635 
636 /*
637  * fd.io coding-style-patch-verification: ON
638  *
639  * Local Variables:
640  * eval: (c-set-style "gnu")
641  * End:
642  */
#define vec_validate(V, I)
Make sure vector is long enough for given index (no header, unspecified alignment) ...
Definition: vec.h:436
u8 * vpd_w
Definition: pci.h:85
static clib_error_t * os_map_pci_resource_internal(uword os_handle, u32 resource, u8 *addr, void **result)
Definition: linux_pci.c:326
format_function_t format_vlib_pci_addr
Definition: pci.h:238
#define hash_set(h, key, value)
Definition: hash.h:254
sll srl srl sll sra u16x4 i
Definition: vector_sse2.h:343
static clib_error_t * unix_input_init(vlib_main_t *vm)
Definition: input.c:269
static void linux_pci_device_free(linux_pci_device_t *l)
Definition: linux_pci.c:286
static clib_error_t * init_device(vlib_main_t *vm, vlib_pci_device_t *dev, linux_pci_device_t *pdev)
Definition: linux_pci.c:455
pci_config_type1_regs_t config1
Definition: pci.h:64
pci_device_registration_t * pci_device_registrations
Definition: pci.h:117
vlib_read_or_write_t
Definition: defs.h:54
unix_main_t unix_main
Definition: main.c:59
clib_error_t * vlib_pci_bind_to_uio(vlib_pci_device_t *d, char *uio_driver_name)
Definition: linux_pci.c:95
u8 * format(u8 *s, const char *fmt,...)
Definition: format.c:418
unformat_function_t unformat_vlib_pci_addr
Definition: pci.h:237
static void add_device(vlib_pci_device_t *dev, linux_pci_device_t *pdev)
Definition: linux_pci.c:244
u16 device_id
Definition: pci.h:80
u8 * vlib_sysfs_link_to_name(char *link)
Definition: util.c:166
#define pool_get(P, E)
Allocate an object E from a pool P (unspecified alignment).
Definition: pool.h:200
vlib_pci_addr_t bus_address
Definition: pci.h:58
int numa_node
Definition: pci.h:75
#define vec_reset_length(v)
Reset vector length to zero NULL-pointer tolerant.
#define clib_unix_error(format, args...)
Definition: error.h:65
u8 * product_name
Definition: pci.h:83
static void pci_config_type1_little_to_host(pci_config_type1_regs_t *r)
Definition: pci_config.h:346
#define VLIB_INIT_FUNCTION(x)
Definition: init.h:111
uword * pci_dev_index_by_pci_addr
Definition: pci.h:118
clib_error_t * vlib_pci_map_resource_fixed(vlib_pci_device_t *dev, u32 resource, u8 *addr, void **result)
Definition: linux_pci.c:389
#define clib_error_return(e, args...)
Definition: error.h:111
struct _pci_device_registration pci_device_registration_t
clib_error_t * vlib_pci_read_write_config(vlib_pci_device_t *dev, vlib_read_or_write_t read_or_write, uword address, void *data, u32 n_bytes)
Definition: linux_pci.c:302
vlib_main_t * vlib_main
Definition: linux_pci.c:78
static clib_error_t * init_device_from_registered(vlib_main_t *vm, vlib_pci_device_t *dev, linux_pci_device_t *pdev)
Definition: linux_pci.c:420
u16 vendor_id
Definition: pci.h:79
#define vlib_call_init_function(vm, x)
Definition: init.h:162
static clib_error_t * linux_pci_uio_read_ready(unix_file_t *uf)
Definition: linux_pci.c:216
void unformat_init_string(unformat_input_t *input, char *string, int string_len)
Definition: unformat.c:1022
u16 device_class
Definition: pci.h:78
static uword unix_file_add(unix_main_t *um, unix_file_t *template)
Definition: unix.h:136
#define pool_elt_at_index(p, i)
Returns pointer to element at given index.
Definition: pool.h:397
u32 file_descriptor
Definition: unix.h:52
uword private_data
Definition: unix.h:59
clib_error_t * vlib_sysfs_read(char *file_name, char *fmt,...)
Definition: util.c:126
vlib_pci_device_t * pci_devs
Definition: pci.h:116
struct _unformat_input_t unformat_input_t
#define clib_error_return_unix(e, args...)
Definition: error.h:114
#define pool_put(P, E)
Free an object E in pool P.
Definition: pool.h:241
#define vec_dup(V)
Return copy of vector (no header, no alignment)
Definition: vec.h:374
void(* interrupt_handler)(struct vlib_pci_device *dev)
Definition: pci.h:69
static clib_error_t * vlib_pci_intr_enable(vlib_pci_device_t *dev)
Definition: pci.h:175
clib_error_t * linux_pci_init(vlib_main_t *vm)
Definition: linux_pci.c:611
void vlib_pci_free_device(vlib_pci_device_t *dev)
Definition: linux_pci.c:397
static void pci_config_type0_little_to_host(pci_config_type0_regs_t *r)
Definition: pci_config.h:272
vlib_main_t * vm
Definition: buffer.c:276
vlib_pci_main_t pci_main
Definition: pci.c:53
#define vec_free(V)
Free vector&#39;s memory (no header).
Definition: vec.h:340
u8 config_data[256]
Definition: pci.h:65
pci_config_type0_regs_t config0
Definition: pci.h:63
#define hash_create(elts, value_bytes)
Definition: hash.h:658
#define clib_elf_section_data_next(a, extra)
Definition: elf_clib.h:57
#define ASSERT(truth)
unsigned int u32
Definition: types.h:88
static clib_error_t * scan_device(void *arg, u8 *dev_dir_name, u8 *ignored)
Definition: linux_pci.c:462
clib_error_t * pci_bus_init(vlib_main_t *vm)
Definition: pci.c:251
static clib_error_t * scan_uio_dir(void *arg, u8 *path_name, u8 *file_name)
Definition: linux_pci.c:201
#define clib_error_report(e)
Definition: error.h:125
clib_error_t * vlib_pci_map_resource(vlib_pci_device_t *dev, u32 resource, void **result)
Definition: linux_pci.c:381
u64 uword
Definition: types.h:112
Definition: defs.h:56
linux_pci_main_t linux_pci_main
Definition: linux_pci.c:92
clib_error_t * foreach_directory_file(char *dir_name, clib_error_t *(*f)(void *arg, u8 *path_name, u8 *file_name), void *arg, int scan_dirs)
Definition: util.c:49
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
unsigned char u8
Definition: types.h:56
static void unformat_free(unformat_input_t *i)
Definition: format.h:161
#define clib_unix_warning(format, args...)
Definition: error.h:68
Definition: unix.h:49
pci_device_registration_t * pci_device_next_registered(pci_device_registration_t *r)
Definition: linux_pci.c:408
clib_error_t * vlib_sysfs_write(char *file_name, char *fmt,...)
Definition: util.c:102
u16 device_id
Definition: pci.h:94
static clib_error_t * linux_pci_uio_error_ready(unix_file_t *uf)
Definition: linux_pci.c:236
uword os_handle
Definition: pci.h:56
vhost_vring_addr_t addr
Definition: vhost-user.h:84
u32 flags
Definition: vhost-user.h:78
u8 * vpd_r
Definition: pci.h:84
linux_pci_device_t * linux_pci_devices
Definition: linux_pci.c:79
vlib_main_t * vlib_main
Definition: pci.h:115
u8 * driver_name
Definition: pci.h:72
pci_config_header_t header
Definition: pci_config.h:240
u16 vendor_id
Definition: pci.h:94
uword unformat(unformat_input_t *i, const char *fmt,...)
Definition: unformat.c:971