Changeset f8e4cb6 in mainline for uspace/drv/usbhid/kbddev.c


Ignore:
Timestamp:
2011-03-22T19:11:21Z (14 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.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • 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);
Note: See TracChangeset for help on using the changeset viewer.