Changeset 882f8b1 in mainline


Ignore:
Timestamp:
2011-02-27T00:07:24Z (13 years ago)
Author:
Lubos Slovak <lubos.slovak@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
c2fa801
Parents:
ad4562c2
Message:

Major changes to usbhid driver.

  • Changed structure usb_hid_dev_kbd_t
    • removed information parsed from descriptors (not needed anymore)
    • active mods and lock keys stored in it
  • Getting interface number assigned to my device.
  • Removed parsing of all descriptors.
  • Removed setting of configuration.
  • Fixed setting of protocol to the device (uses the assigned interface number).
  • Fixed LED setting
    • output buffer should have size 1
    • report type is in higher byte of wValue
    • using assigned interface number
  • Setting of default LEDs.
  • Completely rewritten function for getting report descriptor (usbkbd_get_report_descriptor())
    • now uses usb_dp_parser to find HID descriptor
    • then gets the report descriptor from the device
    • report descriptor is saved in the usb_hid_dev_kbd_t structure.
Location:
uspace/drv/usbhid
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • uspace/drv/usbhid/hid.h

    rad4562c2 r882f8b1  
    7070typedef struct {
    7171        ddf_dev_t *device;
    72         usb_hid_configuration_t *conf;
    73         usb_hid_report_parser_t *parser;
    7472
    7573        usb_device_connection_t wire;
     
    7775        usb_endpoint_pipe_t poll_pipe;
    7876       
     77        uint16_t iface;
     78       
     79        uint8_t *report_desc;
     80        usb_hid_report_parser_t *parser;
     81       
    7982        uint8_t *keycodes;
    8083        size_t keycode_count;
    8184        uint8_t modifiers;
     85       
     86        unsigned mods;
     87        unsigned lock_keys;
    8288} usb_hid_dev_kbd_t;
    8389
  • uspace/drv/usbhid/main.c

    rad4562c2 r882f8b1  
    5252#include <io/console.h>
    5353#include <stdint.h>
     54#include <usb/dp.h>
    5455#include "hid.h"
    55 #include "descparser.h"
    56 #include "descdump.h"
     56//#include "descparser.h"
     57//#include "descdump.h"
    5758#include "conv.h"
    5859#include "layout.h"
     
    6263#define NAME "usbhid"
    6364
    64 #define GUESSED_POLL_ENDPOINT 1
     65//#define GUESSED_POLL_ENDPOINT 1
    6566#define BOOTP_REPORT_SIZE 6
     67
     68static unsigned DEFAULT_ACTIVE_MODS = KM_NUM_LOCK;
    6669
    6770/** Keyboard polling endpoint description for boot protocol class. */
     
    144147 * TODO: put to device?
    145148 */
    146 static unsigned mods = KM_NUM_LOCK;
     149//static unsigned mods = KM_NUM_LOCK;
    147150
    148151/** Currently pressed lock keys. We track these to tackle autorepeat. 
     
    150153 * TODO: put to device?
    151154 */
    152 static unsigned lock_keys;
     155//static unsigned lock_keys;
    153156
    154157#define NUM_LAYOUTS 3
     
    195198}
    196199
    197 static void usbkbd_req_set_protocol(usb_hid_dev_kbd_t *kbd_dev, uint16_t iface,
     200static void usbkbd_req_set_protocol(usb_hid_dev_kbd_t *kbd_dev,
    198201    usb_hid_protocol_t protocol)
    199202{
     
    207210        }
    208211
    209         usb_log_debug("Sending Set_Protocol request to the device.\n");
     212        usb_log_debug("Sending Set_Protocol request to the device ("
     213            "protocol: %d, iface: %d).\n", protocol, kbd_dev->iface);
    210214       
    211215        rc = usb_control_request_set(&kbd_dev->ctrl_pipe,
    212216            USB_REQUEST_TYPE_CLASS, USB_REQUEST_RECIPIENT_INTERFACE,
    213             USB_HIDREQ_SET_PROTOCOL, protocol, iface, NULL, 0);
     217            USB_HIDREQ_SET_PROTOCOL, protocol, kbd_dev->iface, NULL, 0);
    214218
    215219        sess_rc = usb_endpoint_pipe_end_session(&kbd_dev->ctrl_pipe);
     
    228232}
    229233
    230 static void usbkbd_set_led(unsigned mods, usb_hid_dev_kbd_t *kbd_dev)
    231 {
    232         uint8_t buffer[BUFFER_SIZE];
    233         int rc= 0;
    234        
     234static void usbkbd_set_led(usb_hid_dev_kbd_t *kbd_dev)
     235{
     236        uint8_t buffer[BUFFER_OUT_SIZE];
     237        int rc= 0, i;
     238       
     239        memset(buffer, 0, BUFFER_OUT_SIZE);
    235240        uint8_t leds = 0;
    236241
    237         if (mods & KM_NUM_LOCK) {
     242        if (kbd_dev->mods & KM_NUM_LOCK) {
    238243                leds |= USB_HID_LED_NUM_LOCK;
    239244        }
    240245       
    241         if (mods & KM_CAPS_LOCK) {
     246        if (kbd_dev->mods & KM_CAPS_LOCK) {
    242247                leds |= USB_HID_LED_CAPS_LOCK;
    243248        }
    244249       
    245         if (mods & KM_SCROLL_LOCK) {
     250        if (kbd_dev->mods & KM_SCROLL_LOCK) {
    246251                leds |= USB_HID_LED_SCROLL_LOCK;
    247252        }
     
    250255       
    251256        usb_log_debug("Creating output report.\n");
     257        usb_log_debug("Leds: 0x%x\n", leds);
    252258        if ((rc = usb_hid_boot_keyboard_output_report(
    253             leds, buffer, BUFFER_SIZE)) != EOK) {
     259            leds, buffer, BUFFER_OUT_SIZE)) != EOK) {
    254260                usb_log_warning("Error composing output report to the keyboard:"
    255261                    "%s.\n", str_error(rc));
     
    257263        }
    258264       
    259         // TODO: determine what interface to use!! (now set to 1)
    260         usbkbd_req_set_report(kbd_dev, 1, USB_HID_REPORT_TYPE_OUTPUT, buffer,
    261             BUFFER_SIZE);
     265        usb_log_debug("Output report buffer: ");
     266        for (i = 0; i < BUFFER_OUT_SIZE; ++i) {
     267                usb_log_debug("0x%x ", buffer[i]);
     268        }
     269        usb_log_debug("\n");
     270       
     271        uint16_t value = 0;
     272        value |= (USB_HID_REPORT_TYPE_OUTPUT << 8);
     273
     274        usbkbd_req_set_report(kbd_dev, kbd_dev->iface, value, buffer,
     275            BUFFER_OUT_SIZE);
    262276}
    263277
     
    280294        if (mod_mask != 0) {
    281295                if (type == KEY_PRESS)
    282                         mods = mods | mod_mask;
     296                        kbd_dev->mods = kbd_dev->mods | mod_mask;
    283297                else
    284                         mods = mods & ~mod_mask;
     298                        kbd_dev->mods = kbd_dev->mods & ~mod_mask;
    285299        }
    286300
     
    294308        if (mod_mask != 0) {
    295309                usb_log_debug2("\n\nChanging mods and lock keys\n");
    296                 usb_log_debug2("\nmods before: 0x%x\n", mods);
    297                 usb_log_debug2("\nLock keys before:0x%x\n\n", lock_keys);
     310                usb_log_debug2("\nmods before: 0x%x\n", kbd_dev->mods);
     311                usb_log_debug2("\nLock keys before:0x%x\n\n", kbd_dev->lock_keys);
    298312               
    299313                if (type == KEY_PRESS) {
     
    304318                         * up the lock state.
    305319                         */
    306                         mods = mods ^ (mod_mask & ~lock_keys);
    307                         lock_keys = lock_keys | mod_mask;
     320                        kbd_dev->mods =
     321                            kbd_dev->mods ^ (mod_mask & ~kbd_dev->lock_keys);
     322                        kbd_dev->lock_keys = kbd_dev->lock_keys | mod_mask;
    308323
    309324                        /* Update keyboard lock indicator lights. */
    310                         usbkbd_set_led(mods, kbd_dev);
     325                        usbkbd_set_led(kbd_dev);
    311326                } else {
    312327                        usb_log_debug2("\nKey released.\n");
    313                         lock_keys = lock_keys & ~mod_mask;
    314                 }
    315         }
    316 /*
    317         usb_log_debug2("type: %d\n", type);
    318         usb_log_debug2("mods: 0x%x\n", mods);
    319         usb_log_debug2("keycode: %u\n", key);
    320 */
    321         usb_log_debug2("\n\nmods after: 0x%x\n", mods);
    322         usb_log_debug2("\nLock keys after: 0x%x\n\n", lock_keys);
    323        
    324         if (type == KEY_PRESS && (mods & KM_LCTRL) &&
    325                 key == KC_F1) {
     328                        kbd_dev->lock_keys = kbd_dev->lock_keys & ~mod_mask;
     329                }
     330        }
     331
     332        usb_log_debug2("\n\nmods after: 0x%x\n", kbd_dev->mods);
     333        usb_log_debug2("\nLock keys after: 0x%x\n\n", kbd_dev->lock_keys);
     334       
     335        if (type == KEY_PRESS && (kbd_dev->mods & KM_LCTRL) && key == KC_F1) {
    326336                active_layout = 0;
    327337                layout[active_layout]->reset();
     
    329339        }
    330340
    331         if (type == KEY_PRESS && (mods & KM_LCTRL) &&
    332                 key == KC_F2) {
     341        if (type == KEY_PRESS && (kbd_dev->mods & KM_LCTRL) && key == KC_F2) {
    333342                active_layout = 1;
    334343                layout[active_layout]->reset();
     
    336345        }
    337346
    338         if (type == KEY_PRESS && (mods & KM_LCTRL) &&
    339                 key == KC_F3) {
     347        if (type == KEY_PRESS && (kbd_dev->mods & KM_LCTRL) && key == KC_F3) {
    340348                active_layout = 2;
    341349                layout[active_layout]->reset();
     
    345353        ev.type = type;
    346354        ev.key = key;
    347         ev.mods = mods;
     355        ev.mods = kbd_dev->mods;
    348356       
    349357        if (ev.mods & KM_NUM_LOCK) {
     
    506514 * Kbd functions
    507515 */
    508 static int usbkbd_get_report_descriptor(usb_hid_dev_kbd_t *kbd_dev)
    509 {
    510         // iterate over all configurations and interfaces
    511         // TODO: more configurations!!
    512         unsigned i;
    513         for (i = 0; i < kbd_dev->conf->config_descriptor.interface_count; ++i) {
    514                 // TODO: endianness
    515                 uint16_t length =  kbd_dev->conf->interfaces[i].hid_desc.
    516                     report_desc_info.length;
    517                 size_t actual_size = 0;
    518 
    519                 // allocate space for the report descriptor
    520                 kbd_dev->conf->interfaces[i].report_desc =
    521                     (uint8_t *)malloc(length);
     516//static int usbkbd_get_report_descriptor(usb_hid_dev_kbd_t *kbd_dev)
     517//{
     518//      // iterate over all configurations and interfaces
     519//      // TODO: more configurations!!
     520//      unsigned i;
     521//      for (i = 0; i < kbd_dev->conf->config_descriptor.interface_count; ++i) {
     522//              // TODO: endianness
     523//              uint16_t length =  kbd_dev->conf->interfaces[i].hid_desc.
     524//                  report_desc_info.length;
     525//              size_t actual_size = 0;
     526
     527//              // allocate space for the report descriptor
     528//              kbd_dev->conf->interfaces[i].report_desc =
     529//                  (uint8_t *)malloc(length);
    522530               
    523                 // get the descriptor from the device
    524                 int rc = usb_request_get_descriptor(&kbd_dev->ctrl_pipe,
    525                     USB_REQUEST_TYPE_CLASS, USB_DESCTYPE_HID_REPORT,
    526                     i, 0,
    527                     kbd_dev->conf->interfaces[i].report_desc, length,
    528                     &actual_size);
    529 
    530                 if (rc != EOK) {
    531                         return rc;
    532                 }
    533 
    534                 assert(actual_size == length);
    535 
    536                 //dump_hid_class_descriptor(0, USB_DESCTYPE_HID_REPORT,
    537                 //    kbd_dev->conf->interfaces[i].report_desc, length);
    538         }
    539 
     531//              // get the descriptor from the device
     532//              int rc = usb_request_get_descriptor(&kbd_dev->ctrl_pipe,
     533//                  USB_REQUEST_TYPE_CLASS, USB_DESCTYPE_HID_REPORT,
     534//                  i, 0,
     535//                  kbd_dev->conf->interfaces[i].report_desc, length,
     536//                  &actual_size);
     537
     538//              if (rc != EOK) {
     539//                      return rc;
     540//              }
     541
     542//              assert(actual_size == length);
     543
     544//              //dump_hid_class_descriptor(0, USB_DESCTYPE_HID_REPORT,
     545//              //    kbd_dev->conf->interfaces[i].report_desc, length);
     546//      }
     547
     548//      return EOK;
     549//}
     550
     551static int usbkbd_get_report_descriptor(usb_hid_dev_kbd_t *kbd_dev,
     552    uint8_t *config_desc, size_t config_desc_size, uint8_t *iface_desc)
     553{
     554        assert(kbd_dev != NULL);
     555        assert(config_desc != NULL);
     556        assert(config_desc_size != 0);
     557        assert(iface_desc != NULL);
     558       
     559        usb_dp_parser_t parser =  {
     560                .nesting = usb_dp_standard_descriptor_nesting
     561        };
     562       
     563        usb_dp_parser_data_t parser_data = {
     564                .data = config_desc,
     565                .size = config_desc_size,
     566                .arg = NULL
     567        };
     568       
     569        /*
     570         * First nested descriptor of interface descriptor.
     571         */
     572        uint8_t *d =
     573            usb_dp_get_nested_descriptor(&parser, &parser_data, iface_desc);
     574       
     575        /*
     576         * Search through siblings until the HID descriptor is found.
     577         */
     578        while (d != NULL && *(d + 1) != USB_DESCTYPE_HID) {
     579                d = usb_dp_get_sibling_descriptor(&parser, &parser_data,
     580                    iface_desc, d);
     581        }
     582       
     583        if (d == NULL) {
     584                usb_log_fatal("No HID descriptor found!\n");
     585                return ENOENT;
     586        }
     587       
     588        if (*d != sizeof(usb_standard_hid_descriptor_t)) {
     589                usb_log_fatal("HID descriptor hass wrong size (%u, expected %u"
     590                    ")\n", *d, sizeof(usb_standard_hid_descriptor_t));
     591                return EINVAL;
     592        }
     593       
     594        usb_standard_hid_descriptor_t *hid_desc =
     595            (usb_standard_hid_descriptor_t *)d;
     596       
     597        uint16_t length =  hid_desc->report_desc_info.length;
     598        size_t actual_size = 0;
     599
     600        /*
     601         * Allocate space for the report descriptor.
     602         */
     603        kbd_dev->report_desc = (uint8_t *)malloc(length);
     604        if (kbd_dev->report_desc == NULL) {
     605                usb_log_fatal("Failed to allocate space for Report descriptor."
     606                    "\n");
     607                return ENOMEM;
     608        }
     609       
     610        usb_log_debug("Getting Report descriptor, expected size: %u\n", length);
     611       
     612        /*
     613         * Get the descriptor from the device.
     614         */
     615        int rc = usb_request_get_descriptor(&kbd_dev->ctrl_pipe,
     616            USB_REQUEST_TYPE_STANDARD, USB_REQUEST_RECIPIENT_INTERFACE,
     617            USB_DESCTYPE_HID_REPORT, 0,
     618            kbd_dev->iface, kbd_dev->report_desc, length, &actual_size);
     619
     620        if (rc != EOK) {
     621                return rc;
     622        }
     623
     624        if (actual_size != length) {
     625                free(kbd_dev->report_desc);
     626                kbd_dev->report_desc = NULL;
     627                usb_log_fatal("Report descriptor has wrong size (%u, expected "
     628                    "%u)\n", actual_size, length);
     629                return EINVAL;
     630        }
     631       
     632        usb_log_debug("Done.\n");
     633       
    540634        return EOK;
    541635}
     
    588682            descriptors, config_desc.total_length,
    589683            &kbd_dev->wire);
     684       
    590685        if (rc != EOK) {
    591686                usb_log_error("Failed to initialize poll pipe: %s.\n",
    592687                    str_error(rc));
     688                free(descriptors);
    593689                return rc;
    594690        }
     691       
    595692        if (!endpoint_mapping[0].present) {
    596693                usb_log_warning("Not accepting device, " \
    597694                    "not boot-protocol keyboard.\n");
     695                free(descriptors);
    598696                return EREFUSED;
    599697        }
    600 
    601         kbd_dev->conf = (usb_hid_configuration_t *)calloc(1,
    602             sizeof(usb_hid_configuration_t));
    603         if (kbd_dev->conf == NULL) {
     698       
     699        usb_log_debug("Accepted device. Saving interface, and getting Report"
     700            " descriptor.\n");
     701       
     702        /*
     703         * Save assigned interface number.
     704         */
     705        if (endpoint_mapping[0].interface_no < 0) {
     706                usb_log_error("Bad interface number.\n");
    604707                free(descriptors);
    605                 return ENOMEM;
    606         }
    607        
    608         /*rc = usbkbd_parse_descriptors(descriptors, transferred, kbd_dev->conf);
     708                return EINVAL;
     709        }
     710       
     711        kbd_dev->iface = endpoint_mapping[0].interface_no;
     712       
     713        assert(endpoint_mapping[0].interface != NULL);
     714       
     715        rc = usbkbd_get_report_descriptor(kbd_dev, descriptors, transferred,
     716            (uint8_t *)endpoint_mapping[0].interface);
     717       
    609718        free(descriptors);
    610         if (rc != EOK) {
    611                 usb_log_warning("Problem with parsing standard descriptors.\n");
    612                 return rc;
    613         }
    614 
    615         // get and report descriptors*/
    616         rc = usbkbd_get_report_descriptor(kbd_dev);
     719       
    617720        if (rc != EOK) {
    618721                usb_log_warning("Problem with parsing REPORT descriptor.\n");
     
    620723        }
    621724       
    622         //usbkbd_print_config(kbd_dev->conf);
    623 
    624         /*
    625          * TODO:
    626          * 1) select one configuration (lets say the first)
    627          * 2) how many interfaces?? how to select one??
    628          *    ("The default setting for an interface is always alternate
    629          *      setting zero.")
    630          * 3) find endpoint which is IN and INTERRUPT (parse), save its number
    631          *    as the endpoint for polling
    632          */
    633 
     725        usb_log_debug("Done parsing descriptors.\n");
     726       
    634727        return EOK;
    635728}
     
    671764
    672765        /*
    673          * will need all descriptors:
    674          * 1) choose one configuration from configuration descriptors
    675          *    (set it to the device)
    676          * 2) set endpoints from endpoint descriptors
    677          */
    678 
    679         // TODO: get descriptors, parse descriptors and save endpoints
     766         * Get descriptors, parse descriptors and save endpoints.
     767         */
    680768        usb_endpoint_pipe_start_session(&kbd_dev->ctrl_pipe);
     769       
    681770        rc = usbkbd_process_descriptors(kbd_dev);
     771       
    682772        usb_endpoint_pipe_end_session(&kbd_dev->ctrl_pipe);
    683773        if (rc != EOK) {
     
    685775        }
    686776       
    687         // save the size of the report
     777        // save the size of the report (boot protocol report by default)
    688778        kbd_dev->keycode_count = BOOTP_REPORT_SIZE;
    689779        kbd_dev->keycodes = (uint8_t *)calloc(
     
    695785        }
    696786       
    697         // set configuration to the first one
    698         // TODO: handle case with no configurations
    699         usb_endpoint_pipe_start_session(&kbd_dev->ctrl_pipe);
    700         usb_request_set_configuration(&kbd_dev->ctrl_pipe,
    701             kbd_dev->conf->config_descriptor.configuration_number);
    702         usb_endpoint_pipe_end_session(&kbd_dev->ctrl_pipe);
     787        kbd_dev->modifiers = 0;
     788        kbd_dev->mods = DEFAULT_ACTIVE_MODS;
     789        kbd_dev->lock_keys = 0;
    703790       
    704791        // set boot protocol
    705         usbkbd_req_set_protocol(kbd_dev, 1, USB_HID_PROTOCOL_BOOT);
     792        usbkbd_req_set_protocol(kbd_dev, USB_HID_PROTOCOL_BOOT);
     793       
     794        // set LEDs according to internal setup (NUM LOCK enabled)
     795        usbkbd_set_led(kbd_dev);
    706796       
    707797        return kbd_dev;
     
    743833
    744834        while (true) {
    745                 async_usleep(1000 * 1000);
     835                async_usleep(1000 * 10);
    746836
    747837                sess_rc = usb_endpoint_pipe_start_session(&kbd_dev->poll_pipe);
Note: See TracChangeset for help on using the changeset viewer.