2 #include "../port/lib.h"
7 #include "../port/error.h"
9 #include "../port/usb.h"
12 /* Capability Registers */
13 CAPLENGTH = 0x00/4, // 1
14 HCIVERSION = 0x02/4, // 2
32 /* Operational Registers */
33 USBCMD = 0x00/4, /* USB Command Register */
34 RUNSTOP = 1<<0, /* Run/Stop - RW */
35 HCRST = 1<<1, /* Host Controller Reset - RW */
36 INTE = 1<<2, /* Interrupter Enable - RW */
37 HSEE = 1<<3, /* Host System Error Enable - RW */
38 LHCRST = 1<<7, /* Light Host Controller Reset - RO/RW */
39 CSS = 1<<8, /* Controller Save State - RW */
40 CRS = 1<<9, /* Controller Restore State - RW */
41 EWE = 1<<10, /* Enable Wrap Event - RW */
42 EU3S = 1<<11, /* Enable U3 MFINDEX Stop - RW */
44 USBSTS = 0x04/4, /* USB Status Register */
45 HCH = 1<<0, /* HCHalted - RO */
46 HSE = 1<<2, /* Host System Error - RW1C */
47 EINT = 1<<3, /* Event Interrupt - RW1C */
48 PCD = 1<<4, /* Port Change Detect - RW1C */
49 SSS = 1<<8, /* Save State Status - RO */
50 RSS = 1<<9, /* Restore State Status - RO */
51 SRE = 1<<10, /* Save/Restore Error - RW1C */
52 CNR = 1<<11, /* Controller Not Ready - RO */
53 HCE = 1<<12, /* Host Controller Error - RO */
55 PAGESIZE = 0x08/4, /* Page Size - RO */
57 DNCTRL = 0x14/4, /* Device Notification Control Register - RW */
59 CRCR = 0x18/4, /* Command Ring Control Register - RW */
60 RCS = 1<<0, /* Ring Cycle State - RW */
61 CS = 1<<1, /* Command Stop - RW1S */
62 CA = 1<<2, /* Command Abort - RW1S */
63 CRR = 1<<3, /* Command Ring Running - RO */
67 CONFIG = 0x38/4, /* Configure Register (MaxSlotEn[7:0]) */
69 /* Port Register Set */
70 PORTSC = 0x00/4, /* Port tatus and Control Register */
71 CCS = 1<<0, /* Current Connect Status - ROS */
72 PED = 1<<1, /* Port Enable/Disabled - RW1CS */
73 OCA = 1<<3, /* Over-current Active - RO */
74 PR = 1<<4, /* Port Reset - RW1S */
75 PLS = 15<<5, /* Port Link State - RWS */
76 PP = 1<<9, /* Port Power - RWS */
77 PS = 15<<10, /* Port Speed - ROS */
78 PIC = 3<<14, /* Port Indicator Control - RWS */
79 LWS = 1<<16, /* Port Link Write Strobe - RW */
80 CSC = 1<<17, /* Connect Status Change - RW1CS */
81 PEC = 1<<18, /* Port Enabled/Disabled Change - RW1CS */
82 WRC = 1<<19, /* Warm Port Reset Change - RW1CS */
83 OCC = 1<<20, /* Over-current Change - RW1CS */
84 PRC = 1<<21, /* Port Reset Change - RW1CS */
85 PLC = 1<<22, /* Port Link State Change - RW1CS */
86 CEC = 1<<23, /* Port Config Error Change - RW1CS */
87 CAS = 1<<24, /* Cold Attach Status - RO */
88 WCE = 1<<25, /* Wake on Connect Enable - RWS */
89 WDE = 1<<26, /* Wake on Disconnect Enable - RWS */
90 WOE = 1<<27, /* Wake on Over-current Enable - RWS */
91 DR = 1<<30, /* Device Removable - RO */
92 WPR = 1<<31, /* Warm Port Reset - RW1S */
97 /* Host Controller Runtime Register */
98 MFINDEX = 0x0000/4, /* Microframe Index */
99 IR0 = 0x0020/4, /* Interrupt Register Set 0 */
101 /* Interrupter Registers */
102 IMAN = 0x00/4, /* Interrupter Management */
103 IMOD = 0x04/4, /* Interrupter Moderation */
104 ERSTSZ = 0x08/4, /* Event Ring Segment Table Size */
105 ERSTBA = 0x10/4, /* Event Ring Segment Table Base Address */
106 ERDP = 0x18/4, /* Event Ring Dequeue Pointer */
120 TR_SETUPSTAGE = 2<<10,
121 TR_DATASTAGE = 3<<10,
122 TR_STATUSSTAGE = 4<<10,
125 TR_EVENTDATA = 7<<10,
128 CR_ENABLESLOT = 9<<10,
129 CR_DISABLESLOT = 10<<10,
130 CR_ADDRESSDEV = 11<<10,
131 CR_CONFIGEP = 12<<10,
135 CR_SETTRDQP = 16<<10,
136 CR_RESETDEV = 17<<10,
137 CR_FORCECMD = 18<<10,
140 CR_GETPORTBW = 21<<10,
141 CR_FORCEHDR = 22<<10,
144 ER_TRANSFER = 32<<10,
145 ER_CMDCOMPL = 33<<10,
148 ER_DOORBELL = 36<<10,
151 ER_MFINDEXWRAP = 39<<10,
154 typedef struct Ctlr Ctlr;
155 typedef struct Wait Wait;
156 typedef struct Ring Ring;
157 typedef struct Slot Slot;
158 typedef struct Epio Epio;
159 typedef struct Port Port;
222 u32int *opr; /* operational registers */
223 u32int *rts; /* runtime registers */
224 u32int *dba; /* doorbell array */
226 u64int *dcba; /* device context base array */
228 u64int *sba; /* scratchpad buffer array */
229 void *sbp; /* scratchpad buffer pages */
231 u32int *erst[1]; /* event ring segment table */
232 Ring er[1]; /* event ring segment */
233 Ring cr[1]; /* command ring segment */
239 Slot **slot; /* slots by slot id */
250 void (*setrptr)(u32int*, u64int);
273 static char Ebadlen[] = "bad usb request length";
274 static char Enotconfig[] = "usb endpoint not configured";
275 static char Erecover[] = "xhci controller needs reset";
278 setrptr32(u32int *reg, u64int pa)
286 setrptr64(u32int *reg, u64int pa)
289 *((u64int*)reg) = pa;
297 µ = (ctlr->rts[MFINDEX] & (1<<14)-1) |
298 (ctlr->µframe & ~((1<<14)-1));
299 } while((int)(µ - ctlr->µframe) < 0);
309 memset(r, 0, sizeof(*r));
313 initring(Ring *r, int shift)
322 r->mask = (1<<shift)-1;
324 r->base = mallocalign(4*4<<shift, 64, 0, 64*1024);
338 while((w = r->pending) != nil){
339 r->pending = w->next;
341 if((z = w->z) != nil){
356 pa = PADDR(&r->base[4*(r->wp & r->mask)]) | ((~r->wp>>r->shift) & 1);
363 xecp(Ctlr *ctlr, uchar id, u32int *p)
367 e = &ctlr->mmio[ctlr->pcidev->mem[0].size/4];
370 x = ctlr->hccparams>>16;
394 if((r = xecp(ctlr, 1, nil)) == nil)
396 r[0] |= 1<<24; /* request ownership */
397 for(i = 0; (r[0] & (1<<16)) != 0 && i<100; i++)
398 tsleep(&up->sleep, return0, nil, 10);
399 r[1] = 0; /* disable SMI interrupts */
400 r[0] &= ~(1<<16); /* in case of timeout */
406 Ctlr *ctlr = hp->aux;
409 ctlr->opr[USBCMD] = 0;
410 for(i=0; (ctlr->opr[USBSTS] & HCH) == 0 && i < 10; i++)
412 intrdisable(ctlr->pcidev->intl, hp->interrupt, hp, ctlr->pcidev->tbdf, hp->type);
413 pciclrbme(ctlr->pcidev);
422 for(i=0; i<nelem(ctlr->er); i++){
423 freering(&ctlr->er[i]);
427 free(ctlr->port), ctlr->port = nil;
428 free(ctlr->slot), ctlr->slot = nil;
429 free(ctlr->dcba), ctlr->dcba = nil;
430 free(ctlr->sba), ctlr->sba = nil;
431 free(ctlr->sbp), ctlr->sbp = nil;
434 static void recover(void *arg);
446 if(ctlr->mmio[CAPLENGTH] == -1)
447 error("controller vanished");
449 ctlr->opr = &ctlr->mmio[(ctlr->mmio[CAPLENGTH]&0xFF)/4];
450 ctlr->dba = &ctlr->mmio[ctlr->mmio[DBOFF]/4];
451 ctlr->rts = &ctlr->mmio[ctlr->mmio[RTSOFF]/4];
453 ctlr->hccparams = ctlr->mmio[HCCPARAMS];
456 for(i=0; (ctlr->opr[USBSTS] & CNR) != 0 && i<100; i++)
457 tsleep(&up->sleep, return0, nil, 10);
459 ctlr->opr[USBCMD] = HCRST;
460 for(i=0; (ctlr->opr[USBSTS] & (CNR|HCH)) != HCH && i<100; i++)
461 tsleep(&up->sleep, return0, nil, 10);
463 pcisetbme(ctlr->pcidev);
464 pcisetpms(ctlr->pcidev, 0);
465 intrenable(ctlr->pcidev->intl, hp->interrupt, hp, ctlr->pcidev->tbdf, hp->type);
473 ctlr->csz = (ctlr->hccparams & CSZ) != 0;
474 if(ctlr->hccparams & AC64)
475 ctlr->setrptr = setrptr64;
477 ctlr->setrptr = setrptr32;
478 ctlr->pagesize = ctlr->opr[PAGESIZE]<<12;
480 ctlr->nscratch = (ctlr->mmio[HCSPARAMS2] >> 27) & 0x1F;
481 ctlr->nintrs = (ctlr->mmio[HCSPARAMS1] >> 8) & 0x7FF;
482 ctlr->nslots = (ctlr->mmio[HCSPARAMS1] >> 0) & 0xFF;
486 hp->nports = (ctlr->mmio[HCSPARAMS1] >> 24) & 0xFF;
487 ctlr->port = malloc(hp->nports * sizeof(Port));
488 if(ctlr->port == nil)
490 for(i=0; i<hp->nports; i++)
491 ctlr->port[i].reg = &ctlr->opr[0x400/4 + i*4];
494 while((x = xecp(ctlr, 2, x)) != nil){
498 if(i < 1 || i > hp->nports)
500 pp = &ctlr->port[i-1];
501 pp->proto = x[0]>>16;
502 memmove(pp->spec, &x[1], 4);
503 if(memcmp(pp->spec, "USB ", 4) == 0 && pp->proto >= 0x0300)
504 hp->superspeed |= 1<<(i-1);
509 ctlr->slot = malloc((1+ctlr->nslots)*sizeof(ctlr->slot[0]));
510 ctlr->dcba = mallocalign((1+ctlr->nslots)*8, 64, 0, ctlr->pagesize);
511 if(ctlr->slot == nil || ctlr->dcba == nil)
513 if(ctlr->nscratch != 0){
514 ctlr->sba = mallocalign(ctlr->nscratch*8, 64, 0, ctlr->pagesize);
515 ctlr->sbp = mallocalign(ctlr->nscratch*ctlr->pagesize, ctlr->pagesize, 0, 0);
516 if(ctlr->sba == nil || ctlr->sbp == nil)
518 for(i=0, p = ctlr->sbp; i<ctlr->nscratch; i++, p += ctlr->pagesize){
519 memset(p, 0, ctlr->pagesize);
520 ctlr->sba[i] = PADDR(p);
522 ctlr->dcba[0] = PADDR(ctlr->sba);
526 for(i=1; i<=ctlr->nslots; i++)
528 ctlr->opr[CONFIG] = ctlr->nslots; /* MaxSlotsEn */
529 ctlr->setrptr(&ctlr->opr[DCBAAP], PADDR(ctlr->dcba));
531 initring(ctlr->cr, 8); /* 256 entries */
533 ctlr->cr->doorbell = &ctlr->dba[0];
534 ctlr->setrptr(&ctlr->opr[CRCR], resetring(ctlr->cr));
536 for(i=0; i<ctlr->nintrs; i++){
537 u32int *irs = &ctlr->rts[IR0 + i*8];
539 if(i >= nelem(ctlr->er)){
540 irs[ERSTSZ] = 0; /* disable ring */
544 /* allocate and link into event ring segment table */
545 initring(&ctlr->er[i], 8); /* 256 entries */
546 ctlr->erst[i] = mallocalign(16, 64, 0, 0);
547 if(ctlr->erst[i] == nil)
549 *((u64int*)ctlr->erst[i]) = PADDR(ctlr->er[i].base);
550 ctlr->erst[i][2] = ctlr->er[i].mask+1;
551 ctlr->erst[i][3] = 0;
553 irs[ERSTSZ] = 1; /* just one segment */
554 ctlr->setrptr(&irs[ERDP], PADDR(ctlr->er[i].base));
555 ctlr->setrptr(&irs[ERSTBA], PADDR(ctlr->erst[i]));
563 ctlr->opr[USBCMD] = RUNSTOP|INTE|HSEE|EWE;
564 for(i=0; (ctlr->opr[USBSTS] & (CNR|HCH)) != 0 && i<100; i++)
565 tsleep(&up->sleep, return0, nil, 10);
567 kproc("xhcirecover", recover, hp);
571 needrecover(void *arg)
574 return ctlr->er->stopped ||
575 (ctlr->opr[USBSTS] & (HCH|HCE|HSE)) != 0;
582 Ctlr *ctlr = hp->aux;
586 while(!needrecover(ctlr))
587 tsleep(&ctlr->recover, needrecover, ctlr, 1000);
592 * flush all transactions and wait until all devices have
593 * been detached by usbd.
599 ctlr->cr->stopped = 1;
604 qlock(&ctlr->slotlock);
605 for(i=1; i<=ctlr->nslots; i++){
606 Slot *slot = ctlr->slot[i];
610 for(j=0; j < slot->nep; j++){
611 Ring *ring = &slot->epr[j];
612 if(ring->base == nil)
620 qunlock(&ctlr->slotlock);
624 tsleep(&up->sleep, return0, nil, 100);
627 qlock(&ctlr->slotlock);
628 qlock(&ctlr->cmdlock);
632 print("xhci recovery failed: %s\n", up->errstr);
638 qunlock(&ctlr->cmdlock);
639 qunlock(&ctlr->slotlock);
650 queuetd(Ring *r, u32int c, u32int s, u64int p, Wait *w)
655 if((x & r->mask) == r->mask){
656 td = r->base + 4*(x & r->mask);
657 *(u64int*)td = PADDR(r->base);
659 td[3] = ((~x>>r->shift)&1) | (1<<1) | TR_LINK;
662 td = r->base + 4*(x & r->mask);
664 w->er[0] = w->er[1] = w->er[2] = w->er[3] = 0;
670 w->next = r->pending;
677 td[3] = ((~x>>r->shift)&1) | c;
680 static char *ccerrtab[] = {
681 [2] "Data Buffer Error",
682 [3] "Babble Detected Error",
683 [4] "USB Transaction Error",
687 [8] "Bandwidth Error",
688 [9] "No Slots Available",
689 [10] "Invalid Stream Type",
690 [11] "Slot Not Enabled",
691 [12] "Endpoint Not Enabled",
693 [14] "Ring Underrun",
695 [16] "VF Event Ring Full",
696 [17] "Parameter Error",
697 [18] "Bandwidth Overrun Error",
698 [19] "Context State Error",
699 [20] "No Ping Response",
700 [21] "Event Ring Full",
701 [22] "Incompatible Device",
702 [23] "Missed Service Error",
703 [24] "Command Ring Stopped",
704 [25] "Command Aborted",
706 [27] "Stoppe - Length Invalid",
707 [29] "Max Exit Latency Too Large",
708 [31] "Isoch Buffer Overrun",
709 [32] "Event Lost Error",
710 [33] "Undefined Error",
711 [34] "Invalid Stream ID",
712 [35] "Secondary Bandwidth Error",
713 [36] "Split Transaction Error",
721 if(cc == 1 || cc == 13)
723 if(cc < nelem(ccerrtab) && ccerrtab[cc] != nil)
733 return ((Wait*)a)->z == nil;
737 ctlrcmd(Ctlr *ctlr, u32int c, u32int s, u64int p, u32int *er);
740 waittd(Ctlr *ctlr, Wait *w, int tmout)
745 *r->doorbell = r->id;
750 ctlr->opr[CRCR] |= CA;
752 ctlrcmd(ctlr, CR_STOPEP | (r->id<<16) | (r->slot->id<<24), 0, 0, nil);
758 tsleep(&up->sleep, waitdone, w, tmout);
763 sleep(&up->sleep, waitdone, w);
767 return ccerrstr(w->er[2]>>24);
771 ctlrcmd(Ctlr *ctlr, u32int c, u32int s, u64int p, u32int *er)
776 qlock(&ctlr->cmdlock);
777 if(needrecover(ctlr)){
778 qunlock(&ctlr->cmdlock);
781 ctlr->cr->stopped = 0;
782 queuetd(ctlr->cr, c, s, p, w);
783 err = waittd(ctlr, w, 5000);
785 qunlock(&ctlr->cmdlock);
788 memmove(er, w->er, 4*4);
794 completering(Ring *r, u32int *er)
800 pa = (*(u64int*)er) & ~15ULL;
803 for(x = r->rp; (int)(r->wp - x) > 0;){
804 td = &r->base[4*(x++ & r->mask)];
805 if((u64int)PADDR(td) == pa){
813 if((u64int)PADDR(w->td) == pa){
816 memmove(w->er, er, 4*4);
834 interrupt(Ureg*, void *arg)
837 Ctlr *ctlr = hp->aux;
838 Ring *ring = ctlr->er;
842 if(ring->base == nil)
845 irs = &ctlr->rts[IR0];
847 if(x & 1) irs[IMAN] = x & 3;
849 for(x = ring->rp;; x=++ring->rp){
850 td = ring->base + 4*(x & ring->mask);
851 if((((x>>ring->shift)^td[3])&1) == 0)
854 switch(td[3] & 0xFC00){
856 completering(ctlr->cr, td);
860 if(x == 0 || x > ctlr->nslots)
862 slot = ctlr->slot[x];
865 completering(&slot->epr[(td[3]>>16)-1&31], td);
868 ctlr->µframe = (ctlr->rts[MFINDEX] & (1<<14)-1) |
869 (ctlr->µframe+(1<<14) & ~((1<<14)-1));
872 iprint("xhci: host controller error: %ux %ux %ux %ux\n",
873 td[0], td[1], td[2], td[3]);
874 ctlr->er->stopped = 1;
875 wakeup(&ctlr->recover);
883 iprint("xhci: event %ud: %ux %ux %ux %ux\n",
884 x, td[0], td[1], td[2], td[3]);
888 ctlr->setrptr(&irs[ERDP], PADDR(td) | (1<<3));
900 Ctlr *ctlr = slot->ctlr;
901 qlock(&ctlr->slotlock);
902 if(ctlr->slot != nil && ctlr->slot[slot->id] == slot){
903 ctlrcmd(ctlr, CR_DISABLESLOT | (slot->id<<24), 0, 0, nil);
904 ctlr->dcba[slot->id] = 0;
905 ctlr->slot[slot->id] = nil;
907 qunlock(&ctlr->slotlock);
909 freering(&slot->epr[0]);
916 allocslot(Ctlr *ctlr, Udev *dev)
922 slot = malloc(sizeof(Slot));
931 qlock(&ctlr->slotlock);
933 qunlock(&ctlr->slotlock);
937 if(ctlr->slot == nil)
939 slot->ibase = mallocalign(32*33 << ctlr->csz, 64, 0, ctlr->pagesize);
940 slot->obase = mallocalign(32*32 << ctlr->csz, 64, 0, ctlr->pagesize);
941 if(slot->ibase == nil || slot->obase == nil)
943 if((err = ctlrcmd(ctlr, CR_ENABLESLOT, 0, 0, r)) != nil)
946 if(slot->id <= 0 || slot->id > ctlr->nslots || ctlr->slot[slot->id] != nil){
948 error("bad slot id from controller");
952 ctlr->dcba[slot->id] = PADDR(slot->obase);
953 ctlr->slot[slot->id] = slot;
954 qunlock(&ctlr->slotlock);
957 dev->free = freeslot;
986 if(ep->nb > 0 && (io[OREAD].ring != nil || io[OWRITE].ring != nil)){
989 /* input control context */
991 memset(w, 0, 32<<ctlr->csz);
993 if((ring = io[OREAD].ring) != nil){
994 w[0] |= 1 << ring->id;
995 if(ring->id == slot->nep)
997 ctlrcmd(ctlr, CR_STOPEP | (ring->id<<16) | (slot->id<<24), 0, 0, nil);
999 if((ring = io[OWRITE].ring) != nil){
1000 w[0] |= 1 << ring->id;
1001 if(ring->id == slot->nep)
1003 ctlrcmd(ctlr, CR_STOPEP | (ring->id<<16) | (slot->id<<24), 0, 0, nil);
1006 /* (input) slot context */
1008 w[0] = (w[0] & ~(0x1F<<27)) | slot->nep<<27;
1010 /* (input) ep context */
1011 w += ep->nb*2*8<<ctlr->csz;
1012 memset(w, 0, 2*32<<ctlr->csz);
1014 ctlrcmd(ctlr, CR_CONFIGEP | (slot->id<<24), 0, PADDR(slot->ibase), nil);
1016 freering(io[OREAD].ring);
1017 freering(io[OWRITE].ring);
1020 freeb(io[OWRITE].b);
1025 initepctx(u32int *w, Ring *r, Ep *ep)
1029 if(ep->dev->speed == Lowspeed || ep->dev->speed == Fullspeed){
1030 for(ival=3; ival < 11 && (1<<ival) < ep->pollival; ival++)
1033 for(ival=0; ival < 15 && (1<<ival) < ep->pollival; ival++)
1037 w[1] = ((ep->ttype-Tctl)|(r->id&1)<<2)<<3 | (ep->ntds-1)<<8 | ep->maxpkt<<16;
1038 if(ep->ttype != Tiso)
1040 *((u64int*)&w[2]) = PADDR(r->base) | 1;
1043 if(ep->ttype == Tintr || ep->ttype == Tiso)
1044 w[4] |= (ep->maxpkt*ep->ntds)<<16;
1048 initisoio(Epio *io, Ep *ep)
1053 io->period = ep->pollival<<3*(ep->dev->speed == Fullspeed);
1054 io->incr = (ep->hz*io->period<<8)/8000;
1055 io->tdsz = (io->incr+255>>8)*ep->samplesz;
1056 io->b = allocb((io->ring->mask+1)*io->tdsz);
1071 slot = ep->dev->aux;
1073 io[OREAD].ring = io[OWRITE].ring = nil;
1075 io[OWRITE].ring = &slot->epr[0];
1079 /* (input) control context */
1081 memset(w, 0, 32<<ctlr->csz);
1085 freering(io[OWRITE].ring), io[OWRITE].ring = nil;
1086 freering(io[OREAD].ring), io[OREAD].ring = nil;
1089 if(ep->mode != OREAD){
1090 ring = initring(io[OWRITE].ring = &slot->epr[ep->nb*2-1], 8);
1091 ring->id = ep->nb*2;
1092 if(ring->id > slot->nep)
1093 slot->nep = ring->id;
1095 ring->doorbell = &ctlr->dba[slot->id];
1096 ring->ctx = &slot->obase[ring->id*8<<ctlr->csz];
1097 w[1] |= 1 << ring->id;
1099 if(ep->mode != OWRITE){
1100 ring = initring(io[OREAD].ring = &slot->epr[ep->nb*2], 8);
1101 ring->id = ep->nb*2+1;
1102 if(ring->id > slot->nep)
1103 slot->nep = ring->id;
1105 ring->doorbell = &ctlr->dba[slot->id];
1106 ring->ctx = &slot->obase[ring->id*8<<ctlr->csz];
1107 w[1] |= 1 << ring->id;
1110 /* (input) slot context */
1112 w[0] = (w[0] & ~(0x1F<<27)) | slot->nep<<27;
1114 /* (input) ep context */
1115 w += ep->nb*2*8<<ctlr->csz;
1116 memset(w, 0, 2*32<<ctlr->csz);
1117 if(io[OWRITE].ring != nil)
1118 initepctx(w, io[OWRITE].ring, ep);
1121 if(io[OREAD].ring != nil)
1122 initepctx(w, io[OREAD].ring, ep);
1124 if((err = ctlrcmd(ctlr, CR_CONFIGEP | (slot->id<<24), 0,
1125 PADDR(slot->ibase), nil)) != nil){
1128 if(ep->ttype == Tiso){
1129 initisoio(io+OWRITE, ep);
1130 initisoio(io+OREAD, ep);
1139 case Fullspeed: return 1;
1140 case Lowspeed: return 2;
1141 case Highspeed: return 3;
1142 case Superspeed: return 4;
1150 Ctlr *ctlr = ep->hp->aux;
1161 if(needrecover(ctlr))
1163 io = malloc(sizeof(Epio)*2);
1173 if(slot != nil && slot->dev == dev){
1179 /* first open has to be control endpoint */
1183 slot = allocslot(ctlr, dev);
1185 /* allocate control ep 0 ring */
1186 ring = initring(io[OWRITE].ring = &slot->epr[0], 4);
1190 ring->doorbell = &ctlr->dba[slot->id];
1191 ring->ctx = &slot->obase[8];
1193 /* (input) control context */
1195 memset(w, 0, 3*32<<ctlr->csz);
1196 w[1] = 3; /* A0, A1 */
1198 /* (input) slot context */
1201 w[0] = dev->routestr | speedid(dev->speed)<<20 |
1202 (dev->speed == Highspeed && dev->ishub != 0
1203 ||dev->speed < Highspeed && dev->ishub == 0)<<25 |
1204 (dev->ishub != 0)<<26 | slot->nep<<27;
1205 w[1] = dev->rootport<<16;
1207 /* find the parent hub that this device is conected to */
1208 qlock(&ctlr->slotlock);
1209 for(i=1; i<=ctlr->nslots; i++){
1210 hub = ctlr->slot[i];
1211 if(hub == nil || hub->dev == nil || hub->dev->aux != hub)
1213 if(hub == slot || hub->dev == dev)
1215 if(!hub->dev->ishub)
1217 if(hub->dev->addr != dev->hub)
1219 if(hub->dev->rootport != dev->rootport)
1222 if(dev->speed < Highspeed && hub->dev->speed == Highspeed)
1223 w[2] = hub->id | dev->port<<8;
1226 qunlock(&ctlr->slotlock);
1228 /* (input) ep context 0 */
1230 initepctx(w, io[OWRITE].ring, ep);
1232 if((err = ctlrcmd(ctlr, CR_ADDRESSDEV | (slot->id<<24), 0,
1233 PADDR(slot->ibase), nil)) != nil){
1237 /* (output) slot context */
1239 ep->dev->addr = w[3] & 0xFF;
1244 isoread(Ep *, uchar *, long)
1251 isowrite(Ep *ep, uchar *p, long n)
1260 io = (Epio*)ep->aux + OWRITE;
1268 if(needrecover(ctlr))
1270 for(i = io->frame;; i++){
1272 m = (int)(io->ring->wp - io->ring->rp);
1274 i = (80 + µframe(ctlr))/µ;
1275 if(m < io->ring->mask)
1277 *io->ring->doorbell = io->ring->id;
1278 tsleep(&up->sleep, return0, nil, 5);
1280 m = ((io->incr + (i*io->incr&255))>>8)*ep->samplesz;
1281 d = io->b->rp + (i&io->ring->mask)*io->tdsz;
1282 m -= io->nleft, d += io->nleft;
1291 m += io->nleft, d -= io->nleft;
1293 queuetd(io->ring, TR_ISOCH | (i*µ/8 & 0x7ff)<<20 | TR_IOC, m, PADDR(d), nil);
1296 while(io->ring->rp != io->ring->wp){
1297 int d = (int)(i*µ - µframe(ctlr))/8;
1298 d -= ep->sampledelay*1000 / ep->hz;
1301 *io->ring->doorbell = io->ring->id;
1302 tsleep(&up->sleep, return0, nil, d);
1315 switch(r->ctx[0]&7){
1316 case 2: /* halted */
1319 err = ctlrcmd(r->slot->ctlr, CR_RESETEP | (r->id<<16) | (r->slot->id<<24), 0, 0, nil);
1324 err = ctlrcmd(r->slot->ctlr, CR_SETTRDQP | (r->id<<16) | (r->slot->id<<24), 0, resetring(r), nil);
1329 if(r->wp - r->rp >= r->mask)
1335 epread(Ep *ep, void *va, long n)
1346 if(ep->ttype == Tctl){
1347 io = (Epio*)ep->aux + OREAD;
1349 if(io->b == nil || BLEN(io->b) == 0){
1355 memmove(p, io->b->rp, n);
1359 } else if(ep->ttype == Tiso)
1360 return isoread(ep, p, n);
1362 if((uintptr)p <= KZERO){
1370 n = epread(ep, b->rp, n);
1371 memmove(p, b->rp, n);
1377 io = (Epio*)ep->aux + OREAD;
1384 if((err = unstall(io->ring)) != nil)
1387 queuetd(io->ring, TR_NORMAL | TR_IOC, n, PADDR(p), w);
1388 if((err = waittd((Ctlr*)ep->hp->aux, w, ep->tmout)) != nil)
1394 n -= (w->er[2] & 0xFFFFFF);
1402 epwrite(Ep *ep, void *va, long n)
1413 if(ep->ttype == Tctl){
1420 if(p[0] == 0x00 && p[1] == 0x05)
1423 io = (Epio*)ep->aux + OREAD;
1424 ring = io[OWRITE-OREAD].ring;
1428 ring->pending = nil;
1438 dir = (p[0] & Rd2h) != 0;
1440 io->b = allocb(len);
1441 if(dir == 0){ /* out */
1443 memmove(io->b->wp, p+8, n-8);
1445 memset(io->b->wp, 0, len);
1449 if((err = unstall(ring)) != nil)
1452 if((ring->ctx[1]>>16) != ep->maxpkt){
1453 Slot *slot = ring->slot;
1454 Ctlr *ctlr = slot->ctlr;
1455 u32int *w = slot->ibase;
1458 w += (ring->id+1)*8<<ctlr->csz;
1459 initepctx(w, ring, ep);
1460 if((err = ctlrcmd(ctlr, CR_EVALCTX | (slot->id<<24), 0, PADDR(slot->ibase), nil)) != nil)
1464 queuetd(ring, TR_SETUPSTAGE | (len > 0 ? 2+dir : 0)<<16 | TR_IDT | TR_IOC, 8,
1465 p[0] | p[1]<<8 | GET2(&p[2])<<16 |
1466 (u64int)(GET2(&p[4]) | len<<16)<<32, &w[0]);
1468 queuetd(ring, TR_DATASTAGE | dir<<16 | TR_IOC, len,
1469 PADDR(io->b->rp), &w[1]);
1470 queuetd(ring, TR_STATUSSTAGE | (len == 0 || !dir)<<16 | TR_IOC, 0, 0, &w[2]);
1472 if((err = waittd((Ctlr*)ep->hp->aux, &w[0], ep->tmout)) != nil)
1475 if((err = waittd((Ctlr*)ep->hp->aux, &w[1], ep->tmout)) != nil)
1478 io->b->wp -= (w[1].er[2] & 0xFFFFFF);
1479 if(io->b->wp < io->b->rp)
1480 io->b->wp = io->b->rp;
1483 if((err = waittd((Ctlr*)ep->hp->aux, &w[2], ep->tmout)) != nil)
1490 } else if(ep->ttype == Tiso)
1491 return isowrite(ep, p, n);
1493 if((uintptr)p <= KZERO){
1501 memmove(b->wp, p, n);
1502 n = epwrite(ep, b->wp, n);
1508 io = (Epio*)ep->aux + OWRITE;
1515 if((err = unstall(io->ring)) != nil)
1518 queuetd(io->ring, TR_NORMAL | TR_IOC, n, PADDR(p), w);
1519 if((err = waittd((Ctlr*)ep->hp->aux, w, ep->tmout)) != nil)
1529 seprintep(char *s, char*, Ep*)
1535 portstatus(Hci *hp, int port)
1537 Ctlr *ctlr = hp->aux;
1540 if(ctlr->port == nil || needrecover(ctlr))
1544 psc = ctlr->port[port-1].reg[PORTSC];
1545 if(psc & CCS) ps |= HPpresent;
1546 if(psc & PED) ps |= HPenable;
1547 if(psc & OCA) ps |= HPovercurrent;
1548 if(psc & PR) ps |= HPreset;
1550 if((hp->superspeed & (1<<(port-1))) != 0){
1551 ps |= psc & (PLS|PP);
1552 if(psc & CSC) ps |= 1<<0+16;
1553 if(psc & OCC) ps |= 1<<3+16;
1554 if(psc & PRC) ps |= 1<<4+16;
1555 if(psc & WRC) ps |= 1<<5+16;
1556 if(psc & PLC) ps |= 1<<6+16;
1557 if(psc & CEC) ps |= 1<<7+16;
1559 if((ps & HPreset) == 0){
1560 switch((psc>>10)&15){
1572 if(psc & PP) ps |= HPpower;
1573 if(psc & CSC) ps |= HPstatuschg;
1574 if(psc & PRC) ps |= HPchange;
1581 portenable(Hci*, int, int)
1587 portreset(Hci *hp, int port, int on)
1589 Ctlr *ctlr = hp->aux;
1591 if(ctlr->port == nil || needrecover(ctlr))
1595 ctlr->port[port-1].reg[PORTSC] |= PR;
1596 tsleep(&up->sleep, return0, nil, 200);
1602 static Ctlr *ctlrs[Nhcis];
1607 static int already = 0;
1618 while ((p = pcimatch(p, 0, 0)) != nil) {
1620 * Find XHCI controllers (Programming Interface = 0x30).
1622 if(p->ccrb != Pcibcserial || p->ccru != Pciscusb || p->ccrp != 0x30)
1624 io = p->mem[0].bar & ~0x0f;
1627 print("usbxhci: %#x %#x: port %#p size %#x irq %d\n",
1628 p->vid, p->did, io, p->mem[0].size, p->intl);
1629 mmio = vmap(io, p->mem[0].size);
1631 print("usbxhci: cannot map registers\n");
1634 ctlr = malloc(sizeof(Ctlr));
1636 print("usbxhci: no memory\n");
1637 vunmap(mmio, p->mem[0].size);
1644 for(i = 0; i < nelem(ctlrs); i++)
1645 if(ctlrs[i] == nil){
1649 if(i >= nelem(ctlrs))
1650 print("xhci: bug: more than %d controllers\n", nelem(ctlrs));
1660 if(getconf("*nousbxhci"))
1666 * Any adapter matches if no hp->port is supplied,
1667 * otherwise the ports must match.
1669 for(i = 0; i < nelem(ctlrs) && ctlrs[i] != nil; i++){
1671 if(ctlr->active == nil)
1672 if(hp->port == 0 || hp->port == ctlr->base){
1681 hp->port = ctlr->base;
1682 hp->irq = ctlr->pcidev->intl;
1683 hp->tbdf = ctlr->pcidev->tbdf;
1687 hp->interrupt = interrupt;
1688 hp->epopen = epopen;
1689 hp->epclose = epclose;
1690 hp->epread = epread;
1691 hp->epwrite = epwrite;
1692 hp->seprintep = seprintep;
1693 hp->portenable = portenable;
1694 hp->portreset = portreset;
1695 hp->portstatus = portstatus;
1696 hp->shutdown = shutdown;
1697 hp->debug = setdebug;
1706 addhcitype("xhci", reset);