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


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
Files:
15 edited

Legend:

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

    r2f762a7 r1d758fc  
    102102                : 0;
    103103
    104         const size_t size = ehci_batch->base.buffer_size;
     104        const size_t size = ehci_batch->base.size;
    105105
    106106        /* Add TD left over by the previous transfer */
     
    180180
    181181        /* Assume all data got through */
    182         ehci_batch->base.transferred_size = ehci_batch->base.buffer_size;
     182        ehci_batch->base.transferred_size = ehci_batch->base.size;
    183183
    184184        /* Check all TDs */
     
    216216        }
    217217
    218         assert(ehci_batch->base.transferred_size <= ehci_batch->base.buffer_size);
     218        assert(ehci_batch->base.transferred_size <= ehci_batch->base.size);
    219219
    220220        /* Clear TD pointers */
     
    281281        /* Data stage */
    282282        unsigned td_current = 1;
    283         size_t remain_size = ehci_batch->base.buffer_size;
     283        size_t remain_size = ehci_batch->base.size;
    284284        uintptr_t buffer = dma_buffer_phys(&ehci_batch->base.dma_buffer,
    285285            ehci_batch->data_buffer);
     
    335335
    336336        size_t td_current = 0;
    337         size_t remain_size = ehci_batch->base.buffer_size;
     337        size_t remain_size = ehci_batch->base.size;
    338338        uintptr_t buffer = dma_buffer_phys(&ehci_batch->base.dma_buffer,
    339339            ehci_batch->data_buffer);
  • uspace/drv/bus/usb/ehci/ehci_rh.c

    r2f762a7 r1d758fc  
    147147        batch->error = virthub_base_request(&instance->base, batch->target,
    148148            batch->dir, (void*) batch->setup.buffer,
    149             batch->dma_buffer.virt, batch->buffer_size,
     149            batch->dma_buffer.virt, batch->size,
    150150            &batch->transferred_size);
    151151        if (batch->error == ENAK) {
     
    206206                batch->error = virthub_base_request(&instance->base, batch->target,
    207207                    batch->dir, (void*) batch->setup.buffer,
    208                     batch->dma_buffer.virt, batch->buffer_size,
     208                    batch->dma_buffer.virt, batch->size,
    209209                    &batch->transferred_size);
    210210                usb_transfer_batch_finish(batch);
  • uspace/drv/bus/usb/ohci/ohci_batch.c

    r2f762a7 r1d758fc  
    9696                return ENOTSUP;
    9797
    98         ohci_batch->td_count = (usb_batch->buffer_size + OHCI_TD_MAX_TRANSFER - 1)
     98        ohci_batch->td_count = (usb_batch->size + OHCI_TD_MAX_TRANSFER - 1)
    9999            / OHCI_TD_MAX_TRANSFER;
    100100        /* Control transfer need Setup and Status stage */
     
    166166
    167167        /* Assume all data got through */
    168         usb_batch->transferred_size = usb_batch->buffer_size;
     168        usb_batch->transferred_size = usb_batch->size;
    169169
    170170        /* Check all TDs */
     
    212212                }
    213213        }
    214         assert(usb_batch->transferred_size <= usb_batch->buffer_size);
     214        assert(usb_batch->transferred_size <= usb_batch->size);
    215215
    216216        /* Make sure that we are leaving the right TD behind */
     
    289289        size_t td_current = 1;
    290290        const char* buffer = ohci_batch->data_buffer;
    291         size_t remain_size = ohci_batch->base.buffer_size;
     291        size_t remain_size = ohci_batch->base.size;
    292292        while (remain_size > 0) {
    293293                const size_t transfer_size =
     
    343343
    344344        size_t td_current = 0;
    345         size_t remain_size = ohci_batch->base.buffer_size;
     345        size_t remain_size = ohci_batch->base.size;
    346346        char *buffer = ohci_batch->data_buffer;
    347347        while (remain_size > 0) {
  • uspace/drv/bus/usb/ohci/ohci_rh.c

    r2f762a7 r1d758fc  
    182182        batch->error = virthub_base_request(&instance->base, batch->target,
    183183            batch->dir, &batch->setup.packet,
    184             batch->dma_buffer.virt, batch->buffer_size, &batch->transferred_size);
     184            batch->dma_buffer.virt, batch->size, &batch->transferred_size);
    185185        if (batch->error == ENAK) {
    186186                /* Lock the HC guard */
     
    233233                batch->error = virthub_base_request(&instance->base, batch->target,
    234234                    batch->dir, &batch->setup.packet,
    235                     batch->dma_buffer.virt, batch->buffer_size, &batch->transferred_size);
     235                    batch->dma_buffer.virt, batch->size, &batch->transferred_size);
    236236                usb_transfer_batch_finish(batch);
    237237        }
  • uspace/drv/bus/usb/uhci/uhci_batch.c

    r2f762a7 r1d758fc  
    9898        usb_transfer_batch_t *usb_batch = &uhci_batch->base;
    9999
    100         uhci_batch->td_count = (usb_batch->buffer_size + usb_batch->ep->max_packet_size - 1)
     100        uhci_batch->td_count = (usb_batch->size + usb_batch->ep->max_packet_size - 1)
    101101                / usb_batch->ep->max_packet_size;
    102102
     
    190190        }
    191191
    192         assert(batch->transferred_size <= batch->buffer_size);
     192        assert(batch->transferred_size <= batch->size);
    193193
    194194        return true;
     
    228228
    229229        size_t td = 0;
    230         size_t remain_size = uhci_batch->base.buffer_size;
     230        size_t remain_size = uhci_batch->base.size;
    231231        char *buffer = uhci_transfer_batch_data_buffer(uhci_batch);
    232232
     
    297297        size_t td = 1;
    298298        unsigned toggle = 1;
    299         size_t remain_size = uhci_batch->base.buffer_size;
     299        size_t remain_size = uhci_batch->base.size;
    300300        char *buffer = uhci_transfer_batch_data_buffer(uhci_batch);
    301301
  • uspace/drv/bus/usb/uhci/uhci_rh.c

    r2f762a7 r1d758fc  
    107107                batch->error = virthub_base_request(&instance->base, batch->target,
    108108                    batch->dir, (void*) batch->setup.buffer,
    109                     batch->dma_buffer.virt, batch->buffer_size, &batch->transferred_size);
     109                    batch->dma_buffer.virt, batch->size, &batch->transferred_size);
    110110                if (batch->error == ENAK)
    111111                        async_usleep(instance->base.endpoint_descriptor.poll_interval * 1000);
  • uspace/drv/bus/usb/vhc/transfer.c

    r2f762a7 r1d758fc  
    7272                        rc = usbvirt_control_read(dev,
    7373                            batch->setup.buffer, USB_SETUP_PACKET_SIZE,
    74                             batch->dma_buffer.virt, batch->buffer_size,
     74                            batch->dma_buffer.virt, batch->size,
    7575                            actual_data_size);
    7676                } else {
     
    7878                        rc = usbvirt_control_write(dev,
    7979                            batch->setup.buffer, USB_SETUP_PACKET_SIZE,
    80                             batch->dma_buffer.virt, batch->buffer_size);
     80                            batch->dma_buffer.virt, batch->size);
    8181                }
    8282        } else {
     
    8484                        rc = usbvirt_data_in(dev, batch->ep->transfer_type,
    8585                            batch->ep->endpoint,
    86                             batch->dma_buffer.virt, batch->buffer_size,
     86                            batch->dma_buffer.virt, batch->size,
    8787                            actual_data_size);
    8888                } else {
     
    9090                        rc = usbvirt_data_out(dev, batch->ep->transfer_type,
    9191                            batch->ep->endpoint,
    92                             batch->dma_buffer.virt, batch->buffer_size);
     92                            batch->dma_buffer.virt, batch->size);
    9393                }
    9494        }
     
    108108                        rc = usbvirt_ipc_send_control_read(sess,
    109109                            batch->setup.buffer, USB_SETUP_PACKET_SIZE,
    110                             batch->dma_buffer.virt, batch->buffer_size,
     110                            batch->dma_buffer.virt, batch->size,
    111111                            actual_data_size);
    112112                } else {
     
    114114                        rc = usbvirt_ipc_send_control_write(sess,
    115115                            batch->setup.buffer, USB_SETUP_PACKET_SIZE,
    116                             batch->dma_buffer.virt, batch->buffer_size);
     116                            batch->dma_buffer.virt, batch->size);
    117117                }
    118118        } else {
     
    120120                        rc = usbvirt_ipc_send_data_in(sess, batch->ep->endpoint,
    121121                            batch->ep->transfer_type,
    122                             batch->dma_buffer.virt, batch->buffer_size,
     122                            batch->dma_buffer.virt, batch->size,
    123123                            actual_data_size);
    124124                } else {
     
    126126                        rc = usbvirt_ipc_send_data_out(sess, batch->ep->endpoint,
    127127                            batch->ep->transfer_type,
    128                             batch->dma_buffer.virt, batch->buffer_size);
     128                            batch->dma_buffer.virt, batch->size);
    129129                }
    130130        }
  • 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.