@@ -81,6 +81,7 @@ struct hid_report *hid_register_report(struct hid_device *device,
8181 report_enum -> report_id_hash [id ] = report ;
8282
8383 list_add_tail (& report -> list , & report_enum -> report_list );
84+ INIT_LIST_HEAD (& report -> field_entry_list );
8485
8586 return report ;
8687}
@@ -101,14 +102,16 @@ static struct hid_field *hid_register_field(struct hid_report *report, unsigned
101102
102103 field = kzalloc ((sizeof (struct hid_field ) +
103104 usages * sizeof (struct hid_usage ) +
104- usages * sizeof (unsigned )), GFP_KERNEL );
105+ 3 * usages * sizeof (unsigned int )), GFP_KERNEL );
105106 if (!field )
106107 return NULL ;
107108
108109 field -> index = report -> maxfield ++ ;
109110 report -> field [field -> index ] = field ;
110111 field -> usage = (struct hid_usage * )(field + 1 );
111112 field -> value = (s32 * )(field -> usage + usages );
113+ field -> new_value = (s32 * )(field -> value + usages );
114+ field -> usages_priorities = (s32 * )(field -> new_value + usages );
112115 field -> report = report ;
113116
114117 return field ;
@@ -656,6 +659,8 @@ static void hid_free_report(struct hid_report *report)
656659{
657660 unsigned n ;
658661
662+ kfree (report -> field_entries );
663+
659664 for (n = 0 ; n < report -> maxfield ; n ++ )
660665 kfree (report -> field [n ]);
661666 kfree (report );
@@ -1525,25 +1530,41 @@ static void hid_process_event(struct hid_device *hid, struct hid_field *field,
15251530}
15261531
15271532/*
1528- * Analyse a received field, and fetch the data from it. The field
1529- * content is stored for next report processing (we do differential
1530- * reporting to the layer).
1533+ * Checks if the given value is valid within this field
15311534 */
1535+ static inline int hid_array_value_is_valid (struct hid_field * field ,
1536+ __s32 value )
1537+ {
1538+ __s32 min = field -> logical_minimum ;
15321539
1533- static void hid_input_field (struct hid_device * hid , struct hid_field * field ,
1534- __u8 * data , int interrupt )
1540+ /*
1541+ * Value needs to be between logical min and max, and
1542+ * (value - min) is used as an index in the usage array.
1543+ * This array is of size field->maxusage
1544+ */
1545+ return value >= min &&
1546+ value <= field -> logical_maximum &&
1547+ value - min < field -> maxusage ;
1548+ }
1549+
1550+ /*
1551+ * Fetch the field from the data. The field content is stored for next
1552+ * report processing (we do differential reporting to the layer).
1553+ */
1554+ static void hid_input_fetch_field (struct hid_device * hid ,
1555+ struct hid_field * field ,
1556+ __u8 * data )
15351557{
15361558 unsigned n ;
15371559 unsigned count = field -> report_count ;
15381560 unsigned offset = field -> report_offset ;
15391561 unsigned size = field -> report_size ;
15401562 __s32 min = field -> logical_minimum ;
1541- __s32 max = field -> logical_maximum ;
15421563 __s32 * value ;
15431564
1544- value = kmalloc_array ( count , sizeof ( __s32 ), GFP_ATOMIC ) ;
1545- if (! value )
1546- return ;
1565+ value = field -> new_value ;
1566+ memset ( value , 0 , count * sizeof ( __s32 ));
1567+ field -> ignored = false ;
15471568
15481569 for (n = 0 ; n < count ; n ++ ) {
15491570
@@ -1554,35 +1575,228 @@ static void hid_input_field(struct hid_device *hid, struct hid_field *field,
15541575
15551576 /* Ignore report if ErrorRollOver */
15561577 if (!(field -> flags & HID_MAIN_ITEM_VARIABLE ) &&
1557- value [n ] >= min && value [n ] <= max &&
1558- value [n ] - min < field -> maxusage &&
1559- field -> usage [value [n ] - min ].hid == HID_UP_KEYBOARD + 1 )
1560- goto exit ;
1578+ hid_array_value_is_valid (field , value [n ]) &&
1579+ field -> usage [value [n ] - min ].hid == HID_UP_KEYBOARD + 1 ) {
1580+ field -> ignored = true;
1581+ return ;
1582+ }
15611583 }
1584+ }
1585+
1586+ /*
1587+ * Process a received variable field.
1588+ */
1589+
1590+ static void hid_input_var_field (struct hid_device * hid ,
1591+ struct hid_field * field ,
1592+ int interrupt )
1593+ {
1594+ unsigned int count = field -> report_count ;
1595+ __s32 * value = field -> new_value ;
1596+ unsigned int n ;
1597+
1598+ for (n = 0 ; n < count ; n ++ )
1599+ hid_process_event (hid ,
1600+ field ,
1601+ & field -> usage [n ],
1602+ value [n ],
1603+ interrupt );
1604+
1605+ memcpy (field -> value , value , count * sizeof (__s32 ));
1606+ }
1607+
1608+ /*
1609+ * Process a received array field. The field content is stored for
1610+ * next report processing (we do differential reporting to the layer).
1611+ */
1612+
1613+ static void hid_input_array_field (struct hid_device * hid ,
1614+ struct hid_field * field ,
1615+ int interrupt )
1616+ {
1617+ unsigned int n ;
1618+ unsigned int count = field -> report_count ;
1619+ __s32 min = field -> logical_minimum ;
1620+ __s32 * value ;
1621+
1622+ value = field -> new_value ;
1623+
1624+ /* ErrorRollOver */
1625+ if (field -> ignored )
1626+ return ;
15621627
15631628 for (n = 0 ; n < count ; n ++ ) {
1629+ if (hid_array_value_is_valid (field , field -> value [n ]) &&
1630+ search (value , field -> value [n ], count ))
1631+ hid_process_event (hid ,
1632+ field ,
1633+ & field -> usage [field -> value [n ] - min ],
1634+ 0 ,
1635+ interrupt );
1636+
1637+ if (hid_array_value_is_valid (field , value [n ]) &&
1638+ search (field -> value , value [n ], count ))
1639+ hid_process_event (hid ,
1640+ field ,
1641+ & field -> usage [value [n ] - min ],
1642+ 1 ,
1643+ interrupt );
1644+ }
15641645
1565- if (HID_MAIN_ITEM_VARIABLE & field -> flags ) {
1566- hid_process_event (hid , field , & field -> usage [n ], value [n ], interrupt );
1567- continue ;
1646+ memcpy (field -> value , value , count * sizeof (__s32 ));
1647+ }
1648+
1649+ /*
1650+ * Analyse a received report, and fetch the data from it. The field
1651+ * content is stored for next report processing (we do differential
1652+ * reporting to the layer).
1653+ */
1654+ static void hid_process_report (struct hid_device * hid ,
1655+ struct hid_report * report ,
1656+ __u8 * data ,
1657+ int interrupt )
1658+ {
1659+ unsigned int a ;
1660+ struct hid_field_entry * entry ;
1661+ struct hid_field * field ;
1662+
1663+ /* first retrieve all incoming values in data */
1664+ for (a = 0 ; a < report -> maxfield ; a ++ )
1665+ hid_input_fetch_field (hid , field = report -> field [a ], data );
1666+
1667+ if (!list_empty (& report -> field_entry_list )) {
1668+ /* INPUT_REPORT, we have a priority list of fields */
1669+ list_for_each_entry (entry ,
1670+ & report -> field_entry_list ,
1671+ list ) {
1672+ field = entry -> field ;
1673+
1674+ if (field -> flags & HID_MAIN_ITEM_VARIABLE )
1675+ hid_process_event (hid ,
1676+ field ,
1677+ & field -> usage [entry -> index ],
1678+ field -> new_value [entry -> index ],
1679+ interrupt );
1680+ else
1681+ hid_input_array_field (hid , field , interrupt );
15681682 }
15691683
1570- if (field -> value [n ] >= min && field -> value [n ] <= max
1571- && field -> value [n ] - min < field -> maxusage
1572- && field -> usage [field -> value [n ] - min ].hid
1573- && search (value , field -> value [n ], count ))
1574- hid_process_event (hid , field , & field -> usage [field -> value [n ] - min ], 0 , interrupt );
1684+ /* we need to do the memcpy at the end for var items */
1685+ for (a = 0 ; a < report -> maxfield ; a ++ ) {
1686+ field = report -> field [a ];
15751687
1576- if (value [n ] >= min && value [n ] <= max
1577- && value [n ] - min < field -> maxusage
1578- && field -> usage [value [n ] - min ].hid
1579- && search (field -> value , value [n ], count ))
1580- hid_process_event (hid , field , & field -> usage [value [n ] - min ], 1 , interrupt );
1688+ if (field -> flags & HID_MAIN_ITEM_VARIABLE )
1689+ memcpy (field -> value , field -> new_value ,
1690+ field -> report_count * sizeof (__s32 ));
1691+ }
1692+ } else {
1693+ /* FEATURE_REPORT, regular processing */
1694+ for (a = 0 ; a < report -> maxfield ; a ++ ) {
1695+ field = report -> field [a ];
1696+
1697+ if (field -> flags & HID_MAIN_ITEM_VARIABLE )
1698+ hid_input_var_field (hid , field , interrupt );
1699+ else
1700+ hid_input_array_field (hid , field , interrupt );
1701+ }
15811702 }
1703+ }
15821704
1583- memcpy (field -> value , value , count * sizeof (__s32 ));
1584- exit :
1585- kfree (value );
1705+ /*
1706+ * Insert a given usage_index in a field in the list
1707+ * of processed usages in the report.
1708+ *
1709+ * The elements of lower priority score are processed
1710+ * first.
1711+ */
1712+ static void __hid_insert_field_entry (struct hid_device * hid ,
1713+ struct hid_report * report ,
1714+ struct hid_field_entry * entry ,
1715+ struct hid_field * field ,
1716+ unsigned int usage_index )
1717+ {
1718+ struct hid_field_entry * next ;
1719+
1720+ entry -> field = field ;
1721+ entry -> index = usage_index ;
1722+ entry -> priority = field -> usages_priorities [usage_index ];
1723+
1724+ /* insert the element at the correct position */
1725+ list_for_each_entry (next ,
1726+ & report -> field_entry_list ,
1727+ list ) {
1728+ /*
1729+ * the priority of our element is strictly higher
1730+ * than the next one, insert it before
1731+ */
1732+ if (entry -> priority > next -> priority ) {
1733+ list_add_tail (& entry -> list , & next -> list );
1734+ return ;
1735+ }
1736+ }
1737+
1738+ /* lowest priority score: insert at the end */
1739+ list_add_tail (& entry -> list , & report -> field_entry_list );
1740+ }
1741+
1742+ static void hid_report_process_ordering (struct hid_device * hid ,
1743+ struct hid_report * report )
1744+ {
1745+ struct hid_field * field ;
1746+ struct hid_field_entry * entries ;
1747+ unsigned int a , u , usages ;
1748+ unsigned int count = 0 ;
1749+
1750+ /* count the number of individual fields in the report */
1751+ for (a = 0 ; a < report -> maxfield ; a ++ ) {
1752+ field = report -> field [a ];
1753+
1754+ if (field -> flags & HID_MAIN_ITEM_VARIABLE )
1755+ count += field -> report_count ;
1756+ else
1757+ count ++ ;
1758+ }
1759+
1760+ /* allocate the memory to process the fields */
1761+ entries = kcalloc (count , sizeof (* entries ), GFP_KERNEL );
1762+ if (!entries )
1763+ return ;
1764+
1765+ report -> field_entries = entries ;
1766+
1767+ /*
1768+ * walk through all fields in the report and
1769+ * store them by priority order in report->field_entry_list
1770+ *
1771+ * - Var elements are individualized (field + usage_index)
1772+ * - Arrays are taken as one, we can not chose an order for them
1773+ */
1774+ usages = 0 ;
1775+ for (a = 0 ; a < report -> maxfield ; a ++ ) {
1776+ field = report -> field [a ];
1777+
1778+ if (field -> flags & HID_MAIN_ITEM_VARIABLE ) {
1779+ for (u = 0 ; u < field -> report_count ; u ++ ) {
1780+ __hid_insert_field_entry (hid , report ,
1781+ & entries [usages ],
1782+ field , u );
1783+ usages ++ ;
1784+ }
1785+ } else {
1786+ __hid_insert_field_entry (hid , report , & entries [usages ],
1787+ field , 0 );
1788+ usages ++ ;
1789+ }
1790+ }
1791+ }
1792+
1793+ static void hid_process_ordering (struct hid_device * hid )
1794+ {
1795+ struct hid_report * report ;
1796+ struct hid_report_enum * report_enum = & hid -> report_enum [HID_INPUT_REPORT ];
1797+
1798+ list_for_each_entry (report , & report_enum -> report_list , list )
1799+ hid_report_process_ordering (hid , report );
15861800}
15871801
15881802/*
@@ -1746,7 +1960,6 @@ int hid_report_raw_event(struct hid_device *hid, int type, u8 *data, u32 size,
17461960 struct hid_report_enum * report_enum = hid -> report_enum + type ;
17471961 struct hid_report * report ;
17481962 struct hid_driver * hdrv ;
1749- unsigned int a ;
17501963 u32 rsize , csize = size ;
17511964 u8 * cdata = data ;
17521965 int ret = 0 ;
@@ -1782,8 +1995,7 @@ int hid_report_raw_event(struct hid_device *hid, int type, u8 *data, u32 size,
17821995 }
17831996
17841997 if (hid -> claimed != HID_CLAIMED_HIDRAW && report -> maxfield ) {
1785- for (a = 0 ; a < report -> maxfield ; a ++ )
1786- hid_input_field (hid , report -> field [a ], cdata , interrupt );
1998+ hid_process_report (hid , report , cdata , interrupt );
17871999 hdrv = hid -> driver ;
17882000 if (hdrv && hdrv -> report )
17892001 hdrv -> report (hid , report );
@@ -1970,6 +2182,8 @@ int hid_connect(struct hid_device *hdev, unsigned int connect_mask)
19702182 return - ENODEV ;
19712183 }
19722184
2185+ hid_process_ordering (hdev );
2186+
19732187 if ((hdev -> claimed & HID_CLAIMED_INPUT ) &&
19742188 (connect_mask & HID_CONNECT_FF ) && hdev -> ff_init )
19752189 hdev -> ff_init (hdev );
0 commit comments