Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 7 Jul 2003 10:14:05 -0700 (PDT)
From:      wpaul@FreeBSD.ORG (Bill Paul)
To:        imp@bsdimp.com (M. Warner Losh)
Cc:        mobile@freebsd.org
Subject:   Re: MCT USB<->RS232 driver
Message-ID:  <20030707171405.854DF37B401@hub.freebsd.org>
In-Reply-To: <20030707.014628.18704844.imp@bsdimp.com> from "M. Warner Losh" at "Jul 7, 2003 01:46:28 am"

next in thread | previous in thread | raw e-mail | index | archive | help
> In message: <20030707043655.71E6537B422@hub.freebsd.org>
>             wpaul@freebsd.org (Bill Paul) writes:
> : When I got it home, I found that almost everything is supported in
> : FreeBSD 5.x, except for one thing: the serial port. The chip is a
> : MCT USB-232 device, which is supported in NetBSD, but not FreeBSD.
> 
> But Scott Long already committed his umct driver a few days ago... :-)
> 
> Warner
> 

Yes, so I have been told. :P

And guess what. It has a bug. :)

Well ok, to be fair, it doesn't really have a bug: it lacks a workaround
for a buggy chip. The driver determines the bulk output buffer size
by checking the data returned by the chip in its bulk out endpoint
descriptor. This is right in most cases, but not for the
USB_PRODUCT_MCT_SITECOM_USB232 device (which, unfortunately, is what
they put in the port replicator I bought). The value it returns for
wMaxPacketSize is 32, but in reality, you must use 16. If you don't,
the chip drops data under certain circumstances. A good example: attach
a modem to the serial adapter and set up a PPP link over it, then try
to ssh to a remote host somewhere. Ssh will get about halfway through
the connection attempt and then hang. I observed a similar problem
with my IRC client.

It turns out the NetBSD driver that I hacked up worked because it has
a workaround for this chip bug. I applied a similar workaround to Scott's
driver and now PPP works again. Here's a patch:

--- umct.c.orig	Thu Jul  3 18:50:39 2003
+++ umct.c	Mon Jul  7 00:52:55 2003
@@ -241,7 +241,10 @@
 
 		if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT) {
 			ucom->sc_bulkout_no = ed->bEndpointAddress;
-			ucom->sc_obufsize = UGETW(ed->wMaxPacketSize);
+			if (uaa->product == USB_PRODUCT_MCT_SITECOM_USB232)
+				ucom->sc_obufsize = 16; /* device is broken */
+			else
+				ucom->sc_obufsize = UGETW(ed->wMaxPacketSize);
 			continue;
 		}

This is almost literally what NetBSD does. Barring any objections, I'd
like to check this in. (CC'ing Scott on this e-mail.)

-Bill

--
=============================================================================
-Bill Paul            (510) 749-2329 | Senior Engineer, Master of Unix-Fu
                 wpaul@windriver.com | Wind River Systems
=============================================================================
      "If stupidity were a handicap, you'd have the best parking spot."
=============================================================================



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