From 486c84923571900ad0f99f9db04b6dad3bdcb998 Mon Sep 17 00:00:00 2001 From: Tzafrir Cohen Date: Sun, 30 Jan 2011 14:11:49 +0000 Subject: xpp: prepare for phonedev refactor * Allow having XPDs that represent a device that is not a span. * Refactor all span related data from 'struct xpd' to 'struct phonedev' * Refactor span related methods into 'phonedev->phoneops' * Refactor phone related initialization into phonedev_init()/phonedev_cleanup() Signed-off-by: Oron Peled Acked-by: Tzafrir Cohen git-svn-id: http://svn.asterisk.org/svn/dahdi/linux/trunk@9704 a0bf4364-ded3-4de4-8d8a-66a801d63aff --- drivers/dahdi/xpp/card_bri.c | 105 ++++++++++---------- drivers/dahdi/xpp/card_fxo.c | 76 ++++++++------- drivers/dahdi/xpp/card_fxs.c | 144 ++++++++++++++-------------- drivers/dahdi/xpp/card_global.c | 2 +- drivers/dahdi/xpp/card_pri.c | 142 ++++++++++++++------------- drivers/dahdi/xpp/xbus-core.c | 6 +- drivers/dahdi/xpp/xbus-pcm.c | 74 +++++++-------- drivers/dahdi/xpp/xbus-sysfs.c | 4 +- drivers/dahdi/xpp/xdefs.h | 1 - drivers/dahdi/xpp/xpd.h | 56 ++++++----- drivers/dahdi/xpp/xpp_dahdi.c | 206 ++++++++++++++++++++++------------------ drivers/dahdi/xpp/xpp_dahdi.h | 4 +- drivers/dahdi/xpp/xproto.c | 21 ++-- drivers/dahdi/xpp/xproto.h | 29 +++--- 14 files changed, 469 insertions(+), 401 deletions(-) (limited to 'drivers/dahdi/xpp') diff --git a/drivers/dahdi/xpp/card_bri.c b/drivers/dahdi/xpp/card_bri.c index 39fe907..556d175 100644 --- a/drivers/dahdi/xpp/card_bri.c +++ b/drivers/dahdi/xpp/card_bri.c @@ -147,7 +147,7 @@ typedef union { #endif #define BRI_BCHAN_SIGCAP (DAHDI_SIG_CLEAR | DAHDI_SIG_DACS) -#define IS_NT(xpd) ((xpd)->direction == TO_PHONE) +#define IS_NT(xpd) (PHONEDEV(xpd).direction == TO_PHONE) #define BRI_PORT(xpd) ((xpd)->addr.subunit) /* shift in PCM highway */ @@ -732,7 +732,7 @@ static int tx_dchan(xpd_t *xpd) if(atomic_read(&priv->hdlc_pending) == 0) return 0; #endif - if(!SPAN_REGISTERED(xpd) || !(xpd->span.flags & DAHDI_FLAG_RUNNING)) + if(!SPAN_REGISTERED(xpd) || !(PHONEDEV(xpd).span.flags & DAHDI_FLAG_RUNNING)) return 0; dchan = XPD_CHAN(xpd, 2); len = ARRAY_SIZE(priv->dchan_tbuf); @@ -748,7 +748,7 @@ static int tx_dchan(xpd_t *xpd) } if(!test_bit(HFC_L1_ACTIVATED, &priv->l1_flags) && !test_bit(HFC_L1_ACTIVATING, &priv->l1_flags)) { XPD_DBG(SIGNAL, xpd, "Want to transmit: Kick D-Channel transmiter\n"); - if(xpd->direction == TO_PSTN) + if(! IS_NT(xpd)) te_activation(xpd, 1); else nt_activation(xpd, 1); @@ -825,7 +825,7 @@ static xpd_t *BRI_card_new(xbus_t *xbus, int unit, int subunit, const xproto_tab xpd = xpd_alloc(xbus, unit, subunit, subtype, subunits, sizeof(struct BRI_priv_data), proto_table, channels); if(!xpd) return NULL; - xpd->direction = (to_phone) ? TO_PHONE : TO_PSTN; + PHONEDEV(xpd).direction = (to_phone) ? TO_PHONE : TO_PSTN; xpd->type_name = (to_phone) ? "BRI_NT" : "BRI_TE"; if(bri_proc_create(xbus, xpd) < 0) goto err; @@ -898,10 +898,10 @@ static int BRI_card_dahdi_preregistration(xpd_t *xpd, bool on) /* Nothing to do yet */ return 0; } - xpd->span.spantype = "BRI"; - xpd->span.linecompat = DAHDI_CONFIG_AMI | DAHDI_CONFIG_CCS; - xpd->span.deflaw = DAHDI_LAW_ALAW; - BIT_SET(xpd->digital_signalling, 2); /* D-Channel */ + PHONEDEV(xpd).span.spantype = "BRI"; + PHONEDEV(xpd).span.linecompat = DAHDI_CONFIG_AMI | DAHDI_CONFIG_CCS; + PHONEDEV(xpd).span.deflaw = DAHDI_LAW_ALAW; + BIT_SET(PHONEDEV(xpd).digital_signalling, 2); /* D-Channel */ for_each_line(xpd, i) { struct dahdi_chan *cur_chan = XPD_CHAN(xpd, i); @@ -932,8 +932,8 @@ static int BRI_card_dahdi_preregistration(xpd_t *xpd, bool on) cur_chan->sigcap = BRI_BCHAN_SIGCAP; } } - CALL_XMETHOD(card_pcm_recompute, xbus, xpd, 0); - xpd->span.ops = &BRI_span_ops; + PHONE_METHOD(xpd, card_pcm_recompute)(xpd->xbus, xpd, 0); + PHONEDEV(xpd).span.ops = &BRI_span_ops; return 0; } @@ -1151,10 +1151,10 @@ static int BRI_card_open(xpd_t *xpd, lineno_t pos) priv = xpd->priv; if(pos == 2) { LINE_DBG(SIGNAL, xpd, pos, "OFFHOOK the whole span\n"); - BIT_SET(xpd->offhook_state, 0); - BIT_SET(xpd->offhook_state, 1); - BIT_SET(xpd->offhook_state, 2); - CALL_XMETHOD(card_pcm_recompute, xpd->xbus, xpd, 0); + BIT_SET(PHONEDEV(xpd).offhook_state, 0); + BIT_SET(PHONEDEV(xpd).offhook_state, 1); + BIT_SET(PHONEDEV(xpd).offhook_state, 2); + PHONE_METHOD(xpd, card_pcm_recompute)(xpd->xbus, xpd, 0); } return 0; } @@ -1173,10 +1173,10 @@ static int BRI_card_close(xpd_t *xpd, lineno_t pos) #endif if(pos == 2) { LINE_DBG(SIGNAL, xpd, pos, "ONHOOK the whole span\n"); - BIT_CLR(xpd->offhook_state, 0); - BIT_CLR(xpd->offhook_state, 1); - BIT_CLR(xpd->offhook_state, 2); - CALL_XMETHOD(card_pcm_recompute, xpd->xbus, xpd, 0); + BIT_CLR(PHONEDEV(xpd).offhook_state, 0); + BIT_CLR(PHONEDEV(xpd).offhook_state, 1); + BIT_CLR(PHONEDEV(xpd).offhook_state, 2); + PHONE_METHOD(xpd, card_pcm_recompute)(xpd->xbus, xpd, 0); } return 0; } @@ -1186,7 +1186,8 @@ static int BRI_card_close(xpd_t *xpd, lineno_t pos) */ static int bri_spanconfig(struct dahdi_span *span, struct dahdi_lineconfig *lc) { - xpd_t *xpd = container_of(span, struct xpd, span); + struct phonedev *phonedev = container_of(span, struct phonedev, span); + xpd_t *xpd = container_of(phonedev, struct xpd, phonedev); const char *framingstr = ""; const char *codingstr = ""; const char *crcstr = ""; @@ -1242,7 +1243,8 @@ static int bri_chanconfig(struct dahdi_chan *chan, int sigtype) */ static int bri_startup(struct dahdi_span *span) { - xpd_t *xpd = container_of(span, struct xpd, span); + struct phonedev *phonedev = container_of(span, struct phonedev, span); + xpd_t *xpd = container_of(phonedev, struct xpd, phonedev); struct BRI_priv_data *priv; struct dahdi_chan *dchan; @@ -1255,7 +1257,7 @@ static int bri_startup(struct dahdi_span *span) } XPD_DBG(GENERAL, xpd, "STARTUP\n"); // Turn on all channels - CALL_XMETHOD(XPD_STATE, xpd->xbus, xpd, 1); + PHONE_METHOD(xpd, XPD_STATE)(xpd->xbus, xpd, 1); if(SPAN_REGISTERED(xpd)) { dchan = XPD_CHAN(xpd, 2); span->flags |= DAHDI_FLAG_RUNNING; @@ -1278,7 +1280,8 @@ static int bri_startup(struct dahdi_span *span) */ static int bri_shutdown(struct dahdi_span *span) { - xpd_t *xpd = container_of(span, struct xpd, span); + struct phonedev *phonedev = container_of(span, struct phonedev, span); + xpd_t *xpd = container_of(phonedev, struct xpd, phonedev); struct BRI_priv_data *priv; BUG_ON(!xpd); @@ -1290,7 +1293,7 @@ static int bri_shutdown(struct dahdi_span *span) } XPD_DBG(GENERAL, xpd, "SHUTDOWN\n"); // Turn off all channels - CALL_XMETHOD(XPD_STATE, xpd->xbus, xpd, 0); + PHONE_METHOD(xpd, XPD_STATE)(xpd->xbus, xpd, 0); return 0; } @@ -1314,7 +1317,7 @@ static void BRI_card_pcm_recompute(xbus_t *xbus, xpd_t *xpd, * We calculate all subunits, so use the main lock * as a mutex for the whole operation. */ - spin_lock_irqsave(&main_xpd->lock_recompute_pcm, flags); + spin_lock_irqsave(&PHONEDEV(main_xpd).lock_recompute_pcm, flags); line_count = 0; pcm_mask = 0; for(i = 0; i < MAX_SUBUNIT; i++) { @@ -1322,7 +1325,7 @@ static void BRI_card_pcm_recompute(xbus_t *xbus, xpd_t *xpd, if(sub_xpd) { xpp_line_t lines = - sub_xpd->offhook_state & ~sub_xpd->digital_signalling; + PHONEDEV(sub_xpd).offhook_state & ~(PHONEDEV(sub_xpd).digital_signalling); if(lines) { pcm_mask |= PCM_SHIFT(lines, i); @@ -1349,7 +1352,7 @@ static void BRI_card_pcm_recompute(xbus_t *xbus, xpd_t *xpd, ? RPACKET_HEADERSIZE + sizeof(xpp_line_t) + line_count * DAHDI_CHUNKSIZE : 0L; update_wanted_pcm_mask(main_xpd, pcm_mask, pcm_len); - spin_unlock_irqrestore(&main_xpd->lock_recompute_pcm, flags); + spin_unlock_irqrestore(&PHONEDEV(main_xpd).lock_recompute_pcm, flags); } static void BRI_card_pcm_fromspan(xbus_t *xbus, xpd_t *xpd, xpacket_t *pack) @@ -1373,7 +1376,7 @@ static void BRI_card_pcm_fromspan(xbus_t *xbus, xpd_t *xpd, xpacket_t *pack) if(!tmp_xpd || !tmp_xpd->card_present) continue; spin_lock_irqsave(&tmp_xpd->lock, flags); - wanted_lines = tmp_xpd->wanted_pcm_mask; + wanted_lines = PHONEDEV(tmp_xpd).wanted_pcm_mask; for_each_line(tmp_xpd, i) { struct dahdi_chan *chan = XPD_CHAN(tmp_xpd, i); @@ -1452,7 +1455,7 @@ static /* 0x0F */ HOSTCMD(BRI, XPD_STATE, bool on) XPD_DBG(GENERAL, xpd, "%s\n", (on)?"ON":"OFF"); if(on) { if(!test_bit(HFC_L1_ACTIVATED, &priv->l1_flags)) { - if(xpd->direction == TO_PSTN) + if( ! IS_NT(xpd)) te_activation(xpd, 1); else nt_activation(xpd, 1); @@ -1645,7 +1648,7 @@ static int BRI_card_register_reply(xbus_t *xbus, xpd_t *xpd, reg_cmd_t *info) ret = rx_dchan(xpd, info); if (ret < 0) { priv->dchan_rx_drops++; - if(atomic_read(&xpd->open_counter) > 0) + if(atomic_read(&PHONEDEV(xpd).open_counter) > 0) XPD_NOTICE(xpd, "Multibyte Drop: errno=%d\n", ret); } goto end; @@ -1667,6 +1670,29 @@ end: return 0; } +static const struct xops bri_xops = { + .card_new = BRI_card_new, + .card_init = BRI_card_init, + .card_remove = BRI_card_remove, + .card_tick = BRI_card_tick, + .card_register_reply = BRI_card_register_reply, +}; + +static const struct phoneops bri_phoneops = { + .card_dahdi_preregistration = BRI_card_dahdi_preregistration, + .card_dahdi_postregistration = BRI_card_dahdi_postregistration, + .card_hooksig = BRI_card_hooksig, + .card_pcm_recompute = BRI_card_pcm_recompute, + .card_pcm_fromspan = BRI_card_pcm_fromspan, + .card_pcm_tospan = BRI_card_pcm_tospan, + .card_timing_priority = generic_timing_priority, + .card_ioctl = BRI_card_ioctl, + .card_open = BRI_card_open, + .card_close = BRI_card_close, + + .XPD_STATE = XPROTO_CALLER(BRI, XPD_STATE), +}; + static xproto_table_t PROTO_TABLE(BRI) = { .owner = THIS_MODULE, .entries = { @@ -1675,25 +1701,8 @@ static xproto_table_t PROTO_TABLE(BRI) = { .name = "BRI", /* protocol name */ .ports_per_subunit = 1, .type = XPD_TYPE_BRI, - .xops = { - .card_new = BRI_card_new, - .card_init = BRI_card_init, - .card_remove = BRI_card_remove, - .card_dahdi_preregistration = BRI_card_dahdi_preregistration, - .card_dahdi_postregistration = BRI_card_dahdi_postregistration, - .card_hooksig = BRI_card_hooksig, - .card_tick = BRI_card_tick, - .card_pcm_recompute = BRI_card_pcm_recompute, - .card_pcm_fromspan = BRI_card_pcm_fromspan, - .card_pcm_tospan = BRI_card_pcm_tospan, - .card_timing_priority = generic_timing_priority, - .card_ioctl = BRI_card_ioctl, - .card_open = BRI_card_open, - .card_close = BRI_card_close, - .card_register_reply = BRI_card_register_reply, - - .XPD_STATE = XPROTO_CALLER(BRI, XPD_STATE), - }, + .xops = &bri_xops, + .phoneops = &bri_phoneops, .packet_is_valid = bri_packet_is_valid, .packet_dump = bri_packet_dump, }; diff --git a/drivers/dahdi/xpp/card_fxo.c b/drivers/dahdi/xpp/card_fxo.c index 596cbc0..5ee41c5 100644 --- a/drivers/dahdi/xpp/card_fxo.c +++ b/drivers/dahdi/xpp/card_fxo.c @@ -215,7 +215,7 @@ static int do_led(xpd_t *xpd, lineno_t chan, byte which, bool on) xbus = xpd->xbus; priv = xpd->priv; which = which % NUM_LEDS; - if(IS_SET(xpd->digital_outputs, chan) || IS_SET(xpd->digital_inputs, chan)) + if(IS_SET(PHONEDEV(xpd).digital_outputs, chan) || IS_SET(PHONEDEV(xpd).digital_inputs, chan)) goto out; if(chan == PORT_BROADCAST) { priv->ledstate[which] = (on) ? ~0 : 0; @@ -251,7 +251,7 @@ static void handle_fxo_leds(xpd_t *xpd) timer_count = xpd->timer_count; for(color = 0; color < ARRAY_SIZE(colors); color++) { for_each_line(xpd, i) { - if(IS_SET(xpd->digital_outputs, i) || IS_SET(xpd->digital_inputs, i)) + if(IS_SET(PHONEDEV(xpd).digital_outputs, i) || IS_SET(PHONEDEV(xpd).digital_inputs, i)) continue; if((xpd->blink_mode & BIT(i)) || IS_BLINKING(priv, i, color)) { // Blinking int mod_value = LED_COUNTER(priv, i, color); @@ -302,16 +302,16 @@ static void mark_ring(xpd_t *xpd, lineno_t pos, bool on, bool update_dahdi) * due to voltage fluctuations. */ reset_battery_readings(xpd, pos); - if(on && !xpd->ringing[pos]) { + if(on && !PHONEDEV(xpd).ringing[pos]) { LINE_DBG(SIGNAL, xpd, pos, "START\n"); - xpd->ringing[pos] = 1; + PHONEDEV(xpd).ringing[pos] = 1; priv->cidtimer[pos] = xpd->timer_count; MARK_BLINK(priv, pos, LED_GREEN, LED_BLINK_RING); if(update_dahdi) update_dahdi_ring(xpd, pos, on); - } else if(!on && xpd->ringing[pos]) { + } else if(!on && PHONEDEV(xpd).ringing[pos]) { LINE_DBG(SIGNAL, xpd, pos, "STOP\n"); - xpd->ringing[pos] = 0; + PHONEDEV(xpd).ringing[pos] = 0; priv->cidtimer[pos] = xpd->timer_count; if(IS_BLINKING(priv, pos, LED_GREEN)) MARK_BLINK(priv, pos, LED_GREEN, 0); @@ -329,7 +329,7 @@ static int do_sethook(xpd_t *xpd, int pos, bool to_offhook) byte value; BUG_ON(!xpd); - BUG_ON(xpd->direction == TO_PHONE); // We can SETHOOK state only on PSTN + BUG_ON(PHONEDEV(xpd).direction == TO_PHONE); // We can SETHOOK state only on PSTN xbus = xpd->xbus; priv = xpd->priv; BUG_ON(!priv); @@ -443,7 +443,7 @@ static xpd_t *FXO_card_new(xbus_t *xbus, int unit, int subunit, const xproto_tab xpd = xpd_alloc(xbus, unit, subunit, subtype, subunits, sizeof(struct FXO_priv_data), proto_table, channels); if(!xpd) return NULL; - xpd->direction = TO_PSTN; + PHONEDEV(xpd).direction = TO_PSTN; xpd->type_name = "FXO"; if(fxo_proc_create(xbus, xpd) < 0) goto err; @@ -482,7 +482,7 @@ static int FXO_card_init(xbus_t *xbus, xpd_t *xpd) do_led(xpd, i, LED_GREEN, 0); msleep(50); } - CALL_XMETHOD(card_pcm_recompute, xbus, xpd, 0); + PHONE_METHOD(xpd, card_pcm_recompute)(xbus, xpd, 0); return 0; } @@ -511,6 +511,7 @@ static int FXO_card_dahdi_preregistration(xpd_t *xpd, bool on) BUG_ON(!priv); timer_count = xpd->timer_count; XPD_DBG(GENERAL, xpd, "%s\n", (on)?"ON":"OFF"); + PHONEDEV(xpd).span.spantype = "FXO"; for_each_line(xpd, i) { struct dahdi_chan *cur_chan = XPD_CHAN(xpd, i); @@ -562,7 +563,7 @@ static int FXO_card_hooksig(xbus_t *xbus, xpd_t *xpd, int pos, enum dahdi_txsig priv = xpd->priv; BUG_ON(!priv); LINE_DBG(SIGNAL, xpd, pos, "%s\n", txsig2str(txsig)); - BUG_ON(xpd->direction != TO_PSTN); + BUG_ON(PHONEDEV(xpd).direction != TO_PSTN); /* XXX Enable hooksig for FXO XXX */ switch(txsig) { case DAHDI_TXSIG_START: @@ -661,7 +662,7 @@ static void handle_fxo_power_denial(xpd_t *xpd) return; /* Ignore power denials */ priv = xpd->priv; for_each_line(xpd, i) { - if(xpd->ringing[i] || !IS_OFFHOOK(xpd, i)) { + if(PHONEDEV(xpd).ringing[i] || !IS_OFFHOOK(xpd, i)) { priv->power_denial_delay[i] = 0; continue; } @@ -726,7 +727,7 @@ static void check_etsi_dtmf(xpd_t *xpd) timer_count = xpd->timer_count; for_each_line(xpd, portno) { /* Skip offhook and ringing ports */ - if(IS_OFFHOOK(xpd, portno) || xpd->ringing[portno]) + if(IS_OFFHOOK(xpd, portno) || PHONEDEV(xpd).ringing[portno]) continue; if(IS_SET(priv->cidfound, portno)) { if(timer_count > priv->cidtimer[portno] + 4000) { @@ -900,7 +901,7 @@ static void update_battery_voltage(xpd_t *xpd, byte data_low, xportno_t portno) priv = xpd->priv; BUG_ON(!priv); priv->battery_voltage[portno] = volts; - if(xpd->ringing[portno]) + if(PHONEDEV(xpd).ringing[portno]) goto ignore_reading; /* ring voltage create false alarms */ if(abs(volts) < battery_threshold) { /* @@ -1017,7 +1018,7 @@ static void update_battery_current(xpd_t *xpd, byte data_low, xportno_t portno) * During ringing, current is not stable. * During onhook there should not be current anyway. */ - if(xpd->ringing[portno] || !IS_OFFHOOK(xpd, portno)) + if(PHONEDEV(xpd).ringing[portno] || !IS_OFFHOOK(xpd, portno)) goto ignore_it; /* * Power denial with no battery voltage is meaningless @@ -1110,6 +1111,27 @@ static int FXO_card_register_reply(xbus_t *xbus, xpd_t *xpd, reg_cmd_t *info) return 0; } +static const struct xops fxo_xops = { + .card_new = FXO_card_new, + .card_init = FXO_card_init, + .card_remove = FXO_card_remove, + .card_tick = FXO_card_tick, + .card_register_reply = FXO_card_register_reply, +}; + +static const struct phoneops fxo_phoneops = { + .card_dahdi_preregistration = FXO_card_dahdi_preregistration, + .card_dahdi_postregistration = FXO_card_dahdi_postregistration, + .card_hooksig = FXO_card_hooksig, + .card_pcm_recompute = generic_card_pcm_recompute, + .card_pcm_fromspan = generic_card_pcm_fromspan, + .card_pcm_tospan = generic_card_pcm_tospan, + .card_timing_priority = generic_timing_priority, + .card_ioctl = FXO_card_ioctl, + .card_open = FXO_card_open, + + .XPD_STATE = XPROTO_CALLER(FXO, XPD_STATE), +}; static xproto_table_t PROTO_TABLE(FXO) = { .owner = THIS_MODULE, @@ -1120,24 +1142,8 @@ static xproto_table_t PROTO_TABLE(FXO) = { .name = "FXO", /* protocol name */ .ports_per_subunit = 8, .type = XPD_TYPE_FXO, - .xops = { - .card_new = FXO_card_new, - .card_init = FXO_card_init, - .card_remove = FXO_card_remove, - .card_dahdi_preregistration = FXO_card_dahdi_preregistration, - .card_dahdi_postregistration = FXO_card_dahdi_postregistration, - .card_hooksig = FXO_card_hooksig, - .card_tick = FXO_card_tick, - .card_pcm_recompute = generic_card_pcm_recompute, - .card_pcm_fromspan = generic_card_pcm_fromspan, - .card_pcm_tospan = generic_card_pcm_tospan, - .card_timing_priority = generic_timing_priority, - .card_ioctl = FXO_card_ioctl, - .card_open = FXO_card_open, - .card_register_reply = FXO_card_register_reply, - - .XPD_STATE = XPROTO_CALLER(FXO, XPD_STATE), - }, + .xops = &fxo_xops, + .phoneops = &fxo_phoneops, .packet_is_valid = fxo_packet_is_valid, .packet_dump = fxo_packet_dump, }; @@ -1174,20 +1180,20 @@ static int proc_fxo_info_read(char *page, char **start, off_t off, int count, in BUG_ON(!priv); len += sprintf(page + len, "\t%-17s: ", "Channel"); for_each_line(xpd, i) { - if(!IS_SET(xpd->digital_outputs, i) && !IS_SET(xpd->digital_inputs, i)) + if(!IS_SET(PHONEDEV(xpd).digital_outputs, i) && !IS_SET(PHONEDEV(xpd).digital_inputs, i)) len += sprintf(page + len, "%4d ", i % 10); } len += sprintf(page + len, "\nLeds:"); len += sprintf(page + len, "\n\t%-17s: ", "state"); for_each_line(xpd, i) { - if(!IS_SET(xpd->digital_outputs, i) && !IS_SET(xpd->digital_inputs, i)) + if(!IS_SET(PHONEDEV(xpd).digital_outputs, i) && !IS_SET(PHONEDEV(xpd).digital_inputs, i)) len += sprintf(page + len, " %d%d ", IS_SET(priv->ledstate[LED_GREEN], i), IS_SET(priv->ledstate[LED_RED], i)); } len += sprintf(page + len, "\n\t%-17s: ", "blinking"); for_each_line(xpd, i) { - if(!IS_SET(xpd->digital_outputs, i) && !IS_SET(xpd->digital_inputs, i)) + if(!IS_SET(PHONEDEV(xpd).digital_outputs, i) && !IS_SET(PHONEDEV(xpd).digital_inputs, i)) len += sprintf(page + len, " %d%d ", IS_BLINKING(priv,i,LED_GREEN), IS_BLINKING(priv,i,LED_RED)); diff --git a/drivers/dahdi/xpp/card_fxs.c b/drivers/dahdi/xpp/card_fxs.c index 050833e..e3606b5 100644 --- a/drivers/dahdi/xpp/card_fxs.c +++ b/drivers/dahdi/xpp/card_fxs.c @@ -236,7 +236,7 @@ static int do_led(xpd_t *xpd, lineno_t chan, byte which, bool on) xbus = xpd->xbus; priv = xpd->priv; which = which % NUM_LEDS; - if(IS_SET(xpd->digital_outputs, chan) || IS_SET(xpd->digital_inputs, chan)) + if(IS_SET(PHONEDEV(xpd).digital_outputs, chan) || IS_SET(PHONEDEV(xpd).digital_inputs, chan)) goto out; if(chan == PORT_BROADCAST) { priv->ledstate[which] = (on) ? ~0 : 0; @@ -271,7 +271,7 @@ static void handle_fxs_leds(xpd_t *xpd) timer_count = xpd->timer_count; for(color = 0; color < ARRAY_SIZE(colors); color++) { for_each_line(xpd, i) { - if(IS_SET(xpd->digital_outputs | xpd->digital_inputs, i)) + if(IS_SET(PHONEDEV(xpd).digital_outputs | PHONEDEV(xpd).digital_inputs, i)) continue; if((xpd->blink_mode & BIT(i)) || IS_BLINKING(priv, i, color)) { // Blinking int mod_value = LED_COUNTER(priv, i, color); @@ -406,10 +406,10 @@ static xpd_t *FXS_card_new(xbus_t *xbus, int unit, int subunit, const xproto_tab return NULL; if(unit == 0) { XBUS_DBG(GENERAL, xbus, "First XPD detected. Initialize digital outputs/inputs\n"); - xpd->digital_outputs = BITMASK(LINES_DIGI_OUT) << regular_channels; - xpd->digital_inputs = BITMASK(LINES_DIGI_INP) << (regular_channels + LINES_DIGI_OUT); + PHONEDEV(xpd).digital_outputs = BITMASK(LINES_DIGI_OUT) << regular_channels; + PHONEDEV(xpd).digital_inputs = BITMASK(LINES_DIGI_INP) << (regular_channels + LINES_DIGI_OUT); } - xpd->direction = TO_PHONE; + PHONEDEV(xpd).direction = TO_PHONE; xpd->type_name = "FXS"; if(fxs_proc_create(xbus, xpd) < 0) goto err; @@ -455,14 +455,14 @@ static int FXS_card_init(xbus_t *xbus, xpd_t *xpd) msleep(50); } restore_leds(xpd); - CALL_XMETHOD(card_pcm_recompute, xbus, xpd, 0); + PHONE_METHOD(xpd, card_pcm_recompute)(xbus, xpd, 0); /* * We should query our offhook state long enough time after we * set the linefeed_control() * So we do this after the LEDs */ for_each_line(xpd, i) { - if(IS_SET(xpd->digital_outputs | xpd->digital_inputs, i)) + if(IS_SET(PHONEDEV(xpd).digital_outputs | PHONEDEV(xpd).digital_inputs, i)) continue; SLIC_DIRECT_REQUEST(xbus, xpd, i, SLIC_READ, REG_LOOPCLOSURE, 0); } @@ -496,15 +496,15 @@ static int FXS_card_dahdi_preregistration(xpd_t *xpd, bool on) priv = xpd->priv; BUG_ON(!priv); XPD_DBG(GENERAL, xpd, "%s\n", (on)?"on":"off"); - xpd->span.spantype = "FXS"; + PHONEDEV(xpd).span.spantype = "FXS"; for_each_line(xpd, i) { struct dahdi_chan *cur_chan = XPD_CHAN(xpd, i); XPD_DBG(GENERAL, xpd, "setting FXS channel %d\n", i); - if(IS_SET(xpd->digital_outputs, i)) { + if(IS_SET(PHONEDEV(xpd).digital_outputs, i)) { snprintf(cur_chan->name, MAX_CHANNAME, "XPP_OUT/%02d/%1d%1d/%d", xbus->num, xpd->addr.unit, xpd->addr.subunit, i); - } else if(IS_SET(xpd->digital_inputs, i)) { + } else if(IS_SET(PHONEDEV(xpd).digital_inputs, i)) { snprintf(cur_chan->name, MAX_CHANNAME, "XPP_IN/%02d/%1d%1d/%d", xbus->num, xpd->addr.unit, xpd->addr.subunit, i); } else { @@ -556,10 +556,10 @@ static void __do_mute_dtmf(xpd_t *xpd, int pos, bool muteit) { LINE_DBG(SIGNAL, xpd, pos, "%s\n", (muteit) ? "MUTE" : "UNMUTE"); if(muteit) - BIT_SET(xpd->mute_dtmf, pos); + BIT_SET(PHONEDEV(xpd).mute_dtmf, pos); else - BIT_CLR(xpd->mute_dtmf, pos); - CALL_XMETHOD(card_pcm_recompute, xpd->xbus, xpd, 0); /* already spinlocked */ + BIT_CLR(PHONEDEV(xpd).mute_dtmf, pos); + PHONE_METHOD(xpd, card_pcm_recompute)(xpd->xbus, xpd, 0); /* already spinlocked */ } static int set_vm_led_mode(xbus_t *xbus, xpd_t *xpd, int pos, @@ -607,10 +607,10 @@ static void start_stop_vm_led(xbus_t *xbus, xpd_t *xpd, lineno_t pos) unsigned int msgs; BUG_ON(!xpd); - if (IS_SET(xpd->digital_outputs | xpd->digital_inputs, pos)) + if (IS_SET(PHONEDEV(xpd).digital_outputs | PHONEDEV(xpd).digital_inputs, pos)) return; priv = xpd->priv; - msgs = xpd->msg_waiting[pos]; + msgs = PHONEDEV(xpd).msg_waiting[pos]; LINE_DBG(SIGNAL, xpd, pos, "%s\n", (msgs) ? "ON" : "OFF"); set_vm_led_mode(xbus, xpd, pos, msgs); do_chan_power(xbus, xpd, pos, msgs > 0); @@ -671,8 +671,8 @@ static int FXS_card_hooksig(xbus_t *xbus, xpd_t *xpd, int pos, enum dahdi_txsig LINE_DBG(SIGNAL, xpd, pos, "%s\n", txsig2str(txsig)); priv = xpd->priv; - BUG_ON(xpd->direction != TO_PHONE); - if (IS_SET(xpd->digital_inputs, pos)) { + BUG_ON(PHONEDEV(xpd).direction != TO_PHONE); + if (IS_SET(PHONEDEV(xpd).digital_inputs, pos)) { LINE_DBG(SIGNAL, xpd, pos, "Ignoring signal sent to digital input line\n"); return 0; } @@ -681,14 +681,14 @@ static int FXS_card_hooksig(xbus_t *xbus, xpd_t *xpd, int pos, enum dahdi_txsig switch(txsig) { case DAHDI_TXSIG_ONHOOK: spin_lock_irqsave(&xpd->lock, flags); - xpd->ringing[pos] = 0; + PHONEDEV(xpd).ringing[pos] = 0; oht_pcm(xpd, pos, 0); vmwi_search(xpd, pos, 0); BIT_CLR(priv->want_dtmf_events, pos); BIT_CLR(priv->want_dtmf_mute, pos); __do_mute_dtmf(xpd, pos, 0); spin_unlock_irqrestore(&xpd->lock, flags); - if(IS_SET(xpd->digital_outputs, pos)) { + if(IS_SET(PHONEDEV(xpd).digital_outputs, pos)) { LINE_DBG(SIGNAL, xpd, pos, "%s -> digital output OFF\n", txsig2str(txsig)); ret = relay_out(xpd, pos, 0); return ret; @@ -721,16 +721,16 @@ static int FXS_card_hooksig(xbus_t *xbus, xpd_t *xpd, int pos, enum dahdi_txsig ret = linefeed_control(xbus, xpd, pos, txhook); break; case DAHDI_TXSIG_OFFHOOK: - if(IS_SET(xpd->digital_outputs, pos)) { + if(IS_SET(PHONEDEV(xpd).digital_outputs, pos)) { LINE_NOTICE(xpd, pos, "%s -> Is digital output. Ignored\n", txsig2str(txsig)); return -EINVAL; } txhook = priv->lasttxhook[pos]; - if(xpd->ringing[pos]) { + if(PHONEDEV(xpd).ringing[pos]) { oht_pcm(xpd, pos, 1); txhook = FXS_LINE_OHTRANS; } - xpd->ringing[pos] = 0; + PHONEDEV(xpd).ringing[pos] = 0; if(chan) { switch(chan->sig) { case DAHDI_SIG_EM: @@ -744,10 +744,10 @@ static int FXS_card_hooksig(xbus_t *xbus, xpd_t *xpd, int pos, enum dahdi_txsig ret = linefeed_control(xbus, xpd, pos, txhook); break; case DAHDI_TXSIG_START: - xpd->ringing[pos] = 1; + PHONEDEV(xpd).ringing[pos] = 1; oht_pcm(xpd, pos, 0); vmwi_search(xpd, pos, 0); - if(IS_SET(xpd->digital_outputs, pos)) { + if(IS_SET(PHONEDEV(xpd).digital_outputs, pos)) { LINE_DBG(SIGNAL, xpd, pos, "%s -> digital output ON\n", txsig2str(txsig)); ret = relay_out(xpd, pos, 1); return ret; @@ -755,7 +755,7 @@ static int FXS_card_hooksig(xbus_t *xbus, xpd_t *xpd, int pos, enum dahdi_txsig ret = send_ring(xpd, pos, 1); // RING on break; case DAHDI_TXSIG_KEWL: - if(IS_SET(xpd->digital_outputs, pos)) { + if(IS_SET(PHONEDEV(xpd).digital_outputs, pos)) { LINE_DBG(SIGNAL, xpd, pos, "%s -> Is digital output. Ignored\n", txsig2str(txsig)); return -EINVAL; } @@ -807,7 +807,7 @@ static int set_vmwi(xpd_t *xpd, int pos, unsigned long arg) ; /* Disable VMWI */ } priv->vmwisetting[pos] = vmwisetting; - set_vm_led_mode(xpd->xbus, xpd, pos, xpd->msg_waiting[pos]); + set_vm_led_mode(xpd->xbus, xpd, pos, PHONEDEV(xpd).msg_waiting[pos]); return 0; } @@ -829,7 +829,7 @@ static int FXS_card_ioctl(xpd_t *xpd, int pos, unsigned int cmd, unsigned long a BUG_ON(!xbus); if(!XBUS_IS(xbus, READY)) return -ENODEV; - if (pos < 0 || pos >= xpd->channels) { + if (pos < 0 || pos >= PHONEDEV(xpd).channels) { XPD_NOTICE(xpd, "Bad channel number %d in %s(), cmd=%u\n", pos, __FUNCTION__, cmd); return -EINVAL; @@ -840,15 +840,15 @@ static int FXS_card_ioctl(xpd_t *xpd, int pos, unsigned int cmd, unsigned long a if (get_user(val, (int __user *)arg)) return -EFAULT; LINE_DBG(SIGNAL, xpd, pos, "DAHDI_ONHOOKTRANSFER (%d millis)\n", val); - if (IS_SET(xpd->digital_inputs | xpd->digital_outputs, pos)) + if (IS_SET(PHONEDEV(xpd).digital_inputs | PHONEDEV(xpd).digital_outputs, pos)) return 0; /* Nothing to do */ oht_pcm(xpd, pos, 1); /* Get ready of VMWI FSK tones */ if(priv->lasttxhook[pos] == FXS_LINE_POL_ACTIVE) { priv->ohttimer[pos] = val; priv->idletxhookstate[pos] = FXS_LINE_POL_OHTRANS; vmwi_search(xpd, pos, 1); - CALL_XMETHOD(card_pcm_recompute, xbus, xpd, priv->search_fsk_pattern); - LINE_DBG(SIGNAL, xpd, pos, "Start OHT_TIMER. wanted_pcm_mask=0x%X\n", xpd->wanted_pcm_mask); + PHONE_METHOD(xpd, card_pcm_recompute)(xbus, xpd, priv->search_fsk_pattern); + LINE_DBG(SIGNAL, xpd, pos, "Start OHT_TIMER. wanted_pcm_mask=0x%X\n", PHONEDEV(xpd).wanted_pcm_mask); } if (VMWI_NEON(priv, pos) && !IS_OFFHOOK(xpd, pos)) start_stop_vm_led(xbus, xpd, pos); @@ -935,9 +935,9 @@ static int FXS_card_ioctl(xpd_t *xpd, int pos, unsigned int cmd, unsigned long a return 0; } /* Digital inputs/outputs don't have VM leds */ - if (IS_SET(xpd->digital_inputs | xpd->digital_outputs, pos)) + if (IS_SET(PHONEDEV(xpd).digital_inputs | PHONEDEV(xpd).digital_outputs, pos)) return 0; - xpd->msg_waiting[pos] = val; + PHONEDEV(xpd).msg_waiting[pos] = val; LINE_DBG(SIGNAL, xpd, pos, "DAHDI_VMWI: %s\n", (val) ? "yes" : "no"); return 0; @@ -1065,11 +1065,11 @@ static void detect_vmwi(xpd_t *xpd) priv = xpd->priv; BUG_ON(!priv); ignore_mask = - xpd->offhook_state | - ~xpd->oht_pcm_pass | - ~priv->search_fsk_pattern | - xpd->digital_inputs | - xpd->digital_outputs; + PHONEDEV(xpd).offhook_state | + ~(PHONEDEV(xpd).oht_pcm_pass) | + ~(priv->search_fsk_pattern) | + PHONEDEV(xpd).digital_inputs | + PHONEDEV(xpd).digital_outputs; for_each_line(xpd, i) { struct dahdi_chan *chan = XPD_CHAN(xpd, i); byte *writechunk = chan->writechunk; @@ -1097,11 +1097,11 @@ static void detect_vmwi(xpd_t *xpd) oht_pcm(xpd, i, 0); if(unlikely(mem_equal(writechunk, FSK_ON_PATTERN, DAHDI_CHUNKSIZE))) { LINE_DBG(SIGNAL, xpd, i, "MSG WAITING ON\n"); - xpd->msg_waiting[i] = 1; + PHONEDEV(xpd).msg_waiting[i] = 1; start_stop_vm_led(xbus, xpd, i); } else if(unlikely(mem_equal(writechunk, FSK_OFF_PATTERN, DAHDI_CHUNKSIZE))) { LINE_DBG(SIGNAL, xpd, i, "MSG WAITING OFF\n"); - xpd->msg_waiting[i] = 0; + PHONEDEV(xpd).msg_waiting[i] = 0; start_stop_vm_led(xbus, xpd, i); } else { int j; @@ -1179,15 +1179,15 @@ static void process_hookstate(xpd_t *xpd, xpp_line_t offhook, xpp_line_t change_ int i; BUG_ON(!xpd); - BUG_ON(xpd->direction != TO_PHONE); + BUG_ON(PHONEDEV(xpd).direction != TO_PHONE); xbus = xpd->xbus; priv = xpd->priv; XPD_DBG(SIGNAL, xpd, "offhook=0x%X change_mask=0x%X\n", offhook, change_mask); for_each_line(xpd, i) { - if(IS_SET(xpd->digital_outputs, i) || IS_SET(xpd->digital_inputs, i)) + if(IS_SET(PHONEDEV(xpd).digital_outputs, i) || IS_SET(PHONEDEV(xpd).digital_inputs, i)) continue; if(IS_SET(change_mask, i)) { - xpd->ringing[i] = 0; /* No more ringing... */ + PHONEDEV(xpd).ringing[i] = 0; /* No more ringing... */ #ifdef WITH_METERING metering_gen(xpd, i, 0); /* Stop metering... */ #endif @@ -1222,7 +1222,7 @@ HANDLER_DEF(FXS, SIG_CHANGED) unsigned long flags; BUG_ON(!xpd); - BUG_ON(xpd->direction != TO_PHONE); + BUG_ON(PHONEDEV(xpd).direction != TO_PHONE); XPD_DBG(SIGNAL, xpd, "(PHONE) sig_toggles=0x%04X sig_status=0x%04X\n", sig_toggles, sig_status); #if 0 Is this needed? @@ -1250,10 +1250,10 @@ static void process_digital_inputs(xpd_t *xpd, const reg_cmd_t *info) int newchanno; if(IS_SET(lines, channo)) { - newchanno = xpd->channels - LINES_DIGI_INP + i; + newchanno = PHONEDEV(xpd).channels - LINES_DIGI_INP + i; BIT_CLR(lines, channo); BIT_SET(lines, newchanno); - xpd->ringing[newchanno] = 0; // Stop ringing. No leds for digital inputs. + PHONEDEV(xpd).ringing[newchanno] = 0; // Stop ringing. No leds for digital inputs. if(offhook && !IS_OFFHOOK(xpd, newchanno)) { // OFFHOOK LINE_DBG(SIGNAL, xpd, newchanno, "OFFHOOK\n"); hookstate_changed(xpd, newchanno, 1); @@ -1394,6 +1394,29 @@ static int FXS_card_register_reply(xbus_t *xbus, xpd_t *xpd, reg_cmd_t *info) return 0; } +static const struct xops fxs_xops = { + .card_new = FXS_card_new, + .card_init = FXS_card_init, + .card_remove = FXS_card_remove, + .card_tick = FXS_card_tick, + .card_register_reply = FXS_card_register_reply, +}; + +static const struct phoneops fxs_phoneops = { + .card_dahdi_preregistration = FXS_card_dahdi_preregistration, + .card_dahdi_postregistration = FXS_card_dahdi_postregistration, + .card_hooksig = FXS_card_hooksig, + .card_pcm_recompute = generic_card_pcm_recompute, + .card_pcm_fromspan = generic_card_pcm_fromspan, + .card_pcm_tospan = generic_card_pcm_tospan, + .card_timing_priority = generic_timing_priority, + .card_open = FXS_card_open, + .card_close = FXS_card_close, + .card_ioctl = FXS_card_ioctl, + + .XPD_STATE = XPROTO_CALLER(FXS, XPD_STATE), +}; + static xproto_table_t PROTO_TABLE(FXS) = { .owner = THIS_MODULE, .entries = { @@ -1403,25 +1426,8 @@ static xproto_table_t PROTO_TABLE(FXS) = { .name = "FXS", /* protocol name */ .ports_per_subunit = 8, .type = XPD_TYPE_FXS, - .xops = { - .card_new = FXS_card_new, - .card_init = FXS_card_init, - .card_remove = FXS_card_remove, - .card_dahdi_preregistration = FXS_card_dahdi_preregistration, - .card_dahdi_postregistration = FXS_card_dahdi_postregistration, - .card_hooksig = FXS_card_hooksig, - .card_tick = FXS_card_tick, - .card_pcm_recompute = generic_card_pcm_recompute, - .card_pcm_fromspan = generic_card_pcm_fromspan, - .card_pcm_tospan = generic_card_pcm_tospan, - .card_timing_priority = generic_timing_priority, - .card_open = FXS_card_open, - .card_close = FXS_card_close, - .card_ioctl = FXS_card_ioctl, - .card_register_reply = FXS_card_register_reply, - - .XPD_STATE = XPROTO_CALLER(FXS, XPD_STATE), - }, + .xops = &fxs_xops, + .phoneops = &fxs_phoneops, .packet_is_valid = fxs_packet_is_valid, .packet_dump = fxs_packet_dump, }; @@ -1466,9 +1472,9 @@ static int proc_fxs_info_read(char *page, char **start, off_t off, int count, in for_each_line(xpd, i) { char pref; - if(IS_SET(xpd->digital_outputs, i)) + if(IS_SET(PHONEDEV(xpd).digital_outputs, i)) pref = 'O'; - else if(IS_SET(xpd->digital_inputs, i)) + else if(IS_SET(PHONEDEV(xpd).digital_inputs, i)) pref = 'I'; else pref = ' '; @@ -1485,17 +1491,17 @@ static int proc_fxs_info_read(char *page, char **start, off_t off, int count, in len += sprintf(page + len, "LED #%d", led); len += sprintf(page + len, "\n\t%-17s: ", "ledstate"); for_each_line(xpd, i) { - if(!IS_SET(xpd->digital_outputs, i) && !IS_SET(xpd->digital_inputs, i)) + if(!IS_SET(PHONEDEV(xpd).digital_outputs, i) && !IS_SET(PHONEDEV(xpd).digital_inputs, i)) len += sprintf(page + len, "%d ", IS_SET(priv->ledstate[led], i)); } len += sprintf(page + len, "\n\t%-17s: ", "ledcontrol"); for_each_line(xpd, i) { - if(!IS_SET(xpd->digital_outputs, i) && !IS_SET(xpd->digital_inputs, i)) + if(!IS_SET(PHONEDEV(xpd).digital_outputs, i) && !IS_SET(PHONEDEV(xpd).digital_inputs, i)) len += sprintf(page + len, "%d ", IS_SET(priv->ledcontrol[led], i)); } len += sprintf(page + len, "\n\t%-17s: ", "led_counter"); for_each_line(xpd, i) { - if(!IS_SET(xpd->digital_outputs, i) && !IS_SET(xpd->digital_inputs, i)) + if(!IS_SET(PHONEDEV(xpd).digital_outputs, i) && !IS_SET(PHONEDEV(xpd).digital_inputs, i)) len += sprintf(page + len, "%d ", LED_COUNTER(priv,i,led)); } len += sprintf(page + len, "\n"); diff --git a/drivers/dahdi/xpp/card_global.c b/drivers/dahdi/xpp/card_global.c index e731560..ecb79fd 100644 --- a/drivers/dahdi/xpp/card_global.c +++ b/drivers/dahdi/xpp/card_global.c @@ -820,7 +820,7 @@ int run_initialize_registers(xpd_t *xpd) xpd->subunits, i); continue; } - direction_mask |= (su->direction == TO_PHONE) ? BIT(i) : 0; + direction_mask |= (PHONEDEV(su).direction == TO_PHONE) ? BIT(i) : 0; } snprintf(busstr, MAX_ENV_STR, "XBUS_NAME=%s", xbus->busname); snprintf(busnumstr, MAX_ENV_STR, "XBUS_NUMBER=%d", xbus->num); diff --git a/drivers/dahdi/xpp/card_pri.c b/drivers/dahdi/xpp/card_pri.c index 9dd22e9..7e91d2d 100644 --- a/drivers/dahdi/xpp/card_pri.c +++ b/drivers/dahdi/xpp/card_pri.c @@ -563,10 +563,10 @@ static void PRI_card_pcm_recompute(xbus_t *xbus, xpd_t *xpd, BUG_ON(!xpd); priv = xpd->priv; - spin_lock_irqsave(&xpd->lock_recompute_pcm, flags); + spin_lock_irqsave(&PHONEDEV(xpd).lock_recompute_pcm, flags); //XPD_DBG(SIGNAL, xpd, "pcm_mask=0x%X\n", pcm_mask); /* Add/remove all the trivial cases */ - pcm_mask |= xpd->offhook_state; + pcm_mask |= PHONEDEV(xpd).offhook_state; for_each_line(xpd, i) if (IS_SET(pcm_mask, i)) line_count++; @@ -590,7 +590,7 @@ static void PRI_card_pcm_recompute(xbus_t *xbus, xpd_t *xpd, line_count * DAHDI_CHUNKSIZE : 0L; update_wanted_pcm_mask(xpd, pcm_mask, pcm_len); - spin_unlock_irqrestore(&xpd->lock_recompute_pcm, flags); + spin_unlock_irqrestore(&PHONEDEV(xpd).lock_recompute_pcm, flags); } /* @@ -610,7 +610,7 @@ static int set_pri_proto(xpd_t *xpd, enum pri_protocol set_proto) priv = xpd->priv; if(SPAN_REGISTERED(xpd)) { XPD_NOTICE(xpd, "Registered as span %d. Cannot do setup pri protocol (%s)\n", - xpd->span.spanno, __FUNCTION__); + PHONEDEV(xpd).span.spanno, __FUNCTION__); return -EBUSY; } if(priv->pri_protocol != PRI_PROTO_0) { @@ -650,16 +650,16 @@ static int set_pri_proto(xpd_t *xpd, enum pri_protocol set_proto) } priv->pri_protocol = set_proto; priv->is_cas = -1; - xpd->channels = pri_num_channels(set_proto); - xpd->offhook_state = BITMASK(xpd->channels); - CALL_XMETHOD(card_pcm_recompute, xpd->xbus, xpd, 0); + PHONEDEV(xpd).channels = pri_num_channels(set_proto); + PHONEDEV(xpd).offhook_state = BITMASK(PHONEDEV(xpd).channels); + PHONE_METHOD(xpd, card_pcm_recompute)(xpd->xbus, xpd, 0); priv->deflaw = deflaw; priv->dchan_num = dchan_num; priv->local_loopback = 0; xpd->type_name = type_name(priv->pri_protocol); XPD_DBG(GENERAL, xpd, "%s, channels=%d, dchan_num=%d, deflaw=%d\n", pri_protocol_name(set_proto), - xpd->channels, + PHONEDEV(xpd).channels, priv->dchan_num, priv->deflaw ); @@ -692,18 +692,18 @@ static void dahdi_update_syncsrc(xpd_t *xpd) if(priv->clock_source && priv->alarms == 0) { if(best_spanno) XPD_ERR(xpd, "Duplicate XPD's with clock_source=1\n"); - best_spanno = subxpd->span.spanno; + best_spanno = PHONEDEV(subxpd).span.spanno; } } for(i = 0; i < MAX_SLAVES; i++) { subxpd = xpd_byaddr(xpd->xbus, xpd->addr.unit, i); if(!subxpd) continue; - if(subxpd->span.syncsrc == best_spanno) + if(PHONEDEV(subxpd).span.syncsrc == best_spanno) XPD_DBG(SYNC, xpd, "Setting SyncSource to span %d\n", best_spanno); else XPD_DBG(SYNC, xpd, "Slaving to span %d\n", best_spanno); - subxpd->span.syncsrc = best_spanno; + PHONEDEV(subxpd).span.syncsrc = best_spanno; } } @@ -734,10 +734,10 @@ static void set_clocking(xpd_t *xpd) priv = subxpd->priv; if(priv->alarms != 0) continue; - if(subxpd->timing_priority > 0 && subxpd->timing_priority < best_subunit_prio) { + if(PHONEDEV(subxpd).timing_priority > 0 && PHONEDEV(subxpd).timing_priority < best_subunit_prio) { best_xpd = subxpd; best_subunit = i; - best_subunit_prio = subxpd->timing_priority; + best_subunit_prio = PHONEDEV(subxpd).timing_priority; } } /* Now set it */ @@ -779,7 +779,7 @@ static void set_reg_lim0(const char *msg, xpd_t *xpd) BUG_ON(!xpd); priv = xpd->priv; BUG_ON(!priv); - is_master_mode = xpd->timing_priority == 0; + is_master_mode = PHONEDEV(xpd).timing_priority == 0; localloop = priv->local_loopback; lim0 |= (localloop) ? REG_LIM0_LL : 0; if(is_master_mode) @@ -819,7 +819,7 @@ static int set_localloop(xpd_t *xpd, bool localloop) priv = xpd->priv; if(SPAN_REGISTERED(xpd)) { XPD_NOTICE(xpd, "Registered as span %d. Cannot do %s\n", - xpd->span.spanno, __FUNCTION__); + PHONEDEV(xpd).span.spanno, __FUNCTION__); return -EBUSY; } priv->local_loopback = localloop; @@ -869,7 +869,7 @@ static void set_rbslines(xpd_t *xpd, int channo) else BIT_SET(new_rbslines, i); } - new_rbslines &= BITMASK(xpd->channels); + new_rbslines &= BITMASK(PHONEDEV(xpd).channels); modified_lines = priv->rbslines ^ new_rbslines; XPD_DBG(DEVICES, xpd, "RBSLINES-%d(%s): 0x%X\n", channo, pri_protocol_name(priv->pri_protocol), new_rbslines); @@ -1037,7 +1037,7 @@ static int pri_lineconfig(xpd_t *xpd, int lineconfig) force_cas = 1; set_mode_cas(xpd, 1); } - CALL_XMETHOD(card_pcm_recompute, xpd->xbus, xpd, 0); + PHONE_METHOD(xpd, card_pcm_recompute)(xpd->xbus, xpd, 0); /* * E1's can enable CRC checking * CRC4 is legal only for E1, and it is checked by pri_linecompat() @@ -1092,15 +1092,16 @@ bad_lineconfig: static int pri_spanconfig(struct dahdi_span *span, struct dahdi_lineconfig *lc) { - xpd_t *xpd = container_of(span, struct xpd, span); + struct phonedev *phonedev = container_of(span, struct phonedev, span); + xpd_t *xpd = container_of(phonedev, struct xpd, phonedev); struct PRI_priv_data *priv; int ret; BUG_ON(!xpd); priv = xpd->priv; - if(lc->span != xpd->span.spanno) { + if(lc->span != PHONEDEV(xpd).span.spanno) { XPD_ERR(xpd, "I am span %d but got spanconfig for span %d\n", - xpd->span.spanno, lc->span); + PHONEDEV(xpd).span.spanno, lc->span); return -EINVAL; } /* @@ -1112,7 +1113,7 @@ static int pri_spanconfig(struct dahdi_span *span, struct dahdi_lineconfig *lc) ret = pri_lineconfig(xpd, lc->lineconfig); if(!ret) { span->lineconfig = lc->lineconfig; - xpd->timing_priority = lc->sync; + PHONEDEV(xpd).timing_priority = lc->sync; set_master_mode("spanconfig", xpd); elect_syncer("PRI-master_mode"); } @@ -1126,7 +1127,8 @@ static int pri_spanconfig(struct dahdi_span *span, struct dahdi_lineconfig *lc) */ static int pri_chanconfig(struct dahdi_chan *chan, int sigtype) { - xpd_t *xpd = container_of(chan->span, struct xpd, span); + struct phonedev *phonedev = container_of(chan->span, struct phonedev, span); + xpd_t *xpd = container_of(phonedev, struct xpd, phonedev); struct PRI_priv_data *priv; BUG_ON(!xpd); @@ -1158,7 +1160,7 @@ static int pri_chanconfig(struct dahdi_chan *chan, int sigtype) if(priv->pri_protocol != PRI_PROTO_E1 && priv->is_cas != 1) set_mode_cas(xpd, 1); } - if(xpd->span.flags & DAHDI_FLAG_RUNNING) { + if(PHONEDEV(xpd).span.flags & DAHDI_FLAG_RUNNING) { XPD_DBG(DEVICES, xpd, "Span is RUNNING. Updating rbslines.\n"); set_rbslines(xpd, chan->channo); } @@ -1227,9 +1229,9 @@ static int PRI_card_init(xbus_t *xbus, xpd_t *xpd) goto err; } xpd->type_name = type_name(priv->pri_protocol); - xpd->direction = TO_PSTN; + PHONEDEV(xpd).direction = TO_PSTN; XPD_DBG(DEVICES, xpd, "%s\n", xpd->type_name); - xpd->timing_priority = 1; /* High priority SLAVE */ + PHONEDEV(xpd).timing_priority = 1; /* High priority SLAVE */ set_master_mode(__FUNCTION__, xpd); for(ret = 0; ret < NUM_LEDS; ret++) { DO_LED(xpd, ret, PRI_LED_ON); @@ -1308,15 +1310,15 @@ static int PRI_card_dahdi_preregistration(xpd_t *xpd, bool on) XPD_DBG(GENERAL, xpd, "%s (proto=%s, channels=%d, deflaw=%d)\n", (on)?"on":"off", pri_protocol_name(priv->pri_protocol), - xpd->channels, + PHONEDEV(xpd).channels, priv->deflaw); if(!on) { /* Nothing to do yet */ return 0; } - xpd->span.spantype = pri_protocol_name(priv->pri_protocol); - xpd->span.linecompat = pri_linecompat(priv->pri_protocol); - xpd->span.deflaw = priv->deflaw; + PHONEDEV(xpd).span.spantype = pri_protocol_name(priv->pri_protocol); + PHONEDEV(xpd).span.linecompat = pri_linecompat(priv->pri_protocol); + PHONEDEV(xpd).span.deflaw = priv->deflaw; for_each_line(xpd, i) { struct dahdi_chan *cur_chan = XPD_CHAN(xpd, i); bool is_dchan = i == PRI_DCHAN_IDX(priv); @@ -1333,8 +1335,8 @@ static int PRI_card_dahdi_preregistration(xpd_t *xpd, bool on) cur_chan->flags &= ~DAHDI_FLAG_HDLC; } } - xpd->offhook_state = xpd->wanted_pcm_mask; - xpd->span.ops = &PRI_span_ops; + PHONEDEV(xpd).offhook_state = PHONEDEV(xpd).wanted_pcm_mask; + PHONEDEV(xpd).span.ops = &PRI_span_ops; return 0; } @@ -1372,7 +1374,7 @@ static void dchan_state(xpd_t *xpd, bool up) } else { int d = PRI_DCHAN_IDX(priv); - if(SPAN_REGISTERED(xpd) && d >= 0 && d < xpd->channels) { + if(SPAN_REGISTERED(xpd) && d >= 0 && d < PHONEDEV(xpd).channels) { byte *pcm; pcm = (byte *)XPD_CHAN(xpd, d)->readchunk; @@ -1406,7 +1408,7 @@ static void handle_leds(xbus_t *xbus, xpd_t *xpd) BUG_ON(!xpd); priv = xpd->priv; BUG_ON(!priv); - if(xpd->timing_priority == 0) { + if(PHONEDEV(xpd).timing_priority == 0) { which_led = TOP_RED_LED; other_led = BOTTOM_GREEN_LED; } else { @@ -1530,7 +1532,8 @@ static int PRI_card_close(xpd_t *xpd, lineno_t pos) */ static int pri_startup(struct dahdi_span *span) { - xpd_t *xpd = container_of(span, struct xpd, span); + struct phonedev *phonedev = container_of(span, struct phonedev, span); + xpd_t *xpd = container_of(phonedev, struct xpd, phonedev); struct PRI_priv_data *priv; BUG_ON(!xpd); @@ -1542,7 +1545,7 @@ static int pri_startup(struct dahdi_span *span) } XPD_DBG(GENERAL, xpd, "STARTUP\n"); // Turn on all channels - CALL_XMETHOD(XPD_STATE, xpd->xbus, xpd, 1); + PHONE_METHOD(xpd, XPD_STATE)(xpd->xbus, xpd, 1); set_rbslines(xpd, 0); write_subunit(xpd, REG_XPM2, 0x00); return 0; @@ -1553,7 +1556,8 @@ static int pri_startup(struct dahdi_span *span) */ static int pri_shutdown(struct dahdi_span *span) { - xpd_t *xpd = container_of(span, struct xpd, span); + struct phonedev *phonedev = container_of(span, struct phonedev, span); + xpd_t *xpd = container_of(phonedev, struct xpd, phonedev); struct PRI_priv_data *priv; BUG_ON(!xpd); @@ -1565,7 +1569,7 @@ static int pri_shutdown(struct dahdi_span *span) } XPD_DBG(GENERAL, xpd, "SHUTDOWN\n"); // Turn off all channels - CALL_XMETHOD(XPD_STATE, xpd->xbus, xpd, 0); + PHONE_METHOD(xpd, XPD_STATE)(xpd->xbus, xpd, 0); return 0; } @@ -1614,7 +1618,7 @@ static int encode_rbsbits_t1(xpd_t *xpd, int pos, int bits) priv = xpd->priv; BUG_ON(!priv); BUG_ON(priv->pri_protocol != PRI_PROTO_T1); - if(pos < 0 || pos >= xpd->channels) { + if(pos < 0 || pos >= PHONEDEV(xpd).channels) { XPD_ERR(xpd, "%s: Bad pos=%d\n", __FUNCTION__, pos); return 0; } @@ -1741,7 +1745,7 @@ static void PRI_card_pcm_fromspan(xbus_t *xbus, xpd_t *xpd, xpacket_t *pack) BUG_ON(!priv); pcm = RPACKET_FIELD(pack, GLOBAL, PCM_WRITE, pcm); spin_lock_irqsave(&xpd->lock, flags); - wanted_lines = xpd->wanted_pcm_mask; + wanted_lines = PHONEDEV(xpd).wanted_pcm_mask; physical_chan = 0; for_each_line(xpd, i) { struct dahdi_chan *chan = XPD_CHAN(xpd, i); @@ -1858,7 +1862,7 @@ int PRI_timing_priority(xbus_t *xbus, xpd_t *xpd) priv = xpd->priv; BUG_ON(!priv); if (priv->layer1_up) - return xpd->timing_priority; + return PHONEDEV(xpd).timing_priority; XPD_DBG(SYNC, xpd, "No timing priority (no layer1)\n"); return -ENOENT; } @@ -1937,24 +1941,24 @@ static void layer1_state(xpd_t *xpd, byte data_low) query_subunit(xpd, regbase + i); } - if(SPAN_REGISTERED(xpd) && xpd->span.alarms != alarms) { + if(SPAN_REGISTERED(xpd) && PHONEDEV(xpd).span.alarms != alarms) { char str1[MAX_PROC_WRITE]; char str2[MAX_PROC_WRITE]; - alarm2str(xpd->span.alarms, str1, sizeof(str1)); + alarm2str(PHONEDEV(xpd).span.alarms, str1, sizeof(str1)); alarm2str(alarms, str2, sizeof(str2)); XPD_NOTICE(xpd, "Alarms: 0x%X (%s) => 0x%X (%s)\n", - xpd->span.alarms, str1, + PHONEDEV(xpd).span.alarms, str1, alarms, str2); if (priv->is_cas) { if (alarms == DAHDI_ALARM_NONE) send_oldbits(xpd); - else if (xpd->span.alarms == DAHDI_ALARM_NONE) + else if (PHONEDEV(xpd).span.alarms == DAHDI_ALARM_NONE) send_idlebits(xpd, 1); } - xpd->span.alarms = alarms; + PHONEDEV(xpd).span.alarms = alarms; elect_syncer("LAYER1"); - dahdi_alarm_notify(&xpd->span); + dahdi_alarm_notify(&PHONEDEV(xpd).span); set_clocking(xpd); } priv->reg_frs0 = data_low; @@ -1980,14 +1984,14 @@ static int decode_cas_e1(xpd_t *xpd, byte regnum, byte data_low) XPD_ERR(xpd, "%s: got bad pos=%d [0-%d]\n", __FUNCTION__, pos, NUM_CAS_RS_E); return -EINVAL; } - if(chan1 < 0 || chan1 > xpd->channels) { + if(chan1 < 0 || chan1 > PHONEDEV(xpd).channels) { XPD_NOTICE(xpd, "%s: %s CAS: Bad chan1 number (%d)\n", __FUNCTION__, pri_protocol_name(priv->pri_protocol), chan1); return -EINVAL; } - if(chan2 < 0 || chan2 > xpd->channels) { + if(chan2 < 0 || chan2 > PHONEDEV(xpd).channels) { XPD_NOTICE(xpd, "%s: %s CAS: Bad chan2 number (%d)\n", __FUNCTION__, pri_protocol_name(priv->pri_protocol), @@ -2038,7 +2042,7 @@ static int decode_cas_t1(xpd_t *xpd, byte regnum, byte data_low) if (!priv->is_esf) rxsig <<= 2; pos = rsnum * chan_per_reg + chan_per_reg - i - 1; - if(pos < 0 || pos >= xpd->channels) { + if(pos < 0 || pos >= PHONEDEV(xpd).channels) { XPD_ERR(xpd, "%s: Bad pos=%d\n", __FUNCTION__, pos); continue; } @@ -2165,6 +2169,27 @@ end: return 0; } +static const struct xops pri_xops = { + .card_new = PRI_card_new, + .card_init = PRI_card_init, + .card_remove = PRI_card_remove, + .card_tick = PRI_card_tick, + .card_register_reply = PRI_card_register_reply, +}; + +static const struct phoneops pri_phoneops = { + .card_dahdi_preregistration = PRI_card_dahdi_preregistration, + .card_dahdi_postregistration = PRI_card_dahdi_postregistration, + .card_pcm_recompute = PRI_card_pcm_recompute, + .card_pcm_fromspan = PRI_card_pcm_fromspan, + .card_pcm_tospan = PRI_card_pcm_tospan, + .card_timing_priority = PRI_timing_priority, + .card_ioctl = PRI_card_ioctl, + .card_close = PRI_card_close, + + .XPD_STATE = XPROTO_CALLER(PRI, XPD_STATE), +}; + static xproto_table_t PROTO_TABLE(PRI) = { .owner = THIS_MODULE, .entries = { @@ -2173,23 +2198,8 @@ static xproto_table_t PROTO_TABLE(PRI) = { .name = "PRI", /* protocol name */ .ports_per_subunit = 1, .type = XPD_TYPE_PRI, - .xops = { - .card_new = PRI_card_new, - .card_init = PRI_card_init, - .card_remove = PRI_card_remove, - .card_dahdi_preregistration = PRI_card_dahdi_preregistration, - .card_dahdi_postregistration = PRI_card_dahdi_postregistration, - .card_tick = PRI_card_tick, - .card_pcm_recompute = PRI_card_pcm_recompute, - .card_pcm_fromspan = PRI_card_pcm_fromspan, - .card_pcm_tospan = PRI_card_pcm_tospan, - .card_timing_priority = PRI_timing_priority, - .card_ioctl = PRI_card_ioctl, - .card_close = PRI_card_close, - .card_register_reply = PRI_card_register_reply, - - .XPD_STATE = XPROTO_CALLER(PRI, XPD_STATE), - }, + .xops = &pri_xops, + .phoneops = &pri_phoneops, .packet_is_valid = pri_packet_is_valid, .packet_dump = pri_packet_dump, }; diff --git a/drivers/dahdi/xpp/xbus-core.c b/drivers/dahdi/xpp/xbus-core.c index ebc7cba..b0c3261 100644 --- a/drivers/dahdi/xpp/xbus-core.c +++ b/drivers/dahdi/xpp/xbus-core.c @@ -784,7 +784,6 @@ static int new_card(xbus_t *xbus, byte port_dir) { const xproto_table_t *proto_table; - const xops_t *xops; int i; int subunits; int ret = 0; @@ -810,8 +809,7 @@ static int new_card(xbus_t *xbus, subunits, port_dir ); - xops = &proto_table->xops; - BUG_ON(!xops); + BUG_ON(!proto_table->phoneops); xbus->worker.num_units += subunits - 1; for(i = 0; i < subunits; i++) { int subunit_ports = proto_table->ports_per_subunit; @@ -915,7 +913,7 @@ static int xpd_initialize(xpd_t *xpd) } //CALL_XMETHOD(XPD_STATE, xpd->xbus, xpd, 0); /* Turn off all channels */ xpd->card_present = 1; - CALL_XMETHOD(XPD_STATE, xpd->xbus, xpd, 1); /* Turn on all channels */ + PHONE_METHOD(xpd, XPD_STATE)(xpd->xbus, xpd, 1); /* Turn on all channels */ if(!xpd_setstate(xpd, XPD_STATE_READY)) { goto out; } diff --git a/drivers/dahdi/xpp/xbus-pcm.c b/drivers/dahdi/xpp/xbus-pcm.c index ccd28ee..e63e533 100644 --- a/drivers/dahdi/xpp/xbus-pcm.c +++ b/drivers/dahdi/xpp/xbus-pcm.c @@ -496,7 +496,8 @@ static void global_tick(void) #ifdef DAHDI_SYNC_TICK void dahdi_sync_tick(struct dahdi_span *span, int is_master) { - xpd_t *xpd = container_of(span, struct xpd, span); + struct phonedev *phonedev = container_of(span, struct phonedev, span); + xpd_t *xpd = container_of(phonedev, struct xpd, phonedev); static int redundant_ticks; /* for extra spans */ struct timeval now; @@ -629,8 +630,7 @@ void elect_syncer(const char *msg) if(!xpd || !xpd->card_present) continue; - prio = CALL_XMETHOD(card_timing_priority, - xbus, xpd); + prio = PHONE_METHOD(xpd, card_timing_priority)(xbus, xpd); if (prio < 0) { DBG(SYNC, "%s/%s: skip sync\n", xbus->busname, xpd->xpdname); @@ -668,10 +668,10 @@ void elect_syncer(const char *msg) */ void update_wanted_pcm_mask(xpd_t *xpd, xpp_line_t new_mask, uint new_pcm_len) { - xpd->pcm_len = new_pcm_len; - xpd->wanted_pcm_mask = new_mask; + PHONEDEV(xpd).pcm_len = new_pcm_len; + PHONEDEV(xpd).wanted_pcm_mask = new_mask; XPD_DBG(SIGNAL, xpd, "pcm_len=%d wanted_pcm_mask=0x%X\n", - xpd->pcm_len, xpd->wanted_pcm_mask); + PHONEDEV(xpd).pcm_len, PHONEDEV(xpd).wanted_pcm_mask); } /* @@ -686,13 +686,13 @@ void generic_card_pcm_recompute(xbus_t *xbus, xpd_t *xpd, xpp_line_t pcm_mask) unsigned long flags; uint pcm_len; - spin_lock_irqsave(&xpd->lock_recompute_pcm, flags); + spin_lock_irqsave(&PHONEDEV(xpd).lock_recompute_pcm, flags); //XPD_DBG(SIGNAL, xpd, "pcm_mask=0x%X\n", pcm_mask); /* Add/remove all the trivial cases */ - pcm_mask |= xpd->offhook_state; - pcm_mask |= xpd->oht_pcm_pass; - pcm_mask &= ~xpd->digital_inputs; - pcm_mask &= ~xpd->digital_outputs; + pcm_mask |= PHONEDEV(xpd).offhook_state; + pcm_mask |= PHONEDEV(xpd).oht_pcm_pass; + pcm_mask &= ~(PHONEDEV(xpd).digital_inputs); + pcm_mask &= ~(PHONEDEV(xpd).digital_outputs); for_each_line(xpd, i) if(IS_SET(pcm_mask, i)) line_count++; @@ -708,7 +708,7 @@ void generic_card_pcm_recompute(xbus_t *xbus, xpd_t *xpd, xpp_line_t pcm_mask) ? RPACKET_HEADERSIZE + sizeof(xpp_line_t) + line_count * DAHDI_CHUNKSIZE : 0L; update_wanted_pcm_mask(xpd, pcm_mask, pcm_len); - spin_unlock_irqrestore(&xpd->lock_recompute_pcm, flags); + spin_unlock_irqrestore(&PHONEDEV(xpd).lock_recompute_pcm, flags); } void fill_beep(u_char *buf, int num, int duration) @@ -741,16 +741,16 @@ static void do_ec(xpd_t *xpd) { int i; - for (i = 0;i < xpd->span.channels; i++) { + for (i = 0;i < PHONEDEV(xpd).span.channels; i++) { struct dahdi_chan *chan = XPD_CHAN(xpd, i); - if(unlikely(IS_SET(xpd->digital_signalling, i))) /* Don't echo cancel BRI D-chans */ + if(unlikely(IS_SET(PHONEDEV(xpd).digital_signalling, i))) /* Don't echo cancel BRI D-chans */ continue; - if(!IS_SET(xpd->wanted_pcm_mask, i)) /* No ec for unwanted PCM */ + if(!IS_SET(PHONEDEV(xpd).wanted_pcm_mask, i)) /* No ec for unwanted PCM */ continue; - dahdi_ec_chunk(chan, chan->readchunk, xpd->ec_chunk2[i]); - memcpy(xpd->ec_chunk2[i], xpd->ec_chunk1[i], DAHDI_CHUNKSIZE); - memcpy(xpd->ec_chunk1[i], chan->writechunk, DAHDI_CHUNKSIZE); + dahdi_ec_chunk(chan, chan->readchunk, PHONEDEV(xpd).ec_chunk2[i]); + memcpy(PHONEDEV(xpd).ec_chunk2[i], PHONEDEV(xpd).ec_chunk1[i], DAHDI_CHUNKSIZE); + memcpy(PHONEDEV(xpd).ec_chunk1[i], chan->writechunk, DAHDI_CHUNKSIZE); } } @@ -864,11 +864,11 @@ void generic_card_pcm_fromspan(xbus_t *xbus, xpd_t *xpd, xpacket_t *pack) BUG_ON(!xbus); BUG_ON(!xpd); BUG_ON(!pack); - wanted_lines = xpd->wanted_pcm_mask; + wanted_lines = PHONEDEV(xpd).wanted_pcm_mask; RPACKET_FIELD(pack, GLOBAL, PCM_WRITE, lines) = wanted_lines; pcm = RPACKET_FIELD(pack, GLOBAL, PCM_WRITE, pcm); spin_lock_irqsave(&xpd->lock, flags); - for (i = 0; i < xpd->channels; i++) { + for (i = 0; i < PHONEDEV(xpd).channels; i++) { struct dahdi_chan *chan = XPD_CHAN(xpd, i); if(IS_SET(wanted_lines, i)) { @@ -904,11 +904,11 @@ void generic_card_pcm_tospan(xbus_t *xbus, xpd_t *xpd, xpacket_t *pack) /* * Calculate the channels we want to mute */ - pcm_mute = ~xpd->wanted_pcm_mask; - pcm_mute |= xpd->mute_dtmf | xpd->silence_pcm; + pcm_mute = ~(PHONEDEV(xpd).wanted_pcm_mask); + pcm_mute |= PHONEDEV(xpd).mute_dtmf | PHONEDEV(xpd).silence_pcm; if(!SPAN_REGISTERED(xpd)) goto out; - for (i = 0; i < xpd->channels; i++) { + for (i = 0; i < PHONEDEV(xpd).channels; i++) { volatile u_char *r = XPD_CHAN(xpd, i)->readchunk; bool got_data = IS_SET(pcm_mask, i); @@ -916,16 +916,16 @@ void generic_card_pcm_tospan(xbus_t *xbus, xpd_t *xpd, xpacket_t *pack) /* We have and want real data */ // memset((u_char *)r, 0x5A, DAHDI_CHUNKSIZE); // DEBUG memcpy((u_char *)r, pcm, DAHDI_CHUNKSIZE); - } else if(IS_SET(xpd->wanted_pcm_mask | xpd->silence_pcm, i)) { + } else if(IS_SET(PHONEDEV(xpd).wanted_pcm_mask | PHONEDEV(xpd).silence_pcm, i)) { /* Inject SILENCE */ memset((u_char *)r, 0x7F, DAHDI_CHUNKSIZE); - if(IS_SET(xpd->silence_pcm, i)) { + if(IS_SET(PHONEDEV(xpd).silence_pcm, i)) { /* * This will clear the EC buffers until next tick * So we don't have noise residues from the past. */ - memset(xpd->ec_chunk2[i], 0x7F, DAHDI_CHUNKSIZE); - memset(xpd->ec_chunk1[i], 0x7F, DAHDI_CHUNKSIZE); + memset(PHONEDEV(xpd).ec_chunk2[i], 0x7F, DAHDI_CHUNKSIZE); + memset(PHONEDEV(xpd).ec_chunk1[i], 0x7F, DAHDI_CHUNKSIZE); } } if(got_data) @@ -993,7 +993,7 @@ static int copy_pcm_tospan(xbus_t *xbus, xframe_t *xframe) goto out; if(SPAN_REGISTERED(xpd)) { XBUS_COUNTER(xbus, RX_PACK_PCM)++; - CALL_XMETHOD(card_pcm_tospan, xbus, xpd, pack); + PHONE_METHOD(xpd, card_pcm_tospan)(xbus, xpd, pack); } } while(p < xframe_end); ret = 0; /* all good */ @@ -1005,7 +1005,7 @@ out: int generic_timing_priority(xbus_t *xbus, xpd_t *xpd) { - return xpd->timing_priority; + return PHONEDEV(xpd).timing_priority; } static void xbus_tick(xbus_t *xbus) @@ -1024,10 +1024,10 @@ static void xbus_tick(xbus_t *xbus) if(xpd && SPAN_REGISTERED(xpd)) { #ifdef OPTIMIZE_CHANMUTE int j; - xpp_line_t xmit_mask = xpd->wanted_pcm_mask; + xpp_line_t xmit_mask = PHONEDEV(xpd).wanted_pcm_mask; - xmit_mask |= xpd->silence_pcm; - xmit_mask |= xpd->digital_signalling; + xmit_mask |= PHONEDEV(xpd).silence_pcm; + xmit_mask |= PHONEDEV(xpd).digital_signalling; for_each_line(xpd, j) { XPD_CHAN(xpd, j)->chanmute = (optimize_chanmute) ? !IS_SET(xmit_mask, j) @@ -1038,7 +1038,7 @@ static void xbus_tick(xbus_t *xbus) * calls to dahdi_transmit should be out of spinlocks, as it may call back * our hook setting methods. */ - dahdi_transmit(&xpd->span); + dahdi_transmit(&PHONEDEV(xpd).span); } } /* @@ -1049,7 +1049,7 @@ static void xbus_tick(xbus_t *xbus) if((xpd = xpd_of(xbus, i)) == NULL) continue; - pcm_len = xpd->pcm_len; + pcm_len = PHONEDEV(xpd).pcm_len; if(SPAN_REGISTERED(xpd)) { if(pcm_len && xpd->card_present) { do { @@ -1079,7 +1079,7 @@ static void xbus_tick(xbus_t *xbus) XPACKET_ADDR_SYNC(pack) = 1; sent_sync_bit = 1; } - CALL_XMETHOD(card_pcm_fromspan, xbus, xpd, pack); + PHONE_METHOD(xpd, card_pcm_fromspan)(xbus, xpd, pack); XBUS_COUNTER(xbus, TX_PACK_PCM)++; } } @@ -1120,9 +1120,9 @@ static void xbus_tick(xbus_t *xbus) continue; if(SPAN_REGISTERED(xpd)) { do_ec(xpd); - dahdi_receive(&xpd->span); + dahdi_receive(&PHONEDEV(xpd).span); } - xpd->silence_pcm = 0; /* silence was injected */ + PHONEDEV(xpd).silence_pcm = 0; /* silence was injected */ xpd->timer_count = xbus->global_counter; /* * Must be called *after* tx/rx so diff --git a/drivers/dahdi/xpp/xbus-sysfs.c b/drivers/dahdi/xpp/xbus-sysfs.c index e1278df..b9d3e3d 100644 --- a/drivers/dahdi/xpp/xbus-sysfs.c +++ b/drivers/dahdi/xpp/xbus-sysfs.c @@ -621,7 +621,7 @@ static DEVICE_ATTR_READER(span_show, dev, buf) if(!xpd) return -ENODEV; spin_lock_irqsave(&xpd->lock, flags); - len += sprintf(buf, "%d\n", SPAN_REGISTERED(xpd) ? xpd->span.spanno : 0); + len += sprintf(buf, "%d\n", SPAN_REGISTERED(xpd) ? PHONEDEV(xpd).span.spanno : 0); spin_unlock_irqrestore(&xpd->lock, flags); return len; } @@ -693,7 +693,7 @@ static DEVICE_ATTR_READER(timing_priority_show, dev, buf) if(!xpd) return -ENODEV; spin_lock_irqsave(&xpd->lock, flags); - len += sprintf(buf + len, "%d\n", xpd->timing_priority); + len += sprintf(buf + len, "%d\n", PHONEDEV(xpd).timing_priority); spin_unlock_irqrestore(&xpd->lock, flags); return len; } diff --git a/drivers/dahdi/xpp/xdefs.h b/drivers/dahdi/xpp/xdefs.h index 24b2291..c296698 100644 --- a/drivers/dahdi/xpp/xdefs.h +++ b/drivers/dahdi/xpp/xdefs.h @@ -159,7 +159,6 @@ typedef struct xbus xbus_t; typedef struct xpd xpd_t; typedef struct xframe xframe_t; typedef struct xpacket xpacket_t; -typedef struct xops xops_t; typedef __u32 xpp_line_t; /* at most 31 lines for E1 */ typedef byte lineno_t; typedef byte xportno_t; diff --git a/drivers/dahdi/xpp/xpd.h b/drivers/dahdi/xpp/xpd.h index 04d6713..52bef64 100644 --- a/drivers/dahdi/xpp/xpd.h +++ b/drivers/dahdi/xpp/xpd.h @@ -149,21 +149,15 @@ enum xpd_state { bool xpd_setstate(xpd_t *xpd, enum xpd_state newstate); const char *xpd_statename(enum xpd_state st); -/* - * An XPD is a single Xorcom Protocol Device - */ -struct xpd { - char xpdname[XPD_NAMELEN]; +#define PHONEDEV(xpd) ((xpd)->phonedev) + +struct phonedev { + const struct phoneops *phoneops; /* Card level operations */ struct dahdi_span span; struct dahdi_chan *chans[32]; -#define XPD_CHAN(xpd,chan) ((xpd)->chans[(chan)]) - +#define XPD_CHAN(xpd,chan) (PHONEDEV(xpd).chans[(chan)]) int channels; - xpd_type_t type; - const char *type_name; - byte subtype; xpd_direction_t direction; /* TO_PHONE, TO_PSTN */ - int subunits; /* all siblings */ 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 oht_pcm_pass; /* Transfer on-hook PCM */ @@ -174,12 +168,6 @@ struct xpd { xpp_line_t digital_signalling; /* BRI signalling channels */ uint timing_priority; /* from 'span' directives in chan_dahdi.conf */ - enum xpd_state xpd_state; - struct device xpd_dev; -#define dev_to_xpd(dev) container_of(dev, struct xpd, xpd_dev) - struct kref kref; -#define kref_to_xpd(k) container_of(k, struct xpd, kref) - /* Assure atomicity of changes to pcm_len and wanted_pcm_mask */ spinlock_t lock_recompute_pcm; /* maintained by card drivers */ @@ -190,11 +178,35 @@ struct xpd { bool ringing[CHANNELS_PERXPD]; + atomic_t dahdi_registered; /* Am I fully registered with dahdi */ + atomic_t open_counter; /* Number of open channels */ + + /* Echo cancelation */ + u_char ec_chunk1[CHANNELS_PERXPD][DAHDI_CHUNKSIZE]; + u_char ec_chunk2[CHANNELS_PERXPD][DAHDI_CHUNKSIZE]; +}; + +/* + * An XPD is a single Xorcom Protocol Device + */ +struct xpd { + char xpdname[XPD_NAMELEN]; + struct phonedev phonedev; + + const struct xops *xops; + xpd_type_t type; + const char *type_name; + byte subtype; + int subunits; /* all siblings */ + enum xpd_state xpd_state; + struct device xpd_dev; +#define dev_to_xpd(dev) container_of(dev, struct xpd, xpd_dev) + struct kref kref; +#define kref_to_xpd(k) container_of(k, struct xpd, kref) + xbus_t *xbus; /* The XBUS we are connected to */ spinlock_t lock; - atomic_t dahdi_registered; /* Am I fully registered with dahdi */ - atomic_t open_counter; /* Number of open channels */ int flags; unsigned long blink_mode; /* bitmask of blinking ports */ @@ -213,7 +225,6 @@ struct xpd { int counters[XPD_COUNTER_MAX]; const xproto_table_t *xproto; /* Card level protocol table */ - const xops_t *xops; /* Card level operations */ void *priv; /* Card level private data */ bool card_present; reg_cmd_t requested_reply; @@ -224,12 +235,9 @@ struct xpd { struct xpd_addr addr; struct list_head xpd_list; unsigned int timer_count; - /* Echo cancelation */ - u_char ec_chunk1[CHANNELS_PERXPD][DAHDI_CHUNKSIZE]; - u_char ec_chunk2[CHANNELS_PERXPD][DAHDI_CHUNKSIZE]; }; -#define for_each_line(xpd,i) for((i) = 0; (i) < (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 TICK_TOLERANCE 500 /* usec */ diff --git a/drivers/dahdi/xpp/xpp_dahdi.c b/drivers/dahdi/xpp/xpp_dahdi.c index 43dda58..c5e2f6f 100644 --- a/drivers/dahdi/xpp/xpp_dahdi.c +++ b/drivers/dahdi/xpp/xpp_dahdi.c @@ -251,9 +251,9 @@ void xpd_free(xpd_t *xpd) XPD_DBG(DEVICES, xpd, "\n"); xpd_proc_remove(xbus, xpd); xbus_xpd_unbind(xbus, xpd); - for (x = 0; x < xpd->channels; x++) { - if (xpd->chans[x]) - KZFREE(xpd->chans[x]); + for (x = 0; x < PHONEDEV(xpd).channels; x++) { + if (PHONEDEV(xpd).chans[x]) + KZFREE(PHONEDEV(xpd).chans[x]); } KZFREE(xpd); DBG(DEVICES, "refcount_xbus=%d\n", refcount_xbus(xbus)); @@ -293,7 +293,7 @@ int create_xpd(xbus_t *xbus, const xproto_table_t *proto_table, subunit_ports, unit, subunit); return 0; } - xpd = proto_table->xops.card_new(xbus, unit, subunit, proto_table, subtype, subunits, subunit_ports, to_phone); + xpd = proto_table->xops->card_new(xbus, unit, subunit, proto_table, subtype, subunits, subunit_ports, to_phone); if(!xpd) { XBUS_NOTICE(xbus, "card_new(%d,%d,%d,%d,%d) failed. Ignored.\n", unit, subunit, proto_table->type, subtype, to_phone); @@ -337,28 +337,28 @@ static int xpd_read_proc(char *page, char **start, off_t off, int count, int *eo , xpd->xpdname, xpd->type_name, (xpd->card_present) ? "present" : "missing", - (SPAN_REGISTERED(xpd)) ? xpd->span.spanno : 0, - xpd->timing_priority, - xpd->timer_count, xpd->span.mainttimer + (SPAN_REGISTERED(xpd)) ? PHONEDEV(xpd).span.spanno : 0, + PHONEDEV(xpd).timing_priority, + xpd->timer_count, PHONEDEV(xpd).span.mainttimer ); len += sprintf(page + len, "xpd_state: %s (%d)\n", xpd_statename(xpd->xpd_state), xpd->xpd_state); len += sprintf(page + len, "open_counter=%d refcount=%d\n", - atomic_read(&xpd->open_counter), refcount_xpd(xpd)); + atomic_read(&PHONEDEV(xpd).open_counter), refcount_xpd(xpd)); len += sprintf(page + len, "Address: U=%d S=%d\n", xpd->addr.unit, xpd->addr.subunit); len += sprintf(page + len, "Subunits: %d\n", xpd->subunits); len += sprintf(page + len, "Type: %d.%d\n\n", xpd->type, xpd->subtype); - len += sprintf(page + len, "pcm_len=%d\n\n", xpd->pcm_len); - len += sprintf(page + len, "wanted_pcm_mask=0x%04X\n\n", xpd->wanted_pcm_mask); - len += sprintf(page + len, "mute_dtmf=0x%04X\n\n", xpd->mute_dtmf); + len += sprintf(page + len, "pcm_len=%d\n\n", PHONEDEV(xpd).pcm_len); + len += sprintf(page + len, "wanted_pcm_mask=0x%04X\n\n", PHONEDEV(xpd).wanted_pcm_mask); + len += sprintf(page + len, "mute_dtmf=0x%04X\n\n", PHONEDEV(xpd).mute_dtmf); len += sprintf(page + len, "STATES:"); 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)); + len += sprintf(page + len, "%d ", IS_SET(PHONEDEV(xpd).digital_outputs, i)); } len += sprintf(page + len, "\n\t%-17s: ", "input_relays"); for_each_line(xpd, i) { - len += sprintf(page + len, "%d ", IS_SET(xpd->digital_inputs, i)); + len += sprintf(page + len, "%d ", IS_SET(PHONEDEV(xpd).digital_inputs, i)); } len += sprintf(page + len, "\n\t%-17s: ", "offhook"); for_each_line(xpd, i) { @@ -366,19 +366,19 @@ static int xpd_read_proc(char *page, char **start, off_t off, int count, int *eo } len += sprintf(page + len, "\n\t%-17s: ", "oht_pcm_pass"); for_each_line(xpd, i) { - len += sprintf(page + len, "%d ", IS_SET(xpd->oht_pcm_pass, i)); + len += sprintf(page + len, "%d ", IS_SET(PHONEDEV(xpd).oht_pcm_pass, i)); } len += sprintf(page + len, "\n\t%-17s: ", "msg_waiting"); for_each_line(xpd, i) { - len += sprintf(page + len, "%d ", xpd->msg_waiting[i]); + len += sprintf(page + len, "%d ", PHONEDEV(xpd).msg_waiting[i]); } len += sprintf(page + len, "\n\t%-17s: ", "ringing"); for_each_line(xpd, i) { - len += sprintf(page + len, "%d ", xpd->ringing[i]); + len += sprintf(page + len, "%d ", PHONEDEV(xpd).ringing[i]); } len += sprintf(page + len, "\n\t%-17s: ", "no_pcm"); for_each_line(xpd, i) { - len += sprintf(page + len, "%d ", IS_SET(xpd->no_pcm, i)); + len += sprintf(page + len, "%d ", IS_SET(PHONEDEV(xpd).no_pcm, i)); } #if 1 if(SPAN_REGISTERED(xpd)) { @@ -391,11 +391,11 @@ static int xpd_read_proc(char *page, char **start, off_t off, int count, int *eo byte *wp; int j; - if(IS_SET(xpd->digital_outputs, i)) + if(IS_SET(PHONEDEV(xpd).digital_outputs, i)) continue; - if(IS_SET(xpd->digital_inputs, i)) + if(IS_SET(PHONEDEV(xpd).digital_inputs, i)) continue; - if(IS_SET(xpd->digital_signalling, i)) + if(IS_SET(PHONEDEV(xpd).digital_signalling, i)) continue; rp = chan->readchunk; wp = chan->writechunk; @@ -410,9 +410,9 @@ static int xpd_read_proc(char *page, char **start, off_t off, int count, int *eo len += sprintf(page + len, "%02X ", wchunk[j]); } len += sprintf(page + len, " | %c", - (IS_SET(xpd->wanted_pcm_mask, i))?'+':' '); + (IS_SET(PHONEDEV(xpd).wanted_pcm_mask, i))?'+':' '); len += sprintf(page + len, " %c", - (IS_SET(xpd->mute_dtmf, i))?'-':' '); + (IS_SET(PHONEDEV(xpd).mute_dtmf, i))?'-':' '); } } #endif @@ -502,6 +502,48 @@ badstate: } +/* + * Cleanup/initialize phonedev + */ +static void phonedev_cleanup(xpd_t *xpd) +{ + struct phonedev *phonedev = &PHONEDEV(xpd); + unsigned int x; + + for (x = 0; x < phonedev->channels; x++) { + if (phonedev->chans[x]) { + kfree(phonedev->chans[x]); + } + } +} + +__must_check static int phonedev_init(xpd_t *xpd, const xproto_table_t *proto_table, + int channels, xpp_line_t no_pcm) +{ + struct phonedev *phonedev = &PHONEDEV(xpd); + unsigned int x; + + spin_lock_init(&phonedev->lock_recompute_pcm); + phonedev->channels = channels; + phonedev->no_pcm = no_pcm; + phonedev->offhook_state = 0x0; /* ONHOOK */ + phonedev->phoneops = proto_table->phoneops; + phonedev->digital_outputs = 0; + phonedev->digital_inputs = 0; + atomic_set(&phonedev->dahdi_registered, 0); + atomic_set(&phonedev->open_counter, 0); + for (x = 0; x < phonedev->channels; x++) { + if (!(phonedev->chans[x] = kmalloc(sizeof(*(phonedev->chans[x])), GFP_KERNEL))) { + ERR("%s: Unable to allocate channel %d\n", __FUNCTION__, x); + goto err; + } + } + return 0; +err: + phonedev_cleanup(xpd); + return -ENOMEM; +} + /* * xpd_alloc - Allocator for new XPD's * @@ -514,7 +556,7 @@ __must_check xpd_t *xpd_alloc(xbus_t *xbus, xpd_t *xpd = NULL; size_t alloc_size = sizeof(xpd_t) + privsize; int type = proto_table->type; - unsigned int x; + xpp_line_t no_pcm = 0; BUG_ON(!proto_table); XBUS_DBG(DEVICES, xbus, "type=%d channels=%d (alloc_size=%zd)\n", @@ -532,38 +574,23 @@ __must_check xpd_t *xpd_alloc(xbus_t *xbus, } xpd->priv = (byte *)xpd + sizeof(xpd_t); spin_lock_init(&xpd->lock); - spin_lock_init(&xpd->lock_recompute_pcm); - xpd->channels = channels; xpd->card_present = 0; - xpd->offhook_state = 0x0; /* ONHOOK */ xpd->type = proto_table->type; xpd->xproto = proto_table; - xpd->xops = &proto_table->xops; - xpd->digital_outputs = 0; - xpd->digital_inputs = 0; + xpd->xops = proto_table->xops; xpd->xpd_state = XPD_STATE_START; xpd->subtype = subtype; xpd->subunits = subunits; - - atomic_set(&xpd->dahdi_registered, 0); - atomic_set(&xpd->open_counter, 0); kref_init(&xpd->kref); /* For USB-1 disable some channels */ if(MAX_SEND_SIZE(xbus) < RPACKET_SIZE(GLOBAL, PCM_WRITE)) { - xpp_line_t no_pcm; - - no_pcm = 0x7F | xpd->digital_outputs | xpd->digital_inputs; - xpd->no_pcm = no_pcm; + no_pcm = 0x7F | PHONEDEV(xpd).digital_outputs | PHONEDEV(xpd).digital_inputs; XBUS_NOTICE(xbus, "max xframe size = %d, disabling some PCM channels. no_pcm=0x%04X\n", - MAX_SEND_SIZE(xbus), xpd->no_pcm); - } - for (x = 0; x < xpd->channels; x++) { - if (!(xpd->chans[x] = kmalloc(sizeof(*xpd->chans[x]), GFP_KERNEL))) { - ERR("%s: Unable to allocate channel %d\n", __FUNCTION__, x); - goto err; - } + MAX_SEND_SIZE(xbus), PHONEDEV(xpd).no_pcm); } + if (phonedev_init(xpd, proto_table, channels, no_pcm) < 0) + goto err; xbus_xpd_bind(xbus, xpd, unit, subunit); if(xpd_proc_create(xbus, xpd) < 0) goto err; @@ -577,11 +604,7 @@ __must_check xpd_t *xpd_alloc(xbus_t *xbus, err: if(xpd) { xpd_proc_remove(xbus, xpd); - for (x = 0; x < xpd->channels; x++) { - if (xpd->chans[x]) { - kfree(xpd->chans[x]); - } - } + phonedev_cleanup(xpd); KZFREE(xpd); } return NULL; @@ -606,7 +629,7 @@ void xbus_request_removal(xbus_t *xbus) spin_lock_irqsave(&xpd->lock, flags); xpd->card_present = 0; xpd_setstate(xpd, XPD_STATE_NOHW); - xpd->span.alarms = DAHDI_ALARM_NOTOPEN; + PHONEDEV(xpd).span.alarms = DAHDI_ALARM_NOTOPEN; spin_unlock_irqrestore(&xpd->lock, flags); } } @@ -617,9 +640,9 @@ void xbus_request_removal(xbus_t *xbus) if(SPAN_REGISTERED(xpd)) { int j; - dahdi_alarm_notify(&xpd->span); + dahdi_alarm_notify(&PHONEDEV(xpd).span); XPD_DBG(DEVICES, xpd, "Queuing DAHDI_EVENT_REMOVED on all channels to ask user to release them\n"); - for (j=0; jspan.channels; j++) { + for (j=0; jspan; + struct dahdi_span *span = &PHONEDEV(xpd).span; if(!SPAN_REGISTERED(xpd)) { // XPD_NOTICE(xpd, "%s: XPD is not registered. Skipping.\n", __FUNCTION__); @@ -660,7 +683,7 @@ void update_xpd_status(xpd_t *xpd, int alarm_flag) } if(span->alarms == alarm_flag) return; - XPD_DBG(GENERAL, xpd, "Update XPD alarms: %s -> %02X\n", xpd->span.name, alarm_flag); + XPD_DBG(GENERAL, xpd, "Update XPD alarms: %s -> %02X\n", PHONEDEV(xpd).span.name, alarm_flag); span->alarms = alarm_flag; dahdi_alarm_notify(span); } @@ -674,12 +697,12 @@ void oht_pcm(xpd_t *xpd, int pos, bool pass) { if(pass) { LINE_DBG(SIGNAL, xpd, pos, "OHT PCM: pass\n"); - BIT_SET(xpd->oht_pcm_pass, pos); + BIT_SET(PHONEDEV(xpd).oht_pcm_pass, pos); } else { LINE_DBG(SIGNAL, xpd, pos, "OHT PCM: block\n"); - BIT_CLR(xpd->oht_pcm_pass, pos); + BIT_CLR(PHONEDEV(xpd).oht_pcm_pass, pos); } - CALL_XMETHOD(card_pcm_recompute, xpd->xbus, xpd, 0); + PHONE_METHOD(xpd, card_pcm_recompute)(xpd->xbus, xpd, 0); } /* @@ -689,12 +712,12 @@ void mark_offhook(xpd_t *xpd, int pos, bool to_offhook) { if(to_offhook) { LINE_DBG(SIGNAL, xpd, pos, "OFFHOOK\n"); - BIT_SET(xpd->offhook_state, pos); + BIT_SET(PHONEDEV(xpd).offhook_state, pos); } else { LINE_DBG(SIGNAL, xpd, pos, "ONHOOK\n"); - BIT_CLR(xpd->offhook_state, pos); + BIT_CLR(PHONEDEV(xpd).offhook_state, pos); } - CALL_XMETHOD(card_pcm_recompute, xpd->xbus, xpd, 0); + PHONE_METHOD(xpd, card_pcm_recompute)(xpd->xbus, xpd, 0); } /* @@ -730,7 +753,7 @@ void hookstate_changed(xpd_t *xpd, int pos, bool to_offhook) * * This bit will be cleared on the next tick. */ - BIT_SET(xpd->silence_pcm, pos); + BIT_SET(PHONEDEV(xpd).silence_pcm, pos); } notify_rxsig(xpd, pos, (to_offhook) ? DAHDI_RXSIG_OFFHOOK : DAHDI_RXSIG_ONHOOK); } @@ -879,13 +902,13 @@ int xpp_open(struct dahdi_chan *chan) return -ENODEV; } spin_lock_irqsave(&xbus->lock, flags); - atomic_inc(&xpd->open_counter); + atomic_inc(&PHONEDEV(xpd).open_counter); LINE_DBG(DEVICES, xpd, pos, "%s[%d]: open_counter=%d\n", current->comm, current->pid, - atomic_read(&xpd->open_counter)); + atomic_read(&PHONEDEV(xpd).open_counter)); spin_unlock_irqrestore(&xbus->lock, flags); - if(xpd->xops->card_open) - xpd->xops->card_open(xpd, pos); + if(PHONE_METHOD(xpd, card_open)) + PHONE_METHOD(xpd, card_open)(xpd, pos); return 0; } @@ -898,12 +921,12 @@ int xpp_close(struct dahdi_chan *chan) spin_lock_irqsave(&xbus->lock, flags); spin_unlock_irqrestore(&xbus->lock, flags); - if(xpd->xops->card_close) - xpd->xops->card_close(xpd, pos); + if(PHONE_METHOD(xpd, card_close)) + PHONE_METHOD(xpd, card_close)(xpd, pos); LINE_DBG(DEVICES, xpd, pos, "%s[%d]: open_counter=%d\n", current->comm, current->pid, - atomic_read(&xpd->open_counter)); - atomic_dec(&xpd->open_counter); /* from xpp_open() */ + atomic_read(&PHONEDEV(xpd).open_counter)); + atomic_dec(&PHONEDEV(xpd).open_counter); /* from xpp_open() */ put_xpd(__FUNCTION__, xpd); /* from xpp_open() */ return 0; } @@ -935,8 +958,8 @@ int xpp_ioctl(struct dahdi_chan *chan, unsigned int cmd, unsigned long arg) switch (cmd) { default: /* Some span-specific commands before we give up: */ - if (xpd->xops->card_ioctl != NULL) { - return xpd->xops->card_ioctl(xpd, pos, cmd, arg); + if (PHONE_METHOD(xpd, card_ioctl)) { + return PHONE_METHOD(xpd, card_ioctl)(xpd, pos, cmd, arg); } report_bad_ioctl(THIS_MODULE->name, xpd, pos, cmd); return -ENOTTY; @@ -955,7 +978,7 @@ int xpp_hooksig(struct dahdi_chan *chan, enum dahdi_txsig txsig) __FUNCTION__, pos); return -ENODEV; } - if(!xpd->xops->card_hooksig) { + if(!PHONE_METHOD(xpd, card_hooksig)) { LINE_ERR(xpd, pos, "%s: No hooksig method for this channel. Ignore.\n", __FUNCTION__); @@ -964,7 +987,7 @@ int xpp_hooksig(struct dahdi_chan *chan, enum dahdi_txsig txsig) xbus = xpd->xbus; BUG_ON(!xbus); DBG(SIGNAL, "Setting %s to %s (%d)\n", chan->name, txsig2str(txsig), txsig); - return CALL_XMETHOD(card_hooksig, xbus, xpd, pos, txsig); + return PHONE_METHOD(xpd, card_hooksig)(xbus, xpd, pos, txsig); } EXPORT_SYMBOL(xpp_hooksig); @@ -975,7 +998,8 @@ int xpp_setchunksize(struct dahdi_span *span, int chunksize); /* Enable maintenance modes */ int xpp_maint(struct dahdi_span *span, int cmd) { - xpd_t *xpd = container_of(span, struct xpd, span); + struct phonedev *phonedev = container_of(span, struct phonedev, span); + xpd_t *xpd = container_of(phonedev, struct xpd, phonedev); int ret = 0; #if 0 char loopback_data[] = "THE-QUICK-BROWN-FOX-JUMPED-OVER-THE-LAZY-DOG"; @@ -1049,20 +1073,20 @@ int dahdi_unregister_xpd(xpd_t *xpd) } update_xpd_status(xpd, DAHDI_ALARM_NOTOPEN); /* We should now have only a ref from the xbus (from create_xpd()) */ - if(atomic_read(&xpd->open_counter)) { - XPD_NOTICE(xpd, "Busy (open_counter=%d). Skipping.\n", atomic_read(&xpd->open_counter)); + if(atomic_read(&PHONEDEV(xpd).open_counter)) { + XPD_NOTICE(xpd, "Busy (open_counter=%d). Skipping.\n", atomic_read(&PHONEDEV(xpd).open_counter)); spin_unlock_irqrestore(&xpd->lock, flags); return -EBUSY; } 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_dahdi_preregistration(xpd, 0); - atomic_dec(&xpd->dahdi_registered); + PHONE_METHOD(xpd, card_dahdi_preregistration)(xpd, 0); + atomic_dec(&PHONEDEV(xpd).dahdi_registered); atomic_dec(&num_registered_spans); - dahdi_unregister(&xpd->span); + dahdi_unregister(&PHONEDEV(xpd).span); if(xpd->card_present) - xpd->xops->card_dahdi_postregistration(xpd, 0); + PHONE_METHOD(xpd, card_dahdi_postregistration)(xpd, 0); return 0; } @@ -1089,32 +1113,30 @@ int dahdi_register_xpd(xpd_t *xpd) xbus_t *xbus; int cn; int i; - const xops_t *xops; BUG_ON(!xpd); - xops = xpd->xops; xbus = xpd->xbus; if (SPAN_REGISTERED(xpd)) { XPD_ERR(xpd, "Already registered\n"); return -EEXIST; } - cn = xpd->channels; + cn = PHONEDEV(xpd).channels; XPD_DBG(DEVICES, xpd, "Initializing span: %d channels.\n", cn); - memset(&xpd->span, 0, sizeof(struct dahdi_span)); + memset(&PHONEDEV(xpd).span, 0, sizeof(struct dahdi_span)); for(i = 0; i < cn; i++) { memset(XPD_CHAN(xpd, i), 0, sizeof(struct dahdi_chan)); } - span = &xpd->span; + span = &PHONEDEV(xpd).span; snprintf(span->name, MAX_SPANNAME, "%s/%s", xbus->busname, xpd->xpdname); span->deflaw = DAHDI_LAW_MULAW; /* default, may be overriden by card_* drivers */ span->channels = cn; - span->chans = xpd->chans; + span->chans = PHONEDEV(xpd).chans; span->flags = DAHDI_FLAG_RBS; - if(xops->card_hooksig) + if(PHONEDEV(xpd).phoneops->card_hooksig) span->ops = &xpp_rbs_span_ops; /* Only with RBS bits */ else span->ops = &xpp_span_ops; @@ -1152,17 +1174,17 @@ int dahdi_register_xpd(xpd_t *xpd) */ span->irq = 0; - snprintf(xpd->span.desc, MAX_SPANDESC, "Xorcom XPD #%02d/%1d%1d: %s", + snprintf(PHONEDEV(xpd).span.desc, MAX_SPANDESC, "Xorcom XPD #%02d/%1d%1d: %s", xbus->num, xpd->addr.unit, xpd->addr.subunit, xpd->type_name); - XPD_DBG(GENERAL, xpd, "Registering span '%s'\n", xpd->span.desc); - xpd->xops->card_dahdi_preregistration(xpd, 1); - if(dahdi_register(&xpd->span, prefmaster)) { + XPD_DBG(GENERAL, xpd, "Registering span '%s'\n", PHONEDEV(xpd).span.desc); + PHONE_METHOD(xpd, card_dahdi_preregistration)(xpd, 1); + if(dahdi_register(&PHONEDEV(xpd).span, prefmaster)) { XPD_ERR(xpd, "Failed to dahdi_register span\n"); return -ENODEV; } atomic_inc(&num_registered_spans); - atomic_inc(&xpd->dahdi_registered); - xpd->xops->card_dahdi_postregistration(xpd, 1); + atomic_inc(&PHONEDEV(xpd).dahdi_registered); + PHONE_METHOD(xpd, card_dahdi_postregistration)(xpd, 1); /* * Update dahdi about our state: * - Since asterisk didn't open the channel yet, diff --git a/drivers/dahdi/xpp/xpp_dahdi.h b/drivers/dahdi/xpp/xpp_dahdi.h index e048dc7..3ab0299 100644 --- a/drivers/dahdi/xpp/xpp_dahdi.h +++ b/drivers/dahdi/xpp/xpp_dahdi.h @@ -45,7 +45,7 @@ void report_bad_ioctl(const char *msg, xpd_t *xpd, int pos, unsigned int cmd); int total_registered_spans(void); void oht_pcm(xpd_t *xpd, int pos, bool pass); void mark_offhook(xpd_t *xpd, int pos, bool to_offhook); -#define IS_OFFHOOK(xpd,pos) IS_SET((xpd)->offhook_state, (pos)) +#define IS_OFFHOOK(xpd,pos) IS_SET((xpd)->phonedev.offhook_state, (pos)) void notify_rxsig(xpd_t *xpd, int pos, enum dahdi_rxsig rxsig); #ifdef CONFIG_PROC_FS @@ -54,6 +54,6 @@ void notify_rxsig(xpd_t *xpd, int pos, enum dahdi_rxsig rxsig); extern struct proc_dir_entry *xpp_proc_toplevel; #endif -#define SPAN_REGISTERED(xpd) atomic_read(&(xpd)->dahdi_registered) +#define SPAN_REGISTERED(xpd) atomic_read(&PHONEDEV(xpd).dahdi_registered) #endif /* XPP_DAHDI_H */ diff --git a/drivers/dahdi/xpp/xproto.c b/drivers/dahdi/xpp/xproto.c index 4ae64f9..afc6be5 100644 --- a/drivers/dahdi/xpp/xproto.c +++ b/drivers/dahdi/xpp/xproto.c @@ -414,7 +414,7 @@ const char *xproto_name(xpd_type_t xpd_type) return proto_table->name; } -#define CHECK_XOP(f) \ +#define CHECK_XOP(xops, f) \ if(!(xops)->f) { \ ERR("%s: missing xmethod %s [%s (%d)]\n", __FUNCTION__, #f, name, type); \ return -EINVAL; \ @@ -422,9 +422,9 @@ const char *xproto_name(xpd_type_t xpd_type) int xproto_register(const xproto_table_t *proto_table) { - int type; - const char *name; - const xops_t *xops; + int type; + const char *name; + const struct xops *xops; BUG_ON(!proto_table); type = proto_table->type; @@ -436,11 +436,13 @@ int xproto_register(const xproto_table_t *proto_table) DBG(GENERAL, "%s (%d)\n", name, type); if(xprotocol_tables[type]) NOTICE("%s: overriding registration of %s (%d)\n", __FUNCTION__, name, type); - xops = &proto_table->xops; - CHECK_XOP(card_new); - CHECK_XOP(card_init); - CHECK_XOP(card_remove); - CHECK_XOP(card_tick); + xops = proto_table->xops; + CHECK_XOP(xops, card_new); + CHECK_XOP(xops, card_init); + CHECK_XOP(xops, card_remove); + CHECK_XOP(xops, card_tick); +#if 0 + /* FIXME: check PHONE_METHOD() */ CHECK_XOP(card_pcm_recompute); CHECK_XOP(card_pcm_fromspan); CHECK_XOP(card_pcm_tospan); @@ -449,6 +451,7 @@ int xproto_register(const xproto_table_t *proto_table) // CHECK_XOP(card_ioctl); // optional method -- call after testing CHECK_XOP(card_register_reply); CHECK_XOP(XPD_STATE); +#endif xprotocol_tables[type] = proto_table; return 0; diff --git a/drivers/dahdi/xpp/xproto.h b/drivers/dahdi/xpp/xproto.h index 765cc68..5be6797 100644 --- a/drivers/dahdi/xpp/xproto.h +++ b/drivers/dahdi/xpp/xproto.h @@ -216,13 +216,9 @@ xproto_handler_t xproto_global_handler(byte opcode); #define CALL_XMETHOD(name, xbus, xpd, ...) \ (xpd)->xops->name(xbus, xpd, ## __VA_ARGS__ ) -struct xops { - xpd_t *(*card_new)(xbus_t *xbus, int unit, int subunit, - const xproto_table_t *proto_table, byte subtype, - int subunits, int subunit_ports, bool to_phone); - int (*card_init)(xbus_t *xbus, xpd_t *xpd); - int (*card_remove)(xbus_t *xbus, xpd_t *xpd); - int (*card_tick)(xbus_t *xbus, xpd_t *xpd); +#define PHONE_METHOD(xpd, name) PHONEDEV(xpd).phoneops->name + +struct phoneops { void (*card_pcm_recompute)(xbus_t *xbus, xpd_t *xpd, xpp_line_t pcm_mask); void (*card_pcm_fromspan)(xbus_t *xbus, xpd_t *xpd, xpacket_t *pack); void (*card_pcm_tospan)(xbus_t *xbus, xpd_t *xpd, xpacket_t *pack); @@ -233,11 +229,20 @@ struct xops { int (*card_ioctl)(xpd_t *xpd, int pos, unsigned int cmd, unsigned long arg); int (*card_open)(xpd_t *xpd, lineno_t pos); int (*card_close)(xpd_t *xpd, lineno_t pos); - int (*card_register_reply)(xbus_t *xbus, xpd_t *xpd, reg_cmd_t *reg); int (*XPD_STATE)(xbus_t *xbus, xpd_t *xpd, bool on); }; +struct xops { + xpd_t *(*card_new)(xbus_t *xbus, int unit, int subunit, + const xproto_table_t *proto_table, byte subtype, + int subunits, int subunit_ports, bool to_phone); + int (*card_init)(xbus_t *xbus, xpd_t *xpd); + int (*card_remove)(xbus_t *xbus, xpd_t *xpd); + int (*card_tick)(xbus_t *xbus, xpd_t *xpd); + int (*card_register_reply)(xbus_t *xbus, xpd_t *xpd, reg_cmd_t *reg); +}; + struct xproto_entry { xproto_handler_t handler; int datalen; @@ -246,9 +251,11 @@ struct xproto_entry { }; struct xproto_table { - struct module *owner; - xproto_entry_t entries[256]; /* Indexed by opcode */ - xops_t xops; + struct module *owner; + xproto_entry_t entries[256]; /* Indexed by opcode */ + const struct xops *xops; /* Card level operations */ + const struct phoneops *phoneops; /* DAHDI operations */ + //const struct echoops *echo; xpd_type_t type; byte ports_per_subunit; const char *name; -- cgit v1.2.3