.plug = pci_plug,
.unplug = pci_unplug,
.parse = pci_parse,
+ .devargs_parse = rte_pci_devargs_parse,
.dma_map = pci_dma_map,
.dma_unmap = pci_dma_unmap,
.get_iommu_class = rte_pci_get_iommu_class,
#include <rte_dev.h>
#include <rte_errno.h>
#include <rte_kvargs.h>
+#include <rte_devargs.h>
#include <rte_pci.h>
+#include <rte_debug.h>
#include "private.h"
rte_kvargs_free(kvargs);
return dev;
}
+
+int
+rte_pci_devargs_parse(struct rte_devargs *da)
+{
+ struct rte_kvargs *kvargs;
+ const char *addr_str;
+ struct rte_pci_addr addr;
+ int ret;
+
+ if (da == NULL)
+ return 0;
+ RTE_ASSERT(da->bus_str != NULL);
+
+ kvargs = rte_kvargs_parse(da->bus_str, NULL);
+ if (kvargs == NULL) {
+ RTE_LOG(ERR, EAL, "cannot parse argument list: %s\n",
+ da->bus_str);
+ ret = -ENODEV;
+ goto out;
+ }
+
+ addr_str = rte_kvargs_get(kvargs, pci_params_keys[RTE_PCI_PARAM_ADDR]);
+ if (addr_str == NULL) {
+ RTE_LOG(ERR, EAL, "No PCI address specified using '%s=<id>' in: %s\n",
+ pci_params_keys[RTE_PCI_PARAM_ADDR], da->bus_str);
+ ret = -ENODEV;
+ goto out;
+ }
+
+ ret = rte_pci_addr_parse(addr_str, &addr);
+ if (ret != 0) {
+ RTE_LOG(ERR, EAL, "PCI address invalid: %s\n", da->bus_str);
+ ret = -EINVAL;
+ goto out;
+ }
+
+ rte_pci_device_name(&addr, da->name, sizeof(da->name));
+
+out:
+ if (kvargs != NULL)
+ rte_kvargs_free(kvargs);
+ if (ret != 0)
+ rte_errno = -ret;
+ return ret;
+}
const char *str,
const struct rte_dev_iterator *it);
+/*
+ * Parse device arguments and update name.
+ *
+ * @param da
+ * device arguments to parse.
+ *
+ * @return
+ * 0 on success.
+ * -EINVAL: kvargs string is invalid and cannot be parsed.
+ * -ENODEV: no key matching a device ID is found in the kv list.
+ */
+int
+rte_pci_devargs_parse(struct rte_devargs *da);
+
#endif /* _PCI_PRIVATE_H_ */
#include <rte_kvargs.h>
#include <rte_log.h>
#include <rte_tailq.h>
+#include <rte_string_fns.h>
#include "eal_private.h"
/** user device double-linked queue type definition */
return i;
}
+/* Resolve devargs name from bus arguments. */
+static int
+devargs_bus_parse_default(struct rte_devargs *devargs,
+ struct rte_kvargs *bus_args)
+{
+ const char *name;
+
+ /* Parse devargs name from bus key-value list. */
+ name = rte_kvargs_get(bus_args, "name");
+ if (name == NULL) {
+ RTE_LOG(INFO, EAL, "devargs name not found: %s\n",
+ devargs->data);
+ return 0;
+ }
+ if (rte_strscpy(devargs->name, name, sizeof(devargs->name)) < 0) {
+ RTE_LOG(ERR, EAL, "devargs name too long: %s\n",
+ devargs->data);
+ return -E2BIG;
+ }
+ return 0;
+}
+
int
rte_devargs_layers_parse(struct rte_devargs *devargs,
const char *devstr)
if (layers[i].kvlist == NULL)
continue;
kv = &layers[i].kvlist->pairs[0];
+ if (kv->key == NULL)
+ continue;
if (strcmp(kv->key, RTE_DEVARGS_KEY_BUS) == 0) {
bus = rte_bus_find_by_name(kv->value);
if (bus == NULL) {
}
}
+ /* Resolve devargs name. */
+ if (bus != NULL && bus->devargs_parse != NULL)
+ ret = bus->devargs_parse(devargs);
+ else if (layers[0].kvlist != NULL)
+ ret = devargs_bus_parse_default(devargs, layers[0].kvlist);
+
get_out:
for (i = 0; i < RTE_DIM(layers); i++) {
if (layers[i].kvlist)
*/
typedef int (*rte_bus_parse_t)(const char *name, void *addr);
+/**
+ * Parse bus part of the device arguments.
+ *
+ * The field name of the struct rte_devargs will be set.
+ *
+ * @param da
+ * Pointer to the devargs to parse.
+ *
+ * @return
+ * 0 on successful parsing, otherwise rte_errno is set.
+ * -EINVAL: on parsing error.
+ * -ENODEV: if no key matching a device argument is specified.
+ * -E2BIG: device name is too long.
+ */
+typedef int (*rte_bus_devargs_parse_t)(struct rte_devargs *da);
+
/**
* Device level DMA map function.
* After a successful call, the memory segment will be mapped to the
rte_bus_plug_t plug; /**< Probe single device for drivers */
rte_bus_unplug_t unplug; /**< Remove single device from driver */
rte_bus_parse_t parse; /**< Parse a device name */
+ rte_bus_devargs_parse_t devargs_parse; /**< Parse bus devargs */
rte_dev_dma_map_t dma_map; /**< DMA map for device in the bus */
rte_dev_dma_unmap_t dma_unmap; /**< DMA unmap for device in the bus */
struct rte_bus_conf conf; /**< Bus configuration */