vdev: use generic vdev struct for probe and remove
[dpdk.git] / lib / librte_eal / common / eal_common_pci.c
1 /*-
2  *   BSD LICENSE
3  *
4  *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
5  *   All rights reserved.
6  *
7  *   Redistribution and use in source and binary forms, with or without
8  *   modification, are permitted provided that the following conditions
9  *   are met:
10  *
11  *     * Redistributions of source code must retain the above copyright
12  *       notice, this list of conditions and the following disclaimer.
13  *     * Redistributions in binary form must reproduce the above copyright
14  *       notice, this list of conditions and the following disclaimer in
15  *       the documentation and/or other materials provided with the
16  *       distribution.
17  *     * Neither the name of Intel Corporation nor the names of its
18  *       contributors may be used to endorse or promote products derived
19  *       from this software without specific prior written permission.
20  *
21  *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22  *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23  *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24  *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25  *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26  *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27  *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28  *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29  *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30  *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31  *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32  */
33 /*   BSD LICENSE
34  *
35  *   Copyright 2013-2014 6WIND S.A.
36  *
37  *   Redistribution and use in source and binary forms, with or without
38  *   modification, are permitted provided that the following conditions
39  *   are met:
40  *
41  *     * Redistributions of source code must retain the above copyright
42  *       notice, this list of conditions and the following disclaimer.
43  *     * Redistributions in binary form must reproduce the above copyright
44  *       notice, this list of conditions and the following disclaimer in
45  *       the documentation and/or other materials provided with the
46  *       distribution.
47  *     * Neither the name of 6WIND S.A. nor the names of its
48  *       contributors may be used to endorse or promote products derived
49  *       from this software without specific prior written permission.
50  *
51  *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
52  *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
53  *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
54  *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
55  *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
56  *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
57  *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
58  *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
59  *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
60  *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
61  *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
62  */
63
64 #include <string.h>
65 #include <inttypes.h>
66 #include <stdint.h>
67 #include <stdlib.h>
68 #include <stdio.h>
69 #include <sys/queue.h>
70 #include <sys/mman.h>
71
72 #include <rte_errno.h>
73 #include <rte_interrupts.h>
74 #include <rte_log.h>
75 #include <rte_bus.h>
76 #include <rte_pci.h>
77 #include <rte_per_lcore.h>
78 #include <rte_memory.h>
79 #include <rte_memzone.h>
80 #include <rte_eal.h>
81 #include <rte_string_fns.h>
82 #include <rte_common.h>
83 #include <rte_devargs.h>
84
85 #include "eal_private.h"
86
87 extern struct rte_pci_bus rte_pci_bus;
88
89 #define SYSFS_PCI_DEVICES "/sys/bus/pci/devices"
90
91 const char *pci_get_sysfs_path(void)
92 {
93         const char *path = NULL;
94
95         path = getenv("SYSFS_PCI_DEVICES");
96         if (path == NULL)
97                 return SYSFS_PCI_DEVICES;
98
99         return path;
100 }
101
102 static struct rte_devargs *pci_devargs_lookup(struct rte_pci_device *dev)
103 {
104         struct rte_devargs *devargs;
105
106         TAILQ_FOREACH(devargs, &devargs_list, next) {
107                 if (devargs->type != RTE_DEVTYPE_BLACKLISTED_PCI &&
108                         devargs->type != RTE_DEVTYPE_WHITELISTED_PCI)
109                         continue;
110                 if (!rte_eal_compare_pci_addr(&dev->addr, &devargs->pci.addr))
111                         return devargs;
112         }
113         return NULL;
114 }
115
116 /* map a particular resource from a file */
117 void *
118 pci_map_resource(void *requested_addr, int fd, off_t offset, size_t size,
119                  int additional_flags)
120 {
121         void *mapaddr;
122
123         /* Map the PCI memory resource of device */
124         mapaddr = mmap(requested_addr, size, PROT_READ | PROT_WRITE,
125                         MAP_SHARED | additional_flags, fd, offset);
126         if (mapaddr == MAP_FAILED) {
127                 RTE_LOG(ERR, EAL, "%s(): cannot mmap(%d, %p, 0x%lx, 0x%lx): %s (%p)\n",
128                         __func__, fd, requested_addr,
129                         (unsigned long)size, (unsigned long)offset,
130                         strerror(errno), mapaddr);
131         } else
132                 RTE_LOG(DEBUG, EAL, "  PCI memory mapped at %p\n", mapaddr);
133
134         return mapaddr;
135 }
136
137 /* unmap a particular resource */
138 void
139 pci_unmap_resource(void *requested_addr, size_t size)
140 {
141         if (requested_addr == NULL)
142                 return;
143
144         /* Unmap the PCI memory resource of device */
145         if (munmap(requested_addr, size)) {
146                 RTE_LOG(ERR, EAL, "%s(): cannot munmap(%p, 0x%lx): %s\n",
147                         __func__, requested_addr, (unsigned long)size,
148                         strerror(errno));
149         } else
150                 RTE_LOG(DEBUG, EAL, "  PCI memory unmapped at %p\n",
151                                 requested_addr);
152 }
153
154 /*
155  * Match the PCI Driver and Device using the ID Table
156  *
157  * @param pci_drv
158  *      PCI driver from which ID table would be extracted
159  * @param pci_dev
160  *      PCI device to match against the driver
161  * @return
162  *      1 for successful match
163  *      0 for unsuccessful match
164  */
165 static int
166 rte_pci_match(const struct rte_pci_driver *pci_drv,
167               const struct rte_pci_device *pci_dev)
168 {
169         const struct rte_pci_id *id_table;
170
171         for (id_table = pci_drv->id_table; id_table->vendor_id != 0;
172              id_table++) {
173                 /* check if device's identifiers match the driver's ones */
174                 if (id_table->vendor_id != pci_dev->id.vendor_id &&
175                                 id_table->vendor_id != PCI_ANY_ID)
176                         continue;
177                 if (id_table->device_id != pci_dev->id.device_id &&
178                                 id_table->device_id != PCI_ANY_ID)
179                         continue;
180                 if (id_table->subsystem_vendor_id !=
181                     pci_dev->id.subsystem_vendor_id &&
182                     id_table->subsystem_vendor_id != PCI_ANY_ID)
183                         continue;
184                 if (id_table->subsystem_device_id !=
185                     pci_dev->id.subsystem_device_id &&
186                     id_table->subsystem_device_id != PCI_ANY_ID)
187                         continue;
188                 if (id_table->class_id != pci_dev->id.class_id &&
189                                 id_table->class_id != RTE_CLASS_ANY_ID)
190                         continue;
191
192                 return 1;
193         }
194
195         return 0;
196 }
197
198 /*
199  * If vendor/device ID match, call the probe() function of the
200  * driver.
201  */
202 static int
203 rte_eal_pci_probe_one_driver(struct rte_pci_driver *dr,
204                              struct rte_pci_device *dev)
205 {
206         int ret;
207         struct rte_pci_addr *loc;
208
209         if ((dr == NULL) || (dev == NULL))
210                 return -EINVAL;
211
212         loc = &dev->addr;
213
214         /* The device is not blacklisted; Check if driver supports it */
215         if (!rte_pci_match(dr, dev)) {
216                 /* Match of device and driver failed */
217                 RTE_LOG(DEBUG, EAL, "Driver (%s) doesn't match the device\n",
218                         dr->driver.name);
219                 return 1;
220         }
221
222         RTE_LOG(INFO, EAL, "PCI device "PCI_PRI_FMT" on NUMA socket %i\n",
223                         loc->domain, loc->bus, loc->devid, loc->function,
224                         dev->device.numa_node);
225
226         /* no initialization when blacklisted, return without error */
227         if (dev->device.devargs != NULL &&
228                 dev->device.devargs->type ==
229                         RTE_DEVTYPE_BLACKLISTED_PCI) {
230                 RTE_LOG(INFO, EAL, "  Device is blacklisted, not"
231                         " initializing\n");
232                 return 1;
233         }
234
235         RTE_LOG(INFO, EAL, "  probe driver: %x:%x %s\n", dev->id.vendor_id,
236                 dev->id.device_id, dr->driver.name);
237
238         if (dr->drv_flags & RTE_PCI_DRV_NEED_MAPPING) {
239                 /* map resources for devices that use igb_uio */
240                 ret = rte_eal_pci_map_device(dev);
241                 if (ret != 0)
242                         return ret;
243         }
244
245         /* reference driver structure */
246         dev->driver = dr;
247
248         /* call the driver probe() function */
249         ret = dr->probe(dr, dev);
250         if (ret) {
251                 dev->driver = NULL;
252                 if (dr->drv_flags & RTE_PCI_DRV_NEED_MAPPING)
253                         rte_eal_pci_unmap_device(dev);
254         }
255
256         return ret;
257 }
258
259 /*
260  * If vendor/device ID match, call the remove() function of the
261  * driver.
262  */
263 static int
264 rte_eal_pci_detach_dev(struct rte_pci_device *dev)
265 {
266         struct rte_pci_addr *loc;
267         struct rte_pci_driver *dr;
268
269         if (dev == NULL)
270                 return -EINVAL;
271
272         dr = dev->driver;
273         loc = &dev->addr;
274
275         RTE_LOG(DEBUG, EAL, "PCI device "PCI_PRI_FMT" on NUMA socket %i\n",
276                         loc->domain, loc->bus, loc->devid,
277                         loc->function, dev->device.numa_node);
278
279         RTE_LOG(DEBUG, EAL, "  remove driver: %x:%x %s\n", dev->id.vendor_id,
280                         dev->id.device_id, dr->driver.name);
281
282         if (dr->remove && (dr->remove(dev) < 0))
283                 return -1;      /* negative value is an error */
284
285         /* clear driver structure */
286         dev->driver = NULL;
287
288         if (dr->drv_flags & RTE_PCI_DRV_NEED_MAPPING)
289                 /* unmap resources for devices that use igb_uio */
290                 rte_eal_pci_unmap_device(dev);
291
292         return 0;
293 }
294
295 /*
296  * If vendor/device ID match, call the probe() function of all
297  * registered driver for the given device. Return -1 if initialization
298  * failed, return 1 if no driver is found for this device.
299  */
300 static int
301 pci_probe_all_drivers(struct rte_pci_device *dev)
302 {
303         struct rte_pci_driver *dr = NULL;
304         int rc = 0;
305
306         if (dev == NULL)
307                 return -1;
308
309         /* Check if a driver is already loaded */
310         if (dev->driver != NULL)
311                 return 0;
312
313         FOREACH_DRIVER_ON_PCIBUS(dr) {
314                 rc = rte_eal_pci_probe_one_driver(dr, dev);
315                 if (rc < 0)
316                         /* negative value is an error */
317                         return -1;
318                 if (rc > 0)
319                         /* positive value means driver doesn't support it */
320                         continue;
321                 return 0;
322         }
323         return 1;
324 }
325
326 /*
327  * Find the pci device specified by pci address, then invoke probe function of
328  * the driver of the devive.
329  */
330 int
331 rte_eal_pci_probe_one(const struct rte_pci_addr *addr)
332 {
333         struct rte_pci_device *dev = NULL;
334
335         int ret = 0;
336
337         if (addr == NULL)
338                 return -1;
339
340         /* update current pci device in global list, kernel bindings might have
341          * changed since last time we looked at it.
342          */
343         if (pci_update_device(addr) < 0)
344                 goto err_return;
345
346         FOREACH_DEVICE_ON_PCIBUS(dev) {
347                 if (rte_eal_compare_pci_addr(&dev->addr, addr))
348                         continue;
349
350                 ret = pci_probe_all_drivers(dev);
351                 if (ret)
352                         goto err_return;
353                 return 0;
354         }
355         return -1;
356
357 err_return:
358         RTE_LOG(WARNING, EAL,
359                 "Requested device " PCI_PRI_FMT " cannot be used\n",
360                 addr->domain, addr->bus, addr->devid, addr->function);
361         return -1;
362 }
363
364 /*
365  * Detach device specified by its pci address.
366  */
367 int
368 rte_eal_pci_detach(const struct rte_pci_addr *addr)
369 {
370         struct rte_pci_device *dev = NULL;
371         int ret = 0;
372
373         if (addr == NULL)
374                 return -1;
375
376         FOREACH_DEVICE_ON_PCIBUS(dev) {
377                 if (rte_eal_compare_pci_addr(&dev->addr, addr))
378                         continue;
379
380                 ret = rte_eal_pci_detach_dev(dev);
381                 if (ret < 0)
382                         /* negative value is an error */
383                         goto err_return;
384                 if (ret > 0)
385                         /* positive value means driver doesn't support it */
386                         continue;
387
388                 rte_eal_pci_remove_device(dev);
389                 free(dev);
390                 return 0;
391         }
392         return -1;
393
394 err_return:
395         RTE_LOG(WARNING, EAL, "Requested device " PCI_PRI_FMT
396                         " cannot be used\n", dev->addr.domain, dev->addr.bus,
397                         dev->addr.devid, dev->addr.function);
398         return -1;
399 }
400
401 /*
402  * Scan the content of the PCI bus, and call the probe() function for
403  * all registered drivers that have a matching entry in its id_table
404  * for discovered devices.
405  */
406 int
407 rte_eal_pci_probe(void)
408 {
409         struct rte_pci_device *dev = NULL;
410         size_t probed = 0, failed = 0;
411         struct rte_devargs *devargs;
412         int probe_all = 0;
413         int ret = 0;
414
415         if (rte_eal_devargs_type_count(RTE_DEVTYPE_WHITELISTED_PCI) == 0)
416                 probe_all = 1;
417
418         FOREACH_DEVICE_ON_PCIBUS(dev) {
419                 probed++;
420
421                 /* set devargs in PCI structure */
422                 devargs = pci_devargs_lookup(dev);
423                 if (devargs != NULL)
424                         dev->device.devargs = devargs;
425
426                 /* probe all or only whitelisted devices */
427                 if (probe_all)
428                         ret = pci_probe_all_drivers(dev);
429                 else if (devargs != NULL &&
430                         devargs->type == RTE_DEVTYPE_WHITELISTED_PCI)
431                         ret = pci_probe_all_drivers(dev);
432                 if (ret < 0) {
433                         RTE_LOG(ERR, EAL, "Requested device " PCI_PRI_FMT
434                                  " cannot be used\n", dev->addr.domain, dev->addr.bus,
435                                  dev->addr.devid, dev->addr.function);
436                         rte_errno = errno;
437                         failed++;
438                         ret = 0;
439                 }
440         }
441
442         return (probed && probed == failed) ? -1 : 0;
443 }
444
445 /* dump one device */
446 static int
447 pci_dump_one_device(FILE *f, struct rte_pci_device *dev)
448 {
449         int i;
450
451         fprintf(f, PCI_PRI_FMT, dev->addr.domain, dev->addr.bus,
452                dev->addr.devid, dev->addr.function);
453         fprintf(f, " - vendor:%x device:%x\n", dev->id.vendor_id,
454                dev->id.device_id);
455
456         for (i = 0; i != sizeof(dev->mem_resource) /
457                 sizeof(dev->mem_resource[0]); i++) {
458                 fprintf(f, "   %16.16"PRIx64" %16.16"PRIx64"\n",
459                         dev->mem_resource[i].phys_addr,
460                         dev->mem_resource[i].len);
461         }
462         return 0;
463 }
464
465 /* dump devices on the bus */
466 void
467 rte_eal_pci_dump(FILE *f)
468 {
469         struct rte_pci_device *dev = NULL;
470
471         FOREACH_DEVICE_ON_PCIBUS(dev) {
472                 pci_dump_one_device(f, dev);
473         }
474 }
475
476 /* register a driver */
477 void
478 rte_eal_pci_register(struct rte_pci_driver *driver)
479 {
480         TAILQ_INSERT_TAIL(&rte_pci_bus.driver_list, driver, next);
481         driver->bus = &rte_pci_bus;
482 }
483
484 /* unregister a driver */
485 void
486 rte_eal_pci_unregister(struct rte_pci_driver *driver)
487 {
488         TAILQ_REMOVE(&rte_pci_bus.driver_list, driver, next);
489         driver->bus = NULL;
490 }
491
492 /* Add a device to PCI bus */
493 void
494 rte_eal_pci_add_device(struct rte_pci_device *pci_dev)
495 {
496         TAILQ_INSERT_TAIL(&rte_pci_bus.device_list, pci_dev, next);
497 }
498
499 /* Insert a device into a predefined position in PCI bus */
500 void
501 rte_eal_pci_insert_device(struct rte_pci_device *exist_pci_dev,
502                           struct rte_pci_device *new_pci_dev)
503 {
504         TAILQ_INSERT_BEFORE(exist_pci_dev, new_pci_dev, next);
505 }
506
507 /* Remove a device from PCI bus */
508 void
509 rte_eal_pci_remove_device(struct rte_pci_device *pci_dev)
510 {
511         TAILQ_REMOVE(&rte_pci_bus.device_list, pci_dev, next);
512 }
513
514 struct rte_pci_bus rte_pci_bus = {
515         .bus = {
516                 .scan = rte_eal_pci_scan,
517                 .probe = rte_eal_pci_probe,
518         },
519         .device_list = TAILQ_HEAD_INITIALIZER(rte_pci_bus.device_list),
520         .driver_list = TAILQ_HEAD_INITIALIZER(rte_pci_bus.driver_list),
521 };
522
523 RTE_REGISTER_BUS(PCI_BUS_NAME, rte_pci_bus.bus);