1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright 2017 6WIND S.A.
3 * Copyright 2017 Mellanox Technologies, Ltd
6 #include <rte_malloc.h>
8 #include "failsafe_private.h"
11 fs_ethdev_portid_get(const char *name, uint16_t *port_id)
17 DEBUG("Null pointer is specified\n");
21 for (pid = 0; pid < RTE_MAX_ETHPORTS; pid++) {
22 if (rte_eth_dev_is_valid_port(pid) &&
23 !strncmp(name, rte_eth_devices[pid].device->name, len)) {
32 fs_bus_init(struct rte_eth_dev *dev)
34 struct sub_device *sdev;
35 struct rte_devargs *da;
40 FOREACH_SUBDEV(sdev, i, dev) {
41 if (sdev->state != DEV_PARSED)
44 if (fs_ethdev_portid_get(da->name, &pid) != 0) {
45 struct rte_eth_dev_owner pid_owner;
47 ret = rte_eal_hotplug_add(da->bus->name,
51 ERROR("sub_device %d probe failed %s%s%s", i,
53 rte_errno ? strerror(rte_errno) : "",
54 rte_errno ? ")" : "");
57 if (fs_ethdev_portid_get(da->name, &pid) != 0) {
58 ERROR("sub_device %d init went wrong", i);
62 * The NEW callback tried to take ownership, check
63 * whether it succeed or didn't.
65 rte_eth_dev_owner_get(pid, &pid_owner);
66 if (pid_owner.id != PRIV(dev)->my_owner.id) {
67 INFO("sub_device %d owner(%s_%016"PRIX64") is not my,"
68 " owner(%s_%016"PRIX64"), will try again later",
69 i, pid_owner.name, pid_owner.id,
70 PRIV(dev)->my_owner.name,
71 PRIV(dev)->my_owner.id);
75 /* The sub-device port was found. */
76 char devstr[DEVARGS_MAXLEN] = "";
77 struct rte_devargs *probed_da =
78 rte_eth_devices[pid].device->devargs;
80 /* Take control of probed device. */
82 memset(da, 0, sizeof(*da));
83 if (probed_da != NULL)
84 snprintf(devstr, sizeof(devstr), "%s,%s",
85 probed_da->name, probed_da->args);
87 snprintf(devstr, sizeof(devstr), "%s",
88 rte_eth_devices[pid].device->name);
89 ret = rte_devargs_parse(da, "%s", devstr);
91 ERROR("Probed devargs parsing failed with code"
95 INFO("Taking control of a probed sub device"
96 " %d named %s", i, da->name);
97 ret = rte_eth_dev_owner_set(pid, &PRIV(dev)->my_owner);
99 INFO("sub_device %d owner set failed (%s), "
100 "will try again later", i, strerror(-ret));
102 } else if (strncmp(rte_eth_devices[pid].device->name,
103 da->name, strlen(da->name)) != 0) {
105 * The device probably was removed and its port
106 * id was reallocated before ownership set.
108 rte_eth_dev_owner_unset(pid,
109 PRIV(dev)->my_owner.id);
110 INFO("sub_device %d was removed before taking"
111 " ownership, will try again later", i);
115 ETH(sdev) = &rte_eth_devices[pid];
118 sdev->dev = ETH(sdev)->device;
119 sdev->state = DEV_PROBED;
125 failsafe_eal_init(struct rte_eth_dev *dev)
129 ret = fs_bus_init(dev);
132 if (PRIV(dev)->state < DEV_PROBED)
133 PRIV(dev)->state = DEV_PROBED;
134 fs_switch_dev(dev, NULL);
139 fs_bus_uninit(struct rte_eth_dev *dev)
141 struct sub_device *sdev = NULL;
146 FOREACH_SUBDEV_STATE(sdev, i, dev, DEV_PROBED) {
147 sdev_ret = rte_eal_hotplug_remove(sdev->bus->name,
150 ERROR("Failed to remove requested device %s (err: %d)",
151 sdev->dev->name, sdev_ret);
154 sdev->state = DEV_PROBED - 1;
160 failsafe_eal_uninit(struct rte_eth_dev *dev)
164 ret = fs_bus_uninit(dev);
165 PRIV(dev)->state = DEV_PROBED - 1;