Changeset 1968de5 in mainline
- Timestamp:
- 2011-02-11T16:27:45Z (14 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 608afb9
- Parents:
- 03197ffc (diff), 5842493 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - Location:
- uspace/lib
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/c/generic/async.c
r03197ffc r1968de5 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 1569 1583 /** Wrapper for IPC_M_DATA_READ calls using the async framework. 1570 1584 * -
uspace/lib/c/include/async.h
r03197ffc r1968de5 340 340 (arg4), (answer)) 341 341 342 extern aid_t async_data_read(int, void *, size_t, ipc_call_t *); 342 343 extern int async_data_read_start(int, void *, size_t); 343 344 extern bool async_data_read_receive(ipc_callid_t *, size_t *); -
uspace/lib/drv/generic/remote_usbhc.c
r03197ffc r1968de5 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 *);45 44 static void remote_usbhc_interrupt_out(device_t *, void *, ipc_callid_t, ipc_call_t *); 46 45 static void remote_usbhc_interrupt_in(device_t *, void *, ipc_callid_t, ipc_call_t *); … … 64 63 remote_usbhc_get_address, 65 64 66 remote_usbhc_get_buffer,67 68 65 remote_usbhc_reserve_default_address, 69 66 remote_usbhc_release_default_address, … … 98 95 typedef struct { 99 96 ipc_callid_t caller; 97 ipc_callid_t data_caller; 100 98 void *buffer; 101 99 void *setup_packet; … … 127 125 128 126 trans->caller = caller; 127 trans->data_caller = 0; 129 128 trans->buffer = NULL; 130 129 trans->setup_packet = NULL; … … 155 154 } 156 155 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 190 156 void remote_usbhc_reserve_default_address(device_t *device, void *iface, 191 157 ipc_callid_t callid, ipc_call_t *call) … … 290 256 if (outcome != USB_OUTCOME_OK) { 291 257 async_answer_0(trans->caller, outcome); 258 if (trans->data_caller) { 259 async_answer_0(trans->data_caller, EINTR); 260 } 292 261 async_transaction_destroy(trans); 293 262 return; … … 295 264 296 265 trans->size = actual_size; 297 async_answer_1(trans->caller, USB_OUTCOME_OK, (sysarg_t)trans); 266 267 if (trans->data_caller) { 268 async_data_read_finalize(trans->data_caller, 269 trans->buffer, actual_size); 270 } 271 272 async_answer_0(trans->caller, USB_OUTCOME_OK); 273 274 async_transaction_destroy(trans); 298 275 } 299 276 … … 376 353 }; 377 354 355 ipc_callid_t data_callid; 356 if (!async_data_read_receive(&data_callid, &len)) { 357 async_answer_0(callid, EPARTY); 358 return; 359 } 360 378 361 async_transaction_t *trans = async_transaction_create(callid); 379 362 if (trans == NULL) { … … 381 364 return; 382 365 } 366 trans->data_caller = data_callid; 383 367 trans->buffer = malloc(len); 384 368 trans->size = len; … … 630 614 } 631 615 616 ipc_callid_t data_callid; 617 if (!async_data_read_receive(&data_callid, &data_len)) { 618 async_answer_0(callid, EPARTY); 619 free(setup_packet); 620 return; 621 } 622 632 623 async_transaction_t *trans = async_transaction_create(callid); 633 624 if (trans == NULL) { … … 636 627 return; 637 628 } 629 trans->data_caller = data_callid; 638 630 trans->setup_packet = setup_packet; 639 631 trans->size = data_len; -
uspace/lib/drv/include/usbhc_iface.h
r03197ffc r1968de5 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) 68 69 * - the call is not answered until the device returns some data (or until 69 70 * error occurs) 70 * - if the call is answered with EOK, first argument of the answer is buffer71 * hash that could be used to retrieve the actual data72 71 * 73 72 * Some special methods (NO-DATA transactions) do not send any data. These 74 73 * might behave as both OUT or IN transactions because communication parts 75 74 * where actual buffers are exchanged are omitted. 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 * 75 ** 85 76 * For all these methods, wrap functions exists. Important rule: functions 86 77 * for IN transactions have (as parameters) buffers where retrieved data … … 104 95 IPC_M_USBHC_GET_ADDRESS, 105 96 106 /** Asks for data buffer.107 * See explanation at usb_iface_funcs_t.108 * This function does not have counter part in functional interface109 * as it is handled by the remote part itself.110 */111 IPC_M_USBHC_GET_BUFFER,112 113 97 114 98 /** Reserve usage of default address. -
uspace/lib/usb/src/usbdrv.c
r03197ffc r1968de5 49 49 /** Storage for actual number of bytes transferred. */ 50 50 size_t *size_transferred; 51 /** Initial call repl ay data. */51 /** Initial call reply 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; 55 59 } transfer_info_t; 56 60 … … 140 144 141 145 if (rc != EOK) { 142 printf("usb_drv_get_my_address over %d failed: %s\n", phone, str_error(rc));143 146 return rc; 144 147 } … … 250 253 } 251 254 255 transfer->read_request = 0; 252 256 transfer->size_transferred = NULL; 253 257 transfer->buffer = NULL; … … 315 319 } 316 320 321 transfer->read_request = 0; 317 322 transfer->size_transferred = actual_size; 318 323 transfer->buffer = buffer; … … 327 332 &transfer->reply); 328 333 334 if (buffer != NULL) { 335 transfer->read_request = async_data_read(phone, buffer, size, 336 &transfer->read_reply); 337 } 338 329 339 *handle = (usb_handle_t) transfer; 330 340 … … 332 342 } 333 343 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 will341 * 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 }375 344 376 345 /** Blocks caller until given USB transaction is finished. … … 395 364 396 365 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 }403 366 404 367 /* … … 406 369 */ 407 370 if ((transfer->buffer != NULL) && (transfer->size > 0)) { 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; 371 async_wait_for(transfer->read_request, &answer_rc); 372 373 if (answer_rc != EOK) { 374 rc = (int) answer_rc; 416 375 goto leave; 417 376 } 418 377 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; 378 if (transfer->size_transferred != NULL) { 379 *(transfer->size_transferred) 380 = IPC_GET_ARG2(transfer->read_reply); 425 381 } 426 427 if (transfer->size_transferred) { 428 *(transfer->size_transferred) = actual_size; 429 } 382 } 383 384 async_wait_for(transfer->request, &answer_rc); 385 386 if (answer_rc != EOK) { 387 rc = (int) answer_rc; 388 goto leave; 430 389 } 431 390 … … 515 474 } 516 475 476 transfer->read_request = 0; 517 477 transfer->size_transferred = NULL; 518 478 transfer->buffer = NULL; … … 620 580 } 621 581 582 transfer->read_request = async_data_read(phone, buffer, buffer_size, 583 &transfer->read_reply); 584 622 585 *handle = (usb_handle_t) transfer; 623 586
Note:
See TracChangeset
for help on using the changeset viewer.