Changeset 02fc5c4 in mainline
- Timestamp:
- 2011-11-25T17:41:23Z (13 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 095bddfc
- Parents:
- 56bdd9a4
- Location:
- uspace
- Files:
-
- 9 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/bus/usb/ehci/hc_iface.c
r56bdd9a4 r02fc5c4 149 149 .request_address = request_address, 150 150 .bind_address = bind_address, 151 . find_by_address= find_by_address,151 .get_handle = find_by_address, 152 152 .release_address = release_address, 153 153 -
uspace/drv/bus/usb/vhc/connhost.c
r56bdd9a4 r02fc5c4 508 508 .request_address = request_address, 509 509 .bind_address = bind_address, 510 . find_by_address= find_by_address,510 .get_handle = find_by_address, 511 511 .release_address = release_address, 512 512 -
uspace/lib/drv/generic/remote_usbhc.c
r56bdd9a4 r02fc5c4 1 1 /* 2 2 * Copyright (c) 2010-2011 Vojtech Horky 3 * Copyright (c) 2011 Jan Vesely 3 4 * All rights reserved. 4 5 * … … 42 43 #define USB_MAX_PAYLOAD_SIZE 1020 43 44 45 /** IPC methods for communication with HC through DDF interface. 46 * 47 * Notes for async methods: 48 * 49 * Methods for sending data to device (OUT transactions) 50 * - e.g. IPC_M_USBHC_INTERRUPT_OUT - 51 * always use the same semantics: 52 * - first, IPC call with given method is made 53 * - argument #1 is target address 54 * - argument #2 is target endpoint 55 * - argument #3 is max packet size of the endpoint 56 * - this call is immediately followed by IPC data write (from caller) 57 * - the initial call (and the whole transaction) is answer after the 58 * transaction is scheduled by the HC and acknowledged by the device 59 * or immediately after error is detected 60 * - the answer carries only the error code 61 * 62 * Methods for retrieving data from device (IN transactions) 63 * - e.g. IPC_M_USBHC_INTERRUPT_IN - 64 * also use the same semantics: 65 * - first, IPC call with given method is made 66 * - argument #1 is target address 67 * - argument #2 is target endpoint 68 * - this call is immediately followed by IPC data read (async version) 69 * - the call is not answered until the device returns some data (or until 70 * error occurs) 71 * 72 * Some special methods (NO-DATA transactions) do not send any data. These 73 * might behave as both OUT or IN transactions because communication parts 74 * where actual buffers are exchanged are omitted. 75 ** 76 * For all these methods, wrap functions exists. Important rule: functions 77 * for IN transactions have (as parameters) buffers where retrieved data 78 * will be stored. These buffers must be already allocated and shall not be 79 * touch until the transaction is completed 80 * (e.g. not before calling usb_wait_for() with appropriate handle). 81 * OUT transactions buffers can be freed immediately after call is dispatched 82 * (i.e. after return from wrapping function). 83 * 84 */ 85 typedef enum { 86 /** Asks for address assignment by host controller. 87 * Answer: 88 * - ELIMIT - host controller run out of address 89 * - EOK - address assigned 90 * Answer arguments: 91 * - assigned address 92 * 93 * The address must be released by via IPC_M_USBHC_RELEASE_ADDRESS. 94 */ 95 IPC_M_USBHC_REQUEST_ADDRESS, 96 97 /** Bind USB address with devman handle. 98 * Parameters: 99 * - USB address 100 * - devman handle 101 * Answer: 102 * - EOK - address binded 103 * - ENOENT - address is not in use 104 */ 105 IPC_M_USBHC_BIND_ADDRESS, 106 107 /** Get handle binded with given USB address. 108 * Parameters 109 * - USB address 110 * Answer: 111 * - EOK - address binded, first parameter is the devman handle 112 * - ENOENT - address is not in use at the moment 113 */ 114 IPC_M_USBHC_GET_HANDLE_BY_ADDRESS, 115 116 /** Release address in use. 117 * Arguments: 118 * - address to be released 119 * Answer: 120 * - ENOENT - address not in use 121 * - EPERM - trying to release default USB address 122 */ 123 IPC_M_USBHC_RELEASE_ADDRESS, 124 125 /** Register endpoint attributes at host controller. 126 * This is used to reserve portion of USB bandwidth. 127 * When speed is invalid, speed of the device is used. 128 * Parameters: 129 * - USB address + endpoint number 130 * - packed as ADDR << 16 + EP 131 * - speed + transfer type + direction 132 * - packed as ( SPEED << 8 + TYPE ) << 8 + DIR 133 * - maximum packet size + interval (in milliseconds) 134 * - packed as MPS << 16 + INT 135 * Answer: 136 * - EOK - reservation successful 137 * - ELIMIT - not enough bandwidth to satisfy the request 138 */ 139 IPC_M_USBHC_REGISTER_ENDPOINT, 140 141 /** Revert endpoint registration. 142 * Parameters: 143 * - USB address 144 * - endpoint number 145 * - data direction 146 * Answer: 147 * - EOK - endpoint unregistered 148 * - ENOENT - unknown endpoint 149 */ 150 IPC_M_USBHC_UNREGISTER_ENDPOINT, 151 152 /** Get data from device. 153 * See explanation at usb_iface_funcs_t (IN transaction). 154 */ 155 IPC_M_USBHC_READ, 156 157 /** Send data to device. 158 * See explanation at usb_iface_funcs_t (OUT transaction). 159 */ 160 IPC_M_USBHC_WRITE, 161 } usbhc_iface_funcs_t; 162 163 int usbhc_request_address(async_exch_t *exch, usb_address_t *address, 164 bool strict, usb_speed_t speed) 165 { 166 if (!exch || !address) 167 return EINVAL; 168 sysarg_t new_address; 169 const int ret = async_req_4_1(exch, DEV_IFACE_ID(USBHC_DEV_IFACE), 170 IPC_M_USBHC_REQUEST_ADDRESS, *address, strict, speed, &new_address); 171 if (ret == EOK) 172 *address = (usb_address_t)new_address; 173 return ret; 174 } 175 /*----------------------------------------------------------------------------*/ 176 int usbhc_bind_address(async_exch_t *exch, usb_address_t address, 177 devman_handle_t handle) 178 { 179 if (!exch) 180 return EINVAL; 181 return async_req_3_0(exch, DEV_IFACE_ID(USBHC_DEV_IFACE), 182 IPC_M_USBHC_BIND_ADDRESS, address, handle); 183 } 184 /*----------------------------------------------------------------------------*/ 185 int usbhc_get_handle(async_exch_t *exch, usb_address_t address, 186 devman_handle_t *handle) 187 { 188 if (!exch) 189 return EINVAL; 190 sysarg_t h; 191 const int ret = async_req_2_1(exch, DEV_IFACE_ID(USBHC_DEV_IFACE), 192 IPC_M_USBHC_GET_HANDLE_BY_ADDRESS, address, &h); 193 if (ret == EOK && handle) 194 *handle = (devman_handle_t)h; 195 return ret; 196 } 197 /*----------------------------------------------------------------------------*/ 198 int usbhc_release_address(async_exch_t *exch, usb_address_t address) 199 { 200 if (!exch) 201 return EINVAL; 202 return async_req_2_0(exch, DEV_IFACE_ID(USBHC_DEV_IFACE), 203 IPC_M_USBHC_RELEASE_ADDRESS, address); 204 } 205 /*----------------------------------------------------------------------------*/ 206 int usbhc_register_endpoint(async_exch_t *exch, usb_address_t address, 207 usb_endpoint_t endpoint, usb_transfer_type_t type, 208 usb_direction_t direction, size_t mps, unsigned interval) 209 { 210 if (!exch) 211 return EINVAL; 212 const usb_target_t target = 213 {{ .address = address, .endpoint = endpoint }}; 214 #define _PACK2(high, low) (((high & 0xffff) << 16) | (low & 0xffff)) 215 216 return async_req_4_0(exch, DEV_IFACE_ID(USBHC_DEV_IFACE), 217 IPC_M_USBHC_REGISTER_ENDPOINT, target.packed, 218 _PACK2(type, direction), _PACK2(mps, interval)); 219 220 #undef _PACK2 221 } 222 /*----------------------------------------------------------------------------*/ 223 int usbhc_unregister_endpoint(async_exch_t *exch, usb_address_t address, 224 usb_endpoint_t endpoint, usb_direction_t direction) 225 { 226 if (!exch) 227 return EINVAL; 228 return async_req_4_0(exch, DEV_IFACE_ID(USBHC_DEV_IFACE), 229 IPC_M_USBHC_UNREGISTER_ENDPOINT, address, endpoint, direction); 230 } 231 /*----------------------------------------------------------------------------*/ 232 int usbhc_read(async_exch_t *exch, usb_address_t address, 233 usb_endpoint_t endpoint, uint64_t setup, void *data, size_t size, 234 size_t *rec_size) 235 { 236 if (size == 0 && setup == 0) 237 return EOK; 238 239 if (!exch) 240 return EINVAL; 241 const usb_target_t target = 242 {{ .address = address, .endpoint = endpoint }}; 243 244 /* Make call identifying target USB device and type of transfer. */ 245 aid_t opening_request = async_send_4(exch, 246 DEV_IFACE_ID(USBHC_DEV_IFACE), 247 IPC_M_USBHC_READ, target.packed, 248 (setup & UINT32_MAX), (setup >> 32), NULL); 249 250 if (opening_request == 0) { 251 return ENOMEM; 252 } 253 254 /* Retrieve the data. */ 255 ipc_call_t data_request_call; 256 aid_t data_request = 257 async_data_read(exch, data, size, &data_request_call); 258 259 if (data_request == 0) { 260 // FIXME: How to let the other side know that we want to abort? 261 async_wait_for(opening_request, NULL); 262 return ENOMEM; 263 } 264 265 /* Wait for the answer. */ 266 sysarg_t data_request_rc; 267 sysarg_t opening_request_rc; 268 async_wait_for(data_request, &data_request_rc); 269 async_wait_for(opening_request, &opening_request_rc); 270 271 if (data_request_rc != EOK) { 272 /* Prefer the return code of the opening request. */ 273 if (opening_request_rc != EOK) { 274 return (int) opening_request_rc; 275 } else { 276 return (int) data_request_rc; 277 } 278 } 279 if (opening_request_rc != EOK) { 280 return (int) opening_request_rc; 281 } 282 283 *rec_size = IPC_GET_ARG2(data_request_call); 284 return EOK; 285 } 286 /*----------------------------------------------------------------------------*/ 287 int usbhc_write(async_exch_t *exch, usb_address_t address, 288 usb_endpoint_t endpoint, uint64_t setup, const void *data, size_t size) 289 { 290 if (size == 0 && setup == 0) 291 return EOK; 292 293 if (!exch) 294 return EINVAL; 295 const usb_target_t target = 296 {{ .address = address, .endpoint = endpoint }}; 297 298 aid_t opening_request = async_send_5(exch, DEV_IFACE_ID(USBHC_DEV_IFACE), 299 IPC_M_USBHC_WRITE, target.packed, size, 300 (setup & UINT32_MAX), (setup >> 32), NULL); 301 302 if (opening_request == 0) { 303 return ENOMEM; 304 } 305 306 /* Send the data if any. */ 307 if (size > 0) { 308 const int ret = async_data_write_start(exch, data, size); 309 if (ret != EOK) { 310 async_wait_for(opening_request, NULL); 311 return ret; 312 } 313 } 314 315 /* Wait for the answer. */ 316 sysarg_t opening_request_rc; 317 async_wait_for(opening_request, &opening_request_rc); 318 319 return (int) opening_request_rc; 320 } 321 /*----------------------------------------------------------------------------*/ 322 44 323 static void remote_usbhc_request_address(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *); 45 324 static void remote_usbhc_bind_address(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *); 46 static void remote_usbhc_ find_by_address(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *);325 static void remote_usbhc_get_handle(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *); 47 326 static void remote_usbhc_release_address(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *); 48 327 static void remote_usbhc_register_endpoint(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *); … … 57 336 [IPC_M_USBHC_RELEASE_ADDRESS] = remote_usbhc_release_address, 58 337 [IPC_M_USBHC_BIND_ADDRESS] = remote_usbhc_bind_address, 59 [IPC_M_USBHC_GET_HANDLE_BY_ADDRESS] = remote_usbhc_ find_by_address,338 [IPC_M_USBHC_GET_HANDLE_BY_ADDRESS] = remote_usbhc_get_handle, 60 339 61 340 [IPC_M_USBHC_REGISTER_ENDPOINT] = remote_usbhc_register_endpoint, … … 107 386 return trans; 108 387 } 109 388 /*----------------------------------------------------------------------------*/ 110 389 void remote_usbhc_request_address(ddf_fun_t *fun, void *iface, 111 390 ipc_callid_t callid, ipc_call_t *call) 112 391 { 113 usbhc_iface_t *usb_iface = (usbhc_iface_t *)iface;392 const usbhc_iface_t *usb_iface = iface; 114 393 115 394 if (!usb_iface->request_address) { … … 129 408 } 130 409 } 131 410 /*----------------------------------------------------------------------------*/ 132 411 void remote_usbhc_bind_address(ddf_fun_t *fun, void *iface, 133 412 ipc_callid_t callid, ipc_call_t *call) 134 413 { 135 usbhc_iface_t *usb_iface = (usbhc_iface_t *)iface;414 const usbhc_iface_t *usb_iface = iface; 136 415 137 416 if (!usb_iface->bind_address) { … … 140 419 } 141 420 142 usb_address_t address = (usb_address_t) DEV_IPC_GET_ARG1(*call); 143 devman_handle_t handle = (devman_handle_t) DEV_IPC_GET_ARG2(*call); 144 145 int rc = usb_iface->bind_address(fun, address, handle); 146 147 async_answer_0(callid, rc); 148 } 149 150 void remote_usbhc_find_by_address(ddf_fun_t *fun, void *iface, 421 const usb_address_t address = (usb_address_t) DEV_IPC_GET_ARG1(*call); 422 const devman_handle_t handle = (devman_handle_t) DEV_IPC_GET_ARG2(*call); 423 424 const int ret = usb_iface->bind_address(fun, address, handle); 425 async_answer_0(callid, ret); 426 } 427 /*----------------------------------------------------------------------------*/ 428 void remote_usbhc_get_handle(ddf_fun_t *fun, void *iface, 151 429 ipc_callid_t callid, ipc_call_t *call) 152 430 { 153 usbhc_iface_t *usb_iface = (usbhc_iface_t *)iface;154 155 if (!usb_iface-> find_by_address) {156 async_answer_0(callid, ENOTSUP); 157 return; 158 } 159 160 usb_address_t address = (usb_address_t) DEV_IPC_GET_ARG1(*call);431 const usbhc_iface_t *usb_iface = iface; 432 433 if (!usb_iface->get_handle) { 434 async_answer_0(callid, ENOTSUP); 435 return; 436 } 437 438 const usb_address_t address = (usb_address_t) DEV_IPC_GET_ARG1(*call); 161 439 devman_handle_t handle; 162 int rc = usb_iface->find_by_address(fun, address, &handle);163 164 if (r c== EOK) {165 async_answer_1(callid, EOK, handle);440 const int ret = usb_iface->get_handle(fun, address, &handle); 441 442 if (ret == EOK) { 443 async_answer_1(callid, ret, handle); 166 444 } else { 167 async_answer_0(callid, r c);168 } 169 } 170 445 async_answer_0(callid, ret); 446 } 447 } 448 /*----------------------------------------------------------------------------*/ 171 449 void remote_usbhc_release_address(ddf_fun_t *fun, void *iface, 172 450 ipc_callid_t callid, ipc_call_t *call) 173 451 { 174 usbhc_iface_t *usb_iface = (usbhc_iface_t *)iface;452 const usbhc_iface_t *usb_iface = iface; 175 453 176 454 if (!usb_iface->release_address) { … … 179 457 } 180 458 181 usb_address_t address = (usb_address_t) DEV_IPC_GET_ARG1(*call); 182 183 int rc = usb_iface->release_address(fun, address); 184 185 async_answer_0(callid, rc); 186 } 187 188 459 const usb_address_t address = (usb_address_t) DEV_IPC_GET_ARG1(*call); 460 461 const int ret = usb_iface->release_address(fun, address); 462 async_answer_0(callid, ret); 463 } 464 /*----------------------------------------------------------------------------*/ 189 465 static void callback_out(ddf_fun_t *fun, 190 466 int outcome, void *arg) -
uspace/lib/drv/include/usbhc_iface.h
r56bdd9a4 r02fc5c4 42 42 #include <bool.h> 43 43 44 45 /** IPC methods for communication with HC through DDF interface. 46 * 47 * Notes for async methods: 48 * 49 * Methods for sending data to device (OUT transactions) 50 * - e.g. IPC_M_USBHC_INTERRUPT_OUT - 51 * always use the same semantics: 52 * - first, IPC call with given method is made 53 * - argument #1 is target address 54 * - argument #2 is target endpoint 55 * - argument #3 is max packet size of the endpoint 56 * - this call is immediately followed by IPC data write (from caller) 57 * - the initial call (and the whole transaction) is answer after the 58 * transaction is scheduled by the HC and acknowledged by the device 59 * or immediately after error is detected 60 * - the answer carries only the error code 61 * 62 * Methods for retrieving data from device (IN transactions) 63 * - e.g. IPC_M_USBHC_INTERRUPT_IN - 64 * also use the same semantics: 65 * - first, IPC call with given method is made 66 * - argument #1 is target address 67 * - argument #2 is target endpoint 68 * - this call is immediately followed by IPC data read (async version) 69 * - the call is not answered until the device returns some data (or until 70 * error occurs) 71 * 72 * Some special methods (NO-DATA transactions) do not send any data. These 73 * might behave as both OUT or IN transactions because communication parts 74 * where actual buffers are exchanged are omitted. 75 ** 76 * For all these methods, wrap functions exists. Important rule: functions 77 * for IN transactions have (as parameters) buffers where retrieved data 78 * will be stored. These buffers must be already allocated and shall not be 79 * touch until the transaction is completed 80 * (e.g. not before calling usb_wait_for() with appropriate handle). 81 * OUT transactions buffers can be freed immediately after call is dispatched 82 * (i.e. after return from wrapping function). 83 * 84 */ 85 typedef enum { 86 /** Asks for address assignment by host controller. 87 * Answer: 88 * - ELIMIT - host controller run out of address 89 * - EOK - address assigned 90 * Answer arguments: 91 * - assigned address 92 * 93 * The address must be released by via IPC_M_USBHC_RELEASE_ADDRESS. 94 */ 95 IPC_M_USBHC_REQUEST_ADDRESS, 96 97 /** Bind USB address with devman handle. 98 * Parameters: 99 * - USB address 100 * - devman handle 101 * Answer: 102 * - EOK - address binded 103 * - ENOENT - address is not in use 104 */ 105 IPC_M_USBHC_BIND_ADDRESS, 106 107 /** Get handle binded with given USB address. 108 * Parameters 109 * - USB address 110 * Answer: 111 * - EOK - address binded, first parameter is the devman handle 112 * - ENOENT - address is not in use at the moment 113 */ 114 IPC_M_USBHC_GET_HANDLE_BY_ADDRESS, 115 116 /** Release address in use. 117 * Arguments: 118 * - address to be released 119 * Answer: 120 * - ENOENT - address not in use 121 * - EPERM - trying to release default USB address 122 */ 123 IPC_M_USBHC_RELEASE_ADDRESS, 124 125 /** Register endpoint attributes at host controller. 126 * This is used to reserve portion of USB bandwidth. 127 * When speed is invalid, speed of the device is used. 128 * Parameters: 129 * - USB address + endpoint number 130 * - packed as ADDR << 16 + EP 131 * - speed + transfer type + direction 132 * - packed as ( SPEED << 8 + TYPE ) << 8 + DIR 133 * - maximum packet size + interval (in milliseconds) 134 * - packed as MPS << 16 + INT 135 * Answer: 136 * - EOK - reservation successful 137 * - ELIMIT - not enough bandwidth to satisfy the request 138 */ 139 IPC_M_USBHC_REGISTER_ENDPOINT, 140 141 /** Revert endpoint registration. 142 * Parameters: 143 * - USB address 144 * - endpoint number 145 * - data direction 146 * Answer: 147 * - EOK - endpoint unregistered 148 * - ENOENT - unknown endpoint 149 */ 150 IPC_M_USBHC_UNREGISTER_ENDPOINT, 151 152 /** Get data from device. 153 * See explanation at usb_iface_funcs_t (IN transaction). 154 */ 155 IPC_M_USBHC_READ, 156 157 /** Send data to device. 158 * See explanation at usb_iface_funcs_t (OUT transaction). 159 */ 160 IPC_M_USBHC_WRITE, 161 } usbhc_iface_funcs_t; 44 int usbhc_request_address(async_exch_t *, usb_address_t *, bool, usb_speed_t); 45 int usbhc_bind_address(async_exch_t *, usb_address_t, devman_handle_t); 46 int usbhc_get_handle(async_exch_t *, usb_address_t, devman_handle_t *); 47 int usbhc_release_address(async_exch_t *, usb_address_t); 48 int usbhc_register_endpoint(async_exch_t *, usb_address_t, usb_endpoint_t, 49 usb_transfer_type_t, usb_direction_t, size_t, unsigned int); 50 int usbhc_unregister_endpoint(async_exch_t *, usb_address_t, usb_endpoint_t, 51 usb_direction_t); 52 int usbhc_read(async_exch_t *, usb_address_t, usb_endpoint_t, 53 uint64_t, void *, size_t, size_t *); 54 int usbhc_write(async_exch_t *, usb_address_t, usb_endpoint_t, 55 uint64_t, const void *, size_t); 162 56 163 57 /** Callback for outgoing transfer. */ … … 172 66 int (*request_address)(ddf_fun_t *, usb_address_t *, bool, usb_speed_t); 173 67 int (*bind_address)(ddf_fun_t *, usb_address_t, devman_handle_t); 174 int (*find_by_address)(ddf_fun_t *, usb_address_t, devman_handle_t *); 68 int (*get_handle)(ddf_fun_t *, usb_address_t, 69 devman_handle_t *); 175 70 int (*release_address)(ddf_fun_t *, usb_address_t); 176 71 -
uspace/lib/usb/src/hc.c
r56bdd9a4 r02fc5c4 153 153 if (!usb_hc_connection_is_opened(connection)) 154 154 return ENOENT; 155 155 156 156 async_exch_t *exch = async_exchange_begin(connection->hc_sess); 157 158 sysarg_t tmp; 159 int rc = async_req_2_1(exch, DEV_IFACE_ID(USBHC_DEV_IFACE), 160 IPC_M_USBHC_GET_HANDLE_BY_ADDRESS, 161 address, &tmp); 162 157 if (!exch) 158 return ENOMEM; 159 const int ret = usbhc_get_handle(exch, address, handle); 163 160 async_exchange_end(exch); 164 165 if ((rc == EOK) && (handle != NULL)) 166 *handle = tmp; 167 168 return rc; 161 return ret; 169 162 } 170 163 -
uspace/lib/usbdev/src/hub.c
r56bdd9a4 r02fc5c4 76 76 { 77 77 CHECK_CONNECTION(connection); 78 78 79 79 async_exch_t *exch = async_exchange_begin(connection->hc_sess); 80 81 sysarg_t address; 82 int rc = async_req_4_1(exch, DEV_IFACE_ID(USBHC_DEV_IFACE), 83 IPC_M_USBHC_REQUEST_ADDRESS, preferred, strict, speed, &address); 84 80 if (!exch) 81 return (usb_address_t)ENOMEM; 82 83 usb_address_t address = preferred; 84 const int ret = usbhc_request_address(exch, &address, strict, speed); 85 85 86 async_exchange_end(exch); 86 87 if (rc != EOK) 88 return (usb_address_t) rc; 89 90 return (usb_address_t) address; 87 return ret == EOK ? address : ret; 91 88 } 92 89 … … 97 94 * @return Error code. 98 95 */ 99 int usb_hc_register_device(usb_hc_connection_t * 96 int usb_hc_register_device(usb_hc_connection_t *connection, 100 97 const usb_hub_attached_device_t *attached_device) 101 98 { 102 99 CHECK_CONNECTION(connection); 103 104 if (attached_device == NULL) 105 return EBADMEM; 106 100 if (attached_device == NULL || attached_device->fun == NULL) 101 return EINVAL; 102 107 103 async_exch_t *exch = async_exchange_begin(connection->hc_sess); 108 int rc = async_req_3_0(exch, DEV_IFACE_ID(USBHC_DEV_IFACE), 109 IPC_M_USBHC_BIND_ADDRESS, 104 if (!exch) 105 return ENOMEM; 106 const int ret = usbhc_bind_address(exch, 110 107 attached_device->address, attached_device->fun->handle); 111 108 async_exchange_end(exch); 112 113 return r c;109 110 return ret; 114 111 } 115 112 … … 124 121 { 125 122 CHECK_CONNECTION(connection); 126 123 127 124 async_exch_t *exch = async_exchange_begin(connection->hc_sess); 128 int rc = async_req_2_0(exch, DEV_IFACE_ID(USBHC_DEV_IFACE), 129 IPC_M_USBHC_RELEASE_ADDRESS, address); 125 if (!exch) 126 return ENOMEM; 127 const int ret = usbhc_release_address(exch, address); 130 128 async_exchange_end(exch); 131 132 return r c;129 130 return ret; 133 131 } 134 132 -
uspace/lib/usbdev/src/pipesinit.c
r56bdd9a4 r02fc5c4 405 405 } 406 406 407 #define TRY_LOOP(attempt_var) \408 for (attempt_var = 0; attempt_var < 3; attempt_var++)409 410 size_t failed_attempts;411 int rc;412 407 413 408 usb_pipe_start_long_transfer(pipe); … … 415 410 uint8_t dev_descr_start[CTRL_PIPE_MIN_PACKET_SIZE]; 416 411 size_t transferred_size; 417 TRY_LOOP(failed_attempts) { 412 int rc; 413 for (size_t attempt_var = 0; attempt_var < 3; ++attempt_var) { 418 414 rc = usb_request_get_descriptor(pipe, USB_REQUEST_TYPE_STANDARD, 419 415 USB_REQUEST_RECIPIENT_DEVICE, USB_DESCTYPE_DEVICE, … … 450 446 { 451 447 assert(pipe); 448 assert(pipe->wire); 452 449 assert(hc_connection); 453 450 454 451 if (!usb_hc_connection_is_opened(hc_connection)) 455 452 return EBADF; 456 457 const usb_target_t target =458 {{ .address = pipe->wire->address, .endpoint = pipe->endpoint_no }};459 #define _PACK2(high, low) (((high & 0xffff) << 16) | (low & 0xffff))460 461 453 async_exch_t *exch = async_exchange_begin(hc_connection->hc_sess); 462 int rc = async_req_4_0(exch, DEV_IFACE_ID(USBHC_DEV_IFACE), 463 IPC_M_USBHC_REGISTER_ENDPOINT, target.packed, 464 _PACK2(pipe->transfer_type, pipe->direction), 465 _PACK2(pipe->max_packet_size, interval)); 454 if (!exch) 455 return ENOMEM; 456 const int ret = usbhc_register_endpoint(exch, 457 pipe->wire->address, pipe->endpoint_no, pipe->transfer_type, 458 pipe->direction, pipe->max_packet_size, interval); 459 466 460 async_exchange_end(exch); 467 468 #undef _PACK2 469 return rc; 461 return ret; 470 462 } 471 463 … … 482 474 assert(pipe->wire); 483 475 assert(hc_connection); 484 476 485 477 if (!usb_hc_connection_is_opened(hc_connection)) 486 478 return EBADF; 487 479 488 480 async_exch_t *exch = async_exchange_begin(hc_connection->hc_sess); 489 int rc = async_req_4_0(exch, DEV_IFACE_ID(USBHC_DEV_IFACE), 490 IPC_M_USBHC_UNREGISTER_ENDPOINT, 481 if (!exch) 482 return ENOMEM; 483 const int ret = usbhc_unregister_endpoint(exch, 491 484 pipe->wire->address, pipe->endpoint_no, pipe->direction); 492 485 async_exchange_end(exch); 493 494 return r c;486 487 return ret; 495 488 } 496 489 -
uspace/lib/usbdev/src/pipesio.c
r56bdd9a4 r02fc5c4 70 70 return ENOTSUP; 71 71 72 const usb_target_t target =73 {{ .address = pipe->wire->address, .endpoint = pipe->endpoint_no }};74 75 72 /* Ensure serialization over the phone. */ 76 73 pipe_start_transaction(pipe); 77 74 async_exch_t *exch = async_exchange_begin(pipe->hc_sess); 78 79 /* 80 * Make call identifying target USB device and type of transfer. 81 */ 82 aid_t opening_request = async_send_2(exch, DEV_IFACE_ID(USBHC_DEV_IFACE), 83 IPC_M_USBHC_READ, target.packed, NULL); 84 85 if (opening_request == 0) { 86 async_exchange_end(exch); 75 if (!exch) { 87 76 pipe_end_transaction(pipe); 88 77 return ENOMEM; 89 78 } 90 91 /* 92 * Retrieve the data. 93 */ 94 ipc_call_t data_request_call; 95 aid_t data_request = async_data_read(exch, buffer, size, 96 &data_request_call); 97 98 /* 99 * Since now on, someone else might access the backing phone 100 * without breaking the transfer IPC protocol. 101 */ 79 80 const int ret = usbhc_read(exch, pipe->wire->address, pipe->endpoint_no, 81 0, buffer, size, size_transfered); 102 82 async_exchange_end(exch); 103 83 pipe_end_transaction(pipe); 104 105 if (data_request == 0) { 106 /* 107 * FIXME: 108 * How to let the other side know that we want to abort? 109 */ 110 async_wait_for(opening_request, NULL); 111 return ENOMEM; 112 } 113 114 /* 115 * Wait for the answer. 116 */ 117 sysarg_t data_request_rc; 118 sysarg_t opening_request_rc; 119 async_wait_for(data_request, &data_request_rc); 120 async_wait_for(opening_request, &opening_request_rc); 121 122 if (data_request_rc != EOK) { 123 /* Prefer the return code of the opening request. */ 124 if (opening_request_rc != EOK) { 125 return (int) opening_request_rc; 126 } else { 127 return (int) data_request_rc; 128 } 129 } 130 if (opening_request_rc != EOK) { 131 return (int) opening_request_rc; 132 } 133 134 *size_transfered = IPC_GET_ARG2(data_request_call); 135 136 return EOK; 84 return ret; 137 85 } 138 86 … … 209 157 return ENOTSUP; 210 158 211 const usb_target_t target =212 {{ .address = pipe->wire->address, .endpoint = pipe->endpoint_no }};213 214 159 /* Ensure serialization over the phone. */ 215 160 pipe_start_transaction(pipe); 216 161 async_exch_t *exch = async_exchange_begin(pipe->hc_sess); 217 218 /* 219 * Make call identifying target USB device and type of transfer. 220 */ 221 aid_t opening_request = async_send_3(exch, DEV_IFACE_ID(USBHC_DEV_IFACE), 222 IPC_M_USBHC_WRITE, target.packed, size, NULL); 223 224 if (opening_request == 0) { 225 async_exchange_end(exch); 162 if (!exch) { 226 163 pipe_end_transaction(pipe); 227 164 return ENOMEM; 228 165 } 229 230 /* 231 * Send the data. 232 */ 233 int rc = async_data_write_start(exch, buffer, size); 234 235 /* 236 * Since now on, someone else might access the backing phone 237 * without breaking the transfer IPC protocol. 238 */ 166 const int ret = 167 usbhc_write(exch, pipe->wire->address, pipe->endpoint_no, 168 0, buffer, size); 239 169 async_exchange_end(exch); 240 170 pipe_end_transaction(pipe); 241 242 if (rc != EOK) { 243 async_wait_for(opening_request, NULL); 244 return rc; 245 } 246 247 /* 248 * Wait for the answer. 249 */ 250 sysarg_t opening_request_rc; 251 async_wait_for(opening_request, &opening_request_rc); 252 253 return (int) opening_request_rc; 171 return ret; 254 172 } 255 173 … … 334 252 pipe_start_transaction(pipe); 335 253 336 const usb_target_t target =337 {{ .address = pipe->wire->address, .endpoint = pipe->endpoint_no }};338 339 254 assert(setup_buffer_size == 8); 340 255 uint64_t setup_packet; 341 256 memcpy(&setup_packet, setup_buffer, 8); 342 /* 343 * Make call identifying target USB device and control transfer type. 344 */ 257 345 258 async_exch_t *exch = async_exchange_begin(pipe->hc_sess); 346 aid_t opening_request = async_send_4(exch, DEV_IFACE_ID(USBHC_DEV_IFACE), 347 IPC_M_USBHC_READ, target.packed, 348 (setup_packet & UINT32_MAX), (setup_packet >> 32), NULL); 349 350 if (opening_request == 0) { 351 async_exchange_end(exch); 259 if (!exch) { 260 pipe_end_transaction(pipe); 352 261 return ENOMEM; 353 262 } 354 263 355 /* 356 * Retrieve the data. 357 */ 358 ipc_call_t data_request_call; 359 aid_t data_request = async_data_read(exch, data_buffer, 360 data_buffer_size, &data_request_call); 361 362 /* 363 * Since now on, someone else might access the backing phone 364 * without breaking the transfer IPC protocol. 365 */ 264 const int ret = usbhc_read(exch, pipe->wire->address, pipe->endpoint_no, 265 setup_packet, data_buffer, data_buffer_size, data_transfered_size); 366 266 async_exchange_end(exch); 367 267 pipe_end_transaction(pipe); 368 369 if (data_request == 0) { 370 async_wait_for(opening_request, NULL); 371 return ENOMEM; 372 } 373 374 /* 375 * Wait for the answer. 376 */ 377 sysarg_t data_request_rc; 378 sysarg_t opening_request_rc; 379 async_wait_for(data_request, &data_request_rc); 380 async_wait_for(opening_request, &opening_request_rc); 381 382 if (data_request_rc != EOK) { 383 /* Prefer the return code of the opening request. */ 384 if (opening_request_rc != EOK) { 385 return (int) opening_request_rc; 386 } else { 387 return (int) data_request_rc; 388 } 389 } 390 if (opening_request_rc != EOK) { 391 return (int) opening_request_rc; 392 } 393 394 *data_transfered_size = IPC_GET_ARG2(data_request_call); 395 396 return EOK; 268 return ret; 397 269 } 398 270 … … 475 347 pipe_start_transaction(pipe); 476 348 477 const usb_target_t target =478 {{ .address = pipe->wire->address, .endpoint = pipe->endpoint_no }};479 349 assert(setup_buffer_size == 8); 480 350 uint64_t setup_packet; 481 351 memcpy(&setup_packet, setup_buffer, 8); 482 352 483 /* 484 * Make call identifying target USB device and control transfer type. 485 */ 353 /* Make call identifying target USB device and control transfer type. */ 486 354 async_exch_t *exch = async_exchange_begin(pipe->hc_sess); 487 aid_t opening_request = async_send_5(exch, DEV_IFACE_ID(USBHC_DEV_IFACE), 488 IPC_M_USBHC_WRITE, target.packed, data_buffer_size, 489 (setup_packet & UINT32_MAX), (setup_packet >> 32), NULL); 490 491 if (opening_request == 0) { 492 async_exchange_end(exch); 355 if (!exch) { 493 356 pipe_end_transaction(pipe); 494 357 return ENOMEM; 495 358 } 496 497 /* 498 * Send the data (if any). 499 */ 500 if (data_buffer_size > 0) { 501 int rc = async_data_write_start(exch, data_buffer, data_buffer_size); 502 503 /* All data sent, pipe can be released. */ 504 async_exchange_end(exch); 505 pipe_end_transaction(pipe); 506 507 if (rc != EOK) { 508 async_wait_for(opening_request, NULL); 509 return rc; 510 } 511 } else { 512 /* No data to send, we can release the pipe for others. */ 513 async_exchange_end(exch); 514 pipe_end_transaction(pipe); 515 } 516 517 /* 518 * Wait for the answer. 519 */ 520 sysarg_t opening_request_rc; 521 async_wait_for(opening_request, &opening_request_rc); 522 523 return (int) opening_request_rc; 359 const int ret = 360 usbhc_write(exch, pipe->wire->address, pipe->endpoint_no, 361 setup_packet, data_buffer, data_buffer_size); 362 async_exchange_end(exch); 363 pipe_end_transaction(pipe); 364 return ret; 524 365 } 525 366 -
uspace/lib/usbhost/src/iface.c
r56bdd9a4 r02fc5c4 252 252 .request_address = request_address, 253 253 .bind_address = bind_address, 254 . find_by_address= find_by_address,254 .get_handle = find_by_address, 255 255 .release_address = release_address, 256 256
Note:
See TracChangeset
for help on using the changeset viewer.