Quellcodebibliothek Statistik Leitseite products/sources/formale Sprachen/C/Linux/drivers/usb/serial/   (Open Source Betriebssystem Version 6.17.9©)  Datei vom 24.10.2025 mit Größe 98 kB image not shown  

Quelle  ftdi_sio.c   Sprache: C

 
// SPDX-License-Identifier: GPL-2.0+
/*
 * USB FTDI SIO driver
 *
 * Copyright (C) 2009 - 2013
 *     Johan Hovold (jhovold@gmail.com)
 * Copyright (C) 1999 - 2001
 *     Greg Kroah-Hartman (greg@kroah.com)
 *          Bill Ryder (bryder@sgi.com)
 * Copyright (C) 2002
 *     Kuba Ober (kuba@mareimbrium.org)
 *
 * See Documentation/usb/usb-serial.rst for more information on using this
 * driver
 *
 * See http://ftdi-usb-sio.sourceforge.net for up to date testing info
 * and extra documentation
 *
 * Change entries from 2004 and earlier can be found in versions of this
 * file in kernel versions prior to the 2.6.24 release.
 *
 */


/* Bill Ryder - bryder@sgi.com - wrote the FTDI_SIO implementation */
/* Thanx to FTDI for so kindly providing details of the protocol required */
/*   to talk to the device */
/* Thanx to gkh and the rest of the usb dev group for all code I have
   assimilated :-) */


#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/slab.h>
#include <linux/tty.h>
#include <linux/tty_driver.h>
#include <linux/tty_flip.h>
#include <linux/module.h>
#include <linux/spinlock.h>
#include <linux/mutex.h>
#include <linux/uaccess.h>
#include <linux/usb.h>
#include <linux/serial.h>
#include <linux/gpio/driver.h>
#include <linux/usb/serial.h>
#include "ftdi_sio.h"
#include "ftdi_sio_ids.h"

#define DRIVER_AUTHOR "Greg Kroah-Hartman , Bill Ryder , Kuba Ober , Andreas Mohr, Johan Hovold "
#define DRIVER_DESC "USB FTDI Serial Converters Driver"

enum ftdi_chip_type {
 SIO,
 FT232A,
 FT232B,
 FT2232C,
 FT232R,
 FT232H,
 FT2232H,
 FT4232H,
 FT4232HA,
 FT232HP,
 FT233HP,
 FT2232HP,
 FT2233HP,
 FT4232HP,
 FT4233HP,
 FTX,
};

struct ftdi_private {
 enum ftdi_chip_type chip_type;
 int baud_base;  /* baud base clock for divisor setting */
 int custom_divisor; /* custom_divisor kludge, this is for
   baud_base (different from what goes to the
   chip!) */

 u16 last_set_data_value; /* the last data state set - needed for doing
  * a break
  */

 int flags;  /* some ASYNC_xxxx flags are supported */
 unsigned long last_dtr_rts; /* saved modem control outputs */
 char prev_status;        /* Used for TIOCMIWAIT */
 char transmit_empty; /* If transmitter is empty or not */
 u16 channel;  /* channel index, or 0 for legacy types */

 speed_t force_baud; /* if non-zero, force the baud rate to
   this value */

 int force_rtscts; /* if non-zero, force RTS-CTS to always
   be enabled */


 unsigned int latency;  /* latency setting in use */
 unsigned short max_packet_size;
 struct mutex cfg_lock; /* Avoid mess by parallel calls of config ioctl() and change_speed() */
#ifdef CONFIG_GPIOLIB
 struct gpio_chip gc;
 struct mutex gpio_lock; /* protects GPIO state */
 bool gpio_registered; /* is the gpiochip in kernel registered */
 bool gpio_used;  /* true if the user requested a gpio */
 u8 gpio_altfunc; /* which pins are in gpio mode */
 u8 gpio_output;  /* pin directions cache */
 u8 gpio_value;  /* pin value for outputs */
#endif
};

struct ftdi_quirk {
 int (*probe)(struct usb_serial *);
 /* Special settings for probed ports. */
 void (*port_probe)(struct ftdi_private *);
};

static int   ftdi_jtag_probe(struct usb_serial *serial);
static int   ftdi_NDI_device_setup(struct usb_serial *serial);
static int   ftdi_stmclite_probe(struct usb_serial *serial);
static int   ftdi_8u2232c_probe(struct usb_serial *serial);
static void  ftdi_USB_UIRT_setup(struct ftdi_private *priv);
static void  ftdi_HE_TIRA1_setup(struct ftdi_private *priv);

static const struct ftdi_quirk ftdi_jtag_quirk = {
 .probe = ftdi_jtag_probe,
};

static const struct ftdi_quirk ftdi_NDI_device_quirk = {
 .probe = ftdi_NDI_device_setup,
};

static const struct ftdi_quirk ftdi_USB_UIRT_quirk = {
 .port_probe = ftdi_USB_UIRT_setup,
};

static const struct ftdi_quirk ftdi_HE_TIRA1_quirk = {
 .port_probe = ftdi_HE_TIRA1_setup,
};

static const struct ftdi_quirk ftdi_stmclite_quirk = {
 .probe = ftdi_stmclite_probe,
};

static const struct ftdi_quirk ftdi_8u2232c_quirk = {
 .probe = ftdi_8u2232c_probe,
};

/*
 * The 8U232AM has the same API as the sio except for:
 * - it can support MUCH higher baudrates; up to:
 *   o 921600 for RS232 and 2000000 for RS422/485 at 48MHz
 *   o 230400 at 12MHz
 *   so .. 8U232AM's baudrate setting codes are different
 * - it has a two byte status code.
 * - it returns characters every 16ms (the FTDI does it every 40ms)
 *
 * the bcdDevice value is used to differentiate FT232BM and FT245BM from
 * the earlier FT8U232AM and FT8U232BM.  For now, include all known VID/PID
 * combinations in both tables.
 * FIXME: perhaps bcdDevice can also identify 12MHz FT8U232AM devices,
 * but I don't know if those ever went into mass production. [Ian Abbott]
 */




/*
 * Device ID not listed? Test it using
 * /sys/bus/usb-serial/drivers/ftdi_sio/new_id and send a patch or report.
 */

static const struct usb_device_id id_table_combined[] = {
 { USB_DEVICE(FTDI_VID, FTDI_BRICK_PID) },
 { USB_DEVICE(FTDI_VID, FTDI_ZEITCONTROL_TAGTRACE_MIFARE_PID) },
 { USB_DEVICE(FTDI_VID, FTDI_CTI_MINI_PID) },
 { USB_DEVICE(FTDI_VID, FTDI_CTI_NANO_PID) },
 { USB_DEVICE(FTDI_VID, FTDI_AMC232_PID) },
 { USB_DEVICE(FTDI_VID, FTDI_CANUSB_PID) },
 { USB_DEVICE(FTDI_VID, FTDI_CANDAPTER_PID) },
 { USB_DEVICE(FTDI_VID, FTDI_BM_ATOM_NANO_PID) },
 { USB_DEVICE(FTDI_VID, FTDI_NXTCAM_PID) },
 { USB_DEVICE(FTDI_VID, FTDI_EV3CON_PID) },
 { USB_DEVICE(FTDI_VID, FTDI_SCS_DEVICE_0_PID) },
 { USB_DEVICE(FTDI_VID, FTDI_SCS_DEVICE_1_PID) },
 { USB_DEVICE(FTDI_VID, FTDI_SCS_DEVICE_2_PID) },
 { USB_DEVICE(FTDI_VID, FTDI_SCS_DEVICE_3_PID) },
 { USB_DEVICE(FTDI_VID, FTDI_SCS_DEVICE_4_PID) },
 { USB_DEVICE(FTDI_VID, FTDI_SCS_DEVICE_5_PID) },
 { USB_DEVICE(FTDI_VID, FTDI_SCS_DEVICE_6_PID) },
 { USB_DEVICE(FTDI_VID, FTDI_SCS_DEVICE_7_PID) },
 { USB_DEVICE(FTDI_VID, FTDI_USINT_CAT_PID) },
 { USB_DEVICE(FTDI_VID, FTDI_USINT_WKEY_PID) },
 { USB_DEVICE(FTDI_VID, FTDI_USINT_RS232_PID) },
 { USB_DEVICE(FTDI_VID, FTDI_ACTZWAVE_PID) },
 { USB_DEVICE(FTDI_VID, FTDI_IRTRANS_PID) },
 { USB_DEVICE(FTDI_VID, FTDI_IPLUS_PID) },
 { USB_DEVICE(FTDI_VID, FTDI_IPLUS2_PID) },
 { USB_DEVICE(FTDI_VID, FTDI_DMX4ALL) },
 { USB_DEVICE(FTDI_VID, FTDI_SIO_PID) },
 { USB_DEVICE(FTDI_VID, FTDI_8U232AM_PID) },
 { USB_DEVICE(FTDI_VID, FTDI_8U232AM_ALT_PID) },
 { USB_DEVICE(FTDI_VID, FTDI_232RL_PID) },
 { USB_DEVICE(FTDI_VID, FTDI_8U2232C_PID) ,
  .driver_info = (kernel_ulong_t)&ftdi_8u2232c_quirk },
 { USB_DEVICE(FTDI_VID, FTDI_4232H_PID) },
 { USB_DEVICE(FTDI_VID, FTDI_232H_PID) },
 { USB_DEVICE(FTDI_VID, FTDI_FTX_PID) },
 { USB_DEVICE(FTDI_VID, FTDI_FT2233HP_PID) },
 { USB_DEVICE(FTDI_VID, FTDI_FT4233HP_PID) },
 { USB_DEVICE(FTDI_VID, FTDI_FT2232HP_PID) },
 { USB_DEVICE(FTDI_VID, FTDI_FT4232HP_PID) },
 { USB_DEVICE(FTDI_VID, FTDI_FT233HP_PID) },
 { USB_DEVICE(FTDI_VID, FTDI_FT232HP_PID) },
 { USB_DEVICE(FTDI_VID, FTDI_FT4232HA_PID) },
 { USB_DEVICE(FTDI_VID, FTDI_MICRO_CHAMELEON_PID) },
 { USB_DEVICE(FTDI_VID, FTDI_RELAIS_PID) },
 { USB_DEVICE(FTDI_VID, FTDI_OPENDCC_PID) },
 { USB_DEVICE(FTDI_VID, FTDI_OPENDCC_SNIFFER_PID) },
 { USB_DEVICE(FTDI_VID, FTDI_OPENDCC_THROTTLE_PID) },
 { USB_DEVICE(FTDI_VID, FTDI_OPENDCC_GATEWAY_PID) },
 { USB_DEVICE(FTDI_VID, FTDI_OPENDCC_GBM_PID) },
 { USB_DEVICE(FTDI_VID, FTDI_OPENDCC_GBM_BOOST_PID) },
 { USB_DEVICE(NEWPORT_VID, NEWPORT_AGILIS_PID) },
 { USB_DEVICE(NEWPORT_VID, NEWPORT_CONEX_CC_PID) },
 { USB_DEVICE(NEWPORT_VID, NEWPORT_CONEX_AGP_PID) },
 { USB_DEVICE(INTERBIOMETRICS_VID, INTERBIOMETRICS_IOBOARD_PID) },
 { USB_DEVICE(INTERBIOMETRICS_VID, INTERBIOMETRICS_MINI_IOBOARD_PID) },
 { USB_DEVICE(FTDI_VID, FTDI_SPROG_II) },
 { USB_DEVICE(FTDI_VID, FTDI_TAGSYS_LP101_PID) },
 { USB_DEVICE(FTDI_VID, FTDI_TAGSYS_P200X_PID) },
 { USB_DEVICE(FTDI_VID, FTDI_LENZ_LIUSB_PID) },
 { USB_DEVICE(FTDI_VID, FTDI_XF_632_PID) },
 { USB_DEVICE(FTDI_VID, FTDI_XF_634_PID) },
 { USB_DEVICE(FTDI_VID, FTDI_XF_547_PID) },
 { USB_DEVICE(FTDI_VID, FTDI_XF_633_PID) },
 { USB_DEVICE(FTDI_VID, FTDI_XF_631_PID) },
 { USB_DEVICE(FTDI_VID, FTDI_XF_635_PID) },
 { USB_DEVICE(FTDI_VID, FTDI_XF_640_PID) },
 { USB_DEVICE(FTDI_VID, FTDI_XF_642_PID) },
 { USB_DEVICE(FTDI_VID, FTDI_DSS20_PID) },
 { USB_DEVICE(FTDI_VID, FTDI_URBAN_0_PID) },
 { USB_DEVICE(FTDI_VID, FTDI_URBAN_1_PID) },
 { USB_DEVICE(FTDI_NF_RIC_VID, FTDI_NF_RIC_PID) },
 { USB_DEVICE(FTDI_VID, FTDI_VNHCPCUSB_D_PID) },
 { USB_DEVICE(FTDI_VID, FTDI_MTXORB_0_PID) },
 { USB_DEVICE(FTDI_VID, FTDI_MTXORB_1_PID) },
 { USB_DEVICE(FTDI_VID, FTDI_MTXORB_2_PID) },
 { USB_DEVICE(FTDI_VID, FTDI_MTXORB_3_PID) },
 { USB_DEVICE(FTDI_VID, FTDI_MTXORB_4_PID) },
 { USB_DEVICE(FTDI_VID, FTDI_MTXORB_5_PID) },
 { USB_DEVICE(FTDI_VID, FTDI_MTXORB_6_PID) },
 { USB_DEVICE(FTDI_VID, FTDI_R2000KU_TRUE_RNG) },
 { USB_DEVICE(FTDI_VID, FTDI_VARDAAN_PID) },
 { USB_DEVICE(FTDI_VID, FTDI_AUTO_M3_OP_COM_V2_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0100_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0101_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0102_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0103_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0104_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0105_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0106_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0107_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0108_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0109_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_010A_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_010B_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_010C_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_010D_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_010E_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_010F_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0110_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0111_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0112_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0113_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0114_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0115_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0116_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0117_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0118_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0119_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_011A_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_011B_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_011C_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_011D_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_011E_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_011F_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0120_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0121_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0122_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0123_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0124_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0125_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0126_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0127_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0128_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0129_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_012A_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_012B_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_012C_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_012D_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_012E_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_012F_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0130_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0131_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0132_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0133_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0134_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0135_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0136_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0137_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0138_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0139_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_013A_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_013B_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_013C_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_013D_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_013E_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_013F_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0140_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0141_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0142_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0143_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0144_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0145_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0146_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0147_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0148_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0149_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_014A_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_014B_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_014C_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_014D_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_014E_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_014F_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0150_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0151_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0152_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0153_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0154_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0155_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0156_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0157_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0158_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0159_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_015A_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_015B_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_015C_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_015D_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_015E_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_015F_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0160_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0161_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0162_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0163_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0164_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0165_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0166_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0167_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0168_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0169_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_016A_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_016B_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_016C_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_016D_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_016E_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_016F_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0170_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0171_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0172_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0173_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0174_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0175_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0176_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0177_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0178_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0179_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_017A_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_017B_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_017C_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_017D_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_017E_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_017F_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0180_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0181_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0182_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0183_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0184_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0185_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0186_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0187_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0188_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0189_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_018A_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_018B_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_018C_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_018D_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_018E_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_018F_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0190_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0191_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0192_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0193_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0194_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0195_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0196_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0197_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0198_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0199_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_019A_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_019B_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_019C_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_019D_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_019E_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_019F_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01A0_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01A1_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01A2_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01A3_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01A4_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01A5_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01A6_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01A7_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01A8_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01A9_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01AA_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01AB_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01AC_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01AD_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01AE_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01AF_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01B0_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01B1_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01B2_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01B3_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01B4_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01B5_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01B6_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01B7_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01B8_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01B9_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01BA_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01BB_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01BC_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01BD_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01BE_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01BF_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01C0_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01C1_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01C2_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01C3_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01C4_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01C5_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01C6_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01C7_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01C8_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01C9_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01CA_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01CB_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01CC_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01CD_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01CE_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01CF_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01D0_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01D1_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01D2_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01D3_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01D4_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01D5_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01D6_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01D7_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01D8_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01D9_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01DA_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01DB_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01DC_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01DD_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01DE_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01DF_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01E0_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01E1_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01E2_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01E3_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01E4_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01E5_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01E6_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01E7_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01E8_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01E9_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01EA_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01EB_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01EC_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01ED_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01EE_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01EF_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01F0_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01F1_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01F2_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01F3_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01F4_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01F5_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01F6_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01F7_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01F8_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01F9_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01FA_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01FB_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01FC_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01FD_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01FE_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01FF_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_4701_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_9300_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_9301_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_9302_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_9303_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_9304_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_9305_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_9306_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_9307_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_9308_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_9309_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_930A_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_930B_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_930C_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_930D_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_930E_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_930F_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_9310_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_9311_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_9312_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_9313_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_9314_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_9315_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_9316_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_9317_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_9318_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_9319_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_931A_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_931B_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_931C_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_931D_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_931E_PID) },
 { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_931F_PID) },
 { USB_DEVICE(FTDI_VID, FTDI_PERLE_ULTRAPORT_PID) },
 { USB_DEVICE(FTDI_VID, FTDI_PIEGROUP_PID) },
 { USB_DEVICE(FTDI_VID, FTDI_TNC_X_PID) },
 { USB_DEVICE(FTDI_VID, FTDI_USBX_707_PID) },
 { USB_DEVICE(SEALEVEL_VID, SEALEVEL_2101_PID) },
 { USB_DEVICE(SEALEVEL_VID, SEALEVEL_2102_PID) },
 { USB_DEVICE(SEALEVEL_VID, SEALEVEL_2103_PID) },
 { USB_DEVICE(SEALEVEL_VID, SEALEVEL_2104_PID) },
 { USB_DEVICE(SEALEVEL_VID, SEALEVEL_2106_PID) },
 { USB_DEVICE(SEALEVEL_VID, SEALEVEL_2201_1_PID) },
 { USB_DEVICE(SEALEVEL_VID, SEALEVEL_2201_2_PID) },
 { USB_DEVICE(SEALEVEL_VID, SEALEVEL_2202_1_PID) },
 { USB_DEVICE(SEALEVEL_VID, SEALEVEL_2202_2_PID) },
 { USB_DEVICE(SEALEVEL_VID, SEALEVEL_2203_1_PID) },
 { USB_DEVICE(SEALEVEL_VID, SEALEVEL_2203_2_PID) },
 { USB_DEVICE(SEALEVEL_VID, SEALEVEL_2401_1_PID) },
 { USB_DEVICE(SEALEVEL_VID, SEALEVEL_2401_2_PID) },
 { USB_DEVICE(SEALEVEL_VID, SEALEVEL_2401_3_PID) },
 { USB_DEVICE(SEALEVEL_VID, SEALEVEL_2401_4_PID) },
 { USB_DEVICE(SEALEVEL_VID, SEALEVEL_2402_1_PID) },
 { USB_DEVICE(SEALEVEL_VID, SEALEVEL_2402_2_PID) },
 { USB_DEVICE(SEALEVEL_VID, SEALEVEL_2402_3_PID) },
 { USB_DEVICE(SEALEVEL_VID, SEALEVEL_2402_4_PID) },
 { USB_DEVICE(SEALEVEL_VID, SEALEVEL_2403_1_PID) },
 { USB_DEVICE(SEALEVEL_VID, SEALEVEL_2403_2_PID) },
 { USB_DEVICE(SEALEVEL_VID, SEALEVEL_2403_3_PID) },
 { USB_DEVICE(SEALEVEL_VID, SEALEVEL_2403_4_PID) },
 { USB_DEVICE(SEALEVEL_VID, SEALEVEL_2801_1_PID) },
 { USB_DEVICE(SEALEVEL_VID, SEALEVEL_2801_2_PID) },
 { USB_DEVICE(SEALEVEL_VID, SEALEVEL_2801_3_PID) },
 { USB_DEVICE(SEALEVEL_VID, SEALEVEL_2801_4_PID) },
 { USB_DEVICE(SEALEVEL_VID, SEALEVEL_2801_5_PID) },
 { USB_DEVICE(SEALEVEL_VID, SEALEVEL_2801_6_PID) },
 { USB_DEVICE(SEALEVEL_VID, SEALEVEL_2801_7_PID) },
 { USB_DEVICE(SEALEVEL_VID, SEALEVEL_2801_8_PID) },
 { USB_DEVICE(SEALEVEL_VID, SEALEVEL_2802_1_PID) },
 { USB_DEVICE(SEALEVEL_VID, SEALEVEL_2802_2_PID) },
 { USB_DEVICE(SEALEVEL_VID, SEALEVEL_2802_3_PID) },
 { USB_DEVICE(SEALEVEL_VID, SEALEVEL_2802_4_PID) },
 { USB_DEVICE(SEALEVEL_VID, SEALEVEL_2802_5_PID) },
 { USB_DEVICE(SEALEVEL_VID, SEALEVEL_2802_6_PID) },
 { USB_DEVICE(SEALEVEL_VID, SEALEVEL_2802_7_PID) },
 { USB_DEVICE(SEALEVEL_VID, SEALEVEL_2802_8_PID) },
 { USB_DEVICE(SEALEVEL_VID, SEALEVEL_2803_1_PID) },
 { USB_DEVICE(SEALEVEL_VID, SEALEVEL_2803_2_PID) },
 { USB_DEVICE(SEALEVEL_VID, SEALEVEL_2803_3_PID) },
 { USB_DEVICE(SEALEVEL_VID, SEALEVEL_2803_4_PID) },
 { USB_DEVICE(SEALEVEL_VID, SEALEVEL_2803_5_PID) },
 { USB_DEVICE(SEALEVEL_VID, SEALEVEL_2803_6_PID) },
 { USB_DEVICE(SEALEVEL_VID, SEALEVEL_2803_7_PID) },
 { USB_DEVICE(SEALEVEL_VID, SEALEVEL_2803_8_PID) },
 { USB_DEVICE(SEALEVEL_VID, SEALEVEL_2803R_1_PID) },
 { USB_DEVICE(SEALEVEL_VID, SEALEVEL_2803R_2_PID) },
 { USB_DEVICE(SEALEVEL_VID, SEALEVEL_2803R_3_PID) },
 { USB_DEVICE(SEALEVEL_VID, SEALEVEL_2803R_4_PID) },
 { USB_DEVICE(IDTECH_VID, IDTECH_IDT1221U_PID) },
 { USB_DEVICE(OCT_VID, OCT_US101_PID) },
 { USB_DEVICE(OCT_VID, OCT_DK201_PID) },
 { USB_DEVICE(FTDI_VID, FTDI_HE_TIRA1_PID),
  .driver_info = (kernel_ulong_t)&ftdi_HE_TIRA1_quirk },
 { USB_DEVICE(FTDI_VID, FTDI_USB_UIRT_PID),
  .driver_info = (kernel_ulong_t)&ftdi_USB_UIRT_quirk },
 { USB_DEVICE(FTDI_VID, PROTEGO_SPECIAL_1) },
 { USB_DEVICE(FTDI_VID, PROTEGO_R2X0) },
 { USB_DEVICE(FTDI_VID, PROTEGO_SPECIAL_3) },
 { USB_DEVICE(FTDI_VID, PROTEGO_SPECIAL_4) },
 { USB_DEVICE(FTDI_VID, FTDI_GUDEADS_E808_PID) },
 { USB_DEVICE(FTDI_VID, FTDI_GUDEADS_E809_PID) },
 { USB_DEVICE(FTDI_VID, FTDI_GUDEADS_E80A_PID) },
 { USB_DEVICE(FTDI_VID, FTDI_GUDEADS_E80B_PID) },
 { USB_DEVICE(FTDI_VID, FTDI_GUDEADS_E80C_PID) },
 { USB_DEVICE(FTDI_VID, FTDI_GUDEADS_E80D_PID) },
 { USB_DEVICE(FTDI_VID, FTDI_GUDEADS_E80E_PID) },
 { USB_DEVICE(FTDI_VID, FTDI_GUDEADS_E80F_PID) },
 { USB_DEVICE(FTDI_VID, FTDI_GUDEADS_E888_PID) },
 { USB_DEVICE(FTDI_VID, FTDI_GUDEADS_E889_PID) },
 { USB_DEVICE(FTDI_VID, FTDI_GUDEADS_E88A_PID) },
 { USB_DEVICE(FTDI_VID, FTDI_GUDEADS_E88B_PID) },
 { USB_DEVICE(FTDI_VID, FTDI_GUDEADS_E88C_PID) },
 { USB_DEVICE(FTDI_VID, FTDI_GUDEADS_E88D_PID) },
 { USB_DEVICE(FTDI_VID, FTDI_GUDEADS_E88E_PID) },
 { USB_DEVICE(FTDI_VID, FTDI_GUDEADS_E88F_PID) },
 { USB_DEVICE(FTDI_VID, FTDI_ELV_UO100_PID) },
 { USB_DEVICE(FTDI_VID, FTDI_ELV_UM100_PID) },
 { USB_DEVICE(FTDI_VID, FTDI_ELV_UR100_PID) },
 { USB_DEVICE(FTDI_VID, FTDI_ELV_ALC8500_PID) },
 { USB_DEVICE(FTDI_VID, FTDI_PYRAMID_PID) },
 { USB_DEVICE(FTDI_VID, FTDI_ELV_FHZ1000PC_PID) },
 { USB_DEVICE(FTDI_VID, FTDI_IBS_US485_PID) },
 { USB_DEVICE(FTDI_VID, FTDI_IBS_PICPRO_PID) },
 { USB_DEVICE(FTDI_VID, FTDI_IBS_PCMCIA_PID) },
 { USB_DEVICE(FTDI_VID, FTDI_IBS_PK1_PID) },
 { USB_DEVICE(FTDI_VID, FTDI_IBS_RS232MON_PID) },
 { USB_DEVICE(FTDI_VID, FTDI_IBS_APP70_PID) },
 { USB_DEVICE(FTDI_VID, FTDI_IBS_PEDO_PID) },
 { USB_DEVICE(FTDI_VID, FTDI_IBS_PROD_PID) },
 { USB_DEVICE(FTDI_VID, FTDI_TAVIR_STK500_PID) },
 { USB_DEVICE(FTDI_VID, FTDI_TIAO_UMPA_PID),
  .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk },
 { USB_DEVICE(FTDI_VID, FTDI_NT_ORIONLXM_PID),
  .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk },
 { USB_DEVICE(FTDI_VID, FTDI_NT_ORIONLX_PLUS_PID) },
 { USB_DEVICE(FTDI_VID, FTDI_NT_ORION_IO_PID) },
 { USB_DEVICE(FTDI_VID, FTDI_NT_ORIONMX_PID) },
 { USB_DEVICE(FTDI_VID, FTDI_SYNAPSE_SS200_PID) },
 { USB_DEVICE(FTDI_VID, FTDI_CUSTOMWARE_MINIPLEX_PID) },
 { USB_DEVICE(FTDI_VID, FTDI_CUSTOMWARE_MINIPLEX2_PID) },
 { USB_DEVICE(FTDI_VID, FTDI_CUSTOMWARE_MINIPLEX2WI_PID) },
 { USB_DEVICE(FTDI_VID, FTDI_CUSTOMWARE_MINIPLEX3_PID) },
 /*
 * ELV devices:
 */

 { USB_DEVICE(FTDI_ELV_VID, FTDI_ELV_WS300_PID) },
 { USB_DEVICE(FTDI_VID, FTDI_ELV_USR_PID) },
 { USB_DEVICE(FTDI_VID, FTDI_ELV_MSM1_PID) },
 { USB_DEVICE(FTDI_VID, FTDI_ELV_KL100_PID) },
 { USB_DEVICE(FTDI_VID, FTDI_ELV_WS550_PID) },
 { USB_DEVICE(FTDI_VID, FTDI_ELV_EC3000_PID) },
 { USB_DEVICE(FTDI_VID, FTDI_ELV_WS888_PID) },
 { USB_DEVICE(FTDI_VID, FTDI_ELV_TWS550_PID) },
 { USB_DEVICE(FTDI_VID, FTDI_ELV_FEM_PID) },
 { USB_DEVICE(FTDI_VID, FTDI_ELV_CLI7000_PID) },
 { USB_DEVICE(FTDI_VID, FTDI_ELV_PPS7330_PID) },
 { USB_DEVICE(FTDI_VID, FTDI_ELV_TFM100_PID) },
 { USB_DEVICE(FTDI_VID, FTDI_ELV_UDF77_PID) },
 { USB_DEVICE(FTDI_VID, FTDI_ELV_UIO88_PID) },
 { USB_DEVICE(FTDI_VID, FTDI_ELV_UAD8_PID) },
 { USB_DEVICE(FTDI_VID, FTDI_ELV_UDA7_PID) },
 { USB_DEVICE(FTDI_VID, FTDI_ELV_USI2_PID) },
 { USB_DEVICE(FTDI_VID, FTDI_ELV_T1100_PID) },
 { USB_DEVICE(FTDI_VID, FTDI_ELV_PCD200_PID) },
 { USB_DEVICE(FTDI_VID, FTDI_ELV_ULA200_PID) },
 { USB_DEVICE(FTDI_VID, FTDI_ELV_CSI8_PID) },
 { USB_DEVICE(FTDI_VID, FTDI_ELV_EM1000DL_PID) },
 { USB_DEVICE(FTDI_VID, FTDI_ELV_PCK100_PID) },
 { USB_DEVICE(FTDI_VID, FTDI_ELV_RFP500_PID) },
 { USB_DEVICE(FTDI_VID, FTDI_ELV_FS20SIG_PID) },
 { USB_DEVICE(FTDI_VID, FTDI_ELV_UTP8_PID) },
 { USB_DEVICE(FTDI_VID, FTDI_ELV_WS300PC_PID) },
 { USB_DEVICE(FTDI_VID, FTDI_ELV_WS444PC_PID) },
 { USB_DEVICE(FTDI_VID, FTDI_ELV_FHZ1300PC_PID) },
 { USB_DEVICE(FTDI_VID, FTDI_ELV_EM1010PC_PID) },
 { USB_DEVICE(FTDI_VID, FTDI_ELV_WS500_PID) },
 { USB_DEVICE(FTDI_VID, FTDI_ELV_HS485_PID) },
 { USB_DEVICE(FTDI_VID, FTDI_ELV_UMS100_PID) },
 { USB_DEVICE(FTDI_VID, FTDI_ELV_TFD128_PID) },
 { USB_DEVICE(FTDI_VID, FTDI_ELV_FM3RX_PID) },
 { USB_DEVICE(FTDI_VID, FTDI_ELV_WS777_PID) },
 { USB_DEVICE(FTDI_VID, FTDI_PALMSENS_PID) },
 { USB_DEVICE(FTDI_VID, FTDI_IVIUM_XSTAT_PID) },
 { USB_DEVICE(FTDI_VID, LINX_SDMUSBQSS_PID) },
 { USB_DEVICE(FTDI_VID, LINX_MASTERDEVEL2_PID) },
 { USB_DEVICE(FTDI_VID, LINX_FUTURE_0_PID) },
 { USB_DEVICE(FTDI_VID, LINX_FUTURE_1_PID) },
 { USB_DEVICE(FTDI_VID, LINX_FUTURE_2_PID) },
 { USB_DEVICE(FTDI_VID, FTDI_CCSICDU20_0_PID) },
 { USB_DEVICE(FTDI_VID, FTDI_CCSICDU40_1_PID) },
 { USB_DEVICE(FTDI_VID, FTDI_CCSMACHX_2_PID) },
 { USB_DEVICE(FTDI_VID, FTDI_CCSLOAD_N_GO_3_PID) },
 { USB_DEVICE(FTDI_VID, FTDI_CCSICDU64_4_PID) },
 { USB_DEVICE(FTDI_VID, FTDI_CCSPRIME8_5_PID) },
 { USB_DEVICE(FTDI_VID, INSIDE_ACCESSO) },
 { USB_DEVICE(INTREPID_VID, INTREPID_VALUECAN_PID) },
 { USB_DEVICE(INTREPID_VID, INTREPID_NEOVI_PID) },
 { USB_DEVICE(FALCOM_VID, FALCOM_TWIST_PID) },
 { USB_DEVICE(FALCOM_VID, FALCOM_SAMBA_PID) },
 { USB_DEVICE(FTDI_VID, FTDI_SUUNTO_SPORTS_PID) },
 { USB_DEVICE(FTDI_VID, FTDI_OCEANIC_PID) },
 { USB_DEVICE(TTI_VID, TTI_QL355P_PID) },
 { USB_DEVICE(FTDI_VID, FTDI_RM_CANVIEW_PID) },
 { USB_DEVICE(ACTON_VID, ACTON_SPECTRAPRO_PID) },
 { USB_DEVICE(CONTEC_VID, CONTEC_COM1USBH_PID) },
 { USB_DEVICE(MITSUBISHI_VID, MITSUBISHI_FXUSB_PID) },
 { USB_DEVICE(BANDB_VID, BANDB_USOTL4_PID) },
 { USB_DEVICE(BANDB_VID, BANDB_USTL4_PID) },
 { USB_DEVICE(BANDB_VID, BANDB_USO9ML2_PID) },
 { USB_DEVICE(BANDB_VID, BANDB_USOPTL4_PID) },
 { USB_DEVICE(BANDB_VID, BANDB_USPTL4_PID) },
 { USB_DEVICE(BANDB_VID, BANDB_USO9ML2DR_2_PID) },
 { USB_DEVICE(BANDB_VID, BANDB_USO9ML2DR_PID) },
 { USB_DEVICE(BANDB_VID, BANDB_USOPTL4DR2_PID) },
 { USB_DEVICE(BANDB_VID, BANDB_USOPTL4DR_PID) },
 { USB_DEVICE(BANDB_VID, BANDB_485USB9F_2W_PID) },
 { USB_DEVICE(BANDB_VID, BANDB_485USB9F_4W_PID) },
 { USB_DEVICE(BANDB_VID, BANDB_232USB9M_PID) },
 { USB_DEVICE(BANDB_VID, BANDB_485USBTB_2W_PID) },
 { USB_DEVICE(BANDB_VID, BANDB_485USBTB_4W_PID) },
 { USB_DEVICE(BANDB_VID, BANDB_TTL5USB9M_PID) },
 { USB_DEVICE(BANDB_VID, BANDB_TTL3USB9M_PID) },
 { USB_DEVICE(BANDB_VID, BANDB_ZZ_PROG1_USB_PID) },
 { USB_DEVICE(FTDI_VID, EVER_ECO_PRO_CDS) },
 { USB_DEVICE(FTDI_VID, FTDI_4N_GALAXY_DE_1_PID) },
 { USB_DEVICE(FTDI_VID, FTDI_4N_GALAXY_DE_2_PID) },
 { USB_DEVICE(FTDI_VID, FTDI_4N_GALAXY_DE_3_PID) },
 { USB_DEVICE(FTDI_VID, XSENS_CONVERTER_0_PID) },
 { USB_DEVICE(FTDI_VID, XSENS_CONVERTER_1_PID) },
 { USB_DEVICE(FTDI_VID, XSENS_CONVERTER_2_PID) },
 { USB_DEVICE(FTDI_VID, XSENS_CONVERTER_3_PID) },
 { USB_DEVICE(FTDI_VID, XSENS_CONVERTER_4_PID) },
 { USB_DEVICE(FTDI_VID, XSENS_CONVERTER_5_PID) },
 { USB_DEVICE(FTDI_VID, XSENS_CONVERTER_6_PID) },
 { USB_DEVICE(FTDI_VID, XSENS_CONVERTER_7_PID) },
 { USB_DEVICE(XSENS_VID, XSENS_AWINDA_DONGLE_PID) },
 { USB_DEVICE(XSENS_VID, XSENS_AWINDA_STATION_PID) },
 { USB_DEVICE(XSENS_VID, XSENS_CONVERTER_PID) },
 { USB_DEVICE(XSENS_VID, XSENS_MTDEVBOARD_PID) },
 { USB_DEVICE(XSENS_VID, XSENS_MTIUSBCONVERTER_PID) },
 { USB_DEVICE(XSENS_VID, XSENS_MTW_PID) },
 { USB_DEVICE(FTDI_VID, FTDI_OMNI1509) },
 { USB_DEVICE(MOBILITY_VID, MOBILITY_USB_SERIAL_PID) },
 { USB_DEVICE(FTDI_VID, FTDI_ACTIVE_ROBOTS_PID) },
 { USB_DEVICE(FTDI_VID, FTDI_MHAM_KW_PID) },
 { USB_DEVICE(FTDI_VID, FTDI_MHAM_YS_PID) },
 { USB_DEVICE(FTDI_VID, FTDI_MHAM_Y6_PID) },
 { USB_DEVICE(FTDI_VID, FTDI_MHAM_Y8_PID) },
 { USB_DEVICE(FTDI_VID, FTDI_MHAM_IC_PID) },
 { USB_DEVICE(FTDI_VID, FTDI_MHAM_DB9_PID) },
 { USB_DEVICE(FTDI_VID, FTDI_MHAM_RS232_PID) },
 { USB_DEVICE(FTDI_VID, FTDI_MHAM_Y9_PID) },
 { USB_DEVICE(FTDI_VID, FTDI_TERATRONIK_VCP_PID) },
 { USB_DEVICE(FTDI_VID, FTDI_TERATRONIK_D2XX_PID) },
 { USB_DEVICE(EVOLUTION_VID, EVOLUTION_ER1_PID) },
 { USB_DEVICE(EVOLUTION_VID, EVO_HYBRID_PID) },
 { USB_DEVICE(EVOLUTION_VID, EVO_RCM4_PID) },
 { USB_DEVICE(FTDI_VID, FTDI_ARTEMIS_PID) },
 { USB_DEVICE(FTDI_VID, FTDI_ATIK_ATK16_PID) },
 { USB_DEVICE(FTDI_VID, FTDI_ATIK_ATK16C_PID) },
 { USB_DEVICE(FTDI_VID, FTDI_ATIK_ATK16HR_PID) },
 { USB_DEVICE(FTDI_VID, FTDI_ATIK_ATK16HRC_PID) },
 { USB_DEVICE(FTDI_VID, FTDI_ATIK_ATK16IC_PID) },
 { USB_DEVICE(KOBIL_VID, KOBIL_CONV_B1_PID) },
 { USB_DEVICE(KOBIL_VID, KOBIL_CONV_KAAN_PID) },
 { USB_DEVICE(POSIFLEX_VID, POSIFLEX_PP7000_PID) },
 { USB_DEVICE(FTDI_VID, FTDI_TTUSB_PID) },
 { USB_DEVICE(FTDI_VID, FTDI_ECLO_COM_1WIRE_PID) },
 { USB_DEVICE(FTDI_VID, FTDI_WESTREX_MODEL_777_PID) },
 { USB_DEVICE(FTDI_VID, FTDI_WESTREX_MODEL_8900F_PID) },
 { USB_DEVICE(FTDI_VID, FTDI_PCDJ_DAC2_PID) },
 { USB_DEVICE(FTDI_VID, FTDI_RRCIRKITS_LOCOBUFFER_PID) },
 { USB_DEVICE(FTDI_VID, FTDI_ASK_RDR400_PID) },
 { USB_DEVICE(FTDI_VID, FTDI_NZR_SEM_USB_PID) },
 { USB_DEVICE(ICOM_VID, ICOM_ID_1_PID) },
 { USB_DEVICE(ICOM_VID, ICOM_OPC_U_UC_PID) },
 { USB_DEVICE(ICOM_VID, ICOM_ID_RP2C1_PID) },
 { USB_DEVICE(ICOM_VID, ICOM_ID_RP2C2_PID) },
 { USB_DEVICE(ICOM_VID, ICOM_ID_RP2D_PID) },
 { USB_DEVICE(ICOM_VID, ICOM_ID_RP2VT_PID) },
 { USB_DEVICE(ICOM_VID, ICOM_ID_RP2VR_PID) },
 { USB_DEVICE(ICOM_VID, ICOM_ID_RP4KVT_PID) },
 { USB_DEVICE(ICOM_VID, ICOM_ID_RP4KVR_PID) },
 { USB_DEVICE(ICOM_VID, ICOM_ID_RP2KVT_PID) },
 { USB_DEVICE(ICOM_VID, ICOM_ID_RP2KVR_PID) },
 { USB_DEVICE(FTDI_VID, FTDI_ACG_HFDUAL_PID) },
 { USB_DEVICE(FTDI_VID, FTDI_YEI_SERVOCENTER31_PID) },
 { USB_DEVICE(FTDI_VID, FTDI_THORLABS_PID) },
 { USB_DEVICE(TESTO_VID, TESTO_1_PID) },
 { USB_DEVICE(TESTO_VID, TESTO_3_PID) },
 { USB_DEVICE(FTDI_VID, FTDI_GAMMA_SCOUT_PID) },
 { USB_DEVICE(FTDI_VID, FTDI_TACTRIX_OPENPORT_13M_PID) },
 { USB_DEVICE(FTDI_VID, FTDI_TACTRIX_OPENPORT_13S_PID) },
 { USB_DEVICE(FTDI_VID, FTDI_TACTRIX_OPENPORT_13U_PID) },
 { USB_DEVICE(ELEKTOR_VID, ELEKTOR_FT323R_PID) },
 { USB_DEVICE(FTDI_VID, FTDI_NDI_HUC_PID),
  .driver_info = (kernel_ulong_t)&ftdi_NDI_device_quirk },
 { USB_DEVICE(FTDI_VID, FTDI_NDI_SPECTRA_SCU_PID),
  .driver_info = (kernel_ulong_t)&ftdi_NDI_device_quirk },
 { USB_DEVICE(FTDI_VID, FTDI_NDI_FUTURE_2_PID),
  .driver_info = (kernel_ulong_t)&ftdi_NDI_device_quirk },
 { USB_DEVICE(FTDI_VID, FTDI_NDI_FUTURE_3_PID),
  .driver_info = (kernel_ulong_t)&ftdi_NDI_device_quirk },
 { USB_DEVICE(FTDI_VID, FTDI_NDI_AURORA_SCU_PID),
  .driver_info = (kernel_ulong_t)&ftdi_NDI_device_quirk },
 { USB_DEVICE(FTDI_NDI_VID, FTDI_NDI_EMGUIDE_GEMINI_PID),
  .driver_info = (kernel_ulong_t)&ftdi_NDI_device_quirk },
 { USB_DEVICE(TELLDUS_VID, TELLDUS_TELLSTICK_PID) },
 { USB_DEVICE(NOVITUS_VID, NOVITUS_BONO_E_PID) },
 { USB_DEVICE(FTDI_VID, RTSYSTEMS_USB_VX8_PID) },
 { USB_DEVICE(RTSYSTEMS_VID, RTSYSTEMS_USB_S03_PID) },
 { USB_DEVICE(RTSYSTEMS_VID, RTSYSTEMS_USB_59_PID) },
 { USB_DEVICE(RTSYSTEMS_VID, RTSYSTEMS_USB_57A_PID) },
 { USB_DEVICE(RTSYSTEMS_VID, RTSYSTEMS_USB_57B_PID) },
 { USB_DEVICE(RTSYSTEMS_VID, RTSYSTEMS_USB_29A_PID) },
 { USB_DEVICE(RTSYSTEMS_VID, RTSYSTEMS_USB_29B_PID) },
 { USB_DEVICE(RTSYSTEMS_VID, RTSYSTEMS_USB_29F_PID) },
 { USB_DEVICE(RTSYSTEMS_VID, RTSYSTEMS_USB_62B_PID) },
 { USB_DEVICE(RTSYSTEMS_VID, RTSYSTEMS_USB_S01_PID) },
 { USB_DEVICE(RTSYSTEMS_VID, RTSYSTEMS_USB_63_PID) },
 { USB_DEVICE(RTSYSTEMS_VID, RTSYSTEMS_USB_29C_PID) },
 { USB_DEVICE(RTSYSTEMS_VID, RTSYSTEMS_USB_81B_PID) },
 { USB_DEVICE(RTSYSTEMS_VID, RTSYSTEMS_USB_82B_PID) },
 { USB_DEVICE(RTSYSTEMS_VID, RTSYSTEMS_USB_K5D_PID) },
 { USB_DEVICE(RTSYSTEMS_VID, RTSYSTEMS_USB_K4Y_PID) },
 { USB_DEVICE(RTSYSTEMS_VID, RTSYSTEMS_USB_K5G_PID) },
 { USB_DEVICE(RTSYSTEMS_VID, RTSYSTEMS_USB_S05_PID) },
 { USB_DEVICE(RTSYSTEMS_VID, RTSYSTEMS_USB_60_PID) },
 { USB_DEVICE(RTSYSTEMS_VID, RTSYSTEMS_USB_61_PID) },
 { USB_DEVICE(RTSYSTEMS_VID, RTSYSTEMS_USB_62_PID) },
 { USB_DEVICE(RTSYSTEMS_VID, RTSYSTEMS_USB_63B_PID) },
 { USB_DEVICE(RTSYSTEMS_VID, RTSYSTEMS_USB_64_PID) },
 { USB_DEVICE(RTSYSTEMS_VID, RTSYSTEMS_USB_65_PID) },
 { USB_DEVICE(RTSYSTEMS_VID, RTSYSTEMS_USB_92_PID) },
 { USB_DEVICE(RTSYSTEMS_VID, RTSYSTEMS_USB_92D_PID) },
 { USB_DEVICE(RTSYSTEMS_VID, RTSYSTEMS_USB_W5R_PID) },
 { USB_DEVICE(RTSYSTEMS_VID, RTSYSTEMS_USB_A5R_PID) },
 { USB_DEVICE(RTSYSTEMS_VID, RTSYSTEMS_USB_PW1_PID) },
 { USB_DEVICE(FTDI_VID, FTDI_MAXSTREAM_PID) },
 { USB_DEVICE(FTDI_VID, FTDI_PHI_FISCO_PID) },
 { USB_DEVICE(TML_VID, TML_USB_SERIAL_PID) },
 { USB_DEVICE(FTDI_VID, FTDI_ELSTER_UNICOM_PID) },
 { USB_DEVICE(FTDI_VID, FTDI_PROPOX_JTAGCABLEII_PID) },
 { USB_DEVICE(FTDI_VID, FTDI_PROPOX_ISPCABLEIII_PID) },
 { USB_DEVICE(FTDI_VID, CYBER_CORTEX_AV_PID),
  .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk },
 { USB_DEVICE_INTERFACE_NUMBER(OLIMEX_VID, OLIMEX_ARM_USB_OCD_PID, 1) },
 { USB_DEVICE_INTERFACE_NUMBER(OLIMEX_VID, OLIMEX_ARM_USB_OCD_H_PID, 1) },
 { USB_DEVICE_INTERFACE_NUMBER(OLIMEX_VID, OLIMEX_ARM_USB_TINY_PID, 1) },
 { USB_DEVICE_INTERFACE_NUMBER(OLIMEX_VID, OLIMEX_ARM_USB_TINY_H_PID, 1) },
 { USB_DEVICE(FIC_VID, FIC_NEO1973_DEBUG_PID),
  .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk },
 { USB_DEVICE(FTDI_VID, FTDI_OOCDLINK_PID),
  .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk },
 { USB_DEVICE(FTDI_VID, LMI_LM3S_DEVEL_BOARD_PID),
  .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk },
 { USB_DEVICE(FTDI_VID, LMI_LM3S_EVAL_BOARD_PID),
  .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk },
 { USB_DEVICE(FTDI_VID, LMI_LM3S_ICDI_BOARD_PID),
  .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk },
 { USB_DEVICE(FTDI_VID, FTDI_TURTELIZER_PID),
  .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk },
 { USB_DEVICE(RATOC_VENDOR_ID, RATOC_PRODUCT_ID_USB60F) },
 { USB_DEVICE(RATOC_VENDOR_ID, RATOC_PRODUCT_ID_SCU18) },
 { USB_DEVICE(FTDI_VID, FTDI_REU_TINY_PID) },

 /* Papouch devices based on FTDI chip */
 { USB_DEVICE(PAPOUCH_VID, PAPOUCH_SB485_PID) },
 { USB_DEVICE(PAPOUCH_VID, PAPOUCH_AP485_PID) },
 { USB_DEVICE(PAPOUCH_VID, PAPOUCH_SB422_PID) },
 { USB_DEVICE(PAPOUCH_VID, PAPOUCH_SB485_2_PID) },
 { USB_DEVICE(PAPOUCH_VID, PAPOUCH_AP485_2_PID) },
 { USB_DEVICE(PAPOUCH_VID, PAPOUCH_SB422_2_PID) },
 { USB_DEVICE(PAPOUCH_VID, PAPOUCH_SB485S_PID) },
 { USB_DEVICE(PAPOUCH_VID, PAPOUCH_SB485C_PID) },
 { USB_DEVICE(PAPOUCH_VID, PAPOUCH_LEC_PID) },
 { USB_DEVICE(PAPOUCH_VID, PAPOUCH_SB232_PID) },
 { USB_DEVICE(PAPOUCH_VID, PAPOUCH_TMU_PID) },
 { USB_DEVICE(PAPOUCH_VID, PAPOUCH_IRAMP_PID) },
 { USB_DEVICE(PAPOUCH_VID, PAPOUCH_DRAK5_PID) },
 { USB_DEVICE(PAPOUCH_VID, PAPOUCH_QUIDO8x8_PID) },
 { USB_DEVICE(PAPOUCH_VID, PAPOUCH_QUIDO4x4_PID) },
 { USB_DEVICE(PAPOUCH_VID, PAPOUCH_QUIDO2x2_PID) },
 { USB_DEVICE(PAPOUCH_VID, PAPOUCH_QUIDO10x1_PID) },
 { USB_DEVICE(PAPOUCH_VID, PAPOUCH_QUIDO30x3_PID) },
 { USB_DEVICE(PAPOUCH_VID, PAPOUCH_QUIDO60x3_PID) },
 { USB_DEVICE(PAPOUCH_VID, PAPOUCH_QUIDO2x16_PID) },
 { USB_DEVICE(PAPOUCH_VID, PAPOUCH_QUIDO3x32_PID) },
 { USB_DEVICE(PAPOUCH_VID, PAPOUCH_DRAK6_PID) },
 { USB_DEVICE(PAPOUCH_VID, PAPOUCH_UPSUSB_PID) },
 { USB_DEVICE(PAPOUCH_VID, PAPOUCH_MU_PID) },
 { USB_DEVICE(PAPOUCH_VID, PAPOUCH_SIMUKEY_PID) },
 { USB_DEVICE(PAPOUCH_VID, PAPOUCH_AD4USB_PID) },
 { USB_DEVICE(PAPOUCH_VID, PAPOUCH_GMUX_PID) },
 { USB_DEVICE(PAPOUCH_VID, PAPOUCH_GMSR_PID) },

 { USB_DEVICE(FTDI_VID, FTDI_DOMINTELL_DGQG_PID) },
 { USB_DEVICE(FTDI_VID, FTDI_DOMINTELL_DUSB_PID) },
 { USB_DEVICE(ALTI2_VID, ALTI2_N3_PID) },
 { USB_DEVICE(FTDI_VID, DIEBOLD_BCS_SE923_PID) },
 { USB_DEVICE(ATMEL_VID, STK541_PID) },
 { USB_DEVICE(DE_VID, STB_PID) },
 { USB_DEVICE(DE_VID, WHT_PID) },
 { USB_DEVICE(ADI_VID, ADI_GNICE_PID),
  .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk },
 { USB_DEVICE(ADI_VID, ADI_GNICEPLUS_PID),
  .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk },
 { USB_DEVICE_AND_INTERFACE_INFO(MICROCHIP_VID, MICROCHIP_USB_BOARD_PID,
     USB_CLASS_VENDOR_SPEC,
     USB_SUBCLASS_VENDOR_SPEC, 0x00) },
 { USB_DEVICE_INTERFACE_NUMBER(ACTEL_VID, MICROSEMI_ARROW_SF2PLUS_BOARD_PID, 2) },
 { USB_DEVICE(JETI_VID, JETI_SPC1201_PID) },
 { USB_DEVICE(MARVELL_VID, MARVELL_SHEEVAPLUG_PID),
  .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk },
 { USB_DEVICE(LARSENBRUSGAARD_VID, LB_ALTITRACK_PID) },
 { USB_DEVICE(GN_OTOMETRICS_VID, AURICAL_USB_PID) },
 { USB_DEVICE(FTDI_VID, PI_C865_PID) },
 { USB_DEVICE(FTDI_VID, PI_C857_PID) },
 { USB_DEVICE(PI_VID, PI_C866_PID) },
 { USB_DEVICE(PI_VID, PI_C663_PID) },
 { USB_DEVICE(PI_VID, PI_C725_PID) },
 { USB_DEVICE(PI_VID, PI_E517_PID) },
 { USB_DEVICE(PI_VID, PI_C863_PID) },
 { USB_DEVICE(PI_VID, PI_E861_PID) },
 { USB_DEVICE(PI_VID, PI_C867_PID) },
 { USB_DEVICE(PI_VID, PI_E609_PID) },
 { USB_DEVICE(PI_VID, PI_E709_PID) },
 { USB_DEVICE(PI_VID, PI_100F_PID) },
 { USB_DEVICE(PI_VID, PI_1011_PID) },
 { USB_DEVICE(PI_VID, PI_1012_PID) },
 { USB_DEVICE(PI_VID, PI_1013_PID) },
 { USB_DEVICE(PI_VID, PI_1014_PID) },
 { USB_DEVICE(PI_VID, PI_1015_PID) },
 { USB_DEVICE(PI_VID, PI_1016_PID) },
 { USB_DEVICE(KONDO_VID, KONDO_USB_SERIAL_PID) },
 { USB_DEVICE(BAYER_VID, BAYER_CONTOUR_CABLE_PID) },
 { USB_DEVICE(FTDI_VID, MARVELL_OPENRD_PID),
  .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk },
 { USB_DEVICE(FTDI_VID, TI_XDS100V2_PID),
  .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk },
 { USB_DEVICE(FTDI_VID, HAMEG_HO820_PID) },
 { USB_DEVICE(FTDI_VID, HAMEG_HO720_PID) },
 { USB_DEVICE(FTDI_VID, HAMEG_HO730_PID) },
 { USB_DEVICE(FTDI_VID, HAMEG_HO870_PID) },
 { USB_DEVICE(FTDI_VID, MJSG_GENERIC_PID) },
 { USB_DEVICE(FTDI_VID, MJSG_SR_RADIO_PID) },
 { USB_DEVICE(FTDI_VID, MJSG_HD_RADIO_PID) },
 { USB_DEVICE(FTDI_VID, MJSG_XM_RADIO_PID) },
 { USB_DEVICE(FTDI_VID, XVERVE_SIGNALYZER_ST_PID),
  .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk },
 { USB_DEVICE(FTDI_VID, XVERVE_SIGNALYZER_SLITE_PID),
  .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk },
 { USB_DEVICE(FTDI_VID, XVERVE_SIGNALYZER_SH2_PID),
  .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk },
 { USB_DEVICE(FTDI_VID, XVERVE_SIGNALYZER_SH4_PID),
  .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk },
 { USB_DEVICE(FTDI_VID, SEGWAY_RMP200_PID) },
 { USB_DEVICE(FTDI_VID, ACCESIO_COM4SM_PID) },
 { USB_DEVICE(IONICS_VID, IONICS_PLUGCOMPUTER_PID),
  .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk },
 { USB_DEVICE(FTDI_VID, FTDI_CHAMSYS_24_MASTER_WING_PID) },
 { USB_DEVICE(FTDI_VID, FTDI_CHAMSYS_PC_WING_PID) },
 { USB_DEVICE(FTDI_VID, FTDI_CHAMSYS_USB_DMX_PID) },
 { USB_DEVICE(FTDI_VID, FTDI_CHAMSYS_MIDI_TIMECODE_PID) },
 { USB_DEVICE(FTDI_VID, FTDI_CHAMSYS_MINI_WING_PID) },
 { USB_DEVICE(FTDI_VID, FTDI_CHAMSYS_MAXI_WING_PID) },
 { USB_DEVICE(FTDI_VID, FTDI_CHAMSYS_MEDIA_WING_PID) },
 { USB_DEVICE(FTDI_VID, FTDI_CHAMSYS_WING_PID) },
 { USB_DEVICE(FTDI_VID, FTDI_SCIENCESCOPE_LOGBOOKML_PID) },
 { USB_DEVICE(FTDI_VID, FTDI_SCIENCESCOPE_LS_LOGBOOK_PID) },
 { USB_DEVICE(FTDI_VID, FTDI_SCIENCESCOPE_HS_LOGBOOK_PID) },
 { USB_DEVICE(FTDI_VID, FTDI_CINTERION_MC55I_PID) },
 { USB_DEVICE(FTDI_VID, FTDI_FHE_PID) },
 { USB_DEVICE(FTDI_VID, FTDI_DOTEC_PID) },
 { USB_DEVICE(QIHARDWARE_VID, MILKYMISTONE_JTAGSERIAL_PID),
  .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk },
 { USB_DEVICE(ST_VID, ST_STMCLT_2232_PID),
  .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk },
 { USB_DEVICE(ST_VID, ST_STMCLT_4232_PID),
  .driver_info = (kernel_ulong_t)&ftdi_stmclite_quirk },
 { USB_DEVICE(FTDI_VID, FTDI_RF_R106) },
 { USB_DEVICE(FTDI_VID, FTDI_DISTORTEC_JTAG_LOCK_PICK_PID),
  .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk },
 { USB_DEVICE(FTDI_VID, FTDI_LUMEL_PD12_PID) },
 /* Crucible Devices */
 { USB_DEVICE(FTDI_VID, FTDI_CT_COMET_PID) },
 { USB_DEVICE(FTDI_VID, FTDI_Z3X_PID) },
 /* Cressi Devices */
 { USB_DEVICE(FTDI_VID, FTDI_CRESSI_PID) },
 /* Brainboxes Devices */
 { USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_VX_001_PID) },
 { USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_VX_012_PID) },
 { USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_VX_023_PID) },
 { USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_VX_034_PID) },
 { USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_US_101_PID) },
 { USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_US_159_PID) },
 { USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_US_160_1_PID) },
 { USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_US_160_2_PID) },
 { USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_US_160_3_PID) },
 { USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_US_160_4_PID) },
 { USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_US_160_5_PID) },
 { USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_US_160_6_PID) },
 { USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_US_160_7_PID) },
 { USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_US_160_8_PID) },
 { USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_US_235_PID) },
 { USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_US_257_PID) },
 { USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_US_279_1_PID) },
 { USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_US_279_2_PID) },
 { USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_US_279_3_PID) },
 { USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_US_279_4_PID) },
 { USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_US_313_PID) },
 { USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_US_320_PID) },
 { USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_US_324_PID) },
 { USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_US_346_1_PID) },
 { USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_US_346_2_PID) },
 { USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_US_357_PID) },
 { USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_US_606_1_PID) },
 { USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_US_606_2_PID) },
 { USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_US_606_3_PID) },
 { USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_US_701_1_PID) },
 { USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_US_701_2_PID) },
 { USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_US_842_1_PID) },
 { USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_US_842_2_PID) },
 { USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_US_842_3_PID) },
 { USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_US_842_4_PID) },
 /* ekey Devices */
 { USB_DEVICE(FTDI_VID, FTDI_EKEY_CONV_USB_PID) },
 /* Infineon Devices */
 { USB_DEVICE_INTERFACE_NUMBER(INFINEON_VID, INFINEON_TRIBOARD_TC1798_PID, 1) },
 { USB_DEVICE_INTERFACE_NUMBER(INFINEON_VID, INFINEON_TRIBOARD_TC2X7_PID, 1) },
 /* GE Healthcare devices */
 { USB_DEVICE(GE_HEALTHCARE_VID, GE_HEALTHCARE_NEMO_TRACKER_PID) },
 /* Active Research (Actisense) devices */
 { USB_DEVICE(FTDI_VID, ACTISENSE_NDC_PID) },
 { USB_DEVICE(FTDI_VID, ACTISENSE_USG_PID) },
 { USB_DEVICE(FTDI_VID, ACTISENSE_NGT_PID) },
 { USB_DEVICE(FTDI_VID, ACTISENSE_NGW_PID) },
 { USB_DEVICE(FTDI_VID, ACTISENSE_UID_PID) },
 { USB_DEVICE(FTDI_VID, ACTISENSE_USA_PID) },
 { USB_DEVICE(FTDI_VID, ACTISENSE_NGX_PID) },
 { USB_DEVICE(FTDI_VID, ACTISENSE_D9AF_PID) },
 { USB_DEVICE(FTDI_VID, CHETCO_SEAGAUGE_PID) },
 { USB_DEVICE(FTDI_VID, CHETCO_SEASWITCH_PID) },
 { USB_DEVICE(FTDI_VID, CHETCO_SEASMART_NMEA2000_PID) },
 { USB_DEVICE(FTDI_VID, CHETCO_SEASMART_ETHERNET_PID) },
 { USB_DEVICE(FTDI_VID, CHETCO_SEASMART_WIFI_PID) },
 { USB_DEVICE(FTDI_VID, CHETCO_SEASMART_DISPLAY_PID) },
 { USB_DEVICE(FTDI_VID, CHETCO_SEASMART_LITE_PID) },
 { USB_DEVICE(FTDI_VID, CHETCO_SEASMART_ANALOG_PID) },
 /* Belimo Automation devices */
 { USB_DEVICE(FTDI_VID, BELIMO_ZTH_PID) },
 { USB_DEVICE(FTDI_VID, BELIMO_ZIP_PID) },
 /* ICP DAS I-756xU devices */
 { USB_DEVICE(ICPDAS_VID, ICPDAS_I7560U_PID) },
 { USB_DEVICE(ICPDAS_VID, ICPDAS_I7561U_PID) },
 { USB_DEVICE(ICPDAS_VID, ICPDAS_I7563U_PID) },
 { USB_DEVICE(WICED_VID, WICED_USB20706V2_PID) },
 { USB_DEVICE(TI_VID, TI_CC3200_LAUNCHPAD_PID),
  .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk },
 { USB_DEVICE(CYPRESS_VID, CYPRESS_WICED_BT_USB_PID) },
 { USB_DEVICE(CYPRESS_VID, CYPRESS_WICED_WL_USB_PID) },
 { USB_DEVICE(AIRBUS_DS_VID, AIRBUS_DS_P8GR) },
 /* EZPrototypes devices */
 { USB_DEVICE(EZPROTOTYPES_VID, HJELMSLUND_USB485_ISO_PID) },
 { USB_DEVICE_INTERFACE_NUMBER(UNJO_VID, UNJO_ISODEBUG_V1_PID, 1) },
 /* Sienna devices */
 { USB_DEVICE(FTDI_VID, FTDI_SIENNA_PID) },
 { USB_DEVICE(ECHELON_VID, ECHELON_U20_PID) },
 /* IDS GmbH devices */
 { USB_DEVICE(IDS_VID, IDS_SI31A_PID) },
 { USB_DEVICE(IDS_VID, IDS_CM31A_PID) },
 /* Omron devices */
 { USB_DEVICE(OMRON_VID, OMRON_CS1W_CIF31_PID) },
 /* U-Blox devices */
 { USB_DEVICE(UBLOX_VID, UBLOX_C099F9P_ZED_PID) },
 { USB_DEVICE(UBLOX_VID, UBLOX_C099F9P_ODIN_PID) },
 /* FreeCalypso USB adapters */
 { USB_DEVICE(FTDI_VID, FTDI_FALCONIA_JTAG_BUF_PID),
  .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk },
 { USB_DEVICE(FTDI_VID, FTDI_FALCONIA_JTAG_UNBUF_PID),
  .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk },
 /* GMC devices */
 { USB_DEVICE(GMC_VID, GMC_Z216C_PID) },
 /* Altera USB Blaster 3 */
 { USB_DEVICE_INTERFACE_NUMBER(ALTERA_VID, ALTERA_UB3_6022_PID, 1) },
 { USB_DEVICE_INTERFACE_NUMBER(ALTERA_VID, ALTERA_UB3_6025_PID, 2) },
 { USB_DEVICE_INTERFACE_NUMBER(ALTERA_VID, ALTERA_UB3_6026_PID, 2) },
 { USB_DEVICE_INTERFACE_NUMBER(ALTERA_VID, ALTERA_UB3_6026_PID, 3) },
 { USB_DEVICE_INTERFACE_NUMBER(ALTERA_VID, ALTERA_UB3_6029_PID, 2) },
 { USB_DEVICE_INTERFACE_NUMBER(ALTERA_VID, ALTERA_UB3_602A_PID, 2) },
 { USB_DEVICE_INTERFACE_NUMBER(ALTERA_VID, ALTERA_UB3_602A_PID, 3) },
 { USB_DEVICE_INTERFACE_NUMBER(ALTERA_VID, ALTERA_UB3_602C_PID, 1) },
 { USB_DEVICE_INTERFACE_NUMBER(ALTERA_VID, ALTERA_UB3_602D_PID, 1) },
 { USB_DEVICE_INTERFACE_NUMBER(ALTERA_VID, ALTERA_UB3_602D_PID, 2) },
 { USB_DEVICE_INTERFACE_NUMBER(ALTERA_VID, ALTERA_UB3_602E_PID, 1) },
 { USB_DEVICE_INTERFACE_NUMBER(ALTERA_VID, ALTERA_UB3_602E_PID, 2) },
 { USB_DEVICE_INTERFACE_NUMBER(ALTERA_VID, ALTERA_UB3_602E_PID, 3) },
 /* Abacus Electrics */
 { USB_DEVICE(FTDI_VID, ABACUS_OPTICAL_PROBE_PID) },
 { }     /* Terminating entry */
};

MODULE_DEVICE_TABLE(usb, id_table_combined);

static const char *ftdi_chip_name[] = {
 [SIO]  = "SIO"/* the serial part of FT8U100AX */
 [FT232A] = "FT232A",
 [FT232B] = "FT232B",
 [FT2232C] = "FT2232C/D",
 [FT232R] = "FT232R",
 [FT232H] = "FT232H",
 [FT2232H] = "FT2232H",
 [FT4232H] = "FT4232H",
 [FT4232HA] = "FT4232HA",
 [FT232HP] = "FT232HP",
 [FT233HP] = "FT233HP",
 [FT2232HP] = "FT2232HP",
 [FT2233HP] = "FT2233HP",
 [FT4232HP] = "FT4232HP",
 [FT4233HP] = "FT4233HP",
 [FTX]  = "FT-X",
};


/* Used for TIOCMIWAIT */
#define FTDI_STATUS_B0_MASK (FTDI_RS0_CTS | FTDI_RS0_DSR | FTDI_RS0_RI | FTDI_RS0_RLSD)
#define FTDI_STATUS_B1_MASK (FTDI_RS_BI)
/* End TIOCMIWAIT */

static void ftdi_set_termios(struct tty_struct *tty,
        struct usb_serial_port *port,
        const struct ktermios *old_termios);
static int ftdi_get_modem_status(struct usb_serial_port *port,
      unsigned char status[2]);

#define WDR_TIMEOUT 5000 /* default urb timeout */
#define WDR_SHORT_TIMEOUT 1000 /* shorter urb timeout */

/*
 * ***************************************************************************
 * Utility functions
 * ***************************************************************************
 */


static unsigned short int ftdi_232am_baud_base_to_divisor(int baud, int base)
{
 unsigned short int divisor;
 /* divisor shifted 3 bits to the left */
 int divisor3 = DIV_ROUND_CLOSEST(base, 2 * baud);
 if ((divisor3 & 0x7) == 7)
  divisor3++; /* round x.7/8 up to x+1 */
 divisor = divisor3 >> 3;
 divisor3 &= 0x7;
 if (divisor3 == 1)
  divisor |= 0xc000; /* +0.125 */
 else if (divisor3 >= 4)
  divisor |= 0x4000; /* +0.5 */
 else if (divisor3 != 0)
  divisor |= 0x8000; /* +0.25 */
 else if (divisor == 1)
  divisor = 0;  /* special case for maximum baud rate */
 return divisor;
}

static unsigned short int ftdi_232am_baud_to_divisor(int baud)
{
  return ftdi_232am_baud_base_to_divisor(baud, 48000000);
}

static u32 ftdi_232bm_baud_base_to_divisor(int baud, int base)
{
 static const unsigned char divfrac[8] = { 0, 3, 2, 4, 1, 5, 6, 7 };
 u32 divisor;
 /* divisor shifted 3 bits to the left */
 int divisor3 = DIV_ROUND_CLOSEST(base, 2 * baud);
 divisor = divisor3 >> 3;
 divisor |= (u32)divfrac[divisor3 & 0x7] << 14;
 /* Deal with special cases for highest baud rates. */
 if (divisor == 1)  /* 1.0 */
  divisor = 0;
 else if (divisor == 0x4001) /* 1.5 */
  divisor = 1;
 return divisor;
}

static u32 ftdi_232bm_baud_to_divisor(int baud)
{
  return ftdi_232bm_baud_base_to_divisor(baud, 48000000);
}

static u32 ftdi_2232h_baud_base_to_divisor(int baud, int base)
{
 static const unsigned char divfrac[8] = { 0, 3, 2, 4, 1, 5, 6, 7 };
 u32 divisor;
 int divisor3;

 /* hi-speed baud rate is 10-bit sampling instead of 16-bit */
 divisor3 = DIV_ROUND_CLOSEST(8 * base, 10 * baud);

 divisor = divisor3 >> 3;
 divisor |= (u32)divfrac[divisor3 & 0x7] << 14;
 /* Deal with special cases for highest baud rates. */
 if (divisor == 1)  /* 1.0 */
  divisor = 0;
 else if (divisor == 0x4001) /* 1.5 */
  divisor = 1;
 /*
 * Set this bit to turn off a divide by 2.5 on baud rate generator
 * This enables baud rates up to 12Mbaud but cannot reach below 1200
 * baud with this bit set
 */

 divisor |= 0x00020000;
 return divisor;
}

static u32 ftdi_2232h_baud_to_divisor(int baud)
{
  return ftdi_2232h_baud_base_to_divisor(baud, 120000000);
}

#define set_mctrl(port, set)  update_mctrl((port), (set), 0)
#define clear_mctrl(port, clear) update_mctrl((port), 0, (clear))

static int update_mctrl(struct usb_serial_port *port, unsigned int set,
       unsigned int clear)
{
 struct ftdi_private *priv = usb_get_serial_port_data(port);
 struct device *dev = &port->dev;
 unsigned value;
 int rv;

 if (((set | clear) & (TIOCM_DTR | TIOCM_RTS)) == 0) {
  dev_dbg(dev, "%s - DTR|RTS not being set|cleared\n", __func__);
  return 0; /* no change */
 }

 clear &= ~set; /* 'set' takes precedence over 'clear' */
 value = 0;
 if (clear & TIOCM_DTR)
  value |= FTDI_SIO_SET_DTR_LOW;
 if (clear & TIOCM_RTS)
  value |= FTDI_SIO_SET_RTS_LOW;
 if (set & TIOCM_DTR)
  value |= FTDI_SIO_SET_DTR_HIGH;
 if (set & TIOCM_RTS)
  value |= FTDI_SIO_SET_RTS_HIGH;
 rv = usb_control_msg(port->serial->dev,
          usb_sndctrlpipe(port->serial->dev, 0),
          FTDI_SIO_SET_MODEM_CTRL_REQUEST,
          FTDI_SIO_SET_MODEM_CTRL_REQUEST_TYPE,
          value, priv->channel,
          NULL, 0, WDR_TIMEOUT);
 if (rv < 0) {
  dev_dbg(dev, "%s Error from MODEM_CTRL urb: DTR %s, RTS %s\n",
   __func__,
   (set & TIOCM_DTR) ? "HIGH" : (clear & TIOCM_DTR) ? "LOW" : "unchanged",
   (set & TIOCM_RTS) ? "HIGH" : (clear & TIOCM_RTS) ? "LOW" : "unchanged");
  rv = usb_translate_errors(rv);
 } else {
  dev_dbg(dev, "%s - DTR %s, RTS %s\n", __func__,
   (set & TIOCM_DTR) ? "HIGH" : (clear & TIOCM_DTR) ? "LOW" : "unchanged",
   (set & TIOCM_RTS) ? "HIGH" : (clear & TIOCM_RTS) ? "LOW" : "unchanged");
  /* FIXME: locking on last_dtr_rts */
  priv->last_dtr_rts = (priv->last_dtr_rts & ~clear) | set;
 }
 return rv;
}


static u32 get_ftdi_divisor(struct tty_struct *tty,
      struct usb_serial_port *port)
{
 struct ftdi_private *priv = usb_get_serial_port_data(port);
 struct device *dev = &port->dev;
 u32 div_value = 0;
 int div_okay = 1;
 int baud;

 baud = tty_get_baud_rate(tty);
 dev_dbg(dev, "%s - tty_get_baud_rate reports speed %d\n", __func__, baud);

 /*
 * Observe deprecated async-compatible custom_divisor hack, update
 * baudrate if needed.
 */

 if (baud == 38400 &&
     ((priv->flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST) &&
      (priv->custom_divisor)) {
  baud = priv->baud_base / priv->custom_divisor;
  dev_dbg(dev, "%s - custom divisor %d sets baud rate to %d\n",
   __func__, priv->custom_divisor, baud);
 }

 if (!baud)
  baud = 9600;
 switch (priv->chip_type) {
 case SIO:
  switch (baud) {
  case 300: div_value = ftdi_sio_b300; break;
  case 600: div_value = ftdi_sio_b600; break;
  case 1200: div_value = ftdi_sio_b1200; break;
  case 2400: div_value = ftdi_sio_b2400; break;
  case 4800: div_value = ftdi_sio_b4800; break;
  case 9600: div_value = ftdi_sio_b9600; break;
  case 19200: div_value = ftdi_sio_b19200; break;
  case 38400: div_value = ftdi_sio_b38400; break;
  case 57600: div_value = ftdi_sio_b57600;  break;
  case 115200: div_value = ftdi_sio_b115200; break;
  default:
   dev_dbg(dev, "%s - Baudrate (%d) requested is not supported\n",
    __func__,  baud);
   div_value = ftdi_sio_b9600;
   baud = 9600;
   div_okay = 0;
  }
  break;
 case FT232A:
  if (baud <= 3000000) {
   div_value = ftdi_232am_baud_to_divisor(baud);
  } else {
   dev_dbg(dev, "%s - Baud rate too high!\n", __func__);
   baud = 9600;
   div_value = ftdi_232am_baud_to_divisor(9600);
   div_okay = 0;
  }
  break;
 case FT232B:
 case FT2232C:
 case FT232R:
 case FTX:
  if (baud <= 3000000) {
   u16 product_id = le16_to_cpu(
    port->serial->dev->descriptor.idProduct);
   if (((product_id == FTDI_NDI_HUC_PID)  ||
        (product_id == FTDI_NDI_SPECTRA_SCU_PID) ||
        (product_id == FTDI_NDI_FUTURE_2_PID) ||
        (product_id == FTDI_NDI_FUTURE_3_PID) ||
        (product_id == FTDI_NDI_AURORA_SCU_PID)) &&
       (baud == 19200)) {
    baud = 1200000;
   }
   div_value = ftdi_232bm_baud_to_divisor(baud);
  } else {
   dev_dbg(dev, "%s - Baud rate too high!\n", __func__);
   div_value = ftdi_232bm_baud_to_divisor(9600);
   div_okay = 0;
   baud = 9600;
  }
  break;
 default:
  if ((baud <= 12000000) && (baud >= 1200)) {
   div_value = ftdi_2232h_baud_to_divisor(baud);
  } else if (baud < 1200) {
   div_value = ftdi_232bm_baud_to_divisor(baud);
  } else {
   dev_dbg(dev, "%s - Baud rate too high!\n", __func__);
   div_value = ftdi_232bm_baud_to_divisor(9600);
   div_okay = 0;
   baud = 9600;
  }
  break;
 }

 if (div_okay) {
  dev_dbg(dev, "%s - Baud rate set to %d (divisor 0x%lX) on chip %s\n",
   __func__, baud, (unsigned long)div_value,
   ftdi_chip_name[priv->chip_type]);
 }

 tty_encode_baud_rate(tty, baud, baud);
 return div_value;
}

static int change_speed(struct tty_struct *tty, struct usb_serial_port *port)
{
 struct ftdi_private *priv = usb_get_serial_port_data(port);
 u16 value;
 u16 index;
 u32 index_value;
 int rv;

 index_value = get_ftdi_divisor(tty, port);
 value = (u16)index_value;
 index = (u16)(index_value >> 16);
 if (priv->channel)
  index = (u16)((index << 8) | priv->channel);

 rv = usb_control_msg(port->serial->dev,
       usb_sndctrlpipe(port->serial->dev, 0),
       FTDI_SIO_SET_BAUDRATE_REQUEST,
       FTDI_SIO_SET_BAUDRATE_REQUEST_TYPE,
       value, index,
       NULL, 0, WDR_SHORT_TIMEOUT);
 return rv;
}

static int write_latency_timer(struct usb_serial_port *port)
{
 struct ftdi_private *priv = usb_get_serial_port_data(port);
 struct usb_device *udev = port->serial->dev;
 int rv;
 int l = priv->latency;

 if (priv->chip_type == SIO || priv->chip_type == FT232A)
  return -EINVAL;

 if (priv->flags & ASYNC_LOW_LATENCY)
  l = 1;

 dev_dbg(&port->dev, "%s: setting latency timer = %i\n", __func__, l);

 rv = usb_control_msg(udev,
        usb_sndctrlpipe(udev, 0),
        FTDI_SIO_SET_LATENCY_TIMER_REQUEST,
        FTDI_SIO_SET_LATENCY_TIMER_REQUEST_TYPE,
        l, priv->channel,
        NULL, 0, WDR_TIMEOUT);
 if (rv < 0)
  dev_err(&port->dev, "Unable to write latency timer: %i\n", rv);
 return rv;
}

static int _read_latency_timer(struct usb_serial_port *port)
{
 struct ftdi_private *priv = usb_get_serial_port_data(port);
 struct usb_device *udev = port->serial->dev;
 u8 buf;
 int rv;

 rv = usb_control_msg_recv(udev, 0, FTDI_SIO_GET_LATENCY_TIMER_REQUEST,
      FTDI_SIO_GET_LATENCY_TIMER_REQUEST_TYPE, 0,
      priv->channel, &buf, 1, WDR_TIMEOUT,
      GFP_KERNEL);
 if (rv == 0)
  rv = buf;

 return rv;
}

static int read_latency_timer(struct usb_serial_port *port)
{
 struct ftdi_private *priv = usb_get_serial_port_data(port);
 int rv;

 if (priv->chip_type == SIO || priv->chip_type == FT232A)
  return -EINVAL;

 rv = _read_latency_timer(port);
 if (rv < 0) {
  dev_err(&port->dev, "Unable to read latency timer: %i\n", rv);
  return rv;
 }

 priv->latency = rv;

 return 0;
}

static void get_serial_info(struct tty_struct *tty, struct serial_struct *ss)
{
 struct usb_serial_port *port = tty->driver_data;
 struct ftdi_private *priv = usb_get_serial_port_data(port);

 mutex_lock(&priv->cfg_lock);
 ss->flags = priv->flags;
 ss->baud_base = priv->baud_base;
 ss->custom_divisor = priv->custom_divisor;
 mutex_unlock(&priv->cfg_lock);
}

static int set_serial_info(struct tty_struct *tty, struct serial_struct *ss)
{
 struct usb_serial_port *port = tty->driver_data;
 struct ftdi_private *priv = usb_get_serial_port_data(port);
 int old_flags, old_divisor;

 mutex_lock(&priv->cfg_lock);

 if (!capable(CAP_SYS_ADMIN)) {
  if ((ss->flags ^ priv->flags) & ~ASYNC_USR_MASK) {
   mutex_unlock(&priv->cfg_lock);
   return -EPERM;
  }
 }

 old_flags = priv->flags;
 old_divisor = priv->custom_divisor;

 priv->flags = ss->flags & ASYNC_FLAGS;
 priv->custom_divisor = ss->custom_divisor;

 write_latency_timer(port);

 if ((priv->flags ^ old_flags) & ASYNC_SPD_MASK ||
   ((priv->flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST &&
    priv->custom_divisor != old_divisor)) {

  /* warn about deprecation unless clearing */
  if (priv->flags & ASYNC_SPD_MASK)
   dev_warn_ratelimited(&port->dev, "use of SPD flags is deprecated\n");

  change_speed(tty, port);
 }
 mutex_unlock(&priv->cfg_lock);
 return 0;
}

static int get_lsr_info(struct usb_serial_port *port,
   unsigned int __user *retinfo)
{
 struct ftdi_private *priv = usb_get_serial_port_data(port);
 unsigned int result = 0;

 if (priv->transmit_empty)
  result = TIOCSER_TEMT;

 if (copy_to_user(retinfo, &result, sizeof(unsigned int)))
  return -EFAULT;
 return 0;
}

static int ftdi_determine_type(struct usb_serial_port *port)
{
 struct ftdi_private *priv = usb_get_serial_port_data(port);
 struct usb_serial *serial = port->serial;
 struct usb_device *udev = serial->dev;
--> --------------------

--> maximum size reached

--> --------------------

Messung V0.5
C=95 H=99 G=96

¤ Dauer der Verarbeitung: 0.12 Sekunden  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.