[PATCH] Port change from version 0.9 to the kernel tree.

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Version of iuu_phoenix in the kernel is based on original version 0.5 from
http://eczema.ecze.com/iuu_phoenix.html which has many problems and is pretty
old.

This patch apply the changes done from 0.5 to 0.9 to the last kernel version.
The changes covered:

- basic implementation of ioctl(),
- basic implementation of iuu_set_termios(),
- support for more cards.

Signed-off-by: Olivier Bornet <Olivier.Bornet@xxxxxxx>
---
 drivers/usb/serial/iuu_phoenix.c |  115 +++++++++++++++++++++++++++++++-------
 1 files changed, 94 insertions(+), 21 deletions(-)

diff --git a/drivers/usb/serial/iuu_phoenix.c b/drivers/usb/serial/iuu_phoenix.c
index 4473d44..ab33dbf 100644
--- a/drivers/usb/serial/iuu_phoenix.c
+++ b/drivers/usb/serial/iuu_phoenix.c
@@ -40,7 +40,7 @@ static int debug;
 /*
  * Version Information
  */
-#define DRIVER_VERSION "v0.5"
+#define DRIVER_VERSION "v0.10"
 #define DRIVER_DESC "Infinity USB Unlimited Phoenix driver"
 
 static struct usb_device_id id_table[] = {
@@ -77,10 +77,13 @@ struct iuu_private {
 	u8 reset;		/* if 1 reset is needed */
 	int poll;		/* number of poll */
 	u8 *writebuf;		/* buffer for writing to device */
-	int writelen;		/* num of byte to write to device */
+	u8 writelen;		/* num of byte to write to device */
 	u8 *buf;		/* used for initialize speed */
 	u8 *dbgbuf;		/* debug buffer */
 	u8 len;
+	u8 parity;		/* 0=even 1=odd */
+	u8 setline;		/* 1=change request */
+
 };
 
 
@@ -105,6 +108,48 @@ static int iuu_alloc_buf(struct iuu_private *priv)
 	return 0;
 }
 
+static int iuu_ioctl(struct tty_struct *tty, struct file *file,
+		unsigned int cmd, unsigned long arg)
+{
+	int mask;
+	struct usb_serial_port *port = tty->driver_data;
+
+	dbg("%s (%d) cmd = 0x%04x", __FUNCTION__, port->number, cmd);
+
+	switch (cmd) {
+
+		/* could be usefull later... */
+		case TCFLSH:
+			return 0;
+
+		case TIOCGSERIAL:
+		case TCGETS:
+			dbg("%s  TIOCGSERIAL", __FUNCTION__);
+			mask = CLOCAL | CREAD | CS8 | B9600 | TIOCM_CTS | CSTOPB | PARODD;
+			put_user(mask, &arg);
+			return 0;
+		case TIOCMBIS:
+		case TIOCMBIC:
+		case TIOCSSERIAL:
+			if (get_user(mask, (unsigned long *)arg))
+				return -EFAULT;
+			dbg("%s (%d) msg = %04x", __FUNCTION__, port->number, mask);
+			return (0);
+
+		case TIOCMIWAIT:
+			dbg("%s (%d) TIOCMIWAIT", __FUNCTION__, port->number);
+			return 0;
+
+		case TCSBRK:
+			dbg("%s (%d) TIOBRK", __FUNCTION__, port->number);
+			return 0;
+		default:
+			dbg("%s not supported = 0x%04x", __FUNCTION__, cmd);
+
+	}
+	return -ENOIOCTLCMD;
+}
+
 static int iuu_startup(struct usb_serial *serial)
 {
 	struct iuu_private *priv;
@@ -651,32 +696,34 @@ static int iuu_bulk_write(struct usb_serial_port *port)
 	unsigned long flags;
 	int result;
 	int i;
+	u8 buf_len;
 	char *buf_ptr = port->write_urb->transfer_buffer;
 	dbg("%s - enter", __func__);
 
+	spin_lock_irqsave(&priv->lock, flags);
 	*buf_ptr++ = IUU_UART_ESC;
 	*buf_ptr++ = IUU_UART_TX;
 	*buf_ptr++ = priv->writelen;
 
 	memcpy(buf_ptr, priv->writebuf,
 	       priv->writelen);
+	buf_len = priv->writelen ;
+	priv->writelen = 0;
+	spin_unlock_irqrestore(&priv->lock, flags);
 	if (debug == 1) {
-		for (i = 0; i < priv->writelen; i++)
+		for (i = 0; i < buf_len; i++)
 			sprintf(priv->dbgbuf + i*2 ,
 				"%02X", priv->writebuf[i]);
-		priv->dbgbuf[priv->writelen+i*2] = 0;
+		priv->dbgbuf[buf_len+i*2] = 0;
 		dbg("%s - writing %i chars : %s", __func__,
-		    priv->writelen, priv->dbgbuf);
+		    buf_len, priv->dbgbuf);
 	}
 	usb_fill_bulk_urb(port->write_urb, port->serial->dev,
 			  usb_sndbulkpipe(port->serial->dev,
 					  port->bulk_out_endpointAddress),
-			  port->write_urb->transfer_buffer, priv->writelen + 3,
+			  port->write_urb->transfer_buffer, buf_len + 3,
 			  iuu_rxcmd, port);
 	result = usb_submit_urb(port->write_urb, GFP_ATOMIC);
-	spin_lock_irqsave(&priv->lock, flags);
-	priv->writelen = 0;
-	spin_unlock_irqrestore(&priv->lock, flags);
 	usb_serial_port_softint(port);
 	return result;
 }
@@ -770,14 +817,10 @@ static int iuu_uart_write(struct tty_struct *tty, struct usb_serial_port *port,
 		return -ENOMEM;
 
 	spin_lock_irqsave(&priv->lock, flags);
-	if (priv->writelen > 0) {
-		/* buffer already filled but not commited */
-		spin_unlock_irqrestore(&priv->lock, flags);
-		return 0;
-	}
+
 	/* fill the buffer */
-	memcpy(priv->writebuf, buf, count);
-	priv->writelen = count;
+	memcpy(priv->writebuf+priv->writelen, buf, count);
+	priv->writelen += (u8)count;
 	spin_unlock_irqrestore(&priv->lock, flags);
 
 	return count;
@@ -819,7 +862,7 @@ static int iuu_uart_on(struct usb_serial_port *port)
 	buf[0] = IUU_UART_ENABLE;
 	buf[1] = (u8) ((IUU_BAUD_9600 >> 8) & 0x00FF);
 	buf[2] = (u8) (0x00FF & IUU_BAUD_9600);
-	buf[3] = (u8) (0x0F0 & IUU_TWO_STOP_BITS) | (0x07 & IUU_PARITY_EVEN);
+	buf[3] = (u8) (0x0F0 & IUU_ONE_STOP_BIT) | (0x07 & IUU_PARITY_EVEN);
 
 	status = bulk_immediate(port, buf, 4);
 	if (status != IUU_OPERATION_OK) {
@@ -946,6 +989,30 @@ static int iuu_uart_baud(struct usb_serial_port *port, u32 baud,
 	return status;
 }
 
+static void iuu_set_termios(struct tty_struct *tty, struct usb_serial_port *port,
+		struct ktermios *old)
+{
+	unsigned int cflag = tty->termios->c_cflag;
+	int status;
+	u32 actual;
+	dbg("%s (%d) ", __FUNCTION__, port->number);
+	if (cflag & PARODD) {
+		status = iuu_uart_baud(port,
+				(clockmode==2)?16457:9600 * boost / 100,
+				&actual, IUU_PARITY_ODD | IUU_TWO_STOP_BITS);
+		dbg("%s (%d) ODD", __FUNCTION__, port->number);
+		return;
+	}
+
+	if (cflag & PARENB) {
+		status = iuu_uart_baud(port,
+				(clockmode==2)?16457:9600 * boost / 100,
+				&actual, IUU_PARITY_EVEN | IUU_ONE_STOP_BIT);
+		dbg("%s (%d) EVEN", __FUNCTION__, port->number);
+	}
+
+}
+
 static int set_control_lines(struct usb_device *dev, u8 value)
 {
 	return 0;
@@ -1044,13 +1111,16 @@ static int iuu_open(struct tty_struct *tty,
 	if (tty && !priv->termios_initialized) {
 		*(tty->termios) = tty_std_termios;
 		tty->termios->c_cflag = CLOCAL | CREAD | CS8 | B9600
-					| TIOCM_CTS | CSTOPB | PARENB;
+					| TIOCM_CTS | PARENB;
+		tty->termios->c_cflag &= ~(CSIZE|PARODD|CSTOPB);
+		tty->termios->c_lflag &= ~(ECHO|ECHONL|ICANON|ISIG|IEXTEN);
+		tty->termios->c_oflag &= ~OPOST;;
+		tty->termios->c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP
+					   |INLCR|IGNCR|ICRNL|IXON);
 		tty->termios->c_ispeed = 9600;
 		tty->termios->c_ospeed = 9600;
-		tty->termios->c_lflag = 0;
-		tty->termios->c_oflag = 0;
-		tty->termios->c_iflag = 0;
 		priv->termios_initialized = 1;
+		tty->low_latency = 1;
 		priv->poll = 0;
 	 }
 	spin_unlock_irqrestore(&priv->lock, flags);
@@ -1078,6 +1148,7 @@ static int iuu_open(struct tty_struct *tty,
 	kfree(buf);
 	iuu_led(port, 0xF000, 0xF000, 0, 0xFF);
 	iuu_uart_on(port);
+	priv->parity = IUU_PARITY_EVEN;
 	if (boost < 100)
 		boost = 100;
 	switch (clockmode) {
@@ -1175,6 +1246,8 @@ static struct usb_serial_driver iuu_device = {
 	.read_bulk_callback = iuu_uart_read_callback,
 	.tiocmget = iuu_tiocmget,
 	.tiocmset = iuu_tiocmset,
+	.ioctl = iuu_ioctl,
+	.set_termios = iuu_set_termios,
 	.attach = iuu_startup,
 	.shutdown = iuu_shutdown,
 };
-- 
1.6.2.4

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux