Commit c29fba8a authored by Kai Germaschewski's avatar Kai Germaschewski

Merge tp1.ruhr-uni-bochum.de:/scratch/kai/kernel/v2.5/linux-2.5

into tp1.ruhr-uni-bochum.de:/scratch/kai/kernel/v2.5/linux-2.5.isdn
parents 85c9262d 11aeb65a
...@@ -51,9 +51,6 @@ static int __init divert_init(void) ...@@ -51,9 +51,6 @@ static int __init divert_init(void)
printk(KERN_WARNING "dss1_divert: error %d registering module, not loaded\n",i); printk(KERN_WARNING "dss1_divert: error %d registering module, not loaded\n",i);
return(-EIO); return(-EIO);
} }
#if (LINUX_VERSION_CODE < 0x020111)
register_symtab(0);
#endif
printk(KERN_INFO "dss1_divert module successfully installed\n"); printk(KERN_INFO "dss1_divert module successfully installed\n");
return(0); return(0);
} }
......
...@@ -38,12 +38,12 @@ hisax-objs-$(CONFIG_HISAX_S0BOX) += s0box.o isac.o arcofi.o hscx.o ...@@ -38,12 +38,12 @@ hisax-objs-$(CONFIG_HISAX_S0BOX) += s0box.o isac.o arcofi.o hscx.o
hisax-objs-$(CONFIG_HISAX_AVM_A1) += avm_a1.o isac.o arcofi.o hscx.o hisax-objs-$(CONFIG_HISAX_AVM_A1) += avm_a1.o isac.o arcofi.o hscx.o
hisax-objs-$(CONFIG_HISAX_AVM_A1_PCMCIA) += avm_a1p.o isac.o arcofi.o hscx.o hisax-objs-$(CONFIG_HISAX_AVM_A1_PCMCIA) += avm_a1p.o isac.o arcofi.o hscx.o
hisax-objs-$(CONFIG_HISAX_FRITZPCI) += avm_pci.o isac.o arcofi.o hisax-objs-$(CONFIG_HISAX_FRITZPCI) += avm_pci.o isac.o arcofi.o
hisax-objs-$(CONFIG_HISAX_ELSA) += elsa.o isac.o arcofi.o hscx.o hisax-objs-$(CONFIG_HISAX_ELSA) += elsa.o isac.o arcofi.o hscx.o ipac.o
hisax-objs-$(CONFIG_HISAX_IX1MICROR2) += ix1_micro.o isac.o arcofi.o hscx.o hisax-objs-$(CONFIG_HISAX_IX1MICROR2) += ix1_micro.o isac.o arcofi.o hscx.o
hisax-objs-$(CONFIG_HISAX_DIEHLDIVA) += diva.o isac.o arcofi.o hscx.o ipacx.o hisax-objs-$(CONFIG_HISAX_DIEHLDIVA) += diva.o isac.o arcofi.o hscx.o ipac.o ipacx.o
hisax-objs-$(CONFIG_HISAX_ASUSCOM) += asuscom.o isac.o arcofi.o hscx.o hisax-objs-$(CONFIG_HISAX_ASUSCOM) += asuscom.o isac.o arcofi.o hscx.o ipac.o
hisax-objs-$(CONFIG_HISAX_TELEINT) += teleint.o isac.o arcofi.o hfc_2bs0.o hisax-objs-$(CONFIG_HISAX_TELEINT) += teleint.o isac.o arcofi.o hfc_2bs0.o
hisax-objs-$(CONFIG_HISAX_SEDLBAUER) += sedlbauer.o isac.o arcofi.o hscx.o isar.o hisax-objs-$(CONFIG_HISAX_SEDLBAUER) += sedlbauer.o isac.o arcofi.o hscx.o ipac.o isar.o
hisax-objs-$(CONFIG_HISAX_SPORTSTER) += sportster.o isac.o arcofi.o hscx.o hisax-objs-$(CONFIG_HISAX_SPORTSTER) += sportster.o isac.o arcofi.o hscx.o
hisax-objs-$(CONFIG_HISAX_MIC) += mic.o isac.o arcofi.o hscx.o hisax-objs-$(CONFIG_HISAX_MIC) += mic.o isac.o arcofi.o hscx.o
hisax-objs-$(CONFIG_HISAX_NETJET) += nj_s.o netjet.o isac.o arcofi.o hisax-objs-$(CONFIG_HISAX_NETJET) += nj_s.o netjet.o isac.o arcofi.o
...@@ -55,8 +55,8 @@ hisax-objs-$(CONFIG_HISAX_NICCY) += niccy.o isac.o arcofi.o hscx.o ...@@ -55,8 +55,8 @@ hisax-objs-$(CONFIG_HISAX_NICCY) += niccy.o isac.o arcofi.o hscx.o
hisax-objs-$(CONFIG_HISAX_ISURF) += isurf.o isac.o arcofi.o isar.o hisax-objs-$(CONFIG_HISAX_ISURF) += isurf.o isac.o arcofi.o isar.o
hisax-objs-$(CONFIG_HISAX_HSTSAPHIR) += saphir.o isac.o arcofi.o hscx.o hisax-objs-$(CONFIG_HISAX_HSTSAPHIR) += saphir.o isac.o arcofi.o hscx.o
hisax-objs-$(CONFIG_HISAX_BKM_A4T) += bkm_a4t.o isac.o arcofi.o jade.o hisax-objs-$(CONFIG_HISAX_BKM_A4T) += bkm_a4t.o isac.o arcofi.o jade.o
hisax-objs-$(CONFIG_HISAX_SCT_QUADRO) += bkm_a8.o isac.o arcofi.o hscx.o hisax-objs-$(CONFIG_HISAX_SCT_QUADRO) += bkm_a8.o isac.o arcofi.o hscx.o ipac.o
hisax-objs-$(CONFIG_HISAX_GAZEL) += gazel.o isac.o arcofi.o hscx.o hisax-objs-$(CONFIG_HISAX_GAZEL) += gazel.o isac.o arcofi.o hscx.o ipac.o
hisax-objs-$(CONFIG_HISAX_W6692) += w6692.o hisax-objs-$(CONFIG_HISAX_W6692) += w6692.o
hisax-objs-$(CONFIG_HISAX_ENTERNOW_PCI) += enternow_pci.o amd7930_fn.o hisax-objs-$(CONFIG_HISAX_ENTERNOW_PCI) += enternow_pci.o amd7930_fn.o
#hisax-objs-$(CONFIG_HISAX_TESTEMU) += testemu.o #hisax-objs-$(CONFIG_HISAX_TESTEMU) += testemu.o
......
...@@ -659,7 +659,7 @@ Amd7930_l1hw(struct PStack *st, int pr, void *arg) ...@@ -659,7 +659,7 @@ Amd7930_l1hw(struct PStack *st, int pr, void *arg)
} }
} }
void static int
setstack_Amd7930(struct PStack *st, struct IsdnCardState *cs) setstack_Amd7930(struct PStack *st, struct IsdnCardState *cs)
{ {
...@@ -667,16 +667,9 @@ setstack_Amd7930(struct PStack *st, struct IsdnCardState *cs) ...@@ -667,16 +667,9 @@ setstack_Amd7930(struct PStack *st, struct IsdnCardState *cs)
debugl1(cs, "Amd7930: setstack called"); debugl1(cs, "Amd7930: setstack called");
st->l1.l1hw = Amd7930_l1hw; st->l1.l1hw = Amd7930_l1hw;
return 0;
} }
void
DC_Close_Amd7930(struct IsdnCardState *cs) {
if (cs->debug & L1_DEB_ISAC)
debugl1(cs, "Amd7930: DC_Close called");
}
static void static void
dbusy_timer_handler(struct IsdnCardState *cs) dbusy_timer_handler(struct IsdnCardState *cs)
{ {
...@@ -723,7 +716,7 @@ dbusy_timer_handler(struct IsdnCardState *cs) ...@@ -723,7 +716,7 @@ dbusy_timer_handler(struct IsdnCardState *cs)
/* Transmitter reset, abort transmit */ /* Transmitter reset, abort transmit */
wByteAMD(cs, 0x21, 0x82); wByteAMD(cs, 0x21, 0x82);
wByteAMD(cs, 0x21, 0x02); wByteAMD(cs, 0x21, 0x02);
cs->irq_func(cs->irq, cs, NULL); cs->card_ops->irq_func(cs->irq, cs, NULL); /* FIXME? */
if (cs->debug & L1_DEB_ISAC) if (cs->debug & L1_DEB_ISAC)
debugl1(cs, "Amd7930: dbusy_timer_handler: Transmitter reset"); debugl1(cs, "Amd7930: dbusy_timer_handler: Transmitter reset");
...@@ -764,6 +757,11 @@ static u16 initAMD[] = { ...@@ -764,6 +757,11 @@ static u16 initAMD[] = {
0xFFFF}; 0xFFFF};
static struct dc_l1_ops amd7930_l1_ops = {
.open = setstack_Amd7930,
.bh_func = Amd7930_bh,
.dbusy_func = dbusy_timer_handler,
};
void __devinit void __devinit
Amd7930_init(struct IsdnCardState *cs) Amd7930_init(struct IsdnCardState *cs)
...@@ -774,16 +772,11 @@ Amd7930_init(struct IsdnCardState *cs) ...@@ -774,16 +772,11 @@ Amd7930_init(struct IsdnCardState *cs)
if (cs->debug & L1_DEB_ISAC) if (cs->debug & L1_DEB_ISAC)
debugl1(cs, "Amd7930: initamd called"); debugl1(cs, "Amd7930: initamd called");
dc_l1_init(cs, &amd7930_l1_ops);
cs->dc.amd7930.tx_xmtlen = 0; cs->dc.amd7930.tx_xmtlen = 0;
cs->dc.amd7930.old_state = 0; cs->dc.amd7930.old_state = 0;
cs->dc.amd7930.lmr1 = 0x40; cs->dc.amd7930.lmr1 = 0x40;
cs->dc.amd7930.ph_command = Amd7930_ph_command; cs->dc.amd7930.ph_command = Amd7930_ph_command;
INIT_WORK(&cs->work, Amd7930_bh, cs);
cs->setstack_d = setstack_Amd7930;
cs->DC_Close = DC_Close_Amd7930;
cs->dbusytimer.function = (void *) dbusy_timer_handler;
cs->dbusytimer.data = (long) cs;
init_timer(&cs->dbusytimer);
/* AMD Initialisation */ /* AMD Initialisation */
for (ptr = initAMD; *ptr != 0xFFFF; ) { for (ptr = initAMD; *ptr != 0xFFFF; ) {
......
...@@ -113,37 +113,6 @@ static struct dc_hw_ops isac_ops = { ...@@ -113,37 +113,6 @@ static struct dc_hw_ops isac_ops = {
.write_fifo = isac_write_fifo, .write_fifo = isac_write_fifo,
}; };
static u8
ipac_dc_read(struct IsdnCardState *cs, u8 offset)
{
return readreg(cs, cs->hw.asus.isac, offset|0x80);
}
static void
ipac_dc_write(struct IsdnCardState *cs, u8 offset, u8 value)
{
writereg(cs, cs->hw.asus.isac, offset|0x80, value);
}
static void
ipac_dc_read_fifo(struct IsdnCardState *cs, u8 * data, int size)
{
readfifo(cs, cs->hw.asus.isac, 0x80, data, size);
}
static void
ipac_dc_write_fifo(struct IsdnCardState *cs, u8 * data, int size)
{
writefifo(cs, cs->hw.asus.isac, 0x80, data, size);
}
static struct dc_hw_ops ipac_dc_ops = {
.read_reg = ipac_dc_read,
.write_reg = ipac_dc_write,
.read_fifo = ipac_dc_read_fifo,
.write_fifo = ipac_dc_write_fifo,
};
static u8 static u8
hscx_read(struct IsdnCardState *cs, int hscx, u8 offset) hscx_read(struct IsdnCardState *cs, int hscx, u8 offset)
{ {
...@@ -175,141 +144,106 @@ static struct bc_hw_ops hscx_ops = { ...@@ -175,141 +144,106 @@ static struct bc_hw_ops hscx_ops = {
.write_fifo = hscx_write_fifo, .write_fifo = hscx_write_fifo,
}; };
static void static inline u8
asuscom_interrupt(int intno, void *dev_id, struct pt_regs *regs) ipac_read(struct IsdnCardState *cs, u8 off)
{ {
struct IsdnCardState *cs = dev_id; u8 ret;
u8 val; unsigned long flags;
spin_lock(&cs->lock); spin_lock_irqsave(&asuscom_lock, flags);
val = hscx_read(cs, 1, HSCX_ISTA); byteout(cs->hw.asus.adr, off);
Start_HSCX: ret = bytein(cs->hw.asus.isac);
if (val) spin_unlock_irqrestore(&asuscom_lock, flags);
hscx_int_main(cs, val); return ret;
val = isac_read(cs, ISAC_ISTA);
Start_ISAC:
if (val)
isac_interrupt(cs, val);
val = hscx_read(cs, 1, HSCX_ISTA);
if (val) {
if (cs->debug & L1_DEB_HSCX)
debugl1(cs, "HSCX IntStat after IntRoutine");
goto Start_HSCX;
}
val = isac_read(cs, ISAC_ISTA);
if (val) {
if (cs->debug & L1_DEB_ISAC)
debugl1(cs, "ISAC IntStat after IntRoutine");
goto Start_ISAC;
}
hscx_write(cs, 0, HSCX_MASK, 0xFF);
hscx_write(cs, 1, HSCX_MASK, 0xFF);
isac_write(cs, ISAC_MASK, 0xFF);
isac_write(cs, ISAC_MASK, 0x0);
hscx_write(cs, 0, HSCX_MASK, 0x0);
hscx_write(cs, 1, HSCX_MASK, 0x0);
spin_unlock(&cs->lock);
} }
static void static inline void
asuscom_interrupt_ipac(int intno, void *dev_id, struct pt_regs *regs) ipac_write(struct IsdnCardState *cs, u8 off, u8 data)
{ {
struct IsdnCardState *cs = dev_id; unsigned long flags;
u8 ista, val, icnt = 5;
if (!cs) { spin_lock_irqsave(&asuscom_lock, flags);
printk(KERN_WARNING "ISDNLink: Spurious interrupt!\n"); byteout(cs->hw.asus.adr, off);
return; byteout(cs->hw.asus.isac, data);
} spin_unlock_irqrestore(&asuscom_lock, flags);
ista = readreg(cs, cs->hw.asus.isac, IPAC_ISTA);
Start_IPAC:
if (cs->debug & L1_DEB_IPAC)
debugl1(cs, "IPAC ISTA %02X", ista);
if (ista & 0x0f) {
val = hscx_read(cs, 1, HSCX_ISTA);
if (ista & 0x01)
val |= 0x01;
if (ista & 0x04)
val |= 0x02;
if (ista & 0x08)
val |= 0x04;
if (val)
hscx_int_main(cs, val);
}
if (ista & 0x20) {
val = ipac_dc_read(cs, ISAC_ISTA) & 0xfe;
if (val) {
isac_interrupt(cs, val);
}
}
if (ista & 0x10) {
val = 0x01;
isac_interrupt(cs, val);
}
ista = readreg(cs, cs->hw.asus.isac, IPAC_ISTA);
if ((ista & 0x3f) && icnt) {
icnt--;
goto Start_IPAC;
}
if (!icnt)
printk(KERN_WARNING "ASUS IRQ LOOP\n");
writereg(cs, cs->hw.asus.isac, IPAC_MASK, 0xFF);
writereg(cs, cs->hw.asus.isac, IPAC_MASK, 0xC0);
} }
void static inline void
release_io_asuscom(struct IsdnCardState *cs) ipac_readfifo(struct IsdnCardState *cs, u8 off, u8 * data, int size)
{ {
int bytecnt = 8; byteout(cs->hw.asus.adr, off);
insb(cs->hw.asus.isac, data, size);
}
if (cs->hw.asus.cfg_reg)
release_region(cs->hw.asus.cfg_reg, bytecnt); static inline void
ipac_writefifo(struct IsdnCardState *cs, u8 off, u8 * data, int size)
{
byteout(cs->hw.asus.adr, off);
outsb(cs->hw.asus.isac, data, size);
} }
/* This will generate ipac_dc_ops and ipac_bc_ops using the functions
* above */
BUILD_IPAC_OPS(ipac);
static void static void
reset_asuscom(struct IsdnCardState *cs) asuscom_release(struct IsdnCardState *cs)
{
if (cs->hw.asus.cfg_reg)
release_region(cs->hw.asus.cfg_reg, 8);
}
static int
asuscom_reset(struct IsdnCardState *cs)
{ {
if (cs->subtyp == ASUS_IPAC)
writereg(cs, cs->hw.asus.isac, IPAC_POTA2, 0x20);
else
byteout(cs->hw.asus.adr, ASUS_RESET); /* Reset On */ byteout(cs->hw.asus.adr, ASUS_RESET); /* Reset On */
set_current_state(TASK_UNINTERRUPTIBLE); set_current_state(TASK_UNINTERRUPTIBLE);
schedule_timeout((10*HZ)/1000); schedule_timeout((10*HZ)/1000);
if (cs->subtyp == ASUS_IPAC)
writereg(cs, cs->hw.asus.isac, IPAC_POTA2, 0x0);
else
byteout(cs->hw.asus.adr, 0); /* Reset Off */ byteout(cs->hw.asus.adr, 0); /* Reset Off */
set_current_state(TASK_UNINTERRUPTIBLE); set_current_state(TASK_UNINTERRUPTIBLE);
schedule_timeout((10*HZ)/1000); schedule_timeout((10*HZ)/1000);
if (cs->subtyp == ASUS_IPAC) { return 0;
}
static int
asuscom_ipac_reset(struct IsdnCardState *cs)
{
writereg(cs, cs->hw.asus.isac, IPAC_POTA2, 0x20);
set_current_state(TASK_UNINTERRUPTIBLE);
schedule_timeout((10*HZ)/1000);
writereg(cs, cs->hw.asus.isac, IPAC_POTA2, 0x0);
set_current_state(TASK_UNINTERRUPTIBLE);
schedule_timeout((10*HZ)/1000);
writereg(cs, cs->hw.asus.isac, IPAC_CONF, 0x0); writereg(cs, cs->hw.asus.isac, IPAC_CONF, 0x0);
writereg(cs, cs->hw.asus.isac, IPAC_ACFG, 0xff); writereg(cs, cs->hw.asus.isac, IPAC_ACFG, 0xff);
writereg(cs, cs->hw.asus.isac, IPAC_AOE, 0x0); writereg(cs, cs->hw.asus.isac, IPAC_AOE, 0x0);
writereg(cs, cs->hw.asus.isac, IPAC_MASK, 0xc0); writereg(cs, cs->hw.asus.isac, IPAC_MASK, 0xc0);
writereg(cs, cs->hw.asus.isac, IPAC_PCFG, 0x12); writereg(cs, cs->hw.asus.isac, IPAC_PCFG, 0x12);
} return 0;
} }
static int static int
Asus_card_msg(struct IsdnCardState *cs, int mt, void *arg) Asus_card_msg(struct IsdnCardState *cs, int mt, void *arg)
{ {
switch (mt) {
case CARD_RESET:
reset_asuscom(cs);
return(0);
case CARD_RELEASE:
release_io_asuscom(cs);
return(0);
case CARD_INIT:
cs->debug |= L1_DEB_IPAC;
inithscxisac(cs);
return(0);
case CARD_TEST:
return(0);
}
return(0); return(0);
} }
static struct card_ops asuscom_ops = {
.init = inithscxisac,
.reset = asuscom_reset,
.release = asuscom_release,
.irq_func = hscxisac_irq,
};
static struct card_ops asuscom_ipac_ops = {
.init = ipac_init,
.reset = asuscom_ipac_reset,
.release = asuscom_release,
.irq_func = ipac_irq,
};
#ifdef __ISAPNP__ #ifdef __ISAPNP__
static struct isapnp_device_id asus_ids[] __initdata = { static struct isapnp_device_id asus_ids[] __initdata = {
{ ISAPNP_VENDOR('A', 'S', 'U'), ISAPNP_FUNCTION(0x1688), { ISAPNP_VENDOR('A', 'S', 'U'), ISAPNP_FUNCTION(0x1688),
...@@ -396,36 +330,36 @@ setup_asuscom(struct IsdnCard *card) ...@@ -396,36 +330,36 @@ setup_asuscom(struct IsdnCard *card)
} }
printk(KERN_INFO "ISDNLink: defined at 0x%x IRQ %d\n", printk(KERN_INFO "ISDNLink: defined at 0x%x IRQ %d\n",
cs->hw.asus.cfg_reg, cs->irq); cs->hw.asus.cfg_reg, cs->irq);
cs->bc_hw_ops = &hscx_ops;
cs->cardmsg = &Asus_card_msg; cs->cardmsg = &Asus_card_msg;
cs->hw.asus.adr = cs->hw.asus.cfg_reg + ASUS_IPAC_ALE; cs->hw.asus.adr = cs->hw.asus.cfg_reg + ASUS_IPAC_ALE;
val = readreg(cs, cs->hw.asus.cfg_reg + ASUS_IPAC_DATA, IPAC_ID); val = readreg(cs, cs->hw.asus.cfg_reg + ASUS_IPAC_DATA, IPAC_ID);
if ((val == 1) || (val == 2)) { if ((val == 1) || (val == 2)) {
cs->subtyp = ASUS_IPAC; cs->subtyp = ASUS_IPAC;
cs->card_ops = &asuscom_ipac_ops;
cs->hw.asus.isac = cs->hw.asus.cfg_reg + ASUS_IPAC_DATA; cs->hw.asus.isac = cs->hw.asus.cfg_reg + ASUS_IPAC_DATA;
cs->hw.asus.hscx = cs->hw.asus.cfg_reg + ASUS_IPAC_DATA; cs->hw.asus.hscx = cs->hw.asus.cfg_reg + ASUS_IPAC_DATA;
test_and_set_bit(HW_IPAC, &cs->HW_Flags);
cs->dc_hw_ops = &ipac_dc_ops; cs->dc_hw_ops = &ipac_dc_ops;
cs->irq_func = &asuscom_interrupt_ipac; cs->bc_hw_ops = &ipac_bc_ops;
printk(KERN_INFO "Asus: IPAC version %x\n", val); printk(KERN_INFO "Asus: IPAC version %x\n", val);
} else { } else {
cs->subtyp = ASUS_ISACHSCX; cs->subtyp = ASUS_ISACHSCX;
cs->card_ops = &asuscom_ops;
cs->hw.asus.adr = cs->hw.asus.cfg_reg + ASUS_ADR; cs->hw.asus.adr = cs->hw.asus.cfg_reg + ASUS_ADR;
cs->hw.asus.isac = cs->hw.asus.cfg_reg + ASUS_ISAC; cs->hw.asus.isac = cs->hw.asus.cfg_reg + ASUS_ISAC;
cs->hw.asus.hscx = cs->hw.asus.cfg_reg + ASUS_HSCX; cs->hw.asus.hscx = cs->hw.asus.cfg_reg + ASUS_HSCX;
cs->hw.asus.u7 = cs->hw.asus.cfg_reg + ASUS_CTRL_U7; cs->hw.asus.u7 = cs->hw.asus.cfg_reg + ASUS_CTRL_U7;
cs->hw.asus.pots = cs->hw.asus.cfg_reg + ASUS_CTRL_POTS; cs->hw.asus.pots = cs->hw.asus.cfg_reg + ASUS_CTRL_POTS;
cs->dc_hw_ops = &isac_ops; cs->dc_hw_ops = &isac_ops;
cs->irq_func = &asuscom_interrupt; cs->bc_hw_ops = &hscx_ops;
ISACVersion(cs, "ISDNLink:"); ISACVersion(cs, "ISDNLink:");
if (HscxVersion(cs, "ISDNLink:")) { if (HscxVersion(cs, "ISDNLink:")) {
printk(KERN_WARNING printk(KERN_WARNING
"ISDNLink: wrong HSCX versions check IO address\n"); "ISDNLink: wrong HSCX versions check IO address\n");
release_io_asuscom(cs); asuscom_release(cs);
return (0); return (0);
} }
} }
printk(KERN_INFO "ISDNLink: resetting card\n"); printk(KERN_INFO "ISDNLink: resetting card\n");
reset_asuscom(cs); cs->card_ops->reset(cs);
return (1); return (1);
} }
...@@ -167,23 +167,29 @@ release_ioregs(struct IsdnCardState *cs, int mask) ...@@ -167,23 +167,29 @@ release_ioregs(struct IsdnCardState *cs, int mask)
static int static int
AVM_card_msg(struct IsdnCardState *cs, int mt, void *arg) AVM_card_msg(struct IsdnCardState *cs, int mt, void *arg)
{ {
switch (mt) {
case CARD_RESET:
return(0); return(0);
case CARD_RELEASE: }
release_ioregs(cs, 0x3f);
return(0); static void
case CARD_INIT: avm_a1_init(struct IsdnCardState *cs)
{
byteout(cs->hw.avm.cfg_reg, 0x16); byteout(cs->hw.avm.cfg_reg, 0x16);
byteout(cs->hw.avm.cfg_reg, 0x1E); byteout(cs->hw.avm.cfg_reg, 0x1E);
inithscxisac(cs); inithscxisac(cs);
return(0);
case CARD_TEST:
return(0);
}
return(0);
} }
static void
avm_a1_release(struct IsdnCardState *cs)
{
release_ioregs(cs, 0x3f);
}
static struct card_ops avm_a1_ops = {
.init = avm_a1_init,
.release = avm_a1_release,
.irq_func = avm_a1_interrupt,
};
int __init int __init
setup_avm_a1(struct IsdnCard *card) setup_avm_a1(struct IsdnCard *card)
{ {
...@@ -305,7 +311,7 @@ setup_avm_a1(struct IsdnCard *card) ...@@ -305,7 +311,7 @@ setup_avm_a1(struct IsdnCard *card)
cs->dc_hw_ops = &isac_ops; cs->dc_hw_ops = &isac_ops;
cs->bc_hw_ops = &hscx_ops; cs->bc_hw_ops = &hscx_ops;
cs->cardmsg = &AVM_card_msg; cs->cardmsg = &AVM_card_msg;
cs->irq_func = &avm_a1_interrupt; cs->card_ops = &avm_a1_ops;
ISACVersion(cs, "AVM A1:"); ISACVersion(cs, "AVM A1:");
if (HscxVersion(cs, "AVM A1:")) { if (HscxVersion(cs, "AVM A1:")) {
printk(KERN_WARNING printk(KERN_WARNING
......
...@@ -192,36 +192,35 @@ avm_a1p_interrupt(int intno, void *dev_id, struct pt_regs *regs) ...@@ -192,36 +192,35 @@ avm_a1p_interrupt(int intno, void *dev_id, struct pt_regs *regs)
static int static int
AVM_card_msg(struct IsdnCardState *cs, int mt, void *arg) AVM_card_msg(struct IsdnCardState *cs, int mt, void *arg)
{ {
switch (mt) { return 0;
case CARD_RESET: }
static void
avm_a1p_init(struct IsdnCardState *cs)
{
byteout(cs->hw.avm.cfg_reg+ASL0_OFFSET,
ASL0_W_TDISABLE|ASL0_W_TRESET|ASL0_W_IRQENABLE);
inithscxisac(cs);
}
static int
avm_a1p_reset(struct IsdnCardState *cs)
{
byteout(cs->hw.avm.cfg_reg+ASL0_OFFSET,0x00); byteout(cs->hw.avm.cfg_reg+ASL0_OFFSET,0x00);
HZDELAY(HZ / 5 + 1); HZDELAY(HZ / 5 + 1);
byteout(cs->hw.avm.cfg_reg+ASL0_OFFSET,ASL0_W_RESET); byteout(cs->hw.avm.cfg_reg+ASL0_OFFSET,ASL0_W_RESET);
HZDELAY(HZ / 5 + 1); HZDELAY(HZ / 5 + 1);
byteout(cs->hw.avm.cfg_reg+ASL0_OFFSET,0x00); byteout(cs->hw.avm.cfg_reg+ASL0_OFFSET,0x00);
return 0;
case CARD_RELEASE:
/* free_irq is done in HiSax_closecard(). */
/* free_irq(cs->irq, cs); */
return 0;
case CARD_INIT:
byteout(cs->hw.avm.cfg_reg+ASL0_OFFSET,ASL0_W_TDISABLE|ASL0_W_TRESET|ASL0_W_IRQENABLE);
inithscxisac(cs);
return 0;
case CARD_TEST:
/* we really don't need it for the PCMCIA Version */
return 0;
default:
/* all card drivers ignore others, so we do the same */
return 0;
}
return 0; return 0;
} }
static struct card_ops avm_a1p_ops = {
.init = avm_a1p_init,
.reset = avm_a1p_reset,
.irq_func = avm_a1p_interrupt,
};
int __devinit int __devinit
setup_avm_a1_pcmcia(struct IsdnCard *card) setup_avm_a1_pcmcia(struct IsdnCard *card)
{ {
...@@ -259,7 +258,7 @@ setup_avm_a1_pcmcia(struct IsdnCard *card) ...@@ -259,7 +258,7 @@ setup_avm_a1_pcmcia(struct IsdnCard *card)
cs->dc_hw_ops = &isac_ops; cs->dc_hw_ops = &isac_ops;
cs->bc_hw_ops = &hscx_ops; cs->bc_hw_ops = &hscx_ops;
cs->cardmsg = &AVM_card_msg; cs->cardmsg = &AVM_card_msg;
cs->irq_func = &avm_a1p_interrupt; cs->card_ops = &avm_a1p_ops;
ISACVersion(cs, "AVM A1 PCMCIA:"); ISACVersion(cs, "AVM A1 PCMCIA:");
if (HscxVersion(cs, "AVM A1 PCMCIA:")) { if (HscxVersion(cs, "AVM A1 PCMCIA:")) {
......
...@@ -175,6 +175,39 @@ WriteHDLCPnP(struct IsdnCardState *cs, int chan, u8 offset, u8 value) ...@@ -175,6 +175,39 @@ WriteHDLCPnP(struct IsdnCardState *cs, int chan, u8 offset, u8 value)
spin_unlock_irqrestore(&avm_pci_lock, flags); spin_unlock_irqrestore(&avm_pci_lock, flags);
} }
static void
hdlc_read_fifo(struct IsdnCardState *cs, int hscx, u8 *data, int len)
{
u8 idx = hscx ? AVM_HDLC_2 : AVM_HDLC_1;
int i;
if (cs->subtyp == AVM_FRITZ_PCI) {
u32 *ptr = (u32 *) data;
outl(idx, cs->hw.avm.cfg_reg + 4);
for (i = 0; i < len; i += 4) {
#ifdef __powerpc__
#ifdef CONFIG_APUS
*ptr++ = in_le32((u32 *)(cs->hw.avm.isac +_IO_BASE));
#else
*ptr++ = in_be32((u32 *)(cs->hw.avm.isac +_IO_BASE));
#endif /* CONFIG_APUS */
#else
*ptr++ = inl(cs->hw.avm.isac);
#endif /* __powerpc__ */
}
} else {
outb(idx, cs->hw.avm.cfg_reg + 4);
for (i = 0; i < len; i++) {
*data++ = inb(cs->hw.avm.isac);
}
}
}
static struct bc_hw_ops hdlc_hw_ops = {
.read_fifo = hdlc_read_fifo,
};
static inline static inline
struct BCState *Sel_BCS(struct IsdnCardState *cs, int channel) struct BCState *Sel_BCS(struct IsdnCardState *cs, int channel)
{ {
...@@ -259,52 +292,7 @@ modehdlc(struct BCState *bcs, int mode, int bc) ...@@ -259,52 +292,7 @@ modehdlc(struct BCState *bcs, int mode, int bc)
static inline void static inline void
hdlc_empty_fifo(struct BCState *bcs, int count) hdlc_empty_fifo(struct BCState *bcs, int count)
{ {
register u_int *ptr; recv_empty_fifo_b(bcs, count);
u8 *p;
u8 idx = bcs->channel ? AVM_HDLC_2 : AVM_HDLC_1;
int cnt=0;
struct IsdnCardState *cs = bcs->cs;
if ((cs->debug & L1_DEB_HSCX) && !(cs->debug & L1_DEB_HSCX_FIFO))
debugl1(cs, "hdlc_empty_fifo %d", count);
if (bcs->hw.hdlc.rcvidx + count > HSCX_BUFMAX) {
if (cs->debug & L1_DEB_WARN)
debugl1(cs, "hdlc_empty_fifo: incoming packet too large");
return;
}
ptr = (u_int *) p = bcs->hw.hdlc.rcvbuf + bcs->hw.hdlc.rcvidx;
bcs->hw.hdlc.rcvidx += count;
if (cs->subtyp == AVM_FRITZ_PCI) {
outl(idx, cs->hw.avm.cfg_reg + 4);
while (cnt < count) {
#ifdef __powerpc__
#ifdef CONFIG_APUS
*ptr++ = in_le32((unsigned *)(cs->hw.avm.isac +_IO_BASE));
#else
*ptr++ = in_be32((unsigned *)(cs->hw.avm.isac +_IO_BASE));
#endif /* CONFIG_APUS */
#else
*ptr++ = inl(cs->hw.avm.isac);
#endif /* __powerpc__ */
cnt += 4;
}
} else {
outb(idx, cs->hw.avm.cfg_reg + 4);
while (cnt < count) {
*p++ = inb(cs->hw.avm.isac);
cnt++;
}
}
if (cs->debug & L1_DEB_HSCX_FIFO) {
char *t = bcs->blog;
if (cs->subtyp == AVM_FRITZ_PNP)
p = (u8 *) ptr;
t += sprintf(t, "hdlc_empty_fifo %c cnt %d",
bcs->channel ? 'B' : 'A', count);
QuickHex(t, p, count);
debugl1(cs, bcs->blog);
}
} }
static void static void
...@@ -360,15 +348,10 @@ reset_xmit(struct BCState *bcs) ...@@ -360,15 +348,10 @@ reset_xmit(struct BCState *bcs)
hdlc_fill_fifo(bcs); hdlc_fill_fifo(bcs);
} }
static struct bc_l1_ops hdlc_l1_ops = {
.fill_fifo = hdlc_fill_fifo,
};
static inline void static inline void
HDLC_irq(struct BCState *bcs, u_int stat) HDLC_irq(struct BCState *bcs, u_int stat)
{ {
int len; int len;
struct sk_buff *skb;
if (bcs->cs->debug & L1_DEB_HSCX) if (bcs->cs->debug & L1_DEB_HSCX)
debugl1(bcs->cs, "ch%d stat %#x", bcs->channel, stat); debugl1(bcs->cs, "ch%d stat %#x", bcs->channel, stat);
...@@ -384,7 +367,7 @@ HDLC_irq(struct BCState *bcs, u_int stat) ...@@ -384,7 +367,7 @@ HDLC_irq(struct BCState *bcs, u_int stat)
write_ctrl(bcs, 1); write_ctrl(bcs, 1);
bcs->hw.hdlc.ctrl.sr.cmd &= ~HDLC_CMD_RRS; bcs->hw.hdlc.ctrl.sr.cmd &= ~HDLC_CMD_RRS;
write_ctrl(bcs, 1); write_ctrl(bcs, 1);
bcs->hw.hdlc.rcvidx = 0; bcs->rcvidx = 0;
} else { } else {
if (!(len = (stat & HDLC_STAT_RML_MASK)>>8)) if (!(len = (stat & HDLC_STAT_RML_MASK)>>8))
len = 32; len = 32;
...@@ -392,21 +375,13 @@ HDLC_irq(struct BCState *bcs, u_int stat) ...@@ -392,21 +375,13 @@ HDLC_irq(struct BCState *bcs, u_int stat)
if ((stat & HDLC_STAT_RME) || (bcs->mode == L1_MODE_TRANS)) { if ((stat & HDLC_STAT_RME) || (bcs->mode == L1_MODE_TRANS)) {
if (((stat & HDLC_STAT_CRCVFRRAB)==HDLC_STAT_CRCVFR) || if (((stat & HDLC_STAT_CRCVFRRAB)==HDLC_STAT_CRCVFR) ||
(bcs->mode == L1_MODE_TRANS)) { (bcs->mode == L1_MODE_TRANS)) {
if (!(skb = dev_alloc_skb(bcs->hw.hdlc.rcvidx))) recv_rme_b(bcs);
printk(KERN_WARNING "HDLC: receive out of memory\n");
else {
memcpy(skb_put(skb, bcs->hw.hdlc.rcvidx),
bcs->hw.hdlc.rcvbuf, bcs->hw.hdlc.rcvidx);
skb_queue_tail(&bcs->rqueue, skb);
}
bcs->hw.hdlc.rcvidx = 0;
sched_b_event(bcs, B_RCVBUFREADY);
} else { } else {
if (bcs->cs->debug & L1_DEB_HSCX) if (bcs->cs->debug & L1_DEB_HSCX)
debugl1(bcs->cs, "invalid frame"); debugl1(bcs->cs, "invalid frame");
else else
debugl1(bcs->cs, "ch%d invalid frame %#x", bcs->channel, stat); debugl1(bcs->cs, "ch%d invalid frame %#x", bcs->channel, stat);
bcs->hw.hdlc.rcvidx = 0; bcs->rcvidx = 0;
} }
} }
} }
...@@ -492,57 +467,20 @@ void ...@@ -492,57 +467,20 @@ void
close_hdlcstate(struct BCState *bcs) close_hdlcstate(struct BCState *bcs)
{ {
modehdlc(bcs, 0, 0); modehdlc(bcs, 0, 0);
if (test_and_clear_bit(BC_FLG_INIT, &bcs->Flag)) { bc_close(bcs);
if (bcs->hw.hdlc.rcvbuf) {
kfree(bcs->hw.hdlc.rcvbuf);
bcs->hw.hdlc.rcvbuf = NULL;
}
if (bcs->blog) {
kfree(bcs->blog);
bcs->blog = NULL;
}
skb_queue_purge(&bcs->rqueue);
skb_queue_purge(&bcs->squeue);
if (bcs->tx_skb) {
dev_kfree_skb_any(bcs->tx_skb);
bcs->tx_skb = NULL;
test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag);
}
}
} }
int int
open_hdlcstate(struct IsdnCardState *cs, struct BCState *bcs) open_hdlcstate(struct IsdnCardState *cs, struct BCState *bcs)
{ {
if (!test_and_set_bit(BC_FLG_INIT, &bcs->Flag)) { return bc_open(bcs);
if (!(bcs->hw.hdlc.rcvbuf = kmalloc(HSCX_BUFMAX, GFP_ATOMIC))) {
printk(KERN_WARNING
"HiSax: No memory for hdlc.rcvbuf\n");
return (1);
}
if (!(bcs->blog = kmalloc(MAX_BLOG_SPACE, GFP_ATOMIC))) {
printk(KERN_WARNING
"HiSax: No memory for bcs->blog\n");
test_and_clear_bit(BC_FLG_INIT, &bcs->Flag);
kfree(bcs->hw.hdlc.rcvbuf);
bcs->hw.hdlc.rcvbuf = NULL;
return (2);
}
skb_queue_head_init(&bcs->rqueue);
skb_queue_head_init(&bcs->squeue);
}
bcs->tx_skb = NULL;
test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag);
bcs->event = 0;
bcs->hw.hdlc.rcvidx = 0;
bcs->tx_cnt = 0;
return (0);
} }
int int
setstack_hdlc(struct PStack *st, struct BCState *bcs) setstack_hdlc(struct PStack *st, struct BCState *bcs)
{ {
bcs->channel = st->l1.bc; bcs->channel = st->l1.bc;
bcs->unit = bcs->channel;
if (open_hdlcstate(st->l1.hardware, bcs)) if (open_hdlcstate(st->l1.hardware, bcs))
return (-1); return (-1);
st->l1.bcs = bcs; st->l1.bcs = bcs;
...@@ -553,6 +491,12 @@ setstack_hdlc(struct PStack *st, struct BCState *bcs) ...@@ -553,6 +491,12 @@ setstack_hdlc(struct PStack *st, struct BCState *bcs)
return (0); return (0);
} }
static struct bc_l1_ops hdlc_l1_ops = {
.fill_fifo = hdlc_fill_fifo,
.open = setstack_hdlc,
.close = close_hdlcstate,
};
void __init void __init
inithdlc(struct IsdnCardState *cs) inithdlc(struct IsdnCardState *cs)
{ {
...@@ -582,10 +526,6 @@ inithdlc(struct IsdnCardState *cs) ...@@ -582,10 +526,6 @@ inithdlc(struct IsdnCardState *cs)
debugl1(cs, "HDLC 2 VIN %x", val); debugl1(cs, "HDLC 2 VIN %x", val);
} }
cs->bcs[0].BC_SetStack = setstack_hdlc;
cs->bcs[1].BC_SetStack = setstack_hdlc;
cs->bcs[0].BC_Close = close_hdlcstate;
cs->bcs[1].BC_Close = close_hdlcstate;
modehdlc(cs->bcs, -1, 0); modehdlc(cs->bcs, -1, 0);
modehdlc(cs->bcs + 1, -1, 1); modehdlc(cs->bcs + 1, -1, 1);
} }
...@@ -616,8 +556,14 @@ avm_pcipnp_interrupt(int intno, void *dev_id, struct pt_regs *regs) ...@@ -616,8 +556,14 @@ avm_pcipnp_interrupt(int intno, void *dev_id, struct pt_regs *regs)
WriteISAC(cs, ISAC_MASK, 0x0); WriteISAC(cs, ISAC_MASK, 0x0);
} }
static void static int
reset_avmpcipnp(struct IsdnCardState *cs) AVM_card_msg(struct IsdnCardState *cs, int mt, void *arg)
{
return(0);
}
static int
avm_pcipnp_reset(struct IsdnCardState *cs)
{ {
printk(KERN_INFO "AVM PCI/PnP: reset\n"); printk(KERN_INFO "AVM PCI/PnP: reset\n");
outb(AVM_STATUS0_RESET | AVM_STATUS0_DIS_TIMER, cs->hw.avm.cfg_reg + 2); outb(AVM_STATUS0_RESET | AVM_STATUS0_DIS_TIMER, cs->hw.avm.cfg_reg + 2);
...@@ -628,33 +574,34 @@ reset_avmpcipnp(struct IsdnCardState *cs) ...@@ -628,33 +574,34 @@ reset_avmpcipnp(struct IsdnCardState *cs)
set_current_state(TASK_UNINTERRUPTIBLE); set_current_state(TASK_UNINTERRUPTIBLE);
schedule_timeout((10*HZ)/1000); /* Timeout 10ms */ schedule_timeout((10*HZ)/1000); /* Timeout 10ms */
printk(KERN_INFO "AVM PCI/PnP: S1 %x\n", inb(cs->hw.avm.cfg_reg + 3)); printk(KERN_INFO "AVM PCI/PnP: S1 %x\n", inb(cs->hw.avm.cfg_reg + 3));
return 0;
} }
static int static void
AVM_card_msg(struct IsdnCardState *cs, int mt, void *arg) avm_pcipnp_init(struct IsdnCardState *cs)
{ {
switch (mt) {
case CARD_RESET:
reset_avmpcipnp(cs);
return(0);
case CARD_RELEASE:
outb(0, cs->hw.avm.cfg_reg + 2);
release_region(cs->hw.avm.cfg_reg, 32);
return(0);
case CARD_INIT:
initisac(cs); initisac(cs);
inithdlc(cs); inithdlc(cs);
outb(AVM_STATUS0_DIS_TIMER | AVM_STATUS0_RES_TIMER, outb(AVM_STATUS0_DIS_TIMER | AVM_STATUS0_RES_TIMER,
cs->hw.avm.cfg_reg + 2); cs->hw.avm.cfg_reg + 2);
outb(AVM_STATUS0_DIS_TIMER | AVM_STATUS0_RES_TIMER | outb(AVM_STATUS0_DIS_TIMER | AVM_STATUS0_RES_TIMER |
AVM_STATUS0_ENA_IRQ, cs->hw.avm.cfg_reg + 2); AVM_STATUS0_ENA_IRQ, cs->hw.avm.cfg_reg + 2);
return(0);
case CARD_TEST:
return(0);
}
return(0);
} }
static void
avm_pcipnp_release(struct IsdnCardState *cs)
{
outb(0, cs->hw.avm.cfg_reg + 2);
release_region(cs->hw.avm.cfg_reg, 32);
}
static struct card_ops avm_pci_ops = {
.init = avm_pcipnp_init,
.reset = avm_pcipnp_reset,
.release = avm_pcipnp_release,
.irq_func = avm_pcipnp_interrupt,
};
static struct pci_dev *dev_avm __initdata = NULL; static struct pci_dev *dev_avm __initdata = NULL;
#ifdef __ISAPNP__ #ifdef __ISAPNP__
static struct pci_bus *bus_avm __initdata = NULL; static struct pci_bus *bus_avm __initdata = NULL;
...@@ -766,7 +713,7 @@ setup_avm_pcipnp(struct IsdnCard *card) ...@@ -766,7 +713,7 @@ setup_avm_pcipnp(struct IsdnCard *card)
val = inb(cs->hw.avm.cfg_reg); val = inb(cs->hw.avm.cfg_reg);
ver = inb(cs->hw.avm.cfg_reg + 1); ver = inb(cs->hw.avm.cfg_reg + 1);
printk(KERN_INFO "AVM PnP: Class %X Rev %d\n", val, ver); printk(KERN_INFO "AVM PnP: Class %X Rev %d\n", val, ver);
reset_avmpcipnp(cs); avm_pcipnp_reset(cs);
break; break;
} }
printk(KERN_INFO "HiSax: %s config irq:%d base:0x%X\n", printk(KERN_INFO "HiSax: %s config irq:%d base:0x%X\n",
...@@ -774,9 +721,10 @@ setup_avm_pcipnp(struct IsdnCard *card) ...@@ -774,9 +721,10 @@ setup_avm_pcipnp(struct IsdnCard *card)
cs->irq, cs->hw.avm.cfg_reg); cs->irq, cs->hw.avm.cfg_reg);
cs->dc_hw_ops = &isac_ops; cs->dc_hw_ops = &isac_ops;
cs->bc_hw_ops = &hdlc_hw_ops;
cs->bc_l1_ops = &hdlc_l1_ops; cs->bc_l1_ops = &hdlc_l1_ops;
cs->cardmsg = &AVM_card_msg; cs->cardmsg = &AVM_card_msg;
cs->irq_func = &avm_pcipnp_interrupt; cs->card_ops = &avm_pci_ops;
ISACVersion(cs, (cs->subtyp == AVM_FRITZ_PCI) ? "AVM PCI:" : "AVM PnP:"); ISACVersion(cs, (cs->subtyp == AVM_FRITZ_PCI) ? "AVM PCI:" : "AVM PnP:");
return (1); return (1);
} }
...@@ -233,30 +233,42 @@ reset_bkm(struct IsdnCardState *cs) ...@@ -233,30 +233,42 @@ reset_bkm(struct IsdnCardState *cs)
static int static int
BKM_card_msg(struct IsdnCardState *cs, int mt, void *arg) BKM_card_msg(struct IsdnCardState *cs, int mt, void *arg)
{ {
switch (mt) { return (0);
case CARD_RESET: }
static void
bkm_a4t_init(struct IsdnCardState *cs)
{
initisac(cs);
initjade(cs);
/* Enable ints */
enable_bkm_int(cs, 1);
}
static int
bkm_a4t_reset(struct IsdnCardState *cs)
{
/* Disable ints */ /* Disable ints */
enable_bkm_int(cs, 0); enable_bkm_int(cs, 0);
reset_bkm(cs); reset_bkm(cs);
return (0); return 0;
case CARD_RELEASE: }
/* Sanity */
static void
bkm_a4t_release(struct IsdnCardState *cs)
{
enable_bkm_int(cs, 0); enable_bkm_int(cs, 0);
reset_bkm(cs); reset_bkm(cs);
release_io_bkm(cs); release_io_bkm(cs);
return (0);
case CARD_INIT:
initisac(cs);
initjade(cs);
/* Enable ints */
enable_bkm_int(cs, 1);
return (0);
case CARD_TEST:
return (0);
}
return (0);
} }
static struct card_ops bkm_a4t_ops = {
.init = bkm_a4t_init,
.reset = bkm_a4t_reset,
.release = bkm_a4t_release,
.irq_func = bkm_interrupt,
};
static struct pci_dev *dev_a4t __initdata = NULL; static struct pci_dev *dev_a4t __initdata = NULL;
int __init int __init
...@@ -335,8 +347,8 @@ setup_bkm_a4t(struct IsdnCard *card) ...@@ -335,8 +347,8 @@ setup_bkm_a4t(struct IsdnCard *card)
cs->dc_hw_ops = &isac_ops; cs->dc_hw_ops = &isac_ops;
cs->bc_hw_ops = &jade_ops; cs->bc_hw_ops = &jade_ops;
cs->cardmsg = &BKM_card_msg; cs->cardmsg = &BKM_card_msg;
cs->irq_func = &bkm_interrupt;
cs->irq_flags |= SA_SHIRQ; cs->irq_flags |= SA_SHIRQ;
cs->card_ops = &bkm_a4t_ops;
ISACVersion(cs, "Telekom A4T:"); ISACVersion(cs, "Telekom A4T:");
/* Jade version */ /* Jade version */
JadeVersion(cs, "Telekom A4T:"); JadeVersion(cs, "Telekom A4T:");
......
...@@ -42,7 +42,7 @@ static const char *sct_quadro_subtypes[] = ...@@ -42,7 +42,7 @@ static const char *sct_quadro_subtypes[] =
#define wordin(addr) inw(addr) #define wordin(addr) inw(addr)
static inline u8 static inline u8
readreg(struct IsdnCardState *cs, u8 off) ipac_read(struct IsdnCardState *cs, u8 off)
{ {
u8 ret; u8 ret;
unsigned long flags; unsigned long flags;
...@@ -51,13 +51,14 @@ readreg(struct IsdnCardState *cs, u8 off) ...@@ -51,13 +51,14 @@ readreg(struct IsdnCardState *cs, u8 off)
wordout(cs->hw.ax.base, off); wordout(cs->hw.ax.base, off);
ret = wordin(cs->hw.ax.data_adr) & 0xFF; ret = wordin(cs->hw.ax.data_adr) & 0xFF;
spin_unlock_irqrestore(&bkm_a8_lock, flags); spin_unlock_irqrestore(&bkm_a8_lock, flags);
return (ret); return ret;
} }
static inline void static inline void
writereg(struct IsdnCardState *cs, u8 off, u8 data) ipac_write(struct IsdnCardState *cs, u8 off, u8 data)
{ {
unsigned long flags; unsigned long flags;
spin_lock_irqsave(&bkm_a8_lock, flags); spin_lock_irqsave(&bkm_a8_lock, flags);
wordout(cs->hw.ax.base, off); wordout(cs->hw.ax.base, off);
wordout(cs->hw.ax.data_adr, data); wordout(cs->hw.ax.data_adr, data);
...@@ -65,7 +66,7 @@ writereg(struct IsdnCardState *cs, u8 off, u8 data) ...@@ -65,7 +66,7 @@ writereg(struct IsdnCardState *cs, u8 off, u8 data)
} }
static inline void static inline void
readfifo(struct IsdnCardState *cs, u8 off, u8 *data, int size) ipac_readfifo(struct IsdnCardState *cs, u8 off, u8 *data, int size)
{ {
int i; int i;
...@@ -75,7 +76,7 @@ readfifo(struct IsdnCardState *cs, u8 off, u8 *data, int size) ...@@ -75,7 +76,7 @@ readfifo(struct IsdnCardState *cs, u8 off, u8 *data, int size)
} }
static inline void static inline void
writefifo(struct IsdnCardState *cs, u8 off, u8 *data, int size) ipac_writefifo(struct IsdnCardState *cs, u8 off, u8 *data, int size)
{ {
int i; int i;
...@@ -84,127 +85,19 @@ writefifo(struct IsdnCardState *cs, u8 off, u8 *data, int size) ...@@ -84,127 +85,19 @@ writefifo(struct IsdnCardState *cs, u8 off, u8 *data, int size)
wordout(cs->hw.ax.data_adr, data[i]); wordout(cs->hw.ax.data_adr, data[i]);
} }
static u8 /* This will generate ipac_dc_ops and ipac_bc_ops using the functions
ipac_dc_read(struct IsdnCardState *cs, u8 offset) * above */
{
return readreg(cs, offset | 0x80);
}
static void
ipac_dc_write(struct IsdnCardState *cs, u8 offset, u8 value)
{
writereg(cs, offset | 0x80, value);
}
static void
ipac_dc_read_fifo(struct IsdnCardState *cs, u8 * data, int size)
{
readfifo(cs, 0x80, data, size);
}
static void
ipac_dc_write_fifo(struct IsdnCardState *cs, u8 * data, int size)
{
writefifo(cs, 0x80, data, size);
}
static struct dc_hw_ops ipac_dc_ops = {
.read_reg = ipac_dc_read,
.write_reg = ipac_dc_write,
.read_fifo = ipac_dc_read_fifo,
.write_fifo = ipac_dc_write_fifo,
};
static u8
hscx_read(struct IsdnCardState *cs, int hscx, u8 offset)
{
return readreg(cs, offset + (hscx ? 0x40 : 0));
}
static void
hscx_write(struct IsdnCardState *cs, int hscx, u8 offset, u8 value)
{
writereg(cs, offset + (hscx ? 0x40 : 0), value);
}
static void BUILD_IPAC_OPS(ipac);
hscx_read_fifo(struct IsdnCardState *cs, int hscx, u8 *data, int size)
{
readfifo(cs, hscx ? 0x40 : 0, data, size);
}
static void
hscx_write_fifo(struct IsdnCardState *cs, int hscx, u8 *data, int size)
{
writefifo(cs, hscx ? 0x40 : 0, data, size);
}
static struct bc_hw_ops hscx_ops = {
.read_reg = hscx_read,
.write_reg = hscx_write,
.read_fifo = hscx_read_fifo,
.write_fifo = hscx_write_fifo,
};
/* Set the specific ipac to active */ /* Set the specific ipac to active */
static void static void
set_ipac_active(struct IsdnCardState *cs, u_int active) set_ipac_active(struct IsdnCardState *cs, u_int active)
{ {
/* set irq mask */ /* set irq mask */
writereg(cs, IPAC_MASK, active ? 0xc0 : 0xff); ipac_write(cs, IPAC_MASK, active ? 0xc0 : 0xff);
} }
static void
bkm_interrupt_ipac(int intno, void *dev_id, struct pt_regs *regs)
{
struct IsdnCardState *cs = dev_id;
u8 ista, val, icnt = 5;
spin_lock(&cs->lock);
ista = readreg(cs, IPAC_ISTA);
if (!(ista & 0x3f)) /* not this IPAC */
goto unlock;
Start_IPAC:
if (cs->debug & L1_DEB_IPAC)
debugl1(cs, "IPAC ISTA %02X", ista);
if (ista & 0x0f) {
val = hscx_read(cs, 1, HSCX_ISTA);
if (ista & 0x01)
val |= 0x01;
if (ista & 0x04)
val |= 0x02;
if (ista & 0x08)
val |= 0x04;
if (val) {
hscx_int_main(cs, val);
}
}
if (ista & 0x20) {
val = ipac_dc_read(cs, ISAC_ISTA) & 0xfe;
if (val) {
isac_interrupt(cs, val);
}
}
if (ista & 0x10) {
val = 0x01;
isac_interrupt(cs, val);
}
ista = readreg(cs, IPAC_ISTA);
if ((ista & 0x3f) && icnt) {
icnt--;
goto Start_IPAC;
}
if (!icnt)
printk(KERN_WARNING "HiSax: %s (%s) IRQ LOOP\n",
CardType[cs->typ],
sct_quadro_subtypes[cs->subtyp]);
writereg(cs, IPAC_MASK, 0xFF);
writereg(cs, IPAC_MASK, 0xC0);
unlock:
spin_unlock(&cs->lock);
}
void void
release_io_sct_quadro(struct IsdnCardState *cs) release_io_sct_quadro(struct IsdnCardState *cs)
{ {
...@@ -241,32 +134,44 @@ reset_bkm(struct IsdnCardState *cs) ...@@ -241,32 +134,44 @@ reset_bkm(struct IsdnCardState *cs)
static int static int
BKM_card_msg(struct IsdnCardState *cs, int mt, void *arg) BKM_card_msg(struct IsdnCardState *cs, int mt, void *arg)
{ {
switch (mt) { return (0);
case CARD_RESET: }
static void
bkm_a8_init(struct IsdnCardState *cs)
{
cs->debug |= L1_DEB_IPAC;
set_ipac_active(cs, 1);
ipac_init(cs);
/* Enable ints */
enable_bkm_int(cs, 1);
}
static int
bkm_a8_reset(struct IsdnCardState *cs)
{
/* Disable ints */ /* Disable ints */
set_ipac_active(cs, 0); set_ipac_active(cs, 0);
enable_bkm_int(cs, 0); enable_bkm_int(cs, 0);
reset_bkm(cs); reset_bkm(cs);
return (0); return 0;
case CARD_RELEASE: }
/* Sanity */
static void
bkm_a8_release(struct IsdnCardState *cs)
{
set_ipac_active(cs, 0); set_ipac_active(cs, 0);
enable_bkm_int(cs, 0); enable_bkm_int(cs, 0);
release_io_sct_quadro(cs); release_io_sct_quadro(cs);
return (0);
case CARD_INIT:
cs->debug |= L1_DEB_IPAC;
set_ipac_active(cs, 1);
inithscxisac(cs);
/* Enable ints */
enable_bkm_int(cs, 1);
return (0);
case CARD_TEST:
return (0);
}
return (0);
} }
static struct card_ops bkm_a8_ops = {
.init = bkm_a8_init,
.reset = bkm_a8_reset,
.release = bkm_a8_release,
.irq_func = ipac_irq,
};
int __init int __init
sct_alloc_io(u_int adr, u_int len) sct_alloc_io(u_int adr, u_int len)
{ {
...@@ -414,7 +319,7 @@ setup_sct_quadro(struct IsdnCard *card) ...@@ -414,7 +319,7 @@ setup_sct_quadro(struct IsdnCard *card)
break; break;
} }
cs->hw.ax.data_adr = cs->hw.ax.base + 4; cs->hw.ax.data_adr = cs->hw.ax.base + 4;
writereg(cs, IPAC_MASK, 0xFF); ipac_write(cs, IPAC_MASK, 0xFF);
printk(KERN_INFO "HiSax: %s (%s) configured at 0x%.4lX, 0x%.4lX, 0x%.4lX and IRQ %d\n", printk(KERN_INFO "HiSax: %s (%s) configured at 0x%.4lX, 0x%.4lX, 0x%.4lX and IRQ %d\n",
CardType[card->typ], CardType[card->typ],
...@@ -424,17 +329,15 @@ setup_sct_quadro(struct IsdnCard *card) ...@@ -424,17 +329,15 @@ setup_sct_quadro(struct IsdnCard *card)
cs->hw.ax.data_adr, cs->hw.ax.data_adr,
cs->irq); cs->irq);
test_and_set_bit(HW_IPAC, &cs->HW_Flags);
cs->dc_hw_ops = &ipac_dc_ops; cs->dc_hw_ops = &ipac_dc_ops;
cs->bc_hw_ops = &hscx_ops; cs->bc_hw_ops = &ipac_bc_ops;
cs->cardmsg = &BKM_card_msg; cs->cardmsg = &BKM_card_msg;
cs->irq_func = &bkm_interrupt_ipac; cs->card_ops = &bkm_a8_ops;
printk(KERN_INFO "HiSax: %s (%s): IPAC Version %d\n", printk(KERN_INFO "HiSax: %s (%s): IPAC Version %d\n",
CardType[card->typ], CardType[card->typ],
sct_quadro_subtypes[cs->subtyp], sct_quadro_subtypes[cs->subtyp],
readreg(cs, IPAC_ID)); ipac_read(cs, IPAC_ID));
return (1); return (1);
#else #else
printk(KERN_ERR "HiSax: bkm_a8 only supported on PCI Systems\n"); printk(KERN_ERR "HiSax: bkm_a8 only supported on PCI Systems\n");
......
...@@ -853,10 +853,11 @@ CallcFree(void) ...@@ -853,10 +853,11 @@ CallcFree(void)
static void static void
release_b_st(struct Channel *chanp) release_b_st(struct Channel *chanp)
{ {
struct IsdnCardState *cs = chanp->cs;
struct PStack *st = chanp->b_st; struct PStack *st = chanp->b_st;
if(test_and_clear_bit(FLG_START_B, &chanp->Flags)) { if(test_and_clear_bit(FLG_START_B, &chanp->Flags)) {
chanp->bcs->BC_Close(chanp->bcs); cs->bc_l1_ops->close(chanp->bcs);
switch (chanp->l2_active_protocol) { switch (chanp->l2_active_protocol) {
case (ISDN_PROTO_L2_X75I): case (ISDN_PROTO_L2_X75I):
releasestack_isdnl2(st); releasestack_isdnl2(st);
...@@ -1297,7 +1298,7 @@ init_b_st(struct Channel *chanp, int incoming) ...@@ -1297,7 +1298,7 @@ init_b_st(struct Channel *chanp, int incoming)
break; break;
} }
chanp->bcs->conmsg = NULL; chanp->bcs->conmsg = NULL;
if (chanp->bcs->BC_SetStack(st, chanp->bcs)) if (cs->bc_l1_ops->open(st, chanp->bcs))
return (-1); return (-1);
st->l2.flag = 0; st->l2.flag = 0;
test_and_set_bit(FLG_LAPB, &st->l2.flag); test_and_set_bit(FLG_LAPB, &st->l2.flag);
...@@ -1457,12 +1458,8 @@ lli_got_fac_req(struct Channel *chanp, capi_msg *cm) { ...@@ -1457,12 +1458,8 @@ lli_got_fac_req(struct Channel *chanp, capi_msg *cm) {
void void
lli_got_manufacturer(struct Channel *chanp, struct IsdnCardState *cs, capi_msg *cm) { lli_got_manufacturer(struct Channel *chanp, struct IsdnCardState *cs, capi_msg *cm) {
if ((cs->typ == ISDN_CTYPE_ELSA) || (cs->typ == ISDN_CTYPE_ELSA_PNP) || if (cs->card_ops->aux_ind)
(cs->typ == ISDN_CTYPE_ELSA_PCI)) { cs->card_ops->aux_ind(cs, cm->para);
if (cs->hw.elsa.MFlag) {
cs->cardmsg(cs, CARD_AUX_IND, cm->para);
}
}
} }
......
...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
#include <linux/kernel_stat.h> #include <linux/kernel_stat.h>
#include <linux/workqueue.h> #include <linux/workqueue.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include "isdnl1.h"
#define HISAX_STATUS_BUFSIZE 4096 #define HISAX_STATUS_BUFSIZE 4096
#define INCLUDE_INLINE_FUNCS #define INCLUDE_INLINE_FUNCS
...@@ -825,9 +826,9 @@ static void closecard(int cardnr) ...@@ -825,9 +826,9 @@ static void closecard(int cardnr)
{ {
struct IsdnCardState *csta = cards[cardnr].cs; struct IsdnCardState *csta = cards[cardnr].cs;
if (csta->bcs->BC_Close != NULL) { if (csta->bc_l1_ops->close) {
csta->bcs->BC_Close(csta->bcs + 1); csta->bc_l1_ops->close(csta->bcs + 1);
csta->bcs->BC_Close(csta->bcs); csta->bc_l1_ops->close(csta->bcs);
} }
skb_queue_purge(&csta->rq); skb_queue_purge(&csta->rq);
...@@ -840,11 +841,11 @@ static void closecard(int cardnr) ...@@ -840,11 +841,11 @@ static void closecard(int cardnr)
dev_kfree_skb(csta->tx_skb); dev_kfree_skb(csta->tx_skb);
csta->tx_skb = NULL; csta->tx_skb = NULL;
} }
if (csta->DC_Close != NULL) { if (csta->dc_l1_ops->close)
csta->DC_Close(csta); csta->dc_l1_ops->close(csta);
}
if (csta->cardmsg) if (csta->card_ops->release)
csta->cardmsg(csta, CARD_RELEASE, NULL); csta->card_ops->release(csta);
if (csta->dbusytimer.function != NULL) // FIXME? if (csta->dbusytimer.function != NULL) // FIXME?
del_timer(&csta->dbusytimer); del_timer(&csta->dbusytimer);
ll_unload(csta); ll_unload(csta);
...@@ -854,19 +855,18 @@ static int __devinit init_card(struct IsdnCardState *cs) ...@@ -854,19 +855,18 @@ static int __devinit init_card(struct IsdnCardState *cs)
{ {
int irq_cnt, cnt = 3; int irq_cnt, cnt = 3;
if (!cs->irq) cs->card_ops->init(cs);
return cs->cardmsg(cs, CARD_INIT, NULL);
irq_cnt = kstat_irqs(cs->irq); irq_cnt = kstat_irqs(cs->irq);
printk(KERN_INFO "%s: IRQ %d count %d\n", CardType[cs->typ], printk(KERN_INFO "%s: IRQ %d count %d\n", CardType[cs->typ],
cs->irq, irq_cnt); cs->irq, irq_cnt);
if (request_irq(cs->irq, cs->irq_func, cs->irq_flags, "HiSax", cs)) { if (request_irq(cs->irq, cs->card_ops->irq_func, cs->irq_flags, "HiSax", cs)) {
printk(KERN_WARNING "HiSax: couldn't get interrupt %d\n", printk(KERN_WARNING "HiSax: couldn't get interrupt %d\n",
cs->irq); cs->irq);
return 1; return 1;
} }
while (cnt) { while (cnt) {
cs->cardmsg(cs, CARD_INIT, NULL); cs->card_ops->init(cs);
set_current_state(TASK_UNINTERRUPTIBLE); set_current_state(TASK_UNINTERRUPTIBLE);
/* Timeout 10ms */ /* Timeout 10ms */
schedule_timeout((10 * HZ) / 1000); schedule_timeout((10 * HZ) / 1000);
...@@ -880,11 +880,13 @@ static int __devinit init_card(struct IsdnCardState *cs) ...@@ -880,11 +880,13 @@ static int __devinit init_card(struct IsdnCardState *cs)
free_irq(cs->irq, cs); free_irq(cs->irq, cs);
return 2; return 2;
} else { } else {
cs->cardmsg(cs, CARD_RESET, NULL); if (cs->card_ops->reset)
cs->card_ops->reset(cs);
cnt--; cnt--;
} }
} else { } else {
cs->cardmsg(cs, CARD_TEST, NULL); if (cs->card_ops->test)
cs->card_ops->test(cs);
return 0; return 0;
} }
} }
...@@ -1747,6 +1749,10 @@ static void hisax_bc_close(struct BCState *bcs); ...@@ -1747,6 +1749,10 @@ static void hisax_bc_close(struct BCState *bcs);
static void hisax_bh(void *data); static void hisax_bh(void *data);
static void EChannel_proc_rcv(struct hisax_d_if *d_if); static void EChannel_proc_rcv(struct hisax_d_if *d_if);
static struct dc_l1_ops hisax_l1_ops = {
.bh_func = hisax_bh,
};
int hisax_register(struct hisax_d_if *hisax_d_if, struct hisax_b_if *b_if[], int hisax_register(struct hisax_d_if *hisax_d_if, struct hisax_b_if *b_if[],
char *name, int protocol) char *name, int protocol)
{ {
...@@ -1777,12 +1783,12 @@ int hisax_register(struct hisax_d_if *hisax_d_if, struct hisax_b_if *b_if[], ...@@ -1777,12 +1783,12 @@ int hisax_register(struct hisax_d_if *hisax_d_if, struct hisax_b_if *b_if[],
cs->hw.hisax_d_if = hisax_d_if; cs->hw.hisax_d_if = hisax_d_if;
cs->cardmsg = hisax_cardmsg; cs->cardmsg = hisax_cardmsg;
cs->iif.owner = hisax_d_if->owner; // FIXME should be done before registering cs->iif.owner = hisax_d_if->owner; // FIXME should be done before registering
INIT_WORK(&cs->work, hisax_bh, cs); dc_l1_init(cs, &hisax_l1_ops);
cs->channel[0].d_st->l1.l2l1 = hisax_d_l2l1; cs->channel[0].d_st->l1.l2l1 = hisax_d_l2l1;
for (i = 0; i < 2; i++) { cs->bc_l1_ops->open = hisax_bc_setstack;
cs->bcs[i].BC_SetStack = hisax_bc_setstack; cs->bc_l1_ops->close = hisax_bc_close;
cs->bcs[i].BC_Close = hisax_bc_close;
for (i = 0; i < 2; i++) {
b_if[i]->ifc.l1l2 = hisax_b_l1l2; b_if[i]->ifc.l1l2 = hisax_b_l1l2;
hisax_d_if->b_if[i] = b_if[i]; hisax_d_if->b_if[i] = b_if[i];
......
This diff is collapsed.
This diff is collapsed.
...@@ -375,11 +375,6 @@ static inline void transmit_chars(struct IsdnCardState *cs, int *intr_done) ...@@ -375,11 +375,6 @@ static inline void transmit_chars(struct IsdnCardState *cs, int *intr_done)
} }
} }
static struct bc_l1_ops modem_l1_ops = {
.fill_fifo = modem_fill,
};
static void rs_interrupt_elsa(int irq, struct IsdnCardState *cs) static void rs_interrupt_elsa(int irq, struct IsdnCardState *cs)
{ {
int status, iir, msr; int status, iir, msr;
...@@ -424,10 +419,10 @@ close_elsastate(struct BCState *bcs) ...@@ -424,10 +419,10 @@ close_elsastate(struct BCState *bcs)
{ {
modehscx(bcs, 0, bcs->channel); modehscx(bcs, 0, bcs->channel);
if (test_and_clear_bit(BC_FLG_INIT, &bcs->Flag)) { if (test_and_clear_bit(BC_FLG_INIT, &bcs->Flag)) {
if (bcs->hw.hscx.rcvbuf) { if (bcs->rcvbuf) {
if (bcs->mode != L1_MODE_MODEM) if (bcs->mode != L1_MODE_MODEM)
kfree(bcs->hw.hscx.rcvbuf); kfree(bcs->rcvbuf);
bcs->hw.hscx.rcvbuf = NULL; bcs->rcvbuf = NULL;
} }
skb_queue_purge(&bcs->rqueue); skb_queue_purge(&bcs->rqueue);
skb_queue_purge(&bcs->squeue); skb_queue_purge(&bcs->squeue);
...@@ -597,23 +592,23 @@ setstack_elsa(struct PStack *st, struct BCState *bcs) ...@@ -597,23 +592,23 @@ setstack_elsa(struct PStack *st, struct BCState *bcs)
if (open_hscxstate(st->l1.hardware, bcs)) if (open_hscxstate(st->l1.hardware, bcs))
return (-1); return (-1);
st->l1.l2l1 = hscx_l2l1; st->l1.l2l1 = hscx_l2l1;
// bcs->cs->BC_Send_Data = hscx_fill_fifo; // bcs->cs->BC_Send_Data = hscx_fill_fifo; FIXME
break; break;
case L1_MODE_MODEM: case L1_MODE_MODEM:
bcs->mode = L1_MODE_MODEM; bcs->mode = L1_MODE_MODEM;
if (!test_and_set_bit(BC_FLG_INIT, &bcs->Flag)) { if (!test_and_set_bit(BC_FLG_INIT, &bcs->Flag)) {
bcs->hw.hscx.rcvbuf = bcs->cs->hw.elsa.rcvbuf; bcs->rcvbuf = bcs->cs->hw.elsa.rcvbuf;
skb_queue_head_init(&bcs->rqueue); skb_queue_head_init(&bcs->rqueue);
skb_queue_head_init(&bcs->squeue); skb_queue_head_init(&bcs->squeue);
} }
bcs->tx_skb = NULL; bcs->tx_skb = NULL;
test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag); test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag);
bcs->event = 0; bcs->event = 0;
bcs->hw.hscx.rcvidx = 0; bcs->rcvidx = 0;
bcs->tx_cnt = 0; bcs->tx_cnt = 0;
bcs->cs->hw.elsa.bcs = bcs; bcs->cs->hw.elsa.bcs = bcs;
st->l1.l2l1 = modem_l2l1; st->l1.l2l1 = modem_l2l1;
bcs->cs->bc_l1_ops = &modem_l1_ops; // bcs->cs->bc_l1_ops = &modem_l1_ops;
break; break;
} }
st->l1.bcs = bcs; st->l1.bcs = bcs;
...@@ -623,13 +618,17 @@ setstack_elsa(struct PStack *st, struct BCState *bcs) ...@@ -623,13 +618,17 @@ setstack_elsa(struct PStack *st, struct BCState *bcs)
return (0); return (0);
} }
static struct bc_l1_ops modem_l1_ops = {
.fill_fifo = modem_fill,
.open = setstack_elsa,
.close = close_elsastate,
};
void void
init_modem(struct IsdnCardState *cs) { init_modem(struct IsdnCardState *cs)
{
cs->bc_l1_ops = &modem_l1_ops;
cs->bcs[0].BC_SetStack = setstack_elsa;
cs->bcs[1].BC_SetStack = setstack_elsa;
cs->bcs[0].BC_Close = close_elsastate;
cs->bcs[1].BC_Close = close_elsastate;
if (!(cs->hw.elsa.rcvbuf = kmalloc(MAX_MODEM_BUF, if (!(cs->hw.elsa.rcvbuf = kmalloc(MAX_MODEM_BUF,
GFP_ATOMIC))) { GFP_ATOMIC))) {
printk(KERN_WARNING printk(KERN_WARNING
......
...@@ -162,19 +162,6 @@ enpci_card_msg(struct IsdnCardState *cs, int mt, void *arg) ...@@ -162,19 +162,6 @@ enpci_card_msg(struct IsdnCardState *cs, int mt, void *arg)
debugl1(cs, "enter:now PCI: card_msg: 0x%04X", mt); debugl1(cs, "enter:now PCI: card_msg: 0x%04X", mt);
switch (mt) { switch (mt) {
case CARD_RESET:
reset_enpci(cs);
Amd7930_init(cs);
break;
case CARD_RELEASE:
release_io_netjet(cs);
break;
case CARD_INIT:
inittiger(cs);
Amd7930_init(cs);
break;
case CARD_TEST:
break;
case MDL_ASSIGN: case MDL_ASSIGN:
/* TEI assigned, LED1 on */ /* TEI assigned, LED1 on */
cs->hw.njet.auxd = TJ_AMD_IRQ << 1; cs->hw.njet.auxd = TJ_AMD_IRQ << 1;
...@@ -218,6 +205,20 @@ enpci_card_msg(struct IsdnCardState *cs, int mt, void *arg) ...@@ -218,6 +205,20 @@ enpci_card_msg(struct IsdnCardState *cs, int mt, void *arg)
return(0); return(0);
} }
static void
enpci_init(struct IsdnCardState *cs)
{
inittiger(cs);
Amd7930_init(cs);
}
static int
enpci_reset(struct IsdnCardState *cs)
{
reset_enpci(cs);
Amd7930_init(cs);
return 0;
}
static void static void
enpci_interrupt(int intno, void *dev_id, struct pt_regs *regs) enpci_interrupt(int intno, void *dev_id, struct pt_regs *regs)
...@@ -266,6 +267,12 @@ enpci_interrupt(int intno, void *dev_id, struct pt_regs *regs) ...@@ -266,6 +267,12 @@ enpci_interrupt(int intno, void *dev_id, struct pt_regs *regs)
spin_unlock(&cs->lock); spin_unlock(&cs->lock);
} }
static struct card_ops enpci_ops = {
.init = enpci_init,
.reset = enpci_reset,
.release = netjet_release,
.irq_func = enpci_interrupt,
};
static struct pci_dev *dev_netjet __initdata = NULL; static struct pci_dev *dev_netjet __initdata = NULL;
...@@ -371,8 +378,8 @@ setup_enternow_pci(struct IsdnCard *card) ...@@ -371,8 +378,8 @@ setup_enternow_pci(struct IsdnCard *card)
cs->dc.amd7930.setIrqMask = &enpci_setIrqMask; cs->dc.amd7930.setIrqMask = &enpci_setIrqMask;
cs->cardmsg = &enpci_card_msg; cs->cardmsg = &enpci_card_msg;
cs->irq_func = &enpci_interrupt;
cs->irq_flags |= SA_SHIRQ; cs->irq_flags |= SA_SHIRQ;
cs->card_ops = &enpci_ops;
return (1); return (1);
} }
......
This diff is collapsed.
...@@ -824,10 +824,11 @@ HFCD_l1hw(struct PStack *st, int pr, void *arg) ...@@ -824,10 +824,11 @@ HFCD_l1hw(struct PStack *st, int pr, void *arg)
} }
} }
void static int
setstack_hfcd(struct PStack *st, struct IsdnCardState *cs) setstack_hfcd(struct PStack *st, struct IsdnCardState *cs)
{ {
st->l1.l1hw = HFCD_l1hw; st->l1.l1hw = HFCD_l1hw;
return 0;
} }
static void static void
...@@ -850,25 +851,30 @@ unsigned int __init ...@@ -850,25 +851,30 @@ unsigned int __init
return(send); return(send);
} }
static struct bc_l1_ops hfcd_bc_l1_ops = {
.fill_fifo = hfc_fill_fifo,
.open = setstack_2b,
.close = close_2bs0,
};
static struct dc_l1_ops hfcd_dc_l1_ops = {
.fill_fifo = hfc_fill_dfifo,
.open = setstack_hfcd,
.bh_func = hfcd_bh,
.dbusy_func = hfc_dbusy_timer,
};
void __init void __init
init2bds0(struct IsdnCardState *cs) init2bds0(struct IsdnCardState *cs)
{ {
cs->setstack_d = setstack_hfcd; dc_l1_init(cs, &hfcd_dc_l1_ops);
cs->dbusytimer.function = (void *) hfc_dbusy_timer; cs->bc_l1_ops = &hfcd_bc_l1_ops;
cs->dbusytimer.data = (long) cs;
init_timer(&cs->dbusytimer);
INIT_WORK(&cs->work, hfcd_bh, cs);
if (!cs->hw.hfcD.send) if (!cs->hw.hfcD.send)
cs->hw.hfcD.send = init_send_hfcd(16); cs->hw.hfcD.send = init_send_hfcd(16);
if (!cs->bcs[0].hw.hfc.send) if (!cs->bcs[0].hw.hfc.send)
cs->bcs[0].hw.hfc.send = init_send_hfcd(32); cs->bcs[0].hw.hfc.send = init_send_hfcd(32);
if (!cs->bcs[1].hw.hfc.send) if (!cs->bcs[1].hw.hfc.send)
cs->bcs[1].hw.hfc.send = init_send_hfcd(32); cs->bcs[1].hw.hfc.send = init_send_hfcd(32);
cs->DC_Send_Data = hfc_fill_dfifo;
cs->bcs[0].BC_SetStack = setstack_2b;
cs->bcs[1].BC_SetStack = setstack_2b;
cs->bcs[0].BC_Close = close_2bs0;
cs->bcs[1].BC_Close = close_2bs0;
mode_2bs0(cs->bcs, 0, 0); mode_2bs0(cs->bcs, 0, 0);
mode_2bs0(cs->bcs + 1, 0, 1); mode_2bs0(cs->bcs + 1, 0, 1);
} }
......
...@@ -546,6 +546,8 @@ init_send(struct BCState *bcs) ...@@ -546,6 +546,8 @@ init_send(struct BCState *bcs)
static struct bc_l1_ops hfc_l1_ops = { static struct bc_l1_ops hfc_l1_ops = {
.fill_fifo = hfc_fill_fifo, .fill_fifo = hfc_fill_fifo,
.open = setstack_hfc,
.close = close_hfcstate,
}; };
void __init void __init
...@@ -554,10 +556,6 @@ inithfc(struct IsdnCardState *cs) ...@@ -554,10 +556,6 @@ inithfc(struct IsdnCardState *cs)
init_send(&cs->bcs[0]); init_send(&cs->bcs[0]);
init_send(&cs->bcs[1]); init_send(&cs->bcs[1]);
cs->bc_l1_ops = &hfc_l1_ops; cs->bc_l1_ops = &hfc_l1_ops;
cs->bcs[0].BC_SetStack = setstack_hfc;
cs->bcs[1].BC_SetStack = setstack_hfc;
cs->bcs[0].BC_Close = close_hfcstate;
cs->bcs[1].BC_Close = close_hfcstate;
mode_hfc(cs->bcs, 0, 0); mode_hfc(cs->bcs, 0, 0);
mode_hfc(cs->bcs + 1, 0, 0); mode_hfc(cs->bcs + 1, 0, 0);
} }
......
...@@ -70,8 +70,8 @@ static const PCI_ENTRY id_list[] = ...@@ -70,8 +70,8 @@ static const PCI_ENTRY id_list[] =
/******************************************/ /******************************************/
/* free hardware resources used by driver */ /* free hardware resources used by driver */
/******************************************/ /******************************************/
void static void
release_io_hfcpci(struct IsdnCardState *cs) hfcpci_release(struct IsdnCardState *cs)
{ {
printk(KERN_INFO "HiSax: release hfcpci at %p\n", printk(KERN_INFO "HiSax: release hfcpci at %p\n",
cs->hw.hfcpci.pci_io); cs->hw.hfcpci.pci_io);
...@@ -91,8 +91,8 @@ release_io_hfcpci(struct IsdnCardState *cs) ...@@ -91,8 +91,8 @@ release_io_hfcpci(struct IsdnCardState *cs)
/* function called to reset the HFC PCI chip. A complete software reset of chip */ /* function called to reset the HFC PCI chip. A complete software reset of chip */
/* and fifos is done. */ /* and fifos is done. */
/********************************************************************************/ /********************************************************************************/
static void static int
reset_hfcpci(struct IsdnCardState *cs) hfcpci_reset(struct IsdnCardState *cs)
{ {
pci_disable_device(cs->hw.hfcpci.pdev); pci_disable_device(cs->hw.hfcpci.pdev);
cs->hw.hfcpci.int_m2 = 0; /* interrupt output off ! */ cs->hw.hfcpci.int_m2 = 0; /* interrupt output off ! */
...@@ -159,6 +159,8 @@ reset_hfcpci(struct IsdnCardState *cs) ...@@ -159,6 +159,8 @@ reset_hfcpci(struct IsdnCardState *cs)
cs->hw.hfcpci.int_m2 = HFCPCI_IRQ_ENABLE; cs->hw.hfcpci.int_m2 = HFCPCI_IRQ_ENABLE;
Write_hfc(cs, HFCPCI_INT_M2, cs->hw.hfcpci.int_m2); Write_hfc(cs, HFCPCI_INT_M2, cs->hw.hfcpci.int_m2);
if (Read_hfc(cs, HFCPCI_INT_S2)); if (Read_hfc(cs, HFCPCI_INT_S2));
return 0;
} }
/***************************************************/ /***************************************************/
...@@ -1047,10 +1049,11 @@ HFCPCI_l1hw(struct PStack *st, int pr, void *arg) ...@@ -1047,10 +1049,11 @@ HFCPCI_l1hw(struct PStack *st, int pr, void *arg)
/***********************************************/ /***********************************************/
/* called during init setting l1 stack pointer */ /* called during init setting l1 stack pointer */
/***********************************************/ /***********************************************/
void static int
setstack_hfcpci(struct PStack *st, struct IsdnCardState *cs) setstack_hfcpci(struct PStack *st, struct IsdnCardState *cs)
{ {
st->l1.l1hw = HFCPCI_l1hw; st->l1.l1hw = HFCPCI_l1hw;
return 0;
} }
/***************************************************************/ /***************************************************************/
...@@ -1335,8 +1338,17 @@ hfcpci_bh(void *data) ...@@ -1335,8 +1338,17 @@ hfcpci_bh(void *data)
DChannel_proc_xmt(cs); DChannel_proc_xmt(cs);
} }
static struct bc_l1_ops hfcpci_l1_ops = { static struct bc_l1_ops hfcpci_bc_l1_ops = {
.fill_fifo = hfcpci_fill_fifo, .fill_fifo = hfcpci_fill_fifo,
.open = setstack_2b,
.close = close_hfcpci,
};
static struct dc_l1_ops hfcpci_dc_l1_ops = {
.fill_fifo = hfcpci_fill_dfifo,
.open = setstack_hfcpci,
.bh_func = hfcpci_bh,
.dbusy_func = hfcpci_dbusy_timer,
}; };
/********************************/ /********************************/
...@@ -1345,17 +1357,8 @@ static struct bc_l1_ops hfcpci_l1_ops = { ...@@ -1345,17 +1357,8 @@ static struct bc_l1_ops hfcpci_l1_ops = {
void __init void __init
inithfcpci(struct IsdnCardState *cs) inithfcpci(struct IsdnCardState *cs)
{ {
cs->setstack_d = setstack_hfcpci; dc_l1_init(cs, &hfcpci_dc_l1_ops);
cs->dbusytimer.function = (void *) hfcpci_dbusy_timer; cs->bc_l1_ops = &hfcpci_bc_l1_ops;
cs->dbusytimer.data = (long) cs;
init_timer(&cs->dbusytimer);
INIT_WORK(&cs->work, hfcpci_bh, cs);
cs->bc_l1_ops = &hfcpci_l1_ops;
cs->DC_Send_Data = hfcpci_fill_dfifo;
cs->bcs[0].BC_SetStack = setstack_2b;
cs->bcs[1].BC_SetStack = setstack_2b;
cs->bcs[0].BC_Close = close_hfcpci;
cs->bcs[1].BC_Close = close_hfcpci;
mode_hfcpci(cs->bcs, 0, 0); mode_hfcpci(cs->bcs, 0, 0);
mode_hfcpci(cs->bcs + 1, 0, 1); mode_hfcpci(cs->bcs + 1, 0, 1);
} }
...@@ -1368,16 +1371,12 @@ inithfcpci(struct IsdnCardState *cs) ...@@ -1368,16 +1371,12 @@ inithfcpci(struct IsdnCardState *cs)
static int static int
hfcpci_card_msg(struct IsdnCardState *cs, int mt, void *arg) hfcpci_card_msg(struct IsdnCardState *cs, int mt, void *arg)
{ {
if (cs->debug & L1_DEB_ISAC)
debugl1(cs, "HFCPCI: card_msg %x", mt);
switch (mt) {
case CARD_RESET:
reset_hfcpci(cs);
return (0); return (0);
case CARD_RELEASE: }
release_io_hfcpci(cs);
return (0); static void
case CARD_INIT: hfcpci_init(struct IsdnCardState *cs)
{
inithfcpci(cs); inithfcpci(cs);
set_current_state(TASK_UNINTERRUPTIBLE); set_current_state(TASK_UNINTERRUPTIBLE);
schedule_timeout((80 * HZ) / 1000); /* Timeout 80ms */ schedule_timeout((80 * HZ) / 1000); /* Timeout 80ms */
...@@ -1386,13 +1385,15 @@ hfcpci_card_msg(struct IsdnCardState *cs, int mt, void *arg) ...@@ -1386,13 +1385,15 @@ hfcpci_card_msg(struct IsdnCardState *cs, int mt, void *arg)
Write_hfc(cs, HFCPCI_INT_M1, cs->hw.hfcpci.int_m1); Write_hfc(cs, HFCPCI_INT_M1, cs->hw.hfcpci.int_m1);
/* reinit mode reg */ /* reinit mode reg */
Write_hfc(cs, HFCPCI_MST_MODE, cs->hw.hfcpci.mst_m); Write_hfc(cs, HFCPCI_MST_MODE, cs->hw.hfcpci.mst_m);
return (0);
case CARD_TEST:
return (0);
}
return (0);
} }
static struct card_ops hfcpci_ops = {
.init = hfcpci_init,
.reset = hfcpci_reset,
.release = hfcpci_release,
.irq_func = hfcpci_interrupt,
};
/* this variable is used as card index when more than one cards are present */ /* this variable is used as card index when more than one cards are present */
static struct pci_dev *dev_hfcpci __initdata = NULL; static struct pci_dev *dev_hfcpci __initdata = NULL;
...@@ -1476,16 +1477,16 @@ setup_hfcpci(struct IsdnCard *card) ...@@ -1476,16 +1477,16 @@ setup_hfcpci(struct IsdnCard *card)
return (0); /* no valid card type */ return (0); /* no valid card type */
cs->irq_func = &hfcpci_interrupt;
cs->irq_flags |= SA_SHIRQ; cs->irq_flags |= SA_SHIRQ;
cs->hw.hfcpci.timer.function = (void *) hfcpci_Timer; cs->hw.hfcpci.timer.function = (void *) hfcpci_Timer;
cs->hw.hfcpci.timer.data = (long) cs; cs->hw.hfcpci.timer.data = (long) cs;
init_timer(&cs->hw.hfcpci.timer); init_timer(&cs->hw.hfcpci.timer);
reset_hfcpci(cs); hfcpci_reset(cs);
cs->cardmsg = &hfcpci_card_msg; cs->cardmsg = &hfcpci_card_msg;
cs->auxcmd = &hfcpci_auxcmd; cs->auxcmd = &hfcpci_auxcmd;
cs->card_ops = &hfcpci_ops;
return (1); return (1);
#else #else
printk(KERN_WARNING "HFC-PCI: NO_PCI_BIOS\n"); printk(KERN_WARNING "HFC-PCI: NO_PCI_BIOS\n");
......
...@@ -308,8 +308,8 @@ read_fifo(struct IsdnCardState *cs, u8 fifo, int trans_max) ...@@ -308,8 +308,8 @@ read_fifo(struct IsdnCardState *cs, u8 fifo, int trans_max)
/******************************************/ /******************************************/
/* free hardware resources used by driver */ /* free hardware resources used by driver */
/******************************************/ /******************************************/
void static void
release_io_hfcsx(struct IsdnCardState *cs) hfcsx_release(struct IsdnCardState *cs)
{ {
cs->hw.hfcsx.int_m2 = 0; /* interrupt output off ! */ cs->hw.hfcsx.int_m2 = 0; /* interrupt output off ! */
Write_hfc(cs, HFCSX_INT_M2, cs->hw.hfcsx.int_m2); Write_hfc(cs, HFCSX_INT_M2, cs->hw.hfcsx.int_m2);
...@@ -347,8 +347,8 @@ static int set_fifo_size(struct IsdnCardState *cs) ...@@ -347,8 +347,8 @@ static int set_fifo_size(struct IsdnCardState *cs)
/* function called to reset the HFC SX chip. A complete software reset of chip */ /* function called to reset the HFC SX chip. A complete software reset of chip */
/* and fifos is done. */ /* and fifos is done. */
/********************************************************************************/ /********************************************************************************/
static void static int
reset_hfcsx(struct IsdnCardState *cs) hfcsx_reset(struct IsdnCardState *cs)
{ {
cs->hw.hfcsx.int_m2 = 0; /* interrupt output off ! */ cs->hw.hfcsx.int_m2 = 0; /* interrupt output off ! */
Write_hfc(cs, HFCSX_INT_M2, cs->hw.hfcsx.int_m2); Write_hfc(cs, HFCSX_INT_M2, cs->hw.hfcsx.int_m2);
...@@ -415,6 +415,7 @@ reset_hfcsx(struct IsdnCardState *cs) ...@@ -415,6 +415,7 @@ reset_hfcsx(struct IsdnCardState *cs)
cs->hw.hfcsx.int_m2 = HFCSX_IRQ_ENABLE; cs->hw.hfcsx.int_m2 = HFCSX_IRQ_ENABLE;
Write_hfc(cs, HFCSX_INT_M2, cs->hw.hfcsx.int_m2); Write_hfc(cs, HFCSX_INT_M2, cs->hw.hfcsx.int_m2);
if (Read_hfc(cs, HFCSX_INT_S2)); if (Read_hfc(cs, HFCSX_INT_S2));
return 0;
} }
/***************************************************/ /***************************************************/
...@@ -838,10 +839,11 @@ HFCSX_l1hw(struct PStack *st, int pr, void *arg) ...@@ -838,10 +839,11 @@ HFCSX_l1hw(struct PStack *st, int pr, void *arg)
/***********************************************/ /***********************************************/
/* called during init setting l1 stack pointer */ /* called during init setting l1 stack pointer */
/***********************************************/ /***********************************************/
void static int
setstack_hfcsx(struct PStack *st, struct IsdnCardState *cs) setstack_hfcsx(struct PStack *st, struct IsdnCardState *cs)
{ {
st->l1.l1hw = HFCSX_l1hw; st->l1.l1hw = HFCSX_l1hw;
return 0;
} }
/***************************************************************/ /***************************************************************/
...@@ -1112,8 +1114,17 @@ hfcsx_bh(void *data) ...@@ -1112,8 +1114,17 @@ hfcsx_bh(void *data)
DChannel_proc_xmt(cs); DChannel_proc_xmt(cs);
} }
static struct bc_l1_ops hfcsx_l1_ops = { static struct bc_l1_ops hfcsx_bc_l1_ops = {
.fill_fifo = hfcsx_fill_fifo, .fill_fifo = hfcsx_fill_fifo,
.open = setstack_2b,
.close = close_hfcsx,
};
static struct dc_l1_ops hfcsx_dc_l1_ops = {
.fill_fifo = hfcsx_fill_dfifo,
.open = setstack_hfcsx,
.bh_func = hfcsx_bh,
.dbusy_func = hfcsx_dbusy_timer,
}; };
/********************************/ /********************************/
...@@ -1122,17 +1133,8 @@ static struct bc_l1_ops hfcsx_l1_ops = { ...@@ -1122,17 +1133,8 @@ static struct bc_l1_ops hfcsx_l1_ops = {
void __devinit void __devinit
inithfcsx(struct IsdnCardState *cs) inithfcsx(struct IsdnCardState *cs)
{ {
cs->setstack_d = setstack_hfcsx; dc_l1_init(cs, &hfcsx_dc_l1_ops);
cs->dbusytimer.function = (void *) hfcsx_dbusy_timer; cs->bc_l1_ops = &hfcsx_bc_l1_ops;
cs->dbusytimer.data = (long) cs;
init_timer(&cs->dbusytimer);
INIT_WORK(&cs->work, hfcsx_bh, cs);
cs->bc_l1_ops = &hfcsx_l1_ops;
cs->DC_Send_Data = hfcsx_fill_dfifo;
cs->bcs[0].BC_SetStack = setstack_2b;
cs->bcs[1].BC_SetStack = setstack_2b;
cs->bcs[0].BC_Close = close_hfcsx;
cs->bcs[1].BC_Close = close_hfcsx;
mode_hfcsx(cs->bcs, 0, 0); mode_hfcsx(cs->bcs, 0, 0);
mode_hfcsx(cs->bcs + 1, 0, 1); mode_hfcsx(cs->bcs + 1, 0, 1);
} }
...@@ -1145,16 +1147,12 @@ inithfcsx(struct IsdnCardState *cs) ...@@ -1145,16 +1147,12 @@ inithfcsx(struct IsdnCardState *cs)
static int static int
hfcsx_card_msg(struct IsdnCardState *cs, int mt, void *arg) hfcsx_card_msg(struct IsdnCardState *cs, int mt, void *arg)
{ {
if (cs->debug & L1_DEB_ISAC)
debugl1(cs, "HFCSX: card_msg %x", mt);
switch (mt) {
case CARD_RESET:
reset_hfcsx(cs);
return (0); return (0);
case CARD_RELEASE: }
release_io_hfcsx(cs);
return (0); static void
case CARD_INIT: hfcsx_init(struct IsdnCardState *cs)
{
inithfcsx(cs); inithfcsx(cs);
set_current_state(TASK_UNINTERRUPTIBLE); set_current_state(TASK_UNINTERRUPTIBLE);
schedule_timeout((80 * HZ) / 1000); /* Timeout 80ms */ schedule_timeout((80 * HZ) / 1000); /* Timeout 80ms */
...@@ -1163,13 +1161,15 @@ hfcsx_card_msg(struct IsdnCardState *cs, int mt, void *arg) ...@@ -1163,13 +1161,15 @@ hfcsx_card_msg(struct IsdnCardState *cs, int mt, void *arg)
Write_hfc(cs, HFCSX_INT_M1, cs->hw.hfcsx.int_m1); Write_hfc(cs, HFCSX_INT_M1, cs->hw.hfcsx.int_m1);
/* reinit mode reg */ /* reinit mode reg */
Write_hfc(cs, HFCSX_MST_MODE, cs->hw.hfcsx.mst_m); Write_hfc(cs, HFCSX_MST_MODE, cs->hw.hfcsx.mst_m);
return (0);
case CARD_TEST:
return (0);
}
return (0);
} }
static struct card_ops hfcsx_ops = {
.init = hfcsx_init,
.reset = hfcsx_reset,
.release = hfcsx_release,
.irq_func = hfcsx_interrupt,
};
#ifdef __ISAPNP__ #ifdef __ISAPNP__
static struct isapnp_device_id hfc_ids[] __initdata = { static struct isapnp_device_id hfc_ids[] __initdata = {
{ ISAPNP_VENDOR('T', 'A', 'G'), ISAPNP_FUNCTION(0x2620), { ISAPNP_VENDOR('T', 'A', 'G'), ISAPNP_FUNCTION(0x2620),
...@@ -1288,16 +1288,15 @@ setup_hfcsx(struct IsdnCard *card) ...@@ -1288,16 +1288,15 @@ setup_hfcsx(struct IsdnCard *card)
} else } else
return (0); /* no valid card type */ return (0); /* no valid card type */
cs->irq_func = &hfcsx_interrupt;
cs->hw.hfcsx.timer.function = (void *) hfcsx_Timer; cs->hw.hfcsx.timer.function = (void *) hfcsx_Timer;
cs->hw.hfcsx.timer.data = (long) cs; cs->hw.hfcsx.timer.data = (long) cs;
cs->hw.hfcsx.b_fifo_size = 0; /* fifo size still unknown */ cs->hw.hfcsx.b_fifo_size = 0; /* fifo size still unknown */
cs->hw.hfcsx.cirm = ccd_sp_irqtab[cs->irq & 0xF]; /* RAM not evaluated */ cs->hw.hfcsx.cirm = ccd_sp_irqtab[cs->irq & 0xF]; /* RAM not evaluated */
init_timer(&cs->hw.hfcsx.timer); init_timer(&cs->hw.hfcsx.timer);
reset_hfcsx(cs); hfcsx_reset(cs);
cs->cardmsg = &hfcsx_card_msg; cs->cardmsg = &hfcsx_card_msg;
cs->auxcmd = &hfcsx_auxcmd; cs->auxcmd = &hfcsx_auxcmd;
cs->card_ops = &hfcsx_ops;
return (1); return (1);
} }
...@@ -64,8 +64,8 @@ hfcs_Timer(struct IsdnCardState *cs) ...@@ -64,8 +64,8 @@ hfcs_Timer(struct IsdnCardState *cs)
*/ */
} }
void static void
release_io_hfcs(struct IsdnCardState *cs) hfcs_release(struct IsdnCardState *cs)
{ {
release2bds0(cs); release2bds0(cs);
del_timer(&cs->hw.hfcD.timer); del_timer(&cs->hw.hfcD.timer);
...@@ -73,8 +73,8 @@ release_io_hfcs(struct IsdnCardState *cs) ...@@ -73,8 +73,8 @@ release_io_hfcs(struct IsdnCardState *cs)
release_region(cs->hw.hfcD.addr, 2); release_region(cs->hw.hfcD.addr, 2);
} }
static void static int
reset_hfcs(struct IsdnCardState *cs) hfcs_reset(struct IsdnCardState *cs)
{ {
printk(KERN_INFO "HFCS: resetting card\n"); printk(KERN_INFO "HFCS: resetting card\n");
cs->hw.hfcD.cirm = HFCD_RESET; cs->hw.hfcD.cirm = HFCD_RESET;
...@@ -111,21 +111,18 @@ reset_hfcs(struct IsdnCardState *cs) ...@@ -111,21 +111,18 @@ reset_hfcs(struct IsdnCardState *cs)
hfcs_write_reg(cs, HFCD_DATA, HFCD_MST_MODE, cs->hw.hfcD.mst_m); /* HFC Master */ hfcs_write_reg(cs, HFCD_DATA, HFCD_MST_MODE, cs->hw.hfcD.mst_m); /* HFC Master */
cs->hw.hfcD.sctrl = 0; cs->hw.hfcD.sctrl = 0;
hfcs_write_reg(cs, HFCD_DATA, HFCD_SCTRL, cs->hw.hfcD.sctrl); hfcs_write_reg(cs, HFCD_DATA, HFCD_SCTRL, cs->hw.hfcD.sctrl);
return 0;
} }
static int static int
hfcs_card_msg(struct IsdnCardState *cs, int mt, void *arg) hfcs_card_msg(struct IsdnCardState *cs, int mt, void *arg)
{ {
if (cs->debug & L1_DEB_ISAC)
debugl1(cs, "HFCS: card_msg %x", mt);
switch (mt) {
case CARD_RESET:
reset_hfcs(cs);
return(0); return(0);
case CARD_RELEASE: }
release_io_hfcs(cs);
return(0); static void
case CARD_INIT: hfcs_init(struct IsdnCardState *cs)
{
cs->hw.hfcD.timer.expires = jiffies + 75; cs->hw.hfcD.timer.expires = jiffies + 75;
add_timer(&cs->hw.hfcD.timer); add_timer(&cs->hw.hfcD.timer);
init2bds0(cs); init2bds0(cs);
...@@ -134,13 +131,15 @@ hfcs_card_msg(struct IsdnCardState *cs, int mt, void *arg) ...@@ -134,13 +131,15 @@ hfcs_card_msg(struct IsdnCardState *cs, int mt, void *arg)
cs->hw.hfcD.ctmt |= HFCD_TIM800; cs->hw.hfcD.ctmt |= HFCD_TIM800;
hfcs_write_reg(cs, HFCD_DATA, HFCD_CTMT, cs->hw.hfcD.ctmt); hfcs_write_reg(cs, HFCD_DATA, HFCD_CTMT, cs->hw.hfcD.ctmt);
hfcs_write_reg(cs, HFCD_DATA, HFCD_MST_MODE, cs->hw.hfcD.mst_m); hfcs_write_reg(cs, HFCD_DATA, HFCD_MST_MODE, cs->hw.hfcD.mst_m);
return(0);
case CARD_TEST:
return(0);
}
return(0);
} }
static struct card_ops hfcs_ops = {
.init = hfcs_init,
.reset = hfcs_reset,
.release = hfcs_release,
.irq_func = hfcs_interrupt,
};
#ifdef __ISAPNP__ #ifdef __ISAPNP__
static struct isapnp_device_id hfc_ids[] __initdata = { static struct isapnp_device_id hfc_ids[] __initdata = {
{ ISAPNP_VENDOR('A', 'N', 'X'), ISAPNP_FUNCTION(0x1114), { ISAPNP_VENDOR('A', 'N', 'X'), ISAPNP_FUNCTION(0x1114),
...@@ -262,8 +261,8 @@ setup_hfcs(struct IsdnCard *card) ...@@ -262,8 +261,8 @@ setup_hfcs(struct IsdnCard *card)
cs->hw.hfcD.timer.function = (void *) hfcs_Timer; cs->hw.hfcD.timer.function = (void *) hfcs_Timer;
cs->hw.hfcD.timer.data = (long) cs; cs->hw.hfcD.timer.data = (long) cs;
init_timer(&cs->hw.hfcD.timer); init_timer(&cs->hw.hfcD.timer);
reset_hfcs(cs); hfcs_reset(cs);
cs->cardmsg = &hfcs_card_msg; cs->cardmsg = &hfcs_card_msg;
cs->irq_func = &hfcs_interrupt; cs->card_ops = &hfcs_ops;
return (1); return (1);
} }
...@@ -6,6 +6,10 @@ ...@@ -6,6 +6,10 @@
* of the GNU General Public License, incorporated herein by reference. * of the GNU General Public License, incorporated herein by reference.
* *
*/ */
#ifndef __HISAX_H__
#define __HISAX_H__
#include <linux/config.h> #include <linux/config.h>
#include <linux/errno.h> #include <linux/errno.h>
#include <linux/fs.h> #include <linux/fs.h>
...@@ -46,11 +50,6 @@ ...@@ -46,11 +50,6 @@
#define HW_INFO4_P10 0x0048 #define HW_INFO4_P10 0x0048
#define HW_RSYNC 0x0060 #define HW_RSYNC 0x0060
#define HW_TESTLOOP 0x0070 #define HW_TESTLOOP 0x0070
#define CARD_RESET 0x00F0
#define CARD_INIT 0x00F2
#define CARD_RELEASE 0x00F3
#define CARD_TEST 0x00F4
#define CARD_AUX_IND 0x00F5
#define PH_ACTIVATE 0x0100 #define PH_ACTIVATE 0x0100
#define PH_DEACTIVATE 0x0110 #define PH_DEACTIVATE 0x0110
...@@ -349,17 +348,12 @@ struct l3_process { ...@@ -349,17 +348,12 @@ struct l3_process {
}; };
struct hscx_hw { struct hscx_hw {
int hscx;
int rcvidx;
u8 *rcvbuf; /* B-Channel receive Buffer */
u8 tsaxr0; u8 tsaxr0;
u8 tsaxr1; u8 tsaxr1;
}; };
struct w6692B_hw { struct w6692B_hw {
int bchan; int bchan;
int rcvidx;
u8 *rcvbuf; /* B-Channel receive Buffer */
}; };
struct isar_reg { struct isar_reg {
...@@ -407,8 +401,6 @@ struct hdlc_hw { ...@@ -407,8 +401,6 @@ struct hdlc_hw {
struct hdlc_stat_reg sr; struct hdlc_stat_reg sr;
} ctrl; } ctrl;
u_int stat; u_int stat;
int rcvidx;
u8 *rcvbuf; /* B-Channel receive Buffer */
}; };
struct hfcB_hw { struct hfcB_hw {
...@@ -479,8 +471,11 @@ struct amd7930_hw { ...@@ -479,8 +471,11 @@ struct amd7930_hw {
struct BCState { struct BCState {
int channel; int channel;
int mode; int mode;
long Flag; /* long req'd for set_bit --RR */ long Flag;
struct IsdnCardState *cs; struct IsdnCardState *cs;
int unit; /* first or second unit (e.g. HSCX) */
int rcvidx;
u8 *rcvbuf; /* B-Channel receive Buffer */
int tx_cnt; /* B-Channel transmit counter */ int tx_cnt; /* B-Channel transmit counter */
struct sk_buff *tx_skb; /* B-Channel transmit Buffer */ struct sk_buff *tx_skb; /* B-Channel transmit Buffer */
struct sk_buff_head rqueue; /* B-Channel receive queue */ struct sk_buff_head rqueue; /* B-Channel receive queue */
...@@ -492,8 +487,6 @@ struct BCState { ...@@ -492,8 +487,6 @@ struct BCState {
struct timer_list transbusy; struct timer_list transbusy;
struct work_struct work; struct work_struct work;
unsigned long event; unsigned long event;
int (*BC_SetStack) (struct PStack *, struct BCState *);
void (*BC_Close) (struct BCState *);
#ifdef ERROR_STATISTIC #ifdef ERROR_STATISTIC
int err_crc; int err_crc;
int err_tx; int err_tx;
...@@ -861,6 +854,17 @@ struct icc_chip { ...@@ -861,6 +854,17 @@ struct icc_chip {
struct IsdnCardState; 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 *);
};
/* Card specific drivers provide methods to access the /* Card specific drivers provide methods to access the
* chips to the chip drivers */ * chips to the chip drivers */
...@@ -878,10 +882,23 @@ struct dc_hw_ops { ...@@ -878,10 +882,23 @@ struct dc_hw_ops {
void (*write_fifo) (struct IsdnCardState *, u8 *, int); void (*write_fifo) (struct IsdnCardState *, u8 *, int);
}; };
/* Methods provided to shared FIFO handling */ /* Methods provided to shared B-channel FIFO handling */
struct bc_l1_ops { struct bc_l1_ops {
void (*fill_fifo) (struct BCState *); void (*fill_fifo) (struct BCState *);
int (*open) (struct PStack *, struct BCState *);
void (*close) (struct BCState *);
};
/* Methods provided to shared D-channel FIFO handling */
struct dc_l1_ops {
void (*fill_fifo) (struct IsdnCardState *);
int (*open) (struct PStack *, struct IsdnCardState *);
void (*close) (struct IsdnCardState *);
void (*bh_func) (void *);
void (*dbusy_func) (struct IsdnCardState *);
}; };
#define HW_IOM1 0 #define HW_IOM1 0
...@@ -900,6 +917,7 @@ struct IsdnCardState { ...@@ -900,6 +917,7 @@ struct IsdnCardState {
unsigned char typ; unsigned char typ;
unsigned char subtyp; unsigned char subtyp;
spinlock_t lock; spinlock_t lock;
struct card_ops *card_ops;
int protocol; int protocol;
unsigned int irq; unsigned int irq;
unsigned long irq_flags; unsigned long irq_flags;
...@@ -942,12 +960,9 @@ struct IsdnCardState { ...@@ -942,12 +960,9 @@ struct IsdnCardState {
u8 *status_end; u8 *status_end;
struct dc_hw_ops *dc_hw_ops; struct dc_hw_ops *dc_hw_ops;
struct bc_hw_ops *bc_hw_ops; struct bc_hw_ops *bc_hw_ops;
struct dc_l1_ops *dc_l1_ops;
struct bc_l1_ops *bc_l1_ops; struct bc_l1_ops *bc_l1_ops;
int (*cardmsg) (struct IsdnCardState *, int, void *); int (*cardmsg) (struct IsdnCardState *, int, void *);
void (*setstack_d) (struct PStack *, struct IsdnCardState *);
void (*DC_Send_Data) (struct IsdnCardState *);
void (*DC_Close) (struct IsdnCardState *);
void (*irq_func) (int, void *, struct pt_regs *);
int (*auxcmd) (struct IsdnCardState *, isdn_ctrl *); int (*auxcmd) (struct IsdnCardState *, isdn_ctrl *);
struct Channel channel[2+MAX_WAITING_CALLS]; struct Channel channel[2+MAX_WAITING_CALLS];
struct BCState bcs[2+MAX_WAITING_CALLS]; struct BCState bcs[2+MAX_WAITING_CALLS];
...@@ -1363,9 +1378,6 @@ int QuickHex(char *txt, u8 * p, int cnt); ...@@ -1363,9 +1378,6 @@ int QuickHex(char *txt, u8 * p, int cnt);
void LogFrame(struct IsdnCardState *cs, u8 * p, int size); void LogFrame(struct IsdnCardState *cs, u8 * p, int size);
void dlogframe(struct IsdnCardState *cs, struct sk_buff *skb, int dir); void dlogframe(struct IsdnCardState *cs, struct sk_buff *skb, int dir);
void iecpy(u8 * dest, u8 * iestart, int ieoffset); void iecpy(u8 * dest, u8 * iestart, int ieoffset);
#ifdef ISDN_CHIP_ISAC
void setstack_isac(struct PStack *st, struct IsdnCardState *cs);
#endif /* ISDN_CHIP_ISAC */
#endif /* __KERNEL__ */ #endif /* __KERNEL__ */
#define HZDELAY(jiffs) {int tout = jiffs; while (tout--) udelay(1000000/HZ);} #define HZDELAY(jiffs) {int tout = jiffs; while (tout--) udelay(1000000/HZ);}
...@@ -1424,3 +1436,5 @@ L4L3(struct PStack *st, int pr, void *arg) ...@@ -1424,3 +1436,5 @@ L4L3(struct PStack *st, int pr, void *arg)
{ {
st->l3.l4l3(st, pr, arg); st->l3.l4l3(st, pr, arg);
} }
#endif
...@@ -1605,7 +1605,7 @@ static void __devexit hfcpci_remove(struct pci_dev *pdev) ...@@ -1605,7 +1605,7 @@ static void __devexit hfcpci_remove(struct pci_dev *pdev)
static struct pci_driver hfcpci_driver = { static struct pci_driver hfcpci_driver = {
.name = "hfcpci", .name = "hfcpci",
.probe = hfcpci_probe, .probe = hfcpci_probe,
.remove = hfcpci_remove, .remove = __devexit_p(hfcpci_remove),
.id_table = hfcpci_ids, .id_table = hfcpci_ids,
}; };
......
...@@ -25,36 +25,24 @@ static inline u8 ...@@ -25,36 +25,24 @@ static inline u8
hscx_read(struct BCState *bcs, u8 addr) hscx_read(struct BCState *bcs, u8 addr)
{ {
struct IsdnCardState *cs = bcs->cs; struct IsdnCardState *cs = bcs->cs;
u8 hscx = bcs->hw.hscx.hscx;
return cs->bc_hw_ops->read_reg(cs, hscx, addr); return cs->bc_hw_ops->read_reg(cs, bcs->unit, addr);
} }
static inline void static inline void
hscx_write(struct BCState *bcs, u8 addr, u8 val) hscx_write(struct BCState *bcs, u8 addr, u8 val)
{ {
struct IsdnCardState *cs = bcs->cs; struct IsdnCardState *cs = bcs->cs;
u8 hscx = bcs->hw.hscx.hscx;
cs->bc_hw_ops->write_reg(cs, hscx, addr, val); cs->bc_hw_ops->write_reg(cs, bcs->unit, addr, val);
}
static inline void
hscx_read_fifo(struct BCState *bcs, u8 *p, int len)
{
struct IsdnCardState *cs = bcs->cs;
u8 hscx = bcs->hw.hscx.hscx;
cs->bc_hw_ops->read_fifo(cs, hscx, p, len);
} }
static inline void static inline void
hscx_write_fifo(struct BCState *bcs, u8 *p, int len) hscx_write_fifo(struct BCState *bcs, u8 *p, int len)
{ {
struct IsdnCardState *cs = bcs->cs; struct IsdnCardState *cs = bcs->cs;
u8 hscx = bcs->hw.hscx.hscx;
cs->bc_hw_ops->write_fifo(cs, hscx, p, len); cs->bc_hw_ops->write_fifo(cs, bcs->unit, p, len);
} }
int __init int __init
...@@ -67,16 +55,16 @@ HscxVersion(struct IsdnCardState *cs, char *s) ...@@ -67,16 +55,16 @@ HscxVersion(struct IsdnCardState *cs, char *s)
printk(KERN_INFO "%s HSCX version A: %s B: %s\n", s, printk(KERN_INFO "%s HSCX version A: %s B: %s\n", s,
HSCXVer[verA], HSCXVer[verB]); HSCXVer[verA], HSCXVer[verB]);
if ((verA == 0) | (verA == 0xf) | (verB == 0) | (verB == 0xf)) if ((verA == 0) | (verA == 0xf) | (verB == 0) | (verB == 0xf))
return (1); return 1;
else else
return (0); return 0;
} }
void void
modehscx(struct BCState *bcs, int mode, int bc) modehscx(struct BCState *bcs, int mode, int bc)
{ {
struct IsdnCardState *cs = bcs->cs; struct IsdnCardState *cs = bcs->cs;
int hscx = bcs->hw.hscx.hscx; int hscx = bcs->unit;
if (cs->debug & L1_DEB_HSCX) if (cs->debug & L1_DEB_HSCX)
debugl1(cs, "hscx %c mode %d ichan %d", debugl1(cs, "hscx %c mode %d ichan %d",
...@@ -164,52 +152,17 @@ void ...@@ -164,52 +152,17 @@ void
close_hscxstate(struct BCState *bcs) close_hscxstate(struct BCState *bcs)
{ {
modehscx(bcs, 0, bcs->channel); modehscx(bcs, 0, bcs->channel);
if (test_and_clear_bit(BC_FLG_INIT, &bcs->Flag)) { bc_close(bcs);
if (bcs->hw.hscx.rcvbuf) {
kfree(bcs->hw.hscx.rcvbuf);
bcs->hw.hscx.rcvbuf = NULL;
}
if (bcs->blog) {
kfree(bcs->blog);
bcs->blog = NULL;
}
skb_queue_purge(&bcs->rqueue);
skb_queue_purge(&bcs->squeue);
skb_queue_purge(&bcs->cmpl_queue);
if (bcs->tx_skb) {
dev_kfree_skb_any(bcs->tx_skb);
bcs->tx_skb = NULL;
test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag);
}
}
} }
int int
open_hscxstate(struct IsdnCardState *cs, struct BCState *bcs) open_hscxstate(struct IsdnCardState *cs, struct BCState *bcs)
{ {
if (!test_and_set_bit(BC_FLG_INIT, &bcs->Flag)) { bc_open(bcs);
if (!(bcs->hw.hscx.rcvbuf = kmalloc(HSCX_BUFMAX, GFP_ATOMIC))) {
printk(KERN_WARNING
"HiSax: No memory for hscx.rcvbuf\n");
test_and_clear_bit(BC_FLG_INIT, &bcs->Flag);
return (1);
}
if (!(bcs->blog = kmalloc(MAX_BLOG_SPACE, GFP_ATOMIC))) {
printk(KERN_WARNING
"HiSax: No memory for bcs->blog\n");
test_and_clear_bit(BC_FLG_INIT, &bcs->Flag);
kfree(bcs->hw.hscx.rcvbuf);
bcs->hw.hscx.rcvbuf = NULL;
return (2);
}
skb_queue_head_init(&bcs->rqueue);
skb_queue_head_init(&bcs->squeue);
skb_queue_head_init(&bcs->cmpl_queue);
}
bcs->tx_skb = NULL; bcs->tx_skb = NULL;
test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag); test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag);
bcs->event = 0; bcs->event = 0;
bcs->hw.hscx.rcvidx = 0; bcs->rcvidx = 0;
bcs->tx_cnt = 0; bcs->tx_cnt = 0;
return (0); return (0);
} }
...@@ -228,8 +181,12 @@ setstack_hscx(struct PStack *st, struct BCState *bcs) ...@@ -228,8 +181,12 @@ setstack_hscx(struct PStack *st, struct BCState *bcs)
return (0); return (0);
} }
static void hscx_fill_fifo(struct BCState *bcs);
static struct bc_l1_ops hscx_l1_ops = { static struct bc_l1_ops hscx_l1_ops = {
.fill_fifo = hscx_fill_fifo, .fill_fifo = hscx_fill_fifo,
.open = setstack_hscx,
.close = close_hscxstate,
}; };
void __init void __init
...@@ -238,12 +195,8 @@ inithscx(struct IsdnCardState *cs) ...@@ -238,12 +195,8 @@ inithscx(struct IsdnCardState *cs)
int val, eval; int val, eval;
cs->bc_l1_ops = &hscx_l1_ops; cs->bc_l1_ops = &hscx_l1_ops;
cs->bcs[0].BC_SetStack = setstack_hscx; cs->bcs[0].unit = 0;
cs->bcs[1].BC_SetStack = setstack_hscx; cs->bcs[1].unit = 1;
cs->bcs[0].BC_Close = close_hscxstate;
cs->bcs[1].BC_Close = close_hscxstate;
cs->bcs[0].hw.hscx.hscx = 0;
cs->bcs[1].hw.hscx.hscx = 1;
cs->bcs[0].hw.hscx.tsaxr0 = 0x2f; cs->bcs[0].hw.hscx.tsaxr0 = 0x2f;
cs->bcs[0].hw.hscx.tsaxr1 = 3; cs->bcs[0].hw.hscx.tsaxr1 = 3;
cs->bcs[1].hw.hscx.tsaxr0 = 0x2f; cs->bcs[1].hw.hscx.tsaxr0 = 0x2f;
......
...@@ -38,4 +38,4 @@ extern int HscxVersion(struct IsdnCardState *cs, char *s); ...@@ -38,4 +38,4 @@ extern int HscxVersion(struct IsdnCardState *cs, char *s);
extern void modehscx(struct BCState *bcs, int mode, int bc); extern void modehscx(struct BCState *bcs, int mode, int bc);
extern void inithscxisac(struct IsdnCardState *cs); extern void inithscxisac(struct IsdnCardState *cs);
extern void hscx_int_main(struct IsdnCardState *cs, u8 val); extern void hscx_int_main(struct IsdnCardState *cs, u8 val);
extern void hscx_fill_fifo(struct BCState *bcs); extern void hscxisac_irq(int intno, void *dev_id, struct pt_regs *regs);
...@@ -26,7 +26,7 @@ waitforCEC(struct BCState *bcs) ...@@ -26,7 +26,7 @@ waitforCEC(struct BCState *bcs)
} }
static inline void static void
waitforXFW(struct BCState *bcs) waitforXFW(struct BCState *bcs)
{ {
int to = 50; int to = 50;
...@@ -50,71 +50,25 @@ WriteHSCXCMDR(struct BCState *bcs, u8 data) ...@@ -50,71 +50,25 @@ WriteHSCXCMDR(struct BCState *bcs, u8 data)
static void static void
hscx_empty_fifo(struct BCState *bcs, int count) hscx_empty_fifo(struct BCState *bcs, int count)
{ {
u8 *ptr; recv_empty_fifo_b(bcs, count);
struct IsdnCardState *cs = bcs->cs;
if ((cs->debug & L1_DEB_HSCX) && !(cs->debug & L1_DEB_HSCX_FIFO))
debugl1(cs, "hscx_empty_fifo");
if (bcs->hw.hscx.rcvidx + count > HSCX_BUFMAX) {
if (cs->debug & L1_DEB_WARN)
debugl1(cs, "hscx_empty_fifo: incoming packet too large");
WriteHSCXCMDR(bcs, 0x80); WriteHSCXCMDR(bcs, 0x80);
bcs->hw.hscx.rcvidx = 0;
return;
}
ptr = bcs->hw.hscx.rcvbuf + bcs->hw.hscx.rcvidx;
bcs->hw.hscx.rcvidx += count;
hscx_read_fifo(bcs, ptr, count);
WriteHSCXCMDR(bcs, 0x80);
if (cs->debug & L1_DEB_HSCX_FIFO) {
char *t = bcs->blog;
t += sprintf(t, "hscx_empty_fifo %c cnt %d",
bcs->hw.hscx.hscx ? 'B' : 'A', count);
QuickHex(t, ptr, count);
debugl1(cs, bcs->blog);
}
} }
void static void
hscx_fill_fifo(struct BCState *bcs) hscx_fill_fifo(struct BCState *bcs)
{ {
struct IsdnCardState *cs = bcs->cs; struct IsdnCardState *cs = bcs->cs;
int more, count; int more, count;
int fifo_size = test_bit(HW_IPAC, &cs->HW_Flags)? 64: 32; int fifo_size = test_bit(HW_IPAC, &cs->HW_Flags)? 64: 32;
u8 *ptr; u8 *p;
if ((cs->debug & L1_DEB_HSCX) && !(cs->debug & L1_DEB_HSCX_FIFO))
debugl1(cs, "hscx_fill_fifo");
if (!bcs->tx_skb) p = xmit_fill_fifo_b(bcs, fifo_size, &count, &more);
if (!p)
return; return;
if (bcs->tx_skb->len <= 0)
return;
more = (bcs->mode == L1_MODE_TRANS) ? 1 : 0;
if (bcs->tx_skb->len > fifo_size) {
more = !0;
count = fifo_size;
} else
count = bcs->tx_skb->len;
waitforXFW(bcs); waitforXFW(bcs);
ptr = bcs->tx_skb->data; hscx_write_fifo(bcs, p, count);
skb_pull(bcs->tx_skb, count);
bcs->tx_cnt -= count;
bcs->count += count;
hscx_write_fifo(bcs, ptr, count);
WriteHSCXCMDR(bcs, more ? 0x8 : 0xa); WriteHSCXCMDR(bcs, more ? 0x8 : 0xa);
if (cs->debug & L1_DEB_HSCX_FIFO) {
char *t = bcs->blog;
t += sprintf(t, "hscx_fill_fifo %c cnt %d",
bcs->hw.hscx.hscx ? 'B' : 'A', count);
QuickHex(t, ptr, count);
debugl1(cs, bcs->blog);
}
} }
static inline void static inline void
...@@ -122,7 +76,6 @@ hscx_interrupt(struct IsdnCardState *cs, u8 val, u8 hscx) ...@@ -122,7 +76,6 @@ hscx_interrupt(struct IsdnCardState *cs, u8 val, u8 hscx)
{ {
u8 r; u8 r;
struct BCState *bcs = cs->bcs + hscx; struct BCState *bcs = cs->bcs + hscx;
struct sk_buff *skb;
int fifo_size = test_bit(HW_IPAC, &cs->HW_Flags)? 64: 32; int fifo_size = test_bit(HW_IPAC, &cs->HW_Flags)? 64: 32;
int count; int count;
...@@ -155,39 +108,19 @@ hscx_interrupt(struct IsdnCardState *cs, u8 val, u8 hscx) ...@@ -155,39 +108,19 @@ hscx_interrupt(struct IsdnCardState *cs, u8 val, u8 hscx)
#endif #endif
} }
WriteHSCXCMDR(bcs, 0x80); WriteHSCXCMDR(bcs, 0x80);
bcs->rcvidx = 0;
} else { } else {
count = hscx_read(bcs, HSCX_RBCL) & ( count = hscx_read(bcs, HSCX_RBCL) & (fifo_size-1);
test_bit(HW_IPAC, &cs->HW_Flags)? 0x3f: 0x1f);
if (count == 0) if (count == 0)
count = fifo_size; count = fifo_size;
hscx_empty_fifo(bcs, count); hscx_empty_fifo(bcs, count);
if ((count = bcs->hw.hscx.rcvidx - 1) > 0) { recv_rme_b(bcs);
if (cs->debug & L1_DEB_HSCX_FIFO)
debugl1(cs, "HX Frame %d", count);
if (!(skb = dev_alloc_skb(count)))
printk(KERN_WARNING "HSCX: receive out of memory\n");
else {
memcpy(skb_put(skb, count), bcs->hw.hscx.rcvbuf, count);
skb_queue_tail(&bcs->rqueue, skb);
}
} }
} }
bcs->hw.hscx.rcvidx = 0;
sched_b_event(bcs, B_RCVBUFREADY);
}
if (val & 0x40) { /* RPF */ if (val & 0x40) { /* RPF */
hscx_empty_fifo(bcs, fifo_size); hscx_empty_fifo(bcs, fifo_size);
if (bcs->mode == L1_MODE_TRANS) { recv_rpf_b(bcs);
/* receive audio data */
if (!(skb = dev_alloc_skb(fifo_size)))
printk(KERN_WARNING "HiSax: receive out of memory\n");
else {
memcpy(skb_put(skb, fifo_size), bcs->hw.hscx.rcvbuf, fifo_size);
skb_queue_tail(&bcs->rqueue, skb);
}
bcs->hw.hscx.rcvidx = 0;
sched_b_event(bcs, B_RCVBUFREADY);
}
} }
if (val & 0x10) { if (val & 0x10) {
xmit_xpr_b(bcs); xmit_xpr_b(bcs);
...@@ -203,11 +136,9 @@ reset_xmit(struct BCState *bcs) ...@@ -203,11 +136,9 @@ reset_xmit(struct BCState *bcs)
void void
hscx_int_main(struct IsdnCardState *cs, u8 val) hscx_int_main(struct IsdnCardState *cs, u8 val)
{ {
u8 exval; u8 exval;
struct BCState *bcs; struct BCState *bcs;
spin_lock(&cs->lock);
if (val & 0x01) { if (val & 0x01) {
bcs = cs->bcs + 1; bcs = cs->bcs + 1;
exval = hscx_read(bcs, HSCX_EXIR); exval = hscx_read(bcs, HSCX_EXIR);
...@@ -238,5 +169,57 @@ hscx_int_main(struct IsdnCardState *cs, u8 val) ...@@ -238,5 +169,57 @@ hscx_int_main(struct IsdnCardState *cs, u8 val)
debugl1(cs, "HSCX A interrupt %x", exval); debugl1(cs, "HSCX A interrupt %x", exval);
hscx_interrupt(cs, exval, 0); hscx_interrupt(cs, exval, 0);
} }
}
/* ====================================================================== */
static inline u8
isac_read(struct IsdnCardState *cs, u8 addr)
{
return cs->dc_hw_ops->read_reg(cs, addr);
}
static inline void
isac_write(struct IsdnCardState *cs, u8 addr, u8 val)
{
cs->dc_hw_ops->write_reg(cs, addr, val);
}
void
hscxisac_irq(int intno, void *dev_id, struct pt_regs *regs)
{
struct IsdnCardState *cs = dev_id;
u8 val;
int count = 0;
spin_lock(&cs->lock);
val = hscx_read(&cs->bcs[1], HSCX_ISTA);
Start_HSCX:
if (val)
hscx_int_main(cs, val);
val = isac_read(cs, ISAC_ISTA);
Start_ISAC:
if (val)
isac_interrupt(cs, val);
count++;
val = hscx_read(&cs->bcs[1], HSCX_ISTA);
if (val && count < 5) {
if (cs->debug & L1_DEB_HSCX)
debugl1(cs, "HSCX IntStat after IntRoutine");
goto Start_HSCX;
}
val = isac_read(cs, ISAC_ISTA);
if (val && count < 5) {
if (cs->debug & L1_DEB_ISAC)
debugl1(cs, "ISAC IntStat after IntRoutine");
goto Start_ISAC;
}
hscx_write(&cs->bcs[0], HSCX_MASK, 0xFF);
hscx_write(&cs->bcs[1], HSCX_MASK, 0xFF);
isac_write(cs, ISAC_MASK, 0xFF);
isac_write(cs, ISAC_MASK, 0x0);
hscx_write(&cs->bcs[0], HSCX_MASK, 0x0);
hscx_write(&cs->bcs[1], HSCX_MASK, 0x0);
spin_unlock(&cs->lock); spin_unlock(&cs->lock);
} }
...@@ -23,7 +23,6 @@ ...@@ -23,7 +23,6 @@
#define DBUSY_TIMER_VALUE 80 #define DBUSY_TIMER_VALUE 80
#define ARCOFI_USE 0 #define ARCOFI_USE 0
static spinlock_t icc_lock = SPIN_LOCK_UNLOCKED;
static inline u8 static inline u8
icc_read_reg(struct IsdnCardState *cs, u8 addr) icc_read_reg(struct IsdnCardState *cs, u8 addr)
...@@ -137,33 +136,8 @@ icc_bh(void *data) ...@@ -137,33 +136,8 @@ icc_bh(void *data)
void void
icc_empty_fifo(struct IsdnCardState *cs, int count) icc_empty_fifo(struct IsdnCardState *cs, int count)
{ {
u8 *ptr; recv_empty_fifo_d(cs, count);
unsigned long flags;
if ((cs->debug & L1_DEB_ISAC) && !(cs->debug & L1_DEB_ISAC_FIFO))
debugl1(cs, "icc_empty_fifo");
if ((cs->rcvidx + count) >= MAX_DFRAME_LEN_L1) {
if (cs->debug & L1_DEB_WARN)
debugl1(cs, "icc_empty_fifo overrun %d",
cs->rcvidx + count);
icc_write_reg(cs, ICC_CMDR, 0x80); icc_write_reg(cs, ICC_CMDR, 0x80);
cs->rcvidx = 0;
return;
}
ptr = cs->rcvbuf + cs->rcvidx;
cs->rcvidx += count;
spin_lock_irqsave(&icc_lock, flags);
icc_read_fifo(cs, ptr, count);
icc_write_reg(cs, ICC_CMDR, 0x80);
spin_unlock_irqrestore(&icc_lock, flags);
if (cs->debug & L1_DEB_ISAC_FIFO) {
char *t = cs->dlog;
t += sprintf(t, "icc_empty_fifo cnt %d", count);
QuickHex(t, ptr, count);
debugl1(cs, cs->dlog);
}
} }
static void static void
...@@ -171,13 +145,11 @@ icc_fill_fifo(struct IsdnCardState *cs) ...@@ -171,13 +145,11 @@ icc_fill_fifo(struct IsdnCardState *cs)
{ {
int count, more; int count, more;
unsigned char *p; unsigned char *p;
unsigned long flags;
p = xmit_fill_fifo_d(cs, 32, &count, &more); p = xmit_fill_fifo_d(cs, 32, &count, &more);
if (!p) if (!p)
return; return;
spin_lock_irqsave(&icc_lock, flags);
icc_write_fifo(cs, p, count); icc_write_fifo(cs, p, count);
icc_write_reg(cs, ICC_CMDR, more ? 0x8 : 0xa); icc_write_reg(cs, ICC_CMDR, more ? 0x8 : 0xa);
if (test_and_set_bit(FLG_DBUSY_TIMER, &cs->HW_Flags)) { if (test_and_set_bit(FLG_DBUSY_TIMER, &cs->HW_Flags)) {
...@@ -187,16 +159,13 @@ icc_fill_fifo(struct IsdnCardState *cs) ...@@ -187,16 +159,13 @@ icc_fill_fifo(struct IsdnCardState *cs)
init_timer(&cs->dbusytimer); init_timer(&cs->dbusytimer);
cs->dbusytimer.expires = jiffies + ((DBUSY_TIMER_VALUE * HZ)/1000); cs->dbusytimer.expires = jiffies + ((DBUSY_TIMER_VALUE * HZ)/1000);
add_timer(&cs->dbusytimer); add_timer(&cs->dbusytimer);
spin_unlock_irqrestore(&icc_lock, flags);
} }
void void
icc_interrupt(struct IsdnCardState *cs, u8 val) icc_interrupt(struct IsdnCardState *cs, u8 val)
{ {
u8 exval, v1; u8 exval, v1;
struct sk_buff *skb;
unsigned int count; unsigned int count;
unsigned long flags;
if (cs->debug & L1_DEB_ISAC) if (cs->debug & L1_DEB_ISAC)
debugl1(cs, "ICC interrupt %x", val); debugl1(cs, "ICC interrupt %x", val);
...@@ -218,25 +187,14 @@ icc_interrupt(struct IsdnCardState *cs, u8 val) ...@@ -218,25 +187,14 @@ icc_interrupt(struct IsdnCardState *cs, u8 val)
#endif #endif
} }
icc_write_reg(cs, ICC_CMDR, 0x80); icc_write_reg(cs, ICC_CMDR, 0x80);
cs->rcvidx = 0;
} else { } else {
count = icc_read_reg(cs, ICC_RBCL) & 0x1f; count = icc_read_reg(cs, ICC_RBCL) & 0x1f;
if (count == 0) if (count == 0)
count = 32; count = 32;
icc_empty_fifo(cs, count); icc_empty_fifo(cs, count);
spin_lock_irqsave(&icc_lock, flags); recv_rme_d(cs);
if ((count = cs->rcvidx) > 0) {
cs->rcvidx = 0;
if (!(skb = alloc_skb(count, GFP_ATOMIC)))
printk(KERN_WARNING "HiSax: D receive out of memory\n");
else {
memcpy(skb_put(skb, count), cs->rcvbuf, count);
skb_queue_tail(&cs->rq, skb);
}
}
spin_unlock_irqrestore(&icc_lock, flags);
} }
cs->rcvidx = 0;
sched_d_event(cs, D_RCVBUFREADY);
} }
if (val & 0x40) { /* RPF */ if (val & 0x40) { /* RPF */
icc_empty_fifo(cs, 32); icc_empty_fifo(cs, 32);
...@@ -485,10 +443,11 @@ ICC_l1hw(struct PStack *st, int pr, void *arg) ...@@ -485,10 +443,11 @@ ICC_l1hw(struct PStack *st, int pr, void *arg)
} }
} }
void static int
setstack_icc(struct PStack *st, struct IsdnCardState *cs) setstack_icc(struct PStack *st, struct IsdnCardState *cs)
{ {
st->l1.l1hw = ICC_l1hw; st->l1.l1hw = ICC_l1hw;
return 0;
} }
void void
...@@ -534,25 +493,27 @@ dbusy_timer_handler(struct IsdnCardState *cs) ...@@ -534,25 +493,27 @@ dbusy_timer_handler(struct IsdnCardState *cs)
debugl1(cs, "D-Channel Busy no skb"); debugl1(cs, "D-Channel Busy no skb");
} }
icc_write_reg(cs, ICC_CMDR, 0x01); /* Transmitter reset */ icc_write_reg(cs, ICC_CMDR, 0x01); /* Transmitter reset */
cs->irq_func(cs->irq, cs, NULL); cs->card_ops->irq_func(cs->irq, cs, NULL); /* FIXME? */
} }
} }
} }
static struct dc_l1_ops icc_l1_ops = {
.fill_fifo = icc_fill_fifo,
.open = setstack_icc,
.close = DC_Close_icc,
.bh_func = icc_bh,
.dbusy_func = dbusy_timer_handler,
};
void __init void __init
initicc(struct IsdnCardState *cs) initicc(struct IsdnCardState *cs)
{ {
int val, eval; int val, eval;
INIT_WORK(&cs->work, icc_bh, cs); dc_l1_init(cs, &icc_l1_ops);
cs->setstack_d = setstack_icc;
cs->DC_Send_Data = icc_fill_fifo;
cs->DC_Close = DC_Close_icc;
cs->dc.icc.mon_tx = NULL; cs->dc.icc.mon_tx = NULL;
cs->dc.icc.mon_rx = NULL; cs->dc.icc.mon_rx = NULL;
cs->dbusytimer.function = (void *) dbusy_timer_handler;
cs->dbusytimer.data = (long) cs;
init_timer(&cs->dbusytimer);
val = icc_read_reg(cs, ICC_STAR); val = icc_read_reg(cs, ICC_STAR);
debugl1(cs, "ICC STAR %x", val); debugl1(cs, "ICC STAR %x", val);
......
#include "hisax.h"
#include "isdnl1.h"
#include "ipac.h"
#include "hscx.h"
#include "isac.h"
static inline u8
ipac_dc_read(struct IsdnCardState *cs, u8 addr)
{
return cs->dc_hw_ops->read_reg(cs, addr);
}
static inline void
ipac_dc_write(struct IsdnCardState *cs, u8 addr, u8 val)
{
cs->dc_hw_ops->write_reg(cs, addr, val);
}
static inline u8
ipac_bc_read(struct IsdnCardState *cs, int hscx, u8 addr)
{
return cs->bc_hw_ops->read_reg(cs, hscx, addr);
}
static inline void
ipac_bc_write(struct IsdnCardState *cs, int hscx, u8 addr, u8 val)
{
cs->bc_hw_ops->write_reg(cs, hscx, addr, val);
}
static inline u8
ipac_read(struct IsdnCardState *cs, u8 offset)
{
return ipac_dc_read(cs, offset - 0x80);
}
static inline void
ipac_write(struct IsdnCardState *cs, u8 offset, u8 value)
{
ipac_dc_write(cs, offset - 0x80, value);
}
void
ipac_init(struct IsdnCardState *cs)
{
set_bit(HW_IPAC, &cs->HW_Flags);
inithscxisac(cs);
}
void
ipac_irq(int intno, void *dev_id, struct pt_regs *regs)
{
struct IsdnCardState *cs = dev_id;
u8 ista, val, icnt = 5;
spin_lock(&cs->lock);
ista = ipac_read(cs, IPAC_ISTA);
Start_IPAC:
if (cs->debug & L1_DEB_IPAC)
debugl1(cs, "IPAC ISTA %02X", ista);
if (ista & 0x0f) {
val = ipac_bc_read(cs, 1, HSCX_ISTA);
if (ista & 0x01)
val |= 0x01;
if (ista & 0x04)
val |= 0x02;
if (ista & 0x08)
val |= 0x04;
if (val)
hscx_int_main(cs, val);
}
if (ista & 0x20) {
val = ipac_dc_read(cs, ISAC_ISTA) & 0xfe;
if (val) {
isac_interrupt(cs, val);
}
}
if (ista & 0x10) {
val = 0x01;
isac_interrupt(cs, val);
}
ista = ipac_read(cs, IPAC_ISTA);
if ((ista & 0x3f) && icnt) {
icnt--;
goto Start_IPAC;
}
if (!icnt)
printk(KERN_WARNING "IRQ LOOP\n");
ipac_write(cs, IPAC_MASK, 0xFF);
ipac_write(cs, IPAC_MASK, 0xC0);
spin_unlock(&cs->lock);
}
...@@ -27,3 +27,74 @@ ...@@ -27,3 +27,74 @@
#define IPAC_PCFG 0xCA #define IPAC_PCFG 0xCA
#define IPAC_SCFG 0xCB #define IPAC_SCFG 0xCB
#define IPAC_TIMR2 0xCC #define IPAC_TIMR2 0xCC
void ipac_init(struct IsdnCardState *cs);
void ipac_irq(int intno, void *dev_id, struct pt_regs *regs);
/* Macro to build the needed D- and B-Channel access routines given
* access functions for the IPAC */
#define BUILD_IPAC_OPS(ipac) \
\
static u8 \
ipac ## _dc_read(struct IsdnCardState *cs, u8 offset) \
{ \
return ipac ## _read(cs, offset+0x80); \
} \
\
static void \
ipac ## _dc_write(struct IsdnCardState *cs, u8 offset, u8 value) \
{ \
ipac ## _write(cs, offset+0x80, value); \
} \
\
static void \
ipac ## _dc_read_fifo(struct IsdnCardState *cs, u8 * data, int size) \
{ \
ipac ## _readfifo(cs, 0x80, data, size); \
} \
\
static void \
ipac ## _dc_write_fifo(struct IsdnCardState *cs, u8 * data, int size) \
{ \
ipac ## _writefifo(cs, 0x80, data, size); \
} \
\
static struct dc_hw_ops ipac ## _dc_ops = { \
.read_reg = ipac ## _dc_read, \
.write_reg = ipac ## _dc_write, \
.read_fifo = ipac ## _dc_read_fifo, \
.write_fifo = ipac ## _dc_write_fifo, \
}; \
\
static u8 \
ipac ## _bc_read(struct IsdnCardState *cs, int hscx, u8 offset) \
{ \
return ipac ## _read(cs, offset + (hscx ? 0x40 : 0)); \
} \
\
static void \
ipac ## _bc_write(struct IsdnCardState *cs, int hscx, u8 offset, u8 value) \
{ \
ipac ## _write(cs, offset + (hscx ? 0x40 : 0), value); \
} \
\
static void \
ipac ## _bc_read_fifo(struct IsdnCardState *cs, int hscx, u8 *data, int size) \
{ \
ipac ## _readfifo(cs, hscx ? 0x40 : 0, data, size); \
} \
\
static void \
ipac ## _bc_write_fifo(struct IsdnCardState *cs, int hscx, u8 *data, int size)\
{ \
ipac ## _writefifo(cs, hscx ? 0x40 : 0, data, size); \
} \
\
static struct bc_hw_ops ipac ## _bc_ops = { \
.read_reg = ipac ## _bc_read, \
.write_reg = ipac ## _bc_write, \
.read_fifo = ipac ## _bc_read_fifo, \
.write_fifo = ipac ## _bc_write_fifo, \
}
This diff is collapsed.
...@@ -157,6 +157,5 @@ ...@@ -157,6 +157,5 @@
extern void init_ipacx(struct IsdnCardState *cs, int part); extern void init_ipacx(struct IsdnCardState *cs, int part);
extern void interrupt_ipacx(struct IsdnCardState *cs); extern void interrupt_ipacx(struct IsdnCardState *cs);
extern void ipacx_fill_fifo(struct BCState *bcs);
#endif #endif
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
...@@ -132,7 +132,5 @@ extern void jade_sched_event(struct BCState *bcs, int event); ...@@ -132,7 +132,5 @@ extern void jade_sched_event(struct BCState *bcs, int event);
extern void modejade(struct BCState *bcs, int mode, int bc); extern void modejade(struct BCState *bcs, int mode, int bc);
extern void initjade(struct IsdnCardState *cs); extern void initjade(struct IsdnCardState *cs);
extern void jade_int_main(struct IsdnCardState *cs, u_char val, int jade); extern void jade_int_main(struct IsdnCardState *cs, u_char val, int jade);
extern void jade_fill_fifo(struct BCState *bcs);
#endif /* __JADE_H__ */ #endif /* __JADE_H__ */
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
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