Changeset 6cb58e6 in mainline for uspace/lib/usbvirt
- Timestamp:
- 2011-04-28T07:36:48Z (14 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 6fd7062
- Parents:
- 48d1c228
- Location:
- uspace/lib/usbvirt
- Files:
-
- 3 added
- 5 deleted
- 4 edited
- 1 moved
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/usbvirt/Makefile
r48d1c228 r6cb58e6 1 1 # 2 # Copyright (c) 201 0Vojtech Horky2 # Copyright (c) 2011 Vojtech Horky 3 3 # All rights reserved. 4 4 # … … 33 33 34 34 SOURCES = \ 35 src/callback.c \ 36 src/ctrlpipe.c \ 37 src/debug.c \ 38 src/main.c \ 35 src/ipc.c \ 36 src/ctrltransfer.c \ 39 37 src/stdreq.c \ 40 src/trans action.c38 src/transfer.c 41 39 42 40 include $(USPACE_PREFIX)/Makefile.common -
uspace/lib/usbvirt/include/usbvirt/device.h
r48d1c228 r6cb58e6 1 1 /* 2 * Copyright (c) 201 0Vojtech Horky2 * Copyright (c) 2011 Vojtech Horky 3 3 * All rights reserved. 4 4 * … … 38 38 #include <usb/usb.h> 39 39 #include <usb/request.h> 40 #include <usb/descriptor.h>41 40 42 /** Request type of a control transfer. */ 43 typedef enum { 44 /** Standard USB request. */ 45 USBVIRT_REQUEST_TYPE_STANDARD = 0, 46 /** Standard class USB request. */ 47 USBVIRT_REQUEST_TYPE_CLASS = 1 48 } usbvirt_request_type_t; 49 50 /** Recipient of control request. */ 51 typedef enum { 52 /** Device is the recipient of the control request. */ 53 USBVIRT_REQUEST_RECIPIENT_DEVICE = 0, 54 /** Interface is the recipient of the control request. */ 55 USBVIRT_REQUEST_RECIPIENT_INTERFACE = 1, 56 /** Endpoint is the recipient of the control request. */ 57 USBVIRT_REQUEST_RECIPIENT_ENDPOINT = 2, 58 /** Other part of the device is the recipient of the control request. */ 59 USBVIRT_REQUEST_RECIPIENT_OTHER = 3 60 } usbvirt_request_recipient_t; 61 62 /** Possible states of virtual USB device. 63 * Notice that these are not 1:1 mappings to those in USB specification. 64 */ 65 typedef enum { 66 /** Default state, device listens at default address. */ 67 USBVIRT_STATE_DEFAULT, 68 /** Device has non-default address assigned. */ 69 USBVIRT_STATE_ADDRESS, 70 /** Device is configured. */ 71 USBVIRT_STATE_CONFIGURED 72 } usbvirt_device_state_t; 41 #define USBVIRT_ENDPOINT_MAX 16 73 42 74 43 typedef struct usbvirt_device usbvirt_device_t; 75 struct usbvirt_control_transfer;76 44 77 typedef int (*usbvirt_on_device_request_t)(usbvirt_device_t *dev, 78 usb_device_request_setup_packet_t *request, 79 uint8_t *data); 45 typedef int (*usbvirt_on_data_to_device_t)(usbvirt_device_t *, usb_endpoint_t, 46 usb_transfer_type_t, void *, size_t); 47 typedef int (*usbvirt_on_data_from_device_t)(usbvirt_device_t *, usb_endpoint_t, 48 usb_transfer_type_t, void *, size_t, size_t *); 49 typedef int (*usbvirt_on_control_t)(usbvirt_device_t *, 50 const usb_device_request_setup_packet_t *, uint8_t *, size_t *); 80 51 81 /** Callback for control request over pipe zero.82 *83 * @param dev Virtual device answering the call.84 * @param request Request setup packet.85 * @param data Data when DATA stage is present.86 * @return Error code.87 */88 typedef int (*usbvirt_control_request_callback_t)(usbvirt_device_t *dev,89 usb_device_request_setup_packet_t *request,90 uint8_t *data);91 92 /** Handler for control transfer on endpoint zero. */93 52 typedef struct { 94 /** Request type bitmap. 95 * Use USBVIRT_MAKE_CONTROL_REQUEST_TYPE for creating the bitmap. 96 */ 97 uint8_t request_type; 98 /** Request code. */ 53 usb_direction_t req_direction; 54 usb_request_recipient_t req_recipient; 55 usb_request_type_t req_type; 99 56 uint8_t request; 100 /** Request name for debugging. */101 57 const char *name; 102 /** Callback for the request. 103 * NULL value here announces end of a list. 104 */ 105 usbvirt_control_request_callback_t callback; 106 } usbvirt_control_transfer_handler_t; 107 108 /** Create control request type bitmap. 109 * 110 * @param direction Transfer direction (use usb_direction_t). 111 * @param type Request type (use usbvirt_request_type_t). 112 * @param recipient Recipient of the request (use usbvirt_request_recipient_t). 113 * @return Request type bitmap. 114 */ 115 #define USBVIRT_MAKE_CONTROL_REQUEST_TYPE(direction, type, recipient) \ 116 ((((direction) == USB_DIRECTION_IN) ? 1 : 0) << 7) \ 117 | (((type) & 3) << 5) \ 118 | (((recipient) & 31)) 119 120 /** Create last item in an array of control request handlers. */ 121 #define USBVIRT_CONTROL_TRANSFER_HANDLER_LAST { 0, 0, NULL, NULL } 122 123 /** Device operations. */ 124 typedef struct { 125 /** Callbacks for transfers over control pipe zero. */ 126 usbvirt_control_transfer_handler_t *control_transfer_handlers; 127 128 int (*on_control_transfer)(usbvirt_device_t *dev, 129 usb_endpoint_t endpoint, struct usbvirt_control_transfer *transfer); 130 131 /** Callback for all other incoming data. */ 132 int (*on_data)(usbvirt_device_t *dev, 133 usb_endpoint_t endpoint, void *buffer, size_t size); 134 135 /** Callback for host request for data. */ 136 int (*on_data_request)(usbvirt_device_t *dev, 137 usb_endpoint_t endpoint, void *buffer, size_t size, size_t *actual_size); 138 139 /** Decides direction of control transfer. */ 140 usb_direction_t (*decide_control_transfer_direction)( 141 usb_endpoint_t endpoint, void *buffer, size_t size); 142 143 /** Callback when device changes its state. 144 * 145 * It is correct that this function is called when both states 146 * are equal (e.g. this function is called during SET_CONFIGURATION 147 * request done on already configured device). 148 * 149 * @warning The value of <code>dev->state</code> before calling 150 * this function is not specified (i.e. can be @p old_state or 151 * @p new_state). 152 */ 153 void (*on_state_change)(usbvirt_device_t *dev, 154 usbvirt_device_state_t old_state, usbvirt_device_state_t new_state); 155 } usbvirt_device_ops_t; 58 usbvirt_on_control_t callback; 59 } usbvirt_control_request_handler_t; 156 60 157 61 /** Extra configuration data for GET_CONFIGURATION request. */ … … 179 83 */ 180 84 usb_standard_device_descriptor_t *device; 181 85 182 86 /** Configurations. */ 183 87 usbvirt_device_configuration_t *configuration; 184 88 /** Number of configurations. */ 185 89 size_t configuration_count; 186 /** Index of currently selected configuration. */187 uint8_t current_configuration;188 90 } usbvirt_descriptors_t; 189 91 190 /** Information about on-going control transfer. 92 /** Possible states of virtual USB device. 93 * Notice that these are not 1:1 mappings to those in USB specification. 191 94 */ 192 typedef struct usbvirt_control_transfer { 193 /** Transfer direction (read/write control transfer). */ 194 usb_direction_t direction; 195 /** Request data. */ 196 void *request; 197 /** Size of request data. */ 198 size_t request_size; 199 /** Payload. */ 200 void *data; 201 /** Size of payload. */ 202 size_t data_size; 203 } usbvirt_control_transfer_t; 95 typedef enum { 96 /** Default state, device listens at default address. */ 97 USBVIRT_STATE_DEFAULT, 98 /** Device has non-default address assigned. */ 99 USBVIRT_STATE_ADDRESS, 100 /** Device is configured. */ 101 USBVIRT_STATE_CONFIGURED 102 } usbvirt_device_state_t; 204 103 205 typedef enum { 206 USBVIRT_DEBUGTAG_BASE = 1, 207 USBVIRT_DEBUGTAG_TRANSACTION = 2, 208 USBVIRT_DEBUGTAG_CONTROL_PIPE_ZERO = 4, 209 USBVIRT_DEBUGTAG_ALL = 255 210 } usbvirt_debug_tags_t; 104 typedef struct { 105 usbvirt_on_data_to_device_t data_out[USBVIRT_ENDPOINT_MAX]; 106 usbvirt_on_data_from_device_t data_in[USBVIRT_ENDPOINT_MAX]; 107 usbvirt_control_request_handler_t *control; 108 void (*state_changed)(usbvirt_device_t *dev, 109 usbvirt_device_state_t old_state, usbvirt_device_state_t new_state); 110 } usbvirt_device_ops_t; 211 111 212 /** Virtual USB device. */213 112 struct usbvirt_device { 214 /** Callback device operations. */ 113 const char *name; 114 void *device_data; 215 115 usbvirt_device_ops_t *ops; 216 217 /** Custom device data. */ 218 void *device_data; 116 usbvirt_descriptors_t *descriptors; 117 usb_address_t address; 118 usbvirt_device_state_t state; 119 }; 219 120 220 /** Reply onto control transfer. 221 */ 222 int (*control_transfer_reply)(usbvirt_device_t *dev, 223 usb_endpoint_t endpoint, void *buffer, size_t size); 224 225 /** Device name. 226 * Used in debug prints and sent to virtual host controller. 227 */ 228 const char *name; 229 230 /** Standard descriptors. */ 231 usbvirt_descriptors_t *descriptors; 232 233 /** Current device state. */ 234 usbvirt_device_state_t state; 235 236 /** Device address. */ 237 usb_address_t address; 238 /** New device address. 239 * This field is used during SET_ADDRESS request. 240 * On all other occasions, it holds invalid address (e.g. -1). 241 */ 242 usb_address_t new_address; 243 244 /** Process OUT transaction. */ 245 int (*transaction_out)(usbvirt_device_t *dev, 246 usb_endpoint_t endpoint, void *buffer, size_t size); 247 /** Process SETUP transaction. */ 248 int (*transaction_setup)(usbvirt_device_t *dev, 249 usb_endpoint_t endpoint, void *buffer, size_t size); 250 /** Process IN transaction. */ 251 int (*transaction_in)(usbvirt_device_t *dev, 252 usb_endpoint_t endpoint, void *buffer, size_t size, size_t *data_size); 253 254 /** State information on control-transfer endpoints. */ 255 usbvirt_control_transfer_t current_control_transfers[USB11_ENDPOINT_MAX]; 256 257 /* User debugging. */ 258 259 /** Debug print. */ 260 void (*debug)(usbvirt_device_t *dev, int level, uint8_t tag, 261 const char *format, ...); 262 263 /** Current debug level. */ 264 int debug_level; 265 266 /** Bitmap of currently enabled tags. */ 267 uint8_t debug_enabled_tags; 268 269 /* Library debugging. */ 270 271 /** Debug print. */ 272 void (*lib_debug)(usbvirt_device_t *dev, int level, uint8_t tag, 273 const char *format, ...); 274 275 /** Current debug level. */ 276 int lib_debug_level; 277 278 /** Bitmap of currently enabled tags. */ 279 uint8_t lib_debug_enabled_tags; 280 }; 121 int usbvirt_device_plug(usbvirt_device_t *, const char *); 122 123 void usbvirt_control_reply_helper(const usb_device_request_setup_packet_t *, 124 uint8_t *, size_t *, void *, size_t); 125 126 int usbvirt_control_write(usbvirt_device_t *, void *, size_t, void *, size_t); 127 int usbvirt_control_read(usbvirt_device_t *, void *, size_t, void *, size_t, size_t *); 128 int usbvirt_data_out(usbvirt_device_t *, usb_transfer_type_t, usb_endpoint_t, 129 void *, size_t); 130 int usbvirt_data_in(usbvirt_device_t *, usb_transfer_type_t, usb_endpoint_t, 131 void *, size_t, size_t *); 132 281 133 282 134 #endif -
uspace/lib/usbvirt/include/usbvirt/ipc.h
r48d1c228 r6cb58e6 33 33 * @brief Virtual USB device. 34 34 */ 35 #ifndef LIBUSBVIRT_ HUB_H_36 #define LIBUSBVIRT_ HUB_H_35 #ifndef LIBUSBVIRT_IPC_H_ 36 #define LIBUSBVIRT_IPC_H_ 37 37 38 #include "device.h" 38 #include <ipc/common.h> 39 #include <usb/usb.h> 40 #include <bool.h> 39 41 40 /** USB transaction type.41 * This types does not correspond directly to types in USB specification,42 * as actually DATA transactions are marked with these types to identify43 * their direction (and tag).44 */45 42 typedef enum { 46 USBVIRT_TRANSACTION_SETUP, 47 USBVIRT_TRANSACTION_IN, 48 USBVIRT_TRANSACTION_OUT 49 } usbvirt_transaction_type_t; 43 IPC_M_USBVIRT_GET_NAME = IPC_FIRST_USER_METHOD + 80, 44 IPC_M_USBVIRT_CONTROL_READ, 45 IPC_M_USBVIRT_CONTROL_WRITE, 46 IPC_M_USBVIRT_INTERRUPT_IN, 47 IPC_M_USBVIRT_INTERRUPT_OUT 48 } usbvirt_ipc_t; 50 49 51 const char *usbvirt_str_transaction_type(usbvirt_transaction_type_t type); 50 int usbvirt_ipc_send_control_read(int, usb_endpoint_t, void *, size_t, 51 void *, size_t, size_t *); 52 int usbvirt_ipc_send_control_write(int, usb_endpoint_t, void *, size_t, 53 void *, size_t); 54 int usbvirt_ipc_send_data_in(int, usb_endpoint_t, usb_transfer_type_t, 55 void *, size_t, size_t *); 56 int usbvirt_ipc_send_data_out(int, usb_endpoint_t, usb_transfer_type_t, 57 void *, size_t); 52 58 53 /** Telephony methods of virtual devices. */ 54 typedef enum { 55 IPC_M_USBVIRT_GET_NAME = IPC_FIRST_USER_METHOD, 56 IPC_M_USBVIRT_TRANSACTION_SETUP, 57 IPC_M_USBVIRT_TRANSACTION_OUT, 58 IPC_M_USBVIRT_TRANSACTION_IN, 59 } usbvirt_device_method_t; 60 61 int usbvirt_connect(usbvirt_device_t *); 62 int usbvirt_connect_local(usbvirt_device_t *); 63 int usbvirt_disconnect(usbvirt_device_t *dev); 59 bool usbvirt_is_usbvirt_method(sysarg_t); 60 bool usbvirt_ipc_handle_call(usbvirt_device_t *, ipc_callid_t, ipc_call_t *); 64 61 65 62 #endif -
uspace/lib/usbvirt/src/private.h
r48d1c228 r6cb58e6 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 */ 1 #include <usbvirt/device.h> 28 2 29 /** @addtogroup libusbvirt 30 * @{ 31 */ 32 /** @file 33 * @brief Virtual USB private header. 34 */ 35 #ifndef LIBUSBVIRT_PRIVATE_H_ 36 #define LIBUSBVIRT_PRIVATE_H_ 3 int process_control_transfer(usbvirt_device_t *, 4 usbvirt_control_request_handler_t *, 5 usb_device_request_setup_packet_t *, 6 uint8_t *, size_t *); 37 7 38 #include <usbvirt/device.h> 39 #include <usbvirt/hub.h> 40 #include <assert.h> 41 42 43 #define DEVICE_HAS_OP(dev, op) \ 44 ( \ 45 ( ((dev)->ops) != NULL ) \ 46 && \ 47 ( ((dev)->ops->op) != NULL ) \ 48 ) 49 50 int usbvirt_data_to_host(struct usbvirt_device *dev, 51 usb_endpoint_t endpoint, void *buffer, size_t size); 52 53 int handle_incoming_data(struct usbvirt_device *dev, 54 usb_endpoint_t endpoint, void *buffer, size_t size); 55 56 int control_pipe(usbvirt_device_t *device, usbvirt_control_transfer_t *transfer); 57 58 int handle_std_request(usbvirt_device_t *device, usb_device_request_setup_packet_t *request, uint8_t *data); 59 60 void device_callback_connection(usbvirt_device_t *device, ipc_callid_t iid, ipc_call_t *icall); 61 62 int transaction_setup(usbvirt_device_t *device, usb_endpoint_t endpoint, 63 void *buffer, size_t size); 64 int transaction_out(usbvirt_device_t *device, usb_endpoint_t endpoint, 65 void *buffer, size_t size); 66 int transaction_in(usbvirt_device_t *device, usb_endpoint_t endpoint, 67 void *buffer, size_t size, size_t *data_size); 68 69 70 void user_debug(usbvirt_device_t *device, int level, uint8_t tag, 71 const char *format, ...); 72 void lib_debug(usbvirt_device_t *device, int level, uint8_t tag, 73 const char *format, ...); 74 75 static inline const char *str_device_state(usbvirt_device_state_t state) 76 { 77 switch (state) { 78 case USBVIRT_STATE_DEFAULT: 79 return "default"; 80 case USBVIRT_STATE_ADDRESS: 81 return "address"; 82 case USBVIRT_STATE_CONFIGURED: 83 return "configured"; 84 default: 85 return "unknown"; 86 } 87 } 88 89 extern usbvirt_control_transfer_handler_t control_pipe_zero_local_handlers[]; 90 91 #endif 92 /** 93 * @} 94 */ 8 extern usbvirt_control_request_handler_t library_handlers[]; -
uspace/lib/usbvirt/src/stdreq.c
r48d1c228 r6cb58e6 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 */ 1 #include "private.h" 2 #include <usb/request.h> 3 #include <assert.h> 4 #include <errno.h> 28 5 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> 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 } 39 14 40 #include "private.h" 15 memcpy(data, actual_data, actual_data_size); 41 16 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 17 if (act_size != NULL) { 18 *act_size = actual_data_size; 19 } 20 } 21 49 22 /** GET_DESCRIPTOR handler. */ 50 static int handle_get_descriptor(usbvirt_device_t *device,51 usb_device_request_setup_packet_t *setup_packet, uint8_t *extra_data)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) 52 25 { 53 26 uint8_t type = setup_packet->value_high; 54 27 uint8_t index = setup_packet->value_low; 55 28 56 /* 29 /* 57 30 * Standard device descriptor. 58 31 */ 59 32 if ((type == USB_DESCTYPE_DEVICE) && (index == 0)) { 60 33 if (device->descriptors && device->descriptors->device) { 61 return device->control_transfer_reply(device, 0,34 usbvirt_control_reply_helper(setup_packet, data, act_size, 62 35 device->descriptors->device, 63 36 device->descriptors->device->length); 37 return EOK; 64 38 } else { 65 39 return EFORWARD; 66 40 } 67 41 } 68 42 69 43 /* 70 44 * Configuration descriptor together with interface, endpoint and … … 85 59 return ENOMEM; 86 60 } 87 61 88 62 uint8_t *ptr = all_data; 89 63 memcpy(ptr, config->descriptor, config->descriptor->length); … … 96 70 ptr += extra->length; 97 71 } 98 99 int rc = device->control_transfer_reply(device, 0,72 73 usbvirt_control_reply_helper(setup_packet, data, act_size, 100 74 all_data, config->descriptor->total_length); 101 75 102 76 free(all_data); 103 104 return rc;77 78 return EOK; 105 79 } 106 80 107 81 return EFORWARD; 108 82 } 109 83 110 /** SET_ADDRESS handler. */ 111 static int handle_set_address(usbvirt_device_t *device, 112 usb_device_request_setup_packet_t *setup_packet, uint8_t *extra_data) 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) 113 86 { 114 87 uint16_t new_address = setup_packet->value; … … 119 92 return EINVAL; 120 93 } 121 94 122 95 if (new_address > 127) { 123 96 return EINVAL; 124 97 } 125 126 device-> new_address = new_address;127 98 99 device->address = new_address; 100 128 101 return EOK; 129 102 } 130 103 131 /** SET_CONFIGURATION handler. */ 132 static int handle_set_configuration(usbvirt_device_t *device, 133 usb_device_request_setup_packet_t *setup_packet, uint8_t *extra_data) 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) 134 106 { 135 107 uint16_t configuration_value = setup_packet->value; … … 140 112 return EINVAL; 141 113 } 142 114 143 115 /* 144 116 * Configuration value is 1 byte information. … … 147 119 return EINVAL; 148 120 } 149 121 150 122 /* 151 123 * Do nothing when in default state. According to specification, … … 155 127 return EOK; 156 128 } 157 129 130 usbvirt_device_state_t new_state; 158 131 if (configuration_value == 0) { 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; 132 new_state = USBVIRT_STATE_ADDRESS; 164 133 } else { 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 } 134 // FIXME: check that this configuration exists 135 new_state = USBVIRT_STATE_CONFIGURED; 178 136 } 179 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 180 143 return EOK; 181 144 } 182 145 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 190 usbvirt_control_transfer_handler_t control_pipe_zero_local_handlers[] = { 146 usbvirt_control_request_handler_t library_handlers[] = { 191 147 { 192 .request_type = MAKE_BM_REQUEST_DEV(USB_DIRECTION_IN), 193 .request = USB_DEVREQ_GET_DESCRIPTOR, 194 .name = "GetDescriptor()", 195 .callback = handle_get_descriptor 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 196 154 }, 197 155 { 198 .request_type = MAKE_BM_REQUEST_DEV(USB_DIRECTION_OUT), 199 .request = USB_DEVREQ_SET_ADDRESS, 200 .name = "SetAddress()", 201 .callback = handle_set_address 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 202 162 }, 203 163 { 204 .request_type = MAKE_BM_REQUEST_DEV(USB_DIRECTION_OUT), 164 .req_direction = USB_DIRECTION_OUT, 165 .req_recipient = USB_REQUEST_RECIPIENT_DEVICE, 166 .req_type = USB_REQUEST_TYPE_STANDARD, 205 167 .request = USB_DEVREQ_SET_CONFIGURATION, 206 .name = "SetConfiguration ()",207 .callback = handle_set_configuration168 .name = "SetConfiguration", 169 .callback = req_set_configuration 208 170 }, 209 USBVIRT_CONTROL_TRANSFER_HANDLER_LAST 171 172 { .callback = NULL } 210 173 }; 211 174 212 /**213 * @}214 */
Note:
See TracChangeset
for help on using the changeset viewer.