Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 20 Jan 2005 14:18:30 +0100
From:      Michal Mertl <mime@traveller.cz>
To:        Emanuel Strobl <emanuel.strobl@gmx.net>
Cc:        bernd@bwct.de
Subject:   Re: strange ucom (uplcom) error
Message-ID:  <1106227110.716.11.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

--=-k3av6U01ybkct5I0WZMD
Content-Type: text/plain
Content-Transfer-Encoding: 7bit

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

I tested my patch for binary safety on CURRENT yesterday (dialed with
ppp) and didn't notice any problem.

I'm attaching my patch again because some recipients didn't probably
receive it yesterday.

Michal




--=-k3av6U01ybkct5I0WZMD
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	20 Jan 2005 13:15:40 -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,34 @@
 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	UPLCOM_SET_CRTSCTS_2303X	0x61
+#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 +163,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 +307,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 +383,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 +633,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, UPLCOM_SET_CRTSCTS_2303X);
+	else
+		USETW(req.wIndex, UPLCOM_SET_CRTSCTS);
 	USETW(req.wLength, 0);
 
 	err = usbd_do_request(sc->sc_ucom.sc_udev, &req, 0);
@@ -713,6 +732,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) { /* XXX - shouldn't happen */				\
+		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 +799,8 @@
 			return (EIO);
 		}
 	}
-
+	if (sc->sc_chiptype == CHIPTYPE_PL2303X)
+		return (uplcom_initPL2303X(sc));
 	return (0);
 }
 

--=-k3av6U01ybkct5I0WZMD--



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