* [PATCH 01/58] jsm: IRQ handlers doesn't need to have IRQ_DISABLED enabled
2009-12-11 23:28 [GIT PATCH] TTY patches for 2.6.33-git Greg KH
@ 2009-12-11 23:27 ` Greg Kroah-Hartman
2009-12-11 23:27 ` [PATCH 02/58] jsm: Rewriting a bad log message Greg Kroah-Hartman
` (57 subsequent siblings)
58 siblings, 0 replies; 100+ messages in thread
From: Greg Kroah-Hartman @ 2009-12-11 23:27 UTC (permalink / raw)
To: linux-kernel
Cc: Breno Leitão, Scott Kilau, Andrew Morton, Greg Kroah-Hartman
From: Breno Leitão <leitao@linux.vnet.ibm.com>
Currently jsm is showing the following message when loaded:
IRQ 432/JSM: IRQF_DISABLED is not guaranteed on shared IRQs
It's because the request_irq() is called using IRQF_DISABLED
and IRQF_SHARED.
Actually there is no need to use IRQF_DISABLED in this driver.
Signed-off-by: Breno Leitão <leitao@linux.vnet.ibm.com>
Cc: Scott Kilau <scottk@digi.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
---
drivers/serial/jsm/jsm_driver.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/drivers/serial/jsm/jsm_driver.c b/drivers/serial/jsm/jsm_driver.c
index b3604aa..48326f7 100644
--- a/drivers/serial/jsm/jsm_driver.c
+++ b/drivers/serial/jsm/jsm_driver.c
@@ -123,7 +123,7 @@ static int __devinit jsm_probe_one(struct pci_dev *pdev, const struct pci_device
}
rc = request_irq(brd->irq, brd->bd_ops->intr,
- IRQF_DISABLED|IRQF_SHARED, "JSM", brd);
+ IRQF_SHARED, "JSM", brd);
if (rc) {
printk(KERN_WARNING "Failed to hook IRQ %d\n",brd->irq);
goto out_iounmap;
--
1.6.5.5
^ permalink raw reply related [flat|nested] 100+ messages in thread* [PATCH 02/58] jsm: Rewriting a bad log message
2009-12-11 23:28 [GIT PATCH] TTY patches for 2.6.33-git Greg KH
2009-12-11 23:27 ` [PATCH 01/58] jsm: IRQ handlers doesn't need to have IRQ_DISABLED enabled Greg Kroah-Hartman
@ 2009-12-11 23:27 ` Greg Kroah-Hartman
2009-12-11 23:27 ` [PATCH 03/58] jsm: remove the ch_custom_speed field Greg Kroah-Hartman
` (56 subsequent siblings)
58 siblings, 0 replies; 100+ messages in thread
From: Greg Kroah-Hartman @ 2009-12-11 23:27 UTC (permalink / raw)
To: linux-kernel
Cc: Breno Leitão, Scott Kilau, Andrew Morton, Greg Kroah-Hartman
From: Breno Leitão <leitao@linux.vnet.ibm.com>
Actually jsm displays "Device Added" 8 times (for a 8 port device).
This silly patch just makes things more informative, showing
the port (instead of the device) that was added.
Signed-off-by: Breno Leitão <leitao@linux.vnet.ibm.com>
Cc: Scott Kilau <scottk@digi.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
---
drivers/serial/jsm/jsm_tty.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/drivers/serial/jsm/jsm_tty.c b/drivers/serial/jsm/jsm_tty.c
index 7439c03..6423dfb 100644
--- a/drivers/serial/jsm/jsm_tty.c
+++ b/drivers/serial/jsm/jsm_tty.c
@@ -472,7 +472,7 @@ int __devinit jsm_uart_port_init(struct jsm_board *brd)
if (uart_add_one_port (&jsm_uart_driver, &brd->channels[i]->uart_port))
printk(KERN_INFO "jsm: add device failed\n");
else
- printk(KERN_INFO "Added device \n");
+ printk(KERN_INFO "jsm: Port %d added\n", i);
}
jsm_printk(INIT, INFO, &brd->pci_dev, "finish\n");
--
1.6.5.5
^ permalink raw reply related [flat|nested] 100+ messages in thread* [PATCH 03/58] jsm: remove the ch_custom_speed field
2009-12-11 23:28 [GIT PATCH] TTY patches for 2.6.33-git Greg KH
2009-12-11 23:27 ` [PATCH 01/58] jsm: IRQ handlers doesn't need to have IRQ_DISABLED enabled Greg Kroah-Hartman
2009-12-11 23:27 ` [PATCH 02/58] jsm: Rewriting a bad log message Greg Kroah-Hartman
@ 2009-12-11 23:27 ` Greg Kroah-Hartman
2009-12-11 23:27 ` [PATCH 04/58] jsm: removing ch_old_baud field Greg Kroah-Hartman
` (55 subsequent siblings)
58 siblings, 0 replies; 100+ messages in thread
From: Greg Kroah-Hartman @ 2009-12-11 23:27 UTC (permalink / raw)
To: linux-kernel; +Cc: Breno Leitão, Scott Kilau, Greg Kroah-Hartman
From: Breno Leitão <leitao@linux.vnet.ibm.com>
Currently the ch_custom_speed field exists but is never used,
so, this patch removes it.
Signed-off-by: Breno Leitão <leitao@linux.vnet.ibm.com>
Cc: Scott Kilau <scottk@digi.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
---
drivers/serial/jsm/jsm.h | 1 -
drivers/serial/jsm/jsm_neo.c | 4 ----
2 files changed, 0 insertions(+), 5 deletions(-)
diff --git a/drivers/serial/jsm/jsm.h b/drivers/serial/jsm/jsm.h
index 4e5f3bd..afcbee2 100644
--- a/drivers/serial/jsm/jsm.h
+++ b/drivers/serial/jsm/jsm.h
@@ -216,7 +216,6 @@ struct jsm_channel {
u8 ch_startc; /* Start character */
u32 ch_old_baud; /* Cache of the current baud */
- u32 ch_custom_speed;/* Custom baud, if set */
u32 ch_wopen; /* Waiting for open process cnt */
diff --git a/drivers/serial/jsm/jsm_neo.c b/drivers/serial/jsm/jsm_neo.c
index b4b124e..088e702 100644
--- a/drivers/serial/jsm/jsm_neo.c
+++ b/drivers/serial/jsm/jsm_neo.c
@@ -957,10 +957,6 @@ static void neo_param(struct jsm_channel *ch)
ch->ch_old_baud = 0;
return;
- } else if (ch->ch_custom_speed) {
- baud = ch->ch_custom_speed;
- if (ch->ch_flags & CH_BAUD0)
- ch->ch_flags &= ~(CH_BAUD0);
} else {
int i;
unsigned int cflag;
--
1.6.5.5
^ permalink raw reply related [flat|nested] 100+ messages in thread* [PATCH 04/58] jsm: removing ch_old_baud field
2009-12-11 23:28 [GIT PATCH] TTY patches for 2.6.33-git Greg KH
` (2 preceding siblings ...)
2009-12-11 23:27 ` [PATCH 03/58] jsm: remove the ch_custom_speed field Greg Kroah-Hartman
@ 2009-12-11 23:27 ` Greg Kroah-Hartman
2009-12-11 23:27 ` [PATCH 05/58] jsm: Remove ch_cpstime field Greg Kroah-Hartman
` (54 subsequent siblings)
58 siblings, 0 replies; 100+ messages in thread
From: Greg Kroah-Hartman @ 2009-12-11 23:27 UTC (permalink / raw)
To: linux-kernel; +Cc: Breno Leitão, Scott Kilau, Greg Kroah-Hartman
From: Breno Leitão <leitao@linux.vnet.ibm.com>
Currently the field jsm_channel->ch_old_baud is not used, just
assigned in a lot of places but never used. This patches removes
this field.
Signed-off-by: Breno Leitão <leitao@linux.vnet.ibm.com>
Cc: Scott Kilau <scottk@digi.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
---
drivers/serial/jsm/jsm.h | 2 --
drivers/serial/jsm/jsm_neo.c | 2 --
drivers/serial/jsm/jsm_tty.c | 2 --
3 files changed, 0 insertions(+), 6 deletions(-)
diff --git a/drivers/serial/jsm/jsm.h b/drivers/serial/jsm/jsm.h
index afcbee2..d413e4a 100644
--- a/drivers/serial/jsm/jsm.h
+++ b/drivers/serial/jsm/jsm.h
@@ -215,8 +215,6 @@ struct jsm_channel {
u8 ch_stopc; /* Stop character */
u8 ch_startc; /* Start character */
- u32 ch_old_baud; /* Cache of the current baud */
-
u32 ch_wopen; /* Waiting for open process cnt */
u8 ch_mostat; /* FEP output modem status */
diff --git a/drivers/serial/jsm/jsm_neo.c b/drivers/serial/jsm/jsm_neo.c
index 088e702..bee3727 100644
--- a/drivers/serial/jsm/jsm_neo.c
+++ b/drivers/serial/jsm/jsm_neo.c
@@ -954,7 +954,6 @@ static void neo_param(struct jsm_channel *ch)
ch->ch_flags |= (CH_BAUD0);
ch->ch_mostat &= ~(UART_MCR_RTS | UART_MCR_DTR);
neo_assert_modem_signals(ch);
- ch->ch_old_baud = 0;
return;
} else {
@@ -1041,7 +1040,6 @@ static void neo_param(struct jsm_channel *ch)
quot = ch->ch_bd->bd_dividend / baud;
if (quot != 0) {
- ch->ch_old_baud = baud;
writeb(UART_LCR_DLAB, &ch->ch_neo_uart->lcr);
writeb((quot & 0xff), &ch->ch_neo_uart->txrx);
writeb((quot >> 8), &ch->ch_neo_uart->ier);
diff --git a/drivers/serial/jsm/jsm_tty.c b/drivers/serial/jsm/jsm_tty.c
index 6423dfb..1bcad59 100644
--- a/drivers/serial/jsm/jsm_tty.c
+++ b/drivers/serial/jsm/jsm_tty.c
@@ -296,8 +296,6 @@ static void jsm_tty_close(struct uart_port *port)
bd->bd_ops->assert_modem_signals(channel);
}
- channel->ch_old_baud = 0;
-
/* Turn off UART interrupts for this port */
channel->ch_bd->bd_ops->uart_off(channel);
--
1.6.5.5
^ permalink raw reply related [flat|nested] 100+ messages in thread* [PATCH 05/58] jsm: Remove ch_cpstime field
2009-12-11 23:28 [GIT PATCH] TTY patches for 2.6.33-git Greg KH
` (3 preceding siblings ...)
2009-12-11 23:27 ` [PATCH 04/58] jsm: removing ch_old_baud field Greg Kroah-Hartman
@ 2009-12-11 23:27 ` Greg Kroah-Hartman
2009-12-11 23:27 ` [PATCH 06/58] jsm: Removing unused jsm_channel->ch_wopen field Greg Kroah-Hartman
` (53 subsequent siblings)
58 siblings, 0 replies; 100+ messages in thread
From: Greg Kroah-Hartman @ 2009-12-11 23:27 UTC (permalink / raw)
To: linux-kernel; +Cc: Breno Leitão, Scott Kilau, Greg Kroah-Hartman
From: Breno Leitão <leitao@linux.vnet.ibm.com>
Currently the field jsm_channel->ch_cpstime is defined but never
used, so this patch removes it.
Signed-off-by: Breno Leitão <leitao@linux.vnet.ibm.com>
Cc: Scott Kilau <Scott.Kilau@digi.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
---
drivers/serial/jsm/jsm.h | 2 --
1 files changed, 0 insertions(+), 2 deletions(-)
diff --git a/drivers/serial/jsm/jsm.h b/drivers/serial/jsm/jsm.h
index d413e4a..8c14351 100644
--- a/drivers/serial/jsm/jsm.h
+++ b/drivers/serial/jsm/jsm.h
@@ -206,8 +206,6 @@ struct jsm_channel {
u64 ch_close_delay; /* How long we should drop RTS/DTR for */
- u64 ch_cpstime; /* Time for CPS calculations */
-
tcflag_t ch_c_iflag; /* channel iflags */
tcflag_t ch_c_cflag; /* channel cflags */
tcflag_t ch_c_oflag; /* channel oflags */
--
1.6.5.5
^ permalink raw reply related [flat|nested] 100+ messages in thread* [PATCH 06/58] jsm: Removing unused jsm_channel->ch_wopen field
2009-12-11 23:28 [GIT PATCH] TTY patches for 2.6.33-git Greg KH
` (4 preceding siblings ...)
2009-12-11 23:27 ` [PATCH 05/58] jsm: Remove ch_cpstime field Greg Kroah-Hartman
@ 2009-12-11 23:27 ` Greg Kroah-Hartman
2009-12-11 23:27 ` [PATCH 07/58] jsm: removing the field jsm_board->intr_count Greg Kroah-Hartman
` (52 subsequent siblings)
58 siblings, 0 replies; 100+ messages in thread
From: Greg Kroah-Hartman @ 2009-12-11 23:27 UTC (permalink / raw)
To: linux-kernel; +Cc: Breno Leitão, Scott Kilau, Greg Kroah-Hartman
From: Breno Leitão <leitao@linux.vnet.ibm.com>
Currently the jsm_channel->ch_wopen field is defined and never
used. So, this patch removes it.
Signed-off-by: Breno Leitão <leitao@linux.vnet.ibm.com>
Cc: Scott Kilau <Scott.Kilau@digi.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
---
drivers/serial/jsm/jsm.h | 2 --
1 files changed, 0 insertions(+), 2 deletions(-)
diff --git a/drivers/serial/jsm/jsm.h b/drivers/serial/jsm/jsm.h
index 8c14351..484c927 100644
--- a/drivers/serial/jsm/jsm.h
+++ b/drivers/serial/jsm/jsm.h
@@ -213,8 +213,6 @@ struct jsm_channel {
u8 ch_stopc; /* Stop character */
u8 ch_startc; /* Start character */
- u32 ch_wopen; /* Waiting for open process cnt */
-
u8 ch_mostat; /* FEP output modem status */
u8 ch_mistat; /* FEP input modem status */
--
1.6.5.5
^ permalink raw reply related [flat|nested] 100+ messages in thread* [PATCH 07/58] jsm: removing the field jsm_board->intr_count
2009-12-11 23:28 [GIT PATCH] TTY patches for 2.6.33-git Greg KH
` (5 preceding siblings ...)
2009-12-11 23:27 ` [PATCH 06/58] jsm: Removing unused jsm_channel->ch_wopen field Greg Kroah-Hartman
@ 2009-12-11 23:27 ` Greg Kroah-Hartman
2009-12-11 23:27 ` [PATCH 08/58] jsm: adding EEH handlers Greg Kroah-Hartman
` (51 subsequent siblings)
58 siblings, 0 replies; 100+ messages in thread
From: Greg Kroah-Hartman @ 2009-12-11 23:27 UTC (permalink / raw)
To: linux-kernel; +Cc: Breno Leitão, Scott Kilau, Greg Kroah-Hartman
From: Breno Leitão <leitao@linux.vnet.ibm.com>
Currently there is a field in the jsm_board structure to cont
the number of interrupt that the card recevived, but it's not
working properly when the IRQ line is shared, and also nowhere
else this field is used. So, This patch is removing it.
Signed-off-by: Breno Leitão <leitao@linux.vnet.ibm.com>
Cc: Scott Kilau <Scott.Kilau@digi.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
---
drivers/serial/jsm/jsm.h | 1 -
drivers/serial/jsm/jsm_neo.c | 2 --
2 files changed, 0 insertions(+), 3 deletions(-)
diff --git a/drivers/serial/jsm/jsm.h b/drivers/serial/jsm/jsm.h
index 484c927..38a509c 100644
--- a/drivers/serial/jsm/jsm.h
+++ b/drivers/serial/jsm/jsm.h
@@ -138,7 +138,6 @@ struct jsm_board
u32 nasync; /* Number of ports on card */
u32 irq; /* Interrupt request number */
- u64 intr_count; /* Count of interrupts */
u64 membase; /* Start of base memory of the card */
u64 membase_end; /* End of base memory of the card */
diff --git a/drivers/serial/jsm/jsm_neo.c b/drivers/serial/jsm/jsm_neo.c
index bee3727..7960d96 100644
--- a/drivers/serial/jsm/jsm_neo.c
+++ b/drivers/serial/jsm/jsm_neo.c
@@ -1117,8 +1117,6 @@ static irqreturn_t neo_intr(int irq, void *voidbrd)
unsigned long lock_flags2;
int outofloop_count = 0;
- brd->intr_count++;
-
/* Lock out the slow poller from running on this board. */
spin_lock_irqsave(&brd->bd_intr_lock, lock_flags);
--
1.6.5.5
^ permalink raw reply related [flat|nested] 100+ messages in thread* [PATCH 08/58] jsm: adding EEH handlers
2009-12-11 23:28 [GIT PATCH] TTY patches for 2.6.33-git Greg KH
` (6 preceding siblings ...)
2009-12-11 23:27 ` [PATCH 07/58] jsm: removing the field jsm_board->intr_count Greg Kroah-Hartman
@ 2009-12-11 23:27 ` Greg Kroah-Hartman
2009-12-11 23:27 ` [PATCH 09/58] tty: const: constify remaining tty_operations Greg Kroah-Hartman
` (50 subsequent siblings)
58 siblings, 0 replies; 100+ messages in thread
From: Greg Kroah-Hartman @ 2009-12-11 23:27 UTC (permalink / raw)
To: linux-kernel; +Cc: Breno Leitao, Greg Kroah-Hartman
From: Breno Leitao <leitao@linux.vnet.ibm.com>
Adding EEH handlers for the serial jsm driver. This patch adds
the PCI error handlers and also register them to be called when
a error is detected.
Signed-off-by: Breno Leitao <leitao@linux.vnet.ibm.com>
Acked-by: Scott Kilau <scottk@digi.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
---
drivers/serial/jsm/jsm_driver.c | 46 +++++++++++++++++++++++++++++++++++++++
drivers/serial/jsm/jsm_tty.c | 2 +-
2 files changed, 47 insertions(+), 1 deletions(-)
diff --git a/drivers/serial/jsm/jsm_driver.c b/drivers/serial/jsm/jsm_driver.c
index 48326f7..108c3e0 100644
--- a/drivers/serial/jsm/jsm_driver.c
+++ b/drivers/serial/jsm/jsm_driver.c
@@ -48,6 +48,17 @@ struct uart_driver jsm_uart_driver = {
.nr = NR_PORTS,
};
+static pci_ers_result_t jsm_io_error_detected(struct pci_dev *pdev,
+ pci_channel_state_t state);
+static pci_ers_result_t jsm_io_slot_reset(struct pci_dev *pdev);
+static void jsm_io_resume(struct pci_dev *pdev);
+
+static struct pci_error_handlers jsm_err_handler = {
+ .error_detected = jsm_io_error_detected,
+ .slot_reset = jsm_io_slot_reset,
+ .resume = jsm_io_resume,
+};
+
int jsm_debug;
module_param(jsm_debug, int, 0);
MODULE_PARM_DESC(jsm_debug, "Driver debugging level");
@@ -164,6 +175,7 @@ static int __devinit jsm_probe_one(struct pci_dev *pdev, const struct pci_device
}
pci_set_drvdata(pdev, brd);
+ pci_save_state(pdev);
return 0;
out_free_irq:
@@ -222,8 +234,42 @@ static struct pci_driver jsm_driver = {
.id_table = jsm_pci_tbl,
.probe = jsm_probe_one,
.remove = __devexit_p(jsm_remove_one),
+ .err_handler = &jsm_err_handler,
};
+static pci_ers_result_t jsm_io_error_detected(struct pci_dev *pdev,
+ pci_channel_state_t state)
+{
+ struct jsm_board *brd = pci_get_drvdata(pdev);
+
+ jsm_remove_uart_port(brd);
+
+ return PCI_ERS_RESULT_NEED_RESET;
+}
+
+static pci_ers_result_t jsm_io_slot_reset(struct pci_dev *pdev)
+{
+ int rc;
+
+ rc = pci_enable_device(pdev);
+
+ if (rc)
+ return PCI_ERS_RESULT_DISCONNECT;
+
+ pci_set_master(pdev);
+
+ return PCI_ERS_RESULT_RECOVERED;
+}
+
+static void jsm_io_resume(struct pci_dev *pdev)
+{
+ struct jsm_board *brd = pci_get_drvdata(pdev);
+
+ pci_restore_state(pdev);
+
+ jsm_uart_port_init(brd);
+}
+
static int __init jsm_init_module(void)
{
int rc;
diff --git a/drivers/serial/jsm/jsm_tty.c b/drivers/serial/jsm/jsm_tty.c
index 1bcad59..cd95e21 100644
--- a/drivers/serial/jsm/jsm_tty.c
+++ b/drivers/serial/jsm/jsm_tty.c
@@ -430,7 +430,7 @@ int __devinit jsm_tty_init(struct jsm_board *brd)
return 0;
}
-int __devinit jsm_uart_port_init(struct jsm_board *brd)
+int jsm_uart_port_init(struct jsm_board *brd)
{
int i;
unsigned int line;
--
1.6.5.5
^ permalink raw reply related [flat|nested] 100+ messages in thread* [PATCH 09/58] tty: const: constify remaining tty_operations
2009-12-11 23:28 [GIT PATCH] TTY patches for 2.6.33-git Greg KH
` (7 preceding siblings ...)
2009-12-11 23:27 ` [PATCH 08/58] jsm: adding EEH handlers Greg Kroah-Hartman
@ 2009-12-11 23:27 ` Greg Kroah-Hartman
2009-12-11 23:27 ` [PATCH 10/58] tty: esp: remove broken driver Greg Kroah-Hartman
` (49 subsequent siblings)
58 siblings, 0 replies; 100+ messages in thread
From: Greg Kroah-Hartman @ 2009-12-11 23:27 UTC (permalink / raw)
To: linux-kernel; +Cc: Alexey Dobriyan, Greg Kroah-Hartman
From: Alexey Dobriyan <adobriyan@gmail.com>
Signed-off-by: Alexey Dobriyan <adobriyan@gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
---
arch/xtensa/platforms/iss/console.c | 2 +-
drivers/char/bfin_jtag_comm.c | 2 +-
drivers/char/epca.c | 2 +-
drivers/char/pcmcia/ipwireless/tty.c | 2 +-
4 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/arch/xtensa/platforms/iss/console.c b/arch/xtensa/platforms/iss/console.c
index 4c559cf..e60a1f5 100644
--- a/arch/xtensa/platforms/iss/console.c
+++ b/arch/xtensa/platforms/iss/console.c
@@ -196,7 +196,7 @@ static const struct file_operations rs_proc_fops = {
.release = single_release,
};
-static struct tty_operations serial_ops = {
+static const struct tty_operations serial_ops = {
.open = rs_open,
.close = rs_close,
.write = rs_write,
diff --git a/drivers/char/bfin_jtag_comm.c b/drivers/char/bfin_jtag_comm.c
index 1d7c34c..2628c74 100644
--- a/drivers/char/bfin_jtag_comm.c
+++ b/drivers/char/bfin_jtag_comm.c
@@ -226,7 +226,7 @@ bfin_jc_wait_until_sent(struct tty_struct *tty, int timeout)
}
}
-static struct tty_operations bfin_jc_ops = {
+static const struct tty_operations bfin_jc_ops = {
.open = bfin_jc_open,
.close = bfin_jc_close,
.write = bfin_jc_write,
diff --git a/drivers/char/epca.c b/drivers/char/epca.c
index dde5134..17b044a 100644
--- a/drivers/char/epca.c
+++ b/drivers/char/epca.c
@@ -935,7 +935,7 @@ static int info_open(struct tty_struct *tty, struct file *filp)
return 0;
}
-static struct tty_operations info_ops = {
+static const struct tty_operations info_ops = {
.open = info_open,
.ioctl = info_ioctl,
};
diff --git a/drivers/char/pcmcia/ipwireless/tty.c b/drivers/char/pcmcia/ipwireless/tty.c
index 674b3ab..2bb7874 100644
--- a/drivers/char/pcmcia/ipwireless/tty.c
+++ b/drivers/char/pcmcia/ipwireless/tty.c
@@ -603,7 +603,7 @@ void ipwireless_tty_free(struct ipw_tty *tty)
}
}
-static struct tty_operations tty_ops = {
+static const struct tty_operations tty_ops = {
.open = ipw_open,
.close = ipw_close,
.hangup = ipw_hangup,
--
1.6.5.5
^ permalink raw reply related [flat|nested] 100+ messages in thread* [PATCH 10/58] tty: esp: remove broken driver
2009-12-11 23:28 [GIT PATCH] TTY patches for 2.6.33-git Greg KH
` (8 preceding siblings ...)
2009-12-11 23:27 ` [PATCH 09/58] tty: const: constify remaining tty_operations Greg Kroah-Hartman
@ 2009-12-11 23:27 ` Greg Kroah-Hartman
2009-12-11 23:27 ` [PATCH 11/58] tty: istallion: Kill off the BKL ioctl Greg Kroah-Hartman
` (48 subsequent siblings)
58 siblings, 0 replies; 100+ messages in thread
From: Greg Kroah-Hartman @ 2009-12-11 23:27 UTC (permalink / raw)
To: linux-kernel; +Cc: Alan Cox, Greg Kroah-Hartman
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain, Size: 83234 bytes --]
From: Alan Cox <alan@linux.intel.com>
The ESP driver has been marked broken for years. It's an old ISA device
that clearly nobody cares about any more. Remove it
Signed-off-by: Alan Cox <alan@linux.intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
---
Documentation/serial/hayes-esp.txt | 154 ---
drivers/char/Kconfig | 13 -
drivers/char/Makefile | 1 -
drivers/char/esp.c | 2533 ------------------------------------
include/linux/Kbuild | 1 -
include/linux/hayesesp.h | 114 --
6 files changed, 0 insertions(+), 2816 deletions(-)
delete mode 100644 Documentation/serial/hayes-esp.txt
delete mode 100644 drivers/char/esp.c
delete mode 100644 include/linux/hayesesp.h
diff --git a/Documentation/serial/hayes-esp.txt b/Documentation/serial/hayes-esp.txt
deleted file mode 100644
index 09b5d58..0000000
--- a/Documentation/serial/hayes-esp.txt
+++ /dev/null
@@ -1,154 +0,0 @@
-HAYES ESP DRIVER VERSION 2.1
-
-A big thanks to the people at Hayes, especially Alan Adamson. Their support
-has enabled me to provide enhancements to the driver.
-
-Please report your experiences with this driver to me (arobinso@nyx.net). I
-am looking for both positive and negative feedback.
-
-*** IMPORTANT CHANGES FOR 2.1 ***
-Support for PIO mode. Five situations will cause PIO mode to be used:
-1) A multiport card is detected. PIO mode will always be used. (8 port cards
-do not support DMA).
-2) The DMA channel is set to an invalid value (anything other than 1 or 3).
-3) The DMA buffer/channel could not be allocated. The port will revert to PIO
-mode until it is reopened.
-4) Less than a specified number of bytes need to be transferred to/from the
-FIFOs. PIO mode will be used for that transfer only.
-5) A port needs to do a DMA transfer and another port is already using the
-DMA channel. PIO mode will be used for that transfer only.
-
-Since the Hayes ESP seems to conflict with other cards (notably sound cards)
-when using DMA, DMA is turned off by default. To use DMA, it must be turned
-on explicitly, either with the "dma=" option described below or with
-setserial. A multiport card can be forced into DMA mode by using setserial;
-however, most multiport cards don't support DMA.
-
-The latest version of setserial allows the enhanced configuration of the ESP
-card to be viewed and modified.
-***
-
-This package contains the files needed to compile a module to support the Hayes
-ESP card. The drivers are basically a modified version of the serial drivers.
-
-Features:
-
-- Uses the enhanced mode of the ESP card, allowing a wider range of
- interrupts and features than compatibility mode
-- Uses DMA and 16 bit PIO mode to transfer data to and from the ESP's FIFOs,
- reducing CPU load
-- Supports primary and secondary ports
-
-
-If the driver is compiled as a module, the IRQs to use can be specified by
-using the irq= option. The format is:
-
-irq=[0x100],[0x140],[0x180],[0x200],[0x240],[0x280],[0x300],[0x380]
-
-The address in brackets is the base address of the card. The IRQ of
-nonexistent cards can be set to 0. If an IRQ of a card that does exist is set
-to 0, the driver will attempt to guess at the correct IRQ. For example, to set
-the IRQ of the card at address 0x300 to 12, the insmod command would be:
-
-insmod esp irq=0,0,0,0,0,0,12,0
-
-The custom divisor can be set by using the divisor= option. The format is the
-same as for the irq= option. Each divisor value is a series of hex digits,
-with each digit representing the divisor to use for a corresponding port. The
-divisor value is constructed RIGHT TO LEFT. Specifying a nonzero divisor value
-will automatically set the spd_cust flag. To calculate the divisor to use for
-a certain baud rate, divide the port's base baud (generally 921600) by the
-desired rate. For example, to set the divisor of the primary port at 0x300 to
-4 and the divisor of the secondary port at 0x308 to 8, the insmod command would
-be:
-
-insmod esp divisor=0,0,0,0,0,0,0x84,0
-
-The dma= option can be used to set the DMA channel. The channel can be either
-1 or 3. Specifying any other value will force the driver to use PIO mode.
-For example, to set the DMA channel to 3, the insmod command would be:
-
-insmod esp dma=3
-
-The rx_trigger= and tx_trigger= options can be used to set the FIFO trigger
-levels. They specify when the ESP card should send an interrupt. Larger
-values will decrease the number of interrupts; however, a value too high may
-result in data loss. Valid values are 1 through 1023, with 768 being the
-default. For example, to set the receive trigger level to 512 bytes and the
-transmit trigger level to 700 bytes, the insmod command would be:
-
-insmod esp rx_trigger=512 tx_trigger=700
-
-The flow_off= and flow_on= options can be used to set the hardware flow off/
-flow on levels. The flow on level must be lower than the flow off level, and
-the flow off level should be higher than rx_trigger. Valid values are 1
-through 1023, with 1016 being the default flow off level and 944 being the
-default flow on level. For example, to set the flow off level to 1000 bytes
-and the flow on level to 935 bytes, the insmod command would be:
-
-insmod esp flow_off=1000 flow_on=935
-
-The rx_timeout= option can be used to set the receive timeout value. This
-value indicates how long after receiving the last character that the ESP card
-should wait before signalling an interrupt. Valid values are 0 though 255,
-with 128 being the default. A value too high will increase latency, and a
-value too low will cause unnecessary interrupts. For example, to set the
-receive timeout to 255, the insmod command would be:
-
-insmod esp rx_timeout=255
-
-The pio_threshold= option sets the threshold (in number of characters) for
-using PIO mode instead of DMA mode. For example, if this value is 32,
-transfers of 32 bytes or less will always use PIO mode.
-
-insmod esp pio_threshold=32
-
-Multiple options can be listed on the insmod command line by separating each
-option with a space. For example:
-
-insmod esp dma=3 trigger=512
-
-The esp module can be automatically loaded when needed. To cause this to
-happen, add the following lines to /etc/modprobe.conf (replacing the last line
-with options for your configuration):
-
-alias char-major-57 esp
-alias char-major-58 esp
-options esp irq=0,0,0,0,0,0,3,0 divisor=0,0,0,0,0,0,0x4,0
-
-You may also need to run 'depmod -a'.
-
-Devices must be created manually. To create the devices, note the output from
-the module after it is inserted. The output will appear in the location where
-kernel messages usually appear (usually /var/adm/messages). Create two devices
-for each 'tty' mentioned, one with major of 57 and the other with major of 58.
-The minor number should be the same as the tty number reported. The commands
-would be (replace ? with the tty number):
-
-mknod /dev/ttyP? c 57 ?
-mknod /dev/cup? c 58 ?
-
-For example, if the following line appears:
-
-Oct 24 18:17:23 techno kernel: ttyP8 at 0x0140 (irq = 3) is an ESP primary port
-
-...two devices should be created:
-
-mknod /dev/ttyP8 c 57 8
-mknod /dev/cup8 c 58 8
-
-You may need to set the permissions on the devices:
-
-chmod 666 /dev/ttyP*
-chmod 666 /dev/cup*
-
-The ESP module and the serial module should not conflict (they can be used at
-the same time). After the ESP module has been loaded the ports on the ESP card
-will no longer be accessible by the serial driver.
-
-If I/O errors are experienced when accessing the port, check for IRQ and DMA
-conflicts ('cat /proc/interrupts' and 'cat /proc/dma' for a list of IRQs and
-DMAs currently in use).
-
-Enjoy!
-Andrew J. Robinson <arobinso@nyx.net>
diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig
index 6aad99e..6f31c94 100644
--- a/drivers/char/Kconfig
+++ b/drivers/char/Kconfig
@@ -201,19 +201,6 @@ config DIGIEPCA
To compile this driver as a module, choose M here: the
module will be called epca.
-config ESPSERIAL
- tristate "Hayes ESP serial port support"
- depends on SERIAL_NONSTANDARD && ISA && ISA_DMA_API && BROKEN
- help
- This is a driver which supports Hayes ESP serial ports. Both single
- port cards and multiport cards are supported. Make sure to read
- <file:Documentation/hayes-esp.txt>.
-
- To compile this driver as a module, choose M here: the
- module will be called esp.
-
- If unsure, say N.
-
config MOXA_INTELLIO
tristate "Moxa Intellio support"
depends on SERIAL_NONSTANDARD && (ISA || EISA || PCI)
diff --git a/drivers/char/Makefile b/drivers/char/Makefile
index 19a79dd..f957edf 100644
--- a/drivers/char/Makefile
+++ b/drivers/char/Makefile
@@ -18,7 +18,6 @@ obj-$(CONFIG_CONSOLE_TRANSLATIONS) += consolemap.o consolemap_deftbl.o
obj-$(CONFIG_HW_CONSOLE) += vt.o defkeymap.o
obj-$(CONFIG_AUDIT) += tty_audit.o
obj-$(CONFIG_MAGIC_SYSRQ) += sysrq.o
-obj-$(CONFIG_ESPSERIAL) += esp.o
obj-$(CONFIG_MVME147_SCC) += generic_serial.o vme_scc.o
obj-$(CONFIG_MVME162_SCC) += generic_serial.o vme_scc.o
obj-$(CONFIG_BVME6000_SCC) += generic_serial.o vme_scc.o
diff --git a/drivers/char/esp.c b/drivers/char/esp.c
deleted file mode 100644
index b19d43c..0000000
--- a/drivers/char/esp.c
+++ /dev/null
@@ -1,2533 +0,0 @@
-/*
- * esp.c - driver for Hayes ESP serial cards
- *
- * --- Notices from serial.c, upon which this driver is based ---
- *
- * Copyright (C) 1991, 1992 Linus Torvalds
- *
- * Extensively rewritten by Theodore Ts'o, 8/16/92 -- 9/14/92. Now
- * much more extensible to support other serial cards based on the
- * 16450/16550A UART's. Added support for the AST FourPort and the
- * Accent Async board.
- *
- * set_serial_info fixed to set the flags, custom divisor, and uart
- * type fields. Fix suggested by Michael K. Johnson 12/12/92.
- *
- * 11/95: TIOCMIWAIT, TIOCGICOUNT by Angelo Haritsis <ah@doc.ic.ac.uk>
- *
- * 03/96: Modularised by Angelo Haritsis <ah@doc.ic.ac.uk>
- *
- * rs_set_termios fixed to look also for changes of the input
- * flags INPCK, BRKINT, PARMRK, IGNPAR and IGNBRK.
- * Bernd Anhäupl 05/17/96.
- *
- * --- End of notices from serial.c ---
- *
- * Support for the ESP serial card by Andrew J. Robinson
- * <arobinso@nyx.net> (Card detection routine taken from a patch
- * by Dennis J. Boylan). Patches to allow use with 2.1.x contributed
- * by Chris Faylor.
- *
- * Most recent changes: (Andrew J. Robinson)
- * Support for PIO mode. This allows the driver to work properly with
- * multiport cards.
- *
- * Arnaldo Carvalho de Melo <acme@conectiva.com.br> -
- * several cleanups, use module_init/module_exit, etc
- *
- * This module exports the following rs232 io functions:
- *
- * int espserial_init(void);
- */
-
-#include <linux/module.h>
-#include <linux/errno.h>
-#include <linux/signal.h>
-#include <linux/sched.h>
-#include <linux/interrupt.h>
-#include <linux/tty.h>
-#include <linux/tty_flip.h>
-#include <linux/serial.h>
-#include <linux/serialP.h>
-#include <linux/serial_reg.h>
-#include <linux/major.h>
-#include <linux/string.h>
-#include <linux/fcntl.h>
-#include <linux/ptrace.h>
-#include <linux/ioport.h>
-#include <linux/mm.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/bitops.h>
-
-#include <asm/system.h>
-#include <linux/io.h>
-
-#include <asm/dma.h>
-#include <linux/slab.h>
-#include <linux/uaccess.h>
-
-#include <linux/hayesesp.h>
-
-#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 */
-static unsigned int divisor[NR_PRIMARY]; /* custom divisor for each port */
-static unsigned int dma = ESP_DMA_CHANNEL; /* DMA channel */
-static unsigned int rx_trigger = ESP_RX_TRIGGER;
-static unsigned int tx_trigger = ESP_TX_TRIGGER;
-static unsigned int flow_off = ESP_FLOW_OFF;
-static unsigned int flow_on = ESP_FLOW_ON;
-static unsigned int rx_timeout = ESP_RX_TMOUT;
-static unsigned int pio_threshold = ESP_PIO_THRESHOLD;
-
-MODULE_LICENSE("GPL");
-
-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 */
-
-static char *dma_buffer;
-static int dma_bytes;
-static struct esp_pio_buffer *free_pio_buf;
-
-#define DMA_BUFFER_SZ 1024
-
-#define WAKEUP_CHARS 1024
-
-static char serial_name[] __initdata = "ESP serial driver";
-static char serial_version[] __initdata = "2.2";
-
-static struct tty_driver *esp_driver;
-
-/*
- * Serial driver configuration section. Here are the various options:
- *
- * SERIAL_PARANOIA_CHECK
- * Check the magic number for the esp_structure where
- * ever possible.
- */
-
-#undef SERIAL_PARANOIA_CHECK
-#define SERIAL_DO_RESTART
-
-#undef SERIAL_DEBUG_INTR
-#undef SERIAL_DEBUG_OPEN
-#undef SERIAL_DEBUG_FLOW
-
-#if defined(MODULE) && defined(SERIAL_DEBUG_MCOUNT)
-#define DBG_CNT(s) printk(KERN_DEBUG "(%s): [%x] refc=%d, serc=%d, ttyc=%d -> %s\n", \
- tty->name, info->port.flags, \
- serial_driver.refcount, \
- info->port.count, tty->count, s)
-#else
-#define DBG_CNT(s)
-#endif
-
-static struct esp_struct *ports;
-
-static void change_speed(struct esp_struct *info);
-static void rs_wait_until_sent(struct tty_struct *, int);
-
-/*
- * The ESP card has a clock rate of 14.7456 MHz (that is, 2**ESPC_SCALE
- * times the normal 1.8432 Mhz clock of most serial boards).
- */
-#define BASE_BAUD ((1843200 / 16) * (1 << ESPC_SCALE))
-
-/* Standard COM flags (except for COM4, because of the 8514 problem) */
-#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST)
-
-static inline int serial_paranoia_check(struct esp_struct *info,
- char *name, const char *routine)
-{
-#ifdef SERIAL_PARANOIA_CHECK
- static const char badmagic[] = KERN_WARNING
- "Warning: bad magic number for serial struct (%s) in %s\n";
- static const char badinfo[] = KERN_WARNING
- "Warning: null esp_struct for (%s) in %s\n";
-
- if (!info) {
- printk(badinfo, name, routine);
- return 1;
- }
- if (info->magic != ESP_MAGIC) {
- printk(badmagic, name, routine);
- return 1;
- }
-#endif
- return 0;
-}
-
-static inline unsigned int serial_in(struct esp_struct *info, int offset)
-{
- return inb(info->io_port + offset);
-}
-
-static inline void serial_out(struct esp_struct *info, int offset,
- unsigned char value)
-{
- outb(value, info->io_port+offset);
-}
-
-/*
- * ------------------------------------------------------------
- * rs_stop() and rs_start()
- *
- * This routines are called before setting or resetting tty->stopped.
- * They enable or disable transmitter interrupts, as necessary.
- * ------------------------------------------------------------
- */
-static void rs_stop(struct tty_struct *tty)
-{
- struct esp_struct *info = tty->driver_data;
- unsigned long flags;
-
- if (serial_paranoia_check(info, tty->name, "rs_stop"))
- return;
-
- spin_lock_irqsave(&info->lock, flags);
- if (info->IER & UART_IER_THRI) {
- info->IER &= ~UART_IER_THRI;
- serial_out(info, UART_ESI_CMD1, ESI_SET_SRV_MASK);
- serial_out(info, UART_ESI_CMD2, info->IER);
- }
- spin_unlock_irqrestore(&info->lock, flags);
-}
-
-static void rs_start(struct tty_struct *tty)
-{
- struct esp_struct *info = tty->driver_data;
- unsigned long flags;
-
- if (serial_paranoia_check(info, tty->name, "rs_start"))
- return;
-
- spin_lock_irqsave(&info->lock, flags);
- if (info->xmit_cnt && info->xmit_buf && !(info->IER & UART_IER_THRI)) {
- info->IER |= UART_IER_THRI;
- serial_out(info, UART_ESI_CMD1, ESI_SET_SRV_MASK);
- serial_out(info, UART_ESI_CMD2, info->IER);
- }
- spin_unlock_irqrestore(&info->lock, flags);
-}
-
-/*
- * ----------------------------------------------------------------------
- *
- * Here starts the interrupt handling routines. All of the following
- * subroutines are declared as inline and are folded into
- * rs_interrupt(). They were separated out for readability's sake.
- *
- * Note: rs_interrupt() is a "fast" interrupt, which means that it
- * runs with interrupts turned off. People who may want to modify
- * rs_interrupt() should try to keep the interrupt handler as fast as
- * possible. After you are done making modifications, it is not a bad
- * idea to do:
- *
- * gcc -S -DKERNEL -Wall -Wstrict-prototypes -O6 -fomit-frame-pointer serial.c
- *
- * and look at the resulting assemble code in serial.s.
- *
- * - Ted Ts'o (tytso@mit.edu), 7-Mar-93
- * -----------------------------------------------------------------------
- */
-
-static DEFINE_SPINLOCK(pio_lock);
-
-static inline struct esp_pio_buffer *get_pio_buffer(void)
-{
- struct esp_pio_buffer *buf;
- unsigned long flags;
-
- spin_lock_irqsave(&pio_lock, flags);
- if (free_pio_buf) {
- buf = free_pio_buf;
- free_pio_buf = buf->next;
- } else {
- buf = kmalloc(sizeof(struct esp_pio_buffer), GFP_ATOMIC);
- }
- spin_unlock_irqrestore(&pio_lock, flags);
- return buf;
-}
-
-static inline void release_pio_buffer(struct esp_pio_buffer *buf)
-{
- unsigned long flags;
- spin_lock_irqsave(&pio_lock, flags);
- buf->next = free_pio_buf;
- free_pio_buf = buf;
- spin_unlock_irqrestore(&pio_lock, flags);
-}
-
-static inline void receive_chars_pio(struct esp_struct *info, int num_bytes)
-{
- struct tty_struct *tty = info->port.tty;
- int i;
- struct esp_pio_buffer *pio_buf;
- struct esp_pio_buffer *err_buf;
- unsigned char status_mask;
-
- pio_buf = get_pio_buffer();
-
- if (!pio_buf)
- return;
-
- err_buf = get_pio_buffer();
-
- if (!err_buf) {
- release_pio_buffer(pio_buf);
- return;
- }
-
- status_mask = (info->read_status_mask >> 2) & 0x07;
-
- for (i = 0; i < num_bytes - 1; i += 2) {
- *((unsigned short *)(pio_buf->data + i)) =
- inw(info->io_port + UART_ESI_RX);
- err_buf->data[i] = serial_in(info, UART_ESI_RWS);
- err_buf->data[i + 1] = (err_buf->data[i] >> 3) & status_mask;
- err_buf->data[i] &= status_mask;
- }
-
- if (num_bytes & 0x0001) {
- pio_buf->data[num_bytes - 1] = serial_in(info, UART_ESI_RX);
- err_buf->data[num_bytes - 1] =
- (serial_in(info, UART_ESI_RWS) >> 3) & status_mask;
- }
-
- /* make sure everything is still ok since interrupts were enabled */
- tty = info->port.tty;
-
- if (!tty) {
- release_pio_buffer(pio_buf);
- release_pio_buffer(err_buf);
- info->stat_flags &= ~ESP_STAT_RX_TIMEOUT;
- return;
- }
-
- status_mask = (info->ignore_status_mask >> 2) & 0x07;
-
- for (i = 0; i < num_bytes; i++) {
- if (!(err_buf->data[i] & status_mask)) {
- int flag = 0;
-
- if (err_buf->data[i] & 0x04) {
- flag = TTY_BREAK;
- if (info->port.flags & ASYNC_SAK)
- do_SAK(tty);
- } else if (err_buf->data[i] & 0x02)
- flag = TTY_FRAME;
- else if (err_buf->data[i] & 0x01)
- flag = TTY_PARITY;
- tty_insert_flip_char(tty, pio_buf->data[i], flag);
- }
- }
-
- tty_schedule_flip(tty);
-
- info->stat_flags &= ~ESP_STAT_RX_TIMEOUT;
- release_pio_buffer(pio_buf);
- release_pio_buffer(err_buf);
-}
-
-static void program_isa_dma(int dma, int dir, unsigned long addr, int len)
-{
- unsigned long flags;
-
- flags = claim_dma_lock();
- disable_dma(dma);
- clear_dma_ff(dma);
- set_dma_mode(dma, dir);
- set_dma_addr(dma, addr);
- set_dma_count(dma, len);
- enable_dma(dma);
- release_dma_lock(flags);
-}
-
-static void receive_chars_dma(struct esp_struct *info, int num_bytes)
-{
- info->stat_flags &= ~ESP_STAT_RX_TIMEOUT;
- dma_bytes = num_bytes;
- info->stat_flags |= ESP_STAT_DMA_RX;
-
- program_isa_dma(dma, DMA_MODE_READ, isa_virt_to_bus(dma_buffer),
- dma_bytes);
- serial_out(info, UART_ESI_CMD1, ESI_START_DMA_RX);
-}
-
-static inline void receive_chars_dma_done(struct esp_struct *info,
- int status)
-{
- struct tty_struct *tty = info->port.tty;
- int num_bytes;
- unsigned long flags;
-
- flags = claim_dma_lock();
- disable_dma(dma);
- clear_dma_ff(dma);
-
- info->stat_flags &= ~ESP_STAT_DMA_RX;
- num_bytes = dma_bytes - get_dma_residue(dma);
- release_dma_lock(flags);
-
- info->icount.rx += num_bytes;
-
- if (num_bytes > 0) {
- tty_insert_flip_string(tty, dma_buffer, num_bytes - 1);
-
- status &= (0x1c & info->read_status_mask);
-
- /* Is the status significant or do we throw the last byte ? */
- if (!(status & info->ignore_status_mask)) {
- int statflag = 0;
-
- if (status & 0x10) {
- statflag = TTY_BREAK;
- (info->icount.brk)++;
- if (info->port.flags & ASYNC_SAK)
- do_SAK(tty);
- } else if (status & 0x08) {
- statflag = TTY_FRAME;
- info->icount.frame++;
- } else if (status & 0x04) {
- statflag = TTY_PARITY;
- info->icount.parity++;
- }
- tty_insert_flip_char(tty, dma_buffer[num_bytes - 1],
- statflag);
- }
- tty_schedule_flip(tty);
- }
-
- if (dma_bytes != num_bytes) {
- num_bytes = dma_bytes - num_bytes;
- dma_bytes = 0;
- receive_chars_dma(info, num_bytes);
- } else
- dma_bytes = 0;
-}
-
-/* Caller must hold info->lock */
-
-static inline void transmit_chars_pio(struct esp_struct *info,
- int space_avail)
-{
- int i;
- struct esp_pio_buffer *pio_buf;
-
- pio_buf = get_pio_buffer();
-
- if (!pio_buf)
- return;
-
- while (space_avail && info->xmit_cnt) {
- if (info->xmit_tail + space_avail <= ESP_XMIT_SIZE) {
- memcpy(pio_buf->data,
- &(info->xmit_buf[info->xmit_tail]),
- space_avail);
- } else {
- i = ESP_XMIT_SIZE - info->xmit_tail;
- memcpy(pio_buf->data,
- &(info->xmit_buf[info->xmit_tail]), i);
- memcpy(&(pio_buf->data[i]), info->xmit_buf,
- space_avail - i);
- }
-
- info->xmit_cnt -= space_avail;
- info->xmit_tail = (info->xmit_tail + space_avail) &
- (ESP_XMIT_SIZE - 1);
-
- for (i = 0; i < space_avail - 1; i += 2) {
- outw(*((unsigned short *)(pio_buf->data + i)),
- info->io_port + UART_ESI_TX);
- }
-
- if (space_avail & 0x0001)
- serial_out(info, UART_ESI_TX,
- pio_buf->data[space_avail - 1]);
-
- if (info->xmit_cnt) {
- serial_out(info, UART_ESI_CMD1, ESI_NO_COMMAND);
- serial_out(info, UART_ESI_CMD1, ESI_GET_TX_AVAIL);
- space_avail = serial_in(info, UART_ESI_STAT1) << 8;
- space_avail |= serial_in(info, UART_ESI_STAT2);
-
- if (space_avail > info->xmit_cnt)
- space_avail = info->xmit_cnt;
- }
- }
-
- if (info->xmit_cnt < WAKEUP_CHARS) {
- if (info->port.tty)
- tty_wakeup(info->port.tty);
-
-#ifdef SERIAL_DEBUG_INTR
- printk("THRE...");
-#endif
-
- if (info->xmit_cnt <= 0) {
- info->IER &= ~UART_IER_THRI;
- serial_out(info, UART_ESI_CMD1,
- ESI_SET_SRV_MASK);
- serial_out(info, UART_ESI_CMD2, info->IER);
- }
- }
-
- release_pio_buffer(pio_buf);
-}
-
-/* Caller must hold info->lock */
-static inline void transmit_chars_dma(struct esp_struct *info, int num_bytes)
-{
- dma_bytes = num_bytes;
-
- if (info->xmit_tail + dma_bytes <= ESP_XMIT_SIZE) {
- memcpy(dma_buffer, &(info->xmit_buf[info->xmit_tail]),
- dma_bytes);
- } else {
- int i = ESP_XMIT_SIZE - info->xmit_tail;
- memcpy(dma_buffer, &(info->xmit_buf[info->xmit_tail]),
- i);
- memcpy(&(dma_buffer[i]), info->xmit_buf, dma_bytes - i);
- }
-
- info->xmit_cnt -= dma_bytes;
- info->xmit_tail = (info->xmit_tail + dma_bytes) & (ESP_XMIT_SIZE - 1);
-
- if (info->xmit_cnt < WAKEUP_CHARS) {
- if (info->port.tty)
- tty_wakeup(info->port.tty);
-
-#ifdef SERIAL_DEBUG_INTR
- printk("THRE...");
-#endif
-
- if (info->xmit_cnt <= 0) {
- info->IER &= ~UART_IER_THRI;
- serial_out(info, UART_ESI_CMD1, ESI_SET_SRV_MASK);
- serial_out(info, UART_ESI_CMD2, info->IER);
- }
- }
-
- info->stat_flags |= ESP_STAT_DMA_TX;
-
- program_isa_dma(dma, DMA_MODE_WRITE, isa_virt_to_bus(dma_buffer),
- dma_bytes);
- serial_out(info, UART_ESI_CMD1, ESI_START_DMA_TX);
-}
-
-static inline void transmit_chars_dma_done(struct esp_struct *info)
-{
- int num_bytes;
- unsigned long flags;
-
- flags = claim_dma_lock();
- disable_dma(dma);
- clear_dma_ff(dma);
-
- num_bytes = dma_bytes - get_dma_residue(dma);
- info->icount.tx += dma_bytes;
- release_dma_lock(flags);
-
- if (dma_bytes != num_bytes) {
- dma_bytes -= num_bytes;
- memmove(dma_buffer, dma_buffer + num_bytes, dma_bytes);
-
- program_isa_dma(dma, DMA_MODE_WRITE,
- isa_virt_to_bus(dma_buffer), dma_bytes);
-
- serial_out(info, UART_ESI_CMD1, ESI_START_DMA_TX);
- } else {
- dma_bytes = 0;
- info->stat_flags &= ~ESP_STAT_DMA_TX;
- }
-}
-
-static void check_modem_status(struct esp_struct *info)
-{
- int status;
-
- serial_out(info, UART_ESI_CMD1, ESI_GET_UART_STAT);
- status = serial_in(info, UART_ESI_STAT2);
-
- if (status & UART_MSR_ANY_DELTA) {
- /* update input line counters */
- if (status & UART_MSR_TERI)
- info->icount.rng++;
- if (status & UART_MSR_DDSR)
- info->icount.dsr++;
- if (status & UART_MSR_DDCD)
- info->icount.dcd++;
- if (status & UART_MSR_DCTS)
- info->icount.cts++;
- wake_up_interruptible(&info->port.delta_msr_wait);
- }
-
- if ((info->port.flags & ASYNC_CHECK_CD) && (status & UART_MSR_DDCD)) {
-#if (defined(SERIAL_DEBUG_OPEN) || defined(SERIAL_DEBUG_INTR))
- printk("ttys%d CD now %s...", info->line,
- (status & UART_MSR_DCD) ? "on" : "off");
-#endif
- if (status & UART_MSR_DCD)
- wake_up_interruptible(&info->port.open_wait);
- else {
-#ifdef SERIAL_DEBUG_OPEN
- printk("scheduling hangup...");
-#endif
- tty_hangup(info->port.tty);
- }
- }
-}
-
-/*
- * This is the serial driver's interrupt routine
- */
-static irqreturn_t rs_interrupt_single(int irq, void *dev_id)
-{
- struct esp_struct *info;
- unsigned err_status;
- unsigned int scratch;
-
-#ifdef SERIAL_DEBUG_INTR
- printk("rs_interrupt_single(%d)...", irq);
-#endif
- info = (struct esp_struct *)dev_id;
- err_status = 0;
- scratch = serial_in(info, UART_ESI_SID);
-
- spin_lock(&info->lock);
-
- if (!info->port.tty) {
- spin_unlock(&info->lock);
- return IRQ_NONE;
- }
-
- if (scratch & 0x04) { /* error */
- serial_out(info, UART_ESI_CMD1, ESI_GET_ERR_STAT);
- err_status = serial_in(info, UART_ESI_STAT1);
- serial_in(info, UART_ESI_STAT2);
-
- if (err_status & 0x01)
- info->stat_flags |= ESP_STAT_RX_TIMEOUT;
-
- if (err_status & 0x20) /* UART status */
- check_modem_status(info);
-
- if (err_status & 0x80) /* Start break */
- wake_up_interruptible(&info->break_wait);
- }
-
- if ((scratch & 0x88) || /* DMA completed or timed out */
- (err_status & 0x1c) /* receive error */) {
- if (info->stat_flags & ESP_STAT_DMA_RX)
- receive_chars_dma_done(info, err_status);
- else if (info->stat_flags & ESP_STAT_DMA_TX)
- transmit_chars_dma_done(info);
- }
-
- if (!(info->stat_flags & (ESP_STAT_DMA_RX | ESP_STAT_DMA_TX)) &&
- ((scratch & 0x01) || (info->stat_flags & ESP_STAT_RX_TIMEOUT)) &&
- (info->IER & UART_IER_RDI)) {
- int num_bytes;
-
- serial_out(info, UART_ESI_CMD1, ESI_NO_COMMAND);
- serial_out(info, UART_ESI_CMD1, ESI_GET_RX_AVAIL);
- num_bytes = serial_in(info, UART_ESI_STAT1) << 8;
- num_bytes |= serial_in(info, UART_ESI_STAT2);
-
- num_bytes = tty_buffer_request_room(info->port.tty, num_bytes);
-
- if (num_bytes) {
- if (dma_bytes ||
- (info->stat_flags & ESP_STAT_USE_PIO) ||
- (num_bytes <= info->config.pio_threshold))
- receive_chars_pio(info, num_bytes);
- else
- receive_chars_dma(info, num_bytes);
- }
- }
-
- if (!(info->stat_flags & (ESP_STAT_DMA_RX | ESP_STAT_DMA_TX)) &&
- (scratch & 0x02) && (info->IER & UART_IER_THRI)) {
- if ((info->xmit_cnt <= 0) || info->port.tty->stopped) {
- info->IER &= ~UART_IER_THRI;
- serial_out(info, UART_ESI_CMD1, ESI_SET_SRV_MASK);
- serial_out(info, UART_ESI_CMD2, info->IER);
- } else {
- int num_bytes;
-
- serial_out(info, UART_ESI_CMD1, ESI_NO_COMMAND);
- serial_out(info, UART_ESI_CMD1, ESI_GET_TX_AVAIL);
- num_bytes = serial_in(info, UART_ESI_STAT1) << 8;
- num_bytes |= serial_in(info, UART_ESI_STAT2);
-
- if (num_bytes > info->xmit_cnt)
- num_bytes = info->xmit_cnt;
-
- if (num_bytes) {
- if (dma_bytes ||
- (info->stat_flags & ESP_STAT_USE_PIO) ||
- (num_bytes <= info->config.pio_threshold))
- transmit_chars_pio(info, num_bytes);
- else
- transmit_chars_dma(info, num_bytes);
- }
- }
- }
-
- info->last_active = jiffies;
-
-#ifdef SERIAL_DEBUG_INTR
- printk("end.\n");
-#endif
- spin_unlock(&info->lock);
- return IRQ_HANDLED;
-}
-
-/*
- * -------------------------------------------------------------------
- * Here ends the serial interrupt routines.
- * -------------------------------------------------------------------
- */
-
-/*
- * ---------------------------------------------------------------
- * Low level utility subroutines for the serial driver: routines to
- * figure out the appropriate timeout for an interrupt chain, routines
- * to initialize and startup a serial port, and routines to shutdown a
- * serial port. Useful stuff like that.
- *
- * Caller should hold lock
- * ---------------------------------------------------------------
- */
-
-static void esp_basic_init(struct esp_struct *info)
-{
- /* put ESPC in enhanced mode */
- serial_out(info, UART_ESI_CMD1, ESI_SET_MODE);
-
- if (info->stat_flags & ESP_STAT_NEVER_DMA)
- serial_out(info, UART_ESI_CMD2, 0x01);
- else
- serial_out(info, UART_ESI_CMD2, 0x31);
-
- /* disable interrupts for now */
- serial_out(info, UART_ESI_CMD1, ESI_SET_SRV_MASK);
- serial_out(info, UART_ESI_CMD2, 0x00);
-
- /* set interrupt and DMA channel */
- serial_out(info, UART_ESI_CMD1, ESI_SET_IRQ);
-
- if (info->stat_flags & ESP_STAT_NEVER_DMA)
- serial_out(info, UART_ESI_CMD2, 0x01);
- else
- serial_out(info, UART_ESI_CMD2, (dma << 4) | 0x01);
-
- serial_out(info, UART_ESI_CMD1, ESI_SET_ENH_IRQ);
-
- if (info->line % 8) /* secondary port */
- serial_out(info, UART_ESI_CMD2, 0x0d); /* shared */
- else if (info->irq == 9)
- serial_out(info, UART_ESI_CMD2, 0x02);
- else
- serial_out(info, UART_ESI_CMD2, info->irq);
-
- /* set error status mask (check this) */
- serial_out(info, UART_ESI_CMD1, ESI_SET_ERR_MASK);
-
- if (info->stat_flags & ESP_STAT_NEVER_DMA)
- serial_out(info, UART_ESI_CMD2, 0xa1);
- else
- serial_out(info, UART_ESI_CMD2, 0xbd);
-
- serial_out(info, UART_ESI_CMD2, 0x00);
-
- /* set DMA timeout */
- serial_out(info, UART_ESI_CMD1, ESI_SET_DMA_TMOUT);
- serial_out(info, UART_ESI_CMD2, 0xff);
-
- /* set FIFO trigger levels */
- serial_out(info, UART_ESI_CMD1, ESI_SET_TRIGGER);
- serial_out(info, UART_ESI_CMD2, info->config.rx_trigger >> 8);
- serial_out(info, UART_ESI_CMD2, info->config.rx_trigger);
- serial_out(info, UART_ESI_CMD2, info->config.tx_trigger >> 8);
- serial_out(info, UART_ESI_CMD2, info->config.tx_trigger);
-
- /* Set clock scaling and wait states */
- serial_out(info, UART_ESI_CMD1, ESI_SET_PRESCALAR);
- serial_out(info, UART_ESI_CMD2, 0x04 | ESPC_SCALE);
-
- /* set reinterrupt pacing */
- serial_out(info, UART_ESI_CMD1, ESI_SET_REINTR);
- serial_out(info, UART_ESI_CMD2, 0xff);
-}
-
-static int startup(struct esp_struct *info)
-{
- unsigned long flags;
- int retval = 0;
- unsigned int num_chars;
-
- spin_lock_irqsave(&info->lock, flags);
-
- if (info->port.flags & ASYNC_INITIALIZED)
- goto out;
-
- if (!info->xmit_buf) {
- info->xmit_buf = (unsigned char *)get_zeroed_page(GFP_ATOMIC);
- retval = -ENOMEM;
- if (!info->xmit_buf)
- goto out;
- }
-
-#ifdef SERIAL_DEBUG_OPEN
- printk(KERN_DEBUG "starting up ttys%d (irq %d)...",
- info->line, info->irq);
-#endif
-
- /* Flush the RX buffer. Using the ESI flush command may cause */
- /* wild interrupts, so read all the data instead. */
-
- serial_out(info, UART_ESI_CMD1, ESI_NO_COMMAND);
- serial_out(info, UART_ESI_CMD1, ESI_GET_RX_AVAIL);
- num_chars = serial_in(info, UART_ESI_STAT1) << 8;
- num_chars |= serial_in(info, UART_ESI_STAT2);
-
- while (num_chars > 1) {
- inw(info->io_port + UART_ESI_RX);
- num_chars -= 2;
- }
-
- if (num_chars)
- serial_in(info, UART_ESI_RX);
-
- /* set receive character timeout */
- serial_out(info, UART_ESI_CMD1, ESI_SET_RX_TIMEOUT);
- serial_out(info, UART_ESI_CMD2, info->config.rx_timeout);
-
- /* clear all flags except the "never DMA" flag */
- info->stat_flags &= ESP_STAT_NEVER_DMA;
-
- if (info->stat_flags & ESP_STAT_NEVER_DMA)
- info->stat_flags |= ESP_STAT_USE_PIO;
-
- spin_unlock_irqrestore(&info->lock, flags);
-
- /*
- * Allocate the IRQ
- */
-
- retval = request_irq(info->irq, rs_interrupt_single, IRQF_SHARED,
- "esp serial", info);
-
- if (retval) {
- if (capable(CAP_SYS_ADMIN)) {
- if (info->port.tty)
- set_bit(TTY_IO_ERROR,
- &info->port.tty->flags);
- retval = 0;
- }
- goto out_unlocked;
- }
-
- if (!(info->stat_flags & ESP_STAT_USE_PIO) && !dma_buffer) {
- dma_buffer = (char *)__get_dma_pages(
- GFP_KERNEL, get_order(DMA_BUFFER_SZ));
-
- /* use PIO mode if DMA buf/chan cannot be allocated */
- if (!dma_buffer)
- info->stat_flags |= ESP_STAT_USE_PIO;
- else if (request_dma(dma, "esp serial")) {
- free_pages((unsigned long)dma_buffer,
- get_order(DMA_BUFFER_SZ));
- dma_buffer = NULL;
- info->stat_flags |= ESP_STAT_USE_PIO;
- }
-
- }
-
- info->MCR = UART_MCR_DTR | UART_MCR_RTS | UART_MCR_OUT2;
-
- spin_lock_irqsave(&info->lock, flags);
- serial_out(info, UART_ESI_CMD1, ESI_WRITE_UART);
- serial_out(info, UART_ESI_CMD2, UART_MCR);
- serial_out(info, UART_ESI_CMD2, info->MCR);
-
- /*
- * Finally, enable interrupts
- */
- /* info->IER = UART_IER_MSI | UART_IER_RLSI | UART_IER_RDI; */
- info->IER = UART_IER_RLSI | UART_IER_RDI | UART_IER_DMA_TMOUT |
- UART_IER_DMA_TC;
- serial_out(info, UART_ESI_CMD1, ESI_SET_SRV_MASK);
- serial_out(info, UART_ESI_CMD2, info->IER);
-
- if (info->port.tty)
- clear_bit(TTY_IO_ERROR, &info->port.tty->flags);
- info->xmit_cnt = info->xmit_head = info->xmit_tail = 0;
- spin_unlock_irqrestore(&info->lock, flags);
-
- /*
- * Set up the tty->alt_speed kludge
- */
- if (info->port.tty) {
- if ((info->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI)
- info->port.tty->alt_speed = 57600;
- if ((info->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI)
- info->port.tty->alt_speed = 115200;
- if ((info->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_SHI)
- info->port.tty->alt_speed = 230400;
- if ((info->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_WARP)
- info->port.tty->alt_speed = 460800;
- }
-
- /*
- * set the speed of the serial port
- */
- change_speed(info);
- info->port.flags |= ASYNC_INITIALIZED;
- return 0;
-
-out:
- spin_unlock_irqrestore(&info->lock, flags);
-out_unlocked:
- return retval;
-}
-
-/*
- * This routine will shutdown a serial port; interrupts are disabled, and
- * DTR is dropped if the hangup on close termio flag is on.
- */
-static void shutdown(struct esp_struct *info)
-{
- unsigned long flags, f;
-
- if (!(info->port.flags & ASYNC_INITIALIZED))
- return;
-
-#ifdef SERIAL_DEBUG_OPEN
- printk("Shutting down serial port %d (irq %d)....", info->line,
- info->irq);
-#endif
-
- spin_lock_irqsave(&info->lock, flags);
- /*
- * clear delta_msr_wait queue to avoid mem leaks: we may free the irq
- * here so the queue might never be waken up
- */
- wake_up_interruptible(&info->port.delta_msr_wait);
- wake_up_interruptible(&info->break_wait);
-
- /* stop a DMA transfer on the port being closed */
- /* DMA lock is higher priority always */
- if (info->stat_flags & (ESP_STAT_DMA_RX | ESP_STAT_DMA_TX)) {
- f = claim_dma_lock();
- disable_dma(dma);
- clear_dma_ff(dma);
- release_dma_lock(f);
-
- dma_bytes = 0;
- }
-
- /*
- * Free the IRQ
- */
- free_irq(info->irq, info);
-
- if (dma_buffer) {
- struct esp_struct *current_port = ports;
-
- while (current_port) {
- if ((current_port != info) &&
- (current_port->port.flags & ASYNC_INITIALIZED))
- break;
-
- current_port = current_port->next_port;
- }
-
- if (!current_port) {
- free_dma(dma);
- free_pages((unsigned long)dma_buffer,
- get_order(DMA_BUFFER_SZ));
- dma_buffer = NULL;
- }
- }
-
- if (info->xmit_buf) {
- free_page((unsigned long) info->xmit_buf);
- info->xmit_buf = NULL;
- }
-
- info->IER = 0;
- serial_out(info, UART_ESI_CMD1, ESI_SET_SRV_MASK);
- serial_out(info, UART_ESI_CMD2, 0x00);
-
- if (!info->port.tty || (info->port.tty->termios->c_cflag & HUPCL))
- info->MCR &= ~(UART_MCR_DTR|UART_MCR_RTS);
-
- info->MCR &= ~UART_MCR_OUT2;
- serial_out(info, UART_ESI_CMD1, ESI_WRITE_UART);
- serial_out(info, UART_ESI_CMD2, UART_MCR);
- serial_out(info, UART_ESI_CMD2, info->MCR);
-
- if (info->port.tty)
- set_bit(TTY_IO_ERROR, &info->port.tty->flags);
-
- info->port.flags &= ~ASYNC_INITIALIZED;
- spin_unlock_irqrestore(&info->lock, flags);
-}
-
-/*
- * This routine is called to set the UART divisor registers to match
- * the specified baud rate for a serial port.
- */
-static void change_speed(struct esp_struct *info)
-{
- unsigned short port;
- int quot = 0;
- unsigned cflag, cval;
- int baud, bits;
- unsigned char flow1 = 0, flow2 = 0;
- unsigned long flags;
-
- if (!info->port.tty || !info->port.tty->termios)
- return;
- cflag = info->port.tty->termios->c_cflag;
- port = info->io_port;
-
- /* byte size and parity */
- switch (cflag & CSIZE) {
- case CS5: cval = 0x00; bits = 7; break;
- case CS6: cval = 0x01; bits = 8; break;
- case CS7: cval = 0x02; bits = 9; break;
- case CS8: cval = 0x03; bits = 10; break;
- default: cval = 0x00; bits = 7; break;
- }
- if (cflag & CSTOPB) {
- cval |= 0x04;
- bits++;
- }
- if (cflag & PARENB) {
- cval |= UART_LCR_PARITY;
- bits++;
- }
- if (!(cflag & PARODD))
- cval |= UART_LCR_EPAR;
-#ifdef CMSPAR
- if (cflag & CMSPAR)
- cval |= UART_LCR_SPAR;
-#endif
- baud = tty_get_baud_rate(info->port.tty);
- if (baud == 38400 &&
- ((info->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST))
- quot = info->custom_divisor;
- else {
- if (baud == 134) /* Special case since 134 is really 134.5 */
- quot = (2*BASE_BAUD / 269);
- else if (baud)
- quot = BASE_BAUD / baud;
- }
- /* If the quotient is ever zero, default to 9600 bps */
- if (!quot)
- quot = BASE_BAUD / 9600;
-
- if (baud) {
- /* Actual rate */
- baud = BASE_BAUD/quot;
- tty_encode_baud_rate(info->port.tty, baud, baud);
- }
- info->timeout = ((1024 * HZ * bits * quot) / BASE_BAUD) + (HZ / 50);
-
- /* CTS flow control flag and modem status interrupts */
- /* info->IER &= ~UART_IER_MSI; */
- if (cflag & CRTSCTS) {
- info->port.flags |= ASYNC_CTS_FLOW;
- /* info->IER |= UART_IER_MSI; */
- flow1 = 0x04;
- flow2 = 0x10;
- } else
- info->port.flags &= ~ASYNC_CTS_FLOW;
- if (cflag & CLOCAL)
- info->port.flags &= ~ASYNC_CHECK_CD;
- else
- info->port.flags |= ASYNC_CHECK_CD;
-
- /*
- * Set up parity check flag
- */
- info->read_status_mask = UART_LSR_OE | UART_LSR_THRE | UART_LSR_DR;
- if (I_INPCK(info->port.tty))
- info->read_status_mask |= UART_LSR_FE | UART_LSR_PE;
- if (I_BRKINT(info->port.tty) || I_PARMRK(info->port.tty))
- info->read_status_mask |= UART_LSR_BI;
-
- info->ignore_status_mask = 0;
-#if 0
- /* This should be safe, but for some broken bits of hardware... */
- if (I_IGNPAR(info->port.tty)) {
- info->ignore_status_mask |= UART_LSR_PE | UART_LSR_FE;
- info->read_status_mask |= UART_LSR_PE | UART_LSR_FE;
- }
-#endif
- if (I_IGNBRK(info->port.tty)) {
- info->ignore_status_mask |= UART_LSR_BI;
- info->read_status_mask |= UART_LSR_BI;
- /*
- * If we're ignore parity and break indicators, ignore
- * overruns too. (For real raw support).
- */
- if (I_IGNPAR(info->port.tty)) {
- info->ignore_status_mask |= UART_LSR_OE | \
- UART_LSR_PE | UART_LSR_FE;
- info->read_status_mask |= UART_LSR_OE | \
- UART_LSR_PE | UART_LSR_FE;
- }
- }
-
- if (I_IXOFF(info->port.tty))
- flow1 |= 0x81;
-
- spin_lock_irqsave(&info->lock, flags);
- /* set baud */
- serial_out(info, UART_ESI_CMD1, ESI_SET_BAUD);
- serial_out(info, UART_ESI_CMD2, quot >> 8);
- serial_out(info, UART_ESI_CMD2, quot & 0xff);
-
- /* set data bits, parity, etc. */
- serial_out(info, UART_ESI_CMD1, ESI_WRITE_UART);
- serial_out(info, UART_ESI_CMD2, UART_LCR);
- serial_out(info, UART_ESI_CMD2, cval);
-
- /* Enable flow control */
- serial_out(info, UART_ESI_CMD1, ESI_SET_FLOW_CNTL);
- serial_out(info, UART_ESI_CMD2, flow1);
- serial_out(info, UART_ESI_CMD2, flow2);
-
- /* set flow control characters (XON/XOFF only) */
- if (I_IXOFF(info->port.tty)) {
- serial_out(info, UART_ESI_CMD1, ESI_SET_FLOW_CHARS);
- serial_out(info, UART_ESI_CMD2, START_CHAR(info->port.tty));
- serial_out(info, UART_ESI_CMD2, STOP_CHAR(info->port.tty));
- serial_out(info, UART_ESI_CMD2, 0x10);
- serial_out(info, UART_ESI_CMD2, 0x21);
- switch (cflag & CSIZE) {
- case CS5:
- serial_out(info, UART_ESI_CMD2, 0x1f);
- break;
- case CS6:
- serial_out(info, UART_ESI_CMD2, 0x3f);
- break;
- case CS7:
- case CS8:
- serial_out(info, UART_ESI_CMD2, 0x7f);
- break;
- default:
- serial_out(info, UART_ESI_CMD2, 0xff);
- break;
- }
- }
-
- /* Set high/low water */
- serial_out(info, UART_ESI_CMD1, ESI_SET_FLOW_LVL);
- serial_out(info, UART_ESI_CMD2, info->config.flow_off >> 8);
- serial_out(info, UART_ESI_CMD2, info->config.flow_off);
- serial_out(info, UART_ESI_CMD2, info->config.flow_on >> 8);
- serial_out(info, UART_ESI_CMD2, info->config.flow_on);
-
- spin_unlock_irqrestore(&info->lock, flags);
-}
-
-static int rs_put_char(struct tty_struct *tty, unsigned char ch)
-{
- struct esp_struct *info = tty->driver_data;
- unsigned long flags;
- int ret = 0;
-
- if (serial_paranoia_check(info, tty->name, "rs_put_char"))
- return 0;
-
- if (!info->xmit_buf)
- return 0;
-
- spin_lock_irqsave(&info->lock, flags);
- if (info->xmit_cnt < ESP_XMIT_SIZE - 1) {
- info->xmit_buf[info->xmit_head++] = ch;
- info->xmit_head &= ESP_XMIT_SIZE-1;
- info->xmit_cnt++;
- ret = 1;
- }
- spin_unlock_irqrestore(&info->lock, flags);
- return ret;
-}
-
-static void rs_flush_chars(struct tty_struct *tty)
-{
- struct esp_struct *info = tty->driver_data;
- unsigned long flags;
-
- if (serial_paranoia_check(info, tty->name, "rs_flush_chars"))
- return;
-
- spin_lock_irqsave(&info->lock, flags);
-
- if (info->xmit_cnt <= 0 || tty->stopped || !info->xmit_buf)
- goto out;
-
- if (!(info->IER & UART_IER_THRI)) {
- info->IER |= UART_IER_THRI;
- serial_out(info, UART_ESI_CMD1, ESI_SET_SRV_MASK);
- serial_out(info, UART_ESI_CMD2, info->IER);
- }
-out:
- spin_unlock_irqrestore(&info->lock, flags);
-}
-
-static int rs_write(struct tty_struct *tty,
- const unsigned char *buf, int count)
-{
- int c, t, ret = 0;
- struct esp_struct *info = tty->driver_data;
- unsigned long flags;
-
- if (serial_paranoia_check(info, tty->name, "rs_write"))
- return 0;
-
- if (!info->xmit_buf)
- return 0;
-
- while (1) {
- /* Thanks to R. Wolff for suggesting how to do this with */
- /* interrupts enabled */
-
- c = count;
- t = ESP_XMIT_SIZE - info->xmit_cnt - 1;
-
- if (t < c)
- c = t;
-
- t = ESP_XMIT_SIZE - info->xmit_head;
-
- if (t < c)
- c = t;
-
- if (c <= 0)
- break;
-
- memcpy(info->xmit_buf + info->xmit_head, buf, c);
-
- info->xmit_head = (info->xmit_head + c) & (ESP_XMIT_SIZE-1);
- info->xmit_cnt += c;
- buf += c;
- count -= c;
- ret += c;
- }
-
- spin_lock_irqsave(&info->lock, flags);
-
- if (info->xmit_cnt && !tty->stopped && !(info->IER & UART_IER_THRI)) {
- info->IER |= UART_IER_THRI;
- serial_out(info, UART_ESI_CMD1, ESI_SET_SRV_MASK);
- serial_out(info, UART_ESI_CMD2, info->IER);
- }
-
- spin_unlock_irqrestore(&info->lock, flags);
- return ret;
-}
-
-static int rs_write_room(struct tty_struct *tty)
-{
- struct esp_struct *info = tty->driver_data;
- int ret;
- unsigned long flags;
-
- if (serial_paranoia_check(info, tty->name, "rs_write_room"))
- return 0;
-
- spin_lock_irqsave(&info->lock, flags);
-
- ret = ESP_XMIT_SIZE - info->xmit_cnt - 1;
- if (ret < 0)
- ret = 0;
- spin_unlock_irqrestore(&info->lock, flags);
- return ret;
-}
-
-static int rs_chars_in_buffer(struct tty_struct *tty)
-{
- struct esp_struct *info = tty->driver_data;
-
- if (serial_paranoia_check(info, tty->name, "rs_chars_in_buffer"))
- return 0;
- return info->xmit_cnt;
-}
-
-static void rs_flush_buffer(struct tty_struct *tty)
-{
- struct esp_struct *info = tty->driver_data;
- unsigned long flags;
-
- if (serial_paranoia_check(info, tty->name, "rs_flush_buffer"))
- return;
- spin_lock_irqsave(&info->lock, flags);
- info->xmit_cnt = info->xmit_head = info->xmit_tail = 0;
- spin_unlock_irqrestore(&info->lock, flags);
- tty_wakeup(tty);
-}
-
-/*
- * ------------------------------------------------------------
- * rs_throttle()
- *
- * This routine is called by the upper-layer tty layer to signal that
- * incoming characters should be throttled.
- * ------------------------------------------------------------
- */
-static void rs_throttle(struct tty_struct *tty)
-{
- struct esp_struct *info = tty->driver_data;
- unsigned long flags;
-#ifdef SERIAL_DEBUG_THROTTLE
- char buf[64];
-
- printk("throttle %s: %d....\n", tty_name(tty, buf),
- tty_chars_in_buffer(tty));
-#endif
-
- if (serial_paranoia_check(info, tty->name, "rs_throttle"))
- return;
-
- spin_lock_irqsave(&info->lock, flags);
- info->IER &= ~UART_IER_RDI;
- serial_out(info, UART_ESI_CMD1, ESI_SET_SRV_MASK);
- serial_out(info, UART_ESI_CMD2, info->IER);
- serial_out(info, UART_ESI_CMD1, ESI_SET_RX_TIMEOUT);
- serial_out(info, UART_ESI_CMD2, 0x00);
- spin_unlock_irqrestore(&info->lock, flags);
-}
-
-static void rs_unthrottle(struct tty_struct *tty)
-{
- struct esp_struct *info = tty->driver_data;
- unsigned long flags;
-#ifdef SERIAL_DEBUG_THROTTLE
- char buf[64];
-
- printk(KERN_DEBUG "unthrottle %s: %d....\n", tty_name(tty, buf),
- tty_chars_in_buffer(tty));
-#endif
-
- if (serial_paranoia_check(info, tty->name, "rs_unthrottle"))
- return;
-
- spin_lock_irqsave(&info->lock, flags);
- info->IER |= UART_IER_RDI;
- serial_out(info, UART_ESI_CMD1, ESI_SET_SRV_MASK);
- serial_out(info, UART_ESI_CMD2, info->IER);
- serial_out(info, UART_ESI_CMD1, ESI_SET_RX_TIMEOUT);
- serial_out(info, UART_ESI_CMD2, info->config.rx_timeout);
- spin_unlock_irqrestore(&info->lock, flags);
-}
-
-/*
- * ------------------------------------------------------------
- * rs_ioctl() and friends
- * ------------------------------------------------------------
- */
-
-static int get_serial_info(struct esp_struct *info,
- struct serial_struct __user *retinfo)
-{
- struct serial_struct tmp;
-
- lock_kernel();
- memset(&tmp, 0, sizeof(tmp));
- tmp.type = PORT_16550A;
- tmp.line = info->line;
- tmp.port = info->io_port;
- tmp.irq = info->irq;
- tmp.flags = info->port.flags;
- tmp.xmit_fifo_size = 1024;
- tmp.baud_base = BASE_BAUD;
- tmp.close_delay = info->close_delay;
- tmp.closing_wait = info->closing_wait;
- tmp.custom_divisor = info->custom_divisor;
- tmp.hub6 = 0;
- unlock_kernel();
- if (copy_to_user(retinfo, &tmp, sizeof(*retinfo)))
- return -EFAULT;
- return 0;
-}
-
-static int get_esp_config(struct esp_struct *info,
- struct hayes_esp_config __user *retinfo)
-{
- struct hayes_esp_config tmp;
-
- if (!retinfo)
- return -EFAULT;
-
- memset(&tmp, 0, sizeof(tmp));
- lock_kernel();
- tmp.rx_timeout = info->config.rx_timeout;
- tmp.rx_trigger = info->config.rx_trigger;
- tmp.tx_trigger = info->config.tx_trigger;
- tmp.flow_off = info->config.flow_off;
- tmp.flow_on = info->config.flow_on;
- tmp.pio_threshold = info->config.pio_threshold;
- tmp.dma_channel = (info->stat_flags & ESP_STAT_NEVER_DMA ? 0 : dma);
- unlock_kernel();
-
- return copy_to_user(retinfo, &tmp, sizeof(*retinfo)) ? -EFAULT : 0;
-}
-
-static int set_serial_info(struct esp_struct *info,
- struct serial_struct __user *new_info)
-{
- struct serial_struct new_serial;
- struct esp_struct old_info;
- unsigned int change_irq;
- int retval = 0;
- struct esp_struct *current_async;
-
- if (copy_from_user(&new_serial, new_info, sizeof(new_serial)))
- return -EFAULT;
- old_info = *info;
-
- if ((new_serial.type != PORT_16550A) ||
- (new_serial.hub6) ||
- (info->io_port != new_serial.port) ||
- (new_serial.baud_base != BASE_BAUD) ||
- (new_serial.irq > 15) ||
- (new_serial.irq < 2) ||
- (new_serial.irq == 6) ||
- (new_serial.irq == 8) ||
- (new_serial.irq == 13))
- return -EINVAL;
-
- change_irq = new_serial.irq != info->irq;
-
- if (change_irq && (info->line % 8))
- return -EINVAL;
-
- if (!capable(CAP_SYS_ADMIN)) {
- if (change_irq ||
- (new_serial.close_delay != info->close_delay) ||
- ((new_serial.flags & ~ASYNC_USR_MASK) !=
- (info->port.flags & ~ASYNC_USR_MASK)))
- return -EPERM;
- info->port.flags = ((info->port.flags & ~ASYNC_USR_MASK) |
- (new_serial.flags & ASYNC_USR_MASK));
- info->custom_divisor = new_serial.custom_divisor;
- } else {
- if (new_serial.irq == 2)
- new_serial.irq = 9;
-
- if (change_irq) {
- current_async = ports;
-
- while (current_async) {
- if ((current_async->line >= info->line) &&
- (current_async->line < (info->line + 8))) {
- if (current_async == info) {
- if (current_async->port.count > 1)
- return -EBUSY;
- } else if (current_async->port.count)
- return -EBUSY;
- }
-
- current_async = current_async->next_port;
- }
- }
-
- /*
- * OK, past this point, all the error checking has been done.
- * At this point, we start making changes.....
- */
-
- info->port.flags = ((info->port.flags & ~ASYNC_FLAGS) |
- (new_serial.flags & ASYNC_FLAGS));
- info->custom_divisor = new_serial.custom_divisor;
- info->close_delay = new_serial.close_delay * HZ/100;
- info->closing_wait = new_serial.closing_wait * HZ/100;
-
- if (change_irq) {
- /*
- * We need to shutdown the serial port at the old
- * port/irq combination.
- */
- shutdown(info);
-
- current_async = ports;
-
- while (current_async) {
- if ((current_async->line >= info->line) &&
- (current_async->line < (info->line + 8)))
- current_async->irq = new_serial.irq;
-
- current_async = current_async->next_port;
- }
-
- serial_out(info, UART_ESI_CMD1, ESI_SET_ENH_IRQ);
- if (info->irq == 9)
- serial_out(info, UART_ESI_CMD2, 0x02);
- else
- serial_out(info, UART_ESI_CMD2, info->irq);
- }
- }
-
- if (info->port.flags & ASYNC_INITIALIZED) {
- if (((old_info.port.flags & ASYNC_SPD_MASK) !=
- (info->port.flags & ASYNC_SPD_MASK)) ||
- (old_info.custom_divisor != info->custom_divisor)) {
- if ((info->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI)
- info->port.tty->alt_speed = 57600;
- if ((info->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI)
- info->port.tty->alt_speed = 115200;
- if ((info->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_SHI)
- info->port.tty->alt_speed = 230400;
- if ((info->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_WARP)
- info->port.tty->alt_speed = 460800;
- change_speed(info);
- }
- } else
- retval = startup(info);
-
- return retval;
-}
-
-static int set_esp_config(struct esp_struct *info,
- struct hayes_esp_config __user *new_info)
-{
- struct hayes_esp_config new_config;
- unsigned int change_dma;
- int retval = 0;
- struct esp_struct *current_async;
- unsigned long flags;
-
- /* Perhaps a non-sysadmin user should be able to do some of these */
- /* operations. I haven't decided yet. */
-
- if (!capable(CAP_SYS_ADMIN))
- return -EPERM;
-
- if (copy_from_user(&new_config, new_info, sizeof(new_config)))
- return -EFAULT;
-
- if ((new_config.flow_on >= new_config.flow_off) ||
- (new_config.rx_trigger < 1) ||
- (new_config.tx_trigger < 1) ||
- (new_config.flow_off < 1) ||
- (new_config.flow_on < 1) ||
- (new_config.rx_trigger > 1023) ||
- (new_config.tx_trigger > 1023) ||
- (new_config.flow_off > 1023) ||
- (new_config.flow_on > 1023) ||
- (new_config.pio_threshold < 0) ||
- (new_config.pio_threshold > 1024))
- return -EINVAL;
-
- if ((new_config.dma_channel != 1) && (new_config.dma_channel != 3))
- new_config.dma_channel = 0;
-
- if (info->stat_flags & ESP_STAT_NEVER_DMA)
- change_dma = new_config.dma_channel;
- else
- change_dma = (new_config.dma_channel != dma);
-
- if (change_dma) {
- if (new_config.dma_channel) {
- /* PIO mode to DMA mode transition OR */
- /* change current DMA channel */
- current_async = ports;
-
- while (current_async) {
- if (current_async == info) {
- if (current_async->port.count > 1)
- return -EBUSY;
- } else if (current_async->port.count)
- return -EBUSY;
-
- current_async = current_async->next_port;
- }
-
- shutdown(info);
- dma = new_config.dma_channel;
- info->stat_flags &= ~ESP_STAT_NEVER_DMA;
-
- /* all ports must use the same DMA channel */
-
- spin_lock_irqsave(&info->lock, flags);
- current_async = ports;
-
- while (current_async) {
- esp_basic_init(current_async);
- current_async = current_async->next_port;
- }
- spin_unlock_irqrestore(&info->lock, flags);
- } else {
- /* DMA mode to PIO mode only */
- if (info->port.count > 1)
- return -EBUSY;
-
- shutdown(info);
- spin_lock_irqsave(&info->lock, flags);
- info->stat_flags |= ESP_STAT_NEVER_DMA;
- esp_basic_init(info);
- spin_unlock_irqrestore(&info->lock, flags);
- }
- }
-
- info->config.pio_threshold = new_config.pio_threshold;
-
- if ((new_config.flow_off != info->config.flow_off) ||
- (new_config.flow_on != info->config.flow_on)) {
- info->config.flow_off = new_config.flow_off;
- info->config.flow_on = new_config.flow_on;
-
- spin_lock_irqsave(&info->lock, flags);
- serial_out(info, UART_ESI_CMD1, ESI_SET_FLOW_LVL);
- serial_out(info, UART_ESI_CMD2, new_config.flow_off >> 8);
- serial_out(info, UART_ESI_CMD2, new_config.flow_off);
- serial_out(info, UART_ESI_CMD2, new_config.flow_on >> 8);
- serial_out(info, UART_ESI_CMD2, new_config.flow_on);
- spin_unlock_irqrestore(&info->lock, flags);
- }
-
- if ((new_config.rx_trigger != info->config.rx_trigger) ||
- (new_config.tx_trigger != info->config.tx_trigger)) {
- info->config.rx_trigger = new_config.rx_trigger;
- info->config.tx_trigger = new_config.tx_trigger;
- spin_lock_irqsave(&info->lock, flags);
- serial_out(info, UART_ESI_CMD1, ESI_SET_TRIGGER);
- serial_out(info, UART_ESI_CMD2,
- new_config.rx_trigger >> 8);
- serial_out(info, UART_ESI_CMD2, new_config.rx_trigger);
- serial_out(info, UART_ESI_CMD2,
- new_config.tx_trigger >> 8);
- serial_out(info, UART_ESI_CMD2, new_config.tx_trigger);
- spin_unlock_irqrestore(&info->lock, flags);
- }
-
- if (new_config.rx_timeout != info->config.rx_timeout) {
- info->config.rx_timeout = new_config.rx_timeout;
- spin_lock_irqsave(&info->lock, flags);
-
- if (info->IER & UART_IER_RDI) {
- serial_out(info, UART_ESI_CMD1,
- ESI_SET_RX_TIMEOUT);
- serial_out(info, UART_ESI_CMD2,
- new_config.rx_timeout);
- }
-
- spin_unlock_irqrestore(&info->lock, flags);
- }
-
- if (!(info->port.flags & ASYNC_INITIALIZED))
- retval = startup(info);
-
- return retval;
-}
-
-/*
- * get_lsr_info - get line status register info
- *
- * Purpose: Let user call ioctl() to get info when the UART physically
- * is emptied. On bus types like RS485, the transmitter must
- * release the bus after transmitting. This must be done when
- * the transmit shift register is empty, not be done when the
- * transmit holding register is empty. This functionality
- * allows an RS485 driver to be written in user space.
- */
-static int get_lsr_info(struct esp_struct *info, unsigned int __user *value)
-{
- unsigned char status;
- unsigned int result;
- unsigned long flags;
-
- spin_lock_irqsave(&info->lock, flags);
- serial_out(info, UART_ESI_CMD1, ESI_GET_UART_STAT);
- status = serial_in(info, UART_ESI_STAT1);
- spin_unlock_irqrestore(&info->lock, flags);
- result = ((status & UART_LSR_TEMT) ? TIOCSER_TEMT : 0);
- return put_user(result, value);
-}
-
-
-static int esp_tiocmget(struct tty_struct *tty, struct file *file)
-{
- struct esp_struct *info = tty->driver_data;
- unsigned char control, status;
- unsigned long flags;
-
- if (serial_paranoia_check(info, tty->name, __func__))
- return -ENODEV;
- if (tty->flags & (1 << TTY_IO_ERROR))
- return -EIO;
-
- control = info->MCR;
-
- spin_lock_irqsave(&info->lock, flags);
- serial_out(info, UART_ESI_CMD1, ESI_GET_UART_STAT);
- status = serial_in(info, UART_ESI_STAT2);
- spin_unlock_irqrestore(&info->lock, flags);
-
- return ((control & UART_MCR_RTS) ? TIOCM_RTS : 0)
- | ((control & UART_MCR_DTR) ? TIOCM_DTR : 0)
- | ((status & UART_MSR_DCD) ? TIOCM_CAR : 0)
- | ((status & UART_MSR_RI) ? TIOCM_RNG : 0)
- | ((status & UART_MSR_DSR) ? TIOCM_DSR : 0)
- | ((status & UART_MSR_CTS) ? TIOCM_CTS : 0);
-}
-
-static int esp_tiocmset(struct tty_struct *tty, struct file *file,
- unsigned int set, unsigned int clear)
-{
- struct esp_struct *info = tty->driver_data;
- unsigned long flags;
-
- if (serial_paranoia_check(info, tty->name, __func__))
- return -ENODEV;
- if (tty->flags & (1 << TTY_IO_ERROR))
- return -EIO;
-
- spin_lock_irqsave(&info->lock, flags);
-
- if (set & TIOCM_RTS)
- info->MCR |= UART_MCR_RTS;
- if (set & TIOCM_DTR)
- info->MCR |= UART_MCR_DTR;
-
- if (clear & TIOCM_RTS)
- info->MCR &= ~UART_MCR_RTS;
- if (clear & TIOCM_DTR)
- info->MCR &= ~UART_MCR_DTR;
-
- serial_out(info, UART_ESI_CMD1, ESI_WRITE_UART);
- serial_out(info, UART_ESI_CMD2, UART_MCR);
- serial_out(info, UART_ESI_CMD2, info->MCR);
-
- spin_unlock_irqrestore(&info->lock, flags);
- return 0;
-}
-
-/*
- * rs_break() --- routine which turns the break handling on or off
- */
-static int esp_break(struct tty_struct *tty, int break_state)
-{
- struct esp_struct *info = tty->driver_data;
- unsigned long flags;
-
- if (serial_paranoia_check(info, tty->name, "esp_break"))
- return -EINVAL;
-
- if (break_state == -1) {
- spin_lock_irqsave(&info->lock, flags);
- serial_out(info, UART_ESI_CMD1, ESI_ISSUE_BREAK);
- serial_out(info, UART_ESI_CMD2, 0x01);
- spin_unlock_irqrestore(&info->lock, flags);
-
- /* FIXME - new style wait needed here */
- interruptible_sleep_on(&info->break_wait);
- } else {
- spin_lock_irqsave(&info->lock, flags);
- serial_out(info, UART_ESI_CMD1, ESI_ISSUE_BREAK);
- serial_out(info, UART_ESI_CMD2, 0x00);
- spin_unlock_irqrestore(&info->lock, flags);
- }
- return 0;
-}
-
-static int rs_ioctl(struct tty_struct *tty, struct file *file,
- unsigned int cmd, unsigned long arg)
-{
- struct esp_struct *info = tty->driver_data;
- struct async_icount cprev, cnow; /* kernel counter temps */
- struct serial_icounter_struct __user *p_cuser; /* user space */
- void __user *argp = (void __user *)arg;
- unsigned long flags;
- int ret;
-
- if (serial_paranoia_check(info, tty->name, "rs_ioctl"))
- return -ENODEV;
-
- if ((cmd != TIOCGSERIAL) && (cmd != TIOCSSERIAL) &&
- (cmd != TIOCSERCONFIG) && (cmd != TIOCSERGWILD) &&
- (cmd != TIOCSERSWILD) && (cmd != TIOCSERGSTRUCT) &&
- (cmd != TIOCMIWAIT) && (cmd != TIOCGICOUNT) &&
- (cmd != TIOCGHAYESESP) && (cmd != TIOCSHAYESESP)) {
- if (tty->flags & (1 << TTY_IO_ERROR))
- return -EIO;
- }
-
- switch (cmd) {
- case TIOCGSERIAL:
- return get_serial_info(info, argp);
- case TIOCSSERIAL:
- lock_kernel();
- ret = set_serial_info(info, argp);
- unlock_kernel();
- return ret;
- case TIOCSERGWILD:
- return put_user(0L, (unsigned long __user *)argp);
- case TIOCSERGETLSR: /* Get line status register */
- return get_lsr_info(info, argp);
- case TIOCSERSWILD:
- if (!capable(CAP_SYS_ADMIN))
- return -EPERM;
- return 0;
- /*
- * Wait for any of the 4 modem inputs (DCD,RI,DSR,CTS) to change
- * - mask passed in arg for lines of interest
- * (use |'ed TIOCM_RNG/DSR/CD/CTS for masking)
- * Caller should use TIOCGICOUNT to see which one it was
- */
- case TIOCMIWAIT:
- spin_lock_irqsave(&info->lock, flags);
- cprev = info->icount; /* note the counters on entry */
- spin_unlock_irqrestore(&info->lock, flags);
- while (1) {
- /* FIXME: convert to new style wakeup */
- interruptible_sleep_on(&info->port.delta_msr_wait);
- /* see if a signal did it */
- if (signal_pending(current))
- return -ERESTARTSYS;
- spin_lock_irqsave(&info->lock, flags);
- cnow = info->icount; /* atomic copy */
- spin_unlock_irqrestore(&info->lock, flags);
- if (cnow.rng == cprev.rng &&
- cnow.dsr == cprev.dsr &&
- cnow.dcd == cprev.dcd &&
- cnow.cts == cprev.cts)
- return -EIO; /* no change => error */
- if (((arg & TIOCM_RNG) &&
- (cnow.rng != cprev.rng)) ||
- ((arg & TIOCM_DSR) &&
- (cnow.dsr != cprev.dsr)) ||
- ((arg & TIOCM_CD) &&
- (cnow.dcd != cprev.dcd)) ||
- ((arg & TIOCM_CTS) &&
- (cnow.cts != cprev.cts))) {
- return 0;
- }
- cprev = cnow;
- }
- /* NOTREACHED */
- /*
- * Get counter of input serial line interrupts (DCD,RI,DSR,CTS)
- * Return: write counters to the user passed counter struct
- * NB: both 1->0 and 0->1 transitions are counted except for
- * RI where only 0->1 is counted.
- */
- case TIOCGICOUNT:
- spin_lock_irqsave(&info->lock, flags);
- cnow = info->icount;
- spin_unlock_irqrestore(&info->lock, flags);
- p_cuser = argp;
- if (put_user(cnow.cts, &p_cuser->cts) ||
- put_user(cnow.dsr, &p_cuser->dsr) ||
- put_user(cnow.rng, &p_cuser->rng) ||
- put_user(cnow.dcd, &p_cuser->dcd))
- return -EFAULT;
- return 0;
- case TIOCGHAYESESP:
- return get_esp_config(info, argp);
- case TIOCSHAYESESP:
- lock_kernel();
- ret = set_esp_config(info, argp);
- unlock_kernel();
- return ret;
- default:
- return -ENOIOCTLCMD;
- }
- return 0;
-}
-
-static void rs_set_termios(struct tty_struct *tty, struct ktermios *old_termios)
-{
- struct esp_struct *info = tty->driver_data;
- unsigned long flags;
-
- change_speed(info);
-
- spin_lock_irqsave(&info->lock, flags);
-
- /* Handle transition to B0 status */
- if ((old_termios->c_cflag & CBAUD) &&
- !(tty->termios->c_cflag & CBAUD)) {
- info->MCR &= ~(UART_MCR_DTR|UART_MCR_RTS);
- serial_out(info, UART_ESI_CMD1, ESI_WRITE_UART);
- serial_out(info, UART_ESI_CMD2, UART_MCR);
- serial_out(info, UART_ESI_CMD2, info->MCR);
- }
-
- /* Handle transition away from B0 status */
- if (!(old_termios->c_cflag & CBAUD) &&
- (tty->termios->c_cflag & CBAUD)) {
- info->MCR |= (UART_MCR_DTR | UART_MCR_RTS);
- serial_out(info, UART_ESI_CMD1, ESI_WRITE_UART);
- serial_out(info, UART_ESI_CMD2, UART_MCR);
- serial_out(info, UART_ESI_CMD2, info->MCR);
- }
-
- spin_unlock_irqrestore(&info->lock, flags);
-
- /* Handle turning of CRTSCTS */
- if ((old_termios->c_cflag & CRTSCTS) &&
- !(tty->termios->c_cflag & CRTSCTS)) {
- rs_start(tty);
- }
-}
-
-/*
- * ------------------------------------------------------------
- * rs_close()
- *
- * This routine is called when the serial port gets closed. First, we
- * wait for the last remaining data to be sent. Then, we unlink its
- * async structure from the interrupt chain if necessary, and we free
- * that IRQ if nothing is left in the chain.
- * ------------------------------------------------------------
- */
-static void rs_close(struct tty_struct *tty, struct file *filp)
-{
- struct esp_struct *info = tty->driver_data;
- unsigned long flags;
-
- if (!info || serial_paranoia_check(info, tty->name, "rs_close"))
- return;
-
- spin_lock_irqsave(&info->lock, flags);
-
- if (tty_hung_up_p(filp)) {
- DBG_CNT("before DEC-hung");
- goto out;
- }
-
-#ifdef SERIAL_DEBUG_OPEN
- printk(KERN_DEBUG "rs_close ttys%d, count = %d\n",
- info->line, info->port.count);
-#endif
- if (tty->count == 1 && info->port.count != 1) {
- /*
- * Uh, oh. tty->count is 1, which means that the tty
- * structure will be freed. Info->count should always
- * be one in these conditions. If it's greater than
- * one, we've got real problems, since it means the
- * serial port won't be shutdown.
- */
- printk(KERN_DEBUG "rs_close: bad serial port count; tty->count is 1, info->port.count is %d\n", info->port.count);
- info->port.count = 1;
- }
- if (--info->port.count < 0) {
- printk(KERN_ERR "rs_close: bad serial port count for ttys%d: %d\n",
- info->line, info->port.count);
- info->port.count = 0;
- }
- if (info->port.count) {
- DBG_CNT("before DEC-2");
- goto out;
- }
- info->port.flags |= ASYNC_CLOSING;
-
- spin_unlock_irqrestore(&info->lock, flags);
- /*
- * Now we wait for the transmit buffer to clear; and we notify
- * the line discipline to only process XON/XOFF characters.
- */
- tty->closing = 1;
- if (info->closing_wait != ASYNC_CLOSING_WAIT_NONE)
- tty_wait_until_sent(tty, info->closing_wait);
- /*
- * At this point we stop accepting input. To do this, we
- * disable the receive line status interrupts, and tell the
- * interrupt driver to stop checking the data ready bit in the
- * line status register.
- */
- /* info->IER &= ~UART_IER_RLSI; */
- info->IER &= ~UART_IER_RDI;
- info->read_status_mask &= ~UART_LSR_DR;
- if (info->port.flags & ASYNC_INITIALIZED) {
-
- spin_lock_irqsave(&info->lock, flags);
- serial_out(info, UART_ESI_CMD1, ESI_SET_SRV_MASK);
- serial_out(info, UART_ESI_CMD2, info->IER);
-
- /* disable receive timeout */
- serial_out(info, UART_ESI_CMD1, ESI_SET_RX_TIMEOUT);
- serial_out(info, UART_ESI_CMD2, 0x00);
-
- spin_unlock_irqrestore(&info->lock, flags);
-
- /*
- * Before we drop DTR, make sure the UART transmitter
- * has completely drained; this is especially
- * important if there is a transmit FIFO!
- */
- rs_wait_until_sent(tty, info->timeout);
- }
- shutdown(info);
- rs_flush_buffer(tty);
- tty_ldisc_flush(tty);
- tty->closing = 0;
- info->port.tty = NULL;
-
- if (info->port.blocked_open) {
- if (info->close_delay)
- msleep_interruptible(jiffies_to_msecs(info->close_delay));
- wake_up_interruptible(&info->port.open_wait);
- }
- info->port.flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING);
- wake_up_interruptible(&info->port.close_wait);
- return;
-
-out:
- spin_unlock_irqrestore(&info->lock, flags);
-}
-
-static void rs_wait_until_sent(struct tty_struct *tty, int timeout)
-{
- struct esp_struct *info = tty->driver_data;
- unsigned long orig_jiffies, char_time;
- unsigned long flags;
-
- if (serial_paranoia_check(info, tty->name, "rs_wait_until_sent"))
- return;
-
- orig_jiffies = jiffies;
- char_time = ((info->timeout - HZ / 50) / 1024) / 5;
-
- if (!char_time)
- char_time = 1;
-
- spin_lock_irqsave(&info->lock, flags);
- serial_out(info, UART_ESI_CMD1, ESI_NO_COMMAND);
- serial_out(info, UART_ESI_CMD1, ESI_GET_TX_AVAIL);
-
- while ((serial_in(info, UART_ESI_STAT1) != 0x03) ||
- (serial_in(info, UART_ESI_STAT2) != 0xff)) {
-
- spin_unlock_irqrestore(&info->lock, flags);
- msleep_interruptible(jiffies_to_msecs(char_time));
-
- if (signal_pending(current))
- return;
-
- if (timeout && time_after(jiffies, orig_jiffies + timeout))
- return;
-
- spin_lock_irqsave(&info->lock, flags);
- serial_out(info, UART_ESI_CMD1, ESI_NO_COMMAND);
- serial_out(info, UART_ESI_CMD1, ESI_GET_TX_AVAIL);
- }
- spin_unlock_irqrestore(&info->lock, flags);
- set_current_state(TASK_RUNNING);
-}
-
-/*
- * esp_hangup() --- called by tty_hangup() when a hangup is signaled.
- */
-static void esp_hangup(struct tty_struct *tty)
-{
- struct esp_struct *info = tty->driver_data;
-
- if (serial_paranoia_check(info, tty->name, "esp_hangup"))
- return;
-
- rs_flush_buffer(tty);
- shutdown(info);
- info->port.count = 0;
- info->port.flags &= ~ASYNC_NORMAL_ACTIVE;
- info->port.tty = NULL;
- wake_up_interruptible(&info->port.open_wait);
-}
-
-static int esp_carrier_raised(struct tty_port *port)
-{
- struct esp_struct *info = container_of(port, struct esp_struct, port);
- serial_out(info, UART_ESI_CMD1, ESI_GET_UART_STAT);
- if (serial_in(info, UART_ESI_STAT2) & UART_MSR_DCD)
- return 1;
- return 0;
-}
-
-/*
- * ------------------------------------------------------------
- * esp_open() and friends
- * ------------------------------------------------------------
- */
-static int block_til_ready(struct tty_struct *tty, struct file *filp,
- struct esp_struct *info)
-{
- DECLARE_WAITQUEUE(wait, current);
- int retval;
- int do_clocal = 0;
- unsigned long flags;
- int cd;
- struct tty_port *port = &info->port;
-
- /*
- * If the device is in the middle of being closed, then block
- * until it's done, and then try again.
- */
- if (tty_hung_up_p(filp) ||
- (port->flags & ASYNC_CLOSING)) {
- if (port->flags & ASYNC_CLOSING)
- interruptible_sleep_on(&port->close_wait);
-#ifdef SERIAL_DO_RESTART
- if (port->flags & ASYNC_HUP_NOTIFY)
- return -EAGAIN;
- else
- return -ERESTARTSYS;
-#else
- return -EAGAIN;
-#endif
- }
-
- /*
- * If non-blocking mode is set, or the port is not enabled,
- * then make the check up front and then exit.
- */
- if ((filp->f_flags & O_NONBLOCK) ||
- (tty->flags & (1 << TTY_IO_ERROR))) {
- port->flags |= ASYNC_NORMAL_ACTIVE;
- return 0;
- }
-
- if (tty->termios->c_cflag & CLOCAL)
- do_clocal = 1;
-
- /*
- * Block waiting for the carrier detect and the line to become
- * free (i.e., not in use by the callout). While we are in
- * this loop, port->count is dropped by one, so that
- * rs_close() knows when to free things. We restore it upon
- * exit, either normal or abnormal.
- */
- retval = 0;
- add_wait_queue(&port->open_wait, &wait);
-#ifdef SERIAL_DEBUG_OPEN
- printk(KERN_DEBUG "block_til_ready before block: ttys%d, count = %d\n",
- info->line, port->count);
-#endif
- spin_lock_irqsave(&info->lock, flags);
- if (!tty_hung_up_p(filp))
- port->count--;
- port->blocked_open++;
- while (1) {
- if ((tty->termios->c_cflag & CBAUD)) {
- unsigned int scratch;
-
- serial_out(info, UART_ESI_CMD1, ESI_READ_UART);
- serial_out(info, UART_ESI_CMD2, UART_MCR);
- scratch = serial_in(info, UART_ESI_STAT1);
- serial_out(info, UART_ESI_CMD1, ESI_WRITE_UART);
- serial_out(info, UART_ESI_CMD2, UART_MCR);
- serial_out(info, UART_ESI_CMD2,
- scratch | UART_MCR_DTR | UART_MCR_RTS);
- }
- set_current_state(TASK_INTERRUPTIBLE);
- if (tty_hung_up_p(filp) ||
- !(port->flags & ASYNC_INITIALIZED)) {
-#ifdef SERIAL_DO_RESTART
- if (port->flags & ASYNC_HUP_NOTIFY)
- retval = -EAGAIN;
- else
- retval = -ERESTARTSYS;
-#else
- retval = -EAGAIN;
-#endif
- break;
- }
-
- cd = tty_port_carrier_raised(port);
-
- if (!(port->flags & ASYNC_CLOSING) &&
- (do_clocal))
- break;
- if (signal_pending(current)) {
- retval = -ERESTARTSYS;
- break;
- }
-#ifdef SERIAL_DEBUG_OPEN
- printk(KERN_DEBUG "block_til_ready blocking: ttys%d, count = %d\n",
- info->line, port->count);
-#endif
- spin_unlock_irqrestore(&info->lock, flags);
- schedule();
- spin_lock_irqsave(&info->lock, flags);
- }
- set_current_state(TASK_RUNNING);
- remove_wait_queue(&port->open_wait, &wait);
- if (!tty_hung_up_p(filp))
- port->count++;
- port->blocked_open--;
- spin_unlock_irqrestore(&info->lock, flags);
-#ifdef SERIAL_DEBUG_OPEN
- printk(KERN_DEBUG "block_til_ready after blocking: ttys%d, count = %d\n",
- info->line, port->count);
-#endif
- if (retval)
- return retval;
- port->flags |= ASYNC_NORMAL_ACTIVE;
- return 0;
-}
-
-/*
- * This routine is called whenever a serial port is opened. It
- * enables interrupts for a serial port, linking in its async structure into
- * the IRQ chain. It also performs the serial-specific
- * initialization for the tty structure.
- */
-static int esp_open(struct tty_struct *tty, struct file *filp)
-{
- struct esp_struct *info;
- int retval, line;
- unsigned long flags;
-
- line = tty->index;
- if ((line < 0) || (line >= NR_PORTS))
- return -ENODEV;
-
- /* find the port in the chain */
-
- info = ports;
-
- while (info && (info->line != line))
- info = info->next_port;
-
- if (!info) {
- serial_paranoia_check(info, tty->name, "esp_open");
- return -ENODEV;
- }
-
-#ifdef SERIAL_DEBUG_OPEN
- printk(KERN_DEBUG "esp_open %s, count = %d\n", tty->name, info->port.count);
-#endif
- spin_lock_irqsave(&info->lock, flags);
- info->port.count++;
- tty->driver_data = info;
- info->port.tty = tty;
-
- spin_unlock_irqrestore(&info->lock, flags);
-
- /*
- * Start up serial port
- */
- retval = startup(info);
- if (retval)
- return retval;
-
- retval = block_til_ready(tty, filp, info);
- if (retval) {
-#ifdef SERIAL_DEBUG_OPEN
- printk(KERN_DEBUG "esp_open returning after block_til_ready with %d\n",
- retval);
-#endif
- return retval;
- }
-#ifdef SERIAL_DEBUG_OPEN
- printk(KERN_DEBUG "esp_open %s successful...", tty->name);
-#endif
- return 0;
-}
-
-/*
- * ---------------------------------------------------------------------
- * espserial_init() and friends
- *
- * espserial_init() is called at boot-time to initialize the serial driver.
- * ---------------------------------------------------------------------
- */
-
-/*
- * This routine prints out the appropriate serial driver version
- * number, and identifies which options were configured into this
- * driver.
- */
-
-static void __init show_serial_version(void)
-{
- printk(KERN_INFO "%s version %s (DMA %u)\n",
- serial_name, serial_version, dma);
-}
-
-/*
- * This routine is called by espserial_init() to initialize a specific serial
- * port.
- */
-static int autoconfig(struct esp_struct *info)
-{
- int port_detected = 0;
- unsigned long flags;
-
- if (!request_region(info->io_port, REGION_SIZE, "esp serial"))
- return -EIO;
-
- spin_lock_irqsave(&info->lock, flags);
- /*
- * Check for ESP card
- */
-
- if (serial_in(info, UART_ESI_BASE) == 0xf3) {
- serial_out(info, UART_ESI_CMD1, 0x00);
- serial_out(info, UART_ESI_CMD1, 0x01);
-
- if ((serial_in(info, UART_ESI_STAT2) & 0x70) == 0x20) {
- port_detected = 1;
-
- if (!(info->irq)) {
- serial_out(info, UART_ESI_CMD1, 0x02);
-
- if (serial_in(info, UART_ESI_STAT1) & 0x01)
- info->irq = 3;
- else
- info->irq = 4;
- }
-
-
- /* put card in enhanced mode */
- /* this prevents access through */
- /* the "old" IO ports */
- esp_basic_init(info);
-
- /* clear out MCR */
- serial_out(info, UART_ESI_CMD1, ESI_WRITE_UART);
- serial_out(info, UART_ESI_CMD2, UART_MCR);
- serial_out(info, UART_ESI_CMD2, 0x00);
- }
- }
- if (!port_detected)
- release_region(info->io_port, REGION_SIZE);
-
- spin_unlock_irqrestore(&info->lock, flags);
- return (port_detected);
-}
-
-static const struct tty_operations esp_ops = {
- .open = esp_open,
- .close = rs_close,
- .write = rs_write,
- .put_char = rs_put_char,
- .flush_chars = rs_flush_chars,
- .write_room = rs_write_room,
- .chars_in_buffer = rs_chars_in_buffer,
- .flush_buffer = rs_flush_buffer,
- .ioctl = rs_ioctl,
- .throttle = rs_throttle,
- .unthrottle = rs_unthrottle,
- .set_termios = rs_set_termios,
- .stop = rs_stop,
- .start = rs_start,
- .hangup = esp_hangup,
- .break_ctl = esp_break,
- .wait_until_sent = rs_wait_until_sent,
- .tiocmget = esp_tiocmget,
- .tiocmset = esp_tiocmset,
-};
-
-static const struct tty_port_operations esp_port_ops = {
- .esp_carrier_raised,
-};
-
-/*
- * The serial driver boot-time initialization code!
- */
-static int __init espserial_init(void)
-{
- int i, offset;
- struct esp_struct *info;
- struct esp_struct *last_primary = NULL;
- int esp[] = { 0x100, 0x140, 0x180, 0x200, 0x240, 0x280, 0x300, 0x380 };
-
- esp_driver = alloc_tty_driver(NR_PORTS);
- if (!esp_driver)
- return -ENOMEM;
-
- for (i = 0; i < NR_PRIMARY; i++) {
- if (irq[i] != 0) {
- if ((irq[i] < 2) || (irq[i] > 15) || (irq[i] == 6) ||
- (irq[i] == 8) || (irq[i] == 13))
- irq[i] = 0;
- else if (irq[i] == 2)
- irq[i] = 9;
- }
- }
-
- if ((dma != 1) && (dma != 3))
- dma = 0;
-
- if ((rx_trigger < 1) || (rx_trigger > 1023))
- rx_trigger = 768;
-
- if ((tx_trigger < 1) || (tx_trigger > 1023))
- tx_trigger = 768;
-
- if ((flow_off < 1) || (flow_off > 1023))
- flow_off = 1016;
-
- if ((flow_on < 1) || (flow_on > 1023))
- flow_on = 944;
-
- if ((rx_timeout < 0) || (rx_timeout > 255))
- rx_timeout = 128;
-
- if (flow_on >= flow_off)
- flow_on = flow_off - 1;
-
- show_serial_version();
-
- /* Initialize the tty_driver structure */
-
- esp_driver->owner = THIS_MODULE;
- esp_driver->name = "ttyP";
- esp_driver->major = ESP_IN_MAJOR;
- esp_driver->minor_start = 0;
- esp_driver->type = TTY_DRIVER_TYPE_SERIAL;
- esp_driver->subtype = SERIAL_TYPE_NORMAL;
- esp_driver->init_termios = tty_std_termios;
- esp_driver->init_termios.c_cflag =
- B9600 | CS8 | CREAD | HUPCL | CLOCAL;
- esp_driver->init_termios.c_ispeed = 9600;
- esp_driver->init_termios.c_ospeed = 9600;
- esp_driver->flags = TTY_DRIVER_REAL_RAW;
- tty_set_operations(esp_driver, &esp_ops);
- if (tty_register_driver(esp_driver)) {
- printk(KERN_ERR "Couldn't register esp serial driver");
- put_tty_driver(esp_driver);
- return 1;
- }
-
- info = kzalloc(sizeof(struct esp_struct), GFP_KERNEL);
-
- if (!info) {
- printk(KERN_ERR "Couldn't allocate memory for esp serial device information\n");
- tty_unregister_driver(esp_driver);
- put_tty_driver(esp_driver);
- return 1;
- }
-
- spin_lock_init(&info->lock);
- /* rx_trigger, tx_trigger are needed by autoconfig */
- info->config.rx_trigger = rx_trigger;
- info->config.tx_trigger = tx_trigger;
-
- i = 0;
- offset = 0;
-
- do {
- tty_port_init(&info->port);
- info->port.ops = &esp_port_ops;
- info->io_port = esp[i] + offset;
- info->irq = irq[i];
- info->line = (i * 8) + (offset / 8);
-
- if (!autoconfig(info)) {
- i++;
- offset = 0;
- continue;
- }
-
- info->custom_divisor = (divisor[i] >> (offset / 2)) & 0xf;
- info->port.flags = STD_COM_FLAGS;
- if (info->custom_divisor)
- info->port.flags |= ASYNC_SPD_CUST;
- info->magic = ESP_MAGIC;
- info->close_delay = 5*HZ/10;
- info->closing_wait = 30*HZ;
- info->config.rx_timeout = rx_timeout;
- info->config.flow_on = flow_on;
- info->config.flow_off = flow_off;
- info->config.pio_threshold = pio_threshold;
- info->next_port = ports;
- init_waitqueue_head(&info->break_wait);
- ports = info;
- printk(KERN_INFO "ttyP%d at 0x%04x (irq = %d) is an ESP ",
- info->line, info->io_port, info->irq);
-
- if (info->line % 8) {
- printk("secondary port\n");
- /* 8 port cards can't do DMA */
- info->stat_flags |= ESP_STAT_NEVER_DMA;
-
- if (last_primary)
- last_primary->stat_flags |= ESP_STAT_NEVER_DMA;
- } else {
- printk("primary port\n");
- last_primary = info;
- irq[i] = info->irq;
- }
-
- if (!dma)
- info->stat_flags |= ESP_STAT_NEVER_DMA;
-
- info = kzalloc(sizeof(struct esp_struct), GFP_KERNEL);
- if (!info) {
- printk(KERN_ERR "Couldn't allocate memory for esp serial device information\n");
- /* allow use of the already detected ports */
- return 0;
- }
-
- spin_lock_init(&info->lock);
- /* rx_trigger, tx_trigger are needed by autoconfig */
- info->config.rx_trigger = rx_trigger;
- info->config.tx_trigger = tx_trigger;
-
- if (offset == 56) {
- i++;
- offset = 0;
- } else {
- offset += 8;
- }
- } while (i < NR_PRIMARY);
-
- /* free the last port memory allocation */
- kfree(info);
-
- return 0;
-}
-
-static void __exit espserial_exit(void)
-{
- int e1;
- struct esp_struct *temp_async;
- struct esp_pio_buffer *pio_buf;
-
- e1 = tty_unregister_driver(esp_driver);
- if (e1)
- printk(KERN_ERR "esp: failed to unregister driver (%d)\n", e1);
- put_tty_driver(esp_driver);
-
- while (ports) {
- if (ports->io_port)
- release_region(ports->io_port, REGION_SIZE);
- temp_async = ports->next_port;
- kfree(ports);
- ports = temp_async;
- }
-
- if (dma_buffer)
- free_pages((unsigned long)dma_buffer,
- get_order(DMA_BUFFER_SZ));
-
- while (free_pio_buf) {
- pio_buf = free_pio_buf->next;
- kfree(free_pio_buf);
- free_pio_buf = pio_buf;
- }
-}
-
-module_init(espserial_init);
-module_exit(espserial_exit);
diff --git a/include/linux/Kbuild b/include/linux/Kbuild
index 5a53857..f72914d 100644
--- a/include/linux/Kbuild
+++ b/include/linux/Kbuild
@@ -214,7 +214,6 @@ unifdef-y += futex.h
unifdef-y += fs.h
unifdef-y += gameport.h
unifdef-y += generic_serial.h
-unifdef-y += hayesesp.h
unifdef-y += hdlcdrv.h
unifdef-y += hdlc.h
unifdef-y += hdreg.h
diff --git a/include/linux/hayesesp.h b/include/linux/hayesesp.h
deleted file mode 100644
index 92b08cf..0000000
--- a/include/linux/hayesesp.h
+++ /dev/null
@@ -1,114 +0,0 @@
-#ifndef HAYESESP_H
-#define HAYESESP_H
-
-struct hayes_esp_config {
- short flow_on;
- short flow_off;
- short rx_trigger;
- short tx_trigger;
- short pio_threshold;
- unsigned char rx_timeout;
- char dma_channel;
-};
-
-#ifdef __KERNEL__
-
-#define ESP_DMA_CHANNEL 0
-#define ESP_RX_TRIGGER 768
-#define ESP_TX_TRIGGER 768
-#define ESP_FLOW_OFF 1016
-#define ESP_FLOW_ON 944
-#define ESP_RX_TMOUT 128
-#define ESP_PIO_THRESHOLD 32
-
-#define ESP_IN_MAJOR 57 /* major dev # for dial in */
-#define ESP_OUT_MAJOR 58 /* major dev # for dial out */
-#define ESPC_SCALE 3
-#define UART_ESI_BASE 0x00
-#define UART_ESI_SID 0x01
-#define UART_ESI_RX 0x02
-#define UART_ESI_TX 0x02
-#define UART_ESI_CMD1 0x04
-#define UART_ESI_CMD2 0x05
-#define UART_ESI_STAT1 0x04
-#define UART_ESI_STAT2 0x05
-#define UART_ESI_RWS 0x07
-
-#define UART_IER_DMA_TMOUT 0x80
-#define UART_IER_DMA_TC 0x08
-
-#define ESI_SET_IRQ 0x04
-#define ESI_SET_DMA_TMOUT 0x05
-#define ESI_SET_SRV_MASK 0x06
-#define ESI_SET_ERR_MASK 0x07
-#define ESI_SET_FLOW_CNTL 0x08
-#define ESI_SET_FLOW_CHARS 0x09
-#define ESI_SET_FLOW_LVL 0x0a
-#define ESI_SET_TRIGGER 0x0b
-#define ESI_SET_RX_TIMEOUT 0x0c
-#define ESI_SET_FLOW_TMOUT 0x0d
-#define ESI_WRITE_UART 0x0e
-#define ESI_READ_UART 0x0f
-#define ESI_SET_MODE 0x10
-#define ESI_GET_ERR_STAT 0x12
-#define ESI_GET_UART_STAT 0x13
-#define ESI_GET_RX_AVAIL 0x14
-#define ESI_GET_TX_AVAIL 0x15
-#define ESI_START_DMA_RX 0x16
-#define ESI_START_DMA_TX 0x17
-#define ESI_ISSUE_BREAK 0x1a
-#define ESI_FLUSH_RX 0x1b
-#define ESI_FLUSH_TX 0x1c
-#define ESI_SET_BAUD 0x1d
-#define ESI_SET_ENH_IRQ 0x1f
-#define ESI_SET_REINTR 0x20
-#define ESI_SET_PRESCALAR 0x23
-#define ESI_NO_COMMAND 0xff
-
-#define ESP_STAT_RX_TIMEOUT 0x01
-#define ESP_STAT_DMA_RX 0x02
-#define ESP_STAT_DMA_TX 0x04
-#define ESP_STAT_NEVER_DMA 0x08
-#define ESP_STAT_USE_PIO 0x10
-
-#define ESP_MAGIC 0x53ee
-#define ESP_XMIT_SIZE 4096
-
-struct esp_struct {
- int magic;
- struct tty_port port;
- spinlock_t lock;
- int io_port;
- int irq;
- int read_status_mask;
- int ignore_status_mask;
- int timeout;
- int stat_flags;
- int custom_divisor;
- int close_delay;
- unsigned short closing_wait;
- unsigned short closing_wait2;
- int IER; /* Interrupt Enable Register */
- int MCR; /* Modem control register */
- unsigned long last_active;
- int line;
- unsigned char *xmit_buf;
- int xmit_head;
- int xmit_tail;
- int xmit_cnt;
- wait_queue_head_t break_wait;
- struct async_icount icount; /* kernel counters for the 4 input interrupts */
- struct hayes_esp_config config; /* port configuration */
- struct esp_struct *next_port; /* For the linked list */
-};
-
-struct esp_pio_buffer {
- unsigned char data[1024];
- struct esp_pio_buffer *next;
-};
-
-#endif /* __KERNEL__ */
-
-
-#endif /* ESP_H */
-
--
1.6.5.5
^ permalink raw reply related [flat|nested] 100+ messages in thread* [PATCH 11/58] tty: istallion: Kill off the BKL ioctl
2009-12-11 23:28 [GIT PATCH] TTY patches for 2.6.33-git Greg KH
` (9 preceding siblings ...)
2009-12-11 23:27 ` [PATCH 10/58] tty: esp: remove broken driver Greg Kroah-Hartman
@ 2009-12-11 23:27 ` Greg Kroah-Hartman
2009-12-11 23:27 ` [PATCH 12/58] tty: stallion: kill " Greg Kroah-Hartman
` (47 subsequent siblings)
58 siblings, 0 replies; 100+ messages in thread
From: Greg Kroah-Hartman @ 2009-12-11 23:27 UTC (permalink / raw)
To: linux-kernel; +Cc: Alan Cox, Greg Kroah-Hartman
From: Alan Cox <alan@linux.intel.com>
Fairly trivial as the BKL push down into the methods has already been done.
Signed-off-by: Alan Cox <alan@linux.intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
---
drivers/char/istallion.c | 8 ++++----
1 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/char/istallion.c b/drivers/char/istallion.c
index 402838f..babfd44 100644
--- a/drivers/char/istallion.c
+++ b/drivers/char/istallion.c
@@ -621,7 +621,7 @@ static int stli_brdinit(struct stlibrd *brdp);
static int stli_startbrd(struct stlibrd *brdp);
static ssize_t stli_memread(struct file *fp, char __user *buf, size_t count, loff_t *offp);
static ssize_t stli_memwrite(struct file *fp, const char __user *buf, size_t count, loff_t *offp);
-static int stli_memioctl(struct inode *ip, struct file *fp, unsigned int cmd, unsigned long arg);
+static long stli_memioctl(struct file *fp, unsigned int cmd, unsigned long arg);
static void stli_brdpoll(struct stlibrd *brdp, cdkhdr_t __iomem *hdrp);
static void stli_poll(unsigned long arg);
static int stli_hostcmd(struct stlibrd *brdp, struct stliport *portp);
@@ -704,7 +704,7 @@ static const struct file_operations stli_fsiomem = {
.owner = THIS_MODULE,
.read = stli_memread,
.write = stli_memwrite,
- .ioctl = stli_memioctl,
+ .unlocked_ioctl = stli_memioctl,
};
/*****************************************************************************/
@@ -4311,7 +4311,7 @@ static int stli_getbrdstruct(struct stlibrd __user *arg)
* reset it, and start/stop it.
*/
-static int stli_memioctl(struct inode *ip, struct file *fp, unsigned int cmd, unsigned long arg)
+static long stli_memioctl(struct file *fp, unsigned int cmd, unsigned long arg)
{
struct stlibrd *brdp;
int brdnr, rc, done;
@@ -4356,7 +4356,7 @@ static int stli_memioctl(struct inode *ip, struct file *fp, unsigned int cmd, un
* Now handle the board specific ioctls. These all depend on the
* minor number of the device they were called from.
*/
- brdnr = iminor(ip);
+ brdnr = iminor(fp->f_dentry->d_inode);
if (brdnr >= STL_MAXBRDS)
return -ENODEV;
brdp = stli_brds[brdnr];
--
1.6.5.5
^ permalink raw reply related [flat|nested] 100+ messages in thread* [PATCH 12/58] tty: stallion: kill BKL ioctl
2009-12-11 23:28 [GIT PATCH] TTY patches for 2.6.33-git Greg KH
` (10 preceding siblings ...)
2009-12-11 23:27 ` [PATCH 11/58] tty: istallion: Kill off the BKL ioctl Greg Kroah-Hartman
@ 2009-12-11 23:27 ` Greg Kroah-Hartman
2009-12-11 23:27 ` [PATCH 13/58] tty_port: add "tty_port_open" helper Greg Kroah-Hartman
` (46 subsequent siblings)
58 siblings, 0 replies; 100+ messages in thread
From: Greg Kroah-Hartman @ 2009-12-11 23:27 UTC (permalink / raw)
To: linux-kernel; +Cc: Alan Cox, Greg Kroah-Hartman
From: Alan Cox <alan@linux.intel.com>
Signed-off-by: Alan Cox <alan@linux.intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
---
drivers/char/stallion.c | 13 +++++++------
1 files changed, 7 insertions(+), 6 deletions(-)
diff --git a/drivers/char/stallion.c b/drivers/char/stallion.c
index db6dcfa..b4ba5ed 100644
--- a/drivers/char/stallion.c
+++ b/drivers/char/stallion.c
@@ -407,7 +407,7 @@ static unsigned int stl_baudrates[] = {
* Declare all those functions in this driver!
*/
-static int stl_memioctl(struct inode *ip, struct file *fp, unsigned int cmd, unsigned long arg);
+static long stl_memioctl(struct file *fp, unsigned int cmd, unsigned long arg);
static int stl_brdinit(struct stlbrd *brdp);
static int stl_getportstats(struct tty_struct *tty, struct stlport *portp, comstats_t __user *cp);
static int stl_clrportstats(struct stlport *portp, comstats_t __user *cp);
@@ -607,7 +607,7 @@ static unsigned int sc26198_baudtable[] = {
*/
static const struct file_operations stl_fsiomem = {
.owner = THIS_MODULE,
- .ioctl = stl_memioctl,
+ .unlocked_ioctl = stl_memioctl,
};
static struct class *stallion_class;
@@ -2486,18 +2486,19 @@ static int stl_getbrdstruct(struct stlbrd __user *arg)
* collection.
*/
-static int stl_memioctl(struct inode *ip, struct file *fp, unsigned int cmd, unsigned long arg)
+static long stl_memioctl(struct file *fp, unsigned int cmd, unsigned long arg)
{
int brdnr, rc;
void __user *argp = (void __user *)arg;
- pr_debug("stl_memioctl(ip=%p,fp=%p,cmd=%x,arg=%lx)\n", ip, fp, cmd,arg);
+ pr_debug("stl_memioctl(fp=%p,cmd=%x,arg=%lx)\n", fp, cmd,arg);
- brdnr = iminor(ip);
+ brdnr = iminor(fp->f_dentry->d_inode);
if (brdnr >= STL_MAXBRDS)
return -ENODEV;
rc = 0;
+ lock_kernel();
switch (cmd) {
case COM_GETPORTSTATS:
rc = stl_getportstats(NULL, NULL, argp);
@@ -2518,7 +2519,7 @@ static int stl_memioctl(struct inode *ip, struct file *fp, unsigned int cmd, uns
rc = -ENOIOCTLCMD;
break;
}
-
+ unlock_kernel();
return rc;
}
--
1.6.5.5
^ permalink raw reply related [flat|nested] 100+ messages in thread* [PATCH 13/58] tty_port: add "tty_port_open" helper
2009-12-11 23:28 [GIT PATCH] TTY patches for 2.6.33-git Greg KH
` (11 preceding siblings ...)
2009-12-11 23:27 ` [PATCH 12/58] tty: stallion: kill " Greg Kroah-Hartman
@ 2009-12-11 23:27 ` Greg Kroah-Hartman
2009-12-11 23:27 ` [PATCH 14/58] tty_port: coding style cleaning pass Greg Kroah-Hartman
` (45 subsequent siblings)
58 siblings, 0 replies; 100+ messages in thread
From: Greg Kroah-Hartman @ 2009-12-11 23:27 UTC (permalink / raw)
To: linux-kernel; +Cc: Alan Cox, Alan Stern, Oliver Neukum, Greg Kroah-Hartman
From: Alan Cox <alan@linux.intel.com>
For the moment this just moves the USB logic over and fixes the 'what if
we open and hangup at the same time' race noticed by Oliver Neukum.
Signed-off-by: Alan Cox <alan@linux.intel.com>
Cc: Alan Stern <stern@rowland.harvard.edu>
Cc: Oliver Neukum <oliver@neukum.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
---
drivers/char/tty_port.c | 36 +++++++++++++++++++++++++++-
drivers/usb/serial/usb-serial.c | 49 ++++++++++++++++-----------------------
include/linux/tty.h | 10 +++++++-
3 files changed, 64 insertions(+), 31 deletions(-)
diff --git a/drivers/char/tty_port.c b/drivers/char/tty_port.c
index c63f3d3..b22a61a 100644
--- a/drivers/char/tty_port.c
+++ b/drivers/char/tty_port.c
@@ -99,10 +99,11 @@ EXPORT_SYMBOL(tty_port_tty_set);
static void tty_port_shutdown(struct tty_port *port)
{
+ mutex_lock(&port->mutex);
if (port->ops->shutdown &&
test_and_clear_bit(ASYNCB_INITIALIZED, &port->flags))
port->ops->shutdown(port);
-
+ mutex_unlock(&port->mutex);
}
/**
@@ -381,3 +382,36 @@ void tty_port_close(struct tty_port *port, struct tty_struct *tty,
tty_port_tty_set(port, NULL);
}
EXPORT_SYMBOL(tty_port_close);
+
+int tty_port_open(struct tty_port *port, struct tty_struct *tty,
+ struct file *filp)
+{
+ spin_lock_irq(&port->lock);
+ if (!tty_hung_up_p(filp))
+ ++port->count;
+ spin_unlock_irq(&port->lock);
+ tty_port_tty_set(port, tty);
+
+ /*
+ * Do the device-specific open only if the hardware isn't
+ * already initialized. Serialize open and shutdown using the
+ * port mutex.
+ */
+
+ mutex_lock(&port->mutex);
+
+ if (!test_bit(ASYNCB_INITIALIZED, &port->flags)) {
+ if (port->ops->activate) {
+ int retval = port->ops->activate(port, tty);
+ if (retval) {
+ mutex_unlock(&port->mutex);
+ return retval;
+ }
+ }
+ set_bit(ASYNCB_INITIALIZED, &port->flags);
+ }
+ mutex_unlock(&port->mutex);
+ return tty_port_block_til_ready(port, tty, filp);
+}
+
+EXPORT_SYMBOL(tty_port_open);
diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c
index bd3fa7f..b0649d9 100644
--- a/drivers/usb/serial/usb-serial.c
+++ b/drivers/usb/serial/usb-serial.c
@@ -247,41 +247,31 @@ static int serial_install(struct tty_driver *driver, struct tty_struct *tty)
return retval;
}
-static int serial_open(struct tty_struct *tty, struct file *filp)
+static int serial_activate(struct tty_port *tport, struct tty_struct *tty)
{
- struct usb_serial_port *port = tty->driver_data;
+ struct usb_serial_port *port =
+ container_of(tport, struct usb_serial_port, port);
struct usb_serial *serial = port->serial;
int retval;
- dbg("%s - port %d", __func__, port->number);
-
- spin_lock_irq(&port->port.lock);
- if (!tty_hung_up_p(filp))
- ++port->port.count;
- spin_unlock_irq(&port->port.lock);
- tty_port_tty_set(&port->port, tty);
+ if (mutex_lock_interruptible(&port->mutex))
+ return -ERESTARTSYS;
+ mutex_lock(&serial->disc_mutex);
+ if (serial->disconnected)
+ retval = -ENODEV;
+ else
+ retval = port->serial->type->open(tty, port);
+ mutex_unlock(&serial->disc_mutex);
+ mutex_unlock(&port->mutex);
+ return retval;
+}
- /* Do the device-specific open only if the hardware isn't
- * already initialized.
- */
- if (!test_bit(ASYNCB_INITIALIZED, &port->port.flags)) {
- if (mutex_lock_interruptible(&port->mutex))
- return -ERESTARTSYS;
- mutex_lock(&serial->disc_mutex);
- if (serial->disconnected)
- retval = -ENODEV;
- else
- retval = port->serial->type->open(tty, port);
- mutex_unlock(&serial->disc_mutex);
- mutex_unlock(&port->mutex);
- if (retval)
- return retval;
- set_bit(ASYNCB_INITIALIZED, &port->port.flags);
- }
+static int serial_open(struct tty_struct *tty, struct file *filp)
+{
+ struct usb_serial_port *port = tty->driver_data;
- /* Now do the correct tty layer semantics */
- retval = tty_port_block_til_ready(&port->port, tty, filp);
- return retval;
+ dbg("%s - port %d", __func__, port->number);
+ return tty_port_open(&port->port, tty, filp);
}
/**
@@ -725,6 +715,7 @@ static void serial_dtr_rts(struct tty_port *port, int on)
static const struct tty_port_operations serial_port_ops = {
.carrier_raised = serial_carrier_raised,
.dtr_rts = serial_dtr_rts,
+ .activate = serial_activate,
};
int usb_serial_probe(struct usb_interface *interface,
diff --git a/include/linux/tty.h b/include/linux/tty.h
index f0f43d0..6352ac2 100644
--- a/include/linux/tty.h
+++ b/include/linux/tty.h
@@ -190,9 +190,15 @@ struct tty_port_operations {
/* Control the DTR line */
void (*dtr_rts)(struct tty_port *port, int raise);
/* Called when the last close completes or a hangup finishes
- IFF the port was initialized. Do not use to free resources */
+ IFF the port was initialized. Do not use to free resources. Called
+ under the port mutex to serialize against activate/shutdowns */
void (*shutdown)(struct tty_port *port);
void (*drop)(struct tty_port *port);
+ /* Called under the port mutex from tty_port_open, serialized using
+ the port mutex */
+ /* FIXME: long term getting the tty argument *out* of this would be
+ good for consoles */
+ int (*activate)(struct tty_port *port, struct tty_struct *tty);
};
struct tty_port {
@@ -467,6 +473,8 @@ extern int tty_port_close_start(struct tty_port *port,
extern void tty_port_close_end(struct tty_port *port, struct tty_struct *tty);
extern void tty_port_close(struct tty_port *port,
struct tty_struct *tty, struct file *filp);
+extern int tty_port_open(struct tty_port *port,
+ struct tty_struct *tty, struct file *filp);
extern inline int tty_port_users(struct tty_port *port)
{
return port->count + port->blocked_open;
--
1.6.5.5
^ permalink raw reply related [flat|nested] 100+ messages in thread* [PATCH 14/58] tty_port: coding style cleaning pass
2009-12-11 23:28 [GIT PATCH] TTY patches for 2.6.33-git Greg KH
` (12 preceding siblings ...)
2009-12-11 23:27 ` [PATCH 13/58] tty_port: add "tty_port_open" helper Greg Kroah-Hartman
@ 2009-12-11 23:27 ` Greg Kroah-Hartman
2009-12-11 23:27 ` [PATCH 15/58] usb_serial: Use the shutdown() operation Greg Kroah-Hartman
` (44 subsequent siblings)
58 siblings, 0 replies; 100+ messages in thread
From: Greg Kroah-Hartman @ 2009-12-11 23:27 UTC (permalink / raw)
To: linux-kernel; +Cc: Alan Cox, Alan Stern, Oliver Neukum, Greg Kroah-Hartman
From: Alan Cox <alan@linux.intel.com>
Mind the hoover wire...
Signed-off-by: Alan Cox <alan@linux.intel.com>
Cc: Alan Stern <stern@rowland.harvard.edu>
Cc: Oliver Neukum <oliver@neukum.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
---
drivers/char/tty_port.c | 25 +++++++++++++------------
1 files changed, 13 insertions(+), 12 deletions(-)
diff --git a/drivers/char/tty_port.c b/drivers/char/tty_port.c
index b22a61a..41b314c 100644
--- a/drivers/char/tty_port.c
+++ b/drivers/char/tty_port.c
@@ -199,7 +199,7 @@ EXPORT_SYMBOL(tty_port_lower_dtr_rts);
* management of these lines. Note that the dtr/rts raise is done each
* iteration as a hangup may have previously dropped them while we wait.
*/
-
+
int tty_port_block_til_ready(struct tty_port *port,
struct tty_struct *tty, struct file *filp)
{
@@ -254,7 +254,8 @@ int tty_port_block_til_ready(struct tty_port *port,
tty_port_raise_dtr_rts(port);
prepare_to_wait(&port->open_wait, &wait, TASK_INTERRUPTIBLE);
- /* Check for a hangup or uninitialised port. Return accordingly */
+ /* Check for a hangup or uninitialised port.
+ Return accordingly */
if (tty_hung_up_p(filp) || !(port->flags & ASYNC_INITIALIZED)) {
if (port->flags & ASYNC_HUP_NOTIFY)
retval = -EAGAIN;
@@ -286,11 +287,11 @@ int tty_port_block_til_ready(struct tty_port *port,
port->flags |= ASYNC_NORMAL_ACTIVE;
spin_unlock_irqrestore(&port->lock, flags);
return retval;
-
}
EXPORT_SYMBOL(tty_port_block_til_ready);
-int tty_port_close_start(struct tty_port *port, struct tty_struct *tty, struct file *filp)
+int tty_port_close_start(struct tty_port *port,
+ struct tty_struct *tty, struct file *filp)
{
unsigned long flags;
@@ -300,7 +301,7 @@ int tty_port_close_start(struct tty_port *port, struct tty_struct *tty, struct f
return 0;
}
- if( tty->count == 1 && port->count != 1) {
+ if (tty->count == 1 && port->count != 1) {
printk(KERN_WARNING
"tty_port_close_start: tty->count = 1 port count = %d.\n",
port->count);
@@ -332,8 +333,8 @@ int tty_port_close_start(struct tty_port *port, struct tty_struct *tty, struct f
long timeout;
if (bps > 1200)
- timeout = max_t(long, (HZ * 10 * port->drain_delay) / bps,
- HZ / 10);
+ timeout = max_t(long,
+ (HZ * 10 * port->drain_delay) / bps, HZ / 10);
else
timeout = 2 * HZ;
schedule_timeout_interruptible(timeout);
@@ -384,7 +385,7 @@ void tty_port_close(struct tty_port *port, struct tty_struct *tty,
EXPORT_SYMBOL(tty_port_close);
int tty_port_open(struct tty_port *port, struct tty_struct *tty,
- struct file *filp)
+ struct file *filp)
{
spin_lock_irq(&port->lock);
if (!tty_hung_up_p(filp))
@@ -404,10 +405,10 @@ int tty_port_open(struct tty_port *port, struct tty_struct *tty,
if (port->ops->activate) {
int retval = port->ops->activate(port, tty);
if (retval) {
- mutex_unlock(&port->mutex);
- return retval;
- }
- }
+ mutex_unlock(&port->mutex);
+ return retval;
+ }
+ }
set_bit(ASYNCB_INITIALIZED, &port->flags);
}
mutex_unlock(&port->mutex);
--
1.6.5.5
^ permalink raw reply related [flat|nested] 100+ messages in thread* [PATCH 15/58] usb_serial: Use the shutdown() operation
2009-12-11 23:28 [GIT PATCH] TTY patches for 2.6.33-git Greg KH
` (13 preceding siblings ...)
2009-12-11 23:27 ` [PATCH 14/58] tty_port: coding style cleaning pass Greg Kroah-Hartman
@ 2009-12-11 23:27 ` Greg Kroah-Hartman
2009-12-11 23:28 ` [PATCH 16/58] usb_serial: Kill port mutex Greg Kroah-Hartman
` (43 subsequent siblings)
58 siblings, 0 replies; 100+ messages in thread
From: Greg Kroah-Hartman @ 2009-12-11 23:27 UTC (permalink / raw)
To: linux-kernel; +Cc: Alan Cox, Alan Stern, Oliver Neukum, Greg Kroah-Hartman
From: Alan Cox <alan@linux.intel.com>
As Alan Stern pointed out - now we have tty_port_open the shutdown method
and locking allow us to whack the other bits into the full helper methods
and provide a shutdown op which the tty port code will synchronize with
setup for us.
Signed-off-by: Alan Cox <alan@linux.intel.com>
Cc: Alan Stern <stern@rowland.harvard.edu>
Cc: Oliver Neukum <oliver@neukum.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
---
drivers/usb/serial/usb-serial.c | 39 +++++++++++----------------------------
1 files changed, 11 insertions(+), 28 deletions(-)
diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c
index b0649d9..829a466 100644
--- a/drivers/usb/serial/usb-serial.c
+++ b/drivers/usb/serial/usb-serial.c
@@ -254,15 +254,12 @@ static int serial_activate(struct tty_port *tport, struct tty_struct *tty)
struct usb_serial *serial = port->serial;
int retval;
- if (mutex_lock_interruptible(&port->mutex))
- return -ERESTARTSYS;
mutex_lock(&serial->disc_mutex);
if (serial->disconnected)
retval = -ENODEV;
else
retval = port->serial->type->open(tty, port);
mutex_unlock(&serial->disc_mutex);
- mutex_unlock(&port->mutex);
return retval;
}
@@ -276,57 +273,40 @@ static int serial_open(struct tty_struct *tty, struct file *filp)
/**
* serial_down - shut down hardware
- * @port: port to shut down
+ * @tport: tty port to shut down
*
* Shut down a USB serial port unless it is the console. We never
- * shut down the console hardware as it will always be in use.
+ * shut down the console hardware as it will always be in use. Serialized
+ * against activate by the tport mutex and kept to matching open/close pairs
+ * of calls by the ASYNCB_INITIALIZED flag.
*/
-static void serial_down(struct usb_serial_port *port)
+static void serial_down(struct tty_port *tport)
{
+ struct usb_serial_port *port =
+ container_of(tport, struct usb_serial_port, port);
struct usb_serial_driver *drv = port->serial->type;
-
/*
* The console is magical. Do not hang up the console hardware
* or there will be tears.
*/
if (port->console)
return;
-
- /* Don't call the close method if the hardware hasn't been
- * initialized.
- */
- if (!test_and_clear_bit(ASYNCB_INITIALIZED, &port->port.flags))
- return;
-
- mutex_lock(&port->mutex);
if (drv->close)
drv->close(port);
- mutex_unlock(&port->mutex);
}
static void serial_hangup(struct tty_struct *tty)
{
struct usb_serial_port *port = tty->driver_data;
-
dbg("%s - port %d", __func__, port->number);
-
- serial_down(port);
tty_port_hangup(&port->port);
}
static void serial_close(struct tty_struct *tty, struct file *filp)
{
struct usb_serial_port *port = tty->driver_data;
-
dbg("%s - port %d", __func__, port->number);
-
- if (tty_hung_up_p(filp))
- return;
- if (tty_port_close_start(&port->port, tty, filp) == 0)
- return;
- serial_down(port);
- tty_port_close_end(&port->port, tty);
- tty_port_tty_set(&port->port, NULL);
+ tty_port_close(&port->port, tty, filp);
}
/**
@@ -716,6 +696,7 @@ static const struct tty_port_operations serial_port_ops = {
.carrier_raised = serial_carrier_raised,
.dtr_rts = serial_dtr_rts,
.activate = serial_activate,
+ .shutdown = serial_down,
};
int usb_serial_probe(struct usb_interface *interface,
@@ -914,6 +895,8 @@ int usb_serial_probe(struct usb_interface *interface,
port->port.ops = &serial_port_ops;
port->serial = serial;
spin_lock_init(&port->lock);
+ /* Keep this for private driver use for the moment but
+ should probably go away */
mutex_init(&port->mutex);
INIT_WORK(&port->work, usb_serial_port_work);
serial->port[i] = port;
--
1.6.5.5
^ permalink raw reply related [flat|nested] 100+ messages in thread* [PATCH 16/58] usb_serial: Kill port mutex
2009-12-11 23:28 [GIT PATCH] TTY patches for 2.6.33-git Greg KH
` (14 preceding siblings ...)
2009-12-11 23:27 ` [PATCH 15/58] usb_serial: Use the shutdown() operation Greg Kroah-Hartman
@ 2009-12-11 23:28 ` Greg Kroah-Hartman
2009-12-11 23:28 ` [PATCH 17/58] opticon: Fix resume logic Greg Kroah-Hartman
` (42 subsequent siblings)
58 siblings, 0 replies; 100+ messages in thread
From: Greg Kroah-Hartman @ 2009-12-11 23:28 UTC (permalink / raw)
To: linux-kernel; +Cc: Alan Cox, Alan Stern, Oliver Neukum, Greg Kroah-Hartman
From: Alan Cox <alan@linux.intel.com>
The tty port has a port mutex used for all the port related locking so we
don't need the one in the USB serial layer any more.
Signed-off-by: Alan Cox <alan@linux.intel.com>
Cc: Alan Stern <stern@rowland.harvard.edu>
Cc: Oliver Neukum <oliver@neukum.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
---
drivers/usb/serial/opticon.c | 4 ++--
drivers/usb/serial/usb-serial.c | 1 -
include/linux/usb/serial.h | 3 ---
3 files changed, 2 insertions(+), 6 deletions(-)
diff --git a/drivers/usb/serial/opticon.c b/drivers/usb/serial/opticon.c
index 80f59b6..c03fdc0 100644
--- a/drivers/usb/serial/opticon.c
+++ b/drivers/usb/serial/opticon.c
@@ -501,12 +501,12 @@ static int opticon_resume(struct usb_interface *intf)
struct usb_serial_port *port = serial->port[0];
int result;
- mutex_lock(&port->mutex);
+ mutex_lock(&port->port.mutex);
if (port->port.count)
result = usb_submit_urb(priv->bulk_read_urb, GFP_NOIO);
else
result = 0;
- mutex_unlock(&port->mutex);
+ mutex_unlock(&port->port.mutex);
return result;
}
diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c
index 829a466..4543f35 100644
--- a/drivers/usb/serial/usb-serial.c
+++ b/drivers/usb/serial/usb-serial.c
@@ -897,7 +897,6 @@ int usb_serial_probe(struct usb_interface *interface,
spin_lock_init(&port->lock);
/* Keep this for private driver use for the moment but
should probably go away */
- mutex_init(&port->mutex);
INIT_WORK(&port->work, usb_serial_port_work);
serial->port[i] = port;
port->dev.parent = &interface->dev;
diff --git a/include/linux/usb/serial.h b/include/linux/usb/serial.h
index ce911eb..acf6e45 100644
--- a/include/linux/usb/serial.h
+++ b/include/linux/usb/serial.h
@@ -39,8 +39,6 @@ enum port_dev_state {
* @serial: pointer back to the struct usb_serial owner of this port.
* @port: pointer to the corresponding tty_port for this port.
* @lock: spinlock to grab when updating portions of this structure.
- * @mutex: mutex used to synchronize serial_open() and serial_close()
- * access for this port.
* @number: the number of the port (the minor number).
* @interrupt_in_buffer: pointer to the interrupt in buffer for this port.
* @interrupt_in_urb: pointer to the interrupt in struct urb for this port.
@@ -77,7 +75,6 @@ struct usb_serial_port {
struct usb_serial *serial;
struct tty_port port;
spinlock_t lock;
- struct mutex mutex;
unsigned char number;
unsigned char *interrupt_in_buffer;
--
1.6.5.5
^ permalink raw reply related [flat|nested] 100+ messages in thread* [PATCH 17/58] opticon: Fix resume logic
2009-12-11 23:28 [GIT PATCH] TTY patches for 2.6.33-git Greg KH
` (15 preceding siblings ...)
2009-12-11 23:28 ` [PATCH 16/58] usb_serial: Kill port mutex Greg Kroah-Hartman
@ 2009-12-11 23:28 ` Greg Kroah-Hartman
2009-12-11 23:28 ` [PATCH 18/58] serial: fix NULL pointer dereference Greg Kroah-Hartman
` (41 subsequent siblings)
58 siblings, 0 replies; 100+ messages in thread
From: Greg Kroah-Hartman @ 2009-12-11 23:28 UTC (permalink / raw)
To: linux-kernel; +Cc: Alan Cox, Alan Stern, Oliver Neukum, Greg Kroah-Hartman
From: Alan Cox <alan@linux.intel.com>
Opticon now takes the right mutex to check the port status but the status
check is done wrongly for the modern serial code, so fix it.
Signed-off-by: Alan Cox <alan@linux.intel.com>
Cc: Alan Stern <stern@rowland.harvard.edu>
Cc: Oliver Neukum <oliver@neukum.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
---
drivers/usb/serial/opticon.c | 3 ++-
1 files changed, 2 insertions(+), 1 deletions(-)
diff --git a/drivers/usb/serial/opticon.c b/drivers/usb/serial/opticon.c
index c03fdc0..4cdb975 100644
--- a/drivers/usb/serial/opticon.c
+++ b/drivers/usb/serial/opticon.c
@@ -502,7 +502,8 @@ static int opticon_resume(struct usb_interface *intf)
int result;
mutex_lock(&port->port.mutex);
- if (port->port.count)
+ /* This is protected by the port mutex against close/open */
+ if (test_bit(ASYNCB_INITIALIZED, &port->port.flags))
result = usb_submit_urb(priv->bulk_read_urb, GFP_NOIO);
else
result = 0;
--
1.6.5.5
^ permalink raw reply related [flat|nested] 100+ messages in thread* [PATCH 18/58] serial: fix NULL pointer dereference
2009-12-11 23:28 [GIT PATCH] TTY patches for 2.6.33-git Greg KH
` (16 preceding siblings ...)
2009-12-11 23:28 ` [PATCH 17/58] opticon: Fix resume logic Greg Kroah-Hartman
@ 2009-12-11 23:28 ` Greg Kroah-Hartman
2009-12-11 23:28 ` [PATCH 19/58] serial: cascade needless conditionals Greg Kroah-Hartman
` (40 subsequent siblings)
58 siblings, 0 replies; 100+ messages in thread
From: Greg Kroah-Hartman @ 2009-12-11 23:28 UTC (permalink / raw)
To: linux-kernel; +Cc: André Goddard Rosa, Greg Kroah-Hartman
From: André Goddard Rosa <andre.goddard@gmail.com>
If kzalloc() or alloc_tty_driver() fails, we call:
put_tty_driver(normal = NULL).
Then:
put_tty_driver -> tty_driver_kref_put -> kref_put(&NULL->kref, ...)
Signed-off-by: André Goddard Rosa <andre.goddard@gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
---
drivers/serial/serial_core.c | 21 +++++++++++----------
1 files changed, 11 insertions(+), 10 deletions(-)
diff --git a/drivers/serial/serial_core.c b/drivers/serial/serial_core.c
index dcc7244..885eabe 100644
--- a/drivers/serial/serial_core.c
+++ b/drivers/serial/serial_core.c
@@ -2344,7 +2344,7 @@ static const struct tty_operations uart_ops = {
*/
int uart_register_driver(struct uart_driver *drv)
{
- struct tty_driver *normal = NULL;
+ struct tty_driver *normal;
int i, retval;
BUG_ON(drv->state);
@@ -2354,13 +2354,12 @@ int uart_register_driver(struct uart_driver *drv)
* we have a large number of ports to handle.
*/
drv->state = kzalloc(sizeof(struct uart_state) * drv->nr, GFP_KERNEL);
- retval = -ENOMEM;
if (!drv->state)
goto out;
- normal = alloc_tty_driver(drv->nr);
+ normal = alloc_tty_driver(drv->nr);
if (!normal)
- goto out;
+ goto out_kfree;
drv->tty_driver = normal;
@@ -2393,12 +2392,14 @@ int uart_register_driver(struct uart_driver *drv)
}
retval = tty_register_driver(normal);
- out:
- if (retval < 0) {
- put_tty_driver(normal);
- kfree(drv->state);
- }
- return retval;
+ if (retval >= 0)
+ return retval;
+
+ put_tty_driver(normal);
+out_kfree:
+ kfree(drv->state);
+out:
+ return -ENOMEM;
}
/**
--
1.6.5.5
^ permalink raw reply related [flat|nested] 100+ messages in thread* [PATCH 19/58] serial: cascade needless conditionals
2009-12-11 23:28 [GIT PATCH] TTY patches for 2.6.33-git Greg KH
` (17 preceding siblings ...)
2009-12-11 23:28 ` [PATCH 18/58] serial: fix NULL pointer dereference Greg Kroah-Hartman
@ 2009-12-11 23:28 ` Greg Kroah-Hartman
2009-12-11 23:28 ` [PATCH 20/58] serial, 8250: calculate irqflags bitmask before loop Greg Kroah-Hartman
` (39 subsequent siblings)
58 siblings, 0 replies; 100+ messages in thread
From: Greg Kroah-Hartman @ 2009-12-11 23:28 UTC (permalink / raw)
To: linux-kernel; +Cc: André Goddard Rosa, Greg Kroah-Hartman
From: André Goddard Rosa <andre.goddard@gmail.com>
Signed-off-by: André Goddard Rosa <andre.goddard@gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
---
drivers/serial/serial_core.c | 12 +++++-------
1 files changed, 5 insertions(+), 7 deletions(-)
diff --git a/drivers/serial/serial_core.c b/drivers/serial/serial_core.c
index 885eabe..047530b 100644
--- a/drivers/serial/serial_core.c
+++ b/drivers/serial/serial_core.c
@@ -342,11 +342,11 @@ uart_get_baud_rate(struct uart_port *port, struct ktermios *termios,
if (flags == UPF_SPD_HI)
altbaud = 57600;
- if (flags == UPF_SPD_VHI)
+ else if (flags == UPF_SPD_VHI)
altbaud = 115200;
- if (flags == UPF_SPD_SHI)
+ else if (flags == UPF_SPD_SHI)
altbaud = 230400;
- if (flags == UPF_SPD_WARP)
+ else if (flags == UPF_SPD_WARP)
altbaud = 460800;
for (try = 0; try < 2; try++) {
@@ -1217,9 +1217,8 @@ static void uart_set_termios(struct tty_struct *tty,
/* Handle transition to B0 status */
if ((old_termios->c_cflag & CBAUD) && !(cflag & CBAUD))
uart_clear_mctrl(state->uart_port, TIOCM_RTS | TIOCM_DTR);
-
/* Handle transition away from B0 status */
- if (!(old_termios->c_cflag & CBAUD) && (cflag & CBAUD)) {
+ else if (!(old_termios->c_cflag & CBAUD) && (cflag & CBAUD)) {
unsigned int mask = TIOCM_DTR;
if (!(cflag & CRTSCTS) ||
!test_bit(TTY_THROTTLED, &tty->flags))
@@ -1234,9 +1233,8 @@ static void uart_set_termios(struct tty_struct *tty,
__uart_start(tty);
spin_unlock_irqrestore(&state->uart_port->lock, flags);
}
-
/* Handle turning on CRTSCTS */
- if (!(old_termios->c_cflag & CRTSCTS) && (cflag & CRTSCTS)) {
+ else if (!(old_termios->c_cflag & CRTSCTS) && (cflag & CRTSCTS)) {
spin_lock_irqsave(&state->uart_port->lock, flags);
if (!(state->uart_port->ops->get_mctrl(state->uart_port) & TIOCM_CTS)) {
tty->hw_stopped = 1;
--
1.6.5.5
^ permalink raw reply related [flat|nested] 100+ messages in thread* [PATCH 20/58] serial, 8250: calculate irqflags bitmask before loop
2009-12-11 23:28 [GIT PATCH] TTY patches for 2.6.33-git Greg KH
` (18 preceding siblings ...)
2009-12-11 23:28 ` [PATCH 19/58] serial: cascade needless conditionals Greg Kroah-Hartman
@ 2009-12-11 23:28 ` Greg Kroah-Hartman
2009-12-11 23:28 ` [PATCH 21/58] Serial: pxa: work around Errata #75 Greg Kroah-Hartman
` (38 subsequent siblings)
58 siblings, 0 replies; 100+ messages in thread
From: Greg Kroah-Hartman @ 2009-12-11 23:28 UTC (permalink / raw)
To: linux-kernel; +Cc: André Goddard Rosa, Greg Kroah-Hartman
From: André Goddard Rosa <andre.goddard@gmail.com>
Signed-off-by: André Goddard Rosa <andre.goddard@gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
---
drivers/serial/8250.c | 16 ++++++++++------
1 files changed, 10 insertions(+), 6 deletions(-)
diff --git a/drivers/serial/8250.c b/drivers/serial/8250.c
index 737b4c9..b75e63e 100644
--- a/drivers/serial/8250.c
+++ b/drivers/serial/8250.c
@@ -2646,7 +2646,7 @@ static void __init serial8250_isa_init_ports(void)
{
struct uart_8250_port *up;
static int first = 1;
- int i;
+ int i, irqflag = 0;
if (!first)
return;
@@ -2670,6 +2670,9 @@ static void __init serial8250_isa_init_ports(void)
up->port.ops = &serial8250_pops;
}
+ if (share_irqs)
+ irqflag = IRQF_SHARED;
+
for (i = 0, up = serial8250_ports;
i < ARRAY_SIZE(old_serial_port) && i < nr_uarts;
i++, up++) {
@@ -2683,8 +2686,7 @@ static void __init serial8250_isa_init_ports(void)
up->port.iotype = old_serial_port[i].io_type;
up->port.regshift = old_serial_port[i].iomem_reg_shift;
set_io_from_upio(&up->port);
- if (share_irqs)
- up->port.irqflags |= IRQF_SHARED;
+ up->port.irqflags |= irqflag;
}
}
@@ -2940,10 +2942,13 @@ static int __devinit serial8250_probe(struct platform_device *dev)
{
struct plat_serial8250_port *p = dev->dev.platform_data;
struct uart_port port;
- int ret, i;
+ int ret, i, irqflag = 0;
memset(&port, 0, sizeof(struct uart_port));
+ if (share_irqs)
+ irqflag = IRQF_SHARED;
+
for (i = 0; p && p->flags != 0; p++, i++) {
port.iobase = p->iobase;
port.membase = p->membase;
@@ -2960,8 +2965,7 @@ static int __devinit serial8250_probe(struct platform_device *dev)
port.serial_in = p->serial_in;
port.serial_out = p->serial_out;
port.dev = &dev->dev;
- if (share_irqs)
- port.irqflags |= IRQF_SHARED;
+ port.irqflags |= irqflag;
ret = serial8250_register_port(&port);
if (ret < 0) {
dev_err(&dev->dev, "unable to register port at index %d "
--
1.6.5.5
^ permalink raw reply related [flat|nested] 100+ messages in thread* [PATCH 21/58] Serial: pxa: work around Errata #75
2009-12-11 23:28 [GIT PATCH] TTY patches for 2.6.33-git Greg KH
` (19 preceding siblings ...)
2009-12-11 23:28 ` [PATCH 20/58] serial, 8250: calculate irqflags bitmask before loop Greg Kroah-Hartman
@ 2009-12-11 23:28 ` Greg Kroah-Hartman
2009-12-11 23:28 ` [PATCH 22/58] tty: docs: serial/tty, add to ldisc methods Greg Kroah-Hartman
` (37 subsequent siblings)
58 siblings, 0 replies; 100+ messages in thread
From: Greg Kroah-Hartman @ 2009-12-11 23:28 UTC (permalink / raw)
To: linux-kernel
Cc: Uwe Kleine-König, Eric Miao, Alan Cox, Mike Rapoport,
Greg Kroah-Hartman
From: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
Intel(R) PXA27x Processor Family Specification Update (Nov 2005)
says:
E75. UART: Baud rate may not be programmed correctly on
back-to-back writes.
Problem:
When programming the Divisor Latch registers, Low and High (DLL and
DLH), with back-to-back writes, the second register write may not
take effect. The result is an incorrect baud rate.
Workaround:
After programming the first Divisor Latch register, read and verify
it before programming the second Divisor Latch register.
This was hit when changing the baud rate from 115200 to 9600 while
receiving characters at 9600 Bd.
And fixed indention of some comments nearby.
Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
Acked-by: Wolfram Sang <w.sang@pengutronix.de>
Acked-by: Marc Kleine-Budde <mkl@pengutronix.de>
Cc: Eric Miao <eric.y.miao@gmail.com>
Cc: Alan Cox <alan@linux.intel.com>
Cc: Mike Rapoport <mike@compulab.co.il>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
---
drivers/serial/pxa.c | 13 +++++++++++--
1 files changed, 11 insertions(+), 2 deletions(-)
diff --git a/drivers/serial/pxa.c b/drivers/serial/pxa.c
index b8629d7..4a82104 100644
--- a/drivers/serial/pxa.c
+++ b/drivers/serial/pxa.c
@@ -438,6 +438,7 @@ serial_pxa_set_termios(struct uart_port *port, struct ktermios *termios,
unsigned char cval, fcr = 0;
unsigned long flags;
unsigned int baud, quot;
+ unsigned int dll;
switch (termios->c_cflag & CSIZE) {
case CS5:
@@ -534,10 +535,18 @@ serial_pxa_set_termios(struct uart_port *port, struct ktermios *termios,
else
up->mcr &= ~UART_MCR_AFE;
- serial_out(up, UART_LCR, cval | UART_LCR_DLAB);/* set DLAB */
+ serial_out(up, UART_LCR, cval | UART_LCR_DLAB); /* set DLAB */
serial_out(up, UART_DLL, quot & 0xff); /* LS of divisor */
+
+ /*
+ * work around Errata #75 according to Intel(R) PXA27x Processor Family
+ * Specification Update (Nov 2005)
+ */
+ dll = serial_in(up, UART_DLL);
+ WARN_ON(dll != (quot & 0xff));
+
serial_out(up, UART_DLM, quot >> 8); /* MS of divisor */
- serial_out(up, UART_LCR, cval); /* reset DLAB */
+ serial_out(up, UART_LCR, cval); /* reset DLAB */
up->lcr = cval; /* Save LCR */
serial_pxa_set_mctrl(&up->port, up->port.mctrl);
serial_out(up, UART_FCR, fcr);
--
1.6.5.5
^ permalink raw reply related [flat|nested] 100+ messages in thread* [PATCH 22/58] tty: docs: serial/tty, add to ldisc methods
2009-12-11 23:28 [GIT PATCH] TTY patches for 2.6.33-git Greg KH
` (20 preceding siblings ...)
2009-12-11 23:28 ` [PATCH 21/58] Serial: pxa: work around Errata #75 Greg Kroah-Hartman
@ 2009-12-11 23:28 ` Greg Kroah-Hartman
2009-12-11 23:28 ` [PATCH 23/58] Serial: Do not read IIR in serial8250_start_tx when UART_BUG_TXEN Greg Kroah-Hartman
` (36 subsequent siblings)
58 siblings, 0 replies; 100+ messages in thread
From: Greg Kroah-Hartman @ 2009-12-11 23:28 UTC (permalink / raw)
To: linux-kernel; +Cc: Tilman Schmidt, Randy Dunlap, Greg Kroah-Hartman
From: Tilman Schmidt <tilman@imap.cc>
A small addition to the ldisc method descriptions.
Signed-off-by: Tilman Schmidt <tilman@imap.cc>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Acked-by: Alan Cox <alan@linux.intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
---
Documentation/serial/tty.txt | 9 +++++++--
1 files changed, 7 insertions(+), 2 deletions(-)
diff --git a/Documentation/serial/tty.txt b/Documentation/serial/tty.txt
index 8e65c44..5e5349a 100644
--- a/Documentation/serial/tty.txt
+++ b/Documentation/serial/tty.txt
@@ -42,7 +42,8 @@ TTY side interfaces:
open() - Called when the line discipline is attached to
the terminal. No other call into the line
discipline for this tty will occur until it
- completes successfully. Can sleep.
+ completes successfully. Returning an error will
+ prevent the ldisc from being attached. Can sleep.
close() - This is called on a terminal when the line
discipline is being unplugged. At the point of
@@ -52,7 +53,7 @@ close() - This is called on a terminal when the line
hangup() - Called when the tty line is hung up.
The line discipline should cease I/O to the tty.
No further calls into the ldisc code will occur.
- Can sleep.
+ The return value is ignored. Can sleep.
write() - A process is writing data through the line
discipline. Multiple write calls are serialized
@@ -83,6 +84,10 @@ ioctl() - Called when an ioctl is handed to the tty layer
that might be for the ldisc. Multiple ioctl calls
may occur in parallel. May sleep.
+compat_ioctl() - Called when a 32 bit ioctl is handed to the tty layer
+ that might be for the ldisc. Multiple ioctl calls
+ may occur in parallel. May sleep.
+
Driver Side Interfaces:
receive_buf() - Hand buffers of bytes from the driver to the ldisc
--
1.6.5.5
^ permalink raw reply related [flat|nested] 100+ messages in thread* [PATCH 23/58] Serial: Do not read IIR in serial8250_start_tx when UART_BUG_TXEN
2009-12-11 23:28 [GIT PATCH] TTY patches for 2.6.33-git Greg KH
` (21 preceding siblings ...)
2009-12-11 23:28 ` [PATCH 22/58] tty: docs: serial/tty, add to ldisc methods Greg Kroah-Hartman
@ 2009-12-11 23:28 ` Greg Kroah-Hartman
2009-12-11 23:28 ` [PATCH 24/58] devpts_get_tty() should validate inode Greg Kroah-Hartman
` (35 subsequent siblings)
58 siblings, 0 replies; 100+ messages in thread
From: Greg Kroah-Hartman @ 2009-12-11 23:28 UTC (permalink / raw)
To: linux-kernel; +Cc: Ian Jackson, Alan Cox, stable, Greg Kroah-Hartman
From: Ian Jackson <ian.jackson@eu.citrix.com>
Do not read IIR in serial8250_start_tx when UART_BUG_TXEN
Reading the IIR clears some oustanding interrupts so it is not safe.
Instead, simply transmit immediately if the buffer is empty without
regard to IIR.
Signed-off-by: Ian Jackson <ian.jackson@eu.citrix.com>
Reviewed-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Jiri Kosina <jkosina@suse.cz>
Cc: Alan Cox <alan@linux.intel.com>
Cc: stable <stable@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
---
drivers/serial/8250.c | 8 +++-----
1 files changed, 3 insertions(+), 5 deletions(-)
diff --git a/drivers/serial/8250.c b/drivers/serial/8250.c
index b75e63e..c3e37c8 100644
--- a/drivers/serial/8250.c
+++ b/drivers/serial/8250.c
@@ -1339,14 +1339,12 @@ static void serial8250_start_tx(struct uart_port *port)
serial_out(up, UART_IER, up->ier);
if (up->bugs & UART_BUG_TXEN) {
- unsigned char lsr, iir;
+ unsigned char lsr;
lsr = serial_in(up, UART_LSR);
up->lsr_saved_flags |= lsr & LSR_SAVE_FLAGS;
- iir = serial_in(up, UART_IIR) & 0x0f;
if ((up->port.type == PORT_RM9000) ?
- (lsr & UART_LSR_THRE &&
- (iir == UART_IIR_NO_INT || iir == UART_IIR_THRI)) :
- (lsr & UART_LSR_TEMT && iir & UART_IIR_NO_INT))
+ (lsr & UART_LSR_THRE) :
+ (lsr & UART_LSR_TEMT))
transmit_chars(up);
}
}
--
1.6.5.5
^ permalink raw reply related [flat|nested] 100+ messages in thread* [PATCH 24/58] devpts_get_tty() should validate inode
2009-12-11 23:28 [GIT PATCH] TTY patches for 2.6.33-git Greg KH
` (22 preceding siblings ...)
2009-12-11 23:28 ` [PATCH 23/58] Serial: Do not read IIR in serial8250_start_tx when UART_BUG_TXEN Greg Kroah-Hartman
@ 2009-12-11 23:28 ` Greg Kroah-Hartman
2009-12-11 23:28 ` [PATCH 25/58] tty_port: Move hupcl handling Greg Kroah-Hartman
` (34 subsequent siblings)
58 siblings, 0 replies; 100+ messages in thread
From: Greg Kroah-Hartman @ 2009-12-11 23:28 UTC (permalink / raw)
To: linux-kernel; +Cc: Sukadev Bhattiprolu, stable, Greg Kroah-Hartman
From: Sukadev Bhattiprolu <sukadev@linux.vnet.ibm.com>
devpts_get_tty() assumes that the inode passed in is associated with a valid
pty. But if the only reference to the pty is via a bind-mount, the inode
passed to devpts_get_tty() while valid, would refer to a pty that no longer
exists.
With a lot of debug effort, Grzegorz Nosek developed a small program (see
below) to reproduce a crash on recent kernels. This crash is a regression
introduced by the commit:
commit 527b3e4773628b30d03323a2cb5fb0d84441990f
Author: Sukadev Bhattiprolu <sukadev@us.ibm.com>
Date: Mon Oct 13 10:43:08 2008 +0100
To fix, ensure that the dentry associated with the inode has not yet been
deleted/unhashed by devpts_pty_kill().
See also:
https://lists.linux-foundation.org/pipermail/containers/2009-July/019273.html
tty-bug.c:
#define _GNU_SOURCE
#include <fcntl.h>
#include <sched.h>
#include <stdlib.h>
#include <sys/mount.h>
#include <sys/signal.h>
#include <unistd.h>
#include <stdio.h>
#include <linux/fs.h>
void dummy(int sig)
{
}
static int child(void *unused)
{
int fd;
signal(SIGINT, dummy); signal(SIGHUP, dummy);
pause(); /* cheesy synchronisation to wait for /dev/pts/0 to appear */
mount("/dev/pts/0", "/dev/console", NULL, MS_BIND, NULL);
sleep(2);
fd = open("/dev/console", O_RDWR);
dup(0); dup(0);
write(1, "Hello world!\n", sizeof("Hello world!\n")-1);
return 0;
}
int main(void)
{
pid_t pid;
char *stack;
stack = malloc(16384);
pid = clone(child, stack+16384, CLONE_NEWNS|SIGCHLD, NULL);
open("/dev/ptmx", O_RDWR|O_NOCTTY|O_NONBLOCK);
unlockpt(fd); grantpt(fd);
sleep(2);
kill(pid, SIGHUP);
sleep(1);
return 0; /* exit before child opens /dev/console */
}
Reported-by: Grzegorz Nosek <root@localdomain.pl>
Signed-off-by: Sukadev Bhattiprolu <sukadev@linux.vnet.ibm.com>
Tested-by: Serge Hallyn <serue@us.ibm.com>
Cc: stable <stable@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
---
fs/devpts/inode.c | 16 ++++++++++++++--
1 files changed, 14 insertions(+), 2 deletions(-)
diff --git a/fs/devpts/inode.c b/fs/devpts/inode.c
index d5f8c96..8882ecc 100644
--- a/fs/devpts/inode.c
+++ b/fs/devpts/inode.c
@@ -517,11 +517,23 @@ int devpts_pty_new(struct inode *ptmx_inode, struct tty_struct *tty)
struct tty_struct *devpts_get_tty(struct inode *pts_inode, int number)
{
+ struct dentry *dentry;
+ struct tty_struct *tty;
+
BUG_ON(pts_inode->i_rdev == MKDEV(TTYAUX_MAJOR, PTMX_MINOR));
+ /* Ensure dentry has not been deleted by devpts_pty_kill() */
+ dentry = d_find_alias(pts_inode);
+ if (!dentry)
+ return NULL;
+
+ tty = NULL;
if (pts_inode->i_sb->s_magic == DEVPTS_SUPER_MAGIC)
- return (struct tty_struct *)pts_inode->i_private;
- return NULL;
+ tty = (struct tty_struct *)pts_inode->i_private;
+
+ dput(dentry);
+
+ return tty;
}
void devpts_pty_kill(struct tty_struct *tty)
--
1.6.5.5
^ permalink raw reply related [flat|nested] 100+ messages in thread* [PATCH 25/58] tty_port: Move hupcl handling
2009-12-11 23:28 [GIT PATCH] TTY patches for 2.6.33-git Greg KH
` (23 preceding siblings ...)
2009-12-11 23:28 ` [PATCH 24/58] devpts_get_tty() should validate inode Greg Kroah-Hartman
@ 2009-12-11 23:28 ` Greg Kroah-Hartman
2009-12-11 23:28 ` [PATCH 26/58] sdio_uart: use tty_port Greg Kroah-Hartman
` (33 subsequent siblings)
58 siblings, 0 replies; 100+ messages in thread
From: Greg Kroah-Hartman @ 2009-12-11 23:28 UTC (permalink / raw)
To: linux-kernel; +Cc: Alan Cox, Greg Kroah-Hartman
From: Alan Cox <alan@linux.intel.com>
Move the HUCPL handling from the end of close_port_start to the beginning
of close_port_end. What this actually does is change the ordering from
port shutdown
port->dtr_rts
to
port->dtr_rts
port shutdown
Some hardware drops the physical connection on shutdown so we must perform
the port operations before the shutdown.
Signed-off-by: Alan Cox <alan@linux.intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
---
drivers/char/tty_port.c | 13 ++++++++-----
1 files changed, 8 insertions(+), 5 deletions(-)
diff --git a/drivers/char/tty_port.c b/drivers/char/tty_port.c
index 41b314c..dd471d6 100644
--- a/drivers/char/tty_port.c
+++ b/drivers/char/tty_port.c
@@ -339,6 +339,14 @@ int tty_port_close_start(struct tty_port *port,
timeout = 2 * HZ;
schedule_timeout_interruptible(timeout);
}
+ /* Flush the ldisc buffering */
+ tty_ldisc_flush(tty);
+
+ /* Drop DTR/RTS if HUPCL is set. This causes any attached modem to
+ hang up the line */
+ if (tty->termios->c_cflag & HUPCL)
+ tty_port_lower_dtr_rts(port);
+
/* Don't call port->drop for the last reference. Callers will want
to drop the last active reference in ->shutdown() or the tty
shutdown path */
@@ -350,11 +358,6 @@ void tty_port_close_end(struct tty_port *port, struct tty_struct *tty)
{
unsigned long flags;
- tty_ldisc_flush(tty);
-
- if (tty->termios->c_cflag & HUPCL)
- tty_port_lower_dtr_rts(port);
-
spin_lock_irqsave(&port->lock, flags);
tty->closing = 0;
--
1.6.5.5
^ permalink raw reply related [flat|nested] 100+ messages in thread* [PATCH 26/58] sdio_uart: use tty_port
2009-12-11 23:28 [GIT PATCH] TTY patches for 2.6.33-git Greg KH
` (24 preceding siblings ...)
2009-12-11 23:28 ` [PATCH 25/58] tty_port: Move hupcl handling Greg Kroah-Hartman
@ 2009-12-11 23:28 ` Greg Kroah-Hartman
2009-12-11 23:28 ` [PATCH 27/58] sdio_uart: Fix oops caused by the previous changeset Greg Kroah-Hartman
` (32 subsequent siblings)
58 siblings, 0 replies; 100+ messages in thread
From: Greg Kroah-Hartman @ 2009-12-11 23:28 UTC (permalink / raw)
To: linux-kernel; +Cc: Alan Cox, Greg Kroah-Hartman
From: Alan Cox <alan@linux.intel.com>
Add a tty_port object to the sdio uart. For the moment just begin using the
tty field of the port, as this is the critical one to clean up.
Signed-off-by: Alan Cox <alan@linux.intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
---
drivers/mmc/card/sdio_uart.c | 41 +++++++++++++++++++++++------------------
1 files changed, 23 insertions(+), 18 deletions(-)
diff --git a/drivers/mmc/card/sdio_uart.c b/drivers/mmc/card/sdio_uart.c
index b8e7c5a..c2759db 100644
--- a/drivers/mmc/card/sdio_uart.c
+++ b/drivers/mmc/card/sdio_uart.c
@@ -73,6 +73,7 @@ struct uart_icount {
};
struct sdio_uart_port {
+ struct tty_port port;
struct kref kref;
struct tty_struct *tty;
unsigned int index;
@@ -172,7 +173,7 @@ static void sdio_uart_port_remove(struct sdio_uart_port *port)
port->func = NULL;
mutex_unlock(&port->func_lock);
if (port->opened)
- tty_hangup(port->tty);
+ tty_hangup(port->port.tty);
mutex_unlock(&port->open_lock);
sdio_release_irq(func);
sdio_disable_func(func);
@@ -391,7 +392,7 @@ static void sdio_uart_stop_rx(struct sdio_uart_port *port)
static void sdio_uart_receive_chars(struct sdio_uart_port *port,
unsigned int *status)
{
- struct tty_struct *tty = port->tty;
+ struct tty_struct *tty = port->port.tty;
unsigned int ch, flag;
int max_count = 256;
@@ -446,6 +447,7 @@ static void sdio_uart_transmit_chars(struct sdio_uart_port *port)
{
struct circ_buf *xmit = &port->xmit;
int count;
+ struct tty_struct *tty = port->port.tty;
if (port->x_char) {
sdio_out(port, UART_TX, port->x_char);
@@ -453,7 +455,7 @@ static void sdio_uart_transmit_chars(struct sdio_uart_port *port)
port->x_char = 0;
return;
}
- if (circ_empty(xmit) || port->tty->stopped || port->tty->hw_stopped) {
+ if (circ_empty(xmit) || tty->stopped || tty->hw_stopped) {
sdio_uart_stop_tx(port);
return;
}
@@ -468,7 +470,7 @@ static void sdio_uart_transmit_chars(struct sdio_uart_port *port)
} while (--count > 0);
if (circ_chars_pending(xmit) < WAKEUP_CHARS)
- tty_wakeup(port->tty);
+ tty_wakeup(tty);
if (circ_empty(xmit))
sdio_uart_stop_tx(port);
@@ -477,6 +479,7 @@ static void sdio_uart_transmit_chars(struct sdio_uart_port *port)
static void sdio_uart_check_modem_status(struct sdio_uart_port *port)
{
int status;
+ struct tty_struct *tty = port->port.tty;
status = sdio_in(port, UART_MSR);
@@ -491,17 +494,17 @@ static void sdio_uart_check_modem_status(struct sdio_uart_port *port)
port->icount.dcd++;
if (status & UART_MSR_DCTS) {
port->icount.cts++;
- if (port->tty->termios->c_cflag & CRTSCTS) {
+ if (tty->termios->c_cflag & CRTSCTS) {
int cts = (status & UART_MSR_CTS);
- if (port->tty->hw_stopped) {
+ if (tty->hw_stopped) {
if (cts) {
- port->tty->hw_stopped = 0;
+ tty->hw_stopped = 0;
sdio_uart_start_tx(port);
- tty_wakeup(port->tty);
+ tty_wakeup(tty);
}
} else {
if (!cts) {
- port->tty->hw_stopped = 1;
+ tty->hw_stopped = 1;
sdio_uart_stop_tx(port);
}
}
@@ -546,12 +549,13 @@ static int sdio_uart_startup(struct sdio_uart_port *port)
{
unsigned long page;
int ret;
+ struct tty_struct *tty = port->port.tty;
/*
* Set the TTY IO error marker - we will only clear this
* once we have successfully opened the port.
*/
- set_bit(TTY_IO_ERROR, &port->tty->flags);
+ set_bit(TTY_IO_ERROR, &tty->flags);
/* Initialise and allocate the transmit buffer. */
page = __get_free_page(GFP_KERNEL);
@@ -595,14 +599,14 @@ static int sdio_uart_startup(struct sdio_uart_port *port)
port->ier = UART_IER_RLSI | UART_IER_RDI | UART_IER_RTOIE | UART_IER_UUE;
port->mctrl = TIOCM_OUT2;
- sdio_uart_change_speed(port, port->tty->termios, NULL);
+ sdio_uart_change_speed(port, tty->termios, NULL);
- if (port->tty->termios->c_cflag & CBAUD)
+ if (tty->termios->c_cflag & CBAUD)
sdio_uart_set_mctrl(port, TIOCM_RTS | TIOCM_DTR);
- if (port->tty->termios->c_cflag & CRTSCTS)
+ if (tty->termios->c_cflag & CRTSCTS)
if (!(sdio_uart_get_mctrl(port) & TIOCM_CTS))
- port->tty->hw_stopped = 1;
+ tty->hw_stopped = 1;
clear_bit(TTY_IO_ERROR, &port->tty->flags);
@@ -634,7 +638,7 @@ static void sdio_uart_shutdown(struct sdio_uart_port *port)
/* TODO: wait here for TX FIFO to drain */
/* Turn off DTR and RTS early. */
- if (port->tty->termios->c_cflag & HUPCL)
+ if (port->port.tty->termios->c_cflag & HUPCL)
sdio_uart_clear_mctrl(port, TIOCM_DTR | TIOCM_RTS);
/* Disable interrupts from this port */
@@ -684,11 +688,11 @@ static int sdio_uart_open(struct tty_struct *tty, struct file *filp)
if (!port->opened) {
tty->driver_data = port;
- port->tty = tty;
+ port->port.tty = tty;
ret = sdio_uart_startup(port);
if (ret) {
tty->driver_data = NULL;
- port->tty = NULL;
+ port->port.tty = NULL;
mutex_unlock(&port->open_lock);
sdio_uart_port_put(port);
return ret;
@@ -723,7 +727,7 @@ static void sdio_uart_close(struct tty_struct *tty, struct file * filp)
tty->closing = 1;
sdio_uart_shutdown(port);
tty_ldisc_flush(tty);
- port->tty = NULL;
+ port->port.tty = NULL;
tty->driver_data = NULL;
tty->closing = 0;
}
@@ -1068,6 +1072,7 @@ static int sdio_uart_probe(struct sdio_func *func,
port->func = func;
sdio_set_drvdata(func, port);
+ tty_port_init(&port->port);
ret = sdio_uart_add_port(port);
if (ret) {
--
1.6.5.5
^ permalink raw reply related [flat|nested] 100+ messages in thread* [PATCH 27/58] sdio_uart: Fix oops caused by the previous changeset
2009-12-11 23:28 [GIT PATCH] TTY patches for 2.6.33-git Greg KH
` (25 preceding siblings ...)
2009-12-11 23:28 ` [PATCH 26/58] sdio_uart: use tty_port Greg Kroah-Hartman
@ 2009-12-11 23:28 ` Greg Kroah-Hartman
2009-12-11 23:28 ` [PATCH 28/58] sdio_uart: refcount the tty objects Greg Kroah-Hartman
` (31 subsequent siblings)
58 siblings, 0 replies; 100+ messages in thread
From: Greg Kroah-Hartman @ 2009-12-11 23:28 UTC (permalink / raw)
To: linux-kernel; +Cc: Nicolas Pitre, Alan Cox, Greg Kroah-Hartman
From: Nicolas Pitre <nico@fluxnic.net>
Now... testing reveals that the very first patch "sdio_uart: use
tty_port" causes a segmentation fault in sdio_uart_open():
Unable to handle kernel NULL pointer dereference at virtual address 00000084
pgd = dfb44000 [00000084] *pgd=1fb99031, *pte=00000000, *ppte=00000000
Internal error: Oops: 17 [#1] PREEMPT
last sysfs file:
/sys/devices/platform/mvsdio/mmc_host/mmc0/mmc0:f111/uevent
Modules linked in:
CPU: 0 Not tainted (2.6.32-rc5-next-20091102-00001-gb36eae9 #10)
PC is at sdio_uart_open+0x204/0x2cc
[...]
Signed-off-by: Alan Cox <alan@linux.intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
---
drivers/mmc/card/sdio_uart.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/drivers/mmc/card/sdio_uart.c b/drivers/mmc/card/sdio_uart.c
index c2759db..671fe5e 100644
--- a/drivers/mmc/card/sdio_uart.c
+++ b/drivers/mmc/card/sdio_uart.c
@@ -608,7 +608,7 @@ static int sdio_uart_startup(struct sdio_uart_port *port)
if (!(sdio_uart_get_mctrl(port) & TIOCM_CTS))
tty->hw_stopped = 1;
- clear_bit(TTY_IO_ERROR, &port->tty->flags);
+ clear_bit(TTY_IO_ERROR, &tty->flags);
/* Kick the IRQ handler once while we're still holding the host lock */
sdio_uart_irq(port->func);
--
1.6.5.5
^ permalink raw reply related [flat|nested] 100+ messages in thread* [PATCH 28/58] sdio_uart: refcount the tty objects
2009-12-11 23:28 [GIT PATCH] TTY patches for 2.6.33-git Greg KH
` (26 preceding siblings ...)
2009-12-11 23:28 ` [PATCH 27/58] sdio_uart: Fix oops caused by the previous changeset Greg Kroah-Hartman
@ 2009-12-11 23:28 ` Greg Kroah-Hartman
2009-12-11 23:28 ` [PATCH 29/58] sdio_uart: Move the open lock Greg Kroah-Hartman
` (30 subsequent siblings)
58 siblings, 0 replies; 100+ messages in thread
From: Greg Kroah-Hartman @ 2009-12-11 23:28 UTC (permalink / raw)
To: linux-kernel; +Cc: Alan Cox, Greg Kroah-Hartman
From: Alan Cox <alan@linux.intel.com>
The tty can go away underneath us, so we must refcount it. Do the naïve
implementation initially. We will worry about startup shortly.
Signed-off-by: Alan Cox <alan@linux.intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
---
drivers/mmc/card/sdio_uart.c | 59 +++++++++++++++++++++++++++++------------
1 files changed, 42 insertions(+), 17 deletions(-)
diff --git a/drivers/mmc/card/sdio_uart.c b/drivers/mmc/card/sdio_uart.c
index 671fe5e..86ad543 100644
--- a/drivers/mmc/card/sdio_uart.c
+++ b/drivers/mmc/card/sdio_uart.c
@@ -172,8 +172,13 @@ static void sdio_uart_port_remove(struct sdio_uart_port *port)
sdio_claim_host(func);
port->func = NULL;
mutex_unlock(&port->func_lock);
- if (port->opened)
- tty_hangup(port->port.tty);
+ if (port->opened) {
+ struct tty_struct *tty = tty_port_tty_get(&port->port);
+ /* tty_hangup is async so is this safe as is ?? */
+ if (tty)
+ tty_hangup(tty);
+ tty_kref_put(tty);
+ }
mutex_unlock(&port->open_lock);
sdio_release_irq(func);
sdio_disable_func(func);
@@ -392,7 +397,7 @@ static void sdio_uart_stop_rx(struct sdio_uart_port *port)
static void sdio_uart_receive_chars(struct sdio_uart_port *port,
unsigned int *status)
{
- struct tty_struct *tty = port->port.tty;
+ struct tty_struct *tty = tty_port_tty_get(&port->port);
unsigned int ch, flag;
int max_count = 256;
@@ -429,25 +434,30 @@ static void sdio_uart_receive_chars(struct sdio_uart_port *port,
}
if ((*status & port->ignore_status_mask & ~UART_LSR_OE) == 0)
- tty_insert_flip_char(tty, ch, flag);
+ if (tty)
+ tty_insert_flip_char(tty, ch, flag);
/*
* Overrun is special. Since it's reported immediately,
* it doesn't affect the current character.
*/
if (*status & ~port->ignore_status_mask & UART_LSR_OE)
- tty_insert_flip_char(tty, 0, TTY_OVERRUN);
+ if (tty)
+ tty_insert_flip_char(tty, 0, TTY_OVERRUN);
*status = sdio_in(port, UART_LSR);
} while ((*status & UART_LSR_DR) && (max_count-- > 0));
- tty_flip_buffer_push(tty);
+ if (tty) {
+ tty_flip_buffer_push(tty);
+ tty_kref_put(tty);
+ }
}
static void sdio_uart_transmit_chars(struct sdio_uart_port *port)
{
struct circ_buf *xmit = &port->xmit;
int count;
- struct tty_struct *tty = port->port.tty;
+ struct tty_struct *tty;
if (port->x_char) {
sdio_out(port, UART_TX, port->x_char);
@@ -455,8 +465,12 @@ static void sdio_uart_transmit_chars(struct sdio_uart_port *port)
port->x_char = 0;
return;
}
- if (circ_empty(xmit) || tty->stopped || tty->hw_stopped) {
+
+ tty = tty_port_tty_get(&port->port);
+
+ if (tty == NULL || circ_empty(xmit) || tty->stopped || tty->hw_stopped) {
sdio_uart_stop_tx(port);
+ tty_kref_put(tty);
return;
}
@@ -474,12 +488,13 @@ static void sdio_uart_transmit_chars(struct sdio_uart_port *port)
if (circ_empty(xmit))
sdio_uart_stop_tx(port);
+ tty_kref_put(tty);
}
static void sdio_uart_check_modem_status(struct sdio_uart_port *port)
{
int status;
- struct tty_struct *tty = port->port.tty;
+ struct tty_struct *tty;
status = sdio_in(port, UART_MSR);
@@ -494,7 +509,8 @@ static void sdio_uart_check_modem_status(struct sdio_uart_port *port)
port->icount.dcd++;
if (status & UART_MSR_DCTS) {
port->icount.cts++;
- if (tty->termios->c_cflag & CRTSCTS) {
+ tty = tty_port_tty_get(&port->port);
+ if (tty && (tty->termios->c_cflag & CRTSCTS)) {
int cts = (status & UART_MSR_CTS);
if (tty->hw_stopped) {
if (cts) {
@@ -509,6 +525,7 @@ static void sdio_uart_check_modem_status(struct sdio_uart_port *port)
}
}
}
+ tty_kref_put(tty);
}
}
@@ -548,8 +565,10 @@ static void sdio_uart_irq(struct sdio_func *func)
static int sdio_uart_startup(struct sdio_uart_port *port)
{
unsigned long page;
- int ret;
- struct tty_struct *tty = port->port.tty;
+ int ret = -ENOMEM;
+ struct tty_struct *tty = tty_port_tty_get(&port->port);
+
+ /* FIXME: What if it is NULL ?? */
/*
* Set the TTY IO error marker - we will only clear this
@@ -560,7 +579,7 @@ static int sdio_uart_startup(struct sdio_uart_port *port)
/* Initialise and allocate the transmit buffer. */
page = __get_free_page(GFP_KERNEL);
if (!page)
- return -ENOMEM;
+ goto err0;
port->xmit.buf = (unsigned char *)page;
circ_clear(&port->xmit);
@@ -614,6 +633,7 @@ static int sdio_uart_startup(struct sdio_uart_port *port)
sdio_uart_irq(port->func);
sdio_uart_release_func(port);
+ tty_kref_put(tty);
return 0;
err3:
@@ -622,12 +642,15 @@ err2:
sdio_uart_release_func(port);
err1:
free_page((unsigned long)port->xmit.buf);
+err0:
+ tty_kref_put(tty);
return ret;
}
static void sdio_uart_shutdown(struct sdio_uart_port *port)
{
int ret;
+ struct tty_struct *tty;
ret = sdio_uart_claim_func(port);
if (ret)
@@ -637,9 +660,11 @@ static void sdio_uart_shutdown(struct sdio_uart_port *port)
/* TODO: wait here for TX FIFO to drain */
+ tty = tty_port_tty_get(&port->port);
/* Turn off DTR and RTS early. */
- if (port->port.tty->termios->c_cflag & HUPCL)
+ if (tty && (tty->termios->c_cflag & HUPCL))
sdio_uart_clear_mctrl(port, TIOCM_DTR | TIOCM_RTS);
+ tty_kref_put(tty);
/* Disable interrupts from this port */
sdio_release_irq(port->func);
@@ -688,11 +713,11 @@ static int sdio_uart_open(struct tty_struct *tty, struct file *filp)
if (!port->opened) {
tty->driver_data = port;
- port->port.tty = tty;
+ tty_port_tty_set(&port->port, tty);
ret = sdio_uart_startup(port);
if (ret) {
tty->driver_data = NULL;
- port->port.tty = NULL;
+ tty_port_tty_set(&port->port, NULL);
mutex_unlock(&port->open_lock);
sdio_uart_port_put(port);
return ret;
@@ -727,7 +752,7 @@ static void sdio_uart_close(struct tty_struct *tty, struct file * filp)
tty->closing = 1;
sdio_uart_shutdown(port);
tty_ldisc_flush(tty);
- port->port.tty = NULL;
+ tty_port_tty_set(&port->port, NULL);
tty->driver_data = NULL;
tty->closing = 0;
}
--
1.6.5.5
^ permalink raw reply related [flat|nested] 100+ messages in thread* [PATCH 29/58] sdio_uart: Move the open lock
2009-12-11 23:28 [GIT PATCH] TTY patches for 2.6.33-git Greg KH
` (27 preceding siblings ...)
2009-12-11 23:28 ` [PATCH 28/58] sdio_uart: refcount the tty objects Greg Kroah-Hartman
@ 2009-12-11 23:28 ` Greg Kroah-Hartman
2009-12-11 23:28 ` [PATCH 30/58] tty: sdio_uart: Switch to the open/close helpers Greg Kroah-Hartman
` (29 subsequent siblings)
58 siblings, 0 replies; 100+ messages in thread
From: Greg Kroah-Hartman @ 2009-12-11 23:28 UTC (permalink / raw)
To: linux-kernel; +Cc: Alan Cox, Greg Kroah-Hartman
From: Alan Cox <alan@linux.intel.com>
When we move to the tty_port logic the port mutex will protect open v close
v hangup. Move to this first in the existing open code so we have a bisection
point.
Signed-off-by: Alan Cox <alan@linux.intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
---
drivers/mmc/card/sdio_uart.c | 20 +++++++++-----------
1 files changed, 9 insertions(+), 11 deletions(-)
diff --git a/drivers/mmc/card/sdio_uart.c b/drivers/mmc/card/sdio_uart.c
index 86ad543..31f7023 100644
--- a/drivers/mmc/card/sdio_uart.c
+++ b/drivers/mmc/card/sdio_uart.c
@@ -78,7 +78,6 @@ struct sdio_uart_port {
struct tty_struct *tty;
unsigned int index;
unsigned int opened;
- struct mutex open_lock;
struct sdio_func *func;
struct mutex func_lock;
struct task_struct *in_sdio_uart_irq;
@@ -103,7 +102,6 @@ static int sdio_uart_add_port(struct sdio_uart_port *port)
int index, ret = -EBUSY;
kref_init(&port->kref);
- mutex_init(&port->open_lock);
mutex_init(&port->func_lock);
spin_lock_init(&port->write_lock);
@@ -166,7 +164,7 @@ static void sdio_uart_port_remove(struct sdio_uart_port *port)
* give up on that port ASAP.
* Beware: the lock ordering is critical.
*/
- mutex_lock(&port->open_lock);
+ mutex_lock(&port->port.mutex);
mutex_lock(&port->func_lock);
func = port->func;
sdio_claim_host(func);
@@ -179,7 +177,7 @@ static void sdio_uart_port_remove(struct sdio_uart_port *port)
tty_hangup(tty);
tty_kref_put(tty);
}
- mutex_unlock(&port->open_lock);
+ mutex_unlock(&port->port.mutex);
sdio_release_irq(func);
sdio_disable_func(func);
sdio_release_host(func);
@@ -699,14 +697,14 @@ static int sdio_uart_open(struct tty_struct *tty, struct file *filp)
if (!port)
return -ENODEV;
- mutex_lock(&port->open_lock);
+ mutex_lock(&port->port.mutex);
/*
* Make sure not to mess up with a dead port
* which has not been closed yet.
*/
if (tty->driver_data && tty->driver_data != port) {
- mutex_unlock(&port->open_lock);
+ mutex_unlock(&port->port.mutex);
sdio_uart_port_put(port);
return -EBUSY;
}
@@ -718,13 +716,13 @@ static int sdio_uart_open(struct tty_struct *tty, struct file *filp)
if (ret) {
tty->driver_data = NULL;
tty_port_tty_set(&port->port, NULL);
- mutex_unlock(&port->open_lock);
+ mutex_unlock(&port->port.mutex);
sdio_uart_port_put(port);
return ret;
}
}
port->opened++;
- mutex_unlock(&port->open_lock);
+ mutex_unlock(&port->port.mutex);
return 0;
}
@@ -735,7 +733,7 @@ static void sdio_uart_close(struct tty_struct *tty, struct file * filp)
if (!port)
return;
- mutex_lock(&port->open_lock);
+ mutex_lock(&port->port.mutex);
BUG_ON(!port->opened);
/*
@@ -744,7 +742,7 @@ static void sdio_uart_close(struct tty_struct *tty, struct file * filp)
* is larger than port->count.
*/
if (tty->count > port->opened) {
- mutex_unlock(&port->open_lock);
+ mutex_unlock(&port->port.mutex);
return;
}
@@ -756,7 +754,7 @@ static void sdio_uart_close(struct tty_struct *tty, struct file * filp)
tty->driver_data = NULL;
tty->closing = 0;
}
- mutex_unlock(&port->open_lock);
+ mutex_unlock(&port->port.mutex);
sdio_uart_port_put(port);
}
--
1.6.5.5
^ permalink raw reply related [flat|nested] 100+ messages in thread* [PATCH 30/58] tty: sdio_uart: Switch to the open/close helpers
2009-12-11 23:28 [GIT PATCH] TTY patches for 2.6.33-git Greg KH
` (28 preceding siblings ...)
2009-12-11 23:28 ` [PATCH 29/58] sdio_uart: Move the open lock Greg Kroah-Hartman
@ 2009-12-11 23:28 ` Greg Kroah-Hartman
2009-12-11 23:28 ` [PATCH 31/58] tty: sdio_uart: Fix termios handling Greg Kroah-Hartman
` (28 subsequent siblings)
58 siblings, 0 replies; 100+ messages in thread
From: Greg Kroah-Hartman @ 2009-12-11 23:28 UTC (permalink / raw)
To: linux-kernel; +Cc: Alan Cox, Greg Kroah-Hartman
From: Alan Cox <alan@linux.intel.com>
Gets us proper tty semantics, removes some code and fixes up a few corner
case races (hangup during open etc)
Signed-off-by: Alan Cox <alan@linux.intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
---
drivers/mmc/card/sdio_uart.c | 201 +++++++++++++++++++++++++-----------------
1 files changed, 119 insertions(+), 82 deletions(-)
diff --git a/drivers/mmc/card/sdio_uart.c b/drivers/mmc/card/sdio_uart.c
index 31f7023..95027b0 100644
--- a/drivers/mmc/card/sdio_uart.c
+++ b/drivers/mmc/card/sdio_uart.c
@@ -77,7 +77,6 @@ struct sdio_uart_port {
struct kref kref;
struct tty_struct *tty;
unsigned int index;
- unsigned int opened;
struct sdio_func *func;
struct mutex func_lock;
struct task_struct *in_sdio_uart_irq;
@@ -150,6 +149,7 @@ static void sdio_uart_port_put(struct sdio_uart_port *port)
static void sdio_uart_port_remove(struct sdio_uart_port *port)
{
struct sdio_func *func;
+ struct tty_struct *tty;
BUG_ON(sdio_uart_table[port->index] != port);
@@ -170,11 +170,10 @@ static void sdio_uart_port_remove(struct sdio_uart_port *port)
sdio_claim_host(func);
port->func = NULL;
mutex_unlock(&port->func_lock);
- if (port->opened) {
- struct tty_struct *tty = tty_port_tty_get(&port->port);
- /* tty_hangup is async so is this safe as is ?? */
- if (tty)
- tty_hangup(tty);
+ tty = tty_port_tty_get(&port->port);
+ /* tty_hangup is async so is this safe as is ?? */
+ if (tty) {
+ tty_hangup(tty);
tty_kref_put(tty);
}
mutex_unlock(&port->port.mutex);
@@ -560,13 +559,46 @@ static void sdio_uart_irq(struct sdio_func *func)
port->in_sdio_uart_irq = NULL;
}
-static int sdio_uart_startup(struct sdio_uart_port *port)
+/**
+ * uart_dtr_rts - port helper to set uart signals
+ * @tport: tty port to be updated
+ * @onoff: set to turn on DTR/RTS
+ *
+ * Called by the tty port helpers when the modem signals need to be
+ * adjusted during an open, close and hangup.
+ */
+
+static void uart_dtr_rts(struct tty_port *tport, int onoff)
{
- unsigned long page;
- int ret = -ENOMEM;
- struct tty_struct *tty = tty_port_tty_get(&port->port);
+ struct sdio_uart_port *port =
+ container_of(tport, struct sdio_uart_port, port);
+ if (onoff == 0)
+ sdio_uart_clear_mctrl(port, TIOCM_DTR | TIOCM_RTS);
+ else
+ sdio_uart_set_mctrl(port, TIOCM_DTR | TIOCM_RTS);
+}
- /* FIXME: What if it is NULL ?? */
+/**
+ * sdio_uart_activate - start up hardware
+ * @tport: tty port to activate
+ * @tty: tty bound to this port
+ *
+ * Activate a tty port. The port locking guarantees us this will be
+ * run exactly once per set of opens, and if successful will see the
+ * shutdown method run exactly once to match. Start up and shutdown are
+ * protected from each other by the internal locking and will not run
+ * at the same time even during a hangup event.
+ *
+ * If we successfully start up the port we take an extra kref as we
+ * will keep it around until shutdown when the kref is dropped.
+ */
+
+static int sdio_uart_activate(struct tty_port *tport, struct tty_struct *tty)
+{
+ struct sdio_uart_port *port =
+ container_of(tport, struct sdio_uart_port, port);
+ unsigned long page;
+ int ret;
/*
* Set the TTY IO error marker - we will only clear this
@@ -577,7 +609,7 @@ static int sdio_uart_startup(struct sdio_uart_port *port)
/* Initialise and allocate the transmit buffer. */
page = __get_free_page(GFP_KERNEL);
if (!page)
- goto err0;
+ return -ENOMEM;
port->xmit.buf = (unsigned char *)page;
circ_clear(&port->xmit);
@@ -631,7 +663,6 @@ static int sdio_uart_startup(struct sdio_uart_port *port)
sdio_uart_irq(port->func);
sdio_uart_release_func(port);
- tty_kref_put(tty);
return 0;
err3:
@@ -640,15 +671,25 @@ err2:
sdio_uart_release_func(port);
err1:
free_page((unsigned long)port->xmit.buf);
-err0:
- tty_kref_put(tty);
return ret;
}
-static void sdio_uart_shutdown(struct sdio_uart_port *port)
+
+/**
+ * sdio_uart_shutdown - stop hardware
+ * @tport: tty port to shut down
+ *
+ * Deactivate a tty port. The port locking guarantees us this will be
+ * run only if a successful matching activate already ran. The two are
+ * protected from each other by the internal locking and will not run
+ * at the same time even during a hangup event.
+ */
+
+static void sdio_uart_shutdown(struct tty_port *tport)
{
+ struct sdio_uart_port *port =
+ container_of(tport, struct sdio_uart_port, port);
int ret;
- struct tty_struct *tty;
ret = sdio_uart_claim_func(port);
if (ret)
@@ -656,14 +697,6 @@ static void sdio_uart_shutdown(struct sdio_uart_port *port)
sdio_uart_stop_rx(port);
- /* TODO: wait here for TX FIFO to drain */
-
- tty = tty_port_tty_get(&port->port);
- /* Turn off DTR and RTS early. */
- if (tty && (tty->termios->c_cflag & HUPCL))
- sdio_uart_clear_mctrl(port, TIOCM_DTR | TIOCM_RTS);
- tty_kref_put(tty);
-
/* Disable interrupts from this port */
sdio_release_irq(port->func);
port->ier = 0;
@@ -688,74 +721,68 @@ skip:
free_page((unsigned long)port->xmit.buf);
}
-static int sdio_uart_open(struct tty_struct *tty, struct file *filp)
-{
- struct sdio_uart_port *port;
- int ret;
-
- port = sdio_uart_port_get(tty->index);
- if (!port)
- return -ENODEV;
-
- mutex_lock(&port->port.mutex);
+/**
+ * sdio_uart_install - install method
+ * @driver: the driver in use (sdio_uart in our case)
+ * @tty: the tty being bound
+ *
+ * Look up and bind the tty and the driver together. Initialize
+ * any needed private data (in our case the termios)
+ */
- /*
- * Make sure not to mess up with a dead port
- * which has not been closed yet.
- */
- if (tty->driver_data && tty->driver_data != port) {
- mutex_unlock(&port->port.mutex);
+static int sdio_uart_install(struct tty_driver *driver, struct tty_struct *tty)
+{
+ int idx = tty->index;
+ struct sdio_uart_port *port = sdio_uart_port_get(idx);
+ int ret = tty_init_termios(tty);
+
+ if (ret == 0) {
+ tty_driver_kref_get(driver);
+ tty->count++;
+ /* This is the ref sdio_uart_port get provided */
+ tty->driver_data = port;
+ driver->ttys[idx] = tty;
+ } else
sdio_uart_port_put(port);
- return -EBUSY;
- }
+ return ret;
- if (!port->opened) {
- tty->driver_data = port;
- tty_port_tty_set(&port->port, tty);
- ret = sdio_uart_startup(port);
- if (ret) {
- tty->driver_data = NULL;
- tty_port_tty_set(&port->port, NULL);
- mutex_unlock(&port->port.mutex);
- sdio_uart_port_put(port);
- return ret;
- }
- }
- port->opened++;
- mutex_unlock(&port->port.mutex);
- return 0;
}
-static void sdio_uart_close(struct tty_struct *tty, struct file * filp)
+/**
+ * sdio_uart_cleanup - called on the last tty kref drop
+ * @tty: the tty being destroyed
+ *
+ * Called asynchronously when the last reference to the tty is dropped.
+ * We cannot destroy the tty->driver_data port kref until this point
+ */
+
+static void sdio_uart_cleanup(struct tty_struct *tty)
{
struct sdio_uart_port *port = tty->driver_data;
+ tty->driver_data = NULL; /* Bug trap */
+ sdio_uart_port_put(port);
+}
- if (!port)
- return;
+/*
+ * Open/close/hangup is now entirely boilerplate
+ */
- mutex_lock(&port->port.mutex);
- BUG_ON(!port->opened);
+static int sdio_uart_open(struct tty_struct *tty, struct file *filp)
+{
+ struct sdio_uart_port *port = tty->driver_data;
+ return tty_port_open(&port->port, tty, filp);
+}
- /*
- * This is messy. The tty layer calls us even when open()
- * returned an error. Ignore this close request if tty->count
- * is larger than port->count.
- */
- if (tty->count > port->opened) {
- mutex_unlock(&port->port.mutex);
- return;
- }
+static void sdio_uart_close(struct tty_struct *tty, struct file * filp)
+{
+ struct sdio_uart_port *port = tty->driver_data;
+ tty_port_close(&port->port, tty, filp);
+}
- if (--port->opened == 0) {
- tty->closing = 1;
- sdio_uart_shutdown(port);
- tty_ldisc_flush(tty);
- tty_port_tty_set(&port->port, NULL);
- tty->driver_data = NULL;
- tty->closing = 0;
- }
- mutex_unlock(&port->port.mutex);
- sdio_uart_port_put(port);
+static void sdio_uart_hangup(struct tty_struct *tty)
+{
+ struct sdio_uart_port *port = tty->driver_data;
+ tty_port_hangup(&port->port);
}
static int sdio_uart_write(struct tty_struct * tty, const unsigned char *buf,
@@ -1021,6 +1048,12 @@ static const struct file_operations sdio_uart_proc_fops = {
.release = single_release,
};
+static const struct tty_port_operations sdio_uart_port_ops = {
+ .dtr_rts = uart_dtr_rts,
+ .shutdown = sdio_uart_shutdown,
+ .activate = sdio_uart_activate,
+};
+
static const struct tty_operations sdio_uart_ops = {
.open = sdio_uart_open,
.close = sdio_uart_close,
@@ -1031,9 +1064,12 @@ static const struct tty_operations sdio_uart_ops = {
.throttle = sdio_uart_throttle,
.unthrottle = sdio_uart_unthrottle,
.set_termios = sdio_uart_set_termios,
+ .hangup = sdio_uart_hangup,
.break_ctl = sdio_uart_break_ctl,
.tiocmget = sdio_uart_tiocmget,
.tiocmset = sdio_uart_tiocmset,
+ .install = sdio_uart_install,
+ .cleanup = sdio_uart_cleanup,
.proc_fops = &sdio_uart_proc_fops,
};
@@ -1096,6 +1132,7 @@ static int sdio_uart_probe(struct sdio_func *func,
port->func = func;
sdio_set_drvdata(func, port);
tty_port_init(&port->port);
+ port->port.ops = &sdio_uart_port_ops;
ret = sdio_uart_add_port(port);
if (ret) {
--
1.6.5.5
^ permalink raw reply related [flat|nested] 100+ messages in thread* [PATCH 31/58] tty: sdio_uart: Fix termios handling
2009-12-11 23:28 [GIT PATCH] TTY patches for 2.6.33-git Greg KH
` (29 preceding siblings ...)
2009-12-11 23:28 ` [PATCH 30/58] tty: sdio_uart: Switch to the open/close helpers Greg Kroah-Hartman
@ 2009-12-11 23:28 ` Greg Kroah-Hartman
2009-12-11 23:28 ` [PATCH 32/58] tty: sdio_uart: Style fixes Greg Kroah-Hartman
` (27 subsequent siblings)
58 siblings, 0 replies; 100+ messages in thread
From: Greg Kroah-Hartman @ 2009-12-11 23:28 UTC (permalink / raw)
To: linux-kernel; +Cc: Alan Cox, Greg Kroah-Hartman
From: Alan Cox <alan@linux.intel.com>
Switching between two non standard baud rates fails because of the cflag
test. Do as we did elsewhere and just kill the "optimisation".
Signed-off-by: Alan Cox <alan@linux.intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
---
drivers/mmc/card/sdio_uart.c | 6 ------
1 files changed, 0 insertions(+), 6 deletions(-)
diff --git a/drivers/mmc/card/sdio_uart.c b/drivers/mmc/card/sdio_uart.c
index 95027b0..2104397 100644
--- a/drivers/mmc/card/sdio_uart.c
+++ b/drivers/mmc/card/sdio_uart.c
@@ -902,12 +902,6 @@ static void sdio_uart_set_termios(struct tty_struct *tty, struct ktermios *old_t
struct sdio_uart_port *port = tty->driver_data;
unsigned int cflag = tty->termios->c_cflag;
-#define RELEVANT_IFLAG(iflag) ((iflag) & (IGNBRK|BRKINT|IGNPAR|PARMRK|INPCK))
-
- if ((cflag ^ old_termios->c_cflag) == 0 &&
- RELEVANT_IFLAG(tty->termios->c_iflag ^ old_termios->c_iflag) == 0)
- return;
-
if (sdio_uart_claim_func(port) != 0)
return;
--
1.6.5.5
^ permalink raw reply related [flat|nested] 100+ messages in thread* [PATCH 32/58] tty: sdio_uart: Style fixes
2009-12-11 23:28 [GIT PATCH] TTY patches for 2.6.33-git Greg KH
` (30 preceding siblings ...)
2009-12-11 23:28 ` [PATCH 31/58] tty: sdio_uart: Fix termios handling Greg Kroah-Hartman
@ 2009-12-11 23:28 ` Greg Kroah-Hartman
2009-12-11 23:28 ` [PATCH 33/58] tty: sdio_uart: add modem functionality Greg Kroah-Hartman
` (26 subsequent siblings)
58 siblings, 0 replies; 100+ messages in thread
From: Greg Kroah-Hartman @ 2009-12-11 23:28 UTC (permalink / raw)
To: linux-kernel; +Cc: Alan Cox, Greg Kroah-Hartman
From: Alan Cox <alan@linux.intel.com>
Running the current code through checkpatch shows a few bits of noise
mostly but not entirely from before the changes.
Signed-off-by: Alan Cox <alan@linux.intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
---
drivers/mmc/card/sdio_uart.c | 23 ++++++++++++-----------
1 files changed, 12 insertions(+), 11 deletions(-)
diff --git a/drivers/mmc/card/sdio_uart.c b/drivers/mmc/card/sdio_uart.c
index 2104397..b999972 100644
--- a/drivers/mmc/card/sdio_uart.c
+++ b/drivers/mmc/card/sdio_uart.c
@@ -465,7 +465,8 @@ static void sdio_uart_transmit_chars(struct sdio_uart_port *port)
tty = tty_port_tty_get(&port->port);
- if (tty == NULL || circ_empty(xmit) || tty->stopped || tty->hw_stopped) {
+ if (tty == NULL || circ_empty(xmit) ||
+ tty->stopped || tty->hw_stopped) {
sdio_uart_stop_tx(port);
tty_kref_put(tty);
return;
@@ -645,7 +646,7 @@ static int sdio_uart_activate(struct tty_port *tport, struct tty_struct *tty)
*/
sdio_out(port, UART_LCR, UART_LCR_WLEN8);
- port->ier = UART_IER_RLSI | UART_IER_RDI | UART_IER_RTOIE | UART_IER_UUE;
+ port->ier = UART_IER_RLSI|UART_IER_RDI|UART_IER_RTOIE|UART_IER_UUE;
port->mctrl = TIOCM_OUT2;
sdio_uart_change_speed(port, tty->termios, NULL);
@@ -674,7 +675,6 @@ err1:
return ret;
}
-
/**
* sdio_uart_shutdown - stop hardware
* @tport: tty port to shut down
@@ -745,7 +745,6 @@ static int sdio_uart_install(struct tty_driver *driver, struct tty_struct *tty)
} else
sdio_uart_port_put(port);
return ret;
-
}
/**
@@ -785,7 +784,7 @@ static void sdio_uart_hangup(struct tty_struct *tty)
tty_port_hangup(&port->port);
}
-static int sdio_uart_write(struct tty_struct * tty, const unsigned char *buf,
+static int sdio_uart_write(struct tty_struct *tty, const unsigned char *buf,
int count)
{
struct sdio_uart_port *port = tty->driver_data;
@@ -810,7 +809,7 @@ static int sdio_uart_write(struct tty_struct * tty, const unsigned char *buf,
}
spin_unlock(&port->write_lock);
- if ( !(port->ier & UART_IER_THRI)) {
+ if (!(port->ier & UART_IER_THRI)) {
int err = sdio_uart_claim_func(port);
if (!err) {
sdio_uart_start_tx(port);
@@ -897,7 +896,8 @@ static void sdio_uart_unthrottle(struct tty_struct *tty)
sdio_uart_release_func(port);
}
-static void sdio_uart_set_termios(struct tty_struct *tty, struct ktermios *old_termios)
+static void sdio_uart_set_termios(struct tty_struct *tty,
+ struct ktermios *old_termios)
{
struct sdio_uart_port *port = tty->driver_data;
unsigned int cflag = tty->termios->c_cflag;
@@ -976,7 +976,7 @@ static int sdio_uart_tiocmset(struct tty_struct *tty, struct file *file,
int result;
result = sdio_uart_claim_func(port);
- if(!result) {
+ if (!result) {
sdio_uart_update_mctrl(port, set, clear);
sdio_uart_release_func(port);
}
@@ -994,7 +994,7 @@ static int sdio_uart_proc_show(struct seq_file *m, void *v)
struct sdio_uart_port *port = sdio_uart_port_get(i);
if (port) {
seq_printf(m, "%d: uart:SDIO", i);
- if(capable(CAP_SYS_ADMIN)) {
+ if (capable(CAP_SYS_ADMIN)) {
seq_printf(m, " tx:%d rx:%d",
port->icount.tx, port->icount.rx);
if (port->icount.frame)
@@ -1100,7 +1100,7 @@ static int sdio_uart_probe(struct sdio_func *func,
}
if (!tpl) {
printk(KERN_WARNING
- "%s: can't find tuple 0x91 subtuple 0 (SUBTPL_SIOREG) for GPS class\n",
+ "%s: can't find tuple 0x91 subtuple 0 (SUBTPL_SIOREG) for GPS class\n",
sdio_func_id(func));
kfree(port);
return -EINVAL;
@@ -1133,7 +1133,8 @@ static int sdio_uart_probe(struct sdio_func *func,
kfree(port);
} else {
struct device *dev;
- dev = tty_register_device(sdio_uart_tty_driver, port->index, &func->dev);
+ dev = tty_register_device(sdio_uart_tty_driver,
+ port->index, &func->dev);
if (IS_ERR(dev)) {
sdio_uart_port_remove(port);
ret = PTR_ERR(dev);
--
1.6.5.5
^ permalink raw reply related [flat|nested] 100+ messages in thread* [PATCH 33/58] tty: sdio_uart: add modem functionality
2009-12-11 23:28 [GIT PATCH] TTY patches for 2.6.33-git Greg KH
` (31 preceding siblings ...)
2009-12-11 23:28 ` [PATCH 32/58] tty: sdio_uart: Style fixes Greg Kroah-Hartman
@ 2009-12-11 23:28 ` Greg Kroah-Hartman
2009-12-11 23:28 ` [PATCH 34/58] tty: sdio_uart: Fix the locking on "func" for new code Greg Kroah-Hartman
` (25 subsequent siblings)
58 siblings, 0 replies; 100+ messages in thread
From: Greg Kroah-Hartman @ 2009-12-11 23:28 UTC (permalink / raw)
To: linux-kernel; +Cc: Alan Cox, Greg Kroah-Hartman
From: Alan Cox <alan@linux.intel.com>
Add the POSIX block for carrier
Linux TIOCMIWAIT functionality is still lacking from the driver.
Signed-off-by: Alan Cox <alan@linux.intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
---
drivers/mmc/card/sdio_uart.c | 33 ++++++++++++++++++++++++++++++++-
1 files changed, 32 insertions(+), 1 deletions(-)
diff --git a/drivers/mmc/card/sdio_uart.c b/drivers/mmc/card/sdio_uart.c
index b999972..2a13db5 100644
--- a/drivers/mmc/card/sdio_uart.c
+++ b/drivers/mmc/card/sdio_uart.c
@@ -29,6 +29,7 @@
#include <linux/module.h>
#include <linux/init.h>
#include <linux/kernel.h>
+#include <linux/sched.h>
#include <linux/mutex.h>
#include <linux/seq_file.h>
#include <linux/serial_reg.h>
@@ -86,6 +87,7 @@ struct sdio_uart_port {
struct uart_icount icount;
unsigned int uartclk;
unsigned int mctrl;
+ unsigned int rx_mctrl;
unsigned int read_status_mask;
unsigned int ignore_status_mask;
unsigned char x_char;
@@ -220,6 +222,8 @@ static unsigned int sdio_uart_get_mctrl(struct sdio_uart_port *port)
unsigned char status;
unsigned int ret;
+ /* FIXME: What stops this losing the delta bits and breaking
+ sdio_uart_check_modem_status ? */
status = sdio_in(port, UART_MSR);
ret = 0;
@@ -503,8 +507,20 @@ static void sdio_uart_check_modem_status(struct sdio_uart_port *port)
port->icount.rng++;
if (status & UART_MSR_DDSR)
port->icount.dsr++;
- if (status & UART_MSR_DDCD)
+ if (status & UART_MSR_DDCD) {
port->icount.dcd++;
+ /* DCD raise - wake for open */
+ if (status & UART_MSR_DCD)
+ wake_up_interruptible(&port->port.open_wait);
+ else {
+ /* DCD drop - hang up if tty attached */
+ tty = tty_port_tty_get(&port->port);
+ if (tty) {
+ tty_hangup(tty);
+ tty_kref_put(tty);
+ }
+ }
+ }
if (status & UART_MSR_DCTS) {
port->icount.cts++;
tty = tty_port_tty_get(&port->port);
@@ -560,6 +576,20 @@ static void sdio_uart_irq(struct sdio_func *func)
port->in_sdio_uart_irq = NULL;
}
+static int uart_carrier_raised(struct tty_port *tport)
+{
+ struct sdio_uart_port *port =
+ container_of(tport, struct sdio_uart_port, port);
+ unsigned int ret = sdio_uart_claim_func(port);
+ if (ret) /* Missing hardware shoudn't block for carrier */
+ return 1;
+ ret = sdio_uart_get_mctrl(port);
+ sdio_uart_release_func(port);
+ if (ret & TIOCM_CAR)
+ return 1;
+ return 0;
+}
+
/**
* uart_dtr_rts - port helper to set uart signals
* @tport: tty port to be updated
@@ -1044,6 +1074,7 @@ static const struct file_operations sdio_uart_proc_fops = {
static const struct tty_port_operations sdio_uart_port_ops = {
.dtr_rts = uart_dtr_rts,
+ .carrier_raised = uart_carrier_raised,
.shutdown = sdio_uart_shutdown,
.activate = sdio_uart_activate,
};
--
1.6.5.5
^ permalink raw reply related [flat|nested] 100+ messages in thread* [PATCH 34/58] tty: sdio_uart: Fix the locking on "func" for new code
2009-12-11 23:28 [GIT PATCH] TTY patches for 2.6.33-git Greg KH
` (32 preceding siblings ...)
2009-12-11 23:28 ` [PATCH 33/58] tty: sdio_uart: add modem functionality Greg Kroah-Hartman
@ 2009-12-11 23:28 ` Greg Kroah-Hartman
2009-12-11 23:28 ` [PATCH 35/58] tty: tty_port: Change the buffer allocator locking Greg Kroah-Hartman
` (24 subsequent siblings)
58 siblings, 0 replies; 100+ messages in thread
From: Greg Kroah-Hartman @ 2009-12-11 23:28 UTC (permalink / raw)
To: linux-kernel; +Cc: Alan Cox, Greg Kroah-Hartman
From: Alan Cox <alan@linux.intel.com>
The new dtr_rts function didn't take the port->func lock as it should
so add use of the lock there.
Signed-off-by: Alan Cox <alan@linux.intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
---
drivers/mmc/card/sdio_uart.c | 4 ++++
1 files changed, 4 insertions(+), 0 deletions(-)
diff --git a/drivers/mmc/card/sdio_uart.c b/drivers/mmc/card/sdio_uart.c
index 2a13db5..f537555 100644
--- a/drivers/mmc/card/sdio_uart.c
+++ b/drivers/mmc/card/sdio_uart.c
@@ -603,10 +603,14 @@ static void uart_dtr_rts(struct tty_port *tport, int onoff)
{
struct sdio_uart_port *port =
container_of(tport, struct sdio_uart_port, port);
+ int ret = sdio_uart_claim_func(port);
+ if (ret)
+ return;
if (onoff == 0)
sdio_uart_clear_mctrl(port, TIOCM_DTR | TIOCM_RTS);
else
sdio_uart_set_mctrl(port, TIOCM_DTR | TIOCM_RTS);
+ sdio_uart_release_func(port);
}
/**
--
1.6.5.5
^ permalink raw reply related [flat|nested] 100+ messages in thread* [PATCH 35/58] tty: tty_port: Change the buffer allocator locking
2009-12-11 23:28 [GIT PATCH] TTY patches for 2.6.33-git Greg KH
` (33 preceding siblings ...)
2009-12-11 23:28 ` [PATCH 34/58] tty: sdio_uart: Fix the locking on "func" for new code Greg Kroah-Hartman
@ 2009-12-11 23:28 ` Greg Kroah-Hartman
2009-12-11 23:28 ` [PATCH 36/58] tty: riscom8: switch to the tty_port_open API Greg Kroah-Hartman
` (23 subsequent siblings)
58 siblings, 0 replies; 100+ messages in thread
From: Greg Kroah-Hartman @ 2009-12-11 23:28 UTC (permalink / raw)
To: linux-kernel; +Cc: Alan Cox, Greg Kroah-Hartman
From: Alan Cox <alan@linux.intel.com>
We want to be able to do this without regard for the activate/own open
method being used which causes a problem using port->mutex. Add another
mutex for now. Once everything uses port_open to do buffer allocs we can
kill it back off
Signed-off-by: Alan Cox <alan@linux.intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
---
drivers/char/tty_port.c | 9 +++++----
include/linux/tty.h | 1 +
2 files changed, 6 insertions(+), 4 deletions(-)
diff --git a/drivers/char/tty_port.c b/drivers/char/tty_port.c
index dd471d6..3ef644a 100644
--- a/drivers/char/tty_port.c
+++ b/drivers/char/tty_port.c
@@ -25,6 +25,7 @@ void tty_port_init(struct tty_port *port)
init_waitqueue_head(&port->close_wait);
init_waitqueue_head(&port->delta_msr_wait);
mutex_init(&port->mutex);
+ mutex_init(&port->buf_mutex);
spin_lock_init(&port->lock);
port->close_delay = (50 * HZ) / 100;
port->closing_wait = (3000 * HZ) / 100;
@@ -34,10 +35,10 @@ EXPORT_SYMBOL(tty_port_init);
int tty_port_alloc_xmit_buf(struct tty_port *port)
{
/* We may sleep in get_zeroed_page() */
- mutex_lock(&port->mutex);
+ mutex_lock(&port->buf_mutex);
if (port->xmit_buf == NULL)
port->xmit_buf = (unsigned char *)get_zeroed_page(GFP_KERNEL);
- mutex_unlock(&port->mutex);
+ mutex_unlock(&port->buf_mutex);
if (port->xmit_buf == NULL)
return -ENOMEM;
return 0;
@@ -46,12 +47,12 @@ EXPORT_SYMBOL(tty_port_alloc_xmit_buf);
void tty_port_free_xmit_buf(struct tty_port *port)
{
- mutex_lock(&port->mutex);
+ mutex_lock(&port->buf_mutex);
if (port->xmit_buf != NULL) {
free_page((unsigned long)port->xmit_buf);
port->xmit_buf = NULL;
}
- mutex_unlock(&port->mutex);
+ mutex_unlock(&port->buf_mutex);
}
EXPORT_SYMBOL(tty_port_free_xmit_buf);
diff --git a/include/linux/tty.h b/include/linux/tty.h
index 6352ac2..e9269ca 100644
--- a/include/linux/tty.h
+++ b/include/linux/tty.h
@@ -212,6 +212,7 @@ struct tty_port {
wait_queue_head_t delta_msr_wait; /* Modem status change */
unsigned long flags; /* TTY flags ASY_*/
struct mutex mutex; /* Locking */
+ struct mutex buf_mutex; /* Buffer alloc lock */
unsigned char *xmit_buf; /* Optional buffer */
unsigned int close_delay; /* Close port delay */
unsigned int closing_wait; /* Delay for output */
--
1.6.5.5
^ permalink raw reply related [flat|nested] 100+ messages in thread* [PATCH 36/58] tty: riscom8: switch to the tty_port_open API
2009-12-11 23:28 [GIT PATCH] TTY patches for 2.6.33-git Greg KH
` (34 preceding siblings ...)
2009-12-11 23:28 ` [PATCH 35/58] tty: tty_port: Change the buffer allocator locking Greg Kroah-Hartman
@ 2009-12-11 23:28 ` Greg Kroah-Hartman
2009-12-11 23:28 ` [PATCH 37/58] tty: tty_port: Add IO_ERROR bit handling Greg Kroah-Hartman
` (22 subsequent siblings)
58 siblings, 0 replies; 100+ messages in thread
From: Greg Kroah-Hartman @ 2009-12-11 23:28 UTC (permalink / raw)
To: linux-kernel; +Cc: Alan Cox, Greg Kroah-Hartman
From: Alan Cox <alan@linux.intel.com>
Signed-off-by: Alan Cox <alan@linux.intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
---
drivers/char/riscom8.c | 89 ++++++++++++++++++++++--------------------------
1 files changed, 41 insertions(+), 48 deletions(-)
diff --git a/drivers/char/riscom8.c b/drivers/char/riscom8.c
index 3cfa22d..0a8d1e5 100644
--- a/drivers/char/riscom8.c
+++ b/drivers/char/riscom8.c
@@ -793,26 +793,21 @@ static void rc_change_speed(struct tty_struct *tty, struct riscom_board *bp,
}
/* Must be called with interrupts enabled */
-static int rc_setup_port(struct tty_struct *tty, struct riscom_board *bp,
- struct riscom_port *port)
+static int rc_activate_port(struct tty_port *port, struct tty_struct *tty)
{
+ struct riscom_port *rp = container_of(port, struct riscom_port, port);
+ struct riscom_board *bp = port_Board(rp);
unsigned long flags;
- if (port->port.flags & ASYNC_INITIALIZED)
- return 0;
-
- if (tty_port_alloc_xmit_buf(&port->port) < 0)
+ if (tty_port_alloc_xmit_buf(port) < 0)
return -ENOMEM;
spin_lock_irqsave(&riscom_lock, flags);
clear_bit(TTY_IO_ERROR, &tty->flags);
- if (port->port.count == 1)
- bp->count++;
- port->xmit_cnt = port->xmit_head = port->xmit_tail = 0;
- rc_change_speed(tty, bp, port);
- port->port.flags |= ASYNC_INITIALIZED;
-
+ bp->count++;
+ rp->xmit_cnt = rp->xmit_head = rp->xmit_tail = 0;
+ rc_change_speed(tty, bp, rp);
spin_unlock_irqrestore(&riscom_lock, flags);
return 0;
}
@@ -821,9 +816,6 @@ static int rc_setup_port(struct tty_struct *tty, struct riscom_board *bp,
static void rc_shutdown_port(struct tty_struct *tty,
struct riscom_board *bp, struct riscom_port *port)
{
- if (!(port->port.flags & ASYNC_INITIALIZED))
- return;
-
#ifdef RC_REPORT_OVERRUN
printk(KERN_INFO "rc%d: port %d: Total %ld overruns were detected.\n",
board_No(bp), port_No(port), port->overrun);
@@ -840,11 +832,6 @@ static void rc_shutdown_port(struct tty_struct *tty,
}
#endif
tty_port_free_xmit_buf(&port->port);
- if (C_HUPCL(tty)) {
- /* Drop DTR */
- bp->DTR |= (1u << port_No(port));
- rc_out(bp, RC_DTR, bp->DTR);
- }
/* Select port */
rc_out(bp, CD180_CAR, port_No(port));
@@ -856,7 +843,6 @@ static void rc_shutdown_port(struct tty_struct *tty,
rc_out(bp, CD180_IER, port->IER);
set_bit(TTY_IO_ERROR, &tty->flags);
- port->port.flags &= ~ASYNC_INITIALIZED;
if (--bp->count < 0) {
printk(KERN_INFO "rc%d: rc_shutdown_port: "
@@ -889,6 +875,20 @@ static int carrier_raised(struct tty_port *port)
return CD;
}
+static void dtr_rts(struct tty_port *port, int onoff)
+{
+ struct riscom_port *p = container_of(port, struct riscom_port, port);
+ struct riscom_board *bp = port_Board(p);
+ unsigned long flags;
+
+ spin_lock_irqsave(&riscom_lock, flags);
+ bp->DTR &= ~(1u << port_No(p));
+ if (onoff == 0)
+ bp->DTR |= (1u << port_No(p));
+ rc_out(bp, RC_DTR, bp->DTR);
+ spin_unlock_irqrestore(&riscom_lock, flags);
+}
+
static int rc_open(struct tty_struct *tty, struct file *filp)
{
int board;
@@ -909,14 +909,7 @@ static int rc_open(struct tty_struct *tty, struct file *filp)
if (error)
return error;
- port->port.count++;
- tty->driver_data = port;
- tty_port_tty_set(&port->port, tty);
-
- error = rc_setup_port(tty, bp, port);
- if (error == 0)
- error = tty_port_block_til_ready(&port->port, tty, filp);
- return error;
+ return tty_port_open(&port->port, tty, filp);
}
static void rc_flush_buffer(struct tty_struct *tty)
@@ -950,24 +943,23 @@ static void rc_close_port(struct tty_port *port)
spin_lock_irqsave(&riscom_lock, flags);
rp->IER &= ~IER_RXD;
- if (port->flags & ASYNC_INITIALIZED) {
- rp->IER &= ~IER_TXRDY;
- rp->IER |= IER_TXEMPTY;
- rc_out(bp, CD180_CAR, port_No(rp));
- rc_out(bp, CD180_IER, rp->IER);
- /*
- * Before we drop DTR, make sure the UART transmitter
- * has completely drained; this is especially
- * important if there is a transmit FIFO!
- */
- timeout = jiffies + HZ;
- while (rp->IER & IER_TXEMPTY) {
- spin_unlock_irqrestore(&riscom_lock, flags);
- msleep_interruptible(jiffies_to_msecs(rp->timeout));
- spin_lock_irqsave(&riscom_lock, flags);
- if (time_after(jiffies, timeout))
- break;
- }
+
+ rp->IER &= ~IER_TXRDY;
+ rp->IER |= IER_TXEMPTY;
+ rc_out(bp, CD180_CAR, port_No(rp));
+ rc_out(bp, CD180_IER, rp->IER);
+ /*
+ * Before we drop DTR, make sure the UART transmitter
+ * has completely drained; this is especially
+ * important if there is a transmit FIFO!
+ */
+ timeout = jiffies + HZ;
+ while (rp->IER & IER_TXEMPTY) {
+ spin_unlock_irqrestore(&riscom_lock, flags);
+ msleep_interruptible(jiffies_to_msecs(rp->timeout));
+ spin_lock_irqsave(&riscom_lock, flags);
+ if (time_after(jiffies, timeout))
+ break;
}
rc_shutdown_port(port->tty, bp, rp);
spin_unlock_irqrestore(&riscom_lock, flags);
@@ -1354,7 +1346,6 @@ static void rc_hangup(struct tty_struct *tty)
if (rc_paranoia_check(port, tty->name, "rc_hangup"))
return;
- rc_shutdown_port(tty, port_Board(port), port);
tty_port_hangup(&port->port);
}
@@ -1401,7 +1392,9 @@ static const struct tty_operations riscom_ops = {
static const struct tty_port_operations riscom_port_ops = {
.carrier_raised = carrier_raised,
+ .dtr_rts = dtr_rts,
.shutdown = rc_close_port,
+ .activate = rc_activate_port,
};
--
1.6.5.5
^ permalink raw reply related [flat|nested] 100+ messages in thread* [PATCH 37/58] tty: tty_port: Add IO_ERROR bit handling
2009-12-11 23:28 [GIT PATCH] TTY patches for 2.6.33-git Greg KH
` (35 preceding siblings ...)
2009-12-11 23:28 ` [PATCH 36/58] tty: riscom8: switch to the tty_port_open API Greg Kroah-Hartman
@ 2009-12-11 23:28 ` Greg Kroah-Hartman
2009-12-11 23:28 ` [PATCH 38/58] tty: tty_port: Move the IO_ERROR clear Greg Kroah-Hartman
` (21 subsequent siblings)
58 siblings, 0 replies; 100+ messages in thread
From: Greg Kroah-Hartman @ 2009-12-11 23:28 UTC (permalink / raw)
To: linux-kernel; +Cc: Alan Cox, Greg Kroah-Hartman
From: Alan Cox <alan@linux.intel.com>
To propogate tty_port_open/close to a few other devices we need to start
handling the IO_ERROR flag on the tty. We can do this pretty trivially.
Signed-off-by: Alan Cox <alan@linux.intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
---
drivers/char/tty_port.c | 6 +++++-
1 files changed, 5 insertions(+), 1 deletions(-)
diff --git a/drivers/char/tty_port.c b/drivers/char/tty_port.c
index 3ef644a..43a1907 100644
--- a/drivers/char/tty_port.c
+++ b/drivers/char/tty_port.c
@@ -122,8 +122,10 @@ void tty_port_hangup(struct tty_port *port)
spin_lock_irqsave(&port->lock, flags);
port->count = 0;
port->flags &= ~ASYNC_NORMAL_ACTIVE;
- if (port->tty)
+ if (port->tty) {
+ set_bit(TTY_IO_ERROR, &port->tty->flags);
tty_kref_put(port->tty);
+ }
port->tty = NULL;
spin_unlock_irqrestore(&port->lock, flags);
wake_up_interruptible(&port->open_wait);
@@ -383,6 +385,7 @@ void tty_port_close(struct tty_port *port, struct tty_struct *tty,
if (tty_port_close_start(port, tty, filp) == 0)
return;
tty_port_shutdown(port);
+ set_bit(TTY_IO_ERROR, &tty->flags);
tty_port_close_end(port, tty);
tty_port_tty_set(port, NULL);
}
@@ -414,6 +417,7 @@ int tty_port_open(struct tty_port *port, struct tty_struct *tty,
}
}
set_bit(ASYNCB_INITIALIZED, &port->flags);
+ clear_bit(TTY_IO_ERROR, &tty->flags);
}
mutex_unlock(&port->mutex);
return tty_port_block_til_ready(port, tty, filp);
--
1.6.5.5
^ permalink raw reply related [flat|nested] 100+ messages in thread* [PATCH 38/58] tty: tty_port: Move the IO_ERROR clear
2009-12-11 23:28 [GIT PATCH] TTY patches for 2.6.33-git Greg KH
` (36 preceding siblings ...)
2009-12-11 23:28 ` [PATCH 37/58] tty: tty_port: Add IO_ERROR bit handling Greg Kroah-Hartman
@ 2009-12-11 23:28 ` Greg Kroah-Hartman
2009-12-11 23:28 ` [PATCH 39/58] tty: stallion: Convert to the tty_port_open/close methods Greg Kroah-Hartman
` (20 subsequent siblings)
58 siblings, 0 replies; 100+ messages in thread
From: Greg Kroah-Hartman @ 2009-12-11 23:28 UTC (permalink / raw)
To: linux-kernel; +Cc: Alan Cox, Greg Kroah-Hartman
From: Alan Cox <alan@linux.intel.com>
Some devices want to set IO_ERROR in their activate methods so that you can
be handed a 'dead' port for operations like setserial. Thus we need to
clear the flag before activate so that activate can choose to set the flag
and still return 0.
This is fine as the file handle/tty are not accessible to the user yet.
Signed-off-by: Alan Cox <alan@linux.intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
---
drivers/char/tty_port.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/drivers/char/tty_port.c b/drivers/char/tty_port.c
index 43a1907..84006de 100644
--- a/drivers/char/tty_port.c
+++ b/drivers/char/tty_port.c
@@ -409,6 +409,7 @@ int tty_port_open(struct tty_port *port, struct tty_struct *tty,
mutex_lock(&port->mutex);
if (!test_bit(ASYNCB_INITIALIZED, &port->flags)) {
+ clear_bit(TTY_IO_ERROR, &tty->flags);
if (port->ops->activate) {
int retval = port->ops->activate(port, tty);
if (retval) {
@@ -417,7 +418,6 @@ int tty_port_open(struct tty_port *port, struct tty_struct *tty,
}
}
set_bit(ASYNCB_INITIALIZED, &port->flags);
- clear_bit(TTY_IO_ERROR, &tty->flags);
}
mutex_unlock(&port->mutex);
return tty_port_block_til_ready(port, tty, filp);
--
1.6.5.5
^ permalink raw reply related [flat|nested] 100+ messages in thread* [PATCH 39/58] tty: stallion: Convert to the tty_port_open/close methods
2009-12-11 23:28 [GIT PATCH] TTY patches for 2.6.33-git Greg KH
` (37 preceding siblings ...)
2009-12-11 23:28 ` [PATCH 38/58] tty: tty_port: Move the IO_ERROR clear Greg Kroah-Hartman
@ 2009-12-11 23:28 ` Greg Kroah-Hartman
2009-12-11 23:28 ` [PATCH 40/58] tty: istallion: tty port open/close methods Greg Kroah-Hartman
` (19 subsequent siblings)
58 siblings, 0 replies; 100+ messages in thread
From: Greg Kroah-Hartman @ 2009-12-11 23:28 UTC (permalink / raw)
To: linux-kernel; +Cc: Alan Cox, Greg Kroah-Hartman
From: Alan Cox <alan@linux.intel.com>
The driver is already structured this way so just slice and dice
Signed-off-by: Alan Cox <alan@linux.intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
---
drivers/char/stallion.c | 116 ++++++++++++++---------------------------------
1 files changed, 35 insertions(+), 81 deletions(-)
diff --git a/drivers/char/stallion.c b/drivers/char/stallion.c
index b4ba5ed..0e511d6 100644
--- a/drivers/char/stallion.c
+++ b/drivers/char/stallion.c
@@ -702,6 +702,24 @@ static struct stlbrd *stl_allocbrd(void)
/*****************************************************************************/
+static int stl_activate(struct tty_port *port, struct tty_struct *tty)
+{
+ struct stlport *portp = container_of(port, struct stlport, port);
+ if (!portp->tx.buf) {
+ portp->tx.buf = kmalloc(STL_TXBUFSIZE, GFP_KERNEL);
+ if (!portp->tx.buf)
+ return -ENOMEM;
+ portp->tx.head = portp->tx.buf;
+ portp->tx.tail = portp->tx.buf;
+ }
+ stl_setport(portp, tty->termios);
+ portp->sigs = stl_getsignals(portp);
+ stl_setsignals(portp, 1, 1);
+ stl_enablerxtx(portp, 1, 1);
+ stl_startrxtx(portp, 1, 0);
+ return 0;
+}
+
static int stl_open(struct tty_struct *tty, struct file *filp)
{
struct stlport *portp;
@@ -737,32 +755,8 @@ static int stl_open(struct tty_struct *tty, struct file *filp)
if (portp == NULL)
return -ENODEV;
port = &portp->port;
+ return tty_port_open(&portp->port, tty, filp);
-/*
- * On the first open of the device setup the port hardware, and
- * initialize the per port data structure.
- */
- tty_port_tty_set(port, tty);
- tty->driver_data = portp;
- port->count++;
-
- if ((port->flags & ASYNC_INITIALIZED) == 0) {
- if (!portp->tx.buf) {
- portp->tx.buf = kmalloc(STL_TXBUFSIZE, GFP_KERNEL);
- if (!portp->tx.buf)
- return -ENOMEM;
- portp->tx.head = portp->tx.buf;
- portp->tx.tail = portp->tx.buf;
- }
- stl_setport(portp, tty->termios);
- portp->sigs = stl_getsignals(portp);
- stl_setsignals(portp, 1, 1);
- stl_enablerxtx(portp, 1, 1);
- stl_startrxtx(portp, 1, 0);
- clear_bit(TTY_IO_ERROR, &tty->flags);
- port->flags |= ASYNC_INITIALIZED;
- }
- return tty_port_block_til_ready(port, tty, filp);
}
/*****************************************************************************/
@@ -826,38 +820,12 @@ static void stl_waituntilsent(struct tty_struct *tty, int timeout)
/*****************************************************************************/
-static void stl_close(struct tty_struct *tty, struct file *filp)
+static void stl_shutdown(struct tty_port *port)
{
- struct stlport *portp;
- struct tty_port *port;
- unsigned long flags;
-
- pr_debug("stl_close(tty=%p,filp=%p)\n", tty, filp);
-
- portp = tty->driver_data;
- BUG_ON(portp == NULL);
-
- port = &portp->port;
-
- if (tty_port_close_start(port, tty, filp) == 0)
- return;
-/*
- * May want to wait for any data to drain before closing. The BUSY
- * flag keeps track of whether we are still sending or not - it is
- * very accurate for the cd1400, not quite so for the sc26198.
- * (The sc26198 has no "end-of-data" interrupt only empty FIFO)
- */
- stl_waituntilsent(tty, (HZ / 2));
-
- spin_lock_irqsave(&port->lock, flags);
- portp->port.flags &= ~ASYNC_INITIALIZED;
- spin_unlock_irqrestore(&port->lock, flags);
-
+ struct stlport *portp = container_of(port, struct stlport, port);
stl_disableintrs(portp);
- if (tty->termios->c_cflag & HUPCL)
- stl_setsignals(portp, 0, 0);
stl_enablerxtx(portp, 0, 0);
- stl_flushbuffer(tty);
+ stl_flush(portp);
portp->istate = 0;
if (portp->tx.buf != NULL) {
kfree(portp->tx.buf);
@@ -865,9 +833,16 @@ static void stl_close(struct tty_struct *tty, struct file *filp)
portp->tx.head = NULL;
portp->tx.tail = NULL;
}
+}
+
+static void stl_close(struct tty_struct *tty, struct file *filp)
+{
+ struct stlport*portp;
+ pr_debug("stl_close(tty=%p,filp=%p)\n", tty, filp);
- tty_port_close_end(port, tty);
- tty_port_tty_set(port, NULL);
+ portp = tty->driver_data;
+ BUG_ON(portp == NULL);
+ tty_port_close(&portp->port, tty, filp);
}
/*****************************************************************************/
@@ -1314,35 +1289,12 @@ static void stl_stop(struct tty_struct *tty)
static void stl_hangup(struct tty_struct *tty)
{
- struct stlport *portp;
- struct tty_port *port;
- unsigned long flags;
-
+ struct stlport *portp = tty->driver_data;
pr_debug("stl_hangup(tty=%p)\n", tty);
- portp = tty->driver_data;
if (portp == NULL)
return;
- port = &portp->port;
-
- spin_lock_irqsave(&port->lock, flags);
- port->flags &= ~ASYNC_INITIALIZED;
- spin_unlock_irqrestore(&port->lock, flags);
-
- stl_disableintrs(portp);
- if (tty->termios->c_cflag & HUPCL)
- stl_setsignals(portp, 0, 0);
- stl_enablerxtx(portp, 0, 0);
- stl_flushbuffer(tty);
- portp->istate = 0;
- set_bit(TTY_IO_ERROR, &tty->flags);
- if (portp->tx.buf != NULL) {
- kfree(portp->tx.buf);
- portp->tx.buf = NULL;
- portp->tx.head = NULL;
- portp->tx.tail = NULL;
- }
- tty_port_hangup(port);
+ tty_port_hangup(&portp->port);
}
/*****************************************************************************/
@@ -2550,6 +2502,8 @@ static const struct tty_operations stl_ops = {
static const struct tty_port_operations stl_port_ops = {
.carrier_raised = stl_carrier_raised,
.dtr_rts = stl_dtr_rts,
+ .activate = stl_activate,
+ .shutdown = stl_shutdown,
};
/*****************************************************************************/
--
1.6.5.5
^ permalink raw reply related [flat|nested] 100+ messages in thread* [PATCH 40/58] tty: istallion: tty port open/close methods
2009-12-11 23:28 [GIT PATCH] TTY patches for 2.6.33-git Greg KH
` (38 preceding siblings ...)
2009-12-11 23:28 ` [PATCH 39/58] tty: stallion: Convert to the tty_port_open/close methods Greg Kroah-Hartman
@ 2009-12-11 23:28 ` Greg Kroah-Hartman
2009-12-11 23:28 ` [PATCH 41/58] tty: tty_port: Add a kref object to the tty port Greg Kroah-Hartman
` (18 subsequent siblings)
58 siblings, 0 replies; 100+ messages in thread
From: Greg Kroah-Hartman @ 2009-12-11 23:28 UTC (permalink / raw)
To: linux-kernel; +Cc: Alan Cox, Greg Kroah-Hartman
From: Alan Cox <alan@linux.intel.com>
Slice/dice/repeat as with the stallion driver this is just code shuffling
and removal
Signed-off-by: Alan Cox <alan@linux.intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
---
drivers/char/istallion.c | 177 ++++++++++++++++------------------------------
1 files changed, 60 insertions(+), 117 deletions(-)
diff --git a/drivers/char/istallion.c b/drivers/char/istallion.c
index babfd44..4cd6c52 100644
--- a/drivers/char/istallion.c
+++ b/drivers/char/istallion.c
@@ -213,7 +213,6 @@ static int stli_shared;
* with the slave. Most of them need to be updated atomically, so always
* use the bit setting operations (unless protected by cli/sti).
*/
-#define ST_INITIALIZING 1
#define ST_OPENING 2
#define ST_CLOSING 3
#define ST_CMDING 4
@@ -783,13 +782,32 @@ static int stli_parsebrd(struct stlconf *confp, char **argp)
/*****************************************************************************/
+/*
+ * On the first open of the device setup the port hardware, and
+ * initialize the per port data structure. Since initializing the port
+ * requires several commands to the board we will need to wait for any
+ * other open that is already initializing the port.
+ *
+ * Locking: protected by the port mutex.
+ */
+
+static int stli_activate(struct tty_port *port, struct tty_struct *tty)
+{
+ struct stliport *portp = container_of(port, struct stliport, port);
+ struct stlibrd *brdp = stli_brds[portp->brdnr];
+ int rc;
+
+ if ((rc = stli_initopen(tty, brdp, portp)) >= 0)
+ clear_bit(TTY_IO_ERROR, &tty->flags);
+ wake_up_interruptible(&portp->raw_wait);
+ return rc;
+}
+
static int stli_open(struct tty_struct *tty, struct file *filp)
{
struct stlibrd *brdp;
struct stliport *portp;
- struct tty_port *port;
unsigned int minordev, brdnr, portnr;
- int rc;
minordev = tty->index;
brdnr = MINOR2BRD(minordev);
@@ -809,95 +827,56 @@ static int stli_open(struct tty_struct *tty, struct file *filp)
return -ENODEV;
if (portp->devnr < 1)
return -ENODEV;
- port = &portp->port;
-
-/*
- * On the first open of the device setup the port hardware, and
- * initialize the per port data structure. Since initializing the port
- * requires several commands to the board we will need to wait for any
- * other open that is already initializing the port.
- *
- * Review - locking
- */
- tty_port_tty_set(port, tty);
- tty->driver_data = portp;
- port->count++;
-
- wait_event_interruptible(portp->raw_wait,
- !test_bit(ST_INITIALIZING, &portp->state));
- if (signal_pending(current))
- return -ERESTARTSYS;
-
- if ((portp->port.flags & ASYNC_INITIALIZED) == 0) {
- set_bit(ST_INITIALIZING, &portp->state);
- if ((rc = stli_initopen(tty, brdp, portp)) >= 0) {
- /* Locking */
- port->flags |= ASYNC_INITIALIZED;
- clear_bit(TTY_IO_ERROR, &tty->flags);
- }
- clear_bit(ST_INITIALIZING, &portp->state);
- wake_up_interruptible(&portp->raw_wait);
- if (rc < 0)
- return rc;
- }
- return tty_port_block_til_ready(&portp->port, tty, filp);
+ return tty_port_open(&portp->port, tty, filp);
}
+
/*****************************************************************************/
-static void stli_close(struct tty_struct *tty, struct file *filp)
+static void stli_shutdown(struct tty_port *port)
{
struct stlibrd *brdp;
- struct stliport *portp;
- struct tty_port *port;
+ unsigned long ftype;
unsigned long flags;
+ struct stliport *portp = container_of(port, struct stliport, port);
- portp = tty->driver_data;
- if (portp == NULL)
+ if (portp->brdnr >= stli_nrbrds)
return;
- port = &portp->port;
-
- if (tty_port_close_start(port, tty, filp) == 0)
+ brdp = stli_brds[portp->brdnr];
+ if (brdp == NULL)
return;
-/*
- * May want to wait for data to drain before closing. The BUSY flag
- * keeps track of whether we are still transmitting or not. It is
- * updated by messages from the slave - indicating when all chars
- * really have drained.
- */
- spin_lock_irqsave(&stli_lock, flags);
- if (tty == stli_txcooktty)
- stli_flushchars(tty);
- spin_unlock_irqrestore(&stli_lock, flags);
-
- /* We end up doing this twice for the moment. This needs looking at
- eventually. Note we still use portp->closing_wait as a result */
- if (portp->closing_wait != ASYNC_CLOSING_WAIT_NONE)
- tty_wait_until_sent(tty, portp->closing_wait);
+ /*
+ * May want to wait for data to drain before closing. The BUSY
+ * flag keeps track of whether we are still transmitting or not.
+ * It is updated by messages from the slave - indicating when all
+ * chars really have drained.
+ */
- /* FIXME: port locking here needs attending to */
- port->flags &= ~ASYNC_INITIALIZED;
+ if (!test_bit(ST_CLOSING, &portp->state))
+ stli_rawclose(brdp, portp, 0, 0);
- brdp = stli_brds[portp->brdnr];
- stli_rawclose(brdp, portp, 0, 0);
- if (tty->termios->c_cflag & HUPCL) {
- stli_mkasysigs(&portp->asig, 0, 0);
- if (test_bit(ST_CMDING, &portp->state))
- set_bit(ST_DOSIGS, &portp->state);
- else
- stli_sendcmd(brdp, portp, A_SETSIGNALS, &portp->asig,
- sizeof(asysigs_t), 0);
- }
+ spin_lock_irqsave(&stli_lock, flags);
clear_bit(ST_TXBUSY, &portp->state);
clear_bit(ST_RXSTOP, &portp->state);
- set_bit(TTY_IO_ERROR, &tty->flags);
- tty_ldisc_flush(tty);
- set_bit(ST_DOFLUSHRX, &portp->state);
- stli_flushbuffer(tty);
+ spin_unlock_irqrestore(&stli_lock, flags);
- tty_port_close_end(port, tty);
- tty_port_tty_set(port, NULL);
+ ftype = FLUSHTX | FLUSHRX;
+ stli_cmdwait(brdp, portp, A_FLUSH, &ftype, sizeof(u32), 0);
+}
+
+static void stli_close(struct tty_struct *tty, struct file *filp)
+{
+ struct stliport *portp = tty->driver_data;
+ unsigned long flags;
+ if (portp == NULL)
+ return;
+ spin_lock_irqsave(&stli_lock, flags);
+ /* Flush any internal buffering out first */
+ if (tty == stli_txcooktty)
+ stli_flushchars(tty);
+ spin_unlock_irqrestore(&stli_lock, flags);
+ tty_port_close(&portp->port, tty, filp);
}
/*****************************************************************************/
@@ -1724,6 +1703,7 @@ static void stli_start(struct tty_struct *tty)
/*****************************************************************************/
+
/*
* Hangup this port. This is pretty much like closing the port, only
* a little more brutal. No waiting for data to drain. Shutdown the
@@ -1733,47 +1713,8 @@ static void stli_start(struct tty_struct *tty)
static void stli_hangup(struct tty_struct *tty)
{
- struct stliport *portp;
- struct stlibrd *brdp;
- struct tty_port *port;
- unsigned long flags;
-
- portp = tty->driver_data;
- if (portp == NULL)
- return;
- if (portp->brdnr >= stli_nrbrds)
- return;
- brdp = stli_brds[portp->brdnr];
- if (brdp == NULL)
- return;
- port = &portp->port;
-
- spin_lock_irqsave(&port->lock, flags);
- port->flags &= ~ASYNC_INITIALIZED;
- spin_unlock_irqrestore(&port->lock, flags);
-
- if (!test_bit(ST_CLOSING, &portp->state))
- stli_rawclose(brdp, portp, 0, 0);
-
- spin_lock_irqsave(&stli_lock, flags);
- if (tty->termios->c_cflag & HUPCL) {
- stli_mkasysigs(&portp->asig, 0, 0);
- if (test_bit(ST_CMDING, &portp->state)) {
- set_bit(ST_DOSIGS, &portp->state);
- set_bit(ST_DOFLUSHTX, &portp->state);
- set_bit(ST_DOFLUSHRX, &portp->state);
- } else {
- stli_sendcmd(brdp, portp, A_SETSIGNALSF,
- &portp->asig, sizeof(asysigs_t), 0);
- }
- }
-
- clear_bit(ST_TXBUSY, &portp->state);
- clear_bit(ST_RXSTOP, &portp->state);
- set_bit(TTY_IO_ERROR, &tty->flags);
- spin_unlock_irqrestore(&stli_lock, flags);
-
- tty_port_hangup(port);
+ struct stliport *portp = tty->driver_data;
+ tty_port_hangup(&portp->port);
}
/*****************************************************************************/
@@ -4420,6 +4361,8 @@ static const struct tty_operations stli_ops = {
static const struct tty_port_operations stli_port_ops = {
.carrier_raised = stli_carrier_raised,
.dtr_rts = stli_dtr_rts,
+ .activate = stli_activate,
+ .shutdown = stli_shutdown,
};
/*****************************************************************************/
--
1.6.5.5
^ permalink raw reply related [flat|nested] 100+ messages in thread* [PATCH 41/58] tty: tty_port: Add a kref object to the tty port
2009-12-11 23:28 [GIT PATCH] TTY patches for 2.6.33-git Greg KH
` (39 preceding siblings ...)
2009-12-11 23:28 ` [PATCH 40/58] tty: istallion: tty port open/close methods Greg Kroah-Hartman
@ 2009-12-11 23:28 ` Greg Kroah-Hartman
2009-12-11 23:28 ` [PATCH 42/58] tty: isicom: switch to the new tty_port_open helper Greg Kroah-Hartman
` (17 subsequent siblings)
58 siblings, 0 replies; 100+ messages in thread
From: Greg Kroah-Hartman @ 2009-12-11 23:28 UTC (permalink / raw)
To: linux-kernel; +Cc: Alan Cox, Greg Kroah-Hartman
From: Alan Cox <alan@linux.intel.com>
Users of tty port need a way to refcount ports when hotplugging is
involved.
Signed-off-by: Alan Cox <alan@linux.intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
---
drivers/char/tty_port.c | 18 ++++++++++++++++++
include/linux/tty.h | 12 ++++++++++++
2 files changed, 30 insertions(+), 0 deletions(-)
diff --git a/drivers/char/tty_port.c b/drivers/char/tty_port.c
index 84006de..be492dd 100644
--- a/drivers/char/tty_port.c
+++ b/drivers/char/tty_port.c
@@ -29,6 +29,7 @@ void tty_port_init(struct tty_port *port)
spin_lock_init(&port->lock);
port->close_delay = (50 * HZ) / 100;
port->closing_wait = (3000 * HZ) / 100;
+ kref_init(&port->kref);
}
EXPORT_SYMBOL(tty_port_init);
@@ -56,6 +57,23 @@ void tty_port_free_xmit_buf(struct tty_port *port)
}
EXPORT_SYMBOL(tty_port_free_xmit_buf);
+static void tty_port_destructor(struct kref *kref)
+{
+ struct tty_port *port = container_of(kref, struct tty_port, kref);
+ if (port->xmit_buf)
+ free_page((unsigned long)port->xmit_buf);
+ if (port->ops->destruct)
+ port->ops->destruct(port);
+ else
+ kfree(port);
+}
+
+void tty_port_put(struct tty_port *port)
+{
+ if (port)
+ kref_put(&port->kref, tty_port_destructor);
+}
+EXPORT_SYMBOL(tty_port_put);
/**
* tty_port_tty_get - get a tty reference
diff --git a/include/linux/tty.h b/include/linux/tty.h
index e9269ca..e6da667 100644
--- a/include/linux/tty.h
+++ b/include/linux/tty.h
@@ -199,6 +199,8 @@ struct tty_port_operations {
/* FIXME: long term getting the tty argument *out* of this would be
good for consoles */
int (*activate)(struct tty_port *port, struct tty_struct *tty);
+ /* Called on the final put of a port */
+ void (*destruct)(struct tty_port *port);
};
struct tty_port {
@@ -219,6 +221,7 @@ struct tty_port {
int drain_delay; /* Set to zero if no pure time
based drain is needed else
set to size of fifo */
+ struct kref kref; /* Ref counter */
};
/*
@@ -461,6 +464,15 @@ extern int tty_write_lock(struct tty_struct *tty, int ndelay);
extern void tty_port_init(struct tty_port *port);
extern int tty_port_alloc_xmit_buf(struct tty_port *port);
extern void tty_port_free_xmit_buf(struct tty_port *port);
+extern void tty_port_put(struct tty_port *port);
+
+extern inline struct tty_port *tty_port_get(struct tty_port *port)
+{
+ if (port)
+ kref_get(&port->kref);
+ return port;
+}
+
extern struct tty_struct *tty_port_tty_get(struct tty_port *port);
extern void tty_port_tty_set(struct tty_port *port, struct tty_struct *tty);
extern int tty_port_carrier_raised(struct tty_port *port);
--
1.6.5.5
^ permalink raw reply related [flat|nested] 100+ messages in thread* [PATCH 42/58] tty: isicom: switch to the new tty_port_open helper
2009-12-11 23:28 [GIT PATCH] TTY patches for 2.6.33-git Greg KH
` (40 preceding siblings ...)
2009-12-11 23:28 ` [PATCH 41/58] tty: tty_port: Add a kref object to the tty port Greg Kroah-Hartman
@ 2009-12-11 23:28 ` Greg Kroah-Hartman
2009-12-11 23:28 ` [PATCH 43/58] tty: isicom: sort out the board init logic Greg Kroah-Hartman
` (16 subsequent siblings)
58 siblings, 0 replies; 100+ messages in thread
From: Greg Kroah-Hartman @ 2009-12-11 23:28 UTC (permalink / raw)
To: linux-kernel; +Cc: Alan Cox, Greg Kroah-Hartman
From: Alan Cox <alan@linux.intel.com>
Trivial conversion in this case so might as well do it while testing the
port_open design is right
Signed-off-by: Alan Cox <alan@linux.intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
---
drivers/char/isicom.c | 88 ++++++++++++-------------------------------------
1 files changed, 21 insertions(+), 67 deletions(-)
diff --git a/drivers/char/isicom.c b/drivers/char/isicom.c
index 426bfdd..e7be3ec 100644
--- a/drivers/char/isicom.c
+++ b/drivers/char/isicom.c
@@ -804,24 +804,21 @@ static inline void isicom_setup_board(struct isi_board *bp)
bp->status |= BOARD_ACTIVE;
for (channel = 0; channel < bp->port_count; channel++, port++)
drop_dtr_rts(port);
+ bp->count++;
spin_unlock_irqrestore(&bp->card_lock, flags);
}
-static int isicom_setup_port(struct tty_struct *tty)
+static int isicom_activate(struct tty_port *tport, struct tty_struct *tty)
{
- struct isi_port *port = tty->driver_data;
+ struct isi_port *port = container_of(tport, struct isi_port, port);
struct isi_board *card = port->card;
unsigned long flags;
- if (port->port.flags & ASYNC_INITIALIZED)
- return 0;
- if (tty_port_alloc_xmit_buf(&port->port) < 0)
+ if (tty_port_alloc_xmit_buf(tport) < 0)
return -ENOMEM;
spin_lock_irqsave(&card->card_lock, flags);
- clear_bit(TTY_IO_ERROR, &tty->flags);
- if (port->port.count == 1)
- card->count++;
+ isicom_setup_board(card);
port->xmit_cnt = port->xmit_head = port->xmit_tail = 0;
@@ -832,9 +829,7 @@ static int isicom_setup_port(struct tty_struct *tty)
outw(((ISICOM_KILLTX | ISICOM_KILLRX) << 8) | 0x06, card->base);
InterruptTheCard(card->base);
}
-
isicom_config_port(tty);
- port->port.flags |= ASYNC_INITIALIZED;
spin_unlock_irqrestore(&card->card_lock, flags);
return 0;
@@ -871,31 +866,20 @@ static struct tty_port *isicom_find_port(struct tty_struct *tty)
return &port->port;
}
-
+
static int isicom_open(struct tty_struct *tty, struct file *filp)
{
struct isi_port *port;
struct isi_board *card;
struct tty_port *tport;
- int error = 0;
tport = isicom_find_port(tty);
if (tport == NULL)
return -ENODEV;
port = container_of(tport, struct isi_port, port);
card = &isi_card[BOARD(tty->index)];
- isicom_setup_board(card);
- /* FIXME: locking on port.count etc */
- port->port.count++;
- tty->driver_data = port;
- tty_port_tty_set(&port->port, tty);
- /* FIXME: Locking on Initialized flag */
- if (!test_bit(ASYNCB_INITIALIZED, &tport->flags))
- error = isicom_setup_port(tty);
- if (error == 0)
- error = tty_port_block_til_ready(&port->port, tty, filp);
- return error;
+ return tty_port_open(tport, tty, filp);
}
/* close et all */
@@ -914,40 +898,21 @@ static void isicom_shutdown_port(struct isi_port *port)
tty = tty_port_tty_get(&port->port);
- if (!(port->port.flags & ASYNC_INITIALIZED)) {
- tty_kref_put(tty);
- return;
- }
-
tty_port_free_xmit_buf(&port->port);
- port->port.flags &= ~ASYNC_INITIALIZED;
- /* 3rd October 2000 : Vinayak P Risbud */
- tty_port_tty_set(&port->port, NULL);
-
- /*Fix done by Anil .S on 30-04-2001
- remote login through isi port has dtr toggle problem
- due to which the carrier drops before the password prompt
- appears on the remote end. Now we drop the dtr only if the
- HUPCL(Hangup on close) flag is set for the tty*/
-
- if (C_HUPCL(tty))
- /* drop dtr on this port */
- drop_dtr(port);
-
- /* any other port uninits */
- if (tty)
- set_bit(TTY_IO_ERROR, &tty->flags);
-
if (--card->count < 0) {
pr_dbg("isicom_shutdown_port: bad board(0x%lx) count %d.\n",
card->base, card->count);
card->count = 0;
}
- /* last port was closed, shutdown that boad too */
- if (C_HUPCL(tty)) {
- if (!card->count)
- isicom_shutdown_board(card);
+ /* last port was closed, shutdown that board too */
+ if (tty && C_HUPCL(tty)) {
+ /* FIXME: this logic is bogus - it's the old logic that was
+ bogus before but it still wants fixing */
+ if (!card->count) {
+ if (card->status & BOARD_ACTIVE)
+ card->status &= ~BOARD_ACTIVE;
+ }
}
tty_kref_put(tty);
}
@@ -968,7 +933,7 @@ static void isicom_flush_buffer(struct tty_struct *tty)
tty_wakeup(tty);
}
-static void isicom_close_port(struct tty_port *port)
+static void isicom_shutdown(struct tty_port *port)
{
struct isi_port *ip = container_of(port, struct isi_port, port);
struct isi_board *card = ip->card;
@@ -977,10 +942,8 @@ static void isicom_close_port(struct tty_port *port)
/* indicate to the card that no more data can be received
on this port */
spin_lock_irqsave(&card->card_lock, flags);
- if (port->flags & ASYNC_INITIALIZED) {
- card->port_status &= ~(1 << ip->channel);
- outw(card->port_status, card->base + 0x02);
- }
+ card->port_status &= ~(1 << ip->channel);
+ outw(card->port_status, card->base + 0x02);
isicom_shutdown_port(ip);
spin_unlock_irqrestore(&card->card_lock, flags);
}
@@ -991,12 +954,7 @@ static void isicom_close(struct tty_struct *tty, struct file *filp)
struct tty_port *port = &ip->port;
if (isicom_paranoia_check(ip, tty->name, "isicom_close"))
return;
-
- if (tty_port_close_start(port, tty, filp) == 0)
- return;
- isicom_close_port(port);
- isicom_flush_buffer(tty);
- tty_port_close_end(port, tty);
+ tty_port_close(port, tty, filp);
}
/* write et all */
@@ -1326,15 +1284,9 @@ static void isicom_start(struct tty_struct *tty)
static void isicom_hangup(struct tty_struct *tty)
{
struct isi_port *port = tty->driver_data;
- unsigned long flags;
if (isicom_paranoia_check(port, tty->name, "isicom_hangup"))
return;
-
- spin_lock_irqsave(&port->card->card_lock, flags);
- isicom_shutdown_port(port);
- spin_unlock_irqrestore(&port->card->card_lock, flags);
-
tty_port_hangup(&port->port);
}
@@ -1367,6 +1319,8 @@ static const struct tty_operations isicom_ops = {
static const struct tty_port_operations isicom_port_ops = {
.carrier_raised = isicom_carrier_raised,
.dtr_rts = isicom_dtr_rts,
+ .activate = isicom_activate,
+ .shutdown = isicom_shutdown,
};
static int __devinit reset_card(struct pci_dev *pdev,
--
1.6.5.5
^ permalink raw reply related [flat|nested] 100+ messages in thread* [PATCH 43/58] tty: isicom: sort out the board init logic
2009-12-11 23:28 [GIT PATCH] TTY patches for 2.6.33-git Greg KH
` (41 preceding siblings ...)
2009-12-11 23:28 ` [PATCH 42/58] tty: isicom: switch to the new tty_port_open helper Greg Kroah-Hartman
@ 2009-12-11 23:28 ` Greg Kroah-Hartman
2009-12-11 23:28 ` [PATCH 44/58] tty: mxser: use the tty_port_open method Greg Kroah-Hartman
` (15 subsequent siblings)
58 siblings, 0 replies; 100+ messages in thread
From: Greg Kroah-Hartman @ 2009-12-11 23:28 UTC (permalink / raw)
To: linux-kernel; +Cc: Alan Cox, Greg Kroah-Hartman
From: Alan Cox <alan@linux.intel.com>
Split this into two flags - INIT meaning the board is set up and ACTIVE
meaning the board has ports open. Remove the broken HUPCL casing and push
the counts somewhere sensible.
Signed-off-by: Alan Cox <alan@linux.intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
---
drivers/char/isicom.c | 41 +++++++++++------------------------------
include/linux/isicom.h | 1 +
2 files changed, 12 insertions(+), 30 deletions(-)
diff --git a/drivers/char/isicom.c b/drivers/char/isicom.c
index e7be3ec..1e91c30 100644
--- a/drivers/char/isicom.c
+++ b/drivers/char/isicom.c
@@ -793,21 +793,19 @@ static inline void isicom_setup_board(struct isi_board *bp)
{
int channel;
struct isi_port *port;
- unsigned long flags;
- spin_lock_irqsave(&bp->card_lock, flags);
- if (bp->status & BOARD_ACTIVE) {
- spin_unlock_irqrestore(&bp->card_lock, flags);
- return;
- }
- port = bp->ports;
- bp->status |= BOARD_ACTIVE;
- for (channel = 0; channel < bp->port_count; channel++, port++)
- drop_dtr_rts(port);
bp->count++;
- spin_unlock_irqrestore(&bp->card_lock, flags);
+ if (!(bp->status & BOARD_INIT)) {
+ port = bp->ports;
+ for (channel = 0; channel < bp->port_count; channel++, port++)
+ drop_dtr_rts(port);
+ }
+ bp->status |= BOARD_ACTIVE | BOARD_INIT;
}
+/* Activate and thus setup board are protected from races against shutdown
+ by the tty_port mutex */
+
static int isicom_activate(struct tty_port *tport, struct tty_struct *tty)
{
struct isi_port *port = container_of(tport, struct isi_port, port);
@@ -884,19 +882,10 @@ static int isicom_open(struct tty_struct *tty, struct file *filp)
/* close et all */
-static inline void isicom_shutdown_board(struct isi_board *bp)
-{
- if (bp->status & BOARD_ACTIVE)
- bp->status &= ~BOARD_ACTIVE;
-}
-
/* card->lock HAS to be held */
static void isicom_shutdown_port(struct isi_port *port)
{
struct isi_board *card = port->card;
- struct tty_struct *tty;
-
- tty = tty_port_tty_get(&port->port);
tty_port_free_xmit_buf(&port->port);
if (--card->count < 0) {
@@ -904,17 +893,9 @@ static void isicom_shutdown_port(struct isi_port *port)
card->base, card->count);
card->count = 0;
}
-
/* last port was closed, shutdown that board too */
- if (tty && C_HUPCL(tty)) {
- /* FIXME: this logic is bogus - it's the old logic that was
- bogus before but it still wants fixing */
- if (!card->count) {
- if (card->status & BOARD_ACTIVE)
- card->status &= ~BOARD_ACTIVE;
- }
- }
- tty_kref_put(tty);
+ if (!card->count)
+ card->status &= BOARD_ACTIVE;
}
static void isicom_flush_buffer(struct tty_struct *tty)
diff --git a/include/linux/isicom.h b/include/linux/isicom.h
index bbd4219..b92e056 100644
--- a/include/linux/isicom.h
+++ b/include/linux/isicom.h
@@ -67,6 +67,7 @@
#define FIRMWARE_LOADED 0x0001
#define BOARD_ACTIVE 0x0002
+#define BOARD_INIT 0x0004
/* isi_port status bitmap */
--
1.6.5.5
^ permalink raw reply related [flat|nested] 100+ messages in thread* [PATCH 44/58] tty: mxser: use the tty_port_open method
2009-12-11 23:28 [GIT PATCH] TTY patches for 2.6.33-git Greg KH
` (42 preceding siblings ...)
2009-12-11 23:28 ` [PATCH 43/58] tty: isicom: sort out the board init logic Greg Kroah-Hartman
@ 2009-12-11 23:28 ` Greg Kroah-Hartman
2009-12-11 23:28 ` [PATCH 45/58] tty: mxser: Use the new locking rules to fix setserial properly Greg Kroah-Hartman
` (14 subsequent siblings)
58 siblings, 0 replies; 100+ messages in thread
From: Greg Kroah-Hartman @ 2009-12-11 23:28 UTC (permalink / raw)
To: linux-kernel; +Cc: Alan Cox, Greg Kroah-Hartman
From: Alan Cox <alan@linux.intel.com>
At first this looks a fairly trivial conversion but we can't quite push
everything into the right format yet. The open side is easy but care is needed
over the setserial methods. Fix up the locking now that we've adopted the
port->mutex locking rule for the initialization.
Signed-off-by: Alan Cox <alan@linux.intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
---
drivers/char/mxser.c | 111 ++++++++++++++++----------------------------------
1 files changed, 35 insertions(+), 76 deletions(-)
diff --git a/drivers/char/mxser.c b/drivers/char/mxser.c
index 5e28d39..9dac516 100644
--- a/drivers/char/mxser.c
+++ b/drivers/char/mxser.c
@@ -856,9 +856,9 @@ static void mxser_check_modem_status(struct tty_struct *tty,
}
}
-static int mxser_startup(struct tty_struct *tty)
+static int mxser_activate(struct tty_port *port, struct tty_struct *tty)
{
- struct mxser_port *info = tty->driver_data;
+ struct mxser_port *info = container_of(port, struct mxser_port, port);
unsigned long page;
unsigned long flags;
@@ -868,22 +868,13 @@ static int mxser_startup(struct tty_struct *tty)
spin_lock_irqsave(&info->slock, flags);
- if (info->port.flags & ASYNC_INITIALIZED) {
- free_page(page);
- spin_unlock_irqrestore(&info->slock, flags);
- return 0;
- }
-
if (!info->ioaddr || !info->type) {
set_bit(TTY_IO_ERROR, &tty->flags);
free_page(page);
spin_unlock_irqrestore(&info->slock, flags);
return 0;
}
- if (info->port.xmit_buf)
- free_page(page);
- else
- info->port.xmit_buf = (unsigned char *) page;
+ info->port.xmit_buf = (unsigned char *) page;
/*
* Clear the FIFO buffers and disable them
@@ -951,24 +942,19 @@ static int mxser_startup(struct tty_struct *tty)
* and set the speed of the serial port
*/
mxser_change_speed(tty, NULL);
- info->port.flags |= ASYNC_INITIALIZED;
spin_unlock_irqrestore(&info->slock, flags);
return 0;
}
/*
- * This routine will shutdown a serial port; interrupts maybe disabled, and
- * DTR is dropped if the hangup on close termio flag is on.
+ * This routine will shutdown a serial port
*/
-static void mxser_shutdown(struct tty_struct *tty)
+static void mxser_shutdown_port(struct tty_port *port)
{
- struct mxser_port *info = tty->driver_data;
+ struct mxser_port *info = container_of(port, struct mxser_port, port);
unsigned long flags;
- if (!(info->port.flags & ASYNC_INITIALIZED))
- return;
-
spin_lock_irqsave(&info->slock, flags);
/*
@@ -978,7 +964,7 @@ static void mxser_shutdown(struct tty_struct *tty)
wake_up_interruptible(&info->port.delta_msr_wait);
/*
- * Free the IRQ, if necessary
+ * Free the xmit buffer, if necessary
*/
if (info->port.xmit_buf) {
free_page((unsigned long) info->port.xmit_buf);
@@ -988,10 +974,6 @@ static void mxser_shutdown(struct tty_struct *tty)
info->IER = 0;
outb(0x00, info->ioaddr + UART_IER);
- if (tty->termios->c_cflag & HUPCL)
- info->MCR &= ~(UART_MCR_DTR | UART_MCR_RTS);
- outb(info->MCR, info->ioaddr + UART_MCR);
-
/* clear Rx/Tx FIFO's */
if (info->board->chip_flag)
outb(UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT |
@@ -1004,9 +986,6 @@ static void mxser_shutdown(struct tty_struct *tty)
/* read data port to reset things */
(void) inb(info->ioaddr + UART_RX);
- set_bit(TTY_IO_ERROR, &tty->flags);
-
- info->port.flags &= ~ASYNC_INITIALIZED;
if (info->board->chip_flag)
SET_MOXA_MUST_NO_SOFTWARE_FLOW_CONTROL(info->ioaddr);
@@ -1023,8 +1002,7 @@ static void mxser_shutdown(struct tty_struct *tty)
static int mxser_open(struct tty_struct *tty, struct file *filp)
{
struct mxser_port *info;
- unsigned long flags;
- int retval, line;
+ int line;
line = tty->index;
if (line == MXSER_PORTS)
@@ -1035,23 +1013,7 @@ static int mxser_open(struct tty_struct *tty, struct file *filp)
if (!info->ioaddr)
return -ENODEV;
- tty->driver_data = info;
- tty_port_tty_set(&info->port, tty);
- /*
- * Start up serial port
- */
- spin_lock_irqsave(&info->port.lock, flags);
- info->port.count++;
- spin_unlock_irqrestore(&info->port.lock, flags);
- retval = mxser_startup(tty);
- if (retval)
- return retval;
-
- retval = tty_port_block_til_ready(&info->port, tty, filp);
- if (retval)
- return retval;
-
- return 0;
+ return tty_port_open(&info->port, tty, filp);
}
static void mxser_flush_buffer(struct tty_struct *tty)
@@ -1075,19 +1037,11 @@ static void mxser_flush_buffer(struct tty_struct *tty)
}
-static void mxser_close_port(struct tty_struct *tty, struct tty_port *port)
+static void mxser_close_port(struct tty_port *port)
{
struct mxser_port *info = container_of(port, struct mxser_port, port);
unsigned long timeout;
/*
- * Save the termios structure, since this port may have
- * separate termios for callout and dialin.
- *
- * FIXME: Can this go ?
- */
- if (port->flags & ASYNC_NORMAL_ACTIVE)
- info->normal_termios = *tty->termios;
- /*
* At this point we stop accepting input. To do this, we
* disable the receive line status interrupts, and tell the
* interrupt driver to stop checking the data ready bit in the
@@ -1097,22 +1051,18 @@ static void mxser_close_port(struct tty_struct *tty, struct tty_port *port)
if (info->board->chip_flag)
info->IER &= ~MOXA_MUST_RECV_ISR;
- if (port->flags & ASYNC_INITIALIZED) {
- outb(info->IER, info->ioaddr + UART_IER);
- /*
- * Before we drop DTR, make sure the UART transmitter
- * has completely drained; this is especially
- * important if there is a transmit FIFO!
- */
- timeout = jiffies + HZ;
- while (!(inb(info->ioaddr + UART_LSR) & UART_LSR_TEMT)) {
- schedule_timeout_interruptible(5);
- if (time_after(jiffies, timeout))
- break;
- }
+ outb(info->IER, info->ioaddr + UART_IER);
+ /*
+ * Before we drop DTR, make sure the UART transmitter
+ * has completely drained; this is especially
+ * important if there is a transmit FIFO!
+ */
+ timeout = jiffies + HZ;
+ while (!(inb(info->ioaddr + UART_LSR) & UART_LSR_TEMT)) {
+ schedule_timeout_interruptible(5);
+ if (time_after(jiffies, timeout))
+ break;
}
- mxser_shutdown(tty);
-
}
/*
@@ -1130,8 +1080,12 @@ static void mxser_close(struct tty_struct *tty, struct file *filp)
return;
if (tty_port_close_start(port, tty, filp) == 0)
return;
- mxser_close_port(tty, port);
+ mutex_lock(&port->mutex);
+ mxser_close_port(port);
mxser_flush_buffer(tty);
+ mxser_shutdown_port(port);
+ clear_bit(ASYNCB_INITIALIZED, &port->flags);
+ mutex_unlock(&port->mutex);
/* Right now the tty_port set is done outside of the close_end helper
as we don't yet have everyone using refcounts */
tty_port_close_end(port, tty);
@@ -1329,9 +1283,13 @@ static int mxser_set_serial_info(struct tty_struct *tty,
mxser_change_speed(tty, NULL);
spin_unlock_irqrestore(&info->slock, sl_flags);
}
- } else
- retval = mxser_startup(tty);
-
+ } else {
+ mutex_lock(&info->port.mutex);
+ retval = mxser_activate(&info->port, tty);
+ if (retval == 0)
+ set_bit(ASYNCB_INITIALIZED, &info->port.flags);
+ mutex_unlock(&info->port.mutex);
+ }
return retval;
}
@@ -2059,7 +2017,6 @@ static void mxser_hangup(struct tty_struct *tty)
struct mxser_port *info = tty->driver_data;
mxser_flush_buffer(tty);
- mxser_shutdown(tty);
tty_port_hangup(&info->port);
}
@@ -2363,6 +2320,8 @@ static const struct tty_operations mxser_ops = {
struct tty_port_operations mxser_port_ops = {
.carrier_raised = mxser_carrier_raised,
.dtr_rts = mxser_dtr_rts,
+ .activate = mxser_activate,
+ .shutdown = mxser_shutdown_port,
};
/*
--
1.6.5.5
^ permalink raw reply related [flat|nested] 100+ messages in thread* [PATCH 45/58] tty: mxser: Use the new locking rules to fix setserial properly
2009-12-11 23:28 [GIT PATCH] TTY patches for 2.6.33-git Greg KH
` (43 preceding siblings ...)
2009-12-11 23:28 ` [PATCH 44/58] tty: mxser: use the tty_port_open method Greg Kroah-Hartman
@ 2009-12-11 23:28 ` Greg Kroah-Hartman
2009-12-11 23:28 ` [PATCH 46/58] tty: isicom: fix deadlock on shutdown Greg Kroah-Hartman
` (13 subsequent siblings)
58 siblings, 0 replies; 100+ messages in thread
From: Greg Kroah-Hartman @ 2009-12-11 23:28 UTC (permalink / raw)
To: linux-kernel; +Cc: Alan Cox, Greg Kroah-Hartman
From: Alan Cox <alan@linux.intel.com>
Propogate the init/shutdown mutex through the setserial logic. Use the proper
locks for the various bits still using the BKL. Kill the BKL in this driver.
Updated to fix the bug noted by Dan Carpenter
Signed-off-by: Alan Cox <alan@linux.intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
---
drivers/char/mxser.c | 145 +++++++++++++++++++++++++++-----------------------
1 files changed, 78 insertions(+), 67 deletions(-)
diff --git a/drivers/char/mxser.c b/drivers/char/mxser.c
index 9dac516..3d92306 100644
--- a/drivers/char/mxser.c
+++ b/drivers/char/mxser.c
@@ -23,7 +23,6 @@
#include <linux/errno.h>
#include <linux/signal.h>
#include <linux/sched.h>
-#include <linux/smp_lock.h>
#include <linux/timer.h>
#include <linux/interrupt.h>
#include <linux/tty.h>
@@ -1229,6 +1228,7 @@ static int mxser_set_serial_info(struct tty_struct *tty,
struct serial_struct __user *new_info)
{
struct mxser_port *info = tty->driver_data;
+ struct tty_port *port = &info->port;
struct serial_struct new_serial;
speed_t baud;
unsigned long sl_flags;
@@ -1244,7 +1244,7 @@ static int mxser_set_serial_info(struct tty_struct *tty,
new_serial.port != info->ioaddr)
return -EINVAL;
- flags = info->port.flags & ASYNC_SPD_MASK;
+ flags = port->flags & ASYNC_SPD_MASK;
if (!capable(CAP_SYS_ADMIN)) {
if ((new_serial.baud_base != info->baud_base) ||
@@ -1258,16 +1258,17 @@ static int mxser_set_serial_info(struct tty_struct *tty,
* OK, past this point, all the error checking has been done.
* At this point, we start making changes.....
*/
- info->port.flags = ((info->port.flags & ~ASYNC_FLAGS) |
+ port->flags = ((port->flags & ~ASYNC_FLAGS) |
(new_serial.flags & ASYNC_FLAGS));
- info->port.close_delay = new_serial.close_delay * HZ / 100;
- info->port.closing_wait = new_serial.closing_wait * HZ / 100;
- tty->low_latency = (info->port.flags & ASYNC_LOW_LATENCY)
- ? 1 : 0;
- if ((info->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST &&
+ port->close_delay = new_serial.close_delay * HZ / 100;
+ port->closing_wait = new_serial.closing_wait * HZ / 100;
+ tty->low_latency = (port->flags & ASYNC_LOW_LATENCY) ? 1 : 0;
+ if ((port->flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST &&
(new_serial.baud_base != info->baud_base ||
new_serial.custom_divisor !=
info->custom_divisor)) {
+ if (new_serial.custom_divisor == 0)
+ return -EINVAL;
baud = new_serial.baud_base / new_serial.custom_divisor;
tty_encode_baud_rate(tty, baud, baud);
}
@@ -1277,18 +1278,16 @@ static int mxser_set_serial_info(struct tty_struct *tty,
process_txrx_fifo(info);
- if (info->port.flags & ASYNC_INITIALIZED) {
- if (flags != (info->port.flags & ASYNC_SPD_MASK)) {
+ if (test_bit(ASYNCB_INITIALIZED, &port->flags)) {
+ if (flags != (port->flags & ASYNC_SPD_MASK)) {
spin_lock_irqsave(&info->slock, sl_flags);
mxser_change_speed(tty, NULL);
spin_unlock_irqrestore(&info->slock, sl_flags);
}
} else {
- mutex_lock(&info->port.mutex);
- retval = mxser_activate(&info->port, tty);
+ retval = mxser_activate(port, tty);
if (retval == 0)
- set_bit(ASYNCB_INITIALIZED, &info->port.flags);
- mutex_unlock(&info->port.mutex);
+ set_bit(ASYNCB_INITIALIZED, &port->flags);
}
return retval;
}
@@ -1478,7 +1477,8 @@ static int __init mxser_read_register(int port, unsigned short *regs)
static int mxser_ioctl_special(unsigned int cmd, void __user *argp)
{
- struct mxser_port *port;
+ struct mxser_port *ip;
+ struct tty_port *port;
struct tty_struct *tty;
int result, status;
unsigned int i, j;
@@ -1494,38 +1494,39 @@ static int mxser_ioctl_special(unsigned int cmd, void __user *argp)
case MOXA_CHKPORTENABLE:
result = 0;
- lock_kernel();
for (i = 0; i < MXSER_BOARDS; i++)
for (j = 0; j < MXSER_PORTS_PER_BOARD; j++)
if (mxser_boards[i].ports[j].ioaddr)
result |= (1 << i);
- unlock_kernel();
return put_user(result, (unsigned long __user *)argp);
case MOXA_GETDATACOUNT:
- lock_kernel();
+ /* The receive side is locked by port->slock but it isn't
+ clear that an exact snapshot is worth copying here */
if (copy_to_user(argp, &mxvar_log, sizeof(mxvar_log)))
ret = -EFAULT;
- unlock_kernel();
return ret;
case MOXA_GETMSTATUS: {
struct mxser_mstatus ms, __user *msu = argp;
- lock_kernel();
for (i = 0; i < MXSER_BOARDS; i++)
for (j = 0; j < MXSER_PORTS_PER_BOARD; j++) {
- port = &mxser_boards[i].ports[j];
+ ip = &mxser_boards[i].ports[j];
+ port = &ip->port;
memset(&ms, 0, sizeof(ms));
- if (!port->ioaddr)
+ mutex_lock(&port->mutex);
+ if (!ip->ioaddr)
goto copy;
- tty = tty_port_tty_get(&port->port);
+ tty = tty_port_tty_get(port);
if (!tty || !tty->termios)
- ms.cflag = port->normal_termios.c_cflag;
+ ms.cflag = ip->normal_termios.c_cflag;
else
ms.cflag = tty->termios->c_cflag;
tty_kref_put(tty);
- status = inb(port->ioaddr + UART_MSR);
+ spin_lock_irq(&ip->slock);
+ status = inb(ip->ioaddr + UART_MSR);
+ spin_unlock_irq(&ip->slock);
if (status & UART_MSR_DCD)
ms.dcd = 1;
if (status & UART_MSR_DSR)
@@ -1533,13 +1534,11 @@ static int mxser_ioctl_special(unsigned int cmd, void __user *argp)
if (status & UART_MSR_CTS)
ms.cts = 1;
copy:
- if (copy_to_user(msu, &ms, sizeof(ms))) {
- unlock_kernel();
+ mutex_unlock(&port->mutex);
+ if (copy_to_user(msu, &ms, sizeof(ms)))
return -EFAULT;
- }
msu++;
}
- unlock_kernel();
return 0;
}
case MOXA_ASPP_MON_EXT: {
@@ -1551,41 +1550,48 @@ static int mxser_ioctl_special(unsigned int cmd, void __user *argp)
if (!me)
return -ENOMEM;
- lock_kernel();
for (i = 0, p = 0; i < MXSER_BOARDS; i++) {
for (j = 0; j < MXSER_PORTS_PER_BOARD; j++, p++) {
if (p >= ARRAY_SIZE(me->rx_cnt)) {
i = MXSER_BOARDS;
break;
}
- port = &mxser_boards[i].ports[j];
- if (!port->ioaddr)
+ ip = &mxser_boards[i].ports[j];
+ port = &ip->port;
+
+ mutex_lock(&port->mutex);
+ if (!ip->ioaddr) {
+ mutex_unlock(&port->mutex);
continue;
+ }
- status = mxser_get_msr(port->ioaddr, 0, p);
+ spin_lock_irq(&ip->slock);
+ status = mxser_get_msr(ip->ioaddr, 0, p);
if (status & UART_MSR_TERI)
- port->icount.rng++;
+ ip->icount.rng++;
if (status & UART_MSR_DDSR)
- port->icount.dsr++;
+ ip->icount.dsr++;
if (status & UART_MSR_DDCD)
- port->icount.dcd++;
+ ip->icount.dcd++;
if (status & UART_MSR_DCTS)
- port->icount.cts++;
+ ip->icount.cts++;
- port->mon_data.modem_status = status;
- me->rx_cnt[p] = port->mon_data.rxcnt;
- me->tx_cnt[p] = port->mon_data.txcnt;
- me->up_rxcnt[p] = port->mon_data.up_rxcnt;
- me->up_txcnt[p] = port->mon_data.up_txcnt;
+ ip->mon_data.modem_status = status;
+ me->rx_cnt[p] = ip->mon_data.rxcnt;
+ me->tx_cnt[p] = ip->mon_data.txcnt;
+ me->up_rxcnt[p] = ip->mon_data.up_rxcnt;
+ me->up_txcnt[p] = ip->mon_data.up_txcnt;
me->modem_status[p] =
- port->mon_data.modem_status;
- tty = tty_port_tty_get(&port->port);
+ ip->mon_data.modem_status;
+ spin_unlock_irq(&ip->slock);
+
+ tty = tty_port_tty_get(&ip->port);
if (!tty || !tty->termios) {
- cflag = port->normal_termios.c_cflag;
- iflag = port->normal_termios.c_iflag;
- me->baudrate[p] = tty_termios_baud_rate(&port->normal_termios);
+ cflag = ip->normal_termios.c_cflag;
+ iflag = ip->normal_termios.c_iflag;
+ me->baudrate[p] = tty_termios_baud_rate(&ip->normal_termios);
} else {
cflag = tty->termios->c_cflag;
iflag = tty->termios->c_iflag;
@@ -1604,16 +1610,15 @@ static int mxser_ioctl_special(unsigned int cmd, void __user *argp)
if (iflag & (IXON | IXOFF))
me->flowctrl[p] |= 0x0C;
- if (port->type == PORT_16550A)
+ if (ip->type == PORT_16550A)
me->fifo[p] = 1;
- opmode = inb(port->opmode_ioaddr) >>
- ((p % 4) * 2);
+ opmode = inb(ip->opmode_ioaddr)>>((p % 4) * 2);
opmode &= OP_MODE_MASK;
me->iftype[p] = opmode;
+ mutex_unlock(&port->mutex);
}
}
- unlock_kernel();
if (copy_to_user(argp, me, sizeof(*me)))
ret = -EFAULT;
kfree(me);
@@ -1650,6 +1655,7 @@ static int mxser_ioctl(struct tty_struct *tty, struct file *file,
unsigned int cmd, unsigned long arg)
{
struct mxser_port *info = tty->driver_data;
+ struct tty_port *port = &info->port;
struct async_icount cnow;
unsigned long flags;
void __user *argp = (void __user *)arg;
@@ -1674,20 +1680,20 @@ static int mxser_ioctl(struct tty_struct *tty, struct file *file,
opmode != RS422_MODE &&
opmode != RS485_4WIRE_MODE)
return -EFAULT;
- lock_kernel();
mask = ModeMask[p];
shiftbit = p * 2;
+ spin_lock_irq(&info->slock);
val = inb(info->opmode_ioaddr);
val &= mask;
val |= (opmode << shiftbit);
outb(val, info->opmode_ioaddr);
- unlock_kernel();
+ spin_unlock_irq(&info->slock);
} else {
- lock_kernel();
shiftbit = p * 2;
+ spin_lock_irq(&info->slock);
opmode = inb(info->opmode_ioaddr) >> shiftbit;
+ spin_unlock_irq(&info->slock);
opmode &= OP_MODE_MASK;
- unlock_kernel();
if (put_user(opmode, (int __user *)argp))
return -EFAULT;
}
@@ -1700,14 +1706,14 @@ static int mxser_ioctl(struct tty_struct *tty, struct file *file,
switch (cmd) {
case TIOCGSERIAL:
- lock_kernel();
+ mutex_lock(&port->mutex);
retval = mxser_get_serial_info(tty, argp);
- unlock_kernel();
+ mutex_unlock(&port->mutex);
return retval;
case TIOCSSERIAL:
- lock_kernel();
+ mutex_lock(&port->mutex);
retval = mxser_set_serial_info(tty, argp);
- unlock_kernel();
+ mutex_unlock(&port->mutex);
return retval;
case TIOCSERGETLSR: /* Get line status register */
return mxser_get_lsr_info(info, argp);
@@ -1753,31 +1759,33 @@ static int mxser_ioctl(struct tty_struct *tty, struct file *file,
case MOXA_HighSpeedOn:
return put_user(info->baud_base != 115200 ? 1 : 0, (int __user *)argp);
case MOXA_SDS_RSTICOUNTER:
- lock_kernel();
+ spin_lock_irq(&info->slock);
info->mon_data.rxcnt = 0;
info->mon_data.txcnt = 0;
- unlock_kernel();
+ spin_unlock_irq(&info->slock);
return 0;
case MOXA_ASPP_OQUEUE:{
int len, lsr;
- lock_kernel();
len = mxser_chars_in_buffer(tty);
+ spin_lock(&info->slock);
lsr = inb(info->ioaddr + UART_LSR) & UART_LSR_THRE;
+ spin_unlock_irq(&info->slock);
len += (lsr ? 0 : 1);
- unlock_kernel();
return put_user(len, (int __user *)argp);
}
case MOXA_ASPP_MON: {
int mcr, status;
- lock_kernel();
+ spin_lock(&info->slock);
status = mxser_get_msr(info->ioaddr, 1, tty->index);
mxser_check_modem_status(tty, info, status);
mcr = inb(info->ioaddr + UART_MCR);
+ spin_unlock(&info->slock);
+
if (mcr & MOXA_MUST_MCR_XON_FLAG)
info->mon_data.hold_reason &= ~NPPI_NOTIFY_XOFFHOLD;
else
@@ -1792,7 +1800,7 @@ static int mxser_ioctl(struct tty_struct *tty, struct file *file,
info->mon_data.hold_reason |= NPPI_NOTIFY_CTSHOLD;
else
info->mon_data.hold_reason &= ~NPPI_NOTIFY_CTSHOLD;
- unlock_kernel();
+
if (copy_to_user(argp, &info->mon_data,
sizeof(struct mxser_mon)))
return -EFAULT;
@@ -1951,6 +1959,7 @@ static void mxser_wait_until_sent(struct tty_struct *tty, int timeout)
{
struct mxser_port *info = tty->driver_data;
unsigned long orig_jiffies, char_time;
+ unsigned long flags;
int lsr;
if (info->type == PORT_UNKNOWN)
@@ -1990,19 +1999,21 @@ static void mxser_wait_until_sent(struct tty_struct *tty, int timeout)
timeout, char_time);
printk("jiff=%lu...", jiffies);
#endif
- lock_kernel();
+ spin_lock_irqsave(&info->slock, flags);
while (!((lsr = inb(info->ioaddr + UART_LSR)) & UART_LSR_TEMT)) {
#ifdef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT
printk("lsr = %d (jiff=%lu)...", lsr, jiffies);
#endif
+ spin_unlock_irqrestore(&info->slock, flags);
schedule_timeout_interruptible(char_time);
+ spin_lock_irqsave(&info->slock, flags);
if (signal_pending(current))
break;
if (timeout && time_after(jiffies, orig_jiffies + timeout))
break;
}
+ spin_unlock_irqrestore(&info->slock, flags);
set_current_state(TASK_RUNNING);
- unlock_kernel();
#ifdef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT
printk("lsr = %d (jiff=%lu)...done\n", lsr, jiffies);
--
1.6.5.5
^ permalink raw reply related [flat|nested] 100+ messages in thread* [PATCH 46/58] tty: isicom: fix deadlock on shutdown
2009-12-11 23:28 [GIT PATCH] TTY patches for 2.6.33-git Greg KH
` (44 preceding siblings ...)
2009-12-11 23:28 ` [PATCH 45/58] tty: mxser: Use the new locking rules to fix setserial properly Greg Kroah-Hartman
@ 2009-12-11 23:28 ` Greg Kroah-Hartman
2009-12-11 23:28 ` [PATCH 47/58] tty: moxa: Use more tty_port ops Greg Kroah-Hartman
` (12 subsequent siblings)
58 siblings, 0 replies; 100+ messages in thread
From: Greg Kroah-Hartman @ 2009-12-11 23:28 UTC (permalink / raw)
To: linux-kernel; +Cc: Alan Cox, Greg Kroah-Hartman
From: Alan Cox <alan@linux.intel.com>
Alexander Strakh <strakh@ispras.ru> reported
KERNEL_VERSION: 2.6.31
DESCRIBE:
Driver drivers/char/isicom.c might sleep in atomic context, because it
calls
tty_port_xmit_buf under spin_lock.
./drivers/char/isicom.c:
1307 static void isicom_hangup(struct tty_struct *tty)
1308 {
...
1315 spin_lock_irqsave(&port->card->card_lock, flags);
1316 isicom_shutdown_port(port);
...
Path to might_sleep macro from isicom_hangup:
1. isicom_hangup calls spin_lock_irqsave (drivers/char/isicom.c:1315) and
then
calls isicom_shutdown_port.
2. isiscom_shutdown_port calls tty_port_free_xmit_buf at
drivers/char/isicom.c:906
3. tty_port_free_xmit_buf calls mutex_lock at drivers/char/tty_port:48
Found by Linux Driver Verification Project.
Reported-by: Alexander Strakh <strakh@ispras.ru>
Signed-off-by: Alan Cox <alan@linux.intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
---
drivers/char/isicom.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/drivers/char/isicom.c b/drivers/char/isicom.c
index 1e91c30..300d5bd 100644
--- a/drivers/char/isicom.c
+++ b/drivers/char/isicom.c
@@ -887,7 +887,6 @@ static void isicom_shutdown_port(struct isi_port *port)
{
struct isi_board *card = port->card;
- tty_port_free_xmit_buf(&port->port);
if (--card->count < 0) {
pr_dbg("isicom_shutdown_port: bad board(0x%lx) count %d.\n",
card->base, card->count);
@@ -927,6 +926,7 @@ static void isicom_shutdown(struct tty_port *port)
outw(card->port_status, card->base + 0x02);
isicom_shutdown_port(ip);
spin_unlock_irqrestore(&card->card_lock, flags);
+ tty_port_free_xmit_buf(port);
}
static void isicom_close(struct tty_struct *tty, struct file *filp)
--
1.6.5.5
^ permalink raw reply related [flat|nested] 100+ messages in thread* [PATCH 47/58] tty: moxa: Use more tty_port ops
2009-12-11 23:28 [GIT PATCH] TTY patches for 2.6.33-git Greg KH
` (45 preceding siblings ...)
2009-12-11 23:28 ` [PATCH 46/58] tty: isicom: fix deadlock on shutdown Greg Kroah-Hartman
@ 2009-12-11 23:28 ` Greg Kroah-Hartman
2009-12-11 23:28 ` [PATCH 48/58] tty: moxa: rework the locking a bit Greg Kroah-Hartman
` (11 subsequent siblings)
58 siblings, 0 replies; 100+ messages in thread
From: Greg Kroah-Hartman @ 2009-12-11 23:28 UTC (permalink / raw)
To: linux-kernel; +Cc: Alan Cox, Greg Kroah-Hartman
From: Alan Cox <alan@linux.intel.com>
Rework a few bits of this into tty_port format
Signed-off-by: Alan Cox <alan@linux.intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
---
drivers/char/moxa.c | 137 ++++++++-------------------------------------------
1 files changed, 21 insertions(+), 116 deletions(-)
diff --git a/drivers/char/moxa.c b/drivers/char/moxa.c
index dd0083b..d8bcbed 100644
--- a/drivers/char/moxa.c
+++ b/drivers/char/moxa.c
@@ -206,8 +206,9 @@ static int moxa_tiocmset(struct tty_struct *tty, struct file *file,
static void moxa_poll(unsigned long);
static void moxa_set_tty_param(struct tty_struct *, struct ktermios *);
static void moxa_setup_empty_event(struct tty_struct *);
-static void moxa_shut_down(struct tty_struct *);
+static void moxa_shutdown(struct tty_port *);
static int moxa_carrier_raised(struct tty_port *);
+static void moxa_dtr_rts(struct tty_port *, int);
/*
* moxa board interface functions:
*/
@@ -409,6 +410,8 @@ static const struct tty_operations moxa_ops = {
static const struct tty_port_operations moxa_port_ops = {
.carrier_raised = moxa_carrier_raised,
+ .dtr_rts = moxa_dtr_rts,
+ .shutdown = moxa_shutdown,
};
static struct tty_driver *moxaDriver;
@@ -1112,14 +1115,12 @@ static void __exit moxa_exit(void)
module_init(moxa_init);
module_exit(moxa_exit);
-static void moxa_close_port(struct tty_struct *tty)
+static void moxa_shutdown(struct tty_port *port)
{
- struct moxa_port *ch = tty->driver_data;
- moxa_shut_down(tty);
+ struct moxa_port *ch = container_of(port, struct moxa_port, port);
+ MoxaPortDisable(ch);
MoxaPortFlushData(ch, 2);
- ch->port.flags &= ~ASYNC_NORMAL_ACTIVE;
- tty->driver_data = NULL;
- tty_port_tty_set(&ch->port, NULL);
+ clear_bit(ASYNCB_NORMAL_ACTIVE, &port->flags);
}
static int moxa_carrier_raised(struct tty_port *port)
@@ -1133,39 +1134,13 @@ static int moxa_carrier_raised(struct tty_port *port)
return dcd;
}
-static int moxa_block_till_ready(struct tty_struct *tty, struct file *filp,
- struct moxa_port *ch)
+static void moxa_dtr_rts(struct tty_port *port, int onoff)
{
- struct tty_port *port = &ch->port;
- DEFINE_WAIT(wait);
- int retval = 0;
- u8 dcd;
-
- while (1) {
- prepare_to_wait(&port->open_wait, &wait, TASK_INTERRUPTIBLE);
- if (tty_hung_up_p(filp)) {
-#ifdef SERIAL_DO_RESTART
- retval = -ERESTARTSYS;
-#else
- retval = -EAGAIN;
-#endif
- break;
- }
- dcd = tty_port_carrier_raised(port);
- if (dcd)
- break;
-
- if (signal_pending(current)) {
- retval = -ERESTARTSYS;
- break;
- }
- schedule();
- }
- finish_wait(&port->open_wait, &wait);
-
- return retval;
+ struct moxa_port *ch = container_of(port, struct moxa_port, port);
+ MoxaPortLineCtrl(ch, onoff, onoff);
}
+
static int moxa_open(struct tty_struct *tty, struct file *filp)
{
struct moxa_board_conf *brd;
@@ -1194,6 +1169,7 @@ static int moxa_open(struct tty_struct *tty, struct file *filp)
ch->port.count++;
tty->driver_data = ch;
tty_port_tty_set(&ch->port, tty);
+ mutex_lock(&ch->port.mutex);
if (!(ch->port.flags & ASYNC_INITIALIZED)) {
ch->statusflags = 0;
moxa_set_tty_param(tty, tty->termios);
@@ -1202,57 +1178,21 @@ static int moxa_open(struct tty_struct *tty, struct file *filp)
MoxaSetFifo(ch, ch->type == PORT_16550A);
ch->port.flags |= ASYNC_INITIALIZED;
}
+ mutex_unlock(&ch->port.mutex);
mutex_unlock(&moxa_openlock);
- retval = 0;
- if (!(filp->f_flags & O_NONBLOCK) && !C_CLOCAL(tty))
- retval = moxa_block_till_ready(tty, filp, ch);
- mutex_lock(&moxa_openlock);
- if (retval) {
- if (ch->port.count) /* 0 means already hung up... */
- if (--ch->port.count == 0)
- moxa_close_port(tty);
- } else
- ch->port.flags |= ASYNC_NORMAL_ACTIVE;
- mutex_unlock(&moxa_openlock);
-
+ retval = tty_port_block_til_ready(&ch->port, tty, filp);
+ if (retval == 0)
+ set_bit(ASYNCB_NORMAL_ACTIVE, &ch->port.flags);
return retval;
}
static void moxa_close(struct tty_struct *tty, struct file *filp)
{
- struct moxa_port *ch;
- int port;
-
- port = tty->index;
- if (port == MAX_PORTS || tty_hung_up_p(filp))
- return;
-
- mutex_lock(&moxa_openlock);
- ch = tty->driver_data;
- if (ch == NULL)
- goto unlock;
- if (tty->count == 1 && ch->port.count != 1) {
- printk(KERN_WARNING "moxa_close: bad serial port count; "
- "tty->count is 1, ch->port.count is %d\n", ch->port.count);
- ch->port.count = 1;
- }
- if (--ch->port.count < 0) {
- printk(KERN_WARNING "moxa_close: bad serial port count, "
- "device=%s\n", tty->name);
- ch->port.count = 0;
- }
- if (ch->port.count)
- goto unlock;
-
+ struct moxa_port *ch = tty->driver_data;
ch->cflag = tty->termios->c_cflag;
- if (ch->port.flags & ASYNC_INITIALIZED) {
- moxa_setup_empty_event(tty);
- tty_wait_until_sent(tty, 30 * HZ); /* 30 seconds timeout */
- }
-
- moxa_close_port(tty);
-unlock:
+ mutex_lock(&moxa_openlock);
+ tty_port_close(&ch->port, tty, filp);
mutex_unlock(&moxa_openlock);
}
@@ -1300,14 +1240,6 @@ static int moxa_chars_in_buffer(struct tty_struct *tty)
struct moxa_port *ch = tty->driver_data;
int chars;
- /*
- * Sigh...I have to check if driver_data is NULL here, because
- * if an open() fails, the TTY subsystem eventually calls
- * tty_wait_until_sent(), which calls the driver's chars_in_buffer()
- * routine. And since the open() failed, we return 0 here. TDJ
- */
- if (ch == NULL)
- return 0;
lock_kernel();
chars = MoxaPortTxQueue(ch);
if (chars) {
@@ -1436,15 +1368,8 @@ static void moxa_hangup(struct tty_struct *tty)
mutex_lock(&moxa_openlock);
ch = tty->driver_data;
- if (ch == NULL) {
- mutex_unlock(&moxa_openlock);
- return;
- }
- ch->port.count = 0;
- moxa_close_port(tty);
+ tty_port_hangup(&ch->port);
mutex_unlock(&moxa_openlock);
-
- wake_up_interruptible(&ch->port.open_wait);
}
static void moxa_new_dcdstate(struct moxa_port *p, u8 dcd)
@@ -1597,26 +1522,6 @@ static void moxa_setup_empty_event(struct tty_struct *tty)
spin_unlock_bh(&moxa_lock);
}
-static void moxa_shut_down(struct tty_struct *tty)
-{
- struct moxa_port *ch = tty->driver_data;
-
- if (!(ch->port.flags & ASYNC_INITIALIZED))
- return;
-
- MoxaPortDisable(ch);
-
- /*
- * If we're a modem control device and HUPCL is on, drop RTS & DTR.
- */
- if (C_HUPCL(tty))
- MoxaPortLineCtrl(ch, 0, 0);
-
- spin_lock_bh(&moxa_lock);
- ch->port.flags &= ~ASYNC_INITIALIZED;
- spin_unlock_bh(&moxa_lock);
-}
-
/*****************************************************************************
* Driver level functions: *
*****************************************************************************/
--
1.6.5.5
^ permalink raw reply related [flat|nested] 100+ messages in thread* [PATCH 48/58] tty: moxa: rework the locking a bit
2009-12-11 23:28 [GIT PATCH] TTY patches for 2.6.33-git Greg KH
` (46 preceding siblings ...)
2009-12-11 23:28 ` [PATCH 47/58] tty: moxa: Use more tty_port ops Greg Kroah-Hartman
@ 2009-12-11 23:28 ` Greg Kroah-Hartman
2009-12-11 23:28 ` [PATCH 49/58] tty: moxa: Locking clean up Greg Kroah-Hartman
` (10 subsequent siblings)
58 siblings, 0 replies; 100+ messages in thread
From: Greg Kroah-Hartman @ 2009-12-11 23:28 UTC (permalink / raw)
To: linux-kernel; +Cc: Alan Cox, Greg Kroah-Hartman
From: Alan Cox <alan@linux.intel.com>
Introduce a lock for moxafunc() to protect the cases where were get collisions
between two function requests at the same time.
Signed-off-by: Alan Cox <alan@linux.intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
---
drivers/char/moxa.c | 27 ++++++++++++++++++++++-----
1 files changed, 22 insertions(+), 5 deletions(-)
diff --git a/drivers/char/moxa.c b/drivers/char/moxa.c
index d8bcbed..474d936 100644
--- a/drivers/char/moxa.c
+++ b/drivers/char/moxa.c
@@ -248,9 +248,25 @@ static void moxa_wait_finish(void __iomem *ofsAddr)
static void moxafunc(void __iomem *ofsAddr, u16 cmd, u16 arg)
{
+ unsigned long flags;
+ spin_lock_irqsave(&moxafunc_lock, flags);
writew(arg, ofsAddr + FuncArg);
writew(cmd, ofsAddr + FuncCode);
moxa_wait_finish(ofsAddr);
+ spin_unlock_irqrestore(&moxafunc_lock, flags);
+}
+
+static int moxafuncret(void __iomem *ofsAddr, u16 cmd, u16 arg)
+{
+ unsigned long flags;
+ u16 ret;
+ spin_lock_irqsave(&moxafunc_lock, flags);
+ writew(arg, ofsAddr + FuncArg);
+ writew(cmd, ofsAddr + FuncCode);
+ moxa_wait_finish(ofsAddr);
+ ret = readw(ofsAddr + FuncArg);
+ spin_unlock_irqrestore(&moxafunc_lock, flags);
+ return ret;
}
static void moxa_low_water_check(void __iomem *ofsAddr)
@@ -417,6 +433,7 @@ static const struct tty_port_operations moxa_port_ops = {
static struct tty_driver *moxaDriver;
static DEFINE_TIMER(moxaTimer, moxa_poll, 0, 0);
static DEFINE_SPINLOCK(moxa_lock);
+static DEFINE_SPINLOCK(moxafunc_lock);
/*
* HW init
@@ -1823,10 +1840,12 @@ static int MoxaPortSetTermio(struct moxa_port *port, struct ktermios *termio,
baud = MoxaPortSetBaud(port, baud);
if (termio->c_iflag & (IXON | IXOFF | IXANY)) {
+ spin_lock_irq(&moxafunc_lock);
writeb(termio->c_cc[VSTART], ofsAddr + FuncArg);
writeb(termio->c_cc[VSTOP], ofsAddr + FuncArg1);
writeb(FC_SetXonXoff, ofsAddr + FuncCode);
moxa_wait_finish(ofsAddr);
+ spin_unlock_irqrestore(&moxafunc_lock);
}
return baud;
@@ -1879,12 +1898,10 @@ static int MoxaPortLineStatus(struct moxa_port *port)
int val;
ofsAddr = port->tableAddr;
- if (MOXA_IS_320(port->board)) {
- moxafunc(ofsAddr, FC_LineStatus, 0);
- val = readw(ofsAddr + FuncArg);
- } else {
+ if (MOXA_IS_320(port->board))
+ val = moxafuncret(ofsAddr, FC_LineStatus, 0);
+ else
val = readw(ofsAddr + FlagStat) >> 4;
- }
val &= 0x0B;
if (val & 8)
val |= 4;
--
1.6.5.5
^ permalink raw reply related [flat|nested] 100+ messages in thread* [PATCH 49/58] tty: moxa: Locking clean up
2009-12-11 23:28 [GIT PATCH] TTY patches for 2.6.33-git Greg KH
` (47 preceding siblings ...)
2009-12-11 23:28 ` [PATCH 48/58] tty: moxa: rework the locking a bit Greg Kroah-Hartman
@ 2009-12-11 23:28 ` Greg Kroah-Hartman
2009-12-11 23:28 ` [PATCH 50/58] tty: moxa: Kill off the throttle method Greg Kroah-Hartman
` (9 subsequent siblings)
58 siblings, 0 replies; 100+ messages in thread
From: Greg Kroah-Hartman @ 2009-12-11 23:28 UTC (permalink / raw)
To: linux-kernel; +Cc: Alan Cox, Greg Kroah-Hartman
From: Alan Cox <alan@linux.intel.com>
- The open lock is needed to fix up the case of a board reset occuring during
tty open but too early for a sane hangup response.
- The lock can however got for other cases
- Use the port mutex for get/setserial
- Fix up the confused lack of locking on the THROTTLE and other bits in the
private flags. Just use set/test/clear bit and it covers the cases we need
Signed-off-by: Alan Cox <alan@linux.intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
---
drivers/char/moxa.c | 58 ++++++++++++++++++++++-----------------------------
1 files changed, 25 insertions(+), 33 deletions(-)
diff --git a/drivers/char/moxa.c b/drivers/char/moxa.c
index 474d936..7ab720f 100644
--- a/drivers/char/moxa.c
+++ b/drivers/char/moxa.c
@@ -151,10 +151,10 @@ struct mon_str {
};
/* statusflags */
-#define TXSTOPPED 0x1
-#define LOWWAIT 0x2
-#define EMPTYWAIT 0x4
-#define THROTTLE 0x8
+#define TXSTOPPED 1
+#define LOWWAIT 2
+#define EMPTYWAIT 3
+#define THROTTLE 4
#define SERIAL_DO_RESTART
@@ -235,6 +235,8 @@ static void MoxaSetFifo(struct moxa_port *port, int enable);
* I/O functions
*/
+static DEFINE_SPINLOCK(moxafunc_lock);
+
static void moxa_wait_finish(void __iomem *ofsAddr)
{
unsigned long end = jiffies + moxaFuncTout;
@@ -381,14 +383,14 @@ copy:
break;
}
case TIOCGSERIAL:
- mutex_lock(&moxa_openlock);
+ mutex_lock(&ch->port.mutex);
ret = moxa_get_serial_info(ch, argp);
- mutex_unlock(&moxa_openlock);
+ mutex_unlock(&ch->port.mutex);
break;
case TIOCSSERIAL:
- mutex_lock(&moxa_openlock);
+ mutex_lock(&ch->port.mutex);
ret = moxa_set_serial_info(ch, argp);
- mutex_unlock(&moxa_openlock);
+ mutex_unlock(&ch->port.mutex);
break;
default:
ret = -ENOIOCTLCMD;
@@ -433,7 +435,6 @@ static const struct tty_port_operations moxa_port_ops = {
static struct tty_driver *moxaDriver;
static DEFINE_TIMER(moxaTimer, moxa_poll, 0, 0);
static DEFINE_SPINLOCK(moxa_lock);
-static DEFINE_SPINLOCK(moxafunc_lock);
/*
* HW init
@@ -1208,9 +1209,7 @@ static void moxa_close(struct tty_struct *tty, struct file *filp)
{
struct moxa_port *ch = tty->driver_data;
ch->cflag = tty->termios->c_cflag;
- mutex_lock(&moxa_openlock);
tty_port_close(&ch->port, tty, filp);
- mutex_unlock(&moxa_openlock);
}
static int moxa_write(struct tty_struct *tty,
@@ -1226,7 +1225,7 @@ static int moxa_write(struct tty_struct *tty,
len = MoxaPortWriteData(tty, buf, count);
spin_unlock_bh(&moxa_lock);
- ch->statusflags |= LOWWAIT;
+ set_bit(LOWWAIT, &ch->statusflags);
return len;
}
@@ -1264,7 +1263,7 @@ static int moxa_chars_in_buffer(struct tty_struct *tty)
* Make it possible to wakeup anything waiting for output
* in tty_ioctl.c, etc.
*/
- if (!(ch->statusflags & EMPTYWAIT))
+ if (!test_bit(EMPTYWAIT, &ch->statusflags))
moxa_setup_empty_event(tty);
}
unlock_kernel();
@@ -1332,14 +1331,14 @@ static void moxa_throttle(struct tty_struct *tty)
{
struct moxa_port *ch = tty->driver_data;
- ch->statusflags |= THROTTLE;
+ set_bit(THROTTLE, &ch->statusflags);
}
static void moxa_unthrottle(struct tty_struct *tty)
{
struct moxa_port *ch = tty->driver_data;
- ch->statusflags &= ~THROTTLE;
+ clear_bit(THROTTLE, &ch->statusflags);
}
static void moxa_set_termios(struct tty_struct *tty,
@@ -1361,7 +1360,7 @@ static void moxa_stop(struct tty_struct *tty)
if (ch == NULL)
return;
MoxaPortTxDisable(ch);
- ch->statusflags |= TXSTOPPED;
+ set_bit(TXSTOPPED, &ch->statusflags);
}
@@ -1376,17 +1375,13 @@ static void moxa_start(struct tty_struct *tty)
return;
MoxaPortTxEnable(ch);
- ch->statusflags &= ~TXSTOPPED;
+ clear_bit(TXSTOPPED, &ch->statusflags);
}
static void moxa_hangup(struct tty_struct *tty)
{
- struct moxa_port *ch;
-
- mutex_lock(&moxa_openlock);
- ch = tty->driver_data;
+ struct moxa_port *ch = tty->driver_data;
tty_port_hangup(&ch->port);
- mutex_unlock(&moxa_openlock);
}
static void moxa_new_dcdstate(struct moxa_port *p, u8 dcd)
@@ -1412,24 +1407,24 @@ static int moxa_poll_port(struct moxa_port *p, unsigned int handle,
u16 intr;
if (tty) {
- if ((p->statusflags & EMPTYWAIT) &&
+ if (test_bit(EMPTYWAIT, &p->statusflags) &&
MoxaPortTxQueue(p) == 0) {
- p->statusflags &= ~EMPTYWAIT;
+ clear_bit(EMPTYWAIT, &p->statusflags);
tty_wakeup(tty);
}
- if ((p->statusflags & LOWWAIT) && !tty->stopped &&
+ if (test_bit(LOWWAIT, &p->statusflags) && !tty->stopped &&
MoxaPortTxQueue(p) <= WAKEUP_CHARS) {
- p->statusflags &= ~LOWWAIT;
+ clear_bit(LOWWAIT, &p->statusflags);
tty_wakeup(tty);
}
- if (inited && !(p->statusflags & THROTTLE) &&
+ if (inited && !test_bit(THROTTLE, &p->statusflags) &&
MoxaPortRxQueue(p) > 0) { /* RX */
MoxaPortReadData(p);
tty_schedule_flip(tty);
}
} else {
- p->statusflags &= ~EMPTYWAIT;
+ clear_bit(EMPTYWAIT, &p->statusflags);
MoxaPortFlushData(p, 0); /* flush RX */
}
@@ -1533,10 +1528,7 @@ static void moxa_set_tty_param(struct tty_struct *tty, struct ktermios *old_term
static void moxa_setup_empty_event(struct tty_struct *tty)
{
struct moxa_port *ch = tty->driver_data;
-
- spin_lock_bh(&moxa_lock);
- ch->statusflags |= EMPTYWAIT;
- spin_unlock_bh(&moxa_lock);
+ set_bit(EMPTYWAIT, &ch->statusflags);
}
/*****************************************************************************
@@ -1845,7 +1837,7 @@ static int MoxaPortSetTermio(struct moxa_port *port, struct ktermios *termio,
writeb(termio->c_cc[VSTOP], ofsAddr + FuncArg1);
writeb(FC_SetXonXoff, ofsAddr + FuncCode);
moxa_wait_finish(ofsAddr);
- spin_unlock_irqrestore(&moxafunc_lock);
+ spin_unlock_irq(&moxafunc_lock);
}
return baud;
--
1.6.5.5
^ permalink raw reply related [flat|nested] 100+ messages in thread* [PATCH 50/58] tty: moxa: Kill off the throttle method
2009-12-11 23:28 [GIT PATCH] TTY patches for 2.6.33-git Greg KH
` (48 preceding siblings ...)
2009-12-11 23:28 ` [PATCH 49/58] tty: moxa: Locking clean up Greg Kroah-Hartman
@ 2009-12-11 23:28 ` Greg Kroah-Hartman
2009-12-11 23:28 ` [PATCH 51/58] tty: moxa: Fix modem op locking Greg Kroah-Hartman
` (8 subsequent siblings)
58 siblings, 0 replies; 100+ messages in thread
From: Greg Kroah-Hartman @ 2009-12-11 23:28 UTC (permalink / raw)
To: linux-kernel; +Cc: Alan Cox, Greg Kroah-Hartman
From: Alan Cox <alan@linux.intel.com>
The tty flag can be tested so the shadow flag isn't needed
Signed-off-by: Alan Cox <alan@linux.intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
---
drivers/char/moxa.c | 21 +--------------------
1 files changed, 1 insertions(+), 20 deletions(-)
diff --git a/drivers/char/moxa.c b/drivers/char/moxa.c
index 7ab720f..d180aa9 100644
--- a/drivers/char/moxa.c
+++ b/drivers/char/moxa.c
@@ -154,7 +154,6 @@ struct mon_str {
#define TXSTOPPED 1
#define LOWWAIT 2
#define EMPTYWAIT 3
-#define THROTTLE 4
#define SERIAL_DO_RESTART
@@ -194,8 +193,6 @@ static int moxa_write(struct tty_struct *, const unsigned char *, int);
static int moxa_write_room(struct tty_struct *);
static void moxa_flush_buffer(struct tty_struct *);
static int moxa_chars_in_buffer(struct tty_struct *);
-static void moxa_throttle(struct tty_struct *);
-static void moxa_unthrottle(struct tty_struct *);
static void moxa_set_termios(struct tty_struct *, struct ktermios *);
static void moxa_stop(struct tty_struct *);
static void moxa_start(struct tty_struct *);
@@ -415,8 +412,6 @@ static const struct tty_operations moxa_ops = {
.flush_buffer = moxa_flush_buffer,
.chars_in_buffer = moxa_chars_in_buffer,
.ioctl = moxa_ioctl,
- .throttle = moxa_throttle,
- .unthrottle = moxa_unthrottle,
.set_termios = moxa_set_termios,
.stop = moxa_stop,
.start = moxa_start,
@@ -1327,20 +1322,6 @@ static int moxa_tiocmset(struct tty_struct *tty, struct file *file,
return 0;
}
-static void moxa_throttle(struct tty_struct *tty)
-{
- struct moxa_port *ch = tty->driver_data;
-
- set_bit(THROTTLE, &ch->statusflags);
-}
-
-static void moxa_unthrottle(struct tty_struct *tty)
-{
- struct moxa_port *ch = tty->driver_data;
-
- clear_bit(THROTTLE, &ch->statusflags);
-}
-
static void moxa_set_termios(struct tty_struct *tty,
struct ktermios *old_termios)
{
@@ -1418,7 +1399,7 @@ static int moxa_poll_port(struct moxa_port *p, unsigned int handle,
tty_wakeup(tty);
}
- if (inited && !test_bit(THROTTLE, &p->statusflags) &&
+ if (inited && !test_bit(TTY_THROTTLED, &tty->flags) &&
MoxaPortRxQueue(p) > 0) { /* RX */
MoxaPortReadData(p);
tty_schedule_flip(tty);
--
1.6.5.5
^ permalink raw reply related [flat|nested] 100+ messages in thread* [PATCH 51/58] tty: moxa: Fix modem op locking
2009-12-11 23:28 [GIT PATCH] TTY patches for 2.6.33-git Greg KH
` (49 preceding siblings ...)
2009-12-11 23:28 ` [PATCH 50/58] tty: moxa: Kill off the throttle method Greg Kroah-Hartman
@ 2009-12-11 23:28 ` Greg Kroah-Hartman
2009-12-11 23:28 ` [PATCH 52/58] tty: moxa: Kill the use of lock_kernel Greg Kroah-Hartman
` (7 subsequent siblings)
58 siblings, 0 replies; 100+ messages in thread
From: Greg Kroah-Hartman @ 2009-12-11 23:28 UTC (permalink / raw)
To: linux-kernel; +Cc: Alan Cox, Greg Kroah-Hartman
From: Alan Cox <alan@linux.intel.com>
This is overkill and mostly not needed
Signed-off-by: Alan Cox <alan@linux.intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
---
drivers/char/moxa.c | 25 ++++++++++---------------
1 files changed, 10 insertions(+), 15 deletions(-)
diff --git a/drivers/char/moxa.c b/drivers/char/moxa.c
index d180aa9..ac06d01 100644
--- a/drivers/char/moxa.c
+++ b/drivers/char/moxa.c
@@ -139,7 +139,7 @@ struct moxa_port {
int cflag;
unsigned long statusflags;
- u8 DCDState;
+ u8 DCDState; /* Protected by the port lock */
u8 lineCtrl;
u8 lowChkFlag;
};
@@ -1141,9 +1141,9 @@ static int moxa_carrier_raised(struct tty_port *port)
struct moxa_port *ch = container_of(port, struct moxa_port, port);
int dcd;
- spin_lock_bh(&moxa_lock);
+ spin_lock_irq(&port->lock);
dcd = ch->DCDState;
- spin_unlock_bh(&moxa_lock);
+ spin_unlock_irq(&port->lock);
return dcd;
}
@@ -1267,16 +1267,9 @@ static int moxa_chars_in_buffer(struct tty_struct *tty)
static int moxa_tiocmget(struct tty_struct *tty, struct file *file)
{
- struct moxa_port *ch;
+ struct moxa_port *ch = tty->driver_data;
int flag = 0, dtr, rts;
- mutex_lock(&moxa_openlock);
- ch = tty->driver_data;
- if (!ch) {
- mutex_unlock(&moxa_openlock);
- return -EINVAL;
- }
-
MoxaPortGetLineOut(ch, &dtr, &rts);
if (dtr)
flag |= TIOCM_DTR;
@@ -1289,7 +1282,6 @@ static int moxa_tiocmget(struct tty_struct *tty, struct file *file)
flag |= TIOCM_DSR;
if (dtr & 4)
flag |= TIOCM_CD;
- mutex_unlock(&moxa_openlock);
return flag;
}
@@ -1368,15 +1360,20 @@ static void moxa_hangup(struct tty_struct *tty)
static void moxa_new_dcdstate(struct moxa_port *p, u8 dcd)
{
struct tty_struct *tty;
+ unsigned long flags;
dcd = !!dcd;
+ spin_lock_irqsave(&p->port.lock, flags);
if (dcd != p->DCDState) {
+ p->DCDState = dcd;
+ spin_unlock_irqrestore(&p->port.lock, flags);
tty = tty_port_tty_get(&p->port);
if (tty && C_CLOCAL(tty) && !dcd)
tty_hangup(tty);
tty_kref_put(tty);
}
- p->DCDState = dcd;
+ else
+ spin_unlock_irqrestore(&p->port.lock, flags);
}
static int moxa_poll_port(struct moxa_port *p, unsigned int handle,
@@ -1878,9 +1875,7 @@ static int MoxaPortLineStatus(struct moxa_port *port)
val &= 0x0B;
if (val & 8)
val |= 4;
- spin_lock_bh(&moxa_lock);
moxa_new_dcdstate(port, val & 8);
- spin_unlock_bh(&moxa_lock);
val &= 7;
return val;
}
--
1.6.5.5
^ permalink raw reply related [flat|nested] 100+ messages in thread* [PATCH 52/58] tty: moxa: Kill the use of lock_kernel
2009-12-11 23:28 [GIT PATCH] TTY patches for 2.6.33-git Greg KH
` (50 preceding siblings ...)
2009-12-11 23:28 ` [PATCH 51/58] tty: moxa: Fix modem op locking Greg Kroah-Hartman
@ 2009-12-11 23:28 ` Greg Kroah-Hartman
2009-12-11 23:28 ` [PATCH 53/58] tty: moxa: split open lock Greg Kroah-Hartman
` (6 subsequent siblings)
58 siblings, 0 replies; 100+ messages in thread
From: Greg Kroah-Hartman @ 2009-12-11 23:28 UTC (permalink / raw)
To: linux-kernel; +Cc: Alan Cox, Greg Kroah-Hartman
From: Alan Cox <alan@linux.intel.com>
It isn't needed here any more
Signed-off-by: Alan Cox <alan@linux.intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
---
drivers/char/moxa.c | 16 ++--------------
1 files changed, 2 insertions(+), 14 deletions(-)
diff --git a/drivers/char/moxa.c b/drivers/char/moxa.c
index ac06d01..d53fac5 100644
--- a/drivers/char/moxa.c
+++ b/drivers/char/moxa.c
@@ -34,7 +34,6 @@
#include <linux/tty.h>
#include <linux/tty_flip.h>
#include <linux/major.h>
-#include <linux/smp_lock.h>
#include <linux/string.h>
#include <linux/fcntl.h>
#include <linux/ptrace.h>
@@ -202,7 +201,6 @@ static int moxa_tiocmset(struct tty_struct *tty, struct file *file,
unsigned int set, unsigned int clear);
static void moxa_poll(unsigned long);
static void moxa_set_tty_param(struct tty_struct *, struct ktermios *);
-static void moxa_setup_empty_event(struct tty_struct *);
static void moxa_shutdown(struct tty_port *);
static int moxa_carrier_raised(struct tty_port *);
static void moxa_dtr_rts(struct tty_port *, int);
@@ -1251,17 +1249,13 @@ static int moxa_chars_in_buffer(struct tty_struct *tty)
struct moxa_port *ch = tty->driver_data;
int chars;
- lock_kernel();
chars = MoxaPortTxQueue(ch);
- if (chars) {
+ if (chars)
/*
* Make it possible to wakeup anything waiting for output
* in tty_ioctl.c, etc.
*/
- if (!test_bit(EMPTYWAIT, &ch->statusflags))
- moxa_setup_empty_event(tty);
- }
- unlock_kernel();
+ set_bit(EMPTYWAIT, &ch->statusflags);
return chars;
}
@@ -1503,12 +1497,6 @@ static void moxa_set_tty_param(struct tty_struct *tty, struct ktermios *old_term
tty_encode_baud_rate(tty, baud, baud);
}
-static void moxa_setup_empty_event(struct tty_struct *tty)
-{
- struct moxa_port *ch = tty->driver_data;
- set_bit(EMPTYWAIT, &ch->statusflags);
-}
-
/*****************************************************************************
* Driver level functions: *
*****************************************************************************/
--
1.6.5.5
^ permalink raw reply related [flat|nested] 100+ messages in thread* [PATCH 53/58] tty: moxa: split open lock
2009-12-11 23:28 [GIT PATCH] TTY patches for 2.6.33-git Greg KH
` (51 preceding siblings ...)
2009-12-11 23:28 ` [PATCH 52/58] tty: moxa: Kill the use of lock_kernel Greg Kroah-Hartman
@ 2009-12-11 23:28 ` Greg Kroah-Hartman
2009-12-11 23:28 ` [PATCH 54/58] tty: push the BKL down into the handlers a bit Greg Kroah-Hartman
` (5 subsequent siblings)
58 siblings, 0 replies; 100+ messages in thread
From: Greg Kroah-Hartman @ 2009-12-11 23:28 UTC (permalink / raw)
To: linux-kernel; +Cc: Alan Cox, Greg Kroah-Hartman
From: Alan Cox <alan@linux.intel.com>
moxa_openlock is used for several situations where we want to handle the
case of an ioctl that crosses many ports (not just the open tty), and also
cases where an open races a deinit (eg a pci unplug) and we hangup a port
before we can cope with that.
The non open race cases can use the moxa_lock spinlock. This simplifies sorting
out the remaining mess.
Signed-off-by: Alan Cox <alan@linux.intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
---
drivers/char/moxa.c | 23 +++++++++++------------
1 files changed, 11 insertions(+), 12 deletions(-)
diff --git a/drivers/char/moxa.c b/drivers/char/moxa.c
index d53fac5..63ee3bb 100644
--- a/drivers/char/moxa.c
+++ b/drivers/char/moxa.c
@@ -163,6 +163,7 @@ static struct mon_str moxaLog;
static unsigned int moxaFuncTout = HZ / 2;
static unsigned int moxaLowWaterChk;
static DEFINE_MUTEX(moxa_openlock);
+static DEFINE_SPINLOCK(moxa_lock);
/* Variables for insmod */
#ifdef MODULE
static unsigned long baseaddr[MAX_BOARDS];
@@ -313,22 +314,20 @@ static int moxa_ioctl(struct tty_struct *tty, struct file *file,
struct moxa_port *p;
unsigned int i, j;
- mutex_lock(&moxa_openlock);
for (i = 0; i < MAX_BOARDS; i++) {
p = moxa_boards[i].ports;
for (j = 0; j < MAX_PORTS_PER_BOARD; j++, p++, argm++) {
memset(&tmp, 0, sizeof(tmp));
+ spin_lock_bh(&moxa_lock);
if (moxa_boards[i].ready) {
tmp.inq = MoxaPortRxQueue(p);
tmp.outq = MoxaPortTxQueue(p);
}
- if (copy_to_user(argm, &tmp, sizeof(tmp))) {
- mutex_unlock(&moxa_openlock);
+ spin_unlock_bh(&moxa_lock);
+ if (copy_to_user(argm, &tmp, sizeof(tmp)))
return -EFAULT;
- }
}
}
- mutex_unlock(&moxa_openlock);
break;
} case MOXA_GET_OQUEUE:
status = MoxaPortTxQueue(ch);
@@ -344,16 +343,20 @@ static int moxa_ioctl(struct tty_struct *tty, struct file *file,
struct moxa_port *p;
unsigned int i, j;
- mutex_lock(&moxa_openlock);
for (i = 0; i < MAX_BOARDS; i++) {
p = moxa_boards[i].ports;
for (j = 0; j < MAX_PORTS_PER_BOARD; j++, p++, argm++) {
struct tty_struct *ttyp;
memset(&tmp, 0, sizeof(tmp));
- if (!moxa_boards[i].ready)
+ spin_lock_bh(&moxa_lock);
+ if (!moxa_boards[i].ready) {
+ spin_unlock_bh(&moxa_lock);
goto copy;
+ }
status = MoxaPortLineStatus(p);
+ spin_unlock_bh(&moxa_lock);
+
if (status & 1)
tmp.cts = 1;
if (status & 2)
@@ -368,13 +371,10 @@ static int moxa_ioctl(struct tty_struct *tty, struct file *file,
tmp.cflag = ttyp->termios->c_cflag;
tty_kref_put(tty);
copy:
- if (copy_to_user(argm, &tmp, sizeof(tmp))) {
- mutex_unlock(&moxa_openlock);
+ if (copy_to_user(argm, &tmp, sizeof(tmp)))
return -EFAULT;
- }
}
}
- mutex_unlock(&moxa_openlock);
break;
}
case TIOCGSERIAL:
@@ -427,7 +427,6 @@ static const struct tty_port_operations moxa_port_ops = {
static struct tty_driver *moxaDriver;
static DEFINE_TIMER(moxaTimer, moxa_poll, 0, 0);
-static DEFINE_SPINLOCK(moxa_lock);
/*
* HW init
--
1.6.5.5
^ permalink raw reply related [flat|nested] 100+ messages in thread* [PATCH 54/58] tty: push the BKL down into the handlers a bit
2009-12-11 23:28 [GIT PATCH] TTY patches for 2.6.33-git Greg KH
` (52 preceding siblings ...)
2009-12-11 23:28 ` [PATCH 53/58] tty: moxa: split open lock Greg Kroah-Hartman
@ 2009-12-11 23:28 ` Greg Kroah-Hartman
2009-12-11 23:28 ` [PATCH 55/58] tty: Push the lock down further into the ldisc code Greg Kroah-Hartman
` (4 subsequent siblings)
58 siblings, 0 replies; 100+ messages in thread
From: Greg Kroah-Hartman @ 2009-12-11 23:28 UTC (permalink / raw)
To: linux-kernel; +Cc: Alan Cox, Greg Kroah-Hartman
From: Alan Cox <alan@linux.intel.com>
Start trying to untangle the remaining BKL mess
Updated to fix missing unlock_kernel noted by Dan Carpenter
Signed-off-by: Alan "I must be out of my tree" Cox <alan@linux.intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
---
drivers/char/pty.c | 2 +-
drivers/char/tty_io.c | 141 ++++++++++++++++++++++++++--------------------
drivers/char/tty_ldisc.c | 13 ++++
include/linux/tty.h | 2 +-
4 files changed, 95 insertions(+), 63 deletions(-)
diff --git a/drivers/char/pty.c b/drivers/char/pty.c
index d86c0bc..385c44b 100644
--- a/drivers/char/pty.c
+++ b/drivers/char/pty.c
@@ -659,7 +659,7 @@ static int __ptmx_open(struct inode *inode, struct file *filp)
if (!retval)
return 0;
out1:
- tty_release_dev(filp);
+ tty_release(inode, filp);
return retval;
out:
devpts_kill_index(inode, index);
diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c
index 59499ee..1e24130 100644
--- a/drivers/char/tty_io.c
+++ b/drivers/char/tty_io.c
@@ -142,7 +142,6 @@ ssize_t redirected_tty_write(struct file *, const char __user *,
size_t, loff_t *);
static unsigned int tty_poll(struct file *, poll_table *);
static int tty_open(struct inode *, struct file *);
-static int tty_release(struct inode *, struct file *);
long tty_ioctl(struct file *file, unsigned int cmd, unsigned long arg);
#ifdef CONFIG_COMPAT
static long tty_compat_ioctl(struct file *file, unsigned int cmd,
@@ -1017,14 +1016,16 @@ out:
void tty_write_message(struct tty_struct *tty, char *msg)
{
- lock_kernel();
if (tty) {
mutex_lock(&tty->atomic_write_lock);
- if (tty->ops->write && !test_bit(TTY_CLOSING, &tty->flags))
+ lock_kernel();
+ if (tty->ops->write && !test_bit(TTY_CLOSING, &tty->flags)) {
+ unlock_kernel();
tty->ops->write(tty, msg, strlen(msg));
+ } else
+ unlock_kernel();
tty_write_unlock(tty);
}
- unlock_kernel();
return;
}
@@ -1202,14 +1203,21 @@ static int tty_driver_install_tty(struct tty_driver *driver,
struct tty_struct *tty)
{
int idx = tty->index;
+ int ret;
- if (driver->ops->install)
- return driver->ops->install(driver, tty);
+ if (driver->ops->install) {
+ lock_kernel();
+ ret = driver->ops->install(driver, tty);
+ unlock_kernel();
+ return ret;
+ }
if (tty_init_termios(tty) == 0) {
+ lock_kernel();
tty_driver_kref_get(driver);
tty->count++;
driver->ttys[idx] = tty;
+ unlock_kernel();
return 0;
}
return -ENOMEM;
@@ -1302,10 +1310,14 @@ struct tty_struct *tty_init_dev(struct tty_driver *driver, int idx,
struct tty_struct *tty;
int retval;
+ lock_kernel();
/* Check if pty master is being opened multiple times */
if (driver->subtype == PTY_TYPE_MASTER &&
- (driver->flags & TTY_DRIVER_DEVPTS_MEM) && !first_ok)
+ (driver->flags & TTY_DRIVER_DEVPTS_MEM) && !first_ok) {
+ unlock_kernel();
return ERR_PTR(-EIO);
+ }
+ unlock_kernel();
/*
* First time open is complex, especially for PTY devices.
@@ -1335,8 +1347,9 @@ struct tty_struct *tty_init_dev(struct tty_driver *driver, int idx,
* If we fail here just call release_tty to clean up. No need
* to decrement the use counts, as release_tty doesn't care.
*/
-
+ lock_kernel();
retval = tty_ldisc_setup(tty, tty->link);
+ unlock_kernel();
if (retval)
goto release_mem_out;
return tty;
@@ -1350,7 +1363,9 @@ release_mem_out:
if (printk_ratelimit())
printk(KERN_INFO "tty_init_dev: ldisc open failed, "
"clearing slot %d\n", idx);
+ lock_kernel();
release_tty(tty, idx);
+ unlock_kernel();
return ERR_PTR(retval);
}
@@ -1464,7 +1479,17 @@ static void release_tty(struct tty_struct *tty, int idx)
tty_kref_put(tty);
}
-/*
+/**
+ * tty_release - vfs callback for close
+ * @inode: inode of tty
+ * @filp: file pointer for handle to tty
+ *
+ * Called the last time each file handle is closed that references
+ * this tty. There may however be several such references.
+ *
+ * Locking:
+ * Takes bkl. See tty_release_dev
+ *
* Even releasing the tty structures is a tricky business.. We have
* to be very careful that the structures are all released at the
* same time, as interrupts might otherwise get the wrong pointers.
@@ -1472,20 +1497,20 @@ static void release_tty(struct tty_struct *tty, int idx)
* WSH 09/09/97: rewritten to avoid some nasty race conditions that could
* lead to double frees or releasing memory still in use.
*/
-void tty_release_dev(struct file *filp)
+
+int tty_release(struct inode *inode, struct file *filp)
{
struct tty_struct *tty, *o_tty;
int pty_master, tty_closing, o_tty_closing, do_sleep;
int devpts;
int idx;
char buf[64];
- struct inode *inode;
- inode = filp->f_path.dentry->d_inode;
tty = (struct tty_struct *)filp->private_data;
if (tty_paranoia_check(tty, inode, "tty_release_dev"))
- return;
+ return 0;
+ lock_kernel();
check_tty_count(tty, "tty_release_dev");
tty_fasync(-1, filp, 0);
@@ -1500,19 +1525,22 @@ void tty_release_dev(struct file *filp)
if (idx < 0 || idx >= tty->driver->num) {
printk(KERN_DEBUG "tty_release_dev: bad idx when trying to "
"free (%s)\n", tty->name);
- return;
+ unlock_kernel();
+ return 0;
}
if (!devpts) {
if (tty != tty->driver->ttys[idx]) {
+ unlock_kernel();
printk(KERN_DEBUG "tty_release_dev: driver.table[%d] not tty "
"for (%s)\n", idx, tty->name);
- return;
+ return 0;
}
if (tty->termios != tty->driver->termios[idx]) {
+ unlock_kernel();
printk(KERN_DEBUG "tty_release_dev: driver.termios[%d] not termios "
"for (%s)\n",
idx, tty->name);
- return;
+ return 0;
}
}
#endif
@@ -1526,26 +1554,30 @@ void tty_release_dev(struct file *filp)
if (tty->driver->other &&
!(tty->driver->flags & TTY_DRIVER_DEVPTS_MEM)) {
if (o_tty != tty->driver->other->ttys[idx]) {
+ unlock_kernel();
printk(KERN_DEBUG "tty_release_dev: other->table[%d] "
"not o_tty for (%s)\n",
idx, tty->name);
- return;
+ return 0 ;
}
if (o_tty->termios != tty->driver->other->termios[idx]) {
+ unlock_kernel();
printk(KERN_DEBUG "tty_release_dev: other->termios[%d] "
"not o_termios for (%s)\n",
idx, tty->name);
- return;
+ return 0;
}
if (o_tty->link != tty) {
+ unlock_kernel();
printk(KERN_DEBUG "tty_release_dev: bad pty pointers\n");
- return;
+ return 0;
}
}
#endif
if (tty->ops->close)
tty->ops->close(tty, filp);
+ unlock_kernel();
/*
* Sanity check: if tty->count is going to zero, there shouldn't be
* any waiters on tty->read_wait or tty->write_wait. We test the
@@ -1568,6 +1600,7 @@ void tty_release_dev(struct file *filp)
opens on /dev/tty */
mutex_lock(&tty_mutex);
+ lock_kernel();
tty_closing = tty->count <= 1;
o_tty_closing = o_tty &&
(o_tty->count <= (pty_master ? 1 : 0));
@@ -1598,6 +1631,7 @@ void tty_release_dev(struct file *filp)
printk(KERN_WARNING "tty_release_dev: %s: read/write wait queue "
"active!\n", tty_name(tty, buf));
+ unlock_kernel();
mutex_unlock(&tty_mutex);
schedule();
}
@@ -1661,8 +1695,10 @@ void tty_release_dev(struct file *filp)
mutex_unlock(&tty_mutex);
/* check whether both sides are closing ... */
- if (!tty_closing || (o_tty && !o_tty_closing))
- return;
+ if (!tty_closing || (o_tty && !o_tty_closing)) {
+ unlock_kernel();
+ return 0;
+ }
#ifdef TTY_DEBUG_HANGUP
printk(KERN_DEBUG "freeing tty structure...");
@@ -1680,10 +1716,12 @@ void tty_release_dev(struct file *filp)
/* Make this pty number available for reallocation */
if (devpts)
devpts_kill_index(inode, idx);
+ unlock_kernel();
+ return 0;
}
/**
- * __tty_open - open a tty device
+ * tty_open - open a tty device
* @inode: inode of device file
* @filp: file pointer to tty
*
@@ -1703,7 +1741,7 @@ void tty_release_dev(struct file *filp)
* ->siglock protects ->signal/->sighand
*/
-static int __tty_open(struct inode *inode, struct file *filp)
+static int tty_open(struct inode *inode, struct file *filp)
{
struct tty_struct *tty = NULL;
int noctty, retval;
@@ -1720,10 +1758,12 @@ retry_open:
retval = 0;
mutex_lock(&tty_mutex);
+ lock_kernel();
if (device == MKDEV(TTYAUX_MAJOR, 0)) {
tty = get_current_tty();
if (!tty) {
+ unlock_kernel();
mutex_unlock(&tty_mutex);
return -ENXIO;
}
@@ -1755,12 +1795,14 @@ retry_open:
goto got_driver;
}
}
+ unlock_kernel();
mutex_unlock(&tty_mutex);
return -ENODEV;
}
driver = get_tty_driver(device, &index);
if (!driver) {
+ unlock_kernel();
mutex_unlock(&tty_mutex);
return -ENODEV;
}
@@ -1770,6 +1812,7 @@ got_driver:
tty = tty_driver_lookup_tty(driver, inode, index);
if (IS_ERR(tty)) {
+ unlock_kernel();
mutex_unlock(&tty_mutex);
return PTR_ERR(tty);
}
@@ -1784,8 +1827,10 @@ got_driver:
mutex_unlock(&tty_mutex);
tty_driver_kref_put(driver);
- if (IS_ERR(tty))
+ if (IS_ERR(tty)) {
+ unlock_kernel();
return PTR_ERR(tty);
+ }
filp->private_data = tty;
file_move(filp, &tty->tty_files);
@@ -1813,11 +1858,15 @@ got_driver:
printk(KERN_DEBUG "error %d in opening %s...", retval,
tty->name);
#endif
- tty_release_dev(filp);
- if (retval != -ERESTARTSYS)
+ tty_release(inode, filp);
+ if (retval != -ERESTARTSYS) {
+ unlock_kernel();
return retval;
- if (signal_pending(current))
+ }
+ if (signal_pending(current)) {
+ unlock_kernel();
return retval;
+ }
schedule();
/*
* Need to reset f_op in case a hangup happened.
@@ -1826,8 +1875,11 @@ got_driver:
filp->f_op = &tty_fops;
goto retry_open;
}
+ unlock_kernel();
+
mutex_lock(&tty_mutex);
+ lock_kernel();
spin_lock_irq(¤t->sighand->siglock);
if (!noctty &&
current->signal->leader &&
@@ -1835,44 +1887,13 @@ got_driver:
tty->session == NULL)
__proc_set_tty(current, tty);
spin_unlock_irq(¤t->sighand->siglock);
+ unlock_kernel();
mutex_unlock(&tty_mutex);
return 0;
}
-/* BKL pushdown: scary code avoidance wrapper */
-static int tty_open(struct inode *inode, struct file *filp)
-{
- int ret;
-
- lock_kernel();
- ret = __tty_open(inode, filp);
- unlock_kernel();
- return ret;
-}
-
-
-/**
- * tty_release - vfs callback for close
- * @inode: inode of tty
- * @filp: file pointer for handle to tty
- *
- * Called the last time each file handle is closed that references
- * this tty. There may however be several such references.
- *
- * Locking:
- * Takes bkl. See tty_release_dev
- */
-
-static int tty_release(struct inode *inode, struct file *filp)
-{
- lock_kernel();
- tty_release_dev(filp);
- unlock_kernel();
- return 0;
-}
-
/**
* tty_poll - check tty status
* @filp: file being polled
@@ -2317,9 +2338,7 @@ static int tiocsetd(struct tty_struct *tty, int __user *p)
if (get_user(ldisc, p))
return -EFAULT;
- lock_kernel();
ret = tty_set_ldisc(tty, ldisc);
- unlock_kernel();
return ret;
}
diff --git a/drivers/char/tty_ldisc.c b/drivers/char/tty_ldisc.c
index feb5507..d914e77 100644
--- a/drivers/char/tty_ldisc.c
+++ b/drivers/char/tty_ldisc.c
@@ -34,6 +34,8 @@
#include <linux/vt_kern.h>
#include <linux/selection.h>
+#include <linux/smp_lock.h> /* For the moment */
+
#include <linux/kmod.h>
#include <linux/nsproxy.h>
@@ -545,6 +547,7 @@ int tty_set_ldisc(struct tty_struct *tty, int ldisc)
if (IS_ERR(new_ldisc))
return PTR_ERR(new_ldisc);
+ lock_kernel();
/*
* We need to look at the tty locking here for pty/tty pairs
* when both sides try to change in parallel.
@@ -558,6 +561,7 @@ int tty_set_ldisc(struct tty_struct *tty, int ldisc)
*/
if (tty->ldisc->ops->num == ldisc) {
+ unlock_kernel();
tty_ldisc_put(new_ldisc);
return 0;
}
@@ -569,6 +573,7 @@ int tty_set_ldisc(struct tty_struct *tty, int ldisc)
tty_wait_until_sent(tty, 0);
+ unlock_kernel();
mutex_lock(&tty->ldisc_mutex);
/*
@@ -582,6 +587,9 @@ int tty_set_ldisc(struct tty_struct *tty, int ldisc)
test_bit(TTY_LDISC_CHANGING, &tty->flags) == 0);
mutex_lock(&tty->ldisc_mutex);
}
+
+ lock_kernel();
+
set_bit(TTY_LDISC_CHANGING, &tty->flags);
/*
@@ -592,6 +600,8 @@ int tty_set_ldisc(struct tty_struct *tty, int ldisc)
tty->receive_room = 0;
o_ldisc = tty->ldisc;
+
+ unlock_kernel();
/*
* Make sure we don't change while someone holds a
* reference to the line discipline. The TTY_LDISC bit
@@ -617,12 +627,14 @@ int tty_set_ldisc(struct tty_struct *tty, int ldisc)
flush_scheduled_work();
mutex_lock(&tty->ldisc_mutex);
+ lock_kernel();
if (test_bit(TTY_HUPPED, &tty->flags)) {
/* We were raced by the hangup method. It will have stomped
the ldisc data and closed the ldisc down */
clear_bit(TTY_LDISC_CHANGING, &tty->flags);
mutex_unlock(&tty->ldisc_mutex);
tty_ldisc_put(new_ldisc);
+ unlock_kernel();
return -EIO;
}
@@ -664,6 +676,7 @@ int tty_set_ldisc(struct tty_struct *tty, int ldisc)
if (o_work)
schedule_delayed_work(&o_tty->buf.work, 1);
mutex_unlock(&tty->ldisc_mutex);
+ unlock_kernel();
return retval;
}
diff --git a/include/linux/tty.h b/include/linux/tty.h
index e6da667..405a903 100644
--- a/include/linux/tty.h
+++ b/include/linux/tty.h
@@ -449,7 +449,7 @@ extern void initialize_tty_struct(struct tty_struct *tty,
struct tty_driver *driver, int idx);
extern struct tty_struct *tty_init_dev(struct tty_driver *driver, int idx,
int first_ok);
-extern void tty_release_dev(struct file *filp);
+extern int tty_release(struct inode *inode, struct file *filp);
extern int tty_init_termios(struct tty_struct *tty);
extern struct tty_struct *tty_pair_get_tty(struct tty_struct *tty);
--
1.6.5.5
^ permalink raw reply related [flat|nested] 100+ messages in thread* [PATCH 55/58] tty: Push the lock down further into the ldisc code
2009-12-11 23:28 [GIT PATCH] TTY patches for 2.6.33-git Greg KH
` (53 preceding siblings ...)
2009-12-11 23:28 ` [PATCH 54/58] tty: push the BKL down into the handlers a bit Greg Kroah-Hartman
@ 2009-12-11 23:28 ` Greg Kroah-Hartman
2009-12-11 23:28 ` [PATCH 56/58] tty: Push the bkl down a bit in the hangup code Greg Kroah-Hartman
` (3 subsequent siblings)
58 siblings, 0 replies; 100+ messages in thread
From: Greg Kroah-Hartman @ 2009-12-11 23:28 UTC (permalink / raw)
To: linux-kernel; +Cc: Alan Cox, Greg Kroah-Hartman
From: Alan Cox <alan@linux.intel.com>
Signed-off-by: Alan Cox <alan@linux.intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
---
drivers/char/tty_io.c | 2 --
drivers/char/tty_ldisc.c | 12 +++++++++---
2 files changed, 9 insertions(+), 5 deletions(-)
diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c
index 1e24130..c408c81 100644
--- a/drivers/char/tty_io.c
+++ b/drivers/char/tty_io.c
@@ -1347,9 +1347,7 @@ struct tty_struct *tty_init_dev(struct tty_driver *driver, int idx,
* If we fail here just call release_tty to clean up. No need
* to decrement the use counts, as release_tty doesn't care.
*/
- lock_kernel();
retval = tty_ldisc_setup(tty, tty->link);
- unlock_kernel();
if (retval)
goto release_mem_out;
return tty;
diff --git a/drivers/char/tty_ldisc.c b/drivers/char/tty_ldisc.c
index d914e77..3f653f7 100644
--- a/drivers/char/tty_ldisc.c
+++ b/drivers/char/tty_ldisc.c
@@ -445,8 +445,14 @@ static void tty_set_termios_ldisc(struct tty_struct *tty, int num)
static int tty_ldisc_open(struct tty_struct *tty, struct tty_ldisc *ld)
{
WARN_ON(test_and_set_bit(TTY_LDISC_OPEN, &tty->flags));
- if (ld->ops->open)
- return ld->ops->open(tty);
+ if (ld->ops->open) {
+ int ret;
+ /* BKL here locks verus a hangup event */
+ lock_kernel();
+ ret = ld->ops->open(tty);
+ unlock_kernel();
+ return ret;
+ }
return 0;
}
@@ -566,6 +572,7 @@ int tty_set_ldisc(struct tty_struct *tty, int ldisc)
return 0;
}
+ unlock_kernel();
/*
* Problem: What do we do if this blocks ?
* We could deadlock here
@@ -573,7 +580,6 @@ int tty_set_ldisc(struct tty_struct *tty, int ldisc)
tty_wait_until_sent(tty, 0);
- unlock_kernel();
mutex_lock(&tty->ldisc_mutex);
/*
--
1.6.5.5
^ permalink raw reply related [flat|nested] 100+ messages in thread* [PATCH 56/58] tty: Push the bkl down a bit in the hangup code
2009-12-11 23:28 [GIT PATCH] TTY patches for 2.6.33-git Greg KH
` (54 preceding siblings ...)
2009-12-11 23:28 ` [PATCH 55/58] tty: Push the lock down further into the ldisc code Greg Kroah-Hartman
@ 2009-12-11 23:28 ` Greg Kroah-Hartman
2009-12-11 23:28 ` [PATCH 57/58] tty: Move the leader test in disassociate Greg Kroah-Hartman
` (2 subsequent siblings)
58 siblings, 0 replies; 100+ messages in thread
From: Greg Kroah-Hartman @ 2009-12-11 23:28 UTC (permalink / raw)
To: linux-kernel; +Cc: Alan Cox, Greg Kroah-Hartman
From: Alan Cox <alan@linux.intel.com>
We know that the redirect field is handled via its own locking in all
places
Signed-off-by: Alan Cox <alan@linux.intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
---
drivers/char/tty_io.c | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c
index c408c81..cc941a3 100644
--- a/drivers/char/tty_io.c
+++ b/drivers/char/tty_io.c
@@ -505,8 +505,6 @@ static void do_tty_hangup(struct work_struct *work)
if (!tty)
return;
- /* inuse_filps is protected by the single kernel lock */
- lock_kernel();
spin_lock(&redirect_lock);
if (redirect && redirect->private_data == tty) {
@@ -515,6 +513,8 @@ static void do_tty_hangup(struct work_struct *work)
}
spin_unlock(&redirect_lock);
+ /* inuse_filps is protected by the single kernel lock */
+ lock_kernel();
check_tty_count(tty, "do_tty_hangup");
file_list_lock();
/* This breaks for file handles being sent over AF_UNIX sockets ? */
--
1.6.5.5
^ permalink raw reply related [flat|nested] 100+ messages in thread* [PATCH 57/58] tty: Move the leader test in disassociate
2009-12-11 23:28 [GIT PATCH] TTY patches for 2.6.33-git Greg KH
` (55 preceding siblings ...)
2009-12-11 23:28 ` [PATCH 56/58] tty: Push the bkl down a bit in the hangup code Greg Kroah-Hartman
@ 2009-12-11 23:28 ` Greg Kroah-Hartman
2009-12-11 23:28 ` [PATCH 58/58] tty: split the lock up a bit further Greg Kroah-Hartman
2009-12-12 8:46 ` [GIT PATCH] TTY patches for 2.6.33-git Ingo Molnar
58 siblings, 0 replies; 100+ messages in thread
From: Greg Kroah-Hartman @ 2009-12-11 23:28 UTC (permalink / raw)
To: linux-kernel; +Cc: Alan Cox, Greg Kroah-Hartman
From: Alan Cox <alan@linux.intel.com>
There are two call points, both want to check that tty->signal->leader is
set. Move the test into disassociate_ctty() as that will make locking
changes easier in a bit
Signed-off-by: Alan Cox <alan@linux.intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
---
drivers/char/tty_io.c | 5 +++--
kernel/exit.c | 2 +-
2 files changed, 4 insertions(+), 3 deletions(-)
diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c
index cc941a3..a19fef2 100644
--- a/drivers/char/tty_io.c
+++ b/drivers/char/tty_io.c
@@ -707,6 +707,8 @@ void disassociate_ctty(int on_exit)
struct tty_struct *tty;
struct pid *tty_pgrp = NULL;
+ if (!current->signal->leader)
+ return;
tty = get_current_tty();
if (tty) {
@@ -772,8 +774,7 @@ void no_tty(void)
{
struct task_struct *tsk = current;
lock_kernel();
- if (tsk->signal->leader)
- disassociate_ctty(0);
+ disassociate_ctty(0);
unlock_kernel();
proc_clear_tty(tsk);
}
diff --git a/kernel/exit.c b/kernel/exit.c
index 1143012..6f50ef5 100644
--- a/kernel/exit.c
+++ b/kernel/exit.c
@@ -971,7 +971,7 @@ NORET_TYPE void do_exit(long code)
exit_thread();
cgroup_exit(tsk, 1);
- if (group_dead && tsk->signal->leader)
+ if (group_dead)
disassociate_ctty(1);
module_put(task_thread_info(tsk)->exec_domain->module);
--
1.6.5.5
^ permalink raw reply related [flat|nested] 100+ messages in thread* [PATCH 58/58] tty: split the lock up a bit further
2009-12-11 23:28 [GIT PATCH] TTY patches for 2.6.33-git Greg KH
` (56 preceding siblings ...)
2009-12-11 23:28 ` [PATCH 57/58] tty: Move the leader test in disassociate Greg Kroah-Hartman
@ 2009-12-11 23:28 ` Greg Kroah-Hartman
2009-12-12 8:46 ` [GIT PATCH] TTY patches for 2.6.33-git Ingo Molnar
58 siblings, 0 replies; 100+ messages in thread
From: Greg Kroah-Hartman @ 2009-12-11 23:28 UTC (permalink / raw)
To: linux-kernel; +Cc: Alan Cox, Greg Kroah-Hartman
From: Alan Cox <alan@linux.intel.com>
The tty count sanity check may need the BKL, that isn't clear. However it
is clear that the count use of the lock is internal and independant of the
bigger use of the lock.
Furthermore the file list locking is also separately locked already
Signed-off-by: Alan Cox <alan@linux.intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
---
drivers/char/tty_io.c | 3 +++
1 files changed, 3 insertions(+), 0 deletions(-)
diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c
index a19fef2..684f0e0 100644
--- a/drivers/char/tty_io.c
+++ b/drivers/char/tty_io.c
@@ -516,6 +516,8 @@ static void do_tty_hangup(struct work_struct *work)
/* inuse_filps is protected by the single kernel lock */
lock_kernel();
check_tty_count(tty, "do_tty_hangup");
+ unlock_kernel();
+
file_list_lock();
/* This breaks for file handles being sent over AF_UNIX sockets ? */
list_for_each_entry(filp, &tty->tty_files, f_u.fu_list) {
@@ -529,6 +531,7 @@ static void do_tty_hangup(struct work_struct *work)
}
file_list_unlock();
+ lock_kernel();
tty_ldisc_hangup(tty);
read_lock(&tasklist_lock);
--
1.6.5.5
^ permalink raw reply related [flat|nested] 100+ messages in thread* Re: [GIT PATCH] TTY patches for 2.6.33-git
2009-12-11 23:28 [GIT PATCH] TTY patches for 2.6.33-git Greg KH
` (57 preceding siblings ...)
2009-12-11 23:28 ` [PATCH 58/58] tty: split the lock up a bit further Greg Kroah-Hartman
@ 2009-12-12 8:46 ` Ingo Molnar
2009-12-12 9:39 ` Andrew Morton
2009-12-12 10:42 ` Alan Cox
58 siblings, 2 replies; 100+ messages in thread
From: Ingo Molnar @ 2009-12-12 8:46 UTC (permalink / raw)
To: Greg KH, Alan Cox, Thomas Gleixner, Peter Zijlstra
Cc: Linus Torvalds, Andrew Morton, linux-kernel
[-- Attachment #1: Type: text/plain, Size: 562 bytes --]
* Greg KH <gregkh@suse.de> wrote:
> Here's the big TTY patchset for your .33-git tree.
FYI, one of the changes in this tree is causing lockups on x86.
Config attached.
Possible suspects would one of these:
36ba782: tty: split the lock up a bit further
5ec93d1: tty: Move the leader test in disassociate
38c70b2: tty: Push the bkl down a bit in the hangup code
f18f949: tty: Push the lock down further into the ldisc code
eeb89d9: tty: push the BKL down into the handlers a bit
as they deal with locking details and are fresher than two weeks.
Ingo
[-- Attachment #2: config --]
[-- Type: text/plain, Size: 65406 bytes --]
#
# Automatically generated make config: don't edit
# Linux kernel version: 2.6.32
# Sat Dec 12 09:32:54 2009
#
# CONFIG_64BIT is not set
CONFIG_X86_32=y
# CONFIG_X86_64 is not set
CONFIG_X86=y
CONFIG_OUTPUT_FORMAT="elf32-i386"
CONFIG_ARCH_DEFCONFIG="arch/x86/configs/i386_defconfig"
CONFIG_GENERIC_TIME=y
CONFIG_GENERIC_CMOS_UPDATE=y
CONFIG_CLOCKSOURCE_WATCHDOG=y
CONFIG_GENERIC_CLOCKEVENTS=y
CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y
CONFIG_LOCKDEP_SUPPORT=y
CONFIG_STACKTRACE_SUPPORT=y
CONFIG_HAVE_LATENCYTOP_SUPPORT=y
CONFIG_MMU=y
CONFIG_ZONE_DMA=y
CONFIG_GENERIC_ISA_DMA=y
CONFIG_GENERIC_IOMAP=y
CONFIG_GENERIC_BUG=y
CONFIG_GENERIC_HWEIGHT=y
CONFIG_ARCH_MAY_HAVE_PC_FDC=y
# CONFIG_RWSEM_GENERIC_SPINLOCK is not set
CONFIG_RWSEM_XCHGADD_ALGORITHM=y
CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y
CONFIG_GENERIC_CALIBRATE_DELAY=y
# CONFIG_GENERIC_TIME_VSYSCALL is not set
CONFIG_ARCH_HAS_CPU_RELAX=y
CONFIG_ARCH_HAS_DEFAULT_IDLE=y
CONFIG_ARCH_HAS_CACHE_LINE_SIZE=y
CONFIG_HAVE_SETUP_PER_CPU_AREA=y
CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK=y
CONFIG_NEED_PER_CPU_PAGE_FIRST_CHUNK=y
# CONFIG_HAVE_CPUMASK_OF_CPU_MAP is not set
CONFIG_ARCH_HIBERNATION_POSSIBLE=y
CONFIG_ARCH_SUSPEND_POSSIBLE=y
# CONFIG_ZONE_DMA32 is not set
CONFIG_ARCH_POPULATES_NODE_MAP=y
# CONFIG_AUDIT_ARCH is not set
CONFIG_ARCH_SUPPORTS_OPTIMIZED_INLINING=y
CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y
CONFIG_GENERIC_HARDIRQS=y
CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
CONFIG_GENERIC_IRQ_PROBE=y
CONFIG_GENERIC_PENDING_IRQ=y
CONFIG_USE_GENERIC_SMP_HELPERS=y
CONFIG_X86_32_SMP=y
CONFIG_X86_HT=y
CONFIG_X86_TRAMPOLINE=y
CONFIG_KTIME_SCALAR=y
# CONFIG_BOOTPARAM_SUPPORT is not set
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
CONFIG_CONSTRUCTORS=y
#
# General setup
#
CONFIG_EXPERIMENTAL=y
# CONFIG_BROKEN_BOOT_ALLOWED3 is not set
CONFIG_LOCK_KERNEL=y
CONFIG_INIT_ENV_ARG_LIMIT=32
CONFIG_LOCALVERSION=""
CONFIG_LOCALVERSION_AUTO=y
CONFIG_HAVE_KERNEL_GZIP=y
CONFIG_HAVE_KERNEL_BZIP2=y
CONFIG_HAVE_KERNEL_LZMA=y
# CONFIG_KERNEL_GZIP is not set
CONFIG_KERNEL_BZIP2=y
# CONFIG_KERNEL_LZMA is not set
# CONFIG_SWAP is not set
# CONFIG_SYSVIPC is not set
CONFIG_POSIX_MQUEUE=y
# CONFIG_BSD_PROCESS_ACCT is not set
# CONFIG_TASKSTATS is not set
# CONFIG_AUDIT is not set
#
# RCU Subsystem
#
CONFIG_TREE_RCU=y
# CONFIG_TREE_PREEMPT_RCU is not set
# CONFIG_TINY_RCU is not set
CONFIG_RCU_TRACE=y
CONFIG_RCU_FANOUT=32
CONFIG_RCU_FANOUT_EXACT=y
CONFIG_TREE_RCU_TRACE=y
CONFIG_IKCONFIG=y
# CONFIG_IKCONFIG_PROC is not set
CONFIG_LOG_BUF_SHIFT=20
CONFIG_HAVE_UNSTABLE_SCHED_CLOCK=y
# CONFIG_GROUP_SCHED is not set
CONFIG_CGROUPS=y
CONFIG_CGROUP_DEBUG=y
# CONFIG_CGROUP_NS is not set
CONFIG_CGROUP_FREEZER=y
# CONFIG_CGROUP_DEVICE is not set
CONFIG_CPUSETS=y
CONFIG_PROC_PID_CPUSET=y
CONFIG_CGROUP_CPUACCT=y
# CONFIG_RESOURCE_COUNTERS is not set
CONFIG_SYSFS_DEPRECATED=y
CONFIG_SYSFS_DEPRECATED_V2=y
CONFIG_RELAY=y
CONFIG_NAMESPACES=y
CONFIG_UTS_NS=y
CONFIG_IPC_NS=y
# CONFIG_USER_NS is not set
# CONFIG_PID_NS is not set
CONFIG_NET_NS=y
# CONFIG_BLK_DEV_INITRD is not set
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
CONFIG_ANON_INODES=y
CONFIG_EMBEDDED=y
# CONFIG_UID16 is not set
CONFIG_KALLSYMS=y
CONFIG_KALLSYMS_ALL=y
CONFIG_KALLSYMS_EXTRA_PASS=y
CONFIG_HOTPLUG=y
CONFIG_PRINTK=y
CONFIG_BUG=y
CONFIG_ELF_CORE=y
CONFIG_PCSPKR_PLATFORM=y
CONFIG_BASE_FULL=y
CONFIG_FUTEX=y
# CONFIG_EPOLL is not set
# CONFIG_SIGNALFD is not set
# CONFIG_TIMERFD is not set
# CONFIG_EVENTFD is not set
CONFIG_SHMEM=y
CONFIG_AIO=y
CONFIG_HAVE_PERF_EVENTS=y
CONFIG_PERF_USE_VMALLOC=y
#
# Kernel Performance Events And Counters
#
CONFIG_PERF_EVENTS=y
CONFIG_EVENT_PROFILE=y
CONFIG_PERF_COUNTERS=y
CONFIG_DEBUG_PERF_USE_VMALLOC=y
# CONFIG_VM_EVENT_COUNTERS is not set
# CONFIG_PCI_QUIRKS is not set
CONFIG_SLUB_DEBUG=y
# CONFIG_COMPAT_BRK is not set
# CONFIG_SLAB is not set
CONFIG_SLUB=y
# CONFIG_SLOB is not set
CONFIG_PROFILING=y
CONFIG_TRACEPOINTS=y
CONFIG_OPROFILE=m
CONFIG_OPROFILE_IBS=y
# CONFIG_OPROFILE_EVENT_MULTIPLEX is not set
CONFIG_HAVE_OPROFILE=y
# CONFIG_KPROBES is not set
CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y
CONFIG_HAVE_IOREMAP_PROT=y
CONFIG_HAVE_KPROBES=y
CONFIG_HAVE_KRETPROBES=y
CONFIG_HAVE_ARCH_TRACEHOOK=y
CONFIG_HAVE_DMA_ATTRS=y
CONFIG_HAVE_DMA_API_DEBUG=y
CONFIG_HAVE_USER_RETURN_NOTIFIER=y
CONFIG_HAVE_HW_BREAKPOINT=y
#
# GCOV-based kernel profiling
#
CONFIG_SLOW_WORK=y
CONFIG_SLOW_WORK_DEBUG=y
CONFIG_HAVE_GENERIC_DMA_COHERENT=y
CONFIG_SLABINFO=y
CONFIG_RT_MUTEXES=y
CONFIG_BASE_SMALL=0
CONFIG_MODULES=y
# CONFIG_MODULE_FORCE_LOAD is not set
CONFIG_MODULE_UNLOAD=y
CONFIG_MODULE_FORCE_UNLOAD=y
# CONFIG_MODVERSIONS is not set
CONFIG_MODULE_SRCVERSION_ALL=y
CONFIG_STOP_MACHINE=y
CONFIG_BLOCK=y
# CONFIG_LBDAF is not set
# CONFIG_BLK_DEV_BSG is not set
CONFIG_BLK_DEV_INTEGRITY=y
# CONFIG_BLK_CGROUP is not set
#
# IO Schedulers
#
CONFIG_IOSCHED_NOOP=y
CONFIG_IOSCHED_DEADLINE=m
CONFIG_IOSCHED_CFQ=y
# CONFIG_CFQ_GROUP_IOSCHED is not set
# CONFIG_DEFAULT_DEADLINE is not set
CONFIG_DEFAULT_CFQ=y
# CONFIG_DEFAULT_NOOP is not set
CONFIG_DEFAULT_IOSCHED="cfq"
# CONFIG_INLINE_SPIN_TRYLOCK is not set
# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
# CONFIG_INLINE_SPIN_LOCK is not set
# CONFIG_INLINE_SPIN_LOCK_BH is not set
# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
# CONFIG_INLINE_SPIN_UNLOCK is not set
# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
# CONFIG_INLINE_SPIN_UNLOCK_IRQ is not set
# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
# CONFIG_INLINE_READ_TRYLOCK is not set
# CONFIG_INLINE_READ_LOCK is not set
# CONFIG_INLINE_READ_LOCK_BH is not set
# CONFIG_INLINE_READ_LOCK_IRQ is not set
# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
# CONFIG_INLINE_READ_UNLOCK is not set
# CONFIG_INLINE_READ_UNLOCK_BH is not set
# CONFIG_INLINE_READ_UNLOCK_IRQ is not set
# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
# CONFIG_INLINE_WRITE_TRYLOCK is not set
# CONFIG_INLINE_WRITE_LOCK is not set
# CONFIG_INLINE_WRITE_LOCK_BH is not set
# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
# CONFIG_INLINE_WRITE_UNLOCK is not set
# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
# CONFIG_INLINE_WRITE_UNLOCK_IRQ is not set
# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
# CONFIG_MUTEX_SPIN_ON_OWNER is not set
CONFIG_FREEZER=y
#
# Processor type and features
#
CONFIG_TICK_ONESHOT=y
CONFIG_NO_HZ=y
CONFIG_HIGH_RES_TIMERS=y
CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
CONFIG_SMP=y
CONFIG_X86_MPPARSE=y
CONFIG_X86_BIGSMP=y
# CONFIG_X86_EXTENDED_PLATFORM is not set
CONFIG_X86_SUPPORTS_MEMORY_FAILURE=y
# CONFIG_SCHED_OMIT_FRAME_POINTER is not set
CONFIG_PARAVIRT_GUEST=y
# CONFIG_VMI is not set
CONFIG_KVM_CLOCK=y
CONFIG_KVM_GUEST=y
# CONFIG_LGUEST_GUEST is not set
CONFIG_PARAVIRT=y
# CONFIG_PARAVIRT_SPINLOCKS is not set
CONFIG_PARAVIRT_CLOCK=y
CONFIG_PARAVIRT_DEBUG=y
CONFIG_MEMTEST=y
# CONFIG_M386 is not set
# CONFIG_M486 is not set
# CONFIG_M586 is not set
# CONFIG_M586TSC is not set
# CONFIG_M586MMX is not set
# CONFIG_M686 is not set
CONFIG_MPENTIUMII=y
# CONFIG_MPENTIUMIII is not set
# CONFIG_MPENTIUMM is not set
# CONFIG_MPENTIUM4 is not set
# CONFIG_MK6 is not set
# CONFIG_MK7 is not set
# CONFIG_MK8 is not set
# CONFIG_MCRUSOE is not set
# CONFIG_MEFFICEON is not set
# CONFIG_MWINCHIPC6 is not set
# CONFIG_MWINCHIP3D is not set
# CONFIG_MGEODEGX1 is not set
# CONFIG_MGEODE_LX is not set
# CONFIG_MCYRIXIII is not set
# CONFIG_MVIAC3_2 is not set
# CONFIG_MVIAC7 is not set
# CONFIG_MPSC is not set
# CONFIG_MCORE2 is not set
# CONFIG_MATOM is not set
# CONFIG_GENERIC_CPU is not set
# CONFIG_X86_GENERIC is not set
CONFIG_X86_CPU=y
CONFIG_X86_INTERNODE_CACHE_SHIFT=5
CONFIG_X86_CMPXCHG=y
CONFIG_X86_L1_CACHE_SHIFT=5
CONFIG_X86_XADD=y
CONFIG_X86_WP_WORKS_OK=y
CONFIG_X86_INVLPG=y
CONFIG_X86_BSWAP=y
CONFIG_X86_POPAD_OK=y
CONFIG_X86_INTEL_USERCOPY=y
CONFIG_X86_USE_PPRO_CHECKSUM=y
CONFIG_X86_TSC=y
CONFIG_X86_CMPXCHG64=y
CONFIG_X86_CMOV=y
CONFIG_X86_MINIMUM_CPU_FAMILY=5
CONFIG_X86_DEBUGCTLMSR=y
# CONFIG_PROCESSOR_SELECT is not set
CONFIG_CPU_SUP_INTEL=y
CONFIG_CPU_SUP_CYRIX_32=y
CONFIG_CPU_SUP_AMD=y
CONFIG_CPU_SUP_CENTAUR=y
CONFIG_CPU_SUP_TRANSMETA_32=y
CONFIG_CPU_SUP_UMC_32=y
# CONFIG_X86_DS is not set
CONFIG_HPET_TIMER=y
CONFIG_HPET_EMULATE_RTC=y
CONFIG_DMI=y
# CONFIG_IOMMU_HELPER is not set
# CONFIG_IOMMU_API is not set
CONFIG_NR_CPUS=32
# CONFIG_SCHED_SMT is not set
# CONFIG_SCHED_MC is not set
# CONFIG_PREEMPT_NONE is not set
CONFIG_PREEMPT_VOLUNTARY=y
# CONFIG_PREEMPT is not set
CONFIG_X86_LOCAL_APIC=y
CONFIG_X86_IO_APIC=y
CONFIG_X86_REROUTE_FOR_BROKEN_BOOT_IRQS=y
CONFIG_X86_MCE=y
CONFIG_X86_MCE_INTEL=y
# CONFIG_X86_MCE_AMD is not set
CONFIG_X86_ANCIENT_MCE=y
CONFIG_X86_MCE_THRESHOLD=y
# CONFIG_X86_MCE_INJECT is not set
CONFIG_X86_THERMAL_VECTOR=y
# CONFIG_VM86 is not set
CONFIG_I8K=y
CONFIG_X86_REBOOTFIXUPS=y
CONFIG_MICROCODE=m
CONFIG_MICROCODE_INTEL=y
CONFIG_MICROCODE_AMD=y
CONFIG_MICROCODE_OLD_INTERFACE=y
# CONFIG_X86_MSR is not set
CONFIG_X86_CPUID=m
CONFIG_X86_CPU_DEBUG=y
# CONFIG_NOHIGHMEM is not set
CONFIG_HIGHMEM4G=y
# CONFIG_HIGHMEM64G is not set
CONFIG_VMSPLIT_3G=y
# CONFIG_VMSPLIT_3G_OPT is not set
# CONFIG_VMSPLIT_2G is not set
# CONFIG_VMSPLIT_2G_OPT is not set
# CONFIG_VMSPLIT_1G is not set
CONFIG_PAGE_OFFSET=0xC0000000
CONFIG_HIGHMEM=y
# CONFIG_ARCH_PHYS_ADDR_T_64BIT is not set
CONFIG_ARCH_FLATMEM_ENABLE=y
CONFIG_ARCH_SPARSEMEM_ENABLE=y
CONFIG_ARCH_SELECT_MEMORY_MODEL=y
CONFIG_ILLEGAL_POINTER_VALUE=0
CONFIG_SELECT_MEMORY_MODEL=y
CONFIG_FLATMEM_MANUAL=y
# CONFIG_DISCONTIGMEM_MANUAL is not set
# CONFIG_SPARSEMEM_MANUAL is not set
CONFIG_FLATMEM=y
CONFIG_FLAT_NODE_MEM_MAP=y
CONFIG_SPARSEMEM_STATIC=y
CONFIG_PAGEFLAGS_EXTENDED=y
CONFIG_SPLIT_PTLOCK_CPUS=4
# CONFIG_PHYS_ADDR_T_64BIT is not set
CONFIG_ZONE_DMA_FLAG=1
CONFIG_BOUNCE=y
CONFIG_VIRT_TO_BUS=y
CONFIG_HAVE_MLOCK=y
CONFIG_HAVE_MLOCKED_PAGE_BIT=y
# CONFIG_KSM is not set
CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
CONFIG_ARCH_SUPPORTS_MEMORY_FAILURE=y
CONFIG_MEMORY_FAILURE=y
CONFIG_HWPOISON_INJECT=y
# CONFIG_HIGHPTE is not set
CONFIG_X86_CHECK_BIOS_CORRUPTION=y
CONFIG_X86_BOOTPARAM_MEMORY_CORRUPTION_CHECK=y
CONFIG_X86_RESERVE_LOW_64K=y
CONFIG_MATH_EMULATION=y
# CONFIG_MTRR is not set
CONFIG_SECCOMP=y
CONFIG_CC_STACKPROTECTOR=y
# CONFIG_HZ_100 is not set
CONFIG_HZ_250=y
# CONFIG_HZ_300 is not set
# CONFIG_HZ_1000 is not set
CONFIG_HZ=250
CONFIG_SCHED_HRTICK=y
# CONFIG_KEXEC is not set
# CONFIG_CRASH_DUMP is not set
CONFIG_PHYSICAL_START=0x1000000
# CONFIG_RELOCATABLE is not set
CONFIG_PHYSICAL_ALIGN=0x1000000
CONFIG_HOTPLUG_CPU=y
CONFIG_COMPAT_VDSO=y
CONFIG_CMDLINE_BOOL=y
CONFIG_CMDLINE=""
# CONFIG_CMDLINE_OVERRIDE is not set
CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
#
# Power management and ACPI options
#
CONFIG_PM=y
# CONFIG_PM_DEBUG is not set
CONFIG_PM_SLEEP_SMP=y
CONFIG_PM_SLEEP=y
CONFIG_SUSPEND=y
CONFIG_SUSPEND_FREEZER=y
CONFIG_PM_RUNTIME=y
# CONFIG_ACPI is not set
# CONFIG_SFI is not set
# CONFIG_APM is not set
#
# CPU Frequency scaling
#
CONFIG_CPU_FREQ=y
CONFIG_CPU_FREQ_TABLE=y
CONFIG_CPU_FREQ_DEBUG=y
CONFIG_CPU_FREQ_STAT=m
# CONFIG_CPU_FREQ_STAT_DETAILS is not set
# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set
# CONFIG_CPU_FREQ_DEFAULT_GOV_POWERSAVE is not set
# CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set
CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y
# CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE is not set
CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
# CONFIG_CPU_FREQ_GOV_POWERSAVE is not set
CONFIG_CPU_FREQ_GOV_USERSPACE=m
CONFIG_CPU_FREQ_GOV_ONDEMAND=y
# CONFIG_CPU_FREQ_GOV_CONSERVATIVE is not set
#
# CPUFreq processor drivers
#
# CONFIG_X86_POWERNOW_K6 is not set
CONFIG_X86_POWERNOW_K7=y
# CONFIG_X86_GX_SUSPMOD is not set
CONFIG_X86_SPEEDSTEP_CENTRINO=y
CONFIG_X86_SPEEDSTEP_CENTRINO_TABLE=y
CONFIG_X86_SPEEDSTEP_ICH=y
# CONFIG_X86_SPEEDSTEP_SMI is not set
CONFIG_X86_P4_CLOCKMOD=y
CONFIG_X86_CPUFREQ_NFORCE2=y
CONFIG_X86_LONGRUN=y
# CONFIG_X86_E_POWERSAVER is not set
#
# shared options
#
CONFIG_X86_SPEEDSTEP_LIB=y
CONFIG_X86_SPEEDSTEP_RELAXED_CAP_CHECK=y
CONFIG_CPU_IDLE=y
CONFIG_CPU_IDLE_GOV_LADDER=y
CONFIG_CPU_IDLE_GOV_MENU=y
#
# Bus options (PCI etc.)
#
CONFIG_PCI=y
# CONFIG_PCI_GOBIOS is not set
# CONFIG_PCI_GOMMCONFIG is not set
# CONFIG_PCI_GODIRECT is not set
# CONFIG_PCI_GOOLPC is not set
CONFIG_PCI_GOANY=y
CONFIG_PCI_BIOS=y
CONFIG_PCI_DIRECT=y
CONFIG_PCI_OLPC=y
CONFIG_PCI_DOMAINS=y
CONFIG_PCIEPORTBUS=y
CONFIG_HOTPLUG_PCI_PCIE=m
# CONFIG_PCIEAER is not set
# CONFIG_PCIEASPM is not set
CONFIG_ARCH_SUPPORTS_MSI=y
# CONFIG_PCI_MSI is not set
CONFIG_PCI_LEGACY=y
CONFIG_PCI_DEBUG=y
CONFIG_PCI_STUB=y
# CONFIG_HT_IRQ is not set
CONFIG_PCI_IOV=y
CONFIG_ISA_DMA_API=y
CONFIG_ISA=y
CONFIG_EISA=y
# CONFIG_EISA_VLB_PRIMING is not set
CONFIG_EISA_PCI_EISA=y
CONFIG_EISA_VIRTUAL_ROOT=y
CONFIG_EISA_NAMES=y
CONFIG_MCA=y
# CONFIG_MCA_LEGACY is not set
CONFIG_SCx200=y
# CONFIG_SCx200HR_TIMER is not set
CONFIG_OLPC=y
CONFIG_PCCARD=m
CONFIG_PCMCIA=m
CONFIG_PCMCIA_LOAD_CIS=y
# CONFIG_PCMCIA_IOCTL is not set
# CONFIG_CARDBUS is not set
#
# PC-card bridges
#
CONFIG_YENTA=m
CONFIG_YENTA_O2=y
CONFIG_YENTA_RICOH=y
# CONFIG_YENTA_TI is not set
CONFIG_YENTA_TOSHIBA=y
CONFIG_PD6729=m
CONFIG_I82092=m
# CONFIG_I82365 is not set
CONFIG_TCIC=m
CONFIG_PCMCIA_PROBE=y
CONFIG_PCCARD_NONSTATIC=m
CONFIG_HOTPLUG_PCI=m
CONFIG_HOTPLUG_PCI_FAKE=m
CONFIG_HOTPLUG_PCI_COMPAQ=m
CONFIG_HOTPLUG_PCI_COMPAQ_NVRAM=y
# CONFIG_HOTPLUG_PCI_IBM is not set
CONFIG_HOTPLUG_PCI_CPCI=y
CONFIG_HOTPLUG_PCI_CPCI_ZT5550=m
CONFIG_HOTPLUG_PCI_CPCI_GENERIC=m
# CONFIG_HOTPLUG_PCI_SHPC is not set
#
# Executable file formats / Emulations
#
CONFIG_BINFMT_ELF=y
# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
CONFIG_HAVE_AOUT=y
CONFIG_BINFMT_AOUT=y
CONFIG_BINFMT_MISC=m
CONFIG_HAVE_ATOMIC_IOMAP=y
CONFIG_NET=y
#
# Networking options
#
CONFIG_PACKET=y
# CONFIG_PACKET_MMAP is not set
CONFIG_UNIX=y
CONFIG_XFRM=y
CONFIG_XFRM_USER=y
CONFIG_XFRM_SUB_POLICY=y
# CONFIG_XFRM_MIGRATE is not set
CONFIG_XFRM_STATISTICS=y
CONFIG_XFRM_IPCOMP=y
CONFIG_NET_KEY=y
# CONFIG_NET_KEY_MIGRATE is not set
CONFIG_INET=y
CONFIG_IP_MULTICAST=y
# CONFIG_IP_ADVANCED_ROUTER is not set
CONFIG_IP_FIB_HASH=y
CONFIG_IP_PNP=y
CONFIG_IP_PNP_DHCP=y
CONFIG_IP_PNP_BOOTP=y
# CONFIG_IP_PNP_RARP is not set
CONFIG_NET_IPIP=m
CONFIG_NET_IPGRE=m
# CONFIG_NET_IPGRE_BROADCAST is not set
# CONFIG_IP_MROUTE is not set
CONFIG_ARPD=y
CONFIG_SYN_COOKIES=y
CONFIG_INET_AH=y
CONFIG_INET_ESP=y
CONFIG_INET_IPCOMP=y
CONFIG_INET_XFRM_TUNNEL=y
CONFIG_INET_TUNNEL=y
CONFIG_INET_XFRM_MODE_TRANSPORT=m
CONFIG_INET_XFRM_MODE_TUNNEL=y
# CONFIG_INET_XFRM_MODE_BEET is not set
CONFIG_INET_LRO=y
CONFIG_INET_DIAG=m
CONFIG_INET_TCP_DIAG=m
CONFIG_TCP_CONG_ADVANCED=y
CONFIG_TCP_CONG_BIC=m
# CONFIG_TCP_CONG_CUBIC is not set
# CONFIG_TCP_CONG_WESTWOOD is not set
CONFIG_TCP_CONG_HTCP=m
CONFIG_TCP_CONG_HSTCP=m
CONFIG_TCP_CONG_HYBLA=y
# CONFIG_TCP_CONG_VEGAS is not set
CONFIG_TCP_CONG_SCALABLE=y
CONFIG_TCP_CONG_LP=m
CONFIG_TCP_CONG_VENO=m
# CONFIG_TCP_CONG_YEAH is not set
CONFIG_TCP_CONG_ILLINOIS=m
# CONFIG_DEFAULT_BIC is not set
# CONFIG_DEFAULT_CUBIC is not set
# CONFIG_DEFAULT_HTCP is not set
# CONFIG_DEFAULT_VEGAS is not set
# CONFIG_DEFAULT_WESTWOOD is not set
CONFIG_DEFAULT_RENO=y
CONFIG_DEFAULT_TCP_CONG="reno"
CONFIG_TCP_MD5SIG=y
CONFIG_IPV6=y
CONFIG_IPV6_PRIVACY=y
# CONFIG_IPV6_ROUTER_PREF is not set
CONFIG_IPV6_OPTIMISTIC_DAD=y
CONFIG_INET6_AH=y
CONFIG_INET6_ESP=m
# CONFIG_INET6_IPCOMP is not set
# CONFIG_IPV6_MIP6 is not set
# CONFIG_INET6_XFRM_TUNNEL is not set
CONFIG_INET6_TUNNEL=y
# CONFIG_INET6_XFRM_MODE_TRANSPORT is not set
CONFIG_INET6_XFRM_MODE_TUNNEL=y
CONFIG_INET6_XFRM_MODE_BEET=m
CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION=m
CONFIG_IPV6_SIT=y
CONFIG_IPV6_SIT_6RD=y
CONFIG_IPV6_NDISC_NODETYPE=y
CONFIG_IPV6_TUNNEL=y
CONFIG_IPV6_MULTIPLE_TABLES=y
CONFIG_IPV6_SUBTREES=y
# CONFIG_IPV6_MROUTE is not set
CONFIG_NETLABEL=y
CONFIG_NETWORK_SECMARK=y
CONFIG_NETFILTER=y
CONFIG_NETFILTER_DEBUG=y
# CONFIG_NETFILTER_ADVANCED is not set
#
# Core Netfilter Configuration
#
CONFIG_NETFILTER_NETLINK=y
CONFIG_NETFILTER_NETLINK_LOG=y
# CONFIG_NF_CONNTRACK is not set
CONFIG_NETFILTER_XTABLES=y
CONFIG_NETFILTER_XT_TARGET_MARK=m
CONFIG_NETFILTER_XT_TARGET_NFLOG=y
CONFIG_NETFILTER_XT_TARGET_SECMARK=y
CONFIG_NETFILTER_XT_TARGET_TCPMSS=m
# CONFIG_NETFILTER_XT_MATCH_MARK is not set
# CONFIG_NETFILTER_XT_MATCH_POLICY is not set
CONFIG_IP_VS=y
# CONFIG_IP_VS_IPV6 is not set
CONFIG_IP_VS_DEBUG=y
CONFIG_IP_VS_TAB_BITS=12
#
# IPVS transport protocol load balancing support
#
# CONFIG_IP_VS_PROTO_TCP is not set
CONFIG_IP_VS_PROTO_UDP=y
CONFIG_IP_VS_PROTO_AH_ESP=y
CONFIG_IP_VS_PROTO_ESP=y
CONFIG_IP_VS_PROTO_AH=y
#
# IPVS scheduler
#
# CONFIG_IP_VS_RR is not set
CONFIG_IP_VS_WRR=m
CONFIG_IP_VS_LC=y
CONFIG_IP_VS_WLC=m
# CONFIG_IP_VS_LBLC is not set
CONFIG_IP_VS_LBLCR=y
# CONFIG_IP_VS_DH is not set
CONFIG_IP_VS_SH=y
CONFIG_IP_VS_SED=m
CONFIG_IP_VS_NQ=y
#
# IPVS application helper
#
#
# IP: Netfilter Configuration
#
# CONFIG_NF_DEFRAG_IPV4 is not set
CONFIG_IP_NF_IPTABLES=y
# CONFIG_IP_NF_FILTER is not set
CONFIG_IP_NF_TARGET_LOG=m
CONFIG_IP_NF_TARGET_ULOG=y
CONFIG_IP_NF_MANGLE=m
#
# IPv6: Netfilter Configuration
#
CONFIG_IP6_NF_IPTABLES=y
CONFIG_IP6_NF_MATCH_IPV6HEADER=m
CONFIG_IP6_NF_TARGET_LOG=m
# CONFIG_IP6_NF_FILTER is not set
# CONFIG_IP6_NF_MANGLE is not set
CONFIG_IP_DCCP=m
CONFIG_INET_DCCP_DIAG=m
#
# DCCP CCIDs Configuration (EXPERIMENTAL)
#
CONFIG_IP_DCCP_CCID2_DEBUG=y
CONFIG_IP_DCCP_CCID3=y
CONFIG_IP_DCCP_CCID3_DEBUG=y
CONFIG_IP_DCCP_CCID3_RTO=100
CONFIG_IP_DCCP_TFRC_LIB=y
CONFIG_IP_DCCP_TFRC_DEBUG=y
#
# DCCP Kernel Hacking
#
# CONFIG_IP_DCCP_DEBUG is not set
CONFIG_IP_SCTP=y
CONFIG_SCTP_DBG_MSG=y
# CONFIG_SCTP_DBG_OBJCNT is not set
# CONFIG_SCTP_HMAC_NONE is not set
# CONFIG_SCTP_HMAC_SHA1 is not set
CONFIG_SCTP_HMAC_MD5=y
CONFIG_RDS=m
# CONFIG_RDS_RDMA is not set
# CONFIG_RDS_TCP is not set
CONFIG_RDS_DEBUG=y
CONFIG_TIPC=m
CONFIG_TIPC_ADVANCED=y
CONFIG_TIPC_ZONES=3
CONFIG_TIPC_CLUSTERS=1
CONFIG_TIPC_NODES=255
CONFIG_TIPC_SLAVE_NODES=0
CONFIG_TIPC_PORTS=8191
CONFIG_TIPC_LOG=0
CONFIG_TIPC_DEBUG=y
# CONFIG_ATM is not set
CONFIG_STP=y
CONFIG_GARP=y
CONFIG_BRIDGE=y
# CONFIG_NET_DSA is not set
CONFIG_VLAN_8021Q=y
CONFIG_VLAN_8021Q_GVRP=y
CONFIG_DECNET=y
CONFIG_DECNET_ROUTER=y
CONFIG_LLC=y
CONFIG_LLC2=m
CONFIG_IPX=y
CONFIG_IPX_INTERN=y
CONFIG_ATALK=y
# CONFIG_DEV_APPLETALK is not set
# CONFIG_X25 is not set
CONFIG_LAPB=m
CONFIG_ECONET=m
CONFIG_ECONET_AUNUDP=y
CONFIG_ECONET_NATIVE=y
CONFIG_WAN_ROUTER=y
CONFIG_PHONET=y
CONFIG_IEEE802154=m
CONFIG_NET_SCHED=y
#
# Queueing/Scheduling
#
# CONFIG_NET_SCH_CBQ is not set
CONFIG_NET_SCH_HTB=m
# CONFIG_NET_SCH_HFSC is not set
CONFIG_NET_SCH_PRIO=m
CONFIG_NET_SCH_MULTIQ=m
CONFIG_NET_SCH_RED=m
# CONFIG_NET_SCH_SFQ is not set
CONFIG_NET_SCH_TEQL=y
CONFIG_NET_SCH_TBF=y
# CONFIG_NET_SCH_GRED is not set
CONFIG_NET_SCH_DSMARK=y
# CONFIG_NET_SCH_NETEM is not set
CONFIG_NET_SCH_DRR=m
CONFIG_NET_SCH_INGRESS=m
#
# Classification
#
CONFIG_NET_CLS=y
# CONFIG_NET_CLS_BASIC is not set
CONFIG_NET_CLS_TCINDEX=y
CONFIG_NET_CLS_ROUTE4=m
CONFIG_NET_CLS_ROUTE=y
CONFIG_NET_CLS_FW=y
# CONFIG_NET_CLS_U32 is not set
CONFIG_NET_CLS_RSVP=y
CONFIG_NET_CLS_RSVP6=y
CONFIG_NET_CLS_FLOW=y
# CONFIG_NET_CLS_CGROUP is not set
CONFIG_NET_EMATCH=y
CONFIG_NET_EMATCH_STACK=32
CONFIG_NET_EMATCH_CMP=y
CONFIG_NET_EMATCH_NBYTE=y
CONFIG_NET_EMATCH_U32=m
CONFIG_NET_EMATCH_META=y
# CONFIG_NET_EMATCH_TEXT is not set
CONFIG_NET_CLS_ACT=y
CONFIG_NET_ACT_POLICE=y
# CONFIG_NET_ACT_GACT is not set
CONFIG_NET_ACT_MIRRED=y
CONFIG_NET_ACT_IPT=m
CONFIG_NET_ACT_NAT=y
CONFIG_NET_ACT_PEDIT=y
CONFIG_NET_ACT_SIMP=m
# CONFIG_NET_ACT_SKBEDIT is not set
# CONFIG_NET_CLS_IND is not set
CONFIG_NET_SCH_FIFO=y
# CONFIG_DCB is not set
#
# Network testing
#
CONFIG_NET_PKTGEN=y
# CONFIG_NET_DROP_MONITOR is not set
CONFIG_HAMRADIO=y
#
# Packet Radio protocols
#
CONFIG_AX25=m
# CONFIG_AX25_DAMA_SLAVE is not set
CONFIG_NETROM=m
CONFIG_ROSE=m
#
# AX.25 network device drivers
#
CONFIG_MKISS=m
CONFIG_6PACK=m
CONFIG_BPQETHER=m
CONFIG_SCC=m
# CONFIG_SCC_DELAY is not set
CONFIG_SCC_TRXECHO=y
CONFIG_BAYCOM_SER_FDX=m
CONFIG_BAYCOM_SER_HDX=m
CONFIG_YAM=m
# CONFIG_CAN is not set
# CONFIG_IRDA is not set
# CONFIG_BT is not set
# CONFIG_AF_RXRPC is not set
CONFIG_FIB_RULES=y
CONFIG_WIRELESS=y
CONFIG_WIRELESS_EXT=y
CONFIG_WEXT_CORE=y
CONFIG_WEXT_PROC=y
CONFIG_WEXT_SPY=y
CONFIG_WEXT_PRIV=y
# CONFIG_CFG80211 is not set
# CONFIG_WIRELESS_EXT_SYSFS is not set
CONFIG_LIB80211=y
CONFIG_LIB80211_CRYPT_WEP=y
CONFIG_LIB80211_CRYPT_CCMP=y
CONFIG_LIB80211_CRYPT_TKIP=y
# CONFIG_LIB80211_DEBUG is not set
#
# CFG80211 needs to be enabled for MAC80211
#
CONFIG_WIMAX=m
CONFIG_WIMAX_DEBUG_LEVEL=8
# CONFIG_RFKILL is not set
#
# Device Drivers
#
#
# Generic Driver Options
#
CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
CONFIG_DEVTMPFS=y
CONFIG_STANDALONE=y
CONFIG_PREVENT_FIRMWARE_BUILD=y
CONFIG_FW_LOADER=y
CONFIG_FIRMWARE_IN_KERNEL=y
CONFIG_EXTRA_FIRMWARE=""
CONFIG_DEBUG_DRIVER=y
CONFIG_DEBUG_DEVRES=y
# CONFIG_SYS_HYPERVISOR is not set
CONFIG_CONNECTOR=m
# CONFIG_PARPORT is not set
# CONFIG_PNP is not set
CONFIG_BLK_DEV=y
# CONFIG_BLK_DEV_FD is not set
# CONFIG_BLK_DEV_XD is not set
CONFIG_BLK_CPQ_DA=y
CONFIG_BLK_CPQ_CISS_DA=y
CONFIG_CISS_SCSI_TAPE=y
CONFIG_BLK_DEV_DAC960=y
# CONFIG_BLK_DEV_UMEM is not set
# CONFIG_BLK_DEV_COW_COMMON is not set
# CONFIG_BLK_DEV_LOOP is not set
#
# DRBD disabled because PROC_FS, INET or CONNECTOR not selected
#
# CONFIG_BLK_DEV_DRBD is not set
CONFIG_BLK_DEV_NBD=m
# CONFIG_BLK_DEV_OSD is not set
CONFIG_BLK_DEV_SX8=y
CONFIG_BLK_DEV_UB=m
CONFIG_BLK_DEV_RAM=m
CONFIG_BLK_DEV_RAM_COUNT=16
CONFIG_BLK_DEV_RAM_SIZE=4096
CONFIG_BLK_DEV_XIP=y
CONFIG_CDROM_PKTCDVD=y
CONFIG_CDROM_PKTCDVD_BUFFERS=8
# CONFIG_CDROM_PKTCDVD_WCACHE is not set
# CONFIG_ATA_OVER_ETH is not set
CONFIG_VIRTIO_BLK=m
CONFIG_BLK_DEV_HD=y
CONFIG_MISC_DEVICES=y
CONFIG_IBM_ASM=y
CONFIG_PHANTOM=m
CONFIG_SGI_IOC4=m
CONFIG_TIFM_CORE=m
# CONFIG_TIFM_7XX1 is not set
CONFIG_ICS932S401=m
CONFIG_ENCLOSURE_SERVICES=m
CONFIG_HP_ILO=y
# CONFIG_DELL_LAPTOP is not set
CONFIG_ISL29003=m
# CONFIG_DS1682 is not set
CONFIG_C2PORT=m
CONFIG_C2PORT_DURAMAR_2150=m
#
# EEPROM support
#
CONFIG_EEPROM_AT24=m
# CONFIG_EEPROM_AT25 is not set
# CONFIG_EEPROM_LEGACY is not set
CONFIG_EEPROM_MAX6875=m
# CONFIG_EEPROM_93CX6 is not set
CONFIG_CB710_CORE=m
# CONFIG_CB710_DEBUG is not set
CONFIG_CB710_DEBUG_ASSUMPTIONS=y
CONFIG_IWMC3200TOP=m
CONFIG_IWMC3200TOP_DEBUG=y
CONFIG_IWMC3200TOP_DEBUGFS=y
CONFIG_HAVE_IDE=y
#
# SCSI device support
#
CONFIG_RAID_ATTRS=y
CONFIG_SCSI=y
CONFIG_SCSI_DMA=y
CONFIG_SCSI_TGT=y
CONFIG_SCSI_NETLINK=y
CONFIG_SCSI_PROC_FS=y
#
# SCSI support type (disk, tape, CD-ROM)
#
CONFIG_BLK_DEV_SD=y
CONFIG_CHR_DEV_ST=m
CONFIG_CHR_DEV_OSST=y
CONFIG_BLK_DEV_SR=m
# CONFIG_BLK_DEV_SR_VENDOR is not set
CONFIG_CHR_DEV_SG=m
CONFIG_CHR_DEV_SCH=m
# CONFIG_SCSI_ENCLOSURE is not set
CONFIG_SCSI_MULTI_LUN=y
# CONFIG_SCSI_CONSTANTS is not set
CONFIG_SCSI_LOGGING=y
# CONFIG_SCSI_SCAN_ASYNC is not set
CONFIG_SCSI_WAIT_SCAN=m
#
# SCSI Transports
#
CONFIG_SCSI_SPI_ATTRS=y
CONFIG_SCSI_FC_ATTRS=y
# CONFIG_SCSI_FC_TGT_ATTRS is not set
CONFIG_SCSI_ISCSI_ATTRS=y
CONFIG_SCSI_SAS_ATTRS=y
CONFIG_SCSI_SAS_LIBSAS=y
# CONFIG_SCSI_SAS_ATA is not set
CONFIG_SCSI_SAS_HOST_SMP=y
CONFIG_SCSI_SAS_LIBSAS_DEBUG=y
CONFIG_SCSI_SRP_ATTRS=m
# CONFIG_SCSI_SRP_TGT_ATTRS is not set
CONFIG_SCSI_LOWLEVEL=y
CONFIG_ISCSI_TCP=y
CONFIG_SCSI_CXGB3_ISCSI=y
CONFIG_SCSI_BNX2_ISCSI=y
CONFIG_BE2ISCSI=m
# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
CONFIG_SCSI_3W_9XXX=y
CONFIG_SCSI_3W_SAS=y
CONFIG_SCSI_7000FASST=y
CONFIG_SCSI_ACARD=y
CONFIG_SCSI_AHA152X=y
# CONFIG_SCSI_AHA1542 is not set
CONFIG_SCSI_AHA1740=y
CONFIG_SCSI_AACRAID=y
CONFIG_SCSI_AIC7XXX=y
CONFIG_AIC7XXX_CMDS_PER_DEVICE=32
CONFIG_AIC7XXX_RESET_DELAY_MS=5000
# CONFIG_AIC7XXX_DEBUG_ENABLE is not set
CONFIG_AIC7XXX_DEBUG_MASK=0
# CONFIG_AIC7XXX_REG_PRETTY_PRINT is not set
CONFIG_SCSI_AIC7XXX_OLD=y
CONFIG_SCSI_AIC79XX=y
CONFIG_AIC79XX_CMDS_PER_DEVICE=32
CONFIG_AIC79XX_RESET_DELAY_MS=5000
CONFIG_AIC79XX_DEBUG_ENABLE=y
CONFIG_AIC79XX_DEBUG_MASK=0
CONFIG_AIC79XX_REG_PRETTY_PRINT=y
# CONFIG_SCSI_AIC94XX is not set
# CONFIG_SCSI_MVSAS is not set
CONFIG_SCSI_DPT_I2O=m
CONFIG_SCSI_ADVANSYS=m
CONFIG_SCSI_IN2000=y
CONFIG_SCSI_ARCMSR=y
CONFIG_MEGARAID_NEWGEN=y
CONFIG_MEGARAID_MM=m
CONFIG_MEGARAID_MAILBOX=m
CONFIG_MEGARAID_LEGACY=y
CONFIG_MEGARAID_SAS=y
CONFIG_SCSI_MPT2SAS=m
CONFIG_SCSI_MPT2SAS_MAX_SGE=128
CONFIG_SCSI_MPT2SAS_LOGGING=y
# CONFIG_SCSI_HPTIOP is not set
CONFIG_SCSI_BUSLOGIC=m
# CONFIG_SCSI_FLASHPOINT is not set
CONFIG_VMWARE_PVSCSI=y
CONFIG_LIBFC=y
CONFIG_LIBFCOE=y
CONFIG_FCOE=y
# CONFIG_FCOE_FNIC is not set
CONFIG_SCSI_DMX3191D=y
# CONFIG_SCSI_DTC3280 is not set
CONFIG_SCSI_EATA=m
CONFIG_SCSI_EATA_TAGGED_QUEUE=y
CONFIG_SCSI_EATA_LINKED_COMMANDS=y
CONFIG_SCSI_EATA_MAX_TAGS=16
CONFIG_SCSI_FUTURE_DOMAIN=m
CONFIG_SCSI_GDTH=y
CONFIG_SCSI_GENERIC_NCR5380=m
CONFIG_SCSI_GENERIC_NCR5380_MMIO=y
CONFIG_SCSI_GENERIC_NCR53C400=y
CONFIG_SCSI_IBMMCA=m
CONFIG_IBMMCA_SCSI_ORDER_STANDARD=y
CONFIG_IBMMCA_SCSI_DEV_RESET=y
CONFIG_SCSI_IPS=m
CONFIG_SCSI_INITIO=y
# CONFIG_SCSI_INIA100 is not set
# CONFIG_SCSI_NCR53C406A is not set
CONFIG_SCSI_NCR_D700=y
CONFIG_SCSI_STEX=m
# CONFIG_SCSI_SYM53C8XX_2 is not set
CONFIG_SCSI_IPR=y
CONFIG_SCSI_IPR_TRACE=y
CONFIG_SCSI_IPR_DUMP=y
CONFIG_SCSI_NCR_Q720=y
CONFIG_SCSI_NCR53C8XX_DEFAULT_TAGS=8
CONFIG_SCSI_NCR53C8XX_MAX_TAGS=32
CONFIG_SCSI_NCR53C8XX_SYNC=20
# CONFIG_SCSI_PAS16 is not set
CONFIG_SCSI_QLOGIC_FAS=y
CONFIG_SCSI_QLOGIC_1280=y
# CONFIG_SCSI_QLA_FC is not set
CONFIG_SCSI_QLA_ISCSI=y
CONFIG_SCSI_LPFC=y
CONFIG_SCSI_LPFC_DEBUG_FS=y
CONFIG_SCSI_SIM710=y
CONFIG_SCSI_SYM53C416=y
CONFIG_SCSI_DC395x=y
# CONFIG_SCSI_DC390T is not set
CONFIG_SCSI_T128=m
CONFIG_SCSI_U14_34F=m
CONFIG_SCSI_U14_34F_TAGGED_QUEUE=y
CONFIG_SCSI_U14_34F_LINKED_COMMANDS=y
CONFIG_SCSI_U14_34F_MAX_TAGS=8
# CONFIG_SCSI_ULTRASTOR is not set
# CONFIG_SCSI_NSP32 is not set
# CONFIG_SCSI_PMCRAID is not set
CONFIG_SCSI_PM8001=y
CONFIG_SCSI_SRP=y
CONFIG_SCSI_BFA_FC=m
CONFIG_SCSI_LOWLEVEL_PCMCIA=y
CONFIG_PCMCIA_AHA152X=m
# CONFIG_PCMCIA_FDOMAIN is not set
# CONFIG_PCMCIA_NINJA_SCSI is not set
CONFIG_PCMCIA_QLOGIC=m
CONFIG_PCMCIA_SYM53C500=m
# CONFIG_SCSI_DH is not set
CONFIG_SCSI_OSD_INITIATOR=y
CONFIG_SCSI_OSD_ULD=m
CONFIG_SCSI_OSD_DPRINT_SENSE=1
CONFIG_SCSI_OSD_DEBUG=y
CONFIG_ATA=y
# CONFIG_ATA_NONSTANDARD is not set
CONFIG_ATA_VERBOSE_ERROR=y
# CONFIG_SATA_PMP is not set
CONFIG_SATA_AHCI=y
# CONFIG_SATA_SIL24 is not set
CONFIG_ATA_SFF=y
CONFIG_SATA_SVW=m
CONFIG_ATA_PIIX=y
# CONFIG_SATA_MV is not set
CONFIG_SATA_NV=y
CONFIG_PDC_ADMA=m
CONFIG_SATA_QSTOR=m
# CONFIG_SATA_PROMISE is not set
CONFIG_SATA_SX4=m
CONFIG_SATA_SIL=m
# CONFIG_SATA_SIS is not set
# CONFIG_SATA_ULI is not set
CONFIG_SATA_VIA=y
CONFIG_SATA_VITESSE=m
CONFIG_SATA_INIC162X=y
CONFIG_PATA_ALI=m
CONFIG_PATA_AMD=y
# CONFIG_PATA_ARTOP is not set
# CONFIG_PATA_ATP867X is not set
CONFIG_PATA_ATIIXP=m
CONFIG_PATA_CMD640_PCI=y
# CONFIG_PATA_CMD64X is not set
CONFIG_PATA_CS5520=y
CONFIG_PATA_CS5530=m
# CONFIG_PATA_CS5535 is not set
# CONFIG_PATA_CS5536 is not set
CONFIG_PATA_CYPRESS=m
# CONFIG_PATA_EFAR is not set
# CONFIG_ATA_GENERIC is not set
CONFIG_PATA_HPT366=m
CONFIG_PATA_HPT37X=m
CONFIG_PATA_HPT3X2N=y
# CONFIG_PATA_HPT3X3 is not set
CONFIG_PATA_IT821X=m
CONFIG_PATA_IT8213=y
# CONFIG_PATA_JMICRON is not set
# CONFIG_PATA_LEGACY is not set
CONFIG_PATA_TRIFLEX=y
CONFIG_PATA_MARVELL=y
# CONFIG_PATA_MPIIX is not set
CONFIG_PATA_OLDPIIX=y
# CONFIG_PATA_NETCELL is not set
# CONFIG_PATA_NINJA32 is not set
CONFIG_PATA_NS87410=m
# CONFIG_PATA_NS87415 is not set
# CONFIG_PATA_OPTI is not set
# CONFIG_PATA_OPTIDMA is not set
CONFIG_PATA_PCMCIA=m
CONFIG_PATA_PDC2027X=y
CONFIG_PATA_PDC_OLD=y
CONFIG_PATA_QDI=y
CONFIG_PATA_RADISYS=y
CONFIG_PATA_RDC=m
# CONFIG_PATA_RZ1000 is not set
# CONFIG_PATA_SC1200 is not set
# CONFIG_PATA_SERVERWORKS is not set
CONFIG_PATA_SIL680=m
CONFIG_PATA_SIS=m
CONFIG_PATA_TOSHIBA=y
# CONFIG_PATA_VIA is not set
CONFIG_PATA_WINBOND=m
# CONFIG_PATA_WINBOND_VLB is not set
CONFIG_PATA_PLATFORM=m
CONFIG_PATA_SCH=y
# CONFIG_MD is not set
CONFIG_FUSION=y
CONFIG_FUSION_SPI=y
# CONFIG_FUSION_FC is not set
CONFIG_FUSION_SAS=y
CONFIG_FUSION_MAX_SGE=128
CONFIG_FUSION_CTL=m
CONFIG_FUSION_LOGGING=y
#
# IEEE 1394 (FireWire) support
#
#
# You can enable one or both FireWire driver stacks.
#
#
# See the help texts for more information.
#
CONFIG_FIREWIRE=m
CONFIG_FIREWIRE_OHCI=m
CONFIG_FIREWIRE_OHCI_DEBUG=y
CONFIG_FIREWIRE_SBP2=m
CONFIG_FIREWIRE_NET=m
CONFIG_IEEE1394=m
CONFIG_IEEE1394_OHCI1394=m
CONFIG_IEEE1394_PCILYNX=m
CONFIG_IEEE1394_SBP2=m
CONFIG_IEEE1394_SBP2_PHYS_DMA=y
CONFIG_IEEE1394_ETH1394_ROM_ENTRY=y
CONFIG_IEEE1394_ETH1394=m
CONFIG_IEEE1394_RAWIO=m
CONFIG_IEEE1394_VIDEO1394=m
CONFIG_IEEE1394_DV1394=m
CONFIG_IEEE1394_VERBOSEDEBUG=y
CONFIG_I2O=m
# CONFIG_I2O_LCT_NOTIFY_ON_CHANGES is not set
CONFIG_I2O_EXT_ADAPTEC=y
CONFIG_I2O_CONFIG=m
CONFIG_I2O_CONFIG_OLD_IOCTL=y
# CONFIG_I2O_BUS is not set
CONFIG_I2O_BLOCK=m
# CONFIG_I2O_SCSI is not set
CONFIG_I2O_PROC=m
CONFIG_MACINTOSH_DRIVERS=y
# CONFIG_MAC_EMUMOUSEBTN is not set
CONFIG_NETDEVICES=y
CONFIG_IFB=m
CONFIG_DUMMY=m
CONFIG_BONDING=m
# CONFIG_MACVLAN is not set
# CONFIG_EQUALIZER is not set
CONFIG_TUN=m
CONFIG_VETH=y
# CONFIG_ARCNET is not set
CONFIG_PHYLIB=y
#
# MII PHY device drivers
#
CONFIG_MARVELL_PHY=m
CONFIG_DAVICOM_PHY=y
CONFIG_QSEMI_PHY=m
CONFIG_LXT_PHY=m
# CONFIG_CICADA_PHY is not set
CONFIG_VITESSE_PHY=y
CONFIG_SMSC_PHY=y
CONFIG_BROADCOM_PHY=y
CONFIG_ICPLUS_PHY=m
# CONFIG_REALTEK_PHY is not set
CONFIG_NATIONAL_PHY=y
# CONFIG_STE10XP is not set
CONFIG_LSI_ET1011C_PHY=y
CONFIG_FIXED_PHY=y
CONFIG_MDIO_BITBANG=m
CONFIG_NET_ETHERNET=y
CONFIG_MII=y
CONFIG_HAPPYMEAL=m
CONFIG_SUNGEM=y
CONFIG_CASSINI=m
CONFIG_NET_VENDOR_3COM=y
CONFIG_EL1=m
# CONFIG_EL2 is not set
CONFIG_ELPLUS=m
CONFIG_EL16=y
CONFIG_EL3=y
CONFIG_3C515=y
CONFIG_VORTEX=y
# CONFIG_TYPHOON is not set
# CONFIG_LANCE is not set
CONFIG_NET_VENDOR_SMC=y
CONFIG_ULTRAMCA=y
# CONFIG_ULTRA is not set
CONFIG_ULTRA32=y
CONFIG_SMC9194=m
CONFIG_ENC28J60=m
CONFIG_ENC28J60_WRITEVERIFY=y
# CONFIG_ETHOC is not set
# CONFIG_NET_VENDOR_RACAL is not set
CONFIG_DNET=y
# CONFIG_NET_TULIP is not set
CONFIG_AT1700=y
CONFIG_DEPCA=y
# CONFIG_HP100 is not set
CONFIG_NET_ISA=y
# CONFIG_E2100 is not set
# CONFIG_EWRK3 is not set
# CONFIG_EEXPRESS is not set
CONFIG_EEXPRESS_PRO=y
# CONFIG_HPLAN is not set
# CONFIG_LP486E is not set
CONFIG_ETH16I=y
CONFIG_NE2000=y
# CONFIG_ZNET is not set
# CONFIG_SEEQ8005 is not set
# CONFIG_IBMLANA is not set
# CONFIG_IBM_NEW_EMAC_ZMII is not set
# CONFIG_IBM_NEW_EMAC_RGMII is not set
# CONFIG_IBM_NEW_EMAC_TAH is not set
# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set
# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
CONFIG_NET_PCI=y
CONFIG_PCNET32=m
# CONFIG_AMD8111_ETH is not set
CONFIG_ADAPTEC_STARFIRE=y
CONFIG_AC3200=m
CONFIG_APRICOT=y
CONFIG_B44=y
CONFIG_B44_PCI_AUTOSELECT=y
CONFIG_B44_PCICORE_AUTOSELECT=y
CONFIG_B44_PCI=y
CONFIG_FORCEDETH=y
# CONFIG_FORCEDETH_NAPI is not set
CONFIG_CS89x0=m
CONFIG_E100=y
CONFIG_LNE390=m
CONFIG_FEALNX=m
# CONFIG_NATSEMI is not set
CONFIG_NE2K_PCI=y
# CONFIG_NE3210 is not set
CONFIG_ES3210=m
CONFIG_8139CP=y
CONFIG_8139TOO=y
CONFIG_8139TOO_PIO=y
CONFIG_8139TOO_TUNE_TWISTER=y
CONFIG_8139TOO_8129=y
CONFIG_8139_OLD_RX_RESET=y
CONFIG_R6040=m
# CONFIG_SIS900 is not set
CONFIG_EPIC100=y
CONFIG_SMSC9420=y
# CONFIG_SUNDANCE is not set
CONFIG_TLAN=y
CONFIG_KS8842=m
CONFIG_KS8851=m
CONFIG_KS8851_MLL=y
# CONFIG_VIA_RHINE is not set
CONFIG_SC92031=y
CONFIG_ATL2=y
CONFIG_NETDEV_1000=y
CONFIG_ACENIC=m
# CONFIG_ACENIC_OMIT_TIGON_I is not set
CONFIG_DL2K=y
CONFIG_E1000=y
CONFIG_E1000E=y
# CONFIG_IP1000 is not set
# CONFIG_IGB is not set
CONFIG_IGBVF=m
CONFIG_NS83820=y
CONFIG_HAMACHI=y
CONFIG_YELLOWFIN=m
CONFIG_R8169=m
# CONFIG_R8169_VLAN is not set
CONFIG_SIS190=m
# CONFIG_SKGE is not set
# CONFIG_SKY2 is not set
# CONFIG_VIA_VELOCITY is not set
CONFIG_TIGON3=y
CONFIG_BNX2=y
CONFIG_CNIC=y
CONFIG_QLA3XXX=y
CONFIG_ATL1=m
CONFIG_ATL1E=y
CONFIG_ATL1C=y
# CONFIG_JME is not set
CONFIG_NETDEV_10000=y
CONFIG_MDIO=y
# CONFIG_CHELSIO_T1 is not set
CONFIG_CHELSIO_T3_DEPENDS=y
CONFIG_CHELSIO_T3=y
# CONFIG_ENIC is not set
CONFIG_IXGBE=m
# CONFIG_IXGBE_DCA is not set
# CONFIG_IXGB is not set
# CONFIG_S2IO is not set
# CONFIG_MYRI10GE is not set
CONFIG_NIU=m
# CONFIG_MLX4_EN is not set
CONFIG_MLX4_CORE=m
CONFIG_MLX4_DEBUG=y
# CONFIG_TEHUTI is not set
# CONFIG_BNX2X is not set
CONFIG_QLGE=m
CONFIG_SFC=m
# CONFIG_BE2NET is not set
# CONFIG_TR is not set
CONFIG_WLAN=y
# CONFIG_PCMCIA_RAYCS is not set
# CONFIG_AIRO is not set
# CONFIG_ATMEL is not set
# CONFIG_AIRO_CS is not set
CONFIG_PCMCIA_WL3501=m
# CONFIG_PRISM54 is not set
CONFIG_USB_ZD1201=y
CONFIG_HOSTAP=y
CONFIG_HOSTAP_FIRMWARE=y
# CONFIG_HOSTAP_FIRMWARE_NVRAM is not set
CONFIG_HOSTAP_PLX=y
# CONFIG_HOSTAP_PCI is not set
CONFIG_HOSTAP_CS=m
#
# WiMAX Wireless Broadband devices
#
CONFIG_WIMAX_I2400M=m
CONFIG_WIMAX_I2400M_SDIO=m
CONFIG_WIMAX_IWMC3200_SDIO=y
CONFIG_WIMAX_I2400M_DEBUG_LEVEL=8
#
# USB Network Adapters
#
# CONFIG_USB_CATC is not set
# CONFIG_USB_KAWETH is not set
CONFIG_USB_PEGASUS=y
CONFIG_USB_RTL8150=m
# CONFIG_USB_USBNET is not set
# CONFIG_USB_CDC_PHONET is not set
CONFIG_NET_PCMCIA=y
CONFIG_PCMCIA_3C589=m
CONFIG_PCMCIA_3C574=m
CONFIG_PCMCIA_FMVJ18X=m
# CONFIG_PCMCIA_PCNET is not set
CONFIG_PCMCIA_NMCLAN=m
# CONFIG_PCMCIA_SMC91C92 is not set
CONFIG_PCMCIA_XIRC2PS=m
CONFIG_PCMCIA_AXNET=m
CONFIG_WAN=y
# CONFIG_HOSTESS_SV11 is not set
CONFIG_COSA=m
# CONFIG_LANMEDIA is not set
# CONFIG_SEALEVEL_4021 is not set
CONFIG_HDLC=m
CONFIG_HDLC_RAW=m
CONFIG_HDLC_RAW_ETH=m
# CONFIG_HDLC_CISCO is not set
CONFIG_HDLC_FR=m
CONFIG_HDLC_PPP=m
CONFIG_HDLC_X25=m
CONFIG_PCI200SYN=m
# CONFIG_WANXL is not set
# CONFIG_PC300TOO is not set
CONFIG_N2=m
# CONFIG_C101 is not set
# CONFIG_FARSYNC is not set
CONFIG_DSCC4=m
CONFIG_DSCC4_PCISYNC=y
CONFIG_DSCC4_PCI_RST=y
CONFIG_DLCI=y
CONFIG_DLCI_MAX=8
# CONFIG_SDLA is not set
# CONFIG_WAN_ROUTER_DRIVERS is not set
CONFIG_SBNI=m
CONFIG_SBNI_MULTILINE=y
CONFIG_IEEE802154_DRIVERS=m
# CONFIG_IEEE802154_FAKEHARD is not set
CONFIG_FDDI=m
# CONFIG_DEFXX is not set
CONFIG_SKFP=m
# CONFIG_HIPPI is not set
CONFIG_PPP=m
CONFIG_PPP_MULTILINK=y
# CONFIG_PPP_FILTER is not set
CONFIG_PPP_ASYNC=m
CONFIG_PPP_SYNC_TTY=m
# CONFIG_PPP_DEFLATE is not set
CONFIG_PPP_BSDCOMP=m
CONFIG_PPP_MPPE=m
# CONFIG_PPPOE is not set
CONFIG_PPPOL2TP=m
# CONFIG_SLIP is not set
CONFIG_SLHC=m
CONFIG_NET_FC=y
CONFIG_NETCONSOLE=y
CONFIG_NETCONSOLE_DYNAMIC=y
CONFIG_NETPOLL=y
CONFIG_NETPOLL_TRAP=y
CONFIG_NET_POLL_CONTROLLER=y
CONFIG_VIRTIO_NET=m
CONFIG_VMXNET3=m
CONFIG_ISDN=y
# CONFIG_ISDN_I4L is not set
CONFIG_ISDN_CAPI=m
# CONFIG_ISDN_DRV_AVMB1_VERBOSE_REASON is not set
CONFIG_CAPI_TRACE=y
CONFIG_ISDN_CAPI_MIDDLEWARE=y
CONFIG_ISDN_CAPI_CAPI20=m
CONFIG_ISDN_CAPI_CAPIFS_BOOL=y
CONFIG_ISDN_CAPI_CAPIFS=m
#
# CAPI hardware drivers
#
CONFIG_CAPI_AVM=y
# CONFIG_ISDN_DRV_AVMB1_B1ISA is not set
CONFIG_ISDN_DRV_AVMB1_B1PCI=m
CONFIG_ISDN_DRV_AVMB1_B1PCIV4=y
CONFIG_ISDN_DRV_AVMB1_T1ISA=m
CONFIG_ISDN_DRV_AVMB1_B1PCMCIA=m
CONFIG_ISDN_DRV_AVMB1_AVM_CS=m
# CONFIG_ISDN_DRV_AVMB1_T1PCI is not set
CONFIG_ISDN_DRV_AVMB1_C4=m
CONFIG_CAPI_EICON=y
# CONFIG_ISDN_DIVAS is not set
# CONFIG_ISDN_DRV_GIGASET is not set
CONFIG_PHONE=y
# CONFIG_PHONE_IXJ is not set
#
# Input device support
#
CONFIG_INPUT=y
# CONFIG_INPUT_FF_MEMLESS is not set
CONFIG_INPUT_POLLDEV=y
CONFIG_INPUT_SPARSEKMAP=m
#
# Userland interfaces
#
CONFIG_INPUT_MOUSEDEV=y
CONFIG_INPUT_MOUSEDEV_PSAUX=y
CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
# CONFIG_INPUT_JOYDEV is not set
# CONFIG_INPUT_EVDEV is not set
CONFIG_INPUT_EVBUG=y
#
# Input Device Drivers
#
CONFIG_INPUT_KEYBOARD=y
CONFIG_KEYBOARD_ADP5588=m
CONFIG_KEYBOARD_ATKBD=y
# CONFIG_QT2160 is not set
# CONFIG_KEYBOARD_LKKBD is not set
# CONFIG_KEYBOARD_MAX7359 is not set
CONFIG_KEYBOARD_NEWTON=y
# CONFIG_KEYBOARD_OPENCORES is not set
CONFIG_KEYBOARD_STOWAWAY=y
CONFIG_KEYBOARD_SUNKBD=y
CONFIG_KEYBOARD_XTKBD=m
CONFIG_INPUT_MOUSE=y
# CONFIG_MOUSE_PS2 is not set
CONFIG_MOUSE_SERIAL=m
# CONFIG_MOUSE_APPLETOUCH is not set
CONFIG_MOUSE_BCM5974=m
CONFIG_MOUSE_INPORT=y
CONFIG_MOUSE_ATIXL=y
CONFIG_MOUSE_LOGIBM=y
CONFIG_MOUSE_PC110PAD=y
# CONFIG_MOUSE_VSXXXAA is not set
CONFIG_MOUSE_SYNAPTICS_I2C=m
CONFIG_INPUT_JOYSTICK=y
CONFIG_JOYSTICK_ANALOG=m
CONFIG_JOYSTICK_A3D=m
CONFIG_JOYSTICK_ADI=m
# CONFIG_JOYSTICK_COBRA is not set
CONFIG_JOYSTICK_GF2K=m
CONFIG_JOYSTICK_GRIP=y
CONFIG_JOYSTICK_GRIP_MP=m
CONFIG_JOYSTICK_GUILLEMOT=m
CONFIG_JOYSTICK_INTERACT=y
CONFIG_JOYSTICK_SIDEWINDER=y
CONFIG_JOYSTICK_TMDC=y
# CONFIG_JOYSTICK_IFORCE is not set
CONFIG_JOYSTICK_WARRIOR=y
# CONFIG_JOYSTICK_MAGELLAN is not set
# CONFIG_JOYSTICK_SPACEORB is not set
CONFIG_JOYSTICK_SPACEBALL=y
CONFIG_JOYSTICK_STINGER=m
# CONFIG_JOYSTICK_TWIDJOY is not set
CONFIG_JOYSTICK_ZHENHUA=y
CONFIG_JOYSTICK_JOYDUMP=m
CONFIG_JOYSTICK_XPAD=y
# CONFIG_JOYSTICK_XPAD_FF is not set
CONFIG_INPUT_TABLET=y
CONFIG_TABLET_USB_ACECAD=y
CONFIG_TABLET_USB_AIPTEK=y
CONFIG_TABLET_USB_GTCO=y
CONFIG_TABLET_USB_KBTAB=m
CONFIG_TABLET_USB_WACOM=m
CONFIG_INPUT_TOUCHSCREEN=y
CONFIG_TOUCHSCREEN_ADS7846=y
# CONFIG_TOUCHSCREEN_AD7877 is not set
CONFIG_TOUCHSCREEN_AD7879_I2C=m
CONFIG_TOUCHSCREEN_AD7879=m
# CONFIG_TOUCHSCREEN_DYNAPRO is not set
# CONFIG_TOUCHSCREEN_EETI is not set
CONFIG_TOUCHSCREEN_FUJITSU=m
# CONFIG_TOUCHSCREEN_GUNZE is not set
CONFIG_TOUCHSCREEN_ELO=m
CONFIG_TOUCHSCREEN_WACOM_W8001=y
CONFIG_TOUCHSCREEN_MCS5000=m
CONFIG_TOUCHSCREEN_MTOUCH=y
CONFIG_TOUCHSCREEN_INEXIO=m
CONFIG_TOUCHSCREEN_MK712=m
# CONFIG_TOUCHSCREEN_HTCPEN is not set
CONFIG_TOUCHSCREEN_PENMOUNT=m
# CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set
CONFIG_TOUCHSCREEN_TOUCHWIN=m
CONFIG_TOUCHSCREEN_USB_COMPOSITE=m
CONFIG_TOUCHSCREEN_USB_EGALAX=y
CONFIG_TOUCHSCREEN_USB_PANJIT=y
CONFIG_TOUCHSCREEN_USB_3M=y
CONFIG_TOUCHSCREEN_USB_ITM=y
CONFIG_TOUCHSCREEN_USB_ETURBO=y
CONFIG_TOUCHSCREEN_USB_GUNZE=y
CONFIG_TOUCHSCREEN_USB_DMC_TSC10=y
CONFIG_TOUCHSCREEN_USB_IRTOUCH=y
CONFIG_TOUCHSCREEN_USB_IDEALTEK=y
# CONFIG_TOUCHSCREEN_USB_GENERAL_TOUCH is not set
CONFIG_TOUCHSCREEN_USB_GOTOP=y
CONFIG_TOUCHSCREEN_USB_JASTEC=y
CONFIG_TOUCHSCREEN_USB_E2I=y
# CONFIG_TOUCHSCREEN_USB_ZYTRONIC is not set
CONFIG_TOUCHSCREEN_USB_ETT_TC5UH=y
CONFIG_TOUCHSCREEN_TOUCHIT213=m
# CONFIG_TOUCHSCREEN_TSC2007 is not set
CONFIG_TOUCHSCREEN_PCAP=y
# CONFIG_INPUT_MISC is not set
#
# Hardware I/O ports
#
CONFIG_SERIO=y
CONFIG_SERIO_I8042=y
# CONFIG_SERIO_SERPORT is not set
CONFIG_SERIO_CT82C710=m
# CONFIG_SERIO_PCIPS2 is not set
CONFIG_SERIO_LIBPS2=y
CONFIG_SERIO_RAW=m
# CONFIG_SERIO_ALTERA_PS2 is not set
CONFIG_GAMEPORT=y
# CONFIG_GAMEPORT_NS558 is not set
CONFIG_GAMEPORT_L4=y
# CONFIG_GAMEPORT_EMU10K1 is not set
# CONFIG_GAMEPORT_FM801 is not set
#
# Character devices
#
CONFIG_VT=y
# CONFIG_CONSOLE_TRANSLATIONS is not set
CONFIG_VT_CONSOLE=y
CONFIG_HW_CONSOLE=y
CONFIG_VT_HW_CONSOLE_BINDING=y
CONFIG_DEVKMEM=y
CONFIG_SERIAL_NONSTANDARD=y
# CONFIG_COMPUTONE is not set
# CONFIG_ROCKETPORT is not set
CONFIG_CYCLADES=y
CONFIG_CYZ_INTR=y
# CONFIG_DIGIEPCA is not set
CONFIG_MOXA_INTELLIO=y
# CONFIG_MOXA_SMARTIO is not set
CONFIG_ISI=m
# CONFIG_SYNCLINK is not set
CONFIG_SYNCLINKMP=m
CONFIG_SYNCLINK_GT=m
CONFIG_N_HDLC=y
CONFIG_RISCOM8=y
CONFIG_SPECIALIX=m
# CONFIG_STALDRV is not set
# CONFIG_NOZOMI is not set
#
# Serial drivers
#
CONFIG_SERIAL_8250=y
CONFIG_SERIAL_8250_CONSOLE=y
CONFIG_FIX_EARLYCON_MEM=y
CONFIG_SERIAL_8250_PCI=y
CONFIG_SERIAL_8250_CS=m
CONFIG_SERIAL_8250_NR_UARTS=4
CONFIG_SERIAL_8250_RUNTIME_UARTS=4
CONFIG_SERIAL_8250_EXTENDED=y
# CONFIG_SERIAL_8250_MANY_PORTS is not set
CONFIG_SERIAL_8250_SHARE_IRQ=y
# CONFIG_SERIAL_8250_DETECT_IRQ is not set
# CONFIG_SERIAL_8250_RSA is not set
CONFIG_SERIAL_8250_MCA=m
#
# Non-8250 serial port support
#
CONFIG_SERIAL_MAX3100=y
CONFIG_SERIAL_CORE=y
CONFIG_SERIAL_CORE_CONSOLE=y
CONFIG_CONSOLE_POLL=y
CONFIG_SERIAL_JSM=m
CONFIG_UNIX98_PTYS=y
CONFIG_DEVPTS_MULTIPLE_INSTANCES=y
CONFIG_LEGACY_PTYS=y
CONFIG_LEGACY_PTY_COUNT=256
CONFIG_HVC_DRIVER=y
CONFIG_VIRTIO_CONSOLE=y
CONFIG_IPMI_HANDLER=m
CONFIG_IPMI_PANIC_EVENT=y
# CONFIG_IPMI_PANIC_STRING is not set
CONFIG_IPMI_DEVICE_INTERFACE=m
# CONFIG_IPMI_SI is not set
CONFIG_IPMI_WATCHDOG=m
CONFIG_IPMI_POWEROFF=m
CONFIG_HW_RANDOM=y
CONFIG_HW_RANDOM_TIMERIOMEM=m
CONFIG_HW_RANDOM_INTEL=y
CONFIG_HW_RANDOM_AMD=m
CONFIG_HW_RANDOM_GEODE=m
# CONFIG_HW_RANDOM_VIA is not set
# CONFIG_HW_RANDOM_VIRTIO is not set
CONFIG_NVRAM=y
CONFIG_DTLK=m
CONFIG_R3964=y
# CONFIG_APPLICOM is not set
CONFIG_SONYPI=y
#
# PCMCIA character devices
#
CONFIG_SYNCLINK_CS=m
# CONFIG_CARDMAN_4000 is not set
CONFIG_CARDMAN_4040=m
CONFIG_IPWIRELESS=m
# CONFIG_MWAVE is not set
# CONFIG_SCx200_GPIO is not set
# CONFIG_PC8736x_GPIO is not set
# CONFIG_NSC_GPIO is not set
# CONFIG_CS5535_GPIO is not set
CONFIG_RAW_DRIVER=m
CONFIG_MAX_RAW_DEVS=256
CONFIG_HANGCHECK_TIMER=y
CONFIG_TCG_TPM=m
CONFIG_TCG_NSC=m
CONFIG_TCG_ATMEL=m
# CONFIG_TELCLOCK is not set
CONFIG_DEVPORT=y
CONFIG_I2C=m
CONFIG_I2C_BOARDINFO=y
CONFIG_I2C_COMPAT=y
CONFIG_I2C_CHARDEV=m
CONFIG_I2C_HELPER_AUTO=y
CONFIG_I2C_ALGOBIT=m
CONFIG_I2C_ALGOPCA=m
#
# I2C Hardware Bus support
#
#
# PC SMBus host controller drivers
#
CONFIG_I2C_ALI1535=m
# CONFIG_I2C_ALI1563 is not set
CONFIG_I2C_ALI15X3=m
CONFIG_I2C_AMD756=m
CONFIG_I2C_AMD8111=m
# CONFIG_I2C_I801 is not set
CONFIG_I2C_ISCH=m
# CONFIG_I2C_PIIX4 is not set
CONFIG_I2C_NFORCE2=m
CONFIG_I2C_SIS5595=m
CONFIG_I2C_SIS630=m
# CONFIG_I2C_SIS96X is not set
# CONFIG_I2C_VIA is not set
CONFIG_I2C_VIAPRO=m
#
# I2C system bus drivers (mostly embedded / system-on-chip)
#
CONFIG_I2C_OCORES=m
CONFIG_I2C_SIMTEC=m
#
# External I2C/SMBus adapter drivers
#
# CONFIG_I2C_PARPORT_LIGHT is not set
# CONFIG_I2C_TAOS_EVM is not set
# CONFIG_I2C_TINY_USB is not set
#
# Other I2C/SMBus bus drivers
#
CONFIG_I2C_PCA_PLATFORM=m
CONFIG_I2C_STUB=m
# CONFIG_SCx200_ACB is not set
#
# Miscellaneous I2C Chip support
#
CONFIG_SENSORS_TSL2550=m
CONFIG_I2C_DEBUG_CORE=y
CONFIG_I2C_DEBUG_ALGO=y
# CONFIG_I2C_DEBUG_BUS is not set
CONFIG_I2C_DEBUG_CHIP=y
CONFIG_SPI=y
# CONFIG_SPI_DEBUG is not set
CONFIG_SPI_MASTER=y
#
# SPI Master Controller Drivers
#
CONFIG_SPI_BITBANG=y
#
# SPI Protocol Masters
#
CONFIG_SPI_SPIDEV=y
CONFIG_SPI_TLE62X0=y
#
# PPS support
#
# CONFIG_PPS is not set
CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
# CONFIG_GPIOLIB is not set
CONFIG_W1=y
CONFIG_W1_CON=y
#
# 1-wire Bus Masters
#
CONFIG_W1_MASTER_MATROX=y
CONFIG_W1_MASTER_DS2490=m
CONFIG_W1_MASTER_DS2482=m
#
# 1-wire Slaves
#
# CONFIG_W1_SLAVE_THERM is not set
# CONFIG_W1_SLAVE_SMEM is not set
CONFIG_W1_SLAVE_DS2431=y
CONFIG_W1_SLAVE_DS2433=y
CONFIG_W1_SLAVE_DS2433_CRC=y
CONFIG_W1_SLAVE_DS2760=y
# CONFIG_W1_SLAVE_BQ27000 is not set
CONFIG_POWER_SUPPLY=y
CONFIG_POWER_SUPPLY_DEBUG=y
# CONFIG_PDA_POWER is not set
CONFIG_BATTERY_DS2760=y
CONFIG_BATTERY_DS2782=m
# CONFIG_BATTERY_OLPC is not set
CONFIG_BATTERY_BQ27x00=m
# CONFIG_BATTERY_MAX17040 is not set
# CONFIG_CHARGER_PCF50633 is not set
# CONFIG_HWMON is not set
# CONFIG_THERMAL is not set
# CONFIG_WATCHDOG is not set
CONFIG_SSB_POSSIBLE=y
#
# Sonics Silicon Backplane
#
CONFIG_SSB=y
CONFIG_SSB_SPROM=y
CONFIG_SSB_PCIHOST_POSSIBLE=y
CONFIG_SSB_PCIHOST=y
# CONFIG_SSB_B43_PCI_BRIDGE is not set
# CONFIG_SSB_SILENT is not set
CONFIG_SSB_DEBUG=y
CONFIG_SSB_DRIVER_PCICORE_POSSIBLE=y
CONFIG_SSB_DRIVER_PCICORE=y
#
# Multifunction device drivers
#
CONFIG_MFD_CORE=y
# CONFIG_MFD_SM501 is not set
CONFIG_HTC_PASIC3=y
# CONFIG_MFD_TMIO is not set
CONFIG_MFD_WM8400=m
# CONFIG_MFD_WM831X is not set
CONFIG_MFD_PCF50633=m
# CONFIG_MFD_MC13783 is not set
# CONFIG_PCF50633_ADC is not set
CONFIG_PCF50633_GPIO=m
CONFIG_AB3100_CORE=m
CONFIG_AB3100_OTP=m
CONFIG_EZX_PCAP=y
CONFIG_REGULATOR=y
CONFIG_REGULATOR_DEBUG=y
CONFIG_REGULATOR_FIXED_VOLTAGE=m
# CONFIG_REGULATOR_VIRTUAL_CONSUMER is not set
# CONFIG_REGULATOR_USERSPACE_CONSUMER is not set
CONFIG_REGULATOR_BQ24022=m
# CONFIG_REGULATOR_MAX1586 is not set
CONFIG_REGULATOR_WM8400=m
# CONFIG_REGULATOR_PCF50633 is not set
CONFIG_REGULATOR_LP3971=m
CONFIG_REGULATOR_PCAP=m
CONFIG_REGULATOR_AB3100=m
CONFIG_REGULATOR_TPS65023=m
# CONFIG_REGULATOR_TPS6507X is not set
CONFIG_MEDIA_SUPPORT=m
#
# Multimedia core support
#
CONFIG_VIDEO_DEV=m
CONFIG_VIDEO_V4L2_COMMON=m
CONFIG_VIDEO_ALLOW_V4L1=y
CONFIG_VIDEO_V4L1_COMPAT=y
CONFIG_DVB_CORE=m
CONFIG_VIDEO_MEDIA=m
#
# Multimedia drivers
#
CONFIG_VIDEO_SAA7146=m
CONFIG_VIDEO_SAA7146_VV=m
CONFIG_MEDIA_ATTACH=y
CONFIG_MEDIA_TUNER=m
CONFIG_MEDIA_TUNER_CUSTOMISE=y
CONFIG_MEDIA_TUNER_SIMPLE=m
# CONFIG_MEDIA_TUNER_TDA8290 is not set
# CONFIG_MEDIA_TUNER_TDA827X is not set
CONFIG_MEDIA_TUNER_TDA18271=m
CONFIG_MEDIA_TUNER_TDA9887=m
CONFIG_MEDIA_TUNER_TEA5761=m
CONFIG_MEDIA_TUNER_TEA5767=m
CONFIG_MEDIA_TUNER_MT20XX=m
CONFIG_MEDIA_TUNER_MT2060=m
# CONFIG_MEDIA_TUNER_MT2266 is not set
# CONFIG_MEDIA_TUNER_MT2131 is not set
CONFIG_MEDIA_TUNER_QT1010=m
CONFIG_MEDIA_TUNER_XC2028=m
# CONFIG_MEDIA_TUNER_XC5000 is not set
# CONFIG_MEDIA_TUNER_MXL5005S is not set
CONFIG_MEDIA_TUNER_MXL5007T=m
# CONFIG_MEDIA_TUNER_MC44S803 is not set
CONFIG_VIDEO_V4L2=m
CONFIG_VIDEO_V4L1=m
CONFIG_VIDEOBUF_GEN=m
CONFIG_VIDEOBUF_DMA_SG=m
CONFIG_VIDEO_IR=m
# CONFIG_VIDEO_CAPTURE_DRIVERS is not set
CONFIG_RADIO_ADAPTERS=y
CONFIG_RADIO_CADET=m
CONFIG_RADIO_RTRACK2=m
# CONFIG_RADIO_AZTECH is not set
# CONFIG_RADIO_GEMTEK is not set
CONFIG_RADIO_GEMTEK_PCI=m
CONFIG_RADIO_MAXIRADIO=m
CONFIG_RADIO_MAESTRO=m
CONFIG_RADIO_SF16FMI=m
CONFIG_RADIO_SF16FMR2=m
CONFIG_RADIO_TERRATEC=m
CONFIG_RADIO_TRUST=m
CONFIG_RADIO_TYPHOON=m
# CONFIG_RADIO_ZOLTRIX is not set
CONFIG_I2C_SI4713=m
CONFIG_RADIO_SI4713=m
CONFIG_USB_DSBR=m
# CONFIG_RADIO_SI470X is not set
CONFIG_USB_MR800=m
CONFIG_RADIO_TEA5764=m
# CONFIG_RADIO_TEF6862 is not set
CONFIG_DVB_MAX_ADAPTERS=8
CONFIG_DVB_DYNAMIC_MINORS=y
CONFIG_DVB_CAPTURE_DRIVERS=y
#
# Supported SAA7146 based PCI Adapters
#
CONFIG_TTPCI_EEPROM=m
# CONFIG_DVB_AV7110 is not set
CONFIG_DVB_BUDGET_CORE=m
# CONFIG_DVB_BUDGET is not set
CONFIG_DVB_BUDGET_CI=m
CONFIG_DVB_BUDGET_AV=m
#
# Supported USB Adapters
#
# CONFIG_DVB_TTUSB_BUDGET is not set
CONFIG_DVB_TTUSB_DEC=m
CONFIG_SMS_SIANO_MDTV=m
#
# Siano module components
#
# CONFIG_SMS_USB_DRV is not set
CONFIG_SMS_SDIO_DRV=m
#
# Supported FlexCopII (B2C2) Adapters
#
CONFIG_DVB_B2C2_FLEXCOP=m
CONFIG_DVB_B2C2_FLEXCOP_PCI=m
CONFIG_DVB_B2C2_FLEXCOP_USB=m
CONFIG_DVB_B2C2_FLEXCOP_DEBUG=y
#
# Supported BT878 Adapters
#
#
# Supported Pluto2 Adapters
#
# CONFIG_DVB_PLUTO2 is not set
#
# Supported SDMC DM1105 Adapters
#
# CONFIG_DVB_DM1105 is not set
#
# Supported FireWire (IEEE 1394) Adapters
#
CONFIG_DVB_FIREDTV=m
CONFIG_DVB_FIREDTV_FIREWIRE=y
CONFIG_DVB_FIREDTV_IEEE1394=y
CONFIG_DVB_FIREDTV_INPUT=y
#
# Supported Earthsoft PT1 Adapters
#
CONFIG_DVB_PT1=m
#
# Supported DVB Frontends
#
# CONFIG_DVB_FE_CUSTOMISE is not set
CONFIG_DVB_STB0899=m
CONFIG_DVB_STB6100=m
CONFIG_DVB_CX24123=m
CONFIG_DVB_MT312=m
CONFIG_DVB_S5H1420=m
CONFIG_DVB_STV0299=m
CONFIG_DVB_TDA8261=m
CONFIG_DVB_TUNER_ITD1000=m
CONFIG_DVB_TUNER_CX24113=m
CONFIG_DVB_TUA6100=m
CONFIG_DVB_TDA1004X=m
CONFIG_DVB_MT352=m
CONFIG_DVB_TDA10021=m
CONFIG_DVB_TDA10023=m
CONFIG_DVB_STV0297=m
CONFIG_DVB_NXT200X=m
CONFIG_DVB_BCM3510=m
CONFIG_DVB_LGDT330X=m
CONFIG_DVB_PLL=m
CONFIG_DVB_LNBP21=m
CONFIG_DVB_ISL6421=m
CONFIG_DAB=y
CONFIG_USB_DABUSB=m
#
# Graphics support
#
# CONFIG_AGP is not set
# CONFIG_VGA_ARB is not set
# CONFIG_DRM is not set
# CONFIG_VGASTATE is not set
CONFIG_VIDEO_OUTPUT_CONTROL=y
# CONFIG_FB is not set
CONFIG_BACKLIGHT_LCD_SUPPORT=y
# CONFIG_LCD_CLASS_DEVICE is not set
CONFIG_BACKLIGHT_CLASS_DEVICE=y
CONFIG_BACKLIGHT_GENERIC=m
CONFIG_BACKLIGHT_PROGEAR=y
# CONFIG_BACKLIGHT_MBP_NVIDIA is not set
CONFIG_BACKLIGHT_SAHARA=m
#
# Display device support
#
CONFIG_DISPLAY_SUPPORT=m
#
# Display hardware drivers
#
#
# Console display driver support
#
CONFIG_VGA_CONSOLE=y
CONFIG_VGACON_SOFT_SCROLLBACK=y
CONFIG_VGACON_SOFT_SCROLLBACK_SIZE=64
CONFIG_DUMMY_CONSOLE=y
CONFIG_FONT_8x16=y
# CONFIG_SOUND is not set
# CONFIG_HID_SUPPORT is not set
CONFIG_USB_MOUSE=y
CONFIG_USB_SUPPORT=y
CONFIG_USB_ARCH_HAS_HCD=y
CONFIG_USB_ARCH_HAS_OHCI=y
CONFIG_USB_ARCH_HAS_EHCI=y
CONFIG_USB=y
# CONFIG_USB_DEBUG is not set
CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
#
# Miscellaneous USB options
#
CONFIG_USB_DEVICEFS=y
CONFIG_USB_DEVICE_CLASS=y
CONFIG_USB_DYNAMIC_MINORS=y
CONFIG_USB_SUSPEND=y
# CONFIG_USB_OTG is not set
# CONFIG_USB_OTG_WHITELIST is not set
# CONFIG_USB_OTG_BLACKLIST_HUB is not set
CONFIG_USB_MON=y
CONFIG_USB_WUSB=m
CONFIG_USB_WUSB_CBAF=m
CONFIG_USB_WUSB_CBAF_DEBUG=y
#
# USB Host Controller Drivers
#
# CONFIG_USB_C67X00_HCD is not set
# CONFIG_USB_XHCI_HCD is not set
CONFIG_USB_EHCI_HCD=y
CONFIG_USB_EHCI_ROOT_HUB_TT=y
CONFIG_USB_EHCI_TT_NEWSCHED=y
# CONFIG_USB_OXU210HP_HCD is not set
CONFIG_USB_ISP116X_HCD=y
CONFIG_USB_ISP1760_HCD=m
CONFIG_USB_ISP1362_HCD=m
CONFIG_USB_OHCI_HCD=y
# CONFIG_USB_OHCI_HCD_SSB is not set
# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set
# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set
CONFIG_USB_OHCI_LITTLE_ENDIAN=y
CONFIG_USB_UHCI_HCD=y
CONFIG_USB_SL811_HCD=m
CONFIG_USB_SL811_CS=m
CONFIG_USB_R8A66597_HCD=y
CONFIG_USB_HWA_HCD=m
#
# USB Device Class drivers
#
CONFIG_USB_ACM=m
# CONFIG_USB_PRINTER is not set
CONFIG_USB_WDM=m
CONFIG_USB_TMC=m
#
# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
#
#
# also be needed; see USB_STORAGE Help for more info
#
# CONFIG_USB_STORAGE is not set
CONFIG_USB_LIBUSUAL=y
#
# USB Imaging devices
#
# CONFIG_USB_MDC800 is not set
CONFIG_USB_MICROTEK=m
#
# USB port drivers
#
# CONFIG_USB_SERIAL is not set
#
# USB Miscellaneous drivers
#
# CONFIG_USB_EMI62 is not set
# CONFIG_USB_EMI26 is not set
# CONFIG_USB_ADUTUX is not set
CONFIG_USB_SEVSEG=y
CONFIG_USB_RIO500=m
# CONFIG_USB_LEGOTOWER is not set
CONFIG_USB_LCD=m
CONFIG_USB_BERRY_CHARGE=y
# CONFIG_USB_LED is not set
CONFIG_USB_CYPRESS_CY7C63=m
CONFIG_USB_CYTHERM=m
CONFIG_USB_IDMOUSE=y
# CONFIG_USB_FTDI_ELAN is not set
# CONFIG_USB_APPLEDISPLAY is not set
CONFIG_USB_SISUSBVGA=y
CONFIG_USB_SISUSBVGA_CON=y
CONFIG_USB_LD=m
# CONFIG_USB_TRANCEVIBRATOR is not set
CONFIG_USB_IOWARRIOR=m
# CONFIG_USB_TEST is not set
CONFIG_USB_ISIGHTFW=m
# CONFIG_USB_VST is not set
#
# OTG and related infrastructure
#
# CONFIG_NOP_USB_XCEIV is not set
CONFIG_UWB=m
CONFIG_UWB_HWA=m
# CONFIG_UWB_WHCI is not set
# CONFIG_UWB_WLP is not set
# CONFIG_UWB_I1480U is not set
CONFIG_MMC=m
CONFIG_MMC_DEBUG=y
# CONFIG_MMC_UNSAFE_RESUME is not set
#
# MMC/SD/SDIO Card Drivers
#
CONFIG_MMC_BLOCK=m
# CONFIG_MMC_BLOCK_BOUNCE is not set
# CONFIG_SDIO_UART is not set
CONFIG_MMC_TEST=m
#
# MMC/SD/SDIO Host Controller Drivers
#
CONFIG_MMC_SDHCI=m
# CONFIG_MMC_SDHCI_PCI is not set
CONFIG_MMC_SDHCI_PLTFM=m
# CONFIG_MMC_WBSD is not set
# CONFIG_MMC_AT91 is not set
# CONFIG_MMC_ATMELMCI is not set
CONFIG_MMC_TIFM_SD=m
CONFIG_MMC_SDRICOH_CS=m
# CONFIG_MMC_CB710 is not set
# CONFIG_MMC_VIA_SDMMC is not set
CONFIG_MEMSTICK=y
# CONFIG_MEMSTICK_DEBUG is not set
#
# MemoryStick drivers
#
# CONFIG_MEMSTICK_UNSAFE_RESUME is not set
CONFIG_MSPRO_BLOCK=m
#
# MemoryStick Host Controller Drivers
#
# CONFIG_MEMSTICK_TIFM_MS is not set
CONFIG_MEMSTICK_JMICRON_38X=m
# CONFIG_NEW_LEDS is not set
# CONFIG_ACCESSIBILITY is not set
CONFIG_INFINIBAND=y
CONFIG_INFINIBAND_USER_MAD=y
CONFIG_INFINIBAND_USER_ACCESS=m
CONFIG_INFINIBAND_USER_MEM=y
CONFIG_INFINIBAND_ADDR_TRANS=y
# CONFIG_INFINIBAND_MTHCA is not set
# CONFIG_INFINIBAND_AMSO1100 is not set
# CONFIG_INFINIBAND_CXGB3 is not set
CONFIG_MLX4_INFINIBAND=m
CONFIG_INFINIBAND_NES=m
# CONFIG_INFINIBAND_NES_DEBUG is not set
CONFIG_INFINIBAND_IPOIB=y
CONFIG_INFINIBAND_IPOIB_CM=y
# CONFIG_INFINIBAND_IPOIB_DEBUG is not set
CONFIG_INFINIBAND_SRP=m
CONFIG_INFINIBAND_ISER=m
# CONFIG_EDAC is not set
CONFIG_RTC_LIB=y
CONFIG_RTC_CLASS=y
CONFIG_RTC_HCTOSYS=y
CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
CONFIG_RTC_DEBUG=y
#
# RTC interfaces
#
CONFIG_RTC_INTF_SYSFS=y
CONFIG_RTC_INTF_PROC=y
CONFIG_RTC_INTF_DEV=y
CONFIG_RTC_INTF_DEV_UIE_EMUL=y
CONFIG_RTC_DRV_TEST=m
#
# I2C RTC drivers
#
# CONFIG_RTC_DRV_DS1307 is not set
CONFIG_RTC_DRV_DS1374=m
CONFIG_RTC_DRV_DS1672=m
# CONFIG_RTC_DRV_MAX6900 is not set
CONFIG_RTC_DRV_RS5C372=m
# CONFIG_RTC_DRV_ISL1208 is not set
CONFIG_RTC_DRV_X1205=m
CONFIG_RTC_DRV_PCF8563=m
CONFIG_RTC_DRV_PCF8583=m
# CONFIG_RTC_DRV_M41T80 is not set
CONFIG_RTC_DRV_S35390A=m
# CONFIG_RTC_DRV_FM3130 is not set
CONFIG_RTC_DRV_RX8581=m
CONFIG_RTC_DRV_RX8025=m
#
# SPI RTC drivers
#
CONFIG_RTC_DRV_M41T94=y
# CONFIG_RTC_DRV_DS1305 is not set
CONFIG_RTC_DRV_DS1390=y
CONFIG_RTC_DRV_MAX6902=m
CONFIG_RTC_DRV_R9701=m
CONFIG_RTC_DRV_RS5C348=y
CONFIG_RTC_DRV_DS3234=m
CONFIG_RTC_DRV_PCF2123=y
#
# Platform RTC drivers
#
CONFIG_RTC_DRV_CMOS=y
CONFIG_RTC_DRV_DS1286=m
CONFIG_RTC_DRV_DS1511=m
# CONFIG_RTC_DRV_DS1553 is not set
CONFIG_RTC_DRV_DS1742=m
CONFIG_RTC_DRV_STK17TA8=y
CONFIG_RTC_DRV_M48T86=y
CONFIG_RTC_DRV_M48T35=m
CONFIG_RTC_DRV_M48T59=m
CONFIG_RTC_DRV_MSM6242=m
CONFIG_RTC_DRV_BQ4802=m
# CONFIG_RTC_DRV_RP5C01 is not set
CONFIG_RTC_DRV_V3020=y
CONFIG_RTC_DRV_PCF50633=m
CONFIG_RTC_DRV_AB3100=m
#
# on-CPU RTC drivers
#
CONFIG_RTC_DRV_PCAP=m
CONFIG_DMADEVICES=y
#
# DMA Devices
#
CONFIG_ASYNC_TX_DISABLE_CHANNEL_SWITCH=y
CONFIG_INTEL_IOATDMA=m
CONFIG_DMA_ENGINE=y
#
# DMA Clients
#
CONFIG_NET_DMA=y
CONFIG_ASYNC_TX_DMA=y
CONFIG_DMATEST=y
CONFIG_DCA=m
CONFIG_AUXDISPLAY=y
CONFIG_UIO=y
# CONFIG_UIO_CIF is not set
CONFIG_UIO_PDRV=y
# CONFIG_UIO_PDRV_GENIRQ is not set
CONFIG_UIO_SMX=m
CONFIG_UIO_AEC=m
CONFIG_UIO_SERCOS3=m
CONFIG_UIO_PCI_GENERIC=m
#
# TI VLYNQ
#
# CONFIG_STAGING is not set
CONFIG_X86_PLATFORM_DEVICES=y
#
# Firmware Drivers
#
CONFIG_EDD=m
CONFIG_EDD_OFF=y
CONFIG_FIRMWARE_MEMMAP=y
CONFIG_DELL_RBU=y
CONFIG_DCDBAS=m
CONFIG_DMIID=y
CONFIG_ISCSI_IBFT_FIND=y
CONFIG_ISCSI_IBFT=y
#
# File systems
#
CONFIG_EXT2_FS=y
# CONFIG_EXT2_FS_XATTR is not set
# CONFIG_EXT2_FS_XIP is not set
CONFIG_EXT3_FS=y
CONFIG_EXT3_DEFAULTS_TO_ORDERED=y
CONFIG_EXT3_FS_XATTR=y
CONFIG_EXT3_FS_POSIX_ACL=y
CONFIG_EXT3_FS_SECURITY=y
CONFIG_EXT4_FS=y
CONFIG_EXT4_FS_XATTR=y
# CONFIG_EXT4_FS_POSIX_ACL is not set
# CONFIG_EXT4_FS_SECURITY is not set
CONFIG_EXT4_DEBUG=y
CONFIG_JBD=y
# CONFIG_JBD_DEBUG is not set
CONFIG_JBD2=y
# CONFIG_JBD2_DEBUG is not set
CONFIG_FS_MBCACHE=y
CONFIG_REISERFS_FS=y
# CONFIG_REISERFS_CHECK is not set
CONFIG_REISERFS_PROC_INFO=y
CONFIG_REISERFS_FS_XATTR=y
CONFIG_REISERFS_FS_POSIX_ACL=y
CONFIG_REISERFS_FS_SECURITY=y
# CONFIG_JFS_FS is not set
CONFIG_FS_POSIX_ACL=y
CONFIG_XFS_FS=m
# CONFIG_XFS_QUOTA is not set
CONFIG_XFS_POSIX_ACL=y
CONFIG_XFS_RT=y
CONFIG_XFS_DEBUG=y
# CONFIG_OCFS2_FS is not set
CONFIG_BTRFS_FS=m
# CONFIG_BTRFS_FS_POSIX_ACL is not set
CONFIG_NILFS2_FS=y
CONFIG_FILE_LOCKING=y
CONFIG_FSNOTIFY=y
# CONFIG_DNOTIFY is not set
CONFIG_INOTIFY=y
CONFIG_INOTIFY_USER=y
CONFIG_QUOTA=y
CONFIG_QUOTA_NETLINK_INTERFACE=y
CONFIG_PRINT_QUOTA_WARNING=y
CONFIG_QUOTA_TREE=m
CONFIG_QFMT_V1=m
CONFIG_QFMT_V2=m
CONFIG_QUOTACTL=y
# CONFIG_AUTOFS_FS is not set
CONFIG_AUTOFS4_FS=y
# CONFIG_FUSE_FS is not set
CONFIG_GENERIC_ACL=y
#
# Caches
#
CONFIG_FSCACHE=m
CONFIG_FSCACHE_STATS=y
# CONFIG_FSCACHE_HISTOGRAM is not set
CONFIG_FSCACHE_DEBUG=y
CONFIG_FSCACHE_OBJECT_LIST=y
CONFIG_CACHEFILES=m
# CONFIG_CACHEFILES_DEBUG is not set
CONFIG_CACHEFILES_HISTOGRAM=y
#
# CD-ROM/DVD Filesystems
#
CONFIG_ISO9660_FS=m
CONFIG_JOLIET=y
CONFIG_ZISOFS=y
# CONFIG_UDF_FS is not set
#
# DOS/FAT/NT Filesystems
#
CONFIG_FAT_FS=y
CONFIG_MSDOS_FS=y
CONFIG_VFAT_FS=m
CONFIG_FAT_DEFAULT_CODEPAGE=437
CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
# CONFIG_NTFS_FS is not set
#
# Pseudo filesystems
#
CONFIG_PROC_FS=y
CONFIG_PROC_KCORE=y
# CONFIG_PROC_SYSCTL is not set
CONFIG_PROC_PAGE_MONITOR=y
CONFIG_SYSFS=y
CONFIG_TMPFS=y
CONFIG_TMPFS_POSIX_ACL=y
# CONFIG_HUGETLBFS is not set
# CONFIG_HUGETLB_PAGE is not set
CONFIG_CONFIGFS_FS=y
# CONFIG_MISC_FILESYSTEMS is not set
# CONFIG_NETWORK_FILESYSTEMS is not set
CONFIG_EXPORTFS=m
#
# Partition Types
#
CONFIG_PARTITION_ADVANCED=y
# CONFIG_ACORN_PARTITION is not set
CONFIG_OSF_PARTITION=y
CONFIG_AMIGA_PARTITION=y
CONFIG_ATARI_PARTITION=y
# CONFIG_MAC_PARTITION is not set
CONFIG_MSDOS_PARTITION=y
CONFIG_BSD_DISKLABEL=y
CONFIG_MINIX_SUBPARTITION=y
CONFIG_SOLARIS_X86_PARTITION=y
# CONFIG_UNIXWARE_DISKLABEL is not set
CONFIG_LDM_PARTITION=y
CONFIG_LDM_DEBUG=y
CONFIG_SGI_PARTITION=y
# CONFIG_ULTRIX_PARTITION is not set
# CONFIG_SUN_PARTITION is not set
CONFIG_KARMA_PARTITION=y
CONFIG_EFI_PARTITION=y
# CONFIG_SYSV68_PARTITION is not set
CONFIG_NLS=y
CONFIG_NLS_DEFAULT="iso8859-1"
CONFIG_NLS_CODEPAGE_437=y
CONFIG_NLS_CODEPAGE_737=m
CONFIG_NLS_CODEPAGE_775=y
# CONFIG_NLS_CODEPAGE_850 is not set
CONFIG_NLS_CODEPAGE_852=m
# CONFIG_NLS_CODEPAGE_855 is not set
CONFIG_NLS_CODEPAGE_857=y
CONFIG_NLS_CODEPAGE_860=y
CONFIG_NLS_CODEPAGE_861=m
CONFIG_NLS_CODEPAGE_862=m
CONFIG_NLS_CODEPAGE_863=m
CONFIG_NLS_CODEPAGE_864=y
# CONFIG_NLS_CODEPAGE_865 is not set
# CONFIG_NLS_CODEPAGE_866 is not set
# CONFIG_NLS_CODEPAGE_869 is not set
CONFIG_NLS_CODEPAGE_936=y
CONFIG_NLS_CODEPAGE_950=m
# CONFIG_NLS_CODEPAGE_932 is not set
CONFIG_NLS_CODEPAGE_949=m
CONFIG_NLS_CODEPAGE_874=y
CONFIG_NLS_ISO8859_8=y
CONFIG_NLS_CODEPAGE_1250=y
# CONFIG_NLS_CODEPAGE_1251 is not set
CONFIG_NLS_ASCII=y
CONFIG_NLS_ISO8859_1=m
CONFIG_NLS_ISO8859_2=y
# CONFIG_NLS_ISO8859_3 is not set
CONFIG_NLS_ISO8859_4=m
CONFIG_NLS_ISO8859_5=y
# CONFIG_NLS_ISO8859_6 is not set
CONFIG_NLS_ISO8859_7=m
# CONFIG_NLS_ISO8859_9 is not set
CONFIG_NLS_ISO8859_13=m
# CONFIG_NLS_ISO8859_14 is not set
CONFIG_NLS_ISO8859_15=m
CONFIG_NLS_KOI8_R=y
# CONFIG_NLS_KOI8_U is not set
# CONFIG_NLS_UTF8 is not set
CONFIG_DLM=m
# CONFIG_DLM_DEBUG is not set
#
# Kernel hacking
#
CONFIG_TRACE_IRQFLAGS_SUPPORT=y
# CONFIG_PRINTK_TIME is not set
CONFIG_ALLOW_WARNINGS=y
CONFIG_ENABLE_WARN_DEPRECATED=y
CONFIG_ENABLE_MUST_CHECK=y
CONFIG_FRAME_WARN=1024
CONFIG_MAGIC_SYSRQ=y
CONFIG_STRIP_ASM_SYMS=y
# CONFIG_UNUSED_SYMBOLS is not set
CONFIG_DEBUG_FS=y
CONFIG_HEADERS_CHECK=y
# CONFIG_DEBUG_SECTION_MISMATCH is not set
CONFIG_DEBUG_KERNEL=y
# CONFIG_DEBUG_SHIRQ is not set
# CONFIG_DETECT_SOFTLOCKUP is not set
CONFIG_DETECT_HUNG_TASK=y
CONFIG_BOOTPARAM_HUNG_TASK_PANIC=y
CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=1
CONFIG_SCHED_DEBUG=y
CONFIG_SCHEDSTATS=y
CONFIG_TIMER_STATS=y
CONFIG_DEBUG_OBJECTS=y
# CONFIG_DEBUG_OBJECTS_SELFTEST is not set
CONFIG_DEBUG_OBJECTS_FREE=y
CONFIG_DEBUG_OBJECTS_TIMERS=y
# CONFIG_DEBUG_OBJECTS_WORK is not set
CONFIG_DEBUG_OBJECTS_ENABLE_DEFAULT=1
CONFIG_SLUB_DEBUG_ON=y
CONFIG_SLUB_STATS=y
# CONFIG_DEBUG_RT_MUTEXES is not set
CONFIG_RT_MUTEX_TESTER=y
CONFIG_DEBUG_SPINLOCK=y
CONFIG_DEBUG_MUTEXES=y
CONFIG_DEBUG_LOCK_ALLOC=y
CONFIG_PROVE_LOCKING=y
CONFIG_LOCKDEP=y
CONFIG_LOCK_STAT=y
CONFIG_DEBUG_LOCKDEP=y
CONFIG_TRACE_IRQFLAGS=y
# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
CONFIG_STACKTRACE=y
# CONFIG_DEBUG_HIGHMEM is not set
CONFIG_DEBUG_BUGVERBOSE=y
CONFIG_DEBUG_VM=y
CONFIG_DEBUG_VIRTUAL=y
CONFIG_DEBUG_WRITECOUNT=y
CONFIG_DEBUG_MEMORY_INIT=y
CONFIG_DEBUG_LIST=y
# CONFIG_DEBUG_SG is not set
CONFIG_DEBUG_NOTIFIERS=y
CONFIG_DEBUG_CREDENTIALS=y
CONFIG_ARCH_WANT_FRAME_POINTERS=y
CONFIG_FRAME_POINTER=y
CONFIG_BOOT_PRINTK_DELAY=y
CONFIG_RCU_TORTURE_TEST=y
# CONFIG_RCU_TORTURE_TEST_RUNNABLE is not set
CONFIG_RCU_CPU_STALL_DETECTOR=y
# CONFIG_BACKTRACE_SELF_TEST is not set
# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
CONFIG_FAULT_INJECTION=y
# CONFIG_FAILSLAB is not set
CONFIG_FAIL_PAGE_ALLOC=y
CONFIG_FAIL_MAKE_REQUEST=y
CONFIG_FAIL_IO_TIMEOUT=y
CONFIG_FAULT_INJECTION_DEBUG_FS=y
CONFIG_FAULT_INJECTION_STACKTRACE_FILTER=y
# CONFIG_LATENCYTOP is not set
CONFIG_DEBUG_PAGEALLOC=y
CONFIG_USER_STACKTRACE_SUPPORT=y
CONFIG_NOP_TRACER=y
CONFIG_HAVE_FTRACE_NMI_ENTER=y
CONFIG_HAVE_FUNCTION_TRACER=y
CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
CONFIG_HAVE_FUNCTION_GRAPH_FP_TEST=y
CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST=y
CONFIG_HAVE_DYNAMIC_FTRACE=y
CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
CONFIG_HAVE_SYSCALL_TRACEPOINTS=y
CONFIG_TRACER_MAX_TRACE=y
CONFIG_RING_BUFFER=y
CONFIG_FTRACE_NMI_ENTER=y
CONFIG_EVENT_TRACING=y
CONFIG_CONTEXT_SWITCH_TRACER=y
CONFIG_RING_BUFFER_ALLOW_SWAP=y
CONFIG_TRACING=y
CONFIG_GENERIC_TRACER=y
CONFIG_TRACING_SUPPORT=y
CONFIG_FTRACE=y
CONFIG_FUNCTION_TRACER=y
# CONFIG_FUNCTION_GRAPH_TRACER is not set
# CONFIG_IRQSOFF_TRACER is not set
CONFIG_SYSPROF_TRACER=y
CONFIG_SCHED_TRACER=y
# CONFIG_FTRACE_SYSCALLS is not set
# CONFIG_BOOT_TRACER is not set
CONFIG_BRANCH_PROFILE_NONE=y
# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set
# CONFIG_PROFILE_ALL_BRANCHES is not set
CONFIG_POWER_TRACER=y
CONFIG_KSYM_TRACER=y
# CONFIG_PROFILE_KSYM_TRACER is not set
# CONFIG_STACK_TRACER is not set
CONFIG_KMEMTRACE=y
# CONFIG_WORKQUEUE_TRACER is not set
CONFIG_BLK_DEV_IO_TRACE=y
CONFIG_DYNAMIC_FTRACE=y
CONFIG_FUNCTION_PROFILER=y
CONFIG_FTRACE_MCOUNT_RECORD=y
# CONFIG_FTRACE_STARTUP_TEST is not set
CONFIG_MMIOTRACE=y
CONFIG_MMIOTRACE_TEST=m
# CONFIG_RING_BUFFER_BENCHMARK is not set
CONFIG_PROVIDE_OHCI1394_DMA_INIT=y
# CONFIG_FIREWIRE_OHCI_REMOTE_DMA is not set
# CONFIG_BUILD_DOCSRC is not set
CONFIG_DYNAMIC_DEBUG=y
# CONFIG_DMA_API_DEBUG is not set
CONFIG_SAMPLES=y
# CONFIG_SAMPLE_TRACEPOINTS is not set
CONFIG_SAMPLE_TRACE_EVENTS=m
CONFIG_SAMPLE_KOBJECT=m
CONFIG_SAMPLE_HW_BREAKPOINT=m
CONFIG_HAVE_ARCH_KGDB=y
CONFIG_KGDB=y
CONFIG_KGDB_SERIAL_CONSOLE=m
# CONFIG_KGDB_TESTS is not set
CONFIG_HAVE_ARCH_KMEMCHECK=y
CONFIG_STRICT_DEVMEM=y
CONFIG_X86_VERBOSE_BOOTUP=y
CONFIG_EARLY_PRINTK=y
# CONFIG_EARLY_PRINTK_DBGP is not set
CONFIG_DEBUG_STACKOVERFLOW=y
# CONFIG_DEBUG_STACK_USAGE is not set
CONFIG_DEBUG_PER_CPU_MAPS=y
# CONFIG_X86_PTDUMP is not set
CONFIG_DEBUG_RODATA=y
CONFIG_DEBUG_RODATA_TEST=y
# CONFIG_DEBUG_NX_TEST is not set
CONFIG_4KSTACKS=y
CONFIG_DOUBLEFAULT=y
CONFIG_IOMMU_STRESS=y
CONFIG_HAVE_MMIOTRACE_SUPPORT=y
CONFIG_IO_DELAY_TYPE_0X80=0
CONFIG_IO_DELAY_TYPE_0XED=1
CONFIG_IO_DELAY_TYPE_UDELAY=2
CONFIG_IO_DELAY_TYPE_NONE=3
# CONFIG_IO_DELAY_0X80 is not set
# CONFIG_IO_DELAY_0XED is not set
CONFIG_IO_DELAY_UDELAY=y
# CONFIG_IO_DELAY_NONE is not set
CONFIG_DEFAULT_IO_DELAY_TYPE=2
# CONFIG_DEBUG_BOOT_PARAMS is not set
# CONFIG_CPA_DEBUG is not set
CONFIG_OPTIMIZE_INLINING=y
#
# Security options
#
CONFIG_KEYS=y
CONFIG_KEYS_DEBUG_PROC_KEYS=y
CONFIG_SECURITY=y
CONFIG_SECURITYFS=y
CONFIG_SECURITY_NETWORK=y
CONFIG_SECURITY_NETWORK_XFRM=y
CONFIG_SECURITY_PATH=y
# CONFIG_SECURITY_SMACK is not set
CONFIG_SECURITY_TOMOYO=y
# CONFIG_DEFAULT_SECURITY_SELINUX is not set
# CONFIG_DEFAULT_SECURITY_SMACK is not set
CONFIG_DEFAULT_SECURITY_TOMOYO=y
# CONFIG_DEFAULT_SECURITY_DAC is not set
CONFIG_DEFAULT_SECURITY="tomoyo"
CONFIG_ASYNC_TX_DISABLE_PQ_VAL_DMA=y
CONFIG_ASYNC_TX_DISABLE_XOR_VAL_DMA=y
CONFIG_CRYPTO=y
#
# Crypto core or helper
#
CONFIG_CRYPTO_FIPS=y
CONFIG_CRYPTO_ALGAPI=y
CONFIG_CRYPTO_ALGAPI2=y
CONFIG_CRYPTO_AEAD=y
CONFIG_CRYPTO_AEAD2=y
CONFIG_CRYPTO_BLKCIPHER=y
CONFIG_CRYPTO_BLKCIPHER2=y
CONFIG_CRYPTO_HASH=y
CONFIG_CRYPTO_HASH2=y
CONFIG_CRYPTO_RNG=y
CONFIG_CRYPTO_RNG2=y
CONFIG_CRYPTO_PCOMP=y
CONFIG_CRYPTO_MANAGER=y
CONFIG_CRYPTO_MANAGER2=y
CONFIG_CRYPTO_GF128MUL=y
CONFIG_CRYPTO_NULL=y
CONFIG_CRYPTO_WORKQUEUE=y
CONFIG_CRYPTO_CRYPTD=y
CONFIG_CRYPTO_AUTHENC=y
CONFIG_CRYPTO_TEST=m
#
# Authenticated Encryption with Associated Data
#
CONFIG_CRYPTO_CCM=y
# CONFIG_CRYPTO_GCM is not set
CONFIG_CRYPTO_SEQIV=y
#
# Block modes
#
CONFIG_CRYPTO_CBC=y
CONFIG_CRYPTO_CTR=y
CONFIG_CRYPTO_CTS=y
CONFIG_CRYPTO_ECB=y
CONFIG_CRYPTO_LRW=y
CONFIG_CRYPTO_PCBC=m
# CONFIG_CRYPTO_XTS is not set
#
# Hash modes
#
CONFIG_CRYPTO_HMAC=y
CONFIG_CRYPTO_XCBC=m
# CONFIG_CRYPTO_VMAC is not set
#
# Digest
#
CONFIG_CRYPTO_CRC32C=y
CONFIG_CRYPTO_CRC32C_INTEL=m
CONFIG_CRYPTO_GHASH=m
# CONFIG_CRYPTO_MD4 is not set
CONFIG_CRYPTO_MD5=y
CONFIG_CRYPTO_MICHAEL_MIC=y
CONFIG_CRYPTO_RMD128=y
# CONFIG_CRYPTO_RMD160 is not set
# CONFIG_CRYPTO_RMD256 is not set
CONFIG_CRYPTO_RMD320=m
CONFIG_CRYPTO_SHA1=y
CONFIG_CRYPTO_SHA256=m
# CONFIG_CRYPTO_SHA512 is not set
# CONFIG_CRYPTO_TGR192 is not set
CONFIG_CRYPTO_WP512=y
#
# Ciphers
#
CONFIG_CRYPTO_AES=y
# CONFIG_CRYPTO_AES_586 is not set
CONFIG_CRYPTO_ANUBIS=m
CONFIG_CRYPTO_ARC4=y
CONFIG_CRYPTO_BLOWFISH=y
CONFIG_CRYPTO_CAMELLIA=m
# CONFIG_CRYPTO_CAST5 is not set
# CONFIG_CRYPTO_CAST6 is not set
CONFIG_CRYPTO_DES=y
# CONFIG_CRYPTO_FCRYPT is not set
# CONFIG_CRYPTO_KHAZAD is not set
CONFIG_CRYPTO_SALSA20=m
# CONFIG_CRYPTO_SALSA20_586 is not set
CONFIG_CRYPTO_SEED=m
# CONFIG_CRYPTO_SERPENT is not set
CONFIG_CRYPTO_TEA=m
# CONFIG_CRYPTO_TWOFISH is not set
CONFIG_CRYPTO_TWOFISH_COMMON=y
CONFIG_CRYPTO_TWOFISH_586=y
#
# Compression
#
CONFIG_CRYPTO_DEFLATE=y
# CONFIG_CRYPTO_ZLIB is not set
CONFIG_CRYPTO_LZO=y
#
# Random Number Generation
#
CONFIG_CRYPTO_ANSI_CPRNG=y
# CONFIG_CRYPTO_HW is not set
CONFIG_HAVE_KVM=y
CONFIG_VIRTUALIZATION=y
# CONFIG_KVM is not set
CONFIG_VIRTIO=y
CONFIG_VIRTIO_RING=y
# CONFIG_VIRTIO_PCI is not set
CONFIG_VIRTIO_BALLOON=y
CONFIG_BINARY_PRINTF=y
#
# Library routines
#
CONFIG_BITREVERSE=y
CONFIG_GENERIC_FIND_FIRST_BIT=y
CONFIG_GENERIC_FIND_NEXT_BIT=y
CONFIG_GENERIC_FIND_LAST_BIT=y
CONFIG_CRC_CCITT=y
CONFIG_CRC16=y
CONFIG_CRC_T10DIF=y
CONFIG_CRC_ITU_T=m
CONFIG_CRC32=y
CONFIG_CRC7=m
CONFIG_LIBCRC32C=y
CONFIG_ZLIB_INFLATE=y
CONFIG_ZLIB_DEFLATE=y
CONFIG_LZO_COMPRESS=y
CONFIG_LZO_DECOMPRESS=y
CONFIG_HAS_IOMEM=y
CONFIG_HAS_IOPORT=y
CONFIG_HAS_DMA=y
CONFIG_CHECK_SIGNATURE=y
CONFIG_CPUMASK_OFFSTACK=y
CONFIG_NLATTR=y
CONFIG_FORCE_SUCCESSFUL_BUILD=y
CONFIG_FORCE_MINIMAL_CONFIG=y
CONFIG_FORCE_MINIMAL_CONFIG_PHYS=y
CONFIG_X86_32_ALWAYS_ON=y
^ permalink raw reply [flat|nested] 100+ messages in thread* Re: [GIT PATCH] TTY patches for 2.6.33-git
2009-12-12 8:46 ` [GIT PATCH] TTY patches for 2.6.33-git Ingo Molnar
@ 2009-12-12 9:39 ` Andrew Morton
2009-12-12 10:06 ` Ingo Molnar
` (2 more replies)
2009-12-12 10:42 ` Alan Cox
1 sibling, 3 replies; 100+ messages in thread
From: Andrew Morton @ 2009-12-12 9:39 UTC (permalink / raw)
To: Ingo Molnar
Cc: Greg KH, Alan Cox, Thomas Gleixner, Peter Zijlstra,
Linus Torvalds, linux-kernel
On Sat, 12 Dec 2009 09:46:11 +0100 Ingo Molnar <mingo@elte.hu> wrote:
> * Greg KH <gregkh@suse.de> wrote:
>
> > Here's the big TTY patchset for your .33-git tree.
>
> FYI, one of the changes in this tree is causing lockups on x86.
>
> Config attached.
>
> Possible suspects would one of these:
>
> 36ba782: tty: split the lock up a bit further
> 5ec93d1: tty: Move the leader test in disassociate
> 38c70b2: tty: Push the bkl down a bit in the hangup code
> f18f949: tty: Push the lock down further into the ldisc code
> eeb89d9: tty: push the BKL down into the handlers a bit
>
> as they deal with locking details and are fresher than two weeks.
yes, I started getting lockups yesterday when all this hit linux-next.
Seems to be quite .config-dependent.
I get all-cpu backtraces which show all eight CPUs stuck on either
lock_kernel() or files_lock(). It appears that both locks are held.
The do_tty_hangup()->tty_fasync() path takes the locks in the
file_list_lock()->lock_kernel() direction whereas most other code takes
them in the other direction, which cannot be good. But I'm not sure
that this recent merge significantly changed anything in that area.
Enabling lockdep makes the hang go away.
Have a trace. I'm actually wondering if perhaps there's a missing
unlock_kernel() somewhere else, and the tty code is just the victim of
that.
(hm, this trace only showed 6 CPUs. It's a bit of a mess)
[ 72.525902] INFO: RCU detected CPU 0 stall (t=2500 jiffies)
[ 72.525969] NMI backtrace for cpu 4
[ 72.526024] CPU 4
[ 72.526154] Process irqbalance (pid: 3152, threadinfo ffff88025d86e000, task ffff880256fac040)
[ 72.526209] Stack:
[ 72.526255] 0000000000000000 ffff88025d86fd08 ffffffff811a12f5 ffff88025d86fd38
[ 72.526434] <0> ffffffff811a572f ffff88025f0a2910 ffff88024a85c4c0 0000000000000000
[ 72.526698] <0> ffff88024a63f698 ffff88025d86fd48 ffffffff81383af9 ffff88025d86fd68
[ 72.527005] Call Trace:
[ 72.527057] [<ffffffff811a12f5>] __delay+0xa/0xc
[ 72.527112] [<ffffffff811a572f>] _raw_spin_lock+0xbc/0x125
[ 72.527165] [<ffffffff81383af9>] _spin_lock+0x9/0xb
[ 72.527220] [<ffffffff810ce929>] file_move+0x1e/0x4d
[ 72.527247] [<ffffffff810cd033>] __dentry_open+0x17e/0x2ef
[ 72.527247] [<ffffffff810cd26e>] nameidata_to_filp+0x3e/0x4f
[ 72.527247] [<ffffffff810d8bd5>] do_filp_open+0x529/0x972
[ 72.527247] [<ffffffff8105935b>] ? hrtimer_cancel+0x11/0x1d
[ 72.527247] [<ffffffff811a1fa3>] ? __strncpy_from_user+0x2b/0x55
[ 72.527247] [<ffffffff81383b04>] ? _spin_unlock+0x9/0xb
[ 72.527247] [<ffffffff810e2520>] ? alloc_fd+0x111/0x121
[ 72.527247] [<ffffffff810cc77d>] do_sys_open+0x5c/0x123
[ 72.527247] [<ffffffff810cc86d>] sys_open+0x1b/0x1d
[ 72.527247] [<ffffffff81002aab>] system_call_fastpath+0x16/0x1b
[ 72.527247] Code: 02 98 00 00 00 3e 48 89 c8 f7 e2 48 8d 7a 01 e8 b8 ff ff ff c9 c3 55 48 89 e5 50 65 8b 34 25 b0 cd 00 00 66 66 90 0f ae e8 0f 31 <41> 89 c0 66 66 90 0f ae e8 0f 31 89 c0 4c 29 c0 48 39 f8 73 20
[ 72.527247] Call Trace:
[ 72.527247] <#DB[1]> <<EOE>> Pid: 3152, comm: irqbalance Not tainted 2.6.32-mm1 #8
[ 72.527247] Call Trace:
[ 72.527247] <NMI> [<ffffffff81001098>] ? show_regs+0x23/0x27
[ 72.527247] [<ffffffff81385175>] nmi_watchdog_tick+0xc9/0x1ad
[ 72.527247] [<ffffffff813846b0>] do_nmi+0xa7/0x256
[ 72.527247] [<ffffffff8138433a>] nmi+0x1a/0x20
[ 72.527247] [<ffffffff811a134a>] ? delay_tsc+0x15/0x4c
[ 72.527247] <<EOE>> [<ffffffff811a12f5>] __delay+0xa/0xc
[ 72.527247] [<ffffffff811a572f>] _raw_spin_lock+0xbc/0x125
[ 72.527247] [<ffffffff81383af9>] _spin_lock+0x9/0xb
[ 72.527247] [<ffffffff810ce929>] file_move+0x1e/0x4d
[ 72.527247] [<ffffffff810cd033>] __dentry_open+0x17e/0x2ef
[ 72.527247] [<ffffffff810cd26e>] nameidata_to_filp+0x3e/0x4f
[ 72.527247] [<ffffffff810d8bd5>] do_filp_open+0x529/0x972
[ 72.527247] [<ffffffff8105935b>] ? hrtimer_cancel+0x11/0x1d
[ 72.527247] [<ffffffff811a1fa3>] ? __strncpy_from_user+0x2b/0x55
[ 72.527247] [<ffffffff81383b04>] ? _spin_unlock+0x9/0xb
[ 72.527247] [<ffffffff810e2520>] ? alloc_fd+0x111/0x121
[ 72.527247] [<ffffffff810cc77d>] do_sys_open+0x5c/0x123
[ 72.527247] [<ffffffff810cc86d>] sys_open+0x1b/0x1d
[ 72.527247] [<ffffffff81002aab>] system_call_fastpath+0x16/0x1b
[ 72.527230] NMI backtrace for cpu 6
[ 72.527230] CPU 6
[ 72.527230] Process mingetty (pid: 4105, threadinfo ffff88024aac4000, task ffff880256e2f810)
[ 72.527230] Stack:
[ 72.527230] ffffffff811a12f5 ffff88024aac5dc8 ffffffff811a572f 00007ffffbf94690
[ 72.527230] <0> 0000000000000000 000000000000033a ffffffff814ef5d0 ffff88024aac5e08
[ 72.527230] <0> ffffffff81383e0a ffff88025d5a3bc0 00007ffffbf94690 ffff88025d5a3bc0
[ 72.527230] Call Trace:
[ 72.527230] [<ffffffff811a12f5>] ? __delay+0xa/0xc
[ 72.527230] [<ffffffff811a572f>] _raw_spin_lock+0xbc/0x125
[ 72.527230] [<ffffffff81383e0a>] _lock_kernel+0x63/0x7c
[ 72.527230] [<ffffffff81101396>] __posix_lock_file+0x79/0x40e
[ 72.527230] [<ffffffff811018bf>] posix_lock_file+0x11/0x13
[ 72.527230] [<ffffffff811018ec>] vfs_lock_file+0x2b/0x2d
[ 72.527230] [<ffffffff81101ad4>] fcntl_setlk+0x139/0x278
[ 72.527230] [<ffffffff810da34c>] sys_fcntl+0x2ef/0x4a7
[ 72.527230] [<ffffffff81002aab>] system_call_fastpath+0x16/0x1b
[ 72.527230] Code: 48 8b 04 c5 60 85 86 81 48 c7 c2 c0 31 01 00 48 89 e5 48 6b 94 02 98 00 00 00 3e 48 89 c8 f7 e2 48 8d 7a 01 e8 b8 ff ff ff c9 c3 <55> 48 89 e5 50 65 8b 34 25 b0 cd 00 00 66 66 90 0f ae e8 0f 31
[ 72.527230] Call Trace:
[ 72.527230] <#DB[1]> <<EOE>> Pid: 4105, comm: mingetty Not tainted 2.6.32-mm1 #8
[ 72.527230] Call Trace:
[ 72.527230] <NMI> [<ffffffff81001098>] ? show_regs+0x23/0x27
[ 72.527230] [<ffffffff81385175>] nmi_watchdog_tick+0xc9/0x1ad
[ 72.527230] [<ffffffff813846b0>] do_nmi+0xa7/0x256
[ 72.527230] [<ffffffff8138433a>] nmi+0x1a/0x20
[ 72.527230] [<ffffffff811a1335>] ? delay_tsc+0x0/0x4c
[ 72.527230] <<EOE>> [<ffffffff811a12f5>] ? __delay+0xa/0xc
[ 72.527230] [<ffffffff811a572f>] _raw_spin_lock+0xbc/0x125
[ 72.527230] [<ffffffff81383e0a>] _lock_kernel+0x63/0x7c
[ 72.527230] [<ffffffff81101396>] __posix_lock_file+0x79/0x40e
[ 72.527230] [<ffffffff811018bf>] posix_lock_file+0x11/0x13
[ 72.527230] [<ffffffff811018ec>] vfs_lock_file+0x2b/0x2d
[ 72.527230] [<ffffffff81101ad4>] fcntl_setlk+0x139/0x278
[ 72.527230] [<ffffffff810da34c>] sys_fcntl+0x2ef/0x4a7
[ 72.527230] [<ffffffff81002aab>] system_call_fastpath+0x16/0x1b
[ 72.527211] NMI backtrace for cpu 1
[ 72.527230] INFO: RCU detected CPU 6 stall (t=2500 jiffies)
[ 72.527211] CPU 1
[ 72.527211] Process hald-addon-stor (pid: 3999, threadinfo ffff88025235c000, task ffff880256e2a080)
[ 72.527211] Stack:
[ 72.527211] 0000000000000000 ffff88025235dd08 ffffffff811a12f5 ffff88025235dd38
[ 72.527211] <0> ffffffff811a572f ffff88025d47ad10 ffff88025d4fd7c0 0000000000000000
[ 72.527211] <0> ffff8802583c78d0 ffff88025235dd48 ffffffff81383af9 ffff88025235dd68
[ 72.527211] Call Trace:
[ 72.527211] [<ffffffff811a12f5>] __delay+0xa/0xc
[ 72.527211] [<ffffffff811a572f>] _raw_spin_lock+0xbc/0x125
[ 72.527211] [<ffffffff81383af9>] _spin_lock+0x9/0xb
[ 72.527211] [<ffffffff810ce929>] file_move+0x1e/0x4d
[ 72.527211] [<ffffffff810cd033>] __dentry_open+0x17e/0x2ef
[ 72.527211] [<ffffffff810cd26e>] nameidata_to_filp+0x3e/0x4f
[ 72.527211] [<ffffffff810d8bd5>] do_filp_open+0x529/0x972
[ 72.527211] [<ffffffff81383b04>] ? _spin_unlock+0x9/0xb
[ 72.527211] [<ffffffff811a1fa3>] ? __strncpy_from_user+0x2b/0x55
[ 72.527211] [<ffffffff81383b04>] ? _spin_unlock+0x9/0xb
[ 72.527211] [<ffffffff810e2520>] ? alloc_fd+0x111/0x121
[ 72.527211] [<ffffffff810cc77d>] do_sys_open+0x5c/0x123
[ 72.527211] [<ffffffff810cc86d>] sys_open+0x1b/0x1d
[ 72.527211] [<ffffffff81002aab>] system_call_fastpath+0x16/0x1b
[ 72.527211] Code: 7a 01 e8 b8 ff ff ff c9 c3 55 48 89 e5 50 65 8b 34 25 b0 cd 00 00 66 66 90 0f ae e8 0f 31 41 89 c0 66 66 90 0f ae e8 0f 31 89 c0 <4c> 29 c0 48 39 f8 73 20 f3 90 65 8b 0c 25 b0 cd 00 00 39 ce 74
[ 72.527211] Call Trace:
[ 72.527211] <#DB[1]> <<EOE>> Pid: 3999, comm: hald-addon-stor Not tainted 2.6.32-mm1 #8
[ 72.527211] Call Trace:
[ 72.527211] <NMI> [<ffffffff81001098>] ? show_regs+0x23/0x27
[ 72.527211] [<ffffffff81385175>] nmi_watchdog_tick+0xc9/0x1ad
[ 72.527211] [<ffffffff813846b0>] do_nmi+0xa7/0x256
[ 72.527211] [<ffffffff8138433a>] nmi+0x1a/0x20
[ 72.527211] [<ffffffff811a1357>] ? delay_tsc+0x22/0x4c
[ 72.527211] <<EOE>> [<ffffffff811a12f5>] __delay+0xa/0xc
[ 72.527211] [<ffffffff811a572f>] _raw_spin_lock+0xbc/0x125
[ 72.527211] [<ffffffff81383af9>] _spin_lock+0x9/0xb
[ 72.527211] [<ffffffff810ce929>] file_move+0x1e/0x4d
[ 72.527211] [<ffffffff810cd033>] __dentry_open+0x17e/0x2ef
[ 72.527211] [<ffffffff810cd26e>] nameidata_to_filp+0x3e/0x4f
[ 72.527211] [<ffffffff810d8bd5>] do_filp_open+0x529/0x972
[ 72.527211] [<ffffffff81383b04>] ? _spin_unlock+0x9/0xb
[ 72.527211] [<ffffffff811a1fa3>] ? __strncpy_from_user+0x2b/0x55
[ 72.527211] [<ffffffff81383b04>] ? _spin_unlock+0x9/0xb
[ 72.527211] [<ffffffff810e2520>] ? alloc_fd+0x111/0x121
[ 72.527211] [<ffffffff810cc77d>] do_sys_open+0x5c/0x123
[ 72.527211] [<ffffffff810cc86d>] sys_open+0x1b/0x1d
[ 72.527211] [<ffffffff81002aab>] system_call_fastpath+0x16/0x1b
^ permalink raw reply [flat|nested] 100+ messages in thread* Re: [GIT PATCH] TTY patches for 2.6.33-git
2009-12-12 9:39 ` Andrew Morton
@ 2009-12-12 10:06 ` Ingo Molnar
2009-12-12 10:15 ` Ingo Molnar
2009-12-12 10:10 ` Ingo Molnar
2009-12-12 11:02 ` Alan Cox
2 siblings, 1 reply; 100+ messages in thread
From: Ingo Molnar @ 2009-12-12 10:06 UTC (permalink / raw)
To: Andrew Morton
Cc: Greg KH, Alan Cox, Thomas Gleixner, Peter Zijlstra,
Linus Torvalds, linux-kernel
* Andrew Morton <akpm@linux-foundation.org> wrote:
> Have a trace. I'm actually wondering if perhaps there's a missing
> unlock_kernel() somewhere else, and the tty code is just the victim of
> that.
Unlikely i'd say. I have 1000+ successful overnight tests on the latest
tree Linus pushed out:
3ef884b: Merge branch 'drm-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/airlied/d
So that's a guaranteed 'good' kernel.
The moment i merged 053fe57 into -tip the lockups started, so that's a
guaranteed 'bad' kernel. There's only the TTY changes between those two
points that look remotely related.
It's spurious though so quite hard to bisect. I tried one bisection
today already and it got on the wrong track. I'll do a brute-force
revert of the commits i quoted, lets see what happens.
Ingo
^ permalink raw reply [flat|nested] 100+ messages in thread
* Re: [GIT PATCH] TTY patches for 2.6.33-git
2009-12-12 10:06 ` Ingo Molnar
@ 2009-12-12 10:15 ` Ingo Molnar
2009-12-12 10:41 ` Andrew Morton
0 siblings, 1 reply; 100+ messages in thread
From: Ingo Molnar @ 2009-12-12 10:15 UTC (permalink / raw)
To: Andrew Morton
Cc: Greg KH, Alan Cox, Thomas Gleixner, Peter Zijlstra,
Linus Torvalds, linux-kernel
* Ingo Molnar <mingo@elte.hu> wrote:
>
> * Andrew Morton <akpm@linux-foundation.org> wrote:
>
> > Have a trace. I'm actually wondering if perhaps there's a missing
> > unlock_kernel() somewhere else, and the tty code is just the victim of
> > that.
>
> Unlikely i'd say. I have 1000+ successful overnight tests on the latest
> tree Linus pushed out:
>
> 3ef884b: Merge branch 'drm-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/airlied/d
>
> So that's a guaranteed 'good' kernel.
>
> The moment i merged 053fe57 into -tip the lockups started, so that's a
> guaranteed 'bad' kernel. There's only the TTY changes between those two
> points that look remotely related.
>
> It's spurious though so quite hard to bisect. I tried one bisection
> today already and it got on the wrong track. I'll do a brute-force
> revert of the commits i quoted, lets see what happens.
i'm testing the series of 5 reverts below. It's looking good so far. You
might want to try them - how quickly can you reproduce the hangs?
Ingo
--------------->
>From 95b532d4e2f9a82c1dedf7ea4a6c2702402237e6 Mon Sep 17 00:00:00 2001
From: Ingo Molnar <mingo@elte.hu>
Date: Sat, 12 Dec 2009 11:08:04 +0100
Subject: [PATCH] Revert "tty: push the BKL down into the handlers a bit"
This reverts commit eeb89d918c2fa2b809e464136bbafdaec2aacb30.
diff --git a/drivers/char/pty.c b/drivers/char/pty.c
index 385c44b..d86c0bc 100644
--- a/drivers/char/pty.c
+++ b/drivers/char/pty.c
@@ -659,7 +659,7 @@ static int __ptmx_open(struct inode *inode, struct file *filp)
if (!retval)
return 0;
out1:
- tty_release(inode, filp);
+ tty_release_dev(filp);
return retval;
out:
devpts_kill_index(inode, index);
diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c
index 1e24130..59499ee 100644
--- a/drivers/char/tty_io.c
+++ b/drivers/char/tty_io.c
@@ -142,6 +142,7 @@ ssize_t redirected_tty_write(struct file *, const char __user *,
size_t, loff_t *);
static unsigned int tty_poll(struct file *, poll_table *);
static int tty_open(struct inode *, struct file *);
+static int tty_release(struct inode *, struct file *);
long tty_ioctl(struct file *file, unsigned int cmd, unsigned long arg);
#ifdef CONFIG_COMPAT
static long tty_compat_ioctl(struct file *file, unsigned int cmd,
@@ -1016,16 +1017,14 @@ out:
void tty_write_message(struct tty_struct *tty, char *msg)
{
+ lock_kernel();
if (tty) {
mutex_lock(&tty->atomic_write_lock);
- lock_kernel();
- if (tty->ops->write && !test_bit(TTY_CLOSING, &tty->flags)) {
- unlock_kernel();
+ if (tty->ops->write && !test_bit(TTY_CLOSING, &tty->flags))
tty->ops->write(tty, msg, strlen(msg));
- } else
- unlock_kernel();
tty_write_unlock(tty);
}
+ unlock_kernel();
return;
}
@@ -1203,21 +1202,14 @@ static int tty_driver_install_tty(struct tty_driver *driver,
struct tty_struct *tty)
{
int idx = tty->index;
- int ret;
- if (driver->ops->install) {
- lock_kernel();
- ret = driver->ops->install(driver, tty);
- unlock_kernel();
- return ret;
- }
+ if (driver->ops->install)
+ return driver->ops->install(driver, tty);
if (tty_init_termios(tty) == 0) {
- lock_kernel();
tty_driver_kref_get(driver);
tty->count++;
driver->ttys[idx] = tty;
- unlock_kernel();
return 0;
}
return -ENOMEM;
@@ -1310,14 +1302,10 @@ struct tty_struct *tty_init_dev(struct tty_driver *driver, int idx,
struct tty_struct *tty;
int retval;
- lock_kernel();
/* Check if pty master is being opened multiple times */
if (driver->subtype == PTY_TYPE_MASTER &&
- (driver->flags & TTY_DRIVER_DEVPTS_MEM) && !first_ok) {
- unlock_kernel();
+ (driver->flags & TTY_DRIVER_DEVPTS_MEM) && !first_ok)
return ERR_PTR(-EIO);
- }
- unlock_kernel();
/*
* First time open is complex, especially for PTY devices.
@@ -1347,9 +1335,8 @@ struct tty_struct *tty_init_dev(struct tty_driver *driver, int idx,
* If we fail here just call release_tty to clean up. No need
* to decrement the use counts, as release_tty doesn't care.
*/
- lock_kernel();
+
retval = tty_ldisc_setup(tty, tty->link);
- unlock_kernel();
if (retval)
goto release_mem_out;
return tty;
@@ -1363,9 +1350,7 @@ release_mem_out:
if (printk_ratelimit())
printk(KERN_INFO "tty_init_dev: ldisc open failed, "
"clearing slot %d\n", idx);
- lock_kernel();
release_tty(tty, idx);
- unlock_kernel();
return ERR_PTR(retval);
}
@@ -1479,17 +1464,7 @@ static void release_tty(struct tty_struct *tty, int idx)
tty_kref_put(tty);
}
-/**
- * tty_release - vfs callback for close
- * @inode: inode of tty
- * @filp: file pointer for handle to tty
- *
- * Called the last time each file handle is closed that references
- * this tty. There may however be several such references.
- *
- * Locking:
- * Takes bkl. See tty_release_dev
- *
+/*
* Even releasing the tty structures is a tricky business.. We have
* to be very careful that the structures are all released at the
* same time, as interrupts might otherwise get the wrong pointers.
@@ -1497,20 +1472,20 @@ static void release_tty(struct tty_struct *tty, int idx)
* WSH 09/09/97: rewritten to avoid some nasty race conditions that could
* lead to double frees or releasing memory still in use.
*/
-
-int tty_release(struct inode *inode, struct file *filp)
+void tty_release_dev(struct file *filp)
{
struct tty_struct *tty, *o_tty;
int pty_master, tty_closing, o_tty_closing, do_sleep;
int devpts;
int idx;
char buf[64];
+ struct inode *inode;
+ inode = filp->f_path.dentry->d_inode;
tty = (struct tty_struct *)filp->private_data;
if (tty_paranoia_check(tty, inode, "tty_release_dev"))
- return 0;
+ return;
- lock_kernel();
check_tty_count(tty, "tty_release_dev");
tty_fasync(-1, filp, 0);
@@ -1525,22 +1500,19 @@ int tty_release(struct inode *inode, struct file *filp)
if (idx < 0 || idx >= tty->driver->num) {
printk(KERN_DEBUG "tty_release_dev: bad idx when trying to "
"free (%s)\n", tty->name);
- unlock_kernel();
- return 0;
+ return;
}
if (!devpts) {
if (tty != tty->driver->ttys[idx]) {
- unlock_kernel();
printk(KERN_DEBUG "tty_release_dev: driver.table[%d] not tty "
"for (%s)\n", idx, tty->name);
- return 0;
+ return;
}
if (tty->termios != tty->driver->termios[idx]) {
- unlock_kernel();
printk(KERN_DEBUG "tty_release_dev: driver.termios[%d] not termios "
"for (%s)\n",
idx, tty->name);
- return 0;
+ return;
}
}
#endif
@@ -1554,30 +1526,26 @@ int tty_release(struct inode *inode, struct file *filp)
if (tty->driver->other &&
!(tty->driver->flags & TTY_DRIVER_DEVPTS_MEM)) {
if (o_tty != tty->driver->other->ttys[idx]) {
- unlock_kernel();
printk(KERN_DEBUG "tty_release_dev: other->table[%d] "
"not o_tty for (%s)\n",
idx, tty->name);
- return 0 ;
+ return;
}
if (o_tty->termios != tty->driver->other->termios[idx]) {
- unlock_kernel();
printk(KERN_DEBUG "tty_release_dev: other->termios[%d] "
"not o_termios for (%s)\n",
idx, tty->name);
- return 0;
+ return;
}
if (o_tty->link != tty) {
- unlock_kernel();
printk(KERN_DEBUG "tty_release_dev: bad pty pointers\n");
- return 0;
+ return;
}
}
#endif
if (tty->ops->close)
tty->ops->close(tty, filp);
- unlock_kernel();
/*
* Sanity check: if tty->count is going to zero, there shouldn't be
* any waiters on tty->read_wait or tty->write_wait. We test the
@@ -1600,7 +1568,6 @@ int tty_release(struct inode *inode, struct file *filp)
opens on /dev/tty */
mutex_lock(&tty_mutex);
- lock_kernel();
tty_closing = tty->count <= 1;
o_tty_closing = o_tty &&
(o_tty->count <= (pty_master ? 1 : 0));
@@ -1631,7 +1598,6 @@ int tty_release(struct inode *inode, struct file *filp)
printk(KERN_WARNING "tty_release_dev: %s: read/write wait queue "
"active!\n", tty_name(tty, buf));
- unlock_kernel();
mutex_unlock(&tty_mutex);
schedule();
}
@@ -1695,10 +1661,8 @@ int tty_release(struct inode *inode, struct file *filp)
mutex_unlock(&tty_mutex);
/* check whether both sides are closing ... */
- if (!tty_closing || (o_tty && !o_tty_closing)) {
- unlock_kernel();
- return 0;
- }
+ if (!tty_closing || (o_tty && !o_tty_closing))
+ return;
#ifdef TTY_DEBUG_HANGUP
printk(KERN_DEBUG "freeing tty structure...");
@@ -1716,12 +1680,10 @@ int tty_release(struct inode *inode, struct file *filp)
/* Make this pty number available for reallocation */
if (devpts)
devpts_kill_index(inode, idx);
- unlock_kernel();
- return 0;
}
/**
- * tty_open - open a tty device
+ * __tty_open - open a tty device
* @inode: inode of device file
* @filp: file pointer to tty
*
@@ -1741,7 +1703,7 @@ int tty_release(struct inode *inode, struct file *filp)
* ->siglock protects ->signal/->sighand
*/
-static int tty_open(struct inode *inode, struct file *filp)
+static int __tty_open(struct inode *inode, struct file *filp)
{
struct tty_struct *tty = NULL;
int noctty, retval;
@@ -1758,12 +1720,10 @@ retry_open:
retval = 0;
mutex_lock(&tty_mutex);
- lock_kernel();
if (device == MKDEV(TTYAUX_MAJOR, 0)) {
tty = get_current_tty();
if (!tty) {
- unlock_kernel();
mutex_unlock(&tty_mutex);
return -ENXIO;
}
@@ -1795,14 +1755,12 @@ retry_open:
goto got_driver;
}
}
- unlock_kernel();
mutex_unlock(&tty_mutex);
return -ENODEV;
}
driver = get_tty_driver(device, &index);
if (!driver) {
- unlock_kernel();
mutex_unlock(&tty_mutex);
return -ENODEV;
}
@@ -1812,7 +1770,6 @@ got_driver:
tty = tty_driver_lookup_tty(driver, inode, index);
if (IS_ERR(tty)) {
- unlock_kernel();
mutex_unlock(&tty_mutex);
return PTR_ERR(tty);
}
@@ -1827,10 +1784,8 @@ got_driver:
mutex_unlock(&tty_mutex);
tty_driver_kref_put(driver);
- if (IS_ERR(tty)) {
- unlock_kernel();
+ if (IS_ERR(tty))
return PTR_ERR(tty);
- }
filp->private_data = tty;
file_move(filp, &tty->tty_files);
@@ -1858,15 +1813,11 @@ got_driver:
printk(KERN_DEBUG "error %d in opening %s...", retval,
tty->name);
#endif
- tty_release(inode, filp);
- if (retval != -ERESTARTSYS) {
- unlock_kernel();
+ tty_release_dev(filp);
+ if (retval != -ERESTARTSYS)
return retval;
- }
- if (signal_pending(current)) {
- unlock_kernel();
+ if (signal_pending(current))
return retval;
- }
schedule();
/*
* Need to reset f_op in case a hangup happened.
@@ -1875,11 +1826,8 @@ got_driver:
filp->f_op = &tty_fops;
goto retry_open;
}
- unlock_kernel();
-
mutex_lock(&tty_mutex);
- lock_kernel();
spin_lock_irq(¤t->sighand->siglock);
if (!noctty &&
current->signal->leader &&
@@ -1887,13 +1835,44 @@ got_driver:
tty->session == NULL)
__proc_set_tty(current, tty);
spin_unlock_irq(¤t->sighand->siglock);
- unlock_kernel();
mutex_unlock(&tty_mutex);
return 0;
}
+/* BKL pushdown: scary code avoidance wrapper */
+static int tty_open(struct inode *inode, struct file *filp)
+{
+ int ret;
+
+ lock_kernel();
+ ret = __tty_open(inode, filp);
+ unlock_kernel();
+ return ret;
+}
+
+
+/**
+ * tty_release - vfs callback for close
+ * @inode: inode of tty
+ * @filp: file pointer for handle to tty
+ *
+ * Called the last time each file handle is closed that references
+ * this tty. There may however be several such references.
+ *
+ * Locking:
+ * Takes bkl. See tty_release_dev
+ */
+
+static int tty_release(struct inode *inode, struct file *filp)
+{
+ lock_kernel();
+ tty_release_dev(filp);
+ unlock_kernel();
+ return 0;
+}
+
/**
* tty_poll - check tty status
* @filp: file being polled
@@ -2338,7 +2317,9 @@ static int tiocsetd(struct tty_struct *tty, int __user *p)
if (get_user(ldisc, p))
return -EFAULT;
+ lock_kernel();
ret = tty_set_ldisc(tty, ldisc);
+ unlock_kernel();
return ret;
}
diff --git a/drivers/char/tty_ldisc.c b/drivers/char/tty_ldisc.c
index d914e77..feb5507 100644
--- a/drivers/char/tty_ldisc.c
+++ b/drivers/char/tty_ldisc.c
@@ -34,8 +34,6 @@
#include <linux/vt_kern.h>
#include <linux/selection.h>
-#include <linux/smp_lock.h> /* For the moment */
-
#include <linux/kmod.h>
#include <linux/nsproxy.h>
@@ -547,7 +545,6 @@ int tty_set_ldisc(struct tty_struct *tty, int ldisc)
if (IS_ERR(new_ldisc))
return PTR_ERR(new_ldisc);
- lock_kernel();
/*
* We need to look at the tty locking here for pty/tty pairs
* when both sides try to change in parallel.
@@ -561,7 +558,6 @@ int tty_set_ldisc(struct tty_struct *tty, int ldisc)
*/
if (tty->ldisc->ops->num == ldisc) {
- unlock_kernel();
tty_ldisc_put(new_ldisc);
return 0;
}
@@ -573,7 +569,6 @@ int tty_set_ldisc(struct tty_struct *tty, int ldisc)
tty_wait_until_sent(tty, 0);
- unlock_kernel();
mutex_lock(&tty->ldisc_mutex);
/*
@@ -587,9 +582,6 @@ int tty_set_ldisc(struct tty_struct *tty, int ldisc)
test_bit(TTY_LDISC_CHANGING, &tty->flags) == 0);
mutex_lock(&tty->ldisc_mutex);
}
-
- lock_kernel();
-
set_bit(TTY_LDISC_CHANGING, &tty->flags);
/*
@@ -600,8 +592,6 @@ int tty_set_ldisc(struct tty_struct *tty, int ldisc)
tty->receive_room = 0;
o_ldisc = tty->ldisc;
-
- unlock_kernel();
/*
* Make sure we don't change while someone holds a
* reference to the line discipline. The TTY_LDISC bit
@@ -627,14 +617,12 @@ int tty_set_ldisc(struct tty_struct *tty, int ldisc)
flush_scheduled_work();
mutex_lock(&tty->ldisc_mutex);
- lock_kernel();
if (test_bit(TTY_HUPPED, &tty->flags)) {
/* We were raced by the hangup method. It will have stomped
the ldisc data and closed the ldisc down */
clear_bit(TTY_LDISC_CHANGING, &tty->flags);
mutex_unlock(&tty->ldisc_mutex);
tty_ldisc_put(new_ldisc);
- unlock_kernel();
return -EIO;
}
@@ -676,7 +664,6 @@ int tty_set_ldisc(struct tty_struct *tty, int ldisc)
if (o_work)
schedule_delayed_work(&o_tty->buf.work, 1);
mutex_unlock(&tty->ldisc_mutex);
- unlock_kernel();
return retval;
}
diff --git a/include/linux/tty.h b/include/linux/tty.h
index 405a903..e6da667 100644
--- a/include/linux/tty.h
+++ b/include/linux/tty.h
@@ -449,7 +449,7 @@ extern void initialize_tty_struct(struct tty_struct *tty,
struct tty_driver *driver, int idx);
extern struct tty_struct *tty_init_dev(struct tty_driver *driver, int idx,
int first_ok);
-extern int tty_release(struct inode *inode, struct file *filp);
+extern void tty_release_dev(struct file *filp);
extern int tty_init_termios(struct tty_struct *tty);
extern struct tty_struct *tty_pair_get_tty(struct tty_struct *tty);
>From bd9a619494c123470a081e5e30602c307de2bba3 Mon Sep 17 00:00:00 2001
From: Ingo Molnar <mingo@elte.hu>
Date: Sat, 12 Dec 2009 11:07:55 +0100
Subject: [PATCH] Revert "tty: Push the lock down further into the ldisc code"
This reverts commit f18f9498e90327b9b0e245e191029e6e1996d203.
diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c
index c408c81..1e24130 100644
--- a/drivers/char/tty_io.c
+++ b/drivers/char/tty_io.c
@@ -1347,7 +1347,9 @@ struct tty_struct *tty_init_dev(struct tty_driver *driver, int idx,
* If we fail here just call release_tty to clean up. No need
* to decrement the use counts, as release_tty doesn't care.
*/
+ lock_kernel();
retval = tty_ldisc_setup(tty, tty->link);
+ unlock_kernel();
if (retval)
goto release_mem_out;
return tty;
diff --git a/drivers/char/tty_ldisc.c b/drivers/char/tty_ldisc.c
index 3f653f7..d914e77 100644
--- a/drivers/char/tty_ldisc.c
+++ b/drivers/char/tty_ldisc.c
@@ -445,14 +445,8 @@ static void tty_set_termios_ldisc(struct tty_struct *tty, int num)
static int tty_ldisc_open(struct tty_struct *tty, struct tty_ldisc *ld)
{
WARN_ON(test_and_set_bit(TTY_LDISC_OPEN, &tty->flags));
- if (ld->ops->open) {
- int ret;
- /* BKL here locks verus a hangup event */
- lock_kernel();
- ret = ld->ops->open(tty);
- unlock_kernel();
- return ret;
- }
+ if (ld->ops->open)
+ return ld->ops->open(tty);
return 0;
}
@@ -572,7 +566,6 @@ int tty_set_ldisc(struct tty_struct *tty, int ldisc)
return 0;
}
- unlock_kernel();
/*
* Problem: What do we do if this blocks ?
* We could deadlock here
@@ -580,6 +573,7 @@ int tty_set_ldisc(struct tty_struct *tty, int ldisc)
tty_wait_until_sent(tty, 0);
+ unlock_kernel();
mutex_lock(&tty->ldisc_mutex);
/*
>From 8e991a5112643a63820a1088860f0c7c869d6f25 Mon Sep 17 00:00:00 2001
From: Ingo Molnar <mingo@elte.hu>
Date: Sat, 12 Dec 2009 11:07:46 +0100
Subject: [PATCH] Revert "tty: Push the bkl down a bit in the hangup code"
This reverts commit 38c70b27f9502c31c1d0c29676275f7362cdb0d9.
diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c
index cc941a3..c408c81 100644
--- a/drivers/char/tty_io.c
+++ b/drivers/char/tty_io.c
@@ -505,6 +505,8 @@ static void do_tty_hangup(struct work_struct *work)
if (!tty)
return;
+ /* inuse_filps is protected by the single kernel lock */
+ lock_kernel();
spin_lock(&redirect_lock);
if (redirect && redirect->private_data == tty) {
@@ -513,8 +515,6 @@ static void do_tty_hangup(struct work_struct *work)
}
spin_unlock(&redirect_lock);
- /* inuse_filps is protected by the single kernel lock */
- lock_kernel();
check_tty_count(tty, "do_tty_hangup");
file_list_lock();
/* This breaks for file handles being sent over AF_UNIX sockets ? */
>From 9d6d77b3c56e6c169e50b6bb9033e4a2e7d4ec71 Mon Sep 17 00:00:00 2001
From: Ingo Molnar <mingo@elte.hu>
Date: Sat, 12 Dec 2009 11:07:38 +0100
Subject: [PATCH] Revert "tty: Move the leader test in disassociate"
This reverts commit 5ec93d1154fd1e269162398f8e70efc7e004485d.
diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c
index a19fef2..cc941a3 100644
--- a/drivers/char/tty_io.c
+++ b/drivers/char/tty_io.c
@@ -707,8 +707,6 @@ void disassociate_ctty(int on_exit)
struct tty_struct *tty;
struct pid *tty_pgrp = NULL;
- if (!current->signal->leader)
- return;
tty = get_current_tty();
if (tty) {
@@ -774,7 +772,8 @@ void no_tty(void)
{
struct task_struct *tsk = current;
lock_kernel();
- disassociate_ctty(0);
+ if (tsk->signal->leader)
+ disassociate_ctty(0);
unlock_kernel();
proc_clear_tty(tsk);
}
diff --git a/kernel/exit.c b/kernel/exit.c
index 6f50ef5..1143012 100644
--- a/kernel/exit.c
+++ b/kernel/exit.c
@@ -971,7 +971,7 @@ NORET_TYPE void do_exit(long code)
exit_thread();
cgroup_exit(tsk, 1);
- if (group_dead)
+ if (group_dead && tsk->signal->leader)
disassociate_ctty(1);
module_put(task_thread_info(tsk)->exec_domain->module);
>From 153d2afe47cc994d35adc7e61be13bf840fd0b47 Mon Sep 17 00:00:00 2001
From: Ingo Molnar <mingo@elte.hu>
Date: Sat, 12 Dec 2009 11:07:28 +0100
Subject: [PATCH] Revert "tty: split the lock up a bit further"
This reverts commit 36ba782e9674cdc29ec7003757df0b375e99fa96.
diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c
index 684f0e0..a19fef2 100644
--- a/drivers/char/tty_io.c
+++ b/drivers/char/tty_io.c
@@ -516,8 +516,6 @@ static void do_tty_hangup(struct work_struct *work)
/* inuse_filps is protected by the single kernel lock */
lock_kernel();
check_tty_count(tty, "do_tty_hangup");
- unlock_kernel();
-
file_list_lock();
/* This breaks for file handles being sent over AF_UNIX sockets ? */
list_for_each_entry(filp, &tty->tty_files, f_u.fu_list) {
@@ -531,7 +529,6 @@ static void do_tty_hangup(struct work_struct *work)
}
file_list_unlock();
- lock_kernel();
tty_ldisc_hangup(tty);
read_lock(&tasklist_lock);
^ permalink raw reply related [flat|nested] 100+ messages in thread* Re: [GIT PATCH] TTY patches for 2.6.33-git
2009-12-12 10:15 ` Ingo Molnar
@ 2009-12-12 10:41 ` Andrew Morton
2009-12-12 10:52 ` Ingo Molnar
0 siblings, 1 reply; 100+ messages in thread
From: Andrew Morton @ 2009-12-12 10:41 UTC (permalink / raw)
To: Ingo Molnar
Cc: Greg KH, Alan Cox, Thomas Gleixner, Peter Zijlstra,
Linus Torvalds, linux-kernel
On Sat, 12 Dec 2009 11:15:51 +0100 Ingo Molnar <mingo@elte.hu> wrote:
> i'm testing the series of 5 reverts below. It's looking good so far. You
> might want to try them - how quickly can you reproduce the hangs?
Immediately, with http://userweb.kernel.org/~akpm/config-akpm2.txt
^ permalink raw reply [flat|nested] 100+ messages in thread
* Re: [GIT PATCH] TTY patches for 2.6.33-git
2009-12-12 10:41 ` Andrew Morton
@ 2009-12-12 10:52 ` Ingo Molnar
0 siblings, 0 replies; 100+ messages in thread
From: Ingo Molnar @ 2009-12-12 10:52 UTC (permalink / raw)
To: Andrew Morton
Cc: Greg KH, Alan Cox, Thomas Gleixner, Peter Zijlstra,
Linus Torvalds, linux-kernel
* Andrew Morton <akpm@linux-foundation.org> wrote:
> On Sat, 12 Dec 2009 11:15:51 +0100 Ingo Molnar <mingo@elte.hu> wrote:
>
> > i'm testing the series of 5 reverts below. It's looking good so far. You
> > might want to try them - how quickly can you reproduce the hangs?
>
> Immediately, with http://userweb.kernel.org/~akpm/config-akpm2.txt
Ok. The lockups i saw went away with the 5 reverts i posted. I'll keep
testing that over the weekend - that should narrow down the range very
precisely.
Ingo
^ permalink raw reply [flat|nested] 100+ messages in thread
* Re: [GIT PATCH] TTY patches for 2.6.33-git
2009-12-12 9:39 ` Andrew Morton
2009-12-12 10:06 ` Ingo Molnar
@ 2009-12-12 10:10 ` Ingo Molnar
2009-12-12 10:36 ` Andrew Morton
2009-12-12 11:02 ` Alan Cox
2 siblings, 1 reply; 100+ messages in thread
From: Ingo Molnar @ 2009-12-12 10:10 UTC (permalink / raw)
To: Andrew Morton
Cc: Greg KH, Alan Cox, Thomas Gleixner, Peter Zijlstra,
Linus Torvalds, linux-kernel
* Andrew Morton <akpm@linux-foundation.org> wrote:
> Seems to be quite .config-dependent.
My theory is that it's a race and that it's thus timing dependent. TTY
SMP details get stressed most during a particular point during bootup,
when all the mingetty's are starting up all at once and race with each
other.
If you are lucky to not hit the bug then, then the likelyhood is much
lower later on.
It would be nice if Alan posted his TTY stress-testing code. It could
potentially make this bug bisectable.
Ingo
^ permalink raw reply [flat|nested] 100+ messages in thread
* Re: [GIT PATCH] TTY patches for 2.6.33-git
2009-12-12 10:10 ` Ingo Molnar
@ 2009-12-12 10:36 ` Andrew Morton
2009-12-12 17:16 ` Linus Torvalds
0 siblings, 1 reply; 100+ messages in thread
From: Andrew Morton @ 2009-12-12 10:36 UTC (permalink / raw)
To: Ingo Molnar
Cc: Greg KH, Alan Cox, Thomas Gleixner, Peter Zijlstra,
Linus Torvalds, linux-kernel
On Sat, 12 Dec 2009 11:10:32 +0100 Ingo Molnar <mingo@elte.hu> wrote:
>
> * Andrew Morton <akpm@linux-foundation.org> wrote:
>
> > Seems to be quite .config-dependent.
>
> My theory is that it's a race and that it's thus timing dependent. TTY
> SMP details get stressed most during a particular point during bootup,
> when all the mingetty's are starting up all at once and race with each
> other.
>
> If you are lucky to not hit the bug then, then the likelyhood is much
> lower later on.
>
> It would be nice if Alan posted his TTY stress-testing code. It could
> potentially make this bug bisectable.
>
I'm surprised that lockdep didn't notice that ab/ba I thought I saw.
Maybe the do_tty_hangup()->tty_fasync() never happens.
The machine I can reproduce this on is at work and I'm not, until
Monday. I'd try removing the files_lock() calls from tty_io.c, see if
that helps.
I had
[ 71.553228] Warning: dev (tty1) tty->count(7) != #fd's(6) in tty_release_dev
come out once, then it went away.
^ permalink raw reply [flat|nested] 100+ messages in thread
* Re: [GIT PATCH] TTY patches for 2.6.33-git
2009-12-12 10:36 ` Andrew Morton
@ 2009-12-12 17:16 ` Linus Torvalds
2009-12-12 17:26 ` Linus Torvalds
0 siblings, 1 reply; 100+ messages in thread
From: Linus Torvalds @ 2009-12-12 17:16 UTC (permalink / raw)
To: Andrew Morton
Cc: Ingo Molnar, Greg KH, Alan Cox, Thomas Gleixner, Peter Zijlstra,
linux-kernel
On Sat, 12 Dec 2009, Andrew Morton wrote:
> On Sat, 12 Dec 2009 11:10:32 +0100 Ingo Molnar <mingo@elte.hu> wrote:
>
> >
> > * Andrew Morton <akpm@linux-foundation.org> wrote:
> >
> > > Seems to be quite .config-dependent.
> >
> > My theory is that it's a race and that it's thus timing dependent. TTY
> > SMP details get stressed most during a particular point during bootup,
> > when all the mingetty's are starting up all at once and race with each
> > other.
> >
> > If you are lucky to not hit the bug then, then the likelyhood is much
> > lower later on.
> >
> > It would be nice if Alan posted his TTY stress-testing code. It could
> > potentially make this bug bisectable.
> >
>
> I'm surprised that lockdep didn't notice that ab/ba I thought I saw.
> Maybe the do_tty_hangup()->tty_fasync() never happens.
The kernel lock cannot have any ABBA deadlocks.
If somebody blocks on another lock (after getting the kernel lock), the
kernel lock will be dropped. So no ABBA.
Linus
^ permalink raw reply [flat|nested] 100+ messages in thread
* Re: [GIT PATCH] TTY patches for 2.6.33-git
2009-12-12 17:16 ` Linus Torvalds
@ 2009-12-12 17:26 ` Linus Torvalds
2009-12-12 21:42 ` Alan Cox
0 siblings, 1 reply; 100+ messages in thread
From: Linus Torvalds @ 2009-12-12 17:26 UTC (permalink / raw)
To: Andrew Morton
Cc: Ingo Molnar, Greg KH, Alan Cox, Thomas Gleixner, Peter Zijlstra,
linux-kernel
On Sat, 12 Dec 2009, Linus Torvalds wrote:
> >
> > I'm surprised that lockdep didn't notice that ab/ba I thought I saw.
> > Maybe the do_tty_hangup()->tty_fasync() never happens.
>
> The kernel lock cannot have any ABBA deadlocks.
>
> If somebody blocks on another lock (after getting the kernel lock), the
> kernel lock will be dropped. So no ABBA.
Oh, but it turns out that while there cannot be any ABBA deadlocks with
sleeping locks, what the tty code does is invalid for _another_ reason:
file_list_lock() is a spinlock. And that's a no-no.
You cannot take the kernel lock inside a spinlock. Ordering doesn't
matter, there's no ABBA issues - it's simply invalid _regardless_ of any
other use of that lock.
I think we could possibly add a "__might_sleep()" to _lock_kernel(). It
doesn't really sleep, but it's invalid to take the kernel lock in an
atomic region, so __might_sleep() might be the right thing anyway.
Linus
^ permalink raw reply [flat|nested] 100+ messages in thread
* Re: [GIT PATCH] TTY patches for 2.6.33-git
2009-12-12 17:26 ` Linus Torvalds
@ 2009-12-12 21:42 ` Alan Cox
2009-12-12 21:48 ` Thomas Gleixner
2009-12-12 22:21 ` Linus Torvalds
0 siblings, 2 replies; 100+ messages in thread
From: Alan Cox @ 2009-12-12 21:42 UTC (permalink / raw)
To: Linus Torvalds
Cc: Andrew Morton, Ingo Molnar, Greg KH, Thomas Gleixner,
Peter Zijlstra, linux-kernel
> I think we could possibly add a "__might_sleep()" to _lock_kernel(). It
> doesn't really sleep, but it's invalid to take the kernel lock in an
> atomic region, so __might_sleep() might be the right thing anyway.
It's only invalid if you don't already hold the lock. The old tty code
worked because every path into tty_fasync already held the lock ! That
specific case - taking it the first time should definitely
__might_sleep().
Mind you it's probably still rather dumb and would be a good debugging
aid for -next to be able to warn on all offences if only to catch this
stuff for the future BKL removal work.
Alan
^ permalink raw reply [flat|nested] 100+ messages in thread
* Re: [GIT PATCH] TTY patches for 2.6.33-git
2009-12-12 21:42 ` Alan Cox
@ 2009-12-12 21:48 ` Thomas Gleixner
2009-12-12 22:25 ` Linus Torvalds
2009-12-12 22:21 ` Linus Torvalds
1 sibling, 1 reply; 100+ messages in thread
From: Thomas Gleixner @ 2009-12-12 21:48 UTC (permalink / raw)
To: Alan Cox
Cc: Linus Torvalds, Andrew Morton, Ingo Molnar, Greg KH,
Peter Zijlstra, linux-kernel
On Sat, 12 Dec 2009, Alan Cox wrote:
> > I think we could possibly add a "__might_sleep()" to _lock_kernel(). It
> > doesn't really sleep, but it's invalid to take the kernel lock in an
> > atomic region, so __might_sleep() might be the right thing anyway.
>
> It's only invalid if you don't already hold the lock. The old tty code
> worked because every path into tty_fasync already held the lock ! That
> specific case - taking it the first time should definitely
> __might_sleep().
>
> Mind you it's probably still rather dumb and would be a good debugging
> aid for -next to be able to warn on all offences if only to catch this
> stuff for the future BKL removal work.
Just patched the following in and it catched your problem nicely. With
your AB/BA fix patch applied everything is fine.
Thanks,
tglx
---
Subject: BKL: Add might sleep to __lock_kernel
From: Thomas Gleixner <tglx@linutronix.de>
Date: Sat, 12 Dec 2009 20:29:00 +0100
Catches all offenders which take the BKL first time in an atomic
region. Recursive lock_kernel calls are not affected.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
lib/kernel_lock.c | 2 ++
1 file changed, 2 insertions(+)
Index: linux-2.6/lib/kernel_lock.c
===================================================================
--- linux-2.6.orig/lib/kernel_lock.c
+++ linux-2.6/lib/kernel_lock.c
@@ -64,6 +64,8 @@ void __lockfunc __release_kernel_lock(vo
#ifdef CONFIG_PREEMPT
static inline void __lock_kernel(void)
{
+ might_sleep();
+
preempt_disable();
if (unlikely(!_raw_spin_trylock(&kernel_flag))) {
/*
^ permalink raw reply [flat|nested] 100+ messages in thread* Re: [GIT PATCH] TTY patches for 2.6.33-git
2009-12-12 21:48 ` Thomas Gleixner
@ 2009-12-12 22:25 ` Linus Torvalds
2009-12-12 22:31 ` Thomas Gleixner
0 siblings, 1 reply; 100+ messages in thread
From: Linus Torvalds @ 2009-12-12 22:25 UTC (permalink / raw)
To: Thomas Gleixner
Cc: Alan Cox, Andrew Morton, Ingo Molnar, Greg KH, Peter Zijlstra,
linux-kernel
On Sat, 12 Dec 2009, Thomas Gleixner wrote:
>
> Just patched the following in and it catched your problem nicely. With
> your AB/BA fix patch applied everything is fine.
Actually, the patch I just suggested might be better. Admittedly the
CONFIG_PREEMPT case is the more important one (and the one that will catch
more cases), but even without preemptyion the might_sleep() in
_lock_kernel() (one underscore) would trigger on the case of somebody
doing lock_kernel with local interrupts disabled.
Linus
^ permalink raw reply [flat|nested] 100+ messages in thread
* Re: [GIT PATCH] TTY patches for 2.6.33-git
2009-12-12 22:25 ` Linus Torvalds
@ 2009-12-12 22:31 ` Thomas Gleixner
0 siblings, 0 replies; 100+ messages in thread
From: Thomas Gleixner @ 2009-12-12 22:31 UTC (permalink / raw)
To: Linus Torvalds
Cc: Alan Cox, Andrew Morton, Ingo Molnar, Greg KH, Peter Zijlstra,
linux-kernel
On Sat, 12 Dec 2009, Linus Torvalds wrote:
> On Sat, 12 Dec 2009, Thomas Gleixner wrote:
> >
> > Just patched the following in and it catched your problem nicely. With
> > your AB/BA fix patch applied everything is fine.
>
> Actually, the patch I just suggested might be better. Admittedly the
> CONFIG_PREEMPT case is the more important one (and the one that will catch
> more cases), but even without preemptyion the might_sleep() in
> _lock_kernel() (one underscore) would trigger on the case of somebody
> doing lock_kernel with local interrupts disabled.
Fair enough.
tglx
^ permalink raw reply [flat|nested] 100+ messages in thread
* Re: [GIT PATCH] TTY patches for 2.6.33-git
2009-12-12 21:42 ` Alan Cox
2009-12-12 21:48 ` Thomas Gleixner
@ 2009-12-12 22:21 ` Linus Torvalds
2009-12-12 22:33 ` Thomas Gleixner
1 sibling, 1 reply; 100+ messages in thread
From: Linus Torvalds @ 2009-12-12 22:21 UTC (permalink / raw)
To: Alan Cox
Cc: Andrew Morton, Ingo Molnar, Greg KH, Thomas Gleixner,
Peter Zijlstra, linux-kernel
On Sat, 12 Dec 2009, Alan Cox wrote:
> > I think we could possibly add a "__might_sleep()" to _lock_kernel(). It
> > doesn't really sleep, but it's invalid to take the kernel lock in an
> > atomic region, so __might_sleep() might be the right thing anyway.
>
> It's only invalid if you don't already hold the lock.
True.
> The old tty code worked because every path into tty_fasync already held
> the lock ! That specific case - taking it the first time should
> definitely __might_sleep().
That would give us at least somewhat better debugging. And it's a very
natural thing to do. IOW, just something like the appended.
But maybe it complains about valid (but unusual) things. For example, it's
not strictly speaking _wrong_ to take the kernel lock while preemption is
disabled, even though it's a really bad idea.
Anybody willing to be the guinea-pig?
Linus
---
lib/kernel_lock.c | 4 +++-
1 files changed, 3 insertions(+), 1 deletions(-)
diff --git a/lib/kernel_lock.c b/lib/kernel_lock.c
index 4ebfa5a..5526b46 100644
--- a/lib/kernel_lock.c
+++ b/lib/kernel_lock.c
@@ -122,8 +122,10 @@ void __lockfunc _lock_kernel(const char *func, const char *file, int line)
trace_lock_kernel(func, file, line);
- if (likely(!depth))
+ if (likely(!depth)) {
+ might_sleep();
__lock_kernel();
+ }
current->lock_depth = depth;
}
^ permalink raw reply related [flat|nested] 100+ messages in thread* Re: [GIT PATCH] TTY patches for 2.6.33-git
2009-12-12 22:21 ` Linus Torvalds
@ 2009-12-12 22:33 ` Thomas Gleixner
2009-12-12 23:17 ` Linus Torvalds
0 siblings, 1 reply; 100+ messages in thread
From: Thomas Gleixner @ 2009-12-12 22:33 UTC (permalink / raw)
To: Linus Torvalds
Cc: Alan Cox, Andrew Morton, Ingo Molnar, Greg KH, Peter Zijlstra,
linux-kernel
On Sat, 12 Dec 2009, Linus Torvalds wrote:
>
> On Sat, 12 Dec 2009, Alan Cox wrote:
>
> > > I think we could possibly add a "__might_sleep()" to _lock_kernel(). It
> > > doesn't really sleep, but it's invalid to take the kernel lock in an
> > > atomic region, so __might_sleep() might be the right thing anyway.
> >
> > It's only invalid if you don't already hold the lock.
>
> True.
>
> > The old tty code worked because every path into tty_fasync already held
> > the lock ! That specific case - taking it the first time should
> > definitely __might_sleep().
>
> That would give us at least somewhat better debugging. And it's a very
> natural thing to do. IOW, just something like the appended.
>
> But maybe it complains about valid (but unusual) things. For example, it's
> not strictly speaking _wrong_ to take the kernel lock while preemption is
> disabled, even though it's a really bad idea.
>
> Anybody willing to be the guinea-pig?
Replaced my patch with yours and it works the same way (except for the
PREEMPT=n case)
Acked-and-Tested-by: Thomas Gleixner <tglx@linutronix.de>
> Linus
>
> ---
> lib/kernel_lock.c | 4 +++-
> 1 files changed, 3 insertions(+), 1 deletions(-)
>
> diff --git a/lib/kernel_lock.c b/lib/kernel_lock.c
> index 4ebfa5a..5526b46 100644
> --- a/lib/kernel_lock.c
> +++ b/lib/kernel_lock.c
> @@ -122,8 +122,10 @@ void __lockfunc _lock_kernel(const char *func, const char *file, int line)
>
> trace_lock_kernel(func, file, line);
>
> - if (likely(!depth))
> + if (likely(!depth)) {
> + might_sleep();
> __lock_kernel();
> + }
> current->lock_depth = depth;
> }
>
>
^ permalink raw reply [flat|nested] 100+ messages in thread* Re: [GIT PATCH] TTY patches for 2.6.33-git
2009-12-12 22:33 ` Thomas Gleixner
@ 2009-12-12 23:17 ` Linus Torvalds
2009-12-13 6:58 ` Ingo Molnar
0 siblings, 1 reply; 100+ messages in thread
From: Linus Torvalds @ 2009-12-12 23:17 UTC (permalink / raw)
To: Thomas Gleixner
Cc: Alan Cox, Andrew Morton, Ingo Molnar, Greg KH, Peter Zijlstra,
linux-kernel
On Sat, 12 Dec 2009, Thomas Gleixner wrote:
> >
> > Anybody willing to be the guinea-pig?
>
> Replaced my patch with yours and it works the same way (except for the
> PREEMPT=n case)
>
> Acked-and-Tested-by: Thomas Gleixner <tglx@linutronix.de>
Ok, I also decided to just test it myself too (after applying the tty
layer fix) and it doesn't seem to cause any problems, so I've committed
it.
If there is dubious BKL usage that triggers the new might_sleep() warning
(and it turns out that it's necessary and not really fixable), we can
always just remove it again. But on the other hand, maybe it shows some
other potential problems that should just be fixed.
We've had quite a bit of BKL work this merge-window. Maybe we'll even get
rid of it one of these days. There are "only" about 600 instances of
"lock_kernel()" in the tree right now ;)
Linus
^ permalink raw reply [flat|nested] 100+ messages in thread
* Re: [GIT PATCH] TTY patches for 2.6.33-git
2009-12-12 23:17 ` Linus Torvalds
@ 2009-12-13 6:58 ` Ingo Molnar
2009-12-13 11:36 ` Alan Cox
` (2 more replies)
0 siblings, 3 replies; 100+ messages in thread
From: Ingo Molnar @ 2009-12-13 6:58 UTC (permalink / raw)
To: Linus Torvalds
Cc: Thomas Gleixner, Alan Cox, Andrew Morton, Greg KH, Peter Zijlstra,
linux-kernel
* Linus Torvalds <torvalds@linux-foundation.org> wrote:
> We've had quite a bit of BKL work this merge-window. Maybe we'll even get
> rid of it one of these days. There are "only" about 600 instances of
> "lock_kernel()" in the tree right now ;)
I tend to use unlock_kernel() as the metric. (as it's more precisely greppable
and it is also more indicative of the underlying complexity of locking, as it
gets used more in more complex scenarios)
In the last ~4.5 years:
earth4:~/tip> git checkout v2.6.12
Date: Fri Jun 17 12:48:29 2005 -0700
earth4:~/tip> git grep -w unlock_kernel | wc -l
713
earth4:~/tip> git checkout linus
Date: Fri Dec 11 20:58:20 2009 -0800
earth4:~/tip> git grep -w unlock_kernel | wc -l
841
we grew the (absolute) number of BKL sites by ~15%. Certainly the kernel grew
at a much faster rate, so the relative proportion of the BKL shrunk.
Also, a lot of BKL use was hidden before, and due to the BKL removal
activities (by Thomas, Frederic, Jon, Alan and others) the remaining BKL using
sites are a lot more well defined, a lot more isolated and thus a lot more
removable than ever before.
Ingo
^ permalink raw reply [flat|nested] 100+ messages in thread* Re: [GIT PATCH] TTY patches for 2.6.33-git
2009-12-13 6:58 ` Ingo Molnar
@ 2009-12-13 11:36 ` Alan Cox
2009-12-13 12:13 ` Ingo Molnar
2009-12-13 17:46 ` Linus Torvalds
2009-12-13 17:55 ` Arjan van de Ven
2 siblings, 1 reply; 100+ messages in thread
From: Alan Cox @ 2009-12-13 11:36 UTC (permalink / raw)
To: Ingo Molnar
Cc: Linus Torvalds, Thomas Gleixner, Andrew Morton, Greg KH,
Peter Zijlstra, linux-kernel
> earth4:~/tip> git checkout linus
> Date: Fri Dec 11 20:58:20 2009 -0800
> earth4:~/tip> git grep -w unlock_kernel | wc -l
> 841
>
> we grew the (absolute) number of BKL sites by ~15%. Certainly the kernel grew
> at a much faster rate, so the relative proportion of the BKL shrunk.
Thats actually very misleading. The reason is we have created more
lock/unlock points as we remove and drive down the lock.
By your metric the original SMP kernel was best - it had one of each 8)
> Also, a lot of BKL use was hidden before, and due to the BKL removal
> activities (by Thomas, Frederic, Jon, Alan and others) the remaining BKL using
> sites are a lot more well defined, a lot more isolated and thus a lot more
> removable than ever before.
ioctl is almost done and I've gont some other random ones in my tree.
lseek is close. At that point most of the nasties are squashed except tty.
We do have some remaining locking horrors some partly introduced by the
finer locking work in the past including the rather nasty device
unload/load v open file handle races.
^ permalink raw reply [flat|nested] 100+ messages in thread
* Re: [GIT PATCH] TTY patches for 2.6.33-git
2009-12-13 11:36 ` Alan Cox
@ 2009-12-13 12:13 ` Ingo Molnar
0 siblings, 0 replies; 100+ messages in thread
From: Ingo Molnar @ 2009-12-13 12:13 UTC (permalink / raw)
To: Alan Cox
Cc: Linus Torvalds, Thomas Gleixner, Andrew Morton, Greg KH,
Peter Zijlstra, linux-kernel
* Alan Cox <alan@lxorguk.ukuu.org.uk> wrote:
> > earth4:~/tip> git checkout linus
> > Date: Fri Dec 11 20:58:20 2009 -0800
> > earth4:~/tip> git grep -w unlock_kernel | wc -l
> > 841
> >
> > we grew the (absolute) number of BKL sites by ~15%. Certainly the kernel grew
> > at a much faster rate, so the relative proportion of the BKL shrunk.
>
> Thats actually very misleading. [...]
Somewhat, so i qualified it with the next paragraph:
> > Also, a lot of BKL use was hidden before, and due to the BKL removal
> > activities (by Thomas, Frederic, Jon, Alan and others) the remaining BKL
> > using sites are a lot more well defined, a lot more isolated and thus a
> > lot more removable than ever before.
Thanks,
Ingo
^ permalink raw reply [flat|nested] 100+ messages in thread
* Re: [GIT PATCH] TTY patches for 2.6.33-git
2009-12-13 6:58 ` Ingo Molnar
2009-12-13 11:36 ` Alan Cox
@ 2009-12-13 17:46 ` Linus Torvalds
2009-12-13 18:17 ` Ingo Molnar
2009-12-13 17:55 ` Arjan van de Ven
2 siblings, 1 reply; 100+ messages in thread
From: Linus Torvalds @ 2009-12-13 17:46 UTC (permalink / raw)
To: Ingo Molnar
Cc: Thomas Gleixner, Alan Cox, Andrew Morton, Greg KH, Peter Zijlstra,
linux-kernel
On Sun, 13 Dec 2009, Ingo Molnar wrote:
>
> In the last ~4.5 years:
>
> earth4:~/tip> git checkout v2.6.12
> Date: Fri Jun 17 12:48:29 2005 -0700
> earth4:~/tip> git grep -w unlock_kernel | wc -l
> 713
>
> earth4:~/tip> git checkout linus
> Date: Fri Dec 11 20:58:20 2009 -0800
> earth4:~/tip> git grep -w unlock_kernel | wc -l
> 841
Git hint of the day: you don't need to check out a kernel to do "git
grep".
Do this:
git grep -w unlock_kernel v2.6.12 | wc
and it will JustWork(tm).
> Also, a lot of BKL use was hidden before, and due to the BKL removal
> activities (by Thomas, Frederic, Jon, Alan and others) the remaining BKL using
> sites are a lot more well defined, a lot more isolated and thus a lot more
> removable than ever before.
That's the main thing. We've been pushing them down a lot.
We still have a few annoying core ones, though. I hate the execve() and
file locking ones.
Linus
^ permalink raw reply [flat|nested] 100+ messages in thread
* Re: [GIT PATCH] TTY patches for 2.6.33-git
2009-12-13 17:46 ` Linus Torvalds
@ 2009-12-13 18:17 ` Ingo Molnar
2009-12-13 18:33 ` Trond Myklebust
2009-12-13 19:04 ` Frederic Weisbecker
0 siblings, 2 replies; 100+ messages in thread
From: Ingo Molnar @ 2009-12-13 18:17 UTC (permalink / raw)
To: Linus Torvalds
Cc: Thomas Gleixner, Alan Cox, Andrew Morton, Greg KH, Peter Zijlstra,
linux-kernel
* Linus Torvalds <torvalds@linux-foundation.org> wrote:
>
>
> On Sun, 13 Dec 2009, Ingo Molnar wrote:
> >
> > In the last ~4.5 years:
> >
> > earth4:~/tip> git checkout v2.6.12
> > Date: Fri Jun 17 12:48:29 2005 -0700
> > earth4:~/tip> git grep -w unlock_kernel | wc -l
> > 713
> >
> > earth4:~/tip> git checkout linus
> > Date: Fri Dec 11 20:58:20 2009 -0800
> > earth4:~/tip> git grep -w unlock_kernel | wc -l
> > 841
>
> Git hint of the day: you don't need to check out a kernel to do "git
> grep".
>
> Do this:
>
> git grep -w unlock_kernel v2.6.12 | wc
>
> and it will JustWork(tm).
/me adds it to the metal toolbox
> > Also, a lot of BKL use was hidden before, and due to the BKL removal
> > activities (by Thomas, Frederic, Jon, Alan and others) the remaining BKL using
> > sites are a lot more well defined, a lot more isolated and thus a lot more
> > removable than ever before.
>
> That's the main thing. We've been pushing them down a lot.
>
> We still have a few annoying core ones, though. I hate the execve() and file
> locking ones.
When we did the BKL-as-a-mutex trick and let lockdep loose on it, three areas
were particularly tricky: tty, reiser3 and NFS. tty and reiserfs should be ok
now, but i havent seen much activity on the NFS front.
Ingo
^ permalink raw reply [flat|nested] 100+ messages in thread
* Re: [GIT PATCH] TTY patches for 2.6.33-git
2009-12-13 18:17 ` Ingo Molnar
@ 2009-12-13 18:33 ` Trond Myklebust
2009-12-13 19:07 ` Linus Torvalds
2009-12-13 19:04 ` Frederic Weisbecker
1 sibling, 1 reply; 100+ messages in thread
From: Trond Myklebust @ 2009-12-13 18:33 UTC (permalink / raw)
To: Ingo Molnar
Cc: Linus Torvalds, Thomas Gleixner, Alan Cox, Andrew Morton, Greg KH,
Peter Zijlstra, linux-kernel
On Sun, 2009-12-13 at 19:17 +0100, Ingo Molnar wrote:
> When we did the BKL-as-a-mutex trick and let lockdep loose on it, three areas
> were particularly tricky: tty, reiser3 and NFS. tty and reiserfs should be ok
> now, but i havent seen much activity on the NFS front.
I've got a couple of NFS bkl removal patches queued up that I'll send on
to Linus today, but they will not suffice to fully remove BKL from the
NFS code.
The main remaining problem area is that of file locking (i.e. anything
that references inode->i_flock). I've started work on that, but a couple
of higher interrupts have prevented me from pulling it all together in
time for this merge window...
Trond
^ permalink raw reply [flat|nested] 100+ messages in thread
* Re: [GIT PATCH] TTY patches for 2.6.33-git
2009-12-13 18:33 ` Trond Myklebust
@ 2009-12-13 19:07 ` Linus Torvalds
2009-12-13 19:17 ` Trond Myklebust
0 siblings, 1 reply; 100+ messages in thread
From: Linus Torvalds @ 2009-12-13 19:07 UTC (permalink / raw)
To: Trond Myklebust
Cc: Ingo Molnar, Thomas Gleixner, Alan Cox, Andrew Morton, Greg KH,
Peter Zijlstra, linux-kernel
On Sun, 13 Dec 2009, Trond Myklebust wrote:
>
> The main remaining problem area is that of file locking (i.e. anything
> that references inode->i_flock). I've started work on that, but a couple
> of higher interrupts have prevented me from pulling it all together in
> time for this merge window...
I'm pretty sure we've had at least two trees with the file locking code
fixed, but NFS in a status of "unknown".
If I recall correctly, the file locking code itself is not that hard:
we've done it without the kernel lock in the past (long long ago), and the
lock usage doesn't nest (or at least it didn't at some point back then ;).
In fact, I think we even do the actual lock data structure allocations
outside of the kernel lock exactly because we at one time had a patch that
used a spinlock for protection of the lists.
(Again, not only my memory, but the code itself may have bitrotted in the
meantime, of course).
Linus
^ permalink raw reply [flat|nested] 100+ messages in thread
* Re: [GIT PATCH] TTY patches for 2.6.33-git
2009-12-13 19:07 ` Linus Torvalds
@ 2009-12-13 19:17 ` Trond Myklebust
0 siblings, 0 replies; 100+ messages in thread
From: Trond Myklebust @ 2009-12-13 19:17 UTC (permalink / raw)
To: Linus Torvalds
Cc: Ingo Molnar, Thomas Gleixner, Alan Cox, Andrew Morton, Greg KH,
Peter Zijlstra, linux-kernel
On Sun, 2009-12-13 at 11:07 -0800, Linus Torvalds wrote:
>
> On Sun, 13 Dec 2009, Trond Myklebust wrote:
> >
> > The main remaining problem area is that of file locking (i.e. anything
> > that references inode->i_flock). I've started work on that, but a couple
> > of higher interrupts have prevented me from pulling it all together in
> > time for this merge window...
>
> I'm pretty sure we've had at least two trees with the file locking code
> fixed, but NFS in a status of "unknown".
>
> If I recall correctly, the file locking code itself is not that hard:
> we've done it without the kernel lock in the past (long long ago), and the
> lock usage doesn't nest (or at least it didn't at some point back then ;).
> In fact, I think we even do the actual lock data structure allocations
> outside of the kernel lock exactly because we at one time had a patch that
> used a spinlock for protection of the lists.
After the current set of patches, have been merged by you, the only
stuff that will continue to rely on nested BKL will be lockd. I can fix
that up in the next cycle.
> (Again, not only my memory, but the code itself may have bitrotted in the
> meantime, of course).
Agreed. I'm not saying that it's hard. I'm just saying that I ran out of
time due to other commitments.
Cheers
Trond
^ permalink raw reply [flat|nested] 100+ messages in thread
* Re: [GIT PATCH] TTY patches for 2.6.33-git
2009-12-13 18:17 ` Ingo Molnar
2009-12-13 18:33 ` Trond Myklebust
@ 2009-12-13 19:04 ` Frederic Weisbecker
2009-12-13 19:09 ` Trond Myklebust
1 sibling, 1 reply; 100+ messages in thread
From: Frederic Weisbecker @ 2009-12-13 19:04 UTC (permalink / raw)
To: Ingo Molnar
Cc: Linus Torvalds, Thomas Gleixner, Alan Cox, Andrew Morton, Greg KH,
Peter Zijlstra, linux-kernel
On Sun, Dec 13, 2009 at 07:17:26PM +0100, Ingo Molnar wrote:
>
> * Linus Torvalds <torvalds@linux-foundation.org> wrote:
>
> >
> >
> > On Sun, 13 Dec 2009, Ingo Molnar wrote:
> > >
> > > In the last ~4.5 years:
> > >
> > > earth4:~/tip> git checkout v2.6.12
> > > Date: Fri Jun 17 12:48:29 2005 -0700
> > > earth4:~/tip> git grep -w unlock_kernel | wc -l
> > > 713
> > >
> > > earth4:~/tip> git checkout linus
> > > Date: Fri Dec 11 20:58:20 2009 -0800
> > > earth4:~/tip> git grep -w unlock_kernel | wc -l
> > > 841
> >
> > Git hint of the day: you don't need to check out a kernel to do "git
> > grep".
> >
> > Do this:
> >
> > git grep -w unlock_kernel v2.6.12 | wc
> >
> > and it will JustWork(tm).
>
> /me adds it to the metal toolbox
>
> > > Also, a lot of BKL use was hidden before, and due to the BKL removal
> > > activities (by Thomas, Frederic, Jon, Alan and others) the remaining BKL using
> > > sites are a lot more well defined, a lot more isolated and thus a lot more
> > > removable than ever before.
> >
> > That's the main thing. We've been pushing them down a lot.
> >
> > We still have a few annoying core ones, though. I hate the execve() and file
> > locking ones.
>
> When we did the BKL-as-a-mutex trick and let lockdep loose on it, three areas
> were particularly tricky: tty, reiser3 and NFS. tty and reiserfs should be ok
> now, but i havent seen much activity on the NFS front.
>
> Ingo
Nfs was a problem in the BKL-as-a-mutex tree because it is acquired
recursively and then locked up. And I suspect this recursion happens
only on mount time because vfs acquires it too there.
But looking at it more closely, it doesn't look that dramatic at
a first glance.
git-grep unlock_kernel fs/nfs
fs/nfs/callback.c: unlock_kernel();
fs/nfs/callback.c: unlock_kernel();
In nfs4_callback_svc() it embraces the socket
listening/processing callback thread.
svc_recv() might sleep so the bkl can be
lost in the middle.
And then svc_process().
This doesn't seem to protect anything there.
In nfs4_callback_svc() it's about the same thing, plus
a list manipulation but protected by a spinlock.
fs/nfs/delegation.c: unlock_kernel();
fs/nfs/delegation.c: unlock_kernel();
fs/nfs/nfs4state.c: unlock_kernel();
fs/nfs/nfs4state.c: unlock_kernel();
In the above cases we have the following comment:
/* Protect inode->i_flock using the BKL */
And really it doesn't seem to protect anything else,
fortunately it is acquired in a short path.
fs/nfs/super.c: unlock_kernel();
fs/nfs/super.c: unlock_kernel();
Protect the mount/unmount path, a bit trickier there.
But really that looks way much easier to fix than it was
with reiserfs.
^ permalink raw reply [flat|nested] 100+ messages in thread
* Re: [GIT PATCH] TTY patches for 2.6.33-git
2009-12-13 19:04 ` Frederic Weisbecker
@ 2009-12-13 19:09 ` Trond Myklebust
2009-12-13 19:19 ` Linus Torvalds
2009-12-13 19:20 ` Frederic Weisbecker
0 siblings, 2 replies; 100+ messages in thread
From: Trond Myklebust @ 2009-12-13 19:09 UTC (permalink / raw)
To: Frederic Weisbecker
Cc: Ingo Molnar, Linus Torvalds, Thomas Gleixner, Alan Cox,
Andrew Morton, Greg KH, Peter Zijlstra, linux-kernel
On Sun, 2009-12-13 at 20:04 +0100, Frederic Weisbecker wrote:
> In the above cases we have the following comment:
>
> /* Protect inode->i_flock using the BKL */
>
> And really it doesn't seem to protect anything else,
> fortunately it is acquired in a short path.
As I said in my reply, this is the tough one, because the BKL protection
is imposed by the VFS locking scheme used in fs/locks.c.
There is a similar dependency imposed upon fs/lockd/
I'm working on this, but I don't have anything ready for 2.6.33.
> fs/nfs/super.c: unlock_kernel();
> fs/nfs/super.c: unlock_kernel();
>
> Protect the mount/unmount path, a bit trickier there.
>
> But really that looks way much easier to fix than it was
> with reiserfs.
All the other cases you list should be fixed in the GIT PULL request
that I just put out.
Trond
^ permalink raw reply [flat|nested] 100+ messages in thread
* Re: [GIT PATCH] TTY patches for 2.6.33-git
2009-12-13 19:09 ` Trond Myklebust
@ 2009-12-13 19:19 ` Linus Torvalds
2009-12-13 20:04 ` Trond Myklebust
2009-12-13 19:20 ` Frederic Weisbecker
1 sibling, 1 reply; 100+ messages in thread
From: Linus Torvalds @ 2009-12-13 19:19 UTC (permalink / raw)
To: Trond Myklebust
Cc: Frederic Weisbecker, Ingo Molnar, Thomas Gleixner, Alan Cox,
Andrew Morton, Greg KH, Peter Zijlstra, linux-kernel
On Sun, 13 Dec 2009, Trond Myklebust wrote:
> On Sun, 2009-12-13 at 20:04 +0100, Frederic Weisbecker wrote:
> > In the above cases we have the following comment:
> >
> > /* Protect inode->i_flock using the BKL */
> >
> > And really it doesn't seem to protect anything else,
> > fortunately it is acquired in a short path.
>
> As I said in my reply, this is the tough one, because the BKL protection
> is imposed by the VFS locking scheme used in fs/locks.c.
>
> There is a similar dependency imposed upon fs/lockd/
Note that since NFS seems to be the only one who really cares, I think the
appropriate course of action is to just replace the BKL - preferably with
a spinlock that you just drop before you do anything that blocks.
Not only does the BKL already do that (so the locking doesn't change), but
I think most _users_ of the BKL actually already do the explicit dropping
of the lock (rather than the implicit one done by schedule()) because it's
already been a scalability issue and we've had some history of trying
alternative approaches that didn't do that whole auto-dropping anyway
(whether those alternate approaches be semaphores or spinlocks).
So don't worry about the "imposed by the VFS" thing. I think you can
fairly easily change the VFS side.
Linus
^ permalink raw reply [flat|nested] 100+ messages in thread
* Re: [GIT PATCH] TTY patches for 2.6.33-git
2009-12-13 19:19 ` Linus Torvalds
@ 2009-12-13 20:04 ` Trond Myklebust
0 siblings, 0 replies; 100+ messages in thread
From: Trond Myklebust @ 2009-12-13 20:04 UTC (permalink / raw)
To: Linus Torvalds
Cc: Frederic Weisbecker, Ingo Molnar, Thomas Gleixner, Alan Cox,
Andrew Morton, Greg KH, Peter Zijlstra, linux-kernel
On Sun, 2009-12-13 at 11:19 -0800, Linus Torvalds wrote:
>
> On Sun, 13 Dec 2009, Trond Myklebust wrote:
>
> > On Sun, 2009-12-13 at 20:04 +0100, Frederic Weisbecker wrote:
> > > In the above cases we have the following comment:
> > >
> > > /* Protect inode->i_flock using the BKL */
> > >
> > > And really it doesn't seem to protect anything else,
> > > fortunately it is acquired in a short path.
> >
> > As I said in my reply, this is the tough one, because the BKL protection
> > is imposed by the VFS locking scheme used in fs/locks.c.
> >
> > There is a similar dependency imposed upon fs/lockd/
>
> Note that since NFS seems to be the only one who really cares, I think the
> appropriate course of action is to just replace the BKL - preferably with
> a spinlock that you just drop before you do anything that blocks.
>
> Not only does the BKL already do that (so the locking doesn't change), but
> I think most _users_ of the BKL actually already do the explicit dropping
> of the lock (rather than the implicit one done by schedule()) because it's
> already been a scalability issue and we've had some history of trying
> alternative approaches that didn't do that whole auto-dropping anyway
> (whether those alternate approaches be semaphores or spinlocks).
>
> So don't worry about the "imposed by the VFS" thing. I think you can
> fairly easily change the VFS side.
That comment applies to the NFSv4 code, which applies the BKL only
because we need to traverse the inode->i_flock list. There is no
recursive use of the BKL there, and we can trivially replace it with
whichever new lock that that is chosen to replace the BKL in fs/locks.c.
To fix the lockd module, we have to backport some of the lessons we
learned when writing the NFSv4 file locking code. It won't be a huge
job, but I'd feel uncomfortable if I were to do it in a hurry just in
order to meet the merge window deadline.
Trond
^ permalink raw reply [flat|nested] 100+ messages in thread
* Re: [GIT PATCH] TTY patches for 2.6.33-git
2009-12-13 19:09 ` Trond Myklebust
2009-12-13 19:19 ` Linus Torvalds
@ 2009-12-13 19:20 ` Frederic Weisbecker
1 sibling, 0 replies; 100+ messages in thread
From: Frederic Weisbecker @ 2009-12-13 19:20 UTC (permalink / raw)
To: Trond Myklebust
Cc: Ingo Molnar, Linus Torvalds, Thomas Gleixner, Alan Cox,
Andrew Morton, Greg KH, Peter Zijlstra, linux-kernel
On Sun, Dec 13, 2009 at 02:09:14PM -0500, Trond Myklebust wrote:
> On Sun, 2009-12-13 at 20:04 +0100, Frederic Weisbecker wrote:
> > In the above cases we have the following comment:
> >
> > /* Protect inode->i_flock using the BKL */
> >
> > And really it doesn't seem to protect anything else,
> > fortunately it is acquired in a short path.
>
> As I said in my reply, this is the tough one, because the BKL protection
> is imposed by the VFS locking scheme used in fs/locks.c.
>
> There is a similar dependency imposed upon fs/lockd/
Ok.
> > fs/nfs/super.c: unlock_kernel();
> > fs/nfs/super.c: unlock_kernel();
> >
> > Protect the mount/unmount path, a bit trickier there.
> >
> > But really that looks way much easier to fix than it was
> > with reiserfs.
>
> All the other cases you list should be fixed in the GIT PULL request
> that I just put out.
>
Cool, thanks a lot!
^ permalink raw reply [flat|nested] 100+ messages in thread
* Re: [GIT PATCH] TTY patches for 2.6.33-git
2009-12-13 6:58 ` Ingo Molnar
2009-12-13 11:36 ` Alan Cox
2009-12-13 17:46 ` Linus Torvalds
@ 2009-12-13 17:55 ` Arjan van de Ven
2009-12-13 19:16 ` Frederic Weisbecker
2 siblings, 1 reply; 100+ messages in thread
From: Arjan van de Ven @ 2009-12-13 17:55 UTC (permalink / raw)
To: Ingo Molnar
Cc: Linus Torvalds, Thomas Gleixner, Alan Cox, Andrew Morton, Greg KH,
Peter Zijlstra, linux-kernel
On Sun, 13 Dec 2009 07:58:44 +0100
Ingo Molnar <mingo@elte.hu> wrote:
>
> * Linus Torvalds <torvalds@linux-foundation.org> wrote:
>
> > We've had quite a bit of BKL work this merge-window. Maybe we'll
> > even get rid of it one of these days. There are "only" about 600
> > instances of "lock_kernel()" in the tree right now ;)
>
> I tend to use unlock_kernel() as the metric. (as it's more precisely
> greppable and it is also more indicative of the underlying complexity
> of locking, as it gets used more in more complex scenarios)
another metric is... how many times do we take the BKL for some
workload. (For example booting or compiling a kernel).
A counter like "BKLs-per-second" would be nice to expose
(and then we can track that number going up as a regression etc)
For me, a secondary metric would be "how many times do we depend on the
magic auto-drop/reget behavior".. also easy to build a counter for.
--
Arjan van de Ven Intel Open Source Technology Centre
For development, discussion and tips for power savings,
visit http://www.lesswatts.org
^ permalink raw reply [flat|nested] 100+ messages in thread
* Re: [GIT PATCH] TTY patches for 2.6.33-git
2009-12-13 17:55 ` Arjan van de Ven
@ 2009-12-13 19:16 ` Frederic Weisbecker
2009-12-14 5:30 ` Arjan van de Ven
0 siblings, 1 reply; 100+ messages in thread
From: Frederic Weisbecker @ 2009-12-13 19:16 UTC (permalink / raw)
To: Arjan van de Ven
Cc: Ingo Molnar, Linus Torvalds, Thomas Gleixner, Alan Cox,
Andrew Morton, Greg KH, Peter Zijlstra, linux-kernel
On Sun, Dec 13, 2009 at 09:55:34AM -0800, Arjan van de Ven wrote:
> On Sun, 13 Dec 2009 07:58:44 +0100
> Ingo Molnar <mingo@elte.hu> wrote:
>
> >
> > * Linus Torvalds <torvalds@linux-foundation.org> wrote:
> >
> > > We've had quite a bit of BKL work this merge-window. Maybe we'll
> > > even get rid of it one of these days. There are "only" about 600
> > > instances of "lock_kernel()" in the tree right now ;)
> >
> > I tend to use unlock_kernel() as the metric. (as it's more precisely
> > greppable and it is also more indicative of the underlying complexity
> > of locking, as it gets used more in more complex scenarios)
>
> another metric is... how many times do we take the BKL for some
> workload. (For example booting or compiling a kernel).
> A counter like "BKLs-per-second" would be nice to expose
> (and then we can track that number going up as a regression etc)
We have the bkl tracepoints for that, attaching an example below,
blkdev_get/bkldev_put is among the highest consumer for me.
Then after we have (not sorted in order) tty, __blkdev_driver_ioctl(),
etc...
# tracer: nop
#
# TASK-PID CPU# TIMESTAMP FUNCTION
# | | | | |
hald-addon-stor-4285 [000] 413.952233: lock_kernel: depth=0 file:line=fs/block_dev.c:1192 func=__blkdev_get()
hald-addon-stor-4285 [001] 413.969331: unlock_kernel: depth=-1 file:line=fs/block_dev.c:1278 func=__blkdev_get()
hald-addon-stor-4285 [001] 413.969343: lock_kernel: depth=0 file:line=block/ioctl.c:171 func=__blkdev_driver_ioctl()
hald-addon-stor-4285 [001] 413.989339: unlock_kernel: depth=-1 file:line=block/ioctl.c:173 func=__blkdev_driver_ioctl()
hald-addon-stor-4285 [001] 413.989349: lock_kernel: depth=0 file:line=fs/block_dev.c:1358 func=__blkdev_put()
hald-addon-stor-4285 [001] 413.992067: unlock_kernel: depth=-1 file:line=fs/block_dev.c:1383 func=__blkdev_put()
hald-addon-stor-4285 [001] 415.953350: lock_kernel: depth=0 file:line=fs/block_dev.c:1192 func=__blkdev_get()
hald-addon-stor-4285 [001] 415.970537: unlock_kernel: depth=-1 file:line=fs/block_dev.c:1278 func=__blkdev_get()
hald-addon-stor-4285 [001] 415.970552: lock_kernel: depth=0 file:line=block/ioctl.c:171 func=__blkdev_driver_ioctl()
hald-addon-stor-4285 [001] 415.990404: unlock_kernel: depth=-1 file:line=block/ioctl.c:173 func=__blkdev_driver_ioctl()
hald-addon-stor-4285 [001] 415.990414: lock_kernel: depth=0 file:line=fs/block_dev.c:1358 func=__blkdev_put()
hald-addon-stor-4285 [001] 415.993139: unlock_kernel: depth=-1 file:line=fs/block_dev.c:1383 func=__blkdev_put()
less-5147 [001] 416.155702: lock_kernel: depth=0 file:line=drivers/char/tty_io.c:1847 func=tty_open()
less-5147 [001] 416.155712: unlock_kernel: depth=-1 file:line=drivers/char/tty_io.c:1849 func=tty_open()
lesspipe-5149 [001] 416.159402: lock_kernel: depth=0 file:line=drivers/char/tty_io.c:1847 func=tty_open()
lesspipe-5149 [001] 416.159412: unlock_kernel: depth=-1 file:line=drivers/char/tty_io.c:1849 func=tty_open()
lesspipe-5149 [001] 416.159418: lock_kernel: depth=0 file:line=drivers/char/tty_io.c:1870 func=tty_release()
lesspipe-5149 [001] 416.159419: lock_kernel: depth=1 file:line=drivers/char/tty_io.c:1911 func=tty_fasync()
lesspipe-5149 [001] 416.159421: unlock_kernel: depth=0 file:line=drivers/char/tty_io.c:1943 func=tty_fasync()
lesspipe-5149 [001] 416.159423: unlock_kernel: depth=-1 file:line=drivers/char/tty_io.c:1872 func=tty_release()
less-5147 [001] 420.459944: lock_kernel: depth=0 file:line=drivers/char/tty_io.c:1870 func=tty_release()
less-5147 [001] 420.459949: lock_kernel: depth=1 file:line=drivers/char/tty_io.c:1911 func=tty_fasync()
less-5147 [001] 420.459954: unlock_kernel: depth=0 file:line=drivers/char/tty_io.c:1943 func=tty_fasync()
less-5147 [001] 420.459960: unlock_kernel: depth=-1 file:line=drivers/char/tty_io.c:1872 func=tty_release()
hald-addon-stor-4285 [001] 421.954357: lock_kernel: depth=0 file:line=fs/block_dev.c:1192 func=__blkdev_get()
hald-addon-stor-4285 [001] 421.971499: unlock_kernel: depth=-1 file:line=fs/block_dev.c:1278 func=__blkdev_get()
hald-addon-stor-4285 [001] 421.971510: lock_kernel: depth=0 file:line=block/ioctl.c:171 func=__blkdev_driver_ioctl()
hald-addon-stor-4285 [001] 421.991585: unlock_kernel: depth=-1 file:line=block/ioctl.c:173 func=__blkdev_driver_ioctl()
hald-addon-stor-4285 [001] 421.991604: lock_kernel: depth=0 file:line=fs/block_dev.c:1358 func=__blkdev_put()
hald-addon-stor-4285 [001] 421.994321: unlock_kernel: depth=-1 file:line=fs/block_dev.c:1383 func=__blkdev_put()
hald-addon-stor-4285 [000] 22215.805856: lock_kernel: depth=0 file:line=fs/block_dev.c:1192 func=__blkdev_get()
hald-addon-stor-4285 [000] 22215.823023: unlock_kernel: depth=-1 file:line=fs/block_dev.c:1278 func=__blkdev_get()
hald-addon-stor-4285 [000] 22215.823035: lock_kernel: depth=0 file:line=block/ioctl.c:171 func=__blkdev_driver_ioctl()
hald-addon-stor-4285 [000] 22215.842989: unlock_kernel: depth=-1 file:line=block/ioctl.c:173 func=__blkdev_driver_ioctl()
hald-addon-stor-4285 [000] 22215.843001: lock_kernel: depth=0 file:line=fs/block_dev.c:1358 func=__blkdev_put()
hald-addon-stor-4285 [000] 22215.845718: unlock_kernel: depth=-1 file:line=fs/block_dev.c:1383 func=__blkdev_put()
hald-addon-stor-4285 [000] 22217.805987: lock_kernel: depth=0 file:line=fs/block_dev.c:1192 func=__blkdev_get()
hald-addon-stor-4285 [000] 22217.823165: unlock_kernel: depth=-1 file:line=fs/block_dev.c:1278 func=__blkdev_get()
hald-addon-stor-4285 [000] 22217.823178: lock_kernel: depth=0 file:line=block/ioctl.c:171 func=__blkdev_driver_ioctl()
hald-addon-stor-4285 [000] 22217.843182: unlock_kernel: depth=-1 file:line=block/ioctl.c:173 func=__blkdev_driver_ioctl()
hald-addon-stor-4285 [000] 22217.843194: lock_kernel: depth=0 file:line=fs/block_dev.c:1358 func=__blkdev_put()
hald-addon-stor-4285 [001] 22217.845932: unlock_kernel: depth=-1 file:line=fs/block_dev.c:1383 func=__blkdev_put()
less-10802 [000] 22218.162060: lock_kernel: depth=0 file:line=drivers/char/tty_io.c:1847 func=tty_open()
less-10802 [000] 22218.162078: unlock_kernel: depth=-1 file:line=drivers/char/tty_io.c:1849 func=tty_open()
lesspipe-10804 [001] 22218.169025: lock_kernel: depth=0 file:line=drivers/char/tty_io.c:1847 func=tty_open()
lesspipe-10804 [001] 22218.169043: unlock_kernel: depth=-1 file:line=drivers/char/tty_io.c:1849 func=tty_open()
lesspipe-10804 [001] 22218.169052: lock_kernel: depth=0 file:line=drivers/char/tty_io.c:1870 func=tty_release()
lesspipe-10804 [001] 22218.169054: lock_kernel: depth=1 file:line=drivers/char/tty_io.c:1911 func=tty_fasync()
lesspipe-10804 [001] 22218.169059: unlock_kernel: depth=0 file:line=drivers/char/tty_io.c:1943 func=tty_fasync()
lesspipe-10804 [001] 22218.169062: unlock_kernel: depth=-1 file:line=drivers/char/tty_io.c:1872 func=tty_release()
less-10802 [001] 22255.644555: lock_kernel: depth=0 file:line=drivers/char/tty_io.c:1870 func=tty_release()
less-10802 [001] 22255.644560: lock_kernel: depth=1 file:line=drivers/char/tty_io.c:1911 func=tty_fasync()
less-10802 [001] 22255.644565: unlock_kernel: depth=0 file:line=drivers/char/tty_io.c:1943 func=tty_fasync()
less-10802 [001] 22255.644571: unlock_kernel: depth=-1 file:line=drivers/char/tty_io.c:1872 func=tty_release()
hald-addon-stor-4285 [001] 22255.808942: lock_kernel: depth=0 file:line=fs/block_dev.c:1192 func=__blkdev_get()
hald-addon-stor-4285 [001] 22255.826113: unlock_kernel: depth=-1 file:line=fs/block_dev.c:1278 func=__blkdev_get()
hald-addon-stor-4285 [001] 22255.826126: lock_kernel: depth=0 file:line=block/ioctl.c:171 func=__blkdev_driver_ioctl()
hald-addon-stor-4285 [001] 22255.846022: unlock_kernel: depth=-1 file:line=block/ioctl.c:173 func=__blkdev_driver_ioctl()
hald-addon-stor-4285 [001] 22255.846034: lock_kernel: depth=0 file:line=fs/block_dev.c:1358 func=__blkdev_put()
hald-addon-stor-4285 [001] 22255.848822: unlock_kernel: depth=-1 file:line=fs/block_dev.c:1383 func=__blkdev_put()
less-10810 [001] 22256.438465: lock_kernel: depth=0 file:line=drivers/char/tty_io.c:1847 func=tty_open()
less-10810 [001] 22256.438476: unlock_kernel: depth=-1 file:line=drivers/char/tty_io.c:1849 func=tty_open()
lesspipe-10812 [001] 22256.442197: lock_kernel: depth=0 file:line=drivers/char/tty_io.c:1847 func=tty_open()
lesspipe-10812 [001] 22256.442209: unlock_kernel: depth=-1 file:line=drivers/char/tty_io.c:1849 func=tty_open()
lesspipe-10812 [001] 22256.442215: lock_kernel: depth=0 file:line=drivers/char/tty_io.c:1870 func=tty_release()
lesspipe-10812 [001] 22256.442217: lock_kernel: depth=1 file:line=drivers/char/tty_io.c:1911 func=tty_fasync()
lesspipe-10812 [001] 22256.442220: unlock_kernel: depth=0 file:line=drivers/char/tty_io.c:1943 func=tty_fasync()
lesspipe-10812 [001] 22256.442223: unlock_kernel: depth=-1 file:line=drivers/char/tty_io.c:1872 func=tty_release()
less-10810 [001] 22288.556512: lock_kernel: depth=0 file:line=drivers/char/tty_io.c:1870 func=tty_release()
less-10810 [001] 22288.556518: lock_kernel: depth=1 file:line=drivers/char/tty_io.c:1911 func=tty_fasync()
less-10810 [001] 22288.556523: unlock_kernel: depth=0 file:line=drivers/char/tty_io.c:1943 func=tty_fasync()
less-10810 [001] 22288.556528: unlock_kernel: depth=-1 file:line=drivers/char/tty_io.c:1872 func=tty_release()
hald-addon-stor-4285 [001] 22289.811558: lock_kernel: depth=0 file:line=fs/block_dev.c:1192 func=__blkdev_get()
hald-addon-stor-4285 [001] 22289.828644: unlock_kernel: depth=-1 file:line=fs/block_dev.c:1278 func=__blkdev_get()
hald-addon-stor-4285 [001] 22289.828655: lock_kernel: depth=0 file:line=block/ioctl.c:171 func=__blkdev_driver_ioctl()
hald-addon-stor-4285 [001] 22289.848642: unlock_kernel: depth=-1 file:line=block/ioctl.c:173 func=__blkdev_driver_ioctl()
hald-addon-stor-4285 [001] 22289.848654: lock_kernel: depth=0 file:line=fs/block_dev.c:1358 func=__blkdev_put()
hald-addon-stor-4285 [001] 22289.851377: unlock_kernel: depth=-1 file:line=fs/block_dev.c:1383 func=__blkdev_put()
hald-addon-stor-4285 [001] 22291.811651: lock_kernel: depth=0 file:line=fs/block_dev.c:1192 func=__blkdev_get()
hald-addon-stor-4285 [001] 22291.828861: unlock_kernel: depth=-1 file:line=fs/block_dev.c:1278 func=__blkdev_get()
hald-addon-stor-4285 [001] 22291.828873: lock_kernel: depth=0 file:line=block/ioctl.c:171 func=__blkdev_driver_ioctl()
hald-addon-stor-4285 [001] 22291.848808: unlock_kernel: depth=-1 file:line=block/ioctl.c:173 func=__blkdev_driver_ioctl()
hald-addon-stor-4285 [001] 22291.848820: lock_kernel: depth=0 file:line=fs/block_dev.c:1358 func=__blkdev_put()
hald-addon-stor-4285 [001] 22291.851539: unlock_kernel: depth=-1 file:line=fs/block_dev.c:1383 func=__blkdev_put()
hald-addon-stor-4285 [001] 22293.811865: lock_kernel: depth=0 file:line=fs/block_dev.c:1192 func=__blkdev_get()
hald-addon-stor-4285 [001] 22293.829005: unlock_kernel: depth=-1 file:line=fs/block_dev.c:1278 func=__blkdev_get()
hald-addon-stor-4285 [001] 22293.829018: lock_kernel: depth=0 file:line=block/ioctl.c:171 func=__blkdev_driver_ioctl()
hald-addon-stor-4285 [001] 22293.848924: unlock_kernel: depth=-1 file:line=block/ioctl.c:173 func=__blkdev_driver_ioctl()
hald-addon-stor-4285 [001] 22293.848939: lock_kernel: depth=0 file:line=fs/block_dev.c:1358 func=__blkdev_put()
hald-addon-stor-4285 [001] 22293.851648: unlock_kernel: depth=-1 file:line=fs/block_dev.c:1383 func=__blkdev_put()
hald-addon-stor-4285 [000] 22295.812598: lock_kernel: depth=0 file:line=fs/block_dev.c:1192 func=__blkdev_get()
hald-addon-stor-4285 [000] 22295.829710: unlock_kernel: depth=-1 file:line=fs/block_dev.c:1278 func=__blkdev_get()
hald-addon-stor-4285 [000] 22295.829729: lock_kernel: depth=0 file:line=block/ioctl.c:171 func=__blkdev_driver_ioctl()
hald-addon-stor-4285 [001] 22295.849774: unlock_kernel: depth=-1 file:line=block/ioctl.c:173 func=__blkdev_driver_ioctl()
hald-addon-stor-4285 [001] 22295.849793: lock_kernel: depth=0 file:line=fs/block_dev.c:1358 func=__blkdev_put()
hald-addon-stor-4285 [000] 22295.852533: unlock_kernel: depth=-1 file:line=fs/block_dev.c:1383 func=__blkdev_put()
hald-addon-stor-4285 [000] 22297.812827: lock_kernel: depth=0 file:line=fs/block_dev.c:1192 func=__blkdev_get()
hald-addon-stor-4285 [001] 22297.830066: unlock_kernel: depth=-1 file:line=fs/block_dev.c:1278 func=__blkdev_get()
hald-addon-stor-4285 [001] 22297.830080: lock_kernel: depth=0 file:line=block/ioctl.c:171 func=__blkdev_driver_ioctl()
hald-addon-stor-4285 [001] 22297.850050: unlock_kernel: depth=-1 file:line=block/ioctl.c:173 func=__blkdev_driver_ioctl()
hald-addon-stor-4285 [001] 22297.850063: lock_kernel: depth=0 file:line=fs/block_dev.c:1358 func=__blkdev_put()
hald-addon-stor-4285 [001] 22297.852787: unlock_kernel: depth=-1 file:line=fs/block_dev.c:1383 func=__blkdev_put()
hald-addon-stor-4285 [001] 22299.813048: lock_kernel: depth=0 file:line=fs/block_dev.c:1192 func=__blkdev_get()
hald-addon-stor-4285 [001] 22299.830191: unlock_kernel: depth=-1 file:line=fs/block_dev.c:1278 func=__blkdev_get()
hald-addon-stor-4285 [001] 22299.830202: lock_kernel: depth=0 file:line=block/ioctl.c:171 func=__blkdev_driver_ioctl()
hald-addon-stor-4285 [001] 22299.850124: unlock_kernel: depth=-1 file:line=block/ioctl.c:173 func=__blkdev_driver_ioctl()
hald-addon-stor-4285 [001] 22299.850139: lock_kernel: depth=0 file:line=fs/block_dev.c:1358 func=__blkdev_put()
hald-addon-stor-4285 [001] 22299.852861: unlock_kernel: depth=-1 file:line=fs/block_dev.c:1383 func=__blkdev_put()
hald-addon-stor-4285 [001] 22301.813131: lock_kernel: depth=0 file:line=fs/block_dev.c:1192 func=__blkdev_get()
hald-addon-stor-4285 [000] 22301.830331: unlock_kernel: depth=-1 file:line=fs/block_dev.c:1278 func=__blkdev_get()
hald-addon-stor-4285 [000] 22301.830344: lock_kernel: depth=0 file:line=block/ioctl.c:171 func=__blkdev_driver_ioctl()
hald-addon-stor-4285 [000] 22301.850322: unlock_kernel: depth=-1 file:line=block/ioctl.c:173 func=__blkdev_driver_ioctl()
hald-addon-stor-4285 [000] 22301.850336: lock_kernel: depth=0 file:line=fs/block_dev.c:1358 func=__blkdev_put()
hald-addon-stor-4285 [000] 22301.853056: unlock_kernel: depth=-1 file:line=fs/block_dev.c:1383 func=__blkdev_put()
hald-addon-stor-4285 [000] 22303.813335: lock_kernel: depth=0 file:line=fs/block_dev.c:1192 func=__blkdev_get()
hald-addon-stor-4285 [001] 22303.830509: unlock_kernel: depth=-1 file:line=fs/block_dev.c:1278 func=__blkdev_get()
hald-addon-stor-4285 [001] 22303.830524: lock_kernel: depth=0 file:line=block/ioctl.c:171 func=__blkdev_driver_ioctl()
hald-addon-stor-4285 [001] 22303.850524: unlock_kernel: depth=-1 file:line=block/ioctl.c:173 func=__blkdev_driver_ioctl()
hald-addon-stor-4285 [001] 22303.850536: lock_kernel: depth=0 file:line=fs/block_dev.c:1358 func=__blkdev_put()
hald-addon-stor-4285 [001] 22303.853252: unlock_kernel: depth=-1 file:line=fs/block_dev.c:1383 func=__blkdev_put()
hald-addon-stor-4285 [000] 22305.812998: lock_kernel: depth=0 file:line=fs/block_dev.c:1192 func=__blkdev_get()
hald-addon-stor-4285 [001] 22305.830173: unlock_kernel: depth=-1 file:line=fs/block_dev.c:1278 func=__blkdev_get()
hald-addon-stor-4285 [001] 22305.830187: lock_kernel: depth=0 file:line=block/ioctl.c:171 func=__blkdev_driver_ioctl()
hald-addon-stor-4285 [001] 22305.850228: unlock_kernel: depth=-1 file:line=block/ioctl.c:173 func=__blkdev_driver_ioctl()
hald-addon-stor-4285 [001] 22305.850240: lock_kernel: depth=0 file:line=fs/block_dev.c:1358 func=__blkdev_put()
hald-addon-stor-4285 [001] 22305.852977: unlock_kernel: depth=-1 file:line=fs/block_dev.c:1383 func=__blkdev_put()
hald-addon-stor-4285 [001] 22307.813260: lock_kernel: depth=0 file:line=fs/block_dev.c:1192 func=__blkdev_get()
hald-addon-stor-4285 [001] 22307.830358: unlock_kernel: depth=-1 file:line=fs/block_dev.c:1278 func=__blkdev_get()
hald-addon-stor-4285 [001] 22307.830370: lock_kernel: depth=0 file:line=block/ioctl.c:171 func=__blkdev_driver_ioctl()
hald-addon-stor-4285 [001] 22307.850336: unlock_kernel: depth=-1 file:line=block/ioctl.c:173 func=__blkdev_driver_ioctl()
hald-addon-stor-4285 [001] 22307.850348: lock_kernel: depth=0 file:line=fs/block_dev.c:1358 func=__blkdev_put()
hald-addon-stor-4285 [001] 22307.853092: unlock_kernel: depth=-1 file:line=fs/block_dev.c:1383 func=__blkdev_put()
hald-addon-stor-4285 [000] 22309.812671: lock_kernel: depth=0 file:line=fs/block_dev.c:1192 func=__blkdev_get()
hald-addon-stor-4285 [001] 22309.829824: unlock_kernel: depth=-1 file:line=fs/block_dev.c:1278 func=__blkdev_get()
hald-addon-stor-4285 [001] 22309.829838: lock_kernel: depth=0 file:line=block/ioctl.c:171 func=__blkdev_driver_ioctl()
hald-addon-stor-4285 [001] 22309.849862: unlock_kernel: depth=-1 file:line=block/ioctl.c:173 func=__blkdev_driver_ioctl()
hald-addon-stor-4285 [001] 22309.849876: lock_kernel: depth=0 file:line=fs/block_dev.c:1358 func=__blkdev_put()
hald-addon-stor-4285 [001] 22309.852593: unlock_kernel: depth=-1 file:line=fs/block_dev.c:1383 func=__blkdev_put()
hald-addon-stor-4285 [001] 22311.813880: lock_kernel: depth=0 file:line=fs/block_dev.c:1192 func=__blkdev_get()
hald-addon-stor-4285 [001] 22311.830955: unlock_kernel: depth=-1 file:line=fs/block_dev.c:1278 func=__blkdev_get()
hald-addon-stor-4285 [001] 22311.830969: lock_kernel: depth=0 file:line=block/ioctl.c:171 func=__blkdev_driver_ioctl()
hald-addon-stor-4285 [000] 22311.850934: unlock_kernel: depth=-1 file:line=block/ioctl.c:173 func=__blkdev_driver_ioctl()
hald-addon-stor-4285 [000] 22311.850947: lock_kernel: depth=0 file:line=fs/block_dev.c:1358 func=__blkdev_put()
hald-addon-stor-4285 [000] 22311.853683: unlock_kernel: depth=-1 file:line=fs/block_dev.c:1383 func=__blkdev_put()
hald-addon-stor-4285 [000] 22313.813953: lock_kernel: depth=0 file:line=fs/block_dev.c:1192 func=__blkdev_get()
hald-addon-stor-4285 [000] 22313.831033: unlock_kernel: depth=-1 file:line=fs/block_dev.c:1278 func=__blkdev_get()
hald-addon-stor-4285 [000] 22313.831044: lock_kernel: depth=0 file:line=block/ioctl.c:171 func=__blkdev_driver_ioctl()
hald-addon-stor-4285 [000] 22313.850994: unlock_kernel: depth=-1 file:line=block/ioctl.c:173 func=__blkdev_driver_ioctl()
hald-addon-stor-4285 [000] 22313.851008: lock_kernel: depth=0 file:line=fs/block_dev.c:1358 func=__blkdev_put()
hald-addon-stor-4285 [000] 22313.853724: unlock_kernel: depth=-1 file:line=fs/block_dev.c:1383 func=__blkdev_put()
hald-addon-stor-4285 [000] 22315.814036: lock_kernel: depth=0 file:line=fs/block_dev.c:1192 func=__blkdev_get()
hald-addon-stor-4285 [000] 22315.831141: unlock_kernel: depth=-1 file:line=fs/block_dev.c:1278 func=__blkdev_get()
hald-addon-stor-4285 [000] 22315.831152: lock_kernel: depth=0 file:line=block/ioctl.c:171 func=__blkdev_driver_ioctl()
hald-addon-stor-4285 [000] 22315.851149: unlock_kernel: depth=-1 file:line=block/ioctl.c:173 func=__blkdev_driver_ioctl()
hald-addon-stor-4285 [000] 22315.851164: lock_kernel: depth=0 file:line=fs/block_dev.c:1358 func=__blkdev_put()
hald-addon-stor-4285 [000] 22315.853885: unlock_kernel: depth=-1 file:line=fs/block_dev.c:1383 func=__blkdev_put()
hald-addon-stor-4285 [000] 22317.814201: lock_kernel: depth=0 file:line=fs/block_dev.c:1192 func=__blkdev_get()
hald-addon-stor-4285 [000] 22317.831298: unlock_kernel: depth=-1 file:line=fs/block_dev.c:1278 func=__blkdev_get()
hald-addon-stor-4285 [000] 22317.831311: lock_kernel: depth=0 file:line=block/ioctl.c:171 func=__blkdev_driver_ioctl()
hald-addon-stor-4285 [000] 22317.851279: unlock_kernel: depth=-1 file:line=block/ioctl.c:173 func=__blkdev_driver_ioctl()
hald-addon-stor-4285 [000] 22317.851293: lock_kernel: depth=0 file:line=fs/block_dev.c:1358 func=__blkdev_put()
hald-addon-stor-4285 [000] 22317.854013: unlock_kernel: depth=-1 file:line=fs/block_dev.c:1383 func=__blkdev_put()
hald-addon-stor-4285 [000] 22319.814300: lock_kernel: depth=0 file:line=fs/block_dev.c:1192 func=__blkdev_get()
hald-addon-stor-4285 [000] 22319.831452: unlock_kernel: depth=-1 file:line=fs/block_dev.c:1278 func=__blkdev_get()
hald-addon-stor-4285 [000] 22319.831464: lock_kernel: depth=0 file:line=block/ioctl.c:171 func=__blkdev_driver_ioctl()
hald-addon-stor-4285 [000] 22319.851428: unlock_kernel: depth=-1 file:line=block/ioctl.c:173 func=__blkdev_driver_ioctl()
hald-addon-stor-4285 [000] 22319.851442: lock_kernel: depth=0 file:line=fs/block_dev.c:1358 func=__blkdev_put()
hald-addon-stor-4285 [000] 22319.854164: unlock_kernel: depth=-1 file:line=fs/block_dev.c:1383 func=__blkdev_put()
hald-addon-stor-4285 [000] 22321.814478: lock_kernel: depth=0 file:line=fs/block_dev.c:1192 func=__blkdev_get()
hald-addon-stor-4285 [000] 22321.831562: unlock_kernel: depth=-1 file:line=fs/block_dev.c:1278 func=__blkdev_get()
hald-addon-stor-4285 [000] 22321.831574: lock_kernel: depth=0 file:line=block/ioctl.c:171 func=__blkdev_driver_ioctl()
hald-addon-stor-4285 [000] 22321.851544: unlock_kernel: depth=-1 file:line=block/ioctl.c:173 func=__blkdev_driver_ioctl()
hald-addon-stor-4285 [000] 22321.851558: lock_kernel: depth=0 file:line=fs/block_dev.c:1358 func=__blkdev_put()
hald-addon-stor-4285 [000] 22321.854283: unlock_kernel: depth=-1 file:line=fs/block_dev.c:1383 func=__blkdev_put()
hald-addon-stor-4285 [000] 22323.814548: lock_kernel: depth=0 file:line=fs/block_dev.c:1192 func=__blkdev_get()
hald-addon-stor-4285 [000] 22323.831653: unlock_kernel: depth=-1 file:line=fs/block_dev.c:1278 func=__blkdev_get()
hald-addon-stor-4285 [000] 22323.831664: lock_kernel: depth=0 file:line=block/ioctl.c:171 func=__blkdev_driver_ioctl()
hald-addon-stor-4285 [000] 22323.851570: unlock_kernel: depth=-1 file:line=block/ioctl.c:173 func=__blkdev_driver_ioctl()
hald-addon-stor-4285 [000] 22323.851619: lock_kernel: depth=0 file:line=fs/block_dev.c:1358 func=__blkdev_put()
hald-addon-stor-4285 [000] 22323.854349: unlock_kernel: depth=-1 file:line=fs/block_dev.c:1383 func=__blkdev_put()
hald-addon-stor-4285 [000] 22325.814617: lock_kernel: depth=0 file:line=fs/block_dev.c:1192 func=__blkdev_get()
hald-addon-stor-4285 [000] 22325.831827: unlock_kernel: depth=-1 file:line=fs/block_dev.c:1278 func=__blkdev_get()
hald-addon-stor-4285 [000] 22325.831840: lock_kernel: depth=0 file:line=block/ioctl.c:171 func=__blkdev_driver_ioctl()
hald-addon-stor-4285 [000] 22325.851802: unlock_kernel: depth=-1 file:line=block/ioctl.c:173 func=__blkdev_driver_ioctl()
hald-addon-stor-4285 [000] 22325.851815: lock_kernel: depth=0 file:line=fs/block_dev.c:1358 func=__blkdev_put()
hald-addon-stor-4285 [000] 22325.854538: unlock_kernel: depth=-1 file:line=fs/block_dev.c:1383 func=__blkdev_put()
hald-addon-stor-4285 [000] 22327.814807: lock_kernel: depth=0 file:line=fs/block_dev.c:1192 func=__blkdev_get()
hald-addon-stor-4285 [000] 22327.831958: unlock_kernel: depth=-1 file:line=fs/block_dev.c:1278 func=__blkdev_get()
hald-addon-stor-4285 [000] 22327.831971: lock_kernel: depth=0 file:line=block/ioctl.c:171 func=__blkdev_driver_ioctl()
hald-addon-stor-4285 [000] 22327.851955: unlock_kernel: depth=-1 file:line=block/ioctl.c:173 func=__blkdev_driver_ioctl()
hald-addon-stor-4285 [000] 22327.851966: lock_kernel: depth=0 file:line=fs/block_dev.c:1358 func=__blkdev_put()
hald-addon-stor-4285 [000] 22327.854674: unlock_kernel: depth=-1 file:line=fs/block_dev.c:1383 func=__blkdev_put()
hald-addon-stor-4285 [000] 22329.814947: lock_kernel: depth=0 file:line=fs/block_dev.c:1192 func=__blkdev_get()
hald-addon-stor-4285 [000] 22329.832137: unlock_kernel: depth=-1 file:line=fs/block_dev.c:1278 func=__blkdev_get()
hald-addon-stor-4285 [000] 22329.832148: lock_kernel: depth=0 file:line=block/ioctl.c:171 func=__blkdev_driver_ioctl()
hald-addon-stor-4285 [000] 22329.852105: unlock_kernel: depth=-1 file:line=block/ioctl.c:173 func=__blkdev_driver_ioctl()
hald-addon-stor-4285 [000] 22329.852117: lock_kernel: depth=0 file:line=fs/block_dev.c:1358 func=__blkdev_put()
hald-addon-stor-4285 [000] 22329.854842: unlock_kernel: depth=-1 file:line=fs/block_dev.c:1383 func=__blkdev_put()
hald-addon-stor-4285 [000] 22331.815111: lock_kernel: depth=0 file:line=fs/block_dev.c:1192 func=__blkdev_get()
hald-addon-stor-4285 [000] 22331.832302: unlock_kernel: depth=-1 file:line=fs/block_dev.c:1278 func=__blkdev_get()
hald-addon-stor-4285 [000] 22331.832317: lock_kernel: depth=0 file:line=block/ioctl.c:171 func=__blkdev_driver_ioctl()
hald-addon-stor-4285 [000] 22331.852379: unlock_kernel: depth=-1 file:line=block/ioctl.c:173 func=__blkdev_driver_ioctl()
hald-addon-stor-4285 [000] 22331.852396: lock_kernel: depth=0 file:line=fs/block_dev.c:1358 func=__blkdev_put()
hald-addon-stor-4285 [000] 22331.855122: unlock_kernel: depth=-1 file:line=fs/block_dev.c:1383 func=__blkdev_put()
hald-addon-stor-4285 [000] 22333.814527: lock_kernel: depth=0 file:line=fs/block_dev.c:1192 func=__blkdev_get()
hald-addon-stor-4285 [000] 22333.831013: unlock_kernel: depth=-1 file:line=fs/block_dev.c:1278 func=__blkdev_get()
hald-addon-stor-4285 [000] 22333.831025: lock_kernel: depth=0 file:line=block/ioctl.c:171 func=__blkdev_driver_ioctl()
hald-addon-stor-4285 [001] 22333.850780: unlock_kernel: depth=-1 file:line=block/ioctl.c:173 func=__blkdev_driver_ioctl()
hald-addon-stor-4285 [001] 22333.850815: lock_kernel: depth=0 file:line=fs/block_dev.c:1358 func=__blkdev_put()
hald-addon-stor-4285 [001] 22333.853545: unlock_kernel: depth=-1 file:line=fs/block_dev.c:1383 func=__blkdev_put()
hald-addon-stor-4285 [001] 22335.814932: lock_kernel: depth=0 file:line=fs/block_dev.c:1192 func=__blkdev_get()
hald-addon-stor-4285 [000] 22335.831815: unlock_kernel: depth=-1 file:line=fs/block_dev.c:1278 func=__blkdev_get()
hald-addon-stor-4285 [000] 22335.831833: lock_kernel: depth=0 file:line=block/ioctl.c:171 func=__blkdev_driver_ioctl()
hald-addon-stor-4285 [000] 22335.851497: unlock_kernel: depth=-1 file:line=block/ioctl.c:173 func=__blkdev_driver_ioctl()
hald-addon-stor-4285 [000] 22335.851506: lock_kernel: depth=0 file:line=fs/block_dev.c:1358 func=__blkdev_put()
hald-addon-stor-4285 [000] 22335.854229: unlock_kernel: depth=-1 file:line=fs/block_dev.c:1383 func=__blkdev_put()
hald-addon-stor-4285 [000] 22337.816545: lock_kernel: depth=0 file:line=fs/block_dev.c:1192 func=__blkdev_get()
hald-addon-stor-4285 [000] 22337.833716: unlock_kernel: depth=-1 file:line=fs/block_dev.c:1278 func=__blkdev_get()
hald-addon-stor-4285 [000] 22337.833727: lock_kernel: depth=0 file:line=block/ioctl.c:171 func=__blkdev_driver_ioctl()
hald-addon-stor-4285 [000] 22337.853705: unlock_kernel: depth=-1 file:line=block/ioctl.c:173 func=__blkdev_driver_ioctl()
hald-addon-stor-4285 [000] 22337.853718: lock_kernel: depth=0 file:line=fs/block_dev.c:1358 func=__blkdev_put()
hald-addon-stor-4285 [000] 22337.856494: unlock_kernel: depth=-1 file:line=fs/block_dev.c:1383 func=__blkdev_put()
hald-addon-stor-4285 [000] 22339.815783: lock_kernel: depth=0 file:line=fs/block_dev.c:1192 func=__blkdev_get()
hald-addon-stor-4285 [000] 22339.832582: unlock_kernel: depth=-1 file:line=fs/block_dev.c:1278 func=__blkdev_get()
hald-addon-stor-4285 [000] 22339.832594: lock_kernel: depth=0 file:line=block/ioctl.c:171 func=__blkdev_driver_ioctl()
hald-addon-stor-4285 [000] 22339.852607: unlock_kernel: depth=-1 file:line=block/ioctl.c:173 func=__blkdev_driver_ioctl()
hald-addon-stor-4285 [000] 22339.852619: lock_kernel: depth=0 file:line=fs/block_dev.c:1358 func=__blkdev_put()
hald-addon-stor-4285 [000] 22339.855342: unlock_kernel: depth=-1 file:line=fs/block_dev.c:1383 func=__blkdev_put()
hald-addon-stor-4285 [001] 22341.815543: lock_kernel: depth=0 file:line=fs/block_dev.c:1192 func=__blkdev_get()
hald-addon-stor-4285 [001] 22341.832662: unlock_kernel: depth=-1 file:line=fs/block_dev.c:1278 func=__blkdev_get()
hald-addon-stor-4285 [001] 22341.832674: lock_kernel: depth=0 file:line=block/ioctl.c:171 func=__blkdev_driver_ioctl()
hald-addon-stor-4285 [001] 22341.852565: unlock_kernel: depth=-1 file:line=block/ioctl.c:173 func=__blkdev_driver_ioctl()
hald-addon-stor-4285 [001] 22341.852578: lock_kernel: depth=0 file:line=fs/block_dev.c:1358 func=__blkdev_put()
hald-addon-stor-4285 [001] 22341.855297: unlock_kernel: depth=-1 file:line=fs/block_dev.c:1383 func=__blkdev_put()
hald-addon-stor-4285 [001] 22343.816613: lock_kernel: depth=0 file:line=fs/block_dev.c:1192 func=__blkdev_get()
hald-addon-stor-4285 [000] 22343.833956: unlock_kernel: depth=-1 file:line=fs/block_dev.c:1278 func=__blkdev_get()
hald-addon-stor-4285 [000] 22343.833975: lock_kernel: depth=0 file:line=block/ioctl.c:171 func=__blkdev_driver_ioctl()
hald-addon-stor-4285 [000] 22343.853966: unlock_kernel: depth=-1 file:line=block/ioctl.c:173 func=__blkdev_driver_ioctl()
hald-addon-stor-4285 [000] 22343.853981: lock_kernel: depth=0 file:line=fs/block_dev.c:1358 func=__blkdev_put()
hald-addon-stor-4285 [000] 22343.856700: unlock_kernel: depth=-1 file:line=fs/block_dev.c:1383 func=__blkdev_put()
hald-addon-stor-4285 [000] 22345.816971: lock_kernel: depth=0 file:line=fs/block_dev.c:1192 func=__blkdev_get()
hald-addon-stor-4285 [000] 22345.834130: unlock_kernel: depth=-1 file:line=fs/block_dev.c:1278 func=__blkdev_get()
hald-addon-stor-4285 [000] 22345.834143: lock_kernel: depth=0 file:line=block/ioctl.c:171 func=__blkdev_driver_ioctl()
hald-addon-stor-4285 [000] 22345.854081: unlock_kernel: depth=-1 file:line=block/ioctl.c:173 func=__blkdev_driver_ioctl()
hald-addon-stor-4285 [000] 22345.854095: lock_kernel: depth=0 file:line=fs/block_dev.c:1358 func=__blkdev_put()
hald-addon-stor-4285 [000] 22345.856815: unlock_kernel: depth=-1 file:line=fs/block_dev.c:1383 func=__blkdev_put()
hald-addon-stor-4285 [000] 22347.817085: lock_kernel: depth=0 file:line=fs/block_dev.c:1192 func=__blkdev_get()
hald-addon-stor-4285 [000] 22347.834270: unlock_kernel: depth=-1 file:line=fs/block_dev.c:1278 func=__blkdev_get()
hald-addon-stor-4285 [000] 22347.834284: lock_kernel: depth=0 file:line=block/ioctl.c:171 func=__blkdev_driver_ioctl()
hald-addon-stor-4285 [000] 22347.854281: unlock_kernel: depth=-1 file:line=block/ioctl.c:173 func=__blkdev_driver_ioctl()
hald-addon-stor-4285 [000] 22347.854295: lock_kernel: depth=0 file:line=fs/block_dev.c:1358 func=__blkdev_put()
hald-addon-stor-4285 [000] 22347.857011: unlock_kernel: depth=-1 file:line=fs/block_dev.c:1383 func=__blkdev_put()
hald-addon-stor-4285 [000] 22349.817281: lock_kernel: depth=0 file:line=fs/block_dev.c:1192 func=__blkdev_get()
hald-addon-stor-4285 [000] 22349.834499: unlock_kernel: depth=-1 file:line=fs/block_dev.c:1278 func=__blkdev_get()
hald-addon-stor-4285 [000] 22349.834512: lock_kernel: depth=0 file:line=block/ioctl.c:171 func=__blkdev_driver_ioctl()
hald-addon-stor-4285 [000] 22349.854373: unlock_kernel: depth=-1 file:line=block/ioctl.c:173 func=__blkdev_driver_ioctl()
hald-addon-stor-4285 [000] 22349.854387: lock_kernel: depth=0 file:line=fs/block_dev.c:1358 func=__blkdev_put()
hald-addon-stor-4285 [000] 22349.857103: unlock_kernel: depth=-1 file:line=fs/block_dev.c:1383 func=__blkdev_put()
hald-addon-stor-4285 [000] 22351.817387: lock_kernel: depth=0 file:line=fs/block_dev.c:1192 func=__blkdev_get()
hald-addon-stor-4285 [000] 22351.834567: unlock_kernel: depth=-1 file:line=fs/block_dev.c:1278 func=__blkdev_get()
hald-addon-stor-4285 [000] 22351.834580: lock_kernel: depth=0 file:line=block/ioctl.c:171 func=__blkdev_driver_ioctl()
hald-addon-stor-4285 [000] 22351.854612: unlock_kernel: depth=-1 file:line=block/ioctl.c:173 func=__blkdev_driver_ioctl()
hald-addon-stor-4285 [000] 22351.854627: lock_kernel: depth=0 file:line=fs/block_dev.c:1358 func=__blkdev_put()
hald-addon-stor-4285 [000] 22351.857350: unlock_kernel: depth=-1 file:line=fs/block_dev.c:1383 func=__blkdev_put()
hald-addon-stor-4285 [000] 22353.817639: lock_kernel: depth=0 file:line=fs/block_dev.c:1192 func=__blkdev_get()
hald-addon-stor-4285 [000] 22353.834644: unlock_kernel: depth=-1 file:line=fs/block_dev.c:1278 func=__blkdev_get()
hald-addon-stor-4285 [000] 22353.834658: lock_kernel: depth=0 file:line=block/ioctl.c:171 func=__blkdev_driver_ioctl()
hald-addon-stor-4285 [000] 22353.854721: unlock_kernel: depth=-1 file:line=block/ioctl.c:173 func=__blkdev_driver_ioctl()
hald-addon-stor-4285 [000] 22353.854735: lock_kernel: depth=0 file:line=fs/block_dev.c:1358 func=__blkdev_put()
hald-addon-stor-4285 [000] 22353.857476: unlock_kernel: depth=-1 file:line=fs/block_dev.c:1383 func=__blkdev_put()
hald-addon-stor-4285 [000] 22355.817753: lock_kernel: depth=0 file:line=fs/block_dev.c:1192 func=__blkdev_get()
hald-addon-stor-4285 [000] 22355.834840: unlock_kernel: depth=-1 file:line=fs/block_dev.c:1278 func=__blkdev_get()
hald-addon-stor-4285 [000] 22355.834854: lock_kernel: depth=0 file:line=block/ioctl.c:171 func=__blkdev_driver_ioctl()
hald-addon-stor-4285 [000] 22355.854832: unlock_kernel: depth=-1 file:line=block/ioctl.c:173 func=__blkdev_driver_ioctl()
hald-addon-stor-4285 [000] 22355.854852: lock_kernel: depth=0 file:line=fs/block_dev.c:1358 func=__blkdev_put()
hald-addon-stor-4285 [000] 22355.857591: unlock_kernel: depth=-1 file:line=fs/block_dev.c:1383 func=__blkdev_put()
^ permalink raw reply [flat|nested] 100+ messages in thread* Re: [GIT PATCH] TTY patches for 2.6.33-git
2009-12-13 19:16 ` Frederic Weisbecker
@ 2009-12-14 5:30 ` Arjan van de Ven
2009-12-14 10:39 ` Oliver Neukum
2009-12-16 9:15 ` Arnd Bergmann
0 siblings, 2 replies; 100+ messages in thread
From: Arjan van de Ven @ 2009-12-14 5:30 UTC (permalink / raw)
To: Frederic Weisbecker
Cc: Ingo Molnar, Linus Torvalds, Thomas Gleixner, Alan Cox,
Andrew Morton, Greg KH, Peter Zijlstra, linux-kernel
On Sun, 13 Dec 2009 20:16:08 +0100
Frederic Weisbecker <fweisbec@gmail.com> wrote:
> On Sun, Dec 13, 2009 at 09:55:34AM -0800, Arjan van de Ven wrote:
> > On Sun, 13 Dec 2009 07:58:44 +0100
> > Ingo Molnar <mingo@elte.hu> wrote:
> >
> > >
> > > * Linus Torvalds <torvalds@linux-foundation.org> wrote:
> > >
> > > > We've had quite a bit of BKL work this merge-window. Maybe we'll
> > > > even get rid of it one of these days. There are "only" about 600
> > > > instances of "lock_kernel()" in the tree right now ;)
> > >
> > > I tend to use unlock_kernel() as the metric. (as it's more
> > > precisely greppable and it is also more indicative of the
> > > underlying complexity of locking, as it gets used more in more
> > > complex scenarios)
> >
> > another metric is... how many times do we take the BKL for some
> > workload. (For example booting or compiling a kernel).
> > A counter like "BKLs-per-second" would be nice to expose
> > (and then we can track that number going up as a regression etc)
>
>
>
> We have the bkl tracepoints for that, attaching an example below,
> blkdev_get/bkldev_put is among the highest consumer for me.
we have a trace, but not a number that anyone can just pull out without
having to go through great lengths to set stuff up... (esp to capture a
boot)...
Adding a counter always to the lock_kernel function should be fine
instead...
--
Arjan van de Ven Intel Open Source Technology Centre
For development, discussion and tips for power savings,
visit http://www.lesswatts.org
^ permalink raw reply [flat|nested] 100+ messages in thread
* Re: [GIT PATCH] TTY patches for 2.6.33-git
2009-12-14 5:30 ` Arjan van de Ven
@ 2009-12-14 10:39 ` Oliver Neukum
2009-12-14 16:02 ` Arjan van de Ven
2009-12-16 9:15 ` Arnd Bergmann
1 sibling, 1 reply; 100+ messages in thread
From: Oliver Neukum @ 2009-12-14 10:39 UTC (permalink / raw)
To: Arjan van de Ven
Cc: Frederic Weisbecker, Ingo Molnar, Linus Torvalds, Thomas Gleixner,
Alan Cox, Andrew Morton, Greg KH, Peter Zijlstra, linux-kernel
Am Montag, 14. Dezember 2009 06:30:15 schrieb Arjan van de Ven:
> > We have the bkl tracepoints for that, attaching an example below,
> > blkdev_get/bkldev_put is among the highest consumer for me.
>
> we have a trace, but not a number that anyone can just pull out without
> having to go through great lengths to set stuff up... (esp to capture a
> boot)...
> Adding a counter always to the lock_kernel function should be fine
> instead...
But don't we need to know how long it is held? If you just count
you'll make code that drops it while it can look bad.
Regards
Oliver
^ permalink raw reply [flat|nested] 100+ messages in thread
* Re: [GIT PATCH] TTY patches for 2.6.33-git
2009-12-14 10:39 ` Oliver Neukum
@ 2009-12-14 16:02 ` Arjan van de Ven
0 siblings, 0 replies; 100+ messages in thread
From: Arjan van de Ven @ 2009-12-14 16:02 UTC (permalink / raw)
To: Oliver Neukum
Cc: Frederic Weisbecker, Ingo Molnar, Linus Torvalds, Thomas Gleixner,
Alan Cox, Andrew Morton, Greg KH, Peter Zijlstra, linux-kernel
On Mon, 14 Dec 2009 11:39:48 +0100
Oliver Neukum <oliver@neukum.org> wrote:
> Am Montag, 14. Dezember 2009 06:30:15 schrieb Arjan van de Ven:
> > > We have the bkl tracepoints for that, attaching an example below,
> > > blkdev_get/bkldev_put is among the highest consumer for me.
> >
> > we have a trace, but not a number that anyone can just pull out
> > without having to go through great lengths to set stuff up... (esp
> > to capture a boot)...
> > Adding a counter always to the lock_kernel function should be fine
> > instead...
>
> But don't we need to know how long it is held? If you just count
> you'll make code that drops it while it can look bad.
I think/hope we're well past that. At this point, just the act of taking
it at all is bad.
--
Arjan van de Ven Intel Open Source Technology Centre
For development, discussion and tips for power savings,
visit http://www.lesswatts.org
^ permalink raw reply [flat|nested] 100+ messages in thread
* Re: [GIT PATCH] TTY patches for 2.6.33-git
2009-12-14 5:30 ` Arjan van de Ven
2009-12-14 10:39 ` Oliver Neukum
@ 2009-12-16 9:15 ` Arnd Bergmann
1 sibling, 0 replies; 100+ messages in thread
From: Arnd Bergmann @ 2009-12-16 9:15 UTC (permalink / raw)
To: Arjan van de Ven
Cc: Frederic Weisbecker, Ingo Molnar, Linus Torvalds, Thomas Gleixner,
Alan Cox, Andrew Morton, Greg KH, Peter Zijlstra, linux-kernel
On Monday 14 December 2009 05:30:15 Arjan van de Ven wrote:
> On Sun, 13 Dec 2009 20:16:08 +0100 Frederic Weisbecker <fweisbec@gmail.com> wrote:
>
> > We have the bkl tracepoints for that, attaching an example below,
> > blkdev_get/bkldev_put is among the highest consumer for me.
>
> we have a trace, but not a number that anyone can just pull out without
> having to go through great lengths to set stuff up... (esp to capture a
> boot)...
> Adding a counter always to the lock_kernel function should be fine
> instead...
FWIW, I've hacked up some debugging logic in lib/kernel_lock.c to count
and measure the BKL. If anyone is interested in this, I can bring the
patch into a form that is usable. The output for a boot followed by
building a kernel on a four-way box with today's git looks like:
fs/ioctl.c:51 vfs_ioctl,5672809,0,9,108968293432,40528
drivers/char/vt_ioctl.c:512 vt_ioctl,15615,0,45,7967944,16400928
fs/locks.c:826 __posix_lock_file,1272,0,57,2815752,2013920
sound/core/sound.c:175 snd_open,1201,0,0,3863432,0
fs/block_dev.c:1192 __blkdev_get,479,26,14,39860472,686636416
drivers/usb/core/devio.c:656 usbdev_open,240,0,0,1640792,0
drivers/usb/core/devio.c:1868 usbdev_ioctl,240,0,0,369368,0
fs/read_write.c:110 default_llseek,185,0,5,88048,669224
drivers/char/tty_io.c:1761 tty_open,136,0,11,2878344,249472048
fs/block_dev.c:1358 __blkdev_put,117,1,1,10654208,3840
drivers/char/tty_io.c:1882 tty_open,106,0,5,44344,32056
drivers/char/tty_io.c:1603 tty_release,99,0,3,363496,8192
drivers/char/tty_io.c:1513 tty_release,99,0,3,639200,104312
kernel/ptrace.c:610 sys_ptrace,98,0,0,588432,0
block/ioctl.c:171 __blkdev_driver_ioctl,40,0,4,2960544,69288
fs/locks.c:1188 __break_lease,25,0,0,14960,0
fs/namespace.c:1650 do_new_mount,14,1,0,403088,0
fs/locks.c:733 flock_lock_file,14,0,0,33072,0
fs/locks.c:2022 locks_remove_flock,9,0,0,17160,0
drivers/char/pty.c:673 ptmx_open,8,0,0,406200,0
drivers/input/input.c:1767 input_open_file,7,0,0,83776,0
drivers/char/tty_io.c:717 disassociate_ctty,5,0,1,2376,322352
lib/kernel_lock.c:236 stat_read,3,0,0,590328,0
kernel/trace/trace.c:721 register_tracer,3,0,1,2420999112,17296
fs/locks.c:647 posix_test_lock,3,0,0,6920,0
drivers/gpu/drm/drm_fops.c:176 drm_stub_open,2,0,0,16712,0
init/main.c:849 kernel_init,1,0,0,334951112,0
init/main.c:546 start_kernel,1,0,0,873891904,0
fs/ext3/super.c:2548 ext3_remount,1,0,0,86592,0
fs/ext3/super.c:2036 ext3_fill_super,1,1,0,2656,0
drivers/gpu/drm/drm_fops.c:473 drm_release,1,0,0,6360,0
block/ioctl.c:316 blkdev_ioctl,1,0,1,848,32352
The comma-separated fields are
1. caller location
2. number of lock_kernel() calls
3. number of times it was called with BKL held already
4. number of times it blocked
5. total time it was held in get_cycles() units, not counting
time spent during release-on-sleep
6. total time that this lock_kernel() was blocked by another
thread holding the BKL.
It would be easy to add some recording of who is nesting
or blocking whom, or which ones call a function that might_sleep().
Arnd
^ permalink raw reply [flat|nested] 100+ messages in thread
* Re: [GIT PATCH] TTY patches for 2.6.33-git
2009-12-12 9:39 ` Andrew Morton
2009-12-12 10:06 ` Ingo Molnar
2009-12-12 10:10 ` Ingo Molnar
@ 2009-12-12 11:02 ` Alan Cox
2009-12-12 22:34 ` Thomas Gleixner
2 siblings, 1 reply; 100+ messages in thread
From: Alan Cox @ 2009-12-12 11:02 UTC (permalink / raw)
To: Andrew Morton
Cc: Ingo Molnar, Greg KH, Thomas Gleixner, Peter Zijlstra,
Linus Torvalds, linux-kernel
> The do_tty_hangup()->tty_fasync() path takes the locks in the
> file_list_lock()->lock_kernel() direction whereas most other code takes
> them in the other direction, which cannot be good. But I'm not sure
Thats a bug - the BKL does want to be taken first (and will
sleep/yield/drop)
> Have a trace. I'm actually wondering if perhaps there's a missing
> unlock_kernel() somewhere else, and the tty code is just the victim of
> that.
It's introduced by the BKL shuffle. Try the following
commit 1f61f07a985c7e8cfc20ad8fcced2f3d226bd0dc
Author: Alan Cox <alan@linux.intel.com>
Date: Sat Dec 12 10:32:36 2009 +0000
tty: Fix the AB-BA locking bug introduced in the BKL split
The fasync path takes the BKL (it probably doesn't need to in fact) but
this causes lock inversions and deadlocks so we can't do that. Leave the
BKL over that bit for the moment.
Identified by AKPM.
Signed-off-by: Alan Cox <alan@linux.intel.com>
diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c
index 684f0e0..f15df40 100644
--- a/drivers/char/tty_io.c
+++ b/drivers/char/tty_io.c
@@ -516,7 +516,6 @@ static void do_tty_hangup(struct work_struct *work)
/* inuse_filps is protected by the single kernel lock */
lock_kernel();
check_tty_count(tty, "do_tty_hangup");
- unlock_kernel();
file_list_lock();
/* This breaks for file handles being sent over AF_UNIX sockets ? */
@@ -531,7 +530,6 @@ static void do_tty_hangup(struct work_struct *work)
}
file_list_unlock();
- lock_kernel();
tty_ldisc_hangup(tty);
read_lock(&tasklist_lock);
^ permalink raw reply related [flat|nested] 100+ messages in thread* Re: [GIT PATCH] TTY patches for 2.6.33-git
2009-12-12 11:02 ` Alan Cox
@ 2009-12-12 22:34 ` Thomas Gleixner
0 siblings, 0 replies; 100+ messages in thread
From: Thomas Gleixner @ 2009-12-12 22:34 UTC (permalink / raw)
To: Alan Cox
Cc: Andrew Morton, Ingo Molnar, Greg KH, Peter Zijlstra,
Linus Torvalds, linux-kernel
On Sat, 12 Dec 2009, Alan Cox wrote:
> > The do_tty_hangup()->tty_fasync() path takes the locks in the
> > file_list_lock()->lock_kernel() direction whereas most other code takes
> > them in the other direction, which cannot be good. But I'm not sure
>
> Thats a bug - the BKL does want to be taken first (and will
> sleep/yield/drop)
>
> > Have a trace. I'm actually wondering if perhaps there's a missing
> > unlock_kernel() somewhere else, and the tty code is just the victim of
> > that.
>
> It's introduced by the BKL shuffle. Try the following
>
>
> commit 1f61f07a985c7e8cfc20ad8fcced2f3d226bd0dc
> Author: Alan Cox <alan@linux.intel.com>
> Date: Sat Dec 12 10:32:36 2009 +0000
>
> tty: Fix the AB-BA locking bug introduced in the BKL split
>
> The fasync path takes the BKL (it probably doesn't need to in fact) but
> this causes lock inversions and deadlocks so we can't do that. Leave the
> BKL over that bit for the moment.
>
> Identified by AKPM.
>
> Signed-off-by: Alan Cox <alan@linux.intel.com>
Acked-and-Tested-by: Thomas Gleixner <tglx@linutronix.de>
> diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c
> index 684f0e0..f15df40 100644
> --- a/drivers/char/tty_io.c
> +++ b/drivers/char/tty_io.c
> @@ -516,7 +516,6 @@ static void do_tty_hangup(struct work_struct *work)
> /* inuse_filps is protected by the single kernel lock */
> lock_kernel();
> check_tty_count(tty, "do_tty_hangup");
> - unlock_kernel();
>
> file_list_lock();
> /* This breaks for file handles being sent over AF_UNIX sockets ? */
> @@ -531,7 +530,6 @@ static void do_tty_hangup(struct work_struct *work)
> }
> file_list_unlock();
>
> - lock_kernel();
> tty_ldisc_hangup(tty);
>
> read_lock(&tasklist_lock);
>
^ permalink raw reply [flat|nested] 100+ messages in thread
* Re: [GIT PATCH] TTY patches for 2.6.33-git
2009-12-12 8:46 ` [GIT PATCH] TTY patches for 2.6.33-git Ingo Molnar
2009-12-12 9:39 ` Andrew Morton
@ 2009-12-12 10:42 ` Alan Cox
2009-12-12 10:42 ` Ingo Molnar
1 sibling, 1 reply; 100+ messages in thread
From: Alan Cox @ 2009-12-12 10:42 UTC (permalink / raw)
To: Ingo Molnar
Cc: Greg KH, Thomas Gleixner, Peter Zijlstra, Linus Torvalds,
Andrew Morton, linux-kernel
On Sat, 12 Dec 2009 09:46:11 +0100
Ingo Molnar <mingo@elte.hu> wrote:
>
> * Greg KH <gregkh@suse.de> wrote:
>
> > Here's the big TTY patchset for your .33-git tree.
>
> FYI, one of the changes in this tree is causing lockups on x86.
>
> Config attached.
>
> Possible suspects would one of these:
>
> 36ba782: tty: split the lock up a bit further
> 5ec93d1: tty: Move the leader test in disassociate
> 38c70b2: tty: Push the bkl down a bit in the hangup code
> f18f949: tty: Push the lock down further into the ldisc code
> eeb89d9: tty: push the BKL down into the handlers a bit
>
> as they deal with locking details and are fresher than two weeks.
Any diagnostics with the lockup or just a system hang ?
You can pop back those five and if the lockup then vanishes those are
ones trying to work on hangup and BKL rather than security fixes so can
just get punted to next release
^ permalink raw reply [flat|nested] 100+ messages in thread
* Re: [GIT PATCH] TTY patches for 2.6.33-git
2009-12-12 10:42 ` Alan Cox
@ 2009-12-12 10:42 ` Ingo Molnar
0 siblings, 0 replies; 100+ messages in thread
From: Ingo Molnar @ 2009-12-12 10:42 UTC (permalink / raw)
To: Alan Cox
Cc: Greg KH, Thomas Gleixner, Peter Zijlstra, Linus Torvalds,
Andrew Morton, linux-kernel
* Alan Cox <alan@lxorguk.ukuu.org.uk> wrote:
> On Sat, 12 Dec 2009 09:46:11 +0100
> Ingo Molnar <mingo@elte.hu> wrote:
>
> >
> > * Greg KH <gregkh@suse.de> wrote:
> >
> > > Here's the big TTY patchset for your .33-git tree.
> >
> > FYI, one of the changes in this tree is causing lockups on x86.
> >
> > Config attached.
> >
> > Possible suspects would one of these:
> >
> > 36ba782: tty: split the lock up a bit further
> > 5ec93d1: tty: Move the leader test in disassociate
> > 38c70b2: tty: Push the bkl down a bit in the hangup code
> > f18f949: tty: Push the lock down further into the ldisc code
> > eeb89d9: tty: push the BKL down into the handlers a bit
> >
> > as they deal with locking details and are fresher than two weeks.
>
> Any diagnostics with the lockup or just a system hang ?
None that i've captured (the hang is silent) but Andrew posted some.
Ingo
^ permalink raw reply [flat|nested] 100+ messages in thread