BT_DBG("dev %p dlc %p", dev, dlc);
- write_lock_bh(&rfcomm_dev_lock);
- list_del_init(&dev->list);
- write_unlock_bh(&rfcomm_dev_lock);
+ /* Refcount should only hit zero when called from rfcomm_dev_del()
+ which will have taken us off the list. Everything else are
+ refcounting bugs. */
+ BUG_ON(!list_empty(&dev->list));
rfcomm_dlc_lock(dlc);
/* Detach DLC if it's owned by this dev */
tty_unregister_device(rfcomm_tty_driver, dev->id);
- /* Refcount should only hit zero when called from rfcomm_dev_del()
- which will have taken us off the list. Everything else are
- refcounting bugs. */
- BUG_ON(!list_empty(&dev->list));
-
kfree(dev);
/* It's safe to call module_put() here because socket still
return conn ? &conn->dev : NULL;
}
+static ssize_t show_address(struct device *tty_dev, struct device_attribute *attr, char *buf)
+{
+ struct rfcomm_dev *dev = dev_get_drvdata(tty_dev);
+ bdaddr_t bdaddr;
+ baswap(&bdaddr, &dev->dst);
+ return sprintf(buf, "%s\n", batostr(&bdaddr));
+}
+
+static ssize_t show_channel(struct device *tty_dev, struct device_attribute *attr, char *buf)
+{
+ struct rfcomm_dev *dev = dev_get_drvdata(tty_dev);
+ return sprintf(buf, "%d\n", dev->channel);
+}
+
+static DEVICE_ATTR(address, S_IRUGO, show_address, NULL);
+static DEVICE_ATTR(channel, S_IRUGO, show_channel, NULL);
+
static int rfcomm_dev_add(struct rfcomm_dev_req *req, struct rfcomm_dlc *dlc)
{
struct rfcomm_dev *dev;
out:
write_unlock_bh(&rfcomm_dev_lock);
- if (err) {
+ if (err < 0) {
kfree(dev);
return err;
}
dev->tty_dev = tty_register_device(rfcomm_tty_driver, dev->id, NULL);
if (IS_ERR(dev->tty_dev)) {
+ err = PTR_ERR(dev->tty_dev);
list_del(&dev->list);
kfree(dev);
- return PTR_ERR(dev->tty_dev);
+ return err;
}
+ dev_set_drvdata(dev->tty_dev, dev);
+
+ if (device_create_file(dev->tty_dev, &dev_attr_address) < 0)
+ BT_ERR("Failed to create address attribute");
+
+ if (device_create_file(dev->tty_dev, &dev_attr_channel) < 0)
+ BT_ERR("Failed to create channel attribute");
+
return dev->id;
}
{
BT_DBG("dev %p", dev);
- set_bit(RFCOMM_TTY_RELEASED, &dev->flags);
+ if (test_bit(RFCOMM_TTY_RELEASED, &dev->flags))
+ BUG_ON(1);
+ else
+ set_bit(RFCOMM_TTY_RELEASED, &dev->flags);
+
+ write_lock_bh(&rfcomm_dev_lock);
+ list_del_init(&dev->list);
+ write_unlock_bh(&rfcomm_dev_lock);
+
rfcomm_dev_put(dev);
}
BT_DBG("tty %p dev %p dlc %p opened %d", tty, dev, dev->dlc, dev->opened);
if (--dev->opened == 0) {
- device_move(dev->tty_dev, NULL);
+ if (dev->tty_dev->parent)
+ device_move(dev->tty_dev, NULL);
/* Close DLC and dettach TTY */
rfcomm_dlc_close(dev->dlc, 0);