Commit 53f87a8f authored by Bill Marr's avatar Bill Marr Committed by Greg Kroah-Hartman

[PATCH] Status Query On My MCT-U232 Patch

Brief Patch Description:

Fix a problem in the 'mct_u232' driver whereby output data gets held up in the
USB/RS-232 adapter for RS-232 devices which don't assert the 'CTS' signal.

Background:

The Belkin F5U109 is a 9-pin USB/RS-232 adapter that is supported by the
existing 'mct_u232' kernel module.  Recently, I've been testing it under the
2.4.22 (Slackware 9.1) kernel and the 2.6.0-test9 kernel.

I've connected a Garmin 'GPS35 TracPak' GPS receiver (RS-232 interface) and an
ordinary RS-232 external modem to my PC's USB port via the Belkin F5U109
adapter.

Problem:

Although _reads_ from either of the RS-232 devices mentioned above work fine
via the Belkin adapter, _writes_ to the GPS receiver are not being seen by
the GPS.  Writes to the modem, however, work perfectly.

Aside: The 'Linux USB Users' archives show that at least one other person
(circa May 2002) had the exact same problem I'm having, but it sounds like no
solution was ever determined because the person in question just bought a
different USB/RS-232 adapter.

Investigation:

Using the 'seyon' terminal emulator in Linux and a crude hardware RS-232
"breakout box" that I hacked together, I've determined that the problem is
related to the RTS/CTS RS-232 hardware handshaking.

After further investigation, I've concluded that RS-232 devices which do not
assert the 'Clear To Send' ('CTS') signal prevent the Belkin F5U109 adapter
from transmitting data to the RS-232 device when the current (version 1.1)
'mct_u232' module is used. The data gets "queued up" (up to a point -- 16
bytes, I think) in the adapter but never transmitted.

Since this GPS receiver works perfectly (reads and writes) when connected to a
PC running W98se using the same Belkin adapter and the Belkin-supplied
Windows driver, the Linux driver became suspect.

After some testing with SniffUSB, I found that the Windows driver sends a
couple of unique undocumented USB 'device requests' that the Linux driver
does not. As it turns out, the second of those 2 requests is critical in
making the adapter transmit data to a device which doesn't assert 'CTS'.

For completeness, the Windows driver in use was determined from the 'Device
Manager', 'Driver File Details' page:

   U2SPORT.VXD
   Provider: Magic Control Technology
   File version: 1.21P.0104 for Win98/Me

Solution:

My patch adds the 2 missing USB 'device request' commands right after a
baud-change command. This mimics the operation of the W98 driver.

Unfortunately, after much testing, I found no other operation (besides a
baud-change request) under Windows that triggers either of these 2 'device
request' commands. This makes it impossible to fully document the behavior of
these requests, but I've made entries for them alongside the others in the
'mct_u232.h' file.

Purely for clarity, the patch also modifies various comments in 'mct_u232.h',
mostly to reflect proper sizes of the various 'USB Device Request' fields per
the USB 1.1 specification.

The patch also updates the version number of the driver, corrects a minor
typographical error, and documents a difference in the length of the data in
a 'baud rate change' command for certain adapters which use a coded baud-rate
rather than the conventional RS-232 baud rate divisor.

I've provided (tested) patches for both the 2.4.22 and the 2.6.0-test9
kernels.

Please note that the changes to 'mct_u232.h' apply to both 2.4.22 and
2.6.0-test9 since that file has not changed between those kernel releases.
Nevertheless, I've included that (same) portion of the patch in both
attachments for simplicity.

Bill Marr
parent 1a11f106
...@@ -24,6 +24,11 @@ ...@@ -24,6 +24,11 @@
* Basic tests have been performed with minicom/zmodem transfers and * Basic tests have been performed with minicom/zmodem transfers and
* modem dialing under Linux 2.4.0-test10 (for me it works fine). * modem dialing under Linux 2.4.0-test10 (for me it works fine).
* *
* 04-Nov-2003 Bill Marr <marr at flex dot com>
* - Mimic Windows driver by sending 2 USB 'device request' messages
* following normal 'baud rate change' message. This allows data to be
* transmitted to RS-232 devices which don't assert the 'CTS' signal.
*
* 10-Nov-2001 Wolfgang Grandegger * 10-Nov-2001 Wolfgang Grandegger
* - Fixed an endianess problem with the baudrate selection for PowerPC. * - Fixed an endianess problem with the baudrate selection for PowerPC.
* *
...@@ -85,7 +90,7 @@ ...@@ -85,7 +90,7 @@
/* /*
* Version Information * Version Information
*/ */
#define DRIVER_VERSION "v1.1" #define DRIVER_VERSION "v1.2"
#define DRIVER_AUTHOR "Wolfgang Grandegger <wolfgang@ces.ch>" #define DRIVER_AUTHOR "Wolfgang Grandegger <wolfgang@ces.ch>"
#define DRIVER_DESC "Magic Control Technology USB-RS232 converter driver" #define DRIVER_DESC "Magic Control Technology USB-RS232 converter driver"
...@@ -216,6 +221,7 @@ static int mct_u232_set_baud_rate(struct usb_serial *serial, int value) ...@@ -216,6 +221,7 @@ static int mct_u232_set_baud_rate(struct usb_serial *serial, int value)
{ {
unsigned int divisor; unsigned int divisor;
int rc; int rc;
unsigned char zero_byte = 0;
divisor = cpu_to_le32(mct_u232_calculate_baud_rate(serial, value)); divisor = cpu_to_le32(mct_u232_calculate_baud_rate(serial, value));
rc = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0), rc = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
MCT_U232_SET_BAUD_RATE_REQUEST, MCT_U232_SET_BAUD_RATE_REQUEST,
...@@ -225,6 +231,35 @@ static int mct_u232_set_baud_rate(struct usb_serial *serial, int value) ...@@ -225,6 +231,35 @@ static int mct_u232_set_baud_rate(struct usb_serial *serial, int value)
if (rc < 0) if (rc < 0)
err("Set BAUD RATE %d failed (error = %d)", value, rc); err("Set BAUD RATE %d failed (error = %d)", value, rc);
dbg("set_baud_rate: value: %d, divisor: 0x%x", value, divisor); dbg("set_baud_rate: value: %d, divisor: 0x%x", value, divisor);
/* Mimic the MCT-supplied Windows driver (version 1.21P.0104), which
always sends two extra USB 'device request' messages after the
'baud rate change' message. The actual functionality of the
request codes in these messages is not fully understood but these
particular codes are never seen in any operation besides a baud
rate change. Both of these messages send a single byte of data
whose value is always zero. The second of these two extra messages
is required in order for data to be properly written to an RS-232
device which does not assert the 'CTS' signal. */
rc = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
MCT_U232_SET_UNKNOWN1_REQUEST,
MCT_U232_SET_REQUEST_TYPE,
0, 0, &zero_byte, MCT_U232_SET_UNKNOWN1_SIZE,
WDR_TIMEOUT);
if (rc < 0)
err("Sending USB device request code %d failed (error = %d)",
MCT_U232_SET_UNKNOWN1_REQUEST, rc);
rc = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
MCT_U232_SET_UNKNOWN2_REQUEST,
MCT_U232_SET_REQUEST_TYPE,
0, 0, &zero_byte, MCT_U232_SET_UNKNOWN2_SIZE,
WDR_TIMEOUT);
if (rc < 0)
err("Sending USB device request code %d failed (error = %d)",
MCT_U232_SET_UNKNOWN2_REQUEST, rc);
return rc; return rc;
} /* mct_u232_set_baud_rate */ } /* mct_u232_set_baud_rate */
......
...@@ -57,6 +57,21 @@ ...@@ -57,6 +57,21 @@
#define MCT_U232_SET_MODEM_CTRL_REQUEST 10 /* Set Modem Control Register (MCR) */ #define MCT_U232_SET_MODEM_CTRL_REQUEST 10 /* Set Modem Control Register (MCR) */
#define MCT_U232_SET_MODEM_CTRL_SIZE 1 #define MCT_U232_SET_MODEM_CTRL_SIZE 1
/* This USB device request code is not well understood. It is transmitted by
the MCT-supplied Windows driver whenever the baud rate changes.
*/
#define MCT_U232_SET_UNKNOWN1_REQUEST 11 /* Unknown functionality */
#define MCT_U232_SET_UNKNOWN1_SIZE 1
/* This USB device request code is not well understood. It is transmitted by
the MCT-supplied Windows driver whenever the baud rate changes.
Without this USB device request, the USB/RS-232 adapter will not write to
RS-232 devices which do not assert the 'CTS' signal.
*/
#define MCT_U232_SET_UNKNOWN2_REQUEST 12 /* Unknown functionality */
#define MCT_U232_SET_UNKNOWN2_SIZE 1
/* /*
* Baud rate (divisor) * Baud rate (divisor)
*/ */
...@@ -137,22 +152,31 @@ ...@@ -137,22 +152,31 @@
* Baud rate (divisor) * Baud rate (divisor)
* ------------------- * -------------------
* *
* BmRequestType: 0x4 (0100 0000B) * BmRequestType: 0x40 (0100 0000B)
* bRequest: 0x5 * bRequest: 0x05
* wValue: 0x0 * wValue: 0x0000
* wIndex: 0x0 * wIndex: 0x0000
* wLength: 0x4 * wLength: 0x0004
* Data: divisor = 115200 / baud_rate * Data: divisor = 115200 / baud_rate
* *
* SniffUSB observations (Nov 2003): Contrary to the 'wLength' value of 4
* shown above, observations with a Belkin F5U109 adapter, using the
* MCT-supplied Windows98 driver (U2SPORT.VXD, "File version: 1.21P.0104 for
* Win98/Me"), show this request has a length of 1 byte, presumably because
* of the fact that the Belkin adapter and the 'Sitecom U232-P25' adapter
* use a baud-rate code instead of a conventional RS-232 baud rate divisor.
* The current source code for this driver does not reflect this fact, but
* the driver works fine with this adapter/driver combination nonetheless.
*
* *
* Line Control Register (LCR) * Line Control Register (LCR)
* --------------------------- * ---------------------------
* *
* BmRequestType: 0x4 (0100 0000B) 0xc (1100 0000B) * BmRequestType: 0x40 (0100 0000B) 0xc0 (1100 0000B)
* bRequest: 0x7 0x6 * bRequest: 0x07 0x06
* wValue: 0x0 * wValue: 0x0000
* wIndex: 0x0 * wIndex: 0x0000
* wLength: 0x1 * wLength: 0x0001
* Data: LCR (see below) * Data: LCR (see below)
* *
* Bit 7: Divisor Latch Access Bit (DLAB). When set, access to the data * Bit 7: Divisor Latch Access Bit (DLAB). When set, access to the data
...@@ -186,18 +210,18 @@ ...@@ -186,18 +210,18 @@
* *
* SniffUSB observations: Bit 7 seems not to be used. There seem to be two bugs * SniffUSB observations: Bit 7 seems not to be used. There seem to be two bugs
* in the Win98 driver: the break does not work (bit 6 is not asserted) and the * in the Win98 driver: the break does not work (bit 6 is not asserted) and the
* sticky parity bit is not cleared when set once. The LCR can also be read * stick parity bit is not cleared when set once. The LCR can also be read
* back with USB request 6 but this has never been observed with SniffUSB. * back with USB request 6 but this has never been observed with SniffUSB.
* *
* *
* Modem Control Register (MCR) * Modem Control Register (MCR)
* ---------------------------- * ----------------------------
* *
* BmRequestType: 0x4 (0100 0000B) * BmRequestType: 0x40 (0100 0000B)
* bRequest: 0xa * bRequest: 0x0a
* wValue: 0x0 * wValue: 0x0000
* wIndex: 0x0 * wIndex: 0x0000
* wLength: 0x1 * wLength: 0x0001
* Data: MCR (Bit 4..7, see below) * Data: MCR (Bit 4..7, see below)
* *
* Bit 7: Reserved, always 0. * Bit 7: Reserved, always 0.
...@@ -226,11 +250,11 @@ ...@@ -226,11 +250,11 @@
* Modem Status Register (MSR) * Modem Status Register (MSR)
* --------------------------- * ---------------------------
* *
* BmRequestType: 0xc (1100 0000B) * BmRequestType: 0xc0 (1100 0000B)
* bRequest: 0x2 * bRequest: 0x02
* wValue: 0x0 * wValue: 0x0000
* wIndex: 0x0 * wIndex: 0x0000
* wLength: 0x1 * wLength: 0x0001
* Data: MSR (see below) * Data: MSR (see below)
* *
* Bit 7: Data Carrier Detect (CD). Reflects the state of the DCD line on the * Bit 7: Data Carrier Detect (CD). Reflects the state of the DCD line on the
...@@ -287,6 +311,41 @@ ...@@ -287,6 +311,41 @@
* minicom/zmodem transfers (CRC errors). * minicom/zmodem transfers (CRC errors).
* *
* *
* Unknown #1
* -------------------
*
* BmRequestType: 0x40 (0100 0000B)
* bRequest: 0x0b
* wValue: 0x0000
* wIndex: 0x0000
* wLength: 0x0001
* Data: 0x00
*
* SniffUSB observations (Nov 2003): With the MCT-supplied Windows98 driver
* (U2SPORT.VXD, "File version: 1.21P.0104 for Win98/Me"), this request
* occurs immediately after a "Baud rate (divisor)" message. It was not
* observed at any other time. It is unclear what purpose this message
* serves.
*
*
* Unknown #2
* -------------------
*
* BmRequestType: 0x40 (0100 0000B)
* bRequest: 0x0c
* wValue: 0x0000
* wIndex: 0x0000
* wLength: 0x0001
* Data: 0x00
*
* SniffUSB observations (Nov 2003): With the MCT-supplied Windows98 driver
* (U2SPORT.VXD, "File version: 1.21P.0104 for Win98/Me"), this request
* occurs immediately after the 'Unknown #1' message (see above). It was
* not observed at any other time. It is unclear what other purpose (if
* any) this message might serve, but without it, the USB/RS-232 adapter
* will not write to RS-232 devices which do not assert the 'CTS' signal.
*
*
* Flow control * Flow control
* ------------ * ------------
* *
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment