summaryrefslogtreecommitdiffstats
path: root/net/bluetooth/rfcomm/tty.c
diff options
context:
space:
mode:
authorPeter Hurley <peter@hurleysoftware.com>2014-02-10 02:59:19 +0100
committerMarcel Holtmann <marcel@holtmann.org>2014-02-14 22:39:31 +0100
commitf355095756c2a0b77a5b0aa0384c0c09d9735252 (patch)
tree0398680c23156f609f1a95d10430b37c2b193fe0 /net/bluetooth/rfcomm/tty.c
parentBluetooth: Serialize RFCOMMCREATEDEV and RFCOMMRELEASEDEV ioctls (diff)
downloadlinux-f355095756c2a0b77a5b0aa0384c0c09d9735252.tar.xz
linux-f355095756c2a0b77a5b0aa0384c0c09d9735252.zip
Bluetooth: Refactor rfcomm_dev_add()
Move rfcomm_dev allocation and initialization into new function, __rfcomm_dev_add(), to simplify resource release in error handling. Signed-off-by: Peter Hurley <peter@hurleysoftware.com> Tested-By: Alexander Holler <holler@ahsoftware.de> Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
Diffstat (limited to 'net/bluetooth/rfcomm/tty.c')
-rw-r--r--net/bluetooth/rfcomm/tty.c38
1 files changed, 24 insertions, 14 deletions
diff --git a/net/bluetooth/rfcomm/tty.c b/net/bluetooth/rfcomm/tty.c
index ef2769553dab..0537a0501595 100644
--- a/net/bluetooth/rfcomm/tty.c
+++ b/net/bluetooth/rfcomm/tty.c
@@ -208,17 +208,16 @@ static ssize_t show_channel(struct device *tty_dev, struct device_attribute *att
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)
+static struct rfcomm_dev *__rfcomm_dev_add(struct rfcomm_dev_req *req,
+ struct rfcomm_dlc *dlc)
{
struct rfcomm_dev *dev, *entry;
struct list_head *head = &rfcomm_dev_list;
int err = 0;
- BT_DBG("id %d channel %d", req->dev_id, req->channel);
-
dev = kzalloc(sizeof(struct rfcomm_dev), GFP_KERNEL);
if (!dev)
- return -ENOMEM;
+ return ERR_PTR(-ENOMEM);
spin_lock(&rfcomm_dev_lock);
@@ -301,22 +300,37 @@ static int rfcomm_dev_add(struct rfcomm_dev_req *req, struct rfcomm_dlc *dlc)
holds reference to this module. */
__module_get(THIS_MODULE);
+ spin_unlock(&rfcomm_dev_lock);
+ return dev;
+
out:
spin_unlock(&rfcomm_dev_lock);
+ kfree(dev);
+ return ERR_PTR(err);
+}
- if (err < 0)
- goto free;
+static int rfcomm_dev_add(struct rfcomm_dev_req *req, struct rfcomm_dlc *dlc)
+{
+ struct rfcomm_dev *dev;
+ struct device *tty;
+
+ BT_DBG("id %d channel %d", req->dev_id, req->channel);
- dev->tty_dev = tty_port_register_device(&dev->port, rfcomm_tty_driver,
+ dev = __rfcomm_dev_add(req, dlc);
+ if (IS_ERR(dev))
+ return PTR_ERR(dev);
+
+ tty = tty_port_register_device(&dev->port, rfcomm_tty_driver,
dev->id, NULL);
- if (IS_ERR(dev->tty_dev)) {
- err = PTR_ERR(dev->tty_dev);
+ if (IS_ERR(tty)) {
spin_lock(&rfcomm_dev_lock);
list_del(&dev->list);
spin_unlock(&rfcomm_dev_lock);
- goto free;
+ kfree(dev);
+ return PTR_ERR(tty);
}
+ dev->tty_dev = tty;
rfcomm_reparent_device(dev);
dev_set_drvdata(dev->tty_dev, dev);
@@ -327,10 +341,6 @@ out:
BT_ERR("Failed to create channel attribute");
return dev->id;
-
-free:
- kfree(dev);
- return err;
}
/* ---- Send buffer ---- */