Changeset 79ae36dd in mainline for uspace/lib/usbdev
- Timestamp:
- 2011-06-08T19:01:55Z (14 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 0eff68e
- Parents:
- 764d71e
- Location:
- uspace/lib/usbdev
- Files:
-
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/usbdev/include/usb/dev/pipes.h
r764d71e r79ae36dd 43 43 #include <ddf/driver.h> 44 44 #include <fibril_synch.h> 45 #include <async.h> 45 46 46 47 /** Abstraction of a physical connection to the device. … … 62 63 * 63 64 * Locking order: if you want to lock both mutexes 64 * (@c guard and @c hc_ phone_mutex), lock @c guard first.65 * It is not necessary to lock @c guard if you want to lock @c hc_ phone_mutex65 * (@c guard and @c hc_sess_mutex), lock @c guard first. 66 * It is not necessary to lock @c guard if you want to lock @c hc_sess_mutex 66 67 * only. 67 68 */ … … 85 86 size_t max_packet_size; 86 87 87 /** Phoneto the host controller.88 * N egativewhen no session is active.89 * It is an error to access this member without @c hc_ phone_mutex88 /** Session to the host controller. 89 * NULL when no session is active. 90 * It is an error to access this member without @c hc_sess_mutex 90 91 * being locked. 91 92 * If call over the phone is to be made, it must be preceeded by 92 93 * call to pipe_add_ref() [internal libusb function]. 93 94 */ 94 int hc_phone;95 async_sess_t *hc_sess; 95 96 96 /** Guard for serialization of requests over the phone. */97 fibril_mutex_t hc_ phone_mutex;97 /** Guard for serialization of requests over the session. */ 98 fibril_mutex_t hc_sess_mutex; 98 99 99 100 /** Number of active transfers over the pipe. */ -
uspace/lib/usbdev/src/hub.c
r764d71e r79ae36dd 42 42 #include <usb/debug.h> 43 43 #include <time.h> 44 #include <async.h> 44 45 45 46 /** How much time to wait between attempts to register endpoint 0:0. … … 71 72 { 72 73 CHECK_CONNECTION(connection); 73 74 75 async_exch_t *exch = async_exchange_begin(connection->hc_sess); 76 74 77 sysarg_t address; 75 int rc = async_req_2_1(connection->hc_phone, 76 DEV_IFACE_ID(USBHC_DEV_IFACE), 78 int rc = async_req_2_1(exch, DEV_IFACE_ID(USBHC_DEV_IFACE), 77 79 IPC_M_USBHC_REQUEST_ADDRESS, speed, 78 80 &address); 79 if (rc != EOK) { 81 82 async_exchange_end(exch); 83 84 if (rc != EOK) 80 85 return (usb_address_t) rc; 81 } else { 82 return (usb_address_t) address; 83 } 86 87 return (usb_address_t) address; 84 88 } 85 89 … … 94 98 { 95 99 CHECK_CONNECTION(connection); 96 if (attached_device == NULL) { 100 101 if (attached_device == NULL) 97 102 return EBADMEM; 98 } 99 100 return async_req_3_0(connection->hc_phone, 101 DEV_IFACE_ID(USBHC_DEV_IFACE), 103 104 async_exch_t *exch = async_exchange_begin(connection->hc_sess); 105 int rc = async_req_3_0(exch, DEV_IFACE_ID(USBHC_DEV_IFACE), 102 106 IPC_M_USBHC_BIND_ADDRESS, 103 107 attached_device->address, attached_device->handle); 108 async_exchange_end(exch); 109 110 return rc; 104 111 } 105 112 … … 114 121 { 115 122 CHECK_CONNECTION(connection); 116 117 return async_req_2_0(connection->hc_phone,118 123 124 async_exch_t *exch = async_exchange_begin(connection->hc_sess); 125 int rc = async_req_2_0(exch, DEV_IFACE_ID(USBHC_DEV_IFACE), 119 126 IPC_M_USBHC_RELEASE_ADDRESS, address); 127 async_exchange_end(exch); 128 129 return rc; 120 130 } 121 131 … … 192 202 usb_hc_connection_t hc_conn = { 193 203 .hc_handle = connection->hc_handle, 194 .hc_ phone = -1204 .hc_sess = NULL 195 205 }; 196 206 -
uspace/lib/usbdev/src/pipepriv.c
r764d71e r79ae36dd 44 44 void pipe_start_transaction(usb_pipe_t *pipe) 45 45 { 46 fibril_mutex_lock(&pipe->hc_ phone_mutex);46 fibril_mutex_lock(&pipe->hc_sess_mutex); 47 47 } 48 48 … … 53 53 void pipe_end_transaction(usb_pipe_t *pipe) 54 54 { 55 fibril_mutex_unlock(&pipe->hc_ phone_mutex);55 fibril_mutex_unlock(&pipe->hc_sess_mutex); 56 56 } 57 57 … … 85 85 { 86 86 pipe_acquire(pipe); 87 87 88 88 if (pipe->refcount == 0) { 89 89 /* Need to open the phone by ourselves. */ 90 int phone = devman_device_connect(pipe->wire->hc_handle, 0); 91 if (phone < 0) { 90 async_sess_t *sess = 91 devman_device_connect(EXCHANGE_SERIALIZE, pipe->wire->hc_handle, 0); 92 if (!sess) { 92 93 if (hide_failure) { 93 94 pipe->refcount_soft++; 94 phone = EOK; 95 pipe_release(pipe); 96 return EOK; 95 97 } 98 96 99 pipe_release(pipe); 97 return phone;100 return ENOMEM; 98 101 } 102 99 103 /* 100 104 * No locking is needed, refcount is zero and whole pipe 101 105 * mutex is locked. 102 106 */ 103 pipe->hc_phone = phone; 107 108 pipe->hc_sess = sess; 104 109 } 110 105 111 pipe->refcount++; 106 107 112 pipe_release(pipe); 108 113 109 114 return EOK; 110 115 } … … 117 122 { 118 123 pipe_acquire(pipe); 124 119 125 if (pipe->refcount_soft > 0) { 120 126 pipe->refcount_soft--; … … 122 128 return; 123 129 } 130 124 131 assert(pipe->refcount > 0); 132 125 133 pipe->refcount--; 134 126 135 if (pipe->refcount == 0) { 127 136 /* We were the last users, let's hang-up. */ 128 async_hangup(pipe->hc_ phone);129 pipe->hc_ phone = -1;137 async_hangup(pipe->hc_sess); 138 pipe->hc_sess = NULL; 130 139 } 140 131 141 pipe_release(pipe); 132 142 } -
uspace/lib/usbdev/src/pipes.c
r764d71e r79ae36dd 48 48 /** Tell USB address assigned to given device. 49 49 * 50 * @param phone Phoneto parent device.50 * @param sess Session to parent device. 51 51 * @param dev Device in question. 52 52 * @return USB address or error code. 53 53 */ 54 static usb_address_t get_my_address( int phone, ddf_dev_t *dev)55 { 56 sysarg_t address;57 54 static usb_address_t get_my_address(async_sess_t *sess, ddf_dev_t *dev) 55 { 56 async_exch_t *exch = async_exchange_begin(sess); 57 58 58 /* 59 59 * We are sending special value as a handle - zero - to get … … 61 61 * when registering our device @p dev. 62 62 */ 63 int rc = async_req_2_1(phone, DEV_IFACE_ID(USB_DEV_IFACE), 64 IPC_M_USB_GET_ADDRESS, 65 0, &address); 66 67 if (rc != EOK) { 63 sysarg_t address; 64 int rc = async_req_2_1(exch, DEV_IFACE_ID(USB_DEV_IFACE), 65 IPC_M_USB_GET_ADDRESS, 0, &address); 66 67 async_exchange_end(exch); 68 69 if (rc != EOK) 68 70 return rc; 69 } 70 71 71 72 return (usb_address_t) address; 72 73 } … … 79 80 int usb_device_get_assigned_interface(ddf_dev_t *device) 80 81 { 81 int parent_phone = devman_parent_device_connect(device->handle, 82 async_sess_t *parent_sess = 83 devman_parent_device_connect(EXCHANGE_SERIALIZE, device->handle, 82 84 IPC_FLAG_BLOCKING); 83 if ( parent_phone < 0) {85 if (!parent_sess) 84 86 return -1; 85 } 86 87 88 async_exch_t *exch = async_exchange_begin(parent_sess); 89 87 90 sysarg_t iface_no; 88 int rc = async_req_2_1( parent_phone, DEV_IFACE_ID(USB_DEV_IFACE),89 IPC_M_USB_GET_INTERFACE, 90 device->handle, &iface_no);91 92 async_hangup(parent_ phone);93 94 if (rc != EOK) {91 int rc = async_req_2_1(exch, DEV_IFACE_ID(USB_DEV_IFACE), 92 IPC_M_USB_GET_INTERFACE, device->handle, &iface_no); 93 94 async_exchange_end(exch); 95 async_hangup(parent_sess); 96 97 if (rc != EOK) 95 98 return -1; 96 } 97 99 98 100 return (int) iface_no; 99 101 } … … 110 112 assert(connection); 111 113 assert(dev); 112 114 113 115 int rc; 114 116 devman_handle_t hc_handle; 115 117 usb_address_t my_address; 116 118 117 119 rc = usb_hc_find(dev->handle, &hc_handle); 118 if (rc != EOK) {120 if (rc != EOK) 119 121 return rc; 120 }121 122 int parent_phone = devman_parent_device_connect(dev->handle,122 123 async_sess_t *parent_sess = 124 devman_parent_device_connect(EXCHANGE_SERIALIZE, dev->handle, 123 125 IPC_FLAG_BLOCKING); 124 if (parent_phone < 0) { 125 return parent_phone; 126 } 127 126 if (!parent_sess) 127 return ENOMEM; 128 128 129 /* 129 130 * Asking for "my" address may require several attempts. … … 137 138 * So, we need to wait for the HC to learn the binding. 138 139 */ 140 139 141 do { 140 my_address = get_my_address(parent_ phone, dev);141 142 my_address = get_my_address(parent_sess, dev); 143 142 144 if (my_address == ENOENT) { 143 145 /* Be nice, let other fibrils run and try again. */ … … 148 150 goto leave; 149 151 } 150 152 151 153 } while (my_address < 0); 152 154 153 155 rc = usb_device_connection_initialize(connection, 154 156 hc_handle, my_address); 155 157 156 158 leave: 157 async_hangup(parent_ phone);159 async_hangup(parent_sess); 158 160 return rc; 159 161 } -
uspace/lib/usbdev/src/pipesinit.c
r764d71e r79ae36dd 358 358 fibril_mutex_initialize(&pipe->guard); 359 359 pipe->wire = connection; 360 pipe->hc_ phone = -1;361 fibril_mutex_initialize(&pipe->hc_ phone_mutex);360 pipe->hc_sess = NULL; 361 fibril_mutex_initialize(&pipe->hc_sess_mutex); 362 362 pipe->endpoint_no = endpoint_no; 363 363 pipe->transfer_type = transfer_type; … … 482 482 assert(pipe); 483 483 assert(hc_connection); 484 485 if (!usb_hc_connection_is_opened(hc_connection)) {484 485 if (!usb_hc_connection_is_opened(hc_connection)) 486 486 return EBADF; 487 } 488 487 489 488 #define _PACK2(high, low) (((high) << 16) + (low)) 490 489 #define _PACK3(high, middle, low) (((((high) << 8) + (middle)) << 8) + (low)) 491 492 return async_req_4_0(hc_connection->hc_phone, 493 DEV_IFACE_ID(USBHC_DEV_IFACE), IPC_M_USBHC_REGISTER_ENDPOINT, 490 491 async_exch_t *exch = async_exchange_begin(hc_connection->hc_sess); 492 int rc = async_req_4_0(exch, DEV_IFACE_ID(USBHC_DEV_IFACE), 493 IPC_M_USBHC_REGISTER_ENDPOINT, 494 494 _PACK2(pipe->wire->address, pipe->endpoint_no), 495 495 _PACK3(speed, pipe->transfer_type, pipe->direction), 496 496 _PACK2(pipe->max_packet_size, interval)); 497 497 async_exchange_end(exch); 498 498 499 #undef _PACK2 499 500 #undef _PACK3 501 502 return rc; 500 503 } 501 504 … … 511 514 assert(pipe); 512 515 assert(hc_connection); 513 514 if (!usb_hc_connection_is_opened(hc_connection)) {516 517 if (!usb_hc_connection_is_opened(hc_connection)) 515 518 return EBADF; 516 }517 518 return async_req_4_0(hc_connection->hc_phone,519 DEV_IFACE_ID(USBHC_DEV_IFACE),IPC_M_USBHC_UNREGISTER_ENDPOINT,519 520 async_exch_t *exch = async_exchange_begin(hc_connection->hc_sess); 521 int rc = async_req_4_0(exch, DEV_IFACE_ID(USBHC_DEV_IFACE), 522 IPC_M_USBHC_UNREGISTER_ENDPOINT, 520 523 pipe->wire->address, pipe->endpoint_no, pipe->direction); 524 async_exchange_end(exch); 525 526 return rc; 521 527 } 522 528 -
uspace/lib/usbdev/src/pipesio.c
r764d71e r79ae36dd 44 44 * obviously). 45 45 */ 46 46 47 #include <usb/usb.h> 47 48 #include <usb/dev/pipes.h> … … 50 51 #include <usbhc_iface.h> 51 52 #include <usb/dev/request.h> 53 #include <async.h> 52 54 #include "pipepriv.h" 53 55 … … 79 81 return ENOTSUP; 80 82 } 81 83 82 84 /* Ensure serialization over the phone. */ 83 85 pipe_start_transaction(pipe); 84 86 async_exch_t *exch = async_exchange_begin(pipe->hc_sess); 87 85 88 /* 86 89 * Make call identifying target USB device and type of transfer. 87 90 */ 88 aid_t opening_request = async_send_3(pipe->hc_phone, 89 DEV_IFACE_ID(USBHC_DEV_IFACE), ipc_method, 90 pipe->wire->address, pipe->endpoint_no, 91 NULL); 91 aid_t opening_request = async_send_3(exch, DEV_IFACE_ID(USBHC_DEV_IFACE), 92 ipc_method, pipe->wire->address, pipe->endpoint_no, NULL); 93 92 94 if (opening_request == 0) { 95 async_exchange_end(exch); 93 96 pipe_end_transaction(pipe); 94 97 return ENOMEM; 95 98 } 96 99 97 100 /* 98 101 * Retrieve the data. 99 102 */ 100 103 ipc_call_t data_request_call; 101 aid_t data_request = async_data_read( pipe->hc_phone, buffer, size,104 aid_t data_request = async_data_read(exch, buffer, size, 102 105 &data_request_call); 103 106 104 107 /* 105 108 * Since now on, someone else might access the backing phone 106 109 * without breaking the transfer IPC protocol. 107 110 */ 111 async_exchange_end(exch); 108 112 pipe_end_transaction(pipe); 109 113 110 114 if (data_request == 0) { 111 115 /* … … 116 120 return ENOMEM; 117 121 } 118 122 119 123 /* 120 124 * Wait for the answer. … … 124 128 async_wait_for(data_request, &data_request_rc); 125 129 async_wait_for(opening_request, &opening_request_rc); 126 130 127 131 if (data_request_rc != EOK) { 128 132 /* Prefer the return code of the opening request. */ … … 136 140 return (int) opening_request_rc; 137 141 } 138 142 139 143 *size_transfered = IPC_GET_ARG2(data_request_call); 140 144 141 145 return EOK; 142 146 } … … 228 232 /* Ensure serialization over the phone. */ 229 233 pipe_start_transaction(pipe); 230 234 async_exch_t *exch = async_exchange_begin(pipe->hc_sess); 235 231 236 /* 232 237 * Make call identifying target USB device and type of transfer. 233 238 */ 234 aid_t opening_request = async_send_3(pipe->hc_phone, 235 DEV_IFACE_ID(USBHC_DEV_IFACE), ipc_method, 236 pipe->wire->address, pipe->endpoint_no, 237 NULL); 239 aid_t opening_request = async_send_3(exch, DEV_IFACE_ID(USBHC_DEV_IFACE), 240 ipc_method, pipe->wire->address, pipe->endpoint_no, NULL); 241 238 242 if (opening_request == 0) { 243 async_exchange_end(exch); 239 244 pipe_end_transaction(pipe); 240 245 return ENOMEM; 241 246 } 242 247 243 248 /* 244 249 * Send the data. 245 250 */ 246 int rc = async_data_write_start( pipe->hc_phone, buffer, size);247 251 int rc = async_data_write_start(exch, buffer, size); 252 248 253 /* 249 254 * Since now on, someone else might access the backing phone 250 255 * without breaking the transfer IPC protocol. 251 256 */ 257 async_exchange_end(exch); 252 258 pipe_end_transaction(pipe); 253 259 254 260 if (rc != EOK) { 255 261 async_wait_for(opening_request, NULL); 256 262 return rc; 257 263 } 258 264 259 265 /* 260 266 * Wait for the answer. … … 262 268 sysarg_t opening_request_rc; 263 269 async_wait_for(opening_request, &opening_request_rc); 264 270 265 271 return (int) opening_request_rc; 266 272 } … … 349 355 * Make call identifying target USB device and control transfer type. 350 356 */ 351 a id_t opening_request = async_send_3(pipe->hc_phone,352 DEV_IFACE_ID(USBHC_DEV_IFACE), IPC_M_USBHC_CONTROL_READ,353 pipe->wire->address, pipe->endpoint_no,357 async_exch_t *exch = async_exchange_begin(pipe->hc_sess); 358 aid_t opening_request = async_send_3(exch, DEV_IFACE_ID(USBHC_DEV_IFACE), 359 IPC_M_USBHC_CONTROL_READ, pipe->wire->address, pipe->endpoint_no, 354 360 NULL); 361 355 362 if (opening_request == 0) { 363 async_exchange_end(exch); 356 364 return ENOMEM; 357 365 } 358 366 359 367 /* 360 368 * Send the setup packet. 361 369 */ 362 int rc = async_data_write_start( pipe->hc_phone,363 setup_buffer, setup_buffer_size);364 if (rc != EOK) {370 int rc = async_data_write_start(exch, setup_buffer, setup_buffer_size); 371 if (rc != EOK) { 372 async_exchange_end(exch); 365 373 pipe_end_transaction(pipe); 366 374 async_wait_for(opening_request, NULL); 367 375 return rc; 368 376 } 369 377 370 378 /* 371 379 * Retrieve the data. 372 380 */ 373 381 ipc_call_t data_request_call; 374 aid_t data_request = async_data_read(pipe->hc_phone, 375 data_buffer, data_buffer_size, 376 &data_request_call); 377 382 aid_t data_request = async_data_read(exch, data_buffer, 383 data_buffer_size, &data_request_call); 384 378 385 /* 379 386 * Since now on, someone else might access the backing phone 380 387 * without breaking the transfer IPC protocol. 381 388 */ 389 async_exchange_end(exch); 382 390 pipe_end_transaction(pipe); 383 384 391 385 392 if (data_request == 0) { 386 393 async_wait_for(opening_request, NULL); … … 494 501 * Make call identifying target USB device and control transfer type. 495 502 */ 496 a id_t opening_request = async_send_4(pipe->hc_phone,497 DEV_IFACE_ID(USBHC_DEV_IFACE), IPC_M_USBHC_CONTROL_WRITE,498 pipe->wire->address, pipe->endpoint_no,499 data_buffer_size, 500 NULL);503 async_exch_t *exch = async_exchange_begin(pipe->hc_sess); 504 aid_t opening_request = async_send_4(exch, DEV_IFACE_ID(USBHC_DEV_IFACE), 505 IPC_M_USBHC_CONTROL_WRITE, pipe->wire->address, pipe->endpoint_no, 506 data_buffer_size, NULL); 507 501 508 if (opening_request == 0) { 509 async_exchange_end(exch); 502 510 pipe_end_transaction(pipe); 503 511 return ENOMEM; 504 512 } 505 513 506 514 /* 507 515 * Send the setup packet. 508 516 */ 509 int rc = async_data_write_start( pipe->hc_phone,510 setup_buffer, setup_buffer_size);511 if (rc != EOK) {517 int rc = async_data_write_start(exch, setup_buffer, setup_buffer_size); 518 if (rc != EOK) { 519 async_exchange_end(exch); 512 520 pipe_end_transaction(pipe); 513 521 async_wait_for(opening_request, NULL); 514 522 return rc; 515 523 } 516 524 517 525 /* 518 526 * Send the data (if any). 519 527 */ 520 528 if (data_buffer_size > 0) { 521 rc = async_data_write_start(pipe->hc_phone, 522 data_buffer, data_buffer_size); 523 529 rc = async_data_write_start(exch, data_buffer, data_buffer_size); 530 524 531 /* All data sent, pipe can be released. */ 532 async_exchange_end(exch); 525 533 pipe_end_transaction(pipe); 526 534 527 535 if (rc != EOK) { 528 536 async_wait_for(opening_request, NULL); … … 531 539 } else { 532 540 /* No data to send, we can release the pipe for others. */ 541 async_exchange_end(exch); 533 542 pipe_end_transaction(pipe); 534 543 } 535 544 536 545 /* 537 546 * Wait for the answer.
Note:
See TracChangeset
for help on using the changeset viewer.