Ignore:
File:
1 edited

Legend:

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

    rd714945 r25971d2  
    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 *
     
    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 max_packet_size Maximum packet size in bytes.
     126 * @param direction Endpoint direction (in/out).
     127 * @return Error code.
     128 */
     129int usb_endpoint_pipe_initialize(usb_endpoint_pipe_t *pipe,
     130    usb_device_connection_t *connection, usb_endpoint_t endpoint_no,
     131    usb_transfer_type_t transfer_type, size_t max_packet_size,
     132    usb_direction_t direction)
     133{
     134        assert(pipe);
     135        assert(connection);
     136
     137        pipe->wire = connection;
     138        pipe->hc_phone = -1;
     139        pipe->endpoint_no = endpoint_no;
     140        pipe->transfer_type = transfer_type;
     141        pipe->max_packet_size = max_packet_size;
     142        pipe->direction = direction;
     143
     144        return EOK;
     145}
     146
     147
     148/** Initialize USB endpoint pipe as the default zero control pipe.
     149 *
     150 * @param pipe Endpoint pipe to be initialized.
     151 * @param connection Connection to the USB device backing this pipe (the wire).
     152 * @return Error code.
     153 */
     154int usb_endpoint_pipe_initialize_default_control(usb_endpoint_pipe_t *pipe,
     155    usb_device_connection_t *connection)
     156{
     157        assert(pipe);
     158        assert(connection);
     159
     160        int rc = usb_endpoint_pipe_initialize(pipe, connection,
     161            0, USB_TRANSFER_CONTROL, 8, USB_DIRECTION_BOTH);
     162
     163        return rc;
    122164}
    123165
     
    182224}
    183225
     226
     227/** Request a read (in) transfer on an endpoint pipe.
     228 *
     229 * @param[in] pipe Pipe used for the transfer.
     230 * @param[out] buffer Buffer where to store the data.
     231 * @param[in] size Size of the buffer (in bytes).
     232 * @param[out] size_transfered Number of bytes that were actually transfered.
     233 * @return Error code.
     234 */
     235int usb_endpoint_pipe_read(usb_endpoint_pipe_t *pipe,
     236    void *buffer, size_t size, size_t *size_transfered)
     237{
     238        assert(pipe);
     239
     240        int rc;
     241        usb_handle_t handle;
     242
     243        rc = usb_endpoint_pipe_async_read(pipe, buffer, size, size_transfered,
     244            &handle);
     245        if (rc != EOK) {
     246                return rc;
     247        }
     248
     249        rc = usb_endpoint_pipe_wait_for(pipe, handle);
     250        return rc;
     251}
     252
     253/** Request a write (out) transfer on an endpoint pipe.
     254 *
     255 * @param[in] pipe Pipe used for the transfer.
     256 * @param[in] buffer Buffer with data to transfer.
     257 * @param[in] size Size of the buffer (in bytes).
     258 * @return Error code.
     259 */
     260int usb_endpoint_pipe_write(usb_endpoint_pipe_t *pipe,
     261    void *buffer, size_t size)
     262{
     263        assert(pipe);
     264
     265        int rc;
     266        usb_handle_t handle;
     267
     268        rc = usb_endpoint_pipe_async_write(pipe, buffer, size, &handle);
     269        if (rc != EOK) {
     270                return rc;
     271        }
     272
     273        rc = usb_endpoint_pipe_wait_for(pipe, handle);
     274        return rc;
     275}
     276
     277
     278/** Request a control read transfer on an endpoint pipe.
     279 *
     280 * This function encapsulates all three stages of a control transfer.
     281 *
     282 * @param[in] pipe Pipe used for the transfer.
     283 * @param[in] setup_buffer Buffer with the setup packet.
     284 * @param[in] setup_buffer_size Size of the setup packet (in bytes).
     285 * @param[out] data_buffer Buffer for incoming data.
     286 * @param[in] data_buffer_size Size of the buffer for incoming data (in bytes).
     287 * @param[out] data_transfered_size Number of bytes that were actually
     288 *                                  transfered during the DATA stage.
     289 * @return Error code.
     290 */
     291int usb_endpoint_pipe_control_read(usb_endpoint_pipe_t *pipe,
     292    void *setup_buffer, size_t setup_buffer_size,
     293    void *data_buffer, size_t data_buffer_size, size_t *data_transfered_size)
     294{
     295        assert(pipe);
     296
     297        int rc;
     298        usb_handle_t handle;
     299
     300        rc = usb_endpoint_pipe_async_control_read(pipe,
     301            setup_buffer, setup_buffer_size,
     302            data_buffer, data_buffer_size, data_transfered_size,
     303            &handle);
     304        if (rc != EOK) {
     305                return rc;
     306        }
     307
     308        rc = usb_endpoint_pipe_wait_for(pipe, handle);
     309        return rc;
     310}
     311
     312
     313/** Request a control write transfer on an endpoint pipe.
     314 *
     315 * This function encapsulates all three stages of a control transfer.
     316 *
     317 * @param[in] pipe Pipe used for the transfer.
     318 * @param[in] setup_buffer Buffer with the setup packet.
     319 * @param[in] setup_buffer_size Size of the setup packet (in bytes).
     320 * @param[in] data_buffer Buffer with data to be sent.
     321 * @param[in] data_buffer_size Size of the buffer with outgoing data (in bytes).
     322 * @return Error code.
     323 */
     324int usb_endpoint_pipe_control_write(usb_endpoint_pipe_t *pipe,
     325    void *setup_buffer, size_t setup_buffer_size,
     326    void *data_buffer, size_t data_buffer_size)
     327{
     328        assert(pipe);
     329
     330        int rc;
     331        usb_handle_t handle;
     332
     333        rc = usb_endpoint_pipe_async_control_write(pipe,
     334            setup_buffer, setup_buffer_size,
     335            data_buffer, data_buffer_size,
     336            &handle);
     337        if (rc != EOK) {
     338                return rc;
     339        }
     340
     341        rc = usb_endpoint_pipe_wait_for(pipe, handle);
     342        return rc;
     343}
     344
     345
     346/** Request a read (in) transfer on an endpoint pipe (asynchronous version).
     347 *
     348 * @param[in] pipe Pipe used for the transfer.
     349 * @param[out] buffer Buffer where to store the data.
     350 * @param[in] size Size of the buffer (in bytes).
     351 * @param[out] size_transfered Number of bytes that were actually transfered.
     352 * @param[out] handle Handle of the transfer.
     353 * @return Error code.
     354 */
     355int usb_endpoint_pipe_async_read(usb_endpoint_pipe_t *pipe,
     356    void *buffer, size_t size, size_t *size_transfered,
     357    usb_handle_t *handle)
     358{
     359        assert(pipe);
     360
     361        if (pipe->hc_phone < 0) {
     362                return EBADF;
     363        }
     364
     365        if (pipe->direction != USB_DIRECTION_IN) {
     366                return EBADF;
     367        }
     368
     369        int rc;
     370        _PREPARE_TARGET(target, pipe);
     371
     372        switch (pipe->transfer_type) {
     373                case USB_TRANSFER_INTERRUPT:
     374                        rc = usb_drv_async_interrupt_in(pipe->hc_phone, target,
     375                            buffer, size, size_transfered, handle);
     376                        break;
     377                case USB_TRANSFER_CONTROL:
     378                        rc = EBADF;
     379                        break;
     380                default:
     381                        rc = ENOTSUP;
     382                        break;
     383        }
     384
     385        return rc;
     386}
     387
     388
     389/** Request a write (out) transfer on an endpoint pipe (asynchronous version).
     390 *
     391 * @param[in] pipe Pipe used for the transfer.
     392 * @param[in] buffer Buffer with data to transfer.
     393 * @param[in] size Size of the buffer (in bytes).
     394 * @param[out] handle Handle of the transfer.
     395 * @return Error code.
     396 */
     397int usb_endpoint_pipe_async_write(usb_endpoint_pipe_t *pipe,
     398    void *buffer, size_t size,
     399    usb_handle_t *handle)
     400{
     401        assert(pipe);
     402
     403        if (pipe->hc_phone < 0) {
     404                return EBADF;
     405        }
     406
     407        if (pipe->direction != USB_DIRECTION_OUT) {
     408                return EBADF;
     409        }
     410
     411        int rc;
     412        _PREPARE_TARGET(target, pipe);
     413
     414        switch (pipe->transfer_type) {
     415                case USB_TRANSFER_INTERRUPT:
     416                        rc = usb_drv_async_interrupt_out(pipe->hc_phone, target,
     417                            buffer, size, handle);
     418                        break;
     419                case USB_TRANSFER_CONTROL:
     420                        rc = EBADF;
     421                        break;
     422                default:
     423                        rc = ENOTSUP;
     424                        break;
     425        }
     426
     427        return rc;
     428}
     429
     430
     431/** Request a control read transfer on an endpoint pipe (asynchronous version).
     432 *
     433 * This function encapsulates all three stages of a control transfer.
     434 *
     435 * @param[in] pipe Pipe used for the transfer.
     436 * @param[in] setup_buffer Buffer with the setup packet.
     437 * @param[in] setup_buffer_size Size of the setup packet (in bytes).
     438 * @param[out] data_buffer Buffer for incoming data.
     439 * @param[in] data_buffer_size Size of the buffer for incoming data (in bytes).
     440 * @param[out] data_transfered_size Number of bytes that were actually
     441 *                                  transfered during the DATA stage.
     442 * @param[out] handle Handle of the transfer.
     443 * @return Error code.
     444 */
     445int usb_endpoint_pipe_async_control_read(usb_endpoint_pipe_t *pipe,
     446    void *setup_buffer, size_t setup_buffer_size,
     447    void *data_buffer, size_t data_buffer_size, size_t *data_transfered_size,
     448    usb_handle_t *handle)
     449{
     450        assert(pipe);
     451
     452        if (pipe->hc_phone < 0) {
     453                return EBADF;
     454        }
     455
     456        if ((pipe->direction != USB_DIRECTION_BOTH)
     457            || (pipe->transfer_type != USB_TRANSFER_CONTROL)) {
     458                return EBADF;
     459        }
     460
     461        int rc;
     462        _PREPARE_TARGET(target, pipe);
     463
     464        rc = usb_drv_async_control_read(pipe->hc_phone, target,
     465            setup_buffer, setup_buffer_size,
     466            data_buffer, data_buffer_size, data_transfered_size,
     467            handle);
     468
     469        return rc;
     470}
     471
     472
     473/** Request a control write transfer on an endpoint pipe (asynchronous version).
     474 *
     475 * This function encapsulates all three stages of a control transfer.
     476 *
     477 * @param[in] pipe Pipe used for the transfer.
     478 * @param[in] setup_buffer Buffer with the setup packet.
     479 * @param[in] setup_buffer_size Size of the setup packet (in bytes).
     480 * @param[in] data_buffer Buffer with data to be sent.
     481 * @param[in] data_buffer_size Size of the buffer with outgoing data (in bytes).
     482 * @param[out] handle Handle of the transfer.
     483 * @return Error code.
     484 */
     485int usb_endpoint_pipe_async_control_write(usb_endpoint_pipe_t *pipe,
     486    void *setup_buffer, size_t setup_buffer_size,
     487    void *data_buffer, size_t data_buffer_size,
     488    usb_handle_t *handle)
     489{
     490        assert(pipe);
     491
     492        if (pipe->hc_phone < 0) {
     493                return EBADF;
     494        }
     495
     496        if ((pipe->direction != USB_DIRECTION_BOTH)
     497            || (pipe->transfer_type != USB_TRANSFER_CONTROL)) {
     498                return EBADF;
     499        }
     500
     501        int rc;
     502        _PREPARE_TARGET(target, pipe);
     503
     504        rc = usb_drv_async_control_write(pipe->hc_phone, target,
     505            setup_buffer, setup_buffer_size,
     506            data_buffer, data_buffer_size,
     507            handle);
     508
     509        return rc;
     510}
     511
     512/** Wait for transfer completion.
     513 *
     514 * The function blocks the caller fibril until the transfer associated
     515 * with given @p handle is completed.
     516 *
     517 * @param[in] pipe Pipe the transfer executed on.
     518 * @param[in] handle Transfer handle.
     519 * @return Error code.
     520 */
     521int usb_endpoint_pipe_wait_for(usb_endpoint_pipe_t *pipe, usb_handle_t handle)
     522{
     523        return usb_drv_async_wait_for(handle);
     524}
     525
     526
    184527/**
    185528 * @}
Note: See TracChangeset for help on using the changeset viewer.