Changeset 7a7bfeb3 in mainline for uspace/lib/usbvirt
- Timestamp:
- 2010-10-24T16:43:40Z (15 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 355f7c2
- Parents:
- b8a3cda
- Location:
- uspace/lib/usbvirt
- Files:
-
- 1 added
- 1 deleted
- 7 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/usbvirt/Makefile
rb8a3cda r7a7bfeb3 35 35 SOURCES = \ 36 36 ctrlpipe.c \ 37 incoming.c \38 37 main.c \ 39 stdreq.c 38 stdreq.c \ 39 transaction.c 40 40 41 41 include $(USPACE_PREFIX)/Makefile.common -
uspace/lib/usbvirt/ctrlpipe.c
rb8a3cda r7a7bfeb3 53 53 54 54 55 56 int control_pipe(void *buffer, size_t size) 55 int control_pipe(usbvirt_control_transfer_t *transfer) 57 56 { 58 if ( size < sizeof(usb_device_request_setup_packet_t)) {57 if (transfer->request_size < sizeof(usb_device_request_setup_packet_t)) { 59 58 return ENOMEM; 60 59 } 61 60 62 usb_device_request_setup_packet_t *request = (usb_device_request_setup_packet_t *) buffer;63 uint8_t *remaining_data = ((uint8_t *) request) + sizeof(usb_device_request_setup_packet_t);61 usb_device_request_setup_packet_t *request = (usb_device_request_setup_packet_t *) transfer->request; 62 uint8_t *remaining_data = transfer->data; 64 63 65 64 int type = request_get_type(request->request_type); … … 80 79 break; 81 80 } 82 83 device->send_data(device, 0, NULL, 0);84 81 85 82 if (dev_new_address != -1) { -
uspace/lib/usbvirt/device.h
rb8a3cda r7a7bfeb3 41 41 42 42 struct usbvirt_device; 43 struct usbvirt_control_transfer; 43 44 44 45 typedef int (*usbvirt_on_device_request_t)(struct usbvirt_device *dev, … … 70 71 /** Callback for class-specific USB request. */ 71 72 usbvirt_on_device_request_t on_class_device_request; 73 74 int (*on_control_transfer)(struct usbvirt_device *dev, 75 usb_endpoint_t endpoint, struct usbvirt_control_transfer *transfer); 76 72 77 /** Callback for all other incoming data. */ 73 78 int (*on_data)(struct usbvirt_device *dev, 79 usb_endpoint_t endpoint, void *buffer, size_t size); 80 81 /** Callback for host request for data. */ 82 int (*on_data_request)(struct usbvirt_device *dev, 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)( 74 87 usb_endpoint_t endpoint, void *buffer, size_t size); 75 88 } usbvirt_device_ops_t; … … 117 130 } usbvirt_device_state_t; 118 131 132 /** Information about on-going control transfer. 133 */ 134 typedef struct usbvirt_control_transfer { 135 usb_direction_t direction; 136 void *request; 137 size_t request_size; 138 void *data; 139 size_t data_size; 140 } usbvirt_control_transfer_t; 141 119 142 /** Virtual USB device. */ 120 143 typedef struct usbvirt_device { … … 122 145 usbvirt_device_ops_t *ops; 123 146 124 /** Send data to HC. 125 * @warning Do not change after initializing with 126 * usbvirt_device_init(). 127 * This function is here merely to make the interface more OOP. 147 148 /** Reply onto control transfer. 128 149 */ 129 int (* send_data)(struct usbvirt_device *dev,150 int (*control_transfer_reply)(struct usbvirt_device *dev, 130 151 usb_endpoint_t endpoint, void *buffer, size_t size); 131 152 … … 153 174 int device_id_; 154 175 155 /** Main routine called when data is received from HC. 156 * @warning Do not change after initializing with 157 * usbvirt_device_init(). 158 * This function is here merely to make the interface more OOP. 159 */ 160 int (*receive_data)(struct usbvirt_device *dev, 176 int (*transaction_out)(struct usbvirt_device *dev, 161 177 usb_endpoint_t endpoint, void *buffer, size_t size); 178 int (*transaction_setup)(struct usbvirt_device *dev, 179 usb_endpoint_t endpoint, void *buffer, size_t size); 180 int (*transaction_in)(struct usbvirt_device *dev, 181 usb_endpoint_t endpoint, void *buffer, size_t size, size_t *data_size); 162 182 183 usbvirt_control_transfer_t current_control_transfers[USB11_ENDPOINT_MAX]; 163 184 } usbvirt_device_t; 164 185 -
uspace/lib/usbvirt/hub.h
rb8a3cda r7a7bfeb3 41 41 typedef enum { 42 42 IPC_M_USBVIRT_DATA_TO_DEVICE = IPC_FIRST_USER_METHOD, 43 IPC_M_USBVIRT_DATA_FROM_DEVICE 43 IPC_M_USBVIRT_DATA_FROM_DEVICE, 44 IPC_M_USBVIRT_TRANSACTION_SETUP, 45 IPC_M_USBVIRT_TRANSACTION_OUT, 46 IPC_M_USBVIRT_TRANSACTION_IN, 44 47 } usbvirt_device_method_t; 45 48 -
uspace/lib/usbvirt/main.c
rb8a3cda r7a7bfeb3 38 38 #include <errno.h> 39 39 #include <stdlib.h> 40 #include <mem.h> 40 41 41 42 #include "hub.h" … … 47 48 usbvirt_device_t *device = NULL; 48 49 49 50 static void handle_data_to_device(ipc_callid_t iid, ipc_call_t icall) 50 static void handle_setup_transaction(ipc_callid_t iid, ipc_call_t icall) 51 51 { 52 52 usb_address_t address = IPC_GET_ARG1(icall); 53 53 usb_endpoint_t endpoint = IPC_GET_ARG2(icall); 54 size_t expected_len = IPC_GET_ARG 5(icall);54 size_t expected_len = IPC_GET_ARG3(icall); 55 55 56 56 if (address != device->address) { … … 59 59 } 60 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 61 71 size_t len = 0; 62 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 63 108 if (expected_len > 0) { 64 int rc = async_data_write_accept(&buffer, false, 65 1, USB_MAX_PAYLOAD_SIZE, 66 0, &len); 67 109 rc = async_data_write_accept(&buffer, false, 110 1, USB_MAX_PAYLOAD_SIZE, 0, &len); 111 68 112 if (rc != EOK) { 69 113 ipc_answer_0(iid, rc); … … 72 116 } 73 117 74 device->receive_data(device, endpoint, buffer, len);118 rc = device->transaction_out(device, endpoint, buffer, len); 75 119 76 120 if (buffer != NULL) { … … 78 122 } 79 123 80 ipc_answer_0(iid, EOK); 81 } 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; 159 } 160 async_data_read_finalize(iid, buffer, receive_len); 161 } 162 163 ipc_answer_0(iid, rc); 164 } 165 166 82 167 83 168 static void callback_connection(ipc_callid_t iid, ipc_call_t *icall) … … 95 180 return; 96 181 97 case IPC_M_USBVIRT_DATA_TO_DEVICE: 98 handle_data_to_device(callid, call); 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); 99 192 break; 100 193 … … 106 199 } 107 200 201 static int control_transfer_reply(struct usbvirt_device *device, 202 usb_endpoint_t endpoint, void *buffer, size_t size) 203 { 204 usbvirt_control_transfer_t *transfer = &device->current_control_transfers[endpoint]; 205 if (transfer->data != NULL) { 206 free(transfer->data); 207 } 208 transfer->data = malloc(size); 209 memcpy(transfer->data, buffer, size); 210 transfer->data_size = size; 211 212 return EOK; 213 } 214 108 215 static void device_init(usbvirt_device_t *dev) 109 216 { 110 dev->send_data = usbvirt_data_to_host; 111 dev->receive_data = handle_incoming_data; 217 dev->transaction_out = transaction_out; 218 dev->transaction_setup = transaction_setup; 219 dev->transaction_in = transaction_in; 220 221 dev->control_transfer_reply = control_transfer_reply; 222 112 223 dev->state = USBVIRT_STATE_DEFAULT; 113 224 dev->address = 0; 114 } 115 116 int usbvirt_data_to_host(struct usbvirt_device *dev, 117 usb_endpoint_t endpoint, void *buffer, size_t size) 118 { 119 int phone = dev->vhcd_phone_; 120 121 if (phone < 0) { 122 return EINVAL; 123 } 124 if ((buffer == NULL) && (size != 0)) { 125 return EINVAL; 126 } 127 128 ipc_call_t answer_data; 129 ipcarg_t answer_rc; 130 aid_t req; 131 int rc; 132 133 req = async_send_3(phone, 134 IPC_M_USBVIRT_DATA_FROM_DEVICE, 135 dev->address, 136 endpoint, 137 size, 138 &answer_data); 139 140 if (size > 0) { 141 rc = async_data_write_start(phone, buffer, size); 142 if (rc != EOK) { 143 async_wait_for(req, NULL); 144 return rc; 145 } 146 } 147 148 async_wait_for(req, &answer_rc); 149 rc = (int)answer_rc; 150 if (rc != EOK) { 151 return rc; 152 } 153 154 return EOK; 225 226 size_t i; 227 for (i = 0; i < USB11_ENDPOINT_MAX; i++) { 228 usbvirt_control_transfer_t *transfer = &dev->current_control_transfers[i]; 229 transfer->direction = 0; 230 transfer->request = NULL; 231 transfer->request_size = 0; 232 transfer->data = NULL; 233 transfer->data_size = 0; 234 } 155 235 } 156 236 -
uspace/lib/usbvirt/private.h
rb8a3cda r7a7bfeb3 54 54 usb_endpoint_t endpoint, void *buffer, size_t size); 55 55 56 int control_pipe( void *buffer, size_t size);56 int control_pipe(usbvirt_control_transfer_t *transfer); 57 57 58 58 int handle_std_request(usb_device_request_setup_packet_t *request, uint8_t *data); … … 60 60 extern usb_address_t dev_new_address; 61 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 62 69 #endif 63 70 /** -
uspace/lib/usbvirt/stdreq.c
rb8a3cda r7a7bfeb3 57 57 if ((type == USB_DESCTYPE_DEVICE) && (index == 0)) { 58 58 if (device->descriptors && device->descriptors->device) { 59 return device-> send_data(device, 0,59 return device->control_transfer_reply(device, 0, 60 60 device->descriptors->device, 61 61 device->descriptors->device->length); … … 95 95 } 96 96 97 int rc = device-> send_data(device, 0, all_data,98 config->descriptor->total_length);97 int rc = device->control_transfer_reply(device, 0, 98 all_data, config->descriptor->total_length); 99 99 100 100 free(all_data);
Note:
See TracChangeset
for help on using the changeset viewer.