FD.io VPP  v17.07-30-g839fa73
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, *driver_name = 0;
99  DIR *dir = 0;
100  struct dirent *e;
101  int fd, clear_driver_override = 0;
102  u8 *dev_dir_name = format (0, "/sys/bus/pci/devices/%U",
104 
105  s = format (s, "%v/driver%c", dev_dir_name, 0);
106  driver_name = vlib_sysfs_link_to_name ((char *) s);
107  vec_reset_length (s);
108 
109  if (driver_name &&
110  ((strcmp ("vfio-pci", (char *) driver_name) == 0) ||
111  (strcmp ("uio_pci_generic", (char *) driver_name) == 0) ||
112  (strcmp ("igb_uio", (char *) driver_name) == 0)))
113  goto done;
114 
115  /* walk trough all linux interfaces and if interface belonging to
116  this device is founf check if interface is admin up */
117  dir = opendir ("/sys/class/net");
118  s = format (s, "%U%c", format_vlib_pci_addr, &d->bus_address, 0);
119 
120  if (!dir)
121  {
122  error = clib_error_return (0, "Skipping PCI device %U: failed to "
123  "read /sys/class/net",
125  goto done;
126  }
127 
128  fd = socket (PF_INET, SOCK_DGRAM, 0);
129  if (fd < 0)
130  {
131  error = clib_error_return_unix (0, "socket");
132  goto done;
133  }
134 
135  while ((e = readdir (dir)))
136  {
137  struct ifreq ifr;
138  struct ethtool_drvinfo drvinfo;
139 
140  if (e->d_name[0] == '.') /* skip . and .. */
141  continue;
142 
143  memset (&ifr, 0, sizeof ifr);
144  memset (&drvinfo, 0, sizeof drvinfo);
145  ifr.ifr_data = (char *) &drvinfo;
146  strncpy (ifr.ifr_name, e->d_name, IFNAMSIZ - 1);
147  drvinfo.cmd = ETHTOOL_GDRVINFO;
148  if (ioctl (fd, SIOCETHTOOL, &ifr) < 0)
149  {
150  /* Some interfaces (eg "lo") don't support this ioctl */
151  if ((errno != ENOTSUP) && (errno != ENODEV))
152  clib_unix_warning ("ioctl fetch intf %s bus info error",
153  e->d_name);
154  continue;
155  }
156 
157  if (strcmp ((char *) s, drvinfo.bus_info))
158  continue;
159 
160  memset (&ifr, 0, sizeof (ifr));
161  strncpy (ifr.ifr_name, e->d_name, IFNAMSIZ - 1);
162  if (ioctl (fd, SIOCGIFFLAGS, &ifr) < 0)
163  {
164  error = clib_error_return_unix (0, "ioctl fetch intf %s flags",
165  e->d_name);
166  close (fd);
167  goto done;
168  }
169 
170  if (ifr.ifr_flags & IFF_UP)
171  {
172  error = clib_error_return (0, "Skipping PCI device %U as host "
173  "interface %s is up",
175  e->d_name);
176  close (fd);
177  goto done;
178  }
179  }
180 
181  close (fd);
182  vec_reset_length (s);
183 
184  s = format (s, "%v/driver/unbind%c", dev_dir_name, 0);
185  vlib_sysfs_write ((char *) s, "%U", format_vlib_pci_addr, &d->bus_address);
186  vec_reset_length (s);
187 
188  s = format (s, "%v/driver_override%c", dev_dir_name, 0);
189  if (access ((char *) s, F_OK) == 0)
190  {
191  vlib_sysfs_write ((char *) s, "%s", uio_driver_name);
192  clear_driver_override = 1;
193  }
194  else
195  {
196  vec_reset_length (s);
197  s = format (s, "/sys/bus/pci/drivers/%s/new_id%c", uio_driver_name, 0);
198  vlib_sysfs_write ((char *) s, "0x%04x 0x%04x", d->vendor_id,
199  d->device_id);
200  }
201  vec_reset_length (s);
202 
203  s = format (s, "/sys/bus/pci/drivers/%s/bind%c", uio_driver_name, 0);
204  vlib_sysfs_write ((char *) s, "%U", format_vlib_pci_addr, &d->bus_address);
205  vec_reset_length (s);
206 
207  if (clear_driver_override)
208  {
209  s = format (s, "%v/driver_override%c", dev_dir_name, 0);
210  vlib_sysfs_write ((char *) s, "%c", 0);
211  vec_reset_length (s);
212  }
213 
214 done:
215  closedir (dir);
216  vec_free (s);
217  vec_free (dev_dir_name);
218  vec_free (driver_name);
219  return error;
220 }
221 
222 
223 static clib_error_t *
224 scan_uio_dir (void *arg, u8 * path_name, u8 * file_name)
225 {
226  linux_pci_device_t *l = arg;
227  unformat_input_t input;
228 
229  unformat_init_string (&input, (char *) file_name, vec_len (file_name));
230 
231  if (!unformat (&input, "uio%d", &l->uio_minor))
232  abort ();
233 
234  unformat_free (&input);
235  return 0;
236 }
237 
238 static clib_error_t *
240 {
241  vlib_pci_main_t *pm = &pci_main;
243  int __attribute__ ((unused)) rv;
244 
245  u32 icount;
246  rv = read (uf->file_descriptor, &icount, 4);
247 
248  d = pool_elt_at_index (pm->pci_devs, uf->private_data);
249 
250  if (d->interrupt_handler)
251  d->interrupt_handler (d);
252 
254 
255  return /* no error */ 0;
256 }
257 
258 static clib_error_t *
260 {
261  u32 error_index = (u32) uf->private_data;
262 
263  return clib_error_return (0, "pci device %d: error", error_index);
264 }
265 
266 static void
268 {
269  vlib_pci_main_t *pm = &pci_main;
272 
273  pool_get (lpm->linux_pci_devices, l);
274  l[0] = pdev[0];
275 
277 
278  dev->os_handle = l - lpm->linux_pci_devices;
279 
280  {
281  u8 *uio_dir = format (0, "%s/uio", l->dev_dir_name);
282  foreach_directory_file ((char *) uio_dir, scan_uio_dir, l, /* scan_dirs */
283  1);
284  vec_free (uio_dir);
285  }
286 
287  {
288  char *uio_name = (char *) format (0, "/dev/uio%d%c", l->uio_minor, 0);
289  l->uio_fd = open (uio_name, O_RDWR);
290  if (l->uio_fd < 0)
291  clib_unix_error ("open `%s'", uio_name);
292  vec_free (uio_name);
293  }
294 
295  {
296  unix_file_t template = { 0 };
297  unix_main_t *um = &unix_main;
298 
299  template.read_function = linux_pci_uio_read_ready;
300  template.file_descriptor = l->uio_fd;
301  template.error_function = linux_pci_uio_error_ready;
302  template.private_data = dev - pm->pci_devs;
303 
304  l->unix_file_index = unix_file_add (um, &template);
305  }
306 }
307 
308 static void
310 {
311  int i;
312  for (i = 0; i < vec_len (l->resource_fds); i++)
313  if (l->resource_fds[i] > 0)
314  close (l->resource_fds[i]);
315  if (l->config_fd > 0)
316  close (l->config_fd);
317  if (l->uio_fd > 0)
318  close (l->uio_fd);
319  vec_free (l->resource_fds);
320  vec_free (l->dev_dir_name);
321 }
322 
323 /* Configuration space read/write. */
324 clib_error_t *
326  vlib_read_or_write_t read_or_write,
327  uword address, void *data, u32 n_bytes)
328 {
331  int n;
332 
334 
335  if (read_or_write == VLIB_READ)
336  n = pread (p->config_fd, data, n_bytes, address);
337  else
338  n = pwrite (p->config_fd, data, n_bytes, address);
339 
340  if (n != n_bytes)
341  return clib_error_return_unix (0, "%s",
342  read_or_write == VLIB_READ
343  ? "read" : "write");
344 
345  return 0;
346 }
347 
348 static clib_error_t *
350  u32 resource, u8 * addr, void **result)
351 {
354  struct stat stat_buf;
355  u8 *file_name;
356  int fd;
357  clib_error_t *error;
358  int flags = MAP_SHARED;
359 
360  error = 0;
361  p = pool_elt_at_index (pm->linux_pci_devices, os_handle);
362 
363  file_name = format (0, "%v/resource%d%c", p->dev_dir_name, resource, 0);
364  fd = open ((char *) file_name, O_RDWR);
365  if (fd < 0)
366  {
367  error = clib_error_return_unix (0, "open `%s'", file_name);
368  goto done;
369  }
370 
371  if (fstat (fd, &stat_buf) < 0)
372  {
373  error = clib_error_return_unix (0, "fstat `%s'", file_name);
374  goto done;
375  }
376 
377  vec_validate (p->resource_fds, resource);
378  p->resource_fds[resource] = fd;
379  if (addr != 0)
380  flags |= MAP_FIXED;
381 
382  *result = mmap (addr,
383  /* size */ stat_buf.st_size,
384  PROT_READ | PROT_WRITE, flags,
385  /* file */ fd,
386  /* offset */ 0);
387  if (*result == (void *) -1)
388  {
389  error = clib_error_return_unix (0, "mmap `%s'", file_name);
390  goto done;
391  }
392 
393 done:
394  if (error)
395  {
396  if (fd >= 0)
397  close (fd);
398  }
399  vec_free (file_name);
400  return error;
401 }
402 
403 clib_error_t *
404 vlib_pci_map_resource (vlib_pci_device_t * dev, u32 resource, void **result)
405 {
407  (dev->os_handle, resource, 0 /* addr */ ,
408  result));
409 }
410 
411 clib_error_t *
413  u32 resource, u8 * addr, void **result)
414 {
416  (dev->os_handle, resource, addr, result));
417 }
418 
419 void
421 {
424 
427  pool_put (pm->linux_pci_devices, l);
428 }
429 
430 pci_device_registration_t * __attribute__ ((unused))
432 {
433  uword i;
434 
435  /* Null vendor id marks end of initialized list. */
436  for (i = 0; r->supported_devices[i].vendor_id != 0; i++)
437  ;
438 
439  return clib_elf_section_data_next (r, i * sizeof (r->supported_devices[0]));
440 }
441 
442 static clib_error_t *
444  vlib_pci_device_t * dev,
445  linux_pci_device_t * pdev)
446 {
447  vlib_pci_main_t *pm = &pci_main;
450  clib_error_t *error;
451 
452  r = pm->pci_device_registrations;
453 
454  while (r)
455  {
456  for (i = r->supported_devices; i->vendor_id != 0; i++)
457  if (i->vendor_id == dev->vendor_id && i->device_id == dev->device_id)
458  {
459  error = vlib_pci_bind_to_uio (dev, "uio_pci_generic");
460  if (error)
461  {
462  clib_error_report (error);
463  continue;
464  }
465 
466  add_device (dev, pdev);
467  dev->interrupt_handler = r->interrupt_handler;
468  return r->init_function (vm, dev);
469  }
470  r = r->next_registration;
471  }
472  /* No driver, close the PCI config-space FD */
473  close (pdev->config_fd);
474  return 0;
475 }
476 
477 static clib_error_t *
480 {
481  return init_device_from_registered (vm, dev, pdev);
482 }
483 
484 static clib_error_t *
485 scan_device (void *arg, u8 * dev_dir_name, u8 * ignored)
486 {
487  vlib_main_t *vm = arg;
488  vlib_pci_main_t *pm = &pci_main;
489  int fd;
490  u8 *f;
491  clib_error_t *error = 0;
492  vlib_pci_device_t *dev;
493  linux_pci_device_t pdev = { 0 };
494  u32 tmp;
495 
496  f = format (0, "%v/config%c", dev_dir_name, 0);
497  fd = open ((char *) f, O_RDWR);
498 
499  /* Try read-only access if write fails. */
500  if (fd < 0)
501  fd = open ((char *) f, O_RDONLY);
502 
503  if (fd < 0)
504  {
505  error = clib_error_return_unix (0, "open `%s'", f);
506  goto done;
507  }
508 
509  pool_get (pm->pci_devs, dev);
510 
511  /* You can only read more that 64 bytes of config space as root; so we try to
512  read the full space but fall back to just the first 64 bytes. */
513  if (read (fd, &dev->config_data, sizeof (dev->config_data)) !=
514  sizeof (dev->config_data)
515  && read (fd, &dev->config0,
516  sizeof (dev->config0)) != sizeof (dev->config0))
517  {
518  pool_put (pm->pci_devs, dev);
519  error = clib_error_return_unix (0, "read `%s'", f);
520  close (fd);
521  goto done;
522  }
523 
524  {
525  static pci_config_header_t all_ones;
526  if (all_ones.vendor_id == 0)
527  memset (&all_ones, ~0, sizeof (all_ones));
528 
529  if (!memcmp (&dev->config0.header, &all_ones, sizeof (all_ones)))
530  {
531  pool_put (pm->pci_devs, dev);
532  error = clib_error_return (0, "invalid PCI config for `%s'", f);
533  close (fd);
534  goto done;
535  }
536  }
537 
538  if (dev->config0.header.header_type == 0)
540  else
542 
543  /* Parse bus, dev, function from directory name. */
544  {
545  unformat_input_t input;
546 
547  unformat_init_string (&input, (char *) dev_dir_name,
548  vec_len (dev_dir_name));
549 
550  if (!unformat (&input, "/sys/bus/pci/devices/%U",
552  abort ();
553 
554  unformat_free (&input);
555 
556  }
557 
558 
559  pdev.config_fd = fd;
560  pdev.dev_dir_name = dev_dir_name;
561 
563  dev - pm->pci_devs);
564 
565  vec_reset_length (f);
566  f = format (f, "%v/vpd%c", dev_dir_name, 0);
567  fd = open ((char *) f, O_RDONLY);
568  if (fd >= 0)
569  {
570  while (1)
571  {
572  u8 tag[3];
573  u8 *data = 0;
574  int len;
575 
576  if (read (fd, &tag, 3) != 3)
577  break;
578 
579  if (tag[0] != 0x82 && tag[0] != 0x90 && tag[0] != 0x91)
580  break;
581 
582  len = (tag[2] << 8) | tag[1];
583  vec_validate (data, len);
584 
585  if (read (fd, data, len) != len)
586  {
587  vec_free (data);
588  break;
589  }
590  if (tag[0] == 0x82)
591  dev->product_name = data;
592  else if (tag[0] == 0x90)
593  dev->vpd_r = data;
594  else if (tag[0] == 0x91)
595  dev->vpd_w = data;
596 
597  data = 0;
598  }
599  close (fd);
600  }
601 
602  dev->numa_node = -1;
603  vec_reset_length (f);
604  f = format (f, "%v/numa_node%c", dev_dir_name, 0);
605  vlib_sysfs_read ((char *) f, "%u", &dev->numa_node);
606 
607  vec_reset_length (f);
608  f = format (f, "%v/class%c", dev_dir_name, 0);
609  vlib_sysfs_read ((char *) f, "0x%x", &tmp);
610  dev->device_class = tmp >> 8;
611 
612  vec_reset_length (f);
613  f = format (f, "%v/vendor%c", dev_dir_name, 0);
614  vlib_sysfs_read ((char *) f, "0x%x", &tmp);
615  dev->vendor_id = tmp;
616 
617  vec_reset_length (f);
618  f = format (f, "%v/device%c", dev_dir_name, 0);
619  vlib_sysfs_read ((char *) f, "0x%x", &tmp);
620  dev->device_id = tmp;
621 
622  error = init_device (vm, dev, &pdev);
623 
624  vec_reset_length (f);
625  f = format (f, "%v/driver%c", dev_dir_name, 0);
626  dev->driver_name = vlib_sysfs_link_to_name ((char *) f);
627 
628 done:
629  vec_free (f);
630  return error;
631 }
632 
633 clib_error_t *
635 {
636  vlib_pci_main_t *pm = &pci_main;
637  clib_error_t *error;
638 
639  pm->vlib_main = vm;
640 
641  if ((error = vlib_call_init_function (vm, unix_input_init)))
642  return error;
643 
644  ASSERT (sizeof (vlib_pci_addr_t) == sizeof (u32));
645  pm->pci_dev_index_by_pci_addr = hash_create (0, sizeof (uword));
646 
647  error = foreach_directory_file ("/sys/bus/pci/devices", scan_device, vm,
648  /* scan_dirs */ 0);
649 
650  /* Complain and continue. might not be root, etc. */
651  if (error)
652  clib_error_report (error);
653 
654  return error;
655 }
656 
658 
659 /*
660  * fd.io coding-style-patch-verification: ON
661  *
662  * Local Variables:
663  * eval: (c-set-style "gnu")
664  * End:
665  */
#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:349
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:337
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:309
static clib_error_t * init_device(vlib_main_t *vm, vlib_pci_device_t *dev, linux_pci_device_t *pdev)
Definition: linux_pci.c:478
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:60
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:419
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:267
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:412
#define clib_error_return(e, args...)
Definition: error.h:99
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:325
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:443
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:239
void unformat_init_string(unformat_input_t *input, char *string, int string_len)
Definition: unformat.c:1023
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:102
#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:634
void vlib_pci_free_device(vlib_pci_device_t *dev)
Definition: linux_pci.c:420
static void pci_config_type0_little_to_host(pci_config_type0_regs_t *r)
Definition: pci_config.h:272
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:485
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:224
#define clib_error_report(e)
Definition: error.h:113
clib_error_t * vlib_pci_map_resource(vlib_pci_device_t *dev, u32 resource, void **result)
Definition: linux_pci.c:404
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:431
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:259
uword os_handle
Definition: pci.h:56
vhost_vring_addr_t addr
Definition: vhost-user.h:82
u32 flags
Definition: vhost-user.h:76
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:972