Changeset 1d758fc in mainline for uspace/drv/bus/usb/xhci


Ignore:
Timestamp:
2018-02-12T10:11:47Z (8 years ago)
Author:
Ondřej Hlavatý <aearsis@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
5fe3f954
Parents:
2f762a7
git-author:
Ondřej Hlavatý <aearsis@…> (2018-02-05 03:28:50)
git-committer:
Ondřej Hlavatý <aearsis@…> (2018-02-12 10:11:47)
Message:

usb: rethinking DMA buffers

Location:
uspace/drv/bus/usb/xhci
Files:
8 edited

Legend:

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

    r2f762a7 r1d758fc  
    470470        xhci_trb_clean(&cmd->_header.trb);
    471471
    472         TRB_SET_ICTX(cmd->_header.trb, cmd->input_ctx.phys);
     472        const uintptr_t phys = dma_buffer_phys_base(&cmd->input_ctx);
     473        TRB_SET_ICTX(cmd->_header.trb, phys);
    473474
    474475        /**
     
    496497                assert(dma_buffer_is_set(&cmd->input_ctx));
    497498
    498                 TRB_SET_ICTX(cmd->_header.trb, cmd->input_ctx.phys);
     499                const uintptr_t phys = dma_buffer_phys_base(&cmd->input_ctx);
     500                TRB_SET_ICTX(cmd->_header.trb, phys);
    499501        }
    500502
     
    520522        xhci_trb_clean(&cmd->_header.trb);
    521523
    522         TRB_SET_ICTX(cmd->_header.trb, cmd->input_ctx.phys);
     524        const uintptr_t phys = dma_buffer_phys_base(&cmd->input_ctx);
     525        TRB_SET_ICTX(cmd->_header.trb, phys);
    523526
    524527        TRB_SET_TYPE(cmd->_header.trb, XHCI_TRB_TYPE_EVALUATE_CONTEXT_CMD);
     
    594597        xhci_trb_clean(&cmd->_header.trb);
    595598
    596         TRB_SET_ICTX(cmd->_header.trb, cmd->bandwidth_ctx.phys);
     599        const uintptr_t phys = dma_buffer_phys_base(&cmd->input_ctx);
     600        TRB_SET_ICTX(cmd->_header.trb, phys);
    597601
    598602        TRB_SET_TYPE(cmd->_header.trb, XHCI_TRB_TYPE_GET_PORT_BANDWIDTH_CMD);
  • uspace/drv/bus/usb/xhci/endpoint.c

    r2f762a7 r1d758fc  
    116116                goto err;
    117117
    118         /* Driver can handle non-contiguous buffers */
    119         ep->transfer_buffer_policy &= ~DMA_POLICY_CONTIGUOUS;
    120 
    121         /* Driver can handle buffers crossing boundaries */
    122         ep->transfer_buffer_policy &= ~DMA_POLICY_NOT_CROSSING;
     118        unsigned flags = -1U;
    123119
    124120        /* Some xHCs can handle 64-bit addresses */
    125121        xhci_bus_t *bus = bus_to_xhci_bus(ep->device->bus);
    126122        if (bus->hc->ac64)
    127                 ep->transfer_buffer_policy &= ~DMA_POLICY_4GiB;
     123                flags &= ~DMA_POLICY_4GiB;
     124
     125        /* xHCI works best if it can fit 65k transfers in one TRB */
     126        ep->transfer_buffer_policy = dma_policy_create(flags, 1 << 16);
     127
     128        /* But actualy can do full scatter-gather. */
     129        ep->required_transfer_buffer_policy = dma_policy_create(flags, PAGE_SIZE);
    128130
    129131        return EOK;
  • uspace/drv/bus/usb/xhci/hc.c

    r2f762a7 r1d758fc  
    476476                return ETIMEOUT;
    477477
    478         XHCI_REG_WR(hc->op_regs, XHCI_OP_DCBAAP, hc->dcbaa_dma.phys);
     478        uintptr_t dcbaa_phys = dma_buffer_phys_base(&hc->dcbaa_dma);
     479        XHCI_REG_WR(hc->op_regs, XHCI_OP_DCBAAP, dcbaa_phys);
    479480        XHCI_REG_WR(hc->op_regs, XHCI_OP_MAX_SLOTS_EN, hc->max_slots);
    480481
     
    490491        XHCI_REG_WR(intr0, XHCI_INTR_ERSTSZ, hc->event_ring.segment_count);
    491492        XHCI_REG_WR(intr0, XHCI_INTR_ERDP, hc->event_ring.dequeue_ptr);
    492         XHCI_REG_WR(intr0, XHCI_INTR_ERSTBA, hc->event_ring.erst.phys);
     493
     494        const uintptr_t erstba_phys = dma_buffer_phys_base(&hc->event_ring.erst);
     495        XHCI_REG_WR(intr0, XHCI_INTR_ERSTBA, erstba_phys);
    493496
    494497        if (hc->base.irq_cap > 0) {
     
    799802        if (err == EOK) {
    800803                dev->slot_id = cmd.slot_id;
    801                 hc->dcbaa[dev->slot_id] = host2xhci(64, dev->dev_ctx.phys);
     804                hc->dcbaa[dev->slot_id] =
     805                    host2xhci(64, dma_buffer_phys_base(&dev->dev_ctx));
    802806        }
    803807
  • uspace/drv/bus/usb/xhci/isoch.c

    r2f762a7 r1d758fc  
    176176        xhci_trb_clean(&trb);
    177177
    178         trb.parameter = it->data.phys;
     178        trb.parameter = host2xhci(64, dma_buffer_phys_base(&it->data));
    179179        TRB_CTRL_SET_XFER_LEN(trb, it->size);
    180180        TRB_CTRL_SET_TD_SIZE(trb, 0);
     
    481481
    482482        /* This shall be already checked by endpoint */
    483         assert(transfer->batch.buffer_size <= ep->base.max_transfer_size);
     483        assert(transfer->batch.size <= ep->base.max_transfer_size);
    484484
    485485        fibril_mutex_lock(&isoch->guard);
     
    521521
    522522        /* Prepare the transfer. */
    523         it->size = transfer->batch.buffer_size;
     523        it->size = transfer->batch.size;
    524524        memcpy(it->data.virt, transfer->batch.dma_buffer.virt, it->size);
    525525        it->state = ISOCH_FILLED;
     
    544544        xhci_isoch_t * const isoch = ep->isoch;
    545545
    546         if (transfer->batch.buffer_size < ep->base.max_transfer_size) {
     546        if (transfer->batch.size < ep->base.max_transfer_size) {
    547547                usb_log_error("Cannot schedule an undersized isochronous transfer.");
    548548                return ELIMIT;
  • uspace/drv/bus/usb/xhci/scratchpad.c

    r2f762a7 r1d758fc  
    7272        memset(hc->scratchpad_array.virt, 0, size);
    7373
    74         uint64_t phys_begin = hc->scratchpad_array.phys + array_size;
     74        const char *base = hc->scratchpad_array.virt + array_size;
    7575        uint64_t *array = hc->scratchpad_array.virt;
    7676
    77         for (unsigned i = 0; i < num_bufs; ++i)
    78                 array[i] = host2xhci(64, phys_begin + i * PAGE_SIZE);
     77        for (unsigned i = 0; i < num_bufs; ++i) {
     78                array[i] = host2xhci(64, dma_buffer_phys(&hc->scratchpad_array,
     79                            base + i * PAGE_SIZE));
     80        }
    7981
    80         hc->dcbaa[0] = host2xhci(64, hc->scratchpad_array.phys);
     82        hc->dcbaa[0] = host2xhci(64, dma_buffer_phys_base(&hc->scratchpad_array));
    8183
    8284        usb_log_debug("Allocated %d scratchpad buffers.", num_bufs);
  • uspace/drv/bus/usb/xhci/streams.c

    r2f762a7 r1d758fc  
    239239        data->secondary_stream_ctx_array = data->secondary_stream_ctx_dma.virt;
    240240
    241         XHCI_STREAM_DEQ_PTR_SET(*ctx, data->secondary_stream_ctx_dma.phys);
     241        XHCI_STREAM_DEQ_PTR_SET(*ctx, dma_buffer_phys_base(&data->secondary_stream_ctx_dma));
    242242        XHCI_STREAM_SCT_SET(*ctx, fnzb32(count) + 1);
    243243
     
    283283
    284284        XHCI_EP_MAX_P_STREAMS_SET(*ctx, pstreams);
    285         XHCI_EP_TR_DPTR_SET(*ctx, xhci_ep->primary_stream_ctx_dma.phys);
     285        XHCI_EP_TR_DPTR_SET(*ctx, dma_buffer_phys_base(&xhci_ep->primary_stream_ctx_dma));
    286286        XHCI_EP_LSA_SET(*ctx, lsa);
    287287}
  • uspace/drv/bus/usb/xhci/transfers.c

    r2f762a7 r1d758fc  
    126126static int calculate_trb_count(xhci_transfer_t *transfer)
    127127{
    128         const size_t size = transfer->batch.buffer_size;
     128        const size_t size = transfer->batch.size;
    129129        return (size + PAGE_SIZE - 1 )/ PAGE_SIZE;
    130130}
     
    184184                int stage_dir = REQUEST_TYPE_IS_DEVICE_TO_HOST(setup->request_type)
    185185                                        ? STAGE_IN : STAGE_OUT;
    186                 size_t remaining = transfer->batch.buffer_size;
     186                size_t remaining = transfer->batch.size;
    187187
    188188                for (size_t i = 0; i < buffer_count; ++i) {
     
    227227                const size_t buffer_count = calculate_trb_count(transfer);
    228228                xhci_trb_t trbs[buffer_count];
    229                 size_t remaining = transfer->batch.buffer_size;
     229                size_t remaining = transfer->batch.size;
    230230
    231231                for (size_t i = 0; i < buffer_count; ++i) {
     
    254254                const size_t buffer_count = calculate_trb_count(transfer);
    255255                xhci_trb_t trbs[buffer_count + 1];
    256                 size_t remaining = transfer->batch.buffer_size;
     256                size_t remaining = transfer->batch.size;
    257257
    258258                for (size_t i = 0; i < buffer_count; ++i) {
     
    278278        const size_t buffer_count = calculate_trb_count(transfer);
    279279        xhci_trb_t trbs[buffer_count];
    280         size_t remaining = transfer->batch.buffer_size;
     280        size_t remaining = transfer->batch.size;
    281281
    282282        for (size_t i = 0; i < buffer_count; ++i) {
     
    372372                case XHCI_TRBC_SUCCESS:
    373373                        batch->error = EOK;
    374                         batch->transferred_size = batch->buffer_size - TRB_TRANSFER_LENGTH(*trb);
     374                        batch->transferred_size = batch->size - TRB_TRANSFER_LENGTH(*trb);
    375375                        break;
    376376
     
    416416        }
    417417
    418         assert(batch->transferred_size <= batch->buffer_size);
     418        assert(batch->transferred_size <= batch->size);
    419419
    420420        usb_transfer_batch_finish(batch);
  • uspace/drv/bus/usb/xhci/trb_ring.c

    r2f762a7 r1d758fc  
    8989static errno_t trb_segment_alloc(trb_segment_t **segment)
    9090{
    91         dma_buffer_t dbuf;
    92 
    93         const errno_t err = dma_buffer_alloc(&dbuf, PAGE_SIZE);
     91        *segment = AS_AREA_ANY;
     92        uintptr_t phys;
     93
     94        const int err = dmamem_map_anonymous(PAGE_SIZE,
     95            DMAMEM_4GiB, AS_AREA_READ | AS_AREA_WRITE, 0,
     96            &phys, (void **) segment);
    9497        if (err)
    9598                return err;
    9699
    97         *segment = dbuf.virt;
    98100        memset(*segment, 0, PAGE_SIZE);
    99         (*segment)->phys = dbuf.phys;
     101        (*segment)->phys = phys;
    100102        usb_log_debug("Allocated new ring segment.");
    101103        return EOK;
     
    104106static void trb_segment_free(trb_segment_t *segment)
    105107{
    106         dma_buffer_t dbuf = { .virt = segment, .phys = segment->phys };
    107         dma_buffer_free(&dbuf);
     108        dmamem_unmap_anonymous(segment);
    108109}
    109110
Note: See TracChangeset for help on using the changeset viewer.