Changeset b4b534ac in mainline for uspace/lib/drv/generic
- Timestamp:
- 2016-07-22T08:24:47Z (9 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- f76d2c2
- Parents:
- 5b18137 (diff), 8351f9a4 (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/drv/generic
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/drv/generic/driver.c
r5b18137 rb4b534ac 786 786 assert(fun->bound == false); 787 787 assert(fun->name != NULL); 788 assert(fun->dev != NULL); 788 789 789 790 add_to_functions_list(fun); … … 890 891 891 892 /** Set function ops. */ 892 void ddf_fun_set_ops(ddf_fun_t *fun, ddf_dev_ops_t *dev_ops)893 void ddf_fun_set_ops(ddf_fun_t *fun, const ddf_dev_ops_t *dev_ops) 893 894 { 894 895 assert(fun->conn_handler == NULL); -
uspace/lib/drv/generic/private/driver.h
r5b18137 rb4b534ac 93 93 94 94 /** Implementation of operations provided by this function */ 95 ddf_dev_ops_t *ops;95 const ddf_dev_ops_t *ops; 96 96 97 97 /** Connection handler or @c NULL to use the DDF default handler. */ -
uspace/lib/drv/generic/remote_usb.c
r5b18137 rb4b534ac 35 35 36 36 #include <async.h> 37 #include <macros.h> 37 38 #include <errno.h> 38 #include < macros.h>39 #include <devman.h> 39 40 40 41 #include "usb_iface.h" 41 42 #include "ddf/driver.h" 42 43 44 45 usb_dev_session_t *usb_dev_connect(devman_handle_t handle) 46 { 47 return devman_device_connect(handle, IPC_FLAG_BLOCKING); 48 } 49 50 usb_dev_session_t *usb_dev_connect_to_self(ddf_dev_t *dev) 51 { 52 return devman_parent_device_connect(ddf_dev_get_handle(dev), IPC_FLAG_BLOCKING); 53 } 54 55 void usb_dev_disconnect(usb_dev_session_t *sess) 56 { 57 if (sess) 58 async_hangup(sess); 59 } 60 43 61 typedef enum { 44 IPC_M_USB_GET_MY_ADDRESS,45 62 IPC_M_USB_GET_MY_INTERFACE, 46 IPC_M_USB_GET_HOST_CONTROLLER_HANDLE, 63 IPC_M_USB_GET_MY_DEVICE_HANDLE, 64 IPC_M_USB_RESERVE_DEFAULT_ADDRESS, 65 IPC_M_USB_RELEASE_DEFAULT_ADDRESS, 66 IPC_M_USB_DEVICE_ENUMERATE, 67 IPC_M_USB_DEVICE_REMOVE, 68 IPC_M_USB_REGISTER_ENDPOINT, 69 IPC_M_USB_UNREGISTER_ENDPOINT, 70 IPC_M_USB_READ, 71 IPC_M_USB_WRITE, 47 72 } usb_iface_funcs_t; 48 49 /** Tell USB address assigned to device.50 * @param exch Vaid IPC exchange51 * @param address Pointer to address storage place.52 * @return Error code.53 *54 * Exch param is an open communication to device implementing usb_iface.55 */56 int usb_get_my_address(async_exch_t *exch, usb_address_t *address)57 {58 if (!exch)59 return EBADMEM;60 sysarg_t addr;61 const int ret = async_req_1_1(exch, DEV_IFACE_ID(USB_DEV_IFACE),62 IPC_M_USB_GET_MY_ADDRESS, &addr);63 64 if (ret == EOK && address != NULL)65 *address = (usb_address_t) addr;66 return ret;67 }68 73 69 74 /** Tell interface number given device can use. … … 85 90 } 86 91 87 /** Tell devman handle of device host controller.92 /** Tell devman handle of the usb device function. 88 93 * @param[in] exch IPC communication exchange 89 * @param[out] h c_handle devman handle of the HC used by the target device.94 * @param[out] handle devman handle of the HC used by the target device. 90 95 * @return Error code. 91 96 */ 92 int usb_get_hc_handle(async_exch_t *exch, devman_handle_t *hc_handle) 93 { 94 if (!exch) 95 return EBADMEM; 96 devman_handle_t h; 97 int usb_get_my_device_handle(async_exch_t *exch, devman_handle_t *handle) 98 { 99 devman_handle_t h = 0; 97 100 const int ret = async_req_1_1(exch, DEV_IFACE_ID(USB_DEV_IFACE), 98 IPC_M_USB_GET_ HOST_CONTROLLER_HANDLE, &h);99 if (ret == EOK && h c_handle)100 *h c_handle = (devman_handle_t)h;101 IPC_M_USB_GET_MY_DEVICE_HANDLE, &h); 102 if (ret == EOK && handle) 103 *handle = (devman_handle_t)h; 101 104 return ret; 102 105 } 103 106 104 105 static void remote_usb_get_my_address(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *); 107 /** Reserve default USB address. 108 * @param[in] exch IPC communication exchange 109 * @param[in] speed Communication speed of the newly attached device 110 * @return Error code. 111 */ 112 int usb_reserve_default_address(async_exch_t *exch, usb_speed_t speed) 113 { 114 if (!exch) 115 return EBADMEM; 116 return async_req_2_0(exch, DEV_IFACE_ID(USB_DEV_IFACE), 117 IPC_M_USB_RESERVE_DEFAULT_ADDRESS, speed); 118 } 119 120 /** Release default USB address. 121 * @param[in] exch IPC communication exchange 122 * @return Error code. 123 */ 124 int usb_release_default_address(async_exch_t *exch) 125 { 126 if (!exch) 127 return EBADMEM; 128 return async_req_1_0(exch, DEV_IFACE_ID(USB_DEV_IFACE), 129 IPC_M_USB_RELEASE_DEFAULT_ADDRESS); 130 } 131 132 /** Trigger USB device enumeration 133 * @param[in] exch IPC communication exchange 134 * @param[out] handle Identifier of the newly added device (if successful) 135 * @return Error code. 136 */ 137 int usb_device_enumerate(async_exch_t *exch, unsigned port) 138 { 139 if (!exch) 140 return EBADMEM; 141 const int ret = async_req_2_0(exch, DEV_IFACE_ID(USB_DEV_IFACE), 142 IPC_M_USB_DEVICE_ENUMERATE, port); 143 return ret; 144 } 145 146 /** Trigger USB device enumeration 147 * @param[in] exch IPC communication exchange 148 * @param[in] handle Identifier of the device 149 * @return Error code. 150 */ 151 int usb_device_remove(async_exch_t *exch, unsigned port) 152 { 153 if (!exch) 154 return EBADMEM; 155 return async_req_2_0(exch, DEV_IFACE_ID(USB_DEV_IFACE), 156 IPC_M_USB_DEVICE_REMOVE, port); 157 } 158 159 int static_assert[sizeof(sysarg_t) >= 4 ? 1 : -1]; 160 typedef union { 161 uint8_t arr[sizeof(sysarg_t)]; 162 sysarg_t arg; 163 } pack8_t; 164 165 int usb_register_endpoint(async_exch_t *exch, usb_endpoint_t endpoint, 166 usb_transfer_type_t type, usb_direction_t direction, 167 size_t mps, unsigned packets, unsigned interval) 168 { 169 if (!exch) 170 return EBADMEM; 171 pack8_t pack; 172 pack.arr[0] = type; 173 pack.arr[1] = direction; 174 pack.arr[2] = interval; 175 pack.arr[3] = packets; 176 177 return async_req_4_0(exch, DEV_IFACE_ID(USB_DEV_IFACE), 178 IPC_M_USB_REGISTER_ENDPOINT, endpoint, pack.arg, mps); 179 180 } 181 182 int usb_unregister_endpoint(async_exch_t *exch, usb_endpoint_t endpoint, 183 usb_direction_t direction) 184 { 185 if (!exch) 186 return EBADMEM; 187 return async_req_3_0(exch, DEV_IFACE_ID(USB_DEV_IFACE), 188 IPC_M_USB_UNREGISTER_ENDPOINT, endpoint, direction); 189 } 190 191 int usb_read(async_exch_t *exch, usb_endpoint_t endpoint, uint64_t setup, 192 void *data, size_t size, size_t *rec_size) 193 { 194 if (!exch) 195 return EBADMEM; 196 197 if (size == 0 && setup == 0) 198 return EOK; 199 200 /* Make call identifying target USB device and type of transfer. */ 201 aid_t opening_request = async_send_4(exch, 202 DEV_IFACE_ID(USB_DEV_IFACE), IPC_M_USB_READ, endpoint, 203 (setup & UINT32_MAX), (setup >> 32), NULL); 204 205 if (opening_request == 0) { 206 return ENOMEM; 207 } 208 209 /* Retrieve the data. */ 210 ipc_call_t data_request_call; 211 aid_t data_request = 212 async_data_read(exch, data, size, &data_request_call); 213 214 if (data_request == 0) { 215 // FIXME: How to let the other side know that we want to abort? 216 async_forget(opening_request); 217 return ENOMEM; 218 } 219 220 /* Wait for the answer. */ 221 sysarg_t data_request_rc; 222 sysarg_t opening_request_rc; 223 async_wait_for(data_request, &data_request_rc); 224 async_wait_for(opening_request, &opening_request_rc); 225 226 if (data_request_rc != EOK) { 227 /* Prefer the return code of the opening request. */ 228 if (opening_request_rc != EOK) { 229 return (int) opening_request_rc; 230 } else { 231 return (int) data_request_rc; 232 } 233 } 234 if (opening_request_rc != EOK) { 235 return (int) opening_request_rc; 236 } 237 238 *rec_size = IPC_GET_ARG2(data_request_call); 239 return EOK; 240 } 241 242 int usb_write(async_exch_t *exch, usb_endpoint_t endpoint, uint64_t setup, 243 const void *data, size_t size) 244 { 245 if (!exch) 246 return EBADMEM; 247 248 if (size == 0 && setup == 0) 249 return EOK; 250 251 aid_t opening_request = async_send_5(exch, 252 DEV_IFACE_ID(USB_DEV_IFACE), IPC_M_USB_WRITE, endpoint, size, 253 (setup & UINT32_MAX), (setup >> 32), NULL); 254 255 if (opening_request == 0) { 256 return ENOMEM; 257 } 258 259 /* Send the data if any. */ 260 if (size > 0) { 261 const int ret = async_data_write_start(exch, data, size); 262 if (ret != EOK) { 263 async_forget(opening_request); 264 return ret; 265 } 266 } 267 268 /* Wait for the answer. */ 269 sysarg_t opening_request_rc; 270 async_wait_for(opening_request, &opening_request_rc); 271 272 return (int) opening_request_rc; 273 } 274 106 275 static void remote_usb_get_my_interface(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *); 107 static void remote_usb_get_hc_handle(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *); 276 static void remote_usb_get_my_device_handle(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *); 277 static void remote_usb_reserve_default_address(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *); 278 static void remote_usb_release_default_address(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *); 279 static void remote_usb_device_enumerate(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *); 280 static void remote_usb_device_remove(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *); 281 static void remote_usb_register_endpoint(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *); 282 static void remote_usb_unregister_endpoint(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *); 283 static void remote_usb_read(ddf_fun_t *fun, void *iface, ipc_callid_t callid, ipc_call_t *call); 284 static void remote_usb_write(ddf_fun_t *fun, void *iface, ipc_callid_t callid, ipc_call_t *call); 108 285 109 286 /** Remote USB interface operations. */ 110 287 static const remote_iface_func_ptr_t remote_usb_iface_ops [] = { 111 [IPC_M_USB_GET_MY_ADDRESS] = remote_usb_get_my_address,112 288 [IPC_M_USB_GET_MY_INTERFACE] = remote_usb_get_my_interface, 113 [IPC_M_USB_GET_HOST_CONTROLLER_HANDLE] = remote_usb_get_hc_handle, 289 [IPC_M_USB_GET_MY_DEVICE_HANDLE] = remote_usb_get_my_device_handle, 290 [IPC_M_USB_RESERVE_DEFAULT_ADDRESS] = remote_usb_reserve_default_address, 291 [IPC_M_USB_RELEASE_DEFAULT_ADDRESS] = remote_usb_release_default_address, 292 [IPC_M_USB_DEVICE_ENUMERATE] = remote_usb_device_enumerate, 293 [IPC_M_USB_DEVICE_REMOVE] = remote_usb_device_remove, 294 [IPC_M_USB_REGISTER_ENDPOINT] = remote_usb_register_endpoint, 295 [IPC_M_USB_UNREGISTER_ENDPOINT] = remote_usb_unregister_endpoint, 296 [IPC_M_USB_READ] = remote_usb_read, 297 [IPC_M_USB_WRITE] = remote_usb_write, 114 298 }; 115 299 … … 118 302 const remote_iface_t remote_usb_iface = { 119 303 .method_count = ARRAY_SIZE(remote_usb_iface_ops), 120 .methods = remote_usb_iface_ops 304 .methods = remote_usb_iface_ops, 121 305 }; 122 123 124 void remote_usb_get_my_address(ddf_fun_t *fun, void *iface,125 ipc_callid_t callid, ipc_call_t *call)126 {127 const usb_iface_t *usb_iface = (usb_iface_t *) iface;128 129 if (usb_iface->get_my_address == NULL) {130 async_answer_0(callid, ENOTSUP);131 return;132 }133 134 usb_address_t address;135 const int ret = usb_iface->get_my_address(fun, &address);136 if (ret != EOK) {137 async_answer_0(callid, ret);138 } else {139 async_answer_1(callid, EOK, address);140 }141 }142 306 143 307 void remote_usb_get_my_interface(ddf_fun_t *fun, void *iface, … … 160 324 } 161 325 162 void remote_usb_get_ hc_handle(ddf_fun_t *fun, void *iface,326 void remote_usb_get_my_device_handle(ddf_fun_t *fun, void *iface, 163 327 ipc_callid_t callid, ipc_call_t *call) 164 328 { 165 329 const usb_iface_t *usb_iface = (usb_iface_t *) iface; 166 330 167 if (usb_iface->get_ hc_handle == NULL) {331 if (usb_iface->get_my_device_handle == NULL) { 168 332 async_answer_0(callid, ENOTSUP); 169 333 return; … … 171 335 172 336 devman_handle_t handle; 173 const int ret = usb_iface->get_ hc_handle(fun, &handle);337 const int ret = usb_iface->get_my_device_handle(fun, &handle); 174 338 if (ret != EOK) { 175 339 async_answer_0(callid, ret); … … 178 342 async_answer_1(callid, EOK, (sysarg_t) handle); 179 343 } 344 345 void remote_usb_reserve_default_address(ddf_fun_t *fun, void *iface, 346 ipc_callid_t callid, ipc_call_t *call) 347 { 348 const usb_iface_t *usb_iface = (usb_iface_t *) iface; 349 350 if (usb_iface->reserve_default_address == NULL) { 351 async_answer_0(callid, ENOTSUP); 352 return; 353 } 354 355 usb_speed_t speed = DEV_IPC_GET_ARG1(*call); 356 const int ret = usb_iface->reserve_default_address(fun, speed); 357 async_answer_0(callid, ret); 358 } 359 360 void remote_usb_release_default_address(ddf_fun_t *fun, void *iface, 361 ipc_callid_t callid, ipc_call_t *call) 362 { 363 const usb_iface_t *usb_iface = (usb_iface_t *) iface; 364 365 if (usb_iface->release_default_address == NULL) { 366 async_answer_0(callid, ENOTSUP); 367 return; 368 } 369 370 const int ret = usb_iface->release_default_address(fun); 371 async_answer_0(callid, ret); 372 } 373 374 static void remote_usb_device_enumerate(ddf_fun_t *fun, void *iface, 375 ipc_callid_t callid, ipc_call_t *call) 376 { 377 const usb_iface_t *usb_iface = (usb_iface_t *) iface; 378 379 if (usb_iface->device_enumerate == NULL) { 380 async_answer_0(callid, ENOTSUP); 381 return; 382 } 383 384 const unsigned port = DEV_IPC_GET_ARG1(*call); 385 const int ret = usb_iface->device_enumerate(fun, port); 386 async_answer_0(callid, ret); 387 } 388 389 static void remote_usb_device_remove(ddf_fun_t *fun, void *iface, 390 ipc_callid_t callid, ipc_call_t *call) 391 { 392 const usb_iface_t *usb_iface = (usb_iface_t *) iface; 393 394 if (usb_iface->device_remove == NULL) { 395 async_answer_0(callid, ENOTSUP); 396 return; 397 } 398 399 const unsigned port = DEV_IPC_GET_ARG1(*call); 400 const int ret = usb_iface->device_remove(fun, port); 401 async_answer_0(callid, ret); 402 } 403 404 static void remote_usb_register_endpoint(ddf_fun_t *fun, void *iface, 405 ipc_callid_t callid, ipc_call_t *call) 406 { 407 usb_iface_t *usb_iface = (usb_iface_t *) iface; 408 409 if (!usb_iface->register_endpoint) { 410 async_answer_0(callid, ENOTSUP); 411 return; 412 } 413 414 const usb_endpoint_t endpoint = DEV_IPC_GET_ARG1(*call); 415 const pack8_t pack = { .arg = DEV_IPC_GET_ARG2(*call)}; 416 const size_t max_packet_size = DEV_IPC_GET_ARG3(*call); 417 418 const usb_transfer_type_t transfer_type = pack.arr[0]; 419 const usb_direction_t direction = pack.arr[1]; 420 unsigned packets = pack.arr[2]; 421 unsigned interval = pack.arr[3]; 422 423 const int ret = usb_iface->register_endpoint(fun, endpoint, 424 transfer_type, direction, max_packet_size, packets, interval); 425 426 async_answer_0(callid, ret); 427 } 428 429 static void remote_usb_unregister_endpoint(ddf_fun_t *fun, void *iface, 430 ipc_callid_t callid, ipc_call_t *call) 431 { 432 usb_iface_t *usb_iface = (usb_iface_t *) iface; 433 434 if (!usb_iface->unregister_endpoint) { 435 async_answer_0(callid, ENOTSUP); 436 return; 437 } 438 439 usb_endpoint_t endpoint = (usb_endpoint_t) DEV_IPC_GET_ARG1(*call); 440 usb_direction_t direction = (usb_direction_t) DEV_IPC_GET_ARG2(*call); 441 442 int rc = usb_iface->unregister_endpoint(fun, endpoint, direction); 443 444 async_answer_0(callid, rc); 445 } 446 447 typedef struct { 448 ipc_callid_t caller; 449 ipc_callid_t data_caller; 450 void *buffer; 451 } async_transaction_t; 452 453 static void async_transaction_destroy(async_transaction_t *trans) 454 { 455 if (trans == NULL) { 456 return; 457 } 458 if (trans->buffer != NULL) { 459 free(trans->buffer); 460 } 461 462 free(trans); 463 } 464 465 static async_transaction_t *async_transaction_create(ipc_callid_t caller) 466 { 467 async_transaction_t *trans = malloc(sizeof(async_transaction_t)); 468 if (trans == NULL) { 469 return NULL; 470 } 471 472 trans->caller = caller; 473 trans->data_caller = 0; 474 trans->buffer = NULL; 475 476 return trans; 477 } 478 479 static void callback_out(int outcome, void *arg) 480 { 481 async_transaction_t *trans = arg; 482 483 async_answer_0(trans->caller, outcome); 484 485 async_transaction_destroy(trans); 486 } 487 488 static void callback_in(int outcome, size_t actual_size, void *arg) 489 { 490 async_transaction_t *trans = (async_transaction_t *)arg; 491 492 if (outcome != EOK) { 493 async_answer_0(trans->caller, outcome); 494 if (trans->data_caller) { 495 async_answer_0(trans->data_caller, EINTR); 496 } 497 async_transaction_destroy(trans); 498 return; 499 } 500 501 if (trans->data_caller) { 502 async_data_read_finalize(trans->data_caller, 503 trans->buffer, actual_size); 504 } 505 506 async_answer_0(trans->caller, EOK); 507 508 async_transaction_destroy(trans); 509 } 510 511 void remote_usb_read( 512 ddf_fun_t *fun, void *iface, ipc_callid_t callid, ipc_call_t *call) 513 { 514 assert(fun); 515 assert(iface); 516 assert(call); 517 518 const usb_iface_t *usb_iface = iface; 519 520 if (!usb_iface->read) { 521 async_answer_0(callid, ENOTSUP); 522 return; 523 } 524 525 const usb_endpoint_t ep = DEV_IPC_GET_ARG1(*call); 526 const uint64_t setup = 527 ((uint64_t)DEV_IPC_GET_ARG2(*call)) | 528 (((uint64_t)DEV_IPC_GET_ARG3(*call)) << 32); 529 530 async_transaction_t *trans = async_transaction_create(callid); 531 if (trans == NULL) { 532 async_answer_0(callid, ENOMEM); 533 return; 534 } 535 536 size_t size = 0; 537 if (!async_data_read_receive(&trans->data_caller, &size)) { 538 async_answer_0(callid, EPARTY); 539 return; 540 } 541 542 trans->buffer = malloc(size); 543 if (trans->buffer == NULL) { 544 async_answer_0(trans->data_caller, ENOMEM); 545 async_answer_0(callid, ENOMEM); 546 async_transaction_destroy(trans); 547 } 548 549 const int rc = usb_iface->read( 550 fun, ep, setup, trans->buffer, size, callback_in, trans); 551 552 if (rc != EOK) { 553 async_answer_0(trans->data_caller, rc); 554 async_answer_0(callid, rc); 555 async_transaction_destroy(trans); 556 } 557 } 558 559 void remote_usb_write( 560 ddf_fun_t *fun, void *iface, ipc_callid_t callid, ipc_call_t *call) 561 { 562 assert(fun); 563 assert(iface); 564 assert(call); 565 566 const usb_iface_t *usb_iface = iface; 567 568 if (!usb_iface->write) { 569 async_answer_0(callid, ENOTSUP); 570 return; 571 } 572 573 const usb_endpoint_t ep = DEV_IPC_GET_ARG1(*call); 574 const size_t data_buffer_len = DEV_IPC_GET_ARG2(*call); 575 const uint64_t setup = 576 ((uint64_t)DEV_IPC_GET_ARG3(*call)) | 577 (((uint64_t)DEV_IPC_GET_ARG4(*call)) << 32); 578 579 async_transaction_t *trans = async_transaction_create(callid); 580 if (trans == NULL) { 581 async_answer_0(callid, ENOMEM); 582 return; 583 } 584 585 size_t size = 0; 586 if (data_buffer_len > 0) { 587 const int rc = async_data_write_accept(&trans->buffer, false, 588 1, data_buffer_len, 0, &size); 589 590 if (rc != EOK) { 591 async_answer_0(callid, rc); 592 async_transaction_destroy(trans); 593 return; 594 } 595 } 596 597 const int rc = usb_iface->write( 598 fun, ep, setup, trans->buffer, size, callback_out, trans); 599 600 if (rc != EOK) { 601 async_answer_0(callid, rc); 602 async_transaction_destroy(trans); 603 } 604 } 180 605 /** 181 606 * @} -
uspace/lib/drv/generic/remote_usbhc.c
r5b18137 rb4b534ac 85 85 */ 86 86 typedef enum { 87 /** Asks for address assignment by host controller.88 * Answer:89 * - ELIMIT - host controller run out of address90 * - EOK - address assigned91 * Answer arguments:92 * - assigned address93 *94 * The address must be released by via IPC_M_USBHC_RELEASE_ADDRESS.95 */96 IPC_M_USBHC_REQUEST_ADDRESS,97 98 /** Bind USB address with devman handle.99 * Parameters:100 * - USB address101 * - devman handle102 * Answer:103 * - EOK - address binded104 * - ENOENT - address is not in use105 */106 IPC_M_USBHC_BIND_ADDRESS,107 108 /** Get handle binded with given USB address.109 * Parameters110 * - USB address111 * Answer:112 * - EOK - address binded, first parameter is the devman handle113 * - ENOENT - address is not in use at the moment114 */115 IPC_M_USBHC_GET_HANDLE_BY_ADDRESS,116 117 /** Release address in use.118 * Arguments:119 * - address to be released120 * Answer:121 * - ENOENT - address not in use122 * - EPERM - trying to release default USB address123 */124 IPC_M_USBHC_RELEASE_ADDRESS,125 126 /** Register endpoint attributes at host controller.127 * This is used to reserve portion of USB bandwidth.128 * When speed is invalid, speed of the device is used.129 * Parameters:130 * - USB address + endpoint number131 * - packed as ADDR << 16 + EP132 * - speed + transfer type + direction133 * - packed as ( SPEED << 8 + TYPE ) << 8 + DIR134 * - maximum packet size + interval (in milliseconds)135 * - packed as MPS << 16 + INT136 * Answer:137 * - EOK - reservation successful138 * - ELIMIT - not enough bandwidth to satisfy the request139 */140 IPC_M_USBHC_REGISTER_ENDPOINT,141 142 /** Revert endpoint registration.143 * Parameters:144 * - USB address145 * - endpoint number146 * - data direction147 * Answer:148 * - EOK - endpoint unregistered149 * - ENOENT - unknown endpoint150 */151 IPC_M_USBHC_UNREGISTER_ENDPOINT,152 153 87 /** Get data from device. 154 88 * See explanation at usb_iface_funcs_t (IN transaction). … … 161 95 IPC_M_USBHC_WRITE, 162 96 } usbhc_iface_funcs_t; 163 164 int usbhc_request_address(async_exch_t *exch, usb_address_t *address,165 bool strict, usb_speed_t speed)166 {167 if (!exch || !address)168 return EBADMEM;169 sysarg_t new_address;170 const int ret = async_req_4_1(exch, DEV_IFACE_ID(USBHC_DEV_IFACE),171 IPC_M_USBHC_REQUEST_ADDRESS, *address, strict, speed, &new_address);172 if (ret == EOK)173 *address = (usb_address_t)new_address;174 return ret;175 }176 177 int usbhc_bind_address(async_exch_t *exch, usb_address_t address,178 devman_handle_t handle)179 {180 if (!exch)181 return EBADMEM;182 return async_req_3_0(exch, DEV_IFACE_ID(USBHC_DEV_IFACE),183 IPC_M_USBHC_BIND_ADDRESS, address, handle);184 }185 186 int usbhc_get_handle(async_exch_t *exch, usb_address_t address,187 devman_handle_t *handle)188 {189 if (!exch)190 return EBADMEM;191 sysarg_t h;192 const int ret = async_req_2_1(exch, DEV_IFACE_ID(USBHC_DEV_IFACE),193 IPC_M_USBHC_GET_HANDLE_BY_ADDRESS, address, &h);194 if (ret == EOK && handle)195 *handle = (devman_handle_t)h;196 return ret;197 }198 199 int usbhc_release_address(async_exch_t *exch, usb_address_t address)200 {201 if (!exch)202 return EBADMEM;203 return async_req_2_0(exch, DEV_IFACE_ID(USBHC_DEV_IFACE),204 IPC_M_USBHC_RELEASE_ADDRESS, address);205 }206 207 int usbhc_register_endpoint(async_exch_t *exch, usb_address_t address,208 usb_endpoint_t endpoint, usb_transfer_type_t type,209 usb_direction_t direction, size_t mps, unsigned interval)210 {211 if (!exch)212 return EBADMEM;213 const usb_target_t target =214 {{ .address = address, .endpoint = endpoint }};215 #define _PACK2(high, low) (((high & 0xffff) << 16) | (low & 0xffff))216 217 return async_req_4_0(exch, DEV_IFACE_ID(USBHC_DEV_IFACE),218 IPC_M_USBHC_REGISTER_ENDPOINT, target.packed,219 _PACK2(type, direction), _PACK2(mps, interval));220 221 #undef _PACK2222 }223 224 int usbhc_unregister_endpoint(async_exch_t *exch, usb_address_t address,225 usb_endpoint_t endpoint, usb_direction_t direction)226 {227 if (!exch)228 return EBADMEM;229 return async_req_4_0(exch, DEV_IFACE_ID(USBHC_DEV_IFACE),230 IPC_M_USBHC_UNREGISTER_ENDPOINT, address, endpoint, direction);231 }232 97 233 98 int usbhc_read(async_exch_t *exch, usb_address_t address, … … 323 188 } 324 189 325 326 static void remote_usbhc_request_address(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *);327 static void remote_usbhc_bind_address(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *);328 static void remote_usbhc_get_handle(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *);329 static void remote_usbhc_release_address(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *);330 static void remote_usbhc_register_endpoint(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *);331 static void remote_usbhc_unregister_endpoint(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *);332 190 static void remote_usbhc_read(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *); 333 191 static void remote_usbhc_write(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *); 334 //static void remote_usbhc(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *);335 192 336 193 /** Remote USB host controller interface operations. */ 337 194 static const remote_iface_func_ptr_t remote_usbhc_iface_ops[] = { 338 [IPC_M_USBHC_REQUEST_ADDRESS] = remote_usbhc_request_address,339 [IPC_M_USBHC_RELEASE_ADDRESS] = remote_usbhc_release_address,340 [IPC_M_USBHC_BIND_ADDRESS] = remote_usbhc_bind_address,341 [IPC_M_USBHC_GET_HANDLE_BY_ADDRESS] = remote_usbhc_get_handle,342 343 [IPC_M_USBHC_REGISTER_ENDPOINT] = remote_usbhc_register_endpoint,344 [IPC_M_USBHC_UNREGISTER_ENDPOINT] = remote_usbhc_unregister_endpoint,345 346 195 [IPC_M_USBHC_READ] = remote_usbhc_read, 347 196 [IPC_M_USBHC_WRITE] = remote_usbhc_write, … … 386 235 } 387 236 388 void remote_usbhc_request_address(ddf_fun_t *fun, void *iface, 389 ipc_callid_t callid, ipc_call_t *call) 390 { 391 const usbhc_iface_t *usb_iface = iface; 392 393 if (!usb_iface->request_address) { 394 async_answer_0(callid, ENOTSUP); 395 return; 396 } 397 398 usb_address_t address = DEV_IPC_GET_ARG1(*call); 399 const bool strict = DEV_IPC_GET_ARG2(*call); 400 const usb_speed_t speed = DEV_IPC_GET_ARG3(*call); 401 402 const int rc = usb_iface->request_address(fun, &address, strict, speed); 403 if (rc != EOK) { 404 async_answer_0(callid, rc); 405 } else { 406 async_answer_1(callid, EOK, (sysarg_t) address); 407 } 408 } 409 410 void remote_usbhc_bind_address(ddf_fun_t *fun, void *iface, 411 ipc_callid_t callid, ipc_call_t *call) 412 { 413 const usbhc_iface_t *usb_iface = iface; 414 415 if (!usb_iface->bind_address) { 416 async_answer_0(callid, ENOTSUP); 417 return; 418 } 419 420 const usb_address_t address = (usb_address_t) DEV_IPC_GET_ARG1(*call); 421 const devman_handle_t handle = (devman_handle_t) DEV_IPC_GET_ARG2(*call); 422 423 const int ret = usb_iface->bind_address(fun, address, handle); 424 async_answer_0(callid, ret); 425 } 426 427 void remote_usbhc_get_handle(ddf_fun_t *fun, void *iface, 428 ipc_callid_t callid, ipc_call_t *call) 429 { 430 const usbhc_iface_t *usb_iface = iface; 431 432 if (!usb_iface->get_handle) { 433 async_answer_0(callid, ENOTSUP); 434 return; 435 } 436 437 const usb_address_t address = (usb_address_t) DEV_IPC_GET_ARG1(*call); 438 devman_handle_t handle; 439 const int ret = usb_iface->get_handle(fun, address, &handle); 440 441 if (ret == EOK) { 442 async_answer_1(callid, ret, handle); 443 } else { 444 async_answer_0(callid, ret); 445 } 446 } 447 448 void remote_usbhc_release_address(ddf_fun_t *fun, void *iface, 449 ipc_callid_t callid, ipc_call_t *call) 450 { 451 const usbhc_iface_t *usb_iface = iface; 452 453 if (!usb_iface->release_address) { 454 async_answer_0(callid, ENOTSUP); 455 return; 456 } 457 458 const usb_address_t address = (usb_address_t) DEV_IPC_GET_ARG1(*call); 459 460 const int ret = usb_iface->release_address(fun, address); 461 async_answer_0(callid, ret); 462 } 463 464 static void callback_out(ddf_fun_t *fun, 465 int outcome, void *arg) 237 static void callback_out(int outcome, void *arg) 466 238 { 467 239 async_transaction_t *trans = arg; … … 472 244 } 473 245 474 static void callback_in(ddf_fun_t *fun, 475 int outcome, size_t actual_size, void *arg) 246 static void callback_in(int outcome, size_t actual_size, void *arg) 476 247 { 477 248 async_transaction_t *trans = (async_transaction_t *)arg; … … 496 267 } 497 268 498 void remote_usbhc_register_endpoint(ddf_fun_t *fun, void *iface,499 ipc_callid_t callid, ipc_call_t *call)500 {501 usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface;502 503 if (!usb_iface->register_endpoint) {504 async_answer_0(callid, ENOTSUP);505 return;506 }507 508 #define _INIT_FROM_HIGH_DATA2(type, var, arg_no) \509 type var = (type) (DEV_IPC_GET_ARG##arg_no(*call) >> 16)510 #define _INIT_FROM_LOW_DATA2(type, var, arg_no) \511 type var = (type) (DEV_IPC_GET_ARG##arg_no(*call) & 0xffff)512 513 const usb_target_t target = { .packed = DEV_IPC_GET_ARG1(*call) };514 515 _INIT_FROM_HIGH_DATA2(usb_transfer_type_t, transfer_type, 2);516 _INIT_FROM_LOW_DATA2(usb_direction_t, direction, 2);517 518 _INIT_FROM_HIGH_DATA2(size_t, max_packet_size, 3);519 _INIT_FROM_LOW_DATA2(unsigned int, interval, 3);520 521 #undef _INIT_FROM_HIGH_DATA2522 #undef _INIT_FROM_LOW_DATA2523 524 int rc = usb_iface->register_endpoint(fun, target.address,525 target.endpoint, transfer_type, direction, max_packet_size, interval);526 527 async_answer_0(callid, rc);528 }529 530 void remote_usbhc_unregister_endpoint(ddf_fun_t *fun, void *iface,531 ipc_callid_t callid, ipc_call_t *call)532 {533 usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface;534 535 if (!usb_iface->unregister_endpoint) {536 async_answer_0(callid, ENOTSUP);537 return;538 }539 540 usb_address_t address = (usb_address_t) DEV_IPC_GET_ARG1(*call);541 usb_endpoint_t endpoint = (usb_endpoint_t) DEV_IPC_GET_ARG2(*call);542 usb_direction_t direction = (usb_direction_t) DEV_IPC_GET_ARG3(*call);543 544 int rc = usb_iface->unregister_endpoint(fun,545 address, endpoint, direction);546 547 async_answer_0(callid, rc);548 }549 550 269 void remote_usbhc_read( 551 270 ddf_fun_t *fun, void *iface, ipc_callid_t callid, ipc_call_t *call)
Note:
See TracChangeset
for help on using the changeset viewer.