Changes in uspace/lib/usbvirt/src/stdreq.c [6cb58e6:0f21c0c] in mainline
- 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 1 40 #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 22 49 /** 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)50 static int handle_get_descriptor(usbvirt_device_t *device, 51 usb_device_request_setup_packet_t *setup_packet, uint8_t *extra_data) 25 52 { 26 53 uint8_t type = setup_packet->value_high; 27 54 uint8_t index = setup_packet->value_low; 28 55 29 /* 56 /* 30 57 * Standard device descriptor. 31 58 */ 32 59 if ((type == USB_DESCTYPE_DEVICE) && (index == 0)) { 33 60 if (device->descriptors && device->descriptors->device) { 34 usbvirt_control_reply_helper(setup_packet, data, act_size,61 return device->control_transfer_reply(device, 0, 35 62 device->descriptors->device, 36 63 device->descriptors->device->length); 37 return EOK;38 64 } else { 39 65 return EFORWARD; 40 66 } 41 67 } 42 68 43 69 /* 44 70 * Configuration descriptor together with interface, endpoint and … … 59 85 return ENOMEM; 60 86 } 61 87 62 88 uint8_t *ptr = all_data; 63 89 memcpy(ptr, config->descriptor, config->descriptor->length); … … 70 96 ptr += extra->length; 71 97 } 72 73 usbvirt_control_reply_helper(setup_packet, data, act_size,98 99 int rc = device->control_transfer_reply(device, 0, 74 100 all_data, config->descriptor->total_length); 75 101 76 102 free(all_data); 77 78 return EOK;79 } 80 103 104 return rc; 105 } 106 81 107 return EFORWARD; 82 108 } 83 109 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. */ 111 static int handle_set_address(usbvirt_device_t *device, 112 usb_device_request_setup_packet_t *setup_packet, uint8_t *extra_data) 86 113 { 87 114 uint16_t new_address = setup_packet->value; … … 92 119 return EINVAL; 93 120 } 94 121 95 122 if (new_address > 127) { 96 123 return EINVAL; 97 124 } 98 99 device-> address = new_address;100 125 126 device->new_address = new_address; 127 101 128 return EOK; 102 129 } 103 130 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. */ 132 static int handle_set_configuration(usbvirt_device_t *device, 133 usb_device_request_setup_packet_t *setup_packet, uint8_t *extra_data) 106 134 { 107 135 uint16_t configuration_value = setup_packet->value; … … 112 140 return EINVAL; 113 141 } 114 142 115 143 /* 116 144 * Configuration value is 1 byte information. … … 119 147 return EINVAL; 120 148 } 121 149 122 150 /* 123 151 * Do nothing when in default state. According to specification, … … 127 155 return EOK; 128 156 } 129 130 usbvirt_device_state_t new_state; 157 131 158 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; 133 164 } 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 143 180 return EOK; 144 181 } 145 182 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 190 usbvirt_control_transfer_handler_t control_pipe_zero_local_handlers[] = { 147 191 { 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 154 196 }, 155 197 { 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 162 202 }, 163 203 { 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), 167 205 .request = USB_DEVREQ_SET_CONFIGURATION, 168 .name = "SetConfiguration ",169 .callback = req_set_configuration206 .name = "SetConfiguration()", 207 .callback = handle_set_configuration 170 208 }, 171 172 { .callback = NULL } 209 USBVIRT_CONTROL_TRANSFER_HANDLER_LAST 173 210 }; 174 211 212 /** 213 * @} 214 */
Note:
See TracChangeset
for help on using the changeset viewer.