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:
parent
fa2a19276b
commit
8853536066
|
@ -27,14 +27,14 @@
|
||||||
* i4b_isac.c - i4b siemens isdn chipset driver ISAC handler
|
* 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]
|
* last edit-date: [Fri Jan 5 11:36:10 2001]
|
||||||
*
|
*
|
||||||
*---------------------------------------------------------------------------*/
|
*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
#include <sys/cdefs.h>
|
#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__
|
#ifdef __FreeBSD__
|
||||||
#include "opt_i4b.h"
|
#include "opt_i4b.h"
|
||||||
|
@ -553,8 +553,6 @@ isic_isac_l1_cmd(struct isic_softc *sc, int command)
|
||||||
int
|
int
|
||||||
isic_isac_init(struct isic_softc *sc)
|
isic_isac_init(struct isic_softc *sc)
|
||||||
{
|
{
|
||||||
u_int8_t v;
|
|
||||||
|
|
||||||
ISAC_IMASK = 0xff; /* disable all irqs */
|
ISAC_IMASK = 0xff; /* disable all irqs */
|
||||||
|
|
||||||
ISAC_WRITE(I_MASK, ISAC_IMASK);
|
ISAC_WRITE(I_MASK, ISAC_IMASK);
|
||||||
|
@ -597,14 +595,6 @@ isic_isac_init(struct isic_softc *sc)
|
||||||
* STx/SCx = 0
|
* STx/SCx = 0
|
||||||
*/
|
*/
|
||||||
ISAC_WRITE(I_STCR, ISAC_STCR_TBA2|ISAC_STCR_TBA1|ISAC_STCR_TBA0);
|
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
|
else
|
||||||
{
|
{
|
||||||
|
@ -645,16 +635,17 @@ isic_isac_init(struct isic_softc *sc)
|
||||||
* STx/SCx = 0
|
* STx/SCx = 0
|
||||||
*/
|
*/
|
||||||
ISAC_WRITE(I_STCR, ISAC_STCR_TBA2|ISAC_STCR_TBA1|ISAC_STCR_TBA0);
|
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* 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);
|
||||||
|
|
||||||
/* enabled interrupts:
|
/* enabled interrupts:
|
||||||
* ===================
|
* ===================
|
||||||
* RME - receive message end
|
* RME - receive message end
|
||||||
|
@ -670,24 +661,6 @@ isic_isac_init(struct isic_softc *sc)
|
||||||
|
|
||||||
ISAC_WRITE(I_MASK, ISAC_IMASK);
|
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);
|
ISAC_WRITE(I_CMDR, ISAC_CMDR_RRES|ISAC_CMDR_XRES);
|
||||||
ISACCMDRWRDELAY();
|
ISACCMDRWRDELAY();
|
||||||
|
|
||||||
|
|
|
@ -27,14 +27,14 @@
|
||||||
* i4b_isic.c - global isic stuff
|
* 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]
|
* last edit-date: [Fri Jan 5 11:36:10 2001]
|
||||||
*
|
*
|
||||||
*---------------------------------------------------------------------------*/
|
*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
#include <sys/cdefs.h>
|
#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/param.h>
|
||||||
#include <sys/ioccom.h>
|
#include <sys/ioccom.h>
|
||||||
|
@ -190,15 +190,19 @@ isicintr(void *arg)
|
||||||
}
|
}
|
||||||
if(ipac_irq_stat & IPAC_ISTA_ICD)
|
if(ipac_irq_stat & IPAC_ISTA_ICD)
|
||||||
{
|
{
|
||||||
/* ISAC interrupt */
|
/* ISAC interrupt, Obey ISAC-IPAC differences */
|
||||||
isic_isac_irq(sc, ISAC_READ(I_ISTA));
|
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;
|
was_ipac_irq = 1;
|
||||||
}
|
}
|
||||||
if(ipac_irq_stat & IPAC_ISTA_EXD)
|
if(ipac_irq_stat & IPAC_ISTA_EXD)
|
||||||
{
|
{
|
||||||
/* force ISAC interrupt handling */
|
/* ISAC EXI interrupt */
|
||||||
if (sc->sc_intr_valid == ISIC_INTR_VALID)
|
isic_isac_irq(sc, ISAC_ISTA_EXI);
|
||||||
isic_isac_irq(sc, ISAC_ISTA_EXI);
|
|
||||||
was_ipac_irq = 1;
|
was_ipac_irq = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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.
|
* Copyright (c) 1997, 2000 Hellmuth Michaelis. All rights reserved.
|
||||||
|
@ -27,7 +27,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <sys/cdefs.h>
|
#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/param.h>
|
||||||
#include <sys/ioctl.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_data_req(isdn_layer1token, struct mbuf *, int);
|
||||||
static int isic_std_ph_activate_req(isdn_layer1token);
|
static int isic_std_ph_activate_req(isdn_layer1token);
|
||||||
static int isic_std_mph_command_req(isdn_layer1token, int, void*);
|
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 = {
|
const struct isdn_layer1_bri_driver isic_std_driver = {
|
||||||
isic_std_ph_data_req,
|
isic_std_ph_data_req,
|
||||||
|
@ -263,17 +263,16 @@ isic_std_mph_command_req(isdn_layer1token token, int command, void *parm)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
isic_enable_intr(struct isic_softc *sc, int enabled)
|
isic_enable_intr(struct isic_softc *sc, int enable)
|
||||||
{
|
{
|
||||||
if (sc->sc_ipac) {
|
if (enable) {
|
||||||
if (enabled) {
|
isic_isac_init(sc);
|
||||||
isic_isac_init(sc);
|
|
||||||
} else {
|
|
||||||
IPAC_WRITE(IPAC_MASK, 0xff);
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
if (enabled) {
|
/* disable receiver */
|
||||||
isic_isac_init(sc);
|
ISAC_WRITE(I_MODE, ISAC_MODE_MDS2|ISAC_MODE_MDS1|ISAC_MODE_DIM0);
|
||||||
|
/* mask interrupts */
|
||||||
|
if (sc->sc_ipac) {
|
||||||
|
IPAC_WRITE(IPAC_MASK, 0xff);
|
||||||
} else {
|
} else {
|
||||||
ISAC_WRITE(I_MASK, 0xff);
|
ISAC_WRITE(I_MASK, 0xff);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue