Changeset 24aa62c in mainline


Ignore:
Timestamp:
2011-03-02T20:49:12Z (13 years ago)
Author:
Vojtech Horky <vojtechhorky@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
2c22f1f7
Parents:
af430ce (diff), 21bb58d (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:

Add simple USB mouse driver

The driver expects data in boot protocol format. The communication with
console is cripled but it works quite okay in QEMU.

Files:
6 added
10 edited

Legend:

Unmodified
Added
Removed
  • .bzrignore

    raf430ce r24aa62c  
    8989./uspace/drv/usbhid/usbhid
    9090./uspace/drv/usbmid/usbmid
     91./uspace/drv/usbmouse/usbmouse
    9192./uspace/drv/vhc/vhc
    9293./uspace/srv/bd/ata_bd/ata_bd
  • boot/arch/amd64/Makefile.inc

    raf430ce r24aa62c  
    4848        usbhid \
    4949        usbmid \
     50        usbmouse \
    5051        vhc
    5152
  • uspace/Makefile

    raf430ce r24aa62c  
    122122                drv/usbhub \
    123123                drv/usbmid \
     124                drv/usbmouse \
    124125                drv/vhc
    125126endif
     
    138139                drv/usbhub \
    139140                drv/usbmid \
     141                drv/usbmouse \
    140142                drv/vhc
    141143endif
  • uspace/doc/doxygroups.h

    raf430ce r24aa62c  
    245245
    246246        /**
     247         * @defgroup drvusbmouse USB mouse driver
     248         * @ingroup usb
     249         * @brief USB driver for mouse with boot protocol.
     250         */
     251
     252        /**
    247253         * @defgroup drvusbuhci UHCI driver
    248254         * @ingroup usb
  • uspace/drv/usbhid/hiddev.c

    raf430ce r24aa62c  
    149149        usb_log_info("Processing descriptors...\n");
    150150       
    151         // get the first configuration descriptor
    152         usb_standard_configuration_descriptor_t config_desc;
    153        
    154151        int rc;
    155         rc = usb_request_get_bare_configuration_descriptor(&hid_dev->ctrl_pipe,
    156             0, &config_desc);
    157        
    158         if (rc != EOK) {
    159                 usb_log_error("Failed to get bare config descriptor: %s.\n",
     152
     153        uint8_t *descriptors = NULL;
     154        size_t descriptors_size;
     155        rc = usb_request_get_full_configuration_descriptor_alloc(
     156            &hid_dev->ctrl_pipe, 0, (void **) &descriptors, &descriptors_size);
     157        if (rc != EOK) {
     158                usb_log_error("Failed to retrieve config descriptor: %s.\n",
    160159                    str_error(rc));
    161160                return rc;
    162         }
    163        
    164         // prepare space for all underlying descriptors
    165         uint8_t *descriptors = (uint8_t *)malloc(config_desc.total_length);
    166         if (descriptors == NULL) {
    167                 usb_log_error("No memory!.\n");
    168                 return ENOMEM;
    169         }
    170        
    171         size_t transferred = 0;
    172         // get full configuration descriptor
    173         rc = usb_request_get_full_configuration_descriptor(&hid_dev->ctrl_pipe,
    174             0, descriptors, config_desc.total_length, &transferred);
    175        
    176         if (rc != EOK) {
    177                 usb_log_error("Failed to get full config descriptor: %s.\n",
    178                     str_error(rc));
    179                 free(descriptors);
    180                 return rc;
    181         }
    182        
    183         if (transferred != config_desc.total_length) {
    184                 usb_log_error("Configuration descriptor has wrong size (%u, "
    185                     "expected %u).\n", transferred, config_desc.total_length);
    186                 free(descriptors);
    187                 return ELIMIT;
    188161        }
    189162       
     
    201174       
    202175        rc = usb_endpoint_pipe_initialize_from_configuration(
    203             endpoint_mapping, 1, descriptors, config_desc.total_length,
     176            endpoint_mapping, 1, descriptors, descriptors_size,
    204177            &hid_dev->wire);
    205178       
     
    233206        assert(endpoint_mapping[0].interface != NULL);
    234207       
    235         rc = usbhid_dev_get_report_descriptor(hid_dev, descriptors, transferred,
     208        rc = usbhid_dev_get_report_descriptor(hid_dev,
     209            descriptors, descriptors_size,
    236210            (uint8_t *)endpoint_mapping[0].interface);
    237211       
  • uspace/drv/usbhub/usbhub.c

    raf430ce r24aa62c  
    149149        }
    150150
    151         //configuration descriptor
    152         /// \TODO check other configurations?
    153         usb_standard_configuration_descriptor_t config_descriptor;
    154         opResult = usb_request_get_bare_configuration_descriptor(
     151        /* Retrieve full configuration descriptor. */
     152        uint8_t *descriptors = NULL;
     153        size_t descriptors_size = 0;
     154        opResult = usb_request_get_full_configuration_descriptor_alloc(
    155155            &hub->endpoints.control, 0,
    156         &config_descriptor);
    157         if(opResult!=EOK){
    158                 dprintf(USB_LOG_LEVEL_ERROR, "could not get configuration descriptor, %d",opResult);
     156            (void **) &descriptors, &descriptors_size);
     157        if (opResult != EOK) {
     158                usb_log_error("Could not get configuration descriptor: %s.\n",
     159                    str_error(opResult));
    159160                return opResult;
    160161        }
    161         //set configuration
     162        usb_standard_configuration_descriptor_t *config_descriptor
     163            = (usb_standard_configuration_descriptor_t *) descriptors;
     164
     165        /* Set configuration. */
    162166        opResult = usb_request_set_configuration(&hub->endpoints.control,
    163                 config_descriptor.configuration_number);
    164 
    165         if (opResult != EOK) {
    166                 dprintf(USB_LOG_LEVEL_ERROR,
    167                                 "something went wrong when setting hub`s configuration, %d",
    168                                 opResult);
     167            config_descriptor->configuration_number);
     168
     169        if (opResult != EOK) {
     170                usb_log_error("Failed to set hub configuration: %s.\n",
     171                    str_error(opResult));
    169172                return opResult;
    170173        }
    171174        dprintf(USB_LOG_LEVEL_DEBUG, "\tused configuration %d",
    172                         config_descriptor.configuration_number);
    173 
    174         //full configuration descriptor
    175         size_t transferred = 0;
    176         uint8_t * descriptors = (uint8_t *)malloc(config_descriptor.total_length);
    177         if (descriptors == NULL) {
    178                 dprintf(USB_LOG_LEVEL_ERROR, "insufficient memory");
    179                 return ENOMEM;
    180         }
    181         opResult = usb_request_get_full_configuration_descriptor(&hub->endpoints.control,
    182             0, descriptors,
    183             config_descriptor.total_length, &transferred);
    184         if(opResult!=EOK){
    185                 free(descriptors);
    186                 dprintf(USB_LOG_LEVEL_ERROR,
    187                                 "could not get full configuration descriptor, %d",opResult);
    188                 return opResult;
    189         }
    190         if (transferred != config_descriptor.total_length) {
    191                 dprintf(USB_LOG_LEVEL_ERROR,
    192                                 "received incorrect full configuration descriptor");
    193                 return ELIMIT;
    194         }
     175                        config_descriptor->configuration_number);
    195176
    196177        usb_endpoint_mapping_t endpoint_mapping[1] = {
     
    204185        opResult = usb_endpoint_pipe_initialize_from_configuration(
    205186            endpoint_mapping, 1,
    206             descriptors, config_descriptor.total_length,
     187            descriptors, descriptors_size,
    207188            &hub->device_connection);
    208189        if (opResult != EOK) {
  • uspace/drv/usbmid/explore.c

    raf430ce r24aa62c  
    4242#include "usbmid.h"
    4343
    44 /** Allocate and retrieve full configuration descriptor.
    45  *
    46  * @param[in] dev USB device.
    47  * @param[in] config_index Configuration index.
    48  * @param[out] size Pointer where to store size of the allocated buffer.
    49  * @return Allocated full configuration descriptor.
    50  * @retval NULL Error occured.
    51  */
    52 static void *get_configuration_descriptor(usbmid_device_t *dev,
    53     size_t config_index, size_t *size)
    54 {
    55         usb_standard_configuration_descriptor_t config_descriptor;
    56         int rc = usb_request_get_bare_configuration_descriptor(&dev->ctrl_pipe,
    57             config_index, &config_descriptor);
    58         if (rc != EOK) {
    59                 usb_log_error("Failed getting configuration descriptor: %s.\n",
    60                     str_error(rc));
    61                 return NULL;
    62         }
    63 
    64         void *full_config_descriptor = malloc(config_descriptor.total_length);
    65         if (full_config_descriptor == NULL) {
    66                 usb_log_fatal("Out of memory (wanted: %zuB).\n",
    67                     (size_t) config_descriptor.total_length);
    68                 return NULL;
    69         }
    70 
    71         size_t full_config_descriptor_size;
    72         rc = usb_request_get_full_configuration_descriptor(&dev->ctrl_pipe,
    73             config_index,
    74             full_config_descriptor, config_descriptor.total_length,
    75             &full_config_descriptor_size);
    76         if (rc != EOK) {
    77                 usb_log_error("Failed getting configuration descriptor: %s.\n",
    78                     str_error(rc));
    79                 free(full_config_descriptor);
    80                 return NULL;
    81         }
    82 
    83         if (full_config_descriptor_size != config_descriptor.total_length) {
    84                 usb_log_error("Failed getting full configuration descriptor.\n");
    85                 free(full_config_descriptor);
    86                 return NULL;
    87         }
    88 
    89         if (size != NULL) {
    90                 *size = full_config_descriptor_size;
    91         }
    92 
    93         return full_config_descriptor;
    94 }
    95 
    9644/** Find starting indexes of all interface descriptors in a configuration.
    9745 *
     
    178126
    179127        size_t config_descriptor_size;
    180         uint8_t *config_descriptor_raw = get_configuration_descriptor(dev, 0,
    181             &config_descriptor_size);
    182         if (config_descriptor_raw == NULL) {
     128        uint8_t *config_descriptor_raw = NULL;
     129        rc = usb_request_get_full_configuration_descriptor_alloc(
     130            &dev->ctrl_pipe, 0,
     131            (void **) &config_descriptor_raw, &config_descriptor_size);
     132        if (rc != EOK) {
     133                usb_log_error("Failed getting full config descriptor: %s.\n",
     134                    str_error(rc));
    183135                return false;
    184136        }
  • uspace/lib/usb/include/usb/request.h

    raf430ce r24aa62c  
    106106int usb_request_get_full_configuration_descriptor(usb_endpoint_pipe_t *, int,
    107107    void *, size_t, size_t *);
     108int usb_request_get_full_configuration_descriptor_alloc(usb_endpoint_pipe_t *,
     109    int, void **, size_t *);
    108110int usb_request_set_configuration(usb_endpoint_pipe_t *, uint8_t);
    109111
  • uspace/lib/usb/src/request.c

    raf430ce r24aa62c  
    412412}
    413413
     414/** Retrieve full configuration descriptor, allocate space for it.
     415 *
     416 * The function takes care that full configuration descriptor is returned
     417 * (i.e. the function will fail when less data then descriptor.totalLength
     418 * is returned).
     419 *
     420 * @param[in] pipe Control endpoint pipe (session must be already started).
     421 * @param[in] index Configuration index.
     422 * @param[out] descriptor_ptr Where to store pointer to allocated buffer.
     423 * @param[out] descriptor_size Where to store the size of the descriptor.
     424 * @return Error code.
     425 */
     426int usb_request_get_full_configuration_descriptor_alloc(
     427    usb_endpoint_pipe_t *pipe, int index,
     428    void **descriptor_ptr, size_t *descriptor_size)
     429{
     430        int rc;
     431
     432        if (descriptor_ptr == NULL) {
     433                return EBADMEM;
     434        }
     435
     436        usb_standard_configuration_descriptor_t bare_config;
     437        rc = usb_request_get_bare_configuration_descriptor(pipe, index,
     438            &bare_config);
     439        if (rc != EOK) {
     440                return rc;
     441        }
     442
     443        if (bare_config.descriptor_type != USB_DESCTYPE_CONFIGURATION) {
     444                return ENOENT;
     445        }
     446        if (bare_config.total_length < sizeof(bare_config)) {
     447                return ELIMIT;
     448        }
     449
     450        void *buffer = malloc(bare_config.total_length);
     451        if (buffer == NULL) {
     452                return ENOMEM;
     453        }
     454
     455        size_t transferred = 0;
     456        rc = usb_request_get_full_configuration_descriptor(pipe, index,
     457            buffer, bare_config.total_length, &transferred);
     458        if (rc != EOK) {
     459                free(buffer);
     460                return rc;
     461        }
     462
     463        if (transferred != bare_config.total_length) {
     464                free(buffer);
     465                return ELIMIT;
     466        }
     467
     468        /* Everything looks okay, copy the pointers. */
     469
     470        *descriptor_ptr = buffer;
     471
     472        if (descriptor_size != NULL) {
     473                *descriptor_size = bare_config.total_length;
     474        }
     475
     476        return EOK;
     477}
     478
    414479/** Set configuration of USB device.
    415480 *
  • uspace/srv/hid/console/console.c

    raf430ce r24aa62c  
    715715}
    716716
    717 static int connect_keyboard(char *path)
     717static int connect_keyboard_or_mouse(const char *devname,
     718    async_client_conn_t handler, const char *path)
    718719{
    719720        int fd = open(path, O_RDONLY);
     
    728729        }
    729730       
    730         int rc = async_connect_to_me(phone, SERVICE_CONSOLE, 0, 0,
    731             keyboard_events);
     731        int rc = async_connect_to_me(phone, SERVICE_CONSOLE, 0, 0, handler);
    732732        if (rc != EOK) {
    733733                printf(NAME ": " \
     
    737737        }
    738738       
    739         printf(NAME ": found keyboard \"%s\".\n", path);
     739        printf(NAME ": found %s \"%s\".\n", devname, path);
    740740
    741741        return phone;
    742742}
    743743
     744static int connect_keyboard(const char *path)
     745{
     746        return connect_keyboard_or_mouse("keyboard", keyboard_events, path);
     747}
     748
     749static int connect_mouse(const char *path)
     750{
     751        return connect_keyboard_or_mouse("mouse", mouse_events, path);
     752}
     753
     754struct hid_class_info {
     755        char *classname;
     756        int (*connection_func)(const char *);
     757};
    744758
    745759/** Periodically check for new keyboards in /dev/class/.
     
    748762 * @return This function should never exit.
    749763 */
    750 static int check_new_keyboards(void *arg)
    751 {
    752         char *class_name = (char *) arg;
     764static int check_new_device_fibril(void *arg)
     765{
     766        struct hid_class_info *dev_info = arg;
    753767
    754768        size_t index = 1;
     
    758772                char *path;
    759773                int rc = asprintf(&path, "/dev/class/%s\\%zu",
    760                     class_name, index);
     774                    dev_info->classname, index);
    761775                if (rc < 0) {
    762776                        continue;
    763777                }
    764778                rc = 0;
    765                 rc = connect_keyboard(path);
     779                rc = dev_info->connection_func(path);
    766780                if (rc > 0) {
    767781                        /* We do not allow unplug. */
     
    778792/** Start a fibril monitoring hot-plugged keyboards.
    779793 */
    780 static void check_new_keyboards_in_background()
    781 {
    782         fid_t fid = fibril_create(check_new_keyboards, (void *)"keyboard");
     794static void check_new_devices_in_background(int (*connection_func)(const char *),
     795    const char *classname)
     796{
     797        struct hid_class_info *dev_info = malloc(sizeof(struct hid_class_info));
     798        if (dev_info == NULL) {
     799                printf(NAME ": " \
     800                    "out of memory, will not start hot-plug-watch fibril.\n");
     801                return;
     802        }
     803        int rc;
     804
     805        rc = asprintf(&dev_info->classname, "%s", classname);
     806        if (rc < 0) {
     807                printf(NAME ": failed to format classname: %s.\n",
     808                    str_error(rc));
     809                return;
     810        }
     811        dev_info->connection_func = connection_func;
     812
     813        fid_t fid = fibril_create(check_new_device_fibril, (void *)dev_info);
    783814        if (!fid) {
    784                 printf(NAME ": failed to create hot-plug-watch fibril.\n");
     815                printf(NAME
     816                    ": failed to create hot-plug-watch fibril for %s.\n",
     817                    classname);
    785818                return;
    786819        }
     
    796829        }
    797830
    798         /* Connect to mouse device */
    799         mouse_phone = -1;
    800         int mouse_fd = open("/dev/hid_in/mouse", O_RDONLY);
    801        
    802         if (mouse_fd < 0) {
    803                 printf(NAME ": Notice - failed opening %s\n", "/dev/hid_in/mouse");
    804                 goto skip_mouse;
    805         }
    806        
    807         mouse_phone = fd_phone(mouse_fd);
     831        mouse_phone = connect_mouse("/dev/hid_in/mouse");
    808832        if (mouse_phone < 0) {
    809                 printf(NAME ": Failed to connect to mouse device\n");
    810                 goto skip_mouse;
    811         }
    812        
    813         if (async_connect_to_me(mouse_phone, SERVICE_CONSOLE, 0, 0, mouse_events)
    814             != 0) {
    815                 printf(NAME ": Failed to create callback from mouse device\n");
    816                 mouse_phone = -1;
    817                 goto skip_mouse;
    818         }
    819        
    820 skip_mouse:
     833                printf(NAME ": Failed to connect to mouse device: %s.\n",
     834                    str_error(mouse_phone));
     835        }
    821836       
    822837        /* Connect to framebuffer driver */
     
    902917       
    903918        /* Start fibril for checking on hot-plugged keyboards. */
    904         check_new_keyboards_in_background();
     919        check_new_devices_in_background(connect_keyboard, "keyboard");
     920        check_new_devices_in_background(connect_mouse, "mouse");
    905921
    906922        return true;
Note: See TracChangeset for help on using the changeset viewer.