Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/usb/src/pipes.c

    rd714945 r2a11192  
    3131 */
    3232/** @file
    33  * USB endpoint pipes miscellaneous functions.
     33 * Communication between device drivers and host controller driver.
     34 *
     35 * Note on synchronousness of the operations: there is ABSOLUTELY NO
     36 * guarantee that a call to particular function will not trigger a fibril
     37 * switch.
     38 * The initialization functions may actually involve contacting some other
     39 * task, starting/ending a session might involve asynchronous IPC and since
     40 * the transfer functions uses IPC, asynchronous nature of them is obvious.
     41 * The pseudo synchronous versions for the transfers internally call the
     42 * asynchronous ones and so fibril switch is possible in them as well.
    3443 */
    3544#include <usb/usb.h>
     
    3948#include <usb/usbdrv.h>
    4049
     50#define _PREPARE_TARGET(varname, pipe) \
     51        usb_target_t varname = { \
     52                .address = (pipe)->wire->address, \
     53                .endpoint = (pipe)->endpoint_no \
     54        }
     55
    4156/** Initialize connection to USB device.
    4257 *
     
    7590
    7691leave:
    77         async_hangup(hc_phone);
     92        ipc_hangup(hc_phone);
    7893        return rc;
    7994}
     
    102117}
    103118
    104 /** Initialize connection to USB device on default address.
    105  *
    106  * @param dev_connection Device connection structure to be initialized.
    107  * @param hc_connection Initialized connection to host controller.
    108  * @return Error code.
    109  */
    110 int usb_device_connection_initialize_on_default_address(
    111     usb_device_connection_t *dev_connection,
    112     usb_hc_connection_t *hc_connection)
    113 {
    114         assert(dev_connection);
    115 
    116         if (hc_connection == NULL) {
    117                 return EBADMEM;
    118         }
    119 
    120         return usb_device_connection_initialize(dev_connection,
    121             hc_connection->hc_handle, (usb_address_t) 0);
     119/** Initialize USB endpoint pipe.
     120 *
     121 * @param pipe Endpoint pipe to be initialized.
     122 * @param connection Connection to the USB device backing this pipe (the wire).
     123 * @param endpoint_no Endpoint number (in USB 1.1 in range 0 to 15).
     124 * @param transfer_type Transfer type (e.g. interrupt or bulk).
     125 * @param direction Endpoint direction (in/out).
     126 * @return Error code.
     127 */
     128int usb_endpoint_pipe_initialize(usb_endpoint_pipe_t *pipe,
     129    usb_device_connection_t *connection, usb_endpoint_t endpoint_no,
     130    usb_transfer_type_t transfer_type, usb_direction_t direction)
     131{
     132        assert(pipe);
     133        assert(connection);
     134
     135        pipe->wire = connection;
     136        pipe->hc_phone = -1;
     137        pipe->endpoint_no = endpoint_no;
     138        pipe->transfer_type = transfer_type;
     139        pipe->direction = direction;
     140
     141        return EOK;
     142}
     143
     144
     145/** Initialize USB endpoint pipe as the default zero control pipe.
     146 *
     147 * @param pipe Endpoint pipe to be initialized.
     148 * @param connection Connection to the USB device backing this pipe (the wire).
     149 * @return Error code.
     150 */
     151int usb_endpoint_pipe_initialize_default_control(usb_endpoint_pipe_t *pipe,
     152    usb_device_connection_t *connection)
     153{
     154        assert(pipe);
     155        assert(connection);
     156
     157        int rc = usb_endpoint_pipe_initialize(pipe, connection,
     158            0, USB_TRANSFER_CONTROL, USB_DIRECTION_BOTH);
     159
     160        return rc;
    122161}
    123162
     
    172211        }
    173212
    174         int rc = async_hangup(pipe->hc_phone);
     213        int rc = ipc_hangup(pipe->hc_phone);
    175214        if (rc != EOK) {
    176215                return rc;
     
    182221}
    183222
     223
     224/** Request a read (in) transfer on an endpoint pipe.
     225 *
     226 * @param[in] pipe Pipe used for the transfer.
     227 * @param[out] buffer Buffer where to store the data.
     228 * @param[in] size Size of the buffer (in bytes).
     229 * @param[out] size_transfered Number of bytes that were actually transfered.
     230 * @return Error code.
     231 */
     232int usb_endpoint_pipe_read(usb_endpoint_pipe_t *pipe,
     233    void *buffer, size_t size, size_t *size_transfered)
     234{
     235        assert(pipe);
     236
     237        int rc;
     238        usb_handle_t handle;
     239
     240        rc = usb_endpoint_pipe_async_read(pipe, buffer, size, size_transfered,
     241            &handle);
     242        if (rc != EOK) {
     243                return rc;
     244        }
     245
     246        rc = usb_endpoint_pipe_wait_for(pipe, handle);
     247        return rc;
     248}
     249
     250/** Request a write (out) transfer on an endpoint pipe.
     251 *
     252 * @param[in] pipe Pipe used for the transfer.
     253 * @param[in] buffer Buffer with data to transfer.
     254 * @param[in] size Size of the buffer (in bytes).
     255 * @return Error code.
     256 */
     257int usb_endpoint_pipe_write(usb_endpoint_pipe_t *pipe,
     258    void *buffer, size_t size)
     259{
     260        assert(pipe);
     261
     262        int rc;
     263        usb_handle_t handle;
     264
     265        rc = usb_endpoint_pipe_async_write(pipe, buffer, size, &handle);
     266        if (rc != EOK) {
     267                return rc;
     268        }
     269
     270        rc = usb_endpoint_pipe_wait_for(pipe, handle);
     271        return rc;
     272}
     273
     274
     275/** Request a control read transfer on an endpoint pipe.
     276 *
     277 * This function encapsulates all three stages of a control transfer.
     278 *
     279 * @param[in] pipe Pipe used for the transfer.
     280 * @param[in] setup_buffer Buffer with the setup packet.
     281 * @param[in] setup_buffer_size Size of the setup packet (in bytes).
     282 * @param[out] data_buffer Buffer for incoming data.
     283 * @param[in] data_buffer_size Size of the buffer for incoming data (in bytes).
     284 * @param[out] data_transfered_size Number of bytes that were actually
     285 *                                  transfered during the DATA stage.
     286 * @return Error code.
     287 */
     288int usb_endpoint_pipe_control_read(usb_endpoint_pipe_t *pipe,
     289    void *setup_buffer, size_t setup_buffer_size,
     290    void *data_buffer, size_t data_buffer_size, size_t *data_transfered_size)
     291{
     292        assert(pipe);
     293
     294        int rc;
     295        usb_handle_t handle;
     296
     297        rc = usb_endpoint_pipe_async_control_read(pipe,
     298            setup_buffer, setup_buffer_size,
     299            data_buffer, data_buffer_size, data_transfered_size,
     300            &handle);
     301        if (rc != EOK) {
     302                return rc;
     303        }
     304
     305        rc = usb_endpoint_pipe_wait_for(pipe, handle);
     306        return rc;
     307}
     308
     309
     310/** Request a control write transfer on an endpoint pipe.
     311 *
     312 * This function encapsulates all three stages of a control transfer.
     313 *
     314 * @param[in] pipe Pipe used for the transfer.
     315 * @param[in] setup_buffer Buffer with the setup packet.
     316 * @param[in] setup_buffer_size Size of the setup packet (in bytes).
     317 * @param[in] data_buffer Buffer with data to be sent.
     318 * @param[in] data_buffer_size Size of the buffer with outgoing data (in bytes).
     319 * @return Error code.
     320 */
     321int usb_endpoint_pipe_control_write(usb_endpoint_pipe_t *pipe,
     322    void *setup_buffer, size_t setup_buffer_size,
     323    void *data_buffer, size_t data_buffer_size)
     324{
     325        assert(pipe);
     326
     327        int rc;
     328        usb_handle_t handle;
     329
     330        rc = usb_endpoint_pipe_async_control_write(pipe,
     331            setup_buffer, setup_buffer_size,
     332            data_buffer, data_buffer_size,
     333            &handle);
     334        if (rc != EOK) {
     335                return rc;
     336        }
     337
     338        rc = usb_endpoint_pipe_wait_for(pipe, handle);
     339        return rc;
     340}
     341
     342
     343/** Request a read (in) transfer on an endpoint pipe (asynchronous version).
     344 *
     345 * @param[in] pipe Pipe used for the transfer.
     346 * @param[out] buffer Buffer where to store the data.
     347 * @param[in] size Size of the buffer (in bytes).
     348 * @param[out] size_transfered Number of bytes that were actually transfered.
     349 * @param[out] handle Handle of the transfer.
     350 * @return Error code.
     351 */
     352int usb_endpoint_pipe_async_read(usb_endpoint_pipe_t *pipe,
     353    void *buffer, size_t size, size_t *size_transfered,
     354    usb_handle_t *handle)
     355{
     356        assert(pipe);
     357
     358        if (pipe->hc_phone < 0) {
     359                return EBADF;
     360        }
     361
     362        if (pipe->direction != USB_DIRECTION_IN) {
     363                return EBADF;
     364        }
     365
     366        int rc;
     367        _PREPARE_TARGET(target, pipe);
     368
     369        switch (pipe->transfer_type) {
     370                case USB_TRANSFER_INTERRUPT:
     371                        rc = usb_drv_async_interrupt_in(pipe->hc_phone, target,
     372                            buffer, size, size_transfered, handle);
     373                        break;
     374                case USB_TRANSFER_CONTROL:
     375                        rc = EBADF;
     376                        break;
     377                default:
     378                        rc = ENOTSUP;
     379                        break;
     380        }
     381
     382        return rc;
     383}
     384
     385
     386/** Request a write (out) transfer on an endpoint pipe (asynchronous version).
     387 *
     388 * @param[in] pipe Pipe used for the transfer.
     389 * @param[in] buffer Buffer with data to transfer.
     390 * @param[in] size Size of the buffer (in bytes).
     391 * @param[out] handle Handle of the transfer.
     392 * @return Error code.
     393 */
     394int usb_endpoint_pipe_async_write(usb_endpoint_pipe_t *pipe,
     395    void *buffer, size_t size,
     396    usb_handle_t *handle)
     397{
     398        assert(pipe);
     399
     400        if (pipe->hc_phone < 0) {
     401                return EBADF;
     402        }
     403
     404        if (pipe->direction != USB_DIRECTION_OUT) {
     405                return EBADF;
     406        }
     407
     408        int rc;
     409        _PREPARE_TARGET(target, pipe);
     410
     411        switch (pipe->transfer_type) {
     412                case USB_TRANSFER_INTERRUPT:
     413                        rc = usb_drv_async_interrupt_out(pipe->hc_phone, target,
     414                            buffer, size, handle);
     415                        break;
     416                case USB_TRANSFER_CONTROL:
     417                        rc = EBADF;
     418                        break;
     419                default:
     420                        rc = ENOTSUP;
     421                        break;
     422        }
     423
     424        return rc;
     425}
     426
     427
     428/** Request a control read transfer on an endpoint pipe (asynchronous version).
     429 *
     430 * This function encapsulates all three stages of a control transfer.
     431 *
     432 * @param[in] pipe Pipe used for the transfer.
     433 * @param[in] setup_buffer Buffer with the setup packet.
     434 * @param[in] setup_buffer_size Size of the setup packet (in bytes).
     435 * @param[out] data_buffer Buffer for incoming data.
     436 * @param[in] data_buffer_size Size of the buffer for incoming data (in bytes).
     437 * @param[out] data_transfered_size Number of bytes that were actually
     438 *                                  transfered during the DATA stage.
     439 * @param[out] handle Handle of the transfer.
     440 * @return Error code.
     441 */
     442int usb_endpoint_pipe_async_control_read(usb_endpoint_pipe_t *pipe,
     443    void *setup_buffer, size_t setup_buffer_size,
     444    void *data_buffer, size_t data_buffer_size, size_t *data_transfered_size,
     445    usb_handle_t *handle)
     446{
     447        assert(pipe);
     448
     449        if (pipe->hc_phone < 0) {
     450                return EBADF;
     451        }
     452
     453        if ((pipe->direction != USB_DIRECTION_BOTH)
     454            || (pipe->transfer_type != USB_TRANSFER_CONTROL)) {
     455                return EBADF;
     456        }
     457
     458        int rc;
     459        _PREPARE_TARGET(target, pipe);
     460
     461        rc = usb_drv_async_control_read(pipe->hc_phone, target,
     462            setup_buffer, setup_buffer_size,
     463            data_buffer, data_buffer_size, data_transfered_size,
     464            handle);
     465
     466        return rc;
     467}
     468
     469
     470/** Request a control write transfer on an endpoint pipe (asynchronous version).
     471 *
     472 * This function encapsulates all three stages of a control transfer.
     473 *
     474 * @param[in] pipe Pipe used for the transfer.
     475 * @param[in] setup_buffer Buffer with the setup packet.
     476 * @param[in] setup_buffer_size Size of the setup packet (in bytes).
     477 * @param[in] data_buffer Buffer with data to be sent.
     478 * @param[in] data_buffer_size Size of the buffer with outgoing data (in bytes).
     479 * @param[out] handle Handle of the transfer.
     480 * @return Error code.
     481 */
     482int usb_endpoint_pipe_async_control_write(usb_endpoint_pipe_t *pipe,
     483    void *setup_buffer, size_t setup_buffer_size,
     484    void *data_buffer, size_t data_buffer_size,
     485    usb_handle_t *handle)
     486{
     487        assert(pipe);
     488
     489        if (pipe->hc_phone < 0) {
     490                return EBADF;
     491        }
     492
     493        if ((pipe->direction != USB_DIRECTION_BOTH)
     494            || (pipe->transfer_type != USB_TRANSFER_CONTROL)) {
     495                return EBADF;
     496        }
     497
     498        int rc;
     499        _PREPARE_TARGET(target, pipe);
     500
     501        rc = usb_drv_async_control_write(pipe->hc_phone, target,
     502            setup_buffer, setup_buffer_size,
     503            data_buffer, data_buffer_size,
     504            handle);
     505
     506        return rc;
     507}
     508
     509/** Wait for transfer completion.
     510 *
     511 * The function blocks the caller fibril until the transfer associated
     512 * with given @p handle is completed.
     513 *
     514 * @param[in] pipe Pipe the transfer executed on.
     515 * @param[in] handle Transfer handle.
     516 * @return Error code.
     517 */
     518int usb_endpoint_pipe_wait_for(usb_endpoint_pipe_t *pipe, usb_handle_t handle)
     519{
     520        return usb_drv_async_wait_for(handle);
     521}
     522
     523
    184524/**
    185525 * @}
Note: See TracChangeset for help on using the changeset viewer.