Changeset 4db49344 in mainline for uspace/drv/bus/usb/ehci/hc.c


Ignore:
Timestamp:
2018-01-23T21:52:28Z (6 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/ehci/hc.c

    ra6afb4c r4db49344  
    302302        endpoint_t * const ep = batch->ep;
    303303        ehci_endpoint_t * const ehci_ep = ehci_endpoint_get(ep);
    304 
    305         /* creating local reference */
    306         endpoint_add_ref(ep);
    307 
    308         fibril_mutex_lock(&ep->guard);
    309         endpoint_activate_locked(ep, batch);
    310 
    311304        ehci_transfer_batch_t *ehci_batch = ehci_transfer_batch_get(batch);
    312         const int err = ehci_transfer_batch_prepare(ehci_batch);
    313         if (err) {
    314                 endpoint_deactivate_locked(ep);
    315                 fibril_mutex_unlock(&ep->guard);
    316                 /* dropping local reference */
    317                 endpoint_del_ref(ep);
     305
     306        int err;
     307
     308        if ((err = ehci_transfer_batch_prepare(ehci_batch)))
     309                return err;
     310
     311        fibril_mutex_lock(&hc->guard);
     312
     313        if ((err = endpoint_activate_locked(ep, batch))) {
     314                fibril_mutex_unlock(&hc->guard);
    318315                return err;
    319316        }
     
    321318        usb_log_debug("HC(%p): Committing BATCH(%p)", hc, batch);
    322319        ehci_transfer_batch_commit(ehci_batch);
    323         fibril_mutex_unlock(&ep->guard);
    324320
    325321        /* Enqueue endpoint to the checked list */
    326         fibril_mutex_lock(&hc->guard);
    327322        usb_log_debug2("HC(%p): Appending BATCH(%p)", hc, batch);
    328 
    329         /* local reference -> pending list reference */
    330323        list_append(&ehci_ep->pending_link, &hc->pending_endpoints);
     324
    331325        fibril_mutex_unlock(&hc->guard);
    332 
    333326        return EOK;
    334327}
     
    368361                                = list_get_instance(current, ehci_endpoint_t, pending_link);
    369362
    370                         fibril_mutex_lock(&ep->base.guard);
    371363                        ehci_transfer_batch_t *batch
    372364                                = ehci_transfer_batch_get(ep->base.active_batch);
     
    376368                                endpoint_deactivate_locked(&ep->base);
    377369                                list_remove(current);
    378                                 endpoint_del_ref(&ep->base);
    379370                                hc_reset_toggles(&batch->base, &ehci_ep_toggle_reset);
    380371                                usb_transfer_batch_finish(&batch->base);
    381372                        }
    382                         fibril_mutex_unlock(&ep->base.guard);
    383373                }
    384374                fibril_mutex_unlock(&hc->guard);
Note: See TracChangeset for help on using the changeset viewer.