| plan 9 kernel history: overview | file list | diff list |
1995/0117/pc/devi82365.c (diff list | history)
| 1994/1209/sys/src/9/pc/devi82365.c:316,322 – 1994/1210/sys/src/9/pc/devi82365.c:316,324 (short | long) | ||
| 1994/1209 | /* grab ISA address space for memory maps */ for(i = 0; i < Nmap; i++) | |
| 1994/1210 | pp->mmap[i].isa = getisa(0, Mchunk, BY2PG); if(pp->mmap[i].isa == 0) panic("getmap"); | |
| 1994/1209 | } /* look for a map that starts in the right place */ | |
| 1994/1210/sys/src/9/pc/devi82365.c:845,853 – 1994/1211/sys/src/9/pc/devi82365.c:845,850 (short | long) | ||
| 1994/1209 | static int readc(Slot *pp, uchar *x) { | |
| 1994/1211/sys/src/9/pc/devi82365.c:264,274 – 1995/0107/sys/src/9/pc/devi82365.c:264,277 (short | long) | ||
| 1994/1209 | static void slotdis(Slot *pp) { | |
| 1995/0107 | int x; | |
| 1994/1209 | /* disable the windows into the card */ wrreg(pp, Rwe, 0); /* disable the card */ | |
| 1995/0107 | x = vcode(5) | (vcode(5)<<2); wrreg(pp, Rpc, x|Fautopower); | |
| 1994/1209 | pp->enabled = 0; } | |
| 1995/0107/sys/src/9/pc/devi82365.c:712,717 – 1995/0108/sys/src/9/pc/devi82365.c:712,723 (short | long) | ||
| 1994/1209 | return n; } | |
| 1995/0108 | Block* i82365bread(Chan *c, long n, ulong offset) { return devbread(c, n, offset); } | |
| 1994/1209 | long pcmwrite(int dev, int attr, void *a, long n, ulong offset) { | |
| 1995/0107/sys/src/9/pc/devi82365.c:762,767 – 1995/0108/sys/src/9/pc/devi82365.c:768,779 | ||
| 1994/1209 | error(Ebadusefd); } return n; | |
| 1995/0108 | } long i82365bwrite(Chan *c, Block *bp, ulong offset) { return devbwrite(c, bp, offset); | |
| 1994/1209 | } /* | |
| 1995/0108/sys/src/9/pc/devi82365.c:151,156 – 1995/0111/sys/src/9/pc/devi82365.c:151,157 (short | long) | ||
| 1994/1209 | uchar busy; /* cis info */ | |
| 1995/0111 | uchar verstr[512]; /* version string */ | |
| 1994/1209 | uchar vpp1; uchar vpp2; uchar bit16; | |
| 1995/0108/sys/src/9/pc/devi82365.c:379,385 – 1995/0111/sys/src/9/pc/devi82365.c:380,386 | ||
| 1994/1209 | qunlock(pp->cp); } | |
| 1995/0111 | char* | |
| 1994/1209 | pcmspecial(int dev) { Slot *pp; | |
| 1995/0108/sys/src/9/pc/devi82365.c:386,402 – 1995/0111/sys/src/9/pc/devi82365.c:387,403 | ||
| 1994/1209 | i82365reset(); if(dev >= nslot) | |
| 1995/0111 | return 0; | |
| 1994/1209 | pp = slot + dev; if(pp->special) | |
| 1995/0111 | return 0; | |
| 1994/1209 | increfp(pp); if(!pp->occupied){ decrefp(pp); | |
| 1995/0111 | return 0; | |
| 1994/1209 | } pp->special = 1; | |
| 1995/0111 | return pp->verstr; | |
| 1994/1209 | } void | |
| 1995/0108/sys/src/9/pc/devi82365.c:850,858 – 1995/0111/sys/src/9/pc/devi82365.c:851,861 | ||
| 1994/1209 | */ static void tcfig(Slot*, int); static void tentry(Slot*, int); | |
| 1995/0111 | static void tvers1(Slot*, int); | |
| 1994/1209 | static void (*parse[256])(Slot*, int) = { | |
| 1995/0111 | [0x15] tvers1, | |
| 1994/1209 | [0x1A] tcfig, [0x1B] tentry, }; | |
| 1995/0108/sys/src/9/pc/devi82365.c:1158,1161 – 1995/0111/sys/src/9/pc/devi82365.c:1161,1187 | ||
| 1994/1209 | break; } pp->configed++; | |
| 1995/0111 | } void tvers1(Slot *pp, int ttype) { uchar c, major, minor; int i; USED(ttype); if(readc(pp, &major) != 1) return; if(readc(pp, &minor) != 1) return; for(i = 0; i < sizeof(pp->verstr)-1; i++){ if(readc(&c) != 1) return; if(c == 0) c = '\n'; if(c == 0xff) break; pp->verstr[i] = c; } pp->verstr[i] = 0; | |
| 1994/1209 | } | |
| 1995/0111/sys/src/9/pc/devi82365.c:1059,1081 – 1995/0114/sys/src/9/pc/devi82365.c:1059,1079 (short | long) | ||
| 1994/1209 | int i; ulong address, len; | |
| 1995/0114 | if(readc(pp, &c) != 1) return; | |
| 1994/1209 |
| |
| 1995/0114 | pp->nioregs = 1<<(c&0x1f); pp->bit16 = ((c>>5)&3) >= 2; if((c & 0x80) == 0) return; | |
| 1994/1209 |
| |
| 1995/0114 | if(readc(pp, &c) != 1) return; | |
| 1994/1209 |
| |
| 1995/0114 | for(i = (c&0xf)+1; i; i--){ address = getlong(pp, (c>>4)&0x3); len = getlong(pp, (c>>6)&0x3); USED(address, len); | |
| 1994/1209 | } } | |
| 1995/0114/sys/src/9/pc/devi82365.c:151,157 – 1995/0117/sys/src/9/pc/devi82365.c:151,157 (short | long) | ||
| 1994/1209 | uchar busy; /* cis info */ | |
| 1995/0111 |
| |
| 1995/0117 | char verstr[512]; /* version string */ | |
| 1994/1209 | uchar vpp1; uchar vpp2; uchar bit16; | |
| 1995/0114/sys/src/9/pc/devi82365.c:1173,1179 – 1995/0117/sys/src/9/pc/devi82365.c:1173,1179 | ||
| 1995/0111 | if(readc(pp, &minor) != 1) return; for(i = 0; i < sizeof(pp->verstr)-1; i++){ | |
| 1995/0117 | if(readc(pp, &c) != 1) | |
| 1995/0111 | return; if(c == 0) c = '\n'; | |
| 1995/0117/sys/src/9/pc/devi82365.c:815,821 – 1995/0118/sys/src/9/pc/devi82365.c:815,821 (short | long) | ||
| 1994/1209 | /* enable io port map 0 */ if(isa->port == 0) | |
| 1995/0118 | isa->port = 0x300; | |
| 1994/1209 | we = rdreg(pp, Rwe); wrreg(pp, Riobtm0lo, isa->port); wrreg(pp, Riobtm0hi, isa->port>>8); | |
| 1995/0118/sys/src/9/pc/devi82365.c:163,168 – 1995/0131/sys/src/9/pc/devi82365.c:163,171 (short | long) | ||
| 1994/1209 | ulong caddr; /* relative address of config registers */ uchar *cisbase; /* base of mapped in attribute space */ uchar *cispos; /* current position scanning cis */ | |
| 1995/0131 | ulong maxwait; ulong readywait; ulong otherwait; | |
| 1994/1209 | /* memory maps */ int time; | |
| 1995/0118/sys/src/9/pc/devi82365.c:1043,1055 – 1995/0131/sys/src/9/pc/devi82365.c:1046,1058 | ||
| 1994/1209 | return; i = c&0x3; if(i != 3) | |
| 1995/0131 | pp->maxwait = ttiming(pp, i); /* max wait */ | |
| 1994/1209 | i = (c>>2)&0x7; if(i != 7) | |
| 1995/0131 | pp->readywait = ttiming(pp, i); /* max ready/busy wait */ | |
| 1994/1209 | i = (c>>5)&0x7; if(i != 7) | |
| 1995/0131 | pp->otherwait = ttiming(pp, i); /* reserved wait */ | |
| 1994/1209 | } void | |
| 1995/0131/sys/src/9/pc/devi82365.c:117,123 – 1995/0209/sys/src/9/pc/devi82365.c:117,122 (short | long) | ||
| 1994/1209 | }; struct I82365 { | |
| 1995/0131/sys/src/9/pc/devi82365.c:130,135 – 1995/0209/sys/src/9/pc/devi82365.c:129,135 | ||
| 1994/1209 | /* a Slot slot */ struct Slot { | |
| 1995/0209 | Lock; | |
| 1994/1209 | int ref; I82365 *cp; /* controller for this slot */ | |
| 1995/0131/sys/src/9/pc/devi82365.c:168,173 – 1995/0209/sys/src/9/pc/devi82365.c:168,174 | ||
| 1995/0131 | ulong otherwait; | |
| 1994/1209 | /* memory maps */ | |
| 1995/0209 | QLock mlock; /* lock down the maps */ | |
| 1994/1209 | int time; PCMmap mmap[Nmap]; }; | |
| 1995/0131/sys/src/9/pc/devi82365.c:322,331 – 1995/0209/sys/src/9/pc/devi82365.c:323,333 | ||
| 1994/1209 | pp->gotmem = 1; /* grab ISA address space for memory maps */ | |
| 1995/0209 | for(i = 0; i < Nmap; i++){ | |
| 1994/1210 | pp->mmap[i].isa = getisa(0, Mchunk, BY2PG); | |
| 1995/0209 | if(pp->mmap[i].isa == 0) panic("getmap"); } | |
| 1994/1209 | } /* look for a map that starts in the right place */ | |
| 1995/0131/sys/src/9/pc/devi82365.c:368,386 – 1995/0209/sys/src/9/pc/devi82365.c:370,388 | ||
| 1994/1209 | static void increfp(Slot *pp) { | |
| 1995/0209 | lock(pp); | |
| 1994/1209 | if(pp->ref++ == 0) slotena(pp); | |
| 1995/0209 | unlock(pp); | |
| 1994/1209 | } static void decrefp(Slot *pp) { | |
| 1995/0209 | lock(pp); | |
| 1994/1209 | if(pp->ref-- == 1) slotdis(pp); | |
| 1995/0209 | unlock(pp); | |
| 1994/1209 | } | |
| 1995/0111 | char* | |
| 1995/0131/sys/src/9/pc/devi82365.c:653,659 – 1995/0209/sys/src/9/pc/devi82365.c:655,660 | ||
| 1994/1209 | pp = slot + dev; if(pp->memlen < offset) return 0; | |
| 1995/0131/sys/src/9/pc/devi82365.c:670,676 – 1995/0209/sys/src/9/pc/devi82365.c:671,676 | ||
| 1994/1209 | offset += i; ac += i; } | |
| 1995/0131/sys/src/9/pc/devi82365.c:687,693 – 1995/0209/sys/src/9/pc/devi82365.c:687,697 | ||
| 1994/1209 | return devdirread(c, a, n, 0, 0, pcmgen); case Qmem: case Qattr: | |
| 1995/0209 | qlock(&pp->mlock); | |
| 1994/1209 | n = pcmread(DEV(c), p==Qattr, a, n, offset); | |
| 1995/0209 | qunlock(&pp->mlock); if(n < 0) error(Eio); | |
| 1994/1209 | break; case Qctl: cp = buf; | |
| 1995/0131/sys/src/9/pc/devi82365.c:734,740 – 1995/0209/sys/src/9/pc/devi82365.c:738,743 | ||
| 1994/1209 | pp = slot + dev; if(pp->memlen < offset) return 0; | |
| 1995/0131/sys/src/9/pc/devi82365.c:749,755 – 1995/0209/sys/src/9/pc/devi82365.c:752,757 | ||
| 1994/1209 | offset += i; ac += i; } | |
| 1995/0131/sys/src/9/pc/devi82365.c:766,772 – 1995/0209/sys/src/9/pc/devi82365.c:768,778 | ||
| 1994/1209 | pp = slot + DEV(c); if(pp->occupied == 0 || pp->enabled == 0) error(Eio); | |
| 1995/0209 | qlock(&pp->mlock); | |
| 1994/1209 | n = pcmwrite(pp->dev, p == Qattr, a, n, offset); | |
| 1995/0209 | qunlock(&pp->mlock); if(n < 0) error(Eio); | |
| 1994/1209 | break; default: error(Ebadusefd); | |
| 1995/0209/sys/src/9/pc/devi82365.c:184,196 – 1995/0215/sys/src/9/pc/devi82365.c:184,200 (short | long) | ||
| 1994/1209 | static uchar rdreg(Slot *pp, int index) { | |
| 1995/0215 | microdelay(10); | |
| 1994/1209 | outb(pp->cp->xreg, pp->base + index); | |
| 1995/0215 | microdelay(10); | |
| 1994/1209 | return inb(pp->cp->dreg); } static void wrreg(Slot *pp, int index, uchar val) { | |
| 1995/0215 | microdelay(10); | |
| 1994/1209 | outb(pp->cp->xreg, pp->base + index); | |
| 1995/0215 | microdelay(10); | |
| 1994/1209 | outb(pp->cp->dreg, val); } | |
| 1995/0209/sys/src/9/pc/devi82365.c:687,692 – 1995/0215/sys/src/9/pc/devi82365.c:691,697 | ||
| 1994/1209 | return devdirread(c, a, n, 0, 0, pcmgen); case Qmem: case Qattr: | |
| 1995/0215 | pp = slot + DEV(c); | |
| 1995/0209 | qlock(&pp->mlock); | |
| 1994/1209 | n = pcmread(DEV(c), p==Qattr, a, n, offset); | |
| 1995/0209 | qunlock(&pp->mlock); | |
| 1995/0215/sys/src/9/pc/devi82365.c:15,21 – 1995/0222/sys/src/9/pc/devi82365.c:15,21 (short | long) | ||
| 1994/1209 | */ /* | |
| 1995/0222 | * Intel 82365SL PCIC controller for the PCMCIA or | |
| 1994/1209 | * Cirrus Logic PD6710/PD6720 which is mostly register compatible */ enum | |
| 1995/0215/sys/src/9/pc/devi82365.c:64,69 – 1995/0222/sys/src/9/pc/devi82365.c:64,70 | ||
| 1994/1209 | Rfifo= 0x17, /* fifo control */ Fflush= (1<<7), /* flush fifo */ Rmisc2= 0x1E, /* misc control 2 */ | |
| 1995/0222 | Flowpow= (1<<1), /* low power mode */ | |
| 1994/1209 | Rchipinfo= 0x1F, /* chip information */ Ratactl= 0x26, /* ATA control */ | |
| 1995/0215/sys/src/9/pc/devi82365.c:72,83 – 1995/0222/sys/src/9/pc/devi82365.c:73,85 | ||
| 1994/1209 | */ Mbtmlo= 0x0, /* System mem addr mapping start low byte */ Mbtmhi= 0x1, /* System mem addr mapping start high byte */ | |
| 1995/0222 | F16bit= (1<<7), /* 16-bit wide data path */ | |
| 1994/1209 | Mtoplo= 0x2, /* System mem addr mapping stop low byte */ Mtophi= 0x3, /* System mem addr mapping stop high byte */ | |
| 1995/0222 | Ftimer1= (1<<6), /* timer set 1 */ | |
| 1994/1209 | Mofflo= 0x4, /* Card memory offset address low byte */ Moffhi= 0x5, /* Card memory offset address high byte */ | |
| 1995/0222 | Fregactive= (1<<6), /* attribute memory */ | |
| 1994/1209 | Mbits= 13, /* msb of Mchunk */ Mchunk= 1<<Mbits, /* logical mapping granularity */ | |
| 1995/0215/sys/src/9/pc/devi82365.c:135,141 – 1995/0222/sys/src/9/pc/devi82365.c:137,143 | ||
| 1994/1209 | I82365 *cp; /* controller for this slot */ long memlen; /* memory length */ uchar base; /* index register base */ | |
| 1995/0222 | uchar slotno; /* slot number */ | |
| 1994/1209 | /* status */ uchar special; /* in use for a special device */ | |
| 1995/0215/sys/src/9/pc/devi82365.c:147,153 – 1995/0222/sys/src/9/pc/devi82365.c:149,154 | ||
| 1994/1209 | uchar powered; uchar configed; uchar enabled; | |
| 1995/0215/sys/src/9/pc/devi82365.c:161,168 – 1995/0222/sys/src/9/pc/devi82365.c:162,169 | ||
| 1994/1209 | uchar def; /* default configuration */ ushort irqs; /* valid interrupt levels */ ulong caddr; /* relative address of config registers */ | |
| 1995/0222 | int cispos; /* current position scanning cis */ uchar *cisbase; | |
| 1995/0131 | ulong maxwait; ulong readywait; ulong otherwait; | |
| 1995/0215/sys/src/9/pc/devi82365.c:177,182 – 1995/0222/sys/src/9/pc/devi82365.c:178,184 | ||
| 1994/1209 | static nslot; static void cisread(Slot*); | |
| 1995/0222 | static void i82365intr(Ureg*, void*); | |
| 1994/1209 | /* * reading and writing card registers | |
| 1995/0215/sys/src/9/pc/devi82365.c:184,200 – 1995/0222/sys/src/9/pc/devi82365.c:186,198 | ||
| 1994/1209 | static uchar rdreg(Slot *pp, int index) { | |
| 1995/0215 |
| |
| 1994/1209 | outb(pp->cp->xreg, pp->base + index); | |
| 1995/0215 |
| |
| 1994/1209 | return inb(pp->cp->dreg); } static void wrreg(Slot *pp, int index, uchar val) { | |
| 1995/0215 |
| |
| 1994/1209 | outb(pp->cp->xreg, pp->base + index); | |
| 1995/0215 |
| |
| 1994/1209 | outb(pp->cp->dreg, val); } | |
| 1995/0215/sys/src/9/pc/devi82365.c:212,220 – 1995/0222/sys/src/9/pc/devi82365.c:210,215 | ||
| 1994/1209 | pp->battery = (isr & 3) == 3; pp->wrprot = isr & (1<<4); pp->busy = isr & (1<<5); | |
| 1995/0215/sys/src/9/pc/devi82365.c:236,270 – 1995/0222/sys/src/9/pc/devi82365.c:231,260 | ||
| 1994/1209 | static void slotena(Slot *pp) { | |
| 1995/0222 | /* enable the card */ wrreg(pp, Rpc, vcode(5)|Fautopower|Foutena|Fcardena); delay(300); /* give the card time to sit up and take notice */ wrreg(pp, Rigc, 0); delay(100); wrreg(pp, Rigc, Fnotreset); delay(100); wrreg(pp, Rcscic, ((PCMCIAvec-Int0vec)<<4) | Fchangeena); | |
| 1994/1209 |
| |
| 1995/0222 | if(pp->configed) wrreg(pp, Rpc, vcode(pp->vpp1)|Fautopower|Foutena|Fcardena); | |
| 1994/1209 |
| |
| 1995/0222 | } else wrreg(pp, Rpc, vcode(5)|Fautopower); pp->enabled = 1; | |
| 1994/1209 | } /* | |
| 1995/0215/sys/src/9/pc/devi82365.c:273,286 – 1995/0222/sys/src/9/pc/devi82365.c:263,271 | ||
| 1994/1209 | static void slotdis(Slot *pp) { | |
| 1995/0107 |
| |
| 1994/1209 |
| |
| 1995/0107 |
| |
| 1995/0222 | wrreg(pp, Rmisc2, Flowpow); /* low power mode */ wrreg(pp, Rpc, vcode(5)|Fautopower); /* turn off card */ wrreg(pp, Rwe, 0); /* no windows */ | |
| 1994/1209 | pp->enabled = 0; } | |
| 1995/0215/sys/src/9/pc/devi82365.c:288,312 – 1995/0222/sys/src/9/pc/devi82365.c:273,296 | ||
| 1994/1209 | * status change interrupt */ static void | |
| 1995/0222 | i82365intr(Ureg *ur, void *a) | |
| 1994/1209 | { | |
| 1995/0222 | uchar csc, was; | |
| 1994/1209 | Slot *pp; | |
| 1995/0222 | USED(ur,a); if(slot == 0) return; | |
| 1994/1209 | for(pp = slot; pp < lastslot; pp++){ csc = rdreg(pp, Rcsc); | |
| 1995/0222 | was = pp->occupied; | |
| 1994/1209 | slotinfo(pp); | |
| 1995/0222 | if(csc & (1<<3) && was != pp->occupied){ if(pp->occupied) print("slot%d card inserted\n", pp->slotno); else { print("slot%d card removed\n", pp->slotno); | |
| 1994/1209 | slotdis(pp); } } | |
| 1995/0215/sys/src/9/pc/devi82365.c:361,367 – 1995/0222/sys/src/9/pc/devi82365.c:345,351 | ||
| 1994/1209 | wrreg(pp, MAP(i, Mbtmlo), m->isa>>12); wrreg(pp, MAP(i, Mbtmhi), (m->isa>>(12+8)) | F16bit); wrreg(pp, MAP(i, Mtoplo), (m->isa+Mchunk-1)>>12); | |
| 1995/0222 | wrreg(pp, MAP(i, Mtophi), ((m->isa+Mchunk-1)>>(12+8)) | Ftimer1); | |
| 1994/1209 | offset -= m->isa; offset &= (1<<25)-1; offset >>= 12; | |
| 1995/0215/sys/src/9/pc/devi82365.c:389,422 – 1995/0222/sys/src/9/pc/devi82365.c:373,413 | ||
| 1995/0209 | unlock(pp); | |
| 1994/1209 | } | |
| 1995/0111 |
| |
| 1994/1209 |
| |
| 1995/0222 | /* * look for a card whose version contains 'idstr' */ int pcmspecial(char *idstr, ISAConf *isa) | |
| 1994/1209 | { Slot *pp; | |
| 1995/0222 | extern char *strstr(char*, char*); | |
| 1994/1209 | i82365reset(); | |
| 1995/0111 |
| |
| 1994/1209 |
| |
| 1995/0111 |
| |
| 1994/1209 |
| |
| 1995/0222 | for(pp = slot; pp < lastslot; pp++){ if(pp->special) continue; /* already taken */ increfp(pp); if(pp->occupied) if(strstr(pp->verstr, idstr)) if(isa == 0 || pcmio(pp->slotno, isa) == 0){ pp->special = 1; return pp->slotno; } | |
| 1994/1209 | decrefp(pp); | |
| 1995/0111 |
| |
| 1994/1209 | } | |
| 1995/0111 |
| |
| 1995/0222 | return -1; | |
| 1994/1209 | } void | |
| 1995/0222 | pcmspecialclose(int slotno) | |
| 1994/1209 | { Slot *pp; | |
| 1995/0222 | if(slotno >= nslot) | |
| 1994/1209 | panic("pcmspecialclose"); | |
| 1995/0222 | pp = slot + slotno; | |
| 1994/1209 | pp->special = 0; decrefp(pp); } | |
| 1995/0215/sys/src/9/pc/devi82365.c:429,441 – 1995/0222/sys/src/9/pc/devi82365.c:420,433 | ||
| 1994/1209 | Qctl, }; | |
| 1995/0222 | #define SLOTNO(c) ((c->qid.path>>8)&0xff) #define TYPE(c) (c->qid.path&0xff) #define QID(s,t) (((s)<<8)|(t)) | |
| 1994/1209 | static int pcmgen(Chan *c, Dirtab *tab, int ntab, int i, Dir *dp) { | |
| 1995/0222 | int slotno; | |
| 1994/1209 | Qid qid; long len; Slot *pp; | |
| 1995/0215/sys/src/9/pc/devi82365.c:444,466 – 1995/0222/sys/src/9/pc/devi82365.c:436,458 | ||
| 1994/1209 | USED(tab, ntab); if(i>=3*nslot) return -1; | |
| 1995/0222 | slotno = i/3; pp = slot + slotno; | |
| 1994/1209 | len = 0; switch(i%3){ case 0: | |
| 1995/0222 | qid.path = QID(slotno, Qmem); sprint(name, "pcm%dmem", slotno); | |
| 1994/1209 | len = pp->memlen; break; case 1: | |
| 1995/0222 | qid.path = QID(slotno, Qattr); sprint(name, "pcm%dattr", slotno); | |
| 1994/1209 | len = pp->memlen; break; case 2: | |
| 1995/0222 | qid.path = QID(slotno, Qctl); sprint(name, "pcm%dctl", slotno); | |
| 1994/1209 | break; } qid.vers = 0; | |
| 1995/0215/sys/src/9/pc/devi82365.c:538,543 – 1995/0222/sys/src/9/pc/devi82365.c:530,537 | ||
| 1994/1209 | /* look for controllers */ i82386probe(0x3E0, 0x3E1, 0); i82386probe(0x3E0, 0x3E1, 1); | |
| 1995/0222 | i82386probe(0x3E2, 0x3E3, 0); i82386probe(0x3E2, 0x3E3, 1); | |
| 1994/1209 | for(i = 0; i < ncontroller; i++) nslot += controller[i]->nslot; slot = xalloc(nslot * sizeof(Slot)); | |
| 1995/0215/sys/src/9/pc/devi82365.c:547,560 – 1995/0222/sys/src/9/pc/devi82365.c:541,557 | ||
| 1994/1209 | for(i = 0; i < ncontroller; i++){ cp = controller[i]; for(j = 0; j < cp->nslot; j++){ | |
| 1995/0222 | lastslot->slotno = lastslot - slot; | |
| 1994/1209 | lastslot->memlen = 64*MB; lastslot->base = (cp->dev<<7) | (j<<6); lastslot->cp = cp; | |
| 1995/0222 | slotdis(lastslot); | |
| 1994/1209 | lastslot++; } } | |
| 1995/0222 | /* for card management interrupts */ setvec(PCMCIAvec, i82365intr, 0); | |
| 1994/1209 | } void | |
| 1995/0215/sys/src/9/pc/devi82365.c:593,599 – 1995/0222/sys/src/9/pc/devi82365.c:590,596 | ||
| 1994/1209 | if(omode != OREAD) error(Eperm); } else | |
| 1995/0222 | increfp(slot + SLOTNO(c)); | |
| 1994/1209 | c->mode = openmode(omode); c->flag |= COPEN; c->offset = 0; | |
| 1995/0215/sys/src/9/pc/devi82365.c:624,634 – 1995/0222/sys/src/9/pc/devi82365.c:621,639 | ||
| 1994/1209 | void i82365close(Chan *c) { | |
| 1995/0222 | if(c->flag & COPEN) if(c->qid.path != CHDIR) decrefp(slot+SLOTNO(c)); | |
| 1994/1209 | } | |
| 1995/0222 | /* a memmove using only bytes */ static void memmoveb(uchar *to, uchar *from, int n) { while(n-- > 0) *to++ = *from++; } | |
| 1994/1209 | /* a memmove using only shorts & bytes */ static void memmoves(uchar *to, uchar *from, int n) | |
| 1995/0215/sys/src/9/pc/devi82365.c:648,654 – 1995/0222/sys/src/9/pc/devi82365.c:653,659 | ||
| 1994/1209 | } long | |
| 1995/0222 | pcmread(int slotno, int attr, void *a, long n, ulong offset) | |
| 1994/1209 | { int i, len; PCMmap *m; | |
| 1995/0215/sys/src/9/pc/devi82365.c:656,662 – 1995/0222/sys/src/9/pc/devi82365.c:661,667 | ||
| 1994/1209 | uchar *ac; Slot *pp; | |
| 1995/0222 | pp = slot + slotno; | |
| 1994/1209 | if(pp->memlen < offset) return 0; ac = a; | |
| 1995/0215/sys/src/9/pc/devi82365.c:671,677 – 1995/0222/sys/src/9/pc/devi82365.c:676,682 | ||
| 1994/1209 | else i = len; ka = KZERO|(m->isa + (offset&(Mchunk-1))); | |
| 1995/0222 | memmoveb(ac, (void*)ka, i); | |
| 1994/1209 | offset += i; ac += i; } | |
| 1995/0215/sys/src/9/pc/devi82365.c:678,687 – 1995/0222/sys/src/9/pc/devi82365.c:683,698 | ||
| 1994/1209 | return n; } | |
| 1995/0222 | Block* i82365bread(Chan *c, long n, ulong offset) { return devbread(c, n, offset); } | |
| 1994/1209 | long i82365read(Chan *c, void *a, long n, ulong offset) { | |
| 1995/0222 | char *cp, buf[2048]; | |
| 1994/1209 | ulong p; Slot *pp; | |
| 1995/0215/sys/src/9/pc/devi82365.c:691,699 – 1995/0222/sys/src/9/pc/devi82365.c:702,710 | ||
| 1994/1209 | return devdirread(c, a, n, 0, 0, pcmgen); case Qmem: case Qattr: | |
| 1995/0215 |
| |
| 1995/0222 | pp = slot + SLOTNO(c); | |
| 1995/0209 | qlock(&pp->mlock); | |
| 1994/1209 |
| |
| 1995/0222 | n = pcmread(SLOTNO(c), p==Qattr, a, n, offset); | |
| 1995/0209 | qunlock(&pp->mlock); if(n < 0) error(Eio); | |
| 1995/0215/sys/src/9/pc/devi82365.c:700,706 – 1995/0222/sys/src/9/pc/devi82365.c:711,717 | ||
| 1994/1209 | break; case Qctl: cp = buf; | |
| 1995/0222 | pp = slot + SLOTNO(c); | |
| 1994/1209 | if(pp->occupied) cp += sprint(cp, "occupied\n"); if(pp->enabled) | |
| 1995/0215/sys/src/9/pc/devi82365.c:707,714 – 1995/0222/sys/src/9/pc/devi82365.c:718,723 | ||
| 1994/1209 | cp += sprint(cp, "enabled\n"); if(pp->powered) cp += sprint(cp, "powered\n"); | |
| 1995/0215/sys/src/9/pc/devi82365.c:716,721 – 1995/0222/sys/src/9/pc/devi82365.c:725,742 | ||
| 1994/1209 | if(pp->busy) cp += sprint(cp, "busy\n"); cp += sprint(cp, "battery lvl %d\n", pp->battery); | |
| 1995/0222 | { int i; cp += sprint(cp, "x %x d %x b %x\n", pp->cp->xreg, pp->cp->dreg, pp->base); for(i = 0; i < 0x40; i++){ cp += sprint(cp, "%2.2ux ", rdreg(pp, i)); if((i%8) == 7) cp += sprint(cp, "\n"); } if(i%8) cp += sprint(cp, "\n"); } | |
| 1994/1209 | *cp = 0; return readstr(offset, a, n, buf); default: | |
| 1995/0215/sys/src/9/pc/devi82365.c:725,734 – 1995/0222/sys/src/9/pc/devi82365.c:746,755 | ||
| 1994/1209 | return n; } | |
| 1995/0108 |
| |
| 1995/0222 | long i82365bwrite(Chan *c, Block *bp, ulong offset) | |
| 1995/0108 | { | |
| 1995/0222 | return devbwrite(c, bp, offset); | |
| 1995/0108 | } | |
| 1994/1209 | long | |
| 1995/0215/sys/src/9/pc/devi82365.c:753,759 – 1995/0222/sys/src/9/pc/devi82365.c:774,780 | ||
| 1994/1209 | else i = len; ka = KZERO|(m->isa + (offset&(Mchunk-1))); | |
| 1995/0222 | memmoveb((void*)ka, ac, i); | |
| 1994/1209 | offset += i; ac += i; } | |
| 1995/0215/sys/src/9/pc/devi82365.c:770,780 – 1995/0222/sys/src/9/pc/devi82365.c:791,801 | ||
| 1994/1209 | switch(p){ case Qmem: case Qattr: | |
| 1995/0222 | pp = slot + SLOTNO(c); | |
| 1994/1209 | if(pp->occupied == 0 || pp->enabled == 0) error(Eio); | |
| 1995/0209 | qlock(&pp->mlock); | |
| 1994/1209 |
| |
| 1995/0222 | n = pcmwrite(pp->slotno, p == Qattr, a, n, offset); | |
| 1995/0209 | qunlock(&pp->mlock); if(n < 0) error(Eio); | |
| 1995/0215/sys/src/9/pc/devi82365.c:785,796 – 1995/0222/sys/src/9/pc/devi82365.c:806,811 | ||
| 1994/1209 | return n; | |
| 1995/0108 | } | |
| 1994/1209 |
| |
| 1995/0215/sys/src/9/pc/devi82365.c:820,826 – 1995/0222/sys/src/9/pc/devi82365.c:835,841 | ||
| 1994/1209 | wrreg(pp, Rigc, isa->irq | Fnotreset | Fiocard); /* set power and enable device */ | |
| 1995/0222 | x = vcode(pp->vpp1); | |
| 1994/1209 | wrreg(pp, Rpc, x|Fautopower|Foutena|Fcardena); /* 16-bit data path */ | |
| 1995/0215/sys/src/9/pc/devi82365.c:842,851 – 1995/0222/sys/src/9/pc/devi82365.c:857,866 | ||
| 1994/1209 | /* Reset adapter */ x = Creset; pcmwrite(dev, 1, &x, 1, pp->caddr + Rconfig); | |
| 1995/0222 | delay(5); | |
| 1994/1209 | x = 0; pcmwrite(dev, 1, &x, 1, pp->caddr + Rconfig); | |
| 1995/0222 | delay(5); | |
| 1994/1209 | /* * Set level sensitive (not pulsed) interrupts and | |
| 1995/0215/sys/src/9/pc/devi82365.c:854,860 – 1995/0222/sys/src/9/pc/devi82365.c:869,875 | ||
| 1994/1209 | */ x = Clevel | 1; pcmwrite(dev, 1, &x, 1, pp->caddr + Rconfig); | |
| 1995/0222 | delay(5); | |
| 1994/1209 | } return 0; } | |
| 1995/0215/sys/src/9/pc/devi82365.c:877,887 – 1995/0222/sys/src/9/pc/devi82365.c:892,901 | ||
| 1994/1209 | static int readc(Slot *pp, uchar *x) { | |
| 1995/0222 | if(pp->cispos >= Mchunk) | |
| 1994/1209 | return 0; | |
| 1995/0222 | *x = pp->cisbase[2*pp->cispos]; pp->cispos++; | |
| 1994/1209 | return 1; } | |
| 1995/0215/sys/src/9/pc/devi82365.c:888,898 – 1995/0222/sys/src/9/pc/devi82365.c:902,911 | ||
| 1994/1209 | static void cisread(Slot *pp) { | |
| 1995/0222 | int this, i; PCMmap *m; | |
| 1994/1209 | pp->vpp1 = pp->vpp2 = 5; pp->bit16 = 0; | |
| 1995/0215/sys/src/9/pc/devi82365.c:901,909 – 1995/0222/sys/src/9/pc/devi82365.c:914,924 | ||
| 1994/1209 | pp->def = 0; pp->irqs = 0xffff; | |
| 1995/0222 | if(m == 0) return; pp->cisbase = (uchar*)(KZERO|m->isa); pp->cispos = 0; | |
| 1994/1209 | /* loop through all the tuples */ for(i = 0; i < 1000; i++){ | |
| 1995/0215/sys/src/9/pc/devi82365.c:916,924 – 1995/0222/sys/src/9/pc/devi82365.c:931,937 | ||
| 1994/1209 | (*parse[type])(pp, type); if(link == 0xff) break; | |
| 1995/0222 | pp->cispos = this + (2+link); | |
| 1994/1209 | } } | |
| 1995/0222/sys/src/9/pc/devi82365.c:92,97 – 1995/0223/sys/src/9/pc/devi82365.c:92,99 (short | long) | ||
| 1994/1209 | Rconfig= 0, Creset= (1<<7), /* reset device */ Clevel= (1<<6), /* level sensitive interrupt line */ | |
| 1995/0223 | Maxctab= 8, /* maximum configuration table entries */ | |
| 1994/1209 | }; #define MAP(x,o) (Rmap + (x)*0x8 + o) | |
| 1995/0222/sys/src/9/pc/devi82365.c:99,104 – 1995/0223/sys/src/9/pc/devi82365.c:101,107 | ||
| 1994/1209 | typedef struct I82365 I82365; typedef struct Slot Slot; typedef struct PCMmap PCMmap; | |
| 1995/0223 | typedef struct Conftab Conftab; | |
| 1994/1209 | /* maps between ISA memory space and the card memory space */ struct PCMmap | |
| 1995/0222/sys/src/9/pc/devi82365.c:128,134 – 1995/0223/sys/src/9/pc/devi82365.c:131,153 | ||
| 1994/1209 | static I82365 *controller[4]; static int ncontroller; | |
| 1995/0223 | /* configuration table entry */ struct Conftab { int index; ushort irqs; /* legal irqs */ ushort port; /* port address */ uchar nioregs; /* number of io registers */ uchar bit16; /* true for 16 bit access */ uchar vpp1; uchar vpp2; uchar memwait; ulong maxwait; ulong readywait; ulong otherwait; }; /* a card slot */ | |
| 1994/1209 | struct Slot { | |
| 1995/0209 | Lock; | |
| 1995/0222/sys/src/9/pc/devi82365.c:142,148 – 1995/0223/sys/src/9/pc/devi82365.c:161,166 | ||
| 1994/1209 | /* status */ uchar special; /* in use for a special device */ uchar already; /* already inited */ | |
| 1995/0222/sys/src/9/pc/devi82365.c:153,177 – 1995/0223/sys/src/9/pc/devi82365.c:171,191 | ||
| 1994/1209 | /* cis info */ | |
| 1995/0117 | char verstr[512]; /* version string */ | |
| 1994/1209 |
| |
| 1995/0223 | int nctab; /* number of config table entries */ Conftab ctab[Maxctab]; Conftab *def; /* default conftab */ /* for walking through cis */ | |
| 1995/0222 | int cispos; /* current position scanning cis */ uchar *cisbase; | |
| 1995/0131 |
| |
| 1994/1209 | /* memory maps */ | |
| 1995/0209 | QLock mlock; /* lock down the maps */ | |
| 1994/1209 | int time; | |
| 1995/0223 | PCMmap mmap[Nmap]; /* maps, last is always for the kernel */ int nmap; /* number of maps */ | |
| 1994/1209 | }; static Slot *slot; static Slot *lastslot; | |
| 1995/0222/sys/src/9/pc/devi82365.c:234,260 – 1995/0223/sys/src/9/pc/devi82365.c:248,268 | ||
| 1994/1209 | if(pp->enabled) return; | |
| 1995/0222 |
| |
| 1995/0223 | /* power up and reset, wait's are empirical (???) */ wrreg(pp, Rpc, Fautopower|Foutena|Fcardena); delay(300); | |
| 1995/0222 | wrreg(pp, Rigc, 0); delay(100); wrreg(pp, Rigc, Fnotreset); | |
| 1995/0223 | delay(500); | |
| 1994/1209 |
| |
| 1995/0223 | /* get configuration */ | |
| 1994/1209 | slotinfo(pp); if(pp->occupied){ cisread(pp); | |
| 1995/0222 |
| |
| 1994/1209 | ||
| 1995/0223 | pp->enabled = 1; | |
| 1995/0222 | } else | |
| 1995/0223 | wrreg(pp, Rpc, Fautopower); | |
| 1994/1209 | } /* | |
| 1995/0222/sys/src/9/pc/devi82365.c:263,270 – 1995/0223/sys/src/9/pc/devi82365.c:271,277 | ||
| 1994/1209 | static void slotdis(Slot *pp) { | |
| 1995/0222 |
| |
| 1995/0223 | wrreg(pp, Rpc, Fautopower); /* turn off card */ | |
| 1995/0222 | wrreg(pp, Rwe, 0); /* no windows */ | |
| 1994/1209 | pp->enabled = 0; } | |
| 1995/0222/sys/src/9/pc/devi82365.c:307,328 – 1995/0223/sys/src/9/pc/devi82365.c:314,324 | ||
| 1994/1209 | PCMmap *m, *lru; int i; | |
| 1995/0209 |
| |
| 1994/1210 |
| |
| 1995/0209 |
| |
| 1994/1209 |
| |
| 1995/0223 | for(m = pp->mmap; m < &pp->mmap[pp->nmap]; m++){ | |
| 1994/1209 | if((we & bit) && m->attr == attr && offset >= m->ca && offset < m->cea){ m->time = pp->time++; return m; | |
| 1995/0222/sys/src/9/pc/devi82365.c:345,351 – 1995/0223/sys/src/9/pc/devi82365.c:341,347 | ||
| 1994/1209 | wrreg(pp, MAP(i, Mbtmlo), m->isa>>12); wrreg(pp, MAP(i, Mbtmhi), (m->isa>>(12+8)) | F16bit); wrreg(pp, MAP(i, Mtoplo), (m->isa+Mchunk-1)>>12); | |
| 1995/0222 |
| |
| 1995/0223 | wrreg(pp, MAP(i, Mtophi), ((m->isa+Mchunk-1)>>(12+8)) /*| Ftimer1/**/); | |
| 1994/1209 | offset -= m->isa; offset &= (1<<25)-1; offset >>= 12; | |
| 1995/0222/sys/src/9/pc/devi82365.c:509,514 – 1995/0223/sys/src/9/pc/devi82365.c:505,514 | ||
| 1994/1209 | print("pcmcia controller%d is a %d slot %s\n", ncontroller, cp->nslot, chipname[cp->type]); | |
| 1995/0223 | /* low power mode */ outb(x, Rmisc2 + (dev<<7)); outb(d, Flowpow); | |
| 1994/1209 | controller[ncontroller++] = cp; return cp; } | |
| 1995/0222/sys/src/9/pc/devi82365.c:522,527 – 1995/0223/sys/src/9/pc/devi82365.c:522,528 | ||
| 1994/1209 | static int already; int i, j; I82365 *cp; | |
| 1995/0223 | Slot *pp; | |
| 1994/1209 | if(already) return; | |
| 1995/0222/sys/src/9/pc/devi82365.c:541,555 – 1995/0223/sys/src/9/pc/devi82365.c:542,568 | ||
| 1994/1209 | for(i = 0; i < ncontroller; i++){ cp = controller[i]; for(j = 0; j < cp->nslot; j++){ | |
| 1995/0222 |
| |
| 1994/1209 |
| |
| 1995/0222 |
| |
| 1994/1209 |
| |
| 1995/0223 | pp = lastslot++; pp->slotno = pp - slot; pp->memlen = 64*MB; pp->base = (cp->dev<<7) | (j<<6); pp->cp = cp; slotdis(pp); /* interrupt on status change */ wrreg(pp, Rcscic, ((PCMCIAvec-Int0vec)<<4) | Fchangeena); | |
| 1994/1209 | } } | |
| 1995/0222 | ||
| 1995/0223 | /* get ISA address space for memory maps */ for(i = 0; i < Nmap; i++) for(pp = slot; pp < lastslot; pp++){ pp->mmap[i].isa = getisa(0, Mchunk, BY2PG); if(pp->mmap[i].isa == 0) break; pp->nmap++; } | |
| 1995/0222 | /* for card management interrupts */ setvec(PCMCIAvec, i82365intr, 0); | |
| 1994/1209 | } | |
| 1995/0222/sys/src/9/pc/devi82365.c:815,820 – 1995/0223/sys/src/9/pc/devi82365.c:828,834 | ||
| 1994/1209 | { uchar we, x; Slot *pp; | |
| 1995/0223 | Conftab *ct; | |
| 1994/1209 | if(dev > nslot) return -1; | |
| 1995/0222/sys/src/9/pc/devi82365.c:823,845 – 1995/0223/sys/src/9/pc/devi82365.c:837,869 | ||
| 1994/1209 | if(!pp->occupied) return -1; | |
| 1995/0223 | /* find a configuration with the right port */ for(ct = pp->ctab; ct < &pp->ctab[pp->nctab]; ct++) if(ct->nioregs && ct->port == isa->port) break; /* if non found, settle for one with the some ioregs */ if(ct == &pp->ctab[pp->nctab]) for(ct = pp->ctab; ct < &pp->ctab[pp->nctab]; ct++) if(ct->nioregs) break; if(ct == &pp->ctab[pp->nctab]) | |
| 1994/1209 | return -1; | |
| 1995/0223 | print("%s\n\tindex %d vpp1 %d bit16 %d nioregs %d\n", pp->verstr, ct->index, ct->vpp1, ct->bit16, ct->nioregs); /* route interrupts */ | |
| 1994/1209 | if(isa->irq == 2) isa->irq = 9; | |
| 1995/0222 |
| |
| 1995/0223 | x = vcode(ct->vpp1); | |
| 1994/1209 | wrreg(pp, Rpc, x|Fautopower|Foutena|Fcardena); /* 16-bit data path */ | |
| 1995/0223 | if(ct->bit16) | |
| 1994/1209 | wrreg(pp, Rio, (1<<0)|(1<<1)); /* enable io port map 0 */ | |
| 1995/0222/sys/src/9/pc/devi82365.c:848,855 – 1995/0223/sys/src/9/pc/devi82365.c:872,879 | ||
| 1994/1209 | we = rdreg(pp, Rwe); wrreg(pp, Riobtm0lo, isa->port); wrreg(pp, Riobtm0hi, isa->port>>8); | |
| 1995/0223 | wrreg(pp, Riotop0lo, (isa->port+ct->nioregs)); wrreg(pp, Riotop0hi, (isa->port+ct->nioregs)>>8); | |
| 1994/1209 | wrreg(pp, Rwe, we | (1<<6)); /* only touch Rconfig if it is present */ | |
| 1995/0222/sys/src/9/pc/devi82365.c:867,873 – 1995/0223/sys/src/9/pc/devi82365.c:891,900 | ||
| 1994/1209 | * configuration number 1. * Setting the configuration number enables IO port access. */ | |
| 1995/0223 | if(isa->irq > 7) x = Clevel | ct->index; else x = ct->index; | |
| 1994/1209 | pcmwrite(dev, 1, &x, 1, pp->caddr + Rconfig); | |
| 1995/0222 | delay(5); | |
| 1994/1209 | } | |
| 1995/0222/sys/src/9/pc/devi82365.c:907,918 – 1995/0223/sys/src/9/pc/devi82365.c:934,944 | ||
| 1995/0222 | int this, i; PCMmap *m; | |
| 1994/1209 |
| |
| 1995/0223 | memset(pp->ctab, 0, sizeof(pp->ctab)); | |
| 1994/1209 | pp->caddr = 0; pp->cpresent = 0; | |
| 1995/0223 | pp->configed = 0; pp->nctab = 0; | |
| 1994/1209 | m = getmap(pp, 0, 1); | |
| 1995/0222 | if(m == 0) | |
| 1995/0222/sys/src/9/pc/devi82365.c:1062,1068 – 1995/0223/sys/src/9/pc/devi82365.c:1088,1094 | ||
| 1994/1209 | } static void | |
| 1995/0223 | timing(Slot *pp, Conftab *ct) | |
| 1994/1209 | { uchar c, i; | |
| 1995/0222/sys/src/9/pc/devi82365.c:1070,1096 – 1995/0223/sys/src/9/pc/devi82365.c:1096,1122 | ||
| 1994/1209 | return; i = c&0x3; if(i != 3) | |
| 1995/0131 |
| |
| 1995/0223 | ct->maxwait = ttiming(pp, i); /* max wait */ | |
| 1994/1209 | i = (c>>2)&0x7; if(i != 7) | |
| 1995/0131 |
| |
| 1995/0223 | ct->readywait = ttiming(pp, i); /* max ready/busy wait */ | |
| 1994/1209 | i = (c>>5)&0x7; if(i != 7) | |
| 1995/0131 |
| |
| 1995/0223 | ct->otherwait = ttiming(pp, i); /* reserved wait */ | |
| 1994/1209 | } void | |
| 1995/0223 | iospaces(Slot *pp, Conftab *ct) | |
| 1994/1209 | { uchar c; int i; | |
| 1995/0223 | ulong len; | |
| 1994/1209 | ||
| 1995/0114 | if(readc(pp, &c) != 1) return; | |
| 1994/1209 | ||
| 1995/0114 |
| |
| 1995/0223 | ct->nioregs = 1<<(c&0x1f); ct->bit16 = ((c>>5)&3) >= 2; | |
| 1995/0114 | if((c & 0x80) == 0) return; | |
| 1994/1209 | ||
| 1995/0222/sys/src/9/pc/devi82365.c:1098,1111 – 1995/0223/sys/src/9/pc/devi82365.c:1124,1137 | ||
| 1995/0114 | return; | |
| 1994/1209 | ||
| 1995/0114 | for(i = (c&0xf)+1; i; i--){ | |
| 1995/0223 | ct->port = getlong(pp, (c>>4)&0x3); | |
| 1995/0114 | len = getlong(pp, (c>>6)&0x3); | |
| 1995/0223 | USED(len); | |
| 1994/1209 | } } static void | |
| 1995/0223 | irq(Slot *pp, Conftab *ct) | |
| 1994/1209 | { uchar c; | |
| 1995/0222/sys/src/9/pc/devi82365.c:1112,1120 – 1995/0223/sys/src/9/pc/devi82365.c:1138,1146 | ||
| 1994/1209 | if(readc(pp, &c) != 1) return; if(c & 0x10) | |
| 1995/0223 | ct->irqs = getlong(pp, 2); | |
| 1994/1209 | else | |
| 1995/0223 | ct->irqs = 1<<(c&0xf); | |
| 1994/1209 | } static void | |
| 1995/0222/sys/src/9/pc/devi82365.c:1135,1176 – 1995/0223/sys/src/9/pc/devi82365.c:1161,1218 | ||
| 1994/1209 | tentry(Slot *pp, int ttype) { uchar c, i, feature; | |
| 1995/0223 | Conftab *ct; | |
| 1994/1209 | USED(ttype); | |
| 1995/0223 | if(pp->nctab >= Maxctab) return; | |
| 1994/1209 | if(readc(pp, &c) != 1) return; | |
| 1995/0223 | ct = &pp->ctab[pp->nctab++]; /* copy from last default config */ if(pp->def) *ct = *pp->def; ct->index = c & 0x3f; /* is this the new default? */ if(c & 0x40) pp->def = ct; /* memory wait specified? */ | |
| 1994/1209 | if(c & 0x80){ if(readc(pp, &i) != 1) return; if(i&0x80) | |
| 1995/0223 | ct->memwait = 1; | |
| 1994/1209 | } | |
| 1995/0223 | ||
| 1994/1209 | if(readc(pp, &feature) != 1) return; switch(feature&0x3){ case 1: | |
| 1995/0223 | ct->vpp1 = ct->vpp2 = power(pp); | |
| 1994/1209 | break; case 2: power(pp); | |
| 1995/0223 | ct->vpp1 = ct->vpp2 = power(pp); | |
| 1994/1209 | break; case 3: power(pp); | |
| 1995/0223 | ct->vpp1 = power(pp); ct->vpp2 = power(pp); | |
| 1994/1209 | break; default: break; } if(feature&0x4) | |
| 1995/0223 | timing(pp, ct); | |
| 1994/1209 | if(feature&0x8) | |
| 1995/0223 | iospaces(pp, ct); | |
| 1994/1209 | if(feature&0x10) | |
| 1995/0223 | irq(pp, ct); | |
| 1994/1209 | switch(feature&0x3){ case 1: memspace(pp, 0, 2, 0); | |
| 1995/0223/sys/src/9/pc/devi82365.c:100,118 – 1995/0225/sys/src/9/pc/devi82365.c:100,107 (short | long) | ||
| 1994/1209 | typedef struct I82365 I82365; typedef struct Slot Slot; | |
| 1995/0223 | typedef struct Conftab Conftab; | |
| 1994/1209 |
| |
| 1995/0223/sys/src/9/pc/devi82365.c:182,198 – 1995/0225/sys/src/9/pc/devi82365.c:171,189 | ||
| 1995/0222 | uchar *cisbase; | |
| 1994/1209 | /* memory maps */ | |
| 1995/0209 |
| |
| 1995/0225 | Lock mlock; /* lock down the maps */ | |
| 1994/1209 | int time; | |
| 1995/0223 | PCMmap mmap[Nmap]; /* maps, last is always for the kernel */ | |
| 1994/1209 | }; static Slot *slot; static Slot *lastslot; static nslot; | |
| 1995/0222 |
| |
| 1995/0225 | static void cisread(Slot*); static void i82365intr(Ureg*, void*); static int pcmio(int, ISAConf*); static long pcmread(int, int, void*, long, ulong); static long pcmwrite(int, int, void*, long, ulong); | |
| 1994/1209 | /* * reading and writing card registers | |
| 1995/0223/sys/src/9/pc/devi82365.c:304,356 – 1995/0225/sys/src/9/pc/devi82365.c:295,402 | ||
| 1994/1209 | } } | |
| 1995/0225 | enum { Mshift= 12, Mgran= (1<<Mshift), /* granularity of maps */ Mmask= ~(Mgran-1), /* mask for address bits important to the chip */ }; | |
| 1994/1209 | /* * get a map for pc card region, return corrected len */ | |
| 1995/0225 | PCMmap* pcmmap(int slotno, ulong offset, int len, int attr) | |
| 1994/1209 | { | |
| 1995/0225 | Slot *pp; | |
| 1994/1209 | uchar we, bit; | |
| 1995/0225 | PCMmap *m, *nm; | |
| 1994/1209 | int i; | |
| 1995/0225 | ulong e; | |
| 1994/1209 |
| |
| 1995/0225 | pp = slot + slotno; lock(&pp->mlock); /* convert offset to granularity */ if(len <= 0) len = 1; e = ROUND(offset+len, Mgran); offset &= Mmask; len = e - offset; /* look for a map that covers the right area */ | |
| 1994/1209 | we = rdreg(pp, Rwe); bit = 1; | |
| 1995/0223 |
| |
| 1994/1209 |
| |
| 1995/0225 | nm = 0; for(m = pp->mmap; m < &pp->mmap[Nmap]; m++){ if((we & bit)) if(m->attr == attr) if(offset >= m->ca && e <= m->cea){ m->ref++; unlock(&pp->mlock); | |
| 1994/1209 | return m; } bit <<= 1; | |
| 1995/0225 | if(nm == 0 && m->ref == 0) nm = m; | |
| 1994/1209 | } | |
| 1995/0225 | m = nm; if(m == 0){ unlock(&pp->mlock); return 0; } | |
| 1994/1209 |
| |
| 1995/0225 | /* if isa space isn't big enough, free it and get more */ if(m->len < len){ if(m->isa){ putisa(m->isa, m->len); m->len = 0; } m->isa = getisa(0, len, Mgran)&~KZERO; if(m->isa == 0){ print("pcmmap: out of isa space\n"); unlock(&pp->mlock); return 0; } m->len = len; } /* set up new map */ | |
| 1994/1209 | m->ca = offset; | |
| 1995/0225 | m->cea = m->ca + m->len; | |
| 1994/1209 | m->attr = attr; | |
| 1995/0225 | i = m-pp->mmap; | |
| 1994/1209 | bit = 1<<i; wrreg(pp, Rwe, we & ~bit); /* disable map before changing it */ | |
| 1995/0223 |
| |
| 1995/0225 | wrreg(pp, MAP(i, Mbtmlo), m->isa>>Mshift); wrreg(pp, MAP(i, Mbtmhi), (m->isa>>(Mshift+8)) | F16bit); wrreg(pp, MAP(i, Mtoplo), (m->isa+m->len-1)>>Mshift); wrreg(pp, MAP(i, Mtophi), ((m->isa+m->len-1)>>(Mshift+8))); | |
| 1994/1209 | offset -= m->isa; offset &= (1<<25)-1; | |
| 1995/0225 | offset >>= Mshift; | |
| 1994/1209 | wrreg(pp, MAP(i, Mofflo), offset); wrreg(pp, MAP(i, Moffhi), (offset>>8) | (attr ? Fregactive : 0)); wrreg(pp, Rwe, we | bit); /* enable map */ | |
| 1995/0225 | m->ref = 1; unlock(&pp->mlock); | |
| 1994/1209 | return m; } | |
| 1995/0225 | void pcmunmap(int slotno, PCMmap* m) { Slot *pp; pp = slot + slotno; lock(&pp->mlock); m->ref--; unlock(&pp->mlock); } | |
| 1994/1209 | static void increfp(Slot *pp) { | |
| 1995/0223/sys/src/9/pc/devi82365.c:554,568 – 1995/0225/sys/src/9/pc/devi82365.c:600,605 | ||
| 1994/1209 | } } | |
| 1995/0222 | ||
| 1995/0223 |
| |
| 1995/0222 | /* for card management interrupts */ setvec(PCMCIAvec, i82365intr, 0); | |
| 1994/1209 | } | |
| 1995/0223/sys/src/9/pc/devi82365.c:665,671 – 1995/0225/sys/src/9/pc/devi82365.c:702,708 | ||
| 1994/1209 | } } | |
| 1995/0225 | static long | |
| 1995/0222 | pcmread(int slotno, int attr, void *a, long n, ulong offset) | |
| 1994/1209 | { int i, len; | |
| 1995/0223/sys/src/9/pc/devi82365.c:677,698 – 1995/0225/sys/src/9/pc/devi82365.c:714,746 | ||
| 1995/0222 | pp = slot + slotno; | |
| 1994/1209 | if(pp->memlen < offset) return 0; | |
| 1995/0225 | m = 0; if(waserror()){ if(m) pcmunmap(pp->slotno, m); nexterror(); } ac = a; | |
| 1994/1209 | for(len = n; len > 0; len -= i){ | |
| 1995/0225 | m = pcmmap(pp->slotno, offset, 0, attr); if(m == 0) error("can't map PCMCIA card"); | |
| 1994/1209 | if(offset + len > m->cea) i = m->cea - offset; else i = len; | |
| 1995/0225 | ka = KZERO|(m->isa + offset - m->ca); | |
| 1995/0222 | memmoveb(ac, (void*)ka, i); | |
| 1995/0225 | pcmunmap(pp->slotno, m); | |
| 1994/1209 | offset += i; ac += i; } | |
| 1995/0225 | poperror(); | |
| 1994/1209 | return n; } | |
| 1995/0223/sys/src/9/pc/devi82365.c:715,727 – 1995/0225/sys/src/9/pc/devi82365.c:763,769 | ||
| 1994/1209 | return devdirread(c, a, n, 0, 0, pcmgen); case Qmem: case Qattr: | |
| 1995/0222 |
| |
| 1995/0209 |
| |
| 1995/0222 |
| |
| 1995/0209 |
| |
| 1994/1209 |
| |
| 1995/0225 | return pcmread(SLOTNO(c), p==Qattr, a, n, offset); | |
| 1994/1209 | case Qctl: cp = buf; | |
| 1995/0222 | pp = slot + SLOTNO(c); | |
| 1995/0223/sys/src/9/pc/devi82365.c:765,771 – 1995/0225/sys/src/9/pc/devi82365.c:807,813 | ||
| 1995/0222 | return devbwrite(c, bp, offset); | |
| 1995/0108 | } | |
| 1994/1209 |
| |
| 1995/0225 | static long | |
| 1994/1209 | pcmwrite(int dev, int attr, void *a, long n, ulong offset) { int i, len; | |
| 1995/0223/sys/src/9/pc/devi82365.c:777,796 – 1995/0225/sys/src/9/pc/devi82365.c:819,851 | ||
| 1994/1209 | pp = slot + dev; if(pp->memlen < offset) return 0; | |
| 1995/0225 | m = 0; if(waserror()){ if(m) pcmunmap(pp->slotno, m); nexterror(); } ac = a; | |
| 1994/1209 | for(len = n; len > 0; len -= i){ | |
| 1995/0225 | m = pcmmap(pp->slotno, offset, 0, attr); if(m == 0) error("can't map PCMCIA card"); | |
| 1994/1209 | if(offset + len > m->cea) i = m->cea - offset; else i = len; | |
| 1995/0225 | ka = KZERO|(m->isa + offset - m->ca); | |
| 1995/0222 | memmoveb((void*)ka, ac, i); | |
| 1995/0225 | pcmunmap(pp->slotno, m); | |
| 1994/1209 | offset += i; ac += i; } | |
| 1995/0225 | poperror(); | |
| 1994/1209 | return n; } | |
| 1995/0223/sys/src/9/pc/devi82365.c:807,815 – 1995/0225/sys/src/9/pc/devi82365.c:862,868 | ||
| 1995/0222 | pp = slot + SLOTNO(c); | |
| 1994/1209 | if(pp->occupied == 0 || pp->enabled == 0) error(Eio); | |
| 1995/0209 |
| |
| 1995/0222 | n = pcmwrite(pp->slotno, p == Qattr, a, n, offset); | |
| 1995/0209 |
| |
| 1994/1209 | break; | |
| 1995/0223/sys/src/9/pc/devi82365.c:823,846 – 1995/0225/sys/src/9/pc/devi82365.c:876,901 | ||
| 1994/1209 | * configure the Slot for IO. We assume very heavily that we can read * cofiguration info from the CIS. If not, we won't set up correctly. */ | |
| 1995/0225 | static int pcmio(int slotno, ISAConf *isa) | |
| 1994/1209 | { | |
| 1995/0225 | uchar we, x, *p; | |
| 1994/1209 | Slot *pp; | |
| 1995/0223 | Conftab *ct; | |
| 1995/0225 | PCMmap *m; | |
| 1994/1209 |
| |
| 1995/0225 | if(slotno > nslot) | |
| 1994/1209 | return -1; | |
| 1995/0225 | pp = slot + slotno; | |
| 1994/1209 | if(!pp->occupied) return -1; | |
| 1995/0223 | /* find a configuration with the right port */ | |
| 1995/0225 | for(ct = pp->ctab; ct < &pp->ctab[pp->nctab]; ct++){ | |
| 1995/0223 | if(ct->nioregs && ct->port == isa->port) break; | |
| 1995/0225 | } | |
| 1995/0223 | /* if non found, settle for one with the some ioregs */ if(ct == &pp->ctab[pp->nctab]) | |
| 1995/0223/sys/src/9/pc/devi82365.c:851,864 – 1995/0225/sys/src/9/pc/devi82365.c:906,917 | ||
| 1995/0223 | if(ct == &pp->ctab[pp->nctab]) | |
| 1994/1209 | return -1; | |
| 1995/0223 |
| |
| 1994/1209 | if(isa->irq == 2) isa->irq = 9; wrreg(pp, Rigc, isa->irq | Fnotreset | Fiocard); | |
| 1995/0225 | /* set power and enable slotnoice */ | |
| 1995/0223 | x = vcode(ct->vpp1); | |
| 1994/1209 | wrreg(pp, Rpc, x|Fautopower|Foutena|Fcardena); | |
| 1995/0223/sys/src/9/pc/devi82365.c:868,874 – 1995/0225/sys/src/9/pc/devi82365.c:921,927 | ||
| 1994/1209 | /* enable io port map 0 */ if(isa->port == 0) | |
| 1995/0118 |
| |
| 1995/0225 | isa->port = ct->port; | |
| 1994/1209 | we = rdreg(pp, Rwe); wrreg(pp, Riobtm0lo, isa->port); wrreg(pp, Riobtm0hi, isa->port>>8); | |
| 1995/0223/sys/src/9/pc/devi82365.c:879,889 – 1995/0225/sys/src/9/pc/devi82365.c:932,942 | ||
| 1994/1209 | /* only touch Rconfig if it is present */ if(pp->cpresent & (1<<Rconfig)){ /* Reset adapter */ | |
| 1995/0225 | m = pcmmap(slotno, pp->caddr + Rconfig, 1, 1); p = (uchar*)(KZERO|(m->isa + pp->caddr + Rconfig - m->ca)); *p = Creset; | |
| 1995/0222 | delay(5); | |
| 1994/1209 |
| |
| 1995/0225 | *p = 0; | |
| 1995/0222 | delay(5); | |
| 1994/1209 | /* | |
| 1995/0223/sys/src/9/pc/devi82365.c:892,902 – 1995/0225/sys/src/9/pc/devi82365.c:945,955 | ||
| 1994/1209 | * Setting the configuration number enables IO port access. */ | |
| 1995/0223 | if(isa->irq > 7) | |
| 1995/0225 | *p = Clevel | ct->index; | |
| 1995/0223 | else | |
| 1994/1209 |
| |
| 1995/0225 | *p = ct->index; | |
| 1995/0222 | delay(5); | |
| 1995/0225 | pcmunmap(slotno, m); | |
| 1994/1209 | } return 0; } | |
| 1995/0223/sys/src/9/pc/devi82365.c:940,946 – 1995/0225/sys/src/9/pc/devi82365.c:993,999 | ||
| 1995/0223 | pp->configed = 0; pp->nctab = 0; | |
| 1994/1209 |
| |
| 1995/0225 | m = pcmmap(pp->slotno, 0, 0, 1); | |
| 1995/0222 | if(m == 0) return; pp->cisbase = (uchar*)(KZERO|m->isa); | |
| 1995/0223/sys/src/9/pc/devi82365.c:959,964 – 1995/0225/sys/src/9/pc/devi82365.c:1012,1018 | ||
| 1994/1209 | break; | |
| 1995/0222 | pp->cispos = this + (2+link); | |
| 1994/1209 | } | |
| 1995/0225 | pcmunmap(pp->slotno, m); | |
| 1994/1209 | } static ulong | |
| 1995/0225/sys/src/9/pc/devi82365.c:559,564 – 1995/0328/sys/src/9/pc/devi82365.c:559,577 (short | long) | ||
| 1994/1209 | return cp; } | |
| 1995/0328 | static void i82365dump(Slot *pp) { int i; for(i = 0; i < 0x40; i++){ if((i&0x7) == 0) print("\n%ux: ", i); print("%ux ", rdreg(pp, i)); } print("\n"); } | |
| 1994/1209 | /* * set up for slot cards */ | |
| 1995/0225/sys/src/9/pc/devi82365.c:593,599 – 1995/0328/sys/src/9/pc/devi82365.c:606,615 | ||
| 1995/0223 | pp->memlen = 64*MB; pp->base = (cp->dev<<7) | (j<<6); pp->cp = cp; | |
| 1995/0328 | if(pp == slot)i82365dump(pp); /* | |
| 1995/0223 | slotdis(pp); | |
| 1995/0328 | */ | |
| 1995/0223 | /* interrupt on status change */ wrreg(pp, Rcscic, ((PCMCIAvec-Int0vec)<<4) | Fchangeena); | |
| 1995/0225/sys/src/9/pc/devi82365.c:780,797 – 1995/0328/sys/src/9/pc/devi82365.c:796,801 | ||
| 1994/1209 | if(pp->busy) cp += sprint(cp, "busy\n"); cp += sprint(cp, "battery lvl %d\n", pp->battery); | |
| 1995/0222 |
| |
| 1994/1209 | *cp = 0; return readstr(offset, a, n, buf); default: | |
| 1995/0225/sys/src/9/pc/devi82365.c:934,954 – 1995/0328/sys/src/9/pc/devi82365.c:938,958 | ||
| 1994/1209 | /* Reset adapter */ | |
| 1995/0225 | m = pcmmap(slotno, pp->caddr + Rconfig, 1, 1); p = (uchar*)(KZERO|(m->isa + pp->caddr + Rconfig - m->ca)); | |
| 1995/0328 | if(strstr(pp->verstr, "KeepInTouch") == 0){ | |
| 1995/0225 | *p = Creset; | |
| 1995/0222 | delay(5); | |
| 1995/0225 | *p = 0; | |
| 1995/0222 | delay(5); | |
| 1994/1209 |
| |
| 1995/0328 | } /* set configuration */ if(strstr(pp->verstr, "KeepInTouch") == 0){ | |
| 1995/0223 | if(isa->irq > 7) | |
| 1995/0225 | *p = Clevel | ct->index; | |
| 1995/0223 | else | |
| 1995/0225 | *p = ct->index; | |
| 1995/0222 | delay(5); | |
| 1995/0328 | } else i82365dump(pp); | |
| 1995/0225 | pcmunmap(slotno, m); | |
| 1994/1209 | } return 0; | |
| 1995/0225/sys/src/9/pc/devi82365.c:1306,1308 – 1995/0328/sys/src/9/pc/devi82365.c:1310,1313 | ||
| 1995/0111 | } pp->verstr[i] = 0; | |
| 1994/1209 | } | |
| 1995/0328 | ||
| 1995/0328/sys/src/9/pc/devi82365.c:41,46 – 1995/0329/sys/src/9/pc/devi82365.c:41,49 (short | long) | ||
| 1994/1209 | Rwe= 0x6, /* address window enable */ Fmem16= (1<<5), /* use A23-A12 to decode address */ Rio= 0x7, /* I/O control */ | |
| 1995/0329 | Fwidth16= (1<<0), /* 16 bit data width */ Fiocs16= (1<<1), /* IOCS16 determines data width */ Ftiming= (1<<3), /* timing register to use */ | |
| 1994/1209 | Riobtm0lo= 0x8, /* I/O address 0 start low byte */ Riobtm0hi= 0x9, /* I/O address 0 start high byte */ Riotop0lo= 0xa, /* I/O address 0 stop low byte */ | |
| 1995/0328/sys/src/9/pc/devi82365.c:126,131 – 1995/0329/sys/src/9/pc/devi82365.c:129,135 | ||
| 1995/0223 | int index; ushort irqs; /* legal irqs */ ushort port; /* port address */ | |
| 1995/0329 | uchar irqtype; | |
| 1995/0223 | uchar nioregs; /* number of io registers */ uchar bit16; /* true for 16 bit access */ uchar vpp1; | |
| 1995/0328/sys/src/9/pc/devi82365.c:239,252 – 1995/0329/sys/src/9/pc/devi82365.c:243,262 | ||
| 1994/1209 | if(pp->enabled) return; | |
| 1995/0223 |
| |
| 1995/0329 | /* power up and unreset, wait's are empirical (???) */ | |
| 1995/0223 | wrreg(pp, Rpc, Fautopower|Foutena|Fcardena); delay(300); | |
| 1995/0222 |
| |
| 1995/0223 | delay(500); | |
| 1994/1209 | ||
| 1995/0329 | wrreg(pp, Rpc, 0); delay(500); wrreg(pp, Rpc, Fautopower|Foutena|Fcardena); delay(300); wrreg(pp, Rigc, Fnotreset); delay(500); | |
| 1995/0223 | /* get configuration */ | |
| 1994/1209 | slotinfo(pp); if(pp->occupied){ | |
| 1995/0328/sys/src/9/pc/devi82365.c:253,259 – 1995/0329/sys/src/9/pc/devi82365.c:263,269 | ||
| 1994/1209 | cisread(pp); | |
| 1995/0223 | pp->enabled = 1; | |
| 1995/0222 | } else | |
| 1995/0223 |
| |
| 1995/0329 | wrreg(pp, Rpc, 0); | |
| 1994/1209 | } /* | |
| 1995/0328/sys/src/9/pc/devi82365.c:262,269 – 1995/0329/sys/src/9/pc/devi82365.c:272,279 | ||
| 1994/1209 | static void slotdis(Slot *pp) { | |
| 1995/0223 |
| |
| 1995/0222 |
| |
| 1995/0329 | wrreg(pp, Rwe, 0); /* no windows */ wrreg(pp, Rpc, 0); /* turn off card power */ | |
| 1994/1209 | pp->enabled = 0; } | |
| 1995/0328/sys/src/9/pc/devi82365.c:606,615 – 1995/0329/sys/src/9/pc/devi82365.c:616,622 | ||
| 1995/0223 | pp->memlen = 64*MB; pp->base = (cp->dev<<7) | (j<<6); pp->cp = cp; | |
| 1995/0328 |
| |
| 1995/0223 | slotdis(pp); | |
| 1995/0328 |
| |
| 1995/0223 | /* interrupt on status change */ wrreg(pp, Rcscic, ((PCMCIAvec-Int0vec)<<4) | Fchangeena); | |
| 1995/0328/sys/src/9/pc/devi82365.c:796,801 – 1995/0329/sys/src/9/pc/devi82365.c:803,818 | ||
| 1994/1209 | if(pp->busy) cp += sprint(cp, "busy\n"); cp += sprint(cp, "battery lvl %d\n", pp->battery); | |
| 1995/0329 | { int i; for(i = 0; i < 0x40; i++){ if((i&0x7) == 0) cp += sprint(cp, "\n%ux: ", i); cp += sprint(cp, "%ux ", rdreg(pp, i)); } cp += sprint(cp, "\n"); } | |
| 1994/1209 | *cp = 0; return readstr(offset, a, n, buf); default: | |
| 1995/0328/sys/src/9/pc/devi82365.c:915,927 – 1995/0329/sys/src/9/pc/devi82365.c:932,947 | ||
| 1994/1209 | isa->irq = 9; wrreg(pp, Rigc, isa->irq | Fnotreset | Fiocard); | |
| 1995/0225 |
| |
| 1995/0329 | /* set power and enable device */ | |
| 1995/0223 | x = vcode(ct->vpp1); | |
| 1994/1209 | wrreg(pp, Rpc, x|Fautopower|Foutena|Fcardena); /* 16-bit data path */ | |
| 1995/0223 | if(ct->bit16) | |
| 1994/1209 |
| |
| 1995/0329 | x = Fiocs16|Fwidth16; else x = 0; wrreg(pp, Rio, Ftiming|x); | |
| 1994/1209 | /* enable io port map 0 */ if(isa->port == 0) | |
| 1995/0328/sys/src/9/pc/devi82365.c:929,936 – 1995/0329/sys/src/9/pc/devi82365.c:949,956 | ||
| 1994/1209 | we = rdreg(pp, Rwe); wrreg(pp, Riobtm0lo, isa->port); wrreg(pp, Riobtm0hi, isa->port>>8); | |
| 1995/0223 |
| |
| 1995/0329 | wrreg(pp, Riotop0lo, (isa->port+ct->nioregs-1)); wrreg(pp, Riotop0hi, (isa->port+ct->nioregs-1)>>8); | |
| 1994/1209 | wrreg(pp, Rwe, we | (1<<6)); /* only touch Rconfig if it is present */ | |
| 1995/0328/sys/src/9/pc/devi82365.c:938,958 – 1995/0329/sys/src/9/pc/devi82365.c:958,971 | ||
| 1994/1209 | /* Reset adapter */ | |
| 1995/0225 | m = pcmmap(slotno, pp->caddr + Rconfig, 1, 1); p = (uchar*)(KZERO|(m->isa + pp->caddr + Rconfig - m->ca)); | |
| 1995/0328 |
| |
| 1995/0225 |
| |
| 1995/0222 |
| |
| 1995/0225 |
| |
| 1995/0222 |
| |
| 1995/0328 |
| |
| 1995/0223 |
| |
| 1995/0225 |
| |
| 1995/0223 |
| |
| 1995/0225 |
| |
| 1995/0329 | /* set configuration and interrupt type */ x = ct->index; if((ct->irqtype & 0x20) && ((ct->irqtype & 0x40)==0 || isa->irq>7)) x |= Clevel; *p = x|ct->index; | |
| 1995/0222 | delay(5); | |
| 1995/0328 |
| |
| 1995/0329 | ||
| 1995/0225 | pcmunmap(slotno, m); | |
| 1994/1209 | } return 0; | |
| 1995/0328/sys/src/9/pc/devi82365.c:1066,1080 – 1995/0329/sys/src/9/pc/devi82365.c:1079,1104 | ||
| 1994/1209 | { uchar c; ulong microvolts; | |
| 1995/0329 | ulong exp; | |
| 1994/1209 | if(readc(pp, &c) != 1) return 0; | |
| 1995/0329 | exp = vexp[c&0x7]; microvolts = vmant[(c>>3)&0xf]*exp; | |
| 1994/1209 | while(c & 0x80){ if(readc(pp, &c) != 1) return 0; | |
| 1995/0329 | switch(c){ case 0x7d: break; /* high impedence when sleeping */ case 0x7e: case 0x7f: microvolts = 0; /* no connection */ break; default: exp /= 10; microvolts += exp*(c&0x7f); } | |
| 1994/1209 | } return microvolts; } | |
| 1995/0328/sys/src/9/pc/devi82365.c:1121,1127 – 1995/0329/sys/src/9/pc/devi82365.c:1145,1151 | ||
| 1994/1209 | nanoamps(pp); if(feature & 0x20) nanoamps(pp); | |
| 1995/0329 | if(feature & 0x40) | |
| 1994/1209 | nanoamps(pp); return mv/1000000; } | |
| 1995/0328/sys/src/9/pc/devi82365.c:1195,1200 – 1995/0329/sys/src/9/pc/devi82365.c:1219,1225 | ||
| 1994/1209 | if(readc(pp, &c) != 1) return; | |
| 1995/0329 | ct->irqtype = c & 0xe0; | |
| 1994/1209 | if(c & 0x10) | |
| 1995/0223 | ct->irqs = getlong(pp, 2); | |
| 1994/1209 | else | |
| 1995/0328/sys/src/9/pc/devi82365.c:1271,1277 – 1995/0329/sys/src/9/pc/devi82365.c:1296,1302 | ||
| 1995/0223 | iospaces(pp, ct); | |
| 1994/1209 | if(feature&0x10) | |
| 1995/0223 | irq(pp, ct); | |
| 1994/1209 |
| |
| 1995/0329 | switch((feature>>5)&0x3){ | |
| 1994/1209 | case 1: memspace(pp, 0, 2, 0); break; | |
| 1995/0329/sys/src/9/pc/devi82365.c:246,262 – 1995/0331/sys/src/9/pc/devi82365.c:246,256 (short | long) | ||
| 1995/0329 | /* power up and unreset, wait's are empirical (???) */ | |
| 1995/0223 | wrreg(pp, Rpc, Fautopower|Foutena|Fcardena); delay(300); | |
| 1995/0331 | wrreg(pp, Rigc, 0); delay(100); | |
| 1995/0222 | wrreg(pp, Rigc, Fnotreset); | |
| 1995/0223 | delay(500); | |
| 1994/1209 | ||
| 1995/0329 |
| |
| 1995/0223 | /* get configuration */ | |
| 1994/1209 | slotinfo(pp); if(pp->occupied){ | |
| 1995/0329/sys/src/9/pc/devi82365.c:263,269 – 1995/0331/sys/src/9/pc/devi82365.c:257,263 | ||
| 1994/1209 | cisread(pp); | |
| 1995/0223 | pp->enabled = 1; | |
| 1995/0222 | } else | |
| 1995/0329 |
| |
| 1995/0331 | wrreg(pp, Rpc, Fautopower); | |
| 1994/1209 | } /* | |
| 1995/0329/sys/src/9/pc/devi82365.c:272,279 – 1995/0331/sys/src/9/pc/devi82365.c:266,273 | ||
| 1994/1209 | static void slotdis(Slot *pp) { | |
| 1995/0329 |
| |
| 1995/0331 | wrreg(pp, Rpc, 0); /* turn off card power */ wrreg(pp, Rwe, 0); /* no windows */ | |
| 1994/1209 | pp->enabled = 0; } | |
| 1995/0329/sys/src/9/pc/devi82365.c:1306,1312 – 1995/0331/sys/src/9/pc/devi82365.c:1300,1306 | ||
| 1994/1209 | case 3: if(readc(pp, &c) != 1) return; | |
| 1995/0331 | for(i = 0; i <= (c&0x7); i++) | |
| 1994/1209 | memspace(pp, (c>>5)&0x3, (c>>3)&0x3, c&0x80); break; } | |
| 1995/0331/sys/src/9/pc/devi82365.c:898,904 – 1995/0401/sys/src/9/pc/devi82365.c:898,909 (short | long) | ||
| 1994/1209 | Slot *pp; | |
| 1995/0223 | Conftab *ct; | |
| 1995/0225 | PCMmap *m; | |
| 1995/0401 | int irq; | |
| 1994/1209 | ||
| 1995/0401 | irq = isa->irq; if(irq == 2) irq = 9; | |
| 1995/0225 | if(slotno > nslot) | |
| 1994/1209 | return -1; | |
| 1995/0225 | pp = slot + slotno; | |
| 1995/0331/sys/src/9/pc/devi82365.c:908,914 – 1995/0401/sys/src/9/pc/devi82365.c:913,919 | ||
| 1994/1209 | ||
| 1995/0223 | /* find a configuration with the right port */ | |
| 1995/0225 | for(ct = pp->ctab; ct < &pp->ctab[pp->nctab]; ct++){ | |
| 1995/0223 |
| |
| 1995/0401 | if(ct->nioregs && ct->port == isa->port && ((1<<irq) & ct->irqs)) | |
| 1995/0223 | break; | |
| 1995/0225 | } | |
| 1995/0223 | ||
| 1995/0331/sys/src/9/pc/devi82365.c:915,921 – 1995/0401/sys/src/9/pc/devi82365.c:920,926 | ||
| 1995/0223 | /* if non found, settle for one with the some ioregs */ if(ct == &pp->ctab[pp->nctab]) for(ct = pp->ctab; ct < &pp->ctab[pp->nctab]; ct++) | |
| 1995/0401 | if(ct->nioregs && ((1<<irq) & ct->irqs)) | |
| 1995/0223 | break; if(ct == &pp->ctab[pp->nctab]) | |
| 1995/0331/sys/src/9/pc/devi82365.c:922,930 – 1995/0401/sys/src/9/pc/devi82365.c:927,934 | ||
| 1994/1209 | return -1; | |
| 1995/0223 | /* route interrupts */ | |
| 1994/1209 |
| |
| 1995/0401 | isa->irq = irq; wrreg(pp, Rigc, irq | Fnotreset | Fiocard); | |
| 1994/1209 | ||
| 1995/0329 | /* set power and enable device */ | |
| 1995/0223 | x = vcode(ct->vpp1); | |
| 1995/0331/sys/src/9/pc/devi82365.c:957,963 – 1995/0401/sys/src/9/pc/devi82365.c:961,967 | ||
| 1995/0329 | x = ct->index; if((ct->irqtype & 0x20) && ((ct->irqtype & 0x40)==0 || isa->irq>7)) x |= Clevel; | |
| 1995/0401 | *p = x; | |
| 1995/0222 | delay(5); | |
| 1995/0329 | ||
| 1995/0225 | pcmunmap(slotno, m); | |
| 1995/0331/sys/src/9/pc/devi82365.c:1218,1223 – 1995/0401/sys/src/9/pc/devi82365.c:1222,1228 | ||
| 1995/0223 | ct->irqs = getlong(pp, 2); | |
| 1994/1209 | else | |
| 1995/0223 | ct->irqs = 1<<(c&0xf); | |
| 1995/0401 | ct->irqs &= 0xDEB8; /* levels available to card */ | |
| 1994/1209 | } static void | |
| 1995/0401/sys/src/9/pc/devi82365.c:869,877 – 1995/0519/sys/src/9/pc/devi82365.c:869,891 (short | long) | ||
| 1994/1209 | { ulong p; Slot *pp; | |
| 1995/0519 | char buf[32]; | |
| 1994/1209 | p = TYPE(c); switch(p){ | |
| 1995/0519 | case Qctl: if(n >= sizeof(buf)) n = sizeof(buf) - 1; strncpy(buf, a, n); buf[n] = 0; pp = slot + SLOTNO(c); if(!pp->occupied) error(Eio); /* set vpp on card */ if(strncmp(buf, "vpp", 3) == 0) wrreg(pp, Rpc, vcode(atoi(buf+3))|Fautopower|Foutena|Fcardena); break; | |
| 1994/1209 | case Qmem: case Qattr: | |
| 1995/0222 | pp = slot + SLOTNO(c); | |
| 1995/0519/sys/src/9/pc/devi82365.c:665,687 – 1995/0726/sys/src/9/pc/devi82365.c:665,684 (short | long) | ||
| 1994/1209 | } void | |
| 1995/0726 | i82365create(Chan*, char*, int, ulong) | |
| 1994/1209 | { | |
| 1995/0726 | i82365remove(Chan*) | |
| 1994/1209 | { | |
| 1995/0726 | i82365wstat(Chan*, char*) | |
| 1994/1209 | { | |
| 1995/0726/sys/src/9/pc/devi82365.c:277,282 – 1995/1006/sys/src/9/pc/devi82365.c:277,283 (short | long) | ||
| 1994/1209 | static void | |
| 1995/0222 | i82365intr(Ureg *ur, void *a) | |
| 1994/1209 | { | |
| 1995/1006 | int tries, changed; | |
| 1995/0222 | uchar csc, was; | |
| 1994/1209 | Slot *pp; | |
| 1995/0726/sys/src/9/pc/devi82365.c:284,301 – 1995/1006/sys/src/9/pc/devi82365.c:285,309 | ||
| 1995/0222 | if(slot == 0) return; | |
| 1994/1209 |
| |
| 1995/0222 |
| |
| 1994/1209 |
| |
| 1995/0222 |
| |
| 1994/1209 |
| |
| 1995/1006 | changed = 0; for(tries = 0; tries < 5; tries++){ for(pp = slot; pp < lastslot; pp++){ csc = rdreg(pp, Rcsc); was = pp->occupied; slotinfo(pp); if(csc & (1<<3) && was != pp->occupied){ changed++; if(pp->occupied) print("slot%d card inserted\n", pp->slotno); else { print("slot%d card removed\n", pp->slotno); slotdis(pp); } | |
| 1994/1209 | } } | |
| 1995/1006 | if(changed) break; delay(100); | |
| 1994/1209 | } } | |
| 1995/1006/sys/src/9/pc/devi82365.c:277,283 – 1995/1007/sys/src/9/pc/devi82365.c:277,282 (short | long) | ||
| 1994/1209 | static void | |
| 1995/0222 | i82365intr(Ureg *ur, void *a) | |
| 1994/1209 | { | |
| 1995/1006 |
| |
| 1995/0222 | uchar csc, was; | |
| 1994/1209 | Slot *pp; | |
| 1995/1006/sys/src/9/pc/devi82365.c:285,309 – 1995/1007/sys/src/9/pc/devi82365.c:284,301 | ||
| 1995/0222 | if(slot == 0) return; | |
| 1995/1006 |
| |
| 1995/1007 | for(pp = slot; pp < lastslot; pp++){ csc = rdreg(pp, Rcsc); was = pp->occupied; slotinfo(pp); if(csc & (1<<3) && was != pp->occupied){ if(pp->occupied) print("slot%d card inserted\n", pp->slotno); else { print("slot%d card removed\n", pp->slotno); slotdis(pp); | |
| 1994/1209 | } } | |
| 1995/1006 |
| |
| 1994/1209 | } } | |
| 1995/1007/sys/src/9/pc/devi82365.c:538,549 – 1995/1017/sys/src/9/pc/devi82365.c:538,549 (short | long) | ||
| 1994/1209 | outb(x, Rchipinfo + (dev<<7)); outb(d, 0); c = inb(d); | |
| 1995/1017 | if((c & 0xc0) != 0xc0) break; c = inb(d); if((c & 0xc0) != 0x00) break; if(c & 0x20){ | |
| 1994/1209 | cp->type = Tpd6720; } else { cp->type = Tpd6710; | |
| 1995/1007/sys/src/9/pc/devi82365.c:907,913 – 1995/1017/sys/src/9/pc/devi82365.c:907,913 | ||
| 1994/1209 | { | |
| 1995/0225 | uchar we, x, *p; | |
| 1994/1209 | Slot *pp; | |
| 1995/0223 |
| |
| 1995/1017 | Conftab *ct, *et, *t; | |
| 1995/0225 | PCMmap *m; | |
| 1995/0401 | int irq; | |
| 1994/1209 | ||
| 1995/1007/sys/src/9/pc/devi82365.c:922,940 – 1995/1017/sys/src/9/pc/devi82365.c:922,959 | ||
| 1994/1209 | if(!pp->occupied) return -1; | |
| 1995/0223 |
| |
| 1995/0225 |
| |
| 1995/0401 |
| |
| 1995/0223 |
| |
| 1995/0225 |
| |
| 1995/1017 | et = &pp->ctab[pp->nctab]; | |
| 1995/0223 |
| |
| 1995/0401 |
| |
| 1995/1017 | /* assume default is right */ if(pp->def) ct = pp->def; else ct = pp->ctab; /* try for best match */ if(ct->nioregs == 0 || ct->port != isa->port || ((1<<irq) & ct->irqs) == 0){ for(t = pp->ctab; t < et; t++) if(t->nioregs && t->port == isa->port && ((1<<irq) & t->irqs)){ ct = t; | |
| 1995/0223 | break; | |
| 1995/1017 | } } if(ct->nioregs == 0 || ((1<<irq) & ct->irqs) == 0){ for(t = pp->ctab; t < et; t++) if(t->nioregs && ((1<<irq) & t->irqs)){ ct = t; break; } } if(ct->nioregs == 0){ for(t = pp->ctab; t < et; t++) if(t->nioregs){ ct = t; break; } } | |
| 1995/0223 |
| |
| 1995/1017 | if(ct == et || ct->nioregs == 0) | |
| 1994/1209 | return -1; | |
| 1995/0223 | /* route interrupts */ | |
| 1995/1017/sys/src/9/pc/devi82365.c:289,300 – 1995/1027/sys/src/9/pc/devi82365.c:289,296 (short | long) | ||
| 1995/1007 | was = pp->occupied; slotinfo(pp); if(csc & (1<<3) && was != pp->occupied){ | |
| 1995/1027 | if(!pp->occupied) | |
| 1995/1007 | slotdis(pp); | |
| 1994/1209 |
| |
| 1995/1027/sys/src/9/pc/devi82365.c:1265,1271 – 1995/1121/sys/src/9/pc/devi82365.c:1265,1271 (short | long) | ||
| 1994/1209 | } } | |
| 1995/1121 | static void | |
| 1994/1209 | tentry(Slot *pp, int ttype) { uchar c, i, feature; | |
| 1995/1027/sys/src/9/pc/devi82365.c:1338,1344 – 1995/1121/sys/src/9/pc/devi82365.c:1338,1344 | ||
| 1994/1209 | pp->configed++; | |
| 1995/0111 | } | |
| 1995/1121 | static void | |
| 1995/0111 | tvers1(Slot *pp, int ttype) { uchar c, major, minor; | |
| Too many diffs (26 > 25). Stopping. | ||