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

Changeset 929599a8 in mainline


Ignore:
Timestamp:
2018-01-11T13:30:37Z (4 years ago)
Author:
Ondřej Hlavatý <aearsis@…>
Branches:
lfn, master
Children:
4ed803f1
Parents:
351113f
git-author:
Ondřej Hlavatý <aearsis@…> (2018-01-11 13:30:31)
git-committer:
Ondřej Hlavatý <aearsis@…> (2018-01-11 13:30:37)
Message:

uhci: implemented transfer abort

Location:
uspace/drv/bus/usb/uhci
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • uspace/drv/bus/usb/uhci/hc.c

    r351113f r929599a8  
    5353
    5454#include "uhci_batch.h"
     55#include "transfer_list.h"
    5556#include "hc.h"
    5657
     
    323324static void endpoint_unregister(endpoint_t *ep)
    324325{
     326        hc_t * const hc = bus_to_hc(endpoint_get_bus(ep));
    325327        usb2_bus_ops.endpoint_unregister(ep);
     328
     329        uhci_transfer_batch_t *batch = NULL;
    326330
    327331        fibril_mutex_lock(&ep->guard);
    328332        if (ep->active_batch) {
    329                 uhci_transfer_batch_t *ub = uhci_transfer_batch_get(ep->active_batch);
    330                 uhci_transfer_batch_abort(ub);
    331 
    332                 assert(ep->active_batch == NULL);
     333                batch = uhci_transfer_batch_get(ep->active_batch);
     334
     335                transfer_list_t *list = hc->transfers[ep->device->speed][ep->transfer_type];
     336                assert(list);
     337
     338                fibril_mutex_lock(&list->guard);
     339                transfer_list_remove_batch(list, batch);
     340                fibril_mutex_unlock(&list->guard);
     341
     342                endpoint_wait_timeout_locked(ep, 2000);
     343
     344                batch = uhci_transfer_batch_get(ep->active_batch);
     345                if (ep->active_batch) {
     346                        endpoint_deactivate_locked(ep);
     347                }
    333348        }
    334349        fibril_mutex_unlock(&ep->guard);
     350
     351        if (batch) {
     352                batch->base.error = EINTR;
     353                batch->base.transfered_size = 0;
     354                usb_transfer_batch_finish(&batch->base);
     355        }
    335356}
    336357
     
    486507static int hc_schedule(usb_transfer_batch_t *batch)
    487508{
    488         assert(batch);
    489         hc_t *instance = bus_to_hc(endpoint_get_bus(batch->ep));
    490 
    491         if (batch->target.address == uhci_rh_get_address(&instance->rh))
    492                 return uhci_rh_schedule(&instance->rh, batch);
    493 
    494         uhci_transfer_batch_t *uhci_batch = (uhci_transfer_batch_t *) batch;
    495         if (!uhci_batch) {
    496                 usb_log_error("Failed to create UHCI transfer structures.\n");
    497                 return ENOMEM;
    498         }
     509        uhci_transfer_batch_t *uhci_batch = uhci_transfer_batch_get(batch);
     510        endpoint_t *ep = batch->ep;
     511        hc_t *hc = bus_to_hc(endpoint_get_bus(ep));
     512
     513        if (batch->target.address == uhci_rh_get_address(&hc->rh))
     514                return uhci_rh_schedule(&hc->rh, batch);
     515
    499516
    500517        const int err = uhci_transfer_batch_prepare(uhci_batch);
     
    502519                return err;
    503520
    504         transfer_list_t *list =
    505             instance->transfers[batch->ep->device->speed][batch->ep->transfer_type];
     521        transfer_list_t *list = hc->transfers[ep->device->speed][ep->transfer_type];
    506522        assert(list);
    507523        transfer_list_add_batch(list, uhci_batch);
     524
     525        return EOK;
     526}
     527
     528int hc_unschedule_batch(usb_transfer_batch_t *batch)
     529{
    508530
    509531        return EOK;
  • uspace/drv/bus/usb/uhci/hc.h

    r351113f r929599a8  
    139139}
    140140
     141int hc_unschedule_batch(usb_transfer_batch_t *);
     142
    141143extern int hc_add(hc_device_t *, const hw_res_list_parsed_t *);
    142144extern int hc_gen_irq_code(irq_code_t *, hc_device_t *, const hw_res_list_parsed_t *);
  • uspace/drv/bus/usb/uhci/transfer_list.c

    r351113f r929599a8  
    4545#include "transfer_list.h"
    4646
    47 static void transfer_list_remove_batch(
    48     transfer_list_t *instance, uhci_transfer_batch_t *uhci_batch);
    49 
    5047/** Initialize transfer list structures.
    5148 *
  • uspace/drv/bus/usb/uhci/transfer_list.h

    r351113f r929599a8  
    5656} transfer_list_t;
    5757
    58 void transfer_list_fini(transfer_list_t *instance);
    59 int transfer_list_init(transfer_list_t *instance, const char *name);
    60 void transfer_list_set_next(transfer_list_t *instance, transfer_list_t *next);
    61 void transfer_list_add_batch(
    62     transfer_list_t *instance, uhci_transfer_batch_t *batch);
    63 void transfer_list_remove_finished(transfer_list_t *instance, list_t *done);
    64 void transfer_list_abort_all(transfer_list_t *instance);
     58void transfer_list_fini(transfer_list_t *);
     59int transfer_list_init(transfer_list_t *, const char *);
     60void transfer_list_set_next(transfer_list_t *, transfer_list_t *);
     61void transfer_list_add_batch(transfer_list_t *, uhci_transfer_batch_t *);
     62void transfer_list_remove_batch(transfer_list_t *, uhci_transfer_batch_t *);
     63void transfer_list_remove_finished(transfer_list_t *, list_t *);
     64void transfer_list_abort_all(transfer_list_t *);
    6565
    6666#endif
  • uspace/drv/bus/usb/uhci/uhci_batch.c

    r351113f r929599a8  
    6464}
    6565
    66 /**
    67  * Abort a transfer that is currently running.
    68  * Call with endpoint guard locked.
    69  */
    70 void uhci_transfer_batch_abort(uhci_transfer_batch_t *batch)
    71 {
    72         assert(batch);
    73 
    74         endpoint_t *ep = batch->base.ep;
    75         assert(ep);
    76         assert(fibril_mutex_is_locked(&ep->guard));
    77         assert(ep->active_batch == &batch->base);
    78 
    79         /*
    80          * TODO: Do some magic here to remove the batch from schedule.
    81          */
    82 
    83         /*
    84          * Wait for 2 frames. If the transfer was being processed,
    85          * it shall be marked as finished already after 1ms.
    86          */
    87         endpoint_wait_timeout_locked(ep, 2000);
    88         if (ep->active_batch != &batch->base)
    89                 return;
    90 
    91         /*
    92          * Now, we can be sure the transfer is not scheduled,
    93          * and as such will not be completed. We now own the batch.
    94          */
    95         endpoint_deactivate_locked(ep);
    96 
    97         /* Leave the critical section for finishing the batch. */
    98         fibril_mutex_unlock(&ep->guard);
    99 
    100         batch->base.error = EINTR;
    101         batch->base.transfered_size = 0;
    102         usb_transfer_batch_finish(&batch->base);
    103 
    104         fibril_mutex_lock(&ep->guard);
    105 }
    106 
    10766/** Allocate memory and initialize internal data structure.
    10867 *
  • uspace/drv/bus/usb/uhci/uhci_batch.h

    r351113f r929599a8  
    7070int uhci_transfer_batch_prepare(uhci_transfer_batch_t *);
    7171bool uhci_transfer_batch_check_completed(uhci_transfer_batch_t *);
    72 void uhci_transfer_batch_abort(uhci_transfer_batch_t *);
    7372void uhci_transfer_batch_destroy(uhci_transfer_batch_t *);
    7473
Note: See TracChangeset for help on using the changeset viewer.