ref: 995379e388e4cd202f683a00e99749c7f21a225d
parent: 6b2d1f0186f2e38a3b0cd6a19b5980dccb045c3c
author: cinap_lenrek <[email protected]>
date: Fri Feb 13 22:00:31 EST 2015
usbehci: initial support for usb on zynq, remove uncached.h the following hooks have been added to the ehci Ctlr structore to handle cache coherency (on arm): void* (*tdalloc)(ulong,int,ulong); void* (*dmaalloc)(ulong); void (*dmafree)(void*); void (*dmaflush)(int,void*,ulong); tdalloc() is used to allocate descriptors and the periodic frame schedule array. on arm, this needs to return uncached memory. tdalloc()ed memory is never freed. dmaalloc()/dmafree() is used for io buffers. this can return cached memory when when hardware maintains cache coherency (pc) or dmaflush() is provided to flush/invalidate the cache (zynq), otherwise needs to return uncached memory. dmaflush() is used to flush/invalidate the cache. the first argument tells us if we need to flush (non zero) or invalidate (zero). uncached.h is gone now. this change makes the handling explicit.
--- a/sys/src/9/kw/fns.h
+++ b/sys/src/9/kw/fns.h
@@ -110,7 +110,7 @@
uintptr mmukunmap(uintptr, uintptr, usize);
extern void* mmuuncache(void*, usize);
extern void* ucalloc(usize);
-extern void* ucallocalign(usize size, int align, int span);
+extern void* ucallocalign(usize size, int align, usize span);
extern Block* ucallocb(int);
extern void ucfree(void*);
extern void ucfreeb(Block*);
--- a/sys/src/9/kw/mkfile
+++ b/sys/src/9/kw/mkfile
@@ -132,7 +132,7 @@
main.$O: errstr.h init.h reboot.h
mouse.$O: screen.h
devusb.$O: ../port/usb.h
-usbehci.$O usbohci.$O usbuhci.$O: ../port/usb.h usbehci.h uncached.h
+usbehci.$O usbohci.$O usbuhci.$O: ../port/usb.h usbehci.h
init.h:D: ../port/initcode.c init9.s
$CC ../port/initcode.c
--- a/sys/src/9/kw/mmu.c
+++ b/sys/src/9/kw/mmu.c
@@ -261,7 +261,7 @@
for(page = proc->mmul2cache; page != nil; page = next){
next = page->next;
if(--page->ref)
- panic("mmurelease: page->ref %d", page->ref);
+ panic("mmurelease: page->ref %lud", page->ref);
pagechainhead(page);
}
if(proc->mmul2cache && palloc.r.p)
--- a/sys/src/9/kw/ucalloc.c
+++ b/sys/src/9/kw/ucalloc.c
@@ -127,7 +127,7 @@
}
void*
-ucallocalign(usize size, int align, int span)
+ucallocalign(usize size, int align, usize span)
{
assert(size < ucpool.minarena-128);
--- a/sys/src/9/kw/uncached.h
+++ /dev/null
@@ -1,36 +1,0 @@
-/*
- * running the l2 cache as write-back and using cached memory for
- * usb data structures yields spurious errors such as
- *
- * qhintr: td 0x60ee3d80 csw 0x8824a error 0x48 transaction error
- *
- * from usbehci. so, at least for now, we will use uncached memory until
- * we sort out the write-back problems.
- */
-#define free ucfree
-#define malloc myucalloc
-#define mallocz ucallocz
-#define smalloc myucalloc
-#define xspanalloc ucallocalign
-
-#define allocb ucallocb
-#define iallocb uciallocb
-#define freeb ucfreeb
-
-static void *
-ucallocz(uint n, int)
-{
- char *p = ucalloc(n);
-
- if (p)
- memset(p, 0, n);
- else
- panic("ucalloc: out of memory");
- return p;
-}
-
-static void *
-myucalloc(uint n)
-{
- return ucallocz(n, 1);
-}
--- a/sys/src/9/kw/usbehci.h
+++ b/sys/src/9/kw/usbehci.h
@@ -172,6 +172,11 @@
Ecapio* capio; /* Capability i/o regs */
Eopio* opio; /* Operational i/o regs */
+ void* (*tdalloc)(ulong,int,ulong);
+ void* (*dmaalloc)(ulong);
+ void (*dmafree)(void*);
+ void (*dmaflush)(int,void*,ulong len);
+
int nframes; /* 1024, 512, or 256 frames in the list */
ulong* frames; /* periodic frame list (hw) */
Qh* qhs; /* async Qh circular list for bulk/ctl */
--- a/sys/src/9/kw/usbehcikw.c
+++ b/sys/src/9/kw/usbehcikw.c
@@ -13,7 +13,6 @@
#include "../port/error.h"
#include "../port/usb.h"
#include "usbehci.h"
-//#include "uncached.h"
#define WINTARG(ctl) (((ctl) >> 4) & 017)
#define WINATTR(ctl) (((ctl) >> 8) & 0377)
@@ -330,6 +329,10 @@
ddprint("ehci: routing %s, %sport power ctl, %d ports\n",
capio->parms & 0x40 ? "explicit" : "automatic",
capio->parms & 0x10 ? "" : "no ", hp->nports);
+
+ ctlr->tdalloc = ucallocalign;
+ ctlr->dmaalloc = ucalloc;
+ ctlr->dmafree = ucfree;
ehcireset(ctlr);
ehcimeminit(ctlr);
--- a/sys/src/9/omap/mkfile
+++ b/sys/src/9/omap/mkfile
@@ -111,7 +111,7 @@
main.$O: errstr.h init.h reboot.h
devdss.$O devmouse.$O mouse.$O screen.$O: screen.h
devusb.$O: ../port/usb.h
-usbehci.$O usbohci.$O usbuhci.$O: ../port/usb.h usbehci.h uncached.h
+usbehci.$O usbohci.$O usbuhci.$O: ../port/usb.h usbehci.h
init.h:D: ../port/initcode.c init9.s
$CC ../port/initcode.c
--- a/sys/src/9/omap/uncached.h
+++ /dev/null
@@ -1,36 +1,0 @@
-/*
- * running the l2 cache as write-back and using cached memory for
- * usb data structures yields spurious errors such as
- *
- * qhintr: td 0x60ee3d80 csw 0x8824a error 0x48 transaction error
- *
- * from usbehci. so, at least for now, we will use uncached memory until
- * we sort out the write-back problems.
- */
-#define free ucfree
-#define malloc myucalloc
-#define mallocz ucallocz
-#define smalloc myucalloc
-#define xspanalloc ucallocalign
-
-#define allocb ucallocb
-#define iallocb uciallocb
-#define freeb ucfreeb
-
-static void *
-ucallocz(uint n, int)
-{
- char *p = ucalloc(n);
-
- if (p)
- memset(p, 0, n);
- else
- panic("ucalloc: out of memory");
- return p;
-}
-
-static void *
-myucalloc(uint n)
-{
- return ucallocz(n, 1);
-}
--- a/sys/src/9/omap/usbehci.h
+++ b/sys/src/9/omap/usbehci.h
@@ -39,6 +39,11 @@
Ecapio* capio; /* Capability i/o regs */
Eopio* opio; /* Operational i/o regs */
+ void* (*tdalloc)(ulong,int,ulong);
+ void* (*dmaalloc)(ulong);
+ void (*dmafree)(void*);
+ void (*dmaflush)(int,void*,ulong len);
+
int nframes; /* 1024, 512, or 256 frames in the list */
ulong* frames; /* periodic frame list (hw) */
Qh* qhs; /* async Qh circular list for bulk/ctl */
--- a/sys/src/9/omap/usbehciomap.c
+++ b/sys/src/9/omap/usbehciomap.c
@@ -178,6 +178,10 @@
capio->parms & 0x40 ? "explicit" : "automatic",
capio->parms & 0x10 ? "" : "no ", hp->nports);
+ ctlr->tdalloc = ucallocalign;
+ ctlr->dmaalloc = ucalloc;
+ cltr->dmafree = ucfree;
+
ehcireset(ctlr);
ehcimeminit(ctlr);
--- a/sys/src/9/pc/uncached.h
+++ /dev/null
@@ -1,4 +1,0 @@
-/*
- * On the PC, processor accesses, memory caches and DMA are all
- * coherent, so we don't need to use uncached memory.
- */
--- a/sys/src/9/pc/usbehci.h
+++ b/sys/src/9/pc/usbehci.h
@@ -174,6 +174,11 @@
Ecapio* capio; /* Capability i/o regs */
Eopio* opio; /* Operational i/o regs */
+ void* (*tdalloc)(ulong,int,ulong);
+ void* (*dmaalloc)(ulong);
+ void (*dmafree)(void*);
+ void (*dmaflush)(int,void*,ulong len);
+
int nframes; /* 1024, 512, or 256 frames in the list */
ulong* frames; /* periodic frame list (hw) */
Qh* qhs; /* async Qh circular list for bulk/ctl */
--- a/sys/src/9/pc64/mkfile
+++ b/sys/src/9/pc64/mkfile
@@ -83,7 +83,7 @@
# copies generated by the rule below
-PCHEADERS=wifi.h uncached.h usbehci.h screen.h etherif.h ethermii.h mp.h io.h ahci.h
+PCHEADERS=wifi.h usbehci.h screen.h etherif.h ethermii.h mp.h io.h ahci.h
REPCH=`{echo $PCHEADERS | sed 's/\.h//g; s/ /|/g'}
^($REPCH)\.h:R: '../pc/\1.h'
@@ -117,7 +117,7 @@
main.$O: init.h reboot.h
devusb.$O usbuhci.$O usbohci.$O usbehci.$O: ../port/usb.h
-usbehci.$O: usbehci.h uncached.h
+usbehci.$O: usbehci.h
trap.$O: /sys/include/tos.h
ethermii.$O: ethermii.h
etheriwl.$O: wifi.h
--- a/sys/src/9/port/usbehci.c
+++ b/sys/src/9/port/usbehci.c
@@ -20,7 +20,6 @@
#include "../port/error.h"
#include "../port/usb.h"
#include "usbehci.h"
-#include "uncached.h"
#define diprint if(ehcidebug || iso->debug)print
#define ddiprint if(ehcidebug>1 || iso->debug>1)print
@@ -399,7 +398,7 @@
}
static void*
-edalloc(void)
+edalloc(Ctlr *ctlr)
{
Ed *ed, *pool;
int i;
@@ -406,7 +405,7 @@
lock(&edpool);
if(edpool.free == nil){
- pool = xspanalloc(Incr*sizeof(Ed), Align, 0);
+ pool = (*ctlr->tdalloc)(Incr*sizeof(Ed), Align, 0);
if(pool == nil)
panic("edalloc");
for(i=Incr; --i>=0;){
@@ -448,53 +447,54 @@
*/
static Itd*
-itdalloc(void)
+itdalloc(Ctlr *ctlr)
{
Itd *td;
- td = edalloc();
+ td = edalloc(ctlr);
td->link = Lterm;
return td;
}
static void
-itdfree(Itd *td)
+itdfree(Ctlr*, Itd *td)
{
edfree(td);
}
static Sitd*
-sitdalloc(void)
+sitdalloc(Ctlr *ctlr)
{
Sitd *td;
- td = edalloc();
+ td = edalloc(ctlr);
td->link = td->blink = Lterm;
return td;
}
static void
-sitdfree(Sitd *td)
+sitdfree(Ctlr*, Sitd *td)
{
edfree(td);
}
static Td*
-tdalloc(void)
+tdalloc(Ctlr *ctlr)
{
Td *td;
- td = edalloc();
+ td = edalloc(ctlr);
td->nlink = td->alink = Lterm;
return td;
}
static void
-tdfree(Td *td)
+tdfree(Ctlr *ctlr, Td *td)
{
if(td == nil)
return;
- free(td->buff);
+ if(td->buff != nil)
+ (*ctlr->dmafree)(td->buff);
edfree(td);
}
@@ -661,7 +661,7 @@
Qh *qh;
int ttype;
- qh = edalloc();
+ qh = edalloc(ctlr);
qh->nlink = Lterm;
qh->alink = Lterm;
qh->csw = Tdhalt;
@@ -777,7 +777,7 @@
while((td = qh->tds) != nil){
qh->tds = td->next;
- tdfree(td);
+ tdfree(ctlr, td);
}
edfree(qh);
@@ -1236,7 +1236,7 @@
}
static void
-itdinit(Isoio *iso, Itd *td)
+itdinit(Ctlr *ctlr, Isoio *iso, Itd *td)
{
int p, t;
ulong pa, tsize, size;
@@ -1248,6 +1248,8 @@
*/
p = 0;
size = td->ndata = td->mdata;
+ if(ctlr->dmaflush != nil)
+ (*ctlr->dmaflush)(1, td->data, size);
pa = PADDR(td->data);
for(t = 0; size > 0 && t < 8; t++){
tsize = size;
@@ -1265,8 +1267,10 @@
}
static void
-sitdinit(Isoio *iso, Sitd *td)
+sitdinit(Ctlr *ctlr, Isoio *iso, Sitd *td)
{
+ if(ctlr->dmaflush != nil)
+ (*ctlr->dmaflush)(1, td->data, td->mdata);
td->ndata = td->mdata & Stdlenmask;
td->buffer[0] = PADDR(td->data);
td->buffer[1] = (td->buffer[0] & ~0xFFF) + 0x1000;
@@ -1379,7 +1383,7 @@
tdi->ndata = 0;
if(tdi->next == iso->tdu || tdi->next->next == iso->tdu){
memset(iso->tdu->data, 0, iso->tdu->mdata);
- itdinit(iso, iso->tdu);
+ itdinit(ctlr, iso, iso->tdu);
iso->tdu = iso->tdu->next;
iso->nleft = 0;
}
@@ -1444,8 +1448,7 @@
if(stdi->next == iso->stdu || stdi->next->next == iso->stdu){
memset(iso->stdu->data, 0, iso->stdu->mdata);
- coherence();
- sitdinit(iso, iso->stdu);
+ sitdinit(ctlr, iso, iso->stdu);
iso->stdu = iso->stdu->next;
iso->nleft = 0;
}
@@ -1883,6 +1886,8 @@
ep->dev->nb, ep->nb);
else{
iunlock(ctlr); /* We could page fault here */
+ if(ctlr->dmaflush != nil)
+ (*ctlr->dmaflush)(0, tdu->data, tdu->mdata);
memmove(b+tot, tdu->data, nr);
ilock(ctlr);
if(iso->tdu != tdu)
@@ -1893,7 +1898,7 @@
coherence();
}
if(tdu->ndata == 0){
- itdinit(iso, tdu);
+ itdinit(ctlr, iso, tdu);
iso->tdu = tdu->next;
}
}
@@ -1921,6 +1926,8 @@
ep->dev->nb, ep->nb);
else{
iunlock(ctlr); /* We could page fault here */
+ if(ctlr->dmaflush != nil)
+ (*ctlr->dmaflush)(0, stdu->data, stdu->mdata);
memmove(b+tot, stdu->data, nr);
ilock(ctlr);
if(iso->stdu != stdu)
@@ -1932,7 +1939,7 @@
coherence();
}
if(stdu->ndata == 0){
- sitdinit(iso, stdu);
+ sitdinit(ctlr, iso, stdu);
iso->stdu = stdu->next;
}
}
@@ -2024,7 +2031,7 @@
continue;
iso->nleft += n;
if(iso->nleft == tdu->mdata){
- itdinit(iso, tdu);
+ itdinit(ctlr, iso, tdu);
iso->tdu = tdu->next;
iso->nleft = 0;
}
@@ -2039,7 +2046,7 @@
continue;
iso->nleft += n;
if(iso->nleft == stdu->mdata){
- sitdinit(iso, stdu);
+ sitdinit(ctlr, iso, stdu);
iso->stdu = stdu->next;
iso->nleft = 0;
}
@@ -2137,7 +2144,7 @@
}
static Td*
-epgettd(Qio *io, int flags, void *a, int count, int maxpkt)
+epgettd(Ctlr *ctlr, Qio *io, int flags, void *a, int count, int maxpkt)
{
Td *td;
ulong pa;
@@ -2145,7 +2152,7 @@
if(count > Tdmaxpkt)
panic("ehci: epgettd: too many bytes");
- td = tdalloc();
+ td = tdalloc(ctlr);
td->csw = flags | io->toggle | io->tok | count << Tdlenshift |
Tderr2 | Tderr1;
coherence();
@@ -2159,12 +2166,16 @@
td->data = td->sbuff;
td->buff = nil;
} else if(count <= 0x4000){
- td->buff = td->data = smalloc(count);
+ td->buff = td->data = (*ctlr->dmaalloc)(count);
} else {
- td->buff = smalloc(count + 0x1000);
+ td->buff = (*ctlr->dmaalloc)(count+0x1000);
td->data = (uchar*)ROUND((uintptr)td->buff, 0x1000);
}
-
+ if(a != nil && count > 0){
+ memmove(td->data, a, count);
+ if(ctlr->dmaflush != nil && td->buff != nil)
+ (*ctlr->dmaflush)(1, td->data, count);
+ }
pa = PADDR(td->data);
for(i = 0; i < nelem(td->buffer); i++){
td->buffer[i] = pa;
@@ -2172,8 +2183,6 @@
pa += 0x1000;
}
td->ndata = count;
- if(a != nil && count > 0)
- memmove(td->data, a, count);
coherence();
io->toggle = nexttoggle(io->toggle, count, maxpkt);
coherence();
@@ -2386,9 +2395,9 @@
if(count-tot < n)
n = count-tot;
if(c != nil && io->tok != Tdtokin)
- td = epgettd(io, Tdactive, c+tot, n, ep->maxpkt);
+ td = epgettd(ctlr, io, Tdactive, c+tot, n, ep->maxpkt);
else
- td = epgettd(io, Tdactive, nil, n, ep->maxpkt);
+ td = epgettd(ctlr, io, Tdactive, nil, n, ep->maxpkt);
if(td0 == nil)
td0 = td;
else
@@ -2452,6 +2461,8 @@
if((tot + n) > count)
n = count - tot;
if(c != nil && (td->csw & Tdtok) == Tdtokin){
+ if(ctlr->dmaflush != nil && td->buff != nil)
+ (*ctlr->dmaflush)(0, td->data, n);
memmove(c, td->data, n);
c += n;
}
@@ -2459,7 +2470,7 @@
}
}
ntd = td->next;
- tdfree(td);
+ tdfree(ctlr, td);
}
if(mustlock){
qunlock(io);
@@ -2679,12 +2690,14 @@
Sitd *td, *ltd;
int i;
ulong frno;
+ Ctlr *ctlr;
+ ctlr = ep->hp->aux;
left = 0;
ltd = nil;
frno = iso->td0frno;
for(i = 0; i < iso->nframes; i++){
- td = sitdalloc();
+ td = sitdalloc(ctlr);
td->data = iso->data + i * ep->maxpkt;
td->epc = ep->dev->port << Stdportshift;
td->epc |= ep->dev->hub << Stdhubshift;
@@ -2710,7 +2723,7 @@
iso->sitdps[frno] = td;
coherence();
- sitdinit(iso, td);
+ sitdinit(ctlr, iso, td);
if(ltd != nil)
ltd->next = td;
ltd = td;
@@ -2727,16 +2740,18 @@
long left;
ulong frno, i, pa;
Itd *ltd, *td;
+ Ctlr *ctlr;
iso->hs = 1;
ival = 1;
if(ep->pollival > 8)
ival = ep->pollival/8;
+ ctlr = ep->hp->aux;
left = 0;
ltd = nil;
frno = iso->td0frno;
for(i = 0; i < iso->nframes; i++){
- td = itdalloc();
+ td = itdalloc(ctlr);
td->data = iso->data + i * 8 * iso->maxsize;
pa = PADDR(td->data) & ~0xFFF;
for(p = 0; p < nelem(td->buffer); p++){
@@ -2761,7 +2776,7 @@
coherence();
iso->itdps[frno] = td;
coherence();
- itdinit(iso, td);
+ itdinit(ctlr, iso, td);
if(ltd != nil)
ltd->next = td;
ltd = td;
@@ -2826,8 +2841,8 @@
*/
assert(ep->maxpkt > 0 && ep->ntds > 0 && ep->ntds < 4);
assert(ep->maxpkt <= 1024);
- iso->tdps = smalloc(sizeof(uintptr) * Nisoframes);
- iso->data = smalloc(iso->nframes * tpf * ep->ntds * ep->maxpkt);
+ iso->tdps = smalloc(sizeof(void*) * Nisoframes);
+ iso->data = (*ctlr->dmaalloc)(iso->nframes * tpf * ep->ntds * ep->maxpkt);
iso->td0frno = TRUNC(ctlr->opio->frno + 10, Nisoframes);
/* read: now; write: 1s ahead */
@@ -3067,9 +3082,9 @@
frno = iso->td0frno;
for(i = 0; i < iso->nframes; i++){
if(iso->hs != 0)
- itdfree(iso->itdps[frno]);
+ itdfree(ctlr, iso->itdps[frno]);
else
- sitdfree(iso->sitdps[frno]);
+ sitdfree(ctlr, iso->sitdps[frno]);
iso->tdps[frno] = nil;
frno = TRUNC(frno+pollival, Nisoframes);
}
@@ -3165,7 +3180,7 @@
if(qt->bw == nil || tree == nil)
panic("ehci: mkqhtree: no memory");
for(i = 0; i < n; i++){
- tree[i] = qh = edalloc();
+ tree[i] = qh = edalloc(ctlr);
if(qh == nil)
panic("ehci: mkqhtree: no memory");
qh->nlink = qh->alink = qh->link = Lterm;
@@ -3208,10 +3223,17 @@
int i, frsize;
Eopio *opio;
+ if(ctlr->tdalloc == nil)
+ ctlr->tdalloc = xspanalloc;
+ if(ctlr->dmaalloc == nil)
+ ctlr->dmaalloc = smalloc;
+ if(ctlr->dmafree == nil)
+ ctlr->dmafree = free;
+
opio = ctlr->opio;
frsize = ctlr->nframes * sizeof(ulong);
assert((frsize & 0xFFF) == 0); /* must be 4k aligned */
- ctlr->frames = xspanalloc(frsize, frsize, 0);
+ ctlr->frames = (*ctlr->tdalloc)(frsize, frsize, 0);
if(ctlr->frames == nil)
panic("ehci reset: no memory");
@@ -3223,7 +3245,7 @@
qhalloc(ctlr, nil, nil, nil); /* init async list */
mkqhtree(ctlr); /* init sync list */
- edfree(edalloc()); /* try to get some ones pre-allocated */
+ edfree(edalloc(ctlr)); /* try to get some ones pre-allocated */
dprint("ehci %#p flb %#lux frno %#lux\n",
ctlr->capio, opio->frbase, opio->frno);
--- a/sys/src/9/zynq/mkfile
+++ b/sys/src/9/zynq/mkfile
@@ -86,5 +86,5 @@
for(i in $EXTRACOPIES)
import $i / /n/$i && cp $p$CONF $p$CONF.gz /n/$i/$objtype/
-devusb.$O usbehci.$O usbehcizynq.$O: ../port/usb.h uncached.h
+devusb.$O usbehci.$O usbehcizynq.$O: ../port/usb.h
usbehci.$O usbehcizynq.$O: usbehci.h
--- a/sys/src/9/zynq/uncached.h
+++ /dev/null
@@ -1,27 +1,0 @@
-#define free ucfree
-#define malloc myucalloc
-#define mallocz ucallocz
-#define smalloc myucalloc
-#define xspanalloc ucallocalign
-
-#define allocb ucallocb
-#define iallocb uciallocb
-#define freeb ucfreeb
-
-static void *
-ucallocz(uint n, int)
-{
- char *p = ucalloc(n);
-
- if (p)
- memset(p, 0, n);
- else
- panic("ucalloc: out of memory");
- return p;
-}
-
-static void *
-myucalloc(uint n)
-{
- return ucallocz(n, 1);
-}
--- a/sys/src/9/zynq/usbehci.h
+++ b/sys/src/9/zynq/usbehci.h
@@ -84,16 +84,30 @@
struct Eopio
{
- ulong cmd;
- ulong sts;
- ulong intr;
- ulong frno;
- ulong dummy1[2];
- ulong frbase;
- ulong link;
- ulong dummy2[9];
- ulong config;
- ulong portsc[1];
+/*140*/ ulong cmd;
+/*144*/ ulong sts;
+/*148*/ ulong intr;
+/*14c*/ ulong frno;
+
+/*150*/ ulong reserved1;
+
+/*154*/ ulong frbase;
+/*158*/ ulong link;
+
+/*15c*/ ulong _ttctrl;
+/*160*/ ulong _burstsize;
+/*164*/ ulong _txfilltuning;
+/*168*/ ulong _txttfilltuning;
+/*16c*/ ulong _ic_usb;
+/*170*/ ulong _ulpi_viewport;
+
+/*174*/ ulong reserved2;
+
+/*178*/ ulong _endptnak;
+/*17c*/ ulong _endptnaken;
+
+/*180*/ ulong config;
+/*184*/ ulong portsc[1];
};
struct Poll
@@ -112,6 +126,11 @@
int active; /* in use or not */
void* capio; /* base address for debug info */
Eopio* opio; /* Operational i/o regs */
+
+ void* (*tdalloc)(ulong,int,ulong);
+ void* (*dmaalloc)(ulong);
+ void (*dmafree)(void*);
+ void (*dmaflush)(int,void*,ulong len);
int nframes; /* 1024, 512, or 256 frames in the list */
ulong* frames; /* periodic frame list (hw) */
--- a/sys/src/9/zynq/usbehcizynq.c
+++ b/sys/src/9/zynq/usbehcizynq.c
@@ -61,6 +61,47 @@
iunlock(ctlr);
}
+enum {
+ Cls = 64,
+};
+
+/* descriptors need to be allocated in uncached memory */
+static void*
+tdalloc(ulong size, int, ulong)
+{
+ return ucalloc(size);
+}
+
+static void*
+dmaalloc(ulong len)
+{
+ return mallocalign(ROUND(len, Cls), Cls, 0, 0);
+}
+static void
+dmafree(void *data)
+{
+ free(data);
+}
+
+static void
+dmaflush(int clean, void *data, ulong len)
+{
+ uintptr va, pa;
+
+ va = (uintptr)data & ~(Cls-1);
+ pa = PADDR(va);
+ len = ROUND(len, Cls);
+ if(clean){
+ /* flush cache before write */
+ cleandse((uchar*)va, (uchar*)va+len);
+ clean2pa(pa, pa+len);
+ } else {
+ /* invalidate cache before read */
+ invaldse((uchar*)va, (uchar*)va+len);
+ inval2pa(pa, pa+len);
+ }
+}
+
static int
reset(Hci *hp)
{
@@ -84,12 +125,17 @@
ctlr->opio = (Eopio *) ((uchar *) ctlr->r + 0x140);
ctlr->capio = (void *) ctlr->base;
hp->nports = 1;
- ctlr->r[USBMODE] |= USBHOST;
-
+
+ ctlr->tdalloc = tdalloc;
+ ctlr->dmaalloc = dmaalloc;
+ ctlr->dmafree = dmafree;
+ ctlr->dmaflush = dmaflush;
+
ehcireset(ctlr);
+ ctlr->r[USBMODE] |= USBHOST;
+ ctlr->r[ULPI] = 1<<30 | 1<<29 | 0x0B << 16 | 3<<5;
ehcimeminit(ctlr);
ehcilinkage(hp);
- ctlr->r[ULPI] = 1<<30 | 1<<29 | 0x0B << 16 | 3<<5;
if(hp->interrupt != nil)
intrenable(hp->irq, hp->interrupt, hp, LEVEL, hp->type);
return 0;
@@ -98,6 +144,6 @@
void
usbehcilink(void)
{
- ehcidebug = 2;
+// ehcidebug = 2;
addhcitype("ehci", reset);
}
--- a/sys/src/9/zynq/zynq
+++ b/sys/src/9/zynq/zynq
@@ -26,7 +26,7 @@
etherzynq
ethermedium
loopbackmedium
-# usbehci usbehcizynq
+ usbehci usbehcizynq
misc
uartzynq