diff options
-rw-r--r-- | xhfc/TODO | 8 | ||||
-rw-r--r-- | xhfc/xhfc.c | 403 | ||||
-rw-r--r-- | xhfc/xhfc.h | 19 | ||||
-rw-r--r-- | xhfc/xhfc_timers_state.c | 4 |
4 files changed, 183 insertions, 251 deletions
@@ -1,10 +1,8 @@ - the code is a bloody mess, clean it up - - end-of-line comments are used as a way to say that they should not - remain. Remove them. - - remove every XXX + - XXX & TODO - remove any commented-out code - - keep better track of where everything is allocated and initialized - - is the deinit correct? prolly not! + + keep better track of where everything is allocated and initialized + + is the deinit correct? prolly not! - harmonize traces - The alarm should be initialized to DAHDI_ALARM_RED. Redo S/T init/reset code. - the B chan and PCM stuff is not implemented at all diff --git a/xhfc/xhfc.c b/xhfc/xhfc.c index c49fc93..abcacd7 100644 --- a/xhfc/xhfc.c +++ b/xhfc/xhfc.c @@ -17,17 +17,21 @@ MODULE_LICENSE("GPL"); uint debug = 0; uint dbg_spanfilter = 0xFFFFFFFF; +int exit_after_reset = 0; uint ntte = 0x3; static uint reset_gpio = 33; int softconf = 0; +int sync_source = 2; module_param(debug, uint, S_IRUGO | S_IWUSR); module_param(dbg_spanfilter, uint, S_IRUGO | S_IWUSR); module_param(softconf, bool, S_IRUGO); module_param(ntte, uint, S_IRUGO); +module_param(exit_after_reset, bool, S_IRUGO); +module_param(sync_source, uint, S_IRUGO); MODULE_PARM_DESC(debug, "Debug bitfield:\n" "\t0: general\n" @@ -37,13 +41,15 @@ MODULE_PARM_DESC(debug, "Debug bitfield:\n" "\t4: (not used, echo canceller)\n" "\t5: ST state\n" "\t6: HDLC\n" - "\t7: (not used, alarms)\n" - "\t8: (not used, timing)\n"); + "\t7: HDLC (verbose)\n" + "\t8: (not used, timing)\n" + "\t9: alarms\n"); MODULE_PARM_DESC(dbg_spanfilter, "bitfield, filter debug info by span."); MODULE_PARM_DESC(ntte, "bitfield, configuration of the physical ports. ex: 0x3 = 0 NT, 1 NT, 2 TE, 3 TE."); MODULE_PARM_DESC(softconf, "Configure the S/T port line interface in software."); MODULE_PARM_DESC(reset_gpio, "Reset the XHFC using this GPIO"); -MODULE_PARM_DESC(nt, "(Only for S/T) 1 if the interface is NT, 0 if it is TE"); +MODULE_PARM_DESC(exit_after_reset, "Exit after hard reset"); +MODULE_PARM_DESC(sync_source, "Port used as a sync source for the PCM clock."); uint trigger = 0; @@ -133,10 +139,7 @@ void xhfc_config_st(struct xhfc *x, int port, int nt) */ int xhfc_config_pcm(struct xhfc *xhfc, int master_or_slave) { - static char msg[1000]; - u8 r_su_sel1 = 0x00; - - msg[0] = 0; + u8 r_su_sel1 = 0x00, r_su_sync = 0x00; SET_V_F0_LEN(xhfc->r_pcm_md0, 1); @@ -173,7 +176,7 @@ int xhfc_config_pcm(struct xhfc *xhfc, int master_or_slave) /* port 0 as sysnc source for PCM with port 0 in NT mode or as deactivated TE PCM clock becomes free running */ - write_xhfc(xhfc, R_SU_SYNC, 0x8); + write_xhfc(xhfc, R_SU_SYNC, SET_V_SYNC_SEL(r_su_sync, sync_source)); return 0; } @@ -181,8 +184,8 @@ int xhfc_config_pcm(struct xhfc *xhfc, int master_or_slave) /* NOTE: assumes fifo lock is held */ #define debug_fz(b4, fifo, prefix, buf) \ do { \ -sprintf(buf, "%s: (fifo %d): flen=%d, " \ - "zlen=%d\n", prefix, fifo, flen, \ +sprintf(buf, "%s(fifo %d): flen=%d, " \ + "zlen=%d", prefix, fifo, flen, \ zlen); \ } while (0) @@ -221,7 +224,6 @@ void xhfc_config_d_chan_on_fifo(struct xhfc_span *xhfc_span) { struct xhfc *x = xhfc_span->xhfc; u8 r_fifo, a_con_hdlc, a_channel, a_subch_cfg, a_inc_res_fifo; - printk(KERN_DEBUG "%s: entering.\n", __func__); r_fifo = a_con_hdlc = a_channel = a_subch_cfg = a_inc_res_fifo = 0x00; @@ -252,44 +254,51 @@ void xhfc_config_d_chan_on_fifo(struct xhfc_span *xhfc_span) } #undef WRITE_TO_REGS -#if 0 -#define WRITE_TO_REGS() \ -do { \ - write_xhfc(x, R_FIFO, r_fifo); \ - xhfc_waitbusy(x); \ - write_xhfc(x, A_CON_HDLC, a_con_hdlc); \ - write_xhfc(x, A_INC_RES_FIFO, a_inc_res_fifo); \ - xhfc_waitbusy(x); \ -} while(0) -void xhfc_config_b_chan_on_fifo(struct xhfc *x) +void xhfc_config_b_chan_on_fifo(struct xhfc *x, int fifo, int slot, int direction) { - u8 r_fifo, a_con_hdlc, a_inc_res_fifo; - r_fifo = a_con_hdlc = a_inc_res_fifo = 0x00; + u8 r_fifo, a_con_hdlc, r_slot, a_sl_cfg; + r_fifo = a_con_hdlc = r_slot = a_sl_cfg = 0x00; - SET_V_IFF(a_con_hdlc, 1); /* inter frame fill with 1s */ - SET_V_HDLC_TRP(a_con_hdlc, 1); /* transparent mode */ - SET_V_FIFO_IRQ(a_con_hdlc, 7); /* FIFO & IRQ enabled */ - SET_V_DATA_FLOW(a_con_hdlc, 0); /* FIFO -> ST/Up */ + /* b1 TX */ - SET_V_RES_FIFO(a_inc_res_fifo, 1); /* reset FIFO */ - SET_V_RES_LOST(a_inc_res_fifo, 1); /* reset FIFO */ - SET_V_RES_FIFO_ERR(a_inc_res_fifo, 1); /* reset FIFO */ + SET_V_FIFO_DIR(r_fifo, TRANSMIT); + SET_V_FIFO_NUM(r_fifo, fifo); + SET_V_REV(r_fifo, 0); - SET_V_FIFO_NUM(r_fifo, x->testdata->b1); - SET_V_FIFO_DIR(r_fifo, 0); /* transmit */ - WRITE_TO_REGS(); - SET_V_FIFO_DIR(r_fifo, 1); /* receive */ - WRITE_TO_REGS(); + SET_V_IFF(a_con_hdlc, 0); + SET_V_HDLC_TRP(a_con_hdlc, 1); /* transparent mode */ + SET_V_FIFO_IRQ(a_con_hdlc, 7); /* enable data transmission */ + SET_V_DATA_FLOW(a_con_hdlc, 6); /* '110' ST -> PCM */ - SET_V_FIFO_NUM(r_fifo, x->testdata->b2); - SET_V_FIFO_DIR(r_fifo, 0); /* transmit */ - WRITE_TO_REGS(); - SET_V_FIFO_DIR(r_fifo, 1); /* receive */ - WRITE_TO_REGS(); + SET_V_SL_DIR(r_slot, TRANSMIT); /* transmit slot */ + SET_V_SL_NUM(r_slot, slot); + + SET_V_CH_SDIR(a_sl_cfg, TRANSMIT); + SET_V_CH_SNUM(a_sl_cfg, fifo); + SET_V_ROUT(a_sl_cfg, 2); /* '10' data to pin STIO1 */ + + write_xhfc(x, R_FIFO, r_fifo); + xhfc_waitbusy(x); + write_xhfc(x, A_CON_HDLC, a_con_hdlc); + write_xhfc(x, R_SLOT, r_slot); + write_xhfc(x, A_SL_CFG, a_sl_cfg); } -#undef WRITE_TO_REGS -#endif +void xhfc_config_data_flow(struct xhfc* x) +{ + int i; + for(i = 0; i < SPANS_PER_CHIP; i++) { + //XXX Only the D chan is supposed to work atm. + xhfc_config_d_chan_on_fifo(&x->spans[i]); + + /* HFC chan, PCM slot, direction */ + xhfc_config_b_chan_on_fifo(x, i * 4 + 0, i * 2 + 0, TRANSMIT); + xhfc_config_b_chan_on_fifo(x, i * 4 + 0, i * 2 + 0, RECEIVE); + xhfc_config_b_chan_on_fifo(x, i * 4 + 1, i * 2 + 1, TRANSMIT); + xhfc_config_b_chan_on_fifo(x, i * 4 + 1, i * 2 + 1, RECEIVE); + } + // NEVAR FORG3T 4 8 15 16 23 42 +} /** * hdlc_signal_complete() - Signal dahdi that we have a complete frame. @@ -317,7 +326,7 @@ static void hdlc_signal_complete(struct xhfc_span *xhfc_span, u8 stat) } else { if (DBG_HDLC && DBG_SPANFILTER) { xhfc_info(xhfc, - "(span %d) Frame " /*"%d" */ " is good!\n", + "(span %d) Frame " /*"%d" */ "is good!\n", xhfc_span->port + 1 /*, xhfc_span->frames_in */ ); } @@ -326,25 +335,25 @@ static void hdlc_signal_complete(struct xhfc_span *xhfc_span, u8 stat) } /* -* Inner loop for D-channel receive function. Retrieves HDLC data from the -* hardware. If the hardware indicates that the frame is complete, we check -* the HDLC engine's STAT byte and update DAHDI as needed. -* -* Returns the number of HDLC frames left in the FIFO, or -1 if we couldn't -* get the lock. -*/ + * Inner loop for D-channel receive function. Retrieves HDLC data from the + * hardware. If the hardware indicates that the frame is complete, we check + * the HDLC engine's STAT byte and update DAHDI as needed. + * + * Returns the number of HDLC frames left in the FIFO. */ static int hdlc_rx_frame(struct xhfc_span *xhfc_span) { + char debugbuf[MAX(256, HDLC_BUF_LEN * 3 + 1)]; + int dbglen; + int fifo, i, j, k, zleft; - int zlen, flen, new_flen; + int zlen, flen; unsigned char buf[HDLC_BUF_LEN]; - char debugbuf[256]; struct xhfc *x = xhfc_span->xhfc; fifo = dchan_fifo(xhfc_span); - if (DBG_HDLC && DBG_SPANFILTER) - xhfc_info(x, "hdlc_rx_frame fifo %d: start\n", fifo); + if (DBG_VERBOSE_HDLC && DBG_SPANFILTER) + xhfc_info(x, "%s(fifo %d): start\n", __func__, fifo); // TODO sync down @@ -352,12 +361,25 @@ static int hdlc_rx_frame(struct xhfc_span *xhfc_span) flen = get_Flen(x); zlen = get_Zlen(x); - debug_fz(x, fifo, "hdlc_rx_frame", debugbuf); + + debug_fz(x, fifo, __func__, debugbuf); + + if(!flen && !zlen) { + if(DBG_VERBOSE_HDLC && DBG_SPANFILTER) + xhfc_info(x, "%s, nothing to receive (%ld).\n", debugbuf, xhfc_span->non_rx_cnt); + xhfc_span->non_rx_cnt++; + if(DBG_HDLC && DBG_SPANFILTER && 0 == xhfc_span->non_rx_cnt % 2000) + xhfc_info(x, "%s(fifo %d): Received nothing for %ld seconds.\n", + __func__, fifo, xhfc_span->non_rx_cnt / 2000); + return 0; + } + xhfc_span->non_rx_cnt = 0; + // TODO sync up - if (DBG_HDLC && DBG_SPANFILTER) - pr_info("%s", debugbuf); + if (DBG_VERBOSE_HDLC && DBG_SPANFILTER) + xhfc_info(x, "%s\n", debugbuf); /* if we have at least one complete frame, increment zleft to include * status byte */ @@ -391,49 +413,39 @@ static int hdlc_rx_frame(struct xhfc_span *xhfc_span) zleft -= j; - if (DBG_HDLC && DBG_SPANFILTER) { + if (DBG_VERBOSE_HDLC && DBG_SPANFILTER) { xhfc_info(x, "transmitted %d bytes to dahdi, " "zleft=%d\n", k, zleft); } if (DBG_HDLC && DBG_SPANFILTER) { - xhfc_info(x, "hdlc_rx_frame(span %d): " - "zlen=%d, zleft=%d\n", - xhfc_span->port + 1, zlen, zleft); - for (i = 0; i < j; i++) { - xhfc_info(x, "%02x%c", buf[i], - (i < (j - 1)) ? ' ' : '\n'); - } + dbglen = 0; + for (i = 0; i < j; i++) + dbglen += sprintf(debugbuf+dbglen, "%02x ", buf[i]); + debugbuf[dbglen] = '\0'; + + xhfc_info(x, "hdlc_rx_frame(fifo %d): " + "zlen=%d, zleft=%d: %s\n", + fifo, zlen, zleft, debugbuf); } } while (zleft > 0); /* Frame received, increment F2 */ - - // TODO sync down - - /* go get the F count again, just in case another frame snuck in while - * we weren't looking. */ - if (flen) { - xhfc_resetfifo(x); - new_flen = get_Flen(x); - } else - new_flen = flen; - - // TODO sync up + if(flen) + xhfc_inc_f(x); /* If this channel is not configured with a signalling span we don't * need to notify the rest of dahdi about this frame. */ if (!xhfc_span->sigchan) { if (DBG_HDLC && DBG_SPANFILTER) { - xhfc_info(x, "hdlc_rx_frame fifo %d: " - "new_flen %d, early end.\n", fifo, new_flen); + xhfc_info(x, "hdlc_rx_frame(fifo %d): " + "flen %d, early end.\n", fifo, flen); } - return new_flen; + return flen; } if (flen) { - /* disable < 3 check for now */ -#if 0 +#if 0 /* disable < 3 check for now */ if (zlen < 3) { if (DBG_HDLC && DBG_SPANFILTER) xhfc_info(x, "odd, zlen less then 3?\n"); @@ -443,12 +455,12 @@ static int hdlc_rx_frame(struct xhfc_span *xhfc_span) hdlc_signal_complete(xhfc_span, buf[i - 1]); } - if (DBG_HDLC && DBG_SPANFILTER) { - xhfc_info(x, "hdlc_rx_frame fifo %d: new_flen=%d end.\n", - fifo, new_flen); + if (DBG_VERBOSE_HDLC && DBG_SPANFILTER) { + xhfc_info(x, "hdlc_rx_frame(fifo %d): flen=%d end.\n", + fifo, flen); } - return new_flen; + return flen; } static uint frames_out; @@ -466,7 +478,8 @@ static int hdlc_tx_frame(struct xhfc_span *xhfc_span) int flen = -1; unsigned char buf[HDLC_BUF_LEN]; unsigned int size = ARRAY_SIZE(buf); - char debugbuf[256]; + char debugbuf[MAX(256, HDLC_BUF_LEN * 3 + 1)]; + int dbglen; //XXX #if 0 @@ -497,49 +510,42 @@ static int hdlc_tx_frame(struct xhfc_span *xhfc_span) } if (size > 0) { - xhfc_span->sigactive = 1; for (i = 0; i < size; i++) write_xhfc(x, A_FIFO_DATA, buf[i]); /* * If we got a full frame from DAHDI, increment F and - * decrement our HDLC pending counter. Otherwise, select the - * FIFO again (to start transmission) and make sure the TX IRQ - * is enabled so we will get called again to finish off the - * data - */ + * decrement our HDLC pending counter. */ if (res != 0) { frames_out++; - xhfc_span->sigactive = 0; xhfc_inc_f(x); atomic_dec(&xhfc_span->hdlc_pending); - } else { - xhfc_selfifo(x, fifo, TRANSMIT); } } // TODO sync up - if (0 && DBG_HDLC && DBG_SPANFILTER) { - xhfc_info(xhfc_span->xhfc, "%s", debugbuf); + if (DBG_HDLC && DBG_SPANFILTER) { + xhfc_info(xhfc_span->xhfc, "%s\n", debugbuf); + + dbglen = 0; + for (i = 0; i < size; i++) + dbglen += sprintf(debugbuf+dbglen, "%02x ", buf[i]); + debugbuf[dbglen] = '\0'; xhfc_info(xhfc_span->xhfc, - "hdlc_tx_frame(span %d): DAHDI gave %d " - "bytes for FIFO %d (res = %d)\n", xhfc_span->port + 1, - size, fifo, res); + "hdlc_tx_frame(span %d): DAHDI gave %d " + "bytes for FIFO %d (res = %d): %s\n", + xhfc_span->port + 1, + size, fifo, res, debugbuf); - for (i = 0; i < size; i++) + if (size && res != 0) xhfc_info(xhfc_span->xhfc, - "%02x%c\n", buf[i], - (i < (size - 1)) ? ' ' : '\n'); - - if (size && res != 0) { - pr_info("Transmitted frame %d on span %d\n", - frames_out - 1, xhfc_span->port); - } + "Transmitted frame %d on span %d\n", + frames_out - 1, xhfc_span->port); } - return (res == 0); + return !res; } /* DAHDI calls this when it has data it wants to send to the HDLC controller */ @@ -576,21 +582,19 @@ void xhfc_hdlc_hard_xmit(struct dahdi_chan *chan) irqreturn_t xhfc_interrupt(int irq, void *dev_id, struct pt_regs* ptregs) { /* (void) ptregs; */ - + struct xhfc_pi *pi = dev_id; struct xhfc *xhfc; - - int fifo; - u8 b; - + + int i; + u8 r_su_irq; u8 misc_irq; - + xhfc = &pi->xhfc; /* ommit IRQs for other HW with shared IRQ */ - if (!(read_xhfc(xhfc, R_IRQ_OVIEW))) { + if (!(read_xhfc(xhfc, R_IRQ_OVIEW))) return IRQ_NONE; - } /* reset IRQ source */ misc_irq = read_xhfc(xhfc, R_MISC_IRQ); @@ -599,91 +603,28 @@ irqreturn_t xhfc_interrupt(int irq, void *dev_id, struct pt_regs* ptregs) if (misc_irq & M_TI_IRQMSK) xhfc->ticks++; -//#warning xhfc_hdlc_interrupt(xhfc); - + for (i = 0; i < SPANS_PER_CHIP; i++) { + struct xhfc_span* s = &xhfc->spans[i]; -// if (xhfc->shutdown /*XXX || !b4->wc->initialized */) -// return IRQ_HANDLED; - - //b4->fifo_fill = b400m_getreg(b4, R_FILL_BL0); - - //if (b4->irq_oview & V_FIFO_BL0_IRQ) { - // b4->fifo_irqstatus |= b400m_getreg(b4, R_FIFO_BL0_IRQ); - // b4->irq_oview &= ~V_FIFO_BL0_IRQ; - //} - - ///* only look at BL0, we put all D channel FIFOs in the first block. */ - //b = b2 = b4->fifo_irqstatus; - - for (fifo = 0; fifo < 4; fifo++) { - - if(xhfc->spans[fifo].sigchan) - //if (b & V_FIFOx_RX_IRQ) { - // if (fifo < 4) { /* d-channel FIFO */ - - // /* - // * I have to loop here until hdlc_rx_frame - // * says there are no more frames waiting. for - // * whatever reason, the HFC will not generate - // * another interrupt if there are still HDLC - // * frames waiting to be received. i.e. I get - // * an int when F1 changes, not when F1 != F2. - // * - // */ - // do { - /*k =*/ hdlc_rx_frame(&xhfc->spans[fifo]); - // } while (k); - // } - //} - - //b >>= 2; - } - - ///* zero the bits we just processed */ - //b4->fifo_irqstatus &= ~b2; - //b4->fifo_fill &= ~b2; - - ///* All four D channel FIFOs are in BL0. */ - //b = b2 = b4->fifo_fill; + if(s->sigchan) + while(hdlc_rx_frame(s)) + break; - for (fifo = 0; fifo < 4; fifo++) { - //if (b4->spans[fifo].sigactive && (b & V_FIFOx_TX_IRQ)) - if(xhfc->spans[fifo].sigchan) - hdlc_tx_frame(&xhfc->spans[fifo]); + if(s->sigchan && atomic_read(&s->hdlc_pending)) + while(hdlc_tx_frame(s)) + break; - //if (b & V_FIFOx_RX_IRQ) - // hdlc_rx_frame(&b4->spans[fifo]); - - //b >>= 2; +#if 0 //XXX This is so wrong in so many ways, lol + dahdi_receive(&s->span); + dahdi_transmit(&s->span); +#endif } - ///* Check for outgoing HDLC frame requests The HFC does not generate TX - // * interrupts when there is room to send, so I use an atomic counter - // * that is incremented every time DAHDI wants to send a frame, and - // * decremented every time I send a frame. It'd be better if I could - // * just use the interrupt handler, but the HFC seems to trigger a FIFO - // * TX IRQ only when it has finished sending a frame, not when one can - // * be sent. - // */ - //for (i = 0; i < ARRAY_SIZE(b4->spans); i++) { - // struct b400m_span *bspan = &b4->spans[i]; - - // if (atomic_read(&bspan->hdlc_pending)) { - // do { - // k = hdlc_tx_frame(bspan); - // } while (k); - // } - //} - - b = read_xhfc(xhfc, R_SU_IRQ); - if(b || 2 == xhfc->ticks % 100) { //XXX - int port; - for (port = 0; port < ARRAY_SIZE(xhfc->spans); port++) { - - if(b&(1<<port)||2==xhfc->ticks%100) - hfc_handle_state(&xhfc->spans[port]); - } - } + r_su_irq = read_xhfc(xhfc, R_SU_IRQ); + + for (i = 0; i < ARRAY_SIZE(xhfc->spans); i++) + if(r_su_irq & (1 << i) || 2 == xhfc->ticks /* bootstrap XXX*/) + hfc_handle_state(&xhfc->spans[i]); hfc_update_st_timers(xhfc); @@ -712,9 +653,7 @@ static void enable_interrupts(struct xhfc * xhfc) xhfc->running = 1; /* set PCM master mode */ - write_xhfc(xhfc, R_PCM_MD0, M_PCM_MD | M_C4_POL | M_F0_LEN); - // Setting M_F0_LEN here so it's not overwritten - // xilun about above comment: gnnnn? + write_xhfc(xhfc, R_PCM_MD0, M_PCM_MD | M_C4_POL | xhfc->r_pcm_md0); write_xhfc(xhfc, R_TI_WD, 0x02); write_xhfc(xhfc, R_MISC_IRQMSK, M_TI_IRQMSK); @@ -728,7 +667,7 @@ static void enable_interrupts(struct xhfc * xhfc) read_xhfc(xhfc, R_FIFO_BL3_IRQ); /* enable global interrupts */ - write_xhfc(xhfc, R_IRQ_CTRL, M_GLOB_IRQ_EN | M_FIFO_IRQ_EN); + write_xhfc(xhfc, R_IRQ_CTRL, M_GLOB_IRQ_EN); } @@ -785,12 +724,6 @@ void xhfc_init_and_configure(struct xhfc* x) /* Make sure interrupts disabled */ disable_interrupts(x); - /* XXX Other drivers do a lot of "let's make sure that this isn't - * activated" and "let's clear that and that and again that" that - * should prolly be done here too. For now, let's suppose it doesn't - * need to be done immediatly - */ - /* "stage 2" */ xhfc_config_pcm(x, XHFC_PCM_MASTER); @@ -799,11 +732,7 @@ void xhfc_init_and_configure(struct xhfc* x) /* No we need to setup the flow controller and stuff */ - for(i = 0; i < SPANS_PER_CHIP; i++) { - //XXX Only the D chan is supposed to work atm. - xhfc_config_d_chan_on_fifo(&x->spans[i]); - } - // NEVAR FORG3T 4 8 15 16 23 42 + xhfc_config_data_flow(x); } /* should configure the S/T interfaces, in hardware then software */ @@ -812,7 +741,6 @@ int xhfc_spanconfig(struct dahdi_span *span, struct dahdi_lineconfig *lc) struct xhfc_span *xhfc_span; struct xhfc *xhfc; int term; - int pos; xhfc_span = span->pvt; xhfc = xhfc_span->xhfc; @@ -864,6 +792,7 @@ int xhfc_spanconfig(struct dahdi_span *span, struct dahdi_lineconfig *lc) /* chanconfig for us means to configure the HDLC controller, if appropriate * + * // Below is an irrelevant comment * NOTE: apparently the DAHDI ioctl function calls us with a interrupts * disabled. This means we cannot actually touch the hardware, because all * register accesses are wrapped up in a mutex that can sleep. @@ -895,7 +824,6 @@ int xhfc_chanconfig(struct dahdi_chan *chan, int sigtype) "Unc"), chan->name); } bspan->sigchan = chan; - bspan->sigactive = 0; atomic_set(&bspan->hdlc_pending, 0); res = 0; break; @@ -919,7 +847,7 @@ int xhfc_chanconfig(struct dahdi_chan *chan, int sigtype) return res; } -int xhfc_startup(struct dahdi_span* span) //XXX not sure if useful +int xhfc_startup(struct dahdi_span* span) { enable_interrupts(((struct xhfc_span*) span->pvt)->xhfc); return 0; @@ -955,8 +883,7 @@ void init_spans(struct xhfc* x) xhfc_span->port = i; xhfc_span->sigchan = NULL; /* conf'd in chanconfig (xref1) */ - xhfc_span->sigactive = 0; // XXX nanikore - xhfc_span->ts = 0; // XXX PCM stuff + xhfc_span->ts = 0; // TODO PCM stuff xhfc_span->nt = !!(ntte & (1 << i)); /* reconf'd in spanconfig * (xref2) so there's two * different places in @@ -966,9 +893,7 @@ void init_spans(struct xhfc* x) */ xhfc_span->shutdown = 0; - xhfc_span->newalarm = DAHDI_ALARM_RED; /* XXX should prolly be - * initialized in the ST - * reset instead */ + xhfc_span->newalarm = DAHDI_ALARM_RED; /* All the timer stuff is done in the timer and state * functions, not here. */ @@ -1000,7 +925,8 @@ void init_spans(struct xhfc* x) xhfc_span->span.owner = THIS_MODULE; xhfc_span->span.spanconfig = xhfc_spanconfig; xhfc_span->span.chanconfig = xhfc_chanconfig; - xhfc_span->span.startup = xhfc_startup; //XXX not sure about this + xhfc_span->span.startup = xhfc_startup; + // Well, now we kinda need a shutdown xhfc_span->span.ioctl = xhfc_ioctl; xhfc_span->span.hdlc_hard_xmit = xhfc_hdlc_hard_xmit; @@ -1114,12 +1040,14 @@ int __devinit xhfc_init_one(struct pci_dev *pdev, * Hard init * *************/ - leb_init(pi); - - //if(softconf) configure_interface(); - xhfc_hard_reset(); + if(exit_after_reset) { + rc = -EINVAL; + goto exit_after_reset; + } + + leb_init(pi); /******************** * XHFC struct init * @@ -1178,7 +1106,7 @@ int __devinit xhfc_init_one(struct pci_dev *pdev, goto err_dahdi_register; } - enable_interrupts(&pi->xhfc); + enable_interrupts(&pi->xhfc); /* enabled in startup */ return 0; @@ -1189,6 +1117,7 @@ err_request_irq: err_collect_chip_id: //acpi_unregister_gsi(IRQ_TLP_GPIO_30); /* symbol doesn't exist??? */ err_acpi_register: +exit_after_reset: iounmap(pi->cs_n0); err_ioremap_mmbar: iounmap(pi->regs); @@ -1207,12 +1136,11 @@ void __devexit xhfc_remove_one(struct pci_dev *pdev) int i; struct xhfc_pi *pi; - printk(KERN_DEBUG "entering tlp_leb_remove_one.\n"); - pi = pci_get_drvdata(pdev); - printk(KERN_INFO "%s %s: removing card\n", pi->name, - __FUNCTION__); + if(DBG) + printk(KERN_INFO "%s %s: removing card\n", + pi->name, __FUNCTION__); for(i = 0; i < SPANS_PER_CHIP; i++) dahdi_unregister(&pi->xhfc.spans[i].span); @@ -1236,7 +1164,8 @@ void __devexit xhfc_remove_one(struct pci_dev *pdev) void xhfc_shutdown(struct pci_dev *pdev) { - printk(KERN_DEBUG "%s: Au revoir.\n", __FUNCTION__); + if(DBG) + printk(KERN_DEBUG "%s: Au revoir.\n", __FUNCTION__); } /***************/ @@ -1246,16 +1175,14 @@ static int __init xhfc_init(void) { int err; - printk(KERN_INFO DRIVER_NAME " HDLC test %s driver Rev. %s \n", - __FUNCTION__, xhfc_rev); + if(DBG) + printk(KERN_INFO DRIVER_NAME " driver Rev. %s \n", xhfc_rev); err = pci_register_driver(&xhfc_driver); if (err < 0) goto out; - printk(KERN_INFO DRIVER_NAME " HDLC test %d cards installed\n", card_cnt); - /* XXX fail with error if no cards detected */ return 0; @@ -1267,8 +1194,8 @@ static int __init xhfc_init(void) static void __exit xhfc_cleanup(void) { pci_unregister_driver(&xhfc_driver); - - printk(KERN_INFO "%s: driver removed\n", __FUNCTION__); + if(DBG) + printk(KERN_INFO "%s: driver removed\n", __FUNCTION__); } module_init(xhfc_init); diff --git a/xhfc/xhfc.h b/xhfc/xhfc.h index 9d777bf..6f5445d 100644 --- a/xhfc/xhfc.h +++ b/xhfc/xhfc.h @@ -48,13 +48,14 @@ #define DEBUG_FOPS (1 << 3) #define DEBUG_ECHOCAN (1 << 4) /* S/T state machine */ -#define DEBUG_ST_STATE (1 << 5) //XXX not used? +#define DEBUG_ST_STATE (1 << 5) /* HDLC controller */ #define DEBUG_HDLC (1 << 6) -/* alarm changes */ -#define DEBUG_ALARM (1 << 7) //XXX not used? +#define DEBUG_VERBOSE_HDLC (1 << 7) /* Timing related changes */ #define DEBUG_TIMING (1 << 8) //XXX not used? +/* alarm changes */ +#define DEBUG_ALARM (1 << 9) #define DBG (debug & DEBUG_GENERAL) #define DBG_DTMF (debug & DEBUG_DTMF) @@ -63,6 +64,7 @@ #define DBG_EC (debug & DEBUG_ECHOCAN) #define DBG_ST (debug & DEBUG_ST_STATE) #define DBG_HDLC (debug & DEBUG_HDLC) +#define DBG_VERBOSE_HDLC (debug & DEBUG_VERBOSE_HDLC) #define DBG_ALARM (debug & DEBUG_ALARM) #define DBG_TIMING (debug & DEBUG_TIMING) @@ -72,6 +74,13 @@ #define USE_FIFO_IRQ 0 #define HDLC_BUF_LEN 128 /* "arbitrary", or so say DAHDI's drivers */ + +#ifndef MAX +# define MAX(a, b) (((a) > (b))? (a) : (b)) +#endif +#ifndef MIN +# define MIN(a, b) (((a) < (b))? (a) : (b)) +#endif enum data_dir { TRANSMIT = 0, RECEIVE = 1 }; @@ -115,6 +124,8 @@ struct xhfc_span { int sigactive; unsigned long hfc_timers[CHANS_PER_SPAN+1]; /* T1, T2, T3 */ //XXX WTF with this length? int hfc_timer_on[CHANS_PER_SPAN+1]; /* 1=timer active */ + + unsigned long non_rx_cnt; }; struct xhfc { @@ -147,7 +158,7 @@ struct xhfc_pi { struct pci_dev *pci_dev; }; -#define dchan_fifo(span) (span->port * SPANS_PER_CHIP + 2) +#define dchan_fifo(span) (span->port * 4 + 2) void xhfc_config_d_chan_on_fifo(struct xhfc_span*); //void xhfc_hdlc_write_buf(struct xhfc* x, int fifo, u8* buf, int len); diff --git a/xhfc/xhfc_timers_state.c b/xhfc/xhfc_timers_state.c index 46f35b9..9646605 100644 --- a/xhfc/xhfc_timers_state.c +++ b/xhfc/xhfc_timers_state.c @@ -253,12 +253,8 @@ void hfc_update_st_timers(struct xhfc *x) "%d debounced\n", i + 1, s->newalarm); } - // set_bit(WCTDM_CHECK_TIMING, &x->wc->checkflag); NANIKORE } } - - //if (test_and_clear_bit(WCTDM_CHECK_TIMING, &x->wc->checkflag)) - // xhfc_set_sync_src(x, xhfc_find_sync(b4)); } /* this is the driver-level state machine for an S/T port */ |