Changeset 8ad2b0a 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:
94f8c363
Parents:
d60115a
git-author:
Ondřej Hlavatý <aearsis@…> (2018-01-17 17:54:41)
git-committer:
Ondřej Hlavatý <aearsis@…> (2018-01-17 17:55:35)
Message:

ehci: implement transfer abort on endpoint unregister

Location:
uspace/drv/bus/usb
Files:
9 edited

Legend:

Unmodified
Added
Removed
  • uspace/drv/bus/usb/ehci/ehci_batch.c

    rd60115a r8ad2b0a  
    8484
    8585        usb_transfer_batch_init(&ehci_batch->base, ep);
    86         link_initialize(&ehci_batch->link);
    8786
    8887        return ehci_batch;
  • uspace/drv/bus/usb/ehci/ehci_batch.h

    rd60115a r8ad2b0a  
    4949        /** Number of TDs used by the transfer */
    5050        size_t td_count;
    51         /** Link */
    52         link_t link;
    5351        /** Endpoint descriptor of the target endpoint. */
    5452        qh_t *qh;
     
    7068void ehci_transfer_batch_destroy(ehci_transfer_batch_t *batch);
    7169
    72 static inline ehci_transfer_batch_t *ehci_transfer_batch_from_link(link_t *l)
    73 {
    74         assert(l);
    75         return list_get_instance(l, ehci_transfer_batch_t, link);
    76 }
    77 
    7870static inline ehci_transfer_batch_t * ehci_transfer_batch_get(usb_transfer_batch_t *usb_batch)
    7971{
  • uspace/drv/bus/usb/ehci/ehci_bus.c

    rd60115a r8ad2b0a  
    7777        ehci_ep->qh = ehci_ep->dma_buffer.virt;
    7878
    79         link_initialize(&ehci_ep->link);
     79        link_initialize(&ehci_ep->eplist_link);
     80        link_initialize(&ehci_ep->pending_link);
    8081        return &ehci_ep->base;
    8182}
     
    116117        bus_t *bus_base = endpoint_get_bus(ep);
    117118        ehci_bus_t *bus = (ehci_bus_t *) bus_base;
     119        hc_t *hc = bus->hc;
    118120        assert(bus);
    119121        assert(ep);
    120122
    121123        usb2_bus_ops.endpoint_unregister(ep);
    122         hc_dequeue_endpoint(bus->hc, ep);
     124        hc_dequeue_endpoint(hc, ep);
     125
     126        ehci_endpoint_t *ehci_ep = ehci_endpoint_get(ep);
     127
     128        /*
     129         * Now we can be sure the active transfer will not be completed. But first,
     130         * make sure that the handling fibril won't use its link in pending list.
     131         */
     132        fibril_mutex_lock(&hc->guard);
     133        if (link_in_use(&ehci_ep->pending_link))
     134                /* pending list reference */
     135                endpoint_del_ref(ep);
     136        list_remove(&ehci_ep->pending_link);
     137        fibril_mutex_unlock(&hc->guard);
     138
     139        /*
     140         * Finally, the endpoint shall not be used anywhere else. Finish the
     141         * pending batch.
     142         */
     143        fibril_mutex_lock(&ep->guard);
     144        usb_transfer_batch_t * const batch = ep->active_batch;
     145        endpoint_deactivate_locked(ep);
     146        fibril_mutex_unlock(&ep->guard);
     147
     148        if (batch) {
     149                batch->error = EINTR;
     150                batch->transfered_size = 0;
     151                usb_transfer_batch_finish(batch);
     152        }
    123153}
    124154
  • uspace/drv/bus/usb/ehci/ehci_bus.h

    rd60115a r8ad2b0a  
    5353       
    5454        dma_buffer_t dma_buffer;
    55         /** Linked list used by driver software */
    56         link_t link;
     55
     56        /** Link in endpoint_list */
     57        link_t eplist_link;
     58
     59        /** Link in pending_endpoints */
     60        link_t pending_link;
    5761} ehci_endpoint_t;
    5862
     
    8084static inline ehci_endpoint_t * ehci_endpoint_list_instance(link_t *l)
    8185{
    82         return list_get_instance(l, ehci_endpoint_t, link);
     86        return list_get_instance(l, ehci_endpoint_t, eplist_link);
    8387}
    8488
  • uspace/drv/bus/usb/ehci/endpoint_list.c

    rd60115a r8ad2b0a  
    124124        write_barrier();
    125125        /* Add to the sw list */
    126         list_append(&ep->link, &instance->endpoint_list);
     126        list_append(&ep->eplist_link, &instance->endpoint_list);
    127127
    128128        ehci_endpoint_t *first = ehci_endpoint_list_instance(
     
    159159        qh_t *prev_qh;
    160160        /* Remove from the hardware queue */
    161         if (list_first(&instance->endpoint_list) == &ep->link) {
     161        if (list_first(&instance->endpoint_list) == &ep->eplist_link) {
    162162                /* I'm the first one here */
    163163                prev_qh = instance->list_head;
    164164                qpos = "FIRST";
    165165        } else {
    166                 prev_qh = ehci_endpoint_list_instance(ep->link.prev)->qh;
     166                prev_qh = ehci_endpoint_list_instance(ep->eplist_link.prev)->qh;
    167167                qpos = "NOT FIRST";
    168168        }
     
    176176
    177177        /* Remove from the endpoint list */
    178         list_remove(&ep->link);
     178        list_remove(&ep->eplist_link);
    179179        fibril_mutex_unlock(&instance->guard);
    180180}
  • uspace/drv/bus/usb/ehci/hc.c

    rd60115a r8ad2b0a  
    173173            + EHCI_RD8(instance->caps->caplength));
    174174
    175         list_initialize(&instance->pending_batches);
     175        list_initialize(&instance->pending_endpoints);
    176176        fibril_mutex_initialize(&instance->guard);
    177177        fibril_condvar_initialize(&instance->async_doorbell);
     
    299299        }
    300300
     301        endpoint_t * const ep = batch->ep;
     302        ehci_endpoint_t * const ehci_ep = ehci_endpoint_get(ep);
     303
     304        /* creating local reference */
     305        endpoint_add_ref(ep);
     306
     307        fibril_mutex_lock(&ep->guard);
     308        endpoint_activate_locked(ep, batch);
     309
    301310        ehci_transfer_batch_t *ehci_batch = ehci_transfer_batch_get(batch);
    302 
    303311        const int err = ehci_transfer_batch_prepare(ehci_batch);
    304         if (err)
     312        if (err) {
     313                endpoint_deactivate_locked(ep);
     314                fibril_mutex_unlock(&ep->guard);
     315                /* dropping local reference */
     316                endpoint_del_ref(ep);
    305317                return err;
    306 
     318        }
     319
     320        usb_log_debug("HC(%p): Committing BATCH(%p)", hc, batch);
     321        ehci_transfer_batch_commit(ehci_batch);
     322        fibril_mutex_unlock(&ep->guard);
     323
     324        /* Enqueue endpoint to the checked list */
    307325        fibril_mutex_lock(&hc->guard);
    308326        usb_log_debug2("HC(%p): Appending BATCH(%p)", hc, batch);
    309         list_append(&ehci_batch->link, &hc->pending_batches);
    310         usb_log_debug("HC(%p): Committing BATCH(%p)", hc, batch);
    311         ehci_transfer_batch_commit(ehci_batch);
    312 
     327
     328        /* local reference -> pending list reference */
     329        list_append(&ehci_ep->pending_link, &hc->pending_endpoints);
    313330        fibril_mutex_unlock(&hc->guard);
     331
    314332        return EOK;
    315333}
     
    341359
    342360        if (status & (USB_STS_IRQ_FLAG | USB_STS_ERR_IRQ_FLAG)) {
     361
     362                LIST_INITIALIZE(completed);
     363
    343364                fibril_mutex_lock(&hc->guard);
    344365
    345                 usb_log_debug2("HC(%p): Scanning %lu pending batches", hc,
    346                         list_count(&hc->pending_batches));
    347                 list_foreach_safe(hc->pending_batches, current, next) {
    348                         ehci_transfer_batch_t *batch =
    349                             ehci_transfer_batch_from_link(current);
     366                usb_log_debug2("HC(%p): Scanning %lu pending endpoints", hc,
     367                        list_count(&hc->pending_endpoints));
     368                list_foreach_safe(hc->pending_endpoints, current, next) {
     369                        ehci_endpoint_t *ep
     370                                = list_get_instance(current, ehci_endpoint_t, pending_link);
     371
     372                        fibril_mutex_lock(&ep->base.guard);
     373                        ehci_transfer_batch_t *batch
     374                                = ehci_transfer_batch_get(ep->base.active_batch);
     375                        assert(batch);
    350376
    351377                        if (ehci_transfer_batch_check_completed(batch)) {
     378                                endpoint_deactivate_locked(&ep->base);
    352379                                list_remove(current);
     380                                endpoint_del_ref(&ep->base);
    353381                                usb_transfer_batch_finish(&batch->base);
    354382                        }
     383                        fibril_mutex_unlock(&ep->base.guard);
    355384                }
    356385                fibril_mutex_unlock(&hc->guard);
     386
     387
    357388        }
    358389
  • uspace/drv/bus/usb/ehci/hc.h

    rd60115a r8ad2b0a  
    7575
    7676        /** List of active transfers */
    77         list_t pending_batches;
     77        list_t pending_endpoints;
    7878
    7979        /** Guards schedule and endpoint manipulation */
  • uspace/drv/bus/usb/ehci/main.c

    rd60115a r8ad2b0a  
    6767{
    6868        log_init(NAME);
    69         logctl_set_log_level(NAME, LVL_NOTE);
     69        logctl_set_log_level(NAME, LVL_DEBUG2);
    7070        return hc_driver_main(&ehci_driver);
    7171}
  • uspace/drv/bus/usb/uhci/main.c

    rd60115a r8ad2b0a  
    9292        printf(NAME ": HelenOS UHCI driver.\n");
    9393        log_init(NAME);
    94         logctl_set_log_level(NAME, LVL_DEBUG2);
     94        logctl_set_log_level(NAME, LVL_NOTE);
    9595        return hc_driver_main(&uhci_driver);
    9696}
Note: See TracChangeset for help on using the changeset viewer.