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:

Reply via email to