Changeset f8e4cb6 in mainline


Ignore:
Timestamp:
2011-03-22T19:11:21Z (13 years ago)
Author:
Lubos Slovak <lubos.slovak@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
82d04a48
Parents:
62f4212
Message:

Ported usbhid driver to the new USB framework (#141).

Not tested thoroughly yet.

Location:
uspace/drv/usbhid
Files:
6 edited

Legend:

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

    r62f4212 rf8e4cb6  
    4141#include <usb/debug.h>
    4242#include <usb/request.h>
     43#include <usb/pipes.h>
    4344
    4445#include "hidreq.h"
    45 #include "hiddev.h"
    4646
    4747/*----------------------------------------------------------------------------*/
     
    6060 *         usb_control_request_set().
    6161 */
    62 int usbhid_req_set_report(usbhid_dev_t *hid_dev,
     62int usbhid_req_set_report(usb_pipe_t *ctrl_pipe, int iface_no,
    6363    usb_hid_report_type_t type, uint8_t *buffer, size_t buf_size)
    6464{
    65         if (hid_dev == NULL) {
    66                 usb_log_error("usbhid_req_set_report(): no HID device structure"
    67                     " given.\n");
    68                 return EINVAL;
    69         }
    70        
    71         /*
    72          * No need for checking other parameters, as they are checked in
    73          * the called function (usb_control_request_set()).
    74          */
    75        
    76         int rc, sess_rc;
    77        
    78         sess_rc = usb_pipe_start_session(&hid_dev->ctrl_pipe);
     65        if (ctrl_pipe == NULL) {
     66                usb_log_warning("usbhid_req_set_report(): no pipe given.\n");
     67                return EINVAL;
     68        }
     69       
     70        if (iface_no < 0) {
     71                usb_log_warning("usbhid_req_set_report(): no interface given."
     72                    "\n");
     73                return EINVAL;
     74        }
     75       
     76        /*
     77         * No need for checking other parameters, as they are checked in
     78         * the called function (usb_control_request_set()).
     79         */
     80       
     81        int rc, sess_rc;
     82       
     83        sess_rc = usb_pipe_start_session(ctrl_pipe);
    7984        if (sess_rc != EOK) {
    8085                usb_log_warning("Failed to start a session: %s.\n",
     
    8893        usb_log_debug("Sending Set_Report request to the device.\n");
    8994       
    90         rc = usb_control_request_set(&hid_dev->ctrl_pipe,
    91             USB_REQUEST_TYPE_CLASS, USB_REQUEST_RECIPIENT_INTERFACE,
    92             USB_HIDREQ_SET_REPORT, value, hid_dev->iface, buffer, buf_size);
    93 
    94         sess_rc = usb_pipe_end_session(&hid_dev->ctrl_pipe);
     95        rc = usb_control_request_set(ctrl_pipe,
     96            USB_REQUEST_TYPE_CLASS, USB_REQUEST_RECIPIENT_INTERFACE,
     97            USB_HIDREQ_SET_REPORT, value, iface_no, buffer, buf_size);
     98
     99        sess_rc = usb_pipe_end_session(ctrl_pipe);
    95100
    96101        if (rc != EOK) {
     
    122127 *         usb_control_request_set().
    123128 */
    124 int usbhid_req_set_protocol(usbhid_dev_t *hid_dev, usb_hid_protocol_t protocol)
    125 {
    126         if (hid_dev == NULL) {
    127                 usb_log_error("usbhid_req_set_protocol(): no HID device "
    128                     "structure given.\n");
    129                 return EINVAL;
    130         }
    131        
    132         /*
    133          * No need for checking other parameters, as they are checked in
    134          * the called function (usb_control_request_set()).
    135          */
    136        
    137         int rc, sess_rc;
    138        
    139         sess_rc = usb_pipe_start_session(&hid_dev->ctrl_pipe);
     129int usbhid_req_set_protocol(usb_pipe_t *ctrl_pipe, int iface_no,
     130    usb_hid_protocol_t protocol)
     131{
     132        if (ctrl_pipe == NULL) {
     133                usb_log_warning("usbhid_req_set_report(): no pipe given.\n");
     134                return EINVAL;
     135        }
     136       
     137        if (iface_no < 0) {
     138                usb_log_warning("usbhid_req_set_report(): no interface given."
     139                    "\n");
     140                return EINVAL;
     141        }
     142       
     143        /*
     144         * No need for checking other parameters, as they are checked in
     145         * the called function (usb_control_request_set()).
     146         */
     147       
     148        int rc, sess_rc;
     149       
     150        sess_rc = usb_pipe_start_session(ctrl_pipe);
    140151        if (sess_rc != EOK) {
    141152                usb_log_warning("Failed to start a session: %s.\n",
     
    145156
    146157        usb_log_debug("Sending Set_Protocol request to the device ("
    147             "protocol: %d, iface: %d).\n", protocol, hid_dev->iface);
    148        
    149         rc = usb_control_request_set(&hid_dev->ctrl_pipe,
    150             USB_REQUEST_TYPE_CLASS, USB_REQUEST_RECIPIENT_INTERFACE,
    151             USB_HIDREQ_SET_PROTOCOL, protocol, hid_dev->iface, NULL, 0);
    152 
    153         sess_rc = usb_pipe_end_session(&hid_dev->ctrl_pipe);
     158            "protocol: %d, iface: %d).\n", protocol, iface_no);
     159       
     160        rc = usb_control_request_set(ctrl_pipe,
     161            USB_REQUEST_TYPE_CLASS, USB_REQUEST_RECIPIENT_INTERFACE,
     162            USB_HIDREQ_SET_PROTOCOL, protocol, iface_no, NULL, 0);
     163
     164        sess_rc = usb_pipe_end_session(ctrl_pipe);
    154165
    155166        if (rc != EOK) {
     
    182193 *         usb_control_request_set().
    183194 */
    184 int usbhid_req_set_idle(usbhid_dev_t *hid_dev, uint8_t duration)
    185 {
    186         if (hid_dev == NULL) {
    187                 usb_log_error("usbhid_req_set_idle(): no HID device "
    188                     "structure given.\n");
    189                 return EINVAL;
    190         }
    191        
    192         /*
    193          * No need for checking other parameters, as they are checked in
    194          * the called function (usb_control_request_set()).
    195          */
    196        
    197         int rc, sess_rc;
    198        
    199         sess_rc = usb_pipe_start_session(&hid_dev->ctrl_pipe);
     195int usbhid_req_set_idle(usb_pipe_t *ctrl_pipe, int iface_no, uint8_t duration)
     196{
     197        if (ctrl_pipe == NULL) {
     198                usb_log_warning("usbhid_req_set_report(): no pipe given.\n");
     199                return EINVAL;
     200        }
     201       
     202        if (iface_no < 0) {
     203                usb_log_warning("usbhid_req_set_report(): no interface given."
     204                    "\n");
     205                return EINVAL;
     206        }
     207       
     208        /*
     209         * No need for checking other parameters, as they are checked in
     210         * the called function (usb_control_request_set()).
     211         */
     212       
     213        int rc, sess_rc;
     214       
     215        sess_rc = usb_pipe_start_session(ctrl_pipe);
    200216        if (sess_rc != EOK) {
    201217                usb_log_warning("Failed to start a session: %s.\n",
     
    205221
    206222        usb_log_debug("Sending Set_Idle request to the device ("
    207             "duration: %u, iface: %d).\n", duration, hid_dev->iface);
     223            "duration: %u, iface: %d).\n", duration, iface_no);
    208224       
    209225        uint16_t value = duration << 8;
    210226       
    211         rc = usb_control_request_set(&hid_dev->ctrl_pipe,
    212             USB_REQUEST_TYPE_CLASS, USB_REQUEST_RECIPIENT_INTERFACE,
    213             USB_HIDREQ_SET_IDLE, value, hid_dev->iface, NULL, 0);
    214 
    215         sess_rc = usb_pipe_end_session(&hid_dev->ctrl_pipe);
     227        rc = usb_control_request_set(ctrl_pipe,
     228            USB_REQUEST_TYPE_CLASS, USB_REQUEST_RECIPIENT_INTERFACE,
     229            USB_HIDREQ_SET_IDLE, value, iface_no, NULL, 0);
     230
     231        sess_rc = usb_pipe_end_session(ctrl_pipe);
    216232
    217233        if (rc != EOK) {
     
    247263 *         usb_control_request_set().
    248264 */
    249 int usbhid_req_get_report(usbhid_dev_t *hid_dev, usb_hid_report_type_t type,
    250     uint8_t *buffer, size_t buf_size, size_t *actual_size)
    251 {
    252         if (hid_dev == NULL) {
    253                 usb_log_error("usbhid_req_set_report(): no HID device structure"
    254                     " given.\n");
    255                 return EINVAL;
    256         }
    257        
    258         /*
    259          * No need for checking other parameters, as they are checked in
    260          * the called function (usb_control_request_set()).
    261          */
    262        
    263         int rc, sess_rc;
    264        
    265         sess_rc = usb_pipe_start_session(&hid_dev->ctrl_pipe);
     265int usbhid_req_get_report(usb_pipe_t *ctrl_pipe, int iface_no,
     266    usb_hid_report_type_t type, uint8_t *buffer, size_t buf_size,
     267    size_t *actual_size)
     268{
     269        if (ctrl_pipe == NULL) {
     270                usb_log_warning("usbhid_req_set_report(): no pipe given.\n");
     271                return EINVAL;
     272        }
     273       
     274        if (iface_no < 0) {
     275                usb_log_warning("usbhid_req_set_report(): no interface given."
     276                    "\n");
     277                return EINVAL;
     278        }
     279       
     280        /*
     281         * No need for checking other parameters, as they are checked in
     282         * the called function (usb_control_request_set()).
     283         */
     284       
     285        int rc, sess_rc;
     286       
     287        sess_rc = usb_pipe_start_session(ctrl_pipe);
    266288        if (sess_rc != EOK) {
    267289                usb_log_warning("Failed to start a session: %s.\n",
     
    275297        usb_log_debug("Sending Get_Report request to the device.\n");
    276298       
    277         rc = usb_control_request_get(&hid_dev->ctrl_pipe,
    278             USB_REQUEST_TYPE_CLASS, USB_REQUEST_RECIPIENT_INTERFACE,
    279             USB_HIDREQ_GET_REPORT, value, hid_dev->iface, buffer, buf_size,
     299        rc = usb_control_request_get(ctrl_pipe,
     300            USB_REQUEST_TYPE_CLASS, USB_REQUEST_RECIPIENT_INTERFACE,
     301            USB_HIDREQ_GET_REPORT, value, iface_no, buffer, buf_size,
    280302            actual_size);
    281303
    282         sess_rc = usb_pipe_end_session(&hid_dev->ctrl_pipe);
     304        sess_rc = usb_pipe_end_session(ctrl_pipe);
    283305
    284306        if (rc != EOK) {
     
    310332 *         usb_control_request_set().
    311333 */
    312 int usbhid_req_get_protocol(usbhid_dev_t *hid_dev, usb_hid_protocol_t *protocol)
    313 {
    314         if (hid_dev == NULL) {
    315                 usb_log_error("usbhid_req_set_protocol(): no HID device "
    316                     "structure given.\n");
    317                 return EINVAL;
    318         }
    319        
    320         /*
    321          * No need for checking other parameters, as they are checked in
    322          * the called function (usb_control_request_set()).
    323          */
    324        
    325         int rc, sess_rc;
    326        
    327         sess_rc = usb_pipe_start_session(&hid_dev->ctrl_pipe);
     334int usbhid_req_get_protocol(usb_pipe_t *ctrl_pipe, int iface_no,
     335    usb_hid_protocol_t *protocol)
     336{
     337        if (ctrl_pipe == NULL) {
     338                usb_log_warning("usbhid_req_set_report(): no pipe given.\n");
     339                return EINVAL;
     340        }
     341       
     342        if (iface_no < 0) {
     343                usb_log_warning("usbhid_req_set_report(): no interface given."
     344                    "\n");
     345                return EINVAL;
     346        }
     347       
     348        /*
     349         * No need for checking other parameters, as they are checked in
     350         * the called function (usb_control_request_set()).
     351         */
     352       
     353        int rc, sess_rc;
     354       
     355        sess_rc = usb_pipe_start_session(ctrl_pipe);
    328356        if (sess_rc != EOK) {
    329357                usb_log_warning("Failed to start a session: %s.\n",
     
    333361
    334362        usb_log_debug("Sending Get_Protocol request to the device ("
    335             "iface: %d).\n", hid_dev->iface);
     363            "iface: %d).\n", iface_no);
    336364       
    337365        uint8_t buffer[1];
    338366        size_t actual_size = 0;
    339367       
    340         rc = usb_control_request_get(&hid_dev->ctrl_pipe,
    341             USB_REQUEST_TYPE_CLASS, USB_REQUEST_RECIPIENT_INTERFACE,
    342             USB_HIDREQ_GET_PROTOCOL, 0, hid_dev->iface, buffer, 1, &actual_size);
    343 
    344         sess_rc = usb_pipe_end_session(&hid_dev->ctrl_pipe);
     368        rc = usb_control_request_get(ctrl_pipe,
     369            USB_REQUEST_TYPE_CLASS, USB_REQUEST_RECIPIENT_INTERFACE,
     370            USB_HIDREQ_GET_PROTOCOL, 0, iface_no, buffer, 1, &actual_size);
     371
     372        sess_rc = usb_pipe_end_session(ctrl_pipe);
    345373
    346374        if (rc != EOK) {
     
    381409 *         usb_control_request_set().
    382410 */
    383 int usbhid_req_get_idle(usbhid_dev_t *hid_dev, uint8_t *duration)
    384 {
    385         if (hid_dev == NULL) {
    386                 usb_log_error("usbhid_req_set_idle(): no HID device "
    387                     "structure given.\n");
    388                 return EINVAL;
    389         }
    390        
    391         /*
    392          * No need for checking other parameters, as they are checked in
    393          * the called function (usb_control_request_set()).
    394          */
    395        
    396         int rc, sess_rc;
    397        
    398         sess_rc = usb_pipe_start_session(&hid_dev->ctrl_pipe);
     411int usbhid_req_get_idle(usb_pipe_t *ctrl_pipe, int iface_no, uint8_t *duration)
     412{
     413        if (ctrl_pipe == NULL) {
     414                usb_log_warning("usbhid_req_set_report(): no pipe given.\n");
     415                return EINVAL;
     416        }
     417       
     418        if (iface_no < 0) {
     419                usb_log_warning("usbhid_req_set_report(): no interface given."
     420                    "\n");
     421                return EINVAL;
     422        }
     423       
     424        /*
     425         * No need for checking other parameters, as they are checked in
     426         * the called function (usb_control_request_set()).
     427         */
     428       
     429        int rc, sess_rc;
     430       
     431        sess_rc = usb_pipe_start_session(ctrl_pipe);
    399432        if (sess_rc != EOK) {
    400433                usb_log_warning("Failed to start a session: %s.\n",
     
    404437
    405438        usb_log_debug("Sending Get_Idle request to the device ("
    406             "iface: %d).\n", hid_dev->iface);
     439            "iface: %d).\n", iface_no);
    407440       
    408441        uint16_t value = 0;
     
    410443        size_t actual_size = 0;
    411444       
    412         rc = usb_control_request_get(&hid_dev->ctrl_pipe,
    413             USB_REQUEST_TYPE_CLASS, USB_REQUEST_RECIPIENT_INTERFACE,
    414             USB_HIDREQ_GET_IDLE, value, hid_dev->iface, buffer, 1,
     445        rc = usb_control_request_get(ctrl_pipe,
     446            USB_REQUEST_TYPE_CLASS, USB_REQUEST_RECIPIENT_INTERFACE,
     447            USB_HIDREQ_GET_IDLE, value, iface_no, buffer, 1,
    415448            &actual_size);
    416449
    417         sess_rc = usb_pipe_end_session(&hid_dev->ctrl_pipe);
     450        sess_rc = usb_pipe_end_session(ctrl_pipe);
    418451
    419452        if (rc != EOK) {
  • uspace/drv/usbhid/hidreq.h

    r62f4212 rf8e4cb6  
    4040
    4141#include <usb/classes/hid.h>
     42#include <usb/pipes.h>
    4243
    4344#include "hiddev.h"
     
    4546/*----------------------------------------------------------------------------*/
    4647
    47 int usbhid_req_set_report(usbhid_dev_t *hid_dev,
     48int usbhid_req_set_report(usb_pipe_t *ctrl_pipe, int iface_no,
    4849    usb_hid_report_type_t type, uint8_t *buffer, size_t buf_size);
    4950
    50 int usbhid_req_set_protocol(usbhid_dev_t *hid_dev, usb_hid_protocol_t protocol);
     51int usbhid_req_set_protocol(usb_pipe_t *ctrl_pipe, int iface_no,
     52    usb_hid_protocol_t protocol);
    5153
    52 int usbhid_req_set_idle(usbhid_dev_t *hid_dev, uint8_t duration);
     54int usbhid_req_set_idle(usb_pipe_t *ctrl_pipe, int iface_no, uint8_t duration);
    5355
    54 int usbhid_req_get_report(usbhid_dev_t *hid_dev, usb_hid_report_type_t type,
    55     uint8_t *buffer, size_t buf_size, size_t *actual_size);
     56int usbhid_req_get_report(usb_pipe_t *ctrl_pipe, int iface_no,
     57    usb_hid_report_type_t type, uint8_t *buffer, size_t buf_size,
     58    size_t *actual_size);
    5659
    57 int usbhid_req_get_protocol(usbhid_dev_t *hid_dev, usb_hid_protocol_t *protocol);
     60int usbhid_req_get_protocol(usb_pipe_t *ctrl_pipe, int iface_no,
     61    usb_hid_protocol_t *protocol);
    5862
    59 int usbhid_req_get_idle(usbhid_dev_t *hid_dev, uint8_t *duration);
     63int usbhid_req_get_idle(usb_pipe_t *ctrl_pipe, int iface_no, uint8_t *duration);
    6064
    6165/*----------------------------------------------------------------------------*/
  • uspace/drv/usbhid/kbddev.c

    r62f4212 rf8e4cb6  
    4646
    4747#include <usb/usb.h>
     48#include <usb/dp.h>
     49#include <usb/request.h>
    4850#include <usb/classes/hid.h>
    4951#include <usb/pipes.h>
     
    5355#include <usb/classes/hidut.h>
    5456
     57#include <usb/devdrv.h>
     58
    5559#include "kbddev.h"
    5660#include "hiddev.h"
     
    8690
    8791/** Keyboard polling endpoint description for boot protocol class. */
    88 static usb_endpoint_description_t poll_endpoint_description = {
     92static usb_endpoint_description_t boot_poll_endpoint_description = {
    8993        .transfer_type = USB_TRANSFER_INTERRUPT,
    9094        .direction = USB_DIRECTION_IN,
     
    9498        .flags = 0
    9599};
     100
     101/** General keyboard polling endpoint description. */
     102//static usb_endpoint_description_t general_poll_endpoint_description = {
     103//      .transfer_type = USB_TRANSFER_INTERRUPT,
     104//      .direction = USB_DIRECTION_IN,
     105//      .interface_class = USB_CLASS_HID,
     106//      .flags = 0
     107//};
     108
     109/* Array of endpoints expected on the device, NULL terminated. */
     110usb_endpoint_description_t
     111    *usbhid_kbd_endpoints[USBHID_KBD_POLL_EP_COUNT + 1] = {
     112        &boot_poll_endpoint_description,
     113//      &general_poll_endpoint_description,
     114        NULL
     115};
     116
    96117
    97118typedef enum usbhid_kbd_flags {
     
    149170
    150171static void default_connection_handler(ddf_fun_t *, ipc_callid_t, ipc_call_t *);
    151 static ddf_dev_ops_t keyboard_ops = {
     172ddf_dev_ops_t keyboard_ops = {
    152173        .default_handler = default_connection_handler
    153174};
     
    237258            usb_debug_str_buffer(buffer, BOOTP_BUFFER_OUT_SIZE, 0));
    238259       
    239         assert(kbd_dev->hid_dev != NULL);
    240         assert(kbd_dev->hid_dev->initialized == USBHID_KBD_STATUS_INITIALIZED);
    241         usbhid_req_set_report(kbd_dev->hid_dev, USB_HID_REPORT_TYPE_OUTPUT,
     260        assert(kbd_dev->usb_dev != NULL);
     261       
     262        usbhid_req_set_report(&kbd_dev->usb_dev->ctrl_pipe,
     263            kbd_dev->usb_dev->interface_no, USB_HID_REPORT_TYPE_OUTPUT,
    242264            buffer, BOOTP_BUFFER_OUT_SIZE);
    243265}
     
    370392//{
    371393//      /*
    372 //       * TODO: why the USB keyboard has NUM_, SCROLL_ and CAPS_LOCK
     394//       * why the USB keyboard has NUM_, SCROLL_ and CAPS_LOCK
    373395//       *       both as modifiers and as keyUSB_HID_LOCK_COUNTs with their own scancodes???
    374396//       *
     
    434456         * First of all, check if the kbd have reported phantom state.
    435457         *
    436          * TODO: this must be changed as we don't know which keys are modifiers
     458         * this must be changed as we don't know which keys are modifiers
    437459         *       and which are regular keys.
    438460         */
     
    566588 * @param actual_size Size of the data from keyboard (report size) in bytes.
    567589 *
    568  * @sa usbhid_kbd_process_keycodes(), usb_hid_boot_keyboard_input_report().
     590 * @sa usbhid_kbd_process_keycodes(), usb_hid_boot_keyboard_input_report(),
     591 *     usb_hid_parse_report().
    569592 */
    570593static void usbhid_kbd_process_data(usbhid_kbd_t *kbd_dev,
     
    572595{
    573596        assert(kbd_dev->initialized == USBHID_KBD_STATUS_INITIALIZED);
    574         assert(kbd_dev->hid_dev->parser != NULL);
     597        assert(kbd_dev->parser != NULL);
    575598       
    576599        usb_hid_report_in_callbacks_t *callbacks =
     
    585608//      int rc = usb_hid_boot_keyboard_input_report(buffer, actual_size,
    586609//          callbacks, kbd_dev);
    587         int rc = usb_hid_parse_report(kbd_dev->hid_dev->parser, buffer,
     610        int rc = usb_hid_parse_report(kbd_dev->parser, buffer,
    588611            actual_size, callbacks, kbd_dev);
    589612       
     
    597620/* HID/KBD structure manipulation                                             */
    598621/*----------------------------------------------------------------------------*/
     622
     623static void usbhid_kbd_mark_unusable(usbhid_kbd_t *kbd_dev)
     624{
     625        kbd_dev->initialized = USBHID_KBD_STATUS_TO_DESTROY;
     626}
     627
     628/*----------------------------------------------------------------------------*/
     629/* HID/KBD polling                                                            */
     630/*----------------------------------------------------------------------------*/
     631/**
     632 * Main keyboard polling function.
     633 *
     634 * This function uses the Interrupt In pipe of the keyboard to poll for events.
     635 * The keyboard is initialized in a way that it reports only when a key is
     636 * pressed or released, so there is no actual need for any sleeping between
     637 * polls (see usbhid_kbd_try_add_device() or usbhid_kbd_init()).
     638 *
     639 * @param kbd_dev Initialized keyboard structure representing the device to
     640 *                poll.
     641 *
     642 * @sa usbhid_kbd_process_data()
     643 */
     644//static void usbhid_kbd_poll(usbhid_kbd_t *kbd_dev)
     645//{
     646//      int rc, sess_rc;
     647//      uint8_t buffer[BOOTP_BUFFER_SIZE];
     648//      size_t actual_size;
     649       
     650//      usb_log_debug("Polling keyboard...\n");
     651       
     652//      if (!kbd_dev->initialized) {
     653//              usb_log_error("HID/KBD device not initialized!\n");
     654//              return;
     655//      }
     656       
     657//      assert(kbd_dev->hid_dev != NULL);
     658//      assert(kbd_dev->hid_dev->initialized);
     659
     660//      while (true) {
     661//              sess_rc = usb_pipe_start_session(
     662//                  &kbd_dev->hid_dev->poll_pipe);
     663//              if (sess_rc != EOK) {
     664//                      usb_log_warning("Failed to start a session: %s.\n",
     665//                          str_error(sess_rc));
     666//                      break;
     667//              }
     668
     669//              rc = usb_pipe_read(&kbd_dev->hid_dev->poll_pipe,
     670//                  buffer, BOOTP_BUFFER_SIZE, &actual_size);
     671               
     672//              sess_rc = usb_pipe_end_session(
     673//                  &kbd_dev->hid_dev->poll_pipe);
     674
     675//              if (rc != EOK) {
     676//                      usb_log_warning("Error polling the keyboard: %s.\n",
     677//                          str_error(rc));
     678//                      break;
     679//              }
     680
     681//              if (sess_rc != EOK) {
     682//                      usb_log_warning("Error closing session: %s.\n",
     683//                          str_error(sess_rc));
     684//                      break;
     685//              }
     686
     687//              /*
     688//               * If the keyboard answered with NAK, it returned no data.
     689//               * This implies that no change happened since last query.
     690//               */
     691//              if (actual_size == 0) {
     692//                      usb_log_debug("Keyboard returned NAK\n");
     693//                      continue;
     694//              }
     695
     696//              /*
     697//               * TODO: Process pressed keys.
     698//               */
     699//              usb_log_debug("Calling usbhid_kbd_process_data()\n");
     700//              usbhid_kbd_process_data(kbd_dev, buffer, actual_size);
     701               
     702//              // disabled for now, no reason to sleep
     703//              //async_usleep(kbd_dev->hid_dev->poll_interval);
     704//      }
     705//}
     706
     707/*----------------------------------------------------------------------------*/
     708/**
     709 * Function executed by the main driver fibril.
     710 *
     711 * Just starts polling the keyboard for events.
     712 *
     713 * @param arg Initialized keyboard device structure (of type usbhid_kbd_t)
     714 *            representing the device.
     715 *
     716 * @retval EOK if the fibril finished polling the device.
     717 * @retval EINVAL if no device was given in the argument.
     718 *
     719 * @sa usbhid_kbd_poll()
     720 *
     721 * @todo Change return value - only case when the fibril finishes is in case
     722 *       of some error, so the error should probably be propagated from function
     723 *       usbhid_kbd_poll() to here and up.
     724 */
     725//static int usbhid_kbd_fibril(void *arg)
     726//{
     727//      if (arg == NULL) {
     728//              usb_log_error("No device!\n");
     729//              return EINVAL;
     730//      }
     731       
     732//      usbhid_kbd_t *kbd_dev = (usbhid_kbd_t *)arg;
     733
     734//      usbhid_kbd_poll(kbd_dev);
     735       
     736//      // as there is another fibril using this device, so we must leave the
     737//      // structure to it, but mark it for destroying.
     738//      usbhid_kbd_mark_unusable(kbd_dev);
     739//      // at the end, properly destroy the KBD structure
     740////    usbhid_kbd_free(&kbd_dev);
     741////    assert(kbd_dev == NULL);
     742
     743//      return EOK;
     744//}
     745
     746static int usbhid_dev_get_report_descriptor(usbhid_kbd_t *kbd_dev)
     747{
     748        assert(kbd_dev != NULL);
     749        assert(kbd_dev->usb_dev != NULL);
     750        assert(kbd_dev->usb_dev->interface_no >= 0);
     751       
     752        usb_dp_parser_t parser =  {
     753                .nesting = usb_dp_standard_descriptor_nesting
     754        };
     755       
     756        usb_dp_parser_data_t parser_data = {
     757                .data = kbd_dev->usb_dev->descriptors.configuration,
     758                .size = kbd_dev->usb_dev->descriptors.configuration_size,
     759                .arg = NULL
     760        };
     761       
     762        /*
     763         * First nested descriptor of the configuration descriptor.
     764         */
     765        uint8_t *d =
     766            usb_dp_get_nested_descriptor(&parser, &parser_data,
     767            kbd_dev->usb_dev->descriptors.configuration);
     768       
     769        /*
     770         * Find the interface descriptor corresponding to our interface number.
     771         */
     772        int i = 0;
     773        while (d != NULL && i < kbd_dev->usb_dev->interface_no) {
     774                d = usb_dp_get_sibling_descriptor(&parser, &parser_data,
     775                    kbd_dev->usb_dev->descriptors.configuration, d);
     776        }
     777       
     778        if (d == NULL) {
     779                usb_log_fatal("The %. interface descriptor not found!\n",
     780                    kbd_dev->usb_dev->interface_no);
     781                return ENOENT;
     782        }
     783       
     784        /*
     785         * First nested descriptor of the interface descriptor.
     786         */
     787        uint8_t *iface_desc = d;
     788        d = usb_dp_get_nested_descriptor(&parser, &parser_data, iface_desc);
     789       
     790        /*
     791         * Search through siblings until the HID descriptor is found.
     792         */
     793        while (d != NULL && *(d + 1) != USB_DESCTYPE_HID) {
     794                d = usb_dp_get_sibling_descriptor(&parser, &parser_data,
     795                    iface_desc, d);
     796        }
     797       
     798        if (d == NULL) {
     799                usb_log_fatal("No HID descriptor found!\n");
     800                return ENOENT;
     801        }
     802       
     803        if (*d != sizeof(usb_standard_hid_descriptor_t)) {
     804                usb_log_fatal("HID descriptor hass wrong size (%u, expected %u"
     805                    ")\n", *d, sizeof(usb_standard_hid_descriptor_t));
     806                return EINVAL;
     807        }
     808       
     809        usb_standard_hid_descriptor_t *hid_desc =
     810            (usb_standard_hid_descriptor_t *)d;
     811       
     812        uint16_t length =  hid_desc->report_desc_info.length;
     813        size_t actual_size = 0;
     814       
     815        /*
     816         * Start session for the control transfer.
     817         */
     818        int sess_rc = usb_pipe_start_session(&kbd_dev->usb_dev->ctrl_pipe);
     819        if (sess_rc != EOK) {
     820                usb_log_warning("Failed to start a session: %s.\n",
     821                    str_error(sess_rc));
     822                return sess_rc;
     823        }
     824
     825        /*
     826         * Allocate space for the report descriptor.
     827         */
     828        kbd_dev->report_desc = (uint8_t *)malloc(length);
     829        if (kbd_dev->report_desc == NULL) {
     830                usb_log_fatal("Failed to allocate space for Report descriptor."
     831                    "\n");
     832                return ENOMEM;
     833        }
     834       
     835        usb_log_debug("Getting Report descriptor, expected size: %u\n", length);
     836       
     837        /*
     838         * Get the descriptor from the device.
     839         */
     840        int rc = usb_request_get_descriptor(&kbd_dev->usb_dev->ctrl_pipe,
     841            USB_REQUEST_TYPE_STANDARD, USB_REQUEST_RECIPIENT_INTERFACE,
     842            USB_DESCTYPE_HID_REPORT, 0, kbd_dev->usb_dev->interface_no,
     843            kbd_dev->report_desc, length, &actual_size);
     844
     845        if (rc != EOK) {
     846                free(kbd_dev->report_desc);
     847                kbd_dev->report_desc = NULL;
     848                return rc;
     849        }
     850
     851        if (actual_size != length) {
     852                free(kbd_dev->report_desc);
     853                kbd_dev->report_desc = NULL;
     854                usb_log_fatal("Report descriptor has wrong size (%u, expected "
     855                    "%u)\n", actual_size, length);
     856                return EINVAL;
     857        }
     858       
     859        /*
     860         * End session for the control transfer.
     861         */
     862        sess_rc = usb_pipe_end_session(&kbd_dev->usb_dev->ctrl_pipe);
     863        if (sess_rc != EOK) {
     864                usb_log_warning("Failed to end a session: %s.\n",
     865                    str_error(sess_rc));
     866                free(kbd_dev->report_desc);
     867                kbd_dev->report_desc = NULL;
     868                return sess_rc;
     869        }
     870       
     871        kbd_dev->report_desc_size = length;
     872       
     873        usb_log_debug("Done.\n");
     874       
     875        return EOK;
     876}
     877
     878/*----------------------------------------------------------------------------*/
     879
     880static int usbhid_kbd_process_report_descriptor(usbhid_kbd_t *kbd_dev)
     881{
     882        int rc = usbhid_dev_get_report_descriptor(kbd_dev);
     883       
     884        if (rc != EOK) {
     885                usb_log_warning("Problem with getting Report descriptor: %s.\n",
     886                    str_error(rc));
     887                return rc;
     888        }
     889       
     890        rc = usb_hid_parse_report_descriptor(kbd_dev->parser,
     891            kbd_dev->report_desc, kbd_dev->report_desc_size);
     892        if (rc != EOK) {
     893                usb_log_warning("Problem parsing Report descriptor: %s.\n",
     894                    str_error(rc));
     895                return rc;
     896        }
     897       
     898        usb_hid_descriptor_print(kbd_dev->parser);
     899       
     900        /*
     901         * TODO: if failed, try to parse the boot report descriptor.
     902         */
     903       
     904        return EOK;
     905}
     906
     907/*----------------------------------------------------------------------------*/
     908/* API functions                                                              */
     909/*----------------------------------------------------------------------------*/
    599910/**
    600911 * Creates a new USB/HID keyboard structure.
     
    606917 *         NULL if not successful (memory error).
    607918 */
    608 static usbhid_kbd_t *usbhid_kbd_new(void)
     919usbhid_kbd_t *usbhid_kbd_new(void)
    609920{
    610921        usbhid_kbd_t *kbd_dev =
     
    618929        memset(kbd_dev, 0, sizeof(usbhid_kbd_t));
    619930       
    620         kbd_dev->hid_dev = usbhid_dev_new();
    621         if (kbd_dev->hid_dev == NULL) {
    622                 usb_log_fatal("Could not create HID device structure.\n");
    623                 return NULL;
    624         }
    625        
    626931        kbd_dev->console_phone = -1;
    627932        kbd_dev->initialized = USBHID_KBD_STATUS_UNINITIALIZED;
    628933       
    629934        return kbd_dev;
    630 }
    631 
    632 /*----------------------------------------------------------------------------*/
    633 
    634 static void usbhid_kbd_mark_unusable(usbhid_kbd_t *kbd_dev)
    635 {
    636         kbd_dev->initialized = USBHID_KBD_STATUS_TO_DESTROY;
    637935}
    638936
     
    658956 * @return Other value inherited from function usbhid_dev_init().
    659957 */
    660 static int usbhid_kbd_init(usbhid_kbd_t *kbd_dev, ddf_dev_t *dev)
     958int usbhid_kbd_init(usbhid_kbd_t *kbd_dev, usb_device_t *dev)
    661959{
    662960        int rc;
     
    671969       
    672970        if (dev == NULL) {
    673                 usb_log_error("Failed to init keyboard structure: no device"
     971                usb_log_error("Failed to init keyboard structure: no USB device"
    674972                    " given.\n");
    675973                return EINVAL;
     
    681979        }
    682980       
    683         rc = usbhid_dev_init(kbd_dev->hid_dev, dev, &poll_endpoint_description);
    684        
    685         if (rc != EOK) {
    686                 usb_log_error("Failed to initialize HID device structure: %s\n",
    687                    str_error(rc));
    688                 return rc;
    689         }
    690        
    691         assert(kbd_dev->hid_dev->initialized == USBHID_KBD_STATUS_INITIALIZED);
     981        //rc = usbhid_dev_init(kbd_dev->hid_dev, dev, &poll_endpoint_description);
     982       
     983       
     984//      if (rc != EOK) {
     985//              usb_log_error("Failed to initialize HID device structure: %s\n",
     986//                 str_error(rc));
     987//              return rc;
     988//      }
     989       
     990//      assert(kbd_dev->hid_dev->initialized == USBHID_KBD_STATUS_INITIALIZED);
    692991       
    693992        // save the size of the report (boot protocol report by default)
    694993//      kbd_dev->key_count = BOOTP_REPORT_SIZE;
    695994       
     995        /* The USB device should already be initialized, save it in structure */
     996        kbd_dev->usb_dev = dev;
     997       
     998        /* Get the report descriptor and initialize report parser. */
     999        rc = usbhid_kbd_process_report_descriptor(kbd_dev);
     1000        if (rc != EOK) {
     1001                usb_log_warning("Could not process report descriptor.\n");
     1002                return rc;
     1003        }
     1004       
     1005        /*
     1006         * TODO: make more general
     1007         */
    6961008        usb_hid_report_path_t path;
    6971009        path.usage_page = USB_HIDUT_PAGE_KEYBOARD;
    6981010        kbd_dev->key_count = usb_hid_report_input_length(
    699             kbd_dev->hid_dev->parser, &path);
     1011            kbd_dev->parser, &path);
    7001012       
    7011013        usb_log_debug("Size of the input report: %zu\n", kbd_dev->key_count);
     
    7331045         * Set Idle rate
    7341046         */
    735         assert(kbd_dev->hid_dev != NULL);
    736         assert(kbd_dev->hid_dev->initialized);
     1047        //assert(kbd_dev->hid_dev != NULL);
     1048        //assert(kbd_dev->hid_dev->initialized);
    7371049        //usbhid_req_set_protocol(kbd_dev->hid_dev, USB_HID_PROTOCOL_BOOT);
    7381050       
    7391051        usbhid_kbd_set_led(kbd_dev);
    7401052       
    741         usbhid_req_set_idle(kbd_dev->hid_dev, IDLE_RATE);
     1053        usbhid_req_set_idle(&kbd_dev->usb_dev->ctrl_pipe,
     1054            kbd_dev->usb_dev->interface_no, IDLE_RATE);
    7421055       
    7431056        kbd_dev->initialized = USBHID_KBD_STATUS_INITIALIZED;
     
    7481061
    7491062/*----------------------------------------------------------------------------*/
    750 /* HID/KBD polling                                                            */
    751 /*----------------------------------------------------------------------------*/
    752 /**
    753  * Main keyboard polling function.
    754  *
    755  * This function uses the Interrupt In pipe of the keyboard to poll for events.
    756  * The keyboard is initialized in a way that it reports only when a key is
    757  * pressed or released, so there is no actual need for any sleeping between
    758  * polls (see usbhid_kbd_try_add_device() or usbhid_kbd_init()).
    759  *
    760  * @param kbd_dev Initialized keyboard structure representing the device to
    761  *                poll.
    762  *
    763  * @sa usbhid_kbd_process_data()
    764  */
    765 static void usbhid_kbd_poll(usbhid_kbd_t *kbd_dev)
    766 {
    767         int rc, sess_rc;
    768         uint8_t buffer[BOOTP_BUFFER_SIZE];
    769         size_t actual_size;
    770        
    771         usb_log_debug("Polling keyboard...\n");
    772        
    773         if (!kbd_dev->initialized) {
    774                 usb_log_error("HID/KBD device not initialized!\n");
     1063
     1064bool usbhid_kbd_polling_callback(usb_device_t *dev, uint8_t *buffer,
     1065     size_t buffer_size, void *arg)
     1066{
     1067        if (dev == NULL || buffer == NULL || arg == NULL) {
     1068                // do not continue polling (???)
     1069                return false;
     1070        }
     1071       
     1072        usbhid_kbd_t *kbd_dev = (usbhid_kbd_t *)arg;
     1073       
     1074        // TODO: add return value from this function
     1075        usbhid_kbd_process_data(kbd_dev, buffer, buffer_size);
     1076       
     1077        return true;
     1078}
     1079
     1080/*----------------------------------------------------------------------------*/
     1081
     1082void usbhid_kbd_polling_ended_callback(usb_device_t *dev, bool reason,
     1083     void *arg)
     1084{
     1085        if (dev == NULL || arg == NULL) {
    7751086                return;
    7761087        }
    7771088       
    778         assert(kbd_dev->hid_dev != NULL);
    779         assert(kbd_dev->hid_dev->initialized);
    780 
    781         while (true) {
    782                 sess_rc = usb_pipe_start_session(
    783                     &kbd_dev->hid_dev->poll_pipe);
    784                 if (sess_rc != EOK) {
    785                         usb_log_warning("Failed to start a session: %s.\n",
    786                             str_error(sess_rc));
    787                         break;
    788                 }
    789 
    790                 rc = usb_pipe_read(&kbd_dev->hid_dev->poll_pipe,
    791                     buffer, BOOTP_BUFFER_SIZE, &actual_size);
    792                
    793                 sess_rc = usb_pipe_end_session(
    794                     &kbd_dev->hid_dev->poll_pipe);
    795 
    796                 if (rc != EOK) {
    797                         usb_log_warning("Error polling the keyboard: %s.\n",
    798                             str_error(rc));
    799                         break;
    800                 }
    801 
    802                 if (sess_rc != EOK) {
    803                         usb_log_warning("Error closing session: %s.\n",
    804                             str_error(sess_rc));
    805                         break;
    806                 }
    807 
    808                 /*
    809                  * If the keyboard answered with NAK, it returned no data.
    810                  * This implies that no change happened since last query.
    811                  */
    812                 if (actual_size == 0) {
    813                         usb_log_debug("Keyboard returned NAK\n");
    814                         continue;
    815                 }
    816 
    817                 /*
    818                  * TODO: Process pressed keys.
    819                  */
    820                 usb_log_debug("Calling usbhid_kbd_process_data()\n");
    821                 usbhid_kbd_process_data(kbd_dev, buffer, actual_size);
    822                
    823                 // disabled for now, no reason to sleep
    824                 //async_usleep(kbd_dev->hid_dev->poll_interval);
    825         }
    826 }
    827 
    828 /*----------------------------------------------------------------------------*/
    829 /**
    830  * Function executed by the main driver fibril.
    831  *
    832  * Just starts polling the keyboard for events.
    833  *
    834  * @param arg Initialized keyboard device structure (of type usbhid_kbd_t)
    835  *            representing the device.
    836  *
    837  * @retval EOK if the fibril finished polling the device.
    838  * @retval EINVAL if no device was given in the argument.
    839  *
    840  * @sa usbhid_kbd_poll()
    841  *
    842  * @todo Change return value - only case when the fibril finishes is in case
    843  *       of some error, so the error should probably be propagated from function
    844  *       usbhid_kbd_poll() to here and up.
    845  */
    846 static int usbhid_kbd_fibril(void *arg)
    847 {
    848         if (arg == NULL) {
    849                 usb_log_error("No device!\n");
    850                 return EINVAL;
    851         }
    852        
    853         usbhid_kbd_t *kbd_dev = (usbhid_kbd_t *)arg;
    854 
    855         usbhid_kbd_poll(kbd_dev);
    856        
    857         // as there is another fibril using this device, so we must leave the
    858         // structure to it, but mark it for destroying.
    859         usbhid_kbd_mark_unusable(kbd_dev);
    860         // at the end, properly destroy the KBD structure
    861 //      usbhid_kbd_free(&kbd_dev);
    862 //      assert(kbd_dev == NULL);
    863 
    864         return EOK;
    865 }
    866 
    867 /*----------------------------------------------------------------------------*/
    868 /* API functions                                                              */
    869 /*----------------------------------------------------------------------------*/
    870 /**
    871  * Function for adding a new device of type USB/HID/keyboard.
    872  *
    873  * This functions initializes required structures from the device's descriptors
    874  * and starts new fibril for polling the keyboard for events and another one for
    875  * handling auto-repeat of keys.
    876  *
    877  * During initialization, the keyboard is switched into boot protocol, the idle
    878  * rate is set to 0 (infinity), resulting in the keyboard only reporting event
    879  * when a key is pressed or released. Finally, the LED lights are turned on
    880  * according to the default setup of lock keys.
    881  *
    882  * @note By default, the keyboards is initialized with Num Lock turned on and
    883  *       other locks turned off.
    884  * @note Currently supports only boot-protocol keyboards.
    885  *
    886  * @param dev Device to add.
    887  *
    888  * @retval EOK if successful.
    889  * @retval ENOMEM if there
    890  * @return Other error code inherited from one of functions usbhid_kbd_init(),
    891  *         ddf_fun_bind() and ddf_fun_add_to_class().
    892  *
    893  * @sa usbhid_kbd_fibril(), usbhid_kbd_repeat_fibril()
    894  */
    895 int usbhid_kbd_try_add_device(ddf_dev_t *dev)
    896 {
    897         /*
    898          * Create default function.
    899          */
    900         ddf_fun_t *kbd_fun = ddf_fun_create(dev, fun_exposed, "keyboard");
    901         if (kbd_fun == NULL) {
    902                 usb_log_error("Could not create DDF function node.\n");
    903                 return ENOMEM;
    904         }
    905        
    906         /*
    907          * Initialize device (get and process descriptors, get address, etc.)
    908          */
    909         usb_log_debug("Initializing USB/HID KBD device...\n");
    910        
    911         usbhid_kbd_t *kbd_dev = usbhid_kbd_new();
    912         if (kbd_dev == NULL) {
    913                 usb_log_error("Error while creating USB/HID KBD device "
    914                     "structure.\n");
    915                 ddf_fun_destroy(kbd_fun);
    916                 return ENOMEM;  // TODO: some other code??
    917         }
    918        
    919         int rc = usbhid_kbd_init(kbd_dev, dev);
    920        
    921         if (rc != EOK) {
    922                 usb_log_error("Failed to initialize USB/HID KBD device.\n");
    923                 ddf_fun_destroy(kbd_fun);
    924                 usbhid_kbd_free(&kbd_dev);
    925                 return rc;
    926         }       
    927        
    928         usb_log_debug("USB/HID KBD device structure initialized.\n");
    929        
    930         /*
    931          * Store the initialized keyboard device and keyboard ops
    932          * to the DDF function.
    933          */
    934         kbd_fun->driver_data = kbd_dev;
    935         kbd_fun->ops = &keyboard_ops;
    936 
    937         rc = ddf_fun_bind(kbd_fun);
    938         if (rc != EOK) {
    939                 usb_log_error("Could not bind DDF function: %s.\n",
    940                     str_error(rc));
    941                 // TODO: Can / should I destroy the DDF function?
    942                 ddf_fun_destroy(kbd_fun);
    943                 usbhid_kbd_free(&kbd_dev);
    944                 return rc;
    945         }
    946        
    947         rc = ddf_fun_add_to_class(kbd_fun, "keyboard");
    948         if (rc != EOK) {
    949                 usb_log_error(
    950                     "Could not add DDF function to class 'keyboard': %s.\n",
    951                     str_error(rc));
    952                 // TODO: Can / should I destroy the DDF function?
    953                 ddf_fun_destroy(kbd_fun);
    954                 usbhid_kbd_free(&kbd_dev);
    955                 return rc;
    956         }
    957        
    958         /*
    959          * Create new fibril for handling this keyboard
    960          */
    961         fid_t fid = fibril_create(usbhid_kbd_fibril, kbd_dev);
    962         if (fid == 0) {
    963                 usb_log_error("Failed to start fibril for `%s' device.\n",
    964                     dev->name);
    965                 return ENOMEM;
    966         }
    967         fibril_add_ready(fid);
    968        
    969         /*
    970          * Create new fibril for auto-repeat
    971          */
    972         fid = fibril_create(usbhid_kbd_repeat_fibril, kbd_dev);
    973         if (fid == 0) {
    974                 usb_log_error("Failed to start fibril for KBD auto-repeat");
    975                 return ENOMEM;
    976         }
    977         fibril_add_ready(fid);
    978 
    979         (void)keyboard_ops;
    980 
    981         /*
    982          * Hurrah, device is initialized.
    983          */
    984         return EOK;
     1089        usbhid_kbd_t *kbd = (usbhid_kbd_t *)arg;
     1090       
     1091        usbhid_kbd_mark_unusable(kbd);
    9851092}
    9861093
     
    10141121        async_hangup((*kbd_dev)->console_phone);
    10151122       
    1016         if ((*kbd_dev)->hid_dev != NULL) {
    1017                 usbhid_dev_free(&(*kbd_dev)->hid_dev);
    1018                 assert((*kbd_dev)->hid_dev == NULL);
    1019         }
     1123//      if ((*kbd_dev)->hid_dev != NULL) {
     1124//              usbhid_dev_free(&(*kbd_dev)->hid_dev);
     1125//              assert((*kbd_dev)->hid_dev == NULL);
     1126//      }
    10201127       
    10211128        if ((*kbd_dev)->repeat_mtx != NULL) {
     
    10241131                free((*kbd_dev)->repeat_mtx);
    10251132        }
     1133       
     1134        /* TODO: what about the USB device structure?? */
    10261135
    10271136        free(*kbd_dev);
  • uspace/drv/usbhid/kbddev.h

    r62f4212 rf8e4cb6  
    4646#include <usb/pipes.h>
    4747
    48 #include "hiddev.h"
     48#include <usb/devdrv.h>
     49
     50//#include "hiddev.h"
    4951
    5052/*----------------------------------------------------------------------------*/
     
    7577 *       being device-specific.
    7678 */
    77 typedef struct {
    78         /** Structure holding generic USB/HID device information. */
    79         usbhid_dev_t *hid_dev;
     79typedef struct usbhid_kbd_t {
     80        /** Structure holding generic USB device information. */
     81        //usbhid_dev_t *hid_dev;
     82        usb_device_t *usb_dev;
    8083       
    8184        /** Currently pressed keys (not translated to key codes). */
     
    101104        fibril_mutex_t *repeat_mtx;
    102105       
     106        /** Report descriptor. */
     107        uint8_t *report_desc;
     108
     109        /** Report descriptor size. */
     110        size_t report_desc_size;
     111
     112        /** HID Report parser. */
     113        usb_hid_report_parser_t *parser;
     114       
    103115        /** State of the structure (for checking before use).
    104116         *
     
    112124/*----------------------------------------------------------------------------*/
    113125
    114 int usbhid_kbd_try_add_device(ddf_dev_t *dev);
     126enum {
     127        USBHID_KBD_POLL_EP_NO = 0,
     128        USBHID_KBD_POLL_EP_COUNT = 1
     129};
     130
     131usb_endpoint_description_t *usbhid_kbd_endpoints[USBHID_KBD_POLL_EP_COUNT + 1];
     132
     133ddf_dev_ops_t keyboard_ops;
     134
     135/*----------------------------------------------------------------------------*/
     136
     137usbhid_kbd_t *usbhid_kbd_new(void);
     138
     139int usbhid_kbd_init(usbhid_kbd_t *kbd_dev, usb_device_t *dev);
     140
     141bool usbhid_kbd_polling_callback(usb_device_t *dev, uint8_t *buffer,
     142     size_t buffer_size, void *arg);
     143
     144void usbhid_kbd_polling_ended_callback(usb_device_t *dev, bool reason,
     145     void *arg);
    115146
    116147int usbhid_kbd_is_initialized(const usbhid_kbd_t *kbd_dev);
  • uspace/drv/usbhid/kbdrepeat.h

    r62f4212 rf8e4cb6  
    3737#define USBHID_KBDREPEAT_H_
    3838
    39 #include "kbddev.h"
     39struct usbhid_kbd_t;
     40
     41//#include "kbddev.h"
    4042
    4143/*----------------------------------------------------------------------------*/
     
    4345int usbhid_kbd_repeat_fibril(void *arg);
    4446
    45 void usbhid_kbd_repeat_start(usbhid_kbd_t *kbd, unsigned int key);
     47void usbhid_kbd_repeat_start(struct usbhid_kbd_t *kbd, unsigned int key);
    4648
    47 void usbhid_kbd_repeat_stop(usbhid_kbd_t *kbd, unsigned int key);
     49void usbhid_kbd_repeat_stop(struct usbhid_kbd_t *kbd, unsigned int key);
    4850
    4951#endif /* USBHID_KBDREPEAT_H_ */
  • uspace/drv/usbhid/main.c

    r62f4212 rf8e4cb6  
    4141#include <str_error.h>
    4242
     43#include <usb/devdrv.h>
     44
    4345#include "kbddev.h"
     46#include "kbdrepeat.h"
    4447
    4548/*----------------------------------------------------------------------------*/
    4649
    4750#define NAME "usbhid"
     51
     52/**
     53 * Function for adding a new device of type USB/HID/keyboard.
     54 *
     55 * This functions initializes required structures from the device's descriptors
     56 * and starts new fibril for polling the keyboard for events and another one for
     57 * handling auto-repeat of keys.
     58 *
     59 * During initialization, the keyboard is switched into boot protocol, the idle
     60 * rate is set to 0 (infinity), resulting in the keyboard only reporting event
     61 * when a key is pressed or released. Finally, the LED lights are turned on
     62 * according to the default setup of lock keys.
     63 *
     64 * @note By default, the keyboards is initialized with Num Lock turned on and
     65 *       other locks turned off.
     66 * @note Currently supports only boot-protocol keyboards.
     67 *
     68 * @param dev Device to add.
     69 *
     70 * @retval EOK if successful.
     71 * @retval ENOMEM if there
     72 * @return Other error code inherited from one of functions usbhid_kbd_init(),
     73 *         ddf_fun_bind() and ddf_fun_add_to_class().
     74 *
     75 * @sa usbhid_kbd_fibril(), usbhid_kbd_repeat_fibril()
     76 */
     77static int usbhid_try_add_device(usb_device_t *dev)
     78{
     79        /* Create the function exposed under /dev/devices. */
     80        ddf_fun_t *kbd_fun = ddf_fun_create(dev->ddf_dev, fun_exposed,
     81            "keyboard");
     82        if (kbd_fun == NULL) {
     83                usb_log_error("Could not create DDF function node.\n");
     84                return ENOMEM;
     85        }
     86       
     87        /*
     88         * Initialize device (get and process descriptors, get address, etc.)
     89         */
     90        usb_log_debug("Initializing USB/HID KBD device...\n");
     91       
     92        usbhid_kbd_t *kbd_dev = usbhid_kbd_new();
     93        if (kbd_dev == NULL) {
     94                usb_log_error("Error while creating USB/HID KBD device "
     95                    "structure.\n");
     96                ddf_fun_destroy(kbd_fun);
     97                return ENOMEM;  // TODO: some other code??
     98        }
     99       
     100        int rc = usbhid_kbd_init(kbd_dev, dev);
     101       
     102        if (rc != EOK) {
     103                usb_log_error("Failed to initialize USB/HID KBD device.\n");
     104                ddf_fun_destroy(kbd_fun);
     105                usbhid_kbd_free(&kbd_dev);
     106                return rc;
     107        }       
     108       
     109        usb_log_debug("USB/HID KBD device structure initialized.\n");
     110       
     111        /*
     112         * Store the initialized keyboard device and keyboard ops
     113         * to the DDF function.
     114         */
     115        kbd_fun->driver_data = kbd_dev;
     116        kbd_fun->ops = &keyboard_ops;
     117
     118        rc = ddf_fun_bind(kbd_fun);
     119        if (rc != EOK) {
     120                usb_log_error("Could not bind DDF function: %s.\n",
     121                    str_error(rc));
     122                // TODO: Can / should I destroy the DDF function?
     123                ddf_fun_destroy(kbd_fun);
     124                usbhid_kbd_free(&kbd_dev);
     125                return rc;
     126        }
     127       
     128        rc = ddf_fun_add_to_class(kbd_fun, "keyboard");
     129        if (rc != EOK) {
     130                usb_log_error(
     131                    "Could not add DDF function to class 'keyboard': %s.\n",
     132                    str_error(rc));
     133                // TODO: Can / should I destroy the DDF function?
     134                ddf_fun_destroy(kbd_fun);
     135                usbhid_kbd_free(&kbd_dev);
     136                return rc;
     137        }
     138       
     139        /*
     140         * Create new fibril for handling this keyboard
     141         */
     142        //fid_t fid = fibril_create(usbhid_kbd_fibril, kbd_dev);
     143       
     144        /* Start automated polling function.
     145         * This will create a separate fibril that will query the device
     146         * for the data continuously
     147         */
     148       rc = usb_device_auto_poll(dev,
     149           /* Index of the polling pipe. */
     150           USBHID_KBD_POLL_EP_NO,
     151           /* Callback when data arrives. */
     152           usbhid_kbd_polling_callback,
     153           /* How much data to request. */
     154           dev->pipes[USBHID_KBD_POLL_EP_NO].pipe->max_packet_size,
     155           /* Callback when the polling ends. */
     156           usbhid_kbd_polling_ended_callback,
     157           /* Custom argument. */
     158           kbd_dev);
     159       
     160       
     161        if (rc != EOK) {
     162                usb_log_error("Failed to start polling fibril for `%s'.\n",
     163                    dev->ddf_dev->name);
     164                return rc;
     165        }
     166        //fibril_add_ready(fid);
     167       
     168        /*
     169         * Create new fibril for auto-repeat
     170         */
     171        fid_t fid = fibril_create(usbhid_kbd_repeat_fibril, kbd_dev);
     172        if (fid == 0) {
     173                usb_log_error("Failed to start fibril for KBD auto-repeat");
     174                return ENOMEM;
     175        }
     176        fibril_add_ready(fid);
     177
     178        (void)keyboard_ops;
     179
     180        /*
     181         * Hurrah, device is initialized.
     182         */
     183        return EOK;
     184}
    48185
    49186/*----------------------------------------------------------------------------*/
     
    58195 * @retval EREFUSED if the device is not supported.
    59196 */
    60 static int usbhid_add_device(ddf_dev_t *dev)
     197static int usbhid_add_device(usb_device_t *dev)
    61198{
    62199        usb_log_debug("usbhid_add_device()\n");
    63200       
    64         int rc = usbhid_kbd_try_add_device(dev);
     201        if (dev->interface_no < 0) {
     202                usb_log_warning("Device is not a supported keyboard.\n");
     203                usb_log_error("Failed to add HID device: endpoint not found."
     204                    "\n");
     205                return ENOTSUP;
     206        }
     207       
     208        int rc = usbhid_try_add_device(dev);
    65209       
    66210        if (rc != EOK) {
     
    71215        }
    72216       
    73         usb_log_info("Keyboard `%s' ready to use.\n", dev->name);
     217        usb_log_info("Keyboard `%s' ready to use.\n", dev->ddf_dev->name);
    74218
    75219        return EOK;
     
    78222/*----------------------------------------------------------------------------*/
    79223
    80 static driver_ops_t kbd_driver_ops = {
    81         .add_device = usbhid_add_device,
     224/* Currently, the framework supports only device adding. Once the framework
     225 * supports unplug, more callbacks will be added. */
     226static usb_driver_ops_t usbhid_driver_ops = {
     227        .add_device = usbhid_add_device,
    82228};
    83229
    84 /*----------------------------------------------------------------------------*/
    85 
    86 static driver_t kbd_driver = {
    87         .name = NAME,
    88         .driver_ops = &kbd_driver_ops
     230
     231/* The driver itself. */
     232static usb_driver_t usbhid_driver = {
     233        .name = NAME,
     234        .ops = &usbhid_driver_ops,
     235        .endpoints = usbhid_kbd_endpoints
    89236};
     237
     238/*----------------------------------------------------------------------------*/
     239
     240//static driver_ops_t kbd_driver_ops = {
     241//      .add_device = usbhid_add_device,
     242//};
     243
     244///*----------------------------------------------------------------------------*/
     245
     246//static driver_t kbd_driver = {
     247//      .name = NAME,
     248//      .driver_ops = &kbd_driver_ops
     249//};
    90250
    91251/*----------------------------------------------------------------------------*/
     
    95255        printf(NAME ": HelenOS USB HID driver.\n");
    96256
    97         usb_log_enable(USB_LOG_LEVEL_DEFAULT, NAME);
    98 
    99         return ddf_driver_main(&kbd_driver);
     257        usb_log_enable(USB_LOG_LEVEL_DEBUG, NAME);
     258
     259        return usb_driver_main(&usbhid_driver);
    100260}
    101261
Note: See TracChangeset for help on using the changeset viewer.