[bc9a629] | 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 |
|
---|
[b8100da] | 29 | /** @addtogroup libusbvirt usb
|
---|
[bc9a629] | 30 | * @{
|
---|
| 31 | */
|
---|
| 32 | /** @file
|
---|
| 33 | * @brief Virtual USB device.
|
---|
| 34 | */
|
---|
[b8100da] | 35 | #ifndef LIBUSBVIRT_DEVICE_H_
|
---|
| 36 | #define LIBUSBVIRT_DEVICE_H_
|
---|
[bc9a629] | 37 |
|
---|
[b8100da] | 38 | #include <usb/hcd.h>
|
---|
[2193471] | 39 | #include <usb/descriptor.h>
|
---|
[b8100da] | 40 | #include <usb/devreq.h>
|
---|
[bc9a629] | 41 |
|
---|
[ca07cd3] | 42 | typedef struct usbvirt_device usbvirt_device_t;
|
---|
[7a7bfeb3] | 43 | struct usbvirt_control_transfer;
|
---|
[bc9a629] | 44 |
|
---|
[ca07cd3] | 45 | typedef int (*usbvirt_on_device_request_t)(usbvirt_device_t *dev,
|
---|
[d97d209] | 46 | usb_device_request_setup_packet_t *request,
|
---|
| 47 | uint8_t *data);
|
---|
[bc9a629] | 48 |
|
---|
[73301a0] | 49 | /** Callbacks for standard device requests.
|
---|
| 50 | * When these functions are NULL or return EFORWARD, this
|
---|
| 51 | * framework will try to satisfy the request by itself.
|
---|
| 52 | */
|
---|
| 53 | typedef struct {
|
---|
| 54 | usbvirt_on_device_request_t on_get_status;
|
---|
| 55 | usbvirt_on_device_request_t on_clear_feature;
|
---|
| 56 | usbvirt_on_device_request_t on_set_feature;
|
---|
| 57 | usbvirt_on_device_request_t on_set_address;
|
---|
| 58 | usbvirt_on_device_request_t on_get_descriptor;
|
---|
| 59 | usbvirt_on_device_request_t on_set_descriptor;
|
---|
| 60 | usbvirt_on_device_request_t on_get_configuration;
|
---|
| 61 | usbvirt_on_device_request_t on_set_configuration;
|
---|
| 62 | usbvirt_on_device_request_t on_get_interface;
|
---|
| 63 | usbvirt_on_device_request_t on_set_interface;
|
---|
| 64 | usbvirt_on_device_request_t on_synch_frame;
|
---|
| 65 | } usbvirt_standard_device_request_ops_t;
|
---|
| 66 |
|
---|
[2c381250] | 67 | /** Device operations. */
|
---|
[b8100da] | 68 | typedef struct {
|
---|
[73301a0] | 69 | /** Callbacks for standard deivce requests. */
|
---|
| 70 | usbvirt_standard_device_request_ops_t *standard_request_ops;
|
---|
[2c381250] | 71 | /** Callback for class-specific USB request. */
|
---|
[73301a0] | 72 | usbvirt_on_device_request_t on_class_device_request;
|
---|
[7a7bfeb3] | 73 |
|
---|
[ca07cd3] | 74 | int (*on_control_transfer)(usbvirt_device_t *dev,
|
---|
[7a7bfeb3] | 75 | usb_endpoint_t endpoint, struct usbvirt_control_transfer *transfer);
|
---|
| 76 |
|
---|
[2c381250] | 77 | /** Callback for all other incoming data. */
|
---|
[ca07cd3] | 78 | int (*on_data)(usbvirt_device_t *dev,
|
---|
[b8100da] | 79 | usb_endpoint_t endpoint, void *buffer, size_t size);
|
---|
[7a7bfeb3] | 80 |
|
---|
| 81 | /** Callback for host request for data. */
|
---|
[ca07cd3] | 82 | int (*on_data_request)(usbvirt_device_t *dev,
|
---|
[7a7bfeb3] | 83 | usb_endpoint_t endpoint, void *buffer, size_t size, size_t *actual_size);
|
---|
| 84 |
|
---|
| 85 | /** Decides direction of control transfer. */
|
---|
| 86 | usb_direction_t (*decide_control_transfer_direction)(
|
---|
| 87 | usb_endpoint_t endpoint, void *buffer, size_t size);
|
---|
[b8100da] | 88 | } usbvirt_device_ops_t;
|
---|
[bc9a629] | 89 |
|
---|
[2c381250] | 90 | /** Extra configuration data for GET_CONFIGURATION request. */
|
---|
| 91 | typedef struct {
|
---|
| 92 | /** Actual data. */
|
---|
| 93 | uint8_t *data;
|
---|
| 94 | /** Data length. */
|
---|
| 95 | size_t length;
|
---|
| 96 | } usbvirt_device_configuration_extras_t;
|
---|
| 97 |
|
---|
| 98 | /** Single device configuration. */
|
---|
| 99 | typedef struct {
|
---|
| 100 | /** Standard configuration descriptor. */
|
---|
| 101 | usb_standard_configuration_descriptor_t *descriptor;
|
---|
| 102 | /** Array of extra data. */
|
---|
| 103 | usbvirt_device_configuration_extras_t *extra;
|
---|
| 104 | /** Length of @c extra array. */
|
---|
| 105 | size_t extra_count;
|
---|
| 106 | } usbvirt_device_configuration_t;
|
---|
| 107 |
|
---|
| 108 | /** Standard USB descriptors. */
|
---|
| 109 | typedef struct {
|
---|
| 110 | /** Standard device descriptor.
|
---|
| 111 | * There is always only one such descriptor for the device.
|
---|
| 112 | */
|
---|
| 113 | usb_standard_device_descriptor_t *device;
|
---|
| 114 |
|
---|
| 115 | /** Configurations. */
|
---|
| 116 | usbvirt_device_configuration_t *configuration;
|
---|
| 117 | /** Number of configurations. */
|
---|
| 118 | size_t configuration_count;
|
---|
[08af5a6] | 119 | /** Index of currently selected configuration. */
|
---|
| 120 | uint8_t current_configuration;
|
---|
[2c381250] | 121 | } usbvirt_descriptors_t;
|
---|
| 122 |
|
---|
[47e3a8e] | 123 | /** Possible states of virtual USB device.
|
---|
| 124 | * Notice that these are not 1:1 mappings to those in USB specification.
|
---|
| 125 | */
|
---|
| 126 | typedef enum {
|
---|
| 127 | USBVIRT_STATE_DEFAULT,
|
---|
| 128 | USBVIRT_STATE_ADDRESS,
|
---|
| 129 | USBVIRT_STATE_CONFIGURED
|
---|
| 130 | } usbvirt_device_state_t;
|
---|
[2c381250] | 131 |
|
---|
[7a7bfeb3] | 132 | /** Information about on-going control transfer.
|
---|
| 133 | */
|
---|
| 134 | typedef struct usbvirt_control_transfer {
|
---|
[ca07cd3] | 135 | /** Transfer direction (read/write control transfer). */
|
---|
[7a7bfeb3] | 136 | usb_direction_t direction;
|
---|
[ca07cd3] | 137 | /** Request data. */
|
---|
[7a7bfeb3] | 138 | void *request;
|
---|
[ca07cd3] | 139 | /** Size of request data. */
|
---|
[7a7bfeb3] | 140 | size_t request_size;
|
---|
[ca07cd3] | 141 | /** Payload. */
|
---|
[7a7bfeb3] | 142 | void *data;
|
---|
[ca07cd3] | 143 | /** Size of payload. */
|
---|
[7a7bfeb3] | 144 | size_t data_size;
|
---|
| 145 | } usbvirt_control_transfer_t;
|
---|
| 146 |
|
---|
[47e3a8e] | 147 | /** Virtual USB device. */
|
---|
[ca07cd3] | 148 | struct usbvirt_device {
|
---|
[b8100da] | 149 | /** Callback device operations. */
|
---|
| 150 | usbvirt_device_ops_t *ops;
|
---|
| 151 |
|
---|
[7a7bfeb3] | 152 | /** Reply onto control transfer.
|
---|
[b8100da] | 153 | */
|
---|
[ca07cd3] | 154 | int (*control_transfer_reply)(usbvirt_device_t *dev,
|
---|
[b8100da] | 155 | usb_endpoint_t endpoint, void *buffer, size_t size);
|
---|
| 156 |
|
---|
[ca07cd3] | 157 | /** Device name.
|
---|
| 158 | * Used in debug prints and sent to virtual host controller.
|
---|
| 159 | */
|
---|
| 160 | const char *name;
|
---|
[4971812] | 161 |
|
---|
[2c381250] | 162 | /** Standard descriptors. */
|
---|
| 163 | usbvirt_descriptors_t *descriptors;
|
---|
[4971812] | 164 |
|
---|
[47e3a8e] | 165 | /** Current device state. */
|
---|
| 166 | usbvirt_device_state_t state;
|
---|
[ca07cd3] | 167 |
|
---|
[47e3a8e] | 168 | /** Device address. */
|
---|
| 169 | usb_address_t address;
|
---|
[ca07cd3] | 170 | /** New device address.
|
---|
| 171 | * This field is used during SET_ADDRESS request.
|
---|
| 172 | * On all other occasions, it holds invalid address (e.g. -1).
|
---|
[b8100da] | 173 | */
|
---|
[ca07cd3] | 174 | usb_address_t new_address;
|
---|
[186d630] | 175 |
|
---|
[ca07cd3] | 176 | /** Process OUT transaction. */
|
---|
| 177 | int (*transaction_out)(usbvirt_device_t *dev,
|
---|
[7a7bfeb3] | 178 | usb_endpoint_t endpoint, void *buffer, size_t size);
|
---|
[ca07cd3] | 179 | /** Process SETUP transaction. */
|
---|
| 180 | int (*transaction_setup)(usbvirt_device_t *dev,
|
---|
[186d630] | 181 | usb_endpoint_t endpoint, void *buffer, size_t size);
|
---|
[ca07cd3] | 182 | /** Process IN transaction. */
|
---|
| 183 | int (*transaction_in)(usbvirt_device_t *dev,
|
---|
[7a7bfeb3] | 184 | usb_endpoint_t endpoint, void *buffer, size_t size, size_t *data_size);
|
---|
[186d630] | 185 |
|
---|
[ca07cd3] | 186 | /** State information on control-transfer endpoints. */
|
---|
[7a7bfeb3] | 187 | usbvirt_control_transfer_t current_control_transfers[USB11_ENDPOINT_MAX];
|
---|
[ca07cd3] | 188 | };
|
---|
[bc9a629] | 189 |
|
---|
| 190 | #endif
|
---|
| 191 | /**
|
---|
| 192 | * @}
|
---|
| 193 | */
|
---|