Port-macppc archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: MacPPC serial ports in 4.0.1 - not quite



I've been poking around in the source, and I have an idea of what is
going on, but am reluctant to draw firm conclusions, because I
don't know this code well, and could easily be wrong.

It looks to me like the arch independent code disables ints on the
serial when the buffer fills, and the arch dependent code re-enables
them.  The token/bit in question is ZSWR1_TIE and ZSWR1_RIE (and friends).
I see where this happens 4 xmit in dev/ic/z8530tty.c, about line 1646.
The re-enabling of these interrupts, though I can't find.  Maybe
it was forgotten?

I've built a kernel now, and am ready to debug if I have a patch to check
out.

I'm thinking that I could hammer these registers at device open time to
test my theory.  If close/open cycle of the port frees it up, that
would point toward the theory having some validity.

-dgl-

Code snippet: (about line 1617 in 4.0.1 syssrc, dev/id/z8530tty.c)

/*
 * Transmitter Ready interrupt.
 * Called at splzs() and with the channel lock held.
 */
static void
zstty_txint(cs)
        struct zs_chanstate *cs;
{
        struct zstty_softc *zst = cs->cs_private;

        /*
         * If we've delayed a parameter change, do it now, and restart
         * output.
         */
        if (cs->cs_heldchange) {
                zs_loadchannelregs(cs);
                cs->cs_heldchange = 0;
                zst->zst_tbc = zst->zst_heldtbc;
                zst->zst_heldtbc = 0;
        }

        /* Output the next character in the buffer, if any. */
        if (zst->zst_tbc > 0) {
                zs_write_data(cs, *zst->zst_tba);
                zst->zst_tbc--;
                zst->zst_tba++;
        } else {
                /* Disable transmit completion interrupts if necessary. */
                if (ISSET(cs->cs_preg[1], ZSWR1_TIE)) {
                        CLR(cs->cs_preg[1], ZSWR1_TIE);
                        cs->cs_creg[1] = cs->cs_preg[1];
                        zs_write_reg(cs, 1, cs->cs_creg[1]);
                }
                if (zst->zst_tx_busy) {
                        zst->zst_tx_busy = 0;
                        zst->zst_tx_done = 1;
                        cs->cs_softreq = 1;
                }
        }
}


Home | Main Index | Thread Index | Old Index