Ignore:
File:
1 edited

Legend:

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

    r3ddbd38 r7c95d6f5  
    5454
    5555/** Nesting pairs of standard descriptors. */
    56 static const usb_dp_descriptor_nesting_t descriptor_nesting[] = {
     56static usb_dp_descriptor_nesting_t descriptor_nesting[] = {
    5757        NESTING(CONFIGURATION, INTERFACE),
    5858        NESTING(INTERFACE, ENDPOINT),
     
    192192        }
    193193
     194        if (ep_mapping->pipe == NULL) {
     195                return EBADMEM;
     196        }
    194197        if (ep_mapping->present) {
    195198                return EEXISTS;
    196199        }
    197200
    198         int rc = usb_pipe_initialize(&ep_mapping->pipe, wire,
     201        int rc = usb_pipe_initialize(ep_mapping->pipe, wire,
    199202            ep_no, description.transfer_type, endpoint->max_packet_size,
    200203            description.direction);
     
    251254 *
    252255 * The mapping array is expected to conform to following rules:
    253  * - @c pipe must be uninitialized pipe
     256 * - @c pipe must point to already allocated structure with uninitialized pipe
    254257 * - @c description must point to prepared endpoint description
    255258 * - @c descriptor does not need to be initialized (will be overwritten)
     
    294297        }
    295298
    296         /* Go through the mapping and set all endpoints to not present. */
    297         for (size_t i = 0; i < mapping_count; i++) {
     299        /*
     300         * Go through the mapping and set all endpoints to not present.
     301         */
     302        size_t i;
     303        for (i = 0; i < mapping_count; i++) {
    298304                mapping[i].present = false;
    299305                mapping[i].descriptor = NULL;
     
    301307        }
    302308
    303         /* Prepare the descriptor parser. */
     309        /*
     310         * Prepare the descriptor parser.
     311         */
    304312        const usb_dp_parser_t dp_parser = {
    305313                .nesting = descriptor_nesting
     
    405413        }
    406414
     415#define TRY_LOOP(attempt_var) \
     416        for (attempt_var = 0; attempt_var < 3; attempt_var++)
     417
     418        size_t failed_attempts;
     419        int rc;
    407420
    408421        usb_pipe_start_long_transfer(pipe);
     
    410423        uint8_t dev_descr_start[CTRL_PIPE_MIN_PACKET_SIZE];
    411424        size_t transferred_size;
    412         int rc;
    413         for (size_t attempt_var = 0; attempt_var < 3; ++attempt_var) {
     425        TRY_LOOP(failed_attempts) {
    414426                rc = usb_request_get_descriptor(pipe, USB_REQUEST_TYPE_STANDARD,
    415427                    USB_REQUEST_RECIPIENT_DEVICE, USB_DESCTYPE_DEVICE,
     
    442454 * @return Error code.
    443455 */
    444 int usb_pipe_register(usb_pipe_t *pipe, unsigned interval,
     456int usb_pipe_register(usb_pipe_t *pipe,
     457    unsigned int interval,
     458    usb_hc_connection_t *hc_connection)
     459{
     460        return usb_pipe_register_with_speed(pipe, USB_SPEED_MAX + 1,
     461            interval, hc_connection);
     462}
     463
     464/** Register endpoint with a speed at the host controller.
     465 *
     466 * You will rarely need to use this function because it is needed only
     467 * if the registered endpoint is of address 0 and there is no other way
     468 * to tell speed of the device at address 0.
     469 *
     470 * @param pipe Pipe to be registered.
     471 * @param speed Speed of the device
     472 *      (invalid speed means use previously specified one).
     473 * @param interval Polling interval.
     474 * @param hc_connection Connection to the host controller (must be opened).
     475 * @return Error code.
     476 */
     477int usb_pipe_register_with_speed(usb_pipe_t *pipe, usb_speed_t speed,
     478    unsigned int interval,
     479    usb_hc_connection_t *hc_connection)
     480{
     481        assert(pipe);
     482        assert(hc_connection);
     483       
     484        if (!usb_hc_connection_is_opened(hc_connection))
     485                return EBADF;
     486       
     487        const usb_target_t target =
     488            {{ .address = pipe->wire->address, .endpoint = pipe->endpoint_no }};
     489#define _PACK2(high, low) (((high) << 16) + (low))
     490#define _PACK3(high, middle, low) (((((high) << 8) + (middle)) << 8) + (low))
     491       
     492        async_exch_t *exch = async_exchange_begin(hc_connection->hc_sess);
     493        int rc = async_req_4_0(exch, DEV_IFACE_ID(USBHC_DEV_IFACE),
     494            IPC_M_USBHC_REGISTER_ENDPOINT, target.packed,
     495            _PACK3(speed, pipe->transfer_type, pipe->direction),
     496            _PACK2(pipe->max_packet_size, interval));
     497        async_exchange_end(exch);
     498       
     499#undef _PACK2
     500#undef _PACK3
     501       
     502        return rc;
     503}
     504
     505/** Revert endpoint registration with the host controller.
     506 *
     507 * @param pipe Pipe to be unregistered.
     508 * @param hc_connection Connection to the host controller (must be opened).
     509 * @return Error code.
     510 */
     511int usb_pipe_unregister(usb_pipe_t *pipe,
    445512    usb_hc_connection_t *hc_connection)
    446513{
     
    448515        assert(pipe->wire);
    449516        assert(hc_connection);
    450 
     517       
    451518        if (!usb_hc_connection_is_opened(hc_connection))
    452519                return EBADF;
     520       
    453521        async_exch_t *exch = async_exchange_begin(hc_connection->hc_sess);
    454         if (!exch)
    455                 return ENOMEM;
    456         const int ret = usbhc_register_endpoint(exch,
    457             pipe->wire->address, pipe->endpoint_no, pipe->transfer_type,
    458             pipe->direction, pipe->max_packet_size, interval);
    459 
    460         async_exchange_end(exch);
    461         return ret;
    462 }
    463 
    464 /** Revert endpoint registration with the host controller.
    465  *
    466  * @param pipe Pipe to be unregistered.
    467  * @param hc_connection Connection to the host controller (must be opened).
    468  * @return Error code.
    469  */
    470 int usb_pipe_unregister(usb_pipe_t *pipe,
    471     usb_hc_connection_t *hc_connection)
    472 {
    473         assert(pipe);
    474         assert(pipe->wire);
    475         assert(hc_connection);
    476 
    477         if (!usb_hc_connection_is_opened(hc_connection))
    478                 return EBADF;
    479 
    480         async_exch_t *exch = async_exchange_begin(hc_connection->hc_sess);
    481         if (!exch)
    482                 return ENOMEM;
    483         const int ret = usbhc_unregister_endpoint(exch,
     522        int rc = async_req_4_0(exch, DEV_IFACE_ID(USBHC_DEV_IFACE),
     523            IPC_M_USBHC_UNREGISTER_ENDPOINT,
    484524            pipe->wire->address, pipe->endpoint_no, pipe->direction);
    485525        async_exchange_end(exch);
    486 
    487         return ret;
     526       
     527        return rc;
    488528}
    489529
Note: See TracChangeset for help on using the changeset viewer.