Browse Source

TTY: rfcomm/tty, use count from tty_port

This means converting an atomic counter to a counter protected by
lock. This is the first step needed to convert the rest of the code to
the tty_port helpers.

Signed-off-by: Jiri Slaby <jslaby@suse.cz>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Jiri Slaby 13 years ago
parent
commit
f997a01e32
1 changed files with 21 additions and 9 deletions
  1. 21 9
      net/bluetooth/rfcomm/tty.c

+ 21 - 9
net/bluetooth/rfcomm/tty.c

@@ -54,7 +54,6 @@ struct rfcomm_dev {
 	char			name[12];
 	char			name[12];
 	int			id;
 	int			id;
 	unsigned long		flags;
 	unsigned long		flags;
-	atomic_t		opened;
 	int			err;
 	int			err;
 
 
 	bdaddr_t		src;
 	bdaddr_t		src;
@@ -240,8 +239,6 @@ static int rfcomm_dev_add(struct rfcomm_dev_req *req, struct rfcomm_dlc *dlc)
 	dev->flags = req->flags &
 	dev->flags = req->flags &
 		((1 << RFCOMM_RELEASE_ONHUP) | (1 << RFCOMM_REUSE_DLC));
 		((1 << RFCOMM_RELEASE_ONHUP) | (1 << RFCOMM_REUSE_DLC));
 
 
-	atomic_set(&dev->opened, 0);
-
 	tty_port_init(&dev->port);
 	tty_port_init(&dev->port);
 	dev->port.ops = &rfcomm_port_ops;
 	dev->port.ops = &rfcomm_port_ops;
 	init_waitqueue_head(&dev->wait);
 	init_waitqueue_head(&dev->wait);
@@ -311,12 +308,17 @@ free:
 
 
 static void rfcomm_dev_del(struct rfcomm_dev *dev)
 static void rfcomm_dev_del(struct rfcomm_dev *dev)
 {
 {
+	unsigned long flags;
 	BT_DBG("dev %p", dev);
 	BT_DBG("dev %p", dev);
 
 
 	BUG_ON(test_and_set_bit(RFCOMM_TTY_RELEASED, &dev->flags));
 	BUG_ON(test_and_set_bit(RFCOMM_TTY_RELEASED, &dev->flags));
 
 
-	if (atomic_read(&dev->opened) > 0)
+	spin_lock_irqsave(&dev->port.lock, flags);
+	if (dev->port.count > 0) {
+		spin_unlock_irqrestore(&dev->port.lock, flags);
 		return;
 		return;
+	}
+	spin_unlock_irqrestore(&dev->port.lock, flags);
 
 
 	spin_lock(&rfcomm_dev_lock);
 	spin_lock(&rfcomm_dev_lock);
 	list_del_init(&dev->list);
 	list_del_init(&dev->list);
@@ -651,6 +653,7 @@ static int rfcomm_tty_open(struct tty_struct *tty, struct file *filp)
 	DECLARE_WAITQUEUE(wait, current);
 	DECLARE_WAITQUEUE(wait, current);
 	struct rfcomm_dev *dev;
 	struct rfcomm_dev *dev;
 	struct rfcomm_dlc *dlc;
 	struct rfcomm_dlc *dlc;
+	unsigned long flags;
 	int err, id;
 	int err, id;
 
 
 	id = tty->index;
 	id = tty->index;
@@ -666,10 +669,14 @@ static int rfcomm_tty_open(struct tty_struct *tty, struct file *filp)
 		return -ENODEV;
 		return -ENODEV;
 
 
 	BT_DBG("dev %p dst %s channel %d opened %d", dev, batostr(&dev->dst),
 	BT_DBG("dev %p dst %s channel %d opened %d", dev, batostr(&dev->dst),
-				dev->channel, atomic_read(&dev->opened));
+				dev->channel, dev->port.count);
 
 
-	if (atomic_inc_return(&dev->opened) > 1)
+	spin_lock_irqsave(&dev->port.lock, flags);
+	if (++dev->port.count > 1) {
+		spin_unlock_irqrestore(&dev->port.lock, flags);
 		return 0;
 		return 0;
+	}
+	spin_unlock_irqrestore(&dev->port.lock, flags);
 
 
 	dlc = dev->dlc;
 	dlc = dev->dlc;
 
 
@@ -724,13 +731,17 @@ static int rfcomm_tty_open(struct tty_struct *tty, struct file *filp)
 static void rfcomm_tty_close(struct tty_struct *tty, struct file *filp)
 static void rfcomm_tty_close(struct tty_struct *tty, struct file *filp)
 {
 {
 	struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data;
 	struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data;
+	unsigned long flags;
+
 	if (!dev)
 	if (!dev)
 		return;
 		return;
 
 
 	BT_DBG("tty %p dev %p dlc %p opened %d", tty, dev, dev->dlc,
 	BT_DBG("tty %p dev %p dlc %p opened %d", tty, dev, dev->dlc,
-						atomic_read(&dev->opened));
+						dev->port.count);
 
 
-	if (atomic_dec_and_test(&dev->opened)) {
+	spin_lock_irqsave(&dev->port.lock, flags);
+	if (!--dev->port.count) {
+		spin_unlock_irqrestore(&dev->port.lock, flags);
 		if (dev->tty_dev->parent)
 		if (dev->tty_dev->parent)
 			device_move(dev->tty_dev, NULL, DPM_ORDER_DEV_LAST);
 			device_move(dev->tty_dev, NULL, DPM_ORDER_DEV_LAST);
 
 
@@ -751,7 +762,8 @@ static void rfcomm_tty_close(struct tty_struct *tty, struct file *filp)
 
 
 			tty_port_put(&dev->port);
 			tty_port_put(&dev->port);
 		}
 		}
-	}
+	} else
+		spin_unlock_irqrestore(&dev->port.lock, flags);
 
 
 	tty_port_put(&dev->port);
 	tty_port_put(&dev->port);
 }
 }