From 15654c14c8a566edeb07b25aeb73ce2578dad2f2 Mon Sep 17 00:00:00 2001 From: Oron Peled Date: Mon, 23 May 2011 17:58:50 +0300 Subject: xpp: Now each Astribank (xbus) is a dahdi device and each xpd is a span: - This is a minimal patch - More work should be done (e.g: auto_registration etc.) --- drivers/dahdi/xpp/xbus-core.c | 75 ++++++++++++++++++++++++++++-- drivers/dahdi/xpp/xbus-core.h | 1 + drivers/dahdi/xpp/xbus-sysfs.c | 4 ++ drivers/dahdi/xpp/xpd.h | 1 - drivers/dahdi/xpp/xpp_dahdi.c | 102 +++++++++++++++-------------------------- drivers/dahdi/xpp/xpp_dahdi.h | 3 +- 6 files changed, 116 insertions(+), 70 deletions(-) diff --git a/drivers/dahdi/xpp/xbus-core.c b/drivers/dahdi/xpp/xbus-core.c index 331ffee..b414200 100644 --- a/drivers/dahdi/xpp/xbus-core.c +++ b/drivers/dahdi/xpp/xbus-core.c @@ -820,6 +820,75 @@ err: goto out; } +static int xbus_register_dahdi_device(xbus_t *xbus) +{ + int i; + + XBUS_NOTICE(xbus, "Entering %s\n", __FUNCTION__); + xbus->ddev = dahdi_create_device(); + /* + * This actually describe the dahdi_spaninfo version 3 + * A bunch of unrelated data exported via a modified ioctl() + * What a bummer... + */ + xbus->ddev->manufacturer = "Xorcom Inc."; /* OK, that's obvious */ + /* span->spantype = "...."; set in card_dahdi_preregistration() */ + /* + * Yes, this basically duplicates information available + * from the description field. If some more is needed + * why not add it there? + * OK, let's add to the kernel more useless info. + */ + xbus->ddev->devicetype = kasprintf(GFP_KERNEL, "Astribank2"); + if (!xbus->ddev->devicetype) + return -ENOMEM; + + /* + * location is the only usefull new data item. + * For our devices it was available for ages via: + * - The legacy "/proc/xpp/XBUS-??/summary" (CONNECTOR=...) + * - The same info in "/proc/xpp/xbuses" + * - The modern "/sys/bus/astribanks/devices/xbus-??/connector" attribute + * So let's also export it via the newfangled "location" field. + */ + xbus->ddev->location = xbus->connector; + + /* + * Prepare the span list + */ + for(i = 0; i < MAX_XPDS; i++) { + xpd_t *xpd = xpd_of(xbus, i); + if(xpd && IS_PHONEDEV(xpd)) { + XPD_DBG(DEVICES, xpd, "\n"); + dahdi_preregister_xpd(xpd); + } + } + if (dahdi_register_device(xbus->ddev, &xbus->astribank)) { + XBUS_ERR(xbus, "Failed to dahdi_register_device()\n"); + return -ENODEV; + } + for(i = 0; i < MAX_XPDS; i++) { + xpd_t *xpd = xpd_of(xbus, i); + if(xpd && IS_PHONEDEV(xpd)) { + XPD_DBG(DEVICES, xpd, "\n"); + dahdi_postregister_xpd(xpd); + } + } + return 0; +} + +static void xbus_unregister_dahdi_device(xbus_t *xbus) +{ + XBUS_NOTICE(xbus, "%s\n", __FUNCTION__); + dahdi_unregister_device(xbus->ddev); + XBUS_NOTICE(xbus, "%s: finished dahdi_unregister_device()\n", __FUNCTION__); + kfree(xbus->ddev->devicetype); + xbus->ddev->devicetype = NULL; + xbus->ddev->location = NULL; + dahdi_free_device(xbus->ddev); + xbus->ddev = NULL; +} + /* * This must be called from synchronous (non-interrupt) context * it returns only when all XPD's on the bus are detected and @@ -883,6 +952,7 @@ void xbus_populate(void *data) */ xbus_request_sync(xbus, SYNC_MODE_PLL); elect_syncer("xbus_populate(end)"); /* FIXME: try to do it later */ + xbus_register_dahdi_device(xbus); out: XBUS_DBG(DEVICES, xbus, "Leaving\n"); wake_up_interruptible_all(&worker->wait_for_xpd_initialization); @@ -1161,6 +1231,7 @@ void xbus_deactivate(xbus_t *xbus) xbus_setstate(xbus, XBUS_STATE_DEACTIVATED); worker_reset(xbus); xbus_release_xpds(xbus); /* taken in xpd_alloc() [kref_init] */ + xbus_unregister_dahdi_device(xbus); } void xbus_disconnect(xbus_t *xbus) @@ -1738,10 +1809,6 @@ err: void xbus_core_shutdown(void) { - int i; - - for(i = 0; i < MAX_BUSES; i++) - BUG_ON(xbus_num(i)); xbus_core_cleanup(); xpp_driver_exit(); } diff --git a/drivers/dahdi/xpp/xbus-core.h b/drivers/dahdi/xpp/xbus-core.h index 659d3d4..33ca7aa 100644 --- a/drivers/dahdi/xpp/xbus-core.h +++ b/drivers/dahdi/xpp/xbus-core.h @@ -166,6 +166,7 @@ struct xbus { char label[LABEL_SIZE]; byte revision; /* Protocol revision */ struct xbus_transport transport; + struct dahdi_device *ddev; int num; struct xpd *xpds[MAX_XPDS]; diff --git a/drivers/dahdi/xpp/xbus-sysfs.c b/drivers/dahdi/xpp/xbus-sysfs.c index d983f17..c05064a 100644 --- a/drivers/dahdi/xpp/xbus-sysfs.c +++ b/drivers/dahdi/xpp/xbus-sysfs.c @@ -639,10 +639,13 @@ static DEVICE_ATTR_WRITER(span_store, dev, buf, count) if(!XBUS_IS(xpd->xbus, READY)) return -ENODEV; XPD_DBG(GENERAL, xpd, "%s\n", (dahdi_reg) ? "register" : "unregister"); + XPD_ERR(xpd, "No more register/unregister of individual XPD's\n"); +#if 0 if(dahdi_reg) ret = dahdi_register_xpd(xpd); else ret = dahdi_unregister_xpd(xpd); +#endif return (ret < 0) ? ret : count; } @@ -856,6 +859,7 @@ void xbus_sysfs_remove(xbus_t *xbus) BUG_ON(dev_get_drvdata(astribank) != xbus); device_unregister(astribank); dev_set_drvdata(astribank, NULL); + put_device(astribank); /* DEBUG */ } int xbus_sysfs_create(xbus_t *xbus) diff --git a/drivers/dahdi/xpp/xpd.h b/drivers/dahdi/xpp/xpd.h index 0e6fcbc..dadbf55 100644 --- a/drivers/dahdi/xpp/xpd.h +++ b/drivers/dahdi/xpp/xpd.h @@ -146,7 +146,6 @@ const char *xpd_statename(enum xpd_state st); struct phonedev { const struct phoneops *phoneops; /* Card level operations */ - struct dahdi_device *ddev; struct dahdi_span span; struct dahdi_chan *chans[32]; #define XPD_CHAN(xpd,chan) (PHONEDEV(xpd).chans[(chan)]) diff --git a/drivers/dahdi/xpp/xpp_dahdi.c b/drivers/dahdi/xpp/xpp_dahdi.c index 992064a..69a596d 100644 --- a/drivers/dahdi/xpp/xpp_dahdi.c +++ b/drivers/dahdi/xpp/xpp_dahdi.c @@ -256,8 +256,8 @@ int create_xpd(xbus_t *xbus, const xproto_table_t *proto_table, void xpd_post_init(xpd_t *xpd) { XPD_DBG(DEVICES, xpd, "\n"); - if(dahdi_autoreg) - dahdi_register_xpd(xpd); +//DEBUG if(dahdi_autoreg) +//DEBUG dahdi_register_xpd(xpd); } #ifdef CONFIG_PROC_FS @@ -466,7 +466,6 @@ static void phonedev_cleanup(xpd_t *xpd) KZFREE(phonedev->chans[x]); } } - dahdi_free_device(phonedev->ddev); } __must_check static int phonedev_init(xpd_t *xpd, const xproto_table_t *proto_table, @@ -934,7 +933,7 @@ int dahdi_unregister_xpd(xpd_t *xpd) CALL_PHONE_METHOD(card_dahdi_preregistration, xpd, 0); atomic_dec(&PHONEDEV(xpd).dahdi_registered); atomic_dec(&num_registered_spans); - dahdi_unregister_device(PHONEDEV(xpd).ddev); + dahdi_unregister_span(&PHONEDEV(xpd).span); if(xpd->card_present) CALL_PHONE_METHOD(card_dahdi_postregistration, xpd, 0); return 0; @@ -957,12 +956,38 @@ static const struct dahdi_span_ops xpp_rbs_span_ops = { .maint = xpp_maint, }; -int dahdi_register_xpd(xpd_t *xpd) +static void xpd_init_span(xpd_t *xpd, int cn) { struct dahdi_span *span; + int i; + + XPD_NOTICE(xpd, "Initializing span: %d channels.\n", cn); + 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 = &PHONEDEV(xpd).span; + snprintf(span->name, MAX_SPANNAME, "%s/%s", xpd->xbus->busname, xpd->xpdname); + span->deflaw = DAHDI_LAW_MULAW; /* default, may be overriden by card_* drivers */ + span->channels = cn; + span->chans = PHONEDEV(xpd).chans; + + span->flags = DAHDI_FLAG_RBS; + if(PHONEDEV(xpd).phoneops->card_hooksig) + span->ops = &xpp_rbs_span_ops; /* Only with RBS bits */ + else + span->ops = &xpp_span_ops; + + snprintf(PHONEDEV(xpd).span.desc, MAX_SPANDESC, "Xorcom XPD #%02d/%1d%1d: %s", + xpd->xbus->num, xpd->addr.unit, xpd->addr.subunit, xpd->type_name); + list_add_tail(&span->device_node, &xpd->xbus->ddev->spans); +} + +int dahdi_preregister_xpd(xpd_t *xpd) +{ xbus_t *xbus; int cn; - int i; struct phonedev *phonedev; BUG_ON(!xpd); @@ -981,68 +1006,17 @@ int dahdi_register_xpd(xpd_t *xpd) return -EEXIST; } - phonedev->ddev = dahdi_create_device(); - cn = PHONEDEV(xpd).channels; - XPD_DBG(DEVICES, xpd, "Initializing span: %d channels.\n", cn); - 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 = &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 = PHONEDEV(xpd).chans; - - span->flags = DAHDI_FLAG_RBS; - if(PHONEDEV(xpd).phoneops->card_hooksig) - span->ops = &xpp_rbs_span_ops; /* Only with RBS bits */ - else - span->ops = &xpp_span_ops; - - /* - * This actually describe the dahdi_spaninfo version 3 - * A bunch of unrelated data exported via a modified ioctl() - * What a bummer... - */ - phonedev->ddev->manufacturer = "Xorcom Inc."; /* OK, that's obvious */ - /* span->spantype = "...."; set in card_dahdi_preregistration() */ - /* - * Yes, this basically duplicates information available - * from the description field. If some more is needed - * why not add it there? - * OK, let's add to the kernel more useless info. - */ - phonedev->ddev->devicetype = kasprintf(GFP_KERNEL, - "Astribank: Unit %x Subunit %x: %s", - XBUS_UNIT(xpd->xbus_idx), XBUS_SUBUNIT(xpd->xbus_idx), - xpd->type_name); - - if (!phonedev->ddev->devicetype) - return -ENOMEM; - - /* - * location is the only usefull new data item. - * For our devices it was available for ages via: - * - The legacy "/proc/xpp/XBUS-??/summary" (CONNECTOR=...) - * - The same info in "/proc/xpp/xbuses" - * - The modern "/sys/bus/astribanks/devices/xbus-??/connector" attribute - * So let's also export it via the newfangled "location" field. - */ - phonedev->ddev->location = xbus->connector; - - 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_init_span(xpd, cn); XPD_DBG(GENERAL, xpd, "Registering span '%s'\n", PHONEDEV(xpd).span.desc); CALL_PHONE_METHOD(card_dahdi_preregistration, xpd, 1); - list_add_tail(&span->device_node, &phonedev->ddev->spans); + return 0; +} + +int dahdi_postregister_xpd(xpd_t *xpd) +{ + int cn; - if (dahdi_register_device(phonedev->ddev, &xpd->xpd_dev)) { - XPD_ERR(xpd, "Failed to dahdi_register span\n"); - return -ENODEV; - } atomic_inc(&num_registered_spans); atomic_inc(&PHONEDEV(xpd).dahdi_registered); CALL_PHONE_METHOD(card_dahdi_postregistration, xpd, 1); diff --git a/drivers/dahdi/xpp/xpp_dahdi.h b/drivers/dahdi/xpp/xpp_dahdi.h index 3ab0299..8641615 100644 --- a/drivers/dahdi/xpp/xpp_dahdi.h +++ b/drivers/dahdi/xpp/xpp_dahdi.h @@ -25,7 +25,8 @@ #include "xpd.h" #include "xproto.h" -int dahdi_register_xpd(xpd_t *xpd); +int dahdi_preregister_xpd(xpd_t *xpd); +int dahdi_postregister_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, -- cgit v1.2.3