usbehci: introduce dmaflush() function to handle portable cache invalidation for device drivers
This commit is contained in:
parent
a4688b0322
commit
19a883ce7a
15 changed files with 163 additions and 297 deletions
|
@ -175,7 +175,6 @@ struct Ctlr
|
|||
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) */
|
||||
|
@ -245,3 +244,5 @@ extern int ehcidebug;
|
|||
void ehcilinkage(Hci *hp);
|
||||
void ehcimeminit(Ctlr *ctlr);
|
||||
void ehcirun(Ctlr *ctlr, int on);
|
||||
|
||||
#define dmaflush(clean, addr, len)
|
||||
|
|
|
@ -18,7 +18,6 @@
|
|||
#include "../port/etherif.h"
|
||||
#include "../port/flashif.h"
|
||||
#include "../port/usb.h"
|
||||
#include "../port/portusbehci.h"
|
||||
#include "usbehci.h"
|
||||
|
||||
#define FREQSEL(x) ((x) << 4)
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
|
||||
typedef struct Ctlr Ctlr;
|
||||
typedef struct Eopio Eopio;
|
||||
typedef struct Ecapio Ecapio;
|
||||
typedef struct Isoio Isoio;
|
||||
typedef struct Poll Poll;
|
||||
typedef struct Qh Qh;
|
||||
|
@ -22,6 +23,116 @@ typedef struct Qtree Qtree;
|
|||
#pragma incomplete Qh;
|
||||
#pragma incomplete Qtree;
|
||||
|
||||
enum
|
||||
{
|
||||
/* Ecapio->parms reg. */
|
||||
Cnports = 0xF, /* nport bits */
|
||||
Cdbgportshift = 20, /* debug port */
|
||||
Cdbgportmask = 0xF,
|
||||
|
||||
/* Ecapio->capparms bits */
|
||||
C64 = 1<<0, /* 64-bits */
|
||||
Cpfl = 1<<1, /* program'ble frame list: can be <1024 */
|
||||
Casp = 1<<2, /* asynch. sched. park */
|
||||
Ceecpshift = 8, /* extended capabilities ptr. */
|
||||
Ceecpmask = (1<<8) - 1,
|
||||
|
||||
Clegacy = 1, /* legacy support cap. id */
|
||||
CLbiossem = 2, /* legacy cap. bios sem. */
|
||||
CLossem = 3, /* legacy cap. os sem */
|
||||
CLcontrol = 4, /* legacy support control & status */
|
||||
|
||||
/* typed links */
|
||||
Lterm = 1,
|
||||
Litd = 0<<1,
|
||||
Lqh = 1<<1,
|
||||
Lsitd = 2<<1,
|
||||
Lfstn = 3<<1, /* we don't use these */
|
||||
|
||||
/* Cmd reg. */
|
||||
Cstop = 0x00000, /* stop running */
|
||||
Crun = 0x00001, /* start operation */
|
||||
Chcreset = 0x00002, /* host controller reset */
|
||||
Cflsmask = 0x0000C, /* frame list size bits */
|
||||
Cfls1024 = 0x00000, /* frame list size 1024 */
|
||||
Cfls512 = 0x00004, /* frame list size 512 frames */
|
||||
Cfls256 = 0x00008, /* frame list size 256 frames */
|
||||
Cpse = 0x00010, /* periodic sched. enable */
|
||||
Case = 0x00020, /* async sched. enable */
|
||||
Ciasync = 0x00040, /* interrupt on async advance doorbell */
|
||||
/* interrupt threshold ctl. in µframes (1-32 in powers of 2) */
|
||||
Citcshift = 16,
|
||||
Citcmask = 0xff << Citcshift,
|
||||
|
||||
/* Sts reg. */
|
||||
Sasyncss = 0x08000, /* aync schedule status */
|
||||
Speriodss = 0x04000, /* periodic schedule status */
|
||||
Srecl = 0x02000, /* reclamnation (empty async sched.) */
|
||||
Shalted = 0x01000, /* h.c. is halted */
|
||||
Sasync = 0x00020, /* interrupt on async advance */
|
||||
Sherr = 0x00010, /* host system error */
|
||||
Sfrroll = 0x00008, /* frame list roll over */
|
||||
Sportchg = 0x00004, /* port change detect */
|
||||
Serrintr = 0x00002, /* error interrupt */
|
||||
Sintr = 0x00001, /* interrupt */
|
||||
Sintrs = 0x0003F, /* interrupts status */
|
||||
|
||||
/* Intr reg. */
|
||||
Iusb = 0x01, /* intr. on usb */
|
||||
Ierr = 0x02, /* intr. on usb error */
|
||||
Iportchg = 0x04, /* intr. on port change */
|
||||
Ifrroll = 0x08, /* intr. on frlist roll over */
|
||||
Ihcerr = 0x10, /* intr. on host error */
|
||||
Iasync = 0x20, /* intr. on async advance enable */
|
||||
Iall = 0x3F, /* all interrupts */
|
||||
|
||||
/* Config reg. */
|
||||
Callmine = 1, /* route all ports to us */
|
||||
|
||||
/* Portsc reg. */
|
||||
Pspresent = 0x00000001, /* device present */
|
||||
Psstatuschg = 0x00000002, /* Pspresent changed */
|
||||
Psenable = 0x00000004, /* device enabled */
|
||||
Pschange = 0x00000008, /* Psenable changed */
|
||||
Psresume = 0x00000040, /* resume detected */
|
||||
Pssuspend = 0x00000080, /* port suspended */
|
||||
Psreset = 0x00000100, /* port reset */
|
||||
Pspower = 0x00001000, /* port power on */
|
||||
Psowner = 0x00002000, /* port owned by companion */
|
||||
Pslinemask = 0x00000C00, /* line status bits */
|
||||
Pslow = 0x00000400, /* low speed device */
|
||||
|
||||
/* Debug port csw reg. */
|
||||
Cowner = 0x40000000, /* port owned by ehci */
|
||||
Cenable = 0x10000000, /* debug port enabled */
|
||||
Cdone = 0x00010000, /* request is done */
|
||||
Cbusy = 0x00000400, /* port in use by a driver */
|
||||
Cerrmask= 0x00000380, /* error code bits */
|
||||
Chwerr = 0x00000100, /* hardware error */
|
||||
Cterr = 0x00000080, /* transaction error */
|
||||
Cfailed = 0x00000040, /* transaction did fail */
|
||||
Cgo = 0x00000020, /* execute the transaction */
|
||||
Cwrite = 0x00000010, /* request is a write */
|
||||
Clen = 0x0000000F, /* data len */
|
||||
|
||||
/* Debug port pid reg. */
|
||||
Prpidshift = 16, /* received pid */
|
||||
Prpidmask = 0xFF,
|
||||
Pspidshift = 8, /* sent pid */
|
||||
Pspidmask = 0xFF,
|
||||
Ptokshift = 0, /* token pid */
|
||||
Ptokmask = 0xFF,
|
||||
|
||||
Ptoggle = 0x00008800, /* to update toggles */
|
||||
Ptogglemask = 0x0000FF00,
|
||||
|
||||
/* Debug port addr reg. */
|
||||
Adevshift = 8, /* device address */
|
||||
Adevmask = 0x7F,
|
||||
Aepshift = 0, /* endpoint number */
|
||||
Aepmask = 0xF,
|
||||
};
|
||||
|
||||
struct Poll
|
||||
{
|
||||
Lock;
|
||||
|
@ -39,10 +150,9 @@ struct Ctlr
|
|||
Ecapio* capio; /* Capability i/o regs */
|
||||
Eopio* opio; /* Operational i/o regs */
|
||||
|
||||
void* (*tdalloc)(ulong,int,ulong);
|
||||
void* (*dmaalloc)(ulong);
|
||||
void* (*tdalloc)(usize,int,usize);
|
||||
void* (*dmaalloc)(usize);
|
||||
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) */
|
||||
|
@ -82,6 +192,17 @@ struct Eopio
|
|||
ulong insn[6]; /* implementation-specific */
|
||||
};
|
||||
|
||||
/*
|
||||
* Capability registers (hw)
|
||||
*/
|
||||
struct Ecapio
|
||||
{
|
||||
ulong cap; /* 00 controller capability register */
|
||||
ulong parms; /* 04 structural parameters register */
|
||||
ulong capparms; /* 08 capability parameters */
|
||||
ulong portroute; /* 0c not on the CS5536 */
|
||||
};
|
||||
|
||||
typedef struct Uhh Uhh;
|
||||
struct Uhh {
|
||||
ulong revision; /* ro */
|
||||
|
@ -107,3 +228,5 @@ extern int ehcidebug;
|
|||
void ehcilinkage(Hci *hp);
|
||||
void ehcimeminit(Ctlr *ctlr);
|
||||
void ehcirun(Ctlr *ctlr, int on);
|
||||
|
||||
#define dmaflush(clean, addr, len)
|
||||
|
|
|
@ -53,7 +53,7 @@ ehcireset(Ctlr *ctlr)
|
|||
}
|
||||
|
||||
/* requesting more interrupts per µframe may miss interrupts */
|
||||
opio->cmd |= Citc8; /* 1 intr. per ms */
|
||||
opio->cmd |= 0x10000; /* 1 intr. per ms */
|
||||
coherence();
|
||||
switch(opio->cmd & Cflsmask){
|
||||
case Cfls1024:
|
||||
|
@ -180,7 +180,7 @@ reset(Hci *hp)
|
|||
|
||||
ctlr->tdalloc = ucallocalign;
|
||||
ctlr->dmaalloc = ucalloc;
|
||||
cltr->dmafree = ucfree;
|
||||
ctlr->dmafree = ucfree;
|
||||
|
||||
ehcireset(ctlr);
|
||||
ehcimeminit(ctlr);
|
||||
|
|
|
@ -21,6 +21,7 @@ void cpuidprint(void);
|
|||
void (*cycles)(uvlong*);
|
||||
void delay(int);
|
||||
void* dmabva(int);
|
||||
#define dmaflush(clean, addr, len)
|
||||
int dmacount(int);
|
||||
int dmadone(int);
|
||||
void dmaend(int);
|
||||
|
|
|
@ -178,7 +178,6 @@ struct Ctlr
|
|||
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) */
|
||||
|
|
|
@ -21,6 +21,7 @@ void cpuidprint(void);
|
|||
void (*cycles)(uvlong*);
|
||||
void delay(int);
|
||||
void* dmabva(int);
|
||||
#define dmaflush(clean, addr, len)
|
||||
int dmacount(int);
|
||||
int dmadone(int);
|
||||
void dmaend(int);
|
||||
|
|
|
@ -1,144 +0,0 @@
|
|||
/*
|
||||
* ECHI portable hardware definitions
|
||||
*/
|
||||
|
||||
typedef struct Ecapio Ecapio;
|
||||
typedef struct Edbgio Edbgio;
|
||||
|
||||
#pragma incomplete Ecapio;
|
||||
#pragma incomplete Edbgio;
|
||||
|
||||
/*
|
||||
* EHCI interface registers and bits
|
||||
*/
|
||||
enum
|
||||
{
|
||||
/* Ecapio->parms reg. */
|
||||
Cnports = 0xF, /* nport bits */
|
||||
Cdbgportshift = 20, /* debug port */
|
||||
Cdbgportmask = 0xF,
|
||||
|
||||
/* Ecapio->capparms bits */
|
||||
C64 = 1<<0, /* 64-bits */
|
||||
Cpfl = 1<<1, /* program'ble frame list: can be <1024 */
|
||||
Casp = 1<<2, /* asynch. sched. park */
|
||||
Ceecpshift = 8, /* extended capabilities ptr. */
|
||||
Ceecpmask = (1<<8) - 1,
|
||||
|
||||
Clegacy = 1, /* legacy support cap. id */
|
||||
CLbiossem = 2, /* legacy cap. bios sem. */
|
||||
CLossem = 3, /* legacy cap. os sem */
|
||||
CLcontrol = 4, /* legacy support control & status */
|
||||
|
||||
/* typed links */
|
||||
Lterm = 1,
|
||||
Litd = 0<<1,
|
||||
Lqh = 1<<1,
|
||||
Lsitd = 2<<1,
|
||||
Lfstn = 3<<1, /* we don't use these */
|
||||
|
||||
/* Cmd reg. */
|
||||
Cstop = 0x00000, /* stop running */
|
||||
Crun = 0x00001, /* start operation */
|
||||
Chcreset = 0x00002, /* host controller reset */
|
||||
Cflsmask = 0x0000C, /* frame list size bits */
|
||||
Cfls1024 = 0x00000, /* frame list size 1024 */
|
||||
Cfls512 = 0x00004, /* frame list size 512 frames */
|
||||
Cfls256 = 0x00008, /* frame list size 256 frames */
|
||||
Cpse = 0x00010, /* periodic sched. enable */
|
||||
Case = 0x00020, /* async sched. enable */
|
||||
Ciasync = 0x00040, /* interrupt on async advance doorbell */
|
||||
/* interrupt threshold ctl. in µframes (1-32 in powers of 2) */
|
||||
Citcshift = 16,
|
||||
Citcmask = 0xff << Citcshift,
|
||||
|
||||
/* Sts reg. */
|
||||
Sasyncss = 0x08000, /* aync schedule status */
|
||||
Speriodss = 0x04000, /* periodic schedule status */
|
||||
Srecl = 0x02000, /* reclamnation (empty async sched.) */
|
||||
Shalted = 0x01000, /* h.c. is halted */
|
||||
Sasync = 0x00020, /* interrupt on async advance */
|
||||
Sherr = 0x00010, /* host system error */
|
||||
Sfrroll = 0x00008, /* frame list roll over */
|
||||
Sportchg = 0x00004, /* port change detect */
|
||||
Serrintr = 0x00002, /* error interrupt */
|
||||
Sintr = 0x00001, /* interrupt */
|
||||
Sintrs = 0x0003F, /* interrupts status */
|
||||
|
||||
/* Intr reg. */
|
||||
Iusb = 0x01, /* intr. on usb */
|
||||
Ierr = 0x02, /* intr. on usb error */
|
||||
Iportchg = 0x04, /* intr. on port change */
|
||||
Ifrroll = 0x08, /* intr. on frlist roll over */
|
||||
Ihcerr = 0x10, /* intr. on host error */
|
||||
Iasync = 0x20, /* intr. on async advance enable */
|
||||
Iall = 0x3F, /* all interrupts */
|
||||
|
||||
/* Config reg. */
|
||||
Callmine = 1, /* route all ports to us */
|
||||
|
||||
/* Portsc reg. */
|
||||
Pspresent = 0x00000001, /* device present */
|
||||
Psstatuschg = 0x00000002, /* Pspresent changed */
|
||||
Psenable = 0x00000004, /* device enabled */
|
||||
Pschange = 0x00000008, /* Psenable changed */
|
||||
Psresume = 0x00000040, /* resume detected */
|
||||
Pssuspend = 0x00000080, /* port suspended */
|
||||
Psreset = 0x00000100, /* port reset */
|
||||
Pspower = 0x00001000, /* port power on */
|
||||
Psowner = 0x00002000, /* port owned by companion */
|
||||
Pslinemask = 0x00000C00, /* line status bits */
|
||||
Pslow = 0x00000400, /* low speed device */
|
||||
|
||||
/* Debug port csw reg. */
|
||||
Cowner = 0x40000000, /* port owned by ehci */
|
||||
Cenable = 0x10000000, /* debug port enabled */
|
||||
Cdone = 0x00010000, /* request is done */
|
||||
Cbusy = 0x00000400, /* port in use by a driver */
|
||||
Cerrmask= 0x00000380, /* error code bits */
|
||||
Chwerr = 0x00000100, /* hardware error */
|
||||
Cterr = 0x00000080, /* transaction error */
|
||||
Cfailed = 0x00000040, /* transaction did fail */
|
||||
Cgo = 0x00000020, /* execute the transaction */
|
||||
Cwrite = 0x00000010, /* request is a write */
|
||||
Clen = 0x0000000F, /* data len */
|
||||
|
||||
/* Debug port pid reg. */
|
||||
Prpidshift = 16, /* received pid */
|
||||
Prpidmask = 0xFF,
|
||||
Pspidshift = 8, /* sent pid */
|
||||
Pspidmask = 0xFF,
|
||||
Ptokshift = 0, /* token pid */
|
||||
Ptokmask = 0xFF,
|
||||
|
||||
Ptoggle = 0x00008800, /* to update toggles */
|
||||
Ptogglemask = 0x0000FF00,
|
||||
|
||||
/* Debug port addr reg. */
|
||||
Adevshift = 8, /* device address */
|
||||
Adevmask = 0x7F,
|
||||
Aepshift = 0, /* endpoint number */
|
||||
Aepmask = 0xF,
|
||||
};
|
||||
|
||||
/*
|
||||
* Capability registers (hw)
|
||||
*/
|
||||
struct Ecapio
|
||||
{
|
||||
ulong cap; /* 00 controller capability register */
|
||||
ulong parms; /* 04 structural parameters register */
|
||||
ulong capparms; /* 08 capability parameters */
|
||||
ulong portroute; /* 0c not on the CS5536 */
|
||||
};
|
||||
|
||||
/*
|
||||
* Debug port registers (hw)
|
||||
*/
|
||||
struct Edbgio
|
||||
{
|
||||
ulong csw; /* control and status */
|
||||
ulong pid; /* USB pid */
|
||||
uchar data[8]; /* data buffer */
|
||||
ulong addr; /* device and endpoint addresses */
|
||||
};
|
|
@ -1256,8 +1256,7 @@ itdinit(Ctlr *ctlr, Isoio *iso, Itd *td)
|
|||
*/
|
||||
size = td->ndata = td->mdata;
|
||||
td->posi = td->posp = 0;
|
||||
if(ctlr->dmaflush != nil)
|
||||
(*ctlr->dmaflush)(1, td->data, size);
|
||||
dmaflush(1, td->data, size);
|
||||
pa = PADDR(td->data);
|
||||
pg = pa & ~0xFFF;
|
||||
for(p = 0; p < nelem(td->buffer); p++)
|
||||
|
@ -1290,8 +1289,7 @@ itdinit(Ctlr *ctlr, Isoio *iso, Itd *td)
|
|||
static void
|
||||
sitdinit(Ctlr *ctlr, Isoio *iso, Sitd *td)
|
||||
{
|
||||
if(ctlr->dmaflush != nil)
|
||||
(*ctlr->dmaflush)(1, td->data, td->mdata);
|
||||
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;
|
||||
|
@ -1905,8 +1903,7 @@ loop:
|
|||
dp = tdu->data + tdu->posi * iso->maxsize + tdu->posp;
|
||||
if(nr > 0){
|
||||
iunlock(ctlr);
|
||||
if(ctlr->dmaflush != nil)
|
||||
(*ctlr->dmaflush)(0, dp, nr);
|
||||
dmaflush(0, dp, nr);
|
||||
memmove(b+tot, dp, nr);
|
||||
ilock(ctlr);
|
||||
if(iso->tdu != tdu || dp != tdu->data + tdu->posi * iso->maxsize + tdu->posp)
|
||||
|
@ -1947,8 +1944,7 @@ isofscpy(Ctlr *ctlr, Isoio* iso, uchar *b, long count)
|
|||
nr = count - tot;
|
||||
if(nr > 0) {
|
||||
iunlock(ctlr); /* We could page fault here */
|
||||
if(ctlr->dmaflush != nil)
|
||||
(*ctlr->dmaflush)(0, stdu->data, stdu->mdata);
|
||||
dmaflush(0, stdu->data, stdu->mdata);
|
||||
memmove(b+tot, stdu->data, nr);
|
||||
ilock(ctlr);
|
||||
if(iso->stdu != stdu)
|
||||
|
@ -2192,8 +2188,9 @@ epgettd(Ctlr *ctlr, Qio *io, int flags, void *a, int count, int maxpkt)
|
|||
}
|
||||
if(a != nil && count > 0)
|
||||
memmove(td->data, a, count);
|
||||
if(ctlr->dmaflush != nil && td->buff != nil)
|
||||
(*ctlr->dmaflush)(1, td->data, count);
|
||||
if(td->buff != nil){
|
||||
dmaflush(1, td->data, count);
|
||||
}
|
||||
pa = PADDR(td->data);
|
||||
for(i = 0; i < nelem(td->buffer); i++){
|
||||
td->buffer[i] = pa;
|
||||
|
@ -2479,8 +2476,9 @@ epio(Ep *ep, Qio *io, void *a, long count, int mustlock)
|
|||
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);
|
||||
if(td->buff != nil){
|
||||
dmaflush(0, td->data, n);
|
||||
}
|
||||
memmove(c, td->data, n);
|
||||
c += n;
|
||||
}
|
||||
|
|
|
@ -14,9 +14,6 @@
|
|||
#include "../port/netif.h"
|
||||
#include "../port/etherif.h"
|
||||
#include "../port/flashif.h"
|
||||
#include "../port/usb.h"
|
||||
#include "../port/portusbehci.h"
|
||||
#include "usbehci.h"
|
||||
|
||||
enum {
|
||||
/* hardware limits imposed by register contents or layouts */
|
||||
|
|
|
@ -1,104 +0,0 @@
|
|||
/* override default macros from ../port/usb.h */
|
||||
#undef dprint
|
||||
#undef ddprint
|
||||
#undef deprint
|
||||
#undef ddeprint
|
||||
#define dprint if(ehcidebug)print
|
||||
#define ddprint if(ehcidebug>1)print
|
||||
#define deprint if(ehcidebug || ep->debug)print
|
||||
#define ddeprint if(ehcidebug>1 || ep->debug>1)print
|
||||
|
||||
typedef struct Ctlr Ctlr;
|
||||
typedef struct Eopio Eopio;
|
||||
typedef struct Isoio Isoio;
|
||||
typedef struct Poll Poll;
|
||||
typedef struct Qh Qh;
|
||||
typedef struct Qtree Qtree;
|
||||
|
||||
#pragma incomplete Ctlr;
|
||||
#pragma incomplete Eopio;
|
||||
#pragma incomplete Isoio;
|
||||
#pragma incomplete Poll;
|
||||
#pragma incomplete Qh;
|
||||
#pragma incomplete Qtree;
|
||||
|
||||
struct Poll
|
||||
{
|
||||
Lock;
|
||||
Rendez;
|
||||
int must;
|
||||
int does;
|
||||
};
|
||||
|
||||
struct Ctlr
|
||||
{
|
||||
Rendez; /* for waiting to async advance doorbell */
|
||||
Lock; /* for ilock. qh lists and basic ctlr I/O */
|
||||
QLock portlck; /* for port resets/enable... (and doorbell) */
|
||||
int active; /* in use or not */
|
||||
Ecapio* capio; /* Capability i/o regs */
|
||||
Eopio* opio; /* Operational i/o regs */
|
||||
|
||||
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 */
|
||||
Qtree* tree; /* tree of Qhs for the periodic list */
|
||||
int ntree; /* number of dummy qhs in tree */
|
||||
Qh* intrqhs; /* list of (not dummy) qhs in tree */
|
||||
Isoio* iso; /* list of active Iso I/O */
|
||||
ulong load;
|
||||
ulong isoload;
|
||||
int nintr; /* number of interrupts attended */
|
||||
int ntdintr; /* number of intrs. with something to do */
|
||||
int nqhintr; /* number of async td intrs. */
|
||||
int nisointr; /* number of periodic td intrs. */
|
||||
int nreqs;
|
||||
Poll poll;
|
||||
};
|
||||
|
||||
/*
|
||||
* Operational registers (hw)
|
||||
*/
|
||||
struct Eopio
|
||||
{
|
||||
ulong cmd; /* 00 command */
|
||||
ulong sts; /* 04 status */
|
||||
ulong intr; /* 08 interrupt enable */
|
||||
ulong frno; /* 0c frame index */
|
||||
ulong seg; /* 10 bits 63:32 of EHCI datastructs (unused) */
|
||||
ulong frbase; /* 14 frame list base addr, 4096-byte boundary */
|
||||
ulong link; /* 18 link for async list */
|
||||
uchar d2c[0x40-0x1c]; /* 1c dummy */
|
||||
ulong config; /* 40 1: all ports default-routed to this HC */
|
||||
ulong portsc[3]; /* 44 Port status and control, one per port */
|
||||
|
||||
/* defined for omap35 ehci at least */
|
||||
uchar _pad0[0x80 - 0x50];
|
||||
ulong insn[6]; /* implementation-specific */
|
||||
};
|
||||
|
||||
typedef struct Uhh Uhh;
|
||||
struct Uhh {
|
||||
ulong revision; /* ro */
|
||||
uchar _pad0[0x10-0x4];
|
||||
ulong sysconfig;
|
||||
ulong sysstatus; /* ro */
|
||||
|
||||
uchar _pad1[0x40-0x18];
|
||||
ulong hostconfig;
|
||||
ulong debug_csr;
|
||||
};
|
||||
|
||||
enum {
|
||||
/* hostconfig bits */
|
||||
P1ulpi_bypass = 1<<0, /* utmi if set; else ulpi */
|
||||
};
|
||||
|
||||
extern Ecapio *ehcidebugcapio;
|
||||
extern int ehcidebugport;
|
||||
|
||||
extern int ehcidebug;
|
||||
|
||||
void ehcilinkage(Hci *hp);
|
||||
void ehcimeminit(Ctlr *ctlr);
|
||||
void ehcirun(Ctlr *ctlr, int on);
|
|
@ -68,6 +68,7 @@ void clinvdse(void *, void *);
|
|||
void invaldln(void *);
|
||||
void cleandln(void *);
|
||||
void clinvdln(void *);
|
||||
void dmaflush(int, void*, ulong);
|
||||
void* ucalloc(ulong);
|
||||
void clean2pa(uintptr, uintptr);
|
||||
void inval2pa(uintptr, uintptr);
|
||||
|
|
|
@ -133,6 +133,25 @@ inval2pa(uintptr start, uintptr end)
|
|||
l2[0x770/4] = pa;
|
||||
}
|
||||
|
||||
void
|
||||
dmaflush(int clean, void *data, ulong len)
|
||||
{
|
||||
uintptr va, pa;
|
||||
|
||||
va = (uintptr)data & ~31;
|
||||
pa = PADDR(va);
|
||||
len = ROUND(len, 32);
|
||||
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 void
|
||||
options(void)
|
||||
{
|
||||
|
|
|
@ -130,7 +130,6 @@ struct Ctlr
|
|||
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) */
|
||||
|
|
|
@ -61,10 +61,6 @@ ehcireset(Ctlr *ctlr)
|
|||
iunlock(ctlr);
|
||||
}
|
||||
|
||||
enum {
|
||||
Cls = 64,
|
||||
};
|
||||
|
||||
/* descriptors need to be allocated in uncached memory */
|
||||
static void*
|
||||
tdalloc(ulong size, int, ulong)
|
||||
|
@ -75,7 +71,7 @@ tdalloc(ulong size, int, ulong)
|
|||
static void*
|
||||
dmaalloc(ulong len)
|
||||
{
|
||||
return mallocalign(ROUND(len, Cls), Cls, 0, 0);
|
||||
return mallocalign(ROUND(len, BLOCKALIGN), BLOCKALIGN, 0, 0);
|
||||
}
|
||||
static void
|
||||
dmafree(void *data)
|
||||
|
@ -83,25 +79,6 @@ 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 (*ehciportstatus)(Hci*,int);
|
||||
|
||||
static int
|
||||
|
@ -152,7 +129,6 @@ reset(Hci *hp)
|
|||
ctlr->tdalloc = tdalloc;
|
||||
ctlr->dmaalloc = dmaalloc;
|
||||
ctlr->dmafree = dmafree;
|
||||
ctlr->dmaflush = dmaflush;
|
||||
|
||||
ehcireset(ctlr);
|
||||
ctlr->r[USBMODE] |= USBHOST;
|
||||
|
|
Loading…
Reference in a new issue