[parisc-linux-cvs] pdc-console fix to return sane data for ioctls

Richard Hirst rhirst@linuxcare.com
Fri, 14 Jun 2002 17:58:51 +0100


ioctls that 'get' info must write the user buffer before returning
success.  boot-floppies failed because TIOCGSERIAL effectively returned
garbage for 'line'.  It now returns something sane; could be fixed to
return actual line states, etc, sometime, if possible.

Thibaut, you don't need to worry about this, I included a temporary
workaround in the b-f patch I sent you.

Richard

Index: drivers/char/pdc_console.c
===================================================================
RCS file: /var/cvs/linux/drivers/char/pdc_console.c,v
retrieving revision 1.1
diff -u -r1.1 pdc_console.c
--- drivers/char/pdc_console.c	2001/11/29 08:30:08	1.1
+++ drivers/char/pdc_console.c	2002/06/14 17:14:49
@@ -312,6 +312,36 @@
 }
 
 static int
+get_serial_info(struct async_struct * info,
+                           struct serial_struct * retinfo)
+{
+	struct serial_struct tmp;
+
+	if (!retinfo)
+		return -EFAULT;
+	memset(&tmp, 0, sizeof(tmp));
+	tmp.line = info->line;
+	tmp.port = info->line;
+	tmp.flags = info->flags;
+	tmp.close_delay = info->close_delay;
+	return copy_to_user(retinfo,&tmp,sizeof(*retinfo)) ? -EFAULT : 0;
+}
+
+static int get_modem_info(struct async_struct * info, unsigned int *value)
+{
+	unsigned int result = TIOCM_DTR|TIOCM_CAR|TIOCM_CTS|TIOCM_RTS;
+
+	return copy_to_user(value, &result, sizeof(int)) ? -EFAULT : 0;
+}
+
+static int get_lsr_info(struct async_struct * info, unsigned int *value)
+{
+	unsigned int result = TIOCSER_TEMT;
+
+	return copy_to_user(value, &result, sizeof(int)) ? -EFAULT : 0;
+}
+
+static int
 pdc_ioctl(struct tty_struct *tty, struct file *file,
 	  unsigned int cmd, unsigned long arg)
 {
@@ -326,20 +356,20 @@
 
 	switch (cmd) {
 	case TIOCMGET:
-		return 0;
+		return get_modem_info(info, (unsigned int *) arg);
 	case TIOCMBIS:
 	case TIOCMBIC:
 	case TIOCMSET:
 		return 0;
 	case TIOCGSERIAL:
-		return 0;
+		return get_serial_info(info, (struct serial_struct *) arg);
 	case TIOCSSERIAL:
 		return 0;
 	case TIOCSERCONFIG:
 		return 0;
 
 	case TIOCSERGETLSR:	/* Get line status register */
-		return 0;
+		return get_lsr_info(info, (unsigned int *) arg);
 
 	case TIOCSERGSTRUCT:
 		if (copy_to_user((struct async_struct *) arg,