aboutsummaryrefslogtreecommitdiffstats
path: root/net/bluetooth
diff options
context:
space:
mode:
authorPeter Hurley <peter@hurleysoftware.com>2014-02-09 20:59:22 -0500
committerMarcel Holtmann <marcel@holtmann.org>2014-02-14 16:39:32 -0500
commit72e5108c6d637ea2f4c0e64b09621a79f363b664 (patch)
tree9d1475b02d828725aeb80f0366d50c77aa5c2bb3 /net/bluetooth
parent5326a4ee982703ddba14a9821fe5cb10d122e1b0 (diff)
Bluetooth: Don't fail RFCOMM tty writes
The tty driver api design prefers no-fail writes if the driver write_room() method has previously indicated space is available to accept writes. Since this is trivially possible for the RFCOMM tty driver, do so. Introduce rfcomm_dlc_send_noerror(), which queues but does not schedule the krfcomm thread if the dlc is not yet connected (and thus does not error based on the connection state). The mtu size test is also unnecessary since the caller already chunks the written data into mtu size. Signed-off-by: Peter Hurley <peter@hurleysoftware.com> Tested-By: Alexander Holler <holler@ahsoftware.de> Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
Diffstat (limited to 'net/bluetooth')
-rw-r--r--net/bluetooth/rfcomm/core.c14
-rw-r--r--net/bluetooth/rfcomm/tty.c23
2 files changed, 21 insertions, 16 deletions
diff --git a/net/bluetooth/rfcomm/core.c b/net/bluetooth/rfcomm/core.c
index b727cd97c5a2..21e15318937c 100644
--- a/net/bluetooth/rfcomm/core.c
+++ b/net/bluetooth/rfcomm/core.c
@@ -569,6 +569,20 @@ int rfcomm_dlc_send(struct rfcomm_dlc *d, struct sk_buff *skb)
569 return len; 569 return len;
570} 570}
571 571
572void rfcomm_dlc_send_noerror(struct rfcomm_dlc *d, struct sk_buff *skb)
573{
574 int len = skb->len;
575
576 BT_DBG("dlc %p mtu %d len %d", d, d->mtu, len);
577
578 rfcomm_make_uih(skb, d->addr);
579 skb_queue_tail(&d->tx_queue, skb);
580
581 if (d->state == BT_CONNECTED &&
582 !test_bit(RFCOMM_TX_THROTTLED, &d->flags))
583 rfcomm_schedule();
584}
585
572void __rfcomm_dlc_throttle(struct rfcomm_dlc *d) 586void __rfcomm_dlc_throttle(struct rfcomm_dlc *d)
573{ 587{
574 BT_DBG("dlc %p state %ld", d, d->state); 588 BT_DBG("dlc %p state %ld", d, d->state);
diff --git a/net/bluetooth/rfcomm/tty.c b/net/bluetooth/rfcomm/tty.c
index f6b9f0c4c29e..af775f35c019 100644
--- a/net/bluetooth/rfcomm/tty.c
+++ b/net/bluetooth/rfcomm/tty.c
@@ -374,14 +374,10 @@ static void rfcomm_set_owner_w(struct sk_buff *skb, struct rfcomm_dev *dev)
374 374
375static struct sk_buff *rfcomm_wmalloc(struct rfcomm_dev *dev, unsigned long size, gfp_t priority) 375static struct sk_buff *rfcomm_wmalloc(struct rfcomm_dev *dev, unsigned long size, gfp_t priority)
376{ 376{
377 if (atomic_read(&dev->wmem_alloc) < rfcomm_room(dev->dlc)) { 377 struct sk_buff *skb = alloc_skb(size, priority);
378 struct sk_buff *skb = alloc_skb(size, priority); 378 if (skb)
379 if (skb) { 379 rfcomm_set_owner_w(skb, dev);
380 rfcomm_set_owner_w(skb, dev); 380 return skb;
381 return skb;
382 }
383 }
384 return NULL;
385} 381}
386 382
387/* ---- Device IOCTLs ---- */ 383/* ---- Device IOCTLs ---- */
@@ -786,7 +782,7 @@ static int rfcomm_tty_write(struct tty_struct *tty, const unsigned char *buf, in
786 struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data; 782 struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data;
787 struct rfcomm_dlc *dlc = dev->dlc; 783 struct rfcomm_dlc *dlc = dev->dlc;
788 struct sk_buff *skb; 784 struct sk_buff *skb;
789 int err = 0, sent = 0, size; 785 int sent = 0, size;
790 786
791 BT_DBG("tty %p count %d", tty, count); 787 BT_DBG("tty %p count %d", tty, count);
792 788
@@ -794,7 +790,6 @@ static int rfcomm_tty_write(struct tty_struct *tty, const unsigned char *buf, in
794 size = min_t(uint, count, dlc->mtu); 790 size = min_t(uint, count, dlc->mtu);
795 791
796 skb = rfcomm_wmalloc(dev, size + RFCOMM_SKB_RESERVE, GFP_ATOMIC); 792 skb = rfcomm_wmalloc(dev, size + RFCOMM_SKB_RESERVE, GFP_ATOMIC);
797
798 if (!skb) 793 if (!skb)
799 break; 794 break;
800 795
@@ -802,17 +797,13 @@ static int rfcomm_tty_write(struct tty_struct *tty, const unsigned char *buf, in
802 797
803 memcpy(skb_put(skb, size), buf + sent, size); 798 memcpy(skb_put(skb, size), buf + sent, size);
804 799
805 err = rfcomm_dlc_send(dlc, skb); 800 rfcomm_dlc_send_noerror(dlc, skb);
806 if (err < 0) {
807 kfree_skb(skb);
808 break;
809 }
810 801
811 sent += size; 802 sent += size;
812 count -= size; 803 count -= size;
813 } 804 }
814 805
815 return sent ? sent : err; 806 return sent;
816} 807}
817 808
818static int rfcomm_tty_write_room(struct tty_struct *tty) 809static int rfcomm_tty_write_room(struct tty_struct *tty)