Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/drv/bus/usb/usbhid/main.c

    r5f6e25e r90df90c  
    4646#include "usbhid.h"
    4747
    48 /*----------------------------------------------------------------------------*/
    49 
    5048#define NAME "usbhid"
    5149
    5250/**
    53  * Function for adding a new device of type USB/HID/keyboard.
     51 * Callback for passing a new device to the driver.
    5452 *
    55  * This functions initializes required structures from the device's descriptors
    56  * and starts new fibril for polling the keyboard for events and another one for
    57  * handling auto-repeat of keys.
     53 * @note Currently, only boot-protocol keyboards are supported by this driver.
    5854 *
    59  * During initialization, the keyboard is switched into boot protocol, the idle
    60  * rate is set to 0 (infinity), resulting in the keyboard only reporting event
    61  * when a key is pressed or released. Finally, the LED lights are turned on
    62  * according to the default setup of lock keys.
    63  *
    64  * @note By default, the keyboards is initialized with Num Lock turned on and
    65  *       other locks turned off.
    66  * @note Currently supports only boot-protocol keyboards.
    67  *
    68  * @param dev Device to add.
    69  *
    70  * @retval EOK if successful.
    71  * @retval ENOMEM if there
    72  * @return Other error code inherited from one of functions usb_kbd_init(),
    73  *         ddf_fun_bind() and ddf_fun_add_to_class().
     55 * @param dev Structure representing the new device.
     56 * @return Error code.
    7457 */
    75 static int usb_hid_try_add_device(usb_device_t *dev)
     58static int usb_hid_device_add(usb_device_t *dev)
    7659{
    77         assert(dev != NULL);
    78        
    79         /*
    80          * Initialize device (get and process descriptors, get address, etc.)
    81          */
    82         usb_log_debug("Initializing USB/HID device...\n");
    83        
    84         usb_hid_dev_t *hid_dev = usb_hid_new();
     60        usb_log_debug("%s\n", __FUNCTION__);
     61
     62        if (dev == NULL) {
     63                usb_log_error("Wrong parameter given for add_device().\n");
     64                return EINVAL;
     65        }
     66
     67        if (dev->interface_no < 0) {
     68                usb_log_error("Failed to add HID device: endpoints not found."
     69                    "\n");
     70                return ENOTSUP;
     71        }
     72        usb_hid_dev_t *hid_dev =
     73            usb_device_data_alloc(dev, sizeof(usb_hid_dev_t));
    8574        if (hid_dev == NULL) {
    86                 usb_log_error("Error while creating USB/HID device "
    87                     "structure.\n");
     75                usb_log_error("Failed to create USB/HID device structure.\n");
    8876                return ENOMEM;
    8977        }
    90        
     78
    9179        int rc = usb_hid_init(hid_dev, dev);
    92        
    9380        if (rc != EOK) {
    9481                usb_log_error("Failed to initialize USB/HID device.\n");
    95                 usb_hid_destroy(hid_dev);
     82                usb_hid_deinit(hid_dev);
    9683                return rc;
    97         }       
    98        
     84        }
     85
    9986        usb_log_debug("USB/HID device structure initialized.\n");
    100        
    101         /*
    102          * 1) subdriver vytvori vlastnu ddf_fun, vlastne ddf_dev_ops, ktore da
    103          *    do nej.
    104          * 2) do tych ops do .interfaces[DEV_IFACE_USBHID (asi)] priradi
    105          *    vyplnenu strukturu usbhid_iface_t.
    106          * 3) klientska aplikacia - musi si rucne vytvorit telefon
    107          *    (devman_device_connect() - cesta k zariadeniu (/hw/pci0/...) az
    108          *    k tej fcii.
    109          *    pouzit usb/classes/hid/iface.h - prvy int je telefon
    110          */
    111        
     87
    11288        /* Start automated polling function.
    11389         * This will create a separate fibril that will query the device
    114          * for the data continuously
    115          */
     90         * for the data continuously. */
    11691       rc = usb_device_auto_poll(dev,
    11792           /* Index of the polling pipe. */
     
    12095           usb_hid_polling_callback,
    12196           /* How much data to request. */
    122            dev->pipes[hid_dev->poll_pipe_index].pipe->max_packet_size,
     97           dev->pipes[hid_dev->poll_pipe_index].pipe.max_packet_size,
    12398           /* Callback when the polling ends. */
    12499           usb_hid_polling_ended_callback,
    125100           /* Custom argument. */
    126101           hid_dev);
    127        
    128        
     102
    129103        if (rc != EOK) {
    130104                usb_log_error("Failed to start polling fibril for `%s'.\n",
    131105                    dev->ddf_dev->name);
     106                usb_hid_deinit(hid_dev);
    132107                return rc;
    133108        }
     109        hid_dev->running = true;
    134110
    135         /*
    136          * Hurrah, device is initialized.
    137          */
    138         return EOK;
    139 }
    140 
    141 /*----------------------------------------------------------------------------*/
    142 /**
    143  * Callback for passing a new device to the driver.
    144  *
    145  * @note Currently, only boot-protocol keyboards are supported by this driver.
    146  *
    147  * @param dev Structure representing the new device.
    148  *
    149  * @retval EOK if successful.
    150  * @retval EREFUSED if the device is not supported.
    151  */
    152 static int usb_hid_add_device(usb_device_t *dev)
    153 {
    154         usb_log_debug("usb_hid_add_device()\n");
    155        
    156         if (dev == NULL) {
    157                 usb_log_warning("Wrong parameter given for add_device().\n");
    158                 return EINVAL;
    159         }
    160        
    161         if (dev->interface_no < 0) {
    162                 usb_log_warning("Device is not a supported HID device.\n");
    163                 usb_log_error("Failed to add HID device: endpoints not found."
    164                     "\n");
    165                 return ENOTSUP;
    166         }
    167        
    168         int rc = usb_hid_try_add_device(dev);
    169        
    170         if (rc != EOK) {
    171                 usb_log_warning("Device is not a supported HID device.\n");
    172                 usb_log_error("Failed to add HID device: %s.\n",
    173                     str_error(rc));
    174                 return rc;
    175         }
    176        
    177111        usb_log_info("HID device `%s' ready to use.\n", dev->ddf_dev->name);
    178112
    179113        return EOK;
    180114}
     115/*----------------------------------------------------------------------------*/
     116/**
     117 * Callback for a device about to be removed from the driver.
     118 *
     119 * @param dev Structure representing the device.
     120 * @return Error code.
     121 */
     122static int usb_hid_device_rem(usb_device_t *dev)
     123{
     124        // TODO: Stop device polling
     125        // TODO: Call deinit (stops autorepeat too)
     126        return ENOTSUP;
     127}
     128/*----------------------------------------------------------------------------*/
     129/**
     130 * Callback for removing a device from the driver.
     131 *
     132 * @param dev Structure representing the device.
     133 * @return Error code.
     134 */
     135static int usb_hid_device_gone(usb_device_t *dev)
     136{
     137        assert(dev);
     138        assert(dev->driver_data);
     139        usb_hid_dev_t *hid_dev = dev->driver_data;
     140        unsigned tries = 100;
     141        /* Wait for fail. */
     142        while (hid_dev->running && tries--) {
     143                async_usleep(100000);
     144        }
     145        if (hid_dev->running) {
     146                usb_log_error("Can't remove hid, still running.\n");
     147                return EBUSY;
     148        }
    181149
     150        usb_hid_deinit(hid_dev);
     151        usb_log_debug2("%s destruction complete.\n", dev->ddf_dev->name);
     152        return EOK;
     153}
    182154/*----------------------------------------------------------------------------*/
    183 
    184 /* Currently, the framework supports only device adding. Once the framework
    185  * supports unplug, more callbacks will be added. */
    186 static usb_driver_ops_t usb_hid_driver_ops = {
    187         .add_device = usb_hid_add_device,
     155/** USB generic driver callbacks */
     156static const usb_driver_ops_t usb_hid_driver_ops = {
     157        .device_add = usb_hid_device_add,
     158        .device_rem = usb_hid_device_rem,
     159        .device_gone = usb_hid_device_gone,
    188160};
    189 
    190 
    191 /* The driver itself. */
    192 static usb_driver_t usb_hid_driver = {
     161/*----------------------------------------------------------------------------*/
     162/** The driver itself. */
     163static const usb_driver_t usb_hid_driver = {
    193164        .name = NAME,
    194165        .ops = &usb_hid_driver_ops,
    195166        .endpoints = usb_hid_endpoints
    196167};
    197 
    198168/*----------------------------------------------------------------------------*/
    199 
    200169int main(int argc, char *argv[])
    201170{
     
    206175        return usb_driver_main(&usb_hid_driver);
    207176}
    208 
    209177/**
    210178 * @}
Note: See TracChangeset for help on using the changeset viewer.