blob: e447651a2dbe86705a0ad35706b73d06928d8b94 [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.
26 *
27 * $Id: tty.c,v 1.24 2002/10/03 01:54:38 holtmann Exp $
28 */
29
Linus Torvalds1da177e2005-04-16 15:20:36 -070030#include <linux/module.h>
31
32#include <linux/tty.h>
33#include <linux/tty_driver.h>
34#include <linux/tty_flip.h>
35
Randy Dunlap4fc268d2006-01-11 12:17:47 -080036#include <linux/capability.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070037#include <linux/slab.h>
38#include <linux/skbuff.h>
39
40#include <net/bluetooth/bluetooth.h>
Marcel Holtmann0a85b962006-07-06 13:09:02 +020041#include <net/bluetooth/hci_core.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070042#include <net/bluetooth/rfcomm.h>
43
44#ifndef CONFIG_BT_RFCOMM_DEBUG
45#undef BT_DBG
46#define BT_DBG(D...)
47#endif
48
49#define RFCOMM_TTY_MAGIC 0x6d02 /* magic number for rfcomm struct */
50#define RFCOMM_TTY_PORTS RFCOMM_MAX_DEV /* whole lotta rfcomm devices */
51#define RFCOMM_TTY_MAJOR 216 /* device node major id of the usb/bluetooth.c driver */
52#define RFCOMM_TTY_MINOR 0
53
54static struct tty_driver *rfcomm_tty_driver;
55
56struct rfcomm_dev {
57 struct list_head list;
58 atomic_t refcnt;
59
60 char name[12];
61 int id;
62 unsigned long flags;
63 int opened;
64 int err;
65
66 bdaddr_t src;
67 bdaddr_t dst;
68 u8 channel;
69
70 uint modem_status;
71
72 struct rfcomm_dlc *dlc;
73 struct tty_struct *tty;
74 wait_queue_head_t wait;
75 struct tasklet_struct wakeup_task;
76
Marcel Holtmannc1a33132007-02-17 23:58:57 +010077 struct device *tty_dev;
78
Linus Torvalds1da177e2005-04-16 15:20:36 -070079 atomic_t wmem_alloc;
80};
81
82static LIST_HEAD(rfcomm_dev_list);
83static DEFINE_RWLOCK(rfcomm_dev_lock);
84
85static void rfcomm_dev_data_ready(struct rfcomm_dlc *dlc, struct sk_buff *skb);
86static void rfcomm_dev_state_change(struct rfcomm_dlc *dlc, int err);
87static void rfcomm_dev_modem_status(struct rfcomm_dlc *dlc, u8 v24_sig);
88
89static void rfcomm_tty_wakeup(unsigned long arg);
90
91/* ---- Device functions ---- */
92static void rfcomm_dev_destruct(struct rfcomm_dev *dev)
93{
94 struct rfcomm_dlc *dlc = dev->dlc;
95
96 BT_DBG("dev %p dlc %p", dev, dlc);
97
Ville Tervo8de0a152007-07-11 09:23:41 +020098 write_lock_bh(&rfcomm_dev_lock);
99 list_del_init(&dev->list);
100 write_unlock_bh(&rfcomm_dev_lock);
101
Linus Torvalds1da177e2005-04-16 15:20:36 -0700102 rfcomm_dlc_lock(dlc);
103 /* Detach DLC if it's owned by this dev */
104 if (dlc->owner == dev)
105 dlc->owner = NULL;
106 rfcomm_dlc_unlock(dlc);
107
108 rfcomm_dlc_put(dlc);
109
110 tty_unregister_device(rfcomm_tty_driver, dev->id);
111
112 /* Refcount should only hit zero when called from rfcomm_dev_del()
113 which will have taken us off the list. Everything else are
114 refcounting bugs. */
115 BUG_ON(!list_empty(&dev->list));
116
117 kfree(dev);
118
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900119 /* It's safe to call module_put() here because socket still
Linus Torvalds1da177e2005-04-16 15:20:36 -0700120 holds reference to this module. */
121 module_put(THIS_MODULE);
122}
123
124static inline void rfcomm_dev_hold(struct rfcomm_dev *dev)
125{
126 atomic_inc(&dev->refcnt);
127}
128
129static inline void rfcomm_dev_put(struct rfcomm_dev *dev)
130{
131 /* The reason this isn't actually a race, as you no
132 doubt have a little voice screaming at you in your
133 head, is that the refcount should never actually
134 reach zero unless the device has already been taken
135 off the list, in rfcomm_dev_del(). And if that's not
136 true, we'll hit the BUG() in rfcomm_dev_destruct()
137 anyway. */
138 if (atomic_dec_and_test(&dev->refcnt))
139 rfcomm_dev_destruct(dev);
140}
141
142static struct rfcomm_dev *__rfcomm_dev_get(int id)
143{
144 struct rfcomm_dev *dev;
145 struct list_head *p;
146
147 list_for_each(p, &rfcomm_dev_list) {
148 dev = list_entry(p, struct rfcomm_dev, list);
149 if (dev->id == id)
150 return dev;
151 }
152
153 return NULL;
154}
155
156static inline struct rfcomm_dev *rfcomm_dev_get(int id)
157{
158 struct rfcomm_dev *dev;
159
160 read_lock(&rfcomm_dev_lock);
161
162 dev = __rfcomm_dev_get(id);
Ville Tervo8de0a152007-07-11 09:23:41 +0200163
164 if (dev) {
165 if (test_bit(RFCOMM_TTY_RELEASED, &dev->flags))
166 dev = NULL;
167 else
168 rfcomm_dev_hold(dev);
169 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700170
171 read_unlock(&rfcomm_dev_lock);
172
173 return dev;
174}
175
Marcel Holtmann0a85b962006-07-06 13:09:02 +0200176static struct device *rfcomm_get_device(struct rfcomm_dev *dev)
177{
178 struct hci_dev *hdev;
179 struct hci_conn *conn;
180
181 hdev = hci_get_route(&dev->dst, &dev->src);
182 if (!hdev)
183 return NULL;
184
185 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &dev->dst);
Marcel Holtmann0a85b962006-07-06 13:09:02 +0200186
187 hci_dev_put(hdev);
188
Marcel Holtmannb2cfcd72006-10-15 17:31:05 +0200189 return conn ? &conn->dev : NULL;
Marcel Holtmann0a85b962006-07-06 13:09:02 +0200190}
191
Marcel Holtmanndae6a0f2007-10-20 14:52:38 +0200192static ssize_t show_address(struct device *tty_dev, struct device_attribute *attr, char *buf)
193{
194 struct rfcomm_dev *dev = dev_get_drvdata(tty_dev);
195 bdaddr_t bdaddr;
196 baswap(&bdaddr, &dev->dst);
197 return sprintf(buf, "%s\n", batostr(&bdaddr));
198}
199
200static ssize_t show_channel(struct device *tty_dev, struct device_attribute *attr, char *buf)
201{
202 struct rfcomm_dev *dev = dev_get_drvdata(tty_dev);
203 return sprintf(buf, "%d\n", dev->channel);
204}
205
206static DEVICE_ATTR(address, S_IRUGO, show_address, NULL);
207static DEVICE_ATTR(channel, S_IRUGO, show_channel, NULL);
208
Linus Torvalds1da177e2005-04-16 15:20:36 -0700209static int rfcomm_dev_add(struct rfcomm_dev_req *req, struct rfcomm_dlc *dlc)
210{
211 struct rfcomm_dev *dev;
212 struct list_head *head = &rfcomm_dev_list, *p;
213 int err = 0;
214
215 BT_DBG("id %d channel %d", req->dev_id, req->channel);
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900216
Marcel Holtmann25ea6db2006-07-06 15:40:09 +0200217 dev = kzalloc(sizeof(struct rfcomm_dev), GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700218 if (!dev)
219 return -ENOMEM;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700220
221 write_lock_bh(&rfcomm_dev_lock);
222
223 if (req->dev_id < 0) {
224 dev->id = 0;
225
226 list_for_each(p, &rfcomm_dev_list) {
227 if (list_entry(p, struct rfcomm_dev, list)->id != dev->id)
228 break;
229
230 dev->id++;
231 head = p;
232 }
233 } else {
234 dev->id = req->dev_id;
235
236 list_for_each(p, &rfcomm_dev_list) {
237 struct rfcomm_dev *entry = list_entry(p, struct rfcomm_dev, list);
238
239 if (entry->id == dev->id) {
240 err = -EADDRINUSE;
241 goto out;
242 }
243
244 if (entry->id > dev->id - 1)
245 break;
246
247 head = p;
248 }
249 }
250
251 if ((dev->id < 0) || (dev->id > RFCOMM_MAX_DEV - 1)) {
252 err = -ENFILE;
253 goto out;
254 }
255
256 sprintf(dev->name, "rfcomm%d", dev->id);
257
258 list_add(&dev->list, head);
259 atomic_set(&dev->refcnt, 1);
260
261 bacpy(&dev->src, &req->src);
262 bacpy(&dev->dst, &req->dst);
263 dev->channel = req->channel;
264
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900265 dev->flags = req->flags &
Linus Torvalds1da177e2005-04-16 15:20:36 -0700266 ((1 << RFCOMM_RELEASE_ONHUP) | (1 << RFCOMM_REUSE_DLC));
267
268 init_waitqueue_head(&dev->wait);
269 tasklet_init(&dev->wakeup_task, rfcomm_tty_wakeup, (unsigned long) dev);
270
271 rfcomm_dlc_lock(dlc);
272 dlc->data_ready = rfcomm_dev_data_ready;
273 dlc->state_change = rfcomm_dev_state_change;
274 dlc->modem_status = rfcomm_dev_modem_status;
275
276 dlc->owner = dev;
277 dev->dlc = dlc;
278 rfcomm_dlc_unlock(dlc);
279
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900280 /* It's safe to call __module_get() here because socket already
Linus Torvalds1da177e2005-04-16 15:20:36 -0700281 holds reference to this module. */
282 __module_get(THIS_MODULE);
283
284out:
285 write_unlock_bh(&rfcomm_dev_lock);
286
Marcel Holtmann09c7d822007-07-26 00:12:25 -0700287 if (err < 0) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700288 kfree(dev);
289 return err;
290 }
291
Marcel Holtmannc1a33132007-02-17 23:58:57 +0100292 dev->tty_dev = tty_register_device(rfcomm_tty_driver, dev->id, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700293
Ville Tervo8de0a152007-07-11 09:23:41 +0200294 if (IS_ERR(dev->tty_dev)) {
Marcel Holtmann09c7d822007-07-26 00:12:25 -0700295 err = PTR_ERR(dev->tty_dev);
Ville Tervo8de0a152007-07-11 09:23:41 +0200296 list_del(&dev->list);
297 kfree(dev);
Marcel Holtmann09c7d822007-07-26 00:12:25 -0700298 return err;
Ville Tervo8de0a152007-07-11 09:23:41 +0200299 }
300
Marcel Holtmanndae6a0f2007-10-20 14:52:38 +0200301 dev_set_drvdata(dev->tty_dev, dev);
302
303 if (device_create_file(dev->tty_dev, &dev_attr_address) < 0)
304 BT_ERR("Failed to create address attribute");
305
306 if (device_create_file(dev->tty_dev, &dev_attr_channel) < 0)
307 BT_ERR("Failed to create channel attribute");
308
Linus Torvalds1da177e2005-04-16 15:20:36 -0700309 return dev->id;
310}
311
312static void rfcomm_dev_del(struct rfcomm_dev *dev)
313{
314 BT_DBG("dev %p", dev);
315
Ville Tervo8de0a152007-07-11 09:23:41 +0200316 set_bit(RFCOMM_TTY_RELEASED, &dev->flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700317 rfcomm_dev_put(dev);
318}
319
320/* ---- Send buffer ---- */
321static inline unsigned int rfcomm_room(struct rfcomm_dlc *dlc)
322{
323 /* We can't let it be zero, because we don't get a callback
324 when tx_credits becomes nonzero, hence we'd never wake up */
325 return dlc->mtu * (dlc->tx_credits?:1);
326}
327
328static void rfcomm_wfree(struct sk_buff *skb)
329{
330 struct rfcomm_dev *dev = (void *) skb->sk;
331 atomic_sub(skb->truesize, &dev->wmem_alloc);
332 if (test_bit(RFCOMM_TTY_ATTACHED, &dev->flags))
333 tasklet_schedule(&dev->wakeup_task);
334 rfcomm_dev_put(dev);
335}
336
337static inline void rfcomm_set_owner_w(struct sk_buff *skb, struct rfcomm_dev *dev)
338{
339 rfcomm_dev_hold(dev);
340 atomic_add(skb->truesize, &dev->wmem_alloc);
341 skb->sk = (void *) dev;
342 skb->destructor = rfcomm_wfree;
343}
344
Al Virodd0fc662005-10-07 07:46:04 +0100345static struct sk_buff *rfcomm_wmalloc(struct rfcomm_dev *dev, unsigned long size, gfp_t priority)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700346{
347 if (atomic_read(&dev->wmem_alloc) < rfcomm_room(dev->dlc)) {
348 struct sk_buff *skb = alloc_skb(size, priority);
349 if (skb) {
350 rfcomm_set_owner_w(skb, dev);
351 return skb;
352 }
353 }
354 return NULL;
355}
356
357/* ---- Device IOCTLs ---- */
358
359#define NOCAP_FLAGS ((1 << RFCOMM_REUSE_DLC) | (1 << RFCOMM_RELEASE_ONHUP))
360
361static int rfcomm_create_dev(struct sock *sk, void __user *arg)
362{
363 struct rfcomm_dev_req req;
364 struct rfcomm_dlc *dlc;
365 int id;
366
367 if (copy_from_user(&req, arg, sizeof(req)))
368 return -EFAULT;
369
Ville Tervo8de0a152007-07-11 09:23:41 +0200370 BT_DBG("sk %p dev_id %d flags 0x%x", sk, req.dev_id, req.flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700371
372 if (req.flags != NOCAP_FLAGS && !capable(CAP_NET_ADMIN))
373 return -EPERM;
374
375 if (req.flags & (1 << RFCOMM_REUSE_DLC)) {
376 /* Socket must be connected */
377 if (sk->sk_state != BT_CONNECTED)
378 return -EBADFD;
379
380 dlc = rfcomm_pi(sk)->dlc;
381 rfcomm_dlc_hold(dlc);
382 } else {
383 dlc = rfcomm_dlc_alloc(GFP_KERNEL);
384 if (!dlc)
385 return -ENOMEM;
386 }
387
388 id = rfcomm_dev_add(&req, dlc);
389 if (id < 0) {
390 rfcomm_dlc_put(dlc);
391 return id;
392 }
393
394 if (req.flags & (1 << RFCOMM_REUSE_DLC)) {
395 /* DLC is now used by device.
396 * Socket must be disconnected */
397 sk->sk_state = BT_CLOSED;
398 }
399
400 return id;
401}
402
403static int rfcomm_release_dev(void __user *arg)
404{
405 struct rfcomm_dev_req req;
406 struct rfcomm_dev *dev;
407
408 if (copy_from_user(&req, arg, sizeof(req)))
409 return -EFAULT;
410
Ville Tervo8de0a152007-07-11 09:23:41 +0200411 BT_DBG("dev_id %d flags 0x%x", req.dev_id, req.flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700412
413 if (!(dev = rfcomm_dev_get(req.dev_id)))
414 return -ENODEV;
415
416 if (dev->flags != NOCAP_FLAGS && !capable(CAP_NET_ADMIN)) {
417 rfcomm_dev_put(dev);
418 return -EPERM;
419 }
420
421 if (req.flags & (1 << RFCOMM_HANGUP_NOW))
422 rfcomm_dlc_close(dev->dlc, 0);
423
Mikko Rapeli84950cf2007-07-11 09:18:15 +0200424 /* Shut down TTY synchronously before freeing rfcomm_dev */
425 if (dev->tty)
426 tty_vhangup(dev->tty);
427
Linus Torvalds1da177e2005-04-16 15:20:36 -0700428 rfcomm_dev_del(dev);
429 rfcomm_dev_put(dev);
430 return 0;
431}
432
433static int rfcomm_get_dev_list(void __user *arg)
434{
435 struct rfcomm_dev_list_req *dl;
436 struct rfcomm_dev_info *di;
437 struct list_head *p;
438 int n = 0, size, err;
439 u16 dev_num;
440
441 BT_DBG("");
442
443 if (get_user(dev_num, (u16 __user *) arg))
444 return -EFAULT;
445
446 if (!dev_num || dev_num > (PAGE_SIZE * 4) / sizeof(*di))
447 return -EINVAL;
448
449 size = sizeof(*dl) + dev_num * sizeof(*di);
450
451 if (!(dl = kmalloc(size, GFP_KERNEL)))
452 return -ENOMEM;
453
454 di = dl->dev_info;
455
456 read_lock_bh(&rfcomm_dev_lock);
457
458 list_for_each(p, &rfcomm_dev_list) {
459 struct rfcomm_dev *dev = list_entry(p, struct rfcomm_dev, list);
Ville Tervo8de0a152007-07-11 09:23:41 +0200460 if (test_bit(RFCOMM_TTY_RELEASED, &dev->flags))
461 continue;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700462 (di + n)->id = dev->id;
463 (di + n)->flags = dev->flags;
464 (di + n)->state = dev->dlc->state;
465 (di + n)->channel = dev->channel;
466 bacpy(&(di + n)->src, &dev->src);
467 bacpy(&(di + n)->dst, &dev->dst);
468 if (++n >= dev_num)
469 break;
470 }
471
472 read_unlock_bh(&rfcomm_dev_lock);
473
474 dl->dev_num = n;
475 size = sizeof(*dl) + n * sizeof(*di);
476
477 err = copy_to_user(arg, dl, size);
478 kfree(dl);
479
480 return err ? -EFAULT : 0;
481}
482
483static int rfcomm_get_dev_info(void __user *arg)
484{
485 struct rfcomm_dev *dev;
486 struct rfcomm_dev_info di;
487 int err = 0;
488
489 BT_DBG("");
490
491 if (copy_from_user(&di, arg, sizeof(di)))
492 return -EFAULT;
493
494 if (!(dev = rfcomm_dev_get(di.id)))
495 return -ENODEV;
496
497 di.flags = dev->flags;
498 di.channel = dev->channel;
499 di.state = dev->dlc->state;
500 bacpy(&di.src, &dev->src);
501 bacpy(&di.dst, &dev->dst);
502
503 if (copy_to_user(arg, &di, sizeof(di)))
504 err = -EFAULT;
505
506 rfcomm_dev_put(dev);
507 return err;
508}
509
510int rfcomm_dev_ioctl(struct sock *sk, unsigned int cmd, void __user *arg)
511{
512 BT_DBG("cmd %d arg %p", cmd, arg);
513
514 switch (cmd) {
515 case RFCOMMCREATEDEV:
516 return rfcomm_create_dev(sk, arg);
517
518 case RFCOMMRELEASEDEV:
519 return rfcomm_release_dev(arg);
520
521 case RFCOMMGETDEVLIST:
522 return rfcomm_get_dev_list(arg);
523
524 case RFCOMMGETDEVINFO:
525 return rfcomm_get_dev_info(arg);
526 }
527
528 return -EINVAL;
529}
530
531/* ---- DLC callbacks ---- */
532static void rfcomm_dev_data_ready(struct rfcomm_dlc *dlc, struct sk_buff *skb)
533{
534 struct rfcomm_dev *dev = dlc->owner;
535 struct tty_struct *tty;
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900536
Linus Torvalds1da177e2005-04-16 15:20:36 -0700537 if (!dev || !(tty = dev->tty)) {
538 kfree_skb(skb);
539 return;
540 }
541
542 BT_DBG("dlc %p tty %p len %d", dlc, tty, skb->len);
543
Paul Fulghum817d6d32006-06-28 04:26:47 -0700544 tty_insert_flip_string(tty, skb->data, skb->len);
545 tty_flip_buffer_push(tty);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700546
547 kfree_skb(skb);
548}
549
550static void rfcomm_dev_state_change(struct rfcomm_dlc *dlc, int err)
551{
552 struct rfcomm_dev *dev = dlc->owner;
553 if (!dev)
554 return;
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900555
Linus Torvalds1da177e2005-04-16 15:20:36 -0700556 BT_DBG("dlc %p dev %p err %d", dlc, dev, err);
557
558 dev->err = err;
559 wake_up_interruptible(&dev->wait);
560
561 if (dlc->state == BT_CLOSED) {
562 if (!dev->tty) {
563 if (test_bit(RFCOMM_RELEASE_ONHUP, &dev->flags)) {
Marcel Holtmann77f2a452007-05-05 00:36:10 +0200564 if (rfcomm_dev_get(dev->id) == NULL)
565 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700566
Marcel Holtmann77f2a452007-05-05 00:36:10 +0200567 rfcomm_dev_del(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700568 /* We have to drop DLC lock here, otherwise
569 rfcomm_dev_put() will dead lock if it's
570 the last reference. */
571 rfcomm_dlc_unlock(dlc);
572 rfcomm_dev_put(dev);
573 rfcomm_dlc_lock(dlc);
574 }
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900575 } else
Linus Torvalds1da177e2005-04-16 15:20:36 -0700576 tty_hangup(dev->tty);
577 }
578}
579
580static void rfcomm_dev_modem_status(struct rfcomm_dlc *dlc, u8 v24_sig)
581{
582 struct rfcomm_dev *dev = dlc->owner;
583 if (!dev)
584 return;
Timo Teräs7b9eb9e2005-08-09 20:28:21 -0700585
Linus Torvalds1da177e2005-04-16 15:20:36 -0700586 BT_DBG("dlc %p dev %p v24_sig 0x%02x", dlc, dev, v24_sig);
587
Timo Teräs7b9eb9e2005-08-09 20:28:21 -0700588 if ((dev->modem_status & TIOCM_CD) && !(v24_sig & RFCOMM_V24_DV)) {
589 if (dev->tty && !C_CLOCAL(dev->tty))
590 tty_hangup(dev->tty);
591 }
592
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900593 dev->modem_status =
Linus Torvalds1da177e2005-04-16 15:20:36 -0700594 ((v24_sig & RFCOMM_V24_RTC) ? (TIOCM_DSR | TIOCM_DTR) : 0) |
595 ((v24_sig & RFCOMM_V24_RTR) ? (TIOCM_RTS | TIOCM_CTS) : 0) |
596 ((v24_sig & RFCOMM_V24_IC) ? TIOCM_RI : 0) |
597 ((v24_sig & RFCOMM_V24_DV) ? TIOCM_CD : 0);
598}
599
600/* ---- TTY functions ---- */
601static void rfcomm_tty_wakeup(unsigned long arg)
602{
603 struct rfcomm_dev *dev = (void *) arg;
604 struct tty_struct *tty = dev->tty;
605 if (!tty)
606 return;
607
608 BT_DBG("dev %p tty %p", dev, tty);
609
610 if (test_bit(TTY_DO_WRITE_WAKEUP, &tty->flags) && tty->ldisc.write_wakeup)
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900611 (tty->ldisc.write_wakeup)(tty);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700612
613 wake_up_interruptible(&tty->write_wait);
614#ifdef SERIAL_HAVE_POLL_WAIT
615 wake_up_interruptible(&tty->poll_wait);
616#endif
617}
618
619static int rfcomm_tty_open(struct tty_struct *tty, struct file *filp)
620{
621 DECLARE_WAITQUEUE(wait, current);
622 struct rfcomm_dev *dev;
623 struct rfcomm_dlc *dlc;
624 int err, id;
625
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900626 id = tty->index;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700627
628 BT_DBG("tty %p id %d", tty, id);
629
630 /* We don't leak this refcount. For reasons which are not entirely
631 clear, the TTY layer will call our ->close() method even if the
632 open fails. We decrease the refcount there, and decreasing it
633 here too would cause breakage. */
634 dev = rfcomm_dev_get(id);
635 if (!dev)
636 return -ENODEV;
637
638 BT_DBG("dev %p dst %s channel %d opened %d", dev, batostr(&dev->dst), dev->channel, dev->opened);
639
640 if (dev->opened++ != 0)
641 return 0;
642
643 dlc = dev->dlc;
644
645 /* Attach TTY and open DLC */
646
647 rfcomm_dlc_lock(dlc);
648 tty->driver_data = dev;
649 dev->tty = tty;
650 rfcomm_dlc_unlock(dlc);
651 set_bit(RFCOMM_TTY_ATTACHED, &dev->flags);
652
653 err = rfcomm_dlc_open(dlc, &dev->src, &dev->dst, dev->channel);
654 if (err < 0)
655 return err;
656
657 /* Wait for DLC to connect */
658 add_wait_queue(&dev->wait, &wait);
659 while (1) {
660 set_current_state(TASK_INTERRUPTIBLE);
661
662 if (dlc->state == BT_CLOSED) {
663 err = -dev->err;
664 break;
665 }
666
667 if (dlc->state == BT_CONNECTED)
668 break;
669
670 if (signal_pending(current)) {
671 err = -EINTR;
672 break;
673 }
674
675 schedule();
676 }
677 set_current_state(TASK_RUNNING);
678 remove_wait_queue(&dev->wait, &wait);
679
Marcel Holtmannc1a33132007-02-17 23:58:57 +0100680 if (err == 0)
681 device_move(dev->tty_dev, rfcomm_get_device(dev));
682
Linus Torvalds1da177e2005-04-16 15:20:36 -0700683 return err;
684}
685
686static void rfcomm_tty_close(struct tty_struct *tty, struct file *filp)
687{
688 struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data;
689 if (!dev)
690 return;
691
692 BT_DBG("tty %p dev %p dlc %p opened %d", tty, dev, dev->dlc, dev->opened);
693
694 if (--dev->opened == 0) {
Marcel Holtmannc1a33132007-02-17 23:58:57 +0100695 device_move(dev->tty_dev, NULL);
696
Linus Torvalds1da177e2005-04-16 15:20:36 -0700697 /* Close DLC and dettach TTY */
698 rfcomm_dlc_close(dev->dlc, 0);
699
700 clear_bit(RFCOMM_TTY_ATTACHED, &dev->flags);
701 tasklet_kill(&dev->wakeup_task);
702
703 rfcomm_dlc_lock(dev->dlc);
704 tty->driver_data = NULL;
705 dev->tty = NULL;
706 rfcomm_dlc_unlock(dev->dlc);
707 }
708
709 rfcomm_dev_put(dev);
710}
711
712static int rfcomm_tty_write(struct tty_struct *tty, const unsigned char *buf, int count)
713{
714 struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data;
715 struct rfcomm_dlc *dlc = dev->dlc;
716 struct sk_buff *skb;
717 int err = 0, sent = 0, size;
718
719 BT_DBG("tty %p count %d", tty, count);
720
721 while (count) {
722 size = min_t(uint, count, dlc->mtu);
723
724 skb = rfcomm_wmalloc(dev, size + RFCOMM_SKB_RESERVE, GFP_ATOMIC);
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900725
Linus Torvalds1da177e2005-04-16 15:20:36 -0700726 if (!skb)
727 break;
728
729 skb_reserve(skb, RFCOMM_SKB_HEAD_RESERVE);
730
731 memcpy(skb_put(skb, size), buf + sent, size);
732
733 if ((err = rfcomm_dlc_send(dlc, skb)) < 0) {
734 kfree_skb(skb);
735 break;
736 }
737
738 sent += size;
739 count -= size;
740 }
741
742 return sent ? sent : err;
743}
744
745static int rfcomm_tty_write_room(struct tty_struct *tty)
746{
747 struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data;
748 int room;
749
750 BT_DBG("tty %p", tty);
751
Marcel Holtmannb6e557f2007-01-08 02:16:27 +0100752 if (!dev || !dev->dlc)
753 return 0;
754
Linus Torvalds1da177e2005-04-16 15:20:36 -0700755 room = rfcomm_room(dev->dlc) - atomic_read(&dev->wmem_alloc);
756 if (room < 0)
757 room = 0;
Marcel Holtmannb6e557f2007-01-08 02:16:27 +0100758
Linus Torvalds1da177e2005-04-16 15:20:36 -0700759 return room;
760}
761
762static int rfcomm_tty_ioctl(struct tty_struct *tty, struct file *filp, unsigned int cmd, unsigned long arg)
763{
764 BT_DBG("tty %p cmd 0x%02x", tty, cmd);
765
766 switch (cmd) {
767 case TCGETS:
768 BT_DBG("TCGETS is not supported");
769 return -ENOIOCTLCMD;
770
771 case TCSETS:
772 BT_DBG("TCSETS is not supported");
773 return -ENOIOCTLCMD;
774
775 case TIOCMIWAIT:
776 BT_DBG("TIOCMIWAIT");
777 break;
778
779 case TIOCGICOUNT:
780 BT_DBG("TIOCGICOUNT");
781 break;
782
783 case TIOCGSERIAL:
784 BT_ERR("TIOCGSERIAL is not supported");
785 return -ENOIOCTLCMD;
786
787 case TIOCSSERIAL:
788 BT_ERR("TIOCSSERIAL is not supported");
789 return -ENOIOCTLCMD;
790
791 case TIOCSERGSTRUCT:
792 BT_ERR("TIOCSERGSTRUCT is not supported");
793 return -ENOIOCTLCMD;
794
795 case TIOCSERGETLSR:
796 BT_ERR("TIOCSERGETLSR is not supported");
797 return -ENOIOCTLCMD;
798
799 case TIOCSERCONFIG:
800 BT_ERR("TIOCSERCONFIG is not supported");
801 return -ENOIOCTLCMD;
802
803 default:
804 return -ENOIOCTLCMD; /* ioctls which we must ignore */
805
806 }
807
808 return -ENOIOCTLCMD;
809}
810
Alan Cox606d0992006-12-08 02:38:45 -0800811static void rfcomm_tty_set_termios(struct tty_struct *tty, struct ktermios *old)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700812{
Alan Cox606d0992006-12-08 02:38:45 -0800813 struct ktermios *new = tty->termios;
J. Suter3a5e9032005-08-09 20:28:46 -0700814 int old_baud_rate = tty_termios_baud_rate(old);
815 int new_baud_rate = tty_termios_baud_rate(new);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700816
J. Suter3a5e9032005-08-09 20:28:46 -0700817 u8 baud, data_bits, stop_bits, parity, x_on, x_off;
818 u16 changes = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700819
J. Suter3a5e9032005-08-09 20:28:46 -0700820 struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data;
821
822 BT_DBG("tty %p termios %p", tty, old);
823
Marcel Holtmannff2d3672006-11-18 22:14:42 +0100824 if (!dev || !dev->dlc || !dev->dlc->session)
Marcel Holtmanncb19d9e2006-10-15 17:31:10 +0200825 return;
826
J. Suter3a5e9032005-08-09 20:28:46 -0700827 /* Handle turning off CRTSCTS */
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900828 if ((old->c_cflag & CRTSCTS) && !(new->c_cflag & CRTSCTS))
J. Suter3a5e9032005-08-09 20:28:46 -0700829 BT_DBG("Turning off CRTSCTS unsupported");
830
831 /* Parity on/off and when on, odd/even */
832 if (((old->c_cflag & PARENB) != (new->c_cflag & PARENB)) ||
833 ((old->c_cflag & PARODD) != (new->c_cflag & PARODD)) ) {
834 changes |= RFCOMM_RPN_PM_PARITY;
835 BT_DBG("Parity change detected.");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700836 }
J. Suter3a5e9032005-08-09 20:28:46 -0700837
838 /* Mark and space parity are not supported! */
839 if (new->c_cflag & PARENB) {
840 if (new->c_cflag & PARODD) {
841 BT_DBG("Parity is ODD");
842 parity = RFCOMM_RPN_PARITY_ODD;
843 } else {
844 BT_DBG("Parity is EVEN");
845 parity = RFCOMM_RPN_PARITY_EVEN;
846 }
847 } else {
848 BT_DBG("Parity is OFF");
849 parity = RFCOMM_RPN_PARITY_NONE;
850 }
851
852 /* Setting the x_on / x_off characters */
853 if (old->c_cc[VSTOP] != new->c_cc[VSTOP]) {
854 BT_DBG("XOFF custom");
855 x_on = new->c_cc[VSTOP];
856 changes |= RFCOMM_RPN_PM_XON;
857 } else {
858 BT_DBG("XOFF default");
859 x_on = RFCOMM_RPN_XON_CHAR;
860 }
861
862 if (old->c_cc[VSTART] != new->c_cc[VSTART]) {
863 BT_DBG("XON custom");
864 x_off = new->c_cc[VSTART];
865 changes |= RFCOMM_RPN_PM_XOFF;
866 } else {
867 BT_DBG("XON default");
868 x_off = RFCOMM_RPN_XOFF_CHAR;
869 }
870
871 /* Handle setting of stop bits */
872 if ((old->c_cflag & CSTOPB) != (new->c_cflag & CSTOPB))
873 changes |= RFCOMM_RPN_PM_STOP;
874
875 /* POSIX does not support 1.5 stop bits and RFCOMM does not
876 * support 2 stop bits. So a request for 2 stop bits gets
877 * translated to 1.5 stop bits */
878 if (new->c_cflag & CSTOPB) {
879 stop_bits = RFCOMM_RPN_STOP_15;
880 } else {
881 stop_bits = RFCOMM_RPN_STOP_1;
882 }
883
884 /* Handle number of data bits [5-8] */
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900885 if ((old->c_cflag & CSIZE) != (new->c_cflag & CSIZE))
J. Suter3a5e9032005-08-09 20:28:46 -0700886 changes |= RFCOMM_RPN_PM_DATA;
887
888 switch (new->c_cflag & CSIZE) {
889 case CS5:
890 data_bits = RFCOMM_RPN_DATA_5;
891 break;
892 case CS6:
893 data_bits = RFCOMM_RPN_DATA_6;
894 break;
895 case CS7:
896 data_bits = RFCOMM_RPN_DATA_7;
897 break;
898 case CS8:
899 data_bits = RFCOMM_RPN_DATA_8;
900 break;
901 default:
902 data_bits = RFCOMM_RPN_DATA_8;
903 break;
904 }
905
906 /* Handle baudrate settings */
907 if (old_baud_rate != new_baud_rate)
908 changes |= RFCOMM_RPN_PM_BITRATE;
909
910 switch (new_baud_rate) {
911 case 2400:
912 baud = RFCOMM_RPN_BR_2400;
913 break;
914 case 4800:
915 baud = RFCOMM_RPN_BR_4800;
916 break;
917 case 7200:
918 baud = RFCOMM_RPN_BR_7200;
919 break;
920 case 9600:
921 baud = RFCOMM_RPN_BR_9600;
922 break;
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900923 case 19200:
J. Suter3a5e9032005-08-09 20:28:46 -0700924 baud = RFCOMM_RPN_BR_19200;
925 break;
926 case 38400:
927 baud = RFCOMM_RPN_BR_38400;
928 break;
929 case 57600:
930 baud = RFCOMM_RPN_BR_57600;
931 break;
932 case 115200:
933 baud = RFCOMM_RPN_BR_115200;
934 break;
935 case 230400:
936 baud = RFCOMM_RPN_BR_230400;
937 break;
938 default:
939 /* 9600 is standard accordinag to the RFCOMM specification */
940 baud = RFCOMM_RPN_BR_9600;
941 break;
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900942
J. Suter3a5e9032005-08-09 20:28:46 -0700943 }
944
945 if (changes)
946 rfcomm_send_rpn(dev->dlc->session, 1, dev->dlc->dlci, baud,
947 data_bits, stop_bits, parity,
948 RFCOMM_RPN_FLOW_NONE, x_on, x_off, changes);
949
950 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700951}
952
953static void rfcomm_tty_throttle(struct tty_struct *tty)
954{
955 struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data;
956
957 BT_DBG("tty %p dev %p", tty, dev);
J. Suter3a5e9032005-08-09 20:28:46 -0700958
Linus Torvalds1da177e2005-04-16 15:20:36 -0700959 rfcomm_dlc_throttle(dev->dlc);
960}
961
962static void rfcomm_tty_unthrottle(struct tty_struct *tty)
963{
964 struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data;
965
966 BT_DBG("tty %p dev %p", tty, dev);
J. Suter3a5e9032005-08-09 20:28:46 -0700967
Linus Torvalds1da177e2005-04-16 15:20:36 -0700968 rfcomm_dlc_unthrottle(dev->dlc);
969}
970
971static int rfcomm_tty_chars_in_buffer(struct tty_struct *tty)
972{
973 struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700974
975 BT_DBG("tty %p dev %p", tty, dev);
976
Marcel Holtmannb6e557f2007-01-08 02:16:27 +0100977 if (!dev || !dev->dlc)
978 return 0;
979
980 if (!skb_queue_empty(&dev->dlc->tx_queue))
981 return dev->dlc->mtu;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700982
983 return 0;
984}
985
986static void rfcomm_tty_flush_buffer(struct tty_struct *tty)
987{
988 struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700989
990 BT_DBG("tty %p dev %p", tty, dev);
991
Marcel Holtmannb6e557f2007-01-08 02:16:27 +0100992 if (!dev || !dev->dlc)
993 return;
994
Linus Torvalds1da177e2005-04-16 15:20:36 -0700995 skb_queue_purge(&dev->dlc->tx_queue);
996
997 if (test_bit(TTY_DO_WRITE_WAKEUP, &tty->flags) && tty->ldisc.write_wakeup)
998 tty->ldisc.write_wakeup(tty);
999}
1000
1001static void rfcomm_tty_send_xchar(struct tty_struct *tty, char ch)
1002{
1003 BT_DBG("tty %p ch %c", tty, ch);
1004}
1005
1006static void rfcomm_tty_wait_until_sent(struct tty_struct *tty, int timeout)
1007{
1008 BT_DBG("tty %p timeout %d", tty, timeout);
1009}
1010
1011static void rfcomm_tty_hangup(struct tty_struct *tty)
1012{
1013 struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001014
1015 BT_DBG("tty %p dev %p", tty, dev);
1016
Marcel Holtmannb6e557f2007-01-08 02:16:27 +01001017 if (!dev)
1018 return;
1019
Linus Torvalds1da177e2005-04-16 15:20:36 -07001020 rfcomm_tty_flush_buffer(tty);
1021
Marcel Holtmann77f2a452007-05-05 00:36:10 +02001022 if (test_bit(RFCOMM_RELEASE_ONHUP, &dev->flags)) {
1023 if (rfcomm_dev_get(dev->id) == NULL)
1024 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001025 rfcomm_dev_del(dev);
Marcel Holtmann77f2a452007-05-05 00:36:10 +02001026 rfcomm_dev_put(dev);
1027 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001028}
1029
1030static int rfcomm_tty_read_proc(char *buf, char **start, off_t offset, int len, int *eof, void *unused)
1031{
1032 return 0;
1033}
1034
1035static int rfcomm_tty_tiocmget(struct tty_struct *tty, struct file *filp)
1036{
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09001037 struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001038
1039 BT_DBG("tty %p dev %p", tty, dev);
1040
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09001041 return dev->modem_status;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001042}
1043
1044static int rfcomm_tty_tiocmset(struct tty_struct *tty, struct file *filp, unsigned int set, unsigned int clear)
1045{
J. Suter3a5e9032005-08-09 20:28:46 -07001046 struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data;
1047 struct rfcomm_dlc *dlc = dev->dlc;
1048 u8 v24_sig;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001049
1050 BT_DBG("tty %p dev %p set 0x%02x clear 0x%02x", tty, dev, set, clear);
1051
J. Suter3a5e9032005-08-09 20:28:46 -07001052 rfcomm_dlc_get_modem_status(dlc, &v24_sig);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001053
J. Suter3a5e9032005-08-09 20:28:46 -07001054 if (set & TIOCM_DSR || set & TIOCM_DTR)
1055 v24_sig |= RFCOMM_V24_RTC;
1056 if (set & TIOCM_RTS || set & TIOCM_CTS)
1057 v24_sig |= RFCOMM_V24_RTR;
1058 if (set & TIOCM_RI)
1059 v24_sig |= RFCOMM_V24_IC;
1060 if (set & TIOCM_CD)
1061 v24_sig |= RFCOMM_V24_DV;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001062
J. Suter3a5e9032005-08-09 20:28:46 -07001063 if (clear & TIOCM_DSR || clear & TIOCM_DTR)
1064 v24_sig &= ~RFCOMM_V24_RTC;
1065 if (clear & TIOCM_RTS || clear & TIOCM_CTS)
1066 v24_sig &= ~RFCOMM_V24_RTR;
1067 if (clear & TIOCM_RI)
1068 v24_sig &= ~RFCOMM_V24_IC;
1069 if (clear & TIOCM_CD)
1070 v24_sig &= ~RFCOMM_V24_DV;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001071
J. Suter3a5e9032005-08-09 20:28:46 -07001072 rfcomm_dlc_set_modem_status(dlc, v24_sig);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001073
J. Suter3a5e9032005-08-09 20:28:46 -07001074 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001075}
1076
1077/* ---- TTY structure ---- */
1078
Jeff Dikeb68e31d2006-10-02 02:17:18 -07001079static const struct tty_operations rfcomm_ops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001080 .open = rfcomm_tty_open,
1081 .close = rfcomm_tty_close,
1082 .write = rfcomm_tty_write,
1083 .write_room = rfcomm_tty_write_room,
1084 .chars_in_buffer = rfcomm_tty_chars_in_buffer,
1085 .flush_buffer = rfcomm_tty_flush_buffer,
1086 .ioctl = rfcomm_tty_ioctl,
1087 .throttle = rfcomm_tty_throttle,
1088 .unthrottle = rfcomm_tty_unthrottle,
1089 .set_termios = rfcomm_tty_set_termios,
1090 .send_xchar = rfcomm_tty_send_xchar,
1091 .hangup = rfcomm_tty_hangup,
1092 .wait_until_sent = rfcomm_tty_wait_until_sent,
1093 .read_proc = rfcomm_tty_read_proc,
1094 .tiocmget = rfcomm_tty_tiocmget,
1095 .tiocmset = rfcomm_tty_tiocmset,
1096};
1097
1098int rfcomm_init_ttys(void)
1099{
1100 rfcomm_tty_driver = alloc_tty_driver(RFCOMM_TTY_PORTS);
1101 if (!rfcomm_tty_driver)
1102 return -1;
1103
1104 rfcomm_tty_driver->owner = THIS_MODULE;
1105 rfcomm_tty_driver->driver_name = "rfcomm";
Linus Torvalds1da177e2005-04-16 15:20:36 -07001106 rfcomm_tty_driver->name = "rfcomm";
1107 rfcomm_tty_driver->major = RFCOMM_TTY_MAJOR;
1108 rfcomm_tty_driver->minor_start = RFCOMM_TTY_MINOR;
1109 rfcomm_tty_driver->type = TTY_DRIVER_TYPE_SERIAL;
1110 rfcomm_tty_driver->subtype = SERIAL_TYPE_NORMAL;
Greg Kroah-Hartman331b8312005-06-20 21:15:16 -07001111 rfcomm_tty_driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001112 rfcomm_tty_driver->init_termios = tty_std_termios;
1113 rfcomm_tty_driver->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL;
1114 tty_set_operations(rfcomm_tty_driver, &rfcomm_ops);
1115
1116 if (tty_register_driver(rfcomm_tty_driver)) {
1117 BT_ERR("Can't register RFCOMM TTY driver");
1118 put_tty_driver(rfcomm_tty_driver);
1119 return -1;
1120 }
1121
1122 BT_INFO("RFCOMM TTY layer initialized");
1123
1124 return 0;
1125}
1126
1127void rfcomm_cleanup_ttys(void)
1128{
1129 tty_unregister_driver(rfcomm_tty_driver);
1130 put_tty_driver(rfcomm_tty_driver);
1131}