summaryrefslogtreecommitdiff
path: root/drivers/dahdi/xpp/xbus-core.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/dahdi/xpp/xbus-core.c')
-rw-r--r--drivers/dahdi/xpp/xbus-core.c75
1 files changed, 71 insertions, 4 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();
}