check interrupt status of the PCI interface chip (if possible)

before calling the (slow) isic handler
being here, remove #ifdefs for FreeBSD and old version support
and add RCS ID tags
This commit is contained in:
drochner 2002-04-19 10:55:46 +00:00
parent b0b225c021
commit 9c80231f6b
3 changed files with 47 additions and 229 deletions

View File

@ -1,3 +1,5 @@
/* $NetBSD: isic_pci.c,v 1.15 2002/04/19 10:55:46 drochner Exp $ */
/*-
* Copyright (c) 2002 The NetBSD Foundation, Inc.
* All rights reserved.
@ -35,7 +37,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: isic_pci.c,v 1.14 2002/04/14 12:24:27 martin Exp $");
__KERNEL_RCSID(0, "$NetBSD: isic_pci.c,v 1.15 2002/04/19 10:55:46 drochner Exp $");
#include <sys/param.h>
#include <sys/errno.h>
@ -45,6 +47,7 @@ __KERNEL_RCSID(0, "$NetBSD: isic_pci.c,v 1.14 2002/04/14 12:24:27 martin Exp $")
#include <net/if.h>
#include <sys/systm.h>
#include <sys/malloc.h>
#include <sys/callout.h>
#include <machine/cpu.h>
#include <machine/intr.h>
@ -57,16 +60,7 @@ __KERNEL_RCSID(0, "$NetBSD: isic_pci.c,v 1.14 2002/04/14 12:24:27 martin Exp $")
#include <dev/pci/pcivar.h>
#include <dev/pci/pcidevs.h>
#if defined(__NetBSD__) && __NetBSD_Version__ >= 104230000
#include <sys/callout.h>
#endif
#ifdef __FreeBSD__
#include <machine/i4b_ioctl.h>
#else
#include <netisdn/i4b_ioctl.h>
#endif
#include <netisdn/i4b_global.h>
#include <netisdn/i4b_debug.h>
#include <netisdn/i4b_trace.h>
@ -161,10 +155,8 @@ isic_pci_attach(parent, self, aux)
printf(": %s\n", prod->name);
#if defined(__NetBSD__) && __NetBSD_Version__ >= 104230000
callout_init(&sc->sc_T3_callout);
callout_init(&sc->sc_T4_callout);
#endif
/* card initilization and sc setup */
prod->attach(psc, pa);
@ -219,7 +211,7 @@ isic_pci_isdn_attach(psc, pa, cardname)
break;
case 0x02:
printf("%s: IPAC PSB2115 Version 2\n", sc->sc_dev.dv_xname);
printf("%s: IPAC PSB2115 Version 1.2\n", sc->sc_dev.dv_xname);
break;
default:
@ -276,7 +268,7 @@ isic_pci_isdn_attach(psc, pa, cardname)
return;
}
intrstr = pci_intr_string(pc, ih);
psc->sc_ih = pci_intr_establish(pc, ih, IPL_NET, isicintr, sc);
psc->sc_ih = pci_intr_establish(pc, ih, IPL_NET, isic_intr_qs1p, psc);
if (psc->sc_ih == NULL) {
printf("%s: couldn't establish interrupt",
sc->sc_dev.dv_xname);
@ -318,11 +310,6 @@ isic_pci_isdn_attach(psc, pa, cardname)
sc->sc_obuf2 = NULL;
sc->sc_freeflag2 = 0;
#if defined(__FreeBSD__) && __FreeBSD__ >=3
callout_handle_init(&sc->sc_T3_callout);
callout_handle_init(&sc->sc_T4_callout);
#endif
/* init higher protocol layers */
isic_attach_bri(sc, cardname, &isic_std_driver);
}
@ -364,4 +351,3 @@ isic_pci_activate(self, act)
splx(s);
return (error);
}

View File

@ -1,3 +1,5 @@
/* $NetBSD: isic_pci.h,v 1.5 2002/04/19 10:55:46 drochner Exp $ */
/*-
* Copyright (c) 2002 The NetBSD Foundation, Inc.
* All rights reserved.
@ -42,8 +44,10 @@ struct pci_isic_softc {
bus_addr_t sc_base;
bus_size_t sc_size;
pci_chipset_tag_t sc_pc;
int flags;
#define PCIISIC_LCROK 0x01
};
extern void isic_attach_Eqs1pp __P((struct pci_isic_softc *psc, struct pci_attach_args *pa));
extern void isic_attach_fritzPci __P((struct pci_isic_softc *psc, struct pci_attach_args *pa));
extern int isic_intr_qs1p(void *);

View File

@ -1,3 +1,5 @@
/* $NetBSD: isic_pci_elsa_qs1p.c,v 1.9 2002/04/19 10:55:46 drochner Exp $ */
/*
* Copyright (c) 1997, 1999 Hellmuth Michaelis. All rights reserved.
*
@ -27,14 +29,10 @@
* isic - I4B Siemens ISDN Chipset Driver for ELSA Quickstep 1000pro PCI
* =====================================================================
*
* $Id: isic_pci_elsa_qs1p.c,v 1.8 2002/04/18 15:32:30 martin Exp $
*
* last edit-date: [Fri Jan 5 11:38:58 2001]
*
*---------------------------------------------------------------------------*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: isic_pci_elsa_qs1p.c,v 1.8 2002/04/18 15:32:30 martin Exp $");
__KERNEL_RCSID(0, "$NetBSD: isic_pci_elsa_qs1p.c,v 1.9 2002/04/19 10:55:46 drochner Exp $");
#include <sys/param.h>
#include <sys/kernel.h>
@ -42,28 +40,10 @@ __KERNEL_RCSID(0, "$NetBSD: isic_pci_elsa_qs1p.c,v 1.8 2002/04/18 15:32:30 marti
#include <sys/mbuf.h>
#include <sys/socket.h>
#include <net/if.h>
#if defined(__NetBSD__) && __NetBSD_Version__ >= 104230000
#include <sys/callout.h>
#endif
#ifdef __FreeBSD__
#if __FreeBSD__ >= 3
#include <sys/ioccom.h>
#else
#include <sys/ioctl.h>
#endif
#include <machine/clock.h>
#include <i386/isa/isa_device.h>
#else
#include <machine/bus.h>
#include <sys/device.h>
#endif
#ifdef __FreeBSD__
#include <machine/i4b_debug.h>
#include <machine/i4b_ioctl.h>
#else
#include <dev/pci/pcireg.h>
#include <dev/pci/pcivar.h>
@ -71,8 +51,6 @@ __KERNEL_RCSID(0, "$NetBSD: isic_pci_elsa_qs1p.c,v 1.8 2002/04/18 15:32:30 marti
#include <netisdn/i4b_debug.h>
#include <netisdn/i4b_ioctl.h>
#endif
#include <netisdn/i4b_global.h>
#include <netisdn/i4b_debug.h>
#include <netisdn/i4b_l2.h>
@ -83,10 +61,7 @@ __KERNEL_RCSID(0, "$NetBSD: isic_pci_elsa_qs1p.c,v 1.8 2002/04/18 15:32:30 marti
#include <dev/ic/isac.h>
#include <dev/ic/hscx.h>
#include <dev/ic/ipac.h>
#ifndef __FreeBSD__
#include <dev/pci/isic_pci.h>
#endif
/* masks for register encoded in base addr */
@ -121,29 +96,6 @@ static void elsa_led_handler(void *token);
/*---------------------------------------------------------------------------*
* ELSA QuickStep 1000pro/PCI ISAC get fifo routine
*---------------------------------------------------------------------------*/
#ifdef __FreeBSD__
static void
eqs1pp_read_fifo(void *buf, const void *base, size_t len)
{
if(((u_int)base & ELSA_OFF_MASK) == ELSA_IDHSCXB)
{
outb((u_int)((u_int)base & ELSA_BASE_MASK) + ELSA_OFF_ALE, IPAC_HSCXB_OFF);
insb((((u_int)base & ELSA_BASE_MASK) + ELSA_OFF_RW), (u_char *)buf, (u_int)len);
}
else if(((u_int)base & ELSA_OFF_MASK) == ELSA_IDHSCXA)
{
outb((u_int)((u_int)base & ELSA_BASE_MASK) + ELSA_OFF_ALE, IPAC_HSCXA_OFF);
insb((((u_int)base & ELSA_BASE_MASK) + ELSA_OFF_RW), (u_char *)buf, (u_int)len);
}
else /* if(((u_int)base & ELSA_OFF_MASK) == ELSA_IDISAC) */
{
outb((u_int)((u_int)base & ELSA_BASE_MASK) + ELSA_OFF_ALE, IPAC_ISAC_OFF);
insb((((u_int)base & ELSA_BASE_MASK) + ELSA_OFF_RW), (u_char *)buf, (u_int)len);
}
}
#else
static void
eqs1pp_read_fifo(struct isic_softc *sc, int what, void *buf, size_t size)
@ -166,34 +118,9 @@ eqs1pp_read_fifo(struct isic_softc *sc, int what, void *buf, size_t size)
}
}
#endif
/*---------------------------------------------------------------------------*
* ELSA QuickStep 1000pro/PCI ISAC put fifo routine
*---------------------------------------------------------------------------*/
#ifdef __FreeBSD__
static void
eqs1pp_write_fifo(void *base, const void *buf, size_t len)
{
if(((u_int)base & ELSA_OFF_MASK) == ELSA_IDHSCXB)
{
outb((u_int)((u_int)base & ELSA_BASE_MASK) + ELSA_OFF_ALE, IPAC_HSCXB_OFF);
outsb((((u_int)base & ELSA_BASE_MASK) + ELSA_OFF_RW), (u_char *)buf, (u_int)len);
}
else if(((u_int)base & ELSA_OFF_MASK) == ELSA_IDHSCXA)
{
outb((u_int)((u_int)base & ELSA_BASE_MASK) + ELSA_OFF_ALE, IPAC_HSCXA_OFF);
outsb((((u_int)base & ELSA_BASE_MASK) + ELSA_OFF_RW), (u_char *)buf, (u_int)len);
}
else /* if(((u_int)base & ELSA_OFF_MASK) == ELSA_IDISAC) */
{
outb((u_int)((u_int)base & ELSA_BASE_MASK) + ELSA_OFF_ALE, IPAC_ISAC_OFF);
outsb((((u_int)base & ELSA_BASE_MASK) + ELSA_OFF_RW), (u_char *)buf, (u_int)len);
}
}
#else
static void
eqs1pp_write_fifo(struct isic_softc *sc, int what, const void *buf, size_t size)
@ -215,39 +142,10 @@ eqs1pp_write_fifo(struct isic_softc *sc, int what, const void *buf, size_t size)
break;
}
}
#endif
/*---------------------------------------------------------------------------*
* ELSA QuickStep 1000pro/PCI ISAC put register routine
*---------------------------------------------------------------------------*/
#ifdef __FreeBSD__
static void
eqs1pp_write_reg(u_char *base, u_int offset, u_int v)
{
if(((u_int)base & ELSA_OFF_MASK) == ELSA_IDHSCXB)
{
outb(((u_int)base & ELSA_BASE_MASK) + ELSA_OFF_ALE, (u_char)(offset+IPAC_HSCXB_OFF));
outb(((u_int)base & ELSA_BASE_MASK) + ELSA_OFF_RW, (u_char)v);
}
else if(((u_int)base & ELSA_OFF_MASK) == ELSA_IDHSCXA)
{
outb(((u_int)base & ELSA_BASE_MASK) + ELSA_OFF_ALE, (u_char)(offset+IPAC_HSCXA_OFF));
outb(((u_int)base & ELSA_BASE_MASK) + ELSA_OFF_RW, (u_char)v);
}
else if(((u_int)base & ELSA_OFF_MASK) == ELSA_IDISAC)
{
outb(((u_int)base & ELSA_BASE_MASK) + ELSA_OFF_ALE, (u_char)(offset+IPAC_ISAC_OFF));
outb(((u_int)base & ELSA_BASE_MASK) + ELSA_OFF_RW, (u_char)v);
}
else /* IPAC */
{
outb(((u_int)base & ELSA_BASE_MASK) + ELSA_OFF_ALE, (u_char)(offset+IPAC_IPAC_OFF));
outb(((u_int)base & ELSA_BASE_MASK) + ELSA_OFF_RW, (u_char)v);
}
}
#else
static void
eqs1pp_write_reg(struct isic_softc *sc, int what, bus_size_t offs, u_int8_t data)
@ -273,39 +171,10 @@ eqs1pp_write_reg(struct isic_softc *sc, int what, bus_size_t offs, u_int8_t data
break;
}
}
#endif
/*---------------------------------------------------------------------------*
* ELSA QuickStep 1000pro/PCI ISAC get register routine
*---------------------------------------------------------------------------*/
#ifdef __FreeBSD__
static u_char
eqs1pp_read_reg(u_char *base, u_int offset)
{
if(((u_int)base & ELSA_OFF_MASK) == ELSA_IDHSCXB)
{
outb((u_int)((u_int)base & ELSA_BASE_MASK) + ELSA_OFF_ALE, (u_char)(offset+IPAC_HSCXB_OFF));
return(inb(((u_int)base & ELSA_BASE_MASK) + ELSA_OFF_RW));
}
else if(((u_int)base & ELSA_OFF_MASK) == ELSA_IDHSCXA)
{
outb((u_int)((u_int)base & ELSA_BASE_MASK) + ELSA_OFF_ALE, (u_char)(offset+IPAC_HSCXA_OFF));
return(inb(((u_int)base & ELSA_BASE_MASK) + ELSA_OFF_RW));
}
else if(((u_int)base & ELSA_OFF_MASK) == ELSA_IDISAC)
{
outb((u_int)((u_int)base & ELSA_BASE_MASK) + ELSA_OFF_ALE, (u_char)(offset+IPAC_ISAC_OFF));
return(inb(((u_int)base & ELSA_BASE_MASK) + ELSA_OFF_RW));
}
else /* IPAC */
{
outb((u_int)((u_int)base & ELSA_BASE_MASK) + ELSA_OFF_ALE, (u_char)(offset+IPAC_IPAC_OFF));
return(inb(((u_int)base & ELSA_BASE_MASK) + ELSA_OFF_RW));
}
}
#else
static u_int8_t
eqs1pp_read_reg(struct isic_softc *sc, int what, bus_size_t offs)
@ -332,80 +201,9 @@ eqs1pp_read_reg(struct isic_softc *sc, int what, bus_size_t offs)
return 0;
}
#endif
/*---------------------------------------------------------------------------*
* isic_attach_Eqs1pp - attach for ELSA QuickStep 1000pro/PCI
*---------------------------------------------------------------------------*/
#ifdef __FreeBSD__
int
isic_attach_Eqs1pp(int unit, unsigned int iobase1, unsigned int iobase2)
{
struct isic_softc *sc = &l1_sc[unit];
/* check max unit range */
if(unit >= ISIC_MAXUNIT)
{
printf("isic%d: Error, unit %d >= ISIC_MAXUNIT for ELSA QuickStep 1000pro/PCI!\n",
unit, unit);
return(0);
}
sc->sc_unit = unit;
/* setup iobase */
if((iobase2 <= 0) || (iobase2 > 0xffff))
{
printf("isic%d: Error, invalid iobase 0x%x specified for ELSA QuickStep 1000pro/PCI!\n",
unit, iobase2);
return(0);
}
sc->sc_port = iobase2;
/* setup access routines */
sc->clearirq = NULL;
sc->readreg = eqs1pp_read_reg;
sc->writereg = eqs1pp_write_reg;
sc->readfifo = eqs1pp_read_fifo;
sc->writefifo = eqs1pp_write_fifo;
/* setup card type */
sc->sc_cardtyp = CARD_TYPEP_ELSAQS1PCI;
/* setup IOM bus type */
sc->sc_bustyp = BUS_TYPE_IOM2;
/* setup chip type = IPAC ! */
sc->sc_ipac = 1;
sc->sc_bfifolen = IPAC_BFIFO_LEN;
/* setup ISAC and HSCX base addr */
ISAC_BASE = (caddr_t) ((u_int)iobase2 | ELSA_IDISAC);
HSCX_A_BASE = (caddr_t) ((u_int)iobase2 | ELSA_IDHSCXA);
HSCX_B_BASE = (caddr_t) ((u_int)iobase2 | ELSA_IDHSCXB);
IPAC_BASE = (caddr_t) ((u_int)iobase2 | ELSA_IDIPAC);
/* enable hscx/isac irq's */
IPAC_WRITE(IPAC_MASK, (IPAC_MASK_INT1 | IPAC_MASK_INT0));
IPAC_WRITE(IPAC_ACFG, 0); /* outputs are open drain */
IPAC_WRITE(IPAC_AOE, /* aux 5..2 are inputs, 7, 6 outputs */
(IPAC_AOE_OE5 | IPAC_AOE_OE4 | IPAC_AOE_OE3 | IPAC_AOE_OE2));
IPAC_WRITE(IPAC_ATX, 0xff); /* set all output lines high */
outb(iobase1 + 0x4c, 0x41); /* enable card interrupt */
return (1);
}
#else /* !FreeBSD */
void
isic_attach_Eqs1pp(psc, pa)
@ -425,6 +223,15 @@ isic_attach_Eqs1pp(psc, pa)
printf("%s: can't map card registers\n", sc->sc_dev.dv_xname);
return;
}
/* PLX9050 Errata #1 */
if (PCI_REVISION(pa->pa_class) == 1 && psc->sc_base & 0x00000080) {
#ifdef DEBUG
printf("%s: no LCR access\n", sc->sc_dev.dv_xname);
#endif
} else
psc->flags |= PCIISIC_LCROK;
sc->sc_maps[1].size = 0;
if (pci_mapreg_map(pa, ELSA_PORT1_MAPOFF, PCI_MAPREG_TYPE_IO, 0,
&sc->sc_maps[1].t, &sc->sc_maps[1].h, NULL, NULL)) {
@ -466,6 +273,28 @@ isic_attach_Eqs1pp(psc, pa)
bus_space_write_1(sc->sc_maps[0].t, sc->sc_maps[0].h, 0x4c, 0x01);
}
int
isic_intr_qs1p(vsc)
void *vsc;
{
struct pci_isic_softc *psc = vsc;
struct isic_softc *sc = &psc->sc_isic;
u_int32_t intcsr;
/*
* if we are not hit by the PLX bug we can try a shortcut
* (should improve speed for shared IRQs)
*/
if (psc->flags & PCIISIC_LCROK) {
intcsr = bus_space_read_4(sc->sc_maps[0].t, sc->sc_maps[0].h,
0x4c /* INTCSR */);
if (!(intcsr & 0x4 /* LINTi1STAT */))
return (0);
}
return (isicintr(sc));
}
static void
elsa_cmd_req(struct isic_softc *sc, int cmd, void *data)
{
@ -477,7 +306,8 @@ elsa_cmd_req(struct isic_softc *sc, int cmd, void *data)
s = splnet();
/* enable hscx/isac irq's */
IPAC_WRITE(IPAC_MASK, (IPAC_MASK_INT1 | IPAC_MASK_INT0));
bus_space_write_1(sc->sc_maps[0].t, sc->sc_maps[0].h, 0x4c, 0x41); /* enable card interrupt */
/* enable card interrupt */
bus_space_write_1(sc->sc_maps[0].t, sc->sc_maps[0].h, 0x4c, 0x41);
splx(s);
break;
case CMR_DCLOSE:
@ -553,5 +383,3 @@ elsa_led_handler(void *token)
elsa_led_handler, sc);
splx(s);
}
#endif