X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=drivers%2Fchar%2Fspecialix.c;h=5a33227cc388ebe259e240f01d28da217269015c;hb=6a77f38946aaee1cd85eeec6cf4229b204c15071;hp=14ce603602e7f640f0bd271e2fb637838b51470f;hpb=5273a3df6485dc2ad6aa7ddd441b9a21970f003b;p=linux-2.6.git diff --git a/drivers/char/specialix.c b/drivers/char/specialix.c index 14ce60360..5a33227cc 100644 --- a/drivers/char/specialix.c +++ b/drivers/char/specialix.c @@ -72,7 +72,7 @@ /* * There is a bunch of documentation about the card, jumpers, config * settings, restrictions, cables, device names and numbers in - * ../../Documentation/specialix.txt + * Documentation/specialix.txt */ #include @@ -135,10 +135,6 @@ ASYNC_SPD_HI | ASYNC_SPEED_VHI | ASYNC_SESSION_LOCKOUT | \ ASYNC_PGRP_LOCKOUT | ASYNC_CALLOUT_NOHUP) -#ifndef MIN -#define MIN(a,b) ((a) < (b) ? (a) : (b)) -#endif - #undef RS_EVENT_WRITE_WAKEUP #define RS_EVENT_WRITE_WAKEUP 0 @@ -159,7 +155,7 @@ static struct specialix_board sx_board[SX_NBOARD] = { }; static struct specialix_port sx_port[SX_NBOARD * SX_NPORT]; - + #ifdef SPECIALIX_TIMER static struct timer_list missed_irq_timer; @@ -715,7 +711,7 @@ static inline void sx_transmit(struct specialix_board * bp) sx_out(bp, CD186x_TDR, CD186x_C_SBRK); port->COR2 &= ~COR2_ETC; } - count = MIN(port->break_length, 0xff); + count = min_t(int, port->break_length, 0xff); sx_out(bp, CD186x_TDR, CD186x_C_ESC); sx_out(bp, CD186x_TDR, CD186x_C_DELAY); sx_out(bp, CD186x_TDR, count); @@ -1456,8 +1452,7 @@ static void sx_close(struct tty_struct * tty, struct file * filp) */ timeout = jiffies+HZ; while(port->IER & IER_TXEMPTY) { - current->state = TASK_INTERRUPTIBLE; - schedule_timeout(port->timeout); + msleep_interruptible(jiffies_to_msecs(port->timeout)); if (time_after(jiffies, timeout)) { printk (KERN_INFO "Timeout waiting for close\n"); break; @@ -1468,15 +1463,13 @@ 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); - if (tty->ldisc.flush_buffer) - tty->ldisc.flush_buffer(tty); + tty_ldisc_flush(tty); tty->closing = 0; port->event = 0; - port->tty = 0; + port->tty = NULL; if (port->blocked_open) { if (port->close_delay) { - current->state = TASK_INTERRUPTIBLE; - schedule_timeout(port->close_delay); + msleep_interruptible(jiffies_to_msecs(port->close_delay)); } wake_up_interruptible(&port->open_wait); } @@ -1486,7 +1479,7 @@ static void sx_close(struct tty_struct * tty, struct file * filp) } -static int sx_write(struct tty_struct * tty, int from_user, +static int sx_write(struct tty_struct * tty, const unsigned char *buf, int count) { struct specialix_port *port = (struct specialix_port *)tty->driver_data; @@ -1503,52 +1496,22 @@ static int sx_write(struct tty_struct * tty, int from_user, return 0; save_flags(flags); - if (from_user) { - down(&tmp_buf_sem); - while (1) { - c = MIN(count, MIN(SERIAL_XMIT_SIZE - port->xmit_cnt - 1, - SERIAL_XMIT_SIZE - port->xmit_head)); - if (c <= 0) - break; - - c -= copy_from_user(tmp_buf, buf, c); - if (!c) { - if (!total) - total = -EFAULT; - break; - } - - cli(); - c = MIN(c, MIN(SERIAL_XMIT_SIZE - port->xmit_cnt - 1, - SERIAL_XMIT_SIZE - port->xmit_head)); - memcpy(port->xmit_buf + port->xmit_head, tmp_buf, c); - port->xmit_head = (port->xmit_head + c) & (SERIAL_XMIT_SIZE-1); - port->xmit_cnt += c; + while (1) { + cli(); + c = min_t(int, count, min(SERIAL_XMIT_SIZE - port->xmit_cnt - 1, + SERIAL_XMIT_SIZE - port->xmit_head)); + if (c <= 0) { restore_flags(flags); - - buf += c; - count -= c; - total += c; + break; } - up(&tmp_buf_sem); - } else { - while (1) { - cli(); - c = MIN(count, MIN(SERIAL_XMIT_SIZE - port->xmit_cnt - 1, - SERIAL_XMIT_SIZE - port->xmit_head)); - if (c <= 0) { - restore_flags(flags); - break; - } - memcpy(port->xmit_buf + port->xmit_head, buf, c); - port->xmit_head = (port->xmit_head + c) & (SERIAL_XMIT_SIZE-1); - port->xmit_cnt += c; - restore_flags(flags); + memcpy(port->xmit_buf + port->xmit_head, buf, c); + port->xmit_head = (port->xmit_head + c) & (SERIAL_XMIT_SIZE-1); + port->xmit_cnt += c; + restore_flags(flags); - buf += c; - count -= c; - total += c; - } + buf += c; + count -= c; + total += c; } cli(); @@ -1646,10 +1609,8 @@ static void sx_flush_buffer(struct tty_struct *tty) port->xmit_cnt = port->xmit_head = port->xmit_tail = 0; restore_flags(flags); + tty_wakeup(tty); wake_up_interruptible(&tty->write_wait); - if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && - tty->ldisc.write_wakeup) - (tty->ldisc.write_wakeup)(tty); } @@ -1757,18 +1718,13 @@ static inline void sx_send_break(struct specialix_port * port, unsigned long len static inline int sx_set_serial_info(struct specialix_port * port, - struct serial_struct * newinfo) + struct serial_struct __user * newinfo) { struct serial_struct tmp; struct specialix_board *bp = port_Board(port); int change_speed; unsigned long flags; - int error; - error = verify_area(VERIFY_READ, (void *) newinfo, sizeof(tmp)); - if (error) - return error; - if (copy_from_user(&tmp, newinfo, sizeof(tmp))) return -EFAULT; @@ -1813,16 +1769,11 @@ static inline int sx_set_serial_info(struct specialix_port * port, static inline int sx_get_serial_info(struct specialix_port * port, - struct serial_struct * retinfo) + struct serial_struct __user *retinfo) { struct serial_struct tmp; struct specialix_board *bp = port_Board(port); - int error; - error = verify_area(VERIFY_WRITE, (void *) retinfo, sizeof(tmp)); - if (error) - return error; - memset(&tmp, 0, sizeof(tmp)); tmp.type = PORT_CIRRUS; tmp.line = port - sx_port; @@ -1844,8 +1795,8 @@ static int sx_ioctl(struct tty_struct * tty, struct file * filp, unsigned int cmd, unsigned long arg) { struct specialix_port *port = (struct specialix_port *)tty->driver_data; - int error; int retval; + void __user *argp = (void __user *)arg; if (sx_paranoia_check(port, tty->name, "sx_ioctl")) return -ENODEV; @@ -1867,22 +1818,20 @@ static int sx_ioctl(struct tty_struct * tty, struct file * filp, sx_send_break(port, arg ? arg*(HZ/10) : HZ/4); return 0; case TIOCGSOFTCAR: - error = verify_area(VERIFY_WRITE, (void *) arg, sizeof(long)); - if (error) - return error; - put_user(C_CLOCAL(tty) ? 1 : 0, - (unsigned long *) arg); + if (put_user(C_CLOCAL(tty)?1:0, (unsigned long __user *)argp)) + return -EFAULT; return 0; case TIOCSSOFTCAR: - get_user(arg, (unsigned long *) arg); + if (get_user(arg, (unsigned long __user *) argp)) + return -EFAULT; tty->termios->c_cflag = ((tty->termios->c_cflag & ~CLOCAL) | (arg ? CLOCAL : 0)); return 0; case TIOCGSERIAL: - return sx_get_serial_info(port, (struct serial_struct *) arg); + return sx_get_serial_info(port, argp); case TIOCSSERIAL: - return sx_set_serial_info(port, (struct serial_struct *) arg); + return sx_set_serial_info(port, argp); default: return -ENOIOCTLCMD; } @@ -2027,7 +1976,7 @@ static void sx_hangup(struct tty_struct * tty) port->event = 0; port->count = 0; port->flags &= ~ASYNC_NORMAL_ACTIVE; - port->tty = 0; + port->tty = NULL; wake_up_interruptible(&port->open_wait); } @@ -2064,12 +2013,8 @@ static void do_softint(void *private_) if(!(tty = port->tty)) return; - if (test_and_clear_bit(RS_EVENT_WRITE_WAKEUP, &port->event)) { - if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && - tty->ldisc.write_wakeup) - (tty->ldisc.write_wakeup)(tty); - wake_up_interruptible(&tty->write_wait); - } + if (test_and_clear_bit(RS_EVENT_WRITE_WAKEUP, &port->event)) + tty_wakeup(tty); } static struct tty_operations sx_ops = { @@ -2241,8 +2186,8 @@ int iobase[SX_NBOARD] = {0,}; int irq [SX_NBOARD] = {0,}; -MODULE_PARM(iobase,"1-" __MODULE_STRING(SX_NBOARD) "i"); -MODULE_PARM(irq,"1-" __MODULE_STRING(SX_NBOARD) "i"); +module_param_array(iobase, int, NULL, 0); +module_param_array(irq, int, NULL, 0); /* * You can setup up to 4 boards.