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


Ignore:
Timestamp:
2018-01-23T21:52:28Z (8 years ago)
Author:
Ondřej Hlavatý <aearsis@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
3dd80f8
Parents:
a6afb4c
git-author:
Ondřej Hlavatý <aearsis@…> (2018-01-23 20:49:35)
git-committer:
Ondřej Hlavatý <aearsis@…> (2018-01-23 21:52:28)
Message:

usb: fix wrong design of transfer aborting

Apparently, we didn't do a good job in thinking through the problem.
In older HCs, it was done just wrong - the UHCI implementation commited
a batch that could have been already aborted, and EHCI+OHCI might miss
an interrupt because they commited the batch sooner than they added it
to their checked list.

This commit takes everything from the other end, which is probably the
only right one. Instead of an endpoint having an extra mutex, it
inherits a mutex from the outside. It never locks it though, it just
checks if the mutex is locked and uses it for waiting on condition
variables.

This mutex is supposed to be the one which the HC driver uses for
locking its structures in scheduling. This way, we avoid the ABBA
deadlock completely, while preserving the synchronization on an
endpoint.

The good thing is that this implementation is much easier to extend with
multiple active batches per endpoint.

File:
1 edited

Legend:

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

    ra6afb4c r4db49344  
    300300
    301301        if (TRB_EVENT_DATA(*trb)) {
    302                 assert(ep->base.transfer_type != USB_TRANSFER_ISOCHRONOUS);
     302                /* We schedule those only when streams are involved */
     303                assert(ep->primary_stream_ctx_array != NULL);
     304
    303305                /* We are received transfer pointer instead - work with that */
    304306                transfer = (xhci_transfer_t *) addr;
     
    306308                    transfer->interrupt_trb_phys);
    307309                batch = &transfer->batch;
    308 
    309                 fibril_mutex_lock(&ep->base.guard);
    310                 endpoint_deactivate_locked(&ep->base);
    311                 fibril_mutex_unlock(&ep->base.guard);
    312310        }
    313311        else {
     
    321319                }
    322320
    323                 fibril_mutex_lock(&ep->base.guard);
     321                fibril_mutex_lock(&ep->guard);
    324322                batch = ep->base.active_batch;
     323                endpoint_deactivate_locked(&ep->base);
     324                fibril_mutex_unlock(&ep->guard);
     325
    325326                if (!batch) {
    326                         fibril_mutex_unlock(&ep->base.guard);
    327327                        /* Dropping temporary reference */
    328328                        endpoint_del_ref(&ep->base);
     
    331331
    332332                transfer = xhci_transfer_from_batch(batch);
    333 
    334                 endpoint_deactivate_locked(&ep->base);
    335                 fibril_mutex_unlock(&ep->base.guard);
    336333        }
    337334
     
    482479
    483480
    484         fibril_mutex_lock(&ep->guard);
    485         endpoint_activate_locked(ep, batch);
    486         const int err = transfer_handlers[batch->ep->transfer_type](hc, transfer);
    487 
    488         if (err) {
     481        int err;
     482        fibril_mutex_lock(&xhci_ep->guard);
     483
     484        if ((err = endpoint_activate_locked(ep, batch))) {
     485                fibril_mutex_unlock(&xhci_ep->guard);
     486                return err;
     487        }
     488
     489        if ((err = transfer_handlers[batch->ep->transfer_type](hc, transfer))) {
    489490                endpoint_deactivate_locked(ep);
    490                 fibril_mutex_unlock(&ep->guard);
     491                fibril_mutex_unlock(&xhci_ep->guard);
    491492                return err;
    492493        }
    493494
    494495        hc_ring_ep_doorbell(xhci_ep, batch->target.stream);
    495         fibril_mutex_unlock(&ep->guard);
     496        fibril_mutex_unlock(&xhci_ep->guard);
    496497        return EOK;
    497498}
Note: See TracChangeset for help on using the changeset viewer.