From 29767900ef1d5be30d064af05dbb8397679a498f Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Wed, 29 Mar 1995 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 1995-03-29 --- pc/devi82365.c | 87 ++++++++++++++++++++++++++++++----------------- pc/main.c | 2 +- pc/scsi.c | 28 +++++++++++---- pc/trap.c | 2 +- port/devns16552.c | 11 ++++-- port/devsd.c | 14 +++++++- port/portfns.h | 1 + port/proc.c | 1 + port/sysproc.c | 8 +++-- 9 files changed, 110 insertions(+), 44 deletions(-) diff --git a/pc/devi82365.c b/pc/devi82365.c index 980572d2c6836f68f625c958522e15376f6a48a6..fca55e92b515f0276211a5efb05a7f0c9dd8fb82 100644 --- a/pc/devi82365.c +++ b/pc/devi82365.c @@ -41,6 +41,9 @@ enum Rwe= 0x6, /* address window enable */ Fmem16= (1<<5), /* use A23-A12 to decode address */ Rio= 0x7, /* I/O control */ + Fwidth16= (1<<0), /* 16 bit data width */ + Fiocs16= (1<<1), /* IOCS16 determines data width */ + Ftiming= (1<<3), /* timing register to use */ 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 */ @@ -126,6 +129,7 @@ struct Conftab int index; ushort irqs; /* legal irqs */ ushort port; /* port address */ + uchar irqtype; uchar nioregs; /* number of io registers */ uchar bit16; /* true for 16 bit access */ uchar vpp1; @@ -239,11 +243,17 @@ slotena(Slot *pp) if(pp->enabled) return; - /* power up and reset, wait's are empirical (???) */ + /* power up and unreset, wait's are empirical (???) */ + wrreg(pp, Rpc, Fautopower|Foutena|Fcardena); + delay(300); + wrreg(pp, Rigc, Fnotreset); + delay(500); + + wrreg(pp, Rpc, 0); + delay(500); + wrreg(pp, Rpc, Fautopower|Foutena|Fcardena); delay(300); - wrreg(pp, Rigc, 0); - delay(100); wrreg(pp, Rigc, Fnotreset); delay(500); @@ -253,7 +263,7 @@ slotena(Slot *pp) cisread(pp); pp->enabled = 1; } else - wrreg(pp, Rpc, Fautopower); + wrreg(pp, Rpc, 0); } /* @@ -262,8 +272,8 @@ slotena(Slot *pp) static void slotdis(Slot *pp) { - wrreg(pp, Rpc, Fautopower); /* turn off card */ - wrreg(pp, Rwe, 0); /* no windows */ + wrreg(pp, Rwe, 0); /* no windows */ + wrreg(pp, Rpc, 0); /* turn off card power */ pp->enabled = 0; } @@ -606,10 +616,7 @@ i82365reset(void) pp->memlen = 64*MB; pp->base = (cp->dev<<7) | (j<<6); pp->cp = cp; -if(pp == slot)i82365dump(pp); -/* slotdis(pp); -*/ /* interrupt on status change */ wrreg(pp, Rcscic, ((PCMCIAvec-Int0vec)<<4) | Fchangeena); @@ -796,6 +803,16 @@ i82365read(Chan *c, void *a, long n, ulong offset) if(pp->busy) cp += sprint(cp, "busy\n"); cp += sprint(cp, "battery lvl %d\n", pp->battery); +{ + 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"); +} *cp = 0; return readstr(offset, a, n, buf); default: @@ -915,13 +932,16 @@ pcmio(int slotno, ISAConf *isa) isa->irq = 9; wrreg(pp, Rigc, isa->irq | Fnotreset | Fiocard); - /* set power and enable slotnoice */ + /* set power and enable device */ x = vcode(ct->vpp1); wrreg(pp, Rpc, x|Fautopower|Foutena|Fcardena); /* 16-bit data path */ if(ct->bit16) - wrreg(pp, Rio, (1<<0)|(1<<1)); + x = Fiocs16|Fwidth16; + else + x = 0; + wrreg(pp, Rio, Ftiming|x); /* enable io port map 0 */ if(isa->port == 0) @@ -929,8 +949,8 @@ pcmio(int slotno, ISAConf *isa) we = rdreg(pp, Rwe); wrreg(pp, Riobtm0lo, isa->port); wrreg(pp, Riobtm0hi, isa->port>>8); - wrreg(pp, Riotop0lo, (isa->port+ct->nioregs)); - wrreg(pp, Riotop0hi, (isa->port+ct->nioregs)>>8); + wrreg(pp, Riotop0lo, (isa->port+ct->nioregs-1)); + wrreg(pp, Riotop0hi, (isa->port+ct->nioregs-1)>>8); wrreg(pp, Rwe, we | (1<<6)); /* only touch Rconfig if it is present */ @@ -938,21 +958,14 @@ pcmio(int slotno, ISAConf *isa) /* Reset adapter */ m = pcmmap(slotno, pp->caddr + Rconfig, 1, 1); p = (uchar*)(KZERO|(m->isa + pp->caddr + Rconfig - m->ca)); -if(strstr(pp->verstr, "KeepInTouch") == 0){ - *p = Creset; - delay(5); - *p = 0; - delay(5); -} - /* set configuration */ -if(strstr(pp->verstr, "KeepInTouch") == 0){ - if(isa->irq > 7) - *p = Clevel | ct->index; - else - *p = ct->index; + /* 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; delay(5); -} else i82365dump(pp); + pcmunmap(slotno, m); } return 0; @@ -1066,15 +1079,26 @@ microvolt(Slot *pp) { uchar c; ulong microvolts; + ulong exp; if(readc(pp, &c) != 1) return 0; - microvolts = vexp[c&0x7]*vmant[(c>>3)&0xf]; + exp = vexp[c&0x7]; + microvolts = vmant[(c>>3)&0xf]*exp; while(c & 0x80){ if(readc(pp, &c) != 1) return 0; - if(c == 0x7d || c == 0x7e || c == 0x7f) - microvolts = 0; + 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); + } } return microvolts; } @@ -1121,7 +1145,7 @@ power(Slot *pp) nanoamps(pp); if(feature & 0x20) nanoamps(pp); - if(feature & 0x20) + if(feature & 0x40) nanoamps(pp); return mv/1000000; } @@ -1195,6 +1219,7 @@ irq(Slot *pp, Conftab *ct) if(readc(pp, &c) != 1) return; + ct->irqtype = c & 0xe0; if(c & 0x10) ct->irqs = getlong(pp, 2); else @@ -1271,7 +1296,7 @@ tentry(Slot *pp, int ttype) iospaces(pp, ct); if(feature&0x10) irq(pp, ct); - switch(feature&0x3){ + switch((feature>>5)&0x3){ case 1: memspace(pp, 0, 2, 0); break; diff --git a/pc/main.c b/pc/main.c index 34b31f8e35b9ddc9b77c080545fb99ce091f1218..b23d33cb633985d19901fc647255d2ddef10ef7a 100644 --- a/pc/main.c +++ b/pc/main.c @@ -59,8 +59,8 @@ main(void) kbdinit(); procinit0(); initseg(); - links(); printcpufreq(); + links(); chandevreset(); swapinit(); userinit(); diff --git a/pc/scsi.c b/pc/scsi.c index f09e6a43b407a35df7761ab4ab306746b5f1a2ef..7b2f2c4906590c9b4bb9fa8225b7ed60a0f0c4e8 100644 --- a/pc/scsi.c +++ b/pc/scsi.c @@ -12,8 +12,14 @@ enum { Ninq = 255, Nscratch = 255, + CMDtest = 0x00, CMDreqsense = 0x03, + CMDread6 = 0x08, + CMDwrite6 = 0x0A, CMDinquire = 0x12, + CMDstart = 0x1B, + CMDread10 = 0x28, + CMDwrite10 = 0x2A, }; typedef struct { @@ -142,14 +148,12 @@ scsiprobe(Ctlr *ctlr) } /* - * Inquire to find out what the device is + * Inquire to find out what the device is. * Drivers then use the result to attach to targets */ memset(t->inq, 0, Ninq); - cmd[0] = CMDinquire; - cmd[4] = Ninq; nbytes = Ninq; - s = scsiexec(t, SCSIread, cmd, sizeof(cmd), t->inq, &nbytes); + s = scsiinquiry(t, 0, t->inq, &nbytes); if(s < 0) { print("scsi%d: unit %d inquire failed, status %d\n", t->ctlrno, i, s); continue; @@ -196,7 +200,7 @@ scsiinv(int devno, int type, Target **rt, uchar **inq, char *id) t = &scsi[ctlr]->target[unit]; devno++; - if(t->ok && (t->inq[0]&0x0F) == type){ + if(t->ok && (t->inq[0]&0x1F) == type){ *rt = t; *inq = t->inq; sprint(id, "scsi%d: unit %d", ctlr, unit); @@ -212,12 +216,24 @@ scsistart(Target *t, char lun, int s) uchar cmd[6]; memset(cmd, 0, sizeof cmd); - cmd[0] = 0x1b; + cmd[0] = CMDstart; cmd[1] = lun<<5; cmd[4] = s ? 1 : 0; return scsiexec(t, SCSIread, cmd, sizeof(cmd), 0, 0); } +int +scsiinquiry(Target *t, char lun, void *data, int *datalen) +{ + uchar cmd[6]; + + memset(cmd, 0, sizeof cmd); + cmd[0] = CMDinquire; + cmd[1] = lun<<5; + cmd[4] = *datalen; + return scsiexec(t, SCSIread, cmd, sizeof(cmd), data, datalen); +} + int scsicap(Target *t, char lun, ulong *size, ulong *bsize) { diff --git a/pc/trap.c b/pc/trap.c index 9f9c7bbcf9fbbc512caf435a58b2d6e06c105f3f..9e01d3abbc26efe6654ff90fbc4c26de8827cf0a 100644 --- a/pc/trap.c +++ b/pc/trap.c @@ -199,7 +199,7 @@ trapinit(void) /* * Set up the second 8259 interrupt processor. * Make 8259 interrupts start at CPU vector Int1vec. - * Set the 8259 as master with level triggered + * Set the 8259 as master with edge triggered * input with fully nested interrupts. */ outb(Int1ctl, (1<<4)|(1<<3)|(1<<0)); /* ICW1 - master, level triggered, diff --git a/port/devns16552.c b/port/devns16552.c index 12f139f57020ff002cbb07a4f981328eec42fd7e..60eca811ea2f47dc3da098d0a638b12eb7e7abd7 100644 --- a/port/devns16552.c +++ b/port/devns16552.c @@ -414,7 +414,8 @@ ns16552kick(Uart *p) x = splhi(); lock(&p->plock); if(p->printing == 0 || (uartrdreg(p, Lstat) & Outready)) - if(p->cts && p->blocked == 0){ + if(p->cts && p->blocked == 0) + if(p->op < p->oe || stageoutput(p)){ n = 0; while((uartrdreg(p, Lstat) & Outready) == 0){ if(++n > 100000){ @@ -423,9 +424,9 @@ ns16552kick(Uart *p) } } do{ + outb(p->port + Data, *(p->op++)); if(p->op >= p->oe && stageoutput(p) == 0) break; - outb(p->port + Data, *(p->op++)); }while(uartrdreg(p, Lstat) & Outready); } unlock(&p->plock); @@ -813,6 +814,12 @@ uartstatus(Chan *c, Uart *p, void *buf, long n, long offset) strcat(str, " dtr"); if(tstat & Rts) strcat(str, " rts"); +{ +int i, j; + +i = strlen(str); +for(j = 0; j < 8; j++) i+=sprint(str+i, " %ux", uartrdreg(p, j)); +} strcat(str, "\n"); return readstr(offset, buf, n, str); } diff --git a/port/devsd.c b/port/devsd.c index c2439bafbcaf8e202755b60d72232c45e2401c58..92ca00a1cd93b52a081352147f2d2266c7291e8b 100644 --- a/port/devsd.c +++ b/port/devsd.c @@ -87,7 +87,8 @@ sdinit(void) { Disk *d; ulong s, b; - int dev, i; + uchar inq[255]; + int dev, i, nbytes; dev = 0; for(;;) { @@ -102,8 +103,19 @@ sdinit(void) /* Search for other lun's */ for(i = 0; i < Nlun; i++) { d->lun = i; + scsireqsense(d->t, d->lun, 1); + /* + * A SCSI target does not support a lun if the + * the peripheral device type and qualifier fields + * in the response to an inquiry command are 0x7F. + */ + memset(inq, 0, sizeof(inq)); + nbytes = sizeof(inq); + if(scsiinquiry(d->t, d->lun, inq, &nbytes) != STok || inq[0] == 0x7F) + continue; + /* NCR Raid only seems to answer second capacity * command if lun != 0 */ diff --git a/port/portfns.h b/port/portfns.h index ce3bade66d038aa96d8db22cb2814e30c838013f..0b6e62a405cff34e65fa9c890861962b035638a7 100644 --- a/port/portfns.h +++ b/port/portfns.h @@ -239,6 +239,7 @@ int scsibio(Target*, char, int, void*, long, long, long); int scsicap(Target*, char, ulong*, ulong*); int scsiexec(Target*, int, uchar*, int, void*, int*); #define scsifree(p) free(p) +int scsiinquiry(Target*, char, void*, int*); int scsiinv(int, int, Target**, uchar**, char*); int scsireqsense(Target*, char, int); int scsistart(Target*, char, int); diff --git a/port/proc.c b/port/proc.c index 0b38830e2c012605d5514af283f5594725959037..0a6b7b30176c56e9d39a14506f43d30591661c6f 100644 --- a/port/proc.c +++ b/port/proc.c @@ -666,6 +666,7 @@ pexit(char *exitstr, int freemem) if(exitstr && exitstr[0]){ n = sprint(wq->w.msg, "%s %d:", up->text, up->pid); strncpy(wq->w.msg+n, exitstr, ERRLEN-n); + wq->w.msg[ERRLEN-1] = 0; } else wq->w.msg[0] = '\0'; diff --git a/port/sysproc.c b/port/sysproc.c index ddc7f4241081fb6c34b0ce8a58ec7ef6493f6870..84113ddc8c4eb33c2b32084bd4d84cb64d45c6b0 100644 --- a/port/sysproc.c +++ b/port/sysproc.c @@ -486,6 +486,7 @@ sysexits(ulong *arg) { char *status; char *inval = "invalid exit string"; + char buf[ERRLEN]; status = (char*)arg[0]; if(status){ @@ -493,8 +494,11 @@ sysexits(ulong *arg) status = inval; else{ validaddr((ulong)status, 1, 0); - if(vmemchr(status, 0, ERRLEN) == 0) - status = inval; + if(vmemchr(status, 0, ERRLEN) == 0){ + memmove(buf, status, ERRLEN); + buf[ERRLEN-1] = 0; + status = buf; + } } poperror();