[PATCH] implement TIOCGSERIAL in sn_serial.c

From: Jesse Barnes
Date: Wed May 19 2004 - 10:11:33 EST


The sn2 console driver behaves something like a serial port, but was missing
some of the ioctls that userland apps expected. This patch implements the
TIOCGSERIAL ioctl, which allows applications to identify the console as a
serial port.

Jesse
--- linux-2.6.6.orig/drivers/char/sn_serial.c 2004-05-09 22:33:21.000000000 -0400
+++ linux-2.6.6/drivers/char/sn_serial.c 2004-05-19 10:59:20.000000000 -0400
@@ -21,6 +21,7 @@
#include <linux/sysrq.h>
#include <linux/circ_buf.h>
#include <linux/serial_reg.h>
+#include <linux/serial_core.h>
#include <asm/uaccess.h>
#include <asm/sn/sgi.h>
#include <asm/sn/sn_sal.h>
@@ -38,7 +39,7 @@ static unsigned long sysrq_requested;
#define SN_SAL_MINOR 64

/* number of characters left in xmit buffer before we ask for more */
-#define WAKEUP_CHARS 128
+#define SN_WAKEUP_CHARS 128

/* number of characters we can transmit to the SAL console at a time */
#define SN_SAL_MAX_CHARS 120
@@ -411,7 +412,7 @@ sn_poll_transmit_chars(void)
* that we could stand for the upper layer to send us some
* more, ask for it. */
if (sn_sal_tty)
- if (CIRC_CNT(xmit.cb_head, xmit.cb_tail, SN_SAL_BUFFER_SIZE) < WAKEUP_CHARS)
+ if (CIRC_CNT(xmit.cb_head, xmit.cb_tail, SN_SAL_BUFFER_SIZE) < SN_WAKEUP_CHARS)
sn_sal_sched_event(SN_SAL_EVENT_WRITE_WAKEUP);
}

@@ -466,7 +467,7 @@ sn_intr_transmit_chars(void)
* that we could stand for the upper layer to send us some
* more, ask for it. */
if (sn_sal_tty)
- if (CIRC_CNT(xmit.cb_head, xmit.cb_tail, SN_SAL_BUFFER_SIZE) < WAKEUP_CHARS)
+ if (CIRC_CNT(xmit.cb_head, xmit.cb_tail, SN_SAL_BUFFER_SIZE) < SN_WAKEUP_CHARS)
sn_sal_sched_event(SN_SAL_EVENT_WRITE_WAKEUP);
}

@@ -784,6 +785,29 @@ sn_sal_read_proc(char *page, char **star
return count < begin+len-off ? count : begin+len-off;
}

+/*
+ * sn_sal_ioctl - we only support a very limited TIOCGSERIAL
+ */
+static int
+sn_sal_ioctl(struct tty_struct *tty, struct file *filp, unsigned int cmd,
+ unsigned long arg)
+{
+ struct serial_struct tmp_serial;
+ struct serial_struct *force_cast_serial;
+
+ force_cast_serial = (struct serial_struct *)arg;
+
+ memset(&tmp_serial, 0, sizeof(tmp_serial));
+ tmp_serial.irq = sn_sal_irq;
+ tmp_serial.xmit_fifo_size = SN_SAL_UART_FIFO_DEPTH;
+
+ if (cmd == TIOCGSERIAL) {
+ if (copy_to_user(force_cast_serial, &tmp_serial, sizeof(*force_cast_serial)))
+ return -EFAULT;
+ return 0;
+ }
+ return -ENOIOCTLCMD;
+}

static struct tty_operations sn_sal_driver_ops = {
.open = sn_sal_open,
@@ -796,6 +820,7 @@ static struct tty_operations sn_sal_driv
.hangup = sn_sal_hangup,
.wait_until_sent = sn_sal_wait_until_sent,
.read_proc = sn_sal_read_proc,
+ .ioctl = sn_sal_ioctl,
};
static struct tty_driver *sn_sal_driver;