Changes in / [4e38d69:03197ffc] in mainline
- Location:
- uspace
- Files:
-
- 2 added
- 3 deleted
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/c/generic/async.c
r4e38d69 r03197ffc 1567 1567 } 1568 1568 1569 /** Start IPC_M_DATA_READ using the async framework.1570 *1571 * @param phoneid Phone that will be used to contact the receiving side.1572 * @param dst Address of the beginning of the destination buffer.1573 * @param size Size of the destination buffer (in bytes).1574 * @param dataptr Storage of call data (arg 2 holds actual data size).1575 * @return Hash of the sent message or 0 on error.1576 */1577 aid_t async_data_read(int phoneid, void *dst, size_t size, ipc_call_t *dataptr)1578 {1579 return async_send_2(phoneid, IPC_M_DATA_READ, (sysarg_t) dst,1580 (sysarg_t) size, dataptr);1581 }1582 1583 1569 /** Wrapper for IPC_M_DATA_READ calls using the async framework. 1584 1570 * -
uspace/lib/c/include/async.h
r4e38d69 r03197ffc 340 340 (arg4), (answer)) 341 341 342 extern aid_t async_data_read(int, void *, size_t, ipc_call_t *);343 342 extern int async_data_read_start(int, void *, size_t); 344 343 extern bool async_data_read_receive(ipc_callid_t *, size_t *); -
uspace/lib/drv/generic/remote_usbhc.c
r4e38d69 r03197ffc 42 42 43 43 static void remote_usbhc_get_address(device_t *, void *, ipc_callid_t, ipc_call_t *); 44 static void remote_usbhc_get_buffer(device_t *, void *, ipc_callid_t, ipc_call_t *); 44 45 static void remote_usbhc_interrupt_out(device_t *, void *, ipc_callid_t, ipc_call_t *); 45 46 static void remote_usbhc_interrupt_in(device_t *, void *, ipc_callid_t, ipc_call_t *); … … 63 64 remote_usbhc_get_address, 64 65 66 remote_usbhc_get_buffer, 67 65 68 remote_usbhc_reserve_default_address, 66 69 remote_usbhc_release_default_address, … … 95 98 typedef struct { 96 99 ipc_callid_t caller; 97 ipc_callid_t data_caller;98 100 void *buffer; 99 101 void *setup_packet; … … 125 127 126 128 trans->caller = caller; 127 trans->data_caller = 0;128 129 trans->buffer = NULL; 129 130 trans->setup_packet = NULL; … … 154 155 } 155 156 157 void remote_usbhc_get_buffer(device_t *device, void *iface, 158 ipc_callid_t callid, ipc_call_t *call) 159 { 160 sysarg_t buffer_hash = DEV_IPC_GET_ARG1(*call); 161 async_transaction_t * trans = (async_transaction_t *)buffer_hash; 162 if (trans == NULL) { 163 async_answer_0(callid, ENOENT); 164 return; 165 } 166 if (trans->buffer == NULL) { 167 async_answer_0(callid, EINVAL); 168 async_transaction_destroy(trans); 169 return; 170 } 171 172 ipc_callid_t cid; 173 size_t accepted_size; 174 if (!async_data_read_receive(&cid, &accepted_size)) { 175 async_answer_0(callid, EINVAL); 176 async_transaction_destroy(trans); 177 return; 178 } 179 180 if (accepted_size > trans->size) { 181 accepted_size = trans->size; 182 } 183 async_data_read_finalize(cid, trans->buffer, accepted_size); 184 185 async_answer_1(callid, EOK, accepted_size); 186 187 async_transaction_destroy(trans); 188 } 189 156 190 void remote_usbhc_reserve_default_address(device_t *device, void *iface, 157 191 ipc_callid_t callid, ipc_call_t *call) … … 261 295 262 296 trans->size = actual_size; 263 264 if (trans->data_caller) { 265 async_data_read_finalize(trans->data_caller, 266 trans->buffer, actual_size); 267 } 268 269 async_answer_0(trans->caller, USB_OUTCOME_OK); 270 271 async_transaction_destroy(trans); 297 async_answer_1(trans->caller, USB_OUTCOME_OK, (sysarg_t)trans); 272 298 } 273 299 … … 350 376 }; 351 377 352 ipc_callid_t data_callid;353 if (!async_data_read_receive(&data_callid, &len)) {354 async_answer_0(callid, EPARTY);355 return;356 }357 358 378 async_transaction_t *trans = async_transaction_create(callid); 359 379 if (trans == NULL) { … … 361 381 return; 362 382 } 363 trans->data_caller = data_callid;364 383 trans->buffer = malloc(len); 365 384 trans->size = len; … … 611 630 } 612 631 613 ipc_callid_t data_callid;614 if (!async_data_read_receive(&data_callid, &data_len)) {615 async_answer_0(callid, EPARTY);616 free(setup_packet);617 return;618 }619 620 632 async_transaction_t *trans = async_transaction_create(callid); 621 633 if (trans == NULL) { … … 624 636 return; 625 637 } 626 trans->data_caller = data_callid;627 638 trans->setup_packet = setup_packet; 628 639 trans->size = data_len; -
uspace/lib/drv/include/usbhc_iface.h
r4e38d69 r03197ffc 66 66 * - argument #2 is target endpoint 67 67 * - argument #3 is buffer size 68 * - this call is immediately followed by IPC data read (async version)69 68 * - the call is not answered until the device returns some data (or until 70 69 * error occurs) 70 * - if the call is answered with EOK, first argument of the answer is buffer 71 * hash that could be used to retrieve the actual data 71 72 * 72 73 * Some special methods (NO-DATA transactions) do not send any data. These 73 74 * might behave as both OUT or IN transactions because communication parts 74 75 * where actual buffers are exchanged are omitted. 75 ** 76 * 77 * The mentioned data retrieval can be done any time after receiving EOK 78 * answer to IN method. 79 * This retrieval is done using the IPC_M_USBHC_GET_BUFFER where 80 * the first argument is buffer hash from call answer. 81 * This call must be immediately followed by data read-in and after the 82 * data are transferred, the initial call (IPC_M_USBHC_GET_BUFFER) 83 * is answered. Each buffer can be retrieved only once. 84 * 76 85 * For all these methods, wrap functions exists. Important rule: functions 77 86 * for IN transactions have (as parameters) buffers where retrieved data … … 95 104 IPC_M_USBHC_GET_ADDRESS, 96 105 106 /** Asks for data buffer. 107 * See explanation at usb_iface_funcs_t. 108 * This function does not have counter part in functional interface 109 * as it is handled by the remote part itself. 110 */ 111 IPC_M_USBHC_GET_BUFFER, 112 97 113 98 114 /** Reserve usage of default address. -
uspace/lib/usb/src/usbdrv.c
r4e38d69 r03197ffc 49 49 /** Storage for actual number of bytes transferred. */ 50 50 size_t *size_transferred; 51 /** Initial call repl y data. */51 /** Initial call replay data. */ 52 52 ipc_call_t reply; 53 53 /** Initial call identifier. */ 54 54 aid_t request; 55 /** Reply data for data read call. */56 ipc_call_t read_reply;57 /** Data read call identifier. */58 aid_t read_request;59 55 } transfer_info_t; 60 56 … … 144 140 145 141 if (rc != EOK) { 142 printf("usb_drv_get_my_address over %d failed: %s\n", phone, str_error(rc)); 146 143 return rc; 147 144 } … … 253 250 } 254 251 255 transfer->read_request = 0;256 252 transfer->size_transferred = NULL; 257 253 transfer->buffer = NULL; … … 319 315 } 320 316 321 transfer->read_request = 0;322 317 transfer->size_transferred = actual_size; 323 318 transfer->buffer = buffer; … … 332 327 &transfer->reply); 333 328 334 if (buffer != NULL) {335 transfer->read_request = async_data_read(phone, buffer, size,336 &transfer->read_reply);337 }338 339 329 *handle = (usb_handle_t) transfer; 340 330 … … 342 332 } 343 333 334 /** Read buffer from HCD. 335 * 336 * @param phone Opened phone to HCD. 337 * @param hash Buffer hash (obtained after completing IN transaction). 338 * @param buffer Buffer where to store data data. 339 * @param size Buffer size. 340 * @param actual_size Storage where actual number of bytes transferred will 341 * be stored. 342 * @return Error status. 343 */ 344 static int read_buffer_in(int phone, sysarg_t hash, 345 void *buffer, size_t size, size_t *actual_size) 346 { 347 ipc_call_t answer_data; 348 sysarg_t answer_rc; 349 aid_t req; 350 int rc; 351 352 req = async_send_2(phone, 353 DEV_IFACE_ID(USBHC_DEV_IFACE), 354 IPC_M_USBHC_GET_BUFFER, 355 hash, 356 &answer_data); 357 358 rc = async_data_read_start(phone, buffer, size); 359 if (rc != EOK) { 360 async_wait_for(req, NULL); 361 return EINVAL; 362 } 363 364 async_wait_for(req, &answer_rc); 365 rc = (int)answer_rc; 366 367 if (rc != EOK) { 368 return rc; 369 } 370 371 *actual_size = IPC_GET_ARG1(answer_data); 372 373 return EOK; 374 } 344 375 345 376 /** Blocks caller until given USB transaction is finished. … … 364 395 365 396 sysarg_t answer_rc; 397 async_wait_for(transfer->request, &answer_rc); 398 399 if (answer_rc != EOK) { 400 rc = (int) answer_rc; 401 goto leave; 402 } 366 403 367 404 /* … … 369 406 */ 370 407 if ((transfer->buffer != NULL) && (transfer->size > 0)) { 371 async_wait_for(transfer->read_request, &answer_rc); 372 373 if (answer_rc != EOK) { 374 rc = (int) answer_rc; 408 /* 409 * The buffer hash identifies the data on the server 410 * side. 411 * We will use it when actually reading-in the data. 412 */ 413 sysarg_t buffer_hash = IPC_GET_ARG1(transfer->reply); 414 if (buffer_hash == 0) { 415 rc = ENOENT; 375 416 goto leave; 376 417 } 377 418 378 if (transfer->size_transferred != NULL) { 379 *(transfer->size_transferred) 380 = IPC_GET_ARG2(transfer->read_reply); 419 size_t actual_size; 420 rc = read_buffer_in(transfer->phone, buffer_hash, 421 transfer->buffer, transfer->size, &actual_size); 422 423 if (rc != EOK) { 424 goto leave; 381 425 } 382 } 383 384 async_wait_for(transfer->request, &answer_rc); 385 386 if (answer_rc != EOK) { 387 rc = (int) answer_rc; 388 goto leave; 426 427 if (transfer->size_transferred) { 428 *(transfer->size_transferred) = actual_size; 429 } 389 430 } 390 431 … … 474 515 } 475 516 476 transfer->read_request = 0;477 517 transfer->size_transferred = NULL; 478 518 transfer->buffer = NULL; … … 580 620 } 581 621 582 transfer->read_request = async_data_read(phone, buffer, buffer_size,583 &transfer->read_reply);584 585 622 *handle = (usb_handle_t) transfer; 586 623
Note:
See TracChangeset
for help on using the changeset viewer.