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


Ignore:
Timestamp:
2017-10-21T10:34:45Z (7 years ago)
Author:
Petr Manek <petr.manek@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
8ea7459
Parents:
1252e81
Message:

Added option to enqueue multiple TDs at once. Demoted some log messages.

File:
1 edited

Legend:

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

    r1252e81 rd1d7a92  
    155155        }
    156156
    157         xhci_trb_t trb_setup;
    158         xhci_trb_clean(&trb_setup);
    159 
    160         TRB_CTRL_SET_SETUP_WVALUE(trb_setup, setup->value);
    161         TRB_CTRL_SET_SETUP_WLENGTH(trb_setup, setup->length);
    162         TRB_CTRL_SET_SETUP_WINDEX(trb_setup, setup->index);
    163         TRB_CTRL_SET_SETUP_BREQ(trb_setup, setup->request);
    164         TRB_CTRL_SET_SETUP_BMREQTYPE(trb_setup, setup->request_type);
     157        xhci_trb_t trbs[3];
     158        int trbs_used = 0;
     159
     160        xhci_trb_t *trb_setup = trbs + trbs_used++;
     161        xhci_trb_clean(trb_setup);
     162
     163        TRB_CTRL_SET_SETUP_WVALUE(*trb_setup, setup->value);
     164        TRB_CTRL_SET_SETUP_WLENGTH(*trb_setup, setup->length);
     165        TRB_CTRL_SET_SETUP_WINDEX(*trb_setup, setup->index);
     166        TRB_CTRL_SET_SETUP_BREQ(*trb_setup, setup->request);
     167        TRB_CTRL_SET_SETUP_BMREQTYPE(*trb_setup, setup->request_type);
    165168
    166169        /* Size of the setup packet is always 8 */
    167         TRB_CTRL_SET_XFER_LEN(trb_setup, 8);
    168         // if we want an interrupt after this td is done, use
    169         // TRB_CTRL_SET_IOC(trb_setup, 1);
     170        TRB_CTRL_SET_XFER_LEN(*trb_setup, 8);
    170171
    171172        /* Immediate data */
    172         TRB_CTRL_SET_IDT(trb_setup, 1);
    173         TRB_CTRL_SET_TRB_TYPE(trb_setup, XHCI_TRB_TYPE_SETUP_STAGE);
    174         TRB_CTRL_SET_TRT(trb_setup, get_transfer_type(&trb_setup, setup->request_type, setup->length));
     173        TRB_CTRL_SET_IDT(*trb_setup, 1);
     174        TRB_CTRL_SET_TRB_TYPE(*trb_setup, XHCI_TRB_TYPE_SETUP_STAGE);
     175        TRB_CTRL_SET_TRT(*trb_setup, get_transfer_type(trb_setup, setup->request_type, setup->length));
    175176
    176177        /* Data stage */
    177         xhci_trb_t trb_data;
    178         xhci_trb_clean(&trb_data);
    179 
     178        xhci_trb_t *trb_data = NULL;
    180179        if (setup->length > 0) {
    181                 trb_data.parameter = addr_to_phys(transfer->hc_buffer);
     180                trb_data = trbs + trbs_used++;
     181                xhci_trb_clean(trb_data);
     182
     183                trb_data->parameter = addr_to_phys(transfer->hc_buffer);
    182184
    183185                // data size (sent for OUT, or buffer size)
    184                 TRB_CTRL_SET_XFER_LEN(trb_data, batch->buffer_size);
     186                TRB_CTRL_SET_XFER_LEN(*trb_data, batch->buffer_size);
    185187                // FIXME: TD size 4.11.2.4
    186                 TRB_CTRL_SET_TD_SIZE(trb_data, 1);
    187 
    188                 // if we want an interrupt after this td is done, use
    189                 // TRB_CTRL_SET_IOC(trb_data, 1);
     188                TRB_CTRL_SET_TD_SIZE(*trb_data, 1);
    190189
    191190                // Some more fields here, no idea what they mean
    192                 TRB_CTRL_SET_TRB_TYPE(trb_data, XHCI_TRB_TYPE_DATA_STAGE);
     191                TRB_CTRL_SET_TRB_TYPE(*trb_data, XHCI_TRB_TYPE_DATA_STAGE);
    193192
    194193                transfer->direction = REQUEST_TYPE_IS_DEVICE_TO_HOST(setup->request_type)
    195194                                        ? STAGE_IN : STAGE_OUT;
    196                 TRB_CTRL_SET_DIR(trb_data, transfer->direction);
     195                TRB_CTRL_SET_DIR(*trb_data, transfer->direction);
    197196        }
    198197
    199198        /* Status stage */
    200         xhci_trb_t trb_status;
    201         xhci_trb_clean(&trb_status);
     199        xhci_trb_t *trb_status = trbs + trbs_used++;
     200        xhci_trb_clean(trb_status);
    202201
    203202        // FIXME: Evaluate next TRB? 4.12.3
    204         // TRB_CTRL_SET_ENT(trb_status, 1);
    205 
    206         // if we want an interrupt after this td is done, use
    207         TRB_CTRL_SET_IOC(trb_status, 1);
    208 
    209         TRB_CTRL_SET_TRB_TYPE(trb_status, XHCI_TRB_TYPE_STATUS_STAGE);
    210         TRB_CTRL_SET_DIR(trb_status, get_status_direction_flag(&trb_setup, setup->request_type, setup->length));
     203        // TRB_CTRL_SET_ENT(*trb_status, 1);
     204
     205        TRB_CTRL_SET_IOC(*trb_status, 1);
     206        TRB_CTRL_SET_TRB_TYPE(*trb_status, XHCI_TRB_TYPE_STATUS_STAGE);
     207        TRB_CTRL_SET_DIR(*trb_status, get_status_direction_flag(trb_setup, setup->request_type, setup->length));
    211208
    212209        xhci_endpoint_t *xhci_ep = xhci_endpoint_get(batch->ep);
     
    214211        xhci_trb_ring_t* ring = hc->dcbaa_virt[slot_id].trs[batch->ep->target.endpoint];
    215212
    216         uintptr_t dummy = 0;
    217         xhci_trb_ring_enqueue(ring, &trb_setup, &dummy);
    218         if (setup->length > 0) {
    219                 xhci_trb_ring_enqueue(ring, &trb_data, &dummy);
    220         }
    221         xhci_trb_ring_enqueue(ring, &trb_status, &transfer->interrupt_trb_phys);
     213        int err = xhci_trb_ring_enqueue_multiple(ring, trbs, trbs_used, &transfer->interrupt_trb_phys);
     214        if (err != EOK)
     215                return err;
    222216
    223217        list_append(&transfer->link, &hc->transfers);
     
    226220        if (configure_endpoint_needed(setup)) {
    227221                // TODO: figure out the best time to issue this command
    228                 // FIXME: ignoring return code
    229                 xhci_device_configure(xhci_ep->device, hc);
     222                // FIXME: on fail, we need to "cancel" in-flight TRBs and remove transfer from the list
     223                err = xhci_device_configure(xhci_ep->device, hc);
     224                if (err != EOK)
     225                        return err;
    230226        }
    231227
Note: See TracChangeset for help on using the changeset viewer.