Changeset 747ef72 in mainline for uspace/drv/bus


Ignore:
Timestamp:
2011-11-10T11:29:10Z (14 years ago)
Author:
Jan Vesely <jano.vesely@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
54464f6a, c2245a3, c6f189f7
Parents:
2e1b9dc (diff), 2d1ba51 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge USB changes.

Interface changes:

  • GET_ADDRESS has been renamed to GET_MY_ADDRESS and the handle parameter was dropped. Tis call no longer cascades up to the root hub, but it is answered in the first place the information is available (nearest hub)
  • Reintroduced address reservation for USB_DEFAULT_ADDRESS. The interface now enables device drivers to request specific address on initialization and either insists on that address or accept any other if the address is not available. Note that it is not possible to get the default address if the driver does not insist.
  • Any endpoint registered is removed when address is released and a warning is produced if there were any such endpoints.
  • It is no longer necessary or possible to pass device speed information when registering endpoints.

Driver fixes: memory leaks and crashes (not only) in error paths.
Fixes or removes flaky device_remove implementation in device drivers.

Location:
uspace/drv/bus/usb
Files:
28 edited

Legend:

Unmodified
Added
Removed
  • uspace/drv/bus/usb/ehci/hc_iface.c

    r2e1b9dc r747ef72  
    5656 * @return Error code.
    5757 */
    58 static int request_address(ddf_fun_t *fun, usb_speed_t speed,
    59     usb_address_t *address)
     58static int request_address(ddf_fun_t *fun, usb_address_t *address, bool strict,
     59    usb_speed_t speed)
    6060{
    6161        UNSUPPORTED("request_address");
     
    120120 */
    121121static int register_endpoint(ddf_fun_t *fun,
    122     usb_address_t address, usb_speed_t speed, usb_endpoint_t endpoint,
     122    usb_address_t address, usb_endpoint_t endpoint,
    123123    usb_transfer_type_t transfer_type, usb_direction_t direction,
    124124    size_t max_packet_size, unsigned int interval)
  • uspace/drv/bus/usb/ohci/hc.c

    r2e1b9dc r747ef72  
    127127        assert(hub_fun);
    128128
    129         const usb_address_t hub_address =
    130             usb_device_manager_get_free_address(
    131                 &instance->generic.dev_manager, USB_SPEED_FULL);
    132         if (hub_address <= 0) {
     129        /* Try to get address 1 for root hub. */
     130        instance->rh.address = 1;
     131        int ret = usb_device_manager_request_address(
     132            &instance->generic.dev_manager, &instance->rh.address, false,
     133            USB_SPEED_FULL);
     134        if (ret != EOK) {
    133135                usb_log_error("Failed to get OHCI root hub address: %s\n",
    134                     str_error(hub_address));
    135                 return hub_address;
    136         }
    137         instance->rh.address = hub_address;
    138         usb_device_manager_bind(
    139             &instance->generic.dev_manager, hub_address, hub_fun->handle);
     136                    str_error(ret));
     137                return ret;
     138        }
     139        usb_device_manager_bind_address(&instance->generic.dev_manager,
     140            instance->rh.address, hub_fun->handle);
    140141
    141142#define CHECK_RET_UNREG_RETURN(ret, message...) \
     
    143144        usb_log_error(message); \
    144145        usb_endpoint_manager_remove_ep( \
    145             &instance->generic.ep_manager, hub_address, 0, USB_DIRECTION_BOTH, \
    146             NULL, NULL);\
    147         usb_device_manager_release( \
    148             &instance->generic.dev_manager, hub_address); \
     146            &instance->generic.ep_manager, instance->rh.address, 0, \
     147            USB_DIRECTION_BOTH, NULL, NULL); \
     148        usb_device_manager_release_address( \
     149            &instance->generic.dev_manager, instance->rh.address); \
    149150        return ret; \
    150151} else (void)0
    151         int ret = usb_endpoint_manager_add_ep(
    152             &instance->generic.ep_manager, hub_address, 0, USB_DIRECTION_BOTH,
    153             USB_TRANSFER_CONTROL, USB_SPEED_FULL, 64, 0, NULL, NULL);
     152        ret = usb_endpoint_manager_add_ep(
     153            &instance->generic.ep_manager, instance->rh.address, 0,
     154            USB_DIRECTION_BOTH, USB_TRANSFER_CONTROL, USB_SPEED_FULL, 64,
     155            0, NULL, NULL);
    154156        CHECK_RET_UNREG_RETURN(ret,
    155157            "Failed to register root hub control endpoint: %s.\n",
     
    193195        list_initialize(&instance->pending_batches);
    194196
    195         hcd_init(&instance->generic, BANDWIDTH_AVAILABLE_USB11,
    196             bandwidth_count_usb11);
     197        hcd_init(&instance->generic, USB_SPEED_FULL,
     198            BANDWIDTH_AVAILABLE_USB11, bandwidth_count_usb11);
    197199        instance->generic.private_data = instance;
    198200        instance->generic.schedule = hc_schedule;
  • uspace/drv/bus/usb/ohci/ohci.c

    r2e1b9dc r747ef72  
    7676}
    7777/*----------------------------------------------------------------------------*/
    78 /** Get address of the device identified by handle.
    79  *
    80  * @param[in] dev DDF instance of the device to use.
    81  * @param[in] iid (Unused).
    82  * @param[in] call Pointer to the call that represents interrupt.
    83  */
    84 static int usb_iface_get_address(
    85     ddf_fun_t *fun, devman_handle_t handle, usb_address_t *address)
     78/** Get USB address assigned to root hub.
     79 *
     80 * @param[in] fun Root hub function.
     81 * @param[out] address Store the address here.
     82 * @return Error code.
     83 */
     84static int rh_get_my_address(ddf_fun_t *fun, usb_address_t *address)
    8685{
    8786        assert(fun);
    88         usb_device_manager_t *manager =
    89             &dev_to_ohci(fun->dev)->hc.generic.dev_manager;
    90 
    91         const usb_address_t addr =
    92             usb_device_manager_find_address(manager, handle);
    93         if (addr < 0) {
    94                 return addr;
    95         }
    9687
    9788        if (address != NULL) {
    98                 *address = addr;
     89                *address = dev_to_ohci(fun->dev)->hc.rh.address;
    9990        }
    10091
     
    10899 * @return Error code.
    109100 */
    110 static int usb_iface_get_hc_handle(
     101static int rh_get_hc_handle(
    111102    ddf_fun_t *fun, devman_handle_t *handle)
    112103{
     
    122113/** Root hub USB interface */
    123114static usb_iface_t usb_iface = {
    124         .get_hc_handle = usb_iface_get_hc_handle,
    125         .get_address = usb_iface_get_address
     115        .get_hc_handle = rh_get_hc_handle,
     116        .get_my_address = rh_get_my_address,
    126117};
    127118/*----------------------------------------------------------------------------*/
  • uspace/drv/bus/usb/uhci/hc.c

    r2e1b9dc r747ef72  
    199199#undef CHECK_RET_RETURN
    200200
    201         hcd_init(&instance->generic, BANDWIDTH_AVAILABLE_USB11,
    202             bandwidth_count_usb11);
     201        hcd_init(&instance->generic, USB_SPEED_FULL,
     202            BANDWIDTH_AVAILABLE_USB11, bandwidth_count_usb11);
    203203
    204204        instance->generic.private_data = instance;
  • uspace/drv/bus/usb/uhci/uhci.c

    r2e1b9dc r747ef72  
    8989};
    9090/*----------------------------------------------------------------------------*/
    91 /** Get address of the device identified by handle.
    92  *
    93  * @param[in] fun DDF instance of the function to use.
    94  * @param[in] handle DDF handle of the driver seeking its USB address.
    95  * @param[out] address Found address.
    96  */
    97 static int usb_iface_get_address(
    98     ddf_fun_t *fun, devman_handle_t handle, usb_address_t *address)
    99 {
    100         assert(fun);
    101         usb_device_manager_t *manager =
    102             &dev_to_uhci(fun->dev)->hc.generic.dev_manager;
    103         const usb_address_t addr =
    104             usb_device_manager_find_address(manager, handle);
    105 
    106         if (addr < 0) {
    107                 return addr;
    108         }
    109 
    110         if (address != NULL) {
    111                 *address = addr;
    112         }
    113 
    114         return EOK;
    115 }
    116 /*----------------------------------------------------------------------------*/
    11791/** Gets handle of the respective hc.
    11892 *
     
    135109static usb_iface_t usb_iface = {
    136110        .get_hc_handle = usb_iface_get_hc_handle,
    137         .get_address = usb_iface_get_address
    138111};
    139112/*----------------------------------------------------------------------------*/
  • uspace/drv/bus/usb/usbflbk/main.c

    r2e1b9dc r747ef72  
    7474}
    7575
    76 /** Callback when new device is about to be removed.
    77  *
    78  * @param dev Representation of a generic DDF device.
    79  * @return Error code.
    80  */
    81 static int usbfallback_device_remove(usb_device_t *dev)
    82 {
    83         return EOK;
    84 }
    85 
    8676/** Callback when new device is removed and recognized as gone by DDF.
    8777 *
     
    10797static const usb_driver_ops_t usbfallback_driver_ops = {
    10898        .device_add = usbfallback_device_add,
    109         .device_rem = usbfallback_device_remove,
     99        .device_rem = usbfallback_device_gone,
    110100        .device_gone = usbfallback_device_gone,
    111101};
  • uspace/drv/bus/usb/usbhid/generic/hiddev.c

    r2e1b9dc r747ef72  
    6161
    6262/*----------------------------------------------------------------------------*/
    63 
    6463static size_t usb_generic_hid_get_event_length(ddf_fun_t *fun);
    65 
    66 static int usb_generic_hid_get_event(ddf_fun_t *fun, uint8_t *buffer,
     64static int usb_generic_hid_get_event(ddf_fun_t *fun, uint8_t *buffer,
    6765    size_t size, size_t *act_size, int *event_nr, unsigned int flags);
    68 
    6966static int usb_generic_hid_client_connected(ddf_fun_t *fun);
    70 
    7167static size_t usb_generic_get_report_descriptor_length(ddf_fun_t *fun);
    72 
    73 static int usb_generic_get_report_descriptor(ddf_fun_t *fun, uint8_t *desc,
     68static int usb_generic_get_report_descriptor(ddf_fun_t *fun, uint8_t *desc,
    7469    size_t size, size_t *actual_size);
    75 
    76 /*----------------------------------------------------------------------------*/
    77 
     70/*----------------------------------------------------------------------------*/
    7871static usbhid_iface_t usb_generic_iface = {
    7972        .get_event = usb_generic_hid_get_event,
     
    8275        .get_report_descriptor = usb_generic_get_report_descriptor
    8376};
    84 
     77/*----------------------------------------------------------------------------*/
    8578static ddf_dev_ops_t usb_generic_hid_ops = {
    8679        .interfaces[USBHID_DEV_IFACE] = &usb_generic_iface,
    8780        .open = usb_generic_hid_client_connected
    8881};
    89 
    90 /*----------------------------------------------------------------------------*/
    91 
     82/*----------------------------------------------------------------------------*/
    9283static size_t usb_generic_hid_get_event_length(ddf_fun_t *fun)
    9384{
     
    9990        }
    10091
    101         usb_hid_dev_t *hid_dev = (usb_hid_dev_t *)fun->driver_data;
     92        const usb_hid_dev_t *hid_dev = fun->driver_data;
    10293
    10394        usb_log_debug2("hid_dev: %p, Max input report size (%zu).\n",
     
    10697        return hid_dev->max_input_report_size;
    10798}
    108 
    109 /*----------------------------------------------------------------------------*/
    110 
    111 static int usb_generic_hid_get_event(ddf_fun_t *fun, uint8_t *buffer,
     99/*----------------------------------------------------------------------------*/
     100static int usb_generic_hid_get_event(ddf_fun_t *fun, uint8_t *buffer,
    112101    size_t size, size_t *act_size, int *event_nr, unsigned int flags)
    113102{
     
    120109        }
    121110
    122         usb_hid_dev_t *hid_dev = (usb_hid_dev_t *)fun->driver_data;
     111        const usb_hid_dev_t *hid_dev = (usb_hid_dev_t *)fun->driver_data;
    123112
    124113        if (hid_dev->input_report_size > size) {
    125                 usb_log_debug("input_report_size > size (%zu, %zu)\n", 
     114                usb_log_debug("input_report_size > size (%zu, %zu)\n",
    126115                    hid_dev->input_report_size, size);
    127116                return EINVAL;  // TODO: other error code
     
    129118
    130119        /*! @todo This should probably be somehow atomic. */
    131         memcpy(buffer, hid_dev->input_report, 
     120        memcpy(buffer, hid_dev->input_report,
    132121            hid_dev->input_report_size);
    133122        *act_size = hid_dev->input_report_size;
     
    138127        return EOK;
    139128}
    140 
    141 /*----------------------------------------------------------------------------*/
    142 
     129/*----------------------------------------------------------------------------*/
    143130static size_t usb_generic_get_report_descriptor_length(ddf_fun_t *fun)
    144131{
     
    150137        }
    151138
    152         usb_hid_dev_t *hid_dev = (usb_hid_dev_t *)fun->driver_data;
    153 
    154         usb_log_debug2("hid_dev->report_desc_size = %zu\n", 
     139        const usb_hid_dev_t *hid_dev = fun->driver_data;
     140
     141        usb_log_debug2("hid_dev->report_desc_size = %zu\n",
    155142            hid_dev->report_desc_size);
    156143
    157144        return hid_dev->report_desc_size;
    158145}
    159 
    160 /*----------------------------------------------------------------------------*/
    161 
    162 static int usb_generic_get_report_descriptor(ddf_fun_t *fun, uint8_t *desc,
     146/*----------------------------------------------------------------------------*/
     147static int usb_generic_get_report_descriptor(ddf_fun_t *fun, uint8_t *desc,
    163148    size_t size, size_t *actual_size)
    164149{
     
    170155        }
    171156
    172         usb_hid_dev_t *hid_dev = (usb_hid_dev_t *)fun->driver_data;
     157        const usb_hid_dev_t *hid_dev = fun->driver_data;
    173158
    174159        if (hid_dev->report_desc_size > size) {
     
    181166        return EOK;
    182167}
    183 
    184 /*----------------------------------------------------------------------------*/
    185 
     168/*----------------------------------------------------------------------------*/
    186169static int usb_generic_hid_client_connected(ddf_fun_t *fun)
    187170{
     
    189172        return EOK;
    190173}
    191 
    192 /*----------------------------------------------------------------------------*/
    193 
     174/*----------------------------------------------------------------------------*/
    194175void usb_generic_hid_deinit(usb_hid_dev_t *hid_dev, void *data)
    195176{
    196177        ddf_fun_t *fun = data;
    197         const int ret = ddf_fun_unbind(fun);
    198         if (ret != EOK) {
     178        if (fun == NULL)
     179                return;
     180
     181        if (ddf_fun_unbind(fun) != EOK) {
    199182                usb_log_error("Failed to unbind generic hid fun.\n");
    200183                return;
     
    206189        ddf_fun_destroy(fun);
    207190}
    208 
    209 /*----------------------------------------------------------------------------*/
    210 
     191/*----------------------------------------------------------------------------*/
    211192int usb_generic_hid_init(usb_hid_dev_t *hid_dev, void **data)
    212193{
     
    216197
    217198        /* Create the exposed function. */
    218         /** @todo Generate numbers for the devices? */
    219199        usb_log_debug("Creating DDF function %s...\n", HID_GENERIC_FUN_NAME);
    220200        ddf_fun_t *fun = ddf_fun_create(hid_dev->usb_dev->ddf_dev, fun_exposed,
     
    225205        }
    226206
     207        /* This is nasty, both device and this function have the same
     208         * driver data, thus destruction causes to double free */
     209        fun->driver_data = hid_dev;
    227210        fun->ops = &usb_generic_hid_ops;
    228211
     
    231214                usb_log_error("Could not bind DDF function: %s.\n",
    232215                    str_error(rc));
     216                fun->driver_data = NULL;
    233217                ddf_fun_destroy(fun);
    234218                return rc;
    235219        }
    236         /* This is nasty both device and this function have the same
    237          * driver data, thus destruction would lead to double free */
    238         fun->driver_data = hid_dev;
    239220
    240221        usb_log_debug("HID function created. Handle: %" PRIun "\n", fun->handle);
     
    243224        return EOK;
    244225}
    245 
    246 /*----------------------------------------------------------------------------*/
    247 
     226/*----------------------------------------------------------------------------*/
    248227bool usb_generic_hid_polling_callback(usb_hid_dev_t *hid_dev, void *data)
    249228{
    250229        return true;
    251230}
    252 
    253231/**
    254232 * @}
  • uspace/drv/bus/usb/usbhid/kbd/kbddev.c

    r2e1b9dc r747ef72  
    4141#include <io/keycode.h>
    4242#include <io/console.h>
     43#include <abi/ipc/methods.h>
    4344#include <ipc/kbdev.h>
    4445#include <async.h>
     
    8687
    8788/*----------------------------------------------------------------------------*/
    88 
    8989/** Keyboard polling endpoint description for boot protocol class. */
    9090const usb_endpoint_description_t usb_hid_kbd_poll_endpoint_description = {
     
    101101
    102102static void usb_kbd_set_led(usb_hid_dev_t *hid_dev, usb_kbd_t *kbd_dev);
    103 
    104 /*----------------------------------------------------------------------------*/
    105 
    106 enum {
    107         USB_KBD_BOOT_REPORT_DESCRIPTOR_SIZE = 63
     103/*----------------------------------------------------------------------------*/
     104static const uint8_t USB_KBD_BOOT_REPORT_DESCRIPTOR[] = {
     105        0x05, 0x01,  /* Usage Page (Generic Desktop), */
     106        0x09, 0x06,  /* Usage (Keyboard), */
     107        0xA1, 0x01,  /* Collection (Application), */
     108        0x75, 0x01,  /*   Report Size (1), */
     109        0x95, 0x08,  /*   Report Count (8), */
     110        0x05, 0x07,  /*   Usage Page (Key Codes); */
     111        0x19, 0xE0,  /*   Usage Minimum (224), */
     112        0x29, 0xE7,  /*   Usage Maximum (231), */
     113        0x15, 0x00,  /*   Logical Minimum (0), */
     114        0x25, 0x01,  /*   Logical Maximum (1), */
     115        0x81, 0x02,  /*   Input (Data, Variable, Absolute),  ; Modifier byte */
     116        0x95, 0x01,  /*   Report Count (1), */
     117        0x75, 0x08,  /*   Report Size (8), */
     118        0x81, 0x01,  /*   Input (Constant),                  ; Reserved byte */
     119        0x95, 0x05,  /*   Report Count (5), */
     120        0x75, 0x01,  /*   Report Size (1), */
     121        0x05, 0x08,  /*   Usage Page (Page# for LEDs), */
     122        0x19, 0x01,  /*   Usage Minimum (1), */
     123        0x29, 0x05,  /*   Usage Maxmimum (5), */
     124        0x91, 0x02,  /*   Output (Data, Variable, Absolute),  ; LED report */
     125        0x95, 0x01,  /*   Report Count (1), */
     126        0x75, 0x03,  /*   Report Size (3), */
     127        0x91, 0x01,  /*   Output (Constant),            ; LED report padding */
     128        0x95, 0x06,  /*   Report Count (6), */
     129        0x75, 0x08,  /*   Report Size (8), */
     130        0x15, 0x00,  /*   Logical Minimum (0), */
     131        0x25, 0xff,  /*   Logical Maximum (255), */
     132        0x05, 0x07,  /*   Usage Page (Key Codes), */
     133        0x19, 0x00,  /*   Usage Minimum (0), */
     134        0x29, 0xff,  /*   Usage Maximum (255), */
     135        0x81, 0x00,  /*   Input (Data, Array),   ; Key arrays (6 bytes) */
     136        0xC0         /* End Collection */
    108137};
    109 
    110 static const uint8_t USB_KBD_BOOT_REPORT_DESCRIPTOR[
    111     USB_KBD_BOOT_REPORT_DESCRIPTOR_SIZE] = {
    112         0x05, 0x01,  // Usage Page (Generic Desktop),
    113         0x09, 0x06,  // Usage (Keyboard),
    114         0xA1, 0x01,  // Collection (Application),
    115         0x75, 0x01,  //   Report Size (1),
    116         0x95, 0x08,  //   Report Count (8),       
    117         0x05, 0x07,  //   Usage Page (Key Codes);
    118         0x19, 0xE0,  //   Usage Minimum (224),
    119         0x29, 0xE7,  //   Usage Maximum (231),
    120         0x15, 0x00,  //   Logical Minimum (0),
    121         0x25, 0x01,  //   Logical Maximum (1),
    122         0x81, 0x02,  //   Input (Data, Variable, Absolute),   ; Modifier byte
    123         0x95, 0x01,  //   Report Count (1),
    124         0x75, 0x08,  //   Report Size (8),
    125         0x81, 0x01,  //   Input (Constant),                   ; Reserved byte
    126         0x95, 0x05,  //   Report Count (5),
    127         0x75, 0x01,  //   Report Size (1),
    128         0x05, 0x08,  //   Usage Page (Page# for LEDs),
    129         0x19, 0x01,  //   Usage Minimum (1),
    130         0x29, 0x05,  //   Usage Maxmimum (5),
    131         0x91, 0x02,  //   Output (Data, Variable, Absolute),  ; LED report
    132         0x95, 0x01,  //   Report Count (1),
    133         0x75, 0x03,  //   Report Size (3),
    134         0x91, 0x01,  //   Output (Constant),              ; LED report padding
    135         0x95, 0x06,  //   Report Count (6),
    136         0x75, 0x08,  //   Report Size (8),
    137         0x15, 0x00,  //   Logical Minimum (0),
    138         0x25, 0xff,  //   Logical Maximum (255),
    139         0x05, 0x07,  //   Usage Page (Key Codes),
    140         0x19, 0x00,  //   Usage Minimum (0),
    141         0x29, 0xff,  //   Usage Maximum (255),
    142         0x81, 0x00,  //   Input (Data, Array),            ; Key arrays (6 bytes)
    143         0xC0           // End Collection
    144 
    145 };
    146 
    147 /*----------------------------------------------------------------------------*/
    148 
     138/*----------------------------------------------------------------------------*/
    149139typedef enum usb_kbd_flags {
    150140        USB_KBD_STATUS_UNINITIALIZED = 0,
     
    152142        USB_KBD_STATUS_TO_DESTROY = -1
    153143} usb_kbd_flags;
    154 
    155144/*----------------------------------------------------------------------------*/
    156145/* IPC method handler                                                         */
    157146/*----------------------------------------------------------------------------*/
    158 
    159 static void default_connection_handler(ddf_fun_t *, ipc_callid_t, ipc_call_t *);
    160 
    161147/**
    162148 * Default handler for IPC methods not handled by DDF.
    163149 *
    164  * Currently recognizes only one method (IPC_M_CONNECT_TO_ME), in which case it
    165  * assumes the caller is the console and thus it stores IPC session to it for
    166  * later use by the driver to notify about key events.
     150 * Currently recognizes only two methods (IPC_M_CONNECT_TO_ME and KBDEV_SET_IND)
     151 * IPC_M_CONNECT_TO_ME assumes the caller is the console and  stores IPC
     152 * session to it for later use by the driver to notify about key events.
     153 * KBDEV_SET_IND sets LED keyboard indicators.
    167154 *
    168155 * @param fun Device function handling the call.
     
    173160    ipc_callid_t icallid, ipc_call_t *icall)
    174161{
    175         sysarg_t method = IPC_GET_IMETHOD(*icall);
    176 
    177         usb_kbd_t *kbd_dev = (usb_kbd_t *) fun->driver_data;
    178         if (kbd_dev == NULL) {
    179                 usb_log_debug("default_connection_handler: "
    180                     "Missing parameter.\n");
     162        if (fun == NULL || fun->driver_data == NULL) {
     163                usb_log_error("%s: Missing parameter.\n", __FUNCTION__);
    181164                async_answer_0(icallid, EINVAL);
    182165                return;
    183166        }
    184167
    185         async_sess_t *sess =
    186             async_callback_receive_start(EXCHANGE_SERIALIZE, icall);
    187         if (sess != NULL) {
     168        const sysarg_t method = IPC_GET_IMETHOD(*icall);
     169        usb_kbd_t *kbd_dev = fun->driver_data;
     170
     171        switch (method) {
     172        case KBDEV_SET_IND:
     173                kbd_dev->mods = IPC_GET_ARG1(*icall);
     174                usb_kbd_set_led(kbd_dev->hid_dev, kbd_dev);
     175                async_answer_0(icallid, EOK);
     176                break;
     177        /* This might be ugly but async_callback_receive_start makes no
     178         * difference for incorrect call and malloc failure. */
     179        case IPC_M_CONNECT_TO_ME: {
     180                async_sess_t *sess =
     181                    async_callback_receive_start(EXCHANGE_SERIALIZE, icall);
     182                /* Probably ENOMEM error, try again. */
     183                if (sess == NULL) {
     184                        usb_log_warning(
     185                            "Failed to create start console session.\n");
     186                        async_answer_0(icallid, EAGAIN);
     187                        break;
     188                }
    188189                if (kbd_dev->console_sess == NULL) {
    189190                        kbd_dev->console_sess = sess;
    190                         usb_log_debug("default_connection_handler: OK\n");
     191                        usb_log_debug("%s: OK\n", __FUNCTION__);
    191192                        async_answer_0(icallid, EOK);
    192193                } else {
    193                         usb_log_debug("default_connection_handler: "
    194                             "console session already set\n");
     194                        usb_log_error("%s: console session already set\n",
     195                           __FUNCTION__);
    195196                        async_answer_0(icallid, ELIMIT);
    196197                }
    197         } else {
    198                 switch (method) {
    199                 case KBDEV_SET_IND:
    200                         kbd_dev->mods = IPC_GET_ARG1(*icall);
    201                         usb_kbd_set_led(kbd_dev->hid_dev, kbd_dev);
    202                         async_answer_0(icallid, EOK);
    203                         break;
    204                 default:
    205                         usb_log_debug("default_connection_handler: Wrong function.\n");
     198                break;
     199        }
     200        default:
     201                        usb_log_error("%s: Unknown method: %d.\n",
     202                            __FUNCTION__, (int) method);
    206203                        async_answer_0(icallid, EINVAL);
    207204                        break;
    208                 }
    209         }
    210 }
    211 
     205        }
     206
     207}
    212208/*----------------------------------------------------------------------------*/
    213209/* Key processing functions                                                   */
     
    226222 * @param kbd_dev Keyboard device structure.
    227223 */
    228 static void usb_kbd_set_led(usb_hid_dev_t *hid_dev, usb_kbd_t *kbd_dev) 
     224static void usb_kbd_set_led(usb_hid_dev_t *hid_dev, usb_kbd_t *kbd_dev)
    229225{
    230226        if (kbd_dev->output_size == 0) {
     
    274270        }
    275271
    276         usb_log_debug("Output report buffer: %s\n", 
    277             usb_debug_str_buffer(kbd_dev->output_buffer, kbd_dev->output_size, 
     272        usb_log_debug("Output report buffer: %s\n",
     273            usb_debug_str_buffer(kbd_dev->output_buffer, kbd_dev->output_size,
    278274                0));
    279275
    280         usbhid_req_set_report(&hid_dev->usb_dev->ctrl_pipe,
    281             hid_dev->usb_dev->interface_no, USB_HID_REPORT_TYPE_OUTPUT, 
     276        rc = usbhid_req_set_report(&hid_dev->usb_dev->ctrl_pipe,
     277            hid_dev->usb_dev->interface_no, USB_HID_REPORT_TYPE_OUTPUT,
    282278            kbd_dev->output_buffer, kbd_dev->output_size);
    283 }
    284 
     279        if (rc != EOK) {
     280                usb_log_warning("Failed to set kbd indicators.\n");
     281        }
     282}
    285283/*----------------------------------------------------------------------------*/
    286284/** Send key event.
     
    291289 * @param key Key code
    292290 */
    293 void usb_kbd_push_ev(usb_hid_dev_t *hid_dev, usb_kbd_t *kbd_dev, int type,
    294     unsigned int key)
     291void usb_kbd_push_ev(usb_kbd_t *kbd_dev, int type, unsigned key)
    295292{
    296293        usb_log_debug2("Sending kbdev event %d/%d to the console\n", type, key);
     
    302299
    303300        async_exch_t *exch = async_exchange_begin(kbd_dev->console_sess);
    304         async_msg_2(exch, KBDEV_EVENT, type, key);
    305         async_exchange_end(exch);
    306 }
    307 
    308 /*----------------------------------------------------------------------------*/
    309 
    310 static inline int usb_kbd_is_lock(unsigned int key_code)
     301        if (exch != NULL) {
     302                async_msg_2(exch, KBDEV_EVENT, type, key);
     303                async_exchange_end(exch);
     304        } else {
     305                usb_log_warning("Failed to send key to console.\n");
     306        }
     307}
     308/*----------------------------------------------------------------------------*/
     309static inline int usb_kbd_is_lock(unsigned int key_code)
    311310{
    312311        return (key_code == KC_NUM_LOCK
     
    314313            || key_code == KC_CAPS_LOCK);
    315314}
    316 
     315/*----------------------------------------------------------------------------*/
    317316static size_t find_in_array_int32(int32_t val, int32_t *arr, size_t arr_size)
    318317{
     
    325324        return (size_t) -1;
    326325}
    327 
    328326/*----------------------------------------------------------------------------*/
    329327/**
     
    342340 * @sa usb_kbd_push_ev(), usb_kbd_repeat_start(), usb_kbd_repeat_stop()
    343341 */
    344 static void usb_kbd_check_key_changes(usb_hid_dev_t *hid_dev, 
     342static void usb_kbd_check_key_changes(usb_hid_dev_t *hid_dev,
    345343    usb_kbd_t *kbd_dev)
    346344{
    347         unsigned int key;
    348         size_t i;
    349345
    350346        /*
     
    356352         * whole input report.
    357353         */
    358         i = find_in_array_int32(ERROR_ROLLOVER, kbd_dev->keys,
     354        size_t i = find_in_array_int32(ERROR_ROLLOVER, kbd_dev->keys,
    359355            kbd_dev->key_count);
    360356        if (i != (size_t) -1) {
    361                 usb_log_debug("Detected phantom state.\n");
     357                usb_log_error("Detected phantom state.\n");
    362358                return;
    363359        }
     
    367363         */
    368364        for (i = 0; i < kbd_dev->key_count; i++) {
    369                 int32_t old_key = kbd_dev->keys_old[i];
     365                const int32_t old_key = kbd_dev->keys_old[i];
    370366                /* Find the old key among currently pressed keys. */
    371                 size_t pos = find_in_array_int32(old_key, kbd_dev->keys,
     367                const size_t pos = find_in_array_int32(old_key, kbd_dev->keys,
    372368                    kbd_dev->key_count);
    373369                /* If the key was not found, we need to signal release. */
    374370                if (pos == (size_t) -1) {
    375                         key = usbhid_parse_scancode(old_key);
     371                        const unsigned key = usbhid_parse_scancode(old_key);
    376372                        if (!usb_kbd_is_lock(key)) {
    377373                                usb_kbd_repeat_stop(kbd_dev, key);
    378374                        }
    379                         usb_kbd_push_ev(hid_dev, kbd_dev, KEY_RELEASE, key);
     375                        usb_kbd_push_ev(kbd_dev, KEY_RELEASE, key);
    380376                        usb_log_debug2("Key released: %u "
    381377                            "(USB code %" PRIu32 ")\n", key, old_key);
     
    387383         */
    388384        for (i = 0; i < kbd_dev->key_count; ++i) {
    389                 int32_t new_key = kbd_dev->keys[i];
     385                const int32_t new_key = kbd_dev->keys[i];
    390386                /* Find the new key among already pressed keys. */
    391                 size_t pos = find_in_array_int32(new_key, kbd_dev->keys_old,
    392                     kbd_dev->key_count);
     387                const size_t pos = find_in_array_int32(new_key,
     388                    kbd_dev->keys_old, kbd_dev->key_count);
    393389                /* If the key was not found, we need to signal press. */
    394390                if (pos == (size_t) -1) {
    395                         key = usbhid_parse_scancode(kbd_dev->keys[i]);
     391                        unsigned key = usbhid_parse_scancode(kbd_dev->keys[i]);
    396392                        if (!usb_kbd_is_lock(key)) {
    397393                                usb_kbd_repeat_start(kbd_dev, key);
    398394                        }
    399                         usb_kbd_push_ev(hid_dev, kbd_dev, KEY_PRESS, key);
     395                        usb_kbd_push_ev(kbd_dev, KEY_PRESS, key);
    400396                        usb_log_debug2("Key pressed: %u "
    401397                            "(USB code %" PRIu32 ")\n", key, new_key);
     
    405401        memcpy(kbd_dev->keys_old, kbd_dev->keys, kbd_dev->key_count * 4);
    406402
     403        // TODO Get rid of this
    407404        char key_buffer[512];
    408405        ddf_dump_buffer(key_buffer, 512,
     
    410407        usb_log_debug2("Stored keys %s.\n", key_buffer);
    411408}
    412 
    413409/*----------------------------------------------------------------------------*/
    414410/* General kbd functions                                                      */
     
    436432
    437433        usb_hid_report_path_t *path = usb_hid_report_path();
    438         usb_hid_report_path_append_item(path, USB_HIDUT_PAGE_KEYBOARD, 0);
    439 
    440         usb_hid_report_path_set_report_id (path, hid_dev->report_id);
    441 
    442         // fill in the currently pressed keys
    443 
     434        if (path == NULL) {
     435                usb_log_error("Failed to create hid/kbd report path.\n");
     436                return;
     437        }
     438
     439        int ret =
     440           usb_hid_report_path_append_item(path, USB_HIDUT_PAGE_KEYBOARD, 0);
     441        if (ret != EOK) {
     442                usb_log_error("Failed to append to hid/kbd report path.\n");
     443                return;
     444        }
     445
     446        usb_hid_report_path_set_report_id(path, hid_dev->report_id);
     447
     448        /* Fill in the currently pressed keys. */
    444449        usb_hid_report_field_t *field = usb_hid_report_get_sibling(
    445450            &hid_dev->report, NULL, path,
     
    449454
    450455        while (field != NULL) {
    451                 usb_log_debug2("FIELD (%p) - VALUE(%d) USAGE(%u)\n", 
     456                usb_log_debug2("FIELD (%p) - VALUE(%d) USAGE(%u)\n",
    452457                    field, field->value, field->usage);
    453                
     458
    454459                assert(i < kbd_dev->key_count);
    455460
    456                 // save the key usage
     461                /* Save the key usage. */
    457462                if (field->value != 0) {
    458463                        kbd_dev->keys[i] = field->usage;
     
    474479        usb_kbd_check_key_changes(hid_dev, kbd_dev);
    475480}
    476 
    477481/*----------------------------------------------------------------------------*/
    478482/* HID/KBD structure manipulation                                             */
    479483/*----------------------------------------------------------------------------*/
    480 
    481 static void usb_kbd_mark_unusable(usb_kbd_t *kbd_dev)
    482 {
    483         kbd_dev->initialized = USB_KBD_STATUS_TO_DESTROY;
    484 }
    485 
    486 /*----------------------------------------------------------------------------*/
    487 
    488 /**
    489  * Creates a new USB/HID keyboard structure.
    490  *
    491  * The structure returned by this function is not initialized. Use
    492  * usb_kbd_init() to initialize it prior to polling.
    493  *
    494  * @return New uninitialized structure for representing a USB/HID keyboard or
    495  *         NULL if not successful (memory error).
    496  */
    497 static usb_kbd_t *usb_kbd_new(void)
    498 {
    499         usb_kbd_t *kbd_dev =
    500             (usb_kbd_t *)calloc(1, sizeof(usb_kbd_t));
    501 
    502         if (kbd_dev == NULL) {
    503                 usb_log_error("No memory!\n");
    504                 return NULL;
    505         }
    506 
    507         kbd_dev->console_sess = NULL;
    508         kbd_dev->initialized = USB_KBD_STATUS_UNINITIALIZED;
    509 
    510         return kbd_dev;
    511 }
    512 
    513 /*----------------------------------------------------------------------------*/
    514 
    515484static int usb_kbd_create_function(usb_kbd_t *kbd_dev)
    516485{
     
    528497        }
    529498
    530         /*
    531          * Store the initialized HID device and HID ops
    532          * to the DDF function.
    533          */
     499        /* Store the initialized HID device and HID ops
     500         * to the DDF function. */
    534501        fun->ops = &kbd_dev->ops;
    535502        fun->driver_data = kbd_dev;
     
    539506                usb_log_error("Could not bind DDF function: %s.\n",
    540507                    str_error(rc));
    541                 fun->driver_data = NULL; /* We need this later */
     508                fun->driver_data = NULL; /* We did not allocate this. */
    542509                ddf_fun_destroy(fun);
    543510                return rc;
     
    547514            HID_KBD_FUN_NAME, fun->handle);
    548515
    549         usb_log_debug("Adding DDF function to category %s...\n", 
     516        usb_log_debug("Adding DDF function to category %s...\n",
    550517            HID_KBD_CLASS_NAME);
    551518        rc = ddf_fun_add_to_category(fun, HID_KBD_CATEGORY_NAME);
     
    554521                    "Could not add DDF function to category %s: %s.\n",
    555522                    HID_KBD_CLASS_NAME, str_error(rc));
    556                 fun->driver_data = NULL; /* We need this later */
    557                 ddf_fun_destroy(fun);
     523                if (ddf_fun_unbind(fun) == EOK) {
     524                        fun->driver_data = NULL; /* We did not allocate this. */
     525                        ddf_fun_destroy(fun);
     526                } else {
     527                        usb_log_error(
     528                            "Failed to unbind `%s', will not destroy.\n",
     529                            fun->name);
     530                }
    558531                return rc;
    559532        }
     
    562535        return EOK;
    563536}
    564 
    565537/*----------------------------------------------------------------------------*/
    566538/* API functions                                                              */
     
    591563
    592564        if (hid_dev == NULL) {
    593                 usb_log_error("Failed to init keyboard structure: no structure"
    594                     " given.\n");
     565                usb_log_error(
     566                    "Failed to init keyboard structure: no structure given.\n");
    595567                return EINVAL;
    596568        }
    597569
    598         usb_kbd_t *kbd_dev = usb_kbd_new();
     570        usb_kbd_t *kbd_dev = calloc(1, sizeof(usb_kbd_t));
    599571        if (kbd_dev == NULL) {
    600                 usb_log_error("Error while creating USB/HID KBD device "
    601                     "structure.\n");
    602                 return ENOMEM;  // TODO: some other code??
    603         }
     572                usb_log_error("Failed to allocate KBD device structure.\n");
     573                return ENOMEM;
     574        }
     575        /* Default values */
     576        fibril_mutex_initialize(&kbd_dev->repeat_mtx);
     577        kbd_dev->initialized = USB_KBD_STATUS_UNINITIALIZED;
     578        kbd_dev->ops.default_handler = default_connection_handler;
    604579
    605580        /* Store link to HID device */
    606581        kbd_dev->hid_dev = hid_dev;
    607582
    608         /*
    609          * TODO: make more general
    610          */
     583        /* Modifiers and locks */
     584        kbd_dev->mods = DEFAULT_ACTIVE_MODS;
     585
     586        /* Autorepeat */
     587        kbd_dev->repeat.delay_before = DEFAULT_DELAY_BEFORE_FIRST_REPEAT;
     588        kbd_dev->repeat.delay_between = DEFAULT_REPEAT_DELAY;
     589
     590
     591        // TODO: make more general
    611592        usb_hid_report_path_t *path = usb_hid_report_path();
    612         usb_hid_report_path_append_item(path, USB_HIDUT_PAGE_KEYBOARD, 0);
     593        if (path == NULL) {
     594                usb_log_error("Failed to create kbd report path.\n");
     595                usb_kbd_destroy(kbd_dev);
     596                return ENOMEM;
     597        }
     598
     599        int ret =
     600            usb_hid_report_path_append_item(path, USB_HIDUT_PAGE_KEYBOARD, 0);
     601        if (ret != EOK) {
     602                usb_log_error("Failed to append item to kbd report path.\n");
     603                usb_hid_report_path_free(path);
     604                usb_kbd_destroy(kbd_dev);
     605                return ret;
     606        }
    613607
    614608        usb_hid_report_path_set_report_id(path, 0);
    615609
    616         kbd_dev->key_count = usb_hid_report_size(
    617             &hid_dev->report, 0, USB_HID_REPORT_TYPE_INPUT);
     610        kbd_dev->key_count =
     611            usb_hid_report_size(&hid_dev->report, 0, USB_HID_REPORT_TYPE_INPUT);
     612
    618613        usb_hid_report_path_free(path);
    619614
     
    621616
    622617        kbd_dev->keys = calloc(kbd_dev->key_count, sizeof(int32_t));
    623 
    624618        if (kbd_dev->keys == NULL) {
    625                 usb_log_error("No memory!\n");
    626                 free(kbd_dev);
     619                usb_log_error("Failed to allocate key buffer.\n");
     620                usb_kbd_destroy(kbd_dev);
    627621                return ENOMEM;
    628622        }
    629623
    630         kbd_dev->keys_old =
    631                 (int32_t *)calloc(kbd_dev->key_count, sizeof(int32_t));
    632 
     624        kbd_dev->keys_old = calloc(kbd_dev->key_count, sizeof(int32_t));
    633625        if (kbd_dev->keys_old == NULL) {
    634                 usb_log_error("No memory!\n");
    635                 free(kbd_dev->keys);
    636                 free(kbd_dev);
     626                usb_log_error("Failed to allocate old_key buffer.\n");
     627                usb_kbd_destroy(kbd_dev);
    637628                return ENOMEM;
    638629        }
    639630
    640         /*
    641          * Output report
    642          */
     631        /* Output report */
    643632        kbd_dev->output_size = 0;
    644633        kbd_dev->output_buffer = usb_hid_report_output(&hid_dev->report,
    645634            &kbd_dev->output_size, 0);
    646635        if (kbd_dev->output_buffer == NULL) {
    647                 usb_log_warning("Error creating output report buffer.\n");
    648                 free(kbd_dev->keys);
     636                usb_log_error("Error creating output report buffer.\n");
     637                usb_kbd_destroy(kbd_dev);
    649638                return ENOMEM;
    650639        }
     
    653642
    654643        kbd_dev->led_path = usb_hid_report_path();
    655         usb_hid_report_path_append_item(
     644        if (kbd_dev->led_path == NULL) {
     645                usb_log_error("Failed to create kbd led report path.\n");
     646                usb_kbd_destroy(kbd_dev);
     647                return ENOMEM;
     648        }
     649
     650        ret = usb_hid_report_path_append_item(
    656651            kbd_dev->led_path, USB_HIDUT_PAGE_LED, 0);
     652        if (ret != EOK) {
     653                usb_log_error("Failed to append to kbd/led report path.\n");
     654                usb_kbd_destroy(kbd_dev);
     655                return ret;
     656        }
    657657
    658658        kbd_dev->led_output_size = usb_hid_report_size(
    659659            &hid_dev->report, 0, USB_HID_REPORT_TYPE_OUTPUT);
    660660
    661         usb_log_debug("Output report size (in items): %zu\n", 
     661        usb_log_debug("Output report size (in items): %zu\n",
    662662            kbd_dev->led_output_size);
    663663
    664         kbd_dev->led_data = (int32_t *)calloc(
    665             kbd_dev->led_output_size, sizeof(int32_t));
    666 
     664        kbd_dev->led_data = calloc(kbd_dev->led_output_size, sizeof(int32_t));
    667665        if (kbd_dev->led_data == NULL) {
    668                 usb_log_warning("Error creating buffer for LED output report."
    669                     "\n");
    670                 free(kbd_dev->keys);
    671                 usb_hid_report_output_free(kbd_dev->output_buffer);
    672                 free(kbd_dev);
     666                usb_log_error("Error creating buffer for LED output report.\n");
     667                usb_kbd_destroy(kbd_dev);
    673668                return ENOMEM;
    674669        }
    675670
    676         /*
    677          * Modifiers and locks
    678          */
    679         kbd_dev->modifiers = 0;
    680         kbd_dev->mods = DEFAULT_ACTIVE_MODS;
    681         kbd_dev->lock_keys = 0;
    682 
    683         /*
    684          * Autorepeat
    685          */
    686         kbd_dev->repeat.key_new = 0;
    687         kbd_dev->repeat.key_repeated = 0;
    688         kbd_dev->repeat.delay_before = DEFAULT_DELAY_BEFORE_FIRST_REPEAT;
    689         kbd_dev->repeat.delay_between = DEFAULT_REPEAT_DELAY;
    690 
    691         fibril_mutex_initialize(&kbd_dev->repeat_mtx);
    692 
    693         // save the KBD device structure into the HID device structure
     671        /* Set LEDs according to initial setup.
     672         * Set Idle rate */
     673        usb_kbd_set_led(hid_dev, kbd_dev);
     674
     675        usbhid_req_set_idle(&hid_dev->usb_dev->ctrl_pipe,
     676            hid_dev->usb_dev->interface_no, IDLE_RATE);
     677
     678        /* Save the KBD device structure into the HID device structure. */
    694679        *data = kbd_dev;
    695680
    696         // set handler for incoming calls
    697         kbd_dev->ops.default_handler = default_connection_handler;
    698 
    699         /*
    700          * Set LEDs according to initial setup.
    701          * Set Idle rate
    702          */
    703         usb_kbd_set_led(hid_dev, kbd_dev);
    704 
    705         usbhid_req_set_idle(&hid_dev->usb_dev->ctrl_pipe,
    706             hid_dev->usb_dev->interface_no, IDLE_RATE);
    707 
    708         /*
    709          * Create new fibril for auto-repeat
    710          */
     681        kbd_dev->initialized = USB_KBD_STATUS_INITIALIZED;
     682        usb_log_debug("HID/KBD device structure initialized.\n");
     683
     684        usb_log_debug("Creating KBD function...\n");
     685        ret = usb_kbd_create_function(kbd_dev);
     686        if (ret != EOK) {
     687                usb_kbd_destroy(kbd_dev);
     688                return ret;
     689        }
     690
     691        /* Create new fibril for auto-repeat. */
    711692        fid_t fid = fibril_create(usb_kbd_repeat_fibril, kbd_dev);
    712693        if (fid == 0) {
    713694                usb_log_error("Failed to start fibril for KBD auto-repeat");
     695                usb_kbd_destroy(kbd_dev);
    714696                return ENOMEM;
    715697        }
    716698        fibril_add_ready(fid);
    717699
    718         kbd_dev->initialized = USB_KBD_STATUS_INITIALIZED;
    719         usb_log_debug("HID/KBD device structure initialized.\n");
    720 
    721         usb_log_debug("Creating KBD function...\n");
    722         int rc = usb_kbd_create_function(kbd_dev);
    723         if (rc != EOK) {
    724                 usb_kbd_destroy(kbd_dev);
    725                 return rc;
    726         }
    727 
    728700        return EOK;
    729701}
    730 
    731 /*----------------------------------------------------------------------------*/
    732 
     702/*----------------------------------------------------------------------------*/
    733703bool usb_kbd_polling_callback(usb_hid_dev_t *hid_dev, void *data)
    734704{
    735         if (hid_dev == NULL/* || buffer == NULL*/ || data == NULL) {
    736                 // do not continue polling (???)
     705        if (hid_dev == NULL || data == NULL) {
     706                /* This means something serious */
    737707                return false;
    738708        }
    739709
    740         usb_kbd_t *kbd_dev = (usb_kbd_t *)data;
    741         assert(kbd_dev != NULL);
    742 
     710        usb_kbd_t *kbd_dev = data;
    743711        // TODO: add return value from this function
    744712        usb_kbd_process_data(hid_dev, kbd_dev);
     
    746714        return true;
    747715}
    748 
    749 /*----------------------------------------------------------------------------*/
    750 
     716/*----------------------------------------------------------------------------*/
    751717int usb_kbd_is_initialized(const usb_kbd_t *kbd_dev)
    752718{
    753719        return (kbd_dev->initialized == USB_KBD_STATUS_INITIALIZED);
    754720}
    755 
    756 /*----------------------------------------------------------------------------*/
    757 
     721/*----------------------------------------------------------------------------*/
    758722int usb_kbd_is_ready_to_destroy(const usb_kbd_t *kbd_dev)
    759723{
    760724        return (kbd_dev->initialized == USB_KBD_STATUS_TO_DESTROY);
    761725}
    762 
    763726/*----------------------------------------------------------------------------*/
    764727/**
     
    773736        }
    774737
    775         // hangup session to the console
    776         async_hangup(kbd_dev->console_sess);
     738        /* Hangup session to the console. */
     739        if (kbd_dev->console_sess)
     740                async_hangup(kbd_dev->console_sess);
    777741
    778742        //assert(!fibril_mutex_is_locked((*kbd_dev)->repeat_mtx));
     
    781745        while (fibril_mutex_is_locked(&kbd_dev->repeat_mtx)) {}
    782746
    783         // free all buffers
     747        /* Free all buffers. */
    784748        free(kbd_dev->keys);
    785749        free(kbd_dev->keys_old);
    786750        free(kbd_dev->led_data);
    787751
    788         if (kbd_dev->led_path != NULL) {
    789                 usb_hid_report_path_free(kbd_dev->led_path);
    790         }
    791         if (kbd_dev->output_buffer != NULL) {
    792                 usb_hid_report_output_free(kbd_dev->output_buffer);
    793         }
    794 
    795         if (ddf_fun_unbind(kbd_dev->fun) != EOK) {
    796                 usb_log_warning("Failed to unbind kbd function.\n");
    797         } else {
    798                 usb_log_debug2("%s unbound.\n", kbd_dev->fun->name);
    799                 kbd_dev->fun->driver_data = NULL;
    800                 ddf_fun_destroy(kbd_dev->fun);
    801         }
    802 }
    803 
    804 /*----------------------------------------------------------------------------*/
    805 
     752        usb_hid_report_path_free(kbd_dev->led_path);
     753        usb_hid_report_output_free(kbd_dev->output_buffer);
     754
     755        if (kbd_dev->fun) {
     756                if (ddf_fun_unbind(kbd_dev->fun) != EOK) {
     757                        usb_log_warning("Failed to unbind %s.\n",
     758                            kbd_dev->fun->name);
     759                } else {
     760                        usb_log_debug2("%s unbound.\n", kbd_dev->fun->name);
     761                        kbd_dev->fun->driver_data = NULL;
     762                        ddf_fun_destroy(kbd_dev->fun);
     763                }
     764        }
     765        free(kbd_dev);
     766}
     767/*----------------------------------------------------------------------------*/
    806768void usb_kbd_deinit(usb_hid_dev_t *hid_dev, void *data)
    807769{
    808         if (hid_dev == NULL) {
    809                 return;
    810         }
    811 
    812770        if (data != NULL) {
    813771                usb_kbd_t *kbd_dev = data;
    814772                if (usb_kbd_is_initialized(kbd_dev)) {
    815                         usb_kbd_mark_unusable(kbd_dev);
    816                         /* wait for autorepeat */
     773                        kbd_dev->initialized = USB_KBD_STATUS_TO_DESTROY;
     774                        /* Wait for autorepeat */
    817775                        async_usleep(CHECK_DELAY);
    818                         usb_kbd_destroy(kbd_dev);
    819                 }
    820         }
    821 }
    822 
    823 /*----------------------------------------------------------------------------*/
    824 
     776                }
     777                usb_kbd_destroy(kbd_dev);
     778        }
     779}
     780/*----------------------------------------------------------------------------*/
    825781int usb_kbd_set_boot_protocol(usb_hid_dev_t *hid_dev)
    826782{
     783        assert(hid_dev);
    827784        int rc = usb_hid_parse_report_descriptor(
    828785            &hid_dev->report, USB_KBD_BOOT_REPORT_DESCRIPTOR,
    829             USB_KBD_BOOT_REPORT_DESCRIPTOR_SIZE);
     786            sizeof(USB_KBD_BOOT_REPORT_DESCRIPTOR));
    830787
    831788        if (rc != EOK) {
     
    846803        return EOK;
    847804}
    848 
    849805/**
    850806 * @}
  • uspace/drv/bus/usb/usbhid/kbd/kbddev.h

    r2e1b9dc r747ef72  
    135135void usb_kbd_destroy(usb_kbd_t *kbd_dev);
    136136
    137 void usb_kbd_push_ev(struct usb_hid_dev *hid_dev, usb_kbd_t *kbd_dev,
     137void usb_kbd_push_ev(usb_kbd_t *kbd_dev,
    138138    int type, unsigned int key);
    139139
  • uspace/drv/bus/usb/usbhid/kbd/kbdrepeat.c

    r2e1b9dc r747ef72  
    4545#include "kbddev.h"
    4646
    47 
    48 
    49 /*----------------------------------------------------------------------------*/
    5047/**
    5148 * Main loop handling the auto-repeat of keys.
     
    5855 * If the same key is still pressed, it uses the delay between repeats stored
    5956 * in the keyboard structure to wait until the key should be repeated.
    60  * 
     57 *
    6158 * If the currently repeated key is not pressed any more (
    62  * usb_kbd_repeat_stop() was called), it stops repeating it and starts 
     59 * usb_kbd_repeat_stop() was called), it stops repeating it and starts
    6360 * checking again.
    6461 *
    6562 * @note For accessing the keyboard device auto-repeat information a fibril
    6663 *       mutex (repeat_mtx) from the @a kbd structure is used.
    67  * 
     64 *
    6865 * @param kbd Keyboard device structure.
    6966 */
     
    7572
    7673        while (true) {
    77                 // check if the kbd structure is usable
     74                /* Check if the kbd structure is usable. */
    7875                if (!usb_kbd_is_initialized(kbd)) {
    7976                        usb_log_warning("kbd not ready, exiting autorepeat.\n");
    8077                        return;
    8178                }
    82                
     79
    8380                fibril_mutex_lock(&kbd->repeat_mtx);
    8481
    8582                if (kbd->repeat.key_new > 0) {
    8683                        if (kbd->repeat.key_new == kbd->repeat.key_repeated) {
    87                                 usb_log_debug2("Repeating key: %u.\n", 
     84                                usb_log_debug2("Repeating key: %u.\n",
    8885                                    kbd->repeat.key_repeated);
    89                                 // ugly hack with the NULL
    90                                 usb_kbd_push_ev(NULL, kbd, KEY_PRESS,
     86                                usb_kbd_push_ev(kbd, KEY_PRESS,
    9187                                    kbd->repeat.key_repeated);
    9288                                delay = kbd->repeat.delay_between;
     
    106102                }
    107103                fibril_mutex_unlock(&kbd->repeat_mtx);
    108                
    109104                async_usleep(delay);
    110105        }
    111106}
    112 
    113107/*----------------------------------------------------------------------------*/
    114108/**
     
    116110 *
    117111 * Starts the loop for checking changes in auto-repeat.
    118  * 
     112 *
    119113 * @param arg User-specified argument. Expects pointer to the keyboard device
    120114 *            structure representing the keyboard.
     
    132126        }
    133127
    134         usb_kbd_t *kbd = (usb_kbd_t *)arg;
     128        usb_kbd_t *kbd = arg;
    135129
    136130        usb_kbd_repeat_loop(kbd);
     
    138132        return EOK;
    139133}
    140 
    141134/*----------------------------------------------------------------------------*/
    142135/**
     
    156149        fibril_mutex_unlock(&kbd->repeat_mtx);
    157150}
    158 
    159151/*----------------------------------------------------------------------------*/
    160152/**
     
    162154 *
    163155 * @note Only one key is repeated at any time, but this function may be called
    164  *       even with key that is not currently repeated (in that case nothing 
     156 *       even with key that is not currently repeated (in that case nothing
    165157 *       happens).
    166158 *
     
    176168        fibril_mutex_unlock(&kbd->repeat_mtx);
    177169}
    178 
    179170/**
    180171 * @}
  • uspace/drv/bus/usb/usbhid/main.c

    r2e1b9dc r747ef72  
    4949
    5050/**
    51  * Function for adding a new device of type USB/HID/keyboard.
     51 * Callback for passing a new device to the driver.
    5252 *
    53  * This functions initializes required structures from the device's descriptors
    54  * and starts new fibril for polling the keyboard for events and another one for
    55  * handling auto-repeat of keys.
     53 * @note Currently, only boot-protocol keyboards are supported by this driver.
    5654 *
    57  * During initialization, the keyboard is switched into boot protocol, the idle
    58  * rate is set to 0 (infinity), resulting in the keyboard only reporting event
    59  * when a key is pressed or released. Finally, the LED lights are turned on
    60  * according to the default setup of lock keys.
    61  *
    62  * @note By default, the keyboards is initialized with Num Lock turned on and
    63  *       other locks turned off.
    64  * @note Currently supports only boot-protocol keyboards.
    65  *
    66  * @param dev Device to add.
     55 * @param dev Structure representing the new device.
    6756 * @return Error code.
    6857 */
    69 static int usb_hid_try_add_device(usb_device_t *dev)
     58static int usb_hid_device_add(usb_device_t *dev)
    7059{
    71         assert(dev != NULL);
     60        usb_log_debug("%s\n", __FUNCTION__);
    7261
    73         /* Initialize device (get and process descriptors, get address, etc.) */
    74         usb_log_debug("Initializing USB/HID device...\n");
     62        if (dev == NULL) {
     63                usb_log_error("Wrong parameter given for add_device().\n");
     64                return EINVAL;
     65        }
    7566
     67        if (dev->interface_no < 0) {
     68                usb_log_error("Failed to add HID device: endpoints not found."
     69                    "\n");
     70                return ENOTSUP;
     71        }
    7672        usb_hid_dev_t *hid_dev =
    7773            usb_device_data_alloc(dev, sizeof(usb_hid_dev_t));
    7874        if (hid_dev == NULL) {
    79                 usb_log_error("Error while creating USB/HID device "
    80                     "structure.\n");
     75                usb_log_error("Failed to create USB/HID device structure.\n");
    8176                return ENOMEM;
    8277        }
    8378
    8479        int rc = usb_hid_init(hid_dev, dev);
    85 
    8680        if (rc != EOK) {
    8781                usb_log_error("Failed to initialize USB/HID device.\n");
     
    9286        usb_log_debug("USB/HID device structure initialized.\n");
    9387
    94         /*
    95          * 1) subdriver vytvori vlastnu ddf_fun, vlastne ddf_dev_ops, ktore da
    96          *    do nej.
    97          * 2) do tych ops do .interfaces[DEV_IFACE_USBHID (asi)] priradi
    98          *    vyplnenu strukturu usbhid_iface_t.
    99          * 3) klientska aplikacia - musi si rucne vytvorit telefon
    100          *    (devman_device_connect() - cesta k zariadeniu (/hw/pci0/...) az
    101          *    k tej fcii.
    102          *    pouzit usb/classes/hid/iface.h - prvy int je telefon
    103          */
    104 
    10588        /* Start automated polling function.
    10689         * This will create a separate fibril that will query the device
    107          * for the data continuously
    108          */
     90         * for the data continuously. */
    10991       rc = usb_device_auto_poll(dev,
    11092           /* Index of the polling pipe. */
     
    11395           usb_hid_polling_callback,
    11496           /* How much data to request. */
    115            dev->pipes[hid_dev->poll_pipe_index].pipe->max_packet_size,
     97           dev->pipes[hid_dev->poll_pipe_index].pipe.max_packet_size,
    11698           /* Callback when the polling ends. */
    11799           usb_hid_polling_ended_callback,
     
    126108        }
    127109        hid_dev->running = true;
    128 
    129         /*
    130          * Hurrah, device is initialized.
    131          */
    132         return EOK;
    133 }
    134 /*----------------------------------------------------------------------------*/
    135 /**
    136  * Callback for passing a new device to the driver.
    137  *
    138  * @note Currently, only boot-protocol keyboards are supported by this driver.
    139  *
    140  * @param dev Structure representing the new device.
    141  * @return Error code.
    142  */
    143 static int usb_hid_device_add(usb_device_t *dev)
    144 {
    145         usb_log_debug("usb_hid_device_add()\n");
    146 
    147         if (dev == NULL) {
    148                 usb_log_warning("Wrong parameter given for add_device().\n");
    149                 return EINVAL;
    150         }
    151 
    152         if (dev->interface_no < 0) {
    153                 usb_log_warning("Device is not a supported HID device.\n");
    154                 usb_log_error("Failed to add HID device: endpoints not found."
    155                     "\n");
    156                 return ENOTSUP;
    157         }
    158 
    159         int rc = usb_hid_try_add_device(dev);
    160 
    161         if (rc != EOK) {
    162                 usb_log_warning("Device is not a supported HID device.\n");
    163                 usb_log_error("Failed to add HID device: %s.\n",
    164                     str_error(rc));
    165                 return rc;
    166         }
    167110
    168111        usb_log_info("HID device `%s' ready to use.\n", dev->ddf_dev->name);
     
    179122static int usb_hid_device_rem(usb_device_t *dev)
    180123{
    181         return EOK;
     124        // TODO: Stop device polling
     125        // TODO: Call deinit (stops autorepeat too)
     126        return ENOTSUP;
    182127}
    183128/*----------------------------------------------------------------------------*/
     
    190135static int usb_hid_device_gone(usb_device_t *dev)
    191136{
     137        assert(dev);
     138        assert(dev->driver_data);
    192139        usb_hid_dev_t *hid_dev = dev->driver_data;
    193         unsigned tries = 10;
    194         while (hid_dev->running) {
     140        unsigned tries = 100;
     141        /* Wait for fail. */
     142        while (hid_dev->running && tries--) {
    195143                async_usleep(100000);
    196                 if (!tries--) {
    197                         usb_log_error("Can't remove hub, still running.\n");
    198                         return EBUSY;
    199                 }
     144        }
     145        if (hid_dev->running) {
     146                usb_log_error("Can't remove hid, still running.\n");
     147                return EBUSY;
    200148        }
    201149
    202         assert(!hid_dev->running);
    203150        usb_hid_deinit(hid_dev);
    204151        usb_log_debug2("%s destruction complete.\n", dev->ddf_dev->name);
  • uspace/drv/bus/usb/usbhid/mouse/mousedev.c

    r2e1b9dc r747ef72  
    5555#define ARROWS_PER_SINGLE_WHEEL 3
    5656
    57 #define NAME  "mouse"
     57#define NAME "mouse"
    5858
    5959/*----------------------------------------------------------------------------*/
     
    7777
    7878/*----------------------------------------------------------------------------*/
    79 
    80 enum {
    81         USB_MOUSE_BOOT_REPORT_DESCRIPTOR_SIZE = 63
    82 };
    83 
    84 static const uint8_t USB_MOUSE_BOOT_REPORT_DESCRIPTOR[
    85     USB_MOUSE_BOOT_REPORT_DESCRIPTOR_SIZE] = {
     79static const uint8_t USB_MOUSE_BOOT_REPORT_DESCRIPTOR[] = {
    8680        0x05, 0x01,                    // USAGE_PAGE (Generic Desktop)
    8781        0x09, 0x02,                    // USAGE (Mouse)
     
    123117    ipc_callid_t icallid, ipc_call_t *icall)
    124118{
    125         usb_mouse_t *mouse_dev = (usb_mouse_t *) fun->driver_data;
     119        usb_mouse_t *mouse_dev = fun->driver_data;
    126120
    127121        if (mouse_dev == NULL) {
    128                 usb_log_debug("default_connection_handler: Missing "
    129                     "parameters.\n");
     122                usb_log_debug("%s: Missing parameters.\n", __FUNCTION__);
    130123                async_answer_0(icallid, EINVAL);
    131124                return;
    132125        }
    133126
    134         usb_log_debug("default_connection_handler: fun->name: %s\n",
    135                       fun->name);
    136         usb_log_debug("default_connection_handler: mouse_sess: %p, "
    137             "wheel_sess: %p\n", mouse_dev->mouse_sess, mouse_dev->wheel_sess);
    138 
    139         async_sess_t **sess_ptr =
    140             (str_cmp(fun->name, HID_MOUSE_FUN_NAME) == 0) ?
     127        usb_log_debug("%s: fun->name: %s\n", __FUNCTION__, fun->name);
     128        usb_log_debug("%s: mouse_sess: %p, wheel_sess: %p\n",
     129            __FUNCTION__, mouse_dev->mouse_sess, mouse_dev->wheel_sess);
     130
     131        async_sess_t **sess_ptr = (fun == mouse_dev->mouse_fun) ?
    141132            &mouse_dev->mouse_sess : &mouse_dev->wheel_sess;
    142133
     
    146137                if (*sess_ptr == NULL) {
    147138                        *sess_ptr = sess;
    148                         usb_log_debug("Console session to mouse set ok (%p).\n",
    149                             sess);
     139                        usb_log_debug("Console session to %s set ok (%p).\n",
     140                            fun->name, sess);
    150141                        async_answer_0(icallid, EOK);
    151142                } else {
    152                         usb_log_debug("default_connection_handler: Console "
    153                             "session to mouse already set.\n");
     143                        usb_log_error("Console session to %s already set.\n",
     144                            fun->name);
    154145                        async_answer_0(icallid, ELIMIT);
    155146                }
    156147        } else {
    157                 usb_log_debug("default_connection_handler: Invalid function.\n");
     148                usb_log_debug("%s: Invalid function.\n", __FUNCTION__);
    158149                async_answer_0(icallid, EINVAL);
    159         }
    160 }
    161 
    162 /*----------------------------------------------------------------------------*/
    163 
    164 static usb_mouse_t *usb_mouse_new(void)
    165 {
    166         usb_mouse_t *mouse = calloc(1, sizeof(usb_mouse_t));
    167         if (mouse == NULL) {
    168                 return NULL;
    169         }
    170         mouse->mouse_sess = NULL;
    171         mouse->wheel_sess = NULL;
    172 
    173         return mouse;
    174 }
    175 
    176 /*----------------------------------------------------------------------------*/
    177 
    178 static void usb_mouse_destroy(usb_mouse_t *mouse_dev)
    179 {
    180         assert(mouse_dev != NULL);
    181 
    182         // hangup session to the console
    183         if (mouse_dev->mouse_sess != NULL)
    184                 async_hangup(mouse_dev->mouse_sess);
    185 
    186         if (mouse_dev->wheel_sess != NULL)
    187                 async_hangup(mouse_dev->wheel_sess);
    188         int ret = ddf_fun_unbind(mouse_dev->mouse_fun);
    189         if (ret != EOK) {
    190                 usb_log_error("Failed to unbind mouse function.\n");
    191         } else {
    192                 ddf_fun_destroy(mouse_dev->mouse_fun);
    193                 /* Prevent double free */
    194                 mouse_dev->wheel_fun->driver_data = NULL;
    195         }
    196 
    197         ret = ddf_fun_unbind(mouse_dev->wheel_fun);
    198         if (ret != EOK) {
    199                 usb_log_error("Failed to unbind wheel function.\n");
    200         } else {
    201                 ddf_fun_destroy(mouse_dev->wheel_fun);
    202150        }
    203151}
     
    215163        }
    216164
    217         int count = ((wheel < 0) ? -wheel : wheel) * ARROWS_PER_SINGLE_WHEEL;
    218         int i;
    219 
    220         for (i = 0; i < count; i++) {
     165        const unsigned count =
     166            ((wheel < 0) ? -wheel : wheel) * ARROWS_PER_SINGLE_WHEEL;
     167        for (unsigned i = 0; i < count; i++) {
    221168                /* Send arrow press and release. */
    222169                usb_log_debug2("Sending key %d to the console\n", key);
     
    267214        }
    268215
    269         int shift_x = get_mouse_axis_move_value(hid_dev->report_id,
     216        const int shift_x = get_mouse_axis_move_value(hid_dev->report_id,
    270217            &hid_dev->report, USB_HIDUT_USAGE_GENERIC_DESKTOP_X);
    271         int shift_y = get_mouse_axis_move_value(hid_dev->report_id,
     218        const int shift_y = get_mouse_axis_move_value(hid_dev->report_id,
    272219            &hid_dev->report, USB_HIDUT_USAGE_GENERIC_DESKTOP_Y);
    273         int wheel = get_mouse_axis_move_value(hid_dev->report_id,
     220        const int wheel = get_mouse_axis_move_value(hid_dev->report_id,
    274221            &hid_dev->report, USB_HIDUT_USAGE_GENERIC_DESKTOP_WHEEL);
    275222
     
    277224                async_exch_t *exch =
    278225                    async_exchange_begin(mouse_dev->mouse_sess);
    279                 async_req_2_0(exch, MOUSEEV_MOVE_EVENT, shift_x, shift_y);
    280                 async_exchange_end(exch);
     226                if (exch != NULL) {
     227                        async_req_2_0(exch, MOUSEEV_MOVE_EVENT, shift_x, shift_y);
     228                        async_exchange_end(exch);
     229                }
    281230        }
    282231
     
    284233                usb_mouse_send_wheel(mouse_dev, wheel);
    285234
    286         /*
    287          * Buttons
    288          */
     235        /* Buttons */
    289236        usb_hid_report_path_t *path = usb_hid_report_path();
    290         usb_hid_report_path_append_item(path, USB_HIDUT_PAGE_BUTTON, 0);
     237        if (path == NULL) {
     238                usb_log_warning("Failed to create USB HID report path.\n");
     239                return true;
     240        }
     241        int ret =
     242           usb_hid_report_path_append_item(path, USB_HIDUT_PAGE_BUTTON, 0);
     243        if (ret != EOK) {
     244                usb_hid_report_path_free(path);
     245                usb_log_warning("Failed to add buttons to report path.\n");
     246                return true;
     247        }
    291248        usb_hid_report_path_set_report_id(path, hid_dev->report_id);
    292249
     
    298255                usb_log_debug2(NAME " VALUE(%X) USAGE(%X)\n", field->value,
    299256                    field->usage);
    300                
    301                 if (mouse_dev->buttons[field->usage - field->usage_minimum] == 0
    302                     && field->value != 0) {
     257                assert(field->usage > field->usage_minimum);
     258                const unsigned index = field->usage - field->usage_minimum;
     259                assert(index < mouse_dev->buttons_count);
     260
     261                if (mouse_dev->buttons[index] == 0 && field->value != 0) {
    303262                        async_exch_t *exch =
    304263                            async_exchange_begin(mouse_dev->mouse_sess);
    305                         async_req_2_0(exch, MOUSEEV_BUTTON_EVENT, field->usage, 1);
    306                         async_exchange_end(exch);
    307                        
    308                         mouse_dev->buttons[field->usage - field->usage_minimum]
    309                             = field->value;
    310                 } else if (mouse_dev->buttons[field->usage - field->usage_minimum] != 0
    311                     && field->value == 0) {
     264                        if (exch != NULL) {
     265                                async_req_2_0(exch, MOUSEEV_BUTTON_EVENT,
     266                                    field->usage, 1);
     267                                async_exchange_end(exch);
     268                                mouse_dev->buttons[index] = field->value;
     269                        }
     270
     271                } else if (mouse_dev->buttons[index] != 0 && field->value == 0) {
    312272                        async_exch_t *exch =
    313273                            async_exchange_begin(mouse_dev->mouse_sess);
    314                         async_req_2_0(exch, MOUSEEV_BUTTON_EVENT, field->usage, 0);
    315                         async_exchange_end(exch);
    316 
    317                         mouse_dev->buttons[field->usage - field->usage_minimum] =
    318                            field->value;
     274                        if (exch != NULL) {
     275                                async_req_2_0(exch, MOUSEEV_BUTTON_EVENT,
     276                                    field->usage, 0);
     277                                async_exchange_end(exch);
     278                                mouse_dev->buttons[index] = field->value;
     279                        }
    319280                }
    320281
     
    329290        return true;
    330291}
    331 
    332 /*----------------------------------------------------------------------------*/
    333 
     292/*----------------------------------------------------------------------------*/
     293#define FUN_UNBIND_DESTROY(fun) \
     294if (fun) { \
     295        if (ddf_fun_unbind((fun)) == EOK) { \
     296                (fun)->driver_data = NULL; \
     297                ddf_fun_destroy((fun)); \
     298        } else { \
     299                usb_log_error("Could not unbind function `%s', it " \
     300                    "will not be destroyed.\n", (fun)->name); \
     301        } \
     302} else (void)0
     303/*----------------------------------------------------------------------------*/
    334304static int usb_mouse_create_function(usb_hid_dev_t *hid_dev, usb_mouse_t *mouse)
    335305{
     
    339309        /* Create the exposed function. */
    340310        usb_log_debug("Creating DDF function %s...\n", HID_MOUSE_FUN_NAME);
    341         ddf_fun_t *fun = ddf_fun_create(hid_dev->usb_dev->ddf_dev, fun_exposed, 
     311        ddf_fun_t *fun = ddf_fun_create(hid_dev->usb_dev->ddf_dev, fun_exposed,
    342312            HID_MOUSE_FUN_NAME);
    343313        if (fun == NULL) {
    344                 usb_log_error("Could not create DDF function node.\n");
     314                usb_log_error("Could not create DDF function node `%s'.\n",
     315                    HID_MOUSE_FUN_NAME);
    345316                return ENOMEM;
    346317        }
     
    351322        int rc = ddf_fun_bind(fun);
    352323        if (rc != EOK) {
    353                 usb_log_error("Could not bind DDF function: %s.\n",
    354                     str_error(rc));
    355                 return rc;
    356         }
    357 
    358         usb_log_debug("Adding DDF function to category %s...\n",
    359             HID_MOUSE_CATEGORY);
     324                usb_log_error("Could not bind DDF function `%s': %s.\n",
     325                    fun->name, str_error(rc));
     326                fun->driver_data = NULL;
     327                ddf_fun_destroy(fun);
     328                return rc;
     329        }
     330
     331        usb_log_debug("Adding DDF function `%s' to category %s...\n",
     332            fun->name, HID_MOUSE_CATEGORY);
    360333        rc = ddf_fun_add_to_category(fun, HID_MOUSE_CATEGORY);
    361334        if (rc != EOK) {
     
    363336                    "Could not add DDF function to category %s: %s.\n",
    364337                    HID_MOUSE_CATEGORY, str_error(rc));
     338                FUN_UNBIND_DESTROY(fun);
    365339                return rc;
    366340        }
     
    370344         * Special function for acting as keyboard (wheel)
    371345         */
    372         usb_log_debug("Creating DDF function %s...\n", 
     346        usb_log_debug("Creating DDF function %s...\n",
    373347                      HID_MOUSE_WHEEL_FUN_NAME);
    374         fun = ddf_fun_create(hid_dev->usb_dev->ddf_dev, fun_exposed, 
     348        fun = ddf_fun_create(hid_dev->usb_dev->ddf_dev, fun_exposed,
    375349            HID_MOUSE_WHEEL_FUN_NAME);
    376350        if (fun == NULL) {
    377                 usb_log_error("Could not create DDF function node.\n");
     351                usb_log_error("Could not create DDF function node `%s'.\n",
     352                    HID_MOUSE_WHEEL_FUN_NAME);
     353                FUN_UNBIND_DESTROY(mouse->mouse_fun);
     354                mouse->mouse_fun = NULL;
    378355                return ENOMEM;
    379356        }
     
    388365        rc = ddf_fun_bind(fun);
    389366        if (rc != EOK) {
    390                 usb_log_error("Could not bind DDF function: %s.\n",
    391                     str_error(rc));
     367                usb_log_error("Could not bind DDF function `%s': %s.\n",
     368                    fun->name, str_error(rc));
     369                FUN_UNBIND_DESTROY(mouse->mouse_fun);
     370                mouse->mouse_fun = NULL;
     371
     372                fun->driver_data = NULL;
     373                ddf_fun_destroy(fun);
    392374                return rc;
    393375        }
     
    400382                    "Could not add DDF function to category %s: %s.\n",
    401383                    HID_MOUSE_WHEEL_CATEGORY, str_error(rc));
     384
     385                FUN_UNBIND_DESTROY(mouse->mouse_fun);
     386                mouse->mouse_fun = NULL;
     387                FUN_UNBIND_DESTROY(fun);
    402388                return rc;
    403389        }
     
    448434        return highest_button;
    449435}
    450 
    451 /*----------------------------------------------------------------------------*/
    452 
     436/*----------------------------------------------------------------------------*/
    453437int usb_mouse_init(usb_hid_dev_t *hid_dev, void **data)
    454438{
     
    461445        }
    462446
    463         usb_mouse_t *mouse_dev = usb_mouse_new();
     447        usb_mouse_t *mouse_dev = calloc(1, sizeof(usb_mouse_t));
    464448        if (mouse_dev == NULL) {
    465449                usb_log_error("Error while creating USB/HID Mouse device "
     
    484468        }
    485469
    486 
    487         // save the Mouse device structure into the HID device structure
    488         *data = mouse_dev;
    489 
    490470        // set handler for incoming calls
    491471        mouse_dev->ops.default_handler = default_connection_handler;
    492472
    493473        // TODO: how to know if the device supports the request???
    494         usbhid_req_set_idle(&hid_dev->usb_dev->ctrl_pipe, 
     474        usbhid_req_set_idle(&hid_dev->usb_dev->ctrl_pipe,
    495475            hid_dev->usb_dev->interface_no, IDLE_RATE);
    496476
    497477        int rc = usb_mouse_create_function(hid_dev, mouse_dev);
    498478        if (rc != EOK) {
    499                 usb_mouse_destroy(mouse_dev);
    500                 return rc;
    501         }
     479                free(mouse_dev->buttons);
     480                free(mouse_dev);
     481                return rc;
     482        }
     483
     484        /* Save the Mouse device structure into the HID device structure. */
     485        *data = mouse_dev;
    502486
    503487        return EOK;
    504488}
    505 
    506 /*----------------------------------------------------------------------------*/
    507 
     489/*----------------------------------------------------------------------------*/
    508490bool usb_mouse_polling_callback(usb_hid_dev_t *hid_dev, void *data)
    509491{
    510492        if (hid_dev == NULL || data == NULL) {
    511                 usb_log_error("Missing argument to the mouse polling callback."
    512                     "\n");
     493                usb_log_error(
     494                    "Missing argument to the mouse polling callback.\n");
    513495                return false;
    514496        }
    515497
    516         usb_mouse_t *mouse_dev = (usb_mouse_t *)data;
    517                
     498        usb_mouse_t *mouse_dev = data;
     499
    518500        return usb_mouse_process_report(hid_dev, mouse_dev);
    519501}
    520 
    521 /*----------------------------------------------------------------------------*/
    522 
     502/*----------------------------------------------------------------------------*/
    523503void usb_mouse_deinit(usb_hid_dev_t *hid_dev, void *data)
    524504{
    525         if (data != NULL) {
    526                 usb_mouse_destroy(data);
    527         }
    528 }
    529 
    530 /*----------------------------------------------------------------------------*/
    531 
     505        if (data == NULL)
     506                return;
     507
     508        usb_mouse_t *mouse_dev = data;
     509
     510        /* Hangup session to the console */
     511        if (mouse_dev->mouse_sess != NULL) {
     512                const int ret = async_hangup(mouse_dev->mouse_sess);
     513                if (ret != EOK)
     514                        usb_log_warning("Failed to hang up mouse session: "
     515                            "%p, %s.\n", mouse_dev->mouse_sess, str_error(ret));
     516        }
     517
     518        if (mouse_dev->wheel_sess != NULL) {
     519                const int ret = async_hangup(mouse_dev->wheel_sess);
     520                if (ret != EOK)
     521                        usb_log_warning("Failed to hang up wheel session: "
     522                            "%p, %s.\n", mouse_dev->wheel_sess, str_error(ret));
     523        }
     524
     525        FUN_UNBIND_DESTROY(mouse_dev->mouse_fun);
     526        FUN_UNBIND_DESTROY(mouse_dev->wheel_fun);
     527
     528        free(mouse_dev->buttons);
     529        free(mouse_dev);
     530}
     531/*----------------------------------------------------------------------------*/
    532532int usb_mouse_set_boot_protocol(usb_hid_dev_t *hid_dev)
    533533{
    534534        int rc = usb_hid_parse_report_descriptor(
    535535            &hid_dev->report, USB_MOUSE_BOOT_REPORT_DESCRIPTOR,
    536             USB_MOUSE_BOOT_REPORT_DESCRIPTOR_SIZE);
     536            sizeof(USB_MOUSE_BOOT_REPORT_DESCRIPTOR));
    537537
    538538        if (rc != EOK) {
  • uspace/drv/bus/usb/usbhid/multimedia/multimedia.c

    r2e1b9dc r747ef72  
    6767        /** IPC session to the console device (for sending key events). */
    6868        async_sess_t *console_sess;
    69         /** DDF function */
    70         ddf_fun_t *fun;
    7169} usb_multimedia_t;
    7270
    7371
    7472/*----------------------------------------------------------------------------*/
    75 /** 
     73/**
    7674 * Default handler for IPC methods not handled by DDF.
    7775 *
     
    8886{
    8987        usb_log_debug(NAME " default_connection_handler()\n");
    90 
    91         usb_multimedia_t *multim_dev = (usb_multimedia_t *)fun->driver_data;
    92 
    93         if (multim_dev == NULL) {
     88        if (fun == NULL || fun->driver_data == NULL) {
    9489                async_answer_0(icallid, EINVAL);
    9590                return;
    9691        }
     92
     93        usb_multimedia_t *multim_dev = fun->driver_data;
    9794
    9895        async_sess_t *sess =
     
    109106                async_answer_0(icallid, EINVAL);
    110107}
    111 
    112 /*----------------------------------------------------------------------------*/
    113 
     108/*----------------------------------------------------------------------------*/
    114109static ddf_dev_ops_t multimedia_ops = {
    115110        .default_handler = default_connection_handler
    116111};
    117 
    118112/*----------------------------------------------------------------------------*/
    119113/**
     
    127121 *       sends also these keys to application (otherwise it cannot use those
    128122 *       keys at all).
    129  * 
    130  * @param hid_dev 
    131  * @param lgtch_dev
    132  * @param type Type of the event (press / release). Recognized values: 
     123 *
     124 * @param hid_dev
     125 * @param multim_dev
     126 * @param type Type of the event (press / release). Recognized values:
    133127 *             KEY_PRESS, KEY_RELEASE
    134128 * @param key Key code of the key according to HID Usage Tables.
    135129 */
    136 static void usb_multimedia_push_ev(usb_hid_dev_t *hid_dev,
     130static void usb_multimedia_push_ev(
    137131    usb_multimedia_t *multim_dev, int type, unsigned int key)
    138132{
    139         assert(hid_dev != NULL);
    140133        assert(multim_dev != NULL);
    141134
    142         kbd_event_t ev;
    143 
    144         ev.type = type;
    145         ev.key = key;
    146         ev.mods = 0;
    147         ev.c = 0;
     135        const kbd_event_t ev = {
     136                .type = type,
     137                .key = key,
     138                .mods = 0,
     139                .c = 0,
     140        };
    148141
    149142        usb_log_debug2(NAME " Sending key %d to the console\n", ev.key);
     
    155148
    156149        async_exch_t *exch = async_exchange_begin(multim_dev->console_sess);
    157         async_msg_4(exch, KBDEV_EVENT, ev.type, ev.key, ev.mods, ev.c);
    158         async_exchange_end(exch);
    159 }
    160 
    161 /*----------------------------------------------------------------------------*/
    162 
     150        if (exch != NULL) {
     151                async_msg_4(exch, KBDEV_EVENT, ev.type, ev.key, ev.mods, ev.c);
     152                async_exchange_end(exch);
     153        } else {
     154                usb_log_warning("Failed to send multimedia key.\n");
     155        }
     156}
     157/*----------------------------------------------------------------------------*/
    163158int usb_multimedia_init(struct usb_hid_dev *hid_dev, void **data)
    164159{
    165160        if (hid_dev == NULL || hid_dev->usb_dev == NULL) {
    166                 return EINVAL; /*! @todo Other return code? */
     161                return EINVAL;
    167162        }
    168163
     
    187182
    188183        multim_dev->console_sess = NULL;
    189         multim_dev->fun = fun;
    190184
    191185        //todo Autorepeat?
     
    199193        }
    200194
    201         usb_log_debug("%s function created (handle: %" PRIun ").\n",
    202             NAME, fun->handle);
     195        usb_log_debug(NAME " function created (handle: %" PRIun ").\n",
     196            fun->handle);
    203197
    204198        rc = ddf_fun_add_to_category(fun, "keyboard");
     
    207201                    "Could not add DDF function to category 'keyboard': %s.\n",
    208202                    str_error(rc));
    209                 ddf_fun_destroy(fun);
     203                if (ddf_fun_unbind(fun) != EOK) {
     204                        usb_log_error("Failed to unbind %s, won't destroy.\n",
     205                            fun->name);
     206                } else {
     207                        ddf_fun_destroy(fun);
     208                }
    210209                return rc;
    211210        }
    212211
    213212        /* Save the KBD device structure into the HID device structure. */
    214         *data = multim_dev;
     213        *data = fun;
    215214
    216215        usb_log_debug(NAME " HID/multimedia structure initialized.\n");
    217216        return EOK;
    218217}
    219 
    220 /*----------------------------------------------------------------------------*/
    221 
     218/*----------------------------------------------------------------------------*/
    222219void usb_multimedia_deinit(struct usb_hid_dev *hid_dev, void *data)
    223220{
    224         if (hid_dev == NULL) {
    225                 return;
    226         }
    227 
    228         if (data != NULL) {
    229                 usb_multimedia_t *multim_dev = (usb_multimedia_t *)data;
    230                 // hangup session to the console
    231                 async_hangup(multim_dev->console_sess);
    232                 const int ret = ddf_fun_unbind(multim_dev->fun);
    233                 if (ret != EOK) {
    234                         usb_log_error("Failed to unbind multim function.\n");
     221        ddf_fun_t *fun = data;
     222        if (fun != NULL && fun->driver_data != NULL) {
     223                usb_multimedia_t *multim_dev = fun->driver_data;
     224                /* Hangup session to the console */
     225                if (multim_dev->console_sess)
     226                        async_hangup(multim_dev->console_sess);
     227                if (ddf_fun_unbind(fun) != EOK) {
     228                        usb_log_error("Failed to unbind %s, won't destroy.\n",
     229                            fun->name);
    235230                } else {
    236                         usb_log_debug2("%s unbound.\n", multim_dev->fun->name);
    237                         ddf_fun_destroy(multim_dev->fun);
     231                        usb_log_debug2("%s unbound.\n", fun->name);
     232                        /* This frees multim_dev too as it was stored in
     233                         * fun->data */
     234                        ddf_fun_destroy(fun);
    238235                }
    239         }
    240 }
    241 
    242 /*----------------------------------------------------------------------------*/
    243 
     236        } else {
     237                usb_log_error(
     238                    "Failed to deinit multimedia subdriver, data missing.\n");
     239        }
     240}
     241/*----------------------------------------------------------------------------*/
    244242bool usb_multimedia_polling_callback(struct usb_hid_dev *hid_dev, void *data)
    245243{
    246244        // TODO: checks
    247         if (hid_dev == NULL || data == NULL) {
     245        ddf_fun_t *fun = data;
     246        if (hid_dev == NULL || fun == NULL || fun->driver_data == NULL) {
    248247                return false;
    249248        }
    250249
    251         usb_multimedia_t *multim_dev = (usb_multimedia_t *)data;
     250        usb_multimedia_t *multim_dev = fun->driver_data;
    252251
    253252        usb_hid_report_path_t *path = usb_hid_report_path();
    254         usb_hid_report_path_append_item(path, USB_HIDUT_PAGE_CONSUMER, 0);
     253        if (path == NULL)
     254                return true; /* This might be a temporary failure. */
     255
     256        int ret =
     257            usb_hid_report_path_append_item(path, USB_HIDUT_PAGE_CONSUMER, 0);
     258        if (ret != EOK) {
     259                usb_hid_report_path_free(path);
     260                return true; /* This might be a temporary failure. */
     261        }
    255262
    256263        usb_hid_report_path_set_report_id(path, hid_dev->report_id);
     
    261268            USB_HID_REPORT_TYPE_INPUT);
    262269
    263         /*! @todo Is this iterating OK if done multiple times?
    264          *  @todo The parsing is not OK
    265          */
     270        //FIXME Is this iterating OK if done multiple times?
     271        //FIXME The parsing is not OK. (what's wrong?)
    266272        while (field != NULL) {
    267                 if(field->value != 0) {
    268                         usb_log_debug(NAME " KEY VALUE(%X) USAGE(%X)\n", 
     273                if (field->value != 0) {
     274                        usb_log_debug(NAME " KEY VALUE(%X) USAGE(%X)\n",
    269275                            field->value, field->usage);
    270                         unsigned int key =
     276                        const unsigned key =
    271277                            usb_multimedia_map_usage(field->usage);
    272                         const char *key_str = 
     278                        const char *key_str =
    273279                            usbhid_multimedia_usage_to_str(field->usage);
    274280                        usb_log_info("Pressed key: %s\n", key_str);
    275                         usb_multimedia_push_ev(hid_dev, multim_dev, KEY_PRESS,
    276                                                key);
     281                        usb_multimedia_push_ev(multim_dev, KEY_PRESS, key);
    277282                }
    278283
    279284                field = usb_hid_report_get_sibling(
    280285                    &hid_dev->report, field, path, USB_HID_PATH_COMPARE_END
    281                     | USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY, 
     286                    | USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY,
    282287                    USB_HID_REPORT_TYPE_INPUT);
    283288        }
     
    287292        return true;
    288293}
    289 
    290294/**
    291295 * @}
  • uspace/drv/bus/usb/usbhid/subdrivers.c

    r2e1b9dc r747ef72  
    9898                }
    9999        },
    100         {NULL, -1, 0, -1, -1, {NULL, NULL, NULL, NULL, NULL}}
    101100};
    102101
    103 const int USB_HID_MAX_SUBDRIVERS =
     102const size_t USB_HID_MAX_SUBDRIVERS =
    104103    sizeof(usb_hid_subdrivers) / sizeof(usb_hid_subdrivers[0]);
    105104
  • uspace/drv/bus/usb/usbhid/subdrivers.h

    r2e1b9dc r747ef72  
    8484
    8585extern const usb_hid_subdriver_mapping_t usb_hid_subdrivers[];
    86 extern const int USB_HID_MAX_SUBDRIVERS;
     86extern const size_t USB_HID_MAX_SUBDRIVERS;
    8787
    8888/*----------------------------------------------------------------------------*/
  • uspace/drv/bus/usb/usbhid/usbhid.c

    r2e1b9dc r747ef72  
    5151#include "subdrivers.h"
    5252
    53 /*----------------------------------------------------------------------------*/
    54 
    5553/* Array of endpoints expected on the device, NULL terminated. */
    5654const usb_endpoint_description_t *usb_hid_endpoints[] = {
     
    6058        NULL
    6159};
    62 
    63 /*----------------------------------------------------------------------------*/
    64 
     60/*----------------------------------------------------------------------------*/
    6561static int usb_hid_set_boot_kbd_subdriver(usb_hid_dev_t *hid_dev)
    6662{
     
    7874        return EOK;
    7975}
    80 
    81 /*----------------------------------------------------------------------------*/
    82 
     76/*----------------------------------------------------------------------------*/
    8377static int usb_hid_set_boot_mouse_subdriver(usb_hid_dev_t *hid_dev)
    8478{
     
    9286        hid_dev->subdriver_count = 1;
    9387        // TODO 2 should be mouse, but find a better way
    94         hid_dev->subdrivers[2] = usb_hid_subdrivers[0].subdriver;
     88        hid_dev->subdrivers[0] = usb_hid_subdrivers[2].subdriver;
    9589
    9690        return EOK;
    9791}
    98 
    99 /*----------------------------------------------------------------------------*/
    100 
     92/*----------------------------------------------------------------------------*/
    10193static int usb_hid_set_generic_hid_subdriver(usb_hid_dev_t *hid_dev)
    10294{
    103         assert(hid_dev != NULL && hid_dev->subdriver_count == 0);
     95        assert(hid_dev != NULL);
     96        assert(hid_dev->subdriver_count == 0);
    10497
    10598        hid_dev->subdrivers = malloc(sizeof(usb_hid_subdriver_t));
     
    117110        return EOK;
    118111}
    119 
    120 /*----------------------------------------------------------------------------*/
    121 
     112/*----------------------------------------------------------------------------*/
    122113static bool usb_hid_ids_match(const usb_hid_dev_t *hid_dev,
    123114    const usb_hid_subdriver_mapping_t *mapping)
     
    128119        return (hid_dev->usb_dev->descriptors.device.vendor_id
    129120            == mapping->vendor_id
    130             && hid_dev->usb_dev->descriptors.device.product_id 
     121            && hid_dev->usb_dev->descriptors.device.product_id
    131122            == mapping->product_id);
    132123}
    133 
    134 /*----------------------------------------------------------------------------*/
    135 
     124/*----------------------------------------------------------------------------*/
    136125static bool usb_hid_path_matches(usb_hid_dev_t *hid_dev,
    137126    const usb_hid_subdriver_mapping_t *mapping)
     
    145134                return false;
    146135        }
    147         int i = 0;
    148         while (mapping->usage_path[i].usage != 0
    149             || mapping->usage_path[i].usage_page != 0) {
     136
     137        for (int i = 0; mapping->usage_path[i].usage != 0
     138            || mapping->usage_path[i].usage_page != 0; ++i) {
    150139                if (usb_hid_report_path_append_item(usage_path,
    151140                    mapping->usage_path[i].usage_page,
     
    155144                        return false;
    156145                }
    157                 ++i;
    158146        }
    159147
     
    165153        do {
    166154                usb_log_debug("Trying report id %u\n", report_id);
    167 
    168155                if (report_id != 0) {
    169156                        usb_hid_report_path_set_report_id(usage_path,
     
    171158                }
    172159
    173                 usb_hid_report_field_t *field = usb_hid_report_get_sibling(
    174                     &hid_dev->report, NULL, usage_path, mapping->compare,
    175                     USB_HID_REPORT_TYPE_INPUT);
     160                const usb_hid_report_field_t *field =
     161                    usb_hid_report_get_sibling(
     162                        &hid_dev->report, NULL, usage_path, mapping->compare,
     163                        USB_HID_REPORT_TYPE_INPUT);
    176164
    177165                usb_log_debug("Field: %p\n", field);
     
    190178        return matches;
    191179}
    192 
    193 /*----------------------------------------------------------------------------*/
    194 
     180/*----------------------------------------------------------------------------*/
    195181static int usb_hid_save_subdrivers(usb_hid_dev_t *hid_dev,
    196     const usb_hid_subdriver_t **subdrivers, int count)
    197 {
    198         int i;
    199 
    200         if (count <= 0) {
     182    const usb_hid_subdriver_t **subdrivers, unsigned count)
     183{
     184        assert(hid_dev);
     185        assert(subdrivers);
     186
     187        if (count == 0) {
    201188                hid_dev->subdriver_count = 0;
    202189                hid_dev->subdrivers = NULL;
     
    210197        }
    211198
    212         for (i = 0; i < count; ++i) {
    213                 hid_dev->subdrivers[i].init = subdrivers[i]->init;
    214                 hid_dev->subdrivers[i].deinit = subdrivers[i]->deinit;
    215                 hid_dev->subdrivers[i].poll = subdrivers[i]->poll;
    216                 hid_dev->subdrivers[i].poll_end = subdrivers[i]->poll_end;
     199        for (unsigned i = 0; i < count; ++i) {
     200                hid_dev->subdrivers[i] = *subdrivers[i];
    217201        }
    218202
     
    227211        return EOK;
    228212}
    229 
    230 /*----------------------------------------------------------------------------*/
    231 
     213/*----------------------------------------------------------------------------*/
    232214static int usb_hid_find_subdrivers(usb_hid_dev_t *hid_dev)
    233215{
     
    235217
    236218        const usb_hid_subdriver_t *subdrivers[USB_HID_MAX_SUBDRIVERS];
    237 
    238         int i = 0, count = 0;
    239         const usb_hid_subdriver_mapping_t *mapping = &usb_hid_subdrivers[i];
    240 
    241         bool ids_matched;
    242         bool matched;
    243 
    244         while (count < USB_HID_MAX_SUBDRIVERS &&
    245             (mapping->usage_path != NULL
    246             || mapping->vendor_id >= 0 || mapping->product_id >= 0)) {
    247                 // check the vendor & product ID
     219        unsigned count = 0;
     220
     221        for (unsigned i = 0; i < USB_HID_MAX_SUBDRIVERS; ++i) {
     222                const usb_hid_subdriver_mapping_t *mapping =
     223                    &usb_hid_subdrivers[i];
     224                /* Check the vendor & product ID. */
    248225                if (mapping->vendor_id >= 0 && mapping->product_id < 0) {
    249                         usb_log_warning("Missing Product ID for Vendor ID %d\n",
    250                             mapping->vendor_id);
    251                         return EINVAL;
     226                        usb_log_warning("Mapping[%d]: Missing Product ID for "
     227                            "Vendor ID %d\n", i, mapping->vendor_id);
    252228                }
    253229                if (mapping->product_id >= 0 && mapping->vendor_id < 0) {
    254                         usb_log_warning("Missing Vendor ID for Product ID %d\n",
    255                             mapping->product_id);
    256                         return EINVAL;
    257                 }
    258 
    259                 ids_matched = false;
    260                 matched = false;
    261 
    262                 if (mapping->vendor_id >= 0) {
    263                         assert(mapping->product_id >= 0);
     230                        usb_log_warning("Mapping[%d]: Missing Vendor ID for "
     231                            "Product ID %d\n", i, mapping->product_id);
     232                }
     233
     234                bool matched = false;
     235
     236                /* Check ID match. */
     237                if (mapping->vendor_id >= 0 && mapping->product_id >= 0) {
    264238                        usb_log_debug("Comparing device against vendor ID %u"
    265239                            " and product ID %u.\n", mapping->vendor_id,
     
    267241                        if (usb_hid_ids_match(hid_dev, mapping)) {
    268242                                usb_log_debug("IDs matched.\n");
    269                                 ids_matched = true;
     243                                matched = true;
    270244                        }
    271245                }
    272246
     247                /* Check usage match. */
    273248                if (mapping->usage_path != NULL) {
    274249                        usb_log_debug("Comparing device against usage path.\n");
    275250                        if (usb_hid_path_matches(hid_dev, mapping)) {
    276                                 // does not matter if IDs were matched
     251                                /* Does not matter if IDs were matched. */
    277252                                matched = true;
    278253                        }
    279                 } else {
    280                         // matched only if IDs were matched and there is no path
    281                         matched = ids_matched;
    282254                }
    283255
     
    286258                        subdrivers[count++] = &mapping->subdriver;
    287259                }
    288 
    289                 mapping = &usb_hid_subdrivers[++i];
    290260        }
    291261
    292262        /* We have all subdrivers determined, save them into the hid device */
    293         // TODO Dowe really need this complicated stuff if there is
    294         // max_subdrivers limitation?
    295263        return usb_hid_save_subdrivers(hid_dev, subdrivers, count);
    296264}
    297 
    298 /*----------------------------------------------------------------------------*/
    299 
     265/*----------------------------------------------------------------------------*/
    300266static int usb_hid_check_pipes(usb_hid_dev_t *hid_dev, const usb_device_t *dev)
    301267{
     
    303269        assert(dev);
    304270
    305         if (dev->pipes[USB_HID_KBD_POLL_EP_NO].present) {
    306                 usb_log_debug("Found keyboard endpoint.\n");
    307                 // save the pipe index
    308                 hid_dev->poll_pipe_index = USB_HID_KBD_POLL_EP_NO;
    309         } else if (dev->pipes[USB_HID_MOUSE_POLL_EP_NO].present) {
    310                 usb_log_debug("Found mouse endpoint.\n");
    311                 // save the pipe index
    312                 hid_dev->poll_pipe_index = USB_HID_MOUSE_POLL_EP_NO;
    313         } else if (dev->pipes[USB_HID_GENERIC_POLL_EP_NO].present) {
    314                 usb_log_debug("Found generic HID endpoint.\n");
    315                 // save the pipe index
    316                 hid_dev->poll_pipe_index = USB_HID_GENERIC_POLL_EP_NO;
    317         } else {
    318                 usb_log_error("None of supported endpoints found - probably"
    319                     " not a supported device.\n");
    320                 return ENOTSUP;
    321         }
    322 
    323         return EOK;
    324 }
    325 
    326 /*----------------------------------------------------------------------------*/
    327 
     271        static const struct {
     272                unsigned ep_number;
     273                const char* description;
     274        } endpoints[] = {
     275                {USB_HID_KBD_POLL_EP_NO, "Keyboard endpoint"},
     276                {USB_HID_MOUSE_POLL_EP_NO, "Mouse endpoint"},
     277                {USB_HID_GENERIC_POLL_EP_NO, "Generic HID endpoint"},
     278        };
     279
     280        for (unsigned i = 0; i < sizeof(endpoints)/sizeof(endpoints[0]); ++i) {
     281                if (endpoints[i].ep_number >= dev->pipes_count) {
     282                        return EINVAL;
     283                }
     284                if (dev->pipes[endpoints[i].ep_number].present) {
     285                        usb_log_debug("Found: %s.\n", endpoints[i].description);
     286                        hid_dev->poll_pipe_index = endpoints[i].ep_number;
     287                        return EOK;
     288                }
     289        }
     290        return ENOTSUP;
     291}
     292/*----------------------------------------------------------------------------*/
    328293static int usb_hid_init_report(usb_hid_dev_t *hid_dev)
    329294{
     
    357322        return EOK;
    358323}
    359 
    360 /*----------------------------------------------------------------------------*/
    361 
     324/*----------------------------------------------------------------------------*/
     325/*
     326 * This functions initializes required structures from the device's descriptors
     327 * and starts new fibril for polling the keyboard for events and another one for
     328 * handling auto-repeat of keys.
     329 *
     330 * During initialization, the keyboard is switched into boot protocol, the idle
     331 * rate is set to 0 (infinity), resulting in the keyboard only reporting event
     332 * when a key is pressed or released. Finally, the LED lights are turned on
     333 * according to the default setup of lock keys.
     334 *
     335 * @note By default, the keyboards is initialized with Num Lock turned on and
     336 *       other locks turned off.
     337 *
     338 * @param hid_dev Device to initialize, non-NULL.
     339 * @param dev USB device, non-NULL.
     340 * @return Error code.
     341 */
    362342int usb_hid_init(usb_hid_dev_t *hid_dev, usb_device_t *dev)
    363343{
    364         int rc, i;
     344        assert(hid_dev);
     345        assert(dev);
    365346
    366347        usb_log_debug("Initializing HID structure...\n");
    367 
    368         if (hid_dev == NULL) {
    369                 usb_log_error("Failed to init HID structure: no structure given"
    370                     ".\n");
    371                 return EINVAL;
    372         }
    373 
    374         if (dev == NULL) {
    375                 usb_log_error("Failed to init HID structure: no USB device"
    376                     " given.\n");
    377                 return EINVAL;
    378         }
    379348
    380349        usb_hid_report_init(&hid_dev->report);
     
    384353        hid_dev->poll_pipe_index = -1;
    385354
    386         rc = usb_hid_check_pipes(hid_dev, dev);
     355        int rc = usb_hid_check_pipes(hid_dev, dev);
    387356        if (rc != EOK) {
    388357                return rc;
     
    390359
    391360        /* Get the report descriptor and parse it. */
    392         rc = usb_hid_process_report_descriptor(hid_dev->usb_dev,
    393             &hid_dev->report, &hid_dev->report_desc, &hid_dev->report_desc_size);
    394 
    395         bool fallback = false;
    396 
     361        rc = usb_hid_process_report_descriptor(
     362            hid_dev->usb_dev, &hid_dev->report, &hid_dev->report_desc,
     363            &hid_dev->report_desc_size);
     364
     365        /* If report parsing went well, find subdrivers. */
    397366        if (rc == EOK) {
    398                 // try to find subdrivers that may want to handle this device
    399                 rc = usb_hid_find_subdrivers(hid_dev);
    400                 if (rc != EOK || hid_dev->subdriver_count == 0) {
    401                         // try to fall back to the boot protocol if available
    402                         usb_log_info("No subdrivers found to handle this"
    403                             " device.\n");
    404                         fallback = true;
    405                         assert(hid_dev->subdrivers == NULL);
    406                         assert(hid_dev->subdriver_count == 0);
    407                 }
     367                usb_hid_find_subdrivers(hid_dev);
    408368        } else {
    409                 usb_log_error("Failed to parse Report descriptor.\n");
    410                 // try to fall back to the boot protocol if available
    411                 fallback = true;
    412         }
    413 
    414         if (fallback) {
    415                 // fall back to boot protocol
     369                usb_log_error("Failed to parse report descriptor: fallback.\n");
     370                hid_dev->subdrivers = NULL;
     371                hid_dev->subdriver_count = 0;
     372        }
     373
     374        usb_log_debug("Subdriver count(before trying boot protocol): %d\n",
     375            hid_dev->subdriver_count);
     376
     377        /* No subdrivers, fall back to the boot protocol if available. */
     378        if (hid_dev->subdriver_count == 0) {
     379                assert(hid_dev->subdrivers == NULL);
     380                usb_log_info("No subdrivers found to handle device, trying "
     381                    "boot protocol.\n");
     382
    416383                switch (hid_dev->poll_pipe_index) {
    417384                case USB_HID_KBD_POLL_EP_NO:
     
    419386                        rc = usb_kbd_set_boot_protocol(hid_dev);
    420387                        if (rc == EOK) {
    421                                 rc = usb_hid_set_boot_kbd_subdriver(hid_dev);
     388                                usb_hid_set_boot_kbd_subdriver(hid_dev);
    422389                        }
    423390                        break;
     
    426393                        rc = usb_mouse_set_boot_protocol(hid_dev);
    427394                        if (rc == EOK) {
    428                                 rc = usb_hid_set_boot_mouse_subdriver(hid_dev);
     395                                usb_hid_set_boot_mouse_subdriver(hid_dev);
    429396                        }
    430397                        break;
     
    432399                        assert(hid_dev->poll_pipe_index
    433400                            == USB_HID_GENERIC_POLL_EP_NO);
    434 
    435401                        usb_log_info("Falling back to generic HID driver.\n");
    436                         rc = usb_hid_set_generic_hid_subdriver(hid_dev);
    437                 }
    438         }
    439 
    440         if (rc != EOK) {
    441                 usb_log_error("No subdriver for handling this device could be"
    442                     " initialized: %s.\n", str_error(rc));
    443                 usb_log_debug("Subdriver count: %d\n",
    444                     hid_dev->subdriver_count);
    445         } else {
    446                 bool ok = false;
    447 
    448                 usb_log_debug("Subdriver count: %d\n",
    449                     hid_dev->subdriver_count);
    450 
    451                 for (i = 0; i < hid_dev->subdriver_count; ++i) {
    452                         if (hid_dev->subdrivers[i].init != NULL) {
    453                                 usb_log_debug("Initializing subdriver %d.\n",i);
    454                                 rc = hid_dev->subdrivers[i].init(hid_dev,
    455                                     &hid_dev->subdrivers[i].data);
    456                                 if (rc != EOK) {
    457                                         usb_log_warning("Failed to initialize"
    458                                             " HID subdriver structure.\n");
    459                                 } else {
    460                                         // at least one subdriver initialized
    461                                         ok = true;
    462                                 }
     402                        usb_hid_set_generic_hid_subdriver(hid_dev);
     403                }
     404        }
     405
     406        usb_log_debug("Subdriver count(after trying boot protocol): %d\n",
     407            hid_dev->subdriver_count);
     408
     409        /* Still no subdrivers? */
     410        if (hid_dev->subdriver_count == 0) {
     411                assert(hid_dev->subdrivers == NULL);
     412                usb_log_error(
     413                    "No subdriver for handling this device could be found.\n");
     414                return ENOTSUP;
     415        }
     416
     417        /*
     418         * 1) subdriver vytvori vlastnu ddf_fun, vlastne ddf_dev_ops, ktore da
     419         *    do nej.
     420         * 2) do tych ops do .interfaces[DEV_IFACE_USBHID (asi)] priradi
     421         *    vyplnenu strukturu usbhid_iface_t.
     422         * 3) klientska aplikacia - musi si rucne vytvorit telefon
     423         *    (devman_device_connect() - cesta k zariadeniu (/hw/pci0/...) az
     424         *    k tej fcii.
     425         *    pouzit usb/classes/hid/iface.h - prvy int je telefon
     426         */
     427        bool ok = false;
     428        for (unsigned i = 0; i < hid_dev->subdriver_count; ++i) {
     429                if (hid_dev->subdrivers[i].init != NULL) {
     430                        usb_log_debug("Initializing subdriver %d.\n",i);
     431                        const int pret = hid_dev->subdrivers[i].init(hid_dev,
     432                            &hid_dev->subdrivers[i].data);
     433                        if (pret != EOK) {
     434                                usb_log_warning("Failed to initialize"
     435                                    " HID subdriver structure: %s.\n",
     436                                    str_error(pret));
     437                                rc = pret;
    463438                        } else {
     439                                /* At least one subdriver initialized. */
    464440                                ok = true;
    465441                        }
    466                 }
    467 
    468                 rc = (ok) ? EOK : -1;   // what error to report
    469         }
    470 
    471 
    472         if (rc == EOK) {
    473                 // save max input report size and allocate space for the report
     442                } else {
     443                        /* Does not need initialization. */
     444                        ok = true;
     445                }
     446        }
     447
     448        if (ok) {
     449                /* Save max input report size and
     450                 * allocate space for the report */
    474451                rc = usb_hid_init_report(hid_dev);
    475452                if (rc != EOK) {
     
    481458        return rc;
    482459}
    483 
    484 /*----------------------------------------------------------------------------*/
    485 
     460/*----------------------------------------------------------------------------*/
    486461bool usb_hid_polling_callback(usb_device_t *dev, uint8_t *buffer,
    487462    size_t buffer_size, void *arg)
     
    516491        bool cont = false;
    517492        /* Continue if at least one of the subdrivers want to continue */
    518         for (int i = 0; i < hid_dev->subdriver_count; ++i) {
     493        for (unsigned i = 0; i < hid_dev->subdriver_count; ++i) {
    519494                if (hid_dev->subdrivers[i].poll != NULL) {
    520495                        cont = cont || hid_dev->subdrivers[i].poll(
     
    525500        return cont;
    526501}
    527 
    528 /*----------------------------------------------------------------------------*/
    529 
     502/*----------------------------------------------------------------------------*/
    530503void usb_hid_polling_ended_callback(usb_device_t *dev, bool reason, void *arg)
    531504{
     
    535508        usb_hid_dev_t *hid_dev = arg;
    536509
    537         for (int i = 0; i < hid_dev->subdriver_count; ++i) {
     510        for (unsigned i = 0; i < hid_dev->subdriver_count; ++i) {
    538511                if (hid_dev->subdrivers[i].poll_end != NULL) {
    539512                        hid_dev->subdrivers[i].poll_end(
     
    544517        hid_dev->running = false;
    545518}
    546 
    547 /*----------------------------------------------------------------------------*/
    548 
     519/*----------------------------------------------------------------------------*/
    549520void usb_hid_new_report(usb_hid_dev_t *hid_dev)
    550521{
    551522        ++hid_dev->report_nr;
    552523}
    553 
    554 /*----------------------------------------------------------------------------*/
    555 
     524/*----------------------------------------------------------------------------*/
    556525int usb_hid_report_number(const usb_hid_dev_t *hid_dev)
    557526{
    558527        return hid_dev->report_nr;
    559528}
    560 
    561 /*----------------------------------------------------------------------------*/
    562 
     529/*----------------------------------------------------------------------------*/
    563530void usb_hid_deinit(usb_hid_dev_t *hid_dev)
    564531{
     
    570537            hid_dev->subdrivers, hid_dev->subdriver_count);
    571538
    572         for (int i = 0; i < hid_dev->subdriver_count; ++i) {
     539        for (unsigned i = 0; i < hid_dev->subdriver_count; ++i) {
    573540                if (hid_dev->subdrivers[i].deinit != NULL) {
    574541                        hid_dev->subdrivers[i].deinit(hid_dev,
  • uspace/drv/bus/usb/usbhid/usbhid.h

    r2e1b9dc r747ef72  
    104104
    105105        /** Index of the polling pipe in usb_hid_endpoints array. */
    106         int poll_pipe_index;
     106        unsigned poll_pipe_index;
    107107
    108108        /** Subdrivers. */
     
    110110
    111111        /** Number of subdrivers. */
    112         int subdriver_count;
     112        unsigned subdriver_count;
    113113
    114114        /** Report descriptor. */
  • uspace/drv/bus/usb/usbhub/port.c

    r2e1b9dc r747ef72  
    401401{
    402402        usb_hub_port_t *port = arg;
     403        assert(port);
    403404        const int rc =
    404405            usb_hub_port_set_feature(port, USB_HUB_FEATURE_PORT_RESET);
     
    440441            data->port, &new_address, NULL, NULL, &child_fun);
    441442
    442         if (rc != EOK) {
     443        if (rc == EOK) {
     444                fibril_mutex_lock(&data->port->mutex);
     445                data->port->attached_device.fun = child_fun;
     446                data->port->attached_device.address = new_address;
     447                fibril_mutex_unlock(&data->port->mutex);
     448
     449                usb_log_info("Detected new device on `%s' (port %zu), "
     450                    "address %d (handle %" PRIun ").\n",
     451                    data->hub->usb_device->ddf_dev->name,
     452                    data->port->port_number, new_address, child_fun->handle);
     453        } else {
    443454                usb_log_error("Failed registering device on port %zu: %s.\n",
    444455                    data->port->port_number, str_error(rc));
    445                 goto leave;
    446         }
    447 
    448         fibril_mutex_lock(&data->port->mutex);
    449         data->port->attached_device.fun = child_fun;
    450         data->port->attached_device.address = new_address;
    451         fibril_mutex_unlock(&data->port->mutex);
    452 
    453         usb_log_info("Detected new device on `%s' (port %zu), "
    454             "address %d (handle %" PRIun ").\n",
    455             data->hub->usb_device->ddf_dev->name, data->port->port_number,
    456             new_address, child_fun->handle);
    457 
    458 leave:
     456        }
     457
     458
    459459        fibril_mutex_lock(&data->hub->pending_ops_mutex);
    460460        assert(data->hub->pending_ops_count > 0);
  • uspace/drv/bus/usb/usbhub/port.h

    r2e1b9dc r747ef72  
    4444/** Information about single port on a hub. */
    4545typedef struct {
    46         /* Port number as reporteed in descriptors. */
     46        /* Port number as reported in descriptors. */
    4747        size_t port_number;
    4848        /** Device communication pipe. */
  • uspace/drv/bus/usb/usbhub/usbhub.c

    r2e1b9dc r747ef72  
    170170int usb_hub_device_remove(usb_device_t *usb_dev)
    171171{
    172         assert(usb_dev);
    173         usb_hub_dev_t *hub_dev = usb_dev->driver_data;
    174         assert(hub_dev);
    175         //TODO: Cascade the call here.
    176         //TODO: Enable after cascading is implemented.
    177172        return ENOTSUP;
    178         if (!hub_dev->power_switched) {
    179                 /* That is all we can do. */
    180                 return EOK;
    181         }
    182         int ret = EOK;
    183         usb_log_info("Hub is about to be removed, powering down all ports.\n");
    184         for (size_t port = 0; port < hub_dev->port_count; ++port) {
    185                 usb_log_debug("Powering down port %zu.\n", port);
    186                 int pret = usb_hub_port_clear_feature(
    187                     &hub_dev->ports[port], USB_HUB_FEATURE_PORT_POWER);
    188                 if (pret != EOK) {
    189                         usb_log_error("Cannot power down port %zu: %s.\n",
    190                             hub_dev->ports[port].port_number, str_error(pret));
    191                         ret = pret;
    192                 } else {
    193                         if (!hub_dev->per_port_power) {
    194                                 usb_log_debug("Ganged power switching mode, "
    195                                    "one port is enough.\n");
    196                                 break;
    197                         }
    198                 }
    199         }
    200         return ret;
    201173}
    202174/*----------------------------------------------------------------------------*/
  • uspace/drv/bus/usb/usbmast/bo_trans.c

    r2e1b9dc r747ef72  
    6767        int retval = EOK;
    6868        size_t act_size;
    69         usb_pipe_t *bulk_in_pipe = mfun->mdev->usb_dev->pipes[BULK_IN_EP].pipe;
    70         usb_pipe_t *bulk_out_pipe = mfun->mdev->usb_dev->pipes[BULK_OUT_EP].pipe;
     69        usb_pipe_t *bulk_in_pipe = &mfun->mdev->usb_dev->pipes[BULK_IN_EP].pipe;
     70        usb_pipe_t *bulk_out_pipe = &mfun->mdev->usb_dev->pipes[BULK_OUT_EP].pipe;
    7171        usb_direction_t ddir;
    7272        void *dbuf;
     
    118118                if (ddir == USB_DIRECTION_IN) {
    119119                        usb_pipe_clear_halt(&mfun->mdev->usb_dev->ctrl_pipe,
    120                             mfun->mdev->usb_dev->pipes[BULK_IN_EP].pipe);
     120                            &mfun->mdev->usb_dev->pipes[BULK_IN_EP].pipe);
    121121                } else {
    122122                        usb_pipe_clear_halt(&mfun->mdev->usb_dev->ctrl_pipe,
    123                             mfun->mdev->usb_dev->pipes[BULK_OUT_EP].pipe);
     123                            &mfun->mdev->usb_dev->pipes[BULK_OUT_EP].pipe);
    124124                }
    125125        } else if (rc != EOK) {
     
    216216        usb_massstor_reset(mdev);
    217217        usb_pipe_clear_halt(&mdev->usb_dev->ctrl_pipe,
    218             mdev->usb_dev->pipes[BULK_IN_EP].pipe);
     218            &mdev->usb_dev->pipes[BULK_IN_EP].pipe);
    219219        usb_pipe_clear_halt(&mdev->usb_dev->ctrl_pipe,
    220             mdev->usb_dev->pipes[BULK_OUT_EP].pipe);
     220            &mdev->usb_dev->pipes[BULK_OUT_EP].pipe);
    221221}
    222222
  • uspace/drv/bus/usb/usbmast/main.c

    r2e1b9dc r747ef72  
    114114{
    115115        //TODO: flush buffers, or whatever.
     116        //TODO: remove device
    116117        return ENOTSUP;
    117118}
     
    139140
    140141        usb_log_info("Initializing mass storage `%s'.\n", dev->ddf_dev->name);
    141         usb_log_debug(" Bulk in endpoint: %d [%zuB].\n",
    142             dev->pipes[BULK_IN_EP].pipe->endpoint_no,
    143             (size_t) dev->pipes[BULK_IN_EP].descriptor->max_packet_size);
     142        usb_log_debug("Bulk in endpoint: %d [%zuB].\n",
     143            dev->pipes[BULK_IN_EP].pipe.endpoint_no,
     144            dev->pipes[BULK_IN_EP].pipe.max_packet_size);
    144145        usb_log_debug("Bulk out endpoint: %d [%zuB].\n",
    145             dev->pipes[BULK_OUT_EP].pipe->endpoint_no,
    146             (size_t) dev->pipes[BULK_OUT_EP].descriptor->max_packet_size);
     146            dev->pipes[BULK_OUT_EP].pipe.endpoint_no,
     147            dev->pipes[BULK_OUT_EP].pipe.max_packet_size);
    147148
    148149        usb_log_debug("Get LUN count...\n");
  • uspace/drv/bus/usb/usbmid/explore.c

    r2e1b9dc r747ef72  
    5757{
    5858        list_foreach(*list, l) {
    59                 usbmid_interface_t *iface
    60                     = list_get_instance(l, usbmid_interface_t, link);
     59                usbmid_interface_t *iface = usbmid_interface_from_link(l);
    6160                if (iface->interface_no == interface_no) {
    6261                        return true;
     
    8281        };
    8382
    84         usb_dp_parser_t parser = {
     83        static const usb_dp_parser_t parser = {
    8584                .nesting = usb_dp_standard_descriptor_nesting
    8685        };
    8786
    8887        const uint8_t *interface_ptr =
    89             usb_dp_get_nested_descriptor(&parser, &data, data.data);
    90         if (interface_ptr == NULL) {
    91                 return;
    92         }
    93 
    94         do {
    95                 if (interface_ptr[1] != USB_DESCTYPE_INTERFACE) {
    96                         goto next_descriptor;
    97                 }
    98 
    99                 usb_standard_interface_descriptor_t *interface
     88            usb_dp_get_nested_descriptor(&parser, &data, config_descriptor);
     89
     90        /* Walk all descriptors nested in the current configuration decriptor;
     91         * i.e. all interface descriptors. */
     92        for (;interface_ptr != NULL;
     93            interface_ptr = usb_dp_get_sibling_descriptor(
     94                &parser, &data, config_descriptor, interface_ptr))
     95        {
     96                /* The second byte is DESCTYPE byte in all desriptors. */
     97                if (interface_ptr[1] != USB_DESCTYPE_INTERFACE)
     98                        continue;
     99
     100                const usb_standard_interface_descriptor_t *interface
    100101                    = (usb_standard_interface_descriptor_t *) interface_ptr;
    101102
    102103                /* Skip alternate interfaces. */
    103                 if (!interface_in_list(list, interface->interface_number)) {
    104                         usbmid_interface_t *iface
    105                             = malloc(sizeof(usbmid_interface_t));
    106                         if (iface == NULL) {
    107                                 break;
    108                         }
    109                         link_initialize(&iface->link);
    110                         iface->fun = NULL;
    111                         iface->interface_no = interface->interface_number;
    112                         iface->interface = interface;
    113 
    114                         list_append(&iface->link, list);
    115                 }
    116 
    117                 /* TODO: add the alternatives and create match ids from them
    118                  * as well.
    119                  */
    120 
    121 next_descriptor:
    122                 interface_ptr = usb_dp_get_sibling_descriptor(&parser, &data,
    123                     data.data, interface_ptr);
    124 
    125         } while (interface_ptr != NULL);
    126 
     104                if (interface_in_list(list, interface->interface_number)) {
     105                        /* TODO: add the alternatives and create match ids
     106                         * for them. */
     107                        continue;
     108                }
     109                usbmid_interface_t *iface = malloc(sizeof(usbmid_interface_t));
     110                if (iface == NULL) {
     111                        //TODO: Do something about that failure.
     112                        break;
     113                }
     114
     115                link_initialize(&iface->link);
     116                iface->fun = NULL;
     117                iface->interface_no = interface->interface_number;
     118                iface->interface = interface;
     119
     120                list_append(&iface->link, list);
     121        }
    127122}
    128123
     
    139134        int rc;
    140135
    141         int dev_class = dev->descriptors.device.device_class;
     136        unsigned dev_class = dev->descriptors.device.device_class;
    142137        if (dev_class != USB_CLASS_USE_INTERFACE) {
    143138                usb_log_warning(
    144                     "Device class: %d (%s), but expected class 0.\n",
    145                     dev_class, usb_str_class(dev_class));
     139                    "Device class: %u (%s), but expected class %u.\n",
     140                    dev_class, usb_str_class(dev_class),
     141                    USB_CLASS_USE_INTERFACE);
    146142                usb_log_error("Not multi interface device, refusing.\n");
    147143                return false;
    148144        }
    149145
    150         /* Short cuts to save on typing ;-). */
     146        /* Shortcuts to save on typing ;-). */
    151147        const void *config_descriptor_raw = dev->descriptors.configuration;
    152148        size_t config_descriptor_size = dev->descriptors.configuration_size;
     
    163159        }
    164160
     161        /* Create driver soft-state. */
    165162        usb_mid_t *usb_mid = usb_device_data_alloc(dev, sizeof(usb_mid_t));
    166163        if (!usb_mid) {
     
    169166        }
    170167
    171         /* Create control function */
     168        /* Create control function. */
    172169        usb_mid->ctl_fun = ddf_fun_create(dev->ddf_dev, fun_exposed, "ctl");
    173170        if (usb_mid->ctl_fun == NULL) {
     
    175172                return false;
    176173        }
    177 
    178174        usb_mid->ctl_fun->ops = &mid_device_ops;
    179175
     176        /* Bind control function. */
    180177        rc = ddf_fun_bind(usb_mid->ctl_fun);
    181178        if (rc != EOK) {
     
    192189            &usb_mid->interface_list);
    193190
     191        /* Start child function for every interface. */
    194192        list_foreach(usb_mid->interface_list, link) {
    195                 usbmid_interface_t *iface = list_get_instance(link,
    196                     usbmid_interface_t, link);
     193                usbmid_interface_t *iface = usbmid_interface_from_link(link);
    197194
    198195                usb_log_info("Creating child for interface %d (%s).\n",
    199                     (int) iface->interface_no,
     196                    iface->interface_no,
    200197                    usb_str_class(iface->interface->interface_class));
    201198
  • uspace/drv/bus/usb/usbmid/main.c

    r2e1b9dc r747ef72  
    6868/** Callback when a MID device is about to be removed from the host.
    6969 *
    70  * @param gen_dev Generic DDF device representing the removed device.
     70 * @param dev USB device representing the removed device.
    7171 * @return Error code.
    7272 */
     
    7474{
    7575        assert(dev);
    76         int ret = ENOTSUP;
    7776        usb_mid_t *usb_mid = dev->driver_data;
    7877        assert(usb_mid);
    7978
    80         /* Signal all interface functions */
    81         list_foreach(usb_mid->interface_list, item) {
     79        /* Remove ctl function */
     80        int ret = ddf_fun_unbind(usb_mid->ctl_fun);
     81        if (ret != EOK) {
     82                usb_log_error("Failed to unbind USB MID ctl function: %s.\n",
     83                    str_error(ret));
     84                return ret;
     85        }
     86        ddf_fun_destroy(usb_mid->ctl_fun);
     87
     88        /* Remove all children */
     89        while (!list_empty(&usb_mid->interface_list)) {
     90                link_t *item = list_first(&usb_mid->interface_list);
     91                list_remove(item);
     92
    8293                usbmid_interface_t *iface = usbmid_interface_from_link(item);
    8394
    84                 usb_log_info("Signaling remove to child for interface "
    85                     "%d (%s).\n", iface->interface_no,
     95                usb_log_info("Removing child for interface %d (%s).\n",
     96                    iface->interface_no,
    8697                    usb_str_class(iface->interface->interface_class));
    87                 // TODO cascade the call.
     98
     99                /* Tell the child to go off-line. */
     100                int pret = ddf_fun_offline(iface->fun);
     101                if (pret != EOK) {
     102                        usb_log_warning("Failed to turn off child for interface"
     103                            " %d (%s): %s\n", iface->interface_no,
     104                            usb_str_class(iface->interface->interface_class),
     105                            str_error(pret));
     106                        ret = pret;
     107                }
     108
     109                /* Now remove the child. */
     110                pret = usbmid_interface_destroy(iface);
     111                if (pret != EOK) {
     112                        usb_log_error("Failed to destroy child for interface "
     113                            "%d (%s): %s\n", iface->interface_no,
     114                            usb_str_class(iface->interface->interface_class),
     115                            str_error(pret));
     116                        ret = pret;
     117                }
    88118        }
    89119        return ret;
     
    92122/** Callback when a MID device was removed from the host.
    93123 *
    94  * @param gen_dev Generic DDF device representing the removed device.
     124 * @param dev USB device representing the removed device.
    95125 * @return Error code.
    96126 */
     
    98128{
    99129        assert(dev);
     130        usb_mid_t *usb_mid = dev->driver_data;
     131        assert(usb_mid);
     132
    100133        usb_log_info("USB MID gone: `%s'.\n", dev->ddf_dev->name);
    101134
    102135        /* Remove ctl function */
    103         usb_mid_t *usb_mid = dev->driver_data;
    104136        int ret = ddf_fun_unbind(usb_mid->ctl_fun);
    105137        if (ret != EOK) {
     
    117149                usbmid_interface_t *iface = usbmid_interface_from_link(item);
    118150
    119                 usb_log_info("Removing child for interface %d (%s).\n",
     151                usb_log_info("Child for interface %d (%s) gone.\n",
    120152                    iface->interface_no,
    121153                    usb_str_class(iface->interface->interface_class));
  • uspace/drv/bus/usb/usbmid/usbmid.c

    r2e1b9dc r747ef72  
    6262/** DDF interface of the child - interface function. */
    6363static usb_iface_t child_usb_iface = {
    64         .get_hc_handle = usb_iface_get_hc_handle_hub_child_impl,
    65         .get_address = usb_iface_get_address_hub_impl,
    66         .get_interface = usb_iface_get_interface_impl
     64        .get_hc_handle = usb_iface_get_hc_handle_device_impl,
     65        .get_my_address = usb_iface_get_my_address_forward_impl,
     66        .get_interface = usb_iface_get_interface_impl,
    6767};
    6868
     
    110110         * class name something humanly understandable.
    111111         */
    112         rc = asprintf(&child_name, "%s%d",
     112        rc = asprintf(&child_name, "%s%hhu",
    113113            usb_str_class(interface_descriptor->interface_class),
    114             (int) interface_descriptor->interface_number);
     114            interface_descriptor->interface_number);
    115115        if (rc < 0) {
    116116                return ENOMEM;
     
    123123                return ENOMEM;
    124124        }
    125 
    126         iface->fun = child;
    127 
    128         child->driver_data = iface;
    129         child->ops = &child_device_ops;
    130125
    131126        rc = usb_device_create_match_ids_from_interface(device_descriptor,
     
    143138        }
    144139
     140        iface->fun = child;
     141        child->driver_data = iface;
     142        child->ops = &child_device_ops;
     143
    145144        return EOK;
    146145}
  • uspace/drv/bus/usb/usbmid/usbmid.h

    r2e1b9dc r747ef72  
    5151        ddf_fun_t *fun;
    5252        /** Interface descriptor. */
    53         usb_standard_interface_descriptor_t *interface;
     53        const usb_standard_interface_descriptor_t *interface;
    5454        /** Interface number. */
    5555        int interface_no;
  • uspace/drv/bus/usb/vhc/connhost.c

    r2e1b9dc r747ef72  
    5757 * @return Error code.
    5858 */
    59 static int request_address(ddf_fun_t *fun, usb_speed_t speed,
    60     usb_address_t *address)
    61 {
    62         VHC_DATA(vhc, fun);
    63 
    64         usb_address_t addr = usb_device_manager_get_free_address(
    65             &vhc->dev_manager, USB_SPEED_HIGH);
    66         if (addr < 0) {
    67                 return addr;
    68         }
    69 
    70         if (address != NULL) {
    71                 *address = addr;
    72         }
    73 
    74         return EOK;
     59static int request_address(ddf_fun_t *fun, usb_address_t *address, bool strict,
     60    usb_speed_t speed)
     61{
     62        VHC_DATA(vhc, fun);
     63
     64        assert(address);
     65        return usb_device_manager_request_address(
     66            &vhc->dev_manager, address, strict, speed);
    7567}
    7668
     
    8880        usb_log_debug("Binding handle %" PRIun " to address %d.\n",
    8981            handle, address);
    90         usb_device_manager_bind(&vhc->dev_manager, address, handle);
     82        usb_device_manager_bind_address(&vhc->dev_manager, address, handle);
    9183
    9284        return EOK;
     
    118110        VHC_DATA(vhc, fun);
    119111        usb_log_debug("Releasing address %d...\n", address);
    120         usb_device_manager_release(&vhc->dev_manager, address);
     112        usb_device_manager_release_address(&vhc->dev_manager, address);
    121113
    122114        return ENOTSUP;
     
    136128 */
    137129static int register_endpoint(ddf_fun_t *fun,
    138     usb_address_t address, usb_speed_t speed, usb_endpoint_t endpoint,
     130    usb_address_t address, usb_endpoint_t endpoint,
    139131    usb_transfer_type_t transfer_type, usb_direction_t direction,
    140132    size_t max_packet_size, unsigned int interval)
     
    479471}
    480472
    481 static int tell_address(ddf_fun_t *fun, devman_handle_t handle,
    482     usb_address_t *address)
     473static int tell_address(ddf_fun_t *fun, usb_address_t *address)
    483474{
    484475        UNSUPPORTED("tell_address");
     
    497488}
    498489
    499 static int tell_address_rh(ddf_fun_t *root_hub_fun, devman_handle_t handle,
    500     usb_address_t *address)
     490static int tell_address_rh(ddf_fun_t *root_hub_fun, usb_address_t *address)
    501491{
    502492        VHC_DATA(vhc, root_hub_fun);
    503493
    504         if (handle == 0) {
    505                 handle = root_hub_fun->handle;
    506         }
     494        devman_handle_t handle = root_hub_fun->handle;
    507495
    508496        usb_log_debug("tell_address_rh(handle=%" PRIun ")\n", handle);
     
    532520usb_iface_t vhc_usb_iface = {
    533521        .get_hc_handle = usb_iface_get_hc_handle_hc_impl,
    534         .get_address = tell_address
     522        .get_my_address = tell_address
    535523};
    536524
    537525usb_iface_t rh_usb_iface = {
    538526        .get_hc_handle = usb_iface_get_hc_handle_rh_impl,
    539         .get_address = tell_address_rh
     527        .get_my_address = tell_address_rh
    540528};
    541529
  • uspace/drv/bus/usb/vhc/main.c

    r2e1b9dc r747ef72  
    8080                return rc;
    8181        }
    82         usb_device_manager_init(&data->dev_manager);
     82        usb_device_manager_init(&data->dev_manager, USB_SPEED_MAX);
    8383
    8484        ddf_fun_t *hc = ddf_fun_create(dev, fun_exposed, "hc");
Note: See TracChangeset for help on using the changeset viewer.