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>