patch-2.2.15 linux/drivers/char/specialix.c

Next file: linux/drivers/char/stallion.c
Previous file: linux/drivers/char/serial167.c
Back to the patch index
Back to the overall index

diff -u --new-file --recursive --exclude-from ../../exclude v2.2.14/drivers/char/specialix.c linux/drivers/char/specialix.c
@@ -59,11 +59,14 @@
  * Revision 1.8:  Jul 1  1997
  *                port to linux-2.1.43 kernel.
  * Revision 1.9:  Oct 9  1998
- *                Added stuff for the IO8+/PCI version. . 
+ *                Added stuff for the IO8+/PCI version.
+ * Revision 1.10: Oct 22  1999 / Jan 21 2000. 
+ *                Added stuff for setserial. 
+ *                Nicolas Mailhot (Nicolas.Mailhot@email.enst.fr)
  * 
  */
 
-#define VERSION "1.8"
+#define VERSION "1.10"
 
 
 /*
@@ -1069,10 +1072,17 @@
 	/*
 	 * Now we must calculate some speed depended things 
 	 */
-	
+
 	/* Set baud rate for port */
-	tmp = (((SX_OSCFREQ + baud_table[baud]/2) / baud_table[baud] +
-		CD186x_TPC/2) / CD186x_TPC);
+	tmp = port->custom_divisor ;
+	if ( tmp )
+		printk (KERN_INFO "sx%d: Using custom baud rate divisor %ld. \n"
+			        "This is an untested option, please be carefull.\n",
+			        port_No (port), tmp);
+	else
+		tmp = (((SX_OSCFREQ + baud_table[baud]/2) / baud_table[baud] +
+		         CD186x_TPC/2) / CD186x_TPC);
+
 	if ((tmp < 0x10) && time_before(again, jiffies)) { 
 		again = jiffies + HZ * 60;
 		/* Page 48 of version 2.0 of the CL-CD1865 databook */
@@ -1094,9 +1104,13 @@
 	sx_out(bp, CD186x_TBPRH, (tmp >> 8) & 0xff); 
 	sx_out(bp, CD186x_RBPRL, tmp & 0xff); 
 	sx_out(bp, CD186x_TBPRL, tmp & 0xff);
-	
-	baud = (baud_table[baud] + 5) / 10;   /* Estimated CPS */
-	
+
+	if (port->custom_divisor) {
+		baud = (SX_OSCFREQ + port->custom_divisor/2) / port->custom_divisor;
+		baud = ( baud + 5 ) / 10;
+	} else 
+		baud = (baud_table[baud] + 5) / 10;   /* Estimated CPS */
+
 	/* Two timer ticks seems enough to wakeup something like SLIP driver */
 	tmp = ((baud + HZ/2) / HZ) * 2 - CD186x_NFIFO;		
 	port->wakeup_chars = (tmp < 0) ? 0 : ((tmp >= SERIAL_XMIT_SIZE) ?
@@ -1719,6 +1733,7 @@
 	restore_flags(flags);
 	
 	wake_up_interruptible(&tty->write_wait);
+	wake_up_interruptible(&tty->poll_wait);
 	if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
 	    tty->ldisc.write_wakeup)
 		(tty->ldisc.write_wakeup)(tty);
@@ -1859,7 +1874,8 @@
 	if (error)
 		return error;
 
-	copy_from_user(&tmp, newinfo, sizeof(tmp));
+	if (copy_from_user(&tmp, newinfo, sizeof(tmp)))
+		return -EFAULT;
 	
 #if 0	
 	if ((tmp.irq != bp->irq) ||
@@ -1874,6 +1890,7 @@
 
 	change_speed = ((port->flags & ASYNC_SPD_MASK) !=
 			(tmp.flags & ASYNC_SPD_MASK));
+	change_speed |= (tmp.custom_divisor != port->custom_divisor);
 	
 	if (!capable(CAP_SYS_ADMIN)) {
 		if ((tmp.close_delay != port->close_delay) ||
@@ -1883,11 +1900,13 @@
 			return -EPERM;
 		port->flags = ((port->flags & ~ASYNC_USR_MASK) |
 		                  (tmp.flags & ASYNC_USR_MASK));
+		port->custom_divisor = tmp.custom_divisor;
 	} else {
 		port->flags = ((port->flags & ~ASYNC_FLAGS) |
 		                  (tmp.flags & ASYNC_FLAGS));
 		port->close_delay = tmp.close_delay;
 		port->closing_wait = tmp.closing_wait;
+		port->custom_divisor = tmp.custom_divisor;
 	}
 	if (change_speed) {
 		save_flags(flags); cli();
@@ -1918,8 +1937,10 @@
 	tmp.baud_base = (SX_OSCFREQ + CD186x_TPC/2) / CD186x_TPC;
 	tmp.close_delay = port->close_delay * HZ/100;
 	tmp.closing_wait = port->closing_wait * HZ/100;
+	tmp.custom_divisor =  port->custom_divisor;
 	tmp.xmit_fifo_size = CD186x_NFIFO;
-	copy_to_user(retinfo, &tmp, sizeof(tmp));
+	if (copy_to_user(retinfo, &tmp, sizeof(tmp)))
+		return -EFAULT;
 	return 0;
 }
 
@@ -2171,6 +2192,7 @@
 		    tty->ldisc.write_wakeup)
 			(tty->ldisc.write_wakeup)(tty);
 		wake_up_interruptible(&tty->write_wait);
+		wake_up_interruptible(&tty->poll_wait);
 	}
 }
 

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)