Skip to contentSkip to conversation

A different KGDB stub

PATCH In review Tom Rini 1 participant 1 message Feb 12, 2004

lore
Share & tools
lore

Tom Rini

author
#0 lore raw

PATCH 2/6 A different KGDB stub

The following is the 8250 driver for this KGDB stub.

 drivers/serial/8250.c        |   39 +++
 drivers/serial/Kconfig       |    7 
 drivers/serial/Makefile      |    2 
 drivers/serial/kgdb_8250.c   |  506 +++++++++++++++++++++++++++++++++++++++++++
 drivers/serial/serial_core.c |    4 
 5 files changed, 558 insertions(+)
drivers/serial/8250.c +39 -0
@@ -1198,12 +1198,17 @@
 	spin_unlock_irqrestore(&up->port.lock, flags);
 }
 
+static int released_irq = -1;
+
 static int serial8250_startup(struct uart_port *port)
 {
 	struct uart_8250_port *up = (struct uart_8250_port *)port;
 	unsigned long flags;
 	int retval;
 
+	if (up->port.irq == released_irq)
+		return -EBUSY;
+
 	up->capabilities = uart_config[up->port.type].flags;
 
 	if (up->port.type == PORT_16C950) {
@@ -1869,6 +1874,10 @@
 	for (i = 0; i < UART_NR; i++) {
 		struct uart_8250_port *up = &serial8250_ports[i];
 
+		if (up->port.irq == released_irq) {
+			continue;
+		}
+
 		up->port.line = i;
 		up->port.ops = &serial8250_pops;
 		init_timer(&up->timer);
@@ -2136,6 +2145,36 @@
 void serial8250_resume_port(int line)
 {
 	uart_resume_port(&serial8250_reg, &serial8250_ports[line].port);
+}
+
+/*
+ * Find all the ports using the given irq and shut them down.
+ * Result should be that the irq will be released.
+ * At most one irq can be released this way.
+ * Once an irq is released, any attempts to initialize a port with that irq
+ * will fail with EBUSY.
+ */
+
+int serial8250_release_irq(int irq)
+{
+        struct uart_8250_port *up;
+	int ttyS;
+
+	if (released_irq != -1) {
+		return 1;
+	}
+	released_irq = irq;
+	for (ttyS = 0; ttyS < UART_NR; ttyS++){
+		up =  &serial8250_ports[ttyS];
+		if (up->port.irq == irq && (irq_lists + irq)->head) {
+#ifdef CONFIG_DEBUG_SPINLOCK   /* ugly business... */
+			if(up->port.lock.magic != SPINLOCK_MAGIC)
+				spin_lock_init(&up->port.lock);
+#endif
+			serial8250_shutdown(&up->port);
+		}
+        }
+	return 0;
 }
 
 static int __init serial8250_init(void)
drivers/serial/Kconfig +7 -0
@@ -6,6 +6,13 @@
 
 menu "Serial drivers"
 
+config KGDB_8250
+	bool "KGDB: On generic serial port (8250)"
+	depends on KGDB
+	help
+	  Uses generic serial port (8250) for kgdb. This is independent of the
+	  option 9250/16550 and compatible serial port.
+
 #
 # The new 8250/16550 serial drivers
 config SERIAL_8250
drivers/serial/Makefile +2 -0
@@ -35,3 +35,5 @@
 obj-$(CONFIG_SERIAL_PMACZILOG) += pmac_zilog.o
 obj-$(CONFIG_SERIAL_AU1X00) += au1x00_uart.o
 obj-$(CONFIG_SERIAL_DZ) += dz.o
+
+obj-$(CONFIG_KGDB_8250) += kgdb_8250.o
drivers/serial/kgdb_8250.c new file +506 -0

506 lines not on this page · raw message

drivers/serial/serial_core.c +4 -0
@@ -1214,6 +1214,10 @@
 	struct uart_state *state = tty->driver_data;
 	struct uart_port *port;
 
+	if (!state)
+		return;
+	port = state->port;
+
 	BUG_ON(!kernel_locked());
 
 	if (!state || !state->port)
Signature · 2 lines
Tom Rini
http://gate.crashing.org/~trini/