Changeset ca07cd3 in mainline
- Timestamp:
- 2010-10-25T13:23:33Z (14 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 23cb44b
- Parents:
- 355f7c2
- Location:
- uspace
- Files:
-
- 1 added
- 1 deleted
- 14 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/app/virtusbkbd/virtusbkbd.c
r355f7c2 rca07cd3 50 50 #include <usbvirt/device.h> 51 51 #include <usbvirt/hub.h> 52 #include <usbvirt/ids.h>53 52 54 53 #include "kbdconfig.h" … … 154 153 .ops = &keyboard_ops, 155 154 .descriptors = &descriptors, 156 . device_id_ = USBVIRT_DEV_KEYBOARD_ID155 .name = "keyboard" 157 156 }; 158 157 … … 230 229 printf("%s: Terminating...\n", NAME); 231 230 232 usbvirt_disconnect( );231 usbvirt_disconnect(&keyboard_dev); 233 232 234 233 return 0; -
uspace/lib/usbvirt/Makefile
r355f7c2 rca07cd3 34 34 35 35 SOURCES = \ 36 callback.c \ 36 37 ctrlpipe.c \ 37 38 main.c \ -
uspace/lib/usbvirt/ctrlpipe.c
r355f7c2 rca07cd3 47 47 usb_address_t dev_new_address = -1; 48 48 49 /** Tell request type. 50 * By type is meant either standard, class, vendor or other. 51 */ 49 52 static int request_get_type(uint8_t request_type) 50 53 { … … 52 55 } 53 56 54 55 int control_pipe(usbvirt_control_transfer_t *transfer) 57 /** Handle communication over control pipe zero. 58 */ 59 int control_pipe(usbvirt_device_t *device, usbvirt_control_transfer_t *transfer) 56 60 { 57 61 if (transfer->request_size < sizeof(usb_device_request_setup_packet_t)) { … … 68 72 switch (type) { 69 73 case REQUEST_TYPE_STANDARD: 70 rc = handle_std_request( request, remaining_data);74 rc = handle_std_request(device, request, remaining_data); 71 75 break; 72 76 case REQUEST_TYPE_CLASS: … … 80 84 } 81 85 82 if (dev _new_address != -1) {86 if (device->new_address != -1) { 83 87 /* 84 88 * TODO: handle when this request is invalid (e.g. 85 89 * setting address when in configured state). 86 90 */ 87 if (dev _new_address == 0) {91 if (device->new_address == 0) { 88 92 device->state = USBVIRT_STATE_DEFAULT; 89 93 } else { 90 94 device->state = USBVIRT_STATE_ADDRESS; 91 95 } 92 device->address = dev _new_address;96 device->address = device->new_address; 93 97 94 dev _new_address = -1;98 device->new_address = -1; 95 99 } 96 100 -
uspace/lib/usbvirt/device.h
r355f7c2 rca07cd3 40 40 #include <usb/devreq.h> 41 41 42 struct usbvirt_device;42 typedef struct usbvirt_device usbvirt_device_t; 43 43 struct usbvirt_control_transfer; 44 44 45 typedef int (*usbvirt_on_device_request_t)( struct usbvirt_device*dev,45 typedef int (*usbvirt_on_device_request_t)(usbvirt_device_t *dev, 46 46 usb_device_request_setup_packet_t *request, 47 47 uint8_t *data); … … 72 72 usbvirt_on_device_request_t on_class_device_request; 73 73 74 int (*on_control_transfer)( struct usbvirt_device*dev,74 int (*on_control_transfer)(usbvirt_device_t *dev, 75 75 usb_endpoint_t endpoint, struct usbvirt_control_transfer *transfer); 76 76 77 77 /** Callback for all other incoming data. */ 78 int (*on_data)( struct usbvirt_device*dev,78 int (*on_data)(usbvirt_device_t *dev, 79 79 usb_endpoint_t endpoint, void *buffer, size_t size); 80 80 81 81 /** Callback for host request for data. */ 82 int (*on_data_request)( struct usbvirt_device*dev,82 int (*on_data_request)(usbvirt_device_t *dev, 83 83 usb_endpoint_t endpoint, void *buffer, size_t size, size_t *actual_size); 84 84 … … 133 133 */ 134 134 typedef struct usbvirt_control_transfer { 135 /** Transfer direction (read/write control transfer). */ 135 136 usb_direction_t direction; 137 /** Request data. */ 136 138 void *request; 139 /** Size of request data. */ 137 140 size_t request_size; 141 /** Payload. */ 138 142 void *data; 143 /** Size of payload. */ 139 144 size_t data_size; 140 145 } usbvirt_control_transfer_t; 141 146 142 147 /** Virtual USB device. */ 143 typedefstruct usbvirt_device {148 struct usbvirt_device { 144 149 /** Callback device operations. */ 145 150 usbvirt_device_ops_t *ops; 146 151 147 148 152 /** Reply onto control transfer. 149 153 */ 150 int (*control_transfer_reply)( struct usbvirt_device*dev,154 int (*control_transfer_reply)(usbvirt_device_t *dev, 151 155 usb_endpoint_t endpoint, void *buffer, size_t size); 152 156 153 /* Device attributes. */ 157 /** Device name. 158 * Used in debug prints and sent to virtual host controller. 159 */ 160 const char *name; 154 161 155 162 /** Standard descriptors. */ … … 158 165 /** Current device state. */ 159 166 usbvirt_device_state_t state; 167 160 168 /** Device address. */ 161 169 usb_address_t address; 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). 173 */ 174 usb_address_t new_address; 162 175 163 /* Private attributes. */ 164 165 /** Phone to HC. 166 * @warning Do not change, this is private variable. 167 */ 168 int vhcd_phone_; 169 170 /** Device id. 171 * This item will be removed when device enumeration and 172 * recognition is implemented. 173 */ 174 int device_id_; 175 176 int (*transaction_out)(struct usbvirt_device *dev, 176 /** Process OUT transaction. */ 177 int (*transaction_out)(usbvirt_device_t *dev, 177 178 usb_endpoint_t endpoint, void *buffer, size_t size); 178 int (*transaction_setup)(struct usbvirt_device *dev, 179 /** Process SETUP transaction. */ 180 int (*transaction_setup)(usbvirt_device_t *dev, 179 181 usb_endpoint_t endpoint, void *buffer, size_t size); 180 int (*transaction_in)(struct usbvirt_device *dev, 182 /** Process IN transaction. */ 183 int (*transaction_in)(usbvirt_device_t *dev, 181 184 usb_endpoint_t endpoint, void *buffer, size_t size, size_t *data_size); 182 185 186 /** State information on control-transfer endpoints. */ 183 187 usbvirt_control_transfer_t current_control_transfers[USB11_ENDPOINT_MAX]; 184 } usbvirt_device_t;188 }; 185 189 186 190 #endif -
uspace/lib/usbvirt/hub.h
r355f7c2 rca07cd3 38 38 #include "device.h" 39 39 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 identify 43 * their direction (and tag). 44 */ 45 typedef enum { 46 USBVIRT_TRANSACTION_SETUP, 47 USBVIRT_TRANSACTION_IN, 48 USBVIRT_TRANSACTION_OUT 49 } usbvirt_transaction_type_t; 40 50 51 const char *usbvirt_str_transaction_type(usbvirt_transaction_type_t type); 52 53 /** Telephony methods of virtual devices. */ 41 54 typedef enum { 42 IPC_M_USBVIRT_DATA_TO_DEVICE = IPC_FIRST_USER_METHOD, 43 IPC_M_USBVIRT_DATA_FROM_DEVICE, 55 IPC_M_USBVIRT_GET_NAME = IPC_FIRST_USER_METHOD, 44 56 IPC_M_USBVIRT_TRANSACTION_SETUP, 45 57 IPC_M_USBVIRT_TRANSACTION_OUT, … … 48 60 49 61 int usbvirt_connect(usbvirt_device_t *, const char *); 50 int usbvirt_disconnect(void);51 62 int usbvirt_connect_local(usbvirt_device_t *); 63 int usbvirt_disconnect(usbvirt_device_t *dev); 52 64 53 65 #endif -
uspace/lib/usbvirt/main.c
r355f7c2 rca07cd3 31 31 */ 32 32 /** @file 33 * @brief Main handler for virtual USB device.33 * @brief Device registration with virtual USB framework. 34 34 */ 35 35 #include <devmap.h> … … 39 39 #include <stdlib.h> 40 40 #include <mem.h> 41 #include <assert.h> 41 42 42 43 #include "hub.h" … … 46 47 #define NAMESPACE "usb" 47 48 48 usbvirt_device_t *device = NULL; 49 50 static void handle_setup_transaction(ipc_callid_t iid, ipc_call_t icall) 51 { 52 usb_address_t address = IPC_GET_ARG1(icall); 53 usb_endpoint_t endpoint = IPC_GET_ARG2(icall); 54 size_t expected_len = IPC_GET_ARG3(icall); 55 56 if (address != device->address) { 57 ipc_answer_0(iid, EADDRNOTAVAIL); 58 return; 59 } 60 61 if ((endpoint < 0) || (endpoint >= USB11_ENDPOINT_MAX)) { 62 ipc_answer_0(iid, EINVAL); 63 return; 64 } 65 66 if (expected_len == 0) { 67 ipc_answer_0(iid, EINVAL); 68 return; 69 } 70 71 size_t len = 0; 72 void * buffer = NULL; 73 int rc = async_data_write_accept(&buffer, false, 74 1, USB_MAX_PAYLOAD_SIZE, 0, &len); 75 76 if (rc != EOK) { 77 ipc_answer_0(iid, rc); 78 return; 79 } 80 81 rc = device->transaction_setup(device, endpoint, buffer, len); 82 83 ipc_answer_0(iid, rc); 84 } 85 86 87 static void handle_out_transaction(ipc_callid_t iid, ipc_call_t icall) 88 { 89 usb_address_t address = IPC_GET_ARG1(icall); 90 usb_endpoint_t endpoint = IPC_GET_ARG2(icall); 91 size_t expected_len = IPC_GET_ARG3(icall); 92 93 if (address != device->address) { 94 ipc_answer_0(iid, EADDRNOTAVAIL); 95 return; 96 } 97 98 if ((endpoint < 0) || (endpoint >= USB11_ENDPOINT_MAX)) { 99 ipc_answer_0(iid, EINVAL); 100 return; 101 } 102 103 int rc = EOK; 104 105 size_t len = 0; 106 void *buffer = NULL; 107 108 if (expected_len > 0) { 109 rc = async_data_write_accept(&buffer, false, 110 1, USB_MAX_PAYLOAD_SIZE, 0, &len); 111 112 if (rc != EOK) { 113 ipc_answer_0(iid, rc); 114 return; 49 /** Virtual device wrapper. */ 50 typedef struct { 51 /** Actual device. */ 52 usbvirt_device_t *device; 53 /** Phone to host controller. */ 54 int vhcd_phone; 55 /** Device id. */ 56 ipcarg_t id; 57 /** Linked-list member. */ 58 link_t link; 59 } virtual_device_t; 60 61 /*** List of known device. */ 62 static LIST_INITIALIZE(device_list); 63 64 /** Find virtual device wrapper based on the contents. */ 65 static virtual_device_t *find_device(usbvirt_device_t *device) 66 { 67 if (list_empty(&device_list)) { 68 return NULL; 69 } 70 71 link_t *pos; 72 for (pos = device_list.next; pos != &device_list; pos = pos->next) { 73 virtual_device_t *dev 74 = list_get_instance(pos, virtual_device_t, link); 75 if (dev->device == device) { 76 return dev; 115 77 } 116 78 } 117 79 118 rc = device->transaction_out(device, endpoint, buffer, len); 119 120 if (buffer != NULL) { 121 free(buffer); 122 } 123 124 ipc_answer_0(iid, rc); 125 } 126 127 128 129 static void handle_in_transaction(ipc_callid_t iid, ipc_call_t icall) 130 { 131 usb_address_t address = IPC_GET_ARG1(icall); 132 usb_endpoint_t endpoint = IPC_GET_ARG2(icall); 133 size_t expected_len = IPC_GET_ARG3(icall); 134 135 if (address != device->address) { 136 ipc_answer_0(iid, EADDRNOTAVAIL); 137 return; 138 } 139 140 if ((endpoint < 0) || (endpoint >= USB11_ENDPOINT_MAX)) { 141 ipc_answer_0(iid, EINVAL); 142 return; 143 } 144 145 int rc = EOK; 146 147 void *buffer = expected_len > 0 ? malloc(expected_len) : NULL; 148 size_t len; 149 150 rc = device->transaction_in(device, endpoint, buffer, expected_len, &len); 151 /* 152 * If the request was processed, we will send data back. 153 */ 154 if (rc == EOK) { 155 size_t receive_len; 156 if (!async_data_read_receive(&iid, &receive_len)) { 157 ipc_answer_0(iid, EINVAL); 158 return; 80 return NULL; 81 } 82 83 /** Find virtual device wrapper by its id. */ 84 static virtual_device_t *find_device_by_id(ipcarg_t id) 85 { 86 if (list_empty(&device_list)) { 87 return NULL; 88 } 89 90 link_t *pos; 91 for (pos = device_list.next; pos != &device_list; pos = pos->next) { 92 virtual_device_t *dev 93 = list_get_instance(pos, virtual_device_t, link); 94 if (dev->id == id) { 95 return dev; 159 96 } 160 async_data_read_finalize(iid, buffer, receive_len); 161 } 162 163 ipc_answer_0(iid, rc); 164 } 165 166 167 168 static void callback_connection(ipc_callid_t iid, ipc_call_t *icall) 169 { 170 ipc_answer_0(iid, EOK); 171 172 while (true) { 173 ipc_callid_t callid; 174 ipc_call_t call; 175 176 callid = async_get_call(&call); 177 switch (IPC_GET_METHOD(call)) { 178 case IPC_M_PHONE_HUNGUP: 179 ipc_answer_0(callid, EOK); 180 return; 181 182 case IPC_M_USBVIRT_TRANSACTION_SETUP: 183 handle_setup_transaction(callid, call); 184 break; 185 186 case IPC_M_USBVIRT_TRANSACTION_OUT: 187 handle_out_transaction(callid, call); 188 break; 189 190 case IPC_M_USBVIRT_TRANSACTION_IN: 191 handle_in_transaction(callid, call); 192 break; 193 194 default: 195 ipc_answer_0(callid, EINVAL); 196 break; 197 } 198 } 199 } 200 201 static int control_transfer_reply(struct usbvirt_device *device, 97 } 98 99 return NULL; 100 } 101 102 /** Reply to a control transfer. */ 103 static int control_transfer_reply(usbvirt_device_t *device, 202 104 usb_endpoint_t endpoint, void *buffer, size_t size) 203 105 { … … 213 115 } 214 116 117 /** Initialize virtual device. */ 215 118 static void device_init(usbvirt_device_t *dev) 216 119 { … … 223 126 dev->state = USBVIRT_STATE_DEFAULT; 224 127 dev->address = 0; 128 dev->new_address = -1; 225 129 226 130 size_t i; … … 235 139 } 236 140 141 /** Add a virtual device. 142 * The returned device (if not NULL) shall be destroy via destroy_device(). 143 */ 144 static virtual_device_t *add_device(usbvirt_device_t *dev) 145 { 146 assert(find_device(dev) == NULL); 147 virtual_device_t *new_device 148 = (virtual_device_t *) malloc(sizeof(virtual_device_t)); 149 150 new_device->device = dev; 151 link_initialize(&new_device->link); 152 153 list_append(&new_device->link, &device_list); 154 155 return new_device; 156 } 157 158 /** Destroy virtual device. */ 159 static void destroy_device(virtual_device_t *dev) 160 { 161 if (dev->vhcd_phone > 0) { 162 ipc_hangup(dev->vhcd_phone); 163 } 164 165 list_remove(&dev->link); 166 167 free(dev); 168 } 169 170 /** Callback connection handler. */ 171 static void callback_connection(ipc_callid_t iid, ipc_call_t *icall) 172 { 173 // FIXME - determine which device just called back 174 virtual_device_t *dev = find_device_by_id(0); 175 if (dev == NULL) { 176 ipc_answer_0(iid, EINVAL); 177 printf("Ooops\n"); 178 return; 179 } 180 181 device_callback_connection(dev->device, iid, icall); 182 } 183 237 184 /** Create necessary phones for comunication with virtual HCD. 238 185 * This function wraps following calls: … … 254 201 int usbvirt_connect(usbvirt_device_t *dev, const char *hcd_path) 255 202 { 203 virtual_device_t *virtual_device = find_device(dev); 204 if (virtual_device != NULL) { 205 return EEXISTS; 206 } 207 256 208 char dev_path[DEVMAP_NAME_MAXLEN + 1]; 257 209 snprintf(dev_path, DEVMAP_NAME_MAXLEN, … … 270 222 271 223 ipcarg_t phonehash; 272 int rc = ipc_connect_to_me(hcd_phone, 1, dev->device_id_, 0, &phonehash);224 int rc = ipc_connect_to_me(hcd_phone, 1, 0, 0, &phonehash); 273 225 if (rc != EOK) { 274 226 return rc; 275 227 } 276 228 277 dev->vhcd_phone_ = hcd_phone;278 229 device_init(dev); 279 230 280 device = dev; 231 virtual_device = add_device(dev); 232 virtual_device->vhcd_phone = hcd_phone; 233 virtual_device->id = 0; 281 234 282 235 async_new_connection(phonehash, 0, NULL, callback_connection); … … 290 243 * 291 244 * @param dev Device to connect. 292 * @return Always EOK. 245 * @return Error code. 246 * @retval EOK Device connected. 247 * @retval EEXISTS This device is already connected. 293 248 */ 294 249 int usbvirt_connect_local(usbvirt_device_t *dev) 295 250 { 296 dev->vhcd_phone_ = -1; 251 virtual_device_t *virtual_device = find_device(dev); 252 if (virtual_device != NULL) { 253 return EEXISTS; 254 } 255 297 256 device_init(dev); 298 257 299 device = dev; 258 virtual_device = add_device(dev); 259 virtual_device->vhcd_phone = -1; 260 virtual_device->id = 0; 300 261 301 262 return EOK; … … 304 265 /** Disconnects device from HCD. 305 266 * 306 * @return Always EOK. 307 */ 308 int usbvirt_disconnect(void) 309 { 310 ipc_hangup(device->vhcd_phone_); 311 312 device = NULL; 267 * @param dev Device to be disconnected. 268 * @return Error code. 269 * @retval EOK Device connected. 270 * @retval ENOENT This device is not connected. 271 */ 272 int usbvirt_disconnect(usbvirt_device_t *dev) 273 { 274 virtual_device_t *virtual_device = find_device(dev); 275 if (virtual_device == NULL) { 276 return ENOENT; 277 } 278 279 destroy_device(virtual_device); 313 280 314 281 return EOK; -
uspace/lib/usbvirt/private.h
r355f7c2 rca07cd3 39 39 #include "hub.h" 40 40 41 extern usbvirt_device_t *device;42 41 43 42 #define DEVICE_HAS_OP(dev, op) \ … … 54 53 usb_endpoint_t endpoint, void *buffer, size_t size); 55 54 56 int control_pipe(usbvirt_ control_transfer_t *transfer);55 int control_pipe(usbvirt_device_t *device, usbvirt_control_transfer_t *transfer); 57 56 58 int handle_std_request(usb _device_request_setup_packet_t *request, uint8_t *data);57 int handle_std_request(usbvirt_device_t *device, usb_device_request_setup_packet_t *request, uint8_t *data); 59 58 60 extern usb_address_t dev_new_address;59 void device_callback_connection(usbvirt_device_t *device, ipc_callid_t iid, ipc_call_t *icall); 61 60 62 61 int transaction_setup(usbvirt_device_t *device, usb_endpoint_t endpoint, -
uspace/lib/usbvirt/stdreq.c
r355f7c2 rca07cd3 49 49 */ 50 50 51 static int handle_get_descriptor(uint8_t type, uint8_t index, uint16_t language, 51 /** GET_DESCRIPTOR handler. */ 52 static int handle_get_descriptor(usbvirt_device_t *device, 53 uint8_t type, uint8_t index, uint16_t language, 52 54 uint16_t length) 53 55 { … … 106 108 } 107 109 108 static int handle_set_address(uint16_t new_address, 110 /** SET_ADDRESS handler. */ 111 static int handle_set_address(usbvirt_device_t *device, 112 uint16_t new_address, 109 113 uint16_t zero1, uint16_t zero2) 110 114 { … … 117 121 } 118 122 119 dev _new_address = new_address;123 device->new_address = new_address; 120 124 121 125 return EOK; 122 126 } 123 127 124 static int handle_set_configuration(uint16_t configuration_value, 128 /** SET_CONFIGURATION handler. */ 129 static int handle_set_configuration(usbvirt_device_t *device, 130 uint16_t configuration_value, 125 131 uint16_t zero1, uint16_t zero2) 126 132 { … … 177 183 } while (false) 178 184 179 180 int handle_std_request(usb_device_request_setup_packet_t *request, uint8_t *data) 185 /** Handle standard device request. */ 186 int handle_std_request(usbvirt_device_t *device, 187 usb_device_request_setup_packet_t *request, uint8_t *data) 181 188 { 182 189 HANDLE_REQUEST(request, data, USB_DEVREQ_GET_DESCRIPTOR, 183 190 device, on_get_descriptor, 184 handle_get_descriptor( request->value_low, request->value_high,191 handle_get_descriptor(device, request->value_low, request->value_high, 185 192 request->index, request->length)); 186 193 187 194 HANDLE_REQUEST(request, data, USB_DEVREQ_SET_ADDRESS, 188 195 device, on_set_address, 189 handle_set_address( request->value,196 handle_set_address(device, request->value, 190 197 request->index, request->length)); 191 198 192 199 HANDLE_REQUEST(request, data, USB_DEVREQ_SET_CONFIGURATION, 193 200 device, on_set_configuration, 194 handle_set_configuration( request->value,201 handle_set_configuration(device, request->value, 195 202 request->index, request->length)); 196 203 -
uspace/lib/usbvirt/transaction.c
r355f7c2 rca07cd3 38 38 #include <mem.h> 39 39 40 #include " ids.h"40 #include "hub.h" 41 41 #include "private.h" 42 42 43 static usb_direction_t setup_transaction_direction(usb_endpoint_t, void *, size_t); 44 static void process_control_transfer(usb_endpoint_t, usbvirt_control_transfer_t *); 43 static usb_direction_t setup_transaction_direction(usbvirt_device_t *, 44 usb_endpoint_t, void *, size_t); 45 static void process_control_transfer(usbvirt_device_t *, 46 usb_endpoint_t, usbvirt_control_transfer_t *); 45 47 46 48 /** Convert virtual USB transaction type to string. … … 60 62 } 61 63 64 /** SETUP transaction handling. 65 * The setup transaction only prepares control transfer on given endpoint. 66 */ 62 67 int transaction_setup(usbvirt_device_t *device, usb_endpoint_t endpoint, 63 68 void *buffer, size_t size) … … 72 77 } 73 78 74 transfer->direction = setup_transaction_direction( endpoint,79 transfer->direction = setup_transaction_direction(device, endpoint, 75 80 buffer, size); 76 81 transfer->request = buffer; … … 79 84 transfer->data_size = 0; 80 85 86 if (transfer->direction == USB_DIRECTION_IN) { 87 process_control_transfer(device, endpoint, transfer); 88 } 89 81 90 return EOK; 82 91 } 83 92 93 /** OUT transaction handling. 94 * The OUT transaction can trigger processing of a control transfer. 95 */ 84 96 int transaction_out(usbvirt_device_t *device, usb_endpoint_t endpoint, 85 97 void *buffer, size_t size) … … 133 145 } 134 146 147 /** IN transaction handling. 148 * The IN transaction can trigger processing of a control transfer. 149 */ 135 150 int transaction_in(usbvirt_device_t *device, usb_endpoint_t endpoint, 136 151 void *buffer, size_t size, size_t *data_size) … … 145 160 * This means end of input data. 146 161 */ 147 process_control_transfer( endpoint, transfer);162 process_control_transfer(device, endpoint, transfer); 148 163 } else { 149 164 /* … … 151 166 * of the buffer. 152 167 */ 153 // TODO: implement 168 // FIXME: handle when the HC wants the data back 169 // in more chunks 170 size_t actual_size = 0; 171 if (transfer->data) { 172 actual_size = transfer->data_size; 173 } 174 if (actual_size > size) { 175 actual_size = size; 176 } 177 if (actual_size > 0) { 178 memcpy(buffer, transfer->data, actual_size); 179 if (data_size) { 180 *data_size = actual_size; 181 } 182 } 154 183 } 155 184 … … 170 199 } 171 200 172 173 static usb_direction_t setup_transaction_direction(usb_endpoint_t endpoint, 201 /** Determine direction of control transfer. 202 * First, try the user provided callback, otherwise guess, believing that 203 * it uses the same format as control pipe 0. 204 */ 205 static usb_direction_t setup_transaction_direction(usbvirt_device_t *device, 206 usb_endpoint_t endpoint, 174 207 void *data, size_t size) 175 208 { … … 202 235 } 203 236 204 static void process_control_transfer(usb_endpoint_t endpoint, 237 /** Process control transfer. 238 */ 239 static void process_control_transfer(usbvirt_device_t *device, 240 usb_endpoint_t endpoint, 205 241 usbvirt_control_transfer_t *transfer) 206 242 { … … 213 249 if (rc == EFORWARD) { 214 250 if (endpoint == 0) { 215 rc = control_pipe( transfer);251 rc = control_pipe(device, transfer); 216 252 } 217 253 } -
uspace/srv/hw/bus/usb/hcd/virtual/conndev.c
r355f7c2 rca07cd3 42 42 #include "hub.h" 43 43 44 #define DEVICE_NAME_MAXLENGTH 32 45 46 static int get_device_name(int phone, char *buffer, size_t len) 47 { 48 ipc_call_t answer_data; 49 ipcarg_t answer_rc; 50 aid_t req; 51 int rc; 52 53 req = async_send_0(phone, 54 IPC_M_USBVIRT_GET_NAME, 55 &answer_data); 56 57 rc = async_data_read_start(phone, buffer, len); 58 if (rc != EOK) { 59 async_wait_for(req, NULL); 60 return EINVAL; 61 } 62 63 async_wait_for(req, &answer_rc); 64 rc = (int)answer_rc; 65 66 if (IPC_GET_ARG1(answer_data) < len) { 67 len = IPC_GET_ARG1(answer_data); 68 } else { 69 len--; 70 } 71 buffer[len] = 0; 72 73 return rc; 74 } 75 44 76 /** Connection handler for communcation with virtual device. 45 77 * … … 53 85 assert(dev != NULL); 54 86 55 dprintf(0, "virtual device connected through phone %#x", phone_hash); 87 char devname[DEVICE_NAME_MAXLENGTH + 1]; 88 int rc = get_device_name(dev->phone, devname, DEVICE_NAME_MAXLENGTH); 89 90 dprintf(0, "virtual device connected (phone: %#x, name: %s)", 91 phone_hash, rc == EOK ? devname : "<unknown>"); 92 56 93 57 94 while (true) { -
uspace/srv/hw/bus/usb/hcd/virtual/devices.c
r355f7c2 rca07cd3 43 43 #include <str_error.h> 44 44 45 #include <usbvirt/ids.h>46 45 #include <usbvirt/hub.h> 47 46 … … 55 54 56 55 LIST_INITIALIZE(devices); 57 58 /** Recognise device by id.59 *60 * @param id Device id.61 * @param phone Callback phone.62 */63 virtdev_connection_t *virtdev_recognise(int id, int phone)64 {65 virtdev_connection_t * dev = virtdev_add_device(phone);66 67 /*68 * We do not want to mess-up the virtdev_add_device() as69 * the id is needed only before device probing/detection70 * is implemented.71 *72 * However, that does not mean that this will happen soon.73 */74 if (dev) {75 dev->id = id;76 }77 78 return dev;79 }80 56 81 57 /** Create virtual device. -
uspace/srv/hw/bus/usb/hcd/virtual/devices.h
r355f7c2 rca07cd3 45 45 /** Phone used when sending data to device. */ 46 46 int phone; 47 /** Device id. */48 int id;49 47 /** Linked-list handle. */ 50 48 link_t link; 51 49 } virtdev_connection_t; 52 50 53 virtdev_connection_t *virtdev_recognise(int, int);54 51 virtdev_connection_t *virtdev_add_device(int); 55 52 void virtdev_destroy_device(virtdev_connection_t *); -
uspace/srv/hw/bus/usb/hcd/virtual/hc.h
r355f7c2 rca07cd3 37 37 38 38 #include <usb/hcd.h> 39 #include <usbvirt/ ids.h>39 #include <usbvirt/hub.h> 40 40 41 41 /** Callback after transaction is sent to USB. -
uspace/srv/hw/bus/usb/hcd/virtual/hcd.c
r355f7c2 rca07cd3 89 89 return; 90 90 } else if (kind == 1) { 91 int device_id = IPC_GET_ARG2(call);92 91 virtdev_connection_t *dev 93 = virtdev_ recognise(device_id,callback);92 = virtdev_add_device(callback); 94 93 if (!dev) { 95 94 ipc_answer_0(callid, EEXISTS);
Note:
See TracChangeset
for help on using the changeset viewer.