Changeset deb4ba7 in mainline


Ignore:
Timestamp:
2011-03-13T21:39:46Z (13 years ago)
Author:
Vojtech Horky <vojtechhorky@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
1b0b86e6, 92b41f33
Parents:
335382d (diff), adfe5ec (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:

Initial work on USB device driver framework

See messages in individual commits and discussion on
https://sourceforge.net/apps/trac/helenos-usb/ticket/85
for more details.

Only the mouse driver uses this framework.

Location:
uspace
Files:
3 added
6 edited

Legend:

Unmodified
Added
Removed
  • uspace/drv/usbmouse/init.c

    r335382d rdeb4ba7  
    4242
    4343/** Mouse polling endpoint description for boot protocol subclass. */
    44 static usb_endpoint_description_t poll_endpoint_description = {
     44usb_endpoint_description_t poll_endpoint_description = {
    4545        .transfer_type = USB_TRANSFER_INTERRUPT,
    4646        .direction = USB_DIRECTION_IN,
     
    5050        .flags = 0
    5151};
    52 
    53 /** Initialize poll pipe.
    54  *
    55  * Expects that session is already started on control pipe zero.
    56  *
    57  * @param mouse Mouse device.
    58  * @param my_interface Interface number.
    59  * @return Error code.
    60  */
    61 static int intialize_poll_pipe(usb_mouse_t *mouse, int my_interface)
    62 {
    63         assert(usb_endpoint_pipe_is_session_started(&mouse->ctrl_pipe));
    64 
    65         int rc;
    66 
    67         void *config_descriptor;
    68         size_t config_descriptor_size;
    69 
    70         rc = usb_request_get_full_configuration_descriptor_alloc(
    71             &mouse->ctrl_pipe, 0, &config_descriptor, &config_descriptor_size);
    72         if (rc != EOK) {
    73                 return rc;
    74         }
    75 
    76         usb_endpoint_mapping_t endpoint_mapping[1] = {
    77                 {
    78                         .pipe = &mouse->poll_pipe,
    79                         .description = &poll_endpoint_description,
    80                         .interface_no = my_interface
    81                 }
    82         };
    83 
    84         rc = usb_endpoint_pipe_initialize_from_configuration(endpoint_mapping,
    85             1, config_descriptor, config_descriptor_size, &mouse->wire);
    86         if (rc != EOK) {
    87                 return rc;
    88         }
    89 
    90         if (!endpoint_mapping[0].present) {
    91                 return ENOENT;
    92         }
    93 
    94         mouse->poll_interval_us = 1000 * endpoint_mapping[0].descriptor->poll_interval;
    95 
    96         usb_log_debug("prepared polling endpoint %d (interval %zu).\n",
    97             mouse->poll_pipe.endpoint_no, mouse->poll_interval_us);
    98 
    99         return EOK;
    100 }
    10152
    10253static void default_connection_handler(ddf_fun_t *, ipc_callid_t, ipc_call_t *);
     
    14394 * @return Error code.
    14495 */
    145 int usb_mouse_create(ddf_dev_t *dev)
     96int usb_mouse_create(usb_device_t *dev)
    14697{
    14798        usb_mouse_t *mouse = malloc(sizeof(usb_mouse_t));
     
    149100                return ENOMEM;
    150101        }
    151         mouse->device = dev;
     102        mouse->dev = dev;
    152103        mouse->console_phone = -1;
    153104
    154105        int rc;
    155106
    156         /* Initialize the backing connection. */
    157         rc = usb_device_connection_initialize_from_device(&mouse->wire, dev);
    158         if (rc != EOK) {
    159                 goto leave;
    160         }
    161 
    162         /* Initialize the default control pipe. */
    163         rc = usb_endpoint_pipe_initialize_default_control(&mouse->ctrl_pipe,
    164             &mouse->wire);
    165         if (rc != EOK) {
    166                 goto leave;
    167         }
    168 
    169         rc = usb_endpoint_pipe_start_session(&mouse->ctrl_pipe);
    170         if (rc != EOK) {
    171                 goto leave;
    172         }
    173 
    174         rc = intialize_poll_pipe(mouse, usb_device_get_assigned_interface(dev));
    175 
    176         /* We can ignore error here. */
    177         usb_endpoint_pipe_end_session(&mouse->ctrl_pipe);
    178 
    179         if (rc != EOK) {
    180                 goto leave;
    181         }
    182 
    183107        /* Create DDF function. */
    184         mouse->mouse_fun = ddf_fun_create(dev, fun_exposed, "mouse");
     108        mouse->mouse_fun = ddf_fun_create(dev->ddf_dev, fun_exposed, "mouse");
    185109        if (mouse->mouse_fun == NULL) {
    186110                rc = ENOMEM;
  • uspace/drv/usbmouse/main.c

    r335382d rdeb4ba7  
    4444 * @return Error code.
    4545 */
    46 static int usbmouse_add_device(ddf_dev_t *dev)
     46static int usbmouse_add_device(usb_device_t *dev)
    4747{
    4848        int rc = usb_mouse_create(dev);
     
    5353        }
    5454
    55         fid_t poll_fibril = fibril_create(usb_mouse_polling_fibril, dev);
    56         if (poll_fibril == 0) {
    57                 usb_log_error("Failed to initialize polling fibril.\n");
    58                 /* FIXME: free allocated resources. */
    59                 return ENOMEM;
     55        usb_log_debug("Polling pipe at endpoint %d.\n", dev->pipes[0].pipe->endpoint_no);
     56
     57        rc = usb_device_auto_poll(dev, 0,
     58            usb_mouse_polling_callback, dev->pipes[0].pipe->max_packet_size,
     59            usb_mouse_polling_ended_callback, dev->driver_data);
     60
     61        if (rc != EOK) {
     62                usb_log_error("Failed to start polling fibril: %s.\n",
     63                    str_error(rc));
     64                return rc;
    6065        }
    6166
    62         fibril_add_ready(poll_fibril);
    63 
    6467        usb_log_info("controlling new mouse (handle %llu).\n",
    65             dev->handle);
     68            dev->ddf_dev->handle);
    6669
    6770        return EOK;
     
    6972
    7073/** USB mouse driver ops. */
    71 static driver_ops_t mouse_driver_ops = {
     74static usb_driver_ops_t mouse_driver_ops = {
    7275        .add_device = usbmouse_add_device,
    7376};
    7477
     78static usb_endpoint_description_t *endpoints[] = {
     79        &poll_endpoint_description,
     80        NULL
     81};
     82
    7583/** USB mouse driver. */
    76 static driver_t mouse_driver = {
     84static usb_driver_t mouse_driver = {
    7785        .name = NAME,
    78         .driver_ops = &mouse_driver_ops
     86        .ops = &mouse_driver_ops,
     87        .endpoints = endpoints
    7988};
    8089
     
    8392        usb_log_enable(USB_LOG_LEVEL_DEBUG, NAME);
    8493
    85         return ddf_driver_main(&mouse_driver);
     94        return usb_driver_main(&mouse_driver);
    8695}
    8796
  • uspace/drv/usbmouse/mouse.c

    r335382d rdeb4ba7  
    4040#include <ipc/mouse.h>
    4141
    42 /** Fibril function for polling the mouse device.
     42/** Mouse polling callback.
    4343 *
    44  * This function shall not terminate unless the device breaks and fails
    45  * to send data (e.g. stalls on data request).
    46  *
    47  * @param arg ddf_dev_t type representing the mouse device.
    48  * @return EOK Always.
     44 * @param dev Device that is being polled.
     45 * @param buffer Data buffer.
     46 * @param buffer_size Buffer size in bytes.
     47 * @param arg Custom argument - points to usb_mouse_t.
     48 * @return Always true.
    4949 */
    50 int usb_mouse_polling_fibril(void *arg)
     50bool usb_mouse_polling_callback(usb_device_t *dev,
     51    uint8_t *buffer, size_t buffer_size, void *arg)
    5152{
    52         assert(arg != NULL);
    53         ddf_dev_t *dev = (ddf_dev_t *) arg;
    54         usb_mouse_t *mouse = (usb_mouse_t *) dev->driver_data;
     53        usb_mouse_t *mouse = (usb_mouse_t *) arg;
    5554
    56         assert(mouse);
     55        usb_log_debug2("got buffer: %s.\n",
     56            usb_debug_str_buffer(buffer, buffer_size, 0));
    5757
    58         size_t buffer_size = mouse->poll_pipe.max_packet_size;
     58        uint8_t butt = buffer[0];
     59        char str_buttons[4] = {
     60                butt & 1 ? '#' : '.',
     61                butt & 2 ? '#' : '.',
     62                butt & 4 ? '#' : '.',
     63                0
     64        };
    5965
    60         if (buffer_size < 4) {
    61                 usb_log_error("Weird mouse, results will be skewed.\n");
    62                 buffer_size = 4;
     66        int shift_x = ((int) buffer[1]) - 127;
     67        int shift_y = ((int) buffer[2]) - 127;
     68        int wheel = ((int) buffer[3]) - 127;
     69
     70        if (buffer[1] == 0) {
     71                shift_x = 0;
     72        }
     73        if (buffer[2] == 0) {
     74                shift_y = 0;
     75        }
     76        if (buffer[3] == 0) {
     77                wheel = 0;
    6378        }
    6479
    65         uint8_t *buffer = malloc(buffer_size);
    66         if (buffer == NULL) {
    67                 usb_log_error("Out of memory, poll fibril aborted.\n");
    68                 return ENOMEM;
     80        if (mouse->console_phone >= 0) {
     81                if ((shift_x != 0) || (shift_y != 0)) {
     82                        /* FIXME: guessed for QEMU */
     83                        async_req_2_0(mouse->console_phone,
     84                            MEVENT_MOVE,
     85                            - shift_x / 10,  - shift_y / 10);
     86                }
     87                if (butt) {
     88                        /* FIXME: proper button clicking. */
     89                        async_req_2_0(mouse->console_phone,
     90                            MEVENT_BUTTON, 1, 1);
     91                        async_req_2_0(mouse->console_phone,
     92                            MEVENT_BUTTON, 1, 0);
     93                }
    6994        }
    7095
    71         while (true) {
    72                 async_usleep(mouse->poll_interval_us);
     96        usb_log_debug("buttons=%s  dX=%+3d  dY=%+3d  wheel=%+3d\n",
     97            str_buttons, shift_x, shift_y, wheel);
    7398
    74                 size_t actual_size;
    75                 int rc;
     99        /* Guess. */
     100        async_usleep(1000);
    76101
    77                 /*
    78                  * Error checking note:
    79                  * - failure when starting a session is considered
    80                  *   temporary (e.g. out of phones, next try might succeed)
    81                  * - failure of transfer considered fatal (probably the
    82                  *   device was unplugged)
    83                  * - session closing not checked (shall not fail anyway)
    84                  */
     102        return true;
     103}
    85104
    86                 rc = usb_endpoint_pipe_start_session(&mouse->poll_pipe);
    87                 if (rc != EOK) {
    88                         usb_log_warning("Failed to start session, will try again: %s.\n",
    89                             str_error(rc));
    90                         continue;
    91                 }
     105/** Callback when polling is terminated.
     106 *
     107 * @param dev Device where the polling terminated.
     108 * @param recurring_errors Whether the polling was terminated due to
     109 *      recurring errors.
     110 * @param arg Custom argument - points to usb_mouse_t.
     111 */
     112void usb_mouse_polling_ended_callback(usb_device_t *dev,
     113    bool recurring_errors, void *arg)
     114{
     115        usb_mouse_t *mouse = (usb_mouse_t *) arg;
    92116
    93                 rc = usb_endpoint_pipe_read(&mouse->poll_pipe,
    94                     buffer, buffer_size, &actual_size);
    95 
    96                 usb_endpoint_pipe_end_session(&mouse->poll_pipe);
    97 
    98                 if (rc != EOK) {
    99                         usb_log_error("Failed reading mouse input: %s.\n",
    100                             str_error(rc));
    101                         break;
    102                 }
    103 
    104                 usb_log_debug2("got buffer: %s.\n",
    105                     usb_debug_str_buffer(buffer, buffer_size, 0));
    106 
    107                 uint8_t butt = buffer[0];
    108                 char str_buttons[4] = {
    109                         butt & 1 ? '#' : '.',
    110                         butt & 2 ? '#' : '.',
    111                         butt & 4 ? '#' : '.',
    112                         0
    113                 };
    114 
    115                 int shift_x = ((int) buffer[1]) - 127;
    116                 int shift_y = ((int) buffer[2]) - 127;
    117                 int wheel = ((int) buffer[3]) - 127;
    118 
    119                 if (buffer[1] == 0) {
    120                         shift_x = 0;
    121                 }
    122                 if (buffer[2] == 0) {
    123                         shift_y = 0;
    124                 }
    125                 if (buffer[3] == 0) {
    126                         wheel = 0;
    127                 }
    128 
    129                 if (mouse->console_phone >= 0) {
    130                         if ((shift_x != 0) || (shift_y != 0)) {
    131                                 /* FIXME: guessed for QEMU */
    132                                 async_req_2_0(mouse->console_phone,
    133                                     MEVENT_MOVE,
    134                                     - shift_x / 10,  - shift_y / 10);
    135                         }
    136                         if (butt) {
    137                                 /* FIXME: proper button clicking. */
    138                                 async_req_2_0(mouse->console_phone,
    139                                     MEVENT_BUTTON, 1, 1);
    140                                 async_req_2_0(mouse->console_phone,
    141                                     MEVENT_BUTTON, 1, 0);
    142                         }
    143                 }
    144 
    145                 usb_log_debug("buttons=%s  dX=%+3d  dY=%+3d  wheel=%+3d\n",
    146                    str_buttons, shift_x, shift_y, wheel);
    147         }
    148 
    149         /*
    150          * Device was probably unplugged.
    151          * Hang-up the phone to the console.
    152          * FIXME: release allocated memory.
    153          */
    154117        async_hangup(mouse->console_phone);
    155118        mouse->console_phone = -1;
    156 
    157         usb_log_error("Mouse polling fibril terminated.\n");
    158 
    159         return EOK;
    160119}
    161 
    162120
    163121/**
  • uspace/drv/usbmouse/mouse.h

    r335382d rdeb4ba7  
    3737#define USBMOUSE_MOUSE_H_
    3838
    39 #include <ddf/driver.h>
     39#include <usb/devdrv.h>
    4040#include <usb/pipes.h>
    4141#include <time.h>
     
    4646typedef struct {
    4747        /** Generic device container. */
    48         ddf_dev_t *device;
     48        usb_device_t *dev;
    4949        /** Function representing the device. */
    5050        ddf_fun_t *mouse_fun;
    51         /** Representation of connection to the device. */
    52         usb_device_connection_t wire;
    53         /** Default (zero) control pipe. */
    54         usb_endpoint_pipe_t ctrl_pipe;
    55         /** Polling (in) pipe. */
    56         usb_endpoint_pipe_t poll_pipe;
    5751        /** Polling interval in microseconds. */
    5852        suseconds_t poll_interval_us;
     
    6155} usb_mouse_t;
    6256
    63 int usb_mouse_create(ddf_dev_t *);
     57#define POLL_PIPE(dev) ((dev)->pipes[0].pipe)
    6458
    65 int usb_mouse_polling_fibril(void *);
     59extern usb_endpoint_description_t poll_endpoint_description;
     60
     61int usb_mouse_create(usb_device_t *);
     62
     63bool usb_mouse_polling_callback(usb_device_t *, uint8_t *, size_t, void *);
     64void usb_mouse_polling_ended_callback(usb_device_t *, bool, void *);
    6665
    6766#endif
  • uspace/lib/usb/Makefile

    r335382d rdeb4ba7  
    3737        src/ddfiface.c \
    3838        src/debug.c \
     39        src/devdrv.c \
     40        src/devpoll.c \
    3941        src/dp.c \
    4042        src/dump.c \
  • uspace/lib/usb/include/usb/pipes.h

    r335382d rdeb4ba7  
    106106        const usb_endpoint_description_t *description;
    107107        /** Interface number the endpoint must belong to (-1 for any). */
    108         const int interface_no;
     108        int interface_no;
    109109        /** Found descriptor fitting the description. */
    110110        usb_standard_endpoint_descriptor_t *descriptor;
Note: See TracChangeset for help on using the changeset viewer.