usbredir: Add support for buffered bulk input (v2)

Buffered bulk mode is intended for bulk *input* endpoints, where the data is
of a streaming nature (not part of a command-response protocol). These
endpoints' input buffer may overflow if data is not read quickly enough.
So in buffered bulk mode the usb-host takes care of the submitting and
re-submitting of bulk transfers.

Buffered bulk mode is necessary for reliable operation with the bulk in
endpoints of usb to serial convertors. Unfortunatelty buffered bulk input
mode will only work with certain devices, therefor this patch also adds a
usb-id table to enable it for devices which need it, while leaving the
bulk ep handling for other devices unmodified.

Note that the bumping of the required usbredir from 0.5.3 to 0.6 does
not mean that we will now need a newer usbredir release then qemu-1.3,
.pc files reporting 0.5.3 have only ever existed in usbredir builds directly
from git, so qemu-1.3 needs the 0.6 release too.

Changes in v2:
-Split of quirk handling into quirks.c

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
This commit is contained in:
Hans de Goede 2012-12-19 15:08:33 +01:00 committed by Gerd Hoffmann
parent 358d615b69
commit b2d1fe67d0
8 changed files with 2718 additions and 21 deletions

2
configure vendored
View File

@ -2851,7 +2851,7 @@ fi
# check for usbredirparser for usb network redirection support
if test "$usb_redir" != "no" ; then
if $pkg_config --atleast-version=0.5.3 libusbredirparser-0.5 >/dev/null 2>&1 ; then
if $pkg_config --atleast-version=0.6 libusbredirparser-0.5 >/dev/null 2>&1 ; then
usb_redir="yes"
usb_redir_cflags=$($pkg_config --cflags libusbredirparser-0.5 2>/dev/null)
usb_redir_libs=$($pkg_config --libs libusbredirparser-0.5 2>/dev/null)

View File

@ -553,5 +553,15 @@ const USBDesc *usb_device_get_usb_desc(USBDevice *dev);
int ehci_create_ich9_with_companions(PCIBus *bus, int slot);
#endif
/* quirks.c */
/* In bulk endpoints are streaming data sources (iow behave like isoc eps) */
#define USB_QUIRK_BUFFER_BULK_IN 0x01
/* Bulk pkts in FTDI format, need special handling when combining packets */
#define USB_QUIRK_IS_FTDI 0x02
int usb_get_quirks(uint16_t vendor_id, uint16_t product_id,
uint8_t interface_class, uint8_t interface_subclass,
uint8_t interface_protocol);
#endif

View File

@ -5,7 +5,7 @@ common-obj-$(CONFIG_USB_XHCI) += hcd-xhci.o
common-obj-y += libhw.o
common-obj-$(CONFIG_SMARTCARD) += dev-smartcard-reader.o
common-obj-$(CONFIG_USB_REDIR) += redirect.o
common-obj-$(CONFIG_USB_REDIR) += redirect.o quirks.o
common-obj-y += core.o combined-packet.o bus.o desc.o dev-hub.o
common-obj-y += host-$(HOST_USB).o dev-bluetooth.o

1255
hw/usb/quirks-ftdi-ids.h Normal file

File diff suppressed because it is too large Load Diff

150
hw/usb/quirks-pl2303-ids.h Normal file
View File

@ -0,0 +1,150 @@
/*
* Prolific PL2303 USB to serial adaptor driver header file
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
*/
#define BENQ_VENDOR_ID 0x04a5
#define BENQ_PRODUCT_ID_S81 0x4027
#define PL2303_VENDOR_ID 0x067b
#define PL2303_PRODUCT_ID 0x2303
#define PL2303_PRODUCT_ID_RSAQ2 0x04bb
#define PL2303_PRODUCT_ID_DCU11 0x1234
#define PL2303_PRODUCT_ID_PHAROS 0xaaa0
#define PL2303_PRODUCT_ID_RSAQ3 0xaaa2
#define PL2303_PRODUCT_ID_ALDIGA 0x0611
#define PL2303_PRODUCT_ID_MMX 0x0612
#define PL2303_PRODUCT_ID_GPRS 0x0609
#define PL2303_PRODUCT_ID_HCR331 0x331a
#define PL2303_PRODUCT_ID_MOTOROLA 0x0307
#define ATEN_VENDOR_ID 0x0557
#define ATEN_VENDOR_ID2 0x0547
#define ATEN_PRODUCT_ID 0x2008
#define IODATA_VENDOR_ID 0x04bb
#define IODATA_PRODUCT_ID 0x0a03
#define IODATA_PRODUCT_ID_RSAQ5 0x0a0e
#define ELCOM_VENDOR_ID 0x056e
#define ELCOM_PRODUCT_ID 0x5003
#define ELCOM_PRODUCT_ID_UCSGT 0x5004
#define ITEGNO_VENDOR_ID 0x0eba
#define ITEGNO_PRODUCT_ID 0x1080
#define ITEGNO_PRODUCT_ID_2080 0x2080
#define MA620_VENDOR_ID 0x0df7
#define MA620_PRODUCT_ID 0x0620
#define RATOC_VENDOR_ID 0x0584
#define RATOC_PRODUCT_ID 0xb000
#define TRIPP_VENDOR_ID 0x2478
#define TRIPP_PRODUCT_ID 0x2008
#define RADIOSHACK_VENDOR_ID 0x1453
#define RADIOSHACK_PRODUCT_ID 0x4026
#define DCU10_VENDOR_ID 0x0731
#define DCU10_PRODUCT_ID 0x0528
#define SITECOM_VENDOR_ID 0x6189
#define SITECOM_PRODUCT_ID 0x2068
/* Alcatel OT535/735 USB cable */
#define ALCATEL_VENDOR_ID 0x11f7
#define ALCATEL_PRODUCT_ID 0x02df
/* Samsung I330 phone cradle */
#define SAMSUNG_VENDOR_ID 0x04e8
#define SAMSUNG_PRODUCT_ID 0x8001
#define SIEMENS_VENDOR_ID 0x11f5
#define SIEMENS_PRODUCT_ID_SX1 0x0001
#define SIEMENS_PRODUCT_ID_X65 0x0003
#define SIEMENS_PRODUCT_ID_X75 0x0004
#define SIEMENS_PRODUCT_ID_EF81 0x0005
#define SYNTECH_VENDOR_ID 0x0745
#define SYNTECH_PRODUCT_ID 0x0001
/* Nokia CA-42 Cable */
#define NOKIA_CA42_VENDOR_ID 0x078b
#define NOKIA_CA42_PRODUCT_ID 0x1234
/* CA-42 CLONE Cable www.ca-42.com chipset: Prolific Technology Inc */
#define CA_42_CA42_VENDOR_ID 0x10b5
#define CA_42_CA42_PRODUCT_ID 0xac70
#define SAGEM_VENDOR_ID 0x079b
#define SAGEM_PRODUCT_ID 0x0027
/* Leadtek GPS 9531 (ID 0413:2101) */
#define LEADTEK_VENDOR_ID 0x0413
#define LEADTEK_9531_PRODUCT_ID 0x2101
/* USB GSM cable from Speed Dragon Multimedia, Ltd */
#define SPEEDDRAGON_VENDOR_ID 0x0e55
#define SPEEDDRAGON_PRODUCT_ID 0x110b
/* DATAPILOT Universal-2 Phone Cable */
#define DATAPILOT_U2_VENDOR_ID 0x0731
#define DATAPILOT_U2_PRODUCT_ID 0x2003
/* Belkin "F5U257" Serial Adapter */
#define BELKIN_VENDOR_ID 0x050d
#define BELKIN_PRODUCT_ID 0x0257
/* Alcor Micro Corp. USB 2.0 TO RS-232 */
#define ALCOR_VENDOR_ID 0x058F
#define ALCOR_PRODUCT_ID 0x9720
/* Willcom WS002IN Data Driver (by NetIndex Inc.) */
#define WS002IN_VENDOR_ID 0x11f6
#define WS002IN_PRODUCT_ID 0x2001
/* Corega CG-USBRS232R Serial Adapter */
#define COREGA_VENDOR_ID 0x07aa
#define COREGA_PRODUCT_ID 0x002a
/* Y.C. Cable U.S.A., Inc - USB to RS-232 */
#define YCCABLE_VENDOR_ID 0x05ad
#define YCCABLE_PRODUCT_ID 0x0fba
/* "Superial" USB - Serial */
#define SUPERIAL_VENDOR_ID 0x5372
#define SUPERIAL_PRODUCT_ID 0x2303
/* Hewlett-Packard LD220-HP POS Pole Display */
#define HP_VENDOR_ID 0x03f0
#define HP_LD220_PRODUCT_ID 0x3524
/* Cressi Edy (diving computer) PC interface */
#define CRESSI_VENDOR_ID 0x04b8
#define CRESSI_EDY_PRODUCT_ID 0x0521
/* Zeagle dive computer interface */
#define ZEAGLE_VENDOR_ID 0x04b8
#define ZEAGLE_N2ITION3_PRODUCT_ID 0x0522
/* Sony, USB data cable for CMD-Jxx mobile phones */
#define SONY_VENDOR_ID 0x054c
#define SONY_QN3USB_PRODUCT_ID 0x0437
/* Sanwa KB-USB2 multimeter cable (ID: 11ad:0001) */
#define SANWA_VENDOR_ID 0x11ad
#define SANWA_PRODUCT_ID 0x0001
/* ADLINK ND-6530 RS232,RS485 and RS422 adapter */
#define ADLINK_VENDOR_ID 0x0b63
#define ADLINK_ND6530_PRODUCT_ID 0x6530
/* SMART USB Serial Adapter */
#define SMART_VENDOR_ID 0x0b8c
#define SMART_PRODUCT_ID 0x2303

53
hw/usb/quirks.c Normal file
View File

@ -0,0 +1,53 @@
/*
* USB quirk handling
*
* Copyright (c) 2012 Red Hat, Inc.
*
* Red Hat Authors:
* Hans de Goede <hdegoede@redhat.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*/
#include "quirks.h"
#include "hw/usb.h"
static bool usb_id_match(const struct usb_device_id *ids,
uint16_t vendor_id, uint16_t product_id,
uint8_t interface_class, uint8_t interface_subclass,
uint8_t interface_protocol) {
int i;
for (i = 0; ids[i].vendor_id != -1; i++) {
if (ids[i].vendor_id == vendor_id &&
ids[i].product_id == product_id &&
(ids[i].interface_class == -1 ||
(ids[i].interface_class == interface_class &&
ids[i].interface_subclass == interface_subclass &&
ids[i].interface_protocol == interface_protocol))) {
return true;
}
}
return false;
}
int usb_get_quirks(uint16_t vendor_id, uint16_t product_id,
uint8_t interface_class, uint8_t interface_subclass,
uint8_t interface_protocol)
{
int quirks = 0;
if (usb_id_match(usbredir_raw_serial_ids, vendor_id, product_id,
interface_class, interface_subclass, interface_protocol)) {
quirks |= USB_QUIRK_BUFFER_BULK_IN;
}
if (usb_id_match(usbredir_ftdi_serial_ids, vendor_id, product_id,
interface_class, interface_subclass, interface_protocol)) {
quirks |= USB_QUIRK_BUFFER_BULK_IN | USB_QUIRK_IS_FTDI;
}
return quirks;
}

910
hw/usb/quirks.h Normal file
View File

@ -0,0 +1,910 @@
/*
* USB quirk handling
*
* Copyright (c) 2012 Red Hat, Inc.
*
* Red Hat Authors:
* Hans de Goede <hdegoede@redhat.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*/
/* 1 on 1 copy of linux/drivers/usb/serial/ftdi_sio_ids.h */
#include "quirks-ftdi-ids.h"
/* 1 on 1 copy of linux/drivers/usb/serial/pl2303.h */
#include "quirks-pl2303-ids.h"
struct usb_device_id {
int vendor_id;
int product_id;
int interface_class;
int interface_subclass;
int interface_protocol;
};
#define USB_DEVICE(vendor, product) \
.vendor_id = vendor, .product_id = product, .interface_class = -1,
#define USB_DEVICE_AND_INTERFACE_INFO(vend, prod, iclass, isubclass, iproto) \
.vendor_id = vend, .product_id = prod, .interface_class = iclass, \
.interface_subclass = isubclass, .interface_protocol = iproto
static const struct usb_device_id usbredir_raw_serial_ids[] = {
/*
* Silicon Laboratories CP210x USB to RS232 serial adapter ids
* copied from linux/drivers/usb/serial/cp210x.c
*
* Copyright (C) 2005 Craig Shelley (craig@microtron.org.uk)
*/
{ USB_DEVICE(0x045B, 0x0053) }, /* Renesas RX610 RX-Stick */
{ USB_DEVICE(0x0471, 0x066A) }, /* AKTAKOM ACE-1001 cable */
{ USB_DEVICE(0x0489, 0xE000) }, /* Pirelli Broadband S.p.A, DP-L10 SIP/GSM Mobile */
{ USB_DEVICE(0x0489, 0xE003) }, /* Pirelli Broadband S.p.A, DP-L10 SIP/GSM Mobile */
{ USB_DEVICE(0x0745, 0x1000) }, /* CipherLab USB CCD Barcode Scanner 1000 */
{ USB_DEVICE(0x08e6, 0x5501) }, /* Gemalto Prox-PU/CU contactless smartcard reader */
{ USB_DEVICE(0x08FD, 0x000A) }, /* Digianswer A/S , ZigBee/802.15.4 MAC Device */
{ USB_DEVICE(0x0BED, 0x1100) }, /* MEI (TM) Cashflow-SC Bill/Voucher Acceptor */
{ USB_DEVICE(0x0BED, 0x1101) }, /* MEI series 2000 Combo Acceptor */
{ USB_DEVICE(0x0FCF, 0x1003) }, /* Dynastream ANT development board */
{ USB_DEVICE(0x0FCF, 0x1004) }, /* Dynastream ANT2USB */
{ USB_DEVICE(0x0FCF, 0x1006) }, /* Dynastream ANT development board */
{ USB_DEVICE(0x10A6, 0xAA26) }, /* Knock-off DCU-11 cable */
{ USB_DEVICE(0x10AB, 0x10C5) }, /* Siemens MC60 Cable */
{ USB_DEVICE(0x10B5, 0xAC70) }, /* Nokia CA-42 USB */
{ USB_DEVICE(0x10C4, 0x0F91) }, /* Vstabi */
{ USB_DEVICE(0x10C4, 0x1101) }, /* Arkham Technology DS101 Bus Monitor */
{ USB_DEVICE(0x10C4, 0x1601) }, /* Arkham Technology DS101 Adapter */
{ USB_DEVICE(0x10C4, 0x800A) }, /* SPORTident BSM7-D-USB main station */
{ USB_DEVICE(0x10C4, 0x803B) }, /* Pololu USB-serial converter */
{ USB_DEVICE(0x10C4, 0x8044) }, /* Cygnal Debug Adapter */
{ USB_DEVICE(0x10C4, 0x804E) }, /* Software Bisque Paramount ME build-in converter */
{ USB_DEVICE(0x10C4, 0x8053) }, /* Enfora EDG1228 */
{ USB_DEVICE(0x10C4, 0x8054) }, /* Enfora GSM2228 */
{ USB_DEVICE(0x10C4, 0x8066) }, /* Argussoft In-System Programmer */
{ USB_DEVICE(0x10C4, 0x806F) }, /* IMS USB to RS422 Converter Cable */
{ USB_DEVICE(0x10C4, 0x807A) }, /* Crumb128 board */
{ USB_DEVICE(0x10C4, 0x80C4) }, /* Cygnal Integrated Products, Inc., Optris infrared thermometer */
{ USB_DEVICE(0x10C4, 0x80CA) }, /* Degree Controls Inc */
{ USB_DEVICE(0x10C4, 0x80DD) }, /* Tracient RFID */
{ USB_DEVICE(0x10C4, 0x80F6) }, /* Suunto sports instrument */
{ USB_DEVICE(0x10C4, 0x8115) }, /* Arygon NFC/Mifare Reader */
{ USB_DEVICE(0x10C4, 0x813D) }, /* Burnside Telecom Deskmobile */
{ USB_DEVICE(0x10C4, 0x813F) }, /* Tams Master Easy Control */
{ USB_DEVICE(0x10C4, 0x814A) }, /* West Mountain Radio RIGblaster P&P */
{ USB_DEVICE(0x10C4, 0x814B) }, /* West Mountain Radio RIGtalk */
{ USB_DEVICE(0x10C4, 0x8156) }, /* B&G H3000 link cable */
{ USB_DEVICE(0x10C4, 0x815E) }, /* Helicomm IP-Link 1220-DVM */
{ USB_DEVICE(0x10C4, 0x815F) }, /* Timewave HamLinkUSB */
{ USB_DEVICE(0x10C4, 0x818B) }, /* AVIT Research USB to TTL */
{ USB_DEVICE(0x10C4, 0x819F) }, /* MJS USB Toslink Switcher */
{ USB_DEVICE(0x10C4, 0x81A6) }, /* ThinkOptics WavIt */
{ USB_DEVICE(0x10C4, 0x81A9) }, /* Multiplex RC Interface */
{ USB_DEVICE(0x10C4, 0x81AC) }, /* MSD Dash Hawk */
{ USB_DEVICE(0x10C4, 0x81AD) }, /* INSYS USB Modem */
{ USB_DEVICE(0x10C4, 0x81C8) }, /* Lipowsky Industrie Elektronik GmbH, Baby-JTAG */
{ USB_DEVICE(0x10C4, 0x81E2) }, /* Lipowsky Industrie Elektronik GmbH, Baby-LIN */
{ USB_DEVICE(0x10C4, 0x81E7) }, /* Aerocomm Radio */
{ USB_DEVICE(0x10C4, 0x81E8) }, /* Zephyr Bioharness */
{ USB_DEVICE(0x10C4, 0x81F2) }, /* C1007 HF band RFID controller */
{ USB_DEVICE(0x10C4, 0x8218) }, /* Lipowsky Industrie Elektronik GmbH, HARP-1 */
{ USB_DEVICE(0x10C4, 0x822B) }, /* Modem EDGE(GSM) Comander 2 */
{ USB_DEVICE(0x10C4, 0x826B) }, /* Cygnal Integrated Products, Inc., Fasttrax GPS demonstration module */
{ USB_DEVICE(0x10C4, 0x8293) }, /* Telegesis ETRX2USB */
{ USB_DEVICE(0x10C4, 0x82F9) }, /* Procyon AVS */
{ USB_DEVICE(0x10C4, 0x8341) }, /* Siemens MC35PU GPRS Modem */
{ USB_DEVICE(0x10C4, 0x8382) }, /* Cygnal Integrated Products, Inc. */
{ USB_DEVICE(0x10C4, 0x83A8) }, /* Amber Wireless AMB2560 */
{ USB_DEVICE(0x10C4, 0x83D8) }, /* DekTec DTA Plus VHF/UHF Booster/Attenuator */
{ USB_DEVICE(0x10C4, 0x8411) }, /* Kyocera GPS Module */
{ USB_DEVICE(0x10C4, 0x8418) }, /* IRZ Automation Teleport SG-10 GSM/GPRS Modem */
{ USB_DEVICE(0x10C4, 0x846E) }, /* BEI USB Sensor Interface (VCP) */
{ USB_DEVICE(0x10C4, 0x8477) }, /* Balluff RFID */
{ USB_DEVICE(0x10C4, 0x85EA) }, /* AC-Services IBUS-IF */
{ USB_DEVICE(0x10C4, 0x85EB) }, /* AC-Services CIS-IBUS */
{ USB_DEVICE(0x10C4, 0x8664) }, /* AC-Services CAN-IF */
{ USB_DEVICE(0x10C4, 0x8665) }, /* AC-Services OBD-IF */
{ USB_DEVICE(0x10C4, 0xEA60) }, /* Silicon Labs factory default */
{ USB_DEVICE(0x10C4, 0xEA61) }, /* Silicon Labs factory default */
{ USB_DEVICE(0x10C4, 0xEA70) }, /* Silicon Labs factory default */
{ USB_DEVICE(0x10C4, 0xEA80) }, /* Silicon Labs factory default */
{ USB_DEVICE(0x10C4, 0xEA71) }, /* Infinity GPS-MIC-1 Radio Monophone */
{ USB_DEVICE(0x10C4, 0xF001) }, /* Elan Digital Systems USBscope50 */
{ USB_DEVICE(0x10C4, 0xF002) }, /* Elan Digital Systems USBwave12 */
{ USB_DEVICE(0x10C4, 0xF003) }, /* Elan Digital Systems USBpulse100 */
{ USB_DEVICE(0x10C4, 0xF004) }, /* Elan Digital Systems USBcount50 */
{ USB_DEVICE(0x10C5, 0xEA61) }, /* Silicon Labs MobiData GPRS USB Modem */
{ USB_DEVICE(0x10CE, 0xEA6A) }, /* Silicon Labs MobiData GPRS USB Modem 100EU */
{ USB_DEVICE(0x13AD, 0x9999) }, /* Baltech card reader */
{ USB_DEVICE(0x1555, 0x0004) }, /* Owen AC4 USB-RS485 Converter */
{ USB_DEVICE(0x166A, 0x0201) }, /* Clipsal 5500PACA C-Bus Pascal Automation Controller */
{ USB_DEVICE(0x166A, 0x0301) }, /* Clipsal 5800PC C-Bus Wireless PC Interface */
{ USB_DEVICE(0x166A, 0x0303) }, /* Clipsal 5500PCU C-Bus USB interface */
{ USB_DEVICE(0x166A, 0x0304) }, /* Clipsal 5000CT2 C-Bus Black and White Touchscreen */
{ USB_DEVICE(0x166A, 0x0305) }, /* Clipsal C-5000CT2 C-Bus Spectrum Colour Touchscreen */
{ USB_DEVICE(0x166A, 0x0401) }, /* Clipsal L51xx C-Bus Architectural Dimmer */
{ USB_DEVICE(0x166A, 0x0101) }, /* Clipsal 5560884 C-Bus Multi-room Audio Matrix Switcher */
{ USB_DEVICE(0x16D6, 0x0001) }, /* Jablotron serial interface */
{ USB_DEVICE(0x16DC, 0x0010) }, /* W-IE-NE-R Plein & Baus GmbH PL512 Power Supply */
{ USB_DEVICE(0x16DC, 0x0011) }, /* W-IE-NE-R Plein & Baus GmbH RCM Remote Control for MARATON Power Supply */
{ USB_DEVICE(0x16DC, 0x0012) }, /* W-IE-NE-R Plein & Baus GmbH MPOD Multi Channel Power Supply */
{ USB_DEVICE(0x16DC, 0x0015) }, /* W-IE-NE-R Plein & Baus GmbH CML Control, Monitoring and Data Logger */
{ USB_DEVICE(0x17A8, 0x0001) }, /* Kamstrup Optical Eye/3-wire */
{ USB_DEVICE(0x17A8, 0x0005) }, /* Kamstrup M-Bus Master MultiPort 250D */
{ USB_DEVICE(0x17F4, 0xAAAA) }, /* Wavesense Jazz blood glucose meter */
{ USB_DEVICE(0x1843, 0x0200) }, /* Vaisala USB Instrument Cable */
{ USB_DEVICE(0x18EF, 0xE00F) }, /* ELV USB-I2C-Interface */
{ USB_DEVICE(0x1BE3, 0x07A6) }, /* WAGO 750-923 USB Service Cable */
{ USB_DEVICE(0x1E29, 0x0102) }, /* Festo CPX-USB */
{ USB_DEVICE(0x1E29, 0x0501) }, /* Festo CMSP */
{ USB_DEVICE(0x3195, 0xF190) }, /* Link Instruments MSO-19 */
{ USB_DEVICE(0x3195, 0xF280) }, /* Link Instruments MSO-28 */
{ USB_DEVICE(0x3195, 0xF281) }, /* Link Instruments MSO-28 */
{ USB_DEVICE(0x413C, 0x9500) }, /* DW700 GPS USB interface */
/*
* Prolific pl2303 USB to RS232 serial adapter ids
* copied from linux/drivers/usb/serial/pl2303.c
*
* Copyright (C) 2001-2007 Greg Kroah-Hartman (greg@kroah.com)
* Copyright (C) 2003 IBM Corp.
*/
{ USB_DEVICE(PL2303_VENDOR_ID, PL2303_PRODUCT_ID) },
{ USB_DEVICE(PL2303_VENDOR_ID, PL2303_PRODUCT_ID_RSAQ2) },
{ USB_DEVICE(PL2303_VENDOR_ID, PL2303_PRODUCT_ID_DCU11) },
{ USB_DEVICE(PL2303_VENDOR_ID, PL2303_PRODUCT_ID_RSAQ3) },
{ USB_DEVICE(PL2303_VENDOR_ID, PL2303_PRODUCT_ID_PHAROS) },
{ USB_DEVICE(PL2303_VENDOR_ID, PL2303_PRODUCT_ID_ALDIGA) },
{ USB_DEVICE(PL2303_VENDOR_ID, PL2303_PRODUCT_ID_MMX) },
{ USB_DEVICE(PL2303_VENDOR_ID, PL2303_PRODUCT_ID_GPRS) },
{ USB_DEVICE(PL2303_VENDOR_ID, PL2303_PRODUCT_ID_HCR331) },
{ USB_DEVICE(PL2303_VENDOR_ID, PL2303_PRODUCT_ID_MOTOROLA) },
{ USB_DEVICE(IODATA_VENDOR_ID, IODATA_PRODUCT_ID) },
{ USB_DEVICE(IODATA_VENDOR_ID, IODATA_PRODUCT_ID_RSAQ5) },
{ USB_DEVICE(ATEN_VENDOR_ID, ATEN_PRODUCT_ID) },
{ USB_DEVICE(ATEN_VENDOR_ID2, ATEN_PRODUCT_ID) },
{ USB_DEVICE(ELCOM_VENDOR_ID, ELCOM_PRODUCT_ID) },
{ USB_DEVICE(ELCOM_VENDOR_ID, ELCOM_PRODUCT_ID_UCSGT) },
{ USB_DEVICE(ITEGNO_VENDOR_ID, ITEGNO_PRODUCT_ID) },
{ USB_DEVICE(ITEGNO_VENDOR_ID, ITEGNO_PRODUCT_ID_2080) },
{ USB_DEVICE(MA620_VENDOR_ID, MA620_PRODUCT_ID) },
{ USB_DEVICE(RATOC_VENDOR_ID, RATOC_PRODUCT_ID) },
{ USB_DEVICE(TRIPP_VENDOR_ID, TRIPP_PRODUCT_ID) },
{ USB_DEVICE(RADIOSHACK_VENDOR_ID, RADIOSHACK_PRODUCT_ID) },
{ USB_DEVICE(DCU10_VENDOR_ID, DCU10_PRODUCT_ID) },
{ USB_DEVICE(SITECOM_VENDOR_ID, SITECOM_PRODUCT_ID) },
{ USB_DEVICE(ALCATEL_VENDOR_ID, ALCATEL_PRODUCT_ID) },
{ USB_DEVICE(SAMSUNG_VENDOR_ID, SAMSUNG_PRODUCT_ID) },
{ USB_DEVICE(SIEMENS_VENDOR_ID, SIEMENS_PRODUCT_ID_SX1) },
{ USB_DEVICE(SIEMENS_VENDOR_ID, SIEMENS_PRODUCT_ID_X65) },
{ USB_DEVICE(SIEMENS_VENDOR_ID, SIEMENS_PRODUCT_ID_X75) },
{ USB_DEVICE(SIEMENS_VENDOR_ID, SIEMENS_PRODUCT_ID_EF81) },
{ USB_DEVICE(BENQ_VENDOR_ID, BENQ_PRODUCT_ID_S81) }, /* Benq/Siemens S81 */
{ USB_DEVICE(SYNTECH_VENDOR_ID, SYNTECH_PRODUCT_ID) },
{ USB_DEVICE(NOKIA_CA42_VENDOR_ID, NOKIA_CA42_PRODUCT_ID) },
{ USB_DEVICE(CA_42_CA42_VENDOR_ID, CA_42_CA42_PRODUCT_ID) },
{ USB_DEVICE(SAGEM_VENDOR_ID, SAGEM_PRODUCT_ID) },
{ USB_DEVICE(LEADTEK_VENDOR_ID, LEADTEK_9531_PRODUCT_ID) },
{ USB_DEVICE(SPEEDDRAGON_VENDOR_ID, SPEEDDRAGON_PRODUCT_ID) },
{ USB_DEVICE(DATAPILOT_U2_VENDOR_ID, DATAPILOT_U2_PRODUCT_ID) },
{ USB_DEVICE(BELKIN_VENDOR_ID, BELKIN_PRODUCT_ID) },
{ USB_DEVICE(ALCOR_VENDOR_ID, ALCOR_PRODUCT_ID) },
{ USB_DEVICE(WS002IN_VENDOR_ID, WS002IN_PRODUCT_ID) },
{ USB_DEVICE(COREGA_VENDOR_ID, COREGA_PRODUCT_ID) },
{ USB_DEVICE(YCCABLE_VENDOR_ID, YCCABLE_PRODUCT_ID) },
{ USB_DEVICE(SUPERIAL_VENDOR_ID, SUPERIAL_PRODUCT_ID) },
{ USB_DEVICE(HP_VENDOR_ID, HP_LD220_PRODUCT_ID) },
{ USB_DEVICE(CRESSI_VENDOR_ID, CRESSI_EDY_PRODUCT_ID) },
{ USB_DEVICE(ZEAGLE_VENDOR_ID, ZEAGLE_N2ITION3_PRODUCT_ID) },
{ USB_DEVICE(SONY_VENDOR_ID, SONY_QN3USB_PRODUCT_ID) },
{ USB_DEVICE(SANWA_VENDOR_ID, SANWA_PRODUCT_ID) },
{ USB_DEVICE(ADLINK_VENDOR_ID, ADLINK_ND6530_PRODUCT_ID) },
{ USB_DEVICE(SMART_VENDOR_ID, SMART_PRODUCT_ID) },
{ USB_DEVICE(-1, -1) } /* Terminating Entry */
};
static const struct usb_device_id usbredir_ftdi_serial_ids[] = {
/*
* FTDI USB to RS232 serial adapter ids
* copied from linux/drivers/usb/serial/ftdi_sio.c
*
* Copyright (C) 2009 - 2010
* 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)
*/
{ 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_NXTCAM_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) },
{ 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_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(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_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(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(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) },
{ USB_DEVICE(FTDI_VID, FTDI_USB_UIRT_PID) },
{ 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) },
/*
* ELV devices:
*/
{ 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, 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(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(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_USB_INTERFACE_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) },
{ USB_DEVICE(FTDI_VID, FTDI_NDI_SPECTRA_SCU_PID) },
{ USB_DEVICE(FTDI_VID, FTDI_NDI_FUTURE_2_PID) },
{ USB_DEVICE(FTDI_VID, FTDI_NDI_FUTURE_3_PID) },
{ USB_DEVICE(FTDI_VID, FTDI_NDI_AURORA_SCU_PID) },
{ USB_DEVICE(TELLDUS_VID, TELLDUS_TELLSTICK_PID) },
{ USB_DEVICE(RTSYSTEMS_VID, RTSYSTEMS_SERIAL_VX7_PID) },
{ USB_DEVICE(RTSYSTEMS_VID, RTSYSTEMS_CT29B_PID) },
{ USB_DEVICE(RTSYSTEMS_VID, RTSYSTEMS_RTS01_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(OLIMEX_VID, OLIMEX_ARM_USB_OCD_PID) },
{ USB_DEVICE(OLIMEX_VID, OLIMEX_ARM_USB_OCD_H_PID) },
{ USB_DEVICE(FIC_VID, FIC_NEO1973_DEBUG_PID) },
{ USB_DEVICE(FTDI_VID, FTDI_OOCDLINK_PID) },
{ USB_DEVICE(FTDI_VID, LMI_LM3S_DEVEL_BOARD_PID) },
{ USB_DEVICE(FTDI_VID, LMI_LM3S_EVAL_BOARD_PID) },
{ USB_DEVICE(FTDI_VID, LMI_LM3S_ICDI_BOARD_PID) },
{ USB_DEVICE(FTDI_VID, FTDI_TURTELIZER_PID) },
{ USB_DEVICE(RATOC_VENDOR_ID, RATOC_PRODUCT_ID_USB60F) },
{ 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) },
{ USB_DEVICE(ADI_VID, ADI_GNICEPLUS_PID) },
{ USB_DEVICE_AND_INTERFACE_INFO(MICROCHIP_VID, MICROCHIP_USB_BOARD_PID,
0xff, 0xff, 0x00) },
{ USB_DEVICE(JETI_VID, JETI_SPC1201_PID) },
{ USB_DEVICE(MARVELL_VID, MARVELL_SHEEVAPLUG_PID) },
{ 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) },
{ USB_DEVICE(FTDI_VID, TI_XDS100V2_PID) },
{ 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) },
{ USB_DEVICE(FTDI_VID, XVERVE_SIGNALYZER_SLITE_PID) },
{ USB_DEVICE(FTDI_VID, XVERVE_SIGNALYZER_SH2_PID) },
{ USB_DEVICE(FTDI_VID, XVERVE_SIGNALYZER_SH4_PID) },
{ USB_DEVICE(FTDI_VID, SEGWAY_RMP200_PID) },
{ USB_DEVICE(FTDI_VID, ACCESIO_COM4SM_PID) },
{ USB_DEVICE(IONICS_VID, IONICS_PLUGCOMPUTER_PID) },
{ 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_DOTEC_PID) },
{ USB_DEVICE(QIHARDWARE_VID, MILKYMISTONE_JTAGSERIAL_PID) },
{ USB_DEVICE(ST_VID, ST_STMCLT1030_PID) },
{ USB_DEVICE(FTDI_VID, FTDI_RF_R106) },
{ USB_DEVICE(FTDI_VID, FTDI_DISTORTEC_JTAG_LOCK_PICK_PID) },
{ USB_DEVICE(FTDI_VID, FTDI_LUMEL_PD12_PID) },
{ USB_DEVICE(-1, -1) } /* Terminating Entry */
};
#undef USB_DEVICE
#undef USB_DEVICE_AND_INTERFACE_INFO

View File

@ -52,11 +52,13 @@
typedef struct USBRedirDevice USBRedirDevice;
/* Struct to hold buffered packets (iso or int input packets) */
/* Struct to hold buffered packets */
struct buf_packet {
uint8_t *data;
int len;
int status;
void *free_on_destroy;
uint16_t len;
uint16_t offset;
uint8_t status;
QTAILQ_ENTRY(buf_packet)next;
};
@ -70,11 +72,14 @@ struct endp_data {
uint8_t iso_error; /* For reporting iso errors to the HC */
uint8_t interrupt_started;
uint8_t interrupt_error;
uint8_t bulk_receiving_enabled;
uint8_t bulk_receiving_started;
uint8_t bufpq_prefilled;
uint8_t bufpq_dropping_packets;
QTAILQ_HEAD(, buf_packet) bufpq;
int32_t bufpq_size;
int32_t bufpq_target_size;
USBPacket *pending_async_packet;
};
struct PacketIdQueueEntry {
@ -108,6 +113,7 @@ struct USBRedirDevice {
struct endp_data endpoint[MAX_ENDPOINTS];
struct PacketIdQueue cancelled;
struct PacketIdQueue already_in_flight;
void (*buffered_bulk_in_complete)(USBRedirDevice *, USBPacket *, uint8_t);
/* Data for device filtering */
struct usb_redir_device_connect_header device_info;
struct usb_redir_interface_info_header interface_info;
@ -135,6 +141,8 @@ static void usbredir_interrupt_receiving_status(void *priv, uint64_t id,
*interrupt_receiving_status);
static void usbredir_bulk_streams_status(void *priv, uint64_t id,
struct usb_redir_bulk_streams_status_header *bulk_streams_status);
static void usbredir_bulk_receiving_status(void *priv, uint64_t id,
struct usb_redir_bulk_receiving_status_header *bulk_receiving_status);
static void usbredir_control_packet(void *priv, uint64_t id,
struct usb_redir_control_packet_header *control_packet,
uint8_t *data, int data_len);
@ -147,6 +155,9 @@ static void usbredir_iso_packet(void *priv, uint64_t id,
static void usbredir_interrupt_packet(void *priv, uint64_t id,
struct usb_redir_interrupt_packet_header *interrupt_header,
uint8_t *data, int data_len);
static void usbredir_buffered_bulk_packet(void *priv, uint64_t id,
struct usb_redir_buffered_bulk_packet_header *buffered_bulk_packet,
uint8_t *data, int data_len);
static void usbredir_handle_status(USBRedirDevice *dev, USBPacket *p,
int status);
@ -320,12 +331,19 @@ static void packet_id_queue_empty(struct PacketIdQueue *q)
static void usbredir_cancel_packet(USBDevice *udev, USBPacket *p)
{
USBRedirDevice *dev = DO_UPCAST(USBRedirDevice, dev, udev);
int i = USBEP2I(p->ep);
if (p->combined) {
usb_combined_packet_cancel(udev, p);
return;
}
if (dev->endpoint[i].pending_async_packet) {
assert(dev->endpoint[i].pending_async_packet == p);
dev->endpoint[i].pending_async_packet = NULL;
return;
}
packet_id_queue_add(&dev->cancelled, p->id);
usbredirparser_send_cancel_data_packet(dev->parser, p->id);
usbredirparser_do_write(dev->parser);
@ -344,6 +362,11 @@ static void usbredir_fill_already_in_flight_from_ep(USBRedirDevice *dev,
{
static USBPacket *p;
/* async handled packets for bulk receiving eps do not count as inflight */
if (dev->endpoint[USBEP2I(ep)].bulk_receiving_started) {
return;
}
QTAILQ_FOREACH(p, &ep->queue, queue) {
/* Skip combined packets, except for the first */
if (p->combined && p != p->combined->first) {
@ -391,8 +414,8 @@ static USBPacket *usbredir_find_packet_by_id(USBRedirDevice *dev,
return p;
}
static void bufp_alloc(USBRedirDevice *dev,
uint8_t *data, int len, int status, uint8_t ep)
static void bufp_alloc(USBRedirDevice *dev, uint8_t *data, uint16_t len,
uint8_t status, uint8_t ep, void *free_on_destroy)
{
struct buf_packet *bufp;
@ -416,7 +439,9 @@ static void bufp_alloc(USBRedirDevice *dev,
bufp = g_malloc(sizeof(struct buf_packet));
bufp->data = data;
bufp->len = len;
bufp->offset = 0;
bufp->status = status;
bufp->free_on_destroy = free_on_destroy;
QTAILQ_INSERT_TAIL(&dev->endpoint[EP2I(ep)].bufpq, bufp, next);
dev->endpoint[EP2I(ep)].bufpq_size++;
}
@ -426,7 +451,7 @@ static void bufp_free(USBRedirDevice *dev, struct buf_packet *bufp,
{
QTAILQ_REMOVE(&dev->endpoint[EP2I(ep)].bufpq, bufp, next);
dev->endpoint[EP2I(ep)].bufpq_size--;
free(bufp->data);
free(bufp->free_on_destroy);
g_free(bufp);
}
@ -577,19 +602,162 @@ static void usbredir_stop_iso_stream(USBRedirDevice *dev, uint8_t ep)
usbredir_free_bufpq(dev, ep);
}
/*
* The usb-host may poll the endpoint faster then our guest, resulting in lots
* of smaller bulkp-s. The below buffered_bulk_in_complete* functions combine
* data from multiple bulkp-s into a single packet, avoiding bufpq overflows.
*/
static void usbredir_buffered_bulk_add_data_to_packet(USBRedirDevice *dev,
struct buf_packet *bulkp, int count, USBPacket *p, uint8_t ep)
{
usb_packet_copy(p, bulkp->data + bulkp->offset, count);
bulkp->offset += count;
if (bulkp->offset == bulkp->len) {
/* Store status in the last packet with data from this bulkp */
usbredir_handle_status(dev, p, bulkp->status);
bufp_free(dev, bulkp, ep);
}
}
static void usbredir_buffered_bulk_in_complete_raw(USBRedirDevice *dev,
USBPacket *p, uint8_t ep)
{
struct buf_packet *bulkp;
int count;
while ((bulkp = QTAILQ_FIRST(&dev->endpoint[EP2I(ep)].bufpq)) &&
p->actual_length < p->iov.size && p->status == USB_RET_SUCCESS) {
count = bulkp->len - bulkp->offset;
if (count > (p->iov.size - p->actual_length)) {
count = p->iov.size - p->actual_length;
}
usbredir_buffered_bulk_add_data_to_packet(dev, bulkp, count, p, ep);
}
}
static void usbredir_buffered_bulk_in_complete_ftdi(USBRedirDevice *dev,
USBPacket *p, uint8_t ep)
{
const int maxp = dev->endpoint[EP2I(ep)].max_packet_size;
uint8_t header[2] = { 0, 0 };
struct buf_packet *bulkp;
int count;
while ((bulkp = QTAILQ_FIRST(&dev->endpoint[EP2I(ep)].bufpq)) &&
p->actual_length < p->iov.size && p->status == USB_RET_SUCCESS) {
if (bulkp->len < 2) {
WARNING("malformed ftdi bulk in packet\n");
bufp_free(dev, bulkp, ep);
continue;
}
if ((p->actual_length % maxp) == 0) {
usb_packet_copy(p, bulkp->data, 2);
memcpy(header, bulkp->data, 2);
} else {
if (bulkp->data[0] != header[0] || bulkp->data[1] != header[1]) {
break; /* Different header, add to next packet */
}
}
if (bulkp->offset == 0) {
bulkp->offset = 2; /* Skip header */
}
count = bulkp->len - bulkp->offset;
/* Must repeat the header at maxp interval */
if (count > (maxp - (p->actual_length % maxp))) {
count = maxp - (p->actual_length % maxp);
}
usbredir_buffered_bulk_add_data_to_packet(dev, bulkp, count, p, ep);
}
}
static void usbredir_buffered_bulk_in_complete(USBRedirDevice *dev,
USBPacket *p, uint8_t ep)
{
p->status = USB_RET_SUCCESS; /* Clear previous ASYNC status */
dev->buffered_bulk_in_complete(dev, p, ep);
DPRINTF("bulk-token-in ep %02X status %d len %d id %"PRIu64"\n",
ep, p->status, p->actual_length, p->id);
}
static void usbredir_handle_buffered_bulk_in_data(USBRedirDevice *dev,
USBPacket *p, uint8_t ep)
{
/* Input bulk endpoint, buffered packet input */
if (!dev->endpoint[EP2I(ep)].bulk_receiving_started) {
int bpt;
struct usb_redir_start_bulk_receiving_header start = {
.endpoint = ep,
.stream_id = 0,
.no_transfers = 5,
};
/* Round bytes_per_transfer up to a multiple of max_packet_size */
bpt = 512 + dev->endpoint[EP2I(ep)].max_packet_size - 1;
bpt /= dev->endpoint[EP2I(ep)].max_packet_size;
bpt *= dev->endpoint[EP2I(ep)].max_packet_size;
start.bytes_per_transfer = bpt;
/* No id, we look at the ep when receiving a status back */
usbredirparser_send_start_bulk_receiving(dev->parser, 0, &start);
usbredirparser_do_write(dev->parser);
DPRINTF("bulk receiving started bytes/transfer %u count %d ep %02X\n",
start.bytes_per_transfer, start.no_transfers, ep);
dev->endpoint[EP2I(ep)].bulk_receiving_started = 1;
/* We don't really want to drop bulk packets ever, but
having some upper limit to how much we buffer is good. */
dev->endpoint[EP2I(ep)].bufpq_target_size = 5000;
dev->endpoint[EP2I(ep)].bufpq_dropping_packets = 0;
}
if (QTAILQ_EMPTY(&dev->endpoint[EP2I(ep)].bufpq)) {
DPRINTF("bulk-token-in ep %02X, no bulkp\n", ep);
assert(dev->endpoint[EP2I(ep)].pending_async_packet == NULL);
dev->endpoint[EP2I(ep)].pending_async_packet = p;
p->status = USB_RET_ASYNC;
return;
}
usbredir_buffered_bulk_in_complete(dev, p, ep);
}
static void usbredir_stop_bulk_receiving(USBRedirDevice *dev, uint8_t ep)
{
struct usb_redir_stop_bulk_receiving_header stop_bulk = {
.endpoint = ep,
.stream_id = 0,
};
if (dev->endpoint[EP2I(ep)].bulk_receiving_started) {
usbredirparser_send_stop_bulk_receiving(dev->parser, 0, &stop_bulk);
DPRINTF("bulk receiving stopped ep %02X\n", ep);
dev->endpoint[EP2I(ep)].bulk_receiving_started = 0;
}
usbredir_free_bufpq(dev, ep);
}
static void usbredir_handle_bulk_data(USBRedirDevice *dev, USBPacket *p,
uint8_t ep)
{
struct usb_redir_bulk_packet_header bulk_packet;
size_t size = (p->combined) ? p->combined->iov.size : p->iov.size;
DPRINTF("bulk-out ep %02X len %zd id %"PRIu64"\n", ep, size, p->id);
const int maxp = dev->endpoint[EP2I(ep)].max_packet_size;
if (usbredir_already_in_flight(dev, p->id)) {
p->status = USB_RET_ASYNC;
return;
}
if (dev->endpoint[EP2I(ep)].bulk_receiving_enabled) {
if (size != 0 && (size % maxp) == 0) {
usbredir_handle_buffered_bulk_in_data(dev, p, ep);
return;
}
WARNING("bulk recv invalid size %zd ep %02x, disabling\n", size, ep);
assert(dev->endpoint[EP2I(ep)].pending_async_packet == NULL);
usbredir_stop_bulk_receiving(dev, ep);
dev->endpoint[EP2I(ep)].bulk_receiving_enabled = 0;
}
DPRINTF("bulk-out ep %02X len %zd id %"PRIu64"\n", ep, size, p->id);
bulk_packet.endpoint = ep;
bulk_packet.length = size;
bulk_packet.stream_id = 0;
@ -726,9 +894,6 @@ static void usbredir_handle_data(USBDevice *udev, USBPacket *p)
ERROR("handle_data called for control transfer on ep %02X\n", ep);
p->status = USB_RET_NAK;
break;
case USB_ENDPOINT_XFER_ISOC:
usbredir_handle_iso_data(dev, p, ep);
break;
case USB_ENDPOINT_XFER_BULK:
if (p->state == USB_PACKET_SETUP && p->pid == USB_TOKEN_IN &&
p->ep->pipeline) {
@ -737,6 +902,9 @@ static void usbredir_handle_data(USBDevice *udev, USBPacket *p)
}
usbredir_handle_bulk_data(dev, p, ep);
break;
case USB_ENDPOINT_XFER_ISOC:
usbredir_handle_iso_data(dev, p, ep);
break;
case USB_ENDPOINT_XFER_INT:
if (ep & USB_DIR_IN) {
usbredir_handle_interrupt_in_data(dev, p, ep);
@ -763,6 +931,11 @@ static void usbredir_stop_ep(USBRedirDevice *dev, int i)
uint8_t ep = I2EP(i);
switch (dev->endpoint[i].type) {
case USB_ENDPOINT_XFER_BULK:
if (ep & USB_DIR_IN) {
usbredir_stop_bulk_receiving(dev, ep);
}
break;
case USB_ENDPOINT_XFER_ISOC:
usbredir_stop_iso_stream(dev, ep);
break;
@ -942,10 +1115,12 @@ static void usbredir_create_parser(USBRedirDevice *dev)
dev->parser->interrupt_receiving_status_func =
usbredir_interrupt_receiving_status;
dev->parser->bulk_streams_status_func = usbredir_bulk_streams_status;
dev->parser->bulk_receiving_status_func = usbredir_bulk_receiving_status;
dev->parser->control_packet_func = usbredir_control_packet;
dev->parser->bulk_packet_func = usbredir_bulk_packet;
dev->parser->iso_packet_func = usbredir_iso_packet;
dev->parser->interrupt_packet_func = usbredir_interrupt_packet;
dev->parser->buffered_bulk_packet_func = usbredir_buffered_bulk_packet;
dev->read_buf = NULL;
dev->read_buf_size = 0;
@ -954,6 +1129,7 @@ static void usbredir_create_parser(USBRedirDevice *dev)
usbredirparser_caps_set_cap(caps, usb_redir_cap_ep_info_max_packet_size);
usbredirparser_caps_set_cap(caps, usb_redir_cap_64bits_ids);
usbredirparser_caps_set_cap(caps, usb_redir_cap_32bits_bulk_length);
usbredirparser_caps_set_cap(caps, usb_redir_cap_bulk_receiving);
if (runstate_check(RUN_STATE_INMIGRATE)) {
flags |= usbredirparser_fl_no_hello;
@ -1192,6 +1368,52 @@ error:
return -1;
}
static void usbredir_check_bulk_receiving(USBRedirDevice *dev)
{
int i, j, quirks;
if (!usbredirparser_peer_has_cap(dev->parser,
usb_redir_cap_bulk_receiving)) {
return;
}
for (i = EP2I(USB_DIR_IN); i < MAX_ENDPOINTS; i++) {
dev->endpoint[i].bulk_receiving_enabled = 0;
}
for (i = 0; i < dev->interface_info.interface_count; i++) {
quirks = usb_get_quirks(dev->device_info.vendor_id,
dev->device_info.product_id,
dev->interface_info.interface_class[i],
dev->interface_info.interface_subclass[i],
dev->interface_info.interface_protocol[i]);
if (!(quirks & USB_QUIRK_BUFFER_BULK_IN)) {
continue;
}
if (quirks & USB_QUIRK_IS_FTDI) {
dev->buffered_bulk_in_complete =
usbredir_buffered_bulk_in_complete_ftdi;
} else {
dev->buffered_bulk_in_complete =
usbredir_buffered_bulk_in_complete_raw;
}
for (j = EP2I(USB_DIR_IN); j < MAX_ENDPOINTS; j++) {
if (dev->endpoint[j].interface ==
dev->interface_info.interface[i] &&
dev->endpoint[j].type == USB_ENDPOINT_XFER_BULK &&
dev->endpoint[j].max_packet_size != 0) {
dev->endpoint[j].bulk_receiving_enabled = 1;
/*
* With buffering pipelining is not necessary. Also packet
* combining and bulk in buffering don't play nice together!
*/
I2USBEP(dev, j)->pipeline = false;
break; /* Only buffer for the first ep of each intf */
}
}
}
}
/*
* usbredirparser packet complete callbacks
*/
@ -1300,6 +1522,7 @@ static void usbredir_device_connect(void *priv,
return;
}
usbredir_check_bulk_receiving(dev);
qemu_mod_timer(dev->attach_timer, dev->next_attach_time);
}
@ -1338,9 +1561,10 @@ static void usbredir_interface_info(void *priv,
/*
* If we receive interface info after the device has already been
* connected (ie on a set_config), re-check the filter.
* connected (ie on a set_config), re-check interface dependent things.
*/
if (qemu_timer_pending(dev->attach_timer) || dev->dev.attached) {
usbredir_check_bulk_receiving(dev);
if (usbredir_check_filter(dev)) {
ERROR("Device no longer matches filter after interface info "
"change, disconnecting!\n");
@ -1441,6 +1665,7 @@ static void usbredir_ep_info(void *priv,
return;
}
usbredir_setup_usb_eps(dev);
usbredir_check_bulk_receiving(dev);
}
static void usbredir_configuration_status(void *priv, uint64_t id,
@ -1531,6 +1756,25 @@ static void usbredir_bulk_streams_status(void *priv, uint64_t id,
{
}
static void usbredir_bulk_receiving_status(void *priv, uint64_t id,
struct usb_redir_bulk_receiving_status_header *bulk_receiving_status)
{
USBRedirDevice *dev = priv;
uint8_t ep = bulk_receiving_status->endpoint;
DPRINTF("bulk recv status %d ep %02X id %"PRIu64"\n",
bulk_receiving_status->status, ep, id);
if (!dev->dev.attached || !dev->endpoint[EP2I(ep)].bulk_receiving_started) {
return;
}
if (bulk_receiving_status->status == usb_redir_stall) {
DPRINTF("bulk receiving stopped by peer ep %02X\n", ep);
dev->endpoint[EP2I(ep)].bulk_receiving_started = 0;
}
}
static void usbredir_control_packet(void *priv, uint64_t id,
struct usb_redir_control_packet_header *control_packet,
uint8_t *data, int data_len)
@ -1636,7 +1880,7 @@ static void usbredir_iso_packet(void *priv, uint64_t id,
}
/* bufp_alloc also adds the packet to the ep queue */
bufp_alloc(dev, data, data_len, iso_packet->status, ep);
bufp_alloc(dev, data, data_len, iso_packet->status, ep, data);
}
static void usbredir_interrupt_packet(void *priv, uint64_t id,
@ -1667,7 +1911,7 @@ static void usbredir_interrupt_packet(void *priv, uint64_t id,
}
/* bufp_alloc also adds the packet to the ep queue */
bufp_alloc(dev, data, data_len, interrupt_packet->status, ep);
bufp_alloc(dev, data, data_len, interrupt_packet->status, ep, data);
} else {
/*
* We report output interrupt packets as completed directly upon
@ -1680,6 +1924,52 @@ static void usbredir_interrupt_packet(void *priv, uint64_t id,
}
}
static void usbredir_buffered_bulk_packet(void *priv, uint64_t id,
struct usb_redir_buffered_bulk_packet_header *buffered_bulk_packet,
uint8_t *data, int data_len)
{
USBRedirDevice *dev = priv;
uint8_t status, ep = buffered_bulk_packet->endpoint;
void *free_on_destroy;
int i, len;
DPRINTF("buffered-bulk-in status %d ep %02X len %d id %"PRIu64"\n",
buffered_bulk_packet->status, ep, data_len, id);
if (dev->endpoint[EP2I(ep)].type != USB_ENDPOINT_XFER_BULK) {
ERROR("received buffered-bulk packet for non bulk ep %02X\n", ep);
free(data);
return;
}
if (dev->endpoint[EP2I(ep)].bulk_receiving_started == 0) {
DPRINTF("received buffered-bulk packet on not started ep %02X\n", ep);
free(data);
return;
}
/* Data must be in maxp chunks for buffered_bulk_add_*_data_to_packet */
len = dev->endpoint[EP2I(ep)].max_packet_size;
status = usb_redir_success;
free_on_destroy = NULL;
for (i = 0; i < data_len; i += len) {
if (len >= (data_len - i)) {
len = data_len - i;
status = buffered_bulk_packet->status;
free_on_destroy = data;
}
/* bufp_alloc also adds the packet to the ep queue */
bufp_alloc(dev, data + i, len, status, ep, free_on_destroy);
}
if (dev->endpoint[EP2I(ep)].pending_async_packet) {
USBPacket *p = dev->endpoint[EP2I(ep)].pending_async_packet;
dev->endpoint[EP2I(ep)].pending_async_packet = NULL;
usbredir_buffered_bulk_in_complete(dev, p, ep);
usb_packet_complete(&dev->dev, p);
}
}
/*
* Migration code
*/
@ -1714,6 +2004,7 @@ static int usbredir_post_load(void *priv, int version_id)
dev->dev.speedmask = (1 << dev->dev.speed);
usbredir_setup_usb_eps(dev);
usbredir_check_bulk_receiving(dev);
return 0;
}
@ -1787,15 +2078,16 @@ static void usbredir_put_bufpq(QEMUFile *f, void *priv, size_t unused)
struct endp_data *endp = priv;
USBRedirDevice *dev = endp->dev;
struct buf_packet *bufp;
int i = 0;
int len, i = 0;
qemu_put_be32(f, endp->bufpq_size);
QTAILQ_FOREACH(bufp, &endp->bufpq, next) {
len = bufp->len - bufp->offset;
DPRINTF("put_bufpq %d/%d len %d status %d\n", i + 1, endp->bufpq_size,
bufp->len, bufp->status);
qemu_put_be32(f, bufp->len);
len, bufp->status);
qemu_put_be32(f, len);
qemu_put_be32(f, bufp->status);
qemu_put_buffer(f, bufp->data, bufp->len);
qemu_put_buffer(f, bufp->data + bufp->offset, len);
i++;
}
assert(i == endp->bufpq_size);
@ -1813,7 +2105,9 @@ static int usbredir_get_bufpq(QEMUFile *f, void *priv, size_t unused)
bufp = g_malloc(sizeof(struct buf_packet));
bufp->len = qemu_get_be32(f);
bufp->status = qemu_get_be32(f);
bufp->offset = 0;
bufp->data = qemu_oom_check(malloc(bufp->len)); /* regular malloc! */
bufp->free_on_destroy = bufp->data;
qemu_get_buffer(f, bufp->data, bufp->len);
QTAILQ_INSERT_TAIL(&endp->bufpq, bufp, next);
DPRINTF("get_bufpq %d/%d len %d status %d\n", i + 1, endp->bufpq_size,
@ -1830,6 +2124,23 @@ static const VMStateInfo usbredir_ep_bufpq_vmstate_info = {
/* For endp_data migration */
static const VMStateDescription usbredir_bulk_receiving_vmstate = {
.name = "usb-redir-ep/bulk-receiving",
.version_id = 1,
.minimum_version_id = 1,
.fields = (VMStateField[]) {
VMSTATE_UINT8(bulk_receiving_started, struct endp_data),
VMSTATE_END_OF_LIST()
}
};
static bool usbredir_bulk_receiving_needed(void *priv)
{
struct endp_data *endp = priv;
return endp->bulk_receiving_started;
}
static const VMStateDescription usbredir_ep_vmstate = {
.name = "usb-redir-ep",
.version_id = 1,
@ -1856,6 +2167,14 @@ static const VMStateDescription usbredir_ep_vmstate = {
},
VMSTATE_INT32(bufpq_target_size, struct endp_data),
VMSTATE_END_OF_LIST()
},
.subsections = (VMStateSubsection[]) {
{
.vmsd = &usbredir_bulk_receiving_vmstate,
.needed = usbredir_bulk_receiving_needed,
}, {
/* empty */
}
}
};