## diffname pc/devhard.c 1991/0802 ## diff -e /dev/null /n/bootesdump/1991/0802/sys/src/9/safari/devhard.c 0a #include "u.h" #include "lib.h" #include "mem.h" #include "dat.h" #include "fns.h" #include "io.h" #include "errno.h" typedef struct Drive Drive; typedef struct Ident Ident; typedef struct Controller Controller; enum { /* ports */ Pbase= 0x10, Pdata= Pbase+0, /* data port (16 bits) */ Perror= Pbase+1, /* error port */ Pcount= Pbase+2, /* sector count port */ Psector= Pbase+3, /* sector number port */ Pcyllsb= Pbase+4, /* least significant byte cylinder # */ Pcylmsb= Pbase+5, /* most significant byte cylinder # */ Pdh= Pbase+6, /* drive/head port */ Pstatus= Pbase+7, /* status port */ Pcmd= Pbase+7, /* cmd port */ /* commands */ Crecal= 0x10, Cread= 0x20, Cwrite= 0x30, Cident= 0xEC, /* file types */ Qdir= 0, Qdata= (1<<1), Qstruct= (2<<1), Qmask= (3<<1), }; /* * ident sector from drive */ struct Ident { ushort magic; /* must be 0x0A5A */ ushort lcyls; /* logical number of cylinders */ ushort rcyl; /* number of removable cylinders */ ushort lheads; /* logical number of heads */ ushort b2t; /* unformatted bytes/track */ ushort b2s; /* unformated bytes/sector */ ushort ls2t; /* logical sectors/track */ ushort gap; /* bytes in inter-sector gaps */ ushort sync; /* bytes in sync fields */ ushort magic2; /* must be 0x0000 */ ushort serial[10]; /* serial number */ ushort type; /* controller type (0x0003) */ ushort bsize; /* buffer size/512 */ ushort ecc; /* ecc bytes returned by read long */ ushort firm[4]; /* firmware revision */ ushort model[20]; /* model number */ ushort s2i; /* number of sectors/interrupt */ ushort dwtf; /* double word transfer flag */ ushort alernate; ushort piomode; ushort dmamode; ushort reserved[76]; ushort ncyls; /* native number of cylinders */ ushort nheads; /* native number of heads, sectors */ ushort dlcyls; /* default logical number of cyinders */ ushort dlheads; /* default logical number of heads, sectors */ ushort interface; ushort power; /* 0xFFFF if power commands supported */ ushort flags; ushort ageprog; /* MSB = age, LSB = program */ ushort reserved2[120]; }; /* * a hard drive */ struct Drive { int dev; ulong cap; /* drive capacity */ int bytes; /* bytes/sector */ int cyl; /* current cylinder */ int confused; /* needs to be recalibrated (or worse) */ int tcyl; /* target cylinder */ int thead; /* target head */ int tsec; /* target sector */ long len; /* size of xfer */ Ident id; }; /* * a controller for 2 drives */ struct Controller { QLock; /* exclusive access to the drive */ int intr; /* true if interrupt occured */ Rendez r; /* wait here for command termination */ int confused; /* needs to be recalibrated (or worse) */ Drive d[2]; }; Controller hard; Dirtab harddir[]={ "hddata", {Qdata}, 0, 0600, "hdstruct", {Qstruct}, 8, 0600, }; #define NHDIR (sizeof(harddir)/sizeof(Dirtab)) void hardreset(void) { hard.d[0].dev = 0; hard.d[1].dev = 1; setvec(Hardvec, hardintr); } void hardinit(void) { } Chan* hardattach(char *spec) { return devattach('f', spec); } Chan* hardclone(Chan *c, Chan *nc) { return devclone(c, nc); } int hardwalk(Chan *c, char *name) { return devwalk(c, name, harddir, NHDIR, devgen); } void hardstat(Chan *c, char *dp) { devstat(c, dp, harddir, NHDIR, devgen); } Chan* hardopen(Chan *c, int omode) { return devopen(c, omode, harddir, NHDIR, devgen); } void hardcreate(Chan *c, char *name, int omode, ulong perm) { error(Eperm); } void hardclose(Chan *c) { } void hardremove(Chan *c) { error(Eperm); } void hardwstat(Chan *c, char *dp) { error(Eperm); } static void ul2user(uchar *a, ulong x) { a[0] = x >> 24; a[1] = x >> 16; a[2] = x >> 8; a[3] = x; } long hardread(Chan *c, void *a, long n) { Drive *dp; long rv, i; uchar *aa = a; if(c->qid.path == CHDIR) return devdirread(c, a, n, harddir, NHDIR, devgen); rv = 0; dp = &hard.d[c->qid.path & ~Qmask]; switch ((int)(c->qid.path & Qmask)) { case Qdata: for(rv = 0; rv < n; rv += i){ i = hardxfer(dp, Fread, aa+rv, c->offset+rv, n-rv); if(i <= 0) break; } break; case Qstruct: hardident(dp); if (n < 2*sizeof(ulong)) error(Ebadarg); if (c->offset >= 2*sizeof(ulong)) return 0; rv = 2*sizeof(ulong); ul2user((uchar*)a, dp->cap); ul2user((uchar*)a+sizeof(ulong), dp->bytes); break; default: panic("hardread: bad qid"); } return rv; } long hardwrite(Chan *c, void *a, long n) { Drive *dp; long rv, i; uchar *aa = a; rv = 0; dp = &hard.d[c->qid.path & ~Qmask]; switch ((int)(c->qid.path & Qmask)) { case Qdata: for(rv = 0; rv < n; rv += i){ i = hardxfer(dp, Fwrite, aa+rv, c->offset+rv, n-rv); if(i <= 0) break; } break; case Qstruct: error(Eperm); break; default: panic("hardwrite: bad qid"); } return rv; } /* * did an interrupt happen? */ static int interrupted(Drive *dp) { return hard.intr; } /* * get parameters from the drive */ hardident(Drive *dp) { hard.intr = 0; outb(Pdh, dp->dev<<4); outb(Pcmd, Cident); } long hardxfer(Drive *dp, int cmd, void *va, long off, long len) { errors("not implemented"); } . ## diffname pc/devhard.c 1991/0803 ## diff -e /n/bootesdump/1991/0802/sys/src/9/safari/devhard.c /n/bootesdump/1991/0803/sys/src/9/safari/devhard.c 278a } /* * take/clear a disk interrupt */ static void hardintr(Ureg *ur) { hard.status = inb(Pstatus); hard.intr = 1; print("hardintr\n"); wakeup(&hard.r); . 275c static long . 272a sleep(&hard.r, interrupted, 0); insw(Pdata, &hard.id, 512); qunlock(&hard); . 269a qlock(&hard); . 267a static long . 260c interrupted(void *a) . 215a dp->cap = 512 * dp->id->lcyls * dp->id->lheads *dp->id->ls2t; dp->bytes = 512; . 118a static void hardintr(Ureg*); static long hardxfer(Drive*, int, void*, long, long); static long hardident(Drive*); . ## diffname pc/devhard.c 1991/0809 ## diff -e /n/bootesdump/1991/0803/sys/src/9/safari/devhard.c /n/bootesdump/1991/0809/sys/src/9/safari/devhard.c 301a } /* * calculate physical address of a logical byte offset into the disk * * truncate dp->len if it crosses a cylinder boundary */ static void hardpos(Drive *dp, long off) { int lsec; int end; int cyl; lsec = off/dp->bytes; dp->tcyl = lsec/(dp->sectors*dp->heads); dp->tsec = (lsec % dp->sectors) + 1; dp->thead = (lsec/dp->sectors) % dp->heads; /* * can't read across cylinder boundaries. * if so, decrement the bytes to be read. */ lsec = (off+dp->len)/dp->bytes; cyl = lsec/(dp->sectors*dp->heads); if(cyl != dp->tcyl){ dp->len -= (lsec % dp->sectors)*dp->bytes; dp->len -= ((lsec/dp->sectors) % dp->heads)*dp->bytes*dp->sectors; } . 300c print("hardintr\n"); . 298a if(hard.status & Sbusy) panic("disk busy"); . 289c int secs; int i; uchar *aa = va; if(off % dp->bytes) errors("bad offset"); if(len % dp->bytes) errors("bad length"); if(waserror()){ qunlock(&hard); nexterror(); } qlock(&hard); dp->len = len; hardpos(dp, off); secs = dp->len/dp->bytes; outb(Pcount, secs); outb(Psector, dp->tsec); outb(Pdh, (1<<5) | (dp->dev<<4) | dp->thead); outb(Pcyllsb, dp->tcyl); outb(Pcylmsb, dp->tcyl>>8); outb(Pcmd, cmd); if(cmd == Cwrite) outss(Pdata, aa, dp->bytes/2); for(i = 0; i < secs; i++){ hard.intr = 0; sleep(&hard.r, interrupted, 0); if(hard.status & Serr) errors("disk error"); if(cmd == Cread){ if((hard.status & Sdrq) == 0) panic("disk read"); inss(Pdata, aa + i*dp->bytes, dp->bytes/2); } else { if((hard.status & Sdrq) == 0){ if(i+1 != secs) panic("disk write"); } else outss(Pdata, aa + (i+1)*dp->bytes, dp->bytes/2); } } qunlock(&hard); . 282,283c print("getting hard drive ident\n"); inss(Pdata, &hard.id, 512/2); print(" magic %lux lcyls %d rcyl %d lheads %d b2t %d b2s %d ls2t %d\n", hard.id.magic, hard.id.lcyls, hard.id.rcyl, hard.id.lheads, hard.id.b2t, hard.id.b2s, hard.id.ls2t); . 280a print("waiting for hard drive interupt\n"); . 277c print("identify hard drive\n"); . 248c i = hardxfer(dp, Cwrite, aa+rv, c->offset+rv, n-rv); . 219,221d 213c i = hardxfer(dp, Cread, aa+rv, c->offset+rv, n-rv); . 138a Drive *dp; qlock(&hard); for(dp = hard.d; dp < &hard.d[conf.nhard]; dp++){ if(!waserror()){ hardident(dp); dp->cyl = hard.id.lcyls; dp->heads = hard.id.lheads; dp->sectors = hard.id.ls2t; dp->bytes = 512; dp->cap = dp->bytes * dp->cyl * dp->heads * dp->sectors; dp->online = 1; } } . 133a qunlock(&hard); . 126,127c Drive *dp; hard.d = ialloc(conf.nhard * sizeof(Drive), 0); for(dp = hard.d; dp < &hard.d[conf.nhard]; dp++){ dp->dev = dp - hard.d; dp->online = 0; } . 121a static void hardpos(Drive*, long); . 108c Drive *d; Ident id; . 104a int status; /* status of last interupt */ . 93,94d 86,87c int sectors; /* sectors/track */ int heads; /* heads/cyl */ long cyl; /* cylinders/drive */ . 83a int confused; /* needs to be recalibrated (or worse) */ int online; . 24a Sbusy= (1<<7), Sready= (1<<6), Sdrq= (1<<5), Serr= (1<<0), . ## diffname pc/devhard.c 1991/0810 ## diff -e /n/bootesdump/1991/0809/sys/src/9/safari/devhard.c /n/bootesdump/1991/0810/sys/src/9/safari/devhard.c 377d 312,314d 310d 308d 304d 169c qunlock(&hard); return devattach('h', spec); . 166a poperror(); . 16c Pbase= 0x1F0, . ## diffname pc/devhard.c 1991/0811 ## diff -e /n/bootesdump/1991/0810/sys/src/9/safari/devhard.c /n/bootesdump/1991/0811/sys/src/9/safari/devhard.c 404d 402a wakeup(&cp->r); . 397,401c cp = &hardc[0]; cp->status = inb(cp->pbase+Pstatus); switch(cp->cmd){ case Cwrite: if(cp->status & Serr){ cp->cmd = 0; cp->error = inb(cp->pbase+Perror); wakeup(&cp->r); return; } cp->sofar++; if(cp->sofar != cp->secs){ while((inb(cp->pbase+Pstatus) & Sdrq) == 0) ; outss(cp->pbase+Pdata, &cp->buf[cp->sofar*cp->dp->bytes], cp->dp->bytes/2); } else{ cp->cmd = 0; wakeup(&cp->r); } break; case Cread: case Cident: if(cp->status & Serr){ cp->cmd = 0; cp->error = inb(cp->pbase+Perror); wakeup(&cp->r); return; } while((inb(cp->pbase+Pstatus) & Sdrq) == 0) ; inss(cp->pbase+Pdata, &cp->buf[cp->sofar*cp->dp->bytes], cp->dp->bytes/2); cp->sofar++; if(cp->sofar == cp->secs){ cp->cmd = 0; wakeup(&cp->r); } break; default: print("wierd disk interrupt\n"); break; . 394,395c * BUG!! if there is ever more than one controller, we need a way to * distinguish which interrupted . 392a cp->len = 512; cp->secs = 1; cp->sofar = 0; cp->cmd = Cident; outb(cp->pbase+Pdh, (1<<5) | dp->drive<<4); outb(cp->pbase+Pcmd, Cident); sleep(&cp->r, cmddone, cp); if(cp->status & Serr){ print("bad disk magic\n"); errors("disk I/O error"); } memmove(&dp->id, cp->buf, cp->len); if(dp->id.magic != 0xA5A){ print("bad disk magic\n"); errors("bad disk magic"); } if((dp->id.interface & 0x4000) == 0) print("lookaheads disabled\n"); poperror(); qunlock(cp); } /* * we get an interrupt for every sector transferred */ static void hardintr(Ureg *ur) { Controller *cp; . 388,391c cp = dp->cp; qlock(cp); if(waserror()){ qunlock(cp); nexterror(); } . 384,386c Controller *cp; . 381,382c static long hardident(Drive *dp) . 377,379c * get parameters from the drive . 369,373c Controller *cp = dp->cp; qlock(cp); if(waserror()){ qunlock(cp); nexterror(); } outb(cp->pbase+Pbmode, on ? 0xAA : 0x55); outb(cp->pbase+Pdh, (1<<5) | dp->drive<<4); outb(cp->pbase+Pcmd, Csetbuf); poperror(); qunlock(cp); . 367c hardsetbuf(Drive *dp, int on) . 364c * set read ahead mode (1 == on, 0 == off) . 360c sleep(&cp->r, cmddone, cp); if(cp->status & Serr){ print("hd%d err: status %lux, err %lux\n", dp-hard, cp->status, cp->error); print("\ttcyl %d, tsec %d, thead %d\n", cp->tcyl, cp->tsec, cp->thead); print("\tsecs %d, sofar %d\n", cp->secs, cp->sofar); errors("disk I/O error"); } if(cmd == Cread) memmove(va, cp->buf, cp->len); poperror(); qunlock(cp); return cp->len; . 341,358c /* * can't xfer across cylinder boundaries. */ lsec = (off+len)/dp->bytes; cyl = lsec/(dp->sectors*dp->heads); if(cyl == cp->tcyl) cp->len = len; else cp->len = cyl*dp->sectors*dp->heads*dp->bytes - off; /* * wait for the controller to accept commands */ while(inb(cp->pbase+Pstatus) & Sbusy) ; /* * start the transfer */ cp->secs = cp->len/dp->bytes; cp->sofar = 0; cp->cmd = cmd; outb(cp->pbase+Pcount, cp->secs); outb(cp->pbase+Psector, cp->tsec); outb(cp->pbase+Pdh, (1<<5) | (dp->drive<<4) | cp->thead); outb(cp->pbase+Pcyllsb, cp->tcyl); outb(cp->pbase+Pcylmsb, cp->tcyl>>8); outb(cp->pbase+Pcmd, cmd); if(cmd == Cwrite){ memmove(cp->buf, va, cp->len); outss(Pdata, cp->buf, dp->bytes/2); . 334,339c /* * calculate the physical address of off */ lsec = off/dp->bytes; cp->tcyl = lsec/(dp->sectors*dp->heads); cp->tsec = (lsec % dp->sectors) + 1; cp->thead = (lsec/dp->sectors) % dp->heads; . 329,332d 326c qunlock(cp); . 324a cp = dp->cp; qlock(cp); . 323c errors("bad length"); /* BUG - this shouldn't be a problem */ if(off % dp->bytes) errors("bad offset"); /* BUG - this shouldn't be a problem */ . 320,321c if(dp->online == 0) errors("disk offline"); . 316,318c Controller *cp; int err; int lsec; int cyl; . 304,313d 301c * start a disk transfer. hardintr will performa all the iterative * parts. . 297c Controller *cp; return cp->cmd == 0; . 295c cmddone(void *a) . 273c dp = &hard[c->qid.path & ~Qmask]; . 241c dp = &hard[c->qid.path & ~Qmask]; . 238c return devdirread(c, a, n, harddir, conf.nhard*NHDIR, devgen); . 195c return devopen(c, omode, harddir, conf.nhard*NHDIR, devgen); . 189c devstat(c, dp, harddir, conf.nhard*NHDIR, devgen); . 183c return devwalk(c, name, harddir, conf.nhard*NHDIR, devgen); . 170c . 168c } else dp->online = 0; . 165a harddir[NHDIR*dp->drive].length = dp->cap; print("drive %d online\n", dp - hard); . 161,163c dp->cyl = dp->id.lcyls; dp->heads = dp->id.lheads; dp->sectors = dp->id.ls2t; . 159a hardsetbuf(dp, 1); . 157,158c for(dp = hard; dp < &hard[conf.nhard]; dp++){ . 151a /* * Get the characteristics of each drive. Mark unresponsive ones * off line. */ . 149d 142,143d 140a dp->cp = cp; if((drive&1) == 0){ cp->buf = ialloc(Maxxfer, 0); cp->cmd = 0; cp->pbase = Pbase + (cp-hardc)*8; /* BUG!! guessing */ setvec(Hardvec + (cp-hardc)*8, hardintr); /* BUG!! guessing */ } sprint(harddir[drive*2].name, "hd%ddata", drive); dir->length = 0; dir->qid.path = Qdata + drive; dir->perm = 0600; dir++; sprint(dir->name, "hd%dstruct", drive); dir->length = 8; dir->qid.path = Qstruct + drive; dir->perm = 0600; dir++; . 137,139c hard = ialloc(conf.nhard * sizeof(Drive), 0); hardc = ialloc(((conf.nhard+1)/2 + 1) * sizeof(Controller), 0); dir = harddir = ialloc(NHDIR * conf.nhard * sizeof(Dirtab), 0); for(drive = 0; drive < conf.nhard; drive++){ dp = &hard[drive]; cp = &hardc[drive/2]; dp->drive = drive&1; . 135a Controller *cp; int drive; Dirtab *dir; . 131a /* * we assume drives 0 and 1 are on the first controller, 2 and 3 on the * second, etc. */ . 130c static void hardsetbuf(Drive*, int); . 121,126d 119c Controller *hardc; Drive *hard; Dirtab *harddir; #define NHDIR 2 /* directory entries/drive */ . 115,116c /* * current operation */ int cmd; /* current command */ Rendez r; /* wait here for command termination */ char *buf; /* xfer buffer */ int tcyl; /* target cylinder */ int thead; /* target head */ int tsec; /* target sector */ int tbyte; /* target byte */ int len; /* length of transfer (bytes) */ int secs; /* sectors to be xferred */ int sofar; /* bytes transferred so far */ int status; int error; Drive *dp; /* drive being accessed */ . 113a int pbase; /* base port */ . 110,112d 97,100c Ident id; /* disk properties */ . 87c Controller *cp; int drive; . 39,41c Qdata= (1<<4), Qstruct= (2<<4), Qmask= (3<<4), Maxxfer= 4*1024, /* maximum transfer size/cmd */ . 35a Csetbuf= 0xEF, . 29c Pcmd= 7, /* cmd port (write) */ . 17,24c Pdata= 0, /* data port (16 bits) */ Perror= 1, /* error port (read) */ Pbmode= 1, /* buffer mode port (write) */ Pcount= 2, /* sector count port */ Psector= 3, /* sector number port */ Pcyllsb= 4, /* least significant byte cylinder # */ Pcylmsb= 5, /* most significant byte cylinder # */ Pdh= 6, /* drive/head port */ Pstatus= 7, /* status port (read) */ . ## diffname pc/devhard.c 1991/0812 ## diff -e /n/bootesdump/1991/0811/sys/src/9/safari/devhard.c /n/bootesdump/1991/0812/sys/src/9/safari/devhard.c 546d ## diffname pc/devhard.c 1991/0813 ## diff -e /n/bootesdump/1991/0812/sys/src/9/safari/devhard.c /n/bootesdump/1991/0813/sys/src/9/safari/devhard.c 533c if(++loop > 10000) panic("hardintr 2"); . 531a loop = 0; . 516c if(++loop > 10000) panic("hardintr 1"); . 496a long loop; . 490a * read partition table */ static void hardpart(Drive *dp) { Partition *pp; Ptable *pt; uchar buf[1024]; pp = &dp->p[0]; strcpy(pp->name, "disk"); pp->start = 0; pp->end = pp->cap / dp->bytes; qlock(dp->cp); hardxfer(dp, Cread, buf, pp->end - 1, dp->bytes); qunlock(dp->cp); } /* . 483,485d 469c cp->dp = dp; outb(cp->pbase+Pdh, (dp->drive<<4)); . 464a cmdreadywait(cp); . 445a sleep(&cp->r, cmddone, cp); . 442,443c cmdreadywait(cp); outb(cp->pbase+Pprecomp, on ? 0xAA : 0x55); outb(cp->pbase+Pdh, (dp->drive<<4)); . 404c outb(cp->pbase+Pdh, (dp->drive<<4) | cp->thead); . 401a cp->dp = dp; . 390,394c cmdreadywait(cp); . 346a * wait for the controller to be ready to accept a command */ static void cmdreadywait(Controller *cp) { long start; start = m->ticks; while((inb(cp->pbase+Pstatus) & (Sready|Sbusy)) != Sready) if(TK2MS(m->ticks - start) > 1){ print("cmdreadywait failed\n"); errors("disk not responding"); } } /* . 341c Controller *cp = a; . 208d 201a hardpart(dp); . 199a dp->bytes = 512; . 142a static int hardgen(Chan *c, Dirtab *tab, long ntab, long s, Dir *dirp) { Qid qid; int drive; char *name; Drive *dp; Partition *pp; ulong l; qid.vers = 0; drive = s/(Npart+1); s = s % (Npart+1); if(drive >= conf.nhard) return -1; dp = &hard[drive]; if(s == 0){ sprint(name, "hd%dparition", drive); qid.path = MKQID(Qpart, drive, 0); l = dp->npart * sizeof(Partition); } else if(s-1 < p.npart){ pp = &dp->p[s-1]; sprint(name, "hd%d%s", drive, pp->name); qid.path = MKQID(Qdata, drive, s-1); l = (pp->end - pp->start) * dp->cp->bytes; } else return 0; devdir(c, qid, name, l, 0600, dirp); return 1; } . 141a static void hardpart(Drive*); . 96c ulong cap; /* total bytes */ . 94a int npart; /* number of real partitions */ Partition p[Npart]; . 85a struct Partition { ulong start; ulong end; uchar name[NAMELEN]; }; struct Ptable { uchar magic[4]; /* ascii "disk" */ uchar n[4]; /* number of partitions */ struct { uchar start[4]; /* starting block */ uchar end[4]; /* ending block */ uchar name[NAMELEN]; } p[1]; }; . 46a #define PART(x) ((x)&0x3) #define DRIVE(x) (((x)>>3)&0x7) #define MKQID(t,d,p) ((t) | ((d)<<3) | (p)) . 45a Npart= 8+1, /* 8 sub partitions and one for the disk */ . 41,43c Qdata= (1<<(3+3)), Qpart= (2<<(3+3)), Qmask= (3<<(3+3)), . 28c Sdrq= (1<<3), . 19c Pprecomp= 1, /* buffer mode port (write) */ . 11a typedef struct Partition Partition; typedef struct Ptable Ptable; . ## diffname pc/devhard.c 1991/0814 ## diff -e /n/bootesdump/1991/0813/sys/src/9/safari/devhard.c /n/bootesdump/1991/0814/sys/src/9/safari/devhard.c 646c print("weird disk interrupt\n"); . 644a case Csetbuf: cp->cmd = 0; wakeup(&cp->r); break; . 583,586c if(waserror()){ print("error in hardpart\n"); nexterror(); } hardxfer(dp, pp, Cread, buf, (pp->end - 1)*dp->bytes, dp->bytes); buf[dp->bytes] = 0; n = getfields(buf, line, Npart+1, '\n'); if(strncmp(line[0], MAGIC, sizeof(MAGIC)-1) != 0){ print("bad partition table 1\n"); goto out; } for(i = 1; i < n; i++){ pp++; if(getfields(line[i], field, 3, 0) != 3){ print("bad partition field\n"); goto out; } if(strlen(field[0]) > NAMELEN){ print("bad partition name\n"); goto out; } strcpy(pp->name, field[0]); pp->start = strtoul(field[1], 0, 0); pp->end = strtoul(field[2], 0, 0); if(pp->start > pp->end || pp->start >= dp->p[0].end){ print("bad partition limit\n"); goto out; } print("partition %s from %d to %d\n", pp->name, pp->start, pp->end); dp->npart++; } out: poperror(); . 581c pp->end = dp->cap / dp->bytes; pp++; strcpy(pp->name, "partition"); pp->start = dp->p[0].end - 1; pp->end = dp->p[0].end; dp->npart = 2; . 575,576c char *line[Npart+1]; char *field[3]; char buf[1024]; ulong n; int i; . 570a #define MAGIC "plan9 partitions" . 569c * read partition table. The partition table is just ascii strings. . 538a print("waserror in hardident\n"); . 517a cp->cmd = Csetbuf; . 460a lsec += pp->start; if(lsec > pp->end) errors("xfer past end of partition\n"); . 452a lsec += pp->start; if(lsec >= pp->end) errors("xfer past end of partition\n"); . 441a print("hardxfer %ld %ld\n", off, len); print("hardxfer part %s %ld %ld\n", pp->name, pp->start, pp->end); . 428c hardxfer(Drive *dp, Partition *pp, int cmd, void *va, long off, long len) . 387,388c case Qpart: . 382c pp = &dp->p[PART(c->qid.path)]; i = hardxfer(dp, pp, Cwrite, aa+rv, c->offset+rv, n-rv); . 375a Partition *pp; . 355,362c case Qpart: . 350c pp = &dp->p[PART(c->qid.path)]; i = hardxfer(dp, pp, Cread, aa+rv, c->offset+rv, n-rv); . 343c return devdirread(c, a, n, 0, 0, hardgen); . 340a Partition *pp; . 326,334d 300c return devopen(c, omode, 0, 0, hardgen); . 294c devstat(c, dp, 0, 0, hardgen); . 288c return devwalk(c, name, 0, 0, hardgen); . 270a hardpart(dp); . 269d 263d 231,240d 217d 213d 202a . 195,196c qid.path = MKQID(Qdata, drive, s); l = (pp->end - pp->start) * dp->bytes; . 188,193c if(s < dp->npart){ pp = &dp->p[s]; . 182,183c drive = s/Npart; s = s % Npart; . 176c char name[NAMELEN]; . 166c static long hardxfer(Drive*, Partition*, int, void*, long, long); . 162,163d 99,110d 96c char name[NAMELEN+1]; . 48c Npart= 8+2, /* 8 sub partitions, disk, and partiiton */ . 13d ## diffname pc/devhard.c 1991/0815 ## diff -e /n/bootesdump/1991/0814/sys/src/9/safari/devhard.c /n/bootesdump/1991/0815/sys/src/9/safari/devhard.c 646,647c cp->sofar += cp->dp->bytes; if(cp->sofar >= cp->len){ . 513c cp->toskip = 0; . 437c cp->toskip = off % dp->bytes; . 422c lsec = (off+len+dp->bytes-1)/dp->bytes; . 420c * can't xfer across cylinder boundaries or end of disk . 398,400d 393,396c if(len > Maxxfer) len = Maxxfer; . 141a int toskip; /* bytes to skip over */ . 140c int toxfer; /* bytes to be xferred */ . ## diffname pc/devhard.c 1991/0817 ## diff -e /n/bootesdump/1991/0815/sys/src/9/safari/devhard.c /n/bootesdump/1991/0817/sys/src/9/safari/devhard.c 642,643c cp->sofar++; if(cp->sofar >= cp->nsecs){ . 621,622c outss(cp->pbase+Pdata, &cp->buf[cp->sofar*dp->bytes], dp->bytes/2); . 617c if(cp->sofar < cp->nsecs){ . 605a dp = cp->dp; . 598a Drive *dp; . 588a qunlock(cp); . 582c print("bad partition limit\n"); . 575c print("bad partition name\n"); . 571c print("bad partition field\n"); . 565c print("bad partition magic\n"); . 563c n = getfields(cp->buf, line, Npart+1, '\n'); . 560,561c hardxfer(dp, pp, Cread, 0, dp->bytes); cp->buf[dp->bytes-1] = 0; . 555a qunlock(cp); . 554a cp = dp->cp; qlock(cp); . 541d 538a Controller *cp; . 520c memmove(&dp->id, cp->buf, dp->bytes); . 508,509c cp->nsecs = 1; . 458,460c return cp->nsecs*dp->bytes; . 455,456d 452c print("\tnsecs %d, sofar %d\n", cp->nsecs, cp->sofar); . 448a . 447a . 445,446c loop = 0; while((inb(cp->pbase+Pstatus) & Sdrq) == 0) if(++loop > 10000) panic("hardxfer"); outss(cp->pbase+Pdata, cp->buf, dp->bytes/2); . 437c cp->sofar = 0; print("xfer:\ttcyl %d, tsec %d, thead %d\n", cp->tcyl, cp->tsec, cp->thead); print("\tnsecs %d, sofar %d\n", cp->nsecs, cp->sofar); outb(cp->pbase+Pcount, cp->nsecs); . 433,434d 418,426c if(lsec+len > pp->end) len = pp->end - lsec; cp->nsecs = len; . 416c * can't xfer past end of disk . 410c return 0; . 407,408c cp = dp->cp; lsec = start + pp->start; . 405c * calculate physical address . 397,403d 395a len = (len + dp->bytes - 1) / dp->bytes; . 393a /* * cut transfer size down to disk buffer size */ start = start / dp->bytes; . 390a int loop; . 389c long lsec; . 385c hardxfer(Drive *dp, Partition *pp, int cmd, long start, long len) . 381c * transfer a number of sectors. hardintr will perform all the iterative . 349a /* * if not starting on a sector boundary, * read in the first sector before writing * it out. */ i = c->offset % dp->bytes; if(i){ hardxfer(dp, pp, Cread, c->offset-i, dp->bytes); if(i+n > dp->bytes) rv = dp->bytes - i; else rv = n; memmove(cp->buf+i, aa, rv); hardxfer(dp, pp, Cwrite, c->offset-i, dp->bytes); } else rv = 0; /* * write out the full sectors */ for(; rv + dp->bytes <= n; rv += i){ i = n - rv; if(i > Maxxfer) i = Maxxfer; memmove(cp->buf, aa+rv, i); i = hardxfer(dp, pp, Cwrite, c->offset+rv, i); if(i == 0) break; } /* * if not ending on a sector boundary, * read in the last sector before writing * it out. */ if(n > rv){ hardxfer(dp, pp, Cread, c->offset+rv, dp->bytes); memmove(cp->buf, aa+rv, n - rv); hardxfer(dp, pp, Cwrite, c->offset+rv, dp->bytes); rv = n; } qunlock(cp); poperror(); . 334,348c if(c->qid.path == CHDIR) errors("can't write directory"); dp = &hard[DRIVE(c->qid.path)]; pp = &dp->p[PART(c->qid.path)]; cp = dp->cp; qlock(cp); if(waserror()){ qunlock(cp); nexterror(); . 332a Controller *cp; . 322a skip = c->offset % dp->bytes; for(rv = 0; rv < n; rv += i){ i = hardxfer(dp, pp, Cread, c->offset+rv-skip, n-rv+skip); if(i == 0) break; i -= skip; if(i > n - rv) i = n - rv; memmove(aa+rv, cp->buf + skip, i); skip = 0; } qunlock(cp); poperror(); . 307,321c dp = &hard[DRIVE(c->qid.path)]; pp = &dp->p[PART(c->qid.path)]; cp = dp->cp; qlock(cp); if(waserror()){ qunlock(cp); nexterror(); . 302a Controller *cp; . 300a int skip; . 177c qid.path = MKQID(drive, s); . 152c static long hardxfer(Drive*, Partition*, int, long, long); . 142d 139,140c int nsecs; /* length of transfer (sectors) */ . 51c #define MKQID(d,p) (((d)<<3) | (p)) . 42,44d ## diffname pc/devhard.c 1991/0818 ## diff -e /n/bootesdump/1991/0817/sys/src/9/safari/devhard.c /n/bootesdump/1991/0818/sys/src/9/safari/devhard.c 626c break; . 619c break; . 615c break; . ## diffname pc/devhard.c 1991/0819 ## diff -e /n/bootesdump/1991/0818/sys/src/9/safari/devhard.c /n/bootesdump/1991/0819/sys/src/9/safari/devhard.c 617,621c strncpy(pp->name, field[0], NAMELEN); . 605a /* * parse partition table. */ . 595,602c /* * read partition table from disk, null terminate */ . 584a cp = dp->cp; qlock(cp); if(waserror()){ qunlock(cp); print("error in hardpart\n"); nexterror(); } /* * we always have a partition for the whole disk * and one for the partition table */ . 475,476c /*print("xfer:\ttcyl %d, tsec %d, thead %d\n", cp->tcyl, cp->tsec, cp->thead); print("\tnsecs %d, sofar %d\n", cp->nsecs, cp->sofar);/**/ . 171a name[NAMELEN] = 0; . 157c char name[NAMELEN+4]; . ## diffname pc/devhard.c 1991/0820 ## diff -e /n/bootesdump/1991/0819/sys/src/9/safari/devhard.c /n/bootesdump/1991/0820/sys/src/9/safari/devhard.c 693,694c inss(cp->pbase+Pdata, &cp->buf[cp->sofar*dp->bytes], dp->bytes/2); . 635d 632d 624,625c if(getfields(line[i], field, 3, ' ') != 3){ . 619d 476c print("xfer:\ttcyl %d, tsec %d, thead %d\n", cp->tcyl, cp->tsec, cp->thead); . 391c rv += partial; . 389c memmove(cp->buf, aa+rv, partial); . 387c if(partial){ . 372c partial = (n - rv) % dp->bytes; n -= partial; for(; rv < n; rv += i){ . 364,365c memmove(cp->buf+partial, aa, rv); hardxfer(dp, pp, Cwrite, c->offset-partial, dp->bytes); . 357,361c partial = c->offset % dp->bytes; if(partial){ hardxfer(dp, pp, Cread, c->offset-partial, dp->bytes); if(partial+n > dp->bytes) rv = dp->bytes - partial; . 335c long rv, i, partial; . 321a {int j; print("0x%lux(%d) <- ", aa+rv, i); for(j = 0; j<32; j++) print("%.2ux ", cp->buf[j+skip]); print("\n"); } . ## diffname pc/devhard.c 1991/0821 ## diff -e /n/bootesdump/1991/0820/sys/src/9/safari/devhard.c /n/bootesdump/1991/0821/sys/src/9/safari/devhard.c 675a loop = 0; . 665c loop = 0; while((cp->status = inb(cp->pbase+Pstatus)) & Sbusy) if(++loop > 10000) panic("hardintr 0"); . 657a x = spllo(); /* let in other interrupts */ . 656a int x; . 485c cp->status = 0; /*print("xfer:\ttcyl %d, tsec %d, thead %d\n", cp->tcyl, cp->tsec, cp->thead); . 322,328d 177a pp = &dp->p[s]; sprint(name, "hd%d%s", drive, pp->name); name[NAMELEN] = 0; qid.path = MKQID(drive, s); l = (pp->end - pp->start) * dp->bytes; . 169,175c if(s >= dp->npart) . 46,48c #define PART(x) ((x)&0xF) #define DRIVE(x) (((x)>>4)&0x7) #define MKQID(d,p) (((d)<<4) | (p)) . 44c Npart= 8+2, /* 8 sub partitions, disk, and partition */ . ## diffname pc/devhard.c 1991/0906 ## diff -e /n/bootesdump/1991/0821/sys/src/9/safari/devhard.c /n/bootesdump/1991/0906/sys/src/9/safari/devhard.c 652c spllo(); /* let in other interrupts */ . 650d ## diffname pc/devhard.c 1991/0919 ## diff -e /n/bootesdump/1991/0906/sys/src/9/safari/devhard.c /n/bootesdump/1991/0919/sys/src/9/safari/devhard.c 177c devdir(c, qid, name, l, 0666, dirp); . ## diffname pc/devhard.c 1991/0921 ## diff -e /n/bootesdump/1991/0919/sys/src/9/safari/devhard.c /n/bootesdump/1991/0921/sys/src/9/safari/devhard.c 241c return devattach('w', spec); . ## diffname pc/devhard.c 1991/1109 ## diff -e /n/bootesdump/1991/0921/sys/src/9/safari/devhard.c /n/bootesdump/1991/1109/sys/src/9/safari/devhard.c 177c devdir(c, qid, name, l, eve, 0666, dirp); . ## diffname pc/devhard.c 1991/1211 ## diff -e /n/bootesdump/1991/1109/sys/src/9/safari/devhard.c /n/bootesdump/1991/1211/sys/src/9/safari/devhard.c 564,568d 560c print("bad disk ident status\n"); . 545d 229,231c switch(dp->id.magic){ case 0xA5A: /* conner drive on the AT&T NSX (safari) */ dp->cyl = dp->id.lcyls; dp->heads = dp->id.lheads; dp->sectors = dp->id.ls2t; break; case 0x324A: /* hard drive on the AT&T 6386 */ dp->cyl = dp->id.lcyls - 4; dp->heads = dp->id.lheads; dp->sectors = dp->id.ls2t - 1; break; default: print("unknown hard disk type\n"); errors("unknown hard disk type"); } . ## diffname pc/devhard.c 1992/0111 ## diff -e /n/bootesdump/1991/1211/sys/src/9/safari/devhard.c /n/bootesdump/1992/0111/sys/src/9/safari/devhard.c 7c #include "../port/error.h" . ## diffname pc/devhard.c 1992/0114 ## diff -e /n/bootesdump/1992/0111/sys/src/9/safari/devhard.c /n/bootesdump/1992/0114/sys/src/9/safari/devhard.c 572c error(Eio); . 513c error(Eio); . 453c error(Eio); . 435c error(Eio); . 352c error(Eisdir); . 242c error(Egreg); . ## diffname pc/devhard.c 1992/0219 ## diff -e /n/bootesdump/1992/0114/sys/src/9/safari/devhard.c /n/bootesdump/1992/0219/sys/src/9/safari/devhard.c 642d 634,640d 626,632c if(strncmp(line[0], MAGIC, sizeof(MAGIC)-1) == 0){ for(i = 1; i < n; i++){ pp++; if(getfields(line[i], field, 3, ' ') != 3) break; strncpy(pp->name, field[0], NAMELEN); pp->start = strtoul(field[1], 0, 0); pp->end = strtoul(field[2], 0, 0); if(pp->start > pp->end || pp->start >= dp->p[0].end) break; dp->npart++; . ## diffname pc/devhard.c 1992/0220 ## diff -e /n/bootesdump/1992/0219/sys/src/9/safari/devhard.c /n/bootesdump/1992/0220/sys/src/9/safari/devhard.c 460a if(cmd == Cread && len > Maxread) len = Maxread; . 43a Maxread= 1024, /* maximum transfer size/read */ . ## diffname pc/devhard.c 1992/0321 ## diff -e /n/bootesdump/1992/0220/sys/src/9/safari/devhard.c /n/bootesdump/1992/0321/sys/src/9/safari/devhard.c 2c #include "../port/lib.h" . ## diffname pc/devhard.c 1992/0402 ## diff -e /n/bootesdump/1992/0321/sys/src/9/safari/devhard.c /n/bootesdump/1992/0402/sys/src/9/safari/devhard.c 570c outb(cp->pbase+Pdh, 0x20 | (dp->drive<<4)); . 539,540c outb(cp->pbase+Pprecomp, on ? 0xAA : 0xFF); outb(cp->pbase+Pdh, 0x20 | (dp->drive<<4)); . 497c outb(cp->pbase+Pdh, 0x20 | (dp->drive<<4) | cp->thead); . 234a hardsetbuf(dp, 1); . 228c hardsetbuf(dp, 0); . ## diffname pc/devhard.c 1992/0423 ## diff -e /n/bootesdump/1992/0402/sys/src/9/safari/devhard.c /n/bootesdump/1992/0423/sys/src/9/safari/devhard.c 716c print("weird disk interrupt, cmd=%02x\n", cp->cmd); . 254c drivecomment=0; /* only the first time */ . 242,244c default: /* others: we hope this works */ if (drivecomment) { print("unknown hard disk type, magic=%04x\n", dp->id.magic); print(" lcyls=%d lheads=%d sectors=%d\n", dp->id.lcyls, dp->id.lheads, dp->id.ls2t); print(" ncyls=%d nheads=%d dlcyls=%d dlheads=%d\n", dp->id.ncyls, dp->id.nheads, dp->id.dlcyls, dp->id.dlheads); } dp->cyl = dp->id.lcyls; dp->heads = dp->id.lheads; dp->sectors = dp->id.ls2t; break; . 223a static int drivecomment=1; . 56c ushort magic; /* drive type magic */ . ## diffname pc/devhard.c 1992/0424 ## diff -e /n/bootesdump/1992/0423/sys/src/9/safari/devhard.c /n/bootesdump/1992/0424/sys/src/9/safari/devhard.c 728,729c print("weird disk interrupt, cmd=%02x, status=%02x\n", cp->cmd, cp->status); . 726a case 0: /* * These don't seem to mean anything. Should we wakeup? */ break; . 249,251d 247c print(" cyl=%d h=%d sec=%d\n", . 245c print("unknown hard disk type, magic=%04x", . ## diffname pc/devhard.c 1992/0425 ## diff -e /n/bootesdump/1992/0424/sys/src/9/safari/devhard.c /n/bootesdump/1992/0425/sys/src/9/safari/devhard.c 724,726c case 0: print("interrupt cmd=0, lastcmd=%02x status=%02x\n", cp->lastcmd, cp->status); . 720a cp->lastcmd = cp->cmd; . 715a cp->lastcmd = cp->cmd; . 710,711c if(++loop > 10000) { print("cmd=%lux status=%lux\n", cp->cmd, inb(cp->pbase+Pstatus)); panic("hardintr: read/ident"); } . 702a cp->lastcmd = cp->cmd; . 701a loop = 0; while((inb(cp->pbase+Pstatus) & Sbusy) != 0) if(++loop > 10000) { print("cmd=%lux status=%lux\n", cp->cmd, inb(cp->pbase+Pstatus)); panic("hardintr: wait busy"); } . 695a cp->lastcmd = cp->cmd; . 691,692c if(++loop > 10000) { print("cmd=%lux status=%lux\n", cp->cmd, inb(cp->pbase+Pstatus)); panic("hardintr: write"); } . 681a cp->lastcmd = cp->cmd; . 677,678c if(++loop > 10000) { print("cmd=%lux status=%lux\n", cp->cmd, inb(cp->pbase+Pstatus)); panic("hardintr: wait busy"); } . 203a cp->lastcmd = cp->cmd; . 130a int lastcmd; /* debugging info */ . ## diffname pc/devhard.c 1992/0429 ## diff -e /n/bootesdump/1992/0425/sys/src/9/safari/devhard.c /n/bootesdump/1992/0429/sys/src/9/safari/devhard.c 745a break; case Cident2: cp->lastcmd = cp->cmd; cp->cmd = 0; . 738c if (cp->cmd == Cread) cp->cmd = 0; else cp->cmd = Cident2; . 590c /* * this function appears to respond with an extra interrupt after * the indent information is read, except on the safari. The following * delay gives this extra interrupt a chance to happen while we are quiet. * Otherwise, the interrupt may come during a subsequent read or write, * causing a panic and much confusion. */ if (cp->cmd == Cident2) tsleep(&cp->r, return0, 0, 10); cp->cmd = 0; . 37a Cident2= 0xFF, /* pseudo command for post Cident interrupt */ . ## diffname pc/devhard.c 1992/0509 ## diff -e /n/bootesdump/1992/0429/sys/src/9/safari/devhard.c /n/bootesdump/1992/0509/sys/src/9/safari/devhard.c 663a if(dp->repl.p) hardreplinit(dp); . 656a if(strncmp(pp->name, "repl", NAMELEN) == 0) dp->repl.p = pp; . 651c if(strncmp(line[0], PARTMAGIC, sizeof(PARTMAGIC)-1) == 0){ . 641a * initialise the bad-block replacement info */ dp->repl.p = 0; /* . 608d 605a * Read block replacement table. * The table is just ascii block numbers. */ static void hardreplinit(Drive *dp) { Controller *cp; char *line[Nrepl+1]; char *field[1]; ulong n; int i; /* * check the partition is big enough */ if(dp->repl.p->end - dp->repl.p->start < Nrepl+1){ dp->repl.p = 0; return; } cp = dp->cp; /* * read replacement table from disk, null terminate */ hardxfer(dp, dp->repl.p, Cread, 0, dp->bytes); cp->buf[dp->bytes-1] = 0; /* * parse replacement table. */ n = getfields(cp->buf, line, Nrepl+1, '\n'); if(strncmp(line[0], REPLMAGIC, sizeof(REPLMAGIC)-1)){ dp->repl.p = 0; return; } for(dp->repl.nrepl = 0, i = 1; i < n; i++, dp->repl.nrepl++){ if(getfields(line[i], field, 1, ' ') != 1) break; if((dp->repl.blk[dp->repl.nrepl] = strtoul(field[1], 0, 0)) <= 0) break; } } /* . 604a . 526c print("hd%d err: lsec %ld status %lux, err %lux\n", dp-hard, lsec, cp->status, cp->error); . 506,507c . 107a Repl repl; . 96a struct Repl { Partition *p; int nrepl; ulong blk[Nrepl]; }; #define PARTMAGIC "plan9 partitions" #define REPLMAGIC "block replacements" . 46a Nrepl= 16, /* maximum replacement blocks */ . 45c Maxread= 4*1024, /* maximum transfer size/read */ . 12a typedef struct Repl Repl; . ## diffname pc/devhard.c 1992/0512 ## diff -e /n/bootesdump/1992/0509/sys/src/9/safari/devhard.c /n/bootesdump/1992/0512/sys/src/9/safari/devhard.c 46c Maxread= 1*1024, /* maximum transfer size/read */ . ## diffname pc/devhard.c 1992/0513 ## diff -e /n/bootesdump/1992/0512/sys/src/9/safari/devhard.c /n/bootesdump/1992/0513/sys/src/9/safari/devhard.c 658c dp->repl.blk[dp->repl.nrepl] = strtoul(field[0], 0, 0); if(dp->repl.blk[dp->repl.nrepl] <= 0) . 544c return cp->sofar*dp->bytes; . 538,540c print("hd%d err: lblk %ld status %lux, err %lux\n", dp-hard, lblk, cp->status, cp->error); print("\tcyl %d, sec %d, head %d\n", cyl, sec, head); print("\tnsecs %d, sofar %d\n", cp->nsecs, cp->sofar); hardrepl(dp, lblk+cp->sofar); . 520,524c outb(cp->pbase+Pcount, cp->nsecs-cp->sofar); outb(cp->pbase+Psector, sec); outb(cp->pbase+Pdh, 0x20 | head); outb(cp->pbase+Pcyllsb, cyl); outb(cp->pbase+Pcylmsb, cyl>>8); . 517d 506,507c if(lblk+len > pp->end) len = pp->end - lblk; . 499,501c cyl = lblk/(dp->sectors*dp->heads); sec = (lblk % dp->sectors) + 1; head = (dp->drive<<4) | ((lblk/dp->sectors) % dp->heads); . 495,497c lblk = start + pp->start; if(lblk >= pp->end) . 491a retry: if(len == 0) return cp->sofar*dp->bytes; . 481a cp = dp->cp; cp->sofar = 0; . 475,476c long lblk; int cyl, sec, head; . 465a static void hardrepl(Drive *dp, long bblk) { int i; if(dp->repl.p == 0) return; for(i = 0; i < dp->repl.nrepl; i++){ if(dp->repl.blk[i] == bblk) print("found bblk %ld at offset %ld\n", bblk, i); } } . 153c int sofar; /* sectors transferred so far */ . 148,151d 48c Nrepl= 64, /* maximum replacement blocks */ . ## diffname pc/devhard.c 1992/0514 ## diff -e /n/bootesdump/1992/0513/sys/src/9/safari/devhard.c /n/bootesdump/1992/0514/sys/src/9/safari/devhard.c 828c cp->nsecs--; if(cp->nsecs == 0){ . 796c cp->nsecs--; } else { . 786c if(cp->nsecs){ . 775a if(cp->status & (Sdwf|Scorr)) print("hardintr: cmd=#%lux, status=#%lux\n", cp->cmd, cp->status); . 545a cp->nsecs--; . 533c outb(cp->pbase+Pcount, cp->nsecs); . 531a cmdreadywait(cp); . 529,530d 524c cp->cmd = cmd; cp->dp = dp; . 30a Scorr= (1<<2), . 29a Sdwf= (1<<5), . ## diffname pc/devhard.c 1992/05141 ## diff -e /n/bootesdump/1992/0514/sys/src/9/safari/devhard.c /n/bootesdump/1992/05141/sys/src/9/safari/devhard.c 834,835c if(cp->sofar >= cp->nsecs){ . 801,802c } else{ . 791c if(cp->sofar < cp->nsecs){ . 779,780d 548d 535c outb(cp->pbase+Pcount, cp->nsecs-cp->sofar); . 533d 531a cp->cmd = cmd; cp->dp = dp; . 526,527c cmdreadywait(cp); . 32d 30d ## diffname pc/devhard.c 1992/0519 ## diff -e /n/bootesdump/1992/05141/sys/src/9/safari/devhard.c /n/bootesdump/1992/0519/sys/src/9/safari/devhard.c 261a case 0x427a: /* for now: a list of those that work */ . ## diffname pc/devhard.c 1992/0625 ## diff -e /n/bootesdump/1992/0519/sys/src/9/safari/devhard.c /n/bootesdump/1992/0625/sys/src/9/safari/devhard.c 214c cp->buf = xalloc(Maxxfer); . 204,205c hard = xalloc(conf.nhard * sizeof(Drive)); hardc = xalloc(((conf.nhard+1)/2 + 1) * sizeof(Controller)); . ## diffname pc/devhard.c 1992/0711 ## diff -e /n/bootesdump/1992/0625/sys/src/9/safari/devhard.c /n/bootesdump/1992/0711/sys/src/9/safari/devhard.c 760a USED(ur); . 593c static void . 484d 323a USED(c, dp); . 317a USED(c); . 312a USED(c); . 306a USED(c, name, omode, perm); . 173a USED(tab, ntab); . 160c static void hardident(Drive*); . ## diffname pc/devhard.c 1992/0815 ## diff -e /n/bootesdump/1992/0808/sys/src/9/safari/devhard.c /n/bootesdump/1992/0815/sys/src/9/pc/devhard.c 831,832d 824,829c addr = cp->buf; if(addr){ addr += cp->sofar*dp->bytes; inss(cp->pbase+Pdata, addr, dp->bytes/2); . 815a } loop = 0; while((inb(cp->pbase+Pstatus) & Sdrq) == 0) if(++loop > 10000) { print("cmd=%lux status=%lux\n", cp->cmd, inb(cp->pbase+Pstatus)); panic("hardintr: read/ident"); . 800,801c addr = cp->buf; if(addr){ addr += cp->sofar*dp->bytes; outss(cp->pbase+Pdata, addr, dp->bytes/2); } . 763a char *addr; . 751,752d 748a free(buf); poperror(); . 733c n = getfields(buf, line, Npart+1, '\n'); . 727,728c hardxfer(dp, pp, Cread, 0, dp->bytes, buf); buf[dp->bytes-1] = 0; . 723a buf = smalloc(Maxxfer); if(waserror()){ free(buf); nexterror(); } . 697,704d 695a char *buf; . 691d 675,681c free(buf); poperror(); . 673c } else { for(dp->repl.nrepl = 0, i = 1; i < n; i++, dp->repl.nrepl++){ if(getfields(line[i], field, 1, ' ') != 1) break; dp->repl.blk[dp->repl.nrepl] = strtoul(field[0], 0, 0); if(dp->repl.blk[dp->repl.nrepl] <= 0) break; } . 670c n = getfields(buf, line, Nrepl+1, '\n'); . 664,665c hardxfer(dp, dp->repl.p, Cread, 0, dp->bytes, buf); buf[dp->bytes-1] = 0; . 659c buf = smalloc(Maxxfer); if(waserror()){ free(buf); nexterror(); } . 649a char *buf; . 645d 632a cp->buf = 0; . 622c memmove(&dp->id, buf, dp->bytes); . 614a cp->buf = buf; . 602a buf = smalloc(Maxxfer); . 600a char *buf; . 562a cp->buf = 0; qunlock(cp); poperror(); . 522a * go for it */ cp = dp->cp; qlock(cp); cp->sofar = 0; cp->buf = buf; if(waserror()){ cp->buf = 0; qunlock(cp); nexterror(); } /* . 511c return 0; . 508,509d 496,498d 486c hardxfer(Drive *dp, Partition *pp, int cmd, long start, long len, char *buf) . 435c free(buf); . 430,432c hardxfer(dp, pp, Cread, c->offset+rv, dp->bytes, buf); memmove(buf, aa+rv, partial); hardxfer(dp, pp, Cwrite, c->offset+rv, dp->bytes, buf); . 418,419c memmove(buf, aa+rv, i); i = hardxfer(dp, pp, Cwrite, c->offset+rv, i, buf); . 404,405c memmove(buf+partial, aa, rv); hardxfer(dp, pp, Cwrite, c->offset-partial, dp->bytes, buf); . 399c hardxfer(dp, pp, Cread, c->offset-partial, dp->bytes, buf); . 391a . 389c free(buf); . 385,387c buf = smalloc(Maxxfer); . 378c char *buf; . 365c free(buf); . 362c memmove(aa+rv, buf + skip, i); . 356c i = hardxfer(dp, pp, Cread, c->offset+rv-skip, n-rv+skip, buf); . 353a dp = &hard[DRIVE(c->qid.path)]; pp = &dp->p[PART(c->qid.path)]; . 351c free(buf); . 345,349c buf = smalloc(Maxxfer); . 340c char *buf; . 215c cp->buf = 0; . 159c static long hardxfer(Drive*, Partition*, int, long, long, char*); . 45,46c Maxxfer= 512, /* maximum transfer size/cmd */ Maxread= 512, /* maximum transfer size/read */ . ## diffname pc/devhard.c 1992/0826 ## diff -e /n/bootesdump/1992/0815/sys/src/9/pc/devhard.c /n/bootesdump/1992/0826/sys/src/9/pc/devhard.c 836,842d 817,818c while(((cp->status = inb(cp->pbase+Pstatus)) & Sdrq) == 0) if(++loop > 100) { . 804a } . 799,800c while((cp->status = inb(cp->pbase+Pstatus)) & Sbusy){ if(++loop > 100) { . 789d 649a free(buf); . 641c * the ident information is read, except on the safari. The following . 602a if(cp->status & Serr) print("hd%d setbuf err: status %lux, err %lux\n", dp-hard, cp->status, cp->error); . 597c outb(cp->pbase+Pprecomp, 0xAA); . 584c hardsetbuf(Drive *dp) . 581c * set read ahead mode . 503,504d 249c hardsetbuf(dp); . 242d 161c static void hardsetbuf(Drive*); . 45,46c Maxxfer= 32*512, /* maximum transfer size/cmd */ . ## diffname pc/devhard.c 1992/0901 ## diff -e /n/bootesdump/1992/0826/sys/src/9/pc/devhard.c /n/bootesdump/1992/0901/sys/src/9/pc/devhard.c 840c DPRINT("cmd=%lux status=%lux\n", . 820c DPRINT("cmd=%lux status=%lux\n", . 801c DPRINT("cmd=%lux status=%lux\n", . 635c DPRINT("bad disk ident status\n"); . 600c DPRINT("hd%d setbuf err: status %lux, err %lux\n", . 564,565c DPRINT("\tcyl %d, sec %d, head %d\n", cyl, sec, head); DPRINT("\tnsecs %d, sofar %d\n", cp->nsecs, cp->sofar); . 562c DPRINT("hd%d err: lblk %ld status %lux, err %lux\n", . 476c DPRINT("found bblk %ld at offset %ld\n", bblk, i); . 462c DPRINT("cmdreadywait failed\n"); . 8a #define DPRINT if(0)print . ## diffname pc/devhard.c 1992/0902 ## diff -e /n/bootesdump/1992/0901/sys/src/9/pc/devhard.c /n/bootesdump/1992/0902/sys/src/9/pc/devhard.c 876,879d 867a case Cinitparam: . 609a * set the drive parameters */ static void hardinitparam(Drive *dp) { Controller *cp = dp->cp; qlock(cp); if(waserror()){ qunlock(cp); nexterror(); } cmdreadywait(cp); cp->cmd = Cinitparam; outb(cp->pbase+Psector, dp->sectors); outb(cp->pbase+Pdh, 0x20 | (dp->heads-1) | (dp->drive<<4)); outb(cp->pbase+Pcmd, Cinitparam); sleep(&cp->r, cmddone, cp); if(cp->status & Serr) DPRINT("hd%d initparam err: status %lux, err %lux\n", dp-hard, cp->status, cp->error); poperror(); qunlock(cp); } /* . 595c outb(cp->pbase+Pprecomp, on ? 0xAA : 0x55); . 582c hardsetbuf(Drive *dp, int on) . 272c /* * Try reading the partition table (last disk sector). * If an error occurs set the drive parameters and try * again. This works if the parameters reported * by the disk are the physical parameters rather than * the current logical ones (as they are on the NCR 3170). * * We don't routinely set the parameters since it confuses * some disks (on the Gateway and AT&T Safari for example). */ if(waserror()){ hardinitparam(dp); /* set drive parameters */ hardpart(); } else { hardpart(); poperror(); } . 257,263d 245,251c case 0x324A: /* hard drive on the AT&T 6386, it lies */ . 243a hardsetbuf(dp, 1); /* * for now use the configuration word to identify the * wayward 6386 disk. BUG!!! This word isn't * meant to identify disks, but we have nothing * better. */ . 242c /* * the following is magic to determine the parameters * (number of cylinders/sectors/heads) on an IDE drive. * I haven't found a method that is guaranteed to work. * For some drives, it may be necessary to compile the * numbers into this driver and circumvent this code. * The BIOS disk type & tables doesn't help since the * types are inconsistent from one BIOS to the next. */ dp->bytes = 512; /* until we know better */ hardsetbuf(dp, 0); /* turned off during ident */ . 162c static void hardsetbuf(Drive*, int); static void hardinitparam(Drive*); . 42a Cinitparam= 0x91, . ## diffname pc/devhard.c 1992/0903 ## diff -e /n/bootesdump/1992/0902/sys/src/9/pc/devhard.c /n/bootesdump/1992/0903/sys/src/9/pc/devhard.c 709a /* * probe the given sector to see if it exists */ static int hardprobe(Drive *dp, int cyl, int sec, int head) { Controller *cp; char *buf; int rv; cp = dp->cp; buf = smalloc(Maxxfer); qlock(cp); if(waserror()){ qunlock(cp); nexterror(); } cmdreadywait(cp); cp->cmd = Cread; cp->dp = dp; cp->status = 0; cp->nsecs = 1; outb(cp->pbase+Pcount, 1); outb(cp->pbase+Psector, sec+1); outb(cp->pbase+Pdh, 0x20 | head); outb(cp->pbase+Pcyllsb, cyl); outb(cp->pbase+Pcylmsb, cyl>>8); outb(cp->pbase+Pcmd, Cread); sleep(&cp->r, cmddone, cp); if(cp->status & Serr) rv = -1; else rv = 0; cp->buf = 0; free(buf); poperror(); qunlock(cp); return rv; } /* * figure out the drive parameters */ static void hardparams(Drive *dp) { int i, hi, lo; /* * first try the easy way, ask the drive and make sure it * isn't lying. */ dp->bytes = 512; hardident(dp); if(hardprobe(dp, dp->cyl-1, dp->sectors-1, dp->heads-1) == 0) return; /* * the drive lied, determine parameters by seeing which ones * work to read sectors. */ for(i = 0; i < 32; i++) if(hardprobe(dp, 0, 0, i) < 0) break; dp->heads = i; for(i = 0; i < 128; i++) if(hardprobe(dp, 0, i, 0) < 0) break; dp->sectors = i; for(i = 512; ; i += 512) if(hardprobe(dp, i, dp->sectors-1, dp->heads-1) < 0) break; lo = i - 512; hi = i; for(; hi-lo > 1;){ i = lo + (hi - lo)/2; if(hardprobe(dp, i, dp->sectors-1, dp->heads-1) < 0) hi = i; else lo = i; } dp->cyl = lo + 1; dp->cap = dp->bytes * dp->cyl * dp->heads * dp->sectors; } . 702a dp->cyl = ip->lcyls; dp->heads = ip->lheads; dp->sectors = ip->ls2t; dp->cap = dp->bytes * dp->cyl * dp->heads * dp->sectors; . 693c ip = (Ident*)buf; . 669a Ident *ip; . 639,661d 637c ushort magic; /* drive type magic */ ushort lcyls; /* logical number of cylinders */ ushort rcyl; /* number of removable cylinders */ ushort lheads; /* logical number of heads */ ushort b2t; /* unformatted bytes/track */ ushort b2s; /* unformated bytes/sector */ ushort ls2t; /* logical sectors/track */ ushort gap; /* bytes in inter-sector gaps */ ushort sync; /* bytes in sync fields */ ushort magic2; /* must be 0x0000 */ ushort serial[10]; /* serial number */ ushort type; /* controller type (0x0003) */ ushort bsize; /* buffer size/512 */ ushort ecc; /* ecc bytes returned by read long */ ushort firm[4]; /* firmware revision */ ushort model[20]; /* model number */ ushort s2i; /* number of sectors/interrupt */ ushort dwtf; /* double word transfer flag */ ushort alernate; ushort piomode; ushort dmamode; ushort reserved[76]; ushort ncyls; /* native number of cylinders */ ushort nheads; /* native number of heads, sectors */ ushort dlcyls; /* default logical number of cyinders */ ushort dlheads; /* default logical number of heads, sectors */ ushort interface; ushort power; /* 0xFFFF if power commands supported */ ushort flags; ushort ageprog; /* MSB = age, LSB = program */ ushort reserved2[120]; }; . 634,635c struct Ident . 632c * ident sector from drive . 299d 278,297c hardsetbuf(dp, 1); } /* * read Plan 9 partition table */ hardpart(dp); poperror(); . 243,276c if(waserror()){ dp->online = 0; continue; } if(!dp->online){ hardparams(dp); . 240d 165a static int hardprobe(Drive*, int, int, int); . 164c static void hardparams(Drive*); . 129,130d 56,93d 9c #define DPRINT if(1)print . ## diffname pc/devhard.c 1992/0906 ## diff -e /n/bootesdump/1992/0903/sys/src/9/pc/devhard.c /n/bootesdump/1992/0906/sys/src/9/pc/devhard.c 834c if(n && strncmp(line[0], PARTMAGIC, sizeof(PARTMAGIC)-1) == 0){ . ## diffname pc/devhard.c 1992/1001 ## diff -e /n/bootesdump/1992/0906/sys/src/9/pc/devhard.c /n/bootesdump/1992/1001/sys/src/9/pc/devhard.c 934a if(cp->sofar > cp->nsecs) print("hardintr %d %d\n", cp->sofar, cp->nsecs); . 666a cp->sofar = 0; . 656a free(buf); . 614a splx(s); . 607a s = splhi(); . 596a int s; . 516c return len; . 512a len = cp->sofar*dp->bytes; . 502a poperror(); if(loop) nexterror(); . 501a /* * wait for command to complete. if we get a note, * remember it but keep waiting to let the disk finish * the current command. */ loop = 0; while(waserror()){ DPRINT("interrupted hardxfer\n"); if(loop++ > 10){ print("hard disk error\n"); nexterror(); } } . 500a splx(s); . 493d 486,487c outb(cp->pbase+Pcount, cp->nsecs); . 482a s = splhi(); cp->sofar = 0; cp->buf = buf; cp->nsecs = len; . 481c * splhi to make command atomic . 471,477d 463,464d 458,460d 453a if(lblk+len > pp->end) len = pp->end - lblk; . 433c int loop, s; . 404c if(TK2MS(m->ticks - start) > 5){ . 332a if(a&KZERO)print("wr k 0x%lux d 0x%lux\n", a, n); . 328a print("hard write error\n"); . 291a if(a&KZERO)print("rd k 0x%lux d 0x%lux\n", a, n); . 287a print("hard read error\n"); . 170c hardc = xalloc(((conf.nhard+1)/2) * sizeof(Controller)); . 48c Maxxfer= BY2PG, /* maximum transfer size/cmd */ . ## diffname pc/devhard.c 1992/1002 ## diff -e /n/bootesdump/1992/1001/sys/src/9/pc/devhard.c /n/bootesdump/1992/1002/sys/src/9/pc/devhard.c 379c hardxfer(dp, pp, Cwrite, offset+rv, dp->bytes, buf); . 377c hardxfer(dp, pp, Cread, offset+rv, dp->bytes, buf); . 366c i = hardxfer(dp, pp, Cwrite, offset+rv, i, buf); . 352c hardxfer(dp, pp, Cwrite, offset-partial, dp->bytes, buf); . 346c hardxfer(dp, pp, Cread, offset-partial, dp->bytes, buf); . 344c partial = offset % dp->bytes; . 337,338d 332d 317c hardwrite(Chan *c, void *a, long n, ulong offset) . 300c i = hardxfer(dp, pp, Cread, offset+rv-skip, n-rv+skip, buf); . 298c skip = offset % dp->bytes; . 293,294d 288d 274c hardread(Chan *c, void *a, long n, ulong offset) . 8a #include "devtab.h" . ## diffname pc/devhard.c 1992/1103 ## diff -e /n/bootesdump/1992/1002/sys/src/9/pc/devhard.c /n/bootesdump/1992/1103/sys/src/9/pc/devhard.c 688c outb(cp->pbase+Pdh, 0x20 | head | (dp->drive<<4)); . 484c outb(cp->pbase+Pdh, 0x20 | (dp->drive<<4) | head); . 460c head = ((lblk/dp->sectors) % dp->heads); . 173a /* * read nvram for number of hard drives (2 max) */ equip = nvramread(0x12); if(conf.nhard > 0 && (equip>>4) == 0) conf.nhard = 0; if(conf.nhard > 1 && (equip&0xf) == 0) conf.nhard = 1; . 169a uchar equip; . ## diffname pc/devhard.c 1992/1104 ## diff -e /n/bootesdump/1992/1103/sys/src/9/pc/devhard.c /n/bootesdump/1992/1104/sys/src/9/pc/devhard.c 985c print("weird disk interrupt, cmd=%.2ux, status=%.2ux\n", . ## diffname pc/devhard.c 1992/1119 ## diff -e /n/bootesdump/1992/1104/sys/src/9/pc/devhard.c /n/bootesdump/1992/1119/sys/src/9/pc/devhard.c 985,986c print("weird disk interrupt, cmd=%.2ux, lastcmd= %.2ux status=%.2ux\n", cp->cmd, cp->lastcmd, cp->status); . 661a cp->lastcmd = cp->cmd; . 566c dp-hard, cp->status, cp->error);/**/ . 564c /* if(cp->status & Serr) . 228a qunlock(dp); . 218a qlock(dp); . 216a qunlock(dp); . 79a QLock; . ## diffname pc/devhard.c 1993/0114 ## diff -e /n/bootesdump/1992/1119/sys/src/9/pc/devhard.c /n/bootesdump/1993/0114/sys/src/9/pc/devhard.c 236c return devattach('H', spec); . ## diffname pc/devhard.c 1993/0915 ## diff -e /n/bootesdump/1993/0114/sys/src/9/pc/devhard.c /n/fornaxdump/1993/0915/sys/src/brazil/pc/devhard.c 961a } loop = 0; while((inb(cp->pbase+Pstatus) & Sdrq) == 0) if(++loop > 10000) { DPRINT("cmd=%lux status=%lux\n", cp->cmd, inb(cp->pbase+Pstatus)); panic("hardintr: read/ident"); . 949,955d 867d 862a n = getfields(buf, line, Npart+1, '\n'); if(n == 0 || strncmp(line[0], PARTMAGIC, sizeof(PARTMAGIC)-1)){ dp->p[0].end--; dp->p[1].start--; dp->p[1].end--; hardxfer(dp, pp, Cread, 0, dp->bytes, buf); buf[dp->bytes-1] = 0; n = getfields(buf, line, Npart+1, '\n'); } . 859c * read last sector from disk, null terminate. This used * to be the sector we used for the partition tables. * However, this sector is special on some PC's so we've * started to use the second last sector as the partition * table instead. To avoid reconfiguring all our old systems * we first look to see if there is a valid partition * table in the last sector. If so, we use it. Otherwise * we switch to the second last. . 510a if(stat & Serr) error(Eio); . 509c } else stat = 0; . 505c while((stat = inb(cp->pbase+Pstatus) & (Serr|Sdrq)) == 0) . 450c int loop, s, stat; . 158c devdir(c, qid, name, l, eve, 0660, dirp); . ## diffname pc/devhard.c 1993/1124 ## diff -e /n/fornaxdump/1993/0915/sys/src/brazil/pc/devhard.c /n/fornaxdump/1993/1124/sys/src/brazil/pc/devhard.c 923c * distinguish which interrupted (use arg). . 919c USED(ur, arg); . 912c hardintr(Ureg *ur, void *arg) . 197c setvec(Hardvec + (cp-hardc)*8, hardintr, 0); /* BUG!! guessing */ . 124c static void hardintr(Ureg*, void*); . ## diffname pc/devhard.c 1994/0128 ## diff -e /n/fornaxdump/1993/1124/sys/src/brazil/pc/devhard.c /n/fornaxdump/1994/0128/sys/src/brazil/pc/devhard.c 1011a } } void hardclock(void) { int drive; Drive *dp; Controller *cp; int diff; if(spindowntime <= 0) return; for(drive = 0; drive < conf.nhard; drive++){ dp = &hard[drive]; cp = dp->cp; if(canqlock(cp) == 0) continue; diff = TK2SEC(m->ticks - dp->usetime); switch(dp->state){ case Sspinning: if(diff >= spindowntime){ cp->cmd = Cstandby; outb(cp->pbase+Pdh, 0x20 | (dp->drive<<4) | 0); outb(cp->pbase+Pcmd, cp->cmd); dp->state = Sstandby; } break; } qunlock(dp->cp); . 528a dp->state = Sspinning; dp->usetime = m->ticks; . 421c if(TK2MS(m->ticks - start) > 10){ . 176a p = getconf("spindowntime"); if(p) spindowntime = atoi(p); . 172a char *p; . 122a static int spindowntime; . 96a enum { Sspinning, Sstandby, Sidle, Spowerdown, }; . 88a ulong usetime; int state; . 46a /* conner specific commands */ Cstandby= 0xE0, Cidle= 0xE1, Cpowerdown= 0xE3, . ## diffname pc/devhard.c 1994/0205 ## diff -e /n/fornaxdump/1994/0128/sys/src/brazil/pc/devhard.c /n/fornaxdump/1994/0205/sys/src/brazil/pc/devhard.c 1059a outb(cp->pbase+Pcount, 0); . 104,111d 51a /* disk states */ Sspinning, Sstandby, Sidle, Spowerdown, . 48c Cstandby= 0xE2, . ## diffname pc/devhard.c 1994/0222 ## diff -e /n/fornaxdump/1994/0205/sys/src/brazil/pc/devhard.c /n/fornaxdump/1994/0222/sys/src/brazil/pc/devhard.c 910,919c switch(getfields(line[i], field, 3, ' ')) { case 2: if(strcmp(field[0], "unit") == 0) strncpy(dp->vol, field[1], NAMELEN); break; case 3: strncpy(pp->name, field[0], NAMELEN); if(strncmp(pp->name, "repl", NAMELEN) == 0) dp->repl.p = pp; pp->start = strtoul(field[1], 0, 0); pp->end = strtoul(field[2], 0, 0); if(pp->start > pp->end || pp->start >= dp->p[0].end) break; dp->npart++; } . 856a sprint(dp->vol, "hd%d", dp - hard); . 168c sprint(name, "%s%s", dp->vol, pp->name); . 101a char vol[NAMELEN]; . ## diffname pc/devhard.c 1994/0413 ## diff -e /n/fornaxdump/1994/0222/sys/src/brazil/pc/devhard.c /n/fornaxdump/1994/0413/sys/src/brazil/pc/devhard.c 1002,1008d 995a loop = 0; while((cp->status & (Serr|Sdrq)) == 0){ if(++loop > 10000) { DPRINT("cmd=%lux status=%lux\n", cp->cmd, inb(cp->pbase+Pstatus)); panic("hardintr: read/ident"); } cp->status = inb(cp->pbase+Pstatus); } . ## diffname pc/devhard.c 1994/0428 ## diff -e /n/fornaxdump/1994/0413/sys/src/brazil/pc/devhard.c /n/fornaxdump/1994/0428/sys/src/brazil/pc/devhard.c 719c cmdreadywait(dp); . 659c cmdreadywait(dp); . 585c cmdreadywait(dp); . 505c cmdreadywait(dp); . 441c if(TK2MS(m->ticks - start) > period){ . 438a /* give it 2 seconds to spin down and up */ if(dp->state == Sspinning) period = 10; else period = 2000; . 437a int period; Controller *cp = dp->cp; . 435c cmdreadywait(Drive *dp) . ## diffname pc/devhard.c 1994/0505 ## diff -e /n/fornaxdump/1994/0428/sys/src/brazil/pc/devhard.c /n/fornaxdump/1994/0505/sys/src/brazil/pc/devhard.c 1038a case Cidle: case Cstandby: case Cpowerdown: . ## diffname pc/devhard.c 1994/0913 ## diff -e /n/fornaxdump/1994/0505/sys/src/brazil/pc/devhard.c /n/fornaxdump/1994/0913/sys/src/brazil/pc/devhard.c 293c Drive *d; Partition *p; if(c->mode != OWRITE && c->mode != ORDWR) return; d = &hard[DRIVE(c->qid.path)]; p = &d->p[PART(c->qid.path)]; if(strcmp(p->name, "partition") != 0) return; if(waserror()){ qunlock(d); nexterror(); } qlock(d); hardpart(d); qunlock(d); poperror(); . ## diffname pc/devhard.c 1995/0107 ## diff -e /n/fornaxdump/1994/0913/sys/src/brazil/pc/devhard.c /n/fornaxdump/1995/0107/sys/src/brazil/pc/devhard.c 1104d 1093,1102c if((dp->state == Sspinning) && (diff >= spindowntime)){ ilock(cp); cp->cmd = Cstandby; outb(cp->pbase+Pcount, 0); outb(cp->pbase+Pdh, 0x20 | (dp->drive<<4) | 0); outb(cp->pbase+Pcmd, cp->cmd); iunlock(cp); dp->state = Sstandby; . 1089,1090d 1072a iunlock(cp); . 1036c break; . 998c break; . 990a . 982a ilock(cp); . 758a iunlock(cp); . 746a ilock(cp); . 695c iunlock(cp); . 687c ilock(cp); . 675d 616a iunlock(cp); . 612a ilock(cp); . 557c iunlock(cp); . 548a . 542a . 536c dp->usetime = m->ticks; cmdreadywait(dp); ilock(cp); . 534c * Make sure hardclock() doesn't * interfere. . 531,532d 496c int loop, stat; . 450c * Wait for the controller to be ready to accept a command. * This is protected from intereference by hardclock() by * setting dp->usetime before it is called. . 243a /* * Make sure hardclock() doesn't * interfere. */ dp->usetime = m->ticks; . 219a if(conf.nhard && (p = getconf("spindowntime"))) spindowntime = atoi(p); . 193,196d 117a Lock; /* exclusive access to the registers */ . 116c QLock; /* exclusive access to the controller */ . ## diffname pc/devhard.c 1995/0108 ## diff -e /n/fornaxdump/1995/0107/sys/src/brazil/pc/devhard.c /n/fornaxdump/1995/0108/sys/src/brazil/pc/devhard.c 441a } long hardbwrite(Chan *c, Block *bp, ulong offset) { return devbwrite(c, bp, offset); . 373a Block* hardbread(Chan *c, long n, ulong offset) { return devbread(c, n, offset); } . ## diffname pc/devhard.c 1995/0117 ## diff -e /n/fornaxdump/1995/0108/sys/src/brazil/pc/devhard.c /n/fornaxdump/1995/0117/sys/src/brazil/pc/devhard.c 967c switch(getfields(line[i], field, 3, " ")) { . 958c n = getfields(buf, line, Npart+1, "\n"); . 951c n = getfields(buf, line, Npart+1, "\n"); . 888c if(getfields(line[i], field, 1, " ") != 1) . 883c n = getfields(buf, line, Nrepl+1, "\n"); . ## diffname pc/devhard.c 1995/0726 ## diff -e /n/fornaxdump/1995/0117/sys/src/brazil/pc/devhard.c /n/fornaxdump/1995/0726/sys/src/brazil/pc/devhard.c 292d 290c hardcreate(Chan*, char*, int, ulong) . ## diffname pc/devhard.c 1995/0912 # deleted ## diff -e /n/fornaxdump/1995/0726/sys/src/brazil/pc/devhard.c /n/fornaxdump/1995/0912/sys/src/brazil/pc/devhard.c 1,1133d