vserver 1.9.3
[linux-2.6.git] / drivers / char / rocket.c
index b0da37e..72af1be 100644 (file)
@@ -250,12 +250,16 @@ static void rp_do_receive(struct r_port *info,
                          CHANNEL_t * cp, unsigned int ChanStatus)
 {
        unsigned int CharNStat;
-       int ToRecv, wRecv, space, count;
+       int ToRecv, wRecv, space = 0, count;
        unsigned char *cbuf;
        char *fbuf;
+       struct tty_ldisc *ld;
+
+       ld = tty_ldisc_ref(tty);
 
        ToRecv = sGetRxCnt(cp);
-       space = tty->ldisc.receive_room(tty);
+       if (ld)
+               space = ld->receive_room(tty);
        if (space > 2 * TTY_FLIPBUF_SIZE)
                space = 2 * TTY_FLIPBUF_SIZE;
        cbuf = tty->flip.char_buf;
@@ -354,7 +358,8 @@ static void rp_do_receive(struct r_port *info,
                count += ToRecv;
        }
        /*  Push the data up to the tty layer */
-       tty->ldisc.receive_buf(tty, tty->flip.char_buf, tty->flip.flag_buf, count);
+       ld->receive_buf(tty, tty->flip.char_buf, tty->flip.flag_buf, count);
+       tty_ldisc_deref(ld);
 }
 
 /*
@@ -389,7 +394,7 @@ static void rp_do_transmit(struct r_port *info)
        while (1) {
                if (tty->stopped || tty->hw_stopped)
                        break;
-               c = MIN(info->xmit_fifo_room, MIN(info->xmit_cnt, XMIT_BUF_SIZE - info->xmit_tail));
+               c = min(info->xmit_fifo_room, min(info->xmit_cnt, XMIT_BUF_SIZE - info->xmit_tail));
                if (c <= 0 || info->xmit_fifo_room <= 0)
                        break;
                sOutStrW(sGetTxRxDataIO(cp), (unsigned short *) (info->xmit_buf + info->xmit_tail), c / 2);
@@ -408,8 +413,7 @@ static void rp_do_transmit(struct r_port *info)
                clear_bit((info->aiop * 8) + info->chan, (void *) &xmit_flags[info->board]);
 
        if (info->xmit_cnt < WAKEUP_CHARS) {
-               if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && tty->ldisc.write_wakeup)
-                       (tty->ldisc.write_wakeup) (tty);
+               tty_wakeup(tty);
                wake_up_interruptible(&tty->write_wait);
 #ifdef ROCKETPORT_HAVE_POLL_WAIT
                wake_up_interruptible(&tty->poll_wait);
@@ -1022,7 +1026,7 @@ static void rp_close(struct tty_struct *tty, struct file *filp)
        unsigned long flags;
        int timeout;
        CHANNEL_t *cp;
-
+       
        if (rocket_paranoia_check(info, "rp_close"))
                return;
 
@@ -1101,8 +1105,8 @@ static void rp_close(struct tty_struct *tty, struct file *filp)
 
        if (TTY_DRIVER_FLUSH_BUFFER_EXISTS(tty))
                TTY_DRIVER_FLUSH_BUFFER(tty);
-       if (tty->ldisc.flush_buffer)
-               tty->ldisc.flush_buffer(tty);
+               
+       tty_ldisc_flush(tty);
 
        clear_bit((info->aiop * 8) + info->chan, (void *) &xmit_flags[info->board]);
 
@@ -1115,7 +1119,7 @@ static void rp_close(struct tty_struct *tty, struct file *filp)
        } else {
                if (info->xmit_buf) {
                        free_page((unsigned long) info->xmit_buf);
-                       info->xmit_buf = 0;
+                       info->xmit_buf = NULL;
                }
        }
        info->flags &= ~(ROCKET_INITIALIZED | ROCKET_CLOSING | ROCKET_NORMAL_ACTIVE);
@@ -1258,7 +1262,7 @@ static int rp_tiocmset(struct tty_struct *tty, struct file *file,
        return 0;
 }
 
-static int get_config(struct r_port *info, struct rocket_config *retinfo)
+static int get_config(struct r_port *info, struct rocket_config __user *retinfo)
 {
        struct rocket_config tmp;
 
@@ -1276,23 +1280,19 @@ static int get_config(struct r_port *info, struct rocket_config *retinfo)
        return 0;
 }
 
-static int set_config(struct r_port *info, struct rocket_config *new_info)
+static int set_config(struct r_port *info, struct rocket_config __user *new_info)
 {
        struct rocket_config new_serial;
 
        if (copy_from_user(&new_serial, new_info, sizeof (new_serial)))
                return -EFAULT;
 
-#ifdef CAP_SYS_ADMIN
        if (!capable(CAP_SYS_ADMIN))
-#else
-       if (!suser())
-#endif
        {
                if ((new_serial.flags & ~ROCKET_USR_MASK) != (info->flags & ~ROCKET_USR_MASK))
                        return -EPERM;
                info->flags = ((info->flags & ~ROCKET_USR_MASK) | (new_serial.flags & ROCKET_USR_MASK));
-               configure_r_port(info, 0);
+               configure_r_port(info, NULL);
                return 0;
        }
 
@@ -1309,7 +1309,7 @@ static int set_config(struct r_port *info, struct rocket_config *new_info)
        if ((info->flags & ROCKET_SPD_MASK) == ROCKET_SPD_WARP)
                info->tty->alt_speed = 460800;
 
-       configure_r_port(info, 0);
+       configure_r_port(info, NULL);
        return 0;
 }
 
@@ -1319,7 +1319,7 @@ static int set_config(struct r_port *info, struct rocket_config *new_info)
  *  to user space.  See setrocket.c where the info is used to create
  *  the /dev/ttyRx ports.
  */
-static int get_ports(struct r_port *info, struct rocket_ports *retports)
+static int get_ports(struct r_port *info, struct rocket_ports __user *retports)
 {
        struct rocket_ports tmp;
        int board;
@@ -1341,11 +1341,11 @@ static int get_ports(struct r_port *info, struct rocket_ports *retports)
        return 0;
 }
 
-static int reset_rm2(struct r_port *info, unsigned long arg)
+static int reset_rm2(struct r_port *info, void __user *arg)
 {
        int reset;
 
-       if (copy_from_user(&reset, (void *) arg, sizeof (int)))
+       if (copy_from_user(&reset, arg, sizeof (int)))
                return -EFAULT;
        if (reset)
                reset = 1;
@@ -1362,7 +1362,7 @@ static int reset_rm2(struct r_port *info, unsigned long arg)
        return 0;
 }
 
-static int get_version(struct r_port *info, struct rocket_version *retvers)
+static int get_version(struct r_port *info, struct rocket_version __user *retvers)
 {
        if (copy_to_user(retvers, &driver_version, sizeof (*retvers)))
                return -EFAULT;
@@ -1374,25 +1374,26 @@ static int rp_ioctl(struct tty_struct *tty, struct file *file,
                    unsigned int cmd, unsigned long arg)
 {
        struct r_port *info = (struct r_port *) tty->driver_data;
+       void __user *argp = (void __user *)arg;
 
        if (cmd != RCKP_GET_PORTS && rocket_paranoia_check(info, "rp_ioctl"))
                return -ENXIO;
 
        switch (cmd) {
        case RCKP_GET_STRUCT:
-               if (copy_to_user((void *) arg, info, sizeof (struct r_port)))
+               if (copy_to_user(argp, info, sizeof (struct r_port)))
                        return -EFAULT;
                return 0;
        case RCKP_GET_CONFIG:
-               return get_config(info, (struct rocket_config *) arg);
+               return get_config(info, argp);
        case RCKP_SET_CONFIG:
-               return set_config(info, (struct rocket_config *) arg);
+               return set_config(info, argp);
        case RCKP_GET_PORTS:
-               return get_ports(info, (struct rocket_ports *) arg);
+               return get_ports(info, argp);
        case RCKP_RESET_RM2:
-               return reset_rm2(info, arg);
+               return reset_rm2(info, argp);
        case RCKP_GET_VERSION:
-               return get_version(info, (struct rocket_version *) arg);
+               return get_version(info, argp);
        default:
                return -ENOIOCTLCMD;
        }
@@ -1571,7 +1572,7 @@ static void rp_hangup(struct tty_struct *tty)
 
        info->count = 0;
        info->flags &= ~ROCKET_NORMAL_ACTIVE;
-       info->tty = 0;
+       info->tty = NULL;
 
        cp = &info->channel;
        sDisRxFIFO(cp);
@@ -1661,7 +1662,7 @@ static int rp_write(struct tty_struct *tty, int from_user,
         *  into FIFO.  Use the write queue for temp storage.
          */
        if (!tty->stopped && !tty->hw_stopped && info->xmit_cnt == 0 && info->xmit_fifo_room > 0) {
-               c = MIN(count, info->xmit_fifo_room);
+               c = min(count, info->xmit_fifo_room);
                b = buf;
                if (from_user) {
                        if (copy_from_user(info->xmit_buf, buf, c)) {
@@ -1671,7 +1672,7 @@ static int rp_write(struct tty_struct *tty, int from_user,
                        if (info->tty == 0)
                                goto end;
                        b = info->xmit_buf;
-                       c = MIN(c, info->xmit_fifo_room);
+                       c = min(c, info->xmit_fifo_room);
                }
 
                /*  Push data into FIFO, 2 bytes at a time */
@@ -1699,7 +1700,7 @@ static int rp_write(struct tty_struct *tty, int from_user,
                if (info->tty == 0)     /*   Seemingly obligatory check... */
                        goto end;
 
-               c = MIN(count, MIN(XMIT_BUF_SIZE - info->xmit_cnt - 1, XMIT_BUF_SIZE - info->xmit_head));
+               c = min(count, min(XMIT_BUF_SIZE - info->xmit_cnt - 1, XMIT_BUF_SIZE - info->xmit_head));
                if (c <= 0)
                        break;
 
@@ -1730,8 +1731,7 @@ end_intr:
        
 end:
        if (info->xmit_cnt < WAKEUP_CHARS) {
-               if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP))  && tty->ldisc.write_wakeup)
-                       (tty->ldisc.write_wakeup) (tty);
+               tty_wakeup(tty);
                wake_up_interruptible(&tty->write_wait);
 #ifdef ROCKETPORT_HAVE_POLL_WAIT
                wake_up_interruptible(&tty->poll_wait);
@@ -1805,8 +1805,7 @@ static void rp_flush_buffer(struct tty_struct *tty)
 #ifdef ROCKETPORT_HAVE_POLL_WAIT
        wake_up_interruptible(&tty->poll_wait);
 #endif
-       if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && tty->ldisc.write_wakeup)
-               (tty->ldisc.write_wakeup) (tty);
+       tty_wakeup(tty);
 
        cp = &info->channel;
        sFlushTxFIFO(cp);