# This is a BitKeeper generated patch for the following project:
# Project Name: Linux kernel tree
# This patch format is intended for GNU patch command version 2.5 or higher.
# This patch includes the following deltas:
#	           ChangeSet	1.630   -> 1.631  
#	drivers/usb/serial/pl2303.c	1.9     -> 1.10   
#	drivers/usb/serial/pl2303.h	1.4     -> 1.5    
#
# The following is the BitKeeper ChangeSet Log
# --------------------------------------------
# 02/08/29	greg@kroah.com	1.631
# USB: pl2303 update due to usbserial core changes.
# --------------------------------------------
#
diff -Nru a/drivers/usb/serial/pl2303.c b/drivers/usb/serial/pl2303.c
--- a/drivers/usb/serial/pl2303.c	Thu Aug 29 13:54:26 2002
+++ b/drivers/usb/serial/pl2303.c	Thu Aug 29 13:54:26 2002
@@ -1,7 +1,7 @@
 /*
  * Prolific PL2303 USB to serial adaptor driver
  *
- * Copyright (C) 2001 Greg Kroah-Hartman (greg@kroah.com)
+ * Copyright (C) 2001-2002 Greg Kroah-Hartman (greg@kroah.com)
  *
  * Original driver for 2.2.x by anonymous
  *
@@ -32,19 +32,16 @@
 
 #include <linux/config.h>
 #include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/signal.h>
 #include <linux/errno.h>
-#include <linux/poll.h>
 #include <linux/init.h>
 #include <linux/slab.h>
-#include <linux/fcntl.h>
 #include <linux/tty.h>
 #include <linux/tty_driver.h>
 #include <linux/tty_flip.h>
 #include <linux/serial.h>
 #include <linux/module.h>
 #include <linux/spinlock.h>
+#include <asm/uaccess.h>
 #include <linux/usb.h>
 
 #ifdef CONFIG_USB_SERIAL_DEBUG
@@ -71,6 +68,7 @@
 	{ USB_DEVICE(ATEN_VENDOR_ID, ATEN_PRODUCT_ID) },
 	{ USB_DEVICE(ELCOM_VENDOR_ID, ELCOM_PRODUCT_ID) },
 	{ USB_DEVICE(ITEGNO_VENDOR_ID, ITEGNO_PRODUCT_ID) },
+	{ USB_DEVICE(MA620_VENDOR_ID, MA620_PRODUCT_ID) },
 	{ }					/* Terminating entry */
 };
 
@@ -118,26 +116,24 @@
 
 /* All of the device info needed for the PL2303 SIO serial converter */
 static struct usb_serial_device_type pl2303_device = {
-	name:			"PL-2303",
-	id_table:		id_table,
-	needs_interrupt_in:	DONT_CARE,		/* this device must have an interrupt in endpoint */
-	needs_bulk_in:		MUST_HAVE,		/* this device must have a bulk in endpoint */
-	needs_bulk_out:		MUST_HAVE,		/* this device must have a bulk out endpoint */
-	num_interrupt_in:	NUM_DONT_CARE,
-	num_bulk_in:		1,
-	num_bulk_out:		1,
-	num_ports:		1,
-	open:			pl2303_open,
-	close:			pl2303_close,
-	write:			pl2303_write,
-	ioctl:			pl2303_ioctl,
-	break_ctl:		pl2303_break_ctl,
-	set_termios:		pl2303_set_termios,
-	read_bulk_callback:	pl2303_read_bulk_callback,
-	read_int_callback:	pl2303_read_int_callback,
-	write_bulk_callback:	pl2303_write_bulk_callback,
-	startup:		pl2303_startup,
-	shutdown:		pl2303_shutdown,
+	.owner =		THIS_MODULE,
+	.name =			"PL-2303",
+	.id_table =		id_table,
+	.num_interrupt_in =	NUM_DONT_CARE,
+	.num_bulk_in =		1,
+	.num_bulk_out =		1,
+	.num_ports =		1,
+	.open =			pl2303_open,
+	.close =		pl2303_close,
+	.write =		pl2303_write,
+	.ioctl =		pl2303_ioctl,
+	.break_ctl =		pl2303_break_ctl,
+	.set_termios =		pl2303_set_termios,
+	.read_bulk_callback =	pl2303_read_bulk_callback,
+	.read_int_callback =	pl2303_read_int_callback,
+	.write_bulk_callback =	pl2303_write_bulk_callback,
+	.startup =		pl2303_startup,
+	.shutdown =		pl2303_shutdown,
 };
 
 struct pl2303_private { 
@@ -178,11 +174,6 @@
 
 	dbg("%s - port %d, %d bytes", __FUNCTION__, port->number, count);
 
-	if (!port->tty) {
-		err("%s - no tty???", __FUNCTION__);
-		return 0;
-	}
-
 	if (port->write_urb->status == -EINPROGRESS) {
 		dbg("%s - already writing", __FUNCTION__);
 		return 0;
@@ -228,7 +219,7 @@
 		return;
 	}
 
-	if (!(((struct pl2303_private *)port->private)->termios_initialized)) {
+	if (!(((struct pl2303_private *) port->private)->termios_initialized)) {
 		*(port->tty->termios) = tty_std_termios;
 		port->tty->termios->c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL;
 		((struct pl2303_private *) port->private)->termios_initialized = 1;
@@ -378,62 +369,52 @@
 		
 	dbg("%s -  port %d", __FUNCTION__, port->number);
 
-	down (&port->sem);
-
-	++port->open_count;
-	MOD_INC_USE_COUNT;
-
-	if (!port->active) {
-		port->active = 1;
+#define FISH(a,b,c,d)								\
+	result=usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev,0),	\
+			       b, a, c, d, buf, 1, 100);			\
+	dbg("0x%x:0x%x:0x%x:0x%x  %d - %x",a,b,c,d,result,buf[0]);
+
+#define SOUP(a,b,c,d)								\
+	result=usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev,0),	\
+			       b, a, c, d, NULL, 0, 100);			\
+	dbg("0x%x:0x%x:0x%x:0x%x  %d",a,b,c,d,result);
+
+	FISH (VENDOR_READ_REQUEST_TYPE, VENDOR_READ_REQUEST, 0x8484, 0);
+	SOUP (VENDOR_WRITE_REQUEST_TYPE, VENDOR_WRITE_REQUEST, 0x0404, 0);
+	FISH (VENDOR_READ_REQUEST_TYPE, VENDOR_READ_REQUEST, 0x8484, 0);
+	FISH (VENDOR_READ_REQUEST_TYPE, VENDOR_READ_REQUEST, 0x8383, 0);
+	FISH (VENDOR_READ_REQUEST_TYPE, VENDOR_READ_REQUEST, 0x8484, 0);
+	SOUP (VENDOR_WRITE_REQUEST_TYPE, VENDOR_WRITE_REQUEST, 0x0404, 1);
+	FISH (VENDOR_READ_REQUEST_TYPE, VENDOR_READ_REQUEST, 0x8484, 0);
+	FISH (VENDOR_READ_REQUEST_TYPE, VENDOR_READ_REQUEST, 0x8383, 0);
+	SOUP (VENDOR_WRITE_REQUEST_TYPE, VENDOR_WRITE_REQUEST, 0, 1);
+	SOUP (VENDOR_WRITE_REQUEST_TYPE, VENDOR_WRITE_REQUEST, 1, 0xc0);
+	SOUP (VENDOR_WRITE_REQUEST_TYPE, VENDOR_WRITE_REQUEST, 2, 4);
 
-#define FISH(a,b,c,d)									\
-		result=usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev,0),	\
-				       b, a, c, d, buf, 1, 100);			\
-		dbg("0x%x:0x%x:0x%x:0x%x  %d - %x",a,b,c,d,result,buf[0]);
-
-#define SOUP(a,b,c,d)									\
-		result=usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev,0),	\
-				       b, a, c, d, NULL, 0, 100);			\
-		dbg("0x%x:0x%x:0x%x:0x%x  %d",a,b,c,d,result);
-
-		FISH (VENDOR_READ_REQUEST_TYPE, VENDOR_READ_REQUEST, 0x8484, 0);
-		SOUP (VENDOR_WRITE_REQUEST_TYPE, VENDOR_WRITE_REQUEST, 0x0404, 0);
-		FISH (VENDOR_READ_REQUEST_TYPE, VENDOR_READ_REQUEST, 0x8484, 0);
-		FISH (VENDOR_READ_REQUEST_TYPE, VENDOR_READ_REQUEST, 0x8383, 0);
-		FISH (VENDOR_READ_REQUEST_TYPE, VENDOR_READ_REQUEST, 0x8484, 0);
-		SOUP (VENDOR_WRITE_REQUEST_TYPE, VENDOR_WRITE_REQUEST, 0x0404, 1);
-		FISH (VENDOR_READ_REQUEST_TYPE, VENDOR_READ_REQUEST, 0x8484, 0);
-		FISH (VENDOR_READ_REQUEST_TYPE, VENDOR_READ_REQUEST, 0x8383, 0);
-		SOUP (VENDOR_WRITE_REQUEST_TYPE, VENDOR_WRITE_REQUEST, 0, 1);
-		SOUP (VENDOR_WRITE_REQUEST_TYPE, VENDOR_WRITE_REQUEST, 1, 0xc0);
-		SOUP (VENDOR_WRITE_REQUEST_TYPE, VENDOR_WRITE_REQUEST, 2, 4);
-
-		/* Setup termios */
+	/* Setup termios */
+	if (port->tty) {
 		pl2303_set_termios (port, &tmp_termios);
+	}
 
-		//FIXME: need to assert RTS and DTR if CRTSCTS off
+	//FIXME: need to assert RTS and DTR if CRTSCTS off
 
-		dbg("%s - submitting read urb", __FUNCTION__);
-		port->read_urb->dev = serial->dev;
-		result = usb_submit_urb (port->read_urb);
-		if (result) {
-			err("%s - failed submitting read urb, error %d", __FUNCTION__, result);
-			up (&port->sem);
-			pl2303_close (port, NULL);
-			return -EPROTO;
-		}
-
-		dbg("%s - submitting interrupt urb", __FUNCTION__);
-		port->interrupt_in_urb->dev = serial->dev;
-		result = usb_submit_urb (port->interrupt_in_urb);
-		if (result) {
-			err("%s - failed submitting interrupt urb, error %d", __FUNCTION__, result);
-			up (&port->sem);
-			pl2303_close (port, NULL);
-			return -EPROTO;
-		}
+	dbg("%s - submitting read urb", __FUNCTION__);
+	port->read_urb->dev = serial->dev;
+	result = usb_submit_urb (port->read_urb);
+	if (result) {
+		err("%s - failed submitting read urb, error %d", __FUNCTION__, result);
+		pl2303_close (port, NULL);
+		return -EPROTO;
+	}
+
+	dbg("%s - submitting interrupt urb", __FUNCTION__);
+	port->interrupt_in_urb->dev = serial->dev;
+	result = usb_submit_urb (port->interrupt_in_urb);
+	if (result) {
+		err("%s - failed submitting interrupt urb, error %d", __FUNCTION__, result);
+		pl2303_close (port, NULL);
+		return -EPROTO;
 	}
-	up (&port->sem);
 	return 0;
 }
 
@@ -453,11 +434,8 @@
 	
 	dbg("%s - port %d", __FUNCTION__, port->number);
 
-	down (&port->sem);
-
-	--port->open_count;
-	if (port->open_count <= 0) {
-		if (serial->dev) {
+	if (serial->dev) {
+		if (port->tty) {
 			c_cflag = port->tty->termios->c_cflag;
 			if (c_cflag & HUPCL) {
 				/* drop DTR and RTS */
@@ -466,34 +444,28 @@
 				set_control_lines (port->serial->dev,
 						   priv->line_control);
 			}
-
-			/* shutdown our urbs */
-			dbg("%s - shutting down urbs", __FUNCTION__);
-			result = usb_unlink_urb (port->write_urb);
-			if (result)
-				dbg("%s - usb_unlink_urb (write_urb)"
-				    " failed with reason: %d", __FUNCTION__,
-				     result);
-
-			result = usb_unlink_urb (port->read_urb);
-			if (result)
-				dbg("%s - usb_unlink_urb (read_urb) "
-				    "failed with reason: %d", __FUNCTION__,
-				     result);
-
-			result = usb_unlink_urb (port->interrupt_in_urb);
-			if (result)
-				dbg("%s - usb_unlink_urb (interrupt_in_urb)"
-				    " failed with reason: %d", __FUNCTION__,
-				     result);
 		}
 
-		port->active = 0;
-		port->open_count = 0;
+		/* shutdown our urbs */
+		dbg("%s - shutting down urbs", __FUNCTION__);
+		result = usb_unlink_urb (port->write_urb);
+		if (result)
+			dbg("%s - usb_unlink_urb (write_urb)"
+			    " failed with reason: %d", __FUNCTION__,
+			     result);
+
+		result = usb_unlink_urb (port->read_urb);
+		if (result)
+			dbg("%s - usb_unlink_urb (read_urb) "
+			    "failed with reason: %d", __FUNCTION__,
+			     result);
+
+		result = usb_unlink_urb (port->interrupt_in_urb);
+		if (result)
+			dbg("%s - usb_unlink_urb (interrupt_in_urb)"
+			    " failed with reason: %d", __FUNCTION__,
+			     result);
 	}
-
-	up (&port->sem);
-	MOD_DEC_USE_COUNT;
 }
 
 static int set_modem_info (struct usb_serial_port *port, unsigned int cmd, unsigned int *value)
@@ -600,12 +572,8 @@
 
 	dbg("%s", __FUNCTION__);
 
-	/* stop everything on all ports */
 	for (i = 0; i < serial->num_ports; ++i)
-		while (serial->port[i].open_count > 0) {
-			pl2303_close (&serial->port[i], NULL);
-			kfree (serial->port[i].private);
-		}
+		kfree (serial->port[i].private);
 }
 
 
@@ -657,7 +625,7 @@
 
 	if (urb->status) {
 		dbg("%s - urb->status = %d", __FUNCTION__, urb->status);
-		if (!port->active) {
+		if (!port->open_count) {
 			dbg("%s - port is closed, exiting.", __FUNCTION__);
 			return;
 		}
@@ -678,7 +646,7 @@
 	usb_serial_debug_data (__FILE__, __FUNCTION__, urb->actual_length, data);
 
 	tty = port->tty;
-	if (urb->actual_length) {
+	if (tty && urb->actual_length) {
 		for (i = 0; i < urb->actual_length; ++i) {
 			if (tty->flip.count >= TTY_FLIPBUF_SIZE) {
 				tty_flip_buffer_push(tty);
@@ -689,7 +657,7 @@
 	}
 
 	/* Schedule the next read _if_ we are still open */
-	if (port->active) {
+	if (port->open_count) {
 		urb->dev = serial->dev;
 		result = usb_submit_urb(urb);
 		if (result)
diff -Nru a/drivers/usb/serial/pl2303.h b/drivers/usb/serial/pl2303.h
--- a/drivers/usb/serial/pl2303.h	Thu Aug 29 13:54:26 2002
+++ b/drivers/usb/serial/pl2303.h	Thu Aug 29 13:54:26 2002
@@ -22,3 +22,6 @@
 
 #define ITEGNO_VENDOR_ID	0x0eba
 #define ITEGNO_PRODUCT_ID	0x1080
+
+#define MA620_VENDOR_ID		0x0df7
+#define MA620_PRODUCT_ID	0x0620
