The previous thread[1] discussing these controllers includes two patches but they seem to have been merged for the commit in a way that limits support to only Microsoft controllers. 3rd party Xbox 360 controllers have their own vendor and product IDs but use the same subclass and protocol as the Microsoft controllers.
Here's a diff based on the first patch that will match controllers and assign the report descriptor more generally using subclass/protocol rather than vendor/product. Is it more correct to create an array of known vendors/products and match against a call to usb_lookup()? [1] http://marc.info/?l=openbsd-tech&m=138229619410284&w=2 Thanks, Christian Index: uhidev.c =================================================================== RCS file: /cvs/src/sys/dev/usb/uhidev.c,v retrieving revision 1.70 diff -u -p -r1.70 uhidev.c --- uhidev.c 28 Feb 2015 08:42:41 -0000 1.70 +++ uhidev.c 5 Dec 2015 20:14:49 -0000 @@ -62,7 +62,10 @@ #ifndef SMALL_KERNEL /* Replacement report descriptors for devices shipped with broken ones */ #include <dev/usb/uhid_rdesc.h> -int uhidev_use_rdesc(struct uhidev_softc *, int, int, void **, int *); +int uhidev_use_rdesc(struct uhidev_softc *, usb_interface_descriptor_t *, + int, int, void **, int *); +#define UISUBCLASS_XBOX360_CONTROLLER 0x5d +#define UIPROTO_XBOX360_GAMEPAD 0x01 #endif /* !SMALL_KERNEL */ #define DEVNAME(sc) ((sc)->sc_dev.dv_xname) @@ -118,10 +121,10 @@ uhidev_match(struct device *parent, void if (id == NULL) return (UMATCH_NONE); #ifndef SMALL_KERNEL - if (uaa->vendor == USB_VENDOR_MICROSOFT && - uaa->product == USB_PRODUCT_MICROSOFT_XBOX360_CONTROLLER && - id->bInterfaceNumber == 0) - return (UMATCH_VENDOR_PRODUCT); + if (id->bInterfaceClass == UICLASS_VENDOR && + id->bInterfaceSubClass == UISUBCLASS_XBOX360_CONTROLLER && + id->bInterfaceProtocol == UIPROTO_XBOX360_GAMEPAD) + return (UMATCH_IFACECLASS_IFACESUBCLASS_IFACEPROTO); #endif /* !SMALL_KERNEL */ if (id->bInterfaceClass != UICLASS_HID) return (UMATCH_NONE); @@ -191,7 +194,7 @@ uhidev_attach(struct device *parent, str } #ifndef SMALL_KERNEL - if (uhidev_use_rdesc(sc, uaa->vendor, uaa->product, &desc, &size)) + if (uhidev_use_rdesc(sc, id, uaa->vendor, uaa->product, &desc, &size)) return; #endif /* !SMALL_KERNEL */ @@ -275,8 +278,8 @@ uhidev_attach(struct device *parent, str #ifndef SMALL_KERNEL int -uhidev_use_rdesc(struct uhidev_softc *sc, int vendor, int product, - void **descp, int *sizep) +uhidev_use_rdesc(struct uhidev_softc *sc, usb_interface_descriptor_t *id, + int vendor, int product, void **descp, int *sizep) { static uByte reportbuf[] = {2, 2}; const void *descptr = NULL; @@ -300,8 +303,9 @@ uhidev_use_rdesc(struct uhidev_softc *sc default: break; } - } else if (vendor == USB_VENDOR_MICROSOFT && - product == USB_PRODUCT_MICROSOFT_XBOX360_CONTROLLER) { + } else if ((id->bInterfaceClass == UICLASS_VENDOR && + id->bInterfaceSubClass == UISUBCLASS_XBOX360_CONTROLLER && + id->bInterfaceProtocol == UIPROTO_XBOX360_GAMEPAD)) { /* The Xbox 360 gamepad has no report descriptor. */ size = sizeof(uhid_xb360gp_report_descr); descptr = uhid_xb360gp_report_descr;