📄 b1lli.c
字号:
b1outp(base, B1_RESET, 0); udelay(55 * 2 * 1000); /* 2 TIC's */}void T1_reset(unsigned int base){ /* reset T1 Controller */ B1_reset(base); /* disable irq on HEMA */ t1outp(base, B1_INSTAT, 0x00); t1outp(base, B1_OUTSTAT, 0x00); t1outp(base, T1_IRQMASTER, 0x00); /* reset HEMA board configuration */ t1outp(base, T1_RESETBOARD, 0xf);}int B1_detect(unsigned int base, int cardtype){ int onoff, i; if (cardtype == AVM_CARDTYPE_T1) return 0; /* * Statusregister 0000 00xx */ if ((inb(base + B1_INSTAT) & 0xfc) || (inb(base + B1_OUTSTAT) & 0xfc)) return 1; /* * Statusregister 0000 001x */ b1outp(base, B1_INSTAT, 0x2); /* enable irq */ /* b1outp(base, B1_OUTSTAT, 0x2); */ if ((inb(base + B1_INSTAT) & 0xfe) != 0x2 /* || (inb(base + B1_OUTSTAT) & 0xfe) != 0x2 */) return 2; /* * Statusregister 0000 000x */ b1outp(base, B1_INSTAT, 0x0); /* disable irq */ b1outp(base, B1_OUTSTAT, 0x0); if ((inb(base + B1_INSTAT) & 0xfe) || (inb(base + B1_OUTSTAT) & 0xfe)) return 3; for (onoff = !0, i= 0; i < 10 ; i++) { b1_set_test_bit(base, cardtype, onoff); if (b1_get_test_bit(base, cardtype) != onoff) return 4; onoff = !onoff; } if (cardtype == AVM_CARDTYPE_M1) return 0; if ((b1_rd_reg(base, B1_STAT1(cardtype)) & 0x0f) != 0x01) return 5; return 0;}int T1_detectandinit(unsigned int base, unsigned irq, int cardnr){ unsigned char cregs[8]; unsigned char reverse_cardnr; unsigned long flags; unsigned char dummy; int i; reverse_cardnr = ((cardnr & 0x01) << 3) | ((cardnr & 0x02) << 1) | ((cardnr & 0x04) >> 1) | ((cardnr & 0x08) >> 3); cregs[0] = (HEMA_VERSION_ID << 4) | (reverse_cardnr & 0xf); cregs[1] = 0x00; /* fast & slow link connected to CON1 */ cregs[2] = 0x05; /* fast link 20MBit, slow link 20 MBit */ cregs[3] = 0; cregs[4] = 0x11; /* zero wait state */ cregs[5] = hema_irq_table[irq & 0xf]; cregs[6] = 0; cregs[7] = 0; save_flags(flags); cli(); /* board reset */ t1outp(base, T1_RESETBOARD, 0xf); udelay(100 * 1000); dummy = t1inp(base, T1_FASTLINK+T1_OUTSTAT); /* first read */ /* write config */ dummy = (base >> 4) & 0xff; for (i=1;i<=0xf;i++) t1outp(base, i, dummy); t1outp(base, HEMA_PAL_ID & 0xf, dummy); t1outp(base, HEMA_PAL_ID >> 4, cregs[0]); for(i=1;i<7;i++) t1outp(base, 0, cregs[i]); t1outp(base, ((base >> 4)) & 0x3, cregs[7]); restore_flags(flags); udelay(100 * 1000); t1outp(base, T1_FASTLINK+T1_RESETLINK, 0); t1outp(base, T1_SLOWLINK+T1_RESETLINK, 0); udelay(10 * 1000); t1outp(base, T1_FASTLINK+T1_RESETLINK, 1); t1outp(base, T1_SLOWLINK+T1_RESETLINK, 1); udelay(100 * 1000); t1outp(base, T1_FASTLINK+T1_RESETLINK, 0); t1outp(base, T1_SLOWLINK+T1_RESETLINK, 0); udelay(10 * 1000); t1outp(base, T1_FASTLINK+T1_ANALYSE, 0); udelay(5 * 1000); t1outp(base, T1_SLOWLINK+T1_ANALYSE, 0); if (t1inp(base, T1_FASTLINK+T1_OUTSTAT) != 0x1) /* tx empty */ return 1; if (t1inp(base, T1_FASTLINK+T1_INSTAT) != 0x0) /* rx empty */ return 2; if (t1inp(base, T1_FASTLINK+T1_IRQENABLE) != 0x0) return 3; if ((t1inp(base, T1_FASTLINK+T1_FIFOSTAT) & 0xf0) != 0x70) return 4; if ((t1inp(base, T1_FASTLINK+T1_IRQMASTER) & 0x0e) != 0) return 5; if ((t1inp(base, T1_FASTLINK+T1_IDENT) & 0x7d) != 1) return 6; if (t1inp(base, T1_SLOWLINK+T1_OUTSTAT) != 0x1) /* tx empty */ return 7; if ((t1inp(base, T1_SLOWLINK+T1_IRQMASTER) & 0x0e) != 0) return 8; if ((t1inp(base, T1_SLOWLINK+T1_IDENT) & 0x7d) != 0) return 9; return 0;}extern int loaddebug;int B1_load_t4file(unsigned int base, avmb1_t4file * t4file){ /* * Data is in user space !!! */ unsigned char buf[256]; unsigned char *dp; int i, left, retval; dp = t4file->data; left = t4file->len; while (left > sizeof(buf)) { retval = copy_from_user(buf, dp, sizeof(buf)); if (retval) return -EFAULT; if (loaddebug) printk(KERN_DEBUG "b1capi: loading: %d bytes ..", sizeof(buf)); for (i = 0; i < sizeof(buf); i++) B1_put_byte(base, buf[i]); if (loaddebug) printk("ok\n"); left -= sizeof(buf); dp += sizeof(buf); } if (left) { retval = copy_from_user(buf, dp, left); if (retval) return -EFAULT; if (loaddebug) printk(KERN_DEBUG "b1capi: loading: %d bytes ..", left); for (i = 0; i < left; i++) B1_put_byte(base, buf[i]); if (loaddebug) printk("ok\n"); } return 0;}int B1_load_config(unsigned int base, avmb1_t4file * config){ /* * Data is in user space !!! */ unsigned char buf[256]; unsigned char *dp; int i, j, left, retval; dp = config->data; left = config->len; if (left) { B1_put_byte(base, SEND_CONFIG); B1_put_word(base, 1); B1_put_byte(base, SEND_CONFIG); B1_put_word(base, left); } while (left > sizeof(buf)) { retval = copy_from_user(buf, dp, sizeof(buf)); if (retval) return -EFAULT; if (loaddebug) printk(KERN_DEBUG "b1capi: conf load: %d bytes ..", sizeof(buf)); for (i = 0; i < sizeof(buf); ) { B1_put_byte(base, SEND_CONFIG); for (j=0; j < 4; j++) { B1_put_byte(base, buf[i++]); } } if (loaddebug) printk("ok\n"); left -= sizeof(buf); dp += sizeof(buf); } if (left) { retval = copy_from_user(buf, dp, left); if (retval) return -EFAULT; if (loaddebug) printk(KERN_DEBUG "b1capi: conf load: %d bytes ..", left); for (i = 0; i < left; ) { B1_put_byte(base, SEND_CONFIG); for (j=0; j < 4; j++) { if (i < left) B1_put_byte(base, buf[i++]); else B1_put_byte(base, 0); } } if (loaddebug) printk("ok\n"); } return 0;}int B1_loaded(unsigned int base){ int i; unsigned char ans; if (loaddebug) printk(KERN_DEBUG "b1capi: loaded: wait 1 ..\n"); for (i = jiffies + 10 * HZ; i > jiffies;) { if (B1_tx_empty(base)) break; } if (!B1_tx_empty(base)) { printk(KERN_ERR "b1lli(0x%x): B1_loaded: timeout tx\n", base); return 0; } B1_put_byte(base, SEND_POLL); printk(KERN_DEBUG "b1capi: loaded: wait 2 ..\n"); for (i = jiffies + 10 * HZ; i > jiffies;) { if (B1_rx_full(base)) { if ((ans = B1_get_byte(base)) == RECEIVE_POLL) { if (loaddebug) printk(KERN_DEBUG "b1capi: loaded: ok\n"); return 1; } printk(KERN_ERR "b1lli(0x%x): B1_loaded: got 0x%x ???\n", base, ans); return 0; } } printk(KERN_ERR "b1lli(0x%x): B1_loaded: timeout rx\n", base); return 0;}/* * ------------------------------------------------------------------- */static inline void parse_version(avmb1_card * card){ int i, j; for (j = 0; j < AVM_MAXVERSION; j++) card->version[j] = "\0\0" + 1; for (i = 0, j = 0; j < AVM_MAXVERSION && i < card->versionlen; j++, i += card->versionbuf[i] + 1) card->version[j] = &card->versionbuf[i + 1];}/* * ------------------------------------------------------------------- */void B1_send_init(unsigned int port, unsigned int napps, unsigned int nncci, unsigned int cardnr){ unsigned long flags; save_flags(flags); cli(); B1_put_byte(port, SEND_INIT); B1_put_word(port, napps); B1_put_word(port, nncci); B1_put_word(port, cardnr); restore_flags(flags);}void B1_send_register(unsigned int port, __u16 appid, __u32 nmsg, __u32 nb3conn, __u32 nb3blocks, __u32 b3bsize){ unsigned long flags; save_flags(flags); cli(); B1_put_byte(port, SEND_REGISTER); B1_put_word(port, appid); B1_put_word(port, nmsg); B1_put_word(port, nb3conn); B1_put_word(port, nb3blocks); B1_put_word(port, b3bsize); restore_flags(flags);}void B1_send_release(unsigned int port, __u16 appid){ unsigned long flags; save_flags(flags); cli(); B1_put_byte(port, SEND_RELEASE); B1_put_word(port, appid); restore_flags(flags);}void B1_send_message(unsigned int port, struct sk_buff *skb){ unsigned long flags; __u16 len = CAPIMSG_LEN(skb->data); __u8 cmd = CAPIMSG_COMMAND(skb->data); __u8 subcmd = CAPIMSG_SUBCOMMAND(skb->data); __u32 contr = CAPIMSG_CONTROL(skb->data); if (CAPICMD(cmd, subcmd) == CAPI_DATA_B3_REQ) { __u16 dlen = CAPIMSG_DATALEN(skb->data); if (showcapimsgs > 2) { if (showcapimsgs & 1) { printk(KERN_DEBUG "b1lli: Put [0x%lx] id#%d %s len=%u\n", (unsigned long) contr, CAPIMSG_APPID(skb->data), capi_cmd2str(cmd, subcmd), len); } else { printk(KERN_DEBUG "b1lli: Put [0x%lx] %s\n", (unsigned long) contr, capi_message2str(skb->data)); } } save_flags(flags); cli(); B1_put_byte(port, SEND_DATA_B3_REQ); B1_put_slice(port, skb->data, len); B1_put_slice(port, skb->data + len, dlen); restore_flags(flags); } else { if (showcapimsgs) { if (showcapimsgs & 1) { printk(KERN_DEBUG "b1lli: Put [0x%lx] id#%d %s len=%u\n", (unsigned long) contr, CAPIMSG_APPID(skb->data), capi_cmd2str(cmd, subcmd), len); } else { printk(KERN_DEBUG "b1lli: Put [0x%lx] %s\n", (unsigned long)contr, capi_message2str(skb->data)); } } save_flags(flags); cli(); B1_put_byte(port, SEND_MESSAGE); B1_put_slice(port, skb->data, len); restore_flags(flags); } dev_kfree_skb(skb, FREE_WRITE);}/* * ------------------------------------------------------------------- */void B1_handle_interrupt(avmb1_card * card){ unsigned char b1cmd; struct sk_buff *skb; unsigned ApplId; unsigned MsgLen; unsigned DataB3Len; unsigned NCCI; unsigned WindowSize;t1retry: if (!B1_rx_full(card->port)) return; b1cmd = B1_get_byte(card->port); switch (b1cmd) { case RECEIVE_DATA_B3_IND: ApplId = (unsigned) B1_get_word(card->port); MsgLen = B1_get_slice(card->port, card->msgbuf); DataB3Len = B1_get_slice(card->port, card->databuf); if (showcapimsgs > 2) { __u8 cmd = CAPIMSG_COMMAND(card->msgbuf); __u8 subcmd = CAPIMSG_SUBCOMMAND(card->msgbuf); __u32 contr = CAPIMSG_CONTROL(card->msgbuf); CAPIMSG_SETDATA(card->msgbuf, card->databuf); if (showcapimsgs & 1) { printk(KERN_DEBUG "b1lli: Got [0x%lx] id#%d %s len=%u/%u\n", (unsigned long) contr, CAPIMSG_APPID(card->msgbuf), capi_cmd2str(cmd, subcmd), MsgLen, DataB3Len); } else { printk(KERN_DEBUG "b1lli: Got [0x%lx] %s\n", (unsigned long)contr, capi_message2str(card->msgbuf)); } } if (!(skb = dev_alloc_skb(DataB3Len + MsgLen))) { printk(KERN_ERR "b1lli: incoming packet dropped\n"); } else { SET_SKB_FREE(skb); memcpy(skb_put(skb, MsgLen), card->msgbuf, MsgLen); memcpy(skb_put(skb, DataB3Len), card->databuf, DataB3Len); CAPIMSG_SETDATA(skb->data, skb->data + MsgLen); avmb1_handle_capimsg(card, ApplId, skb); } break; case RECEIVE_MESSAGE: ApplId = (unsigned) B1_get_word(card->port); MsgLen = B1_get_slice(card->port, card->msgbuf); if (showcapimsgs) { __u8 cmd = CAPIMSG_COMMAND(card->msgbuf); __u8 subcmd = CAPIMSG_SUBCOMMAND(card->msgbuf); __u32 contr = CAPIMSG_CONTROL(card->msgbuf); if (showcapimsgs & 1) { printk(KERN_DEBUG "b1lli: Got [0x%lx] id#%d %s len=%u\n", (unsigned long) contr, CAPIMSG_APPID(card->msgbuf), capi_cmd2str(cmd, subcmd), MsgLen); } else { printk(KERN_DEBUG "b1lli: Got [0x%lx] %s\n", (unsigned long) contr, capi_message2str(card->msgbuf)); } } if (!(skb = dev_alloc_skb(MsgLen))) { printk(KERN_ERR "b1lli: incoming packet dropped\n"); } else { SET_SKB_FREE(skb); memcpy(skb_put(skb, MsgLen), card->msgbuf, MsgLen); avmb1_handle_capimsg(card, ApplId, skb); } break; case RECEIVE_NEW_NCCI: ApplId = B1_get_word(card->port); NCCI = B1_get_word(card->port); WindowSize = B1_get_word(card->port); if (showcapimsgs) printk(KERN_DEBUG "b1lli(0x%x): NEW_NCCI app %u ncci 0x%x\n", card->port, ApplId, NCCI); avmb1_handle_new_ncci(card, ApplId, NCCI, WindowSize); break; case RECEIVE_FREE_NCCI: ApplId = B1_get_word(card->port); NCCI = B1_get_word(card->port); if (showcapimsgs) printk(KERN_DEBUG "b1lli(0x%x): FREE_NCCI app %u ncci 0x%x\n", card->port, ApplId, NCCI); avmb1_handle_free_ncci(card, ApplId, NCCI); break; case RECEIVE_START: if (card->cardtype == AVM_CARDTYPE_T1) { B1_put_byte(card->port, SEND_POLLACK); /* printk(KERN_DEBUG "b1lli: T1 watchdog\n"); */ } if (card->blocked) printk(KERN_DEBUG "b1lli(0x%x): RESTART\n", card->port); card->blocked = 0; break; case RECEIVE_STOP: printk(KERN_DEBUG "b1lli(0x%x): STOP\n", card->port); card->blocked = 1; break; case RECEIVE_INIT: card->versionlen = B1_get_slice(card->port, card->versionbuf); card->cardstate = CARD_ACTIVE; parse_version(card); printk(KERN_INFO "b1lli(0x%x): %s-card (%s) now active\n", card->port, card->version[VER_CARDTYPE], card->version[VER_DRIVER]); avmb1_card_ready(card); break; case RECEIVE_TASK_READY: ApplId = (unsigned) B1_get_word(card->port); MsgLen = B1_get_slice(card->port, card->msgbuf); card->msgbuf[MsgLen] = 0; printk(KERN_INFO "b1lli(0x%x): Task %d \"%s\" ready.\n", card->port, ApplId, card->msgbuf); break; default: printk(KERN_ERR "b1lli(0x%x): B1_handle_interrupt: 0x%x ???\n", card->port, b1cmd); break; } if (card->cardtype == AVM_CARDTYPE_T1) goto t1retry;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -