diff --git a/src/add-ons/kernel/drivers/input/usb_hid/Driver.cpp b/src/add-ons/kernel/drivers/input/usb_hid/Driver.cpp index e525175f3a..657b7f5139 100644 --- a/src/add-ons/kernel/drivers/input/usb_hid/Driver.cpp +++ b/src/add-ons/kernel/drivers/input/usb_hid/Driver.cpp @@ -82,10 +82,33 @@ usb_hid_device_added(usb_device device, void **cookie) i, interfaceClass, interface->descr->interface_subclass, interface->descr->interface_protocol); - if (interfaceClass == USB_INTERFACE_CLASS_HID) { + // check for quirky devices first + int32 quirkyIndex = -1; + for (int32 j = 0; j < gQuirkyDeviceCount; j++) { + usb_hid_quirky_device &quirky = gQuirkyDevices[j]; + if ((quirky.vendor_id != 0 + && deviceDescriptor->vendor_id != quirky.vendor_id) + || (quirky.product_id != 0 + && deviceDescriptor->product_id != quirky.product_id) + || (quirky.device_class != 0 + && interfaceClass != quirky.device_class) + || (quirky.device_subclass != 0 + && interface->descr->interface_subclass + != quirky.device_subclass) + || (quirky.device_protocol != 0 + && interface->descr->interface_protocol + != quirky.device_protocol)) { + continue; + } + + quirkyIndex = j; + break; + } + + if (quirkyIndex >= 0 || interfaceClass == USB_INTERFACE_CLASS_HID) { mutex_lock(&sDriverLock); HIDDevice *hidDevice - = new(std::nothrow) HIDDevice(device, config, i); + = new(std::nothrow) HIDDevice(device, config, i, quirkyIndex); if (hidDevice != NULL && hidDevice->InitCheck() == B_OK) { hidDevice->SetParentCookie(parentCookie); diff --git a/src/add-ons/kernel/drivers/input/usb_hid/HIDDevice.cpp b/src/add-ons/kernel/drivers/input/usb_hid/HIDDevice.cpp index 8fc93ffdef..6477bcde4d 100644 --- a/src/add-ons/kernel/drivers/input/usb_hid/HIDDevice.cpp +++ b/src/add-ons/kernel/drivers/input/usb_hid/HIDDevice.cpp @@ -24,7 +24,7 @@ HIDDevice::HIDDevice(usb_device device, const usb_configuration_info *config, - size_t interfaceIndex) + size_t interfaceIndex, int32 quirkyIndex) : fStatus(B_NO_INIT), fDevice(device), fInterfaceIndex(interfaceIndex), @@ -44,25 +44,18 @@ HIDDevice::HIDDevice(usb_device device, const usb_configuration_info *config, const usb_device_descriptor *deviceDescriptor = gUSBModule->get_device_descriptor(device); - // check for quirky devices first and don't bother in that case HIDWriter descriptorWriter; bool hasFixedDescriptor = false; - quirky_init_function quirkyInit = NULL; - for (int32 i = 0; i < gQuirkyDeviceCount; i++) { - usb_hid_quirky_device &quirky = gQuirkyDevices[i]; - if (deviceDescriptor->vendor_id == quirky.vendor_id - && deviceDescriptor->product_id == quirky.product_id) { + if (quirkyIndex >= 0) { + quirky_build_descriptor quirkyBuildDescriptor + = gQuirkyDevices[quirkyIndex].build_descriptor; - quirkyInit = quirky.init_function; - if (quirky.build_descriptor != NULL - && quirky.build_descriptor(descriptorWriter) == B_OK) { + if (quirkyBuildDescriptor != NULL + && quirkyBuildDescriptor(descriptorWriter) == B_OK) { - reportDescriptor = (uint8 *)descriptorWriter.Buffer(); - descriptorLength = descriptorWriter.BufferLength(); - hasFixedDescriptor = true; - } - - break; + reportDescriptor = (uint8 *)descriptorWriter.Buffer(); + descriptorLength = descriptorWriter.BufferLength(); + hasFixedDescriptor = true; } } @@ -176,10 +169,15 @@ HIDDevice::HIDDevice(usb_device device, const usb_configuration_info *config, return; } - if (quirkyInit != NULL) { - fStatus = quirkyInit(device, config, interfaceIndex); - if (fStatus != B_OK) - return; + if (quirkyIndex >= 0) { + quirky_init_function quirkyInit + = gQuirkyDevices[quirkyIndex].init_function; + + if (quirkyInit != NULL) { + fStatus = quirkyInit(device, config, interfaceIndex); + if (fStatus != B_OK) + return; + } } ProtocolHandler::AddHandlers(*this, fProtocolHandlerList, diff --git a/src/add-ons/kernel/drivers/input/usb_hid/HIDDevice.h b/src/add-ons/kernel/drivers/input/usb_hid/HIDDevice.h index 677fab9d8b..744b9ba0fd 100644 --- a/src/add-ons/kernel/drivers/input/usb_hid/HIDDevice.h +++ b/src/add-ons/kernel/drivers/input/usb_hid/HIDDevice.h @@ -18,7 +18,7 @@ class HIDDevice { public: HIDDevice(usb_device device, const usb_configuration_info *config, - size_t interfaceIndex); + size_t interfaceIndex, int32 quirkyIndex); ~HIDDevice(); void SetParentCookie(int32 cookie);