Changeset 2185776 in mainline
- Timestamp:
- 2010-10-26T13:47:46Z (14 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 56cb9bd
- Parents:
- 23cb44b
- Location:
- uspace
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/usb/hcd.c
r23cb44b r2185776 35 35 #include "hcd.h" 36 36 #include <devmap.h> 37 #include <stdlib.h> 37 38 #include <fcntl.h> 38 39 #include <vfs/vfs.h> 39 40 #include <errno.h> 40 41 42 typedef struct { 43 int phone; 44 void *buffer; 45 size_t size; 46 size_t *size_transferred; 47 ipc_call_t reply; 48 aid_t request; 49 } transfer_info_t; 41 50 42 51 #define NAMESPACE "usb" … … 339 348 340 349 350 351 352 /* 353 * ================= 354 * async versions of the above functions 355 * ================= 356 */ 357 358 static int async_send_buffer(int phone, int method, 359 usb_target_t target, 360 void *buffer, size_t size, 361 usb_handle_t *handle) 362 { 363 if (phone < 0) { 364 return EINVAL; 365 } 366 367 if ((buffer == NULL) && (size > 0)) { 368 return EINVAL; 369 } 370 371 if (handle == NULL) { 372 return EINVAL; 373 } 374 375 transfer_info_t *transfer 376 = (transfer_info_t *) malloc(sizeof(transfer_info_t)); 377 if (transfer == NULL) { 378 return ENOMEM; 379 } 380 381 transfer->size_transferred = NULL; 382 transfer->buffer = NULL; 383 transfer->size = 0; 384 transfer->phone = phone; 385 386 int rc; 387 388 transfer->request = async_send_3(phone, 389 method, 390 target.address, target.endpoint, 391 size, 392 &transfer->reply); 393 394 if (size > 0) { 395 rc = async_data_write_start(phone, buffer, size); 396 if (rc != EOK) { 397 async_wait_for(transfer->request, NULL); 398 return rc; 399 } 400 } 401 402 *handle = (usb_handle_t) transfer; 403 404 return EOK; 405 } 406 407 static int async_recv_buffer(int phone, int method, 408 usb_target_t target, 409 void *buffer, size_t size, size_t *actual_size, 410 usb_handle_t *handle) 411 { 412 if (phone < 0) { 413 return EINVAL; 414 } 415 416 if ((buffer == NULL) && (size > 0)) { 417 return EINVAL; 418 } 419 420 if (handle == NULL) { 421 return EINVAL; 422 } 423 424 transfer_info_t *transfer 425 = (transfer_info_t *) malloc(sizeof(transfer_info_t)); 426 if (transfer == NULL) { 427 return ENOMEM; 428 } 429 430 transfer->size_transferred = actual_size; 431 transfer->buffer = buffer; 432 transfer->size = size; 433 transfer->phone = phone; 434 435 transfer->request = async_send_3(phone, 436 method, 437 target.address, target.endpoint, 438 size, 439 &transfer->reply); 440 441 *handle = (usb_handle_t) transfer; 442 443 return EOK; 444 } 445 446 static int read_buffer_in(int phone, ipcarg_t hash, 447 void *buffer, size_t size, size_t *actual_size) 448 { 449 ipc_call_t answer_data; 450 ipcarg_t answer_rc; 451 aid_t req; 452 int rc; 453 454 req = async_send_1(phone, 455 IPC_M_USB_HCD_GET_BUFFER_ASYNC, 456 hash, 457 &answer_data); 458 459 rc = async_data_read_start(phone, buffer, size); 460 if (rc != EOK) { 461 async_wait_for(req, NULL); 462 return EINVAL; 463 } 464 465 async_wait_for(req, &answer_rc); 466 rc = (int)answer_rc; 467 468 if (rc != EOK) { 469 return rc; 470 } 471 472 *actual_size = IPC_GET_ARG1(answer_data); 473 474 return EOK; 475 } 476 477 478 int usb_hcd_async_wait_for(usb_handle_t handle) 479 { 480 if (handle == 0) { 481 return EBADMEM; 482 } 483 484 int rc = EOK; 485 486 transfer_info_t *transfer = (transfer_info_t *) handle; 487 488 ipcarg_t answer_rc; 489 async_wait_for(transfer->request, &answer_rc); 490 491 if (answer_rc != EOK) { 492 rc = (int) answer_rc; 493 goto leave; 494 } 495 496 /* 497 * If the buffer is not NULL, we must accept some data. 498 */ 499 if ((transfer->buffer != NULL) && (transfer->size > 0)) { 500 /* 501 * The buffer hash identifies the data on the server 502 * side. 503 * We will use it when actually reading-in the data. 504 */ 505 ipcarg_t buffer_hash = IPC_GET_ARG1(transfer->reply); 506 if (buffer_hash == 0) { 507 rc = ENOENT; 508 goto leave; 509 } 510 511 size_t actual_size; 512 rc = read_buffer_in(transfer->phone, buffer_hash, 513 transfer->buffer, transfer->size, &actual_size); 514 515 if (rc != EOK) { 516 goto leave; 517 } 518 519 if (transfer->size_transferred) { 520 *(transfer->size_transferred) = actual_size; 521 } 522 } 523 524 leave: 525 free(transfer); 526 527 return rc; 528 } 529 530 int usb_hcd_async_transfer_interrupt_out(int hcd_phone, 531 usb_target_t target, 532 void *buffer, size_t size, 533 usb_handle_t *handle) 534 { 535 return async_send_buffer(hcd_phone, 536 IPC_M_USB_HCD_INTERRUPT_OUT_ASYNC, 537 target, 538 buffer, size, 539 handle); 540 } 541 542 int usb_hcd_async_transfer_interrupt_in(int hcd_phone, 543 usb_target_t target, 544 void *buffer, size_t size, size_t *actual_size, 545 usb_handle_t *handle) 546 { 547 return async_recv_buffer(hcd_phone, 548 IPC_M_USB_HCD_INTERRUPT_IN_ASYNC, 549 target, 550 buffer, size, actual_size, 551 handle); 552 } 553 554 int usb_hcd_async_transfer_control_write_setup(int hcd_phone, 555 usb_target_t target, 556 void *buffer, size_t size, 557 usb_handle_t *handle) 558 { 559 return async_send_buffer(hcd_phone, 560 IPC_M_USB_HCD_CONTROL_WRITE_SETUP_ASYNC, 561 target, 562 buffer, size, 563 handle); 564 } 565 566 int usb_hcd_async_transfer_control_write_data(int hcd_phone, 567 usb_target_t target, 568 void *buffer, size_t size, 569 usb_handle_t *handle) 570 { 571 return async_send_buffer(hcd_phone, 572 IPC_M_USB_HCD_CONTROL_WRITE_DATA_ASYNC, 573 target, 574 buffer, size, 575 handle); 576 } 577 578 int usb_hcd_async_transfer_control_write_status(int hcd_phone, 579 usb_target_t target, 580 usb_handle_t *handle) 581 { 582 return async_recv_buffer(hcd_phone, 583 IPC_M_USB_HCD_CONTROL_WRITE_STATUS_ASYNC, 584 target, 585 NULL, 0, NULL, 586 handle); 587 } 588 589 int usb_hcd_async_transfer_control_read_setup(int hcd_phone, 590 usb_target_t target, 591 void *buffer, size_t size, 592 usb_handle_t *handle) 593 { 594 return async_send_buffer(hcd_phone, 595 IPC_M_USB_HCD_CONTROL_READ_SETUP_ASYNC, 596 target, 597 buffer, size, 598 handle); 599 } 600 601 int usb_hcd_async_transfer_control_read_data(int hcd_phone, 602 usb_target_t target, 603 void *buffer, size_t size, size_t *actual_size, 604 usb_handle_t *handle) 605 { 606 return async_recv_buffer(hcd_phone, 607 IPC_M_USB_HCD_CONTROL_READ_DATA_ASYNC, 608 target, 609 buffer, size, actual_size, 610 handle); 611 } 612 613 int usb_hcd_async_transfer_control_read_status(int hcd_phone, 614 usb_target_t target, 615 usb_handle_t *handle) 616 { 617 return async_send_buffer(hcd_phone, 618 IPC_M_USB_HCD_CONTROL_READ_STATUS_ASYNC, 619 target, 620 NULL, 0, 621 handle); 622 } 623 341 624 /** 342 625 * @} -
uspace/lib/usb/hcd.h
r23cb44b r2185776 156 156 IPC_M_USB_HCD_CONTROL_READ_DATA, 157 157 IPC_M_USB_HCD_CONTROL_READ_STATUS, 158 159 IPC_M_USB_HCD_GET_BUFFER_ASYNC, 160 161 IPC_M_USB_HCD_INTERRUPT_OUT_ASYNC, 162 IPC_M_USB_HCD_INTERRUPT_IN_ASYNC, 163 164 IPC_M_USB_HCD_CONTROL_WRITE_SETUP_ASYNC, 165 IPC_M_USB_HCD_CONTROL_WRITE_DATA_ASYNC, 166 IPC_M_USB_HCD_CONTROL_WRITE_STATUS_ASYNC, 167 168 IPC_M_USB_HCD_CONTROL_READ_SETUP_ASYNC, 169 IPC_M_USB_HCD_CONTROL_READ_DATA_ASYNC, 170 IPC_M_USB_HCD_CONTROL_READ_STATUS_ASYNC, 158 171 /* IPC_M_USB_HCD_ */ 159 172 } usb_hcd_method_t; … … 215 228 usb_transaction_handle_t *); 216 229 230 int usb_hcd_async_transfer_interrupt_out(int, usb_target_t, 231 void *, size_t, usb_handle_t *); 232 int usb_hcd_async_transfer_interrupt_in(int, usb_target_t, 233 void *, size_t, size_t *, usb_handle_t *); 234 235 int usb_hcd_async_transfer_control_write_setup(int, usb_target_t, 236 void *, size_t, usb_handle_t *); 237 int usb_hcd_async_transfer_control_write_data(int, usb_target_t, 238 void *, size_t, usb_handle_t *); 239 int usb_hcd_async_transfer_control_write_status(int, usb_target_t, 240 usb_handle_t *); 241 242 int usb_hcd_async_transfer_control_read_setup(int, usb_target_t, 243 void *, size_t, usb_handle_t *); 244 int usb_hcd_async_transfer_control_read_data(int, usb_target_t, 245 void *, size_t, size_t *, usb_handle_t *); 246 int usb_hcd_async_transfer_control_read_status(int, usb_target_t, 247 usb_handle_t *); 248 249 int usb_hcd_async_wait_for(usb_handle_t); 250 217 251 #endif 218 252 /** -
uspace/lib/usb/usb.h
r23cb44b r2185776 37 37 38 38 #include <sys/types.h> 39 #include <ipc/ipc.h> 39 40 40 41 /** USB transfer type. */ … … 83 84 } 84 85 86 /** General handle type. 87 * Used by various USB functions as opaque handle. 88 */ 89 typedef ipcarg_t usb_handle_t; 90 85 91 #endif 86 92 /** -
uspace/srv/hw/bus/usb/hcd/virtual/connhost.c
r23cb44b r2185776 52 52 } transaction_details_t; 53 53 54 54 55 /** Callback for outgoing transaction. 55 56 */ … … 193 194 194 195 196 typedef struct { 197 ipc_callid_t caller; 198 void *buffer; 199 size_t size; 200 } async_transaction_t; 201 202 static void async_out_callback(void * buffer, size_t len, 203 usb_transaction_outcome_t outcome, void * arg) 204 { 205 async_transaction_t * trans = (async_transaction_t *)arg; 206 207 dprintf(2, "async_out_callback(buffer, %u, %d, %p) -> %x", 208 len, outcome, arg, trans->caller); 209 210 // FIXME - answer according to outcome 211 ipc_answer_1(trans->caller, EOK, 0); 212 213 free(trans); 214 if (buffer) { 215 free(buffer); 216 } 217 dprintf(4, "async_out_callback answered"); 218 } 219 220 static void async_to_device(ipc_callid_t iid, ipc_call_t icall, bool setup_transaction) 221 { 222 size_t expected_len = IPC_GET_ARG3(icall); 223 usb_target_t target = { 224 .address = IPC_GET_ARG1(icall), 225 .endpoint = IPC_GET_ARG2(icall) 226 }; 227 228 dprintf(1, "async_to_device: dev=%d:%d, size=%d, iid=%x", 229 target.address, target.endpoint, expected_len, iid); 230 231 size_t len = 0; 232 void * buffer = NULL; 233 if (expected_len > 0) { 234 int rc = async_data_write_accept(&buffer, false, 235 1, USB_MAX_PAYLOAD_SIZE, 236 0, &len); 237 238 if (rc != EOK) { 239 ipc_answer_0(iid, rc); 240 return; 241 } 242 } 243 244 async_transaction_t * trans = malloc(sizeof(async_transaction_t)); 245 trans->caller = iid; 246 trans->buffer = NULL; 247 trans->size = 0; 248 249 hc_add_transaction_to_device(setup_transaction, target, 250 buffer, len, 251 async_out_callback, trans); 252 253 dprintf(2, "async transaction to device scheduled (%p)", trans); 254 } 255 256 static void async_in_callback(void * buffer, size_t len, 257 usb_transaction_outcome_t outcome, void * arg) 258 { 259 async_transaction_t * trans = (async_transaction_t *)arg; 260 261 dprintf(2, "async_in_callback(buffer, %u, %d, %p) -> %x", 262 len, outcome, arg, trans->caller); 263 264 trans->buffer = buffer; 265 trans->size = len; 266 267 ipc_callid_t caller = trans->caller; 268 269 if (buffer == NULL) { 270 free(trans); 271 trans = NULL; 272 } 273 274 275 // FIXME - answer according to outcome 276 ipc_answer_1(caller, EOK, (ipcarg_t)trans); 277 dprintf(4, "async_in_callback answered (%#x)", (ipcarg_t)trans); 278 } 279 280 static void async_from_device(ipc_callid_t iid, ipc_call_t icall) 281 { 282 usb_target_t target = { 283 .address = IPC_GET_ARG1(icall), 284 .endpoint = IPC_GET_ARG2(icall) 285 }; 286 size_t len = IPC_GET_ARG3(icall); 287 288 dprintf(1, "async_from_device: dev=%d:%d, size=%d, iid=%x", 289 target.address, target.endpoint, len, iid); 290 291 void * buffer = NULL; 292 if (len > 0) { 293 buffer = malloc(len); 294 } 295 296 async_transaction_t * trans = malloc(sizeof(async_transaction_t)); 297 trans->caller = iid; 298 trans->buffer = NULL; 299 trans->size = 0; 300 301 hc_add_transaction_from_device(target, 302 buffer, len, 303 async_in_callback, trans); 304 305 dprintf(2, "async transfer from device scheduled (%p)", trans); 306 } 307 308 static void async_get_buffer(ipc_callid_t iid, ipc_call_t icall) 309 { 310 ipcarg_t buffer_hash = IPC_GET_ARG1(icall); 311 async_transaction_t * trans = (async_transaction_t *)buffer_hash; 312 if (trans == NULL) { 313 ipc_answer_0(iid, ENOENT); 314 return; 315 } 316 if (trans->buffer == NULL) { 317 ipc_answer_0(iid, EINVAL); 318 free(trans); 319 return; 320 } 321 322 ipc_callid_t callid; 323 size_t accepted_size; 324 if (!async_data_read_receive(&callid, &accepted_size)) { 325 ipc_answer_0(iid, EINVAL); 326 return; 327 } 328 329 if (accepted_size > trans->size) { 330 accepted_size = trans->size; 331 } 332 async_data_read_finalize(callid, trans->buffer, accepted_size); 333 334 ipc_answer_1(iid, EOK, accepted_size); 335 336 free(trans->buffer); 337 free(trans); 338 } 339 195 340 196 341 /** Connection handler for communcation with host. … … 214 359 215 360 callid = async_get_call(&call); 361 362 dprintf(6, "host on %#x calls [%x: %u (%u, %u, %u, %u, %u)]", 363 phone_hash, 364 callid, 365 IPC_GET_METHOD(call), 366 IPC_GET_ARG1(call), IPC_GET_ARG2(call), IPC_GET_ARG3(call), 367 IPC_GET_ARG4(call), IPC_GET_ARG5(call)); 216 368 217 369 switch (IPC_GET_METHOD(call)) { … … 231 383 break; 232 384 385 /* callback-result methods */ 233 386 234 387 case IPC_M_USB_HCD_INTERRUPT_OUT: … … 259 412 true, host_phone); 260 413 break; 261 262 case IPC_M_USB_HCD_CONTROL_READ_DATA: 263 case IPC_M_USB_HCD_CONTROL_READ_STATUS: 414 415 /* async methods */ 416 417 case IPC_M_USB_HCD_GET_BUFFER_ASYNC: 418 async_get_buffer(callid, call); 419 break; 420 421 case IPC_M_USB_HCD_INTERRUPT_OUT_ASYNC: 422 case IPC_M_USB_HCD_CONTROL_WRITE_DATA_ASYNC: 423 case IPC_M_USB_HCD_CONTROL_READ_STATUS_ASYNC: 424 async_to_device(callid, call, false); 425 break; 426 427 case IPC_M_USB_HCD_CONTROL_WRITE_SETUP_ASYNC: 428 case IPC_M_USB_HCD_CONTROL_READ_SETUP_ASYNC: 429 async_to_device(callid, call, true); 430 break; 431 432 case IPC_M_USB_HCD_INTERRUPT_IN_ASYNC: 433 case IPC_M_USB_HCD_CONTROL_WRITE_STATUS_ASYNC: 434 case IPC_M_USB_HCD_CONTROL_READ_DATA_ASYNC: 435 async_from_device(callid, call); 436 break; 437 438 /* end of known methods */ 264 439 265 440 default: -
uspace/srv/hw/bus/usb/hcd/virtual/devices.c
r23cb44b r2185776 147 147 if (virthub_dev.address == transaction->target.address) { 148 148 size_t tmp; 149 dprintf(3, "sending `%s' transaction to hub", 150 usbvirt_str_transaction_type(transaction->type)); 149 151 switch (transaction->type) { 150 152 case USBVIRT_TRANSACTION_SETUP: … … 170 172 break; 171 173 } 174 dprintf(4, "transaction on hub processed..."); 172 175 } 173 176
Note:
See TracChangeset
for help on using the changeset viewer.