--- zzzz-none-000/linux-3.10.107/drivers/tty/n_r3964.c 2017-06-27 09:49:32.000000000 +0000 +++ scorpion-7490-727/linux-3.10.107/drivers/tty/n_r3964.c 2021-02-04 17:41:59.000000000 +0000 @@ -276,7 +276,7 @@ add_msg(pHeader->owner, R3964_MSG_ACK, pHeader->length, error_code, NULL); } - wake_up_interruptible(&pInfo->read_wait); + wake_up_interruptible(&pInfo->tty->read_wait); } spin_lock_irqsave(&pInfo->lock, flags); @@ -542,7 +542,7 @@ pBlock); } } - wake_up_interruptible(&pInfo->read_wait); + wake_up_interruptible(&pInfo->tty->read_wait); pInfo->state = R3964_IDLE; @@ -978,8 +978,8 @@ } spin_lock_init(&pInfo->lock); + mutex_init(&pInfo->read_lock); pInfo->tty = tty; - init_waitqueue_head(&pInfo->read_wait); pInfo->priority = R3964_MASTER; pInfo->rx_first = pInfo->rx_last = NULL; pInfo->tx_first = pInfo->tx_last = NULL; @@ -1045,7 +1045,6 @@ } /* Free buffers: */ - wake_up_interruptible(&pInfo->read_wait); kfree(pInfo->rx_buf); TRACE_M("r3964_close - rx_buf kfree %p", pInfo->rx_buf); kfree(pInfo->tx_buf); @@ -1065,7 +1064,16 @@ TRACE_L("read()"); - tty_lock(tty); + /* + * Internal serialization of reads. + */ + if (file->f_flags & O_NONBLOCK) { + if (!mutex_trylock(&pInfo->read_lock)) + return -EAGAIN; + } else { + if (mutex_lock_interruptible(&pInfo->read_lock)) + return -ERESTARTSYS; + } pClient = findClient(pInfo, task_pid(current)); if (pClient) { @@ -1077,7 +1085,7 @@ goto unlock; } /* block until there is a message: */ - wait_event_interruptible_tty(tty, pInfo->read_wait, + wait_event_interruptible(tty->read_wait, (pMsg = remove_msg(pInfo, pClient))); } @@ -1107,7 +1115,7 @@ } ret = -EPERM; unlock: - tty_unlock(tty); + mutex_unlock(&pInfo->read_lock); return ret; } @@ -1156,8 +1164,6 @@ pHeader->locks = 0; pHeader->owner = NULL; - tty_lock(tty); - pClient = findClient(pInfo, task_pid(current)); if (pClient) { pHeader->owner = pClient; @@ -1175,8 +1181,6 @@ add_tx_queue(pInfo, pHeader); trigger_transmit(pInfo); - tty_unlock(tty); - return 0; } @@ -1227,7 +1231,7 @@ pClient = findClient(pInfo, task_pid(current)); if (pClient) { - poll_wait(file, &pInfo->read_wait, wait); + poll_wait(file, &tty->read_wait, wait); spin_lock_irqsave(&pInfo->lock, flags); pMsg = pClient->first_msg; spin_unlock_irqrestore(&pInfo->lock, flags); @@ -1244,7 +1248,7 @@ { struct r3964_info *pInfo = tty->disc_data; const unsigned char *p; - char *f, flags = 0; + char *f, flags = TTY_NORMAL; int i; for (i = count, p = cp, f = fp; i; i--, p++) {