[haiku-commits] r41017 - haiku/trunk/src/add-ons/kernel/drivers/input/usb_hid

  • From: mmlr@xxxxxxxx
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Thu, 17 Mar 2011 23:21:56 +0100 (CET)

Author: mmlr
Date: 2011-03-17 23:21:55 +0100 (Thu, 17 Mar 2011)
New Revision: 41017
Changeset: https://dev.haiku-os.org/changeset/41017

Added:
   haiku/trunk/src/add-ons/kernel/drivers/input/usb_hid/QuirkyDevices.h
Modified:
   haiku/trunk/src/add-ons/kernel/drivers/input/usb_hid/HIDDevice.cpp
Log:
Add a way to override report descriptors with fixed ones based on vendor and
product id. Currently the list only has an example entry.


Modified: haiku/trunk/src/add-ons/kernel/drivers/input/usb_hid/HIDDevice.cpp
===================================================================
--- haiku/trunk/src/add-ons/kernel/drivers/input/usb_hid/HIDDevice.cpp  
2011-03-17 21:41:44 UTC (rev 41016)
+++ haiku/trunk/src/add-ons/kernel/drivers/input/usb_hid/HIDDevice.cpp  
2011-03-17 22:21:55 UTC (rev 41017)
@@ -11,6 +11,7 @@
 #include "HIDDevice.h"
 #include "HIDReport.h"
 #include "ProtocolHandler.h"
+#include "QuirkyDevices.h"
 
 #include <usb/USB_hid.h>
 
@@ -36,55 +37,78 @@
                fProtocolHandlerCount(0),
                fProtocolHandlers(NULL)
 {
-       // read HID descriptor
-       size_t descriptorLength = sizeof(usb_hid_descriptor);
-       usb_hid_descriptor *hidDescriptor
-               = (usb_hid_descriptor *)malloc(descriptorLength);
-       if (hidDescriptor == NULL) {
-               TRACE_ALWAYS("failed to allocate buffer for hid descriptor\n");
-               fStatus = B_NO_MEMORY;
-               return;
+       uint8 *reportDescriptor = NULL;
+       size_t descriptorLength = 0;
+       bool isQuirky = false;
+
+       const usb_device_descriptor *deviceDescriptor
+               = gUSBModule->get_device_descriptor(device);
+
+       // check for quirky devices first and don't bother in that case
+       for (int32 i = 0; i < sQuirkyDeviceCount; i++) {
+               usb_hid_quirky_device &quirky = sQuirkyDevices[i];
+               if (deviceDescriptor->vendor_id == quirky.vendor_id
+                       && deviceDescriptor->product_id == quirky.product_id) {
+                       reportDescriptor = (uint8 *)quirky.fixed_descriptor;
+                       descriptorLength = quirky.descriptor_length;
+                       isQuirky = true;
+                       break;
+               }
        }
 
-       status_t result = gUSBModule->send_request(device,
-               USB_REQTYPE_INTERFACE_IN | USB_REQTYPE_STANDARD,
-               USB_REQUEST_GET_DESCRIPTOR,
-               B_USB_HID_DESCRIPTOR_HID << 8, interfaceIndex, descriptorLength,
-               hidDescriptor, &descriptorLength);
+       if (!isQuirky) {
+               // conforming device, read HID and report descriptors
+               descriptorLength = sizeof(usb_hid_descriptor);
+               usb_hid_descriptor *hidDescriptor
+                       = (usb_hid_descriptor *)malloc(descriptorLength);
+               if (hidDescriptor == NULL) {
+                       TRACE_ALWAYS("failed to allocate buffer for hid 
descriptor\n");
+                       fStatus = B_NO_MEMORY;
+                       return;
+               }
 
-       TRACE("get hid descriptor: result: 0x%08lx; length: %lu\n", result,
-               descriptorLength);
-       if (result == B_OK)
-               descriptorLength = 
hidDescriptor->descriptor_info[0].descriptor_length;
-       else
-               descriptorLength = 256; /* XXX */
-       free(hidDescriptor);
+               status_t result = gUSBModule->send_request(device,
+                       USB_REQTYPE_INTERFACE_IN | USB_REQTYPE_STANDARD,
+                       USB_REQUEST_GET_DESCRIPTOR,
+                       B_USB_HID_DESCRIPTOR_HID << 8, interfaceIndex, 
descriptorLength,
+                       hidDescriptor, &descriptorLength);
 
-       uint8 *reportDescriptor = (uint8 *)malloc(descriptorLength);
-       if (reportDescriptor == NULL) {
-               TRACE_ALWAYS("failed to allocate buffer for report 
descriptor\n");
-               fStatus = B_NO_MEMORY;
-               return;
-       }
+               TRACE("get hid descriptor: result: 0x%08lx; length: %lu\n", 
result,
+                       descriptorLength);
+               if (result == B_OK) {
+                       descriptorLength
+                               = 
hidDescriptor->descriptor_info[0].descriptor_length;
+               } else
+                       descriptorLength = 256; /* XXX */
 
-       result = gUSBModule->send_request(device,
-               USB_REQTYPE_INTERFACE_IN | USB_REQTYPE_STANDARD,
-               USB_REQUEST_GET_DESCRIPTOR,
-               B_USB_HID_DESCRIPTOR_REPORT << 8, interfaceIndex, 
descriptorLength,
-               reportDescriptor, &descriptorLength);
+               free(hidDescriptor);
 
-       TRACE("get report descriptor: result: 0x%08lx; length: %lu\n", result,
-               descriptorLength);
-       if (result != B_OK) {
-               TRACE_ALWAYS("failed tot get report descriptor\n");
-               free(reportDescriptor);
-               return;
+               reportDescriptor = (uint8 *)malloc(descriptorLength);
+               if (reportDescriptor == NULL) {
+                       TRACE_ALWAYS("failed to allocate buffer for report 
descriptor\n");
+                       fStatus = B_NO_MEMORY;
+                       return;
+               }
+
+               result = gUSBModule->send_request(device,
+                       USB_REQTYPE_INTERFACE_IN | USB_REQTYPE_STANDARD,
+                       USB_REQUEST_GET_DESCRIPTOR,
+                       B_USB_HID_DESCRIPTOR_REPORT << 8, interfaceIndex, 
descriptorLength,
+                       reportDescriptor, &descriptorLength);
+
+               TRACE("get report descriptor: result: 0x%08lx; length: %lu\n", 
result,
+                       descriptorLength);
+               if (result != B_OK) {
+                       TRACE_ALWAYS("failed tot get report descriptor\n");
+                       free(reportDescriptor);
+                       return;
+               }
+       } else {
+               TRACE_ALWAYS("found quirky device, using patched descriptor\n");
        }
 
 #if 1
        // save report descriptor for troubleshooting
-       const usb_device_descriptor *deviceDescriptor
-               = gUSBModule->get_device_descriptor(device);
        char outputFile[128];
        sprintf(outputFile, "/tmp/usb_hid_report_descriptor_%04x_%04x_%lu.bin",
                deviceDescriptor->vendor_id, deviceDescriptor->product_id,
@@ -96,8 +120,11 @@
        }
 #endif
 
-       result = fParser.ParseReportDescriptor(reportDescriptor, 
descriptorLength);
-       free(reportDescriptor);
+       status_t result = fParser.ParseReportDescriptor(reportDescriptor,
+               descriptorLength);
+       if (!isQuirky)
+               free(reportDescriptor);
+
        if (result != B_OK) {
                TRACE_ALWAYS("parsing the report descriptor failed\n");
                fStatus = result;

Added: haiku/trunk/src/add-ons/kernel/drivers/input/usb_hid/QuirkyDevices.h
===================================================================
--- haiku/trunk/src/add-ons/kernel/drivers/input/usb_hid/QuirkyDevices.h        
                        (rev 0)
+++ haiku/trunk/src/add-ons/kernel/drivers/input/usb_hid/QuirkyDevices.h        
2011-03-17 22:21:55 UTC (rev 41017)
@@ -0,0 +1,27 @@
+/*
+ * Copyright 2011 Michael Lotz <mmlr@xxxxxxxx>
+ * Distributed under the terms of the MIT license.
+ */
+#ifndef USB_HID_QUIRKY_DEVICES
+#define USB_HID_QUIRKY_DEVICES
+
+static uint8 sDescriptorExample[] = { 0x00, 0x00 };
+
+struct usb_hid_quirky_device {
+       uint16                  vendor_id;
+       uint16                  product_id;
+       size_t                  descriptor_length;
+       const uint8 *   fixed_descriptor;
+};
+
+#define ADD_QUIRKY_DEVICE(vendorID, productID, descriptor) \
+       { vendorID, productID, sizeof(descriptor), descriptor }
+
+static usb_hid_quirky_device sQuirkyDevices[] = {
+       ADD_QUIRKY_DEVICE(0xffff, 0xffff, sDescriptorExample)
+};
+
+static int32 sQuirkyDeviceCount
+       = sizeof(sQuirkyDevices) / sizeof(sQuirkyDevices[0]);
+
+#endif // USB_HID_QUIRKY_DEVICES


Other related posts:

  • » [haiku-commits] r41017 - haiku/trunk/src/add-ons/kernel/drivers/input/usb_hid - mmlr