blob: 4bf54b37725565031211110253a07920d52df433 [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 {
51 struct list_head list;
52 atomic_t refcnt;
53
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;
67 struct tty_struct *tty;
68 wait_queue_head_t wait;
David Herrmann96af7392011-10-24 15:30:58 +020069 struct work_struct wakeup_task;
Linus Torvalds1da177e2005-04-16 15:20:36 -070070
Marcel Holtmannc1a33132007-02-17 23:58:57 +010071 struct device *tty_dev;
72
Andrei Emeltchenko285b4e92010-12-01 16:58:23 +020073 atomic_t wmem_alloc;
Marcel Holtmanna0c22f22008-07-14 20:13:52 +020074
75 struct sk_buff_head pending;
Linus Torvalds1da177e2005-04-16 15:20:36 -070076};
77
78static LIST_HEAD(rfcomm_dev_list);
Gustavo F. Padovan393432c2011-12-27 15:28:45 -020079static DEFINE_SPINLOCK(rfcomm_dev_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -070080
81static void rfcomm_dev_data_ready(struct rfcomm_dlc *dlc, struct sk_buff *skb);
82static void rfcomm_dev_state_change(struct rfcomm_dlc *dlc, int err);
83static void rfcomm_dev_modem_status(struct rfcomm_dlc *dlc, u8 v24_sig);
84
David Herrmann96af7392011-10-24 15:30:58 +020085static void rfcomm_tty_wakeup(struct work_struct *work);
Linus Torvalds1da177e2005-04-16 15:20:36 -070086
87/* ---- Device functions ---- */
88static void rfcomm_dev_destruct(struct rfcomm_dev *dev)
89{
90 struct rfcomm_dlc *dlc = dev->dlc;
91
92 BT_DBG("dev %p dlc %p", dev, dlc);
93
Dave Youngf9513752008-01-10 22:22:52 -080094 /* Refcount should only hit zero when called from rfcomm_dev_del()
95 which will have taken us off the list. Everything else are
96 refcounting bugs. */
97 BUG_ON(!list_empty(&dev->list));
Ville Tervo8de0a152007-07-11 09:23:41 +020098
Linus Torvalds1da177e2005-04-16 15:20:36 -070099 rfcomm_dlc_lock(dlc);
100 /* Detach DLC if it's owned by this dev */
101 if (dlc->owner == dev)
102 dlc->owner = NULL;
103 rfcomm_dlc_unlock(dlc);
104
105 rfcomm_dlc_put(dlc);
106
107 tty_unregister_device(rfcomm_tty_driver, dev->id);
108
Linus Torvalds1da177e2005-04-16 15:20:36 -0700109 kfree(dev);
110
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900111 /* It's safe to call module_put() here because socket still
Linus Torvalds1da177e2005-04-16 15:20:36 -0700112 holds reference to this module. */
113 module_put(THIS_MODULE);
114}
115
116static inline void rfcomm_dev_hold(struct rfcomm_dev *dev)
117{
118 atomic_inc(&dev->refcnt);
119}
120
121static inline void rfcomm_dev_put(struct rfcomm_dev *dev)
122{
123 /* The reason this isn't actually a race, as you no
124 doubt have a little voice screaming at you in your
125 head, is that the refcount should never actually
126 reach zero unless the device has already been taken
127 off the list, in rfcomm_dev_del(). And if that's not
128 true, we'll hit the BUG() in rfcomm_dev_destruct()
129 anyway. */
130 if (atomic_dec_and_test(&dev->refcnt))
131 rfcomm_dev_destruct(dev);
132}
133
134static struct rfcomm_dev *__rfcomm_dev_get(int id)
135{
136 struct rfcomm_dev *dev;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700137
Luiz Augusto von Dentz8035ded2011-11-01 10:58:56 +0200138 list_for_each_entry(dev, &rfcomm_dev_list, list)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700139 if (dev->id == id)
140 return dev;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700141
142 return NULL;
143}
144
145static inline struct rfcomm_dev *rfcomm_dev_get(int id)
146{
147 struct rfcomm_dev *dev;
148
Gustavo F. Padovan393432c2011-12-27 15:28:45 -0200149 spin_lock(&rfcomm_dev_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700150
151 dev = __rfcomm_dev_get(id);
Ville Tervo8de0a152007-07-11 09:23:41 +0200152
153 if (dev) {
154 if (test_bit(RFCOMM_TTY_RELEASED, &dev->flags))
155 dev = NULL;
156 else
157 rfcomm_dev_hold(dev);
158 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700159
Gustavo F. Padovan393432c2011-12-27 15:28:45 -0200160 spin_unlock(&rfcomm_dev_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700161
162 return dev;
163}
164
Marcel Holtmann0a85b962006-07-06 13:09:02 +0200165static struct device *rfcomm_get_device(struct rfcomm_dev *dev)
166{
167 struct hci_dev *hdev;
168 struct hci_conn *conn;
169
170 hdev = hci_get_route(&dev->dst, &dev->src);
171 if (!hdev)
172 return NULL;
173
174 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &dev->dst);
Marcel Holtmann0a85b962006-07-06 13:09:02 +0200175
176 hci_dev_put(hdev);
177
Marcel Holtmannb2cfcd72006-10-15 17:31:05 +0200178 return conn ? &conn->dev : NULL;
Marcel Holtmann0a85b962006-07-06 13:09:02 +0200179}
180
Marcel Holtmanndae6a0f2007-10-20 14:52:38 +0200181static ssize_t show_address(struct device *tty_dev, struct device_attribute *attr, char *buf)
182{
183 struct rfcomm_dev *dev = dev_get_drvdata(tty_dev);
Gustavo F. Padovand6b2eb22010-09-03 18:29:46 -0300184 return sprintf(buf, "%s\n", batostr(&dev->dst));
Marcel Holtmanndae6a0f2007-10-20 14:52:38 +0200185}
186
187static ssize_t show_channel(struct device *tty_dev, struct device_attribute *attr, char *buf)
188{
189 struct rfcomm_dev *dev = dev_get_drvdata(tty_dev);
190 return sprintf(buf, "%d\n", dev->channel);
191}
192
193static DEVICE_ATTR(address, S_IRUGO, show_address, NULL);
194static DEVICE_ATTR(channel, S_IRUGO, show_channel, NULL);
195
Linus Torvalds1da177e2005-04-16 15:20:36 -0700196static int rfcomm_dev_add(struct rfcomm_dev_req *req, struct rfcomm_dlc *dlc)
197{
Luiz Augusto von Dentz8035ded2011-11-01 10:58:56 +0200198 struct rfcomm_dev *dev, *entry;
Luiz Augusto von Dentze57d758a2012-03-07 20:20:14 +0200199 struct list_head *head = &rfcomm_dev_list;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700200 int err = 0;
201
202 BT_DBG("id %d channel %d", req->dev_id, req->channel);
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900203
Marcel Holtmann25ea6db2006-07-06 15:40:09 +0200204 dev = kzalloc(sizeof(struct rfcomm_dev), GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700205 if (!dev)
206 return -ENOMEM;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700207
Gustavo F. Padovan393432c2011-12-27 15:28:45 -0200208 spin_lock(&rfcomm_dev_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700209
210 if (req->dev_id < 0) {
211 dev->id = 0;
212
Luiz Augusto von Dentz8035ded2011-11-01 10:58:56 +0200213 list_for_each_entry(entry, &rfcomm_dev_list, list) {
214 if (entry->id != dev->id)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700215 break;
216
217 dev->id++;
Luiz Augusto von Dentze57d758a2012-03-07 20:20:14 +0200218 head = &entry->list;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700219 }
220 } else {
221 dev->id = req->dev_id;
222
Luiz Augusto von Dentz8035ded2011-11-01 10:58:56 +0200223 list_for_each_entry(entry, &rfcomm_dev_list, list) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700224 if (entry->id == dev->id) {
225 err = -EADDRINUSE;
226 goto out;
227 }
228
229 if (entry->id > dev->id - 1)
230 break;
231
Luiz Augusto von Dentze57d758a2012-03-07 20:20:14 +0200232 head = &entry->list;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700233 }
234 }
235
236 if ((dev->id < 0) || (dev->id > RFCOMM_MAX_DEV - 1)) {
237 err = -ENFILE;
238 goto out;
239 }
240
241 sprintf(dev->name, "rfcomm%d", dev->id);
242
243 list_add(&dev->list, head);
244 atomic_set(&dev->refcnt, 1);
245
246 bacpy(&dev->src, &req->src);
247 bacpy(&dev->dst, &req->dst);
248 dev->channel = req->channel;
249
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900250 dev->flags = req->flags &
Linus Torvalds1da177e2005-04-16 15:20:36 -0700251 ((1 << RFCOMM_RELEASE_ONHUP) | (1 << RFCOMM_REUSE_DLC));
252
Marcel Holtmann9a5df922008-11-30 12:17:29 +0100253 atomic_set(&dev->opened, 0);
254
Linus Torvalds1da177e2005-04-16 15:20:36 -0700255 init_waitqueue_head(&dev->wait);
David Herrmann96af7392011-10-24 15:30:58 +0200256 INIT_WORK(&dev->wakeup_task, rfcomm_tty_wakeup);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700257
Marcel Holtmanna0c22f22008-07-14 20:13:52 +0200258 skb_queue_head_init(&dev->pending);
259
Linus Torvalds1da177e2005-04-16 15:20:36 -0700260 rfcomm_dlc_lock(dlc);
Marcel Holtmanna0c22f22008-07-14 20:13:52 +0200261
262 if (req->flags & (1 << RFCOMM_REUSE_DLC)) {
263 struct sock *sk = dlc->owner;
264 struct sk_buff *skb;
265
266 BUG_ON(!sk);
267
268 rfcomm_dlc_throttle(dlc);
269
270 while ((skb = skb_dequeue(&sk->sk_receive_queue))) {
271 skb_orphan(skb);
272 skb_queue_tail(&dev->pending, skb);
273 atomic_sub(skb->len, &sk->sk_rmem_alloc);
274 }
275 }
276
Linus Torvalds1da177e2005-04-16 15:20:36 -0700277 dlc->data_ready = rfcomm_dev_data_ready;
278 dlc->state_change = rfcomm_dev_state_change;
279 dlc->modem_status = rfcomm_dev_modem_status;
280
281 dlc->owner = dev;
282 dev->dlc = dlc;
Marcel Holtmann8b6b3da2008-07-14 20:13:52 +0200283
284 rfcomm_dev_modem_status(dlc, dlc->remote_v24_sig);
285
Linus Torvalds1da177e2005-04-16 15:20:36 -0700286 rfcomm_dlc_unlock(dlc);
287
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900288 /* It's safe to call __module_get() here because socket already
Linus Torvalds1da177e2005-04-16 15:20:36 -0700289 holds reference to this module. */
290 __module_get(THIS_MODULE);
291
292out:
Gustavo F. Padovan393432c2011-12-27 15:28:45 -0200293 spin_unlock(&rfcomm_dev_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700294
Ilpo Järvinen037322a2008-12-14 23:18:00 -0800295 if (err < 0)
296 goto free;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700297
Marcel Holtmannc1a33132007-02-17 23:58:57 +0100298 dev->tty_dev = tty_register_device(rfcomm_tty_driver, dev->id, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700299
Ville Tervo8de0a152007-07-11 09:23:41 +0200300 if (IS_ERR(dev->tty_dev)) {
Marcel Holtmann09c7d822007-07-26 00:12:25 -0700301 err = PTR_ERR(dev->tty_dev);
Ville Tervo8de0a152007-07-11 09:23:41 +0200302 list_del(&dev->list);
Ilpo Järvinen037322a2008-12-14 23:18:00 -0800303 goto free;
Ville Tervo8de0a152007-07-11 09:23:41 +0200304 }
305
Marcel Holtmanndae6a0f2007-10-20 14:52:38 +0200306 dev_set_drvdata(dev->tty_dev, dev);
307
308 if (device_create_file(dev->tty_dev, &dev_attr_address) < 0)
309 BT_ERR("Failed to create address attribute");
310
311 if (device_create_file(dev->tty_dev, &dev_attr_channel) < 0)
312 BT_ERR("Failed to create channel attribute");
313
Linus Torvalds1da177e2005-04-16 15:20:36 -0700314 return dev->id;
Ilpo Järvinen037322a2008-12-14 23:18:00 -0800315
316free:
317 kfree(dev);
318 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700319}
320
321static void rfcomm_dev_del(struct rfcomm_dev *dev)
322{
323 BT_DBG("dev %p", dev);
324
Marcel Holtmann9a5df922008-11-30 12:17:29 +0100325 BUG_ON(test_and_set_bit(RFCOMM_TTY_RELEASED, &dev->flags));
326
327 if (atomic_read(&dev->opened) > 0)
328 return;
Dave Youngf9513752008-01-10 22:22:52 -0800329
Gustavo F. Padovan393432c2011-12-27 15:28:45 -0200330 spin_lock(&rfcomm_dev_lock);
Dave Youngf9513752008-01-10 22:22:52 -0800331 list_del_init(&dev->list);
Gustavo F. Padovan393432c2011-12-27 15:28:45 -0200332 spin_unlock(&rfcomm_dev_lock);
Dave Youngf9513752008-01-10 22:22:52 -0800333
Linus Torvalds1da177e2005-04-16 15:20:36 -0700334 rfcomm_dev_put(dev);
335}
336
337/* ---- Send buffer ---- */
338static inline unsigned int rfcomm_room(struct rfcomm_dlc *dlc)
339{
340 /* We can't let it be zero, because we don't get a callback
341 when tx_credits becomes nonzero, hence we'd never wake up */
342 return dlc->mtu * (dlc->tx_credits?:1);
343}
344
345static void rfcomm_wfree(struct sk_buff *skb)
346{
347 struct rfcomm_dev *dev = (void *) skb->sk;
348 atomic_sub(skb->truesize, &dev->wmem_alloc);
349 if (test_bit(RFCOMM_TTY_ATTACHED, &dev->flags))
David Herrmann96af7392011-10-24 15:30:58 +0200350 queue_work(system_nrt_wq, &dev->wakeup_task);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700351 rfcomm_dev_put(dev);
352}
353
354static inline void rfcomm_set_owner_w(struct sk_buff *skb, struct rfcomm_dev *dev)
355{
356 rfcomm_dev_hold(dev);
357 atomic_add(skb->truesize, &dev->wmem_alloc);
358 skb->sk = (void *) dev;
359 skb->destructor = rfcomm_wfree;
360}
361
Al Virodd0fc662005-10-07 07:46:04 +0100362static struct sk_buff *rfcomm_wmalloc(struct rfcomm_dev *dev, unsigned long size, gfp_t priority)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700363{
364 if (atomic_read(&dev->wmem_alloc) < rfcomm_room(dev->dlc)) {
365 struct sk_buff *skb = alloc_skb(size, priority);
366 if (skb) {
367 rfcomm_set_owner_w(skb, dev);
368 return skb;
369 }
370 }
371 return NULL;
372}
373
374/* ---- Device IOCTLs ---- */
375
376#define NOCAP_FLAGS ((1 << RFCOMM_REUSE_DLC) | (1 << RFCOMM_RELEASE_ONHUP))
377
378static int rfcomm_create_dev(struct sock *sk, void __user *arg)
379{
380 struct rfcomm_dev_req req;
381 struct rfcomm_dlc *dlc;
382 int id;
383
384 if (copy_from_user(&req, arg, sizeof(req)))
385 return -EFAULT;
386
Ville Tervo8de0a152007-07-11 09:23:41 +0200387 BT_DBG("sk %p dev_id %d flags 0x%x", sk, req.dev_id, req.flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700388
389 if (req.flags != NOCAP_FLAGS && !capable(CAP_NET_ADMIN))
390 return -EPERM;
391
392 if (req.flags & (1 << RFCOMM_REUSE_DLC)) {
393 /* Socket must be connected */
394 if (sk->sk_state != BT_CONNECTED)
395 return -EBADFD;
396
397 dlc = rfcomm_pi(sk)->dlc;
398 rfcomm_dlc_hold(dlc);
399 } else {
400 dlc = rfcomm_dlc_alloc(GFP_KERNEL);
401 if (!dlc)
402 return -ENOMEM;
403 }
404
405 id = rfcomm_dev_add(&req, dlc);
406 if (id < 0) {
407 rfcomm_dlc_put(dlc);
408 return id;
409 }
410
411 if (req.flags & (1 << RFCOMM_REUSE_DLC)) {
412 /* DLC is now used by device.
413 * Socket must be disconnected */
414 sk->sk_state = BT_CLOSED;
415 }
416
417 return id;
418}
419
420static int rfcomm_release_dev(void __user *arg)
421{
422 struct rfcomm_dev_req req;
423 struct rfcomm_dev *dev;
424
425 if (copy_from_user(&req, arg, sizeof(req)))
426 return -EFAULT;
427
Ville Tervo8de0a152007-07-11 09:23:41 +0200428 BT_DBG("dev_id %d flags 0x%x", req.dev_id, req.flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700429
Andrei Emeltchenko285b4e92010-12-01 16:58:23 +0200430 dev = rfcomm_dev_get(req.dev_id);
431 if (!dev)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700432 return -ENODEV;
433
434 if (dev->flags != NOCAP_FLAGS && !capable(CAP_NET_ADMIN)) {
435 rfcomm_dev_put(dev);
436 return -EPERM;
437 }
438
439 if (req.flags & (1 << RFCOMM_HANGUP_NOW))
440 rfcomm_dlc_close(dev->dlc, 0);
441
Mikko Rapeli84950cf2007-07-11 09:18:15 +0200442 /* Shut down TTY synchronously before freeing rfcomm_dev */
443 if (dev->tty)
444 tty_vhangup(dev->tty);
445
Dave Young93d80742008-02-05 03:12:06 -0800446 if (!test_bit(RFCOMM_RELEASE_ONHUP, &dev->flags))
447 rfcomm_dev_del(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700448 rfcomm_dev_put(dev);
449 return 0;
450}
451
452static int rfcomm_get_dev_list(void __user *arg)
453{
Luiz Augusto von Dentz8035ded2011-11-01 10:58:56 +0200454 struct rfcomm_dev *dev;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700455 struct rfcomm_dev_list_req *dl;
456 struct rfcomm_dev_info *di;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700457 int n = 0, size, err;
458 u16 dev_num;
459
460 BT_DBG("");
461
462 if (get_user(dev_num, (u16 __user *) arg))
463 return -EFAULT;
464
465 if (!dev_num || dev_num > (PAGE_SIZE * 4) / sizeof(*di))
466 return -EINVAL;
467
468 size = sizeof(*dl) + dev_num * sizeof(*di);
469
Andrei Emeltchenko285b4e92010-12-01 16:58:23 +0200470 dl = kmalloc(size, GFP_KERNEL);
471 if (!dl)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700472 return -ENOMEM;
473
474 di = dl->dev_info;
475
Gustavo F. Padovan393432c2011-12-27 15:28:45 -0200476 spin_lock(&rfcomm_dev_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700477
Luiz Augusto von Dentz8035ded2011-11-01 10:58:56 +0200478 list_for_each_entry(dev, &rfcomm_dev_list, list) {
Ville Tervo8de0a152007-07-11 09:23:41 +0200479 if (test_bit(RFCOMM_TTY_RELEASED, &dev->flags))
480 continue;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700481 (di + n)->id = dev->id;
482 (di + n)->flags = dev->flags;
483 (di + n)->state = dev->dlc->state;
484 (di + n)->channel = dev->channel;
485 bacpy(&(di + n)->src, &dev->src);
486 bacpy(&(di + n)->dst, &dev->dst);
487 if (++n >= dev_num)
488 break;
489 }
490
Gustavo F. Padovan393432c2011-12-27 15:28:45 -0200491 spin_unlock(&rfcomm_dev_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700492
493 dl->dev_num = n;
494 size = sizeof(*dl) + n * sizeof(*di);
495
496 err = copy_to_user(arg, dl, size);
497 kfree(dl);
498
499 return err ? -EFAULT : 0;
500}
501
502static int rfcomm_get_dev_info(void __user *arg)
503{
504 struct rfcomm_dev *dev;
505 struct rfcomm_dev_info di;
506 int err = 0;
507
508 BT_DBG("");
509
510 if (copy_from_user(&di, arg, sizeof(di)))
511 return -EFAULT;
512
Andrei Emeltchenko285b4e92010-12-01 16:58:23 +0200513 dev = rfcomm_dev_get(di.id);
514 if (!dev)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700515 return -ENODEV;
516
517 di.flags = dev->flags;
518 di.channel = dev->channel;
519 di.state = dev->dlc->state;
520 bacpy(&di.src, &dev->src);
521 bacpy(&di.dst, &dev->dst);
522
523 if (copy_to_user(arg, &di, sizeof(di)))
524 err = -EFAULT;
525
526 rfcomm_dev_put(dev);
527 return err;
528}
529
530int rfcomm_dev_ioctl(struct sock *sk, unsigned int cmd, void __user *arg)
531{
532 BT_DBG("cmd %d arg %p", cmd, arg);
533
534 switch (cmd) {
535 case RFCOMMCREATEDEV:
536 return rfcomm_create_dev(sk, arg);
537
538 case RFCOMMRELEASEDEV:
539 return rfcomm_release_dev(arg);
540
541 case RFCOMMGETDEVLIST:
542 return rfcomm_get_dev_list(arg);
543
544 case RFCOMMGETDEVINFO:
545 return rfcomm_get_dev_info(arg);
546 }
547
548 return -EINVAL;
549}
550
551/* ---- DLC callbacks ---- */
552static void rfcomm_dev_data_ready(struct rfcomm_dlc *dlc, struct sk_buff *skb)
553{
554 struct rfcomm_dev *dev = dlc->owner;
555 struct tty_struct *tty;
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900556
Marcel Holtmanna0c22f22008-07-14 20:13:52 +0200557 if (!dev) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700558 kfree_skb(skb);
559 return;
560 }
561
Andrei Emeltchenko285b4e92010-12-01 16:58:23 +0200562 tty = dev->tty;
563 if (!tty || !skb_queue_empty(&dev->pending)) {
Marcel Holtmanna0c22f22008-07-14 20:13:52 +0200564 skb_queue_tail(&dev->pending, skb);
565 return;
566 }
567
Linus Torvalds1da177e2005-04-16 15:20:36 -0700568 BT_DBG("dlc %p tty %p len %d", dlc, tty, skb->len);
569
Paul Fulghum817d6d32006-06-28 04:26:47 -0700570 tty_insert_flip_string(tty, skb->data, skb->len);
571 tty_flip_buffer_push(tty);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700572
573 kfree_skb(skb);
574}
575
576static void rfcomm_dev_state_change(struct rfcomm_dlc *dlc, int err)
577{
578 struct rfcomm_dev *dev = dlc->owner;
579 if (!dev)
580 return;
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900581
Linus Torvalds1da177e2005-04-16 15:20:36 -0700582 BT_DBG("dlc %p dev %p err %d", dlc, dev, err);
583
584 dev->err = err;
585 wake_up_interruptible(&dev->wait);
586
587 if (dlc->state == BT_CLOSED) {
588 if (!dev->tty) {
589 if (test_bit(RFCOMM_RELEASE_ONHUP, &dev->flags)) {
Dave Young537d59a2008-06-01 23:50:52 -0700590 /* Drop DLC lock here to avoid deadlock
591 * 1. rfcomm_dev_get will take rfcomm_dev_lock
592 * but in rfcomm_dev_add there's lock order:
593 * rfcomm_dev_lock -> dlc lock
594 * 2. rfcomm_dev_put will deadlock if it's
595 * the last reference
596 */
597 rfcomm_dlc_unlock(dlc);
598 if (rfcomm_dev_get(dev->id) == NULL) {
599 rfcomm_dlc_lock(dlc);
Marcel Holtmann77f2a452007-05-05 00:36:10 +0200600 return;
Dave Young537d59a2008-06-01 23:50:52 -0700601 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700602
Marcel Holtmann77f2a452007-05-05 00:36:10 +0200603 rfcomm_dev_del(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700604 rfcomm_dev_put(dev);
Dave Young537d59a2008-06-01 23:50:52 -0700605 rfcomm_dlc_lock(dlc);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700606 }
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900607 } else
Linus Torvalds1da177e2005-04-16 15:20:36 -0700608 tty_hangup(dev->tty);
609 }
610}
611
612static void rfcomm_dev_modem_status(struct rfcomm_dlc *dlc, u8 v24_sig)
613{
614 struct rfcomm_dev *dev = dlc->owner;
615 if (!dev)
616 return;
Timo Teräs7b9eb9e2005-08-09 20:28:21 -0700617
Linus Torvalds1da177e2005-04-16 15:20:36 -0700618 BT_DBG("dlc %p dev %p v24_sig 0x%02x", dlc, dev, v24_sig);
619
Timo Teräs7b9eb9e2005-08-09 20:28:21 -0700620 if ((dev->modem_status & TIOCM_CD) && !(v24_sig & RFCOMM_V24_DV)) {
621 if (dev->tty && !C_CLOCAL(dev->tty))
622 tty_hangup(dev->tty);
623 }
624
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900625 dev->modem_status =
Linus Torvalds1da177e2005-04-16 15:20:36 -0700626 ((v24_sig & RFCOMM_V24_RTC) ? (TIOCM_DSR | TIOCM_DTR) : 0) |
627 ((v24_sig & RFCOMM_V24_RTR) ? (TIOCM_RTS | TIOCM_CTS) : 0) |
628 ((v24_sig & RFCOMM_V24_IC) ? TIOCM_RI : 0) |
629 ((v24_sig & RFCOMM_V24_DV) ? TIOCM_CD : 0);
630}
631
632/* ---- TTY functions ---- */
David Herrmann96af7392011-10-24 15:30:58 +0200633static void rfcomm_tty_wakeup(struct work_struct *work)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700634{
David Herrmann96af7392011-10-24 15:30:58 +0200635 struct rfcomm_dev *dev = container_of(work, struct rfcomm_dev,
636 wakeup_task);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700637 struct tty_struct *tty = dev->tty;
638 if (!tty)
639 return;
640
641 BT_DBG("dev %p tty %p", dev, tty);
Alan Coxa352def2008-07-16 21:53:12 +0100642 tty_wakeup(tty);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700643}
644
Marcel Holtmanna0c22f22008-07-14 20:13:52 +0200645static void rfcomm_tty_copy_pending(struct rfcomm_dev *dev)
646{
647 struct tty_struct *tty = dev->tty;
648 struct sk_buff *skb;
649 int inserted = 0;
650
651 if (!tty)
652 return;
653
654 BT_DBG("dev %p tty %p", dev, tty);
655
656 rfcomm_dlc_lock(dev->dlc);
657
658 while ((skb = skb_dequeue(&dev->pending))) {
659 inserted += tty_insert_flip_string(tty, skb->data, skb->len);
660 kfree_skb(skb);
661 }
662
663 rfcomm_dlc_unlock(dev->dlc);
664
665 if (inserted > 0)
666 tty_flip_buffer_push(tty);
667}
668
Linus Torvalds1da177e2005-04-16 15:20:36 -0700669static int rfcomm_tty_open(struct tty_struct *tty, struct file *filp)
670{
671 DECLARE_WAITQUEUE(wait, current);
672 struct rfcomm_dev *dev;
673 struct rfcomm_dlc *dlc;
674 int err, id;
675
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900676 id = tty->index;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700677
678 BT_DBG("tty %p id %d", tty, id);
679
680 /* We don't leak this refcount. For reasons which are not entirely
681 clear, the TTY layer will call our ->close() method even if the
682 open fails. We decrease the refcount there, and decreasing it
683 here too would cause breakage. */
684 dev = rfcomm_dev_get(id);
685 if (!dev)
686 return -ENODEV;
687
Marcel Holtmann9a5df922008-11-30 12:17:29 +0100688 BT_DBG("dev %p dst %s channel %d opened %d", dev, batostr(&dev->dst),
689 dev->channel, atomic_read(&dev->opened));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700690
Marcel Holtmann9a5df922008-11-30 12:17:29 +0100691 if (atomic_inc_return(&dev->opened) > 1)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700692 return 0;
693
694 dlc = dev->dlc;
695
696 /* Attach TTY and open DLC */
697
698 rfcomm_dlc_lock(dlc);
699 tty->driver_data = dev;
700 dev->tty = tty;
701 rfcomm_dlc_unlock(dlc);
702 set_bit(RFCOMM_TTY_ATTACHED, &dev->flags);
703
704 err = rfcomm_dlc_open(dlc, &dev->src, &dev->dst, dev->channel);
705 if (err < 0)
706 return err;
707
708 /* Wait for DLC to connect */
709 add_wait_queue(&dev->wait, &wait);
710 while (1) {
711 set_current_state(TASK_INTERRUPTIBLE);
712
713 if (dlc->state == BT_CLOSED) {
714 err = -dev->err;
715 break;
716 }
717
718 if (dlc->state == BT_CONNECTED)
719 break;
720
721 if (signal_pending(current)) {
722 err = -EINTR;
723 break;
724 }
725
Vladislav P840af822011-02-14 15:21:50 -0200726 tty_unlock();
Linus Torvalds1da177e2005-04-16 15:20:36 -0700727 schedule();
Vladislav P840af822011-02-14 15:21:50 -0200728 tty_lock();
Linus Torvalds1da177e2005-04-16 15:20:36 -0700729 }
730 set_current_state(TASK_RUNNING);
731 remove_wait_queue(&dev->wait, &wait);
732
Marcel Holtmannc1a33132007-02-17 23:58:57 +0100733 if (err == 0)
Cornelia Huckffa6a702009-03-04 12:44:00 +0100734 device_move(dev->tty_dev, rfcomm_get_device(dev),
735 DPM_ORDER_DEV_AFTER_PARENT);
Marcel Holtmannc1a33132007-02-17 23:58:57 +0100736
Marcel Holtmanna0c22f22008-07-14 20:13:52 +0200737 rfcomm_tty_copy_pending(dev);
738
739 rfcomm_dlc_unthrottle(dev->dlc);
740
Linus Torvalds1da177e2005-04-16 15:20:36 -0700741 return err;
742}
743
744static void rfcomm_tty_close(struct tty_struct *tty, struct file *filp)
745{
746 struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data;
747 if (!dev)
748 return;
749
Marcel Holtmann9a5df922008-11-30 12:17:29 +0100750 BT_DBG("tty %p dev %p dlc %p opened %d", tty, dev, dev->dlc,
751 atomic_read(&dev->opened));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700752
Marcel Holtmann9a5df922008-11-30 12:17:29 +0100753 if (atomic_dec_and_test(&dev->opened)) {
Dave Youngacea6852008-01-21 22:35:21 -0800754 if (dev->tty_dev->parent)
Cornelia Huckffa6a702009-03-04 12:44:00 +0100755 device_move(dev->tty_dev, NULL, DPM_ORDER_DEV_LAST);
Marcel Holtmannc1a33132007-02-17 23:58:57 +0100756
Linus Torvalds1da177e2005-04-16 15:20:36 -0700757 /* Close DLC and dettach TTY */
758 rfcomm_dlc_close(dev->dlc, 0);
759
760 clear_bit(RFCOMM_TTY_ATTACHED, &dev->flags);
David Herrmann96af7392011-10-24 15:30:58 +0200761 cancel_work_sync(&dev->wakeup_task);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700762
763 rfcomm_dlc_lock(dev->dlc);
764 tty->driver_data = NULL;
765 dev->tty = NULL;
766 rfcomm_dlc_unlock(dev->dlc);
Marcel Holtmann9a5df922008-11-30 12:17:29 +0100767
768 if (test_bit(RFCOMM_TTY_RELEASED, &dev->flags)) {
Gustavo F. Padovan393432c2011-12-27 15:28:45 -0200769 spin_lock(&rfcomm_dev_lock);
Marcel Holtmann9a5df922008-11-30 12:17:29 +0100770 list_del_init(&dev->list);
Gustavo F. Padovan393432c2011-12-27 15:28:45 -0200771 spin_unlock(&rfcomm_dev_lock);
Marcel Holtmann9a5df922008-11-30 12:17:29 +0100772
773 rfcomm_dev_put(dev);
774 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700775 }
776
777 rfcomm_dev_put(dev);
778}
779
780static int rfcomm_tty_write(struct tty_struct *tty, const unsigned char *buf, int count)
781{
782 struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data;
783 struct rfcomm_dlc *dlc = dev->dlc;
784 struct sk_buff *skb;
785 int err = 0, sent = 0, size;
786
787 BT_DBG("tty %p count %d", tty, count);
788
789 while (count) {
790 size = min_t(uint, count, dlc->mtu);
791
792 skb = rfcomm_wmalloc(dev, size + RFCOMM_SKB_RESERVE, GFP_ATOMIC);
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900793
Linus Torvalds1da177e2005-04-16 15:20:36 -0700794 if (!skb)
795 break;
796
797 skb_reserve(skb, RFCOMM_SKB_HEAD_RESERVE);
798
799 memcpy(skb_put(skb, size), buf + sent, size);
800
Andrei Emeltchenko285b4e92010-12-01 16:58:23 +0200801 err = rfcomm_dlc_send(dlc, skb);
802 if (err < 0) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700803 kfree_skb(skb);
804 break;
805 }
806
807 sent += size;
808 count -= size;
809 }
810
811 return sent ? sent : err;
812}
813
814static int rfcomm_tty_write_room(struct tty_struct *tty)
815{
816 struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data;
817 int room;
818
819 BT_DBG("tty %p", tty);
820
Marcel Holtmannb6e557f2007-01-08 02:16:27 +0100821 if (!dev || !dev->dlc)
822 return 0;
823
Linus Torvalds1da177e2005-04-16 15:20:36 -0700824 room = rfcomm_room(dev->dlc) - atomic_read(&dev->wmem_alloc);
825 if (room < 0)
826 room = 0;
Marcel Holtmannb6e557f2007-01-08 02:16:27 +0100827
Linus Torvalds1da177e2005-04-16 15:20:36 -0700828 return room;
829}
830
Alan Cox6caa76b2011-02-14 16:27:22 +0000831static int rfcomm_tty_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700832{
833 BT_DBG("tty %p cmd 0x%02x", tty, cmd);
834
835 switch (cmd) {
836 case TCGETS:
837 BT_DBG("TCGETS is not supported");
838 return -ENOIOCTLCMD;
839
840 case TCSETS:
841 BT_DBG("TCSETS is not supported");
842 return -ENOIOCTLCMD;
843
844 case TIOCMIWAIT:
845 BT_DBG("TIOCMIWAIT");
846 break;
847
Linus Torvalds1da177e2005-04-16 15:20:36 -0700848 case TIOCGSERIAL:
849 BT_ERR("TIOCGSERIAL is not supported");
850 return -ENOIOCTLCMD;
851
852 case TIOCSSERIAL:
853 BT_ERR("TIOCSSERIAL is not supported");
854 return -ENOIOCTLCMD;
855
856 case TIOCSERGSTRUCT:
857 BT_ERR("TIOCSERGSTRUCT is not supported");
858 return -ENOIOCTLCMD;
859
860 case TIOCSERGETLSR:
861 BT_ERR("TIOCSERGETLSR is not supported");
862 return -ENOIOCTLCMD;
863
864 case TIOCSERCONFIG:
865 BT_ERR("TIOCSERCONFIG is not supported");
866 return -ENOIOCTLCMD;
867
868 default:
869 return -ENOIOCTLCMD; /* ioctls which we must ignore */
870
871 }
872
873 return -ENOIOCTLCMD;
874}
875
Alan Cox606d0992006-12-08 02:38:45 -0800876static void rfcomm_tty_set_termios(struct tty_struct *tty, struct ktermios *old)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700877{
Alan Cox606d0992006-12-08 02:38:45 -0800878 struct ktermios *new = tty->termios;
J. Suter3a5e9032005-08-09 20:28:46 -0700879 int old_baud_rate = tty_termios_baud_rate(old);
880 int new_baud_rate = tty_termios_baud_rate(new);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700881
J. Suter3a5e9032005-08-09 20:28:46 -0700882 u8 baud, data_bits, stop_bits, parity, x_on, x_off;
883 u16 changes = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700884
J. Suter3a5e9032005-08-09 20:28:46 -0700885 struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data;
886
887 BT_DBG("tty %p termios %p", tty, old);
888
Marcel Holtmannff2d3672006-11-18 22:14:42 +0100889 if (!dev || !dev->dlc || !dev->dlc->session)
Marcel Holtmanncb19d9e2006-10-15 17:31:10 +0200890 return;
891
J. Suter3a5e9032005-08-09 20:28:46 -0700892 /* Handle turning off CRTSCTS */
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900893 if ((old->c_cflag & CRTSCTS) && !(new->c_cflag & CRTSCTS))
J. Suter3a5e9032005-08-09 20:28:46 -0700894 BT_DBG("Turning off CRTSCTS unsupported");
895
896 /* Parity on/off and when on, odd/even */
897 if (((old->c_cflag & PARENB) != (new->c_cflag & PARENB)) ||
Andrei Emeltchenko285b4e92010-12-01 16:58:23 +0200898 ((old->c_cflag & PARODD) != (new->c_cflag & PARODD))) {
J. Suter3a5e9032005-08-09 20:28:46 -0700899 changes |= RFCOMM_RPN_PM_PARITY;
900 BT_DBG("Parity change detected.");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700901 }
J. Suter3a5e9032005-08-09 20:28:46 -0700902
903 /* Mark and space parity are not supported! */
904 if (new->c_cflag & PARENB) {
905 if (new->c_cflag & PARODD) {
906 BT_DBG("Parity is ODD");
907 parity = RFCOMM_RPN_PARITY_ODD;
908 } else {
909 BT_DBG("Parity is EVEN");
910 parity = RFCOMM_RPN_PARITY_EVEN;
911 }
912 } else {
913 BT_DBG("Parity is OFF");
914 parity = RFCOMM_RPN_PARITY_NONE;
915 }
916
917 /* Setting the x_on / x_off characters */
918 if (old->c_cc[VSTOP] != new->c_cc[VSTOP]) {
919 BT_DBG("XOFF custom");
920 x_on = new->c_cc[VSTOP];
921 changes |= RFCOMM_RPN_PM_XON;
922 } else {
923 BT_DBG("XOFF default");
924 x_on = RFCOMM_RPN_XON_CHAR;
925 }
926
927 if (old->c_cc[VSTART] != new->c_cc[VSTART]) {
928 BT_DBG("XON custom");
929 x_off = new->c_cc[VSTART];
930 changes |= RFCOMM_RPN_PM_XOFF;
931 } else {
932 BT_DBG("XON default");
933 x_off = RFCOMM_RPN_XOFF_CHAR;
934 }
935
936 /* Handle setting of stop bits */
937 if ((old->c_cflag & CSTOPB) != (new->c_cflag & CSTOPB))
938 changes |= RFCOMM_RPN_PM_STOP;
939
940 /* POSIX does not support 1.5 stop bits and RFCOMM does not
941 * support 2 stop bits. So a request for 2 stop bits gets
942 * translated to 1.5 stop bits */
Andrei Emeltchenko285b4e92010-12-01 16:58:23 +0200943 if (new->c_cflag & CSTOPB)
J. Suter3a5e9032005-08-09 20:28:46 -0700944 stop_bits = RFCOMM_RPN_STOP_15;
Andrei Emeltchenko285b4e92010-12-01 16:58:23 +0200945 else
J. Suter3a5e9032005-08-09 20:28:46 -0700946 stop_bits = RFCOMM_RPN_STOP_1;
J. Suter3a5e9032005-08-09 20:28:46 -0700947
948 /* Handle number of data bits [5-8] */
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900949 if ((old->c_cflag & CSIZE) != (new->c_cflag & CSIZE))
J. Suter3a5e9032005-08-09 20:28:46 -0700950 changes |= RFCOMM_RPN_PM_DATA;
951
952 switch (new->c_cflag & CSIZE) {
953 case CS5:
954 data_bits = RFCOMM_RPN_DATA_5;
955 break;
956 case CS6:
957 data_bits = RFCOMM_RPN_DATA_6;
958 break;
959 case CS7:
960 data_bits = RFCOMM_RPN_DATA_7;
961 break;
962 case CS8:
963 data_bits = RFCOMM_RPN_DATA_8;
964 break;
965 default:
966 data_bits = RFCOMM_RPN_DATA_8;
967 break;
968 }
969
970 /* Handle baudrate settings */
971 if (old_baud_rate != new_baud_rate)
972 changes |= RFCOMM_RPN_PM_BITRATE;
973
974 switch (new_baud_rate) {
975 case 2400:
976 baud = RFCOMM_RPN_BR_2400;
977 break;
978 case 4800:
979 baud = RFCOMM_RPN_BR_4800;
980 break;
981 case 7200:
982 baud = RFCOMM_RPN_BR_7200;
983 break;
984 case 9600:
985 baud = RFCOMM_RPN_BR_9600;
986 break;
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900987 case 19200:
J. Suter3a5e9032005-08-09 20:28:46 -0700988 baud = RFCOMM_RPN_BR_19200;
989 break;
990 case 38400:
991 baud = RFCOMM_RPN_BR_38400;
992 break;
993 case 57600:
994 baud = RFCOMM_RPN_BR_57600;
995 break;
996 case 115200:
997 baud = RFCOMM_RPN_BR_115200;
998 break;
999 case 230400:
1000 baud = RFCOMM_RPN_BR_230400;
1001 break;
1002 default:
1003 /* 9600 is standard accordinag to the RFCOMM specification */
1004 baud = RFCOMM_RPN_BR_9600;
1005 break;
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09001006
J. Suter3a5e9032005-08-09 20:28:46 -07001007 }
1008
1009 if (changes)
1010 rfcomm_send_rpn(dev->dlc->session, 1, dev->dlc->dlci, baud,
1011 data_bits, stop_bits, parity,
1012 RFCOMM_RPN_FLOW_NONE, x_on, x_off, changes);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001013}
1014
1015static void rfcomm_tty_throttle(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_throttle(dev->dlc);
1022}
1023
1024static void rfcomm_tty_unthrottle(struct tty_struct *tty)
1025{
1026 struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data;
1027
1028 BT_DBG("tty %p dev %p", tty, dev);
J. Suter3a5e9032005-08-09 20:28:46 -07001029
Linus Torvalds1da177e2005-04-16 15:20:36 -07001030 rfcomm_dlc_unthrottle(dev->dlc);
1031}
1032
1033static int rfcomm_tty_chars_in_buffer(struct tty_struct *tty)
1034{
1035 struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001036
1037 BT_DBG("tty %p dev %p", tty, dev);
1038
Marcel Holtmannb6e557f2007-01-08 02:16:27 +01001039 if (!dev || !dev->dlc)
1040 return 0;
1041
1042 if (!skb_queue_empty(&dev->dlc->tx_queue))
1043 return dev->dlc->mtu;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001044
1045 return 0;
1046}
1047
1048static void rfcomm_tty_flush_buffer(struct tty_struct *tty)
1049{
1050 struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001051
1052 BT_DBG("tty %p dev %p", tty, dev);
1053
Marcel Holtmannb6e557f2007-01-08 02:16:27 +01001054 if (!dev || !dev->dlc)
1055 return;
1056
Linus Torvalds1da177e2005-04-16 15:20:36 -07001057 skb_queue_purge(&dev->dlc->tx_queue);
Alan Coxa352def2008-07-16 21:53:12 +01001058 tty_wakeup(tty);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001059}
1060
1061static void rfcomm_tty_send_xchar(struct tty_struct *tty, char ch)
1062{
1063 BT_DBG("tty %p ch %c", tty, ch);
1064}
1065
1066static void rfcomm_tty_wait_until_sent(struct tty_struct *tty, int timeout)
1067{
1068 BT_DBG("tty %p timeout %d", tty, timeout);
1069}
1070
1071static void rfcomm_tty_hangup(struct tty_struct *tty)
1072{
1073 struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001074
1075 BT_DBG("tty %p dev %p", tty, dev);
1076
Marcel Holtmannb6e557f2007-01-08 02:16:27 +01001077 if (!dev)
1078 return;
1079
Linus Torvalds1da177e2005-04-16 15:20:36 -07001080 rfcomm_tty_flush_buffer(tty);
1081
Marcel Holtmann77f2a452007-05-05 00:36:10 +02001082 if (test_bit(RFCOMM_RELEASE_ONHUP, &dev->flags)) {
1083 if (rfcomm_dev_get(dev->id) == NULL)
1084 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001085 rfcomm_dev_del(dev);
Marcel Holtmann77f2a452007-05-05 00:36:10 +02001086 rfcomm_dev_put(dev);
1087 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001088}
1089
Alan Cox60b33c12011-02-14 16:26:14 +00001090static int rfcomm_tty_tiocmget(struct tty_struct *tty)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001091{
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09001092 struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001093
1094 BT_DBG("tty %p dev %p", tty, dev);
1095
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09001096 return dev->modem_status;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001097}
1098
Alan Cox20b9d172011-02-14 16:26:50 +00001099static int rfcomm_tty_tiocmset(struct tty_struct *tty, unsigned int set, unsigned int clear)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001100{
J. Suter3a5e9032005-08-09 20:28:46 -07001101 struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data;
1102 struct rfcomm_dlc *dlc = dev->dlc;
1103 u8 v24_sig;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001104
1105 BT_DBG("tty %p dev %p set 0x%02x clear 0x%02x", tty, dev, set, clear);
1106
J. Suter3a5e9032005-08-09 20:28:46 -07001107 rfcomm_dlc_get_modem_status(dlc, &v24_sig);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001108
J. Suter3a5e9032005-08-09 20:28:46 -07001109 if (set & TIOCM_DSR || set & TIOCM_DTR)
1110 v24_sig |= RFCOMM_V24_RTC;
1111 if (set & TIOCM_RTS || set & TIOCM_CTS)
1112 v24_sig |= RFCOMM_V24_RTR;
1113 if (set & TIOCM_RI)
1114 v24_sig |= RFCOMM_V24_IC;
1115 if (set & TIOCM_CD)
1116 v24_sig |= RFCOMM_V24_DV;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001117
J. Suter3a5e9032005-08-09 20:28:46 -07001118 if (clear & TIOCM_DSR || clear & TIOCM_DTR)
1119 v24_sig &= ~RFCOMM_V24_RTC;
1120 if (clear & TIOCM_RTS || clear & TIOCM_CTS)
1121 v24_sig &= ~RFCOMM_V24_RTR;
1122 if (clear & TIOCM_RI)
1123 v24_sig &= ~RFCOMM_V24_IC;
1124 if (clear & TIOCM_CD)
1125 v24_sig &= ~RFCOMM_V24_DV;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001126
J. Suter3a5e9032005-08-09 20:28:46 -07001127 rfcomm_dlc_set_modem_status(dlc, v24_sig);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001128
J. Suter3a5e9032005-08-09 20:28:46 -07001129 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001130}
1131
1132/* ---- TTY structure ---- */
1133
Jeff Dikeb68e31d2006-10-02 02:17:18 -07001134static const struct tty_operations rfcomm_ops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001135 .open = rfcomm_tty_open,
1136 .close = rfcomm_tty_close,
1137 .write = rfcomm_tty_write,
1138 .write_room = rfcomm_tty_write_room,
1139 .chars_in_buffer = rfcomm_tty_chars_in_buffer,
1140 .flush_buffer = rfcomm_tty_flush_buffer,
1141 .ioctl = rfcomm_tty_ioctl,
1142 .throttle = rfcomm_tty_throttle,
1143 .unthrottle = rfcomm_tty_unthrottle,
1144 .set_termios = rfcomm_tty_set_termios,
1145 .send_xchar = rfcomm_tty_send_xchar,
1146 .hangup = rfcomm_tty_hangup,
1147 .wait_until_sent = rfcomm_tty_wait_until_sent,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001148 .tiocmget = rfcomm_tty_tiocmget,
1149 .tiocmset = rfcomm_tty_tiocmset,
1150};
1151
Gustavo F. Padovan2f8362a2010-07-24 02:04:45 -03001152int __init rfcomm_init_ttys(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001153{
David Herrmann5ada9912011-10-24 15:30:57 +02001154 int error;
1155
Linus Torvalds1da177e2005-04-16 15:20:36 -07001156 rfcomm_tty_driver = alloc_tty_driver(RFCOMM_TTY_PORTS);
1157 if (!rfcomm_tty_driver)
David Herrmann5ada9912011-10-24 15:30:57 +02001158 return -ENOMEM;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001159
Linus Torvalds1da177e2005-04-16 15:20:36 -07001160 rfcomm_tty_driver->driver_name = "rfcomm";
Linus Torvalds1da177e2005-04-16 15:20:36 -07001161 rfcomm_tty_driver->name = "rfcomm";
1162 rfcomm_tty_driver->major = RFCOMM_TTY_MAJOR;
1163 rfcomm_tty_driver->minor_start = RFCOMM_TTY_MINOR;
1164 rfcomm_tty_driver->type = TTY_DRIVER_TYPE_SERIAL;
1165 rfcomm_tty_driver->subtype = SERIAL_TYPE_NORMAL;
Greg Kroah-Hartman331b8312005-06-20 21:15:16 -07001166 rfcomm_tty_driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001167 rfcomm_tty_driver->init_termios = tty_std_termios;
1168 rfcomm_tty_driver->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL;
Marcel Holtmannca37bdd2008-07-14 20:13:52 +02001169 rfcomm_tty_driver->init_termios.c_lflag &= ~ICANON;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001170 tty_set_operations(rfcomm_tty_driver, &rfcomm_ops);
1171
David Herrmann5ada9912011-10-24 15:30:57 +02001172 error = tty_register_driver(rfcomm_tty_driver);
1173 if (error) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001174 BT_ERR("Can't register RFCOMM TTY driver");
1175 put_tty_driver(rfcomm_tty_driver);
David Herrmann5ada9912011-10-24 15:30:57 +02001176 return error;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001177 }
1178
1179 BT_INFO("RFCOMM TTY layer initialized");
1180
1181 return 0;
1182}
1183
Gustavo F. Padovan28e95092010-07-31 19:57:05 -03001184void rfcomm_cleanup_ttys(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001185{
1186 tty_unregister_driver(rfcomm_tty_driver);
1187 put_tty_driver(rfcomm_tty_driver);
1188}