Changeset 7a7bfeb3 in mainline for uspace/lib/usbvirt/main.c
- 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
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
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
Note:
See TracChangeset
for help on using the changeset viewer.