summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjoerg <joerg@FreeBSD.org>1994-10-21 16:58:50 +0000
committerjoerg <joerg@FreeBSD.org>1994-10-21 16:58:50 +0000
commit945b826761b5a8cee200b2cfc8d3ef87bafe6eef (patch)
tree658709f1b88c51d5623bcb32d7386ec9c0db8093
parente52bf400dfc0a15bee44756c5fe29eea0db4ead7 (diff)
downloadFreeBSD-src-945b826761b5a8cee200b2cfc8d3ef87bafe6eef.zip
FreeBSD-src-945b826761b5a8cee200b2cfc8d3ef87bafe6eef.tar.gz
Checking for timeout at several critical calls to ``out_fdc()'' now,
so i hope i've finally removed all the occasions where the driver got stuck when there's no floppy in the drive. Also attemmpting to omit the error mesage for ``recalib failed'' for the first time, since people tend to be confused about this.
-rw-r--r--sys/dev/fdc/fdc.c70
-rw-r--r--sys/i386/isa/fd.c70
-rw-r--r--sys/isa/fd.c70
3 files changed, 168 insertions, 42 deletions
diff --git a/sys/dev/fdc/fdc.c b/sys/dev/fdc/fdc.c
index a645d34..edbb903 100644
--- a/sys/dev/fdc/fdc.c
+++ b/sys/dev/fdc/fdc.c
@@ -40,7 +40,7 @@
* SUCH DAMAGE.
*
* from: @(#)fd.c 7.4 (Berkeley) 5/25/91
- * $Id: fd.c,v 1.33 1994/10/10 01:12:25 phk Exp $
+ * $Id: fd.c,v 1.35 1994/10/19 01:58:56 wollman Exp $
*
*/
@@ -552,6 +552,11 @@ set_motor(fdcu, fdsu, turnon)
TRACE1("[0x%x->FDOUT]", fdout);
if(needspecify) {
+ /*
+ * special case: since we have just woken up the FDC
+ * from its sleep, we silently assume the command will
+ * be accepted, and do not test for a timeout
+ */
out_fdc(fdcu, NE7CMD_SPECIFY);
out_fdc(fdcu, NE7_SPEC_1(3, 240));
out_fdc(fdcu, NE7_SPEC_2(2, 0));
@@ -619,6 +624,7 @@ fdc_reset(fdc)
outb(fdc->baseport + FDOUT, fdc->fdout);
TRACE1("[0x%x->FDOUT]", fdc->fdout);
+ /* after a reset, silently believe the FDC will accept commands */
out_fdc(fdcu, NE7CMD_SPECIFY);
out_fdc(fdcu, NE7_SPEC_1(3, 240));
out_fdc(fdcu, NE7_SPEC_2(2, 0));
@@ -1047,7 +1053,15 @@ fdstate(fdcu, fdc)
fdc->state = SEEKCOMPLETE;
break;
}
- out_fdc(fdcu, NE7CMD_SEEK); /* Seek function */
+ if(out_fdc(fdcu, NE7CMD_SEEK) < 0) /* Seek function */
+ {
+ /*
+ * seek command not accepted, looks like
+ * the FDC went off to the Saints...
+ */
+ fdc->retry = 6; /* try a reset */
+ return(retrier(fdcu));
+ }
out_fdc(fdcu, fd->fdsu); /* Drive number */
out_fdc(fdcu, bp->b_cylin * fd->ft->steptrac);
fd->track = -2;
@@ -1117,7 +1131,12 @@ fdstate(fdcu, fdc)
if(format || !read)
{
/* make sure the drive is writable */
- out_fdc(fdcu, NE7CMD_SENSED);
+ if(out_fdc(fdcu, NE7CMD_SENSED) < 0)
+ {
+ /* stuck controller? */
+ fdc->retry = 6; /* reset the beast */
+ return(retrier(fdcu));
+ }
out_fdc(fdcu, fdu);
st3 = in_fdc(fdcu);
if(st3 & NE7_ST3_WP)
@@ -1144,7 +1163,12 @@ fdstate(fdcu, fdc)
if(format)
{
/* formatting */
- out_fdc(fdcu, NE7CMD_FORMAT);
+ if(out_fdc(fdcu, NE7CMD_FORMAT) < 0)
+ {
+ /* controller fell over */
+ fdc->retry = 6;
+ return(retrier(fdcu));
+ }
out_fdc(fdcu, head << 2 | fdu);
out_fdc(fdcu, finfo->fd_formb_secshift);
out_fdc(fdcu, finfo->fd_formb_nsecs);
@@ -1153,13 +1177,13 @@ fdstate(fdcu, fdc)
}
else
{
- if (read)
- {
- out_fdc(fdcu, NE7CMD_READ); /* READ */
- }
- else
+ if ((read && out_fdc(fdcu, NE7CMD_READ) < 0)
+ || (!read /* i.e., write */
+ && out_fdc(fdcu, NE7CMD_WRITE) < 0))
{
- out_fdc(fdcu, NE7CMD_WRITE); /* WRITE */
+ /* the beast is sleeping again */
+ fdc->retry = 6;
+ return(retrier(fdcu));
}
out_fdc(fdcu, head << 2 | fdu); /* head & unit */
out_fdc(fdcu, fd->track); /* track */
@@ -1236,7 +1260,12 @@ fdstate(fdcu, fdc)
fdc->state = STARTRECAL;
break;
case STARTRECAL:
- out_fdc(fdcu, NE7CMD_RECAL); /* Recalibrate Function */
+ if(out_fdc(fdcu, NE7CMD_RECAL) < 0) /* Recalibrate Function */
+ {
+ /* arrgl */
+ fdc->retry = 6;
+ return(retrier(fdcu));
+ }
out_fdc(fdcu, fdu);
fdc->state = RECALWAIT;
return(0); /* will return later */
@@ -1258,8 +1287,17 @@ fdstate(fdcu, fdc)
} while ((st0 & NE7_ST0_IC) == NE7_ST0_IC_RC);
if ((st0 & NE7_ST0_IC) != NE7_ST0_IC_NT || cyl != 0)
{
- printf("fd%d: recal failed ST0 %b cyl %d\n", fdu,
- st0, NE7_ST0BITS, cyl);
+ if(fdc->retry > 3)
+ /*
+ * a recalibrate from beyond cylinder 77
+ * will "fail" due to the FDC limitations;
+ * since people used to complain much about
+ * the failure message, try not logging
+ * this one if it seems to be the first
+ * time in a line
+ */
+ printf("fd%d: recal failed ST0 %b cyl %d\n",
+ fdu, st0, NE7_ST0BITS, cyl);
if(fdc->retry < 3) fdc->retry = 3;
return(retrier(fdcu));
}
@@ -1281,7 +1319,11 @@ fdstate(fdcu, fdc)
return(1); /* will return immediatly */
default:
printf("Unexpected FD int->");
- out_fdc(fdcu, NE7CMD_SENSEI);
+ if(out_fdc(fdcu, NE7CMD_SENSEI) < 0)
+ {
+ printf("[controller is dead now]\n");
+ return(0);
+ }
st0 = in_fdc(fdcu);
cyl = in_fdc(fdcu);
printf("ST0 = %x, PCN = %x\n", st0, cyl);
diff --git a/sys/i386/isa/fd.c b/sys/i386/isa/fd.c
index a645d34..edbb903 100644
--- a/sys/i386/isa/fd.c
+++ b/sys/i386/isa/fd.c
@@ -40,7 +40,7 @@
* SUCH DAMAGE.
*
* from: @(#)fd.c 7.4 (Berkeley) 5/25/91
- * $Id: fd.c,v 1.33 1994/10/10 01:12:25 phk Exp $
+ * $Id: fd.c,v 1.35 1994/10/19 01:58:56 wollman Exp $
*
*/
@@ -552,6 +552,11 @@ set_motor(fdcu, fdsu, turnon)
TRACE1("[0x%x->FDOUT]", fdout);
if(needspecify) {
+ /*
+ * special case: since we have just woken up the FDC
+ * from its sleep, we silently assume the command will
+ * be accepted, and do not test for a timeout
+ */
out_fdc(fdcu, NE7CMD_SPECIFY);
out_fdc(fdcu, NE7_SPEC_1(3, 240));
out_fdc(fdcu, NE7_SPEC_2(2, 0));
@@ -619,6 +624,7 @@ fdc_reset(fdc)
outb(fdc->baseport + FDOUT, fdc->fdout);
TRACE1("[0x%x->FDOUT]", fdc->fdout);
+ /* after a reset, silently believe the FDC will accept commands */
out_fdc(fdcu, NE7CMD_SPECIFY);
out_fdc(fdcu, NE7_SPEC_1(3, 240));
out_fdc(fdcu, NE7_SPEC_2(2, 0));
@@ -1047,7 +1053,15 @@ fdstate(fdcu, fdc)
fdc->state = SEEKCOMPLETE;
break;
}
- out_fdc(fdcu, NE7CMD_SEEK); /* Seek function */
+ if(out_fdc(fdcu, NE7CMD_SEEK) < 0) /* Seek function */
+ {
+ /*
+ * seek command not accepted, looks like
+ * the FDC went off to the Saints...
+ */
+ fdc->retry = 6; /* try a reset */
+ return(retrier(fdcu));
+ }
out_fdc(fdcu, fd->fdsu); /* Drive number */
out_fdc(fdcu, bp->b_cylin * fd->ft->steptrac);
fd->track = -2;
@@ -1117,7 +1131,12 @@ fdstate(fdcu, fdc)
if(format || !read)
{
/* make sure the drive is writable */
- out_fdc(fdcu, NE7CMD_SENSED);
+ if(out_fdc(fdcu, NE7CMD_SENSED) < 0)
+ {
+ /* stuck controller? */
+ fdc->retry = 6; /* reset the beast */
+ return(retrier(fdcu));
+ }
out_fdc(fdcu, fdu);
st3 = in_fdc(fdcu);
if(st3 & NE7_ST3_WP)
@@ -1144,7 +1163,12 @@ fdstate(fdcu, fdc)
if(format)
{
/* formatting */
- out_fdc(fdcu, NE7CMD_FORMAT);
+ if(out_fdc(fdcu, NE7CMD_FORMAT) < 0)
+ {
+ /* controller fell over */
+ fdc->retry = 6;
+ return(retrier(fdcu));
+ }
out_fdc(fdcu, head << 2 | fdu);
out_fdc(fdcu, finfo->fd_formb_secshift);
out_fdc(fdcu, finfo->fd_formb_nsecs);
@@ -1153,13 +1177,13 @@ fdstate(fdcu, fdc)
}
else
{
- if (read)
- {
- out_fdc(fdcu, NE7CMD_READ); /* READ */
- }
- else
+ if ((read && out_fdc(fdcu, NE7CMD_READ) < 0)
+ || (!read /* i.e., write */
+ && out_fdc(fdcu, NE7CMD_WRITE) < 0))
{
- out_fdc(fdcu, NE7CMD_WRITE); /* WRITE */
+ /* the beast is sleeping again */
+ fdc->retry = 6;
+ return(retrier(fdcu));
}
out_fdc(fdcu, head << 2 | fdu); /* head & unit */
out_fdc(fdcu, fd->track); /* track */
@@ -1236,7 +1260,12 @@ fdstate(fdcu, fdc)
fdc->state = STARTRECAL;
break;
case STARTRECAL:
- out_fdc(fdcu, NE7CMD_RECAL); /* Recalibrate Function */
+ if(out_fdc(fdcu, NE7CMD_RECAL) < 0) /* Recalibrate Function */
+ {
+ /* arrgl */
+ fdc->retry = 6;
+ return(retrier(fdcu));
+ }
out_fdc(fdcu, fdu);
fdc->state = RECALWAIT;
return(0); /* will return later */
@@ -1258,8 +1287,17 @@ fdstate(fdcu, fdc)
} while ((st0 & NE7_ST0_IC) == NE7_ST0_IC_RC);
if ((st0 & NE7_ST0_IC) != NE7_ST0_IC_NT || cyl != 0)
{
- printf("fd%d: recal failed ST0 %b cyl %d\n", fdu,
- st0, NE7_ST0BITS, cyl);
+ if(fdc->retry > 3)
+ /*
+ * a recalibrate from beyond cylinder 77
+ * will "fail" due to the FDC limitations;
+ * since people used to complain much about
+ * the failure message, try not logging
+ * this one if it seems to be the first
+ * time in a line
+ */
+ printf("fd%d: recal failed ST0 %b cyl %d\n",
+ fdu, st0, NE7_ST0BITS, cyl);
if(fdc->retry < 3) fdc->retry = 3;
return(retrier(fdcu));
}
@@ -1281,7 +1319,11 @@ fdstate(fdcu, fdc)
return(1); /* will return immediatly */
default:
printf("Unexpected FD int->");
- out_fdc(fdcu, NE7CMD_SENSEI);
+ if(out_fdc(fdcu, NE7CMD_SENSEI) < 0)
+ {
+ printf("[controller is dead now]\n");
+ return(0);
+ }
st0 = in_fdc(fdcu);
cyl = in_fdc(fdcu);
printf("ST0 = %x, PCN = %x\n", st0, cyl);
diff --git a/sys/isa/fd.c b/sys/isa/fd.c
index a645d34..edbb903 100644
--- a/sys/isa/fd.c
+++ b/sys/isa/fd.c
@@ -40,7 +40,7 @@
* SUCH DAMAGE.
*
* from: @(#)fd.c 7.4 (Berkeley) 5/25/91
- * $Id: fd.c,v 1.33 1994/10/10 01:12:25 phk Exp $
+ * $Id: fd.c,v 1.35 1994/10/19 01:58:56 wollman Exp $
*
*/
@@ -552,6 +552,11 @@ set_motor(fdcu, fdsu, turnon)
TRACE1("[0x%x->FDOUT]", fdout);
if(needspecify) {
+ /*
+ * special case: since we have just woken up the FDC
+ * from its sleep, we silently assume the command will
+ * be accepted, and do not test for a timeout
+ */
out_fdc(fdcu, NE7CMD_SPECIFY);
out_fdc(fdcu, NE7_SPEC_1(3, 240));
out_fdc(fdcu, NE7_SPEC_2(2, 0));
@@ -619,6 +624,7 @@ fdc_reset(fdc)
outb(fdc->baseport + FDOUT, fdc->fdout);
TRACE1("[0x%x->FDOUT]", fdc->fdout);
+ /* after a reset, silently believe the FDC will accept commands */
out_fdc(fdcu, NE7CMD_SPECIFY);
out_fdc(fdcu, NE7_SPEC_1(3, 240));
out_fdc(fdcu, NE7_SPEC_2(2, 0));
@@ -1047,7 +1053,15 @@ fdstate(fdcu, fdc)
fdc->state = SEEKCOMPLETE;
break;
}
- out_fdc(fdcu, NE7CMD_SEEK); /* Seek function */
+ if(out_fdc(fdcu, NE7CMD_SEEK) < 0) /* Seek function */
+ {
+ /*
+ * seek command not accepted, looks like
+ * the FDC went off to the Saints...
+ */
+ fdc->retry = 6; /* try a reset */
+ return(retrier(fdcu));
+ }
out_fdc(fdcu, fd->fdsu); /* Drive number */
out_fdc(fdcu, bp->b_cylin * fd->ft->steptrac);
fd->track = -2;
@@ -1117,7 +1131,12 @@ fdstate(fdcu, fdc)
if(format || !read)
{
/* make sure the drive is writable */
- out_fdc(fdcu, NE7CMD_SENSED);
+ if(out_fdc(fdcu, NE7CMD_SENSED) < 0)
+ {
+ /* stuck controller? */
+ fdc->retry = 6; /* reset the beast */
+ return(retrier(fdcu));
+ }
out_fdc(fdcu, fdu);
st3 = in_fdc(fdcu);
if(st3 & NE7_ST3_WP)
@@ -1144,7 +1163,12 @@ fdstate(fdcu, fdc)
if(format)
{
/* formatting */
- out_fdc(fdcu, NE7CMD_FORMAT);
+ if(out_fdc(fdcu, NE7CMD_FORMAT) < 0)
+ {
+ /* controller fell over */
+ fdc->retry = 6;
+ return(retrier(fdcu));
+ }
out_fdc(fdcu, head << 2 | fdu);
out_fdc(fdcu, finfo->fd_formb_secshift);
out_fdc(fdcu, finfo->fd_formb_nsecs);
@@ -1153,13 +1177,13 @@ fdstate(fdcu, fdc)
}
else
{
- if (read)
- {
- out_fdc(fdcu, NE7CMD_READ); /* READ */
- }
- else
+ if ((read && out_fdc(fdcu, NE7CMD_READ) < 0)
+ || (!read /* i.e., write */
+ && out_fdc(fdcu, NE7CMD_WRITE) < 0))
{
- out_fdc(fdcu, NE7CMD_WRITE); /* WRITE */
+ /* the beast is sleeping again */
+ fdc->retry = 6;
+ return(retrier(fdcu));
}
out_fdc(fdcu, head << 2 | fdu); /* head & unit */
out_fdc(fdcu, fd->track); /* track */
@@ -1236,7 +1260,12 @@ fdstate(fdcu, fdc)
fdc->state = STARTRECAL;
break;
case STARTRECAL:
- out_fdc(fdcu, NE7CMD_RECAL); /* Recalibrate Function */
+ if(out_fdc(fdcu, NE7CMD_RECAL) < 0) /* Recalibrate Function */
+ {
+ /* arrgl */
+ fdc->retry = 6;
+ return(retrier(fdcu));
+ }
out_fdc(fdcu, fdu);
fdc->state = RECALWAIT;
return(0); /* will return later */
@@ -1258,8 +1287,17 @@ fdstate(fdcu, fdc)
} while ((st0 & NE7_ST0_IC) == NE7_ST0_IC_RC);
if ((st0 & NE7_ST0_IC) != NE7_ST0_IC_NT || cyl != 0)
{
- printf("fd%d: recal failed ST0 %b cyl %d\n", fdu,
- st0, NE7_ST0BITS, cyl);
+ if(fdc->retry > 3)
+ /*
+ * a recalibrate from beyond cylinder 77
+ * will "fail" due to the FDC limitations;
+ * since people used to complain much about
+ * the failure message, try not logging
+ * this one if it seems to be the first
+ * time in a line
+ */
+ printf("fd%d: recal failed ST0 %b cyl %d\n",
+ fdu, st0, NE7_ST0BITS, cyl);
if(fdc->retry < 3) fdc->retry = 3;
return(retrier(fdcu));
}
@@ -1281,7 +1319,11 @@ fdstate(fdcu, fdc)
return(1); /* will return immediatly */
default:
printf("Unexpected FD int->");
- out_fdc(fdcu, NE7CMD_SENSEI);
+ if(out_fdc(fdcu, NE7CMD_SENSEI) < 0)
+ {
+ printf("[controller is dead now]\n");
+ return(0);
+ }
st0 = in_fdc(fdcu);
cyl = in_fdc(fdcu);
printf("ST0 = %x, PCN = %x\n", st0, cyl);
OpenPOWER on IntegriCloud