Re: uplcom driver update for 23a3 (HXN) chip
On 26.10.2020 09:30, Patrick Wildt wrote: On Mon, Oct 26, 2020 at 09:12:17AM +0100, Stefan Huber wrote: Hey all, I recently got hands on an USB-TTY converter that is not (yet) supported by OpenBSD: > addr 03: 067b:23a3 Prolific Technology Inc., USB-Serial Controller Simply adding the device ID to usbdevs and the uplcom driver did not do the trick, as apparently it is what the linux driver calls a "HXN" chip, which is (as of now) not yet supported by the uplcom driver (also, not in NetBSD where the uplcom driver seems to come from). Some hours (days) later, I have produced the following diff, butchering both the uplcom and the linux driver. I know it looks like shit, but it works (for now and for me). I will try to "streamline" the driver, and am happy for any feedback (since you may see watching the code I am not a good kernel hacker yet). I was also thinking of adding all the other IDs from the linux driver to uplcom, but then I can't test them since I only have the two chips 067b:2303 and 067b:23a3. So I'd rather not merge the other IDs to prevent the kernel from doing nasty things to them (or was it the other way around?) The diff's below. Works for me. Not looking for okay or a merge, mostly feedback and maybe a merge for a future version of this diff. First of all, we need unified diffs. Usually you have a CVS checkout and then run cvs diff -u. Yours don't look like you used cvs, was that a diff -r? Well, even then you should add -u, otherwise diffs become unreadable. Second, only OpenBSD account holders can ask for OKs. :) So, please resend with diff -u, otherwise no one will have a look at it since the diff is hard to follow. Thanks, Patrick Thanks Patrick! The unified diff is below: diff -u /home/src_orig/sys/dev/usb/uplcom.c /usr/src/sys/dev/usb/uplcom.c --- /home/src_orig/sys/dev/usb/uplcom.c Fri Jul 31 12:49:33 2020 +++ /usr/src/sys/dev/usb/uplcom.c Mon Oct 26 09:26:13 2020 @@ -69,12 +69,26 @@ #define UPLCOM_SECOND_IFACE_INDEX 1 #define UPLCOM_SET_REQUEST 0x01 +#define UPLCOM_SET_NREQUEST0x80 +#define UPLCOM_READ_REQUEST0x01 +#define UPLCOM_READ_NREQUEST 0x81 #define UPLCOM_SET_CRTSCTS 0x41 #define UPLCOM_HX_SET_CRTSCTS 0x61 #define RSAQ_STATUS_CTS 0x80 #define RSAQ_STATUS_DSR 0x02 #define RSAQ_STATUS_DCD 0x01 +#define UPLCOM_READ_HX_STATUS 0x8080 +#define UPLCOM_HXN_RESET_REG 0x07 +#define UPLCOM_HXN_RESET_UPSTREAM_PIPE 0x02 +#define UPLCOM_HXN_RESET_DOWNSTREAM_PIPE 0x01 + +#define UPLCOM_HXN_FLOWCTRL_REG0x0a +#define UPLCOM_HXN_FLOWCTRL_MASK 0x1c +#define UPLCOM_HXN_FLOWCTRL_NONE 0x1c +#define UPLCOM_HXN_FLOWCTRL_RTS_CTS0x18 +#define UPLCOM_HXN_FLOWCTRL_XON_XOFF 0x0c + structuplcom_softc { struct devicesc_dev;/* base device */ struct usbd_device *sc_udev; /* USB device */ @@ -96,6 +110,7 @@ u_char sc_lsr;/* Local status register */ u_char sc_msr;/* uplcom status register */ int sc_type_hx;/* HX variant */ + int sc_type_hxn; /* HXN variant */ }; /* @@ -106,6 +121,10 @@ #define UPLCOMOBUFSIZE 256 usbd_status uplcom_reset(struct uplcom_softc *); +usbd_status uplcom_update_reg(struct uplcom_softc *sc, char reg, char mask, char val); +usbd_status uplcom_vendor_read(struct uplcom_softc *sc, char val, char buf[1]); +usbd_status uplcom_vendor_write(struct uplcom_softc *sc, char val, char index); +int uplcom_test_hxn(struct uplcom_softc *); usbd_status uplcom_set_line_coding(struct uplcom_softc *sc, struct usb_cdc_line_state *state); usbd_status uplcom_set_crtscts(struct uplcom_softc *); @@ -151,6 +170,7 @@ { USB_VENDOR_PLX, USB_PRODUCT_PLX_CA42 }, { USB_VENDOR_PANASONIC, USB_PRODUCT_PANASONIC_TYTP50P6S }, { USB_VENDOR_PROLIFIC, USB_PRODUCT_PROLIFIC_PL2303 }, + { USB_VENDOR_PROLIFIC, USB_PRODUCT_PROLIFIC_PL23a3 }, { USB_VENDOR_PROLIFIC, USB_PRODUCT_PROLIFIC_PL2303X }, { USB_VENDOR_PROLIFIC, USB_PRODUCT_PROLIFIC_PL2303X2 }, { USB_VENDOR_PROLIFIC, USB_PRODUCT_PROLIFIC_RSAQ2 }, @@ -247,16 +267,34 @@ * The Linux driver suggest this will only be true for the HX * variants. The datasheets disagree. */ - if (ddesc->bDeviceClass == 0x02) + if (ddesc->bDeviceClass == 0x02) { /* type 0 */ sc->sc_type_hx = 0; - else if (ddesc->bMaxPacketSize == 0x40) + sc->sc_type_hxn = 0; + } + else if (ddesc->bMaxPacketSize == 0x40) { /* type hx */ sc->sc_type_hx = 1; - else + sc->sc_type_hxn = 0; + } + else { /* probably type 1 */ sc->sc_type_hx = 0; +
Re: uplcom driver update for 23a3 (HXN) chip
On Mon, Oct 26, 2020 at 09:12:17AM +0100, Stefan Huber wrote: > Hey all, > > I recently got hands on an USB-TTY converter that is not (yet) supported by > OpenBSD: > > > addr 03: 067b:23a3 Prolific Technology Inc., USB-Serial Controller > > Simply adding the device ID to usbdevs and the uplcom driver did not do the > trick, as apparently it is what the linux driver calls a "HXN" chip, which > is (as of now) not yet supported by the uplcom driver (also, not in NetBSD > where the uplcom driver seems to come from). Some hours (days) later, I have > produced the following diff, butchering both the uplcom and the linux > driver. I know it looks like shit, but it works (for now and for me). I will > try to "streamline" the driver, and am happy for any feedback (since you may > see watching the code I am not a good kernel hacker yet). > > I was also thinking of adding all the other IDs from the linux driver to > uplcom, but then I can't test them since I only have the two chips 067b:2303 > and 067b:23a3. So I'd rather not merge the other IDs to prevent the kernel > from doing nasty things to them (or was it the other way around?) > > The diff's below. Works for me. Not looking for okay or a merge, mostly > feedback and maybe a merge for a future version of this diff. First of all, we need unified diffs. Usually you have a CVS checkout and then run cvs diff -u. Yours don't look like you used cvs, was that a diff -r? Well, even then you should add -u, otherwise diffs become unreadable. Second, only OpenBSD account holders can ask for OKs. :) So, please resend with diff -u, otherwise no one will have a look at it since the diff is hard to follow. Thanks, Patrick > Happy Hacking, > Stefan > > > Common subdirectories: /home/src_orig/sys/dev/usb/CVS and > /usr/src/sys/dev/usb/CVS > Common subdirectories: /home/src_orig/sys/dev/usb/dwc2 and > /usr/src/sys/dev/usb/dwc2 > diff /home/src_orig/sys/dev/usb/uplcom.c /usr/src/sys/dev/usb/uplcom.c > 66c66 > < #define DPRINTF(x) DPRINTFN(0, x) > --- > > #define DPRINTF(x) printf x; > 71a72,74 > > #define UPLCOM_SET_NREQUEST 0x80 > > #define UPLCOM_READ_REQUEST 0x01 > > #define UPLCOM_READ_NREQUEST0x81 > 77a81,91 > > #define UPLCOM_READ_HX_STATUS 0x8080 > > #define UPLCOM_HXN_RESET_REG0x07 > > #define UPLCOM_HXN_RESET_UPSTREAM_PIPE 0x02 > > #define UPLCOM_HXN_RESET_DOWNSTREAM_PIPE0x01 > > > > #define UPLCOM_HXN_FLOWCTRL_REG 0x0a > > #define UPLCOM_HXN_FLOWCTRL_MASK0x1c > > #define UPLCOM_HXN_FLOWCTRL_NONE0x1c > > #define UPLCOM_HXN_FLOWCTRL_RTS_CTS 0x18 > > #define UPLCOM_HXN_FLOWCTRL_XON_XOFF0x0c > > > 98a113 > > int sc_type_hxn; /* HXN variant */ > 108a124,127 > > usbd_status uplcom_update_reg(struct uplcom_softc *sc, char reg, char > > mask, char val); > > usbd_status uplcom_vendor_read(struct uplcom_softc *sc, char val, char > > buf[1]); > > usbd_status uplcom_vendor_write(struct uplcom_softc *sc, char val, char > > index); > > int uplcom_test_hxn(struct uplcom_softc *); > 153a173 > > { USB_VENDOR_PROLIFIC, USB_PRODUCT_PROLIFIC_PL23a3 }, > 250c270,272 > < if (ddesc->bDeviceClass == 0x02) > --- > > printf("[DEBUG] DeviceClass: %x\n", ddesc->bDeviceClass); > > printf("[DEBUG] MaxPacketSize: %x\n", ddesc->bMaxPacketSize); > > if (ddesc->bDeviceClass == 0x02) { /* type 0 */ > 252c274,276 > < else if (ddesc->bMaxPacketSize == 0x40) > --- > > sc->sc_type_hxn = 0; > > } > > else if (ddesc->bMaxPacketSize == 0x40) { /* type hx */ > 254c278,280 > < else > --- > > sc->sc_type_hxn = 0; > > } > > else { /* probably type 1 */ > 255a282,283 > > sc->sc_type_hxn = 0; > > } > 256a285,298 > > /* > > * The Linux driver also distinguishes HXN variant... > > * Let's see if that is needed for the 23a3 variant. > > */ > > if (sc->sc_type_hx == 1) { > > printf("[DEBUG] seems to be HX type. Checking for HXN type.\n"); > > if (uplcom_test_hxn(sc)) { > > printf("[DEBUG] Probably HXN.\n"); > > sc->sc_type_hxn = 1; > > } else { > > printf("[DEBUG] Probably not HXN.\n"); > > } > > } > > > 259c301,303 > < if (sc->sc_type_hx) { > --- > > if (sc->sc_type_hxn) { > > DPRINTF(("uplcom_attach: chiptype 2303XN\n")); > > } else if (sc->sc_type_hx) { > 419a464,471 > > > > if (sc->sc_type_hxn) { > > DPRINTF(("[DEBUG] trying to reset hxn\n")); > > req.bmRequestType = UT_WRITE_VENDOR_DEVICE; > > req.bRequest = UPLCOM_SET_NREQUEST; > > USETW(req.wValue, 0x07); > > USETW(req.wIndex, UPLCOM_HXN_RESET_UPSTREAM_PIPE | > > UPLCOM_HXN_RESET_DOWNSTREAM_PIPE); > > USETW(req.wLength, 0); > 421,425c473,484 > <
uplcom driver update for 23a3 (HXN) chip
Hey all, I recently got hands on an USB-TTY converter that is not (yet) supported by OpenBSD: addr 03: 067b:23a3 Prolific Technology Inc., USB-Serial Controller Simply adding the device ID to usbdevs and the uplcom driver did not do the trick, as apparently it is what the linux driver calls a "HXN" chip, which is (as of now) not yet supported by the uplcom driver (also, not in NetBSD where the uplcom driver seems to come from). Some hours (days) later, I have produced the following diff, butchering both the uplcom and the linux driver. I know it looks like shit, but it works (for now and for me). I will try to "streamline" the driver, and am happy for any feedback (since you may see watching the code I am not a good kernel hacker yet). I was also thinking of adding all the other IDs from the linux driver to uplcom, but then I can't test them since I only have the two chips 067b:2303 and 067b:23a3. So I'd rather not merge the other IDs to prevent the kernel from doing nasty things to them (or was it the other way around?) The diff's below. Works for me. Not looking for okay or a merge, mostly feedback and maybe a merge for a future version of this diff. Happy Hacking, Stefan Common subdirectories: /home/src_orig/sys/dev/usb/CVS and /usr/src/sys/dev/usb/CVS Common subdirectories: /home/src_orig/sys/dev/usb/dwc2 and /usr/src/sys/dev/usb/dwc2 diff /home/src_orig/sys/dev/usb/uplcom.c /usr/src/sys/dev/usb/uplcom.c 66c66 < #define DPRINTF(x) DPRINTFN(0, x) --- #define DPRINTF(x) printf x; 71a72,74 #define UPLCOM_SET_NREQUEST 0x80 #define UPLCOM_READ_REQUEST 0x01 #define UPLCOM_READ_NREQUEST0x81 77a81,91 #define UPLCOM_READ_HX_STATUS 0x8080 #define UPLCOM_HXN_RESET_REG0x07 #define UPLCOM_HXN_RESET_UPSTREAM_PIPE 0x02 #define UPLCOM_HXN_RESET_DOWNSTREAM_PIPE0x01 #define UPLCOM_HXN_FLOWCTRL_REG 0x0a #define UPLCOM_HXN_FLOWCTRL_MASK0x1c #define UPLCOM_HXN_FLOWCTRL_NONE0x1c #define UPLCOM_HXN_FLOWCTRL_RTS_CTS 0x18 #define UPLCOM_HXN_FLOWCTRL_XON_XOFF0x0c 98a113 int sc_type_hxn; /* HXN variant */ 108a124,127 usbd_status uplcom_update_reg(struct uplcom_softc *sc, char reg, char mask, char val); usbd_status uplcom_vendor_read(struct uplcom_softc *sc, char val, char buf[1]); usbd_status uplcom_vendor_write(struct uplcom_softc *sc, char val, char index); int uplcom_test_hxn(struct uplcom_softc *); 153a173 { USB_VENDOR_PROLIFIC, USB_PRODUCT_PROLIFIC_PL23a3 }, 250c270,272bDeviceClass == 0x02) --- printf("[DEBUG] DeviceClass: %x\n", ddesc->bDeviceClass); printf("[DEBUG] MaxPacketSize: %x\n", ddesc->bMaxPacketSize); if (ddesc->bDeviceClass == 0x02) { /* type 0 */ 252c274,276 bMaxPacketSize == 0x40) --- sc->sc_type_hxn = 0; } else if (ddesc->bMaxPacketSize == 0x40) { /* type hx */ 254c278,280 sc_type_hxn = 0; } else { /* probably type 1 */ 255a282,283 sc->sc_type_hxn = 0; } 256a285,298 /* * The Linux driver also distinguishes HXN variant... * Let's see if that is needed for the 23a3 variant. */ if (sc->sc_type_hx == 1) { printf("[DEBUG] seems to be HX type. Checking for HXN type.\n"); if (uplcom_test_hxn(sc)) { printf("[DEBUG] Probably HXN.\n"); sc->sc_type_hxn = 1; } else { printf("[DEBUG] Probably not HXN.\n"); } } 259c301,303 sc_type_hx) { --- if (sc->sc_type_hxn) { DPRINTF(("uplcom_attach: chiptype 2303XN\n")); } else if (sc->sc_type_hx) { 419a464,471 if (sc->sc_type_hxn) { DPRINTF(("[DEBUG] trying to reset hxn\n")); req.bmRequestType = UT_WRITE_VENDOR_DEVICE; req.bRequest = UPLCOM_SET_NREQUEST; USETW(req.wValue, 0x07); USETW(req.wIndex, UPLCOM_HXN_RESET_UPSTREAM_PIPE | UPLCOM_HXN_RESET_DOWNSTREAM_PIPE); USETW(req.wLength, 0); 421,425c473,484 sc_iface_number); sc_udev, , 0); if (err) { DPRINTF(("[DEBUG] uplcom_reset_hxn err=%d\n", err)); return (err); } } else { DPRINTF(("[DEBUG] trying to reset non-hxn device\n")); req.bmRequestType = UT_WRITE_VENDOR_DEVICE; req.bRequest = UPLCOM_SET_REQUEST; USETW(req.wValue, 8);