On 05/12/15(Sat) 15:22, Christian Heckendorf wrote:
> 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()?

It's fine since the same check is used in uhidev_use_rdesc().

Could you try this on a Microsoft controller?  Does it still work?
Jeremy could you check this out?

> 
> [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;
> 

Reply via email to