Commit b362b375 authored by Kai Germaschewski's avatar Kai Germaschewski

ISDN/HiSax: Unify LED handling

Share the code to display line status via LEDs and get rid of the
remaining ->cardmsg() users.
parent e4c8bb11
......@@ -205,24 +205,39 @@ lli_deliver_cause(struct Channel *chanp)
}
static inline void
mdl_info_rel(struct Channel *chanp)
mdl_info_setup(struct Channel *chanp)
{
if (chanp->cs->cardmsg)
chanp->cs->cardmsg(chanp->cs, MDL_INFO_REL, (void *) (long)chanp->chan);
if (chanp->chan)
chanp->cs->status |= 0x0200;
else
chanp->cs->status |= 0x0100;
if (chanp->cs->card_ops->led_handler)
chanp->cs->card_ops->led_handler(chanp->cs);
}
static inline void
mdl_info_setup(struct Channel *chanp)
mdl_info_connect(struct Channel *chanp)
{
if (chanp->cs->cardmsg)
chanp->cs->cardmsg(chanp->cs, MDL_INFO_SETUP, (void *) (long)chanp->chan);
if (chanp->chan)
chanp->cs->status |= 0x2000;
else
chanp->cs->status |= 0x1000;
if (chanp->cs->card_ops->led_handler)
chanp->cs->card_ops->led_handler(chanp->cs);
}
static inline void
mdl_info_conn(struct Channel *chanp)
mdl_info_release(struct Channel *chanp)
{
if (chanp->cs->cardmsg)
chanp->cs->cardmsg(chanp->cs, MDL_INFO_CONN, (void *) (long)chanp->chan);
if (chanp->chan)
chanp->cs->status &= ~0x2200;
else
chanp->cs->status &= ~0x1100;
if (chanp->cs->card_ops->led_handler)
chanp->cs->card_ops->led_handler(chanp->cs);
}
static void
......@@ -232,7 +247,7 @@ lli_close(struct FsmInst *fi)
FsmChangeState(fi, ST_NULL);
chanp->Flags = 0;
mdl_info_rel(chanp);
mdl_info_release(chanp);
}
static void
......@@ -262,7 +277,7 @@ lli_leased_in(struct FsmInst *fi, int event, void *arg)
if (chanp->debug & 1)
link_debug(chanp, 1, "statcallb ret=%d", ret);
if (!ret) {
mdl_info_rel(chanp);
mdl_info_release(chanp);
FsmChangeState(fi, ST_NULL);
}
}
......@@ -338,7 +353,7 @@ lli_go_active(struct FsmInst *fi, int event, void *arg)
ic.command = ISDN_STAT_BCONN;
ic.arg = chanp->chan;
chanp->cs->iif.statcallb(&ic);
mdl_info_conn(chanp);
mdl_info_connect(chanp);
}
......@@ -403,13 +418,13 @@ lli_deliver_call(struct FsmInst *fi, int event, void *arg)
case 0: /* OK, nobody likes this call */
default: /* statcallb problems */
L4L3(chanp->d_st, CC_IGNORE | REQUEST, chanp->proc);
mdl_info_rel(chanp);
mdl_info_release(chanp);
FsmChangeState(fi, ST_NULL);
break;
}
} else {
L4L3(chanp->d_st, CC_IGNORE | REQUEST, chanp->proc);
mdl_info_rel(chanp);
mdl_info_release(chanp);
}
}
......@@ -752,7 +767,7 @@ lli_failure_l(struct FsmInst *fi, int event, void *arg)
chanp->cs->iif.statcallb(&ic);
HL_LL(chanp, ISDN_STAT_DHUP);
chanp->Flags = 0;
mdl_info_rel(chanp);
mdl_info_release(chanp);
}
static void
......
......@@ -443,20 +443,12 @@ diva_reset(struct IsdnCardState *cs)
return 0;
}
#define DIVA_ASSIGN 1
static void
diva_led_handler(struct IsdnCardState *cs)
{
int blink = 0;
// if ((cs->subtyp == DIVA_IPAC_ISA) || (cs->subtyp == DIVA_IPAC_PCI))
if ((cs->subtyp == DIVA_IPAC_ISA) ||
(cs->subtyp == DIVA_IPAC_PCI) ||
(cs->subtyp == DIVA_IPACX_PCI) )
return;
del_timer(&cs->hw.diva.tl);
if (cs->hw.diva.status & DIVA_ASSIGN)
if (cs->status & 0x0001)
cs->hw.diva.ctrl_reg |= (DIVA_ISA == cs->subtyp) ?
DIVA_ISA_LED_A : DIVA_PCI_LED_A;
else {
......@@ -464,10 +456,10 @@ diva_led_handler(struct IsdnCardState *cs)
DIVA_ISA_LED_A : DIVA_PCI_LED_A;
blink = 250;
}
if (cs->hw.diva.status & 0xf000)
if (cs->status & 0xf000)
cs->hw.diva.ctrl_reg |= (DIVA_ISA == cs->subtyp) ?
DIVA_ISA_LED_B : DIVA_PCI_LED_B;
else if (cs->hw.diva.status & 0x0f00) {
else if (cs->status & 0x0f00) {
cs->hw.diva.ctrl_reg ^= (DIVA_ISA == cs->subtyp) ?
DIVA_ISA_LED_B : DIVA_PCI_LED_B;
blink = 500;
......@@ -476,50 +468,8 @@ diva_led_handler(struct IsdnCardState *cs)
DIVA_ISA_LED_B : DIVA_PCI_LED_B);
byteout(cs->hw.diva.ctrl, cs->hw.diva.ctrl_reg);
if (blink) {
init_timer(&cs->hw.diva.tl);
cs->hw.diva.tl.expires = jiffies + ((blink * HZ) / 1000);
add_timer(&cs->hw.diva.tl);
}
}
static int
Diva_card_msg(struct IsdnCardState *cs, int mt, void *arg)
{
switch (mt) {
case (MDL_REMOVE | REQUEST):
cs->hw.diva.status = 0;
break;
case (MDL_ASSIGN | REQUEST):
cs->hw.diva.status |= DIVA_ASSIGN;
break;
case MDL_INFO_SETUP:
if ((long)arg)
cs->hw.diva.status |= 0x0200;
else
cs->hw.diva.status |= 0x0100;
break;
case MDL_INFO_CONN:
if ((long)arg)
cs->hw.diva.status |= 0x2000;
else
cs->hw.diva.status |= 0x1000;
break;
case MDL_INFO_REL:
if ((long)arg) {
cs->hw.diva.status &= ~0x2000;
cs->hw.diva.status &= ~0x0200;
} else {
cs->hw.diva.status &= ~0x1000;
cs->hw.diva.status &= ~0x0100;
}
break;
}
if ((cs->subtyp != DIVA_IPAC_ISA) &&
(cs->subtyp != DIVA_IPAC_PCI) &&
(cs->subtyp != DIVA_IPACX_PCI) )
diva_led_handler(cs);
return(0);
if (blink)
mod_timer(&cs->hw.diva.tl, jiffies + (blink * HZ) / 1000);
}
static void
......@@ -537,31 +487,32 @@ diva_ipac_pci_init(struct IsdnCardState *cs)
}
static struct card_ops diva_ops = {
.init = inithscxisac,
.reset = diva_reset,
.release = diva_release,
.irq_func = diva_interrupt,
.init = inithscxisac,
.reset = diva_reset,
.release = diva_release,
.led_handler = diva_led_handler,
.irq_func = diva_interrupt,
};
static struct card_ops diva_ipac_isa_ops = {
.init = ipac_init,
.reset = diva_ipac_isa_reset,
.release = hisax_release_resources,
.irq_func = ipac_irq,
.init = ipac_init,
.reset = diva_ipac_isa_reset,
.release = hisax_release_resources,
.irq_func = ipac_irq,
};
static struct card_ops diva_ipac_pci_ops = {
.init = diva_ipac_pci_init,
.reset = diva_ipac_pci_reset,
.release = diva_ipac_pci_release,
.irq_func = diva_ipac_pci_irq,
.init = diva_ipac_pci_init,
.reset = diva_ipac_pci_reset,
.release = diva_ipac_pci_release,
.irq_func = diva_ipac_pci_irq,
};
static struct card_ops diva_ipacx_pci_ops = {
.init = diva_ipacx_pci_init,
.reset = diva_ipacx_pci_reset,
.release = diva_ipac_pci_release,
.irq_func = diva_ipacx_pci_irq,
.init = diva_ipacx_pci_init,
.reset = diva_ipacx_pci_reset,
.release = diva_ipac_pci_release,
.irq_func = diva_ipacx_pci_irq,
};
static struct pci_dev *dev_diva __initdata = NULL;
......@@ -607,7 +558,6 @@ setup_diva(struct IsdnCard *card)
printk(KERN_INFO "HiSax: Eicon.Diehl Diva driver Rev. %s\n", HiSax_getrev(tmp));
if (cs->typ != ISDN_CTYPE_DIEHLDIVA)
return(0);
cs->hw.diva.status = 0;
if (card->para[1]) {
cs->hw.diva.ctrl_reg = 0;
cs->hw.diva.cfg_reg = card->para[1];
......@@ -775,7 +725,6 @@ setup_diva(struct IsdnCard *card)
if (!request_io(&cs->rs, cs->hw.diva.cfg_reg, bytecnt, "diva isdn"))
return 0;
}
cs->cardmsg = &Diva_card_msg;
if (cs->subtyp == DIVA_IPAC_ISA) {
diva_ipac_isa_reset(cs);
cs->dc_hw_ops = &ipac_dc_ops;
......
......@@ -106,7 +106,6 @@ const char *ITACVer[] =
/* Status Flags */
#define ELSA_TIMER_AKTIV 1
#define ELSA_BAD_PWR 2
#define ELSA_ASSIGN 4
#define RS_ISR_PASS_LIMIT 256
#define _INLINE_ inline
......@@ -553,8 +552,15 @@ elsa_led_handler(struct IsdnCardState *cs)
if (cs->subtyp == ELSA_PCMCIA || cs->subtyp == ELSA_PCMCIA_IPAC)
return;
del_timer(&cs->hw.elsa.tl);
if (cs->hw.elsa.status & ELSA_ASSIGN)
if (cs->typ == ISDN_CTYPE_ELSA) {
int pwr = bytein(cs->hw.elsa.ale);
if (pwr & 0x08)
cs->hw.elsa.status |= ELSA_BAD_PWR;
else
cs->hw.elsa.status &= ~ELSA_BAD_PWR;
}
if (cs->status & 0x0001)
cs->hw.elsa.ctrl_reg |= ELSA_STAT_LED;
else if (cs->hw.elsa.status & ELSA_BAD_PWR)
cs->hw.elsa.ctrl_reg &= ~ELSA_STAT_LED;
......@@ -562,9 +568,9 @@ elsa_led_handler(struct IsdnCardState *cs)
cs->hw.elsa.ctrl_reg ^= ELSA_STAT_LED;
blink = 250;
}
if (cs->hw.elsa.status & 0xf000)
if (cs->status & 0xf000)
cs->hw.elsa.ctrl_reg |= ELSA_LINE_LED;
else if (cs->hw.elsa.status & 0x0f00) {
else if (cs->status & 0x0f00) {
cs->hw.elsa.ctrl_reg ^= ELSA_LINE_LED;
blink = 500;
} else
......@@ -580,56 +586,9 @@ elsa_led_handler(struct IsdnCardState *cs)
writereg(cs, cs->hw.elsa.isac, IPAC_ATX, led);
} else
byteout(cs->hw.elsa.ctrl, cs->hw.elsa.ctrl_reg);
if (blink) {
init_timer(&cs->hw.elsa.tl);
cs->hw.elsa.tl.expires = jiffies + ((blink * HZ) / 1000);
add_timer(&cs->hw.elsa.tl);
}
}
static int
Elsa_card_msg(struct IsdnCardState *cs, int mt, void *arg)
{
int ret = 0;
switch (mt) {
case (MDL_REMOVE | REQUEST):
cs->hw.elsa.status &= 0;
break;
case (MDL_ASSIGN | REQUEST):
cs->hw.elsa.status |= ELSA_ASSIGN;
break;
case MDL_INFO_SETUP:
if ((long) arg)
cs->hw.elsa.status |= 0x0200;
else
cs->hw.elsa.status |= 0x0100;
break;
case MDL_INFO_CONN:
if ((long) arg)
cs->hw.elsa.status |= 0x2000;
else
cs->hw.elsa.status |= 0x1000;
break;
case MDL_INFO_REL:
if ((long) arg) {
cs->hw.elsa.status &= ~0x2000;
cs->hw.elsa.status &= ~0x0200;
} else {
cs->hw.elsa.status &= ~0x1000;
cs->hw.elsa.status &= ~0x0100;
}
break;
}
if (cs->typ == ISDN_CTYPE_ELSA) {
int pwr = bytein(cs->hw.elsa.ale);
if (pwr & 0x08)
cs->hw.elsa.status |= ELSA_BAD_PWR;
else
cs->hw.elsa.status &= ~ELSA_BAD_PWR;
}
elsa_led_handler(cs);
return(ret);
if (blink)
mod_timer(&cs->hw.elsa.tl, jiffies + (blink * HZ) / 1000);
}
#if ARCOFI_USE
......@@ -712,21 +671,23 @@ elsa_test(struct IsdnCardState *cs)
}
static struct card_ops elsa_ops = {
.init = elsa_init,
.test = elsa_test,
.reset = elsa_reset,
.release = elsa_release,
.aux_ind = elsa_aux_ind,
.irq_func = elsa_interrupt,
.init = elsa_init,
.test = elsa_test,
.reset = elsa_reset,
.release = elsa_release,
.aux_ind = elsa_aux_ind,
.led_handler = elsa_led_handler,
.irq_func = elsa_interrupt,
};
static struct card_ops elsa_ipac_ops = {
.init = elsa_ipac_init,
.test = elsa_test,
.reset = elsa_reset,
.release = elsa_release,
.aux_ind = elsa_aux_ind,
.irq_func = elsa_interrupt_ipac,
.init = elsa_ipac_init,
.test = elsa_test,
.reset = elsa_reset,
.release = elsa_release,
.aux_ind = elsa_aux_ind,
.led_handler = elsa_led_handler,
.irq_func = elsa_interrupt_ipac,
};
static unsigned char
......@@ -1085,7 +1046,6 @@ setup_elsa(struct IsdnCard *card)
}
printk(KERN_INFO "Elsa: timer OK; resetting card\n");
}
cs->cardmsg = &Elsa_card_msg;
elsa_reset(cs);
if ((cs->subtyp == ELSA_QS1000PCI) || (cs->subtyp == ELSA_QS3000PCI) || (cs->subtyp == ELSA_PCMCIA_IPAC)) {
cs->dc_hw_ops = &ipac_dc_ops;
......
......@@ -178,25 +178,18 @@ enpci_bc_deactivate(struct IsdnCardState *cs, int chan)
}
}
static int
enpci_card_msg(struct IsdnCardState *cs, int mt, void *arg)
static void
enpci_led_handler(struct IsdnCardState *cs)
{
if (cs->debug & L1_DEB_ISAC)
debugl1(cs, "enter:now PCI: card_msg: 0x%04X", mt);
switch (mt) {
case MDL_ASSIGN:
/* TEI assigned, LED1 on */
cs->hw.njet.auxd = TJ_AMD_IRQ << 1;
OutByte(cs->hw.njet.base + NETJET_AUXDATA, cs->hw.njet.auxd);
break;
case MDL_REMOVE:
/* TEI removed, LEDs off */
cs->hw.njet.auxd = 0;
OutByte(cs->hw.njet.base + NETJET_AUXDATA, 0x00);
break;
if (cs->status & 0x0001) {
/* TEI assigned, LED1 on */
cs->hw.njet.auxd = TJ_AMD_IRQ << 1;
OutByte(cs->hw.njet.base + NETJET_AUXDATA, cs->hw.njet.auxd);
} else {
/* TEI removed, LEDs off */
cs->hw.njet.auxd = 0;
OutByte(cs->hw.njet.base + NETJET_AUXDATA, 0x00);
}
return(0);
}
static void
......@@ -262,10 +255,11 @@ enpci_interrupt(int intno, void *dev_id, struct pt_regs *regs)
}
static struct card_ops enpci_ops = {
.init = enpci_init,
.reset = enpci_reset,
.release = netjet_release,
.irq_func = enpci_interrupt,
.init = enpci_init,
.reset = enpci_reset,
.release = netjet_release,
.led_handler = enpci_led_handler,
.irq_func = enpci_interrupt,
};
static struct pci_dev *dev_netjet __initdata = NULL;
......@@ -350,7 +344,6 @@ setup_enternow_pci(struct IsdnCard *card)
cs->dc_hw_ops = &enternow_ops;
cs->dc.amd7930.setIrqMask = &enpci_setIrqMask;
cs->cardmsg = &enpci_card_msg;
cs->irq_flags |= SA_SHIRQ;
cs->card_ops = &enpci_ops;
......
......@@ -70,9 +70,6 @@
#define MDL_ASSIGN 0x0280
#define MDL_REMOVE 0x0284
#define MDL_ERROR 0x0288
#define MDL_INFO_SETUP 0x02E0
#define MDL_INFO_CONN 0x02E4
#define MDL_INFO_REL 0x02E8
#define CC_SETUP 0x0300
#define CC_RESUME 0x0304
......@@ -619,7 +616,6 @@ struct diva_hw {
unsigned int isac;
unsigned long hscx_adr;
unsigned int hscx;
unsigned int status;
struct timer_list tl;
u8 ctrl_reg;
};
......@@ -885,12 +881,13 @@ struct IsdnCardState;
/* Methods provided by driver for a specific card */
struct card_ops {
void (*init) (struct IsdnCardState *);
void (*test) (struct IsdnCardState *);
int (*reset) (struct IsdnCardState *);
void (*release) (struct IsdnCardState *);
void (*aux_ind) (struct IsdnCardState *, void *);
void (*irq_func) (int, void *, struct pt_regs *);
void (*init) (struct IsdnCardState *);
void (*test) (struct IsdnCardState *);
int (*reset) (struct IsdnCardState *);
void (*release) (struct IsdnCardState *);
void (*aux_ind) (struct IsdnCardState *, void *);
void (*led_handler)(struct IsdnCardState *);
void (*irq_func) (int, void *, struct pt_regs *);
};
/* Card specific drivers provide methods to access the
......@@ -950,6 +947,7 @@ struct IsdnCardState {
struct resources rs;
unsigned int irq;
unsigned long irq_flags;
int status;
long HW_Flags;
int *busy_flag;
int chanlimit; /* limited number of B-chans to use */
......
......@@ -401,30 +401,23 @@ sedlbauer_isar_release(struct IsdnCardState *cs)
hisax_release_resources(cs);
}
static int
Sedl_card_msg(struct IsdnCardState *cs, int mt, void *arg)
static void
sedlbauer_led_handler(struct IsdnCardState *cs)
{
switch (mt) {
case MDL_INFO_CONN:
if (cs->subtyp != SEDL_SPEEDFAX_PYRAMID)
return(0);
if ((long) arg)
cs->hw.sedl.reset_off &= ~SEDL_ISAR_PCI_LED2;
else
cs->hw.sedl.reset_off &= ~SEDL_ISAR_PCI_LED1;
byteout(cs->hw.sedl.cfg_reg +3, cs->hw.sedl.reset_off);
break;
case MDL_INFO_REL:
if (cs->subtyp != SEDL_SPEEDFAX_PYRAMID)
return(0);
if ((long) arg)
cs->hw.sedl.reset_off |= SEDL_ISAR_PCI_LED2;
else
cs->hw.sedl.reset_off |= SEDL_ISAR_PCI_LED1;
byteout(cs->hw.sedl.cfg_reg +3, cs->hw.sedl.reset_off);
break;
}
return(0);
if (cs->subtyp != SEDL_SPEEDFAX_PYRAMID)
return;
if (cs->status & 0x2000)
cs->hw.sedl.reset_off &= ~SEDL_ISAR_PCI_LED2;
else
cs->hw.sedl.reset_off |= SEDL_ISAR_PCI_LED2;
if (cs->status & 0x1000)
cs->hw.sedl.reset_off &= ~SEDL_ISAR_PCI_LED1;
else
cs->hw.sedl.reset_off |= SEDL_ISAR_PCI_LED1;
byteout(cs->hw.sedl.cfg_reg +3, cs->hw.sedl.reset_off);
}
static void
......@@ -436,24 +429,27 @@ sedlbauer_isar_init(struct IsdnCardState *cs)
}
static struct card_ops sedlbauer_ops = {
.init = inithscxisac,
.reset = sedlbauer_reset,
.release = hisax_release_resources,
.irq_func = sedlbauer_interrupt,
.init = inithscxisac,
.reset = sedlbauer_reset,
.release = hisax_release_resources,
.led_handler = sedlbauer_led_handler,
.irq_func = sedlbauer_interrupt,
};
static struct card_ops sedlbauer_ipac_ops = {
.init = ipac_init,
.reset = sedlbauer_reset,
.release = hisax_release_resources,
.irq_func = ipac_irq,
.init = ipac_init,
.reset = sedlbauer_reset,
.release = hisax_release_resources,
.led_handler = sedlbauer_led_handler,
.irq_func = ipac_irq,
};
static struct card_ops sedlbauer_isar_ops = {
.init = sedlbauer_isar_init,
.reset = sedlbauer_reset,
.release = sedlbauer_isar_release,
.irq_func = sedlbauer_isar_interrupt,
.init = sedlbauer_isar_init,
.reset = sedlbauer_reset,
.release = sedlbauer_isar_release,
.led_handler = sedlbauer_led_handler,
.irq_func = sedlbauer_isar_interrupt,
};
static struct pci_dev *dev_sedl __devinitdata = NULL;
......@@ -629,8 +625,6 @@ setup_sedlbauer(struct IsdnCard *card)
cs->hw.sedl.cfg_reg + bytecnt,
cs->irq);
cs->cardmsg = &Sedl_card_msg;
/*
* testing ISA and PCMCIA Cards for IPAC, default is ISAC
* do not test for PCI card, because ports are different
......
......@@ -77,15 +77,17 @@ static char *strTeiEvent[] =
static inline void
mdl_assign(struct IsdnCardState *cs)
{
if (cs->cardmsg)
cs->cardmsg(cs, MDL_ASSIGN | REQUEST, NULL);
cs->status |= 0x0001;
if (cs->card_ops->led_handler)
cs->card_ops->led_handler(cs);
}
static inline void
mdl_remove(struct IsdnCardState *cs)
{
if (cs->cardmsg)
cs->cardmsg(cs, MDL_REMOVE | REQUEST, NULL);
cs->status = 0;
if (cs->card_ops->led_handler)
cs->card_ops->led_handler(cs);
}
unsigned int
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment