/*-
* BSD LICENSE
*
- * Copyright(c) 2010-2013 Intel Corporation. All rights reserved.
+ * Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
#include <rte_string_fns.h>
#include <rte_debug.h>
+#include "rte_pci_dev_ids.h"
#include "eal_filesystem.h"
#include "eal_private.h"
struct dirent *e;
DIR *dir;
char dirname[PATH_MAX];
+ char filename[PATH_MAX];
char dirname2[PATH_MAX];
char devname[PATH_MAX]; /* contains the /dev/uioX */
void *mapaddr;
unsigned uio_num;
+ unsigned long start,size;
uint64_t phaddr;
uint64_t offset;
uint64_t pagesz;
dev->intr_handle.fd = -1;
/* secondary processes - use already recorded details */
- if (rte_eal_process_type() != RTE_PROC_PRIMARY)
+ if ((rte_eal_process_type() != RTE_PROC_PRIMARY) &&
+ (dev->id.vendor_id != PCI_VENDOR_ID_QUMRANET))
return (pci_uio_map_secondary(dev));
/* depending on kernel version, uio can be located in uio/uioX
* or uio:uioX */
rte_snprintf(dirname, sizeof(dirname),
- "/sys/bus/pci/devices/" PCI_PRI_FMT "/uio",
+ SYSFS_PCI_DEVICES "/" PCI_PRI_FMT "/uio",
loc->domain, loc->bus, loc->devid, loc->function);
dir = opendir(dirname);
if (dir == NULL) {
/* retry with the parent directory */
rte_snprintf(dirname, sizeof(dirname),
- "/sys/bus/pci/devices/" PCI_PRI_FMT,
+ SYSFS_PCI_DEVICES "/" PCI_PRI_FMT,
loc->domain, loc->bus, loc->devid, loc->function);
dir = opendir(dirname);
/* first try uio%d */
errno = 0;
uio_num = strtoull(e->d_name + shortprefix_len, &endptr, 10);
- if (errno == 0 && endptr != e->d_name) {
+ if (errno == 0 && endptr != (e->d_name + shortprefix_len)) {
rte_snprintf(dirname2, sizeof(dirname2),
"%s/uio%u", dirname, uio_num);
break;
/* then try uio:uio%d */
errno = 0;
uio_num = strtoull(e->d_name + longprefix_len, &endptr, 10);
- if (errno == 0 && endptr != e->d_name) {
+ if (errno == 0 && endptr != (e->d_name + longprefix_len)) {
rte_snprintf(dirname2, sizeof(dirname2),
"%s/uio:uio%u", dirname, uio_num);
break;
return -1;
}
+ if(dev->id.vendor_id == PCI_VENDOR_ID_QUMRANET) {
+ /* get portio size */
+ rte_snprintf(filename, sizeof(filename),
+ "%s/portio/port0/size", dirname2);
+ if (eal_parse_sysfs_value(filename, &size) < 0) {
+ RTE_LOG(ERR, EAL, "%s(): cannot parse size\n",
+ __func__);
+ return -1;
+ }
+
+ /* get portio start */
+ rte_snprintf(filename, sizeof(filename),
+ "%s/portio/port0/start", dirname2);
+ if (eal_parse_sysfs_value(filename, &start) < 0) {
+ RTE_LOG(ERR, EAL, "%s(): cannot parse portio start\n",
+ __func__);
+ return -1;
+ }
+ dev->mem_resource[0].addr = (void *)(uintptr_t)start;
+ dev->mem_resource[0].len = (uint64_t)size;
+ RTE_LOG(DEBUG, EAL, "PCI Port IO found start=0x%lx with size=0x%lx\n", start, size);
+ /* rte_virtio_pmd does not need any other bar even if available */
+ return (0);
+ }
+
/* allocate the mapping details for secondary processes*/
if ((uio_res = rte_zmalloc("UIO_RES", sizeof (*uio_res), 0)) == NULL) {
RTE_LOG(ERR, EAL,
"%s(): cannot store uio mmap details\n", __func__);
return (-1);
}
-
+
rte_snprintf(devname, sizeof(devname), "/dev/uio%u", uio_num);
rte_snprintf(uio_res->path, sizeof(uio_res->path), "%s", devname);
memcpy(&uio_res->pci_addr, &dev->addr, sizeof(uio_res->pci_addr));
-
+
/* collect info about device mappings */
if ((nb_maps = pci_uio_get_mappings(dirname2, uio_res->maps,
sizeof (uio_res->maps) / sizeof (uio_res->maps[0])))
rte_eal_pci_probe_one_driver(struct rte_pci_driver *dr, struct rte_pci_device *dev)
{
struct rte_pci_id *id_table;
-#ifdef RTE_EAL_UNBIND_PORTS
- const char *module_name = NULL;
- int uio_status = -1;
-
- if (dr->drv_flags & RTE_PCI_DRV_NEED_IGB_UIO)
- module_name = IGB_UIO_NAME;
-#endif
for (id_table = dr->id_table ; id_table->vendor_id != 0; id_table++) {
}
#ifdef RTE_EAL_UNBIND_PORTS
- /* Unbind PCI devices if needed */
- if (module_name != NULL)
- if (pci_switch_module(dr, dev, uio_status, module_name) < 0)
+ if (dr->drv_flags & RTE_PCI_DRV_NEED_IGB_UIO) {
+ /* unbind driver and load uio resources for Intel NICs */
+ if (pci_switch_module(dr, dev, 1, IGB_UIO_NAME) < 0)
+ return -1;
+ } else if (dr->drv_flags & RTE_PCI_DRV_FORCE_UNBIND &&
+ rte_eal_process_type() == RTE_PROC_PRIMARY) {
+ /* unbind current driver */
+ if (pci_unbind_kernel_driver(dev) < 0)
return -1;
+ }
#else
- /* just map the NIC resources */
- if (pci_uio_map_resource(dev) < 0)
- return -1;
+ if (dr->drv_flags & RTE_PCI_DRV_NEED_IGB_UIO)
+ /* just map resources for Intel NICs */
+ if (pci_uio_map_resource(dev) < 0)
+ return -1;
#endif
- /* We always should have BAR0 mapped */
- if (rte_eal_process_type() == RTE_PROC_PRIMARY &&
- dev->mem_resource[0].addr == NULL) {
- RTE_LOG(ERR, EAL,
- "%s(): BAR0 is not mapped\n",
- __func__);
- return (-1);
- }
-
/* reference driver structure */
dev->driver = dr;