@@ -144,8 +144,7 @@ fs_bus_uninit(struct rte_eth_dev *dev)
int ret = 0;
FOREACH_SUBDEV_STATE(sdev, i, dev, DEV_PROBED) {
- sdev_ret = rte_eal_hotplug_remove(sdev->bus->name,
- sdev->dev->name);
+ sdev_ret = rte_dev_remove(sdev->dev);
if (sdev_ret) {
ERROR("Failed to remove requested device %s (err: %d)",
sdev->dev->name, sdev_ret);
@@ -282,8 +282,7 @@ fs_dev_remove(struct sub_device *sdev)
sdev->state = DEV_PROBED;
/* fallthrough */
case DEV_PROBED:
- ret = rte_eal_hotplug_remove(sdev->bus->name,
- sdev->dev->name);
+ ret = rte_dev_remove(sdev->dev);
if (ret) {
ERROR("Bus detach failed for sub_device %u",
SUB_ID(sdev));
@@ -129,46 +129,62 @@ int rte_eal_dev_detach(struct rte_device *dev)
int
rte_eal_hotplug_add(const char *busname, const char *devname,
- const char *devargs)
+ const char *drvargs)
{
- struct rte_bus *bus;
- struct rte_device *dev;
- struct rte_devargs *da;
int ret;
+ char *devargs = NULL;
+ int length;
- bus = rte_bus_find_by_name(busname);
- if (bus == NULL) {
- RTE_LOG(ERR, EAL, "Cannot find bus (%s)\n", busname);
- return -ENOENT;
- }
+ length = snprintf(NULL, 0, "%s:%s,%s", busname, devname, drvargs);
+ if (length < 0)
+ return -EINVAL;
+ devargs = malloc(length + 1);
+ if (devargs == NULL)
+ return -ENOMEM;
+ ret = snprintf(devargs, length + 1, "%s:%s,%s", busname, devname, drvargs);
+ if (ret < 0)
+ return -EINVAL;
- if (bus->plug == NULL) {
- RTE_LOG(ERR, EAL, "Function plug not supported by bus (%s)\n",
- bus->name);
- return -ENOTSUP;
- }
+ ret = rte_dev_probe(devargs);
+
+ free(devargs);
+ return ret;
+}
+
+int __rte_experimental
+rte_dev_probe(const char *devargs)
+{
+ struct rte_device *dev;
+ struct rte_devargs *da;
+ int ret;
da = calloc(1, sizeof(*da));
if (da == NULL)
return -ENOMEM;
- ret = rte_devargs_parsef(da, "%s:%s,%s",
- busname, devname, devargs);
+ ret = rte_devargs_parse(da, devargs);
if (ret)
goto err_devarg;
+ if (da->bus->plug == NULL) {
+ RTE_LOG(ERR, EAL, "Function plug not supported by bus (%s)\n",
+ da->bus->name);
+ ret = -ENOTSUP;
+ goto err_devarg;
+ }
+
ret = rte_devargs_insert(da);
if (ret)
goto err_devarg;
- ret = bus->scan();
+ ret = da->bus->scan();
if (ret)
goto err_devarg;
- dev = bus->find_device(NULL, cmp_dev_name, devname);
+ dev = da->bus->find_device(NULL, cmp_dev_name, da->name);
if (dev == NULL) {
RTE_LOG(ERR, EAL, "Cannot find device (%s)\n",
- devname);
+ da->name);
ret = -ENODEV;
goto err_devarg;
}
@@ -178,7 +194,7 @@ rte_eal_hotplug_add(const char *busname, const char *devname,
return -EEXIST;
}
- ret = bus->plug(dev);
+ ret = dev->bus->plug(dev);
if (ret) {
RTE_LOG(ERR, EAL, "Driver cannot attach the device (%s)\n",
dev->name);
@@ -197,9 +213,8 @@ rte_eal_hotplug_add(const char *busname, const char *devname,
int
rte_eal_hotplug_remove(const char *busname, const char *devname)
{
- struct rte_bus *bus;
struct rte_device *dev;
- int ret;
+ struct rte_bus *bus;
bus = rte_bus_find_by_name(busname);
if (bus == NULL) {
@@ -207,24 +222,32 @@ rte_eal_hotplug_remove(const char *busname, const char *devname)
return -ENOENT;
}
- if (bus->unplug == NULL) {
- RTE_LOG(ERR, EAL, "Function unplug not supported by bus (%s)\n",
- bus->name);
- return -ENOTSUP;
- }
-
dev = bus->find_device(NULL, cmp_dev_name, devname);
if (dev == NULL) {
RTE_LOG(ERR, EAL, "Cannot find plugged device (%s)\n", devname);
return -EINVAL;
}
+ return rte_dev_remove(dev);
+}
+
+int __rte_experimental
+rte_dev_remove(struct rte_device *dev)
+{
+ int ret;
+
if (dev->driver == NULL) {
RTE_LOG(ERR, EAL, "Device is already unplugged\n");
return -ENOENT;
}
- ret = bus->unplug(dev);
+ if (dev->bus->unplug == NULL) {
+ RTE_LOG(ERR, EAL, "Function unplug not supported by bus (%s)\n",
+ dev->bus->name);
+ return -ENOTSUP;
+ }
+
+ ret = dev->bus->unplug(dev);
if (ret)
RTE_LOG(ERR, EAL, "Driver cannot detach the device (%s)\n",
dev->name);
@@ -197,13 +197,26 @@ int rte_eal_dev_detach(struct rte_device *dev);
* @param devname
* The device name. Based on this device name, eal will identify a driver
* capable of handling it and pass it to the driver probing function.
- * @param devargs
+ * @param drvargs
* Device arguments to be passed to the driver.
* @return
* 0 on success, negative on error.
*/
int rte_eal_hotplug_add(const char *busname, const char *devname,
- const char *devargs);
+ const char *drvargs);
+
+/**
+ * @warning
+ * @b EXPERIMENTAL: this API may change without prior notice
+ *
+ * Add matching devices.
+ *
+ * @param devargs
+ * Device arguments including bus, class and driver properties.
+ * @return
+ * 0 on success, negative on error.
+ */
+int __rte_experimental rte_dev_probe(const char *devargs);
/**
* Hotplug remove a given device from a specific bus.
@@ -217,6 +230,19 @@ int rte_eal_hotplug_add(const char *busname, const char *devname,
*/
int rte_eal_hotplug_remove(const char *busname, const char *devname);
+/**
+ * @warning
+ * @b EXPERIMENTAL: this API may change without prior notice
+ *
+ * Remove one device.
+ *
+ * @param dev
+ * Data structure of the device to remove.
+ * @return
+ * 0 on success, negative on error.
+ */
+int __rte_experimental rte_dev_remove(struct rte_device *dev);
+
/**
* Device comparison function.
*
@@ -281,6 +281,8 @@ EXPERIMENTAL {
rte_dev_event_monitor_stop;
rte_dev_iterator_init;
rte_dev_iterator_next;
+ rte_dev_probe;
+ rte_dev_remove;
rte_devargs_add;
rte_devargs_dump;
rte_devargs_insert;