Patches from Matthias Drochner, slightly modified by me:

Remove the clear-the-irq-after-enabling it dance (which had bad side
effects on some cards). Instead disble the ISAC receiver when we have
interrupts disabled. Adjust the interrupt handler to properly deal with
subtle differences of the ISAC implementation in IPAC chips.
This commit is contained in:
martin 2002-04-29 13:42:42 +00:00
parent fa2a19276b
commit 8853536066
3 changed files with 33 additions and 57 deletions

View File

@ -27,14 +27,14 @@
* i4b_isac.c - i4b siemens isdn chipset driver ISAC handler
* ---------------------------------------------------------
*
* $Id: isac.c,v 1.15 2002/04/18 12:19:05 martin Exp $
* $Id: isac.c,v 1.16 2002/04/29 13:42:42 martin Exp $
*
* last edit-date: [Fri Jan 5 11:36:10 2001]
*
*---------------------------------------------------------------------------*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: isac.c,v 1.15 2002/04/18 12:19:05 martin Exp $");
__KERNEL_RCSID(0, "$NetBSD: isac.c,v 1.16 2002/04/29 13:42:42 martin Exp $");
#ifdef __FreeBSD__
#include "opt_i4b.h"
@ -553,8 +553,6 @@ isic_isac_l1_cmd(struct isic_softc *sc, int command)
int
isic_isac_init(struct isic_softc *sc)
{
u_int8_t v;
ISAC_IMASK = 0xff; /* disable all irqs */
ISAC_WRITE(I_MASK, ISAC_IMASK);
@ -597,14 +595,6 @@ isic_isac_init(struct isic_softc *sc)
* STx/SCx = 0
*/
ISAC_WRITE(I_STCR, ISAC_STCR_TBA2|ISAC_STCR_TBA1|ISAC_STCR_TBA0);
/* MODE: Mode Register:
* MDSx - transparent mode 2
* TMD - timer mode = external
* RAC - Receiver enabled
* DIMx - digital i/f mode
*/
ISAC_WRITE(I_MODE, ISAC_MODE_MDS2|ISAC_MODE_MDS1|ISAC_MODE_RAC|ISAC_MODE_DIM0);
}
else
{
@ -645,6 +635,8 @@ isic_isac_init(struct isic_softc *sc)
* STx/SCx = 0
*/
ISAC_WRITE(I_STCR, ISAC_STCR_TBA2|ISAC_STCR_TBA1|ISAC_STCR_TBA0);
}
/* MODE: Mode Register:
* MDSx - transparent mode 2
@ -653,7 +645,6 @@ isic_isac_init(struct isic_softc *sc)
* DIMx - digital i/f mode
*/
ISAC_WRITE(I_MODE, ISAC_MODE_MDS2|ISAC_MODE_MDS1|ISAC_MODE_RAC|ISAC_MODE_DIM0);
}
/* enabled interrupts:
* ===================
@ -670,24 +661,6 @@ isic_isac_init(struct isic_softc *sc)
ISAC_WRITE(I_MASK, ISAC_IMASK);
/*
* Even if interrupts are masked, the EXI bit may get set
* (but does not cause an interrupt).
* Clear the extended interrupts, and reset receiver and
* transmitter.
*/
if (sc->sc_ipac)
IPAC_READ(IPAC_ISTA);
v = ISAC_READ(I_ISTA);
if (v & ISAC_ISTA_EXI)
v = ISAC_READ(I_EXIR);
/* if we've just removed an interrupt status, make sure to cover
* all traces of it */
if (sc->clearirq)
sc->clearirq(sc);
ISAC_WRITE(I_CMDR, ISAC_CMDR_RRES|ISAC_CMDR_XRES);
ISACCMDRWRDELAY();

View File

@ -27,14 +27,14 @@
* i4b_isic.c - global isic stuff
* ==============================
*
* $Id: isic.c,v 1.15 2002/04/18 12:19:06 martin Exp $
* $Id: isic.c,v 1.16 2002/04/29 13:42:42 martin Exp $
*
* last edit-date: [Fri Jan 5 11:36:10 2001]
*
*---------------------------------------------------------------------------*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: isic.c,v 1.15 2002/04/18 12:19:06 martin Exp $");
__KERNEL_RCSID(0, "$NetBSD: isic.c,v 1.16 2002/04/29 13:42:42 martin Exp $");
#include <sys/param.h>
#include <sys/ioccom.h>
@ -190,14 +190,18 @@ isicintr(void *arg)
}
if(ipac_irq_stat & IPAC_ISTA_ICD)
{
/* ISAC interrupt */
isic_isac_irq(sc, ISAC_READ(I_ISTA));
/* ISAC interrupt, Obey ISAC-IPAC differences */
u_int8_t isac_ista = ISAC_READ(I_ISTA);
if (isac_ista & 0xfe)
isic_isac_irq(sc, isac_ista & 0xfe);
if (isac_ista & 0x01) /* unexpected */
printf("%s: unexpected ipac timer2 irq\n",
sc->sc_dev.dv_xname);
was_ipac_irq = 1;
}
if(ipac_irq_stat & IPAC_ISTA_EXD)
{
/* force ISAC interrupt handling */
if (sc->sc_intr_valid == ISIC_INTR_VALID)
/* ISAC EXI interrupt */
isic_isac_irq(sc, ISAC_ISTA_EXI);
was_ipac_irq = 1;
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: isic_l1.c,v 1.10 2002/04/13 10:28:36 martin Exp $ */
/* $NetBSD: isic_l1.c,v 1.11 2002/04/29 13:42:43 martin Exp $ */
/*
* Copyright (c) 1997, 2000 Hellmuth Michaelis. All rights reserved.
@ -27,7 +27,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: isic_l1.c,v 1.10 2002/04/13 10:28:36 martin Exp $");
__KERNEL_RCSID(0, "$NetBSD: isic_l1.c,v 1.11 2002/04/29 13:42:43 martin Exp $");
#include <sys/param.h>
#include <sys/ioctl.h>
@ -62,7 +62,7 @@ unsigned int i4b_l1_debug = L1_DEBUG_DEFAULT;
static int isic_std_ph_data_req(isdn_layer1token, struct mbuf *, int);
static int isic_std_ph_activate_req(isdn_layer1token);
static int isic_std_mph_command_req(isdn_layer1token, int, void*);
static void isic_enable_intr(struct isic_softc *sc, int enabled);
static void isic_enable_intr(struct isic_softc *sc, int enable);
const struct isdn_layer1_bri_driver isic_std_driver = {
isic_std_ph_data_req,
@ -263,17 +263,16 @@ isic_std_mph_command_req(isdn_layer1token token, int command, void *parm)
}
static void
isic_enable_intr(struct isic_softc *sc, int enabled)
isic_enable_intr(struct isic_softc *sc, int enable)
{
if (enable) {
isic_isac_init(sc);
} else {
/* disable receiver */
ISAC_WRITE(I_MODE, ISAC_MODE_MDS2|ISAC_MODE_MDS1|ISAC_MODE_DIM0);
/* mask interrupts */
if (sc->sc_ipac) {
if (enabled) {
isic_isac_init(sc);
} else {
IPAC_WRITE(IPAC_MASK, 0xff);
}
} else {
if (enabled) {
isic_isac_init(sc);
} else {
ISAC_WRITE(I_MASK, 0xff);
}