diff options
Diffstat (limited to 'xpp/xpp_zap.c')
-rw-r--r-- | xpp/xpp_zap.c | 320 |
1 files changed, 135 insertions, 185 deletions
diff --git a/xpp/xpp_zap.c b/xpp/xpp_zap.c index 4c8d3e9..4209fda 100644 --- a/xpp/xpp_zap.c +++ b/xpp/xpp_zap.c @@ -40,7 +40,7 @@ #include <linux/proc_fs.h> #ifdef STANDALONE_ZAPATA -#include "zaptel.h" +#include "../zaptel.h" #else #include <zaptel/zaptel.h> #endif @@ -69,25 +69,20 @@ static struct timer_list xpp_timer; static xpd_t *sync_master = NULL; // Start with host based sync static unsigned int xpp_timer_count = 0; static unsigned int xpp_last_jiffies = 0; -struct workqueue_struct *xpp_worker = NULL; - -static LIST_HEAD(xpd_list); DEF_PARM(int, print_dbg, 0, "Print DBG statements"); DEF_PARM(int, max_queue_len, MAX_QUEUE_LEN, "Maximum Queue Length."); -DEF_PARM(int, ignore_xpds, 0, "a bitmask of xpd numbers to ignore"); -DEF_PARM(int, xbus_err_disable_bus, 1000, "Number of errors needed to disable bus"); // FIXME: unused now. -DEF_PARM(ulong, pcm_gen, 0, "a bitmask of line numbers for hardware tone generator"); DEF_PARM(bool, have_sync_bus, 0, "True if all Astribank(TM) devices are connected via a sync-cable"); DEF_PARM(bool, zap_autoreg, 1, "Register spans automatically (1) or not (0)"); -DEF_ARRAY(ulong, enabled_channels, MAX_XPDS, ~0, "Enabled channels for each xpd"); - #include "zap_debug.h" +#ifdef XPP_EC_CHUNK +#include "echo_supress/ec_xpp.h" +#endif -static int xpd_zaptel_register(xpd_t *xpd); -static int xpd_zaptel_unregister(xpd_t *xpd); +static int zaptel_register_xpd(xpd_t *xpd); +static int zaptel_unregister_xpd(xpd_t *xpd); static void xpp_ring_generate(xpd_t *xpd); static void xpp_transmitprep(xpd_t *xpd); static void xpp_receiveprep(xpd_t *xpd); @@ -207,7 +202,10 @@ static void xpd_free(xpd_t *xpd) if(!xpd) return; xbus = xpd->xbus; + if(!xbus) + return; DBG("%s/%s\n", xbus->busname, xpd->xpdname); + xbus_unregister_xpd(xbus, xpd); #ifdef CONFIG_PROC_FS if(xpd->proc_xpd_dir) { if(xpd->proc_xpd_summary) { @@ -227,23 +225,42 @@ static void xpd_free(xpd_t *xpd) #endif if(xpd->writechunk) kfree((void *)xpd->writechunk); + xpd->writechunk = NULL; if(xpd->xproto) xproto_put(xpd->xproto); + xpd->xproto = NULL; kfree(xpd); } /*------------------------- XPD Management -------------------------*/ +#define REV(x,y) (10 * (x) + (y)) +static byte good_revs[] = { + REV(1,9), + REV(2,0), +}; +#undef REV + +static bool good_rev(byte rev) +{ + int i; + + for(i = 0; i < ARRAY_SIZE(good_revs); i++) { + if(good_revs[i] == rev) + return 1; + } + return 0; +} + /* * Synchronous part of XPD detection. - * Called from xpp_worker workqueue. + * Called from xbus_poll() */ -void card_detected(void *data) +void card_detected(struct card_desc_struct *card_desc) { - struct card_desc_struct *card_desc = (struct card_desc_struct *)data; xbus_t *xbus; - xpd_t *xpd; + xpd_t *xpd = NULL; int xpd_num; byte type; byte rev; @@ -254,16 +271,24 @@ void card_detected(void *data) BUG_ON(!card_desc); BUG_ON(card_desc->magic != CARD_DESC_MAGIC); xbus = card_desc->xbus; - xpd_num = card_desc->xpd_num; + xpd_num = xpd_addr2num(&card_desc->xpd_addr); type = card_desc->type; rev = card_desc->rev; BUG_ON(!xbus); - DBG("%s: xpd_num=%d type=%d rev=%d\n", xbus->busname, xpd_num, type, rev); + if(!good_rev(rev)) { + NOTICE("%s: New XPD #%d (%d-%d) type=%d has bad firmware revision %d.%d\n", xbus->busname, + xpd_num, card_desc->xpd_addr.unit, card_desc->xpd_addr.subunit, + type, rev / 10, rev % 10); + goto err; + } + INFO("%s: New XPD #%d (%d-%d) type=%d Revision %d.%d\n", xbus->busname, + xpd_num, card_desc->xpd_addr.unit, card_desc->xpd_addr.subunit, + type, rev / 10, rev % 10); xpd = xpd_of(xbus, xpd_num); if(xpd) { if(type == XPD_TYPE_NOMODULE) { NOTICE("%s: xpd #%d: removed\n", __FUNCTION__, xpd_num); - xpd_disconnect(xpd); + BUG(); goto out; } NOTICE("%s: xpd #%d: already exists\n", __FUNCTION__, xpd_num); @@ -285,13 +310,14 @@ void card_detected(void *data) NOTICE("card_new(%s,%d,%d,%d) failed. Ignored.\n", xbus->busname, xpd_num, proto_table->type, rev); goto err; } + xpd->addr = card_desc->xpd_addr; /* For USB-1 disable some channels */ if(xbus->max_packet_size < RPACKET_SIZE(GLOBAL, PCM_WRITE)) { xpp_line_t no_pcm; no_pcm = 0x7F | xpd->digital_outputs | xpd->digital_inputs; - xpd->no_pcm = no_pcm & xpd->enabled_chans; + xpd->no_pcm = no_pcm; NOTICE("%s: max packet size = %d, disabling some PCM channels. no_pcm=0x%04X\n", xbus->busname, xbus->max_packet_size, xpd->no_pcm); } @@ -308,28 +334,28 @@ void card_detected(void *data) ERR("Failed to create proc '%s' for %s/%s\n", PROC_XPD_SUMMARY, xbus->busname, xpd->xpdname); goto err; } + xpd->proc_xpd_summary->owner = THIS_MODULE; xpd->proc_xpd_ztregister = create_proc_entry(PROC_XPD_ZTREGISTER, 0644, xpd->proc_xpd_dir); if (!xpd->proc_xpd_ztregister) { ERR("Failed to create proc '%s' for %s/%s\n", PROC_XPD_ZTREGISTER, xbus->busname, xpd->xpdname); goto err; } + xpd->proc_xpd_ztregister->owner = THIS_MODULE; xpd->proc_xpd_ztregister->data = xpd; xpd->proc_xpd_ztregister->read_proc = proc_xpd_ztregister_read; xpd->proc_xpd_ztregister->write_proc = proc_xpd_ztregister_write; #endif + xbus_register_xpd(xbus, xpd); if(CALL_XMETHOD(card_init, xbus, xpd) < 0) goto err; - list_add(&xpd->xpd_list, &xpd_list); - xbus->xpds[xpd->id] = xpd; - xbus->num_xpds++; // Turn off all channels CALL_XMETHOD(CHAN_ENABLE, xbus, xpd, ~0, 0); xpd->card_present = 1; - // Turn on enabled channels - CALL_XMETHOD(CHAN_ENABLE, xbus, xpd, xpd->enabled_chans, 1); + // Turn on all channels + CALL_XMETHOD(CHAN_ENABLE, xbus, xpd, ALL_LINES, 1); if(zap_autoreg) - xpd_zaptel_register(xpd); + zaptel_register_xpd(xpd); out: memset(card_desc, 0, sizeof(struct card_desc_struct)); kfree(card_desc); @@ -372,10 +398,6 @@ static int xpd_read_proc(char *page, char **start, off_t off, int count, int *eo xpd->timer_count, xpd->span.mainttimer ); len += sprintf(page + len, "STATES:"); - len += sprintf(page + len, "\n\t%-17s: ", "enabled"); - for_each_line(xpd, i) { - len += sprintf(page + len, "%d ", IS_SET(xpd->enabled_chans, i)); - } len += sprintf(page + len, "\n\t%-17s: ", "output_relays"); for_each_line(xpd, i) { len += sprintf(page + len, "%d ", IS_SET(xpd->digital_outputs, i)); @@ -469,8 +491,7 @@ xpd_t *xpd_alloc(size_t privsize, xbus_t *xbus, int xpd_num, const xproto_table_ size_t alloc_size = sizeof(xpd_t) + privsize; int i; - INFO("New XPD #%d (Revision %d.%d) detected on xbus %s\n", - xpd_num, revision / 10, revision % 10, xbus->busname); + DBG("%s: xpd #%d\n", xbus->busname, xpd_num); if(!VALID_XPD_NUM(xpd_num)) { ERR("%s: illegal xpd id = %d\n", __FUNCTION__, xpd_num); goto err; @@ -498,7 +519,6 @@ xpd_t *xpd_alloc(size_t privsize, xbus_t *xbus, int xpd_num, const xproto_table_ xpd->type = proto_table->type; xpd->xproto = proto_table; xpd->xops = &proto_table->xops; - xpd->enabled_chans = enabled_channels[xpd_num]; xpd->digital_outputs = 0; xpd->digital_inputs = 0; @@ -535,6 +555,13 @@ err: return NULL; } +/* FIXME: this should be removed once digium patch their zaptel.h + * I simply wish to avoid changing zaptel.h in the xpp patches. + */ +#ifndef ZT_EVENT_REMOVED +#define ZT_EVENT_REMOVED (20) +#endif + void xpd_disconnect(xpd_t *xpd) { unsigned long flags; @@ -550,8 +577,15 @@ void xpd_disconnect(xpd_t *xpd) if(!xpd->card_present) /* Multiple reports */ goto out; xpd->card_present = 0; - if(SPAN_REGISTERED(xpd)) + if(SPAN_REGISTERED(xpd)) { + int i; + update_xpd_status(xpd, ZT_ALARM_NOTOPEN); + /* TODO: Should this be done before releasing the spinlock? */ + DBG("Queuing ZT_EVENT_REMOVED on all channels to ask user to release them\n"); + for (i=0; i<xpd->span.channels; i++) + zt_qevent_lock(&xpd->chans[i],ZT_EVENT_REMOVED); + } out: spin_unlock_irqrestore(&xpd->lock, flags); } @@ -562,12 +596,9 @@ void xpd_remove(xpd_t *xpd) BUG_ON(!xpd); xbus = xpd->xbus; - INFO("Remove XPD #%d from xbus=%s\n", xpd->id, xbus->busname); + INFO("%s: Remove XPD #%d from\n", xbus->busname, xpd->id); - xpd_zaptel_unregister(xpd); - xbus->xpds[xpd->id] = NULL; - list_del(&xpd->xpd_list); - xbus->num_xpds--; + zaptel_unregister_xpd(xpd); CALL_XMETHOD(card_remove, xbus, xpd); xpd_free(xpd); } @@ -595,6 +626,18 @@ void update_xpd_status(xpd_t *xpd, int alarm_flag) DBG("Update XPD alarms: %s -> %02X\n", xpd->span.name, alarm_flag); } +void update_line_status(xpd_t *xpd, int pos, bool good) +{ + struct zt_chan *chan; + + BUG_ON(!xpd); + chan = &xpd->chans[pos]; + if(good) + zt_hooksig(chan, ZT_RXSIG_OFFHOOK); + else + zt_hooksig(chan, ZT_RXSIG_ONHOOK); +} + static void xpp_ring_generate(xpd_t *xpd) { int i; @@ -616,7 +659,7 @@ static void xpp_ring_generate(xpd_t *xpd) * Ring detect logic: * fxo_power is toggled */ - for_each_enabled_line(xpd, i) { + for_each_line(xpd, i) { if(xpd->ringing[i] || xpd->ringer_on[i]) { // ring state is only changed once per second: if((xpd->timer_count % 1000) == 0) { @@ -764,9 +807,9 @@ static int proc_xpd_ztregister_write(struct file *file, const char __user *buffe DBG("%s: %s/%s %s\n", __FUNCTION__, xpd->xbus->busname, xpd->xpdname, (zt_reg) ? "register" : "unregister"); if(zt_reg) - ret = xpd_zaptel_register(xpd); + ret = zaptel_register_xpd(xpd); else - ret = xpd_zaptel_unregister(xpd); + ret = zaptel_unregister_xpd(xpd); return (ret < 0) ? ret : count; } @@ -870,14 +913,14 @@ static void xpp_transmitprep(xpd_t *xpd) wake_up_interruptible(&xpd->txstateq[i]); } } - if(IS_SET(xpd->hookstate, i)) { + if(IS_SET(xpd->hookstate, i) || IS_SET(xpd->cid_on, i)) { memcpy((u_char *)w, chans[i].writechunk, ZT_CHUNKSIZE); // fill_beep((u_char *)w, 5); } w += ZT_CHUNKSIZE; } // if(xpd->hookstate != 0 || sync_master != xpd) { - ret = CALL_XMETHOD(PCM_WRITE, xpd->xbus, xpd, xpd->hookstate, writechunk); + ret = CALL_XMETHOD(PCM_WRITE, xpd->xbus, xpd, xpd->hookstate | xpd->cid_on, writechunk); if(ret < 0) { DBG("failed to write PCM %d\n", ret); } @@ -918,7 +961,7 @@ static inline void xpp_ec_chunk(struct zt_chan *chan, unsigned char *rxchunk, co spin_lock_irqsave(&chan->lock, flags); for (x=0;x<ZT_CHUNKSIZE;x++) { rxlin = ZT_XLAW(rxchunk[x], chan); - rxlin = echo_can_update(chan->ec, ZT_XLAW(txchunk[x], chan), rxlin); + rxlin = xpp_echo_can_update(chan->ec, ZT_XLAW(txchunk[x], chan), rxlin); rxchunk[x] = ZT_LIN2X((int)rxlin, chan); } spin_unlock_irqrestore(&chan->lock, flags); @@ -950,6 +993,8 @@ static void xpp_receiveprep(xpd_t *xpd) // memset((u_char *)readchunk, 0x5A, ZT_CHUNKSIZE); // DEBUG // fill_beep((u_char *)readchunk, 1); // DEBUG: BEEP memcpy(chans[i].readchunk, (u_char *)readchunk, ZT_CHUNKSIZE); + } else { + memset(chans[i].readchunk, 0x7F, ZT_CHUNKSIZE); // SILENCE } readchunk += ZT_CHUNKSIZE; } @@ -1051,7 +1096,7 @@ int xpp_ioctl(struct zt_chan *chan, unsigned int cmd, unsigned long arg) xpd->idletxhookstate[pos] = FXS_LINE_CID; /* OHT mode when idle */ if (xpd->lasttxhook[pos] == FXS_LINE_ENABLED) { /* Apply the change if appropriate */ - CALL_XMETHOD(CHAN_CID, xpd->xbus, xpd, BIT(pos)); // CALLER ID + CALL_XMETHOD(CHAN_CID, xpd->xbus, xpd, pos); // CALLER ID } DBG("xpd=%d: ZT_ONHOOKTRANSFER (%d millis) chan=%d\n", xpd->id, x, pos); return -ENOTTY; @@ -1062,6 +1107,13 @@ int xpp_ioctl(struct zt_chan *chan, unsigned int cmd, unsigned long arg) xpd->id, pos, (x & ZT_TONEDETECT_ON), (x & ZT_TONEDETECT_MUTE)); return -ENOTTY; default: + /* Some span-specific commands before we give up: */ + if (xpd->xops->card_ioctl != NULL) { + x = xpd->xops->card_ioctl(xpd, pos, cmd, arg); + if (x != -ENOTTY) + return x; + } + DBG("ENOTTY: chan=%d cmd=0x%x\n", pos, cmd); DBG(" IOC_TYPE=0x%02X\n", _IOC_TYPE(cmd)); DBG(" IOC_DIR=0x%02X\n", _IOC_DIR(cmd)); @@ -1078,85 +1130,12 @@ static int xpp_hooksig(struct zt_chan *chan, zt_txsig_t txsig) xpd_t *xpd = chan->pvt; xbus_t *xbus; int pos = chan->chanpos - 1; - int ret = 0; BUG_ON(!xpd); xbus = xpd->xbus; BUG_ON(!xbus); - DBG("Setting %s to %s (%d)\n", chan->name, txsig2str(txsig), txsig); - if(xpd->direction == TO_PSTN) { - /* XXX Enable hooksig for FXO XXX */ - switch(txsig) { - case ZT_TXSIG_START: - // DBG("%s: ZT_TXSIG_START (drop through.)\n", chan->name); - case ZT_TXSIG_OFFHOOK: - // DBG("%s: ZT_TXSIG_OFFHOOK\n", chan->name); - do_sethook(xpd, pos, 1); - break; - case ZT_TXSIG_ONHOOK: - // DBG("%s: ZT_TXSIG_ONHOOK\n", chan->name); - do_sethook(xpd, pos, 0); - break; - default: - NOTICE("Can't set tx state to %s (%d)\n", txsig2str(txsig), txsig); - return -EINVAL; - } - } else { /* TO_PHONE */ - switch(txsig) { - case ZT_TXSIG_ONHOOK: - // DBG("%s: ZT_TXSIG_ONHOOK\n", chan->name); - xpd->ringing[pos] = 0; - ret = CALL_XMETHOD(RING, xbus, xpd, pos, 0); // RING off - switch(chan->sig) { - case ZT_SIG_EM: - case ZT_SIG_FXOKS: - case ZT_SIG_FXOLS: - xpd->lasttxhook[pos] = xpd->idletxhookstate[pos]; - break; - case ZT_SIG_FXOGS: - xpd->lasttxhook[pos] = FXS_LINE_TIPOPEN; - break; - } - break; - case ZT_TXSIG_OFFHOOK: - // DBG("%s: ZT_TXSIG_OFFHOOK\n", chan->name); - xpd->ringing[pos] = 0; - ret = CALL_XMETHOD(RING, xbus, xpd, pos, 0); // RING off - switch(chan->sig) { - case ZT_SIG_EM: - xpd->lasttxhook[pos] = FXS_LINE_REV_ACTIVE; - break; - default: - xpd->lasttxhook[pos] = xpd->idletxhookstate[pos]; - break; - } - break; - case ZT_TXSIG_START: - // DBG("%s: ZT_TXSIG_START\n", chan->name); - xpd->lasttxhook[pos] = FXS_LINE_RING; - xpd->ringing[pos] = 1; - if(IS_SET(xpd->digital_inputs, pos)) { - NOTICE("%s: Trying to RING a digital input channel %d. Ignoring\n", __FUNCTION__, pos); - return -EINVAL; - } - if(IS_SET(xpd->digital_outputs, pos)) { - DBG("ZT_RING %s digital output ON\n", chan->name); - ret = CALL_XMETHOD(RELAY_OUT, xpd->xbus, xpd, pos-8, 1); - return ret; - } - ret = CALL_XMETHOD(RING, xbus, xpd, pos, 1); // RING on - break; - case ZT_TXSIG_KEWL: - // DBG("%s: ZT_TXSIG_KEWL\n", chan->name); - xpd->lasttxhook[pos] = FXS_LINE_DISABLED; - break; - default: - NOTICE("%s: Can't set tx state to %s (%d)\n", __FUNCTION__, txsig2str(txsig), txsig); - return -EINVAL; - } - } - return 0; + return CALL_XMETHOD(card_hooksig, xbus, xpd, pos, txsig); } #else @@ -1254,6 +1233,29 @@ int (*hooksig)(struct zt_chan *chan, zt_txsig_t hookstate); int (*sethook)(struct zt_chan *chan, int hookstate); #endif +#ifdef XPP_EC_CHUNK +static int xpp_echocan(struct zt_chan *chan, int len) +{ + if(len == 0) { /* shut down */ + /* zaptel calls this also during channel initialization */ + if(chan->ec) { + xpp_echo_can_free(chan->ec); + } + return 0; + } + if(chan->ec) { + ERR("%s: Trying to override an existing EC (%p)\n", __FUNCTION__, chan->ec); + return -EINVAL; + } + chan->ec = xpp_echo_can_create(len, 0); + if(!chan->ec) { + ERR("%s: Failed creating xpp EC (len=%d)\n", __FUNCTION__, len); + return -EINVAL; + } + return 0; +} +#endif + #ifdef CONFIG_ZAPTEL_WATCHDOG /* * If the watchdog detects no received data, it will call the @@ -1280,7 +1282,7 @@ static int xpp_watchdog(struct zt_span *span, int cause) * - User action through /proc * - During xpd_remove() */ -static int xpd_zaptel_unregister(xpd_t *xpd) +static int zaptel_unregister_xpd(xpd_t *xpd) { unsigned long flags; @@ -1303,18 +1305,17 @@ static int xpd_zaptel_unregister(xpd_t *xpd) mdelay(2); // FIXME: This is to give chance for transmit/receiveprep to finish. spin_unlock_irqrestore(&xpd->lock, flags); if(xpd->card_present) - xpd->xops->card_zaptel_registration(xpd, 0); + xpd->xops->card_zaptel_preregistration(xpd, 0); zt_unregister(&xpd->span); + if(xpd->card_present) + xpd->xops->card_zaptel_postregistration(xpd, 0); return 0; } -static int xpd_zaptel_register(xpd_t *xpd) +static int zaptel_register_xpd(xpd_t *xpd) { - struct zt_chan *cur_chan; struct zt_span *span; xbus_t *xbus; - int sigfxs; - int i; int cn; const xops_t *xops; @@ -1325,7 +1326,6 @@ static int xpd_zaptel_register(xpd_t *xpd) ERR("xpd %s already registered\n", xpd->xpdname); return -EEXIST; } - sigfxs = ! (xpd->direction == TO_PHONE); /* signaling is opposite */ cn = xpd->channels; DBG("Initializing span: xpd %d have %d channels.\n", xpd->id, cn); @@ -1334,46 +1334,7 @@ static int xpd_zaptel_register(xpd_t *xpd) span = &xpd->span; xbus = xpd->xbus; - snprintf(span->name, MAX_SPANNAME, "%s/%s", - xbus->busname, xpd->xpdname); - snprintf(span->desc, MAX_SPANDESC, "Xorcom XPD #%d/%d: %s", - xbus->num, xpd->id, - (xpd->direction == TO_PHONE) ? "FXS" : "FXO" - ); - for(i = 0; i < cn; i++) { - - cur_chan = &xpd->chans[i]; - DBG("setting channel %d (sigfxs=%d)\n", i, sigfxs); - if(IS_SET(xpd->digital_outputs, i)) { - snprintf(cur_chan->name, MAX_CHANNAME, "XPP_OUT/%d/%d/%d", xbus->num, xpd->id, i); - } else if(IS_SET(xpd->digital_inputs, i)) { - snprintf(cur_chan->name, MAX_CHANNAME, "XPP_IN/%d/%d/%d", xbus->num, xpd->id, i); - } else { - snprintf(cur_chan->name, MAX_CHANNAME, "XPP_%s/%d/%d/%d", (sigfxs) ? "FXO" : "FXS", xbus->num, xpd->id, i); - } - cur_chan->chanpos = i + 1; - cur_chan->pvt = xpd; - if (sigfxs) - cur_chan->sigcap = -#if 1 - ZT_SIG_FXSKS | - ZT_SIG_FXSLS | -#else - ZT_SIG_SF | -#endif - 0; - else - cur_chan->sigcap = -#if 1 - ZT_SIG_FXOKS | - ZT_SIG_FXOLS | - ZT_SIG_FXOGS | -#else - ZT_SIG_SF | - ZT_SIG_EM | -#endif - 0; - } + snprintf(span->name, MAX_SPANNAME, "%s/%s", xbus->busname, xpd->xpdname); span->deflaw = ZT_LAW_MULAW; init_waitqueue_head(&span->maintq); span->pvt = xpd; @@ -1394,22 +1355,21 @@ static int xpd_zaptel_register(xpd_t *xpd) #endif span->ioctl = xpp_ioctl; span->maint = xpp_maint; +#ifdef XPP_EC_CHUNK + span->echocan = xpp_echocan; +#endif #ifdef CONFIG_ZAPTEL_WATCHDOG span->watchdog = xpp_watchdog; #endif - DBG("Finished span_load: ZT_FLAG_RUNNING=%d\n", span->flags & ZT_FLAG_RUNNING); - DBG("Registering span of %s.\n", xpd->xpdname); + xpd->xops->card_zaptel_preregistration(xpd, 1); if(zt_register(&xpd->span, 1)) { xbus_t *xbus = xpd->xbus; - ERR("Failed to zt_register of span of xpd %s.\n", xpd->xpdname); - xbus->xpds[xpd->id] = NULL; - list_del(&xpd->xpd_list); - xbus->num_xpds--; + ERR("%s/%s: Failed to zt_register span\n", xbus->busname, xpd->xpdname); return -ENODEV; } - xpd->xops->card_zaptel_registration(xpd, 1); + xpd->xops->card_zaptel_postregistration(xpd, 1); return 0; } @@ -1498,7 +1458,7 @@ static ssize_t xpp_sys_write (struct file * file, const char __user * buf, if (copy_from_user (pack_tx->content.raw, buf, count)) { return -EFAULT; } - XPD_ADDR_SET(pack_tx->content.addr, xpdnum); + xpd_set_addr(&pack_tx->content.addr, xpdnum); pack_tx->datalen = count; // pack_tx->flags |= XPP_PACKET_FIREANDFORGET; DBG("sending op=%d to %d\n", pack_tx->content.opcode, xpdnum); @@ -1528,11 +1488,6 @@ static void do_cleanup(void) { if(timer_pending(&xpp_timer)) del_timer_sync(&xpp_timer); - if (xpp_worker) { - flush_workqueue(xpp_worker); - destroy_workqueue(xpp_worker); - xpp_worker = NULL; - } #if 0 unregister_chrdev(XPP_CTL_MAJOR, THIS_MODULE->name); #endif @@ -1582,12 +1537,6 @@ int __init xpp_zap_init(void) ent->write_proc = proc_sync_write; ent->data = NULL; #endif - xpp_worker = create_singlethread_workqueue("xppworker"); - if(!xpp_worker) { - ERR("Failed to create card detector workqueue.\n"); - do_cleanup(); - return -ENOMEM; - } ret = xbus_core_init(); if(ret) { ERR("xbus_core_init failed (%d)\n", ret); @@ -1621,6 +1570,7 @@ EXPORT_SYMBOL(xpd_alloc); EXPORT_SYMBOL(xpd_disconnect); EXPORT_SYMBOL(packet_send); EXPORT_SYMBOL(update_xpd_status); +EXPORT_SYMBOL(update_line_status); EXPORT_SYMBOL(fill_beep); EXPORT_SYMBOL(xpp_tick); EXPORT_SYMBOL(xpp_open); |