Commit 50765282 authored by Kai Germaschewski's avatar Kai Germaschewski

ISDN/HiSax: "ops" structure for the shared xmit handling

When separating out the duplicated xmit handling, we were lucky that
we could reuse BC_Send_Data for our purposes. Introduce a more
extensible "struct bc_l1_ops" instead, and initialize that in
the code that provides the functionality, not in the users.
parent 8119a9aa
......@@ -398,7 +398,6 @@ 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->BC_Send_Data = &hscx_fill_fifo;
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);
......
......@@ -304,7 +304,6 @@ setup_avm_a1(struct IsdnCard *card)
cs->dc_hw_ops = &isac_ops;
cs->bc_hw_ops = &hscx_ops;
cs->BC_Send_Data = &hscx_fill_fifo;
cs->cardmsg = &AVM_card_msg;
cs->irq_func = &avm_a1_interrupt;
ISACVersion(cs, "AVM A1:");
......
......@@ -258,7 +258,6 @@ setup_avm_a1_pcmcia(struct IsdnCard *card)
cs->dc_hw_ops = &isac_ops;
cs->bc_hw_ops = &hscx_ops;
cs->BC_Send_Data = &hscx_fill_fifo;
cs->cardmsg = &AVM_card_msg;
cs->irq_func = &avm_a1p_interrupt;
......
......@@ -307,7 +307,7 @@ hdlc_empty_fifo(struct BCState *bcs, int count)
}
}
static inline void
static void
hdlc_fill_fifo(struct BCState *bcs)
{
struct IsdnCardState *cs = bcs->cs;
......@@ -360,6 +360,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)
{
......@@ -772,7 +776,7 @@ setup_avm_pcipnp(struct IsdnCard *card)
cs->irq, cs->hw.avm.cfg_reg);
cs->dc_hw_ops = &isac_ops;
cs->BC_Send_Data = &hdlc_fill_fifo;
cs->bc_l1_ops = &hdlc_l1_ops;
cs->cardmsg = &AVM_card_msg;
cs->irq_func = &avm_pcipnp_interrupt;
ISACVersion(cs, (cs->subtyp == AVM_FRITZ_PCI) ? "AVM PCI:" : "AVM PnP:");
......
......@@ -334,7 +334,6 @@ setup_bkm_a4t(struct IsdnCard *card)
reset_bkm(cs);
cs->dc_hw_ops = &isac_ops;
cs->bc_hw_ops = &jade_ops;
cs->BC_Send_Data = &jade_fill_fifo;
cs->cardmsg = &BKM_card_msg;
cs->irq_func = &bkm_interrupt;
cs->irq_flags |= SA_SHIRQ;
......
......@@ -430,7 +430,6 @@ setup_sct_quadro(struct IsdnCard *card)
cs->dc_hw_ops = &ipac_dc_ops;
cs->bc_hw_ops = &hscx_ops;
cs->BC_Send_Data = &hscx_fill_fifo;
cs->cardmsg = &BKM_card_msg;
cs->irq_func = &bkm_interrupt_ipac;
......
......@@ -499,6 +499,10 @@ Memhscx_fill_fifo(struct BCState *bcs)
MemWriteHSCXCMDR(cs, bcs->hw.hscx.hscx, more ? 0x8 : 0xa);
}
static struct bc_l1_ops mem_hscx_l1_ops = {
.fill_fifo = Memhscx_fill_fifo,
};
static inline void
Memhscx_interrupt(struct IsdnCardState *cs, u8 val, u8 hscx)
{
......@@ -1095,7 +1099,6 @@ setup_diva(struct IsdnCard *card)
}
reset_diva(cs);
cs->bc_hw_ops = &hscx_ops;
cs->BC_Send_Data = &hscx_fill_fifo;
cs->cardmsg = &Diva_card_msg;
if (cs->subtyp == DIVA_IPAC_ISA) {
cs->dc_hw_ops = &ipac_dc_ops;
......@@ -1105,14 +1108,13 @@ setup_diva(struct IsdnCard *card)
} else if (cs->subtyp == DIVA_IPAC_PCI) {
cs->dc_hw_ops = &mem_ipac_dc_ops;
cs->bc_hw_ops = &mem_hscx_ops;
cs->BC_Send_Data = &Memhscx_fill_fifo;
cs->bc_l1_ops = &mem_hscx_l1_ops;
cs->irq_func = &diva_irq_ipac_pci;
val = memreadreg(cs->hw.diva.cfg_reg, IPAC_ID);
printk(KERN_INFO "Diva: IPAC version %x\n", val);
} else if (cs->subtyp == DIVA_IPACX_PCI) {
cs->dc_hw_ops = &ipacx_dc_ops;
cs->bc_hw_ops = &ipacx_bc_ops;
cs->BC_Send_Data = &ipacx_fill_fifo;
cs->irq_func = &diva_irq_ipacx_pci;
printk(KERN_INFO "Diva: IPACX Design Id: %x\n",
ipacx_dc_read(cs, IPACX_ID) &0x3F);
......
......@@ -1169,7 +1169,6 @@ setup_elsa(struct IsdnCard *card)
printk(KERN_INFO "Elsa: timer OK; resetting card\n");
}
cs->bc_hw_ops = &hscx_ops;
cs->BC_Send_Data = &hscx_fill_fifo;
cs->cardmsg = &Elsa_card_msg;
reset_elsa(cs);
if ((cs->subtyp == ELSA_QS1000PCI) || (cs->subtyp == ELSA_QS3000PCI) || (cs->subtyp == ELSA_PCMCIA_IPAC)) {
......
......@@ -375,6 +375,10 @@ 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)
{
......@@ -609,7 +613,7 @@ setstack_elsa(struct PStack *st, struct BCState *bcs)
bcs->tx_cnt = 0;
bcs->cs->hw.elsa.bcs = bcs;
st->l1.l2l1 = modem_l2l1;
bcs->cs->BC_Send_Data = modem_fill;
bcs->cs->bc_l1_ops = &modem_l1_ops;
break;
}
st->l1.bcs = bcs;
......
......@@ -372,7 +372,6 @@ setup_enternow_pci(struct IsdnCard *card)
cs->dc_hw_ops = &enternow_ops;
cs->dc.amd7930.setIrqMask = &enpci_setIrqMask;
cs->BC_Send_Data = &netjet_fill_dma;
cs->cardmsg = &enpci_card_msg;
cs->irq_func = &enpci_interrupt;
cs->irq_flags |= SA_SHIRQ;
......
......@@ -679,7 +679,6 @@ setup_gazel(struct IsdnCard *card)
}
cs->dc_hw_ops = &isac_ops;
cs->bc_hw_ops = &hscx_ops;
cs->BC_Send_Data = &hscx_fill_fifo;
cs->cardmsg = &Gazel_card_msg;
switch (cs->subtyp) {
......
......@@ -864,7 +864,6 @@ init2bds0(struct IsdnCardState *cs)
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->BC_Send_Data = hfc_fill_fifo;
cs->DC_Send_Data = hfc_fill_dfifo;
cs->bcs[0].BC_SetStack = setstack_2b;
cs->bcs[1].BC_SetStack = setstack_2b;
......
......@@ -544,12 +544,16 @@ init_send(struct BCState *bcs)
bcs->hw.hfc.send[i] = 0x1fff;
}
static struct bc_l1_ops hfc_l1_ops = {
.fill_fifo = hfc_fill_fifo,
};
void __init
inithfc(struct IsdnCardState *cs)
{
init_send(&cs->bcs[0]);
init_send(&cs->bcs[1]);
cs->BC_Send_Data = &hfc_fill_fifo;
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;
......
......@@ -1335,6 +1335,9 @@ hfcpci_bh(void *data)
DChannel_proc_xmt(cs);
}
static struct bc_l1_ops hfcpci_l1_ops = {
.fill_fifo = hfcpci_fill_fifo,
};
/********************************/
/* called for card init message */
......@@ -1347,7 +1350,7 @@ inithfcpci(struct IsdnCardState *cs)
cs->dbusytimer.data = (long) cs;
init_timer(&cs->dbusytimer);
INIT_WORK(&cs->work, hfcpci_bh, cs);
cs->BC_Send_Data = hfcpci_fill_fifo;
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;
......
......@@ -1112,6 +1112,9 @@ hfcsx_bh(void *data)
DChannel_proc_xmt(cs);
}
static struct bc_l1_ops hfcsx_l1_ops = {
.fill_fifo = hfcsx_fill_fifo,
};
/********************************/
/* called for card init message */
......@@ -1124,7 +1127,7 @@ inithfcsx(struct IsdnCardState *cs)
cs->dbusytimer.data = (long) cs;
init_timer(&cs->dbusytimer);
INIT_WORK(&cs->work, hfcsx_bh, cs);
cs->BC_Send_Data = hfcsx_fill_fifo;
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;
......
......@@ -348,15 +348,6 @@ struct l3_process {
} prot;
};
struct IsdnCardState;
struct bc_hw_ops {
u8 (*read_reg) (struct IsdnCardState *, int, u8);
void (*write_reg) (struct IsdnCardState *, int, u8, u8);
void (*read_fifo) (struct IsdnCardState *, int, u8 *, int);
void (*write_fifo) (struct IsdnCardState *, int, u8 *, int);
};
struct hscx_hw {
int hscx;
int rcvidx;
......@@ -868,6 +859,18 @@ struct icc_chip {
u8 adf2;
};
struct IsdnCardState;
/* Card specific drivers provide methods to access the
* chips to the chip drivers */
struct bc_hw_ops {
u8 (*read_reg) (struct IsdnCardState *, int, u8);
void (*write_reg) (struct IsdnCardState *, int, u8, u8);
void (*read_fifo) (struct IsdnCardState *, int, u8 *, int);
void (*write_fifo) (struct IsdnCardState *, int, u8 *, int);
};
struct dc_hw_ops {
u8 (*read_reg) (struct IsdnCardState *, u8);
void (*write_reg) (struct IsdnCardState *, u8, u8);
......@@ -875,6 +878,12 @@ struct dc_hw_ops {
void (*write_fifo) (struct IsdnCardState *, u8 *, int);
};
/* Methods provided to shared FIFO handling */
struct bc_l1_ops {
void (*fill_fifo) (struct BCState *);
};
#define HW_IOM1 0
#define HW_IPAC 1
#define HW_ISAR 2
......@@ -933,7 +942,7 @@ struct IsdnCardState {
u8 *status_end;
struct dc_hw_ops *dc_hw_ops;
struct bc_hw_ops *bc_hw_ops;
void (*BC_Send_Data) (struct BCState *);
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 *);
......
......@@ -228,11 +228,16 @@ setstack_hscx(struct PStack *st, struct BCState *bcs)
return (0);
}
static struct bc_l1_ops hscx_l1_ops = {
.fill_fifo = hscx_fill_fifo,
};
void __init
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;
......
......@@ -820,6 +820,10 @@ clear_pending_ints(struct IsdnCardState *cs)
if (ista &0x01) ipacx_read_reg(cs, IPACX_ISTAD);
}
static struct bc_l1_ops ipacx_bc_l1_ops = {
.fill_fifo = ipacx_fill_fifo,
};
//----------------------------------------------------------
// Does chip configuration work
// Work to do depends on bit mask in part
......@@ -828,6 +832,7 @@ void __init
init_ipacx(struct IsdnCardState *cs, int part)
{
if (part &1) { // initialise chip
cs->bc_l1_ops = &ipacx_bc_l1_ops;
clear_pending_ints(cs);
bch_init(cs, 0);
bch_init(cs, 1);
......
......@@ -1743,9 +1743,14 @@ isar_auxcmd(struct IsdnCardState *cs, isdn_ctrl *ic) {
return(0);
}
static struct bc_l1_ops isar_l1_ops = {
.fill_fifo = isar_fill_fifo,
};
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;
......
......@@ -31,6 +31,12 @@ extern void DChannel_proc_rcv(struct IsdnCardState *cs);
extern void l1_msg(struct IsdnCardState *cs, int pr, void *arg);
extern void l1_msg_b(struct PStack *st, int pr, void *arg);
static inline void
fill_fifo_b(struct BCState *bcs)
{
bcs->cs->bc_l1_ops->fill_fifo(bcs);
}
#ifdef L2FRAME_DEBUG
extern void Logl2Frame(struct IsdnCardState *cs, struct sk_buff *skb, char *buf, int dir);
#endif
......@@ -74,7 +80,7 @@ xmit_ready_b(struct BCState *bcs)
if (bcs->tx_skb) {
bcs->count = 0;
set_bit(BC_FLG_BUSY, &bcs->Flag);
bcs->cs->BC_Send_Data(bcs);
fill_fifo_b(bcs);
} else {
clear_bit(BC_FLG_BUSY, &bcs->Flag);
sched_b_event(bcs, B_XMTBUFREADY);
......@@ -107,7 +113,7 @@ xmit_data_req_b(struct BCState *bcs, struct sk_buff *skb)
set_bit(BC_FLG_BUSY, &bcs->Flag);
bcs->tx_skb = skb;
bcs->count = 0;
bcs->cs->BC_Send_Data(bcs);
fill_fifo_b(bcs);
}
spin_unlock_irqrestore(&cs->lock, flags);
}
......@@ -153,7 +159,7 @@ xmit_pull_ind_b(struct BCState *bcs, struct sk_buff *skb)
set_bit(BC_FLG_BUSY, &bcs->Flag);
bcs->tx_skb = skb;
bcs->count = 0;
bcs->cs->BC_Send_Data(bcs);
fill_fifo_b(bcs);
}
spin_unlock_irqrestore(&cs->lock, flags);
}
......@@ -268,7 +274,7 @@ xmit_xpr_b(struct BCState *bcs)
if (bcs->tx_skb) {
/* last frame not done yet? */
if (bcs->tx_skb->len) {
bcs->cs->BC_Send_Data(bcs);
fill_fifo_b(bcs);
return;
}
xmit_complete_b(bcs);
......@@ -310,7 +316,7 @@ xmit_xdu_b(struct BCState *bcs, void (*reset_xmit)(struct BCState *bcs))
debugl1(cs, "HSCX %c EXIR XDU", 'A' + bcs->channel);
if (bcs->mode == L1_MODE_TRANS) {
cs->BC_Send_Data(bcs);
fill_fifo_b(bcs);
} else {
xmit_restart_b(bcs);
reset_xmit(bcs);
......
......@@ -292,7 +292,6 @@ setup_isurf(struct IsdnCard *card)
test_and_set_bit(HW_ISAR, &cs->HW_Flags);
ISACVersion(cs, "ISurf:");
cs->bc_hw_ops = &isar_ops;
cs->BC_Send_Data = &isar_fill_fifo;
ver = ISARVersion(cs, "ISurf:");
if (ver < 0) {
printk(KERN_WARNING
......
......@@ -306,7 +306,6 @@ setup_ix1micro(struct IsdnCard *card)
ix1_reset(cs);
cs->dc_hw_ops = &isac_ops;
cs->bc_hw_ops = &hscx_ops;
cs->BC_Send_Data = &hscx_fill_fifo;
cs->cardmsg = &ix1_card_msg;
cs->irq_func = &ix1micro_interrupt;
ISACVersion(cs, "ix1-Micro:");
......
......@@ -263,11 +263,16 @@ setstack_jade(struct PStack *st, struct BCState *bcs)
return (0);
}
static struct bc_l1_ops jade_l1_ops = {
.fill_fifo = jade_fill_fifo,
};
void __init
initjade(struct IsdnCardState *cs)
{
int val;
cs->bc_l1_ops = &jade_l1_ops;
cs->bcs[0].BC_SetStack = setstack_jade;
cs->bcs[1].BC_SetStack = setstack_jade;
cs->bcs[0].BC_Close = close_jadestate;
......
......@@ -231,7 +231,6 @@ setup_mic(struct IsdnCard *card)
cs->irq);
cs->dc_hw_ops = &isac_ops;
cs->bc_hw_ops = &hscx_ops;
cs->BC_Send_Data = &hscx_fill_fifo;
cs->cardmsg = &mic_card_msg;
cs->irq_func = &mic_interrupt;
ISACVersion(cs, "mic:");
......
......@@ -935,9 +935,15 @@ setstack_tiger(struct PStack *st, struct BCState *bcs)
}
static struct bc_l1_ops netjet_l1_ops = {
.fill_fifo = netjet_fill_dma,
};
void __init
inittiger(struct IsdnCardState *cs)
{
cs->bc_l1_ops = &netjet_l1_ops;
cs->bcs[0].hw.tiger.send =
pci_alloc_consistent(cs->hw.njet.pdev,
NETJET_DMA_TXSIZE * sizeof(unsigned int),
......
......@@ -383,7 +383,6 @@ setup_niccy(struct IsdnCard *card)
cs->irq, cs->hw.niccy.isac, cs->hw.niccy.isac_ale);
cs->dc_hw_ops = &isac_ops;
cs->bc_hw_ops = &hscx_ops;
cs->BC_Send_Data = &hscx_fill_fifo;
cs->cardmsg = &niccy_card_msg;
cs->irq_func = &niccy_interrupt;
ISACVersion(cs, "Niccy:");
......
......@@ -227,7 +227,6 @@ setup_netjet_s(struct IsdnCard *card)
}
reset_netjet_s(cs);
cs->dc_hw_ops = &netjet_dc_ops;
cs->BC_Send_Data = &netjet_fill_dma;
cs->cardmsg = &NETjet_S_card_msg;
cs->irq_func = &netjet_s_interrupt;
cs->irq_flags |= SA_SHIRQ;
......
......@@ -225,7 +225,6 @@ setup_netjet_u(struct IsdnCard *card)
}
reset_netjet_u(cs);
cs->dc_hw_ops = &netjet_dc_ops;
cs->BC_Send_Data = &netjet_fill_dma;
cs->cardmsg = &NETjet_U_card_msg;
cs->irq_func = &netjet_u_interrupt;
cs->irq_flags |= SA_SHIRQ;
......
......@@ -268,7 +268,6 @@ setup_s0box(struct IsdnCard *card)
cs->hw.teles3.hscx[0], cs->hw.teles3.hscx[1]);
cs->dc_hw_ops = &isac_ops;
cs->bc_hw_ops = &hscx_ops;
cs->BC_Send_Data = &hscx_fill_fifo;
cs->cardmsg = &S0Box_card_msg;
cs->irq_func = &s0box_interrupt;
ISACVersion(cs, "S0Box:");
......
......@@ -291,7 +291,6 @@ setup_saphir(struct IsdnCard *card)
}
cs->dc_hw_ops = &isac_ops;
cs->bc_hw_ops = &hscx_ops;
cs->BC_Send_Data = &hscx_fill_fifo;
cs->cardmsg = &saphir_card_msg;
cs->irq_func = &saphir_interrupt;
ISACVersion(cs, "saphir:");
......
......@@ -707,7 +707,6 @@ setup_sedlbauer(struct IsdnCard *card)
cs->irq);
cs->bc_hw_ops = &hscx_ops;
cs->BC_Send_Data = &hscx_fill_fifo;
cs->cardmsg = &Sedl_card_msg;
/*
......@@ -789,7 +788,6 @@ setup_sedlbauer(struct IsdnCard *card)
cs->auxcmd = &isar_auxcmd;
ISACVersion(cs, "Sedlbauer:");
cs->bc_hw_ops = &isar_ops;
cs->BC_Send_Data = &isar_fill_fifo;
ver = ISARVersion(cs, "Sedlbauer:");
if (ver < 0) {
printk(KERN_WARNING
......
......@@ -261,7 +261,6 @@ setup_sportster(struct IsdnCard *card)
cs->dc_hw_ops = &isac_ops;
cs->bc_hw_ops = &hscx_ops;
cs->BC_Send_Data = &hscx_fill_fifo;
cs->cardmsg = &Sportster_card_msg;
cs->irq_func = &sportster_interrupt;
ISACVersion(cs, "Sportster:");
......
......@@ -313,7 +313,6 @@ setup_teles0(struct IsdnCard *card)
}
cs->dc_hw_ops = &isac_ops;
cs->bc_hw_ops = &hscx_ops;
cs->BC_Send_Data = &hscx_fill_fifo;
cs->cardmsg = &Teles_card_msg;
cs->irq_func = &teles0_interrupt;
ISACVersion(cs, "Teles0:");
......
......@@ -481,7 +481,6 @@ setup_teles3(struct IsdnCard *card)
}
cs->dc_hw_ops = &isac_ops;
cs->bc_hw_ops = &hscx_ops;
cs->BC_Send_Data = &hscx_fill_fifo;
cs->cardmsg = &Teles_card_msg;
cs->irq_func = &teles3_interrupt;
ISACVersion(cs, "Teles3:");
......
......@@ -307,7 +307,6 @@ setup_telespci(struct IsdnCard *card)
cs->dc_hw_ops = &isac_ops;
cs->bc_hw_ops = &hscx_ops;
cs->BC_Send_Data = &hscx_fill_fifo;
cs->cardmsg = &TelesPCI_card_msg;
cs->irq_func = &telespci_interrupt;
cs->irq_flags |= SA_SHIRQ;
......
......@@ -772,6 +772,10 @@ w6692_card_msg(struct IsdnCardState *cs, int mt, void *arg)
return (0);
}
static struct bc_l1_ops w6692_bc_l1_ops = {
.fill_fifo = W6692B_fill_fifo,
};
static int id_idx ;
static struct pci_dev *dev_w6692 __initdata = NULL;
......@@ -862,7 +866,7 @@ setup_w6692(struct IsdnCard *card)
id_list[cs->subtyp].card_name, cs->irq,
cs->hw.w6692.iobase);
cs->BC_Send_Data = &W6692B_fill_fifo;
cs->bc_l1_ops = &w6692_bc_l1_ops;
cs->DC_Send_Data = &W6692_fill_fifo;
cs->cardmsg = &w6692_card_msg;
cs->irq_func = &W6692_interrupt;
......
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