FD.io VPP  v16.06
Vector Packet Processing
pci.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2015 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 #include <vlib/unix/pci.h>
44 
45 #include <sys/types.h>
46 #include <sys/stat.h>
47 #include <fcntl.h>
48 #include <dirent.h>
49 #include <sys/ioctl.h>
50 #include <net/if.h>
51 #include <linux/ethtool.h>
52 #include <linux/sockios.h>
53 
54 
56 
58 vlib_pci_bind_to_uio (vlib_pci_device_t * d, char * uio_driver_name)
59 {
60  clib_error_t * error = 0;
61  u8 *s = 0;
62  DIR *dir = 0;
63  struct dirent *e;
64  int fd;
66  u8 * dev_dir_name = format(0, "/sys/bus/pci/devices/%U",
68 
69  c = &d->config0.header;
70 
71  /* if uio sub-directory exists, we are fine, device is
72  already bound to UIO driver */
73  s = format (s, "%v/uio%c", dev_dir_name, 0);
74  if (access ( (char *) s, F_OK) == 0)
75  goto done;
76  vec_reset_length (s);
77 
78  /* walk trough all linux interfaces and if interface belonging to
79  this device is founf check if interface is admin up */
80  dir = opendir ("/sys/class/net");
81  s = format(s, "%U%c", format_vlib_pci_addr, &d->bus_address, 0);
82 
83  if (!dir)
84  {
85  error = clib_error_return (0, "Skipping PCI device %U: failed to "
86  "read /sys/class/net",
88  goto done;
89  }
90 
91  fd = socket(PF_INET, SOCK_DGRAM, 0);
92 
93  while((e = readdir (dir)))
94  {
95  struct ifreq ifr;
96  struct ethtool_drvinfo drvinfo;
97 
98  if (e->d_name[0] == '.') /* skip . and .. */
99  continue;
100 
101  memset(&ifr, 0, sizeof ifr);
102  memset(&drvinfo, 0, sizeof drvinfo);
103  ifr.ifr_data = (char *) &drvinfo;
104  strncpy(ifr.ifr_name, e->d_name, IFNAMSIZ);
105  drvinfo.cmd = ETHTOOL_GDRVINFO;
106  ioctl (fd, SIOCETHTOOL, &ifr);
107 
108  if (strcmp ((char *) s, drvinfo.bus_info))
109  continue;
110 
111  memset (&ifr, 0, sizeof(ifr));
112  strncpy (ifr.ifr_name, e->d_name, IFNAMSIZ);
113  ioctl (fd, SIOCGIFFLAGS, &ifr);
114  close (fd);
115 
116  if (ifr.ifr_flags & IFF_UP)
117  {
118  error = clib_error_return (0, "Skipping PCI device %U as host "
119  "interface %s is up",
121  e->d_name);
122  goto done;
123  }
124  }
125 
126  close (fd);
127  vec_reset_length (s);
128 
129  s = format (s, "%v/driver/unbind%c", dev_dir_name, 0);
130  write_sys_fs ((char *) s, "%U", format_vlib_pci_addr, &d->bus_address);
131  vec_reset_length (s);
132 
133  s = format (s, "/sys/bus/pci/drivers/%s/new_id%c", uio_driver_name, 0);
134  write_sys_fs ((char *) s, "0x%04x 0x%04x", c->vendor_id, c->device_id);
135  vec_reset_length (s);
136 
137  s = format (s, "/sys/bus/pci/drivers/%s/bind%c", uio_driver_name, 0);
138  write_sys_fs ((char *) s, "%U", format_vlib_pci_addr, &d->bus_address);
139 
140 done:
141  closedir (dir);
142  vec_free (s);
143  vec_free (dev_dir_name);
144  return error;
145 }
146 
147 
148 static clib_error_t *
149 scan_uio_dir (void * arg, u8 * path_name, u8 * file_name)
150 {
151  linux_pci_device_t * l = arg;
152  unformat_input_t input;
153 
154  unformat_init_string (&input, (char *) file_name, vec_len (file_name));
155 
156  if (! unformat (&input, "uio%d", &l->uio_minor))
157  abort ();
158 
159  unformat_free (&input);
160  return 0;
161 }
162 
164 {
166  vlib_main_t * vm = pm->vlib_main;
167  linux_pci_device_t * l;
168  u32 li = uf->private_data;
169 
170  l = pool_elt_at_index (pm->linux_pci_devices, li);
172 
173  /* Let node know which device is interrupting. */
174  {
176  rt->runtime_data[0] |= 1 << l->device_index;
177  }
178 
179  return /* no error */ 0;
180 }
181 
183 {
184  u32 error_index = (u32) uf->private_data;
185 
186  return clib_error_return (0, "pci device %d: error", error_index);
187 }
188 
189 static uword pci_resource_size (uword os_handle, uword resource)
190 {
192  linux_pci_device_t * p;
193  u8 * file_name;
194  struct stat b;
195  uword result = 0;
196 
197  p = pool_elt_at_index (pm->linux_pci_devices, os_handle);
198 
199  file_name = format (0, "%v/resource%d%c", p->dev_dir_name, resource, 0);
200  if (stat ((char *) file_name, &b) >= 0)
201  result = b.st_size;
202  vec_free (file_name);
203  return result;
204 }
205 
206 void os_add_pci_disable_interrupts_reg (uword os_handle, u32 resource,
207  u32 reg_offset, u32 reg_value)
208 {
210  linux_pci_device_t * l;
211  char * file_name;
212  clib_error_t * error;
213 
214  l = pool_elt_at_index (pm->linux_pci_devices, os_handle);
215  ASSERT (resource == 0);
216  ASSERT (reg_offset < pci_resource_size (os_handle, resource));
217  file_name = (char *) format (0, "%s/disable_interrupt_regs%c", l->dev_dir_name, 0);
218  error = write_sys_fs (file_name, "%x %x", reg_offset, reg_value);
219  if (error)
220  clib_error_report (error);
221  vec_free (file_name);
222 }
223 
225 {
227  linux_pci_device_t * l;
229  u32 x[4];
230  clib_error_t * error;
231 
232  c = &dev->config0.header;
233 
234  pool_get (pm->linux_pci_devices, l);
235  l[0] = pdev[0];
236 
238 
239  dev->os_handle = l - pm->linux_pci_devices;
240 
241  error = write_sys_fs ("/sys/bus/pci/drivers/uio_pci_dma/new_id",
242  "%x %x", c->vendor_id, c->device_id);
243  if (error)
244  clib_error_report (error);
245  error = write_sys_fs ("/sys/bus/pci/drivers/uio_pci_dma/bind",
246  "%04x:%02x:%02x.%x", x[0], x[1], x[2], x[3]);
247  /* Errors happen when re-binding so just ignore them. */
248  if (error)
249  clib_error_free (error);
250 
251  {
252  u8 * uio_dir = format (0, "%s/uio", l->dev_dir_name);
253  foreach_directory_file ((char *) uio_dir, scan_uio_dir, l, /* scan_dirs */ 1);
254  vec_free (uio_dir);
255  }
256 
257  {
258  char * uio_name = (char *) format (0, "/dev/uio%d%c", l->uio_minor, 0);
259  l->uio_fd = open (uio_name, O_RDWR);
260  if (l->uio_fd < 0)
261  clib_unix_error ("open `%s'", uio_name);
262  vec_free (uio_name);
263  }
264 
265  {
266  unix_file_t template = {0};
267  unix_main_t * um = &unix_main;
268 
269  template.read_function = linux_pci_uio_read_ready;
270  template.file_descriptor = l->uio_fd;
271  template.error_function = linux_pci_uio_error_ready;
272  template.private_data = l - pm->linux_pci_devices;
273 
274  /* To be filled in by driver. */
275  l->device_input_node_index = ~0;
276  l->device_index = 0;
277 
278  l->unix_file_index = unix_file_add (um, &template);
279  }
280 }
281 
283 {
284  int i;
285  for (i = 0; i < vec_len (l->resource_fds); i++)
286  if (l->resource_fds[i] > 0)
287  close (l->resource_fds[i]);
288  if (l->config_fd > 0)
289  close (l->config_fd);
290  if (l->uio_fd > 0)
291  close (l->uio_fd);
292  vec_free (l->resource_fds);
293  vec_free (l->dev_dir_name);
294 }
295 
296 /* Configuration space read/write. */
297 clib_error_t *
299  vlib_read_or_write_t read_or_write,
300  uword address,
301  void * data,
302  u32 n_bytes)
303 {
305  linux_pci_device_t * p;
306  int n;
307 
308  p = pool_elt_at_index (pm->linux_pci_devices, os_handle);
309 
310  if (address != lseek (p->config_fd, address, SEEK_SET))
311  return clib_error_return_unix (0, "seek offset %d", address);
312 
313  if (read_or_write == VLIB_READ)
314  n = read (p->config_fd, data, n_bytes);
315  else
316  n = write (p->config_fd, data, n_bytes);
317 
318  if (n != n_bytes)
319  return clib_error_return_unix (0, "%s",
320  read_or_write == VLIB_READ
321  ? "read" : "write");
322 
323  return 0;
324 }
325 
326 static clib_error_t *
328  u32 resource,
329  u8 *addr,
330  void ** result)
331 {
333  linux_pci_device_t * p;
334  struct stat stat_buf;
335  u8 * file_name;
336  int fd;
337  clib_error_t * error;
338  int flags = MAP_SHARED;
339 
340  error = 0;
341  p = pool_elt_at_index (pm->linux_pci_devices, os_handle);
342 
343  file_name = format (0, "%v/resource%d%c", p->dev_dir_name, resource, 0);
344  fd = open ((char *) file_name, O_RDWR);
345  if (fd < 0)
346  {
347  error = clib_error_return_unix (0, "open `%s'", file_name);
348  goto done;
349  }
350 
351  if (fstat (fd, &stat_buf) < 0)
352  {
353  error = clib_error_return_unix (0, "fstat `%s'", file_name);
354  goto done;
355  }
356 
357  vec_validate (p->resource_fds, resource);
358  p->resource_fds[resource] = fd;
359  if (addr != 0)
360  flags |= MAP_FIXED;
361 
362  *result = mmap (addr,
363  /* size */ stat_buf.st_size,
364  PROT_READ | PROT_WRITE,
365  flags,
366  /* file */ fd,
367  /* offset */ 0);
368  if (*result == (void *) -1)
369  {
370  error = clib_error_return_unix (0, "mmap `%s'", file_name);
371  goto done;
372  }
373 
374  done:
375  if (error)
376  {
377  if (fd > 0)
378  close (fd);
379  }
380  vec_free (file_name);
381  return error;
382 }
383 
384 clib_error_t *
386  u32 resource,
387  void ** result)
388 {
389  return (os_map_pci_resource_internal (os_handle, resource, 0 /* addr */,
390  result));
391 }
392 
393 clib_error_t *
395  u32 resource,
396  u8 *addr,
397  void ** result)
398 {
399  return (os_map_pci_resource_internal (os_handle, resource, addr, result));
400 }
401 
402 void os_free_pci_device (uword os_handle)
403 {
405  linux_pci_device_t * l;
406 
407  l = pool_elt_at_index (pm->linux_pci_devices, os_handle);
409  pool_put (pm->linux_pci_devices, l);
410 }
411 
412 u8 * format_os_pci_handle (u8 * s, va_list * va)
413 {
415  uword os_pci_handle = va_arg (*va, uword);
416  linux_pci_device_t * l;
417 
418  l = pool_elt_at_index (pm->linux_pci_devices, os_pci_handle);
419  return format (s, "%x/%x/%x", l->bus_address.bus,
420  l->bus_address.slot, l->bus_address.function);
421 }
422 
423 pci_device_registration_t * __attribute__((unused))
425 {
426  uword i;
427 
428  /* Null vendor id marks end of initialized list. */
429  for (i = 0; r->supported_devices[i].vendor_id != 0; i++)
430  ;
431 
432  return clib_elf_section_data_next (r, i * sizeof (r->supported_devices[0]));
433 }
434 
436 {
437  u8 * link_name;
438  struct stat b;
439 
440  link_name = format (0, "/sys/bus/pci/drivers/%s", r->kernel_driver);
441  if (stat ((char *)link_name, &b) >= 0)
442  r->kernel_driver_running++;
443  else
444  r->kernel_driver_running=0;
445 
446  vec_free (link_name);
447  return r->kernel_driver_running;
448 }
449 
450 static clib_error_t *
452  vlib_pci_device_t * dev,
453  linux_pci_device_t * pdev)
454 {
457  pci_device_id_t * i;
459 
460  c = &dev->config0.header;
461 
462  r = lpm->pci_device_registrations;
463 
464  while (r)
465  {
466  for (i = r->supported_devices; i->vendor_id != 0; i++)
467  if (i->vendor_id == c->vendor_id && i->device_id == c->device_id)
468  {
469  if (r->kernel_driver && kernel_driver_installed(r))
470  {
471  if (r->kernel_driver_running == 1)
472  {
473  clib_warning("PCI device type [%04x:%04x] is busy!\n"
474  "\tUninstall the associated linux kernel "
475  "driver: sudo rmmod %s",
476  c->vendor_id, c->device_id, r->kernel_driver);
477  }
478  continue;
479  }
480  add_device (dev, pdev);
481  return r->init_function (vm, dev);
482  }
483  r = r->next_registration;
484  }
485  /* No driver, close the PCI config-space FD */
486  close (pdev->config_fd);
487  return 0;
488 }
489 
490 static clib_error_t *
492  vlib_pci_device_t * dev,
493  linux_pci_device_t * pdev)
494 {
495  return init_device_from_registered (vm, dev, pdev);
496 }
497 
498 static clib_error_t *
499 scan_device (void * arg, u8 * dev_dir_name, u8 * ignored)
500 {
501  vlib_main_t * vm = arg;
503  int fd;
504  u8 * f;
505  clib_error_t * error = 0;
506  vlib_pci_device_t * dev;
507  linux_pci_device_t pdev = {0};
508 
509  f = format (0, "%v/config%c", dev_dir_name, 0);
510  fd = open ((char *) f, O_RDWR);
511 
512  /* Try read-only access if write fails. */
513  if (fd < 0)
514  fd = open ((char *) f, O_RDONLY);
515 
516  if (fd < 0)
517  {
518  error = clib_error_return_unix (0, "open `%s'", f);
519  goto done;
520  }
521 
522  pool_get (pm->pci_devs, dev);
523 
524  /* You can only read more that 64 bytes of config space as root; so we try to
525  read the full space but fall back to just the first 64 bytes. */
526  if (read (fd, &dev->config_data, sizeof (dev->config_data)) != sizeof (dev->config_data)
527  && read (fd, &dev->config0, sizeof (dev->config0)) != sizeof (dev->config0))
528  {
529  pool_put (pm->pci_devs, dev);
530  error = clib_error_return_unix (0, "read `%s'", f);
531  goto done;
532  }
533 
534  {
535  static pci_config_header_t all_ones;
536  if (all_ones.vendor_id == 0)
537  memset (&all_ones, ~0, sizeof (all_ones));
538 
539  if (! memcmp (&dev->config0.header, &all_ones, sizeof (all_ones)))
540  {
541  pool_put (pm->pci_devs, dev);
542  error = clib_error_return (0, "invalid PCI config for `%s'", f);
543  goto done;
544  }
545  }
546 
547  if (dev->config0.header.header_type == 0)
549  else
551 
552  /* Parse bus, dev, function from directory name. */
553  {
554  unformat_input_t input;
555 
556  unformat_init_string (&input, (char *) dev_dir_name,
557  vec_len (dev_dir_name));
558 
559  if (! unformat (&input, "/sys/bus/pci/devices/%U",
561  abort ();
562 
563  unformat_free (&input);
564 
565  pdev.bus_address = dev->bus_address;
566  }
567 
568 
569  pdev.config_fd = fd;
570  pdev.dev_dir_name = dev_dir_name;
571 
573  dev - pm->pci_devs);
574 
575  error = init_device (vm, dev, &pdev);
576 
577  done:
578  vec_free (f);
579  return error;
580 }
581 
583 {
585  clib_error_t * error;
586 
587  pm->vlib_main = vm;
588 
589  if ((error = vlib_call_init_function (vm, unix_input_init)))
590  return error;
591 
592  ASSERT(sizeof(vlib_pci_addr_t) == sizeof(u32));
593  pm->pci_dev_index_by_pci_addr = hash_create (0, sizeof (uword));
594 
595  error = foreach_directory_file ("/sys/bus/pci/devices", scan_device, vm, /* scan_dirs */ 0);
596 
597  /* Complain and continue. might not be root, etc. */
598  if (error)
599  clib_error_report (error);
600 
601  return error;
602 }
603 
#define vec_validate(V, I)
Make sure vector is long enough for given index (no header, unspecified alignment) ...
Definition: vec.h:394
pci_device_registration_t * pci_device_registrations
Definition: pci.h:79
#define hash_set(h, key, value)
Definition: hash.h:237
sll srl srl sll sra u16x4 i
Definition: vector_sse2.h:267
uword unformat(unformat_input_t *i, char *fmt,...)
Definition: unformat.c:942
static u8 * format_vlib_pci_addr(u8 *s, va_list *va)
Definition: pci.h:169
clib_error_t * pci_bus_init(vlib_main_t *vm)
Definition: pci.c:582
u8 config_data[256]
Definition: pci.h:66
static clib_error_t * init_device(vlib_main_t *vm, vlib_pci_device_t *dev, linux_pci_device_t *pdev)
Definition: pci.c:491
vlib_read_or_write_t
Definition: defs.h:53
always_inline void unformat_free(unformat_input_t *i)
Definition: format.h:160
u8 * dev_dir_name
Definition: pci.h:47
u32 unix_file_index
Definition: pci.h:65
always_inline uword unix_file_add(unix_main_t *um, unix_file_t *template)
Definition: unix.h:131
always_inline void vlib_node_set_interrupt_pending(vlib_main_t *vm, u32 node_index)
Definition: node_funcs.h:134
#define clib_error_report(e)
Definition: error.h:126
static clib_error_t * scan_uio_dir(void *arg, u8 *path_name, u8 *file_name)
Definition: pci.c:149
#define pool_get(P, E)
Definition: pool.h:186
#define vec_reset_length(v)
Reset vector length to zero NULL-pointer tolerant.
int * resource_fds
Definition: pci.h:50
vlib_pci_addr_t bus_address
Definition: pci.h:56
static clib_error_t * init_device_from_registered(vlib_main_t *vm, vlib_pci_device_t *dev, linux_pci_device_t *pdev)
Definition: pci.c:451
#define VLIB_INIT_FUNCTION(x)
Definition: init.h:109
vlib_pci_addr_t bus_address
Definition: pci.h:60
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
u32 device_input_node_index
Definition: pci.h:68
clib_error_t * vlib_pci_bind_to_uio(vlib_pci_device_t *d, char *uio_driver_name)
Definition: pci.c:58
#define clib_warning(format, args...)
Definition: error.h:59
vlib_main_t * vlib_main
Definition: pci.h:76
void unformat_init_string(unformat_input_t *input, char *string, int string_len)
Definition: unformat.c:991
#define vlib_call_init_function(vm, x)
Definition: init.h:159
static void linux_pci_device_free(linux_pci_device_t *l)
Definition: pci.c:282
always_inline void pci_config_type1_little_to_host(pci_config_type1_regs_t *r)
Definition: pci_config.h:340
#define pool_elt_at_index(p, i)
Definition: pool.h:346
static u8 kernel_driver_installed(pci_device_registration_t *r)
Definition: pci.c:435
uword * pci_dev_index_by_pci_addr
Definition: pci.h:80
int config_fd
Definition: pci.h:53
uword private_data
Definition: unix.h:58
vlib_pci_device_t * pci_devs
Definition: pci.h:77
static clib_error_t * os_map_pci_resource_internal(uword os_handle, u32 resource, u8 *addr, void **result)
Definition: pci.c:327
#define clib_error_return_unix(e, args...)
Definition: error.h:115
#define pool_put(P, E)
Definition: pool.h:200
#define vec_dup(V)
Return copy of vector (no header, no alignment)
Definition: vec.h:332
u32 device_index
Definition: pci.h:71
clib_error_t * os_read_write_pci_config(uword os_handle, vlib_read_or_write_t read_or_write, uword address, void *data, u32 n_bytes)
Definition: pci.c:298
static clib_error_t * linux_pci_uio_error_ready(unix_file_t *uf)
Definition: pci.c:182
static clib_error_t * unix_input_init(vlib_main_t *vm)
Definition: input.c:245
linux_pci_main_t linux_pci_main
Definition: pci.c:55
clib_error_t * os_map_pci_resource_fixed(uword os_handle, u32 resource, u8 *addr, void **result)
Definition: pci.c:394
#define vec_free(V)
Free vector&#39;s memory (no header).
Definition: vec.h:298
#define clib_error_free(e)
Definition: error.h:97
#define hash_create(elts, value_bytes)
Definition: hash.h:615
#define clib_elf_section_data_next(a, extra)
Definition: elf_clib.h:57
#define ASSERT(truth)
unsigned int u32
Definition: types.h:88
void os_add_pci_disable_interrupts_reg(uword os_handle, u32 resource, u32 reg_offset, u32 reg_value)
Definition: pci.c:206
u8 * format(u8 *s, char *fmt,...)
Definition: format.c:405
pci_config_type1_regs_t config1
Definition: pci.h:65
static uword unformat_vlib_pci_addr(unformat_input_t *input, va_list *args)
Definition: pci.h:152
unix_main_t unix_main
Definition: main.c:57
#define clib_unix_error(format, args...)
Definition: error.h:65
static clib_error_t * scan_device(void *arg, u8 *dev_dir_name, u8 *ignored)
Definition: pci.c:499
u64 uword
Definition: types.h:112
pci_config_type0_regs_t config0
Definition: pci.h:64
Definition: defs.h:54
uword os_handle
Definition: pci.h:58
clib_error_t * write_sys_fs(char *file_name, char *fmt,...)
Definition: util.c:104
u8 * format_os_pci_handle(u8 *s, va_list *va)
Definition: pci.c:412
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
unsigned char u8
Definition: types.h:56
void os_free_pci_device(uword os_handle)
Definition: pci.c:402
static uword pci_resource_size(uword os_handle, uword resource)
Definition: pci.c:189
Definition: unix.h:49
struct _pci_device_registration pci_device_registration_t
u16 device_id
Definition: pci.h:71
clib_error_t * os_map_pci_resource(uword os_handle, u32 resource, void **result)
Definition: pci.c:385
static clib_error_t * linux_pci_uio_read_ready(unix_file_t *uf)
Definition: pci.c:163
always_inline vlib_node_runtime_t * vlib_node_get_runtime(vlib_main_t *vm, u32 node_index)
Definition: node_funcs.h:61
vhost_vring_addr_t addr
Definition: vhost-user.h:78
#define clib_error_return(e, args...)
Definition: error.h:112
always_inline void pci_config_type0_little_to_host(pci_config_type0_regs_t *r)
Definition: pci_config.h:267
struct _unformat_input_t unformat_input_t
u32 flags
Definition: vhost-user.h:73
pci_device_registration_t * pci_device_next_registered(pci_device_registration_t *r)
Definition: pci.c:424
linux_pci_device_t * linux_pci_devices
Definition: pci.h:78
uword runtime_data[(128-1 *sizeof(vlib_node_function_t *)-1 *sizeof(vlib_error_t *)-11 *sizeof(u32)-5 *sizeof(u16))/sizeof(uword)]
Definition: node.h:432
pci_config_header_t header
Definition: pci_config.h:235
u16 vendor_id
Definition: pci.h:71
u32 uio_minor
Definition: pci.h:62
static void add_device(vlib_pci_device_t *dev, linux_pci_device_t *pdev)
Definition: pci.c:224