Commit 62a758c5 authored by Kai Germaschewski's avatar Kai Germaschewski

Merge uidc2-166.inav.uiowa.net:kernel/v2.5/linux-2.5.isdn

into tp1.ruhr-uni-bochum.de:/scratch/kai/kernel/v2.5/linux-2.5.isdn
parents 1013687e c3ed6a93
...@@ -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);
} }
...@@ -774,6 +714,7 @@ setup_avm_pcipnp(struct IsdnCard *card) ...@@ -774,6 +714,7 @@ 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->irq_func = &avm_pcipnp_interrupt;
......
...@@ -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);
......
...@@ -825,9 +825,9 @@ static void closecard(int cardnr) ...@@ -825,9 +825,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);
...@@ -1779,10 +1779,10 @@ int hisax_register(struct hisax_d_if *hisax_d_if, struct hisax_b_if *b_if[], ...@@ -1779,10 +1779,10 @@ int hisax_register(struct hisax_d_if *hisax_d_if, struct hisax_b_if *b_if[],
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); INIT_WORK(&cs->work, hisax_bh, cs);
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];
......
...@@ -272,9 +272,29 @@ mem_hscx_write(struct IsdnCardState *cs, int hscx, u8 offset, u8 value) ...@@ -272,9 +272,29 @@ mem_hscx_write(struct IsdnCardState *cs, int hscx, u8 offset, u8 value)
memwritereg(cs->hw.diva.cfg_reg, offset + (hscx ? 0x40 : 0), value); memwritereg(cs->hw.diva.cfg_reg, offset + (hscx ? 0x40 : 0), value);
} }
static void
mem_hscx_read_fifo(struct IsdnCardState *cs, int hscx, u8 *data, int len)
{
int i;
for (i = 0; i < len; i++)
*data++ = memreadreg(cs->hw.diva.cfg_reg, hscx ? 0x40 : 0);
}
static void
mem_hscx_write_fifo(struct IsdnCardState *cs, int hscx, u8 *data, int len)
{
int i;
for (i = 0; i < len; i++)
memwritereg(cs->hw.diva.cfg_reg, hscx ? 0x40 : 0, *data++);
}
static struct bc_hw_ops mem_hscx_ops = { static struct bc_hw_ops mem_hscx_ops = {
.read_reg = mem_hscx_read, .read_reg = mem_hscx_read,
.write_reg = mem_hscx_write, .write_reg = mem_hscx_write,
.read_fifo = mem_hscx_read_fifo,
.write_fifo = mem_hscx_write_fifo,
}; };
/* IO-Functions for IPACX type cards */ /* IO-Functions for IPACX type cards */
...@@ -325,9 +345,19 @@ ipacx_bc_write(struct IsdnCardState *cs, int hscx, u8 offset, u8 value) ...@@ -325,9 +345,19 @@ ipacx_bc_write(struct IsdnCardState *cs, int hscx, u8 offset, u8 value)
(hscx ? IPACX_OFF_B2 : IPACX_OFF_B1), value); (hscx ? IPACX_OFF_B2 : IPACX_OFF_B1), value);
} }
static void
ipacx_bc_read_fifo(struct IsdnCardState *cs, int hscx, u8 *data, int len)
{
int i;
for (i = 0; i < len ; i++)
*data++ = ipacx_bc_read(cs, hscx, IPACX_RFIFOB);
}
static struct bc_hw_ops ipacx_bc_ops = { static struct bc_hw_ops ipacx_bc_ops = {
.read_reg = ipacx_bc_read, .read_reg = ipacx_bc_read,
.write_reg = ipacx_bc_write, .write_reg = ipacx_bc_write,
.read_fifo = ipacx_bc_read_fifo,
}; };
static void static void
...@@ -405,213 +435,6 @@ diva_irq_ipac_isa(int intno, void *dev_id, struct pt_regs *regs) ...@@ -405,213 +435,6 @@ diva_irq_ipac_isa(int intno, void *dev_id, struct pt_regs *regs)
writereg(cs->hw.diva.isac_adr, cs->hw.diva.isac, IPAC_MASK, 0xC0); writereg(cs->hw.diva.isac_adr, cs->hw.diva.isac, IPAC_MASK, 0xC0);
} }
static inline void
MemwaitforCEC(struct IsdnCardState *cs, int hscx)
{
int to = 50;
while ((mem_hscx_read(cs, hscx, HSCX_STAR) & 0x04) && to) {
udelay(1);
to--;
}
if (!to)
printk(KERN_WARNING "HiSax: waitforCEC timeout\n");
}
static inline void
MemwaitforXFW(struct IsdnCardState *cs, int hscx)
{
int to = 50;
while ((!(mem_hscx_read(cs, hscx, HSCX_STAR) & 0x44) == 0x40) && to) {
udelay(1);
to--;
}
if (!to)
printk(KERN_WARNING "HiSax: waitforXFW timeout\n");
}
static inline void
MemWriteHSCXCMDR(struct IsdnCardState *cs, int hscx, u8 data)
{
unsigned long flags;
spin_lock_irqsave(&diva_lock, flags);
MemwaitforCEC(cs, hscx);
mem_hscx_write(cs, hscx, HSCX_CMDR, data);
spin_unlock_irqrestore(&diva_lock, flags);
}
static void
Memhscx_empty_fifo(struct BCState *bcs, int count)
{
u8 *ptr;
struct IsdnCardState *cs = bcs->cs;
unsigned long flags;
int cnt;
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");
MemWriteHSCXCMDR(cs, bcs->hw.hscx.hscx, 0x80);
bcs->hw.hscx.rcvidx = 0;
return;
}
spin_lock_irqsave(&diva_lock, flags);
ptr = bcs->hw.hscx.rcvbuf + bcs->hw.hscx.rcvidx;
cnt = count;
while (cnt--)
*ptr++ = memreadreg(cs->hw.diva.cfg_reg, bcs->hw.hscx.hscx ? 0x40 : 0);
MemWriteHSCXCMDR(cs, bcs->hw.hscx.hscx, 0x80);
ptr = bcs->hw.hscx.rcvbuf + bcs->hw.hscx.rcvidx;
bcs->hw.hscx.rcvidx += count;
spin_unlock_irqrestore(&diva_lock, flags);
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);
}
}
static void
Memhscx_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;
unsigned char *p;
p = xmit_fill_fifo_b(bcs, fifo_size, &count, &more);
if (!p)
return;
MemwaitforXFW(cs, bcs->hw.hscx.hscx);
while (count--)
memwritereg(cs->hw.diva.cfg_reg, bcs->hw.hscx.hscx ? 0x40 : 0,
*p++);
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)
{
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;
if (!test_bit(BC_FLG_INIT, &bcs->Flag))
return;
if (val & 0x80) { /* RME */
r = mem_hscx_read(cs, hscx, HSCX_RSTA);
if ((r & 0xf0) != 0xa0) {
if (!(r & 0x80))
if (cs->debug & L1_DEB_WARN)
debugl1(cs, "HSCX invalid frame");
if ((r & 0x40) && bcs->mode)
if (cs->debug & L1_DEB_WARN)
debugl1(cs, "HSCX RDO mode=%d",
bcs->mode);
if (!(r & 0x20))
if (cs->debug & L1_DEB_WARN)
debugl1(cs, "HSCX CRC error");
MemWriteHSCXCMDR(cs, hscx, 0x80);
} else {
count = mem_hscx_read(cs, hscx, HSCX_RBCL) & (
test_bit(HW_IPAC, &cs->HW_Flags)? 0x3f: 0x1f);
if (count == 0)
count = fifo_size;
Memhscx_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);
}
}
}
bcs->hw.hscx.rcvidx = 0;
sched_b_event(bcs, B_RCVBUFREADY);
}
if (val & 0x40) { /* RPF */
Memhscx_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);
}
}
if (val & 0x10) {
xmit_xpr_b(bcs);/* XPR */
}
}
static void
Memhscx_reset_xmit(struct BCState *bcs)
{
MemWriteHSCXCMDR(bcs->cs, bcs->hw.hscx.hscx, 0x01);
}
static inline void
Memhscx_int_main(struct IsdnCardState *cs, u8 val)
{
u8 exval;
struct BCState *bcs;
if (val & 0x01) { // EXB
bcs = cs->bcs + 1;
exval = mem_hscx_read(cs, 1, HSCX_EXIR);
if (exval & 0x40) {
if (cs->debug & L1_DEB_HSCX)
debugl1(cs, "HSCX B EXIR %x", exval);
xmit_xdu_b(bcs, Memhscx_reset_xmit);
}
}
if (val & 0xf8) {
if (cs->debug & L1_DEB_HSCX)
debugl1(cs, "HSCX B interrupt %x", val);
Memhscx_interrupt(cs, val, 1);
}
if (val & 0x02) { // EXA
bcs = cs->bcs;
exval = mem_hscx_read(cs, 0, HSCX_EXIR);
if (exval & 0x40) {
if (cs->debug & L1_DEB_HSCX)
debugl1(cs, "HSCX A EXIR %x", exval);
xmit_xdu_b(bcs, Memhscx_reset_xmit);
}
}
if (val & 0x04) { // ICA
exval = mem_hscx_read(cs, 0, HSCX_ISTA);
if (cs->debug & L1_DEB_HSCX)
debugl1(cs, "HSCX A interrupt %x", exval);
Memhscx_interrupt(cs, exval, 0);
}
}
static void static void
diva_irq_ipac_pci(int intno, void *dev_id, struct pt_regs *regs) diva_irq_ipac_pci(int intno, void *dev_id, struct pt_regs *regs)
{ {
...@@ -642,7 +465,7 @@ diva_irq_ipac_pci(int intno, void *dev_id, struct pt_regs *regs) ...@@ -642,7 +465,7 @@ diva_irq_ipac_pci(int intno, void *dev_id, struct pt_regs *regs)
if (ista & 0x08) if (ista & 0x08)
val |= 0x04; val |= 0x04;
if (val) if (val)
Memhscx_int_main(cs, val); hscx_int_main(cs, val);
} }
if (ista & 0x20) { if (ista & 0x20) {
val = 0xfe & memreadreg(cs->hw.diva.cfg_reg, ISAC_ISTA + 0x80); val = 0xfe & memreadreg(cs->hw.diva.cfg_reg, ISAC_ISTA + 0x80);
...@@ -1108,7 +931,6 @@ setup_diva(struct IsdnCard *card) ...@@ -1108,7 +931,6 @@ setup_diva(struct IsdnCard *card)
} else if (cs->subtyp == DIVA_IPAC_PCI) { } else if (cs->subtyp == DIVA_IPAC_PCI) {
cs->dc_hw_ops = &mem_ipac_dc_ops; cs->dc_hw_ops = &mem_ipac_dc_ops;
cs->bc_hw_ops = &mem_hscx_ops; cs->bc_hw_ops = &mem_hscx_ops;
cs->bc_l1_ops = &mem_hscx_l1_ops;
cs->irq_func = &diva_irq_ipac_pci; cs->irq_func = &diva_irq_ipac_pci;
val = memreadreg(cs->hw.diva.cfg_reg, IPAC_ID); val = memreadreg(cs->hw.diva.cfg_reg, IPAC_ID);
printk(KERN_INFO "Diva: IPAC version %x\n", val); printk(KERN_INFO "Diva: IPAC version %x\n", val);
......
...@@ -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
......
...@@ -850,9 +850,16 @@ unsigned int __init ...@@ -850,9 +850,16 @@ unsigned int __init
return(send); return(send);
} }
static struct bc_l1_ops hfcd_l1_ops = {
.fill_fifo = hfc_fill_fifo,
.open = setstack_2b,
.close = close_2bs0,
};
void __init void __init
init2bds0(struct IsdnCardState *cs) init2bds0(struct IsdnCardState *cs)
{ {
cs->bc_l1_ops = &hfcd_l1_ops;
cs->setstack_d = setstack_hfcd; cs->setstack_d = setstack_hfcd;
cs->dbusytimer.function = (void *) hfc_dbusy_timer; cs->dbusytimer.function = (void *) hfc_dbusy_timer;
cs->dbusytimer.data = (long) cs; cs->dbusytimer.data = (long) cs;
...@@ -865,10 +872,6 @@ init2bds0(struct IsdnCardState *cs) ...@@ -865,10 +872,6 @@ init2bds0(struct IsdnCardState *cs)
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->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);
} }
......
...@@ -1337,6 +1337,8 @@ hfcpci_bh(void *data) ...@@ -1337,6 +1337,8 @@ hfcpci_bh(void *data)
static struct bc_l1_ops hfcpci_l1_ops = { static struct bc_l1_ops hfcpci_l1_ops = {
.fill_fifo = hfcpci_fill_fifo, .fill_fifo = hfcpci_fill_fifo,
.open = setstack_2b,
.close = close_hfcpci,
}; };
/********************************/ /********************************/
...@@ -1352,10 +1354,6 @@ inithfcpci(struct IsdnCardState *cs) ...@@ -1352,10 +1354,6 @@ inithfcpci(struct IsdnCardState *cs)
INIT_WORK(&cs->work, hfcpci_bh, cs); INIT_WORK(&cs->work, hfcpci_bh, cs);
cs->bc_l1_ops = &hfcpci_l1_ops; cs->bc_l1_ops = &hfcpci_l1_ops;
cs->DC_Send_Data = hfcpci_fill_dfifo; 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);
} }
......
...@@ -1114,6 +1114,8 @@ hfcsx_bh(void *data) ...@@ -1114,6 +1114,8 @@ hfcsx_bh(void *data)
static struct bc_l1_ops hfcsx_l1_ops = { static struct bc_l1_ops hfcsx_l1_ops = {
.fill_fifo = hfcsx_fill_fifo, .fill_fifo = hfcsx_fill_fifo,
.open = setstack_2b,
.close = close_hfcsx,
}; };
/********************************/ /********************************/
...@@ -1129,10 +1131,6 @@ inithfcsx(struct IsdnCardState *cs) ...@@ -1129,10 +1131,6 @@ inithfcsx(struct IsdnCardState *cs)
INIT_WORK(&cs->work, hfcsx_bh, cs); INIT_WORK(&cs->work, hfcsx_bh, cs);
cs->bc_l1_ops = &hfcsx_l1_ops; cs->bc_l1_ops = &hfcsx_l1_ops;
cs->DC_Send_Data = hfcsx_fill_dfifo; 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);
} }
......
...@@ -349,17 +349,12 @@ struct l3_process { ...@@ -349,17 +349,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 +402,6 @@ struct hdlc_hw { ...@@ -407,8 +402,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 +472,11 @@ struct amd7930_hw { ...@@ -479,8 +472,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 +488,6 @@ struct BCState { ...@@ -492,8 +488,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;
...@@ -882,6 +876,8 @@ struct dc_hw_ops { ...@@ -882,6 +876,8 @@ struct dc_hw_ops {
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 *);
}; };
#define HW_IOM1 0 #define HW_IOM1 0
......
...@@ -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,3 @@ extern int HscxVersion(struct IsdnCardState *cs, char *s); ...@@ -38,4 +38,3 @@ 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);
...@@ -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)) p = xmit_fill_fifo_b(bcs, fifo_size, &count, &more);
debugl1(cs, "hscx_fill_fifo"); if (!p)
if (!bcs->tx_skb)
return;
if (bcs->tx_skb->len <= 0)
return; 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,4 @@ hscx_int_main(struct IsdnCardState *cs, u8 val) ...@@ -238,5 +169,4 @@ 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);
} }
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);
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); 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,26 +187,15 @@ icc_interrupt(struct IsdnCardState *cs, u8 val) ...@@ -218,26 +187,15 @@ 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);
} }
......
...@@ -44,7 +44,7 @@ static inline void dch_int(struct IsdnCardState *cs); ...@@ -44,7 +44,7 @@ static inline void dch_int(struct IsdnCardState *cs);
static void __devinit dch_setstack(struct PStack *st, struct IsdnCardState *cs); static void __devinit dch_setstack(struct PStack *st, struct IsdnCardState *cs);
static void __devinit dch_init(struct IsdnCardState *cs); static void __devinit dch_init(struct IsdnCardState *cs);
static void bch_l2l1(struct PStack *st, int pr, void *arg); static void bch_l2l1(struct PStack *st, int pr, void *arg);
static void bch_empty_fifo(struct BCState *bcs, int count); static void ipacx_bc_empty_fifo(struct BCState *bcs, int count);
static void bch_int(struct IsdnCardState *cs, u8 hscx); static void bch_int(struct IsdnCardState *cs, u8 hscx);
static void bch_mode(struct BCState *bcs, int mode, int bc); static void bch_mode(struct BCState *bcs, int mode, int bc);
static void bch_close_state(struct BCState *bcs); static void bch_close_state(struct BCState *bcs);
...@@ -57,18 +57,16 @@ static inline u8 ...@@ -57,18 +57,16 @@ static inline u8
ipacx_bc_read_reg(struct BCState *bcs, u8 addr) ipacx_bc_read_reg(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
ipacx_bc_write_reg(struct BCState *bcs, u8 addr, u8 val) ipacx_bc_write_reg(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 u8 static inline u8
...@@ -305,33 +303,8 @@ dch_bh(void *data) ...@@ -305,33 +303,8 @@ dch_bh(void *data)
static void static void
dch_empty_fifo(struct IsdnCardState *cs, int count) dch_empty_fifo(struct IsdnCardState *cs, int count)
{ {
u8 *ptr; recv_empty_fifo_d(cs, count);
if ((cs->debug &L1_DEB_ISAC) && !(cs->debug &L1_DEB_ISAC_FIFO))
debugl1(cs, "dch_empty_fifo()");
// message too large, remove
if ((cs->rcvidx + count) >= MAX_DFRAME_LEN_L1) {
if (cs->debug &L1_DEB_WARN)
debugl1(cs, "dch_empty_fifo() incoming message too large");
ipacx_write_reg(cs, IPACX_CMDRD, 0x80); // RMC ipacx_write_reg(cs, IPACX_CMDRD, 0x80); // RMC
cs->rcvidx = 0;
return;
}
ptr = cs->rcvbuf + cs->rcvidx;
cs->rcvidx += count;
ipacx_read_fifo(cs, ptr, count);
ipacx_write_reg(cs, IPACX_CMDRD, 0x80); // RMC
if (cs->debug &L1_DEB_ISAC_FIFO) {
char *t = cs->dlog;
t += sprintf(t, "dch_empty_fifo() cnt %d", count);
QuickHex(t, ptr, count);
debugl1(cs, cs->dlog);
}
} }
//---------------------------------------------------------- //----------------------------------------------------------
...@@ -372,7 +345,6 @@ dch_fill_fifo(struct IsdnCardState *cs) ...@@ -372,7 +345,6 @@ dch_fill_fifo(struct IsdnCardState *cs)
static inline void static inline void
dch_int(struct IsdnCardState *cs) dch_int(struct IsdnCardState *cs)
{ {
struct sk_buff *skb;
u8 istad, rstad; u8 istad, rstad;
int count; int count;
...@@ -391,25 +363,18 @@ dch_int(struct IsdnCardState *cs) ...@@ -391,25 +363,18 @@ dch_int(struct IsdnCardState *cs)
if (cs->debug &L1_DEB_WARN) if (cs->debug &L1_DEB_WARN)
debugl1(cs, "dch_int(): CRC error"); debugl1(cs, "dch_int(): CRC error");
ipacx_write_reg(cs, IPACX_CMDRD, 0x80); // RMC ipacx_write_reg(cs, IPACX_CMDRD, 0x80); // RMC
cs->rcvidx = 0;
} else { // received frame ok } else { // received frame ok
count = ipacx_read_reg(cs, IPACX_RBCLD); count = ipacx_read_reg(cs, IPACX_RBCLD);
// FIXME this looks flaky
if (count) count--; // RSTAB is last byte if (count) count--; // RSTAB is last byte
count &= D_FIFO_SIZE-1; count &= D_FIFO_SIZE-1;
if (count == 0) count = D_FIFO_SIZE; if (count == 0)
count = D_FIFO_SIZE;
dch_empty_fifo(cs, count); dch_empty_fifo(cs, count);
if ((count = cs->rcvidx) > 0) { recv_rme_d(cs);
cs->rcvidx = 0;
if (!(skb = dev_alloc_skb(count)))
printk(KERN_WARNING "HiSax dch_int(): receive out of memory\n");
else {
memcpy(skb_put(skb, count), cs->rcvbuf, count);
skb_queue_tail(&cs->rq, skb);
} }
} }
}
cs->rcvidx = 0;
sched_d_event(cs, D_RCVBUFREADY);
}
if (istad &0x40) { // RPF if (istad &0x40) { // RPF
dch_empty_fifo(cs, D_FIFO_SIZE); dch_empty_fifo(cs, D_FIFO_SIZE);
...@@ -501,49 +466,17 @@ bch_l2l1(struct PStack *st, int pr, void *arg) ...@@ -501,49 +466,17 @@ bch_l2l1(struct PStack *st, int pr, void *arg)
// Read B channel fifo to receive buffer // Read B channel fifo to receive buffer
//---------------------------------------------------------- //----------------------------------------------------------
static void static void
bch_empty_fifo(struct BCState *bcs, int count) ipacx_bc_empty_fifo(struct BCState *bcs, int count)
{ {
u8 *ptr, hscx; recv_empty_fifo_b(bcs, count);
struct IsdnCardState *cs;
int cnt;
cs = bcs->cs;
hscx = bcs->hw.hscx.hscx;
if ((cs->debug &L1_DEB_HSCX) && !(cs->debug &L1_DEB_HSCX_FIFO))
debugl1(cs, "bch_empty_fifo()");
// message too large, remove
if (bcs->hw.hscx.rcvidx + count > HSCX_BUFMAX) {
if (cs->debug &L1_DEB_WARN)
debugl1(cs, "bch_empty_fifo() incoming packet too large");
ipacx_bc_write_reg(bcs, IPACX_CMDRB, 0x80); // RMC ipacx_bc_write_reg(bcs, IPACX_CMDRB, 0x80); // RMC
bcs->hw.hscx.rcvidx = 0;
return;
}
// Read data uninterruptible
ptr = bcs->hw.hscx.rcvbuf + bcs->hw.hscx.rcvidx;
cnt = count;
while (cnt--) *ptr++ = ipacx_bc_read_reg(bcs, IPACX_RFIFOB);
ipacx_bc_write_reg(bcs, IPACX_CMDRB, 0x80); // RMC
ptr = bcs->hw.hscx.rcvbuf + bcs->hw.hscx.rcvidx;
bcs->hw.hscx.rcvidx += count;
if (cs->debug &L1_DEB_HSCX_FIFO) {
char *t = bcs->blog;
t += sprintf(t, "bch_empty_fifo() B-%d cnt %d", hscx, count);
QuickHex(t, ptr, count);
debugl1(cs, bcs->blog);
}
} }
//---------------------------------------------------------- //----------------------------------------------------------
// Fill buffer to transmit FIFO // Fill buffer to transmit FIFO
//---------------------------------------------------------- //----------------------------------------------------------
void static void
ipacx_fill_fifo(struct BCState *bcs) ipacx_bc_fill_fifo(struct BCState *bcs)
{ {
int more, count; int more, count;
unsigned char *p; unsigned char *p;
...@@ -573,7 +506,6 @@ bch_int(struct IsdnCardState *cs, u8 hscx) ...@@ -573,7 +506,6 @@ bch_int(struct IsdnCardState *cs, u8 hscx)
{ {
u8 istab; u8 istab;
struct BCState *bcs; struct BCState *bcs;
struct sk_buff *skb;
int count; int count;
u8 rstab; u8 rstab;
...@@ -594,40 +526,20 @@ bch_int(struct IsdnCardState *cs, u8 hscx) ...@@ -594,40 +526,20 @@ bch_int(struct IsdnCardState *cs, u8 hscx)
if (cs->debug &L1_DEB_WARN) if (cs->debug &L1_DEB_WARN)
debugl1(cs, "bch_int() B-%d: CRC error", hscx); debugl1(cs, "bch_int() B-%d: CRC error", hscx);
ipacx_bc_write_reg(bcs, IPACX_CMDRB, 0x80); // RMC ipacx_bc_write_reg(bcs, IPACX_CMDRB, 0x80); // RMC
} bcs->rcvidx = 0;
else { // received frame ok } else { // received frame ok
count = ipacx_bc_read_reg(bcs, IPACX_RBCLB) &(B_FIFO_SIZE-1); count = ipacx_bc_read_reg(bcs, IPACX_RBCLB) &(B_FIFO_SIZE-1);
if (count == 0) count = B_FIFO_SIZE; if (count == 0)
bch_empty_fifo(bcs, count); count = B_FIFO_SIZE;
if ((count = bcs->hw.hscx.rcvidx - 1) > 0) {
if (cs->debug &L1_DEB_HSCX_FIFO) ipacx_bc_empty_fifo(bcs, count);
debugl1(cs, "bch_int Frame %d", count); recv_rme_b(bcs);
if (!(skb = dev_alloc_skb(count)))
printk(KERN_WARNING "HiSax bch_int(): receive frame 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 (istab &0x40) { // RPF if (istab &0x40) { // RPF
bch_empty_fifo(bcs, B_FIFO_SIZE); ipacx_bc_empty_fifo(bcs, B_FIFO_SIZE);
recv_rpf_b(bcs);
if (bcs->mode == L1_MODE_TRANS) { // queue every chunk
// receive transparent audio data
if (!(skb = dev_alloc_skb(B_FIFO_SIZE)))
printk(KERN_WARNING "HiSax bch_int(): receive transparent out of memory\n");
else {
memcpy(skb_put(skb, B_FIFO_SIZE), bcs->hw.hscx.rcvbuf, B_FIFO_SIZE);
skb_queue_tail(&bcs->rqueue, skb);
}
bcs->hw.hscx.rcvidx = 0;
sched_b_event(bcs, B_RCVBUFREADY);
}
} }
if (istab &0x20) { // RFO if (istab &0x20) { // RFO
...@@ -651,7 +563,7 @@ static void ...@@ -651,7 +563,7 @@ static void
bch_mode(struct BCState *bcs, int mode, int bc) bch_mode(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;
bc = bc ? 1 : 0; // in case bc is greater than 1 bc = bc ? 1 : 0; // in case bc is greater than 1
if (cs->debug & L1_DEB_HSCX) if (cs->debug & L1_DEB_HSCX)
...@@ -699,23 +611,7 @@ static void ...@@ -699,23 +611,7 @@ static void
bch_close_state(struct BCState *bcs) bch_close_state(struct BCState *bcs)
{ {
bch_mode(bcs, 0, bcs->channel); bch_mode(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);
if (bcs->tx_skb) {
dev_kfree_skb_any(bcs->tx_skb);
bcs->tx_skb = NULL;
clear_bit(BC_FLG_BUSY, &bcs->Flag);
}
}
} }
//---------------------------------------------------------- //----------------------------------------------------------
...@@ -723,30 +619,7 @@ bch_close_state(struct BCState *bcs) ...@@ -723,30 +619,7 @@ bch_close_state(struct BCState *bcs)
static int static int
bch_open_state(struct IsdnCardState *cs, struct BCState *bcs) bch_open_state(struct IsdnCardState *cs, struct BCState *bcs)
{ {
if (!test_and_set_bit(BC_FLG_INIT, &bcs->Flag)) { return bc_open(bcs);
if (!(bcs->hw.hscx.rcvbuf = kmalloc(HSCX_BUFMAX, GFP_ATOMIC))) {
printk(KERN_WARNING
"HiSax open_bchstate(): No memory for hscx.rcvbuf\n");
clear_bit(BC_FLG_INIT, &bcs->Flag);
return (1);
}
if (!(bcs->blog = kmalloc(MAX_BLOG_SPACE, GFP_ATOMIC))) {
printk(KERN_WARNING
"HiSax open_bchstate: No memory for bcs->blog\n");
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);
}
bcs->tx_skb = NULL;
clear_bit(BC_FLG_BUSY, &bcs->Flag);
bcs->event = 0;
bcs->hw.hscx.rcvidx = 0;
bcs->tx_cnt = 0;
return (0);
} }
//---------------------------------------------------------- //----------------------------------------------------------
...@@ -769,9 +642,7 @@ bch_setstack(struct PStack *st, struct BCState *bcs) ...@@ -769,9 +642,7 @@ bch_setstack(struct PStack *st, struct BCState *bcs)
static void __devinit static void __devinit
bch_init(struct IsdnCardState *cs, int hscx) bch_init(struct IsdnCardState *cs, int hscx)
{ {
cs->bcs[hscx].BC_SetStack = bch_setstack; cs->bcs[hscx].unit = hscx;
cs->bcs[hscx].BC_Close = bch_close_state;
cs->bcs[hscx].hw.hscx.hscx = hscx;
cs->bcs[hscx].cs = cs; cs->bcs[hscx].cs = cs;
bch_mode(cs->bcs + hscx, 0, hscx); bch_mode(cs->bcs + hscx, 0, hscx);
} }
...@@ -821,7 +692,9 @@ clear_pending_ints(struct IsdnCardState *cs) ...@@ -821,7 +692,9 @@ clear_pending_ints(struct IsdnCardState *cs)
} }
static struct bc_l1_ops ipacx_bc_l1_ops = { static struct bc_l1_ops ipacx_bc_l1_ops = {
.fill_fifo = ipacx_fill_fifo, .fill_fifo = ipacx_bc_fill_fifo,
.open = bch_setstack,
.close = bch_close_state,
}; };
//---------------------------------------------------------- //----------------------------------------------------------
......
...@@ -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
...@@ -39,12 +39,6 @@ isac_write(struct IsdnCardState *cs, u8 addr, u8 val) ...@@ -39,12 +39,6 @@ isac_write(struct IsdnCardState *cs, u8 addr, u8 val)
cs->dc_hw_ops->write_reg(cs, addr, val); cs->dc_hw_ops->write_reg(cs, addr, val);
} }
static inline void
isac_read_fifo(struct IsdnCardState *cs, u8 *p, int len)
{
return cs->dc_hw_ops->read_fifo(cs, p, len);
}
static inline void static inline void
isac_write_fifo(struct IsdnCardState *cs, u8 *p, int len) isac_write_fifo(struct IsdnCardState *cs, u8 *p, int len)
{ {
...@@ -140,30 +134,8 @@ isac_bh(void *data) ...@@ -140,30 +134,8 @@ isac_bh(void *data)
void void
isac_empty_fifo(struct IsdnCardState *cs, int count) isac_empty_fifo(struct IsdnCardState *cs, int count)
{ {
u8 *ptr; recv_empty_fifo_d(cs, count);
if ((cs->debug & L1_DEB_ISAC) && !(cs->debug & L1_DEB_ISAC_FIFO))
debugl1(cs, "isac_empty_fifo");
if ((cs->rcvidx + count) >= MAX_DFRAME_LEN_L1) {
if (cs->debug & L1_DEB_WARN)
debugl1(cs, "isac_empty_fifo overrun %d",
cs->rcvidx + count);
isac_write(cs, ISAC_CMDR, 0x80); isac_write(cs, ISAC_CMDR, 0x80);
cs->rcvidx = 0;
return;
}
ptr = cs->rcvbuf + cs->rcvidx;
cs->rcvidx += count;
isac_read_fifo(cs, ptr, count);
isac_write(cs, ISAC_CMDR, 0x80);
if (cs->debug & L1_DEB_ISAC_FIFO) {
char *t = cs->dlog;
t += sprintf(t, "isac_empty_fifo cnt %d", count);
QuickHex(t, ptr, count);
debugl1(cs, cs->dlog);
}
} }
static void static void
...@@ -191,7 +163,6 @@ void ...@@ -191,7 +163,6 @@ void
isac_interrupt(struct IsdnCardState *cs, u8 val) isac_interrupt(struct IsdnCardState *cs, u8 val)
{ {
u8 exval, v1; u8 exval, v1;
struct sk_buff *skb;
unsigned int count; unsigned int count;
if (cs->debug & L1_DEB_ISAC) if (cs->debug & L1_DEB_ISAC)
...@@ -214,20 +185,13 @@ isac_interrupt(struct IsdnCardState *cs, u8 val) ...@@ -214,20 +185,13 @@ isac_interrupt(struct IsdnCardState *cs, u8 val)
#endif #endif
} }
isac_write(cs, ISAC_CMDR, 0x80); isac_write(cs, ISAC_CMDR, 0x80);
cs->rcvidx = 0;
} else { } else {
count = isac_read(cs, ISAC_RBCL) & 0x1f; count = isac_read(cs, ISAC_RBCL) & 0x1f;
if (count == 0) if (count == 0)
count = 32; count = 32;
isac_empty_fifo(cs, count); isac_empty_fifo(cs, count);
if ((count = cs->rcvidx) > 0) { recv_rme_d(cs);
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);
}
}
} }
cs->rcvidx = 0; cs->rcvidx = 0;
sched_d_event(cs, D_RCVBUFREADY); sched_d_event(cs, D_RCVBUFREADY);
......
...@@ -1745,14 +1745,12 @@ isar_auxcmd(struct IsdnCardState *cs, isdn_ctrl *ic) { ...@@ -1745,14 +1745,12 @@ isar_auxcmd(struct IsdnCardState *cs, isdn_ctrl *ic) {
static struct bc_l1_ops isar_l1_ops = { static struct bc_l1_ops isar_l1_ops = {
.fill_fifo = isar_fill_fifo, .fill_fifo = isar_fill_fifo,
.open = setstack_isar,
.close = close_isarstate,
}; };
void __devinit void __devinit
initisar(struct IsdnCardState *cs) initisar(struct IsdnCardState *cs)
{ {
cs->bc_l1_ops = &isar_l1_ops; 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, ...@@ -358,8 +358,6 @@ init_bcstate(struct IsdnCardState *cs,
bcs->cs = cs; bcs->cs = cs;
bcs->channel = bc; bcs->channel = bc;
INIT_WORK(&bcs->work, BChannel_bh, bcs); INIT_WORK(&bcs->work, BChannel_bh, bcs);
bcs->BC_SetStack = NULL;
bcs->BC_Close = NULL;
bcs->Flag = 0; bcs->Flag = 0;
} }
......
...@@ -372,7 +372,7 @@ xmit_fill_fifo_b(struct BCState *bcs, int fifo_size, int *count, int *more) ...@@ -372,7 +372,7 @@ xmit_fill_fifo_b(struct BCState *bcs, int fifo_size, int *count, int *more)
char *t = bcs->blog; char *t = bcs->blog;
t += sprintf(t, "%s %c cnt %d", __FUNCTION__, t += sprintf(t, "%s %c cnt %d", __FUNCTION__,
bcs->hw.hscx.hscx ? 'B' : 'A', *count); bcs->unit ? 'B' : 'A', *count);
QuickHex(t, p, *count); QuickHex(t, p, *count);
debugl1(cs, bcs->blog); debugl1(cs, bcs->blog);
} }
...@@ -413,3 +413,172 @@ xmit_fill_fifo_d(struct IsdnCardState *cs, int fifo_size, int *count, int *more) ...@@ -413,3 +413,172 @@ xmit_fill_fifo_d(struct IsdnCardState *cs, int fifo_size, int *count, int *more)
} }
return p; return p;
} }
static inline void
recv_empty_fifo_d(struct IsdnCardState *cs, int count)
{
u8 *p;
if ((cs->debug & L1_DEB_ISAC) && !(cs->debug & L1_DEB_ISAC_FIFO))
debugl1(cs, __FUNCTION__);
if (cs->rcvidx + count > MAX_DFRAME_LEN_L1) {
if (cs->debug & L1_DEB_WARN)
debugl1(cs, "%s: incoming packet too large", __FUNCTION__);
cs->rcvidx = 0;
return;
}
p = cs->rcvbuf + cs->rcvidx;
cs->rcvidx += count;
cs->dc_hw_ops->read_fifo(cs, p, count);
if (cs->debug & L1_DEB_ISAC_FIFO) {
char *t = cs->dlog;
t += sprintf(t, "%s cnt %d", __FUNCTION__, count);
QuickHex(t, p, count);
debugl1(cs, cs->dlog);
}
}
static inline void
recv_empty_fifo_b(struct BCState *bcs, int count)
{
u8 *p;
struct IsdnCardState *cs = bcs->cs;
if ((cs->debug & L1_DEB_HSCX) && !(cs->debug & L1_DEB_HSCX_FIFO))
debugl1(cs, __FUNCTION__);
if (bcs->rcvidx + count > HSCX_BUFMAX) {
if (cs->debug & L1_DEB_WARN)
debugl1(cs, "%s: incoming packet too large", __FUNCTION__);
bcs->rcvidx = 0;
return;
}
p = bcs->rcvbuf + bcs->rcvidx;
bcs->rcvidx += count;
cs->bc_hw_ops->read_fifo(cs, bcs->unit, p, count);
if (cs->debug & L1_DEB_HSCX_FIFO) {
char *t = bcs->blog;
t += sprintf(t, "%s %c cnt %d", __FUNCTION__,
bcs->unit ? 'B' : 'A', count);
QuickHex(t, p, count);
debugl1(cs, bcs->blog);
}
}
/* RME - receive message end */
static inline void
recv_rme_d(struct IsdnCardState *cs)
{
struct sk_buff *skb;
int count;
count = cs->rcvidx - 1;
cs->rcvidx = 0;
if (count == 0)
return;
skb = dev_alloc_skb(count);
if (!skb) {
printk(KERN_WARNING "HiSax: %s: out of memory\n", __FUNCTION__);
return;
}
memcpy(skb_put(skb, count), cs->rcvbuf, count);
skb_queue_tail(&cs->rq, skb);
sched_d_event(cs, D_RCVBUFREADY);
}
static inline void
recv_rme_b(struct BCState *bcs)
{
struct IsdnCardState *cs = bcs->cs;
struct sk_buff *skb;
int count;
count = bcs->rcvidx - 1;
bcs->rcvidx = 0;
if (count == 0)
return;
if (cs->debug & L1_DEB_HSCX_FIFO)
debugl1(cs, "HX Frame %d", count);
skb = dev_alloc_skb(count);
if (!skb) {
printk(KERN_WARNING "HiSax: %s: out of memory\n", __FUNCTION__);
return;
}
memcpy(skb_put(skb, count), bcs->rcvbuf, count);
skb_queue_tail(&bcs->rqueue, skb);
sched_b_event(bcs, B_RCVBUFREADY);
}
/* RPF - receive pull full */
static inline void
recv_rpf_b(struct BCState *bcs)
{
if (bcs->mode != L1_MODE_TRANS)
return;
recv_rme_b(bcs);
}
static inline int
bc_open(struct BCState *bcs)
{
if (test_and_set_bit(BC_FLG_INIT, &bcs->Flag))
return 0;
bcs->rcvbuf = kmalloc(HSCX_BUFMAX, GFP_ATOMIC);
if (!bcs->rcvbuf)
goto err;
bcs->blog = kmalloc(MAX_BLOG_SPACE, GFP_ATOMIC);
if (!bcs->blog)
goto err_rcvbuf;
skb_queue_head_init(&bcs->rqueue);
skb_queue_head_init(&bcs->squeue);
skb_queue_head_init(&bcs->cmpl_queue);
clear_bit(BC_FLG_BUSY, &bcs->Flag);
bcs->tx_skb = NULL;
bcs->rcvidx = 0;
bcs->tx_cnt = 0;
bcs->event = 0;
return 0;
err_rcvbuf:
kfree(bcs->rcvbuf);
err:
clear_bit(BC_FLG_INIT, &bcs->Flag);
printk(KERN_WARNING "HiSax: %s: out of memory\n", __FUNCTION__);
return -ENOMEM;;
}
static inline void
bc_close(struct BCState *bcs)
{
if (!test_and_clear_bit(BC_FLG_INIT, &bcs->Flag))
return;
kfree(bcs->rcvbuf);
bcs->rcvbuf = NULL;
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;
clear_bit(BC_FLG_BUSY, &bcs->Flag);
}
}
...@@ -32,22 +32,12 @@ jade_write_reg(struct IsdnCardState *cs, int jade, u8 addr, u8 val) ...@@ -32,22 +32,12 @@ jade_write_reg(struct IsdnCardState *cs, int jade, u8 addr, u8 val)
cs->bc_hw_ops->write_reg(cs, jade, addr, val); cs->bc_hw_ops->write_reg(cs, jade, addr, val);
} }
static inline void
jade_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
jade_write_fifo(struct BCState *bcs, u8 *p, int len) jade_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
...@@ -112,7 +102,7 @@ void ...@@ -112,7 +102,7 @@ void
modejade(struct BCState *bcs, int mode, int bc) modejade(struct BCState *bcs, int mode, int bc)
{ {
struct IsdnCardState *cs = bcs->cs; struct IsdnCardState *cs = bcs->cs;
int jade = bcs->hw.hscx.hscx; int jade = bcs->unit;
if (cs->debug & L1_DEB_HSCX) { if (cs->debug & L1_DEB_HSCX) {
char tmp[40]; char tmp[40];
...@@ -200,52 +190,13 @@ void ...@@ -200,52 +190,13 @@ void
close_jadestate(struct BCState *bcs) close_jadestate(struct BCState *bcs)
{ {
modejade(bcs, 0, bcs->channel); modejade(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);
if (bcs->tx_skb) {
dev_kfree_skb_any(bcs->tx_skb);
bcs->tx_skb = NULL;
test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag);
}
}
} }
static int static int
open_jadestate(struct IsdnCardState *cs, struct BCState *bcs) open_jadestate(struct IsdnCardState *cs, struct BCState *bcs)
{ {
if (!test_and_set_bit(BC_FLG_INIT, &bcs->Flag)) { return 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);
}
bcs->tx_skb = NULL;
test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag);
bcs->event = 0;
bcs->hw.hscx.rcvidx = 0;
bcs->tx_cnt = 0;
return (0);
} }
...@@ -263,8 +214,12 @@ setstack_jade(struct PStack *st, struct BCState *bcs) ...@@ -263,8 +214,12 @@ setstack_jade(struct PStack *st, struct BCState *bcs)
return (0); return (0);
} }
static void jade_fill_fifo(struct BCState *bcs);
static struct bc_l1_ops jade_l1_ops = { static struct bc_l1_ops jade_l1_ops = {
.fill_fifo = jade_fill_fifo, .fill_fifo = jade_fill_fifo,
.open = setstack_jade,
.close = close_jadestate,
}; };
void __init void __init
...@@ -273,12 +228,8 @@ initjade(struct IsdnCardState *cs) ...@@ -273,12 +228,8 @@ initjade(struct IsdnCardState *cs)
int val; int val;
cs->bc_l1_ops = &jade_l1_ops; cs->bc_l1_ops = &jade_l1_ops;
cs->bcs[0].BC_SetStack = setstack_jade; cs->bcs[0].unit = 0;
cs->bcs[1].BC_SetStack = setstack_jade; cs->bcs[1].unit = 1;
cs->bcs[0].BC_Close = close_jadestate;
cs->bcs[1].BC_Close = close_jadestate;
cs->bcs[0].hw.hscx.hscx = 0;
cs->bcs[1].hw.hscx.hscx = 1;
jade_write_reg(cs, 0, jade_HDLC_IMR, 0x00); jade_write_reg(cs, 0, jade_HDLC_IMR, 0x00);
jade_write_reg(cs, 1, jade_HDLC_IMR, 0x00); jade_write_reg(cs, 1, jade_HDLC_IMR, 0x00);
......
...@@ -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__ */
...@@ -9,7 +9,6 @@ ...@@ -9,7 +9,6 @@
* of the GNU General Public License, incorporated herein by reference. * of the GNU General Public License, incorporated herein by reference.
* *
*/ */
static spinlock_t jade_irq_lock = SPIN_LOCK_UNLOCKED;
static inline void static inline void
waitforCEC(struct IsdnCardState *cs, int jade, int reg) waitforCEC(struct IsdnCardState *cs, int jade, int reg)
...@@ -26,20 +25,17 @@ waitforCEC(struct IsdnCardState *cs, int jade, int reg) ...@@ -26,20 +25,17 @@ waitforCEC(struct IsdnCardState *cs, int jade, int reg)
static inline void static inline void
waitforXFW(struct IsdnCardState *cs, int jade) waitforXFW(struct BCState *bcs)
{ {
/* Does not work on older jade versions, don't care */
} }
static inline void static inline void
WriteJADECMDR(struct IsdnCardState *cs, int jade, int reg, u8 data) WriteJADECMDR(struct BCState *bcs, int reg, u8 data)
{ {
unsigned long flags; int jade = bcs->unit;
spin_lock_irqsave(&jade_irq_lock, flags); waitforCEC(bcs->cs, jade, reg);
waitforCEC(cs, jade, reg); jade_write_reg(bcs->cs, jade, reg, data);
jade_write_reg(cs, jade, reg, data);
spin_unlock_irqrestore(&jade_irq_lock, flags);
} }
...@@ -47,49 +43,24 @@ WriteJADECMDR(struct IsdnCardState *cs, int jade, int reg, u8 data) ...@@ -47,49 +43,24 @@ WriteJADECMDR(struct IsdnCardState *cs, int jade, int reg, u8 data)
static void static void
jade_empty_fifo(struct BCState *bcs, int count) jade_empty_fifo(struct BCState *bcs, int count)
{ {
u8 *ptr; recv_empty_fifo_b(bcs, count);
struct IsdnCardState *cs = bcs->cs; WriteJADECMDR(bcs, jade_HDLC_RCMD, jadeRCMD_RMC);
if ((cs->debug & L1_DEB_HSCX) && !(cs->debug & L1_DEB_HSCX_FIFO))
debugl1(cs, "jade_empty_fifo");
if (bcs->hw.hscx.rcvidx + count > HSCX_BUFMAX) {
if (cs->debug & L1_DEB_WARN)
debugl1(cs, "jade_empty_fifo: incoming packet too large");
WriteJADECMDR(cs, bcs->hw.hscx.hscx, jade_HDLC_RCMD, jadeRCMD_RMC);
bcs->hw.hscx.rcvidx = 0;
return;
}
ptr = bcs->hw.hscx.rcvbuf + bcs->hw.hscx.rcvidx;
bcs->hw.hscx.rcvidx += count;
jade_read_fifo(bcs, ptr, count);
WriteJADECMDR(cs, bcs->hw.hscx.hscx, jade_HDLC_RCMD, jadeRCMD_RMC);
if (cs->debug & L1_DEB_HSCX_FIFO) {
char *t = bcs->blog;
t += sprintf(t, "jade_empty_fifo %c cnt %d",
bcs->hw.hscx.hscx ? 'B' : 'A', count);
QuickHex(t, ptr, count);
debugl1(cs, bcs->blog);
}
} }
void static void
jade_fill_fifo(struct BCState *bcs) jade_fill_fifo(struct BCState *bcs)
{ {
struct IsdnCardState *cs = bcs->cs;
int more, count; int more, count;
int fifo_size = 32; int fifo_size = 32;
int hscx = bcs->hw.hscx.hscx;
unsigned char *p; unsigned char *p;
p = xmit_fill_fifo_b(bcs, fifo_size, &count, &more); p = xmit_fill_fifo_b(bcs, fifo_size, &count, &more);
if (!p) if (!p)
return; return;
waitforXFW(cs, hscx); waitforXFW(bcs);
jade_write_fifo(bcs, p, count); jade_write_fifo(bcs, p, count);
WriteJADECMDR(cs, hscx, jade_HDLC_XCMD, WriteJADECMDR(bcs, jade_HDLC_XCMD,
more ? jadeXCMD_XF : (jadeXCMD_XF|jadeXCMD_XME)); more ? jadeXCMD_XF : (jadeXCMD_XF|jadeXCMD_XME));
} }
...@@ -99,7 +70,6 @@ jade_interrupt(struct IsdnCardState *cs, u8 val, u8 jade) ...@@ -99,7 +70,6 @@ jade_interrupt(struct IsdnCardState *cs, u8 val, u8 jade)
{ {
u8 r; u8 r;
struct BCState *bcs = cs->bcs + jade; struct BCState *bcs = cs->bcs + jade;
struct sk_buff *skb;
int fifo_size = 32; int fifo_size = 32;
int count; int count;
int i_jade = (int) jade; /* To satisfy the compiler */ int i_jade = (int) jade; /* To satisfy the compiler */
...@@ -119,39 +89,20 @@ jade_interrupt(struct IsdnCardState *cs, u8 val, u8 jade) ...@@ -119,39 +89,20 @@ jade_interrupt(struct IsdnCardState *cs, u8 val, u8 jade)
if (!(r & 0x20)) if (!(r & 0x20))
if (cs->debug & L1_DEB_WARN) if (cs->debug & L1_DEB_WARN)
debugl1(cs, "JADE %c CRC error", 'A'+jade); debugl1(cs, "JADE %c CRC error", 'A'+jade);
WriteJADECMDR(cs, jade, jade_HDLC_RCMD, jadeRCMD_RMC); WriteJADECMDR(bcs, jade_HDLC_RCMD, jadeRCMD_RMC);
bcs->rcvidx = 0;
} else { } else {
count = jade_read_reg(cs, i_jade, jade_HDLC_RBCL) & 0x1F; count = jade_read_reg(cs, i_jade, jade_HDLC_RBCL) & 0x1F;
if (count == 0) if (count == 0)
count = fifo_size; count = fifo_size;
jade_empty_fifo(bcs, count); jade_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 "JADE %s receive out of memory\n", (jade ? "B":"A"));
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 */
jade_empty_fifo(bcs, fifo_size); jade_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) { /* XPR */ if (val & 0x10) { /* XPR */
xmit_xpr_b(bcs); xmit_xpr_b(bcs);
...@@ -161,7 +112,7 @@ jade_interrupt(struct IsdnCardState *cs, u8 val, u8 jade) ...@@ -161,7 +112,7 @@ jade_interrupt(struct IsdnCardState *cs, u8 val, u8 jade)
static void static void
reset_xmit(struct BCState *bcs) reset_xmit(struct BCState *bcs)
{ {
WriteJADECMDR(bcs->cs, bcs->hw.hscx.hscx, jade_HDLC_XCMD, jadeXCMD_XRES); WriteJADECMDR(bcs, jade_HDLC_XCMD, jadeXCMD_XRES);
} }
void void
......
...@@ -937,6 +937,8 @@ setstack_tiger(struct PStack *st, struct BCState *bcs) ...@@ -937,6 +937,8 @@ setstack_tiger(struct PStack *st, struct BCState *bcs)
static struct bc_l1_ops netjet_l1_ops = { static struct bc_l1_ops netjet_l1_ops = {
.fill_fifo = netjet_fill_dma, .fill_fifo = netjet_fill_dma,
.open = setstack_tiger,
.close = close_tigerstate,
}; };
void __init void __init
...@@ -994,10 +996,6 @@ inittiger(struct IsdnCardState *cs) ...@@ -994,10 +996,6 @@ inittiger(struct IsdnCardState *cs)
inl(cs->hw.njet.base + NETJET_DMA_READ_ADR), inl(cs->hw.njet.base + NETJET_DMA_READ_ADR),
bytein(cs->hw.njet.base + NETJET_PULSE_CNT)); bytein(cs->hw.njet.base + NETJET_PULSE_CNT));
cs->hw.njet.last_is0 = 0; 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 void
......
...@@ -57,7 +57,7 @@ w6692_write_reg(struct IsdnCardState *cs, u8 offset, u8 value) ...@@ -57,7 +57,7 @@ w6692_write_reg(struct IsdnCardState *cs, u8 offset, u8 value)
outb(value, cs->hw.w6692.iobase + offset); outb(value, cs->hw.w6692.iobase + offset);
} }
static inline void static void
w6692_read_fifo(struct IsdnCardState *cs, u8 * data, int size) w6692_read_fifo(struct IsdnCardState *cs, u8 * data, int size)
{ {
insb(cs->hw.w6692.iobase + W_D_RFIFO, data, size); insb(cs->hw.w6692.iobase + W_D_RFIFO, data, size);
...@@ -69,6 +69,10 @@ w6692_write_fifo(struct IsdnCardState *cs, u8 * data, int size) ...@@ -69,6 +69,10 @@ w6692_write_fifo(struct IsdnCardState *cs, u8 * data, int size)
outsb(cs->hw.w6692.iobase + W_D_XFIFO, data, size); outsb(cs->hw.w6692.iobase + W_D_XFIFO, data, size);
} }
static struct dc_hw_ops w6692_dc_hw_ops = {
.read_fifo = w6692_read_fifo,
};
static inline u8 static inline u8
w6692_bc_read_reg(struct IsdnCardState *cs, int bchan, u8 offset) w6692_bc_read_reg(struct IsdnCardState *cs, int bchan, u8 offset)
{ {
...@@ -81,6 +85,16 @@ w6692_bc_write_reg(struct IsdnCardState *cs, int bchan, u8 offset, u8 value) ...@@ -81,6 +85,16 @@ w6692_bc_write_reg(struct IsdnCardState *cs, int bchan, u8 offset, u8 value)
outb(value, cs->hw.w6692.iobase + (bchan ? 0x40 : 0) + offset); outb(value, cs->hw.w6692.iobase + (bchan ? 0x40 : 0) + offset);
} }
static void
w6692_bc_read_fifo(struct IsdnCardState *cs, int bchan, u8 *data, int len)
{
insb(cs->hw.w6692.iobase + W_B_RFIFO + (bchan ? 0x40:0), data, len);
}
static struct bc_hw_ops w6692_bc_hw_ops = {
.read_fifo = w6692_bc_read_fifo,
};
static char *W6692Ver[] __initdata = static char *W6692Ver[] __initdata =
{"W6692 V00", "W6692 V01", "W6692 V10", {"W6692 V00", "W6692 V01", "W6692 V10",
"W6692 V11"}; "W6692 V11"};
...@@ -171,30 +185,8 @@ W6692_bh(void *data) ...@@ -171,30 +185,8 @@ W6692_bh(void *data)
static void static void
W6692_empty_fifo(struct IsdnCardState *cs, int count) W6692_empty_fifo(struct IsdnCardState *cs, int count)
{ {
u8 *ptr; recv_empty_fifo_d(cs, count);
if ((cs->debug & L1_DEB_ISAC) && !(cs->debug & L1_DEB_ISAC_FIFO))
debugl1(cs, "W6692_empty_fifo");
if ((cs->rcvidx + count) >= MAX_DFRAME_LEN_L1) {
if (cs->debug & L1_DEB_WARN)
debugl1(cs, "W6692_empty_fifo overrun %d",
cs->rcvidx + count);
w6692_write_reg(cs, W_D_CMDR, W_D_CMDR_RACK);
cs->rcvidx = 0;
return;
}
ptr = cs->rcvbuf + cs->rcvidx;
cs->rcvidx += count;
w6692_read_fifo(cs, ptr, count);
w6692_write_reg(cs, W_D_CMDR, W_D_CMDR_RACK); w6692_write_reg(cs, W_D_CMDR, W_D_CMDR_RACK);
if (cs->debug & L1_DEB_ISAC_FIFO) {
char *t = cs->dlog;
t += sprintf(t, "W6692_empty_fifo cnt %d", count);
QuickHex(t, ptr, count);
debugl1(cs, cs->dlog);
}
} }
static void static void
...@@ -221,31 +213,8 @@ W6692_fill_fifo(struct IsdnCardState *cs) ...@@ -221,31 +213,8 @@ W6692_fill_fifo(struct IsdnCardState *cs)
static void static void
W6692B_empty_fifo(struct BCState *bcs, int count) W6692B_empty_fifo(struct BCState *bcs, int count)
{ {
u8 *ptr; recv_empty_fifo_b(bcs, count);
struct IsdnCardState *cs = bcs->cs; w6692_bc_write_reg(bcs->cs, bcs->channel, W_B_CMDR, W_B_CMDR_RACK | W_B_CMDR_RACT);
if ((cs->debug & L1_DEB_HSCX) && !(cs->debug & L1_DEB_HSCX_FIFO))
debugl1(cs, "W6692B_empty_fifo");
if (bcs->hw.w6692.rcvidx + count > HSCX_BUFMAX) {
if (cs->debug & L1_DEB_WARN)
debugl1(cs, "W6692B_empty_fifo: incoming packet too large");
w6692_bc_write_reg(cs, bcs->channel, W_B_CMDR, W_B_CMDR_RACK | W_B_CMDR_RACT);
bcs->hw.w6692.rcvidx = 0;
return;
}
ptr = bcs->hw.w6692.rcvbuf + bcs->hw.w6692.rcvidx;
bcs->hw.w6692.rcvidx += count;
READW6692BFIFO(cs, bcs->channel, ptr, count);
w6692_bc_write_reg(cs, bcs->channel, W_B_CMDR, W_B_CMDR_RACK | W_B_CMDR_RACT);
if (cs->debug & L1_DEB_HSCX_FIFO) {
char *t = bcs->blog;
t += sprintf(t, "W6692B_empty_fifo %c cnt %d",
bcs->channel + '1', count);
QuickHex(t, ptr, count);
debugl1(cs, bcs->blog);
}
} }
static void static void
...@@ -276,7 +245,6 @@ W6692B_interrupt(struct IsdnCardState *cs, u8 bchan) ...@@ -276,7 +245,6 @@ W6692B_interrupt(struct IsdnCardState *cs, u8 bchan)
u8 val; u8 val;
u8 r; u8 r;
struct BCState *bcs; struct BCState *bcs;
struct sk_buff *skb;
int count; int count;
bcs = (cs->bcs->channel == bchan) ? cs->bcs : (cs->bcs+1); bcs = (cs->bcs->channel == bchan) ? cs->bcs : (cs->bcs+1);
...@@ -298,38 +266,18 @@ W6692B_interrupt(struct IsdnCardState *cs, u8 bchan) ...@@ -298,38 +266,18 @@ W6692B_interrupt(struct IsdnCardState *cs, u8 bchan)
if (cs->debug & L1_DEB_WARN) if (cs->debug & L1_DEB_WARN)
debugl1(cs, "W6692 B CRC error"); debugl1(cs, "W6692 B CRC error");
w6692_bc_write_reg(cs, bchan, W_B_CMDR, W_B_CMDR_RACK | W_B_CMDR_RRST | W_B_CMDR_RACT); w6692_bc_write_reg(cs, bchan, W_B_CMDR, W_B_CMDR_RACK | W_B_CMDR_RRST | W_B_CMDR_RACT);
bcs->rcvidx = 0;
} else { } else {
count = w6692_bc_read_reg(cs, bchan, W_B_RBCL) & (W_B_FIFO_THRESH - 1); count = w6692_bc_read_reg(cs, bchan, W_B_RBCL) & (W_B_FIFO_THRESH - 1);
if (count == 0) if (count == 0)
count = W_B_FIFO_THRESH; count = W_B_FIFO_THRESH;
W6692B_empty_fifo(bcs, count); W6692B_empty_fifo(bcs, count);
if ((count = bcs->hw.w6692.rcvidx) > 0) { recv_rme_b(bcs);
if (cs->debug & L1_DEB_HSCX_FIFO)
debugl1(cs, "W6692 Bchan Frame %d", count);
if (!(skb = dev_alloc_skb(count)))
printk(KERN_WARNING "W6692: Bchan receive out of memory\n");
else {
memcpy(skb_put(skb, count), bcs->hw.w6692.rcvbuf, count);
skb_queue_tail(&bcs->rqueue, skb);
}
}
} }
bcs->hw.w6692.rcvidx = 0;
sched_b_event(bcs, B_RCVBUFREADY);
} }
if (val & W_B_EXI_RMR) { /* RMR */ if (val & W_B_EXI_RMR) { /* RMR */
W6692B_empty_fifo(bcs, W_B_FIFO_THRESH); W6692B_empty_fifo(bcs, W_B_FIFO_THRESH);
if (bcs->mode == L1_MODE_TRANS) { recv_rpf_b(bcs);
/* receive audio data */
if (!(skb = dev_alloc_skb(W_B_FIFO_THRESH)))
printk(KERN_WARNING "HiSax: receive out of memory\n");
else {
memcpy(skb_put(skb, W_B_FIFO_THRESH), bcs->hw.w6692.rcvbuf, W_B_FIFO_THRESH);
skb_queue_tail(&bcs->rqueue, skb);
}
bcs->hw.w6692.rcvidx = 0;
sched_b_event(bcs, B_RCVBUFREADY);
}
} }
if (val & W_B_EXI_XFR) { /* XFR */ if (val & W_B_EXI_XFR) { /* XFR */
xmit_xpr_b(bcs); xmit_xpr_b(bcs);
...@@ -344,7 +292,6 @@ W6692_interrupt(int intno, void *dev_id, struct pt_regs *regs) ...@@ -344,7 +292,6 @@ W6692_interrupt(int intno, void *dev_id, struct pt_regs *regs)
{ {
struct IsdnCardState *cs = dev_id; struct IsdnCardState *cs = dev_id;
u8 val, exval, v1; u8 val, exval, v1;
struct sk_buff *skb;
unsigned int count; unsigned int count;
int icnt = 5; int icnt = 5;
...@@ -369,24 +316,15 @@ W6692_interrupt(int intno, void *dev_id, struct pt_regs *regs) ...@@ -369,24 +316,15 @@ W6692_interrupt(int intno, void *dev_id, struct pt_regs *regs)
if (cs->debug & L1_DEB_WARN) if (cs->debug & L1_DEB_WARN)
debugl1(cs, "W6692 D-channel ABORT"); debugl1(cs, "W6692 D-channel ABORT");
w6692_write_reg(cs, W_D_CMDR, W_D_CMDR_RACK | W_D_CMDR_RRST); w6692_write_reg(cs, W_D_CMDR, W_D_CMDR_RACK | W_D_CMDR_RRST);
cs->rcvidx = 0;
} else { } else {
count = w6692_read_reg(cs, W_D_RBCL) & (W_D_FIFO_THRESH - 1); count = w6692_read_reg(cs, W_D_RBCL) & (W_D_FIFO_THRESH - 1);
if (count == 0) if (count == 0)
count = W_D_FIFO_THRESH; count = W_D_FIFO_THRESH;
W6692_empty_fifo(cs, count); W6692_empty_fifo(cs, count);
if ((count = cs->rcvidx) > 0) { recv_rme_d(cs);
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);
} }
} }
}
cs->rcvidx = 0;
sched_d_event(cs, D_RCVBUFREADY);
}
if (val & W_INT_D_RMR) { /* RMR */ if (val & W_INT_D_RMR) { /* RMR */
W6692_empty_fifo(cs, W_D_FIFO_THRESH); W6692_empty_fifo(cs, W_D_FIFO_THRESH);
} }
...@@ -632,52 +570,13 @@ static void ...@@ -632,52 +570,13 @@ static void
close_w6692state(struct BCState *bcs) close_w6692state(struct BCState *bcs)
{ {
W6692Bmode(bcs, 0, bcs->channel); W6692Bmode(bcs, 0, bcs->channel);
if (test_and_clear_bit(BC_FLG_INIT, &bcs->Flag)) { bc_close(bcs);
if (bcs->hw.w6692.rcvbuf) {
kfree(bcs->hw.w6692.rcvbuf);
bcs->hw.w6692.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);
}
}
} }
static int static int
open_w6692state(struct IsdnCardState *cs, struct BCState *bcs) open_w6692state(struct IsdnCardState *cs, struct BCState *bcs)
{ {
if (!test_and_set_bit(BC_FLG_INIT, &bcs->Flag)) { return bc_open(bcs);
if (!(bcs->hw.w6692.rcvbuf = kmalloc(HSCX_BUFMAX, GFP_ATOMIC))) {
printk(KERN_WARNING
"HiSax: No memory for w6692.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.w6692.rcvbuf);
bcs->hw.w6692.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.w6692.rcvidx = 0;
bcs->tx_cnt = 0;
return (0);
} }
static int static int
...@@ -731,10 +630,6 @@ void __init initW6692(struct IsdnCardState *cs, int part) ...@@ -731,10 +630,6 @@ void __init initW6692(struct IsdnCardState *cs, int part)
W6692_new_ph(cs); W6692_new_ph(cs);
ph_command(cs, W_L1CMD_ECK); ph_command(cs, W_L1CMD_ECK);
cs->bcs[0].BC_SetStack = setstack_w6692;
cs->bcs[1].BC_SetStack = setstack_w6692;
cs->bcs[0].BC_Close = close_w6692state;
cs->bcs[1].BC_Close = close_w6692state;
W6692Bmode(cs->bcs, 0, 0); W6692Bmode(cs->bcs, 0, 0);
W6692Bmode(cs->bcs + 1, 0, 0); W6692Bmode(cs->bcs + 1, 0, 0);
} }
...@@ -774,6 +669,8 @@ w6692_card_msg(struct IsdnCardState *cs, int mt, void *arg) ...@@ -774,6 +669,8 @@ w6692_card_msg(struct IsdnCardState *cs, int mt, void *arg)
static struct bc_l1_ops w6692_bc_l1_ops = { static struct bc_l1_ops w6692_bc_l1_ops = {
.fill_fifo = W6692B_fill_fifo, .fill_fifo = W6692B_fill_fifo,
.open = setstack_w6692,
.close = close_w6692state,
}; };
static int id_idx ; static int id_idx ;
...@@ -864,6 +761,8 @@ setup_w6692(struct IsdnCard *card) ...@@ -864,6 +761,8 @@ setup_w6692(struct IsdnCard *card)
id_list[cs->subtyp].card_name, cs->irq, id_list[cs->subtyp].card_name, cs->irq,
cs->hw.w6692.iobase); cs->hw.w6692.iobase);
cs->dc_hw_ops = &w6692_dc_hw_ops;
cs->bc_hw_ops = &w6692_bc_hw_ops;
cs->bc_l1_ops = &w6692_bc_l1_ops; cs->bc_l1_ops = &w6692_bc_l1_ops;
cs->DC_Send_Data = &W6692_fill_fifo; cs->DC_Send_Data = &W6692_fill_fifo;
cs->cardmsg = &w6692_card_msg; cs->cardmsg = &w6692_card_msg;
......
...@@ -18,9 +18,6 @@ ...@@ -18,9 +18,6 @@
/* B-channel FIFO read/write routines */ /* B-channel FIFO read/write routines */
#define READW6692BFIFO(cs,bchan,ptr,count) \
insb(cs->hw.w6692.iobase+W_B_RFIFO+(bchan?0x40:0),ptr,count)
#define WRITEW6692BFIFO(cs,bchan,ptr,count) \ #define WRITEW6692BFIFO(cs,bchan,ptr,count) \
outsb(cs->hw.w6692.iobase+W_B_XFIFO+(bchan?0x40:0),ptr,count) outsb(cs->hw.w6692.iobase+W_B_XFIFO+(bchan?0x40:0),ptr,count)
......
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