X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=drivers%2Fchar%2Fspecialix.c;h=2ee4d98937572195b474b5efdd42666606520a7a;hb=90621ed829ac64eb25b4d1214e9a5155e5c67ff2;hp=5ff83df67b447d18054bf45359c183d18fdb9e5a;hpb=afbf331ed1252c85753ac6790356c11e171f3d0b;p=linux-2.6 diff --git a/drivers/char/specialix.c b/drivers/char/specialix.c index 5ff83df67b..2ee4d98937 100644 --- a/drivers/char/specialix.c +++ b/drivers/char/specialix.c @@ -131,8 +131,8 @@ static int sx_rxfifo = SPECIALIX_RXFIFO; #define SX_DEBUG_FIFO 0x0800 -#define func_enter() dprintk (SX_DEBUG_FLOW, "io8: enter %s\n",__FUNCTION__) -#define func_exit() dprintk (SX_DEBUG_FLOW, "io8: exit %s\n", __FUNCTION__) +#define func_enter() dprintk (SX_DEBUG_FLOW, "io8: enter %s\n",__func__) +#define func_exit() dprintk (SX_DEBUG_FLOW, "io8: exit %s\n", __func__) #define jiffies_from_ms(a) ((((a) * HZ)/1000)+1) @@ -443,8 +443,7 @@ void missed_irq (unsigned long data) spin_unlock_irqrestore(&bp->lock, flags); if (irq) { printk (KERN_INFO "Missed interrupt... Calling int from timer. \n"); - sx_interrupt (((struct specialix_board *)data)->irq, - (void*)data); + sx_interrupt (-1, bp); } mod_timer(&missed_irq_timer, jiffies + sx_poll); } @@ -862,23 +861,22 @@ static inline void sx_check_modem(struct specialix_board * bp) /* The main interrupt processing routine */ -static irqreturn_t sx_interrupt(int irq, void *dev_id) +static irqreturn_t sx_interrupt(int dummy, void *dev_id) { unsigned char status; unsigned char ack; - struct specialix_board *bp; + struct specialix_board *bp = dev_id; unsigned long loop = 0; int saved_reg; unsigned long flags; func_enter(); - bp = dev_id; spin_lock_irqsave(&bp->lock, flags); - dprintk (SX_DEBUG_FLOW, "enter %s port %d room: %ld\n", __FUNCTION__, port_No(sx_get_port(bp, "INT")), SERIAL_XMIT_SIZE - sx_get_port(bp, "ITN")->xmit_cnt - 1); + dprintk (SX_DEBUG_FLOW, "enter %s port %d room: %ld\n", __func__, port_No(sx_get_port(bp, "INT")), SERIAL_XMIT_SIZE - sx_get_port(bp, "ITN")->xmit_cnt - 1); if (!(bp->flags & SX_BOARD_ACTIVE)) { - dprintk (SX_DEBUG_IRQ, "sx: False interrupt. irq %d.\n", irq); + dprintk (SX_DEBUG_IRQ, "sx: False interrupt. irq %d.\n", bp->irq); spin_unlock_irqrestore(&bp->lock, flags); func_exit(); return IRQ_NONE; @@ -1506,6 +1504,27 @@ static int sx_open(struct tty_struct * tty, struct file * filp) return 0; } +static void sx_flush_buffer(struct tty_struct *tty) +{ + struct specialix_port *port = (struct specialix_port *)tty->driver_data; + unsigned long flags; + struct specialix_board * bp; + + func_enter(); + + if (sx_paranoia_check(port, tty->name, "sx_flush_buffer")) { + func_exit(); + return; + } + + bp = port_Board(port); + spin_lock_irqsave(&port->lock, flags); + port->xmit_cnt = port->xmit_head = port->xmit_tail = 0; + spin_unlock_irqrestore(&port->lock, flags); + tty_wakeup(tty); + + func_exit(); +} static void sx_close(struct tty_struct * tty, struct file * filp) { @@ -1599,8 +1618,7 @@ static void sx_close(struct tty_struct * tty, struct file * filp) } sx_shutdown_port(bp, port); - if (tty->driver->flush_buffer) - tty->driver->flush_buffer(tty); + sx_flush_buffer(tty); tty_ldisc_flush(tty); spin_lock_irqsave(&port->lock, flags); tty->closing = 0; @@ -1672,7 +1690,7 @@ static int sx_write(struct tty_struct * tty, } -static void sx_put_char(struct tty_struct * tty, unsigned char ch) +static int sx_put_char(struct tty_struct * tty, unsigned char ch) { struct specialix_port *port = (struct specialix_port *)tty->driver_data; unsigned long flags; @@ -1682,12 +1700,12 @@ static void sx_put_char(struct tty_struct * tty, unsigned char ch) if (sx_paranoia_check(port, tty->name, "sx_put_char")) { func_exit(); - return; + return 0; } dprintk (SX_DEBUG_TX, "check tty: %p %p\n", tty, port->xmit_buf); if (!port->xmit_buf) { func_exit(); - return; + return 0; } bp = port_Board(port); spin_lock_irqsave(&port->lock, flags); @@ -1697,7 +1715,7 @@ static void sx_put_char(struct tty_struct * tty, unsigned char ch) spin_unlock_irqrestore(&port->lock, flags); dprintk (SX_DEBUG_TX, "Exit size\n"); func_exit(); - return; + return 0; } dprintk (SX_DEBUG_TX, "Handle xmit: %p %p\n", port, port->xmit_buf); port->xmit_buf[port->xmit_head++] = ch; @@ -1706,6 +1724,7 @@ static void sx_put_char(struct tty_struct * tty, unsigned char ch) spin_unlock_irqrestore(&port->lock, flags); func_exit(); + return 1; } @@ -1772,28 +1791,6 @@ static int sx_chars_in_buffer(struct tty_struct *tty) } -static void sx_flush_buffer(struct tty_struct *tty) -{ - struct specialix_port *port = (struct specialix_port *)tty->driver_data; - unsigned long flags; - struct specialix_board * bp; - - func_enter(); - - if (sx_paranoia_check(port, tty->name, "sx_flush_buffer")) { - func_exit(); - return; - } - - bp = port_Board(port); - spin_lock_irqsave(&port->lock, flags); - port->xmit_cnt = port->xmit_head = port->xmit_tail = 0; - spin_unlock_irqrestore(&port->lock, flags); - tty_wakeup(tty); - - func_exit(); -} - static int sx_tiocmget(struct tty_struct *tty, struct file *file) { @@ -1805,7 +1802,7 @@ static int sx_tiocmget(struct tty_struct *tty, struct file *file) func_enter(); - if (sx_paranoia_check(port, tty->name, __FUNCTION__)) { + if (sx_paranoia_check(port, tty->name, __func__)) { func_exit(); return -ENODEV; } @@ -1847,7 +1844,7 @@ static int sx_tiocmset(struct tty_struct *tty, struct file *file, func_enter(); - if (sx_paranoia_check(port, tty->name, __FUNCTION__)) { + if (sx_paranoia_check(port, tty->name, __func__)) { func_exit(); return -ENODEV; } @@ -1924,29 +1921,13 @@ static inline int sx_set_serial_info(struct specialix_port * port, int change_speed; func_enter(); - /* - if (!access_ok(VERIFY_READ, (void *) newinfo, sizeof(tmp))) { - func_exit(); - return -EFAULT; - } - */ + if (copy_from_user(&tmp, newinfo, sizeof(tmp))) { func_enter(); return -EFAULT; } -#if 0 - if ((tmp.irq != bp->irq) || - (tmp.port != bp->base) || - (tmp.type != PORT_CIRRUS) || - (tmp.baud_base != (SX_OSCFREQ + CD186x_TPC/2) / CD186x_TPC) || - (tmp.custom_divisor != 0) || - (tmp.xmit_fifo_size != CD186x_NFIFO) || - (tmp.flags & ~SPECIALIX_LEGAL_FLAGS)) { - func_exit(); - return -EINVAL; - } -#endif + lock_kernel(); change_speed = ((port->flags & ASYNC_SPD_MASK) != (tmp.flags & ASYNC_SPD_MASK)); @@ -1958,6 +1939,7 @@ static inline int sx_set_serial_info(struct specialix_port * port, ((tmp.flags & ~ASYNC_USR_MASK) != (port->flags & ~ASYNC_USR_MASK))) { func_exit(); + unlock_kernel(); return -EPERM; } port->flags = ((port->flags & ~ASYNC_USR_MASK) | @@ -1974,6 +1956,7 @@ static inline int sx_set_serial_info(struct specialix_port * port, sx_change_speed(bp, port); } func_exit(); + unlock_kernel(); return 0; } @@ -1986,12 +1969,8 @@ static inline int sx_get_serial_info(struct specialix_port * port, func_enter(); - /* - if (!access_ok(VERIFY_WRITE, (void *) retinfo, sizeof(tmp))) - return -EFAULT; - */ - memset(&tmp, 0, sizeof(tmp)); + lock_kernel(); tmp.type = PORT_CIRRUS; tmp.line = port - sx_port; tmp.port = bp->base; @@ -2002,6 +1981,7 @@ static inline int sx_get_serial_info(struct specialix_port * port, tmp.closing_wait = port->closing_wait * HZ/100; tmp.custom_divisor = port->custom_divisor; tmp.xmit_fifo_size = CD186x_NFIFO; + unlock_kernel(); if (copy_to_user(retinfo, &tmp, sizeof(tmp))) { func_exit(); return -EFAULT; @@ -2047,23 +2027,6 @@ static int sx_ioctl(struct tty_struct * tty, struct file * filp, sx_send_break(port, arg ? arg*(HZ/10) : HZ/4); func_exit(); return 0; - case TIOCGSOFTCAR: - if (put_user(C_CLOCAL(tty)?1:0, (unsigned long __user *)argp)) { - func_exit(); - return -EFAULT; - } - func_exit(); - return 0; - case TIOCSSOFTCAR: - if (get_user(arg, (unsigned long __user *) argp)) { - func_exit(); - return -EFAULT; - } - tty->termios->c_cflag = - ((tty->termios->c_cflag & ~CLOCAL) | - (arg ? CLOCAL : 0)); - func_exit(); - return 0; case TIOCGSERIAL: func_exit(); return sx_get_serial_info(port, argp);