Add a way to override report descriptors with fixed ones based on vendor and
product id. Currently the list only has an example entry. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@41017 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
02845142e3
commit
6339610f44
@ -11,6 +11,7 @@
|
|||||||
#include "HIDDevice.h"
|
#include "HIDDevice.h"
|
||||||
#include "HIDReport.h"
|
#include "HIDReport.h"
|
||||||
#include "ProtocolHandler.h"
|
#include "ProtocolHandler.h"
|
||||||
|
#include "QuirkyDevices.h"
|
||||||
|
|
||||||
#include <usb/USB_hid.h>
|
#include <usb/USB_hid.h>
|
||||||
|
|
||||||
@ -36,55 +37,78 @@ HIDDevice::HIDDevice(usb_device device, const usb_configuration_info *config,
|
|||||||
fProtocolHandlerCount(0),
|
fProtocolHandlerCount(0),
|
||||||
fProtocolHandlers(NULL)
|
fProtocolHandlers(NULL)
|
||||||
{
|
{
|
||||||
// read HID descriptor
|
uint8 *reportDescriptor = NULL;
|
||||||
size_t descriptorLength = sizeof(usb_hid_descriptor);
|
size_t descriptorLength = 0;
|
||||||
usb_hid_descriptor *hidDescriptor
|
bool isQuirky = false;
|
||||||
= (usb_hid_descriptor *)malloc(descriptorLength);
|
|
||||||
if (hidDescriptor == NULL) {
|
const usb_device_descriptor *deviceDescriptor
|
||||||
TRACE_ALWAYS("failed to allocate buffer for hid descriptor\n");
|
= gUSBModule->get_device_descriptor(device);
|
||||||
fStatus = B_NO_MEMORY;
|
|
||||||
return;
|
// 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,
|
if (!isQuirky) {
|
||||||
USB_REQTYPE_INTERFACE_IN | USB_REQTYPE_STANDARD,
|
// conforming device, read HID and report descriptors
|
||||||
USB_REQUEST_GET_DESCRIPTOR,
|
descriptorLength = sizeof(usb_hid_descriptor);
|
||||||
B_USB_HID_DESCRIPTOR_HID << 8, interfaceIndex, descriptorLength,
|
usb_hid_descriptor *hidDescriptor
|
||||||
hidDescriptor, &descriptorLength);
|
= (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,
|
status_t result = gUSBModule->send_request(device,
|
||||||
descriptorLength);
|
USB_REQTYPE_INTERFACE_IN | USB_REQTYPE_STANDARD,
|
||||||
if (result == B_OK)
|
USB_REQUEST_GET_DESCRIPTOR,
|
||||||
descriptorLength = hidDescriptor->descriptor_info[0].descriptor_length;
|
B_USB_HID_DESCRIPTOR_HID << 8, interfaceIndex, descriptorLength,
|
||||||
else
|
hidDescriptor, &descriptorLength);
|
||||||
descriptorLength = 256; /* XXX */
|
|
||||||
free(hidDescriptor);
|
|
||||||
|
|
||||||
uint8 *reportDescriptor = (uint8 *)malloc(descriptorLength);
|
TRACE("get hid descriptor: result: 0x%08lx; length: %lu\n", result,
|
||||||
if (reportDescriptor == NULL) {
|
descriptorLength);
|
||||||
TRACE_ALWAYS("failed to allocate buffer for report descriptor\n");
|
if (result == B_OK) {
|
||||||
fStatus = B_NO_MEMORY;
|
descriptorLength
|
||||||
return;
|
= hidDescriptor->descriptor_info[0].descriptor_length;
|
||||||
}
|
} else
|
||||||
|
descriptorLength = 256; /* XXX */
|
||||||
|
|
||||||
result = gUSBModule->send_request(device,
|
free(hidDescriptor);
|
||||||
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,
|
reportDescriptor = (uint8 *)malloc(descriptorLength);
|
||||||
descriptorLength);
|
if (reportDescriptor == NULL) {
|
||||||
if (result != B_OK) {
|
TRACE_ALWAYS("failed to allocate buffer for report descriptor\n");
|
||||||
TRACE_ALWAYS("failed tot get report descriptor\n");
|
fStatus = B_NO_MEMORY;
|
||||||
free(reportDescriptor);
|
return;
|
||||||
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
|
#if 1
|
||||||
// save report descriptor for troubleshooting
|
// save report descriptor for troubleshooting
|
||||||
const usb_device_descriptor *deviceDescriptor
|
|
||||||
= gUSBModule->get_device_descriptor(device);
|
|
||||||
char outputFile[128];
|
char outputFile[128];
|
||||||
sprintf(outputFile, "/tmp/usb_hid_report_descriptor_%04x_%04x_%lu.bin",
|
sprintf(outputFile, "/tmp/usb_hid_report_descriptor_%04x_%04x_%lu.bin",
|
||||||
deviceDescriptor->vendor_id, deviceDescriptor->product_id,
|
deviceDescriptor->vendor_id, deviceDescriptor->product_id,
|
||||||
@ -96,8 +120,11 @@ HIDDevice::HIDDevice(usb_device device, const usb_configuration_info *config,
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
result = fParser.ParseReportDescriptor(reportDescriptor, descriptorLength);
|
status_t result = fParser.ParseReportDescriptor(reportDescriptor,
|
||||||
free(reportDescriptor);
|
descriptorLength);
|
||||||
|
if (!isQuirky)
|
||||||
|
free(reportDescriptor);
|
||||||
|
|
||||||
if (result != B_OK) {
|
if (result != B_OK) {
|
||||||
TRACE_ALWAYS("parsing the report descriptor failed\n");
|
TRACE_ALWAYS("parsing the report descriptor failed\n");
|
||||||
fStatus = result;
|
fStatus = result;
|
||||||
|
27
src/add-ons/kernel/drivers/input/usb_hid/QuirkyDevices.h
Normal file
27
src/add-ons/kernel/drivers/input/usb_hid/QuirkyDevices.h
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2011 Michael Lotz <mmlr@mlotz.ch>
|
||||||
|
* 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
|
Loading…
Reference in New Issue
Block a user