diff options
| author | mycroft <mycroft@NetBSD.org> | 1994-03-04 03:43:48 +0000 |
|---|---|---|
| committer | mycroft <mycroft@NetBSD.org> | 1994-03-04 03:43:48 +0000 |
| commit | 220512c2a88b4e117617d925bfe1648476b903b8 (patch) | |
| tree | f0518977a7524864b64293f0afd95de00855ae74 /sys/dev | |
| parent | 499a02a6a9c6893d1a3fa4b337089cd185d4bfed (diff) | |
De-ANSIfy. Move the timeout counter into struct disk. Remove unneeded args
to wd[gs]etctlr(). Other minor changes.
Diffstat (limited to 'sys/dev')
| -rw-r--r-- | sys/dev/ata/wd.c | 253 | ||||
| -rw-r--r-- | sys/dev/isa/wd.c | 253 |
2 files changed, 266 insertions, 240 deletions
diff --git a/sys/dev/ata/wd.c b/sys/dev/ata/wd.c index 1b2a55fee96..33e15e1ecb9 100644 --- a/sys/dev/ata/wd.c +++ b/sys/dev/ata/wd.c @@ -35,15 +35,12 @@ * SUCH DAMAGE. * * from: @(#)wd.c 7.2 (Berkeley) 5/9/91 - * $Id: wd.c,v 1.54 1994/03/03 01:58:21 mycroft Exp $ + * $Id: wd.c,v 1.55 1994/03/04 03:43:48 mycroft Exp $ */ #define QUIETWORKS /* define this to make wdopen() set DKFL_QUIET */ #define INSTRUMENT /* instrumentation stuff by Brad Parker */ -/* TODO: peel out buffer at low ipl, speed improvement */ -/* TODO: find and fix the timing bugs apparent on some controllers */ - #include "wd.h" #if NWDC > 0 @@ -113,6 +110,7 @@ struct disk { char dk_unit; /* physical unit number */ char dk_lunit; /* logical unit number */ char dk_state; /* control state */ + int dk_timeout; /* timeout counter */ u_char dk_status; /* copy of status reg. */ u_char dk_error; /* copy of error reg. */ short dk_port; /* i/o port base */ @@ -144,7 +142,6 @@ struct buf wdtab[NWDC]; /* various per-controller info */ struct buf wdutab[NWD]; /* head of queue per drive */ struct buf rwdbuf[NWD]; /* buffers for raw IO */ long wdxfer[NWD]; /* count of transfers */ -int wdtimeoutstatus[NWD]; /* timeout counters */ int wdprobe(), wdattach(); @@ -152,17 +149,17 @@ struct isa_driver wdcdriver = { wdprobe, wdattach, "wdc", }; -static void wdustart(struct disk *); -static void wdstart(int); -static int wdcommand(struct disk *, int); -static int wdcontrol(struct buf *); -static int wdsetctlr(dev_t, struct disk *); -static int wdgetctlr(int, struct disk *); -static void bad144intern(struct disk *); -static int wdreset(struct disk *, int); -static int wdtimeout(caddr_t); -void wddisksort(struct buf *dp, struct buf *bp); -int wdc_wait(struct disk *, int); +static void wdustart __P((struct disk *)); +static void wdstart __P((int)); +static int wdcommand __P((struct disk *, int)); +static int wdcontrol __P((struct buf *)); +static int wdsetctlr __P((struct disk *)); +static int wdgetctlr __P((struct disk *)); +static void bad144intern __P((struct disk *)); +static int wdreset __P((struct disk *, int)); +static int wdtimeout __P((caddr_t)); +void wddisksort __P((struct buf *dp, struct buf *bp)); +int wdc_wait __P((struct disk *, int)); #define wait_for_drq(d) wdc_wait(d, WDCS_DRQ) #define wait_for_ready(d) wdc_wait(d, WDCS_READY | WDCS_SEEKCMPLT) #define wait_for_unbusy(d) wdc_wait(d, 0) @@ -171,23 +168,24 @@ int wdc_wait(struct disk *, int); * Probe for controller. */ int -wdprobe(struct isa_device *dvp) +wdprobe(isa_dev) + struct isa_device *isa_dev; { struct disk *du; int wdc; - if (dvp->id_unit >= NWDC) + if (isa_dev->id_unit >= NWDC) return 0; du = (struct disk *)malloc(sizeof(struct disk), M_TEMP, M_NOWAIT); bzero(du, sizeof(struct disk)); - du->dk_ctrlr = dvp->id_unit; + du->dk_ctrlr = isa_dev->id_unit; du->dk_unit = 0; du->dk_lunit = 0; - wdcontroller[dvp->id_unit].dkc_port = dvp->id_iobase; + wdcontroller[isa_dev->id_unit].dkc_port = isa_dev->id_iobase; - wdc = du->dk_port = dvp->id_iobase; + wdc = du->dk_port = isa_dev->id_iobase; /* check if we have registers that work */ outb(wdc+wd_error, 0x5a); /* error register not writable */ @@ -214,24 +212,25 @@ nodevice: * Attach each drive if possible. */ int -wdattach(struct isa_device *dvp) +wdattach(isa_dev) + struct isa_device *isa_dev; { int unit, lunit; struct disk *du; - if (dvp->id_masunit == -1) + if (isa_dev->id_masunit == -1) return 0; - if (dvp->id_masunit >= NWDC) + if (isa_dev->id_masunit >= NWDC) return 0; - lunit = dvp->id_unit; + lunit = isa_dev->id_unit; if (lunit == -1) { - printf("wdc%d: cannot support unit ?\n", dvp->id_masunit); + printf("wdc%d: cannot support unit ?\n", isa_dev->id_masunit); return 0; } if (lunit >= NWD) return 0; - unit = dvp->id_physid; + unit = isa_dev->id_physid; du = wddrives[lunit] = (struct disk *)malloc(sizeof(struct disk), M_TEMP, M_NOWAIT); @@ -239,18 +238,17 @@ wdattach(struct isa_device *dvp) bzero(&wdutab[lunit], sizeof(struct buf)); bzero(&rwdbuf[lunit], sizeof(struct buf)); wdxfer[lunit] = 0; - wdtimeoutstatus[lunit] = 0; - wdtimeout(lunit); - du->dk_ctrlr = dvp->id_masunit; + wdtimeout((caddr_t)du); + du->dk_ctrlr = isa_dev->id_masunit; du->dk_unit = unit; du->dk_lunit = lunit; - du->dk_port = wdcontroller[dvp->id_masunit].dkc_port; + du->dk_port = wdcontroller[isa_dev->id_masunit].dkc_port; - if (wdgetctlr(unit, du) == 0) { + if (wdgetctlr(du) == 0) { int i, blank; - printf("wd%d at wdc%d targ %d: ", dvp->id_unit, - dvp->id_masunit, dvp->id_physid); + printf("wd%d at wdc%d targ %d: ", isa_dev->id_unit, + isa_dev->id_masunit, isa_dev->id_physid); if (du->dk_params.wdp_heads == 0) printf("(unknown size) <"); else @@ -278,7 +276,7 @@ wdattach(struct isa_device *dvp) printf(">\n"); } else { /*printf("wd%d at wdc%d slave %d -- error\n", lunit, - dvp->id_masunit, unit);*/ + isa_dev->id_masunit, unit);*/ wddrives[lunit] = 0; free(du, M_TEMP); return 0; @@ -292,9 +290,10 @@ wdattach(struct isa_device *dvp) * be a multiple of a sector in length. */ int -wdstrategy(register struct buf *bp) +wdstrategy(bp) + struct buf *bp; { - register struct buf *dp; + struct buf *dp; struct disk *du; /* Disk unit to do the IO. */ int lunit = WDUNIT(bp->b_dev); int s; @@ -349,9 +348,10 @@ done: * Need to skip over multitransfer bufs. */ void -wddisksort(struct buf *dp, struct buf *bp) +wddisksort(dp, bp) + struct buf *dp, *bp; { - register struct buf *ap; + struct buf *ap; while ((ap = dp->b_actf) && ap->b_flags & B_XXX) dp = ap; @@ -364,9 +364,10 @@ wddisksort(struct buf *dp, struct buf *bp) * If the controller is idle, the transfer is started. */ static void -wdustart(register struct disk *du) +wdustart(du) + struct disk *du; { - register struct buf *dp = &wdutab[du->dk_lunit]; + struct buf *dp = &wdutab[du->dk_lunit]; int ctrlr = du->dk_ctrlr; /* unit already active? */ @@ -397,7 +398,8 @@ wdustart(register struct disk *du) * 1. The transfer length must be an exact multiple of the sector size. */ static void -wdstart(int ctrlr) +wdstart(ctrlr) + int ctrlr; { register struct disk *du; /* disk unit for IO */ register struct buf *bp; @@ -430,7 +432,7 @@ loop: du = wddrives[lunit]; /* clear any pending timeout, just in case */ - wdtimeoutstatus[lunit] = 0; + du->dk_timeout = 0; /* if not really a transfer, do control operations specially */ if (du->dk_state < OPEN) { @@ -606,7 +608,7 @@ retry: /* if this is a read operation, just go away until it's done. */ if (bp->b_flags & B_READ) { - wdtimeoutstatus[lunit] = 2; + du->dk_timeout = 2; return; } @@ -621,7 +623,7 @@ retry: du->dk_bc -= DEV_BSIZE; du->dk_bct -= DEV_BSIZE; - wdtimeoutstatus[lunit] = 2; + du->dk_timeout = 2; } /* Interrupt routine for the controller. Acknowledge the interrupt, check for @@ -630,7 +632,8 @@ retry: * continue with the next chunk if so. */ void -wdintr(int ctrlr) +wdintr(ctrlr) + int ctrlr; { register struct disk *du; register struct buf *bp, *dp; @@ -645,7 +648,7 @@ wdintr(int ctrlr) bp = dp->b_actf; du = wddrives[WDUNIT(bp->b_dev)]; wdc = du->dk_port; - wdtimeoutstatus[WDUNIT(bp->b_dev)] = 0; + du->dk_timeout = 0; #ifdef WDDEBUG printf("I%d ", ctrlr); @@ -799,7 +802,11 @@ done: * Initialize a drive. */ int -wdopen(dev_t dev, int flags, int fmt, struct proc *p) +wdopen(dev, flag, fmt, p) + dev_t dev; + int flag; + int fmt; + struct proc *p; { int lunit; struct disk *du; @@ -842,11 +849,11 @@ wdopen(dev_t dev, int flags, int fmt, struct proc *p) du->dk_state = WANTOPEN; /* read label using "raw" partition */ -#if defined(TIHMODS) && defined(garbage) - /* wdsetctlr(dev, du); */ /* Maybe do this TIH */ +#ifdef notdef + /* wdsetctlr(du); */ /* Maybe do this TIH */ msg = readdisklabel(makewddev(major(dev), WDUNIT(dev), WDRAW), wdstrategy, &du->dk_dd, &du->dk_cpd); - wdsetctlr(dev, du); + wdsetctlr(du); #endif if (msg = readdisklabel(makewddev(major(dev), WDUNIT(dev), WDRAW), wdstrategy, &du->dk_dd, &du->dk_cpd)) { @@ -857,7 +864,7 @@ wdopen(dev_t dev, int flags, int fmt, struct proc *p) return EINVAL; /* XXX needs translation */ } } else { - wdsetctlr(dev, du); + wdsetctlr(du); du->dk_flags |= DKFL_BSDLABEL; du->dk_flags &= ~DKFL_WRITEPROT; if (du->dk_dd.d_flags & D_BADSECT) @@ -917,7 +924,8 @@ wdopen(dev_t dev, int flags, int fmt, struct proc *p) * Returns 0 if operation still in progress, 1 if completed. */ static int -wdcontrol(register struct buf *bp) +wdcontrol(bp) + struct buf *bp; { struct disk *du; int unit, lunit; @@ -938,27 +946,23 @@ wdcontrol(register struct buf *bp) printf("wd%d: recal ", lunit); #endif s = splbio(); /* not called from intr level ... */ - wdgetctlr(unit, du); + wdgetctlr(du); if (wait_for_unbusy(du) < 0) { + lose: wdreset(du, 1); goto tryagainrecal; } - outb(wdc+wd_sdh, WDSD_IBM | (unit << 4)); - if (wait_for_ready(du) < 0) { - wdreset(du, 1); - goto tryagainrecal; - } - + if (wait_for_ready(du) < 0) + goto lose; wdtab[ctrlr].b_active = 1; - if (wdcommand(du, WDCC_RESTORE | WD_STEP) < 0) { - wdreset(du, 1); - goto tryagainrecal; - } + if (wdcommand(du, WDCC_RESTORE | WD_STEP) < 0) + goto lose; du->dk_state = RECAL; splx(s); return 0; + case RECAL: if ((stat = inb(wdc+wd_altsts)) & WDCS_ERR) { if ((du->dk_flags & DKFL_QUIET) == 0) { @@ -973,7 +977,7 @@ wdcontrol(register struct buf *bp) } /* some controllers require this ... */ - wdsetctlr(bp->b_dev, du); + wdsetctlr(du); wdtab[ctrlr].b_errcnt = 0; du->dk_state = OPEN; @@ -982,6 +986,7 @@ wdcontrol(register struct buf *bp) * by normal means. */ return 1; + default: panic("wdcontrol"); } @@ -1002,7 +1007,9 @@ badopen: * assumes interrupts are blocked. */ static int -wdcommand(struct disk *du, int cmd) +wdcommand(du, cmd) + struct disk *du; + int cmd; { int stat, wdc; @@ -1037,7 +1044,8 @@ wdcommand(struct disk *du, int cmd) * issue IDC to drive to tell it just what geometry it is to be. */ static int -wdsetctlr(dev_t dev, struct disk *du) +wdsetctlr(du) + struct disk *du; { int stat, s, wdc; @@ -1070,7 +1078,8 @@ wdsetctlr(dev_t dev, struct disk *du) * issue READP to drive to ask it what it is. */ static int -wdgetctlr(int u, struct disk *du) +wdgetctlr(du) + struct disk *du; { int stat, s, i, wdc; char tb[DEV_BSIZE]; @@ -1079,21 +1088,16 @@ wdgetctlr(int u, struct disk *du) s = splbio(); /* not called from intr level ... */ wdc = du->dk_port; if (wait_for_unbusy(du) < 0) { + lose: splx(s); return -1; } - - outb(wdc+wd_sdh, WDSD_IBM | (u << 4)); - if (wait_for_ready(du) < 0) { - splx(s); - return -1; - } - + outb(wdc+wd_sdh, WDSD_IBM | (du->dk_unit << 4)); + if (wait_for_ready(du) < 0) + goto lose; stat = wdcommand(du, WDCC_READP); - if (stat < 0) { - splx(s); - return -1; - } + if (stat < 0) + goto lose; if ((stat & WDCS_ERR) == 0) { /* obtain parameters */ @@ -1157,10 +1161,11 @@ wdgetctlr(int u, struct disk *du) return 0; } - -/* ARGSUSED */ int -wdclose(dev_t dev, int flags, int fmt) +wdclose(dev, flag, fmt) + dev_t dev; + int flag; + int fmt; { struct disk *du; int part = WDPART(dev), mask = 1 << part; @@ -1181,7 +1186,12 @@ wdclose(dev_t dev, int flags, int fmt) } int -wdioctl(dev_t dev, int cmd, caddr_t addr, int flag, struct proc *p) +wdioctl(dev, cmd, addr, flag, p) + dev_t dev; + int cmd; + caddr_t addr; + int flag; + struct proc *p; { int lunit = WDUNIT(dev); struct disk *du = wddrives[lunit]; @@ -1214,7 +1224,7 @@ wdioctl(dev_t dev, int cmd, caddr_t addr, int flag, struct proc *p) &du->dk_cpd); if (error == 0) { du->dk_flags |= DKFL_BSDLABEL; - wdsetctlr(dev, du); + wdsetctlr(du); } return error; @@ -1237,7 +1247,7 @@ wdioctl(dev_t dev, int cmd, caddr_t addr, int flag, struct proc *p) int wlab; du->dk_flags |= DKFL_BSDLABEL; - wdsetctlr(dev, du); + wdsetctlr(du); /* simulate opening partition 0 so write succeeds */ du->dk_openpart |= (1 << 0); /* XXX */ @@ -1300,7 +1310,8 @@ wdformat(struct buf *bp) #endif int -wdsize(dev_t dev) +wdsize(dev) + dev_t dev; { int lunit = WDUNIT(dev), part = WDPART(dev); struct disk *du; @@ -1315,6 +1326,7 @@ wdsize(dev_t dev) int val; val = wdopen(makewddev(major(dev), lunit, WDRAW), FREAD, S_IFBLK, 0); + /* XXX Clear the open flag? */ if (val != 0) return -1; } @@ -1325,11 +1337,10 @@ wdsize(dev_t dev) return (int)du->dk_dd.d_partitions[part].p_size; } -extern char *vmmap; /* poor name! */ - /* dump core after a system crash */ int -wddump(dev_t dev) +wddump(dev) + dev_t dev; { register struct disk *du; /* disk unit to do the IO */ long num; /* number of sectors to write */ @@ -1397,7 +1408,7 @@ wddump(dev_t dev) return EIO; /* some compaq controllers require this ... */ - wdsetctlr(dev, du); + wdsetctlr(du); blknum = dumplo + blkoff; while (num > 0) { @@ -1491,27 +1502,31 @@ wddump(dev_t dev) * Internalize the bad sector table. */ void -bad144intern(struct disk *du) +bad144intern(du) + struct disk *du; { int i; - if (du->dk_flags & DKFL_BADSECT) { - for (i = 0; i < 127; i++) - du->dk_badsect[i] = -1; - for (i = 0; i < 126; i++) { - if (du->dk_cpd.bad.bt_bad[i].bt_cyl == 0xffff) - break; - du->dk_badsect[i] = - du->dk_cpd.bad.bt_bad[i].bt_cyl * - du->dk_dd.d_secpercyl + - (du->dk_cpd.bad.bt_bad[i].bt_trksec >> 8) * - du->dk_dd.d_nsectors + - (du->dk_cpd.bad.bt_bad[i].bt_trksec & 0x00ff); - } + + if ((du->dk_flags & DKFL_BADSECT) == 0) + return; + + for (i = 0; i < 127; i++) + du->dk_badsect[i] = -1; + for (i = 0; i < 126; i++) { + if (du->dk_cpd.bad.bt_bad[i].bt_cyl == 0xffff) + break; + du->dk_badsect[i] = + du->dk_cpd.bad.bt_bad[i].bt_cyl * du->dk_dd.d_secpercyl + + (du->dk_cpd.bad.bt_bad[i].bt_trksec >> 8) * + du->dk_dd.d_nsectors + + (du->dk_cpd.bad.bt_bad[i].bt_trksec & 0x00ff); } } static int -wdreset(struct disk *du, int err) +wdreset(du, err) + struct disk *du; + int err; { int wdc = du->dk_port; int stat; @@ -1522,6 +1537,9 @@ wdreset(struct disk *du, int err) /* reset the device */ outb(wdc+wd_ctlr, WDCTL_RST | WDCTL_IDS); DELAY(1000); + outb(wdc+wd_ctlr, WDCTL_IDS); + DELAY(1000); + (void) inb(wdc+wd_error); outb(wdc+wd_ctlr, WDCTL_4BIT); if (wait_for_unbusy(du) < 0) @@ -1541,9 +1559,9 @@ wdc_wait(du, mask) stat = inb(wdc+wd_altsts); if ((stat & WDCS_BUSY) == 0 && (stat & mask) == mask) break; - DELAY(WDCDELAY); if (++timeout > WDCNDELAY) return -1; + DELAY(WDCDELAY); } #ifdef WDCNDELAY_DEBUG if (timeout > WDCNDELAY_DEBUG) @@ -1554,29 +1572,24 @@ wdc_wait(du, mask) } static int -wdtimeout(caddr_t arg) +wdtimeout(arg) + caddr_t arg; { - int x = splbio(); - register int unit = (int)arg; + int s = splbio(); + struct disk *du = (void *)arg; - if (wdtimeoutstatus[unit] && --wdtimeoutstatus[unit] == 0) { - struct disk *du = wddrives[unit]; + if (du->dk_timeout && --du->dk_timeout == 0) { int wdc = du->dk_port; printf("wd%d: lost interrupt - status %x, error %x\n", - unit, inb(wdc+wd_status), inb(wdc+wd_error)); - outb(wdc+wd_ctlr, WDCTL_RST | WDCTL_IDS); - DELAY(1000); - outb(wdc+wd_ctlr, WDCTL_IDS); - DELAY(1000); - (void) inb(wdc+wd_error); - outb(wdc+wd_ctlr, WDCTL_4BIT); + du->dk_lunit, inb(wdc+wd_status), inb(wdc+wd_error)); + wdreset(du, 0); du->dk_skip = 0; du->dk_flags |= DKFL_SINGLE; wdstart(du->dk_ctrlr); /* start controller */ } - timeout((timeout_t)wdtimeout, (caddr_t)unit, hz*2); - splx(x); + timeout((timeout_t)wdtimeout, arg, hz); + splx(s); return 0; } diff --git a/sys/dev/isa/wd.c b/sys/dev/isa/wd.c index 1b2a55fee96..33e15e1ecb9 100644 --- a/sys/dev/isa/wd.c +++ b/sys/dev/isa/wd.c @@ -35,15 +35,12 @@ * SUCH DAMAGE. * * from: @(#)wd.c 7.2 (Berkeley) 5/9/91 - * $Id: wd.c,v 1.54 1994/03/03 01:58:21 mycroft Exp $ + * $Id: wd.c,v 1.55 1994/03/04 03:43:48 mycroft Exp $ */ #define QUIETWORKS /* define this to make wdopen() set DKFL_QUIET */ #define INSTRUMENT /* instrumentation stuff by Brad Parker */ -/* TODO: peel out buffer at low ipl, speed improvement */ -/* TODO: find and fix the timing bugs apparent on some controllers */ - #include "wd.h" #if NWDC > 0 @@ -113,6 +110,7 @@ struct disk { char dk_unit; /* physical unit number */ char dk_lunit; /* logical unit number */ char dk_state; /* control state */ + int dk_timeout; /* timeout counter */ u_char dk_status; /* copy of status reg. */ u_char dk_error; /* copy of error reg. */ short dk_port; /* i/o port base */ @@ -144,7 +142,6 @@ struct buf wdtab[NWDC]; /* various per-controller info */ struct buf wdutab[NWD]; /* head of queue per drive */ struct buf rwdbuf[NWD]; /* buffers for raw IO */ long wdxfer[NWD]; /* count of transfers */ -int wdtimeoutstatus[NWD]; /* timeout counters */ int wdprobe(), wdattach(); @@ -152,17 +149,17 @@ struct isa_driver wdcdriver = { wdprobe, wdattach, "wdc", }; -static void wdustart(struct disk *); -static void wdstart(int); -static int wdcommand(struct disk *, int); -static int wdcontrol(struct buf *); -static int wdsetctlr(dev_t, struct disk *); -static int wdgetctlr(int, struct disk *); -static void bad144intern(struct disk *); -static int wdreset(struct disk *, int); -static int wdtimeout(caddr_t); -void wddisksort(struct buf *dp, struct buf *bp); -int wdc_wait(struct disk *, int); +static void wdustart __P((struct disk *)); +static void wdstart __P((int)); +static int wdcommand __P((struct disk *, int)); +static int wdcontrol __P((struct buf *)); +static int wdsetctlr __P((struct disk *)); +static int wdgetctlr __P((struct disk *)); +static void bad144intern __P((struct disk *)); +static int wdreset __P((struct disk *, int)); +static int wdtimeout __P((caddr_t)); +void wddisksort __P((struct buf *dp, struct buf *bp)); +int wdc_wait __P((struct disk *, int)); #define wait_for_drq(d) wdc_wait(d, WDCS_DRQ) #define wait_for_ready(d) wdc_wait(d, WDCS_READY | WDCS_SEEKCMPLT) #define wait_for_unbusy(d) wdc_wait(d, 0) @@ -171,23 +168,24 @@ int wdc_wait(struct disk *, int); * Probe for controller. */ int -wdprobe(struct isa_device *dvp) +wdprobe(isa_dev) + struct isa_device *isa_dev; { struct disk *du; int wdc; - if (dvp->id_unit >= NWDC) + if (isa_dev->id_unit >= NWDC) return 0; du = (struct disk *)malloc(sizeof(struct disk), M_TEMP, M_NOWAIT); bzero(du, sizeof(struct disk)); - du->dk_ctrlr = dvp->id_unit; + du->dk_ctrlr = isa_dev->id_unit; du->dk_unit = 0; du->dk_lunit = 0; - wdcontroller[dvp->id_unit].dkc_port = dvp->id_iobase; + wdcontroller[isa_dev->id_unit].dkc_port = isa_dev->id_iobase; - wdc = du->dk_port = dvp->id_iobase; + wdc = du->dk_port = isa_dev->id_iobase; /* check if we have registers that work */ outb(wdc+wd_error, 0x5a); /* error register not writable */ @@ -214,24 +212,25 @@ nodevice: * Attach each drive if possible. */ int -wdattach(struct isa_device *dvp) +wdattach(isa_dev) + struct isa_device *isa_dev; { int unit, lunit; struct disk *du; - if (dvp->id_masunit == -1) + if (isa_dev->id_masunit == -1) return 0; - if (dvp->id_masunit >= NWDC) + if (isa_dev->id_masunit >= NWDC) return 0; - lunit = dvp->id_unit; + lunit = isa_dev->id_unit; if (lunit == -1) { - printf("wdc%d: cannot support unit ?\n", dvp->id_masunit); + printf("wdc%d: cannot support unit ?\n", isa_dev->id_masunit); return 0; } if (lunit >= NWD) return 0; - unit = dvp->id_physid; + unit = isa_dev->id_physid; du = wddrives[lunit] = (struct disk *)malloc(sizeof(struct disk), M_TEMP, M_NOWAIT); @@ -239,18 +238,17 @@ wdattach(struct isa_device *dvp) bzero(&wdutab[lunit], sizeof(struct buf)); bzero(&rwdbuf[lunit], sizeof(struct buf)); wdxfer[lunit] = 0; - wdtimeoutstatus[lunit] = 0; - wdtimeout(lunit); - du->dk_ctrlr = dvp->id_masunit; + wdtimeout((caddr_t)du); + du->dk_ctrlr = isa_dev->id_masunit; du->dk_unit = unit; du->dk_lunit = lunit; - du->dk_port = wdcontroller[dvp->id_masunit].dkc_port; + du->dk_port = wdcontroller[isa_dev->id_masunit].dkc_port; - if (wdgetctlr(unit, du) == 0) { + if (wdgetctlr(du) == 0) { int i, blank; - printf("wd%d at wdc%d targ %d: ", dvp->id_unit, - dvp->id_masunit, dvp->id_physid); + printf("wd%d at wdc%d targ %d: ", isa_dev->id_unit, + isa_dev->id_masunit, isa_dev->id_physid); if (du->dk_params.wdp_heads == 0) printf("(unknown size) <"); else @@ -278,7 +276,7 @@ wdattach(struct isa_device *dvp) printf(">\n"); } else { /*printf("wd%d at wdc%d slave %d -- error\n", lunit, - dvp->id_masunit, unit);*/ + isa_dev->id_masunit, unit);*/ wddrives[lunit] = 0; free(du, M_TEMP); return 0; @@ -292,9 +290,10 @@ wdattach(struct isa_device *dvp) * be a multiple of a sector in length. */ int -wdstrategy(register struct buf *bp) +wdstrategy(bp) + struct buf *bp; { - register struct buf *dp; + struct buf *dp; struct disk *du; /* Disk unit to do the IO. */ int lunit = WDUNIT(bp->b_dev); int s; @@ -349,9 +348,10 @@ done: * Need to skip over multitransfer bufs. */ void -wddisksort(struct buf *dp, struct buf *bp) +wddisksort(dp, bp) + struct buf *dp, *bp; { - register struct buf *ap; + struct buf *ap; while ((ap = dp->b_actf) && ap->b_flags & B_XXX) dp = ap; @@ -364,9 +364,10 @@ wddisksort(struct buf *dp, struct buf *bp) * If the controller is idle, the transfer is started. */ static void -wdustart(register struct disk *du) +wdustart(du) + struct disk *du; { - register struct buf *dp = &wdutab[du->dk_lunit]; + struct buf *dp = &wdutab[du->dk_lunit]; int ctrlr = du->dk_ctrlr; /* unit already active? */ @@ -397,7 +398,8 @@ wdustart(register struct disk *du) * 1. The transfer length must be an exact multiple of the sector size. */ static void -wdstart(int ctrlr) +wdstart(ctrlr) + int ctrlr; { register struct disk *du; /* disk unit for IO */ register struct buf *bp; @@ -430,7 +432,7 @@ loop: du = wddrives[lunit]; /* clear any pending timeout, just in case */ - wdtimeoutstatus[lunit] = 0; + du->dk_timeout = 0; /* if not really a transfer, do control operations specially */ if (du->dk_state < OPEN) { @@ -606,7 +608,7 @@ retry: /* if this is a read operation, just go away until it's done. */ if (bp->b_flags & B_READ) { - wdtimeoutstatus[lunit] = 2; + du->dk_timeout = 2; return; } @@ -621,7 +623,7 @@ retry: du->dk_bc -= DEV_BSIZE; du->dk_bct -= DEV_BSIZE; - wdtimeoutstatus[lunit] = 2; + du->dk_timeout = 2; } /* Interrupt routine for the controller. Acknowledge the interrupt, check for @@ -630,7 +632,8 @@ retry: * continue with the next chunk if so. */ void -wdintr(int ctrlr) +wdintr(ctrlr) + int ctrlr; { register struct disk *du; register struct buf *bp, *dp; @@ -645,7 +648,7 @@ wdintr(int ctrlr) bp = dp->b_actf; du = wddrives[WDUNIT(bp->b_dev)]; wdc = du->dk_port; - wdtimeoutstatus[WDUNIT(bp->b_dev)] = 0; + du->dk_timeout = 0; #ifdef WDDEBUG printf("I%d ", ctrlr); @@ -799,7 +802,11 @@ done: * Initialize a drive. */ int -wdopen(dev_t dev, int flags, int fmt, struct proc *p) +wdopen(dev, flag, fmt, p) + dev_t dev; + int flag; + int fmt; + struct proc *p; { int lunit; struct disk *du; @@ -842,11 +849,11 @@ wdopen(dev_t dev, int flags, int fmt, struct proc *p) du->dk_state = WANTOPEN; /* read label using "raw" partition */ -#if defined(TIHMODS) && defined(garbage) - /* wdsetctlr(dev, du); */ /* Maybe do this TIH */ +#ifdef notdef + /* wdsetctlr(du); */ /* Maybe do this TIH */ msg = readdisklabel(makewddev(major(dev), WDUNIT(dev), WDRAW), wdstrategy, &du->dk_dd, &du->dk_cpd); - wdsetctlr(dev, du); + wdsetctlr(du); #endif if (msg = readdisklabel(makewddev(major(dev), WDUNIT(dev), WDRAW), wdstrategy, &du->dk_dd, &du->dk_cpd)) { @@ -857,7 +864,7 @@ wdopen(dev_t dev, int flags, int fmt, struct proc *p) return EINVAL; /* XXX needs translation */ } } else { - wdsetctlr(dev, du); + wdsetctlr(du); du->dk_flags |= DKFL_BSDLABEL; du->dk_flags &= ~DKFL_WRITEPROT; if (du->dk_dd.d_flags & D_BADSECT) @@ -917,7 +924,8 @@ wdopen(dev_t dev, int flags, int fmt, struct proc *p) * Returns 0 if operation still in progress, 1 if completed. */ static int -wdcontrol(register struct buf *bp) +wdcontrol(bp) + struct buf *bp; { struct disk *du; int unit, lunit; @@ -938,27 +946,23 @@ wdcontrol(register struct buf *bp) printf("wd%d: recal ", lunit); #endif s = splbio(); /* not called from intr level ... */ - wdgetctlr(unit, du); + wdgetctlr(du); if (wait_for_unbusy(du) < 0) { + lose: wdreset(du, 1); goto tryagainrecal; } - outb(wdc+wd_sdh, WDSD_IBM | (unit << 4)); - if (wait_for_ready(du) < 0) { - wdreset(du, 1); - goto tryagainrecal; - } - + if (wait_for_ready(du) < 0) + goto lose; wdtab[ctrlr].b_active = 1; - if (wdcommand(du, WDCC_RESTORE | WD_STEP) < 0) { - wdreset(du, 1); - goto tryagainrecal; - } + if (wdcommand(du, WDCC_RESTORE | WD_STEP) < 0) + goto lose; du->dk_state = RECAL; splx(s); return 0; + case RECAL: if ((stat = inb(wdc+wd_altsts)) & WDCS_ERR) { if ((du->dk_flags & DKFL_QUIET) == 0) { @@ -973,7 +977,7 @@ wdcontrol(register struct buf *bp) } /* some controllers require this ... */ - wdsetctlr(bp->b_dev, du); + wdsetctlr(du); wdtab[ctrlr].b_errcnt = 0; du->dk_state = OPEN; @@ -982,6 +986,7 @@ wdcontrol(register struct buf *bp) * by normal means. */ return 1; + default: panic("wdcontrol"); } @@ -1002,7 +1007,9 @@ badopen: * assumes interrupts are blocked. */ static int -wdcommand(struct disk *du, int cmd) +wdcommand(du, cmd) + struct disk *du; + int cmd; { int stat, wdc; @@ -1037,7 +1044,8 @@ wdcommand(struct disk *du, int cmd) * issue IDC to drive to tell it just what geometry it is to be. */ static int -wdsetctlr(dev_t dev, struct disk *du) +wdsetctlr(du) + struct disk *du; { int stat, s, wdc; @@ -1070,7 +1078,8 @@ wdsetctlr(dev_t dev, struct disk *du) * issue READP to drive to ask it what it is. */ static int -wdgetctlr(int u, struct disk *du) +wdgetctlr(du) + struct disk *du; { int stat, s, i, wdc; char tb[DEV_BSIZE]; @@ -1079,21 +1088,16 @@ wdgetctlr(int u, struct disk *du) s = splbio(); /* not called from intr level ... */ wdc = du->dk_port; if (wait_for_unbusy(du) < 0) { + lose: splx(s); return -1; } - - outb(wdc+wd_sdh, WDSD_IBM | (u << 4)); - if (wait_for_ready(du) < 0) { - splx(s); - return -1; - } - + outb(wdc+wd_sdh, WDSD_IBM | (du->dk_unit << 4)); + if (wait_for_ready(du) < 0) + goto lose; stat = wdcommand(du, WDCC_READP); - if (stat < 0) { - splx(s); - return -1; - } + if (stat < 0) + goto lose; if ((stat & WDCS_ERR) == 0) { /* obtain parameters */ @@ -1157,10 +1161,11 @@ wdgetctlr(int u, struct disk *du) return 0; } - -/* ARGSUSED */ int -wdclose(dev_t dev, int flags, int fmt) +wdclose(dev, flag, fmt) + dev_t dev; + int flag; + int fmt; { struct disk *du; int part = WDPART(dev), mask = 1 << part; @@ -1181,7 +1186,12 @@ wdclose(dev_t dev, int flags, int fmt) } int -wdioctl(dev_t dev, int cmd, caddr_t addr, int flag, struct proc *p) +wdioctl(dev, cmd, addr, flag, p) + dev_t dev; + int cmd; + caddr_t addr; + int flag; + struct proc *p; { int lunit = WDUNIT(dev); struct disk *du = wddrives[lunit]; @@ -1214,7 +1224,7 @@ wdioctl(dev_t dev, int cmd, caddr_t addr, int flag, struct proc *p) &du->dk_cpd); if (error == 0) { du->dk_flags |= DKFL_BSDLABEL; - wdsetctlr(dev, du); + wdsetctlr(du); } return error; @@ -1237,7 +1247,7 @@ wdioctl(dev_t dev, int cmd, caddr_t addr, int flag, struct proc *p) int wlab; du->dk_flags |= DKFL_BSDLABEL; - wdsetctlr(dev, du); + wdsetctlr(du); /* simulate opening partition 0 so write succeeds */ du->dk_openpart |= (1 << 0); /* XXX */ @@ -1300,7 +1310,8 @@ wdformat(struct buf *bp) #endif int -wdsize(dev_t dev) +wdsize(dev) + dev_t dev; { int lunit = WDUNIT(dev), part = WDPART(dev); struct disk *du; @@ -1315,6 +1326,7 @@ wdsize(dev_t dev) int val; val = wdopen(makewddev(major(dev), lunit, WDRAW), FREAD, S_IFBLK, 0); + /* XXX Clear the open flag? */ if (val != 0) return -1; } @@ -1325,11 +1337,10 @@ wdsize(dev_t dev) return (int)du->dk_dd.d_partitions[part].p_size; } -extern char *vmmap; /* poor name! */ - /* dump core after a system crash */ int -wddump(dev_t dev) +wddump(dev) + dev_t dev; { register struct disk *du; /* disk unit to do the IO */ long num; /* number of sectors to write */ @@ -1397,7 +1408,7 @@ wddump(dev_t dev) return EIO; /* some compaq controllers require this ... */ - wdsetctlr(dev, du); + wdsetctlr(du); blknum = dumplo + blkoff; while (num > 0) { @@ -1491,27 +1502,31 @@ wddump(dev_t dev) * Internalize the bad sector table. */ void -bad144intern(struct disk *du) +bad144intern(du) + struct disk *du; { int i; - if (du->dk_flags & DKFL_BADSECT) { - for (i = 0; i < 127; i++) - du->dk_badsect[i] = -1; - for (i = 0; i < 126; i++) { - if (du->dk_cpd.bad.bt_bad[i].bt_cyl == 0xffff) - break; - du->dk_badsect[i] = - du->dk_cpd.bad.bt_bad[i].bt_cyl * - du->dk_dd.d_secpercyl + - (du->dk_cpd.bad.bt_bad[i].bt_trksec >> 8) * - du->dk_dd.d_nsectors + - (du->dk_cpd.bad.bt_bad[i].bt_trksec & 0x00ff); - } + + if ((du->dk_flags & DKFL_BADSECT) == 0) + return; + + for (i = 0; i < 127; i++) + du->dk_badsect[i] = -1; + for (i = 0; i < 126; i++) { + if (du->dk_cpd.bad.bt_bad[i].bt_cyl == 0xffff) + break; + du->dk_badsect[i] = + du->dk_cpd.bad.bt_bad[i].bt_cyl * du->dk_dd.d_secpercyl + + (du->dk_cpd.bad.bt_bad[i].bt_trksec >> 8) * + du->dk_dd.d_nsectors + + (du->dk_cpd.bad.bt_bad[i].bt_trksec & 0x00ff); } } static int -wdreset(struct disk *du, int err) +wdreset(du, err) + struct disk *du; + int err; { int wdc = du->dk_port; int stat; @@ -1522,6 +1537,9 @@ wdreset(struct disk *du, int err) /* reset the device */ outb(wdc+wd_ctlr, WDCTL_RST | WDCTL_IDS); DELAY(1000); + outb(wdc+wd_ctlr, WDCTL_IDS); + DELAY(1000); + (void) inb(wdc+wd_error); outb(wdc+wd_ctlr, WDCTL_4BIT); if (wait_for_unbusy(du) < 0) @@ -1541,9 +1559,9 @@ wdc_wait(du, mask) stat = inb(wdc+wd_altsts); if ((stat & WDCS_BUSY) == 0 && (stat & mask) == mask) break; - DELAY(WDCDELAY); if (++timeout > WDCNDELAY) return -1; + DELAY(WDCDELAY); } #ifdef WDCNDELAY_DEBUG if (timeout > WDCNDELAY_DEBUG) @@ -1554,29 +1572,24 @@ wdc_wait(du, mask) } static int -wdtimeout(caddr_t arg) +wdtimeout(arg) + caddr_t arg; { - int x = splbio(); - register int unit = (int)arg; + int s = splbio(); + struct disk *du = (void *)arg; - if (wdtimeoutstatus[unit] && --wdtimeoutstatus[unit] == 0) { - struct disk *du = wddrives[unit]; + if (du->dk_timeout && --du->dk_timeout == 0) { int wdc = du->dk_port; printf("wd%d: lost interrupt - status %x, error %x\n", - unit, inb(wdc+wd_status), inb(wdc+wd_error)); - outb(wdc+wd_ctlr, WDCTL_RST | WDCTL_IDS); - DELAY(1000); - outb(wdc+wd_ctlr, WDCTL_IDS); - DELAY(1000); - (void) inb(wdc+wd_error); - outb(wdc+wd_ctlr, WDCTL_4BIT); + du->dk_lunit, inb(wdc+wd_status), inb(wdc+wd_error)); + wdreset(du, 0); du->dk_skip = 0; du->dk_flags |= DKFL_SINGLE; wdstart(du->dk_ctrlr); /* start controller */ } - timeout((timeout_t)wdtimeout, (caddr_t)unit, hz*2); - splx(x); + timeout((timeout_t)wdtimeout, arg, hz); + splx(s); return 0; } |
