blob: 9c0e142041bdc5ef7de97d572d1af70ef5b21d36 [file] [log] [blame]
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09001/*
Linus Torvalds1da177e2005-04-16 15:20:36 -07002 RFCOMM implementation for Linux Bluetooth stack (BlueZ).
3 Copyright (C) 2002 Maxim Krasnyansky <maxk@qualcomm.com>
4 Copyright (C) 2002 Marcel Holtmann <marcel@holtmann.org>
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License version 2 as
8 published by the Free Software Foundation;
9
10 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
11 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
12 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
13 IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +090014 CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
15 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
Linus Torvalds1da177e2005-04-16 15:20:36 -070017 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +090019 ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
20 COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
Linus Torvalds1da177e2005-04-16 15:20:36 -070021 SOFTWARE IS DISCLAIMED.
22*/
23
24/*
25 * RFCOMM TTY.
Linus Torvalds1da177e2005-04-16 15:20:36 -070026 */
27
Linus Torvalds1da177e2005-04-16 15:20:36 -070028#include <linux/module.h>
29
30#include <linux/tty.h>
31#include <linux/tty_driver.h>
32#include <linux/tty_flip.h>
33
Linus Torvalds1da177e2005-04-16 15:20:36 -070034#include <net/bluetooth/bluetooth.h>
Marcel Holtmann0a85b962006-07-06 13:09:02 +020035#include <net/bluetooth/hci_core.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070036#include <net/bluetooth/rfcomm.h>
37
Linus Torvalds1da177e2005-04-16 15:20:36 -070038#define RFCOMM_TTY_MAGIC 0x6d02 /* magic number for rfcomm struct */
39#define RFCOMM_TTY_PORTS RFCOMM_MAX_DEV /* whole lotta rfcomm devices */
40#define RFCOMM_TTY_MAJOR 216 /* device node major id of the usb/bluetooth.c driver */
41#define RFCOMM_TTY_MINOR 0
42
43static struct tty_driver *rfcomm_tty_driver;
44
45struct rfcomm_dev {
Jiri Slabyf60db8c2012-04-02 13:54:50 +020046 struct tty_port port;
Linus Torvalds1da177e2005-04-16 15:20:36 -070047 struct list_head list;
Linus Torvalds1da177e2005-04-16 15:20:36 -070048
49 char name[12];
50 int id;
51 unsigned long flags;
Linus Torvalds1da177e2005-04-16 15:20:36 -070052 int err;
53
54 bdaddr_t src;
55 bdaddr_t dst;
Andrei Emeltchenko285b4e92010-12-01 16:58:23 +020056 u8 channel;
Linus Torvalds1da177e2005-04-16 15:20:36 -070057
Andrei Emeltchenko285b4e92010-12-01 16:58:23 +020058 uint modem_status;
Linus Torvalds1da177e2005-04-16 15:20:36 -070059
60 struct rfcomm_dlc *dlc;
Linus Torvalds1da177e2005-04-16 15:20:36 -070061 wait_queue_head_t wait;
Linus Torvalds1da177e2005-04-16 15:20:36 -070062
Marcel Holtmannc1a33132007-02-17 23:58:57 +010063 struct device *tty_dev;
64
Andrei Emeltchenko285b4e92010-12-01 16:58:23 +020065 atomic_t wmem_alloc;
Marcel Holtmanna0c22f22008-07-14 20:13:52 +020066
67 struct sk_buff_head pending;
Linus Torvalds1da177e2005-04-16 15:20:36 -070068};
69
70static LIST_HEAD(rfcomm_dev_list);
Gustavo F. Padovan393432c2011-12-27 15:28:45 -020071static DEFINE_SPINLOCK(rfcomm_dev_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -070072
73static void rfcomm_dev_data_ready(struct rfcomm_dlc *dlc, struct sk_buff *skb);
74static void rfcomm_dev_state_change(struct rfcomm_dlc *dlc, int err);
75static void rfcomm_dev_modem_status(struct rfcomm_dlc *dlc, u8 v24_sig);
76
Linus Torvalds1da177e2005-04-16 15:20:36 -070077/* ---- Device functions ---- */
Jiri Slaby67054012012-04-02 13:54:51 +020078
Jiri Slaby67054012012-04-02 13:54:51 +020079static void rfcomm_dev_destruct(struct tty_port *port)
Linus Torvalds1da177e2005-04-16 15:20:36 -070080{
Jiri Slaby67054012012-04-02 13:54:51 +020081 struct rfcomm_dev *dev = container_of(port, struct rfcomm_dev, port);
Linus Torvalds1da177e2005-04-16 15:20:36 -070082 struct rfcomm_dlc *dlc = dev->dlc;
83
84 BT_DBG("dev %p dlc %p", dev, dlc);
85
Gianluca Anzolinebe937f2013-07-29 17:08:09 +020086 spin_lock(&rfcomm_dev_lock);
87 list_del(&dev->list);
88 spin_unlock(&rfcomm_dev_lock);
Ville Tervo8de0a152007-07-11 09:23:41 +020089
Linus Torvalds1da177e2005-04-16 15:20:36 -070090 rfcomm_dlc_lock(dlc);
91 /* Detach DLC if it's owned by this dev */
92 if (dlc->owner == dev)
93 dlc->owner = NULL;
94 rfcomm_dlc_unlock(dlc);
95
96 rfcomm_dlc_put(dlc);
97
98 tty_unregister_device(rfcomm_tty_driver, dev->id);
99
Linus Torvalds1da177e2005-04-16 15:20:36 -0700100 kfree(dev);
101
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900102 /* It's safe to call module_put() here because socket still
Linus Torvalds1da177e2005-04-16 15:20:36 -0700103 holds reference to this module. */
104 module_put(THIS_MODULE);
105}
106
Jiri Slaby67054012012-04-02 13:54:51 +0200107static const struct tty_port_operations rfcomm_port_ops = {
108 .destruct = rfcomm_dev_destruct,
109};
Linus Torvalds1da177e2005-04-16 15:20:36 -0700110
111static struct rfcomm_dev *__rfcomm_dev_get(int id)
112{
113 struct rfcomm_dev *dev;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700114
Luiz Augusto von Dentz8035ded2011-11-01 10:58:56 +0200115 list_for_each_entry(dev, &rfcomm_dev_list, list)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700116 if (dev->id == id)
117 return dev;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700118
119 return NULL;
120}
121
Gustavo Padovan6039aa72012-05-23 04:04:18 -0300122static struct rfcomm_dev *rfcomm_dev_get(int id)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700123{
124 struct rfcomm_dev *dev;
125
Gustavo F. Padovan393432c2011-12-27 15:28:45 -0200126 spin_lock(&rfcomm_dev_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700127
128 dev = __rfcomm_dev_get(id);
Ville Tervo8de0a152007-07-11 09:23:41 +0200129
130 if (dev) {
131 if (test_bit(RFCOMM_TTY_RELEASED, &dev->flags))
132 dev = NULL;
133 else
Jiri Slaby67054012012-04-02 13:54:51 +0200134 tty_port_get(&dev->port);
Ville Tervo8de0a152007-07-11 09:23:41 +0200135 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700136
Gustavo F. Padovan393432c2011-12-27 15:28:45 -0200137 spin_unlock(&rfcomm_dev_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700138
139 return dev;
140}
141
Marcel Holtmann0a85b962006-07-06 13:09:02 +0200142static struct device *rfcomm_get_device(struct rfcomm_dev *dev)
143{
144 struct hci_dev *hdev;
145 struct hci_conn *conn;
146
147 hdev = hci_get_route(&dev->dst, &dev->src);
148 if (!hdev)
149 return NULL;
150
151 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &dev->dst);
Marcel Holtmann0a85b962006-07-06 13:09:02 +0200152
153 hci_dev_put(hdev);
154
Marcel Holtmannb2cfcd72006-10-15 17:31:05 +0200155 return conn ? &conn->dev : NULL;
Marcel Holtmann0a85b962006-07-06 13:09:02 +0200156}
157
Marcel Holtmanndae6a0f2007-10-20 14:52:38 +0200158static ssize_t show_address(struct device *tty_dev, struct device_attribute *attr, char *buf)
159{
160 struct rfcomm_dev *dev = dev_get_drvdata(tty_dev);
Andrei Emeltchenkofcb73332012-09-25 12:49:44 +0300161 return sprintf(buf, "%pMR\n", &dev->dst);
Marcel Holtmanndae6a0f2007-10-20 14:52:38 +0200162}
163
164static ssize_t show_channel(struct device *tty_dev, struct device_attribute *attr, char *buf)
165{
166 struct rfcomm_dev *dev = dev_get_drvdata(tty_dev);
167 return sprintf(buf, "%d\n", dev->channel);
168}
169
170static DEVICE_ATTR(address, S_IRUGO, show_address, NULL);
171static DEVICE_ATTR(channel, S_IRUGO, show_channel, NULL);
172
Linus Torvalds1da177e2005-04-16 15:20:36 -0700173static int rfcomm_dev_add(struct rfcomm_dev_req *req, struct rfcomm_dlc *dlc)
174{
Luiz Augusto von Dentz8035ded2011-11-01 10:58:56 +0200175 struct rfcomm_dev *dev, *entry;
Luiz Augusto von Dentze57d758a2012-03-07 20:20:14 +0200176 struct list_head *head = &rfcomm_dev_list;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700177 int err = 0;
178
179 BT_DBG("id %d channel %d", req->dev_id, req->channel);
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900180
Marcel Holtmann25ea6db2006-07-06 15:40:09 +0200181 dev = kzalloc(sizeof(struct rfcomm_dev), GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700182 if (!dev)
183 return -ENOMEM;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700184
Gustavo F. Padovan393432c2011-12-27 15:28:45 -0200185 spin_lock(&rfcomm_dev_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700186
187 if (req->dev_id < 0) {
188 dev->id = 0;
189
Luiz Augusto von Dentz8035ded2011-11-01 10:58:56 +0200190 list_for_each_entry(entry, &rfcomm_dev_list, list) {
191 if (entry->id != dev->id)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700192 break;
193
194 dev->id++;
Luiz Augusto von Dentze57d758a2012-03-07 20:20:14 +0200195 head = &entry->list;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700196 }
197 } else {
198 dev->id = req->dev_id;
199
Luiz Augusto von Dentz8035ded2011-11-01 10:58:56 +0200200 list_for_each_entry(entry, &rfcomm_dev_list, list) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700201 if (entry->id == dev->id) {
202 err = -EADDRINUSE;
203 goto out;
204 }
205
206 if (entry->id > dev->id - 1)
207 break;
208
Luiz Augusto von Dentze57d758a2012-03-07 20:20:14 +0200209 head = &entry->list;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700210 }
211 }
212
213 if ((dev->id < 0) || (dev->id > RFCOMM_MAX_DEV - 1)) {
214 err = -ENFILE;
215 goto out;
216 }
217
218 sprintf(dev->name, "rfcomm%d", dev->id);
219
220 list_add(&dev->list, head);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700221
222 bacpy(&dev->src, &req->src);
223 bacpy(&dev->dst, &req->dst);
224 dev->channel = req->channel;
225
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900226 dev->flags = req->flags &
Linus Torvalds1da177e2005-04-16 15:20:36 -0700227 ((1 << RFCOMM_RELEASE_ONHUP) | (1 << RFCOMM_REUSE_DLC));
228
Jiri Slabyf60db8c2012-04-02 13:54:50 +0200229 tty_port_init(&dev->port);
Jiri Slaby67054012012-04-02 13:54:51 +0200230 dev->port.ops = &rfcomm_port_ops;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700231 init_waitqueue_head(&dev->wait);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700232
Marcel Holtmanna0c22f22008-07-14 20:13:52 +0200233 skb_queue_head_init(&dev->pending);
234
Linus Torvalds1da177e2005-04-16 15:20:36 -0700235 rfcomm_dlc_lock(dlc);
Marcel Holtmanna0c22f22008-07-14 20:13:52 +0200236
237 if (req->flags & (1 << RFCOMM_REUSE_DLC)) {
238 struct sock *sk = dlc->owner;
239 struct sk_buff *skb;
240
241 BUG_ON(!sk);
242
243 rfcomm_dlc_throttle(dlc);
244
245 while ((skb = skb_dequeue(&sk->sk_receive_queue))) {
246 skb_orphan(skb);
247 skb_queue_tail(&dev->pending, skb);
248 atomic_sub(skb->len, &sk->sk_rmem_alloc);
249 }
250 }
251
Linus Torvalds1da177e2005-04-16 15:20:36 -0700252 dlc->data_ready = rfcomm_dev_data_ready;
253 dlc->state_change = rfcomm_dev_state_change;
254 dlc->modem_status = rfcomm_dev_modem_status;
255
256 dlc->owner = dev;
257 dev->dlc = dlc;
Marcel Holtmann8b6b3da2008-07-14 20:13:52 +0200258
259 rfcomm_dev_modem_status(dlc, dlc->remote_v24_sig);
260
Linus Torvalds1da177e2005-04-16 15:20:36 -0700261 rfcomm_dlc_unlock(dlc);
262
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900263 /* It's safe to call __module_get() here because socket already
Linus Torvalds1da177e2005-04-16 15:20:36 -0700264 holds reference to this module. */
265 __module_get(THIS_MODULE);
266
267out:
Gustavo F. Padovan393432c2011-12-27 15:28:45 -0200268 spin_unlock(&rfcomm_dev_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700269
Ilpo Järvinen037322a2008-12-14 23:18:00 -0800270 if (err < 0)
271 goto free;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700272
Jiri Slaby734cc172012-08-07 21:47:47 +0200273 dev->tty_dev = tty_port_register_device(&dev->port, rfcomm_tty_driver,
274 dev->id, NULL);
Ville Tervo8de0a152007-07-11 09:23:41 +0200275 if (IS_ERR(dev->tty_dev)) {
Marcel Holtmann09c7d822007-07-26 00:12:25 -0700276 err = PTR_ERR(dev->tty_dev);
Gianluca Anzolinebe937f2013-07-29 17:08:09 +0200277 spin_lock(&rfcomm_dev_lock);
Ville Tervo8de0a152007-07-11 09:23:41 +0200278 list_del(&dev->list);
Gianluca Anzolinebe937f2013-07-29 17:08:09 +0200279 spin_unlock(&rfcomm_dev_lock);
Ilpo Järvinen037322a2008-12-14 23:18:00 -0800280 goto free;
Ville Tervo8de0a152007-07-11 09:23:41 +0200281 }
282
Marcel Holtmanndae6a0f2007-10-20 14:52:38 +0200283 dev_set_drvdata(dev->tty_dev, dev);
284
285 if (device_create_file(dev->tty_dev, &dev_attr_address) < 0)
286 BT_ERR("Failed to create address attribute");
287
288 if (device_create_file(dev->tty_dev, &dev_attr_channel) < 0)
289 BT_ERR("Failed to create channel attribute");
290
Linus Torvalds1da177e2005-04-16 15:20:36 -0700291 return dev->id;
Ilpo Järvinen037322a2008-12-14 23:18:00 -0800292
293free:
294 kfree(dev);
295 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700296}
297
298static void rfcomm_dev_del(struct rfcomm_dev *dev)
299{
Jiri Slabyf997a012012-04-02 13:54:53 +0200300 unsigned long flags;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700301 BT_DBG("dev %p", dev);
302
Marcel Holtmann9a5df922008-11-30 12:17:29 +0100303 BUG_ON(test_and_set_bit(RFCOMM_TTY_RELEASED, &dev->flags));
304
Jiri Slabyf997a012012-04-02 13:54:53 +0200305 spin_lock_irqsave(&dev->port.lock, flags);
306 if (dev->port.count > 0) {
307 spin_unlock_irqrestore(&dev->port.lock, flags);
Marcel Holtmann9a5df922008-11-30 12:17:29 +0100308 return;
Jiri Slabyf997a012012-04-02 13:54:53 +0200309 }
310 spin_unlock_irqrestore(&dev->port.lock, flags);
Dave Youngf9513752008-01-10 22:22:52 -0800311
Jiri Slaby67054012012-04-02 13:54:51 +0200312 tty_port_put(&dev->port);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700313}
314
315/* ---- Send buffer ---- */
316static inline unsigned int rfcomm_room(struct rfcomm_dlc *dlc)
317{
318 /* We can't let it be zero, because we don't get a callback
319 when tx_credits becomes nonzero, hence we'd never wake up */
320 return dlc->mtu * (dlc->tx_credits?:1);
321}
322
323static void rfcomm_wfree(struct sk_buff *skb)
324{
325 struct rfcomm_dev *dev = (void *) skb->sk;
326 atomic_sub(skb->truesize, &dev->wmem_alloc);
Gianluca Anzolin396dc222013-07-29 17:08:08 +0200327 if (test_bit(RFCOMM_TTY_ATTACHED, &dev->flags))
328 tty_port_tty_wakeup(&dev->port);
Jiri Slaby67054012012-04-02 13:54:51 +0200329 tty_port_put(&dev->port);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700330}
331
Gustavo Padovan6039aa72012-05-23 04:04:18 -0300332static void rfcomm_set_owner_w(struct sk_buff *skb, struct rfcomm_dev *dev)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700333{
Jiri Slaby67054012012-04-02 13:54:51 +0200334 tty_port_get(&dev->port);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700335 atomic_add(skb->truesize, &dev->wmem_alloc);
336 skb->sk = (void *) dev;
337 skb->destructor = rfcomm_wfree;
338}
339
Al Virodd0fc662005-10-07 07:46:04 +0100340static struct sk_buff *rfcomm_wmalloc(struct rfcomm_dev *dev, unsigned long size, gfp_t priority)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700341{
342 if (atomic_read(&dev->wmem_alloc) < rfcomm_room(dev->dlc)) {
343 struct sk_buff *skb = alloc_skb(size, priority);
344 if (skb) {
345 rfcomm_set_owner_w(skb, dev);
346 return skb;
347 }
348 }
349 return NULL;
350}
351
352/* ---- Device IOCTLs ---- */
353
354#define NOCAP_FLAGS ((1 << RFCOMM_REUSE_DLC) | (1 << RFCOMM_RELEASE_ONHUP))
355
356static int rfcomm_create_dev(struct sock *sk, void __user *arg)
357{
358 struct rfcomm_dev_req req;
359 struct rfcomm_dlc *dlc;
360 int id;
361
362 if (copy_from_user(&req, arg, sizeof(req)))
363 return -EFAULT;
364
Ville Tervo8de0a152007-07-11 09:23:41 +0200365 BT_DBG("sk %p dev_id %d flags 0x%x", sk, req.dev_id, req.flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700366
367 if (req.flags != NOCAP_FLAGS && !capable(CAP_NET_ADMIN))
368 return -EPERM;
369
370 if (req.flags & (1 << RFCOMM_REUSE_DLC)) {
371 /* Socket must be connected */
372 if (sk->sk_state != BT_CONNECTED)
373 return -EBADFD;
374
375 dlc = rfcomm_pi(sk)->dlc;
376 rfcomm_dlc_hold(dlc);
377 } else {
378 dlc = rfcomm_dlc_alloc(GFP_KERNEL);
379 if (!dlc)
380 return -ENOMEM;
381 }
382
383 id = rfcomm_dev_add(&req, dlc);
384 if (id < 0) {
385 rfcomm_dlc_put(dlc);
386 return id;
387 }
388
389 if (req.flags & (1 << RFCOMM_REUSE_DLC)) {
390 /* DLC is now used by device.
391 * Socket must be disconnected */
392 sk->sk_state = BT_CLOSED;
393 }
394
395 return id;
396}
397
398static int rfcomm_release_dev(void __user *arg)
399{
400 struct rfcomm_dev_req req;
401 struct rfcomm_dev *dev;
Gianluca Anzolin396dc222013-07-29 17:08:08 +0200402 struct tty_struct *tty;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700403
404 if (copy_from_user(&req, arg, sizeof(req)))
405 return -EFAULT;
406
Ville Tervo8de0a152007-07-11 09:23:41 +0200407 BT_DBG("dev_id %d flags 0x%x", req.dev_id, req.flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700408
Andrei Emeltchenko285b4e92010-12-01 16:58:23 +0200409 dev = rfcomm_dev_get(req.dev_id);
410 if (!dev)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700411 return -ENODEV;
412
413 if (dev->flags != NOCAP_FLAGS && !capable(CAP_NET_ADMIN)) {
Jiri Slaby67054012012-04-02 13:54:51 +0200414 tty_port_put(&dev->port);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700415 return -EPERM;
416 }
417
418 if (req.flags & (1 << RFCOMM_HANGUP_NOW))
419 rfcomm_dlc_close(dev->dlc, 0);
420
Mikko Rapeli84950cf2007-07-11 09:18:15 +0200421 /* Shut down TTY synchronously before freeing rfcomm_dev */
Gianluca Anzolin396dc222013-07-29 17:08:08 +0200422 tty = tty_port_tty_get(&dev->port);
423 if (tty) {
424 tty_vhangup(tty);
425 tty_kref_put(tty);
426 }
Mikko Rapeli84950cf2007-07-11 09:18:15 +0200427
Dave Young93d80742008-02-05 03:12:06 -0800428 if (!test_bit(RFCOMM_RELEASE_ONHUP, &dev->flags))
429 rfcomm_dev_del(dev);
Jiri Slaby67054012012-04-02 13:54:51 +0200430 tty_port_put(&dev->port);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700431 return 0;
432}
433
434static int rfcomm_get_dev_list(void __user *arg)
435{
Luiz Augusto von Dentz8035ded2011-11-01 10:58:56 +0200436 struct rfcomm_dev *dev;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700437 struct rfcomm_dev_list_req *dl;
438 struct rfcomm_dev_info *di;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700439 int n = 0, size, err;
440 u16 dev_num;
441
442 BT_DBG("");
443
444 if (get_user(dev_num, (u16 __user *) arg))
445 return -EFAULT;
446
447 if (!dev_num || dev_num > (PAGE_SIZE * 4) / sizeof(*di))
448 return -EINVAL;
449
450 size = sizeof(*dl) + dev_num * sizeof(*di);
451
Mathias Krausef9432c52012-08-15 11:31:49 +0000452 dl = kzalloc(size, GFP_KERNEL);
Andrei Emeltchenko285b4e92010-12-01 16:58:23 +0200453 if (!dl)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700454 return -ENOMEM;
455
456 di = dl->dev_info;
457
Gustavo F. Padovan393432c2011-12-27 15:28:45 -0200458 spin_lock(&rfcomm_dev_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700459
Luiz Augusto von Dentz8035ded2011-11-01 10:58:56 +0200460 list_for_each_entry(dev, &rfcomm_dev_list, list) {
Ville Tervo8de0a152007-07-11 09:23:41 +0200461 if (test_bit(RFCOMM_TTY_RELEASED, &dev->flags))
462 continue;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700463 (di + n)->id = dev->id;
464 (di + n)->flags = dev->flags;
465 (di + n)->state = dev->dlc->state;
466 (di + n)->channel = dev->channel;
467 bacpy(&(di + n)->src, &dev->src);
468 bacpy(&(di + n)->dst, &dev->dst);
469 if (++n >= dev_num)
470 break;
471 }
472
Gustavo F. Padovan393432c2011-12-27 15:28:45 -0200473 spin_unlock(&rfcomm_dev_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700474
475 dl->dev_num = n;
476 size = sizeof(*dl) + n * sizeof(*di);
477
478 err = copy_to_user(arg, dl, size);
479 kfree(dl);
480
481 return err ? -EFAULT : 0;
482}
483
484static int rfcomm_get_dev_info(void __user *arg)
485{
486 struct rfcomm_dev *dev;
487 struct rfcomm_dev_info di;
488 int err = 0;
489
490 BT_DBG("");
491
492 if (copy_from_user(&di, arg, sizeof(di)))
493 return -EFAULT;
494
Andrei Emeltchenko285b4e92010-12-01 16:58:23 +0200495 dev = rfcomm_dev_get(di.id);
496 if (!dev)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700497 return -ENODEV;
498
499 di.flags = dev->flags;
500 di.channel = dev->channel;
501 di.state = dev->dlc->state;
502 bacpy(&di.src, &dev->src);
503 bacpy(&di.dst, &dev->dst);
504
505 if (copy_to_user(arg, &di, sizeof(di)))
506 err = -EFAULT;
507
Jiri Slaby67054012012-04-02 13:54:51 +0200508 tty_port_put(&dev->port);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700509 return err;
510}
511
512int rfcomm_dev_ioctl(struct sock *sk, unsigned int cmd, void __user *arg)
513{
514 BT_DBG("cmd %d arg %p", cmd, arg);
515
516 switch (cmd) {
517 case RFCOMMCREATEDEV:
518 return rfcomm_create_dev(sk, arg);
519
520 case RFCOMMRELEASEDEV:
521 return rfcomm_release_dev(arg);
522
523 case RFCOMMGETDEVLIST:
524 return rfcomm_get_dev_list(arg);
525
526 case RFCOMMGETDEVINFO:
527 return rfcomm_get_dev_info(arg);
528 }
529
530 return -EINVAL;
531}
532
533/* ---- DLC callbacks ---- */
534static void rfcomm_dev_data_ready(struct rfcomm_dlc *dlc, struct sk_buff *skb)
535{
536 struct rfcomm_dev *dev = dlc->owner;
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900537
Marcel Holtmanna0c22f22008-07-14 20:13:52 +0200538 if (!dev) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700539 kfree_skb(skb);
540 return;
541 }
542
Jiri Slaby2e124b42013-01-03 15:53:06 +0100543 if (!skb_queue_empty(&dev->pending)) {
Marcel Holtmanna0c22f22008-07-14 20:13:52 +0200544 skb_queue_tail(&dev->pending, skb);
545 return;
546 }
547
Jiri Slaby2e124b42013-01-03 15:53:06 +0100548 BT_DBG("dlc %p len %d", dlc, skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700549
Jiri Slaby05c7cd32013-01-03 15:53:04 +0100550 tty_insert_flip_string(&dev->port, skb->data, skb->len);
Jiri Slaby2e124b42013-01-03 15:53:06 +0100551 tty_flip_buffer_push(&dev->port);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700552
553 kfree_skb(skb);
554}
555
556static void rfcomm_dev_state_change(struct rfcomm_dlc *dlc, int err)
557{
558 struct rfcomm_dev *dev = dlc->owner;
Gianluca Anzolin396dc222013-07-29 17:08:08 +0200559 struct tty_struct *tty;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700560 if (!dev)
561 return;
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900562
Linus Torvalds1da177e2005-04-16 15:20:36 -0700563 BT_DBG("dlc %p dev %p err %d", dlc, dev, err);
564
565 dev->err = err;
566 wake_up_interruptible(&dev->wait);
567
568 if (dlc->state == BT_CLOSED) {
Gianluca Anzolin396dc222013-07-29 17:08:08 +0200569 tty = tty_port_tty_get(&dev->port);
570 if (!tty) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700571 if (test_bit(RFCOMM_RELEASE_ONHUP, &dev->flags)) {
Dave Young537d59a2008-06-01 23:50:52 -0700572 /* Drop DLC lock here to avoid deadlock
573 * 1. rfcomm_dev_get will take rfcomm_dev_lock
574 * but in rfcomm_dev_add there's lock order:
575 * rfcomm_dev_lock -> dlc lock
Jiri Slaby67054012012-04-02 13:54:51 +0200576 * 2. tty_port_put will deadlock if it's
Dave Young537d59a2008-06-01 23:50:52 -0700577 * the last reference
578 */
579 rfcomm_dlc_unlock(dlc);
580 if (rfcomm_dev_get(dev->id) == NULL) {
581 rfcomm_dlc_lock(dlc);
Marcel Holtmann77f2a452007-05-05 00:36:10 +0200582 return;
Dave Young537d59a2008-06-01 23:50:52 -0700583 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700584
Marcel Holtmann77f2a452007-05-05 00:36:10 +0200585 rfcomm_dev_del(dev);
Jiri Slaby67054012012-04-02 13:54:51 +0200586 tty_port_put(&dev->port);
Dave Young537d59a2008-06-01 23:50:52 -0700587 rfcomm_dlc_lock(dlc);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700588 }
Gianluca Anzolin396dc222013-07-29 17:08:08 +0200589 } else {
590 tty_hangup(tty);
591 tty_kref_put(tty);
592 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700593 }
594}
595
596static void rfcomm_dev_modem_status(struct rfcomm_dlc *dlc, u8 v24_sig)
597{
598 struct rfcomm_dev *dev = dlc->owner;
599 if (!dev)
600 return;
Timo Teräs7b9eb9e2005-08-09 20:28:21 -0700601
Linus Torvalds1da177e2005-04-16 15:20:36 -0700602 BT_DBG("dlc %p dev %p v24_sig 0x%02x", dlc, dev, v24_sig);
603
Gianluca Anzolin396dc222013-07-29 17:08:08 +0200604 if ((dev->modem_status & TIOCM_CD) && !(v24_sig & RFCOMM_V24_DV))
605 tty_port_tty_hangup(&dev->port, true);
Timo Teräs7b9eb9e2005-08-09 20:28:21 -0700606
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900607 dev->modem_status =
Linus Torvalds1da177e2005-04-16 15:20:36 -0700608 ((v24_sig & RFCOMM_V24_RTC) ? (TIOCM_DSR | TIOCM_DTR) : 0) |
609 ((v24_sig & RFCOMM_V24_RTR) ? (TIOCM_RTS | TIOCM_CTS) : 0) |
610 ((v24_sig & RFCOMM_V24_IC) ? TIOCM_RI : 0) |
611 ((v24_sig & RFCOMM_V24_DV) ? TIOCM_CD : 0);
612}
613
614/* ---- TTY functions ---- */
Marcel Holtmanna0c22f22008-07-14 20:13:52 +0200615static void rfcomm_tty_copy_pending(struct rfcomm_dev *dev)
616{
Marcel Holtmanna0c22f22008-07-14 20:13:52 +0200617 struct sk_buff *skb;
618 int inserted = 0;
619
Jiri Slaby2e124b42013-01-03 15:53:06 +0100620 BT_DBG("dev %p", dev);
Marcel Holtmanna0c22f22008-07-14 20:13:52 +0200621
622 rfcomm_dlc_lock(dev->dlc);
623
624 while ((skb = skb_dequeue(&dev->pending))) {
Jiri Slaby05c7cd32013-01-03 15:53:04 +0100625 inserted += tty_insert_flip_string(&dev->port, skb->data,
626 skb->len);
Marcel Holtmanna0c22f22008-07-14 20:13:52 +0200627 kfree_skb(skb);
628 }
629
630 rfcomm_dlc_unlock(dev->dlc);
631
632 if (inserted > 0)
Jiri Slaby2e124b42013-01-03 15:53:06 +0100633 tty_flip_buffer_push(&dev->port);
Marcel Holtmanna0c22f22008-07-14 20:13:52 +0200634}
635
Linus Torvalds1da177e2005-04-16 15:20:36 -0700636static int rfcomm_tty_open(struct tty_struct *tty, struct file *filp)
637{
638 DECLARE_WAITQUEUE(wait, current);
639 struct rfcomm_dev *dev;
640 struct rfcomm_dlc *dlc;
Jiri Slabyf997a012012-04-02 13:54:53 +0200641 unsigned long flags;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700642 int err, id;
643
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900644 id = tty->index;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700645
646 BT_DBG("tty %p id %d", tty, id);
647
648 /* We don't leak this refcount. For reasons which are not entirely
649 clear, the TTY layer will call our ->close() method even if the
650 open fails. We decrease the refcount there, and decreasing it
651 here too would cause breakage. */
652 dev = rfcomm_dev_get(id);
653 if (!dev)
654 return -ENODEV;
655
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +0300656 BT_DBG("dev %p dst %pMR channel %d opened %d", dev, &dev->dst,
657 dev->channel, dev->port.count);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700658
Jiri Slabyf997a012012-04-02 13:54:53 +0200659 spin_lock_irqsave(&dev->port.lock, flags);
660 if (++dev->port.count > 1) {
661 spin_unlock_irqrestore(&dev->port.lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700662 return 0;
Jiri Slabyf997a012012-04-02 13:54:53 +0200663 }
664 spin_unlock_irqrestore(&dev->port.lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700665
666 dlc = dev->dlc;
667
668 /* Attach TTY and open DLC */
669
670 rfcomm_dlc_lock(dlc);
671 tty->driver_data = dev;
Jiri Slabyf60db8c2012-04-02 13:54:50 +0200672 dev->port.tty = tty;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700673 rfcomm_dlc_unlock(dlc);
674 set_bit(RFCOMM_TTY_ATTACHED, &dev->flags);
675
676 err = rfcomm_dlc_open(dlc, &dev->src, &dev->dst, dev->channel);
677 if (err < 0)
678 return err;
679
680 /* Wait for DLC to connect */
681 add_wait_queue(&dev->wait, &wait);
682 while (1) {
683 set_current_state(TASK_INTERRUPTIBLE);
684
685 if (dlc->state == BT_CLOSED) {
686 err = -dev->err;
687 break;
688 }
689
690 if (dlc->state == BT_CONNECTED)
691 break;
692
693 if (signal_pending(current)) {
694 err = -EINTR;
695 break;
696 }
697
Alan Cox89c8d912012-08-08 16:30:13 +0100698 tty_unlock(tty);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700699 schedule();
Alan Cox89c8d912012-08-08 16:30:13 +0100700 tty_lock(tty);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700701 }
702 set_current_state(TASK_RUNNING);
703 remove_wait_queue(&dev->wait, &wait);
704
Marcel Holtmannc1a33132007-02-17 23:58:57 +0100705 if (err == 0)
Cornelia Huckffa6a702009-03-04 12:44:00 +0100706 device_move(dev->tty_dev, rfcomm_get_device(dev),
707 DPM_ORDER_DEV_AFTER_PARENT);
Marcel Holtmannc1a33132007-02-17 23:58:57 +0100708
Marcel Holtmanna0c22f22008-07-14 20:13:52 +0200709 rfcomm_tty_copy_pending(dev);
710
711 rfcomm_dlc_unthrottle(dev->dlc);
712
Linus Torvalds1da177e2005-04-16 15:20:36 -0700713 return err;
714}
715
716static void rfcomm_tty_close(struct tty_struct *tty, struct file *filp)
717{
718 struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data;
Jiri Slabyf997a012012-04-02 13:54:53 +0200719 unsigned long flags;
720
Linus Torvalds1da177e2005-04-16 15:20:36 -0700721 if (!dev)
722 return;
723
Marcel Holtmann9a5df922008-11-30 12:17:29 +0100724 BT_DBG("tty %p dev %p dlc %p opened %d", tty, dev, dev->dlc,
Jiri Slabyf997a012012-04-02 13:54:53 +0200725 dev->port.count);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700726
Jiri Slabyf997a012012-04-02 13:54:53 +0200727 spin_lock_irqsave(&dev->port.lock, flags);
728 if (!--dev->port.count) {
729 spin_unlock_irqrestore(&dev->port.lock, flags);
Dave Youngacea6852008-01-21 22:35:21 -0800730 if (dev->tty_dev->parent)
Cornelia Huckffa6a702009-03-04 12:44:00 +0100731 device_move(dev->tty_dev, NULL, DPM_ORDER_DEV_LAST);
Marcel Holtmannc1a33132007-02-17 23:58:57 +0100732
Linus Torvalds1da177e2005-04-16 15:20:36 -0700733 /* Close DLC and dettach TTY */
734 rfcomm_dlc_close(dev->dlc, 0);
735
736 clear_bit(RFCOMM_TTY_ATTACHED, &dev->flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700737
738 rfcomm_dlc_lock(dev->dlc);
739 tty->driver_data = NULL;
Jiri Slabyf60db8c2012-04-02 13:54:50 +0200740 dev->port.tty = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700741 rfcomm_dlc_unlock(dev->dlc);
Marcel Holtmann9a5df922008-11-30 12:17:29 +0100742
Gianluca Anzolinebe937f2013-07-29 17:08:09 +0200743 if (test_bit(RFCOMM_TTY_RELEASED, &dev->flags))
Jiri Slaby67054012012-04-02 13:54:51 +0200744 tty_port_put(&dev->port);
Jiri Slabyf997a012012-04-02 13:54:53 +0200745 } else
746 spin_unlock_irqrestore(&dev->port.lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700747
Jiri Slaby67054012012-04-02 13:54:51 +0200748 tty_port_put(&dev->port);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700749}
750
751static int rfcomm_tty_write(struct tty_struct *tty, const unsigned char *buf, int count)
752{
753 struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data;
754 struct rfcomm_dlc *dlc = dev->dlc;
755 struct sk_buff *skb;
756 int err = 0, sent = 0, size;
757
758 BT_DBG("tty %p count %d", tty, count);
759
760 while (count) {
761 size = min_t(uint, count, dlc->mtu);
762
763 skb = rfcomm_wmalloc(dev, size + RFCOMM_SKB_RESERVE, GFP_ATOMIC);
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900764
Linus Torvalds1da177e2005-04-16 15:20:36 -0700765 if (!skb)
766 break;
767
768 skb_reserve(skb, RFCOMM_SKB_HEAD_RESERVE);
769
770 memcpy(skb_put(skb, size), buf + sent, size);
771
Andrei Emeltchenko285b4e92010-12-01 16:58:23 +0200772 err = rfcomm_dlc_send(dlc, skb);
773 if (err < 0) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700774 kfree_skb(skb);
775 break;
776 }
777
778 sent += size;
779 count -= size;
780 }
781
782 return sent ? sent : err;
783}
784
785static int rfcomm_tty_write_room(struct tty_struct *tty)
786{
787 struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data;
788 int room;
789
790 BT_DBG("tty %p", tty);
791
Marcel Holtmannb6e557f2007-01-08 02:16:27 +0100792 if (!dev || !dev->dlc)
793 return 0;
794
Linus Torvalds1da177e2005-04-16 15:20:36 -0700795 room = rfcomm_room(dev->dlc) - atomic_read(&dev->wmem_alloc);
796 if (room < 0)
797 room = 0;
Marcel Holtmannb6e557f2007-01-08 02:16:27 +0100798
Linus Torvalds1da177e2005-04-16 15:20:36 -0700799 return room;
800}
801
Alan Cox6caa76b2011-02-14 16:27:22 +0000802static int rfcomm_tty_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700803{
804 BT_DBG("tty %p cmd 0x%02x", tty, cmd);
805
806 switch (cmd) {
807 case TCGETS:
808 BT_DBG("TCGETS is not supported");
809 return -ENOIOCTLCMD;
810
811 case TCSETS:
812 BT_DBG("TCSETS is not supported");
813 return -ENOIOCTLCMD;
814
815 case TIOCMIWAIT:
816 BT_DBG("TIOCMIWAIT");
817 break;
818
Linus Torvalds1da177e2005-04-16 15:20:36 -0700819 case TIOCGSERIAL:
820 BT_ERR("TIOCGSERIAL is not supported");
821 return -ENOIOCTLCMD;
822
823 case TIOCSSERIAL:
824 BT_ERR("TIOCSSERIAL is not supported");
825 return -ENOIOCTLCMD;
826
827 case TIOCSERGSTRUCT:
828 BT_ERR("TIOCSERGSTRUCT is not supported");
829 return -ENOIOCTLCMD;
830
831 case TIOCSERGETLSR:
832 BT_ERR("TIOCSERGETLSR is not supported");
833 return -ENOIOCTLCMD;
834
835 case TIOCSERCONFIG:
836 BT_ERR("TIOCSERCONFIG is not supported");
837 return -ENOIOCTLCMD;
838
839 default:
840 return -ENOIOCTLCMD; /* ioctls which we must ignore */
841
842 }
843
844 return -ENOIOCTLCMD;
845}
846
Alan Cox606d0992006-12-08 02:38:45 -0800847static void rfcomm_tty_set_termios(struct tty_struct *tty, struct ktermios *old)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700848{
Alan Coxadc8d742012-07-14 15:31:47 +0100849 struct ktermios *new = &tty->termios;
J. Suter3a5e9032005-08-09 20:28:46 -0700850 int old_baud_rate = tty_termios_baud_rate(old);
851 int new_baud_rate = tty_termios_baud_rate(new);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700852
J. Suter3a5e9032005-08-09 20:28:46 -0700853 u8 baud, data_bits, stop_bits, parity, x_on, x_off;
854 u16 changes = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700855
J. Suter3a5e9032005-08-09 20:28:46 -0700856 struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data;
857
858 BT_DBG("tty %p termios %p", tty, old);
859
Marcel Holtmannff2d3672006-11-18 22:14:42 +0100860 if (!dev || !dev->dlc || !dev->dlc->session)
Marcel Holtmanncb19d9e2006-10-15 17:31:10 +0200861 return;
862
J. Suter3a5e9032005-08-09 20:28:46 -0700863 /* Handle turning off CRTSCTS */
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900864 if ((old->c_cflag & CRTSCTS) && !(new->c_cflag & CRTSCTS))
J. Suter3a5e9032005-08-09 20:28:46 -0700865 BT_DBG("Turning off CRTSCTS unsupported");
866
867 /* Parity on/off and when on, odd/even */
868 if (((old->c_cflag & PARENB) != (new->c_cflag & PARENB)) ||
Andrei Emeltchenko285b4e92010-12-01 16:58:23 +0200869 ((old->c_cflag & PARODD) != (new->c_cflag & PARODD))) {
J. Suter3a5e9032005-08-09 20:28:46 -0700870 changes |= RFCOMM_RPN_PM_PARITY;
871 BT_DBG("Parity change detected.");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700872 }
J. Suter3a5e9032005-08-09 20:28:46 -0700873
874 /* Mark and space parity are not supported! */
875 if (new->c_cflag & PARENB) {
876 if (new->c_cflag & PARODD) {
877 BT_DBG("Parity is ODD");
878 parity = RFCOMM_RPN_PARITY_ODD;
879 } else {
880 BT_DBG("Parity is EVEN");
881 parity = RFCOMM_RPN_PARITY_EVEN;
882 }
883 } else {
884 BT_DBG("Parity is OFF");
885 parity = RFCOMM_RPN_PARITY_NONE;
886 }
887
888 /* Setting the x_on / x_off characters */
889 if (old->c_cc[VSTOP] != new->c_cc[VSTOP]) {
890 BT_DBG("XOFF custom");
891 x_on = new->c_cc[VSTOP];
892 changes |= RFCOMM_RPN_PM_XON;
893 } else {
894 BT_DBG("XOFF default");
895 x_on = RFCOMM_RPN_XON_CHAR;
896 }
897
898 if (old->c_cc[VSTART] != new->c_cc[VSTART]) {
899 BT_DBG("XON custom");
900 x_off = new->c_cc[VSTART];
901 changes |= RFCOMM_RPN_PM_XOFF;
902 } else {
903 BT_DBG("XON default");
904 x_off = RFCOMM_RPN_XOFF_CHAR;
905 }
906
907 /* Handle setting of stop bits */
908 if ((old->c_cflag & CSTOPB) != (new->c_cflag & CSTOPB))
909 changes |= RFCOMM_RPN_PM_STOP;
910
911 /* POSIX does not support 1.5 stop bits and RFCOMM does not
912 * support 2 stop bits. So a request for 2 stop bits gets
913 * translated to 1.5 stop bits */
Andrei Emeltchenko285b4e92010-12-01 16:58:23 +0200914 if (new->c_cflag & CSTOPB)
J. Suter3a5e9032005-08-09 20:28:46 -0700915 stop_bits = RFCOMM_RPN_STOP_15;
Andrei Emeltchenko285b4e92010-12-01 16:58:23 +0200916 else
J. Suter3a5e9032005-08-09 20:28:46 -0700917 stop_bits = RFCOMM_RPN_STOP_1;
J. Suter3a5e9032005-08-09 20:28:46 -0700918
919 /* Handle number of data bits [5-8] */
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900920 if ((old->c_cflag & CSIZE) != (new->c_cflag & CSIZE))
J. Suter3a5e9032005-08-09 20:28:46 -0700921 changes |= RFCOMM_RPN_PM_DATA;
922
923 switch (new->c_cflag & CSIZE) {
924 case CS5:
925 data_bits = RFCOMM_RPN_DATA_5;
926 break;
927 case CS6:
928 data_bits = RFCOMM_RPN_DATA_6;
929 break;
930 case CS7:
931 data_bits = RFCOMM_RPN_DATA_7;
932 break;
933 case CS8:
934 data_bits = RFCOMM_RPN_DATA_8;
935 break;
936 default:
937 data_bits = RFCOMM_RPN_DATA_8;
938 break;
939 }
940
941 /* Handle baudrate settings */
942 if (old_baud_rate != new_baud_rate)
943 changes |= RFCOMM_RPN_PM_BITRATE;
944
945 switch (new_baud_rate) {
946 case 2400:
947 baud = RFCOMM_RPN_BR_2400;
948 break;
949 case 4800:
950 baud = RFCOMM_RPN_BR_4800;
951 break;
952 case 7200:
953 baud = RFCOMM_RPN_BR_7200;
954 break;
955 case 9600:
956 baud = RFCOMM_RPN_BR_9600;
957 break;
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900958 case 19200:
J. Suter3a5e9032005-08-09 20:28:46 -0700959 baud = RFCOMM_RPN_BR_19200;
960 break;
961 case 38400:
962 baud = RFCOMM_RPN_BR_38400;
963 break;
964 case 57600:
965 baud = RFCOMM_RPN_BR_57600;
966 break;
967 case 115200:
968 baud = RFCOMM_RPN_BR_115200;
969 break;
970 case 230400:
971 baud = RFCOMM_RPN_BR_230400;
972 break;
973 default:
974 /* 9600 is standard accordinag to the RFCOMM specification */
975 baud = RFCOMM_RPN_BR_9600;
976 break;
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900977
J. Suter3a5e9032005-08-09 20:28:46 -0700978 }
979
980 if (changes)
981 rfcomm_send_rpn(dev->dlc->session, 1, dev->dlc->dlci, baud,
982 data_bits, stop_bits, parity,
983 RFCOMM_RPN_FLOW_NONE, x_on, x_off, changes);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700984}
985
986static void rfcomm_tty_throttle(struct tty_struct *tty)
987{
988 struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data;
989
990 BT_DBG("tty %p dev %p", tty, dev);
J. Suter3a5e9032005-08-09 20:28:46 -0700991
Linus Torvalds1da177e2005-04-16 15:20:36 -0700992 rfcomm_dlc_throttle(dev->dlc);
993}
994
995static void rfcomm_tty_unthrottle(struct tty_struct *tty)
996{
997 struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data;
998
999 BT_DBG("tty %p dev %p", tty, dev);
J. Suter3a5e9032005-08-09 20:28:46 -07001000
Linus Torvalds1da177e2005-04-16 15:20:36 -07001001 rfcomm_dlc_unthrottle(dev->dlc);
1002}
1003
1004static int rfcomm_tty_chars_in_buffer(struct tty_struct *tty)
1005{
1006 struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001007
1008 BT_DBG("tty %p dev %p", tty, dev);
1009
Marcel Holtmannb6e557f2007-01-08 02:16:27 +01001010 if (!dev || !dev->dlc)
1011 return 0;
1012
1013 if (!skb_queue_empty(&dev->dlc->tx_queue))
1014 return dev->dlc->mtu;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001015
1016 return 0;
1017}
1018
1019static void rfcomm_tty_flush_buffer(struct tty_struct *tty)
1020{
1021 struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001022
1023 BT_DBG("tty %p dev %p", tty, dev);
1024
Marcel Holtmannb6e557f2007-01-08 02:16:27 +01001025 if (!dev || !dev->dlc)
1026 return;
1027
Linus Torvalds1da177e2005-04-16 15:20:36 -07001028 skb_queue_purge(&dev->dlc->tx_queue);
Alan Coxa352def2008-07-16 21:53:12 +01001029 tty_wakeup(tty);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001030}
1031
1032static void rfcomm_tty_send_xchar(struct tty_struct *tty, char ch)
1033{
1034 BT_DBG("tty %p ch %c", tty, ch);
1035}
1036
1037static void rfcomm_tty_wait_until_sent(struct tty_struct *tty, int timeout)
1038{
1039 BT_DBG("tty %p timeout %d", tty, timeout);
1040}
1041
1042static void rfcomm_tty_hangup(struct tty_struct *tty)
1043{
1044 struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001045
1046 BT_DBG("tty %p dev %p", tty, dev);
1047
Marcel Holtmannb6e557f2007-01-08 02:16:27 +01001048 if (!dev)
1049 return;
1050
Linus Torvalds1da177e2005-04-16 15:20:36 -07001051 rfcomm_tty_flush_buffer(tty);
1052
Marcel Holtmann77f2a452007-05-05 00:36:10 +02001053 if (test_bit(RFCOMM_RELEASE_ONHUP, &dev->flags)) {
1054 if (rfcomm_dev_get(dev->id) == NULL)
1055 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001056 rfcomm_dev_del(dev);
Jiri Slaby67054012012-04-02 13:54:51 +02001057 tty_port_put(&dev->port);
Marcel Holtmann77f2a452007-05-05 00:36:10 +02001058 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001059}
1060
Alan Cox60b33c12011-02-14 16:26:14 +00001061static int rfcomm_tty_tiocmget(struct tty_struct *tty)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001062{
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09001063 struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001064
1065 BT_DBG("tty %p dev %p", tty, dev);
1066
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09001067 return dev->modem_status;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001068}
1069
Alan Cox20b9d172011-02-14 16:26:50 +00001070static int rfcomm_tty_tiocmset(struct tty_struct *tty, unsigned int set, unsigned int clear)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001071{
J. Suter3a5e9032005-08-09 20:28:46 -07001072 struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data;
1073 struct rfcomm_dlc *dlc = dev->dlc;
1074 u8 v24_sig;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001075
1076 BT_DBG("tty %p dev %p set 0x%02x clear 0x%02x", tty, dev, set, clear);
1077
J. Suter3a5e9032005-08-09 20:28:46 -07001078 rfcomm_dlc_get_modem_status(dlc, &v24_sig);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001079
J. Suter3a5e9032005-08-09 20:28:46 -07001080 if (set & TIOCM_DSR || set & TIOCM_DTR)
1081 v24_sig |= RFCOMM_V24_RTC;
1082 if (set & TIOCM_RTS || set & TIOCM_CTS)
1083 v24_sig |= RFCOMM_V24_RTR;
1084 if (set & TIOCM_RI)
1085 v24_sig |= RFCOMM_V24_IC;
1086 if (set & TIOCM_CD)
1087 v24_sig |= RFCOMM_V24_DV;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001088
J. Suter3a5e9032005-08-09 20:28:46 -07001089 if (clear & TIOCM_DSR || clear & TIOCM_DTR)
1090 v24_sig &= ~RFCOMM_V24_RTC;
1091 if (clear & TIOCM_RTS || clear & TIOCM_CTS)
1092 v24_sig &= ~RFCOMM_V24_RTR;
1093 if (clear & TIOCM_RI)
1094 v24_sig &= ~RFCOMM_V24_IC;
1095 if (clear & TIOCM_CD)
1096 v24_sig &= ~RFCOMM_V24_DV;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001097
J. Suter3a5e9032005-08-09 20:28:46 -07001098 rfcomm_dlc_set_modem_status(dlc, v24_sig);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001099
J. Suter3a5e9032005-08-09 20:28:46 -07001100 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001101}
1102
1103/* ---- TTY structure ---- */
1104
Jeff Dikeb68e31d2006-10-02 02:17:18 -07001105static const struct tty_operations rfcomm_ops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001106 .open = rfcomm_tty_open,
1107 .close = rfcomm_tty_close,
1108 .write = rfcomm_tty_write,
1109 .write_room = rfcomm_tty_write_room,
1110 .chars_in_buffer = rfcomm_tty_chars_in_buffer,
1111 .flush_buffer = rfcomm_tty_flush_buffer,
1112 .ioctl = rfcomm_tty_ioctl,
1113 .throttle = rfcomm_tty_throttle,
1114 .unthrottle = rfcomm_tty_unthrottle,
1115 .set_termios = rfcomm_tty_set_termios,
1116 .send_xchar = rfcomm_tty_send_xchar,
1117 .hangup = rfcomm_tty_hangup,
1118 .wait_until_sent = rfcomm_tty_wait_until_sent,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001119 .tiocmget = rfcomm_tty_tiocmget,
1120 .tiocmset = rfcomm_tty_tiocmset,
1121};
1122
Gustavo F. Padovan2f8362a2010-07-24 02:04:45 -03001123int __init rfcomm_init_ttys(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001124{
David Herrmann5ada9912011-10-24 15:30:57 +02001125 int error;
1126
Linus Torvalds1da177e2005-04-16 15:20:36 -07001127 rfcomm_tty_driver = alloc_tty_driver(RFCOMM_TTY_PORTS);
1128 if (!rfcomm_tty_driver)
David Herrmann5ada9912011-10-24 15:30:57 +02001129 return -ENOMEM;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001130
Linus Torvalds1da177e2005-04-16 15:20:36 -07001131 rfcomm_tty_driver->driver_name = "rfcomm";
Linus Torvalds1da177e2005-04-16 15:20:36 -07001132 rfcomm_tty_driver->name = "rfcomm";
1133 rfcomm_tty_driver->major = RFCOMM_TTY_MAJOR;
1134 rfcomm_tty_driver->minor_start = RFCOMM_TTY_MINOR;
1135 rfcomm_tty_driver->type = TTY_DRIVER_TYPE_SERIAL;
1136 rfcomm_tty_driver->subtype = SERIAL_TYPE_NORMAL;
Greg Kroah-Hartman331b8312005-06-20 21:15:16 -07001137 rfcomm_tty_driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001138 rfcomm_tty_driver->init_termios = tty_std_termios;
1139 rfcomm_tty_driver->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL;
Marcel Holtmannca37bdd52008-07-14 20:13:52 +02001140 rfcomm_tty_driver->init_termios.c_lflag &= ~ICANON;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001141 tty_set_operations(rfcomm_tty_driver, &rfcomm_ops);
1142
David Herrmann5ada9912011-10-24 15:30:57 +02001143 error = tty_register_driver(rfcomm_tty_driver);
1144 if (error) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001145 BT_ERR("Can't register RFCOMM TTY driver");
1146 put_tty_driver(rfcomm_tty_driver);
David Herrmann5ada9912011-10-24 15:30:57 +02001147 return error;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001148 }
1149
1150 BT_INFO("RFCOMM TTY layer initialized");
1151
1152 return 0;
1153}
1154
Gustavo F. Padovan28e95092010-07-31 19:57:05 -03001155void rfcomm_cleanup_ttys(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001156{
1157 tty_unregister_driver(rfcomm_tty_driver);
1158 put_tty_driver(rfcomm_tty_driver);
1159}