From b.candler@pobox.com Mon Aug 16 08:34:05 2004 Return-Path: Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 6A09016A4CE for ; Mon, 16 Aug 2004 08:34:05 +0000 (GMT) Received: from puzzle.pobox.com (puzzle.sasl.smtp.pobox.com [207.8.226.4]) by mx1.FreeBSD.org (Postfix) with ESMTP id 0BE8143D68 for ; Mon, 16 Aug 2004 08:34:04 +0000 (GMT) (envelope-from b.candler@pobox.com) Received: from localhost.localdomain (localhost [127.0.0.1]) by puzzle.pobox.com (Postfix) with ESMTP id D28AB138F95 for ; Mon, 16 Aug 2004 04:32:26 -0400 (EDT) Received: from billdog.local.linnet.org (dsl-212-74-113-65.access.uk.tiscali.com [212.74.113.65]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by puzzle.pobox.com (Postfix) with ESMTP id 92E39138F8B for ; Mon, 16 Aug 2004 04:32:24 -0400 (EDT) Received: from brian by billdog.local.linnet.org with local (Exim 4.31) id 1BwcwK-0000H7-NF for FreeBSD-gnats-submit@freebsd.org; Mon, 16 Aug 2004 09:34:00 +0100 Message-Id: Date: Mon, 16 Aug 2004 09:34:00 +0100 From: Brian Candler Reply-To: Brian Candler To: FreeBSD-gnats-submit@freebsd.org Cc: Subject: umct sending/receiving wrong characters X-Send-Pr-Version: 3.113 X-GNATS-Notify: >Number: 70523 >Category: usb >Synopsis: [umct] [patch] umct sending/receiving wrong characters >Confidential: no >Severity: non-critical >Priority: low >Responsible: hselasky >State: open >Quarter: >Keywords: >Date-Required: >Class: sw-bug >Submitter-Id: current-users >Arrival-Date: Mon Aug 16 08:40:33 GMT 2004 >Closed-Date: >Last-Modified: Mon Jul 25 17:05:15 UTC 2011 >Originator: Brian Candler >Release: FreeBSD 5.2.1-RELEASE i386 >Organization: >Environment: I have the same occuring on two different systems: FreeBSD 5.2.1-RELEASE #1: Tue Mar 30 11:09:14 BST 2004 CPU: AMD Athlon(tm) XP 2500+ (1837.51-MHz 686-class CPU) ohci0: mem 0xee084000-0xee084fff irq 10 at device 2.0 on pci0 FreeBSD 4.10-RELEASE #0: Sun Aug 15 20:22:15 BST 2004 CPU: Pentium/P55C (quarter-micron) (263.93-MHz 586-class CPU) uhci0: port 0xfcc0-0xfcdf irq 9 at device 7.2 on pci0 The first is a desktop, the second a Sony Vaio PCG-C1F laptop. Since I get identical results, I'm pretty sure it's the umct driver which has the problem. >Description: I plug in a 'Intel USB Solution USB-232' cable (USB to DB25). It identifies as: ucom0: MCT Corporation. USB-232 Interfact Controller, rev 1.00/1.02, addr 3 (sic - Interfact not Interface) However it consistently reads incorrect characters. Connecting back-to-back with a real COM port, and using: cu -l ucom0 -s 19200 cu -l cuaa0 -s 19200 * REAL COM PORT --> USB-232 If I send a space (20) I receive hex E8. If I send a capital A (41) I receive hex E0. It's perfectly consistent, here's a mapping: tx 20 30 31 32 33 34 35 36 37 38 39 rx e8 ec ec ed ed ee ee ef ef ec ec tx 40 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f rx e0 e0 e1 e1 e2 e2 e3 e3 e0 e0 e1 e1 e2 e2 e3 e3 tx 50 51 52 53 54 55 56 57 58 59 5a rx e4 e4 e5 e5 e6 e6 e7 e7 e4 e4 e5 * USB-232 --> REAL COM PORT This time I get two bytes on the COM port for each byte I send on the USB232. tx 20 30 31 32 33 rx 00FC C0FC C3FC C4FC or CCFC C7FC or CFFC It does look rather a bit like speed mismatch (esp. USB-232 -> REAL), but I tried different speed combinations and couldn't get them to talk. I have not yet had a chance to try this device on a Linux box to see if their mct_u232 driver works with it. At 2400bps I managed to freeze the laptop totally, requiring me to remove the battery and reboot. However that also happens with a different [uplcom] USB->RS232 adaptor I have as well, so that's a subject of a different PR. >How-To-Repeat: See above. You need 'kldload umct', a genuine serial port, and a null-modem serial cable. Run 'cu' at both ends (under 'script' if you want to catch the data and use 'hexdump -C' to view it afterwards). I also have a little C protocol-analyser program to view bytes directly in hex. >Fix: No idea! Would like to know if anyone else has a USB<->RS232 device which uses the umct driver working successfully. >Release-Note: >Audit-Trail: From: Brian Candler To: FreeBSD-gnats-submit@FreeBSD.org, freebsd-bugs@FreeBSD.org Cc: sanpei@freebsd.org, rwatson@freebsd.org Subject: Re: kern/70523: umct sending/receiving wrong characters Date: Sat, 21 Aug 2004 21:21:46 +0100 This device worked correctly under Linux, and I have now made a patch [attached below] so that it works under FreeBSD too. Looking at linux-2.4.27/drivers/usb/serial/mct_u232.[ch], you'll see that there are two different ways of calculating the baud rate divider, depending on which type of device you have. FreeBSD only implemented one of these, and unfortunately I had the other sort of device. I wasn't sure if there was an easy way to access the 'uaa' structure in the middle of umct_calc_baud, so instead I added an extra structure member to 'sc' to flag which divider constants to use. If there's a way of doing this without having to store this extra state then please do so. I notice a new entry USB_PRODUCT_BELKIN_F5U409 has recently been added to umct.c (but is not in the Linux driver); someone needs to check which way it works. Aside: Something else the Linux driver does is to send commands 11 and 12 (constants MCT_U232_SET_UNKNOWN1_REQUEST and MCT_U232_SET_UNKNOWN2_REQUEST) after setting the baud rate. The comment says: /* 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. */ I tried making the FreeBSD driver do this too, but on my hardware it just gave timeouts: /kernel: ucom0: ubsa_request: TIMEOUT So I guess it's not needed for the device I have, and I've taken it out. (That debug message should have said "umct_request", and the patch below also fixes that) Regards, Brian Candler. --- sys/dev/usb/umct.c.orig Tue Apr 13 04:39:16 2004 +++ sys/dev/usb/umct.c Sat Aug 21 21:17:07 2004 @@ -81,6 +81,7 @@ uint8_t sc_msr; uint8_t sc_lcr; uint8_t sc_mcr; + uint8_t sc_divider_type; #if __FreeBSD_version >= 500000 void *sc_swicookie; #endif @@ -193,6 +194,10 @@ sc->sc_intr_number = -1; sc->sc_intr_pipe = NULL; + if (uaa->product == USB_PRODUCT_MCT_SITECOM_USB232 || + uaa->product == USB_PRODUCT_BELKIN_F5U109) + sc->sc_divider_type = 1; + err = usbd_set_config_index(dev, UMCT_CONFIG_INDEX, 1); if (err) { printf("%s: failed to set configuration: %s\n", @@ -328,7 +333,7 @@ err = usbd_do_request(sc->sc_ucom.sc_udev, &req, oval); if (err) - printf("%s: ubsa_request: %s\n", + printf("%s: umct_request: %s\n", USBDEVNAME(sc->sc_ucom.sc_dev), usbd_errstr(err)); return (err); } @@ -418,22 +423,34 @@ } Static int -umct_calc_baud(u_int baud) +umct_calc_baud(struct umct_softc *sc, u_int baud) { - switch(baud) { - case B300: return (0x1); - case B600: return (0x2); - case B1200: return (0x3); - case B2400: return (0x4); - case B4800: return (0x6); - case B9600: return (0x8); - case B19200: return (0x9); - case B38400: return (0xa); - case B57600: return (0xb); - case 115200: return (0xc); - case B0: - default: - break; + if (sc->sc_divider_type == 1) { + switch(baud) { + case B300: return (0x1); + case B600: return (0x2); + case B1200: return (0x3); + case B2400: return (0x4); + case B4800: return (0x6); + case B9600: return (0x8); + case B19200: return (0x9); + case B38400: return (0xa); + case B57600: return (0xb); + case 115200: return (0xc); + } + } else { + switch(baud) { + case B300: return 115200/300; + case B600: return 115200/600; + case B1200: return 115200/1200; + case B2400: return 115200/2400; + case B4800: return 115200/4800; + case B9600: return 115200/9600; + case B19200: return 115200/19200; + case B38400: return 115200/38400; + case B57600: return 115200/57600; + case 115200: return 115200/115200; + } } return (0x0); @@ -446,7 +463,8 @@ uint32_t value; sc = addr; - value = umct_calc_baud(ti->c_ospeed); + value = umct_calc_baud(sc, ti->c_ospeed); + if (value == 0) return (EIO); umct_request(sc, UMCT_SET_BAUD, UMCT_SET_BAUD_SIZE, value); value = sc->sc_lcr & 0x40; From: Brian Candler To: FreeBSD-gnats-submit@FreeBSD.org, freebsd-bugs@FreeBSD.org Cc: sanpei@freebsd.org, rwatson@freebsd.org Subject: Re: kern/70523: umct sending/receiving wrong characters Date: Thu, 26 Aug 2004 16:42:19 +0100 [Aside] My Vaio, which was prone to freeze up completely with the other (uplcom) USB->232 interface, has a UHCI USB controller. I applied the following two patches to the base 4.10-RELEASE: http://www.freebsd.org/cgi/cvsweb.cgi/src/sys/dev/usb/uhci.c.diff?r1=1.40.2.14&r2=1.151 http://www.freebsd.org/cgi/cvsweb.cgi/src/sys/sys/queue.h.diff?r1=1.54&r2=1.55 and the uplcom device seems to work now. Hasn't had much testing, but I'm hopeful that things will be happier in 4.11-RELEASE :-) Responsible-Changed-From-To: freebsd-bugs->freebsd-usb Responsible-Changed-By: linimon Responsible-Changed-When: Thu Nov 4 07:30:40 GMT 2004 Responsible-Changed-Why: Reassign to appropriate mailing list. http://www.freebsd.org/cgi/query-pr.cgi?pr=70523 From: Brian Candler To: FreeBSD-gnats-submit@FreeBSD.org, freebsd-bugs@FreeBSD.org Cc: sanpei@freebsd.org Subject: Re: kern/70523: umct sending/receiving wrong characters Date: Sat, 21 Aug 2004 21:21:46 +0100 This device worked correctly under Linux, and I have now made a patch [attached below] so that it works under FreeBSD too. Looking at linux-2.4.27/drivers/usb/serial/mct_u232.[ch], you'll see that there are two different ways of calculating the baud rate divider, depending on which type of device you have. FreeBSD only implemented one of these, and unfortunately I had the other sort of device. I wasn't sure if there was an easy way to access the 'uaa' structure in the middle of umct_calc_baud, so instead I added an extra structure member to 'sc' to flag which divider constants to use. If there's a way of doing this without having to store this extra state then please do so. I notice a new entry USB_PRODUCT_BELKIN_F5U409 has recently been added to umct.c (but is not in the Linux driver); someone needs to check which way it works. Aside: Something else the Linux driver does is to send commands 11 and 12 (constants MCT_U232_SET_UNKNOWN1_REQUEST and MCT_U232_SET_UNKNOWN2_REQUEST) after setting the baud rate. The comment says: /* 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. */ I tried making the FreeBSD driver do this too, but on my hardware it just gave timeouts: /kernel: ucom0: ubsa_request: TIMEOUT So I guess it's not needed for the device I have, and I've taken it out. (That debug message should have said "umct_request", and the patch below also fixes that) Regards, Brian Candler. --- sys/dev/usb/umct.c.orig Tue Apr 13 04:39:16 2004 +++ sys/dev/usb/umct.c Sat Aug 21 21:17:07 2004 @@ -81,6 +81,7 @@ uint8_t sc_msr; uint8_t sc_lcr; uint8_t sc_mcr; + uint8_t sc_divider_type; #if __FreeBSD_version >= 500000 void *sc_swicookie; #endif @@ -193,6 +194,10 @@ sc->sc_intr_number = -1; sc->sc_intr_pipe = NULL; + if (uaa->product == USB_PRODUCT_MCT_SITECOM_USB232 || + uaa->product == USB_PRODUCT_BELKIN_F5U109) + sc->sc_divider_type = 1; + err = usbd_set_config_index(dev, UMCT_CONFIG_INDEX, 1); if (err) { printf("%s: failed to set configuration: %s\n", @@ -328,7 +333,7 @@ err = usbd_do_request(sc->sc_ucom.sc_udev, &req, oval); if (err) - printf("%s: ubsa_request: %s\n", + printf("%s: umct_request: %s\n", USBDEVNAME(sc->sc_ucom.sc_dev), usbd_errstr(err)); return (err); } @@ -418,22 +423,34 @@ } Static int -umct_calc_baud(u_int baud) +umct_calc_baud(struct umct_softc *sc, u_int baud) { - switch(baud) { - case B300: return (0x1); - case B600: return (0x2); - case B1200: return (0x3); - case B2400: return (0x4); - case B4800: return (0x6); - case B9600: return (0x8); - case B19200: return (0x9); - case B38400: return (0xa); - case B57600: return (0xb); - case 115200: return (0xc); - case B0: - default: - break; + if (sc->sc_divider_type == 1) { + switch(baud) { + case B300: return (0x1); + case B600: return (0x2); + case B1200: return (0x3); + case B2400: return (0x4); + case B4800: return (0x6); + case B9600: return (0x8); + case B19200: return (0x9); + case B38400: return (0xa); + case B57600: return (0xb); + case 115200: return (0xc); + } + } else { + switch(baud) { + case B300: return 115200/300; + case B600: return 115200/600; + case B1200: return 115200/1200; + case B2400: return 115200/2400; + case B4800: return 115200/4800; + case B9600: return 115200/9600; + case B19200: return 115200/19200; + case B38400: return 115200/38400; + case B57600: return 115200/57600; + case 115200: return 115200/115200; + } } return (0x0); @@ -446,7 +463,8 @@ uint32_t value; sc = addr; - value = umct_calc_baud(ti->c_ospeed); + value = umct_calc_baud(sc, ti->c_ospeed); + if (value == 0) return (EIO); umct_request(sc, UMCT_SET_BAUD, UMCT_SET_BAUD_SIZE, value); value = sc->sc_lcr & 0x40; _______________________________________________ freebsd-bugs@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-bugs To unsubscribe, send any mail to "freebsd-bugs-unsubscribe@freebsd.org" Responsible-Changed-From-To: freebsd-usb->hps Responsible-Changed-By: eadler Responsible-Changed-When: Sun Jul 24 22:39:58 UTC 2011 Responsible-Changed-Why: work http://www.freebsd.org/cgi/query-pr.cgi?pr=70523 Responsible-Changed-From-To: hps->hselasky Responsible-Changed-By: linimon Responsible-Changed-When: Mon Jul 25 17:04:21 UTC 2011 Responsible-Changed-Why: Use committer's canonical login. http://www.freebsd.org/cgi/query-pr.cgi?pr=70523 >Unformatted: