| plan 9 kernel history: overview | file list | diff list |
2001/0728/port/devpnp.c (diff list | history)
| 2001/0728/sys/src/9/port/devpnp.c:21,26 – 2001/0731/sys/src/9/port/devpnp.c:21,27 (short | long) | ||
| 2001/0728 | int csn; ulong id1; ulong id2; | |
| 2001/0731 | char *cfgstr; | |
| 2001/0728 | int ncfg; Card* next; }; | |
| 2001/0728/sys/src/9/port/devpnp.c:62,67 – 2001/0731/sys/src/9/port/devpnp.c:63,69 | ||
| 2001/0728 | }; extern Dev pnpdevtab; | |
| 2001/0731 | static int wrconfig(Card*, char*); | |
| 2001/0728 | static char key[32] = { | |
| 2001/0728/sys/src/9/port/devpnp.c:230,236 – 2001/0731/sys/src/9/port/devpnp.c:232,238 | ||
| 2001/0728 | /* look for cards, and assign them CSNs */ static int | |
| 2001/0731 | pnpscan(int rddata, int dawn) | |
| 2001/0728 | { Card *c; int csn, ok; | |
| 2001/0728/sys/src/9/port/devpnp.c:238,244 – 2001/0731/sys/src/9/port/devpnp.c:240,246 | ||
| 2001/0728 | ilock(&pnp); pnp.rddata = rddata; | |
| 2001/0731 | initiation(); /* upsilon sigma */ | |
| 2001/0728 | cmd(0x02, 0x04+0x01); /* reset CSN on all cards and reset logical devices */ delay(1); /* delay after resetting cards */ | |
| 2001/0728/sys/src/9/port/devpnp.c:254,261 – 2001/0731/sys/src/9/port/devpnp.c:256,269 | ||
| 2001/0728 | c->id1 = id1; c->id2 = id2; } | |
| 2001/0731 | else if(c->cfgstr != nil) { if(!wrconfig(c, c->cfgstr)) print("pnp%d: bad cfg: %s\n", c->csn, c->cfgstr); c->cfgstr = nil; } | |
| 2001/0728 | cmd(0x06, c->csn); /* set the card's csn */ | |
| 2001/0731 | if(dawn) print("pnp%d: %s\n", c->csn, serial(id1, id2)); | |
| 2001/0728 | c->ncfg = pnpncfg(rddata); cmd(0x03, 0); /* Wake all cards with a CSN of 0, putting this card to sleep */ } | |
| 2001/0728/sys/src/9/port/devpnp.c:296,308 – 2001/0731/sys/src/9/port/devpnp.c:304,321 | ||
| 2001/0728 | 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); | |
| 2001/0731 | if(*p == ' ') p++; else if(*p == '\0') p = nil; else | |
| 2001/0728 | goto bad; c = findcsn(csn, 1); c->id1 = id1; c->id2 = id2; | |
| 2001/0731 | c->cfgstr = p; | |
| 2001/0728 | } | |
| 2001/0731 | pnpscan(isa.port, 1); | |
| 2001/0728 | } static int | |
| 2001/0728/sys/src/9/port/devpnp.c:334,340 – 2001/0731/sys/src/9/port/devpnp.c:347,352 | ||
| 2001/0728 | Card *cp; char name[KNAMELEN]; | |
| 2001/0728/sys/src/9/port/devpnp.c:351,361 – 2001/0731/sys/src/9/port/devpnp.c:363,371 | ||
| 2001/0728 | devdir(c, q, name, 0, eve, 0555, dp); return 1; } | |
| 2001/0731 | if(s < nelem(pnpdir)-1) | |
| 2001/0728 | return devgen(c, nil, pnpdir, nelem(pnpdir), s, dp); | |
| 2001/0731 | s -= nelem(pnpdir)-1; | |
| 2001/0728 | ilock(&pnp); cp = pnp.cards; while(s >= 2 && cp != nil) { | |
| 2001/0728/sys/src/9/port/devpnp.c:363,369 – 2001/0731/sys/src/9/port/devpnp.c:373,378 | ||
| 2001/0728 | cp = cp->next; } iunlock(&pnp); | |
| 2001/0728/sys/src/9/port/devpnp.c:472,493 – 2001/0731/sys/src/9/port/devpnp.c:481,505 | ||
| 2001/0728 | } static long | |
| 2001/0731 | pnpwrite(Chan *c, void *a, long n, vlong) | |
| 2001/0728 | { | |
| 2001/0731 | int csn; Card *cp; | |
| 2001/0728 | ulong port; char buf[256]; | |
| 2001/0731 | if(n >= sizeof(buf)) n = sizeof(buf)-1; strncpy(buf, a, n); buf[n] = 0; | |
| 2001/0728 | switch(TYPE(c->qid)){ case Qpnpctl: | |
| 2001/0731 | if(strncmp(buf, "port ", 5) == 0) { port = strtoul(buf+5, 0, 0); | |
| 2001/0728 | if(port < 0x203 || port > 0x3ff) error("bad value for rddata port"); | |
| 2001/0731 | if(!pnpscan(port, 0)) | |
| 2001/0728 | error("no cards found"); } else if(strncmp(buf, "debug ", 6) == 0) | |
| 2001/0728/sys/src/9/port/devpnp.c:495,506 – 2001/0731/sys/src/9/port/devpnp.c:507,550 | ||
| 2001/0728 | else error(Ebadctl); break; | |
| 2001/0731 | 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; | |
| 2001/0728 | default: | |
| 2001/0731 | 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; } | |
| 2001/0728 | Dev pnpdevtab = { '$', | |
| 2001/0731/sys/src/9/port/devpnp.c:3,8 – 2001/0801/sys/src/9/port/devpnp.c:3,9 (short | long) | ||
| 2001/0728 | #include "mem.h" #include "dat.h" #include "fns.h" | |
| 2001/0801 | #include "io.h" | |
| 2001/0728 | #include "../port/error.h" typedef struct Pnp Pnp; | |
| 2001/0731/sys/src/9/port/devpnp.c:319,328 – 2001/0801/sys/src/9/port/devpnp.c:320,329 | ||
| 2001/0728 | } static int | |
| 2001/0801 | csngen(Chan *c, int t, int csn, Card *cp, Dir *dp) | |
| 2001/0728 | { Qid q; | |
| 2001/0801 | static char buf[20]; | |
| 2001/0728 | switch(t) { case Qcsnctl: | |
| 2001/0731/sys/src/9/port/devpnp.c:340,351 – 2001/0801/sys/src/9/port/devpnp.c:341,373 | ||
| 2001/0728 | } static int | |
| 2001/0801 | 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 | |
| 2001/0728 | pnpgen(Chan *c, char *, Dirtab*, int, int s, Dir *dp) { Qid q; | |
| 2001/0801 | Pcidev *p; int csn, tbdf; static char name[KNAMELEN]; | |
| 2001/0728 | switch(TYPE(c->qid)){ case Qtopdir: | |
| 2001/0731/sys/src/9/port/devpnp.c:375,381 – 2001/0801/sys/src/9/port/devpnp.c:397,403 | ||
| 2001/0728 | iunlock(&pnp); if(cp == nil) return -1; | |
| 2001/0801 | return csngen(c, s+Qcsnctl, cp->csn, cp, dp); | |
| 2001/0728 | case Qpnpctl: return devgen(c, nil, pnpdir, nelem(pnpdir), s, dp); case Qcsnctl: | |
| 2001/0731/sys/src/9/port/devpnp.c:386,392 – 2001/0801/sys/src/9/port/devpnp.c:408,436 | ||
| 2001/0728 | iunlock(&pnp); if(cp == nil) return -1; | |
| 2001/0801 | 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); | |
| 2001/0728 | default: break; } | |
| 2001/0731/sys/src/9/port/devpnp.c:430,438 – 2001/0801/sys/src/9/port/devpnp.c:474,483 | ||
| 2001/0728 | static long pnpread(Chan *c, void *va, long n, vlong offset) { | |
| 2001/0801 | Pcidev *p; int csn, i, tbdf; char *a = va, buf[256]; | |
| 2001/0728 | switch(TYPE(c->qid)){ case Qtopdir: | |
| 2001/0731/sys/src/9/port/devpnp.c:474,479 – 2001/0801/sys/src/9/port/devpnp.c:519,538 | ||
| 2001/0728 | error(Egreg); sprint(buf, "%s\n", serial(cp->id1, cp->id2)); return readstr(offset, a, n, buf); | |
| 2001/0801 | 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; | |
| 2001/0728 | default: error(Egreg); } | |
| 2001/0801/sys/src/9/port/devpnp.c:1,3 – 2001/0809/sys/src/9/port/devpnp.c:1,14 (short | long) | ||
| 2001/0809 | /* * 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... */ | |
| 2001/0728 | #include "u.h" #include "../port/lib.h" #include "mem.h" | |
| 2001/0801/sys/src/9/port/devpnp.c:11,17 – 2001/0809/sys/src/9/port/devpnp.c:22,28 | ||
| 2001/0728 | struct Pnp { | |
| 2001/0809 | QLock; | |
| 2001/0728 | int rddata; int debug; Card *cards; | |
| 2001/0801/sys/src/9/port/devpnp.c:167,192 – 2001/0809/sys/src/9/port/devpnp.c:178,208 | ||
| 2001/0728 | return buf; } | |
| 2001/0809 | findcsn(int csn, int create, int dolock) | |
| 2001/0728 | { Card *c, *nc, **l; | |
| 2001/0809 | if(dolock) qlock(&pnp); | |
| 2001/0728 | l = &pnp.cards; for(c = *l; c != nil; c = *l) { if(c->csn == csn) | |
| 2001/0809 | goto done; | |
| 2001/0728 | if(c->csn > csn) break; l = &c->next; } | |
| 2001/0809 | if(create) { *l = nc = malloc(sizeof(Card)); nc->next = c; nc->csn = csn; c = nc; } done: if(dolock) qunlock(&pnp); return c; | |
| 2001/0728 | } static int | |
| 2001/0801/sys/src/9/port/devpnp.c:236,246 – 2001/0809/sys/src/9/port/devpnp.c:252,260 | ||
| 2001/0731 | pnpscan(int rddata, int dawn) | |
| 2001/0728 | { Card *c; | |
| 2001/0809 | int csn; | |
| 2001/0728 | ulong id1, id2; | |
| 2001/0731 | initiation(); /* upsilon sigma */ | |
| 2001/0728 | cmd(0x02, 0x04+0x01); /* reset CSN on all cards and reset logical devices */ delay(1); /* delay after resetting cards */ | |
| 2001/0801/sys/src/9/port/devpnp.c:253,259 – 2001/0809/sys/src/9/port/devpnp.c:267,273 | ||
| 2001/0728 | break; if(c == nil) { csn = newcsn(); | |
| 2001/0809 | c = findcsn(csn, 1, 0); | |
| 2001/0728 | c->id1 = id1; c->id2 = id2; } | |
| 2001/0801/sys/src/9/port/devpnp.c:269,277 – 2001/0809/sys/src/9/port/devpnp.c:283,293 | ||
| 2001/0728 | 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 */ | |
| 2001/0809 | if(pnp.cards != 0) { pnp.rddata = rddata; return 1; } return 0; | |
| 2001/0728 | } static void | |
| 2001/0801/sys/src/9/port/devpnp.c:311,317 – 2001/0809/sys/src/9/port/devpnp.c:327,333 | ||
| 2001/0731 | p = nil; else | |
| 2001/0728 | goto bad; | |
| 2001/0809 | c = findcsn(csn, 1, 0); | |
| 2001/0728 | c->id1 = id1; c->id2 = id2; | |
| 2001/0731 | c->cfgstr = p; | |
| 2001/0801/sys/src/9/port/devpnp.c:323,340 – 2001/0809/sys/src/9/port/devpnp.c:339,355 | ||
| 2001/0801 | csngen(Chan *c, int t, int csn, Card *cp, Dir *dp) | |
| 2001/0728 | { Qid q; | |
| 2001/0801 |
| |
| 2001/0728 | switch(t) { case Qcsnctl: q = (Qid){QID(csn, Qcsnctl), 0, 0}; | |
| 2001/0809 | sprint(up->genbuf, "csn%dctl", csn); devdir(c, q, up->genbuf, 0, eve, 0664, dp); | |
| 2001/0728 | return 1; case Qcsnraw: q = (Qid){QID(csn, Qcsnraw), 0, 0}; | |
| 2001/0809 | sprint(up->genbuf, "csn%draw", csn); devdir(c, q, up->genbuf, cp->ncfg, eve, 0444, dp); | |
| 2001/0728 | return 1; } return -1; | |
| 2001/0801/sys/src/9/port/devpnp.c:344,360 – 2001/0809/sys/src/9/port/devpnp.c:359,374 | ||
| 2001/0801 | pcigen(Chan *c, int t, int tbdf, Dir *dp) { Qid q; | |
| 2001/0809 | sprint(up->genbuf, "%d.%d.%dctl", BUSBNO(tbdf), BUSDNO(tbdf), BUSFNO(tbdf)); devdir(c, q, up->genbuf, 0, eve, 0444, dp); | |
| 2001/0801 | return 1; case Qpciraw: | |
| 2001/0809 | sprint(up->genbuf, "%d.%d.%draw", BUSBNO(tbdf), BUSDNO(tbdf), BUSFNO(tbdf)); devdir(c, q, up->genbuf, 128, eve, 0444, dp); | |
| 2001/0801 | return 1; } return -1; | |
| 2001/0801/sys/src/9/port/devpnp.c:367,380 – 2001/0809/sys/src/9/port/devpnp.c:381,393 | ||
| 2001/0728 | Card *cp; | |
| 2001/0801 | Pcidev *p; int csn, tbdf; | |
| 2001/0728 | switch(TYPE(c->qid)){ case Qtopdir: if(s == DEVDOTDOT){ q = (Qid){QID(0, Qtopdir), 0, QTDIR}; | |
| 2001/0809 | sprint(up->genbuf, "#%C", pnpdevtab.dc); devdir(c, q, up->genbuf, 0, eve, 0555, dp); | |
| 2001/0728 | return 1; } return devgen(c, nil, topdir, nelem(topdir), s, dp); | |
| 2001/0801/sys/src/9/port/devpnp.c:381,400 – 2001/0809/sys/src/9/port/devpnp.c:394,413 | ||
| 2001/0728 | case Qpnpdir: if(s == DEVDOTDOT){ q = (Qid){QID(0, Qtopdir), 0, QTDIR}; | |
| 2001/0809 | sprint(up->genbuf, "#%C", pnpdevtab.dc); devdir(c, q, up->genbuf, 0, eve, 0555, dp); | |
| 2001/0728 | return 1; } | |
| 2001/0731 | if(s < nelem(pnpdir)-1) | |
| 2001/0728 | return devgen(c, nil, pnpdir, nelem(pnpdir), s, dp); | |
| 2001/0731 | s -= nelem(pnpdir)-1; | |
| 2001/0728 |
| |
| 2001/0809 | qlock(&pnp); | |
| 2001/0728 | cp = pnp.cards; while(s >= 2 && cp != nil) { s -= 2; cp = cp->next; } | |
| 2001/0809 | qunlock(&pnp); | |
| 2001/0728 | if(cp == nil) return -1; | |
| 2001/0801 | return csngen(c, s+Qcsnctl, cp->csn, cp, dp); | |
| 2001/0801/sys/src/9/port/devpnp.c:403,411 – 2001/0809/sys/src/9/port/devpnp.c:416,422 | ||
| 2001/0728 | case Qcsnctl: case Qcsnraw: csn = CSN(c->qid); | |
| 2001/0809 | cp = findcsn(csn, 0, 1); | |
| 2001/0728 | if(cp == nil) return -1; | |
| 2001/0801 | return csngen(c, TYPE(c->qid), csn, cp, dp); | |
| 2001/0801/sys/src/9/port/devpnp.c:412,419 – 2001/0809/sys/src/9/port/devpnp.c:423,430 | ||
| 2001/0801 | case Qpcidir: if(s == DEVDOTDOT){ q = (Qid){QID(0, Qtopdir), 0, QTDIR}; | |
| 2001/0809 | sprint(up->genbuf, "#%C", pnpdevtab.dc); devdir(c, q, up->genbuf, 0, eve, 0555, dp); | |
| 2001/0801 | return 1; } p = pcimatch(nil, 0, 0); | |
| 2001/0801/sys/src/9/port/devpnp.c:477,483 – 2001/0809/sys/src/9/port/devpnp.c:488,494 | ||
| 2001/0728 | Card *cp; | |
| 2001/0801 | Pcidev *p; int csn, i, tbdf; | |
| 2001/0809 | char *a = va; | |
| 2001/0728 | switch(TYPE(c->qid)){ case Qtopdir: | |
| 2001/0801/sys/src/9/port/devpnp.c:486,505 – 2001/0809/sys/src/9/port/devpnp.c:497,514 | ||
| 2001/0728 | return devdirread(c, a, n, (Dirtab *)0, 0L, pnpgen); case Qpnpctl: if(pnp.rddata > 0) | |
| 2001/0809 | sprint(up->genbuf, "enabled 0x%x\n", pnp.rddata); | |
| 2001/0728 | else | |
| 2001/0809 | sprint(up->genbuf, "disabled\n"); return readstr(offset, a, n, up->genbuf); | |
| 2001/0728 | case Qcsnraw: csn = CSN(c->qid); | |
| 2001/0809 | cp = findcsn(csn, 0, 1); | |
| 2001/0728 | if(cp == nil) error(Egreg); if(offset+n > cp->ncfg) n = cp->ncfg - offset; | |
| 2001/0809 | qlock(&pnp); | |
| 2001/0728 | initiation(); cmd(0x03, csn); /* Wake up the card */ for (i = 0; i < offset+9; i++) /* 9 == skip serial + csum */ | |
| 2001/0801/sys/src/9/port/devpnp.c:508,532 – 2001/0809/sys/src/9/port/devpnp.c:517,539 | ||
| 2001/0728 | 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 */ | |
| 2001/0809 | qunlock(&pnp); | |
| 2001/0728 | break; case Qcsnctl: csn = CSN(c->qid); | |
| 2001/0809 | cp = findcsn(csn, 0, 1); | |
| 2001/0728 | if(cp == nil) error(Egreg); | |
| 2001/0809 | sprint(up->genbuf, "%s\n", serial(cp->id1, cp->id2)); return readstr(offset, a, n, up->genbuf); | |
| 2001/0801 | case Qpcictl: tbdf = MKBUS(BusPCI, 0, 0, 0)|BUSBDF((ulong)c->qid.path); p = pcimatchtbdf(tbdf); if(p == nil) error(Egreg); | |
| 2001/0809 | sprint(up->genbuf, "class %.2x subclass %.2x piclass %.2x vid %.4x did %.4x intl %d\n", | |
| 2001/0801 | p->ccrb, p->ccru, p->ccrp, p->vid, p->did, p->intl); | |
| 2001/0809 | return readstr(offset, a, n, up->genbuf); | |
| 2001/0801 | case Qpciraw: tbdf = MKBUS(BusPCI, 0, 0, 0)|BUSBDF((ulong)c->qid.path); p = pcimatchtbdf(tbdf); | |
| 2001/0801/sys/src/9/port/devpnp.c:558,565 – 2001/0809/sys/src/9/port/devpnp.c:565,580 | ||
| 2001/0731 | port = strtoul(buf+5, 0, 0); | |
| 2001/0728 | if(port < 0x203 || port > 0x3ff) error("bad value for rddata port"); | |
| 2001/0809 | qlock(&pnp); if(waserror()) { qunlock(&pnp); nexterror(); } if(pnp.rddata > 0) error("pnp port already set"); | |
| 2001/0731 | if(!pnpscan(port, 0)) | |
| 2001/0728 | error("no cards found"); | |
| 2001/0809 | qunlock(&pnp); | |
| 2001/0728 | } else if(strncmp(buf, "debug ", 6) == 0) pnp.debug = strtoul(buf+6, 0, 0); | |
| 2001/0801/sys/src/9/port/devpnp.c:568,576 – 2001/0809/sys/src/9/port/devpnp.c:583,589 | ||
| 2001/0728 | break; | |
| 2001/0731 | case Qcsnctl: csn = CSN(c->qid); | |
| 2001/0809 | cp = findcsn(csn, 0, 1); | |
| 2001/0731 | if(cp == nil) error(Egreg); if(!wrconfig(cp, buf)) | |
| 2001/0809/sys/src/9/port/devpnp.c:624,629 – 2002/0109/sys/src/9/port/devpnp.c:624,630 (short | long) | ||
|
Add devshutdown.
rsc Fri Mar 4 12:44:25 2005 | ||
| 2001/0728 | pnpreset, devinit, | |
| 2002/0109 | devshutdown, | |
| 2001/0728 | pnpattach, pnpwalk, pnpstat, | |
| 2002/0109/sys/src/9/port/devpnp.c:485,494 – 2002/0414/sys/src/9/port/devpnp.c:485,496 (short | long) | ||
| 2001/0728 | static long pnpread(Chan *c, void *va, long n, vlong offset) { | |
| 2002/0414 | ulong x; | |
| 2001/0728 | Card *cp; | |
| 2001/0801 | Pcidev *p; | |
| 2002/0414 | char buf[256], *ebuf, *w; | |
| 2001/0809 | char *a = va; | |
| 2002/0414 | int csn, i, tbdf, r; | |
| 2001/0728 | switch(TYPE(c->qid)){ case Qtopdir: | |
| 2002/0109/sys/src/9/port/devpnp.c:511,519 – 2002/0414/sys/src/9/port/devpnp.c:513,521 | ||
| 2001/0809 | qlock(&pnp); | |
| 2001/0728 | initiation(); cmd(0x03, csn); /* Wake up the card */ | |
| 2002/0414 | for(i = 0; i < offset+9; i++) /* 9 == skip serial + csum */ | |
| 2001/0728 | getresbyte(pnp.rddata); | |
| 2002/0414 | for(i = 0; i < n; i++) | |
| 2001/0728 | 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 */ | |
| 2002/0109/sys/src/9/port/devpnp.c:531,545 – 2002/0414/sys/src/9/port/devpnp.c:533,571 | ||
| 2001/0801 | p = pcimatchtbdf(tbdf); if(p == nil) error(Egreg); | |
| 2001/0809 |
| |
| 2002/0414 | ebuf = buf+sizeof buf-1; /* -1 for newline */ w = seprint(buf, ebuf, "%.2x.%.2x.%.2x %.4x/%.4x %3d", | |
| 2001/0801 | p->ccrb, p->ccru, p->ccrp, p->vid, p->did, p->intl); | |
| 2001/0809 |
| |
| 2002/0414 | 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); | |
| 2001/0801 | case Qpciraw: tbdf = MKBUS(BusPCI, 0, 0, 0)|BUSBDF((ulong)c->qid.path); p = pcimatchtbdf(tbdf); if(p == nil) error(Egreg); | |
| 2002/0414 | 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; | |
| 2001/0728 | default: error(Egreg); } | |
| 2002/0414/sys/src/9/port/devpnp.c:549,558 – 2002/0416/sys/src/9/port/devpnp.c:549,558 (short | long) | ||
| 2001/0801 | p = pcimatchtbdf(tbdf); if(p == nil) error(Egreg); | |
| 2002/0414 |
| |
| 2002/0416 | if(offset > 256) | |
| 2002/0414 | return 0; | |
| 2002/0416 | if(n+offset > 256) n = 256-offset; | |
| 2002/0414 | if(offset%4) error(Ebadarg); r = offset; | |
| 2002/0416/sys/src/9/port/devpnp.c:3,13 – 2002/0427/sys/src/9/port/devpnp.c:3,12 (short | long) | ||
| 2001/0809 | * * TODO * - implement PNP card configuration (setting io bases etc) | |
| 2002/0427 | * - write user program to drive PNP configuration... * - extend PCI raw access to configuration space (writes, byte/short access?) | |
| 2001/0809 | * - implement PCI access to memory/io space/BIOS ROM | |
| 2002/0427 | * - use c->aux instead of performing lookup on each read/write? | |
| 2001/0809 | */ | |
| 2001/0728 | #include "u.h" #include "../port/lib.h" | |
| 2002/0416/sys/src/9/port/devpnp.c:601,606 – 2002/0427/sys/src/9/port/devpnp.c:600,606 | ||
| 2001/0731 | if(!pnpscan(port, 0)) | |
| 2001/0728 | error("no cards found"); | |
| 2001/0809 | qunlock(&pnp); | |
| 2002/0427 | poperror(); | |
| 2001/0728 | } else if(strncmp(buf, "debug ", 6) == 0) pnp.debug = strtoul(buf+6, 0, 0); | |
| 2002/0416/sys/src/9/port/devpnp.c:624,645 – 2002/0427/sys/src/9/port/devpnp.c:624,631 | ||
| 2001/0731 | static int wrconfig(Card *c, char *cmd) { | |
| 2002/0427 | /* This should implement setting of I/O bases, etc */ USED(c, cmd); | |
| 2001/0731 | return 1; } | |
| 2002/0427/sys/src/9/port/devpnp.c:127,147 – 2003/0406/sys/src/9/port/devpnp.c:127,147 (short | long) | ||
| 2001/0728 | outb(Address, 0x01); /* point to serial isolation register */ delay(1); csum = 0x6a; | |
| 2003/0406 | for(i = 0; i < 64; i++){ | |
| 2001/0728 | bit = readbit(rddata); csum = (csum>>1) | (((csum&1) ^ ((csum>>1)&1) ^ bit)<<7); p = &id[i>>3]; *p = (*p>>1) | (bit<<7); } | |
| 2003/0406 | for(; i < 72; i++){ | |
| 2001/0728 | 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]; | |
| 2003/0406 | if(*id1 == 0) | |
| 2001/0728 | return 0; | |
| 2003/0406 | if(id[8] != csum) | |
| 2001/0728 | DPRINT("pnp: bad checksum id1 %lux id2 %lux csum %x != %x\n", *id1, *id2, csum, id[8]); /**/ return id[8] == csum; } | |