summaryrefslogtreecommitdiff
path: root/drivers/dahdi/xpp/xpp_dahdi.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/xpp_dahdi.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/xpp_dahdi.c')
-rw-r--r--drivers/dahdi/xpp/xpp_dahdi.c26
1 files changed, 17 insertions, 9 deletions
diff --git a/drivers/dahdi/xpp/xpp_dahdi.c b/drivers/dahdi/xpp/xpp_dahdi.c
index 1f57878..07041fc 100644
--- a/drivers/dahdi/xpp/xpp_dahdi.c
+++ b/drivers/dahdi/xpp/xpp_dahdi.c
@@ -122,30 +122,38 @@ static int proc_xpd_blink_write(struct file *file, const char __user *buffer, un
/*------------------------- 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 @@ __must_check xpd_t *xpd_alloc(xbus_t *xbus,
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 @@ void xbus_request_removal(xbus_t *xbus)
dahdi_qevent_lock(XPD_CHAN(xpd, j),DAHDI_EVENT_REMOVED);
}
}
- xpd_device_unregister(xpd);
}
}
}