Changeset 970f6e1 in mainline


Ignore:
Timestamp:
2018-01-09T18:25:56Z (6 years ago)
Author:
Petr Manek <petr.manek@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
4793023
Parents:
c386d6d
Message:

usbhid: join polling fibrils in device_remove()

Location:
uspace/drv/hid/usbhid
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • uspace/drv/hid/usbhid/generic/hiddev.c

    rc386d6d r970f6e1  
    219219bool usb_generic_hid_polling_callback(usb_hid_dev_t *hid_dev, void *data)
    220220{
    221         return true;
     221        /* Continue polling until the device is about to be removed. */
     222        return !hid_dev->will_deinit;
    222223}
    223224
  • uspace/drv/hid/usbhid/main.c

    rc386d6d r970f6e1  
    4040#include <errno.h>
    4141#include <str_error.h>
     42#include <fibril_synch.h>
    4243
    4344#include <usb/dev/driver.h>
     
    9899           /* Delay */
    99100           -1,
     101           /* Callback when the polling fails. */
     102           usb_hid_polling_error_callback,
    100103           /* Callback when the polling ends. */
    101104           usb_hid_polling_ended_callback,
     
    128131        assert(hid_dev);
    129132
    130         /* TODO: Stop device polling prior to deinit. Now it fails on endpoint error. */
    131 
     133        usb_log_debug2("%s will be removed, setting remove flag.\n", usb_device_get_name(dev));
     134        usb_hid_prepare_deinit(hid_dev);
     135
     136        return EOK;
     137}
     138
     139/**
     140 * Callback for when a device has just been from the driver.
     141 *
     142 * @param dev Structure representing the device.
     143 * @return Error code.
     144 */
     145static int usb_hid_device_removed(usb_device_t *dev)
     146{
     147        assert(dev);
     148        usb_hid_dev_t *hid_dev = usb_device_data_get(dev);
     149        assert(hid_dev);
     150
     151        /* Join polling fibril. */
     152        fibril_mutex_lock(&hid_dev->guard);
     153        while (hid_dev->running)
     154                fibril_condvar_wait(&hid_dev->poll_end, &hid_dev->guard);
     155        fibril_mutex_unlock(&hid_dev->guard);
     156
     157        /* Clean up. */
    132158        usb_hid_deinit(hid_dev);
    133159        usb_log_debug2("%s destruction complete.\n", usb_device_get_name(dev));
     160
    134161        return EOK;
    135162}
     
    165192        .device_add = usb_hid_device_add,
    166193        .device_remove = usb_hid_device_remove,
     194        .device_removed = usb_hid_device_removed,
    167195        .device_gone = usb_hid_device_gone,
    168196};
  • uspace/drv/hid/usbhid/mouse/mousedev.c

    rc386d6d r970f6e1  
    165165}
    166166
    167 static bool usb_mouse_process_report(usb_hid_dev_t *hid_dev,
     167static void usb_mouse_process_report(usb_hid_dev_t *hid_dev,
    168168    usb_mouse_t *mouse_dev)
    169169{
     
    172172        if (mouse_dev->mouse_sess == NULL) {
    173173                usb_log_warning(NAME " No console session.\n");
    174                 return true;
     174                return;
    175175        }
    176176
     
    191191        if (absolute_x != absolute_y) {
    192192                usb_log_error(NAME " cannot handle mix of absolute and relative mouse move.");
    193                 return true;
     193                return;
    194194        }
    195195
     
    226226        if (path == NULL) {
    227227                usb_log_warning("Failed to create USB HID report path.\n");
    228                 return true;
     228                return;
    229229        }
    230230        int ret =
     
    233233                usb_hid_report_path_free(path);
    234234                usb_log_warning("Failed to add buttons to report path.\n");
    235                 return true;
     235                return;
    236236        }
    237237        usb_hid_report_path_set_report_id(path, hid_dev->report_id);
     
    266266
    267267        usb_hid_report_path_free(path);
    268 
    269         return true;
    270268}
    271269
     
    414412
    415413        usb_mouse_t *mouse_dev = data;
    416 
    417         return usb_mouse_process_report(hid_dev, mouse_dev);
     414        usb_mouse_process_report(hid_dev, mouse_dev);
     415
     416        /* Continue polling until the device is about to be removed. */
     417        return !hid_dev->will_deinit;
    418418}
    419419
  • uspace/drv/hid/usbhid/usbhid.c

    rc386d6d r970f6e1  
    332332 * During initialization, the keyboard is switched into boot protocol, the idle
    333333 * rate is set to 0 (infinity), resulting in the keyboard only reporting event
    334  * when a key is pressed or released. Finally, the LED lights are turned on 
     334 * when a key is pressed or released. Finally, the LED lights are turned on
    335335 * according to the default setup of lock keys.
    336336 *
    337  * @note By default, the keyboards is initialized with Num Lock turned on and 
     337 * @note By default, the keyboards is initialized with Num Lock turned on and
    338338 *       other locks turned off.
    339339 *
     
    354354        hid_dev->usb_dev = dev;
    355355        hid_dev->poll_pipe_mapping = NULL;
     356
     357        hid_dev->will_deinit = false;
     358        fibril_mutex_initialize(&hid_dev->guard);
     359        fibril_condvar_initialize(&hid_dev->poll_end);
    356360
    357361        int rc = usb_hid_check_pipes(hid_dev, dev);
     
    492496}
    493497
     498bool usb_hid_polling_error_callback(usb_device_t *dev, int err_code, void *arg)
     499{
     500        assert(dev);
     501        assert(arg);
     502        usb_hid_dev_t *hid_dev = arg;
     503
     504        usb_log_error("Device %s polling error: %s", usb_device_get_name(dev),
     505            str_error(err_code));
     506
     507        /* Continue polling until the device is about to be removed. */
     508        return hid_dev->running && !hid_dev->will_deinit;
     509}
     510
    494511void usb_hid_polling_ended_callback(usb_device_t *dev, bool reason, void *arg)
    495512{
     
    507524
    508525        hid_dev->running = false;
     526
     527        /* Signal polling end to joining thread. */
     528        fibril_mutex_lock(&hid_dev->guard);
     529        fibril_condvar_signal(&hid_dev->poll_end);
     530        fibril_mutex_unlock(&hid_dev->guard);
    509531}
    510532
     
    517539{
    518540        return hid_dev->report_nr;
     541}
     542
     543void usb_hid_prepare_deinit(usb_hid_dev_t *hid_dev)
     544{
     545        assert(hid_dev);
     546        hid_dev->will_deinit = true;
    519547}
    520548
     
    524552        assert(hid_dev->subdrivers != NULL || hid_dev->subdriver_count == 0);
    525553
    526 
    527         usb_log_debug("Subdrivers: %p, subdriver count: %d\n",
     554        usb_log_debug("Subdrivers: %p, subdriver count: %d\n",
    528555            hid_dev->subdrivers, hid_dev->subdriver_count);
    529556
     
    541568        /* Destroy the parser */
    542569        usb_hid_report_deinit(&hid_dev->report);
    543 
    544570}
    545571
  • uspace/drv/hid/usbhid/usbhid.h

    rc386d6d r970f6e1  
    4545#include <usb/hid/hid.h>
    4646#include <stdbool.h>
     47#include <fibril_synch.h>
    4748
    4849typedef struct usb_hid_dev usb_hid_dev_t;
     
    130131        int report_nr;
    131132        volatile bool running;
     133
     134        volatile bool will_deinit;
     135        fibril_mutex_t guard;
     136        fibril_condvar_t poll_end;
    132137};
    133138
     
    136141int usb_hid_init(usb_hid_dev_t *hid_dev, usb_device_t *dev);
    137142
     143void usb_hid_prepare_deinit(usb_hid_dev_t *hid_dev);
     144
    138145void usb_hid_deinit(usb_hid_dev_t *hid_dev);
    139146
    140147bool usb_hid_polling_callback(usb_device_t *dev,
    141148    uint8_t *buffer, size_t buffer_size, void *arg);
     149
     150bool usb_hid_polling_error_callback(usb_device_t *dev, int err_code, void *arg);
    142151
    143152void usb_hid_polling_ended_callback(usb_device_t *dev, bool reason, void *arg);
Note: See TracChangeset for help on using the changeset viewer.