[Oops, re-sent with a subject line this time...] Linus, This patch fixes some bugs in drivers/usb/hid.c. Johannes Erdfelt (the maintainer) sent it to you previously but it got missed. Could it go in 2.4.4 please? Here are the comments explaining the patch that I wrote originally: > The first hunk just fixes some typos in s32ton. For example, with > n == 8, the code as it was would return 0x80 if value > 127 but 0xff > if value < -128. With my change it returns 0x7f for value > 127 and > 0x80 for value < -128. > > The second hunk fixes the "cdcd" problem that we see on apple > keyboards that can only handle 2-key rollover. If you type "c" "d" > <space> quickly on these keyboards, you get a report with the > error-rollover code (1) in bytes 2 - 7 (instead of the codes for the > keys that are down). Without this patch the code thinks that all the > keys that were down are now up. When you release one key you get a > normal report again and the code thinks that the remaining keys have > been pressed again. The patch makes the code just discard the report > once it sees the error-rollover code. > > The remaining hunks fix some endianness problems in the code that sets > the keyboard leds. Thanks, Paul. diff -urN linux/drivers/usb/hid.c linuxppc_2_4/drivers/usb/hid.c --- linux/drivers/usb/hid.c Thu Feb 22 14:25:27 2001 +++ linuxppc_2_4/drivers/usb/hid.c Mon Feb 12 13:35:00 2001 @@ -698,7 +698,7 @@ static __inline__ __u32 s32ton(__s32 value, unsigned n) { __s32 a = value >> (n - 1); - if (a && a != -1) return value > 0 ? 1 << (n - 1) : (1 << n) - 1; + if (a && a != -1) return value < 0 ? 1 << (n - 1) : (1 << (n - 1)) - 1; return value & ((1 << n) - 1); } @@ -1016,9 +1016,15 @@ __s32 max = field->logical_maximum; __s32 value[count]; /* WARNING: gcc specific */ - for (n = 0; n < count; n++) + for (n = 0; n < count; n++) { value[n] = min < 0 ? snto32(extract(data, offset + n * size, size), size) : extract(data, offset + n * size, size); + /* Handle the ErrorRollOver code (1) by simply ignoring this +report */ + if (!(field->flags & HID_MAIN_ITEM_VARIABLE) + && value[n] >= min && value[n] <= max + && field->usage[value[n] - min].hid == HID_UP_KEYBOARD + 1) + return; + } for (n = 0; n < count; n++) { @@ -1231,7 +1237,7 @@ static int hid_submit_out(struct hid_device *hid) { - hid->urbout.transfer_buffer_length = hid->out[hid->outtail].dr.length; + hid->urbout.transfer_buffer_length = +le16_to_cpup(&hid->out[hid->outtail].dr.length); hid->urbout.transfer_buffer = hid->out[hid->outtail].buffer; hid->urbout.setup_packet = (void *) &(hid->out[hid->outtail].dr); hid->urbout.dev = hid->dev; @@ -1271,8 +1277,8 @@ hid_set_field(field, offset, value); hid_output_report(field->report, hid->out[hid->outhead].buffer); - hid->out[hid->outhead].dr.value = 0x200 | field->report->id; - hid->out[hid->outhead].dr.length = ((field->report->size - 1) >> 3) + 1; + hid->out[hid->outhead].dr.value = cpu_to_le16(0x200 | field->report->id); + hid->out[hid->outhead].dr.length = cpu_to_le16((field->report->size + 7) >> 3); hid->outhead = (hid->outhead + 1) & (HID_CONTROL_FIFO_SIZE - 1); @@ -1445,7 +1451,7 @@ for (n = 0; n < HID_CONTROL_FIFO_SIZE; n++) { hid->out[n].dr.requesttype = USB_TYPE_CLASS | USB_RECIP_INTERFACE; hid->out[n].dr.request = USB_REQ_SET_REPORT; - hid->out[n].dr.index = hid->ifnum; + hid->out[n].dr.index = cpu_to_le16(hid->ifnum); } hid->input.name = hid->name; - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/