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


Ignore:
Timestamp:
2017-10-22T03:47:41Z (6 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/transfers.c

    r766043c r2b61945  
    9494}
    9595
    96 int xhci_init_transfers(xhci_hc_t *hc)
    97 {
    98         assert(hc);
    99 
    100         list_initialize(&hc->transfers);
    101         return EOK;
    102 }
    103 
    104 void xhci_fini_transfers(xhci_hc_t *hc)
    105 {
    106         // Note: Untested.
    107         assert(hc);
    108 }
    109 
    110 xhci_transfer_t* xhci_transfer_create(endpoint_t* ep) {
    111         xhci_transfer_t* transfer = calloc(1, sizeof(xhci_transfer_t));
    112         if (!transfer)
    113                 return NULL;
     96/**
     97 * There can currently be only one active transfer, because
     98 * usb_transfer_batch_init locks the endpoint by endpoint_use.
     99 * Therefore, we store the only active transfer per endpoint there.
     100 */
     101xhci_transfer_t* xhci_transfer_create(endpoint_t* ep)
     102{
     103        xhci_endpoint_t *xhci_ep = xhci_endpoint_get(ep);
     104        xhci_transfer_t *transfer = &xhci_ep->active_transfer;
     105
     106        /* Do not access the transfer yet, it may be still in use. */
    114107
    115108        usb_transfer_batch_init(&transfer->batch, ep);
    116 
    117         link_initialize(&transfer->link);
     109        assert(ep->active);
     110
     111        /* Clean just our data. */
     112        memset(((void *) transfer) + sizeof(usb_transfer_batch_t), 0,
     113            sizeof(xhci_transfer_t) - sizeof(usb_transfer_batch_t));
    118114
    119115        return transfer;
     
    126122        if (transfer->hc_buffer)
    127123                free32(transfer->hc_buffer);
    128 
    129         free(transfer);
    130124}
    131125
    132126static xhci_trb_ring_t *get_ring(xhci_hc_t *hc, xhci_transfer_t *transfer)
    133127{
    134         xhci_endpoint_t *xhci_ep = xhci_endpoint_get(transfer->batch.ep);
    135         uint8_t slot_id = xhci_ep->device->slot_id;
    136 
    137         xhci_trb_ring_t* ring = hc->dcbaa_virt[slot_id].trs[transfer->batch.ep->target.endpoint];
    138         assert(ring);
    139         return ring;
     128        return &xhci_endpoint_get(transfer->batch.ep)->ring;
    140129}
    141130
     
    202191        // Issue a Configure Endpoint command, if needed.
    203192        if (configure_endpoint_needed(setup)) {
    204                 const int err = xhci_device_configure(xhci_ep->device, hc);
     193                const int err = xhci_device_configure(xhci_ep_to_dev(xhci_ep), hc);
    205194                if (err)
    206195                        return err;
     
    226215        TRB_CTRL_SET_TRB_TYPE(trb, XHCI_TRB_TYPE_NORMAL);
    227216
    228         xhci_endpoint_t *xhci_ep = xhci_endpoint_get(transfer->batch.ep);
    229         uint8_t slot_id = xhci_ep->device->slot_id;
    230         xhci_trb_ring_t* ring = hc->dcbaa_virt[slot_id].trs[transfer->batch.ep->target.endpoint];
     217        xhci_trb_ring_t* ring = get_ring(hc, transfer);
    231218
    232219        return xhci_trb_ring_enqueue(ring, &trb, &transfer->interrupt_trb_phys);
     
    249236        TRB_CTRL_SET_TRB_TYPE(trb, XHCI_TRB_TYPE_NORMAL);
    250237
    251         xhci_endpoint_t *xhci_ep = xhci_endpoint_get(transfer->batch.ep);
    252         uint8_t slot_id = xhci_ep->device->slot_id;
    253         xhci_trb_ring_t* ring = hc->dcbaa_virt[slot_id].trs[transfer->batch.ep->target.endpoint];
     238        xhci_trb_ring_t* ring = get_ring(hc, transfer);
    254239
    255240        return xhci_trb_ring_enqueue(ring, &trb, &transfer->interrupt_trb_phys);
     
    266251{
    267252        uintptr_t addr = trb->parameter;
    268         xhci_transfer_t *transfer = NULL;
    269 
    270         link_t *transfer_link = list_first(&hc->transfers);
    271         while (transfer_link) {
    272                 transfer = list_get_instance(transfer_link, xhci_transfer_t, link);
    273 
    274                 if (transfer->interrupt_trb_phys == addr)
    275                         break;
    276 
    277                 transfer_link = list_next(transfer_link, &hc->transfers);
    278         }
    279 
    280         if (!transfer_link) {
    281                 usb_log_warning("Transfer not found.");
     253        const unsigned slot_id = XHCI_DWORD_EXTRACT(trb->control, 31, 24);
     254        const unsigned ep_dci = XHCI_DWORD_EXTRACT(trb->control, 20, 16);
     255
     256        xhci_device_t *dev = hc->bus.devices_by_slot[slot_id];
     257        if (!dev) {
     258                usb_log_error("Transfer event on unknown device slot %u!", slot_id);
    282259                return ENOENT;
    283260        }
    284261
    285         list_remove(transfer_link);
     262        const usb_endpoint_t ep_num = ep_dci / 2;
     263        xhci_endpoint_t *ep = xhci_device_get_endpoint(dev, ep_num);
     264        if (!ep) {
     265                usb_log_error("Transfer event on unknown endpoint num %u, device slot %u!", ep_num, slot_id);
     266                return ENOENT;
     267        }
     268
     269        xhci_transfer_t *transfer = &ep->active_transfer;
     270
     271        /** FIXME: This is racy. Do we care? */
     272        ep->ring.dequeue = addr;
     273
    286274        usb_transfer_batch_t *batch = &transfer->batch;
    287275
     
    314302        xhci_transfer_t *transfer = xhci_transfer_from_batch(batch);
    315303        xhci_endpoint_t *xhci_ep = xhci_endpoint_get(batch->ep);
    316         uint8_t slot_id = xhci_ep->device->slot_id;
    317 
    318304        assert(xhci_ep);
    319         assert(slot_id);
    320305
    321306        const usb_transfer_type_t type = batch->ep->transfer_type;
     
    336321                return err;
    337322
    338         list_append(&transfer->link, &hc->transfers);
    339 
     323        const uint8_t slot_id = xhci_ep_to_dev(xhci_ep)->slot_id;
    340324        const uint8_t target = xhci_endpoint_index(xhci_ep) + 1; /* EP Doorbells start at 1 */
    341325        return hc_ring_doorbell(hc, slot_id, target);
Note: See TracChangeset for help on using the changeset viewer.