uplcom(4) does not work on cuaU0 ?

Hans Petter Selasky hselasky at c2i.net
Sat Nov 13 11:40:25 UTC 2010


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

--HPS
-------------- next part --------------
=== 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))


More information about the freebsd-usb mailing list