summaryrefslogtreecommitdiff
path: root/xpp/card_bri.c
diff options
context:
space:
mode:
authortzafrir <tzafrir@5390a7c7-147a-4af0-8ec9-7488f05a26cb>2007-12-18 14:31:07 +0000
committertzafrir <tzafrir@5390a7c7-147a-4af0-8ec9-7488f05a26cb>2007-12-18 14:31:07 +0000
commitcfd61537b47387b0fb5c8228baad6cec16d8f6e6 (patch)
tree108deea65c09c7c273a9b981f8783efcd433eaea /xpp/card_bri.c
parent4391b4a6ee42bdfd8e097c5ee5485e9eb13f19a0 (diff)
xpp r5151:
* xpd_pri: Basically ready. * PCM synchronization changes: - Each Astribank unit ticks independently. Each with its own PLL. - HOST synchronization is gone. Loading of xpp will no longer cause useless 250 ticks per second if you have no Astribank. - Synchronization from the zaptel sync master requires setting ZAPTEL as sync source (xpp_sync ZAPTEL). * rx_tasklet is now a parameter of the module xpp, rather than of xpp_usb. * New FPGA firmware: 5128 (1151) / 5122 (1141, 1131): - Fixes synchronization issues. - PRI module: E1 should now work. * perl module and utilities: - Modules no longer magically scan system on initialization. - Scanning is by calling explicit methods. - "Serial" has been renamed "Label". It is basically unique, but should be modifieble. - Some basic documentation of zaptel perl modules. * Default sort order of zt_registration is back to SORT_CONNCTOR. * zt_registration proc file now shows the number of span registered to if registered. Try: grep . /proc/xpp/XBUS-*/XPD-*/zt_registration * genzaptelconf: Allow using a custom command instead of /etc/init.d/asterisk to start/stop asterisk. * Fixed the typo "Slagish". git-svn-id: http://svn.digium.com/svn/zaptel/branches/1.2@3506 5390a7c7-147a-4af0-8ec9-7488f05a26cb
Diffstat (limited to 'xpp/card_bri.c')
-rw-r--r--xpp/card_bri.c84
1 files changed, 48 insertions, 36 deletions
diff --git a/xpp/card_bri.c b/xpp/card_bri.c
index 3e67c4d..fb423a3 100644
--- a/xpp/card_bri.c
+++ b/xpp/card_bri.c
@@ -481,7 +481,7 @@ static int send_bri_multibyte(xpd_t *xpd, byte *buf, int len, bool eoftx)
XPD_ERR(xpd, "%s: len=%d is too long. dropping.\n", __FUNCTION__, len);
return -EINVAL;
}
- XFRAME_NEW(xframe, pack, xbus, GLOBAL, REGISTER_REQUEST, xpd->xbus_idx);
+ XFRAME_NEW_CMD(xframe, pack, xbus, GLOBAL, REGISTER_REQUEST, xpd->xbus_idx);
reg_cmd = &RPACKET_FIELD(pack, GLOBAL, REGISTER_REQUEST, reg_cmd);
reg_cmd->bytes = len;
reg_cmd->eoframe = eoftx;
@@ -643,15 +643,6 @@ static int BRI_card_init(xbus_t *xbus, xpd_t *xpd)
ret = run_initialize_registers(xpd);
if(ret < 0)
goto err;
-#if 1
-#warning "Test BRI! (removed old SYNC_SOURCE manipulation)"
-#else
- /*
- * FPGA firmware limitation:
- * Force HOST sync *before* sending PCM
- */
- CALL_PROTO(GLOBAL, SYNC_SOURCE, xbus, NULL, SYNC_MODE_HOST, 0);
-#endif
XPD_DBG(PROC, xpd, "done\n");
priv->initialized = 1;
return 0;
@@ -848,7 +839,7 @@ static int BRI_card_tick(xbus_t *xbus, xpd_t *xpd)
BUG_ON(!xpd);
priv = xpd->priv;
BUG_ON(!priv);
- if(!priv->initialized)
+ if(!priv->initialized || !xbus->self_ticking)
return 0;
if(poll_interval != 0 && (priv->tick_counter % poll_interval) == 0) {
// XPD_DBG(GENERAL, xpd, "%d\n", priv->tick_counter);
@@ -902,6 +893,26 @@ static int BRI_card_tick(xbus_t *xbus, xpd_t *xpd)
return 0;
}
+static int BRI_card_ioctl(xpd_t *xpd, int pos, unsigned int cmd, unsigned long arg)
+{
+ BUG_ON(!xpd);
+ if(!TRANSPORT_RUNNING(xpd->xbus))
+ return -ENODEV;
+ switch (cmd) {
+ case ZT_TONEDETECT:
+ /*
+ * Asterisk call all span types with this (FXS specific)
+ * call. Silently ignore it.
+ */
+ LINE_DBG(SIGNAL, xpd, pos, "BRI: Starting a call\n");
+ return -ENOTTY;
+ default:
+ report_bad_ioctl(THIS_MODULE->name, xpd, pos, cmd);
+ return -ENOTTY;
+ }
+ return 0;
+}
+
static int BRI_card_close(xpd_t *xpd, lineno_t pos)
{
struct zt_chan *chan = &xpd->span.chans[pos];
@@ -982,7 +993,7 @@ static int bri_startup(struct zt_span *span)
BUG_ON(!xpd);
priv = xpd->priv;
BUG_ON(!priv);
- if(!xpd->xbus->hardware_exists) {
+ if(!TRANSPORT_RUNNING(xpd->xbus)) {
XPD_DBG(GENERAL, xpd, "Startup called by zaptel. No Hardware. Ignored\n");
return -ENODEV;
}
@@ -1017,7 +1028,7 @@ static int bri_shutdown(struct zt_span *span)
BUG_ON(!xpd);
priv = xpd->priv;
BUG_ON(!priv);
- if(!xpd->xbus->hardware_exists) {
+ if(!TRANSPORT_RUNNING(xpd->xbus)) {
XPD_DBG(GENERAL, xpd, "Shutdown called by zaptel. No Hardware. Ignored\n");
return -ENODEV;
}
@@ -1075,7 +1086,6 @@ static void BRI_card_pcm_fromspan(xbus_t *xbus, xpd_t *xpd, xpp_line_t wanted_li
static void BRI_card_pcm_tospan(xbus_t *xbus, xpd_t *xpd, xpacket_t *pack)
{
- volatile u_char *r;
byte *pcm;
xpp_line_t pcm_mask;
unsigned long flags;
@@ -1087,6 +1097,8 @@ static void BRI_card_pcm_tospan(xbus_t *xbus, xpd_t *xpd, xpacket_t *pack)
*/
if(xpd->addr.subunit != 0)
return;
+ if(!SPAN_REGISTERED(xpd))
+ return;
pcm = RPACKET_FIELD(pack, GLOBAL, PCM_READ, pcm);
pcm_mask = RPACKET_FIELD(pack, GLOBAL, PCM_WRITE, lines);
for(subunit = 0; subunit < MAX_SUBUNIT; subunit++, pcm_mask >>= SUBUNIT_PCM_SHIFT) {
@@ -1095,19 +1107,15 @@ static void BRI_card_pcm_tospan(xbus_t *xbus, xpd_t *xpd, xpacket_t *pack)
if(!pcm_mask)
break; /* optimize */
tmp_xpd = xpd_byaddr(xbus, xpd->addr.unit, subunit);
- if(!tmp_xpd || !tmp_xpd->card_present)
+ if(!tmp_xpd || !tmp_xpd->card_present || !SPAN_REGISTERED(tmp_xpd))
continue;
spin_lock_irqsave(&tmp_xpd->lock, flags);
- if (tmp_xpd->timer_count & 1) {
- /* First part */
- r = tmp_xpd->readchunk;
- } else {
- r = tmp_xpd->readchunk + ZT_CHUNKSIZE * CHANNELS_PERXPD;
- }
- for (i = 0; i < 2; i++, r += ZT_CHUNKSIZE) {
+ for (i = 0; i < 2; i++) {
xpp_line_t tmp_mask = pcm_mask & (BIT(0) | BIT(1));
+ volatile u_char *r;
if(IS_SET(tmp_mask, i)) {
+ r = tmp_xpd->span.chans[i].readchunk;
// memset((u_char *)r, 0x5A, ZT_CHUNKSIZE); // DEBUG
// fill_beep((u_char *)r, 1, 1); // DEBUG: BEEP
memcpy((u_char *)r, pcm, ZT_CHUNKSIZE);
@@ -1155,7 +1163,7 @@ static /* 0x33 */ HOSTCMD(BRI, SET_LED, enum bri_led_names which_led, enum led_s
XPD_DBG(LEDS, xpd, "%s -> %d\n",
(which_led)?"RED":"GREEN",
to_led_state);
- XFRAME_NEW(xframe, pack, xbus, BRI, SET_LED, xpd->xbus_idx);
+ XFRAME_NEW_CMD(xframe, pack, xbus, BRI, SET_LED, xpd->xbus_idx);
bri_leds = &RPACKET_FIELD(pack, BRI, SET_LED, bri_leds);
bri_leds->state = to_led_state;
bri_leds->led_sel = which_led;
@@ -1362,6 +1370,7 @@ static xproto_table_t PROTO_TABLE(BRI_NT) = {
.card_tick = BRI_card_tick,
.card_pcm_fromspan = BRI_card_pcm_fromspan,
.card_pcm_tospan = BRI_card_pcm_tospan,
+ .card_ioctl = BRI_card_ioctl,
.card_close = BRI_card_close,
.card_register_reply = BRI_card_register_reply,
@@ -1507,12 +1516,13 @@ static int handle_register_command(xpd_t *xpd, char *cmdline)
char *p;
reg_cmd_t regcmd;
xbus_t *xbus;
- int ret;
+ int ret = -EINVAL;
struct BRI_priv_data *priv;
byte buf[MAX_PROC_WRITE];
BUG_ON(!xpd);
xbus = xpd->xbus;
+ BUG_ON(!xbus);
priv = xpd->priv;
BUG_ON(!priv);
if((p = strchr(cmdline, '#')) != NULL) /* Truncate comments */
@@ -1524,6 +1534,10 @@ static int handle_register_command(xpd_t *xpd, char *cmdline)
if(*p == '\0')
return 0;
+ if(!XBUS_GET(xbus)) {
+ XBUS_DBG(GENERAL, xbus, "Dropped packet. Is shutting down.\n");
+ return -EBUSY;
+ }
memset(buf, 0, MAX_PROC_WRITE);
elements = sscanf(cmdline, "%d %c%c %x %x %x %x %x",
&chipsel,
@@ -1533,11 +1547,11 @@ static int handle_register_command(xpd_t *xpd, char *cmdline)
XPD_DBG(PROC, xpd, "'%s': %d %c%c %02X %02X %02X\n", cmdline, chipsel, op, reg_type, reg_num, subreg, data);
if(elements < 3) { // At least: chipsel, op, reg_type, reg_num
ERR("Not enough arguments: (%d args) '%s'\n", elements, cmdline);
- return -EINVAL;
+ goto out;
}
if(!VALID_CHIPSEL(chipsel)) {
ERR("Bad chip select number: %d\n", chipsel);
- return -EINVAL;
+ goto out;
}
REG_FIELD(&regcmd, chipsel) = chipsel;
switch(op) {
@@ -1549,7 +1563,7 @@ static int handle_register_command(xpd_t *xpd, char *cmdline)
break;
default:
ERR("Unkown operation type '%c'\n", op);
- return -EINVAL;
+ goto out;
}
if(
(op == 'W' && reg_type == 'D' && elements != 5) ||
@@ -1560,7 +1574,7 @@ static int handle_register_command(xpd_t *xpd, char *cmdline)
ERR("Bad number of elements: '%s' (%d elements): %d %c%c %02X %02X %02X\n",
cmdline, elements,
chipsel, op, reg_type, reg_num, subreg, data);
- return -EINVAL;
+ goto out;
}
switch(reg_type) {
case 'S':
@@ -1579,7 +1593,7 @@ static int handle_register_command(xpd_t *xpd, char *cmdline)
case 'm': /* Multi with eoftx */
if(!writing) {
ERR("Read multibyte is not implemented\n");
- return -EINVAL;
+ goto out;
}
elements -= 3;
REG_XDATA(&regcmd)[0] = reg_num;
@@ -1587,18 +1601,15 @@ static int handle_register_command(xpd_t *xpd, char *cmdline)
REG_XDATA(&regcmd)[2] = data;
REG_XDATA(&regcmd)[3] = xdata1;
REG_XDATA(&regcmd)[4] = xdata2;
- return send_bri_multibyte(xpd, REG_XDATA(&regcmd), elements, (reg_type == 'm'));
+ ret = send_bri_multibyte(xpd, REG_XDATA(&regcmd), elements, (reg_type == 'm'));
+ goto out;
default:
ERR("Unkown register type '%c'\n", reg_type);
- return -EINVAL;
+ goto out;
}
regcmd.bytes = sizeof(regcmd) - 1;
REG_FIELD(&regcmd, read_request) = writing;
REG_FIELD(&regcmd, data_high) = 0;
- if(!down_read_trylock(&xbus->in_use)) {
- XBUS_DBG(GENERAL, xbus, "Dropped packet. Is in_use\n");
- return -EBUSY;
- }
priv->requested_reply = regcmd;
if(print_dbg)
dump_reg_cmd("BRI", &regcmd, 1);
@@ -1610,7 +1621,8 @@ static int handle_register_command(xpd_t *xpd, char *cmdline)
REG_FIELD(&regcmd, subreg),
REG_FIELD(&regcmd, data_low),
REG_FIELD(&regcmd, data_high));
- up_read(&xbus->in_use);
+out:
+ XBUS_PUT(xbus);
return ret;
}