Project

General

Profile

Actions

Bug #748

closed

Better chips distinguishing code for uplcom(4)

Added by hasso over 17 years ago. Updated over 17 years ago.

Status:
Closed
Priority:
Low
Assignee:
-
Category:
-
Target version:
-
Start date:
Due date:
% Done:

0%

Estimated time:

Description

  1. HG changeset patch
  2. User Hasso Tepper <>
  3. Date 1185626194 -10800
  4. Branch HEAD
  5. Node ID e934355abc88da7910c99487c22d12e2c021dfd6
  6. Parent f7c2990c9f78edd4b38694bcfa1a17f66182c35d
    Better chips distinguishing code for uplcom(4).

Kill current method to distinguish between old PL-2303(H) and newer
PL-2303(H)X chips. Instead of managing list try as hard as possible to
make it automatic: look at known device release numbers at first and if
it fails, try to determine chip via looking at other fields (magic values
borrowed from Linux driver) in the device descriptor.

diff --git a/sys/dev/usbmisc/uplcom/uplcom.c b/sys/dev/usbmisc/uplcom/uplcom.c
--- a/sys/dev/usbmisc/uplcom/uplcom.c
+++ b/sys/dev/usbmisc/uplcom/uplcom.c
@ -68,15 +68,16 @

/*
 * This driver supports several USB-to-RS232 serial adapters driven by
- * Prolific PL-2303, PL-2303X and probably PL-2303HX USB-to-RS232
- * bridge chip. The adapters are sold under many different brand
- * names.
+ * Prolific PL-2303 (known also as PL-2303H), PL-2303X and PL-2303HX
+ * USB-to-RS232 bridge chip. The adapters are sold under many different
+ * brand names. * * Datasheets are available at Prolific www site at * http://www.prolific.com.tw. The datasheets don't contain full * programming information for the chip. *
- * PL-2303HX is probably programmed the same as PL-2303X.
+ * PL-2303HX has the same features as PL-2303X (at least from the point of
+ * view of device driver) but is pin-to-pin compatible with PL-2303. * * There are several differences between PL-2303 and PL-2303(H)X. * PL-2303(H)X can do higher bitrate in bulk mode, has probably
@ -144,6 +145,10 @ SYSCTL_INT(_hw_usb_uplcom, OID_AUTO, deb
#define RSAQ_STATUS_DSR 0x02
#define RSAQ_STATUS_DCD 0x01

#define CHIP_PL2303 0x0202
#define CHIP_PL2303X 0x0300
#define CHIP_PL2303HX 0x0400

#define TYPE_PL2303 0
#define TYPE_PL2303X 1

@ -209,60 +214,42 @ struct ucom_callback uplcom_callback = {
NULL
};

static const struct uplcom_product {
uint16_t vendor;
- uint16_t product;
- int32_t release; /* release is a 16bit entity,
- * if 1 is specified we "don't care"
* This is a floor value. The table
- * must have newer revs before older
- * revs (and 1 last).
*/
- char chiptype;
} uplcom_products [] = {
{ USB_VENDOR_RADIOSHACK, USB_PRODUCT_RADIOSHACK_USBCABLE, -1, TYPE_PL2303 },
static const struct usb_devno uplcom_devs[] = {
{ USB_VENDOR_RADIOSHACK, USB_PRODUCT_RADIOSHACK_USBCABLE },

/* I/O DATA USB-RSAQ /
- { USB_VENDOR_IODATA, USB_PRODUCT_IODATA_USBRSAQ, 1, TYPE_PL2303 },
+ { USB_VENDOR_IODATA, USB_PRODUCT_IODATA_USBRSAQ },
/
Prolific Pharos /
{ USB_VENDOR_PROLIFIC, USB_PRODUCT_PROLIFIC_PL2303X, 1, TYPE_PL2303 },
+ { USB_VENDOR_PROLIFIC, USB_PRODUCT_PROLIFIC_PL2303X },
/
I/O DATA USB-RSAQ2 /
{ USB_VENDOR_PROLIFIC, USB_PRODUCT_PROLIFIC_RSAQ2, 1, TYPE_PL2303 },
+ { USB_VENDOR_PROLIFIC, USB_PRODUCT_PROLIFIC_RSAQ2 },
/
I/O DATA USB-RSAQ3 /
{ USB_VENDOR_PROLIFIC, USB_PRODUCT_PROLIFIC_RSAQ3, 1, TYPE_PL2303X },
+ { USB_VENDOR_PROLIFIC, USB_PRODUCT_PROLIFIC_RSAQ3 },
/
Willcom W-SIM /
{ USB_VENDOR_PROLIFIC2, USB_PRODUCT_PROLIFIC2_WSIM, 1, TYPE_PL2303X},
+ { USB_VENDOR_PROLIFIC2, USB_PRODUCT_PROLIFIC2_WSIM },
/
PLANEX USB-RS232 URS-03 /
{ USB_VENDOR_ATEN, USB_PRODUCT_ATEN_UC232A, 1, TYPE_PL2303 },
/
ST Lab USB-SERIAL-4 /
- { USB_VENDOR_PROLIFIC, USB_PRODUCT_PROLIFIC_PL2303,
- 0x300, TYPE_PL2303X },
- /
IOGEAR/ATEN UC-232A (also ST Lab USB-SERIAL-1) /
- { USB_VENDOR_PROLIFIC, USB_PRODUCT_PROLIFIC_PL2303, 1, TYPE_PL2303 },
/
HAMLET exagerate XURS232 /
- { USB_VENDOR_PROLIFIC, USB_PRODUCT_PROLIFIC_PL2303, 1, TYPE_PL2303X },
+ { USB_VENDOR_ATEN, USB_PRODUCT_ATEN_UC232A },
+ /
IOGEAR/ATEN UC-232A, ST Lab USB-SERIAL-X etc /
+ { USB_VENDOR_PROLIFIC, USB_PRODUCT_PROLIFIC_PL2303 },
/
TDK USB-PHS Adapter UHA6400 /
{ USB_VENDOR_TDK, USB_PRODUCT_TDK_UHA6400, 1, TYPE_PL2303 },
+ { USB_VENDOR_TDK, USB_PRODUCT_TDK_UHA6400 },
/
RATOC REX-USB60 /
{ USB_VENDOR_RATOC, USB_PRODUCT_RATOC_REXUSB60, 1, TYPE_PL2303 },
+ { USB_VENDOR_RATOC, USB_PRODUCT_RATOC_REXUSB60 },
/
ELECOM UC-SGT /
{ USB_VENDOR_ELECOM, USB_PRODUCT_ELECOM_UCSGT, 1, TYPE_PL2303 },
{ USB_VENDOR_ELECOM, USB_PRODUCT_ELECOM_UCSGT0, 1, TYPE_PL2303 },
+ { USB_VENDOR_ELECOM, USB_PRODUCT_ELECOM_UCSGT },
+ { USB_VENDOR_ELECOM, USB_PRODUCT_ELECOM_UCSGT0 },
/
Sony Ericsson USB Cable /
{ USB_VENDOR_SONYERICSSON, USB_PRODUCT_SONYERICSSON_DCU10,
- 1,TYPE_PL2303 },
+ { USB_VENDOR_SONYERICSSON, USB_PRODUCT_SONYERICSSON_DCU10 },
/
SOURCENEXT KeikaiDenwa 8 /
{ USB_VENDOR_SOURCENEXT, USB_PRODUCT_SOURCENEXT_KEIKAI8,
- 1, TYPE_PL2303 },
+ { USB_VENDOR_SOURCENEXT, USB_PRODUCT_SOURCENEXT_KEIKAI8 },
/
SOURCENEXT KeikaiDenwa 8 with charger /
{ USB_VENDOR_SOURCENEXT, USB_PRODUCT_SOURCENEXT_KEIKAI8_CHG,
- 1, TYPE_PL2303 },
+ { USB_VENDOR_SOURCENEXT, USB_PRODUCT_SOURCENEXT_KEIKAI8_CHG },
/
HAL Corporation Crossam2+USB /
{ USB_VENDOR_HAL, USB_PRODUCT_HAL_IMR001, 1, TYPE_PL2303 },
+ { USB_VENDOR_HAL, USB_PRODUCT_HAL_IMR001 },
/
Sitecom USB to Serial /
{ USB_VENDOR_MCT, USB_PRODUCT_MCT_SITECOM_USB232, 1, TYPE_PL2303 },
+ { USB_VENDOR_MCT, USB_PRODUCT_MCT_SITECOM_USB232 },
/
Tripp-Lite U209-000-R */
{ USB_VENDOR_TRIPPLITE, USB_PRODUCT_TRIPPLITE_U209, -1, TYPE_PL2303X },
+ { USB_VENDOR_TRIPPLITE, USB_PRODUCT_TRIPPLITE_U209 }, { 0, 0 }
};

@ -316,20 +303,12 @ uplcom_match(device_t self)
uplcom_match(device_t self) {
struct usb_attach_arg *uaa = device_get_ivars(self);
- int i;

if (uaa->iface != NULL)
return (UMATCH_NONE);

- for (i = 0; uplcom_products[i].vendor != 0; i++) {
- if (uplcom_products[i].vendor uaa->vendor &&
- uplcom_products[i].product uaa->product &&
- (uplcom_products[i].release <= uaa->release ||
- uplcom_products[i].release == 1)) {
return (UMATCH_VENDOR_PRODUCT);
- }
- }
- return (UMATCH_NONE);
+ return (usb_lookup(uplcom_devs, uaa->vendor, uaa->product) != NULL ?
+ UMATCH_VENDOR_PRODUCT : UMATCH_NONE);
}

static int
@ -338,6 +317,7 @ uplcom_attach(device_t self)
struct uplcom_softc *sc = device_get_softc(self);
struct usb_attach_arg *uaa = device_get_ivars(self);
usbd_device_handle dev = uaa->device;
+ usb_device_descriptor_t *dd;
struct ucom_softc *ucom;
usb_config_descriptor_t *cdesc;
usb_interface_descriptor_t *id;
@ -364,35 +344,61 @ uplcom_attach(device_t self)
DPRINTF(("uplcom attach: sc = %p\n", sc));

- /* determine chip type */
- for (i = 0; uplcom_products[i].vendor != 0; i++) {
- if (uplcom_products[i].vendor uaa->vendor &&
- uplcom_products[i].product uaa->product &&
- (uplcom_products[i].release uaa->release ||
- uplcom_products[i].release 1)) {
sc->sc_chiptype = uplcom_products[i].chiptype;
- break;
- }
- }
+ dd = usbd_get_device_descriptor(uaa->device);

if (!dd)
+ goto error;

/*
- * check we found the device - attach should have ensured we
- * don't get here without matching device
+ * Determine chip type. At first we try to match known device
+ * release numbers.
/
- if (uplcom_products[i].vendor == 0) {
- kprintf("%s: didn't match\n", devname);
- ucom->sc_dying = 1;
- goto error;
- }

+ if (UGETW(dd
>bcdDevice) == CHIP_PL2303HX) {
+ sc->sc_chiptype = TYPE_PL2303X;
#ifdef USB_DEBUG
- /
print the chip type /
- if (sc->sc_chiptype TYPE_PL2303X) {
- DPRINTF(("uplcom_attach: chiptype 2303X\n"));
- } else {
- DPRINTF(("uplcom_attach: chiptype 2303\n"));
- }
+ DPRINTF(("uplcom_attach: chiptype PL-2303HX (rev D)\n"));
#endif
+ }
+ else if (UGETW(dd->bcdDevice) CHIP_PL2303X) {
+ sc->sc_chiptype = TYPE_PL2303X;
#ifdef USB_DEBUG
DPRINTF(("uplcom_attach: chiptype PL-2303X or" \
+ " PL-2303HX (rev A)\n"));
#endif
}
+ else if (UGETW(dd->bcdDevice) == CHIP_PL2303) {
+ sc->sc_chiptype = TYPE_PL2303;
#ifdef USB_DEBUG
DPRINTF(("uplcom_attach: chiptype PL-2303 (rel 2.02)\n"));
#endif
}
+ /

+ * If it doesn't work, try matching sequence Linux driver uses
+ * (device release number in chip could be replaced by the contents
+ * of external EEPROM). As I don't have access to any adequate old
+ * PL-2303 datasheet, I can't comment how bulletproof it is.
+
+ * FIXME Fix it if more info will appear.
+ */
+ else if (dd->bDeviceClass == 0x02) {
+ sc->sc_chiptype = TYPE_PL2303;
#ifdef USB_DEBUG
DPRINTF(("uplcom_attach: chiptype PL-2303\n"));
#endif
}
+ else if (dd->bMaxPacketSize == 0x40) {
+ sc->sc_chiptype = TYPE_PL2303X;
#ifdef USB_DEBUG
DPRINTF(("uplcom_attach: chiptype PL-2303(H)X\n"));
#endif
}
+ /
Fallback to PL-2303. */
+ else {
+ sc->sc_chiptype = TYPE_PL2303;
#ifdef USB_DEBUG
DPRINTF(("uplcom_attach: fallback to chiptype PL-2303\n"));
#endif
}
/* initialize endpoints */
ucom->sc_bulkin_no = ucom->sc_bulkout_no = -1;
Actions #1

Updated by hasso over 18 years ago

Commited modified version. Looking at known device release numbers turned out
to be quite useless - mots of vendors changed it.

Actions

Also available in: Atom PDF