Changeset 6283cefb in mainline


Ignore:
Timestamp:
2017-11-21T18:13:28Z (6 years ago)
Author:
Aearsis <Hlavaty.Ondrej@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
ae303ad
Parents:
6d91888
git-author:
Aearsis <Hlavaty.Ondrej@…> (2017-11-21 18:13:26)
git-committer:
Aearsis <Hlavaty.Ondrej@…> (2017-11-21 18:13:28)
Message:

usbhid: rewrite the way values are extracted

There was a bug, and I'm not able to find it. After the rewrite, it is
working as expected.

Location:
uspace/lib/usbhid/src
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/usbhid/src/hiddescriptor.c

    r6d91888 r6283cefb  
    246246                field->size = report_item->size;
    247247
    248                 if(report_item->type == USB_HID_REPORT_TYPE_INPUT) {
    249                         int offset = report_item->offset + report_item->size * i;
    250                         int field_offset = (offset/8)*8 + (offset/8 + 1) * 8 -
    251                                 offset - report_item->size;
    252                         if(field_offset < 0) {
    253                                 field->offset = 0;
    254                         }
    255                         else {
    256                                 field->offset = field_offset;
    257                         }
    258                 }
    259                 else {
    260                         field->offset = report_item->offset + (i * report_item->size);
    261                 }
    262 
     248                field->offset = report_item->offset + (i * report_item->size);
    263249
    264250                if(report->use_report_ids != 0) {
     
    901887        list_foreach(*list, ritems_link, usb_hid_report_field_t,
    902888            report_item) {
    903                 usb_log_debug("\t\tOFFSET: %X\n", report_item->offset);
     889                usb_log_debug("\t\tOFFSET: %u\n", report_item->offset);
    904890                usb_log_debug("\t\tSIZE: %zu\n", report_item->size);
    905891                usb_log_debug("\t\tLOGMIN: %d\n",
  • uspace/lib/usbhid/src/hidparser.c

    r6d91888 r6283cefb  
    4040#include <usb/debug.h>
    4141#include <assert.h>
     42#include <bitops.h>
     43#include <macros.h>
    4244
    4345
     
    199201int usb_hid_translate_data(usb_hid_report_field_t *item, const uint8_t *data)
    200202{
    201         int resolution;
    202         int offset;
    203         int part_size;
    204        
    205         int32_t value = 0;
    206         int32_t mask = 0;
    207         const uint8_t *foo = 0;
    208 
    209203        /* now only short tags are allowed */
    210204        if (item->size > 32) {
     
    214208        if ((item->physical_minimum == 0) && (item->physical_maximum == 0)) {
    215209                item->physical_minimum = item->logical_minimum;
    216                 item->physical_maximum = item->logical_maximum;                 
    217         }
    218        
    219 
     210                item->physical_maximum = item->logical_maximum;
     211        }
     212
     213        int resolution;
    220214        if (item->physical_maximum == item->physical_minimum) {
    221215            resolution = 1;
    222216        } else {
    223             resolution = (item->logical_maximum - item->logical_minimum) / 
    224                 ((item->physical_maximum - item->physical_minimum) * 
     217            resolution = (item->logical_maximum - item->logical_minimum) /
     218                ((item->physical_maximum - item->physical_minimum) *
    225219                (usb_pow(10, (item->unit_exponent))));
    226220        }
    227221
    228         offset = item->offset;
    229         // FIXME
    230         if ((size_t) (offset / 8) != (size_t) ((offset+item->size - 1) / 8)) {
    231                
    232                 part_size = 0;
    233 
    234                 size_t i = 0;
    235                 for (i = (size_t) (offset / 8);
    236                     i <= (size_t) (offset + item->size - 1) / 8; i++) {
    237                         if (i == (size_t) (offset / 8)) {
    238                                 /* the higher one */
    239                                 part_size = 8 - (offset % 8);
    240                                 foo = data + i;
    241                                 mask =  ((1 << (item->size - part_size)) - 1);
    242                                 value = (*foo & mask);
    243                         } else if (i == ((offset + item->size - 1) / 8)) {
    244                                 /* the lower one */
    245                                 foo = data + i;
    246                                 mask = ((1 << (item->size - part_size)) - 1) <<
    247                                     (8 - (item->size - part_size));
    248 
    249                                 value = (((*foo & mask) >> (8 -
    250                                     (item->size - part_size))) << part_size) +
    251                                     value;
    252                         } else {
    253                                 value = (*(data + 1) << (part_size + 8)) +
    254                                     value;
    255                                 part_size += 8;
    256                         }
    257                 }
    258         } else {               
    259                 foo = data + (offset / 8);
    260                 mask = ((1 << item->size) - 1) <<
    261                     (8 - ((offset % 8) + item->size));
    262                 value = (*foo & mask) >> (8 - ((offset % 8) + item->size));
     222        int32_t value = 0;
     223
     224        /* First, skip all bytes we don't care */
     225        data += item->offset / 8;
     226
     227        int bits = item->size;
     228        int taken = 0;
     229
     230        /* Than we take the higher bits from the LSB */
     231        const unsigned bit_offset = item->offset % 8;
     232        const int lsb_bits = min(bits, 8);
     233
     234        value |= (*data >> bit_offset) & BIT_RRANGE(uint8_t, lsb_bits);
     235        bits -= lsb_bits;
     236        taken += lsb_bits;
     237        data++;
     238
     239        /* Then there may be bytes, which we take as a whole. */
     240        while (bits > 8) {
     241                value |= *data << taken;
     242                taken += 8;
     243                bits -= 8;
     244                data++;
     245        }
     246
     247        /* And, finally, lower bits from HSB. */
     248        if (bits > 0) {
     249                value |= (*data & BIT_RRANGE(uint8_t, bits)) << taken;
    263250        }
    264251
Note: See TracChangeset for help on using the changeset viewer.