Commit 53373504 authored by Ingo Molnar's avatar Ingo Molnar Committed by Linus Torvalds

[PATCH] floppy boot-time detection fix

When the FDC hardware is initialized, it sometimes generates a floppy
interrupt right away - without being told to.  This interrupt can hit
the detection code that executes right after the initialization code, in
particular it can get intermixed with user_reset_fdc() that the
detection code uses.  The fd driver is fundamentally single-threaded
when it comes to handling events: an unexpected irq that arrives in the
wrong moment can confuse the reset_fdc() code, which, with softirq and
hardirq threading on, executes in keventd.

In the stock kernel this stale irq doesnt seem to hit the detection code
in the wrong moment, but i think under certain circumstances it may
still happen.  One of the typical incarnations of the race was the
following message:

 reset set in interrupt, calling c0258400

and googling for "reset set in interrupt, calling" does turn up a fair
number of bootlogs (most of them 2.4 ones) that show such a detection
failure, so i think upstream wants to have the fix too.

the fix is simple: delay a bit after initialization, to make sure the
stale irq does not interfere with the detection code. It will be safely
ignored, since do_floppy is still NULL. It might look sloppy that i went
for a delay, but delay i think it is better than waiting for the irq to
occur, because i dont think there's a guarantee that fdc initialization
triggers an interrupt, so waiting for it could hang the boot process. A
delay OTOH is totally harmless.

The attached patch implements this fix, which resolves the detection
problem on my testbox.

here's again how a failure looks like:

 Floppy drive(s): fd0 is 1.44M
 reset set in interrupt, calling c0258400
 floppy0: no floppy controllers found

and this is how it works with the fix:

 Floppy drive(s): fd0 is 1.44M
 FDC 0 is a post-1991 82077
Signed-off-by: default avatarIngo Molnar <mingo@elte.hu>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent d0b7fcbf
......@@ -4323,6 +4323,12 @@ int __init floppy_init(void)
floppy_track_buffer = NULL;
max_buffer_sectors = 0;
}
/*
* Small 10 msec delay to let through any interrupt that
* initialization might have triggered, to not
* confuse detection:
*/
msleep(10);
for (i = 0; i < N_FDC; i++) {
fdc = i;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment