diff options
Diffstat (limited to 'xpp/card_bri.c')
-rw-r--r-- | xpp/card_bri.c | 84 |
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(®cmd, 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(®cmd)[0] = reg_num; @@ -1587,18 +1601,15 @@ static int handle_register_command(xpd_t *xpd, char *cmdline) REG_XDATA(®cmd)[2] = data; REG_XDATA(®cmd)[3] = xdata1; REG_XDATA(®cmd)[4] = xdata2; - return send_bri_multibyte(xpd, REG_XDATA(®cmd), elements, (reg_type == 'm')); + ret = send_bri_multibyte(xpd, REG_XDATA(®cmd), 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(®cmd, read_request) = writing; REG_FIELD(®cmd, 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", ®cmd, 1); @@ -1610,7 +1621,8 @@ static int handle_register_command(xpd_t *xpd, char *cmdline) REG_FIELD(®cmd, subreg), REG_FIELD(®cmd, data_low), REG_FIELD(®cmd, data_high)); - up_read(&xbus->in_use); +out: + XBUS_PUT(xbus); return ret; } |