Hi!
This is a patch that takes several fixes present in the 2.5 HID driver and
applies them to 2.4. This fixes behavior with several devices (namely an
oops with a Logitech Precision Gamepad).
--
Vojtech Pavlik
SuSE Labs
diff -urN linux-2.4.19-pre5/drivers/input/joydev.c
linux-2.4.19-pre5-hidfix/drivers/input/joydev.c
--- linux-2.4.19-pre5/drivers/input/joydev.c Sun Sep 30 21:26:05 2001
+++ linux-2.4.19-pre5-hidfix/drivers/input/joydev.c Sat Mar 30 11:23:54 2002
@@ -411,7 +411,7 @@
static struct input_handle *joydev_connect(struct input_handler *handler, struct
input_dev *dev)
{
struct joydev *joydev;
- int i, j, minor;
+ int i, j, t, minor;
if (!(test_bit(EV_KEY, dev->evbit) && test_bit(EV_ABS, dev->evbit) &&
(test_bit(ABS_X, dev->absbit) || test_bit(ABS_Y, dev->absbit)) &&
@@ -470,8 +470,10 @@
joydev->corr[i].prec = dev->absfuzz[j];
joydev->corr[i].coef[0] = (dev->absmax[j] + dev->absmin[j]) / 2 -
dev->absflat[j];
joydev->corr[i].coef[1] = (dev->absmax[j] + dev->absmin[j]) / 2 +
dev->absflat[j];
- joydev->corr[i].coef[2] = (1 << 29) / ((dev->absmax[j] -
dev->absmin[j]) / 2 - 2 * dev->absflat[j]);
- joydev->corr[i].coef[3] = (1 << 29) / ((dev->absmax[j] -
dev->absmin[j]) / 2 - 2 * dev->absflat[j]);
+ if (!(t = ((dev->absmax[j] - dev->absmin[j]) / 2 - 2 *
+dev->absflat[j])))
+ continue;
+ joydev->corr[i].coef[2] = (1 << 29) / t;
+ joydev->corr[i].coef[3] = (1 << 29) / t;
joydev->abs[i] = joydev_correct(dev->abs[j], joydev->corr + i);
}
diff -urN linux-2.4.19-pre5/drivers/usb/hid-core.c
linux-2.4.19-pre5-hidfix/drivers/usb/hid-core.c
--- linux-2.4.19-pre5/drivers/usb/hid-core.c Sat Mar 30 11:19:05 2002
+++ linux-2.4.19-pre5-hidfix/drivers/usb/hid-core.c Sat Mar 30 11:25:24 2002
@@ -204,17 +204,13 @@
return -1;
}
- if (HID_MAIN_ITEM_VARIABLE & ~flags) { /* ARRAY */
- if (parser->global.logical_maximum <= parser->global.logical_minimum) {
- dbg("logical range invalid %d %d",
parser->global.logical_minimum, parser->global.logical_maximum);
- return -1;
- }
- usages = parser->local.usage_index;
- /* Hint: we can assume usages < MAX_USAGE here */
- } else { /* VARIABLE */
- usages = parser->global.report_count;
+ if (parser->global.logical_maximum <= parser->global.logical_minimum) {
+ dbg("logical range invalid %d %d", parser->global.logical_minimum,
+parser->global.logical_maximum);
+ return -1;
}
+ usages = parser->local.usage_index;
+
offset = report->size;
report->size += parser->global.report_size * parser->global.report_count;
@@ -310,7 +306,10 @@
return 0;
case HID_GLOBAL_ITEM_TAG_LOGICAL_MAXIMUM:
- parser->global.logical_maximum = item_sdata(item);
+ if (parser->global.logical_minimum < 0)
+ parser->global.logical_maximum = item_sdata(item);
+ else
+ parser->global.logical_maximum = item_udata(item);
return 0;
case HID_GLOBAL_ITEM_TAG_PHYSICAL_MINIMUM:
@@ -318,7 +317,10 @@
return 0;
case HID_GLOBAL_ITEM_TAG_PHYSICAL_MAXIMUM:
- parser->global.physical_maximum = item_sdata(item);
+ if (parser->global.physical_minimum < 0)
+ parser->global.physical_maximum = item_sdata(item);
+ else
+ parser->global.physical_maximum = item_udata(item);
return 0;
case HID_GLOBAL_ITEM_TAG_UNIT_EXPONENT: