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