Changeset 0206d35 in mainline for uspace/drv/bus/usb/xhci/rh.c


Ignore:
Timestamp:
2017-10-25T00:03:57Z (6 years ago)
Author:
Ondřej Hlavatý <aearsis@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
c3d926f
Parents:
56db65d
Message:

Moving things around to improve isolation of responsibilities

Bus interface was simplified, xHCI implementation of address_device was spread into stack of rh → bus → hc and back.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/drv/bus/usb/xhci/rh.c

    r56db65d r0206d35  
    7474}
    7575
    76 static void setup_control_ep0_ctx(xhci_ep_ctx_t *ctx, xhci_trb_ring_t *ring,
    77                 const xhci_port_speed_t *speed)
    78 {
    79         XHCI_EP_TYPE_SET(*ctx, EP_TYPE_CONTROL);
    80         // TODO: must be changed with a command after USB descriptor is read
    81         // See 4.6.5 in XHCI specification, first note
    82         XHCI_EP_MAX_PACKET_SIZE_SET(*ctx, speed->major == 3 ? 512 : 8);
    83         XHCI_EP_MAX_BURST_SIZE_SET(*ctx, 0);
    84         XHCI_EP_TR_DPTR_SET(*ctx, ring->dequeue);
    85         XHCI_EP_DCS_SET(*ctx, 1);
    86         XHCI_EP_INTERVAL_SET(*ctx, 0);
    87         XHCI_EP_MAX_P_STREAMS_SET(*ctx, 0);
    88         XHCI_EP_MULT_SET(*ctx, 0);
    89         XHCI_EP_ERROR_COUNT_SET(*ctx, 3);
    90 }
    91 
    92 /* FIXME Are these really static? Older HCs fetch it from descriptor. */
    93 /* FIXME Add USB3 options, if applicable. */
    94 static const usb_endpoint_desc_t ep0_desc = {
    95         .endpoint_no = 0,
    96         .direction = USB_DIRECTION_BOTH,
    97         .transfer_type = USB_TRANSFER_CONTROL,
    98         .max_packet_size = CTRL_PIPE_MIN_PACKET_SIZE,
    99         .packets = 1,
    100 };
    101 
    102 // TODO: This currently assumes the device is attached to rh directly.
    103 //       Also, we should consider moving a lot of functionailty to xhci bus
    104 int xhci_rh_address_device(xhci_rh_t *rh, device_t *dev, xhci_bus_t *bus)
    105 {
    106         int err;
    107 
    108         const xhci_port_speed_t *speed = xhci_rh_get_port_speed(rh, dev->port);
    109         xhci_device_t *xhci_dev = xhci_device_get(dev);
    110         xhci_dev->hc = rh->hc;
    111         xhci_dev->usb3 = speed->major == 3;
    112 
    113         /* Enable new slot. */
    114         if ((err = hc_enable_slot(rh->hc, &xhci_dev->slot_id)) != EOK)
    115                 return err;
    116         usb_log_debug2("Obtained slot ID: %u.\n", xhci_dev->slot_id);
    117 
    118         /* Create and configure control endpoint. */
    119         endpoint_t *ep0_base = bus_create_endpoint(&rh->hc->bus.base);
    120         if (!ep0_base)
    121                 return ENOMEM;
    122 
    123         xhci_endpoint_t *ep0 = xhci_endpoint_get(ep0_base);
    124 
    125         if ((err = xhci_endpoint_alloc_transfer_ds(ep0)))
    126                 goto err_ep;
    127 
    128         xhci_ep_ctx_t ep_ctx;
    129         memset(&ep_ctx, 0, sizeof(xhci_ep_ctx_t));
    130         setup_control_ep0_ctx(&ep_ctx, &ep0->ring, speed);
    131 
    132         /* Setup and register device context */
    133         xhci_dev->dev_ctx = malloc32(sizeof(xhci_device_ctx_t));
    134         if (!xhci_dev->dev_ctx) {
    135                 err = ENOMEM;
    136                 goto err_ds;
    137         }
    138         rh->hc->dcbaa[xhci_dev->slot_id] = addr_to_phys(xhci_dev->dev_ctx);
    139         memset(xhci_dev->dev_ctx, 0, sizeof(xhci_device_ctx_t));
    140 
    141         /* Address device */
    142         if ((err = hc_address_rh_device(rh->hc, xhci_dev->slot_id, dev->port, &ep_ctx)))
    143                 goto err_dctx;
    144         dev->address = XHCI_SLOT_DEVICE_ADDRESS(xhci_dev->dev_ctx->slot_ctx);
    145         usb_log_debug2("Obtained USB address: %d.\n", dev->address);
    146 
    147         /* From now on, the device is officially online, yay! */
    148         fibril_mutex_lock(&dev->guard);
    149         xhci_dev->online = true;
    150         fibril_mutex_unlock(&dev->guard);
    151 
    152         ep0_base->device = dev;
    153 
    154         bus_register_endpoint(&rh->hc->bus.base, ep0_base, &ep0_desc);
    155 
    156         if (!rh->devices[dev->port - 1]) {
    157                 /* Only save the device if it's the first one connected to this port. */
    158                 rh->devices[dev->port - 1] = xhci_dev;
    159         }
    160 
    161         return EOK;
    162 
    163 err_dctx:
    164         free32(xhci_dev->dev_ctx);
    165         rh->hc->dcbaa[xhci_dev->slot_id] = 0;
    166 err_ds:
    167         xhci_endpoint_free_transfer_ds(ep0);
    168 err_ep:
    169         xhci_endpoint_fini(ep0);
    170         free(ep0);
    171         return err;
     76static usb_speed_t port_speed_to_usb_speed(const xhci_port_speed_t *port_speed)
     77{
     78        assert(port_speed->major > 0 && port_speed->major <= USB_SPEED_SUPER);
     79
     80        switch (port_speed->major) {
     81                case 3: return USB_SPEED_SUPER;
     82                case 2: return USB_SPEED_HIGH;
     83                case 1: return port_speed->minor ? USB_SPEED_FULL : USB_SPEED_LOW;
     84        }
     85
     86        assert(false);
    17287}
    17388
     
    188103        }
    189104
     105        const xhci_port_speed_t *port_speed = xhci_rh_get_port_speed(rh, port_id);
     106        xhci_device_t *xhci_dev = xhci_device_get(dev);
     107        xhci_dev->hc = rh->hc;
     108        xhci_dev->usb3 = port_speed->major == 3;
     109
    190110        dev->hub = &rh->device;
    191111        dev->port = port_id;
     112        dev->speed = port_speed_to_usb_speed(port_speed);
    192113
    193114        if ((err = xhci_bus_enumerate_device(bus, rh->hc, dev))) {
     
    207128        fibril_mutex_lock(&rh->device.guard);
    208129        list_append(&dev->link, &rh->device.devices);
     130        if (!rh->devices[port_id - 1]) {
     131                /* Only save the device if it's the first one connected to this port. */
     132                rh->devices[port_id - 1] = xhci_dev;
     133        }
    209134        fibril_mutex_unlock(&rh->device.guard);
    210135
     
    286211                        continue;
    287212
     213                /* FIXME: This is racy. */
    288214                if ((err = xhci_transfer_abort(&ep->active_transfer))) {
    289215                        usb_log_warning("Failed to abort active %s transfer to "
     
    305231
    306232        /* Unregister EP0. */
    307         if ((err = bus_unregister_endpoint(&rh->hc->bus.base, &dev->endpoints[0]->base))) {
     233        if ((err = bus_remove_endpoint(&rh->hc->bus.base, &dev->endpoints[0]->base))) {
    308234                usb_log_warning("Failed to unregister configuration endpoint of device '%s' from XHCI bus: %s",
    309235                    ddf_fun_get_name(dev->base.fun), str_error(err));
Note: See TracChangeset for help on using the changeset viewer.