Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 13 Nov 2010 12:41:24 +0100
From:      Hans Petter Selasky <hselasky@c2i.net>
To:        freebsd-usb@freebsd.org
Subject:   Re: uplcom(4) does not work on cuaU0 ?
Message-ID:  <201011131241.24671.hselasky@c2i.net>
In-Reply-To: <201011121525.13324.hselasky@c2i.net>
References:  <20101112145849.161e39a8@davenulle.org> <201011121525.13324.hselasky@c2i.net>

next in thread | previous in thread | raw e-mail | index | archive | help
--Boundary-00=_kln3MirHbDD469G
Content-Type: Text/Plain;
  charset="iso-8859-1"
Content-Transfer-Encoding: 7bit

Please try the attached patch. Others having UPLCOM devices should try this 
patch aswell and see if their device is still working.

--HPS

--Boundary-00=_kln3MirHbDD469G
Content-Type: text/plain; charset="iso-8859-1"; name="uplcom_detect_patch.txt"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
	filename="uplcom_detect_patch.txt"

=== uplcom.c
==================================================================
--- uplcom.c	(revision 215173)
+++ uplcom.c	(local)
@@ -176,7 +176,7 @@
 static usb_error_t uplcom_reset(struct uplcom_softc *, struct usb_device *);
 static usb_error_t uplcom_pl2303_do(struct usb_device *, int8_t, uint8_t,
 			uint16_t, uint16_t, uint16_t);
-static int	uplcom_pl2303_init(struct usb_device *, uint8_t);
+static int	uplcom_pl2303_init(struct uplcom_softc *sc, struct usb_device *);
 static void	uplcom_cfg_set_dtr(struct ucom_softc *, uint8_t);
 static void	uplcom_cfg_set_rts(struct ucom_softc *, uint8_t);
 static void	uplcom_cfg_set_break(struct ucom_softc *, uint8_t);
@@ -355,7 +355,6 @@
 	struct uplcom_softc *sc = device_get_softc(dev);
 	struct usb_interface *iface;
 	struct usb_interface_descriptor *id;
-	struct usb_device_descriptor *dd;
 	int error;
 
 	DPRINTFN(11, "\n");
@@ -367,19 +366,6 @@
 
 	sc->sc_udev = uaa->device;
 
-	/* Determine the chip type.  This algorithm is taken from Linux. */
-	dd = usbd_get_device_descriptor(sc->sc_udev);
-	if (dd->bDeviceClass == 0x02)
-		sc->sc_chiptype = TYPE_PL2303;
-	else if (dd->bMaxPacketSize == 0x40)
-		sc->sc_chiptype = TYPE_PL2303HX;
-	else
-		sc->sc_chiptype = TYPE_PL2303;
-
-	DPRINTF("chiptype: %s\n",
-	    (sc->sc_chiptype == TYPE_PL2303HX) ?
-	    "2303X" : "2303");
-
 	/*
 	 * USB-RSAQ1 has two interface
 	 *
@@ -432,19 +418,20 @@
 	usbd_xfer_set_stall(sc->sc_xfer[UPLCOM_BULK_DT_RD]);
 	mtx_unlock(&sc->sc_mtx);
 
-	error = ucom_attach(&sc->sc_super_ucom, &sc->sc_ucom, 1, sc,
-	    &uplcom_callback, &sc->sc_mtx);
-	if (error) {
-		goto detach;
-	}
 	/*
-	 * do the initialization during attach so that the system does not
-	 * sleep during open:
+	 * do the initialization during attach so that the system does
+	 * not sleep during open:
 	 */
-	if (uplcom_pl2303_init(uaa->device, sc->sc_chiptype)) {
+	if (uplcom_pl2303_init(sc, uaa->device)) {
 		device_printf(dev, "init failed\n");
 		goto detach;
 	}
+
+	error = ucom_attach(&sc->sc_super_ucom, &sc->sc_ucom, 1, sc,
+	    &uplcom_callback, &sc->sc_mtx);
+	if (error) {
+		goto detach;
+	}
 	ucom_set_pnpinfo_usb(&sc->sc_super_ucom, dev);
 
 	return (0);
@@ -506,7 +493,7 @@
 }
 
 static int
-uplcom_pl2303_init(struct usb_device *udev, uint8_t chiptype)
+uplcom_pl2303_init(struct uplcom_softc *sc, struct usb_device *udev)
 {
 	int err;
 
@@ -522,12 +509,22 @@
 	    || uplcom_pl2303_do(udev, UT_WRITE_VENDOR_DEVICE, UPLCOM_SET_REQUEST, 1, 0, 0))
 		return (EIO);
 
-	if (chiptype == TYPE_PL2303HX)
-		err = uplcom_pl2303_do(udev, UT_WRITE_VENDOR_DEVICE, UPLCOM_SET_REQUEST, 2, 0x44, 0);
-	else
+	/* Determine chiptype by trial and error. */
+
+	err = uplcom_pl2303_do(udev, UT_WRITE_VENDOR_DEVICE, UPLCOM_SET_REQUEST, 2, 0x44, 0);
+	if (err == 0)
+		sc->sc_chiptype = TYPE_PL2303HX;
+	else {
 		err = uplcom_pl2303_do(udev, UT_WRITE_VENDOR_DEVICE, UPLCOM_SET_REQUEST, 2, 0x24, 0);
+		if (err == 0)
+			sc->sc_chiptype = TYPE_PL2303;
+	}
+
 	if (err)
 		return (EIO);
+
+	DPRINTF("chiptype: %s\n", (sc->sc_chiptype == TYPE_PL2303HX) ?
+	    "2303X" : "2303");
 	
 	if (uplcom_pl2303_do(udev, UT_WRITE_VENDOR_DEVICE, UPLCOM_SET_REQUEST, 8, 0, 0)
 	    || uplcom_pl2303_do(udev, UT_WRITE_VENDOR_DEVICE, UPLCOM_SET_REQUEST, 9, 0, 0))

--Boundary-00=_kln3MirHbDD469G--



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