| 939 | } |
| 940 | |
| 941 | int |
| 942 | rte_bbdev_callback_register(uint16_t dev_id, enum rte_bbdev_event_type event, |
| 943 | rte_bbdev_cb_fn cb_fn, void *cb_arg) |
| 944 | { |
| 945 | struct rte_bbdev_callback *user_cb; |
| 946 | struct rte_bbdev *dev = get_dev(dev_id); |
| 947 | VALID_DEV_OR_RET_ERR(dev, dev_id); |
| 948 | |
| 949 | if (event >= RTE_BBDEV_EVENT_MAX) { |
| 950 | rte_bbdev_log(ERR, |
| 951 | "Invalid event type (%u), should be less than %u", |
| 952 | event, RTE_BBDEV_EVENT_MAX); |
| 953 | return -EINVAL; |
| 954 | } |
| 955 | |
| 956 | if (cb_fn == NULL) { |
| 957 | rte_bbdev_log(ERR, "NULL callback function"); |
| 958 | return -EINVAL; |
| 959 | } |
| 960 | |
| 961 | rte_spinlock_lock(&rte_bbdev_cb_lock); |
| 962 | |
| 963 | TAILQ_FOREACH(user_cb, &(dev->list_cbs), next) { |
| 964 | if (user_cb->cb_fn == cb_fn && |
| 965 | user_cb->cb_arg == cb_arg && |
| 966 | user_cb->event == event) |
| 967 | break; |
| 968 | } |
| 969 | |
| 970 | /* create a new callback. */ |
| 971 | if (user_cb == NULL) { |
| 972 | user_cb = rte_zmalloc("INTR_USER_CALLBACK", |
| 973 | sizeof(struct rte_bbdev_callback), 0); |
| 974 | if (user_cb != NULL) { |
| 975 | user_cb->cb_fn = cb_fn; |
| 976 | user_cb->cb_arg = cb_arg; |
| 977 | user_cb->event = event; |
| 978 | TAILQ_INSERT_TAIL(&(dev->list_cbs), user_cb, next); |
| 979 | } |
| 980 | } |
| 981 | |
| 982 | rte_spinlock_unlock(&rte_bbdev_cb_lock); |
| 983 | return (user_cb == NULL) ? -ENOMEM : 0; |
| 984 | } |
| 985 | |
| 986 | int |
| 987 | rte_bbdev_callback_unregister(uint16_t dev_id, enum rte_bbdev_event_type event, |