ttyS0 = 0x3f8, irq 4 (mouse)
ttyS1 = 0x2f8, irq 3 (dumb terminal)
ttyS3 = 0x2e8, irq 5 (modem)
Before I run "setserial /dev/ttyS3 irq 5", the kernel assumes ttyS3 is
running on irq 4 (conflicting with ttyS0). Now let's say I start using
ttyS0 (for example, gpm). Then I try to access ttyS3 (cat /dev/ttyS3).
It spits back an EBUSY, since the irq is already in use. However, it
has a side effect of decrementing the module's usage count (without
incrementing it in the first place!) If I repeatedly try to "cat
/dev/ttyS3" I can get the usage count into negative numbers :-)
Anyway, here's what I found in the source:
tty_io.c:tty_open() contains:
1259: if (tty->driver.open)
1260: retval = tty->driver.open(tty, flip)
...
1268: if (retval) {
...
1274: release_dev(filp);
...
In this case, tty->driver.open points to serial.c:rs_open()...
serial.c:rs_open() contains:
2614: retval = startup(info);
2615: if (retval)
2616: return retval;
2617:
2618: MOD_INC_USE_COUNT
My IRQ conflict is detected in the startup() function, which ends up
returning -EBUSY. So what happens is that value is returned back to
tty_open() _before_ the MOD_INC_USE_COUNT. Because of the nonzero
retval, tty_open() calls release_dev()...
tty_io.c:release_dev() contains:
1030: if (tty->driver.close)
1031: tty->driver.close(tty, filp);
And tty->driver.close is a pointer to rs_close(), which calls the
MOD_DEC_USE_COUNT. The only condition where MOD_DEC_USE_COUNT is not
called, is if the "info" pointer is either NULL or bad, but this is not
the case.
Since this is the first time I have looked at the tty/serial code, I'm
not sure what is the "right thing" to do. My guess is the
MOD_INC_USE_COUNT in serial.c:rs_open() should be moved up above
any of the "return" statements.
Although I haven't tested it, from the looks of the 2.0.34 code, it
appears to behave the same way.
andy
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu