summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sys/src/cmd/nusb/ether/asix.c70
-rw-r--r--sys/src/cmd/nusb/ether/aue.c62
-rw-r--r--sys/src/cmd/nusb/ether/cdc.c51
-rw-r--r--sys/src/cmd/nusb/ether/dat.h43
-rw-r--r--sys/src/cmd/nusb/ether/ether.c218
-rw-r--r--sys/src/cmd/nusb/ether/smsc.c71
-rw-r--r--sys/src/cmd/nusb/ether/url.c64
7 files changed, 328 insertions, 251 deletions
diff --git a/sys/src/cmd/nusb/ether/asix.c b/sys/src/cmd/nusb/ether/asix.c
index 4b725f57c..7ef5df64d 100644
--- a/sys/src/cmd/nusb/ether/asix.c
+++ b/sys/src/cmd/nusb/ether/asix.c
@@ -207,51 +207,53 @@ eepromread(Dev *d, int i)
}
static int
-asixread(Dev *ep, uchar *p, int plen)
+asixreceive(Dev *ep)
{
- int n, m;
+ Block *b;
uint hd;
+ int n;
- if(nbin < 4)
- nbin = read(ep->dfd, bin, sizeof(bin));
- if(nbin < 0)
+ b = allocb(Maxpkt+4);
+ if((n = read(ep->dfd, b->wp, b->lim - b->base)) < 0){
+ freeb(b);
return -1;
- if(nbin < 4)
- return 0;
- hd = GET4(bin);
- n = hd & 0xFFFF;
- m = n+4;
- hd = (hd>>16) ^ 0xFFFF;
- if((n != hd) || (n < 6) || (m > nbin)){
- nbin = 0;
- return 0;
}
- if(n > plen)
- n = plen;
- if(n > 0)
- memmove(p, bin+4, n);
- if(m < nbin)
- memmove(bin, bin+m, nbin - m);
- nbin -= m;
- return n;
+ b->wp += n;
+ while(BLEN(b) >= 4){
+ hd = GET4(b->rp);
+ b->rp += 4;
+ n = hd & 0xFFFF;
+ hd = (hd>>16) ^ 0xFFFF;
+ if((n != hd) || (n > BLEN(b)))
+ break;
+ if(n == BLEN(b)){
+ etheriq(b, 1);
+ return 0;
+ }
+ etheriq(copyblock(b, n), 1);
+ b->rp += n;
+ }
+ freeb(b);
+ return 0;
}
static void
-asixwrite(Dev *ep, uchar *p, int n)
+asixtransmit(Dev *ep, Block *b)
{
uint hd;
+ int n;
- if(n > sizeof(bout)-8)
- n = sizeof(bout)-8;
+ n = BLEN(b);
hd = n | (n<<16)^0xFFFF0000;
- PUT4(bout, hd);
- memmove(bout+4, p, n);
+ b->rp -= 4;
+ PUT4(b->rp, hd);
n += 4;
if((n % ep->maxpkt) == 0){
- PUT4(bout+n, 0xFFFF0000);
- n += 4;
+ PUT4(b->wp, 0xFFFF0000);
+ b->wp += 4;
}
- write(ep->dfd, bout, n);
+ write(ep->dfd, b->rp, BLEN(b));
+ freeb(b);
}
static int
@@ -312,8 +314,8 @@ a88178init(Dev *d)
asixset(d, Cwmedium, Mall178);
asixset(d, Cwrxctl, Rxctlso|Rxctlab);
- epread = asixread;
- epwrite = asixwrite;
+ epreceive = asixreceive;
+ eptransmit = asixtransmit;
return 0;
}
@@ -369,7 +371,7 @@ a88772init(Dev *d)
if(asixset(d, Cwrxctl, Rxctlso|Rxctlab) < 0)
return -1;
- epread = asixread;
- epwrite = asixwrite;
+ epreceive = asixreceive;
+ eptransmit = asixtransmit;
return 0;
}
diff --git a/sys/src/cmd/nusb/ether/aue.c b/sys/src/cmd/nusb/ether/aue.c
index 1ee77a3cd..cccfefeaa 100644
--- a/sys/src/cmd/nusb/ether/aue.c
+++ b/sys/src/cmd/nusb/ether/aue.c
@@ -78,8 +78,6 @@ static int csr16r(Dev *, int);
static int csr8w(Dev *, int, int);
static int eeprom16r(Dev *, int);
static void reset(Dev *);
-static int aueread(Dev *, uchar *, int);
-static void auewrite(Dev *, uchar *, int);
static int
csr8r(Dev *d, int reg)
@@ -165,49 +163,43 @@ reset(Dev *d)
}
static int
-aueread(Dev *ep, uchar *p, int plen)
+auereceive(Dev *ep)
{
- int n;
+ Block *b;
uint hd;
- uchar *q;
+ int n;
- if(nbin < 4)
- nbin = read(ep->dfd, bin, sizeof bin);
- if(nbin < 0)
+ b = allocb(Maxpkt+4);
+ if((n = read(ep->dfd, b->wp, b->lim - b->base)) < 0){
+ freeb(b);
return -1;
- if(nbin < 4)
+ }
+ if(n < 4){
+ freeb(b);
return 0;
- q = bin + nbin - 4;
- hd = GET4(q);
+ }
+ b->wp += n-4;
+ hd = GET4(b->wp);
n = hd & 0xfff;
- if(n < 6 || n > nbin) {
- nbin = 0;
+ if((hd & Rxerror) != 0 || n > BLEN(b)){
+ freeb(b);
return 0;
}
- if(hd & Rxerror) {
- fprint(2, "%s: rx error %#ux\n",
- argv0, hd);
- n = 0;
- } else {
- if(n > plen)
- n = plen;
- if(n > 0)
- memmove(p, bin, n);
- }
- if(n < nbin)
- memmove(bin, bin+n, nbin-n);
- nbin -= n;
- return n;
+ b->wp = b->rp + n;
+ etheriq(b, 1);
+ return 0;
}
static void
-auewrite(Dev *ep, uchar *p, int n)
+auetransmit(Dev *ep, Block *b)
{
- if(n > sizeof bout-2)
- n = sizeof bout - 2;
- PUT2(bout, n);
- memmove(bout+2, p, n);
- write(ep->dfd, bout, n+2);
+ int n;
+
+ n = BLEN(b);
+ b->rp -= 2;
+ PUT2(b->rp, n);
+ write(ep->dfd, b->rp, BLEN(b));
+ freeb(b);
}
int
@@ -227,7 +219,7 @@ aueinit(Dev *d)
csr8w(d, Ctl0, C0rxstatappend|C0rxen);
csr8w(d, Ctl0, csr8r(d, Ctl0)|C0txen);
csr8w(d, Ctl2, csr8r(d, Ctl2)|C2ep3clr);
- epread = aueread;
- epwrite = auewrite;
+ epreceive = auereceive;
+ eptransmit = auetransmit;
return 0;
}
diff --git a/sys/src/cmd/nusb/ether/cdc.c b/sys/src/cmd/nusb/ether/cdc.c
index 28f56c0ae..c37efe145 100644
--- a/sys/src/cmd/nusb/ether/cdc.c
+++ b/sys/src/cmd/nusb/ether/cdc.c
@@ -5,33 +5,50 @@
#include <u.h>
#include <libc.h>
#include <thread.h>
-#include <ip.h>
#include "usb.h"
#include "dat.h"
+#include <ip.h>
+
static int
-cdcread(Dev *ep, uchar *p, int n)
+cdcreceive(Dev *ep)
{
- return read(ep->dfd, p, n);
+ Block *b;
+ int n;
+
+ b = allocb(Maxpkt);
+ if((n = read(ep->dfd, b->wp, b->lim - b->base)) < 0){
+ freeb(b);
+ return -1;
+ }
+ b->wp += n;
+ etheriq(b, 1);
+ return 0;
}
static void
-cdcwrite(Dev *ep, uchar *p, int n)
+cdctransmit(Dev *ep, Block *b)
{
- if(write(ep->dfd, p, n) < 0){
- fprint(2, "cdcwrite: %r\n");
- } else {
- /*
- * this may not work with all CDC devices. the
- * linux driver sends one more random byte
- * instead of a zero byte transaction. maybe we
- * should do the same?
- */
- if(n % ep->maxpkt == 0)
- write(ep->dfd, "", 0);
+ int n;
+
+ n = BLEN(b);
+ if(write(ep->dfd, b->rp, n) < 0){
+ freeb(b);
+ return;
}
+ freeb(b);
+
+ /*
+ * this may not work with all CDC devices. the
+ * linux driver sends one more random byte
+ * instead of a zero byte transaction. maybe we
+ * should do the same?
+ */
+ if((n % ep->maxpkt) == 0)
+ write(ep->dfd, "", 0);
}
+
int
cdcinit(Dev *d)
{
@@ -55,8 +72,8 @@ cdcinit(Dev *d)
parseether(macaddr, mac);
free(mac);
- epread = cdcread;
- epwrite = cdcwrite;
+ epreceive = cdcreceive;
+ eptransmit = cdctransmit;
return 0;
}
}
diff --git a/sys/src/cmd/nusb/ether/dat.h b/sys/src/cmd/nusb/ether/dat.h
index 0e5a962ce..180e4596e 100644
--- a/sys/src/cmd/nusb/ether/dat.h
+++ b/sys/src/cmd/nusb/ether/dat.h
@@ -1,3 +1,36 @@
+typedef struct Block Block;
+struct Block
+{
+ Ref;
+
+ Block *next;
+
+ uchar *rp;
+ uchar *wp;
+ uchar *lim;
+
+ uchar base[];
+};
+
+#define BLEN(s) ((s)->wp - (s)->rp)
+
+Block* allocb(int size);
+void freeb(Block*);
+Block* copyblock(Block*, int);
+
+typedef struct Ehdr Ehdr;
+struct Ehdr
+{
+ uchar d[6];
+ uchar s[6];
+ uchar type[2];
+};
+
+enum {
+ Ehdrsz = 6+6+2,
+ Maxpkt = 2000,
+};
+
enum
{
Cdcunion = 6,
@@ -10,10 +43,8 @@ int setmac;
/* to be filled in by *init() */
uchar macaddr[6];
-int (*epread)(Dev *, uchar *, int);
-void (*epwrite)(Dev *, uchar *, int);
-/* temporary buffers */
-uchar bout[4*1024];
-uchar bin[4*1024];
-int nbin;
+void etheriq(Block*, int wire);
+
+int (*epreceive)(Dev*);
+void (*eptransmit)(Dev*, Block*);
diff --git a/sys/src/cmd/nusb/ether/ether.c b/sys/src/cmd/nusb/ether/ether.c
index 042edcdcd..c7a622255 100644
--- a/sys/src/cmd/nusb/ether/ether.c
+++ b/sys/src/cmd/nusb/ether/ether.c
@@ -1,18 +1,17 @@
#include <u.h>
#include <libc.h>
#include <thread.h>
-#include <fcall.h>
-#include <9p.h>
-#include <ip.h>
#include "usb.h"
#include "dat.h"
+#include <fcall.h>
+#include <9p.h>
+#include <ip.h>
+
typedef struct Tab Tab;
-typedef struct Qbuf Qbuf;
typedef struct Dq Dq;
typedef struct Conn Conn;
-typedef struct Ehdr Ehdr;
typedef struct Stats Stats;
enum
@@ -48,41 +47,31 @@ Tab tab[] =
"type", 0444,
};
-struct Qbuf
-{
- Qbuf *next;
- int ndata;
- uchar data[];
-};
-
struct Dq
{
- QLock l;
+ QLock;
+
Dq *next;
Req *r;
Req **rt;
- Qbuf *q;
- Qbuf **qt;
+ Block *q;
+ Block **qt;
+
+ int size;
int nb;
};
struct Conn
{
- QLock l;
+ QLock;
+
int used;
int type;
int prom;
Dq *dq;
};
-struct Ehdr
-{
- uchar d[6];
- uchar s[6];
- uchar type[2];
-};
-
struct Stats
{
int in;
@@ -104,9 +93,6 @@ static char *uname;
#define NUM(path) (((uint)(path) & 0xFFFFFF00)>>8)
#define NUMCONN(c) (((long)(c)-(long)&conn[0])/sizeof(conn[0]))
-static int
-receivepacket(void *buf, int len);
-
static void
fillstat(Dir *d, uvlong path)
{
@@ -238,24 +224,27 @@ static void
matchrq(Dq *d)
{
Req *r;
- Qbuf *b;
+ Block *b;
while(r = d->r){
int n;
if((b = d->q) == nil)
break;
+
+ d->size -= BLEN(b);
if((d->q = b->next) == nil)
d->qt = &d->q;
if((d->r = (Req*)r->aux) == nil)
d->rt = &d->r;
n = r->ifcall.count;
- if(n > b->ndata)
- n = b->ndata;
- memmove(r->ofcall.data, b->data, n);
- free(b);
+ if(n > BLEN(b))
+ n = BLEN(b);
+ memmove(r->ofcall.data, b->rp, n);
r->ofcall.count = n;
+ freeb(b);
+
respond(r, nil);
}
}
@@ -266,19 +255,18 @@ readconndata(Req *r)
Dq *d;
d = r->fid->aux;
- qlock(&d->l);
+ qlock(d);
if(d->q==nil && d->nb){
- qunlock(&d->l);
+ qunlock(d);
r->ofcall.count = 0;
respond(r, nil);
return;
}
- // enqueue request
r->aux = nil;
*d->rt = r;
d->rt = (Req**)&r->aux;
matchrq(d);
- qunlock(&d->l);
+ qunlock(d);
}
static void
@@ -287,6 +275,7 @@ writeconndata(Req *r)
Dq *d;
void *p;
int n;
+ Block *b;
d = r->fid->aux;
p = r->ifcall.data;
@@ -295,11 +284,28 @@ writeconndata(Req *r)
d->nb = 1;
goto out;
}
- epwrite(epout, p, n);
- if(receivepacket(p, n) == 0)
- stats.out++;
+
+ /* minimum frame length for rtl8150 */
+ if(n < 60)
+ n = 60;
+
+ /* slack space for header and trailers */
+ n += 2*16;
+
+ b = allocb(n);
+
+ /* header space */
+ b->wp += 16;
+ b->rp = b->wp;
+
+ /* copy in the ethernet packet */
+ memmove(b->wp, p, r->ifcall.count);
+ b->wp += r->ifcall.count;
+
+ etheriq(b, 0);
+
out:
- r->ofcall.count = n;
+ r->ofcall.count = r->ifcall.count;
respond(r, nil);
}
@@ -433,7 +439,6 @@ fsopen(Req *r)
Dq *d;
Conn *c;
-
/*
* lib9p already handles the blatantly obvious.
* we just have to enforce the permissions we have set.
@@ -472,7 +477,7 @@ fsopen(Req *r)
case Qtype:
CaseConn:
c = &conn[NUM(path)];
- qlock(&c->l);
+ qlock(c);
if(c->used++ == 0){
c->type = 0;
c->prom = 0;
@@ -481,7 +486,7 @@ fsopen(Req *r)
d->next = c->dq;
c->dq = d;
}
- qunlock(&c->l);
+ qunlock(c);
break;
}
@@ -501,7 +506,7 @@ fsflush(Req *r)
f = o->fid;
if(TYPE(f->qid.path) == Qdata){
d = f->aux;
- qlock(&d->l);
+ qlock(d);
for(p=&d->r; *p; p=(Req**)&((*p)->aux)){
if(*p == o){
if((*p = (Req*)o->aux) == nil)
@@ -511,7 +516,7 @@ fsflush(Req *r)
break;
}
}
- qunlock(&d->l);
+ qunlock(d);
}
respond(r, nil);
}
@@ -521,12 +526,12 @@ static void
fsdestroyfid(Fid *fid)
{
Conn *c;
- Qbuf *b;
Dq **x, *d;
+ Block *b;
if(TYPE(fid->qid.path) >= Qndir){
c = &conn[NUM(fid->qid.path)];
- qlock(&c->l);
+ qlock(c);
if(d = fid->aux){
fid->aux = nil;
for(x=&c->dq; *x; x=&((*x)->next)){
@@ -535,17 +540,16 @@ fsdestroyfid(Fid *fid)
break;
}
}
- qlock(&d->l);
while(b = d->q){
d->q = b->next;
- free(b);
+ freeb(b);
}
- qunlock(&d->l);
+ free(d);
}
if(TYPE(fid->qid.path) == Qctl)
c->prom = 0;
c->used--;
- qunlock(&c->l);
+ qunlock(c);
}
}
@@ -648,26 +652,26 @@ inote(void *, char *msg)
return 0;
}
-static int
-receivepacket(void *buf, int len)
+void
+etheriq(Block *b, int wire)
{
- int i;
- int t;
+ int i, t;
+ Block *q;
+ Conn *c;
+ Dq *d;
Ehdr *h;
- if(len < sizeof(*h))
- return -1;
+ if(BLEN(b) < Ehdrsz){
+ freeb(b);
+ return;
+ }
- h = (Ehdr*)buf;
+ h = (Ehdr*)b->rp;
t = (h->type[0]<<8)|h->type[1];
for(i=0; i<nconn; i++){
- Qbuf *b;
- Conn *c;
- Dq *d;
-
c = &conn[i];
- qlock(&c->l);
+ qlock(c);
if(!c->used)
goto next;
if(c->type > 0)
@@ -677,36 +681,42 @@ receivepacket(void *buf, int len)
if(memcmp(h->d, macaddr, sizeof(macaddr)))
goto next;
for(d=c->dq; d; d=d->next){
- int n;
-
- n = len;
- if(c->type == -2 && n > 64)
- n = 64;
-
- b = emalloc9p(sizeof(*b) + n);
- b->ndata = n;
- memcpy(b->data, buf, n);
-
- qlock(&d->l);
- // enqueue buffer
- b->next = nil;
- *d->qt = b;
- d->qt = &b->next;
+ if(d->size > 100000)
+ continue;
+ if(c->type == -2) {
+ q = copyblock(b, 64);
+ } else if(wire && b->ref == 1) {
+ incref(b);
+ q = b;
+ } else {
+ q = copyblock(b, BLEN(b));
+ }
+ qlock(d);
+ q->next = nil;
+ *d->qt = q;
+ d->qt = &q->next;
+ d->size += BLEN(q);
matchrq(d);
- qunlock(&d->l);
+ qunlock(d);
}
next:
- qunlock(&c->l);
+ qunlock(c);
+ }
+ if(wire) {
+ freeb(b);
+ stats.in++;
+ } else {
+ /* transmit frees buffer */
+ (*eptransmit)(epout, b);
+ stats.out++;
}
- return 0;
}
static void
usbreadproc(void *)
{
char err[ERRMAX];
- uchar buf[4*1024];
- int n, nerr;
+ int nerr;
atnotify(inote, 1);
@@ -714,8 +724,8 @@ usbreadproc(void *)
nerr = 0;
for(;;){
- n = epread(epin, buf, sizeof(buf));
- if(n < 0){
+ /* receive allocates buffer and calls etheriq(b, 1); */
+ if((*epreceive)(epin) < 0){
rerrstr(err, sizeof(err));
if(strstr(err, "interrupted") || strstr(err, "timed out"))
continue;
@@ -725,10 +735,6 @@ usbreadproc(void *)
threadexitsall(err);
}
nerr = 0;
- if(n == 0)
- continue;
- if(receivepacket(buf, n) == 0)
- stats.in++;
}
}
@@ -819,7 +825,7 @@ threadmain(int argc, char **argv)
werrstr("");
if((*ethertype[et].init)(d) < 0)
sysfatal("%s init failed: %r", ethertype[et].name);
- if(epread == nil || epwrite == nil)
+ if(epreceive == nil || eptransmit == nil)
sysfatal("bug in init");
if((epin = openep(d, ei)) == nil)
@@ -846,3 +852,37 @@ threadmain(int argc, char **argv)
threadexits(0);
}
+
+Block*
+allocb(int size)
+{
+ Block *b;
+
+ b = emalloc9p(sizeof(*b) + size);
+ b->lim = b->base + size;
+ b->rp = b->base;
+ b->wp = b->base;
+ b->next = nil;
+ b->ref = 1;
+ return b;
+}
+
+void
+freeb(Block *b)
+{
+ if(decref(b) == 0)
+ free(b);
+}
+
+Block*
+copyblock(Block *b, int count)
+{
+ Block *nb;
+
+ if(count > BLEN(b))
+ count = BLEN(b);
+ nb = allocb(count);
+ memmove(nb->wp, b->rp, count);
+ nb->wp += count;
+ return nb;
+}
diff --git a/sys/src/cmd/nusb/ether/smsc.c b/sys/src/cmd/nusb/ether/smsc.c
index cefdeb2ed..deb8aef43 100644
--- a/sys/src/cmd/nusb/ether/smsc.c
+++ b/sys/src/cmd/nusb/ether/smsc.c
@@ -205,48 +205,51 @@ doreset(Dev *d, int reg, int bit)
}
static int
-smscread(Dev *ep, uchar *p, int plen)
+smscreceive(Dev *ep)
{
- int n, m;
+ Block *b;
uint hd;
+ int n;
- if(nbin < 4)
- nbin = read(ep->dfd, bin, Doburst ? Hsburst*512: sizeof(bin));
- if(nbin < 0)
+ if(Doburst)
+ b = allocb(Hsburst*512);
+ else
+ b = allocb(Maxpkt+4);
+ if((n = read(ep->dfd, b->wp, b->lim - b->base)) < 0){
+ freeb(b);
return -1;
- if(nbin < 4)
- return 0;
- hd = GET4(bin);
- n = hd >> 16;
- m = (n + 4 + 3) & ~3;
- if(n < 6 || n > nbin-4){
- nbin = 0;
- return 0;
}
- if(hd & Rxerror){
- fprint(2, "smsc rx error %8.8ux\n", hd);
- n = 0;
- }else{
- if(n > plen)
- n = plen;
- if(n > 0)
- memmove(p, bin+4, n);
+ b->wp += n;
+ while(BLEN(b) >= 4){
+ hd = GET4(b->rp);
+ b->rp += 4;
+ n = hd >> 16;
+ if(n > BLEN(b))
+ break;
+ if((hd & Rxerror) == 0){
+ if(n == BLEN(b)){
+ etheriq(b, 1);
+ return 0;
+ }
+ etheriq(copyblock(b, n), 1);
+ }
+ b->rp += (n + 3) & ~3;
}
- if(m < nbin)
- memmove(bin, bin+m, nbin - m);
- nbin -= m;
- return n;
+ freeb(b);
+ return 0;
}
static void
-smscwrite(Dev *ep, uchar *p, int n)
+smsctransmit(Dev *ep, Block *b)
{
- if(n > sizeof(bout)-8)
- n = sizeof(bout)-8;
- PUT4(bout, n | Txfirst | Txlast);
- PUT4(bout+4, n);
- memmove(bout+8, p, n);
- write(ep->dfd, bout, n+8);
+ int n;
+
+ n = BLEN(b);
+ b->rp -= 8;
+ PUT4(b->rp, n | Txfirst | Txlast);
+ PUT4(b->rp+4, n);
+ write(ep->dfd, b->rp, BLEN(b));
+ freeb(b);
}
int
@@ -284,7 +287,7 @@ smscinit(Dev *d)
wr(d, Maccr, rr(d, Maccr)|Txen|Rxen);
wr(d, Txcfg, Txon);
- epwrite = smscwrite;
- epread = smscread;
+ eptransmit = smsctransmit;
+ epreceive = smscreceive;
return 0;
}
diff --git a/sys/src/cmd/nusb/ether/url.c b/sys/src/cmd/nusb/ether/url.c
index af3cfe7c2..a411c6d4d 100644
--- a/sys/src/cmd/nusb/ether/url.c
+++ b/sys/src/cmd/nusb/ether/url.c
@@ -164,8 +164,6 @@ static int csr8w(Dev *, int, int);
static int csr16w(Dev *, int, int);
static int csr32w(Dev *, int, int);
static void reset(Dev *);
-static int urlread(Dev *, uchar *, int);
-static void urlwrite(Dev *, uchar *, int);
int urlinit(Dev *);
static int
@@ -263,49 +261,43 @@ reset(Dev *d)
}
static int
-urlread(Dev *ep, uchar *p, int plen)
+urlreceive(Dev *ep)
{
- int n;
+ Block *b;
uint hd;
- uchar *q;
+ int n;
- if(nbin < 4)
- nbin = read(ep->dfd, bin, sizeof bin);
- if(nbin < 0)
+ b = allocb(Maxpkt+4);
+ if((n = read(ep->dfd, b->wp, b->lim - b->base)) < 0){
+ freeb(b);
return -1;
- if(nbin < 4)
- return 0;
- n = nbin - 4;
- if(n < 6) {
- nbin = 0;
- return 0;
}
- q = bin + n;
- hd = GET2(q);
- if((hd & Vpm) == 0) {
- fprint(2, "url: rx error: %#.4ux\n", hd);
- n = 0;
- } else {
- if(n > plen)
- n = plen;
- if(n > 0)
- memmove(p, bin, n);
+ if(n < 4){
+ freeb(b);
+ return 0;
}
- nbin = 0;
- return n;
+ n -= 4;
+ b->wp += n;
+ hd = GET2(b->wp);
+ if((hd & Vpm) == 0)
+ freeb(b);
+ else
+ etheriq(b, 1);
+ return 0;
}
static void
-urlwrite(Dev *ep, uchar *p, int n)
+urltransmit(Dev *ep, Block *b)
{
- if(n > sizeof bout)
- n = sizeof bout;
- memmove(bout, p, n);
- if(n < Mfl) {
- memset(bout+n, 0, Mfl-n);
- n = Mfl;
+ int n;
+
+ n = BLEN(b);
+ if(n < Mfl){
+ memset(b->wp, 0, Mfl-n);
+ b->wp += (Mfl-n);
}
- write(ep->dfd, bout, n);
+ write(ep->dfd, b->rp, BLEN(b));
+ freeb(b);
}
int
@@ -331,7 +323,7 @@ urlinit(Dev *d)
csr8w(d, Cr, Te|Re);
- epwrite = urlwrite;
- epread = urlread;
+ epreceive = urlreceive;
+ eptransmit = urltransmit;
return 0;
}