blob: 0433d26323341174b68a5412f1b352af22878fc8 [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;
Marcel Holtmann9a5df922008-11-30 12:17:29 +010057 atomic_t opened;
Linus Torvalds1da177e2005-04-16 15:20:36 -070058 int err;
59
60 bdaddr_t src;
61 bdaddr_t dst;
Andrei Emeltchenko285b4e92010-12-01 16:58:23 +020062 u8 channel;
Linus Torvalds1da177e2005-04-16 15:20:36 -070063
Andrei Emeltchenko285b4e92010-12-01 16:58:23 +020064 uint modem_status;
Linus Torvalds1da177e2005-04-16 15:20:36 -070065
66 struct rfcomm_dlc *dlc;
Linus Torvalds1da177e2005-04-16 15:20:36 -070067 wait_queue_head_t wait;
Linus Torvalds1da177e2005-04-16 15:20:36 -070068
Marcel Holtmannc1a33132007-02-17 23:58:57 +010069 struct device *tty_dev;
70
Andrei Emeltchenko285b4e92010-12-01 16:58:23 +020071 atomic_t wmem_alloc;
Marcel Holtmanna0c22f22008-07-14 20:13:52 +020072
73 struct sk_buff_head pending;
Linus Torvalds1da177e2005-04-16 15:20:36 -070074};
75
76static LIST_HEAD(rfcomm_dev_list);
Gustavo F. Padovan393432c2011-12-27 15:28:45 -020077static DEFINE_SPINLOCK(rfcomm_dev_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -070078
79static void rfcomm_dev_data_ready(struct rfcomm_dlc *dlc, struct sk_buff *skb);
80static void rfcomm_dev_state_change(struct rfcomm_dlc *dlc, int err);
81static void rfcomm_dev_modem_status(struct rfcomm_dlc *dlc, u8 v24_sig);
82
Linus Torvalds1da177e2005-04-16 15:20:36 -070083/* ---- Device functions ---- */
Jiri Slaby67054012012-04-02 13:54:51 +020084
85/*
86 * The reason this isn't actually a race, as you no doubt have a little voice
87 * screaming at you in your head, is that the refcount should never actually
88 * reach zero unless the device has already been taken off the list, in
89 * rfcomm_dev_del(). And if that's not true, we'll hit the BUG() in
90 * rfcomm_dev_destruct() anyway.
91 */
92static void rfcomm_dev_destruct(struct tty_port *port)
Linus Torvalds1da177e2005-04-16 15:20:36 -070093{
Jiri Slaby67054012012-04-02 13:54:51 +020094 struct rfcomm_dev *dev = container_of(port, struct rfcomm_dev, port);
Linus Torvalds1da177e2005-04-16 15:20:36 -070095 struct rfcomm_dlc *dlc = dev->dlc;
96
97 BT_DBG("dev %p dlc %p", dev, dlc);
98
Dave Youngf9513752008-01-10 22:22:52 -080099 /* Refcount should only hit zero when called from rfcomm_dev_del()
100 which will have taken us off the list. Everything else are
101 refcounting bugs. */
102 BUG_ON(!list_empty(&dev->list));
Ville Tervo8de0a152007-07-11 09:23:41 +0200103
Linus Torvalds1da177e2005-04-16 15:20:36 -0700104 rfcomm_dlc_lock(dlc);
105 /* Detach DLC if it's owned by this dev */
106 if (dlc->owner == dev)
107 dlc->owner = NULL;
108 rfcomm_dlc_unlock(dlc);
109
110 rfcomm_dlc_put(dlc);
111
112 tty_unregister_device(rfcomm_tty_driver, dev->id);
113
Linus Torvalds1da177e2005-04-16 15:20:36 -0700114 kfree(dev);
115
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900116 /* It's safe to call module_put() here because socket still
Linus Torvalds1da177e2005-04-16 15:20:36 -0700117 holds reference to this module. */
118 module_put(THIS_MODULE);
119}
120
Jiri Slaby67054012012-04-02 13:54:51 +0200121static const struct tty_port_operations rfcomm_port_ops = {
122 .destruct = rfcomm_dev_destruct,
123};
Linus Torvalds1da177e2005-04-16 15:20:36 -0700124
125static struct rfcomm_dev *__rfcomm_dev_get(int id)
126{
127 struct rfcomm_dev *dev;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700128
Luiz Augusto von Dentz8035ded2011-11-01 10:58:56 +0200129 list_for_each_entry(dev, &rfcomm_dev_list, list)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700130 if (dev->id == id)
131 return dev;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700132
133 return NULL;
134}
135
136static inline struct rfcomm_dev *rfcomm_dev_get(int id)
137{
138 struct rfcomm_dev *dev;
139
Gustavo F. Padovan393432c2011-12-27 15:28:45 -0200140 spin_lock(&rfcomm_dev_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700141
142 dev = __rfcomm_dev_get(id);
Ville Tervo8de0a152007-07-11 09:23:41 +0200143
144 if (dev) {
145 if (test_bit(RFCOMM_TTY_RELEASED, &dev->flags))
146 dev = NULL;
147 else
Jiri Slaby67054012012-04-02 13:54:51 +0200148 tty_port_get(&dev->port);
Ville Tervo8de0a152007-07-11 09:23:41 +0200149 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700150
Gustavo F. Padovan393432c2011-12-27 15:28:45 -0200151 spin_unlock(&rfcomm_dev_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700152
153 return dev;
154}
155
Marcel Holtmann0a85b962006-07-06 13:09:02 +0200156static struct device *rfcomm_get_device(struct rfcomm_dev *dev)
157{
158 struct hci_dev *hdev;
159 struct hci_conn *conn;
160
161 hdev = hci_get_route(&dev->dst, &dev->src);
162 if (!hdev)
163 return NULL;
164
165 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &dev->dst);
Marcel Holtmann0a85b962006-07-06 13:09:02 +0200166
167 hci_dev_put(hdev);
168
Marcel Holtmannb2cfcd72006-10-15 17:31:05 +0200169 return conn ? &conn->dev : NULL;
Marcel Holtmann0a85b962006-07-06 13:09:02 +0200170}
171
Marcel Holtmanndae6a0f2007-10-20 14:52:38 +0200172static ssize_t show_address(struct device *tty_dev, struct device_attribute *attr, char *buf)
173{
174 struct rfcomm_dev *dev = dev_get_drvdata(tty_dev);
Gustavo F. Padovand6b2eb22010-09-03 18:29:46 -0300175 return sprintf(buf, "%s\n", batostr(&dev->dst));
Marcel Holtmanndae6a0f2007-10-20 14:52:38 +0200176}
177
178static ssize_t show_channel(struct device *tty_dev, struct device_attribute *attr, char *buf)
179{
180 struct rfcomm_dev *dev = dev_get_drvdata(tty_dev);
181 return sprintf(buf, "%d\n", dev->channel);
182}
183
184static DEVICE_ATTR(address, S_IRUGO, show_address, NULL);
185static DEVICE_ATTR(channel, S_IRUGO, show_channel, NULL);
186
Linus Torvalds1da177e2005-04-16 15:20:36 -0700187static int rfcomm_dev_add(struct rfcomm_dev_req *req, struct rfcomm_dlc *dlc)
188{
Luiz Augusto von Dentz8035ded2011-11-01 10:58:56 +0200189 struct rfcomm_dev *dev, *entry;
Luiz Augusto von Dentze57d758a2012-03-07 20:20:14 +0200190 struct list_head *head = &rfcomm_dev_list;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700191 int err = 0;
192
193 BT_DBG("id %d channel %d", req->dev_id, req->channel);
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900194
Marcel Holtmann25ea6db2006-07-06 15:40:09 +0200195 dev = kzalloc(sizeof(struct rfcomm_dev), GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700196 if (!dev)
197 return -ENOMEM;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700198
Gustavo F. Padovan393432c2011-12-27 15:28:45 -0200199 spin_lock(&rfcomm_dev_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700200
201 if (req->dev_id < 0) {
202 dev->id = 0;
203
Luiz Augusto von Dentz8035ded2011-11-01 10:58:56 +0200204 list_for_each_entry(entry, &rfcomm_dev_list, list) {
205 if (entry->id != dev->id)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700206 break;
207
208 dev->id++;
Luiz Augusto von Dentze57d758a2012-03-07 20:20:14 +0200209 head = &entry->list;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700210 }
211 } else {
212 dev->id = req->dev_id;
213
Luiz Augusto von Dentz8035ded2011-11-01 10:58:56 +0200214 list_for_each_entry(entry, &rfcomm_dev_list, list) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700215 if (entry->id == dev->id) {
216 err = -EADDRINUSE;
217 goto out;
218 }
219
220 if (entry->id > dev->id - 1)
221 break;
222
Luiz Augusto von Dentze57d758a2012-03-07 20:20:14 +0200223 head = &entry->list;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700224 }
225 }
226
227 if ((dev->id < 0) || (dev->id > RFCOMM_MAX_DEV - 1)) {
228 err = -ENFILE;
229 goto out;
230 }
231
232 sprintf(dev->name, "rfcomm%d", dev->id);
233
234 list_add(&dev->list, head);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700235
236 bacpy(&dev->src, &req->src);
237 bacpy(&dev->dst, &req->dst);
238 dev->channel = req->channel;
239
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900240 dev->flags = req->flags &
Linus Torvalds1da177e2005-04-16 15:20:36 -0700241 ((1 << RFCOMM_RELEASE_ONHUP) | (1 << RFCOMM_REUSE_DLC));
242
Marcel Holtmann9a5df922008-11-30 12:17:29 +0100243 atomic_set(&dev->opened, 0);
244
Jiri Slabyf60db8c2012-04-02 13:54:50 +0200245 tty_port_init(&dev->port);
Jiri Slaby67054012012-04-02 13:54:51 +0200246 dev->port.ops = &rfcomm_port_ops;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700247 init_waitqueue_head(&dev->wait);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700248
Marcel Holtmanna0c22f22008-07-14 20:13:52 +0200249 skb_queue_head_init(&dev->pending);
250
Linus Torvalds1da177e2005-04-16 15:20:36 -0700251 rfcomm_dlc_lock(dlc);
Marcel Holtmanna0c22f22008-07-14 20:13:52 +0200252
253 if (req->flags & (1 << RFCOMM_REUSE_DLC)) {
254 struct sock *sk = dlc->owner;
255 struct sk_buff *skb;
256
257 BUG_ON(!sk);
258
259 rfcomm_dlc_throttle(dlc);
260
261 while ((skb = skb_dequeue(&sk->sk_receive_queue))) {
262 skb_orphan(skb);
263 skb_queue_tail(&dev->pending, skb);
264 atomic_sub(skb->len, &sk->sk_rmem_alloc);
265 }
266 }
267
Linus Torvalds1da177e2005-04-16 15:20:36 -0700268 dlc->data_ready = rfcomm_dev_data_ready;
269 dlc->state_change = rfcomm_dev_state_change;
270 dlc->modem_status = rfcomm_dev_modem_status;
271
272 dlc->owner = dev;
273 dev->dlc = dlc;
Marcel Holtmann8b6b3da2008-07-14 20:13:52 +0200274
275 rfcomm_dev_modem_status(dlc, dlc->remote_v24_sig);
276
Linus Torvalds1da177e2005-04-16 15:20:36 -0700277 rfcomm_dlc_unlock(dlc);
278
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900279 /* It's safe to call __module_get() here because socket already
Linus Torvalds1da177e2005-04-16 15:20:36 -0700280 holds reference to this module. */
281 __module_get(THIS_MODULE);
282
283out:
Gustavo F. Padovan393432c2011-12-27 15:28:45 -0200284 spin_unlock(&rfcomm_dev_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700285
Ilpo Järvinen037322a2008-12-14 23:18:00 -0800286 if (err < 0)
287 goto free;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700288
Marcel Holtmannc1a33132007-02-17 23:58:57 +0100289 dev->tty_dev = tty_register_device(rfcomm_tty_driver, dev->id, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700290
Ville Tervo8de0a152007-07-11 09:23:41 +0200291 if (IS_ERR(dev->tty_dev)) {
Marcel Holtmann09c7d822007-07-26 00:12:25 -0700292 err = PTR_ERR(dev->tty_dev);
Ville Tervo8de0a152007-07-11 09:23:41 +0200293 list_del(&dev->list);
Ilpo Järvinen037322a2008-12-14 23:18:00 -0800294 goto free;
Ville Tervo8de0a152007-07-11 09:23:41 +0200295 }
296
Marcel Holtmanndae6a0f2007-10-20 14:52:38 +0200297 dev_set_drvdata(dev->tty_dev, dev);
298
299 if (device_create_file(dev->tty_dev, &dev_attr_address) < 0)
300 BT_ERR("Failed to create address attribute");
301
302 if (device_create_file(dev->tty_dev, &dev_attr_channel) < 0)
303 BT_ERR("Failed to create channel attribute");
304
Linus Torvalds1da177e2005-04-16 15:20:36 -0700305 return dev->id;
Ilpo Järvinen037322a2008-12-14 23:18:00 -0800306
307free:
308 kfree(dev);
309 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700310}
311
312static void rfcomm_dev_del(struct rfcomm_dev *dev)
313{
314 BT_DBG("dev %p", dev);
315
Marcel Holtmann9a5df922008-11-30 12:17:29 +0100316 BUG_ON(test_and_set_bit(RFCOMM_TTY_RELEASED, &dev->flags));
317
318 if (atomic_read(&dev->opened) > 0)
319 return;
Dave Youngf9513752008-01-10 22:22:52 -0800320
Gustavo F. Padovan393432c2011-12-27 15:28:45 -0200321 spin_lock(&rfcomm_dev_lock);
Dave Youngf9513752008-01-10 22:22:52 -0800322 list_del_init(&dev->list);
Gustavo F. Padovan393432c2011-12-27 15:28:45 -0200323 spin_unlock(&rfcomm_dev_lock);
Dave Youngf9513752008-01-10 22:22:52 -0800324
Jiri Slaby67054012012-04-02 13:54:51 +0200325 tty_port_put(&dev->port);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700326}
327
328/* ---- Send buffer ---- */
329static inline unsigned int rfcomm_room(struct rfcomm_dlc *dlc)
330{
331 /* We can't let it be zero, because we don't get a callback
332 when tx_credits becomes nonzero, hence we'd never wake up */
333 return dlc->mtu * (dlc->tx_credits?:1);
334}
335
336static void rfcomm_wfree(struct sk_buff *skb)
337{
338 struct rfcomm_dev *dev = (void *) skb->sk;
Jiri Slabyb2c4be32012-04-02 13:54:52 +0200339 struct tty_struct *tty = dev->port.tty;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700340 atomic_sub(skb->truesize, &dev->wmem_alloc);
Jiri Slabyb2c4be32012-04-02 13:54:52 +0200341 if (test_bit(RFCOMM_TTY_ATTACHED, &dev->flags) && tty)
342 tty_wakeup(tty);
Jiri Slaby67054012012-04-02 13:54:51 +0200343 tty_port_put(&dev->port);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700344}
345
346static inline void rfcomm_set_owner_w(struct sk_buff *skb, struct rfcomm_dev *dev)
347{
Jiri Slaby67054012012-04-02 13:54:51 +0200348 tty_port_get(&dev->port);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700349 atomic_add(skb->truesize, &dev->wmem_alloc);
350 skb->sk = (void *) dev;
351 skb->destructor = rfcomm_wfree;
352}
353
Al Virodd0fc662005-10-07 07:46:04 +0100354static struct sk_buff *rfcomm_wmalloc(struct rfcomm_dev *dev, unsigned long size, gfp_t priority)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700355{
356 if (atomic_read(&dev->wmem_alloc) < rfcomm_room(dev->dlc)) {
357 struct sk_buff *skb = alloc_skb(size, priority);
358 if (skb) {
359 rfcomm_set_owner_w(skb, dev);
360 return skb;
361 }
362 }
363 return NULL;
364}
365
366/* ---- Device IOCTLs ---- */
367
368#define NOCAP_FLAGS ((1 << RFCOMM_REUSE_DLC) | (1 << RFCOMM_RELEASE_ONHUP))
369
370static int rfcomm_create_dev(struct sock *sk, void __user *arg)
371{
372 struct rfcomm_dev_req req;
373 struct rfcomm_dlc *dlc;
374 int id;
375
376 if (copy_from_user(&req, arg, sizeof(req)))
377 return -EFAULT;
378
Ville Tervo8de0a152007-07-11 09:23:41 +0200379 BT_DBG("sk %p dev_id %d flags 0x%x", sk, req.dev_id, req.flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700380
381 if (req.flags != NOCAP_FLAGS && !capable(CAP_NET_ADMIN))
382 return -EPERM;
383
384 if (req.flags & (1 << RFCOMM_REUSE_DLC)) {
385 /* Socket must be connected */
386 if (sk->sk_state != BT_CONNECTED)
387 return -EBADFD;
388
389 dlc = rfcomm_pi(sk)->dlc;
390 rfcomm_dlc_hold(dlc);
391 } else {
392 dlc = rfcomm_dlc_alloc(GFP_KERNEL);
393 if (!dlc)
394 return -ENOMEM;
395 }
396
397 id = rfcomm_dev_add(&req, dlc);
398 if (id < 0) {
399 rfcomm_dlc_put(dlc);
400 return id;
401 }
402
403 if (req.flags & (1 << RFCOMM_REUSE_DLC)) {
404 /* DLC is now used by device.
405 * Socket must be disconnected */
406 sk->sk_state = BT_CLOSED;
407 }
408
409 return id;
410}
411
412static int rfcomm_release_dev(void __user *arg)
413{
414 struct rfcomm_dev_req req;
415 struct rfcomm_dev *dev;
416
417 if (copy_from_user(&req, arg, sizeof(req)))
418 return -EFAULT;
419
Ville Tervo8de0a152007-07-11 09:23:41 +0200420 BT_DBG("dev_id %d flags 0x%x", req.dev_id, req.flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700421
Andrei Emeltchenko285b4e92010-12-01 16:58:23 +0200422 dev = rfcomm_dev_get(req.dev_id);
423 if (!dev)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700424 return -ENODEV;
425
426 if (dev->flags != NOCAP_FLAGS && !capable(CAP_NET_ADMIN)) {
Jiri Slaby67054012012-04-02 13:54:51 +0200427 tty_port_put(&dev->port);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700428 return -EPERM;
429 }
430
431 if (req.flags & (1 << RFCOMM_HANGUP_NOW))
432 rfcomm_dlc_close(dev->dlc, 0);
433
Mikko Rapeli84950cf2007-07-11 09:18:15 +0200434 /* Shut down TTY synchronously before freeing rfcomm_dev */
Jiri Slabyf60db8c2012-04-02 13:54:50 +0200435 if (dev->port.tty)
436 tty_vhangup(dev->port.tty);
Mikko Rapeli84950cf2007-07-11 09:18:15 +0200437
Dave Young93d80742008-02-05 03:12:06 -0800438 if (!test_bit(RFCOMM_RELEASE_ONHUP, &dev->flags))
439 rfcomm_dev_del(dev);
Jiri Slaby67054012012-04-02 13:54:51 +0200440 tty_port_put(&dev->port);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700441 return 0;
442}
443
444static int rfcomm_get_dev_list(void __user *arg)
445{
Luiz Augusto von Dentz8035ded2011-11-01 10:58:56 +0200446 struct rfcomm_dev *dev;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700447 struct rfcomm_dev_list_req *dl;
448 struct rfcomm_dev_info *di;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700449 int n = 0, size, err;
450 u16 dev_num;
451
452 BT_DBG("");
453
454 if (get_user(dev_num, (u16 __user *) arg))
455 return -EFAULT;
456
457 if (!dev_num || dev_num > (PAGE_SIZE * 4) / sizeof(*di))
458 return -EINVAL;
459
460 size = sizeof(*dl) + dev_num * sizeof(*di);
461
Andrei Emeltchenko285b4e92010-12-01 16:58:23 +0200462 dl = kmalloc(size, GFP_KERNEL);
463 if (!dl)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700464 return -ENOMEM;
465
466 di = dl->dev_info;
467
Gustavo F. Padovan393432c2011-12-27 15:28:45 -0200468 spin_lock(&rfcomm_dev_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700469
Luiz Augusto von Dentz8035ded2011-11-01 10:58:56 +0200470 list_for_each_entry(dev, &rfcomm_dev_list, list) {
Ville Tervo8de0a152007-07-11 09:23:41 +0200471 if (test_bit(RFCOMM_TTY_RELEASED, &dev->flags))
472 continue;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700473 (di + n)->id = dev->id;
474 (di + n)->flags = dev->flags;
475 (di + n)->state = dev->dlc->state;
476 (di + n)->channel = dev->channel;
477 bacpy(&(di + n)->src, &dev->src);
478 bacpy(&(di + n)->dst, &dev->dst);
479 if (++n >= dev_num)
480 break;
481 }
482
Gustavo F. Padovan393432c2011-12-27 15:28:45 -0200483 spin_unlock(&rfcomm_dev_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700484
485 dl->dev_num = n;
486 size = sizeof(*dl) + n * sizeof(*di);
487
488 err = copy_to_user(arg, dl, size);
489 kfree(dl);
490
491 return err ? -EFAULT : 0;
492}
493
494static int rfcomm_get_dev_info(void __user *arg)
495{
496 struct rfcomm_dev *dev;
497 struct rfcomm_dev_info di;
498 int err = 0;
499
500 BT_DBG("");
501
502 if (copy_from_user(&di, arg, sizeof(di)))
503 return -EFAULT;
504
Andrei Emeltchenko285b4e92010-12-01 16:58:23 +0200505 dev = rfcomm_dev_get(di.id);
506 if (!dev)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700507 return -ENODEV;
508
509 di.flags = dev->flags;
510 di.channel = dev->channel;
511 di.state = dev->dlc->state;
512 bacpy(&di.src, &dev->src);
513 bacpy(&di.dst, &dev->dst);
514
515 if (copy_to_user(arg, &di, sizeof(di)))
516 err = -EFAULT;
517
Jiri Slaby67054012012-04-02 13:54:51 +0200518 tty_port_put(&dev->port);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700519 return err;
520}
521
522int rfcomm_dev_ioctl(struct sock *sk, unsigned int cmd, void __user *arg)
523{
524 BT_DBG("cmd %d arg %p", cmd, arg);
525
526 switch (cmd) {
527 case RFCOMMCREATEDEV:
528 return rfcomm_create_dev(sk, arg);
529
530 case RFCOMMRELEASEDEV:
531 return rfcomm_release_dev(arg);
532
533 case RFCOMMGETDEVLIST:
534 return rfcomm_get_dev_list(arg);
535
536 case RFCOMMGETDEVINFO:
537 return rfcomm_get_dev_info(arg);
538 }
539
540 return -EINVAL;
541}
542
543/* ---- DLC callbacks ---- */
544static void rfcomm_dev_data_ready(struct rfcomm_dlc *dlc, struct sk_buff *skb)
545{
546 struct rfcomm_dev *dev = dlc->owner;
547 struct tty_struct *tty;
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900548
Marcel Holtmanna0c22f22008-07-14 20:13:52 +0200549 if (!dev) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700550 kfree_skb(skb);
551 return;
552 }
553
Jiri Slabyf60db8c2012-04-02 13:54:50 +0200554 tty = dev->port.tty;
Andrei Emeltchenko285b4e92010-12-01 16:58:23 +0200555 if (!tty || !skb_queue_empty(&dev->pending)) {
Marcel Holtmanna0c22f22008-07-14 20:13:52 +0200556 skb_queue_tail(&dev->pending, skb);
557 return;
558 }
559
Linus Torvalds1da177e2005-04-16 15:20:36 -0700560 BT_DBG("dlc %p tty %p len %d", dlc, tty, skb->len);
561
Paul Fulghum817d6d32006-06-28 04:26:47 -0700562 tty_insert_flip_string(tty, skb->data, skb->len);
563 tty_flip_buffer_push(tty);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700564
565 kfree_skb(skb);
566}
567
568static void rfcomm_dev_state_change(struct rfcomm_dlc *dlc, int err)
569{
570 struct rfcomm_dev *dev = dlc->owner;
571 if (!dev)
572 return;
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900573
Linus Torvalds1da177e2005-04-16 15:20:36 -0700574 BT_DBG("dlc %p dev %p err %d", dlc, dev, err);
575
576 dev->err = err;
577 wake_up_interruptible(&dev->wait);
578
579 if (dlc->state == BT_CLOSED) {
Jiri Slabyf60db8c2012-04-02 13:54:50 +0200580 if (!dev->port.tty) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700581 if (test_bit(RFCOMM_RELEASE_ONHUP, &dev->flags)) {
Dave Young537d59a2008-06-01 23:50:52 -0700582 /* Drop DLC lock here to avoid deadlock
583 * 1. rfcomm_dev_get will take rfcomm_dev_lock
584 * but in rfcomm_dev_add there's lock order:
585 * rfcomm_dev_lock -> dlc lock
Jiri Slaby67054012012-04-02 13:54:51 +0200586 * 2. tty_port_put will deadlock if it's
Dave Young537d59a2008-06-01 23:50:52 -0700587 * the last reference
588 */
589 rfcomm_dlc_unlock(dlc);
590 if (rfcomm_dev_get(dev->id) == NULL) {
591 rfcomm_dlc_lock(dlc);
Marcel Holtmann77f2a452007-05-05 00:36:10 +0200592 return;
Dave Young537d59a2008-06-01 23:50:52 -0700593 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700594
Marcel Holtmann77f2a452007-05-05 00:36:10 +0200595 rfcomm_dev_del(dev);
Jiri Slaby67054012012-04-02 13:54:51 +0200596 tty_port_put(&dev->port);
Dave Young537d59a2008-06-01 23:50:52 -0700597 rfcomm_dlc_lock(dlc);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700598 }
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900599 } else
Jiri Slabyf60db8c2012-04-02 13:54:50 +0200600 tty_hangup(dev->port.tty);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700601 }
602}
603
604static void rfcomm_dev_modem_status(struct rfcomm_dlc *dlc, u8 v24_sig)
605{
606 struct rfcomm_dev *dev = dlc->owner;
607 if (!dev)
608 return;
Timo Teräs7b9eb9e2005-08-09 20:28:21 -0700609
Linus Torvalds1da177e2005-04-16 15:20:36 -0700610 BT_DBG("dlc %p dev %p v24_sig 0x%02x", dlc, dev, v24_sig);
611
Timo Teräs7b9eb9e2005-08-09 20:28:21 -0700612 if ((dev->modem_status & TIOCM_CD) && !(v24_sig & RFCOMM_V24_DV)) {
Jiri Slabyf60db8c2012-04-02 13:54:50 +0200613 if (dev->port.tty && !C_CLOCAL(dev->port.tty))
614 tty_hangup(dev->port.tty);
Timo Teräs7b9eb9e2005-08-09 20:28:21 -0700615 }
616
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900617 dev->modem_status =
Linus Torvalds1da177e2005-04-16 15:20:36 -0700618 ((v24_sig & RFCOMM_V24_RTC) ? (TIOCM_DSR | TIOCM_DTR) : 0) |
619 ((v24_sig & RFCOMM_V24_RTR) ? (TIOCM_RTS | TIOCM_CTS) : 0) |
620 ((v24_sig & RFCOMM_V24_IC) ? TIOCM_RI : 0) |
621 ((v24_sig & RFCOMM_V24_DV) ? TIOCM_CD : 0);
622}
623
624/* ---- TTY functions ---- */
Marcel Holtmanna0c22f22008-07-14 20:13:52 +0200625static void rfcomm_tty_copy_pending(struct rfcomm_dev *dev)
626{
Jiri Slabyf60db8c2012-04-02 13:54:50 +0200627 struct tty_struct *tty = dev->port.tty;
Marcel Holtmanna0c22f22008-07-14 20:13:52 +0200628 struct sk_buff *skb;
629 int inserted = 0;
630
631 if (!tty)
632 return;
633
634 BT_DBG("dev %p tty %p", dev, tty);
635
636 rfcomm_dlc_lock(dev->dlc);
637
638 while ((skb = skb_dequeue(&dev->pending))) {
639 inserted += tty_insert_flip_string(tty, skb->data, skb->len);
640 kfree_skb(skb);
641 }
642
643 rfcomm_dlc_unlock(dev->dlc);
644
645 if (inserted > 0)
646 tty_flip_buffer_push(tty);
647}
648
Linus Torvalds1da177e2005-04-16 15:20:36 -0700649static int rfcomm_tty_open(struct tty_struct *tty, struct file *filp)
650{
651 DECLARE_WAITQUEUE(wait, current);
652 struct rfcomm_dev *dev;
653 struct rfcomm_dlc *dlc;
654 int err, id;
655
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900656 id = tty->index;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700657
658 BT_DBG("tty %p id %d", tty, id);
659
660 /* We don't leak this refcount. For reasons which are not entirely
661 clear, the TTY layer will call our ->close() method even if the
662 open fails. We decrease the refcount there, and decreasing it
663 here too would cause breakage. */
664 dev = rfcomm_dev_get(id);
665 if (!dev)
666 return -ENODEV;
667
Marcel Holtmann9a5df922008-11-30 12:17:29 +0100668 BT_DBG("dev %p dst %s channel %d opened %d", dev, batostr(&dev->dst),
669 dev->channel, atomic_read(&dev->opened));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700670
Marcel Holtmann9a5df922008-11-30 12:17:29 +0100671 if (atomic_inc_return(&dev->opened) > 1)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700672 return 0;
673
674 dlc = dev->dlc;
675
676 /* Attach TTY and open DLC */
677
678 rfcomm_dlc_lock(dlc);
679 tty->driver_data = dev;
Jiri Slabyf60db8c2012-04-02 13:54:50 +0200680 dev->port.tty = tty;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700681 rfcomm_dlc_unlock(dlc);
682 set_bit(RFCOMM_TTY_ATTACHED, &dev->flags);
683
684 err = rfcomm_dlc_open(dlc, &dev->src, &dev->dst, dev->channel);
685 if (err < 0)
686 return err;
687
688 /* Wait for DLC to connect */
689 add_wait_queue(&dev->wait, &wait);
690 while (1) {
691 set_current_state(TASK_INTERRUPTIBLE);
692
693 if (dlc->state == BT_CLOSED) {
694 err = -dev->err;
695 break;
696 }
697
698 if (dlc->state == BT_CONNECTED)
699 break;
700
701 if (signal_pending(current)) {
702 err = -EINTR;
703 break;
704 }
705
Vladislav P840af822011-02-14 15:21:50 -0200706 tty_unlock();
Linus Torvalds1da177e2005-04-16 15:20:36 -0700707 schedule();
Vladislav P840af822011-02-14 15:21:50 -0200708 tty_lock();
Linus Torvalds1da177e2005-04-16 15:20:36 -0700709 }
710 set_current_state(TASK_RUNNING);
711 remove_wait_queue(&dev->wait, &wait);
712
Marcel Holtmannc1a33132007-02-17 23:58:57 +0100713 if (err == 0)
Cornelia Huckffa6a702009-03-04 12:44:00 +0100714 device_move(dev->tty_dev, rfcomm_get_device(dev),
715 DPM_ORDER_DEV_AFTER_PARENT);
Marcel Holtmannc1a33132007-02-17 23:58:57 +0100716
Marcel Holtmanna0c22f22008-07-14 20:13:52 +0200717 rfcomm_tty_copy_pending(dev);
718
719 rfcomm_dlc_unthrottle(dev->dlc);
720
Linus Torvalds1da177e2005-04-16 15:20:36 -0700721 return err;
722}
723
724static void rfcomm_tty_close(struct tty_struct *tty, struct file *filp)
725{
726 struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data;
727 if (!dev)
728 return;
729
Marcel Holtmann9a5df922008-11-30 12:17:29 +0100730 BT_DBG("tty %p dev %p dlc %p opened %d", tty, dev, dev->dlc,
731 atomic_read(&dev->opened));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700732
Marcel Holtmann9a5df922008-11-30 12:17:29 +0100733 if (atomic_dec_and_test(&dev->opened)) {
Dave Youngacea6852008-01-21 22:35:21 -0800734 if (dev->tty_dev->parent)
Cornelia Huckffa6a702009-03-04 12:44:00 +0100735 device_move(dev->tty_dev, NULL, DPM_ORDER_DEV_LAST);
Marcel Holtmannc1a33132007-02-17 23:58:57 +0100736
Linus Torvalds1da177e2005-04-16 15:20:36 -0700737 /* Close DLC and dettach TTY */
738 rfcomm_dlc_close(dev->dlc, 0);
739
740 clear_bit(RFCOMM_TTY_ATTACHED, &dev->flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700741
742 rfcomm_dlc_lock(dev->dlc);
743 tty->driver_data = NULL;
Jiri Slabyf60db8c2012-04-02 13:54:50 +0200744 dev->port.tty = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700745 rfcomm_dlc_unlock(dev->dlc);
Marcel Holtmann9a5df922008-11-30 12:17:29 +0100746
747 if (test_bit(RFCOMM_TTY_RELEASED, &dev->flags)) {
Gustavo F. Padovan393432c2011-12-27 15:28:45 -0200748 spin_lock(&rfcomm_dev_lock);
Marcel Holtmann9a5df922008-11-30 12:17:29 +0100749 list_del_init(&dev->list);
Gustavo F. Padovan393432c2011-12-27 15:28:45 -0200750 spin_unlock(&rfcomm_dev_lock);
Marcel Holtmann9a5df922008-11-30 12:17:29 +0100751
Jiri Slaby67054012012-04-02 13:54:51 +0200752 tty_port_put(&dev->port);
Marcel Holtmann9a5df922008-11-30 12:17:29 +0100753 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700754 }
755
Jiri Slaby67054012012-04-02 13:54:51 +0200756 tty_port_put(&dev->port);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700757}
758
759static int rfcomm_tty_write(struct tty_struct *tty, const unsigned char *buf, int count)
760{
761 struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data;
762 struct rfcomm_dlc *dlc = dev->dlc;
763 struct sk_buff *skb;
764 int err = 0, sent = 0, size;
765
766 BT_DBG("tty %p count %d", tty, count);
767
768 while (count) {
769 size = min_t(uint, count, dlc->mtu);
770
771 skb = rfcomm_wmalloc(dev, size + RFCOMM_SKB_RESERVE, GFP_ATOMIC);
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900772
Linus Torvalds1da177e2005-04-16 15:20:36 -0700773 if (!skb)
774 break;
775
776 skb_reserve(skb, RFCOMM_SKB_HEAD_RESERVE);
777
778 memcpy(skb_put(skb, size), buf + sent, size);
779
Andrei Emeltchenko285b4e92010-12-01 16:58:23 +0200780 err = rfcomm_dlc_send(dlc, skb);
781 if (err < 0) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700782 kfree_skb(skb);
783 break;
784 }
785
786 sent += size;
787 count -= size;
788 }
789
790 return sent ? sent : err;
791}
792
793static int rfcomm_tty_write_room(struct tty_struct *tty)
794{
795 struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data;
796 int room;
797
798 BT_DBG("tty %p", tty);
799
Marcel Holtmannb6e557f2007-01-08 02:16:27 +0100800 if (!dev || !dev->dlc)
801 return 0;
802
Linus Torvalds1da177e2005-04-16 15:20:36 -0700803 room = rfcomm_room(dev->dlc) - atomic_read(&dev->wmem_alloc);
804 if (room < 0)
805 room = 0;
Marcel Holtmannb6e557f2007-01-08 02:16:27 +0100806
Linus Torvalds1da177e2005-04-16 15:20:36 -0700807 return room;
808}
809
Alan Cox6caa76b2011-02-14 16:27:22 +0000810static int rfcomm_tty_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700811{
812 BT_DBG("tty %p cmd 0x%02x", tty, cmd);
813
814 switch (cmd) {
815 case TCGETS:
816 BT_DBG("TCGETS is not supported");
817 return -ENOIOCTLCMD;
818
819 case TCSETS:
820 BT_DBG("TCSETS is not supported");
821 return -ENOIOCTLCMD;
822
823 case TIOCMIWAIT:
824 BT_DBG("TIOCMIWAIT");
825 break;
826
Linus Torvalds1da177e2005-04-16 15:20:36 -0700827 case TIOCGSERIAL:
828 BT_ERR("TIOCGSERIAL is not supported");
829 return -ENOIOCTLCMD;
830
831 case TIOCSSERIAL:
832 BT_ERR("TIOCSSERIAL is not supported");
833 return -ENOIOCTLCMD;
834
835 case TIOCSERGSTRUCT:
836 BT_ERR("TIOCSERGSTRUCT is not supported");
837 return -ENOIOCTLCMD;
838
839 case TIOCSERGETLSR:
840 BT_ERR("TIOCSERGETLSR is not supported");
841 return -ENOIOCTLCMD;
842
843 case TIOCSERCONFIG:
844 BT_ERR("TIOCSERCONFIG is not supported");
845 return -ENOIOCTLCMD;
846
847 default:
848 return -ENOIOCTLCMD; /* ioctls which we must ignore */
849
850 }
851
852 return -ENOIOCTLCMD;
853}
854
Alan Cox606d0992006-12-08 02:38:45 -0800855static void rfcomm_tty_set_termios(struct tty_struct *tty, struct ktermios *old)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700856{
Alan Cox606d0992006-12-08 02:38:45 -0800857 struct ktermios *new = tty->termios;
J. Suter3a5e9032005-08-09 20:28:46 -0700858 int old_baud_rate = tty_termios_baud_rate(old);
859 int new_baud_rate = tty_termios_baud_rate(new);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700860
J. Suter3a5e9032005-08-09 20:28:46 -0700861 u8 baud, data_bits, stop_bits, parity, x_on, x_off;
862 u16 changes = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700863
J. Suter3a5e9032005-08-09 20:28:46 -0700864 struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data;
865
866 BT_DBG("tty %p termios %p", tty, old);
867
Marcel Holtmannff2d3672006-11-18 22:14:42 +0100868 if (!dev || !dev->dlc || !dev->dlc->session)
Marcel Holtmanncb19d9e2006-10-15 17:31:10 +0200869 return;
870
J. Suter3a5e9032005-08-09 20:28:46 -0700871 /* Handle turning off CRTSCTS */
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900872 if ((old->c_cflag & CRTSCTS) && !(new->c_cflag & CRTSCTS))
J. Suter3a5e9032005-08-09 20:28:46 -0700873 BT_DBG("Turning off CRTSCTS unsupported");
874
875 /* Parity on/off and when on, odd/even */
876 if (((old->c_cflag & PARENB) != (new->c_cflag & PARENB)) ||
Andrei Emeltchenko285b4e92010-12-01 16:58:23 +0200877 ((old->c_cflag & PARODD) != (new->c_cflag & PARODD))) {
J. Suter3a5e9032005-08-09 20:28:46 -0700878 changes |= RFCOMM_RPN_PM_PARITY;
879 BT_DBG("Parity change detected.");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700880 }
J. Suter3a5e9032005-08-09 20:28:46 -0700881
882 /* Mark and space parity are not supported! */
883 if (new->c_cflag & PARENB) {
884 if (new->c_cflag & PARODD) {
885 BT_DBG("Parity is ODD");
886 parity = RFCOMM_RPN_PARITY_ODD;
887 } else {
888 BT_DBG("Parity is EVEN");
889 parity = RFCOMM_RPN_PARITY_EVEN;
890 }
891 } else {
892 BT_DBG("Parity is OFF");
893 parity = RFCOMM_RPN_PARITY_NONE;
894 }
895
896 /* Setting the x_on / x_off characters */
897 if (old->c_cc[VSTOP] != new->c_cc[VSTOP]) {
898 BT_DBG("XOFF custom");
899 x_on = new->c_cc[VSTOP];
900 changes |= RFCOMM_RPN_PM_XON;
901 } else {
902 BT_DBG("XOFF default");
903 x_on = RFCOMM_RPN_XON_CHAR;
904 }
905
906 if (old->c_cc[VSTART] != new->c_cc[VSTART]) {
907 BT_DBG("XON custom");
908 x_off = new->c_cc[VSTART];
909 changes |= RFCOMM_RPN_PM_XOFF;
910 } else {
911 BT_DBG("XON default");
912 x_off = RFCOMM_RPN_XOFF_CHAR;
913 }
914
915 /* Handle setting of stop bits */
916 if ((old->c_cflag & CSTOPB) != (new->c_cflag & CSTOPB))
917 changes |= RFCOMM_RPN_PM_STOP;
918
919 /* POSIX does not support 1.5 stop bits and RFCOMM does not
920 * support 2 stop bits. So a request for 2 stop bits gets
921 * translated to 1.5 stop bits */
Andrei Emeltchenko285b4e92010-12-01 16:58:23 +0200922 if (new->c_cflag & CSTOPB)
J. Suter3a5e9032005-08-09 20:28:46 -0700923 stop_bits = RFCOMM_RPN_STOP_15;
Andrei Emeltchenko285b4e92010-12-01 16:58:23 +0200924 else
J. Suter3a5e9032005-08-09 20:28:46 -0700925 stop_bits = RFCOMM_RPN_STOP_1;
J. Suter3a5e9032005-08-09 20:28:46 -0700926
927 /* Handle number of data bits [5-8] */
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900928 if ((old->c_cflag & CSIZE) != (new->c_cflag & CSIZE))
J. Suter3a5e9032005-08-09 20:28:46 -0700929 changes |= RFCOMM_RPN_PM_DATA;
930
931 switch (new->c_cflag & CSIZE) {
932 case CS5:
933 data_bits = RFCOMM_RPN_DATA_5;
934 break;
935 case CS6:
936 data_bits = RFCOMM_RPN_DATA_6;
937 break;
938 case CS7:
939 data_bits = RFCOMM_RPN_DATA_7;
940 break;
941 case CS8:
942 data_bits = RFCOMM_RPN_DATA_8;
943 break;
944 default:
945 data_bits = RFCOMM_RPN_DATA_8;
946 break;
947 }
948
949 /* Handle baudrate settings */
950 if (old_baud_rate != new_baud_rate)
951 changes |= RFCOMM_RPN_PM_BITRATE;
952
953 switch (new_baud_rate) {
954 case 2400:
955 baud = RFCOMM_RPN_BR_2400;
956 break;
957 case 4800:
958 baud = RFCOMM_RPN_BR_4800;
959 break;
960 case 7200:
961 baud = RFCOMM_RPN_BR_7200;
962 break;
963 case 9600:
964 baud = RFCOMM_RPN_BR_9600;
965 break;
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900966 case 19200:
J. Suter3a5e9032005-08-09 20:28:46 -0700967 baud = RFCOMM_RPN_BR_19200;
968 break;
969 case 38400:
970 baud = RFCOMM_RPN_BR_38400;
971 break;
972 case 57600:
973 baud = RFCOMM_RPN_BR_57600;
974 break;
975 case 115200:
976 baud = RFCOMM_RPN_BR_115200;
977 break;
978 case 230400:
979 baud = RFCOMM_RPN_BR_230400;
980 break;
981 default:
982 /* 9600 is standard accordinag to the RFCOMM specification */
983 baud = RFCOMM_RPN_BR_9600;
984 break;
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900985
J. Suter3a5e9032005-08-09 20:28:46 -0700986 }
987
988 if (changes)
989 rfcomm_send_rpn(dev->dlc->session, 1, dev->dlc->dlci, baud,
990 data_bits, stop_bits, parity,
991 RFCOMM_RPN_FLOW_NONE, x_on, x_off, changes);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700992}
993
994static void rfcomm_tty_throttle(struct tty_struct *tty)
995{
996 struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data;
997
998 BT_DBG("tty %p dev %p", tty, dev);
J. Suter3a5e9032005-08-09 20:28:46 -0700999
Linus Torvalds1da177e2005-04-16 15:20:36 -07001000 rfcomm_dlc_throttle(dev->dlc);
1001}
1002
1003static void rfcomm_tty_unthrottle(struct tty_struct *tty)
1004{
1005 struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data;
1006
1007 BT_DBG("tty %p dev %p", tty, dev);
J. Suter3a5e9032005-08-09 20:28:46 -07001008
Linus Torvalds1da177e2005-04-16 15:20:36 -07001009 rfcomm_dlc_unthrottle(dev->dlc);
1010}
1011
1012static int rfcomm_tty_chars_in_buffer(struct tty_struct *tty)
1013{
1014 struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001015
1016 BT_DBG("tty %p dev %p", tty, dev);
1017
Marcel Holtmannb6e557f2007-01-08 02:16:27 +01001018 if (!dev || !dev->dlc)
1019 return 0;
1020
1021 if (!skb_queue_empty(&dev->dlc->tx_queue))
1022 return dev->dlc->mtu;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001023
1024 return 0;
1025}
1026
1027static void rfcomm_tty_flush_buffer(struct tty_struct *tty)
1028{
1029 struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001030
1031 BT_DBG("tty %p dev %p", tty, dev);
1032
Marcel Holtmannb6e557f2007-01-08 02:16:27 +01001033 if (!dev || !dev->dlc)
1034 return;
1035
Linus Torvalds1da177e2005-04-16 15:20:36 -07001036 skb_queue_purge(&dev->dlc->tx_queue);
Alan Coxa352def2008-07-16 21:53:12 +01001037 tty_wakeup(tty);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001038}
1039
1040static void rfcomm_tty_send_xchar(struct tty_struct *tty, char ch)
1041{
1042 BT_DBG("tty %p ch %c", tty, ch);
1043}
1044
1045static void rfcomm_tty_wait_until_sent(struct tty_struct *tty, int timeout)
1046{
1047 BT_DBG("tty %p timeout %d", tty, timeout);
1048}
1049
1050static void rfcomm_tty_hangup(struct tty_struct *tty)
1051{
1052 struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001053
1054 BT_DBG("tty %p dev %p", tty, dev);
1055
Marcel Holtmannb6e557f2007-01-08 02:16:27 +01001056 if (!dev)
1057 return;
1058
Linus Torvalds1da177e2005-04-16 15:20:36 -07001059 rfcomm_tty_flush_buffer(tty);
1060
Marcel Holtmann77f2a452007-05-05 00:36:10 +02001061 if (test_bit(RFCOMM_RELEASE_ONHUP, &dev->flags)) {
1062 if (rfcomm_dev_get(dev->id) == NULL)
1063 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001064 rfcomm_dev_del(dev);
Jiri Slaby67054012012-04-02 13:54:51 +02001065 tty_port_put(&dev->port);
Marcel Holtmann77f2a452007-05-05 00:36:10 +02001066 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001067}
1068
Alan Cox60b33c12011-02-14 16:26:14 +00001069static int rfcomm_tty_tiocmget(struct tty_struct *tty)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001070{
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09001071 struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001072
1073 BT_DBG("tty %p dev %p", tty, dev);
1074
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09001075 return dev->modem_status;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001076}
1077
Alan Cox20b9d172011-02-14 16:26:50 +00001078static int rfcomm_tty_tiocmset(struct tty_struct *tty, unsigned int set, unsigned int clear)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001079{
J. Suter3a5e9032005-08-09 20:28:46 -07001080 struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data;
1081 struct rfcomm_dlc *dlc = dev->dlc;
1082 u8 v24_sig;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001083
1084 BT_DBG("tty %p dev %p set 0x%02x clear 0x%02x", tty, dev, set, clear);
1085
J. Suter3a5e9032005-08-09 20:28:46 -07001086 rfcomm_dlc_get_modem_status(dlc, &v24_sig);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001087
J. Suter3a5e9032005-08-09 20:28:46 -07001088 if (set & TIOCM_DSR || set & TIOCM_DTR)
1089 v24_sig |= RFCOMM_V24_RTC;
1090 if (set & TIOCM_RTS || set & TIOCM_CTS)
1091 v24_sig |= RFCOMM_V24_RTR;
1092 if (set & TIOCM_RI)
1093 v24_sig |= RFCOMM_V24_IC;
1094 if (set & TIOCM_CD)
1095 v24_sig |= RFCOMM_V24_DV;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001096
J. Suter3a5e9032005-08-09 20:28:46 -07001097 if (clear & TIOCM_DSR || clear & TIOCM_DTR)
1098 v24_sig &= ~RFCOMM_V24_RTC;
1099 if (clear & TIOCM_RTS || clear & TIOCM_CTS)
1100 v24_sig &= ~RFCOMM_V24_RTR;
1101 if (clear & TIOCM_RI)
1102 v24_sig &= ~RFCOMM_V24_IC;
1103 if (clear & TIOCM_CD)
1104 v24_sig &= ~RFCOMM_V24_DV;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001105
J. Suter3a5e9032005-08-09 20:28:46 -07001106 rfcomm_dlc_set_modem_status(dlc, v24_sig);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001107
J. Suter3a5e9032005-08-09 20:28:46 -07001108 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001109}
1110
1111/* ---- TTY structure ---- */
1112
Jeff Dikeb68e31d2006-10-02 02:17:18 -07001113static const struct tty_operations rfcomm_ops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001114 .open = rfcomm_tty_open,
1115 .close = rfcomm_tty_close,
1116 .write = rfcomm_tty_write,
1117 .write_room = rfcomm_tty_write_room,
1118 .chars_in_buffer = rfcomm_tty_chars_in_buffer,
1119 .flush_buffer = rfcomm_tty_flush_buffer,
1120 .ioctl = rfcomm_tty_ioctl,
1121 .throttle = rfcomm_tty_throttle,
1122 .unthrottle = rfcomm_tty_unthrottle,
1123 .set_termios = rfcomm_tty_set_termios,
1124 .send_xchar = rfcomm_tty_send_xchar,
1125 .hangup = rfcomm_tty_hangup,
1126 .wait_until_sent = rfcomm_tty_wait_until_sent,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001127 .tiocmget = rfcomm_tty_tiocmget,
1128 .tiocmset = rfcomm_tty_tiocmset,
1129};
1130
Gustavo F. Padovan2f8362a2010-07-24 02:04:45 -03001131int __init rfcomm_init_ttys(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001132{
David Herrmann5ada9912011-10-24 15:30:57 +02001133 int error;
1134
Linus Torvalds1da177e2005-04-16 15:20:36 -07001135 rfcomm_tty_driver = alloc_tty_driver(RFCOMM_TTY_PORTS);
1136 if (!rfcomm_tty_driver)
David Herrmann5ada9912011-10-24 15:30:57 +02001137 return -ENOMEM;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001138
Linus Torvalds1da177e2005-04-16 15:20:36 -07001139 rfcomm_tty_driver->driver_name = "rfcomm";
Linus Torvalds1da177e2005-04-16 15:20:36 -07001140 rfcomm_tty_driver->name = "rfcomm";
1141 rfcomm_tty_driver->major = RFCOMM_TTY_MAJOR;
1142 rfcomm_tty_driver->minor_start = RFCOMM_TTY_MINOR;
1143 rfcomm_tty_driver->type = TTY_DRIVER_TYPE_SERIAL;
1144 rfcomm_tty_driver->subtype = SERIAL_TYPE_NORMAL;
Greg Kroah-Hartman331b8312005-06-20 21:15:16 -07001145 rfcomm_tty_driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001146 rfcomm_tty_driver->init_termios = tty_std_termios;
1147 rfcomm_tty_driver->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL;
Marcel Holtmannca37bdd52008-07-14 20:13:52 +02001148 rfcomm_tty_driver->init_termios.c_lflag &= ~ICANON;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001149 tty_set_operations(rfcomm_tty_driver, &rfcomm_ops);
1150
David Herrmann5ada9912011-10-24 15:30:57 +02001151 error = tty_register_driver(rfcomm_tty_driver);
1152 if (error) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001153 BT_ERR("Can't register RFCOMM TTY driver");
1154 put_tty_driver(rfcomm_tty_driver);
David Herrmann5ada9912011-10-24 15:30:57 +02001155 return error;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001156 }
1157
1158 BT_INFO("RFCOMM TTY layer initialized");
1159
1160 return 0;
1161}
1162
Gustavo F. Padovan28e95092010-07-31 19:57:05 -03001163void rfcomm_cleanup_ttys(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001164{
1165 tty_unregister_driver(rfcomm_tty_driver);
1166 put_tty_driver(rfcomm_tty_driver);
1167}