## diffname port/devpnp.c 2001/0728
## diff -e /dev/null /n/emeliedump/2001/0728/sys/src/9/port/devpnp.c
0a
#include "u.h"
#include "../port/lib.h"
#include "mem.h"
#include "dat.h"
#include "fns.h"
#include "../port/error.h"
typedef struct Pnp Pnp;
typedef struct Card Card;
struct Pnp
{
Lock;
int rddata;
int debug;
Card *cards;
};
struct Card
{
int csn;
ulong id1;
ulong id2;
int ncfg;
Card* next;
};
static Pnp pnp;
#define DPRINT if(pnp.debug) print
#define XPRINT if(1) print
enum {
Address = 0x279,
WriteData = 0xa79,
Qtopdir = 0,
Qpnpdir,
Qpnpctl,
Qcsnctl,
Qcsnraw,
Qpcidir,
Qpcictl,
Qpciraw,
};
#define TYPE(q) ((ulong)(q).path & 0x0F)
#define CSN(q) (((ulong)(q).path>>4) & 0xFF)
#define QID(c, t) (((c)<<4)|(t))
static Dirtab topdir[] = {
".", { Qtopdir, 0, QTDIR }, 0, 0555,
"pnp", { Qpnpdir, 0, QTDIR }, 0, 0555,
"pci", { Qpcidir, 0, QTDIR }, 0, 0555,
};
static Dirtab pnpdir[] = {
".", { Qpnpdir, 0, QTDIR }, 0, 0555,
"ctl", { Qpnpctl, 0, 0 }, 0, 0666,
};
extern Dev pnpdevtab;
static char key[32] =
{
0x6A, 0xB5, 0xDA, 0xED, 0xF6, 0xFB, 0x7D, 0xBE,
0xDF, 0x6F, 0x37, 0x1B, 0x0D, 0x86, 0xC3, 0x61,
0xB0, 0x58, 0x2C, 0x16, 0x8B, 0x45, 0xA2, 0xD1,
0xE8, 0x74, 0x3A, 0x9D, 0xCE, 0xE7, 0x73, 0x39,
};
static void
cmd(int reg, int val)
{
outb(Address, reg);
outb(WriteData, val);
}
/* Send initiation key, putting each card in Sleep state */
static void
initiation(void)
{
int i;
/* ensure each card's LFSR is reset */
outb(Address, 0x00);
outb(Address, 0x00);
/* send initiation key */
for (i = 0; i < 32; i++)
outb(Address, key[i]);
}
/* isolation protocol... */
static int
readbit(int rddata)
{
int r1, r2;
r1 = inb(rddata);
r2 = inb(rddata);
microdelay(250);
return (r1 == 0x55) && (r2 == 0xaa);
}
static int
isolate(int rddata, ulong *id1, ulong *id2)
{
int i, csum, bit;
uchar *p, id[9];
outb(Address, 0x01); /* point to serial isolation register */
delay(1);
csum = 0x6a;
for (i = 0; i < 64; i++) {
bit = readbit(rddata);
csum = (csum>>1) | (((csum&1) ^ ((csum>>1)&1) ^ bit)<<7);
p = &id[i>>3];
*p = (*p>>1) | (bit<<7);
}
for (; i < 72; i++) {
p = &id[i>>3];
*p = (*p>>1) | (readbit(rddata)<<7);
}
*id1 = (id[3]<<24)|(id[2]<<16)|(id[1]<<8)|id[0];
*id2 = (id[7]<<24)|(id[6]<<16)|(id[5]<<8)|id[4];
if (*id1 == 0)
return 0;
if (id[8] != csum)
DPRINT("pnp: bad checksum id1 %lux id2 %lux csum %x != %x\n", *id1, *id2, csum, id[8]); /**/
return id[8] == csum;
}
static int
getresbyte(int rddata)
{
int tries = 0;
outb(Address, 0x05);
while ((inb(rddata) & 1) == 0)
if (tries++ > 1000000)
error("pnp: timeout waiting for resource data\n");
outb(Address, 0x04);
return inb(rddata);
}
static char *
serial(ulong id1, ulong id2)
{
int i1, i2, i3;
ulong x;
static char buf[20];
i1 = (id1>>2)&31;
i2 = ((id1<<3)&24)+((id1>>13)&7);
i3 = (id1>>8)&31;
x = (id1>>8)&0xff00|(id1>>24)&0x00ff;
if (i1 > 0 && i1 < 27 && i2 > 0 && i2 < 27 && i3 > 0 && i3 < 27 && (id1 & (1<<7)) == 0)
snprint(buf, sizeof(buf), "%c%c%c%.4lux.%lux", 'A'+i1-1, 'A'+i2-1, 'A'+i3-1, x, id2);
else
snprint(buf, sizeof(buf), "%.4lux%.4lux.%lux", (id1<<8)&0xff00|(id1>>8)&0x00ff, x, id2);
return buf;
}
/* called with pnp locked */
static Card *
findcsn(int csn, int create)
{
Card *c, *nc, **l;
l = &pnp.cards;
for(c = *l; c != nil; c = *l) {
if(c->csn == csn)
return c;
if(c->csn > csn)
break;
l = &c->next;
}
if(!create)
return nil;
*l = nc = malloc(sizeof(Card));
nc->next = c;
nc->csn = csn;
return nc;
}
static int
newcsn(void)
{
int csn;
Card *c;
csn = 1;
for(c = pnp.cards; c != nil; c = c->next) {
if(c->csn > csn)
break;
csn = c->csn+1;
}
return csn;
}
static int
pnpncfg(int rddata)
{
int i, n, x, ncfg, n1, n2;
ncfg = 0;
for (;;) {
x = getresbyte(rddata);
if((x & 0x80) == 0) {
n = (x&7)+1;
for(i = 1; i < n; i++)
getresbyte(rddata);
}
else {
n1 = getresbyte(rddata);
n2 = getresbyte(rddata);
n = (n2<<8)|n1 + 3;
for (i = 3; i < n; i++)
getresbyte(rddata);
}
ncfg += n;
if((x>>3) == 0x0f)
break;
}
return ncfg;
}
/* look for cards, and assign them CSNs */
static int
pnpscan(int rddata)
{
Card *c;
int csn, ok;
ulong id1, id2;
ilock(&pnp);
pnp.rddata = rddata;
initiation();
cmd(0x02, 0x04+0x01); /* reset CSN on all cards and reset logical devices */
delay(1); /* delay after resetting cards */
cmd(0x03, 0); /* Wake all cards with a CSN of 0 */
cmd(0x00, rddata>>2); /* Set the READ_DATA port on all cards */
while(isolate(rddata, &id1, &id2)) {
for(c = pnp.cards; c != nil; c = c->next)
if(c->id1 == id1 && c->id2 == id2)
break;
if(c == nil) {
csn = newcsn();
c = findcsn(csn, 1);
c->id1 = id1;
c->id2 = id2;
}
cmd(0x06, c->csn); /* set the card's csn */
print("pnp%d: %s\n", c->csn, serial(id1, id2));
c->ncfg = pnpncfg(rddata);
cmd(0x03, 0); /* Wake all cards with a CSN of 0, putting this card to sleep */
}
cmd(0x02, 0x02); /* return cards to Wait for Key state */
ok = (pnp.cards != 0);
iunlock(&pnp);
return ok;
}
static void
pnpreset(void)
{
Card *c;
ulong id1, id2;
int csn, i1, i2, i3, x;
char *s, *p, buf[20];
ISAConf isa;
memset(&isa, 0, sizeof(ISAConf));
pnp.rddata = -1;
if (isaconfig("pnp", 0, &isa) == 0)
return;
if(isa.port < 0x203 || isa.port > 0x3ff)
return;
for(csn = 1; csn < 256; csn++) {
sprint(buf, "pnp%d", csn);
s = getconf(buf);
if(s == 0)
continue;
if(strlen(s) < 8 || s[7] != '.' || s[0] < 'A' || s[0] > 'Z' || s[1] < 'A' || s[1] > 'Z' || s[2] < 'A' || s[2] > 'Z') {
bad:
print("pnp%d: bad conf string %s\n", csn, s);
continue;
}
i1 = s[0]-'A'+1;
i2 = s[1]-'A'+1;
i3 = s[2]-'A'+1;
x = strtoul(&s[3], 0, 16);
id1 = (i1<<2)|((i2>>3)&3)|((i2&7)<<13)|(i3<<8)|((x&0xff)<<24)|((x&0xff00)<<8);
id2 = strtoul(&s[8], &p, 16);
if(*p != ' ' && *p != '\0')
goto bad;
c = findcsn(csn, 1);
c->id1 = id1;
c->id2 = id2;
}
pnpscan(isa.port);
}
static int
pnpgen1(Chan *c, int t, int csn, Card *cp, Dir *dp)
{
Qid q;
char buf[20];
switch(t) {
case Qcsnctl:
q = (Qid){QID(csn, Qcsnctl), 0, 0};
sprint(buf, "csn%dctl", csn);
devdir(c, q, buf, 0, eve, 0664, dp);
return 1;
case Qcsnraw:
q = (Qid){QID(csn, Qcsnraw), 0, 0};
sprint(buf, "csn%draw", csn);
devdir(c, q, buf, cp->ncfg, eve, 0444, dp);
return 1;
}
return -1;
}
static int
pnpgen(Chan *c, char *, Dirtab*, int, int s, Dir *dp)
{
Qid q;
int csn;
Card *cp;
char name[KNAMELEN];
DPRINT("pnpgen s %d offset %uld qid %lux\n", s, (ulong)c->offset, (ulong)c->qid.path);
switch(TYPE(c->qid)){
case Qtopdir:
if(s == DEVDOTDOT){
q = (Qid){QID(0, Qtopdir), 0, QTDIR};
snprint(name, KNAMELEN, "#%C", pnpdevtab.dc);
devdir(c, q, name, 0, eve, 0555, dp);
return 1;
}
return devgen(c, nil, topdir, nelem(topdir), s, dp);
case Qpnpdir:
if(s == DEVDOTDOT){
q = (Qid){QID(0, Qtopdir), 0, QTDIR};
snprint(name, KNAMELEN, "#%C", pnpdevtab.dc);
devdir(c, q, name, 0, eve, 0555, dp);
return 1;
}
DPRINT("Qpnpdir s %d\n", s);
if(s < nelem(pnpdir))
return devgen(c, nil, pnpdir, nelem(pnpdir), s, dp);
s -= nelem(pnpdir);
DPRINT("Qpnpdir s now %d\n", s);
ilock(&pnp);
cp = pnp.cards;
while(s >= 2 && cp != nil) {
s -= 2;
cp = cp->next;
}
iunlock(&pnp);
DPRINT("Qpnpdir s now %d, cp %p\n", s, cp);
if(cp == nil)
return -1;
return pnpgen1(c, s+Qcsnctl, cp->csn, cp, dp);
case Qpnpctl:
return devgen(c, nil, pnpdir, nelem(pnpdir), s, dp);
case Qcsnctl:
case Qcsnraw:
csn = CSN(c->qid);
ilock(&pnp);
cp = findcsn(csn, 0);
iunlock(&pnp);
if(cp == nil)
return -1;
return pnpgen1(c, TYPE(c->qid), csn, cp, dp);
default:
break;
}
return -1;
}
static Chan*
pnpattach(char *spec)
{
return devattach(pnpdevtab.dc, spec);
}
Walkqid*
pnpwalk(Chan* c, Chan *nc, char** name, int nname)
{
return devwalk(c, nc, name, nname, (Dirtab *)0, 0, pnpgen);
}
static int
pnpstat(Chan* c, uchar* dp, int n)
{
return devstat(c, dp, n, (Dirtab *)0, 0L, pnpgen);
}
static Chan*
pnpopen(Chan *c, int omode)
{
c = devopen(c, omode, (Dirtab*)0, 0, pnpgen);
switch(TYPE(c->qid)){
default:
break;
}
return c;
}
static void
pnpclose(Chan*)
{
}
static long
pnpread(Chan *c, void *va, long n, vlong offset)
{
int csn, i;
Card *cp;
char *a = va, buf[20];
switch(TYPE(c->qid)){
case Qtopdir:
case Qpnpdir:
case Qpcidir:
return devdirread(c, a, n, (Dirtab *)0, 0L, pnpgen);
case Qpnpctl:
if(pnp.rddata > 0)
sprint(buf, "enabled 0x%x\n", pnp.rddata);
else
sprint(buf, "disabled\n");
return readstr(offset, a, n, buf);
case Qcsnraw:
csn = CSN(c->qid);
ilock(&pnp);
cp = findcsn(csn, 0);
iunlock(&pnp);
if(cp == nil)
error(Egreg);
if(offset+n > cp->ncfg)
n = cp->ncfg - offset;
ilock(&pnp);
initiation();
cmd(0x03, csn); /* Wake up the card */
for (i = 0; i < offset+9; i++) /* 9 == skip serial + csum */
getresbyte(pnp.rddata);
for (i = 0; i < n; i++)
a[i] = getresbyte(pnp.rddata);
cmd(0x03, 0); /* Wake all cards with a CSN of 0, putting this card to sleep */
cmd(0x02, 0x02); /* return cards to Wait for Key state */
iunlock(&pnp);
break;
case Qcsnctl:
csn = CSN(c->qid);
ilock(&pnp);
cp = findcsn(csn, 0);
iunlock(&pnp);
if(cp == nil)
error(Egreg);
sprint(buf, "%s\n", serial(cp->id1, cp->id2));
return readstr(offset, a, n, buf);
default:
error(Egreg);
}
return n;
}
static long
pnpwrite(Chan *c, void *a, long n, vlong offset)
{
ulong port;
char buf[256];
switch(TYPE(c->qid)){
case Qpnpctl:
if(n >= sizeof(buf))
n = sizeof(buf)-1;
strncpy(buf, a, n);
buf[n] = 0;
if(strncmp(buf, "rddata ", 7) == 0) {
port = strtoul(buf+7, 0, 0);
if(port < 0x203 || port > 0x3ff)
error("bad value for rddata port");
if(!pnpscan(port))
error("no cards found");
}
else if(strncmp(buf, "debug ", 6) == 0)
pnp.debug = strtoul(buf+6, 0, 0);
else
error(Ebadctl);
break;
default:
USED(offset);
error(Egreg);
}
return n;
}
Dev pnpdevtab = {
'$',
"pnp",
pnpreset,
devinit,
pnpattach,
pnpwalk,
pnpstat,
pnpopen,
devcreate,
pnpclose,
pnpread,
devbread,
pnpwrite,
devbwrite,
devremove,
devwstat,
};
.
## diffname port/devpnp.c 2001/0731
## diff -e /n/emeliedump/2001/0728/sys/src/9/port/devpnp.c /n/emeliedump/2001/0731/sys/src/9/port/devpnp.c
503a
static int
wrconfig(Card *c, char *cmd)
{
for(;;) {
while(*cmd == ' ' || *cmd == '\t' || *cmd == '\n')
cmd++;
if(*cmd == '\0')
break;
if(strncmp(cmd, "foo ", 4) == 0) {
print("pnp%d: got foo\n", c->csn);
cmd += 4;
}
else if(strncmp(cmd, "bar ", 4) == 0) {
print("pnp%d: got bar\n", c->csn);
cmd += 4;
}
else
return 0;
}
return 1;
}
.
499d
497a
case Qcsnctl:
csn = CSN(c->qid);
ilock(&pnp);
cp = findcsn(csn, 0);
iunlock(&pnp);
if(cp == nil)
error(Egreg);
if(!wrconfig(cp, buf))
error(Ebadctl);
break;
.
490c
if(!pnpscan(port, 0))
.
482,487c
if(strncmp(buf, "port ", 5) == 0) {
port = strtoul(buf+5, 0, 0);
.
479a
if(n >= sizeof(buf))
n = sizeof(buf)-1;
strncpy(buf, a, n);
buf[n] = 0;
.
476a
int csn;
Card *cp;
.
475c
pnpwrite(Chan *c, void *a, long n, vlong)
.
366d
357,358c
s -= nelem(pnpdir)-1;
.
354,355c
if(s < nelem(pnpdir)-1)
.
337d
305c
pnpscan(isa.port, 1);
.
303a
c->cfgstr = p;
.
299c
if(*p == ' ')
p++;
else if(*p == '\0')
p = nil;
else
.
258c
if(dawn)
print("pnp%d: %s\n", c->csn, serial(id1, id2));
.
256a
else if(c->cfgstr != nil) {
if(!wrconfig(c, c->cfgstr))
print("pnp%d: bad cfg: %s\n", c->csn, c->cfgstr);
c->cfgstr = nil;
}
.
241c
initiation(); /* upsilon sigma */
.
233c
pnpscan(int rddata, int dawn)
.
64a
static int wrconfig(Card*, char*);
.
23a
char *cfgstr;
.
## diffname port/devpnp.c 2001/0801
## diff -e /n/emeliedump/2001/0731/sys/src/9/port/devpnp.c /n/emeliedump/2001/0801/sys/src/9/port/devpnp.c
476a
case Qpcictl:
tbdf = MKBUS(BusPCI, 0, 0, 0)|BUSBDF((ulong)c->qid.path);
p = pcimatchtbdf(tbdf);
if(p == nil)
error(Egreg);
snprint(buf, sizeof(buf), "class %.2x subclass %.2x piclass %.2x vid %.4x did %.4x intl %d\n",
p->ccrb, p->ccru, p->ccrp, p->vid, p->did, p->intl);
return readstr(offset, a, n, buf);
case Qpciraw:
tbdf = MKBUS(BusPCI, 0, 0, 0)|BUSBDF((ulong)c->qid.path);
p = pcimatchtbdf(tbdf);
if(p == nil)
error(Egreg);
break;
.
435c
Pcidev *p;
int csn, i, tbdf;
char *a = va, buf[256];
.
433d
389c
return csngen(c, TYPE(c->qid), csn, cp, dp);
case Qpcidir:
if(s == DEVDOTDOT){
q = (Qid){QID(0, Qtopdir), 0, QTDIR};
snprint(name, KNAMELEN, "#%C", pnpdevtab.dc);
devdir(c, q, name, 0, eve, 0555, dp);
return 1;
}
p = pcimatch(nil, 0, 0);
while(s >= 2 && p != nil) {
p = pcimatch(p, 0, 0);
s -= 2;
}
if(p == nil)
return -1;
return pcigen(c, s+Qpcictl, p->tbdf, dp);
case Qpcictl:
case Qpciraw:
tbdf = MKBUS(BusPCI, 0, 0, 0)|BUSBDF((ulong)c->qid.path);
p = pcimatchtbdf(tbdf);
if(p == nil)
return -1;
return pcigen(c, TYPE(c->qid), tbdf, dp);
.
378c
return csngen(c, s+Qcsnctl, cp->csn, cp, dp);
.
348c
Pcidev *p;
int csn, tbdf;
static char name[KNAMELEN];
.
346d
342a
pcigen(Chan *c, int t, int tbdf, Dir *dp)
{
Qid q;
static char name[KNAMELEN];
q = (Qid){BUSBDF(tbdf)|t, 0, 0};
switch(t) {
case Qpcictl:
snprint(name, KNAMELEN, "%d.%d.%dctl", BUSBNO(tbdf), BUSDNO(tbdf), BUSFNO(tbdf));
devdir(c, q, name, 0, eve, 0444, dp);
return 1;
case Qpciraw:
snprint(name, KNAMELEN, "%d.%d.%draw", BUSBNO(tbdf), BUSDNO(tbdf), BUSFNO(tbdf));
devdir(c, q, name, 128, eve, 0444, dp);
return 1;
}
return -1;
}
static int
.
325c
static char buf[20];
.
322c
csngen(Chan *c, int t, int csn, Card *cp, Dir *dp)
.
5a
#include "io.h"
.
## diffname port/devpnp.c 2001/0809
## diff -e /n/emeliedump/2001/0801/sys/src/9/port/devpnp.c /n/emeliedump/2001/0809/sys/src/9/port/devpnp.c
571,573c
cp = findcsn(csn, 0, 1);
.
562a
qunlock(&pnp);
.
560a
qlock(&pnp);
if(waserror()) {
qunlock(&pnp);
nexterror();
}
if(pnp.rddata > 0)
error("pnp port already set");
.
529c
return readstr(offset, a, n, up->genbuf);
.
527c
sprint(up->genbuf, "class %.2x subclass %.2x piclass %.2x vid %.4x did %.4x intl %d\n",
.
520,521c
sprint(up->genbuf, "%s\n", serial(cp->id1, cp->id2));
return readstr(offset, a, n, up->genbuf);
.
515,517c
cp = findcsn(csn, 0, 1);
.
511c
qunlock(&pnp);
.
502c
qlock(&pnp);
.
495,497c
cp = findcsn(csn, 0, 1);
.
491,492c
sprint(up->genbuf, "disabled\n");
return readstr(offset, a, n, up->genbuf);
.
489c
sprint(up->genbuf, "enabled 0x%x\n", pnp.rddata);
.
480c
char *a = va;
.
415,416c
sprint(up->genbuf, "#%C", pnpdevtab.dc);
devdir(c, q, up->genbuf, 0, eve, 0555, dp);
.
406,408c
cp = findcsn(csn, 0, 1);
.
397c
qunlock(&pnp);
.
391c
qlock(&pnp);
.
384,385c
sprint(up->genbuf, "#%C", pnpdevtab.dc);
devdir(c, q, up->genbuf, 0, eve, 0555, dp);
.
376,377c
sprint(up->genbuf, "#%C", pnpdevtab.dc);
devdir(c, q, up->genbuf, 0, eve, 0555, dp);
.
370d
356,357c
sprint(up->genbuf, "%d.%d.%draw", BUSBNO(tbdf), BUSDNO(tbdf), BUSFNO(tbdf));
devdir(c, q, up->genbuf, 128, eve, 0444, dp);
.
352,353c
sprint(up->genbuf, "%d.%d.%dctl", BUSBNO(tbdf), BUSDNO(tbdf), BUSFNO(tbdf));
devdir(c, q, up->genbuf, 0, eve, 0444, dp);
.
347d
336,337c
sprint(up->genbuf, "csn%draw", csn);
devdir(c, q, up->genbuf, cp->ncfg, eve, 0444, dp);
.
331,332c
sprint(up->genbuf, "csn%dctl", csn);
devdir(c, q, up->genbuf, 0, eve, 0664, dp);
.
326d
314c
c = findcsn(csn, 1, 0);
.
272,274c
if(pnp.cards != 0) {
pnp.rddata = rddata;
return 1;
}
return 0;
.
256c
c = findcsn(csn, 1, 0);
.
242,243d
239c
int csn;
.
184,189c
if(create) {
*l = nc = malloc(sizeof(Card));
nc->next = c;
nc->csn = csn;
c = nc;
}
done:
if(dolock)
qunlock(&pnp);
return c;
.
179c
goto done;
.
175a
if(dolock)
qlock(&pnp);
.
172c
findcsn(int csn, int create, int dolock)
.
170d
14c
QLock;
.
0a
/*
* ISA PNP 1.0 support + access to PCI configuration space
*
* TODO
* - implement PNP card configuration (setting io bases etc)
* - implement PCI raw access to configuration space
* - implement PCI access to memory/io space/BIOS ROM
* - use c->aux instead of performing lookup on each read/write
*
* I also need to write the user program that'll drive the PNP configuration...
*/
.
## diffname port/devpnp.c 2002/0109
## diff -e /n/emeliedump/2001/0809/sys/src/9/port/devpnp.c /n/emeliedump/2002/0109/sys/src/9/port/devpnp.c
626a
devshutdown,
.
## diffname port/devpnp.c 2002/0414
## diff -e /n/emeliedump/2002/0109/sys/src/9/port/devpnp.c /n/emeliedump/2002/0414/sys/src/9/port/devpnp.c
542c
if(offset > 128)
return 0;
if(n+offset > 128)
n = 128-offset;
if(offset%4)
error(Ebadarg);
r = offset;
for(i = 0; i+4 <= n; i+=4) {
x = pcicfgr32(p, r);
a[0] = x;
a[1] = (x>>8);
a[2] = (x>>16);
a[3] = (x>>24);
a += 4;
r += 4;
}
return i;
.
536c
for(i=0; i<nelem(p->mem); i++){
if(p->mem[i].size == 0)
continue;
w = seprint(w, ebuf, " %d:%.8lux %d", i, p->mem[i].bar, p->mem[i].size);
}
*w++ = '\n';
*w = '\0';
return readstr(offset, a, n, buf);
.
534c
ebuf = buf+sizeof buf-1; /* -1 for newline */
w = seprint(buf, ebuf, "%.2x.%.2x.%.2x %.4x/%.4x %3d",
.
516c
for(i = 0; i < n; i++)
.
514c
for(i = 0; i < offset+9; i++) /* 9 == skip serial + csum */
.
491a
int csn, i, tbdf, r;
.
490c
char buf[256], *ebuf, *w;
.
487a
ulong x;
.
## diffname port/devpnp.c 2002/0416
## diff -e /n/emeliedump/2002/0414/sys/src/9/port/devpnp.c /n/emeliedump/2002/0416/sys/src/9/port/devpnp.c
554,555c
if(n+offset > 256)
n = 256-offset;
.
552c
if(offset > 256)
.
## diffname port/devpnp.c 2002/0427
## diff -e /n/emeliedump/2002/0416/sys/src/9/port/devpnp.c /n/emeliedump/2002/0427/sys/src/9/port/devpnp.c
627,642c
/* This should implement setting of I/O bases, etc */
USED(c, cmd);
.
603a
poperror();
.
8,10c
* - use c->aux instead of performing lookup on each read/write?
.
6c
* - write user program to drive PNP configuration...
* - extend PCI raw access to configuration space (writes, byte/short access?)
.
## diffname port/devpnp.c 2003/0406
## diff -e /n/emeliedump/2002/0427/sys/src/9/port/devpnp.c /n/emeliedump/2003/0406/sys/src/9/port/devpnp.c
144c
if(id[8] != csum)
.
142c
if(*id1 == 0)
.
136c
for(; i < 72; i++){
.
130c
for(i = 0; i < 64; i++){
.
|