summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorJeremy Evans <jeremy@cvs.openbsd.org>2013-10-25 03:10:00 +0000
committerJeremy Evans <jeremy@cvs.openbsd.org>2013-10-25 03:10:00 +0000
commitea39bca214ca70ce731f26dc1bdb1ae4ddc5bdc7 (patch)
tree6431d11b5aca6f9e6433c11f6fb91b4979825935 /sys
parent7ba4dac18407abde24abc0a24cbebbfb180d9926 (diff)
Add support for Microsoft XBox 360 controller as a uhid. It doesn't use
the standard interface class and doesn't have a report descriptor, so use a manually created one. The controller shows up as multiple devices with different interface numbers, so only match the first one as a uhid. The controller shows up as both a uhid and a ugen. Rename ugraphire_rdesc.h to uhid_rdesc.h and add the manually created Xbox 360 report descriptor to the file. Add ifndef SMALL_KERNEL around the related blocks for the XBox 360 controller and Wacom Graphire, so this should actually shrink the ramdisks. Manual report descriptor taken from a 2005 FreeBSD commit. Much help from mpi@ for getting this suitable for commit to OpenBSD. OK mpi@
Diffstat (limited to 'sys')
-rw-r--r--sys/dev/usb/uhid_rdesc.h (renamed from sys/dev/usb/ugraphire_rdesc.h)100
-rw-r--r--sys/dev/usb/uhidev.c25
2 files changed, 120 insertions, 5 deletions
diff --git a/sys/dev/usb/ugraphire_rdesc.h b/sys/dev/usb/uhid_rdesc.h
index 0daa50c4380..ecf24a6238f 100644
--- a/sys/dev/usb/ugraphire_rdesc.h
+++ b/sys/dev/usb/uhid_rdesc.h
@@ -1,7 +1,9 @@
-/* $OpenBSD: ugraphire_rdesc.h,v 1.3 2006/01/06 03:36:32 brad Exp $ */
+/* $OpenBSD: uhid_rdesc.h,v 1.1 2013/10/25 03:09:59 jeremy Exp $ */
/* $NetBSD: ugraphire_rdesc.h,v 1.1 2000/12/29 01:47:49 augustss Exp $ */
+/* $FreeBSD: uxb360gp_rdesc.h,v 1.3 2008/05/24 18:35:55 ed Exp $ */
/*
* Copyright (c) 2000 Nick Hibma <n_hibma@freebsd.org>
+ * Copyright (c) 2005 Ed Schouten <ed@FreeBSD.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -175,3 +177,99 @@ static uByte uhid_graphire3_4x5_report_descr[] = {
0xc0 /* END_COLLECTION */
};
+/*
+ * The descriptor has no output report format, thus preventing you from
+ * controlling the LEDs and the built-in rumblers.
+ */
+static const uByte uhid_xb360gp_report_descr[] = {
+ 0x05, 0x01, /* USAGE PAGE (Generic Desktop) */
+ 0x09, 0x05, /* USAGE (Gamepad) */
+ 0xa1, 0x01, /* COLLECTION (Application) */
+ /* Unused */
+ 0x75, 0x08, /* REPORT SIZE (8) */
+ 0x95, 0x01, /* REPORT COUNT (1) */
+ 0x81, 0x01, /* INPUT (Constant) */
+ /* Byte count */
+ 0x75, 0x08, /* REPORT SIZE (8) */
+ 0x95, 0x01, /* REPORT COUNT (1) */
+ 0x05, 0x01, /* USAGE PAGE (Generic Desktop) */
+ 0x09, 0x3b, /* USAGE (Byte Count) */
+ 0x81, 0x01, /* INPUT (Constant) */
+ /* D-Pad */
+ 0x05, 0x01, /* USAGE PAGE (Generic Desktop) */
+ 0x09, 0x01, /* USAGE (Pointer) */
+ 0xa1, 0x00, /* COLLECTION (Physical) */
+ 0x75, 0x01, /* REPORT SIZE (1) */
+ 0x15, 0x00, /* LOGICAL MINIMUM (0) */
+ 0x25, 0x01, /* LOGICAL MAXIMUM (1) */
+ 0x35, 0x00, /* PHYSICAL MINIMUM (0) */
+ 0x45, 0x01, /* PHYSICAL MAXIMUM (1) */
+ 0x95, 0x04, /* REPORT COUNT (4) */
+ 0x05, 0x01, /* USAGE PAGE (Generic Desktop) */
+ 0x09, 0x90, /* USAGE (D-Pad Up) */
+ 0x09, 0x91, /* USAGE (D-Pad Down) */
+ 0x09, 0x93, /* USAGE (D-Pad Left) */
+ 0x09, 0x92, /* USAGE (D-Pad Right) */
+ 0x81, 0x02, /* INPUT (Data, Variable, Absolute) */
+ 0xc0, /* END COLLECTION */
+ /* Buttons 5-11 */
+ 0x75, 0x01, /* REPORT SIZE (1) */
+ 0x15, 0x00, /* LOGICAL MINIMUM (0) */
+ 0x25, 0x01, /* LOGICAL MAXIMUM (1) */
+ 0x35, 0x00, /* PHYSICAL MINIMUM (0) */
+ 0x45, 0x01, /* PHYSICAL MAXIMUM (1) */
+ 0x95, 0x07, /* REPORT COUNT (7) */
+ 0x05, 0x09, /* USAGE PAGE (Button) */
+ 0x09, 0x08, /* USAGE (Button 8) */
+ 0x09, 0x07, /* USAGE (Button 7) */
+ 0x09, 0x09, /* USAGE (Button 9) */
+ 0x09, 0x0a, /* USAGE (Button 10) */
+ 0x09, 0x05, /* USAGE (Button 5) */
+ 0x09, 0x06, /* USAGE (Button 6) */
+ 0x09, 0x0b, /* USAGE (Button 11) */
+ 0x81, 0x02, /* INPUT (Data, Variable, Absolute) */
+ /* Unused */
+ 0x75, 0x01, /* REPORT SIZE (1) */
+ 0x95, 0x01, /* REPORT COUNT (1) */
+ 0x81, 0x01, /* INPUT (Constant) */
+ /* Buttons 1-4 */
+ 0x75, 0x01, /* REPORT SIZE (1) */
+ 0x15, 0x00, /* LOGICAL MINIMUM (0) */
+ 0x25, 0x01, /* LOGICAL MAXIMUM (1) */
+ 0x35, 0x00, /* PHYSICAL MINIMUM (0) */
+ 0x45, 0x01, /* PHYSICAL MAXIMUM (1) */
+ 0x95, 0x04, /* REPORT COUNT (4) */
+ 0x05, 0x09, /* USAGE PAGE (Button) */
+ 0x19, 0x01, /* USAGE MINIMUM (Button 1) */
+ 0x29, 0x04, /* USAGE MAXIMUM (Button 4) */
+ 0x81, 0x02, /* INPUT (Data, Variable, Absolute) */
+ /* Triggers */
+ 0x75, 0x08, /* REPORT SIZE (8) */
+ 0x15, 0x00, /* LOGICAL MINIMUM (0) */
+ 0x26, 0xff, 0x00, /* LOGICAL MAXIMUM (255) */
+ 0x35, 0x00, /* PHYSICAL MINIMUM (0) */
+ 0x46, 0xff, 0x00, /* PHYSICAL MAXIMUM (255) */
+ 0x95, 0x02, /* REPORT SIZE (2) */
+ 0x05, 0x01, /* USAGE PAGE (Generic Desktop) */
+ 0x09, 0x32, /* USAGE (Z) */
+ 0x09, 0x35, /* USAGE (Rz) */
+ 0x81, 0x02, /* INPUT (Data, Variable, Absolute) */
+ /* Sticks */
+ 0x75, 0x10, /* REPORT SIZE (16) */
+ 0x16, 0x00, 0x80, /* LOGICAL MINIMUM (-32768) */
+ 0x26, 0xff, 0x7f, /* LOGICAL MAXIMUM (32767) */
+ 0x36, 0x00, 0x80, /* PHYSICAL MINIMUM (-32768) */
+ 0x46, 0xff, 0x7f, /* PHYSICAL MAXIMUM (32767) */
+ 0x95, 0x04, /* REPORT COUNT (4) */
+ 0x05, 0x01, /* USAGE PAGE (Generic Desktop) */
+ 0x09, 0x30, /* USAGE (X) */
+ 0x09, 0x31, /* USAGE (Y) */
+ 0x09, 0x33, /* USAGE (Rx) */
+ 0x09, 0x34, /* USAGE (Ry) */
+ 0x81, 0x02, /* INPUT (Data, Variable, Absolute) */
+ /* Unused */
+ 0x75, 0x30, /* REPORT SIZE (48) */
+ 0x95, 0x01, /* REPORT COUNT (1) */
+ 0x81, 0x01, /* INPUT (Constant) */
+ 0xc0, /* END COLLECTION */
+};
diff --git a/sys/dev/usb/uhidev.c b/sys/dev/usb/uhidev.c
index cd3f797773a..341d08e2aca 100644
--- a/sys/dev/usb/uhidev.c
+++ b/sys/dev/usb/uhidev.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: uhidev.c,v 1.46 2013/09/20 15:34:50 mpi Exp $ */
+/* $OpenBSD: uhidev.c,v 1.47 2013/10/25 03:09:59 jeremy Exp $ */
/* $NetBSD: uhidev.c,v 1.14 2003/03/11 16:44:00 augustss Exp $ */
/*
@@ -55,8 +55,10 @@
#include <dev/usb/uhidev.h>
-/* Report descriptor for broken Wacom Graphire */
-#include <dev/usb/ugraphire_rdesc.h>
+#ifndef SMALL_KERNEL
+/* Replacement report descriptors for devices shipped with broken ones */
+#include <dev/usb/uhid_rdesc.h>
+#endif /* !SMALL_KERNEL */
#ifdef UHIDEV_DEBUG
#define DPRINTF(x) do { if (uhidevdebug) printf x; } while (0)
@@ -99,7 +101,15 @@ uhidev_match(struct device *parent, void *match, void *aux)
if (uaa->iface == NULL)
return (UMATCH_NONE);
id = usbd_get_interface_descriptor(uaa->iface);
- if (id == NULL || id->bInterfaceClass != UICLASS_HID)
+ 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);
+#endif /* !SMALL_KERNEL */
+ if (id->bInterfaceClass != UICLASS_HID)
return (UMATCH_NONE);
if (usbd_get_quirks(uaa->device)->uq_flags & UQ_BAD_HID)
return (UMATCH_NONE);
@@ -180,6 +190,7 @@ uhidev_attach(struct device *parent, struct device *self, void *aux)
/* XXX need to extend this */
descptr = NULL;
+#ifndef SMALL_KERNEL
if (uaa->vendor == USB_VENDOR_WACOM) {
static uByte reportbuf[] = {2, 2, 2};
@@ -200,7 +211,13 @@ uhidev_attach(struct device *parent, struct device *self, void *aux)
/* Keep descriptor */
break;
}
+ } else if (uaa->vendor == USB_VENDOR_MICROSOFT &&
+ uaa->product == USB_PRODUCT_MICROSOFT_XBOX360_CONTROLLER) {
+ /* The Xbox 360 gamepad has no report descriptor. */
+ size = sizeof uhid_xb360gp_report_descr;
+ descptr = uhid_xb360gp_report_descr;
}
+#endif /* !SMALL_KERNEL */
if (descptr) {
desc = malloc(size, M_USBDEV, M_NOWAIT);