Commit 811b6a3b authored by Linus Torvalds's avatar Linus Torvalds

Merge http://linux-isdn.bkbits.net/linux-2.5.isdn

into home.transmeta.com:/home/torvalds/v2.5/linux
parents b18e5d6c c29fba8a
......@@ -51,9 +51,6 @@ static int __init divert_init(void)
printk(KERN_WARNING "dss1_divert: error %d registering module, not loaded\n",i);
return(-EIO);
}
#if (LINUX_VERSION_CODE < 0x020111)
register_symtab(0);
#endif
printk(KERN_INFO "dss1_divert module successfully installed\n");
return(0);
}
......
......@@ -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_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_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_DIEHLDIVA) += diva.o isac.o arcofi.o hscx.o ipacx.o
hisax-objs-$(CONFIG_HISAX_ASUSCOM) += asuscom.o isac.o arcofi.o hscx.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 ipac.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_MIC) += mic.o isac.o arcofi.o hscx.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
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_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_GAZEL) += gazel.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 ipac.o
hisax-objs-$(CONFIG_HISAX_W6692) += w6692.o
hisax-objs-$(CONFIG_HISAX_ENTERNOW_PCI) += enternow_pci.o amd7930_fn.o
#hisax-objs-$(CONFIG_HISAX_TESTEMU) += testemu.o
......
......@@ -659,7 +659,7 @@ Amd7930_l1hw(struct PStack *st, int pr, void *arg)
}
}
void
static int
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");
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
dbusy_timer_handler(struct IsdnCardState *cs)
{
......@@ -723,7 +716,7 @@ dbusy_timer_handler(struct IsdnCardState *cs)
/* Transmitter reset, abort transmit */
wByteAMD(cs, 0x21, 0x82);
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)
debugl1(cs, "Amd7930: dbusy_timer_handler: Transmitter reset");
......@@ -764,26 +757,26 @@ static u16 initAMD[] = {
0xFFFF};
static struct dc_l1_ops amd7930_l1_ops = {
.open = setstack_Amd7930,
.bh_func = Amd7930_bh,
.dbusy_func = dbusy_timer_handler,
};
void __devinit
Amd7930_init(struct IsdnCardState *cs)
{
u16 *ptr;
u8 cmd, cnt;
u16 *ptr;
u8 cmd, cnt;
if (cs->debug & L1_DEB_ISAC)
debugl1(cs, "Amd7930: initamd called");
dc_l1_init(cs, &amd7930_l1_ops);
cs->dc.amd7930.tx_xmtlen = 0;
cs->dc.amd7930.old_state = 0;
cs->dc.amd7930.lmr1 = 0x40;
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 */
for (ptr = initAMD; *ptr != 0xFFFF; ) {
......
......@@ -113,37 +113,6 @@ static struct dc_hw_ops isac_ops = {
.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
hscx_read(struct IsdnCardState *cs, int hscx, u8 offset)
{
......@@ -175,141 +144,106 @@ static struct bc_hw_ops hscx_ops = {
.write_fifo = hscx_write_fifo,
};
static void
asuscom_interrupt(int intno, void *dev_id, struct pt_regs *regs)
static inline u8
ipac_read(struct IsdnCardState *cs, u8 off)
{
struct IsdnCardState *cs = dev_id;
u8 val;
u8 ret;
unsigned long flags;
spin_lock(&cs->lock);
val = hscx_read(cs, 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);
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);
spin_lock_irqsave(&asuscom_lock, flags);
byteout(cs->hw.asus.adr, off);
ret = bytein(cs->hw.asus.isac);
spin_unlock_irqrestore(&asuscom_lock, flags);
return ret;
}
static void
asuscom_interrupt_ipac(int intno, void *dev_id, struct pt_regs *regs)
static inline void
ipac_write(struct IsdnCardState *cs, u8 off, u8 data)
{
struct IsdnCardState *cs = dev_id;
u8 ista, val, icnt = 5;
unsigned long flags;
if (!cs) {
printk(KERN_WARNING "ISDNLink: Spurious interrupt!\n");
return;
}
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);
spin_lock_irqsave(&asuscom_lock, flags);
byteout(cs->hw.asus.adr, off);
byteout(cs->hw.asus.isac, data);
spin_unlock_irqrestore(&asuscom_lock, flags);
}
void
release_io_asuscom(struct IsdnCardState *cs)
static inline void
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
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);
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);
schedule_timeout((10*HZ)/1000);
if (cs->subtyp == ASUS_IPAC) {
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_AOE, 0x0);
writereg(cs, cs->hw.asus.isac, IPAC_MASK, 0xc0);
writereg(cs, cs->hw.asus.isac, IPAC_PCFG, 0x12);
}
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_ACFG, 0xff);
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_PCFG, 0x12);
return 0;
}
static int
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);
}
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__
static struct isapnp_device_id asus_ids[] __initdata = {
{ ISAPNP_VENDOR('A', 'S', 'U'), ISAPNP_FUNCTION(0x1688),
......@@ -396,36 +330,36 @@ setup_asuscom(struct IsdnCard *card)
}
printk(KERN_INFO "ISDNLink: defined at 0x%x IRQ %d\n",
cs->hw.asus.cfg_reg, cs->irq);
cs->bc_hw_ops = &hscx_ops;
cs->cardmsg = &Asus_card_msg;
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);
if ((val == 1) || (val == 2)) {
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.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->irq_func = &asuscom_interrupt_ipac;
cs->bc_hw_ops = &ipac_bc_ops;
printk(KERN_INFO "Asus: IPAC version %x\n", val);
} else {
cs->subtyp = ASUS_ISACHSCX;
cs->card_ops = &asuscom_ops;
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.hscx = cs->hw.asus.cfg_reg + ASUS_HSCX;
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->dc_hw_ops = &isac_ops;
cs->irq_func = &asuscom_interrupt;
cs->bc_hw_ops = &hscx_ops;
ISACVersion(cs, "ISDNLink:");
if (HscxVersion(cs, "ISDNLink:")) {
printk(KERN_WARNING
"ISDNLink: wrong HSCX versions check IO address\n");
release_io_asuscom(cs);
asuscom_release(cs);
return (0);
}
}
printk(KERN_INFO "ISDNLink: resetting card\n");
reset_asuscom(cs);
cs->card_ops->reset(cs);
return (1);
}
......@@ -167,23 +167,29 @@ release_ioregs(struct IsdnCardState *cs, int mask)
static int
AVM_card_msg(struct IsdnCardState *cs, int mt, void *arg)
{
switch (mt) {
case CARD_RESET:
return(0);
case CARD_RELEASE:
release_ioregs(cs, 0x3f);
return(0);
case CARD_INIT:
byteout(cs->hw.avm.cfg_reg, 0x16);
byteout(cs->hw.avm.cfg_reg, 0x1E);
inithscxisac(cs);
return(0);
case CARD_TEST:
return(0);
}
return(0);
}
static void
avm_a1_init(struct IsdnCardState *cs)
{
byteout(cs->hw.avm.cfg_reg, 0x16);
byteout(cs->hw.avm.cfg_reg, 0x1E);
inithscxisac(cs);
}
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
setup_avm_a1(struct IsdnCard *card)
{
......@@ -305,7 +311,7 @@ setup_avm_a1(struct IsdnCard *card)
cs->dc_hw_ops = &isac_ops;
cs->bc_hw_ops = &hscx_ops;
cs->cardmsg = &AVM_card_msg;
cs->irq_func = &avm_a1_interrupt;
cs->card_ops = &avm_a1_ops;
ISACVersion(cs, "AVM A1:");
if (HscxVersion(cs, "AVM A1:")) {
printk(KERN_WARNING
......
......@@ -192,36 +192,35 @@ avm_a1p_interrupt(int intno, void *dev_id, struct pt_regs *regs)
static int
AVM_card_msg(struct IsdnCardState *cs, int mt, void *arg)
{
switch (mt) {
case CARD_RESET:
byteout(cs->hw.avm.cfg_reg+ASL0_OFFSET,0x00);
HZDELAY(HZ / 5 + 1);
byteout(cs->hw.avm.cfg_reg+ASL0_OFFSET,ASL0_W_RESET);
HZDELAY(HZ / 5 + 1);
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;
}
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);
HZDELAY(HZ / 5 + 1);
byteout(cs->hw.avm.cfg_reg+ASL0_OFFSET,ASL0_W_RESET);
HZDELAY(HZ / 5 + 1);
byteout(cs->hw.avm.cfg_reg+ASL0_OFFSET,0x00);
return 0;
}
static struct card_ops avm_a1p_ops = {
.init = avm_a1p_init,
.reset = avm_a1p_reset,
.irq_func = avm_a1p_interrupt,
};
int __devinit
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->bc_hw_ops = &hscx_ops;
cs->cardmsg = &AVM_card_msg;
cs->irq_func = &avm_a1p_interrupt;
cs->card_ops = &avm_a1p_ops;
ISACVersion(cs, "AVM A1 PCMCIA:");
if (HscxVersion(cs, "AVM A1 PCMCIA:")) {
......
......@@ -175,6 +175,39 @@ WriteHDLCPnP(struct IsdnCardState *cs, int chan, u8 offset, u8 value)
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
struct BCState *Sel_BCS(struct IsdnCardState *cs, int channel)
{
......@@ -259,52 +292,7 @@ modehdlc(struct BCState *bcs, int mode, int bc)
static inline void
hdlc_empty_fifo(struct BCState *bcs, int count)
{
register u_int *ptr;
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);
}
recv_empty_fifo_b(bcs, count);
}
static void
......@@ -360,15 +348,10 @@ reset_xmit(struct BCState *bcs)
hdlc_fill_fifo(bcs);
}
static struct bc_l1_ops hdlc_l1_ops = {
.fill_fifo = hdlc_fill_fifo,
};
static inline void
HDLC_irq(struct BCState *bcs, u_int stat)
{
int len;
struct sk_buff *skb;
if (bcs->cs->debug & L1_DEB_HSCX)
debugl1(bcs->cs, "ch%d stat %#x", bcs->channel, stat);
......@@ -384,7 +367,7 @@ HDLC_irq(struct BCState *bcs, u_int stat)
write_ctrl(bcs, 1);
bcs->hw.hdlc.ctrl.sr.cmd &= ~HDLC_CMD_RRS;
write_ctrl(bcs, 1);
bcs->hw.hdlc.rcvidx = 0;
bcs->rcvidx = 0;
} else {
if (!(len = (stat & HDLC_STAT_RML_MASK)>>8))
len = 32;
......@@ -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_CRCVFRRAB)==HDLC_STAT_CRCVFR) ||
(bcs->mode == L1_MODE_TRANS)) {
if (!(skb = dev_alloc_skb(bcs->hw.hdlc.rcvidx)))
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);
recv_rme_b(bcs);
} else {
if (bcs->cs->debug & L1_DEB_HSCX)
debugl1(bcs->cs, "invalid frame");
else
debugl1(bcs->cs, "ch%d invalid frame %#x", bcs->channel, stat);
bcs->hw.hdlc.rcvidx = 0;
bcs->rcvidx = 0;
}
}
}
......@@ -492,57 +467,20 @@ void
close_hdlcstate(struct BCState *bcs)
{
modehdlc(bcs, 0, 0);
if (test_and_clear_bit(BC_FLG_INIT, &bcs->Flag)) {
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);
}
}
bc_close(bcs);
}
int
open_hdlcstate(struct IsdnCardState *cs, struct BCState *bcs)
{
if (!test_and_set_bit(BC_FLG_INIT, &bcs->Flag)) {
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);
return bc_open(bcs);
}
int
setstack_hdlc(struct PStack *st, struct BCState *bcs)
{
bcs->channel = st->l1.bc;
bcs->unit = bcs->channel;
if (open_hdlcstate(st->l1.hardware, bcs))
return (-1);
st->l1.bcs = bcs;
......@@ -553,6 +491,12 @@ setstack_hdlc(struct PStack *st, struct BCState *bcs)
return (0);
}
static struct bc_l1_ops hdlc_l1_ops = {
.fill_fifo = hdlc_fill_fifo,
.open = setstack_hdlc,
.close = close_hdlcstate,
};
void __init
inithdlc(struct IsdnCardState *cs)
{
......@@ -582,10 +526,6 @@ inithdlc(struct IsdnCardState *cs)
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, -1, 1);
}
......@@ -616,8 +556,14 @@ avm_pcipnp_interrupt(int intno, void *dev_id, struct pt_regs *regs)
WriteISAC(cs, ISAC_MASK, 0x0);
}
static void
reset_avmpcipnp(struct IsdnCardState *cs)
static int
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");
outb(AVM_STATUS0_RESET | AVM_STATUS0_DIS_TIMER, cs->hw.avm.cfg_reg + 2);
......@@ -628,33 +574,34 @@ reset_avmpcipnp(struct IsdnCardState *cs)
set_current_state(TASK_UNINTERRUPTIBLE);
schedule_timeout((10*HZ)/1000); /* Timeout 10ms */
printk(KERN_INFO "AVM PCI/PnP: S1 %x\n", inb(cs->hw.avm.cfg_reg + 3));
return 0;
}
static int
AVM_card_msg(struct IsdnCardState *cs, int mt, void *arg)
static void
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);
inithdlc(cs);
outb(AVM_STATUS0_DIS_TIMER | AVM_STATUS0_RES_TIMER,
cs->hw.avm.cfg_reg + 2);
outb(AVM_STATUS0_DIS_TIMER | AVM_STATUS0_RES_TIMER |
AVM_STATUS0_ENA_IRQ, cs->hw.avm.cfg_reg + 2);
return(0);
case CARD_TEST:
return(0);
}
return(0);
initisac(cs);
inithdlc(cs);
outb(AVM_STATUS0_DIS_TIMER | AVM_STATUS0_RES_TIMER,
cs->hw.avm.cfg_reg + 2);
outb(AVM_STATUS0_DIS_TIMER | AVM_STATUS0_RES_TIMER |
AVM_STATUS0_ENA_IRQ, cs->hw.avm.cfg_reg + 2);
}
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;
#ifdef __ISAPNP__
static struct pci_bus *bus_avm __initdata = NULL;
......@@ -766,7 +713,7 @@ setup_avm_pcipnp(struct IsdnCard *card)
val = inb(cs->hw.avm.cfg_reg);
ver = inb(cs->hw.avm.cfg_reg + 1);
printk(KERN_INFO "AVM PnP: Class %X Rev %d\n", val, ver);
reset_avmpcipnp(cs);
avm_pcipnp_reset(cs);
break;
}
printk(KERN_INFO "HiSax: %s config irq:%d base:0x%X\n",
......@@ -774,9 +721,10 @@ setup_avm_pcipnp(struct IsdnCard *card)
cs->irq, cs->hw.avm.cfg_reg);
cs->dc_hw_ops = &isac_ops;
cs->bc_hw_ops = &hdlc_hw_ops;
cs->bc_l1_ops = &hdlc_l1_ops;
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:");
return (1);
}
......@@ -233,30 +233,42 @@ reset_bkm(struct IsdnCardState *cs)
static int
BKM_card_msg(struct IsdnCardState *cs, int mt, void *arg)
{
switch (mt) {
case CARD_RESET:
/* Disable ints */
enable_bkm_int(cs, 0);
reset_bkm(cs);
return (0);
case CARD_RELEASE:
/* Sanity */
enable_bkm_int(cs, 0);
reset_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 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 */
enable_bkm_int(cs, 0);
reset_bkm(cs);
return 0;
}
static void
bkm_a4t_release(struct IsdnCardState *cs)
{
enable_bkm_int(cs, 0);
reset_bkm(cs);
release_io_bkm(cs);
}
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;
int __init
......@@ -335,8 +347,8 @@ setup_bkm_a4t(struct IsdnCard *card)
cs->dc_hw_ops = &isac_ops;
cs->bc_hw_ops = &jade_ops;
cs->cardmsg = &BKM_card_msg;
cs->irq_func = &bkm_interrupt;
cs->irq_flags |= SA_SHIRQ;
cs->card_ops = &bkm_a4t_ops;
ISACVersion(cs, "Telekom A4T:");
/* Jade version */
JadeVersion(cs, "Telekom A4T:");
......
......@@ -42,7 +42,7 @@ static const char *sct_quadro_subtypes[] =
#define wordin(addr) inw(addr)
static inline u8
readreg(struct IsdnCardState *cs, u8 off)
ipac_read(struct IsdnCardState *cs, u8 off)
{
u8 ret;
unsigned long flags;
......@@ -51,13 +51,14 @@ readreg(struct IsdnCardState *cs, u8 off)
wordout(cs->hw.ax.base, off);
ret = wordin(cs->hw.ax.data_adr) & 0xFF;
spin_unlock_irqrestore(&bkm_a8_lock, flags);
return (ret);
return ret;
}
static inline void
writereg(struct IsdnCardState *cs, u8 off, u8 data)
ipac_write(struct IsdnCardState *cs, u8 off, u8 data)
{
unsigned long flags;
spin_lock_irqsave(&bkm_a8_lock, flags);
wordout(cs->hw.ax.base, off);
wordout(cs->hw.ax.data_adr, data);
......@@ -65,7 +66,7 @@ writereg(struct IsdnCardState *cs, u8 off, u8 data)
}
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;
......@@ -75,7 +76,7 @@ readfifo(struct IsdnCardState *cs, u8 off, u8 *data, int size)
}
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;
......@@ -84,127 +85,19 @@ writefifo(struct IsdnCardState *cs, u8 off, u8 *data, int size)
wordout(cs->hw.ax.data_adr, data[i]);
}
static u8
ipac_dc_read(struct IsdnCardState *cs, u8 offset)
{
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
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,
};
/* This will generate ipac_dc_ops and ipac_bc_ops using the functions
* above */
BUILD_IPAC_OPS(ipac);
/* Set the specific ipac to active */
static void
set_ipac_active(struct IsdnCardState *cs, u_int active)
{
/* 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
release_io_sct_quadro(struct IsdnCardState *cs)
{
......@@ -241,32 +134,44 @@ reset_bkm(struct IsdnCardState *cs)
static int
BKM_card_msg(struct IsdnCardState *cs, int mt, void *arg)
{
switch (mt) {
case CARD_RESET:
/* Disable ints */
set_ipac_active(cs, 0);
enable_bkm_int(cs, 0);
reset_bkm(cs);
return (0);
case CARD_RELEASE:
/* Sanity */
set_ipac_active(cs, 0);
enable_bkm_int(cs, 0);
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 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 */
set_ipac_active(cs, 0);
enable_bkm_int(cs, 0);
reset_bkm(cs);
return 0;
}
static void
bkm_a8_release(struct IsdnCardState *cs)
{
set_ipac_active(cs, 0);
enable_bkm_int(cs, 0);
release_io_sct_quadro(cs);
}
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
sct_alloc_io(u_int adr, u_int len)
{
......@@ -414,7 +319,7 @@ setup_sct_quadro(struct IsdnCard *card)
break;
}
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",
CardType[card->typ],
......@@ -424,17 +329,15 @@ setup_sct_quadro(struct IsdnCard *card)
cs->hw.ax.data_adr,
cs->irq);
test_and_set_bit(HW_IPAC, &cs->HW_Flags);
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->irq_func = &bkm_interrupt_ipac;
cs->card_ops = &bkm_a8_ops;
printk(KERN_INFO "HiSax: %s (%s): IPAC Version %d\n",
CardType[card->typ],
sct_quadro_subtypes[cs->subtyp],
readreg(cs, IPAC_ID));
ipac_read(cs, IPAC_ID));
return (1);
#else
printk(KERN_ERR "HiSax: bkm_a8 only supported on PCI Systems\n");
......
......@@ -853,10 +853,11 @@ CallcFree(void)
static void
release_b_st(struct Channel *chanp)
{
struct IsdnCardState *cs = chanp->cs;
struct PStack *st = chanp->b_st;
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) {
case (ISDN_PROTO_L2_X75I):
releasestack_isdnl2(st);
......@@ -1297,7 +1298,7 @@ init_b_st(struct Channel *chanp, int incoming)
break;
}
chanp->bcs->conmsg = NULL;
if (chanp->bcs->BC_SetStack(st, chanp->bcs))
if (cs->bc_l1_ops->open(st, chanp->bcs))
return (-1);
st->l2.flag = 0;
test_and_set_bit(FLG_LAPB, &st->l2.flag);
......@@ -1457,12 +1458,8 @@ lli_got_fac_req(struct Channel *chanp, capi_msg *cm) {
void
lli_got_manufacturer(struct Channel *chanp, struct IsdnCardState *cs, capi_msg *cm) {
if ((cs->typ == ISDN_CTYPE_ELSA) || (cs->typ == ISDN_CTYPE_ELSA_PNP) ||
(cs->typ == ISDN_CTYPE_ELSA_PCI)) {
if (cs->hw.elsa.MFlag) {
cs->cardmsg(cs, CARD_AUX_IND, cm->para);
}
}
if (cs->card_ops->aux_ind)
cs->card_ops->aux_ind(cs, cm->para);
}
......
......@@ -24,6 +24,7 @@
#include <linux/kernel_stat.h>
#include <linux/workqueue.h>
#include <linux/interrupt.h>
#include "isdnl1.h"
#define HISAX_STATUS_BUFSIZE 4096
#define INCLUDE_INLINE_FUNCS
......@@ -825,9 +826,9 @@ static void closecard(int cardnr)
{
struct IsdnCardState *csta = cards[cardnr].cs;
if (csta->bcs->BC_Close != NULL) {
csta->bcs->BC_Close(csta->bcs + 1);
csta->bcs->BC_Close(csta->bcs);
if (csta->bc_l1_ops->close) {
csta->bc_l1_ops->close(csta->bcs + 1);
csta->bc_l1_ops->close(csta->bcs);
}
skb_queue_purge(&csta->rq);
......@@ -840,11 +841,11 @@ static void closecard(int cardnr)
dev_kfree_skb(csta->tx_skb);
csta->tx_skb = NULL;
}
if (csta->DC_Close != NULL) {
csta->DC_Close(csta);
}
if (csta->cardmsg)
csta->cardmsg(csta, CARD_RELEASE, NULL);
if (csta->dc_l1_ops->close)
csta->dc_l1_ops->close(csta);
if (csta->card_ops->release)
csta->card_ops->release(csta);
if (csta->dbusytimer.function != NULL) // FIXME?
del_timer(&csta->dbusytimer);
ll_unload(csta);
......@@ -854,19 +855,18 @@ static int __devinit init_card(struct IsdnCardState *cs)
{
int irq_cnt, cnt = 3;
if (!cs->irq)
return cs->cardmsg(cs, CARD_INIT, NULL);
cs->card_ops->init(cs);
irq_cnt = kstat_irqs(cs->irq);
printk(KERN_INFO "%s: IRQ %d count %d\n", CardType[cs->typ],
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",
cs->irq);
return 1;
}
while (cnt) {
cs->cardmsg(cs, CARD_INIT, NULL);
cs->card_ops->init(cs);
set_current_state(TASK_UNINTERRUPTIBLE);
/* Timeout 10ms */
schedule_timeout((10 * HZ) / 1000);
......@@ -880,11 +880,13 @@ static int __devinit init_card(struct IsdnCardState *cs)
free_irq(cs->irq, cs);
return 2;
} else {
cs->cardmsg(cs, CARD_RESET, NULL);
if (cs->card_ops->reset)
cs->card_ops->reset(cs);
cnt--;
}
} else {
cs->cardmsg(cs, CARD_TEST, NULL);
if (cs->card_ops->test)
cs->card_ops->test(cs);
return 0;
}
}
......@@ -1747,6 +1749,10 @@ static void hisax_bc_close(struct BCState *bcs);
static void hisax_bh(void *data);
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[],
char *name, int protocol)
{
......@@ -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->cardmsg = hisax_cardmsg;
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;
for (i = 0; i < 2; i++) {
cs->bcs[i].BC_SetStack = hisax_bc_setstack;
cs->bcs[i].BC_Close = hisax_bc_close;
cs->bc_l1_ops->open = hisax_bc_setstack;
cs->bc_l1_ops->close = hisax_bc_close;
for (i = 0; i < 2; i++) {
b_if[i]->ifc.l1l2 = hisax_b_l1l2;
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)
}
}
static struct bc_l1_ops modem_l1_ops = {
.fill_fifo = modem_fill,
};
static void rs_interrupt_elsa(int irq, struct IsdnCardState *cs)
{
int status, iir, msr;
......@@ -424,10 +419,10 @@ close_elsastate(struct BCState *bcs)
{
modehscx(bcs, 0, bcs->channel);
if (test_and_clear_bit(BC_FLG_INIT, &bcs->Flag)) {
if (bcs->hw.hscx.rcvbuf) {
if (bcs->rcvbuf) {
if (bcs->mode != L1_MODE_MODEM)
kfree(bcs->hw.hscx.rcvbuf);
bcs->hw.hscx.rcvbuf = NULL;
kfree(bcs->rcvbuf);
bcs->rcvbuf = NULL;
}
skb_queue_purge(&bcs->rqueue);
skb_queue_purge(&bcs->squeue);
......@@ -597,23 +592,23 @@ setstack_elsa(struct PStack *st, struct BCState *bcs)
if (open_hscxstate(st->l1.hardware, bcs))
return (-1);
st->l1.l2l1 = hscx_l2l1;
// bcs->cs->BC_Send_Data = hscx_fill_fifo;
// bcs->cs->BC_Send_Data = hscx_fill_fifo; FIXME
break;
case L1_MODE_MODEM:
bcs->mode = L1_MODE_MODEM;
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->squeue);
}
bcs->tx_skb = NULL;
test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag);
bcs->event = 0;
bcs->hw.hscx.rcvidx = 0;
bcs->rcvidx = 0;
bcs->tx_cnt = 0;
bcs->cs->hw.elsa.bcs = bcs;
st->l1.l2l1 = modem_l2l1;
bcs->cs->bc_l1_ops = &modem_l1_ops;
// bcs->cs->bc_l1_ops = &modem_l1_ops;
break;
}
st->l1.bcs = bcs;
......@@ -623,13 +618,17 @@ setstack_elsa(struct PStack *st, struct BCState *bcs)
return (0);
}
static struct bc_l1_ops modem_l1_ops = {
.fill_fifo = modem_fill,
.open = setstack_elsa,
.close = close_elsastate,
};
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,
GFP_ATOMIC))) {
printk(KERN_WARNING
......
......@@ -162,19 +162,6 @@ enpci_card_msg(struct IsdnCardState *cs, int mt, void *arg)
debugl1(cs, "enter:now PCI: card_msg: 0x%04X", 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:
/* TEI assigned, LED1 on */
cs->hw.njet.auxd = TJ_AMD_IRQ << 1;
......@@ -218,6 +205,20 @@ enpci_card_msg(struct IsdnCardState *cs, int mt, void *arg)
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
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);
}
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;
......@@ -371,8 +378,8 @@ setup_enternow_pci(struct IsdnCard *card)
cs->dc.amd7930.setIrqMask = &enpci_setIrqMask;
cs->cardmsg = &enpci_card_msg;
cs->irq_func = &enpci_interrupt;
cs->irq_flags |= SA_SHIRQ;
cs->card_ops = &enpci_ops;
return (1);
}
......
This diff is collapsed.
......@@ -824,10 +824,11 @@ HFCD_l1hw(struct PStack *st, int pr, void *arg)
}
}
void
static int
setstack_hfcd(struct PStack *st, struct IsdnCardState *cs)
{
st->l1.l1hw = HFCD_l1hw;
return 0;
}
static void
......@@ -850,25 +851,30 @@ unsigned int __init
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
init2bds0(struct IsdnCardState *cs)
{
cs->setstack_d = setstack_hfcd;
cs->dbusytimer.function = (void *) hfc_dbusy_timer;
cs->dbusytimer.data = (long) cs;
init_timer(&cs->dbusytimer);
INIT_WORK(&cs->work, hfcd_bh, cs);
dc_l1_init(cs, &hfcd_dc_l1_ops);
cs->bc_l1_ops = &hfcd_bc_l1_ops;
if (!cs->hw.hfcD.send)
cs->hw.hfcD.send = init_send_hfcd(16);
if (!cs->bcs[0].hw.hfc.send)
cs->bcs[0].hw.hfc.send = init_send_hfcd(32);
if (!cs->bcs[1].hw.hfc.send)
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 + 1, 0, 1);
}
......
......@@ -546,6 +546,8 @@ init_send(struct BCState *bcs)
static struct bc_l1_ops hfc_l1_ops = {
.fill_fifo = hfc_fill_fifo,
.open = setstack_hfc,
.close = close_hfcstate,
};
void __init
......@@ -554,10 +556,6 @@ inithfc(struct IsdnCardState *cs)
init_send(&cs->bcs[0]);
init_send(&cs->bcs[1]);
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 + 1, 0, 0);
}
......
......@@ -70,8 +70,8 @@ static const PCI_ENTRY id_list[] =
/******************************************/
/* free hardware resources used by driver */
/******************************************/
void
release_io_hfcpci(struct IsdnCardState *cs)
static void
hfcpci_release(struct IsdnCardState *cs)
{
printk(KERN_INFO "HiSax: release hfcpci at %p\n",
cs->hw.hfcpci.pci_io);
......@@ -91,8 +91,8 @@ release_io_hfcpci(struct IsdnCardState *cs)
/* function called to reset the HFC PCI chip. A complete software reset of chip */
/* and fifos is done. */
/********************************************************************************/
static void
reset_hfcpci(struct IsdnCardState *cs)
static int
hfcpci_reset(struct IsdnCardState *cs)
{
pci_disable_device(cs->hw.hfcpci.pdev);
cs->hw.hfcpci.int_m2 = 0; /* interrupt output off ! */
......@@ -159,6 +159,8 @@ reset_hfcpci(struct IsdnCardState *cs)
cs->hw.hfcpci.int_m2 = HFCPCI_IRQ_ENABLE;
Write_hfc(cs, HFCPCI_INT_M2, cs->hw.hfcpci.int_m2);
if (Read_hfc(cs, HFCPCI_INT_S2));
return 0;
}
/***************************************************/
......@@ -1047,10 +1049,11 @@ HFCPCI_l1hw(struct PStack *st, int pr, void *arg)
/***********************************************/
/* called during init setting l1 stack pointer */
/***********************************************/
void
static int
setstack_hfcpci(struct PStack *st, struct IsdnCardState *cs)
{
st->l1.l1hw = HFCPCI_l1hw;
return 0;
}
/***************************************************************/
......@@ -1335,8 +1338,17 @@ hfcpci_bh(void *data)
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,
.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 = {
void __init
inithfcpci(struct IsdnCardState *cs)
{
cs->setstack_d = setstack_hfcpci;
cs->dbusytimer.function = (void *) hfcpci_dbusy_timer;
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;
dc_l1_init(cs, &hfcpci_dc_l1_ops);
cs->bc_l1_ops = &hfcpci_bc_l1_ops;
mode_hfcpci(cs->bcs, 0, 0);
mode_hfcpci(cs->bcs + 1, 0, 1);
}
......@@ -1368,31 +1371,29 @@ inithfcpci(struct IsdnCardState *cs)
static int
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);
case CARD_RELEASE:
release_io_hfcpci(cs);
return (0);
case CARD_INIT:
inithfcpci(cs);
set_current_state(TASK_UNINTERRUPTIBLE);
schedule_timeout((80 * HZ) / 1000); /* Timeout 80ms */
/* now switch timer interrupt off */
cs->hw.hfcpci.int_m1 &= ~HFCPCI_INTS_TIMER;
Write_hfc(cs, HFCPCI_INT_M1, cs->hw.hfcpci.int_m1);
/* reinit mode reg */
Write_hfc(cs, HFCPCI_MST_MODE, cs->hw.hfcpci.mst_m);
return (0);
case CARD_TEST:
return (0);
}
return (0);
}
static void
hfcpci_init(struct IsdnCardState *cs)
{
inithfcpci(cs);
set_current_state(TASK_UNINTERRUPTIBLE);
schedule_timeout((80 * HZ) / 1000); /* Timeout 80ms */
/* now switch timer interrupt off */
cs->hw.hfcpci.int_m1 &= ~HFCPCI_INTS_TIMER;
Write_hfc(cs, HFCPCI_INT_M1, cs->hw.hfcpci.int_m1);
/* reinit mode reg */
Write_hfc(cs, HFCPCI_MST_MODE, cs->hw.hfcpci.mst_m);
}
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 */
static struct pci_dev *dev_hfcpci __initdata = NULL;
......@@ -1476,16 +1477,16 @@ setup_hfcpci(struct IsdnCard *card)
return (0); /* no valid card type */
cs->irq_func = &hfcpci_interrupt;
cs->irq_flags |= SA_SHIRQ;
cs->hw.hfcpci.timer.function = (void *) hfcpci_Timer;
cs->hw.hfcpci.timer.data = (long) cs;
init_timer(&cs->hw.hfcpci.timer);
reset_hfcpci(cs);
hfcpci_reset(cs);
cs->cardmsg = &hfcpci_card_msg;
cs->auxcmd = &hfcpci_auxcmd;
cs->card_ops = &hfcpci_ops;
return (1);
#else
printk(KERN_WARNING "HFC-PCI: NO_PCI_BIOS\n");
......
......@@ -308,8 +308,8 @@ read_fifo(struct IsdnCardState *cs, u8 fifo, int trans_max)
/******************************************/
/* free hardware resources used by driver */
/******************************************/
void
release_io_hfcsx(struct IsdnCardState *cs)
static void
hfcsx_release(struct IsdnCardState *cs)
{
cs->hw.hfcsx.int_m2 = 0; /* interrupt output off ! */
Write_hfc(cs, HFCSX_INT_M2, cs->hw.hfcsx.int_m2);
......@@ -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 */
/* and fifos is done. */
/********************************************************************************/
static void
reset_hfcsx(struct IsdnCardState *cs)
static int
hfcsx_reset(struct IsdnCardState *cs)
{
cs->hw.hfcsx.int_m2 = 0; /* interrupt output off ! */
Write_hfc(cs, HFCSX_INT_M2, cs->hw.hfcsx.int_m2);
......@@ -415,6 +415,7 @@ reset_hfcsx(struct IsdnCardState *cs)
cs->hw.hfcsx.int_m2 = HFCSX_IRQ_ENABLE;
Write_hfc(cs, HFCSX_INT_M2, cs->hw.hfcsx.int_m2);
if (Read_hfc(cs, HFCSX_INT_S2));
return 0;
}
/***************************************************/
......@@ -838,10 +839,11 @@ HFCSX_l1hw(struct PStack *st, int pr, void *arg)
/***********************************************/
/* called during init setting l1 stack pointer */
/***********************************************/
void
static int
setstack_hfcsx(struct PStack *st, struct IsdnCardState *cs)
{
st->l1.l1hw = HFCSX_l1hw;
return 0;
}
/***************************************************************/
......@@ -1112,8 +1114,17 @@ hfcsx_bh(void *data)
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,
.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 = {
void __devinit
inithfcsx(struct IsdnCardState *cs)
{
cs->setstack_d = setstack_hfcsx;
cs->dbusytimer.function = (void *) hfcsx_dbusy_timer;
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;
dc_l1_init(cs, &hfcsx_dc_l1_ops);
cs->bc_l1_ops = &hfcsx_bc_l1_ops;
mode_hfcsx(cs->bcs, 0, 0);
mode_hfcsx(cs->bcs + 1, 0, 1);
}
......@@ -1145,31 +1147,29 @@ inithfcsx(struct IsdnCardState *cs)
static int
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);
case CARD_RELEASE:
release_io_hfcsx(cs);
return (0);
case CARD_INIT:
inithfcsx(cs);
set_current_state(TASK_UNINTERRUPTIBLE);
schedule_timeout((80 * HZ) / 1000); /* Timeout 80ms */
/* now switch timer interrupt off */
cs->hw.hfcsx.int_m1 &= ~HFCSX_INTS_TIMER;
Write_hfc(cs, HFCSX_INT_M1, cs->hw.hfcsx.int_m1);
/* reinit mode reg */
Write_hfc(cs, HFCSX_MST_MODE, cs->hw.hfcsx.mst_m);
return (0);
case CARD_TEST:
return (0);
}
return (0);
}
static void
hfcsx_init(struct IsdnCardState *cs)
{
inithfcsx(cs);
set_current_state(TASK_UNINTERRUPTIBLE);
schedule_timeout((80 * HZ) / 1000); /* Timeout 80ms */
/* now switch timer interrupt off */
cs->hw.hfcsx.int_m1 &= ~HFCSX_INTS_TIMER;
Write_hfc(cs, HFCSX_INT_M1, cs->hw.hfcsx.int_m1);
/* reinit mode reg */
Write_hfc(cs, HFCSX_MST_MODE, cs->hw.hfcsx.mst_m);
}
static struct card_ops hfcsx_ops = {
.init = hfcsx_init,
.reset = hfcsx_reset,
.release = hfcsx_release,
.irq_func = hfcsx_interrupt,
};
#ifdef __ISAPNP__
static struct isapnp_device_id hfc_ids[] __initdata = {
{ ISAPNP_VENDOR('T', 'A', 'G'), ISAPNP_FUNCTION(0x2620),
......@@ -1288,16 +1288,15 @@ setup_hfcsx(struct IsdnCard *card)
} else
return (0); /* no valid card type */
cs->irq_func = &hfcsx_interrupt;
cs->hw.hfcsx.timer.function = (void *) hfcsx_Timer;
cs->hw.hfcsx.timer.data = (long) cs;
cs->hw.hfcsx.b_fifo_size = 0; /* fifo size still unknown */
cs->hw.hfcsx.cirm = ccd_sp_irqtab[cs->irq & 0xF]; /* RAM not evaluated */
init_timer(&cs->hw.hfcsx.timer);
reset_hfcsx(cs);
hfcsx_reset(cs);
cs->cardmsg = &hfcsx_card_msg;
cs->auxcmd = &hfcsx_auxcmd;
cs->card_ops = &hfcsx_ops;
return (1);
}
......@@ -64,8 +64,8 @@ hfcs_Timer(struct IsdnCardState *cs)
*/
}
void
release_io_hfcs(struct IsdnCardState *cs)
static void
hfcs_release(struct IsdnCardState *cs)
{
release2bds0(cs);
del_timer(&cs->hw.hfcD.timer);
......@@ -73,8 +73,8 @@ release_io_hfcs(struct IsdnCardState *cs)
release_region(cs->hw.hfcD.addr, 2);
}
static void
reset_hfcs(struct IsdnCardState *cs)
static int
hfcs_reset(struct IsdnCardState *cs)
{
printk(KERN_INFO "HFCS: resetting card\n");
cs->hw.hfcD.cirm = HFCD_RESET;
......@@ -111,36 +111,35 @@ reset_hfcs(struct IsdnCardState *cs)
hfcs_write_reg(cs, HFCD_DATA, HFCD_MST_MODE, cs->hw.hfcD.mst_m); /* HFC Master */
cs->hw.hfcD.sctrl = 0;
hfcs_write_reg(cs, HFCD_DATA, HFCD_SCTRL, cs->hw.hfcD.sctrl);
return 0;
}
static int
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);
case CARD_RELEASE:
release_io_hfcs(cs);
return(0);
case CARD_INIT:
cs->hw.hfcD.timer.expires = jiffies + 75;
add_timer(&cs->hw.hfcD.timer);
init2bds0(cs);
set_current_state(TASK_UNINTERRUPTIBLE);
schedule_timeout((80*HZ)/1000);
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_MST_MODE, cs->hw.hfcD.mst_m);
return(0);
case CARD_TEST:
return(0);
}
return(0);
}
static void
hfcs_init(struct IsdnCardState *cs)
{
cs->hw.hfcD.timer.expires = jiffies + 75;
add_timer(&cs->hw.hfcD.timer);
init2bds0(cs);
set_current_state(TASK_UNINTERRUPTIBLE);
schedule_timeout((80*HZ)/1000);
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_MST_MODE, cs->hw.hfcD.mst_m);
}
static struct card_ops hfcs_ops = {
.init = hfcs_init,
.reset = hfcs_reset,
.release = hfcs_release,
.irq_func = hfcs_interrupt,
};
#ifdef __ISAPNP__
static struct isapnp_device_id hfc_ids[] __initdata = {
{ ISAPNP_VENDOR('A', 'N', 'X'), ISAPNP_FUNCTION(0x1114),
......@@ -262,8 +261,8 @@ setup_hfcs(struct IsdnCard *card)
cs->hw.hfcD.timer.function = (void *) hfcs_Timer;
cs->hw.hfcD.timer.data = (long) cs;
init_timer(&cs->hw.hfcD.timer);
reset_hfcs(cs);
hfcs_reset(cs);
cs->cardmsg = &hfcs_card_msg;
cs->irq_func = &hfcs_interrupt;
cs->card_ops = &hfcs_ops;
return (1);
}
......@@ -6,6 +6,10 @@
* of the GNU General Public License, incorporated herein by reference.
*
*/
#ifndef __HISAX_H__
#define __HISAX_H__
#include <linux/config.h>
#include <linux/errno.h>
#include <linux/fs.h>
......@@ -46,11 +50,6 @@
#define HW_INFO4_P10 0x0048
#define HW_RSYNC 0x0060
#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_DEACTIVATE 0x0110
......@@ -349,17 +348,12 @@ struct l3_process {
};
struct hscx_hw {
int hscx;
int rcvidx;
u8 *rcvbuf; /* B-Channel receive Buffer */
u8 tsaxr0;
u8 tsaxr1;
};
struct w6692B_hw {
int bchan;
int rcvidx;
u8 *rcvbuf; /* B-Channel receive Buffer */
};
struct isar_reg {
......@@ -407,8 +401,6 @@ struct hdlc_hw {
struct hdlc_stat_reg sr;
} ctrl;
u_int stat;
int rcvidx;
u8 *rcvbuf; /* B-Channel receive Buffer */
};
struct hfcB_hw {
......@@ -479,10 +471,13 @@ struct amd7930_hw {
struct BCState {
int channel;
int mode;
long Flag; /* long req'd for set_bit --RR */
long Flag;
struct IsdnCardState *cs;
int tx_cnt; /* B-Channel transmit counter */
struct sk_buff *tx_skb; /* B-Channel transmit Buffer */
int unit; /* first or second unit (e.g. HSCX) */
int rcvidx;
u8 *rcvbuf; /* B-Channel receive Buffer */
int tx_cnt; /* B-Channel transmit counter */
struct sk_buff *tx_skb; /* B-Channel transmit Buffer */
struct sk_buff_head rqueue; /* B-Channel receive queue */
struct sk_buff_head squeue; /* B-Channel send queue */
struct sk_buff_head cmpl_queue; /* B-Channel send complete queue */
......@@ -492,8 +487,6 @@ struct BCState {
struct timer_list transbusy;
struct work_struct work;
unsigned long event;
int (*BC_SetStack) (struct PStack *, struct BCState *);
void (*BC_Close) (struct BCState *);
#ifdef ERROR_STATISTIC
int err_crc;
int err_tx;
......@@ -861,6 +854,17 @@ struct icc_chip {
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
* chips to the chip drivers */
......@@ -878,10 +882,23 @@ struct dc_hw_ops {
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 {
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
......@@ -900,6 +917,7 @@ struct IsdnCardState {
unsigned char typ;
unsigned char subtyp;
spinlock_t lock;
struct card_ops *card_ops;
int protocol;
unsigned int irq;
unsigned long irq_flags;
......@@ -942,12 +960,9 @@ struct IsdnCardState {
u8 *status_end;
struct dc_hw_ops *dc_hw_ops;
struct bc_hw_ops *bc_hw_ops;
struct dc_l1_ops *dc_l1_ops;
struct bc_l1_ops *bc_l1_ops;
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 *);
struct Channel channel[2+MAX_WAITING_CALLS];
struct BCState bcs[2+MAX_WAITING_CALLS];
......@@ -1363,9 +1378,6 @@ int QuickHex(char *txt, u8 * p, int cnt);
void LogFrame(struct IsdnCardState *cs, u8 * p, int size);
void dlogframe(struct IsdnCardState *cs, struct sk_buff *skb, int dir);
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__ */
#define HZDELAY(jiffs) {int tout = jiffs; while (tout--) udelay(1000000/HZ);}
......@@ -1424,3 +1436,5 @@ L4L3(struct PStack *st, int pr, void *arg)
{
st->l3.l4l3(st, pr, arg);
}
#endif
......@@ -1605,7 +1605,7 @@ static void __devexit hfcpci_remove(struct pci_dev *pdev)
static struct pci_driver hfcpci_driver = {
.name = "hfcpci",
.probe = hfcpci_probe,
.remove = hfcpci_remove,
.remove = __devexit_p(hfcpci_remove),
.id_table = hfcpci_ids,
};
......
......@@ -25,36 +25,24 @@ static inline u8
hscx_read(struct BCState *bcs, u8 addr)
{
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
hscx_write(struct BCState *bcs, u8 addr, u8 val)
{
struct IsdnCardState *cs = bcs->cs;
u8 hscx = bcs->hw.hscx.hscx;
cs->bc_hw_ops->write_reg(cs, hscx, 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);
cs->bc_hw_ops->write_reg(cs, bcs->unit, addr, val);
}
static inline void
hscx_write_fifo(struct BCState *bcs, u8 *p, int len)
{
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
......@@ -67,16 +55,16 @@ HscxVersion(struct IsdnCardState *cs, char *s)
printk(KERN_INFO "%s HSCX version A: %s B: %s\n", s,
HSCXVer[verA], HSCXVer[verB]);
if ((verA == 0) | (verA == 0xf) | (verB == 0) | (verB == 0xf))
return (1);
return 1;
else
return (0);
return 0;
}
void
modehscx(struct BCState *bcs, int mode, int bc)
{
struct IsdnCardState *cs = bcs->cs;
int hscx = bcs->hw.hscx.hscx;
int hscx = bcs->unit;
if (cs->debug & L1_DEB_HSCX)
debugl1(cs, "hscx %c mode %d ichan %d",
......@@ -164,52 +152,17 @@ void
close_hscxstate(struct BCState *bcs)
{
modehscx(bcs, 0, bcs->channel);
if (test_and_clear_bit(BC_FLG_INIT, &bcs->Flag)) {
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);
}
}
bc_close(bcs);
}
int
open_hscxstate(struct IsdnCardState *cs, struct BCState *bcs)
{
if (!test_and_set_bit(BC_FLG_INIT, &bcs->Flag)) {
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);
}
bc_open(bcs);
bcs->tx_skb = NULL;
test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag);
bcs->event = 0;
bcs->hw.hscx.rcvidx = 0;
bcs->rcvidx = 0;
bcs->tx_cnt = 0;
return (0);
}
......@@ -228,8 +181,12 @@ setstack_hscx(struct PStack *st, struct BCState *bcs)
return (0);
}
static void hscx_fill_fifo(struct BCState *bcs);
static struct bc_l1_ops hscx_l1_ops = {
.fill_fifo = hscx_fill_fifo,
.open = setstack_hscx,
.close = close_hscxstate,
};
void __init
......@@ -238,12 +195,8 @@ inithscx(struct IsdnCardState *cs)
int val, eval;
cs->bc_l1_ops = &hscx_l1_ops;
cs->bcs[0].BC_SetStack = setstack_hscx;
cs->bcs[1].BC_SetStack = setstack_hscx;
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].unit = 0;
cs->bcs[1].unit = 1;
cs->bcs[0].hw.hscx.tsaxr0 = 0x2f;
cs->bcs[0].hw.hscx.tsaxr1 = 3;
cs->bcs[1].hw.hscx.tsaxr0 = 0x2f;
......
......@@ -38,4 +38,4 @@ extern int HscxVersion(struct IsdnCardState *cs, char *s);
extern void modehscx(struct BCState *bcs, int mode, int bc);
extern void inithscxisac(struct IsdnCardState *cs);
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)
}
static inline void
static void
waitforXFW(struct BCState *bcs)
{
int to = 50;
......@@ -50,71 +50,25 @@ WriteHSCXCMDR(struct BCState *bcs, u8 data)
static void
hscx_empty_fifo(struct BCState *bcs, int count)
{
u8 *ptr;
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);
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);
recv_empty_fifo_b(bcs, 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)
{
struct IsdnCardState *cs = bcs->cs;
int more, count;
int fifo_size = test_bit(HW_IPAC, &cs->HW_Flags)? 64: 32;
u8 *ptr;
if ((cs->debug & L1_DEB_HSCX) && !(cs->debug & L1_DEB_HSCX_FIFO))
debugl1(cs, "hscx_fill_fifo");
u8 *p;
if (!bcs->tx_skb)
return;
if (bcs->tx_skb->len <= 0)
p = xmit_fill_fifo_b(bcs, fifo_size, &count, &more);
if (!p)
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);
ptr = bcs->tx_skb->data;
skb_pull(bcs->tx_skb, count);
bcs->tx_cnt -= count;
bcs->count += count;
hscx_write_fifo(bcs, ptr, count);
hscx_write_fifo(bcs, p, count);
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
......@@ -122,7 +76,6 @@ hscx_interrupt(struct IsdnCardState *cs, u8 val, u8 hscx)
{
u8 r;
struct BCState *bcs = cs->bcs + hscx;
struct sk_buff *skb;
int fifo_size = test_bit(HW_IPAC, &cs->HW_Flags)? 64: 32;
int count;
......@@ -155,39 +108,19 @@ hscx_interrupt(struct IsdnCardState *cs, u8 val, u8 hscx)
#endif
}
WriteHSCXCMDR(bcs, 0x80);
bcs->rcvidx = 0;
} else {
count = hscx_read(bcs, HSCX_RBCL) & (
test_bit(HW_IPAC, &cs->HW_Flags)? 0x3f: 0x1f);
count = hscx_read(bcs, HSCX_RBCL) & (fifo_size-1);
if (count == 0)
count = fifo_size;
hscx_empty_fifo(bcs, count);
if ((count = bcs->hw.hscx.rcvidx - 1) > 0) {
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);
}
}
recv_rme_b(bcs);
}
bcs->hw.hscx.rcvidx = 0;
sched_b_event(bcs, B_RCVBUFREADY);
}
if (val & 0x40) { /* RPF */
hscx_empty_fifo(bcs, fifo_size);
if (bcs->mode == L1_MODE_TRANS) {
/* 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);
}
recv_rpf_b(bcs);
}
if (val & 0x10) {
xmit_xpr_b(bcs);
......@@ -203,11 +136,9 @@ reset_xmit(struct BCState *bcs)
void
hscx_int_main(struct IsdnCardState *cs, u8 val)
{
u8 exval;
struct BCState *bcs;
spin_lock(&cs->lock);
if (val & 0x01) {
bcs = cs->bcs + 1;
exval = hscx_read(bcs, HSCX_EXIR);
......@@ -238,5 +169,57 @@ hscx_int_main(struct IsdnCardState *cs, u8 val)
debugl1(cs, "HSCX A interrupt %x", exval);
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);
}
......@@ -23,7 +23,6 @@
#define DBUSY_TIMER_VALUE 80
#define ARCOFI_USE 0
static spinlock_t icc_lock = SPIN_LOCK_UNLOCKED;
static inline u8
icc_read_reg(struct IsdnCardState *cs, u8 addr)
......@@ -137,33 +136,8 @@ icc_bh(void *data)
void
icc_empty_fifo(struct IsdnCardState *cs, int count)
{
u8 *ptr;
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);
cs->rcvidx = 0;
return;
}
ptr = cs->rcvbuf + cs->rcvidx;
cs->rcvidx += count;
spin_lock_irqsave(&icc_lock, flags);
icc_read_fifo(cs, ptr, count);
recv_empty_fifo_d(cs, 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
......@@ -171,13 +145,11 @@ icc_fill_fifo(struct IsdnCardState *cs)
{
int count, more;
unsigned char *p;
unsigned long flags;
p = xmit_fill_fifo_d(cs, 32, &count, &more);
if (!p)
return;
spin_lock_irqsave(&icc_lock, flags);
icc_write_fifo(cs, p, count);
icc_write_reg(cs, ICC_CMDR, more ? 0x8 : 0xa);
if (test_and_set_bit(FLG_DBUSY_TIMER, &cs->HW_Flags)) {
......@@ -187,16 +159,13 @@ icc_fill_fifo(struct IsdnCardState *cs)
init_timer(&cs->dbusytimer);
cs->dbusytimer.expires = jiffies + ((DBUSY_TIMER_VALUE * HZ)/1000);
add_timer(&cs->dbusytimer);
spin_unlock_irqrestore(&icc_lock, flags);
}
void
icc_interrupt(struct IsdnCardState *cs, u8 val)
{
u8 exval, v1;
struct sk_buff *skb;
unsigned int count;
unsigned long flags;
if (cs->debug & L1_DEB_ISAC)
debugl1(cs, "ICC interrupt %x", val);
......@@ -218,25 +187,14 @@ icc_interrupt(struct IsdnCardState *cs, u8 val)
#endif
}
icc_write_reg(cs, ICC_CMDR, 0x80);
cs->rcvidx = 0;
} else {
count = icc_read_reg(cs, ICC_RBCL) & 0x1f;
if (count == 0)
count = 32;
icc_empty_fifo(cs, count);
spin_lock_irqsave(&icc_lock, flags);
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);
recv_rme_d(cs);
}
cs->rcvidx = 0;
sched_d_event(cs, D_RCVBUFREADY);
}
if (val & 0x40) { /* RPF */
icc_empty_fifo(cs, 32);
......@@ -485,10 +443,11 @@ ICC_l1hw(struct PStack *st, int pr, void *arg)
}
}
void
static int
setstack_icc(struct PStack *st, struct IsdnCardState *cs)
{
st->l1.l1hw = ICC_l1hw;
return 0;
}
void
......@@ -534,25 +493,27 @@ dbusy_timer_handler(struct IsdnCardState *cs)
debugl1(cs, "D-Channel Busy no skb");
}
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
initicc(struct IsdnCardState *cs)
{
int val, eval;
INIT_WORK(&cs->work, icc_bh, cs);
cs->setstack_d = setstack_icc;
cs->DC_Send_Data = icc_fill_fifo;
cs->DC_Close = DC_Close_icc;
dc_l1_init(cs, &icc_l1_ops);
cs->dc.icc.mon_tx = 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);
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 @@
#define IPAC_PCFG 0xCA
#define IPAC_SCFG 0xCB
#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 @@
extern void init_ipacx(struct IsdnCardState *cs, int part);
extern void interrupt_ipacx(struct IsdnCardState *cs);
extern void ipacx_fill_fifo(struct BCState *bcs);
#endif
This diff is collapsed.
......@@ -174,7 +174,7 @@ ISARVersion(struct IsdnCardState *cs, char *s)
u8 len;
int debug;
cs->cardmsg(cs, CARD_RESET, NULL);
cs->card_ops->reset(cs);
/* disable ISAR IRQ */
isar_write_reg(cs, 0, ISAR_IRQBIT, 0);
debug = cs->debug;
......@@ -1745,14 +1745,12 @@ isar_auxcmd(struct IsdnCardState *cs, isdn_ctrl *ic) {
static struct bc_l1_ops isar_l1_ops = {
.fill_fifo = isar_fill_fifo,
.open = setstack_isar,
.close = close_isarstate,
};
void __devinit
initisar(struct IsdnCardState *cs)
{
cs->bc_l1_ops = &isar_l1_ops;
cs->bcs[0].BC_SetStack = setstack_isar;
cs->bcs[1].BC_SetStack = setstack_isar;
cs->bcs[0].BC_Close = close_isarstate;
cs->bcs[1].BC_Close = close_isarstate;
}
......@@ -358,8 +358,6 @@ init_bcstate(struct IsdnCardState *cs,
bcs->cs = cs;
bcs->channel = bc;
INIT_WORK(&bcs->work, BChannel_bh, bcs);
bcs->BC_SetStack = NULL;
bcs->BC_Close = NULL;
bcs->Flag = 0;
}
......@@ -907,8 +905,18 @@ setstack_HiSax(struct PStack *st, struct IsdnCardState *cs)
setstack_manager(st);
st->l1.stlistp = &(cs->stlist);
st->l1.l2l1 = dch_l2l1;
if (cs->setstack_d)
cs->setstack_d(st, cs);
if (cs->dc_l1_ops->open)
cs->dc_l1_ops->open(st, cs);
}
void
dc_l1_init(struct IsdnCardState *cs, struct dc_l1_ops *ops)
{
cs->dc_l1_ops = ops;
INIT_WORK(&cs->work, ops->bh_func, cs);
init_timer(&cs->dbusytimer);
cs->dbusytimer.function = (void *)(unsigned long) ops->dbusy_func;
cs->dbusytimer.data = (unsigned long) cs;
}
void
......
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);
extern void modejade(struct BCState *bcs, int mode, int bc);
extern void initjade(struct IsdnCardState *cs);
extern void jade_int_main(struct IsdnCardState *cs, u_char val, int jade);
extern void jade_fill_fifo(struct BCState *bcs);
#endif /* __JADE_H__ */
This diff is collapsed.
This diff is collapsed.
......@@ -937,6 +937,8 @@ setstack_tiger(struct PStack *st, struct BCState *bcs)
static struct bc_l1_ops netjet_l1_ops = {
.fill_fifo = netjet_fill_dma,
.open = setstack_tiger,
.close = close_tigerstate,
};
void __init
......@@ -994,13 +996,9 @@ inittiger(struct IsdnCardState *cs)
inl(cs->hw.njet.base + NETJET_DMA_READ_ADR),
bytein(cs->hw.njet.base + NETJET_PULSE_CNT));
cs->hw.njet.last_is0 = 0;
cs->bcs[0].BC_SetStack = setstack_tiger;
cs->bcs[1].BC_SetStack = setstack_tiger;
cs->bcs[0].BC_Close = close_tigerstate;
cs->bcs[1].BC_Close = close_tigerstate;
}
void
static void
releasetiger(struct IsdnCardState *cs)
{
if (cs->bcs[0].hw.tiger.send) {
......@@ -1026,7 +1024,7 @@ releasetiger(struct IsdnCardState *cs)
}
void
release_io_netjet(struct IsdnCardState *cs)
netjet_release(struct IsdnCardState *cs)
{
byteout(cs->hw.njet.base + NETJET_IRQMASK0, 0);
byteout(cs->hw.njet.base + NETJET_IRQMASK1, 0);
......
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