Changeset 239eea41 in mainline
- Timestamp:
- 2018-02-05T02:04:58Z (7 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- fc3dfe6d
- Parents:
- af16ebe
- Location:
- uspace/lib
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/drv/generic/remote_usbhc.c
raf16ebe r239eea41 51 51 IPC_M_USB_REGISTER_ENDPOINT, 52 52 IPC_M_USB_UNREGISTER_ENDPOINT, 53 IPC_M_USB_READ, 54 IPC_M_USB_WRITE, 53 IPC_M_USB_TRANSFER, 55 54 } usbhc_iface_funcs_t; 56 55 … … 183 182 * temporarily shared with the HC. 184 183 */ 185 errno_t usbhc_transfer(async_exch_t *exch, usb_endpoint_t endpoint, 186 usb_direction_t dir, uint64_t setup, void *area, size_t size, 187 size_t *transferred) 184 errno_t usbhc_transfer(async_exch_t *exch, 185 const usbhc_iface_transfer_request_t *req, size_t *transferred) 188 186 { 189 187 if (transferred) … … 193 191 return EBADMEM; 194 192 195 if (size == 0 && setup == 0)196 return EOK;197 198 sysarg_t method = (dir == USB_DIRECTION_IN)199 ? IPC_M_USB_READ : IPC_M_USB_WRITE;200 201 193 ipc_call_t call; 202 194 203 204 aid_t opening_request = async_send_5(exch, DEV_IFACE_ID(USBHC_DEV_IFACE), 205 method, endpoint, size, (setup & UINT32_MAX), (setup >> 32), &call); 195 aid_t opening_request = async_send_1(exch, DEV_IFACE_ID(USBHC_DEV_IFACE), 196 IPC_M_USB_TRANSFER, &call); 206 197 207 198 if (opening_request == 0) 208 199 return ENOMEM; 209 200 210 /* Send the data if any. */ 211 if (size > 0) { 212 unsigned flags = (dir == USB_DIRECTION_IN) 201 const errno_t ret = async_data_write_start(exch, req, sizeof(*req)); 202 if (ret != EOK) { 203 async_forget(opening_request); 204 return ret; 205 } 206 207 /* Share the data, if any. */ 208 if (req->size > 0) { 209 unsigned flags = (req->dir == USB_DIRECTION_IN) 213 210 ? AS_AREA_WRITE : AS_AREA_READ; 214 211 215 const errno_t ret = async_share_out_start(exch, area, flags);212 const errno_t ret = async_share_out_start(exch, req->base, flags); 216 213 if (ret != EOK) { 217 214 async_forget(opening_request); … … 244 241 [IPC_M_USB_REGISTER_ENDPOINT] = remote_usbhc_register_endpoint, 245 242 [IPC_M_USB_UNREGISTER_ENDPOINT] = remote_usbhc_unregister_endpoint, 246 [IPC_M_USB_READ] = remote_usbhc_transfer, 247 [IPC_M_USB_WRITE] = remote_usbhc_transfer, 243 [IPC_M_USB_TRANSFER] = remote_usbhc_transfer, 248 244 }; 249 245 … … 257 253 typedef struct { 258 254 ipc_callid_t caller; 259 void *buffer;255 usbhc_iface_transfer_request_t request; 260 256 } async_transaction_t; 261 257 … … 378 374 return; 379 375 } 380 if (trans-> buffer!= NULL) {381 as_area_destroy(trans-> buffer);376 if (trans->request.base != NULL) { 377 as_area_destroy(trans->request.base); 382 378 } 383 379 … … 387 383 static async_transaction_t *async_transaction_create(ipc_callid_t caller) 388 384 { 389 async_transaction_t *trans = malloc(sizeof(async_transaction_t)); 390 if (trans == NULL) { 391 return NULL; 392 } 393 394 trans->caller = caller; 395 trans->buffer = NULL; 385 async_transaction_t *trans = calloc(1, sizeof(async_transaction_t)); 386 387 if (trans != NULL) 388 trans->caller = caller; 396 389 397 390 return trans; … … 406 399 } 407 400 408 static errno_t receive_memory_buffer(async_transaction_t *trans, 409 size_t required_size, unsigned required_flags) 401 static errno_t receive_memory_buffer(async_transaction_t *trans) 410 402 { 411 403 assert(trans); 412 assert(required_size > 0); 404 assert(trans->request.size > 0); 405 406 const size_t required_size = trans->request.offset + trans->request.size; 407 const unsigned required_flags = 408 (trans->request.dir == USB_DIRECTION_IN) 409 ? AS_AREA_WRITE : AS_AREA_READ; 413 410 414 411 errno_t err; … … 425 422 } 426 423 427 if ((err = async_share_out_finalize(data_callid, &trans-> buffer)))424 if ((err = async_share_out_finalize(data_callid, &trans->request.base))) 428 425 return err; 429 426 … … 435 432 if (flags & AS_AREA_READ) { 436 433 char foo = 0; 437 volatile const char *buf = trans-> buffer;434 volatile const char *buf = trans->request.base + trans->request.offset; 438 435 for (size_t i = 0; i < size; i += PAGE_SIZE) 439 436 foo += buf[i]; 440 437 } else { 441 volatile char *buf = trans-> buffer;438 volatile char *buf = trans->request.base + trans->request.offset; 442 439 for (size_t i = 0; i < size; i += PAGE_SIZE) 443 440 buf[i] = 0xff; … … 460 457 } 461 458 462 const sysarg_t method = IPC_GET_ARG1(*call);463 const usb_direction_t dir =464 method == IPC_M_USB_READ ? USB_DIRECTION_IN : USB_DIRECTION_OUT;465 466 const usb_endpoint_t ep = IPC_GET_ARG2(*call);467 const size_t size = IPC_GET_ARG3(*call);468 const uint64_t setup = ((uint64_t)IPC_GET_ARG4(*call)) |469 (((uint64_t)IPC_GET_ARG5(*call)) << 32);470 471 459 async_transaction_t *trans = async_transaction_create(callid); 472 460 if (trans == NULL) { … … 475 463 } 476 464 477 if (size > 0) { 478 const unsigned required_flags = (dir == USB_DIRECTION_IN) 479 ? AS_AREA_WRITE : AS_AREA_READ; 480 481 const errno_t rc = receive_memory_buffer(trans, size, required_flags); 482 if (rc != EOK) { 483 async_transaction_destroy(trans); 484 async_answer_0(callid, rc); 485 return; 486 } 487 } 488 489 const usb_target_t target = {{ 490 /* .address is initialized by write itself */ 491 .endpoint = ep, 492 /* streams are not given by the API call yet */ 493 .stream = 0, 494 }}; 495 496 const errno_t rc = usbhc_iface->transfer(fun, target, dir, setup, 497 trans->buffer, size, &transfer_finished, trans); 498 499 if (rc != EOK) { 500 async_answer_0(callid, rc); 501 async_transaction_destroy(trans); 502 } 465 errno_t err = EPARTY; 466 467 ipc_callid_t data_callid; 468 size_t len; 469 if (!async_data_write_receive(&data_callid, &len) 470 || len != sizeof(trans->request)) { 471 async_answer_0(data_callid, EINVAL); 472 goto err; 473 } 474 475 if ((err = async_data_write_finalize(data_callid, 476 &trans->request, sizeof(trans->request)))) 477 goto err; 478 479 if (trans->request.size > 0) { 480 if ((err = receive_memory_buffer(trans))) 481 goto err; 482 } else { 483 /* The value was valid on the other side, for us, its garbage. */ 484 trans->request.base = NULL; 485 } 486 487 if ((err = usbhc_iface->transfer(fun, &trans->request, 488 &transfer_finished, trans))) 489 goto err; 490 491 /* The call will be answered asynchronously by the callback. */ 492 return; 493 494 err: 495 async_answer_0(callid, err); 496 async_transaction_destroy(trans); 503 497 } 504 498 -
uspace/lib/drv/include/usbhc_iface.h
raf16ebe r239eea41 126 126 } usb_pipe_desc_t; 127 127 128 typedef struct usb_pipe_transfer_request { 129 usb_direction_t dir; 130 usb_endpoint_t endpoint; 131 usb_stream_t stream; 132 133 uint64_t setup; /**< Valid iff the transfer is of control type */ 134 135 /** 136 * Base address of the buffer to share. Must be at least offset + size 137 * large. Is patched after being transmitted over IPC, so the pointer is 138 * still valid. 139 */ 140 void *base; 141 size_t offset; /**< Offset to the buffer */ 142 size_t size; /**< Requested size. */ 143 dma_policy_t buffer_policy; /**< Properties of the buffer. */ 144 } usbhc_iface_transfer_request_t; 145 128 146 /** This structure follows standard endpoint descriptor + superspeed companion 129 147 * descriptor, and exists to avoid dependency of libdrv on libusb. Keep the … … 157 175 extern errno_t usbhc_unregister_endpoint(async_exch_t *, const usb_pipe_desc_t *); 158 176 159 extern errno_t usbhc_transfer(async_exch_t *, usb_endpoint_t, usb_direction_t, 160 uint64_t, void *, size_t, size_t *); 177 extern errno_t usbhc_transfer(async_exch_t *, const usbhc_iface_transfer_request_t *, size_t *); 161 178 162 179 /** Callback for outgoing transfer */ … … 173 190 errno_t (*unregister_endpoint)(ddf_fun_t *, const usb_pipe_desc_t *); 174 191 175 errno_t (*transfer)(ddf_fun_t *, usb_target_t, 176 usb_direction_t, uint64_t, char *, size_t, 177 usbhc_iface_transfer_callback_t, void *); 192 errno_t (*transfer)(ddf_fun_t *, const usbhc_iface_transfer_request_t *, 193 usbhc_iface_transfer_callback_t, void *); 178 194 } usbhc_iface_t; 179 195 -
uspace/lib/usb/include/usb/usb.h
raf16ebe r239eea41 132 132 * @return True, if values are wihtin limits, false otherwise. 133 133 */ 134 static inline bool usb_target_is_valid( usb_target_t *target)134 static inline bool usb_target_is_valid(const usb_target_t *target) 135 135 { 136 136 return usb_address_is_valid(target->address) && -
uspace/lib/usbdev/src/pipes.c
raf16ebe r239eea41 39 39 40 40 #include <assert.h> 41 #include <bitops.h> 41 42 #include <async.h> 43 #include <as.h> 42 44 #include <errno.h> 43 45 #include <mem.h> … … 61 63 } 62 64 65 /* Helper structure to avoid passing loads of arguments through */ 63 66 typedef struct { 64 67 usb_pipe_t *pipe; 65 68 usb_direction_t dir; 66 bool is_control; 67 uint64_t setup; 69 bool is_control; // Only for checking purposes 68 70 void *buffer; 69 71 size_t buffer_size; 72 73 usbhc_iface_transfer_request_t req; 74 70 75 size_t transferred_size; 71 76 } transfer_t; … … 80 85 return ENOMEM; 81 86 82 const errno_t rc = usbhc_transfer(exch, t->pipe->desc.endpoint_no, 83 t->dir, t->setup, t->buffer, t->buffer_size, &t->transferred_size); 87 t->req.dir = t->dir; 88 t->req.endpoint = t->pipe->desc.endpoint_no; 89 90 /* We support only aligned buffers for now. */ 91 t->req.base = t->buffer; 92 t->req.offset = 0; 93 t->req.size = t->buffer_size; 94 95 const errno_t rc = usbhc_transfer(exch, &t->req, &t->transferred_size); 84 96 85 97 async_exchange_end(exch); … … 143 155 return EINVAL; 144 156 145 memcpy(&t-> setup, setup, 8);157 memcpy(&t->req.setup, setup, 8); 146 158 return EOK; 147 159 } -
uspace/lib/usbhost/src/ddf_helpers.c
raf16ebe r239eea41 271 271 * @return Error code. 272 272 */ 273 static errno_t transfer(ddf_fun_t *fun, usb_target_t target, 274 usb_direction_t dir, uint64_t setup_data, char *data, size_t size, 273 static errno_t transfer(ddf_fun_t *fun, const usbhc_iface_transfer_request_t *req, 275 274 usbhc_iface_transfer_callback_t callback, void *arg) 276 275 { … … 279 278 assert(dev); 280 279 281 target.address = dev->address; 280 const usb_target_t target = {{ 281 .address = dev->address, 282 .endpoint = req->endpoint, 283 .stream = req->stream, 284 }}; 282 285 283 286 if (!usb_target_is_valid(&target)) 284 287 return EINVAL; 285 288 286 if ( size > 0 && data== NULL)289 if (req->size > 0 && req->base == NULL) 287 290 return EBADMEM; 288 291 … … 290 293 return EBADMEM; 291 294 292 const char *name = (dir == USB_DIRECTION_IN) ? "READ" : "WRITE"; 293 294 return bus_device_send_batch(dev, target, dir, 295 (char *) data, size, setup_data, 295 const char *name = (req->dir == USB_DIRECTION_IN) ? "READ" : "WRITE"; 296 297 char *buffer = req->base + req->offset; 298 299 return bus_device_send_batch(dev, target, req->dir, 300 buffer, req->size, req->setup, 296 301 callback, arg, name); 297 302 }
Note:
See TracChangeset
for help on using the changeset viewer.