X-Git-Url: http://pilppa.org/gitweb/gitweb.cgi?a=blobdiff_plain;f=drivers%2Fchar%2Famiserial.c;h=9d6713a93ed74ddb74adaf18aa85fd22e0ee6508;hb=e08870c87ab5b0c0c3cb05d0d0041240736493e4;hp=a124f8c5d062dd65b29775881f9b9c55a0d95a14;hpb=012e060c95e547eceea4a12c6f58592473bf4011;p=linux-2.6-omap-h63xx.git diff --git a/drivers/char/amiserial.c b/drivers/char/amiserial.c index a124f8c5d06..9d6713a93ed 100644 --- a/drivers/char/amiserial.c +++ b/drivers/char/amiserial.c @@ -31,7 +31,6 @@ * ever possible. */ -#include #include #undef SERIAL_PARANOIA_CHECK @@ -46,8 +45,6 @@ /* Sanity checks */ -#define SERIAL_INLINE - #if defined(MODULE) && defined(SERIAL_DEBUG_MCOUNT) #define DBG_CNT(s) printk("(%s): [%x] refc=%d, serc=%d, ttyc=%d -> %s\n", \ tty->name, (info->flags), serial_driver->refcount,info->count,tty->count,s) @@ -95,10 +92,7 @@ static char *serial_version = "4.30"; #include #include -#ifdef SERIAL_INLINE -#define _INLINE_ inline -#endif - +#define custom amiga_custom static char *serial_name = "Amiga-builtin serial driver"; static struct tty_driver *serial_driver; @@ -116,7 +110,7 @@ static void rs_wait_until_sent(struct tty_struct *tty, int timeout); static struct serial_state rs_table[1]; -#define NR_PORTS (sizeof(rs_table)/sizeof(struct serial_state)) +#define NR_PORTS ARRAY_SIZE(rs_table) /* * tmp_buf is used as a temporary buffer by serial_write. We need to @@ -128,7 +122,6 @@ static struct serial_state rs_table[1]; * memory if large numbers of serial ports are open. */ static unsigned char *tmp_buf; -static DECLARE_MUTEX(tmp_buf_sem); #include @@ -253,20 +246,21 @@ static void rs_start(struct tty_struct *tty) * This routine is used by the interrupt handler to schedule * processing in the software interrupt portion of the driver. */ -static _INLINE_ void rs_sched_event(struct async_struct *info, - int event) +static void rs_sched_event(struct async_struct *info, + int event) { info->event |= 1 << event; tasklet_schedule(&info->tlet); } -static _INLINE_ void receive_chars(struct async_struct *info) +static void receive_chars(struct async_struct *info) { int status; int serdatr; struct tty_struct *tty = info->tty; - unsigned char ch; + unsigned char ch, flag; struct async_icount *icount; + int oe = 0; icount = &info->state->icount; @@ -282,15 +276,12 @@ static _INLINE_ void receive_chars(struct async_struct *info) status |= UART_LSR_OE; ch = serdatr & 0xff; - if (tty->flip.count >= TTY_FLIPBUF_SIZE) - goto ignore_char; - *tty->flip.char_buf_ptr = ch; icount->rx++; #ifdef SERIAL_DEBUG_INTR printk("DR%02x:%02x...", ch, status); #endif - *tty->flip.flag_buf_ptr = 0; + flag = TTY_NORMAL; /* * We don't handle parity or frame errors - but I have left @@ -319,7 +310,7 @@ static _INLINE_ void receive_chars(struct async_struct *info) * should be ignored. */ if (status & info->ignore_status_mask) - goto ignore_char; + goto out; status &= info->read_status_mask; @@ -327,36 +318,31 @@ static _INLINE_ void receive_chars(struct async_struct *info) #ifdef SERIAL_DEBUG_INTR printk("handling break...."); #endif - *tty->flip.flag_buf_ptr = TTY_BREAK; + flag = TTY_BREAK; if (info->flags & ASYNC_SAK) do_SAK(tty); } else if (status & UART_LSR_PE) - *tty->flip.flag_buf_ptr = TTY_PARITY; + flag = TTY_PARITY; else if (status & UART_LSR_FE) - *tty->flip.flag_buf_ptr = TTY_FRAME; + flag = TTY_FRAME; if (status & UART_LSR_OE) { /* * Overrun is special, since it's * reported immediately, and doesn't * affect the current character */ - if (tty->flip.count < TTY_FLIPBUF_SIZE) { - tty->flip.count++; - tty->flip.flag_buf_ptr++; - tty->flip.char_buf_ptr++; - *tty->flip.flag_buf_ptr = TTY_OVERRUN; - } + oe = 1; } } - tty->flip.flag_buf_ptr++; - tty->flip.char_buf_ptr++; - tty->flip.count++; - ignore_char: - + tty_insert_flip_char(tty, ch, flag); + if (oe == 1) + tty_insert_flip_char(tty, 0, TTY_OVERRUN); tty_flip_buffer_push(tty); +out: + return; } -static _INLINE_ void transmit_chars(struct async_struct *info) +static void transmit_chars(struct async_struct *info) { custom.intreq = IF_TBE; mb(); @@ -396,7 +382,7 @@ static _INLINE_ void transmit_chars(struct async_struct *info) } } -static _INLINE_ void check_modem_status(struct async_struct *info) +static void check_modem_status(struct async_struct *info) { unsigned char status = ciab.pra & (SER_DCD | SER_CTS | SER_DSR); unsigned char dstatus; @@ -1095,7 +1081,7 @@ static void rs_unthrottle(struct tty_struct * tty) */ static int get_serial_info(struct async_struct * info, - struct serial_struct * retinfo) + struct serial_struct __user * retinfo) { struct serial_struct tmp; struct serial_state *state = info->state; @@ -1119,7 +1105,7 @@ static int get_serial_info(struct async_struct * info, } static int set_serial_info(struct async_struct * info, - struct serial_struct * new_info) + struct serial_struct __user * new_info) { struct serial_struct new_serial; struct serial_state old_state, *state; @@ -1200,7 +1186,7 @@ check_and_exit: * transmit holding register is empty. This functionality * allows an RS485 driver to be written in user space. */ -static int get_lsr_info(struct async_struct * info, unsigned int *value) +static int get_lsr_info(struct async_struct * info, unsigned int __user *value) { unsigned char status; unsigned int result; @@ -1291,6 +1277,7 @@ static int rs_ioctl(struct tty_struct *tty, struct file * file, struct async_struct * info = (struct async_struct *)tty->driver_data; struct async_icount cprev, cnow; /* kernel counter temps */ struct serial_icounter_struct icount; + void __user *argp = (void __user *)arg; unsigned long flags; if (serial_paranoia_check(info, tty->name, "rs_ioctl")) @@ -1305,19 +1292,17 @@ static int rs_ioctl(struct tty_struct *tty, struct file * file, switch (cmd) { case TIOCGSERIAL: - return get_serial_info(info, - (struct serial_struct *) arg); + return get_serial_info(info, argp); case TIOCSSERIAL: - return set_serial_info(info, - (struct serial_struct *) arg); + return set_serial_info(info, argp); case TIOCSERCONFIG: return 0; case TIOCSERGETLSR: /* Get line status register */ - return get_lsr_info(info, (unsigned int *) arg); + return get_lsr_info(info, argp); case TIOCSERGSTRUCT: - if (copy_to_user((struct async_struct *) arg, + if (copy_to_user(argp, info, sizeof(struct async_struct))) return -EFAULT; return 0; @@ -1376,7 +1361,7 @@ static int rs_ioctl(struct tty_struct *tty, struct file * file, icount.brk = cnow.brk; icount.buf_overrun = cnow.buf_overrun; - if (copy_to_user((void *)arg, &icount, sizeof(icount))) + if (copy_to_user(argp, &icount, sizeof(icount))) return -EFAULT; return 0; case TIOCSERGWILD: @@ -1967,7 +1952,7 @@ done: * number, and identifies which options were configured into this * driver. */ -static _INLINE_ void show_serial_version(void) +static void show_serial_version(void) { printk(KERN_INFO "%s version %s\n", serial_name, serial_version); } @@ -2066,7 +2051,7 @@ static int __init rs_init(void) /* set ISRs, and then disable the rx interrupts */ request_irq(IRQ_AMIGA_TBE, ser_tx_int, 0, "serial TX", state); - request_irq(IRQ_AMIGA_RBF, ser_rx_int, SA_INTERRUPT, "serial RX", state); + request_irq(IRQ_AMIGA_RBF, ser_rx_int, IRQF_DISABLED, "serial RX", state); /* turn off Rx and Tx interrupts */ custom.intena = IF_RBF | IF_TBE;