ref: 3cd7978a72baf77bfd08e6a6be2da497393a02a9
parent: 07c7fa6716a2f54f9feab3eb56f8677edb1b033d
author: cinap_lenrek <cinap_lenrek@felloff.net>
date: Thu Mar 5 18:48:23 EST 2015
zynq: fix usb by implementing delay() and give proper port speed in portstatus
--- a/sys/src/9/zynq/timer.c
+++ b/sys/src/9/zynq/timer.c
@@ -23,13 +23,19 @@
uvlong timerhz;
void
-delay(int)
+microdelay(int n)
{
+ ulong now;
+
+ now = µs();
+ while(µs() - now < n);
}
void
-microdelay(int)
+delay(int n)
{
+ while(--n >= 0)
+ microdelay(1000);
}
uvlong
--- a/sys/src/9/zynq/usbehcizynq.c
+++ b/sys/src/9/zynq/usbehcizynq.c
@@ -102,7 +102,30 @@
}
}
+static int (*ehciportstatus)(Hci*,int);
+
static int
+portstatus(Hci *hp, int port)
+{
+ Ctlr *ctlr;
+ Eopio *opio;
+ int r, sts;
+
+ ctlr = hp->aux;
+ opio = ctlr->opio;
+ r = (*ehciportstatus)(hp, port);
+ if(r & HPpresent){
+ sts = opio->portsc[port-1];
+ r &= ~(HPhigh|HPslow);
+ if(sts & (1<<9))
+ r |= HPhigh;
+ else if(sts & 1<<26)
+ r |= HPslow;
+ }
+ return r;
+}
+
+static int
reset(Hci *hp)
{
static Lock resetlck;
@@ -124,7 +147,7 @@
ctlr->r = vmap(ctlr->base, 0x1F0);
ctlr->opio = (Eopio *) ((uchar *) ctlr->r + 0x140);
ctlr->capio = (void *) ctlr->base;
- hp->nports = 1;
+ hp->nports = 1;
ctlr->tdalloc = tdalloc;
ctlr->dmaalloc = dmaalloc;
@@ -136,6 +159,11 @@
ctlr->r[ULPI] = 1<<30 | 1<<29 | 0x0B << 16 | 3<<5;
ehcimeminit(ctlr);
ehcilinkage(hp);
+
+ /* hook portstatus */
+ ehciportstatus = hp->portstatus;
+ hp->portstatus = portstatus;
+
if(hp->interrupt != nil)
intrenable(hp->irq, hp->interrupt, hp, LEVEL, hp->type);
return 0;