Re: uplcom driver update for 23a3 (HXN) chip

2020-10-26 Thread Stefan Huber

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

2020-10-26 Thread Patrick Wildt
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

2020-10-26 Thread Stefan Huber

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,272
bDeviceClass == 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);