[dahdi-commits] tzafrir: linux/trunk r8900 - /linux/trunk/drivers/dahdi/xpp/
SVN commits to the DAHDI project
dahdi-commits at lists.digium.com
Tue Jul 13 10:10:34 CDT 2010
Author: tzafrir
Date: Tue Jul 13 10:10:30 2010
New Revision: 8900
URL: http://svnview.digium.com/svn/dahdi?view=rev&rev=8900
Log:
Keep SYSFS objects after disconnect
* Astribanks no longer live directly under the USB devices in the device tree.
* The 'transport' link does point there as before, however.
* When the USB device disconnects, we keep references to them to make sure
they don't disappear.
Modified:
linux/trunk/drivers/dahdi/xpp/xbus-core.c
linux/trunk/drivers/dahdi/xpp/xbus-core.h
linux/trunk/drivers/dahdi/xpp/xbus-sysfs.c
linux/trunk/drivers/dahdi/xpp/xpd.h
linux/trunk/drivers/dahdi/xpp/xpp_dahdi.c
Modified: linux/trunk/drivers/dahdi/xpp/xbus-core.c
URL: http://svnview.digium.com/svn/dahdi/linux/trunk/drivers/dahdi/xpp/xbus-core.c?view=diff&rev=8900&r1=8899&r2=8900
==============================================================================
--- linux/trunk/drivers/dahdi/xpp/xbus-core.c (original)
+++ linux/trunk/drivers/dahdi/xpp/xbus-core.c Tue Jul 13 10:10:30 2010
@@ -141,28 +141,36 @@
}
}
+/*
+ * Called by put_xbus() when XBUS has no more references.
+ */
+static void xbus_destroy(struct kref *kref)
+{
+ xbus_t *xbus;
+
+ xbus = kref_to_xbus(kref);
+ XBUS_NOTICE(xbus, "%s\n", __func__);
+ xbus_sysfs_remove(xbus);
+}
+
xbus_t *get_xbus(const char *msg, xbus_t *xbus)
{
- struct device *dev;
-
XBUS_DBG(DEVICES, xbus, "%s: refcount_xbus=%d\n",
msg, refcount_xbus(xbus));
- dev = get_device(&xbus->astribank);
- if (!dev)
- return NULL;
- return dev_to_xbus(dev);
+ kref_get(&xbus->kref);
+ return xbus;
}
void put_xbus(const char *msg, xbus_t *xbus)
{
XBUS_DBG(DEVICES, xbus, "%s: refcount_xbus=%d\n",
msg, refcount_xbus(xbus));
- put_device(&xbus->astribank);
+ kref_put(&xbus->kref, xbus_destroy);
}
int refcount_xbus(xbus_t *xbus)
{
- struct kref *kref = &xbus->astribank.kobj.kref;
+ struct kref *kref = &xbus->kref;
return atomic_read(&kref->refcount);
}
@@ -1049,7 +1057,6 @@
BUG_ON(!xbus);
worker = &xbus->worker;
- xbus = container_of(worker, xbus_t, worker);
name = (xbus) ? xbus->busname : "detached";
DBG(DEVICES, "%s\n", name);
if(!worker->xpds_init_done) {
@@ -1300,7 +1307,7 @@
xbus_command_queue_waitempty(xbus);
xbus_setstate(xbus, XBUS_STATE_DEACTIVATED);
worker_reset(xbus);
- xbus_release_xpds(xbus); /* taken in xpd_device_register() */
+ xbus_release_xpds(xbus); /* taken in xpd_alloc() [kref_init] */
elect_syncer("deactivate");
}
@@ -1323,7 +1330,8 @@
worker_destroy(xbus);
XBUS_DBG(DEVICES, xbus, "Deactivated refcount_xbus=%d\n",
refcount_xbus(xbus));
- xbus_sysfs_remove(xbus); /* Device-Model */
+ xbus_sysfs_transport_remove(xbus); /* Device-Model */
+ put_xbus(__func__, xbus); /* from xbus_new() [kref_init()] */
}
static xbus_t *xbus_alloc(void)
@@ -1427,12 +1435,19 @@
xbus->min_tx_sync = INT_MAX;
xbus->min_rx_sync = INT_MAX;
+ kref_init(&xbus->kref);
worker_init(xbus);
atomic_set(&xbus->num_xpds, 0);
xbus->sync_mode = SYNC_MODE_NONE;
err = xbus_sysfs_create(xbus);
if(err) {
XBUS_ERR(xbus, "SYSFS creation failed: %d\n", err);
+ goto nobus;
+ }
+ err = xbus_sysfs_transport_create(xbus);
+ if (err) {
+ XBUS_ERR(xbus, "SYSFS transport link creation failed: %d\n",
+ err);
goto nobus;
}
xbus_reset_counters(xbus);
Modified: linux/trunk/drivers/dahdi/xpp/xbus-core.h
URL: http://svnview.digium.com/svn/dahdi/linux/trunk/drivers/dahdi/xpp/xbus-core.h?view=diff&rev=8900&r1=8899&r2=8900
==============================================================================
--- linux/trunk/drivers/dahdi/xpp/xbus-core.h (original)
+++ linux/trunk/drivers/dahdi/xpp/xbus-core.h Tue Jul 13 10:10:30 2010
@@ -24,6 +24,7 @@
#include <linux/wait.h>
#include <linux/interrupt.h> /* for tasklets */
+#include <linux/kref.h>
#include "xpd.h"
#include "xframe_queue.h"
#include "xbus-pcm.h"
@@ -206,6 +207,8 @@
/* Device-Model */
struct device astribank;
#define dev_to_xbus(dev) container_of(dev, struct xbus, astribank)
+ struct kref kref;
+#define kref_to_xbus(k) container_of(k, struct xbus, kref)
spinlock_t lock;
@@ -326,6 +329,8 @@
int xpp_driver_init(void);
void xpp_driver_exit(void);
+int xbus_sysfs_transport_create(xbus_t *xbus);
+void xbus_sysfs_transport_remove(xbus_t *xbus);
int xbus_sysfs_create(xbus_t *xbus);
void xbus_sysfs_remove(xbus_t *xbus);
Modified: linux/trunk/drivers/dahdi/xpp/xbus-sysfs.c
URL: http://svnview.digium.com/svn/dahdi/linux/trunk/drivers/dahdi/xpp/xbus-sysfs.c?view=diff&rev=8900&r1=8899&r2=8900
==============================================================================
--- linux/trunk/drivers/dahdi/xpp/xbus-sysfs.c (original)
+++ linux/trunk/drivers/dahdi/xpp/xbus-sysfs.c Tue Jul 13 10:10:30 2010
@@ -781,8 +781,6 @@
XPD_ERR(xpd, "%s: device_register failed: %d\n", __FUNCTION__, ret);
return ret;
}
- xpd = get_xpd(__func__, xpd); /* Released in xbus_release_xpds() */
- BUG_ON(!xpd);
return 0;
}
@@ -804,7 +802,7 @@
/*--------- Sysfs Device handling ----*/
-void xbus_sysfs_remove(xbus_t *xbus)
+void xbus_sysfs_transport_remove(xbus_t *xbus)
{
struct device *astribank;
@@ -812,6 +810,33 @@
XBUS_DBG(DEVICES, xbus, "\n");
astribank = &xbus->astribank;
sysfs_remove_link(&astribank->kobj, "transport");
+}
+
+int xbus_sysfs_transport_create(xbus_t *xbus)
+{
+ struct device *astribank;
+ int ret = 0;
+
+ BUG_ON(!xbus);
+ XBUS_DBG(DEVICES, xbus, "\n");
+ astribank = &xbus->astribank;
+ ret = sysfs_create_link(&astribank->kobj, &astribank->parent->kobj,
+ "transport");
+ if (ret < 0) {
+ XBUS_ERR(xbus, "%s: sysfs_create_link failed: %d\n",
+ __func__, ret);
+ dev_set_drvdata(astribank, NULL);
+ }
+ return ret;
+}
+
+void xbus_sysfs_remove(xbus_t *xbus)
+{
+ struct device *astribank;
+
+ BUG_ON(!xbus);
+ XBUS_DBG(DEVICES, xbus, "\n");
+ astribank = &xbus->astribank;
if(!dev_get_drvdata(astribank))
return;
BUG_ON(dev_get_drvdata(astribank) != xbus);
@@ -836,15 +861,7 @@
if(ret) {
XBUS_ERR(xbus, "%s: device_register failed: %d\n", __FUNCTION__, ret);
dev_set_drvdata(astribank, NULL);
- goto out;
- }
- ret = sysfs_create_link(&astribank->kobj, &astribank->parent->kobj, "transport");
- if(ret < 0) {
- XBUS_ERR(xbus, "%s: sysfs_create_link failed: %d\n", __FUNCTION__, ret);
- dev_set_drvdata(astribank, NULL);
- goto out;
- }
-out:
+ }
return ret;
}
Modified: linux/trunk/drivers/dahdi/xpp/xpd.h
URL: http://svnview.digium.com/svn/dahdi/linux/trunk/drivers/dahdi/xpp/xpd.h?view=diff&rev=8900&r1=8899&r2=8900
==============================================================================
--- linux/trunk/drivers/dahdi/xpp/xpd.h (original)
+++ linux/trunk/drivers/dahdi/xpp/xpd.h Tue Jul 13 10:10:30 2010
@@ -177,6 +177,8 @@
enum xpd_state xpd_state;
struct device xpd_dev;
#define dev_to_xpd(dev) container_of(dev, struct xpd, xpd_dev)
+ struct kref kref;
+#define kref_to_xpd(k) container_of(k, struct xpd, kref)
/* Assure atomicity of changes to pcm_len and wanted_pcm_mask */
spinlock_t lock_recompute_pcm;
Modified: linux/trunk/drivers/dahdi/xpp/xpp_dahdi.c
URL: http://svnview.digium.com/svn/dahdi/linux/trunk/drivers/dahdi/xpp/xpp_dahdi.c?view=diff&rev=8900&r1=8899&r2=8900
==============================================================================
--- linux/trunk/drivers/dahdi/xpp/xpp_dahdi.c (original)
+++ linux/trunk/drivers/dahdi/xpp/xpp_dahdi.c Tue Jul 13 10:10:30 2010
@@ -122,30 +122,38 @@
/*------------------------- XPD Management -------------------------*/
+/*
+ * Called by put_xpd() when XPD has no more references.
+ */
+static void xpd_destroy(struct kref *kref)
+{
+ xpd_t *xpd;
+
+ xpd = kref_to_xpd(kref);
+ XPD_NOTICE(xpd, "%s\n", __func__);
+ xpd_device_unregister(xpd);
+}
+
int refcount_xpd(xpd_t *xpd)
{
- struct kref *kref = &xpd->xpd_dev.kobj.kref;
+ struct kref *kref = &xpd->kref;
return atomic_read(&kref->refcount);
}
xpd_t *get_xpd(const char *msg, xpd_t *xpd)
{
- struct device *dev;
-
XPD_DBG(DEVICES, xpd, "%s: refcount_xpd=%d\n",
msg, refcount_xpd(xpd));
- dev = get_device(&xpd->xpd_dev);
- if (!dev)
- return NULL;
- return dev_to_xpd(dev);
+ kref_get(&xpd->kref);
+ return xpd;
}
void put_xpd(const char *msg, xpd_t *xpd)
{
XPD_DBG(DEVICES, xpd, "%s: refcount_xpd=%d\n",
msg, refcount_xpd(xpd));
- put_device(&xpd->xpd_dev);
+ kref_put(&xpd->kref, xpd_destroy);
}
static void xpd_proc_remove(xbus_t *xbus, xpd_t *xpd)
@@ -539,6 +547,7 @@
atomic_set(&xpd->dahdi_registered, 0);
atomic_set(&xpd->open_counter, 0);
+ kref_init(&xpd->kref);
/* For USB-1 disable some channels */
if(MAX_SEND_SIZE(xbus) < RPACKET_SIZE(GLOBAL, PCM_WRITE)) {
@@ -614,7 +623,6 @@
dahdi_qevent_lock(XPD_CHAN(xpd, j),DAHDI_EVENT_REMOVED);
}
}
- xpd_device_unregister(xpd);
}
}
}
More information about the dahdi-commits
mailing list