'wait' based on suggestion by Rod in -hackers.
No functional change as all the TIMEOUTS are identical currently, but
this will probably change.
* SUCH DAMAGE.
*
* from: @(#)wd.c 7.2 (Berkeley) 5/9/91
* SUCH DAMAGE.
*
* from: @(#)wd.c 7.2 (Berkeley) 5/9/91
- * $Id: wd.c,v 1.27 1994/02/07 04:20:57 davidg Exp $
+ * $Id: wd.c,v 1.28 1994/02/07 15:40:38 ache Exp $
#include "syslog.h"
#include "vm/vm.h"
#include "syslog.h"
#include "vm/vm.h"
-#ifndef WDCTIMEOUT
-#define WDCTIMEOUT 10000000 /* arbitrary timeout for drive ready waits */
-#endif
+#define TIMEOUT 10000 /* XXX? WDCC_DIAGNOSE can take > 1.1 sec */
#define RETRIES 5 /* number of retries before giving up */
#define RECOVERYTIME 500000 /* usec for controller to recover after err */
#define RETRIES 5 /* number of retries before giving up */
#define RECOVERYTIME 500000 /* usec for controller to recover after err */
static void wdsleep(int ctrlr, char *wmesg);
static void wdtimeout(caddr_t cdu, int ticks);
static int wdunwedge(struct disk *du);
static void wdsleep(int ctrlr, char *wmesg);
static void wdtimeout(caddr_t cdu, int ticks);
static int wdunwedge(struct disk *du);
-static int wdwait(struct disk *du, u_char bits_wanted);
+static int wdwait(struct disk *du, u_char bits_wanted, int timeout);
struct isa_driver wdcdriver = {
wdprobe, wdattach, "wdc",
struct isa_driver wdcdriver = {
wdprobe, wdattach, "wdc",
/* execute a controller only command */
if (wdcommand(du, 0, 0, 0, 0, WDCC_DIAGNOSE) != 0
/* execute a controller only command */
if (wdcommand(du, 0, 0, 0, 0, WDCC_DIAGNOSE) != 0
+ || wdwait(du, 0, TIMEOUT) != 0)
goto nodevice;
free(du, M_TEMP);
goto nodevice;
free(du, M_TEMP);
return;
/* Ready to send data? */
return;
/* Ready to send data? */
- if (wdwait(du, WDCS_READY | WDCS_SEEKCMPLT | WDCS_DRQ) < 0) {
+ if (wdwait(du, WDCS_READY | WDCS_SEEKCMPLT | WDCS_DRQ, TIMEOUT) < 0) {
wderror(bp, du, "wdstart: timeout waiting for DRQ");
/*
* XXX what do we do now? If we've just issued the command,
wderror(bp, du, "wdstart: timeout waiting for DRQ");
/*
* XXX what do we do now? If we've just issued the command,
du = wddrives[wdunit(bp->b_dev)];
du->dk_timeout = 0;
du = wddrives[wdunit(bp->b_dev)];
du->dk_timeout = 0;
- if (wdwait(du, 0) < 0) {
+ if (wdwait(du, 0, TIMEOUT) < 0) {
wderror(bp, du, "wdintr: timeout waiting for status");
du->dk_status |= WDCS_ERR; /* XXX */
}
wderror(bp, du, "wdintr: timeout waiting for status");
du->dk_status |= WDCS_ERR; /* XXX */
}
chk = min(DEV_BSIZE / sizeof(short), du->dk_bc / sizeof(short));
/* ready to receive data? */
chk = min(DEV_BSIZE / sizeof(short), du->dk_bc / sizeof(short));
/* ready to receive data? */
- if (wdwait(du, WDCS_READY | WDCS_SEEKCMPLT | WDCS_DRQ) != 0) {
+ if (wdwait(du, WDCS_READY | WDCS_SEEKCMPLT | WDCS_DRQ, TIMEOUT) != 0) {
wderror(bp, du, "wdintr: read error detected late");
goto oops;
}
wderror(bp, du, "wdintr: read error detected late");
goto oops;
}
+ if (wdwait(du, 0, TIMEOUT) < 0)
return (1);
wdc = du->dk_port;
outb(wdc + wd_precomp, du->dk_dd.d_precompcyl / 4);
return (1);
wdc = du->dk_port;
outb(wdc + wd_precomp, du->dk_dd.d_precompcyl / 4);
outb(wdc + wd_sector, sector + 1);
outb(wdc + wd_seccnt, count);
if (wdwait(du, command == WDCC_DIAGNOSE || command == WDCC_IDC
outb(wdc + wd_sector, sector + 1);
outb(wdc + wd_seccnt, count);
if (wdwait(du, command == WDCC_DIAGNOSE || command == WDCC_IDC
+ ? 0 : WDCS_READY, TIMEOUT) < 0)
return (1);
outb(wdc + wd_command, command);
return (0);
return (1);
outb(wdc + wd_command, command);
return (0);
}
if (wdcommand(du, du->dk_dd.d_ncylinders, du->dk_dd.d_ntracks - 1, 0,
du->dk_dd.d_nsectors, WDCC_IDC) != 0
}
if (wdcommand(du, du->dk_dd.d_ncylinders, du->dk_dd.d_ntracks - 1, 0,
du->dk_dd.d_nsectors, WDCC_IDC) != 0
- || wdwait(du, WDCS_READY) != 0) {
+ || wdwait(du, WDCS_READY, TIMEOUT) != 0) {
wderror((struct buf *)NULL, du, "wdsetctlr failed");
return (1);
}
wderror((struct buf *)NULL, du, "wdsetctlr failed");
return (1);
}
struct wdparams *wp;
if (wdcommand(du, 0, 0, 0, 0, WDCC_READP) != 0
struct wdparams *wp;
if (wdcommand(du, 0, 0, 0, 0, WDCC_READP) != 0
- || wdwait(du, WDCS_READY | WDCS_SEEKCMPLT | WDCS_DRQ) < 0) {
+ || wdwait(du, WDCS_READY | WDCS_SEEKCMPLT | WDCS_DRQ, TIMEOUT) < 0) {
/* XXX need to check error status after final transfer. */
/*
* Old drives don't support WDCC_READP. Try a seek to 0.
/* XXX need to check error status after final transfer. */
/*
* Old drives don't support WDCC_READP. Try a seek to 0.
* attached, so first test that the drive can be selected.
* This also avoids long waits for nonexistent drives.
*/
* attached, so first test that the drive can be selected.
* This also avoids long waits for nonexistent drives.
*/
+ if (wdwait(du, 0, TIMEOUT) < 0)
return (1);
outb(du->dk_port + wd_sdh, WDSD_IBM | (du->dk_unit << 4));
DELAY(5000); /* usually unnecessary; drive select is fast */
if ((inb(du->dk_port + wd_status) & (WDCS_BUSY | WDCS_READY))
!= WDCS_READY
|| wdcommand(du, 0, 0, 0, 0, WDCC_RESTORE | WD_STEP) != 0
return (1);
outb(du->dk_port + wd_sdh, WDSD_IBM | (du->dk_unit << 4));
DELAY(5000); /* usually unnecessary; drive select is fast */
if ((inb(du->dk_port + wd_status) & (WDCS_BUSY | WDCS_READY))
!= WDCS_READY
|| wdcommand(du, 0, 0, 0, 0, WDCC_RESTORE | WD_STEP) != 0
- || wdwait(du, WDCS_READY | WDCS_SEEKCMPLT) != 0)
+ || wdwait(du, WDCS_READY | WDCS_SEEKCMPLT, TIMEOUT) != 0)
/* Recalibrate the drive. */
DELAY(5); /* ATA spec XXX NOT */
if (wdcommand(du, 0, 0, 0, 0, WDCC_RESTORE | WD_STEP) != 0
/* Recalibrate the drive. */
DELAY(5); /* ATA spec XXX NOT */
if (wdcommand(du, 0, 0, 0, 0, WDCC_RESTORE | WD_STEP) != 0
- || wdwait(du, WDCS_READY | WDCS_SEEKCMPLT) != 0
+ || wdwait(du, WDCS_READY | WDCS_SEEKCMPLT, TIMEOUT) != 0
|| wdsetctlr(du) != 0) {
wderror((struct buf *)NULL, du, "wddump: recalibrate failed");
return (EIO);
|| wdsetctlr(du) != 0) {
wderror((struct buf *)NULL, du, "wddump: recalibrate failed");
return (EIO);
/* Ready to send data? */
DELAY(5); /* ATA spec */
/* Ready to send data? */
DELAY(5); /* ATA spec */
- if (wdwait(du, WDCS_READY | WDCS_SEEKCMPLT | WDCS_DRQ)
+ if (wdwait(du, WDCS_READY | WDCS_SEEKCMPLT | WDCS_DRQ, TIMEOUT)
< 0) {
wderror((struct buf *)NULL, du,
"wddump: timeout waiting for DRQ");
< 0) {
wderror((struct buf *)NULL, du,
"wddump: timeout waiting for DRQ");
/* Wait for completion. */
DELAY(5); /* ATA spec XXX NOT */
/* Wait for completion. */
DELAY(5); /* ATA spec XXX NOT */
- if (wdwait(du, WDCS_READY | WDCS_SEEKCMPLT) < 0) {
+ if (wdwait(du, WDCS_READY | WDCS_SEEKCMPLT, TIMEOUT) < 0) {
wderror((struct buf *)NULL, du,
"wddump: timeout waiting for status");
return (EIO);
wderror((struct buf *)NULL, du,
"wddump: timeout waiting for status");
return (EIO);
int wdc;
wdc = du->dk_port;
int wdc;
wdc = du->dk_port;
+ (void)wdwait(du, 0, TIMEOUT);
outb(wdc + wd_ctlr, WDCTL_IDS | WDCTL_RST);
DELAY(10 * 1000);
outb(wdc + wd_ctlr, WDCTL_IDS);
outb(wdc + wd_ctlr, WDCTL_IDS | WDCTL_RST);
DELAY(10 * 1000);
outb(wdc + wd_ctlr, WDCTL_IDS);
- if (wdwait(du, WDCS_READY | WDCS_SEEKCMPLT) != 0
+ if (wdwait(du, WDCS_READY | WDCS_SEEKCMPLT, TIMEOUT) != 0
|| (du->dk_error = inb(wdc + wd_error)) != 0x01)
return (1);
outb(wdc + wd_ctlr, WDCTL_4BIT);
|| (du->dk_error = inb(wdc + wd_error)) != 0x01)
return (1);
outb(wdc + wd_ctlr, WDCTL_4BIT);
* aren't prepared to have its state change.
*/
if (wdcommand(du, 0, 0, 0, 0, WDCC_RESTORE | WD_STEP) == 0
* aren't prepared to have its state change.
*/
if (wdcommand(du, 0, 0, 0, 0, WDCC_RESTORE | WD_STEP) == 0
- && wdwait(du, WDCS_READY | WDCS_SEEKCMPLT) == 0
+ && wdwait(du, WDCS_READY | WDCS_SEEKCMPLT, TIMEOUT) == 0
&& wdsetctlr(du) == 0)
return (0);
}
&& wdsetctlr(du) == 0)
return (0);
}
-wdwait(struct disk *du, u_char bits_wanted)
+wdwait(struct disk *du, u_char bits_wanted, int timeout)
int wdc;
u_char status;
#define POLLING 1000
int wdc;
u_char status;
#define POLLING 1000
-#define TIMEOUT 10000 /* XXX? WDCC_DIAGNOSE can take > 1.1 sec */
- retries = POLLING + TIMEOUT;
do {
#ifdef WD_COUNT_RETRIES
do {
#ifdef WD_COUNT_RETRIES
- if (min_retries[du->dk_ctrlr] > retries
+ if (min_retries[du->dk_ctrlr] > timeout
|| min_retries[du->dk_ctrlr] == 0)
|| min_retries[du->dk_ctrlr] == 0)
- min_retries[du->dk_ctrlr] = retries;
+ min_retries[du->dk_ctrlr] = timeout;
#endif
DELAY(5); /* ATA spec XXX NOT */
du->dk_status = status = inb(wdc + wd_status);
#endif
DELAY(5); /* ATA spec XXX NOT */
du->dk_status = status = inb(wdc + wd_status);
if ((status & bits_wanted) == bits_wanted)
return (status & WDCS_ERR);
}
if ((status & bits_wanted) == bits_wanted)
return (status & WDCS_ERR);
}
/*
* Switch to a polling rate of about 1 KHz so that
* the timeout is almost machine-independent. The
/*
* Switch to a polling rate of about 1 KHz so that
* the timeout is almost machine-independent. The
* an extra msec won't matter.
*/
DELAY(1000);
* an extra msec won't matter.
*/
DELAY(1000);
- } while (--retries != 0);
+ } while (--timeout != 0);