Merge branch 'sched-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel...
[pandora-kernel.git] / drivers / char / n_r3964.c
index 6b918b8..ae377aa 100644 (file)
@@ -143,7 +143,7 @@ static unsigned int r3964_poll(struct tty_struct *tty, struct file *file,
 static void r3964_receive_buf(struct tty_struct *tty, const unsigned char *cp,
                char *fp, int count);
 
-static struct tty_ldisc tty_ldisc_N_R3964 = {
+static struct tty_ldisc_ops tty_ldisc_N_R3964 = {
        .owner = THIS_MODULE,
        .magic = TTY_LDISC_MAGIC,
        .name = "R3964",
@@ -376,8 +376,9 @@ static void put_char(struct r3964_info *pInfo, unsigned char ch)
        if (tty == NULL)
                return;
 
-       if (tty->driver->put_char) {
-               tty->driver->put_char(tty, ch);
+       /* FIXME: put_char should not be called from an IRQ */
+       if (tty->ops->put_char) {
+               tty->ops->put_char(tty, ch);
        }
        pInfo->bcc ^= ch;
 }
@@ -386,12 +387,9 @@ static void flush(struct r3964_info *pInfo)
 {
        struct tty_struct *tty = pInfo->tty;
 
-       if (tty == NULL)
+       if (tty == NULL || tty->ops->flush_chars == NULL)
                return;
-
-       if (tty->driver->flush_chars) {
-               tty->driver->flush_chars(tty);
-       }
+       tty->ops->flush_chars(tty);
 }
 
 static void trigger_transmit(struct r3964_info *pInfo)
@@ -449,12 +447,11 @@ static void transmit_block(struct r3964_info *pInfo)
        struct r3964_block_header *pBlock = pInfo->tx_first;
        int room = 0;
 
-       if ((tty == NULL) || (pBlock == NULL)) {
+       if (tty == NULL || pBlock == NULL) {
                return;
        }
 
-       if (tty->driver->write_room)
-               room = tty->driver->write_room(tty);
+       room = tty_write_room(tty);
 
        TRACE_PS("transmit_block %p, room %d, length %d",
                 pBlock, room, pBlock->length);
@@ -1075,12 +1072,15 @@ static ssize_t r3964_read(struct tty_struct *tty, struct file *file,
 
        TRACE_L("read()");
 
+       lock_kernel();
+
        pClient = findClient(pInfo, task_pid(current));
        if (pClient) {
                pMsg = remove_msg(pInfo, pClient);
                if (pMsg == NULL) {
                        /* no messages available. */
                        if (file->f_flags & O_NONBLOCK) {
+                               unlock_kernel();
                                return -EAGAIN;
                        }
                        /* block until there is a message: */
@@ -1090,8 +1090,10 @@ static ssize_t r3964_read(struct tty_struct *tty, struct file *file,
 
                /* If we still haven't got a message, we must have been signalled */
 
-               if (!pMsg)
+               if (!pMsg) {
+                       unlock_kernel();
                        return -EINTR;
+               }
 
                /* deliver msg to client process: */
                theMsg.msg_id = pMsg->msg_id;
@@ -1102,12 +1104,15 @@ static ssize_t r3964_read(struct tty_struct *tty, struct file *file,
                kfree(pMsg);
                TRACE_M("r3964_read - msg kfree %p", pMsg);
 
-               if (copy_to_user(buf, &theMsg, count))
+               if (copy_to_user(buf, &theMsg, count)) {
+                       unlock_kernel();
                        return -EFAULT;
+               }
 
                TRACE_PS("read - return %d", count);
                return count;
        }
+       unlock_kernel();
        return -EPERM;
 }
 
@@ -1156,6 +1161,8 @@ static ssize_t r3964_write(struct tty_struct *tty, struct file *file,
        pHeader->locks = 0;
        pHeader->owner = NULL;
 
+       lock_kernel();
+
        pClient = findClient(pInfo, task_pid(current));
        if (pClient) {
                pHeader->owner = pClient;
@@ -1173,6 +1180,8 @@ static ssize_t r3964_write(struct tty_struct *tty, struct file *file,
        add_tx_queue(pInfo, pHeader);
        trigger_transmit(pInfo);
 
+       unlock_kernel();
+
        return 0;
 }