Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge tag 'tty-4.11-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty

Pull tty/serial fixes frpm Greg KH:
"Here are two bugfixes for tty stuff for 4.11-rc2.

One of them resolves the pretty bad bug in the n_hdlc code that
Alexander Popov found and fixed and has been reported everywhere. The
other just fixes a samsung serial driver issue when DMA fails on some
systems.

Both have been in linux-next with no reported issues"

* tag 'tty-4.11-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty:
serial: samsung: Continue to work if DMA request fails
tty: n_hdlc: get rid of racy n_hdlc.tbuf

+73 -65
+69 -63
drivers/tty/n_hdlc.c
··· 114 114 #define DEFAULT_TX_BUF_COUNT 3 115 115 116 116 struct n_hdlc_buf { 117 - struct n_hdlc_buf *link; 117 + struct list_head list_item; 118 118 int count; 119 119 char buf[1]; 120 120 }; ··· 122 122 #define N_HDLC_BUF_SIZE (sizeof(struct n_hdlc_buf) + maxframe) 123 123 124 124 struct n_hdlc_buf_list { 125 - struct n_hdlc_buf *head; 126 - struct n_hdlc_buf *tail; 125 + struct list_head list; 127 126 int count; 128 127 spinlock_t spinlock; 129 128 }; ··· 135 136 * @backup_tty - TTY to use if tty gets closed 136 137 * @tbusy - reentrancy flag for tx wakeup code 137 138 * @woke_up - FIXME: describe this field 138 - * @tbuf - currently transmitting tx buffer 139 139 * @tx_buf_list - list of pending transmit frame buffers 140 140 * @rx_buf_list - list of received frame buffers 141 141 * @tx_free_buf_list - list unused transmit frame buffers ··· 147 149 struct tty_struct *backup_tty; 148 150 int tbusy; 149 151 int woke_up; 150 - struct n_hdlc_buf *tbuf; 151 152 struct n_hdlc_buf_list tx_buf_list; 152 153 struct n_hdlc_buf_list rx_buf_list; 153 154 struct n_hdlc_buf_list tx_free_buf_list; ··· 156 159 /* 157 160 * HDLC buffer list manipulation functions 158 161 */ 162 + static void n_hdlc_buf_return(struct n_hdlc_buf_list *buf_list, 163 + struct n_hdlc_buf *buf); 159 164 static void n_hdlc_buf_put(struct n_hdlc_buf_list *list, 160 165 struct n_hdlc_buf *buf); 161 166 static struct n_hdlc_buf *n_hdlc_buf_get(struct n_hdlc_buf_list *list); ··· 207 208 { 208 209 struct n_hdlc *n_hdlc = tty2n_hdlc(tty); 209 210 struct n_hdlc_buf *buf; 210 - unsigned long flags; 211 211 212 212 while ((buf = n_hdlc_buf_get(&n_hdlc->tx_buf_list))) 213 213 n_hdlc_buf_put(&n_hdlc->tx_free_buf_list, buf); 214 - spin_lock_irqsave(&n_hdlc->tx_buf_list.spinlock, flags); 215 - if (n_hdlc->tbuf) { 216 - n_hdlc_buf_put(&n_hdlc->tx_free_buf_list, n_hdlc->tbuf); 217 - n_hdlc->tbuf = NULL; 218 - } 219 - spin_unlock_irqrestore(&n_hdlc->tx_buf_list.spinlock, flags); 220 214 } 221 215 222 216 static struct tty_ldisc_ops n_hdlc_ldisc = { ··· 275 283 } else 276 284 break; 277 285 } 278 - kfree(n_hdlc->tbuf); 279 286 kfree(n_hdlc); 280 287 281 288 } /* end of n_hdlc_release() */ ··· 393 402 n_hdlc->woke_up = 0; 394 403 spin_unlock_irqrestore(&n_hdlc->tx_buf_list.spinlock, flags); 395 404 396 - /* get current transmit buffer or get new transmit */ 397 - /* buffer from list of pending transmit buffers */ 398 - 399 - tbuf = n_hdlc->tbuf; 400 - if (!tbuf) 401 - tbuf = n_hdlc_buf_get(&n_hdlc->tx_buf_list); 402 - 405 + tbuf = n_hdlc_buf_get(&n_hdlc->tx_buf_list); 403 406 while (tbuf) { 404 407 if (debuglevel >= DEBUG_LEVEL_INFO) 405 408 printk("%s(%d)sending frame %p, count=%d\n", ··· 405 420 406 421 /* rollback was possible and has been done */ 407 422 if (actual == -ERESTARTSYS) { 408 - n_hdlc->tbuf = tbuf; 423 + n_hdlc_buf_return(&n_hdlc->tx_buf_list, tbuf); 409 424 break; 410 425 } 411 426 /* if transmit error, throw frame away by */ ··· 420 435 421 436 /* free current transmit buffer */ 422 437 n_hdlc_buf_put(&n_hdlc->tx_free_buf_list, tbuf); 423 - 424 - /* this tx buffer is done */ 425 - n_hdlc->tbuf = NULL; 426 - 438 + 427 439 /* wait up sleeping writers */ 428 440 wake_up_interruptible(&tty->write_wait); 429 441 ··· 430 448 if (debuglevel >= DEBUG_LEVEL_INFO) 431 449 printk("%s(%d)frame %p pending\n", 432 450 __FILE__,__LINE__,tbuf); 433 - 434 - /* buffer not accepted by driver */ 435 - /* set this buffer as pending buffer */ 436 - n_hdlc->tbuf = tbuf; 451 + 452 + /* 453 + * the buffer was not accepted by driver, 454 + * return it back into tx queue 455 + */ 456 + n_hdlc_buf_return(&n_hdlc->tx_buf_list, tbuf); 437 457 break; 438 458 } 439 459 } ··· 733 749 int error = 0; 734 750 int count; 735 751 unsigned long flags; 736 - 752 + struct n_hdlc_buf *buf = NULL; 753 + 737 754 if (debuglevel >= DEBUG_LEVEL_INFO) 738 755 printk("%s(%d)n_hdlc_tty_ioctl() called %d\n", 739 756 __FILE__,__LINE__,cmd); ··· 748 763 /* report count of read data available */ 749 764 /* in next available frame (if any) */ 750 765 spin_lock_irqsave(&n_hdlc->rx_buf_list.spinlock,flags); 751 - if (n_hdlc->rx_buf_list.head) 752 - count = n_hdlc->rx_buf_list.head->count; 766 + buf = list_first_entry_or_null(&n_hdlc->rx_buf_list.list, 767 + struct n_hdlc_buf, list_item); 768 + if (buf) 769 + count = buf->count; 753 770 else 754 771 count = 0; 755 772 spin_unlock_irqrestore(&n_hdlc->rx_buf_list.spinlock,flags); ··· 763 776 count = tty_chars_in_buffer(tty); 764 777 /* add size of next output frame in queue */ 765 778 spin_lock_irqsave(&n_hdlc->tx_buf_list.spinlock,flags); 766 - if (n_hdlc->tx_buf_list.head) 767 - count += n_hdlc->tx_buf_list.head->count; 779 + buf = list_first_entry_or_null(&n_hdlc->tx_buf_list.list, 780 + struct n_hdlc_buf, list_item); 781 + if (buf) 782 + count += buf->count; 768 783 spin_unlock_irqrestore(&n_hdlc->tx_buf_list.spinlock,flags); 769 784 error = put_user(count, (int __user *)arg); 770 785 break; ··· 814 825 poll_wait(filp, &tty->write_wait, wait); 815 826 816 827 /* set bits for operations that won't block */ 817 - if (n_hdlc->rx_buf_list.head) 828 + if (!list_empty(&n_hdlc->rx_buf_list.list)) 818 829 mask |= POLLIN | POLLRDNORM; /* readable */ 819 830 if (test_bit(TTY_OTHER_CLOSED, &tty->flags)) 820 831 mask |= POLLHUP; 821 832 if (tty_hung_up_p(filp)) 822 833 mask |= POLLHUP; 823 834 if (!tty_is_writelocked(tty) && 824 - n_hdlc->tx_free_buf_list.head) 835 + !list_empty(&n_hdlc->tx_free_buf_list.list)) 825 836 mask |= POLLOUT | POLLWRNORM; /* writable */ 826 837 } 827 838 return mask; ··· 845 856 spin_lock_init(&n_hdlc->tx_free_buf_list.spinlock); 846 857 spin_lock_init(&n_hdlc->rx_buf_list.spinlock); 847 858 spin_lock_init(&n_hdlc->tx_buf_list.spinlock); 848 - 859 + 860 + INIT_LIST_HEAD(&n_hdlc->rx_free_buf_list.list); 861 + INIT_LIST_HEAD(&n_hdlc->tx_free_buf_list.list); 862 + INIT_LIST_HEAD(&n_hdlc->rx_buf_list.list); 863 + INIT_LIST_HEAD(&n_hdlc->tx_buf_list.list); 864 + 849 865 /* allocate free rx buffer list */ 850 866 for(i=0;i<DEFAULT_RX_BUF_COUNT;i++) { 851 867 buf = kmalloc(N_HDLC_BUF_SIZE, GFP_KERNEL); ··· 878 884 } /* end of n_hdlc_alloc() */ 879 885 880 886 /** 887 + * n_hdlc_buf_return - put the HDLC buffer after the head of the specified list 888 + * @buf_list - pointer to the buffer list 889 + * @buf - pointer to the buffer 890 + */ 891 + static void n_hdlc_buf_return(struct n_hdlc_buf_list *buf_list, 892 + struct n_hdlc_buf *buf) 893 + { 894 + unsigned long flags; 895 + 896 + spin_lock_irqsave(&buf_list->spinlock, flags); 897 + 898 + list_add(&buf->list_item, &buf_list->list); 899 + buf_list->count++; 900 + 901 + spin_unlock_irqrestore(&buf_list->spinlock, flags); 902 + } 903 + 904 + /** 881 905 * n_hdlc_buf_put - add specified HDLC buffer to tail of specified list 882 - * @list - pointer to buffer list 906 + * @buf_list - pointer to buffer list 883 907 * @buf - pointer to buffer 884 908 */ 885 - static void n_hdlc_buf_put(struct n_hdlc_buf_list *list, 909 + static void n_hdlc_buf_put(struct n_hdlc_buf_list *buf_list, 886 910 struct n_hdlc_buf *buf) 887 911 { 888 912 unsigned long flags; 889 - spin_lock_irqsave(&list->spinlock,flags); 890 - 891 - buf->link=NULL; 892 - if (list->tail) 893 - list->tail->link = buf; 894 - else 895 - list->head = buf; 896 - list->tail = buf; 897 - (list->count)++; 898 - 899 - spin_unlock_irqrestore(&list->spinlock,flags); 900 - 913 + 914 + spin_lock_irqsave(&buf_list->spinlock, flags); 915 + 916 + list_add_tail(&buf->list_item, &buf_list->list); 917 + buf_list->count++; 918 + 919 + spin_unlock_irqrestore(&buf_list->spinlock, flags); 901 920 } /* end of n_hdlc_buf_put() */ 902 921 903 922 /** 904 923 * n_hdlc_buf_get - remove and return an HDLC buffer from list 905 - * @list - pointer to HDLC buffer list 924 + * @buf_list - pointer to HDLC buffer list 906 925 * 907 926 * Remove and return an HDLC buffer from the head of the specified HDLC buffer 908 927 * list. 909 928 * Returns a pointer to HDLC buffer if available, otherwise %NULL. 910 929 */ 911 - static struct n_hdlc_buf* n_hdlc_buf_get(struct n_hdlc_buf_list *list) 930 + static struct n_hdlc_buf *n_hdlc_buf_get(struct n_hdlc_buf_list *buf_list) 912 931 { 913 932 unsigned long flags; 914 933 struct n_hdlc_buf *buf; 915 - spin_lock_irqsave(&list->spinlock,flags); 916 - 917 - buf = list->head; 934 + 935 + spin_lock_irqsave(&buf_list->spinlock, flags); 936 + 937 + buf = list_first_entry_or_null(&buf_list->list, 938 + struct n_hdlc_buf, list_item); 918 939 if (buf) { 919 - list->head = buf->link; 920 - (list->count)--; 940 + list_del(&buf->list_item); 941 + buf_list->count--; 921 942 } 922 - if (!list->head) 923 - list->tail = NULL; 924 - 925 - spin_unlock_irqrestore(&list->spinlock,flags); 943 + 944 + spin_unlock_irqrestore(&buf_list->spinlock, flags); 926 945 return buf; 927 - 928 946 } /* end of n_hdlc_buf_get() */ 929 947 930 948 static char hdlc_banner[] __initdata =
+4 -2
drivers/tty/serial/samsung.c
··· 1031 1031 if (ourport->dma) { 1032 1032 ret = s3c24xx_serial_request_dma(ourport); 1033 1033 if (ret < 0) { 1034 - dev_warn(port->dev, "DMA request failed\n"); 1035 - return ret; 1034 + dev_warn(port->dev, 1035 + "DMA request failed, DMA will not be used\n"); 1036 + devm_kfree(port->dev, ourport->dma); 1037 + ourport->dma = NULL; 1036 1038 } 1037 1039 } 1038 1040