From c248c20a3191cfb1fced59084c9c3d4dafec83e8 Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Wed, 13 May 1992 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 1992-05-13 --- pc/devhard.c | 70 ++++++++++++++++++++++++++++++++-------------------- 1 file changed, 43 insertions(+), 27 deletions(-) diff --git a/pc/devhard.c b/pc/devhard.c index b61592a58537f4bfeb2ca687c742f00c22151a3a..55482f8ff2ba68cc2d0ef5c5f75437c4c140db1e 100644 --- a/pc/devhard.c +++ b/pc/devhard.c @@ -45,7 +45,7 @@ enum Maxxfer= 4*1024, /* maximum transfer size/cmd */ Maxread= 1*1024, /* maximum transfer size/read */ Npart= 8+2, /* 8 sub partitions, disk, and partition */ - Nrepl= 16, /* maximum replacement blocks */ + Nrepl= 64, /* maximum replacement blocks */ }; #define PART(x) ((x)&0xF) #define DRIVE(x) (((x)>>4)&0x7) @@ -145,12 +145,8 @@ struct Controller int lastcmd; /* debugging info */ 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 nsecs; /* length of transfer (sectors) */ - int sofar; /* bytes transferred so far */ + int sofar; /* sectors transferred so far */ int status; int error; Drive *dp; /* drive being accessed */ @@ -463,6 +459,19 @@ print("cmdreadywait failed\n"); } } +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); + } +} + /* * transfer a number of sectors. hardintr will perform all the iterative * parts. @@ -472,13 +481,16 @@ hardxfer(Drive *dp, Partition *pp, int cmd, long start, long len) { Controller *cp; int err; - long lsec; - int cyl; + long lblk; + int cyl, sec, head; int loop; if(dp->online == 0) error(Eio); + cp = dp->cp; + cp->sofar = 0; + /* * cut transfer size down to disk buffer size */ @@ -489,22 +501,24 @@ hardxfer(Drive *dp, Partition *pp, int cmd, long start, long len) len = Maxread; len = (len + dp->bytes - 1) / dp->bytes; +retry: + if(len == 0) + return cp->sofar*dp->bytes; /* * calculate physical address */ - cp = dp->cp; - lsec = start + pp->start; - if(lsec >= pp->end) + lblk = start + pp->start; + if(lblk >= pp->end) return 0; - cp->tcyl = lsec/(dp->sectors*dp->heads); - cp->tsec = (lsec % dp->sectors) + 1; - cp->thead = (lsec/dp->sectors) % dp->heads; + cyl = lblk/(dp->sectors*dp->heads); + sec = (lblk % dp->sectors) + 1; + head = (dp->drive<<4) | ((lblk/dp->sectors) % dp->heads); /* * can't xfer past end of disk */ - if(lsec+len > pp->end) - len = pp->end - lsec; + if(lblk+len > pp->end) + len = pp->end - lblk; cp->nsecs = len; cmdreadywait(cp); @@ -514,14 +528,13 @@ hardxfer(Drive *dp, Partition *pp, int cmd, long start, long len) */ cp->cmd = cmd; cp->dp = dp; - cp->sofar = 0; cp->status = 0; - outb(cp->pbase+Pcount, cp->nsecs); - outb(cp->pbase+Psector, cp->tsec); - outb(cp->pbase+Pdh, 0x20 | (dp->drive<<4) | cp->thead); - outb(cp->pbase+Pcyllsb, cp->tcyl); - outb(cp->pbase+Pcylmsb, cp->tcyl>>8); + 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); outb(cp->pbase+Pcmd, cmd); if(cmd == Cwrite){ @@ -535,13 +548,15 @@ hardxfer(Drive *dp, Partition *pp, int cmd, long start, long len) sleep(&cp->r, cmddone, cp); if(cp->status & Serr){ -print("hd%d err: lsec %ld status %lux, err %lux\n", dp-hard, lsec, cp->status, cp->error); -print("\ttcyl %d, tsec %d, thead %d\n", cp->tcyl, cp->tsec, cp->thead); -print("\tnsecs %d, sofar %d\n", cp->nsecs, cp->sofar); + 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); error(Eio); } - return cp->nsecs*dp->bytes; + return cp->sofar*dp->bytes; } /* @@ -655,7 +670,8 @@ hardreplinit(Drive *dp) 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) + dp->repl.blk[dp->repl.nrepl] = strtoul(field[0], 0, 0); + if(dp->repl.blk[dp->repl.nrepl] <= 0) break; } }