1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright 2017 6WIND S.A.
3 * Copyright 2017 Mellanox Technologies, Ltd
6 #include <rte_string_fns.h>
7 #include <rte_malloc.h>
9 #include "failsafe_private.h"
12 fs_ethdev_portid_get(const char *name, uint16_t *port_id)
18 DEBUG("Null pointer is specified\n");
22 for (pid = 0; pid < RTE_MAX_ETHPORTS; pid++) {
23 if (rte_eth_dev_is_valid_port(pid) &&
24 !strncmp(name, rte_eth_devices[pid].device->name, len)) {
33 fs_bus_init(struct rte_eth_dev *dev)
35 struct sub_device *sdev;
36 struct rte_devargs *da;
41 FOREACH_SUBDEV(sdev, i, dev) {
42 if (sdev->state != DEV_PARSED)
45 if (fs_ethdev_portid_get(da->name, &pid) != 0) {
46 struct rte_eth_dev_owner pid_owner;
48 ret = rte_eal_hotplug_add(da->bus->name,
52 ERROR("sub_device %d probe failed %s%s%s", i,
54 rte_errno ? strerror(rte_errno) : "",
55 rte_errno ? ")" : "");
58 if (fs_ethdev_portid_get(da->name, &pid) != 0) {
59 ERROR("sub_device %d init went wrong", i);
63 * The NEW callback tried to take ownership, check
64 * whether it succeed or didn't.
66 rte_eth_dev_owner_get(pid, &pid_owner);
67 if (pid_owner.id != PRIV(dev)->my_owner.id) {
68 INFO("sub_device %d owner(%s_%016"PRIX64") is not my,"
69 " owner(%s_%016"PRIX64"), will try again later",
70 i, pid_owner.name, pid_owner.id,
71 PRIV(dev)->my_owner.name,
72 PRIV(dev)->my_owner.id);
76 /* The sub-device port was found. */
77 char devstr[DEVARGS_MAXLEN] = "";
78 struct rte_devargs *probed_da =
79 rte_eth_devices[pid].device->devargs;
81 /* Take control of probed device. */
82 rte_devargs_reset(da);
83 memset(da, 0, sizeof(*da));
84 if (probed_da != NULL)
85 snprintf(devstr, sizeof(devstr), "%s,%s",
86 probed_da->name, probed_da->args);
89 rte_eth_devices[pid].device->name,
91 ret = rte_devargs_parse(da, devstr);
93 ERROR("Probed devargs parsing failed with code"
97 INFO("Taking control of a probed sub device"
98 " %d named %s", i, da->name);
99 ret = rte_eth_dev_owner_set(pid, &PRIV(dev)->my_owner);
101 INFO("sub_device %d owner set failed (%s), "
102 "will try again later", i, strerror(-ret));
104 } else if (strncmp(rte_eth_devices[pid].device->name,
105 da->name, strlen(da->name)) != 0) {
107 * The device probably was removed and its port
108 * id was reallocated before ownership set.
110 rte_eth_dev_owner_unset(pid,
111 PRIV(dev)->my_owner.id);
112 INFO("sub_device %d was removed before taking"
113 " ownership, will try again later", i);
117 sdev->sdev_port_id = pid;
119 sdev->fs_port_id = dev->data->port_id;
120 sdev->dev = ETH(sdev)->device;
121 sdev->state = DEV_PROBED;
127 failsafe_eal_init(struct rte_eth_dev *dev)
131 ret = fs_bus_init(dev);
134 if (PRIV(dev)->state < DEV_PROBED)
135 PRIV(dev)->state = DEV_PROBED;
136 fs_switch_dev(dev, NULL);
141 fs_bus_uninit(struct rte_eth_dev *dev)
143 struct sub_device *sdev = NULL;
148 FOREACH_SUBDEV_STATE(sdev, i, dev, DEV_PROBED) {
149 sdev_ret = rte_dev_remove(sdev->dev);
151 ERROR("Failed to remove requested device %s (err: %d)",
152 sdev->dev->name, sdev_ret);
155 sdev->state = DEV_PROBED - 1;
161 failsafe_eal_uninit(struct rte_eth_dev *dev)
165 ret = fs_bus_uninit(dev);
166 PRIV(dev)->state = DEV_PROBED - 1;