This commit was manufactured by cvs2svn to create tag
[linux-2.6.git] / net / bluetooth / rfcomm / tty.c
index 08907d3..ed8abef 100644 (file)
@@ -645,26 +645,32 @@ static void rfcomm_tty_close(struct tty_struct *tty, struct file *filp)
        rfcomm_dev_put(dev);
 }
 
-static int rfcomm_tty_write(struct tty_struct *tty, const unsigned char *buf, int count)
+static int rfcomm_tty_write(struct tty_struct *tty, int from_user, const unsigned char *buf, int count)
 {
        struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data;
        struct rfcomm_dlc *dlc = dev->dlc;
        struct sk_buff *skb;
        int err = 0, sent = 0, size;
 
-       BT_DBG("tty %p count %d", tty, count);
+       BT_DBG("tty %p from_user %d count %d", tty, from_user, count);
 
        while (count) {
                size = min_t(uint, count, dlc->mtu);
 
-               skb = rfcomm_wmalloc(dev, size + RFCOMM_SKB_RESERVE, GFP_ATOMIC);
+               if (from_user)
+                       skb = rfcomm_wmalloc(dev, size + RFCOMM_SKB_RESERVE, GFP_KERNEL);
+               else
+                       skb = rfcomm_wmalloc(dev, size + RFCOMM_SKB_RESERVE, GFP_ATOMIC);
                
                if (!skb)
                        break;
 
                skb_reserve(skb, RFCOMM_SKB_HEAD_RESERVE);
 
-               memcpy(skb_put(skb, size), buf + sent, size);
+               if (from_user)
+                       copy_from_user(skb_put(skb, size), buf + sent, size);
+               else
+                       memcpy(skb_put(skb, size), buf + sent, size);
 
                if ((err = rfcomm_dlc_send(dlc, skb)) < 0) {
                        kfree_skb(skb);