Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/usbdev/src/pipesinit.c

    r3538b0e rb77931d  
    3131 */
    3232/** @file
    33  * Non trivial initialization of endpoint pipes.
     33 * Initialization of endpoint pipes.
    3434 *
    3535 */
     
    3838#include <usb/dev/dp.h>
    3939#include <usb/dev/request.h>
     40#include <usbhc_iface.h>
    4041#include <errno.h>
    4142#include <assert.h>
    4243
     44#define CTRL_PIPE_MIN_PACKET_SIZE 8
    4345#define DEV_DESCR_MAX_PACKET_SIZE_OFFSET 7
     46
    4447
    4548#define NESTING(parentname, childname) \
     
    5154
    5255/** Nesting pairs of standard descriptors. */
    53 static const usb_dp_descriptor_nesting_t descriptor_nesting[] = {
     56static usb_dp_descriptor_nesting_t descriptor_nesting[] = {
    5457        NESTING(CONFIGURATION, INTERFACE),
    5558        NESTING(INTERFACE, ENDPOINT),
     
    326329}
    327330
     331/** Initialize USB endpoint pipe.
     332 *
     333 * @param pipe Endpoint pipe to be initialized.
     334 * @param connection Connection to the USB device backing this pipe (the wire).
     335 * @param endpoint_no Endpoint number (in USB 1.1 in range 0 to 15).
     336 * @param transfer_type Transfer type (e.g. interrupt or bulk).
     337 * @param max_packet_size Maximum packet size in bytes.
     338 * @param direction Endpoint direction (in/out).
     339 * @return Error code.
     340 */
     341int usb_pipe_initialize(usb_pipe_t *pipe,
     342    usb_device_connection_t *connection, usb_endpoint_t endpoint_no,
     343    usb_transfer_type_t transfer_type, size_t max_packet_size,
     344    usb_direction_t direction)
     345{
     346        assert(pipe);
     347        assert(connection);
     348
     349        fibril_mutex_initialize(&pipe->guard);
     350        pipe->wire = connection;
     351        pipe->hc_sess = NULL;
     352        fibril_mutex_initialize(&pipe->hc_sess_mutex);
     353        pipe->endpoint_no = endpoint_no;
     354        pipe->transfer_type = transfer_type;
     355        pipe->max_packet_size = max_packet_size;
     356        pipe->direction = direction;
     357        pipe->refcount = 0;
     358        pipe->refcount_soft = 0;
     359        pipe->auto_reset_halt = false;
     360
     361        return EOK;
     362}
     363
     364
     365/** Initialize USB endpoint pipe as the default zero control pipe.
     366 *
     367 * @param pipe Endpoint pipe to be initialized.
     368 * @param connection Connection to the USB device backing this pipe (the wire).
     369 * @return Error code.
     370 */
     371int usb_pipe_initialize_default_control(usb_pipe_t *pipe,
     372    usb_device_connection_t *connection)
     373{
     374        assert(pipe);
     375        assert(connection);
     376
     377        int rc = usb_pipe_initialize(pipe, connection,
     378            0, USB_TRANSFER_CONTROL, CTRL_PIPE_MIN_PACKET_SIZE,
     379            USB_DIRECTION_BOTH);
     380
     381        pipe->auto_reset_halt = true;
     382
     383        return rc;
     384}
     385
    328386/** Probe default control pipe for max packet size.
    329387 *
     
    347405        }
    348406
     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;
    349412
    350413        usb_pipe_start_long_transfer(pipe);
     
    352415        uint8_t dev_descr_start[CTRL_PIPE_MIN_PACKET_SIZE];
    353416        size_t transferred_size;
    354         int rc;
    355         for (size_t attempt_var = 0; attempt_var < 3; ++attempt_var) {
     417        TRY_LOOP(failed_attempts) {
    356418                rc = usb_request_get_descriptor(pipe, USB_REQUEST_TYPE_STANDARD,
    357419                    USB_REQUEST_RECIPIENT_DEVICE, USB_DESCTYPE_DEVICE,
     
    377439}
    378440
     441/** Register endpoint with the host controller.
     442 *
     443 * @param pipe Pipe to be registered.
     444 * @param interval Polling interval.
     445 * @param hc_connection Connection to the host controller (must be opened).
     446 * @return Error code.
     447 */
     448int usb_pipe_register(usb_pipe_t *pipe, unsigned interval,
     449    usb_hc_connection_t *hc_connection)
     450{
     451        assert(pipe);
     452        assert(hc_connection);
     453
     454        if (!usb_hc_connection_is_opened(hc_connection))
     455                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        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));
     466        async_exchange_end(exch);
     467
     468#undef _PACK2
     469        return rc;
     470}
     471
     472/** Revert endpoint registration with the host controller.
     473 *
     474 * @param pipe Pipe to be unregistered.
     475 * @param hc_connection Connection to the host controller (must be opened).
     476 * @return Error code.
     477 */
     478int usb_pipe_unregister(usb_pipe_t *pipe,
     479    usb_hc_connection_t *hc_connection)
     480{
     481        assert(pipe);
     482        assert(pipe->wire);
     483        assert(hc_connection);
     484       
     485        if (!usb_hc_connection_is_opened(hc_connection))
     486                return EBADF;
     487       
     488        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,
     491            pipe->wire->address, pipe->endpoint_no, pipe->direction);
     492        async_exchange_end(exch);
     493       
     494        return rc;
     495}
     496
    379497/**
    380498 * @}
Note: See TracChangeset for help on using the changeset viewer.