+static inline struct rte_eth_dev *
+fs_dev(struct sub_device *sdev) {
+ return &rte_eth_devices[sdev->fs_port_id];
+}
+
+/*
+ * Lock hot-plug mutex.
+ * is_alarm means that the caller is, for sure, the hot-plug alarm mechanism.
+ */
+static inline int
+fs_lock(struct rte_eth_dev *dev, unsigned int is_alarm)
+{
+ int ret;
+
+ if (is_alarm) {
+ ret = pthread_mutex_trylock(&PRIV(dev)->hotplug_mutex);
+ if (ret) {
+ DEBUG("Hot-plug mutex lock trying failed(%s), will try"
+ " again later...", strerror(ret));
+ return ret;
+ }
+ PRIV(dev)->alarm_lock = 1;
+ } else {
+ ret = pthread_mutex_lock(&PRIV(dev)->hotplug_mutex);
+ if (ret) {
+ ERROR("Cannot lock mutex(%s)", strerror(ret));
+ return ret;
+ }
+ }
+ return ret;
+}
+
+/*
+ * Unlock hot-plug mutex.
+ * is_alarm means that the caller is, for sure, the hot-plug alarm mechanism.
+ */
+static inline void
+fs_unlock(struct rte_eth_dev *dev, unsigned int is_alarm)
+{
+ int ret;
+
+ if (is_alarm) {
+ RTE_ASSERT(PRIV(dev)->alarm_lock == 1);
+ PRIV(dev)->alarm_lock = 0;
+ }
+ ret = pthread_mutex_unlock(&PRIV(dev)->hotplug_mutex);
+ if (ret)
+ ERROR("Cannot unlock hot-plug mutex(%s)", strerror(ret));
+}
+
+/*
+ * Switch emitting device.
+ * If banned is set, banned must not be considered for
+ * the role of emitting device.
+ */
+static inline void
+fs_switch_dev(struct rte_eth_dev *dev,
+ struct sub_device *banned)
+{
+ struct sub_device *txd;
+ enum dev_state req_state;
+
+ req_state = PRIV(dev)->state;
+ txd = TX_SUBDEV(dev);
+ if (PREFERRED_SUBDEV(dev)->state >= req_state &&
+ PREFERRED_SUBDEV(dev) != banned) {
+ if (txd != PREFERRED_SUBDEV(dev) &&
+ (txd == NULL ||
+ (req_state == DEV_STARTED) ||
+ (txd && txd->state < DEV_STARTED))) {
+ DEBUG("Switching tx_dev to preferred sub_device");
+ PRIV(dev)->subs_tx = 0;
+ }
+ } else if ((txd && txd->state < req_state) ||
+ txd == NULL ||
+ txd == banned) {
+ struct sub_device *sdev = NULL;
+ uint8_t i;
+
+ /* Using acceptable device */
+ FOREACH_SUBDEV_STATE(sdev, i, dev, req_state) {
+ if (sdev == banned)
+ continue;
+ DEBUG("Switching tx_dev to sub_device %d",
+ i);
+ PRIV(dev)->subs_tx = i;
+ break;
+ }
+ if (i >= PRIV(dev)->subs_tail || sdev == NULL) {
+ DEBUG("No device ready, deactivating tx_dev");
+ PRIV(dev)->subs_tx = PRIV(dev)->subs_tail;
+ }
+ } else {
+ return;
+ }
+ failsafe_set_burst_fn(dev, 0);
+ rte_wmb();
+}
+
+/*
+ * Adjust error value and rte_errno to the fail-safe actual error value.
+ */
+static inline int
+fs_err(struct sub_device *sdev, int err)
+{
+ /* A device removal shouldn't be reported as an error. */
+ if (sdev->remove == 1 || err == -EIO)
+ return rte_errno = 0;
+ return err;
+}
+#endif /* _ETH_FAILSAFE_PRIVATE_H_ */