This adds so-called "HX" with a backport from 2.6. We ship this with RHEL 3,
so I thought I would post it for great justice, in case someone needs it.
The failure symptom is that adapter gets recognized fine, receive works fine,
but transmit doesn't.

diff -urp -X dontdiff linux-2.4.31-pre1/drivers/usb/serial/pl2303.c 
linux-2.4.31-pre1-usb/drivers/usb/serial/pl2303.c
--- linux-2.4.31-pre1/drivers/usb/serial/pl2303.c       2004-08-10 
13:43:36.000000000 -0700
+++ linux-2.4.31-pre1-usb/drivers/usb/serial/pl2303.c   2005-04-28 
09:38:04.000000000 -0700
@@ -59,7 +59,7 @@
 /*
  * Version Information
  */
-#define DRIVER_VERSION "v0.10"
+#define DRIVER_VERSION "v0.10.1"       /* Takes from 2.6's */
 #define DRIVER_DESC "Prolific PL2303 USB to serial adaptor driver"
 
 
@@ -156,20 +156,38 @@ static struct usb_serial_device_type pl2
        .shutdown =             pl2303_shutdown,
 };
 
+enum pl2303_type {
+       type_0,         /* don't know the difference between type 0 and */
+       type_1,         /* type 1, until someone from prolific tells us... */
+       HX,             /* HX version of the pl2303 chip */
+};
+
 struct pl2303_private {
        spinlock_t lock;
        wait_queue_head_t delta_msr_wait;
        u8 line_control;
        u8 line_status;
        u8 termios_initialized;
+       enum pl2303_type type;
 };
 
 
 static int pl2303_startup (struct usb_serial *serial)
 {
        struct pl2303_private *priv;
+       enum pl2303_type type = type_0;
        int i;
 
+       if (serial->dev->descriptor.bDeviceClass == 0x02)
+               type = type_0;
+       else if (serial->dev->descriptor.bMaxPacketSize0 == 0x40)
+               type = HX;
+       else if (serial->dev->descriptor.bDeviceClass == 0x00)
+               type = type_1;
+       else if (serial->dev->descriptor.bDeviceClass == 0xFF)
+               type = type_1;
+       dbg("device type: %d", type);
+
        for (i = 0; i < serial->num_ports; ++i) {
                priv = kmalloc (sizeof (struct pl2303_private), GFP_KERNEL);
                if (!priv)
@@ -178,6 +196,7 @@ static int pl2303_startup (struct usb_se
                spin_lock_init(&priv->lock);
                init_waitqueue_head(&priv->delta_msr_wait);
                usb_set_serial_port_data(&serial->port[i], priv);
+               priv->type = type;
        }
        return 0;
 }
@@ -380,10 +402,17 @@ static void pl2303_set_termios (struct u
             buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], buf[6]);
 
        if (cflag & CRTSCTS) {
-               i = usb_control_msg (serial->dev, usb_sndctrlpipe (serial->dev, 
0),
-                                    VENDOR_WRITE_REQUEST, 
VENDOR_WRITE_REQUEST_TYPE,
-                                    0x0, 0x41, NULL, 0, 100);
-               dbg ("0x40:0x1:0x0:0x41  %d", i);
+               __u16 index;
+               if (priv->type == HX)
+                       index = 0x61;
+               else
+                       index = 0x41;
+               i = usb_control_msg(serial->dev, 
+                                   usb_sndctrlpipe(serial->dev, 0),
+                                   VENDOR_WRITE_REQUEST,
+                                   VENDOR_WRITE_REQUEST_TYPE,
+                                   0x0, index, NULL, 0, 100);
+               dbg ("0x40:0x1:0x0:0x%x  %d", index, i);
        }
 
        kfree (buf);
@@ -395,6 +424,7 @@ static int pl2303_open (struct usb_seria
        struct termios tmp_termios;
        struct usb_serial *serial = port->serial;
        unsigned char *buf;
+       struct pl2303_private *priv = port->private;
        int result;
 
        if (port_paranoia_check (port, __FUNCTION__))
@@ -427,6 +457,18 @@ static int pl2303_open (struct usb_seria
        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, 0);
+ 
+       if (priv->type == HX) {
+               /* HX chip */
+               SOUP (VENDOR_WRITE_REQUEST_TYPE, VENDOR_WRITE_REQUEST, 2, 0x44);
+               /* reset upstream data pipes */
+               SOUP (VENDOR_WRITE_REQUEST_TYPE, VENDOR_WRITE_REQUEST, 8, 0);
+               SOUP (VENDOR_WRITE_REQUEST_TYPE, VENDOR_WRITE_REQUEST, 9, 0);
+       } else {
+               SOUP (VENDOR_WRITE_REQUEST_TYPE, VENDOR_WRITE_REQUEST, 2, 0x24);
+       }
 
        kfree(buf);
 


-------------------------------------------------------
SF.Net email is sponsored by: Tell us your software development plans!
Take this survey and enter to win a one-year sub to SourceForge.net
Plus IDC's 2005 look-ahead and a copy of this survey
Click here to start!  http://www.idcswdc.com/cgi-bin/survey?id=105hix
_______________________________________________
linux-usb-devel@lists.sourceforge.net
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel

Reply via email to