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