blob: 111c6c8582473cb9c9c8ec5a3b0e9040ab284ef7 [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;
Marcel Holtmann9a5df922008-11-30 12:17:29 +010056 atomic_t opened;
Linus Torvalds1da177e2005-04-16 15:20:36 -070057 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
Marcel Holtmann9a5df922008-11-30 12:17:29 +0100259 atomic_set(&dev->opened, 0);
260
Linus Torvalds1da177e2005-04-16 15:20:36 -0700261 init_waitqueue_head(&dev->wait);
262 tasklet_init(&dev->wakeup_task, rfcomm_tty_wakeup, (unsigned long) dev);
263
Marcel Holtmanna0c22f22008-07-14 20:13:52 +0200264 skb_queue_head_init(&dev->pending);
265
Linus Torvalds1da177e2005-04-16 15:20:36 -0700266 rfcomm_dlc_lock(dlc);
Marcel Holtmanna0c22f22008-07-14 20:13:52 +0200267
268 if (req->flags & (1 << RFCOMM_REUSE_DLC)) {
269 struct sock *sk = dlc->owner;
270 struct sk_buff *skb;
271
272 BUG_ON(!sk);
273
274 rfcomm_dlc_throttle(dlc);
275
276 while ((skb = skb_dequeue(&sk->sk_receive_queue))) {
277 skb_orphan(skb);
278 skb_queue_tail(&dev->pending, skb);
279 atomic_sub(skb->len, &sk->sk_rmem_alloc);
280 }
281 }
282
Linus Torvalds1da177e2005-04-16 15:20:36 -0700283 dlc->data_ready = rfcomm_dev_data_ready;
284 dlc->state_change = rfcomm_dev_state_change;
285 dlc->modem_status = rfcomm_dev_modem_status;
286
287 dlc->owner = dev;
288 dev->dlc = dlc;
Marcel Holtmann8b6b3da2008-07-14 20:13:52 +0200289
290 rfcomm_dev_modem_status(dlc, dlc->remote_v24_sig);
291
Linus Torvalds1da177e2005-04-16 15:20:36 -0700292 rfcomm_dlc_unlock(dlc);
293
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900294 /* It's safe to call __module_get() here because socket already
Linus Torvalds1da177e2005-04-16 15:20:36 -0700295 holds reference to this module. */
296 __module_get(THIS_MODULE);
297
298out:
299 write_unlock_bh(&rfcomm_dev_lock);
300
Marcel Holtmann09c7d822007-07-26 00:12:25 -0700301 if (err < 0) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700302 kfree(dev);
303 return err;
304 }
305
Marcel Holtmannc1a33132007-02-17 23:58:57 +0100306 dev->tty_dev = tty_register_device(rfcomm_tty_driver, dev->id, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700307
Ville Tervo8de0a152007-07-11 09:23:41 +0200308 if (IS_ERR(dev->tty_dev)) {
Marcel Holtmann09c7d822007-07-26 00:12:25 -0700309 err = PTR_ERR(dev->tty_dev);
Ville Tervo8de0a152007-07-11 09:23:41 +0200310 list_del(&dev->list);
311 kfree(dev);
Marcel Holtmann09c7d822007-07-26 00:12:25 -0700312 return err;
Ville Tervo8de0a152007-07-11 09:23:41 +0200313 }
314
Marcel Holtmanndae6a0f2007-10-20 14:52:38 +0200315 dev_set_drvdata(dev->tty_dev, dev);
316
317 if (device_create_file(dev->tty_dev, &dev_attr_address) < 0)
318 BT_ERR("Failed to create address attribute");
319
320 if (device_create_file(dev->tty_dev, &dev_attr_channel) < 0)
321 BT_ERR("Failed to create channel attribute");
322
Linus Torvalds1da177e2005-04-16 15:20:36 -0700323 return dev->id;
324}
325
326static void rfcomm_dev_del(struct rfcomm_dev *dev)
327{
328 BT_DBG("dev %p", dev);
329
Marcel Holtmann9a5df922008-11-30 12:17:29 +0100330 BUG_ON(test_and_set_bit(RFCOMM_TTY_RELEASED, &dev->flags));
331
332 if (atomic_read(&dev->opened) > 0)
333 return;
Dave Youngf9513752008-01-10 22:22:52 -0800334
335 write_lock_bh(&rfcomm_dev_lock);
336 list_del_init(&dev->list);
337 write_unlock_bh(&rfcomm_dev_lock);
338
Linus Torvalds1da177e2005-04-16 15:20:36 -0700339 rfcomm_dev_put(dev);
340}
341
342/* ---- Send buffer ---- */
343static inline unsigned int rfcomm_room(struct rfcomm_dlc *dlc)
344{
345 /* We can't let it be zero, because we don't get a callback
346 when tx_credits becomes nonzero, hence we'd never wake up */
347 return dlc->mtu * (dlc->tx_credits?:1);
348}
349
350static void rfcomm_wfree(struct sk_buff *skb)
351{
352 struct rfcomm_dev *dev = (void *) skb->sk;
353 atomic_sub(skb->truesize, &dev->wmem_alloc);
354 if (test_bit(RFCOMM_TTY_ATTACHED, &dev->flags))
355 tasklet_schedule(&dev->wakeup_task);
356 rfcomm_dev_put(dev);
357}
358
359static inline void rfcomm_set_owner_w(struct sk_buff *skb, struct rfcomm_dev *dev)
360{
361 rfcomm_dev_hold(dev);
362 atomic_add(skb->truesize, &dev->wmem_alloc);
363 skb->sk = (void *) dev;
364 skb->destructor = rfcomm_wfree;
365}
366
Al Virodd0fc662005-10-07 07:46:04 +0100367static struct sk_buff *rfcomm_wmalloc(struct rfcomm_dev *dev, unsigned long size, gfp_t priority)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700368{
369 if (atomic_read(&dev->wmem_alloc) < rfcomm_room(dev->dlc)) {
370 struct sk_buff *skb = alloc_skb(size, priority);
371 if (skb) {
372 rfcomm_set_owner_w(skb, dev);
373 return skb;
374 }
375 }
376 return NULL;
377}
378
379/* ---- Device IOCTLs ---- */
380
381#define NOCAP_FLAGS ((1 << RFCOMM_REUSE_DLC) | (1 << RFCOMM_RELEASE_ONHUP))
382
383static int rfcomm_create_dev(struct sock *sk, void __user *arg)
384{
385 struct rfcomm_dev_req req;
386 struct rfcomm_dlc *dlc;
387 int id;
388
389 if (copy_from_user(&req, arg, sizeof(req)))
390 return -EFAULT;
391
Ville Tervo8de0a152007-07-11 09:23:41 +0200392 BT_DBG("sk %p dev_id %d flags 0x%x", sk, req.dev_id, req.flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700393
394 if (req.flags != NOCAP_FLAGS && !capable(CAP_NET_ADMIN))
395 return -EPERM;
396
397 if (req.flags & (1 << RFCOMM_REUSE_DLC)) {
398 /* Socket must be connected */
399 if (sk->sk_state != BT_CONNECTED)
400 return -EBADFD;
401
402 dlc = rfcomm_pi(sk)->dlc;
403 rfcomm_dlc_hold(dlc);
404 } else {
405 dlc = rfcomm_dlc_alloc(GFP_KERNEL);
406 if (!dlc)
407 return -ENOMEM;
408 }
409
410 id = rfcomm_dev_add(&req, dlc);
411 if (id < 0) {
412 rfcomm_dlc_put(dlc);
413 return id;
414 }
415
416 if (req.flags & (1 << RFCOMM_REUSE_DLC)) {
417 /* DLC is now used by device.
418 * Socket must be disconnected */
419 sk->sk_state = BT_CLOSED;
420 }
421
422 return id;
423}
424
425static int rfcomm_release_dev(void __user *arg)
426{
427 struct rfcomm_dev_req req;
428 struct rfcomm_dev *dev;
429
430 if (copy_from_user(&req, arg, sizeof(req)))
431 return -EFAULT;
432
Ville Tervo8de0a152007-07-11 09:23:41 +0200433 BT_DBG("dev_id %d flags 0x%x", req.dev_id, req.flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700434
435 if (!(dev = rfcomm_dev_get(req.dev_id)))
436 return -ENODEV;
437
438 if (dev->flags != NOCAP_FLAGS && !capable(CAP_NET_ADMIN)) {
439 rfcomm_dev_put(dev);
440 return -EPERM;
441 }
442
443 if (req.flags & (1 << RFCOMM_HANGUP_NOW))
444 rfcomm_dlc_close(dev->dlc, 0);
445
Mikko Rapeli84950cf2007-07-11 09:18:15 +0200446 /* Shut down TTY synchronously before freeing rfcomm_dev */
447 if (dev->tty)
448 tty_vhangup(dev->tty);
449
Dave Young93d80742008-02-05 03:12:06 -0800450 if (!test_bit(RFCOMM_RELEASE_ONHUP, &dev->flags))
451 rfcomm_dev_del(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700452 rfcomm_dev_put(dev);
453 return 0;
454}
455
456static int rfcomm_get_dev_list(void __user *arg)
457{
458 struct rfcomm_dev_list_req *dl;
459 struct rfcomm_dev_info *di;
460 struct list_head *p;
461 int n = 0, size, err;
462 u16 dev_num;
463
464 BT_DBG("");
465
466 if (get_user(dev_num, (u16 __user *) arg))
467 return -EFAULT;
468
469 if (!dev_num || dev_num > (PAGE_SIZE * 4) / sizeof(*di))
470 return -EINVAL;
471
472 size = sizeof(*dl) + dev_num * sizeof(*di);
473
474 if (!(dl = kmalloc(size, GFP_KERNEL)))
475 return -ENOMEM;
476
477 di = dl->dev_info;
478
479 read_lock_bh(&rfcomm_dev_lock);
480
481 list_for_each(p, &rfcomm_dev_list) {
482 struct rfcomm_dev *dev = list_entry(p, struct rfcomm_dev, list);
Ville Tervo8de0a152007-07-11 09:23:41 +0200483 if (test_bit(RFCOMM_TTY_RELEASED, &dev->flags))
484 continue;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700485 (di + n)->id = dev->id;
486 (di + n)->flags = dev->flags;
487 (di + n)->state = dev->dlc->state;
488 (di + n)->channel = dev->channel;
489 bacpy(&(di + n)->src, &dev->src);
490 bacpy(&(di + n)->dst, &dev->dst);
491 if (++n >= dev_num)
492 break;
493 }
494
495 read_unlock_bh(&rfcomm_dev_lock);
496
497 dl->dev_num = n;
498 size = sizeof(*dl) + n * sizeof(*di);
499
500 err = copy_to_user(arg, dl, size);
501 kfree(dl);
502
503 return err ? -EFAULT : 0;
504}
505
506static int rfcomm_get_dev_info(void __user *arg)
507{
508 struct rfcomm_dev *dev;
509 struct rfcomm_dev_info di;
510 int err = 0;
511
512 BT_DBG("");
513
514 if (copy_from_user(&di, arg, sizeof(di)))
515 return -EFAULT;
516
517 if (!(dev = rfcomm_dev_get(di.id)))
518 return -ENODEV;
519
520 di.flags = dev->flags;
521 di.channel = dev->channel;
522 di.state = dev->dlc->state;
523 bacpy(&di.src, &dev->src);
524 bacpy(&di.dst, &dev->dst);
525
526 if (copy_to_user(arg, &di, sizeof(di)))
527 err = -EFAULT;
528
529 rfcomm_dev_put(dev);
530 return err;
531}
532
533int rfcomm_dev_ioctl(struct sock *sk, unsigned int cmd, void __user *arg)
534{
535 BT_DBG("cmd %d arg %p", cmd, arg);
536
537 switch (cmd) {
538 case RFCOMMCREATEDEV:
539 return rfcomm_create_dev(sk, arg);
540
541 case RFCOMMRELEASEDEV:
542 return rfcomm_release_dev(arg);
543
544 case RFCOMMGETDEVLIST:
545 return rfcomm_get_dev_list(arg);
546
547 case RFCOMMGETDEVINFO:
548 return rfcomm_get_dev_info(arg);
549 }
550
551 return -EINVAL;
552}
553
554/* ---- DLC callbacks ---- */
555static void rfcomm_dev_data_ready(struct rfcomm_dlc *dlc, struct sk_buff *skb)
556{
557 struct rfcomm_dev *dev = dlc->owner;
558 struct tty_struct *tty;
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900559
Marcel Holtmanna0c22f22008-07-14 20:13:52 +0200560 if (!dev) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700561 kfree_skb(skb);
562 return;
563 }
564
Marcel Holtmanna0c22f22008-07-14 20:13:52 +0200565 if (!(tty = dev->tty) || !skb_queue_empty(&dev->pending)) {
566 skb_queue_tail(&dev->pending, skb);
567 return;
568 }
569
Linus Torvalds1da177e2005-04-16 15:20:36 -0700570 BT_DBG("dlc %p tty %p len %d", dlc, tty, skb->len);
571
Paul Fulghum817d6d32006-06-28 04:26:47 -0700572 tty_insert_flip_string(tty, skb->data, skb->len);
573 tty_flip_buffer_push(tty);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700574
575 kfree_skb(skb);
576}
577
578static void rfcomm_dev_state_change(struct rfcomm_dlc *dlc, int err)
579{
580 struct rfcomm_dev *dev = dlc->owner;
581 if (!dev)
582 return;
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900583
Linus Torvalds1da177e2005-04-16 15:20:36 -0700584 BT_DBG("dlc %p dev %p err %d", dlc, dev, err);
585
586 dev->err = err;
587 wake_up_interruptible(&dev->wait);
588
589 if (dlc->state == BT_CLOSED) {
590 if (!dev->tty) {
591 if (test_bit(RFCOMM_RELEASE_ONHUP, &dev->flags)) {
Dave Young537d59a2008-06-01 23:50:52 -0700592 /* Drop DLC lock here to avoid deadlock
593 * 1. rfcomm_dev_get will take rfcomm_dev_lock
594 * but in rfcomm_dev_add there's lock order:
595 * rfcomm_dev_lock -> dlc lock
596 * 2. rfcomm_dev_put will deadlock if it's
597 * the last reference
598 */
599 rfcomm_dlc_unlock(dlc);
600 if (rfcomm_dev_get(dev->id) == NULL) {
601 rfcomm_dlc_lock(dlc);
Marcel Holtmann77f2a452007-05-05 00:36:10 +0200602 return;
Dave Young537d59a2008-06-01 23:50:52 -0700603 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700604
Marcel Holtmann77f2a452007-05-05 00:36:10 +0200605 rfcomm_dev_del(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700606 rfcomm_dev_put(dev);
Dave Young537d59a2008-06-01 23:50:52 -0700607 rfcomm_dlc_lock(dlc);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700608 }
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900609 } else
Linus Torvalds1da177e2005-04-16 15:20:36 -0700610 tty_hangup(dev->tty);
611 }
612}
613
614static void rfcomm_dev_modem_status(struct rfcomm_dlc *dlc, u8 v24_sig)
615{
616 struct rfcomm_dev *dev = dlc->owner;
617 if (!dev)
618 return;
Timo Teräs7b9eb9e2005-08-09 20:28:21 -0700619
Linus Torvalds1da177e2005-04-16 15:20:36 -0700620 BT_DBG("dlc %p dev %p v24_sig 0x%02x", dlc, dev, v24_sig);
621
Timo Teräs7b9eb9e2005-08-09 20:28:21 -0700622 if ((dev->modem_status & TIOCM_CD) && !(v24_sig & RFCOMM_V24_DV)) {
623 if (dev->tty && !C_CLOCAL(dev->tty))
624 tty_hangup(dev->tty);
625 }
626
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900627 dev->modem_status =
Linus Torvalds1da177e2005-04-16 15:20:36 -0700628 ((v24_sig & RFCOMM_V24_RTC) ? (TIOCM_DSR | TIOCM_DTR) : 0) |
629 ((v24_sig & RFCOMM_V24_RTR) ? (TIOCM_RTS | TIOCM_CTS) : 0) |
630 ((v24_sig & RFCOMM_V24_IC) ? TIOCM_RI : 0) |
631 ((v24_sig & RFCOMM_V24_DV) ? TIOCM_CD : 0);
632}
633
634/* ---- TTY functions ---- */
635static void rfcomm_tty_wakeup(unsigned long arg)
636{
637 struct rfcomm_dev *dev = (void *) arg;
638 struct tty_struct *tty = dev->tty;
639 if (!tty)
640 return;
641
642 BT_DBG("dev %p tty %p", dev, tty);
Alan Coxa352def2008-07-16 21:53:12 +0100643 tty_wakeup(tty);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700644}
645
Marcel Holtmanna0c22f22008-07-14 20:13:52 +0200646static void rfcomm_tty_copy_pending(struct rfcomm_dev *dev)
647{
648 struct tty_struct *tty = dev->tty;
649 struct sk_buff *skb;
650 int inserted = 0;
651
652 if (!tty)
653 return;
654
655 BT_DBG("dev %p tty %p", dev, tty);
656
657 rfcomm_dlc_lock(dev->dlc);
658
659 while ((skb = skb_dequeue(&dev->pending))) {
660 inserted += tty_insert_flip_string(tty, skb->data, skb->len);
661 kfree_skb(skb);
662 }
663
664 rfcomm_dlc_unlock(dev->dlc);
665
666 if (inserted > 0)
667 tty_flip_buffer_push(tty);
668}
669
Linus Torvalds1da177e2005-04-16 15:20:36 -0700670static int rfcomm_tty_open(struct tty_struct *tty, struct file *filp)
671{
672 DECLARE_WAITQUEUE(wait, current);
673 struct rfcomm_dev *dev;
674 struct rfcomm_dlc *dlc;
675 int err, id;
676
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900677 id = tty->index;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700678
679 BT_DBG("tty %p id %d", tty, id);
680
681 /* We don't leak this refcount. For reasons which are not entirely
682 clear, the TTY layer will call our ->close() method even if the
683 open fails. We decrease the refcount there, and decreasing it
684 here too would cause breakage. */
685 dev = rfcomm_dev_get(id);
686 if (!dev)
687 return -ENODEV;
688
Marcel Holtmann9a5df922008-11-30 12:17:29 +0100689 BT_DBG("dev %p dst %s channel %d opened %d", dev, batostr(&dev->dst),
690 dev->channel, atomic_read(&dev->opened));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700691
Marcel Holtmann9a5df922008-11-30 12:17:29 +0100692 if (atomic_inc_return(&dev->opened) > 1)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700693 return 0;
694
695 dlc = dev->dlc;
696
697 /* Attach TTY and open DLC */
698
699 rfcomm_dlc_lock(dlc);
700 tty->driver_data = dev;
701 dev->tty = tty;
702 rfcomm_dlc_unlock(dlc);
703 set_bit(RFCOMM_TTY_ATTACHED, &dev->flags);
704
705 err = rfcomm_dlc_open(dlc, &dev->src, &dev->dst, dev->channel);
706 if (err < 0)
707 return err;
708
709 /* Wait for DLC to connect */
710 add_wait_queue(&dev->wait, &wait);
711 while (1) {
712 set_current_state(TASK_INTERRUPTIBLE);
713
714 if (dlc->state == BT_CLOSED) {
715 err = -dev->err;
716 break;
717 }
718
719 if (dlc->state == BT_CONNECTED)
720 break;
721
722 if (signal_pending(current)) {
723 err = -EINTR;
724 break;
725 }
726
727 schedule();
728 }
729 set_current_state(TASK_RUNNING);
730 remove_wait_queue(&dev->wait, &wait);
731
Marcel Holtmannc1a33132007-02-17 23:58:57 +0100732 if (err == 0)
733 device_move(dev->tty_dev, rfcomm_get_device(dev));
734
Marcel Holtmanna0c22f22008-07-14 20:13:52 +0200735 rfcomm_tty_copy_pending(dev);
736
737 rfcomm_dlc_unthrottle(dev->dlc);
738
Linus Torvalds1da177e2005-04-16 15:20:36 -0700739 return err;
740}
741
742static void rfcomm_tty_close(struct tty_struct *tty, struct file *filp)
743{
744 struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data;
745 if (!dev)
746 return;
747
Marcel Holtmann9a5df922008-11-30 12:17:29 +0100748 BT_DBG("tty %p dev %p dlc %p opened %d", tty, dev, dev->dlc,
749 atomic_read(&dev->opened));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700750
Marcel Holtmann9a5df922008-11-30 12:17:29 +0100751 if (atomic_dec_and_test(&dev->opened)) {
Dave Youngacea6852008-01-21 22:35:21 -0800752 if (dev->tty_dev->parent)
753 device_move(dev->tty_dev, NULL);
Marcel Holtmannc1a33132007-02-17 23:58:57 +0100754
Linus Torvalds1da177e2005-04-16 15:20:36 -0700755 /* Close DLC and dettach TTY */
756 rfcomm_dlc_close(dev->dlc, 0);
757
758 clear_bit(RFCOMM_TTY_ATTACHED, &dev->flags);
759 tasklet_kill(&dev->wakeup_task);
760
761 rfcomm_dlc_lock(dev->dlc);
762 tty->driver_data = NULL;
763 dev->tty = NULL;
764 rfcomm_dlc_unlock(dev->dlc);
Marcel Holtmann9a5df922008-11-30 12:17:29 +0100765
766 if (test_bit(RFCOMM_TTY_RELEASED, &dev->flags)) {
767 write_lock_bh(&rfcomm_dev_lock);
768 list_del_init(&dev->list);
769 write_unlock_bh(&rfcomm_dev_lock);
770
771 rfcomm_dev_put(dev);
772 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700773 }
774
775 rfcomm_dev_put(dev);
776}
777
778static int rfcomm_tty_write(struct tty_struct *tty, const unsigned char *buf, int count)
779{
780 struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data;
781 struct rfcomm_dlc *dlc = dev->dlc;
782 struct sk_buff *skb;
783 int err = 0, sent = 0, size;
784
785 BT_DBG("tty %p count %d", tty, count);
786
787 while (count) {
788 size = min_t(uint, count, dlc->mtu);
789
790 skb = rfcomm_wmalloc(dev, size + RFCOMM_SKB_RESERVE, GFP_ATOMIC);
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900791
Linus Torvalds1da177e2005-04-16 15:20:36 -0700792 if (!skb)
793 break;
794
795 skb_reserve(skb, RFCOMM_SKB_HEAD_RESERVE);
796
797 memcpy(skb_put(skb, size), buf + sent, size);
798
799 if ((err = rfcomm_dlc_send(dlc, skb)) < 0) {
800 kfree_skb(skb);
801 break;
802 }
803
804 sent += size;
805 count -= size;
806 }
807
808 return sent ? sent : err;
809}
810
811static int rfcomm_tty_write_room(struct tty_struct *tty)
812{
813 struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data;
814 int room;
815
816 BT_DBG("tty %p", tty);
817
Marcel Holtmannb6e557f2007-01-08 02:16:27 +0100818 if (!dev || !dev->dlc)
819 return 0;
820
Linus Torvalds1da177e2005-04-16 15:20:36 -0700821 room = rfcomm_room(dev->dlc) - atomic_read(&dev->wmem_alloc);
822 if (room < 0)
823 room = 0;
Marcel Holtmannb6e557f2007-01-08 02:16:27 +0100824
Linus Torvalds1da177e2005-04-16 15:20:36 -0700825 return room;
826}
827
828static int rfcomm_tty_ioctl(struct tty_struct *tty, struct file *filp, unsigned int cmd, unsigned long arg)
829{
830 BT_DBG("tty %p cmd 0x%02x", tty, cmd);
831
832 switch (cmd) {
833 case TCGETS:
834 BT_DBG("TCGETS is not supported");
835 return -ENOIOCTLCMD;
836
837 case TCSETS:
838 BT_DBG("TCSETS is not supported");
839 return -ENOIOCTLCMD;
840
841 case TIOCMIWAIT:
842 BT_DBG("TIOCMIWAIT");
843 break;
844
845 case TIOCGICOUNT:
846 BT_DBG("TIOCGICOUNT");
847 break;
848
849 case TIOCGSERIAL:
850 BT_ERR("TIOCGSERIAL is not supported");
851 return -ENOIOCTLCMD;
852
853 case TIOCSSERIAL:
854 BT_ERR("TIOCSSERIAL is not supported");
855 return -ENOIOCTLCMD;
856
857 case TIOCSERGSTRUCT:
858 BT_ERR("TIOCSERGSTRUCT is not supported");
859 return -ENOIOCTLCMD;
860
861 case TIOCSERGETLSR:
862 BT_ERR("TIOCSERGETLSR is not supported");
863 return -ENOIOCTLCMD;
864
865 case TIOCSERCONFIG:
866 BT_ERR("TIOCSERCONFIG is not supported");
867 return -ENOIOCTLCMD;
868
869 default:
870 return -ENOIOCTLCMD; /* ioctls which we must ignore */
871
872 }
873
874 return -ENOIOCTLCMD;
875}
876
Alan Cox606d0992006-12-08 02:38:45 -0800877static void rfcomm_tty_set_termios(struct tty_struct *tty, struct ktermios *old)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700878{
Alan Cox606d0992006-12-08 02:38:45 -0800879 struct ktermios *new = tty->termios;
J. Suter3a5e9032005-08-09 20:28:46 -0700880 int old_baud_rate = tty_termios_baud_rate(old);
881 int new_baud_rate = tty_termios_baud_rate(new);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700882
J. Suter3a5e9032005-08-09 20:28:46 -0700883 u8 baud, data_bits, stop_bits, parity, x_on, x_off;
884 u16 changes = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700885
J. Suter3a5e9032005-08-09 20:28:46 -0700886 struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data;
887
888 BT_DBG("tty %p termios %p", tty, old);
889
Marcel Holtmannff2d3672006-11-18 22:14:42 +0100890 if (!dev || !dev->dlc || !dev->dlc->session)
Marcel Holtmanncb19d9e2006-10-15 17:31:10 +0200891 return;
892
J. Suter3a5e9032005-08-09 20:28:46 -0700893 /* Handle turning off CRTSCTS */
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900894 if ((old->c_cflag & CRTSCTS) && !(new->c_cflag & CRTSCTS))
J. Suter3a5e9032005-08-09 20:28:46 -0700895 BT_DBG("Turning off CRTSCTS unsupported");
896
897 /* Parity on/off and when on, odd/even */
898 if (((old->c_cflag & PARENB) != (new->c_cflag & PARENB)) ||
899 ((old->c_cflag & PARODD) != (new->c_cflag & PARODD)) ) {
900 changes |= RFCOMM_RPN_PM_PARITY;
901 BT_DBG("Parity change detected.");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700902 }
J. Suter3a5e9032005-08-09 20:28:46 -0700903
904 /* Mark and space parity are not supported! */
905 if (new->c_cflag & PARENB) {
906 if (new->c_cflag & PARODD) {
907 BT_DBG("Parity is ODD");
908 parity = RFCOMM_RPN_PARITY_ODD;
909 } else {
910 BT_DBG("Parity is EVEN");
911 parity = RFCOMM_RPN_PARITY_EVEN;
912 }
913 } else {
914 BT_DBG("Parity is OFF");
915 parity = RFCOMM_RPN_PARITY_NONE;
916 }
917
918 /* Setting the x_on / x_off characters */
919 if (old->c_cc[VSTOP] != new->c_cc[VSTOP]) {
920 BT_DBG("XOFF custom");
921 x_on = new->c_cc[VSTOP];
922 changes |= RFCOMM_RPN_PM_XON;
923 } else {
924 BT_DBG("XOFF default");
925 x_on = RFCOMM_RPN_XON_CHAR;
926 }
927
928 if (old->c_cc[VSTART] != new->c_cc[VSTART]) {
929 BT_DBG("XON custom");
930 x_off = new->c_cc[VSTART];
931 changes |= RFCOMM_RPN_PM_XOFF;
932 } else {
933 BT_DBG("XON default");
934 x_off = RFCOMM_RPN_XOFF_CHAR;
935 }
936
937 /* Handle setting of stop bits */
938 if ((old->c_cflag & CSTOPB) != (new->c_cflag & CSTOPB))
939 changes |= RFCOMM_RPN_PM_STOP;
940
941 /* POSIX does not support 1.5 stop bits and RFCOMM does not
942 * support 2 stop bits. So a request for 2 stop bits gets
943 * translated to 1.5 stop bits */
944 if (new->c_cflag & CSTOPB) {
945 stop_bits = RFCOMM_RPN_STOP_15;
946 } else {
947 stop_bits = RFCOMM_RPN_STOP_1;
948 }
949
950 /* Handle number of data bits [5-8] */
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900951 if ((old->c_cflag & CSIZE) != (new->c_cflag & CSIZE))
J. Suter3a5e9032005-08-09 20:28:46 -0700952 changes |= RFCOMM_RPN_PM_DATA;
953
954 switch (new->c_cflag & CSIZE) {
955 case CS5:
956 data_bits = RFCOMM_RPN_DATA_5;
957 break;
958 case CS6:
959 data_bits = RFCOMM_RPN_DATA_6;
960 break;
961 case CS7:
962 data_bits = RFCOMM_RPN_DATA_7;
963 break;
964 case CS8:
965 data_bits = RFCOMM_RPN_DATA_8;
966 break;
967 default:
968 data_bits = RFCOMM_RPN_DATA_8;
969 break;
970 }
971
972 /* Handle baudrate settings */
973 if (old_baud_rate != new_baud_rate)
974 changes |= RFCOMM_RPN_PM_BITRATE;
975
976 switch (new_baud_rate) {
977 case 2400:
978 baud = RFCOMM_RPN_BR_2400;
979 break;
980 case 4800:
981 baud = RFCOMM_RPN_BR_4800;
982 break;
983 case 7200:
984 baud = RFCOMM_RPN_BR_7200;
985 break;
986 case 9600:
987 baud = RFCOMM_RPN_BR_9600;
988 break;
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900989 case 19200:
J. Suter3a5e9032005-08-09 20:28:46 -0700990 baud = RFCOMM_RPN_BR_19200;
991 break;
992 case 38400:
993 baud = RFCOMM_RPN_BR_38400;
994 break;
995 case 57600:
996 baud = RFCOMM_RPN_BR_57600;
997 break;
998 case 115200:
999 baud = RFCOMM_RPN_BR_115200;
1000 break;
1001 case 230400:
1002 baud = RFCOMM_RPN_BR_230400;
1003 break;
1004 default:
1005 /* 9600 is standard accordinag to the RFCOMM specification */
1006 baud = RFCOMM_RPN_BR_9600;
1007 break;
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09001008
J. Suter3a5e9032005-08-09 20:28:46 -07001009 }
1010
1011 if (changes)
1012 rfcomm_send_rpn(dev->dlc->session, 1, dev->dlc->dlci, baud,
1013 data_bits, stop_bits, parity,
1014 RFCOMM_RPN_FLOW_NONE, x_on, x_off, changes);
1015
1016 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001017}
1018
1019static void rfcomm_tty_throttle(struct tty_struct *tty)
1020{
1021 struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data;
1022
1023 BT_DBG("tty %p dev %p", tty, dev);
J. Suter3a5e9032005-08-09 20:28:46 -07001024
Linus Torvalds1da177e2005-04-16 15:20:36 -07001025 rfcomm_dlc_throttle(dev->dlc);
1026}
1027
1028static void rfcomm_tty_unthrottle(struct tty_struct *tty)
1029{
1030 struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data;
1031
1032 BT_DBG("tty %p dev %p", tty, dev);
J. Suter3a5e9032005-08-09 20:28:46 -07001033
Linus Torvalds1da177e2005-04-16 15:20:36 -07001034 rfcomm_dlc_unthrottle(dev->dlc);
1035}
1036
1037static int rfcomm_tty_chars_in_buffer(struct tty_struct *tty)
1038{
1039 struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001040
1041 BT_DBG("tty %p dev %p", tty, dev);
1042
Marcel Holtmannb6e557f2007-01-08 02:16:27 +01001043 if (!dev || !dev->dlc)
1044 return 0;
1045
1046 if (!skb_queue_empty(&dev->dlc->tx_queue))
1047 return dev->dlc->mtu;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001048
1049 return 0;
1050}
1051
1052static void rfcomm_tty_flush_buffer(struct tty_struct *tty)
1053{
1054 struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001055
1056 BT_DBG("tty %p dev %p", tty, dev);
1057
Marcel Holtmannb6e557f2007-01-08 02:16:27 +01001058 if (!dev || !dev->dlc)
1059 return;
1060
Linus Torvalds1da177e2005-04-16 15:20:36 -07001061 skb_queue_purge(&dev->dlc->tx_queue);
Alan Coxa352def2008-07-16 21:53:12 +01001062 tty_wakeup(tty);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001063}
1064
1065static void rfcomm_tty_send_xchar(struct tty_struct *tty, char ch)
1066{
1067 BT_DBG("tty %p ch %c", tty, ch);
1068}
1069
1070static void rfcomm_tty_wait_until_sent(struct tty_struct *tty, int timeout)
1071{
1072 BT_DBG("tty %p timeout %d", tty, timeout);
1073}
1074
1075static void rfcomm_tty_hangup(struct tty_struct *tty)
1076{
1077 struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001078
1079 BT_DBG("tty %p dev %p", tty, dev);
1080
Marcel Holtmannb6e557f2007-01-08 02:16:27 +01001081 if (!dev)
1082 return;
1083
Linus Torvalds1da177e2005-04-16 15:20:36 -07001084 rfcomm_tty_flush_buffer(tty);
1085
Marcel Holtmann77f2a452007-05-05 00:36:10 +02001086 if (test_bit(RFCOMM_RELEASE_ONHUP, &dev->flags)) {
1087 if (rfcomm_dev_get(dev->id) == NULL)
1088 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001089 rfcomm_dev_del(dev);
Marcel Holtmann77f2a452007-05-05 00:36:10 +02001090 rfcomm_dev_put(dev);
1091 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001092}
1093
1094static int rfcomm_tty_read_proc(char *buf, char **start, off_t offset, int len, int *eof, void *unused)
1095{
1096 return 0;
1097}
1098
1099static int rfcomm_tty_tiocmget(struct tty_struct *tty, struct file *filp)
1100{
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09001101 struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001102
1103 BT_DBG("tty %p dev %p", tty, dev);
1104
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09001105 return dev->modem_status;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001106}
1107
1108static int rfcomm_tty_tiocmset(struct tty_struct *tty, struct file *filp, unsigned int set, unsigned int clear)
1109{
J. Suter3a5e9032005-08-09 20:28:46 -07001110 struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data;
1111 struct rfcomm_dlc *dlc = dev->dlc;
1112 u8 v24_sig;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001113
1114 BT_DBG("tty %p dev %p set 0x%02x clear 0x%02x", tty, dev, set, clear);
1115
J. Suter3a5e9032005-08-09 20:28:46 -07001116 rfcomm_dlc_get_modem_status(dlc, &v24_sig);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001117
J. Suter3a5e9032005-08-09 20:28:46 -07001118 if (set & TIOCM_DSR || set & TIOCM_DTR)
1119 v24_sig |= RFCOMM_V24_RTC;
1120 if (set & TIOCM_RTS || set & TIOCM_CTS)
1121 v24_sig |= RFCOMM_V24_RTR;
1122 if (set & TIOCM_RI)
1123 v24_sig |= RFCOMM_V24_IC;
1124 if (set & TIOCM_CD)
1125 v24_sig |= RFCOMM_V24_DV;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001126
J. Suter3a5e9032005-08-09 20:28:46 -07001127 if (clear & TIOCM_DSR || clear & TIOCM_DTR)
1128 v24_sig &= ~RFCOMM_V24_RTC;
1129 if (clear & TIOCM_RTS || clear & TIOCM_CTS)
1130 v24_sig &= ~RFCOMM_V24_RTR;
1131 if (clear & TIOCM_RI)
1132 v24_sig &= ~RFCOMM_V24_IC;
1133 if (clear & TIOCM_CD)
1134 v24_sig &= ~RFCOMM_V24_DV;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001135
J. Suter3a5e9032005-08-09 20:28:46 -07001136 rfcomm_dlc_set_modem_status(dlc, v24_sig);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001137
J. Suter3a5e9032005-08-09 20:28:46 -07001138 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001139}
1140
1141/* ---- TTY structure ---- */
1142
Jeff Dikeb68e31d2006-10-02 02:17:18 -07001143static const struct tty_operations rfcomm_ops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001144 .open = rfcomm_tty_open,
1145 .close = rfcomm_tty_close,
1146 .write = rfcomm_tty_write,
1147 .write_room = rfcomm_tty_write_room,
1148 .chars_in_buffer = rfcomm_tty_chars_in_buffer,
1149 .flush_buffer = rfcomm_tty_flush_buffer,
1150 .ioctl = rfcomm_tty_ioctl,
1151 .throttle = rfcomm_tty_throttle,
1152 .unthrottle = rfcomm_tty_unthrottle,
1153 .set_termios = rfcomm_tty_set_termios,
1154 .send_xchar = rfcomm_tty_send_xchar,
1155 .hangup = rfcomm_tty_hangup,
1156 .wait_until_sent = rfcomm_tty_wait_until_sent,
1157 .read_proc = rfcomm_tty_read_proc,
1158 .tiocmget = rfcomm_tty_tiocmget,
1159 .tiocmset = rfcomm_tty_tiocmset,
1160};
1161
1162int rfcomm_init_ttys(void)
1163{
1164 rfcomm_tty_driver = alloc_tty_driver(RFCOMM_TTY_PORTS);
1165 if (!rfcomm_tty_driver)
1166 return -1;
1167
1168 rfcomm_tty_driver->owner = THIS_MODULE;
1169 rfcomm_tty_driver->driver_name = "rfcomm";
Linus Torvalds1da177e2005-04-16 15:20:36 -07001170 rfcomm_tty_driver->name = "rfcomm";
1171 rfcomm_tty_driver->major = RFCOMM_TTY_MAJOR;
1172 rfcomm_tty_driver->minor_start = RFCOMM_TTY_MINOR;
1173 rfcomm_tty_driver->type = TTY_DRIVER_TYPE_SERIAL;
1174 rfcomm_tty_driver->subtype = SERIAL_TYPE_NORMAL;
Greg Kroah-Hartman331b8312005-06-20 21:15:16 -07001175 rfcomm_tty_driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001176 rfcomm_tty_driver->init_termios = tty_std_termios;
1177 rfcomm_tty_driver->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL;
Marcel Holtmannca37bdd2008-07-14 20:13:52 +02001178 rfcomm_tty_driver->init_termios.c_lflag &= ~ICANON;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001179 tty_set_operations(rfcomm_tty_driver, &rfcomm_ops);
1180
1181 if (tty_register_driver(rfcomm_tty_driver)) {
1182 BT_ERR("Can't register RFCOMM TTY driver");
1183 put_tty_driver(rfcomm_tty_driver);
1184 return -1;
1185 }
1186
1187 BT_INFO("RFCOMM TTY layer initialized");
1188
1189 return 0;
1190}
1191
1192void rfcomm_cleanup_ttys(void)
1193{
1194 tty_unregister_driver(rfcomm_tty_driver);
1195 put_tty_driver(rfcomm_tty_driver);
1196}