summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTzafrir Cohen <tzafrir.cohen@xorcom.com>2009-04-20 10:26:35 +0000
committerTzafrir Cohen <tzafrir.cohen@xorcom.com>2009-04-20 10:26:35 +0000
commit5af88c77e19a108eb1fe9144d157d72e03551309 (patch)
treea5a8674452a1d33e0b8e2be6770322bd4c4f62b1
parent104115d00a132f3cb751991af70a1d90fdd98fe8 (diff)
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
-rw-r--r--drivers/dahdi/xpp/card_bri.c7
-rw-r--r--drivers/dahdi/xpp/card_fxo.c7
-rw-r--r--drivers/dahdi/xpp/card_fxs.c7
-rw-r--r--drivers/dahdi/xpp/card_pri.c7
-rw-r--r--drivers/dahdi/xpp/xbus-core.c23
-rw-r--r--drivers/dahdi/xpp/xpp_dahdi.c8
-rw-r--r--drivers/dahdi/xpp/xpp_dahdi.h2
-rw-r--r--drivers/dahdi/xpp/xproto.h3
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);