M bitsy/power.c => bitsy/power.c +7 -9
@@ 77,9 77,9 @@ void (*restart)(void) = nil;
static void
sa1100_power_off(void)
{
- cacheflush();
- mmuinvalidate();
- mmudisable();
+
+iprint("calling resume\n");
+sa1100_power_resume();
/* enable wakeup by µcontroller, on/off switch or real-time clock alarm */
powerregs->pwer = 1 << IRQrtc | 1 << IRQgpio0 | 1 << IRQgpio1;
@@ 87,18 87,16 @@ sa1100_power_off(void)
/* clear previous reset status */
resetregs->rcsr = RCSR_all;
-sa1100_power_resume();
-
/* disable internal oscillator, float CS lines */
powerregs->pcfr = PCFR_opde | PCFR_fp | PCFR_fs;
powerregs->pgsr = 0;
/* set resume address. The loader jumps to it */
// powerregs->pspr = (ulong)sa1100_power_resume;
-// powerregs->pspr = (ulong)_start;
+ powerregs->pspr = (ulong)_start;
/* set lowest clock; delay to avoid resume hangs on fast sa1110 */
delay(90);
-// powerregs->ppcr = 0;
+ powerregs->ppcr = 0;
delay(90);
/* set all GPIOs to input mode */
@@ 179,9 177,9 @@ deepsleep(void) {
clockpower(0);
irpower(0);
audiopower(0);
- screenpower(0);
+// screenpower(0);
µcpower(0);
- rs232power(0);
+// rs232power(0);
sa1100_power_off();
/* no return */
}
M ip/esp.c => ip/esp.c +1 -1
@@ 301,7 301,7 @@ espkick(Conv *c)
}
void
-espiput(Proto *esp, uchar*, Block *bp)
+espiput(Proto *esp, Ipifc*, Block *bp)
{
Esphdr *eh;
Esptail *et;
M ip/ethermedium.c => ip/ethermedium.c +1 -1
@@ 283,7 283,7 @@ etherread(void *a)
if(ifc->lifc == nil)
freeb(bp);
else
- ipiput(er->f, ifc->lifc->local, bp);
+ ipiput(er->f, ifc, bp);
runlock(ifc);
poperror();
}
M ip/gre.c => ip/gre.c +1 -1
@@ 160,7 160,7 @@ grekick(Conv *c)
}
static void
-greiput(Proto *gre, uchar*, Block *bp)
+greiput(Proto *gre, Ipifc*, Block *bp)
{
int len;
GREhdr *ghp;
M ip/icmp.c => ip/icmp.c +3 -3
@@ 178,7 178,7 @@ icmpkick(Conv *c)
}
extern void
-icmpttlexceeded(Fs *f, uchar *ia, Block *bp)
+icmpttlexceeded(Fs *f, Ipifc *ifc, Block *bp)
{
Block *nbp;
Icmp *p, *np;
@@ 190,7 190,7 @@ icmpttlexceeded(Fs *f, uchar *ia, Block *bp)
nbp->wp += ICMP_IPSIZE + ICMP_HDRSIZE + ICMP_IPSIZE + 8;
np = (Icmp *)nbp->rp;
memmove(np->dst, p->src, sizeof(np->dst));
- v6tov4(np->src, ia);
+ v6tov4(np->src, ifc->lifc->local);
memmove(np->data, bp->rp, ICMP_IPSIZE + 8);
np->type = TimeExceed;
np->code = 0;
@@ 293,7 293,7 @@ static char *unreachcode[] =
};
static void
-icmpiput(Proto *icmp, uchar*, Block *bp)
+icmpiput(Proto *icmp, Ipifc*, Block *bp)
{
int n, iplen;
Icmp *p;
M ip/igmp.c => ip/igmp.c +1 -1
@@ 166,7 166,7 @@ igmpproc(void *a)
}
void
-igmpiput(Media *m, Block *bp)
+igmpiput(Media *m, Ipifc*, Block *bp)
{
int n;
IGMPpkt *ghp;
M ip/il.c => ip/il.c +2 -2
@@ 218,7 218,7 @@ void ilsettimeout(Ilcb*);
char* ilstart(Conv*, int, int);
void ilackproc(void*);
void iloutoforder(Conv*, Ilhdr*, Block*);
-void iliput(Proto*, uchar*, Block*);
+void iliput(Proto*, Ipifc*, Block*);
void iladvise(Proto*, Block*, char*);
int ilnextqt(Ilcb*);
void ilcbinit(Ilcb*);
@@ 528,7 528,7 @@ ilackto(Ilcb *ic, ulong ackto, Block *bp)
}
void
-iliput(Proto *il, uchar*, Block *bp)
+iliput(Proto *il, Ipifc*, Block *bp)
{
char *st;
Ilcb *ic;
M ip/ip.c => ip/ip.c +3 -3
@@ 344,7 344,7 @@ initfrag(IP *ip, int size)
#define DBG(x) if((logmask & Logipmsg) && (iponly == 0 || x == iponly))netlog
void
-ipiput(Fs *f, uchar *ia, Block *bp)
+ipiput(Fs *f, Ipifc *ifc, Block *bp)
{
int hl;
Iphdr *h;
@@ 428,7 428,7 @@ ipiput(Fs *f, uchar *ia, Block *bp)
/* don't forward if packet has timed out */
if(h->ttl <= 1){
ip->stats[InHdrErrors]++;
- icmpttlexceeded(f, ia, bp);
+ icmpttlexceeded(f, ifc, bp);
freeblist(bp);
return;
}
@@ 455,7 455,7 @@ ipiput(Fs *f, uchar *ia, Block *bp)
p = Fsrcvpcol(f, h->proto);
if(p != nil && p->rcv != nil) {
ip->stats[InDelivers]++;
- (*p->rcv)(p, ia, bp);
+ (*p->rcv)(p, ifc, bp);
return;
}
ip->stats[InDiscards]++;
M ip/ip.h => ip/ip.h +3 -3
@@ 245,7 245,7 @@ struct Proto
int (*state)(Conv*, char*, int);
void (*create)(Conv*);
void (*close)(Conv*);
- void (*rcv)(Proto*, uchar*, Block*);
+ void (*rcv)(Proto*, Ipifc*, Block*);
char* (*ctl)(Conv*, char**, int);
void (*advise)(Proto*, Block*, char*);
int (*stats)(Proto*, char*, int);
@@ 531,10 531,10 @@ extern long ipselftabread(Fs*, char *a, ulong offset, int n);
extern void iprouting(Fs*, int);
extern void closeifcconv(Ifcconv*);
extern void icmpnoconv(Fs*, Block*);
-extern void icmpttlexceeded(Fs*, uchar*, Block*);
+extern void icmpttlexceeded(Fs*, Ipifc*, Block*);
extern void initfrag(IP*, int);
extern ushort ipcsum(uchar*);
-extern void ipiput(Fs*, uchar*, Block*);
+extern void ipiput(Fs*, Ipifc*, Block*);
extern void ipoput(Fs*, Block*, int, int, int);
extern int ipstats(Fs*, char*, int);
extern ushort ptclbsum(uchar*, int);
M ip/ipmux.c => ip/ipmux.c +5 -2
@@ 641,7 641,7 @@ ipmuxkick(Conv *c)
}
static void
-ipmuxiput(Proto *p, uchar *ia, Block *bp)
+ipmuxiput(Proto *p, Ipifc *ifc, Block *bp)
{
int len;
Fs *f = p->f;
@@ 649,6 649,9 @@ ipmuxiput(Proto *p, uchar *ia, Block *bp)
Conv *c;
Ipmux *mux;
Iphdr *ip;
+ uchar *ia;
+
+ ia = ifc->lifc->local;
if(p->priv == nil)
goto nomatch;
@@ 737,7 740,7 @@ nomatch:
ip = (Iphdr*)bp->rp;
p = f->t2p[ip->proto];
if(p)
- (*p->rcv)(p, ia, bp);
+ (*p->rcv)(p, ifc, bp);
else
freeblist(bp);
return;
M ip/loopbackmedium.c => ip/loopbackmedium.c +1 -1
@@ 94,7 94,7 @@ loopbackread(void *a)
if(ifc->lifc == nil)
freeb(bp);
else
- ipiput(lb->f, ifc->lifc->local, bp);
+ ipiput(lb->f, ifc, bp);
runlock(ifc);
poperror();
}
M ip/netdevmedium.c => ip/netdevmedium.c +1 -1
@@ 140,7 140,7 @@ ZZZ is this a good idea?
if(ifc->lifc == nil)
freeb(bp);
else
- ipiput(er->f, ifc->lifc->local, bp);
+ ipiput(er->f, ifc, bp);
runlock(ifc);
poperror();
}
M ip/pktmedium.c => ip/pktmedium.c +1 -1
@@ 64,7 64,7 @@ pktin(Fs *f, Ipifc *ifc, Block *bp)
if(ifc->lifc == nil)
freeb(bp);
else
- ipiput(f, ifc->lifc->local, bp);
+ ipiput(f, ifc, bp);
}
void
M ip/rudp.c => ip/rudp.c +4 -4
@@ 475,7 475,7 @@ rudpkick(Conv *c)
}
void
-rudpiput(Proto *rudp, uchar *ia, Block *bp)
+rudpiput(Proto *rudp, Ipifc *ifc, Block *bp)
{
int len, olen, ottl;
Udphdr *uh;
@@ 569,7 569,7 @@ rudpiput(Proto *rudp, uchar *ia, Block *bp)
if(ipforme(f, laddr) == Runi)
ipmove(bp->rp+IPaddrlen, laddr);
else
- ipmove(bp->rp+IPaddrlen, ia);
+ ipmove(bp->rp+IPaddrlen, ifc->lifc->local);
hnputs(bp->rp+2*IPaddrlen, rport);
hnputs(bp->rp+2*IPaddrlen+2, lport);
break;
@@ 580,7 580,7 @@ rudpiput(Proto *rudp, uchar *ia, Block *bp)
if(ipforme(f, laddr) == Runi)
v6tov4(bp->rp+IPv4addrlen, laddr);
else
- v6tov4(bp->rp+IPv4addrlen, ia);
+ v6tov4(bp->rp+IPv4addrlen, ifc->lifc->local);
hnputs(bp->rp + 2*IPv4addrlen, rport);
hnputs(bp->rp + 2*IPv4addrlen + 2, lport);
break;
@@ 595,7 595,7 @@ rudpiput(Proto *rudp, uchar *ia, Block *bp)
if(ipforme(f, laddr) == Runi)
ipmove(c->laddr, laddr);
else
- v4tov6(c->laddr, ia);
+ v4tov6(c->laddr, ifc->lifc->local);
}
break;
}
M ip/tcp.c => ip/tcp.c +2 -2
@@ 259,7 259,7 @@ int addreseq(Tcpctl*, Tcp*, Block*, ushort);
void getreseq(Tcpctl*, Tcp*, Block**, ushort*);
void localclose(Conv*, char*);
void procsyn(Conv*, Tcp*);
-void tcpiput(Proto*, uchar*, Block*);
+void tcpiput(Proto*, Ipifc*, Block*);
void tcpoutput(Conv*);
int tcptrim(Tcpctl*, Tcp*, Block**, ushort*);
void tcpstart(Conv*, int, ushort);
@@ 1234,7 1234,7 @@ done:
}
void
-tcpiput(Proto *tcp, uchar*, Block *bp)
+tcpiput(Proto *tcp, Ipifc*, Block *bp)
{
Tcp seg;
Tcphdr *h;
M ip/tripmedium.c => ip/tripmedium.c +1 -1
@@ 142,7 142,7 @@ tripread(void *a)
for(;;) {
bp = devtab[er->mchan->type]->bread(er->mchan, ifc->maxmtu, 0);
ifc->in++;
- ipiput(er->fs, ifc->lifc->local, bp);
+ ipiput(er->fs, ifc, bp);
}
pexit("hangup", 1);
M ip/udp.c => ip/udp.c +4 -4
@@ 251,7 251,7 @@ udpincoming(Conv *c, uchar *raddr, ushort rport, uchar *laddr, ushort lport)
}
void
-udpiput(Proto *udp, uchar *ia, Block *bp)
+udpiput(Proto *udp, Ipifc *ifc, Block *bp)
{
int len, olen, ottl;
Udphdr *uh;
@@ 312,7 312,7 @@ udpiput(Proto *udp, uchar *ia, Block *bp)
if(ucb->headers == 0){
/* create a new conversation */
if(ipforme(f, laddr) != Runi)
- v4tov6(laddr, ia);
+ v4tov6(laddr, ifc->lifc->local);
c = Fsnewcall(c, raddr, rport, laddr, lport);
if(c == nil){
qunlock(udp);
@@ 351,7 351,7 @@ udpiput(Proto *udp, uchar *ia, Block *bp)
if(ipforme(f, laddr) == Runi)
ipmove(bp->rp+IPaddrlen, laddr);
else
- ipmove(bp->rp+IPaddrlen, ia);
+ ipmove(bp->rp+IPaddrlen, ifc->lifc->local);
hnputs(bp->rp+2*IPaddrlen, rport);
hnputs(bp->rp+2*IPaddrlen+2, lport);
break;
@@ 362,7 362,7 @@ udpiput(Proto *udp, uchar *ia, Block *bp)
if(ipforme(f, laddr) == Runi)
v6tov4(bp->rp+IPv4addrlen, laddr);
else
- v6tov4(bp->rp+IPv4addrlen, ia);
+ v6tov4(bp->rp+IPv4addrlen, ifc->lifc->local);
hnputs(bp->rp + 2*IPv4addrlen, rport);
hnputs(bp->rp + 2*IPv4addrlen + 2, lport);
break;
M pc/etherelnk3.c => pc/etherelnk3.c +32 -5
@@ 441,6 441,9 @@ typedef struct {
ulong dninterrupts;
ulong dnqueued;
+ int did; /* Controller's device ID */
+ ulong cbfns; /* CardBus functions */
+
int xcvr; /* transceiver type */
int rxstatus9; /* old-style RxStatus register */
int rxearly; /* RxEarlyThreshold */
@@ 615,9 618,9 @@ attach(Ether* ether)
COMMAND(port, RxEnable, 0);
COMMAND(port, TxEnable, 0);
- if (ether->mem)
+ if (ctlr->cbfns)
/* This must be a cardbus card. Acknowledge the interrupt */
- intrack3c575(KADDR(ether->mem));
+ intrack3c575(KADDR(ctlr->cbfns));
/*
* Prime the busmaster channel for receiving directly into a
@@ 960,6 963,18 @@ receive(Ether* ether)
}
}
+static int
+ejectable(int did)
+{
+ switch (did) {
+ case 0x5157:
+ return 1;
+
+ default:
+ return 0;
+ }
+}
+
static void
interrupt(Ureg*, void* arg)
{
@@ 996,6 1011,13 @@ interrupt(Ureg*, void* arg)
COMMAND(port, SelectRegisterWindow, Wdiagnostic);
x = ins(port+FifoDiagnostic);
COMMAND(port, SelectRegisterWindow, Wop);
+
+ if (status == 0xFFFF && x == 0xFFFF && ejectable(ctlr->did)) {
+ print("#l%d: Card ejected?\n", ether->ctlrno);
+ iunlock(&ctlr->wlock);
+ return;
+ }
+
print("#l%d: status 0x%uX, diag 0x%uX\n",
ether->ctlrno, status, x);
@@ 1138,7 1160,7 @@ interrupt(Ureg*, void* arg)
panic("#l%d: interrupt mask 0x%uX\n", ether->ctlrno, status);
COMMAND(port, AcknowledgeInterrupt, interruptLatch);
- if (ether->mem) intrack3c575((ulong *)KADDR(ether->mem));
+ if (ctlr->cbfns) intrack3c575((ulong *)KADDR(ctlr->cbfns));
}while((status = STATUS(port)) & (interruptMask|interruptLatch));
@@ 1482,7 1504,7 @@ tcm59Xpci(void)
if (p->did == 0x5157) {
/* Map the CardBus functions */
bar = pcicfgr32(p, PciBAR2);
- print("tcmp59Xpci: CardBus functions at %.8uX\n", bar & ~KZERO);
+ print("tcmp59Xpci: CardBus functions at %.8ulX\n", bar & ~KZERO);
}
tcmadapter(port, irq, p->tbdf, p->did, bar);
@@ 1759,6 1781,7 @@ etherelnk3reset(Ether* ether)
Ctlr *ctlr;
static int scandone;
char *p;
+ ulong cbfns;
/*
* Scan for adapter on PCI, EISA and finally
@@ 1777,6 1800,7 @@ etherelnk3reset(Ether* ether)
*/
port = 0;
did = 0;
+ cbfns = 0;
bpp = &adapter;
for(bp = *bpp; bp; bp = bp->next){
ap = (Adapter*)bp->rp;
@@ 1785,7 1809,7 @@ etherelnk3reset(Ether* ether)
did = ap->did;
ether->irq = ap->irq;
ether->tbdf = ap->tbdf;
- ether->mem = ap->cbfns;
+ cbfns = ap->cbfns;
*bpp = bp->next;
freeb(bp);
break;
@@ 2034,6 2058,9 @@ etherelnk3reset(Ether* ether)
if(rxearly >= 2048)
ctlr->ts = 2;
+ ctlr->did = did;
+ ctlr->cbfns = cbfns;
+
COMMAND(port, StatisticsEnable, 0);
/*
M pc/etherwavelan.c => pc/etherwavelan.c +3 -1
@@ 1187,7 1187,7 @@ reset(Ether* ether)
if (ioalloc(ether->port,WIOLen,0,"wavelan")<0){
print("#l%d: port 0x%lx in use\n",
ether->ctlrno, ether->port);
- goto abort;
+ goto abort1;
}
if ((ctlr->slot = pcmspecial("WaveLAN/IEEE", ether))<0){
@@ 1267,6 1267,8 @@ reset(Ether* ether)
return 0;
abort:
+ iofree(ether->port);
+abort1:
iunlock(&ctlr->Lock);
free(ctlr);
ether->ctlr = nil;