M mpc/devrtc.c => mpc/devrtc.c +110 -18
@@ 10,6 10,7 @@
enum{
Qrtc = 1,
Qnvram,
+ Qeeprom,
Qnvram2,
Qled,
@@ 21,23 22,31 @@ enum{
RTE= 1<<0,
R38K= 1<<4,
- Nvoff= 4*1024, /* where usable nvram lives */
- Nvsize= 4*1024,
+ Nvoff= 0, /* where usable EEPROM lives */
+ Nvsize= 256,/*128x16=256x8*/
Nvoff2= 8*1024, /* where second usable nvram lives */
Nvsize2= 4*1024,
};
static QLock rtclock; /* mutex on clock operations */
static Lock nvrtlock;
+static Lock eepromlock;
static Dirtab rtcdir[]={
"rtc", {Qrtc, 0}, 12, 0666,
- "nvram", {Qnvram, 0}, Nvsize, 0664,
+ "eeprom", {Qeeprom, 0}, Nvsize, 0664,
"nvram2", {Qnvram2, 0}, Nvsize, 0664,
"led", {Qled, 0}, 0, 0664,
};
#define NRTC (sizeof(rtcdir)/sizeof(rtcdir[0]))
+extern void spiread(ulong addr, uchar *buf);
+extern void spiwrite(ulong addr, uchar *buf);
+extern void spiresult(void);
+extern void spienwrite(void);
+extern void spidiswrite(void);
+extern void spiwriteall(uchar *buf);
+
static void
rtcreset(void)
{
@@ 82,7 91,8 @@ rtcopen(Chan *c, int omode)
if(strcmp(up->user, eve)!=0 && omode!=OREAD)
error(Eperm);
break;
- case Qnvram:
+ case Qeeprom:
+ //case Qnvram:
case Qnvram2:
if(strcmp(up->user, eve)!=0)
error(Eperm);
@@ 99,8 109,10 @@ rtcclose(Chan*)
static long
rtcread(Chan *c, void *buf, long n, vlong offset)
{
- ulong t;
-
+ ulong t,readaddr;
+ uchar spibuf[2];
+ int index;
+
if(c->qid.path & CHDIR)
return devdirread(c, buf, n, rtcdir, NRTC, devgen);
@@ 109,18 121,47 @@ rtcread(Chan *c, void *buf, long n, vlong offset)
t = m->iomem->rtc;
n = readnum(offset, buf, n, t, 12);
return n;
- case Qnvram:
- return 0;
+ case Qeeprom:
+ //case Qnvram:
if(offset >= Nvsize)
return 0;
t = offset;
if(t + n > Nvsize)
n = Nvsize - t;
- ilock(&nvrtlock);
- memmove(buf, (uchar*)(NVRAMMEM + Nvoff + t), n);
- iunlock(&nvrtlock);
+ ilock(&eepromlock);
+
+ /* read from eeprom through spi, two bytes a time*/
+
+ index=0;
+ if(t%2!=0){
+ print("not starting from an even address\n");
+ readaddr=(t-1)/2;
+ spiread(readaddr,spibuf);
+ memmove((uchar*)buf+index,(uchar *)spibuf+1,1);
+ index++;
+ readaddr++;
+ }
+ else
+ readaddr=t/2;
+
+ while(index<n){
+ spiread(readaddr,spibuf);
+ memmove((uchar*)buf+index,spibuf,1);
+ if(index+1<n)
+ memmove((uchar*)buf+index+1,(uchar*)spibuf+1,1);
+ readaddr++;
+ index+=2;
+ }
+
+/* print("result of reading is \n");
+ for(index=0;index<n;index++)
+ print(" %ux ",((uchar*)buf)[index]);
+ print("\n");
+*/
+ iunlock(&eepromlock);
return n;
case Qnvram2:
+ print("ram 2\n");
return 0;
if(offset >= Nvsize2)
return 0;
@@ 132,7 173,13 @@ rtcread(Chan *c, void *buf, long n, vlong offset)
iunlock(&nvrtlock);
return n;
case Qled:
- return 0;
+ if(offset >= 5)
+ return 0;
+ t = offset;
+ if(t + n > 5)
+ n = 5 - t;
+ memmove(buf, "kitty" + t, n);
+ return n;
}
error(Egreg);
return 0; /* not reached */
@@ 144,7 191,9 @@ rtcwrite(Chan *c, void *buf, long n, vlong offset)
ulong secs;
char *cp, *ep;
IMM *io;
- ulong t;
+ ulong t,readaddr,writeaddr;
+ int index;
+ uchar spibuf[2];
switch(c->qid.path){
case Qrtc:
@@ 170,18 219,61 @@ rtcwrite(Chan *c, void *buf, long n, vlong offset)
io->rtck = ~KEEP_ALIVE_KEY;
iopunlock();
return n;
- case Qnvram:
- return 0;
+ case Qeeprom:
+ //case Qnvram:
+ print("write %d to eeprom\n",n);
if(offset >= Nvsize)
return 0;
t = offset;
if(t + n > Nvsize)
n = Nvsize - t;
- ilock(&nvrtlock);
- memmove((uchar*)(NVRAMMEM + Nvoff + offset), buf, n);
- iunlock(&nvrtlock);
+
+ ilock(&eepromlock);
+ index=0;
+ spienwrite();
+ /*if the writing addr starts at an odd address, we need to read in
+ the higher byte first, combined it with the lower byte,
+ and then write them out
+ */
+ if(t%2!=0){
+ print("not starting from an even address\n");
+ readaddr=(t-1)/2;
+ spiread(readaddr,spibuf);
+ memmove((uchar*)spibuf+1,(uchar*)buf+index,1);
+ //spienwrite();
+ spiwrite(readaddr,spibuf);
+ //spidiswrite();
+ index++;
+ writeaddr=readaddr+1;
+ }
+ else
+ writeaddr=t/2;
+
+ while(index<n){
+ if(index+1==n){
+ //spienwrite();
+ spiread(writeaddr,spibuf);
+ //spidiswrite();
+ }
+ else
+ memmove((uchar*)spibuf+1,(uchar*)buf+index+1,1);
+
+ memmove((uchar*)spibuf,(uchar*)buf+index,1);
+ // spienwrite();
+ spiwrite(writeaddr,spibuf);
+ // spidiswrite();
+ writeaddr++;
+ index+=2;
+ }
+
+ spidiswrite();
+ //memmove((uchar*)(NVRAMMEM + Nvoff + offset), buf, n);
+ iunlock(&eepromlock);
return n;
+
case Qnvram2:
+ memmove((uchar*)spibuf,(uchar*)buf,2);
+ spiwriteall(spibuf);
return 0;
if(offset >= Nvsize2)
return 0;
M mpc/main.c => mpc/main.c +1 -0
@@ 39,6 39,7 @@ main(void)
cpminit();
uartinstall();
print("hello world from kernel %ux %ux %ux\n", m->iomem->pddat, m->iomem->pddir, m->iomem->pdpar);
+ spiinit();
mmuinit();
pageinit();
procinit0();
M mpc/spi.c => mpc/spi.c +250 -224
@@ 154,7 154,7 @@ spireset(void)
/* step 13: enable in master mode, 8 bit chacters, slow clock */
spi->spmode = MMaster|MRev|MDiv16|MEnable|(0x7<<4)|0xf;
-print("spi->spmode = %ux\n", spi->spmode);
+
}
static void
@@ 168,7 168,7 @@ interrupt(Ureg*, void *arg)
spi = ctlr->spi;
events = spi->spie;
spi->spie = events;
- print("SPI#%x\n", events);
+// print("SPI#%x\n", events);
}
void
@@ 199,6 199,7 @@ spitest(void)
int len;
Ctlr *ctlr;
ulong status;
+ uchar buf[2];
ctlr = spictlr;
@@ 223,7 224,6 @@ print("len = %d\n", len);
print("addr = %lux\n", PADDR(b->rp));
dre->length = len;
dre->status = (dre->status & BDWrap) | BDReady|BDInt|BDLast;
- eieio();
spdump(ctlr->sp);
m->iomem->pbdat |= IBIT(31);
microdelay(1);
@@ 248,6 248,14 @@ print("%d status = %lux len=%d\n", ctlr->rdrx, status, len);
memmove(b->wp, KADDR(dre->addr), len);
b->wp += len;
print("%ux %ux %ux %ux\n", b->rp[0], b->rp[1], b->rp[2], b->rp[3]);
+
+/* get the data out of the receiving block
+ the data begins at the 13th bit, and ends at the (13+16)th bit
+*/
+ buf[0]=b->rp[1]<<4 | b->rp[2]>>4;
+ buf[1]=b->rp[2]<<4 | b->rp[3]>>4;
+
+print("the value of address 0 in EEPROM is %ux %ux\n",buf[0],buf[1]);
dcflush(KADDR(dre->addr), len);
dre->status = (status & BDWrap) | BDEmpty | BDInt;
ctlr->rdrx = NEXT(ctlr->rdrx, Nrdre);
@@ 260,262 268,280 @@ void
spiinit(void)
{
spireset();
- spitest();
+// spitest();
}
-#ifdef XXX
+void
+spicmdsend(Block *b, BD *dre, Ctlr *ctlr, int CSdown)
+{
+ int len;
+
+ if(dre->status & BDReady)
+ panic("spicmdsend: txstart");
+
+ len = BLEN(b);
+ dcflush(b->rp, len);
+
+ ctlr->txb[ctlr->tdrh] = b;
+ dre->addr = PADDR(b->rp);
+ dre->length = len;
+ dre->status = (dre->status & BDWrap) | BDReady|BDInt|BDLast;
+ m->iomem->pbdat |= IBIT(31);
+
+ ctlr->spi->spcom = 1<<7; /* transmit now */
+
+ //eieio();
+ ctlr->ntq++;
+ ctlr->tdrh = NEXT(ctlr->tdrh, Ntdre);
+
+ delay(1);
+
+ while(dre->status&BDReady) microdelay(10);
+
+ if(CSdown) m->iomem->pbdat &= ~(IBIT(31));
-static void
-epprod(Ctlr *ctlr, int epn)
-{
- ctlr->spi->uscom = FifoFill | (epn&3);
- eieio();
}
-static void
-txstart(Endpt *r)
+
+void
+spiread(ulong addr,uchar * buf)
{
- int len, flags;
+
+ BD *dre;
Block *b;
- BD *dre, *rdy;
+ int len;
+ Ctlr *ctlr;
+ ushort status;
+
+ ctlr = spictlr;
- if(r->ctlr->init)
- return;
- rdy = nil;
- while(r->ntq < Ntdre-1){
- b = qget(r->oq);
- if(b == 0)
- break;
-
- dre = &r->tdr[r->tdrh];
- if(dre->status & BDReady)
- panic("txstart");
-dumpspi(b, "TX");
+ dre = &ctlr->tdr[ctlr->tdrh];
+
+ b = allocb(4);
+ b->wp[0] = 0xc0 | addr>>3;
+ b->wp[1] = addr<<5;
+ b->wp[2] = 0x00;
+ b->wp[3] = 0x00;
+ b->wp += 4;
+
+ spicmdsend(b, dre, ctlr, 0);
+
+ //delay(10);
- /*
- * Give ownership of the descriptor to the chip, increment the
- * software ring descriptor pointer and tell the chip to poll.
- */
- flags = 0;
- switch(b->rp[0]){
- case TokDATA1:
- flags = BDData1|BDData0;
- case TokDATA0:
- flags |= BDtxcrc|BDcnf|BDReady;
- flags |= BDData0;
- b->rp++; /* skip DATAn */
- }
- len = BLEN(b);
- dcflush(b->rp, len);
- if(r->txb[r->tdrh] != nil)
- panic("spi: txstart");
- r->txb[r->tdrh] = b;
- dre->addr = PADDR(b->rp);
- dre->length = len;
- eieio();
- dre->status = (dre->status & BDWrap) | BDInt|BDLast | flags;
- if(rdy){
- rdy->status |= BDReady;
- rdy = nil;
- }
- if((flags & BDReady) == 0)
- rdy = dre;
- eieio();
- r->ntq++;
- r->tdrh = NEXT(r->tdrh, Ntdre);
- }
- if(rdy)
- rdy->status |= BDReady;
- eieio();
+ dre = &ctlr->rdr[ctlr->rdrx];
+ status = dre->status;
+ len = dre->length;
+
+ while(dre->status&BDEmpty) microdelay(10);
+
+ b = iallocb(len);
+ memmove(b->wp, KADDR(dre->addr), len);
+ b->wp += len;
+
+
+/* get the data out of the receiving block
+ the data begins at the 13th bit, and ends at the (13+16)th bit
+*/
+ buf[0]=b->rp[1]<<4 | b->rp[2]>>4;
+ buf[1]=b->rp[2]<<4 | b->rp[3]>>4;
+
+// print("read out %ux %ux\n", buf[0],buf[1]);
+ dcflush(KADDR(dre->addr), len);
+ dre->status = (status & BDWrap) | BDEmpty | BDInt;
+ ctlr->rdrx = NEXT(ctlr->rdrx, Nrdre);
+ freeb(b);
+ m->iomem->pbdat &= ~(IBIT(31));
+ microdelay(5);
+
+ return;
}
-static void
-transmit(Endpt *r)
+void
+spienwrite(void)
{
- ilock(r->ctlr);
- txstart(r);
- iunlock(r->ctlr);
+ BD *dre;
+ Block *b;
+ Ctlr *ctlr;
+ int len;
+
+ ctlr = spictlr;
+
+ b = allocb(4);
+ b->wp[0] = 0x98;
+ b->wp[1] = 0x00;
+ b->wp[2] = 0x00;
+ b->wp[3] = 0x00;
+ b->wp += 4;
+
+ dre = &ctlr->tdr[ctlr->tdrh];
+ spicmdsend(b,dre,ctlr,1);
+
+ dre=&ctlr->rdr[ctlr->rdrx];
+ len=dre->length;
+ dcflush(KADDR(dre->addr),len);
+ dre->status=(dre->status&BDWrap)|BDEmpty|BDInt;
+ ctlr->rdrx=NEXT(ctlr->rdrx,Nrdre);
+
+ freeb(b);
+ microdelay(5);
+ return;
}
-static void
-endptintr(Endpt *r, int events)
+void
+spidiswrite(void)
{
- int len, status;
- BD *dre;
+ BD *dre;
Block *b;
+ Ctlr *ctlr;
+ int len;
- if(events & Frxb || 1){
- dre = &r->rdr[r->rdrx];
- while(((status = dre->status) & BDEmpty) == 0){
- if(status & BDrxerr || (status & (BDFirst|BDLast)) != (BDFirst|BDLast)){
- print("spi rx: %4.4ux %d ", status, dre->length);
- {uchar *p;int i; p=KADDR(dre->addr); for(i=0;i<14&&i<dre->length; i++)print(" %.2ux", p[i]);print("\n");}
- }
- else{
- /*
- * We have a packet. Read it into the next
- * free ring buffer, if any.
- */
- len = dre->length-2; /* discard CRC */
- if(len >= 0 && (b = iallocb(len)) != 0){
- memmove(b->wp, KADDR(dre->addr), len);
- dcflush(KADDR(dre->addr), len);
- b->wp += len;
- // spiiq(ctlr, b);
- dumpspi(b, "RX");
- freeb(b);
- }
- }
-
- /*
- * Finished with this descriptor, reinitialise it,
- * give it back to the chip, then on to the next...
- */
- dre->length = 0;
- dre->status = (dre->status & BDWrap) | BDEmpty | BDInt;
- eieio();
-
- r->rdrx = NEXT(r->rdrx, Nrdre);
- dre = &r->rdr[r->rdrx];
- r->rxintr = 1;
- wakeup(&r->ir);
- }
- }
+ ctlr = spictlr;
- /*
- * Transmitter interrupt: handle anything queued for a free descriptor.
- */
- if(events & (Ftxb|Ftxe0|Ftxe1)){
- lock(r->ctlr);
- while(r->ntq){
- dre = &r->tdr[r->tdri];
- if(dre->status & BDReady)
- break;
- print("spitx=#%.4x %8.8lux\n", dre->status, dre->addr);
- /* TO DO: error counting */
- b = r->txb[r->tdri];
- if(b == nil)
- panic("spi/interrupt: bufp");
- r->txb[r->tdri] = nil;
- freeb(b);
- r->ntq--;
- r->tdri = NEXT(r->tdri, Ntdre);
- }
- txstart(r);
- unlock(r->ctlr);
- if(r->ntq)
- epprod(r->ctlr, r->x);
- }
-}
+ dre = &ctlr->tdr[ctlr->tdrh];
+ b = allocb(4);
+ b->wp[0] = 0x80;
+ b->wp[1] = 0x00;
+ b->wp[2] = 0x00;
+ b->wp[3] = 0x00;
+ b->wp += 4;
-static void
-dumpspi(Block *b, char *msg)
-{
- int i;
+ spicmdsend(b,dre,ctlr,1);
+
+ dre=&ctlr->rdr[ctlr->rdrx];
+ len=dre->length;
+ dcflush(KADDR(dre->addr),len);
+ dre->status=(dre->status&BDWrap)|BDEmpty|BDInt;
+ ctlr->rdrx=NEXT(ctlr->rdrx,Nrdre);
- print("%s: %8.8lux [%d]: ", msg, (ulong)b->rp, BLEN(b));
- for(i=0; i<BLEN(b) && i < 16; i++)
- print(" %.2x", b->rp[i]);
- print("\n");
+ freeb(b);
+ microdelay(5);
+ return;
}
-static void
-setaddr(Endpt *e, int dev, int endpt)
+void
+spiwrite(ulong addr, uchar *buf)
{
- ushort v;
-
- e->dev = dev;
- e->endpt = endpt;
- v = (e->endpt<<7) | e->dev;
- v |= crc5(v) << 11;
- e->addr[0] = v;
- e->addr[1] = v>>8;
+ BD *dre;
+ Block *b;
+ Ctlr *ctlr;
+ int len;
+
+ ctlr = spictlr;
+
+ dre = &ctlr->tdr[ctlr->tdrh];
+
+ b = allocb(4);
+ b->wp[0] = 0x05 ;
+ b->wp[1] = 0x7f & addr;
+ b->wp+=2;
+ memmove((uchar*)b->wp,buf,2);
+ b->wp += 2;
+
+ spicmdsend(b,dre,ctlr,1);
+
+ dre=&ctlr->rdr[ctlr->rdrx];
+ len=dre->length;
+ dcflush(KADDR(dre->addr),len);
+ dre->status=(dre->status&BDWrap)|BDEmpty|BDInt;
+ ctlr->rdrx=NEXT(ctlr->rdrx,Nrdre);
+
+ freeb(b);
+ delay(15);
+ //sleep(15); //sleep for 15ms
+ return;
}
-static int
-spiinput(void *a)
+void
+spiwriteall(uchar *buf)
{
- return ((Ctlr*)a)->rxintr;
+ BD *dre;
+ Block *b;
+ Ctlr *ctlr;
+ int len;
+
+ ctlr = spictlr;
+
+ dre = &ctlr->tdr[ctlr->tdrh];
+
+ b = allocb(4);
+ b->wp[0] = 0x04;
+ b->wp[1] = 0x40;
+ b->wp+=2;
+ memmove((uchar*)b->wp,buf,2);
+ //b->wp[2]=0xf0;
+ //b->wp[3]=0xf0;
+ b->wp += 2;
+
+ spicmdsend(b,dre,ctlr,1);
+
+ dre=&ctlr->rdr[ctlr->rdrx];
+ len=dre->length;
+ dcflush(KADDR(dre->addr),len);
+ dre->status=(dre->status&BDWrap)|BDEmpty|BDInt;
+ ctlr->rdrx=NEXT(ctlr->rdrx,Nrdre);
+
+ freeb(b);
+ delay(15);
+ //sleep(15000); //sleep for 15ms
+ print("leave spiwriteall\n");
+ return;
}
-static void
-spitest(void)
+void
+spierase(ulong addr)
{
+ BD *dre;
+ Block *b;
Ctlr *ctlr;
- Endpt *e, *e1;
- uchar msg[8];
- int epn, testing, i;
+ int len;
ctlr = spictlr;
- epn = 0;
- testing = ctlr->spi->usmod & TEST;
- if(testing)
- epn = 1;
- e = &ctlr->pts[0];
- e1 = &ctlr->pts[1];
- memset(msg, 0, 8);
- msg[0] = 0;
- msg[1] = 8; /* set configuration */
- msg[2] = 1;
- setaddr(e, 0, epn);
- sendtoken(e, TokSETUP);
- senddata(e, msg, 8);
- if(!testing){
- for(i=0; i<8; i++)
- msg[i] = 0x40+i;
- senddata(e1, msg, 8);
- e->rxintr = 0;
- sendtoken(e, TokIN);
- transmit(e);
- epprod(ctlr, 0);
- tsleep(&e->ir, spiinput, e, 1000);
- if(!spiinput(e))
- print("RX: none\n");
- }
- sendtoken(e, TokSETUP);
- msg[0] = 0x23;
- msg[1] = 3; /* set feature */
- msg[2] = 8; /* port power */
- msg[3] = 0;
- msg[4] = 1; /* port 1 */
- senddata(e, msg, 8);
- if(!testing){
- for(i=0; i<8; i++)
- msg[i] = 0x60+i;
- senddata(e1, msg, 8);
- e->rxintr = 0;
- sendtoken(e, TokIN);
- transmit(e);
- epprod(ctlr, 0);
- tsleep(&e->ir, spiinput, e, 1000);
- if(!spiinput(e))
- print("RX: none\n");
- }
+
+ b = allocb(2);
+ b->wp[0] = 0x07;
+ b->wp[1] = addr&0x7f;
+ b->wp+=2;
+
+ dre = &ctlr->tdr[ctlr->tdrh];
+ spicmdsend(b,dre,ctlr,1);
+
+ dre=&ctlr->rdr[ctlr->rdrx];
+ len=dre->length;
+ dcflush(KADDR(dre->addr),len);
+ dre->status=(dre->status&BDWrap)|BDEmpty|BDInt;
+ ctlr->rdrx=NEXT(ctlr->rdrx,Nrdre);
+
+ freeb(b);
+ delay(15);
+ return;
}
-static void
-setupep(int n, EPparam *ep)
+void
+spieraseall(void)
{
- Endpt *e;
-
- e = &usbctlr->pts[n];
- e->x = n;
- e->ctlr = usbctlr;
- e->xtog = TokDATA0;
- if(e->oq == nil)
- e->oq = qopen(8*1024, 1, 0, 0);
- if(e->iq == nil)
- e->iq = qopen(8*1024, 1, 0, 0);
- e->ep = ep;
- if(ioringinit(e, Nrdre, Ntdre, Bufsize) < 0)
- panic("usbreset");
- ep->rbase = PADDR(e->rdr);
- ep->rbptr = ep->rbase;
- ep->tbase = PADDR(e->tdr);
- ep->tbptr = ep->tbase;
- eieio();
-}
+ BD *dre;
+ Block *b;
+ Ctlr *ctlr;
+ int len;
+
+ ctlr = spictlr;
+ b = allocb(2);
+ b->wp[0] = 0x07;
+ b->wp[1] = 0x80;
+ b->wp+=2;
-#endif
+ dre = &ctlr->tdr[ctlr->tdrh];
+ spicmdsend(b,dre,ctlr,1);
+
+ dre=&ctlr->rdr[ctlr->rdrx];
+ len=dre->length;
+ dcflush(KADDR(dre->addr),len);
+ dre->status=(dre->status&BDWrap)|BDEmpty|BDInt;
+ ctlr->rdrx=NEXT(ctlr->rdrx,Nrdre);
+
+ freeb(b);
+ delay(15);
+ return;
+}
M pc/devether.c => pc/devether.c +23 -10
@@ 244,10 244,19 @@ etherwrite(Chan* chan, void* buf, long n, vlong)
{
Ether *ether;
Block *bp;
+ int nn;
ether = etherxx[chan->dev];
- if(NETTYPE(chan->qid.path) != Ndataqid)
- return netifwrite(ether, chan, buf, n);
+ if(NETTYPE(chan->qid.path) != Ndataqid) {
+ nn = netifwrite(ether, chan, buf, n);
+ if(nn >= 0)
+ return nn;
+
+ if(ether->ctl!=nil)
+ return ether->ctl(ether,buf,n);
+
+ error(Ebadctl);
+ }
if(n > ETHERMAXTU)
error(Etoobig);
@@ 255,13 264,8 @@ etherwrite(Chan* chan, void* buf, long n, vlong)
error(Etoosmall);
bp = allocb(n);
- if(waserror()){
- freeb(bp);
- nexterror();
- }
memmove(bp->rp, buf, n);
memmove(bp->rp+Eaddrlen, ether->ea, Eaddrlen);
- poperror();
bp->wp += n;
return etheroq(ether, bp);
@@ 274,12 278,16 @@ etherbwrite(Chan* chan, Block* bp, ulong)
long n;
n = BLEN(bp);
- ether = etherxx[chan->dev];
if(NETTYPE(chan->qid.path) != Ndataqid){
- n = netifwrite(ether, chan, bp->rp, n);
+ if(waserror()) {
+ freeb(bp);
+ nexterror();
+ }
+ n = etherwrite(chan, bp->rp, n, 0);
freeb(bp);
return n;
}
+ ether = etherxx[chan->dev];
if(n > ETHERMAXTU){
freeb(bp);
@@ 369,7 377,12 @@ etherreset(void)
if(ether->irq == 2)
ether->irq = 9;
snprint(name, sizeof(name), "ether%d", ctlrno);
- intrenable(ether->irq, ether->interrupt, ether, ether->tbdf, name);
+
+ /* If ether->irq is less than 0, it is a hack to indicate no interrupt
+ * used for the seocnd logical ethernet for the wavelan card
+ */
+ if(ether->irq >= 0)
+ intrenable(ether->irq, ether->interrupt, ether, ether->tbdf, name);
i = sprint(buf, "#l%d: %s: %dMbps port 0x%luX irq %lud",
ctlrno, ether->type, ether->mbps, ether->port, ether->irq);
M pc/etherif.h => pc/etherif.h +2 -0
@@ 11,11 11,13 @@ struct Ether {
int tbdf; /* type+busno+devno+funcno */
int mbps; /* Mbps */
uchar ea[Eaddrlen];
+ int encry;
void (*attach)(Ether*); /* filled in by reset routine */
void (*transmit)(Ether*);
void (*interrupt)(Ureg*, void*);
long (*ifstat)(Ether*, void*, long, ulong);
+ long (*ctl)(Ether*, void*, long); /* custom ctl messages */
void *ctlr;
Queue* oq;
M port/dev.c => port/dev.c +5 -0
@@ 288,7 288,12 @@ devbwrite(Chan *c, Block *bp, ulong offset)
{
long n;
+ if(waserror()) {
+ freeb(bp);
+ nexterror();
+ }
n = devtab[c->type]->write(c, bp->rp, BLEN(bp), offset);
+ poperror();
freeb(bp);
return n;