📄 torisa.c
字号:
if (span == spans) return 1; if (span == spans + 1) return 2; return -1;}static int torisa_shutdown(struct zt_span *span){ int i; int tspan; int wasrunning; unsigned long flags; tspan = getspan(span); if (tspan < 0) { printk("TorISA: Span '%d' isn't us?\n", span->spanno); return -1; } write_lock_irqsave(&torisa, flags); wasrunning = span->flags & ZT_FLAG_RUNNING; span->flags &= ~ZT_FLAG_RUNNING; /* Zero out all registers */ for (i = 0; i< 0xff; i++) t1out(tspan, i, 0); if (wasrunning) spansstarted--; write_unlock_irqrestore(&torisa, flags); if (!spans[0].flags & ZT_FLAG_RUNNING && !spans[1].flags & ZT_FLAG_RUNNING) /* No longer in use, disable interrupts */ setctlreg(clockvals[syncsrc]); if (debug) printk("Span %d (%s) shutdown\n", span->spanno, span->name); return 0;}static int torisa_startup(struct zt_span *span){ unsigned long endjif; int i; int tspan; unsigned long flags; char *coding; char *framing; char *crcing; int alreadyrunning; tspan = getspan(span); if (tspan < 0) { printk("TorISA: Span '%d' isn't us?\n", span->spanno); return -1; } write_lock_irqsave(&torisa, flags); alreadyrunning = span->flags & ZT_FLAG_RUNNING; /* initialize the start value for the last ec buffer */ for(i = 0; i < span->channels; i++) { last_ecwrite[tspan - 1][i] = ZT_LIN2X(0,&span->chans[i]); } crcing = ""; if (card_type == TYPE_T1) { /* if its a T1 card */ if (!alreadyrunning) { setctlreg(MASTERCLOCK); /* Zero out all registers */ for (i = 0x20; i< 0x40; i++) t1out(tspan, i, 0); for (i = 0x60; i< 0x80; i++) t1out(tspan, i, 0); /* Full-on Sync required (RCR1) */ t1out(tspan, 0x2b, 8); /* RSYNC is an input (RCR2) */ t1out(tspan, 0x2c, 8); /* RBS enable (TCR1) */ t1out(tspan, 0x35, 0x10); /* TSYNC to be output (TCR2) */ t1out(tspan, 0x36, 4); /* Tx & Rx Elastic store, sysclk = 2.048 mhz, loopback controls (CCR1) */ t1out(tspan, 0x37, 0x8c); } /* Enable F bits pattern */ i = 0x20; if (span->lineconfig & ZT_CONFIG_ESF) i = 0x88; if (span->lineconfig & ZT_CONFIG_B8ZS) i |= 0x44; t1out(tspan, 0x38, i); if (i & 0x80) coding = "ESF"; else coding = "SF"; if (i & 0x40) framing = "B8ZS"; else { framing = "AMI"; t1out(tspan,0x7e,0x1c); /* F bits pattern (0x1c) into FDL register */ } t1out(tspan, 0x7c, span->txlevel << 5); if (!alreadyrunning) { /* LIRST to 1 in CCR3 */ t1out(tspan, 0x30, 1); /* Wait 100 ms */ endjif = jiffies + 10; write_unlock_irqrestore(&torisa, flags); while(jiffies < endjif); /* wait 100 ms */ write_lock_irqsave(&torisa, flags); t1out(tspan,0x30,0x40); /* set CCR3 to 0x40, resetting Elastic Store */ span->flags |= ZT_FLAG_RUNNING; spansstarted++;#if 0 printk("Enabling interrupts: %d\n", clockvals[syncsrc] | INTENA);#endif /* output the clock info and enable interrupts */ setctlreg(clockvals[syncsrc] | INTENA); } set_clear(); /* this only applies to a T1 */ } else { /* if its an E1 card */ u_char ccr1 = 0, tcr1 = 0; if (!alreadyrunning) { t1out(tspan,0x1a,4); /* CCR2: set LOTCMC */ for(i = 0; i <= 8; i++) t1out(tspan,i,0); for(i = 0x10; i <= 0x4f; i++) if (i != 0x1a) t1out(tspan,i,0); t1out(tspan,0x10,0x20); /* RCR1: Rsync as input */ t1out(tspan,0x11,6); /* RCR2: Sysclk=2.048 Mhz */ t1out(tspan,0x12,8); /* TCR1: TSiS mode */ } tcr1 = 8; /* base TCR1 value: TSis mode */ if (span->lineconfig & ZT_CONFIG_CCS) { ccr1 |= 8; /* CCR1: Rx Sig mode: CCS */ coding = "CCS"; } else { tcr1 |= 0x20; coding = "CAS"; } if (span->lineconfig & ZT_CONFIG_HDB3) { ccr1 |= 0x44; /* CCR1: TX and RX HDB3 */ framing = "HDB3"; } else framing = "AMI"; if (span->lineconfig & ZT_CONFIG_CRC4) { ccr1 |= 0x11; /* CCR1: TX and TX CRC4 */ crcing = "/CRC4"; } t1out(tspan,0x12,tcr1); t1out(tspan,0x14,ccr1); t1out(tspan, 0x18, 0x80); if (!alreadyrunning) { t1out(tspan,0x1b,0x8a); /* CCR3: LIRST & TSCLKM */ t1out(tspan,0x20,0x1b); /* TAFR */ t1out(tspan,0x21,0x5f); /* TNAFR */ t1out(tspan,0x40,0xb); /* TSR1 */ for(i = 0x41; i <= 0x4f; i++) t1out(tspan,i,0x55); for(i = 0x22; i <= 0x25; i++) t1out(tspan,i,0xff); /* Wait 100 ms */ endjif = jiffies + 10; write_unlock_irqrestore(&torisa, flags); while(jiffies < endjif); /* wait 100 ms */ write_lock_irqsave(&torisa, flags); t1out(tspan,0x1b,0x9a); /* CCR3: set also ESR */ t1out(tspan,0x1b,0x82); /* CCR3: TSCLKM only now */ /* output the clock info and enable interrupts */ setctlreg(clockvals[syncsrc] | INTENA); } } write_unlock_irqrestore(&torisa, flags); if (debug) { if (card_type == TYPE_T1) { if (alreadyrunning) printk("TorISA: Reconfigured span %d (%s/%s) LBO: %s\n", span->spanno, coding, framing, zt_lboname(span->txlevel)); else printk("TorISA: Startup span %d (%s/%s) LBO: %s\n", span->spanno, coding, framing, zt_lboname(span->txlevel)); } else { if (alreadyrunning) printk("TorISA: Reconfigured span %d (%s/%s%s) 120 ohms\n", span->spanno, coding, framing, crcing); else printk("TorISA: Startup span %d (%s/%s%s) 120 ohms\n", span->spanno, coding, framing, crcing); } } if (syncs[0] == span->spanno) printk("SPAN %d: Primary Sync Source\n",span->spanno); if (syncs[1] == span->spanno) printk("SPAN %d: Secondary Sync Source\n",span->spanno); return 0;}static int torisa_spanconfig(struct zt_span *span, struct zt_lineconfig *lc){ if (debug) printk("TorISA: Configuring span %d\n", span->spanno); /* XXX We assume lineconfig is okay and shouldn't XXX */ span->lineconfig = lc->lineconfig; span->txlevel = lc->lbo; span->rxlevel = 0; span->syncsrc = syncsrc; /* remove this span number from the current sync sources, if there */ if (syncs[0] == span->spanno) syncs[0] = 0; if (syncs[1] == span->spanno) syncs[1] = 0; /* if a sync src, put it in proper place */ if (lc->sync) syncs[lc->sync - 1] = span->spanno; /* If we're already running, then go ahead and apply the changes */ if (span->flags & ZT_FLAG_RUNNING) return torisa_startup(span); return 0;}static int torisa_chanconfig(struct zt_chan *chan, int sigtype){ int alreadyrunning; unsigned long flags; alreadyrunning = chan->span->flags & ZT_FLAG_RUNNING; if (debug) { if (alreadyrunning) printk("TorISA: Reconfigured channel %d (%s) sigtype %d\n", chan->channo, chan->name, sigtype); else printk("TorISA: Configured channel %d (%s) sigtype %d\n", chan->channo, chan->name, sigtype); } write_lock_irqsave(&torisa, flags); if (alreadyrunning && (card_type == TYPE_T1)) set_clear(); write_unlock_irqrestore(&torisa, flags); return 0;}static int torisa_open(struct zt_chan *chan){#ifndef LINUX26 MOD_INC_USE_COUNT;#endif return 0;}static int torisa_close(struct zt_chan *chan){#ifndef LINUX26 MOD_DEC_USE_COUNT;#endif return 0;}static int torisa_maint(struct zt_span *span, int cmd){ int tspan = getspan(span); switch(cmd) { case ZT_MAINT_NONE: t1out(tspan,0x1a,4); /* clear system */ break; case ZT_MAINT_LOCALLOOP: t1out(tspan,0x1a,5); /* local loopback */ break; case ZT_MAINT_REMOTELOOP: t1out(tspan,0x37,6); /* remote loopback */ break; case ZT_MAINT_LOOPUP: if (card_type == TYPE_E1) return -ENOSYS; t1out(tspan,0x30,2); /* send loopup code */ break; case ZT_MAINT_LOOPDOWN: if (card_type == TYPE_E1) return -ENOSYS; t1out(tspan,0x30,4); /* send loopdown code */ break; case ZT_MAINT_LOOPSTOP: if (card_type == TYPE_T1) t1out(tspan,0x30,0); /* stop sending loopup code */ break; default: printk("torisa: Unknown maint command: %d\n", cmd); break; } return 0;}static int taskletpending;static struct tasklet_struct torisa_tlet;static void torisa_tasklet(unsigned long data){ int x,y; u_char mychunk[2][ZT_CHUNKSIZE]; taskletrun++; if (taskletpending) { taskletexec++; /* Perform receive data calculations. Reverse to run most likely master last */ if (spans[1].flags & ZT_FLAG_RUNNING) { /* Perform echo cancellation */ for (x=0;x<channels_per_span;x++) { for(y = 0; y < ZT_CHUNKSIZE; y++) { mychunk[1][y] = last_ecwrite[1][x]; last_ecwrite[1][x] = writedata[1-curread][x + channels_per_span][y]; } zt_ec_chunk(&spans[1].chans[x], spans[1].chans[x].readchunk,mychunk[1]); } zt_receive(&spans[1]); } if (spans[0].flags & ZT_FLAG_RUNNING) { /* Perform echo cancellation */ for (x=0;x<channels_per_span;x++) { for(y = 0; y < ZT_CHUNKSIZE; y++) { mychunk[0][y] = last_ecwrite[0][x]; last_ecwrite[0][x] = writedata[1-curread][x][y]; } zt_ec_chunk(&spans[0].chans[x], spans[0].chans[x].readchunk,mychunk[0]); } zt_receive(&spans[0]); } /* Prepare next set for transmission */ if (spans[1].flags & ZT_FLAG_RUNNING) zt_transmit(&spans[1]); if (spans[0].flags & ZT_FLAG_RUNNING) zt_transmit(&spans[0]); } taskletpending = 0;}static int txerrors;#ifdef LINUX26static irqreturn_t torisa_intr(int irq, void *dev_id, struct pt_regs *regs)#elsestatic void torisa_intr(int irq, void *dev_id, struct pt_regs *regs)#endif{ static unsigned int passno = 0, mysynccnt = 0, lastsyncsrc = -1; int n, n1, i, j, k, x, mysyncsrc, oldn; static unsigned short rxword[33],txword[33]; unsigned char txc, rxc, c; unsigned char abits, bbits, cbits, dbits; irqcount++; /* 1. Do all I/O Immediately -- Normally we would ask for the transmission first, but because of the incredibly tight timing we're lucky to be able to do the I/O at this point */ /* make sure its a real interrupt for us */ if (!(getctlreg() & 1)) /* if not, just return */ {#ifdef LINUX26 return IRQ_NONE;#else return; #endif } /* set outbit and put int 16 bit bus mode, reset interrupt enable */ setctlreg(clockvals[syncsrc] | OUTBIT | ENA16);#if 0 if (!passno) printk("Interrupt handler\n");#endif /* Do the actual transmit and receive in poopy order */ for(n1 = 0; n1 < channels_per_span; n1++) { n = chseq[n1]; maddr[DDATA + datxlt[n]] = txword[n]; rxword[n] = maddr[DDATA + datxlt[n]]; /* get rx word */ } setctlreg(clockvals[syncsrc] | OUTBIT); /* clear 16 bit mode */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -