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

Changeset 6602e97 in mainline


Ignore:
Timestamp:
2014-01-25T07:06:48Z (8 years ago)
Author:
Jan Vesely <jano.vesely@…>
Branches:
lfn, master
Children:
a752c78c
Parents:
3f2cb17
Message:

ehci: Implement batch structure initialization

Location:
uspace/drv/bus/usb/ehci
Files:
1 added
4 edited

Legend:

Unmodified
Added
Removed
  • uspace/drv/bus/usb/ehci/Makefile

    r3f2cb17 r6602e97  
    5151        hc.c \
    5252        hw_struct/queue_head.c \
     53        hw_struct/transfer_descriptor.c \
    5354        main.c \
    5455        res.c
  • uspace/drv/bus/usb/ehci/ehci_batch.c

    r3f2cb17 r6602e97  
    4646#include "utils/malloc32.h"
    4747
     48/* The buffer pointer list in the qTD is long enough to support a maximum
     49 * transfer size of 20K bytes. This case occurs when all five buffer pointers
     50 * are used and the first offset is zero. A qTD handles a 16Kbyte buffer
     51 * with any starting buffer alignment. EHCI specs p. 87 (pdf p. 97) */
     52#define EHCI_TD_MAX_TRANSFER   (16 * 1024)
     53
    4854static void (*const batch_setup[])(ehci_transfer_batch_t*, usb_direction_t);
    4955
     
    6066                    ehci_endpoint_get(ehci_batch->usb_batch->ep);
    6167                assert(ehci_ep);
    62                 for (unsigned i = 0; i < ehci_batch->td_count; ++i) {
     68                for (size_t i = 0; i < ehci_batch->td_count; ++i) {
    6369                        if (ehci_batch->tds[i] != ehci_ep->td)
    6470                                free32(ehci_batch->tds[i]);
     
    105111        }
    106112        link_initialize(&ehci_batch->link);
    107 //      ehci_batch->td_count =
    108 //          (usb_batch->buffer_size + EHCI_TD_MAX_TRANSFER - 1)
    109 //          / EHCI_TD_MAX_TRANSFER;
     113        ehci_batch->td_count =
     114            (usb_batch->buffer_size + EHCI_TD_MAX_TRANSFER - 1)
     115            / EHCI_TD_MAX_TRANSFER;
     116
    110117        /* Control transfer need Setup and Status stage */
    111118        if (usb_batch->ep->transfer_type == USB_TRANSFER_CONTROL) {
     
    113120        }
    114121
    115         /* We need an extra place for TD that was left at ED */
    116         ehci_batch->tds = calloc(ehci_batch->td_count + 1, sizeof(td_t*));
     122        ehci_batch->tds = calloc(ehci_batch->td_count, sizeof(td_t*));
    117123        if (!ehci_batch->tds) {
    118124                usb_log_error("Failed to allocate EHCI transfer descriptors.");
     
    122128        /* Add TD left over by the previous transfer */
    123129        ehci_batch->qh = ehci_endpoint_get(usb_batch->ep)->qh;
    124         ehci_batch->tds[0] = ehci_endpoint_get(usb_batch->ep)->td;
    125 
    126         for (unsigned i = 1; i <= ehci_batch->td_count; ++i) {
     130
     131        for (unsigned i = 0; i < ehci_batch->td_count; ++i) {
    127132                ehci_batch->tds[i] = malloc32(sizeof(td_t));
    128133                if (!ehci_batch->tds[i]) {
     
    133138
    134139
    135         /* NOTE: EHCI is capable of handling buffer that crosses page boundaries
    136          * it is, however, not capable of handling buffer that occupies more
    137          * than two pages (the first page is computed using start pointer, the
    138          * other using the end pointer) */
     140        /* Mix setup stage and data together, we have enough space */
    139141        if (usb_batch->setup_size + usb_batch->buffer_size > 0) {
    140142                /* Use one buffer for setup and data stage */
     
    182184        usb_log_debug("Batch %p checking %zu td(s) for completion.\n",
    183185            ehci_batch->usb_batch, ehci_batch->td_count);
    184 #if 0
    185         usb_log_debug2("ED: %08x:%08x:%08x:%08x.\n",
    186             ehci_batch->ed->status, ehci_batch->ed->td_head,
    187             ehci_batch->ed->td_tail, ehci_batch->ed->next);
    188 
    189         if (!ed_inactive(ehci_batch->ed) && ed_transfer_pending(ehci_batch->ed))
     186
     187        usb_log_debug2("QH: %08x:%08x:%08x:%08x:%08x:%08x.\n",
     188            ehci_batch->qh->ep_char, ehci_batch->qh->ep_cap,
     189            ehci_batch->qh->status, ehci_batch->qh->current,
     190            ehci_batch->qh->next, ehci_batch->qh->alternate);
     191
     192        if (!qh_halted(ehci_batch->qh) && qh_transfer_pending(ehci_batch->qh))
    190193                return false;
    191194
     
    197200            ehci_batch->usb_batch->buffer_size;
    198201
    199         /* Assume we will leave the last(unused) TD behind */
    200         unsigned leave_td = ehci_batch->td_count;
    201 
    202202        /* Check all TDs */
    203203        for (size_t i = 0; i < ehci_batch->td_count; ++i) {
    204204                assert(ehci_batch->tds[i] != NULL);
    205                 usb_log_debug("TD %zu: %08x:%08x:%08x:%08x.\n", i,
    206                     ehci_batch->tds[i]->status, ehci_batch->tds[i]->cbp,
    207                     ehci_batch->tds[i]->next, ehci_batch->tds[i]->be);
    208 
     205                usb_log_debug("TD %zu: %08x:%08x:%08x.", i,
     206                    ehci_batch->tds[i]->status, ehci_batch->tds[i]->next,
     207                    ehci_batch->tds[i]->alternate);
     208#if 0
    209209                ehci_batch->usb_batch->error = td_error(ehci_batch->tds[i]);
    210210                if (ehci_batch->usb_batch->error == EOK) {
     
    251251                        break;
    252252                }
    253         }
     253#endif
     254        }
     255
    254256        assert(ehci_batch->usb_batch->transfered_size <=
    255257            ehci_batch->usb_batch->buffer_size);
    256 
     258#if 0
    257259        /* Store the remaining TD */
    258260        ehci_endpoint_t *ehci_ep = ehci_endpoint_get(ehci_batch->usb_batch->ep);
     
    291293        assert(ehci_batch->usb_batch);
    292294        assert(dir == USB_DIRECTION_IN || dir == USB_DIRECTION_OUT);
    293 #if 0
    294         usb_log_debug("Using ED(%p): %08x:%08x:%08x:%08x.\n", ehci_batch->ed,
    295             ehci_batch->ed->status, ehci_batch->ed->td_tail,
    296             ehci_batch->ed->td_head, ehci_batch->ed->next);
     295
     296        usb_log_debug2("Control QH: %08x:%08x:%08x:%08x:%08x:%08x",
     297            ehci_batch->qh->ep_char, ehci_batch->qh->ep_cap,
     298            ehci_batch->qh->status, ehci_batch->qh->current,
     299            ehci_batch->qh->next, ehci_batch->qh->alternate);
    297300        static const usb_direction_t reverse_dir[] = {
    298301                [USB_DIRECTION_IN]  = USB_DIRECTION_OUT,
     
    309312            ehci_batch->tds[0], ehci_batch->tds[1], USB_DIRECTION_BOTH,
    310313            buffer, ehci_batch->usb_batch->setup_size, toggle);
    311         usb_log_debug("Created CONTROL SETUP TD: %08x:%08x:%08x:%08x.\n",
    312             ehci_batch->tds[0]->status, ehci_batch->tds[0]->cbp,
    313             ehci_batch->tds[0]->next, ehci_batch->tds[0]->be);
     314        usb_log_debug("Created CONTROL SETUP TD: %08x:%08x:%08x",
     315            ehci_batch->tds[0]->status, ehci_batch->tds[0]->next,
     316            ehci_batch->tds[0]->alternate);
    314317        buffer += ehci_batch->usb_batch->setup_size;
    315318
     
    325328                    ehci_batch->tds[td_current + 1],
    326329                    data_dir, buffer, transfer_size, toggle);
    327                 usb_log_debug("Created CONTROL DATA TD: %08x:%08x:%08x:%08x.\n",
     330                usb_log_debug("Created CONTROL DATA TD: %08x:%08x:%08x",
    328331                    ehci_batch->tds[td_current]->status,
    329                     ehci_batch->tds[td_current]->cbp,
    330332                    ehci_batch->tds[td_current]->next,
    331                     ehci_batch->tds[td_current]->be);
     333                    ehci_batch->tds[td_current]->alternate);
    332334
    333335                buffer += transfer_size;
     
    341343        td_init(ehci_batch->tds[td_current], ehci_batch->tds[td_current + 1],
    342344            status_dir, NULL, 0, 1);
    343         usb_log_debug("Created CONTROL STATUS TD: %08x:%08x:%08x:%08x.\n",
     345        usb_log_debug("Created CONTROL STATUS TD: %08x:%08x:%08x",
    344346            ehci_batch->tds[td_current]->status,
    345             ehci_batch->tds[td_current]->cbp,
    346347            ehci_batch->tds[td_current]->next,
    347             ehci_batch->tds[td_current]->be);
    348 #endif
     348            ehci_batch->tds[td_current]->alternate);
     349
    349350        usb_log_debug2(
    350351            "Batch %p %s %s " USB_TRANSFER_BATCH_FMT " initialized.\n", \
     
    368369        assert(ehci_batch->usb_batch);
    369370        assert(dir == USB_DIRECTION_IN || dir == USB_DIRECTION_OUT);
    370 #if 0
    371         usb_log_debug("Using ED(%p): %08x:%08x:%08x:%08x.\n", ehci_batch->ed,
    372             ehci_batch->ed->status, ehci_batch->ed->td_tail,
    373             ehci_batch->ed->td_head, ehci_batch->ed->next);
     371
     372        usb_log_debug2("Control QH: %08x:%08x:%08x:%08x:%08x:%08x",
     373            ehci_batch->qh->ep_char, ehci_batch->qh->ep_cap,
     374            ehci_batch->qh->status, ehci_batch->qh->current,
     375            ehci_batch->qh->next, ehci_batch->qh->alternate);
    374376
    375377        size_t td_current = 0;
     
    384386                    dir, buffer, transfer_size, -1);
    385387
    386                 usb_log_debug("Created DATA TD: %08x:%08x:%08x:%08x.\n",
     388                usb_log_debug("Created DATA TD: %08x:%08x:%08x",
    387389                    ehci_batch->tds[td_current]->status,
    388                     ehci_batch->tds[td_current]->cbp,
    389390                    ehci_batch->tds[td_current]->next,
    390                     ehci_batch->tds[td_current]->be);
     391                    ehci_batch->tds[td_current]->alternate);
    391392
    392393                buffer += transfer_size;
     
    395396                ++td_current;
    396397        }
    397 #endif
     398
    398399        usb_log_debug2(
    399             "Batch %p %s %s " USB_TRANSFER_BATCH_FMT " initialized.\n", \
     400            "Batch %p %s %s " USB_TRANSFER_BATCH_FMT " initialized",
    400401            ehci_batch->usb_batch,
    401402            usb_str_transfer_type(ehci_batch->usb_batch->ep->transfer_type),
  • uspace/drv/bus/usb/ehci/hw_struct/queue_head.h

    r3f2cb17 r6602e97  
    178178}
    179179
     180static inline bool qh_halted(const qh_t *qh)
     181{
     182        assert(qh);
     183        return (EHCI_MEM32_RD(qh->status) & QH_STATUS_HALTED_FLAG);
     184}
     185
     186static inline void qh_halt(qh_t *qh)
     187{
     188        assert(qh);
     189        EHCI_MEM32_SET(qh->status, QH_STATUS_HALTED_FLAG);
     190}
     191
     192static inline bool qh_transfer_pending(const qh_t *qh)
     193{
     194        assert(qh);
     195        return !(EHCI_MEM32_RD(qh->next) & LINK_POINTER_TERMINATE_FLAG);
     196}
     197
    180198
    181199void qh_init(qh_t *instance, const endpoint_t *ep);
  • uspace/drv/bus/usb/ehci/hw_struct/transfer_descriptor.h

    r3f2cb17 r6602e97  
    6767
    6868        volatile uint32_t buffer_pointer[5];
    69 #define SITD_BUFFER_POINTER_MASK   0xfffff000
     69#define TD_BUFFER_POINTER_MASK   0xfffff000
    7070/* Only the first page pointer */
    71 #define SITD_BUFFER_POINTER_CURRENT_MASK    0xfff
    72 #define SITD_BUFFER_POINTER_CURRENT_SHIFT   0
     71#define TD_BUFFER_POINTER_OFFSET_MASK    0xfff
    7372
    7473} td_t;
     74
     75void td_init(td_t *td, const td_t *next, usb_direction_t dir, const void * buf,
     76    size_t buf_size, int toggle);
     77
    7578#endif
    7679/**
Note: See TracChangeset for help on using the changeset viewer.