libata: improve 0xff status handling
[safe/jmp/linux-2.6] / drivers / char / esp.c
index 57539d8..d1bfbaa 100644 (file)
@@ -150,17 +150,6 @@ static void rs_wait_until_sent(struct tty_struct *, int);
 /* Standard COM flags (except for COM4, because of the 8514 problem) */
 #define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST)
 
-/*
- * tmp_buf is used as a temporary buffer by serial_write.  We need to
- * lock it in case the memcpy_fromfs blocks while swapping in a page,
- * and some other program tries to do a serial write at the same time.
- * Since the lock will only come under contention when the system is
- * swapping and available memory is low, it makes sense to share one
- * buffer across all the serial ports, since it significantly saves
- * memory if large numbers of serial ports are open.
- */
-static unsigned char *tmp_buf;
-
 static inline int serial_paranoia_check(struct esp_struct *info,
                                        char *name, const char *routine)
 {
@@ -626,8 +615,7 @@ static inline void check_modem_status(struct esp_struct *info)
 /*
  * This is the serial driver's interrupt routine
  */
-static irqreturn_t rs_interrupt_single(int irq, void *dev_id,
-                                       struct pt_regs *regs)
+static irqreturn_t rs_interrupt_single(int irq, void *dev_id)
 {
        struct esp_struct * info;
        unsigned err_status;
@@ -735,9 +723,10 @@ static irqreturn_t rs_interrupt_single(int irq, void *dev_id,
  * -------------------------------------------------------------------
  */
 
-static void do_softint(void *private_)
+static void do_softint(struct work_struct *work)
 {
-       struct esp_struct       *info = (struct esp_struct *) private_;
+       struct esp_struct       *info =
+               container_of(work, struct esp_struct, tqueue);
        struct tty_struct       *tty;
        
        tty = info->tty;
@@ -758,9 +747,10 @@ static void do_softint(void *private_)
  *     do_serial_hangup() -> tty->hangup() -> esp_hangup()
  * 
  */
-static void do_serial_hangup(void *private_)
+static void do_serial_hangup(struct work_struct *work)
 {
-       struct esp_struct       *info = (struct esp_struct *) private_;
+       struct esp_struct       *info =
+               container_of(work, struct esp_struct, tqueue_hangup);
        struct tty_struct       *tty;
        
        tty = info->tty;
@@ -894,7 +884,7 @@ static int startup(struct esp_struct * info)
         * Allocate the IRQ
         */
 
-       retval = request_irq(info->irq, rs_interrupt_single, SA_SHIRQ,
+       retval = request_irq(info->irq, rs_interrupt_single, IRQF_SHARED,
                             "esp serial", info);
 
        if (retval) {
@@ -1223,7 +1213,7 @@ static void rs_put_char(struct tty_struct *tty, unsigned char ch)
        if (serial_paranoia_check(info, tty->name, "rs_put_char"))
                return;
 
-       if (!tty || !info->xmit_buf)
+       if (!info->xmit_buf)
                return;
 
        spin_lock_irqsave(&info->lock, flags);
@@ -1267,7 +1257,7 @@ static int rs_write(struct tty_struct * tty,
        if (serial_paranoia_check(info, tty->name, "rs_write"))
                return 0;
 
-       if (!tty || !info->xmit_buf || !tmp_buf)
+       if (!info->xmit_buf)
                return 0;
            
        while (1) {
@@ -1925,7 +1915,7 @@ static int rs_ioctl(struct tty_struct *tty, struct file * file,
        return 0;
 }
 
-static void rs_set_termios(struct tty_struct *tty, struct termios *old_termios)
+static void rs_set_termios(struct tty_struct *tty, struct ktermios *old_termios)
 {
        struct esp_struct *info = (struct esp_struct *)tty->driver_data;
        unsigned long flags;
@@ -2291,11 +2281,7 @@ static int esp_open(struct tty_struct *tty, struct file * filp)
        tty->driver_data = info;
        info->tty = tty;
 
-       if (!tmp_buf) {
-               tmp_buf = (unsigned char *) get_zeroed_page(GFP_KERNEL);
-               if (!tmp_buf)
-                       return -ENOMEM;
-       }
+       spin_unlock_irqrestore(&info->lock, flags);
        
        /*
         * Start up serial port
@@ -2391,7 +2377,7 @@ static inline int autoconfig(struct esp_struct * info)
        return (port_detected);
 }
 
-static struct tty_operations esp_ops = {
+static const struct tty_operations esp_ops = {
        .open = esp_open,
        .close = rs_close,
        .write = rs_write,
@@ -2464,7 +2450,6 @@ static int __init espserial_init(void)
        
        esp_driver->owner = THIS_MODULE;
        esp_driver->name = "ttyP";
-       esp_driver->devfs_name = "tts/P";
        esp_driver->major = ESP_IN_MAJOR;
        esp_driver->minor_start = 0;
        esp_driver->type = TTY_DRIVER_TYPE_SERIAL;
@@ -2518,8 +2503,8 @@ static int __init espserial_init(void)
                info->magic = ESP_MAGIC;
                info->close_delay = 5*HZ/10;
                info->closing_wait = 30*HZ;
-               INIT_WORK(&info->tqueue, do_softint, info);
-               INIT_WORK(&info->tqueue_hangup, do_serial_hangup, info);
+               INIT_WORK(&info->tqueue, do_softint);
+               INIT_WORK(&info->tqueue_hangup, do_serial_hangup);
                info->config.rx_timeout = rx_timeout;
                info->config.flow_on = flow_on;
                info->config.flow_off = flow_off;
@@ -2602,9 +2587,6 @@ static void __exit espserial_exit(void)
                free_pages((unsigned long)dma_buffer,
                        get_order(DMA_BUFFER_SZ));
 
-       if (tmp_buf)
-               free_page((unsigned long)tmp_buf);
-
        while (free_pio_buf) {
                pio_buf = free_pio_buf->next;
                kfree(free_pio_buf);