The branch stable/11 has been updated by hselasky:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=671c393854a5ae60369beadfb74007e240bb18ab

commit 671c393854a5ae60369beadfb74007e240bb18ab
Author:     Hans Petter Selasky <[email protected]>
AuthorDate: 2021-01-07 14:34:26 +0000
Commit:     Hans Petter Selasky <[email protected]>
CommitDate: 2021-02-01 09:31:58 +0000

    MFC ea0efc370416:
    Add support for PL2303HXN to uplcom(4).
    
    Code changes in this commit were obtained from straight from OpenBSD's
    uplcom.c with almost no modification, the list of chip names and USB
    IDs was obtained from Linux.
    
    Differential Revision: https://reviews.freebsd.org/D27952
    Submitted by: tomli_tomli.me (Yifeng Li)
    Sponsored by: Mellanox Technologies // NVIDIA Networking
    
    (cherry picked from commit ea0efc37041640686fbfb226e80ee60e58cb17f1)
---
 share/man/man4/uplcom.4     |  4 +-
 sys/dev/usb/serial/uplcom.c | 94 +++++++++++++++++++++++++++++++++++++++------
 sys/dev/usb/usbdevs         |  6 +++
 3 files changed, 92 insertions(+), 12 deletions(-)

diff --git a/share/man/man4/uplcom.4 b/share/man/man4/uplcom.4
index b3f1fbb3ff18..ca29ee8d454d 100644
--- a/share/man/man4/uplcom.4
+++ b/share/man/man4/uplcom.4
@@ -29,7 +29,7 @@
 .\"
 .\" $FreeBSD$
 .\"
-.Dd April 26, 2017
+.Dd January 7, 2021
 .Dt UPLCOM 4
 .Os
 .Sh NAME
@@ -132,6 +132,8 @@ PLANEX USB-RS232 URS-03
 .It
 Prolific Generic USB-Serial Adapters
 .It
+Prolific Generic USB-Serial Adapters (HXN)
+.It
 Prolific Pharos USB-Serial Adapter
 .It
 RATOC REX-USB60
diff --git a/sys/dev/usb/serial/uplcom.c b/sys/dev/usb/serial/uplcom.c
index 27858af68692..0913cc7890d4 100644
--- a/sys/dev/usb/serial/uplcom.c
+++ b/sys/dev/usb/serial/uplcom.c
@@ -129,8 +129,13 @@ SYSCTL_INT(_hw_usb_uplcom, OID_AUTO, debug, CTLFLAG_RWTUN,
 #define        UPLCOM_BULK_BUF_SIZE 1024       /* bytes */
 
 #define        UPLCOM_SET_REQUEST              0x01
+#define        UPLCOM_SET_REQUEST_PL2303HXN    0x80
 #define        UPLCOM_SET_CRTSCTS              0x41
 #define        UPLCOM_SET_CRTSCTS_PL2303X      0x61
+#define        UPLCOM_SET_CRTSCTS_PL2303HXN    0xFA
+#define        UPLCOM_CLEAR_CRTSCTS_PL2303HXN  0xFF
+#define        UPLCOM_CRTSCTS_REG_PL2303HXN    0x0A
+#define        UPLCOM_STATUS_REG_PL2303HX      0x8080
 #define        RSAQ_STATUS_CTS                 0x80
 #define        RSAQ_STATUS_OVERRUN_ERROR       0x40
 #define        RSAQ_STATUS_PARITY_ERROR        0x20 
@@ -143,6 +148,7 @@ SYSCTL_INT(_hw_usb_uplcom, OID_AUTO, debug, CTLFLAG_RWTUN,
 #define        TYPE_PL2303                     0
 #define        TYPE_PL2303HX                   1
 #define        TYPE_PL2303HXD                  2
+#define        TYPE_PL2303HXN                  3
 
 #define        UPLCOM_STATE_INDEX              8
 
@@ -286,6 +292,12 @@ static const STRUCT_USB_HOST_ID uplcom_devs[] = {
        UPLCOM_DEV(PROLIFIC, MOTOROLA),         /* Motorola cable */
        UPLCOM_DEV(PROLIFIC, PHAROS),           /* Prolific Pharos */
        UPLCOM_DEV(PROLIFIC, PL2303),           /* Generic adapter */
+       UPLCOM_DEV(PROLIFIC, PL2303GC),         /* Generic adapter (PL2303HXN, 
type GC) */
+       UPLCOM_DEV(PROLIFIC, PL2303GB),         /* Generic adapter (PL2303HXN, 
type GB) */
+       UPLCOM_DEV(PROLIFIC, PL2303GT),         /* Generic adapter (PL2303HXN, 
type GT) */
+       UPLCOM_DEV(PROLIFIC, PL2303GL),         /* Generic adapter (PL2303HXN, 
type GL) */
+       UPLCOM_DEV(PROLIFIC, PL2303GE),         /* Generic adapter (PL2303HXN, 
type GE) */
+       UPLCOM_DEV(PROLIFIC, PL2303GS),         /* Generic adapter (PL2303HXN, 
type GS) */
        UPLCOM_DEV(PROLIFIC, RSAQ2),            /* I/O DATA USB-RSAQ2 */
        UPLCOM_DEV(PROLIFIC, RSAQ3),            /* I/O DATA USB-RSAQ3 */
        UPLCOM_DEV(PROLIFIC, UIC_MSR206),       /* UIC MSR206 Card Reader */
@@ -365,6 +377,10 @@ uplcom_attach(device_t dev)
        struct usb_device_descriptor *dd;
        int error;
 
+       struct usb_device_request req;
+       usb_error_t err;
+       uint8_t buf[4];
+
        DPRINTFN(11, "\n");
 
        device_set_usb_desc(dev);
@@ -404,6 +420,25 @@ uplcom_attach(device_t dev)
                break;
        }
 
+       /*
+        * The new chip revision PL2303HXN is only compatible with the new
+        * UPLCOM_SET_REQUEST_PL2303HXN command. Issuing the old command
+        * UPLCOM_SET_REQUEST to the new chip raises an error. Thus, PL2303HX
+        * and PL2303HXN can be distinguished by issuing an old-style request
+        * (on a status register) to the new chip and checking the error.
+        */
+       if (sc->sc_chiptype == TYPE_PL2303HX) {
+               req.bmRequestType = UT_READ_VENDOR_DEVICE;
+               req.bRequest = UPLCOM_SET_REQUEST;
+               USETW(req.wValue, UPLCOM_STATUS_REG_PL2303HX);
+               req.wIndex[0] = sc->sc_data_iface_no;
+               req.wIndex[1] = 0;
+               USETW(req.wLength, 1);
+               err = usbd_do_request(sc->sc_udev, NULL, &req, buf);
+               if (err)
+                       sc->sc_chiptype = TYPE_PL2303HXN;
+       }
+
        switch (sc->sc_chiptype) {
        case TYPE_PL2303:
                DPRINTF("chiptype: 2303\n");
@@ -411,6 +446,9 @@ uplcom_attach(device_t dev)
        case TYPE_PL2303HX:
                DPRINTF("chiptype: 2303HX/TA\n");
                break;
+       case TYPE_PL2303HXN:
+               DPRINTF("chiptype: 2303HXN\n");
+               break;
        case TYPE_PL2303HXD:
                DPRINTF("chiptype: 2303HXD/TB/RA/EA\n");
                break;
@@ -472,7 +510,8 @@ uplcom_attach(device_t dev)
                usbd_xfer_set_stall(sc->sc_xfer[UPLCOM_BULK_DT_WR]);
                usbd_xfer_set_stall(sc->sc_xfer[UPLCOM_BULK_DT_RD]);
                mtx_unlock(&sc->sc_mtx);
-       } else {
+       } else if (sc->sc_chiptype == TYPE_PL2303HX ||
+                  sc->sc_chiptype == TYPE_PL2303HXD) {
                /* reset upstream data pipes */
                if (uplcom_pl2303_do(sc->sc_udev, UT_WRITE_VENDOR_DEVICE,
                    UPLCOM_SET_REQUEST, 8, 0, 0) ||
@@ -480,6 +519,12 @@ uplcom_attach(device_t dev)
                    UPLCOM_SET_REQUEST, 9, 0, 0)) {
                        goto detach;
                }
+       } else if (sc->sc_chiptype == TYPE_PL2303HXN) {
+               /* reset upstream data pipes */
+               if (uplcom_pl2303_do(sc->sc_udev, UT_WRITE_VENDOR_DEVICE,
+                   UPLCOM_SET_REQUEST_PL2303HXN, 0x07, 0x03, 0)) {
+                       goto detach;
+               }
        }
 
        error = ucom_attach(&sc->sc_super_ucom, &sc->sc_ucom, 1, sc,
@@ -543,6 +588,11 @@ uplcom_reset(struct uplcom_softc *sc, struct usb_device 
*udev)
 {
        struct usb_device_request req;
 
+       if (sc->sc_chiptype == TYPE_PL2303HXN) {
+               /* PL2303HXN doesn't need this reset sequence */
+               return (0);
+       }
+
        req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
        req.bRequest = UPLCOM_SET_REQUEST;
        USETW(req.wValue, 0);
@@ -580,6 +630,11 @@ uplcom_pl2303_init(struct usb_device *udev, uint8_t 
chiptype)
 {
        int err;
 
+       if (chiptype == TYPE_PL2303HXN) {
+               /* PL2303HXN doesn't need this initialization sequence */
+               return (0);
+       }
+
        if (uplcom_pl2303_do(udev, UT_READ_VENDOR_DEVICE, UPLCOM_SET_REQUEST, 
0x8484, 0, 1)
            || uplcom_pl2303_do(udev, UT_WRITE_VENDOR_DEVICE, 
UPLCOM_SET_REQUEST, 0x0404, 0, 0)
            || uplcom_pl2303_do(udev, UT_READ_VENDOR_DEVICE, 
UPLCOM_SET_REQUEST, 0x8484, 0, 1)
@@ -726,7 +781,7 @@ uplcom_pre_param(struct ucom_softc *ucom, struct termios *t)
         *
         * The PL2303 can only set specific baud rates, up to 1228800 baud.
         * The PL2303HX can set any baud rate up to 6Mb.
-        * The PL2303HX rev. D can set any baud rate up to 12Mb.
+        * The PL2303HX rev. D and PL2303HXN can set any baud rate up to 12Mb.
         *
         */
 
@@ -734,6 +789,10 @@ uplcom_pre_param(struct ucom_softc *ucom, struct termios 
*t)
        if (t->c_ospeed & 0x80000000)
                return 0;
        switch (sc->sc_chiptype) {
+               case TYPE_PL2303HXN:
+                       if (t->c_ospeed <= 12000000)
+                               return (0);
+                       break;
                case TYPE_PL2303HXD:
                        if (t->c_ospeed <= 12000000)
                                return (0);
@@ -871,21 +930,34 @@ uplcom_cfg_param(struct ucom_softc *ucom, struct termios 
*t)
                DPRINTF("crtscts = on\n");
 
                req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
-               req.bRequest = UPLCOM_SET_REQUEST;
-               USETW(req.wValue, 0);
-               if (sc->sc_chiptype != TYPE_PL2303)
-                       USETW(req.wIndex, UPLCOM_SET_CRTSCTS_PL2303X);
-               else
-                       USETW(req.wIndex, UPLCOM_SET_CRTSCTS);
+               if (sc->sc_chiptype == TYPE_PL2303HXN) {
+                       req.bRequest = UPLCOM_SET_REQUEST_PL2303HXN;
+                       USETW(req.wValue, UPLCOM_CRTSCTS_REG_PL2303HXN);
+                       USETW(req.wIndex, UPLCOM_SET_CRTSCTS_PL2303HXN);
+               } else {
+                       req.bRequest = UPLCOM_SET_REQUEST;
+                       USETW(req.wValue, 0);
+                       if (sc->sc_chiptype != TYPE_PL2303)
+                               USETW(req.wIndex, UPLCOM_SET_CRTSCTS_PL2303X);
+                       else
+                               USETW(req.wIndex, UPLCOM_SET_CRTSCTS);
+               }
                USETW(req.wLength, 0);
 
                ucom_cfg_do_request(sc->sc_udev, &sc->sc_ucom, 
                    &req, NULL, 0, 1000);
        } else {
                req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
-               req.bRequest = UPLCOM_SET_REQUEST;
-               USETW(req.wValue, 0);
-               USETW(req.wIndex, 0);
+               if (sc->sc_chiptype == TYPE_PL2303HXN) {
+                       req.bRequest = UPLCOM_SET_REQUEST_PL2303HXN;
+                       USETW(req.wValue, UPLCOM_CRTSCTS_REG_PL2303HXN);
+                       USETW(req.wIndex, UPLCOM_CLEAR_CRTSCTS_PL2303HXN);
+               }
+               else {
+                       req.bRequest = UPLCOM_SET_REQUEST;
+                       USETW(req.wValue, 0);
+                       USETW(req.wIndex, 0);
+               }
                USETW(req.wLength, 0);
                ucom_cfg_do_request(sc->sc_udev, &sc->sc_ucom, 
                    &req, NULL, 0, 1000);
diff --git a/sys/dev/usb/usbdevs b/sys/dev/usb/usbdevs
index 5d52ff0f7217..2bb5e05035f6 100644
--- a/sys/dev/usb/usbdevs
+++ b/sys/dev/usb/usbdevs
@@ -3654,6 +3654,12 @@ product PROLIFIC MICROMAX_610U   0x0612  Micromax 610U
 product PROLIFIC DCU11         0x1234  DCU-11 Phone Cable
 product PROLIFIC UIC_MSR206    0x206a  UIC MSR206 Card Reader
 product PROLIFIC PL2303                0x2303  PL2303 Serial (ATEN/IOGEAR 
UC232A)
+product PROLIFIC PL2303GC      0x23a3  PL2303HXN Serial, type GC
+product PROLIFIC PL2303GB      0x23b3  PL2303HXN Serial, type GB
+product PROLIFIC PL2303GT      0x23c3  PL2303HXN Serial, type GT
+product PROLIFIC PL2303GL      0x23d3  PL2303HXN Serial, type GL
+product PROLIFIC PL2303GE      0x23e3  PL2303HXN Serial, type GE
+product PROLIFIC PL2303GS      0x23f3  PL2303HXN Serial, type GS
 product PROLIFIC PL2305                0x2305  Parallel printer
 product PROLIFIC ATAPI4                0x2307  ATAPI-4 Controller
 product PROLIFIC PL2501                0x2501  PL2501 Host-Host interface
_______________________________________________
[email protected] mailing list
https://lists.freebsd.org/mailman/listinfo/dev-commits-src-all
To unsubscribe, send any mail to "[email protected]"

Reply via email to