patch-2.4.11-dontuse linux/drivers/usb/serial/keyspan.c

Next file: linux/drivers/usb/serial/keyspan.h
Previous file: linux/drivers/usb/serial/ir-usb.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.4.10/linux/drivers/usb/serial/keyspan.c linux/drivers/usb/serial/keyspan.c
@@ -1,16 +1,15 @@
 /*
   Keyspan USB to Serial Converter driver
  
-  (C) Copyright (C) 2000
-      Hugh Blemings <hugh@linuxcare.com>
+  (C) Copyright (C) 2000-2001
+      Hugh Blemings <hugh@misc.nu>
    
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2 of the License, or
   (at your option) any later version.
 
-  See http://www.linuxcare.com.au/hugh/keyspan.html for more
-  information on this driver.
+  See http://misc.nu/hugh/keyspan.html for more information.
   
   Code in this driver inspired by and in a number of places taken
   from Brian Warner's original Keyspan-PDA driver.
@@ -24,17 +23,26 @@
   having the patience to sit down and explain why and where he'd changed
   stuff. 
   
-  Tip 'o the hat to Linuxcare for supporting staff in their work on
-  open source projects.
+  Tip 'o the hat to IBM (and previously Linuxcare :) for supporting 
+  staff in their work on open source projects.
 
   Change History
+
+    Mon Oct  8 14:29:00 EST 2001 hugh
+      Fixed bug that prevented mulitport devices operating correctly
+      if they weren't the first unit attached.
+
+    Sat Oct  6 12:31:21 EST 2001 hugh
+      Added support for USA-28XA and -28XB, misc cleanups, break support
+      for usa26 based models thanks to David Gibson.
+
     Thu May 31 11:56:42 PDT 2001 gkh
       switched from using spinlock to a semaphore
    
-   (04/08/2001) gb
+    (04/08/2001) gb
 	Identify version on module load.
    
-   (11/01/2000) Adam J. Richter
+    (11/01/2000) Adam J. Richter
 	usb_device_id table support.
    
     Tue Oct 10 23:15:33 EST 2000 Hugh
@@ -73,18 +81,22 @@
 
 #ifdef CONFIG_USB_SERIAL_DEBUG
 	static int debug = 1;
+	#define DEBUG
 #else
 	static int debug;
+	#undef DEBUG
 #endif
 
+#include <linux/usb.h>
+
 #include "usb-serial.h"
 #include "keyspan.h"
 
 /*
  * Version Information
  */
-#define DRIVER_VERSION "v1.0.0"
-#define DRIVER_AUTHOR "Hugh Blemings <hugh@linuxcare.com>"
+#define DRIVER_VERSION "v1.1.1"
+#define DRIVER_AUTHOR "Hugh Blemings <hugh@misc.nu"
 #define DRIVER_DESC "Keyspan USB to Serial Converter Driver"
 
 #define INSTAT_BUFLEN	32
@@ -141,6 +153,7 @@
 	int		dsr_state;
 	int		dcd_state;
 	int		ri_state;
+	int		break_on;
 
 	unsigned long	tx_start_time[2];
 	int		resend_cont;	/* need to resend control packet */
@@ -161,7 +174,6 @@
   #define	dbg	printk 
 #endif
 
-static void keyspan_send_setup(struct usb_serial_port *port);
 
 /* Functions used by new usb-serial code. */
 int keyspan_init (void)
@@ -171,6 +183,8 @@
 	usb_serial_register (&keyspan_usa19w_pre_device);
 	usb_serial_register (&keyspan_usa28_pre_device);
 	usb_serial_register (&keyspan_usa28x_pre_device);
+	usb_serial_register (&keyspan_usa28xa_pre_device);
+	usb_serial_register (&keyspan_usa28xb_pre_device);
 	usb_serial_register (&keyspan_usa49w_pre_device);
 
 	usb_serial_register (&keyspan_usa18x_device);
@@ -178,6 +192,8 @@
 	usb_serial_register (&keyspan_usa19w_device);
 	usb_serial_register (&keyspan_usa28_device);
 	usb_serial_register (&keyspan_usa28x_device);
+	usb_serial_register (&keyspan_usa28xa_device);
+	/* We don't need a separate entry for the usa28xb as it appears as a 28x anyway */
 	usb_serial_register (&keyspan_usa49w_device);
 
 	info(DRIVER_VERSION ":" DRIVER_DESC);
@@ -192,6 +208,8 @@
 	usb_serial_deregister (&keyspan_usa19w_pre_device);
 	usb_serial_deregister (&keyspan_usa28_pre_device);
 	usb_serial_deregister (&keyspan_usa28x_pre_device);
+	usb_serial_deregister (&keyspan_usa28xa_pre_device);
+	usb_serial_deregister (&keyspan_usa28xb_pre_device);
 	usb_serial_deregister (&keyspan_usa49w_pre_device);
 
 	usb_serial_deregister (&keyspan_usa18x_device);
@@ -199,6 +217,8 @@
 	usb_serial_deregister (&keyspan_usa19w_device);
 	usb_serial_deregister (&keyspan_usa28_device);
 	usb_serial_deregister (&keyspan_usa28x_device);
+	usb_serial_deregister (&keyspan_usa28xa_device);
+	/* We don't need a separate entry for the usa28xb as it appears as a 28x anyway */
 	usb_serial_deregister (&keyspan_usa49w_device);
 }
 
@@ -207,19 +227,30 @@
 
 static void keyspan_rx_throttle (struct usb_serial_port *port)
 {
-	dbg("keyspan_rx_throttle port %d", port->number);
+	dbg("keyspan_rx_throttle port %d\n", port->number);
 }
 
 
 static void keyspan_rx_unthrottle (struct usb_serial_port *port)
 {
-	dbg("keyspan_rx_unthrottle port %d", port->number);
+	dbg("keyspan_rx_unthrottle port %d\n", port->number);
 }
 
 
 static void keyspan_break_ctl (struct usb_serial_port *port, int break_state)
 {
-	dbg("keyspan_break_ctl");
+	struct keyspan_port_private 	*p_priv;
+
+ 	dbg("keyspan_break_ctl\n");
+
+	p_priv = (struct keyspan_port_private *)port->private;
+
+	if (break_state == -1)
+		p_priv->break_on = 1;
+	else
+		p_priv->break_on = 0;
+
+	keyspan_send_setup(port, 0);
 }
 
 
@@ -231,7 +262,7 @@
 	const keyspan_device_details	*d_details;
 	unsigned int 			cflag;
 
-	/*  dbg(__FUNCTION__ "."); */
+	dbg(__FUNCTION__ ".\n"); 
 
 	p_priv = (struct keyspan_port_private *)(port->private);
 	d_details = p_priv->device_details;
@@ -252,7 +283,7 @@
 	p_priv->cflag = cflag;
 	p_priv->flow_control = (cflag & CRTSCTS)? flow_cts: flow_none;
 
-	keyspan_send_setup(port);
+	keyspan_send_setup(port, 0);
 }
 
 static int keyspan_ioctl(struct usb_serial_port *port, struct file *file,
@@ -281,7 +312,7 @@
 			return -EFAULT;
 		p_priv->rts_state = ((value & TIOCM_RTS) ? 1 : 0);
 		p_priv->dtr_state = ((value & TIOCM_DTR) ? 1 : 0);
-		keyspan_send_setup(port);
+		keyspan_send_setup(port, 0);
 		return 0;
 
 	case TIOCMBIS:
@@ -293,7 +324,7 @@
 			p_priv->rts_state = set;
 		if (value & TIOCM_DTR)
 			p_priv->dtr_state = set;
-		keyspan_send_setup(port);
+		keyspan_send_setup(port, 0);
 		return 0;
 	}
 
@@ -308,15 +339,15 @@
 	struct keyspan_port_private 	*p_priv;
 	const keyspan_device_details	*d_details;
 	int				flip;
-	int left, todo;
-	urb_t *this_urb;
-	int err;
+	int 				left, todo;
+	urb_t 				*this_urb;
+	int 				err;
 
 	p_priv = (struct keyspan_port_private *)(port->private);
 	d_details = p_priv->device_details;
 
 #if 0
-	dbg(__FUNCTION__ " for port %d (%d chars [%x]), flip=%d",
+	dbg(__FUNCTION__ " for port %d (%d chars [%x]), flip=%d\n",
 	    port->number, count, buf[0], p_priv->out_flip);
 #endif
 
@@ -330,10 +361,12 @@
 		/* Check we have a valid urb/endpoint before we use it... */
 		if ((this_urb = p_priv->out_urbs[flip]) == 0) {
 			/* no bulk out, so return 0 bytes written */
-			dbg(__FUNCTION__ " no output urb :(");
+			dbg(__FUNCTION__ " no output urb :(\n");
 			return count;
 		}
 
+		dbg(__FUNCTION__ " endpoint %d\n", usb_pipeendpoint(this_urb->pipe));
+
 		if (this_urb->status == -EINPROGRESS) {
 			if (this_urb->transfer_flags & USB_ASYNC_UNLINK)
 				break;
@@ -362,7 +395,7 @@
 		this_urb->transfer_flags &= ~USB_ASYNC_UNLINK;
 		this_urb->dev = port->serial->dev;
 		if ((err = usb_submit_urb(this_urb)) != 0) {
-			dbg("usb_submit_urb(write bulk) failed (%d)", err);
+			dbg("usb_submit_urb(write bulk) failed (%d)\n", err);
 		}
 		p_priv->tx_start_time[flip] = jiffies;
 
@@ -382,12 +415,12 @@
 	struct tty_struct	*tty;
 	unsigned char 		*data = urb->transfer_buffer;
 
-	/*  dbg (__FUNCTION__); */
+	dbg ("%s\n", __FUNCTION__); 
 
 	endpoint = usb_pipeendpoint(urb->pipe);
 
 	if (urb->status) {
-		dbg(__FUNCTION__ "nonzero status: %x on endpoint %d.",
+		dbg(__FUNCTION__ "nonzero status: %x on endpoint %d.\n",
 			      		urb->status, endpoint);
 		return;
 	}
@@ -420,7 +453,7 @@
 		/* Resubmit urb so we continue receiving */
 	urb->dev = port->serial->dev;
 	if ((err = usb_submit_urb(urb)) != 0) {
-		dbg(__FUNCTION__ "resubmit read urb failed. (%d)", err);
+		dbg(__FUNCTION__ "resubmit read urb failed. (%d)\n", err);
 	}
 	return;
 }
@@ -433,7 +466,7 @@
 
 	port = (struct usb_serial_port *) urb->context;
 	p_priv = (struct keyspan_port_private *)(port->private);
-	/*  dbg (__FUNCTION__ " urb %d", urb == p_priv->out_urbs[1]); */
+	dbg (__FUNCTION__ " urb %d\n", urb == p_priv->out_urbs[1]); 
 
 	if (port->active) {
 		queue_task(&port->tqueue, &tq_immediate);
@@ -443,7 +476,7 @@
 
 static void	usa26_inack_callback(struct urb *urb)
 {
-	dbg (__FUNCTION__);
+	dbg ("%s\n", __FUNCTION__); 
 	
 }
 
@@ -456,8 +489,8 @@
 	p_priv = (struct keyspan_port_private *)(port->private);
 
 	if (p_priv->resend_cont) {
-		/*  dbg (__FUNCTION__ " sending setup"); */
-		keyspan_usa26_send_setup(port->serial, port);
+		dbg (__FUNCTION__ " sending setup\n"); 
+		keyspan_usa26_send_setup(port->serial, port, 0);
 	}
 }
 
@@ -473,18 +506,18 @@
 	serial = (struct usb_serial *) urb->context;
 
 	if (urb->status) {
-		dbg(__FUNCTION__ " nonzero status: %x", urb->status);
+		dbg(__FUNCTION__ " nonzero status: %x\n", urb->status);
 		return;
 	}
 	if (urb->actual_length != 9) {
-		dbg(__FUNCTION__ " %d byte report??", urb->actual_length);
+		dbg(__FUNCTION__ " %d byte report??\n", urb->actual_length);
 		goto exit;
 	}
 
 	msg = (keyspan_usa26_portStatusMessage *)data;
 
 #if 0
-	dbg(__FUNCTION__ " port status: port %d cts %d dcd %d dsr %d ri %d toff %d txoff %d rxen %d cr %d",
+	dbg(__FUNCTION__ " port status: port %d cts %d dcd %d dsr %d ri %d toff %d txoff %d rxen %d cr %d\n",
 	    msg->port, msg->hskia_cts, msg->gpia_dcd, msg->dsr, msg->ri, msg->_txOff,
 	    msg->_txXoff, msg->rxEnabled, msg->controlResponse);
 #endif
@@ -494,7 +527,7 @@
 
 	/* Check port number from message and retrieve private data */	
 	if (msg->port >= serial->num_ports) {
-		dbg ("Unexpected port number %d", msg->port);
+		dbg ("Unexpected port number %d\n", msg->port);
 		goto exit;
 	}
 	port = &serial->port[msg->port];
@@ -519,13 +552,13 @@
 	/* Resubmit urb so we continue receiving */
 	urb->dev = serial->dev;
 	if ((err = usb_submit_urb(urb)) != 0) {
-		dbg(__FUNCTION__ "resubmit read urb failed. (%d)", err);
+		dbg(__FUNCTION__ "resubmit read urb failed. (%d)\n", err);
 	}
 }
 
 static void	usa26_glocont_callback(struct urb *urb)
 {
-	dbg (__FUNCTION__);
+	dbg ("%s\n", __FUNCTION__);
 	
 }
 
@@ -538,7 +571,7 @@
 	unsigned char           *data;
 	struct keyspan_port_private             *p_priv;
 
-	/*  dbg (__FUNCTION__); */
+	dbg ("%s\n", __FUNCTION__);
 
 	port = (struct usb_serial_port *) urb->context;
 	p_priv = (struct keyspan_port_private *)(port->private);
@@ -550,7 +583,7 @@
 	do {
 		if (urb->status) {
 			dbg(__FUNCTION__ "nonzero status: %x on endpoint
-%d.",
+%d.\n",
 			    urb->status, usb_pipeendpoint(urb->pipe));
 			return;
 		}
@@ -570,7 +603,7 @@
 		/* Resubmit urb so we continue receiving */
 		urb->dev = port->serial->dev;
 		if ((err = usb_submit_urb(urb)) != 0) {
-			dbg(__FUNCTION__ "resubmit read urb failed. (%d)",
+			dbg(__FUNCTION__ "resubmit read urb failed. (%d)\n",
 err);
 		}
 		p_priv->in_flip ^= 1;
@@ -581,7 +614,7 @@
 
 static void	usa28_inack_callback(struct urb *urb)
 {
-	dbg (__FUNCTION__);
+	dbg ("%s\n", __FUNCTION__);
 }
 
 static void	usa28_outcont_callback(struct urb *urb)
@@ -593,8 +626,8 @@
 	p_priv = (struct keyspan_port_private *)(port->private);
 
 	if (p_priv->resend_cont) {
-		dbg (__FUNCTION__ " sending setup");
-		keyspan_usa28_send_setup(port->serial, port);
+		dbg (__FUNCTION__ " sending setup\n");
+		keyspan_usa28_send_setup(port->serial, port, 0);
 	}
 }
 
@@ -611,16 +644,16 @@
 	serial = (struct usb_serial *) urb->context;
 
 	if (urb->status) {
-		dbg(__FUNCTION__ " nonzero status: %x", urb->status);
+		dbg(__FUNCTION__ " nonzero status: %x\n", urb->status);
 		return;
 	}
 
 	if (urb->actual_length != sizeof(struct keyspan_usa28_portStatusMessage)) {
-		dbg(__FUNCTION__ " bad length %d", urb->actual_length);
+		dbg(__FUNCTION__ " bad length %d\n", urb->actual_length);
 		goto exit;
 	}
 
-	/*dbg(__FUNCTION__ " %x %x %x %x %x %x %x %x %x %x %x %x",
+	/*dbg(__FUNCTION__ " %x %x %x %x %x %x %x %x %x %x %x %x\n",
 	    data[0], data[1], data[2], data[3], data[4], data[5],
 	    data[6], data[7], data[8], data[9], data[10], data[11]);*/
 	
@@ -630,7 +663,7 @@
 
 		/* Check port number from message and retrieve private data */	
 	if (msg->port >= serial->num_ports) {
-		dbg ("Unexpected port number %d", msg->port);
+		dbg ("Unexpected port number %d\n", msg->port);
 		goto exit;
 	}
 	port = &serial->port[msg->port];
@@ -655,13 +688,13 @@
 		/* Resubmit urb so we continue receiving */
 	urb->dev = serial->dev;
 	if ((err = usb_submit_urb(urb)) != 0) {
-		dbg(__FUNCTION__ "resubmit read urb failed. (%d)", err);
+		dbg(__FUNCTION__ "resubmit read urb failed. (%d)\n", err);
 	}
 }
 
 static void	usa28_glocont_callback(struct urb *urb)
 {
-	dbg (__FUNCTION__);
+	dbg ("%s\n", __FUNCTION__);
 }
 
 
@@ -672,7 +705,7 @@
 	struct keyspan_port_private *p_priv;
 	int i;
 
-	/*  dbg (__FUNCTION__); */
+	dbg ("%s\n", __FUNCTION__);
 
 	serial = (struct usb_serial *) urb->context;
 	for (i = 0; i < serial->num_ports; ++i) {
@@ -680,8 +713,8 @@
 		p_priv = (struct keyspan_port_private *)(port->private);
 
 		if (p_priv->resend_cont) {
-			/*  dbg (__FUNCTION__ " sending setup"); */
-			keyspan_usa49_send_setup(serial, port);
+			dbg (__FUNCTION__ " sending setup\n"); 
+			keyspan_usa49_send_setup(serial, port, 0);
 			break;
 		}
 	}
@@ -699,21 +732,21 @@
 	struct keyspan_port_private	 	*p_priv;
 	int old_dcd_state;
 
-	/*  dbg (__FUNCTION__); */
+	dbg ("%s\n", __FUNCTION__);
 
 	serial = (struct usb_serial *) urb->context;
 
 	if (urb->status) {
-		dbg(__FUNCTION__ " nonzero status: %x", urb->status);
+		dbg(__FUNCTION__ " nonzero status: %x\n", urb->status);
 		return;
 	}
 
 	if (urb->actual_length != sizeof(struct keyspan_usa49_portStatusMessage)) {
-		dbg(__FUNCTION__ " bad length %d", urb->actual_length);
+		dbg(__FUNCTION__ " bad length %d\n", urb->actual_length);
 		goto exit;
 	}
 
-	/*dbg(__FUNCTION__ " %x %x %x %x %x %x %x %x %x %x %x",
+	/*dbg(__FUNCTION__ " %x %x %x %x %x %x %x %x %x %x %x\n",
 	    data[0], data[1], data[2], data[3], data[4], data[5],
 	    data[6], data[7], data[8], data[9], data[10]);*/
 	
@@ -722,7 +755,7 @@
 
 		/* Check port number from message and retrieve private data */	
 	if (msg->portNumber >= serial->num_ports) {
-		dbg ("Unexpected port number %d", msg->portNumber);
+		dbg ("Unexpected port number %d\n", msg->portNumber);
 		goto exit;
 	}
 	port = &serial->port[msg->portNumber];
@@ -748,13 +781,13 @@
 	urb->dev = serial->dev;
 
 	if ((err = usb_submit_urb(urb)) != 0) {
-		dbg(__FUNCTION__ "resubmit read urb failed. (%d)", err);
+		dbg(__FUNCTION__ "resubmit read urb failed. (%d)\n", err);
 	}
 }
 
 static void	usa49_inack_callback(struct urb *urb)
 {
-	dbg (__FUNCTION__);
+	dbg ("%s\n", __FUNCTION__);
 }
 
 static void	usa49_indat_callback(struct urb *urb)
@@ -765,12 +798,12 @@
 	struct tty_struct	*tty;
 	unsigned char 		*data = urb->transfer_buffer;
 
-	/*  dbg (__FUNCTION__); */
+	dbg ("%s\n", __FUNCTION__);
 
 	endpoint = usb_pipeendpoint(urb->pipe);
 
 	if (urb->status) {
-		dbg(__FUNCTION__ "nonzero status: %x on endpoint %d.",
+		dbg(__FUNCTION__ "nonzero status: %x on endpoint %d.\n",
 			      		urb->status, endpoint);
 		return;
 	}
@@ -803,21 +836,21 @@
 		/* Resubmit urb so we continue receiving */
 	urb->dev = port->serial->dev;
 	if ((err = usb_submit_urb(urb)) != 0) {
-		dbg(__FUNCTION__ "resubmit read urb failed. (%d)", err);
+		dbg(__FUNCTION__ "resubmit read urb failed. (%d)\n", err);
 	}
 }
 
 /* not used, usa-49 doesn't have per-port control endpoints */
 static void	usa49_outcont_callback(struct urb *urb)
 {
-	dbg (__FUNCTION__);
+	dbg ("%s\n", __FUNCTION__);
 }
 
 
 
 static int keyspan_write_room (struct usb_serial_port *port)
 {
-//	dbg("keyspan_write_room called");
+	dbg("keyspan_write_room called\n");
 	return (32);
 
 }
@@ -842,7 +875,8 @@
 	p_priv = (struct keyspan_port_private *)(port->private);
 	d_details = s_priv->device_details;
 	
-	/*  dbg("keyspan_open called."); */
+	dbg("keyspan_open called for port%d.\n", port->number); 
+
 	MOD_INC_USE_COUNT;
 
 	down (&port->sem);
@@ -855,7 +889,7 @@
 		return 0;
 
 	p_priv = (struct keyspan_port_private *)(port->private);
-
+	
 	/* Set some sane defaults */
 	p_priv->rts_state = 1;
 	p_priv->dtr_state = 1;
@@ -866,7 +900,7 @@
 			continue;
 		urb->dev = serial->dev;
 		if ((err = usb_submit_urb(urb)) != 0) {
-			dbg(__FUNCTION__ " submit urb %d failed (%d)", i, err);
+			dbg(__FUNCTION__ " submit urb %d failed (%d)\n", i, err);
 		}
 	}
 
@@ -890,9 +924,21 @@
 	struct keyspan_serial_private 	*s_priv;
 	struct keyspan_port_private 	*p_priv;
 
-	/*  dbg("keyspan_close called"); */
+	dbg("keyspan_close called\n");
 	s_priv = (struct keyspan_serial_private *)(serial->private);
 	p_priv = (struct keyspan_port_private *)(port->private);
+	
+	p_priv->rts_state = 0;
+	p_priv->dtr_state = 0;
+	
+	keyspan_send_setup(port, 1);
+
+	/*while (p_priv->outcont_urb->status == -EINPROGRESS) {
+		dbg("close - urb in progress\n");
+	}*/
+
+	p_priv->out_flip = 0;
+	p_priv->in_flip = 0;
 
 	down (&port->sem);
 
@@ -928,43 +974,53 @@
 	const struct ezusb_hex_record 	*record;
 	char				*fw_name;
 
-	dbg("Keyspan startup version %04x product %04x",
+	dbg("Keyspan startup version %04x product %04x\n",
 	    serial->dev->descriptor.bcdDevice,
 	    serial->dev->descriptor.idProduct); 
 	
 	if ((serial->dev->descriptor.bcdDevice & 0x8000) != 0x8000) {
-		dbg("Firmware already loaded.  Quitting.");
+		dbg("Firmware already loaded.  Quitting.\n");
 		return(1);
 	}
 
 		/* Select firmware image on the basis of idProduct */
 	switch (serial->dev->descriptor.idProduct) {
-	case 0x0101:
+	case keyspan_usa28_pre_product_id:
 		record = &keyspan_usa28_firmware[0];
 		fw_name = "USA28";
 		break;
 
-	case 0x0102:
+	case keyspan_usa28x_pre_product_id:
 		record = &keyspan_usa28x_firmware[0];
 		fw_name = "USA28X";
 		break;
 
-	case 0x0103:
+	case keyspan_usa28xa_pre_product_id:
+		record = &keyspan_usa28xa_firmware[0];
+		fw_name = "USA28XA";
+		break;
+
+	case keyspan_usa28xb_pre_product_id:
+		record = &keyspan_usa28xb_firmware[0];
+		fw_name = "USA28XB";
+		break;
+
+	case keyspan_usa19_pre_product_id:
 		record = &keyspan_usa19_firmware[0];
 		fw_name = "USA19";
 		break;
 			     
-	case 0x0105:
+	case keyspan_usa18x_pre_product_id:
 		record = &keyspan_usa18x_firmware[0];
 		fw_name = "USA18X";
 		break;
 			     
-	case 0x0106:
+	case keyspan_usa19w_pre_product_id:
 		record = &keyspan_usa19w_firmware[0];
 		fw_name = "USA19W";
 		break;
 		
-	case 0x0109:
+	case keyspan_usa49w_pre_product_id:
 		record = &keyspan_usa49w_firmware[0];
 		fw_name = "USA49W";
 		break;
@@ -980,7 +1036,7 @@
 		return(1);
 	}
 
-	dbg("Uploading Keyspan %s firmware.", fw_name);
+	dbg("Uploading Keyspan %s firmware.\n", fw_name);
 
 		/* download the firmware image */
 	response = ezusb_set_reset(serial, 1);
@@ -1016,10 +1072,10 @@
 	if (endpoint == -1)
 		return NULL;		/* endpoint not needed */
 
-	/*  dbg (__FUNCTION__ " alloc for endpoint %d.", endpoint); */
+	dbg (__FUNCTION__ " alloc for endpoint %d.\n", endpoint);
 	urb = usb_alloc_urb(0);		/* No ISO */
 	if (urb == NULL) {
-		dbg (__FUNCTION__ " alloc for endpoint %d failed.", endpoint);
+		dbg (__FUNCTION__ " alloc for endpoint %d failed.\n", endpoint);
 		return NULL;
 	}
 
@@ -1078,7 +1134,7 @@
 	struct callbacks		*cback;
 	int				endp;
 
-	/*  dbg (__FUNCTION__); */
+	dbg ("%s\n", __FUNCTION__);
 
 	s_priv = (struct keyspan_serial_private *)(serial->private);
 	d_details = s_priv->device_details;
@@ -1197,7 +1253,7 @@
 	u8	best_prescaler;
 	int	i;
 
-	/*  dbg (__FUNCTION__ " %d.", baud_rate); */
+	dbg (__FUNCTION__ " %d.\n", baud_rate);
 
 		/* prevent divide by zero */
 	if( (b16 = baud_rate * 16L) == 0) {
@@ -1253,7 +1309,8 @@
 }
 
 static int keyspan_usa26_send_setup(struct usb_serial *serial,
-				    struct usb_serial_port *port)
+				    struct usb_serial_port *port,
+				    int reset_port)
 {
 	struct keyspan_usa26_portControlMessage	msg;		
 	struct keyspan_serial_private 		*s_priv;
@@ -1263,7 +1320,7 @@
 	urb_t *this_urb;
 	int err;
 
-	/*  dbg (__FUNCTION__); */
+	dbg ("%s reset=%d\n", __FUNCTION__, reset_port); 
 
 	s_priv = (struct keyspan_serial_private *)(serial->private);
 	p_priv = (struct keyspan_port_private *)(port->private);
@@ -1272,9 +1329,11 @@
 	outcont_urb = d_details->outcont_endpoints[port->number];
 	this_urb = p_priv->outcont_urb;
 
+	dbg(__FUNCTION__ " endpoint %d\n", usb_pipeendpoint(this_urb->pipe));
+
 		/* Make sure we have an urb then send the message */
 	if (this_urb == NULL) {
-		dbg(__FUNCTION__ " oops no urb.");
+		dbg(__FUNCTION__ " oops no urb.\n");
 		return -1;
 	}
 
@@ -1293,7 +1352,7 @@
 		if (d_details->calculate_baud_rate
 		    (p_priv->baud, d_details->baudclk, &msg.baudHi,
 		     &msg.baudLo, &msg.prescaler) == KEYSPAN_INVALID_BAUD_RATE ) {
-			dbg(__FUNCTION__ "Invalid baud rate %d requested, using 9600.",
+			dbg(__FUNCTION__ "Invalid baud rate %d requested, using 9600.\n",
 			    p_priv->baud);
 			msg.baudLo = 0;
 			msg.baudHi = 125;	/* Values for 9600 baud */
@@ -1331,17 +1390,31 @@
 	msg.forwardingLength = 1;
 	msg.xonChar = 17;
 	msg.xoffChar = 19;
-	
-	msg._txOn = 1;
-	msg._txOff = 0;
-	msg.txFlush = 0;
-	msg.txBreak = 0;
-	msg.rxOn = 1;
-	msg.rxOff = 0;
-	msg.rxFlush = 0;
-	msg.rxForward = 0;
-	/*msg.returnStatus = 1;
-	msg.resetDataToggle = 0xff;*/
+
+	if (reset_port) {
+		msg._txOn = 0;
+		msg._txOff = 1;
+		msg.txFlush = 0;
+		msg.txBreak = 0;
+		msg.rxOn = 0;
+		msg.rxOff = 1;
+		msg.rxFlush = 1;
+		msg.rxForward = 0;
+		msg.returnStatus = 0;
+		msg.resetDataToggle = 0xff;
+	}
+	else {
+		msg._txOn = (! p_priv->break_on);
+		msg._txOff = 0;
+		msg.txFlush = 0;
+		msg.txBreak = (p_priv->break_on);
+		msg.rxOn = 1;
+		msg.rxOff = 0;
+		msg.rxFlush = 0;
+		msg.rxForward = 0;
+		msg.returnStatus = 0;
+		msg.resetDataToggle = 0x0;
+	}
 
 		/* Do handshaking outputs */	
 	msg.setTxTriState_setRts = 0xff;
@@ -1358,7 +1431,7 @@
 
 	this_urb->dev = serial->dev;
 	if ((err = usb_submit_urb(this_urb)) != 0) {
-		dbg(__FUNCTION__ " usb_submit_urb(setup) failed (%d)", err);
+		dbg(__FUNCTION__ " usb_submit_urb(setup) failed (%d)\n", err);
 	}
 #if 0
 	else {
@@ -1372,7 +1445,8 @@
 }
 
 static int keyspan_usa28_send_setup(struct usb_serial *serial,
-				    struct usb_serial_port *port)
+				    struct usb_serial_port *port,
+				    int reset_port)
 {
 	struct keyspan_usa28_portControlMessage	msg;		
 	struct keyspan_serial_private	 	*s_priv;
@@ -1387,13 +1461,13 @@
 
 	/* only do something if we have a bulk out endpoint */
 	if ((this_urb = p_priv->outcont_urb) == NULL) {
-		dbg(__FUNCTION__ " oops no urb.");
+		dbg(__FUNCTION__ " oops no urb.\n");
 		return -1;
 	}
 
 	p_priv->resend_cont = 1;
 	if (this_urb->status == -EINPROGRESS) {
-		dbg (__FUNCTION__ " already writing");
+		dbg (__FUNCTION__ " already writing\n");
 		return(-1);
 	}
 
@@ -1402,7 +1476,7 @@
 	msg.setBaudRate = 1;
 	if (keyspan_usa19_calc_baud(p_priv->baud, d_details->baudclk,
 		&msg.baudHi, &msg.baudLo, NULL) == KEYSPAN_INVALID_BAUD_RATE ) {
-		dbg(__FUNCTION__ "Invalid baud rate requested %d.", 9600);
+		dbg(__FUNCTION__ "Invalid baud rate requested %d.", p_priv->baud);
 		msg.baudLo = 0xff;
 		msg.baudHi = 0xb2;	/* Values for 9600 baud */
 	}
@@ -1443,7 +1517,7 @@
 
 	this_urb->dev = serial->dev;
 	if ((err = usb_submit_urb(this_urb)) != 0) {
-		dbg(__FUNCTION__ " usb_submit_urb(setup) failed");
+		dbg(__FUNCTION__ " usb_submit_urb(setup) failed\n");
 	}
 #if 0
 	else {
@@ -1456,17 +1530,19 @@
 }
 
 static int keyspan_usa49_send_setup(struct usb_serial *serial,
-				    struct usb_serial_port *port)
+				    struct usb_serial_port *port,
+				    int reset_port)
 {
 	struct keyspan_usa49_portControlMessage	msg;		
 	struct keyspan_serial_private 		*s_priv;
 	struct keyspan_port_private 		*p_priv;
 	const  keyspan_device_details		*d_details;
 	int 					glocont_urb;
-	urb_t *this_urb;
-	int err;
+	urb_t 					*this_urb;
+	int 					err;
+	int					device_port;
 
-	/*  dbg (__FUNCTION__); */
+	dbg ("%s\n", __FUNCTION__);
 
 	s_priv = (struct keyspan_serial_private *)(serial->private);
 	p_priv = (struct keyspan_port_private *)(port->private);
@@ -1475,11 +1551,14 @@
 	glocont_urb = d_details->glocont_endpoint;
 	this_urb = s_priv->glocont_urb;
 
-	/*  dbg(__FUNCTION__ " port %d\n", port->number); */
+		/* Work out which port within the device is being setup */
+	device_port = port->number - port->serial->minor;
+
+	dbg(__FUNCTION__ " endpoint %d port %d (%d)\n", usb_pipeendpoint(this_urb->pipe), port->number, device_port);
 
 		/* Make sure we have an urb then send the message */
 	if (this_urb == NULL) {
-		dbg(__FUNCTION__ " oops no urb for port %d.", port->number);
+		dbg(__FUNCTION__ " oops no urb for port %d.\n", port->number);
 		return -1;
 	}
 
@@ -1491,7 +1570,8 @@
 
 	memset(&msg, 0, sizeof (struct keyspan_usa49_portControlMessage));
 
-	msg.portNumber = port->number;
+	/*msg.portNumber = port->number;*/
+	msg.portNumber = device_port;
 	
 		/* Only set baud rate if it's changed */	
 	if (p_priv->old_baud != p_priv->baud) {
@@ -1500,7 +1580,7 @@
 		if (d_details->calculate_baud_rate
 		    (p_priv->baud, d_details->baudclk, &msg.baudHi,
 		     &msg.baudLo, &msg.prescaler) == KEYSPAN_INVALID_BAUD_RATE ) {
-			dbg(__FUNCTION__ "Invalid baud rate %d requested, using 9600.",
+			dbg(__FUNCTION__ "Invalid baud rate %d requested, using 9600.\n",
 			    p_priv->baud);
 			msg.baudLo = 0;
 			msg.baudHi = 125;	/* Values for 9600 baud */
@@ -1565,7 +1645,7 @@
 
 	this_urb->dev = serial->dev;
 	if ((err = usb_submit_urb(this_urb)) != 0) {
-		dbg(__FUNCTION__ " usb_submit_urb(setup) failed (%d)", err);
+		dbg(__FUNCTION__ " usb_submit_urb(setup) failed (%d)\n", err);
 	}
 #if 0
 	else {
@@ -1578,7 +1658,7 @@
 	return (0);
 }
 
-static void keyspan_send_setup(struct usb_serial_port *port)
+static void keyspan_send_setup(struct usb_serial_port *port, int reset_port)
 {
 	struct usb_serial *serial = port->serial;
 	struct keyspan_serial_private 	*s_priv;
@@ -1589,13 +1669,13 @@
 
 	switch (d_details->msg_format) {
 	case msg_usa26:
-		keyspan_usa26_send_setup(serial, port);
+		keyspan_usa26_send_setup(serial, port, reset_port);
 		break;
 	case msg_usa28:
-		keyspan_usa28_send_setup(serial, port);
+		keyspan_usa28_send_setup(serial, port, reset_port);
 		break;
 	case msg_usa49:
-		keyspan_usa49_send_setup(serial, port);
+		keyspan_usa49_send_setup(serial, port, reset_port);
 		break;
 	}
 }
@@ -1610,7 +1690,7 @@
 	struct keyspan_port_private	*p_priv;
 	const keyspan_device_details	*d_details;
 
-	/*  dbg("keyspan_startup called."); */
+	dbg("keyspan_startup called.\n");
 
 	for (i = 0; (d_details = keyspan_devices[i]) != NULL; ++i)
 		if (d_details->product_id == serial->dev->descriptor.idProduct)
@@ -1625,7 +1705,7 @@
 	serial->private = kmalloc(sizeof(struct keyspan_serial_private),
 				  GFP_KERNEL);
 	if (!serial->private) {
-		dbg(__FUNCTION__ "kmalloc for keyspan_serial_private failed.");
+		dbg(__FUNCTION__ "kmalloc for keyspan_serial_private failed.\n");
 		return (1);
 	}
 	memset(serial->private, 0, sizeof(struct keyspan_serial_private));
@@ -1639,7 +1719,7 @@
 		port->private = kmalloc(sizeof(struct keyspan_port_private),
 					GFP_KERNEL);
 		if (!port->private) {
-			dbg(__FUNCTION__ "kmalloc for keyspan_port_private (%d) failed!.", i);
+			dbg(__FUNCTION__ "kmalloc for keyspan_port_private (%d) failed!.\n", i);
 			return (1);
 		}
 		memset(port->private, 0, sizeof(struct keyspan_port_private));
@@ -1651,7 +1731,7 @@
 
 	s_priv->instat_urb->dev = serial->dev;
 	if ((err = usb_submit_urb(s_priv->instat_urb)) != 0) {
-		dbg(__FUNCTION__ " submit instat urb failed %d", err);
+		dbg(__FUNCTION__ " submit instat urb failed %d\n", err);
 	}
 			
 	return (0);
@@ -1664,7 +1744,7 @@
 	struct keyspan_serial_private 	*s_priv;
 	struct keyspan_port_private	*p_priv;
 
-	/*  dbg("keyspan_shutdown called"); */
+	dbg("keyspan_shutdown called\n");
 
 	s_priv = (struct keyspan_serial_private *)(serial->private);
 

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