| 374 | ****************************************************************************/ |
| 375 | |
| 376 | static int sim_reqwrite(struct sim_usbdev_s *priv, struct sim_ep_s *privep) |
| 377 | { |
| 378 | struct sim_req_s *privreq; |
| 379 | uint8_t *write_data; |
| 380 | int write_len; |
| 381 | uint8_t epno; |
| 382 | |
| 383 | /* Get the unadorned endpoint number */ |
| 384 | |
| 385 | epno = USB_EPNO(privep->ep.eplog); |
| 386 | |
| 387 | /* We get here when an IN endpoint interrupt occurs. So now we know that |
| 388 | * there is no TX transfer in progress. |
| 389 | */ |
| 390 | |
| 391 | while (privep->epstate == SIM_EPSTATE_IDLE) |
| 392 | { |
| 393 | /* Check the request from the head of the endpoint request queue */ |
| 394 | |
| 395 | privreq = sim_rqpeek(&privep->reqq); |
| 396 | if (!privreq) |
| 397 | { |
| 398 | return OK; |
| 399 | } |
| 400 | |
| 401 | while (privreq->req.xfrd < privreq->req.len) |
| 402 | { |
| 403 | /* Handle any bytes in flight. */ |
| 404 | |
| 405 | write_data = privreq->req.buf + privreq->req.xfrd; |
| 406 | write_len = privreq->req.len - privreq->req.xfrd; |
| 407 | |
| 408 | write_len = host_usbdev_epwrite(epno, privreq->req.flags, |
| 409 | write_data, write_len); |
| 410 | |
| 411 | if (write_len < 0) |
| 412 | { |
| 413 | return -EPERM; |
| 414 | } |
| 415 | |
| 416 | privreq->req.xfrd += write_len; |
| 417 | } |
| 418 | |
| 419 | /* If all of the bytes were sent (including any final zero length |
| 420 | * packet) then we are finished with the request buffer and we can |
| 421 | * return the request buffer to the class driver. The state will |
| 422 | * remain IDLE only if nothing else was put in flight. |
| 423 | * |
| 424 | * Note that we will then loop to check to check the next queued |
| 425 | * write request. |
| 426 | */ |
| 427 | |
| 428 | usbtrace(TRACE_COMPLETE(USB_EPNO(privep->ep.eplog)), |
| 429 | privreq->req.xfrd); |
| 430 | sim_reqcomplete(privep, OK); |
| 431 | } |
| 432 | |
| 433 | return OK; |
no test coverage detected