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



MacPPC2%caution.icompute.com@localhost wrote:

> I'm set up to build kernels, and can test patches or run experiments.
> If someone can provide some patches/experiments to run, I can
> make a contribution.

The attached patch seems to avoid some hangup,
but I'm not sure what actually happens on stalls
in current code.

---
Index: z8530sc.c
===================================================================
RCS file: /cvsroot/src/sys/dev/ic/z8530sc.c,v
retrieving revision 1.28
diff -u -r1.28 z8530sc.c
--- z8530sc.c   29 Mar 2008 19:15:36 -0000      1.28
+++ z8530sc.c   9 Jan 2009 18:58:51 -0000
@@ -289,55 +289,59 @@
 zsc_intr_hard(void *arg)
 {
        struct zsc_softc *zsc = arg;
-       struct zs_chanstate *cs;
+       struct zs_chanstate *cs0, *cs1;
+       int handled;
        uint8_t rr3;
 
-       /* First look at channel A. */
-       cs = zsc->zsc_cs[0];
+       handled = 0;
 
-       /* Lock both channels */
-       mutex_spin_enter(&cs->cs_lock);
-       mutex_spin_enter(&zsc->zsc_cs[1]->cs_lock);
-       /* Note: only channel A has an RR3 */
-       rr3 = zs_read_reg(cs, 3);
+       /* First look at channel A. */
+       cs0 = zsc->zsc_cs[0];
+       cs1 = zsc->zsc_cs[1];
 
        /*
-        * Clear interrupt first to avoid a race condition.
-        * If a new interrupt condition happens while we are
-        * servicing this one, we will get another interrupt
-        * shortly.  We can NOT just sit here in a loop, or
-        * we will cause horrible latency for other devices
-        * on this interrupt level (i.e. sun3x floppy disk).
+        * We have to clear interrupt first to avoid a race condition,
+        * but it will be done in each MD handler.
         */
-       if (rr3 & (ZSRR3_IP_A_RX | ZSRR3_IP_A_TX | ZSRR3_IP_A_STAT)) {
-               zs_write_csr(cs, ZSWR0_CLR_INTR);
+       for (;;) {
+               /* Lock both channels */
+               mutex_spin_enter(&cs1->cs_lock);
+               mutex_spin_enter(&cs0->cs_lock);
+               /* Note: only channel A has an RR3 */
+               rr3 = zs_read_reg(cs0, 3);
+
+               if ((rr3 & (ZSRR3_IP_A_RX | ZSRR3_IP_A_TX | ZSRR3_IP_A_STAT |
+                   ZSRR3_IP_B_RX | ZSRR3_IP_B_TX | ZSRR3_IP_B_STAT)) == 0) {
+                       mutex_spin_exit(&cs0->cs_lock);
+                       mutex_spin_exit(&cs1->cs_lock);
+                       break;
+               }
+               handled = 1;
+
+               /* First look at channel A. */
                if (rr3 & ZSRR3_IP_A_RX)
-                       (*cs->cs_ops->zsop_rxint)(cs);
+                       (*cs0->cs_ops->zsop_rxint)(cs0);
                if (rr3 & ZSRR3_IP_A_STAT)
-                       (*cs->cs_ops->zsop_stint)(cs, 0);
+                       (*cs0->cs_ops->zsop_stint)(cs0, 0);
                if (rr3 & ZSRR3_IP_A_TX)
-                       (*cs->cs_ops->zsop_txint)(cs);
-       }
+                       (*cs0->cs_ops->zsop_txint)(cs0);
 
-       /* Done with channel A */
-       mutex_spin_exit(&cs->cs_lock);
+               /* Done with channel A */
+               mutex_spin_exit(&cs0->cs_lock);
 
-       /* Now look at channel B. */
-       cs = zsc->zsc_cs[1];
-       if (rr3 & (ZSRR3_IP_B_RX | ZSRR3_IP_B_TX | ZSRR3_IP_B_STAT)) {
-               zs_write_csr(cs, ZSWR0_CLR_INTR);
+               /* Now look at channel B. */
                if (rr3 & ZSRR3_IP_B_RX)
-                       (*cs->cs_ops->zsop_rxint)(cs);
+                       (*cs1->cs_ops->zsop_rxint)(cs1);
                if (rr3 & ZSRR3_IP_B_STAT)
-                       (*cs->cs_ops->zsop_stint)(cs, 0);
+                       (*cs1->cs_ops->zsop_stint)(cs1, 0);
                if (rr3 & ZSRR3_IP_B_TX)
-                       (*cs->cs_ops->zsop_txint)(cs);
-       }
+                       (*cs1->cs_ops->zsop_txint)(cs1);
 
-       mutex_spin_exit(&cs->cs_lock);
+               mutex_spin_exit(&cs1->cs_lock);
+       }
 
        /* Note: caller will check cs_x->cs_softreq and DTRT. */
-       return (rr3);
+       return handled;
 }
 
 
Index: z8530tty.c
===================================================================
RCS file: /cvsroot/src/sys/dev/ic/z8530tty.c,v
retrieving revision 1.123
diff -u -r1.123 z8530tty.c
--- z8530tty.c  21 Apr 2008 12:56:31 -0000      1.123
+++ z8530tty.c  9 Jan 2009 18:58:51 -0000
@@ -439,7 +439,7 @@
                 * but we must make sure status interrupts are turned on by
                 * the time zsparam() reads the initial rr0 state.
                 */
-               SET(cs->cs_preg[1], ZSWR1_RIE | ZSWR1_SIE);
+               SET(cs->cs_preg[1], ZSWR1_RIE | ZSWR1_TIE | ZSWR1_SIE);
 
                /* Make sure zsparam will see changes. */
                tp->t_ospeed = 0;
@@ -511,7 +511,7 @@
 
        /* Turn off interrupts if not the console. */
        if (!ISSET(zst->zst_hwflags, ZS_HWFLAG_CONSOLE)) {
-               CLR(cs->cs_preg[1], ZSWR1_RIE | ZSWR1_SIE);
+               CLR(cs->cs_preg[1], ZSWR1_RIE | ZSWR1_TIE | ZSWR1_SIE);
                cs->cs_creg[1] = cs->cs_preg[1];
                zs_write_reg(cs, 1, cs->cs_creg[1]);
        }
@@ -597,7 +597,7 @@
                 * but we must make sure status interrupts are turned on by
                 * the time zsparam() reads the initial rr0 state.
                 */
-               SET(cs->cs_preg[1], ZSWR1_RIE | ZSWR1_SIE);
+               SET(cs->cs_preg[1], ZSWR1_RIE | ZSWR1_TIE | ZSWR1_SIE);
 
                /* Clear PPS capture state on first open. */
                mutex_spin_enter(&timecounter_lock);
@@ -915,13 +915,6 @@
        }
 #endif
 
-       /* Enable transmit completion interrupts if necessary. */
-       if (!ISSET(cs->cs_preg[1], ZSWR1_TIE)) {
-               SET(cs->cs_preg[1], ZSWR1_TIE);
-               cs->cs_creg[1] = cs->cs_preg[1];
-               zs_write_reg(cs, 1, cs->cs_creg[1]);
-       }
-
        /* Output the first character of the contiguous buffer. */
        zs_write_data(cs, *zst->zst_tba);
        zst->zst_tbc--;
@@ -1436,17 +1429,12 @@
        }
 
        /* Output the next character in the buffer, if any. */
+       zs_write_csr(cs, ZSWR0_RESET_TXINT);
        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;

---
Izumi Tsutsui


Home | Main Index | Thread Index | Old Index