aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/usb/input/hid-core.c24
1 files changed, 17 insertions, 7 deletions
diff --git a/drivers/usb/input/hid-core.c b/drivers/usb/input/hid-core.c
index a6738a83ff5b..feabda73a6f9 100644
--- a/drivers/usb/input/hid-core.c
+++ b/drivers/usb/input/hid-core.c
@@ -750,21 +750,31 @@ static __inline__ __u32 s32ton(__s32 value, unsigned n)
750} 750}
751 751
752/* 752/*
753 * Extract/implement a data field from/to a report. 753 * Extract/implement a data field from/to a little endian report (bit array).
754 */ 754 */
755 755
756static __inline__ __u32 extract(__u8 *report, unsigned offset, unsigned n) 756static __inline__ __u32 extract(__u8 *report, unsigned offset, unsigned n)
757{ 757{
758 report += (offset >> 5) << 2; offset &= 31; 758 u32 x;
759 return (le64_to_cpu(get_unaligned((__le64*)report)) >> offset) & ((1ULL << n) - 1); 759
760 report += offset >> 3; /* adjust byte index */
761 offset &= 8 - 1;
762 x = get_unaligned((u32 *) report);
763 x = le32_to_cpu(x);
764 x = (x >> offset) & ((1 << n) - 1);
765 return x;
760} 766}
761 767
762static __inline__ void implement(__u8 *report, unsigned offset, unsigned n, __u32 value) 768static __inline__ void implement(__u8 *report, unsigned offset, unsigned n, __u32 value)
763{ 769{
764 report += (offset >> 5) << 2; offset &= 31; 770 u32 x;
765 put_unaligned((get_unaligned((__le64*)report) 771
766 & cpu_to_le64(~((((__u64) 1 << n) - 1) << offset))) 772 report += offset >> 3;
767 | cpu_to_le64((__u64)value << offset), (__le64*)report); 773 offset &= 8 - 1;
774 x = get_unaligned((u32 *)report);
775 x &= cpu_to_le32(~((((__u32) 1 << n) - 1) << offset));
776 x |= cpu_to_le32(value << offset);
777 put_unaligned(x,(u32 *)report);
768} 778}
769 779
770/* 780/*