From 5af88c77e19a108eb1fe9144d157d72e03551309 Mon Sep 17 00:00:00 2001 From: Tzafrir Cohen Date: Mon, 20 Apr 2009 10:26:35 +0000 Subject: xpp: Do use information about number of ports the Astribank provides git-svn-id: http://svn.asterisk.org/svn/dahdi/linux/trunk@6408 a0bf4364-ded3-4de4-8d8a-66a801d63aff --- drivers/dahdi/xpp/card_bri.c | 7 ++++++- drivers/dahdi/xpp/card_fxo.c | 7 ++++--- drivers/dahdi/xpp/card_fxs.c | 7 ++++--- drivers/dahdi/xpp/card_pri.c | 7 ++++++- drivers/dahdi/xpp/xbus-core.c | 23 ++++++++++++++++++++--- drivers/dahdi/xpp/xpp_dahdi.c | 8 +++++++- drivers/dahdi/xpp/xpp_dahdi.h | 2 +- drivers/dahdi/xpp/xproto.h | 3 ++- 8 files changed, 50 insertions(+), 14 deletions(-) diff --git a/drivers/dahdi/xpp/card_bri.c b/drivers/dahdi/xpp/card_bri.c index c5b0d9e..8bf1aa6 100644 --- a/drivers/dahdi/xpp/card_bri.c +++ b/drivers/dahdi/xpp/card_bri.c @@ -610,11 +610,16 @@ err: return -EINVAL; } -static xpd_t *BRI_card_new(xbus_t *xbus, int unit, int subunit, const xproto_table_t *proto_table, byte subtype, int subunits, bool to_phone) +static xpd_t *BRI_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) { xpd_t *xpd = NULL; int channels = min(3, CHANNELS_PERXPD); + if(subunit_ports != 1) { + XBUS_ERR(xbus, "Bad subunit_ports=%d\n", subunit_ports); + return NULL; + } XBUS_DBG(GENERAL, xbus, "\n"); xpd = xpd_alloc(xbus, unit, subunit, subtype, subunits, sizeof(struct BRI_priv_data), proto_table, channels); if(!xpd) diff --git a/drivers/dahdi/xpp/card_fxo.c b/drivers/dahdi/xpp/card_fxo.c index 93b5f5b..79b7ce2 100644 --- a/drivers/dahdi/xpp/card_fxo.c +++ b/drivers/dahdi/xpp/card_fxo.c @@ -422,7 +422,8 @@ err: return -EINVAL; } -static xpd_t *FXO_card_new(xbus_t *xbus, int unit, int subunit, const xproto_table_t *proto_table, byte subtype, int subunits, bool to_phone) +static xpd_t *FXO_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) { xpd_t *xpd = NULL; int channels; @@ -434,9 +435,9 @@ static xpd_t *FXO_card_new(xbus_t *xbus, int unit, int subunit, const xproto_tab return NULL; } if(subtype == 2) - channels = min(2, CHANNELS_PERXPD); + channels = min(2, subunit_ports); else - channels = min(8, CHANNELS_PERXPD); + channels = min(8, subunit_ports); xpd = xpd_alloc(xbus, unit, subunit, subtype, subunits, sizeof(struct FXO_priv_data), proto_table, channels); if(!xpd) return NULL; diff --git a/drivers/dahdi/xpp/card_fxs.c b/drivers/dahdi/xpp/card_fxs.c index 7171f9b..c00684e 100644 --- a/drivers/dahdi/xpp/card_fxs.c +++ b/drivers/dahdi/xpp/card_fxs.c @@ -377,7 +377,8 @@ err: return -EINVAL; } -static xpd_t *FXS_card_new(xbus_t *xbus, int unit, int subunit, const xproto_table_t *proto_table, byte subtype, int subunits, bool to_phone) +static xpd_t *FXS_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) { xpd_t *xpd = NULL; int channels; @@ -392,9 +393,9 @@ static xpd_t *FXS_card_new(xbus_t *xbus, int unit, int subunit, const xproto_tab return NULL; } if(subtype == 2) - regular_channels = min(6, CHANNELS_PERXPD); + regular_channels = min(6, subunit_ports); else - regular_channels = min(8, CHANNELS_PERXPD); + regular_channels = min(8, subunit_ports); channels = regular_channels; if(unit == 0) channels += 6; /* 2 DIGITAL OUTPUTS, 4 DIGITAL INPUTS */ diff --git a/drivers/dahdi/xpp/card_pri.c b/drivers/dahdi/xpp/card_pri.c index 3cdf3a8..d39c3f3 100644 --- a/drivers/dahdi/xpp/card_pri.c +++ b/drivers/dahdi/xpp/card_pri.c @@ -909,12 +909,17 @@ static int pri_chanconfig(struct dahdi_chan *chan, int sigtype) return 0; } -static xpd_t *PRI_card_new(xbus_t *xbus, int unit, int subunit, const xproto_table_t *proto_table, byte subtype, int subunits, bool to_phone) +static xpd_t *PRI_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) { xpd_t *xpd = NULL; struct PRI_priv_data *priv; int channels = min(31, CHANNELS_PERXPD); /* worst case */ + if(subunit_ports != 1) { + XBUS_ERR(xbus, "Bad subunit_ports=%d\n", subunit_ports); + return NULL; + } XBUS_DBG(GENERAL, xbus, "\n"); xpd = xpd_alloc(xbus, unit, subunit, subtype, subunits, sizeof(struct PRI_priv_data), proto_table, channels); if(!xpd) diff --git a/drivers/dahdi/xpp/xbus-core.c b/drivers/dahdi/xpp/xbus-core.c index b4716a4..f65d0b1 100644 --- a/drivers/dahdi/xpp/xbus-core.c +++ b/drivers/dahdi/xpp/xbus-core.c @@ -728,6 +728,7 @@ static int new_card(xbus_t *xbus, int i; int subunits; int ret = 0; + int remaining_ports; proto_table = xproto_get(type); if(!proto_table) { @@ -736,6 +737,7 @@ static int new_card(xbus_t *xbus, unit, type); return -EINVAL; } + remaining_ports = ports; subunits = (ports + proto_table->ports_per_subunit - 1) / proto_table->ports_per_subunit; XBUS_DBG(DEVICES, xbus, "CARD %d type=%d.%d ports=%d (%dx%d), %d subunits, port-dir=0x%02X\n", @@ -752,6 +754,21 @@ static int new_card(xbus_t *xbus, BUG_ON(!xops); xbus->worker->num_units += subunits - 1; for(i = 0; i < subunits; i++) { + int subunit_ports = proto_table->ports_per_subunit; + + if(subunit_ports > remaining_ports) + subunit_ports = remaining_ports; + remaining_ports -= proto_table->ports_per_subunit; + if(subunit_ports <= 0) { + XBUS_NOTICE(xbus, + "Subunit XPD=%d%d without ports (%d of %d)\n", + unit, + i, + subunit_ports, + ports); + ret = -ENODEV; + goto out; + } if(!XBUS_IS(xbus, RECVD_DESC)) { XBUS_NOTICE(xbus, "Cannot create XPD=%d%d in state %s\n", @@ -761,18 +778,18 @@ static int new_card(xbus_t *xbus, ret = -ENODEV; goto out; } - XBUS_DBG(DEVICES, xbus, "Creating XPD=%d%d type=%d.%d\n", + XBUS_DBG(DEVICES, xbus, "Creating XPD=%d%d type=%d.%d (%d ports)\n", unit, i, type, - subtype); + subtype, subunit_ports); if(!XBUS_IS(xbus, RECVD_DESC)) { XBUS_ERR(xbus, "Aborting creation -- In bad state %s\n", xbus_statename(XBUS_STATE(xbus))); ret = -ENODEV; goto out; } - ret = create_xpd(xbus, proto_table, unit, i, type, subtype, subunits, port_dir); + ret = create_xpd(xbus, proto_table, unit, i, type, subtype, subunits, subunit_ports, port_dir); if(ret < 0) { XBUS_ERR(xbus, "Creation of XPD=%d%d failed %d\n", unit, i, ret); diff --git a/drivers/dahdi/xpp/xpp_dahdi.c b/drivers/dahdi/xpp/xpp_dahdi.c index e7b024a..e6543dd 100644 --- a/drivers/dahdi/xpp/xpp_dahdi.c +++ b/drivers/dahdi/xpp/xpp_dahdi.c @@ -255,6 +255,7 @@ int create_xpd(xbus_t *xbus, const xproto_table_t *proto_table, byte type, byte subtype, int subunits, + int subunit_ports, byte port_dir) { xpd_t *xpd = NULL; @@ -269,7 +270,12 @@ int create_xpd(xbus_t *xbus, const xproto_table_t *proto_table, unit, subunit); return 0; } - xpd = proto_table->xops.card_new(xbus, unit, subunit, proto_table, subtype, subunits, to_phone); + if(subunit_ports <= 0 || subunit_ports > CHANNELS_PERXPD) { + XBUS_NOTICE(xbus, "Illegal number of ports %d for XPD %d%d\n", + subunit_ports, unit, subunit); + return 0; + } + 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); diff --git a/drivers/dahdi/xpp/xpp_dahdi.h b/drivers/dahdi/xpp/xpp_dahdi.h index ad87b86..96e7fc3 100644 --- a/drivers/dahdi/xpp/xpp_dahdi.h +++ b/drivers/dahdi/xpp/xpp_dahdi.h @@ -29,7 +29,7 @@ int dahdi_register_xpd(xpd_t *xpd); int dahdi_unregister_xpd(xpd_t *xpd); void xbus_request_removal(xbus_t *xbus); int create_xpd(xbus_t *xbus, const xproto_table_t *proto_table, - int unit, int subunit, byte type, byte subtype, int subunits, byte port_dir); + int unit, int subunit, byte type, byte subtype, int subunits, int subunit_ports, byte port_dir); void xpd_post_init(xpd_t *xpd); xpd_t *xpd_alloc(xbus_t *xbus, int unit, int subunit, int subtype, int subunits, size_t privsize, const xproto_table_t *proto_table, int channels); void xpd_free(xpd_t *xpd); diff --git a/drivers/dahdi/xpp/xproto.h b/drivers/dahdi/xpp/xproto.h index 899791f..0034ab6 100644 --- a/drivers/dahdi/xpp/xproto.h +++ b/drivers/dahdi/xpp/xproto.h @@ -218,7 +218,8 @@ xproto_handler_t xproto_global_handler(byte opcode); struct xops { xpd_t *(*card_new)(xbus_t *xbus, int unit, int subunit, - const xproto_table_t *proto_table, byte subtype, int subunits, bool to_phone); + 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); -- cgit v1.2.3