Changeset 73a5857 in mainline


Ignore:
Timestamp:
2018-01-31T23:31:05Z (6 years ago)
Author:
Ondřej Hlavatý <aearsis@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
53fdf8c
Parents:
2ca5a198
Message:

usbhost: add joinable_fibril utility

Location:
uspace
Files:
6 edited

Legend:

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

    r2ca5a198 r73a5857  
    277277                goto err_cmd;
    278278
    279         fid_t fid = fibril_create(&event_worker, hc);
    280         if (!fid)
     279        hc->event_worker = joinable_fibril_create(&event_worker, hc);
     280        if (!hc->event_worker)
    281281                goto err_bus;
    282282
    283         // TODO: completion_reset
    284         hc->event_fibril_completion.active = true;
    285         fibril_mutex_initialize(&hc->event_fibril_completion.guard);
    286         fibril_condvar_initialize(&hc->event_fibril_completion.cv);
    287 
    288283        xhci_sw_ring_init(&hc->sw_ring, PAGE_SIZE / sizeof(xhci_trb_t));
    289284
    290         fibril_add_ready(fid);
     285        joinable_fibril_start(hc->event_worker);
    291286
    292287        return EOK;
     
    598593        }
    599594
    600         // TODO: completion_complete
    601         fibril_mutex_lock(&hc->event_fibril_completion.guard);
    602         hc->event_fibril_completion.active = false;
    603         fibril_condvar_broadcast(&hc->event_fibril_completion.cv);
    604         fibril_mutex_unlock(&hc->event_fibril_completion.guard);
    605 
    606         return EOK;
     595        return 0;
    607596}
    608597
     
    688677{
    689678        xhci_sw_ring_stop(&hc->sw_ring);
    690 
    691         // TODO: completion_wait
    692         fibril_mutex_lock(&hc->event_fibril_completion.guard);
    693         while (hc->event_fibril_completion.active)
    694                 fibril_condvar_wait(&hc->event_fibril_completion.cv,
    695                     &hc->event_fibril_completion.guard);
    696         fibril_mutex_unlock(&hc->event_fibril_completion.guard);
     679        joinable_fibril_join(hc->event_worker);
    697680        xhci_sw_ring_fini(&hc->sw_ring);
    698681
  • uspace/drv/bus/usb/xhci/hc.h

    r2ca5a198 r73a5857  
    3939#include <fibril_synch.h>
    4040#include <usb/host/usb_transfer_batch.h>
     41#include <usb/host/utility.h>
    4142#include "hw_struct/regs.h"
    4243#include "hw_struct/context.h"
     
    7879        xhci_sw_ring_t sw_ring;
    7980
    80         struct {
    81                 fibril_mutex_t guard;
    82                 fibril_condvar_t cv;
    83                 bool active;
    84         } event_fibril_completion;
     81        /** Event handling fibril */
     82        joinable_fibril_t *event_worker;
    8583
    8684        /* Root hub emulation */
  • uspace/drv/bus/usb/xhci/rh.c

    r2ca5a198 r73a5857  
    9696        }
    9797
    98         fid_t fid = fibril_create(&rh_worker, rh);
    99         if (!fid) {
     98        rh->event_worker = joinable_fibril_create(&rh_worker, rh);
     99        if (!rh->event_worker) {
    100100                free(rh->ports);
    101101                return err;
     
    113113        xhci_sw_ring_init(&rh->event_ring, rh->max_ports);
    114114
    115         hc->event_fibril_completion.active = true;
    116         fibril_mutex_initialize(&hc->event_fibril_completion.guard);
    117         fibril_condvar_initialize(&hc->event_fibril_completion.cv);
    118 
    119         fibril_add_ready(fid);
     115        joinable_fibril_start(rh->event_worker);
    120116
    121117        return EOK;
     
    132128
    133129        xhci_sw_ring_stop(&rh->event_ring);
    134 
    135         // TODO: completion_wait
    136         fibril_mutex_lock(&rh->event_fibril_completion.guard);
    137         while (rh->event_fibril_completion.active)
    138                 fibril_condvar_wait(&rh->event_fibril_completion.cv,
    139                     &rh->event_fibril_completion.guard);
    140         fibril_mutex_unlock(&rh->event_fibril_completion.guard);
     130        joinable_fibril_join(rh->event_worker);
    141131        xhci_sw_ring_fini(&rh->event_ring);
    142132        return EOK;
     
    332322        }
    333323
    334         // TODO: completion_complete
    335         fibril_mutex_lock(&rh->event_fibril_completion.guard);
    336         rh->event_fibril_completion.active = false;
    337         fibril_condvar_broadcast(&rh->event_fibril_completion.cv);
    338         fibril_mutex_unlock(&rh->event_fibril_completion.guard);
    339 
    340         return EOK;
     324        return 0;
    341325}
    342326
  • uspace/drv/bus/usb/xhci/rh.h

    r2ca5a198 r73a5857  
    3737#define XHCI_RH_H
    3838
     39#include <usb/host/bus.h>
    3940#include <usb/host/usb_transfer_batch.h>
    40 #include <usb/host/bus.h>
     41#include <usb/host/utility.h>
    4142
    4243#include "hw_struct/regs.h"
     
    7778        xhci_sw_ring_t event_ring;
    7879
    79         struct {
    80                 fibril_mutex_t guard;
    81                 fibril_condvar_t cv;
    82                 bool active;
    83         } event_fibril_completion;
     80        joinable_fibril_t *event_worker;
    8481} xhci_rh_t;
    8582
  • uspace/lib/usbhost/include/usb/host/utility.h

    r2ca5a198 r73a5857  
    5454int hc_device_explore(device_t *);
    5555
     56/** Joinable fibril */
     57
     58typedef int (*fibril_worker_t)(void *);
     59typedef struct joinable_fibril joinable_fibril_t;
     60
     61joinable_fibril_t *joinable_fibril_create(fibril_worker_t, void *);
     62void joinable_fibril_start(joinable_fibril_t *);
     63void joinable_fibril_join(joinable_fibril_t *);
     64void joinable_fibril_destroy(joinable_fibril_t *);
     65
     66
    5667#endif
    5768/**
  • uspace/lib/usbhost/src/utility.c

    r2ca5a198 r73a5857  
    284284}
    285285
     286typedef struct joinable_fibril {
     287        fid_t fid;
     288        void *arg;
     289        fibril_worker_t worker;
     290
     291        bool running;
     292        fibril_mutex_t guard;
     293        fibril_condvar_t dead_cv;
     294} joinable_fibril_t;
     295
     296static int joinable_fibril_worker(void *arg)
     297{
     298        joinable_fibril_t *jf = arg;
     299        jf->worker(jf->arg);
     300
     301        fibril_mutex_lock(&jf->guard);
     302        jf->running = false;
     303        fibril_mutex_unlock(&jf->guard);
     304        fibril_condvar_broadcast(&jf->dead_cv);
     305        return 0;
     306}
     307
     308/**
     309 * Create a fibril that is joinable. Similar to fibril_create.
     310 */
     311joinable_fibril_t *joinable_fibril_create(fibril_worker_t worker, void *arg)
     312{
     313        joinable_fibril_t *jf = calloc(1, sizeof(joinable_fibril_t));
     314        if (!jf)
     315                return NULL;
     316
     317        jf->fid = fibril_create(joinable_fibril_worker, jf);
     318        if (!jf->fid) {
     319                free(jf);
     320                return NULL;
     321        }
     322
     323        jf->worker = worker;
     324        jf->arg = arg;
     325        fibril_mutex_initialize(&jf->guard);
     326        fibril_condvar_initialize(&jf->dead_cv);
     327
     328        return jf;
     329}
     330
     331
     332/**
     333 * Start a joinable fibril. Similar to fibril_add_ready.
     334 */
     335void joinable_fibril_start(joinable_fibril_t *jf)
     336{
     337        assert(jf);
     338        assert(!jf->running);
     339
     340        jf->running = true;
     341        fibril_add_ready(jf->fid);
     342}
     343
     344/**
     345 * Join a joinable fibril. Not similar to anything, obviously.
     346 */
     347void joinable_fibril_join(joinable_fibril_t *jf)
     348{
     349        assert(jf);
     350
     351        fibril_mutex_lock(&jf->guard);
     352        while (jf->running)
     353                fibril_condvar_wait(&jf->dead_cv, &jf->guard);
     354        fibril_mutex_unlock(&jf->guard);
     355}
     356
     357/**
     358 * Regular fibrils clean after themselves, joinable fibrils cannot.
     359 */
     360void joinable_fibril_destroy(joinable_fibril_t *jf)
     361{
     362        if (jf) {
     363                joinable_fibril_join(jf);
     364                free(jf);
     365        }
     366}
     367
    286368/**
    287369 * @}
Note: See TracChangeset for help on using the changeset viewer.