summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNoe Rubinstein <nrubinstein@proformatique.com>2010-08-23 16:04:48 +0200
committerNoe Rubinstein <nrubinstein@proformatique.com>2010-08-23 16:04:48 +0200
commit903500ec9e587eba454943719668bef0ea0660fd (patch)
treed200f84516efd0ce42b5a0ffa671b988e0f29d55
parent5a56b078a7aa178dac2707a7d60d850e3ebed25b (diff)
clean up, traces, fix hdlc_rx_frame, b chans...
-rw-r--r--xhfc/TODO8
-rw-r--r--xhfc/xhfc.c403
-rw-r--r--xhfc/xhfc.h19
-rw-r--r--xhfc/xhfc_timers_state.c4
4 files changed, 183 insertions, 251 deletions
diff --git a/xhfc/TODO b/xhfc/TODO
index e8ced5c..559955f 100644
--- a/xhfc/TODO
+++ b/xhfc/TODO
@@ -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 */