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


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

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

Not tested thoroughly yet.

File:
1 edited

Legend:

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

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