Changeset 2b61945 in mainline for uspace/drv/bus/usb/xhci/rh.c


Ignore:
Timestamp:
2017-10-22T03:47:41Z (7 years ago)
Author:
Ondřej Hlavatý <aearsis@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
2e5aea1
Parents:
766043c
Message:

xhci: use device_t for bookkeeping

This started as a little refactoring to move active transfer batch to endpoint. Finding the EP in handler needs devices indexed by slot id. Then I found out we do not use the device_t extendable mechanism. Then there were a lot of errors found while doing all this…

File:
1 edited

Legend:

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

    r766043c r2b61945  
    9292}
    9393
    94 // TODO: Check device deallocation, we free device_ctx in hc.c, not
    95 //       sure about the other structs.
    9694// TODO: This currently assumes the device is attached to rh directly.
    9795//       Also, we should consider moving a lot of functionailty to xhci bus
    9896int xhci_rh_address_device(xhci_rh_t *rh, device_t *dev, xhci_bus_t *bus)
    9997{
     98        int err;
     99        xhci_device_t *xhci_dev = xhci_device_get(dev);
     100
    100101        /* FIXME: Certainly not generic solution. */
    101102        const uint32_t route_str = 0;
    102103
    103         int err;
    104         xhci_hc_t *hc = rh->hc;
     104        xhci_dev->hc = rh->hc;
     105
    105106        const xhci_port_speed_t *speed = xhci_rh_get_port_speed(rh, dev->port);
     107        xhci_dev->usb3 = speed->major == 3;
    106108
    107109        /* Enable new slot */
    108         uint32_t slot_id;
    109         if ((err = hc_enable_slot(hc, &slot_id)) != EOK)
     110        if ((err = hc_enable_slot(rh->hc, &xhci_dev->slot_id)) != EOK)
    110111                return err;
    111         usb_log_debug2("Obtained slot ID: %u.\n", slot_id);
     112        usb_log_debug2("Obtained slot ID: %u.\n", xhci_dev->slot_id);
    112113
    113114        /* Setup input context */
    114         xhci_input_ctx_t *ictx = malloc(sizeof(xhci_input_ctx_t));
     115        xhci_input_ctx_t *ictx = malloc32(sizeof(xhci_input_ctx_t));
    115116        if (!ictx)
    116117                return ENOMEM;
     
    126127        XHCI_SLOT_ROUTE_STRING_SET(ictx->slot_ctx, route_str);
    127128
    128         xhci_trb_ring_t *ep_ring = malloc(sizeof(xhci_trb_ring_t));
    129         if (!ep_ring) {
    130                 err = ENOMEM;
     129        endpoint_t *ep0_base = bus_create_endpoint(&rh->hc->bus.base);
     130        if (!ep0_base)
    131131                goto err_ictx;
    132         }
    133 
    134         err = xhci_trb_ring_init(ep_ring);
    135         if (err)
    136                 goto err_ring;
    137         setup_control_ep0_ctx(&ictx->endpoint_ctx[0], ep_ring, speed);
     132        xhci_endpoint_t *ep0 = xhci_endpoint_get(ep0_base);
     133        setup_control_ep0_ctx(&ictx->endpoint_ctx[0], &ep0->ring, speed);
    138134
    139135        /* Setup and register device context */
     
    141137        if (!dctx) {
    142138                err = ENOMEM;
    143                 goto err_ring;
    144         }
     139                goto err_ep;
     140        }
     141        xhci_dev->dev_ctx = dctx;
     142        rh->hc->dcbaa[xhci_dev->slot_id] = addr_to_phys(dctx);
    145143        memset(dctx, 0, sizeof(xhci_device_ctx_t));
    146         hc->dcbaa[slot_id] = addr_to_phys(dctx);
    147 
    148         memset(&hc->dcbaa_virt[slot_id], 0, sizeof(xhci_virt_device_ctx_t));
    149         hc->dcbaa_virt[slot_id].dev_ctx = dctx;
    150         hc->dcbaa_virt[slot_id].trs[0] = ep_ring;
    151144
    152145        /* Address device */
    153         if ((err = hc_address_device(hc, slot_id, ictx)) != EOK)
     146        if ((err = hc_address_device(rh->hc, xhci_dev->slot_id, ictx)) != EOK)
    154147                goto err_dctx;
    155148        dev->address = XHCI_SLOT_DEVICE_ADDRESS(dctx->slot_ctx);
    156149        usb_log_debug2("Obtained USB address: %d.\n", dev->address);
    157150
    158         // Ask libusbhost to create a control endpoint for EP0.
    159         bus_t *bus_base = &bus->base;
    160         usb_target_t ep0_target = { .address = dev->address, .endpoint = 0 };
    161         usb_direction_t ep0_direction = USB_DIRECTION_BOTH;
    162 
    163         // TODO: Should this call be unified with other calls to `bus_add_ep()`?
    164         err = bus_add_ep(bus_base, dev, ep0_target.endpoint, ep0_direction,
    165             USB_TRANSFER_CONTROL, CTRL_PIPE_MIN_PACKET_SIZE, CTRL_PIPE_MIN_PACKET_SIZE, 1);
    166 
    167         if (err != EOK)
    168                 goto err_add_ep;
    169 
    170         // Save all data structures in the corresponding xhci_device_t.
    171         endpoint_t *ep0_base = bus_find_endpoint(bus_base, ep0_target, ep0_direction);
    172         xhci_endpoint_t *ep0 = xhci_endpoint_get(ep0_base);
    173         xhci_device_t *xhci_dev = ep0->device;
    174 
    175         xhci_dev->device = dev;
    176         xhci_dev->slot_id = slot_id;
    177         xhci_dev->usb3 = speed->major == 3;
    178         xhci_dev->hc = hc;
     151        // XXX: Going around bus, duplicating code
     152        ep0_base->device = dev;
     153        ep0_base->target.address = dev->address;
     154        ep0_base->target.endpoint = 0;
     155        ep0_base->direction = USB_DIRECTION_BOTH;
     156        ep0_base->transfer_type = USB_TRANSFER_CONTROL;
     157        ep0_base->max_packet_size = CTRL_PIPE_MIN_PACKET_SIZE;
     158        ep0_base->packets = 1;
     159        ep0_base->bandwidth = CTRL_PIPE_MIN_PACKET_SIZE;
     160
     161        bus_register_endpoint(&rh->hc->bus.base, ep0_base);
    179162
    180163        if (!rh->devices[dev->port - 1]) {
     
    183166        }
    184167
    185         return EOK;
    186 
    187 err_add_ep:
     168        free32(ictx);
     169        return EOK;
     170
    188171err_dctx:
    189         if (dctx) {
    190                 free(dctx);
    191                 hc->dcbaa[slot_id] = 0;
    192                 memset(&hc->dcbaa_virt[slot_id], 0, sizeof(xhci_virt_device_ctx_t));
    193         }
    194 err_ring:
    195         if (ep_ring) {
    196                 xhci_trb_ring_fini(ep_ring);
    197                 free(ep_ring);
    198         }
     172        free32(dctx);
     173        rh->hc->dcbaa[xhci_dev->slot_id] = 0;
     174err_ep:
     175        xhci_endpoint_fini(ep0);
     176        free(ep0);
    199177err_ictx:
    200         free(ictx);
     178        free32(ictx);
    201179        return err;
    202180}
Note: See TracChangeset for help on using the changeset viewer.