Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/usbvirt/src/stdreq.c

    r6cb58e6 r0f21c0c  
     1/*
     2 * Copyright (c) 2010 Vojtech Horky
     3 * All rights reserved.
     4 *
     5 * Redistribution and use in source and binary forms, with or without
     6 * modification, are permitted provided that the following conditions
     7 * are met:
     8 *
     9 * - Redistributions of source code must retain the above copyright
     10 *   notice, this list of conditions and the following disclaimer.
     11 * - Redistributions in binary form must reproduce the above copyright
     12 *   notice, this list of conditions and the following disclaimer in the
     13 *   documentation and/or other materials provided with the distribution.
     14 * - The name of the author may not be used to endorse or promote products
     15 *   derived from this software without specific prior written permission.
     16 *
     17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
     18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
     21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     27 */
     28
     29/** @addtogroup libusbvirt
     30 * @{
     31 */
     32/** @file
     33 * @brief Preprocessing of standard device requests.
     34 */
     35#include <errno.h>
     36#include <stdlib.h>
     37#include <mem.h>
     38#include <usb/request.h>
     39
    140#include "private.h"
    2 #include <usb/request.h>
    3 #include <assert.h>
    4 #include <errno.h>
    5 
    6 void usbvirt_control_reply_helper(const usb_device_request_setup_packet_t *setup_packet,
    7     uint8_t *data, size_t *act_size,
    8     void *actual_data, size_t actual_data_size)
    9 {
    10         size_t expected_size = setup_packet->length;
    11         if (expected_size < actual_data_size) {
    12                 actual_data_size = expected_size;
    13         }
    14 
    15         memcpy(data, actual_data, actual_data_size);
    16 
    17         if (act_size != NULL) {
    18                 *act_size = actual_data_size;
    19         }
    20 }
    21 
     41
     42/*
     43 * All sub handlers must return EFORWARD to inform the caller that
     44 * they were not able to process the request (yes, it is abuse of
     45 * this error code but such error code shall not collide with anything
     46 * else in this context).
     47 */
     48 
    2249/** GET_DESCRIPTOR handler. */
    23 static int req_get_descriptor(usbvirt_device_t *device,
    24     const usb_device_request_setup_packet_t *setup_packet, uint8_t *data, size_t *act_size)
     50static int handle_get_descriptor(usbvirt_device_t *device,
     51    usb_device_request_setup_packet_t *setup_packet, uint8_t *extra_data)
    2552{
    2653        uint8_t type = setup_packet->value_high;
    2754        uint8_t index = setup_packet->value_low;
    2855
    29         /*
     56        /* 
    3057         * Standard device descriptor.
    3158         */
    3259        if ((type == USB_DESCTYPE_DEVICE) && (index == 0)) {
    3360                if (device->descriptors && device->descriptors->device) {
    34                         usbvirt_control_reply_helper(setup_packet, data, act_size,
     61                        return device->control_transfer_reply(device, 0,
    3562                            device->descriptors->device,
    3663                            device->descriptors->device->length);
    37                         return EOK;
    3864                } else {
    3965                        return EFORWARD;
    4066                }
    4167        }
    42 
     68       
    4369        /*
    4470         * Configuration descriptor together with interface, endpoint and
     
    5985                        return ENOMEM;
    6086                }
    61 
     87               
    6288                uint8_t *ptr = all_data;
    6389                memcpy(ptr, config->descriptor, config->descriptor->length);
     
    7096                        ptr += extra->length;
    7197                }
    72 
    73                 usbvirt_control_reply_helper(setup_packet, data, act_size,
     98               
     99                int rc = device->control_transfer_reply(device, 0,
    74100                    all_data, config->descriptor->total_length);
    75 
     101               
    76102                free(all_data);
    77 
    78                 return EOK;
    79         }
    80 
     103               
     104                return rc;
     105        }
     106       
    81107        return EFORWARD;
    82108}
    83109
    84 static int req_set_address(usbvirt_device_t *device,
    85     const usb_device_request_setup_packet_t *setup_packet, uint8_t *data, size_t *act_size)
     110/** SET_ADDRESS handler. */
     111static int handle_set_address(usbvirt_device_t *device,
     112    usb_device_request_setup_packet_t *setup_packet, uint8_t *extra_data)
    86113{
    87114        uint16_t new_address = setup_packet->value;
     
    92119                return EINVAL;
    93120        }
    94 
     121       
    95122        if (new_address > 127) {
    96123                return EINVAL;
    97124        }
    98 
    99         device->address = new_address;
    100 
     125       
     126        device->new_address = new_address;
     127       
    101128        return EOK;
    102129}
    103130
    104 static int req_set_configuration(usbvirt_device_t *device,
    105     const usb_device_request_setup_packet_t *setup_packet, uint8_t *data, size_t *act_size)
     131/** SET_CONFIGURATION handler. */
     132static int handle_set_configuration(usbvirt_device_t *device,
     133    usb_device_request_setup_packet_t *setup_packet, uint8_t *extra_data)
    106134{
    107135        uint16_t configuration_value = setup_packet->value;
     
    112140                return EINVAL;
    113141        }
    114 
     142       
    115143        /*
    116144         * Configuration value is 1 byte information.
     
    119147                return EINVAL;
    120148        }
    121 
     149       
    122150        /*
    123151         * Do nothing when in default state. According to specification,
     
    127155                return EOK;
    128156        }
    129 
    130         usbvirt_device_state_t new_state;
     157       
    131158        if (configuration_value == 0) {
    132                 new_state = USBVIRT_STATE_ADDRESS;
     159                if (DEVICE_HAS_OP(device, on_state_change)) {
     160                        device->ops->on_state_change(device, device->state,
     161                            USBVIRT_STATE_ADDRESS);
     162                }
     163                device->state = USBVIRT_STATE_ADDRESS;
    133164        } else {
    134                 // FIXME: check that this configuration exists
    135                 new_state = USBVIRT_STATE_CONFIGURED;
    136         }
    137 
    138         if (device->ops && device->ops->state_changed) {
    139                 device->ops->state_changed(device, device->state, new_state);
    140         }
    141         device->state = new_state;
    142 
     165                /*
     166                * TODO: browse provided configurations and verify that
     167                * user selected existing configuration.
     168                */
     169                if (DEVICE_HAS_OP(device, on_state_change)) {
     170                        device->ops->on_state_change(device, device->state,
     171                            USBVIRT_STATE_CONFIGURED);
     172                }
     173                device->state = USBVIRT_STATE_CONFIGURED;
     174                if (device->descriptors) {
     175                        device->descriptors->current_configuration
     176                            = configuration_value;
     177                }
     178        }
     179               
    143180        return EOK;
    144181}
    145182
    146 usbvirt_control_request_handler_t library_handlers[] = {
     183
     184#define MAKE_BM_REQUEST(direction, recipient) \
     185        USBVIRT_MAKE_CONTROL_REQUEST_TYPE(direction, \
     186            USBVIRT_REQUEST_TYPE_STANDARD, recipient)
     187#define MAKE_BM_REQUEST_DEV(direction) \
     188        MAKE_BM_REQUEST(direction, USBVIRT_REQUEST_RECIPIENT_DEVICE)
     189
     190usbvirt_control_transfer_handler_t control_pipe_zero_local_handlers[] = {
    147191        {
    148                 .req_direction = USB_DIRECTION_OUT,
    149                 .req_recipient = USB_REQUEST_RECIPIENT_DEVICE,
    150                 .req_type = USB_REQUEST_TYPE_STANDARD,
    151                 .request = USB_DEVREQ_SET_ADDRESS,
    152                 .name = "SetAddress",
    153                 .callback = req_set_address
     192                .request_type = MAKE_BM_REQUEST_DEV(USB_DIRECTION_IN),
     193                .request = USB_DEVREQ_GET_DESCRIPTOR,
     194                .name = "GetDescriptor()",
     195                .callback = handle_get_descriptor
    154196        },
    155197        {
    156                 .req_direction = USB_DIRECTION_IN,
    157                 .req_recipient = USB_REQUEST_RECIPIENT_DEVICE,
    158                 .req_type = USB_REQUEST_TYPE_STANDARD,
    159                 .request = USB_DEVREQ_GET_DESCRIPTOR,
    160                 .name = "GetDescriptor",
    161                 .callback = req_get_descriptor
     198                .request_type = MAKE_BM_REQUEST_DEV(USB_DIRECTION_OUT),
     199                .request = USB_DEVREQ_SET_ADDRESS,
     200                .name = "SetAddress()",
     201                .callback = handle_set_address
    162202        },
    163203        {
    164                 .req_direction = USB_DIRECTION_OUT,
    165                 .req_recipient = USB_REQUEST_RECIPIENT_DEVICE,
    166                 .req_type = USB_REQUEST_TYPE_STANDARD,
     204                .request_type = MAKE_BM_REQUEST_DEV(USB_DIRECTION_OUT),
    167205                .request = USB_DEVREQ_SET_CONFIGURATION,
    168                 .name = "SetConfiguration",
    169                 .callback = req_set_configuration
     206                .name = "SetConfiguration()",
     207                .callback = handle_set_configuration
    170208        },
    171 
    172         { .callback = NULL }
     209        USBVIRT_CONTROL_TRANSFER_HANDLER_LAST
    173210};
    174211
     212/**
     213 * @}
     214 */
Note: See TracChangeset for help on using the changeset viewer.