Fork us on GitHub Follow us on Facebook Follow us on Twitter

Changeset d1d7a92 in mainline


Ignore:
Timestamp:
2017-10-21T10:34:45Z (4 years ago)
Author:
Petr Manek <petr.manek@…>
Branches:
lfn, master
Children:
8ea7459
Parents:
1252e81
Message:

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

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

Legend:

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

    r1252e81 rd1d7a92  
    187187        ret_dev->device = dev;
    188188
    189         usb_log_debug("Device(%d) registered to XHCI bus.", dev->address);
     189        usb_log_info("Device(%d) registered to XHCI bus.", dev->address);
    190190
    191191        hash_table_insert(&bus->devices, &ret_dev->link);
     
    202202static int hashed_device_remove(xhci_bus_t *bus, hashed_device_t *hashed_dev)
    203203{
    204         usb_log_debug("Device(%d) released from XHCI bus.", hashed_dev->device->address);
     204        usb_log_info("Device(%d) released from XHCI bus.", hashed_dev->device->address);
    205205
    206206        hash_table_remove(&bus->devices, &hashed_dev->device->address);
     
    229229        }
    230230
    231         usb_log_debug("Endpoint(%d:%d) registered to XHCI bus.", ep->target.address, ep->target.endpoint);
     231        usb_log_info("Endpoint(%d:%d) registered to XHCI bus.", ep->target.address, ep->target.endpoint);
    232232
    233233        return xhci_device_add_endpoint(hashed_dev->device, xhci_endpoint_get(ep));
     
    239239        assert(bus);
    240240
    241         usb_log_debug("Endpoint(%d:%d) released from XHCI bus.", ep->target.address, ep->target.endpoint);
     241        usb_log_info("Endpoint(%d:%d) released from XHCI bus.", ep->target.address, ep->target.endpoint);
    242242
    243243        hashed_device_t *hashed_dev;
  • uspace/drv/bus/usb/xhci/commands.c

    r1252e81 rd1d7a92  
    443443        assert(trb);
    444444
    445         usb_log_debug("HC(%p) Command completed.", hc);
     445        usb_log_debug2("HC(%p) Command completed.", hc);
    446446
    447447        int code;
     
    454454        if (command == NULL) {
    455455                // TODO: STOP & ABORT may not have command structs in the list!
    456                 usb_log_debug("No command struct for this completion event found.");
     456                usb_log_warning("No command struct for this completion event found.");
    457457
    458458                if (code != XHCI_TRBC_SUCCESS)
  • 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
  • uspace/drv/bus/usb/xhci/trb_ring.c

    r1252e81 rd1d7a92  
    116116        fibril_mutex_initialize(&ring->guard);
    117117
    118         usb_log_debug("Initialized new TRB ring.");
     118        usb_log_debug2("Initialized new TRB ring.");
    119119
    120120        return EOK;
     
    156156
    157157/**
    158  * Enqueue a TD composed of TRBs.
    159  *
    160  * This will copy all TRBs chained together into the ring. The cycle flag in
    161  * TRBs may be changed.
    162  *
    163  * The chained TRBs must be contiguous in memory, and must not contain Link TRBs.
     158 * Enqueue TDs composed of TRBs.
     159 *
     160 * This will copy specified number of TRBs chained together into the ring. The
     161 * cycle flag in TRBs may be changed.
     162 *
     163 * The copied TRBs must be contiguous in memory, and must not contain Link TRBs.
    164164 *
    165165 * We cannot avoid the copying, because the TRB in ring should be updated atomically.
    166166 *
    167  * @param td the first TRB of TD
    168  * @param phys returns address of the first TRB enqueued
     167 * @param first_trb the first TRB
     168 * @param trbs number of TRBS to enqueue
     169 * @param phys returns address of the last TRB enqueued
    169170 * @return EOK on success,
    170171 *         EAGAIN when the ring is too full to fit all TRBs (temporary)
    171172 */
    172 int xhci_trb_ring_enqueue(xhci_trb_ring_t *ring, xhci_trb_t *td, uintptr_t *phys)
    173 {
     173int xhci_trb_ring_enqueue_multiple(xhci_trb_ring_t *ring, xhci_trb_t *first_trb,
     174        size_t trbs, uintptr_t *phys)
     175{
     176        assert(trbs > 0);
    174177        fibril_mutex_lock(&ring->guard);
    175178
     
    183186         * be full anytime during the transaction.
    184187         */
    185         xhci_trb_t *trb = td;
    186         do {
     188        xhci_trb_t *trb = first_trb;
     189        for (size_t i = 0; i < trbs; ++i, ++trb) {
    187190                ring->enqueue_trb++;
    188191
     
    192195                if (trb_ring_enqueue_phys(ring) == ring->dequeue)
    193196                        goto err_again;
    194         } while (xhci_trb_is_chained(trb++));
     197        }
    195198
    196199        ring->enqueue_segment = saved_enqueue_segment;
    197200        ring->enqueue_trb = saved_enqueue_trb;
    198         if (phys)
    199                 *phys = trb_ring_enqueue_phys(ring);
    200201
    201202        /*
    202203         * Now, copy the TRBs without further checking.
    203204         */
    204         trb = td;
    205         do {
     205        trb = first_trb;
     206        for (size_t i = 0; i < trbs; ++i, ++trb) {
     207                if (phys && i == trbs - 1)
     208                        *phys = trb_ring_enqueue_phys(ring);
     209
    206210                xhci_trb_set_cycle(trb, ring->pcs);
    207211                xhci_trb_copy(ring->enqueue_trb, trb);
     
    221225                        trb_ring_resolve_link(ring);
    222226                }
    223         } while (xhci_trb_is_chained(trb++));
     227        }
    224228
    225229        fibril_mutex_unlock(&ring->guard);
     
    234238
    235239/**
     240 * Enqueue TD composed of a single TRB. See: `xhci_trb_ring_enqueue_multiple`
     241 */
     242int xhci_trb_ring_enqueue(xhci_trb_ring_t *ring, xhci_trb_t *td, uintptr_t *phys)
     243{
     244        return xhci_trb_ring_enqueue_multiple(ring, td, 1, phys);
     245}
     246
     247/**
    236248 * Initializes an event ring.
    237249 * Even when it fails, the structure needs to be finalized.
  • uspace/drv/bus/usb/xhci/trb_ring.h

    r1252e81 rd1d7a92  
    7676int xhci_trb_ring_fini(xhci_trb_ring_t *);
    7777int xhci_trb_ring_enqueue(xhci_trb_ring_t *, xhci_trb_t *, uintptr_t *);
     78int xhci_trb_ring_enqueue_multiple(xhci_trb_ring_t *, xhci_trb_t *, size_t, uintptr_t *);
    7879
    7980/**
Note: See TracChangeset for help on using the changeset viewer.