Pull a similar fix from sparc/dev/zs.c rev 1.119:

Establish interrupt handlers with proper softc per each zs device
 rather than sharing them among all zs devices and searching softc
 in handlers, to avoid possible recursive lock.
This commit is contained in:
tsutsui 2010-06-26 03:44:49 +00:00
parent 42db966caf
commit 995d4be272
3 changed files with 22 additions and 63 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: zs_ap.c,v 1.25 2008/04/28 20:23:30 martin Exp $ */
/* $NetBSD: zs_ap.c,v 1.26 2010/06/26 03:44:49 tsutsui Exp $ */
/*-
* Copyright (c) 1996 The NetBSD Foundation, Inc.
@ -38,7 +38,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: zs_ap.c,v 1.25 2008/04/28 20:23:30 martin Exp $");
__KERNEL_RCSID(0, "$NetBSD: zs_ap.c,v 1.26 2010/06/26 03:44:49 tsutsui Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@ -213,7 +213,6 @@ zs_ap_attach(device_t parent, device_t self, void *aux)
volatile u_int *portBctl = (void *)(apa->apa_hwbase + PORTB_OFFSET);
volatile u_int *portActl = (void *)(apa->apa_hwbase + PORTA_OFFSET);
volatile u_int *esccregs = (void *)(apa->apa_hwbase + ESCC_REG);
static int didintr;
zsc->zsc_dev = self;
zs_unit = device_unit(self);
@ -295,20 +294,12 @@ zs_ap_attach(device_t parent, device_t self, void *aux)
}
/*
* Now safe to install interrupt handlers. Note the arguments
* to the interrupt handlers aren't used. Note, we only do this
* once since both SCCs interrupt at the same level and vector.
* Now safe to install interrupt handlers.
*/
if (!didintr) {
didintr = 1;
zsc->zsc_si = softint_establish(SOFTINT_SERIAL, zssoft, zsc);
apbus_intr_establish(1, /* interrupt level ( 0 or 1 ) */
NEWS5000_INT1_SCC,
0, /* priority */
zshard_ap, zsc,
apa->apa_name, apa->apa_ctlnum);
}
zsc->zsc_si = softint_establish(SOFTINT_SERIAL, zssoft, zsc);
apbus_intr_establish(1, /* interrupt level ( 0 or 1 ) */
NEWS5000_INT1_SCC, 0, /* priority */
zshard_ap, zsc, apa->apa_name, apa->apa_ctlnum);
/* XXX; evcnt_attach() ? */
#if 0

View File

@ -1,4 +1,4 @@
/* $NetBSD: zs.c,v 1.25 2008/06/13 12:26:35 cegger Exp $ */
/* $NetBSD: zs.c,v 1.26 2010/06/26 03:44:49 tsutsui Exp $ */
/*-
* Copyright (c) 1996 The NetBSD Foundation, Inc.
@ -38,7 +38,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: zs.c,v 1.25 2008/06/13 12:26:35 cegger Exp $");
__KERNEL_RCSID(0, "$NetBSD: zs.c,v 1.26 2010/06/26 03:44:49 tsutsui Exp $");
#include "opt_ddb.h"
@ -80,50 +80,23 @@ zs_print(void *aux, const char *name)
}
/*
* Our ZS chips all share a common, autovectored interrupt,
* so we have to look at all of them on each interrupt.
* Our ZS chips all share a common interrupt level,
* but we establish zshard handler per each ZS chips
* to avoid holding unnecessary locks in interrupt context.
*/
int
zshard(void *arg)
{
struct zsc_softc *zsc;
int unit, rval, softreq;
struct zsc_softc *zsc = arg;
int rval;
rval = 0;
for (unit = 0; unit < zsc_cd.cd_ndevs; unit++) {
zsc = device_lookup_private(&zsc_cd, unit);
if (zsc == NULL)
continue;
rval |= zsc_intr_hard(zsc);
softreq = zsc->zsc_cs[0]->cs_softreq;
softreq |= zsc->zsc_cs[1]->cs_softreq;
if (softreq)
softint_schedule(zsc->zsc_si);
}
rval = zsc_intr_hard(zsc);
if (zsc->zsc_cs[0]->cs_softreq || zsc->zsc_cs[1]->cs_softreq)
softint_schedule(zsc->zsc_si);
return rval;
}
/*
* Similar scheme as for zshard (look at all of them)
*/
void
zssoft(void *arg)
{
struct zsc_softc *zsc;
int s, unit;
/* Make sure we call the tty layer at spltty. */
s = spltty();
for (unit = 0; unit < zsc_cd.cd_ndevs; unit++) {
zsc = device_lookup_private(&zsc_cd, unit);
if (zsc == NULL)
continue;
(void)zsc_intr_soft(zsc);
}
splx(s);
}
/*
* Compute the current baud rate given a ZS channel.
*/

View File

@ -1,4 +1,4 @@
/* $NetBSD: zs_hb.c,v 1.25 2008/04/28 20:23:30 martin Exp $ */
/* $NetBSD: zs_hb.c,v 1.26 2010/06/26 03:44:49 tsutsui Exp $ */
/*-
* Copyright (c) 1996 The NetBSD Foundation, Inc.
@ -38,7 +38,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: zs_hb.c,v 1.25 2008/04/28 20:23:30 martin Exp $");
__KERNEL_RCSID(0, "$NetBSD: zs_hb.c,v 1.26 2010/06/26 03:44:49 tsutsui Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@ -196,7 +196,6 @@ zs_hb_attach(device_t parent, device_t self, void *aux)
volatile struct zschan *zc;
struct zs_chanstate *cs;
int s, zs_unit, channel, intlevel;
static int didintr;
zsc->zsc_dev = self;
zs_unit = device_unit(self);
@ -284,13 +283,9 @@ zs_hb_attach(device_t parent, device_t self, void *aux)
* to the interrupt handlers aren't used. Note, we only do this
* once since both SCCs interrupt at the same level and vector.
*/
if (!didintr) {
didintr = 1;
zsc->zsc_si = softint_establish(SOFTINT_SERIAL, zssoft, zsc);
hb_intr_establish(intlevel, INTST1_SCC, IPL_SERIAL,
zshard_hb, NULL);
}
zsc->zsc_si = softint_establish(SOFTINT_SERIAL,
(void (*)(void *))zsc_intr_soft, zsc);
hb_intr_establish(intlevel, INTST1_SCC, IPL_SERIAL, zshard_hb, zsc);
/* XXX; evcnt_attach() ? */
/*