blob: aa5d73b786aca23793f7691bbab7f86ceb2e96d1 [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
Randy Dunlap4fc268d2006-01-11 12:17:47 -080034#include <linux/capability.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070035#include <linux/slab.h>
36#include <linux/skbuff.h>
David Herrmann96af7392011-10-24 15:30:58 +020037#include <linux/workqueue.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070038
39#include <net/bluetooth/bluetooth.h>
Marcel Holtmann0a85b962006-07-06 13:09:02 +020040#include <net/bluetooth/hci_core.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070041#include <net/bluetooth/rfcomm.h>
42
Linus Torvalds1da177e2005-04-16 15:20:36 -070043#define RFCOMM_TTY_MAGIC 0x6d02 /* magic number for rfcomm struct */
44#define RFCOMM_TTY_PORTS RFCOMM_MAX_DEV /* whole lotta rfcomm devices */
45#define RFCOMM_TTY_MAJOR 216 /* device node major id of the usb/bluetooth.c driver */
46#define RFCOMM_TTY_MINOR 0
47
48static struct tty_driver *rfcomm_tty_driver;
49
50struct rfcomm_dev {
Jiri Slabyf60db8c2012-04-02 13:54:50 +020051 struct tty_port port;
Linus Torvalds1da177e2005-04-16 15:20:36 -070052 struct list_head list;
Linus Torvalds1da177e2005-04-16 15:20:36 -070053
54 char name[12];
55 int id;
56 unsigned long flags;
Linus Torvalds1da177e2005-04-16 15:20:36 -070057 int err;
58
59 bdaddr_t src;
60 bdaddr_t dst;
Andrei Emeltchenko285b4e92010-12-01 16:58:23 +020061 u8 channel;
Linus Torvalds1da177e2005-04-16 15:20:36 -070062
Andrei Emeltchenko285b4e92010-12-01 16:58:23 +020063 uint modem_status;
Linus Torvalds1da177e2005-04-16 15:20:36 -070064
65 struct rfcomm_dlc *dlc;
Linus Torvalds1da177e2005-04-16 15:20:36 -070066 wait_queue_head_t wait;
Linus Torvalds1da177e2005-04-16 15:20:36 -070067
Marcel Holtmannc1a33132007-02-17 23:58:57 +010068 struct device *tty_dev;
69
Andrei Emeltchenko285b4e92010-12-01 16:58:23 +020070 atomic_t wmem_alloc;
Marcel Holtmanna0c22f22008-07-14 20:13:52 +020071
72 struct sk_buff_head pending;
Linus Torvalds1da177e2005-04-16 15:20:36 -070073};
74
75static LIST_HEAD(rfcomm_dev_list);
Gustavo F. Padovan393432c2011-12-27 15:28:45 -020076static DEFINE_SPINLOCK(rfcomm_dev_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -070077
78static void rfcomm_dev_data_ready(struct rfcomm_dlc *dlc, struct sk_buff *skb);
79static void rfcomm_dev_state_change(struct rfcomm_dlc *dlc, int err);
80static void rfcomm_dev_modem_status(struct rfcomm_dlc *dlc, u8 v24_sig);
81
Linus Torvalds1da177e2005-04-16 15:20:36 -070082/* ---- Device functions ---- */
Jiri Slaby67054012012-04-02 13:54:51 +020083
84/*
85 * The reason this isn't actually a race, as you no doubt have a little voice
86 * screaming at you in your head, is that the refcount should never actually
87 * reach zero unless the device has already been taken off the list, in
88 * rfcomm_dev_del(). And if that's not true, we'll hit the BUG() in
89 * rfcomm_dev_destruct() anyway.
90 */
91static void rfcomm_dev_destruct(struct tty_port *port)
Linus Torvalds1da177e2005-04-16 15:20:36 -070092{
Jiri Slaby67054012012-04-02 13:54:51 +020093 struct rfcomm_dev *dev = container_of(port, struct rfcomm_dev, port);
Linus Torvalds1da177e2005-04-16 15:20:36 -070094 struct rfcomm_dlc *dlc = dev->dlc;
95
96 BT_DBG("dev %p dlc %p", dev, dlc);
97
Dave Youngf9513752008-01-10 22:22:52 -080098 /* Refcount should only hit zero when called from rfcomm_dev_del()
99 which will have taken us off the list. Everything else are
100 refcounting bugs. */
101 BUG_ON(!list_empty(&dev->list));
Ville Tervo8de0a152007-07-11 09:23:41 +0200102
Linus Torvalds1da177e2005-04-16 15:20:36 -0700103 rfcomm_dlc_lock(dlc);
104 /* Detach DLC if it's owned by this dev */
105 if (dlc->owner == dev)
106 dlc->owner = NULL;
107 rfcomm_dlc_unlock(dlc);
108
109 rfcomm_dlc_put(dlc);
110
111 tty_unregister_device(rfcomm_tty_driver, dev->id);
112
Linus Torvalds1da177e2005-04-16 15:20:36 -0700113 kfree(dev);
114
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900115 /* It's safe to call module_put() here because socket still
Linus Torvalds1da177e2005-04-16 15:20:36 -0700116 holds reference to this module. */
117 module_put(THIS_MODULE);
118}
119
Jiri Slaby67054012012-04-02 13:54:51 +0200120static const struct tty_port_operations rfcomm_port_ops = {
121 .destruct = rfcomm_dev_destruct,
122};
Linus Torvalds1da177e2005-04-16 15:20:36 -0700123
124static struct rfcomm_dev *__rfcomm_dev_get(int id)
125{
126 struct rfcomm_dev *dev;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700127
Luiz Augusto von Dentz8035ded2011-11-01 10:58:56 +0200128 list_for_each_entry(dev, &rfcomm_dev_list, list)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700129 if (dev->id == id)
130 return dev;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700131
132 return NULL;
133}
134
135static inline struct rfcomm_dev *rfcomm_dev_get(int id)
136{
137 struct rfcomm_dev *dev;
138
Gustavo F. Padovan393432c2011-12-27 15:28:45 -0200139 spin_lock(&rfcomm_dev_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700140
141 dev = __rfcomm_dev_get(id);
Ville Tervo8de0a152007-07-11 09:23:41 +0200142
143 if (dev) {
144 if (test_bit(RFCOMM_TTY_RELEASED, &dev->flags))
145 dev = NULL;
146 else
Jiri Slaby67054012012-04-02 13:54:51 +0200147 tty_port_get(&dev->port);
Ville Tervo8de0a152007-07-11 09:23:41 +0200148 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700149
Gustavo F. Padovan393432c2011-12-27 15:28:45 -0200150 spin_unlock(&rfcomm_dev_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700151
152 return dev;
153}
154
Marcel Holtmann0a85b962006-07-06 13:09:02 +0200155static struct device *rfcomm_get_device(struct rfcomm_dev *dev)
156{
157 struct hci_dev *hdev;
158 struct hci_conn *conn;
159
160 hdev = hci_get_route(&dev->dst, &dev->src);
161 if (!hdev)
162 return NULL;
163
164 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &dev->dst);
Marcel Holtmann0a85b962006-07-06 13:09:02 +0200165
166 hci_dev_put(hdev);
167
Marcel Holtmannb2cfcd72006-10-15 17:31:05 +0200168 return conn ? &conn->dev : NULL;
Marcel Holtmann0a85b962006-07-06 13:09:02 +0200169}
170
Marcel Holtmanndae6a0f2007-10-20 14:52:38 +0200171static ssize_t show_address(struct device *tty_dev, struct device_attribute *attr, char *buf)
172{
173 struct rfcomm_dev *dev = dev_get_drvdata(tty_dev);
Gustavo F. Padovand6b2eb22010-09-03 18:29:46 -0300174 return sprintf(buf, "%s\n", batostr(&dev->dst));
Marcel Holtmanndae6a0f2007-10-20 14:52:38 +0200175}
176
177static ssize_t show_channel(struct device *tty_dev, struct device_attribute *attr, char *buf)
178{
179 struct rfcomm_dev *dev = dev_get_drvdata(tty_dev);
180 return sprintf(buf, "%d\n", dev->channel);
181}
182
183static DEVICE_ATTR(address, S_IRUGO, show_address, NULL);
184static DEVICE_ATTR(channel, S_IRUGO, show_channel, NULL);
185
Linus Torvalds1da177e2005-04-16 15:20:36 -0700186static int rfcomm_dev_add(struct rfcomm_dev_req *req, struct rfcomm_dlc *dlc)
187{
Luiz Augusto von Dentz8035ded2011-11-01 10:58:56 +0200188 struct rfcomm_dev *dev, *entry;
Luiz Augusto von Dentze57d7582012-03-07 20:20:14 +0200189 struct list_head *head = &rfcomm_dev_list;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700190 int err = 0;
191
192 BT_DBG("id %d channel %d", req->dev_id, req->channel);
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900193
Marcel Holtmann25ea6db2006-07-06 15:40:09 +0200194 dev = kzalloc(sizeof(struct rfcomm_dev), GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700195 if (!dev)
196 return -ENOMEM;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700197
Gustavo F. Padovan393432c2011-12-27 15:28:45 -0200198 spin_lock(&rfcomm_dev_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700199
200 if (req->dev_id < 0) {
201 dev->id = 0;
202
Luiz Augusto von Dentz8035ded2011-11-01 10:58:56 +0200203 list_for_each_entry(entry, &rfcomm_dev_list, list) {
204 if (entry->id != dev->id)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700205 break;
206
207 dev->id++;
Luiz Augusto von Dentze57d7582012-03-07 20:20:14 +0200208 head = &entry->list;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700209 }
210 } else {
211 dev->id = req->dev_id;
212
Luiz Augusto von Dentz8035ded2011-11-01 10:58:56 +0200213 list_for_each_entry(entry, &rfcomm_dev_list, list) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700214 if (entry->id == dev->id) {
215 err = -EADDRINUSE;
216 goto out;
217 }
218
219 if (entry->id > dev->id - 1)
220 break;
221
Luiz Augusto von Dentze57d7582012-03-07 20:20:14 +0200222 head = &entry->list;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700223 }
224 }
225
226 if ((dev->id < 0) || (dev->id > RFCOMM_MAX_DEV - 1)) {
227 err = -ENFILE;
228 goto out;
229 }
230
231 sprintf(dev->name, "rfcomm%d", dev->id);
232
233 list_add(&dev->list, head);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700234
235 bacpy(&dev->src, &req->src);
236 bacpy(&dev->dst, &req->dst);
237 dev->channel = req->channel;
238
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900239 dev->flags = req->flags &
Linus Torvalds1da177e2005-04-16 15:20:36 -0700240 ((1 << RFCOMM_RELEASE_ONHUP) | (1 << RFCOMM_REUSE_DLC));
241
Jiri Slabyf60db8c2012-04-02 13:54:50 +0200242 tty_port_init(&dev->port);
Jiri Slaby67054012012-04-02 13:54:51 +0200243 dev->port.ops = &rfcomm_port_ops;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700244 init_waitqueue_head(&dev->wait);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700245
Marcel Holtmanna0c22f22008-07-14 20:13:52 +0200246 skb_queue_head_init(&dev->pending);
247
Linus Torvalds1da177e2005-04-16 15:20:36 -0700248 rfcomm_dlc_lock(dlc);
Marcel Holtmanna0c22f22008-07-14 20:13:52 +0200249
250 if (req->flags & (1 << RFCOMM_REUSE_DLC)) {
251 struct sock *sk = dlc->owner;
252 struct sk_buff *skb;
253
254 BUG_ON(!sk);
255
256 rfcomm_dlc_throttle(dlc);
257
258 while ((skb = skb_dequeue(&sk->sk_receive_queue))) {
259 skb_orphan(skb);
260 skb_queue_tail(&dev->pending, skb);
261 atomic_sub(skb->len, &sk->sk_rmem_alloc);
262 }
263 }
264
Linus Torvalds1da177e2005-04-16 15:20:36 -0700265 dlc->data_ready = rfcomm_dev_data_ready;
266 dlc->state_change = rfcomm_dev_state_change;
267 dlc->modem_status = rfcomm_dev_modem_status;
268
269 dlc->owner = dev;
270 dev->dlc = dlc;
Marcel Holtmann8b6b3da2008-07-14 20:13:52 +0200271
272 rfcomm_dev_modem_status(dlc, dlc->remote_v24_sig);
273
Linus Torvalds1da177e2005-04-16 15:20:36 -0700274 rfcomm_dlc_unlock(dlc);
275
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900276 /* It's safe to call __module_get() here because socket already
Linus Torvalds1da177e2005-04-16 15:20:36 -0700277 holds reference to this module. */
278 __module_get(THIS_MODULE);
279
280out:
Gustavo F. Padovan393432c2011-12-27 15:28:45 -0200281 spin_unlock(&rfcomm_dev_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700282
Ilpo Järvinen037322a2008-12-14 23:18:00 -0800283 if (err < 0)
284 goto free;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700285
Marcel Holtmannc1a33132007-02-17 23:58:57 +0100286 dev->tty_dev = tty_register_device(rfcomm_tty_driver, dev->id, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700287
Ville Tervo8de0a152007-07-11 09:23:41 +0200288 if (IS_ERR(dev->tty_dev)) {
Marcel Holtmann09c7d822007-07-26 00:12:25 -0700289 err = PTR_ERR(dev->tty_dev);
Ville Tervo8de0a152007-07-11 09:23:41 +0200290 list_del(&dev->list);
Ilpo Järvinen037322a2008-12-14 23:18:00 -0800291 goto free;
Ville Tervo8de0a152007-07-11 09:23:41 +0200292 }
293
Marcel Holtmanndae6a0f2007-10-20 14:52:38 +0200294 dev_set_drvdata(dev->tty_dev, dev);
295
296 if (device_create_file(dev->tty_dev, &dev_attr_address) < 0)
297 BT_ERR("Failed to create address attribute");
298
299 if (device_create_file(dev->tty_dev, &dev_attr_channel) < 0)
300 BT_ERR("Failed to create channel attribute");
301
Linus Torvalds1da177e2005-04-16 15:20:36 -0700302 return dev->id;
Ilpo Järvinen037322a2008-12-14 23:18:00 -0800303
304free:
305 kfree(dev);
306 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700307}
308
309static void rfcomm_dev_del(struct rfcomm_dev *dev)
310{
Jiri Slabyf997a012012-04-02 13:54:53 +0200311 unsigned long flags;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700312 BT_DBG("dev %p", dev);
313
Marcel Holtmann9a5df922008-11-30 12:17:29 +0100314 BUG_ON(test_and_set_bit(RFCOMM_TTY_RELEASED, &dev->flags));
315
Jiri Slabyf997a012012-04-02 13:54:53 +0200316 spin_lock_irqsave(&dev->port.lock, flags);
317 if (dev->port.count > 0) {
318 spin_unlock_irqrestore(&dev->port.lock, flags);
Marcel Holtmann9a5df922008-11-30 12:17:29 +0100319 return;
Jiri Slabyf997a012012-04-02 13:54:53 +0200320 }
321 spin_unlock_irqrestore(&dev->port.lock, flags);
Dave Youngf9513752008-01-10 22:22:52 -0800322
Gustavo F. Padovan393432c2011-12-27 15:28:45 -0200323 spin_lock(&rfcomm_dev_lock);
Dave Youngf9513752008-01-10 22:22:52 -0800324 list_del_init(&dev->list);
Gustavo F. Padovan393432c2011-12-27 15:28:45 -0200325 spin_unlock(&rfcomm_dev_lock);
Dave Youngf9513752008-01-10 22:22:52 -0800326
Jiri Slaby67054012012-04-02 13:54:51 +0200327 tty_port_put(&dev->port);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700328}
329
330/* ---- Send buffer ---- */
331static inline unsigned int rfcomm_room(struct rfcomm_dlc *dlc)
332{
333 /* We can't let it be zero, because we don't get a callback
334 when tx_credits becomes nonzero, hence we'd never wake up */
335 return dlc->mtu * (dlc->tx_credits?:1);
336}
337
338static void rfcomm_wfree(struct sk_buff *skb)
339{
340 struct rfcomm_dev *dev = (void *) skb->sk;
Jiri Slabyb2c4be32012-04-02 13:54:52 +0200341 struct tty_struct *tty = dev->port.tty;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700342 atomic_sub(skb->truesize, &dev->wmem_alloc);
Jiri Slabyb2c4be32012-04-02 13:54:52 +0200343 if (test_bit(RFCOMM_TTY_ATTACHED, &dev->flags) && tty)
344 tty_wakeup(tty);
Jiri Slaby67054012012-04-02 13:54:51 +0200345 tty_port_put(&dev->port);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700346}
347
348static inline void rfcomm_set_owner_w(struct sk_buff *skb, struct rfcomm_dev *dev)
349{
Jiri Slaby67054012012-04-02 13:54:51 +0200350 tty_port_get(&dev->port);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700351 atomic_add(skb->truesize, &dev->wmem_alloc);
352 skb->sk = (void *) dev;
353 skb->destructor = rfcomm_wfree;
354}
355
Al Virodd0fc662005-10-07 07:46:04 +0100356static struct sk_buff *rfcomm_wmalloc(struct rfcomm_dev *dev, unsigned long size, gfp_t priority)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700357{
358 if (atomic_read(&dev->wmem_alloc) < rfcomm_room(dev->dlc)) {
359 struct sk_buff *skb = alloc_skb(size, priority);
360 if (skb) {
361 rfcomm_set_owner_w(skb, dev);
362 return skb;
363 }
364 }
365 return NULL;
366}
367
368/* ---- Device IOCTLs ---- */
369
370#define NOCAP_FLAGS ((1 << RFCOMM_REUSE_DLC) | (1 << RFCOMM_RELEASE_ONHUP))
371
372static int rfcomm_create_dev(struct sock *sk, void __user *arg)
373{
374 struct rfcomm_dev_req req;
375 struct rfcomm_dlc *dlc;
376 int id;
377
378 if (copy_from_user(&req, arg, sizeof(req)))
379 return -EFAULT;
380
Ville Tervo8de0a152007-07-11 09:23:41 +0200381 BT_DBG("sk %p dev_id %d flags 0x%x", sk, req.dev_id, req.flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700382
383 if (req.flags != NOCAP_FLAGS && !capable(CAP_NET_ADMIN))
384 return -EPERM;
385
386 if (req.flags & (1 << RFCOMM_REUSE_DLC)) {
387 /* Socket must be connected */
388 if (sk->sk_state != BT_CONNECTED)
389 return -EBADFD;
390
391 dlc = rfcomm_pi(sk)->dlc;
392 rfcomm_dlc_hold(dlc);
393 } else {
394 dlc = rfcomm_dlc_alloc(GFP_KERNEL);
395 if (!dlc)
396 return -ENOMEM;
397 }
398
399 id = rfcomm_dev_add(&req, dlc);
400 if (id < 0) {
401 rfcomm_dlc_put(dlc);
402 return id;
403 }
404
405 if (req.flags & (1 << RFCOMM_REUSE_DLC)) {
406 /* DLC is now used by device.
407 * Socket must be disconnected */
408 sk->sk_state = BT_CLOSED;
409 }
410
411 return id;
412}
413
414static int rfcomm_release_dev(void __user *arg)
415{
416 struct rfcomm_dev_req req;
417 struct rfcomm_dev *dev;
418
419 if (copy_from_user(&req, arg, sizeof(req)))
420 return -EFAULT;
421
Ville Tervo8de0a152007-07-11 09:23:41 +0200422 BT_DBG("dev_id %d flags 0x%x", req.dev_id, req.flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700423
Andrei Emeltchenko285b4e92010-12-01 16:58:23 +0200424 dev = rfcomm_dev_get(req.dev_id);
425 if (!dev)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700426 return -ENODEV;
427
428 if (dev->flags != NOCAP_FLAGS && !capable(CAP_NET_ADMIN)) {
Jiri Slaby67054012012-04-02 13:54:51 +0200429 tty_port_put(&dev->port);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700430 return -EPERM;
431 }
432
433 if (req.flags & (1 << RFCOMM_HANGUP_NOW))
434 rfcomm_dlc_close(dev->dlc, 0);
435
Mikko Rapeli84950cf2007-07-11 09:18:15 +0200436 /* Shut down TTY synchronously before freeing rfcomm_dev */
Jiri Slabyf60db8c2012-04-02 13:54:50 +0200437 if (dev->port.tty)
438 tty_vhangup(dev->port.tty);
Mikko Rapeli84950cf2007-07-11 09:18:15 +0200439
Dave Young93d80742008-02-05 03:12:06 -0800440 if (!test_bit(RFCOMM_RELEASE_ONHUP, &dev->flags))
441 rfcomm_dev_del(dev);
Jiri Slaby67054012012-04-02 13:54:51 +0200442 tty_port_put(&dev->port);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700443 return 0;
444}
445
446static int rfcomm_get_dev_list(void __user *arg)
447{
Luiz Augusto von Dentz8035ded2011-11-01 10:58:56 +0200448 struct rfcomm_dev *dev;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700449 struct rfcomm_dev_list_req *dl;
450 struct rfcomm_dev_info *di;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700451 int n = 0, size, err;
452 u16 dev_num;
453
454 BT_DBG("");
455
456 if (get_user(dev_num, (u16 __user *) arg))
457 return -EFAULT;
458
459 if (!dev_num || dev_num > (PAGE_SIZE * 4) / sizeof(*di))
460 return -EINVAL;
461
462 size = sizeof(*dl) + dev_num * sizeof(*di);
463
Andrei Emeltchenko285b4e92010-12-01 16:58:23 +0200464 dl = kmalloc(size, GFP_KERNEL);
465 if (!dl)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700466 return -ENOMEM;
467
468 di = dl->dev_info;
469
Gustavo F. Padovan393432c2011-12-27 15:28:45 -0200470 spin_lock(&rfcomm_dev_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700471
Luiz Augusto von Dentz8035ded2011-11-01 10:58:56 +0200472 list_for_each_entry(dev, &rfcomm_dev_list, list) {
Ville Tervo8de0a152007-07-11 09:23:41 +0200473 if (test_bit(RFCOMM_TTY_RELEASED, &dev->flags))
474 continue;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700475 (di + n)->id = dev->id;
476 (di + n)->flags = dev->flags;
477 (di + n)->state = dev->dlc->state;
478 (di + n)->channel = dev->channel;
479 bacpy(&(di + n)->src, &dev->src);
480 bacpy(&(di + n)->dst, &dev->dst);
481 if (++n >= dev_num)
482 break;
483 }
484
Gustavo F. Padovan393432c2011-12-27 15:28:45 -0200485 spin_unlock(&rfcomm_dev_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700486
487 dl->dev_num = n;
488 size = sizeof(*dl) + n * sizeof(*di);
489
490 err = copy_to_user(arg, dl, size);
491 kfree(dl);
492
493 return err ? -EFAULT : 0;
494}
495
496static int rfcomm_get_dev_info(void __user *arg)
497{
498 struct rfcomm_dev *dev;
499 struct rfcomm_dev_info di;
500 int err = 0;
501
502 BT_DBG("");
503
504 if (copy_from_user(&di, arg, sizeof(di)))
505 return -EFAULT;
506
Andrei Emeltchenko285b4e92010-12-01 16:58:23 +0200507 dev = rfcomm_dev_get(di.id);
508 if (!dev)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700509 return -ENODEV;
510
511 di.flags = dev->flags;
512 di.channel = dev->channel;
513 di.state = dev->dlc->state;
514 bacpy(&di.src, &dev->src);
515 bacpy(&di.dst, &dev->dst);
516
517 if (copy_to_user(arg, &di, sizeof(di)))
518 err = -EFAULT;
519
Jiri Slaby67054012012-04-02 13:54:51 +0200520 tty_port_put(&dev->port);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700521 return err;
522}
523
524int rfcomm_dev_ioctl(struct sock *sk, unsigned int cmd, void __user *arg)
525{
526 BT_DBG("cmd %d arg %p", cmd, arg);
527
528 switch (cmd) {
529 case RFCOMMCREATEDEV:
530 return rfcomm_create_dev(sk, arg);
531
532 case RFCOMMRELEASEDEV:
533 return rfcomm_release_dev(arg);
534
535 case RFCOMMGETDEVLIST:
536 return rfcomm_get_dev_list(arg);
537
538 case RFCOMMGETDEVINFO:
539 return rfcomm_get_dev_info(arg);
540 }
541
542 return -EINVAL;
543}
544
545/* ---- DLC callbacks ---- */
546static void rfcomm_dev_data_ready(struct rfcomm_dlc *dlc, struct sk_buff *skb)
547{
548 struct rfcomm_dev *dev = dlc->owner;
549 struct tty_struct *tty;
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900550
Marcel Holtmanna0c22f22008-07-14 20:13:52 +0200551 if (!dev) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700552 kfree_skb(skb);
553 return;
554 }
555
Jiri Slabyf60db8c2012-04-02 13:54:50 +0200556 tty = dev->port.tty;
Andrei Emeltchenko285b4e92010-12-01 16:58:23 +0200557 if (!tty || !skb_queue_empty(&dev->pending)) {
Marcel Holtmanna0c22f22008-07-14 20:13:52 +0200558 skb_queue_tail(&dev->pending, skb);
559 return;
560 }
561
Linus Torvalds1da177e2005-04-16 15:20:36 -0700562 BT_DBG("dlc %p tty %p len %d", dlc, tty, skb->len);
563
Paul Fulghum817d6d32006-06-28 04:26:47 -0700564 tty_insert_flip_string(tty, skb->data, skb->len);
565 tty_flip_buffer_push(tty);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700566
567 kfree_skb(skb);
568}
569
570static void rfcomm_dev_state_change(struct rfcomm_dlc *dlc, int err)
571{
572 struct rfcomm_dev *dev = dlc->owner;
573 if (!dev)
574 return;
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900575
Linus Torvalds1da177e2005-04-16 15:20:36 -0700576 BT_DBG("dlc %p dev %p err %d", dlc, dev, err);
577
578 dev->err = err;
579 wake_up_interruptible(&dev->wait);
580
581 if (dlc->state == BT_CLOSED) {
Jiri Slabyf60db8c2012-04-02 13:54:50 +0200582 if (!dev->port.tty) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700583 if (test_bit(RFCOMM_RELEASE_ONHUP, &dev->flags)) {
Dave Young537d59a2008-06-01 23:50:52 -0700584 /* Drop DLC lock here to avoid deadlock
585 * 1. rfcomm_dev_get will take rfcomm_dev_lock
586 * but in rfcomm_dev_add there's lock order:
587 * rfcomm_dev_lock -> dlc lock
Jiri Slaby67054012012-04-02 13:54:51 +0200588 * 2. tty_port_put will deadlock if it's
Dave Young537d59a2008-06-01 23:50:52 -0700589 * the last reference
590 */
591 rfcomm_dlc_unlock(dlc);
592 if (rfcomm_dev_get(dev->id) == NULL) {
593 rfcomm_dlc_lock(dlc);
Marcel Holtmann77f2a452007-05-05 00:36:10 +0200594 return;
Dave Young537d59a2008-06-01 23:50:52 -0700595 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700596
Marcel Holtmann77f2a452007-05-05 00:36:10 +0200597 rfcomm_dev_del(dev);
Jiri Slaby67054012012-04-02 13:54:51 +0200598 tty_port_put(&dev->port);
Dave Young537d59a2008-06-01 23:50:52 -0700599 rfcomm_dlc_lock(dlc);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700600 }
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900601 } else
Jiri Slabyf60db8c2012-04-02 13:54:50 +0200602 tty_hangup(dev->port.tty);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700603 }
604}
605
606static void rfcomm_dev_modem_status(struct rfcomm_dlc *dlc, u8 v24_sig)
607{
608 struct rfcomm_dev *dev = dlc->owner;
609 if (!dev)
610 return;
Timo Teräs7b9eb9e2005-08-09 20:28:21 -0700611
Linus Torvalds1da177e2005-04-16 15:20:36 -0700612 BT_DBG("dlc %p dev %p v24_sig 0x%02x", dlc, dev, v24_sig);
613
Timo Teräs7b9eb9e2005-08-09 20:28:21 -0700614 if ((dev->modem_status & TIOCM_CD) && !(v24_sig & RFCOMM_V24_DV)) {
Jiri Slabyf60db8c2012-04-02 13:54:50 +0200615 if (dev->port.tty && !C_CLOCAL(dev->port.tty))
616 tty_hangup(dev->port.tty);
Timo Teräs7b9eb9e2005-08-09 20:28:21 -0700617 }
618
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900619 dev->modem_status =
Linus Torvalds1da177e2005-04-16 15:20:36 -0700620 ((v24_sig & RFCOMM_V24_RTC) ? (TIOCM_DSR | TIOCM_DTR) : 0) |
621 ((v24_sig & RFCOMM_V24_RTR) ? (TIOCM_RTS | TIOCM_CTS) : 0) |
622 ((v24_sig & RFCOMM_V24_IC) ? TIOCM_RI : 0) |
623 ((v24_sig & RFCOMM_V24_DV) ? TIOCM_CD : 0);
624}
625
626/* ---- TTY functions ---- */
Marcel Holtmanna0c22f22008-07-14 20:13:52 +0200627static void rfcomm_tty_copy_pending(struct rfcomm_dev *dev)
628{
Jiri Slabyf60db8c2012-04-02 13:54:50 +0200629 struct tty_struct *tty = dev->port.tty;
Marcel Holtmanna0c22f22008-07-14 20:13:52 +0200630 struct sk_buff *skb;
631 int inserted = 0;
632
633 if (!tty)
634 return;
635
636 BT_DBG("dev %p tty %p", dev, tty);
637
638 rfcomm_dlc_lock(dev->dlc);
639
640 while ((skb = skb_dequeue(&dev->pending))) {
641 inserted += tty_insert_flip_string(tty, skb->data, skb->len);
642 kfree_skb(skb);
643 }
644
645 rfcomm_dlc_unlock(dev->dlc);
646
647 if (inserted > 0)
648 tty_flip_buffer_push(tty);
649}
650
Linus Torvalds1da177e2005-04-16 15:20:36 -0700651static int rfcomm_tty_open(struct tty_struct *tty, struct file *filp)
652{
653 DECLARE_WAITQUEUE(wait, current);
654 struct rfcomm_dev *dev;
655 struct rfcomm_dlc *dlc;
Jiri Slabyf997a012012-04-02 13:54:53 +0200656 unsigned long flags;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700657 int err, id;
658
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900659 id = tty->index;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700660
661 BT_DBG("tty %p id %d", tty, id);
662
663 /* We don't leak this refcount. For reasons which are not entirely
664 clear, the TTY layer will call our ->close() method even if the
665 open fails. We decrease the refcount there, and decreasing it
666 here too would cause breakage. */
667 dev = rfcomm_dev_get(id);
668 if (!dev)
669 return -ENODEV;
670
Marcel Holtmann9a5df922008-11-30 12:17:29 +0100671 BT_DBG("dev %p dst %s channel %d opened %d", dev, batostr(&dev->dst),
Jiri Slabyf997a012012-04-02 13:54:53 +0200672 dev->channel, dev->port.count);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700673
Jiri Slabyf997a012012-04-02 13:54:53 +0200674 spin_lock_irqsave(&dev->port.lock, flags);
675 if (++dev->port.count > 1) {
676 spin_unlock_irqrestore(&dev->port.lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700677 return 0;
Jiri Slabyf997a012012-04-02 13:54:53 +0200678 }
679 spin_unlock_irqrestore(&dev->port.lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700680
681 dlc = dev->dlc;
682
683 /* Attach TTY and open DLC */
684
685 rfcomm_dlc_lock(dlc);
686 tty->driver_data = dev;
Jiri Slabyf60db8c2012-04-02 13:54:50 +0200687 dev->port.tty = tty;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700688 rfcomm_dlc_unlock(dlc);
689 set_bit(RFCOMM_TTY_ATTACHED, &dev->flags);
690
691 err = rfcomm_dlc_open(dlc, &dev->src, &dev->dst, dev->channel);
692 if (err < 0)
693 return err;
694
695 /* Wait for DLC to connect */
696 add_wait_queue(&dev->wait, &wait);
697 while (1) {
698 set_current_state(TASK_INTERRUPTIBLE);
699
700 if (dlc->state == BT_CLOSED) {
701 err = -dev->err;
702 break;
703 }
704
705 if (dlc->state == BT_CONNECTED)
706 break;
707
708 if (signal_pending(current)) {
709 err = -EINTR;
710 break;
711 }
712
Alan Coxd29f3ef2012-05-03 22:24:08 +0100713 tty_unlock(tty);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700714 schedule();
Alan Coxd29f3ef2012-05-03 22:24:08 +0100715 tty_lock(tty);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700716 }
717 set_current_state(TASK_RUNNING);
718 remove_wait_queue(&dev->wait, &wait);
719
Marcel Holtmannc1a33132007-02-17 23:58:57 +0100720 if (err == 0)
Cornelia Huckffa6a702009-03-04 12:44:00 +0100721 device_move(dev->tty_dev, rfcomm_get_device(dev),
722 DPM_ORDER_DEV_AFTER_PARENT);
Marcel Holtmannc1a33132007-02-17 23:58:57 +0100723
Marcel Holtmanna0c22f22008-07-14 20:13:52 +0200724 rfcomm_tty_copy_pending(dev);
725
726 rfcomm_dlc_unthrottle(dev->dlc);
727
Linus Torvalds1da177e2005-04-16 15:20:36 -0700728 return err;
729}
730
731static void rfcomm_tty_close(struct tty_struct *tty, struct file *filp)
732{
733 struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data;
Jiri Slabyf997a012012-04-02 13:54:53 +0200734 unsigned long flags;
735
Linus Torvalds1da177e2005-04-16 15:20:36 -0700736 if (!dev)
737 return;
738
Marcel Holtmann9a5df922008-11-30 12:17:29 +0100739 BT_DBG("tty %p dev %p dlc %p opened %d", tty, dev, dev->dlc,
Jiri Slabyf997a012012-04-02 13:54:53 +0200740 dev->port.count);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700741
Jiri Slabyf997a012012-04-02 13:54:53 +0200742 spin_lock_irqsave(&dev->port.lock, flags);
743 if (!--dev->port.count) {
744 spin_unlock_irqrestore(&dev->port.lock, flags);
Dave Youngacea6852008-01-21 22:35:21 -0800745 if (dev->tty_dev->parent)
Cornelia Huckffa6a702009-03-04 12:44:00 +0100746 device_move(dev->tty_dev, NULL, DPM_ORDER_DEV_LAST);
Marcel Holtmannc1a33132007-02-17 23:58:57 +0100747
Linus Torvalds1da177e2005-04-16 15:20:36 -0700748 /* Close DLC and dettach TTY */
749 rfcomm_dlc_close(dev->dlc, 0);
750
751 clear_bit(RFCOMM_TTY_ATTACHED, &dev->flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700752
753 rfcomm_dlc_lock(dev->dlc);
754 tty->driver_data = NULL;
Jiri Slabyf60db8c2012-04-02 13:54:50 +0200755 dev->port.tty = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700756 rfcomm_dlc_unlock(dev->dlc);
Marcel Holtmann9a5df922008-11-30 12:17:29 +0100757
758 if (test_bit(RFCOMM_TTY_RELEASED, &dev->flags)) {
Gustavo F. Padovan393432c2011-12-27 15:28:45 -0200759 spin_lock(&rfcomm_dev_lock);
Marcel Holtmann9a5df922008-11-30 12:17:29 +0100760 list_del_init(&dev->list);
Gustavo F. Padovan393432c2011-12-27 15:28:45 -0200761 spin_unlock(&rfcomm_dev_lock);
Marcel Holtmann9a5df922008-11-30 12:17:29 +0100762
Jiri Slaby67054012012-04-02 13:54:51 +0200763 tty_port_put(&dev->port);
Marcel Holtmann9a5df922008-11-30 12:17:29 +0100764 }
Jiri Slabyf997a012012-04-02 13:54:53 +0200765 } else
766 spin_unlock_irqrestore(&dev->port.lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700767
Jiri Slaby67054012012-04-02 13:54:51 +0200768 tty_port_put(&dev->port);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700769}
770
771static int rfcomm_tty_write(struct tty_struct *tty, const unsigned char *buf, int count)
772{
773 struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data;
774 struct rfcomm_dlc *dlc = dev->dlc;
775 struct sk_buff *skb;
776 int err = 0, sent = 0, size;
777
778 BT_DBG("tty %p count %d", tty, count);
779
780 while (count) {
781 size = min_t(uint, count, dlc->mtu);
782
783 skb = rfcomm_wmalloc(dev, size + RFCOMM_SKB_RESERVE, GFP_ATOMIC);
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900784
Linus Torvalds1da177e2005-04-16 15:20:36 -0700785 if (!skb)
786 break;
787
788 skb_reserve(skb, RFCOMM_SKB_HEAD_RESERVE);
789
790 memcpy(skb_put(skb, size), buf + sent, size);
791
Andrei Emeltchenko285b4e92010-12-01 16:58:23 +0200792 err = rfcomm_dlc_send(dlc, skb);
793 if (err < 0) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700794 kfree_skb(skb);
795 break;
796 }
797
798 sent += size;
799 count -= size;
800 }
801
802 return sent ? sent : err;
803}
804
805static int rfcomm_tty_write_room(struct tty_struct *tty)
806{
807 struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data;
808 int room;
809
810 BT_DBG("tty %p", tty);
811
Marcel Holtmannb6e557f2007-01-08 02:16:27 +0100812 if (!dev || !dev->dlc)
813 return 0;
814
Linus Torvalds1da177e2005-04-16 15:20:36 -0700815 room = rfcomm_room(dev->dlc) - atomic_read(&dev->wmem_alloc);
816 if (room < 0)
817 room = 0;
Marcel Holtmannb6e557f2007-01-08 02:16:27 +0100818
Linus Torvalds1da177e2005-04-16 15:20:36 -0700819 return room;
820}
821
Alan Cox6caa76b2011-02-14 16:27:22 +0000822static int rfcomm_tty_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700823{
824 BT_DBG("tty %p cmd 0x%02x", tty, cmd);
825
826 switch (cmd) {
827 case TCGETS:
828 BT_DBG("TCGETS is not supported");
829 return -ENOIOCTLCMD;
830
831 case TCSETS:
832 BT_DBG("TCSETS is not supported");
833 return -ENOIOCTLCMD;
834
835 case TIOCMIWAIT:
836 BT_DBG("TIOCMIWAIT");
837 break;
838
Linus Torvalds1da177e2005-04-16 15:20:36 -0700839 case TIOCGSERIAL:
840 BT_ERR("TIOCGSERIAL is not supported");
841 return -ENOIOCTLCMD;
842
843 case TIOCSSERIAL:
844 BT_ERR("TIOCSSERIAL is not supported");
845 return -ENOIOCTLCMD;
846
847 case TIOCSERGSTRUCT:
848 BT_ERR("TIOCSERGSTRUCT is not supported");
849 return -ENOIOCTLCMD;
850
851 case TIOCSERGETLSR:
852 BT_ERR("TIOCSERGETLSR is not supported");
853 return -ENOIOCTLCMD;
854
855 case TIOCSERCONFIG:
856 BT_ERR("TIOCSERCONFIG is not supported");
857 return -ENOIOCTLCMD;
858
859 default:
860 return -ENOIOCTLCMD; /* ioctls which we must ignore */
861
862 }
863
864 return -ENOIOCTLCMD;
865}
866
Alan Cox606d0992006-12-08 02:38:45 -0800867static void rfcomm_tty_set_termios(struct tty_struct *tty, struct ktermios *old)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700868{
Alan Cox606d0992006-12-08 02:38:45 -0800869 struct ktermios *new = tty->termios;
J. Suter3a5e9032005-08-09 20:28:46 -0700870 int old_baud_rate = tty_termios_baud_rate(old);
871 int new_baud_rate = tty_termios_baud_rate(new);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700872
J. Suter3a5e9032005-08-09 20:28:46 -0700873 u8 baud, data_bits, stop_bits, parity, x_on, x_off;
874 u16 changes = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700875
J. Suter3a5e9032005-08-09 20:28:46 -0700876 struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data;
877
878 BT_DBG("tty %p termios %p", tty, old);
879
Marcel Holtmannff2d3672006-11-18 22:14:42 +0100880 if (!dev || !dev->dlc || !dev->dlc->session)
Marcel Holtmanncb19d9e2006-10-15 17:31:10 +0200881 return;
882
J. Suter3a5e9032005-08-09 20:28:46 -0700883 /* Handle turning off CRTSCTS */
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900884 if ((old->c_cflag & CRTSCTS) && !(new->c_cflag & CRTSCTS))
J. Suter3a5e9032005-08-09 20:28:46 -0700885 BT_DBG("Turning off CRTSCTS unsupported");
886
887 /* Parity on/off and when on, odd/even */
888 if (((old->c_cflag & PARENB) != (new->c_cflag & PARENB)) ||
Andrei Emeltchenko285b4e92010-12-01 16:58:23 +0200889 ((old->c_cflag & PARODD) != (new->c_cflag & PARODD))) {
J. Suter3a5e9032005-08-09 20:28:46 -0700890 changes |= RFCOMM_RPN_PM_PARITY;
891 BT_DBG("Parity change detected.");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700892 }
J. Suter3a5e9032005-08-09 20:28:46 -0700893
894 /* Mark and space parity are not supported! */
895 if (new->c_cflag & PARENB) {
896 if (new->c_cflag & PARODD) {
897 BT_DBG("Parity is ODD");
898 parity = RFCOMM_RPN_PARITY_ODD;
899 } else {
900 BT_DBG("Parity is EVEN");
901 parity = RFCOMM_RPN_PARITY_EVEN;
902 }
903 } else {
904 BT_DBG("Parity is OFF");
905 parity = RFCOMM_RPN_PARITY_NONE;
906 }
907
908 /* Setting the x_on / x_off characters */
909 if (old->c_cc[VSTOP] != new->c_cc[VSTOP]) {
910 BT_DBG("XOFF custom");
911 x_on = new->c_cc[VSTOP];
912 changes |= RFCOMM_RPN_PM_XON;
913 } else {
914 BT_DBG("XOFF default");
915 x_on = RFCOMM_RPN_XON_CHAR;
916 }
917
918 if (old->c_cc[VSTART] != new->c_cc[VSTART]) {
919 BT_DBG("XON custom");
920 x_off = new->c_cc[VSTART];
921 changes |= RFCOMM_RPN_PM_XOFF;
922 } else {
923 BT_DBG("XON default");
924 x_off = RFCOMM_RPN_XOFF_CHAR;
925 }
926
927 /* Handle setting of stop bits */
928 if ((old->c_cflag & CSTOPB) != (new->c_cflag & CSTOPB))
929 changes |= RFCOMM_RPN_PM_STOP;
930
931 /* POSIX does not support 1.5 stop bits and RFCOMM does not
932 * support 2 stop bits. So a request for 2 stop bits gets
933 * translated to 1.5 stop bits */
Andrei Emeltchenko285b4e92010-12-01 16:58:23 +0200934 if (new->c_cflag & CSTOPB)
J. Suter3a5e9032005-08-09 20:28:46 -0700935 stop_bits = RFCOMM_RPN_STOP_15;
Andrei Emeltchenko285b4e92010-12-01 16:58:23 +0200936 else
J. Suter3a5e9032005-08-09 20:28:46 -0700937 stop_bits = RFCOMM_RPN_STOP_1;
J. Suter3a5e9032005-08-09 20:28:46 -0700938
939 /* Handle number of data bits [5-8] */
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900940 if ((old->c_cflag & CSIZE) != (new->c_cflag & CSIZE))
J. Suter3a5e9032005-08-09 20:28:46 -0700941 changes |= RFCOMM_RPN_PM_DATA;
942
943 switch (new->c_cflag & CSIZE) {
944 case CS5:
945 data_bits = RFCOMM_RPN_DATA_5;
946 break;
947 case CS6:
948 data_bits = RFCOMM_RPN_DATA_6;
949 break;
950 case CS7:
951 data_bits = RFCOMM_RPN_DATA_7;
952 break;
953 case CS8:
954 data_bits = RFCOMM_RPN_DATA_8;
955 break;
956 default:
957 data_bits = RFCOMM_RPN_DATA_8;
958 break;
959 }
960
961 /* Handle baudrate settings */
962 if (old_baud_rate != new_baud_rate)
963 changes |= RFCOMM_RPN_PM_BITRATE;
964
965 switch (new_baud_rate) {
966 case 2400:
967 baud = RFCOMM_RPN_BR_2400;
968 break;
969 case 4800:
970 baud = RFCOMM_RPN_BR_4800;
971 break;
972 case 7200:
973 baud = RFCOMM_RPN_BR_7200;
974 break;
975 case 9600:
976 baud = RFCOMM_RPN_BR_9600;
977 break;
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900978 case 19200:
J. Suter3a5e9032005-08-09 20:28:46 -0700979 baud = RFCOMM_RPN_BR_19200;
980 break;
981 case 38400:
982 baud = RFCOMM_RPN_BR_38400;
983 break;
984 case 57600:
985 baud = RFCOMM_RPN_BR_57600;
986 break;
987 case 115200:
988 baud = RFCOMM_RPN_BR_115200;
989 break;
990 case 230400:
991 baud = RFCOMM_RPN_BR_230400;
992 break;
993 default:
994 /* 9600 is standard accordinag to the RFCOMM specification */
995 baud = RFCOMM_RPN_BR_9600;
996 break;
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900997
J. Suter3a5e9032005-08-09 20:28:46 -0700998 }
999
1000 if (changes)
1001 rfcomm_send_rpn(dev->dlc->session, 1, dev->dlc->dlci, baud,
1002 data_bits, stop_bits, parity,
1003 RFCOMM_RPN_FLOW_NONE, x_on, x_off, changes);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001004}
1005
1006static void rfcomm_tty_throttle(struct tty_struct *tty)
1007{
1008 struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data;
1009
1010 BT_DBG("tty %p dev %p", tty, dev);
J. Suter3a5e9032005-08-09 20:28:46 -07001011
Linus Torvalds1da177e2005-04-16 15:20:36 -07001012 rfcomm_dlc_throttle(dev->dlc);
1013}
1014
1015static void rfcomm_tty_unthrottle(struct tty_struct *tty)
1016{
1017 struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data;
1018
1019 BT_DBG("tty %p dev %p", tty, dev);
J. Suter3a5e9032005-08-09 20:28:46 -07001020
Linus Torvalds1da177e2005-04-16 15:20:36 -07001021 rfcomm_dlc_unthrottle(dev->dlc);
1022}
1023
1024static int rfcomm_tty_chars_in_buffer(struct tty_struct *tty)
1025{
1026 struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001027
1028 BT_DBG("tty %p dev %p", tty, dev);
1029
Marcel Holtmannb6e557f2007-01-08 02:16:27 +01001030 if (!dev || !dev->dlc)
1031 return 0;
1032
1033 if (!skb_queue_empty(&dev->dlc->tx_queue))
1034 return dev->dlc->mtu;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001035
1036 return 0;
1037}
1038
1039static void rfcomm_tty_flush_buffer(struct tty_struct *tty)
1040{
1041 struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001042
1043 BT_DBG("tty %p dev %p", tty, dev);
1044
Marcel Holtmannb6e557f2007-01-08 02:16:27 +01001045 if (!dev || !dev->dlc)
1046 return;
1047
Linus Torvalds1da177e2005-04-16 15:20:36 -07001048 skb_queue_purge(&dev->dlc->tx_queue);
Alan Coxa352def2008-07-16 21:53:12 +01001049 tty_wakeup(tty);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001050}
1051
1052static void rfcomm_tty_send_xchar(struct tty_struct *tty, char ch)
1053{
1054 BT_DBG("tty %p ch %c", tty, ch);
1055}
1056
1057static void rfcomm_tty_wait_until_sent(struct tty_struct *tty, int timeout)
1058{
1059 BT_DBG("tty %p timeout %d", tty, timeout);
1060}
1061
1062static void rfcomm_tty_hangup(struct tty_struct *tty)
1063{
1064 struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001065
1066 BT_DBG("tty %p dev %p", tty, dev);
1067
Marcel Holtmannb6e557f2007-01-08 02:16:27 +01001068 if (!dev)
1069 return;
1070
Linus Torvalds1da177e2005-04-16 15:20:36 -07001071 rfcomm_tty_flush_buffer(tty);
1072
Marcel Holtmann77f2a452007-05-05 00:36:10 +02001073 if (test_bit(RFCOMM_RELEASE_ONHUP, &dev->flags)) {
1074 if (rfcomm_dev_get(dev->id) == NULL)
1075 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001076 rfcomm_dev_del(dev);
Jiri Slaby67054012012-04-02 13:54:51 +02001077 tty_port_put(&dev->port);
Marcel Holtmann77f2a452007-05-05 00:36:10 +02001078 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001079}
1080
Alan Cox60b33c12011-02-14 16:26:14 +00001081static int rfcomm_tty_tiocmget(struct tty_struct *tty)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001082{
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09001083 struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001084
1085 BT_DBG("tty %p dev %p", tty, dev);
1086
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09001087 return dev->modem_status;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001088}
1089
Alan Cox20b9d172011-02-14 16:26:50 +00001090static int rfcomm_tty_tiocmset(struct tty_struct *tty, unsigned int set, unsigned int clear)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001091{
J. Suter3a5e9032005-08-09 20:28:46 -07001092 struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data;
1093 struct rfcomm_dlc *dlc = dev->dlc;
1094 u8 v24_sig;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001095
1096 BT_DBG("tty %p dev %p set 0x%02x clear 0x%02x", tty, dev, set, clear);
1097
J. Suter3a5e9032005-08-09 20:28:46 -07001098 rfcomm_dlc_get_modem_status(dlc, &v24_sig);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001099
J. Suter3a5e9032005-08-09 20:28:46 -07001100 if (set & TIOCM_DSR || set & TIOCM_DTR)
1101 v24_sig |= RFCOMM_V24_RTC;
1102 if (set & TIOCM_RTS || set & TIOCM_CTS)
1103 v24_sig |= RFCOMM_V24_RTR;
1104 if (set & TIOCM_RI)
1105 v24_sig |= RFCOMM_V24_IC;
1106 if (set & TIOCM_CD)
1107 v24_sig |= RFCOMM_V24_DV;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001108
J. Suter3a5e9032005-08-09 20:28:46 -07001109 if (clear & TIOCM_DSR || clear & TIOCM_DTR)
1110 v24_sig &= ~RFCOMM_V24_RTC;
1111 if (clear & TIOCM_RTS || clear & TIOCM_CTS)
1112 v24_sig &= ~RFCOMM_V24_RTR;
1113 if (clear & TIOCM_RI)
1114 v24_sig &= ~RFCOMM_V24_IC;
1115 if (clear & TIOCM_CD)
1116 v24_sig &= ~RFCOMM_V24_DV;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001117
J. Suter3a5e9032005-08-09 20:28:46 -07001118 rfcomm_dlc_set_modem_status(dlc, v24_sig);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001119
J. Suter3a5e9032005-08-09 20:28:46 -07001120 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001121}
1122
1123/* ---- TTY structure ---- */
1124
Jeff Dikeb68e31d2006-10-02 02:17:18 -07001125static const struct tty_operations rfcomm_ops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001126 .open = rfcomm_tty_open,
1127 .close = rfcomm_tty_close,
1128 .write = rfcomm_tty_write,
1129 .write_room = rfcomm_tty_write_room,
1130 .chars_in_buffer = rfcomm_tty_chars_in_buffer,
1131 .flush_buffer = rfcomm_tty_flush_buffer,
1132 .ioctl = rfcomm_tty_ioctl,
1133 .throttle = rfcomm_tty_throttle,
1134 .unthrottle = rfcomm_tty_unthrottle,
1135 .set_termios = rfcomm_tty_set_termios,
1136 .send_xchar = rfcomm_tty_send_xchar,
1137 .hangup = rfcomm_tty_hangup,
1138 .wait_until_sent = rfcomm_tty_wait_until_sent,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001139 .tiocmget = rfcomm_tty_tiocmget,
1140 .tiocmset = rfcomm_tty_tiocmset,
1141};
1142
Gustavo F. Padovan2f8362a2010-07-24 02:04:45 -03001143int __init rfcomm_init_ttys(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001144{
David Herrmann5ada9912011-10-24 15:30:57 +02001145 int error;
1146
Linus Torvalds1da177e2005-04-16 15:20:36 -07001147 rfcomm_tty_driver = alloc_tty_driver(RFCOMM_TTY_PORTS);
1148 if (!rfcomm_tty_driver)
David Herrmann5ada9912011-10-24 15:30:57 +02001149 return -ENOMEM;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001150
Linus Torvalds1da177e2005-04-16 15:20:36 -07001151 rfcomm_tty_driver->driver_name = "rfcomm";
Linus Torvalds1da177e2005-04-16 15:20:36 -07001152 rfcomm_tty_driver->name = "rfcomm";
1153 rfcomm_tty_driver->major = RFCOMM_TTY_MAJOR;
1154 rfcomm_tty_driver->minor_start = RFCOMM_TTY_MINOR;
1155 rfcomm_tty_driver->type = TTY_DRIVER_TYPE_SERIAL;
1156 rfcomm_tty_driver->subtype = SERIAL_TYPE_NORMAL;
Greg Kroah-Hartman331b8312005-06-20 21:15:16 -07001157 rfcomm_tty_driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001158 rfcomm_tty_driver->init_termios = tty_std_termios;
1159 rfcomm_tty_driver->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL;
Marcel Holtmannca37bdd2008-07-14 20:13:52 +02001160 rfcomm_tty_driver->init_termios.c_lflag &= ~ICANON;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001161 tty_set_operations(rfcomm_tty_driver, &rfcomm_ops);
1162
David Herrmann5ada9912011-10-24 15:30:57 +02001163 error = tty_register_driver(rfcomm_tty_driver);
1164 if (error) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001165 BT_ERR("Can't register RFCOMM TTY driver");
1166 put_tty_driver(rfcomm_tty_driver);
David Herrmann5ada9912011-10-24 15:30:57 +02001167 return error;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001168 }
1169
1170 BT_INFO("RFCOMM TTY layer initialized");
1171
1172 return 0;
1173}
1174
Gustavo F. Padovan28e95092010-07-31 19:57:05 -03001175void rfcomm_cleanup_ttys(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001176{
1177 tty_unregister_driver(rfcomm_tty_driver);
1178 put_tty_driver(rfcomm_tty_driver);
1179}