📄 amd7930.c
字号:
if (!test_and_set_bit(BC_FLG_INIT, &bcs->Flag)) { skb_queue_head_init(&bcs->rqueue); skb_queue_head_init(&bcs->squeue); } test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag); amd7930_bopen(0, bcs->channel, 0xff); hw->rv_buff_in = 0; hw->rv_buff_out = 0; hw->tx_skb = NULL; init_hdlc_state(hw->hdlc_state, 0); amd7930_brecv(0, bcs->channel, hw->rv_buff + hw->rv_buff_in, RCV_BUFSIZE/RCV_BUFBLKS, (void *) &Bchan_recv_callback, (void *) bcs); bcs->event = 0; bcs->tx_cnt = 0; return (0);}static voidBchan_init(struct BCState *bcs){ if (!(bcs->hw.amd7930.tx_buff = kmalloc(RAW_BUFMAX, GFP_ATOMIC))) { printk(KERN_WARNING "HiSax: No memory for amd7930.tx_buff\n"); return; } if (!(bcs->hw.amd7930.rv_buff = kmalloc(RCV_BUFSIZE, GFP_ATOMIC))) { printk(KERN_WARNING "HiSax: No memory for amd7930.rv_buff\n"); return; } if (!(bcs->hw.amd7930.rv_skb = dev_alloc_skb(HSCX_BUFMAX))) { printk(KERN_WARNING "HiSax: No memory for amd7930.rv_skb\n"); return; } if (!(bcs->hw.amd7930.hdlc_state = kmalloc(sizeof(struct hdlc_state), GFP_ATOMIC))) { printk(KERN_WARNING "HiSax: No memory for amd7930.hdlc_state\n"); return; } bcs->hw.amd7930.tq_rcv.sync = 0; bcs->hw.amd7930.tq_rcv.routine = (void (*)(void *)) &Bchan_rcv_bh; bcs->hw.amd7930.tq_rcv.data = (void *) bcs; bcs->hw.amd7930.tq_xmt.sync = 0; bcs->hw.amd7930.tq_xmt.routine = (void (*)(void *)) &Bchan_xmt_bh; bcs->hw.amd7930.tq_xmt.data = (void *) bcs;}static voidBchan_manl1(struct PStack *st, int pr, void *arg){ switch (pr) { case (PH_ACTIVATE_REQ): test_and_set_bit(BC_FLG_ACTIV, &st->l1.bcs->Flag); Bchan_mode(st->l1.bcs, st->l1.mode, st->l1.bc); st->l1.l1man(st, PH_ACTIVATE_CNF, NULL); break; case (PH_DEACTIVATE_REQ): if (!test_bit(BC_FLG_BUSY, &st->l1.bcs->Flag)) Bchan_mode(st->l1.bcs, 0, 0); test_and_clear_bit(BC_FLG_ACTIV, &st->l1.bcs->Flag); break; }}intsetstack_amd7930(struct PStack *st, struct BCState *bcs){ if (Bchan_open(bcs)) return (-1); st->l1.bcs = bcs; st->l2.l2l1 = Bchan_l2l1; st->ma.manl1 = Bchan_manl1; setstack_manager(st); bcs->st = st; return (0);}static voidamd7930_drecv_callback(void *arg, int error, unsigned int count){ struct IsdnCardState *cs = (struct IsdnCardState *) arg; static struct tq_struct task; struct sk_buff *skb; /* NOTE: This function is called directly from an interrupt handler */ if (1) { 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); } task.routine = (void *) DChannel_proc_rcv; task.data = (void *) cs; queue_task(&task, &tq_immediate); mark_bh(IMMEDIATE_BH); } if (cs->debug & L1_DEB_ISAC_FIFO) { char tmp[128]; char *t = tmp; t += sprintf(t, "amd7930 Drecv cnt %d", count); if (error) t += sprintf(t, " ERR %x", error); QuickHex(t, cs->rcvbuf, count); debugl1(cs, tmp); } amd7930_drecv(0, cs->rcvbuf, MAX_DFRAME_LEN, &amd7930_drecv_callback, cs);}static voidamd7930_dxmit_callback(void *arg, int error){ struct IsdnCardState *cs = (struct IsdnCardState *) arg; static struct tq_struct task; /* NOTE: This function is called directly from an interrupt handler */ /* may wish to do retransmission here, if error indicates collision */ if (cs->debug & L1_DEB_ISAC_FIFO) { char tmp[128]; char *t = tmp; t += sprintf(t, "amd7930 Dxmit cnt %d", cs->tx_skb->len); if (error) t += sprintf(t, " ERR %x", error); QuickHex(t, cs->tx_skb->data, cs->tx_skb->len); debugl1(cs, tmp); } cs->tx_skb = NULL; task.routine = (void *) DChannel_proc_xmt; task.data = (void *) cs; queue_task(&task, &tq_immediate); mark_bh(IMMEDIATE_BH);}static voidamd7930_Dchan_l2l1(struct PStack *st, int pr, void *arg){ struct IsdnCardState *cs = (struct IsdnCardState *) st->l1.hardware; struct sk_buff *skb = arg; char str[64]; switch (pr) { case (PH_DATA_REQ): if (cs->tx_skb) { skb_queue_tail(&cs->sq, skb);#ifdef L2FRAME_DEBUG /* psa */ if (cs->debug & L1_DEB_LAPD) Logl2Frame(cs, skb, "PH_DATA Queued", 0);#endif } else { if ((cs->dlogflag) && (!(skb->data[2] & 1))) { /* I-FRAME */ LogFrame(cs, skb->data, skb->len); sprintf(str, "Q.931 frame user->network tei %d", st->l2.tei); dlogframe(cs, skb->data+4, skb->len-4, str); } cs->tx_skb = skb; cs->tx_cnt = 0;#ifdef L2FRAME_DEBUG /* psa */ if (cs->debug & L1_DEB_LAPD) Logl2Frame(cs, skb, "PH_DATA", 0);#endif amd7930_dxmit(0, skb->data, skb->len, &amd7930_dxmit_callback, cs); } break; case (PH_PULL_IND): if (cs->tx_skb) { if (cs->debug & L1_DEB_WARN) debugl1(cs, " l2l1 tx_skb exist this shouldn't happen"); skb_queue_tail(&cs->sq, skb); break; } if ((cs->dlogflag) && (!(skb->data[2] & 1))) { /* I-FRAME */ LogFrame(cs, skb->data, skb->len); sprintf(str, "Q.931 frame user->network tei %d", st->l2.tei); dlogframe(cs, skb->data + 4, skb->len - 4, str); } cs->tx_skb = skb; cs->tx_cnt = 0;#ifdef L2FRAME_DEBUG /* psa */ if (cs->debug & L1_DEB_LAPD) Logl2Frame(cs, skb, "PH_DATA_PULLED", 0);#endif amd7930_dxmit(0, cs->tx_skb->data, cs->tx_skb->len, &amd7930_dxmit_callback, cs); break; case (PH_PULL_REQ):#ifdef L2FRAME_DEBUG /* psa */ if (cs->debug & L1_DEB_LAPD) debugl1(cs, "-> PH_REQUEST_PULL");#endif if (!cs->tx_skb) { test_and_clear_bit(FLG_L1_PULL_REQ, &st->l1.Flags); st->l1.l1l2(st, PH_PULL_CNF, NULL); } else test_and_set_bit(FLG_L1_PULL_REQ, &st->l1.Flags); break; }}intsetDstack_amd7930(struct PStack *st, struct IsdnCardState *cs){ st->l2.l2l1 = amd7930_Dchan_l2l1; if (! cs->rcvbuf) { printk("setDstack_amd7930: No cs->rcvbuf!\n"); } else { amd7930_drecv(0, cs->rcvbuf, MAX_DFRAME_LEN, &amd7930_drecv_callback, cs); } return (0);}static voidmanl1_msg(struct IsdnCardState *cs, int msg, void *arg) { struct PStack *st; st = cs->stlist; while (st) { st->ma.manl1(st, msg, arg); st = st->next; }}static voidamd7930_new_ph(struct IsdnCardState *cs){ switch (amd7930_get_liu_state(0)) { case 3: manl1_msg(cs, PH_POWERUP_CNF, NULL); break; case 7: manl1_msg(cs, PH_I4_P8_IND, NULL); break; case 8: manl1_msg(cs, PH_RSYNC_IND, NULL); break; }}/* amd7930 LIU state change callback */static voidamd7930_liu_callback(struct IsdnCardState *cs){ static struct tq_struct task; if (!cs) return; if (cs->debug & L1_DEB_ISAC) { char tmp[32]; sprintf(tmp, "amd7930_liu state %d", amd7930_get_liu_state(0)); debugl1(cs, tmp); } task.sync = 0; task.routine = (void *) &amd7930_new_ph; task.data = (void *) cs; queue_task(&task, &tq_immediate); mark_bh(IMMEDIATE_BH);}voidamd7930_l1cmd(struct IsdnCardState *cs, int msg, void *arg){ u_char val; char tmp[32]; if (cs->debug & L1_DEB_ISAC) { char tmp[32]; sprintf(tmp, "amd7930_l1cmd msg %x", msg); debugl1(cs, tmp); } switch(msg) { case PH_RESET_REQ: if (amd7930_get_liu_state(0) <= 3) amd7930_liu_activate(0,0); else amd7930_liu_deactivate(0); break; case PH_ENABLE_REQ: break; case PH_INFO3_REQ: amd7930_liu_activate(0,0); break; case PH_TESTLOOP_REQ: break; default: if (cs->debug & L1_DEB_WARN) { sprintf(tmp, "amd7930_l1cmd unknown %4x", msg); debugl1(cs, tmp); } break; }}static void init_amd7930(struct IsdnCardState *cs){ Bchan_init(&cs->bcs[0]); Bchan_init(&cs->bcs[1]); cs->bcs[0].BC_SetStack = setstack_amd7930; cs->bcs[1].BC_SetStack = setstack_amd7930; cs->bcs[0].BC_Close = Bchan_close; cs->bcs[1].BC_Close = Bchan_close; Bchan_mode(cs->bcs, 0, 0); Bchan_mode(cs->bcs + 1, 0, 0);}voidrelease_amd7930(struct IsdnCardState *cs){}static intamd7930_card_msg(struct IsdnCardState *cs, int mt, void *arg){ switch (mt) { case CARD_RESET: return(0); case CARD_RELEASE: release_amd7930(cs); return(0); case CARD_INIT: cs->l1cmd = amd7930_l1cmd; amd7930_liu_init(0, &amd7930_liu_callback, (void *)cs); init_amd7930(cs); return(0); case CARD_TEST: return(0); } return(0);}int __initsetup_amd7930(struct IsdnCard *card){ struct IsdnCardState *cs = card->cs; char tmp[64]; strcpy(tmp, amd7930_revision); printk(KERN_INFO "HiSax: AMD7930 driver Rev. %s\n", HiSax_getrev(tmp)); if (cs->typ != ISDN_CTYPE_AMD7930) return (0); cs->irq = amd7930_get_irqnum(0); if (cs->irq == 0) return (0); cs->cardmsg = &amd7930_card_msg; return (1);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -