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.
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
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);
}
_______________________________________________
[email protected] mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-stable
To unsubscribe, send any mail to "[EMAIL PROTECTED]"