Module Name: src Committed By: tsutsui Date: Sun Apr 10 15:23:06 UTC 2011
Modified Files: src/sys/arch/x68k/dev: fd.c Log Message: Fix hangup on the first floppy access since 2008. Problem was reported by isaki@. On X680x0 (and most other machines other than ISA FDC), the ready line from FDD is connected to FDC and fdc driver can be notified of the ready state after fd_set_motor() by interrupts. In this case no need to use callout(9) to wait the FDD motor stabilized, and the callout(9) method used in ISA fdc(4) driver rather caused infinite unhandled interrupts since callout(9) was no longer invoked during interrupt storm after vmlocking2 merge, I guess. Should be pulled up to netbsd-5. To generate a diff of this commit: cvs rdiff -u -r1.93 -r1.94 src/sys/arch/x68k/dev/fd.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/arch/x68k/dev/fd.c diff -u src/sys/arch/x68k/dev/fd.c:1.93 src/sys/arch/x68k/dev/fd.c:1.94 --- src/sys/arch/x68k/dev/fd.c:1.93 Sun Jun 6 04:52:01 2010 +++ src/sys/arch/x68k/dev/fd.c Sun Apr 10 15:23:06 2011 @@ -1,4 +1,4 @@ -/* $NetBSD: fd.c,v 1.93 2010/06/06 04:52:01 mrg Exp $ */ +/* $NetBSD: fd.c,v 1.94 2011/04/10 15:23:06 tsutsui Exp $ */ /*- * Copyright (c) 1998 The NetBSD Foundation, Inc. @@ -64,7 +64,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: fd.c,v 1.93 2010/06/06 04:52:01 mrg Exp $"); +__KERNEL_RCSID(0, "$NetBSD: fd.c,v 1.94 2011/04/10 15:23:06 tsutsui Exp $"); #include "rnd.h" #include "opt_ddb.h" @@ -212,7 +212,9 @@ struct fd_type *sc_deftype; /* default type descriptor */ struct fd_type *sc_type; /* current type descriptor */ +#if 0 /* see comments in fd_motor_on() */ struct callout sc_motoron_ch; +#endif struct callout sc_motoroff_ch; daddr_t sc_blkno; /* starting block number */ @@ -278,7 +280,9 @@ void fd_set_motor(struct fdc_softc *, int); void fd_motor_off(void *); +#if 0 void fd_motor_on(void *); +#endif int fdcresult(struct fdc_softc *); int out_fdc(bus_space_tag_t, bus_space_handle_t, u_char); void fdcstart(struct fdc_softc *); @@ -564,7 +568,9 @@ struct fd_type *type = &fd_types[0]; /* XXX 1.2MB */ int drive = fa->fa_drive; +#if 0 callout_init(&fd->sc_motoron_ch, 0); +#endif callout_init(&fd->sc_motoroff_ch, 0); fd->sc_dev = self; @@ -788,6 +794,7 @@ splx(s); } +#if 0 /* on x68k motor on triggers interrupts by state change of ready line. */ void fd_motor_on(void *arg) { @@ -803,6 +810,7 @@ (void) fdcintr(fdc); splx(s); } +#endif int fdcresult(struct fdc_softc *fdc) @@ -1082,9 +1090,11 @@ fd->sc_flags |= FD_MOTOR | FD_MOTOR_WAIT; fd_set_motor(fdc, 0); fdc->sc_state = MOTORWAIT; +#if 0 /* no need to callout on x68k; motor on will trigger interrupts */ /* allow .5s for motor to stabilize */ callout_reset(&fd->sc_motoron_ch, hz / 2, fd_motor_on, fd); +#endif return 1; } /* Make sure the right drive is selected. */ @@ -1437,8 +1447,22 @@ goto doseek; case MOTORWAIT: +#if 0 /* on x68k motor on triggers interrupts by state change of ready line. */ if (fd->sc_flags & FD_MOTOR_WAIT) return 1; /* time's not up yet */ +#else + /* check drive ready by state change interrupt */ + KASSERT(fd->sc_flags & FD_MOTOR_WAIT); + out_fdc(iot, ioh, NE7CMD_SENSEI); + tmp = fdcresult(fdc); + if (tmp != 2 || (st0 & 0xc0) != 0xc0 /* ready changed */) { + printf("%s: unexpected interrupt during MOTORWAIT", + device_xname(fd->sc_dev)); + fdcpstatus(7, fdc); + return 1; + } + fd->sc_flags &= ~FD_MOTOR_WAIT; +#endif goto doseek; default: