Changeset d60115a in mainline


Ignore:
Timestamp:
2018-01-17T17:55:35Z (6 years ago)
Author:
Ondřej Hlavatý <aearsis@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
8ad2b0a
Parents:
ed8575f
git-author:
Ondřej Hlavatý <aearsis@…> (2018-01-17 17:54:31)
git-committer:
Ondřej Hlavatý <aearsis@…> (2018-01-17 17:55:35)
Message:

ohci: implement transfer abort on endpoint unregister

Location:
uspace/drv/bus/usb/ohci
Files:
8 edited

Legend:

Unmodified
Added
Removed
  • uspace/drv/bus/usb/ohci/endpoint_list.c

    red8575f rd60115a  
    108108                /* There are active EDs, get the last one */
    109109                ohci_endpoint_t *last = list_get_instance(
    110                     list_last(&instance->endpoint_list), ohci_endpoint_t, link);
     110                    list_last(&instance->endpoint_list), ohci_endpoint_t, eplist_link);
    111111                last_ed = last->ed;
    112112        }
     
    122122
    123123        /* Add to the sw list */
    124         list_append(&ep->link, &instance->endpoint_list);
     124        list_append(&ep->eplist_link, &instance->endpoint_list);
    125125
    126126        ohci_endpoint_t *first = list_get_instance(
    127             list_first(&instance->endpoint_list), ohci_endpoint_t, link);
     127            list_first(&instance->endpoint_list), ohci_endpoint_t, eplist_link);
    128128        usb_log_debug("HCD EP(%p) added to list %s, first is %p(%p).",
    129129                ep, instance->name, first, first->ed);
     
    156156        ed_t *prev_ed;
    157157        /* Remove from the hardware queue */
    158         if (list_first(&instance->endpoint_list) == &ep->link) {
     158        if (list_first(&instance->endpoint_list) == &ep->eplist_link) {
    159159                /* I'm the first one here */
    160160                prev_ed = instance->list_head;
     
    162162        } else {
    163163                ohci_endpoint_t *prev =
    164                     list_get_instance(ep->link.prev, ohci_endpoint_t, link);
     164                    list_get_instance(ep->eplist_link.prev, ohci_endpoint_t, eplist_link);
    165165                prev_ed = prev->ed;
    166166                qpos = "NOT FIRST";
     
    175175
    176176        /* Remove from the endpoint list */
    177         list_remove(&ep->link);
     177        list_remove(&ep->eplist_link);
    178178        fibril_mutex_unlock(&instance->guard);
    179179}
  • uspace/drv/bus/usb/ohci/hc.c

    red8575f rd60115a  
    168168            hw_res->mem_ranges.ranges[0].size);
    169169
    170         list_initialize(&instance->pending_batches);
     170        list_initialize(&instance->pending_endpoints);
    171171        fibril_mutex_initialize(&instance->guard);
    172172
     
    304304                return err;
    305305
    306         fibril_mutex_lock(&hc->guard);
    307         list_append(&ohci_batch->link, &hc->pending_batches);
     306        endpoint_t *ep = batch->ep;
     307        ohci_endpoint_t * const ohci_ep = ohci_endpoint_get(ep);
     308
     309        /* creating local reference */
     310        endpoint_add_ref(ep);
     311
     312        fibril_mutex_lock(&ep->guard);
     313        endpoint_activate_locked(ep, batch);
    308314        ohci_transfer_batch_commit(ohci_batch);
     315        fibril_mutex_unlock(&ep->guard);
    309316
    310317        /* Control and bulk schedules need a kick to start working */
     
    320327                break;
    321328        }
     329
     330        fibril_mutex_lock(&hc->guard);
     331        list_append(&ohci_ep->pending_link, &hc->pending_endpoints);
    322332        fibril_mutex_unlock(&hc->guard);
     333
    323334        return EOK;
    324335}
     
    353364                    OHCI_RD(hc->registers->periodic_current));
    354365
    355                 link_t *current = list_first(&hc->pending_batches);
    356                 while (current && current != &hc->pending_batches.head) {
    357                         link_t *next = current->next;
    358                         ohci_transfer_batch_t *batch =
    359                             ohci_transfer_batch_from_link(current);
     366                list_foreach_safe(hc->pending_endpoints, current, next) {
     367                        ohci_endpoint_t *ep
     368                                = list_get_instance(current, ohci_endpoint_t, pending_link);
     369
     370                        fibril_mutex_lock(&ep->base.guard);
     371                        ohci_transfer_batch_t *batch
     372                                = ohci_transfer_batch_get(ep->base.active_batch);
     373                        assert(batch);
    360374
    361375                        if (ohci_transfer_batch_check_completed(batch)) {
     376                                endpoint_deactivate_locked(&ep->base);
    362377                                list_remove(current);
     378                                endpoint_del_ref(&ep->base);
    363379                                usb_transfer_batch_finish(&batch->base);
    364380                        }
    365 
    366                         current = next;
     381                        fibril_mutex_unlock(&ep->base.guard);
    367382                }
    368383                fibril_mutex_unlock(&hc->guard);
  • uspace/drv/bus/usb/ohci/hc.h

    red8575f rd60115a  
    7070        endpoint_list_t lists[4];
    7171
    72         /** List of active transfers */
    73         list_t pending_batches;
     72        /** List of active endpoints */
     73        list_t pending_endpoints;
    7474
    7575        /** Guards schedule and endpoint manipulation */
  • uspace/drv/bus/usb/ohci/main.c

    red8575f rd60115a  
    3939#include <errno.h>
    4040#include <io/log.h>
     41#include <io/logctl.h>
    4142#include <str_error.h>
    4243
     
    7273{
    7374        log_init(NAME);
     75        logctl_set_log_level(NAME, LVL_DEBUG2);
    7476        return hc_driver_main(&ohci_driver);
    7577}
  • uspace/drv/bus/usb/ohci/ohci_batch.c

    red8575f rd60115a  
    8888
    8989        usb_transfer_batch_init(&ohci_batch->base, ep);
    90         link_initialize(&ohci_batch->link);
    9190
    9291        return ohci_batch;
  • uspace/drv/bus/usb/ohci/ohci_batch.h

    red8575f rd60115a  
    4747        usb_transfer_batch_t base;
    4848
    49         /** Link */
    50         link_t link;
    5149        /** Endpoint descriptor of the target endpoint. */
    5250        ed_t *ed;
     
    6563void ohci_transfer_batch_destroy(ohci_transfer_batch_t *ohci_batch);
    6664
    67 static inline ohci_transfer_batch_t *ohci_transfer_batch_from_link(link_t *l)
    68 {
    69         assert(l);
    70         return list_get_instance(l, ohci_transfer_batch_t, link);
    71 }
    72 
    7365static inline ohci_transfer_batch_t * ohci_transfer_batch_get(usb_transfer_batch_t *usb_batch)
    7466{
  • uspace/drv/bus/usb/ohci/ohci_bus.c

    red8575f rd60115a  
    8282        }
    8383
    84         link_initialize(&ohci_ep->link);
     84        link_initialize(&ohci_ep->eplist_link);
     85        link_initialize(&ohci_ep->pending_link);
    8586        return &ohci_ep->base;
    8687}
     
    120121static void ohci_unregister_ep(endpoint_t *ep)
    121122{
    122         ohci_bus_t *bus = (ohci_bus_t *) endpoint_get_bus(ep);
     123        ohci_bus_t * const bus = (ohci_bus_t *) endpoint_get_bus(ep);
     124        hc_t * const hc = bus->hc;
    123125        assert(ep);
    124126
    125127        usb2_bus_ops.endpoint_unregister(ep);
    126128        hc_dequeue_endpoint(bus->hc, ep);
     129
     130        ohci_endpoint_t * const ohci_ep = ohci_endpoint_get(ep);
     131
     132        /*
     133         * Now we can be sure the active transfer will not be completed. But first,
     134         * make sure that the handling fibril won't use its link in pending list.
     135         */
     136        fibril_mutex_lock(&hc->guard);
     137        if (link_in_use(&ohci_ep->pending_link))
     138                /* pending list reference */
     139                endpoint_del_ref(ep);
     140        list_remove(&ohci_ep->pending_link);
     141        fibril_mutex_unlock(&hc->guard);
     142
     143        /*
     144         * Finally, the endpoint shall not be used anywhere else. Finish the
     145         * pending batch.
     146         */
     147        fibril_mutex_lock(&ep->guard);
     148        usb_transfer_batch_t * const batch = ep->active_batch;
     149        endpoint_deactivate_locked(ep);
     150        fibril_mutex_unlock(&ep->guard);
     151
     152        if (batch) {
     153                batch->error = EINTR;
     154                batch->transfered_size = 0;
     155                usb_transfer_batch_finish(batch);
     156        }
    127157}
    128158
  • uspace/drv/bus/usb/ohci/ohci_bus.h

    red8575f rd60115a  
    5151        /** Currently enqueued transfer descriptor */
    5252        td_t *td;
    53         /** Linked list used by driver software */
    54         link_t link;
     53        /** Link in endpoint_list*/
     54        link_t eplist_link;
     55        /** Link in pending_endpoints */
     56        link_t pending_link;
    5557} ohci_endpoint_t;
    5658
Note: See TracChangeset for help on using the changeset viewer.