Ignore:
File:
1 edited

Legend:

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

    r18cb870 r206f71a  
    3737#include <usb/pipes.h>
    3838#include <usb/dp.h>
     39#include <usb/request.h>
     40#include <usbhc_iface.h>
    3941#include <errno.h>
    4042#include <assert.h>
     43
     44#define CTRL_PIPE_MIN_PACKET_SIZE 8
     45#define DEV_DESCR_MAX_PACKET_SIZE_OFFSET 7
    4146
    4247
     
    369374
    370375        int rc = usb_endpoint_pipe_initialize(pipe, connection,
    371             0, USB_TRANSFER_CONTROL, 8, USB_DIRECTION_BOTH);
     376            0, USB_TRANSFER_CONTROL, CTRL_PIPE_MIN_PACKET_SIZE,
     377            USB_DIRECTION_BOTH);
    372378
    373379        return rc;
     380}
     381
     382/** Probe default control pipe for max packet size.
     383 *
     384 * The function tries to get the correct value of max packet size several
     385 * time before giving up.
     386 *
     387 * The session on the pipe shall not be started.
     388 *
     389 * @param pipe Default control pipe.
     390 * @return Error code.
     391 */
     392int usb_endpoint_pipe_probe_default_control(usb_endpoint_pipe_t *pipe)
     393{
     394        assert(pipe);
     395        assert(DEV_DESCR_MAX_PACKET_SIZE_OFFSET < CTRL_PIPE_MIN_PACKET_SIZE);
     396
     397        if ((pipe->direction != USB_DIRECTION_BOTH) ||
     398            (pipe->transfer_type != USB_TRANSFER_CONTROL) ||
     399            (pipe->endpoint_no != 0)) {
     400                return EINVAL;
     401        }
     402
     403#define TRY_LOOP(attempt_var) \
     404        for (attempt_var = 0; attempt_var < 3; attempt_var++)
     405
     406        size_t failed_attempts;
     407        int rc;
     408
     409        TRY_LOOP(failed_attempts) {
     410                rc = usb_endpoint_pipe_start_session(pipe);
     411                if (rc == EOK) {
     412                        break;
     413                }
     414        }
     415        if (rc != EOK) {
     416                return rc;
     417        }
     418
     419
     420        uint8_t dev_descr_start[CTRL_PIPE_MIN_PACKET_SIZE];
     421        size_t transferred_size;
     422        TRY_LOOP(failed_attempts) {
     423                rc = usb_request_get_descriptor(pipe, USB_REQUEST_TYPE_STANDARD,
     424                    USB_REQUEST_RECIPIENT_DEVICE, USB_DESCTYPE_DEVICE,
     425                    0, 0, dev_descr_start, CTRL_PIPE_MIN_PACKET_SIZE,
     426                    &transferred_size);
     427                if (rc == EOK) {
     428                        if (transferred_size != CTRL_PIPE_MIN_PACKET_SIZE) {
     429                                rc = ELIMIT;
     430                                continue;
     431                        }
     432                        break;
     433                }
     434        }
     435        usb_endpoint_pipe_end_session(pipe);
     436        if (rc != EOK) {
     437                return rc;
     438        }
     439
     440        pipe->max_packet_size
     441            = dev_descr_start[DEV_DESCR_MAX_PACKET_SIZE_OFFSET];
     442
     443        return EOK;
     444}
     445
     446/** Register endpoint with the host controller.
     447 *
     448 * @param pipe Pipe to be registered.
     449 * @param interval Polling interval.
     450 * @param hc_connection Connection to the host controller (must be opened).
     451 * @return Error code.
     452 */
     453int usb_endpoint_pipe_register(usb_endpoint_pipe_t *pipe,
     454    unsigned int interval,
     455    usb_hc_connection_t *hc_connection)
     456{
     457        assert(pipe);
     458        assert(hc_connection);
     459
     460        if (!usb_hc_connection_is_opened(hc_connection)) {
     461                return EBADF;
     462        }
     463
     464#define _PACK(high, low) ((high) * 256 + (low))
     465
     466        return async_req_5_0(hc_connection->hc_phone,
     467            DEV_IFACE_ID(USBHC_DEV_IFACE), IPC_M_USBHC_REGISTER_ENDPOINT,
     468            _PACK(pipe->wire->address, pipe->endpoint_no),
     469            _PACK(pipe->transfer_type, pipe->direction),
     470            pipe->max_packet_size, interval);
     471
     472#undef _PACK
     473}
     474
     475/** Revert endpoint registration with the host controller.
     476 *
     477 * @param pipe Pipe to be unregistered.
     478 * @param hc_connection Connection to the host controller (must be opened).
     479 * @return Error code.
     480 */
     481int usb_endpoint_pipe_unregister(usb_endpoint_pipe_t *pipe,
     482    usb_hc_connection_t *hc_connection)
     483{
     484        assert(pipe);
     485        assert(hc_connection);
     486
     487        if (!usb_hc_connection_is_opened(hc_connection)) {
     488                return EBADF;
     489        }
     490
     491        return async_req_4_0(hc_connection->hc_phone,
     492            DEV_IFACE_ID(USBHC_DEV_IFACE), IPC_M_USBHC_UNREGISTER_ENDPOINT,
     493            pipe->wire->address, pipe->endpoint_no, pipe->direction);
    374494}
    375495
Note: See TracChangeset for help on using the changeset viewer.