Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 19 Jan 2005 13:11:31 +0100
From:      Michal Mertl <mime@secservers.com>
To:        Emanuel Strobl <emanuel.strobl@gmx.net>
Cc:        bernd@bwct.de
Subject:   Re: strange ucom (uplcom) error
Message-ID:  <1106136691.1132.17.camel@genius2.i.cz>
In-Reply-To: <1106134006.1132.12.camel@genius2.i.cz>
References:  <1106134006.1132.12.camel@genius2.i.cz>

next in thread | previous in thread | raw e-mail | index | archive | help

--=-LuMBlHTdF+ceeQIQ9Ebh
Content-Type: text/plain
Content-Transfer-Encoding: 7bit

Sorry to reply to myself but I would better really attach the patch.

I wrote:
> Emanuel Strobl wrote:
> > Am Dienstag, 18. Januar 2005 16:17 schrieb Andrew L. Neporada:
> > > On Tue, Jan 18, 2005 at 01:06:43PM +0100, Emanuel Strobl wrote:
> > > > Dear experts,
> > > >
> > > > I have two USB-RS232 Adaptors, both with PL2303 chipset. One is working
> > > > the other one not (I hate to say it but both are working under win).
> > > >
> > > > The not working (more expensive) one gets recognized as ucom0 and I have
> > > > ucom0, also I can receive signal but not transmit.
> > >
> > > [skip]
> > >
> > > Take a look at http://gate.intercaf.ru/~lesha/6100/ and try patch
> > > http://gate.intercaf.ru/~lesha/6100/pl2303x.patch
> > >
> > > It can break old (working) PL2303 chip, but it works for me with newer
> > 
> > Thanks a lot, this indeed fixes the revision 3.0 adaptor but unfortunately 
> > also breakes the 2.02 version :(
> > 
> > Perhaps there's a goog guy out there who can refurbish the uplcom driver with 
> > this information (akiyama?)?
> > 
> > Thanks a lot,
> 
> I've just recently been looking into this too. I used the mentioned
> patch and also linux driver source and have come with the attached
> patch. It contains one more change but I don't know if it's correct. It
> works for both chips on CURRENT for serial console. It detects if the
> chip is rev 3.00 and aplies the patch only for it.
> 
> The author of the patch mentions it isn't binary safe - sometimes the
> chip stops working. I planned to test it with binary transfers (ppp)
> today, check if it's working and submit it (with some cleanup) for
> inclusion in FreeBSD.
> 
> Michal Mertl

--=-LuMBlHTdF+ceeQIQ9Ebh
Content-Disposition: attachment; filename=uplcom.c.pl2303x.diff
Content-Type: text/x-patch; name=uplcom.c.pl2303x.diff; charset=ISO-8859-2
Content-Transfer-Encoding: 7bit

Index: uplcom.c
===================================================================
RCS file: /home/fcvs/cvs/src/sys/dev/usb/uplcom.c,v
retrieving revision 1.25
diff -u -r1.25 uplcom.c
--- uplcom.c	6 Jan 2005 01:43:29 -0000	1.25
+++ uplcom.c	15 Jan 2005 00:44:20 -0000
@@ -97,10 +97,13 @@
 #include <sys/sysctl.h>
 #include <sys/uio.h>
 
+#include <machine/bus.h>
+
 #include <dev/usb/usb.h>
 #include <dev/usb/usbcdc.h>
 
 #include <dev/usb/usbdi.h>
+#include <dev/usb/usbdivar.h>
 #include <dev/usb/usbdi_util.h>
 #include "usbdevs.h"
 #include <dev/usb/usb_quirks.h>
@@ -113,30 +116,33 @@
 SYSCTL_INT(_hw_usb_uplcom, OID_AUTO, debug, CTLFLAG_RW,
 	   &uplcomdebug, 0, "uplcom debug level");
 
-#define DPRINTFN(n, x)	do { \
+#define	DPRINTFN(n, x)	do { \
 				if (uplcomdebug > (n)) \
 					logprintf x; \
 			} while (0)
 #else
-#define DPRINTFN(n, x)
+#define	DPRINTFN(n, x)
 #endif
-#define DPRINTF(x) DPRINTFN(0, x)
+#define	DPRINTF(x) DPRINTFN(0, x)
 
-#define UPLCOM_MODVER			1	/* module version */
+#define	UPLCOM_MODVER			1	/* module version */
 
 #define	UPLCOM_CONFIG_INDEX		0
 #define	UPLCOM_IFACE_INDEX		0
 #define	UPLCOM_SECOND_IFACE_INDEX	1
 
 #ifndef UPLCOM_INTR_INTERVAL
-#define UPLCOM_INTR_INTERVAL		100	/* ms */
+#define	UPLCOM_INTR_INTERVAL		100	/* ms */
 #endif
 
 #define	UPLCOM_SET_REQUEST		0x01
 #define	UPLCOM_SET_CRTSCTS		0x41
-#define RSAQ_STATUS_CTS			0x80
-#define RSAQ_STATUS_DSR			0x02
-#define RSAQ_STATUS_DCD			0x01
+#define	RSAQ_STATUS_CTS			0x80
+#define	RSAQ_STATUS_DSR			0x02
+#define	RSAQ_STATUS_DCD			0x01
+
+#define	CHIPTYPE_PL2303			0
+#define	CHIPTYPE_PL2303X		1
 
 struct	uplcom_softc {
 	struct ucom_softc	sc_ucom;
@@ -156,14 +162,15 @@
 
 	u_char			sc_lsr;		/* Local status register */
 	u_char			sc_msr;		/* uplcom status register */
+	int		        sc_chiptype;
 };
 
 /*
  * These are the maximum number of bytes transferred per frame.
  * The output buffer size cannot be increased due to the size encoding.
  */
-#define UPLCOMIBUFSIZE 256
-#define UPLCOMOBUFSIZE 256
+#define	UPLCOMIBUFSIZE 256
+#define	UPLCOMOBUFSIZE 256
 
 Static	usbd_status uplcom_reset(struct uplcom_softc *);
 Static	usbd_status uplcom_set_line_coding(struct uplcom_softc *,
@@ -299,6 +306,7 @@
 	char *devinfo;
 	const char *devname;
 	usbd_status err;
+	usb_device_descriptor_t *udd;
 	int i;
 
 	devinfo = malloc(1024, M_USBDEV, M_WAITOK);
@@ -374,7 +382,14 @@
 			sc->sc_isize = UGETW(ed->wMaxPacketSize);
 		}
 	}
-
+	udd = &dev->ddesc;
+	if (UGETW(udd->bcdDevice) == 0x300) {
+		DPRINTF(("chiptype 2303X\n"));
+		sc->sc_chiptype = CHIPTYPE_PL2303X;
+	} else {
+		DPRINTF(("chiptype 2303\n"));
+		sc->sc_chiptype = CHIPTYPE_PL2303;
+	}
 	if (sc->sc_intr_number == -1) {
 		printf("%s: Could not find interrupt in\n",
 			USBDEVNAME(ucom->sc_dev));
@@ -617,7 +632,10 @@
 	req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
 	req.bRequest = UPLCOM_SET_REQUEST;
 	USETW(req.wValue, 0);
-	USETW(req.wIndex, UPLCOM_SET_CRTSCTS);
+	if (sc->sc_chiptype == CHIPTYPE_PL2303X)
+		USETW(req.wIndex, 0x61);
+	else
+		USETW(req.wIndex, UPLCOM_SET_CRTSCTS);
 	USETW(req.wLength, 0);
 
 	err = usbd_do_request(sc->sc_ucom.sc_udev, &req, 0);
@@ -713,6 +731,43 @@
 	return (0);
 }
 
+#define DO_REQ(type, reQ, wVal, wInd) do {				\
+	req.bmRequestType = (type);					\
+	req.bRequest = (reQ);						\
+	USETW(req.wValue, (wVal));					\
+	USETW(req.wIndex, (wInd));					\
+	USETW(req.wLength, 0);						\
+	err = usbd_do_request(sc->sc_ucom.sc_udev, &req, 0);		\
+	if (err) {							\
+		printf("%s: uplcom_initPL2303X_%d: %s\n",		\
+		USBDEVNAME(sc->sc_ucom.sc_dev), i++, usbd_errstr(err));	\
+		return (EIO);						\
+	}								\
+	} while (0);
+
+Static usbd_status
+uplcom_initPL2303X(struct uplcom_softc *sc)
+{
+	usb_device_request_t req;
+	usbd_status err;
+	int i = 0;
+	
+	DO_REQ(0xc0, 0x1, 0x8484, 0);
+	DO_REQ(0x40, 0x1, 0x0404, 0);
+	DO_REQ(0xc0, 0x1, 0x8484, 0);
+	DO_REQ(0xc0, 0x1, 0x8383, 0);
+	DO_REQ(0xc0, 0x1, 0x8484, 0);
+	DO_REQ(0x40, 0x1, 0x0404, 1);
+	DO_REQ(0xc0, 0x1, 0x8484, 0);
+	DO_REQ(0xc0, 0x1, 0x8383, 0);
+	DO_REQ(0x40, 0x1, 0x0000, 1);
+	DO_REQ(0x40, 0x1, 0x0001, 0);
+	DO_REQ(0x40, 0x1, 0x0002, 0x44);
+	return (0);
+}
+
+#undef DO_REQ
+
 Static int
 uplcom_open(void *addr, int portno)
 {
@@ -743,7 +798,8 @@
 			return (EIO);
 		}
 	}
-
+	if (sc->sc_chiptype == CHIPTYPE_PL2303X)
+		return (uplcom_initPL2303X(sc));
 	return (0);
 }
 

--=-LuMBlHTdF+ceeQIQ9Ebh--



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?1106136691.1132.17.camel>