Ignore:
File:
1 edited

Legend:

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

    r36f737a rfec47d4  
    4242#include <usb/classes/hidreq.h>
    4343#include <errno.h>
    44 #include <str_error.h>
    4544
    4645#include "usbhid.h"
     
    4847#include "kbd/kbddev.h"
    4948#include "generic/hiddev.h"
    50 #include "mouse/mousedev.h"
    51 #include "subdrivers.h"
    52 
    53 /*----------------------------------------------------------------------------*/
     49
     50/*----------------------------------------------------------------------------*/
     51
     52/** Mouse polling endpoint description for boot protocol class. */
     53static usb_endpoint_description_t usb_hid_mouse_poll_endpoint_description = {
     54        .transfer_type = USB_TRANSFER_INTERRUPT,
     55        .direction = USB_DIRECTION_IN,
     56        .interface_class = USB_CLASS_HID,
     57        .interface_subclass = USB_HID_SUBCLASS_BOOT,
     58        .interface_protocol = USB_HID_PROTOCOL_MOUSE,
     59        .flags = 0
     60};
    5461
    5562/* Array of endpoints expected on the device, NULL terminated. */
     
    6168};
    6269
    63 static const int USB_HID_MAX_SUBDRIVERS = 10;
    64 
    65 /*----------------------------------------------------------------------------*/
    66 
    67 static int usb_hid_set_boot_kbd_subdriver(usb_hid_dev_t *hid_dev)
    68 {
    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));
    73         if (hid_dev->subdrivers == NULL) {
    74                 return ENOMEM;
    75         }
    76        
    77         // set the init callback
    78         hid_dev->subdrivers[0].init = usb_kbd_init;
    79        
    80         // set the polling callback
    81         hid_dev->subdrivers[0].poll = usb_kbd_polling_callback;
    82        
    83         // set the polling ended callback
    84         hid_dev->subdrivers[0].poll_end = NULL;
    85        
    86         // set the deinit callback
    87         hid_dev->subdrivers[0].deinit = usb_kbd_deinit;
    88        
    89         // set subdriver count
    90         hid_dev->subdriver_count = 1;
    91        
    92         return EOK;
    93 }
    94 
    95 /*----------------------------------------------------------------------------*/
    96 
    97 static int usb_hid_set_boot_mouse_subdriver(usb_hid_dev_t *hid_dev)
    98 {
    99         assert(hid_dev != NULL && hid_dev->subdriver_count == 0);
    100        
    101         hid_dev->subdrivers = (usb_hid_subdriver_t *)malloc(
    102             sizeof(usb_hid_subdriver_t));
    103         if (hid_dev->subdrivers == NULL) {
    104                 return ENOMEM;
    105         }
    106        
    107         // set the init callback
    108         hid_dev->subdrivers[0].init = usb_mouse_init;
    109        
    110         // set the polling callback
    111         hid_dev->subdrivers[0].poll = usb_mouse_polling_callback;
    112        
    113         // set the polling ended callback
    114         hid_dev->subdrivers[0].poll_end = NULL;
    115        
    116         // set the deinit callback
    117         hid_dev->subdrivers[0].deinit = usb_mouse_deinit;
    118        
    119         // set subdriver count
    120         hid_dev->subdriver_count = 1;
    121        
    122         return EOK;
    123 }
    124 
    125 /*----------------------------------------------------------------------------*/
    126 
    127 static int usb_hid_set_generic_hid_subdriver(usb_hid_dev_t *hid_dev)
    128 {
    129         assert(hid_dev != NULL && hid_dev->subdriver_count == 0);
    130        
    131         hid_dev->subdrivers = (usb_hid_subdriver_t *)malloc(
    132             sizeof(usb_hid_subdriver_t));
    133         if (hid_dev->subdrivers == NULL) {
    134                 return ENOMEM;
    135         }
    136        
    137         // set the init callback
    138         hid_dev->subdrivers[0].init = NULL;
    139        
    140         // set the polling callback
    141         hid_dev->subdrivers[0].poll = usb_generic_hid_polling_callback;
    142        
    143         // set the polling ended callback
    144         hid_dev->subdrivers[0].poll_end = NULL;
    145        
    146         // set the deinit callback
    147         hid_dev->subdrivers[0].deinit = NULL;
    148        
    149         // set subdriver count
    150         hid_dev->subdriver_count = 1;
    151        
    152         return EOK;
    153 }
    154 
    155 /*----------------------------------------------------------------------------*/
    156 
    157 static bool usb_hid_ids_match(usb_hid_dev_t *hid_dev,
    158     const usb_hid_subdriver_mapping_t *mapping)
    159 {
    160         assert(hid_dev != NULL);
    161         assert(hid_dev->usb_dev != NULL);
    162        
    163         return (hid_dev->usb_dev->descriptors.device.vendor_id
    164             == mapping->vendor_id
    165             && hid_dev->usb_dev->descriptors.device.product_id
    166             == mapping->product_id);
    167 }
    168 
    169 /*----------------------------------------------------------------------------*/
    170 
    171 static bool usb_hid_path_matches(usb_hid_dev_t *hid_dev,
    172     const usb_hid_subdriver_mapping_t *mapping)
    173 {
    174         assert(hid_dev != NULL);
    175         assert(mapping != NULL);
    176        
    177         usb_hid_report_path_t *usage_path = usb_hid_report_path();
    178         if (usage_path == NULL) {
    179                 usb_log_debug("Failed to create usage path.\n");
    180                 return false;
    181         }
    182         int i = 0;
    183         while (mapping->usage_path[i].usage != 0
    184             || mapping->usage_path[i].usage_page != 0) {
    185                 if (usb_hid_report_path_append_item(usage_path,
    186                     mapping->usage_path[i].usage_page,
    187                     mapping->usage_path[i].usage) != EOK) {
    188                         usb_log_debug("Failed to append to usage path.\n");
    189                         usb_hid_report_path_free(usage_path);
    190                         return false;
    191                 }
    192                 ++i;
    193         }
    194        
    195         if (mapping->report_id >= 0) {
    196                 usb_hid_report_path_set_report_id(usage_path,
    197                     mapping->report_id);
    198         }
    199        
    200         assert(hid_dev->report != NULL);
    201        
    202         usb_log_debug("Compare flags: %d\n", mapping->compare);
    203         size_t size = usb_hid_report_input_length(hid_dev->report, usage_path,
    204             mapping->compare);
    205         usb_log_debug("Size of the input report: %zuB\n", size);
    206        
    207         usb_hid_report_path_free(usage_path);
    208        
    209         return (size > 0);
    210 }
    211 
    212 /*----------------------------------------------------------------------------*/
    213 
    214 static int usb_hid_save_subdrivers(usb_hid_dev_t *hid_dev,
    215     const usb_hid_subdriver_t **subdrivers, int count)
    216 {
    217         int i;
    218        
    219         if (count <= 0) {
    220                 hid_dev->subdriver_count = 0;
    221                 hid_dev->subdrivers = NULL;
    222                 return EOK;
    223         }
    224        
    225         hid_dev->subdrivers = (usb_hid_subdriver_t *)malloc(count *
    226             sizeof(usb_hid_subdriver_t));
    227         if (hid_dev->subdrivers == NULL) {
    228                 return ENOMEM;
    229         }
    230        
    231         for (i = 0; i < count; ++i) {
    232                 hid_dev->subdrivers[i].init = subdrivers[i]->init;
    233                 hid_dev->subdrivers[i].deinit = subdrivers[i]->deinit;
    234                 hid_dev->subdrivers[i].poll = subdrivers[i]->poll;
    235                 hid_dev->subdrivers[i].poll_end = subdrivers[i]->poll_end;
    236         }
    237        
    238         hid_dev->subdriver_count = count;
    239        
    240         return EOK;
    241 }
    242 
    243 /*----------------------------------------------------------------------------*/
    244 
    245 static int usb_hid_find_subdrivers(usb_hid_dev_t *hid_dev)
    246 {
    247         assert(hid_dev != NULL);
    248        
    249         const usb_hid_subdriver_t *subdrivers[USB_HID_MAX_SUBDRIVERS];
    250        
    251         int i = 0, count = 0;
    252         const usb_hid_subdriver_mapping_t *mapping = &usb_hid_subdrivers[i];
    253 
    254         bool ids_matched;
    255         bool matched;
    256        
    257         while (count < USB_HID_MAX_SUBDRIVERS &&
    258             (mapping->usage_path != NULL
    259             || mapping->vendor_id >= 0 || mapping->product_id >= 0)) {
    260                 // check the vendor & product ID
    261                 if (mapping->vendor_id >= 0 && mapping->product_id < 0) {
    262                         usb_log_warning("Missing Product ID for Vendor ID %d\n",
    263                             mapping->vendor_id);
    264                         return EINVAL;
    265                 }
    266                 if (mapping->product_id >= 0 && mapping->vendor_id < 0) {
    267                         usb_log_warning("Missing Vendor ID for Product ID %d\n",
    268                             mapping->product_id);
    269                         return EINVAL;
    270                 }
    271                
    272                 ids_matched = false;
    273                 matched = false;
    274                
    275                 if (mapping->vendor_id >= 0) {
    276                         assert(mapping->product_id >= 0);
    277                         usb_log_debug("Comparing device against vendor ID %u"
    278                             " and product ID %u.\n", mapping->vendor_id,
    279                             mapping->product_id);
    280                         if (usb_hid_ids_match(hid_dev, mapping)) {
    281                                 usb_log_debug("IDs matched.\n");
    282                                 ids_matched = true;
    283                         }
    284                 }
    285                
    286                 if (mapping->usage_path != NULL) {
    287                         usb_log_debug("Comparing device against usage path.\n");
    288                         if (usb_hid_path_matches(hid_dev, mapping)) {
    289                                 // does not matter if IDs were matched
    290                                 matched = true;
    291                         }
    292                 } else {
    293                         // matched only if IDs were matched and there is no path
    294                         matched = ids_matched;
    295                 }
    296                
    297                 if (matched) {
    298                         subdrivers[count++] = &mapping->subdriver;
    299                 }
    300                
    301                 mapping = &usb_hid_subdrivers[++i];
    302         }
    303        
    304         // we have all subdrivers determined, save them into the hid device
    305         return usb_hid_save_subdrivers(hid_dev, subdrivers, count);
    306 }
    307 
    308 /*----------------------------------------------------------------------------*/
    309 
    310 static int usb_hid_check_pipes(usb_hid_dev_t *hid_dev, usb_device_t *dev)
    311 {
    312         assert(hid_dev != NULL && dev != NULL);
    313        
    314         int rc = EOK;
    315        
    316         if (dev->pipes[USB_HID_KBD_POLL_EP_NO].present) {
    317                 usb_log_debug("Found keyboard endpoint.\n");
    318                 // save the pipe index
    319                 hid_dev->poll_pipe_index = USB_HID_KBD_POLL_EP_NO;
    320         } else if (dev->pipes[USB_HID_MOUSE_POLL_EP_NO].present) {
    321                 usb_log_debug("Found mouse endpoint.\n");
    322                 // save the pipe index
    323                 hid_dev->poll_pipe_index = USB_HID_MOUSE_POLL_EP_NO;
    324         } else if (dev->pipes[USB_HID_GENERIC_POLL_EP_NO].present) {
    325                 usb_log_debug("Found generic HID endpoint.\n");
    326                 // save the pipe index
    327                 hid_dev->poll_pipe_index = USB_HID_GENERIC_POLL_EP_NO;
    328         } else {
    329                 usb_log_error("None of supported endpoints found - probably"
    330                     " not a supported device.\n");
    331                 rc = ENOTSUP;
    332         }
    333        
    334         return rc;
    335 }
     70static const char *HID_MOUSE_FUN_NAME = "mouse";
     71static const char *HID_MOUSE_CLASS_NAME = "mouse";
    33672
    33773/*----------------------------------------------------------------------------*/
     
    34783        }
    34884       
    349         hid_dev->report = (usb_hid_report_t *)(malloc(sizeof(
    350             usb_hid_report_t)));
    351         if (hid_dev->report == NULL) {
     85        hid_dev->parser = (usb_hid_report_parser_t *)(malloc(sizeof(
     86            usb_hid_report_parser_t)));
     87        if (hid_dev->parser == NULL) {
    35288                usb_log_fatal("No memory!\n");
    35389                free(hid_dev);
     
    35591        }
    35692       
    357         hid_dev->poll_pipe_index = -1;
    358        
    35993        return hid_dev;
    36094}
     
    36296/*----------------------------------------------------------------------------*/
    36397
     98static bool usb_dummy_polling_callback(usb_device_t *dev, uint8_t *buffer,
     99     size_t buffer_size, void *arg)
     100{
     101        usb_log_debug("Dummy polling callback.\n");
     102        return false;
     103}
     104
     105/*----------------------------------------------------------------------------*/
     106
     107static int usb_hid_check_pipes(usb_hid_dev_t *hid_dev, usb_device_t *dev)
     108{
     109        if (dev->pipes[USB_HID_KBD_POLL_EP_NO].present) {
     110                usb_log_debug("Found keyboard endpoint.\n");
     111               
     112                // save the pipe index and device type
     113                hid_dev->poll_pipe_index = USB_HID_KBD_POLL_EP_NO;
     114                hid_dev->device_type = USB_HID_PROTOCOL_KEYBOARD;
     115               
     116                // set the polling callback
     117                hid_dev->poll_callback = usb_kbd_polling_callback;
     118
     119        } else if (dev->pipes[USB_HID_MOUSE_POLL_EP_NO].present) {
     120                usb_log_debug("Found mouse endpoint.\n");
     121               
     122                // save the pipe index and device type
     123                hid_dev->poll_pipe_index = USB_HID_MOUSE_POLL_EP_NO;
     124                hid_dev->device_type = USB_HID_PROTOCOL_MOUSE;
     125               
     126                // set the polling callback
     127                hid_dev->poll_callback = usb_dummy_polling_callback;
     128               
     129        } else if (dev->pipes[USB_HID_GENERIC_POLL_EP_NO].present) {
     130                usb_log_debug("Found generic HID endpoint.\n");
     131               
     132                // save the pipe index and device type
     133                hid_dev->poll_pipe_index = USB_HID_GENERIC_POLL_EP_NO;
     134                hid_dev->device_type = USB_HID_PROTOCOL_NONE;
     135               
     136                // set the polling callback
     137                hid_dev->poll_callback = usb_hid_polling_callback;
     138               
     139        } else {
     140                usb_log_warning("None of supported endpoints found - probably"
     141                    " not a supported device.\n");
     142                return ENOTSUP;
     143        }
     144       
     145        return EOK;
     146}
     147
     148/*----------------------------------------------------------------------------*/
     149
     150static int usb_hid_init_parser(usb_hid_dev_t *hid_dev)
     151{
     152        /* Initialize the report parser. */
     153        int rc = usb_hid_parser_init(hid_dev->parser);
     154        if (rc != EOK) {
     155                usb_log_error("Failed to initialize report parser.\n");
     156                return rc;
     157        }
     158       
     159        /* Get the report descriptor and parse it. */
     160        rc = usb_hid_process_report_descriptor(hid_dev->usb_dev,
     161            hid_dev->parser);
     162       
     163        if (rc != EOK) {
     164                usb_log_warning("Could not process report descriptor.\n");
     165               
     166                if (hid_dev->device_type == USB_HID_PROTOCOL_KEYBOARD) {
     167                        usb_log_warning("Falling back to boot protocol.\n");
     168                       
     169                        rc = usb_kbd_set_boot_protocol(hid_dev);
     170                       
     171                } else if (hid_dev->device_type == USB_HID_PROTOCOL_MOUSE) {
     172                        usb_log_warning("No boot protocol for mouse yet.\n");
     173                        rc = ENOTSUP;
     174                }
     175        }
     176       
     177        return rc;
     178}
     179
     180/*----------------------------------------------------------------------------*/
     181
    364182int usb_hid_init(usb_hid_dev_t *hid_dev, usb_device_t *dev)
    365183{
    366         int rc, i;
     184        int rc;
    367185       
    368186        usb_log_debug("Initializing HID structure...\n");
     
    385203        rc = usb_hid_check_pipes(hid_dev, dev);
    386204        if (rc != EOK) {
    387                 //usb_hid_free(&hid_dev);
    388205                return rc;
    389206        }
    390                
    391         /* Get the report descriptor and parse it. */
    392         rc = usb_hid_process_report_descriptor(hid_dev->usb_dev,
    393             hid_dev->report);
    394        
    395         bool fallback = false;
    396        
    397         if (rc == EOK) {
    398                 // try to find subdrivers that may want to handle this device
    399                 rc = usb_hid_find_subdrivers(hid_dev);
    400                 if (rc != EOK || hid_dev->subdriver_count == 0) {
    401                         // try to fall back to the boot protocol if available
    402                         usb_log_info("No subdrivers found to handle this"
    403                             " device.\n");
    404                         fallback = true;
    405                         assert(hid_dev->subdrivers == NULL);
    406                         assert(hid_dev->subdriver_count == 0);
     207       
     208        rc = usb_hid_init_parser(hid_dev);
     209        if (rc != EOK) {
     210                usb_log_error("Failed to initialize HID parser.\n");
     211                return rc;
     212        }
     213       
     214        switch (hid_dev->device_type) {
     215        case USB_HID_PROTOCOL_KEYBOARD:
     216                // initialize the keyboard structure
     217                rc = usb_kbd_init(hid_dev);
     218                if (rc != EOK) {
     219                        usb_log_warning("Failed to initialize KBD structure."
     220                            "\n");
    407221                }
    408         } else {
    409                 usb_log_error("Failed to parse Report descriptor.\n");
    410                 // try to fall back to the boot protocol if available
    411                 fallback = true;
    412         }
    413        
    414         // TODO: remove the mouse hack
    415         if (hid_dev->poll_pipe_index == USB_HID_MOUSE_POLL_EP_NO ||
    416             fallback) {
    417                 // fall back to boot protocol
    418                 switch (hid_dev->poll_pipe_index) {
    419                 case USB_HID_KBD_POLL_EP_NO:
    420                         usb_log_info("Falling back to kbd boot protocol.\n");
    421                         rc = usb_kbd_set_boot_protocol(hid_dev);
    422                         if (rc == EOK) {
    423                                 rc = usb_hid_set_boot_kbd_subdriver(hid_dev);
    424                         }
    425                         break;
    426                 case USB_HID_MOUSE_POLL_EP_NO:
    427                         usb_log_info("Falling back to mouse boot protocol.\n");
    428                         rc = usb_mouse_set_boot_protocol(hid_dev);
    429                         if (rc == EOK) {
    430                                 rc = usb_hid_set_boot_mouse_subdriver(hid_dev);
    431                         }
    432                         break;
    433                 default:
    434                         assert(hid_dev->poll_pipe_index
    435                             == USB_HID_GENERIC_POLL_EP_NO);
    436                        
    437                         /* TODO: this has no meaning if the report descriptor
    438                                  is not parsed */
    439                         usb_log_info("Falling back to generic HID driver.\n");
    440                         rc = usb_hid_set_generic_hid_subdriver(hid_dev);
    441                 }
    442         }
    443        
    444         if (rc != EOK) {
    445                 usb_log_error("No subdriver for handling this device could be"
    446                     " initialized: %s.\n", str_error(rc));
    447                 usb_log_debug("Subdriver count: %d\n",
    448                     hid_dev->subdriver_count);
    449                 //usb_hid_free(&hid_dev);
    450         } else {
    451                 bool ok = false;
    452                
    453                 usb_log_debug("Subdriver count: %d\n",
    454                     hid_dev->subdriver_count);
    455                
    456                 for (i = 0; i < hid_dev->subdriver_count; ++i) {
    457                         if (hid_dev->subdrivers[i].init != NULL) {
    458                                 usb_log_debug("Initializing subdriver %d.\n",i);
    459                                 rc = hid_dev->subdrivers[i].init(hid_dev);
    460                                 if (rc != EOK) {
    461                                         usb_log_warning("Failed to initialize"
    462                                             " HID subdriver structure.\n");
    463                                 } else {
    464                                         // at least one subdriver initialized
    465                                         ok = true;
    466                                 }
    467                         } else {
    468                                 ok = true;
    469                         }
    470                 }
    471                
    472                 rc = (ok) ? EOK : -1;   // what error to report
     222                break;
     223        case USB_HID_PROTOCOL_MOUSE:
     224                break;
     225        default:
     226//              usbhid_req_set_idle(&hid_dev->usb_dev->ctrl_pipe,
     227//                  hid_dev->usb_dev->interface_no, 0);
     228                break;
    473229        }
    474230       
    475231        return rc;
    476 }
    477 
    478 /*----------------------------------------------------------------------------*/
    479 
    480 bool usb_hid_polling_callback(usb_device_t *dev, uint8_t *buffer,
    481     size_t buffer_size, void *arg)
    482 {
    483         int i;
    484        
    485         if (dev == NULL || arg == NULL || buffer == NULL) {
    486                 usb_log_error("Missing arguments to polling callback.\n");
    487                 return false;
    488         }
    489        
    490         usb_hid_dev_t *hid_dev = (usb_hid_dev_t *)arg;
    491        
    492         bool cont = false;
    493        
    494         // continue if at least one of the subdrivers want to continue
    495         for (i = 0; i < hid_dev->subdriver_count; ++i) {
    496                 if (hid_dev->subdrivers[i].poll != NULL
    497                     && hid_dev->subdrivers[i].poll(hid_dev, buffer,
    498                     buffer_size)) {
    499                         cont = true;
    500                 }
    501         }
    502        
    503         return cont;
    504232}
    505233
     
    509237     void *arg)
    510238{
    511         int i;
    512        
    513239        if (dev == NULL || arg == NULL) {
    514240                return;
     
    517243        usb_hid_dev_t *hid_dev = (usb_hid_dev_t *)arg;
    518244       
    519         for (i = 0; i < hid_dev->subdriver_count; ++i) {
    520                 if (hid_dev->subdrivers[i].poll_end != NULL) {
    521                         hid_dev->subdrivers[i].poll_end(hid_dev, reason);
    522                 }
    523         }
    524        
    525245        usb_hid_free(&hid_dev);
    526246}
     
    528248/*----------------------------------------------------------------------------*/
    529249
    530 const char *usb_hid_get_function_name(const usb_hid_dev_t *hid_dev)
    531 {
    532         switch (hid_dev->poll_pipe_index) {
    533         case USB_HID_KBD_POLL_EP_NO:
     250const char *usb_hid_get_function_name(usb_hid_iface_protocol_t device_type)
     251{
     252        switch (device_type) {
     253        case USB_HID_PROTOCOL_KEYBOARD:
    534254                return HID_KBD_FUN_NAME;
    535255                break;
    536         case USB_HID_MOUSE_POLL_EP_NO:
     256        case USB_HID_PROTOCOL_MOUSE:
    537257                return HID_MOUSE_FUN_NAME;
    538258                break;
     
    544264/*----------------------------------------------------------------------------*/
    545265
    546 const char *usb_hid_get_class_name(const usb_hid_dev_t *hid_dev)
    547 {
    548         // this means that only boot protocol keyboards will be connected
    549         // to the console; there is probably no better way to do this
    550        
    551         switch (hid_dev->poll_pipe_index) {
    552         case USB_HID_KBD_POLL_EP_NO:
     266const char *usb_hid_get_class_name(usb_hid_iface_protocol_t device_type)
     267{
     268        switch (device_type) {
     269        case USB_HID_PROTOCOL_KEYBOARD:
    553270                return HID_KBD_CLASS_NAME;
    554271                break;
    555         case USB_HID_MOUSE_POLL_EP_NO:
     272        case USB_HID_PROTOCOL_MOUSE:
    556273                return HID_MOUSE_CLASS_NAME;
    557274                break;
     
    565282void usb_hid_free(usb_hid_dev_t **hid_dev)
    566283{
    567         int i;
    568        
    569284        if (hid_dev == NULL || *hid_dev == NULL) {
    570285                return;
    571286        }
    572287       
    573         usb_log_debug("Subdrivers: %p, subdriver count: %d\n",
    574             (*hid_dev)->subdrivers, (*hid_dev)->subdriver_count);
    575        
    576         assert((*hid_dev)->subdrivers != NULL
    577             || (*hid_dev)->subdriver_count == 0);
    578        
    579         for (i = 0; i < (*hid_dev)->subdriver_count; ++i) {
    580                 if ((*hid_dev)->subdrivers[i].deinit != NULL) {
    581                         (*hid_dev)->subdrivers[i].deinit(*hid_dev);
    582                 }
    583         }
    584        
    585         // free the subdrivers info
    586         if ((*hid_dev)->subdrivers != NULL) {
    587                 free((*hid_dev)->subdrivers);
     288        switch ((*hid_dev)->device_type) {
     289        case USB_HID_PROTOCOL_KEYBOARD:
     290                usb_kbd_deinit(*hid_dev);
     291                break;
     292        case USB_HID_PROTOCOL_MOUSE:
     293                break;
     294        default:
     295                break;
    588296        }
    589297
    590298        // destroy the parser
    591         if ((*hid_dev)->report != NULL) {
    592                 usb_hid_free_report((*hid_dev)->report);
     299        if ((*hid_dev)->parser != NULL) {
     300                usb_hid_free_report_parser((*hid_dev)->parser);
    593301        }
    594302
Note: See TracChangeset for help on using the changeset viewer.