vserver 1.9.5.x5
[linux-2.6.git] / drivers / char / esp.c
index d67098c..fb68199 100644 (file)
@@ -57,6 +57,7 @@
 #include <linux/ioport.h>
 #include <linux/mm.h>
 #include <linux/init.h>
+#include <linux/delay.h>
 
 #include <asm/system.h>
 #include <asm/io.h>
@@ -70,6 +71,7 @@
 
 #define NR_PORTS 64    /* maximum number of ports */
 #define NR_PRIMARY 8   /* maximum number of primary ports */
+#define REGION_SIZE 8   /* size of io region to request */
 
 /* The following variables can be set by giving module options */
 static int irq[NR_PRIMARY];    /* IRQ for each base port */
@@ -84,15 +86,15 @@ static unsigned int pio_threshold = ESP_PIO_THRESHOLD;
 
 MODULE_LICENSE("GPL");
 
-MODULE_PARM(irq, "1-8i");
-MODULE_PARM(divisor, "1-8i");
-MODULE_PARM(dma, "i");
-MODULE_PARM(rx_trigger, "i");
-MODULE_PARM(tx_trigger, "i");
-MODULE_PARM(flow_off, "i");
-MODULE_PARM(flow_on, "i");
-MODULE_PARM(rx_timeout, "i");
-MODULE_PARM(pio_threshold, "i");
+module_param_array(irq, int, NULL, 0);
+module_param_array(divisor, uint, NULL, 0);
+module_param(dma, uint, 0);
+module_param(rx_trigger, uint, 0);
+module_param(tx_trigger, uint, 0);
+module_param(flow_off, uint, 0);
+module_param(flow_on, uint, 0);
+module_param(rx_timeout, uint, 0);
+module_param(pio_threshold, uint, 0);
 
 /* END */
 
@@ -1263,7 +1265,7 @@ static void rs_flush_chars(struct tty_struct *tty)
        restore_flags(flags);
 }
 
-static int rs_write(struct tty_struct * tty, int from_user,
+static int rs_write(struct tty_struct * tty,
                    const unsigned char *buf, int count)
 {
        int     c, t, ret = 0;
@@ -1276,9 +1278,6 @@ static int rs_write(struct tty_struct * tty, int from_user,
        if (!tty || !info->xmit_buf || !tmp_buf)
                return 0;
            
-       if (from_user)
-               down(&tmp_buf_sem);
-
        while (1) {
                /* Thanks to R. Wolff for suggesting how to do this with */
                /* interrupts enabled */
@@ -1297,18 +1296,7 @@ static int rs_write(struct tty_struct * tty, int from_user,
                if (c <= 0)
                        break;
 
-               if (from_user) {
-                       c -= copy_from_user(tmp_buf, buf, c);
-
-                       if (!c) {
-                               if (!ret)
-                                       ret = -EFAULT;
-                               break;
-                       }
-
-                       memcpy(info->xmit_buf + info->xmit_head, tmp_buf, c);
-               } else
-                       memcpy(info->xmit_buf + info->xmit_head, buf, c);
+               memcpy(info->xmit_buf + info->xmit_head, buf, c);
 
                info->xmit_head = (info->xmit_head + c) & (ESP_XMIT_SIZE-1);
                info->xmit_cnt += c;
@@ -1317,9 +1305,6 @@ static int rs_write(struct tty_struct * tty, int from_user,
                ret += c;
        }
 
-       if (from_user)
-               up(&tmp_buf_sem);
-       
        save_flags(flags); cli();
 
        if (info->xmit_cnt && !tty->stopped && !(info->IER & UART_IER_THRI)) {
@@ -2066,8 +2051,7 @@ static void rs_close(struct tty_struct *tty, struct file * filp)
 
        if (info->blocked_open) {
                if (info->close_delay) {
-                       set_current_state(TASK_INTERRUPTIBLE);
-                       schedule_timeout(info->close_delay);
+                       msleep_interruptible(jiffies_to_msecs(info->close_delay));
                }
                wake_up_interruptible(&info->open_wait);
        }
@@ -2098,8 +2082,7 @@ static void rs_wait_until_sent(struct tty_struct *tty, int timeout)
 
        while ((serial_in(info, UART_ESI_STAT1) != 0x03) ||
                (serial_in(info, UART_ESI_STAT2) != 0xff)) {
-               set_current_state(TASK_INTERRUPTIBLE);
-               schedule_timeout(char_time);
+               msleep_interruptible(jiffies_to_msecs(char_time));
 
                if (signal_pending(current))
                        break;
@@ -2344,19 +2327,21 @@ static _INLINE_ void show_serial_version(void)
  * This routine is called by espserial_init() to initialize a specific serial
  * port.
  */
-static _INLINE_ int autoconfig(struct esp_struct * info, int *region_start)
+static _INLINE_ int autoconfig(struct esp_struct * info)
 {
        int port_detected = 0;
        unsigned long flags;
 
+       if (!request_region(info->port, REGION_SIZE, "esp serial"))
+               return -EIO;
+
        save_flags(flags); cli();
        
        /*
         * Check for ESP card
         */
 
-       if (!check_region(info->port, 8) && 
-           serial_in(info, UART_ESI_BASE) == 0xf3) {
+       if (serial_in(info, UART_ESI_BASE) == 0xf3) {
                serial_out(info, UART_ESI_CMD1, 0x00);
                serial_out(info, UART_ESI_CMD1, 0x01);
 
@@ -2372,19 +2357,6 @@ static _INLINE_ int autoconfig(struct esp_struct * info, int *region_start)
                                        info->irq = 4;
                        }
 
-                       if (ports && (ports->port == (info->port - 8))) {
-                               release_region(*region_start,
-                                              info->port - *region_start);
-                       } else
-                               *region_start = info->port;
-
-                       if (!request_region(*region_start,
-                                      info->port - *region_start + 8,
-                                      "esp serial"))
-                       {
-                               restore_flags(flags);
-                               return -EIO;
-                       }
 
                        /* put card in enhanced mode */
                        /* this prevents access through */
@@ -2397,6 +2369,8 @@ static _INLINE_ int autoconfig(struct esp_struct * info, int *region_start)
                        serial_out(info, UART_ESI_CMD2, 0x00);
                }
        }
+       if (!port_detected)
+               release_region(info->port, REGION_SIZE);
 
        restore_flags(flags);
        return (port_detected);
@@ -2427,10 +2401,9 @@ static struct tty_operations esp_ops = {
 /*
  * The serial driver boot-time initialization code!
  */
-int __init espserial_init(void)
+static int __init espserial_init(void)
 {
        int i, offset;
-       int region_start;
        struct esp_struct * info;
        struct esp_struct *last_primary = NULL;
        int esp[] = {0x100,0x140,0x180,0x200,0x240,0x280,0x300,0x380};
@@ -2516,7 +2489,7 @@ int __init espserial_init(void)
                info->irq = irq[i];
                info->line = (i * 8) + (offset / 8);
 
-               if (!autoconfig(info, &region_start)) {
+               if (!autoconfig(info)) {
                        i++;
                        offset = 0;
                        continue;
@@ -2592,7 +2565,6 @@ static void __exit espserial_exit(void)
 {
        unsigned long flags;
        int e1;
-       unsigned int region_start, region_end;
        struct esp_struct *temp_async;
        struct esp_pio_buffer *pio_buf;
 
@@ -2607,27 +2579,8 @@ static void __exit espserial_exit(void)
 
        while (ports) {
                if (ports->port) {
-                       region_start = region_end = ports->port;
-                       temp_async = ports;
-
-                       while (temp_async) {
-                               if ((region_start - temp_async->port) == 8) {
-                                       region_start = temp_async->port;
-                                       temp_async->port = 0;
-                                       temp_async = ports;
-                               } else if ((temp_async->port - region_end)
-                                          == 8) {
-                                       region_end = temp_async->port;
-                                       temp_async->port = 0;
-                                       temp_async = ports;
-                               } else
-                                       temp_async = temp_async->next_port;
-                       }
-                       
-                       release_region(region_start,
-                                      region_end - region_start + 8);
+                       release_region(ports->port, REGION_SIZE);
                }
-
                temp_async = ports->next_port;
                kfree(ports);
                ports = temp_async;