drm/drm_crtc: return -EFAULT on copy_to_user errors
[safe/jmp/linux-2.6] / drivers / serial / 68328serial.c
index 5ce3e57..3046386 100644 (file)
@@ -35,6 +35,7 @@
 #include <linux/pm.h>
 #include <linux/bitops.h>
 #include <linux/delay.h>
+#include <linux/gfp.h>
 
 #include <asm/io.h>
 #include <asm/irq.h>
@@ -66,7 +67,6 @@
 #endif
 
 static struct m68k_serial m68k_soft[NR_PORTS];
-struct m68k_serial *IRQ_ports[NR_IRQS];
 
 static unsigned int uart_irqs[NR_PORTS] = UART_IRQ_DEFNS;
 
@@ -154,8 +154,6 @@ static int baud_table[] = {
        0, 50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400, 4800,
        9600, 19200, 38400, 57600, 115200, 0 };
 
-#define BAUD_TABLE_SIZE (sizeof(baud_table)/sizeof(baud_table[0]))
-
 /* Sets or clears DTR/RTS on the requested line */
 static inline void m68k_rtsdtr(struct m68k_serial *ss, int set)
 {
@@ -200,7 +198,7 @@ static void rs_stop(struct tty_struct *tty)
        local_irq_restore(flags);
 }
 
-static void rs_put_char(char ch)
+static int rs_put_char(char ch)
 {
         int flags, loops = 0;
 
@@ -214,6 +212,7 @@ static void rs_put_char(char ch)
        UTX_TXDATA = ch;
         udelay(5);
         local_irq_restore(flags);
+        return 1;
 }
 
 static void rs_start(struct tty_struct *tty)
@@ -248,7 +247,7 @@ static void status_handle(struct m68k_serial *info, unsigned short status)
 {
 #if 0
        if(status & DCD) {
-               if((info->tty->termios->c_cflag & CRTSCTS) &&
+               if((info->port.tty->termios->c_cflag & CRTSCTS) &&
                   ((info->curregs[3] & AUTO_ENAB)==0)) {
                        info->curregs[3] |= AUTO_ENAB;
                        info->pendregs[3] |= AUTO_ENAB;
@@ -273,7 +272,7 @@ static void status_handle(struct m68k_serial *info, unsigned short status)
 
 static void receive_chars(struct m68k_serial *info, unsigned short rx)
 {
-       struct tty_struct *tty = info->tty;
+       struct tty_struct *tty = info->port.tty;
        m68328_uart *uart = &uart_addr[info->line];
        unsigned char ch, flag;
 
@@ -344,7 +343,7 @@ static void transmit_chars(struct m68k_serial *info)
                goto clear_and_return;
        }
 
-       if((info->xmit_cnt <= 0) || info->tty->stopped) {
+       if((info->xmit_cnt <= 0) || info->port.tty->stopped) {
                /* That's peculiar... TX ints off */
                uart->ustcnt &= ~USTCNT_TX_INTR_MASK;
                goto clear_and_return;
@@ -374,15 +373,11 @@ clear_and_return:
  */
 irqreturn_t rs_interrupt(int irq, void *dev_id)
 {
-       struct m68k_serial * info;
+       struct m68k_serial *info = dev_id;
        m68328_uart *uart;
        unsigned short rx;
        unsigned short tx;
 
-       info = IRQ_ports[irq];
-       if(!info)
-           return IRQ_NONE;
-
        uart = &uart_addr[info->line];
        rx = uart->urx.w;
 
@@ -402,7 +397,7 @@ static void do_softint(struct work_struct *work)
        struct m68k_serial      *info = container_of(work, struct m68k_serial, tqueue);
        struct tty_struct       *tty;
        
-       tty = info->tty;
+       tty = info->port.tty;
        if (!tty)
                return;
 #if 0
@@ -426,7 +421,7 @@ static void do_serial_hangup(struct work_struct *work)
        struct m68k_serial      *info = container_of(work, struct m68k_serial, tqueue_hangup);
        struct tty_struct       *tty;
        
-       tty = info->tty;
+       tty = info->port.tty;
        if (!tty)
                return;
 
@@ -470,8 +465,8 @@ static int startup(struct m68k_serial * info)
        uart->ustcnt = USTCNT_UEN | USTCNT_RXEN | USTCNT_RX_INTR_MASK;
 #endif
 
-       if (info->tty)
-               clear_bit(TTY_IO_ERROR, &info->tty->flags);
+       if (info->port.tty)
+               clear_bit(TTY_IO_ERROR, &info->port.tty->flags);
        info->xmit_cnt = info->xmit_head = info->xmit_tail = 0;
 
        /*
@@ -505,8 +500,8 @@ static void shutdown(struct m68k_serial * info)
                info->xmit_buf = 0;
        }
 
-       if (info->tty)
-               set_bit(TTY_IO_ERROR, &info->tty->flags);
+       if (info->port.tty)
+               set_bit(TTY_IO_ERROR, &info->port.tty->flags);
        
        info->flags &= ~S_INITIALIZED;
        local_irq_restore(flags);
@@ -572,9 +567,9 @@ static void change_speed(struct m68k_serial *info)
        unsigned cflag;
        int     i;
 
-       if (!info->tty || !info->tty->termios)
+       if (!info->port.tty || !info->port.tty->termios)
                return;
-       cflag = info->tty->termios->c_cflag;
+       cflag = info->port.tty->termios->c_cflag;
        if (!(port = info->port))
                return;
 
@@ -1130,7 +1125,7 @@ static void rs_close(struct tty_struct *tty, struct file * filp)
        tty_ldisc_flush(tty);
        tty->closing = 0;
        info->event = 0;
-       info->tty = 0;
+       info->port.tty = NULL;
 #warning "This is not and has never been valid so fix it"      
 #if 0
        if (tty->ldisc.num != ldiscs[N_TTY].num) {
@@ -1168,7 +1163,7 @@ void rs_hangup(struct tty_struct *tty)
        info->event = 0;
        info->count = 0;
        info->flags &= ~S_NORMAL_ACTIVE;
-       info->tty = 0;
+       info->port.tty = NULL;
        wake_up_interruptible(&info->open_wait);
 }
 
@@ -1285,7 +1280,7 @@ int rs_open(struct tty_struct *tty, struct file * filp)
 
        info->count++;
        tty->driver_data = info;
-       info->tty = tty;
+       info->port.tty = tty;
 
        /*
         * Start up serial port
@@ -1362,7 +1357,7 @@ rs68328_init(void)
            info = &m68k_soft[i];
            info->magic = SERIAL_MAGIC;
            info->port = (int) &uart_addr[i];
-           info->tty = 0;
+           info->port.tty = NULL;
            info->irq = uart_irqs[i];
            info->custom_divisor = 16;
            info->close_delay = 50;
@@ -1382,8 +1377,6 @@ rs68328_init(void)
                   info->port, info->irq);
            printk(" is a builtin MC68328 UART\n");
            
-           IRQ_ports[info->irq] = info;        /* waste of space */
-
 #ifdef CONFIG_M68VZ328
                if (i > 0 )
                        PJSEL &= 0xCF;  /* PSW enable second port output */
@@ -1392,7 +1385,7 @@ rs68328_init(void)
            if (request_irq(uart_irqs[i],
                            rs_interrupt,
                            IRQF_DISABLED,
-                           "M68328_UART", NULL))
+                           "M68328_UART", info))
                 panic("Unable to attach 68328 serial interrupt\n");
        }
        local_irq_restore(flags);
@@ -1412,10 +1405,10 @@ static void m68328_set_baud(void)
        USTCNT = ustcnt & ~USTCNT_TXEN;
 
 again:
-       for (i = 0; i < sizeof(baud_table) / sizeof(baud_table[0]); i++)
+       for (i = 0; i < ARRAY_SIZE(baud_table); i++)
                if (baud_table[i] == m68328_console_baud)
                        break;
-       if (i >= sizeof(baud_table) / sizeof(baud_table[0])) {
+       if (i >= ARRAY_SIZE(baud_table)) {
                m68328_console_baud = 9600;
                goto again;
        }
@@ -1441,10 +1434,10 @@ int m68328_console_setup(struct console *cp, char *arg)
        if (arg)
                n = simple_strtoul(arg,NULL,0);
 
-       for (i = 0; i < BAUD_TABLE_SIZE; i++)
+       for (i = 0; i < ARRAY_SIZE(baud_table); i++)
                if (baud_table[i] == n)
                        break;
-       if (i < BAUD_TABLE_SIZE) {
+       if (i < ARRAY_SIZE(baud_table)) {
                m68328_console_baud = n;
                m68328_console_cbaud = 0;
                if (i > 15) {