diff --git a/src/xrt/drivers/psmv/psmv_driver.c b/src/xrt/drivers/psmv/psmv_driver.c index 87352eca0..5887077b2 100644 --- a/src/xrt/drivers/psmv/psmv_driver.c +++ b/src/xrt/drivers/psmv/psmv_driver.c @@ -446,7 +446,7 @@ int psmv_found(struct xrt_prober *xp, struct xrt_prober_device **devices, size_t index, - struct xrt_device **out_xdev) + struct xrt_device **out_xdevs) { struct os_hid_device *hid = NULL; int ret; @@ -506,6 +506,6 @@ psmv_found(struct xrt_prober *xp, psmv_read_hid(psmv); // And finally done - *out_xdev = &psmv->base; - return 0; + *out_xdevs = &psmv->base; + return 1; } diff --git a/src/xrt/drivers/psmv/psmv_interface.h b/src/xrt/drivers/psmv/psmv_interface.h index 3a1de60a4..5e3bd5b7b 100644 --- a/src/xrt/drivers/psmv/psmv_interface.h +++ b/src/xrt/drivers/psmv/psmv_interface.h @@ -33,7 +33,7 @@ int psmv_found(struct xrt_prober *xp, struct xrt_prober_device **devices, size_t index, - struct xrt_device **out_xdev); + struct xrt_device **out_xdevs); /*! * @dir drivers/psmv diff --git a/src/xrt/include/xrt/xrt_prober.h b/src/xrt/include/xrt/xrt_prober.h index 4aa06c428..e0c8a8698 100644 --- a/src/xrt/include/xrt/xrt_prober.h +++ b/src/xrt/include/xrt/xrt_prober.h @@ -27,6 +27,14 @@ extern "C" { struct xrt_prober; struct xrt_prober_device; +/*! + * The maximum number of devices that a single "found" function called by the + * prober can create per-call. + * + * @ingroup xrt_iface + */ +#define XRT_MAX_DEVICES_PER_PROBE 16 + /*! * Entry for a single device. * @@ -40,7 +48,7 @@ struct xrt_prober_entry int (*found)(struct xrt_prober *xp, struct xrt_prober_device **devices, size_t index, - struct xrt_device **out_xdev); + struct xrt_device **out_xdevs); const char *name; }; diff --git a/src/xrt/state_trackers/prober/p_prober.c b/src/xrt/state_trackers/prober/p_prober.c index 632f5061e..aaf761d85 100644 --- a/src/xrt/state_trackers/prober/p_prober.c +++ b/src/xrt/state_trackers/prober/p_prober.c @@ -444,14 +444,28 @@ select_device(struct xrt_prober* xp, continue; } - struct xrt_device* xdev = NULL; - entry->found(xp, dev_list, i, &xdev); + struct xrt_device* + new_xdevs[XRT_MAX_DEVICES_PER_PROBE] = {NULL}; + int num_found = + entry->found(xp, dev_list, i, &(new_xdevs[0])); - if (xdev == NULL) { + if (num_found <= 0) { continue; } - - handle_found_device(p, xdevs, num_xdevs, xdev); + for (int created_idx = 0; created_idx < num_found; + ++created_idx) { + if (new_xdevs[created_idx] == NULL) { + P_DEBUG( + p, + "Leaving device creation loop " + "early: found function reported %i " + "created, but only %i non-null", + num_found, created_idx); + continue; + } + handle_found_device(p, xdevs, num_xdevs, + new_xdevs[created_idx]); + } } } diff --git a/src/xrt/targets/common/target_lists.c b/src/xrt/targets/common/target_lists.c index 7dd609e3b..1d1885206 100644 --- a/src/xrt/targets/common/target_lists.c +++ b/src/xrt/targets/common/target_lists.c @@ -34,11 +34,13 @@ * - `struct xrt_prober *xp` * - `struct xrt_prober_device **devices` * - `size_t index` - * - `struct xrt_device **out_xdev` + * - `struct xrt_device **out_xdevs` (an array of XRT_MAX_DEVICES_PER_PROBE + * xrt_device pointers) * * It is called when devices[index] match the VID and PID in the list. - * It should return 0 if it decides not to create any devices, or 1 if it - * creates one: it should assign *out_xdev to the created device. + * It should return 0 if it decides not to create any devices, negative on + * error, and the number of devices created if it creates one or more: it should + * assign sequential elements of out_xdevs to the created devices. */ struct xrt_prober_entry target_entry_list[] = { #ifdef XRT_BUILD_PSVR