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. */
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;