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