/* * Synchronous part of XPD detection. * Called from xbus_poll() */ 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) { xpd_t *xpd = NULL; bool to_phone; int ret = -EINVAL; BUG_ON(type == XPD_TYPE_NOMODULE); to_phone = BIT(subunit) & port_dir; BUG_ON(!xbus); xpd = xpd_byaddr(xbus, unit, subunit); if(xpd) { XPD_NOTICE(xpd, "XPD at %d%d already exists\n", unit, subunit); goto out; } xpd = proto_table->xops.card_new(xbus, unit, subunit, proto_table, subtype, subunits, 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); goto err; } out: return 0; err: if(xpd) xpd_free(xpd); return ret; }
static xpd_t *FXO_card_new(xbus_t *xbus, int unit, int subunit, const xproto_table_t *proto_table, __u8 subtype, int subunits, int subunit_ports, bool to_phone) { xpd_t *xpd = NULL; int channels; if (to_phone) { XBUS_NOTICE(xbus, "XPD=%d%d: try to instanciate FXO with " "reverse direction\n", unit, subunit); return NULL; } if (subtype == 2) channels = min(2, subunit_ports); else 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; PHONEDEV(xpd).direction = TO_PSTN; xpd->type_name = "FXO"; if (fxo_proc_create(xbus, xpd) < 0) goto err; return xpd; err: xpd_free(xpd); return NULL; }