xpp: style - clean many long lines (manually)

Signed-off-by: Oron Peled <oron.peled@xorcom.com>
Acked-By: Tzafrir Cohen <tzafrir.cohen@xorcom.com>

git-svn-id: http://svn.asterisk.org/svn/dahdi/linux/trunk@10430 a0bf4364-ded3-4de4-8d8a-66a801d63aff
This commit is contained in:
Oron Peled 2012-01-11 19:56:35 +00:00 committed by Tzafrir Cohen
parent 4ff781c2ba
commit dbf3f017d9
22 changed files with 865 additions and 571 deletions

View File

@ -39,7 +39,8 @@ static const char rcsid[] = "$Id$";
#error Cannot build BRI without HARDHDLC supprt #error Cannot build BRI without HARDHDLC supprt
#endif #endif
static DEF_PARM(int, debug, 0, 0644, "Print DBG statements"); /* must be before dahdi_debug.h */ /* must be before dahdi_debug.h */
static DEF_PARM(int, debug, 0, 0644, "Print DBG statements");
static DEF_PARM(uint, poll_interval, 500, 0644, static DEF_PARM(uint, poll_interval, 500, 0644,
"Poll channel state interval in milliseconds (0 - disable)"); "Poll channel state interval in milliseconds (0 - disable)");
static DEF_PARM_BOOL(nt_keepalive, 1, 0644, static DEF_PARM_BOOL(nt_keepalive, 1, 0644,
@ -113,7 +114,7 @@ static const char *xhfc_state_name(bool is_nt, enum xhfc_states state)
#define HFC_TIMER_T3 8000 /* 8s activation timer T3 */ #define HFC_TIMER_T3 8000 /* 8s activation timer T3 */
#define HFC_TIMER_OFF -1 /* timer disabled */ #define HFC_TIMER_OFF -1 /* timer disabled */
#define A_SU_WR_STA 0x30 /* ST/Up state machine register */ #define A_SU_WR_STA 0x30 /* ST/Up state machine register */
#define V_SU_LD_STA 0x10 #define V_SU_LD_STA 0x10
#define V_SU_ACT 0x60 /* start activation/deactivation */ #define V_SU_ACT 0x60 /* start activation/deactivation */
#define STA_DEACTIVATE 0x40 /* start deactivation in A_SU_WR_STA */ #define STA_DEACTIVATE 0x40 /* start deactivation in A_SU_WR_STA */
@ -232,8 +233,8 @@ DEF_RPACKET_DATA(BRI, SET_LED, /* Set one of the LED's */
static /* 0x33 */ DECLARE_CMD(BRI, SET_LED, enum bri_led_names which_led, static /* 0x33 */ DECLARE_CMD(BRI, SET_LED, enum bri_led_names which_led,
enum led_state to_led_state); enum led_state to_led_state);
#define DO_LED(xpd, which, tostate) \ #define DO_LED(xpd, which, tostate) \
CALL_PROTO(BRI, SET_LED, (xpd)->xbus, (xpd), (which), (tostate)) CALL_PROTO(BRI, SET_LED, (xpd)->xbus, (xpd), (which), (tostate))
#define DEBUG_BUF_SIZE (100) #define DEBUG_BUF_SIZE (100)
static void dump_hex_buf(xpd_t *xpd, char *msg, __u8 *buf, size_t len) static void dump_hex_buf(xpd_t *xpd, char *msg, __u8 *buf, size_t len)
@ -358,7 +359,8 @@ static void te_activation(xpd_t *xpd, bool on)
case ST_TE_SYNCED: /* F6 */ case ST_TE_SYNCED: /* F6 */
case ST_TE_ACTIVATED: /* F7 */ case ST_TE_ACTIVATED: /* F7 */
XPD_DBG(SIGNAL, xpd, XPD_DBG(SIGNAL, xpd,
"HFC_L1_FORCE_DEACTIVATE_TE (state %d, ignored)\n", "HFC_L1_FORCE_DEACTIVATE_TE "
"(state %d, ignored)\n",
curr_state); curr_state);
break; break;
case ST_TE_SIGWAIT: /* F4 */ case ST_TE_SIGWAIT: /* F4 */
@ -489,9 +491,11 @@ static int rx_dchan(xpd_t *xpd, reg_cmd_t *regcmd)
if ((ret = bri_check_stat(xpd, dchan, src, len)) < 0) if ((ret = bri_check_stat(xpd, dchan, src, len)) < 0)
goto out; goto out;
/* /*
* Tell Dahdi that we received len-1 bytes. They include the data and a 2-byte checksum. * Tell Dahdi that we received len-1 bytes.
* The last byte (that we don't pass on) is 0 if the checksum is correct. If it were wrong, * They include the data and a 2-byte checksum.
* we would drop the packet in the "if (src[len-1])" above. * The last byte (that we don't pass on) is 0 if the
* checksum is correct. If it were wrong, we would drop the
* packet in the "if (src[len-1])" above.
*/ */
dahdi_hdlc_finish(dchan); dahdi_hdlc_finish(dchan);
priv->dchan_rx_counter++; priv->dchan_rx_counter++;
@ -503,7 +507,10 @@ out:
/* /*
* D-Chan transmit * D-Chan transmit
*/ */
/* DAHDI calls this when it has data it wants to send to the HDLC controller */ /*
* DAHDI calls this when it has data it wants to send to
* the HDLC controller
*/
static void bri_hdlc_hard_xmit(struct dahdi_chan *chan) static void bri_hdlc_hard_xmit(struct dahdi_chan *chan)
{ {
xpd_t *xpd = chan->pvt; xpd_t *xpd = chan->pvt;
@ -551,8 +558,8 @@ static int send_dchan_frame(xpd_t *xpd, xframe_t *xframe, bool is_eof)
/* /*
* Fill a single multibyte REGISTER_REQUEST * Fill a single multibyte REGISTER_REQUEST
*/ */
static void fill_multibyte(xpd_t *xpd, xpacket_t *pack, bool eoframe, char *buf, static void fill_multibyte(xpd_t *xpd, xpacket_t *pack,
int len) bool eoframe, char *buf, int len)
{ {
reg_cmd_t *reg_cmd; reg_cmd_t *reg_cmd;
char *p; char *p;
@ -628,8 +635,8 @@ static int tx_dchan(xpd_t *xpd)
*/ */
if (printk_ratelimit()) if (printk_ratelimit())
XPD_ERR(xpd, XPD_ERR(xpd,
"%s: hdlc_pending, but nothing to transmit?\n", "%s: hdlc_pending, but nothing "
__func__); "to transmit?\n", __func__);
FREE_SEND_XFRAME(xpd->xbus, xframe); FREE_SEND_XFRAME(xpd->xbus, xframe);
return -EINVAL; return -EINVAL;
} }
@ -893,15 +900,19 @@ static void handle_bri_timers(xpd_t *xpd)
set_bri_timer(xpd, "T1", &priv->t1, set_bri_timer(xpd, "T1", &priv->t1,
HFC_TIMER_OFF); HFC_TIMER_OFF);
if (!nt_keepalive) { if (!nt_keepalive) {
if (priv->state_register.bits.v_su_sta == ST_NT_ACTIVATING) { /* G2 */ /* G2 */
if (priv->state_register.bits.v_su_sta == ST_NT_ACTIVATING) {
XPD_DBG(SIGNAL, xpd, XPD_DBG(SIGNAL, xpd,
"T1 Expired. Deactivate NT\n"); "T1 Expired. "
"Deactivate NT\n");
clear_bit(HFC_L1_ACTIVATING, clear_bit(HFC_L1_ACTIVATING,
&priv->l1_flags); &priv->l1_flags);
nt_activation(xpd, 0); /* Deactivate NT */ /* Deactivate NT */
nt_activation(xpd, 0);
} else } else
XPD_DBG(SIGNAL, xpd, XPD_DBG(SIGNAL, xpd,
"T1 Expired. (state %d, ignored)\n", "T1 Expired. "
"(state %d, ignored)\n",
priv->state_register. priv->state_register.
bits.v_su_sta); bits.v_su_sta);
} }
@ -937,15 +948,16 @@ static int BRI_card_tick(xbus_t *xbus, xpd_t *xpd)
if (poll_interval != 0 && (priv->tick_counter % poll_interval) == 0) { if (poll_interval != 0 && (priv->tick_counter % poll_interval) == 0) {
// XPD_DBG(GENERAL, xpd, "%d\n", priv->tick_counter); // XPD_DBG(GENERAL, xpd, "%d\n", priv->tick_counter);
priv->poll_counter++; priv->poll_counter++;
xpp_register_request(xbus, xpd, BRI_PORT(xpd), /* portno */ xpp_register_request(xbus, xpd,
0, /* writing */ BRI_PORT(xpd), /* portno */
A_SU_RD_STA, /* regnum */ 0, /* writing */
0, /* do_subreg */ A_SU_RD_STA, /* regnum */
0, /* subreg */ 0, /* do_subreg */
0, /* data_low */ 0, /* subreg */
0, /* do_datah */ 0, /* data_low */
0, /* data_high */ 0, /* do_datah */
0 /* should_reply */ 0, /* data_high */
0 /* should_reply */
); );
if (IS_NT(xpd) && nt_keepalive if (IS_NT(xpd) && nt_keepalive
@ -1293,7 +1305,10 @@ static void BRI_card_pcm_tospan(xpd_t *xpd, xpacket_t *pack)
if (IS_SET(tmp_mask, i)) { if (IS_SET(tmp_mask, i)) {
r = XPD_CHAN(tmp_xpd, i)->readchunk; r = XPD_CHAN(tmp_xpd, i)->readchunk;
// memset((u_char *)r, 0x5A, DAHDI_CHUNKSIZE); // DEBUG #if 0
/* DEBUG */
memset((u_char *)r, 0x5A, DAHDI_CHUNKSIZE);
#endif
memcpy((u_char *)r, pcm, DAHDI_CHUNKSIZE); memcpy((u_char *)r, pcm, DAHDI_CHUNKSIZE);
pcm += DAHDI_CHUNKSIZE; pcm += DAHDI_CHUNKSIZE;
} }
@ -1374,15 +1389,16 @@ static int write_state_register(xpd_t *xpd, __u8 value)
int ret; int ret;
XPD_DBG(REGS, xpd, "value = 0x%02X\n", value); XPD_DBG(REGS, xpd, "value = 0x%02X\n", value);
ret = xpp_register_request(xpd->xbus, xpd, BRI_PORT(xpd), /* portno */ ret = xpp_register_request(xpd->xbus, xpd,
1, /* writing */ BRI_PORT(xpd), /* portno */
A_SU_WR_STA, /* regnum */ 1, /* writing */
0, /* do_subreg */ A_SU_WR_STA, /* regnum */
0, /* subreg */ 0, /* do_subreg */
value, /* data_low */ 0, /* subreg */
0, /* do_datah */ value, /* data_low */
0, /* data_high */ 0, /* do_datah */
0 /* should_reply */ 0, /* data_high */
0 /* should_reply */
); );
return ret; return ret;
} }
@ -1537,11 +1553,12 @@ static int BRI_card_register_reply(xbus_t *xbus, xpd_t *xpd, reg_cmd_t *info)
} }
/* Update /proc info only if reply relate to the last slic read request */ /* Update /proc info only if reply relate to the last slic read request */
if (REG_FIELD(&xpd->requested_reply, regnum) == REG_FIELD(info, regnum) if (REG_FIELD(&xpd->requested_reply, regnum) ==
&& REG_FIELD(&xpd->requested_reply, do_subreg) == REG_FIELD(info, REG_FIELD(info, regnum)
do_subreg) && REG_FIELD(&xpd->requested_reply, do_subreg) ==
&& REG_FIELD(&xpd->requested_reply, subreg) == REG_FIELD(info, REG_FIELD(info, do_subreg)
subreg)) { && REG_FIELD(&xpd->requested_reply, subreg) ==
REG_FIELD(info, subreg)) {
xpd->last_reply = *info; xpd->last_reply = *info;
} }

View File

@ -123,11 +123,12 @@ static int ECHO_card_register_reply(xbus_t *xbus, xpd_t *xpd, reg_cmd_t *info)
} }
spin_lock_irqsave(&xpd->lock, flags); spin_lock_irqsave(&xpd->lock, flags);
/* Update /proc info only if reply related to last reg read request */ /* Update /proc info only if reply related to last reg read request */
if (REG_FIELD(&xpd->requested_reply, regnum) == REG_FIELD(info, regnum) if (REG_FIELD(&xpd->requested_reply, regnum) ==
&& REG_FIELD(&xpd->requested_reply, do_subreg) == REG_FIELD(info, REG_FIELD(info, regnum)
do_subreg) && REG_FIELD(&xpd->requested_reply, do_subreg) ==
&& REG_FIELD(&xpd->requested_reply, subreg) == REG_FIELD(info, REG_FIELD(info, do_subreg)
subreg)) { && REG_FIELD(&xpd->requested_reply, subreg) ==
REG_FIELD(info, subreg)) {
xpd->last_reply = *info; xpd->last_reply = *info;
} }
spin_unlock_irqrestore(&xpd->lock, flags); spin_unlock_irqrestore(&xpd->lock, flags);
@ -226,13 +227,13 @@ static void ECHO_ec_dump(xbus_t *xbus)
ts = xbus->echo_state.timeslots; ts = xbus->echo_state.timeslots;
for (i = 0; i + 15 < ECHO_TIMESLOTS; i += 16) { for (i = 0; i + 15 < ECHO_TIMESLOTS; i += 16) {
XBUS_DBG(GENERAL, xbus, XBUS_DBG(GENERAL, xbus,
"EC-DUMP[%03d]: " "EC-DUMP[%03d]: "
"0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X " "0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X "
"0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X\n", "0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X\n",
i, ts[i + 0], ts[i + 1], ts[i + 2], ts[i + 3], i, ts[i + 0], ts[i + 1], ts[i + 2], ts[i + 3],
ts[i + 4], ts[i + 5], ts[i + 6], ts[i + 7], ts[i + 8], ts[i + 4], ts[i + 5], ts[i + 6], ts[i + 7], ts[i + 8],
ts[i + 9], ts[i + 10], ts[i + 11], ts[i + 12], ts[i + 9], ts[i + 10], ts[i + 11], ts[i + 12],
ts[i + 13], ts[i + 14], ts[i + 15] ts[i + 13], ts[i + 14], ts[i + 15]
); );
} }
} }

View File

@ -87,7 +87,8 @@ enum fxo_leds {
#define DAA_WRITE 1 #define DAA_WRITE 1
#define DAA_READ 0 #define DAA_READ 0
#define DAA_DIRECT_REQUEST(xbus, xpd, port, writing, reg, dL) \ #define DAA_DIRECT_REQUEST(xbus, xpd, port, writing, reg, dL) \
xpp_register_request((xbus), (xpd), (port), (writing), (reg), 0, 0, (dL), 0, 0, 0) xpp_register_request((xbus), (xpd), (port), \
(writing), (reg), 0, 0, (dL), 0, 0, 0)
/*---------------- FXO Protocol Commands ----------------------------------*/ /*---------------- FXO Protocol Commands ----------------------------------*/
@ -169,9 +170,18 @@ struct FXO_priv_data {
*/ */
#define LED_COUNTER(priv, pos, color) ((priv)->led_counter[color][pos]) #define LED_COUNTER(priv, pos, color) ((priv)->led_counter[color][pos])
#define IS_BLINKING(priv, pos, color) (LED_COUNTER(priv, pos, color) > 0) #define IS_BLINKING(priv, pos, color) (LED_COUNTER(priv, pos, color) > 0)
#define MARK_BLINK(priv, pos, color, t) ((priv)->led_counter[color][pos] = (t)) #define MARK_BLINK(priv, pos, color, t) \
#define MARK_OFF(priv, pos, color) do { BIT_CLR((priv)->ledcontrol[color], (pos)); MARK_BLINK((priv), (pos), (color), 0); } while (0) ((priv)->led_counter[color][pos] = (t))
#define MARK_ON(priv, pos, color) do { BIT_SET((priv)->ledcontrol[color], (pos)); MARK_BLINK((priv), (pos), (color), 0); } while (0) #define MARK_OFF(priv, pos, color) \
do { \
BIT_CLR((priv)->ledcontrol[color], (pos)); \
MARK_BLINK((priv), (pos), (color), 0); \
} while (0)
#define MARK_ON(priv, pos, color) \
do { \
BIT_SET((priv)->ledcontrol[color], (pos)); \
MARK_BLINK((priv), (pos), (color), 0); \
} while (0)
#define LED_BLINK_RING (1000/8) /* in ticks */ #define LED_BLINK_RING (1000/8) /* in ticks */
@ -266,11 +276,13 @@ static void handle_fxo_leds(xpd_t *xpd)
if (IS_SET(PHONEDEV(xpd).digital_outputs, i) if (IS_SET(PHONEDEV(xpd).digital_outputs, i)
|| IS_SET(PHONEDEV(xpd).digital_inputs, i)) || IS_SET(PHONEDEV(xpd).digital_inputs, i))
continue; continue;
if ((xpd->blink_mode & BIT(i)) || IS_BLINKING(priv, i, color)) { // Blinking /* Blinking? */
if ((xpd->blink_mode & BIT(i)) || IS_BLINKING(priv, i, color)) {
int mod_value = LED_COUNTER(priv, i, color); int mod_value = LED_COUNTER(priv, i, color);
if (!mod_value) if (!mod_value)
mod_value = DEFAULT_LED_PERIOD; /* safety value */ /* safety value */
mod_value = DEFAULT_LED_PERIOD;
// led state is toggled // led state is toggled
if ((timer_count % mod_value) == 0) { if ((timer_count % mod_value) == 0) {
LINE_DBG(LEDS, xpd, i, "ledstate=%s\n", LINE_DBG(LEDS, xpd, i, "ledstate=%s\n",
@ -347,7 +359,8 @@ static int do_sethook(xpd_t *xpd, int pos, bool to_offhook)
__u8 value; __u8 value;
BUG_ON(!xpd); BUG_ON(!xpd);
BUG_ON(PHONEDEV(xpd).direction == TO_PHONE); // We can SETHOOK state only on PSTN /* We can SETHOOK state only on PSTN */
BUG_ON(PHONEDEV(xpd).direction == TO_PHONE);
xbus = xpd->xbus; xbus = xpd->xbus;
priv = xpd->priv; priv = xpd->priv;
BUG_ON(!priv); BUG_ON(!priv);
@ -378,7 +391,8 @@ static int do_sethook(xpd_t *xpd, int pos, bool to_offhook)
priv->metering_tone_state = 0L; priv->metering_tone_state = 0L;
DAA_DIRECT_REQUEST(xbus, xpd, pos, DAA_WRITE, DAA_REG_METERING, 0x2D); DAA_DIRECT_REQUEST(xbus, xpd, pos, DAA_WRITE, DAA_REG_METERING, 0x2D);
#endif #endif
reset_battery_readings(xpd, pos); /* unstable during hook changes */ /* unstable during hook changes */
reset_battery_readings(xpd, pos);
if (to_offhook) { if (to_offhook) {
priv->power_denial_safezone[pos] = power_denial_safezone; priv->power_denial_safezone[pos] = power_denial_safezone;
} else { } else {
@ -460,8 +474,9 @@ static xpd_t *FXO_card_new(xbus_t *xbus, int unit, int subunit,
if (to_phone) { if (to_phone) {
XBUS_NOTICE(xbus, XBUS_NOTICE(xbus,
"XPD=%d%d: try to instanciate FXO with reverse direction\n", "XPD=%d%d: try to instanciate FXO with "
unit, subunit); "reverse direction\n",
unit, subunit);
return NULL; return NULL;
} }
if (subtype == 2) if (subtype == 2)
@ -493,10 +508,13 @@ static int FXO_card_init(xbus_t *xbus, xpd_t *xpd)
// Hanghup all lines // Hanghup all lines
for_each_line(xpd, i) { for_each_line(xpd, i) {
do_sethook(xpd, i, 0); do_sethook(xpd, i, 0);
priv->polarity[i] = POL_UNKNOWN; /* will be updated on next battery sample */ /* will be updated on next battery sample */
priv->polarity[i] = POL_UNKNOWN;
priv->polarity_debounce[i] = 0; priv->polarity_debounce[i] = 0;
priv->battery[i] = BATTERY_UNKNOWN; /* will be updated on next battery sample */ /* will be updated on next battery sample */
priv->power[i] = POWER_UNKNOWN; /* will be updated on next battery sample */ priv->battery[i] = BATTERY_UNKNOWN;
/* will be updated on next battery sample */
priv->power[i] = POWER_UNKNOWN;
if (caller_id_style == CID_STYLE_ETSI_DTMF) if (caller_id_style == CID_STYLE_ETSI_DTMF)
oht_pcm(xpd, i, 1); oht_pcm(xpd, i, 1);
} }
@ -696,7 +714,7 @@ static void handle_fxo_power_denial(xpd_t *xpd)
if (priv->power_denial_safezone[i] > 0) { if (priv->power_denial_safezone[i] > 0) {
if (--priv->power_denial_safezone[i] == 0) { if (--priv->power_denial_safezone[i] == 0) {
/* /*
* Poll current, previous answers are meaningless * Poll current, prev answers are meaningless
*/ */
DAA_DIRECT_REQUEST(xpd->xbus, xpd, i, DAA_READ, DAA_DIRECT_REQUEST(xpd->xbus, xpd, i, DAA_READ,
DAA_REG_CURRENT, 0); DAA_REG_CURRENT, 0);
@ -707,9 +725,11 @@ static void handle_fxo_power_denial(xpd_t *xpd)
priv->power_denial_length[i]--; priv->power_denial_length[i]--;
if (priv->power_denial_length[i] <= 0) { if (priv->power_denial_length[i] <= 0) {
/* /*
* But maybe the FXS started to ring (and the firmware haven't * But maybe the FXS started to ring (and
* detected it yet). This would cause false power denials. * the firmware haven't detected it yet).
* So we just flag it and schedule more ticks to wait. * This would cause false power denials so
* we just flag it and schedule more ticks
* to wait.
*/ */
LINE_DBG(SIGNAL, xpd, i, LINE_DBG(SIGNAL, xpd, i,
"Possible Power Denial Hangup\n"); "Possible Power Denial Hangup\n");
@ -850,8 +870,9 @@ static int FXO_card_ioctl(xpd_t *xpd, int pos, unsigned int cmd,
echotune_data[i]); echotune_data[i]);
if (ret < 0) { if (ret < 0) {
LINE_NOTICE(xpd, pos, LINE_NOTICE(xpd, pos,
"Couldn't write %0x02X to register %0x02X\n", "Couldn't write %0x02X to "
echotune_data[i], echotune_regs[i]); "register %0x02X\n",
echotune_data[i], echotune_regs[i]);
return ret; return ret;
} }
msleep(1); msleep(1);
@ -903,19 +924,20 @@ HANDLER_DEF(FXO, SIG_CHANGED)
if (IS_SET(sig_toggles, i)) { if (IS_SET(sig_toggles, i)) {
if (priv->battery[i] == BATTERY_OFF) { if (priv->battery[i] == BATTERY_OFF) {
/* /*
* With poll_battery_interval==0 we cannot have BATTERY_OFF * With poll_battery_interval==0 we cannot
* so we won't get here * have BATTERY_OFF so we won't get here
*/ */
LINE_NOTICE(xpd, i, LINE_NOTICE(xpd, i,
"SIG_CHANGED while battery is off. Ignored.\n"); "SIG_CHANGED while battery is off. "
"Ignored.\n");
continue; continue;
} }
/* First report false ring alarms */ /* First report false ring alarms */
debounce = atomic_read(&priv->ring_debounce[i]); debounce = atomic_read(&priv->ring_debounce[i]);
if (debounce) if (debounce)
LINE_NOTICE(xpd, i, LINE_NOTICE(xpd, i,
"debounced false ring (only %d ticks)\n", "debounced false ring (only %d ticks)\n",
debounce); debounce);
/* /*
* Now set a new ring alarm. * Now set a new ring alarm.
* It will be checked in handle_fxo_ring() * It will be checked in handle_fxo_ring()
@ -930,7 +952,8 @@ HANDLER_DEF(FXO, SIG_CHANGED)
return 0; return 0;
} }
static void update_battery_voltage(xpd_t *xpd, __u8 data_low, xportno_t portno) static void update_battery_voltage(xpd_t *xpd, __u8 data_low,
xportno_t portno)
{ {
struct FXO_priv_data *priv; struct FXO_priv_data *priv;
enum polarity_state pol; enum polarity_state pol;
@ -988,7 +1011,8 @@ static void update_battery_voltage(xpd_t *xpd, __u8 data_low, xportno_t portno)
MARK_OFF(priv, portno, LED_RED); MARK_OFF(priv, portno, LED_RED);
#endif #endif
if (priv->battery[portno] != BATTERY_ON) { if (priv->battery[portno] != BATTERY_ON) {
priv->polarity[portno] = POL_UNKNOWN; /* What's the polarity ? */ /* What's the polarity ? */
priv->polarity[portno] = POL_UNKNOWN;
return; return;
} }
/* /*
@ -1028,11 +1052,12 @@ static void update_battery_voltage(xpd_t *xpd, __u8 data_low, xportno_t portno)
/* /*
* Inform dahdi/Asterisk: * Inform dahdi/Asterisk:
* 1. Maybe used for hangup detection during offhook * 1. Maybe used for hangup detection during offhook
* 2. In some countries used to report caller-id during onhook * 2. In some countries used to report caller-id
* but before first ring. * during onhook but before first ring.
*/ */
if (caller_id_style == CID_STYLE_ETSI_FSK) if (caller_id_style == CID_STYLE_ETSI_FSK)
oht_pcm(xpd, portno, 1); /* will be cleared on ring/offhook */ /* will be cleared on ring/offhook */
oht_pcm(xpd, portno, 1);
if (SPAN_REGISTERED(xpd)) { if (SPAN_REGISTERED(xpd)) {
LINE_DBG(SIGNAL, xpd, portno, LINE_DBG(SIGNAL, xpd, portno,
"Send DAHDI_EVENT_POLARITY: %s\n", "Send DAHDI_EVENT_POLARITY: %s\n",
@ -1048,10 +1073,12 @@ ignore_reading:
/* /*
* Reset debounce counters to prevent false alarms * Reset debounce counters to prevent false alarms
*/ */
reset_battery_readings(xpd, portno); /* unstable during hook changes */ /* unstable during hook changes */
reset_battery_readings(xpd, portno);
} }
static void update_battery_current(xpd_t *xpd, __u8 data_low, xportno_t portno) static void update_battery_current(xpd_t *xpd, __u8 data_low,
xportno_t portno)
{ {
struct FXO_priv_data *priv; struct FXO_priv_data *priv;
@ -1145,11 +1172,12 @@ static int FXO_card_register_reply(xbus_t *xbus, xpd_t *xpd, reg_cmd_t *info)
((info->bytes == 3) ? 'I' : 'D'), REG_FIELD(info, regnum), ((info->bytes == 3) ? 'I' : 'D'), REG_FIELD(info, regnum),
REG_FIELD(info, data_low), REG_FIELD(info, data_high)); REG_FIELD(info, data_low), REG_FIELD(info, data_high));
/* Update /proc info only if reply relate to the last slic read request */ /* Update /proc info only if reply relate to the last slic read request */
if (REG_FIELD(&xpd->requested_reply, regnum) == REG_FIELD(info, regnum) if (REG_FIELD(&xpd->requested_reply, regnum) ==
&& REG_FIELD(&xpd->requested_reply, do_subreg) == REG_FIELD(info, REG_FIELD(info, regnum)
do_subreg) && REG_FIELD(&xpd->requested_reply, do_subreg) ==
&& REG_FIELD(&xpd->requested_reply, subreg) == REG_FIELD(info, REG_FIELD(info, do_subreg)
subreg)) { && REG_FIELD(&xpd->requested_reply, subreg) ==
REG_FIELD(info, subreg)) {
xpd->last_reply = *info; xpd->last_reply = *info;
} }
return 0; return 0;

View File

@ -25,14 +25,16 @@
#include "xpd.h" #include "xpd.h"
enum fxo_opcodes { enum fxo_opcodes {
XPROTO_NAME(FXO, SIG_CHANGED) = 0x06, XPROTO_NAME(FXO, SIG_CHANGED) = 0x06, /**/
/**/ XPROTO_NAME(FXO, DAA_WRITE) = 0x0F, /* Write to DAA */ XPROTO_NAME(FXO, DAA_WRITE) = 0x0F, /* Write to DAA */
XPROTO_NAME(FXO, CHAN_CID) = 0x0F, /* Write to DAA */ XPROTO_NAME(FXO, CHAN_CID) = 0x0F, /* Write to DAA */
XPROTO_NAME(FXO, LED) = 0x0F, /* Write to DAA */ XPROTO_NAME(FXO, LED) = 0x0F, /* Write to DAA */
}; };
DEF_RPACKET_DATA(FXO, SIG_CHANGED, xpp_line_t sig_status; /* channels: lsb=1, msb=8 */
xpp_line_t sig_toggles; /* channels: lsb=1, msb=8 */ DEF_RPACKET_DATA(FXO, SIG_CHANGED,
); xpp_line_t sig_status; /* channels: lsb=1, msb=8 */
xpp_line_t sig_toggles; /* channels: lsb=1, msb=8 */
);
#endif /* CARD_FXO_H */ #endif /* CARD_FXO_H */

View File

@ -33,7 +33,8 @@
static const char rcsid[] = "$Id$"; static const char rcsid[] = "$Id$";
static DEF_PARM(int, debug, 0, 0644, "Print DBG statements"); /* must be before dahdi_debug.h */ /* must be before dahdi_debug.h */
static DEF_PARM(int, debug, 0, 0644, "Print DBG statements");
static DEF_PARM_BOOL(reversepolarity, 0, 0644, "Reverse Line Polarity"); static DEF_PARM_BOOL(reversepolarity, 0, 0644, "Reverse Line Polarity");
static DEF_PARM_BOOL(dtmf_detection, 1, 0644, "Do DTMF detection in hardware"); static DEF_PARM_BOOL(dtmf_detection, 1, 0644, "Do DTMF detection in hardware");
#ifdef POLL_DIGITAL_INPUTS #ifdef POLL_DIGITAL_INPUTS
@ -46,9 +47,11 @@ static DEF_PARM_BOOL(ring_trapez, 0, 0664, "Use trapezoid ring type");
/* Signaling is opposite (fxo signalling for fxs card) */ /* Signaling is opposite (fxo signalling for fxs card) */
#if 1 #if 1
#define FXS_DEFAULT_SIGCAP (DAHDI_SIG_FXOKS | DAHDI_SIG_FXOLS | DAHDI_SIG_FXOGS) #define FXS_DEFAULT_SIGCAP \
(DAHDI_SIG_FXOKS | DAHDI_SIG_FXOLS | DAHDI_SIG_FXOGS)
#else #else
#define FXS_DEFAULT_SIGCAP (DAHDI_SIG_SF | DAHDI_SIG_EM) #define FXS_DEFAULT_SIGCAP \
(DAHDI_SIG_SF | DAHDI_SIG_EM)
#endif #endif
#define VMWI_TYPE(priv, pos, type) \ #define VMWI_TYPE(priv, pos, type) \
@ -70,11 +73,14 @@ enum fxs_leds {
#define SLIC_WRITE 1 #define SLIC_WRITE 1
#define SLIC_READ 0 #define SLIC_READ 0
#define SLIC_DIRECT_REQUEST(xbus, xpd, port, writing, reg, dL) \ #define SLIC_DIRECT_REQUEST(xbus, xpd, port, writing, reg, dL) \
xpp_register_request((xbus), (xpd), (port), (writing), (reg), 0, 0, (dL), 0, 0, 0) xpp_register_request((xbus), (xpd), (port), \
(writing), (reg), 0, 0, (dL), 0, 0, 0)
#define SLIC_INDIRECT_REQUEST(xbus, xpd, port, writing, reg, dL, dH) \ #define SLIC_INDIRECT_REQUEST(xbus, xpd, port, writing, reg, dL, dH) \
xpp_register_request((xbus), (xpd), (port), (writing), 0x1E, 1, (reg), (dL), 1, (dH), 0) xpp_register_request((xbus), (xpd), (port), \
(writing), 0x1E, 1, (reg), (dL), 1, (dH), 0)
#define VALID_PORT(port) (((port) >= 0 && (port) <= 7) || (port) == PORT_BROADCAST) #define VALID_PORT(port) \
(((port) >= 0 && (port) <= 7) || (port) == PORT_BROADCAST)
#define REG_DIGITAL_IOCTRL 0x06 /* LED and RELAY control */ #define REG_DIGITAL_IOCTRL 0x06 /* LED and RELAY control */
@ -90,8 +96,10 @@ enum fxs_state {
FXS_LINE_RING_OPEN = 0x07 /* RING open */ FXS_LINE_RING_OPEN = 0x07 /* RING open */
}; };
#define FXS_LINE_POL_ACTIVE ((reversepolarity) ? FXS_LINE_REV_ACTIVE : FXS_LINE_ACTIVE) #define FXS_LINE_POL_ACTIVE \
#define FXS_LINE_POL_OHTRANS ((reversepolarity) ? FXS_LINE_REV_OHTRANS : FXS_LINE_OHTRANS) ((reversepolarity) ? FXS_LINE_REV_ACTIVE : FXS_LINE_ACTIVE)
#define FXS_LINE_POL_OHTRANS \
((reversepolarity) ? FXS_LINE_REV_OHTRANS : FXS_LINE_OHTRANS)
/* /*
* DTMF detection * DTMF detection
@ -100,7 +108,8 @@ enum fxs_state {
#define REG_BATTERY 0x42 /* 66 - Battery Feed Control */ #define REG_BATTERY 0x42 /* 66 - Battery Feed Control */
#define REG_BATTERY_BATSL BIT(1) /* Battery Feed Select */ #define REG_BATTERY_BATSL BIT(1) /* Battery Feed Select */
#define REG_LOOPCLOSURE 0x44 /* 68 - Loop Closure/Ring Trip Detect Status */ /* 68 - Loop Closure/Ring Trip Detect Status */
#define REG_LOOPCLOSURE 0x44
#define REG_LOOPCLOSURE_ZERO 0xF8 /* Loop Closure zero bits. */ #define REG_LOOPCLOSURE_ZERO 0xF8 /* Loop Closure zero bits. */
#define REG_LOOPCLOSURE_LCR BIT(0) /* Loop Closure Detect Indicator. */ #define REG_LOOPCLOSURE_LCR BIT(0) /* Loop Closure Detect Indicator. */
@ -112,8 +121,8 @@ static void fxs_packet_dump(const char *msg, xpacket_t *pack);
static int proc_fxs_info_read(char *page, char **start, off_t off, int count, static int proc_fxs_info_read(char *page, char **start, off_t off, int count,
int *eof, void *data); int *eof, void *data);
#ifdef WITH_METERING #ifdef WITH_METERING
static int proc_xpd_metering_write(struct file *file, const char __user *buffer, static int proc_xpd_metering_write(struct file *file,
unsigned long count, void *data); const char __user *buffer, unsigned long count, void *data);
#endif #endif
#endif #endif
static void start_stop_vm_led(xbus_t *xbus, xpd_t *xpd, lineno_t pos); static void start_stop_vm_led(xbus_t *xbus, xpd_t *xpd, lineno_t pos);
@ -142,7 +151,8 @@ struct FXS_priv_data {
int led_counter[NUM_LEDS][CHANNELS_PERXPD]; int led_counter[NUM_LEDS][CHANNELS_PERXPD];
int ohttimer[CHANNELS_PERXPD]; int ohttimer[CHANNELS_PERXPD];
#define OHT_TIMER 6000 /* How long after RING to retain OHT */ #define OHT_TIMER 6000 /* How long after RING to retain OHT */
enum fxs_state idletxhookstate[CHANNELS_PERXPD]; /* IDLE changing hook state */ /* IDLE changing hook state */
enum fxs_state idletxhookstate[CHANNELS_PERXPD];
enum fxs_state lasttxhook[CHANNELS_PERXPD]; enum fxs_state lasttxhook[CHANNELS_PERXPD];
struct dahdi_vmwi_info vmwisetting[CHANNELS_PERXPD]; struct dahdi_vmwi_info vmwisetting[CHANNELS_PERXPD];
}; };
@ -153,9 +163,18 @@ struct FXS_priv_data {
*/ */
#define LED_COUNTER(priv, pos, color) ((priv)->led_counter[color][pos]) #define LED_COUNTER(priv, pos, color) ((priv)->led_counter[color][pos])
#define IS_BLINKING(priv, pos, color) (LED_COUNTER(priv, pos, color) > 0) #define IS_BLINKING(priv, pos, color) (LED_COUNTER(priv, pos, color) > 0)
#define MARK_BLINK(priv, pos, color, t) ((priv)->led_counter[color][pos] = (t)) #define MARK_BLINK(priv, pos, color, t) \
#define MARK_OFF(priv, pos, color) do { BIT_CLR((priv)->ledcontrol[color], (pos)); MARK_BLINK((priv), (pos), (color), 0); } while (0) ((priv)->led_counter[color][pos] = (t))
#define MARK_ON(priv, pos, color) do { BIT_SET((priv)->ledcontrol[color], (pos)); MARK_BLINK((priv), (pos), (color), 0); } while (0) #define MARK_OFF(priv, pos, color) \
do { \
BIT_CLR((priv)->ledcontrol[color], (pos)); \
MARK_BLINK((priv), (pos), (color), 0); \
} while (0)
#define MARK_ON(priv, pos, color) \
do { \
BIT_SET((priv)->ledcontrol[color], (pos)); \
MARK_BLINK((priv), (pos), (color), 0); \
} while (0)
#define LED_BLINK_RING (1000/8) /* in ticks */ #define LED_BLINK_RING (1000/8) /* in ticks */
@ -200,24 +219,24 @@ static void vmwi_search(xpd_t *xpd, lineno_t pos, bool on)
/* /*
* LED and RELAY control is done via SLIC register 0x06: * LED and RELAY control is done via SLIC register 0x06:
* 7 6 5 4 3 2 1 0 * 7 6 5 4 3 2 1 0
* +-----+-----+-----+-----+-----+-----+-----+-----+ * +-----+-----+-----+-----+-----+-----+-----+-----+
* | M2 | M1 | M3 | C2 | O1 | O3 | C1 | C3 | * | M2 | M1 | M3 | C2 | O1 | O3 | C1 | C3 |
* +-----+-----+-----+-----+-----+-----+-----+-----+ * +-----+-----+-----+-----+-----+-----+-----+-----+
* *
* Cn - Control bit (control one digital line) * Cn - Control bit (control one digital line)
* On - Output bit (program a digital line for output) * On - Output bit (program a digital line for output)
* Mn - Mask bit (only the matching output control bit is affected) * Mn - Mask bit (only the matching output control bit is affected)
* *
* C3 - OUTPUT RELAY (0 - OFF, 1 - ON) * C3 - OUTPUT RELAY (0 - OFF, 1 - ON)
* C1 - GREEN LED (0 - OFF, 1 - ON) * C1 - GREEN LED (0 - OFF, 1 - ON)
* O3 - Output RELAY (this line is output) * O3 - Output RELAY (this line is output)
* O1 - Output GREEN (this line is output) * O1 - Output GREEN (this line is output)
* C2 - RED LED (0 - OFF, 1 - ON) * C2 - RED LED (0 - OFF, 1 - ON)
* M3 - Mask RELAY. (1 - C3 effect the OUTPUT RELAY) * M3 - Mask RELAY. (1 - C3 effect the OUTPUT RELAY)
* M2 - Mask RED. (1 - C2 effect the RED LED) * M2 - Mask RED. (1 - C2 effect the RED LED)
* M1 - Mask GREEN. (1 - C1 effect the GREEN LED) * M1 - Mask GREEN. (1 - C1 effect the GREEN LED)
* *
* The OUTPUT RELAY (actually a relay out) is connected to line 0 and 4 only. * The OUTPUT RELAY (actually a relay out) is connected to line 0 and 4 only.
*/ */
// GREEN RED OUTPUT RELAY // GREEN RED OUTPUT RELAY
@ -283,12 +302,14 @@ static void handle_fxs_leds(xpd_t *xpd)
(PHONEDEV(xpd).digital_outputs | PHONEDEV(xpd). (PHONEDEV(xpd).digital_outputs | PHONEDEV(xpd).
digital_inputs, i)) digital_inputs, i))
continue; continue;
if ((xpd->blink_mode & BIT(i)) || IS_BLINKING(priv, i, color)) { // Blinking /* Blinking? */
if ((xpd->blink_mode & BIT(i)) || IS_BLINKING(priv, i, color)) {
int mod_value = LED_COUNTER(priv, i, color); int mod_value = LED_COUNTER(priv, i, color);
if (!mod_value) if (!mod_value)
mod_value = DEFAULT_LED_PERIOD; /* safety value */ /* safety value */
// led state is toggled mod_value = DEFAULT_LED_PERIOD;
/* led state is toggled */
if ((timer_count % mod_value) == 0) { if ((timer_count % mod_value) == 0) {
LINE_DBG(LEDS, xpd, i, "ledstate=%s\n", LINE_DBG(LEDS, xpd, i, "ledstate=%s\n",
(IS_SET (IS_SET
@ -478,7 +499,9 @@ static int FXS_card_init(xbus_t *xbus, xpd_t *xpd)
* Setup ring timers * Setup ring timers
*/ */
/* Software controled ringing (for CID) */ /* Software controled ringing (for CID) */
ret = SLIC_DIRECT_REQUEST(xbus, xpd, PORT_BROADCAST, SLIC_WRITE, 0x22, 0x00); /* Ringing Oscilator Control */ /* Ringing Oscilator Control */
ret = SLIC_DIRECT_REQUEST(xbus, xpd, PORT_BROADCAST, SLIC_WRITE,
0x22, 0x00);
if (ret < 0) if (ret < 0)
goto err; goto err;
for_each_line(xpd, i) { for_each_line(xpd, i) {
@ -678,30 +701,28 @@ static int set_vm_led_mode(xbus_t *xbus, xpd_t *xpd, int pos,
LINE_DBG(SIGNAL, xpd, pos, "RINGER\n"); LINE_DBG(SIGNAL, xpd, pos, "RINGER\n");
BIT_CLR(priv->neon_blinking, pos); BIT_CLR(priv->neon_blinking, pos);
ret += ret += SLIC_INDIRECT_REQUEST(xbus, xpd, pos, SLIC_WRITE,
SLIC_INDIRECT_REQUEST(xbus, xpd, pos, SLIC_WRITE, 0x16, 0x16, 0x00, 0x00);
0x00, 0x00); ret += SLIC_INDIRECT_REQUEST(xbus, xpd, pos, SLIC_WRITE,
ret += 0x15, 0x77, 0x01);
SLIC_INDIRECT_REQUEST(xbus, xpd, pos, SLIC_WRITE, 0x15, ret += SLIC_INDIRECT_REQUEST(xbus, xpd, pos, SLIC_WRITE,
0x77, 0x01); 0x14, 0xFD, 0x7E);
ret +=
SLIC_INDIRECT_REQUEST(xbus, xpd, pos, SLIC_WRITE, 0x14,
0xFD, 0x7E);
ret += ret += SLIC_DIRECT_REQUEST(xbus, xpd, pos, SLIC_WRITE,
SLIC_DIRECT_REQUEST(xbus, xpd, pos, SLIC_WRITE, 0x22, 0x00); 0x22, 0x00);
ret += ret += SLIC_DIRECT_REQUEST(xbus, xpd, pos, SLIC_WRITE,
SLIC_DIRECT_REQUEST(xbus, xpd, pos, SLIC_WRITE, 0x30, 0x00); 0x30, 0x00);
ret += ret += SLIC_DIRECT_REQUEST(xbus, xpd, pos, SLIC_WRITE,
SLIC_DIRECT_REQUEST(xbus, xpd, pos, SLIC_WRITE, 0x31, 0x00); 0x31, 0x00);
ret += ret += SLIC_DIRECT_REQUEST(xbus, xpd, pos, SLIC_WRITE,
SLIC_DIRECT_REQUEST(xbus, xpd, pos, SLIC_WRITE, 0x32, 0x00); 0x32, 0x00);
ret += ret += SLIC_DIRECT_REQUEST(xbus, xpd, pos, SLIC_WRITE,
SLIC_DIRECT_REQUEST(xbus, xpd, pos, SLIC_WRITE, 0x33, 0x00); 0x33, 0x00);
ret += SLIC_DIRECT_REQUEST(xbus, xpd, pos, SLIC_WRITE, 0x4A, 0x34); /* High Vbat~ -82V[Dc] */ /* High Vbat~ -82V[Dc] */
ret += ret += SLIC_DIRECT_REQUEST(xbus, xpd, pos, SLIC_WRITE,
SLIC_INDIRECT_REQUEST(xbus, xpd, pos, SLIC_WRITE, 0x1D, 0x4A, 0x34);
0x00, 0x36); ret += SLIC_INDIRECT_REQUEST(xbus, xpd, pos, SLIC_WRITE,
0x1D, 0x00, 0x36);
} }
return (ret ? -EPROTO : 0); return (ret ? -EPROTO : 0);
} }
@ -988,7 +1009,10 @@ static int FXS_card_ioctl(xpd_t *xpd, int pos, unsigned int cmd,
if (!dtmf_detection) { if (!dtmf_detection) {
spin_lock_irqsave(&xpd->lock, flags); spin_lock_irqsave(&xpd->lock, flags);
if (IS_SET(priv->want_dtmf_events, pos)) { if (IS_SET(priv->want_dtmf_events, pos)) {
/* Detection mode changed: Disable DTMF interrupts */ /*
* Detection mode changed:
* Disable DTMF interrupts
*/
SLIC_DIRECT_REQUEST(xbus, xpd, pos, SLIC_WRITE, SLIC_DIRECT_REQUEST(xbus, xpd, pos, SLIC_WRITE,
0x17, 0); 0x17, 0);
} }
@ -1006,18 +1030,26 @@ static int FXS_card_ioctl(xpd_t *xpd, int pos, unsigned int cmd,
spin_lock_irqsave(&xpd->lock, flags); spin_lock_irqsave(&xpd->lock, flags);
if (val & DAHDI_TONEDETECT_ON) { if (val & DAHDI_TONEDETECT_ON) {
if (!IS_SET(priv->want_dtmf_events, pos)) { if (!IS_SET(priv->want_dtmf_events, pos)) {
/* Detection mode changed: Enable DTMF interrupts */ /*
* Detection mode changed:
* Enable DTMF interrupts
*/
LINE_DBG(SIGNAL, xpd, pos, LINE_DBG(SIGNAL, xpd, pos,
"DAHDI_TONEDETECT: Enable Hardware DTMF\n"); "DAHDI_TONEDETECT: "
"Enable Hardware DTMF\n");
SLIC_DIRECT_REQUEST(xbus, xpd, pos, SLIC_WRITE, SLIC_DIRECT_REQUEST(xbus, xpd, pos, SLIC_WRITE,
0x17, 1); 0x17, 1);
} }
BIT_SET(priv->want_dtmf_events, pos); BIT_SET(priv->want_dtmf_events, pos);
} else { } else {
if (IS_SET(priv->want_dtmf_events, pos)) { if (IS_SET(priv->want_dtmf_events, pos)) {
/* Detection mode changed: Disable DTMF interrupts */ /*
* Detection mode changed:
* Disable DTMF interrupts
*/
LINE_DBG(SIGNAL, xpd, pos, LINE_DBG(SIGNAL, xpd, pos,
"DAHDI_TONEDETECT: Disable Hardware DTMF\n"); "DAHDI_TONEDETECT: "
"Disable Hardware DTMF\n");
SLIC_DIRECT_REQUEST(xbus, xpd, pos, SLIC_WRITE, SLIC_DIRECT_REQUEST(xbus, xpd, pos, SLIC_WRITE,
0x17, 0); 0x17, 0);
} }
@ -1052,8 +1084,9 @@ static int FXS_card_ioctl(xpd_t *xpd, int pos, unsigned int cmd,
if (priv->lasttxhook[pos] == FXS_LINE_RING if (priv->lasttxhook[pos] == FXS_LINE_RING
|| priv->lasttxhook[pos] == FXS_LINE_OPEN) { || priv->lasttxhook[pos] == FXS_LINE_OPEN) {
LINE_DBG(SIGNAL, xpd, pos, LINE_DBG(SIGNAL, xpd, pos,
"DAHDI_SETPOLARITY: %s Cannot change when lasttxhook=0x%X\n", "DAHDI_SETPOLARITY: %s Cannot change "
(val) ? "ON" : "OFF", priv->lasttxhook[pos]); "when lasttxhook=0x%X\n",
(val) ? "ON" : "OFF", priv->lasttxhook[pos]);
return -EINVAL; return -EINVAL;
} }
LINE_DBG(SIGNAL, xpd, pos, "DAHDI_SETPOLARITY: %s\n", LINE_DBG(SIGNAL, xpd, pos, "DAHDI_SETPOLARITY: %s\n",
@ -1076,7 +1109,9 @@ static int FXS_card_ioctl(xpd_t *xpd, int pos, unsigned int cmd,
if (!notified++) if (!notified++)
LINE_NOTICE(xpd, pos, LINE_NOTICE(xpd, pos,
"Got DAHDI_VMWI notification but vmwi_ioctl parameter is off. Ignoring.\n"); "Got DAHDI_VMWI notification "
"but vmwi_ioctl parameter is off. "
"Ignoring.\n");
return 0; return 0;
} }
/* Digital inputs/outputs don't have VM leds */ /* Digital inputs/outputs don't have VM leds */
@ -1249,7 +1284,8 @@ static void detect_vmwi(xpd_t *xpd)
(mem_equal (mem_equal
(writechunk, FSK_COMMON_PATTERN, DAHDI_CHUNKSIZE))) { (writechunk, FSK_COMMON_PATTERN, DAHDI_CHUNKSIZE))) {
LINE_DBG(SIGNAL, xpd, i, LINE_DBG(SIGNAL, xpd, i,
"Found common FSK pattern. Start looking for ON/OFF patterns.\n"); "Found common FSK pattern. "
"Start looking for ON/OFF patterns.\n");
BIT_SET(priv->found_fsk_pattern, i); BIT_SET(priv->found_fsk_pattern, i);
} else if (unlikely(IS_SET(priv->found_fsk_pattern, i))) { } else if (unlikely(IS_SET(priv->found_fsk_pattern, i))) {
BIT_CLR(priv->found_fsk_pattern, i); BIT_CLR(priv->found_fsk_pattern, i);
@ -1314,7 +1350,8 @@ static int FXS_card_tick(xbus_t *xbus, xpd_t *xpd)
IS_OFFHOOK(xpd, IS_OFFHOOK(xpd,
i) ? DAHDI_RXSIG_OFFHOOK : i) ? DAHDI_RXSIG_OFFHOOK :
DAHDI_RXSIG_ONHOOK; DAHDI_RXSIG_ONHOOK;
notify_rxsig(xpd, i, rxsig); /* Notify after open() */ /* Notify after open() */
notify_rxsig(xpd, i, rxsig);
BIT_CLR(priv->update_offhook_state, i); BIT_CLR(priv->update_offhook_state, i);
} }
} }
@ -1393,8 +1430,9 @@ HANDLER_DEF(FXS, SIG_CHANGED)
sig_toggles, sig_status); sig_toggles, sig_status);
#if 0 #if 0
Is this needed ? for_each_line(xpd, i) { Is this needed ? for_each_line(xpd, i) {
// Power down (prevent overheating!!!)
if (IS_SET(sig_toggles, i)) if (IS_SET(sig_toggles, i))
do_chan_power(xpd->xbus, xpd, BIT(i), 0); // Power down (prevent overheating!!!) do_chan_power(xpd->xbus, xpd, BIT(i), 0);
} }
#endif #endif
spin_lock_irqsave(&xpd->lock, flags); spin_lock_irqsave(&xpd->lock, flags);
@ -1425,11 +1463,12 @@ static void process_digital_inputs(xpd_t *xpd, const reg_cmd_t *info)
newchanno = PHONEDEV(xpd).channels - LINES_DIGI_INP + i; newchanno = PHONEDEV(xpd).channels - LINES_DIGI_INP + i;
BIT_CLR(lines, channo); BIT_CLR(lines, channo);
BIT_SET(lines, newchanno); BIT_SET(lines, newchanno);
PHONEDEV(xpd).ringing[newchanno] = 0; // Stop ringing. No leds for digital inputs. /* Stop ringing. No leds for digital inputs. */
if (offhook && !IS_OFFHOOK(xpd, newchanno)) { // OFFHOOK PHONEDEV(xpd).ringing[newchanno] = 0;
if (offhook && !IS_OFFHOOK(xpd, newchanno)) {
LINE_DBG(SIGNAL, xpd, newchanno, "OFFHOOK\n"); LINE_DBG(SIGNAL, xpd, newchanno, "OFFHOOK\n");
hookstate_changed(xpd, newchanno, 1); hookstate_changed(xpd, newchanno, 1);
} else if (!offhook && IS_OFFHOOK(xpd, newchanno)) { // ONHOOK } else if (!offhook && IS_OFFHOOK(xpd, newchanno)) {
LINE_DBG(SIGNAL, xpd, newchanno, "ONHOOK\n"); LINE_DBG(SIGNAL, xpd, newchanno, "ONHOOK\n");
hookstate_changed(xpd, newchanno, 0); hookstate_changed(xpd, newchanno, 0);
} }
@ -1477,10 +1516,11 @@ static void process_dtmf(xpd_t *xpd, uint portnum, __u8 val)
msec = usec_diff(&now, &priv->prev_key_time[portnum]) / 1000; msec = usec_diff(&now, &priv->prev_key_time[portnum]) / 1000;
priv->prev_key_time[portnum] = now; priv->prev_key_time[portnum] = now;
LINE_DBG(SIGNAL, xpd, portnum, LINE_DBG(SIGNAL, xpd, portnum,
"[%lu.%06lu] DTMF digit %-4s '%c' (val=%d, want_mute=%s want_event=%s, delta=%d msec)\n", "[%lu.%06lu] DTMF digit %-4s '%c' "
now.tv_sec, now.tv_usec, (key_down) ? "DOWN" : "UP", digit, "(val=%d, want_mute=%s want_event=%s, delta=%d msec)\n",
val, (want_mute) ? "yes" : "no", (want_event) ? "yes" : "no", now.tv_sec, now.tv_usec, (key_down) ? "DOWN" : "UP", digit,
msec); val, (want_mute) ? "yes" : "no", (want_event) ? "yes" : "no",
msec);
/* /*
* FIXME: we currently don't use the want_dtmf_mute until * FIXME: we currently don't use the want_dtmf_mute until
* we are sure about the logic in Asterisk native bridging. * we are sure about the logic in Asterisk native bridging.
@ -1538,25 +1578,31 @@ static int FXS_card_register_reply(xbus_t *xbus, xpd_t *xpd, reg_cmd_t *info)
if ((val & REG_LOOPCLOSURE_ZERO) == 0) { if ((val & REG_LOOPCLOSURE_ZERO) == 0) {
offhook = (val & REG_LOOPCLOSURE_LCR) ? mask : 0; offhook = (val & REG_LOOPCLOSURE_LCR) ? mask : 0;
LINE_DBG(SIGNAL, xpd, info->portnum, LINE_DBG(SIGNAL, xpd, info->portnum,
"REG_LOOPCLOSURE: dataL=0x%X (offhook=0x%X mask=0x%X\n", "REG_LOOPCLOSURE: dataL=0x%X "
val, offhook, mask); "(offhook=0x%X mask=0x%X)\n",
val, offhook, mask);
process_hookstate(xpd, offhook, mask); process_hookstate(xpd, offhook, mask);
} }
} else { } else {
#if 0 #if 0
XPD_NOTICE(xpd, XPD_NOTICE(xpd,
"Spurious register reply(ignored): %s reg_num=0x%X, dataL=0x%X dataH=0x%X\n", "Spurious register reply(ignored): "
(indirect) ? "I" : "D", regnum, REG_FIELD(info, "%s reg_num=0x%X, dataL=0x%X dataH=0x%X\n",
data_low), (indirect) ? "I" : "D",
REG_FIELD(info, data_high)); regnum, REG_FIELD(info, data_low),
REG_FIELD(info, data_high));
#endif #endif
} }
/* Update /proc info only if reply relate to the last slic read request */ /*
if (REG_FIELD(&xpd->requested_reply, regnum) == REG_FIELD(info, regnum) * Update /proc info only if reply relate to the last slic
&& REG_FIELD(&xpd->requested_reply, do_subreg) == REG_FIELD(info, * read request
do_subreg) */
&& REG_FIELD(&xpd->requested_reply, subreg) == REG_FIELD(info, if (REG_FIELD(&xpd->requested_reply, regnum) ==
subreg)) { REG_FIELD(info, regnum)
&& REG_FIELD(&xpd->requested_reply, do_subreg) ==
REG_FIELD(info, do_subreg)
&& REG_FIELD(&xpd->requested_reply, subreg) ==
REG_FIELD(info, subreg)) {
xpd->last_reply = *info; xpd->last_reply = *info;
} }
spin_unlock_irqrestore(&xpd->lock, flags); spin_unlock_irqrestore(&xpd->lock, flags);
@ -1698,8 +1744,8 @@ static int proc_fxs_info_read(char *page, char **start, off_t off, int count,
#endif #endif
#ifdef WITH_METERING #ifdef WITH_METERING
static int proc_xpd_metering_write(struct file *file, const char __user *buffer, static int proc_xpd_metering_write(struct file *file, const char
unsigned long count, void *data) __user *buffer, unsigned long count, void *data)
{ {
xpd_t *xpd = data; xpd_t *xpd = data;
char buf[MAX_PROC_WRITE]; char buf[MAX_PROC_WRITE];

View File

@ -31,8 +31,9 @@ enum fxs_opcodes {
XPROTO_NAME(FXS, LED) = 0x0F, /* Write to SLIC */ XPROTO_NAME(FXS, LED) = 0x0F, /* Write to SLIC */
}; };
DEF_RPACKET_DATA(FXS, SIG_CHANGED, xpp_line_t sig_status; /* channels: lsb=1, msb=8 */ DEF_RPACKET_DATA(FXS, SIG_CHANGED,
xpp_line_t sig_toggles; /* channels: lsb=1, msb=8 */ xpp_line_t sig_status; /* channels: lsb=1, msb=8 */
); xpp_line_t sig_toggles; /* channels: lsb=1, msb=8 */
);
#endif /* CARD_FXS_H */ #endif /* CARD_FXS_H */

View File

@ -102,7 +102,8 @@ static int execute_chip_command(xpd_t *xpd, const int argc, char *argv[])
if (argc < num_args) { if (argc < num_args) {
XPD_ERR(xpd, "Not enough arguments (%d)\n", argc); XPD_ERR(xpd, "Not enough arguments (%d)\n", argc);
XPD_ERR(xpd, XPD_ERR(xpd,
"Any Command is composed of at least %d words (got only %d)\n", "Any Command is composed of at least %d words "
"(got only %d)\n",
num_args, argc); num_args, argc);
goto out; goto out;
} }
@ -143,7 +144,8 @@ static int execute_chip_command(xpd_t *xpd, const int argc, char *argv[])
switch (addr_mode) { switch (addr_mode) {
case 'I': case 'I':
XPD_NOTICE(xpd, XPD_NOTICE(xpd,
"'I' is deprecated in register commands. Use 'S' instead.\n"); "'I' is deprecated in register commands. "
"Use 'S' instead.\n");
/* fall through */ /* fall through */
case 'S': case 'S':
do_subreg = 1; do_subreg = 1;
@ -176,7 +178,8 @@ static int execute_chip_command(xpd_t *xpd, const int argc, char *argv[])
} }
if (argc < num_args) { if (argc < num_args) {
XPD_ERR(xpd, XPD_ERR(xpd,
"Command \"%s\" is composed of at least %d words (got only %d)\n", "Command \"%s\" is composed of at least %d words "
"(got only %d)\n",
argv[argno], num_args, argc); argv[argno], num_args, argc);
goto out; goto out;
} }
@ -259,14 +262,13 @@ static int execute_chip_command(xpd_t *xpd, const int argc, char *argv[])
} }
#if 0 #if 0
XPD_DBG(REGS, xpd, XPD_DBG(REGS, xpd,
"portno=%d writing=%d regnum=%d do_subreg=%d subreg=%d dataL=%d do_datah=%d dataH=%d\n", "portno=%d writing=%d regnum=%d do_subreg=%d subreg=%d "
portno, /* portno */ "dataL=%d do_datah=%d dataH=%d\n",
writing, /* writing */ portno, /* portno */
regnum, writing, /* writing */
do_subreg, /* use subreg */ regnum, do_subreg, /* use subreg */
subreg, /* subreg */ subreg, /* subreg */
data_low, data_low, do_datah, /* use data_high */
do_datah, /* use data_high*/
data_high); data_high);
#endif #endif
ret = xpp_register_request(xpd->xbus, xpd, portno, ret = xpp_register_request(xpd->xbus, xpd, portno,
@ -302,7 +304,8 @@ int parse_chip_command(xpd_t *xpd, char *cmdline)
*p = '\0'; *p = '\0';
if ((p = strchr(buf, ';')) != NULL) /* Truncate comments */ if ((p = strchr(buf, ';')) != NULL) /* Truncate comments */
*p = '\0'; *p = '\0';
for (p = buf; *p && (*p == ' ' || *p == '\t'); p++) /* Trim leading whitespace */ /* Trim leading whitespace */
for (p = buf; *p && (*p == ' ' || *p == '\t'); p++)
; ;
str = p; str = p;
for (i = 0; (p = strsep(&str, " \t")) != NULL && i < MAX_ARGS;) { for (i = 0; (p = strsep(&str, " \t")) != NULL && i < MAX_ARGS;) {
@ -375,7 +378,8 @@ int xpp_register_request(xbus_t *xbus, xpd_t *xpd, xportno_t portno,
(writing) ? 'W' : 'R', (do_subreg) ? 'S' : 'D', regnum, subreg, (writing) ? 'W' : 'R', (do_subreg) ? 'S' : 'D', regnum, subreg,
data_low, data_high); data_low, data_high);
reg_cmd = &RPACKET_FIELD(pack, GLOBAL, REGISTER_REQUEST, reg_cmd); reg_cmd = &RPACKET_FIELD(pack, GLOBAL, REGISTER_REQUEST, reg_cmd);
reg_cmd->bytes = sizeof(*reg_cmd) - 1; // do not count the 'bytes' field /* do not count the 'bytes' field */
reg_cmd->bytes = sizeof(*reg_cmd) - 1;
reg_cmd->is_multibyte = 0; reg_cmd->is_multibyte = 0;
if (portno == PORT_BROADCAST) { if (portno == PORT_BROADCAST) {
reg_cmd->portnum = 0; reg_cmd->portnum = 0;
@ -525,11 +529,12 @@ HANDLER_DEF(GLOBAL, AB_DESCRIPTION)
card_desc->ports = card_desc->ports =
card_desc->numchips * card_desc->ports_per_chip; card_desc->numchips * card_desc->ports_per_chip;
XBUS_INFO(xbus, XBUS_INFO(xbus,
" CARD %d type=%d.%d ports=%d (%dx%d), port-dir=0x%02X\n", " CARD %d type=%d.%d ports=%d (%dx%d), "
card_desc->xpd_addr.unit, card_desc->type, "port-dir=0x%02X\n",
card_desc->subtype, card_desc->ports, card_desc->xpd_addr.unit, card_desc->type,
card_desc->numchips, card_desc->ports_per_chip, card_desc->subtype, card_desc->ports,
card_desc->port_dir); card_desc->numchips, card_desc->ports_per_chip,
card_desc->port_dir);
spin_lock_irqsave(&worker->worker_lock, flags); spin_lock_irqsave(&worker->worker_lock, flags);
worker->num_units++; worker->num_units++;
XBUS_COUNTER(xbus, UNITS)++; XBUS_COUNTER(xbus, UNITS)++;
@ -565,7 +570,7 @@ HANDLER_DEF(GLOBAL, REGISTER_REPLY)
} }
if (!XMETHOD(card_register_reply, xpd)) { if (!XMETHOD(card_register_reply, xpd)) {
XPD_ERR(xpd, XPD_ERR(xpd,
"REGISTER_REPLY: without card_register_reply() method\n"); "REGISTER_REPLY: missing card_register_reply()\n");
return -EINVAL; return -EINVAL;
} }
return CALL_XMETHOD(card_register_reply, xpd, reg); return CALL_XMETHOD(card_register_reply, xpd, reg);
@ -721,8 +726,9 @@ int run_initialize_registers(xpd_t *xpd)
(init_card, MAX_PATH_STR, "%s/init_card_%d_%d", initdir, xpd->type, (init_card, MAX_PATH_STR, "%s/init_card_%d_%d", initdir, xpd->type,
xbus->revision) > MAX_PATH_STR) { xbus->revision) > MAX_PATH_STR) {
XPD_NOTICE(xpd, XPD_NOTICE(xpd,
"Cannot initialize. pathname is longer than %d characters.\n", "Cannot initialize. pathname is longer "
MAX_PATH_STR); "than %d characters.\n",
MAX_PATH_STR);
ret = -E2BIG; ret = -E2BIG;
goto err; goto err;
} }

View File

@ -35,7 +35,8 @@
static const char rcsid[] = "$Id$"; static const char rcsid[] = "$Id$";
static DEF_PARM(int, debug, 0, 0644, "Print DBG statements"); /* must be before dahdi_debug.h */ /* must be before dahdi_debug.h */
static DEF_PARM(int, debug, 0, 0644, "Print DBG statements");
static DEF_PARM(uint, poll_interval, 500, 0644, static DEF_PARM(uint, poll_interval, 500, 0644,
"Poll channel state interval in milliseconds (0 - disable)"); "Poll channel state interval in milliseconds (0 - disable)");
@ -201,13 +202,18 @@ struct pri_leds {
#define REG_FRS1 0x4D /* Framer Receive Status Register 1 */ #define REG_FRS1 0x4D /* Framer Receive Status Register 1 */
#define REG_LIM0 0x36 #define REG_LIM0 0x36
#define REG_LIM0_MAS BIT(0) /* Master Mode, DCO-R circuitry is frequency synchronized to the clock supplied by SYNC */ /*
#define REG_LIM0_RTRS BIT(5) /* * Master Mode, DCO-R circuitry is frequency synchronized
* Receive Termination Resistance Selection: * to the clock supplied by SYNC
* integrated resistor to create 75 Ohm termination (100 || 300 = 75) */
* 0 = 100 Ohm #define REG_LIM0_MAS BIT(0)
* 1 = 75 Ohm /*
*/ * Receive Termination Resistance Selection:
* integrated resistor to create 75 Ohm termination (100 || 300 = 75)
* 0 = 100 Ohm
* 1 = 75 Ohm
*/
#define REG_LIM0_RTRS BIT(5)
#define REG_LIM0_LL BIT(1) /* LL (Local Loopback) */ #define REG_LIM0_LL BIT(1) /* LL (Local Loopback) */
#define REG_FMR0 0x1C #define REG_FMR0 0x1C
@ -234,9 +240,12 @@ struct pri_leds {
#define REG_FMR2_E_PLB BIT(2) /* Payload Loop-Back */ #define REG_FMR2_E_PLB BIT(2) /* Payload Loop-Back */
#define REG_FMR2_E_RFS0 BIT(6) /* Receive Framing Select - LSB */ #define REG_FMR2_E_RFS0 BIT(6) /* Receive Framing Select - LSB */
#define REG_FMR2_E_RFS1 BIT(7) /* Receive Framing Select - MSB */ #define REG_FMR2_E_RFS1 BIT(7) /* Receive Framing Select - MSB */
#define REG_FMR2_T_SSP BIT(5) /* Select Synchronization/Resynchronization Procedure */ /* Select Synchronization/Resynchronization Procedure */
#define REG_FMR2_T_MCSP BIT(6) /* Multiple Candidates Synchronization Procedure */ #define REG_FMR2_T_SSP BIT(5)
#define REG_FMR2_T_AFRS BIT(7) /* Automatic Force Resynchronization */ /* Multiple Candidates Synchronization Procedure */
#define REG_FMR2_T_MCSP BIT(6)
/* Automatic Force Resynchronization */
#define REG_FMR2_T_AFRS BIT(7)
#define REG_FMR3 0x31 #define REG_FMR3 0x31
#define REG_FMR3_EXTIW BIT(0) /* Extended CRC4 to Non-CRC4 Interworking */ #define REG_FMR3_EXTIW BIT(0) /* Extended CRC4 to Non-CRC4 Interworking */
@ -263,10 +272,13 @@ struct pri_leds {
#define REG_XSP_E 0x21 #define REG_XSP_E 0x21
#define REG_FMR5_T 0x21 #define REG_FMR5_T 0x21
#define REG_XSP_E_XSIF BIT(2) /* Transmit Spare Bit For International Use (FAS Word) */ /* Transmit Spare Bit For International Use (FAS Word) */
#define REG_XSP_E_XSIF BIT(2)
#define REG_FMR5_T_XTM BIT(2) /* Transmit Transparent Mode */ #define REG_FMR5_T_XTM BIT(2) /* Transmit Transparent Mode */
#define REG_XSP_E_AXS BIT(3) /* Automatic Transmission of Submultiframe Status */ /* Automatic Transmission of Submultiframe Status */
#define REG_XSP_E_EBP BIT(4) /* E-Bit Polarity, Si-bit position of every outgoing CRC multiframe */ #define REG_XSP_E_AXS BIT(3)
/* E-Bit Polarity, Si-bit position of every outgoing CRC multiframe */
#define REG_XSP_E_EBP BIT(4)
#define REG_XSP_E_CASEN BIT(6) /* CAS: Channel Associated Signaling Enable */ #define REG_XSP_E_CASEN BIT(6) /* CAS: Channel Associated Signaling Enable */
#define REG_FMR5_T_EIBR BIT(6) /* CAS: Enable Internal Bit Robbing Access */ #define REG_FMR5_T_EIBR BIT(6) /* CAS: Enable Internal Bit Robbing Access */
@ -384,14 +396,15 @@ static int write_subunit(xpd_t *xpd, __u8 regnum, __u8 val)
{ {
XPD_DBG(REGS, xpd, "(%d%d): REG=0x%02X dataL=0x%02X\n", xpd->addr.unit, XPD_DBG(REGS, xpd, "(%d%d): REG=0x%02X dataL=0x%02X\n", xpd->addr.unit,
xpd->addr.subunit, regnum, val); xpd->addr.subunit, regnum, val);
return xpp_register_request(xpd->xbus, xpd, PRI_PORT(xpd), /* portno */ return xpp_register_request(xpd->xbus, xpd,
1, /* writing */ PRI_PORT(xpd), /* portno */
regnum, 0, /* do_subreg */ 1, /* writing */
0, /* subreg */ regnum, 0, /* do_subreg */
val, /* data_L */ 0, /* subreg */
0, /* do_datah */ val, /* data_L */
0, /* data_H */ 0, /* do_datah */
0 /* should_reply */ 0, /* data_H */
0 /* should_reply */
); );
} }
@ -635,7 +648,7 @@ static void dahdi_update_syncsrc(xpd_t *xpd)
if (priv->clock_source && priv->alarms == 0) { if (priv->clock_source && priv->alarms == 0) {
if (best_spanno) if (best_spanno)
XPD_ERR(xpd, XPD_ERR(xpd,
"Duplicate XPD's with clock_source=1\n"); "Duplicate XPD with clock_source=1\n");
best_spanno = PHONEDEV(subxpd).span.spanno; best_spanno = PHONEDEV(subxpd).span.spanno;
} }
} }
@ -783,17 +796,15 @@ static const struct {
const int flags; const int flags;
} valid_spanconfigs[sizeof(unsigned int) * 8] = { } valid_spanconfigs[sizeof(unsigned int) * 8] = {
/* These apply to T1 */ /* These apply to T1 */
VALID_CONFIG(4, DAHDI_CONFIG_D4, "D4"), VALID_CONFIG(5, VALID_CONFIG(4, DAHDI_CONFIG_D4, "D4"),
DAHDI_CONFIG_ESF, VALID_CONFIG(5, DAHDI_CONFIG_ESF, "ESF"),
"ESF"), VALID_CONFIG(6, DAHDI_CONFIG_AMI, "AMI"),
VALID_CONFIG(6, DAHDI_CONFIG_AMI, "AMI"), VALID_CONFIG(7, VALID_CONFIG(7, DAHDI_CONFIG_B8ZS, "B8ZS"),
DAHDI_CONFIG_B8ZS, /* These apply to E1 */
"B8ZS"), VALID_CONFIG(8, DAHDI_CONFIG_CCS, "CCS"),
/* These apply to E1 */ VALID_CONFIG(9, DAHDI_CONFIG_HDB3, "HDB3"),
VALID_CONFIG(8, DAHDI_CONFIG_CCS, "CCS"), VALID_CONFIG(9, VALID_CONFIG(10, DAHDI_CONFIG_CRC4, "CRC4"),
DAHDI_CONFIG_HDB3, };
"HDB3"),
VALID_CONFIG(10, DAHDI_CONFIG_CRC4, "CRC4"),};
/* /*
* Mark the lines as CLEAR or RBS signalling. * Mark the lines as CLEAR or RBS signalling.
@ -842,12 +853,10 @@ static void set_rbslines(xpd_t *xpd, int channo)
bytenum += REG_CCB1_T; bytenum += REG_CCB1_T;
XPD_DBG(DEVICES, xpd, XPD_DBG(DEVICES, xpd,
"RBS(%s): modified=0x%X rbslines=0x%X reg=0x%X clear_lines=0x%X\n", "RBS(%s): modified=0x%X rbslines=0x%X reg=0x%X clear_lines=0x%X\n",
pri_protocol_name(priv-> pri_protocol_name(priv->pri_protocol),
pri_protocol),
modified_lines, new_rbslines, modified_lines, new_rbslines,
bytenum, clear_lines); bytenum, clear_lines);
write_subunit(xpd, bytenum, write_subunit(xpd, bytenum, clear_lines);
clear_lines);
} }
clear_lines = 0; clear_lines = 0;
reg_changed = 0; reg_changed = 0;
@ -911,7 +920,8 @@ static int pri_lineconfig(xpd_t *xpd, int lineconfig)
} else { } else {
/* we got real garbage */ /* we got real garbage */
XPD_ERR(xpd, XPD_ERR(xpd,
"Unknown config item 0x%lX for %s. Ignore\n", "Unknown config item 0x%lX for %s. "
"Ignore.\n",
BIT(i), BIT(i),
pri_protocol_name(priv->pri_protocol)); pri_protocol_name(priv->pri_protocol));
} }
@ -990,9 +1000,11 @@ static int pri_lineconfig(xpd_t *xpd, int lineconfig)
codingstr = "D4"; codingstr = "D4";
} else if (lineconfig & DAHDI_CONFIG_CCS) { } else if (lineconfig & DAHDI_CONFIG_CCS) {
codingstr = "CCS"; codingstr = "CCS";
set_mode_cas(xpd, 0); /* In E1 we know right from the span statement. */ /* In E1 we know right from the span statement. */
set_mode_cas(xpd, 0);
} else { } else {
codingstr = "CAS"; /* In E1 we know right from the span statement. */ /* In E1 we know right from the span statement. */
codingstr = "CAS";
force_cas = 1; force_cas = 1;
set_mode_cas(xpd, 1); set_mode_cas(xpd, 1);
} }
@ -1135,7 +1147,9 @@ static int pri_chanconfig(struct file *file, struct dahdi_chan *chan,
*/ */
if (is_sigtype_dchan(sigtype)) { if (is_sigtype_dchan(sigtype)) {
if (VALID_DCHAN(priv) && DCHAN(priv) != chan->channo) { if (VALID_DCHAN(priv) && DCHAN(priv) != chan->channo) {
ERR("channel %d (%s) marked DChan but also channel %d.\n", chan->channo, chan->name, DCHAN(priv)); ERR("channel %d (%s) marked DChan but "
"also channel %d.\n",
chan->channo, chan->name, DCHAN(priv));
return -EINVAL; return -EINVAL;
} }
XPD_DBG(GENERAL, xpd, "channel %d (%s) marked as DChan\n", XPD_DBG(GENERAL, xpd, "channel %d (%s) marked as DChan\n",
@ -1185,8 +1199,10 @@ static xpd_t *PRI_card_new(xbus_t *xbus, int unit, int subunit,
if (!xpd) if (!xpd)
return NULL; return NULL;
priv = xpd->priv; priv = xpd->priv;
priv->pri_protocol = PRI_PROTO_0; /* Default, changes in set_pri_proto() */ /* Default, changes in set_pri_proto() */
priv->deflaw = DAHDI_LAW_DEFAULT; /* Default, changes in set_pri_proto() */ priv->pri_protocol = PRI_PROTO_0;
/* Default, changes in set_pri_proto() */
priv->deflaw = DAHDI_LAW_DEFAULT;
xpd->type_name = type_name(priv->pri_protocol); xpd->type_name = type_name(priv->pri_protocol);
xbus->sync_mode_default = SYNC_MODE_AB; xbus->sync_mode_default = SYNC_MODE_AB;
return xpd; return xpd;
@ -1791,7 +1807,8 @@ static void PRI_card_pcm_fromspan(xpd_t *xpd, xpacket_t *pack)
} else if (chan->writechunk[0] == 0xFF) } else if (chan->writechunk[0] == 0xFF)
dchan_state(xpd, 0); dchan_state(xpd, 0);
else else
chan->writechunk[0] = 0xFF; /* Clobber for next tick */ /* Clobber for next tick */
chan->writechunk[0] = 0xFF;
} }
} else } else
memset((u_char *)pcm, DAHDI_XLAW(0, chan), memset((u_char *)pcm, DAHDI_XLAW(0, chan),
@ -1848,8 +1865,8 @@ static void PRI_card_pcm_tospan(xpd_t *xpd, xpacket_t *pack)
if (priv->dchan_rx_sample != pcm[0]) { if (priv->dchan_rx_sample != pcm[0]) {
if (debug & DBG_PCM) { if (debug & DBG_PCM) {
XPD_INFO(xpd, XPD_INFO(xpd,
"RX-D-Chan: prev=0x%X now=0x%X\n", "RX-D-Chan: prev=0x%X now=0x%X\n",
priv->dchan_rx_sample, pcm[0]); priv->dchan_rx_sample, pcm[0]);
dump_packet("RX-D-Chan", pack, 1); dump_packet("RX-D-Chan", pack, 1);
} }
priv->dchan_rx_sample = pcm[0]; priv->dchan_rx_sample = pcm[0];
@ -2134,9 +2151,10 @@ static void process_cas_dchan(xpd_t *xpd, __u8 regnum, __u8 data_low)
return; return;
XPD_NOTICE(xpd, XPD_NOTICE(xpd,
"%s: received register 0x%X in protocol %s. Ignore\n", "%s: received register 0x%X in protocol %s. "
__func__, regnum, "Ignore.\n",
pri_protocol_name(priv->pri_protocol)); __func__, regnum,
pri_protocol_name(priv->pri_protocol));
return; return;
} }
if (decode_cas_e1(xpd, regnum, data_low) < 0) if (decode_cas_e1(xpd, regnum, data_low) < 0)
@ -2144,8 +2162,9 @@ static void process_cas_dchan(xpd_t *xpd, __u8 regnum, __u8 data_low)
} else if (priv->pri_protocol == PRI_PROTO_T1) { } else if (priv->pri_protocol == PRI_PROTO_T1) {
if (regnum > REG_RS12_E) { if (regnum > REG_RS12_E) {
XPD_NOTICE(xpd, XPD_NOTICE(xpd,
"%s: received register 0x%X in protocol %s. Ignore\n", "%s: received register 0x%X in protocol %s. "
__func__, regnum, "Ignore.\n",
__func__, regnum,
pri_protocol_name(priv->pri_protocol)); pri_protocol_name(priv->pri_protocol));
return; return;
} }
@ -2199,12 +2218,16 @@ static int PRI_card_register_reply(xbus_t *xbus, xpd_t *xpd, reg_cmd_t *info)
process_cas_dchan(xpd, regnum, data_low); process_cas_dchan(xpd, regnum, data_low);
} }
} }
/* Update /proc info only if reply relate to the last slic read request */ /*
if (REG_FIELD(&xpd->requested_reply, regnum) == REG_FIELD(info, regnum) * Update /proc info only if reply relate to the
&& REG_FIELD(&xpd->requested_reply, do_subreg) == REG_FIELD(info, * last slic read request
do_subreg) */
&& REG_FIELD(&xpd->requested_reply, subreg) == REG_FIELD(info, if (REG_FIELD(&xpd->requested_reply, regnum) ==
subreg)) { REG_FIELD(info, regnum)
&& REG_FIELD(&xpd->requested_reply, do_subreg) ==
REG_FIELD(info, do_subreg)
&& REG_FIELD(&xpd->requested_reply, subreg) ==
REG_FIELD(info, subreg)) {
xpd->last_reply = *info; xpd->last_reply = *info;
} }
@ -2300,8 +2323,9 @@ static DEVICE_ATTR_WRITER(pri_protocol_store, dev, buf, count)
i = strcspn(buf, " \r\n"); i = strcspn(buf, " \r\n");
if (i != 2) { if (i != 2) {
XPD_NOTICE(xpd, XPD_NOTICE(xpd,
"Protocol name '%s' has %d characters (should be 2). Ignored.\n", "Protocol name '%s' has %d characters (should be 2). "
buf, i); "Ignored.\n",
buf, i);
return -EINVAL; return -EINVAL;
} }
if (strnicmp(buf, "E1", 2) == 0) if (strnicmp(buf, "E1", 2) == 0)
@ -2312,8 +2336,9 @@ static DEVICE_ATTR_WRITER(pri_protocol_store, dev, buf, count)
new_protocol = PRI_PROTO_J1; new_protocol = PRI_PROTO_J1;
else { else {
XPD_NOTICE(xpd, XPD_NOTICE(xpd,
"Unknown PRI protocol '%s' (should be E1|T1|J1). Ignored.\n", "Unknown PRI protocol '%s' (should be E1|T1|J1). "
buf); "Ignored.\n",
buf);
return -EINVAL; return -EINVAL;
} }
ret = set_pri_proto(xpd, new_protocol); ret = set_pri_proto(xpd, new_protocol);
@ -2356,8 +2381,8 @@ static DEVICE_ATTR_WRITER(pri_localloop_store, dev, buf, count)
return -ENODEV; return -ENODEV;
if ((i = strcspn(buf, " \r\n")) != 1) { if ((i = strcspn(buf, " \r\n")) != 1) {
XPD_NOTICE(xpd, XPD_NOTICE(xpd,
"Value '%s' has %d characters (should be 1). Ignored.\n", "Value '%s' has %d characters (should be 1). Ignored\n",
buf, i); buf, i);
return -EINVAL; return -EINVAL;
} }
if (strchr("1Yy", buf[0]) != NULL) if (strchr("1Yy", buf[0]) != NULL)
@ -2366,8 +2391,8 @@ static DEVICE_ATTR_WRITER(pri_localloop_store, dev, buf, count)
ll = 0; ll = 0;
else { else {
XPD_NOTICE(xpd, XPD_NOTICE(xpd,
"Unknown value '%s' (should be [1Yy]|[0Nn]). Ignored.\n", "Unknown value '%s' (should be [1Yy]|[0Nn]). Ignored\n",
buf); buf);
return -EINVAL; return -EINVAL;
} }
ret = set_localloop(xpd, ll); ret = set_localloop(xpd, ll);

View File

@ -26,55 +26,76 @@
/* Debugging Macros */ /* Debugging Macros */
#define PRINTK(level, category, fmt, ...) \ #define PRINTK(level, category, fmt, ...) \
printk(KERN_ ## level "%s%s-%s: " fmt, #level, category, THIS_MODULE->name, ## __VA_ARGS__) printk(KERN_ ## level "%s%s-%s: " fmt, \
#level, category, THIS_MODULE->name, ## __VA_ARGS__)
#define XBUS_PRINTK(level, category, xbus, fmt, ...) \ #define XBUS_PRINTK(level, category, xbus, fmt, ...) \
printk(KERN_ ## level "%s%s-%s: %s: " fmt, #level, \ printk(KERN_ ## level "%s%s-%s: %s: " fmt, #level, \
category, THIS_MODULE->name, (xbus)->busname, ## __VA_ARGS__) category, THIS_MODULE->name, (xbus)->busname, ## __VA_ARGS__)
#define XPD_PRINTK(level, category, xpd, fmt, ...) \ #define XPD_PRINTK(level, category, xpd, fmt, ...) \
printk(KERN_ ## level "%s%s-%s: %s/%s: " fmt, #level, \ printk(KERN_ ## level "%s%s-%s: %s/%s: " fmt, #level, \
category, THIS_MODULE->name, (xpd)->xbus->busname, (xpd)->xpdname, ## __VA_ARGS__) category, THIS_MODULE->name, \
(xpd)->xbus->busname, (xpd)->xpdname, ## __VA_ARGS__)
#define LINE_PRINTK(level, category, xpd, pos, fmt, ...) \ #define LINE_PRINTK(level, category, xpd, pos, fmt, ...) \
printk(KERN_ ## level "%s%s-%s: %s/%s/%d: " fmt, #level, \ printk(KERN_ ## level "%s%s-%s: %s/%s/%d: " fmt, #level, \
category, THIS_MODULE->name, (xpd)->xbus->busname, (xpd)->xpdname, (pos), ## __VA_ARGS__) category, THIS_MODULE->name, \
(xpd)->xbus->busname, (xpd)->xpdname, (pos), ## __VA_ARGS__)
#define PORT_PRINTK(level, category, xbus, unit, port, fmt, ...) \ #define PORT_PRINTK(level, category, xbus, unit, port, fmt, ...) \
printk(KERN_ ## level "%s%s-%s: %s UNIT=%d PORT=%d: " fmt, #level, \ printk(KERN_ ## level "%s%s-%s: %s UNIT=%d PORT=%d: " fmt, #level, \
category, THIS_MODULE->name, (xbus)->busname, (unit), (port), ## __VA_ARGS__) category, THIS_MODULE->name, \
(xbus)->busname, (unit), (port), ## __VA_ARGS__)
#define DBG(bits, fmt, ...) \ #define DBG(bits, fmt, ...) \
((void)((debug & (DBG_ ## bits)) && PRINTK(DEBUG, "-" #bits, "%s: " fmt, __func__, ## __VA_ARGS__))) ((void)((debug & (DBG_ ## bits)) && \
PRINTK(DEBUG, "-" #bits, "%s: " fmt, \
__func__, ## __VA_ARGS__)))
#define INFO(fmt, ...) PRINTK(INFO, "", fmt, ## __VA_ARGS__) #define INFO(fmt, ...) PRINTK(INFO, "", fmt, ## __VA_ARGS__)
#define NOTICE(fmt, ...) PRINTK(NOTICE, "", fmt, ## __VA_ARGS__) #define NOTICE(fmt, ...) PRINTK(NOTICE, "", fmt, ## __VA_ARGS__)
#define WARNING(fmt, ...) PRINTK(WARNING, "", fmt, ## __VA_ARGS__) #define WARNING(fmt, ...) PRINTK(WARNING, "", fmt, ## __VA_ARGS__)
#define ERR(fmt, ...) PRINTK(ERR, "", fmt, ## __VA_ARGS__) #define ERR(fmt, ...) PRINTK(ERR, "", fmt, ## __VA_ARGS__)
#define XBUS_DBG(bits, xbus, fmt, ...) \ #define XBUS_DBG(bits, xbus, fmt, ...) \
((void)((debug & (DBG_ ## bits)) && XBUS_PRINTK(DEBUG, "-" #bits, xbus, "%s: " fmt, __func__, ## __VA_ARGS__))) ((void)((debug & (DBG_ ## bits)) && XBUS_PRINTK(DEBUG, "-" #bits, \
#define XBUS_INFO(xbus, fmt, ...) XBUS_PRINTK(INFO, "", xbus, fmt, ## __VA_ARGS__) xbus, "%s: " fmt, __func__, ## __VA_ARGS__)))
#define XBUS_NOTICE(xbus, fmt, ...) XBUS_PRINTK(NOTICE, "", xbus, fmt, ## __VA_ARGS__) #define XBUS_INFO(xbus, fmt, ...) \
#define XBUS_ERR(xbus, fmt, ...) XBUS_PRINTK(ERR, "", xbus, fmt, ## __VA_ARGS__) XBUS_PRINTK(INFO, "", xbus, fmt, ## __VA_ARGS__)
#define XBUS_NOTICE(xbus, fmt, ...) \
XBUS_PRINTK(NOTICE, "", xbus, fmt, ## __VA_ARGS__)
#define XBUS_ERR(xbus, fmt, ...) \
XBUS_PRINTK(ERR, "", xbus, fmt, ## __VA_ARGS__)
#define XPD_DBG(bits, xpd, fmt, ...) \ #define XPD_DBG(bits, xpd, fmt, ...) \
((void)((debug & (DBG_ ## bits)) && XPD_PRINTK(DEBUG, "-" #bits, xpd, "%s: " fmt, __func__, ## __VA_ARGS__))) ((void)((debug & (DBG_ ## bits)) && XPD_PRINTK(DEBUG, "-" #bits, \
#define XPD_INFO(xpd, fmt, ...) XPD_PRINTK(INFO, "", xpd, fmt, ## __VA_ARGS__) xpd, "%s: " fmt, __func__, ## __VA_ARGS__)))
#define XPD_NOTICE(xpd, fmt, ...) XPD_PRINTK(NOTICE, "", xpd, fmt, ## __VA_ARGS__) #define XPD_INFO(xpd, fmt, ...) \
#define XPD_WARNING(xpd, fmt, ...) XPD_PRINTK(WARNING, "", xpd, fmt, ## __VA_ARGS__) XPD_PRINTK(INFO, "", xpd, fmt, ## __VA_ARGS__)
#define XPD_ERR(xpd, fmt, ...) XPD_PRINTK(ERR, "", xpd, fmt, ## __VA_ARGS__) #define XPD_NOTICE(xpd, fmt, ...) \
XPD_PRINTK(NOTICE, "", xpd, fmt, ## __VA_ARGS__)
#define XPD_WARNING(xpd, fmt, ...) \
XPD_PRINTK(WARNING, "", xpd, fmt, ## __VA_ARGS__)
#define XPD_ERR(xpd, fmt, ...) \
XPD_PRINTK(ERR, "", xpd, fmt, ## __VA_ARGS__)
#define LINE_DBG(bits, xpd, pos, fmt, ...) \ #define LINE_DBG(bits, xpd, pos, fmt, ...) \
((void)((debug & (DBG_ ## bits)) && LINE_PRINTK(DEBUG, "-" #bits, xpd, pos, "%s: " fmt, __func__, ## __VA_ARGS__))) ((void)((debug & (DBG_ ## bits)) && LINE_PRINTK(DEBUG, "-" #bits, \
#define LINE_NOTICE(xpd, pos, fmt, ...) LINE_PRINTK(NOTICE, "", xpd, pos, fmt, ## __VA_ARGS__) xpd, pos, "%s: " fmt, __func__, ## __VA_ARGS__)))
#define LINE_ERR(xpd, pos, fmt, ...) LINE_PRINTK(ERR, "", xpd, pos, fmt, ## __VA_ARGS__) #define LINE_NOTICE(xpd, pos, fmt, ...) \
LINE_PRINTK(NOTICE, "", xpd, pos, fmt, ## __VA_ARGS__)
#define LINE_ERR(xpd, pos, fmt, ...) \
LINE_PRINTK(ERR, "", xpd, pos, fmt, ## __VA_ARGS__)
#define PORT_DBG(bits, xbus, unit, port, fmt, ...) \ #define PORT_DBG(bits, xbus, unit, port, fmt, ...) \
((void)((debug & (DBG_ ## bits)) && PORT_PRINTK(DEBUG, "-" #bits, \ ((void)((debug & (DBG_ ## bits)) && \
xbus, unit, port, "%s: " fmt, __func__, ## __VA_ARGS__))) PORT_PRINTK(DEBUG, "-" #bits, \
#define PORT_NOTICE(xbus, unit, port, fmt, ...) PORT_PRINTK(NOTICE, "", xbus, unit, port, fmt, ## __VA_ARGS__) xbus, unit, port, "%s: " fmt, __func__, ## __VA_ARGS__)))
#define PORT_ERR(xbus, unit, port, fmt, ...) PORT_PRINTK(ERR, "", xbus, unit, port, fmt, ## __VA_ARGS__) #define PORT_NOTICE(xbus, unit, port, fmt, ...) \
PORT_PRINTK(NOTICE, "", xbus, unit, port, fmt, ## __VA_ARGS__)
#define PORT_ERR(xbus, unit, port, fmt, ...) \
PORT_PRINTK(ERR, "", xbus, unit, port, fmt, ## __VA_ARGS__)
/* /*
* Bits for debug * Bits for debug

View File

@ -51,9 +51,15 @@ static int rx_intr_counter;
#define END_OF_FRAME 0x0001 #define END_OF_FRAME 0x0001
#define GET_LEN 0x0002 #define GET_LEN 0x0002
#define START_RD_BURST 0x0008 #define START_RD_BURST 0x0008
#define AS_BF_MODE 0x0010 //stand alone Astribank without USB (Asterisk BlackFin Mode) /* stand alone Astribank without USB (Asterisk BlackFin Mode) */
#define EC_BF_MODE 0x0020 //all data between Astribank and USB routed thru BF(EchoCanceler BlackFin Mode) #define AS_BF_MODE 0x0010
#define NO_BF_MODE 0x0040 //Astribank worke with USB only (no BlackFin Mode) /*
* all data between Astribank and USB routed
* thru BF(EchoCanceler BlackFin Mode)
*/
#define EC_BF_MODE 0x0020
/* Astribank worke with USB only (no BlackFin Mode) */
#define NO_BF_MODE 0x0040
#define SET_XA_DIR 0x0080 #define SET_XA_DIR 0x0080
#define GET_XPD_STS 0x0100 #define GET_XPD_STS 0x0100
#define GET_CHECKSUM 0x0200 #define GET_CHECKSUM 0x0200
@ -164,7 +170,10 @@ static irqreturn_t xpp_mmap_rx_irq(int irq, void *dev_id)
#endif #endif
if (rxcnt & 1) if (rxcnt & 1)
buf[rxcnt - 1] = inw(FPGA_BASE_ADDR); buf[rxcnt - 1] = inw(FPGA_BASE_ADDR);
/* Sanity check: length of first packet in frame should be no more than the frame length */ /*
* Sanity check: length of first packet in frame
* should be no more than the frame length
*/
if (((buf[0] | (buf[1] << 8)) & 0x3FF) > rxcnt) { if (((buf[0] | (buf[1] << 8)) & 0x3FF) > rxcnt) {
if (printk_ratelimit()) { if (printk_ratelimit()) {
ERR("Packet len=%d, frame len=%d\n", ERR("Packet len=%d, frame len=%d\n",
@ -263,7 +272,8 @@ static int xframe_send_common(xbus_t *xbus, xframe_t *xframe, bool pcm)
static int rate_limit; static int rate_limit;
if ((rate_limit++ % 1000) == 0) if ((rate_limit++ % 1000) == 0)
XBUS_ERR(xbus, XBUS_ERR(xbus,
"Dropped PCM xframe (pcm_in_pool_count=%d).\n", "Dropped PCM xframe "
"(pcm_in_pool_count=%d).\n",
pcm_in_pool_count); pcm_in_pool_count);
FREE_SEND_XFRAME(xbus, xframe); FREE_SEND_XFRAME(xbus, xframe);
pcm_dropped++; pcm_dropped++;
@ -273,7 +283,8 @@ static int xframe_send_common(xbus_t *xbus, xframe_t *xframe, bool pcm)
spin_unlock_irqrestore(&tx_ready_lock, flags); spin_unlock_irqrestore(&tx_ready_lock, flags);
if ((rate_limit++ % 1000) == 0) if ((rate_limit++ % 1000) == 0)
XBUS_ERR(xbus, XBUS_ERR(xbus,
"Dropped xframe. Cannot enqueue.\n"); "Dropped xframe. "
"Cannot enqueue.\n");
FREE_SEND_XFRAME(xbus, xframe); FREE_SEND_XFRAME(xbus, xframe);
return -E2BIG; return -E2BIG;
} }
@ -327,12 +338,12 @@ static int fill_proc_queue(char *p, struct xframe_queue *q)
{ {
int len; int len;
len = len = sprintf(p,
sprintf(p, "%-15s: counts %3d, %3d, %3d worst %3d, overflows %3d "
"%-15s: counts %3d, %3d, %3d worst %3d, overflows %3d worst_lag %02ld.%ld ms\n", "worst_lag %02ld.%ld ms\n",
q->name, q->steady_state_count, q->count, q->max_count, q->name, q->steady_state_count, q->count, q->max_count,
q->worst_count, q->overflows, q->worst_lag_usec / 1000, q->worst_count, q->overflows, q->worst_lag_usec / 1000,
q->worst_lag_usec % 1000); q->worst_lag_usec % 1000);
xframe_queue_clearstats(q); xframe_queue_clearstats(q);
return len; return len;
} }
@ -421,29 +432,38 @@ static struct mmap_device astribank_dev = {
static int __init xpp_mmap_load_fpga(u8 * data, size_t size) static int __init xpp_mmap_load_fpga(u8 * data, size_t size)
{ {
size_t i; size_t i;
bfin_write_PORTGIO_DIR(bfin_read_PORTGIO_DIR() | DATA | NCONFIG | DCLK); //set data, nconfig and dclk to port out /* set data, nconfig and dclk to port out */
bfin_write_PORTGIO_DIR(bfin_read_PORTGIO_DIR() | DATA | NCONFIG | DCLK);
bfin_write_PORTG_FER(bfin_read_PORTG_FER() & ~(DATA | NCONFIG | DCLK)); bfin_write_PORTG_FER(bfin_read_PORTG_FER() & ~(DATA | NCONFIG | DCLK));
bfin_write_PORTGIO_DIR(bfin_read_PORTGIO_DIR() & ~(CONF_DONE | NSTATUS)); //set conf_done and nstatus to port in /* set conf_done and nstatus to port in */
bfin_write_PORTGIO_INEN(bfin_read_PORTGIO_INEN() & bfin_write_PORTGIO_DIR(
~(DATA | NCONFIG | DCLK)); bfin_read_PORTGIO_DIR() & ~(CONF_DONE | NSTATUS));
bfin_write_PORTGIO_INEN(
bfin_read_PORTGIO_INEN() & ~(DATA | NCONFIG | DCLK));
bfin_write_PORTGIO_INEN(bfin_read_PORTGIO_INEN() | CONF_DONE | NSTATUS); bfin_write_PORTGIO_INEN(bfin_read_PORTGIO_INEN() | CONF_DONE | NSTATUS);
bfin_write_PORTGIO_CLEAR(NCONFIG); //reset fpga during configuration holds nCONFIG low /* reset fpga during configuration holds nCONFIG low */
udelay(40); //Tcfg ~40us delay bfin_write_PORTGIO_CLEAR(NCONFIG);
bfin_write_PORTGIO_SET(NCONFIG); //transition nCONFIG to high - reset end. udelay(40); /* Tcfg ~40us delay */
udelay(40); //Tcf2ck ~40us delay /* transition nCONFIG to high - reset end. */
bfin_write_PORTGIO_SET(NCONFIG);
udelay(40); /* Tcf2ck ~40us delay */
if (!(bfin_read_PORTGIO() & NSTATUS)) if (!(bfin_read_PORTGIO() & NSTATUS))
return -EIO; //report reset faill - Tcf2st1 pass return -EIO; /* report reset faill - Tcf2st1 pass */
#if 0 #if 0
if (!(bfin_read_PORTGIO() & CONF_DONE)) if (!(bfin_read_PORTGIO() & CONF_DONE))
return -EIO; return -EIO;
#endif #endif
bfin_write_PORTGIO_CLEAR(DCLK); bfin_write_PORTGIO_CLEAR(DCLK);
for (i = 0; i < size; i++) { // loop EP2OUT buffer data to FPGA for (i = 0; i < size; i++) { /* loop EP2OUT buffer data to FPGA */
int j; int j;
u8 __u8 = data[i]; u8 __u8 = data[i];
for (j = 0; j < 8; j++) //send the configuration data through the DATA0 pin one bit at a time. /*
* Send the configuration data through the DATA0 pin
* one bit at a time.
*/
for (j = 0; j < 8; j++)
{ {
if (__u8 &1) if (__u8 &1)
bfin_write_PORTGIO_SET(DATA); bfin_write_PORTGIO_SET(DATA);
@ -454,7 +474,7 @@ static int __init xpp_mmap_load_fpga(u8 * data, size_t size)
bfin_write_PORTGIO_CLEAR(DCLK); bfin_write_PORTGIO_CLEAR(DCLK);
} }
if (!(bfin_read_PORTGIO() & NSTATUS)) if (!(bfin_read_PORTGIO() & NSTATUS))
return -EIO; //check the nSTATUS return -EIO; /* check the nSTATUS */
} }
bfin_write_PORTGIO_CLEAR(DATA); bfin_write_PORTGIO_CLEAR(DATA);
udelay(1); udelay(1);
@ -466,22 +486,29 @@ static int __init xpp_mmap_load_fpga(u8 * data, size_t size)
* some pins that were used only during initialization * some pins that were used only during initialization
* to be used for debugging from now on. * to be used for debugging from now on.
*/ */
bfin_write_PORTGIO_DIR(bfin_read_PORTGIO_DIR() | DEBUG_GPIO1 | DEBUG_GPIO2); //set to port out /* set to port out */
bfin_write_PORTGIO_DIR(
bfin_read_PORTGIO_DIR() | DEBUG_GPIO1 | DEBUG_GPIO2);
bfin_write_PORTG_FER(bfin_read_PORTG_FER() & bfin_write_PORTG_FER(bfin_read_PORTG_FER() &
~(DEBUG_GPIO1 | DEBUG_GPIO2)); ~(DEBUG_GPIO1 | DEBUG_GPIO2));
bfin_write_PORTGIO_INEN(bfin_read_PORTGIO_INEN() & bfin_write_PORTGIO_INEN(bfin_read_PORTGIO_INEN() &
~(DEBUG_GPIO1 | DEBUG_GPIO2)); ~(DEBUG_GPIO1 | DEBUG_GPIO2));
#endif #endif
udelay(40); //tCD2UM - CONF_DONE high to user mode udelay(40); /* tCD2UM - CONF_DONE high to user mode */
return 0; return 0;
} }
static void __exit xpp_mmap_unload_fpga(void) static void __exit xpp_mmap_unload_fpga(void)
{ {
bfin_write_PORTGIO_CLEAR(NCONFIG); //reset fpga during configuration holds nCONFIG low /* reset fpga during configuration holds nCONFIG low */
udelay(40); //Tcfg ~40us delay bfin_write_PORTGIO_CLEAR(NCONFIG);
bfin_write_PORTGIO_DIR(bfin_read_PORTGIO_DIR() & ~(DATA | NCONFIG | DCLK)); //disable output pin udelay(40); /* Tcfg ~40us delay */
bfin_write_PORTGIO_INEN(bfin_read_PORTGIO_INEN() & ~(CONF_DONE | NSTATUS)); //disable input buffer /* disable output pin */
bfin_write_PORTGIO_DIR(
bfin_read_PORTGIO_DIR() & ~(DATA | NCONFIG | DCLK));
/* disable input buffer */
bfin_write_PORTGIO_INEN(
bfin_read_PORTGIO_INEN() & ~(CONF_DONE | NSTATUS));
INFO("FPGA Firmware unloaded\n"); INFO("FPGA Firmware unloaded\n");
} }

View File

@ -28,10 +28,10 @@ int main(int argc, char *argv[])
if (fxo_modes[i].ring_x) if (fxo_modes[i].ring_x)
snprintf(ring_x, BUFSIZ, "ring_x=%04X", snprintf(ring_x, BUFSIZ, "ring_x=%04X",
fxo_modes[i].ring_x); fxo_modes[i].ring_x);
printf printf("%-15s\treg16=%02X\treg26=%02X\treg30=%02X\t"
("%-15s\treg16=%02X\treg26=%02X\treg30=%02X\treg31=%02X\t%s\t%s\n", "reg31=%02X\t%s\t%s\n",
fxo_modes[i].name, reg16, reg26, reg30, reg31, ring_osc, fxo_modes[i].name, reg16, reg26, reg30, reg31,
ring_x); ring_osc, ring_x);
} }
return 0; return 0;
} }

View File

@ -52,8 +52,8 @@ static const char rcsid[] = "$Id$";
#ifdef PROTOCOL_DEBUG #ifdef PROTOCOL_DEBUG
#ifdef CONFIG_PROC_FS #ifdef CONFIG_PROC_FS
#define PROC_XBUS_COMMAND "command" #define PROC_XBUS_COMMAND "command"
static int proc_xbus_command_write(struct file *file, const char __user *buffer, static int proc_xbus_command_write(struct file *file,
unsigned long count, void *data); const char __user *buffer, unsigned long count, void *data);
#endif #endif
#endif #endif
@ -110,9 +110,10 @@ int xbus_check_unique(xbus_t *xbus)
xbus_old = xbus_byhwid(xbus->label); xbus_old = xbus_byhwid(xbus->label);
if (xbus_old && xbus_old != xbus) { if (xbus_old && xbus_old != xbus) {
XBUS_NOTICE(xbus_old, XBUS_NOTICE(xbus_old,
"Duplicate LABEL='%s'. Leave %s unused. refcount_xbus=%d\n", "Duplicate LABEL='%s'. Leave %s unused. "
xbus_old->label, xbus->busname, "refcount_xbus=%d\n",
refcount_xbus(xbus_old)); xbus_old->label, xbus->busname,
refcount_xbus(xbus_old));
return -EBUSY; return -EBUSY;
} }
} else { } else {
@ -255,7 +256,10 @@ xpacket_t *xframe_next_packet(xframe_t *frm, int len)
int newlen = XFRAME_LEN(frm); int newlen = XFRAME_LEN(frm);
newlen += len; newlen += len;
// DBG(GENERAL, "len=%d, newlen=%d, frm->frame_len=%d\n", len, newlen, XFRAME_LEN(frm)); #if 0
DBG(GENERAL, "len=%d, newlen=%d,
frm->frame_len=%d\n", len, newlen, XFRAME_LEN(frm));
#endif
if (newlen > XFRAME_DATASIZE) { if (newlen > XFRAME_DATASIZE) {
return NULL; return NULL;
} }
@ -304,8 +308,9 @@ void dump_xframe(const char msg[], const xbus_t *xbus, const xframe_t *xframe,
if (pos > frm_len) { if (pos > frm_len) {
if (printk_ratelimit()) { if (printk_ratelimit()) {
XBUS_NOTICE(xbus, XBUS_NOTICE(xbus,
"%s: packet overflow pos=%d frame_len=%d\n", "%s: packet overflow pos=%d "
msg, pos, frm_len); "frame_len=%d\n",
msg, pos, frm_len);
do_hexdump(msg, xframe->packets, frm_len); do_hexdump(msg, xframe->packets, frm_len);
} }
break; break;
@ -314,9 +319,9 @@ void dump_xframe(const char msg[], const xbus_t *xbus, const xframe_t *xframe,
if (XPACKET_LEN(pack) <= 0) { if (XPACKET_LEN(pack) <= 0) {
if (printk_ratelimit()) { if (printk_ratelimit()) {
XBUS_NOTICE(xbus, XBUS_NOTICE(xbus,
"%s: xframe -- bad packet_len=%d pos=%d frame_len=%d\n", "%s: xframe -- bad packet_len=%d "
msg, XPACKET_LEN(pack), pos, "pos=%d frame_len=%d\n",
frm_len); msg, XPACKET_LEN(pack), pos, frm_len);
do_hexdump(msg, xframe->packets, frm_len); do_hexdump(msg, xframe->packets, frm_len);
} }
break; break;
@ -325,8 +330,9 @@ void dump_xframe(const char msg[], const xbus_t *xbus, const xframe_t *xframe,
if (nextpos > frm_len) { if (nextpos > frm_len) {
if (printk_ratelimit()) { if (printk_ratelimit()) {
XBUS_NOTICE(xbus, XBUS_NOTICE(xbus,
"%s: packet overflow nextpos=%d frame_len=%d\n", "%s: packet overflow nextpos=%d "
msg, nextpos, frm_len); "frame_len=%d\n",
msg, nextpos, frm_len);
do_hexdump(msg, xframe->packets, frm_len); do_hexdump(msg, xframe->packets, frm_len);
} }
break; break;
@ -350,11 +356,12 @@ void dump_xframe(const char msg[], const xbus_t *xbus, const xframe_t *xframe,
? "(IS_PCM)" : ""); ? "(IS_PCM)" : "");
} }
XBUS_DBG(ANY, xbus, XBUS_DBG(ANY, xbus,
" %3d. DATALEN=%d pcm=%d slot=%d OP=0x%02X XPD-%d%d (pos=%d)\n", " %3d. DATALEN=%d pcm=%d slot=%d OP=0x%02X "
num, XPACKET_LEN(pack), XPACKET_IS_PCM(pack), "XPD-%d%d (pos=%d)\n",
XPACKET_PCMSLOT(pack), XPACKET_OP(pack), num, XPACKET_LEN(pack), XPACKET_IS_PCM(pack),
XPACKET_ADDR_UNIT(pack), XPACKET_PCMSLOT(pack), XPACKET_OP(pack),
XPACKET_ADDR_SUBUNIT(pack), pos); XPACKET_ADDR_UNIT(pack),
XPACKET_ADDR_SUBUNIT(pack), pos);
dump_packet(" ", pack, debug); dump_packet(" ", pack, debug);
} }
num++; num++;
@ -406,7 +413,8 @@ static int really_send_cmd_frame(xbus_t *xbus, xframe_t *xframe)
BUG_ON(xframe->xframe_magic != XFRAME_MAGIC); BUG_ON(xframe->xframe_magic != XFRAME_MAGIC);
if (!XBUS_FLAGS(xbus, CONNECTED)) { if (!XBUS_FLAGS(xbus, CONNECTED)) {
XBUS_ERR(xbus, XBUS_ERR(xbus,
"Dropped command before sending -- hardware deactivated.\n"); "Dropped command before sending -- "
"hardware deactivated.\n");
dump_xframe("Dropped", xbus, xframe, DBG_ANY); dump_xframe("Dropped", xbus, xframe, DBG_ANY);
FREE_SEND_XFRAME(xbus, xframe); FREE_SEND_XFRAME(xbus, xframe);
return -ENODEV; return -ENODEV;
@ -489,7 +497,8 @@ int send_cmd_frame(xbus_t *xbus, xframe_t *xframe)
BUG_ON(xframe->xframe_magic != XFRAME_MAGIC); BUG_ON(xframe->xframe_magic != XFRAME_MAGIC);
if (!XBUS_FLAGS(xbus, CONNECTED)) { if (!XBUS_FLAGS(xbus, CONNECTED)) {
XBUS_ERR(xbus, XBUS_ERR(xbus,
"Dropped command before queueing -- hardware deactivated.\n"); "Dropped command before queueing -- "
"hardware deactivated.\n");
ret = -ENODEV; ret = -ENODEV;
goto err; goto err;
} }
@ -498,8 +507,8 @@ int send_cmd_frame(xbus_t *xbus, xframe_t *xframe)
if (!xframe_enqueue(&xbus->command_queue, xframe)) { if (!xframe_enqueue(&xbus->command_queue, xframe)) {
if ((rate_limit++ % 1003) == 0) { if ((rate_limit++ % 1003) == 0) {
XBUS_ERR(xbus, XBUS_ERR(xbus,
"Dropped command xframe. Cannot enqueue (%d)\n", "Dropped command xframe. Cannot enqueue (%d)\n",
rate_limit); rate_limit);
dump_xframe(__func__, xbus, xframe, DBG_ANY); dump_xframe(__func__, xbus, xframe, DBG_ANY);
} }
xbus_setstate(xbus, XBUS_STATE_FAIL); xbus_setstate(xbus, XBUS_STATE_FAIL);
@ -558,7 +567,8 @@ void xbus_receive_xframe(xbus_t *xbus, xframe_t *xframe)
if (likely(XBUS_FLAGS(xbus, CONNECTED))) if (likely(XBUS_FLAGS(xbus, CONNECTED)))
xframe_receive(xbus, xframe); xframe_receive(xbus, xframe);
else else
FREE_RECV_XFRAME(xbus, xframe); /* return to receive_pool */ /* return to receive_pool */
FREE_RECV_XFRAME(xbus, xframe);
} }
} }
@ -657,8 +667,9 @@ static int new_card(xbus_t *xbus, int unit, __u8 type, __u8 subtype,
proto_table = xproto_get(type); proto_table = xproto_get(type);
if (!proto_table) { if (!proto_table) {
XBUS_NOTICE(xbus, XBUS_NOTICE(xbus,
"CARD %d: missing protocol table for type %d. Ignored.\n", "CARD %d: missing protocol table for type %d. "
unit, type); "Ignored.\n",
unit, type);
return -EINVAL; return -EINVAL;
} }
echoops = proto_table->echoops; echoops = proto_table->echoops;
@ -666,8 +677,9 @@ static int new_card(xbus_t *xbus, int unit, __u8 type, __u8 subtype,
XBUS_INFO(xbus, "Detected ECHO Canceler (%d)\n", unit); XBUS_INFO(xbus, "Detected ECHO Canceler (%d)\n", unit);
if (ECHOOPS(xbus)) { if (ECHOOPS(xbus)) {
XBUS_NOTICE(xbus, XBUS_NOTICE(xbus,
"CARD %d: tryies to define echoops (type %d) but we already have one. Ignored.\n", "CARD %d: tryies to define echoops (type %d) "
unit, type); "but we already have one. Ignored.\n",
unit, type);
return -EINVAL; return -EINVAL;
} }
xbus->echo_state.echoops = echoops; xbus->echo_state.echoops = echoops;
@ -678,9 +690,10 @@ static int new_card(xbus_t *xbus, int unit, __u8 type, __u8 subtype,
(ports + proto_table->ports_per_subunit - (ports + proto_table->ports_per_subunit -
1) / proto_table->ports_per_subunit; 1) / proto_table->ports_per_subunit;
XBUS_DBG(DEVICES, xbus, XBUS_DBG(DEVICES, xbus,
"CARD %d type=%d.%d ports=%d (%dx%d), %d subunits, port-dir=0x%02X\n", "CARD %d type=%d.%d ports=%d (%dx%d), "
unit, type, subtype, ports, numchips, ports_per_chip, subunits, "%d subunits, port-dir=0x%02X\n",
port_dir); unit, type, subtype, ports, numchips, ports_per_chip, subunits,
port_dir);
if (type == XPD_TYPE_PRI || type == XPD_TYPE_BRI) if (type == XPD_TYPE_PRI || type == XPD_TYPE_BRI)
xbus->quirks.has_digital_span = 1; xbus->quirks.has_digital_span = 1;
if (type == XPD_TYPE_FXO) if (type == XPD_TYPE_FXO)
@ -694,8 +707,8 @@ static int new_card(xbus_t *xbus, int unit, __u8 type, __u8 subtype,
remaining_ports -= proto_table->ports_per_subunit; remaining_ports -= proto_table->ports_per_subunit;
if (subunit_ports <= 0) { if (subunit_ports <= 0) {
XBUS_NOTICE(xbus, XBUS_NOTICE(xbus,
"Subunit XPD=%d%d without ports (%d of %d)\n", "Subunit XPD=%d%d without ports (%d of %d)\n",
unit, i, subunit_ports, ports); unit, i, subunit_ports, ports);
ret = -ENODEV; ret = -ENODEV;
goto out; goto out;
} }
@ -782,7 +795,8 @@ static int xpd_initialize(xpd_t *xpd)
* Asterisk will tell us when/if it's needed. * Asterisk will tell us when/if it's needed.
*/ */
CALL_PHONE_METHOD(echocancel_setmask, xpd, 0); CALL_PHONE_METHOD(echocancel_setmask, xpd, 0);
CALL_PHONE_METHOD(card_state, xpd, 1); /* Turn on all channels */ /* Turn on all channels */
CALL_PHONE_METHOD(card_state, xpd, 1);
} }
if (!xpd_setstate(xpd, XPD_STATE_READY)) { if (!xpd_setstate(xpd, XPD_STATE_READY)) {
goto out; goto out;
@ -966,7 +980,8 @@ int xbus_register_dahdi_device(xbus_t *xbus)
* For our devices it was available for ages via: * For our devices it was available for ages via:
* - The legacy "/proc/xpp/XBUS-??/summary" (CONNECTOR=...) * - The legacy "/proc/xpp/XBUS-??/summary" (CONNECTOR=...)
* - The same info in "/proc/xpp/xbuses" * - The same info in "/proc/xpp/xbuses"
* - The modern "/sys/bus/astribanks/devices/xbus-??/connector" attribute * - The modern "/sys/bus/astribanks/devices/xbus-??/connector"
* attribute
* So let's also export it via the newfangled "location" field. * So let's also export it via the newfangled "location" field.
*/ */
xbus->ddev->location = xbus->connector; xbus->ddev->location = xbus->connector;
@ -1067,14 +1082,15 @@ void xbus_populate(void *data)
spin_unlock_irqrestore(&worker->worker_lock, flags); spin_unlock_irqrestore(&worker->worker_lock, flags);
if (xbus_initialize(xbus) < 0) { if (xbus_initialize(xbus) < 0) {
XBUS_NOTICE(xbus, XBUS_NOTICE(xbus,
"Initialization failed. Leave unused. refcount_xbus=%d\n", "Initialization failed. Leave unused. "
refcount_xbus(xbus)); "refcount_xbus=%d\n",
refcount_xbus(xbus));
goto failed; goto failed;
} }
if (!xbus_setstate(xbus, XBUS_STATE_READY)) { if (!xbus_setstate(xbus, XBUS_STATE_READY)) {
XBUS_NOTICE(xbus, XBUS_NOTICE(xbus,
"Illegal transition. Leave unused. refcount_xbus=%d\n", "Illegal transition. Leave unused. refcount_xbus=%d\n",
refcount_xbus(xbus)); refcount_xbus(xbus));
goto failed; goto failed;
} }
worker->xpds_init_done = 1; worker->xpds_init_done = 1;
@ -1321,7 +1337,8 @@ int xbus_activate(xbus_t *xbus)
xpp_drift_init(xbus); xpp_drift_init(xbus);
xbus_set_command_timer(xbus, 1); xbus_set_command_timer(xbus, 1);
xframe_queue_disable(&xbus->command_queue, 0); xframe_queue_disable(&xbus->command_queue, 0);
xbus_setstate(xbus, XBUS_STATE_IDLE); /* must be done after transport is valid */ /* must be done after transport is valid */
xbus_setstate(xbus, XBUS_STATE_IDLE);
CALL_PROTO(GLOBAL, AB_REQUEST, xbus, NULL); CALL_PROTO(GLOBAL, AB_REQUEST, xbus, NULL);
/* /*
* Make sure Astribank knows not to send us ticks. * Make sure Astribank knows not to send us ticks.
@ -1648,12 +1665,12 @@ static int xbus_fill_proc_queue(char *p, struct xframe_queue *q)
{ {
int len; int len;
len = len = sprintf(p,
sprintf(p, "%-15s: counts %3d, %3d, %3d worst %3d, overflows %3d "
"%-15s: counts %3d, %3d, %3d worst %3d, overflows %3d worst_lag %02ld.%ld ms\n", "worst_lag %02ld.%ld ms\n",
q->name, q->steady_state_count, q->count, q->max_count, q->name, q->steady_state_count, q->count, q->max_count,
q->worst_count, q->overflows, q->worst_lag_usec / 1000, q->worst_count, q->overflows, q->worst_lag_usec / 1000,
q->worst_lag_usec % 1000); q->worst_lag_usec % 1000);
xframe_queue_clearstats(q); xframe_queue_clearstats(q);
return len; return len;
} }
@ -1739,8 +1756,8 @@ out:
} }
#ifdef PROTOCOL_DEBUG #ifdef PROTOCOL_DEBUG
static int proc_xbus_command_write(struct file *file, const char __user *buffer, static int proc_xbus_command_write(struct file *file,
unsigned long count, void *data) const char __user *buffer, unsigned long count, void *data)
{ {
char *buf; char *buf;
xbus_t *xbus = data; xbus_t *xbus = data;
@ -1783,8 +1800,9 @@ static int proc_xbus_command_write(struct file *file, const char __user *buffer,
break; break;
if (!isxdigit(*p)) { if (!isxdigit(*p)) {
XBUS_ERR(xbus, XBUS_ERR(xbus,
"%s: bad hex value ASCII='0x%X' at position %ld\n", "%s: bad hex value ASCII='0x%X' "
__func__, *p, (long)(p - buf)); "at position %ld\n",
__func__, *p, (long)(p - buf));
count = -EINVAL; count = -EINVAL;
goto out; goto out;
} }

View File

@ -110,7 +110,8 @@ struct xbus_transport {
#define TRANSPORT_EXIST(xbus) ((xbus)->transport.ops != NULL) #define TRANSPORT_EXIST(xbus) ((xbus)->transport.ops != NULL)
#define XBUS_FLAG_CONNECTED 0 #define XBUS_FLAG_CONNECTED 0
#define XBUS_FLAGS(xbus, flg) test_bit(XBUS_FLAG_ ## flg, &((xbus)->transport.transport_flags)) #define XBUS_FLAGS(xbus, flg) \
test_bit(XBUS_FLAG_ ## flg, &((xbus)->transport.transport_flags))
struct xbus_ops *transportops_get(xbus_t *xbus); struct xbus_ops *transportops_get(xbus_t *xbus);
void transportops_put(xbus_t *xbus); void transportops_put(xbus_t *xbus);
@ -139,10 +140,14 @@ struct xbus_workqueue {
xframe_t *get_xframe(struct xframe_queue *q); xframe_t *get_xframe(struct xframe_queue *q);
void put_xframe(struct xframe_queue *q, xframe_t *xframe); void put_xframe(struct xframe_queue *q, xframe_t *xframe);
#define ALLOC_SEND_XFRAME(xbus) get_xframe(&(xbus)->send_pool) #define ALLOC_SEND_XFRAME(xbus) \
#define ALLOC_RECV_XFRAME(xbus) get_xframe(&(xbus)->receive_pool) get_xframe(&(xbus)->send_pool)
#define FREE_SEND_XFRAME(xbus, xframe) put_xframe(&(xbus)->send_pool, (xframe)) #define ALLOC_RECV_XFRAME(xbus) \
#define FREE_RECV_XFRAME(xbus, xframe) put_xframe(&(xbus)->receive_pool, (xframe)) get_xframe(&(xbus)->receive_pool)
#define FREE_SEND_XFRAME(xbus, xframe) \
put_xframe(&(xbus)->send_pool, (xframe))
#define FREE_RECV_XFRAME(xbus, xframe) \
put_xframe(&(xbus)->receive_pool, (xframe))
xbus_t *xbus_num(uint num); xbus_t *xbus_num(uint num);
xbus_t *get_xbus(const char *msg, uint num); xbus_t *get_xbus(const char *msg, uint num);

View File

@ -60,18 +60,25 @@ static struct xpp_ticker dahdi_ticker;
static struct xpp_ticker *ref_ticker; static struct xpp_ticker *ref_ticker;
static DEFINE_SPINLOCK(ref_ticker_lock); static DEFINE_SPINLOCK(ref_ticker_lock);
static DEFINE_SPINLOCK(elect_syncer_lock); static DEFINE_SPINLOCK(elect_syncer_lock);
static bool force_dahdi_sync; /* from /sys/bus/astribanks/drivers/xppdrv/sync */ /* from /sys/bus/astribanks/drivers/xppdrv/sync */
static bool force_dahdi_sync;
static xbus_t *global_ticker; static xbus_t *global_ticker;
static struct xpp_ticker global_ticks_series; static struct xpp_ticker global_ticks_series;
#define PROC_SYNC "sync" #define PROC_SYNC "sync"
#define SYNC_CYCLE 500 /* Sampling cycle in usec */ /* Sampling cycle in usec */
#define SYNC_CYCLE_SAMPLE 100 /* Samples from end of SYNC_CYCLE */ #define SYNC_CYCLE 500
#define SYNC_CONVERGE 10 /* Number of SYNC_CYCLE's to converge speed */ /* Samples from end of SYNC_CYCLE */
#define SYNC_CENTER 500 /* Offset from ref_ticker to other AB's */ #define SYNC_CYCLE_SAMPLE 100
#define SYNC_DELTA 40 /* If within +/-SYNC_DELTA, try to stay there */ /* Number of SYNC_CYCLE's to converge speed */
#define SYNC_CONVERGE 10
/* Offset from ref_ticker to other AB's */
#define SYNC_CENTER 500
/* If within +/-SYNC_DELTA, try to stay there */
#define SYNC_DELTA 40
#define BIG_TICK_INTERVAL 1000 #define BIG_TICK_INTERVAL 1000
#define SYNC_ADJ_MAX 20 /* maximal firmware drift unit (hardware limit 63) */ /* maximal firmware drift unit (hardware limit 63) */
#define SYNC_ADJ_MAX 20
/* /*
* The USB bulk endpoints have a large jitter in the timing of frames * The USB bulk endpoints have a large jitter in the timing of frames
@ -120,7 +127,8 @@ static int xpp_ticker_step(struct xpp_ticker *ticker, const struct timeval *t)
spin_lock_irqsave(&ticker->lock, flags); spin_lock_irqsave(&ticker->lock, flags);
ticker->last_sample.tv = *t; ticker->last_sample.tv = *t;
if ((ticker->count % ticker->cycle) == ticker->cycle - 1) { /* rate adjust */ /* rate adjust */
if ((ticker->count % ticker->cycle) == ticker->cycle - 1) {
usec = usec =
(long)usec_diff(&ticker->last_sample.tv, (long)usec_diff(&ticker->last_sample.tv,
&ticker->first_sample.tv); &ticker->first_sample.tv);
@ -277,12 +285,13 @@ static void xpp_drift_step(xbus_t *xbus, const struct timeval *tv)
di->offset_min = offset; di->offset_min = offset;
XBUS_DBG(SYNC, xbus, XBUS_DBG(SYNC, xbus,
"offset: %d, min_speed=%d, max_speed=%d, usec_delta(last)=%ld\n", "offset: %d, min_speed=%d, "
offset_prev, di->min_speed, "max_speed=%d, usec_delta(last)=%ld\n",
di->max_speed, usec_delta); offset_prev, di->min_speed,
di->max_speed, usec_delta);
XBUS_DBG(SYNC, xbus, XBUS_DBG(SYNC, xbus,
"ADJ: speed=%d (best_speed=%d) fix=%d\n", "ADJ: speed=%d (best_speed=%d) fix=%d\n",
speed, best_speed, fix); speed, best_speed, fix);
xbus->sync_adjustment_offset = speed; xbus->sync_adjustment_offset = speed;
if (xbus != syncer if (xbus != syncer
&& xbus->sync_adjustment != speed) && xbus->sync_adjustment != speed)
@ -354,8 +363,8 @@ static void xbus_command_timer(unsigned long param)
BUG_ON(!xbus); BUG_ON(!xbus);
do_gettimeofday(&now); do_gettimeofday(&now);
xbus_command_queue_tick(xbus); xbus_command_queue_tick(xbus);
if (!xbus->self_ticking) if (!xbus->self_ticking) /* Must be 1KHz rate */
mod_timer(&xbus->command_timer, jiffies + 1); /* Must be 1KHz rate */ mod_timer(&xbus->command_timer, jiffies + 1);
} }
void xbus_set_command_timer(xbus_t *xbus, bool on) void xbus_set_command_timer(xbus_t *xbus, bool on)
@ -531,7 +540,8 @@ void dahdi_sync_tick(struct dahdi_span *span, int is_master)
if ((rate_limit++ % 10003) == 0) if ((rate_limit++ % 10003) == 0)
XPD_NOTICE(xpd, XPD_NOTICE(xpd,
"Is a DAHDI sync master: ignore sync from DAHDI\n"); "Is a DAHDI sync master: "
"ignore sync from DAHDI\n");
goto noop; goto noop;
} }
/* Now we know for sure someone else is dahdi sync master */ /* Now we know for sure someone else is dahdi sync master */
@ -767,9 +777,11 @@ static void do_ec(xpd_t *xpd)
for (i = 0; i < PHONEDEV(xpd).span.channels; i++) { for (i = 0; i < PHONEDEV(xpd).span.channels; i++) {
struct dahdi_chan *chan = XPD_CHAN(xpd, i); struct dahdi_chan *chan = XPD_CHAN(xpd, i);
if (unlikely(IS_SET(PHONEDEV(xpd).digital_signalling, i))) /* Don't echo cancel BRI D-chans */ /* Don't echo cancel BRI D-chans */
if (unlikely(IS_SET(PHONEDEV(xpd).digital_signalling, i)))
continue; continue;
if (!IS_SET(PHONEDEV(xpd).wanted_pcm_mask, i)) /* No ec for unwanted PCM */ /* No ec for unwanted PCM */
if (!IS_SET(PHONEDEV(xpd).wanted_pcm_mask, i))
continue; continue;
dahdi_ec_chunk(chan, chan->readchunk, dahdi_ec_chunk(chan, chan->readchunk,
PHONEDEV(xpd).ec_chunk2[i]); PHONEDEV(xpd).ec_chunk2[i]);
@ -826,7 +838,8 @@ static bool pcm_valid(xpd_t *xpd, xpacket_t *pack)
XPD_COUNTER(xpd, RECV_ERRORS)++; XPD_COUNTER(xpd, RECV_ERRORS)++;
if ((rate_limit++ % 1000) <= 10) { if ((rate_limit++ % 1000) <= 10) {
XPD_ERR(xpd, XPD_ERR(xpd,
"BAD PCM REPLY: packet_len=%d (should be %d), count=%d\n", "BAD PCM REPLY: packet_len=%d "
"(should be %d), count=%d\n",
XPACKET_LEN(pack), good_len, count); XPACKET_LEN(pack), good_len, count);
dump_packet("BAD PCM REPLY", pack, 1); dump_packet("BAD PCM REPLY", pack, 1);
} }
@ -856,8 +869,9 @@ static inline void pcm_frame_out(xbus_t *xbus, xframe_t *xframe)
if ((rate_limit++ % 5003) == 0) if ((rate_limit++ % 5003) == 0)
XBUS_DBG(SYNC, xbus, XBUS_DBG(SYNC, xbus,
"Bad PCM TX timing(%d): usec=%ld.\n", "Bad PCM TX timing(%d): "
rate_limit, usec); "usec=%ld.\n",
rate_limit, usec);
} }
if (usec > xbus->max_tx_sync) if (usec > xbus->max_tx_sync)
xbus->max_tx_sync = usec; xbus->max_tx_sync = usec;
@ -952,8 +966,9 @@ void generic_card_pcm_tospan(xpd_t *xpd, xpacket_t *pack)
memset((u_char *)r, 0x7F, DAHDI_CHUNKSIZE); memset((u_char *)r, 0x7F, DAHDI_CHUNKSIZE);
if (IS_SET(PHONEDEV(xpd).silence_pcm, i)) { if (IS_SET(PHONEDEV(xpd).silence_pcm, i)) {
/* /*
* This will clear the EC buffers until next tick * This will clear the EC buffers until next
* So we don't have noise residues from the past. * tick so we don't have noise residues
* from the past.
*/ */
memset(PHONEDEV(xpd).ec_chunk2[i], 0x7F, memset(PHONEDEV(xpd).ec_chunk2[i], 0x7F,
DAHDI_CHUNKSIZE); DAHDI_CHUNKSIZE);
@ -1022,8 +1037,9 @@ static int copy_pcm_tospan(xbus_t *xbus, xframe_t *xframe)
if ((rate_limit++ % 1003) == 0) { if ((rate_limit++ % 1003) == 0) {
XBUS_NOTICE(xbus, XBUS_NOTICE(xbus,
"%s: Non-PCM packet within a PCM xframe. (%d)\n", "%s: Non-PCM packet within "
__func__, rate_limit); "a PCM xframe. (%d)\n",
__func__, rate_limit);
dump_xframe("In PCM xframe", xbus, xframe, dump_xframe("In PCM xframe", xbus, xframe,
debug); debug);
} }
@ -1035,8 +1051,8 @@ static int copy_pcm_tospan(xbus_t *xbus, xframe_t *xframe)
if ((rate_limit++ % 1003) == 0) { if ((rate_limit++ % 1003) == 0) {
XBUS_NOTICE(xbus, XBUS_NOTICE(xbus,
"%s: Invalid packet length %d. (%d)\n", "%s: Invalid packet length %d. (%d)\n",
__func__, len, rate_limit); __func__, len, rate_limit);
dump_xframe("BAD LENGTH", xbus, xframe, debug); dump_xframe("BAD LENGTH", xbus, xframe, debug);
} }
goto out; goto out;
@ -1102,8 +1118,8 @@ static void xbus_tick(xbus_t *xbus)
} }
#endif #endif
/* /*
* calls to dahdi_transmit should be out of spinlocks, as it may call back * calls to dahdi_transmit should be out of spinlocks,
* our hook setting methods. * as it may call back our hook setting methods.
*/ */
dahdi_transmit(&PHONEDEV(xpd).span); dahdi_transmit(&PHONEDEV(xpd).span);
} }
@ -1121,7 +1137,10 @@ static void xbus_tick(xbus_t *xbus)
if (pcm_len && xpd->card_present) { if (pcm_len && xpd->card_present) {
do { do {
// pack = NULL; /* FORCE single packet frames */ #if 0
/* FORCE single packet frames */
pack = NULL;
#endif
if (xframe && !pack) { /* FULL frame */ if (xframe && !pack) { /* FULL frame */
pcm_frame_out(xbus, xframe); pcm_frame_out(xbus, xframe);
xframe = NULL; xframe = NULL;
@ -1134,11 +1153,10 @@ static void xbus_tick(xbus_t *xbus)
if (!xframe) { if (!xframe) {
static int rate_limit; static int rate_limit;
if ((rate_limit++ % if ((rate_limit++ % 3001) == 0)
3001) == 0)
XBUS_ERR(xbus, XBUS_ERR(xbus,
"%s: failed to allocate new xframe\n", "%s: failed to allocate new xframe\n",
__func__); __func__);
return; return;
} }
} }
@ -1180,8 +1198,10 @@ static void xbus_tick(xbus_t *xbus)
if ((rate_limit++ % 5003) == 0) if ((rate_limit++ % 5003) == 0)
XBUS_DBG(SYNC, xbus, XBUS_DBG(SYNC, xbus,
"Bad PCM RX timing(%d): usec=%ld.\n", "Bad PCM RX "
rate_limit, usec); "timing(%d): "
"usec=%ld.\n",
rate_limit, usec);
} }
if (usec > xbus->max_rx_sync) if (usec > xbus->max_rx_sync)
xbus->max_rx_sync = usec; xbus->max_rx_sync = usec;
@ -1199,7 +1219,8 @@ static void xbus_tick(xbus_t *xbus)
do_ec(xpd); do_ec(xpd);
dahdi_receive(&PHONEDEV(xpd).span); dahdi_receive(&PHONEDEV(xpd).span);
} }
PHONEDEV(xpd).silence_pcm = 0; /* silence was injected */ /* silence was injected */
PHONEDEV(xpd).silence_pcm = 0;
} }
xpd->timer_count = xbus->global_counter; xpd->timer_count = xbus->global_counter;
/* /*

View File

@ -245,7 +245,9 @@ static DEVICE_ATTR_READER(driftinfo_show, dev, buf)
seconds = seconds % 60; seconds = seconds % 60;
hours = minutes / 60; hours = minutes / 60;
minutes = minutes % 60; minutes = minutes % 60;
#define SHOW(ptr,item) len += snprintf(buf + len, PAGE_SIZE - len, "%-15s: %8d\n", #item, (ptr)->item) #define SHOW(ptr,item) \
len += snprintf(buf + len, PAGE_SIZE - len, \
"%-15s: %8d\n", #item, (ptr)->item)
len += len +=
snprintf(buf + len, PAGE_SIZE - len, snprintf(buf + len, PAGE_SIZE - len,
"%-15s: %8d (was %d:%02d:%02d ago)\n", "lost_ticks", "%-15s: %8d (was %d:%02d:%02d ago)\n", "lost_ticks",
@ -518,9 +520,8 @@ static DEVICE_ATTR_READER(chipregs_show, dev, buf)
return -ENODEV; return -ENODEV;
spin_lock_irqsave(&xpd->lock, flags); spin_lock_irqsave(&xpd->lock, flags);
regs = &xpd->last_reply; regs = &xpd->last_reply;
len += len += sprintf(buf + len,
sprintf(buf + len, "# Writing bad data to this file may damage your hardware!\n");
"# Writing bad data into this file may damage your hardware!\n");
len += sprintf(buf + len, "# Consult firmware docs first\n"); len += sprintf(buf + len, "# Consult firmware docs first\n");
len += sprintf(buf + len, "#\n"); len += sprintf(buf + len, "#\n");
do_datah = REG_FIELD(regs, do_datah) ? 1 : 0; do_datah = REG_FIELD(regs, do_datah) ? 1 : 0;
@ -758,7 +759,8 @@ static int xpd_match(struct device *dev, struct device_driver *driver)
xpd = dev_to_xpd(dev); xpd = dev_to_xpd(dev);
if (xpd_driver->type != xpd->type) { if (xpd_driver->type != xpd->type) {
XPD_DBG(DEVICES, xpd, XPD_DBG(DEVICES, xpd,
"SYSFS match fail: xpd->type = %d, xpd_driver->type = %d\n", "SYSFS match fail: xpd->type = %d, "
"xpd_driver->type = %d\n",
xpd->type, xpd_driver->type); xpd->type, xpd_driver->type);
return 0; return 0;
} }
@ -911,7 +913,8 @@ static DEVICE_ATTR_WRITER(echocancel_store, dev, buf, count)
} }
if (mask != 0 && __ffs(mask) > channels) { if (mask != 0 && __ffs(mask) > channels) {
XPD_ERR(xpd, XPD_ERR(xpd,
"Channel mask (0x%lX) larger than available channels (%d)\n", "Channel mask (0x%lX) larger than "
"available channels (%d)\n",
mask, channels); mask, channels);
return -EINVAL; return -EINVAL;
} }

View File

@ -64,7 +64,7 @@ struct list_head {
#define IS_SET(x, i) (((x) & BIT(i)) != 0) #define IS_SET(x, i) (((x) & BIT(i)) != 0)
#define BITMASK(i) (((u64)1 << (i)) - 1) #define BITMASK(i) (((u64)1 << (i)) - 1)
#define MAX_PROC_WRITE 100 /* Largest buffer we allow writing our /proc files */ #define MAX_PROC_WRITE 100 /* Longest write allowed to our /proc files */
#define CHANNELS_PERXPD 32 /* Depends on xpp_line_t and protocol fields */ #define CHANNELS_PERXPD 32 /* Depends on xpp_line_t and protocol fields */
#define MAX_SPANNAME 20 /* From dahdi/kernel.h */ #define MAX_SPANNAME 20 /* From dahdi/kernel.h */
@ -80,7 +80,8 @@ struct list_head {
#define UNIT_BITS 3 /* Bit for Astribank unit number */ #define UNIT_BITS 3 /* Bit for Astribank unit number */
#define SUBUNIT_BITS 3 /* Bit for Astribank subunit number */ #define SUBUNIT_BITS 3 /* Bit for Astribank subunit number */
#define MAX_UNIT (1 << UNIT_BITS) /* 1 FXS + 3 FXS/FXO | 1 BRI + 3 FXS/FXO */ /* 1 FXS + 3 FXS/FXO | 1 BRI + 3 FXS/FXO */
#define MAX_UNIT (1 << UNIT_BITS)
#define MAX_SUBUNIT (1 << SUBUNIT_BITS) /* 8 port BRI */ #define MAX_SUBUNIT (1 << SUBUNIT_BITS) /* 8 port BRI */
/* /*
@ -112,10 +113,11 @@ typedef unsigned char byte;
#endif #endif
#define KZALLOC(size, gfp) my_kzalloc(size, gfp) #define KZALLOC(size, gfp) my_kzalloc(size, gfp)
#define KZFREE(p) do { \ #define KZFREE(p) \
memset((p), 0, sizeof(*(p))); \ do { \
kfree(p); \ memset((p), 0, sizeof(*(p))); \
} while (0); kfree(p); \
} while (0);
/* /*
* Hotplug replaced with uevent in 2.6.16 * Hotplug replaced with uevent in 2.6.16
@ -128,23 +130,29 @@ typedef unsigned char byte;
#endif #endif
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 14) #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 14)
#define DEVICE_ATTR_READER(name, dev, buf) \ #define DEVICE_ATTR_READER(name, dev, buf) \
ssize_t name(struct device *dev, struct device_attribute *attr, char *buf) ssize_t name(struct device *dev, \
#define DEVICE_ATTR_WRITER(name, dev, buf, count) \ struct device_attribute *attr, char *buf)
ssize_t name(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) #define DEVICE_ATTR_WRITER(name, dev, buf, count) \
ssize_t name(struct device *dev, \
struct device_attribute *attr, \
const char *buf, size_t count)
#else #else
#define DEVICE_ATTR_READER(name, dev, buf) \ #define DEVICE_ATTR_READER(name, dev, buf) \
ssize_t name(struct device *dev, char *buf) ssize_t name(struct device *dev, char *buf)
#define DEVICE_ATTR_WRITER(name, dev, buf, count) \ #define DEVICE_ATTR_WRITER(name, dev, buf, count) \
ssize_t name(struct device *dev, const char *buf, size_t count) ssize_t name(struct device *dev, const char *buf, size_t count)
#endif #endif
#define DRIVER_ATTR_READER(name, drv, buf) \ #define DRIVER_ATTR_READER(name, drv, buf) \
ssize_t name(struct device_driver *drv, char * buf) ssize_t name(struct device_driver *drv, char * buf)
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 30) #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 30)
#define SET_PROC_DIRENTRY_OWNER(p) do { (p)->owner = THIS_MODULE; } while (0); #define SET_PROC_DIRENTRY_OWNER(p) \
do { \
(p)->owner = THIS_MODULE; \
} while (0);
#else #else
#define SET_PROC_DIRENTRY_OWNER(p) do { } while (0); #define SET_PROC_DIRENTRY_OWNER(p) do { } while (0);
#endif #endif
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 19) #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 19)

View File

@ -7,8 +7,9 @@ extern int debug;
static xframe_t *transport_alloc_xframe(xbus_t *xbus, gfp_t gfp_flags); static xframe_t *transport_alloc_xframe(xbus_t *xbus, gfp_t gfp_flags);
static void transport_free_xframe(xbus_t *xbus, xframe_t *xframe); static void transport_free_xframe(xbus_t *xbus, xframe_t *xframe);
void xframe_queue_init(struct xframe_queue *q, unsigned int steady_state_count, void xframe_queue_init(struct xframe_queue *q,
unsigned int max_count, const char *name, void *priv) unsigned int steady_state_count, unsigned int max_count,
const char *name, void *priv)
{ {
memset(q, 0, sizeof(*q)); memset(q, 0, sizeof(*q));
spin_lock_init(&q->lock); spin_lock_init(&q->lock);
@ -57,8 +58,9 @@ static bool __xframe_enqueue(struct xframe_queue *q, xframe_t *xframe)
if (q->count >= q->max_count) { if (q->count >= q->max_count) {
q->overflows++; q->overflows++;
if ((overflow_cnt++ % 1000) < 5) { if ((overflow_cnt++ % 1000) < 5) {
NOTICE NOTICE("Overflow of %-15s: counts %3d, %3d, %3d "
("Overflow of %-15s: counts %3d, %3d, %3d worst %3d, overflows %3d worst_lag %02ld.%ld ms\n", "worst %3d, overflows %3d "
"worst_lag %02ld.%ld ms\n",
q->name, q->steady_state_count, q->count, q->name, q->steady_state_count, q->count,
q->max_count, q->worst_count, q->overflows, q->max_count, q->worst_count, q->overflows,
q->worst_lag_usec / 1000, q->worst_lag_usec / 1000,
@ -163,15 +165,18 @@ static xframe_t *transport_alloc_xframe(xbus_t *xbus, gfp_t gfp_flags)
return NULL; return NULL;
} }
spin_lock_irqsave(&xbus->transport.lock, flags); spin_lock_irqsave(&xbus->transport.lock, flags);
//XBUS_INFO(xbus, "%s (transport_refcount=%d)\n", __func__, atomic_read(&xbus->transport.transport_refcount)); #if 0
XBUS_INFO(xbus, "%s (transport_refcount=%d)\n",
__func__, atomic_read(&xbus->transport.transport_refcount));
#endif
xframe = ops->alloc_xframe(xbus, gfp_flags); xframe = ops->alloc_xframe(xbus, gfp_flags);
if (!xframe) { if (!xframe) {
static int rate_limit; static int rate_limit;
if ((rate_limit++ % 3001) == 0) if ((rate_limit++ % 3001) == 0)
XBUS_ERR(xbus, XBUS_ERR(xbus,
"Failed xframe allocation from transport (%d)\n", "Failed xframe allocation from transport (%d)\n",
rate_limit); rate_limit);
transportops_put(xbus); transportops_put(xbus);
/* fall through */ /* fall through */
} }
@ -188,7 +193,10 @@ static void transport_free_xframe(xbus_t *xbus, xframe_t *xframe)
ops = xbus->transport.ops; ops = xbus->transport.ops;
BUG_ON(!ops); BUG_ON(!ops);
spin_lock_irqsave(&xbus->transport.lock, flags); spin_lock_irqsave(&xbus->transport.lock, flags);
//XBUS_INFO(xbus, "%s (transport_refcount=%d)\n", __func__, atomic_read(&xbus->transport.transport_refcount)); #if 0
XBUS_INFO(xbus, "%s (transport_refcount=%d)\n",
__func__, atomic_read(&xbus->transport.transport_refcount));
#endif
ops->free_xframe(xbus, xframe); ops->free_xframe(xbus, xframe);
transportops_put(xbus); transportops_put(xbus);
spin_unlock_irqrestore(&xbus->transport.lock, flags); spin_unlock_irqrestore(&xbus->transport.lock, flags);

View File

@ -54,14 +54,14 @@ typedef unsigned gfp_t; /* Added in 2.6.14 */
* bool is now defined as a proper boolean type (gcc _Bool) * bool is now defined as a proper boolean type (gcc _Bool)
* but the command line parsing framework handles it as int. * but the command line parsing framework handles it as int.
*/ */
#define DEF_PARM_BOOL(name, init, perm, desc) \ #define DEF_PARM_BOOL(name, init, perm, desc) \
int name = init; \ int name = init; \
module_param(name, bool, perm); \ module_param(name, bool, perm); \
MODULE_PARM_DESC(name, desc " [default " #init "]") MODULE_PARM_DESC(name, desc " [default " #init "]")
#define DEF_PARM(type, name, init, perm, desc) \ #define DEF_PARM(type, name, init, perm, desc) \
type name = init; \ type name = init; \
module_param(name, type, perm); \ module_param(name, type, perm); \
MODULE_PARM_DESC(name, desc " [default " #init "]") MODULE_PARM_DESC(name, desc " [default " #init "]")
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 10) #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 10)
@ -69,16 +69,16 @@ typedef unsigned gfp_t; /* Added in 2.6.14 */
* Old 2.6 kernels had module_param_array() macro that receive the counter * Old 2.6 kernels had module_param_array() macro that receive the counter
* by value. * by value.
*/ */
#define DEF_ARRAY(type, name, count, init, desc) \ #define DEF_ARRAY(type, name, count, init, desc) \
unsigned int name ## _num_values; \ unsigned int name ## _num_values; \
type name[count] = { [0 ... ((count)-1)] = (init) }; \ type name[count] = { [0 ... ((count)-1)] = (init) }; \
module_param_array(name, type, name ## _num_values, 0644); \ module_param_array(name, type, name ## _num_values, 0644); \
MODULE_PARM_DESC(name, desc " ( 1-" __MODULE_STRING(count) ")") MODULE_PARM_DESC(name, desc " ( 1-" __MODULE_STRING(count) ")")
#else #else
#define DEF_ARRAY(type, name, count, init, desc) \ #define DEF_ARRAY(type, name, count, init, desc) \
unsigned int name ## _num_values; \ unsigned int name ## _num_values; \
type name[count] = {[0 ... ((count)-1)] = init}; \ type name[count] = {[0 ... ((count)-1)] = init}; \
module_param_array(name, type, &name ## _num_values, 0644); \ module_param_array(name, type, &name ## _num_values, 0644); \
MODULE_PARM_DESC(name, desc " ( 1-" __MODULE_STRING(count) ")") MODULE_PARM_DESC(name, desc " ( 1-" __MODULE_STRING(count) ")")
#endif #endif
#endif // __KERNEL__ #endif // __KERNEL__
@ -150,8 +150,8 @@ struct phonedev {
int channels; int channels;
xpd_direction_t direction; /* TO_PHONE, TO_PSTN */ xpd_direction_t direction; /* TO_PHONE, TO_PSTN */
xpp_line_t no_pcm; /* Temporary: disable PCM (for USB-1) */ xpp_line_t no_pcm; /* Temporary: disable PCM (for USB-1) */
xpp_line_t offhook_state; /* Actual chip state: 0 - ONHOOK, 1 - OFHOOK */ xpp_line_t offhook_state; /* chip state: 0 - ONHOOK, 1 - OFHOOK */
xpp_line_t oht_pcm_pass; /* Transfer on-hook PCM */ xpp_line_t oht_pcm_pass; /* Transfer on-hook PCM */
/* Voice Mail Waiting Indication: */ /* Voice Mail Waiting Indication: */
unsigned int msg_waiting[CHANNELS_PERXPD]; unsigned int msg_waiting[CHANNELS_PERXPD];
@ -225,7 +225,8 @@ struct xpd {
unsigned int timer_count; unsigned int timer_count;
}; };
#define for_each_line(xpd, i) for ((i) = 0; (i) < PHONEDEV(xpd).channels; (i)++) #define for_each_line(xpd, i) \
for ((i) = 0; (i) < PHONEDEV(xpd).channels; (i)++)
#define IS_BRI(xpd) ((xpd)->type == XPD_TYPE_BRI) #define IS_BRI(xpd) ((xpd)->type == XPD_TYPE_BRI)
#define TICK_TOLERANCE 500 /* usec */ #define TICK_TOLERANCE 500 /* usec */
@ -249,7 +250,8 @@ struct xpd_driver {
xpd_type_t type; xpd_type_t type;
struct device_driver driver; struct device_driver driver;
#define driver_to_xpd_driver(driver) container_of(driver, struct xpd_driver, driver) #define driver_to_xpd_driver(driver) \
container_of(driver, struct xpd_driver, driver)
}; };
int xpd_driver_register(struct device_driver *driver); int xpd_driver_register(struct device_driver *driver);

View File

@ -341,9 +341,10 @@ static int xpd_read_proc(char *page, char **start, off_t off, int count,
} }
#if 1 #if 1
if (SPAN_REGISTERED(xpd)) { if (SPAN_REGISTERED(xpd)) {
len += len += sprintf(page + len,
sprintf(page + len, "\nPCM:\n |"
"\nPCM:\n | [readchunk] | [writechunk] | W D"); " [readchunk] |"
" [writechunk] | W D");
for_each_line(xpd, i) { for_each_line(xpd, i) {
struct dahdi_chan *chan = XPD_CHAN(xpd, i); struct dahdi_chan *chan = XPD_CHAN(xpd, i);
__u8 rchunk[DAHDI_CHUNKSIZE]; __u8 rchunk[DAHDI_CHUNKSIZE];
@ -444,8 +445,8 @@ bool xpd_setstate(xpd_t *xpd, enum xpd_state newstate)
goto badstate; goto badstate;
if (xpd->addr.subunit != 0) { if (xpd->addr.subunit != 0) {
XPD_NOTICE(xpd, XPD_NOTICE(xpd,
"%s: Moving to %s allowed only for subunit 0\n", "%s: Moving to %s allowed only for subunit 0\n",
__func__, xpd_statename(newstate)); __func__, xpd_statename(newstate));
goto badstate; goto badstate;
} }
break; break;
@ -531,9 +532,9 @@ err:
* xpd_alloc - Allocator for new XPD's * xpd_alloc - Allocator for new XPD's
* *
*/ */
__must_check xpd_t *xpd_alloc(xbus_t *xbus, int unit, int subunit, int subtype, __must_check xpd_t *xpd_alloc(xbus_t *xbus, int unit, int subunit,
int subunits, size_t privsize, int subtype, int subunits, size_t privsize,
const xproto_table_t *proto_table, int channels) const xproto_table_t *proto_table, int channels)
{ {
xpd_t *xpd = NULL; xpd_t *xpd = NULL;
size_t alloc_size = sizeof(xpd_t) + privsize; size_t alloc_size = sizeof(xpd_t) + privsize;
@ -571,8 +572,9 @@ __must_check xpd_t *xpd_alloc(xbus_t *xbus, int unit, int subunit, int subtype,
0x7F | PHONEDEV(xpd).digital_outputs | PHONEDEV(xpd). 0x7F | PHONEDEV(xpd).digital_outputs | PHONEDEV(xpd).
digital_inputs; digital_inputs;
XBUS_NOTICE(xbus, XBUS_NOTICE(xbus,
"max xframe size = %d, disabling some PCM channels. no_pcm=0x%04X\n", "max xframe size = %d, disabling some PCM channels. "
MAX_SEND_SIZE(xbus), PHONEDEV(xpd).no_pcm); "no_pcm=0x%04X\n",
MAX_SEND_SIZE(xbus), PHONEDEV(xpd).no_pcm);
} }
if (phonedev_init(xpd, proto_table, channels, no_pcm) < 0) if (phonedev_init(xpd, proto_table, channels, no_pcm) < 0)
goto err; goto err;
@ -611,7 +613,11 @@ void update_xpd_status(xpd_t *xpd, int alarm_flag)
struct dahdi_span *span = &PHONEDEV(xpd).span; struct dahdi_span *span = &PHONEDEV(xpd).span;
if (!SPAN_REGISTERED(xpd)) { if (!SPAN_REGISTERED(xpd)) {
// XPD_NOTICE(xpd, "%s: XPD is not registered. Skipping.\n", __func__); #if 0
XPD_NOTICE(xpd,
"%s: XPD is not registered. Skipping.\n",
__func__);
#endif
return; return;
} }
switch (alarm_flag) { switch (alarm_flag) {
@ -948,9 +954,10 @@ const char *xpp_echocan_name(const struct dahdi_chan *chan)
EXPORT_SYMBOL(xpp_echocan_name); EXPORT_SYMBOL(xpp_echocan_name);
int xpp_echocan_create(struct dahdi_chan *chan, struct dahdi_echocanparams *ecp, int xpp_echocan_create(struct dahdi_chan *chan,
struct dahdi_echocanparam *p, struct dahdi_echocanparams *ecp,
struct dahdi_echocan_state **ec) struct dahdi_echocanparam *p,
struct dahdi_echocan_state **ec)
{ {
xpd_t *xpd; xpd_t *xpd;
xbus_t *xbus; xbus_t *xbus;
@ -1044,7 +1051,7 @@ static void xpd_init_span(xpd_t *xpd, unsigned offset, int cn)
memset(XPD_CHAN(xpd, i), 0, sizeof(struct dahdi_chan)); memset(XPD_CHAN(xpd, i), 0, sizeof(struct dahdi_chan));
span = &PHONEDEV(xpd).span; span = &PHONEDEV(xpd).span;
span->deflaw = DAHDI_LAW_MULAW; /* default, may be overriden by card_* drivers */ span->deflaw = DAHDI_LAW_MULAW; /* card_* drivers may override */
span->channels = cn; span->channels = cn;
span->chans = PHONEDEV(xpd).chans; span->chans = PHONEDEV(xpd).chans;
@ -1115,7 +1122,8 @@ int xpd_dahdi_postregister(xpd_t *xpd)
* Try our best to make asterisk close all channels related to * Try our best to make asterisk close all channels related to
* this Astribank: * this Astribank:
* - Set span state to DAHDI_ALARM_NOTOPEN in all relevant spans. * - Set span state to DAHDI_ALARM_NOTOPEN in all relevant spans.
* - Notify dahdi afterwards about spans (so it can see all changes at once). * - Notify dahdi afterwards about spans
* (so it can see all changes at once).
* - Also send DAHDI_EVENT_REMOVED on all channels. * - Also send DAHDI_EVENT_REMOVED on all channels.
*/ */
void xpd_dahdi_preunregister(xpd_t *xpd) void xpd_dahdi_preunregister(xpd_t *xpd)
@ -1132,7 +1140,8 @@ void xpd_dahdi_preunregister(xpd_t *xpd)
dahdi_alarm_notify(&PHONEDEV(xpd).span); dahdi_alarm_notify(&PHONEDEV(xpd).span);
XPD_DBG(DEVICES, xpd, XPD_DBG(DEVICES, xpd,
"Queuing DAHDI_EVENT_REMOVED on all channels to ask user to release them\n"); "Queuing DAHDI_EVENT_REMOVED on all channels "
"to ask user to release them\n");
for (j = 0; j < PHONEDEV(xpd).span.channels; j++) { for (j = 0; j < PHONEDEV(xpd).span.channels; j++) {
dahdi_qevent_lock(XPD_CHAN(xpd, j), dahdi_qevent_lock(XPD_CHAN(xpd, j),
DAHDI_EVENT_REMOVED); DAHDI_EVENT_REMOVED);

View File

@ -44,7 +44,8 @@
static const char rcsid[] = "$Id$"; static const char rcsid[] = "$Id$";
static DEF_PARM(int, debug, 0, 0644, "Print DBG statements"); /* must be before dahdi_debug.h */ /* must be before dahdi_debug.h */
static DEF_PARM(int, debug, 0, 0644, "Print DBG statements");
static DEF_PARM(int, usb1, 0, 0644, "Allow using USB 1.1 interfaces"); static DEF_PARM(int, usb1, 0, 0644, "Allow using USB 1.1 interfaces");
static DEF_PARM(uint, tx_sluggish, 2000, 0644, "A sluggish transmit (usec)"); static DEF_PARM(uint, tx_sluggish, 2000, 0644, "A sluggish transmit (usec)");
static DEF_PARM(uint, drop_pcm_after, 6, 0644, static DEF_PARM(uint, drop_pcm_after, 6, 0644,
@ -54,13 +55,18 @@ static DEF_PARM(uint, drop_pcm_after, 6, 0644,
#define XUSB_PRINTK(level, xusb, fmt, ...) \ #define XUSB_PRINTK(level, xusb, fmt, ...) \
printk(KERN_ ## level "%s-%s: xusb-%d (%s) [%s]: " fmt, #level, \ printk(KERN_ ## level "%s-%s: xusb-%d (%s) [%s]: " fmt, #level, \
THIS_MODULE->name, (xusb)->index, xusb->path, xusb->serial, ## __VA_ARGS__) THIS_MODULE->name, (xusb)->index, xusb->path, \
xusb->serial, ## __VA_ARGS__)
#define XUSB_DBG(bits, xusb, fmt, ...) \ #define XUSB_DBG(bits, xusb, fmt, ...) \
((void)((debug & (DBG_ ## bits)) && XUSB_PRINTK(DEBUG, xusb, "%s: " fmt, __func__, ## __VA_ARGS__))) ((void)((debug & (DBG_ ## bits)) && XUSB_PRINTK(DEBUG, \
#define XUSB_ERR(xusb, fmt, ...) XUSB_PRINTK(ERR, xusb, fmt, ## __VA_ARGS__) xusb, "%s: " fmt, __func__, ## __VA_ARGS__)))
#define XUSB_NOTICE(xusb, fmt, ...) XUSB_PRINTK(NOTICE, xusb, fmt, ## __VA_ARGS__) #define XUSB_ERR(xusb, fmt, ...) \
#define XUSB_INFO(xusb, fmt, ...) XUSB_PRINTK(INFO, xusb, fmt, ## __VA_ARGS__) XUSB_PRINTK(ERR, xusb, fmt, ## __VA_ARGS__)
#define XUSB_NOTICE(xusb, fmt, ...) \
XUSB_PRINTK(NOTICE, xusb, fmt, ## __VA_ARGS__)
#define XUSB_INFO(xusb, fmt, ...) \
XUSB_PRINTK(INFO, xusb, fmt, ## __VA_ARGS__)
/* FIXME: A flag that was deprecated at some point, and rather useless */ /* FIXME: A flag that was deprecated at some point, and rather useless */
/* anyway. Only used in the code or-ed to other flags */ /* anyway. Only used in the code or-ed to other flags */
@ -95,7 +101,8 @@ static DEF_PARM(uint, drop_pcm_after, 6, 0644,
do { \ do { \
if ((udev)->descriptor.field) { \ if ((udev)->descriptor.field) { \
char tmp[USB_MAX_STRING]; \ char tmp[USB_MAX_STRING]; \
if (usb_string((udev), (udev)->descriptor.field, tmp, sizeof(tmp)) > 0) \ if (usb_string((udev), (udev)->descriptor.field, \
tmp, sizeof(tmp)) > 0) \
snprintf((buf), USB_MAX_STRING, "%s", tmp); \ snprintf((buf), USB_MAX_STRING, "%s", tmp); \
} \ } \
} while (0); } while (0);
@ -103,7 +110,8 @@ static DEF_PARM(uint, drop_pcm_after, 6, 0644,
do { \ do { \
if ((iface)->desc.iInterface) { \ if ((iface)->desc.iInterface) { \
char tmp[USB_MAX_STRING]; \ char tmp[USB_MAX_STRING]; \
if (usb_string((udev), (iface)->desc.iInterface, tmp, sizeof(tmp)) > 0) \ if (usb_string((udev), (iface)->desc.iInterface, \
tmp, sizeof(tmp)) > 0) \
snprintf((buf), USB_MAX_STRING, "%s", tmp); \ snprintf((buf), USB_MAX_STRING, "%s", tmp); \
} \ } \
} while (0); } while (0);
@ -185,9 +193,12 @@ struct uframe {
xusb_t *xusb; xusb_t *xusb;
}; };
#define urb_to_uframe(urb) container_of(urb, struct uframe, urb) #define urb_to_uframe(urb) \
#define xframe_to_uframe(xframe) container_of(xframe, struct uframe, xframe) container_of(urb, struct uframe, urb)
#define xusb_of(xbus) ((xusb_t *)((xbus)->transport.priv)) #define xframe_to_uframe(xframe) \
container_of(xframe, struct uframe, xframe)
#define xusb_of(xbus) \
((xusb_t *)((xbus)->transport.priv))
#define USEC_BUCKET 100 /* usec */ #define USEC_BUCKET 100 /* usec */
#define NUM_BUCKETS 15 #define NUM_BUCKETS 15
@ -199,7 +210,7 @@ struct uframe {
struct xusb { struct xusb {
uint xbus_num; uint xbus_num;
struct usb_device *udev; /* save off the usb device pointer */ struct usb_device *udev; /* save off the usb device pointer */
struct usb_interface *interface; /* the interface for this device */ struct usb_interface *interface; /* the interface for this device */
unsigned char minor; /* the starting minor number for this device */ unsigned char minor; /* the starting minor number for this device */
uint index; uint index;
char path[XBUS_DESCLEN]; /* a unique path */ char path[XBUS_DESCLEN]; /* a unique path */
@ -305,8 +316,9 @@ static xframe_t *alloc_xframe(xbus_t *xbus, gfp_t gfp_flags)
if (!xusb->present) { if (!xusb->present) {
if ((rate_limit++ % 1003) == 0) if ((rate_limit++ % 1003) == 0)
XUSB_ERR(xusb, XUSB_ERR(xusb,
"abort allocations during device disconnect (%d)\n", "abort allocations during "
rate_limit); "device disconnect (%d)\n",
rate_limit);
return NULL; return NULL;
} }
size = size =
@ -372,8 +384,9 @@ static int do_send_xframe(xbus_t *xbus, xframe_t *xframe)
if ((rate_limit++ % 1003) == 0) if ((rate_limit++ % 1003) == 0)
XUSB_ERR(xusb, XUSB_ERR(xusb,
"abort do_send_xframe during device disconnect (%d)\n", "abort do_send_xframe during "
rate_limit); "device disconnect (%d)\n",
rate_limit);
ret = -ENODEV; ret = -ENODEV;
goto failure; goto failure;
} }
@ -385,8 +398,9 @@ static int do_send_xframe(xbus_t *xbus, xframe_t *xframe)
if ((rate_limit++ % 5000) == 0) if ((rate_limit++ % 5000) == 0)
XUSB_ERR(xusb, XUSB_ERR(xusb,
"USB device is totaly stuck. Dropping packets (#%d).\n", "USB device is totaly stuck. "
rate_limit); "Dropping packets (#%d).\n",
rate_limit);
ret = -ENODEV; ret = -ENODEV;
goto failure; goto failure;
} }
@ -502,16 +516,23 @@ static const struct xusb_model_info {
/* table of devices that work with this driver */ /* table of devices that work with this driver */
static const struct usb_device_id xusb_table[] = { static const struct usb_device_id xusb_table[] = {
{USB_DEVICE(0xE4E4, 0x1132),.driver_info = (kernel_ulong_t) & model_table[MODEL_FPGA_XPD]}, // FPGA_FXS /* FPGA_FXS */ {USB_DEVICE(0xE4E4, 0x1132),
{USB_DEVICE(0xE4E4, 0x1142),.driver_info = (kernel_ulong_t) & model_table[MODEL_FPGA_XPD]}, // FPGA_1141 .driver_info = (kernel_ulong_t) & model_table[MODEL_FPGA_XPD]},
{USB_DEVICE(0xE4E4, 0x1152),.driver_info = (kernel_ulong_t) & model_table[MODEL_FPGA_XPD]}, // FPGA_1151 /* FPGA_1141 */ {USB_DEVICE(0xE4E4, 0x1142),
{USB_DEVICE(0xE4E4, 0x1162),.driver_info = (kernel_ulong_t) & model_table[MODEL_FPGA_XPD]}, // FPGA_1161 .driver_info = (kernel_ulong_t) & model_table[MODEL_FPGA_XPD]},
{} /* Terminating entry */ /* FPGA_1151 */ {USB_DEVICE(0xE4E4, 0x1152),
.driver_info = (kernel_ulong_t) & model_table[MODEL_FPGA_XPD]},
/* FPGA_1161 */ {USB_DEVICE(0xE4E4, 0x1162),
.driver_info = (kernel_ulong_t) & model_table[MODEL_FPGA_XPD]},
/* Terminate */ {}
}; };
MODULE_DEVICE_TABLE(usb, xusb_table); MODULE_DEVICE_TABLE(usb, xusb_table);
/* usb specific object needed to register this driver with the usb subsystem */ /*
* USB specific object needed to register this driver
* with the usb subsystem
*/
static struct usb_driver xusb_driver = { static struct usb_driver xusb_driver = {
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 16) #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 16)
.owner = THIS_MODULE, .owner = THIS_MODULE,
@ -577,21 +598,25 @@ static int check_usb1(struct usb_endpoint_descriptor *endpoint)
return 1; return 1;
if (usb1) { if (usb1) {
NOTICE NOTICE("USB1 endpoint detected: "
("USB1 endpoint detected: USB %s endpoint 0x%X support only wMaxPacketSize=%d.\n", "USB %s endpoint 0x%X support only wMaxPacketSize=%d\n",
msg, endpoint->bEndpointAddress, endpoint->wMaxPacketSize); msg,
endpoint->bEndpointAddress,
endpoint->wMaxPacketSize);
return 1; return 1;
} }
NOTICE NOTICE("USB1 endpoint detected: "
("USB1 endpoint detected. Device disabled. To enable: usb1=1, and read docs. (%s, endpoint %d, size %d).\n", "Device disabled. To enable: usb1=1, and read docs. "
msg, endpoint->bEndpointAddress, endpoint->wMaxPacketSize); "(%s, endpoint %d, size %d)\n",
msg, endpoint->bEndpointAddress, endpoint->wMaxPacketSize);
return 0; return 0;
} }
/* /*
* set up the endpoint information * set up the endpoint information
* check out the endpoints * check out the endpoints
* FIXME: Should be simplified (above 2.6.10) to use usb_dev->ep_in[0..16] and usb_dev->ep_out[0..16] * FIXME: Should be simplified (above 2.6.10) to use
* usb_dev->ep_in[0..16] and usb_dev->ep_out[0..16]
*/ */
static int set_endpoints(xusb_t *xusb, struct usb_host_interface *iface_desc, static int set_endpoints(xusb_t *xusb, struct usb_host_interface *iface_desc,
struct xusb_model_info *model_info) struct xusb_model_info *model_info)
@ -601,7 +626,9 @@ static int set_endpoints(xusb_t *xusb, struct usb_host_interface *iface_desc,
int ep_addr; int ep_addr;
int i; int i;
#define BULK_ENDPOINT(ep) (((ep)->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_BULK) #define BULK_ENDPOINT(ep) \
(((ep)->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == \
USB_ENDPOINT_XFER_BULK)
for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) { for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) {
endpoint = &iface_desc->endpoint[i].desc; endpoint = &iface_desc->endpoint[i].desc;
@ -646,7 +673,8 @@ static int set_endpoints(xusb_t *xusb, struct usb_host_interface *iface_desc,
/* /*
* The USB stack before 2.6.10 seems to be a bit shoddy. It seems that when * The USB stack before 2.6.10 seems to be a bit shoddy. It seems that when
* being called from the probe we may already have the lock to udev (the Usb DEVice). * being called from the probe we may already have the lock to
* udev (the Usb DEVice).
* Thus we call the internal __usb_reset_device instead. * Thus we call the internal __usb_reset_device instead.
*/ */
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 10) #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 10)
@ -769,7 +797,8 @@ static int xusb_probe(struct usb_interface *interface,
retval = -ENOMEM; retval = -ENOMEM;
goto probe_failed; goto probe_failed;
} }
usb_make_path(udev, xusb->path, XBUS_DESCLEN); // May trunacte... ignore /* May trunacte... ignore */
usb_make_path(udev, xusb->path, XBUS_DESCLEN);
snprintf(xbus->connector, XBUS_DESCLEN, "%s", xusb->path); snprintf(xbus->connector, XBUS_DESCLEN, "%s", xusb->path);
if (xusb->serial && xusb->serial[0]) if (xusb->serial && xusb->serial[0])
snprintf(xbus->label, LABEL_SIZE, "usb:%s", xusb->serial); snprintf(xbus->label, LABEL_SIZE, "usb:%s", xusb->serial);
@ -899,7 +928,7 @@ static void xpp_send_callback(USB_PASS_CB(urb))
if (!xbus) { if (!xbus) {
XUSB_ERR(xusb, XUSB_ERR(xusb,
"Sent URB does not belong to a valid xbus anymore...\n"); "Sent URB does not belong to a valid xbus...\n");
return; return;
} }
//flip_parport_bit(6); //flip_parport_bit(6);
@ -918,10 +947,12 @@ static void xpp_send_callback(USB_PASS_CB(urb))
if (xusb->sluggish_debounce++ > drop_pcm_after) { if (xusb->sluggish_debounce++ > drop_pcm_after) {
static int rate_limit; static int rate_limit;
if ((rate_limit++ % 1003) == 500) /* skip first messages */ /* skip first messages */
if ((rate_limit++ % 1003) == 500)
XUSB_NOTICE(xusb, XUSB_NOTICE(xusb,
"Sluggish USB. Dropping next PCM frame (pending_writes=%d)\n", "Sluggish USB. Dropping next PCM frame "
writes); "(pending_writes=%d)\n",
writes);
atomic_inc(&xusb->pcm_tx_drops); atomic_inc(&xusb->pcm_tx_drops);
xusb->drop_next_pcm = 1; xusb->drop_next_pcm = 1;
xusb->sluggish_debounce = 0; xusb->sluggish_debounce = 0;
@ -934,8 +965,9 @@ static void xpp_send_callback(USB_PASS_CB(urb))
static int rate_limit; static int rate_limit;
if ((rate_limit++ % 1000) < 10) { if ((rate_limit++ % 1000) < 10) {
XUSB_ERR(xusb, XUSB_ERR(xusb,
"nonzero write bulk status received: %d (pending_writes=%d)\n", "nonzero write bulk status received: "
urb->status, writes); "%d (pending_writes=%d)\n",
urb->status, writes);
dump_xframe("usb-write-error", xbus, xframe, DBG_ANY); dump_xframe("usb-write-error", xbus, xframe, DBG_ANY);
} }
XUSB_COUNTER(xusb, TX_ERRORS)++; XUSB_COUNTER(xusb, TX_ERRORS)++;
@ -960,7 +992,7 @@ static void xpp_receive_callback(USB_PASS_CB(urb))
atomic_dec(&xusb->pending_reads); atomic_dec(&xusb->pending_reads);
if (!xbus) { if (!xbus) {
XUSB_ERR(xusb, XUSB_ERR(xusb,
"Received URB does not belong to a valid xbus anymore...\n"); "Received URB does not belong to a valid xbus...\n");
return; return;
} }
if (!xusb->present) { if (!xusb->present) {

View File

@ -44,7 +44,7 @@ bool valid_xpd_addr(const struct xpd_addr *addr)
&& ((addr->unit & ~BITMASK(UNIT_BITS)) == 0); && ((addr->unit & ~BITMASK(UNIT_BITS)) == 0);
} }
/*---------------- General Protocol Management ----------------------------*/ /*------ General Protocol Management ----------------------------*/
const xproto_entry_t *xproto_card_entry(const xproto_table_t *table, const xproto_entry_t *xproto_card_entry(const xproto_table_t *table,
__u8 opcode) __u8 opcode)
@ -87,9 +87,9 @@ const xproto_table_t *xproto_get(xpd_type_t cardtype)
if (!xtable) { /* Try to load the relevant module */ if (!xtable) { /* Try to load the relevant module */
int ret = request_module(XPD_TYPE_PREFIX "%d", cardtype); int ret = request_module(XPD_TYPE_PREFIX "%d", cardtype);
if (ret != 0) { if (ret != 0) {
NOTICE NOTICE("%s: Failed to load module for type=%d. "
("%s: Failed to load module for type=%d. exit status=%d.\n", "exit status=%d.\n",
__func__, cardtype, ret); __func__, cardtype, ret);
/* Drop through: we may be lucky... */ /* Drop through: we may be lucky... */
} }
xtable = xprotocol_tables[cardtype]; xtable = xprotocol_tables[cardtype];
@ -120,7 +120,8 @@ void xproto_put(const xproto_table_t *xtable)
module_put(xtable->owner); module_put(xtable->owner);
} }
xproto_handler_t xproto_card_handler(const xproto_table_t *table, __u8 opcode) xproto_handler_t xproto_card_handler(const xproto_table_t *table,
__u8 opcode)
{ {
const xproto_entry_t *xe; const xproto_entry_t *xe;
@ -169,9 +170,10 @@ static int packet_process(xbus_t *xbus, xpacket_t *pack)
if (!xpd) { if (!xpd) {
if (printk_ratelimit()) { if (printk_ratelimit()) {
XBUS_NOTICE(xbus, XBUS_NOTICE(xbus,
"%s: from %d%d opcode=0x%02X: no such global command.\n", "%s: from %d%d opcode=0x%02X: "
__func__, XPACKET_ADDR_UNIT(pack), "no such global command.\n",
XPACKET_ADDR_SUBUNIT(pack), op); __func__, XPACKET_ADDR_UNIT(pack),
XPACKET_ADDR_SUBUNIT(pack), op);
dump_packet dump_packet
("packet_process -- no such global command", ("packet_process -- no such global command",
pack, 1); pack, 1);
@ -190,10 +192,10 @@ static int packet_process(xbus_t *xbus, xpacket_t *pack)
if (!xe) { if (!xe) {
if (printk_ratelimit()) { if (printk_ratelimit()) {
XPD_NOTICE(xpd, XPD_NOTICE(xpd,
"%s: bad command (type=%d,opcode=0x%x)\n", "%s: bad command (type=%d,opcode=0x%x)\n",
__func__, xpd->type, op); __func__, xpd->type, op);
dump_packet("packet_process -- bad command", dump_packet("packet_process -- bad command",
pack, 1); pack, 1);
} }
goto out; goto out;
} }
@ -239,9 +241,9 @@ static int xframe_receive_cmd(xbus_t *xbus, xframe_t *xframe)
if ((rate_limit++ % 1003) == 0) { if ((rate_limit++ % 1003) == 0) {
XBUS_DBG(GENERAL, xbus, XBUS_DBG(GENERAL, xbus,
"A PCM packet within a Non-PCM xframe\n"); "A PCM packet within a Non-PCM xframe\n");
dump_xframe("In Non-PCM xframe", xbus, xframe, dump_xframe("In Non-PCM xframe",
debug); xbus, xframe, debug);
} }
ret = -EPROTO; ret = -EPROTO;
goto out; goto out;
@ -336,9 +338,14 @@ void dump_packet(const char *msg, const xpacket_t *packet, bool debug)
if (i >= sizeof(xpacket_t)) { if (i >= sizeof(xpacket_t)) {
if (limiter < ERR_REPORT_LIMIT) { if (limiter < ERR_REPORT_LIMIT) {
ERR("%s: length overflow i=%d > sizeof(xpacket_t)=%lu\n", __func__, i + 1, (long)sizeof(xpacket_t)); ERR("%s: length overflow "
"i=%d > sizeof(xpacket_t)=%lu\n",
__func__, i + 1,
(long)sizeof(xpacket_t));
} else if (limiter == ERR_REPORT_LIMIT) { } else if (limiter == ERR_REPORT_LIMIT) {
ERR("%s: error packet #%d... squelsh reports.\n", __func__, limiter); ERR("%s: error packet #%d... "
"squelsh reports.\n",
__func__, limiter);
} }
limiter++; limiter++;
break; break;
@ -351,8 +358,8 @@ void dump_packet(const char *msg, const xpacket_t *packet, bool debug)
printk("\n"); printk("\n");
} }
void dump_reg_cmd(const char msg[], bool writing, xbus_t *xbus, __u8 unit, void dump_reg_cmd(const char msg[], bool writing, xbus_t *xbus,
xportno_t port, const reg_cmd_t *regcmd) __u8 unit, xportno_t port, const reg_cmd_t *regcmd)
{ {
char action; char action;
char modifier; char modifier;
@ -360,7 +367,8 @@ void dump_reg_cmd(const char msg[], bool writing, xbus_t *xbus, __u8 unit,
char reg_buf[MAX_PROC_WRITE]; char reg_buf[MAX_PROC_WRITE];
char data_buf[MAX_PROC_WRITE]; char data_buf[MAX_PROC_WRITE];
if (regcmd->bytes > sizeof(*regcmd) - 1) { /* The size byte is not included */ /* The size byte is not included */
if (regcmd->bytes > sizeof(*regcmd) - 1) {
PORT_NOTICE(xbus, unit, port, PORT_NOTICE(xbus, unit, port,
"%s: %s: Too long: regcmd->bytes = %d\n", __func__, "%s: %s: Too long: regcmd->bytes = %d\n", __func__,
msg, regcmd->bytes); msg, regcmd->bytes);
@ -378,12 +386,14 @@ void dump_reg_cmd(const char msg[], bool writing, xbus_t *xbus, __u8 unit,
n += snprintf(&buf[n], MAX_PROC_WRITE - n, "%02X ", n += snprintf(&buf[n], MAX_PROC_WRITE - n, "%02X ",
p[i]); p[i]);
PORT_DBG(REGS, xbus, unit, port, PORT_DBG(REGS, xbus, unit, port,
"UNIT-%d PORT-%d: Multibyte(eoframe=%d) %s[0..%zd]: %s%s\n", "UNIT-%d PORT-%d: Multibyte(eoframe=%d) "
unit, port, regcmd->eoframe, msg, len - 1, buf, "%s[0..%zd]: %s%s\n",
(n >= MAX_PROC_WRITE) ? "..." : ""); unit, port, regcmd->eoframe, msg, len - 1, buf,
(n >= MAX_PROC_WRITE) ? "..." : "");
return; return;
} }
if (regcmd->bytes != sizeof(*regcmd) - 1) { /* The size byte is not included */ /* The size byte is not included */
if (regcmd->bytes != sizeof(*regcmd) - 1) {
PORT_NOTICE(xbus, unit, port, PORT_NOTICE(xbus, unit, port,
"%s: %s: Wrong size: regcmd->bytes = %d\n", "%s: %s: Wrong size: regcmd->bytes = %d\n",
__func__, msg, regcmd->bytes); __func__, msg, regcmd->bytes);
@ -429,13 +439,15 @@ const char *xproto_name(xpd_type_t xpd_type)
#define CHECK_XOP(xops, f) \ #define CHECK_XOP(xops, f) \
if (!(xops)->f) { \ if (!(xops)->f) { \
ERR("%s: missing xmethod %s [%s (%d)]\n", __func__, #f, name, type); \ ERR("%s: missing xmethod %s [%s (%d)]\n", \
__func__, #f, name, type); \
return -EINVAL; \ return -EINVAL; \
} }
#define CHECK_PHONEOP(phoneops, f) \ #define CHECK_PHONEOP(phoneops, f) \
if (!(phoneops)->f) { \ if (!(phoneops)->f) { \
ERR("%s: missing phone method %s [%s (%d)]\n", __func__, #f, name, type); \ ERR("%s: missing phone method %s [%s (%d)]\n", \
__func__, #f, name, type); \
return -EINVAL; \ return -EINVAL; \
} }

View File

@ -120,7 +120,8 @@ bool valid_xpd_addr(const struct xpd_addr *addr);
__VA_ARGS__ \ __VA_ARGS__ \
} PACKED } PACKED
#define RPACKET_HEADERSIZE sizeof(struct xpacket_header) #define RPACKET_HEADERSIZE sizeof(struct xpacket_header)
#define RPACKET_FIELD(p, card, op, field) (((RPACKET_TYPE(card, op) *)(p))->field) #define RPACKET_FIELD(p, card, op, field) \
(((RPACKET_TYPE(card, op) *)(p))->field)
#define RPACKET_SIZE(card, op) sizeof(RPACKET_TYPE(card, op)) #define RPACKET_SIZE(card, op) sizeof(RPACKET_TYPE(card, op))
#define XENTRY(prototab, module, op) \ #define XENTRY(prototab, module, op) \
@ -162,7 +163,7 @@ bool valid_xpd_addr(const struct xpd_addr *addr);
#endif #endif
/*--------------------------- register handling --------------------------------*/ /*----------------- register handling --------------------------------*/
#define MULTIBYTE_MAX_LEN 5 /* FPGA firmware limitation */ #define MULTIBYTE_MAX_LEN 5 /* FPGA firmware limitation */
@ -195,7 +196,7 @@ typedef struct reg_cmd {
#define REG_XDATA(regptr) ((regptr)->alt.d.xdata) #define REG_XDATA(regptr) ((regptr)->alt.d.xdata)
#ifdef __KERNEL__ #ifdef __KERNEL__
/*--------------------------- protocol tables ----------------------------------*/ /*----------------- protocol tables ----------------------------------*/
typedef struct xproto_entry xproto_entry_t; typedef struct xproto_entry xproto_entry_t;
typedef struct xproto_table xproto_table_t; typedef struct xproto_table xproto_table_t;
@ -207,7 +208,8 @@ const xproto_table_t *xproto_get(xpd_type_t cardtype);
void xproto_put(const xproto_table_t *xtable); void xproto_put(const xproto_table_t *xtable);
const xproto_entry_t *xproto_card_entry(const xproto_table_t *table, const xproto_entry_t *xproto_card_entry(const xproto_table_t *table,
__u8 opcode); __u8 opcode);
xproto_handler_t xproto_card_handler(const xproto_table_t *table, __u8 opcode); xproto_handler_t xproto_card_handler(const xproto_table_t *table,
__u8 opcode);
const xproto_entry_t *xproto_global_entry(__u8 opcode); const xproto_entry_t *xproto_global_entry(__u8 opcode);
xproto_handler_t xproto_global_handler(__u8 opcode); xproto_handler_t xproto_global_handler(__u8 opcode);
@ -301,8 +303,8 @@ struct xpacket {
} PACKED; } PACKED;
void dump_packet(const char *msg, const xpacket_t *packet, bool debug); void dump_packet(const char *msg, const xpacket_t *packet, bool debug);
void dump_reg_cmd(const char msg[], bool writing, xbus_t *xbus, __u8 unit, void dump_reg_cmd(const char msg[], bool writing, xbus_t *xbus,
xportno_t port, const reg_cmd_t *regcmd); __u8 unit, xportno_t port, const reg_cmd_t *regcmd);
int xframe_receive(xbus_t *xbus, xframe_t *xframe); int xframe_receive(xbus_t *xbus, xframe_t *xframe);
void notify_bad_xpd(const char *funcname, xbus_t *xbus, void notify_bad_xpd(const char *funcname, xbus_t *xbus,
const struct xpd_addr addr, const char *msg); const struct xpd_addr addr, const char *msg);