Date: Fri, 21 Jan 2005 12:14:14 +0100 From: Emanuel Strobl <emanuel.strobl@gmx.net> To: freebsd-stable@freebsd.org Cc: freebsd-current@freebsd.org Subject: Re: strange ucom (uplcom) error Message-ID: <200501211214.15327.emanuel.strobl@gmx.net> In-Reply-To: <1106227110.716.11.camel@genius2.i.cz> References: <1106134006.1132.12.camel@genius2.i.cz> <1106227110.716.11.camel@genius2.i.cz>
next in thread | previous in thread | raw e-mail | index | archive | help
--Boundary-00=_HQO8B7C8ZC4Yjnp
Content-Type: text/plain;
charset="iso-8859-15"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline
Am Donnerstag, 20. Januar 2005 14:18 schrieb 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.
This didn't apply cleanly against my -stable from today.
Attached is a cleaned version (#define RSAQ_STATUS_CTS doesn't exist in
-stable uplcom.c) for -stable which compiles for me.
>
> Michal
--Boundary-00=_HQO8B7C8ZC4Yjnp
Content-Type: text/x-diff;
charset="iso-8859-15";
name="uplcom.c.2303x.patch"
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment;
filename="uplcom.c.2303x.patch"
--- sys/dev/usb/uplcom.c Fri Jan 21 10:49:09 2005
+++ sys/dev/usb/uplcom.c Fri Jan 21 11:01:33 2005
@@ -96,10 +96,13 @@
#include <sys/poll.h>
#include <sys/sysctl.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>
@@ -112,29 +115,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_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;
@@ -154,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 *,
@@ -297,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);
@@ -372,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));
@@ -615,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, 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);
@@ -711,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) { /* 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)
{
@@ -741,7 +798,8 @@
return (EIO);
}
}
-
+ if (sc->sc_chiptype == CHIPTYPE_PL2303X)
+ return (uplcom_initPL2303X(sc));
return (0);
}
--Boundary-00=_HQO8B7C8ZC4Yjnp--
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200501211214.15327.emanuel.strobl>
