+int
+rte_vdev_add_custom_scan(rte_vdev_scan_callback callback, void *user_arg)
+{
+ struct vdev_custom_scan *custom_scan;
+
+ rte_spinlock_lock(&vdev_custom_scan_lock);
+
+ /* check if already registered */
+ TAILQ_FOREACH(custom_scan, &vdev_custom_scans, next) {
+ if (custom_scan->callback == callback &&
+ custom_scan->user_arg == user_arg)
+ break;
+ }
+
+ if (custom_scan == NULL) {
+ custom_scan = malloc(sizeof(struct vdev_custom_scan));
+ if (custom_scan != NULL) {
+ custom_scan->callback = callback;
+ custom_scan->user_arg = user_arg;
+ TAILQ_INSERT_TAIL(&vdev_custom_scans, custom_scan, next);
+ }
+ }
+
+ rte_spinlock_unlock(&vdev_custom_scan_lock);
+
+ return (custom_scan == NULL) ? -1 : 0;
+}
+
+int
+rte_vdev_remove_custom_scan(rte_vdev_scan_callback callback, void *user_arg)
+{
+ struct vdev_custom_scan *custom_scan, *tmp_scan;
+
+ rte_spinlock_lock(&vdev_custom_scan_lock);
+ TAILQ_FOREACH_SAFE(custom_scan, &vdev_custom_scans, next, tmp_scan) {
+ if (custom_scan->callback != callback ||
+ (custom_scan->user_arg != (void *)-1 &&
+ custom_scan->user_arg != user_arg))
+ continue;
+ TAILQ_REMOVE(&vdev_custom_scans, custom_scan, next);
+ free(custom_scan);
+ }
+ rte_spinlock_unlock(&vdev_custom_scan_lock);
+
+ return 0;
+}
+