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

Changeset 5a2c42b in mainline


Ignore:
Timestamp:
2011-04-13T12:37:20Z (11 years ago)
Author:
Jan Vesely <jano.vesely@…>
Branches:
lfn, master
Children:
592369ae
Parents:
2759c52
Message:

Use endpoint lists instead of transfer lists.

Create and enqueue static endpoint descriptor when endpoint is registered.

Location:
uspace/drv/ohci
Files:
3 edited
2 moved

Legend:

Unmodified
Added
Removed
  • uspace/drv/ohci/Makefile

    r2759c52 r5a2c42b  
    3434SOURCES = \
    3535        batch.c \
     36        endpoint_list.c \
    3637        hc.c \
    3738        hcd_endpoint.c \
     
    4142        pci.c \
    4243        root_hub.c \
    43         transfer_list.c \
    4444        hw_struct/endpoint_descriptor.c \
    4545        hw_struct/transfer_descriptor.c
  • uspace/drv/ohci/endpoint_list.c

    r2759c52 r5a2c42b  
    3535#include <usb/debug.h>
    3636
    37 #include "transfer_list.h"
    38 
    39 static void transfer_list_remove_batch(
    40     transfer_list_t *instance, usb_transfer_batch_t *batch);
    41 /*----------------------------------------------------------------------------*/
     37#include "endpoint_list.h"
     38
    4239/** Initialize transfer list structures.
    4340 *
     
    4845 * Allocates memory for internal qh_t structure.
    4946 */
    50 int transfer_list_init(transfer_list_t *instance, const char *name)
     47int endpoint_list_init(endpoint_list_t *instance, const char *name)
    5148{
    5249        assert(instance);
     
    6259
    6360        ed_init(instance->list_head, NULL);
    64         list_initialize(&instance->batch_list);
     61        list_initialize(&instance->endpoint_list);
    6562        fibril_mutex_initialize(&instance->guard);
    6663        return EOK;
     
    7572 * Does not check whether this replaces an existing list .
    7673 */
    77 void transfer_list_set_next(transfer_list_t *instance, transfer_list_t *next)
     74void endpoint_list_set_next(endpoint_list_t *instance, endpoint_list_t *next)
    7875{
    7976        assert(instance);
     
    8279}
    8380/*----------------------------------------------------------------------------*/
    84 /** Submit transfer batch to the list and queue.
    85  *
    86  * @param[in] instance List to use.
    87  * @param[in] batch Transfer batch to submit.
    88  * @return Error code
    89  *
    90  * The batch is added to the end of the list and queue.
    91  */
    92 void transfer_list_add_batch(
    93     transfer_list_t *instance, usb_transfer_batch_t *batch)
    94 {
    95         assert(instance);
    96         assert(batch);
    97         usb_log_debug2("Queue %s: Adding batch(%p).\n", instance->name, batch);
     81/** Submit transfer endpoint to the list and queue.
     82 *
     83 * @param[in] instance List to use.
     84 * @param[in] endpoint Transfer endpoint to submit.
     85 * @return Error code
     86 *
     87 * The endpoint is added to the end of the list and queue.
     88 */
     89void endpoint_list_add_ep(endpoint_list_t *instance, hcd_endpoint_t *hcd_ep)
     90{
     91        assert(instance);
     92        assert(hcd_ep);
     93        usb_log_debug2("Queue %s: Adding endpoint(%p).\n",
     94            instance->name, hcd_ep);
    9895
    9996        fibril_mutex_lock(&instance->guard);
     
    10198        ed_t *last_ed = NULL;
    10299        /* Add to the hardware queue. */
    103         if (list_empty(&instance->batch_list)) {
     100        if (list_empty(&instance->endpoint_list)) {
    104101                /* There is nothing scheduled */
    105102                last_ed = instance->list_head;
    106103        } else {
    107104                /* There is something scheduled */
    108                 usb_transfer_batch_t *last = list_get_instance(
    109                     instance->batch_list.prev, usb_transfer_batch_t, link);
    110                 last_ed = batch_ed(last);
     105                hcd_endpoint_t *last = list_get_instance(
     106                    instance->endpoint_list.prev, hcd_endpoint_t, link);
     107                last_ed = last->ed;
    111108        }
    112109        /* keep link */
    113         batch_ed(batch)->next = last_ed->next;
    114         ed_append_ed(last_ed, batch_ed(batch));
     110        hcd_ep->ed->next = last_ed->next;
     111        ed_append_ed(last_ed, hcd_ep->ed);
    115112
    116113        asm volatile ("": : :"memory");
    117114
    118115        /* Add to the driver list */
    119         list_append(&batch->link, &instance->batch_list);
    120 
    121         usb_transfer_batch_t *first = list_get_instance(
    122             instance->batch_list.next, usb_transfer_batch_t, link);
    123         usb_log_debug("Batch(%p) added to list %s, first is %p(%p).\n",
    124                 batch, instance->name, first, batch_ed(first));
     116        list_append(&hcd_ep->link, &instance->endpoint_list);
     117
     118        hcd_endpoint_t *first = list_get_instance(
     119            instance->endpoint_list.next, hcd_endpoint_t, link);
     120        usb_log_debug("HCD EP(%p) added to list %s, first is %p(%p).\n",
     121                hcd_ep, instance->name, first, first->ed);
    125122        if (last_ed == instance->list_head) {
    126123                usb_log_debug2("%s head ED(%p-%p): %x:%x:%x:%x.\n",
     
    132129}
    133130/*----------------------------------------------------------------------------*/
    134 /** Create list for finished batches.
     131#if 0
     132/** Create list for finished endpoints.
    135133 *
    136134 * @param[in] instance List to use.
    137135 * @param[in] done list to fill
    138136 */
    139 void transfer_list_remove_finished(transfer_list_t *instance, link_t *done)
     137void endpoint_list_remove_finished(endpoint_list_t *instance, link_t *done)
    140138{
    141139        assert(instance);
     
    143141
    144142        fibril_mutex_lock(&instance->guard);
    145         usb_log_debug2("Checking list %s for completed batches(%d).\n",
    146             instance->name, list_count(&instance->batch_list));
    147         link_t *current = instance->batch_list.next;
    148         while (current != &instance->batch_list) {
     143        usb_log_debug2("Checking list %s for completed endpointes(%d).\n",
     144            instance->name, list_count(&instance->endpoint_list));
     145        link_t *current = instance->endpoint_list.next;
     146        while (current != &instance->endpoint_list) {
    149147                link_t *next = current->next;
    150                 usb_transfer_batch_t *batch =
    151                     list_get_instance(current, usb_transfer_batch_t, link);
    152 
    153                 if (batch_is_complete(batch)) {
     148                hcd_endpoint_t *endpoint =
     149                    list_get_instance(current, hcd_endpoint_t, link);
     150
     151                if (endpoint_is_complete(endpoint)) {
    154152                        /* Save for post-processing */
    155                         transfer_list_remove_batch(instance, batch);
     153                        endpoint_list_remove_endpoint(instance, endpoint);
    156154                        list_append(current, done);
    157155                }
     
    161159}
    162160/*----------------------------------------------------------------------------*/
    163 /** Walk the list and abort all batches.
    164  *
    165  * @param[in] instance List to use.
    166  */
    167 void transfer_list_abort_all(transfer_list_t *instance)
     161/** Walk the list and abort all endpointes.
     162 *
     163 * @param[in] instance List to use.
     164 */
     165void endpoint_list_abort_all(endpoint_list_t *instance)
    168166{
    169167        fibril_mutex_lock(&instance->guard);
    170         while (!list_empty(&instance->batch_list)) {
    171                 link_t *current = instance->batch_list.next;
    172                 usb_transfer_batch_t *batch =
    173                     list_get_instance(current, usb_transfer_batch_t, link);
    174                 transfer_list_remove_batch(instance, batch);
    175                 usb_transfer_batch_finish_error(batch, EIO);
     168        while (!list_empty(&instance->endpoint_list)) {
     169                link_t *current = instance->endpoint_list.next;
     170                hcd_endpoint_t *endpoint =
     171                    list_get_instance(current, hcd_endpoint_t, link);
     172                endpoint_list_remove_endpoint(instance, endpoint);
     173                hcd_endpoint_finish_error(endpoint, EIO);
    176174        }
    177175        fibril_mutex_unlock(&instance->guard);
    178176}
    179 /*----------------------------------------------------------------------------*/
    180 /** Remove a transfer batch from the list and queue.
    181  *
    182  * @param[in] instance List to use.
    183  * @param[in] batch Transfer batch to remove.
     177#endif
     178/*----------------------------------------------------------------------------*/
     179/** Remove a transfer endpoint from the list and queue.
     180 *
     181 * @param[in] instance List to use.
     182 * @param[in] endpoint Transfer endpoint to remove.
    184183 * @return Error code
    185184 *
    186185 * Does not lock the transfer list, caller is responsible for that.
    187186 */
    188 void transfer_list_remove_batch(
    189     transfer_list_t *instance, usb_transfer_batch_t *batch)
     187void endpoint_list_remove_ep(endpoint_list_t *instance, hcd_endpoint_t *hcd_ep)
    190188{
    191189        assert(instance);
    192190        assert(instance->list_head);
    193         assert(batch);
    194         assert(batch_ed(batch));
     191        assert(hcd_ep);
     192        assert(hcd_ep->ed);
    195193        assert(fibril_mutex_is_locked(&instance->guard));
    196194
    197195        usb_log_debug2(
    198             "Queue %s: removing batch(%p).\n", instance->name, batch);
     196            "Queue %s: removing endpoint(%p).\n", instance->name, hcd_ep);
    199197
    200198        const char *qpos = NULL;
     199        ed_t *prev_ed;
    201200        /* Remove from the hardware queue */
    202         if (instance->batch_list.next == &batch->link) {
     201        if (instance->endpoint_list.next == &hcd_ep->link) {
    203202                /* I'm the first one here */
    204                 assert((instance->list_head->next & ED_NEXT_PTR_MASK)
    205                     == addr_to_phys(batch_ed(batch)));
    206                 instance->list_head->next = batch_ed(batch)->next;
     203                prev_ed = instance->list_head;
    207204                qpos = "FIRST";
    208205        } else {
    209                 usb_transfer_batch_t *prev =
    210                     list_get_instance(
    211                         batch->link.prev, usb_transfer_batch_t, link);
    212                 assert((batch_ed(prev)->next & ED_NEXT_PTR_MASK)
    213                     == addr_to_phys(batch_ed(batch)));
    214                 batch_ed(prev)->next = batch_ed(batch)->next;
     206                hcd_endpoint_t *prev =
     207                    list_get_instance(hcd_ep->link.prev, hcd_endpoint_t, link);
     208                prev_ed = prev->ed;
    215209                qpos = "NOT FIRST";
    216210        }
     211        assert((prev_ed->next & ED_NEXT_PTR_MASK) == addr_to_phys(hcd_ep->ed));
     212        prev_ed->next = hcd_ep->ed->next;
     213
    217214        asm volatile ("": : :"memory");
    218         usb_log_debug("Batch(%p) removed (%s) from %s, next %x.\n",
    219             batch, qpos, instance->name, batch_ed(batch)->next);
    220 
    221         /* Remove from the batch list */
    222         list_remove(&batch->link);
     215        usb_log_debug("HCD EP(%p) removed (%s) from %s, next %x.\n",
     216            hcd_ep, qpos, instance->name, hcd_ep->ed->next);
     217
     218        /* Remove from the endpoint list */
     219        list_remove(&hcd_ep->link);
    223220}
    224221/**
  • uspace/drv/ohci/endpoint_list.h

    r2759c52 r5a2c42b  
    3232 * @brief OHCI driver transfer list structure
    3333 */
    34 #ifndef DRV_OHCI_TRANSFER_LIST_H
    35 #define DRV_OHCI_TRANSFER_LIST_H
     34#ifndef DRV_OHCI_ENDPOINT_LIST_H
     35#define DRV_OHCI_ENDPOINT_LIST_H
    3636
    3737#include <fibril_synch.h>
    3838
    39 #include "batch.h"
     39#include "hcd_endpoint.h"
    4040#include "hw_struct/endpoint_descriptor.h"
    4141#include "utils/malloc32.h"
    4242
    43 typedef struct transfer_list
     43typedef struct endpoint_list
    4444{
    4545        fibril_mutex_t guard;
     
    4747        uint32_t list_head_pa;
    4848        const char *name;
    49         link_t batch_list;
    50 } transfer_list_t;
     49        link_t endpoint_list;
     50} endpoint_list_t;
    5151
    5252/** Dispose transfer list structures.
     
    5656 * Frees memory for internal qh_t structure.
    5757 */
    58 static inline void transfer_list_fini(transfer_list_t *instance)
     58static inline void endpoint_list_fini(endpoint_list_t *instance)
    5959{
    6060        assert(instance);
     
    6262}
    6363
    64 int transfer_list_init(transfer_list_t *instance, const char *name);
     64int endpoint_list_init(endpoint_list_t *instance, const char *name);
    6565
    66 void transfer_list_set_next(transfer_list_t *instance, transfer_list_t *next);
     66void endpoint_list_set_next(endpoint_list_t *instance, endpoint_list_t *next);
    6767
    68 void transfer_list_add_batch(transfer_list_t *instance, usb_transfer_batch_t *batch);
     68void endpoint_list_add_ep(endpoint_list_t *instance, hcd_endpoint_t *hcd_ep);
    6969
    70 void transfer_list_remove_finished(transfer_list_t *instance, link_t *done);
     70void endpoint_list_remove_ep(endpoint_list_t *instance, hcd_endpoint_t *hcd_ep);
     71#if 0
     72void endpoint_list_remove_finished(endpoint_list_t *instance, link_t *done);
    7173
    72 void transfer_list_abort_all(transfer_list_t *instance);
     74void endpoint_list_abort_all(endpoint_list_t *instance);
     75#endif
    7376#endif
    7477/**
  • uspace/drv/ohci/hc.c

    r2759c52 r5a2c42b  
    155155                return ENOMEM;
    156156        }
    157         // TODO: enqueue hcd_ep here!
    158157
    159158        ret = usb_endpoint_manager_register_ep(&instance->ep_manager, ep, size);
    160159        if (ret != EOK) {
    161160                endpoint_destroy(ep);
    162         }
     161                return ret;
     162        }
     163
     164        /* Enqueue hcd_ep */
     165        switch (ep->transfer_type) {
     166        case USB_TRANSFER_CONTROL:
     167                instance->registers->control &= ~C_CLE;
     168                endpoint_list_add_ep(
     169                    &instance->lists[ep->transfer_type], hcd_ep);
     170                instance->registers->control_current = 0;
     171                instance->registers->control |= C_CLE;
     172                break;
     173        case USB_TRANSFER_BULK:
     174                instance->registers->control &= ~C_BLE;
     175                endpoint_list_add_ep(
     176                    &instance->lists[ep->transfer_type], hcd_ep);
     177                instance->registers->control |= C_BLE;
     178                break;
     179        case USB_TRANSFER_ISOCHRONOUS:
     180        case USB_TRANSFER_INTERRUPT:
     181                instance->registers->control &= (~C_PLE & ~C_IE);
     182                endpoint_list_add_ep(
     183                    &instance->lists[ep->transfer_type], hcd_ep);
     184                instance->registers->control |= C_PLE | C_IE;
     185                break;
     186        default:
     187                break;
     188        }
     189
    163190        return ret;
    164191}
     
    176203        hcd_endpoint_t *hcd_ep = hcd_endpoint_get(ep);
    177204        if (hcd_ep) {
    178                 // TODO: dequeue hcd_ep here!
     205                /* Dequeue hcd_ep */
     206                switch (ep->transfer_type) {
     207                case USB_TRANSFER_CONTROL:
     208                        instance->registers->control &= ~C_CLE;
     209                        endpoint_list_remove_ep(
     210                            &instance->lists[ep->transfer_type], hcd_ep);
     211                        instance->registers->control_current = 0;
     212                        instance->registers->control |= C_CLE;
     213                        break;
     214                case USB_TRANSFER_BULK:
     215                        instance->registers->control &= ~C_BLE;
     216                        endpoint_list_remove_ep(
     217                            &instance->lists[ep->transfer_type], hcd_ep);
     218                        instance->registers->control |= C_BLE;
     219                        break;
     220                case USB_TRANSFER_ISOCHRONOUS:
     221                case USB_TRANSFER_INTERRUPT:
     222                        instance->registers->control &= (~C_PLE & ~C_IE);
     223                        endpoint_list_remove_ep(
     224                            &instance->lists[ep->transfer_type], hcd_ep);
     225                        instance->registers->control |= C_PLE | C_IE;
     226                        break;
     227                default:
     228                        break;
     229                }
    179230                hcd_endpoint_clear(ep);
    180231        } else {
     
    195246                return rh_request(&instance->rh, batch);
    196247        }
    197 
     248#if 0
    198249        fibril_mutex_lock(&instance->guard);
    199250        switch (batch->ep->transfer_type) {
     
    230281        }
    231282        fibril_mutex_unlock(&instance->guard);
     283#endif
    232284        return EOK;
    233285}
     
    249301                usb_log_debug2("Periodic current: %p.\n",
    250302                    instance->registers->periodic_current);
     303#if 0
    251304                LIST_INITIALIZE(done);
    252305                transfer_list_remove_finished(
     
    267320                }
    268321                fibril_mutex_unlock(&instance->guard);
     322#endif
    269323        }
    270324}
     
    358412
    359413        /* Use queues */
    360         instance->registers->bulk_head = instance->transfers_bulk.list_head_pa;
     414        instance->registers->bulk_head =
     415            instance->lists[USB_TRANSFER_BULK].list_head_pa;
    361416        usb_log_debug2("Bulk HEAD set to: %p(%p).\n",
    362             instance->transfers_bulk.list_head,
    363             instance->transfers_bulk.list_head_pa);
     417            instance->lists[USB_TRANSFER_BULK].list_head,
     418            instance->lists[USB_TRANSFER_BULK].list_head_pa);
    364419
    365420        instance->registers->control_head =
    366             instance->transfers_control.list_head_pa;
     421            instance->lists[USB_TRANSFER_CONTROL].list_head_pa;
    367422        usb_log_debug2("Control HEAD set to: %p(%p).\n",
    368             instance->transfers_control.list_head,
    369             instance->transfers_control.list_head_pa);
     423            instance->lists[USB_TRANSFER_CONTROL].list_head,
     424            instance->lists[USB_TRANSFER_CONTROL].list_head_pa);
    370425
    371426        /* Enable queues */
     
    398453        assert(instance);
    399454
    400 #define SETUP_TRANSFER_LIST(type, name) \
     455#define SETUP_ENDPOINT_LIST(type) \
    401456do { \
    402         int ret = transfer_list_init(&instance->type, name); \
     457        const char *name = usb_str_transfer_type(type); \
     458        int ret = endpoint_list_init(&instance->lists[type], name); \
    403459        if (ret != EOK) { \
    404                 usb_log_error("Failed(%d) to setup %s transfer list.\n", \
     460                usb_log_error("Failed(%d) to setup %s endpoint list.\n", \
    405461                    ret, name); \
    406                 transfer_list_fini(&instance->transfers_isochronous); \
    407                 transfer_list_fini(&instance->transfers_interrupt); \
    408                 transfer_list_fini(&instance->transfers_control); \
    409                 transfer_list_fini(&instance->transfers_bulk); \
     462                endpoint_list_fini(&instance->lists[USB_TRANSFER_ISOCHRONOUS]); \
     463                endpoint_list_fini(&instance->lists[USB_TRANSFER_INTERRUPT]); \
     464                endpoint_list_fini(&instance->lists[USB_TRANSFER_CONTROL]); \
     465                endpoint_list_fini(&instance->lists[USB_TRANSFER_BULK]); \
    410466        } \
    411467} while (0)
    412468
    413         SETUP_TRANSFER_LIST(transfers_isochronous, "ISOCHRONOUS");
    414         SETUP_TRANSFER_LIST(transfers_interrupt, "INTERRUPT");
    415         SETUP_TRANSFER_LIST(transfers_control, "CONTROL");
    416         SETUP_TRANSFER_LIST(transfers_bulk, "BULK");
    417 #undef SETUP_TRANSFER_LIST
    418         transfer_list_set_next(&instance->transfers_interrupt,
    419             &instance->transfers_isochronous);
    420 
    421         /* Assign pointers to be used during scheduling */
    422         instance->transfers[USB_TRANSFER_INTERRUPT] =
    423           &instance->transfers_interrupt;
    424         instance->transfers[USB_TRANSFER_ISOCHRONOUS] =
    425           &instance->transfers_interrupt;
    426         instance->transfers[USB_TRANSFER_CONTROL] =
    427           &instance->transfers_control;
    428         instance->transfers[USB_TRANSFER_BULK] =
    429           &instance->transfers_bulk;
     469        SETUP_ENDPOINT_LIST(USB_TRANSFER_ISOCHRONOUS);
     470        SETUP_ENDPOINT_LIST(USB_TRANSFER_INTERRUPT);
     471        SETUP_ENDPOINT_LIST(USB_TRANSFER_CONTROL);
     472        SETUP_ENDPOINT_LIST(USB_TRANSFER_BULK);
     473#undef SETUP_ENDPOINT_LIST
     474        endpoint_list_set_next(&instance->lists[USB_TRANSFER_INTERRUPT],
     475            &instance->lists[USB_TRANSFER_ISOCHRONOUS]);
    430476
    431477        return EOK;
     
    448494        for (; i < 32; ++i) {
    449495                instance->hcca->int_ep[i] =
    450                     instance->transfers_interrupt.list_head_pa;
     496                    instance->lists[USB_TRANSFER_INTERRUPT].list_head_pa;
    451497        }
    452498        usb_log_debug2("Interrupt HEADs set to: %p(%p).\n",
    453             instance->transfers_interrupt.list_head,
    454             instance->transfers_interrupt.list_head_pa);
     499            instance->lists[USB_TRANSFER_INTERRUPT].list_head,
     500            instance->lists[USB_TRANSFER_INTERRUPT].list_head_pa);
    455501
    456502        return EOK;
  • uspace/drv/ohci/hc.h

    r2759c52 r5a2c42b  
    4848#include "ohci_regs.h"
    4949#include "root_hub.h"
    50 #include "transfer_list.h"
     50#include "endpoint_list.h"
    5151#include "hw_struct/hcca.h"
    5252
     
    5858        hcca_t *hcca;
    5959
    60         transfer_list_t transfers_isochronous;
    61         transfer_list_t transfers_interrupt;
    62         transfer_list_t transfers_control;
    63         transfer_list_t transfers_bulk;
    64 
    65         transfer_list_t *transfers[4];
     60        endpoint_list_t lists[4];
    6661
    6762        ddf_fun_t *ddf_instance;
Note: See TracChangeset for help on using the changeset viewer.