The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/pc/usbehci.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*
    2  * USB Enhanced Host Controller Interface (EHCI) driver
    3  * High speed USB 2.0.
    4  *
    5  * BUGS:
    6  * - Too many delays and ilocks.
    7  * - bandwidth admission control must be done per-frame.
    8  * - requires polling (some controllers miss interrupts).
    9  * - must warn of power overruns.
   10  */
   11 
   12 #include        "u.h"
   13 #include        "../port/lib.h"
   14 #include        "mem.h"
   15 #include        "dat.h"
   16 #include        "fns.h"
   17 #include        "io.h"
   18 #include        "../port/error.h"
   19 #include        "usb.h"
   20 #include        "usbehci.h"
   21 
   22 typedef struct Ctlio Ctlio;
   23 typedef struct Ctlr Ctlr;
   24 typedef struct Itd Itd;
   25 typedef struct Sitd Sitd;
   26 typedef struct Qtd Qtd;
   27 typedef struct Td Td;
   28 typedef struct Qh Qh;
   29 typedef struct Fstn Fstn;
   30 typedef union Ed Ed;
   31 typedef struct Edpool Edpool;
   32 typedef struct Qio Qio;
   33 typedef struct Qtree Qtree;
   34 typedef struct Isoio Isoio;
   35 typedef struct Poll Poll;
   36 
   37 /*
   38  * EHCI interface registers and bits
   39  */
   40 enum {
   41         /* Queue states (software) */
   42         Qidle           = 0,
   43         Qinstall,
   44         Qrun,
   45         Qdone,
   46         Qclose,
   47         Qfree,
   48 
   49         Enabledelay     = 100,          /* waiting for a port to enable */
   50         Abortdelay      = 5,            /* delay after cancelling Tds (ms) */
   51         Ctltmout        = 2000,         /* timeout for a ctl. request (ms) */
   52         Bulktmout       = 2000,         /* timeout for a bulk xfer. (ms) */
   53         Isotmout        = 2000,         /* timeout for an iso. request (ms) */
   54 
   55         Incr            = 64,           /* for pools of Tds, Qhs, etc. */
   56         Align           = 128,          /* in bytes for all those descriptors */
   57 
   58         /* Keep them as a power of 2, lower than ctlr->nframes */
   59         /* Also, keep Nisoframes >= Nintrleafs */
   60         Nintrleafs      = 32,           /* nb. of leaf frames in intr. tree */
   61         Nisoframes      = 64,           /* nb. of iso frames (in window) */
   62 
   63         /*
   64          * HW constants
   65          */
   66 
   67         /* Itd bits (csw[]) */
   68         Itdactive       = 0x80000000,   /* execution enabled */
   69         Itddberr        = 0x40000000,   /* data buffer error */
   70         Itdbabble       = 0x20000000,   /* babble error */
   71         Itdtrerr        = 0x10000000,   /* transaction error */
   72         Itdlenshift     = 16,           /* transaction length */
   73         Itdlenmask      = 0xFFF,
   74         Itdioc          = 0x00008000,   /* interrupt on complete */
   75         Itdpgshift      = 12,           /* page select field */
   76         Itdoffshift     = 0,            /* transaction offset */
   77         /* Itd bits, buffer[] */
   78         Itdepshift      = 8,            /* endpoint address (buffer[0]) */
   79         Itddevshift     = 0,            /* device address (buffer[0]) */
   80         Itdin           = 0x800,        /* is input (buffer[1]) */
   81         Itdout          = 0,
   82         Itdmaxpktshift  = 0,            /* max packet (buffer[1]) */
   83         Itdntdsshift    = 0,            /* nb. of tds per µframe (buffer[2]) */
   84 
   85         Itderrors       = Itddberr|Itdbabble|Itdtrerr,
   86 
   87         /* Sitd bits (epc) */
   88         Stdin           = 0x80000000,   /* input direction */
   89         Stdportshift    = 24,           /* hub port number */
   90         Stdhubshift     = 16,           /* hub address */
   91         Stdepshift      = 8,            /* endpoint address */
   92         Stddevshift     = 0,            /* device address */
   93         /* Sitd bits (mfs) */
   94         Stdssmshift     = 0,            /* split start mask */
   95         Stdscmshift     = 8,            /* split complete mask */
   96         /* Sitd bits (csw) */
   97         Stdioc          = 0x80000000,   /* interrupt on complete */
   98         Stdpg           = 0x40000000,   /* page select */
   99         Stdlenshift     = 16,           /* total bytes to transfer */
  100         Stdlenmask      = 0x3FF,
  101         Stdactive       = 0x00000080,   /* active */
  102         Stderr          = 0x00000040,   /* tr. translator error */
  103         Stddberr        = 0x00000020,   /* data buffer error */
  104         Stdbabble       = 0x00000010,   /* babble error */
  105         Stdtrerr        = 0x00000008,   /* transanction error */
  106         Stdmmf          = 0x00000004,   /* missed µframe */
  107         Stddcs          = 0x00000002,   /* do complete split */
  108 
  109         Stderrors       = Stderr|Stddberr|Stdbabble|Stdtrerr|Stdmmf,
  110 
  111         /* Sitd bits buffer[1] */
  112         Stdtpall        = 0x00000000,   /* all payload here (188 bytes) */
  113         Stdtpbegin      = 0x00000008,   /* first payload for fs trans. */
  114         Stdtcntmask     = 0x00000007,   /* T-count */
  115 
  116         /* Td bits (csw) */
  117         Tddata1         = 0x80000000,   /* data toggle 1 */
  118         Tddata0         = 0x00000000,   /* data toggle 0 */
  119         Tdlenshift      = 16,           /* total bytes to transfer */
  120         Tdlenmask       = 0x7FFF,
  121         Tdmaxpkt        = 0x5000,       /* max buffer for a Td */
  122         Tdioc           = 0x00008000,   /* interrupt on complete */
  123         Tdpgshift       = 12,           /* current page */
  124         Tdpgmask        = 7,
  125         Tderr1          = 0x00000400,   /* bit 0 of error counter */
  126         Tderr2          = 0x00000800,   /* bit 1 of error counter */
  127         Tdtokout        = 0x00000000,   /* direction out */
  128         Tdtokin         = 0x00000100,   /* direction in */
  129         Tdtoksetup      = 0x00000200,   /* setup packet */
  130         Tdtok           = 0x00000300,   /* token bits */
  131         Tdactive                = 0x00000080,   /* active */
  132         Tdhalt          = 0x00000040,   /* halted */
  133         Tddberr         = 0x00000020,   /* data buffer error */
  134         Tdbabble        = 0x00000010,   /* babble error */
  135         Tdtrerr         = 0x00000008,   /* transanction error */
  136         Tdmmf           = 0x00000004,   /* missed µframe */
  137         Tddcs           = 0x00000002,   /* do complete split */
  138         Tdping          = 0x00000001,   /* do ping */
  139 
  140         Tderrors        = Tdhalt|Tddberr|Tdbabble|Tdtrerr|Tdmmf,
  141 
  142         /* Qh bits (eps0) */
  143         Qhrlcmask       = 0xF,          /* nak reload count */
  144         Qhrlcshift      = 28,           /* nak reload count */
  145         Qhnhctl         = 0x08000000,   /* not-high speed ctl */
  146         Qhmplmask       = 0x7FF,        /* max packet */
  147         Qhmplshift      = 16,
  148         Qhhrl           = 0x00008000,   /* head of reclamation list */
  149         Qhdtc           = 0x00004000,   /* data toggle ctl. */
  150         Qhint           = 0x00000080,   /* inactivate on next transition */
  151         Qhspeedmask     = 0x00003000,   /* speed bits */
  152         Qhfull          = 0x00000000,   /* full speed */
  153         Qhlow           = 0x00001000,   /* low speed */
  154         Qhhigh          = 0x00002000,   /* high speed */
  155 
  156         /* Qh bits (eps1) */
  157         Qhmultshift     = 30,           /* multiple tds per µframe */
  158         Qhmultmask      = 3,
  159         Qhportshift     = 23,           /* hub port number */
  160         Qhhubshift      = 16,           /* hub address */
  161         Qhscmshift      = 8,            /* split completion mask bits */
  162         Qhismshift      = 0,            /* interrupt sched. mask bits */
  163 };
  164 
  165 /*
  166  * Endpoint tree (software)
  167  */
  168 struct Qtree {
  169         int     nel;
  170         int     depth;
  171         ulong*  bw;
  172         Qh**    root;
  173 };
  174 
  175 /*
  176  * One per endpoint per direction, to control I/O.
  177  */
  178 struct Qio {
  179         QLock;                  /* for the entire I/O process */
  180         Rendez;                 /* wait for completion */
  181         Qh*     qh;             /* Td list (field const after init) */
  182         int     usbid;          /* usb address for endpoint/device */
  183         int     toggle;         /* Tddata0/Tddata1 */
  184         int     tok;            /* Tdtoksetup, Tdtokin, Tdtokout */
  185         ulong   iotime;         /* last I/O time; to hold interrupt polls */
  186         int     debug;          /* debug flag from the endpoint */
  187         char*   err;            /* error string */
  188         char*   tag;            /* debug (no room in Qh for this) */
  189         ulong   bw;
  190 };
  191 
  192 struct Ctlio {
  193         Qio;                    /* a single Qio for each RPC */
  194         uchar*  data;           /* read from last ctl req. */
  195         int     ndata;          /* number of bytes read */
  196 };
  197 
  198 struct Isoio {
  199         QLock;
  200         Rendez;                 /* wait for space/completion/errors */
  201         int     usbid;          /* address used for device/endpoint */
  202         int     tok;            /* Tdtokin or Tdtokout */
  203         int     state;          /* Qrun -> Qdone -> Qrun... -> Qclose */
  204         int     nframes;        /* number of frames ([S]Itds) used */
  205         uchar*  data;           /* iso data buffers if not embedded */
  206         char*   err;            /* error string */
  207         int     nerrs;          /* nb of consecutive I/O errors */
  208         ulong   maxsize;                /* ntds * ep->maxpkt */
  209         long    nleft;          /* number of bytes left from last write */
  210         int     debug;          /* debug flag from the endpoint */
  211         int     hs;             /* is high speed? */
  212         Isoio*  next;           /* in list of active Isoios */
  213         ulong   td0frno;        /* first frame used in ctlr */
  214         union{
  215                 Itd*    tdi;    /* next td processed by interrupt */
  216                 Sitd*   stdi;
  217         };
  218         union{
  219                 Itd*    tdu;    /* next td for user I/O in tdps */
  220                 Sitd*   stdu;
  221         };
  222         union{
  223                 Itd**   itdps;  /* itdps[i]: ptr to Itd for i-th frame or nil */
  224                 Sitd**  sitdps; /* sitdps[i]: ptr to Sitd for i-th frame or nil */
  225                 ulong** tdps;   /* same thing, as seen by hw */
  226         };
  227 };
  228 
  229 struct Poll {
  230         Lock;
  231         Rendez;
  232         int must;
  233         int does;
  234 };
  235 
  236 struct Ctlr {
  237         Rendez;                 /* for waiting to async advance doorbell */
  238         Lock;                   /* for ilock. qh lists and basic ctlr I/O */
  239         QLock   portlck;        /* for port resets/enable... (and doorbell) */
  240         int     active;         /* in use or not */
  241         Pcidev* pcidev;
  242         Ecapio* capio;          /* Capability i/o regs */
  243         Eopio*  opio;           /* Operational i/o regs */
  244 
  245         int     nframes;        /* 1024, 512, or 256 frames in the list */
  246         ulong*  frames;         /* periodic frame list (hw) */
  247         Qh*     qhs;            /* async Qh circular list for bulk/ctl */
  248         Qtree*  tree;           /* tree of Qhs for the periodic list */
  249         int     ntree;          /* number of dummy qhs in tree */
  250         Qh*     intrqhs;                /* list of (not dummy) qhs in tree  */
  251         Isoio*  iso;            /* list of active Iso I/O */
  252         ulong   load;
  253         ulong   isoload;
  254         int     nintr;          /* number of interrupts attended */
  255         int     ntdintr;                /* number of intrs. with something to do */
  256         int     nqhintr;                /* number of async td intrs. */
  257         int     nisointr;       /* number of periodic td intrs. */
  258         int     nreqs;
  259         Poll    poll;
  260 };
  261 
  262 struct Edpool {
  263         Lock;
  264         Ed*     free;
  265         int     nalloc;
  266         int     ninuse;
  267         int     nfree;
  268 };
  269 
  270 /*
  271  * We use the 64-bit version for Itd, Sitd, Td, and Qh.
  272  * If the ehci is 64-bit capable it assumes we are using those
  273  * structures even when the system is 32 bits.
  274  */
  275 
  276 /*
  277  * Iso transfer descriptor. hw. 92 bytes, 104 bytes total
  278  * aligned to 32.
  279  */
  280 struct Itd {
  281         ulong   link;           /* to next hw struct */
  282         ulong   csw[8];         /* sts/length/pg/off. updated by hw */
  283         ulong   buffer[7];      /* buffer pointers, addrs, maxsz */
  284         ulong   xbuffer[7];     /* high 32 bits of buffer for 64-bits */
  285 
  286         /* software */
  287         Itd*    next;
  288         ulong   ndata;          /* number of bytes in data */
  289         ulong   mdata;          /* max number of bytes in data */
  290         uchar*  data;
  291 };
  292 
  293 /*
  294  * Split transaction iso transfer descriptor.
  295  * hw: 36 bytes, 52 bytes total. aligned to 32.
  296  */
  297 struct Sitd {
  298         ulong   link;           /* to next hw struct */
  299         ulong   epc;            /* static endpoint state. addrs */
  300         ulong   mfs;            /* static endpoint state. µ-frame sched. */
  301         ulong   csw;            /* transfer state. updated by hw */
  302         ulong   buffer[2];      /* buf. ptr/offset. offset updated by hw */
  303                                 /* buf ptr/TP/Tcnt. TP/Tcnt updated by hw */
  304         ulong   blink;          /* back pointer */
  305         ulong   xbuffer[2];     /* high 32 bits of buffer for 64-bits */
  306 
  307         /* software */
  308         Sitd*   next;
  309         ulong   ndata;          /* number of bytes in data */
  310         ulong   mdata;          /* max number of bytes in data */
  311         uchar*  data;
  312 };
  313 
  314 /*
  315  * Queue element transfer descriptor.
  316  * hw: first 52 bytes; total 68+sbuff bytes aligned to 32 bytes.
  317  */
  318 struct Td {
  319         ulong   nlink;          /* to next Td */
  320         ulong   alink;          /* alternate link to next Td */
  321         ulong   csw;            /* cmd/sts. updated by hw */
  322         ulong   buffer[5];      /* buf ptrs. offset updated by hw */
  323         ulong   xbuffer[5];     /* high 32 bits of buffer for 64-bits */
  324 
  325         Td*     next;           /* in qh or Isoio or free list */
  326         ulong   ndata;          /* bytes available/used at data */
  327         uchar*  data;           /* pointer to actual data */
  328         uchar*  buff;           /* allocated data buffer or nil */
  329         uchar   sbuff[1];       /* first byte of embedded buffer */
  330 };
  331 
  332 /*
  333  * Queue head. Aligned to 32 bytes.
  334  * hw uses the first 68 bytes, 92 total.
  335  */
  336 struct Qh {
  337         ulong   link;           /* to next Qh in round robin */
  338         ulong   eps0;           /* static endpoint state. addrs */
  339         ulong   eps1;           /* static endpoint state. µ-frame sched. */
  340 
  341         /* updated by hw */
  342         ulong   clink;          /* current Td (No Term bit here!) */
  343         ulong   nlink;          /* to next Td */
  344         ulong   alink;          /* alternate link to next Td */
  345         ulong   csw;            /* cmd/sts. updated by hw */
  346         ulong   buffer[5];      /* buf ptrs. offset updated by hw */
  347         ulong   xbuffer[5];     /* high 32 bits of buffer for 64-bits */
  348 
  349         /* software */
  350         Qh*     next;           /* in controller list/tree of Qhs */
  351         int     state;          /* Qidle -> Qinstall -> Qrun -> Qdone | Qclose */
  352         Qio*    io;             /* for this queue */
  353         Td*     tds;            /* for this queue */
  354         int     sched;          /* slot for for intr. Qhs */
  355         Qh*     inext;          /* next in list of intr. qhs */
  356 };
  357 
  358 /*
  359  * We can avoid frame span traversal nodes if we don't span frames.
  360  * Just schedule transfer that can fit on the current frame and
  361  * wait a little bit otherwise.
  362  */
  363 
  364 /*
  365  * Software. Ehci descriptors provided by pool.
  366  * There are soo few because we avoid using Fstn.
  367  */
  368 union Ed {
  369         Ed*     next;           /* in free list */
  370         Qh      qh;
  371         Td      td;
  372         Itd     itd;
  373         Sitd    sitd;
  374         uchar   align[Align];
  375 };
  376 
  377 #define diprint         if(debug || iso->debug)print
  378 #define ddiprint        if(debug>1 || iso->debug>1)print
  379 #define dqprint         if(debug || (qh->io && qh->io->debug))print
  380 #define ddqprint        if(debug>1 || (qh->io && qh->io->debug>1))print
  381 #define TRUNC(x, sz)    ((x) & ((sz)-1))
  382 #define LPTR(q)         ((ulong*)KADDR((q) & ~0x1F))
  383 
  384 static int debug;
  385 static Edpool edpool;
  386 static Ctlr* ctlrs[Nhcis];
  387 static char Ebug[] = "not yet implemented";
  388 static char* qhsname[] = { "idle", "install", "run", "done", "close", "FREE" };
  389 
  390 
  391 static void
  392 ehcirun(Ctlr *ctlr, int on)
  393 {
  394         int i;
  395         Eopio *opio;
  396 
  397         ddprint("ehci %#p %s\n", ctlr->capio, on ? "starting" : "halting");
  398         opio = ctlr->opio;
  399         if(on)
  400                 opio->cmd |= Crun;
  401         else
  402                 opio->cmd = Cstop;
  403         for(i = 0; i < 100; i++)
  404                 if(on == 0 && (opio->sts & Shalted) != 0)
  405                         break;
  406                 else if(on != 0 && (opio->sts & Shalted) == 0)
  407                         break;
  408                 else
  409                         delay(1);
  410         if(i == 100)
  411                 print("ehci %#p %s cmd timed out\n",
  412                         ctlr->capio, on ? "run" : "halt");
  413         ddprint("ehci %#p cmd %#ulx sts %#ulx\n",
  414                 ctlr->capio, opio->cmd, opio->sts);
  415 }
  416 
  417 static void*
  418 edalloc(void)
  419 {
  420         Ed *ed, *pool;
  421         int i;
  422 
  423         lock(&edpool);
  424         if(edpool.free == nil){
  425                 pool = xspanalloc(Incr*sizeof(Ed), Align, 0);
  426                 if(pool == nil)
  427                         panic("edalloc");
  428                 for(i=Incr; --i>=0;){
  429                         pool[i].next = edpool.free;
  430                         edpool.free = &pool[i];
  431                 }
  432                 edpool.nalloc += Incr;
  433                 edpool.nfree += Incr;
  434                 dprint("ehci: edalloc: %d eds\n", edpool.nalloc);
  435         }
  436         ed = edpool.free;
  437         edpool.free = ed->next;
  438         edpool.ninuse++;
  439         edpool.nfree--;
  440         unlock(&edpool);
  441 
  442         memset(ed, 0, sizeof(Ed));      /* safety */
  443         assert(((ulong)ed & 0xF) == 0);
  444         return ed;
  445 }
  446 
  447 static void
  448 edfree(void *a)
  449 {
  450         Ed *ed;
  451 
  452         ed = a;
  453         lock(&edpool);
  454         ed->next = edpool.free;
  455         edpool.free = ed;
  456         edpool.ninuse--;
  457         edpool.nfree++;
  458         unlock(&edpool);
  459 }
  460 
  461 /*
  462  * Allocate and so same initialization.
  463  * Free after releasing buffers used.
  464  */
  465 
  466 static Itd*
  467 itdalloc(void)
  468 {
  469         Itd *td;
  470 
  471         td = edalloc();
  472         td->link = Lterm;
  473         return td;
  474 }
  475 
  476 static void
  477 itdfree(Itd *td)
  478 {
  479         edfree(td);
  480 }
  481 
  482 static Sitd*
  483 sitdalloc(void)
  484 {
  485         Sitd *td;
  486 
  487         td = edalloc();
  488         td->link = td->blink = Lterm;
  489         return td;
  490 }
  491 
  492 static void
  493 sitdfree(Sitd *td)
  494 {
  495         edfree(td);
  496 }
  497 
  498 static Td*
  499 tdalloc(void)
  500 {
  501         Td *td;
  502 
  503         td = edalloc();
  504         td->nlink = td->alink = Lterm;
  505         return td;
  506 }
  507 
  508 static void
  509 tdfree(Td *td)
  510 {
  511         if(td == nil)
  512                 return;
  513         free(td->buff);
  514         edfree(td);
  515 }
  516 
  517 static void
  518 tdlinktd(Td *td, Td *next)
  519 {
  520         td->next = next;
  521         td->alink = Lterm;
  522         if(next == nil)
  523                 td->nlink = Lterm;
  524         else
  525                 td->nlink = PADDR(next);
  526 }
  527 
  528 static Qh*
  529 qhlinkqh(Qh *qh, Qh *next)
  530 {
  531         qh->next = next;
  532         qh->link = PADDR(next)|Lqh;
  533         return qh;
  534 }
  535 
  536 static void
  537 qhsetaddr(Qh *qh, ulong addr)
  538 {
  539         ulong eps0;
  540         ulong ep;
  541         ulong dev;
  542 
  543         eps0 = qh->eps0 & ~((Epmax<<8)|Devmax);
  544         ep = (addr >> 7) & Epmax;
  545         dev = addr & Devmax;
  546         eps0 |= ep << 8;
  547         eps0 |= dev;
  548         qh->eps0 = eps0;
  549 }
  550 
  551 /*
  552  * return smallest power of 2 <= n
  553  */
  554 static int
  555 flog2lower(int n)
  556 {
  557         int i;
  558 
  559         for(i = 0; (1 << (i + 1)) <= n; i++)
  560                 ;
  561         return i;
  562 }
  563 
  564 static int
  565 pickschedq(Qtree *qt, int pollival, ulong bw, ulong limit)
  566 {
  567         int i, j, d, upperb, q;
  568         ulong best, worst, total;
  569 
  570         d = flog2lower(pollival);
  571         if(d > qt->depth)
  572                 d = qt->depth;
  573         q = -1;
  574         worst = 0;
  575         best = ~0;
  576         upperb = (1 << (d+1)) - 1;
  577         for(i = (1 << d) - 1; i < upperb; i++){
  578                 total = qt->bw[0];
  579                 for(j = i; j > 0; j = (j - 1) / 2)
  580                         total += qt->bw[j];
  581                 if(total < best){
  582                         best = total;
  583                         q = i;
  584                 }
  585                 if(total > worst)
  586                         worst = total;
  587         }
  588         if(worst + bw >= limit)
  589                 return -1;
  590         return q;
  591 }
  592 
  593 static int
  594 schedq(Ctlr *ctlr, Qh *qh, int pollival)
  595 {
  596         int q;
  597         Qh *tqh;
  598         ulong bw;
  599 
  600         bw = qh->io->bw;
  601         q = pickschedq(ctlr->tree, pollival, 0, ~0);
  602         ddqprint("ehci: sched %#p q %d, ival %d, bw %uld\n",
  603                 qh->io, q, pollival, bw);
  604         if(q < 0){
  605                 print("ehci: no room for ed\n");
  606                 return -1;
  607         }
  608         ctlr->tree->bw[q] += bw;
  609         tqh = ctlr->tree->root[q];
  610         qh->sched = q;
  611         qhlinkqh(qh, tqh->next);
  612         qhlinkqh(tqh, qh);
  613         qh->inext = ctlr->intrqhs;
  614         ctlr->intrqhs = qh;
  615         return 0;
  616 }
  617 
  618 static void
  619 unschedq(Ctlr *ctlr, Qh *qh)
  620 {
  621         int q;
  622         Qh *prev, *this, *next;
  623         Qh **l;
  624         ulong bw;
  625 
  626         bw = qh->io->bw;
  627         q = qh->sched;
  628         if(q < 0)
  629                 return;
  630         ctlr->tree->bw[q] -= bw;
  631 
  632         prev = ctlr->tree->root[q];
  633         this = prev->next;
  634         while(this != nil && this != qh){
  635                 prev = this;
  636                 this = this->next;
  637         }
  638         if(this == nil)
  639                 print("ehci: unschedq %d: not found\n", q);
  640         else{
  641                 next = this->next;
  642                 qhlinkqh(prev, next);
  643         }
  644         for(l = &ctlr->intrqhs; *l != nil; l = &(*l)->inext)
  645                 if(*l == qh){
  646                         *l = (*l)->inext;
  647                         return;
  648                 }
  649         print("ehci: unschedq: qh %#p not found\n", qh);
  650 }
  651 
  652 static ulong
  653 qhmaxpkt(Qh *qh)
  654 {
  655         return (qh->eps0 >> Qhmplshift) & Qhmplmask;
  656 }
  657 
  658 static void
  659 qhsetmaxpkt(Qh *qh, int maxpkt)
  660 {
  661         ulong eps0;
  662 
  663         eps0 = qh->eps0 & ~(Qhmplmask << Qhmplshift);
  664         eps0 |= (maxpkt & Qhmplmask) << Qhmplshift;
  665         qh->eps0 = eps0;
  666 }
  667 
  668 /*
  669  * Initialize the round-robin circular list of ctl/bulk Qhs
  670  * if ep is nil. Otherwise, allocate and link a new Qh in the ctlr.
  671  */
  672 static Qh*
  673 qhalloc(Ctlr *ctlr, Ep *ep, Qio *io, char* tag)
  674 {
  675         Qh *qh;
  676         int ttype;
  677 
  678         qh = edalloc();
  679         qh->nlink = Lterm;
  680         qh->alink = Lterm;
  681         qh->csw = Tdhalt;
  682         qh->state = Qidle;
  683         qh->sched = -1;
  684         qh->io = io;
  685         if(ep != nil){
  686                 qh->eps0 = 0;
  687                 qhsetmaxpkt(qh, ep->maxpkt);
  688                 if(ep->dev->speed == Lowspeed)
  689                         qh->eps0 |= Qhlow;
  690                 if(ep->dev->speed == Highspeed)
  691                         qh->eps0 |= Qhhigh;
  692                 else if(ep->ttype == Tctl)
  693                         qh->eps0 |= Qhnhctl;
  694                 qh->eps0 |= Qhdtc;
  695                 qh->eps0 |= (8 << Qhrlcshift);  /* 8 naks max */
  696                 qhsetaddr(qh, io->usbid);
  697                 qh->eps1 = (ep->ntds & Qhmultmask) << Qhmultshift;
  698                 qh->eps1 |= ep->dev->port << Qhportshift;
  699                 qh->eps1 |= ep->dev->hub << Qhhubshift;
  700                 qh->eps1 |= 034 << Qhscmshift;
  701                 if(ep->ttype == Tintr)
  702                         qh->eps1 |= (1 << Qhismshift); /* intr. start µf. */
  703                 if(io != nil)
  704                         io->tag = tag;
  705         }
  706         ilock(ctlr);
  707         ttype = Tctl;
  708         if(ep != nil)
  709                 ttype = ep->ttype;
  710         switch(ttype){
  711         case Tctl:
  712         case Tbulk:
  713                 if(ctlr->qhs == nil){
  714                         ctlr->qhs = qhlinkqh(qh, qh);
  715                         ctlr->opio->link = PADDR(qh)|Lqh;
  716                         qh->eps0 |= Qhhigh | Qhhrl;
  717                 }else{
  718                         qhlinkqh(qh, ctlr->qhs->next);
  719                         qhlinkqh(ctlr->qhs, qh);
  720                 }
  721                 break;
  722         case Tintr:
  723                 schedq(ctlr, qh, ep->pollival);
  724                 break;
  725         default:
  726                 print("ehci: qhalloc called for ttype != ctl/bulk\n");
  727         }
  728         iunlock(ctlr);
  729         return qh;
  730 }
  731 
  732 static int
  733 qhadvanced(void *a)
  734 {
  735         Ctlr *ctlr;
  736 
  737         ctlr = a;
  738         return (ctlr->opio->cmd & Ciasync) == 0;
  739 }
  740 
  741 /*
  742  * called when a qh is removed, to be sure the hw is not
  743  * keeping pointers into it.
  744  */
  745 static void
  746 qhcoherency(Ctlr *ctlr)
  747 {
  748         int i;
  749 
  750         qlock(&ctlr->portlck);
  751         ctlr->opio->cmd |= Ciasync;     /* ask for intr. on async advance */
  752         for(i = 0; i < 3 && qhadvanced(ctlr) == 0; i++)
  753                 if(!waserror()){
  754                         tsleep(ctlr, qhadvanced, ctlr, Abortdelay);
  755                         poperror();
  756                 }
  757         dprint("ehci: qhcoherency: doorbell %d\n", qhadvanced(ctlr));
  758         if(i == 3)
  759                 print("ehci: async advance doorbell did not ring\n");
  760         ctlr->opio->cmd &= ~Ciasync;    /* try to clean */
  761         qunlock(&ctlr->portlck);
  762 }
  763 
  764 static void
  765 qhfree(Ctlr *ctlr, Qh *qh)
  766 {
  767         Td *td;
  768         Td *ltd;
  769         Qh *q;
  770 
  771         if(qh == nil)
  772                 return;
  773         ilock(ctlr);
  774         if(qh->sched < 0){
  775                 for(q = ctlr->qhs; q != nil; q = q->next)
  776                         if(q->next == qh)
  777                                 break;
  778                 if(q == nil)
  779                         panic("qhfree: nil q");
  780                 q->next = qh->next;
  781                 q->link = qh->link;
  782         }else
  783                 unschedq(ctlr, qh);
  784         iunlock(ctlr);
  785 
  786         qhcoherency(ctlr);
  787 
  788         for(td = qh->tds; td != nil; td = ltd){
  789                 ltd = td->next;
  790                 tdfree(td);
  791         }
  792 
  793         edfree(qh);
  794 }
  795 
  796 static void
  797 qhlinktd(Qh *qh, Td *td)
  798 {
  799         ulong csw;
  800         int i;
  801 
  802         if(td == nil){
  803                 qh->tds = nil;
  804                 qh->csw |= Tdhalt;
  805                 qh->csw &= ~Tdactive;
  806         }else{
  807                 qh->tds = td;
  808                 csw = qh->csw & (Tddata1|Tdping);       /* save */
  809                 qh->csw = Tdhalt;
  810                 qh->clink = 0;
  811                 qh->alink = Lterm;
  812                 qh->nlink = PADDR(td);
  813                 for(i = 0; i < nelem(qh->buffer); i++)
  814                         qh->buffer[i] = 0;
  815                 qh->csw = csw & ~(Tdhalt|Tdactive);     /* activate next */
  816         }
  817 }
  818 
  819 static char*
  820 seprintlink(char *s, char *se, char *name, ulong l, int typed)
  821 {
  822         s = seprint(s, se, "%s %ulx", name, l);
  823         if((l & Lterm) != 0)
  824                 return seprint(s, se, "T");
  825         if(typed == 0)
  826                 return s;
  827         switch(l & (3<<1)){
  828         case Litd:
  829                 return seprint(s, se, "I");
  830         case Lqh:
  831                 return seprint(s, se, "Q");
  832         case Lsitd:
  833                 return seprint(s, se, "S");
  834         default:
  835                 return seprint(s, se, "F");
  836         }
  837 }
  838 
  839 static char*
  840 seprintitd(char *s, char *se, Itd *td)
  841 {
  842         int i;
  843         char flags[6];
  844         ulong b0;
  845         ulong b1;
  846         char *rw;
  847 
  848         if(td == nil)
  849                 return seprint(s, se, "<nil itd>\n");
  850         b0 = td->buffer[0];
  851         b1 = td->buffer[1];
  852 
  853         s = seprint(s, se, "itd %#p", td);
  854         rw = (b1 & Itdin) ? "in" : "out";
  855         s = seprint(s, se, " %s ep %uld dev %uld max %uld mult %uld",
  856                 rw, (b0>>8)&Epmax, (b0&Devmax),
  857                 td->buffer[1] & 0x7ff, b1 & 3);
  858         s = seprintlink(s, se, " link", td->link, 1);
  859         s = seprint(s, se, "\n");
  860         for(i = 0; i < nelem(td->csw); i++){
  861                 memset(flags, '-', 5);
  862                 if((td->csw[i] & Itdactive) != 0)
  863                         flags[0] = 'a';
  864                 if((td->csw[i] & Itdioc) != 0)
  865                         flags[1] = 'i';
  866                 if((td->csw[i] & Itddberr) != 0)
  867                         flags[2] = 'd';
  868                 if((td->csw[i] & Itdbabble) != 0)
  869                         flags[3] = 'b';
  870                 if((td->csw[i] & Itdtrerr) != 0)
  871                         flags[4] = 't';
  872                 flags[5] = 0;
  873                 s = seprint(s, se, "\ttd%d %s", i, flags);
  874                 s = seprint(s, se, " len %uld", (td->csw[i] >> 16) & 0x7ff);
  875                 s = seprint(s, se, " pg %uld", (td->csw[i] >> 12) & 0x7);
  876                 s = seprint(s, se, " off %uld\n", td->csw[i] & 0xfff);
  877         }
  878         s = seprint(s, se, "\tbuffs:");
  879         for(i = 0; i < nelem(td->buffer); i++)
  880                 s = seprint(s, se, " %#ulx", td->buffer[i] >> 12);
  881         return seprint(s, se, "\n");
  882 }
  883 
  884 static char*
  885 seprintsitd(char *s, char *se, Sitd *td)
  886 {
  887         static char pc[4] = { 'a', 'b', 'm', 'e' };
  888         char rw;
  889         char pg;
  890         char ss;
  891         char flags[8];
  892 
  893         if(td == nil)
  894                 return seprint(s, se, "<nil sitd>\n");
  895         s = seprint(s, se, "sitd %#p", td);
  896         rw = (td->epc & Stdin) ? 'r' : 'w';
  897         s = seprint(s, se, " %c ep %uld dev %uld",
  898                 rw, (td->epc>>8)&0xf, td->epc&0x7f);
  899         s = seprint(s, se, " max %uld", (td->csw >> 16) & 0x3ff);
  900         s = seprint(s, se, " hub %uld", (td->epc >> 16) & 0x7f);
  901         s = seprint(s, se, " port %uld\n", (td->epc >> 24) & 0x7f);
  902         memset(flags, '-', 7);
  903         if((td->csw & Stdactive) != 0)
  904                 flags[0] = 'a';
  905         if((td->csw & Stdioc) != 0)
  906                 flags[1] = 'i';
  907         if((td->csw & Stderr) != 0)
  908                 flags[2] = 'e';
  909         if((td->csw & Stddberr) != 0)
  910                 flags[3] = 'd';
  911         if((td->csw & Stdbabble) != 0)
  912                 flags[4] = 'b';
  913         if((td->csw & Stdtrerr) != 0)
  914                 flags[5] = 't';
  915         if((td->csw & Stdmmf) != 0)
  916                 flags[6] = 'n';
  917         flags[7] = 0;
  918         ss = (td->csw & Stddcs) ? 'c' : 's';
  919         pg = (td->csw & Stdpg) ? '1' : '';
  920         s = seprint(s, se, "\t%s %cs pg%c", flags, ss, pg);
  921         s = seprint(s, se, " b0 %#ulx b1 %#ulx off %uld\n",
  922                 td->buffer[0] >> 12, td->buffer[1] >> 12, td->buffer[0] & 0xfff);
  923         s = seprint(s, se, "\ttpos %c tcnt %uld",
  924                 pc[(td->buffer[0]>>3)&3], td->buffer[1] & 7);
  925         s = seprint(s, se, " ssm %#ulx csm %#ulx cspm %#ulx",
  926                 td->mfs & 0xff, (td->mfs>>8) & 0xff, (td->csw>>8) & 0xff);
  927         s = seprintlink(s, se, " link", td->link, 1);
  928         s = seprintlink(s, se, " blink", td->blink, 0);
  929         return seprint(s, se, "\n");
  930 }
  931 
  932 static long
  933 maxtdlen(Td *td)
  934 {
  935         return (td->csw >> Tdlenshift) & Tdlenmask;
  936 }
  937 
  938 static long
  939 tdlen(Td *td)
  940 {
  941         if(td->data == nil)
  942                 return 0;
  943         return td->ndata - maxtdlen(td);
  944 }
  945 
  946 static char*
  947 seprinttd(char *s, char *se, Td *td, char *tag)
  948 {
  949         static char *tok[4] = { "out", "in", "setup", "BUG" };
  950         char flags[9];
  951         char t;
  952         char ss;
  953         int i;
  954 
  955         s = seprint(s, se, "%s %#p", tag, td);
  956         s = seprintlink(s, se, " nlink", td->nlink, 0);
  957         s = seprintlink(s, se, " alink", td->alink, 0);
  958         s = seprint(s, se, " %s", tok[(td->csw & Tdtok) >> 8]);
  959         if((td->csw & Tdping) != 0)
  960                 s = seprint(s, se, " png");
  961         memset(flags, '-', 8);
  962         if((td->csw & Tdactive) != 0)
  963                 flags[0] = 'a';
  964         if((td->csw & Tdioc) != 0)
  965                 flags[1] = 'i';
  966         if((td->csw & Tdhalt) != 0)
  967                 flags[2] = 'h';
  968         if((td->csw & Tddberr) != 0)
  969                 flags[3] = 'd';
  970         if((td->csw & Tdbabble) != 0)
  971                 flags[4] = 'b';
  972         if((td->csw & Tdtrerr) != 0)
  973                 flags[5] = 't';
  974         if((td->csw & Tdmmf) != 0)
  975                 flags[6] = 'n';
  976         if((td->csw & (Tderr2|Tderr1)) == 0)
  977                 flags[7] = 'z';
  978         flags[8] = 0;
  979         t = (td->csw & Tddata1) ? '1' : '';
  980         ss = (td->csw & Tddcs) ? 'c' : 's';
  981         s = seprint(s, se, "\n\td%c %s %cs", t, flags, ss);
  982         s = seprint(s, se, " max %uld", maxtdlen(td));
  983         s = seprint(s, se, " pg %uld off %#ulx\n",
  984                 (td->csw >> Tdpgshift) & Tdpgmask, td->buffer[0] & 0xFFF);
  985         s = seprint(s, se, "\tbuffs:");
  986         for(i = 0; i < nelem(td->buffer); i++)
  987                 s = seprint(s, se, " %#ulx", td->buffer[i]>>12);
  988         if(td->data != nil)
  989                 s = seprintdata(s, se, td->data, td->ndata);
  990         return seprint(s, se, "\n");
  991 }
  992 
  993 static void
  994 dumptd(Td *td, char *pref)
  995 {
  996         char buf[256];
  997         char *se;
  998         int i;
  999 
 1000         i = 0;
 1001         se = buf+sizeof(buf);
 1002         for(; td != nil; td = td->next){
 1003                 seprinttd(buf, se, td, pref);
 1004                 print("%s", buf);
 1005                 if(i++ > 20){
 1006                         print("...more tds...\n");
 1007                         break;
 1008                 }
 1009         }
 1010 }
 1011 
 1012 static void
 1013 qhdump(Qh *qh)
 1014 {
 1015         static char *speed[] = {"full", "low", "high", "BUG"};
 1016         char buf[256];
 1017         char *s;
 1018         char *se;
 1019         char *tag;
 1020         Td td;
 1021 
 1022         if(qh == nil){
 1023                 print("<nil qh>\n");
 1024                 return;
 1025         }
 1026         if(qh->io == nil)
 1027                 tag = "qh";
 1028         else
 1029                 tag = qh->io->tag;
 1030         se = buf+sizeof(buf);
 1031         s = seprint(buf, se, "%s %#p", tag, qh);
 1032         s = seprint(s, se, " ep %uld dev %uld",
 1033                 (qh->eps0>>8)&0xf, qh->eps0&0x7f);
 1034         s = seprint(s, se, " hub %uld", (qh->eps1 >> 16) & 0x7f);
 1035         s = seprint(s, se, " port %uld", (qh->eps1 >> 23) & 0x7f);
 1036         s = seprintlink(s, se, " link", qh->link, 1);
 1037         seprint(s, se, "  clink %#ulx", qh->clink);
 1038         print("%s\n", buf);
 1039         s = seprint(buf, se, "\tnrld %uld", (qh->eps0 >> Qhrlcshift) & Qhrlcmask);
 1040         s = seprint(s, se, " nak %uld", (qh->alink >> 1) & 0xf);
 1041         s = seprint(s, se, " max %uld ", qhmaxpkt(qh));
 1042         if((qh->eps0 & Qhnhctl) != 0)
 1043                 s = seprint(s, se, "c");
 1044         if((qh->eps0 & Qhhrl) != 0)
 1045                 s = seprint(s, se, "h");
 1046         if((qh->eps0 & Qhdtc) != 0)
 1047                 s = seprint(s, se, "d");
 1048         if((qh->eps0 & Qhint) != 0)
 1049                 s = seprint(s, se, "i");
 1050         s = seprint(s, se, " %s", speed[(qh->eps0 >> 12) & 3]);
 1051         s = seprint(s, se, " mult %uld", (qh->eps1 >> Qhmultshift) & Qhmultmask);
 1052         seprint(s, se, " scm %#ulx ism %#ulx\n",
 1053                 (qh->eps1 >> 8 & 0xff), qh->eps1 & 0xff);
 1054         print("%s\n", buf);
 1055         memset(&td, 0, sizeof(td));
 1056         memmove(&td, &qh->nlink, 32);   /* overlay area */
 1057         seprinttd(buf, se, &td, "\tovl");
 1058         print("%s", buf);
 1059 }
 1060 
 1061 static void
 1062 isodump(Isoio* iso, int all)
 1063 {
 1064         Itd *td, *tdi, *tdu;
 1065         Sitd *std, *stdi, *stdu;
 1066         char buf[256];
 1067         int i;
 1068 
 1069         if(iso == nil){
 1070                 print("<nil iso>\n");
 1071                 return;
 1072         }
 1073         print("iso %#p %s %s speed state %d nframes %d maxsz %uld",
 1074                 iso, iso->tok == Tdtokin ? "in" : "out",
 1075                 iso->hs ? "high" : "full",
 1076                 iso->state, iso->nframes, iso->maxsize);
 1077         print(" td0 %uld tdi %#p tdu %#p data %#p\n",
 1078                 iso->td0frno, iso->tdi, iso->tdu, iso->data);
 1079         if(iso->err != nil)
 1080                 print("\terr %s\n", iso->err);
 1081         if(iso->err != nil)
 1082                 print("\terr='%s'\n", iso->err);
 1083         if(all == 0)
 1084                 if(iso->hs != 0){
 1085                         tdi = iso->tdi;
 1086                         seprintitd(buf, buf+sizeof(buf), tdi);
 1087                         print("\ttdi %s\n", buf);
 1088                         tdu = iso->tdu;
 1089                         seprintitd(buf, buf+sizeof(buf), tdu);
 1090                         print("\ttdu %s\n", buf);
 1091                 }else{
 1092                         stdi = iso->stdi;
 1093                         seprintsitd(buf, buf+sizeof(buf), stdi);
 1094                         print("\tstdi %s\n", buf);
 1095                         stdu = iso->stdu;
 1096                         seprintsitd(buf, buf+sizeof(buf), stdu);
 1097                         print("\tstdu %s\n", buf);
 1098                 }
 1099         else{
 1100                 for(i = 0; i < Nisoframes; i++)
 1101                         if(iso->tdps[i] != nil)
 1102                         if(iso->hs != 0){
 1103                                 td = iso->itdps[i];
 1104                                 seprintitd(buf, buf+sizeof(buf), td);
 1105                                 if(td == iso->tdi)
 1106                                         print("i->");
 1107                                 if(td == iso->tdu)
 1108                                         print("i->");
 1109                                 print("[%d]\t%s", i, buf);
 1110                         }else{
 1111                                 std = iso->sitdps[i];
 1112                                 seprintsitd(buf, buf+sizeof(buf), std);
 1113                                 if(std == iso->stdi)
 1114                                         print("i->");
 1115                                 if(std == iso->stdu)
 1116                                         print("u->");
 1117                                 print("[%d]\t%s", i, buf);
 1118                         }
 1119         }
 1120 }
 1121 
 1122 static void
 1123 dump(Hci *hp)
 1124 {
 1125         Ctlr *ctlr;
 1126         Isoio *iso;
 1127         Eopio *opio;
 1128         int i;
 1129         char buf[128];
 1130         char *s;
 1131         char *se;
 1132         Qh *qh;
 1133 
 1134         ctlr = hp->aux;
 1135         opio = ctlr->opio;
 1136         ilock(ctlr);
 1137         print("ehci port %#p frames %#p (%d fr.) nintr %d ntdintr %d",
 1138                 ctlr->capio, ctlr->frames, ctlr->nframes,
 1139                 ctlr->nintr, ctlr->ntdintr);
 1140         print(" nqhintr %d nisointr %d\n", ctlr->nqhintr, ctlr->nisointr);
 1141         print("\tcmd %#ulx sts %#ulx intr %#ulx frno %uld",
 1142                 opio->cmd, opio->sts, opio->intr, opio->frno);
 1143         print(" base %#ulx link %#ulx fr0 %#ulx\n",
 1144                 opio->frbase, opio->link, ctlr->frames[0]);
 1145         se = buf+sizeof(buf);
 1146         s = seprint(buf, se, "\t");
 1147         for(i = 0; i < hp->nports; i++){
 1148                 s = seprint(s, se, "p%d %#ulx ", i, opio->portsc[i]);
 1149                 if(hp->nports > 4 && i == hp->nports/2 - 1)
 1150                         s = seprint(s, se, "\n\t");
 1151         }
 1152         print("%s\n", buf);
 1153         qh = ctlr->qhs;
 1154         i = 0;
 1155         do{
 1156                 qhdump(qh);
 1157                 qh = qh->next;
 1158         }while(qh != ctlr->qhs && i++ < 100);
 1159         if(i > 100)
 1160                 print("...too many Qhs...\n");
 1161         if(ctlr->intrqhs != nil)
 1162                 print("intr qhs:\n");
 1163         for(qh = ctlr->intrqhs; qh != nil; qh = qh->inext)
 1164                 qhdump(qh);
 1165         if(ctlr->iso != nil)
 1166                 print("iso:\n");
 1167         for(iso = ctlr->iso; iso != nil; iso = iso->next)
 1168                 isodump(ctlr->iso, 0);
 1169         print("%d eds in tree\n", ctlr->ntree);
 1170         iunlock(ctlr);
 1171         lock(&edpool);
 1172         print("%d eds allocated = %d in use + %d free\n",
 1173                 edpool.nalloc, edpool.ninuse, edpool.nfree);
 1174         unlock(&edpool);
 1175 }
 1176 
 1177 static char*
 1178 errmsg(int err)
 1179 {
 1180         if(err == 0)
 1181                 return "ok";
 1182         if(err & Tddberr)
 1183                 return "data buffer error";
 1184         if(err & Tdbabble)
 1185                 return "babble detected";
 1186         if(err & Tdtrerr)
 1187                 return "transaction error";
 1188         if(err & Tdmmf)
 1189                 return "missed µframe";
 1190         if(err & Tdhalt)
 1191                 return Estalled;        /* [uo]hci report this error */
 1192         return Eio;
 1193 }
 1194 
 1195 static char*
 1196 ierrmsg(int err)
 1197 {
 1198         if(err == 0)
 1199                 return "ok";
 1200         if(err & Itddberr)
 1201                 return "data buffer error";
 1202         if(err & Itdbabble)
 1203                 return "babble detected";
 1204         if(err & Itdtrerr)
 1205                 return "transaction error";
 1206         return Eio;
 1207 }
 1208 
 1209 static char*
 1210 serrmsg(int err)
 1211 {
 1212         if(err & Stderr)
 1213                 return "translation translator error";
 1214         /* other errors have same numbers than Td errors */
 1215         return errmsg(err);
 1216 }
 1217 
 1218 static int
 1219 isocanread(void *a)
 1220 {
 1221         Isoio *iso;
 1222 
 1223         iso = a;
 1224         if(iso->state == Qclose)
 1225                 return 1;
 1226         if(iso->state == Qrun && iso->tok == Tdtokin){
 1227                 if(iso->hs != 0 && iso->tdi != iso->tdu)
 1228                         return 1;
 1229                 if(iso->hs == 0 && iso->stdi != iso->stdu)
 1230                         return 1;
 1231         }
 1232         return 0;
 1233 }
 1234 
 1235 static int
 1236 isocanwrite(void *a)
 1237 {
 1238         Isoio *iso;
 1239 
 1240         iso = a;
 1241         if(iso->state == Qclose)
 1242                 return 1;
 1243         if(iso->state == Qrun && iso->tok == Tdtokout){
 1244                 if(iso->hs != 0 && iso->tdu->next != iso->tdi)
 1245                         return 1;
 1246                 if(iso->hs == 0 && iso->stdu->next != iso->stdi)
 1247                         return 1;
 1248         }
 1249         return 0;
 1250 }
 1251 
 1252 static void
 1253 itdinit(Isoio *iso, Itd *td)
 1254 {
 1255         ulong pa;
 1256         int p;
 1257         int t;
 1258         ulong tsize;
 1259         ulong size;
 1260 
 1261         /*
 1262          * BUG: This does not put an integral number of samples
 1263          * on each µframe unless samples per packet % 8 == 0
 1264          * Also, all samples are packed early on each frame.
 1265          */
 1266         p = 0;
 1267         size = td->ndata = td->mdata;
 1268         pa = PADDR(td->data);
 1269         for(t = 0; size > 0 && t < 8; t++){
 1270                 tsize = size;
 1271                 if(tsize > iso->maxsize)
 1272                         tsize = iso->maxsize;
 1273                 size -= tsize;
 1274                 td->csw[t] = tsize << Itdlenshift;
 1275                 assert(p < nelem(td->buffer));
 1276                 td->csw[t] |= p << Itdpgshift;
 1277                 td->csw[t] |= (pa & 0xFFF) << Itdoffshift;
 1278                 td->csw[t] |= Itdactive|Itdioc;
 1279                 if(((pa+tsize) & ~0xFFF) != (pa & ~0xFFF))
 1280                         p++;
 1281                 pa += tsize;
 1282         }
 1283 }
 1284 
 1285 static void
 1286 sitdinit(Isoio *iso, Sitd *td)
 1287 {
 1288         td->ndata = td->mdata & Stdlenmask;
 1289         td->csw = (td->ndata << Stdlenshift) | Stdactive | Stdioc;
 1290         td->buffer[0] = PADDR(td->data);
 1291         td->buffer[1] = (td->buffer[0] & ~0xFFF) + 0x1000;
 1292         if(iso->tok == Tdtokin || td->ndata <= 188)
 1293                 td->buffer[1] |= Stdtpall;
 1294         else
 1295                 td->buffer[1] |= Stdtpbegin;
 1296         if(iso->tok == Tdtokin)
 1297                 td->buffer[1] |= 1;
 1298         else
 1299                 td->buffer[1] |= ((td->ndata + 187 ) / 188) & Stdtcntmask;
 1300 }
 1301 
 1302 static int
 1303 itdactive(Itd *td)
 1304 {
 1305         int i;
 1306 
 1307         for(i = 0; i < nelem(td->csw); i++)
 1308                 if((td->csw[i] & Itdactive) != 0)
 1309                         return 1;
 1310         return 0;
 1311 }
 1312 
 1313 static int
 1314 isohsinterrupt(Ctlr *ctlr, Isoio *iso)
 1315 {
 1316         Itd *tdi;
 1317         int err;
 1318         int i;
 1319         int t;
 1320         int nframes;
 1321 
 1322         tdi = iso->tdi;
 1323         assert(tdi != nil);
 1324         if(itdactive(tdi))      /* not all tds are done */
 1325                 return 0;
 1326         ctlr->nisointr++;
 1327         ddiprint("isohsintr: iso %#p: tdi %#p tdu %#p\n", iso, tdi, iso->tdu);
 1328         if(iso->state != Qrun && iso->state != Qdone)
 1329                 panic("isofsintr: iso state");
 1330         if(debug > 1 || iso->debug > 1)
 1331                 isodump(iso, 0);
 1332 
 1333         nframes = iso->nframes / 2;             /* limit how many we look */
 1334         if(nframes > Nisoframes)
 1335                 nframes = Nisoframes;
 1336 
 1337         if(iso->tok == Tdtokin)
 1338                 tdi->ndata = 0;
 1339         /* else, it has the number of bytes transferred */
 1340 
 1341         for(i = 0; i < nframes && itdactive(tdi) == 0; i++){
 1342                 err = 0;
 1343                 if(iso->tok == Tdtokin)
 1344                         tdi->ndata += (tdi->csw[i] >> Itdlenshift)&Itdlenmask;
 1345                 for(t = 0; t < nelem(tdi->csw); t++){
 1346                         tdi->csw[i] &= ~Itdioc;
 1347                         err |= tdi->csw[i] & Itderrors;
 1348                 }
 1349                 if(err == 0)
 1350                         iso->nerrs = 0;
 1351                 else if(iso->nerrs++ > iso->nframes/2){
 1352                         if(iso->err == nil){
 1353                                 iso->err = ierrmsg(err);
 1354                                 diprint("isohsintr: tdi %#p error %#ux %s\n",
 1355                                         tdi, err, iso->err);
 1356                                 diprint("ctlr load %uld\n", ctlr->load);
 1357                         }
 1358                         tdi->ndata = 0;
 1359                 }else
 1360                         tdi->ndata = 0;
 1361                 if(tdi->next == iso->tdu || tdi->next->next == iso->tdu){
 1362                         memset(iso->tdu->data, 0, iso->tdu->mdata);
 1363                         itdinit(iso, iso->tdu);
 1364                         iso->tdu = iso->tdu->next;
 1365                         iso->nleft = 0;
 1366                 }
 1367                 tdi = tdi->next;
 1368         }
 1369         ddiprint("isohsintr: %d frames processed\n", nframes);
 1370         if(i == nframes)
 1371                 tdi->csw[0] |= Itdioc;
 1372         iso->tdi = tdi;
 1373         if(isocanwrite(iso) || isocanread(iso)){
 1374                 diprint("wakeup iso %#p tdi %#p tdu %#p\n", iso,
 1375                         iso->tdi, iso->tdu);
 1376                 wakeup(iso);
 1377         }
 1378         return 1;
 1379 }
 1380 
 1381 static int
 1382 isofsinterrupt(Ctlr *ctlr, Isoio *iso)
 1383 {
 1384         Sitd *stdi;
 1385         int err;
 1386         int i;
 1387         int nframes;
 1388 
 1389         stdi = iso->stdi;
 1390         assert(stdi != nil);
 1391         if((stdi->csw & Stdactive) != 0)                /* nothing new done */
 1392                 return 0;
 1393         ctlr->nisointr++;
 1394         ddiprint("isofsintr: iso %#p: tdi %#p tdu %#p\n", iso, stdi, iso->stdu);
 1395         if(iso->state != Qrun && iso->state != Qdone)
 1396                 panic("isofsintr: iso state");
 1397         if(debug > 1 || iso->debug > 1)
 1398                 isodump(iso, 0);
 1399 
 1400         nframes = iso->nframes / 2;             /* limit how many we look */
 1401         if(nframes > Nisoframes)
 1402                 nframes = Nisoframes;
 1403 
 1404         for(i = 0; i < nframes && (stdi->csw & Stdactive) == 0; i++){
 1405                 stdi->csw &= ~Stdioc;
 1406                 err = stdi->csw & Stderrors;
 1407                 if(err == 0){
 1408                         iso->nerrs = 0;
 1409                         if(iso->tok == Tdtokin)
 1410                                 stdi->ndata = (stdi->csw>>Stdlenshift)&Stdlenmask;
 1411                         /* else len is assumed correct */
 1412                 }else if(iso->nerrs++ > iso->nframes/2){
 1413                         if(iso->err == nil){
 1414                                 iso->err = serrmsg(err);
 1415                                 diprint("isofsintr: tdi %#p error %#ux %s\n",
 1416                                         stdi, err, iso->err);
 1417                                 diprint("ctlr load %uld\n", ctlr->load);
 1418                         }
 1419                         stdi->ndata = 0;
 1420                 }else
 1421                         stdi->ndata = 0;
 1422 
 1423                 if(stdi->next == iso->stdu || stdi->next->next == iso->stdu){
 1424                         memset(iso->stdu->data, 0, iso->stdu->mdata);
 1425                         sitdinit(iso, iso->stdu);
 1426                         iso->stdu = iso->stdu->next;
 1427                         iso->nleft = 0;
 1428                 }
 1429                 stdi = stdi->next;
 1430         }
 1431         ddiprint("isofsintr: %d frames processed\n", nframes);
 1432         if(i == nframes)
 1433                 stdi->csw |= Stdioc;
 1434         iso->stdi = stdi;
 1435         if(isocanwrite(iso) || isocanread(iso)){
 1436                 diprint("wakeup iso %#p tdi %#p tdu %#p\n", iso,
 1437                         iso->stdi, iso->stdu);
 1438                 wakeup(iso);
 1439         }
 1440         return 1;
 1441 }
 1442 
 1443 static int
 1444 qhinterrupt(Ctlr *ctlr, Qh *qh)
 1445 {
 1446         Td *td;
 1447         int err;
 1448         char buf[256];
 1449 
 1450         if(qh->state != Qrun)
 1451                 panic("qhinterrupt: qh state");
 1452         if(qh->tds == nil)
 1453                 panic("qhinterrupt: no tds");
 1454         if((qh->tds->csw & Tdactive) == 0)
 1455                 ddqprint("qhinterrupt port %#p qh %#p\n",ctlr->capio, qh);
 1456         for(td = qh->tds; td != nil; td = td->next){
 1457                 if(td->csw & Tdactive)
 1458                         return 0;
 1459                 if((td->csw & Tderrors) != 0){
 1460                         err = td->csw & Tderrors;
 1461 if(debug || qh->io->debug){
 1462 seprinttd(buf, buf+sizeof(buf), td, "intr-fail-td");
 1463 print("qh %#p io %#p\n\t%s\n", qh, qh->io, buf);
 1464 }
 1465                         if(qh->io->err == nil){
 1466                                 qh->io->err = errmsg(td->csw & Tderrors);
 1467                                 dqprint("qhintr: td %#p csw %#ulx error %#ux %s\n",
 1468                                         td, td->csw, err, qh->io->err);
 1469                         }
 1470                         break;
 1471                 }
 1472                 td->ndata = tdlen(td);
 1473                 if(td->ndata < maxtdlen(td)){   /* EOT */
 1474                         td = td->next;
 1475                         break;
 1476                 }
 1477         }
 1478         /*
 1479          * Done. Make void the Tds not used (errors or EOT) and wakeup epio.
 1480          */
 1481         for(; td != nil; td = td->next)
 1482                 td->ndata = 0;
 1483         qh->state = Qdone;
 1484         wakeup(qh->io);
 1485         return 1;
 1486 }
 1487 
 1488 static int
 1489 ehciintr(Hci *hp)
 1490 {
 1491         Ctlr *ctlr;
 1492         Eopio *opio;
 1493         Isoio *iso;
 1494         ulong sts;
 1495         Qh *qh;
 1496         int i;
 1497         int some;
 1498 
 1499         ctlr = hp->aux;
 1500         opio = ctlr->opio;
 1501 
 1502         /*
 1503          * Will we know in USB 3.0 who the interrupt was for?.
 1504          * Do they still teach indexing in CS?
 1505          * This is Intel's doing.
 1506          */
 1507         ilock(ctlr);
 1508         ctlr->nintr++;
 1509         sts = opio->sts & Sintrs;
 1510         if(sts == 0){           /* not ours; shared intr. */
 1511                 iunlock(ctlr);
 1512                 return 0;
 1513         }
 1514         opio->sts = sts;
 1515         if((sts & Sherr) != 0)
 1516                 print("ehci: port %#p fatal host system error\n", ctlr->capio);
 1517         if((sts & Shalted) != 0)
 1518                 print("ehci: port %#p: halted\n", ctlr->capio);
 1519         if((sts & Sasync) != 0){
 1520                 dprint("ehci: doorbell\n");
 1521                 wakeup(ctlr);
 1522         }
 1523         /*
 1524          * We enter always this if, even if it seems the
 1525          * interrupt does not report anything done/failed.
 1526          * Some controllers don't post interrupts right.
 1527          */
 1528         some = 0;
 1529         if((sts & (Serrintr|Sintr)) != 0){
 1530                 ctlr->ntdintr++;
 1531                 if(debug > 1){
 1532                         print("ehci port %#p frames %#p nintr %d ntdintr %d",
 1533                                 ctlr->capio, ctlr->frames,
 1534                                 ctlr->nintr, ctlr->ntdintr);
 1535                         print(" nqhintr %d nisointr %d\n",
 1536                                 ctlr->nqhintr, ctlr->nisointr);
 1537                         print("\tcmd %#ulx sts %#ulx intr %#ulx frno %uld",
 1538                                 opio->cmd, opio->sts, opio->intr, opio->frno);
 1539                 }
 1540 
 1541                 /* process the Iso transfers */
 1542                 for(iso = ctlr->iso; iso != nil; iso = iso->next)
 1543                         if(iso->state == Qrun || iso->state == Qdone)
 1544                                 if(iso->hs != 0)
 1545                                         some += isohsinterrupt(ctlr, iso);
 1546                                 else
 1547                                         some += isofsinterrupt(ctlr, iso);
 1548 
 1549                 /* process the qhs in the periodic tree */
 1550                 for(qh = ctlr->intrqhs; qh != nil; qh = qh->inext)
 1551                         if(qh->state == Qrun)
 1552                                 some += qhinterrupt(ctlr, qh);
 1553 
 1554                 /* process the async Qh circular list */
 1555                 qh = ctlr->qhs;
 1556                 i = 0;
 1557                 do{
 1558                         if(qh->state == Qrun)
 1559                                 some += qhinterrupt(ctlr, qh);
 1560                         qh = qh->next;
 1561                 }while(qh != ctlr->qhs && i++ < 100);
 1562                 if(i > 100)
 1563                         print("echi: interrupt: qh loop?\n");
 1564         }
 1565         iunlock(ctlr);
 1566         return some;
 1567 }
 1568 
 1569 static void
 1570 interrupt(Ureg*, void* a)
 1571 {
 1572         ehciintr(a);
 1573 }
 1574 
 1575 static int
 1576 portenable(Hci *hp, int port, int on)
 1577 {
 1578         Ctlr *ctlr;
 1579         Eopio *opio;
 1580         int s;
 1581 
 1582         ctlr = hp->aux;
 1583         opio = ctlr->opio;
 1584         s = opio->portsc[port-1];
 1585         qlock(&ctlr->portlck);
 1586         if(waserror()){
 1587                 qunlock(&ctlr->portlck);
 1588                 nexterror();
 1589         }
 1590         dprint("ehci %#p port %d enable=%d; sts %#x\n",
 1591                 ctlr->capio, port, on, s);
 1592         ilock(ctlr);
 1593         if(s & (Psstatuschg | Pschange))
 1594                 opio->portsc[port-1] = s;
 1595         if(on)
 1596                 opio->portsc[port-1] |= Psenable;
 1597         else
 1598                 opio->portsc[port-1] &= ~Psenable;
 1599         microdelay(64);
 1600         iunlock(ctlr);
 1601         tsleep(&up->sleep, return0, 0, Enabledelay);
 1602         dprint("ehci %#p port %d enable=%d: sts %#ulx\n",
 1603                 ctlr->capio, port, on, opio->portsc[port-1]);
 1604         qunlock(&ctlr->portlck);
 1605         poperror();
 1606         return 0;
 1607 }
 1608 
 1609 /*
 1610  * If we detect during status that the port is low-speed or
 1611  * during reset that it's full-speed, the device is not for
 1612  * ourselves. The companion controller will take care.
 1613  * Low-speed devices will not be seen by usbd. Full-speed
 1614  * ones are seen because it's only after reset that we know what
 1615  * they are (usbd may notice a device not enabled in this case).
 1616  */
 1617 static void
 1618 portlend(Ctlr *ctlr, int port, char *ss)
 1619 {
 1620         Eopio *opio;
 1621         ulong s;
 1622 
 1623         opio = ctlr->opio;
 1624 
 1625         dprint("ehci %#p port %d: %s speed device: no longer owned\n",
 1626                 ctlr->capio, port, ss);
 1627         s = opio->portsc[port-1];
 1628         s &= ~(Pschange|Psstatuschg);
 1629         s |= Psowner;
 1630         opio->portsc[port-1] = s;
 1631 
 1632 }
 1633 
 1634 static int
 1635 portreset(Hci *hp, int port, int on)
 1636 {
 1637         ulong s;
 1638         Eopio *opio;
 1639         Ctlr *ctlr;
 1640         int i;
 1641 
 1642         if(on == 0)
 1643                 return 0;
 1644 
 1645         ctlr = hp->aux;
 1646         opio = ctlr->opio;
 1647         qlock(&ctlr->portlck);
 1648         if(waserror()){
 1649                 iunlock(ctlr);
 1650                 qunlock(&ctlr->portlck);
 1651                 nexterror();
 1652         }
 1653         s = opio->portsc[port-1];
 1654         dprint("ehci %#p port %d reset; sts %#ulx\n", ctlr->capio, port, s);
 1655         ilock(ctlr);
 1656         s &= ~(Psenable|Psreset);
 1657         opio->portsc[port-1] = s|Psreset;
 1658         for(i = 0; i < 10; i++){
 1659                 delay(10);
 1660                 if((opio->portsc[port-1] & Psreset) == 0)
 1661                         break;
 1662         }
 1663         opio->portsc[port-1] &= ~Psreset;
 1664         delay(10);
 1665         if((opio->portsc[port-1] & Psenable) == 0)
 1666                 portlend(ctlr, port, "full");
 1667 
 1668         iunlock(ctlr);
 1669         dprint("ehci %#p after port %d reset; sts %#ulx\n",
 1670                 ctlr->capio, port, opio->portsc[port-1]);
 1671         qunlock(&ctlr->portlck);
 1672         poperror();
 1673         return 0;
 1674 }
 1675 
 1676 static int
 1677 portstatus(Hci *hp, int port)
 1678 {
 1679         int s;
 1680         int r;
 1681         Eopio *opio;
 1682         Ctlr *ctlr;
 1683 
 1684         ctlr = hp->aux;
 1685         opio = ctlr->opio;
 1686         qlock(&ctlr->portlck);
 1687         if(waserror()){
 1688                 iunlock(ctlr);
 1689                 qunlock(&ctlr->portlck);
 1690                 nexterror();
 1691         }
 1692         ilock(ctlr);
 1693         s = opio->portsc[port-1];
 1694         if(s & (Psstatuschg | Pschange)){
 1695                 opio->portsc[port-1] = s;
 1696                 ddprint("ehci %#p port %d status %#x\n", ctlr->capio, port, s);
 1697         }
 1698         /*
 1699          * If the port is a low speed port we yield ownership now
 1700          * to the [uo]hci companion controller and pretend it's not here.
 1701          */
 1702         if((s & Pspresent) != 0 && (s & Pslinemask) == Pslow){
 1703                 portlend(ctlr, port, "low");
 1704                 s &= ~Pspresent;                        /* not for us this time */
 1705         }
 1706         iunlock(ctlr);
 1707         qunlock(&ctlr->portlck);
 1708         poperror();
 1709 
 1710         /*
 1711          * We must return status bits as a
 1712          * get port status hub request would do.
 1713          */
 1714         r = 0;
 1715         if(s & Pspresent)
 1716                 r |= HPpresent|HPhigh;
 1717         if(s & Psenable)
 1718                 r |= HPenable;
 1719         if(s & Pssuspend)
 1720                 r |= HPsuspend;
 1721         if(s & Psreset)
 1722                 r |= HPreset;
 1723         if(s & Psstatuschg)
 1724                 r |= HPstatuschg;
 1725         if(s & Pschange)
 1726                 r |= HPchange;
 1727         return r;
 1728 }
 1729 
 1730 static char*
 1731 seprintio(char *s, char *e, Qio *io, char *pref)
 1732 {
 1733         s = seprint(s,e,"%s io %#p qh %#p id %#x", pref, io, io->qh, io->usbid);
 1734         s = seprint(s,e," iot %ld", io->iotime);
 1735         s = seprint(s,e," tog %#x tok %#x err %s", io->toggle, io->tok, io->err);
 1736         return s;
 1737 }
 1738 
 1739 static char*
 1740 seprintep(char *s, char *e, Ep *ep)
 1741 {
 1742         Qio *io;
 1743         Ctlio *cio;
 1744         Ctlr *ctlr;
 1745 
 1746         ctlr = ep->hp->aux;
 1747         ilock(ctlr);
 1748         if(ep->aux == nil){
 1749                 *s = 0;
 1750                 iunlock(ctlr);
 1751                 return s;
 1752         }
 1753         switch(ep->ttype){
 1754         case Tctl:
 1755                 cio = ep->aux;
 1756                 s = seprintio(s, e, cio, "c");
 1757                 s = seprint(s, e, "\trepl %d ndata %d\n", ep->rhrepl, cio->ndata);
 1758                 break;
 1759         case Tbulk:
 1760         case Tintr:
 1761                 io = ep->aux;
 1762                 if(ep->mode != OWRITE)
 1763                         s = seprintio(s, e, &io[OREAD], "r");
 1764                 if(ep->mode != OREAD)
 1765                         s = seprintio(s, e, &io[OWRITE], "w");
 1766                 break;
 1767         case Tiso:
 1768                 *s = 0;
 1769                 break;
 1770         }
 1771         iunlock(ctlr);
 1772         return s;
 1773 }
 1774 
 1775 /*
 1776  * halt condition was cleared on the endpoint. update our toggles.
 1777  */
 1778 static void
 1779 clrhalt(Ep *ep)
 1780 {
 1781         Qio *io;
 1782         ep->clrhalt = 0;
 1783         switch(ep->ttype){
 1784         case Tintr:
 1785         case Tbulk:
 1786                 io = ep->aux;
 1787                 if(ep->mode != OREAD){
 1788                         qlock(&io[OWRITE]);
 1789                         io[OWRITE].toggle = Tddata0;
 1790                         deprint("ep clrhalt for io %#p\n", io+OWRITE);
 1791                         qunlock(&io[OWRITE]);
 1792                 }
 1793                 if(ep->mode != OWRITE){
 1794                         qlock(&io[OREAD]);
 1795                         io[OREAD].toggle = Tddata0;
 1796                         deprint("ep clrhalt for io %#p\n", io+OREAD);
 1797                         qunlock(&io[OREAD]);
 1798                 }
 1799                 break;
 1800         }
 1801 }
 1802 
 1803 static void
 1804 xdump(char* pref, void *qh)
 1805 {
 1806         int i;
 1807         ulong *u;
 1808 
 1809         u = qh;
 1810         print("%s %#p:", pref, u);
 1811         for(i = 0; i < 16; i++)
 1812                 if((i%4) == 0)
 1813                         print("\n %#8.8ulx", u[i]);
 1814                 else
 1815                         print(" %#8.8ulx", u[i]);
 1816         print("\n");
 1817 }
 1818 
 1819 static long
 1820 episohscpy(Ctlr *ctlr, Ep *ep, Isoio* iso, uchar *b, long count)
 1821 {
 1822         int nr;
 1823         long tot;
 1824         Itd *tdu;
 1825 
 1826         for(tot = 0; iso->tdi != iso->tdu && tot < count; tot += nr){
 1827                 tdu = iso->tdu;
 1828                 if(itdactive(tdu))
 1829                         break;
 1830                 nr = tdu->ndata;
 1831                 if(tot + nr > count)
 1832                         nr = count - tot;
 1833                 if(nr == 0)
 1834                         print("ehci: ep%d.%d: too many polls\n",
 1835                                 ep->dev->nb, ep->nb);
 1836                 else{
 1837                         iunlock(ctlr);          /* We could page fault here */
 1838                         memmove(b+tot, tdu->data, nr);
 1839                         ilock(ctlr);
 1840                         if(nr < tdu->ndata)
 1841                                 memmove(tdu->data, tdu->data+nr, tdu->ndata - nr);
 1842                         tdu->ndata -= nr;
 1843                 }
 1844                 if(tdu->ndata == 0){
 1845                         itdinit(iso, tdu);
 1846                         iso->tdu = tdu->next;
 1847                 }
 1848         }
 1849         return tot;
 1850 }
 1851 
 1852 static long
 1853 episofscpy(Ctlr *ctlr, Ep *ep, Isoio* iso, uchar *b, long count)
 1854 {
 1855         int nr;
 1856         long tot;
 1857         Sitd *stdu;
 1858 
 1859         for(tot = 0; iso->stdi != iso->stdu && tot < count; tot += nr){
 1860                 stdu = iso->stdu;
 1861                 if(stdu->csw & Stdactive){
 1862                         diprint("ehci: episoread: %#p tdu active\n", iso);
 1863                         break;
 1864                 }
 1865                 nr = stdu->ndata;
 1866                 if(tot + nr > count)
 1867                         nr = count - tot;
 1868                 if(nr == 0)
 1869                         print("ehci: ep%d.%d: too many polls\n",
 1870                                 ep->dev->nb, ep->nb);
 1871                 else{
 1872                         iunlock(ctlr);          /* We could page fault here */
 1873                         memmove(b+tot, stdu->data, nr);
 1874                         ilock(ctlr);
 1875                         if(nr < stdu->ndata)
 1876                                 memmove(stdu->data,stdu->data+nr,stdu->ndata - nr);
 1877                         stdu->ndata -= nr;
 1878                 }
 1879                 if(stdu->ndata == 0){
 1880                         sitdinit(iso, stdu);
 1881                         iso->stdu = stdu->next;
 1882                 }
 1883         }
 1884         return tot;
 1885 }
 1886 
 1887 static long
 1888 episoread(Ep *ep, Isoio *iso, void *a, long count)
 1889 {
 1890         Ctlr *ctlr;
 1891         uchar *b;
 1892         long tot;
 1893 
 1894         iso->debug = ep->debug;
 1895         diprint("ehci: episoread: %#p ep%d.%d\n", iso, ep->dev->nb, ep->nb);
 1896 
 1897         b = a;
 1898         ctlr = ep->hp->aux;
 1899         qlock(iso);
 1900         if(waserror()){
 1901                 qunlock(iso);
 1902                 nexterror();
 1903         }
 1904         iso->err = nil;
 1905         iso->nerrs = 0;
 1906         ilock(ctlr);
 1907         if(iso->state == Qclose){
 1908                 iunlock(ctlr);
 1909                 error(iso->err ? iso->err : Eio);
 1910         }
 1911         iso->state = Qrun;
 1912         while(isocanread(iso) == 0){
 1913                 iunlock(ctlr);
 1914                 diprint("ehci: episoread: %#p sleep\n", iso);
 1915                 if(waserror()){
 1916                         if(iso->err == nil)
 1917                                 iso->err = "I/O timed out";
 1918                         ilock(ctlr);
 1919                         break;
 1920                 }
 1921                 tsleep(iso, isocanread, iso, Isotmout);
 1922                 poperror();
 1923                 ilock(ctlr);
 1924         }
 1925         if(iso->state == Qclose){
 1926                 iunlock(ctlr);
 1927                 error(iso->err ? iso->err : Eio);
 1928         }
 1929         iso->state = Qdone;
 1930         assert(iso->tdu != iso->tdi);
 1931 
 1932         if(iso->hs != 0)
 1933                 tot = episohscpy(ctlr, ep, iso, b, count);
 1934         else
 1935                 tot = episofscpy(ctlr, ep, iso, b, count);
 1936         iunlock(ctlr);
 1937         qunlock(iso);
 1938         poperror();
 1939         diprint("uhci: episoread: %#p %uld bytes err '%s'\n", iso, tot, iso->err);
 1940         if(iso->err != nil)
 1941                 error(iso->err);
 1942         return tot;
 1943 }
 1944 
 1945 /*
 1946  * iso->tdu is the next place to put data. When it gets full
 1947  * it is activated and tdu advanced.
 1948  */
 1949 static long
 1950 putsamples(Isoio *iso, uchar *b, long count)
 1951 {
 1952         long tot;
 1953         long n;
 1954 
 1955         for(tot = 0; isocanwrite(iso) && tot < count; tot += n){
 1956                 n = count-tot;
 1957                 if(iso->hs != 0){
 1958                         if(n > iso->tdu->mdata - iso->nleft)
 1959                                 n = iso->tdu->mdata - iso->nleft;
 1960                         memmove(iso->tdu->data+iso->nleft, b+tot, n);
 1961                         iso->nleft += n;
 1962                         if(iso->nleft == iso->tdu->mdata){
 1963                                 itdinit(iso, iso->tdu);
 1964                                 iso->nleft = 0;
 1965                                 iso->tdu = iso->tdu->next;
 1966                         }
 1967                 }else{
 1968                         if(n > iso->stdu->mdata - iso->nleft)
 1969                                 n = iso->stdu->mdata - iso->nleft;
 1970                         memmove(iso->stdu->data+iso->nleft, b+tot, n);
 1971                         iso->nleft += n;
 1972                         if(iso->nleft == iso->stdu->mdata){
 1973                                 sitdinit(iso, iso->stdu);
 1974                                 iso->nleft = 0;
 1975                                 iso->stdu = iso->stdu->next;
 1976                         }
 1977                 }
 1978         }
 1979         return tot;
 1980 }
 1981 
 1982 /*
 1983  * Queue data for writing and return error status from
 1984  * last writes done, to maintain buffered data.
 1985  */
 1986 static long
 1987 episowrite(Ep *ep, Isoio *iso, void *a, long count)
 1988 {
 1989         Ctlr *ctlr;
 1990         uchar *b;
 1991         int tot;
 1992         int nw;
 1993         char *err;
 1994 
 1995         iso->debug = ep->debug;
 1996         diprint("ehci: episowrite: %#p ep%d.%d\n", iso, ep->dev->nb, ep->nb);
 1997 
 1998         ctlr = ep->hp->aux;
 1999         qlock(iso);
 2000         if(waserror()){
 2001                 qunlock(iso);
 2002                 nexterror();
 2003         }
 2004         ilock(ctlr);
 2005         if(iso->state == Qclose){
 2006                 iunlock(ctlr);
 2007                 error(iso->err ? iso->err : Eio);
 2008         }
 2009         iso->state = Qrun;
 2010         b = a;
 2011         for(tot = 0; tot < count; tot += nw){
 2012                 while(isocanwrite(iso) == 0){
 2013                         iunlock(ctlr);
 2014                         diprint("ehci: episowrite: %#p sleep\n", iso);
 2015                         if(waserror()){
 2016                                 if(iso->err == nil)
 2017                                         iso->err = "I/O timed out";
 2018                                 ilock(ctlr);
 2019                                 break;
 2020                         }
 2021                         tsleep(iso, isocanwrite, iso, Isotmout);
 2022                         poperror();
 2023                         ilock(ctlr);
 2024                 }
 2025                 err = iso->err;
 2026                 iso->err = nil;
 2027                 if(iso->state == Qclose || err != nil){
 2028                         iunlock(ctlr);
 2029                         error(err ? err : Eio);
 2030                 }
 2031                 if(iso->state != Qrun)
 2032                         panic("episowrite: iso not running");
 2033                 iunlock(ctlr);          /* We could page fault here */
 2034                 nw = putsamples(iso, b+tot, count-tot);
 2035                 ilock(ctlr);
 2036         }
 2037         if(iso->state != Qclose)
 2038                 iso->state = Qdone;
 2039         iunlock(ctlr);
 2040         err = iso->err;         /* in case it failed early */
 2041         iso->err = nil;
 2042         qunlock(iso);
 2043         poperror();
 2044         if(err != nil)
 2045                 error(err);
 2046         diprint("ehci: episowrite: %#p %d bytes\n", iso, tot);
 2047         return tot;
 2048 }
 2049 
 2050 static int
 2051 nexttoggle(int toggle, int count, int maxpkt)
 2052 {
 2053         int np;
 2054 
 2055         np = count / maxpkt;
 2056         if(np == 0)
 2057                 np = 1;
 2058         if((np % 2) == 0)
 2059                 return toggle;
 2060         if(toggle == Tddata1)
 2061                 return Tddata0;
 2062         else
 2063                 return Tddata1;
 2064 }
 2065 
 2066 static Td*
 2067 epgettd(Qio *io, int flags, void *a, int count, int maxpkt)
 2068 {
 2069         Td *td;
 2070         ulong pa;
 2071         int i;
 2072         if(count > Tdmaxpkt)
 2073                 panic("ehci: epgettd: too many bytes");
 2074         td = tdalloc();
 2075         td->csw = flags;
 2076         td->csw |= io->toggle | io->tok | (count << Tdlenshift);
 2077         td->csw |= Tderr2|Tderr1;
 2078 
 2079         /*
 2080          * use the space wasted by alignment as an
 2081          * embedded buffer if count bytes fit in there.
 2082          */
 2083         assert(Align > sizeof(Td));
 2084         if(count <= Align - sizeof(Td))
 2085                 td->data = td->sbuff;
 2086         else
 2087                 td->data = td->buff = smalloc(Tdmaxpkt);
 2088 
 2089         pa = PADDR(td->data);
 2090         for(i = 0; i < nelem(td->buffer); i++){
 2091                 td->buffer[i] = pa;
 2092                 if(i > 0)
 2093                         td->buffer[i] &= ~0xFFF;
 2094                 pa += 0x1000;
 2095         }
 2096         td->ndata = count;
 2097         if(a != nil && count > 0)
 2098                 memmove(td->data, a, count);
 2099         io->toggle = nexttoggle(io->toggle, count, maxpkt);
 2100         return td;
 2101 }
 2102 
 2103 /*
 2104  * Try to get them idle
 2105  */
 2106 static void
 2107 aborttds(Qh *qh)
 2108 {
 2109         Td *td;
 2110 
 2111         qh->state = Qdone;
 2112         if(qh->sched >= 0 && (qh->eps0&Qhspeedmask) != Qhhigh)
 2113                 qh->eps0 |= Qhint;      /* inactivate on next pass */
 2114         for(td = qh->tds; td != nil; td = td->next){
 2115                 if(td->csw & Tdactive)
 2116                         td->ndata = 0;
 2117                 td->csw |= Tdhalt;
 2118         }
 2119 }
 2120 
 2121 /*
 2122  * Some controllers do not post the usb/error interrupt after
 2123  * the work has been done. It seems that we must poll for them.
 2124  */
 2125 static int
 2126 workpending(void *a)
 2127 {
 2128         Ctlr *ctlr;
 2129 
 2130         ctlr = a;
 2131         return ctlr->nreqs > 0;
 2132 }
 2133 
 2134 static void
 2135 ehcipoll(void* a)
 2136 {
 2137         Hci *hp;
 2138         Ctlr *ctlr;
 2139         Poll *poll;
 2140         int i;
 2141 
 2142         hp = a;
 2143         ctlr = hp->aux;
 2144         poll = &ctlr->poll;
 2145         for(;;){
 2146                 if(ctlr->nreqs == 0){
 2147                         if(0)ddprint("ehcipoll %#p sleep\n", ctlr->capio);
 2148                         sleep(poll, workpending, ctlr);
 2149                         if(0)ddprint("ehcipoll %#p awaken\n", ctlr->capio);
 2150                 }
 2151                 for(i = 0; i < 16 && ctlr->nreqs > 0; i++)
 2152                         if(ehciintr(hp) == 0)
 2153                                  break;
 2154                 do{
 2155                         tsleep(&up->sleep, return0, 0, 1);
 2156                         ehciintr(hp);
 2157                 }while(ctlr->nreqs > 0);
 2158         }
 2159 }
 2160 
 2161 static void
 2162 pollcheck(Hci *hp)
 2163 {
 2164         Ctlr *ctlr;
 2165         Poll *poll;
 2166 
 2167         ctlr = hp->aux;
 2168         poll = &ctlr->poll;
 2169 
 2170         if(poll->must != 0 && poll->does == 0){
 2171                 lock(poll);
 2172                 if(poll->must != 0 && poll->does == 0){
 2173                         poll->does++;
 2174                         print("ehci %#p: polling\n", ctlr->capio);
 2175                         kproc("ehcipoll", ehcipoll, hp);
 2176                 }
 2177                 unlock(poll);
 2178         }
 2179 }
 2180 
 2181 static int
 2182 epiodone(void *a)
 2183 {
 2184         Qh *qh;
 2185 
 2186         qh = a;
 2187         return qh->state != Qrun;
 2188 }
 2189 
 2190 static void
 2191 epiowait(Hci *hp, Qio *io, int tmout, ulong load)
 2192 {
 2193         Qh *qh;
 2194         int timedout;
 2195         Ctlr *ctlr;
 2196 
 2197         ctlr = hp->aux;
 2198         qh = io->qh;
 2199         ddqprint("ehci io %#p sleep on qh %#p state %s\n",
 2200                 io, qh, qhsname[qh->state]);
 2201         timedout = 0;
 2202         if(waserror()){
 2203                 dqprint("ehci io %#p qh %#p timed out\n", io, qh);
 2204                 timedout++;
 2205         }else{
 2206                 if(tmout == 0)
 2207                         sleep(io, epiodone, qh);
 2208                 else
 2209                         tsleep(io, epiodone, qh, tmout);
 2210                 poperror();
 2211         }
 2212 
 2213         ilock(ctlr);
 2214         /* Are we missing interrupts? */
 2215         if(qh->state == Qrun){
 2216                 iunlock(ctlr);
 2217                 ehciintr(hp);
 2218                 ilock(ctlr);
 2219                 if(qh->state == Qdone){
 2220                         dqprint("ehci %#p: polling required\n", ctlr->capio);
 2221                         ctlr->poll.must = 1;
 2222                         pollcheck(hp);
 2223                 }
 2224         }
 2225 
 2226         if(qh->state == Qrun){
 2227                 dqprint("ehci io %#p qh %#p timed out (no intr?)\n", io, qh);
 2228                 timedout = 1;
 2229         }else if(qh->state != Qdone && qh->state != Qclose)
 2230                 panic("ehci: epio: queue state %d", qh->state);
 2231         if(timedout){
 2232                 aborttds(io->qh);
 2233                 io->err = "request timed out";
 2234                 iunlock(ctlr);
 2235                 if(!waserror()){
 2236                         tsleep(&up->sleep, return0, 0, Abortdelay);
 2237                         poperror();
 2238                 }
 2239                 ilock(ctlr);
 2240         }
 2241         if(qh->state != Qclose)
 2242                 qh->state = Qidle;
 2243         qhlinktd(qh, nil);
 2244         ctlr->load -= load;
 2245         ctlr->nreqs--;
 2246         iunlock(ctlr);
 2247 }
 2248 
 2249 /*
 2250  * Non iso I/O.
 2251  * To make it work for control transfers, the caller may
 2252  * lock the Qio for the entire control transfer.
 2253  * If tmout is not 0 it is a timeout value in ms.
 2254  *
 2255  */
 2256 static long
 2257 epio(Ep *ep, Qio *io, void *a, long count, int tmout, int mustlock)
 2258 {
 2259         Td *td;
 2260         Td *ltd;
 2261         Td *td0;
 2262         Td *ntd;
 2263         Ctlr *ctlr;
 2264         Qh* qh;
 2265         long n;
 2266         long tot;
 2267         char buf[128];
 2268         uchar *c;
 2269         int saved;
 2270         int ntds;
 2271         ulong load;
 2272         char *err;
 2273 
 2274         qh = io->qh;
 2275         ctlr = ep->hp->aux;
 2276         io->debug = ep->debug;
 2277         ddeprint("epio: %s ep%d.%d io %#p count %ld load %uld\n",
 2278                 io->tok == Tdtokin ? "in" : "out",
 2279                 ep->dev->nb, ep->nb, io, count, ctlr->load);
 2280         if((debug > 1 || ep->debug > 1) && io->tok != Tdtokin){
 2281                 seprintdata(buf, buf+sizeof(buf), a, count);
 2282                 print("echi epio: user data: %s\n", buf);
 2283         }
 2284         if(mustlock){
 2285                 qlock(io);
 2286                 if(waserror()){
 2287                         qunlock(io);
 2288                         nexterror();
 2289                 }
 2290         }
 2291         io->err = nil;
 2292         ilock(ctlr);
 2293         if(qh->state == Qclose){        /* Tds released by cancelio */
 2294                 iunlock(ctlr);
 2295                 error(io->err ? io->err : Eio);
 2296         }
 2297         if(qh->state != Qidle)
 2298                 panic("epio: qh not idle");
 2299         qh->state = Qinstall;
 2300         iunlock(ctlr);
 2301 
 2302         c = a;
 2303         td0 = ltd = nil;
 2304         load = tot = 0;
 2305         do{
 2306                 n = (Tdmaxpkt / ep->maxpkt) * ep->maxpkt;
 2307                 if(count-tot < n)
 2308                         n = count-tot;
 2309                 if(io->tok != Tdtokin)
 2310                         td = epgettd(io, Tdactive, c+tot, n, ep->maxpkt);
 2311                 else
 2312                         td = epgettd(io, Tdactive, nil, n, ep->maxpkt);
 2313                 if(td0 == nil)
 2314                         td0 = td;
 2315                 else
 2316                         tdlinktd(ltd, td);
 2317                 ltd = td;
 2318                 tot += n;
 2319                 load += ep->load;
 2320         }while(tot < count);
 2321         if(td0 == nil || ltd == nil)
 2322                 panic("epio: no td");
 2323 
 2324         ltd->csw |= Tdioc;      /* the last one interrupts */
 2325 
 2326         ddeprint("ehci: load %uld ctlr load %uld\n", load, ctlr->load);
 2327         if(debug > 1 || ep->debug > 1)
 2328                 dumptd(td0, "epio: put: ");
 2329 
 2330         ilock(ctlr);
 2331         if(qh->state != Qclose){
 2332                 io->iotime = TK2MS(MACHP(0)->ticks);
 2333                 qh->state = Qrun;
 2334                 qhlinktd(qh, td0);
 2335                 ctlr->nreqs++;
 2336                 ctlr->load += load;
 2337         }
 2338         iunlock(ctlr);
 2339 
 2340         if(ctlr->poll.does)
 2341                 wakeup(&ctlr->poll);
 2342 
 2343         epiowait(ep->hp, io, tmout, load);
 2344         if(debug > 1 || ep->debug > 1){
 2345                 dumptd(td0, "epio: got: ");
 2346                 qhdump(qh);
 2347         }
 2348 
 2349         tot = 0;
 2350         c = a;
 2351         saved = 0;
 2352         ntds = 0;
 2353         for(td = td0; td != nil; td = ntd){
 2354                 ntds++;
 2355                 /*
 2356                  * Use td tok, not io tok, because of setup packets.
 2357                  * Also, if the Td was stalled or active (previous Td
 2358                  * was a short packet), we must save the toggle as it is.
 2359                  */
 2360                 if(td->csw & (Tdhalt|Tdactive)){
 2361                         if(saved++ == 0)
 2362                                 io->toggle = td->csw & Tddata1;
 2363                 }else{
 2364                         tot += td->ndata;
 2365                         if((td->csw & Tdtok) == Tdtokin && td->ndata > 0){
 2366                                 memmove(c, td->data, td->ndata);
 2367                                 c += td->ndata;
 2368                         }
 2369                 }
 2370                 ntd = td->next;
 2371                 tdfree(td);
 2372         }
 2373         err = io->err;
 2374         if(mustlock){
 2375                 qunlock(io);
 2376                 poperror();
 2377         }
 2378         ddeprint("epio: io %#p: %d tds: return %ld err '%s'\n",
 2379                 io, ntds, tot, err);
 2380         if(err == Estalled)
 2381                 return 0;       /* that's our convention */
 2382         if(err != nil)
 2383                 error(err);
 2384         if(tot < 0)
 2385                 error(Eio);
 2386         return tot;
 2387 }
 2388 
 2389 static long
 2390 epread(Ep *ep, void *a, long count)
 2391 {
 2392         Ctlio *cio;
 2393         Qio *io;
 2394         Isoio *iso;
 2395         char buf[160];
 2396         ulong delta;
 2397 
 2398         ddeprint("ehci: epread\n");
 2399         if(ep->aux == nil)
 2400                 panic("epread: not open");
 2401 
 2402         pollcheck(ep->hp);
 2403 
 2404         switch(ep->ttype){
 2405         case Tctl:
 2406                 cio = ep->aux;
 2407                 qlock(cio);
 2408                 if(waserror()){
 2409                         qunlock(cio);
 2410                         nexterror();
 2411                 }
 2412                 ddeprint("epread ctl ndata %d\n", cio->ndata);
 2413                 if(cio->ndata < 0)
 2414                         error("request expected");
 2415                 else if(cio->ndata == 0){
 2416                         cio->ndata = -1;
 2417                         count = 0;
 2418                 }else{
 2419                         if(count > cio->ndata)
 2420                                 count = cio->ndata;
 2421                         if(count > 0)
 2422                                 memmove(a, cio->data, count);
 2423                         /* BUG for big transfers */
 2424                         free(cio->data);
 2425                         cio->data = nil;
 2426                         cio->ndata = 0; /* signal EOF next time */
 2427                 }
 2428                 qunlock(cio);
 2429                 poperror();
 2430                 if(debug>1 || ep->debug){
 2431                         seprintdata(buf, buf+sizeof(buf), a, count);
 2432                         print("epread: %s\n", buf);
 2433                 }
 2434                 return count;
 2435         case Tbulk:
 2436                 io = ep->aux;
 2437                 if(ep->clrhalt)
 2438                         clrhalt(ep);
 2439                 return epio(ep, &io[OREAD], a, count, Bulktmout, 1);
 2440         case Tintr:
 2441                 io = ep->aux;
 2442                 delta = TK2MS(MACHP(0)->ticks) - io[OREAD].iotime + 1;
 2443                 if(delta < ep->pollival / 2)
 2444                         tsleep(&up->sleep, return0, 0, ep->pollival/2 - delta);
 2445                 if(ep->clrhalt)
 2446                         clrhalt(ep);
 2447                 return epio(ep, &io[OREAD], a, count, 0, 1);
 2448         case Tiso:
 2449                 iso = ep->aux;
 2450                 return episoread(ep, iso, a, count);
 2451         }
 2452         return -1;
 2453 }
 2454 
 2455 /*
 2456  * Control transfers are one setup write (data0)
 2457  * plus zero or more reads/writes (data1, data0, ...)
 2458  * plus a final write/read with data1 to ack.
 2459  * For both host to device and device to host we perform
 2460  * the entire transfer when the user writes the request,
 2461  * and keep any data read from the device for a later read.
 2462  * We call epio three times instead of placing all Tds at
 2463  * the same time because doing so leads to crc/tmout errors
 2464  * for some devices.
 2465  * Upon errors on the data phase we must still run the status
 2466  * phase or the device may cease responding in the future.
 2467  */
 2468 static long
 2469 epctlio(Ep *ep, Ctlio *cio, void *a, long count)
 2470 {
 2471         uchar *c;
 2472         long len;
 2473 
 2474         ddeprint("epctlio: cio %#p ep%d.%d count %ld\n",
 2475                 cio, ep->dev->nb, ep->nb, count);
 2476         if(count < Rsetuplen)
 2477                 error("short usb comand");
 2478         qlock(cio);
 2479         free(cio->data);
 2480         cio->data = nil;
 2481         cio->ndata = 0;
 2482         if(waserror()){
 2483                 qunlock(cio);
 2484                 free(cio->data);
 2485                 cio->data = nil;
 2486                 cio->ndata = 0;
 2487                 nexterror();
 2488         }
 2489 
 2490         /* set the address if unset and out of configuration state */
 2491         if(ep->dev->state != Dconfig && cio->usbid == 0){
 2492                 cio->usbid = ((ep->nb&Epmax)<<7)|(ep->dev->nb&Devmax);
 2493                 qhsetaddr(cio->qh, cio->usbid);
 2494         }
 2495         /* adjust maxpkt if the user has learned a different one */
 2496         if(qhmaxpkt(cio->qh) != ep->maxpkt)
 2497                 qhsetmaxpkt(cio->qh, ep->maxpkt);
 2498         c = a;
 2499         cio->tok = Tdtoksetup;
 2500         cio->toggle = Tddata0;
 2501         if(epio(ep, cio, a, Rsetuplen, Ctltmout, 0) < Rsetuplen)
 2502                 error(Eio);
 2503         a = c + Rsetuplen;
 2504         count -= Rsetuplen;
 2505 
 2506         cio->toggle = Tddata1;
 2507         if(c[Rtype] & Rd2h){
 2508                 cio->tok = Tdtokin;
 2509                 len = GET2(c+Rcount);
 2510                 if(len <= 0)
 2511                         error("bad length in d2h request");
 2512                 if(len > Maxctllen)
 2513                         error("d2h data too large to fit in ehci");
 2514                 a = cio->data = smalloc(len+1);
 2515         }else{
 2516                 cio->tok = Tdtokout;
 2517                 len = count;
 2518         }
 2519         if(len > 0)
 2520                 if(waserror())
 2521                         len = -1;
 2522                 else{
 2523                         len = epio(ep, cio, a, len, Ctltmout, 0);
 2524                         poperror();
 2525                 }
 2526         if(c[Rtype] & Rd2h){
 2527                 count = Rsetuplen;
 2528                 cio->ndata = len;
 2529                 cio->tok = Tdtokout;
 2530         }else{
 2531                 if(len < 0)
 2532                         count = -1;
 2533                 else
 2534                         count = Rsetuplen + len;
 2535                 cio->tok = Tdtokin;
 2536         }
 2537         cio->toggle = Tddata1;
 2538         epio(ep, cio, nil, 0, Ctltmout, 0);
 2539         qunlock(cio);
 2540         poperror();
 2541         ddeprint("epctlio cio %#p return %ld\n", cio, count);
 2542         return count;
 2543 }
 2544 
 2545 static long
 2546 epwrite(Ep *ep, void *a, long count)
 2547 {
 2548         Qio *io;
 2549         Ctlio *cio;
 2550         Isoio *iso;
 2551         ulong delta;
 2552 
 2553         pollcheck(ep->hp);
 2554 
 2555         ddeprint("ehci: epwrite ep%d.%d\n", ep->dev->nb, ep->nb);
 2556         if(ep->aux == nil)
 2557                 panic("ehci: epwrite: not open");
 2558         switch(ep->ttype){
 2559         case Tctl:
 2560                 cio = ep->aux;
 2561                 return epctlio(ep, cio, a, count);
 2562         case Tbulk:
 2563                 io = ep->aux;
 2564                 if(ep->clrhalt)
 2565                         clrhalt(ep);
 2566                 return epio(ep, &io[OWRITE], a, count, Bulktmout, 1);
 2567         case Tintr:
 2568                 io = ep->aux;
 2569                 delta = TK2MS(MACHP(0)->ticks) - io[OWRITE].iotime + 1;
 2570                 if(delta < ep->pollival)
 2571                         tsleep(&up->sleep, return0, 0, ep->pollival - delta);
 2572                 if(ep->clrhalt)
 2573                         clrhalt(ep);
 2574                 return epio(ep, &io[OWRITE], a, count, 0, 1);
 2575         case Tiso:
 2576                 iso = ep->aux;
 2577                 return episowrite(ep, iso, a, count);
 2578         }
 2579         return -1;
 2580 }
 2581 
 2582 static void
 2583 isofsinit(Ep *ep, Isoio *iso)
 2584 {
 2585         long left;
 2586         Sitd *td;
 2587         Sitd *ltd;
 2588         int i;
 2589         ulong frno;
 2590 
 2591         left = 0;
 2592         ltd = nil;
 2593         frno = iso->td0frno;
 2594         for(i = 0; i < iso->nframes; i++){
 2595                 td = iso->sitdps[frno] = sitdalloc();
 2596                 td->data = iso->data + i * ep->maxpkt;
 2597                 td->epc = ep->dev->port << Stdportshift;
 2598                 td->epc |= ep->dev->hub << Stdhubshift;
 2599                 td->epc |= ep->nb << Stdepshift;
 2600                 td->epc |= ep->dev->nb << Stddevshift;
 2601                 td->mfs = (034 << Stdscmshift) | (1 << Stdssmshift);
 2602                 if(ep->mode == OREAD){
 2603                         td->epc |= Stdin;
 2604                         td->mdata = ep->maxpkt;
 2605                 }else{
 2606                         td->mdata = (ep->hz+left) * ep->pollival / 1000;
 2607                         td->mdata *= ep->samplesz;
 2608                         left = (ep->hz+left) * ep->pollival % 1000;
 2609                         if(td->mdata > ep->maxpkt){
 2610                                 print("ehci: ep%d.%d: size > maxpkt\n",
 2611                                         ep->dev->nb, ep->nb);
 2612                                 print("size = %ld max = %ld\n",
 2613                                         td->mdata,ep->maxpkt);
 2614                                 td->mdata = ep->maxpkt;
 2615                         }
 2616                 }
 2617 
 2618                 sitdinit(iso, td);
 2619                 if(ltd != nil)
 2620                         ltd->next = td;
 2621                 ltd = td;
 2622                 frno = TRUNC(frno+ep->pollival, Nisoframes);
 2623         }
 2624         ltd->next = iso->sitdps[iso->td0frno];
 2625 }
 2626 
 2627 static void
 2628 isohsinit(Ep *ep, Isoio *iso)
 2629 {
 2630         long left;
 2631         Itd *td;
 2632         Itd *ltd;
 2633         ulong i;
 2634         ulong pa;
 2635         int p;
 2636         ulong frno;
 2637         int ival;
 2638 
 2639         iso->hs = 1;
 2640         ival = 1;
 2641         if(ep->pollival > 8)
 2642                 ival = ep->pollival/8;
 2643         left = 0;
 2644         ltd = nil;
 2645         frno = iso->td0frno;
 2646         for(i = 0; i < iso->nframes; i++){
 2647                 td = iso->itdps[frno] = itdalloc();
 2648                 td->data = iso->data + i * 8  * iso->maxsize;
 2649                 pa = PADDR(td->data) & ~0xFFF;
 2650                 for(p = 0; p < 8; p++)
 2651                         td->buffer[i] = pa + p * 0x1000;
 2652                 td->buffer[0] = PADDR(iso->data) & ~0xFFF;
 2653                 td->buffer[0] |= ep->nb << Itdepshift;
 2654                 td->buffer[0] |= ep->dev->nb << Itddevshift;
 2655                 if(ep->mode == OREAD)
 2656                         td->buffer[1] |= Itdin;
 2657                 else
 2658                         td->buffer[1] |= Itdout;
 2659                 td->buffer[1] |= ep->maxpkt << Itdmaxpktshift;
 2660                 td->buffer[2] |= ep->ntds << Itdntdsshift;
 2661 
 2662                 if(ep->mode == OREAD)
 2663                         td->mdata = 8 * iso->maxsize;
 2664                 else{
 2665                         td->mdata = (ep->hz + left) * ep->pollival / 1000;
 2666                         td->mdata *= ep->samplesz;
 2667                         left = (ep->hz + left) * ep->pollival % 1000;
 2668                 }
 2669                 itdinit(iso, td);
 2670                 if(ltd != nil)
 2671                         ltd->next = td;
 2672                 ltd = td;
 2673                 frno = TRUNC(frno + ival, Nisoframes);
 2674         }
 2675 }
 2676 
 2677 static void
 2678 isoopen(Ctlr *ctlr, Ep *ep)
 2679 {
 2680         Isoio *iso;
 2681         int ival;       /* pollival in ms */
 2682         int n;
 2683         ulong frno;
 2684         int i;
 2685         int w;
 2686         int woff;
 2687         int tpf;                /* tds per frame */
 2688 
 2689         iso = ep->aux;
 2690         switch(ep->mode){
 2691         case OREAD:
 2692                 iso->tok = Tdtokin;
 2693                 break;
 2694         case OWRITE:
 2695                 iso->tok = Tdtokout;
 2696                 break;
 2697         default:
 2698                 error("iso i/o is half-duplex");
 2699         }
 2700         iso->usbid = (ep->nb<<7)|(ep->dev->nb & Devmax);
 2701         iso->state = Qidle;
 2702         iso->debug = ep->debug;
 2703         ival = ep->pollival;
 2704         tpf = 1;
 2705         if(ep->dev->speed == Highspeed){
 2706                 tpf = 8;
 2707                 if(ival <= 8)
 2708                         ival = 1;
 2709                 else
 2710                         ival /= 8;
 2711         }
 2712         iso->nframes = Nisoframes / ival;
 2713         if(iso->nframes < 3)
 2714                 error("uhci isoopen bug");      /* we need at least 3 tds */
 2715         iso->maxsize = ep->ntds * ep->maxpkt;
 2716         ilock(ctlr);
 2717         if(ctlr->load + ep->load > 800){
 2718                 iunlock(ctlr);
 2719                 error("bandwidth exceeded");
 2720         }
 2721         ctlr->load += ep->load;
 2722         ctlr->isoload += ep->load;
 2723         ctlr->nreqs++;
 2724         dprint("ehci: load %uld isoload %uld\n", ctlr->load, ctlr->isoload);
 2725         diprint("iso nframes %d pollival %uld ival %d maxpkt %uld ntds %d\n",
 2726                 iso->nframes, ep->pollival, ival, ep->maxpkt, ep->ntds);
 2727         iunlock(ctlr);
 2728         if(ctlr->poll.does)
 2729                 wakeup(&ctlr->poll);
 2730 
 2731         /*
 2732          * From here on this cannot raise errors
 2733          * unless we catch them and release here all memory allocated.
 2734          */
 2735         assert(ep->maxpkt > 0 && ep->ntds > 0 && ep->ntds < 4);
 2736         assert(ep->maxpkt <= 1024);
 2737         iso->tdps = smalloc(sizeof(uintptr) * Nisoframes);
 2738         iso->data = smalloc(iso->nframes * tpf * ep->ntds * ep->maxpkt);
 2739         iso->td0frno = TRUNC(ctlr->opio->frno + 10, Nisoframes);
 2740         /* read: now; write: 1s ahead */
 2741 
 2742         if(ep->dev->speed == Highspeed)
 2743                 isohsinit(ep, iso);
 2744         else
 2745                 isofsinit(ep, iso);
 2746         iso->tdu = iso->tdi = iso->itdps[iso->td0frno];
 2747         iso->stdu = iso->stdi = iso->sitdps[iso->td0frno];
 2748 
 2749         ilock(ctlr);
 2750         frno = iso->td0frno;
 2751         for(i = 0; i < iso->nframes; i++){
 2752                 *iso->tdps[frno] = ctlr->frames[frno];
 2753                 frno = TRUNC(frno+ival, Nisoframes);
 2754         }
 2755 
 2756         /*
 2757          * Iso uses a virtual frame window of Nisoframes, and we must
 2758          * fill the actual ctlr frame array by placing ctlr->nframes/Nisoframes
 2759          * copies of the window in the frame array.
 2760          */
 2761         assert(ctlr->nframes >= Nisoframes && Nisoframes >= iso->nframes);
 2762         assert(Nisoframes >= Nintrleafs);
 2763         n = ctlr->nframes / Nisoframes;
 2764         for(w = 0; w < n; w++){
 2765                 frno = iso->td0frno;
 2766                 woff = w * Nisoframes;
 2767                 for(i = 0; i < iso->nframes ; i++){
 2768                         assert(woff+frno < ctlr->nframes);
 2769                         assert(iso->tdps[frno] != nil);
 2770                         if(ep->dev->speed == Highspeed)
 2771                                 ctlr->frames[woff+frno] = PADDR(iso->tdps[frno])|Litd;
 2772                         else
 2773                                 ctlr->frames[woff+frno] = PADDR(iso->tdps[frno])|Lsitd;
 2774                         frno = TRUNC(frno+ep->pollival, Nisoframes);
 2775                 }
 2776         }
 2777         iso->next = ctlr->iso;
 2778         ctlr->iso = iso;
 2779         iso->state = Qdone;
 2780         iunlock(ctlr);
 2781         if(debug > 1 || iso->debug >1)
 2782                 isodump(iso, 0);
 2783 
 2784 
 2785 }
 2786 
 2787 /*
 2788  * Allocate the endpoint and set it up for I/O
 2789  * in the controller. This must follow what's said
 2790  * in Ep regarding configuration, including perhaps
 2791  * the saved toggles (saved on a previous close of
 2792  * the endpoint data file by epclose).
 2793  */
 2794 static void
 2795 epopen(Ep *ep)
 2796 {
 2797         Ctlr *ctlr;
 2798         Ctlio *cio;
 2799         Qio *io;
 2800         int usbid;
 2801 
 2802         ctlr = ep->hp->aux;
 2803         deprint("ehci: epopen ep%d.%d\n", ep->dev->nb, ep->nb);
 2804         if(ep->aux != nil)
 2805                 panic("ehci: epopen called with open ep");
 2806         if(waserror()){
 2807                 free(ep->aux);
 2808                 ep->aux = nil;
 2809                 nexterror();
 2810         }
 2811         switch(ep->ttype){
 2812         case Tnone:
 2813                 error("endpoint not configured");
 2814         case Tiso:
 2815                 ep->aux = smalloc(sizeof(Isoio));
 2816                 isoopen(ctlr, ep);
 2817                 break;
 2818         case Tctl:
 2819                 cio = ep->aux = smalloc(sizeof(Ctlio));
 2820                 cio->debug = ep->debug;
 2821                 cio->ndata = -1;
 2822                 cio->data = nil;
 2823                 if(ep->dev->isroot != 0 && ep->nb == 0) /* root hub */
 2824                         break;
 2825                 cio->qh = qhalloc(ctlr, ep, cio, "epc");
 2826                 break;
 2827         case Tbulk:
 2828                 ep->pollival = 1;       /* assume this; doesn't really matter */
 2829                 /* and fall... */
 2830         case Tintr:
 2831                 io = ep->aux = smalloc(sizeof(Qio)*2);
 2832                 io[OREAD].debug = io[OWRITE].debug = ep->debug;
 2833                 usbid = ((ep->nb&Epmax)<<7)|(ep->dev->nb &Devmax);
 2834                 if(ep->mode != OREAD){
 2835                         if(ep->toggle[OWRITE] != 0)
 2836                                 io[OWRITE].toggle = Tddata1;
 2837                         else
 2838                                 io[OWRITE].toggle = Tddata0;
 2839                         io[OWRITE].tok = Tdtokout;
 2840                         io[OWRITE].usbid = usbid;
 2841                         io[OWRITE].bw = ep->maxpkt*1000/ep->pollival; /* bytes/s */
 2842                         io[OWRITE].qh = qhalloc(ctlr, ep, io+OWRITE, "epw");
 2843                 }
 2844                 if(ep->mode != OWRITE){
 2845                         if(ep->toggle[OREAD] != 0)
 2846                                 io[OREAD].toggle = Tddata1;
 2847                         else
 2848                                 io[OREAD].toggle = Tddata0;
 2849                         io[OREAD].tok = Tdtokin;
 2850                         io[OREAD].usbid = usbid;
 2851                         io[OREAD].bw = ep->maxpkt*1000/ep->pollival; /* bytes/s */
 2852                         io[OREAD].qh = qhalloc(ctlr, ep, io+OREAD, "epr");
 2853                 }
 2854                 break;
 2855         }
 2856         if(debug>1 || ep->debug)
 2857                 dump(ep->hp);
 2858         deprint("ehci: epopen done\n");
 2859         poperror();
 2860 }
 2861 
 2862 static void
 2863 cancelio(Ctlr *ctlr, Qio *io)
 2864 {
 2865         Qh *qh;
 2866 
 2867         ilock(ctlr);
 2868         qh = io->qh;
 2869         if(io == nil || io->qh == nil || io->qh->state == Qclose){
 2870                 iunlock(ctlr);
 2871                 return;
 2872         }
 2873         dqprint("ehci: cancelio for qh %#p state %s\n",
 2874                 qh, qhsname[qh->state]);
 2875         aborttds(qh);
 2876         qh->state = Qclose;
 2877         iunlock(ctlr);
 2878         if(!waserror()){
 2879                 tsleep(&up->sleep, return0, 0, Abortdelay);
 2880                 poperror();
 2881         }
 2882         wakeup(io);
 2883         qlock(io);
 2884         /* wait for epio if running */
 2885         qunlock(io);
 2886 
 2887         qhfree(ctlr, qh);
 2888         io->qh = nil;
 2889 }
 2890 
 2891 static void
 2892 cancelisoio(Ctlr *ctlr, Isoio *iso, int pollival, ulong load)
 2893 {
 2894         Isoio **il;
 2895         ulong *lp;
 2896         int i;
 2897         int frno;
 2898         int w;
 2899         int n;
 2900         int woff;
 2901         ulong *tp;
 2902         Itd *td;
 2903         Sitd *std;
 2904         int t;
 2905 
 2906         ilock(ctlr);
 2907         if(iso->state == Qclose){
 2908                 iunlock(ctlr);
 2909                 return;
 2910         }
 2911         ctlr->nreqs--;
 2912         if(iso->state != Qrun && iso->state != Qdone)
 2913                 panic("bad iso state");
 2914         iso->state = Qclose;
 2915         if(ctlr->isoload < load)
 2916                 panic("ehci: low isoload");
 2917         ctlr->isoload -= load;
 2918         ctlr->load -= load;
 2919         for(il = &ctlr->iso; *il != nil; il = &(*il)->next)
 2920                 if(*il == iso)
 2921                         break;
 2922         if(*il == nil)
 2923                 panic("cancleiso: not found");
 2924         *il = iso->next;
 2925 
 2926         frno = iso->td0frno;
 2927         for(i = 0; i < iso->nframes; i++){
 2928                 tp = iso->tdps[frno];
 2929                 if(iso->hs != 0){
 2930                         td = iso->itdps[frno];
 2931                         for(t = 0; t < nelem(td->csw); t++)
 2932                                 td->csw[1] &= ~(Itdioc|Itdactive);
 2933                 }else{
 2934                         std = iso->sitdps[frno];
 2935                         std->csw &= ~(Stdioc|Stdactive);
 2936                 }
 2937                 for(lp=&ctlr->frames[frno]; !(*lp & Lterm); lp = &LPTR(*lp)[0])
 2938                         if(LPTR(*lp) == tp)
 2939                                 break;
 2940                 if(*lp & Lterm)
 2941                         panic("cancelisoio: td not found");
 2942                 *lp = tp[0];
 2943                 /*
 2944                  * Iso uses a virtual frame window of Nisoframes, and we must
 2945                  * restore pointers in copies of the window kept at ctlr->frames.
 2946                  */
 2947                 if(lp == &ctlr->frames[frno]){
 2948                         n = ctlr->nframes / Nisoframes;
 2949                         for(w = 1; w < n; w++){
 2950                                 woff = w * Nisoframes;
 2951                                 ctlr->frames[woff+frno] = *lp;
 2952                         }
 2953                 }
 2954                 frno = TRUNC(frno+pollival, Nisoframes);
 2955         }
 2956         iunlock(ctlr);
 2957 
 2958         /*
 2959          * wakeup anyone waiting for I/O and
 2960          * wait to be sure no I/O is in progress in the controller.
 2961          * and then wait to be sure episo* is no longer running.
 2962          */
 2963         wakeup(iso);
 2964         diprint("cancelisoio iso %#p waiting for I/O to cease\n", iso);
 2965         tsleep(&up->sleep, return0, 0, 5);
 2966         qlock(iso);
 2967         qunlock(iso);
 2968         diprint("cancelisoio iso %#p releasing iso\n", iso);
 2969 
 2970         frno = iso->td0frno;
 2971         for(i = 0; i < iso->nframes; i++){
 2972                 if(iso->hs != 0)
 2973                         itdfree(iso->itdps[frno]);
 2974                 else
 2975                         sitdfree(iso->sitdps[frno]);
 2976                 iso->tdps[frno] = nil;
 2977                 frno = TRUNC(frno+pollival, Nisoframes);
 2978         }
 2979         free(iso->tdps);
 2980         iso->tdps = nil;
 2981         free(iso->data);
 2982         iso->data = nil;
 2983 }
 2984 
 2985 static void
 2986 epclose(Ep *ep)
 2987 {
 2988         Qio *io;
 2989         Ctlio *cio;
 2990         Isoio *iso;
 2991         Ctlr *ctlr;
 2992 
 2993         ctlr = ep->hp->aux;
 2994         deprint("ehci: epclose ep%d.%d\n", ep->dev->nb, ep->nb);
 2995 
 2996         if(ep->aux == nil)
 2997                 panic("ehci: epclose called with closed ep");
 2998         switch(ep->ttype){
 2999         case Tctl:
 3000                 cio = ep->aux;
 3001                 cancelio(ctlr, cio);
 3002                 free(cio->data);
 3003                 cio->data = nil;
 3004                 break;
 3005         case Tintr:
 3006         case Tbulk:
 3007                 io = ep->aux;
 3008                 ep->toggle[OREAD] = ep->toggle[OWRITE] = 0;
 3009                 if(ep->mode != OWRITE){
 3010                         cancelio(ctlr, &io[OREAD]);
 3011                         if(io[OREAD].toggle == Tddata1)
 3012                                 ep->toggle[OREAD] = 1;
 3013                 }
 3014                 if(ep->mode != OREAD){
 3015                         cancelio(ctlr, &io[OWRITE]);
 3016                         if(io[OWRITE].toggle == Tddata1)
 3017                                 ep->toggle[OWRITE] = 1;
 3018                 }
 3019                 break;
 3020         case Tiso:
 3021                 iso = ep->aux;
 3022                 cancelisoio(ctlr, iso, ep->pollival, ep->load);
 3023                 break;
 3024                 break;
 3025         default:
 3026                 panic("epclose: bad ttype");
 3027         }
 3028         free(ep->aux);
 3029         ep->aux = nil;
 3030 }
 3031 
 3032 static void
 3033 scanpci(void)
 3034 {
 3035         static int already = 0;
 3036         int i;
 3037         ulong io;
 3038         Ctlr *ctlr;
 3039         Pcidev *p;
 3040         Ecapio *capio;
 3041 
 3042         if(already)
 3043                 return;
 3044         already = 1;
 3045         p = nil;
 3046         while ((p = pcimatch(p, 0, 0)) != nil) {
 3047                 /*
 3048                  * Find EHCI controllers (Programming Interface = 0x20).
 3049                  */
 3050                 if(p->ccrb != Pcibcserial || p->ccru != Pciscusb)
 3051                         continue;
 3052                 switch(p->ccrp){
 3053                 case 0x20:
 3054                         io = p->mem[0].bar & ~0x0f;
 3055                         break;
 3056                 default:
 3057                         continue;
 3058                 }
 3059                 if(io == 0){
 3060                         print("usbehci: %x %x: failed to map registers\n",
 3061                                 p->vid, p->did);
 3062                         continue;
 3063                 }
 3064                 if(p->intl == 0xff || p->intl == 0) {
 3065                         print("usbehci: no irq assigned for port %#ulx\n", io);
 3066                         continue;
 3067                 }
 3068                 dprint("usbehci: %#x %#x: port %#ulx size %#x irq %d\n",
 3069                         p->vid, p->did, io, p->mem[0].size, p->intl);
 3070 
 3071                 ctlr = mallocz(sizeof(Ctlr), 1);
 3072                 ctlr->pcidev = p;
 3073                 capio = ctlr->capio = vmap(io, p->mem[0].size);
 3074                 ctlr->opio = (Eopio*)((uintptr)capio + (capio->cap & 0xff));
 3075                 pcisetbme(p);
 3076                 pcisetpms(p, 0);
 3077                 for(i = 0; i < Nhcis; i++)
 3078                         if(ctlrs[i] == nil){
 3079                                 ctlrs[i] = ctlr;
 3080                                 break;
 3081                         }
 3082                 if(i == Nhcis)
 3083                         print("ehci: bug: no more controllers\n");
 3084         }
 3085 }
 3086 
 3087 /*
 3088  * return smallest power of 2 >= n
 3089  */
 3090 static int
 3091 flog2(int n)
 3092 {
 3093         int i;
 3094 
 3095         for(i = 0; (1 << i) < n; i++)
 3096                 ;
 3097         return i;
 3098 }
 3099 
 3100 /*
 3101  * build the periodic scheduling tree:
 3102  * framesize must be a multiple of the tree size
 3103  */
 3104 static void
 3105 mkqhtree(Ctlr *ctlr)
 3106 {
 3107         int i, n, d, o, leaf0, depth;
 3108         Qh **tree;
 3109         Qtree *qt;
 3110         Qh *qh;
 3111         ulong leafs[Nintrleafs];
 3112 
 3113         depth = flog2(Nintrleafs);
 3114         n = (1 << (depth+1)) - 1;
 3115         qt = mallocz(sizeof(*qt), 1);
 3116         if(qt == nil)
 3117                 panic("ehci: mkqhtree: no memory");
 3118         qt->nel = n;
 3119         qt->depth = depth;
 3120         qt->bw = mallocz(n * sizeof(qt->bw), 1);
 3121         qt->root = tree = mallocz(n * sizeof(Qh *), 1);
 3122         if(qt->bw == nil || tree == nil)
 3123                 panic("ehci: mkqhtree: no memory");
 3124         for(i = 0; i < n; i++){
 3125                 qh = tree[i] = edalloc();
 3126                 if(qh == nil)
 3127                         panic("ehci: mkqhtree: no memory");
 3128                 qh->nlink = qh->alink = qh->link = Lterm;
 3129                 qh->csw = Tdhalt;
 3130                 qh->state = Qidle;
 3131                 if(i > 0)
 3132                         qhlinkqh(tree[i], tree[(i-1)/2]);
 3133         }
 3134         ctlr->ntree = i;
 3135         dprint("ehci: tree: %d endpoints allocated\n", i);
 3136 
 3137         /* distribute leaves evenly round the frame list */
 3138         leaf0 = n / 2;
 3139         for(i = 0; i < Nintrleafs; i++){
 3140                 o = 0;
 3141                 for(d = 0; d < depth; d++){
 3142                         o <<= 1;
 3143                         if(i & (1 << d))
 3144                                 o |= 1;
 3145                 }
 3146                 if(leaf0 + o >= n){
 3147                         print("leaf0=%d o=%d i=%d n=%d\n", leaf0, o, i, n);
 3148                         break;
 3149                 }
 3150                 leafs[i] = PADDR(tree[leaf0 + o]) | Lqh;
 3151         }
 3152         assert((ctlr->nframes % Nintrleafs) == 0);
 3153         for(i = 0; i < ctlr->nframes; i += Nintrleafs)
 3154                 memmove(ctlr->frames + i, leafs, sizeof(leafs));
 3155         ctlr->tree = qt;
 3156 }
 3157 
 3158 static void
 3159 ehcimeminit(Ctlr *ctlr)
 3160 {
 3161         int frsize;
 3162         Eopio *opio;
 3163         int i;
 3164 
 3165         opio = ctlr->opio;
 3166         frsize = ctlr->nframes*sizeof(ulong);
 3167         assert((frsize & 0xFFF) == 0);          /* must be 4k aligned */
 3168         ctlr->frames = xspanalloc(frsize, frsize, 0);
 3169         if(ctlr->frames == nil)
 3170                 panic("ehci reset: no memory");
 3171 
 3172         for (i = 0; i < ctlr->nframes; i++)
 3173                 ctlr->frames[i] = Lterm;
 3174         opio->frbase = PADDR(ctlr->frames);
 3175         opio->frno = 0;
 3176 
 3177         qhalloc(ctlr, nil, nil, nil);   /* init async list */
 3178         mkqhtree(ctlr);                 /* init sync list */
 3179         edfree(edalloc());              /* try to get some ones pre-allocated */
 3180 
 3181         dprint("ehci %#p flb %#ulx frno %#ulx\n",
 3182                 ctlr->capio, opio->frbase, opio->frno);
 3183 }
 3184 
 3185 static void
 3186 init(Hci *hp)
 3187 {
 3188         Ctlr *ctlr;
 3189         Eopio *opio;
 3190         int i;
 3191 
 3192         hp->highspeed = 1;
 3193         ctlr = hp->aux;
 3194         opio = ctlr->opio;
 3195         dprint("ehci %#p init\n", ctlr->capio);
 3196 
 3197         ilock(ctlr);
 3198         /*
 3199          * Unless we activate frroll interrupt
 3200          * some machines won't post other interrupts.
 3201          */
 3202         opio->intr = Iusb|Ierr|Iportchg|Ihcerr|Iasync;
 3203         opio->config = Callmine;        /* reclaim all ports */
 3204         opio->cmd |= Cpse;
 3205         opio->cmd |= Case;
 3206         ehcirun(ctlr, 1);
 3207 
 3208         for (i = 0; i < hp->nports; i++)
 3209                 opio->portsc[i] = Pspower;
 3210         iunlock(ctlr);
 3211 
 3212         if(debug > 1)
 3213                 dump(hp);
 3214 
 3215 }
 3216 
 3217 static void
 3218 ehcireset(Ctlr *ctlr)
 3219 {
 3220         Eopio *opio;
 3221         int i;
 3222 
 3223         ilock(ctlr);
 3224         dprint("ehci %#p reset\n", ctlr->capio);
 3225 
 3226         /*
 3227          * Turn off legacy mode. Some controllers won't
 3228          * interrupt us as expected otherwise.
 3229          */
 3230         ehcirun(ctlr, 0);
 3231         pcicfgw16(ctlr->pcidev, 0xc0, 0x2000);
 3232 
 3233         /* clear high 32 bits of address signals if it's 64 bits capable.
 3234          * This is probably not needed but it does not hurt and others do it.
 3235          */
 3236         if((ctlr->capio->capparms & C64) != 0){
 3237                 dprint("ehci: 64 bits\n");
 3238                 ctlr->opio->seg = 0;
 3239         }
 3240 
 3241         opio = ctlr->opio;
 3242         opio->cmd |= Chcreset;  /* controller reset */
 3243         for(i = 0; i < 100; i++){
 3244                 if((opio->cmd & Chcreset) == 0)
 3245                         break;
 3246                 delay(1);
 3247         }
 3248         if(i == 100)
 3249                 print("ehci %#p controller reset timed out\n", ctlr->capio);
 3250 
 3251         /* requesting more interrupts per µframe may miss interrupts */
 3252         opio->cmd |= Citc8;     /* 1 intr. per ms */
 3253         switch(opio->cmd & Cflsmask){
 3254         case Cfls1024:
 3255                 ctlr->nframes = 1024;
 3256                 break;
 3257         case Cfls512:
 3258                 ctlr->nframes = 512;
 3259                 break;
 3260         case Cfls256:
 3261                 ctlr->nframes = 256;
 3262                 break;
 3263         default:
 3264                 panic("ehci: unknown fls %#lux", opio->cmd & Cflsmask);
 3265         }
 3266         dprint("ehci: %d frames\n", ctlr->nframes);
 3267         iunlock(ctlr);
 3268 }
 3269 
 3270 static void
 3271 setdebug(Hci*, int d)
 3272 {
 3273         debug = d;
 3274 }
 3275 
 3276 static int
 3277 reset(Hci *hp)
 3278 {
 3279         static Lock resetlck;
 3280         int i;
 3281         Ctlr *ctlr;
 3282         Ecapio *capio;
 3283         Pcidev *p;
 3284 
 3285         if(getconf("*nousbehci"))
 3286                 return -1;
 3287         ilock(&resetlck);
 3288         scanpci();
 3289 
 3290         /*
 3291          * Any adapter matches if no hp->port is supplied,
 3292          * otherwise the ports must match.
 3293          */
 3294         ctlr = nil;
 3295         for(i = 0; i < Nhcis && ctlrs[i] != nil; i++){
 3296                 ctlr = ctlrs[i];
 3297                 if(ctlr->active == 0)
 3298                 if(hp->port == 0 || hp->port == (uintptr)ctlr->capio){
 3299                         ctlr->active = 1;
 3300                         break;
 3301                 }
 3302         }
 3303         iunlock(&resetlck);
 3304         if(ctlrs[i] == nil || i == Nhcis)
 3305                 return -1;
 3306 
 3307         p = ctlr->pcidev;
 3308         hp->aux = ctlr;
 3309         hp->port = (uintptr)ctlr->capio;
 3310         hp->irq = p->intl;
 3311         hp->tbdf = p->tbdf;
 3312 
 3313         capio = ctlr->capio;
 3314         hp->nports = capio->parms & Cnports;
 3315 
 3316         ddprint("echi: %s, ncc %lud npcc %lud\n",
 3317                 capio->parms & 0x10000 ? "leds" : "no leds",
 3318                 (capio->parms >> 12) & 0xf, (capio->parms >> 8) & 0xf);
 3319         ddprint("ehci: routing %s, %sport power ctl, %d ports\n",
 3320                 capio->parms & 0x40 ? "explicit" : "automatic",
 3321                 capio->parms & 0x10 ? "" : "no ", hp->nports);
 3322 
 3323         ehcireset(ctlr);
 3324         ehcimeminit(ctlr);
 3325 
 3326         /*
 3327          * Linkage to the generic HCI driver.
 3328          */
 3329         hp->init = init;
 3330         hp->dump = dump;
 3331         hp->interrupt = interrupt;
 3332         hp->epopen = epopen;
 3333         hp->epclose = epclose;
 3334         hp->epread = epread;
 3335         hp->epwrite = epwrite;
 3336         hp->seprintep = seprintep;
 3337         hp->portenable = portenable;
 3338         hp->portreset = portreset;
 3339         hp->portstatus = portstatus;
 3340         hp->debug = setdebug;
 3341         hp->type = "ehci";
 3342         return 0;
 3343 }
 3344 
 3345 void
 3346 usbehcilink(void)
 3347 {
 3348         addhcitype("ehci", reset);
 3349 }
 3350 

Cache object: 8b8003e0a4b6a8a16dcdd6f7b551c187


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.