The patch titled hid-core: big-endian fix fix has been removed from the -mm tree. Its filename was hid-core-big-endian-fix-fix.patch This patch was dropped because it was merged into mainline or a subsystem tree ------------------------------------------------------ Subject: hid-core: big-endian fix fix From: Grant Grundler <grundler@xxxxxxxxxxxxxxxx> Adam Kropelin had posted 32-bit fix in June 2005 about two weeks after I originally had posted my fixes for big endian support. Adam has a UPS device which reports LINEV using 32-bits. Added comments to describe the limitations of the code. extract() is the same version I posted earlier and tested in user space. Made similar changes to implement() routine. I've written (and will shortly post) a test for implement(). Code tested on C3600 (parisc) with USB keyboard/mouse attached. I've dropped test_implement.c and a few other user space test programs on http://iou.parisc-linux.org/~grundler/tests/ -rw-r--r-- 1 grundler grundler 1750 Oct 18 09:13 test_extract.c -rw-r--r-- 1 grundler grundler 561 Jan 25 2006 test_ffs.c -rw-r--r-- 1 grundler users 7175 Apr 8 2005 test_fls.c -rw-r--r-- 1 grundler grundler 206 Sep 1 15:52 test_gettimeofday.c -rw-r--r-- 1 grundler grundler 1886 Oct 19 09:20 test_implement.c -rw-r--r-- 1 grundler users 2707 Jun 4 2005 test_unaligned.c I would appreciate if someone else would look at the output of test_implement.c to make it does The Right Thing. Adam has identified a couple of the problematic UPSes: [0] The a-ha! message: http://www.kroptech.com/~adk0212/mailimport/showmsg.php?msg_id=2755959844&db_name=apcupsd-users [1] Top of thread, or close to it: http://www.kroptech.com/~adk0212/mailimport/showmsg.php?msg_id=2013770374&db_name=apcupsd-users [akpm@xxxxxxxx: cleanups, fix a few wrong inlinings] Signed-off-by: Grant Grundler <grundler@xxxxxxxxxxxxxxxx> Cc: Adam Kropelin <akropel1@xxxxxxxxxxxxxxxx> Cc: Greg Kroah-Hartman <gregkh@xxxxxxx> Cc: Matthew Wilcox <matthew@xxxxxx> Cc: Dmitry Torokhov <dtor@xxxxxxx> Signed-off-by: Andrew Morton <akpm@xxxxxxxx> --- drivers/usb/input/hid-core.c | 67 ++++++++++++++++++++++----------- 1 files changed, 46 insertions(+), 21 deletions(-) diff -puN drivers/usb/input/hid-core.c~hid-core-big-endian-fix-fix drivers/usb/input/hid-core.c --- a/drivers/usb/input/hid-core.c~hid-core-big-endian-fix-fix +++ a/drivers/usb/input/hid-core.c @@ -270,7 +270,7 @@ static int hid_add_field(struct hid_pars * Read data value from item. */ -static __inline__ __u32 item_udata(struct hid_item *item) +static u32 item_udata(struct hid_item *item) { switch (item->size) { case 1: return item->data.u8; @@ -280,7 +280,7 @@ static __inline__ __u32 item_udata(struc return 0; } -static __inline__ __s32 item_sdata(struct hid_item *item) +static s32 item_sdata(struct hid_item *item) { switch (item->size) { case 1: return item->data.s8; @@ -727,7 +727,7 @@ static struct hid_device *hid_parse_repo * done by hand. */ -static __inline__ __s32 snto32(__u32 value, unsigned n) +static s32 snto32(__u32 value, unsigned n) { switch (n) { case 8: return ((__s8)value); @@ -741,9 +741,9 @@ static __inline__ __s32 snto32(__u32 val * Convert a signed 32-bit integer to a signed n-bit integer. */ -static __inline__ __u32 s32ton(__s32 value, unsigned n) +static u32 s32ton(__s32 value, unsigned n) { - __s32 a = value >> (n - 1); + s32 a = value >> (n - 1); if (a && a != -1) return value < 0 ? 1 << (n - 1) : (1 << (n - 1)) - 1; return value & ((1 << n) - 1); @@ -751,37 +751,62 @@ static __inline__ __u32 s32ton(__s32 val /* * Extract/implement a data field from/to a little endian report (bit array). + * + * Code sort-of follows HID spec: + * http://www.usb.org/developers/devclass_docs/HID1_11.pdf + * + * While the USB HID spec allows unlimited length bit fields in "report + * fields", many devices never use more than 16 bits. UPSes routinely have + * 24 bit fields. One UPS model reports "LINEV" as a 32-bit field. + * Search linux-kernel and linux-usb-devel archives for "hid-core extract". */ - -static __inline__ __u32 extract(__u8 *report, unsigned offset, unsigned n) +static u32 extract(u8 *report, unsigned offset, unsigned n) { - u32 x; + u64 x; + + WARN_ON(n > 32); report += offset >> 3; /* adjust byte index */ - offset &= 8 - 1; - x = get_unaligned((u32 *) report); - x = le32_to_cpu(x); - x = (x >> offset) & ((1 << n) - 1); - return x; + offset &= 7; /* now only need bit offset into one byte */ + x = get_unaligned((u64 *) report); + x = le64_to_cpu(x); + x = (x >> offset) & ((1ULL << n) - 1); /* extract bit field */ + return (u32) x; } -static __inline__ void implement(__u8 *report, unsigned offset, unsigned n, __u32 value) +/* + * "implement" : set bits in a little endian bit stream. + * Same concepts as "extract" (see comments above). + * The data mangled in the bit stream remains in little endian + * order the whole time. It make more sense to talk about + * endianness of register values by considering a register + * a "cached" copy of the little endian bit stream. + */ +static void implement(u8 *report, unsigned offset, unsigned n, + u32 value) { - u32 x; + u64 x; + u64 m = (1ULL << n) - 1; + + WARN_ON(n > 32); + + WARN_ON(value > m); + value &= m; report += offset >> 3; - offset &= 8 - 1; - x = get_unaligned((u32 *)report); - x &= cpu_to_le32(~((((__u32) 1 << n) - 1) << offset)); - x |= cpu_to_le32(value << offset); - put_unaligned(x,(u32 *)report); + offset &= 7; + + x = get_unaligned((u64 *)report); + x &= cpu_to_le64(~(m << offset)); + x |= cpu_to_le64(((u64) value) << offset); + put_unaligned(x, (u64 *) report); } /* * Search an array for a value. */ -static __inline__ int search(__s32 *array, __s32 value, unsigned n) +static inline int search(s32 *array, s32 value, unsigned n) { while (n--) { if (*array++ == value) _ Patches currently in -mm which might be from grundler@xxxxxxxxxxxxxxxx are tulip-fix-shutdown-dma-irq-race.patch tulip-fix-for-64-bit-mips.patch tulip-natsemi-dp83840a-phy-fix.patch - To unsubscribe from this list: send the line "unsubscribe mm-commits" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html