Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/drv/bus/usb/usbhid/usbhid.c

    r93d2684 r065064e6  
    5454
    5555/* Array of endpoints expected on the device, NULL terminated. */
    56 const usb_endpoint_description_t *usb_hid_endpoints[] = {
     56usb_endpoint_description_t *usb_hid_endpoints[] = {
    5757        &usb_hid_kbd_poll_endpoint_description,
    5858        &usb_hid_mouse_poll_endpoint_description,
     
    6161};
    6262
     63static const int USB_HID_MAX_SUBDRIVERS = 10;
     64
    6365/*----------------------------------------------------------------------------*/
    6466
    6567static int usb_hid_set_boot_kbd_subdriver(usb_hid_dev_t *hid_dev)
    6668{
    67         assert(hid_dev != NULL);
    68         assert(hid_dev->subdriver_count == 0);
    69 
    70         hid_dev->subdrivers = malloc(sizeof(usb_hid_subdriver_t));
     69        assert(hid_dev != NULL && hid_dev->subdriver_count == 0);
     70
     71        hid_dev->subdrivers = (usb_hid_subdriver_t *)malloc(
     72            sizeof(usb_hid_subdriver_t));
    7173        if (hid_dev->subdrivers == NULL) {
    7274                return ENOMEM;
    7375        }
    74         hid_dev->subdriver_count = 1;
    75         // TODO 0 should be keyboard, but find a better way
    76         hid_dev->subdrivers[0] = usb_hid_subdrivers[0].subdriver;
     76
     77        assert(hid_dev->subdriver_count >= 0);
     78
     79        // set the init callback
     80        hid_dev->subdrivers[hid_dev->subdriver_count].init = usb_kbd_init;
     81
     82        // set the polling callback
     83        hid_dev->subdrivers[hid_dev->subdriver_count].poll =
     84            usb_kbd_polling_callback;
     85
     86        // set the polling ended callback
     87        hid_dev->subdrivers[hid_dev->subdriver_count].poll_end = NULL;
     88
     89        // set the deinit callback
     90        hid_dev->subdrivers[hid_dev->subdriver_count].deinit = usb_kbd_deinit;
     91
     92        // set subdriver count
     93        ++hid_dev->subdriver_count;
    7794
    7895        return EOK;
     
    83100static int usb_hid_set_boot_mouse_subdriver(usb_hid_dev_t *hid_dev)
    84101{
    85         assert(hid_dev != NULL);
    86         assert(hid_dev->subdriver_count == 0);
    87 
    88         hid_dev->subdrivers = malloc(sizeof(usb_hid_subdriver_t));
     102        assert(hid_dev != NULL && hid_dev->subdriver_count == 0);
     103
     104        hid_dev->subdrivers = (usb_hid_subdriver_t *)malloc(
     105            sizeof(usb_hid_subdriver_t));
    89106        if (hid_dev->subdrivers == NULL) {
    90107                return ENOMEM;
    91108        }
    92         hid_dev->subdriver_count = 1;
    93         // TODO 2 should be mouse, but find a better way
    94         hid_dev->subdrivers[2] = usb_hid_subdrivers[0].subdriver;
     109
     110        assert(hid_dev->subdriver_count >= 0);
     111
     112        // set the init callback
     113        hid_dev->subdrivers[hid_dev->subdriver_count].init = usb_mouse_init;
     114
     115        // set the polling callback
     116        hid_dev->subdrivers[hid_dev->subdriver_count].poll =
     117            usb_mouse_polling_callback;
     118
     119        // set the polling ended callback
     120        hid_dev->subdrivers[hid_dev->subdriver_count].poll_end = NULL;
     121
     122        // set the deinit callback
     123        hid_dev->subdrivers[hid_dev->subdriver_count].deinit = usb_mouse_deinit;
     124
     125        // set subdriver count
     126        ++hid_dev->subdriver_count;
    95127
    96128        return EOK;
     
    103135        assert(hid_dev != NULL && hid_dev->subdriver_count == 0);
    104136
    105         hid_dev->subdrivers = malloc(sizeof(usb_hid_subdriver_t));
     137        hid_dev->subdrivers = (usb_hid_subdriver_t *)malloc(
     138            sizeof(usb_hid_subdriver_t));
    106139        if (hid_dev->subdrivers == NULL) {
    107140                return ENOMEM;
    108141        }
    109         hid_dev->subdriver_count = 1;
    110 
    111         /* Set generic hid subdriver routines */
    112         hid_dev->subdrivers[0].init = usb_generic_hid_init;
    113         hid_dev->subdrivers[0].poll = usb_generic_hid_polling_callback;
    114         hid_dev->subdrivers[0].poll_end = NULL;
    115         hid_dev->subdrivers[0].deinit = usb_generic_hid_deinit;
     142
     143        assert(hid_dev->subdriver_count >= 0);
     144
     145        // set the init callback
     146        hid_dev->subdrivers[hid_dev->subdriver_count].init =
     147            usb_generic_hid_init;
     148
     149        // set the polling callback
     150        hid_dev->subdrivers[hid_dev->subdriver_count].poll =
     151            usb_generic_hid_polling_callback;
     152
     153        // set the polling ended callback
     154        hid_dev->subdrivers[hid_dev->subdriver_count].poll_end = NULL;
     155
     156        // set the deinit callback
     157        hid_dev->subdrivers[hid_dev->subdriver_count].deinit =
     158            usb_generic_hid_deinit;
     159
     160        // set subdriver count
     161        ++hid_dev->subdriver_count;
    116162
    117163        return EOK;
     
    120166/*----------------------------------------------------------------------------*/
    121167
    122 static bool usb_hid_ids_match(const usb_hid_dev_t *hid_dev,
     168static bool usb_hid_ids_match(usb_hid_dev_t *hid_dev,
    123169    const usb_hid_subdriver_mapping_t *mapping)
    124170{
     
    126172        assert(hid_dev->usb_dev != NULL);
    127173
    128         return (hid_dev->usb_dev->descriptors.device.vendor_id
     174        return (hid_dev->usb_dev->descriptors.device.vendor_id 
    129175            == mapping->vendor_id
    130176            && hid_dev->usb_dev->descriptors.device.product_id
     
    134180/*----------------------------------------------------------------------------*/
    135181
    136 static bool usb_hid_path_matches(usb_hid_dev_t *hid_dev,
     182static bool usb_hid_path_matches(usb_hid_dev_t *hid_dev, 
    137183    const usb_hid_subdriver_mapping_t *mapping)
    138184{
     
    146192        }
    147193        int i = 0;
    148         while (mapping->usage_path[i].usage != 0
     194        while (mapping->usage_path[i].usage != 0 
    149195            || mapping->usage_path[i].usage_page != 0) {
    150                 if (usb_hid_report_path_append_item(usage_path,
    151                     mapping->usage_path[i].usage_page,
     196                if (usb_hid_report_path_append_item(usage_path, 
     197                    mapping->usage_path[i].usage_page, 
    152198                    mapping->usage_path[i].usage) != EOK) {
    153199                        usb_log_debug("Failed to append to usage path.\n");
     
    158204        }
    159205
     206        assert(hid_dev->report != NULL);
     207
    160208        usb_log_debug("Compare flags: %d\n", mapping->compare);
    161209
     
    165213        do {
    166214                usb_log_debug("Trying report id %u\n", report_id);
    167 
     215               
    168216                if (report_id != 0) {
    169217                        usb_hid_report_path_set_report_id(usage_path,
     
    172220
    173221                usb_hid_report_field_t *field = usb_hid_report_get_sibling(
    174                     &hid_dev->report, NULL, usage_path, mapping->compare,
     222                    hid_dev->report,
     223                    NULL, usage_path, mapping->compare,
    175224                    USB_HID_REPORT_TYPE_INPUT);
    176 
     225               
    177226                usb_log_debug("Field: %p\n", field);
    178227
     
    181230                        break;
    182231                }
    183 
     232               
    184233                report_id = usb_hid_get_next_report_id(
    185                     &hid_dev->report, report_id, USB_HID_REPORT_TYPE_INPUT);
     234                    hid_dev->report, report_id,
     235                    USB_HID_REPORT_TYPE_INPUT);
    186236        } while (!matches && report_id != 0);
    187237
     
    193243/*----------------------------------------------------------------------------*/
    194244
    195 static int usb_hid_save_subdrivers(usb_hid_dev_t *hid_dev,
     245static int usb_hid_save_subdrivers(usb_hid_dev_t *hid_dev, 
    196246    const usb_hid_subdriver_t **subdrivers, int count)
    197247{
     
    204254        }
    205255
    206         /* +1 for generic hid subdriver */
    207         hid_dev->subdrivers = calloc((count + 1), sizeof(usb_hid_subdriver_t));
     256        // add one generic HID subdriver per device
     257
     258        hid_dev->subdrivers = (usb_hid_subdriver_t *)malloc((count + 1) *
     259            sizeof(usb_hid_subdriver_t));
    208260        if (hid_dev->subdrivers == NULL) {
    209261                return ENOMEM;
     
    217269        }
    218270
    219         /* Add one generic HID subdriver per device */
    220271        hid_dev->subdrivers[count].init = usb_generic_hid_init;
    221272        hid_dev->subdrivers[count].poll = usb_generic_hid_polling_callback;
     
    256307                        return EINVAL;
    257308                }
    258 
     309               
    259310                ids_matched = false;
    260311                matched = false;
    261 
     312               
    262313                if (mapping->vendor_id >= 0) {
    263314                        assert(mapping->product_id >= 0);
     
    270321                        }
    271322                }
    272 
     323               
    273324                if (mapping->usage_path != NULL) {
    274325                        usb_log_debug("Comparing device against usage path.\n");
     
    281332                        matched = ids_matched;
    282333                }
    283 
     334               
    284335                if (matched) {
    285336                        usb_log_debug("Subdriver matched.\n");
    286337                        subdrivers[count++] = &mapping->subdriver;
    287338                }
    288 
     339               
    289340                mapping = &usb_hid_subdrivers[++i];
    290341        }
    291342
    292         /* We have all subdrivers determined, save them into the hid device */
    293         // TODO Dowe really need this complicated stuff if there is
    294         // max_subdrivers limitation?
     343        // we have all subdrivers determined, save them into the hid device
    295344        return usb_hid_save_subdrivers(hid_dev, subdrivers, count);
    296345}
     
    298347/*----------------------------------------------------------------------------*/
    299348
    300 static int usb_hid_check_pipes(usb_hid_dev_t *hid_dev, const usb_device_t *dev)
    301 {
    302         assert(hid_dev);
    303         assert(dev);
     349static int usb_hid_check_pipes(usb_hid_dev_t *hid_dev, usb_device_t *dev)
     350{
     351        assert(hid_dev != NULL && dev != NULL);
     352
     353        int rc = EOK;
    304354
    305355        if (dev->pipes[USB_HID_KBD_POLL_EP_NO].present) {
     
    318368                usb_log_error("None of supported endpoints found - probably"
    319369                    " not a supported device.\n");
    320                 return ENOTSUP;
    321         }
    322 
    323         return EOK;
     370                rc = ENOTSUP;
     371        }
     372
     373        return rc;
    324374}
    325375
     
    328378static int usb_hid_init_report(usb_hid_dev_t *hid_dev)
    329379{
    330         assert(hid_dev != NULL);
     380        assert(hid_dev != NULL && hid_dev->report != NULL);
    331381
    332382        uint8_t report_id = 0;
     383        size_t size;
     384
    333385        size_t max_size = 0;
    334386
    335387        do {
    336388                usb_log_debug("Getting size of the report.\n");
    337                 const size_t size =
    338                     usb_hid_report_byte_size(&hid_dev->report, report_id,
    339                         USB_HID_REPORT_TYPE_INPUT);
     389                size = usb_hid_report_byte_size(hid_dev->report, report_id,
     390                    USB_HID_REPORT_TYPE_INPUT);
    340391                usb_log_debug("Report ID: %u, size: %zu\n", report_id, size);
    341392                max_size = (size > max_size) ? size : max_size;
    342393                usb_log_debug("Getting next report ID\n");
    343                 report_id = usb_hid_get_next_report_id(&hid_dev->report,
     394                report_id = usb_hid_get_next_report_id(hid_dev->report,
    344395                    report_id, USB_HID_REPORT_TYPE_INPUT);
    345396        } while (report_id != 0);
     
    347398        usb_log_debug("Max size of input report: %zu\n", max_size);
    348399
     400        hid_dev->max_input_report_size = max_size;
    349401        assert(hid_dev->input_report == NULL);
    350402
    351         hid_dev->input_report = calloc(1, max_size);
     403        hid_dev->input_report = malloc(max_size);
    352404        if (hid_dev->input_report == NULL) {
    353405                return ENOMEM;
    354406        }
    355         hid_dev->max_input_report_size = max_size;
     407        memset(hid_dev->input_report, 0, max_size);
    356408
    357409        return EOK;
     
    378430        }
    379431
    380         usb_hid_report_init(&hid_dev->report);
     432        hid_dev->report = (usb_hid_report_t *)(malloc(sizeof(
     433            usb_hid_report_t)));
     434        if (hid_dev->report == NULL) {
     435                usb_log_error("No memory!\n");
     436                return ENOMEM;
     437        }
     438        usb_hid_report_init(hid_dev->report);
    381439
    382440        /* The USB device should already be initialized, save it in structure */
     
    388446                return rc;
    389447        }
    390 
     448               
    391449        /* Get the report descriptor and parse it. */
    392         rc = usb_hid_process_report_descriptor(hid_dev->usb_dev,
    393             &hid_dev->report, &hid_dev->report_desc, &hid_dev->report_desc_size);
     450        rc = usb_hid_process_report_descriptor(hid_dev->usb_dev, 
     451            hid_dev->report, &hid_dev->report_desc, &hid_dev->report_desc_size);
    394452
    395453        bool fallback = false;
     
    430488                        break;
    431489                default:
    432                         assert(hid_dev->poll_pipe_index
     490                        assert(hid_dev->poll_pipe_index 
    433491                            == USB_HID_GENERIC_POLL_EP_NO);
    434 
     492                       
    435493                        usb_log_info("Falling back to generic HID driver.\n");
    436494                        rc = usb_hid_set_generic_hid_subdriver(hid_dev);
     
    441499                usb_log_error("No subdriver for handling this device could be"
    442500                    " initialized: %s.\n", str_error(rc));
    443                 usb_log_debug("Subdriver count: %d\n",
     501                usb_log_debug("Subdriver count: %d\n", 
    444502                    hid_dev->subdriver_count);
     503               
    445504        } else {
    446505                bool ok = false;
    447 
    448                 usb_log_debug("Subdriver count: %d\n",
     506               
     507                usb_log_debug("Subdriver count: %d\n", 
    449508                    hid_dev->subdriver_count);
    450 
     509               
    451510                for (i = 0; i < hid_dev->subdriver_count; ++i) {
    452511                        if (hid_dev->subdrivers[i].init != NULL) {
     
    465524                        }
    466525                }
    467 
     526               
    468527                rc = (ok) ? EOK : -1;   // what error to report
    469528        }
     
    479538        }
    480539
     540
    481541        return rc;
    482542}
     
    484544/*----------------------------------------------------------------------------*/
    485545
    486 bool usb_hid_polling_callback(usb_device_t *dev, uint8_t *buffer,
     546bool usb_hid_polling_callback(usb_device_t *dev, uint8_t *buffer, 
    487547    size_t buffer_size, void *arg)
    488548{
     549        int i;
     550
    489551        if (dev == NULL || arg == NULL || buffer == NULL) {
    490552                usb_log_error("Missing arguments to polling callback.\n");
    491553                return false;
    492554        }
    493         usb_hid_dev_t *hid_dev = arg;
     555
     556        usb_hid_dev_t *hid_dev = (usb_hid_dev_t *)arg;
    494557
    495558        assert(hid_dev->input_report != NULL);
    496 
    497559        usb_log_debug("New data [%zu/%zu]: %s\n", buffer_size,
    498560            hid_dev->max_input_report_size,
     
    506568        }
    507569
    508         /* Parse the input report */
    509         const int rc = usb_hid_parse_report(
    510             &hid_dev->report, buffer, buffer_size, &hid_dev->report_id);
     570        // parse the input report
     571
     572        int rc = usb_hid_parse_report(hid_dev->report, buffer, buffer_size,
     573            &hid_dev->report_id);
     574
    511575        if (rc != EOK) {
    512576                usb_log_warning("Error in usb_hid_parse_report():"
    513577                    "%s\n", str_error(rc));
    514         }
     578        }       
    515579
    516580        bool cont = false;
    517         /* Continue if at least one of the subdrivers want to continue */
    518         for (int i = 0; i < hid_dev->subdriver_count; ++i) {
    519                 if (hid_dev->subdrivers[i].poll != NULL) {
    520                         cont = cont || hid_dev->subdrivers[i].poll(
    521                             hid_dev, hid_dev->subdrivers[i].data);
     581
     582        // continue if at least one of the subdrivers want to continue
     583        for (i = 0; i < hid_dev->subdriver_count; ++i) {
     584                if (hid_dev->subdrivers[i].poll != NULL
     585                    && hid_dev->subdrivers[i].poll(hid_dev,
     586                        hid_dev->subdrivers[i].data)) {
     587                        cont = true;
    522588                }
    523589        }
     
    528594/*----------------------------------------------------------------------------*/
    529595
    530 void usb_hid_polling_ended_callback(usb_device_t *dev, bool reason, void *arg)
    531 {
    532         assert(dev);
    533         assert(arg);
    534 
    535         usb_hid_dev_t *hid_dev = arg;
    536 
    537         for (int i = 0; i < hid_dev->subdriver_count; ++i) {
     596void usb_hid_polling_ended_callback(usb_device_t *dev, bool reason,
     597     void *arg)
     598{
     599        int i;
     600
     601        if (dev == NULL || arg == NULL) {
     602                return;
     603        }
     604
     605        usb_hid_dev_t *hid_dev = (usb_hid_dev_t *)arg;
     606
     607        for (i = 0; i < hid_dev->subdriver_count; ++i) {
    538608                if (hid_dev->subdrivers[i].poll_end != NULL) {
    539                         hid_dev->subdrivers[i].poll_end(
    540                             hid_dev, hid_dev->subdrivers[i].data, reason);
     609                        hid_dev->subdrivers[i].poll_end(hid_dev,
     610                            hid_dev->subdrivers[i].data, reason);
    541611                }
    542612        }
     
    554624/*----------------------------------------------------------------------------*/
    555625
    556 int usb_hid_report_number(const usb_hid_dev_t *hid_dev)
     626int usb_hid_report_number(usb_hid_dev_t *hid_dev)
    557627{
    558628        return hid_dev->report_nr;
     
    561631/*----------------------------------------------------------------------------*/
    562632
    563 void usb_hid_deinit(usb_hid_dev_t *hid_dev)
    564 {
    565         assert(hid_dev);
    566         assert(hid_dev->subdrivers != NULL || hid_dev->subdriver_count == 0);
    567 
     633void usb_hid_destroy(usb_hid_dev_t *hid_dev)
     634{
     635        int i;
     636
     637        if (hid_dev == NULL) {
     638                return;
     639        }
    568640
    569641        usb_log_debug("Subdrivers: %p, subdriver count: %d\n",
    570642            hid_dev->subdrivers, hid_dev->subdriver_count);
    571643
    572         for (int i = 0; i < hid_dev->subdriver_count; ++i) {
     644        assert(hid_dev->subdrivers != NULL
     645            || hid_dev->subdriver_count == 0);
     646
     647        for (i = 0; i < hid_dev->subdriver_count; ++i) {
    573648                if (hid_dev->subdrivers[i].deinit != NULL) {
    574649                        hid_dev->subdrivers[i].deinit(hid_dev,
     
    582657
    583658        /* Destroy the parser */
    584         usb_hid_report_deinit(&hid_dev->report);
     659        if (hid_dev->report != NULL) {
     660                usb_hid_free_report(hid_dev->report);
     661        }
    585662
    586663}
Note: See TracChangeset for help on using the changeset viewer.