summaryrefslogtreecommitdiff
path: root/drivers/dahdi/xpp/xbus-core.c
diff options
context:
space:
mode:
authorTzafrir Cohen <tzafrir.cohen@xorcom.com>2010-07-13 15:10:30 +0000
committerTzafrir Cohen <tzafrir.cohen@xorcom.com>2010-07-13 15:10:30 +0000
commitfe0081acc9a07f762121338e9e3f523b240ed178 (patch)
treee8e2174cb2e859ef0e22b987a0f9544e26d44628 /drivers/dahdi/xpp/xbus-core.c
parent921654884fd0ad506e7f7f6a34760a905f96b2ea (diff)
Keep SYSFS objects after disconnect
When the USB device disconnects, we keep references to them to make sure they don't disappear. git-svn-id: http://svn.asterisk.org/svn/dahdi/linux/trunk@8900 a0bf4364-ded3-4de4-8d8a-66a801d63aff
Diffstat (limited to 'drivers/dahdi/xpp/xbus-core.c')
-rw-r--r--drivers/dahdi/xpp/xbus-core.c37
1 files changed, 26 insertions, 11 deletions
diff --git a/drivers/dahdi/xpp/xbus-core.c b/drivers/dahdi/xpp/xbus-core.c
index 569b678..2d2ecb4 100644
--- a/drivers/dahdi/xpp/xbus-core.c
+++ b/drivers/dahdi/xpp/xbus-core.c
@@ -141,28 +141,36 @@ static void finalize_xbuses_array(void)
}
}
-xbus_t *get_xbus(const char *msg, xbus_t *xbus)
+/*
+ * Called by put_xbus() when XBUS has no more references.
+ */
+static void xbus_destroy(struct kref *kref)
{
- struct device *dev;
+ 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)
+{
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 @@ static void worker_reset(xbus_t *xbus)
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 @@ void xbus_deactivate(xbus_t *xbus)
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 @@ void xbus_disconnect(xbus_t *xbus)
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,6 +1435,7 @@ xbus_t *xbus_new(struct xbus_ops *ops, ushort max_send_size, struct device *tran
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;
@@ -1435,6 +1444,12 @@ xbus_t *xbus_new(struct xbus_ops *ops, ushort max_send_size, struct device *tran
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);
#ifdef CONFIG_PROC_FS
XBUS_DBG(PROC, xbus, "Creating xbus proc directory\n");