aboutsummaryrefslogtreecommitdiffstats
path: root/net/bluetooth/rfcomm/tty.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/bluetooth/rfcomm/tty.c')
-rw-r--r--net/bluetooth/rfcomm/tty.c70
1 files changed, 58 insertions, 12 deletions
diff --git a/net/bluetooth/rfcomm/tty.c b/net/bluetooth/rfcomm/tty.c
index c9191871c1e0..d3340dd52bcf 100644
--- a/net/bluetooth/rfcomm/tty.c
+++ b/net/bluetooth/rfcomm/tty.c
@@ -23,8 +23,6 @@
23 23
24/* 24/*
25 * RFCOMM TTY. 25 * RFCOMM TTY.
26 *
27 * $Id: tty.c,v 1.24 2002/10/03 01:54:38 holtmann Exp $
28 */ 26 */
29 27
30#include <linux/module.h> 28#include <linux/module.h>
@@ -77,6 +75,8 @@ struct rfcomm_dev {
77 struct device *tty_dev; 75 struct device *tty_dev;
78 76
79 atomic_t wmem_alloc; 77 atomic_t wmem_alloc;
78
79 struct sk_buff_head pending;
80}; 80};
81 81
82static LIST_HEAD(rfcomm_dev_list); 82static LIST_HEAD(rfcomm_dev_list);
@@ -264,13 +264,34 @@ static int rfcomm_dev_add(struct rfcomm_dev_req *req, struct rfcomm_dlc *dlc)
264 init_waitqueue_head(&dev->wait); 264 init_waitqueue_head(&dev->wait);
265 tasklet_init(&dev->wakeup_task, rfcomm_tty_wakeup, (unsigned long) dev); 265 tasklet_init(&dev->wakeup_task, rfcomm_tty_wakeup, (unsigned long) dev);
266 266
267 skb_queue_head_init(&dev->pending);
268
267 rfcomm_dlc_lock(dlc); 269 rfcomm_dlc_lock(dlc);
270
271 if (req->flags & (1 << RFCOMM_REUSE_DLC)) {
272 struct sock *sk = dlc->owner;
273 struct sk_buff *skb;
274
275 BUG_ON(!sk);
276
277 rfcomm_dlc_throttle(dlc);
278
279 while ((skb = skb_dequeue(&sk->sk_receive_queue))) {
280 skb_orphan(skb);
281 skb_queue_tail(&dev->pending, skb);
282 atomic_sub(skb->len, &sk->sk_rmem_alloc);
283 }
284 }
285
268 dlc->data_ready = rfcomm_dev_data_ready; 286 dlc->data_ready = rfcomm_dev_data_ready;
269 dlc->state_change = rfcomm_dev_state_change; 287 dlc->state_change = rfcomm_dev_state_change;
270 dlc->modem_status = rfcomm_dev_modem_status; 288 dlc->modem_status = rfcomm_dev_modem_status;
271 289
272 dlc->owner = dev; 290 dlc->owner = dev;
273 dev->dlc = dlc; 291 dev->dlc = dlc;
292
293 rfcomm_dev_modem_status(dlc, dlc->remote_v24_sig);
294
274 rfcomm_dlc_unlock(dlc); 295 rfcomm_dlc_unlock(dlc);
275 296
276 /* It's safe to call __module_get() here because socket already 297 /* It's safe to call __module_get() here because socket already
@@ -539,11 +560,16 @@ static void rfcomm_dev_data_ready(struct rfcomm_dlc *dlc, struct sk_buff *skb)
539 struct rfcomm_dev *dev = dlc->owner; 560 struct rfcomm_dev *dev = dlc->owner;
540 struct tty_struct *tty; 561 struct tty_struct *tty;
541 562
542 if (!dev || !(tty = dev->tty)) { 563 if (!dev) {
543 kfree_skb(skb); 564 kfree_skb(skb);
544 return; 565 return;
545 } 566 }
546 567
568 if (!(tty = dev->tty) || !skb_queue_empty(&dev->pending)) {
569 skb_queue_tail(&dev->pending, skb);
570 return;
571 }
572
547 BT_DBG("dlc %p tty %p len %d", dlc, tty, skb->len); 573 BT_DBG("dlc %p tty %p len %d", dlc, tty, skb->len);
548 574
549 tty_insert_flip_string(tty, skb->data, skb->len); 575 tty_insert_flip_string(tty, skb->data, skb->len);
@@ -617,14 +643,31 @@ static void rfcomm_tty_wakeup(unsigned long arg)
617 return; 643 return;
618 644
619 BT_DBG("dev %p tty %p", dev, tty); 645 BT_DBG("dev %p tty %p", dev, tty);
646 tty_wakeup(tty);
647}
620 648
621 if (test_bit(TTY_DO_WRITE_WAKEUP, &tty->flags) && tty->ldisc.write_wakeup) 649static void rfcomm_tty_copy_pending(struct rfcomm_dev *dev)
622 (tty->ldisc.write_wakeup)(tty); 650{
651 struct tty_struct *tty = dev->tty;
652 struct sk_buff *skb;
653 int inserted = 0;
623 654
624 wake_up_interruptible(&tty->write_wait); 655 if (!tty)
625#ifdef SERIAL_HAVE_POLL_WAIT 656 return;
626 wake_up_interruptible(&tty->poll_wait); 657
627#endif 658 BT_DBG("dev %p tty %p", dev, tty);
659
660 rfcomm_dlc_lock(dev->dlc);
661
662 while ((skb = skb_dequeue(&dev->pending))) {
663 inserted += tty_insert_flip_string(tty, skb->data, skb->len);
664 kfree_skb(skb);
665 }
666
667 rfcomm_dlc_unlock(dev->dlc);
668
669 if (inserted > 0)
670 tty_flip_buffer_push(tty);
628} 671}
629 672
630static int rfcomm_tty_open(struct tty_struct *tty, struct file *filp) 673static int rfcomm_tty_open(struct tty_struct *tty, struct file *filp)
@@ -691,6 +734,10 @@ static int rfcomm_tty_open(struct tty_struct *tty, struct file *filp)
691 if (err == 0) 734 if (err == 0)
692 device_move(dev->tty_dev, rfcomm_get_device(dev)); 735 device_move(dev->tty_dev, rfcomm_get_device(dev));
693 736
737 rfcomm_tty_copy_pending(dev);
738
739 rfcomm_dlc_unthrottle(dev->dlc);
740
694 return err; 741 return err;
695} 742}
696 743
@@ -1005,9 +1052,7 @@ static void rfcomm_tty_flush_buffer(struct tty_struct *tty)
1005 return; 1052 return;
1006 1053
1007 skb_queue_purge(&dev->dlc->tx_queue); 1054 skb_queue_purge(&dev->dlc->tx_queue);
1008 1055 tty_wakeup(tty);
1009 if (test_bit(TTY_DO_WRITE_WAKEUP, &tty->flags) && tty->ldisc.write_wakeup)
1010 tty->ldisc.write_wakeup(tty);
1011} 1056}
1012 1057
1013static void rfcomm_tty_send_xchar(struct tty_struct *tty, char ch) 1058static void rfcomm_tty_send_xchar(struct tty_struct *tty, char ch)
@@ -1123,6 +1168,7 @@ int rfcomm_init_ttys(void)
1123 rfcomm_tty_driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV; 1168 rfcomm_tty_driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV;
1124 rfcomm_tty_driver->init_termios = tty_std_termios; 1169 rfcomm_tty_driver->init_termios = tty_std_termios;
1125 rfcomm_tty_driver->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL; 1170 rfcomm_tty_driver->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL;
1171 rfcomm_tty_driver->init_termios.c_lflag &= ~ICANON;
1126 tty_set_operations(rfcomm_tty_driver, &rfcomm_ops); 1172 tty_set_operations(rfcomm_tty_driver, &rfcomm_ops);
1127 1173
1128 if (tty_register_driver(rfcomm_tty_driver)) { 1174 if (tty_register_driver(rfcomm_tty_driver)) {