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 have not yet tried this patch.  The patch is against version 1.28,
which is from -current, and I am only set up to try 4.0.1.  I need to
re-work the patch for an earlier version of z8530sc.c.  I started doing
this today, but ran out of time.

-dgl-

>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