blob: 1e4100bb0b65cc27414bc312ad9ec3ef52c6391f [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>
37
38#include <net/bluetooth/bluetooth.h>
Marcel Holtmann0a85b962006-07-06 13:09:02 +020039#include <net/bluetooth/hci_core.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070040#include <net/bluetooth/rfcomm.h>
41
Linus Torvalds1da177e2005-04-16 15:20:36 -070042#define RFCOMM_TTY_MAGIC 0x6d02 /* magic number for rfcomm struct */
43#define RFCOMM_TTY_PORTS RFCOMM_MAX_DEV /* whole lotta rfcomm devices */
44#define RFCOMM_TTY_MAJOR 216 /* device node major id of the usb/bluetooth.c driver */
45#define RFCOMM_TTY_MINOR 0
46
47static struct tty_driver *rfcomm_tty_driver;
48
49struct rfcomm_dev {
50 struct list_head list;
51 atomic_t refcnt;
52
53 char name[12];
54 int id;
55 unsigned long flags;
56 int opened;
57 int err;
58
59 bdaddr_t src;
60 bdaddr_t dst;
61 u8 channel;
62
63 uint modem_status;
64
65 struct rfcomm_dlc *dlc;
66 struct tty_struct *tty;
67 wait_queue_head_t wait;
68 struct tasklet_struct wakeup_task;
69
Marcel Holtmannc1a33132007-02-17 23:58:57 +010070 struct device *tty_dev;
71
Linus Torvalds1da177e2005-04-16 15:20:36 -070072 atomic_t wmem_alloc;
Marcel Holtmanna0c22f22008-07-14 20:13:52 +020073
74 struct sk_buff_head pending;
Linus Torvalds1da177e2005-04-16 15:20:36 -070075};
76
77static LIST_HEAD(rfcomm_dev_list);
78static DEFINE_RWLOCK(rfcomm_dev_lock);
79
80static void rfcomm_dev_data_ready(struct rfcomm_dlc *dlc, struct sk_buff *skb);
81static void rfcomm_dev_state_change(struct rfcomm_dlc *dlc, int err);
82static void rfcomm_dev_modem_status(struct rfcomm_dlc *dlc, u8 v24_sig);
83
84static void rfcomm_tty_wakeup(unsigned long arg);
85
86/* ---- Device functions ---- */
87static void rfcomm_dev_destruct(struct rfcomm_dev *dev)
88{
89 struct rfcomm_dlc *dlc = dev->dlc;
90
91 BT_DBG("dev %p dlc %p", dev, dlc);
92
Dave Youngf9513752008-01-10 22:22:52 -080093 /* Refcount should only hit zero when called from rfcomm_dev_del()
94 which will have taken us off the list. Everything else are
95 refcounting bugs. */
96 BUG_ON(!list_empty(&dev->list));
Ville Tervo8de0a152007-07-11 09:23:41 +020097
Linus Torvalds1da177e2005-04-16 15:20:36 -070098 rfcomm_dlc_lock(dlc);
99 /* Detach DLC if it's owned by this dev */
100 if (dlc->owner == dev)
101 dlc->owner = NULL;
102 rfcomm_dlc_unlock(dlc);
103
104 rfcomm_dlc_put(dlc);
105
106 tty_unregister_device(rfcomm_tty_driver, dev->id);
107
Linus Torvalds1da177e2005-04-16 15:20:36 -0700108 kfree(dev);
109
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900110 /* It's safe to call module_put() here because socket still
Linus Torvalds1da177e2005-04-16 15:20:36 -0700111 holds reference to this module. */
112 module_put(THIS_MODULE);
113}
114
115static inline void rfcomm_dev_hold(struct rfcomm_dev *dev)
116{
117 atomic_inc(&dev->refcnt);
118}
119
120static inline void rfcomm_dev_put(struct rfcomm_dev *dev)
121{
122 /* The reason this isn't actually a race, as you no
123 doubt have a little voice screaming at you in your
124 head, is that the refcount should never actually
125 reach zero unless the device has already been taken
126 off the list, in rfcomm_dev_del(). And if that's not
127 true, we'll hit the BUG() in rfcomm_dev_destruct()
128 anyway. */
129 if (atomic_dec_and_test(&dev->refcnt))
130 rfcomm_dev_destruct(dev);
131}
132
133static struct rfcomm_dev *__rfcomm_dev_get(int id)
134{
135 struct rfcomm_dev *dev;
136 struct list_head *p;
137
138 list_for_each(p, &rfcomm_dev_list) {
139 dev = list_entry(p, struct rfcomm_dev, list);
140 if (dev->id == id)
141 return dev;
142 }
143
144 return NULL;
145}
146
147static inline struct rfcomm_dev *rfcomm_dev_get(int id)
148{
149 struct rfcomm_dev *dev;
150
151 read_lock(&rfcomm_dev_lock);
152
153 dev = __rfcomm_dev_get(id);
Ville Tervo8de0a152007-07-11 09:23:41 +0200154
155 if (dev) {
156 if (test_bit(RFCOMM_TTY_RELEASED, &dev->flags))
157 dev = NULL;
158 else
159 rfcomm_dev_hold(dev);
160 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700161
162 read_unlock(&rfcomm_dev_lock);
163
164 return dev;
165}
166
Marcel Holtmann0a85b962006-07-06 13:09:02 +0200167static struct device *rfcomm_get_device(struct rfcomm_dev *dev)
168{
169 struct hci_dev *hdev;
170 struct hci_conn *conn;
171
172 hdev = hci_get_route(&dev->dst, &dev->src);
173 if (!hdev)
174 return NULL;
175
176 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &dev->dst);
Marcel Holtmann0a85b962006-07-06 13:09:02 +0200177
178 hci_dev_put(hdev);
179
Marcel Holtmannb2cfcd72006-10-15 17:31:05 +0200180 return conn ? &conn->dev : NULL;
Marcel Holtmann0a85b962006-07-06 13:09:02 +0200181}
182
Marcel Holtmanndae6a0f2007-10-20 14:52:38 +0200183static ssize_t show_address(struct device *tty_dev, struct device_attribute *attr, char *buf)
184{
185 struct rfcomm_dev *dev = dev_get_drvdata(tty_dev);
186 bdaddr_t bdaddr;
187 baswap(&bdaddr, &dev->dst);
188 return sprintf(buf, "%s\n", batostr(&bdaddr));
189}
190
191static ssize_t show_channel(struct device *tty_dev, struct device_attribute *attr, char *buf)
192{
193 struct rfcomm_dev *dev = dev_get_drvdata(tty_dev);
194 return sprintf(buf, "%d\n", dev->channel);
195}
196
197static DEVICE_ATTR(address, S_IRUGO, show_address, NULL);
198static DEVICE_ATTR(channel, S_IRUGO, show_channel, NULL);
199
Linus Torvalds1da177e2005-04-16 15:20:36 -0700200static int rfcomm_dev_add(struct rfcomm_dev_req *req, struct rfcomm_dlc *dlc)
201{
202 struct rfcomm_dev *dev;
203 struct list_head *head = &rfcomm_dev_list, *p;
204 int err = 0;
205
206 BT_DBG("id %d channel %d", req->dev_id, req->channel);
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900207
Marcel Holtmann25ea6db2006-07-06 15:40:09 +0200208 dev = kzalloc(sizeof(struct rfcomm_dev), GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700209 if (!dev)
210 return -ENOMEM;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700211
212 write_lock_bh(&rfcomm_dev_lock);
213
214 if (req->dev_id < 0) {
215 dev->id = 0;
216
217 list_for_each(p, &rfcomm_dev_list) {
218 if (list_entry(p, struct rfcomm_dev, list)->id != dev->id)
219 break;
220
221 dev->id++;
222 head = p;
223 }
224 } else {
225 dev->id = req->dev_id;
226
227 list_for_each(p, &rfcomm_dev_list) {
228 struct rfcomm_dev *entry = list_entry(p, struct rfcomm_dev, list);
229
230 if (entry->id == dev->id) {
231 err = -EADDRINUSE;
232 goto out;
233 }
234
235 if (entry->id > dev->id - 1)
236 break;
237
238 head = p;
239 }
240 }
241
242 if ((dev->id < 0) || (dev->id > RFCOMM_MAX_DEV - 1)) {
243 err = -ENFILE;
244 goto out;
245 }
246
247 sprintf(dev->name, "rfcomm%d", dev->id);
248
249 list_add(&dev->list, head);
250 atomic_set(&dev->refcnt, 1);
251
252 bacpy(&dev->src, &req->src);
253 bacpy(&dev->dst, &req->dst);
254 dev->channel = req->channel;
255
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900256 dev->flags = req->flags &
Linus Torvalds1da177e2005-04-16 15:20:36 -0700257 ((1 << RFCOMM_RELEASE_ONHUP) | (1 << RFCOMM_REUSE_DLC));
258
259 init_waitqueue_head(&dev->wait);
260 tasklet_init(&dev->wakeup_task, rfcomm_tty_wakeup, (unsigned long) dev);
261
Marcel Holtmanna0c22f22008-07-14 20:13:52 +0200262 skb_queue_head_init(&dev->pending);
263
Linus Torvalds1da177e2005-04-16 15:20:36 -0700264 rfcomm_dlc_lock(dlc);
Marcel Holtmanna0c22f22008-07-14 20:13:52 +0200265
266 if (req->flags & (1 << RFCOMM_REUSE_DLC)) {
267 struct sock *sk = dlc->owner;
268 struct sk_buff *skb;
269
270 BUG_ON(!sk);
271
272 rfcomm_dlc_throttle(dlc);
273
274 while ((skb = skb_dequeue(&sk->sk_receive_queue))) {
275 skb_orphan(skb);
276 skb_queue_tail(&dev->pending, skb);
277 atomic_sub(skb->len, &sk->sk_rmem_alloc);
278 }
279 }
280
Linus Torvalds1da177e2005-04-16 15:20:36 -0700281 dlc->data_ready = rfcomm_dev_data_ready;
282 dlc->state_change = rfcomm_dev_state_change;
283 dlc->modem_status = rfcomm_dev_modem_status;
284
285 dlc->owner = dev;
286 dev->dlc = dlc;
Marcel Holtmann8b6b3da2008-07-14 20:13:52 +0200287
288 rfcomm_dev_modem_status(dlc, dlc->remote_v24_sig);
289
Linus Torvalds1da177e2005-04-16 15:20:36 -0700290 rfcomm_dlc_unlock(dlc);
291
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900292 /* It's safe to call __module_get() here because socket already
Linus Torvalds1da177e2005-04-16 15:20:36 -0700293 holds reference to this module. */
294 __module_get(THIS_MODULE);
295
296out:
297 write_unlock_bh(&rfcomm_dev_lock);
298
Marcel Holtmann09c7d822007-07-26 00:12:25 -0700299 if (err < 0) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700300 kfree(dev);
301 return err;
302 }
303
Marcel Holtmannc1a33132007-02-17 23:58:57 +0100304 dev->tty_dev = tty_register_device(rfcomm_tty_driver, dev->id, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700305
Ville Tervo8de0a152007-07-11 09:23:41 +0200306 if (IS_ERR(dev->tty_dev)) {
Marcel Holtmann09c7d822007-07-26 00:12:25 -0700307 err = PTR_ERR(dev->tty_dev);
Ville Tervo8de0a152007-07-11 09:23:41 +0200308 list_del(&dev->list);
309 kfree(dev);
Marcel Holtmann09c7d822007-07-26 00:12:25 -0700310 return err;
Ville Tervo8de0a152007-07-11 09:23:41 +0200311 }
312
Marcel Holtmanndae6a0f2007-10-20 14:52:38 +0200313 dev_set_drvdata(dev->tty_dev, dev);
314
315 if (device_create_file(dev->tty_dev, &dev_attr_address) < 0)
316 BT_ERR("Failed to create address attribute");
317
318 if (device_create_file(dev->tty_dev, &dev_attr_channel) < 0)
319 BT_ERR("Failed to create channel attribute");
320
Linus Torvalds1da177e2005-04-16 15:20:36 -0700321 return dev->id;
322}
323
324static void rfcomm_dev_del(struct rfcomm_dev *dev)
325{
326 BT_DBG("dev %p", dev);
327
Dave Youngf9513752008-01-10 22:22:52 -0800328 if (test_bit(RFCOMM_TTY_RELEASED, &dev->flags))
329 BUG_ON(1);
330 else
331 set_bit(RFCOMM_TTY_RELEASED, &dev->flags);
332
333 write_lock_bh(&rfcomm_dev_lock);
334 list_del_init(&dev->list);
335 write_unlock_bh(&rfcomm_dev_lock);
336
Linus Torvalds1da177e2005-04-16 15:20:36 -0700337 rfcomm_dev_put(dev);
338}
339
340/* ---- Send buffer ---- */
341static inline unsigned int rfcomm_room(struct rfcomm_dlc *dlc)
342{
343 /* We can't let it be zero, because we don't get a callback
344 when tx_credits becomes nonzero, hence we'd never wake up */
345 return dlc->mtu * (dlc->tx_credits?:1);
346}
347
348static void rfcomm_wfree(struct sk_buff *skb)
349{
350 struct rfcomm_dev *dev = (void *) skb->sk;
351 atomic_sub(skb->truesize, &dev->wmem_alloc);
352 if (test_bit(RFCOMM_TTY_ATTACHED, &dev->flags))
353 tasklet_schedule(&dev->wakeup_task);
354 rfcomm_dev_put(dev);
355}
356
357static inline void rfcomm_set_owner_w(struct sk_buff *skb, struct rfcomm_dev *dev)
358{
359 rfcomm_dev_hold(dev);
360 atomic_add(skb->truesize, &dev->wmem_alloc);
361 skb->sk = (void *) dev;
362 skb->destructor = rfcomm_wfree;
363}
364
Al Virodd0fc662005-10-07 07:46:04 +0100365static struct sk_buff *rfcomm_wmalloc(struct rfcomm_dev *dev, unsigned long size, gfp_t priority)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700366{
367 if (atomic_read(&dev->wmem_alloc) < rfcomm_room(dev->dlc)) {
368 struct sk_buff *skb = alloc_skb(size, priority);
369 if (skb) {
370 rfcomm_set_owner_w(skb, dev);
371 return skb;
372 }
373 }
374 return NULL;
375}
376
377/* ---- Device IOCTLs ---- */
378
379#define NOCAP_FLAGS ((1 << RFCOMM_REUSE_DLC) | (1 << RFCOMM_RELEASE_ONHUP))
380
381static int rfcomm_create_dev(struct sock *sk, void __user *arg)
382{
383 struct rfcomm_dev_req req;
384 struct rfcomm_dlc *dlc;
385 int id;
386
387 if (copy_from_user(&req, arg, sizeof(req)))
388 return -EFAULT;
389
Ville Tervo8de0a152007-07-11 09:23:41 +0200390 BT_DBG("sk %p dev_id %d flags 0x%x", sk, req.dev_id, req.flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700391
392 if (req.flags != NOCAP_FLAGS && !capable(CAP_NET_ADMIN))
393 return -EPERM;
394
395 if (req.flags & (1 << RFCOMM_REUSE_DLC)) {
396 /* Socket must be connected */
397 if (sk->sk_state != BT_CONNECTED)
398 return -EBADFD;
399
400 dlc = rfcomm_pi(sk)->dlc;
401 rfcomm_dlc_hold(dlc);
402 } else {
403 dlc = rfcomm_dlc_alloc(GFP_KERNEL);
404 if (!dlc)
405 return -ENOMEM;
406 }
407
408 id = rfcomm_dev_add(&req, dlc);
409 if (id < 0) {
410 rfcomm_dlc_put(dlc);
411 return id;
412 }
413
414 if (req.flags & (1 << RFCOMM_REUSE_DLC)) {
415 /* DLC is now used by device.
416 * Socket must be disconnected */
417 sk->sk_state = BT_CLOSED;
418 }
419
420 return id;
421}
422
423static int rfcomm_release_dev(void __user *arg)
424{
425 struct rfcomm_dev_req req;
426 struct rfcomm_dev *dev;
427
428 if (copy_from_user(&req, arg, sizeof(req)))
429 return -EFAULT;
430
Ville Tervo8de0a152007-07-11 09:23:41 +0200431 BT_DBG("dev_id %d flags 0x%x", req.dev_id, req.flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700432
433 if (!(dev = rfcomm_dev_get(req.dev_id)))
434 return -ENODEV;
435
436 if (dev->flags != NOCAP_FLAGS && !capable(CAP_NET_ADMIN)) {
437 rfcomm_dev_put(dev);
438 return -EPERM;
439 }
440
441 if (req.flags & (1 << RFCOMM_HANGUP_NOW))
442 rfcomm_dlc_close(dev->dlc, 0);
443
Mikko Rapeli84950cf2007-07-11 09:18:15 +0200444 /* Shut down TTY synchronously before freeing rfcomm_dev */
445 if (dev->tty)
446 tty_vhangup(dev->tty);
447
Dave Young93d80742008-02-05 03:12:06 -0800448 if (!test_bit(RFCOMM_RELEASE_ONHUP, &dev->flags))
449 rfcomm_dev_del(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700450 rfcomm_dev_put(dev);
451 return 0;
452}
453
454static int rfcomm_get_dev_list(void __user *arg)
455{
456 struct rfcomm_dev_list_req *dl;
457 struct rfcomm_dev_info *di;
458 struct list_head *p;
459 int n = 0, size, err;
460 u16 dev_num;
461
462 BT_DBG("");
463
464 if (get_user(dev_num, (u16 __user *) arg))
465 return -EFAULT;
466
467 if (!dev_num || dev_num > (PAGE_SIZE * 4) / sizeof(*di))
468 return -EINVAL;
469
470 size = sizeof(*dl) + dev_num * sizeof(*di);
471
472 if (!(dl = kmalloc(size, GFP_KERNEL)))
473 return -ENOMEM;
474
475 di = dl->dev_info;
476
477 read_lock_bh(&rfcomm_dev_lock);
478
479 list_for_each(p, &rfcomm_dev_list) {
480 struct rfcomm_dev *dev = list_entry(p, struct rfcomm_dev, list);
Ville Tervo8de0a152007-07-11 09:23:41 +0200481 if (test_bit(RFCOMM_TTY_RELEASED, &dev->flags))
482 continue;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700483 (di + n)->id = dev->id;
484 (di + n)->flags = dev->flags;
485 (di + n)->state = dev->dlc->state;
486 (di + n)->channel = dev->channel;
487 bacpy(&(di + n)->src, &dev->src);
488 bacpy(&(di + n)->dst, &dev->dst);
489 if (++n >= dev_num)
490 break;
491 }
492
493 read_unlock_bh(&rfcomm_dev_lock);
494
495 dl->dev_num = n;
496 size = sizeof(*dl) + n * sizeof(*di);
497
498 err = copy_to_user(arg, dl, size);
499 kfree(dl);
500
501 return err ? -EFAULT : 0;
502}
503
504static int rfcomm_get_dev_info(void __user *arg)
505{
506 struct rfcomm_dev *dev;
507 struct rfcomm_dev_info di;
508 int err = 0;
509
510 BT_DBG("");
511
512 if (copy_from_user(&di, arg, sizeof(di)))
513 return -EFAULT;
514
515 if (!(dev = rfcomm_dev_get(di.id)))
516 return -ENODEV;
517
518 di.flags = dev->flags;
519 di.channel = dev->channel;
520 di.state = dev->dlc->state;
521 bacpy(&di.src, &dev->src);
522 bacpy(&di.dst, &dev->dst);
523
524 if (copy_to_user(arg, &di, sizeof(di)))
525 err = -EFAULT;
526
527 rfcomm_dev_put(dev);
528 return err;
529}
530
531int rfcomm_dev_ioctl(struct sock *sk, unsigned int cmd, void __user *arg)
532{
533 BT_DBG("cmd %d arg %p", cmd, arg);
534
535 switch (cmd) {
536 case RFCOMMCREATEDEV:
537 return rfcomm_create_dev(sk, arg);
538
539 case RFCOMMRELEASEDEV:
540 return rfcomm_release_dev(arg);
541
542 case RFCOMMGETDEVLIST:
543 return rfcomm_get_dev_list(arg);
544
545 case RFCOMMGETDEVINFO:
546 return rfcomm_get_dev_info(arg);
547 }
548
549 return -EINVAL;
550}
551
552/* ---- DLC callbacks ---- */
553static void rfcomm_dev_data_ready(struct rfcomm_dlc *dlc, struct sk_buff *skb)
554{
555 struct rfcomm_dev *dev = dlc->owner;
556 struct tty_struct *tty;
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900557
Marcel Holtmanna0c22f22008-07-14 20:13:52 +0200558 if (!dev) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700559 kfree_skb(skb);
560 return;
561 }
562
Marcel Holtmanna0c22f22008-07-14 20:13:52 +0200563 if (!(tty = dev->tty) || !skb_queue_empty(&dev->pending)) {
564 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 ---- */
633static void rfcomm_tty_wakeup(unsigned long arg)
634{
635 struct rfcomm_dev *dev = (void *) arg;
636 struct tty_struct *tty = dev->tty;
637 if (!tty)
638 return;
639
640 BT_DBG("dev %p tty %p", dev, tty);
Alan Coxa352def2008-07-16 21:53:12 +0100641 tty_wakeup(tty);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700642}
643
Marcel Holtmanna0c22f22008-07-14 20:13:52 +0200644static void rfcomm_tty_copy_pending(struct rfcomm_dev *dev)
645{
646 struct tty_struct *tty = dev->tty;
647 struct sk_buff *skb;
648 int inserted = 0;
649
650 if (!tty)
651 return;
652
653 BT_DBG("dev %p tty %p", dev, tty);
654
655 rfcomm_dlc_lock(dev->dlc);
656
657 while ((skb = skb_dequeue(&dev->pending))) {
658 inserted += tty_insert_flip_string(tty, skb->data, skb->len);
659 kfree_skb(skb);
660 }
661
662 rfcomm_dlc_unlock(dev->dlc);
663
664 if (inserted > 0)
665 tty_flip_buffer_push(tty);
666}
667
Linus Torvalds1da177e2005-04-16 15:20:36 -0700668static int rfcomm_tty_open(struct tty_struct *tty, struct file *filp)
669{
670 DECLARE_WAITQUEUE(wait, current);
671 struct rfcomm_dev *dev;
672 struct rfcomm_dlc *dlc;
673 int err, id;
674
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900675 id = tty->index;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700676
677 BT_DBG("tty %p id %d", tty, id);
678
679 /* We don't leak this refcount. For reasons which are not entirely
680 clear, the TTY layer will call our ->close() method even if the
681 open fails. We decrease the refcount there, and decreasing it
682 here too would cause breakage. */
683 dev = rfcomm_dev_get(id);
684 if (!dev)
685 return -ENODEV;
686
687 BT_DBG("dev %p dst %s channel %d opened %d", dev, batostr(&dev->dst), dev->channel, dev->opened);
688
689 if (dev->opened++ != 0)
690 return 0;
691
692 dlc = dev->dlc;
693
694 /* Attach TTY and open DLC */
695
696 rfcomm_dlc_lock(dlc);
697 tty->driver_data = dev;
698 dev->tty = tty;
699 rfcomm_dlc_unlock(dlc);
700 set_bit(RFCOMM_TTY_ATTACHED, &dev->flags);
701
702 err = rfcomm_dlc_open(dlc, &dev->src, &dev->dst, dev->channel);
703 if (err < 0)
704 return err;
705
706 /* Wait for DLC to connect */
707 add_wait_queue(&dev->wait, &wait);
708 while (1) {
709 set_current_state(TASK_INTERRUPTIBLE);
710
711 if (dlc->state == BT_CLOSED) {
712 err = -dev->err;
713 break;
714 }
715
716 if (dlc->state == BT_CONNECTED)
717 break;
718
719 if (signal_pending(current)) {
720 err = -EINTR;
721 break;
722 }
723
724 schedule();
725 }
726 set_current_state(TASK_RUNNING);
727 remove_wait_queue(&dev->wait, &wait);
728
Marcel Holtmannc1a33132007-02-17 23:58:57 +0100729 if (err == 0)
730 device_move(dev->tty_dev, rfcomm_get_device(dev));
731
Marcel Holtmanna0c22f22008-07-14 20:13:52 +0200732 rfcomm_tty_copy_pending(dev);
733
734 rfcomm_dlc_unthrottle(dev->dlc);
735
Linus Torvalds1da177e2005-04-16 15:20:36 -0700736 return err;
737}
738
739static void rfcomm_tty_close(struct tty_struct *tty, struct file *filp)
740{
741 struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data;
742 if (!dev)
743 return;
744
745 BT_DBG("tty %p dev %p dlc %p opened %d", tty, dev, dev->dlc, dev->opened);
746
747 if (--dev->opened == 0) {
Dave Youngacea6852008-01-21 22:35:21 -0800748 if (dev->tty_dev->parent)
749 device_move(dev->tty_dev, NULL);
Marcel Holtmannc1a33132007-02-17 23:58:57 +0100750
Linus Torvalds1da177e2005-04-16 15:20:36 -0700751 /* Close DLC and dettach TTY */
752 rfcomm_dlc_close(dev->dlc, 0);
753
754 clear_bit(RFCOMM_TTY_ATTACHED, &dev->flags);
755 tasklet_kill(&dev->wakeup_task);
756
757 rfcomm_dlc_lock(dev->dlc);
758 tty->driver_data = NULL;
759 dev->tty = NULL;
760 rfcomm_dlc_unlock(dev->dlc);
761 }
762
763 rfcomm_dev_put(dev);
764}
765
766static int rfcomm_tty_write(struct tty_struct *tty, const unsigned char *buf, int count)
767{
768 struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data;
769 struct rfcomm_dlc *dlc = dev->dlc;
770 struct sk_buff *skb;
771 int err = 0, sent = 0, size;
772
773 BT_DBG("tty %p count %d", tty, count);
774
775 while (count) {
776 size = min_t(uint, count, dlc->mtu);
777
778 skb = rfcomm_wmalloc(dev, size + RFCOMM_SKB_RESERVE, GFP_ATOMIC);
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900779
Linus Torvalds1da177e2005-04-16 15:20:36 -0700780 if (!skb)
781 break;
782
783 skb_reserve(skb, RFCOMM_SKB_HEAD_RESERVE);
784
785 memcpy(skb_put(skb, size), buf + sent, size);
786
787 if ((err = rfcomm_dlc_send(dlc, skb)) < 0) {
788 kfree_skb(skb);
789 break;
790 }
791
792 sent += size;
793 count -= size;
794 }
795
796 return sent ? sent : err;
797}
798
799static int rfcomm_tty_write_room(struct tty_struct *tty)
800{
801 struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data;
802 int room;
803
804 BT_DBG("tty %p", tty);
805
Marcel Holtmannb6e557f2007-01-08 02:16:27 +0100806 if (!dev || !dev->dlc)
807 return 0;
808
Linus Torvalds1da177e2005-04-16 15:20:36 -0700809 room = rfcomm_room(dev->dlc) - atomic_read(&dev->wmem_alloc);
810 if (room < 0)
811 room = 0;
Marcel Holtmannb6e557f2007-01-08 02:16:27 +0100812
Linus Torvalds1da177e2005-04-16 15:20:36 -0700813 return room;
814}
815
816static int rfcomm_tty_ioctl(struct tty_struct *tty, struct file *filp, unsigned int cmd, unsigned long arg)
817{
818 BT_DBG("tty %p cmd 0x%02x", tty, cmd);
819
820 switch (cmd) {
821 case TCGETS:
822 BT_DBG("TCGETS is not supported");
823 return -ENOIOCTLCMD;
824
825 case TCSETS:
826 BT_DBG("TCSETS is not supported");
827 return -ENOIOCTLCMD;
828
829 case TIOCMIWAIT:
830 BT_DBG("TIOCMIWAIT");
831 break;
832
833 case TIOCGICOUNT:
834 BT_DBG("TIOCGICOUNT");
835 break;
836
837 case TIOCGSERIAL:
838 BT_ERR("TIOCGSERIAL is not supported");
839 return -ENOIOCTLCMD;
840
841 case TIOCSSERIAL:
842 BT_ERR("TIOCSSERIAL is not supported");
843 return -ENOIOCTLCMD;
844
845 case TIOCSERGSTRUCT:
846 BT_ERR("TIOCSERGSTRUCT is not supported");
847 return -ENOIOCTLCMD;
848
849 case TIOCSERGETLSR:
850 BT_ERR("TIOCSERGETLSR is not supported");
851 return -ENOIOCTLCMD;
852
853 case TIOCSERCONFIG:
854 BT_ERR("TIOCSERCONFIG is not supported");
855 return -ENOIOCTLCMD;
856
857 default:
858 return -ENOIOCTLCMD; /* ioctls which we must ignore */
859
860 }
861
862 return -ENOIOCTLCMD;
863}
864
Alan Cox606d0992006-12-08 02:38:45 -0800865static void rfcomm_tty_set_termios(struct tty_struct *tty, struct ktermios *old)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700866{
Alan Cox606d0992006-12-08 02:38:45 -0800867 struct ktermios *new = tty->termios;
J. Suter3a5e9032005-08-09 20:28:46 -0700868 int old_baud_rate = tty_termios_baud_rate(old);
869 int new_baud_rate = tty_termios_baud_rate(new);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700870
J. Suter3a5e9032005-08-09 20:28:46 -0700871 u8 baud, data_bits, stop_bits, parity, x_on, x_off;
872 u16 changes = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700873
J. Suter3a5e9032005-08-09 20:28:46 -0700874 struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data;
875
876 BT_DBG("tty %p termios %p", tty, old);
877
Marcel Holtmannff2d3672006-11-18 22:14:42 +0100878 if (!dev || !dev->dlc || !dev->dlc->session)
Marcel Holtmanncb19d9e2006-10-15 17:31:10 +0200879 return;
880
J. Suter3a5e9032005-08-09 20:28:46 -0700881 /* Handle turning off CRTSCTS */
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900882 if ((old->c_cflag & CRTSCTS) && !(new->c_cflag & CRTSCTS))
J. Suter3a5e9032005-08-09 20:28:46 -0700883 BT_DBG("Turning off CRTSCTS unsupported");
884
885 /* Parity on/off and when on, odd/even */
886 if (((old->c_cflag & PARENB) != (new->c_cflag & PARENB)) ||
887 ((old->c_cflag & PARODD) != (new->c_cflag & PARODD)) ) {
888 changes |= RFCOMM_RPN_PM_PARITY;
889 BT_DBG("Parity change detected.");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700890 }
J. Suter3a5e9032005-08-09 20:28:46 -0700891
892 /* Mark and space parity are not supported! */
893 if (new->c_cflag & PARENB) {
894 if (new->c_cflag & PARODD) {
895 BT_DBG("Parity is ODD");
896 parity = RFCOMM_RPN_PARITY_ODD;
897 } else {
898 BT_DBG("Parity is EVEN");
899 parity = RFCOMM_RPN_PARITY_EVEN;
900 }
901 } else {
902 BT_DBG("Parity is OFF");
903 parity = RFCOMM_RPN_PARITY_NONE;
904 }
905
906 /* Setting the x_on / x_off characters */
907 if (old->c_cc[VSTOP] != new->c_cc[VSTOP]) {
908 BT_DBG("XOFF custom");
909 x_on = new->c_cc[VSTOP];
910 changes |= RFCOMM_RPN_PM_XON;
911 } else {
912 BT_DBG("XOFF default");
913 x_on = RFCOMM_RPN_XON_CHAR;
914 }
915
916 if (old->c_cc[VSTART] != new->c_cc[VSTART]) {
917 BT_DBG("XON custom");
918 x_off = new->c_cc[VSTART];
919 changes |= RFCOMM_RPN_PM_XOFF;
920 } else {
921 BT_DBG("XON default");
922 x_off = RFCOMM_RPN_XOFF_CHAR;
923 }
924
925 /* Handle setting of stop bits */
926 if ((old->c_cflag & CSTOPB) != (new->c_cflag & CSTOPB))
927 changes |= RFCOMM_RPN_PM_STOP;
928
929 /* POSIX does not support 1.5 stop bits and RFCOMM does not
930 * support 2 stop bits. So a request for 2 stop bits gets
931 * translated to 1.5 stop bits */
932 if (new->c_cflag & CSTOPB) {
933 stop_bits = RFCOMM_RPN_STOP_15;
934 } else {
935 stop_bits = RFCOMM_RPN_STOP_1;
936 }
937
938 /* Handle number of data bits [5-8] */
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900939 if ((old->c_cflag & CSIZE) != (new->c_cflag & CSIZE))
J. Suter3a5e9032005-08-09 20:28:46 -0700940 changes |= RFCOMM_RPN_PM_DATA;
941
942 switch (new->c_cflag & CSIZE) {
943 case CS5:
944 data_bits = RFCOMM_RPN_DATA_5;
945 break;
946 case CS6:
947 data_bits = RFCOMM_RPN_DATA_6;
948 break;
949 case CS7:
950 data_bits = RFCOMM_RPN_DATA_7;
951 break;
952 case CS8:
953 data_bits = RFCOMM_RPN_DATA_8;
954 break;
955 default:
956 data_bits = RFCOMM_RPN_DATA_8;
957 break;
958 }
959
960 /* Handle baudrate settings */
961 if (old_baud_rate != new_baud_rate)
962 changes |= RFCOMM_RPN_PM_BITRATE;
963
964 switch (new_baud_rate) {
965 case 2400:
966 baud = RFCOMM_RPN_BR_2400;
967 break;
968 case 4800:
969 baud = RFCOMM_RPN_BR_4800;
970 break;
971 case 7200:
972 baud = RFCOMM_RPN_BR_7200;
973 break;
974 case 9600:
975 baud = RFCOMM_RPN_BR_9600;
976 break;
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900977 case 19200:
J. Suter3a5e9032005-08-09 20:28:46 -0700978 baud = RFCOMM_RPN_BR_19200;
979 break;
980 case 38400:
981 baud = RFCOMM_RPN_BR_38400;
982 break;
983 case 57600:
984 baud = RFCOMM_RPN_BR_57600;
985 break;
986 case 115200:
987 baud = RFCOMM_RPN_BR_115200;
988 break;
989 case 230400:
990 baud = RFCOMM_RPN_BR_230400;
991 break;
992 default:
993 /* 9600 is standard accordinag to the RFCOMM specification */
994 baud = RFCOMM_RPN_BR_9600;
995 break;
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900996
J. Suter3a5e9032005-08-09 20:28:46 -0700997 }
998
999 if (changes)
1000 rfcomm_send_rpn(dev->dlc->session, 1, dev->dlc->dlci, baud,
1001 data_bits, stop_bits, parity,
1002 RFCOMM_RPN_FLOW_NONE, x_on, x_off, changes);
1003
1004 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001005}
1006
1007static void rfcomm_tty_throttle(struct tty_struct *tty)
1008{
1009 struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data;
1010
1011 BT_DBG("tty %p dev %p", tty, dev);
J. Suter3a5e9032005-08-09 20:28:46 -07001012
Linus Torvalds1da177e2005-04-16 15:20:36 -07001013 rfcomm_dlc_throttle(dev->dlc);
1014}
1015
1016static void rfcomm_tty_unthrottle(struct tty_struct *tty)
1017{
1018 struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data;
1019
1020 BT_DBG("tty %p dev %p", tty, dev);
J. Suter3a5e9032005-08-09 20:28:46 -07001021
Linus Torvalds1da177e2005-04-16 15:20:36 -07001022 rfcomm_dlc_unthrottle(dev->dlc);
1023}
1024
1025static int rfcomm_tty_chars_in_buffer(struct tty_struct *tty)
1026{
1027 struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001028
1029 BT_DBG("tty %p dev %p", tty, dev);
1030
Marcel Holtmannb6e557f2007-01-08 02:16:27 +01001031 if (!dev || !dev->dlc)
1032 return 0;
1033
1034 if (!skb_queue_empty(&dev->dlc->tx_queue))
1035 return dev->dlc->mtu;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001036
1037 return 0;
1038}
1039
1040static void rfcomm_tty_flush_buffer(struct tty_struct *tty)
1041{
1042 struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001043
1044 BT_DBG("tty %p dev %p", tty, dev);
1045
Marcel Holtmannb6e557f2007-01-08 02:16:27 +01001046 if (!dev || !dev->dlc)
1047 return;
1048
Linus Torvalds1da177e2005-04-16 15:20:36 -07001049 skb_queue_purge(&dev->dlc->tx_queue);
Alan Coxa352def2008-07-16 21:53:12 +01001050 tty_wakeup(tty);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001051}
1052
1053static void rfcomm_tty_send_xchar(struct tty_struct *tty, char ch)
1054{
1055 BT_DBG("tty %p ch %c", tty, ch);
1056}
1057
1058static void rfcomm_tty_wait_until_sent(struct tty_struct *tty, int timeout)
1059{
1060 BT_DBG("tty %p timeout %d", tty, timeout);
1061}
1062
1063static void rfcomm_tty_hangup(struct tty_struct *tty)
1064{
1065 struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001066
1067 BT_DBG("tty %p dev %p", tty, dev);
1068
Marcel Holtmannb6e557f2007-01-08 02:16:27 +01001069 if (!dev)
1070 return;
1071
Linus Torvalds1da177e2005-04-16 15:20:36 -07001072 rfcomm_tty_flush_buffer(tty);
1073
Marcel Holtmann77f2a452007-05-05 00:36:10 +02001074 if (test_bit(RFCOMM_RELEASE_ONHUP, &dev->flags)) {
1075 if (rfcomm_dev_get(dev->id) == NULL)
1076 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001077 rfcomm_dev_del(dev);
Marcel Holtmann77f2a452007-05-05 00:36:10 +02001078 rfcomm_dev_put(dev);
1079 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001080}
1081
1082static int rfcomm_tty_read_proc(char *buf, char **start, off_t offset, int len, int *eof, void *unused)
1083{
1084 return 0;
1085}
1086
1087static int rfcomm_tty_tiocmget(struct tty_struct *tty, struct file *filp)
1088{
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09001089 struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001090
1091 BT_DBG("tty %p dev %p", tty, dev);
1092
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09001093 return dev->modem_status;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001094}
1095
1096static int rfcomm_tty_tiocmset(struct tty_struct *tty, struct file *filp, unsigned int set, unsigned int clear)
1097{
J. Suter3a5e9032005-08-09 20:28:46 -07001098 struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data;
1099 struct rfcomm_dlc *dlc = dev->dlc;
1100 u8 v24_sig;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001101
1102 BT_DBG("tty %p dev %p set 0x%02x clear 0x%02x", tty, dev, set, clear);
1103
J. Suter3a5e9032005-08-09 20:28:46 -07001104 rfcomm_dlc_get_modem_status(dlc, &v24_sig);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001105
J. Suter3a5e9032005-08-09 20:28:46 -07001106 if (set & TIOCM_DSR || set & TIOCM_DTR)
1107 v24_sig |= RFCOMM_V24_RTC;
1108 if (set & TIOCM_RTS || set & TIOCM_CTS)
1109 v24_sig |= RFCOMM_V24_RTR;
1110 if (set & TIOCM_RI)
1111 v24_sig |= RFCOMM_V24_IC;
1112 if (set & TIOCM_CD)
1113 v24_sig |= RFCOMM_V24_DV;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001114
J. Suter3a5e9032005-08-09 20:28:46 -07001115 if (clear & TIOCM_DSR || clear & TIOCM_DTR)
1116 v24_sig &= ~RFCOMM_V24_RTC;
1117 if (clear & TIOCM_RTS || clear & TIOCM_CTS)
1118 v24_sig &= ~RFCOMM_V24_RTR;
1119 if (clear & TIOCM_RI)
1120 v24_sig &= ~RFCOMM_V24_IC;
1121 if (clear & TIOCM_CD)
1122 v24_sig &= ~RFCOMM_V24_DV;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001123
J. Suter3a5e9032005-08-09 20:28:46 -07001124 rfcomm_dlc_set_modem_status(dlc, v24_sig);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001125
J. Suter3a5e9032005-08-09 20:28:46 -07001126 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001127}
1128
1129/* ---- TTY structure ---- */
1130
Jeff Dikeb68e31d2006-10-02 02:17:18 -07001131static const struct tty_operations rfcomm_ops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001132 .open = rfcomm_tty_open,
1133 .close = rfcomm_tty_close,
1134 .write = rfcomm_tty_write,
1135 .write_room = rfcomm_tty_write_room,
1136 .chars_in_buffer = rfcomm_tty_chars_in_buffer,
1137 .flush_buffer = rfcomm_tty_flush_buffer,
1138 .ioctl = rfcomm_tty_ioctl,
1139 .throttle = rfcomm_tty_throttle,
1140 .unthrottle = rfcomm_tty_unthrottle,
1141 .set_termios = rfcomm_tty_set_termios,
1142 .send_xchar = rfcomm_tty_send_xchar,
1143 .hangup = rfcomm_tty_hangup,
1144 .wait_until_sent = rfcomm_tty_wait_until_sent,
1145 .read_proc = rfcomm_tty_read_proc,
1146 .tiocmget = rfcomm_tty_tiocmget,
1147 .tiocmset = rfcomm_tty_tiocmset,
1148};
1149
1150int rfcomm_init_ttys(void)
1151{
1152 rfcomm_tty_driver = alloc_tty_driver(RFCOMM_TTY_PORTS);
1153 if (!rfcomm_tty_driver)
1154 return -1;
1155
1156 rfcomm_tty_driver->owner = THIS_MODULE;
1157 rfcomm_tty_driver->driver_name = "rfcomm";
Linus Torvalds1da177e2005-04-16 15:20:36 -07001158 rfcomm_tty_driver->name = "rfcomm";
1159 rfcomm_tty_driver->major = RFCOMM_TTY_MAJOR;
1160 rfcomm_tty_driver->minor_start = RFCOMM_TTY_MINOR;
1161 rfcomm_tty_driver->type = TTY_DRIVER_TYPE_SERIAL;
1162 rfcomm_tty_driver->subtype = SERIAL_TYPE_NORMAL;
Greg Kroah-Hartman331b8312005-06-20 21:15:16 -07001163 rfcomm_tty_driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001164 rfcomm_tty_driver->init_termios = tty_std_termios;
1165 rfcomm_tty_driver->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL;
Marcel Holtmannca37bdd2008-07-14 20:13:52 +02001166 rfcomm_tty_driver->init_termios.c_lflag &= ~ICANON;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001167 tty_set_operations(rfcomm_tty_driver, &rfcomm_ops);
1168
1169 if (tty_register_driver(rfcomm_tty_driver)) {
1170 BT_ERR("Can't register RFCOMM TTY driver");
1171 put_tty_driver(rfcomm_tty_driver);
1172 return -1;
1173 }
1174
1175 BT_INFO("RFCOMM TTY layer initialized");
1176
1177 return 0;
1178}
1179
1180void rfcomm_cleanup_ttys(void)
1181{
1182 tty_unregister_driver(rfcomm_tty_driver);
1183 put_tty_driver(rfcomm_tty_driver);
1184}