Changeset 306a36d in mainline


Ignore:
Timestamp:
2017-11-19T23:43:31Z (6 years ago)
Author:
Aearsis <Hlavaty.Ondrej@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
ff14aede
Parents:
e76c0ea
Message:

xhci: configuration of endpoint 0

Moved fetching of the first 8B of device descriptor from usb2_bus to
hcd, and using it in xhci bus. Also, the value was previously read wrong
by the endpoint descriptor macros, although the value is raw in the
device descriptor - now fixed.

Location:
uspace
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • uspace/drv/bus/usb/ehci/hc.c

    re76c0ea r306a36d  
    238238        assert(ep);
    239239        ehci_endpoint_t *ehci_ep = ehci_endpoint_get(ep);
    240         usb_log_debug("HC(%p) dequeue EP(%d:%d:%s:%s)\n", instance,
    241             ep->device->address, ep->endpoint,
     240        usb_log_debug("HC(%p) dequeue EP(?:%d:%s:%s)\n", instance,
     241            ep->endpoint,
    242242            usb_str_transfer_type_short(ep->transfer_type),
    243243            usb_str_direction(ep->direction));
  • uspace/drv/bus/usb/xhci/bus.c

    re76c0ea r306a36d  
    5050
    5151
    52 /* FIXME Are these really static? Older HCs fetch it from descriptor. */
    53 /* FIXME Add USB3 options, if applicable. */
    54 static const usb_endpoint_desc_t ep0_desc = {
     52static const usb_endpoint_desc_t ep0_initial_desc = {
    5553        .endpoint_no = 0,
    5654        .direction = USB_DIRECTION_BOTH,
     
    9795        xhci_endpoint_t *ep0 = xhci_endpoint_get(ep0_base);
    9896
    99         if ((err = prepare_endpoint(ep0, &ep0_desc)))
     97        if ((err = prepare_endpoint(ep0, &ep0_initial_desc)))
    10098                goto err_ep;
    10199
     
    124122}
    125123
     124static int setup_ep0_packet_size(xhci_hc_t *hc, xhci_device_t *dev)
     125{
     126        int err;
     127
     128        uint16_t max_packet_size;
     129        if ((err = hcd_get_ep0_max_packet_size(&max_packet_size, hc->hcd, &dev->base)))
     130                return err;
     131
     132        xhci_endpoint_t *ep0 = dev->endpoints[0];
     133        assert(ep0);
     134
     135        if (ep0->base.max_packet_size == max_packet_size)
     136                return EOK;
     137
     138        ep0->base.max_packet_size = max_packet_size;
     139
     140        xhci_ep_ctx_t ep_ctx;
     141        xhci_setup_endpoint_context(ep0, &ep_ctx);
     142
     143        if ((err = hc_update_endpoint(hc, dev->slot_id, 0, &ep_ctx)))
     144                return err;
     145
     146        return EOK;
     147}
     148
    126149int xhci_bus_enumerate_device(xhci_bus_t *bus, xhci_hc_t *hc, device_t *dev)
    127150{
     
    160183        }
    161184
    162         // TODO: Fetch descriptor of EP0 and reconfigure it accordingly
    163         assert(xhci_dev->endpoints[0]);
     185        if ((err = setup_ep0_packet_size(hc, xhci_dev))) {
     186                usb_log_error("Failed to setup control endpoint of the new device: %s", str_error(err));
     187                goto err_address;
     188        }
    164189
    165190        assert(bus->devices_by_slot[xhci_dev->slot_id] == NULL);
  • uspace/drv/bus/usb/xhci/hc.c

    re76c0ea r306a36d  
    651651}
    652652
    653 // TODO: This currently assumes the device is attached to rh directly
    654 //      -> calculate route string
    655653int hc_address_device(xhci_hc_t *hc, xhci_device_t *dev, xhci_endpoint_t *ep0)
    656654{
     
    767765}
    768766
     767int hc_update_endpoint(xhci_hc_t *hc, uint32_t slot_id, uint8_t ep_idx, xhci_ep_ctx_t *ep_ctx)
     768{
     769        dma_buffer_t ictx_dma_buf;
     770        const int err = dma_buffer_alloc(&ictx_dma_buf, sizeof(xhci_input_ctx_t));
     771        if (err)
     772                return err;
     773
     774        xhci_input_ctx_t *ictx = ictx_dma_buf.virt;
     775        memset(ictx, 0, sizeof(xhci_input_ctx_t));
     776
     777        XHCI_INPUT_CTRL_CTX_ADD_SET(ictx->ctrl_ctx, ep_idx + 1);
     778        memcpy(&ictx->endpoint_ctx[ep_idx], ep_ctx, sizeof(xhci_ep_ctx_t));
     779
     780        return xhci_cmd_sync_inline(hc, EVALUATE_CONTEXT, .slot_id = slot_id, .input_ctx = ictx_dma_buf);
     781}
     782
    769783/**
    770784 * @}
  • uspace/drv/bus/usb/xhci/hc.h

    re76c0ea r306a36d  
    110110int hc_add_endpoint(xhci_hc_t *, uint32_t, uint8_t, xhci_ep_ctx_t *);
    111111int hc_drop_endpoint(xhci_hc_t *, uint32_t, uint8_t);
     112int hc_update_endpoint(xhci_hc_t *, uint32_t, uint8_t, xhci_ep_ctx_t *);
    112113
    113114#endif
  • uspace/lib/usbhost/include/usb/host/hcd.h

    re76c0ea r306a36d  
    102102}
    103103
     104extern int hcd_get_ep0_max_packet_size(uint16_t *, hcd_t *, device_t *);
     105
    104106extern int hcd_send_batch(hcd_t *, device_t *, usb_target_t,
    105107    usb_direction_t direction, char *, size_t, uint64_t,
  • uspace/lib/usbhost/src/hcd.c

    re76c0ea r306a36d  
    3535
    3636#include <usb/debug.h>
     37#include <usb/descriptor.h>
    3738#include <usb/request.h>
    3839
     
    4041#include <async.h>
    4142#include <errno.h>
     43#include <macros.h>
    4244#include <usb_iface.h>
    4345#include <str_error.h>
     
    5961        hcd_set_implementation(hcd, NULL, NULL, NULL);
    6062}
     63
     64/** Get max packet size for the control endpoint 0.
     65 *
     66 * For LS, HS, and SS devices this value is fixed. For FS devices we must fetch
     67 * the first 8B of the device descriptor to determine it.
     68 *
     69 * @return Combined value of max_packet_size and scheduling oppertunities,
     70 *      see usb_standard_device_descriptor_t.
     71 */
     72int hcd_get_ep0_max_packet_size(uint16_t *mps, hcd_t *hcd, device_t *dev)
     73{
     74        static const uint16_t mps_fixed [] = {
     75                [USB_SPEED_LOW] = 8,
     76                [USB_SPEED_HIGH] = 64,
     77                [USB_SPEED_SUPER] = 512,
     78        };
     79
     80        if (dev->speed < ARRAY_SIZE(mps_fixed) && mps_fixed[dev->speed] != 0) {
     81                *mps = mps_fixed[dev->speed];
     82                return EOK;
     83        }
     84
     85        const usb_target_t control_ep = {{
     86                .address = dev->address,
     87                .endpoint = 0,
     88        }};
     89
     90        usb_standard_device_descriptor_t desc = { 0 };
     91        const usb_device_request_setup_packet_t get_device_desc_8 =
     92            GET_DEVICE_DESC(CTRL_PIPE_MIN_PACKET_SIZE);
     93
     94        usb_log_debug("Requesting first 8B of device descriptor.");
     95        ssize_t got = hcd_send_batch_sync(hcd, dev, control_ep, USB_DIRECTION_IN,
     96            (char *) &desc, CTRL_PIPE_MIN_PACKET_SIZE, *(uint64_t *)&get_device_desc_8,
     97            "read first 8 bytes of dev descriptor");
     98
     99        if (got != CTRL_PIPE_MIN_PACKET_SIZE) {
     100                const int err = got < 0 ? got : EOVERFLOW;
     101                usb_log_error("Failed to get 8B of dev descr: %s.", str_error(err));
     102                return err;
     103        }
     104
     105        *mps = uint16_usb2host(desc.max_packet_size);
     106        return EOK;
     107}
     108
    61109
    62110/** Prepare generic usb_transfer_batch and schedule it.
  • uspace/lib/usbhost/src/usb2_bus.c

    re76c0ea r306a36d  
    132132        }
    133133
    134         /* Get max packet size for default pipe */
    135         usb_standard_device_descriptor_t desc = { 0 };
    136         const usb_device_request_setup_packet_t get_device_desc_8 =
    137             GET_DEVICE_DESC(CTRL_PIPE_MIN_PACKET_SIZE);
    138 
    139         usb_log_debug("Device(%d): Requesting first 8B of device descriptor.",
    140             address);
    141         ssize_t got = hcd_send_batch_sync(hcd, dev, usb2_default_target, USB_DIRECTION_IN,
    142             (char *) &desc, CTRL_PIPE_MIN_PACKET_SIZE, *(uint64_t *)&get_device_desc_8,
    143             "read first 8 bytes of dev descriptor");
    144 
    145         if (got != CTRL_PIPE_MIN_PACKET_SIZE) {
    146                 err = got < 0 ? got : EOVERFLOW;
    147                 usb_log_error("Device(%d): Failed to get 8B of dev descr: %s.",
    148                     address, str_error(err));
    149                 goto err_default_control_ep;
    150         }
     134        uint16_t max_packet_size;
     135        if ((err = hcd_get_ep0_max_packet_size(&max_packet_size, hcd, dev)))
     136                goto err_address;
    151137
    152138        /* Set new address */
     
    158144        if (err != 0) {
    159145                usb_log_error("Device(%d): Failed to set new address: %s.",
    160                     address, str_error(got));
     146                    address, str_error(err));
    161147                goto err_default_control_ep;
    162148        }
     
    175161                .transfer_type = USB_TRANSFER_CONTROL,
    176162                .direction = USB_DIRECTION_BOTH,
    177                 .max_packet_size = ED_MPS_PACKET_SIZE_GET(uint16_usb2host(desc.max_packet_size)),
    178                 .packets = ED_MPS_TRANS_OPPORTUNITIES_GET(uint16_usb2host(desc.max_packet_size)),
     163                .max_packet_size = max_packet_size,
     164                .packets = 1,
    179165        };
    180166
Note: See TracChangeset for help on using the changeset viewer.