Re: [PATCH] fix serial close hang

From: Russell King (rmk@arm.linux.org.uk)
Date: Sun Dec 30 2001 - 09:42:35 EST


On Sun, Dec 30, 2001 at 03:17:31PM +0100, Heinz Diehl wrote:
> serial.c:3131: state' undeclared (first use in this function)

Whoops. This should fix it.

--- orig/include/linux/serialP.h Sat Jul 21 10:47:15 2001
+++ linux/include/linux/serialP.h Sun Dec 30 13:09:27 2001
@@ -70,7 +70,7 @@
         int x_char; /* xon/xoff character */
         int close_delay;
         unsigned short closing_wait;
- unsigned short closing_wait2;
+ unsigned short closing_wait2; /* obsolete */
         int IER; /* Interrupt Enable Register */
         int MCR; /* Modem control register */
         int LCR; /* Line control register */
--- orig/drivers/char/serial.c Sun Dec 30 13:37:23 2001
+++ linux/drivers/char/serial.c Sun Dec 30 13:49:27 2001
@@ -3095,36 +3095,52 @@
 
         sstate = rs_table + line;
         sstate->count++;
- if (sstate->info) {
- *ret_info = sstate->info;
- return 0;
- }
+ info = sstate->info;
+
+ /*
+ * If the async_struct is already allocated, do the fastpath.
+ */
+ if (info)
+ goto out;
+
         info = kmalloc(sizeof(struct async_struct), GFP_KERNEL);
         if (!info) {
                 sstate->count--;
                 return -ENOMEM;
         }
+
         memset(info, 0, sizeof(struct async_struct));
         init_waitqueue_head(&info->open_wait);
         init_waitqueue_head(&info->close_wait);
         init_waitqueue_head(&info->delta_msr_wait);
         info->magic = SERIAL_MAGIC;
         info->port = sstate->port;
+ info->hub6 = sstate->hub6;
         info->flags = sstate->flags;
- info->io_type = sstate->io_type;
- info->iomem_base = sstate->iomem_base;
- info->iomem_reg_shift = sstate->iomem_reg_shift;
         info->xmit_fifo_size = sstate->xmit_fifo_size;
+ info->state = sstate;
         info->line = line;
+ info->iomem_base = sstate->iomem_base;
+ info->iomem_reg_shift = sstate->iomem_reg_shift;
+ info->io_type = sstate->io_type;
         info->tqueue.routine = do_softint;
         info->tqueue.data = info;
- info->state = sstate;
+
         if (sstate->info) {
                 kfree(info);
- *ret_info = sstate->info;
- return 0;
+ info = sstate->info;
+ } else {
+ sstate->info = info;
+ }
+
+out:
+ /*
+ * If this is the first open, copy over some timeouts.
+ */
+ if (sstate->count == 1) {
+ info->closing_wait = sstate->closing_wait;
         }
- *ret_info = sstate->info = info;
+ *ret_info = info;
         return 0;
 }
 

-- 
Russell King (rmk@arm.linux.org.uk)                The developer of ARM Linux
             http://www.arm.linux.org.uk/personal/aboutme.html

- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/



This archive was generated by hypermail 2b29 : Mon Dec 31 2001 - 21:00:22 EST