diff options
Diffstat (limited to 'ANDROID_3.4.5/drivers/usb/serial')
88 files changed, 0 insertions, 57370 deletions
diff --git a/ANDROID_3.4.5/drivers/usb/serial/Kconfig b/ANDROID_3.4.5/drivers/usb/serial/Kconfig deleted file mode 100644 index 7141d659..00000000 --- a/ANDROID_3.4.5/drivers/usb/serial/Kconfig +++ /dev/null @@ -1,682 +0,0 @@ -# -# USB Serial device configuration -# - -menuconfig USB_SERIAL - tristate "USB Serial Converter support" - depends on USB - ---help--- - Say Y here if you have a USB device that provides normal serial - ports, or acts like a serial device, and you want to connect it to - your USB bus. - - Please read <file:Documentation/usb/usb-serial.txt> for more - information on the specifics of the different devices that are - supported, and on how to use them. - - To compile this driver as a module, choose M here: the - module will be called usbserial. - -if USB_SERIAL - -config USB_SERIAL_CONSOLE - bool "USB Serial Console device support" - depends on USB_SERIAL=y - ---help--- - If you say Y here, it will be possible to use a USB to serial - converter port as the system console (the system console is the - device which receives all kernel messages and warnings and which - allows logins in single user mode). This could be useful if some - terminal or printer is connected to that serial port. - - Even if you say Y here, the currently visible virtual console - (/dev/tty0) will still be used as the system console by default, but - you can alter that using a kernel command line option such as - "console=ttyUSB0". (Try "man bootparam" or see the documentation of - your boot loader (lilo or loadlin) about how to pass options to the - kernel at boot time.) - - If you don't have a VGA card installed and you say Y here, the - kernel will automatically use the first USB to serial converter - port, /dev/ttyUSB0, as system console. - - If unsure, say N. - -config USB_EZUSB - bool "Functions for loading firmware on EZUSB chips" - help - Say Y here if you need EZUSB device support. - -config USB_SERIAL_GENERIC - bool "USB Generic Serial Driver" - help - Say Y here if you want to use the generic USB serial driver. Please - read <file:Documentation/usb/usb-serial.txt> for more information on - using this driver. It is recommended that the "USB Serial converter - support" be compiled as a module for this driver to be used - properly. - -config USB_SERIAL_AIRCABLE - tristate "USB AIRcable Bluetooth Dongle Driver" - help - Say Y here if you want to use USB AIRcable Bluetooth Dongle. - - To compile this driver as a module, choose M here: the module - will be called aircable. - -config USB_SERIAL_ARK3116 - tristate "USB ARK Micro 3116 USB Serial Driver" - help - Say Y here if you want to use a ARK Micro 3116 USB to Serial - device. - - To compile this driver as a module, choose M here: the - module will be called ark3116 - -config USB_SERIAL_BELKIN - tristate "USB Belkin and Peracom Single Port Serial Driver" - help - Say Y here if you want to use a Belkin USB Serial single port - adaptor (F5U103 is one of the model numbers) or the Peracom single - port USB to serial adapter. - - To compile this driver as a module, choose M here: the - module will be called belkin_sa. - -config USB_SERIAL_CH341 - tristate "USB Winchiphead CH341 Single Port Serial Driver" - help - Say Y here if you want to use a Winchiphead CH341 single port - USB to serial adapter. - - To compile this driver as a module, choose M here: the - module will be called ch341. - -config USB_SERIAL_WHITEHEAT - tristate "USB ConnectTech WhiteHEAT Serial Driver" - select USB_EZUSB - help - Say Y here if you want to use a ConnectTech WhiteHEAT 4 port - USB to serial converter device. - - To compile this driver as a module, choose M here: the - module will be called whiteheat. - -config USB_SERIAL_DIGI_ACCELEPORT - tristate "USB Digi International AccelePort USB Serial Driver" - ---help--- - Say Y here if you want to use Digi AccelePort USB 2 or 4 devices, - 2 port (plus parallel port) and 4 port USB serial converters. The - parallel port on the USB 2 appears as a third serial port on Linux. - The Digi Acceleport USB 8 is not yet supported by this driver. - - This driver works under SMP with the usb-uhci driver. It does not - work under SMP with the uhci driver. - - To compile this driver as a module, choose M here: the - module will be called digi_acceleport. - -config USB_SERIAL_CP210X - tristate "USB CP210x family of UART Bridge Controllers" - help - Say Y here if you want to use a CP2101/CP2102/CP2103 based USB - to RS232 converters. - - To compile this driver as a module, choose M here: the - module will be called cp210x. - -config USB_SERIAL_CYPRESS_M8 - tristate "USB Cypress M8 USB Serial Driver" - help - Say Y here if you want to use a device that contains the Cypress - USB to Serial microcontroller, such as the DeLorme Earthmate GPS. - - Attempted SMP support... send bug reports! - - Supported microcontrollers in the CY4601 family are: - CY7C63741 CY7C63742 CY7C63743 CY7C64013 - - To compile this driver as a module, choose M here: the - module will be called cypress_m8. - -config USB_SERIAL_EMPEG - tristate "USB Empeg empeg-car Mark I/II Driver" - help - Say Y here if you want to connect to your Empeg empeg-car Mark I/II - mp3 player via USB. The driver uses a single ttyUSB{0,1,2,...} - device node. See <file:Documentation/usb/usb-serial.txt> for more - tidbits of information. - - To compile this driver as a module, choose M here: the - module will be called empeg. - -config USB_SERIAL_FTDI_SIO - tristate "USB FTDI Single Port Serial Driver" - ---help--- - Say Y here if you want to use a FTDI SIO single port USB to serial - converter device. The implementation I have is called the USC-1000. - This driver has also be tested with the 245 and 232 devices. - - See <http://ftdi-usb-sio.sourceforge.net/> for more - information on this driver and the device. - - To compile this driver as a module, choose M here: the - module will be called ftdi_sio. - -config USB_SERIAL_FUNSOFT - tristate "USB Fundamental Software Dongle Driver" - ---help--- - Say Y here if you want to use the Fundamental Software dongle. - - To compile this driver as a module, choose M here: the - module will be called funsoft. - -config USB_SERIAL_VISOR - tristate "USB Handspring Visor / Palm m50x / Sony Clie Driver" - help - Say Y here if you want to connect to your HandSpring Visor, Palm - m500 or m505 through its USB docking station. See - <http://usbvisor.sourceforge.net/index.php3> for more information on using this - driver. - - To compile this driver as a module, choose M here: the - module will be called visor. - -config USB_SERIAL_IPAQ - tristate "USB PocketPC PDA Driver" - help - Say Y here if you want to connect to your Compaq iPAQ, HP Jornada - or any other PDA running Windows CE 3.0 or PocketPC 2002 - using a USB cradle/cable. For information on using the driver, - read <file:Documentation/usb/usb-serial.txt>. - - To compile this driver as a module, choose M here: the - module will be called ipaq. - -config USB_SERIAL_IR - tristate "USB IR Dongle Serial Driver" - help - Say Y here if you want to enable simple serial support for USB IrDA - devices. This is useful if you do not want to use the full IrDA - stack. - - To compile this driver as a module, choose M here: the - module will be called ir-usb. - -config USB_SERIAL_EDGEPORT - tristate "USB Inside Out Edgeport Serial Driver" - ---help--- - Say Y here if you want to use any of the following devices from - Inside Out Networks (Digi): - Edgeport/4 - Rapidport/4 - Edgeport/4t - Edgeport/2 - Edgeport/4i - Edgeport/2i - Edgeport/421 - Edgeport/21 - Edgeport/8 - Edgeport/8 Dual - Edgeport/2D8 - Edgeport/4D8 - Edgeport/8i - Edgeport/2 DIN - Edgeport/4 DIN - Edgeport/16 Dual - - To compile this driver as a module, choose M here: the - module will be called io_edgeport. - -config USB_SERIAL_EDGEPORT_TI - tristate "USB Inside Out Edgeport Serial Driver (TI devices)" - help - Say Y here if you want to use any of the devices from Inside Out - Networks (Digi) that are not supported by the io_edgeport driver. - This includes the Edgeport/1 device. - - To compile this driver as a module, choose M here: the - module will be called io_ti. - -config USB_SERIAL_F81232 - tristate "USB Fintek F81232 Single Port Serial Driver" - help - Say Y here if you want to use the Fintek F81232 single - port usb to serial adapter. - - To compile this driver as a module, choose M here: the - module will be called f81232. - -config USB_SERIAL_GARMIN - tristate "USB Garmin GPS driver" - help - Say Y here if you want to connect to your Garmin GPS. - Should work with most Garmin GPS devices which have a native USB port. - - See <http://sourceforge.net/projects/garmin-gps> for the latest - version of the driver. - - To compile this driver as a module, choose M here: the - module will be called garmin_gps. - -config USB_SERIAL_IPW - tristate "USB IPWireless (3G UMTS TDD) Driver" - select USB_SERIAL_WWAN - help - Say Y here if you want to use a IPWireless USB modem such as - the ones supplied by Axity3G/Sentech South Africa. - - To compile this driver as a module, choose M here: the - module will be called ipw. - -config USB_SERIAL_IUU - tristate "USB Infinity USB Unlimited Phoenix Driver" - help - Say Y here if you want to use a IUU in phoenix mode and get - an extra ttyUSBx device. More information available on - http://eczema.ecze.com/iuu_phoenix.html - - To compile this driver as a module, choose M here: the - module will be called iuu_phoenix.o - -config USB_SERIAL_KEYSPAN_PDA - tristate "USB Keyspan PDA Single Port Serial Driver" - select USB_EZUSB - help - Say Y here if you want to use a Keyspan PDA single port USB to - serial converter device. This driver makes use of firmware - developed from scratch by Brian Warner. - - To compile this driver as a module, choose M here: the - module will be called keyspan_pda. - -config USB_SERIAL_KEYSPAN - tristate "USB Keyspan USA-xxx Serial Driver" - select USB_EZUSB - ---help--- - Say Y here if you want to use Keyspan USB to serial converter - devices. This driver makes use of Keyspan's official firmware - and was developed with their support. You must also include - firmware to support your particular device(s). - - See <http://blemings.org/hugh/keyspan.html> for more information. - - To compile this driver as a module, choose M here: the - module will be called keyspan. - -config USB_SERIAL_KEYSPAN_MPR - bool "USB Keyspan MPR Firmware" - depends on USB_SERIAL_KEYSPAN && FIRMWARE_IN_KERNEL - help - Say Y here to include firmware for the Keyspan MPR converter. - -config USB_SERIAL_KEYSPAN_USA28 - bool "USB Keyspan USA-28 Firmware" - depends on USB_SERIAL_KEYSPAN && FIRMWARE_IN_KERNEL - help - Say Y here to include firmware for the USA-28 converter. - -config USB_SERIAL_KEYSPAN_USA28X - bool "USB Keyspan USA-28X Firmware" - depends on USB_SERIAL_KEYSPAN && FIRMWARE_IN_KERNEL - help - Say Y here to include firmware for the USA-28X converter. - Be sure you have a USA-28X, there are also 28XA and 28XB - models, the label underneath has the actual part number. - -config USB_SERIAL_KEYSPAN_USA28XA - bool "USB Keyspan USA-28XA Firmware" - depends on USB_SERIAL_KEYSPAN && FIRMWARE_IN_KERNEL - help - Say Y here to include firmware for the USA-28XA converter. - Be sure you have a USA-28XA, there are also 28X and 28XB - models, the label underneath has the actual part number. - -config USB_SERIAL_KEYSPAN_USA28XB - bool "USB Keyspan USA-28XB Firmware" - depends on USB_SERIAL_KEYSPAN && FIRMWARE_IN_KERNEL - help - Say Y here to include firmware for the USA-28XB converter. - Be sure you have a USA-28XB, there are also 28X and 28XA - models, the label underneath has the actual part number. - -config USB_SERIAL_KEYSPAN_USA19 - bool "USB Keyspan USA-19 Firmware" - depends on USB_SERIAL_KEYSPAN && FIRMWARE_IN_KERNEL - help - Say Y here to include firmware for the USA-19 converter. - -config USB_SERIAL_KEYSPAN_USA18X - bool "USB Keyspan USA-18X Firmware" - depends on USB_SERIAL_KEYSPAN && FIRMWARE_IN_KERNEL - help - Say Y here to include firmware for the USA-18X converter. - -config USB_SERIAL_KEYSPAN_USA19W - bool "USB Keyspan USA-19W Firmware" - depends on USB_SERIAL_KEYSPAN && FIRMWARE_IN_KERNEL - help - Say Y here to include firmware for the USA-19W converter. - -config USB_SERIAL_KEYSPAN_USA19QW - bool "USB Keyspan USA-19QW Firmware" - depends on USB_SERIAL_KEYSPAN && FIRMWARE_IN_KERNEL - help - Say Y here to include firmware for the USA-19QW converter. - -config USB_SERIAL_KEYSPAN_USA19QI - bool "USB Keyspan USA-19QI Firmware" - depends on USB_SERIAL_KEYSPAN && FIRMWARE_IN_KERNEL - help - Say Y here to include firmware for the USA-19QI converter. - -config USB_SERIAL_KEYSPAN_USA49W - bool "USB Keyspan USA-49W Firmware" - depends on USB_SERIAL_KEYSPAN && FIRMWARE_IN_KERNEL - help - Say Y here to include firmware for the USA-49W converter. - -config USB_SERIAL_KEYSPAN_USA49WLC - bool "USB Keyspan USA-49WLC Firmware" - depends on USB_SERIAL_KEYSPAN && FIRMWARE_IN_KERNEL - help - Say Y here to include firmware for the USA-49WLC converter. - -config USB_SERIAL_KLSI - tristate "USB KL5KUSB105 (Palmconnect) Driver" - ---help--- - Say Y here if you want to use a KL5KUSB105 - based single port - serial adapter. The most widely known -- and currently the only - tested -- device in this category is the PalmConnect USB Serial - adapter sold by Palm Inc. for use with their Palm III and Palm V - series PDAs. - - Please read <file:Documentation/usb/usb-serial.txt> for more - information. - - To compile this driver as a module, choose M here: the - module will be called kl5kusb105. - -config USB_SERIAL_KOBIL_SCT - tristate "USB KOBIL chipcard reader" - ---help--- - Say Y here if you want to use one of the following KOBIL USB chipcard - readers: - - - USB TWIN - - KAAN Standard Plus - - KAAN SIM - - SecOVID Reader Plus - - B1 Professional - - KAAN Professional - - Note that you need a current CT-API. - To compile this driver as a module, choose M here: the - module will be called kobil_sct. - -config USB_SERIAL_MCT_U232 - tristate "USB MCT Single Port Serial Driver" - ---help--- - Say Y here if you want to use a USB Serial single port adapter from - Magic Control Technology Corp. (U232 is one of the model numbers). - - This driver also works with Sitecom U232-P25 and D-Link DU-H3SP USB - BAY, Belkin F5U109, and Belkin F5U409 devices. - - To compile this driver as a module, choose M here: the - module will be called mct_u232. - -config USB_SERIAL_METRO - tristate "USB Metrologic Instruments USB-POS Barcode Scanner Driver" - ---help--- - Say Y here if you want to use a USB POS Metrologic barcode scanner. - - To compile this driver as a module, choose M here: the - module will be called metro-usb. - -config USB_SERIAL_MOS7720 - tristate "USB Moschip 7720 Serial Driver" - ---help--- - Say Y here if you want to use USB Serial single and double - port adapters from Moschip Semiconductor Tech. - - To compile this driver as a module, choose M here: the - module will be called mos7720. - -config USB_SERIAL_MOS7715_PARPORT - bool "Support for parallel port on the Moschip 7715" - depends on USB_SERIAL_MOS7720 - depends on PARPORT=y || PARPORT=USB_SERIAL_MOS7720 - select PARPORT_NOT_PC - ---help--- - Say Y if you have a Moschip 7715 device and would like to use - the parallel port it provides. The port will register with - the parport subsystem as a low-level driver. - -config USB_SERIAL_MOS7840 - tristate "USB Moschip 7840/7820 USB Serial Driver" - ---help--- - Say Y here if you want to use a MCS7840 Quad-Serial or MCS7820 - Dual-Serial port device from MosChip Semiconductor. - - The MCS7840 and MCS7820 have been developed to connect a wide range - of standard serial devices to a USB host. The MCS7840 has a USB - device controller connected to four (4) individual UARTs while the - MCS7820 controller connects to two (2) individual UARTs. - - To compile this driver as a module, choose M here: the - module will be called mos7840. If unsure, choose N. - -config USB_SERIAL_MOTOROLA - tristate "USB Motorola Phone modem driver" - ---help--- - Say Y here if you want to use a Motorola phone with a USB - connector as a modem link. - - To compile this driver as a module, choose M here: the - module will be called moto_modem. If unsure, choose N. - -config USB_SERIAL_NAVMAN - tristate "USB Navman GPS device" - help - To compile this driver as a module, choose M here: the - module will be called navman. - -config USB_SERIAL_PL2303 - tristate "USB Prolific 2303 Single Port Serial Driver" - help - Say Y here if you want to use the PL2303 USB Serial single port - adapter from Prolific. - - To compile this driver as a module, choose M here: the - module will be called pl2303. - -config USB_SERIAL_OTI6858 - tristate "USB Ours Technology Inc. OTi-6858 USB To RS232 Bridge Controller" - help - Say Y here if you want to use the OTi-6858 single port USB to serial - converter device. - - To compile this driver as a module, choose M here: the - module will be called oti6858. - -config USB_SERIAL_QCAUX - tristate "USB Qualcomm Auxiliary Serial Port Driver" - help - Say Y here if you want to use the auxiliary serial ports provided - by many modems based on Qualcomm chipsets. These ports often use - a proprietary protocol called DM and cannot be used for AT- or - PPP-based communication. - - To compile this driver as a module, choose M here: the - module will be called qcaux. If unsure, choose N. - -config USB_SERIAL_QUALCOMM - tristate "USB Qualcomm Serial modem" - select USB_SERIAL_WWAN - help - Say Y here if you have a Qualcomm USB modem device. These are - usually wireless cellular modems. - - To compile this driver as a module, choose M here: the - module will be called qcserial. - -config USB_SERIAL_SPCP8X5 - tristate "USB SPCP8x5 USB To Serial Driver" - help - Say Y here if you want to use the spcp8x5 converter chip. This is - commonly found in some Z-Wave USB devices. - - To compile this driver as a module, choose M here: the - module will be called spcp8x5. - -config USB_SERIAL_HP4X - tristate "USB HP4x Calculators support" - help - Say Y here if you want to use an Hewlett-Packard 4x Calculator. - - To compile this driver as a module, choose M here: the - module will be called hp4x. - -config USB_SERIAL_SAFE - tristate "USB Safe Serial (Encapsulated) Driver" - -config USB_SERIAL_SAFE_PADDED - bool "USB Secure Encapsulated Driver - Padded" - depends on USB_SERIAL_SAFE - -config USB_SERIAL_SIEMENS_MPI - tristate "USB Siemens MPI driver" - help - Say M here if you want to use a Siemens USB/MPI adapter. - - To compile this driver as a module, choose M here: the - module will be called siemens_mpi. - -config USB_SERIAL_SIERRAWIRELESS - tristate "USB Sierra Wireless Driver" - help - Say M here if you want to use Sierra Wireless devices. - - Many devices have a feature known as TRU-Install. For those devices - to work properly, the USB Storage Sierra feature must be enabled. - - To compile this driver as a module, choose M here: the - module will be called sierra. - -config USB_SERIAL_SYMBOL - tristate "USB Symbol Barcode driver (serial mode)" - help - Say Y here if you want to use a Symbol USB Barcode device - in serial emulation mode. - - To compile this driver as a module, choose M here: the - module will be called symbolserial. - -config USB_SERIAL_TI - tristate "USB TI 3410/5052 Serial Driver" - help - Say Y here if you want to use the TI USB 3410 or 5052 - serial devices. - - To compile this driver as a module, choose M here: the - module will be called ti_usb_3410_5052. - -config USB_SERIAL_CYBERJACK - tristate "USB REINER SCT cyberJack pinpad/e-com chipcard reader" - ---help--- - Say Y here if you want to use a cyberJack pinpad/e-com USB chipcard - reader. This is an interface to ISO 7816 compatible contact-based - chipcards, e.g. GSM SIMs. - - To compile this driver as a module, choose M here: the - module will be called cyberjack. - - If unsure, say N. - -config USB_SERIAL_XIRCOM - tristate "USB Xircom / Entregra Single Port Serial Driver" - select USB_EZUSB - help - Say Y here if you want to use a Xircom or Entregra single port USB to - serial converter device. This driver makes use of firmware - developed from scratch by Brian Warner. - - To compile this driver as a module, choose M here: the - module will be called keyspan_pda. - -config USB_SERIAL_WWAN - tristate - -config USB_SERIAL_OPTION - tristate "USB driver for GSM and CDMA modems" - select USB_SERIAL_WWAN - help - Say Y here if you have a GSM or CDMA modem that's connected to USB. - - This driver also supports several PCMCIA cards which have a - built-in OHCI-USB adapter and an internally-connected GSM modem. - The USB bus on these cards is not accessible externally. - - Supported devices include (some of?) those made by: - Option, Huawei, Audiovox, Novatel Wireless, or Anydata. - - To compile this driver as a module, choose M here: the - module will be called option. - - If this driver doesn't recognize your device, - it might be accessible via the FTDI_SIO driver. - -config USB_SERIAL_OMNINET - tristate "USB ZyXEL omni.net LCD Plus Driver" - help - Say Y here if you want to use a ZyXEL omni.net LCD ISDN TA. - - To compile this driver as a module, choose M here: the - module will be called omninet. - -config USB_SERIAL_OPTICON - tristate "USB Opticon Barcode driver (serial mode)" - help - Say Y here if you want to use a Opticon USB Barcode device - in serial emulation mode. - - To compile this driver as a module, choose M here: the - module will be called opticon. - -config USB_SERIAL_VIVOPAY_SERIAL - tristate "USB ViVOpay serial interface driver" - help - Say Y here if you want to use a ViVOtech ViVOpay USB device. - - To compile this driver as a module, choose M here: the - module will be called vivopay-serial. - -config USB_SERIAL_ZIO - tristate "ZIO Motherboard USB serial interface driver" - help - Say Y here if you want to use ZIO Motherboard. - - To compile this driver as a module, choose M here: the - module will be called zio. - -config USB_SERIAL_SSU100 - tristate "USB Quatech SSU-100 Single Port Serial Driver" - help - Say Y here if you want to use the Quatech SSU-100 single - port usb to serial adapter. - - To compile this driver as a module, choose M here: the - module will be called ssu100. - -config USB_SERIAL_DEBUG - tristate "USB Debugging Device" - help - Say Y here if you have a USB debugging device used to receive - debugging data from another machine. The most common of these - devices is the NetChip TurboCONNECT device. - - To compile this driver as a module, choose M here: the - module will be called usb-debug. - -endif # USB_SERIAL diff --git a/ANDROID_3.4.5/drivers/usb/serial/Makefile b/ANDROID_3.4.5/drivers/usb/serial/Makefile deleted file mode 100644 index d0bd3be2..00000000 --- a/ANDROID_3.4.5/drivers/usb/serial/Makefile +++ /dev/null @@ -1,65 +0,0 @@ -# -# Makefile for the USB serial device drivers. -# - -# Object file lists. - -obj-$(CONFIG_USB_SERIAL) += usbserial.o - -usbserial-y := usb-serial.o generic.o bus.o - -usbserial-$(CONFIG_USB_SERIAL_CONSOLE) += console.o -usbserial-$(CONFIG_USB_EZUSB) += ezusb.o - -obj-$(CONFIG_USB_SERIAL_AIRCABLE) += aircable.o -obj-$(CONFIG_USB_SERIAL_ARK3116) += ark3116.o -obj-$(CONFIG_USB_SERIAL_BELKIN) += belkin_sa.o -obj-$(CONFIG_USB_SERIAL_CH341) += ch341.o -obj-$(CONFIG_USB_SERIAL_CP210X) += cp210x.o -obj-$(CONFIG_USB_SERIAL_CYBERJACK) += cyberjack.o -obj-$(CONFIG_USB_SERIAL_CYPRESS_M8) += cypress_m8.o -obj-$(CONFIG_USB_SERIAL_DEBUG) += usb_debug.o -obj-$(CONFIG_USB_SERIAL_DIGI_ACCELEPORT) += digi_acceleport.o -obj-$(CONFIG_USB_SERIAL_EDGEPORT) += io_edgeport.o -obj-$(CONFIG_USB_SERIAL_EDGEPORT_TI) += io_ti.o -obj-$(CONFIG_USB_SERIAL_EMPEG) += empeg.o -obj-$(CONFIG_USB_SERIAL_F81232) += f81232.o -obj-$(CONFIG_USB_SERIAL_FTDI_SIO) += ftdi_sio.o -obj-$(CONFIG_USB_SERIAL_FUNSOFT) += funsoft.o -obj-$(CONFIG_USB_SERIAL_GARMIN) += garmin_gps.o -obj-$(CONFIG_USB_SERIAL_HP4X) += hp4x.o -obj-$(CONFIG_USB_SERIAL_IPAQ) += ipaq.o -obj-$(CONFIG_USB_SERIAL_IPW) += ipw.o -obj-$(CONFIG_USB_SERIAL_IR) += ir-usb.o -obj-$(CONFIG_USB_SERIAL_IUU) += iuu_phoenix.o -obj-$(CONFIG_USB_SERIAL_KEYSPAN) += keyspan.o -obj-$(CONFIG_USB_SERIAL_KEYSPAN_PDA) += keyspan_pda.o -obj-$(CONFIG_USB_SERIAL_KLSI) += kl5kusb105.o -obj-$(CONFIG_USB_SERIAL_KOBIL_SCT) += kobil_sct.o -obj-$(CONFIG_USB_SERIAL_MCT_U232) += mct_u232.o -obj-$(CONFIG_USB_SERIAL_METRO) += metro-usb.o -obj-$(CONFIG_USB_SERIAL_MOS7720) += mos7720.o -obj-$(CONFIG_USB_SERIAL_MOS7840) += mos7840.o -obj-$(CONFIG_USB_SERIAL_MOTOROLA) += moto_modem.o -obj-$(CONFIG_USB_SERIAL_NAVMAN) += navman.o -obj-$(CONFIG_USB_SERIAL_OMNINET) += omninet.o -obj-$(CONFIG_USB_SERIAL_OPTICON) += opticon.o -obj-$(CONFIG_USB_SERIAL_OPTION) += option.o -obj-$(CONFIG_USB_SERIAL_OTI6858) += oti6858.o -obj-$(CONFIG_USB_SERIAL_PL2303) += pl2303.o -obj-$(CONFIG_USB_SERIAL_QCAUX) += qcaux.o -obj-$(CONFIG_USB_SERIAL_QUALCOMM) += qcserial.o -obj-$(CONFIG_USB_SERIAL_SAFE) += safe_serial.o -obj-$(CONFIG_USB_SERIAL_SIEMENS_MPI) += siemens_mpi.o -obj-$(CONFIG_USB_SERIAL_SIERRAWIRELESS) += sierra.o -obj-$(CONFIG_USB_SERIAL_SPCP8X5) += spcp8x5.o -obj-$(CONFIG_USB_SERIAL_SSU100) += ssu100.o -obj-$(CONFIG_USB_SERIAL_SYMBOL) += symbolserial.o -obj-$(CONFIG_USB_SERIAL_WWAN) += usb_wwan.o -obj-$(CONFIG_USB_SERIAL_TI) += ti_usb_3410_5052.o -obj-$(CONFIG_USB_SERIAL_VISOR) += visor.o -obj-$(CONFIG_USB_SERIAL_WHITEHEAT) += whiteheat.o -obj-$(CONFIG_USB_SERIAL_XIRCOM) += keyspan_pda.o -obj-$(CONFIG_USB_SERIAL_VIVOPAY_SERIAL) += vivopay-serial.o -obj-$(CONFIG_USB_SERIAL_ZIO) += zio.o -obj-m += via_option.o diff --git a/ANDROID_3.4.5/drivers/usb/serial/Makefile-keyspan_pda_fw b/ANDROID_3.4.5/drivers/usb/serial/Makefile-keyspan_pda_fw deleted file mode 100644 index c20baf72..00000000 --- a/ANDROID_3.4.5/drivers/usb/serial/Makefile-keyspan_pda_fw +++ /dev/null @@ -1,16 +0,0 @@ - -# some rules to handle the quirks of the 'as31' assembler, like -# insisting upon fixed suffixes for the input and output files, -# and its lack of preprocessor support - -all: keyspan_pda_fw.h - -%.asm: %.S - gcc -x assembler-with-cpp -P -E -o $@ $< - -%.hex: %.asm - as31 -l $< - mv $*.obj $@ - -%_fw.h: %.hex ezusb_convert.pl - perl ezusb_convert.pl $* < $< > $@ diff --git a/ANDROID_3.4.5/drivers/usb/serial/aircable.c b/ANDROID_3.4.5/drivers/usb/serial/aircable.c deleted file mode 100644 index eec4fb9a..00000000 --- a/ANDROID_3.4.5/drivers/usb/serial/aircable.c +++ /dev/null @@ -1,207 +0,0 @@ -/* - * AIRcable USB Bluetooth Dongle Driver. - * - * Copyright (C) 2010 Johan Hovold <jhovold@gmail.com> - * Copyright (C) 2006 Manuel Francisco Naranjo (naranjo.manuel@gmail.com) - * - * This program is free software; you can redistribute it and/or modify it under - * the terms of the GNU General Public License version 2 as published by the - * Free Software Foundation. - * - * The device works as an standard CDC device, it has 2 interfaces, the first - * one is for firmware access and the second is the serial one. - * The protocol is very simply, there are two posibilities reading or writing. - * When writing the first urb must have a Header that starts with 0x20 0x29 the - * next two bytes must say how much data will be sended. - * When reading the process is almost equal except that the header starts with - * 0x00 0x20. - * - * The device simply need some stuff to understand data coming from the usb - * buffer: The First and Second byte is used for a Header, the Third and Fourth - * tells the device the amount of information the package holds. - * Packages are 60 bytes long Header Stuff. - * When writing to the device the first two bytes of the header are 0x20 0x29 - * When reading the bytes are 0x00 0x20, or 0x00 0x10, there is an strange - * situation, when too much data arrives to the device because it sends the data - * but with out the header. I will use a simply hack to override this situation, - * if there is data coming that does not contain any header, then that is data - * that must go directly to the tty, as there is no documentation about if there - * is any other control code, I will simply check for the first - * one. - * - * The driver registers himself with the USB-serial core and the USB Core. I had - * to implement a probe function against USB-serial, because other way, the - * driver was attaching himself to both interfaces. I have tryed with different - * configurations of usb_serial_driver with out exit, only the probe function - * could handle this correctly. - * - * I have taken some info from a Greg Kroah-Hartman article: - * http://www.linuxjournal.com/article/6573 - * And from Linux Device Driver Kit CD, which is a great work, the authors taken - * the work to recompile lots of information an knowladge in drivers development - * and made it all avaible inside a cd. - * URL: http://kernel.org/pub/linux/kernel/people/gregkh/ddk/ - * - */ - -#include <asm/unaligned.h> -#include <linux/tty.h> -#include <linux/slab.h> -#include <linux/module.h> -#include <linux/tty_flip.h> -#include <linux/usb.h> -#include <linux/usb/serial.h> - -static bool debug; - -/* Vendor and Product ID */ -#define AIRCABLE_VID 0x16CA -#define AIRCABLE_USB_PID 0x1502 - -/* Protocol Stuff */ -#define HCI_HEADER_LENGTH 0x4 -#define TX_HEADER_0 0x20 -#define TX_HEADER_1 0x29 -#define RX_HEADER_0 0x00 -#define RX_HEADER_1 0x20 -#define HCI_COMPLETE_FRAME 64 - -/* rx_flags */ -#define THROTTLED 0x01 -#define ACTUALLY_THROTTLED 0x02 - -/* - * Version Information - */ -#define DRIVER_VERSION "v2.0" -#define DRIVER_AUTHOR "Naranjo, Manuel Francisco <naranjo.manuel@gmail.com>, Johan Hovold <jhovold@gmail.com>" -#define DRIVER_DESC "AIRcable USB Driver" - -/* ID table that will be registered with USB core */ -static const struct usb_device_id id_table[] = { - { USB_DEVICE(AIRCABLE_VID, AIRCABLE_USB_PID) }, - { }, -}; -MODULE_DEVICE_TABLE(usb, id_table); - -static int aircable_prepare_write_buffer(struct usb_serial_port *port, - void *dest, size_t size) -{ - int count; - unsigned char *buf = dest; - - count = kfifo_out_locked(&port->write_fifo, buf + HCI_HEADER_LENGTH, - size - HCI_HEADER_LENGTH, &port->lock); - buf[0] = TX_HEADER_0; - buf[1] = TX_HEADER_1; - put_unaligned_le16(count, &buf[2]); - - return count + HCI_HEADER_LENGTH; -} - -static int aircable_probe(struct usb_serial *serial, - const struct usb_device_id *id) -{ - struct usb_host_interface *iface_desc = serial->interface-> - cur_altsetting; - struct usb_endpoint_descriptor *endpoint; - int num_bulk_out = 0; - int i; - - for (i = 0; i < iface_desc->desc.bNumEndpoints; i++) { - endpoint = &iface_desc->endpoint[i].desc; - if (usb_endpoint_is_bulk_out(endpoint)) { - dbg("found bulk out on endpoint %d", i); - ++num_bulk_out; - } - } - - if (num_bulk_out == 0) { - dbg("Invalid interface, discarding"); - return -ENODEV; - } - - return 0; -} - -static int aircable_process_packet(struct tty_struct *tty, - struct usb_serial_port *port, int has_headers, - char *packet, int len) -{ - if (has_headers) { - len -= HCI_HEADER_LENGTH; - packet += HCI_HEADER_LENGTH; - } - if (len <= 0) { - dbg("%s - malformed packet", __func__); - return 0; - } - - tty_insert_flip_string(tty, packet, len); - - return len; -} - -static void aircable_process_read_urb(struct urb *urb) -{ - struct usb_serial_port *port = urb->context; - char *data = (char *)urb->transfer_buffer; - struct tty_struct *tty; - int has_headers; - int count; - int len; - int i; - - tty = tty_port_tty_get(&port->port); - if (!tty) - return; - - has_headers = (urb->actual_length > 2 && data[0] == RX_HEADER_0); - - count = 0; - for (i = 0; i < urb->actual_length; i += HCI_COMPLETE_FRAME) { - len = min_t(int, urb->actual_length - i, HCI_COMPLETE_FRAME); - count += aircable_process_packet(tty, port, has_headers, - &data[i], len); - } - - if (count) - tty_flip_buffer_push(tty); - tty_kref_put(tty); -} - -static struct usb_driver aircable_driver = { - .name = "aircable", - .probe = usb_serial_probe, - .disconnect = usb_serial_disconnect, - .id_table = id_table, -}; - -static struct usb_serial_driver aircable_device = { - .driver = { - .owner = THIS_MODULE, - .name = "aircable", - }, - .id_table = id_table, - .num_ports = 1, - .bulk_out_size = HCI_COMPLETE_FRAME, - .probe = aircable_probe, - .process_read_urb = aircable_process_read_urb, - .prepare_write_buffer = aircable_prepare_write_buffer, - .throttle = usb_serial_generic_throttle, - .unthrottle = usb_serial_generic_unthrottle, -}; - -static struct usb_serial_driver * const serial_drivers[] = { - &aircable_device, NULL -}; - -module_usb_serial_driver(aircable_driver, serial_drivers); - -MODULE_AUTHOR(DRIVER_AUTHOR); -MODULE_DESCRIPTION(DRIVER_DESC); -MODULE_VERSION(DRIVER_VERSION); -MODULE_LICENSE("GPL"); - -module_param(debug, bool, S_IRUGO | S_IWUSR); -MODULE_PARM_DESC(debug, "Debug enabled or not"); diff --git a/ANDROID_3.4.5/drivers/usb/serial/ark3116.c b/ANDROID_3.4.5/drivers/usb/serial/ark3116.c deleted file mode 100644 index f99f4710..00000000 --- a/ANDROID_3.4.5/drivers/usb/serial/ark3116.c +++ /dev/null @@ -1,859 +0,0 @@ -/* - * Copyright (C) 2009 by Bart Hartgers (bart.hartgers+ark3116@gmail.com) - * Original version: - * Copyright (C) 2006 - * Simon Schulz (ark3116_driver <at> auctionant.de) - * - * ark3116 - * - implements a driver for the arkmicro ark3116 chipset (vendor=0x6547, - * productid=0x0232) (used in a datacable called KQ-U8A) - * - * Supports full modem status lines, break, hardware flow control. Does not - * support software flow control, since I do not know how to enable it in hw. - * - * This driver is a essentially new implementation. I initially dug - * into the old ark3116.c driver and suddenly realized the ark3116 is - * a 16450 with a USB interface glued to it. See comments at the - * bottom of this 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. - */ - -#include <linux/kernel.h> -#include <linux/init.h> -#include <linux/ioctl.h> -#include <linux/tty.h> -#include <linux/slab.h> -#include <linux/tty_flip.h> -#include <linux/module.h> -#include <linux/usb.h> -#include <linux/usb/serial.h> -#include <linux/serial.h> -#include <linux/serial_reg.h> -#include <linux/uaccess.h> -#include <linux/mutex.h> -#include <linux/spinlock.h> - -static bool debug; -/* - * Version information - */ - -#define DRIVER_VERSION "v0.7" -#define DRIVER_AUTHOR "Bart Hartgers <bart.hartgers+ark3116@gmail.com>" -#define DRIVER_DESC "USB ARK3116 serial/IrDA driver" -#define DRIVER_DEV_DESC "ARK3116 RS232/IrDA" -#define DRIVER_NAME "ark3116" - -/* usb timeout of 1 second */ -#define ARK_TIMEOUT (1*HZ) - -static const struct usb_device_id id_table[] = { - { USB_DEVICE(0x6547, 0x0232) }, - { USB_DEVICE(0x18ec, 0x3118) }, /* USB to IrDA adapter */ - { }, -}; -MODULE_DEVICE_TABLE(usb, id_table); - -static int is_irda(struct usb_serial *serial) -{ - struct usb_device *dev = serial->dev; - if (le16_to_cpu(dev->descriptor.idVendor) == 0x18ec && - le16_to_cpu(dev->descriptor.idProduct) == 0x3118) - return 1; - return 0; -} - -struct ark3116_private { - wait_queue_head_t delta_msr_wait; - struct async_icount icount; - int irda; /* 1 for irda device */ - - /* protects hw register updates */ - struct mutex hw_lock; - - int quot; /* baudrate divisor */ - __u32 lcr; /* line control register value */ - __u32 hcr; /* handshake control register (0x8) - * value */ - __u32 mcr; /* modem contol register value */ - - /* protects the status values below */ - spinlock_t status_lock; - __u32 msr; /* modem status register value */ - __u32 lsr; /* line status register value */ -}; - -static int ark3116_write_reg(struct usb_serial *serial, - unsigned reg, __u8 val) -{ - int result; - /* 0xfe 0x40 are magic values taken from original driver */ - result = usb_control_msg(serial->dev, - usb_sndctrlpipe(serial->dev, 0), - 0xfe, 0x40, val, reg, - NULL, 0, ARK_TIMEOUT); - return result; -} - -static int ark3116_read_reg(struct usb_serial *serial, - unsigned reg, unsigned char *buf) -{ - int result; - /* 0xfe 0xc0 are magic values taken from original driver */ - result = usb_control_msg(serial->dev, - usb_rcvctrlpipe(serial->dev, 0), - 0xfe, 0xc0, 0, reg, - buf, 1, ARK_TIMEOUT); - if (result < 0) - return result; - else - return buf[0]; -} - -static inline int calc_divisor(int bps) -{ - /* Original ark3116 made some exceptions in rounding here - * because windows did the same. Assume that is not really - * necessary. - * Crystal is 12MHz, probably because of USB, but we divide by 4? - */ - return (12000000 + 2*bps) / (4*bps); -} - -static int ark3116_attach(struct usb_serial *serial) -{ - struct usb_serial_port *port = serial->port[0]; - struct ark3116_private *priv; - - /* make sure we have our end-points */ - if ((serial->num_bulk_in == 0) || - (serial->num_bulk_out == 0) || - (serial->num_interrupt_in == 0)) { - dev_err(&serial->dev->dev, - "%s - missing endpoint - " - "bulk in: %d, bulk out: %d, int in %d\n", - KBUILD_MODNAME, - serial->num_bulk_in, - serial->num_bulk_out, - serial->num_interrupt_in); - return -EINVAL; - } - - priv = kzalloc(sizeof(struct ark3116_private), - GFP_KERNEL); - if (!priv) - return -ENOMEM; - - init_waitqueue_head(&priv->delta_msr_wait); - mutex_init(&priv->hw_lock); - spin_lock_init(&priv->status_lock); - - priv->irda = is_irda(serial); - - usb_set_serial_port_data(port, priv); - - /* setup the hardware */ - ark3116_write_reg(serial, UART_IER, 0); - /* disable DMA */ - ark3116_write_reg(serial, UART_FCR, 0); - /* handshake control */ - priv->hcr = 0; - ark3116_write_reg(serial, 0x8 , 0); - /* modem control */ - priv->mcr = 0; - ark3116_write_reg(serial, UART_MCR, 0); - - if (!(priv->irda)) { - ark3116_write_reg(serial, 0xb , 0); - } else { - ark3116_write_reg(serial, 0xb , 1); - ark3116_write_reg(serial, 0xc , 0); - ark3116_write_reg(serial, 0xd , 0x41); - ark3116_write_reg(serial, 0xa , 1); - } - - /* setup baudrate */ - ark3116_write_reg(serial, UART_LCR, UART_LCR_DLAB); - - /* setup for 9600 8N1 */ - priv->quot = calc_divisor(9600); - ark3116_write_reg(serial, UART_DLL, priv->quot & 0xff); - ark3116_write_reg(serial, UART_DLM, (priv->quot>>8) & 0xff); - - priv->lcr = UART_LCR_WLEN8; - ark3116_write_reg(serial, UART_LCR, UART_LCR_WLEN8); - - ark3116_write_reg(serial, 0xe, 0); - - if (priv->irda) - ark3116_write_reg(serial, 0x9, 0); - - dev_info(&serial->dev->dev, - "%s using %s mode\n", - KBUILD_MODNAME, - priv->irda ? "IrDA" : "RS232"); - return 0; -} - -static void ark3116_release(struct usb_serial *serial) -{ - struct usb_serial_port *port = serial->port[0]; - struct ark3116_private *priv = usb_get_serial_port_data(port); - - /* device is closed, so URBs and DMA should be down */ - - usb_set_serial_port_data(port, NULL); - - mutex_destroy(&priv->hw_lock); - - kfree(priv); -} - -static void ark3116_init_termios(struct tty_struct *tty) -{ - struct ktermios *termios = tty->termios; - *termios = tty_std_termios; - termios->c_cflag = B9600 | CS8 - | CREAD | HUPCL | CLOCAL; - termios->c_ispeed = 9600; - termios->c_ospeed = 9600; -} - -static void ark3116_set_termios(struct tty_struct *tty, - struct usb_serial_port *port, - struct ktermios *old_termios) -{ - struct usb_serial *serial = port->serial; - struct ark3116_private *priv = usb_get_serial_port_data(port); - struct ktermios *termios = tty->termios; - unsigned int cflag = termios->c_cflag; - int bps = tty_get_baud_rate(tty); - int quot; - __u8 lcr, hcr, eval; - - /* set data bit count */ - switch (cflag & CSIZE) { - case CS5: - lcr = UART_LCR_WLEN5; - break; - case CS6: - lcr = UART_LCR_WLEN6; - break; - case CS7: - lcr = UART_LCR_WLEN7; - break; - default: - case CS8: - lcr = UART_LCR_WLEN8; - break; - } - if (cflag & CSTOPB) - lcr |= UART_LCR_STOP; - if (cflag & PARENB) - lcr |= UART_LCR_PARITY; - if (!(cflag & PARODD)) - lcr |= UART_LCR_EPAR; -#ifdef CMSPAR - if (cflag & CMSPAR) - lcr |= UART_LCR_SPAR; -#endif - /* handshake control */ - hcr = (cflag & CRTSCTS) ? 0x03 : 0x00; - - /* calc baudrate */ - dbg("%s - setting bps to %d", __func__, bps); - eval = 0; - switch (bps) { - case 0: - quot = calc_divisor(9600); - break; - default: - if ((bps < 75) || (bps > 3000000)) - bps = 9600; - quot = calc_divisor(bps); - break; - case 460800: - eval = 1; - quot = calc_divisor(bps); - break; - case 921600: - eval = 2; - quot = calc_divisor(bps); - break; - } - - /* Update state: synchronize */ - mutex_lock(&priv->hw_lock); - - /* keep old LCR_SBC bit */ - lcr |= (priv->lcr & UART_LCR_SBC); - - dbg("%s - setting hcr:0x%02x,lcr:0x%02x,quot:%d", - __func__, hcr, lcr, quot); - - /* handshake control */ - if (priv->hcr != hcr) { - priv->hcr = hcr; - ark3116_write_reg(serial, 0x8, hcr); - } - - /* baudrate */ - if (priv->quot != quot) { - priv->quot = quot; - priv->lcr = lcr; /* need to write lcr anyway */ - - /* disable DMA since transmit/receive is - * shadowed by UART_DLL - */ - ark3116_write_reg(serial, UART_FCR, 0); - - ark3116_write_reg(serial, UART_LCR, - lcr|UART_LCR_DLAB); - ark3116_write_reg(serial, UART_DLL, quot & 0xff); - ark3116_write_reg(serial, UART_DLM, (quot>>8) & 0xff); - - /* restore lcr */ - ark3116_write_reg(serial, UART_LCR, lcr); - /* magic baudrate thingy: not sure what it does, - * but windows does this as well. - */ - ark3116_write_reg(serial, 0xe, eval); - - /* enable DMA */ - ark3116_write_reg(serial, UART_FCR, UART_FCR_DMA_SELECT); - } else if (priv->lcr != lcr) { - priv->lcr = lcr; - ark3116_write_reg(serial, UART_LCR, lcr); - } - - mutex_unlock(&priv->hw_lock); - - /* check for software flow control */ - if (I_IXOFF(tty) || I_IXON(tty)) { - dev_warn(&serial->dev->dev, - "%s: don't know how to do software flow control\n", - KBUILD_MODNAME); - } - - /* Don't rewrite B0 */ - if (tty_termios_baud_rate(termios)) - tty_termios_encode_baud_rate(termios, bps, bps); -} - -static void ark3116_close(struct usb_serial_port *port) -{ - struct usb_serial *serial = port->serial; - - if (serial->dev) { - /* disable DMA */ - ark3116_write_reg(serial, UART_FCR, 0); - - /* deactivate interrupts */ - ark3116_write_reg(serial, UART_IER, 0); - - usb_serial_generic_close(port); - if (serial->num_interrupt_in) - usb_kill_urb(port->interrupt_in_urb); - } - -} - -static int ark3116_open(struct tty_struct *tty, struct usb_serial_port *port) -{ - struct ark3116_private *priv = usb_get_serial_port_data(port); - struct usb_serial *serial = port->serial; - unsigned char *buf; - int result; - - buf = kmalloc(1, GFP_KERNEL); - if (buf == NULL) - return -ENOMEM; - - result = usb_serial_generic_open(tty, port); - if (result) { - dbg("%s - usb_serial_generic_open failed: %d", - __func__, result); - goto err_out; - } - - /* remove any data still left: also clears error state */ - ark3116_read_reg(serial, UART_RX, buf); - - /* read modem status */ - priv->msr = ark3116_read_reg(serial, UART_MSR, buf); - /* read line status */ - priv->lsr = ark3116_read_reg(serial, UART_LSR, buf); - - result = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL); - if (result) { - dev_err(&port->dev, "submit irq_in urb failed %d\n", - result); - ark3116_close(port); - goto err_out; - } - - /* activate interrupts */ - ark3116_write_reg(port->serial, UART_IER, UART_IER_MSI|UART_IER_RLSI); - - /* enable DMA */ - ark3116_write_reg(port->serial, UART_FCR, UART_FCR_DMA_SELECT); - - /* setup termios */ - if (tty) - ark3116_set_termios(tty, port, NULL); - -err_out: - kfree(buf); - return result; -} - -static int ark3116_get_icount(struct tty_struct *tty, - struct serial_icounter_struct *icount) -{ - struct usb_serial_port *port = tty->driver_data; - struct ark3116_private *priv = usb_get_serial_port_data(port); - struct async_icount cnow = priv->icount; - icount->cts = cnow.cts; - icount->dsr = cnow.dsr; - icount->rng = cnow.rng; - icount->dcd = cnow.dcd; - icount->rx = cnow.rx; - icount->tx = cnow.tx; - icount->frame = cnow.frame; - icount->overrun = cnow.overrun; - icount->parity = cnow.parity; - icount->brk = cnow.brk; - icount->buf_overrun = cnow.buf_overrun; - return 0; -} - -static int ark3116_ioctl(struct tty_struct *tty, - unsigned int cmd, unsigned long arg) -{ - struct usb_serial_port *port = tty->driver_data; - struct ark3116_private *priv = usb_get_serial_port_data(port); - struct serial_struct serstruct; - void __user *user_arg = (void __user *)arg; - - switch (cmd) { - case TIOCGSERIAL: - /* XXX: Some of these values are probably wrong. */ - memset(&serstruct, 0, sizeof(serstruct)); - serstruct.type = PORT_16654; - serstruct.line = port->serial->minor; - serstruct.port = port->number; - serstruct.custom_divisor = 0; - serstruct.baud_base = 460800; - - if (copy_to_user(user_arg, &serstruct, sizeof(serstruct))) - return -EFAULT; - - return 0; - case TIOCSSERIAL: - if (copy_from_user(&serstruct, user_arg, sizeof(serstruct))) - return -EFAULT; - return 0; - case TIOCMIWAIT: - for (;;) { - struct async_icount prev = priv->icount; - interruptible_sleep_on(&priv->delta_msr_wait); - /* see if a signal did it */ - if (signal_pending(current)) - return -ERESTARTSYS; - if ((prev.rng == priv->icount.rng) && - (prev.dsr == priv->icount.dsr) && - (prev.dcd == priv->icount.dcd) && - (prev.cts == priv->icount.cts)) - return -EIO; - if ((arg & TIOCM_RNG && - (prev.rng != priv->icount.rng)) || - (arg & TIOCM_DSR && - (prev.dsr != priv->icount.dsr)) || - (arg & TIOCM_CD && - (prev.dcd != priv->icount.dcd)) || - (arg & TIOCM_CTS && - (prev.cts != priv->icount.cts))) - return 0; - } - break; - } - - return -ENOIOCTLCMD; -} - -static int ark3116_tiocmget(struct tty_struct *tty) -{ - struct usb_serial_port *port = tty->driver_data; - struct ark3116_private *priv = usb_get_serial_port_data(port); - __u32 status; - __u32 ctrl; - unsigned long flags; - - mutex_lock(&priv->hw_lock); - ctrl = priv->mcr; - mutex_unlock(&priv->hw_lock); - - spin_lock_irqsave(&priv->status_lock, flags); - status = priv->msr; - spin_unlock_irqrestore(&priv->status_lock, flags); - - return (status & UART_MSR_DSR ? TIOCM_DSR : 0) | - (status & UART_MSR_CTS ? TIOCM_CTS : 0) | - (status & UART_MSR_RI ? TIOCM_RI : 0) | - (status & UART_MSR_DCD ? TIOCM_CD : 0) | - (ctrl & UART_MCR_DTR ? TIOCM_DTR : 0) | - (ctrl & UART_MCR_RTS ? TIOCM_RTS : 0) | - (ctrl & UART_MCR_OUT1 ? TIOCM_OUT1 : 0) | - (ctrl & UART_MCR_OUT2 ? TIOCM_OUT2 : 0); -} - -static int ark3116_tiocmset(struct tty_struct *tty, - unsigned set, unsigned clr) -{ - struct usb_serial_port *port = tty->driver_data; - struct ark3116_private *priv = usb_get_serial_port_data(port); - - /* we need to take the mutex here, to make sure that the value - * in priv->mcr is actually the one that is in the hardware - */ - - mutex_lock(&priv->hw_lock); - - if (set & TIOCM_RTS) - priv->mcr |= UART_MCR_RTS; - if (set & TIOCM_DTR) - priv->mcr |= UART_MCR_DTR; - if (set & TIOCM_OUT1) - priv->mcr |= UART_MCR_OUT1; - if (set & TIOCM_OUT2) - priv->mcr |= UART_MCR_OUT2; - if (clr & TIOCM_RTS) - priv->mcr &= ~UART_MCR_RTS; - if (clr & TIOCM_DTR) - priv->mcr &= ~UART_MCR_DTR; - if (clr & TIOCM_OUT1) - priv->mcr &= ~UART_MCR_OUT1; - if (clr & TIOCM_OUT2) - priv->mcr &= ~UART_MCR_OUT2; - - ark3116_write_reg(port->serial, UART_MCR, priv->mcr); - - mutex_unlock(&priv->hw_lock); - - return 0; -} - -static void ark3116_break_ctl(struct tty_struct *tty, int break_state) -{ - struct usb_serial_port *port = tty->driver_data; - struct ark3116_private *priv = usb_get_serial_port_data(port); - - /* LCR is also used for other things: protect access */ - mutex_lock(&priv->hw_lock); - - if (break_state) - priv->lcr |= UART_LCR_SBC; - else - priv->lcr &= ~UART_LCR_SBC; - - ark3116_write_reg(port->serial, UART_LCR, priv->lcr); - - mutex_unlock(&priv->hw_lock); -} - -static void ark3116_update_msr(struct usb_serial_port *port, __u8 msr) -{ - struct ark3116_private *priv = usb_get_serial_port_data(port); - unsigned long flags; - - spin_lock_irqsave(&priv->status_lock, flags); - priv->msr = msr; - spin_unlock_irqrestore(&priv->status_lock, flags); - - if (msr & UART_MSR_ANY_DELTA) { - /* update input line counters */ - if (msr & UART_MSR_DCTS) - priv->icount.cts++; - if (msr & UART_MSR_DDSR) - priv->icount.dsr++; - if (msr & UART_MSR_DDCD) - priv->icount.dcd++; - if (msr & UART_MSR_TERI) - priv->icount.rng++; - wake_up_interruptible(&priv->delta_msr_wait); - } -} - -static void ark3116_update_lsr(struct usb_serial_port *port, __u8 lsr) -{ - struct ark3116_private *priv = usb_get_serial_port_data(port); - unsigned long flags; - - spin_lock_irqsave(&priv->status_lock, flags); - /* combine bits */ - priv->lsr |= lsr; - spin_unlock_irqrestore(&priv->status_lock, flags); - - if (lsr&UART_LSR_BRK_ERROR_BITS) { - if (lsr & UART_LSR_BI) - priv->icount.brk++; - if (lsr & UART_LSR_FE) - priv->icount.frame++; - if (lsr & UART_LSR_PE) - priv->icount.parity++; - if (lsr & UART_LSR_OE) - priv->icount.overrun++; - } -} - -static void ark3116_read_int_callback(struct urb *urb) -{ - struct usb_serial_port *port = urb->context; - int status = urb->status; - const __u8 *data = urb->transfer_buffer; - int result; - - switch (status) { - case -ECONNRESET: - case -ENOENT: - case -ESHUTDOWN: - /* this urb is terminated, clean up */ - dbg("%s - urb shutting down with status: %d", - __func__, status); - return; - default: - dbg("%s - nonzero urb status received: %d", - __func__, status); - break; - case 0: /* success */ - /* discovered this by trail and error... */ - if ((urb->actual_length == 4) && (data[0] == 0xe8)) { - const __u8 id = data[1]&UART_IIR_ID; - dbg("%s: iir=%02x", __func__, data[1]); - if (id == UART_IIR_MSI) { - dbg("%s: msr=%02x", __func__, data[3]); - ark3116_update_msr(port, data[3]); - break; - } else if (id == UART_IIR_RLSI) { - dbg("%s: lsr=%02x", __func__, data[2]); - ark3116_update_lsr(port, data[2]); - break; - } - } - /* - * Not sure what this data meant... - */ - usb_serial_debug_data(debug, &port->dev, - __func__, - urb->actual_length, - urb->transfer_buffer); - break; - } - - result = usb_submit_urb(urb, GFP_ATOMIC); - if (result) - dev_err(&urb->dev->dev, - "%s - Error %d submitting interrupt urb\n", - __func__, result); -} - - -/* Data comes in via the bulk (data) URB, erors/interrupts via the int URB. - * This means that we cannot be sure which data byte has an associated error - * condition, so we report an error for all data in the next bulk read. - * - * Actually, there might even be a window between the bulk data leaving the - * ark and reading/resetting the lsr in the read_bulk_callback where an - * interrupt for the next data block could come in. - * Without somekind of ordering on the ark, we would have to report the - * error for the next block of data as well... - * For now, let's pretend this can't happen. - */ -static void ark3116_process_read_urb(struct urb *urb) -{ - struct usb_serial_port *port = urb->context; - struct ark3116_private *priv = usb_get_serial_port_data(port); - struct tty_struct *tty; - unsigned char *data = urb->transfer_buffer; - char tty_flag = TTY_NORMAL; - unsigned long flags; - __u32 lsr; - - /* update line status */ - spin_lock_irqsave(&priv->status_lock, flags); - lsr = priv->lsr; - priv->lsr &= ~UART_LSR_BRK_ERROR_BITS; - spin_unlock_irqrestore(&priv->status_lock, flags); - - if (!urb->actual_length) - return; - - tty = tty_port_tty_get(&port->port); - if (!tty) - return; - - if (lsr & UART_LSR_BRK_ERROR_BITS) { - if (lsr & UART_LSR_BI) - tty_flag = TTY_BREAK; - else if (lsr & UART_LSR_PE) - tty_flag = TTY_PARITY; - else if (lsr & UART_LSR_FE) - tty_flag = TTY_FRAME; - - /* overrun is special, not associated with a char */ - if (lsr & UART_LSR_OE) - tty_insert_flip_char(tty, 0, TTY_OVERRUN); - } - tty_insert_flip_string_fixed_flag(tty, data, tty_flag, - urb->actual_length); - tty_flip_buffer_push(tty); - tty_kref_put(tty); -} - -static struct usb_driver ark3116_driver = { - .name = "ark3116", - .probe = usb_serial_probe, - .disconnect = usb_serial_disconnect, - .id_table = id_table, -}; - -static struct usb_serial_driver ark3116_device = { - .driver = { - .owner = THIS_MODULE, - .name = "ark3116", - }, - .id_table = id_table, - .num_ports = 1, - .attach = ark3116_attach, - .release = ark3116_release, - .set_termios = ark3116_set_termios, - .init_termios = ark3116_init_termios, - .ioctl = ark3116_ioctl, - .tiocmget = ark3116_tiocmget, - .tiocmset = ark3116_tiocmset, - .get_icount = ark3116_get_icount, - .open = ark3116_open, - .close = ark3116_close, - .break_ctl = ark3116_break_ctl, - .read_int_callback = ark3116_read_int_callback, - .process_read_urb = ark3116_process_read_urb, -}; - -static struct usb_serial_driver * const serial_drivers[] = { - &ark3116_device, NULL -}; - -module_usb_serial_driver(ark3116_driver, serial_drivers); - -MODULE_LICENSE("GPL"); - -MODULE_AUTHOR(DRIVER_AUTHOR); -MODULE_DESCRIPTION(DRIVER_DESC); - -module_param(debug, bool, S_IRUGO | S_IWUSR); -MODULE_PARM_DESC(debug, "Enable debug"); - -/* - * The following describes what I learned from studying the old - * ark3116.c driver, disassembling the windows driver, and some lucky - * guesses. Since I do not have any datasheet or other - * documentation, inaccuracies are almost guaranteed. - * - * Some specs for the ARK3116 can be found here: - * http://web.archive.org/web/20060318000438/ - * www.arkmicro.com/en/products/view.php?id=10 - * On that page, 2 GPIO pins are mentioned: I assume these are the - * OUT1 and OUT2 pins of the UART, so I added support for those - * through the MCR. Since the pins are not available on my hardware, - * I could not verify this. - * Also, it states there is "on-chip hardware flow control". I have - * discovered how to enable that. Unfortunately, I do not know how to - * enable XON/XOFF (software) flow control, which would need support - * from the chip as well to work. Because of the wording on the web - * page there is a real possibility the chip simply does not support - * software flow control. - * - * I got my ark3116 as part of a mobile phone adapter cable. On the - * PCB, the following numbered contacts are present: - * - * 1:- +5V - * 2:o DTR - * 3:i RX - * 4:i DCD - * 5:o RTS - * 6:o TX - * 7:i RI - * 8:i DSR - * 10:- 0V - * 11:i CTS - * - * On my chip, all signals seem to be 3.3V, but 5V tolerant. But that - * may be different for the one you have ;-). - * - * The windows driver limits the registers to 0-F, so I assume there - * are actually 16 present on the device. - * - * On an UART interrupt, 4 bytes of data come in on the interrupt - * endpoint. The bytes are 0xe8 IIR LSR MSR. - * - * The baudrate seems to be generated from the 12MHz crystal, using - * 4-times subsampling. So quot=12e6/(4*baud). Also see description - * of register E. - * - * Registers 0-7: - * These seem to be the same as for a regular 16450. The FCR is set - * to UART_FCR_DMA_SELECT (0x8), I guess to enable transfers between - * the UART and the USB bridge/DMA engine. - * - * Register 8: - * By trial and error, I found out that bit 0 enables hardware CTS, - * stopping TX when CTS is +5V. Bit 1 does the same for RTS, making - * RTS +5V when the 3116 cannot transfer the data to the USB bus - * (verified by disabling the reading URB). Note that as far as I can - * tell, the windows driver does NOT use this, so there might be some - * hardware bug or something. - * - * According to a patch provided here - * (http://lkml.org/lkml/2009/7/26/56), the ARK3116 can also be used - * as an IrDA dongle. Since I do not have such a thing, I could not - * investigate that aspect. However, I can speculate ;-). - * - * - IrDA encodes data differently than RS232. Most likely, one of - * the bits in registers 9..E enables the IR ENDEC (encoder/decoder). - * - Depending on the IR transceiver, the input and output need to be - * inverted, so there are probably bits for that as well. - * - IrDA is half-duplex, so there should be a bit for selecting that. - * - * This still leaves at least two registers unaccounted for. Perhaps - * The chip can do XON/XOFF or CRC in HW? - * - * Register 9: - * Set to 0x00 for IrDA, when the baudrate is initialised. - * - * Register A: - * Set to 0x01 for IrDA, at init. - * - * Register B: - * Set to 0x01 for IrDA, 0x00 for RS232, at init. - * - * Register C: - * Set to 00 for IrDA, at init. - * - * Register D: - * Set to 0x41 for IrDA, at init. - * - * Register E: - * Somekind of baudrate override. The windows driver seems to set - * this to 0x00 for normal baudrates, 0x01 for 460800, 0x02 for 921600. - * Since 460800 and 921600 cannot be obtained by dividing 3MHz by an integer, - * it could be somekind of subdivisor thingy. - * However,it does not seem to do anything: selecting 921600 (divisor 3, - * reg E=2), still gets 1 MHz. I also checked if registers 9, C or F would - * work, but they don't. - * - * Register F: unknown - */ diff --git a/ANDROID_3.4.5/drivers/usb/serial/belkin_sa.c b/ANDROID_3.4.5/drivers/usb/serial/belkin_sa.c deleted file mode 100644 index a52e0d2c..00000000 --- a/ANDROID_3.4.5/drivers/usb/serial/belkin_sa.c +++ /dev/null @@ -1,535 +0,0 @@ -/* - * Belkin USB Serial Adapter Driver - * - * Copyright (C) 2000 William Greathouse (wgreathouse@smva.com) - * Copyright (C) 2000-2001 Greg Kroah-Hartman (greg@kroah.com) - * Copyright (C) 2010 Johan Hovold (jhovold@gmail.com) - * - * This program is largely derived from work by the linux-usb group - * and associated source files. Please see the usb/serial files for - * individual credits and copyrights. - * - * 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. - * - * See Documentation/usb/usb-serial.txt for more information on using this - * driver - * - * TODO: - * -- Add true modem contol line query capability. Currently we track the - * states reported by the interrupt and the states we request. - * -- Add support for flush commands - */ - -#include <linux/kernel.h> -#include <linux/errno.h> -#include <linux/init.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/uaccess.h> -#include <linux/usb.h> -#include <linux/usb/serial.h> -#include "belkin_sa.h" - -static bool debug; - -/* - * Version Information - */ -#define DRIVER_VERSION "v1.3" -#define DRIVER_AUTHOR "William Greathouse <wgreathouse@smva.com>" -#define DRIVER_DESC "USB Belkin Serial converter driver" - -/* function prototypes for a Belkin USB Serial Adapter F5U103 */ -static int belkin_sa_startup(struct usb_serial *serial); -static void belkin_sa_release(struct usb_serial *serial); -static int belkin_sa_open(struct tty_struct *tty, - struct usb_serial_port *port); -static void belkin_sa_close(struct usb_serial_port *port); -static void belkin_sa_read_int_callback(struct urb *urb); -static void belkin_sa_process_read_urb(struct urb *urb); -static void belkin_sa_set_termios(struct tty_struct *tty, - struct usb_serial_port *port, struct ktermios * old); -static void belkin_sa_break_ctl(struct tty_struct *tty, int break_state); -static int belkin_sa_tiocmget(struct tty_struct *tty); -static int belkin_sa_tiocmset(struct tty_struct *tty, - unsigned int set, unsigned int clear); - - -static const struct usb_device_id id_table_combined[] = { - { USB_DEVICE(BELKIN_SA_VID, BELKIN_SA_PID) }, - { USB_DEVICE(BELKIN_OLD_VID, BELKIN_OLD_PID) }, - { USB_DEVICE(PERACOM_VID, PERACOM_PID) }, - { USB_DEVICE(GOHUBS_VID, GOHUBS_PID) }, - { USB_DEVICE(GOHUBS_VID, HANDYLINK_PID) }, - { USB_DEVICE(BELKIN_DOCKSTATION_VID, BELKIN_DOCKSTATION_PID) }, - { } /* Terminating entry */ -}; -MODULE_DEVICE_TABLE(usb, id_table_combined); - -static struct usb_driver belkin_driver = { - .name = "belkin", - .probe = usb_serial_probe, - .disconnect = usb_serial_disconnect, - .id_table = id_table_combined, -}; - -/* All of the device info needed for the serial converters */ -static struct usb_serial_driver belkin_device = { - .driver = { - .owner = THIS_MODULE, - .name = "belkin", - }, - .description = "Belkin / Peracom / GoHubs USB Serial Adapter", - .id_table = id_table_combined, - .num_ports = 1, - .open = belkin_sa_open, - .close = belkin_sa_close, - .read_int_callback = belkin_sa_read_int_callback, - .process_read_urb = belkin_sa_process_read_urb, - .set_termios = belkin_sa_set_termios, - .break_ctl = belkin_sa_break_ctl, - .tiocmget = belkin_sa_tiocmget, - .tiocmset = belkin_sa_tiocmset, - .attach = belkin_sa_startup, - .release = belkin_sa_release, -}; - -static struct usb_serial_driver * const serial_drivers[] = { - &belkin_device, NULL -}; - -struct belkin_sa_private { - spinlock_t lock; - unsigned long control_state; - unsigned char last_lsr; - unsigned char last_msr; - int bad_flow_control; -}; - - -/* - * *************************************************************************** - * Belkin USB Serial Adapter F5U103 specific driver functions - * *************************************************************************** - */ - -#define WDR_TIMEOUT 5000 /* default urb timeout */ - -/* assumes that struct usb_serial *serial is available */ -#define BSA_USB_CMD(c, v) usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0), \ - (c), BELKIN_SA_SET_REQUEST_TYPE, \ - (v), 0, NULL, 0, WDR_TIMEOUT) - -/* do some startup allocations not currently performed by usb_serial_probe() */ -static int belkin_sa_startup(struct usb_serial *serial) -{ - struct usb_device *dev = serial->dev; - struct belkin_sa_private *priv; - - /* allocate the private data structure */ - priv = kmalloc(sizeof(struct belkin_sa_private), GFP_KERNEL); - if (!priv) - return -1; /* error */ - /* set initial values for control structures */ - spin_lock_init(&priv->lock); - priv->control_state = 0; - priv->last_lsr = 0; - priv->last_msr = 0; - /* see comments at top of file */ - priv->bad_flow_control = - (le16_to_cpu(dev->descriptor.bcdDevice) <= 0x0206) ? 1 : 0; - dev_info(&dev->dev, "bcdDevice: %04x, bfc: %d\n", - le16_to_cpu(dev->descriptor.bcdDevice), - priv->bad_flow_control); - - init_waitqueue_head(&serial->port[0]->write_wait); - usb_set_serial_port_data(serial->port[0], priv); - - return 0; -} - -static void belkin_sa_release(struct usb_serial *serial) -{ - int i; - - dbg("%s", __func__); - - for (i = 0; i < serial->num_ports; ++i) - kfree(usb_get_serial_port_data(serial->port[i])); -} - -static int belkin_sa_open(struct tty_struct *tty, - struct usb_serial_port *port) -{ - int retval; - - dbg("%s port %d", __func__, port->number); - - retval = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL); - if (retval) { - dev_err(&port->dev, "usb_submit_urb(read int) failed\n"); - return retval; - } - - retval = usb_serial_generic_open(tty, port); - if (retval) - usb_kill_urb(port->interrupt_in_urb); - - return retval; -} - -static void belkin_sa_close(struct usb_serial_port *port) -{ - dbg("%s port %d", __func__, port->number); - - usb_serial_generic_close(port); - usb_kill_urb(port->interrupt_in_urb); -} - -static void belkin_sa_read_int_callback(struct urb *urb) -{ - struct usb_serial_port *port = urb->context; - struct belkin_sa_private *priv; - unsigned char *data = urb->transfer_buffer; - int retval; - int status = urb->status; - unsigned long flags; - - switch (status) { - case 0: - /* success */ - break; - case -ECONNRESET: - case -ENOENT: - case -ESHUTDOWN: - /* this urb is terminated, clean up */ - dbg("%s - urb shutting down with status: %d", - __func__, status); - return; - default: - dbg("%s - nonzero urb status received: %d", - __func__, status); - goto exit; - } - - usb_serial_debug_data(debug, &port->dev, __func__, - urb->actual_length, data); - - /* Handle known interrupt data */ - /* ignore data[0] and data[1] */ - - priv = usb_get_serial_port_data(port); - spin_lock_irqsave(&priv->lock, flags); - priv->last_msr = data[BELKIN_SA_MSR_INDEX]; - - /* Record Control Line states */ - if (priv->last_msr & BELKIN_SA_MSR_DSR) - priv->control_state |= TIOCM_DSR; - else - priv->control_state &= ~TIOCM_DSR; - - if (priv->last_msr & BELKIN_SA_MSR_CTS) - priv->control_state |= TIOCM_CTS; - else - priv->control_state &= ~TIOCM_CTS; - - if (priv->last_msr & BELKIN_SA_MSR_RI) - priv->control_state |= TIOCM_RI; - else - priv->control_state &= ~TIOCM_RI; - - if (priv->last_msr & BELKIN_SA_MSR_CD) - priv->control_state |= TIOCM_CD; - else - priv->control_state &= ~TIOCM_CD; - - priv->last_lsr = data[BELKIN_SA_LSR_INDEX]; - spin_unlock_irqrestore(&priv->lock, flags); -exit: - retval = usb_submit_urb(urb, GFP_ATOMIC); - if (retval) - dev_err(&port->dev, "%s - usb_submit_urb failed with " - "result %d\n", __func__, retval); -} - -static void belkin_sa_process_read_urb(struct urb *urb) -{ - struct usb_serial_port *port = urb->context; - struct belkin_sa_private *priv = usb_get_serial_port_data(port); - struct tty_struct *tty; - unsigned char *data = urb->transfer_buffer; - unsigned long flags; - unsigned char status; - char tty_flag; - - /* Update line status */ - tty_flag = TTY_NORMAL; - - spin_lock_irqsave(&priv->lock, flags); - status = priv->last_lsr; - priv->last_lsr &= ~BELKIN_SA_LSR_ERR; - spin_unlock_irqrestore(&priv->lock, flags); - - if (!urb->actual_length) - return; - - tty = tty_port_tty_get(&port->port); - if (!tty) - return; - - if (status & BELKIN_SA_LSR_ERR) { - /* Break takes precedence over parity, which takes precedence - * over framing errors. */ - if (status & BELKIN_SA_LSR_BI) - tty_flag = TTY_BREAK; - else if (status & BELKIN_SA_LSR_PE) - tty_flag = TTY_PARITY; - else if (status & BELKIN_SA_LSR_FE) - tty_flag = TTY_FRAME; - dev_dbg(&port->dev, "tty_flag = %d\n", tty_flag); - - /* Overrun is special, not associated with a char. */ - if (status & BELKIN_SA_LSR_OE) - tty_insert_flip_char(tty, 0, TTY_OVERRUN); - } - - tty_insert_flip_string_fixed_flag(tty, data, tty_flag, - urb->actual_length); - tty_flip_buffer_push(tty); - tty_kref_put(tty); -} - -static void belkin_sa_set_termios(struct tty_struct *tty, - struct usb_serial_port *port, struct ktermios *old_termios) -{ - struct usb_serial *serial = port->serial; - struct belkin_sa_private *priv = usb_get_serial_port_data(port); - unsigned int iflag; - unsigned int cflag; - unsigned int old_iflag = 0; - unsigned int old_cflag = 0; - __u16 urb_value = 0; /* Will hold the new flags */ - unsigned long flags; - unsigned long control_state; - int bad_flow_control; - speed_t baud; - struct ktermios *termios = tty->termios; - - iflag = termios->c_iflag; - cflag = termios->c_cflag; - - termios->c_cflag &= ~CMSPAR; - - /* get a local copy of the current port settings */ - spin_lock_irqsave(&priv->lock, flags); - control_state = priv->control_state; - bad_flow_control = priv->bad_flow_control; - spin_unlock_irqrestore(&priv->lock, flags); - - old_iflag = old_termios->c_iflag; - old_cflag = old_termios->c_cflag; - - /* Set the baud rate */ - if ((cflag & CBAUD) != (old_cflag & CBAUD)) { - /* reassert DTR and (maybe) RTS on transition from B0 */ - if ((old_cflag & CBAUD) == B0) { - control_state |= (TIOCM_DTR|TIOCM_RTS); - if (BSA_USB_CMD(BELKIN_SA_SET_DTR_REQUEST, 1) < 0) - dev_err(&port->dev, "Set DTR error\n"); - /* don't set RTS if using hardware flow control */ - if (!(old_cflag & CRTSCTS)) - if (BSA_USB_CMD(BELKIN_SA_SET_RTS_REQUEST - , 1) < 0) - dev_err(&port->dev, "Set RTS error\n"); - } - } - - baud = tty_get_baud_rate(tty); - if (baud) { - urb_value = BELKIN_SA_BAUD(baud); - /* Clip to maximum speed */ - if (urb_value == 0) - urb_value = 1; - /* Turn it back into a resulting real baud rate */ - baud = BELKIN_SA_BAUD(urb_value); - - /* Report the actual baud rate back to the caller */ - tty_encode_baud_rate(tty, baud, baud); - if (BSA_USB_CMD(BELKIN_SA_SET_BAUDRATE_REQUEST, urb_value) < 0) - dev_err(&port->dev, "Set baudrate error\n"); - } else { - /* Disable flow control */ - if (BSA_USB_CMD(BELKIN_SA_SET_FLOW_CTRL_REQUEST, - BELKIN_SA_FLOW_NONE) < 0) - dev_err(&port->dev, "Disable flowcontrol error\n"); - /* Drop RTS and DTR */ - control_state &= ~(TIOCM_DTR | TIOCM_RTS); - if (BSA_USB_CMD(BELKIN_SA_SET_DTR_REQUEST, 0) < 0) - dev_err(&port->dev, "DTR LOW error\n"); - if (BSA_USB_CMD(BELKIN_SA_SET_RTS_REQUEST, 0) < 0) - dev_err(&port->dev, "RTS LOW error\n"); - } - - /* set the parity */ - if ((cflag ^ old_cflag) & (PARENB | PARODD)) { - if (cflag & PARENB) - urb_value = (cflag & PARODD) ? BELKIN_SA_PARITY_ODD - : BELKIN_SA_PARITY_EVEN; - else - urb_value = BELKIN_SA_PARITY_NONE; - if (BSA_USB_CMD(BELKIN_SA_SET_PARITY_REQUEST, urb_value) < 0) - dev_err(&port->dev, "Set parity error\n"); - } - - /* set the number of data bits */ - if ((cflag & CSIZE) != (old_cflag & CSIZE)) { - switch (cflag & CSIZE) { - case CS5: - urb_value = BELKIN_SA_DATA_BITS(5); - break; - case CS6: - urb_value = BELKIN_SA_DATA_BITS(6); - break; - case CS7: - urb_value = BELKIN_SA_DATA_BITS(7); - break; - case CS8: - urb_value = BELKIN_SA_DATA_BITS(8); - break; - default: dbg("CSIZE was not CS5-CS8, using default of 8"); - urb_value = BELKIN_SA_DATA_BITS(8); - break; - } - if (BSA_USB_CMD(BELKIN_SA_SET_DATA_BITS_REQUEST, urb_value) < 0) - dev_err(&port->dev, "Set data bits error\n"); - } - - /* set the number of stop bits */ - if ((cflag & CSTOPB) != (old_cflag & CSTOPB)) { - urb_value = (cflag & CSTOPB) ? BELKIN_SA_STOP_BITS(2) - : BELKIN_SA_STOP_BITS(1); - if (BSA_USB_CMD(BELKIN_SA_SET_STOP_BITS_REQUEST, - urb_value) < 0) - dev_err(&port->dev, "Set stop bits error\n"); - } - - /* Set flow control */ - if (((iflag ^ old_iflag) & (IXOFF | IXON)) || - ((cflag ^ old_cflag) & CRTSCTS)) { - urb_value = 0; - if ((iflag & IXOFF) || (iflag & IXON)) - urb_value |= (BELKIN_SA_FLOW_OXON | BELKIN_SA_FLOW_IXON); - else - urb_value &= ~(BELKIN_SA_FLOW_OXON | BELKIN_SA_FLOW_IXON); - - if (cflag & CRTSCTS) - urb_value |= (BELKIN_SA_FLOW_OCTS | BELKIN_SA_FLOW_IRTS); - else - urb_value &= ~(BELKIN_SA_FLOW_OCTS | BELKIN_SA_FLOW_IRTS); - - if (bad_flow_control) - urb_value &= ~(BELKIN_SA_FLOW_IRTS); - - if (BSA_USB_CMD(BELKIN_SA_SET_FLOW_CTRL_REQUEST, urb_value) < 0) - dev_err(&port->dev, "Set flow control error\n"); - } - - /* save off the modified port settings */ - spin_lock_irqsave(&priv->lock, flags); - priv->control_state = control_state; - spin_unlock_irqrestore(&priv->lock, flags); -} - -static void belkin_sa_break_ctl(struct tty_struct *tty, int break_state) -{ - struct usb_serial_port *port = tty->driver_data; - struct usb_serial *serial = port->serial; - - if (BSA_USB_CMD(BELKIN_SA_SET_BREAK_REQUEST, break_state ? 1 : 0) < 0) - dev_err(&port->dev, "Set break_ctl %d\n", break_state); -} - -static int belkin_sa_tiocmget(struct tty_struct *tty) -{ - struct usb_serial_port *port = tty->driver_data; - struct belkin_sa_private *priv = usb_get_serial_port_data(port); - unsigned long control_state; - unsigned long flags; - - dbg("%s", __func__); - - spin_lock_irqsave(&priv->lock, flags); - control_state = priv->control_state; - spin_unlock_irqrestore(&priv->lock, flags); - - return control_state; -} - -static int belkin_sa_tiocmset(struct tty_struct *tty, - unsigned int set, unsigned int clear) -{ - struct usb_serial_port *port = tty->driver_data; - struct usb_serial *serial = port->serial; - struct belkin_sa_private *priv = usb_get_serial_port_data(port); - unsigned long control_state; - unsigned long flags; - int retval; - int rts = 0; - int dtr = 0; - - dbg("%s", __func__); - - spin_lock_irqsave(&priv->lock, flags); - control_state = priv->control_state; - - if (set & TIOCM_RTS) { - control_state |= TIOCM_RTS; - rts = 1; - } - if (set & TIOCM_DTR) { - control_state |= TIOCM_DTR; - dtr = 1; - } - if (clear & TIOCM_RTS) { - control_state &= ~TIOCM_RTS; - rts = 0; - } - if (clear & TIOCM_DTR) { - control_state &= ~TIOCM_DTR; - dtr = 0; - } - - priv->control_state = control_state; - spin_unlock_irqrestore(&priv->lock, flags); - - retval = BSA_USB_CMD(BELKIN_SA_SET_RTS_REQUEST, rts); - if (retval < 0) { - dev_err(&port->dev, "Set RTS error %d\n", retval); - goto exit; - } - - retval = BSA_USB_CMD(BELKIN_SA_SET_DTR_REQUEST, dtr); - if (retval < 0) { - dev_err(&port->dev, "Set DTR error %d\n", retval); - goto exit; - } -exit: - return retval; -} - -module_usb_serial_driver(belkin_driver, serial_drivers); - -MODULE_AUTHOR(DRIVER_AUTHOR); -MODULE_DESCRIPTION(DRIVER_DESC); -MODULE_VERSION(DRIVER_VERSION); -MODULE_LICENSE("GPL"); - -module_param(debug, bool, S_IRUGO | S_IWUSR); -MODULE_PARM_DESC(debug, "Debug enabled or not"); diff --git a/ANDROID_3.4.5/drivers/usb/serial/belkin_sa.h b/ANDROID_3.4.5/drivers/usb/serial/belkin_sa.h deleted file mode 100644 index c74b58ab..00000000 --- a/ANDROID_3.4.5/drivers/usb/serial/belkin_sa.h +++ /dev/null @@ -1,124 +0,0 @@ -/* - * Definitions for Belkin USB Serial Adapter Driver - * - * Copyright (C) 2000 - * William Greathouse (wgreathouse@smva.com) - * - * This program is largely derived from work by the linux-usb group - * and associated source files. Please see the usb/serial files for - * individual credits and copyrights. - * - * 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. - * - * See Documentation/usb/usb-serial.txt for more information on using this - * driver - * - * 12-Mar-2001 gkh - * Added GoHubs GO-COM232 device id. - * - * 06-Nov-2000 gkh - * Added old Belkin and Peracom device ids, which this driver supports - * - * 12-Oct-2000 William Greathouse - * First cut at supporting Belkin USB Serial Adapter F5U103 - * I did not have a copy of the original work to support this - * adapter, so pardon any stupid mistakes. All of the information - * I am using to write this driver was acquired by using a modified - * UsbSnoop on Windows2000. - * - */ - -#ifndef __LINUX_USB_SERIAL_BSA_H -#define __LINUX_USB_SERIAL_BSA_H - -#define BELKIN_DOCKSTATION_VID 0x050d /* Vendor Id */ -#define BELKIN_DOCKSTATION_PID 0x1203 /* Product Id */ - -#define BELKIN_SA_VID 0x050d /* Vendor Id */ -#define BELKIN_SA_PID 0x0103 /* Product Id */ - -#define BELKIN_OLD_VID 0x056c /* Belkin's "old" vendor id */ -#define BELKIN_OLD_PID 0x8007 /* Belkin's "old" single port serial converter's id */ - -#define PERACOM_VID 0x0565 /* Peracom's vendor id */ -#define PERACOM_PID 0x0001 /* Peracom's single port serial converter's id */ - -#define GOHUBS_VID 0x0921 /* GoHubs vendor id */ -#define GOHUBS_PID 0x1000 /* GoHubs single port serial converter's id (identical to the Peracom device) */ -#define HANDYLINK_PID 0x1200 /* HandyLink USB's id (identical to the Peracom device) */ - -/* Vendor Request Interface */ -#define BELKIN_SA_SET_BAUDRATE_REQUEST 0 /* Set baud rate */ -#define BELKIN_SA_SET_STOP_BITS_REQUEST 1 /* Set stop bits (1,2) */ -#define BELKIN_SA_SET_DATA_BITS_REQUEST 2 /* Set data bits (5,6,7,8) */ -#define BELKIN_SA_SET_PARITY_REQUEST 3 /* Set parity (None, Even, Odd) */ - -#define BELKIN_SA_SET_DTR_REQUEST 10 /* Set DTR state */ -#define BELKIN_SA_SET_RTS_REQUEST 11 /* Set RTS state */ -#define BELKIN_SA_SET_BREAK_REQUEST 12 /* Set BREAK state */ - -#define BELKIN_SA_SET_FLOW_CTRL_REQUEST 16 /* Set flow control mode */ - - -#ifdef WHEN_I_LEARN_THIS -#define BELKIN_SA_SET_MAGIC_REQUEST 17 /* I don't know, possibly flush */ - /* (always in Wininit sequence before flow control) */ -#define BELKIN_SA_RESET xx /* Reset the port */ -#define BELKIN_SA_GET_MODEM_STATUS xx /* Force return of modem status register */ -#endif - -#define BELKIN_SA_SET_REQUEST_TYPE 0x40 - -#define BELKIN_SA_BAUD(b) (230400/b) - -#define BELKIN_SA_STOP_BITS(b) (b-1) - -#define BELKIN_SA_DATA_BITS(b) (b-5) - -#define BELKIN_SA_PARITY_NONE 0 -#define BELKIN_SA_PARITY_EVEN 1 -#define BELKIN_SA_PARITY_ODD 2 -#define BELKIN_SA_PARITY_MARK 3 -#define BELKIN_SA_PARITY_SPACE 4 - -#define BELKIN_SA_FLOW_NONE 0x0000 /* No flow control */ -#define BELKIN_SA_FLOW_OCTS 0x0001 /* use CTS input to throttle output */ -#define BELKIN_SA_FLOW_ODSR 0x0002 /* use DSR input to throttle output */ -#define BELKIN_SA_FLOW_IDSR 0x0004 /* use DSR input to enable receive */ -#define BELKIN_SA_FLOW_IDTR 0x0008 /* use DTR output for input flow control */ -#define BELKIN_SA_FLOW_IRTS 0x0010 /* use RTS output for input flow control */ -#define BELKIN_SA_FLOW_ORTS 0x0020 /* use RTS to indicate data available to send */ -#define BELKIN_SA_FLOW_ERRSUB 0x0040 /* ???? guess ???? substitute inline errors */ -#define BELKIN_SA_FLOW_OXON 0x0080 /* use XON/XOFF for output flow control */ -#define BELKIN_SA_FLOW_IXON 0x0100 /* use XON/XOFF for input flow control */ - -/* - * It seems that the interrupt pipe is closely modelled after the - * 16550 register layout. This is probably because the adapter can - * be used in a "DOS" environment to simulate a standard hardware port. - */ -#define BELKIN_SA_LSR_INDEX 2 /* Line Status Register */ -#define BELKIN_SA_LSR_RDR 0x01 /* receive data ready */ -#define BELKIN_SA_LSR_OE 0x02 /* overrun error */ -#define BELKIN_SA_LSR_PE 0x04 /* parity error */ -#define BELKIN_SA_LSR_FE 0x08 /* framing error */ -#define BELKIN_SA_LSR_BI 0x10 /* break indicator */ -#define BELKIN_SA_LSR_THE 0x20 /* tx holding register empty */ -#define BELKIN_SA_LSR_TE 0x40 /* transmit register empty */ -#define BELKIN_SA_LSR_ERR 0x80 /* OE | PE | FE | BI */ - -#define BELKIN_SA_MSR_INDEX 3 /* Modem Status Register */ -#define BELKIN_SA_MSR_DCTS 0x01 /* Delta CTS */ -#define BELKIN_SA_MSR_DDSR 0x02 /* Delta DSR */ -#define BELKIN_SA_MSR_DRI 0x04 /* Delta RI */ -#define BELKIN_SA_MSR_DCD 0x08 /* Delta CD */ -#define BELKIN_SA_MSR_CTS 0x10 /* Current CTS */ -#define BELKIN_SA_MSR_DSR 0x20 /* Current DSR */ -#define BELKIN_SA_MSR_RI 0x40 /* Current RI */ -#define BELKIN_SA_MSR_CD 0x80 /* Current CD */ - -#endif /* __LINUX_USB_SERIAL_BSA_H */ - diff --git a/ANDROID_3.4.5/drivers/usb/serial/bus.c b/ANDROID_3.4.5/drivers/usb/serial/bus.c deleted file mode 100644 index ed8adb05..00000000 --- a/ANDROID_3.4.5/drivers/usb/serial/bus.c +++ /dev/null @@ -1,179 +0,0 @@ -/* - * USB Serial Converter Bus specific functions - * - * Copyright (C) 2002 Greg Kroah-Hartman (greg@kroah.com) - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License version - * 2 as published by the Free Software Foundation. - */ - -#include <linux/kernel.h> -#include <linux/errno.h> -#include <linux/tty.h> -#include <linux/slab.h> -#include <linux/module.h> -#include <linux/usb.h> -#include <linux/usb/serial.h> - -static int usb_serial_device_match(struct device *dev, - struct device_driver *drv) -{ - struct usb_serial_driver *driver; - const struct usb_serial_port *port; - - /* - * drivers are already assigned to ports in serial_probe so it's - * a simple check here. - */ - port = to_usb_serial_port(dev); - if (!port) - return 0; - - driver = to_usb_serial_driver(drv); - - if (driver == port->serial->type) - return 1; - - return 0; -} - -static ssize_t show_port_number(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct usb_serial_port *port = to_usb_serial_port(dev); - - return sprintf(buf, "%d\n", port->number - port->serial->minor); -} - -static DEVICE_ATTR(port_number, S_IRUGO, show_port_number, NULL); - -static int usb_serial_device_probe(struct device *dev) -{ - struct usb_serial_driver *driver; - struct usb_serial_port *port; - int retval = 0; - int minor; - - port = to_usb_serial_port(dev); - if (!port) { - retval = -ENODEV; - goto exit; - } - - driver = port->serial->type; - if (driver->port_probe) { - retval = driver->port_probe(port); - if (retval) - goto exit; - } - - retval = device_create_file(dev, &dev_attr_port_number); - if (retval) { - if (driver->port_remove) - retval = driver->port_remove(port); - goto exit; - } - - minor = port->number; - tty_register_device(usb_serial_tty_driver, minor, dev); - dev_info(&port->serial->dev->dev, - "%s converter now attached to ttyUSB%d\n", - driver->description, minor); - -exit: - return retval; -} - -static int usb_serial_device_remove(struct device *dev) -{ - struct usb_serial_driver *driver; - struct usb_serial_port *port; - int retval = 0; - int minor; - - port = to_usb_serial_port(dev); - if (!port) - return -ENODEV; - - device_remove_file(&port->dev, &dev_attr_port_number); - - driver = port->serial->type; - if (driver->port_remove) - retval = driver->port_remove(port); - - minor = port->number; - tty_unregister_device(usb_serial_tty_driver, minor); - dev_info(dev, "%s converter now disconnected from ttyUSB%d\n", - driver->description, minor); - - return retval; -} - -#ifdef CONFIG_HOTPLUG -static ssize_t store_new_id(struct device_driver *driver, - const char *buf, size_t count) -{ - struct usb_serial_driver *usb_drv = to_usb_serial_driver(driver); - ssize_t retval = usb_store_new_id(&usb_drv->dynids, driver, buf, count); - - if (retval >= 0 && usb_drv->usb_driver != NULL) - retval = usb_store_new_id(&usb_drv->usb_driver->dynids, - &usb_drv->usb_driver->drvwrap.driver, - buf, count); - return retval; -} - -static struct driver_attribute drv_attrs[] = { - __ATTR(new_id, S_IWUSR, NULL, store_new_id), - __ATTR_NULL, -}; - -static void free_dynids(struct usb_serial_driver *drv) -{ - struct usb_dynid *dynid, *n; - - spin_lock(&drv->dynids.lock); - list_for_each_entry_safe(dynid, n, &drv->dynids.list, node) { - list_del(&dynid->node); - kfree(dynid); - } - spin_unlock(&drv->dynids.lock); -} - -#else -static struct driver_attribute drv_attrs[] = { - __ATTR_NULL, -}; -static inline void free_dynids(struct usb_serial_driver *drv) -{ -} -#endif - -struct bus_type usb_serial_bus_type = { - .name = "usb-serial", - .match = usb_serial_device_match, - .probe = usb_serial_device_probe, - .remove = usb_serial_device_remove, - .drv_attrs = drv_attrs, -}; - -int usb_serial_bus_register(struct usb_serial_driver *driver) -{ - int retval; - - driver->driver.bus = &usb_serial_bus_type; - spin_lock_init(&driver->dynids.lock); - INIT_LIST_HEAD(&driver->dynids.list); - - retval = driver_register(&driver->driver); - - return retval; -} - -void usb_serial_bus_deregister(struct usb_serial_driver *driver) -{ - free_dynids(driver); - driver_unregister(&driver->driver); -} - diff --git a/ANDROID_3.4.5/drivers/usb/serial/ch341.c b/ANDROID_3.4.5/drivers/usb/serial/ch341.c deleted file mode 100644 index aaab32db..00000000 --- a/ANDROID_3.4.5/drivers/usb/serial/ch341.c +++ /dev/null @@ -1,660 +0,0 @@ -/* - * Copyright 2007, Frank A Kingswood <frank@kingswood-consulting.co.uk> - * Copyright 2007, Werner Cornelius <werner@cornelius-consult.de> - * Copyright 2009, Boris Hajduk <boris@hajduk.org> - * - * ch341.c implements a serial port driver for the Winchiphead CH341. - * - * The CH341 device can be used to implement an RS232 asynchronous - * serial port, an IEEE-1284 parallel printer port or a memory-like - * interface. In all cases the CH341 supports an I2C interface as well. - * This driver only supports the asynchronous serial interface. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License version - * 2 as published by the Free Software Foundation. - */ - -#include <linux/kernel.h> -#include <linux/init.h> -#include <linux/tty.h> -#include <linux/module.h> -#include <linux/slab.h> -#include <linux/usb.h> -#include <linux/usb/serial.h> -#include <linux/serial.h> -#include <asm/unaligned.h> - -#define DEFAULT_BAUD_RATE 9600 -#define DEFAULT_TIMEOUT 1000 - -/* flags for IO-Bits */ -#define CH341_BIT_RTS (1 << 6) -#define CH341_BIT_DTR (1 << 5) - -/******************************/ -/* interrupt pipe definitions */ -/******************************/ -/* always 4 interrupt bytes */ -/* first irq byte normally 0x08 */ -/* second irq byte base 0x7d + below */ -/* third irq byte base 0x94 + below */ -/* fourth irq byte normally 0xee */ - -/* second interrupt byte */ -#define CH341_MULT_STAT 0x04 /* multiple status since last interrupt event */ - -/* status returned in third interrupt answer byte, inverted in data - from irq */ -#define CH341_BIT_CTS 0x01 -#define CH341_BIT_DSR 0x02 -#define CH341_BIT_RI 0x04 -#define CH341_BIT_DCD 0x08 -#define CH341_BITS_MODEM_STAT 0x0f /* all bits */ - -/*******************************/ -/* baudrate calculation factor */ -/*******************************/ -#define CH341_BAUDBASE_FACTOR 1532620800 -#define CH341_BAUDBASE_DIVMAX 3 - -/* Break support - the information used to implement this was gleaned from - * the Net/FreeBSD uchcom.c driver by Takanori Watanabe. Domo arigato. - */ - -#define CH341_REQ_WRITE_REG 0x9A -#define CH341_REQ_READ_REG 0x95 -#define CH341_REG_BREAK1 0x05 -#define CH341_REG_BREAK2 0x18 -#define CH341_NBREAK_BITS_REG1 0x01 -#define CH341_NBREAK_BITS_REG2 0x40 - - -static bool debug; - -static const struct usb_device_id id_table[] = { - { USB_DEVICE(0x4348, 0x5523) }, - { USB_DEVICE(0x1a86, 0x7523) }, - { USB_DEVICE(0x1a86, 0x5523) }, - { }, -}; -MODULE_DEVICE_TABLE(usb, id_table); - -struct ch341_private { - spinlock_t lock; /* access lock */ - wait_queue_head_t delta_msr_wait; /* wait queue for modem status */ - unsigned baud_rate; /* set baud rate */ - u8 line_control; /* set line control value RTS/DTR */ - u8 line_status; /* active status of modem control inputs */ - u8 multi_status_change; /* status changed multiple since last call */ -}; - -static int ch341_control_out(struct usb_device *dev, u8 request, - u16 value, u16 index) -{ - int r; - dbg("ch341_control_out(%02x,%02x,%04x,%04x)", USB_DIR_OUT|0x40, - (int)request, (int)value, (int)index); - - r = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), request, - USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_OUT, - value, index, NULL, 0, DEFAULT_TIMEOUT); - - return r; -} - -static int ch341_control_in(struct usb_device *dev, - u8 request, u16 value, u16 index, - char *buf, unsigned bufsize) -{ - int r; - dbg("ch341_control_in(%02x,%02x,%04x,%04x,%p,%u)", USB_DIR_IN|0x40, - (int)request, (int)value, (int)index, buf, (int)bufsize); - - r = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), request, - USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN, - value, index, buf, bufsize, DEFAULT_TIMEOUT); - return r; -} - -static int ch341_set_baudrate(struct usb_device *dev, - struct ch341_private *priv) -{ - short a, b; - int r; - unsigned long factor; - short divisor; - - dbg("ch341_set_baudrate(%d)", priv->baud_rate); - - if (!priv->baud_rate) - return -EINVAL; - factor = (CH341_BAUDBASE_FACTOR / priv->baud_rate); - divisor = CH341_BAUDBASE_DIVMAX; - - while ((factor > 0xfff0) && divisor) { - factor >>= 3; - divisor--; - } - - if (factor > 0xfff0) - return -EINVAL; - - factor = 0x10000 - factor; - a = (factor & 0xff00) | divisor; - b = factor & 0xff; - - r = ch341_control_out(dev, 0x9a, 0x1312, a); - if (!r) - r = ch341_control_out(dev, 0x9a, 0x0f2c, b); - - return r; -} - -static int ch341_set_handshake(struct usb_device *dev, u8 control) -{ - dbg("ch341_set_handshake(0x%02x)", control); - return ch341_control_out(dev, 0xa4, ~control, 0); -} - -static int ch341_get_status(struct usb_device *dev, struct ch341_private *priv) -{ - char *buffer; - int r; - const unsigned size = 8; - unsigned long flags; - - dbg("ch341_get_status()"); - - buffer = kmalloc(size, GFP_KERNEL); - if (!buffer) - return -ENOMEM; - - r = ch341_control_in(dev, 0x95, 0x0706, 0, buffer, size); - if (r < 0) - goto out; - - /* setup the private status if available */ - if (r == 2) { - r = 0; - spin_lock_irqsave(&priv->lock, flags); - priv->line_status = (~(*buffer)) & CH341_BITS_MODEM_STAT; - priv->multi_status_change = 0; - spin_unlock_irqrestore(&priv->lock, flags); - } else - r = -EPROTO; - -out: kfree(buffer); - return r; -} - -/* -------------------------------------------------------------------------- */ - -static int ch341_configure(struct usb_device *dev, struct ch341_private *priv) -{ - char *buffer; - int r; - const unsigned size = 8; - - dbg("ch341_configure()"); - - buffer = kmalloc(size, GFP_KERNEL); - if (!buffer) - return -ENOMEM; - - /* expect two bytes 0x27 0x00 */ - r = ch341_control_in(dev, 0x5f, 0, 0, buffer, size); - if (r < 0) - goto out; - - r = ch341_control_out(dev, 0xa1, 0, 0); - if (r < 0) - goto out; - - r = ch341_set_baudrate(dev, priv); - if (r < 0) - goto out; - - /* expect two bytes 0x56 0x00 */ - r = ch341_control_in(dev, 0x95, 0x2518, 0, buffer, size); - if (r < 0) - goto out; - - r = ch341_control_out(dev, 0x9a, 0x2518, 0x0050); - if (r < 0) - goto out; - - /* expect 0xff 0xee */ - r = ch341_get_status(dev, priv); - if (r < 0) - goto out; - - r = ch341_control_out(dev, 0xa1, 0x501f, 0xd90a); - if (r < 0) - goto out; - - r = ch341_set_baudrate(dev, priv); - if (r < 0) - goto out; - - r = ch341_set_handshake(dev, priv->line_control); - if (r < 0) - goto out; - - /* expect 0x9f 0xee */ - r = ch341_get_status(dev, priv); - -out: kfree(buffer); - return r; -} - -/* allocate private data */ -static int ch341_attach(struct usb_serial *serial) -{ - struct ch341_private *priv; - int r; - - dbg("ch341_attach()"); - - /* private data */ - priv = kzalloc(sizeof(struct ch341_private), GFP_KERNEL); - if (!priv) - return -ENOMEM; - - spin_lock_init(&priv->lock); - init_waitqueue_head(&priv->delta_msr_wait); - priv->baud_rate = DEFAULT_BAUD_RATE; - priv->line_control = CH341_BIT_RTS | CH341_BIT_DTR; - - r = ch341_configure(serial->dev, priv); - if (r < 0) - goto error; - - usb_set_serial_port_data(serial->port[0], priv); - return 0; - -error: kfree(priv); - return r; -} - -static int ch341_carrier_raised(struct usb_serial_port *port) -{ - struct ch341_private *priv = usb_get_serial_port_data(port); - if (priv->line_status & CH341_BIT_DCD) - return 1; - return 0; -} - -static void ch341_dtr_rts(struct usb_serial_port *port, int on) -{ - struct ch341_private *priv = usb_get_serial_port_data(port); - unsigned long flags; - - dbg("%s - port %d", __func__, port->number); - /* drop DTR and RTS */ - spin_lock_irqsave(&priv->lock, flags); - if (on) - priv->line_control |= CH341_BIT_RTS | CH341_BIT_DTR; - else - priv->line_control &= ~(CH341_BIT_RTS | CH341_BIT_DTR); - spin_unlock_irqrestore(&priv->lock, flags); - ch341_set_handshake(port->serial->dev, priv->line_control); - wake_up_interruptible(&priv->delta_msr_wait); -} - -static void ch341_close(struct usb_serial_port *port) -{ - dbg("%s - port %d", __func__, port->number); - - usb_serial_generic_close(port); - usb_kill_urb(port->interrupt_in_urb); -} - - -/* open this device, set default parameters */ -static int ch341_open(struct tty_struct *tty, struct usb_serial_port *port) -{ - struct usb_serial *serial = port->serial; - struct ch341_private *priv = usb_get_serial_port_data(serial->port[0]); - int r; - - dbg("ch341_open()"); - - priv->baud_rate = DEFAULT_BAUD_RATE; - - r = ch341_configure(serial->dev, priv); - if (r) - goto out; - - r = ch341_set_handshake(serial->dev, priv->line_control); - if (r) - goto out; - - r = ch341_set_baudrate(serial->dev, priv); - if (r) - goto out; - - dbg("%s - submitting interrupt urb", __func__); - r = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL); - if (r) { - dev_err(&port->dev, "%s - failed submitting interrupt urb," - " error %d\n", __func__, r); - ch341_close(port); - goto out; - } - - r = usb_serial_generic_open(tty, port); - -out: return r; -} - -/* Old_termios contains the original termios settings and - * tty->termios contains the new setting to be used. - */ -static void ch341_set_termios(struct tty_struct *tty, - struct usb_serial_port *port, struct ktermios *old_termios) -{ - struct ch341_private *priv = usb_get_serial_port_data(port); - unsigned baud_rate; - unsigned long flags; - - dbg("ch341_set_termios()"); - - baud_rate = tty_get_baud_rate(tty); - - priv->baud_rate = baud_rate; - - if (baud_rate) { - spin_lock_irqsave(&priv->lock, flags); - priv->line_control |= (CH341_BIT_DTR | CH341_BIT_RTS); - spin_unlock_irqrestore(&priv->lock, flags); - ch341_set_baudrate(port->serial->dev, priv); - } else { - spin_lock_irqsave(&priv->lock, flags); - priv->line_control &= ~(CH341_BIT_DTR | CH341_BIT_RTS); - spin_unlock_irqrestore(&priv->lock, flags); - } - - ch341_set_handshake(port->serial->dev, priv->line_control); - - /* Unimplemented: - * (cflag & CSIZE) : data bits [5, 8] - * (cflag & PARENB) : parity {NONE, EVEN, ODD} - * (cflag & CSTOPB) : stop bits [1, 2] - */ -} - -static void ch341_break_ctl(struct tty_struct *tty, int break_state) -{ - const uint16_t ch341_break_reg = - CH341_REG_BREAK1 | ((uint16_t) CH341_REG_BREAK2 << 8); - struct usb_serial_port *port = tty->driver_data; - int r; - uint16_t reg_contents; - uint8_t *break_reg; - - dbg("%s()", __func__); - - break_reg = kmalloc(2, GFP_KERNEL); - if (!break_reg) { - dev_err(&port->dev, "%s - kmalloc failed\n", __func__); - return; - } - - r = ch341_control_in(port->serial->dev, CH341_REQ_READ_REG, - ch341_break_reg, 0, break_reg, 2); - if (r < 0) { - dev_err(&port->dev, "%s - USB control read error (%d)\n", - __func__, r); - goto out; - } - dbg("%s - initial ch341 break register contents - reg1: %x, reg2: %x", - __func__, break_reg[0], break_reg[1]); - if (break_state != 0) { - dbg("%s - Enter break state requested", __func__); - break_reg[0] &= ~CH341_NBREAK_BITS_REG1; - break_reg[1] &= ~CH341_NBREAK_BITS_REG2; - } else { - dbg("%s - Leave break state requested", __func__); - break_reg[0] |= CH341_NBREAK_BITS_REG1; - break_reg[1] |= CH341_NBREAK_BITS_REG2; - } - dbg("%s - New ch341 break register contents - reg1: %x, reg2: %x", - __func__, break_reg[0], break_reg[1]); - reg_contents = get_unaligned_le16(break_reg); - r = ch341_control_out(port->serial->dev, CH341_REQ_WRITE_REG, - ch341_break_reg, reg_contents); - if (r < 0) - dev_err(&port->dev, "%s - USB control write error (%d)\n", - __func__, r); -out: - kfree(break_reg); -} - -static int ch341_tiocmset(struct tty_struct *tty, - unsigned int set, unsigned int clear) -{ - struct usb_serial_port *port = tty->driver_data; - struct ch341_private *priv = usb_get_serial_port_data(port); - unsigned long flags; - u8 control; - - spin_lock_irqsave(&priv->lock, flags); - if (set & TIOCM_RTS) - priv->line_control |= CH341_BIT_RTS; - if (set & TIOCM_DTR) - priv->line_control |= CH341_BIT_DTR; - if (clear & TIOCM_RTS) - priv->line_control &= ~CH341_BIT_RTS; - if (clear & TIOCM_DTR) - priv->line_control &= ~CH341_BIT_DTR; - control = priv->line_control; - spin_unlock_irqrestore(&priv->lock, flags); - - return ch341_set_handshake(port->serial->dev, control); -} - -static void ch341_read_int_callback(struct urb *urb) -{ - struct usb_serial_port *port = (struct usb_serial_port *) urb->context; - unsigned char *data = urb->transfer_buffer; - unsigned int actual_length = urb->actual_length; - int status; - - dbg("%s (%d)", __func__, port->number); - - switch (urb->status) { - case 0: - /* success */ - break; - case -ECONNRESET: - case -ENOENT: - case -ESHUTDOWN: - /* this urb is terminated, clean up */ - dbg("%s - urb shutting down with status: %d", __func__, - urb->status); - return; - default: - dbg("%s - nonzero urb status received: %d", __func__, - urb->status); - goto exit; - } - - usb_serial_debug_data(debug, &port->dev, __func__, - urb->actual_length, urb->transfer_buffer); - - if (actual_length >= 4) { - struct ch341_private *priv = usb_get_serial_port_data(port); - unsigned long flags; - u8 prev_line_status = priv->line_status; - - spin_lock_irqsave(&priv->lock, flags); - priv->line_status = (~(data[2])) & CH341_BITS_MODEM_STAT; - if ((data[1] & CH341_MULT_STAT)) - priv->multi_status_change = 1; - spin_unlock_irqrestore(&priv->lock, flags); - - if ((priv->line_status ^ prev_line_status) & CH341_BIT_DCD) { - struct tty_struct *tty = tty_port_tty_get(&port->port); - if (tty) - usb_serial_handle_dcd_change(port, tty, - priv->line_status & CH341_BIT_DCD); - tty_kref_put(tty); - } - - wake_up_interruptible(&priv->delta_msr_wait); - } - -exit: - status = usb_submit_urb(urb, GFP_ATOMIC); - if (status) - dev_err(&urb->dev->dev, - "%s - usb_submit_urb failed with result %d\n", - __func__, status); -} - -static int wait_modem_info(struct usb_serial_port *port, unsigned int arg) -{ - struct ch341_private *priv = usb_get_serial_port_data(port); - unsigned long flags; - u8 prevstatus; - u8 status; - u8 changed; - u8 multi_change = 0; - - spin_lock_irqsave(&priv->lock, flags); - prevstatus = priv->line_status; - priv->multi_status_change = 0; - spin_unlock_irqrestore(&priv->lock, flags); - - while (!multi_change) { - interruptible_sleep_on(&priv->delta_msr_wait); - /* see if a signal did it */ - if (signal_pending(current)) - return -ERESTARTSYS; - - spin_lock_irqsave(&priv->lock, flags); - status = priv->line_status; - multi_change = priv->multi_status_change; - spin_unlock_irqrestore(&priv->lock, flags); - - changed = prevstatus ^ status; - - if (((arg & TIOCM_RNG) && (changed & CH341_BIT_RI)) || - ((arg & TIOCM_DSR) && (changed & CH341_BIT_DSR)) || - ((arg & TIOCM_CD) && (changed & CH341_BIT_DCD)) || - ((arg & TIOCM_CTS) && (changed & CH341_BIT_CTS))) { - return 0; - } - prevstatus = status; - } - - return 0; -} - -static int ch341_ioctl(struct tty_struct *tty, - unsigned int cmd, unsigned long arg) -{ - struct usb_serial_port *port = tty->driver_data; - dbg("%s (%d) cmd = 0x%04x", __func__, port->number, cmd); - - switch (cmd) { - case TIOCMIWAIT: - dbg("%s (%d) TIOCMIWAIT", __func__, port->number); - return wait_modem_info(port, arg); - - default: - dbg("%s not supported = 0x%04x", __func__, cmd); - break; - } - - return -ENOIOCTLCMD; -} - -static int ch341_tiocmget(struct tty_struct *tty) -{ - struct usb_serial_port *port = tty->driver_data; - struct ch341_private *priv = usb_get_serial_port_data(port); - unsigned long flags; - u8 mcr; - u8 status; - unsigned int result; - - dbg("%s (%d)", __func__, port->number); - - spin_lock_irqsave(&priv->lock, flags); - mcr = priv->line_control; - status = priv->line_status; - spin_unlock_irqrestore(&priv->lock, flags); - - result = ((mcr & CH341_BIT_DTR) ? TIOCM_DTR : 0) - | ((mcr & CH341_BIT_RTS) ? TIOCM_RTS : 0) - | ((status & CH341_BIT_CTS) ? TIOCM_CTS : 0) - | ((status & CH341_BIT_DSR) ? TIOCM_DSR : 0) - | ((status & CH341_BIT_RI) ? TIOCM_RI : 0) - | ((status & CH341_BIT_DCD) ? TIOCM_CD : 0); - - dbg("%s - result = %x", __func__, result); - - return result; -} - - -static int ch341_reset_resume(struct usb_interface *intf) -{ - struct usb_device *dev = interface_to_usbdev(intf); - struct usb_serial *serial = NULL; - struct ch341_private *priv; - - serial = usb_get_intfdata(intf); - priv = usb_get_serial_port_data(serial->port[0]); - - /*reconfigure ch341 serial port after bus-reset*/ - ch341_configure(dev, priv); - - usb_serial_resume(intf); - - return 0; -} - -static struct usb_driver ch341_driver = { - .name = "ch341", - .probe = usb_serial_probe, - .disconnect = usb_serial_disconnect, - .suspend = usb_serial_suspend, - .resume = usb_serial_resume, - .reset_resume = ch341_reset_resume, - .id_table = id_table, - .supports_autosuspend = 1, -}; - -static struct usb_serial_driver ch341_device = { - .driver = { - .owner = THIS_MODULE, - .name = "ch341-uart", - }, - .id_table = id_table, - .num_ports = 1, - .open = ch341_open, - .dtr_rts = ch341_dtr_rts, - .carrier_raised = ch341_carrier_raised, - .close = ch341_close, - .ioctl = ch341_ioctl, - .set_termios = ch341_set_termios, - .break_ctl = ch341_break_ctl, - .tiocmget = ch341_tiocmget, - .tiocmset = ch341_tiocmset, - .read_int_callback = ch341_read_int_callback, - .attach = ch341_attach, -}; - -static struct usb_serial_driver * const serial_drivers[] = { - &ch341_device, NULL -}; - -module_usb_serial_driver(ch341_driver, serial_drivers); - -MODULE_LICENSE("GPL"); - -module_param(debug, bool, S_IRUGO | S_IWUSR); -MODULE_PARM_DESC(debug, "Debug enabled or not"); diff --git a/ANDROID_3.4.5/drivers/usb/serial/console.c b/ANDROID_3.4.5/drivers/usb/serial/console.c deleted file mode 100644 index 1ee6b2ab..00000000 --- a/ANDROID_3.4.5/drivers/usb/serial/console.c +++ /dev/null @@ -1,317 +0,0 @@ -/* - * USB Serial Console driver - * - * Copyright (C) 2001 - 2002 Greg Kroah-Hartman (greg@kroah.com) - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License version - * 2 as published by the Free Software Foundation. - * - * Thanks to Randy Dunlap for the original version of this code. - * - */ - -#include <linux/kernel.h> -#include <linux/init.h> -#include <linux/slab.h> -#include <linux/tty.h> -#include <linux/console.h> -#include <linux/serial.h> -#include <linux/usb.h> -#include <linux/usb/serial.h> - -static int debug; - -struct usbcons_info { - int magic; - int break_flag; - struct usb_serial_port *port; -}; - -static struct usbcons_info usbcons_info; -static struct console usbcons; - -/* - * ------------------------------------------------------------ - * USB Serial console driver - * - * Much of the code here is copied from drivers/char/serial.c - * and implements a phony serial console in the same way that - * serial.c does so that in case some software queries it, - * it will get the same results. - * - * Things that are different from the way the serial port code - * does things, is that we call the lower level usb-serial - * driver code to initialize the device, and we set the initial - * console speeds based on the command line arguments. - * ------------------------------------------------------------ - */ - - -/* - * The parsing of the command line works exactly like the - * serial.c code, except that the specifier is "ttyUSB" instead - * of "ttyS". - */ -static int usb_console_setup(struct console *co, char *options) -{ - struct usbcons_info *info = &usbcons_info; - int baud = 9600; - int bits = 8; - int parity = 'n'; - int doflow = 0; - int cflag = CREAD | HUPCL | CLOCAL; - char *s; - struct usb_serial *serial; - struct usb_serial_port *port; - int retval; - struct tty_struct *tty = NULL; - struct ktermios dummy; - - dbg("%s", __func__); - - if (options) { - baud = simple_strtoul(options, NULL, 10); - s = options; - while (*s >= '0' && *s <= '9') - s++; - if (*s) - parity = *s++; - if (*s) - bits = *s++ - '0'; - if (*s) - doflow = (*s++ == 'r'); - } - - /* Sane default */ - if (baud == 0) - baud = 9600; - - switch (bits) { - case 7: - cflag |= CS7; - break; - default: - case 8: - cflag |= CS8; - break; - } - switch (parity) { - case 'o': case 'O': - cflag |= PARODD; - break; - case 'e': case 'E': - cflag |= PARENB; - break; - } - co->cflag = cflag; - - /* - * no need to check the index here: if the index is wrong, console - * code won't call us - */ - serial = usb_serial_get_by_index(co->index); - if (serial == NULL) { - /* no device is connected yet, sorry :( */ - err("No USB device connected to ttyUSB%i", co->index); - return -ENODEV; - } - - retval = usb_autopm_get_interface(serial->interface); - if (retval) - goto error_get_interface; - - port = serial->port[co->index - serial->minor]; - tty_port_tty_set(&port->port, NULL); - - info->port = port; - - ++port->port.count; - if (!test_bit(ASYNCB_INITIALIZED, &port->port.flags)) { - if (serial->type->set_termios) { - /* - * allocate a fake tty so the driver can initialize - * the termios structure, then later call set_termios to - * configure according to command line arguments - */ - tty = kzalloc(sizeof(*tty), GFP_KERNEL); - if (!tty) { - retval = -ENOMEM; - err("no more memory"); - goto reset_open_count; - } - kref_init(&tty->kref); - tty_port_tty_set(&port->port, tty); - tty->driver = usb_serial_tty_driver; - tty->index = co->index; - if (tty_init_termios(tty)) { - retval = -ENOMEM; - err("no more memory"); - goto free_tty; - } - } - - /* only call the device specific open if this - * is the first time the port is opened */ - if (serial->type->open) - retval = serial->type->open(NULL, port); - else - retval = usb_serial_generic_open(NULL, port); - - if (retval) { - err("could not open USB console port"); - goto fail; - } - - if (serial->type->set_termios) { - tty->termios->c_cflag = cflag; - tty_termios_encode_baud_rate(tty->termios, baud, baud); - memset(&dummy, 0, sizeof(struct ktermios)); - serial->type->set_termios(tty, port, &dummy); - - tty_port_tty_set(&port->port, NULL); - kfree(tty); - } - set_bit(ASYNCB_INITIALIZED, &port->port.flags); - } - /* Now that any required fake tty operations are completed restore - * the tty port count */ - --port->port.count; - /* The console is special in terms of closing the device so - * indicate this port is now acting as a system console. */ - port->port.console = 1; - - mutex_unlock(&serial->disc_mutex); - return retval; - - fail: - tty_port_tty_set(&port->port, NULL); - free_tty: - kfree(tty); - reset_open_count: - port->port.count = 0; - usb_autopm_put_interface(serial->interface); - error_get_interface: - usb_serial_put(serial); - mutex_unlock(&serial->disc_mutex); - return retval; -} - -static void usb_console_write(struct console *co, - const char *buf, unsigned count) -{ - static struct usbcons_info *info = &usbcons_info; - struct usb_serial_port *port = info->port; - struct usb_serial *serial; - int retval = -ENODEV; - - if (!port || port->serial->dev->state == USB_STATE_NOTATTACHED) - return; - serial = port->serial; - - if (count == 0) - return; - - dbg("%s - port %d, %d byte(s)", __func__, port->number, count); - - if (!port->port.console) { - dbg("%s - port not opened", __func__); - return; - } - - while (count) { - unsigned int i; - unsigned int lf; - /* search for LF so we can insert CR if necessary */ - for (i = 0, lf = 0 ; i < count ; i++) { - if (*(buf + i) == 10) { - lf = 1; - i++; - break; - } - } - /* pass on to the driver specific version of this function if - it is available */ - if (serial->type->write) - retval = serial->type->write(NULL, port, buf, i); - else - retval = usb_serial_generic_write(NULL, port, buf, i); - dbg("%s - return value : %d", __func__, retval); - if (lf) { - /* append CR after LF */ - unsigned char cr = 13; - if (serial->type->write) - retval = serial->type->write(NULL, - port, &cr, 1); - else - retval = usb_serial_generic_write(NULL, - port, &cr, 1); - dbg("%s - return value : %d", __func__, retval); - } - buf += i; - count -= i; - } -} - -static struct tty_driver *usb_console_device(struct console *co, int *index) -{ - struct tty_driver **p = (struct tty_driver **)co->data; - - if (!*p) - return NULL; - - *index = co->index; - return *p; -} - -static struct console usbcons = { - .name = "ttyUSB", - .write = usb_console_write, - .device = usb_console_device, - .setup = usb_console_setup, - .flags = CON_PRINTBUFFER, - .index = -1, - .data = &usb_serial_tty_driver, -}; - -void usb_serial_console_disconnect(struct usb_serial *serial) -{ - if (serial && serial->port && serial->port[0] - && serial->port[0] == usbcons_info.port) { - usb_serial_console_exit(); - usb_serial_put(serial); - } -} - -void usb_serial_console_init(int serial_debug, int minor) -{ - debug = serial_debug; - - if (minor == 0) { - /* - * Call register_console() if this is the first device plugged - * in. If we call it earlier, then the callback to - * console_setup() will fail, as there is not a device seen by - * the USB subsystem yet. - */ - /* - * Register console. - * NOTES: - * console_setup() is called (back) immediately (from - * register_console). console_write() is called immediately - * from register_console iff CON_PRINTBUFFER is set in flags. - */ - dbg("registering the USB serial console."); - register_console(&usbcons); - } -} - -void usb_serial_console_exit(void) -{ - if (usbcons_info.port) { - unregister_console(&usbcons); - usbcons_info.port->port.console = 0; - usbcons_info.port = NULL; - } -} - diff --git a/ANDROID_3.4.5/drivers/usb/serial/cp210x.c b/ANDROID_3.4.5/drivers/usb/serial/cp210x.c deleted file mode 100644 index 53e7e692..00000000 --- a/ANDROID_3.4.5/drivers/usb/serial/cp210x.c +++ /dev/null @@ -1,913 +0,0 @@ -/* - * Silicon Laboratories CP210x USB to RS232 serial adaptor driver - * - * Copyright (C) 2005 Craig Shelley (craig@microtron.org.uk) - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License version - * 2 as published by the Free Software Foundation. - * - * Support to set flow control line levels using TIOCMGET and TIOCMSET - * thanks to Karl Hiramoto karl@hiramoto.org. RTSCTS hardware flow - * control thanks to Munir Nassar nassarmu@real-time.com - * - */ - -#include <linux/kernel.h> -#include <linux/errno.h> -#include <linux/slab.h> -#include <linux/tty.h> -#include <linux/tty_flip.h> -#include <linux/module.h> -#include <linux/moduleparam.h> -#include <linux/usb.h> -#include <linux/uaccess.h> -#include <linux/usb/serial.h> - -/* - * Version Information - */ -#define DRIVER_VERSION "v0.09" -#define DRIVER_DESC "Silicon Labs CP210x RS232 serial adaptor driver" - -/* - * Function Prototypes - */ -static int cp210x_open(struct tty_struct *tty, struct usb_serial_port *); -static void cp210x_close(struct usb_serial_port *); -static void cp210x_get_termios(struct tty_struct *, - struct usb_serial_port *port); -static void cp210x_get_termios_port(struct usb_serial_port *port, - unsigned int *cflagp, unsigned int *baudp); -static void cp210x_change_speed(struct tty_struct *, struct usb_serial_port *, - struct ktermios *); -static void cp210x_set_termios(struct tty_struct *, struct usb_serial_port *, - struct ktermios*); -static int cp210x_tiocmget(struct tty_struct *); -static int cp210x_tiocmset(struct tty_struct *, unsigned int, unsigned int); -static int cp210x_tiocmset_port(struct usb_serial_port *port, - unsigned int, unsigned int); -static void cp210x_break_ctl(struct tty_struct *, int); -static int cp210x_startup(struct usb_serial *); -static void cp210x_release(struct usb_serial *); -static void cp210x_dtr_rts(struct usb_serial_port *p, int on); - -static bool debug; - -static const struct usb_device_id id_table[] = { - { 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 */ - { } /* Terminating Entry */ -}; - -MODULE_DEVICE_TABLE(usb, id_table); - -struct cp210x_port_private { - __u8 bInterfaceNumber; -}; - -static struct usb_driver cp210x_driver = { - .name = "cp210x", - .probe = usb_serial_probe, - .disconnect = usb_serial_disconnect, - .id_table = id_table, -}; - -static struct usb_serial_driver cp210x_device = { - .driver = { - .owner = THIS_MODULE, - .name = "cp210x", - }, - .id_table = id_table, - .num_ports = 1, - .bulk_in_size = 256, - .bulk_out_size = 256, - .open = cp210x_open, - .close = cp210x_close, - .break_ctl = cp210x_break_ctl, - .set_termios = cp210x_set_termios, - .tiocmget = cp210x_tiocmget, - .tiocmset = cp210x_tiocmset, - .attach = cp210x_startup, - .release = cp210x_release, - .dtr_rts = cp210x_dtr_rts -}; - -static struct usb_serial_driver * const serial_drivers[] = { - &cp210x_device, NULL -}; - -/* Config request types */ -#define REQTYPE_HOST_TO_DEVICE 0x41 -#define REQTYPE_DEVICE_TO_HOST 0xc1 - -/* Config request codes */ -#define CP210X_IFC_ENABLE 0x00 -#define CP210X_SET_BAUDDIV 0x01 -#define CP210X_GET_BAUDDIV 0x02 -#define CP210X_SET_LINE_CTL 0x03 -#define CP210X_GET_LINE_CTL 0x04 -#define CP210X_SET_BREAK 0x05 -#define CP210X_IMM_CHAR 0x06 -#define CP210X_SET_MHS 0x07 -#define CP210X_GET_MDMSTS 0x08 -#define CP210X_SET_XON 0x09 -#define CP210X_SET_XOFF 0x0A -#define CP210X_SET_EVENTMASK 0x0B -#define CP210X_GET_EVENTMASK 0x0C -#define CP210X_SET_CHAR 0x0D -#define CP210X_GET_CHARS 0x0E -#define CP210X_GET_PROPS 0x0F -#define CP210X_GET_COMM_STATUS 0x10 -#define CP210X_RESET 0x11 -#define CP210X_PURGE 0x12 -#define CP210X_SET_FLOW 0x13 -#define CP210X_GET_FLOW 0x14 -#define CP210X_EMBED_EVENTS 0x15 -#define CP210X_GET_EVENTSTATE 0x16 -#define CP210X_SET_CHARS 0x19 -#define CP210X_GET_BAUDRATE 0x1D -#define CP210X_SET_BAUDRATE 0x1E - -/* CP210X_IFC_ENABLE */ -#define UART_ENABLE 0x0001 -#define UART_DISABLE 0x0000 - -/* CP210X_(SET|GET)_BAUDDIV */ -#define BAUD_RATE_GEN_FREQ 0x384000 - -/* CP210X_(SET|GET)_LINE_CTL */ -#define BITS_DATA_MASK 0X0f00 -#define BITS_DATA_5 0X0500 -#define BITS_DATA_6 0X0600 -#define BITS_DATA_7 0X0700 -#define BITS_DATA_8 0X0800 -#define BITS_DATA_9 0X0900 - -#define BITS_PARITY_MASK 0x00f0 -#define BITS_PARITY_NONE 0x0000 -#define BITS_PARITY_ODD 0x0010 -#define BITS_PARITY_EVEN 0x0020 -#define BITS_PARITY_MARK 0x0030 -#define BITS_PARITY_SPACE 0x0040 - -#define BITS_STOP_MASK 0x000f -#define BITS_STOP_1 0x0000 -#define BITS_STOP_1_5 0x0001 -#define BITS_STOP_2 0x0002 - -/* CP210X_SET_BREAK */ -#define BREAK_ON 0x0001 -#define BREAK_OFF 0x0000 - -/* CP210X_(SET_MHS|GET_MDMSTS) */ -#define CONTROL_DTR 0x0001 -#define CONTROL_RTS 0x0002 -#define CONTROL_CTS 0x0010 -#define CONTROL_DSR 0x0020 -#define CONTROL_RING 0x0040 -#define CONTROL_DCD 0x0080 -#define CONTROL_WRITE_DTR 0x0100 -#define CONTROL_WRITE_RTS 0x0200 - -/* - * cp210x_get_config - * Reads from the CP210x configuration registers - * 'size' is specified in bytes. - * 'data' is a pointer to a pre-allocated array of integers large - * enough to hold 'size' bytes (with 4 bytes to each integer) - */ -static int cp210x_get_config(struct usb_serial_port *port, u8 request, - unsigned int *data, int size) -{ - struct usb_serial *serial = port->serial; - struct cp210x_port_private *port_priv = usb_get_serial_port_data(port); - __le32 *buf; - int result, i, length; - - /* Number of integers required to contain the array */ - length = (((size - 1) | 3) + 1)/4; - - buf = kcalloc(length, sizeof(__le32), GFP_KERNEL); - if (!buf) { - dev_err(&port->dev, "%s - out of memory.\n", __func__); - return -ENOMEM; - } - - /* Issue the request, attempting to read 'size' bytes */ - result = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0), - request, REQTYPE_DEVICE_TO_HOST, 0x0000, - port_priv->bInterfaceNumber, buf, size, - USB_CTRL_GET_TIMEOUT); - - /* Convert data into an array of integers */ - for (i = 0; i < length; i++) - data[i] = le32_to_cpu(buf[i]); - - kfree(buf); - - if (result != size) { - dbg("%s - Unable to send config request, " - "request=0x%x size=%d result=%d", - __func__, request, size, result); - if (result > 0) - result = -EPROTO; - - return result; - } - - return 0; -} - -/* - * cp210x_set_config - * Writes to the CP210x configuration registers - * Values less than 16 bits wide are sent directly - * 'size' is specified in bytes. - */ -static int cp210x_set_config(struct usb_serial_port *port, u8 request, - unsigned int *data, int size) -{ - struct usb_serial *serial = port->serial; - struct cp210x_port_private *port_priv = usb_get_serial_port_data(port); - __le32 *buf; - int result, i, length; - - /* Number of integers required to contain the array */ - length = (((size - 1) | 3) + 1)/4; - - buf = kmalloc(length * sizeof(__le32), GFP_KERNEL); - if (!buf) { - dev_err(&port->dev, "%s - out of memory.\n", - __func__); - return -ENOMEM; - } - - /* Array of integers into bytes */ - for (i = 0; i < length; i++) - buf[i] = cpu_to_le32(data[i]); - - if (size > 2) { - result = usb_control_msg(serial->dev, - usb_sndctrlpipe(serial->dev, 0), - request, REQTYPE_HOST_TO_DEVICE, 0x0000, - port_priv->bInterfaceNumber, buf, size, - USB_CTRL_SET_TIMEOUT); - } else { - result = usb_control_msg(serial->dev, - usb_sndctrlpipe(serial->dev, 0), - request, REQTYPE_HOST_TO_DEVICE, data[0], - port_priv->bInterfaceNumber, NULL, 0, - USB_CTRL_SET_TIMEOUT); - } - - kfree(buf); - - if ((size > 2 && result != size) || result < 0) { - dbg("%s - Unable to send request, " - "request=0x%x size=%d result=%d", - __func__, request, size, result); - if (result > 0) - result = -EPROTO; - - return result; - } - - return 0; -} - -/* - * cp210x_set_config_single - * Convenience function for calling cp210x_set_config on single data values - * without requiring an integer pointer - */ -static inline int cp210x_set_config_single(struct usb_serial_port *port, - u8 request, unsigned int data) -{ - return cp210x_set_config(port, request, &data, 2); -} - -/* - * cp210x_quantise_baudrate - * Quantises the baud rate as per AN205 Table 1 - */ -static unsigned int cp210x_quantise_baudrate(unsigned int baud) { - if (baud <= 300) - baud = 300; - else if (baud <= 600) baud = 600; - else if (baud <= 1200) baud = 1200; - else if (baud <= 1800) baud = 1800; - else if (baud <= 2400) baud = 2400; - else if (baud <= 4000) baud = 4000; - else if (baud <= 4803) baud = 4800; - else if (baud <= 7207) baud = 7200; - else if (baud <= 9612) baud = 9600; - else if (baud <= 14428) baud = 14400; - else if (baud <= 16062) baud = 16000; - else if (baud <= 19250) baud = 19200; - else if (baud <= 28912) baud = 28800; - else if (baud <= 38601) baud = 38400; - else if (baud <= 51558) baud = 51200; - else if (baud <= 56280) baud = 56000; - else if (baud <= 58053) baud = 57600; - else if (baud <= 64111) baud = 64000; - else if (baud <= 77608) baud = 76800; - else if (baud <= 117028) baud = 115200; - else if (baud <= 129347) baud = 128000; - else if (baud <= 156868) baud = 153600; - else if (baud <= 237832) baud = 230400; - else if (baud <= 254234) baud = 250000; - else if (baud <= 273066) baud = 256000; - else if (baud <= 491520) baud = 460800; - else if (baud <= 567138) baud = 500000; - else if (baud <= 670254) baud = 576000; - else if (baud < 1000000) - baud = 921600; - else if (baud > 2000000) - baud = 2000000; - return baud; -} - -static int cp210x_open(struct tty_struct *tty, struct usb_serial_port *port) -{ - int result; - - dbg("%s - port %d", __func__, port->number); - - result = cp210x_set_config_single(port, CP210X_IFC_ENABLE, - UART_ENABLE); - if (result) { - dev_err(&port->dev, "%s - Unable to enable UART\n", __func__); - return result; - } - - /* Configure the termios structure */ - cp210x_get_termios(tty, port); - - /* The baud rate must be initialised on cp2104 */ - if (tty) - cp210x_change_speed(tty, port, NULL); - - return usb_serial_generic_open(tty, port); -} - -static void cp210x_close(struct usb_serial_port *port) -{ - dbg("%s - port %d", __func__, port->number); - - usb_serial_generic_close(port); - - mutex_lock(&port->serial->disc_mutex); - if (!port->serial->disconnected) - cp210x_set_config_single(port, CP210X_IFC_ENABLE, UART_DISABLE); - mutex_unlock(&port->serial->disc_mutex); -} - -/* - * cp210x_get_termios - * Reads the baud rate, data bits, parity, stop bits and flow control mode - * from the device, corrects any unsupported values, and configures the - * termios structure to reflect the state of the device - */ -static void cp210x_get_termios(struct tty_struct *tty, - struct usb_serial_port *port) -{ - unsigned int baud; - - if (tty) { - cp210x_get_termios_port(tty->driver_data, - &tty->termios->c_cflag, &baud); - tty_encode_baud_rate(tty, baud, baud); - } - - else { - unsigned int cflag; - cflag = 0; - cp210x_get_termios_port(port, &cflag, &baud); - } -} - -/* - * cp210x_get_termios_port - * This is the heart of cp210x_get_termios which always uses a &usb_serial_port. - */ -static void cp210x_get_termios_port(struct usb_serial_port *port, - unsigned int *cflagp, unsigned int *baudp) -{ - unsigned int cflag, modem_ctl[4]; - unsigned int baud; - unsigned int bits; - - dbg("%s - port %d", __func__, port->number); - - cp210x_get_config(port, CP210X_GET_BAUDRATE, &baud, 4); - - dbg("%s - baud rate = %d", __func__, baud); - *baudp = baud; - - cflag = *cflagp; - - cp210x_get_config(port, CP210X_GET_LINE_CTL, &bits, 2); - cflag &= ~CSIZE; - switch (bits & BITS_DATA_MASK) { - case BITS_DATA_5: - dbg("%s - data bits = 5", __func__); - cflag |= CS5; - break; - case BITS_DATA_6: - dbg("%s - data bits = 6", __func__); - cflag |= CS6; - break; - case BITS_DATA_7: - dbg("%s - data bits = 7", __func__); - cflag |= CS7; - break; - case BITS_DATA_8: - dbg("%s - data bits = 8", __func__); - cflag |= CS8; - break; - case BITS_DATA_9: - dbg("%s - data bits = 9 (not supported, using 8 data bits)", - __func__); - cflag |= CS8; - bits &= ~BITS_DATA_MASK; - bits |= BITS_DATA_8; - cp210x_set_config(port, CP210X_SET_LINE_CTL, &bits, 2); - break; - default: - dbg("%s - Unknown number of data bits, using 8", __func__); - cflag |= CS8; - bits &= ~BITS_DATA_MASK; - bits |= BITS_DATA_8; - cp210x_set_config(port, CP210X_SET_LINE_CTL, &bits, 2); - break; - } - - switch (bits & BITS_PARITY_MASK) { - case BITS_PARITY_NONE: - dbg("%s - parity = NONE", __func__); - cflag &= ~PARENB; - break; - case BITS_PARITY_ODD: - dbg("%s - parity = ODD", __func__); - cflag |= (PARENB|PARODD); - break; - case BITS_PARITY_EVEN: - dbg("%s - parity = EVEN", __func__); - cflag &= ~PARODD; - cflag |= PARENB; - break; - case BITS_PARITY_MARK: - dbg("%s - parity = MARK", __func__); - cflag |= (PARENB|PARODD|CMSPAR); - break; - case BITS_PARITY_SPACE: - dbg("%s - parity = SPACE", __func__); - cflag &= ~PARODD; - cflag |= (PARENB|CMSPAR); - break; - default: - dbg("%s - Unknown parity mode, disabling parity", __func__); - cflag &= ~PARENB; - bits &= ~BITS_PARITY_MASK; - cp210x_set_config(port, CP210X_SET_LINE_CTL, &bits, 2); - break; - } - - cflag &= ~CSTOPB; - switch (bits & BITS_STOP_MASK) { - case BITS_STOP_1: - dbg("%s - stop bits = 1", __func__); - break; - case BITS_STOP_1_5: - dbg("%s - stop bits = 1.5 (not supported, using 1 stop bit)", - __func__); - bits &= ~BITS_STOP_MASK; - cp210x_set_config(port, CP210X_SET_LINE_CTL, &bits, 2); - break; - case BITS_STOP_2: - dbg("%s - stop bits = 2", __func__); - cflag |= CSTOPB; - break; - default: - dbg("%s - Unknown number of stop bits, using 1 stop bit", - __func__); - bits &= ~BITS_STOP_MASK; - cp210x_set_config(port, CP210X_SET_LINE_CTL, &bits, 2); - break; - } - - cp210x_get_config(port, CP210X_GET_FLOW, modem_ctl, 16); - if (modem_ctl[0] & 0x0008) { - dbg("%s - flow control = CRTSCTS", __func__); - cflag |= CRTSCTS; - } else { - dbg("%s - flow control = NONE", __func__); - cflag &= ~CRTSCTS; - } - - *cflagp = cflag; -} - -/* - * CP2101 supports the following baud rates: - * - * 300, 600, 1200, 1800, 2400, 4800, 7200, 9600, 14400, 19200, 28800, - * 38400, 56000, 57600, 115200, 128000, 230400, 460800, 921600 - * - * CP2102 and CP2103 support the following additional rates: - * - * 4000, 16000, 51200, 64000, 76800, 153600, 250000, 256000, 500000, - * 576000 - * - * The device will map a requested rate to a supported one, but the result - * of requests for rates greater than 1053257 is undefined (see AN205). - * - * CP2104, CP2105 and CP2110 support most rates up to 2M, 921k and 1M baud, - * respectively, with an error less than 1%. The actual rates are determined - * by - * - * div = round(freq / (2 x prescale x request)) - * actual = freq / (2 x prescale x div) - * - * For CP2104 and CP2105 freq is 48Mhz and prescale is 4 for request <= 365bps - * or 1 otherwise. - * For CP2110 freq is 24Mhz and prescale is 4 for request <= 300bps or 1 - * otherwise. - */ -static void cp210x_change_speed(struct tty_struct *tty, - struct usb_serial_port *port, struct ktermios *old_termios) -{ - u32 baud; - - baud = tty->termios->c_ospeed; - - /* This maps the requested rate to a rate valid on cp2102 or cp2103, - * or to an arbitrary rate in [1M,2M]. - * - * NOTE: B0 is not implemented. - */ - baud = cp210x_quantise_baudrate(baud); - - dbg("%s - setting baud rate to %u", __func__, baud); - if (cp210x_set_config(port, CP210X_SET_BAUDRATE, &baud, - sizeof(baud))) { - dev_warn(&port->dev, "failed to set baud rate to %u\n", baud); - if (old_termios) - baud = old_termios->c_ospeed; - else - baud = 9600; - } - - tty_encode_baud_rate(tty, baud, baud); -} - -static void cp210x_set_termios(struct tty_struct *tty, - struct usb_serial_port *port, struct ktermios *old_termios) -{ - unsigned int cflag, old_cflag; - unsigned int bits; - unsigned int modem_ctl[4]; - - dbg("%s - port %d", __func__, port->number); - - if (!tty) - return; - - cflag = tty->termios->c_cflag; - old_cflag = old_termios->c_cflag; - - if (tty->termios->c_ospeed != old_termios->c_ospeed) - cp210x_change_speed(tty, port, old_termios); - - /* If the number of data bits is to be updated */ - if ((cflag & CSIZE) != (old_cflag & CSIZE)) { - cp210x_get_config(port, CP210X_GET_LINE_CTL, &bits, 2); - bits &= ~BITS_DATA_MASK; - switch (cflag & CSIZE) { - case CS5: - bits |= BITS_DATA_5; - dbg("%s - data bits = 5", __func__); - break; - case CS6: - bits |= BITS_DATA_6; - dbg("%s - data bits = 6", __func__); - break; - case CS7: - bits |= BITS_DATA_7; - dbg("%s - data bits = 7", __func__); - break; - case CS8: - bits |= BITS_DATA_8; - dbg("%s - data bits = 8", __func__); - break; - /*case CS9: - bits |= BITS_DATA_9; - dbg("%s - data bits = 9", __func__); - break;*/ - default: - dbg("cp210x driver does not " - "support the number of bits requested," - " using 8 bit mode"); - bits |= BITS_DATA_8; - break; - } - if (cp210x_set_config(port, CP210X_SET_LINE_CTL, &bits, 2)) - dbg("Number of data bits requested " - "not supported by device"); - } - - if ((cflag & (PARENB|PARODD|CMSPAR)) != - (old_cflag & (PARENB|PARODD|CMSPAR))) { - cp210x_get_config(port, CP210X_GET_LINE_CTL, &bits, 2); - bits &= ~BITS_PARITY_MASK; - if (cflag & PARENB) { - if (cflag & CMSPAR) { - if (cflag & PARODD) { - bits |= BITS_PARITY_MARK; - dbg("%s - parity = MARK", __func__); - } else { - bits |= BITS_PARITY_SPACE; - dbg("%s - parity = SPACE", __func__); - } - } else { - if (cflag & PARODD) { - bits |= BITS_PARITY_ODD; - dbg("%s - parity = ODD", __func__); - } else { - bits |= BITS_PARITY_EVEN; - dbg("%s - parity = EVEN", __func__); - } - } - } - if (cp210x_set_config(port, CP210X_SET_LINE_CTL, &bits, 2)) - dbg("Parity mode not supported by device"); - } - - if ((cflag & CSTOPB) != (old_cflag & CSTOPB)) { - cp210x_get_config(port, CP210X_GET_LINE_CTL, &bits, 2); - bits &= ~BITS_STOP_MASK; - if (cflag & CSTOPB) { - bits |= BITS_STOP_2; - dbg("%s - stop bits = 2", __func__); - } else { - bits |= BITS_STOP_1; - dbg("%s - stop bits = 1", __func__); - } - if (cp210x_set_config(port, CP210X_SET_LINE_CTL, &bits, 2)) - dbg("Number of stop bits requested " - "not supported by device"); - } - - if ((cflag & CRTSCTS) != (old_cflag & CRTSCTS)) { - cp210x_get_config(port, CP210X_GET_FLOW, modem_ctl, 16); - dbg("%s - read modem controls = 0x%.4x 0x%.4x 0x%.4x 0x%.4x", - __func__, modem_ctl[0], modem_ctl[1], - modem_ctl[2], modem_ctl[3]); - - if (cflag & CRTSCTS) { - modem_ctl[0] &= ~0x7B; - modem_ctl[0] |= 0x09; - modem_ctl[1] = 0x80; - dbg("%s - flow control = CRTSCTS", __func__); - } else { - modem_ctl[0] &= ~0x7B; - modem_ctl[0] |= 0x01; - modem_ctl[1] |= 0x40; - dbg("%s - flow control = NONE", __func__); - } - - dbg("%s - write modem controls = 0x%.4x 0x%.4x 0x%.4x 0x%.4x", - __func__, modem_ctl[0], modem_ctl[1], - modem_ctl[2], modem_ctl[3]); - cp210x_set_config(port, CP210X_SET_FLOW, modem_ctl, 16); - } - -} - -static int cp210x_tiocmset (struct tty_struct *tty, - unsigned int set, unsigned int clear) -{ - struct usb_serial_port *port = tty->driver_data; - return cp210x_tiocmset_port(port, set, clear); -} - -static int cp210x_tiocmset_port(struct usb_serial_port *port, - unsigned int set, unsigned int clear) -{ - unsigned int control = 0; - - dbg("%s - port %d", __func__, port->number); - - if (set & TIOCM_RTS) { - control |= CONTROL_RTS; - control |= CONTROL_WRITE_RTS; - } - if (set & TIOCM_DTR) { - control |= CONTROL_DTR; - control |= CONTROL_WRITE_DTR; - } - if (clear & TIOCM_RTS) { - control &= ~CONTROL_RTS; - control |= CONTROL_WRITE_RTS; - } - if (clear & TIOCM_DTR) { - control &= ~CONTROL_DTR; - control |= CONTROL_WRITE_DTR; - } - - dbg("%s - control = 0x%.4x", __func__, control); - - return cp210x_set_config(port, CP210X_SET_MHS, &control, 2); -} - -static void cp210x_dtr_rts(struct usb_serial_port *p, int on) -{ - if (on) - cp210x_tiocmset_port(p, TIOCM_DTR|TIOCM_RTS, 0); - else - cp210x_tiocmset_port(p, 0, TIOCM_DTR|TIOCM_RTS); -} - -static int cp210x_tiocmget (struct tty_struct *tty) -{ - struct usb_serial_port *port = tty->driver_data; - unsigned int control; - int result; - - dbg("%s - port %d", __func__, port->number); - - cp210x_get_config(port, CP210X_GET_MDMSTS, &control, 1); - - result = ((control & CONTROL_DTR) ? TIOCM_DTR : 0) - |((control & CONTROL_RTS) ? TIOCM_RTS : 0) - |((control & CONTROL_CTS) ? TIOCM_CTS : 0) - |((control & CONTROL_DSR) ? TIOCM_DSR : 0) - |((control & CONTROL_RING)? TIOCM_RI : 0) - |((control & CONTROL_DCD) ? TIOCM_CD : 0); - - dbg("%s - control = 0x%.2x", __func__, control); - - return result; -} - -static void cp210x_break_ctl (struct tty_struct *tty, int break_state) -{ - struct usb_serial_port *port = tty->driver_data; - unsigned int state; - - dbg("%s - port %d", __func__, port->number); - if (break_state == 0) - state = BREAK_OFF; - else - state = BREAK_ON; - dbg("%s - turning break %s", __func__, - state == BREAK_OFF ? "off" : "on"); - cp210x_set_config(port, CP210X_SET_BREAK, &state, 2); -} - -static int cp210x_startup(struct usb_serial *serial) -{ - struct cp210x_port_private *port_priv; - int i; - - /* cp210x buffers behave strangely unless device is reset */ - usb_reset_device(serial->dev); - - for (i = 0; i < serial->num_ports; i++) { - port_priv = kzalloc(sizeof(*port_priv), GFP_KERNEL); - if (!port_priv) - return -ENOMEM; - - memset(port_priv, 0x00, sizeof(*port_priv)); - port_priv->bInterfaceNumber = - serial->interface->cur_altsetting->desc.bInterfaceNumber; - - usb_set_serial_port_data(serial->port[i], port_priv); - } - - return 0; -} - -static void cp210x_release(struct usb_serial *serial) -{ - struct cp210x_port_private *port_priv; - int i; - - for (i = 0; i < serial->num_ports; i++) { - port_priv = usb_get_serial_port_data(serial->port[i]); - kfree(port_priv); - usb_set_serial_port_data(serial->port[i], NULL); - } -} - -module_usb_serial_driver(cp210x_driver, serial_drivers); - -MODULE_DESCRIPTION(DRIVER_DESC); -MODULE_VERSION(DRIVER_VERSION); -MODULE_LICENSE("GPL"); - -module_param(debug, bool, S_IRUGO | S_IWUSR); -MODULE_PARM_DESC(debug, "Enable verbose debugging messages"); diff --git a/ANDROID_3.4.5/drivers/usb/serial/cyberjack.c b/ANDROID_3.4.5/drivers/usb/serial/cyberjack.c deleted file mode 100644 index d39b9418..00000000 --- a/ANDROID_3.4.5/drivers/usb/serial/cyberjack.c +++ /dev/null @@ -1,486 +0,0 @@ -/* - * REINER SCT cyberJack pinpad/e-com USB Chipcard Reader Driver - * - * Copyright (C) 2001 REINER SCT - * Author: Matthias Bruestle - * - * Contact: support@reiner-sct.com (see MAINTAINERS) - * - * This program is largely derived from work by the linux-usb group - * and associated source files. Please see the usb/serial files for - * individual credits and copyrights. - * - * 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. - * - * Thanks to Greg Kroah-Hartman (greg@kroah.com) for his help and - * patience. - * - * In case of problems, please write to the contact e-mail address - * mentioned above. - * - * Please note that later models of the cyberjack reader family are - * supported by a libusb-based userspace device driver. - * - * Homepage: http://www.reiner-sct.de/support/treiber_cyberjack.php#linux - */ - - -#include <linux/kernel.h> -#include <linux/errno.h> -#include <linux/init.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/uaccess.h> -#include <linux/usb.h> -#include <linux/usb/serial.h> - -#define CYBERJACK_LOCAL_BUF_SIZE 32 - -static bool debug; - -/* - * Version Information - */ -#define DRIVER_VERSION "v1.01" -#define DRIVER_AUTHOR "Matthias Bruestle" -#define DRIVER_DESC "REINER SCT cyberJack pinpad/e-com USB Chipcard Reader Driver" - - -#define CYBERJACK_VENDOR_ID 0x0C4B -#define CYBERJACK_PRODUCT_ID 0x0100 - -/* Function prototypes */ -static int cyberjack_startup(struct usb_serial *serial); -static void cyberjack_disconnect(struct usb_serial *serial); -static void cyberjack_release(struct usb_serial *serial); -static int cyberjack_open(struct tty_struct *tty, - struct usb_serial_port *port); -static void cyberjack_close(struct usb_serial_port *port); -static int cyberjack_write(struct tty_struct *tty, - struct usb_serial_port *port, const unsigned char *buf, int count); -static int cyberjack_write_room(struct tty_struct *tty); -static void cyberjack_read_int_callback(struct urb *urb); -static void cyberjack_read_bulk_callback(struct urb *urb); -static void cyberjack_write_bulk_callback(struct urb *urb); - -static const struct usb_device_id id_table[] = { - { USB_DEVICE(CYBERJACK_VENDOR_ID, CYBERJACK_PRODUCT_ID) }, - { } /* Terminating entry */ -}; - -MODULE_DEVICE_TABLE(usb, id_table); - -static struct usb_driver cyberjack_driver = { - .name = "cyberjack", - .probe = usb_serial_probe, - .disconnect = usb_serial_disconnect, - .id_table = id_table, -}; - -static struct usb_serial_driver cyberjack_device = { - .driver = { - .owner = THIS_MODULE, - .name = "cyberjack", - }, - .description = "Reiner SCT Cyberjack USB card reader", - .id_table = id_table, - .num_ports = 1, - .attach = cyberjack_startup, - .disconnect = cyberjack_disconnect, - .release = cyberjack_release, - .open = cyberjack_open, - .close = cyberjack_close, - .write = cyberjack_write, - .write_room = cyberjack_write_room, - .read_int_callback = cyberjack_read_int_callback, - .read_bulk_callback = cyberjack_read_bulk_callback, - .write_bulk_callback = cyberjack_write_bulk_callback, -}; - -static struct usb_serial_driver * const serial_drivers[] = { - &cyberjack_device, NULL -}; - -struct cyberjack_private { - spinlock_t lock; /* Lock for SMP */ - short rdtodo; /* Bytes still to read */ - unsigned char wrbuf[5*64]; /* Buffer for collecting data to write */ - short wrfilled; /* Overall data size we already got */ - short wrsent; /* Data already sent */ -}; - -/* do some startup allocations not currently performed by usb_serial_probe() */ -static int cyberjack_startup(struct usb_serial *serial) -{ - struct cyberjack_private *priv; - int i; - - dbg("%s", __func__); - - /* allocate the private data structure */ - priv = kmalloc(sizeof(struct cyberjack_private), GFP_KERNEL); - if (!priv) - return -ENOMEM; - - /* set initial values */ - spin_lock_init(&priv->lock); - priv->rdtodo = 0; - priv->wrfilled = 0; - priv->wrsent = 0; - usb_set_serial_port_data(serial->port[0], priv); - - init_waitqueue_head(&serial->port[0]->write_wait); - - for (i = 0; i < serial->num_ports; ++i) { - int result; - result = usb_submit_urb(serial->port[i]->interrupt_in_urb, - GFP_KERNEL); - if (result) - dev_err(&serial->dev->dev, - "usb_submit_urb(read int) failed\n"); - dbg("%s - usb_submit_urb(int urb)", __func__); - } - - return 0; -} - -static void cyberjack_disconnect(struct usb_serial *serial) -{ - int i; - - dbg("%s", __func__); - - for (i = 0; i < serial->num_ports; ++i) - usb_kill_urb(serial->port[i]->interrupt_in_urb); -} - -static void cyberjack_release(struct usb_serial *serial) -{ - int i; - - dbg("%s", __func__); - - for (i = 0; i < serial->num_ports; ++i) { - /* My special items, the standard routines free my urbs */ - kfree(usb_get_serial_port_data(serial->port[i])); - } -} - -static int cyberjack_open(struct tty_struct *tty, - struct usb_serial_port *port) -{ - struct cyberjack_private *priv; - unsigned long flags; - int result = 0; - - dbg("%s - port %d", __func__, port->number); - - dbg("%s - usb_clear_halt", __func__); - usb_clear_halt(port->serial->dev, port->write_urb->pipe); - - priv = usb_get_serial_port_data(port); - spin_lock_irqsave(&priv->lock, flags); - priv->rdtodo = 0; - priv->wrfilled = 0; - priv->wrsent = 0; - spin_unlock_irqrestore(&priv->lock, flags); - - return result; -} - -static void cyberjack_close(struct usb_serial_port *port) -{ - dbg("%s - port %d", __func__, port->number); - - if (port->serial->dev) { - /* shutdown any bulk reads that might be going on */ - usb_kill_urb(port->write_urb); - usb_kill_urb(port->read_urb); - } -} - -static int cyberjack_write(struct tty_struct *tty, - struct usb_serial_port *port, const unsigned char *buf, int count) -{ - struct cyberjack_private *priv = usb_get_serial_port_data(port); - unsigned long flags; - int result; - int wrexpected; - - dbg("%s - port %d", __func__, port->number); - - if (count == 0) { - dbg("%s - write request of 0 bytes", __func__); - return 0; - } - - if (!test_and_clear_bit(0, &port->write_urbs_free)) { - dbg("%s - already writing", __func__); - return 0; - } - - spin_lock_irqsave(&priv->lock, flags); - - if (count+priv->wrfilled > sizeof(priv->wrbuf)) { - /* To much data for buffer. Reset buffer. */ - priv->wrfilled = 0; - spin_unlock_irqrestore(&priv->lock, flags); - set_bit(0, &port->write_urbs_free); - return 0; - } - - /* Copy data */ - memcpy(priv->wrbuf + priv->wrfilled, buf, count); - - usb_serial_debug_data(debug, &port->dev, __func__, count, - priv->wrbuf + priv->wrfilled); - priv->wrfilled += count; - - if (priv->wrfilled >= 3) { - wrexpected = ((int)priv->wrbuf[2]<<8)+priv->wrbuf[1]+3; - dbg("%s - expected data: %d", __func__, wrexpected); - } else - wrexpected = sizeof(priv->wrbuf); - - if (priv->wrfilled >= wrexpected) { - /* We have enough data to begin transmission */ - int length; - - dbg("%s - transmitting data (frame 1)", __func__); - length = (wrexpected > port->bulk_out_size) ? - port->bulk_out_size : wrexpected; - - memcpy(port->write_urb->transfer_buffer, priv->wrbuf, length); - priv->wrsent = length; - - /* set up our urb */ - port->write_urb->transfer_buffer_length = length; - - /* send the data out the bulk port */ - result = usb_submit_urb(port->write_urb, GFP_ATOMIC); - if (result) { - dev_err(&port->dev, - "%s - failed submitting write urb, error %d", - __func__, result); - /* Throw away data. No better idea what to do with it. */ - priv->wrfilled = 0; - priv->wrsent = 0; - spin_unlock_irqrestore(&priv->lock, flags); - set_bit(0, &port->write_urbs_free); - return 0; - } - - dbg("%s - priv->wrsent=%d", __func__, priv->wrsent); - dbg("%s - priv->wrfilled=%d", __func__, priv->wrfilled); - - if (priv->wrsent >= priv->wrfilled) { - dbg("%s - buffer cleaned", __func__); - memset(priv->wrbuf, 0, sizeof(priv->wrbuf)); - priv->wrfilled = 0; - priv->wrsent = 0; - } - } - - spin_unlock_irqrestore(&priv->lock, flags); - - return count; -} - -static int cyberjack_write_room(struct tty_struct *tty) -{ - /* FIXME: .... */ - return CYBERJACK_LOCAL_BUF_SIZE; -} - -static void cyberjack_read_int_callback(struct urb *urb) -{ - struct usb_serial_port *port = urb->context; - struct cyberjack_private *priv = usb_get_serial_port_data(port); - unsigned char *data = urb->transfer_buffer; - int status = urb->status; - int result; - - dbg("%s - port %d", __func__, port->number); - - /* the urb might have been killed. */ - if (status) - return; - - usb_serial_debug_data(debug, &port->dev, __func__, - urb->actual_length, data); - - /* React only to interrupts signaling a bulk_in transfer */ - if (urb->actual_length == 4 && data[0] == 0x01) { - short old_rdtodo; - - /* This is a announcement of coming bulk_ins. */ - unsigned short size = ((unsigned short)data[3]<<8)+data[2]+3; - - spin_lock(&priv->lock); - - old_rdtodo = priv->rdtodo; - - if (old_rdtodo + size < old_rdtodo) { - dbg("To many bulk_in urbs to do."); - spin_unlock(&priv->lock); - goto resubmit; - } - - /* "+=" is probably more fault tollerant than "=" */ - priv->rdtodo += size; - - dbg("%s - rdtodo: %d", __func__, priv->rdtodo); - - spin_unlock(&priv->lock); - - if (!old_rdtodo) { - result = usb_submit_urb(port->read_urb, GFP_ATOMIC); - if (result) - dev_err(&port->dev, "%s - failed resubmitting " - "read urb, error %d\n", - __func__, result); - dbg("%s - usb_submit_urb(read urb)", __func__); - } - } - -resubmit: - result = usb_submit_urb(port->interrupt_in_urb, GFP_ATOMIC); - if (result) - dev_err(&port->dev, "usb_submit_urb(read int) failed\n"); - dbg("%s - usb_submit_urb(int urb)", __func__); -} - -static void cyberjack_read_bulk_callback(struct urb *urb) -{ - struct usb_serial_port *port = urb->context; - struct cyberjack_private *priv = usb_get_serial_port_data(port); - struct tty_struct *tty; - unsigned char *data = urb->transfer_buffer; - short todo; - int result; - int status = urb->status; - - dbg("%s - port %d", __func__, port->number); - - usb_serial_debug_data(debug, &port->dev, __func__, - urb->actual_length, data); - if (status) { - dbg("%s - nonzero read bulk status received: %d", - __func__, status); - return; - } - - tty = tty_port_tty_get(&port->port); - if (!tty) { - dbg("%s - ignoring since device not open", __func__); - return; - } - if (urb->actual_length) { - tty_insert_flip_string(tty, data, urb->actual_length); - tty_flip_buffer_push(tty); - } - tty_kref_put(tty); - - spin_lock(&priv->lock); - - /* Reduce urbs to do by one. */ - priv->rdtodo -= urb->actual_length; - /* Just to be sure */ - if (priv->rdtodo < 0) - priv->rdtodo = 0; - todo = priv->rdtodo; - - spin_unlock(&priv->lock); - - dbg("%s - rdtodo: %d", __func__, todo); - - /* Continue to read if we have still urbs to do. */ - if (todo /* || (urb->actual_length==port->bulk_in_endpointAddress)*/) { - result = usb_submit_urb(port->read_urb, GFP_ATOMIC); - if (result) - dev_err(&port->dev, "%s - failed resubmitting read " - "urb, error %d\n", __func__, result); - dbg("%s - usb_submit_urb(read urb)", __func__); - } -} - -static void cyberjack_write_bulk_callback(struct urb *urb) -{ - struct usb_serial_port *port = urb->context; - struct cyberjack_private *priv = usb_get_serial_port_data(port); - int status = urb->status; - - dbg("%s - port %d", __func__, port->number); - - set_bit(0, &port->write_urbs_free); - if (status) { - dbg("%s - nonzero write bulk status received: %d", - __func__, status); - return; - } - - spin_lock(&priv->lock); - - /* only do something if we have more data to send */ - if (priv->wrfilled) { - int length, blksize, result; - - dbg("%s - transmitting data (frame n)", __func__); - - length = ((priv->wrfilled - priv->wrsent) > port->bulk_out_size) ? - port->bulk_out_size : (priv->wrfilled - priv->wrsent); - - memcpy(port->write_urb->transfer_buffer, - priv->wrbuf + priv->wrsent, length); - priv->wrsent += length; - - /* set up our urb */ - port->write_urb->transfer_buffer_length = length; - - /* send the data out the bulk port */ - result = usb_submit_urb(port->write_urb, GFP_ATOMIC); - if (result) { - dev_err(&port->dev, - "%s - failed submitting write urb, error %d\n", - __func__, result); - /* Throw away data. No better idea what to do with it. */ - priv->wrfilled = 0; - priv->wrsent = 0; - goto exit; - } - - dbg("%s - priv->wrsent=%d", __func__, priv->wrsent); - dbg("%s - priv->wrfilled=%d", __func__, priv->wrfilled); - - blksize = ((int)priv->wrbuf[2]<<8)+priv->wrbuf[1]+3; - - if (priv->wrsent >= priv->wrfilled || - priv->wrsent >= blksize) { - dbg("%s - buffer cleaned", __func__); - memset(priv->wrbuf, 0, sizeof(priv->wrbuf)); - priv->wrfilled = 0; - priv->wrsent = 0; - } - } - -exit: - spin_unlock(&priv->lock); - usb_serial_port_softint(port); -} - -module_usb_serial_driver(cyberjack_driver, serial_drivers); - -MODULE_AUTHOR(DRIVER_AUTHOR); -MODULE_DESCRIPTION(DRIVER_DESC); -MODULE_VERSION(DRIVER_VERSION); -MODULE_LICENSE("GPL"); - -module_param(debug, bool, S_IRUGO | S_IWUSR); -MODULE_PARM_DESC(debug, "Debug enabled or not"); diff --git a/ANDROID_3.4.5/drivers/usb/serial/cypress_m8.c b/ANDROID_3.4.5/drivers/usb/serial/cypress_m8.c deleted file mode 100644 index afc886c7..00000000 --- a/ANDROID_3.4.5/drivers/usb/serial/cypress_m8.c +++ /dev/null @@ -1,1363 +0,0 @@ -/* - * USB Cypress M8 driver - * - * Copyright (C) 2004 - * Lonnie Mendez (dignome@gmail.com) - * Copyright (C) 2003,2004 - * Neil Whelchel (koyama@firstlight.net) - * - * 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. - * - * See Documentation/usb/usb-serial.txt for more information on using this - * driver - * - * See http://geocities.com/i0xox0i for information on this driver and the - * earthmate usb device. - */ - -/* Thanks to Neil Whelchel for writing the first cypress m8 implementation - for linux. */ -/* Thanks to cypress for providing references for the hid reports. */ -/* Thanks to Jiang Zhang for providing links and for general help. */ -/* Code originates and was built up from ftdi_sio, belkin, pl2303 and others.*/ - - -#include <linux/kernel.h> -#include <linux/errno.h> -#include <linux/init.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/moduleparam.h> -#include <linux/spinlock.h> -#include <linux/usb.h> -#include <linux/usb/serial.h> -#include <linux/serial.h> -#include <linux/kfifo.h> -#include <linux/delay.h> -#include <linux/uaccess.h> -#include <asm/unaligned.h> - -#include "cypress_m8.h" - - -static bool debug; -static bool stats; -static int interval; -static bool unstable_bauds; - -/* - * Version Information - */ -#define DRIVER_VERSION "v1.10" -#define DRIVER_AUTHOR "Lonnie Mendez <dignome@gmail.com>, Neil Whelchel <koyama@firstlight.net>" -#define DRIVER_DESC "Cypress USB to Serial Driver" - -/* write buffer size defines */ -#define CYPRESS_BUF_SIZE 1024 - -static const struct usb_device_id id_table_earthmate[] = { - { USB_DEVICE(VENDOR_ID_DELORME, PRODUCT_ID_EARTHMATEUSB) }, - { USB_DEVICE(VENDOR_ID_DELORME, PRODUCT_ID_EARTHMATEUSB_LT20) }, - { } /* Terminating entry */ -}; - -static const struct usb_device_id id_table_cyphidcomrs232[] = { - { USB_DEVICE(VENDOR_ID_CYPRESS, PRODUCT_ID_CYPHIDCOM) }, - { USB_DEVICE(VENDOR_ID_POWERCOM, PRODUCT_ID_UPS) }, - { } /* Terminating entry */ -}; - -static const struct usb_device_id id_table_nokiaca42v2[] = { - { USB_DEVICE(VENDOR_ID_DAZZLE, PRODUCT_ID_CA42) }, - { } /* Terminating entry */ -}; - -static const struct usb_device_id id_table_combined[] = { - { USB_DEVICE(VENDOR_ID_DELORME, PRODUCT_ID_EARTHMATEUSB) }, - { USB_DEVICE(VENDOR_ID_DELORME, PRODUCT_ID_EARTHMATEUSB_LT20) }, - { USB_DEVICE(VENDOR_ID_CYPRESS, PRODUCT_ID_CYPHIDCOM) }, - { USB_DEVICE(VENDOR_ID_POWERCOM, PRODUCT_ID_UPS) }, - { USB_DEVICE(VENDOR_ID_DAZZLE, PRODUCT_ID_CA42) }, - { } /* Terminating entry */ -}; - -MODULE_DEVICE_TABLE(usb, id_table_combined); - -static struct usb_driver cypress_driver = { - .name = "cypress", - .probe = usb_serial_probe, - .disconnect = usb_serial_disconnect, - .id_table = id_table_combined, -}; - -enum packet_format { - packet_format_1, /* b0:status, b1:payload count */ - packet_format_2 /* b0[7:3]:status, b0[2:0]:payload count */ -}; - -struct cypress_private { - spinlock_t lock; /* private lock */ - int chiptype; /* identifier of device, for quirks/etc */ - int bytes_in; /* used for statistics */ - int bytes_out; /* used for statistics */ - int cmd_count; /* used for statistics */ - int cmd_ctrl; /* always set this to 1 before issuing a command */ - struct kfifo write_fifo; /* write fifo */ - int write_urb_in_use; /* write urb in use indicator */ - int write_urb_interval; /* interval to use for write urb */ - int read_urb_interval; /* interval to use for read urb */ - int comm_is_ok; /* true if communication is (still) ok */ - int termios_initialized; - __u8 line_control; /* holds dtr / rts value */ - __u8 current_status; /* received from last read - info on dsr,cts,cd,ri,etc */ - __u8 current_config; /* stores the current configuration byte */ - __u8 rx_flags; /* throttling - used from whiteheat/ftdi_sio */ - enum packet_format pkt_fmt; /* format to use for packet send / receive */ - int get_cfg_unsafe; /* If true, the CYPRESS_GET_CONFIG is unsafe */ - int baud_rate; /* stores current baud rate in - integer form */ - int isthrottled; /* if throttled, discard reads */ - wait_queue_head_t delta_msr_wait; /* used for TIOCMIWAIT */ - char prev_status, diff_status; /* used for TIOCMIWAIT */ - /* we pass a pointer to this as the argument sent to - cypress_set_termios old_termios */ - struct ktermios tmp_termios; /* stores the old termios settings */ -}; - -/* function prototypes for the Cypress USB to serial device */ -static int cypress_earthmate_startup(struct usb_serial *serial); -static int cypress_hidcom_startup(struct usb_serial *serial); -static int cypress_ca42v2_startup(struct usb_serial *serial); -static void cypress_release(struct usb_serial *serial); -static int cypress_open(struct tty_struct *tty, struct usb_serial_port *port); -static void cypress_close(struct usb_serial_port *port); -static void cypress_dtr_rts(struct usb_serial_port *port, int on); -static int cypress_write(struct tty_struct *tty, struct usb_serial_port *port, - const unsigned char *buf, int count); -static void cypress_send(struct usb_serial_port *port); -static int cypress_write_room(struct tty_struct *tty); -static int cypress_ioctl(struct tty_struct *tty, - unsigned int cmd, unsigned long arg); -static void cypress_set_termios(struct tty_struct *tty, - struct usb_serial_port *port, struct ktermios *old); -static int cypress_tiocmget(struct tty_struct *tty); -static int cypress_tiocmset(struct tty_struct *tty, - unsigned int set, unsigned int clear); -static int cypress_chars_in_buffer(struct tty_struct *tty); -static void cypress_throttle(struct tty_struct *tty); -static void cypress_unthrottle(struct tty_struct *tty); -static void cypress_set_dead(struct usb_serial_port *port); -static void cypress_read_int_callback(struct urb *urb); -static void cypress_write_int_callback(struct urb *urb); - -static struct usb_serial_driver cypress_earthmate_device = { - .driver = { - .owner = THIS_MODULE, - .name = "earthmate", - }, - .description = "DeLorme Earthmate USB", - .id_table = id_table_earthmate, - .num_ports = 1, - .attach = cypress_earthmate_startup, - .release = cypress_release, - .open = cypress_open, - .close = cypress_close, - .dtr_rts = cypress_dtr_rts, - .write = cypress_write, - .write_room = cypress_write_room, - .ioctl = cypress_ioctl, - .set_termios = cypress_set_termios, - .tiocmget = cypress_tiocmget, - .tiocmset = cypress_tiocmset, - .chars_in_buffer = cypress_chars_in_buffer, - .throttle = cypress_throttle, - .unthrottle = cypress_unthrottle, - .read_int_callback = cypress_read_int_callback, - .write_int_callback = cypress_write_int_callback, -}; - -static struct usb_serial_driver cypress_hidcom_device = { - .driver = { - .owner = THIS_MODULE, - .name = "cyphidcom", - }, - .description = "HID->COM RS232 Adapter", - .id_table = id_table_cyphidcomrs232, - .num_ports = 1, - .attach = cypress_hidcom_startup, - .release = cypress_release, - .open = cypress_open, - .close = cypress_close, - .dtr_rts = cypress_dtr_rts, - .write = cypress_write, - .write_room = cypress_write_room, - .ioctl = cypress_ioctl, - .set_termios = cypress_set_termios, - .tiocmget = cypress_tiocmget, - .tiocmset = cypress_tiocmset, - .chars_in_buffer = cypress_chars_in_buffer, - .throttle = cypress_throttle, - .unthrottle = cypress_unthrottle, - .read_int_callback = cypress_read_int_callback, - .write_int_callback = cypress_write_int_callback, -}; - -static struct usb_serial_driver cypress_ca42v2_device = { - .driver = { - .owner = THIS_MODULE, - .name = "nokiaca42v2", - }, - .description = "Nokia CA-42 V2 Adapter", - .id_table = id_table_nokiaca42v2, - .num_ports = 1, - .attach = cypress_ca42v2_startup, - .release = cypress_release, - .open = cypress_open, - .close = cypress_close, - .dtr_rts = cypress_dtr_rts, - .write = cypress_write, - .write_room = cypress_write_room, - .ioctl = cypress_ioctl, - .set_termios = cypress_set_termios, - .tiocmget = cypress_tiocmget, - .tiocmset = cypress_tiocmset, - .chars_in_buffer = cypress_chars_in_buffer, - .throttle = cypress_throttle, - .unthrottle = cypress_unthrottle, - .read_int_callback = cypress_read_int_callback, - .write_int_callback = cypress_write_int_callback, -}; - -static struct usb_serial_driver * const serial_drivers[] = { - &cypress_earthmate_device, &cypress_hidcom_device, - &cypress_ca42v2_device, NULL -}; - -/***************************************************************************** - * Cypress serial helper functions - *****************************************************************************/ - - -static int analyze_baud_rate(struct usb_serial_port *port, speed_t new_rate) -{ - struct cypress_private *priv; - priv = usb_get_serial_port_data(port); - - if (unstable_bauds) - return new_rate; - - /* - * The general purpose firmware for the Cypress M8 allows for - * a maximum speed of 57600bps (I have no idea whether DeLorme - * chose to use the general purpose firmware or not), if you - * need to modify this speed setting for your own project - * please add your own chiptype and modify the code likewise. - * The Cypress HID->COM device will work successfully up to - * 115200bps (but the actual throughput is around 3kBps). - */ - if (port->serial->dev->speed == USB_SPEED_LOW) { - /* - * Mike Isely <isely@pobox.com> 2-Feb-2008: The - * Cypress app note that describes this mechanism - * states the the low-speed part can't handle more - * than 800 bytes/sec, in which case 4800 baud is the - * safest speed for a part like that. - */ - if (new_rate > 4800) { - dbg("%s - failed setting baud rate, device incapable " - "speed %d", __func__, new_rate); - return -1; - } - } - switch (priv->chiptype) { - case CT_EARTHMATE: - if (new_rate <= 600) { - /* 300 and 600 baud rates are supported under - * the generic firmware, but are not used with - * NMEA and SiRF protocols */ - dbg("%s - failed setting baud rate, unsupported speed " - "of %d on Earthmate GPS", __func__, new_rate); - return -1; - } - break; - default: - break; - } - return new_rate; -} - - -/* This function can either set or retrieve the current serial line settings */ -static int cypress_serial_control(struct tty_struct *tty, - struct usb_serial_port *port, speed_t baud_rate, int data_bits, - int stop_bits, int parity_enable, int parity_type, int reset, - int cypress_request_type) -{ - int new_baudrate = 0, retval = 0, tries = 0; - struct cypress_private *priv; - u8 *feature_buffer; - const unsigned int feature_len = 5; - unsigned long flags; - - dbg("%s", __func__); - - priv = usb_get_serial_port_data(port); - - if (!priv->comm_is_ok) - return -ENODEV; - - feature_buffer = kcalloc(feature_len, sizeof(u8), GFP_KERNEL); - if (!feature_buffer) - return -ENOMEM; - - switch (cypress_request_type) { - case CYPRESS_SET_CONFIG: - /* 0 means 'Hang up' so doesn't change the true bit rate */ - new_baudrate = priv->baud_rate; - if (baud_rate && baud_rate != priv->baud_rate) { - dbg("%s - baud rate is changing", __func__); - retval = analyze_baud_rate(port, baud_rate); - if (retval >= 0) { - new_baudrate = retval; - dbg("%s - New baud rate set to %d", - __func__, new_baudrate); - } - } - dbg("%s - baud rate is being sent as %d", - __func__, new_baudrate); - - /* fill the feature_buffer with new configuration */ - put_unaligned_le32(new_baudrate, feature_buffer); - feature_buffer[4] |= data_bits; /* assign data bits in 2 bit space ( max 3 ) */ - /* 1 bit gap */ - feature_buffer[4] |= (stop_bits << 3); /* assign stop bits in 1 bit space */ - feature_buffer[4] |= (parity_enable << 4); /* assign parity flag in 1 bit space */ - feature_buffer[4] |= (parity_type << 5); /* assign parity type in 1 bit space */ - /* 1 bit gap */ - feature_buffer[4] |= (reset << 7); /* assign reset at end of byte, 1 bit space */ - - dbg("%s - device is being sent this feature report:", - __func__); - dbg("%s - %02X - %02X - %02X - %02X - %02X", __func__, - feature_buffer[0], feature_buffer[1], - feature_buffer[2], feature_buffer[3], - feature_buffer[4]); - - do { - retval = usb_control_msg(port->serial->dev, - usb_sndctrlpipe(port->serial->dev, 0), - HID_REQ_SET_REPORT, - USB_DIR_OUT | USB_RECIP_INTERFACE | USB_TYPE_CLASS, - 0x0300, 0, feature_buffer, - feature_len, 500); - - if (tries++ >= 3) - break; - - } while (retval != feature_len && - retval != -ENODEV); - - if (retval != feature_len) { - dev_err(&port->dev, "%s - failed sending serial " - "line settings - %d\n", __func__, retval); - cypress_set_dead(port); - } else { - spin_lock_irqsave(&priv->lock, flags); - priv->baud_rate = new_baudrate; - priv->current_config = feature_buffer[4]; - spin_unlock_irqrestore(&priv->lock, flags); - /* If we asked for a speed change encode it */ - if (baud_rate) - tty_encode_baud_rate(tty, - new_baudrate, new_baudrate); - } - break; - case CYPRESS_GET_CONFIG: - if (priv->get_cfg_unsafe) { - /* Not implemented for this device, - and if we try to do it we're likely - to crash the hardware. */ - retval = -ENOTTY; - goto out; - } - dbg("%s - retreiving serial line settings", __func__); - do { - retval = usb_control_msg(port->serial->dev, - usb_rcvctrlpipe(port->serial->dev, 0), - HID_REQ_GET_REPORT, - USB_DIR_IN | USB_RECIP_INTERFACE | USB_TYPE_CLASS, - 0x0300, 0, feature_buffer, - feature_len, 500); - - if (tries++ >= 3) - break; - } while (retval != feature_len - && retval != -ENODEV); - - if (retval != feature_len) { - dev_err(&port->dev, "%s - failed to retrieve serial " - "line settings - %d\n", __func__, retval); - cypress_set_dead(port); - goto out; - } else { - spin_lock_irqsave(&priv->lock, flags); - /* store the config in one byte, and later - use bit masks to check values */ - priv->current_config = feature_buffer[4]; - priv->baud_rate = get_unaligned_le32(feature_buffer); - spin_unlock_irqrestore(&priv->lock, flags); - } - } - spin_lock_irqsave(&priv->lock, flags); - ++priv->cmd_count; - spin_unlock_irqrestore(&priv->lock, flags); -out: - kfree(feature_buffer); - return retval; -} /* cypress_serial_control */ - - -static void cypress_set_dead(struct usb_serial_port *port) -{ - struct cypress_private *priv = usb_get_serial_port_data(port); - unsigned long flags; - - spin_lock_irqsave(&priv->lock, flags); - if (!priv->comm_is_ok) { - spin_unlock_irqrestore(&priv->lock, flags); - return; - } - priv->comm_is_ok = 0; - spin_unlock_irqrestore(&priv->lock, flags); - - dev_err(&port->dev, "cypress_m8 suspending failing port %d - " - "interval might be too short\n", port->number); -} - - -/***************************************************************************** - * Cypress serial driver functions - *****************************************************************************/ - - -static int generic_startup(struct usb_serial *serial) -{ - struct cypress_private *priv; - struct usb_serial_port *port = serial->port[0]; - - dbg("%s - port %d", __func__, port->number); - - priv = kzalloc(sizeof(struct cypress_private), GFP_KERNEL); - if (!priv) - return -ENOMEM; - - priv->comm_is_ok = !0; - spin_lock_init(&priv->lock); - if (kfifo_alloc(&priv->write_fifo, CYPRESS_BUF_SIZE, GFP_KERNEL)) { - kfree(priv); - return -ENOMEM; - } - init_waitqueue_head(&priv->delta_msr_wait); - - usb_reset_configuration(serial->dev); - - priv->cmd_ctrl = 0; - priv->line_control = 0; - priv->termios_initialized = 0; - priv->rx_flags = 0; - /* Default packet format setting is determined by packet size. - Anything with a size larger then 9 must have a separate - count field since the 3 bit count field is otherwise too - small. Otherwise we can use the slightly more compact - format. This is in accordance with the cypress_m8 serial - converter app note. */ - if (port->interrupt_out_size > 9) - priv->pkt_fmt = packet_format_1; - else - priv->pkt_fmt = packet_format_2; - - if (interval > 0) { - priv->write_urb_interval = interval; - priv->read_urb_interval = interval; - dbg("%s - port %d read & write intervals forced to %d", - __func__, port->number, interval); - } else { - priv->write_urb_interval = port->interrupt_out_urb->interval; - priv->read_urb_interval = port->interrupt_in_urb->interval; - dbg("%s - port %d intervals: read=%d write=%d", - __func__, port->number, - priv->read_urb_interval, priv->write_urb_interval); - } - usb_set_serial_port_data(port, priv); - - return 0; -} - - -static int cypress_earthmate_startup(struct usb_serial *serial) -{ - struct cypress_private *priv; - struct usb_serial_port *port = serial->port[0]; - - dbg("%s", __func__); - - if (generic_startup(serial)) { - dbg("%s - Failed setting up port %d", __func__, - port->number); - return 1; - } - - priv = usb_get_serial_port_data(port); - priv->chiptype = CT_EARTHMATE; - /* All Earthmate devices use the separated-count packet - format! Idiotic. */ - priv->pkt_fmt = packet_format_1; - if (serial->dev->descriptor.idProduct != - cpu_to_le16(PRODUCT_ID_EARTHMATEUSB)) { - /* The old original USB Earthmate seemed able to - handle GET_CONFIG requests; everything they've - produced since that time crashes if this command is - attempted :-( */ - dbg("%s - Marking this device as unsafe for GET_CONFIG " - "commands", __func__); - priv->get_cfg_unsafe = !0; - } - - return 0; -} /* cypress_earthmate_startup */ - - -static int cypress_hidcom_startup(struct usb_serial *serial) -{ - struct cypress_private *priv; - - dbg("%s", __func__); - - if (generic_startup(serial)) { - dbg("%s - Failed setting up port %d", __func__, - serial->port[0]->number); - return 1; - } - - priv = usb_get_serial_port_data(serial->port[0]); - priv->chiptype = CT_CYPHIDCOM; - - return 0; -} /* cypress_hidcom_startup */ - - -static int cypress_ca42v2_startup(struct usb_serial *serial) -{ - struct cypress_private *priv; - - dbg("%s", __func__); - - if (generic_startup(serial)) { - dbg("%s - Failed setting up port %d", __func__, - serial->port[0]->number); - return 1; - } - - priv = usb_get_serial_port_data(serial->port[0]); - priv->chiptype = CT_CA42V2; - - return 0; -} /* cypress_ca42v2_startup */ - - -static void cypress_release(struct usb_serial *serial) -{ - struct cypress_private *priv; - - dbg("%s - port %d", __func__, serial->port[0]->number); - - /* all open ports are closed at this point */ - - priv = usb_get_serial_port_data(serial->port[0]); - - if (priv) { - kfifo_free(&priv->write_fifo); - kfree(priv); - } -} - - -static int cypress_open(struct tty_struct *tty, struct usb_serial_port *port) -{ - struct cypress_private *priv = usb_get_serial_port_data(port); - struct usb_serial *serial = port->serial; - unsigned long flags; - int result = 0; - - dbg("%s - port %d", __func__, port->number); - - if (!priv->comm_is_ok) - return -EIO; - - /* clear halts before open */ - usb_clear_halt(serial->dev, 0x81); - usb_clear_halt(serial->dev, 0x02); - - spin_lock_irqsave(&priv->lock, flags); - /* reset read/write statistics */ - priv->bytes_in = 0; - priv->bytes_out = 0; - priv->cmd_count = 0; - priv->rx_flags = 0; - spin_unlock_irqrestore(&priv->lock, flags); - - /* Set termios */ - cypress_send(port); - - if (tty) - cypress_set_termios(tty, port, &priv->tmp_termios); - - /* setup the port and start reading from the device */ - if (!port->interrupt_in_urb) { - dev_err(&port->dev, "%s - interrupt_in_urb is empty!\n", - __func__); - return -1; - } - - usb_fill_int_urb(port->interrupt_in_urb, serial->dev, - usb_rcvintpipe(serial->dev, port->interrupt_in_endpointAddress), - port->interrupt_in_urb->transfer_buffer, - port->interrupt_in_urb->transfer_buffer_length, - cypress_read_int_callback, port, priv->read_urb_interval); - result = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL); - - if (result) { - dev_err(&port->dev, - "%s - failed submitting read urb, error %d\n", - __func__, result); - cypress_set_dead(port); - } - port->port.drain_delay = 256; - return result; -} /* cypress_open */ - -static void cypress_dtr_rts(struct usb_serial_port *port, int on) -{ - struct cypress_private *priv = usb_get_serial_port_data(port); - /* drop dtr and rts */ - spin_lock_irq(&priv->lock); - if (on == 0) - priv->line_control = 0; - else - priv->line_control = CONTROL_DTR | CONTROL_RTS; - priv->cmd_ctrl = 1; - spin_unlock_irq(&priv->lock); - cypress_write(NULL, port, NULL, 0); -} - -static void cypress_close(struct usb_serial_port *port) -{ - struct cypress_private *priv = usb_get_serial_port_data(port); - unsigned long flags; - - dbg("%s - port %d", __func__, port->number); - - /* writing is potentially harmful, lock must be taken */ - mutex_lock(&port->serial->disc_mutex); - if (port->serial->disconnected) { - mutex_unlock(&port->serial->disc_mutex); - return; - } - spin_lock_irqsave(&priv->lock, flags); - kfifo_reset_out(&priv->write_fifo); - spin_unlock_irqrestore(&priv->lock, flags); - - dbg("%s - stopping urbs", __func__); - usb_kill_urb(port->interrupt_in_urb); - usb_kill_urb(port->interrupt_out_urb); - - if (stats) - dev_info(&port->dev, "Statistics: %d Bytes In | %d Bytes Out | %d Commands Issued\n", - priv->bytes_in, priv->bytes_out, priv->cmd_count); - mutex_unlock(&port->serial->disc_mutex); -} /* cypress_close */ - - -static int cypress_write(struct tty_struct *tty, struct usb_serial_port *port, - const unsigned char *buf, int count) -{ - struct cypress_private *priv = usb_get_serial_port_data(port); - - dbg("%s - port %d, %d bytes", __func__, port->number, count); - - /* line control commands, which need to be executed immediately, - are not put into the buffer for obvious reasons. - */ - if (priv->cmd_ctrl) { - count = 0; - goto finish; - } - - if (!count) - return count; - - count = kfifo_in_locked(&priv->write_fifo, buf, count, &priv->lock); - -finish: - cypress_send(port); - - return count; -} /* cypress_write */ - - -static void cypress_send(struct usb_serial_port *port) -{ - int count = 0, result, offset, actual_size; - struct cypress_private *priv = usb_get_serial_port_data(port); - unsigned long flags; - - if (!priv->comm_is_ok) - return; - - dbg("%s - port %d", __func__, port->number); - dbg("%s - interrupt out size is %d", __func__, - port->interrupt_out_size); - - spin_lock_irqsave(&priv->lock, flags); - if (priv->write_urb_in_use) { - dbg("%s - can't write, urb in use", __func__); - spin_unlock_irqrestore(&priv->lock, flags); - return; - } - spin_unlock_irqrestore(&priv->lock, flags); - - /* clear buffer */ - memset(port->interrupt_out_urb->transfer_buffer, 0, - port->interrupt_out_size); - - spin_lock_irqsave(&priv->lock, flags); - switch (priv->pkt_fmt) { - default: - case packet_format_1: - /* this is for the CY7C64013... */ - offset = 2; - port->interrupt_out_buffer[0] = priv->line_control; - break; - case packet_format_2: - /* this is for the CY7C63743... */ - offset = 1; - port->interrupt_out_buffer[0] = priv->line_control; - break; - } - - if (priv->line_control & CONTROL_RESET) - priv->line_control &= ~CONTROL_RESET; - - if (priv->cmd_ctrl) { - priv->cmd_count++; - dbg("%s - line control command being issued", __func__); - spin_unlock_irqrestore(&priv->lock, flags); - goto send; - } else - spin_unlock_irqrestore(&priv->lock, flags); - - count = kfifo_out_locked(&priv->write_fifo, - &port->interrupt_out_buffer[offset], - port->interrupt_out_size - offset, - &priv->lock); - if (count == 0) - return; - - switch (priv->pkt_fmt) { - default: - case packet_format_1: - port->interrupt_out_buffer[1] = count; - break; - case packet_format_2: - port->interrupt_out_buffer[0] |= count; - } - - dbg("%s - count is %d", __func__, count); - -send: - spin_lock_irqsave(&priv->lock, flags); - priv->write_urb_in_use = 1; - spin_unlock_irqrestore(&priv->lock, flags); - - if (priv->cmd_ctrl) - actual_size = 1; - else - actual_size = count + - (priv->pkt_fmt == packet_format_1 ? 2 : 1); - - usb_serial_debug_data(debug, &port->dev, __func__, - port->interrupt_out_size, - port->interrupt_out_urb->transfer_buffer); - - usb_fill_int_urb(port->interrupt_out_urb, port->serial->dev, - usb_sndintpipe(port->serial->dev, port->interrupt_out_endpointAddress), - port->interrupt_out_buffer, port->interrupt_out_size, - cypress_write_int_callback, port, priv->write_urb_interval); - result = usb_submit_urb(port->interrupt_out_urb, GFP_ATOMIC); - if (result) { - dev_err_console(port, - "%s - failed submitting write urb, error %d\n", - __func__, result); - priv->write_urb_in_use = 0; - cypress_set_dead(port); - } - - spin_lock_irqsave(&priv->lock, flags); - if (priv->cmd_ctrl) - priv->cmd_ctrl = 0; - - /* do not count the line control and size bytes */ - priv->bytes_out += count; - spin_unlock_irqrestore(&priv->lock, flags); - - usb_serial_port_softint(port); -} /* cypress_send */ - - -/* returns how much space is available in the soft buffer */ -static int cypress_write_room(struct tty_struct *tty) -{ - struct usb_serial_port *port = tty->driver_data; - struct cypress_private *priv = usb_get_serial_port_data(port); - int room = 0; - unsigned long flags; - - dbg("%s - port %d", __func__, port->number); - - spin_lock_irqsave(&priv->lock, flags); - room = kfifo_avail(&priv->write_fifo); - spin_unlock_irqrestore(&priv->lock, flags); - - dbg("%s - returns %d", __func__, room); - return room; -} - - -static int cypress_tiocmget(struct tty_struct *tty) -{ - struct usb_serial_port *port = tty->driver_data; - struct cypress_private *priv = usb_get_serial_port_data(port); - __u8 status, control; - unsigned int result = 0; - unsigned long flags; - - dbg("%s - port %d", __func__, port->number); - - spin_lock_irqsave(&priv->lock, flags); - control = priv->line_control; - status = priv->current_status; - spin_unlock_irqrestore(&priv->lock, flags); - - result = ((control & CONTROL_DTR) ? TIOCM_DTR : 0) - | ((control & CONTROL_RTS) ? TIOCM_RTS : 0) - | ((status & UART_CTS) ? TIOCM_CTS : 0) - | ((status & UART_DSR) ? TIOCM_DSR : 0) - | ((status & UART_RI) ? TIOCM_RI : 0) - | ((status & UART_CD) ? TIOCM_CD : 0); - - dbg("%s - result = %x", __func__, result); - - return result; -} - - -static int cypress_tiocmset(struct tty_struct *tty, - unsigned int set, unsigned int clear) -{ - struct usb_serial_port *port = tty->driver_data; - struct cypress_private *priv = usb_get_serial_port_data(port); - unsigned long flags; - - dbg("%s - port %d", __func__, port->number); - - spin_lock_irqsave(&priv->lock, flags); - if (set & TIOCM_RTS) - priv->line_control |= CONTROL_RTS; - if (set & TIOCM_DTR) - priv->line_control |= CONTROL_DTR; - if (clear & TIOCM_RTS) - priv->line_control &= ~CONTROL_RTS; - if (clear & TIOCM_DTR) - priv->line_control &= ~CONTROL_DTR; - priv->cmd_ctrl = 1; - spin_unlock_irqrestore(&priv->lock, flags); - - return cypress_write(tty, port, NULL, 0); -} - - -static int cypress_ioctl(struct tty_struct *tty, - unsigned int cmd, unsigned long arg) -{ - struct usb_serial_port *port = tty->driver_data; - struct cypress_private *priv = usb_get_serial_port_data(port); - - dbg("%s - port %d, cmd 0x%.4x", __func__, port->number, cmd); - - switch (cmd) { - /* This code comes from drivers/char/serial.c and ftdi_sio.c */ - case TIOCMIWAIT: - while (priv != NULL) { - interruptible_sleep_on(&priv->delta_msr_wait); - /* see if a signal did it */ - if (signal_pending(current)) - return -ERESTARTSYS; - else { - char diff = priv->diff_status; - if (diff == 0) - return -EIO; /* no change => error */ - - /* consume all events */ - priv->diff_status = 0; - - /* return 0 if caller wanted to know about - these bits */ - if (((arg & TIOCM_RNG) && (diff & UART_RI)) || - ((arg & TIOCM_DSR) && (diff & UART_DSR)) || - ((arg & TIOCM_CD) && (diff & UART_CD)) || - ((arg & TIOCM_CTS) && (diff & UART_CTS))) - return 0; - /* otherwise caller can't care less about what - * happened, and so we continue to wait for - * more events. - */ - } - } - return 0; - default: - break; - } - dbg("%s - arg not supported - it was 0x%04x - check include/asm/ioctls.h", __func__, cmd); - return -ENOIOCTLCMD; -} /* cypress_ioctl */ - - -static void cypress_set_termios(struct tty_struct *tty, - struct usb_serial_port *port, struct ktermios *old_termios) -{ - struct cypress_private *priv = usb_get_serial_port_data(port); - int data_bits, stop_bits, parity_type, parity_enable; - unsigned cflag, iflag; - unsigned long flags; - __u8 oldlines; - int linechange = 0; - - dbg("%s - port %d", __func__, port->number); - - spin_lock_irqsave(&priv->lock, flags); - /* We can't clean this one up as we don't know the device type - early enough */ - if (!priv->termios_initialized) { - if (priv->chiptype == CT_EARTHMATE) { - *(tty->termios) = tty_std_termios; - tty->termios->c_cflag = B4800 | CS8 | CREAD | HUPCL | - CLOCAL; - tty->termios->c_ispeed = 4800; - tty->termios->c_ospeed = 4800; - } else if (priv->chiptype == CT_CYPHIDCOM) { - *(tty->termios) = tty_std_termios; - tty->termios->c_cflag = B9600 | CS8 | CREAD | HUPCL | - CLOCAL; - tty->termios->c_ispeed = 9600; - tty->termios->c_ospeed = 9600; - } else if (priv->chiptype == CT_CA42V2) { - *(tty->termios) = tty_std_termios; - tty->termios->c_cflag = B9600 | CS8 | CREAD | HUPCL | - CLOCAL; - tty->termios->c_ispeed = 9600; - tty->termios->c_ospeed = 9600; - } - priv->termios_initialized = 1; - } - spin_unlock_irqrestore(&priv->lock, flags); - - /* Unsupported features need clearing */ - tty->termios->c_cflag &= ~(CMSPAR|CRTSCTS); - - cflag = tty->termios->c_cflag; - iflag = tty->termios->c_iflag; - - /* check if there are new settings */ - if (old_termios) { - spin_lock_irqsave(&priv->lock, flags); - priv->tmp_termios = *(tty->termios); - spin_unlock_irqrestore(&priv->lock, flags); - } - - /* set number of data bits, parity, stop bits */ - /* when parity is disabled the parity type bit is ignored */ - - /* 1 means 2 stop bits, 0 means 1 stop bit */ - stop_bits = cflag & CSTOPB ? 1 : 0; - - if (cflag & PARENB) { - parity_enable = 1; - /* 1 means odd parity, 0 means even parity */ - parity_type = cflag & PARODD ? 1 : 0; - } else - parity_enable = parity_type = 0; - - switch (cflag & CSIZE) { - case CS5: - data_bits = 0; - break; - case CS6: - data_bits = 1; - break; - case CS7: - data_bits = 2; - break; - case CS8: - data_bits = 3; - break; - default: - dev_err(&port->dev, "%s - CSIZE was set, but not CS5-CS8\n", - __func__); - data_bits = 3; - } - spin_lock_irqsave(&priv->lock, flags); - oldlines = priv->line_control; - if ((cflag & CBAUD) == B0) { - /* drop dtr and rts */ - dbg("%s - dropping the lines, baud rate 0bps", __func__); - priv->line_control &= ~(CONTROL_DTR | CONTROL_RTS); - } else - priv->line_control = (CONTROL_DTR | CONTROL_RTS); - spin_unlock_irqrestore(&priv->lock, flags); - - dbg("%s - sending %d stop_bits, %d parity_enable, %d parity_type, " - "%d data_bits (+5)", __func__, stop_bits, - parity_enable, parity_type, data_bits); - - cypress_serial_control(tty, port, tty_get_baud_rate(tty), - data_bits, stop_bits, - parity_enable, parity_type, - 0, CYPRESS_SET_CONFIG); - - /* we perform a CYPRESS_GET_CONFIG so that the current settings are - * filled into the private structure this should confirm that all is - * working if it returns what we just set */ - cypress_serial_control(tty, port, 0, 0, 0, 0, 0, 0, CYPRESS_GET_CONFIG); - - /* Here we can define custom tty settings for devices; the main tty - * termios flag base comes from empeg.c */ - - spin_lock_irqsave(&priv->lock, flags); - if (priv->chiptype == CT_EARTHMATE && priv->baud_rate == 4800) { - dbg("Using custom termios settings for a baud rate of " - "4800bps."); - /* define custom termios settings for NMEA protocol */ - - tty->termios->c_iflag /* input modes - */ - &= ~(IGNBRK /* disable ignore break */ - | BRKINT /* disable break causes interrupt */ - | PARMRK /* disable mark parity errors */ - | ISTRIP /* disable clear high bit of input char */ - | INLCR /* disable translate NL to CR */ - | IGNCR /* disable ignore CR */ - | ICRNL /* disable translate CR to NL */ - | IXON); /* disable enable XON/XOFF flow control */ - - tty->termios->c_oflag /* output modes */ - &= ~OPOST; /* disable postprocess output char */ - - tty->termios->c_lflag /* line discipline modes */ - &= ~(ECHO /* disable echo input characters */ - | ECHONL /* disable echo new line */ - | ICANON /* disable erase, kill, werase, and rprnt - special characters */ - | ISIG /* disable interrupt, quit, and suspend - special characters */ - | IEXTEN); /* disable non-POSIX special characters */ - } /* CT_CYPHIDCOM: Application should handle this for device */ - - linechange = (priv->line_control != oldlines); - spin_unlock_irqrestore(&priv->lock, flags); - - /* if necessary, set lines */ - if (linechange) { - priv->cmd_ctrl = 1; - cypress_write(tty, port, NULL, 0); - } -} /* cypress_set_termios */ - - -/* returns amount of data still left in soft buffer */ -static int cypress_chars_in_buffer(struct tty_struct *tty) -{ - struct usb_serial_port *port = tty->driver_data; - struct cypress_private *priv = usb_get_serial_port_data(port); - int chars = 0; - unsigned long flags; - - dbg("%s - port %d", __func__, port->number); - - spin_lock_irqsave(&priv->lock, flags); - chars = kfifo_len(&priv->write_fifo); - spin_unlock_irqrestore(&priv->lock, flags); - - dbg("%s - returns %d", __func__, chars); - return chars; -} - - -static void cypress_throttle(struct tty_struct *tty) -{ - struct usb_serial_port *port = tty->driver_data; - struct cypress_private *priv = usb_get_serial_port_data(port); - - dbg("%s - port %d", __func__, port->number); - - spin_lock_irq(&priv->lock); - priv->rx_flags = THROTTLED; - spin_unlock_irq(&priv->lock); -} - - -static void cypress_unthrottle(struct tty_struct *tty) -{ - struct usb_serial_port *port = tty->driver_data; - struct cypress_private *priv = usb_get_serial_port_data(port); - int actually_throttled, result; - - dbg("%s - port %d", __func__, port->number); - - spin_lock_irq(&priv->lock); - actually_throttled = priv->rx_flags & ACTUALLY_THROTTLED; - priv->rx_flags = 0; - spin_unlock_irq(&priv->lock); - - if (!priv->comm_is_ok) - return; - - if (actually_throttled) { - result = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL); - if (result) { - dev_err(&port->dev, "%s - failed submitting read urb, " - "error %d\n", __func__, result); - cypress_set_dead(port); - } - } -} - - -static void cypress_read_int_callback(struct urb *urb) -{ - struct usb_serial_port *port = urb->context; - struct cypress_private *priv = usb_get_serial_port_data(port); - struct tty_struct *tty; - unsigned char *data = urb->transfer_buffer; - unsigned long flags; - char tty_flag = TTY_NORMAL; - int havedata = 0; - int bytes = 0; - int result; - int i = 0; - int status = urb->status; - - dbg("%s - port %d", __func__, port->number); - - switch (status) { - case 0: /* success */ - break; - case -ECONNRESET: - case -ENOENT: - case -ESHUTDOWN: - /* precursor to disconnect so just go away */ - return; - case -EPIPE: - /* Can't call usb_clear_halt while in_interrupt */ - /* FALLS THROUGH */ - default: - /* something ugly is going on... */ - dev_err(&urb->dev->dev, - "%s - unexpected nonzero read status received: %d\n", - __func__, status); - cypress_set_dead(port); - return; - } - - spin_lock_irqsave(&priv->lock, flags); - if (priv->rx_flags & THROTTLED) { - dbg("%s - now throttling", __func__); - priv->rx_flags |= ACTUALLY_THROTTLED; - spin_unlock_irqrestore(&priv->lock, flags); - return; - } - spin_unlock_irqrestore(&priv->lock, flags); - - tty = tty_port_tty_get(&port->port); - if (!tty) { - dbg("%s - bad tty pointer - exiting", __func__); - return; - } - - spin_lock_irqsave(&priv->lock, flags); - result = urb->actual_length; - switch (priv->pkt_fmt) { - default: - case packet_format_1: - /* This is for the CY7C64013... */ - priv->current_status = data[0] & 0xF8; - bytes = data[1] + 2; - i = 2; - if (bytes > 2) - havedata = 1; - break; - case packet_format_2: - /* This is for the CY7C63743... */ - priv->current_status = data[0] & 0xF8; - bytes = (data[0] & 0x07) + 1; - i = 1; - if (bytes > 1) - havedata = 1; - break; - } - spin_unlock_irqrestore(&priv->lock, flags); - if (result < bytes) { - dbg("%s - wrong packet size - received %d bytes but packet " - "said %d bytes", __func__, result, bytes); - goto continue_read; - } - - usb_serial_debug_data(debug, &port->dev, __func__, - urb->actual_length, data); - - spin_lock_irqsave(&priv->lock, flags); - /* check to see if status has changed */ - if (priv->current_status != priv->prev_status) { - priv->diff_status |= priv->current_status ^ - priv->prev_status; - wake_up_interruptible(&priv->delta_msr_wait); - priv->prev_status = priv->current_status; - } - spin_unlock_irqrestore(&priv->lock, flags); - - /* hangup, as defined in acm.c... this might be a bad place for it - * though */ - if (tty && !(tty->termios->c_cflag & CLOCAL) && - !(priv->current_status & UART_CD)) { - dbg("%s - calling hangup", __func__); - tty_hangup(tty); - goto continue_read; - } - - /* There is one error bit... I'm assuming it is a parity error - * indicator as the generic firmware will set this bit to 1 if a - * parity error occurs. - * I can not find reference to any other error events. */ - spin_lock_irqsave(&priv->lock, flags); - if (priv->current_status & CYP_ERROR) { - spin_unlock_irqrestore(&priv->lock, flags); - tty_flag = TTY_PARITY; - dbg("%s - Parity Error detected", __func__); - } else - spin_unlock_irqrestore(&priv->lock, flags); - - /* process read if there is data other than line status */ - if (tty && bytes > i) { - tty_insert_flip_string_fixed_flag(tty, data + i, - tty_flag, bytes - i); - tty_flip_buffer_push(tty); - } - - spin_lock_irqsave(&priv->lock, flags); - /* control and status byte(s) are also counted */ - priv->bytes_in += bytes; - spin_unlock_irqrestore(&priv->lock, flags); - -continue_read: - tty_kref_put(tty); - - /* Continue trying to always read */ - - if (priv->comm_is_ok) { - usb_fill_int_urb(port->interrupt_in_urb, port->serial->dev, - usb_rcvintpipe(port->serial->dev, - port->interrupt_in_endpointAddress), - port->interrupt_in_urb->transfer_buffer, - port->interrupt_in_urb->transfer_buffer_length, - cypress_read_int_callback, port, - priv->read_urb_interval); - result = usb_submit_urb(port->interrupt_in_urb, GFP_ATOMIC); - if (result && result != -EPERM) { - dev_err(&urb->dev->dev, "%s - failed resubmitting " - "read urb, error %d\n", __func__, - result); - cypress_set_dead(port); - } - } -} /* cypress_read_int_callback */ - - -static void cypress_write_int_callback(struct urb *urb) -{ - struct usb_serial_port *port = urb->context; - struct cypress_private *priv = usb_get_serial_port_data(port); - int result; - int status = urb->status; - - dbg("%s - port %d", __func__, port->number); - - switch (status) { - case 0: - /* success */ - break; - case -ECONNRESET: - case -ENOENT: - case -ESHUTDOWN: - /* this urb is terminated, clean up */ - dbg("%s - urb shutting down with status: %d", - __func__, status); - priv->write_urb_in_use = 0; - return; - case -EPIPE: /* no break needed; clear halt and resubmit */ - if (!priv->comm_is_ok) - break; - usb_clear_halt(port->serial->dev, 0x02); - /* error in the urb, so we have to resubmit it */ - dbg("%s - nonzero write bulk status received: %d", - __func__, status); - port->interrupt_out_urb->transfer_buffer_length = 1; - result = usb_submit_urb(port->interrupt_out_urb, GFP_ATOMIC); - if (!result) - return; - dev_err(&urb->dev->dev, - "%s - failed resubmitting write urb, error %d\n", - __func__, result); - cypress_set_dead(port); - break; - default: - dev_err(&urb->dev->dev, - "%s - unexpected nonzero write status received: %d\n", - __func__, status); - cypress_set_dead(port); - break; - } - priv->write_urb_in_use = 0; - - /* send any buffered data */ - cypress_send(port); -} - -module_usb_serial_driver(cypress_driver, serial_drivers); - -MODULE_AUTHOR(DRIVER_AUTHOR); -MODULE_DESCRIPTION(DRIVER_DESC); -MODULE_VERSION(DRIVER_VERSION); -MODULE_LICENSE("GPL"); - -module_param(debug, bool, S_IRUGO | S_IWUSR); -MODULE_PARM_DESC(debug, "Debug enabled or not"); -module_param(stats, bool, S_IRUGO | S_IWUSR); -MODULE_PARM_DESC(stats, "Enable statistics or not"); -module_param(interval, int, S_IRUGO | S_IWUSR); -MODULE_PARM_DESC(interval, "Overrides interrupt interval"); -module_param(unstable_bauds, bool, S_IRUGO | S_IWUSR); -MODULE_PARM_DESC(unstable_bauds, "Allow unstable baud rates"); diff --git a/ANDROID_3.4.5/drivers/usb/serial/cypress_m8.h b/ANDROID_3.4.5/drivers/usb/serial/cypress_m8.h deleted file mode 100644 index 67cf6082..00000000 --- a/ANDROID_3.4.5/drivers/usb/serial/cypress_m8.h +++ /dev/null @@ -1,70 +0,0 @@ -#ifndef CYPRESS_M8_H -#define CYPRESS_M8_H - -/* - * definitions and function prototypes used for the cypress USB to Serial - * controller - */ - -/* - * For sending our feature buffer - controlling serial communication states. - * Linux HID has no support for serial devices so we do this through the driver - */ -#define HID_REQ_GET_REPORT 0x01 -#define HID_REQ_SET_REPORT 0x09 - -/* List other cypress USB to Serial devices here, and add them to the id_table */ - -/* DeLorme Earthmate USB - a GPS device */ -#define VENDOR_ID_DELORME 0x1163 -#define PRODUCT_ID_EARTHMATEUSB 0x0100 -#define PRODUCT_ID_EARTHMATEUSB_LT20 0x0200 - -/* Cypress HID->COM RS232 Adapter */ -#define VENDOR_ID_CYPRESS 0x04b4 -#define PRODUCT_ID_CYPHIDCOM 0x5500 - -/* Powercom UPS, chip CY7C63723 */ -#define VENDOR_ID_POWERCOM 0x0d9f -#define PRODUCT_ID_UPS 0x0002 - -/* Nokia CA-42 USB to serial cable */ -#define VENDOR_ID_DAZZLE 0x07d0 -#define PRODUCT_ID_CA42 0x4101 -/* End of device listing */ - -/* Used for setting / requesting serial line settings */ -#define CYPRESS_SET_CONFIG 0x01 -#define CYPRESS_GET_CONFIG 0x02 - -/* Used for throttle control */ -#define THROTTLED 0x1 -#define ACTUALLY_THROTTLED 0x2 - -/* - * chiptypes - used in case firmware differs from the generic form ... offering - * different baud speeds/etc. - */ -#define CT_EARTHMATE 0x01 -#define CT_CYPHIDCOM 0x02 -#define CT_CA42V2 0x03 -#define CT_GENERIC 0x0F -/* End of chiptype definitions */ - -/* RS-232 serial data communication protocol definitions */ -/* these are sent / read at byte 0 of the input/output hid reports */ -/* You can find these values defined in the CY4601 USB to Serial design notes */ - -#define CONTROL_DTR 0x20 /* data terminal ready - flow control - host to device */ -#define UART_DSR 0x20 /* data set ready - flow control - device to host */ -#define CONTROL_RTS 0x10 /* request to send - flow control - host to device */ -#define UART_CTS 0x10 /* clear to send - flow control - device to host */ -#define UART_RI 0x10 /* ring indicator - modem - device to host */ -#define UART_CD 0x40 /* carrier detect - modem - device to host */ -#define CYP_ERROR 0x08 /* received from input report - device to host */ -/* Note - the below has nothing to do with the "feature report" reset */ -#define CONTROL_RESET 0x08 /* sent with output report - host to device */ - -/* End of RS-232 protocol definitions */ - -#endif /* CYPRESS_M8_H */ diff --git a/ANDROID_3.4.5/drivers/usb/serial/digi_acceleport.c b/ANDROID_3.4.5/drivers/usb/serial/digi_acceleport.c deleted file mode 100644 index 999f91bf..00000000 --- a/ANDROID_3.4.5/drivers/usb/serial/digi_acceleport.c +++ /dev/null @@ -1,1590 +0,0 @@ -/* -* Digi AccelePort USB-4 and USB-2 Serial Converters -* -* Copyright 2000 by Digi International -* -* 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. -* -* Shamelessly based on Brian Warner's keyspan_pda.c and Greg Kroah-Hartman's -* usb-serial driver. -* -* Peter Berger (pberger@brimson.com) -* Al Borchers (borchers@steinerpoint.com) -*/ - -#include <linux/kernel.h> -#include <linux/errno.h> -#include <linux/init.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/workqueue.h> -#include <linux/uaccess.h> -#include <linux/usb.h> -#include <linux/wait.h> -#include <linux/usb/serial.h> - -/* Defines */ - -/* - * Version Information - */ -#define DRIVER_VERSION "v1.80.1.2" -#define DRIVER_AUTHOR "Peter Berger <pberger@brimson.com>, Al Borchers <borchers@steinerpoint.com>" -#define DRIVER_DESC "Digi AccelePort USB-2/USB-4 Serial Converter driver" - -/* port output buffer length -- must be <= transfer buffer length - 2 */ -/* so we can be sure to send the full buffer in one urb */ -#define DIGI_OUT_BUF_SIZE 8 - -/* port input buffer length -- must be >= transfer buffer length - 3 */ -/* so we can be sure to hold at least one full buffer from one urb */ -#define DIGI_IN_BUF_SIZE 64 - -/* retry timeout while sleeping */ -#define DIGI_RETRY_TIMEOUT (HZ/10) - -/* timeout while waiting for tty output to drain in close */ -/* this delay is used twice in close, so the total delay could */ -/* be twice this value */ -#define DIGI_CLOSE_TIMEOUT (5*HZ) - - -/* AccelePort USB Defines */ - -/* ids */ -#define DIGI_VENDOR_ID 0x05c5 -#define DIGI_2_ID 0x0002 /* USB-2 */ -#define DIGI_4_ID 0x0004 /* USB-4 */ - -/* commands - * "INB": can be used on the in-band endpoint - * "OOB": can be used on the out-of-band endpoint - */ -#define DIGI_CMD_SET_BAUD_RATE 0 /* INB, OOB */ -#define DIGI_CMD_SET_WORD_SIZE 1 /* INB, OOB */ -#define DIGI_CMD_SET_PARITY 2 /* INB, OOB */ -#define DIGI_CMD_SET_STOP_BITS 3 /* INB, OOB */ -#define DIGI_CMD_SET_INPUT_FLOW_CONTROL 4 /* INB, OOB */ -#define DIGI_CMD_SET_OUTPUT_FLOW_CONTROL 5 /* INB, OOB */ -#define DIGI_CMD_SET_DTR_SIGNAL 6 /* INB, OOB */ -#define DIGI_CMD_SET_RTS_SIGNAL 7 /* INB, OOB */ -#define DIGI_CMD_READ_INPUT_SIGNALS 8 /* OOB */ -#define DIGI_CMD_IFLUSH_FIFO 9 /* OOB */ -#define DIGI_CMD_RECEIVE_ENABLE 10 /* INB, OOB */ -#define DIGI_CMD_BREAK_CONTROL 11 /* INB, OOB */ -#define DIGI_CMD_LOCAL_LOOPBACK 12 /* INB, OOB */ -#define DIGI_CMD_TRANSMIT_IDLE 13 /* INB, OOB */ -#define DIGI_CMD_READ_UART_REGISTER 14 /* OOB */ -#define DIGI_CMD_WRITE_UART_REGISTER 15 /* INB, OOB */ -#define DIGI_CMD_AND_UART_REGISTER 16 /* INB, OOB */ -#define DIGI_CMD_OR_UART_REGISTER 17 /* INB, OOB */ -#define DIGI_CMD_SEND_DATA 18 /* INB */ -#define DIGI_CMD_RECEIVE_DATA 19 /* INB */ -#define DIGI_CMD_RECEIVE_DISABLE 20 /* INB */ -#define DIGI_CMD_GET_PORT_TYPE 21 /* OOB */ - -/* baud rates */ -#define DIGI_BAUD_50 0 -#define DIGI_BAUD_75 1 -#define DIGI_BAUD_110 2 -#define DIGI_BAUD_150 3 -#define DIGI_BAUD_200 4 -#define DIGI_BAUD_300 5 -#define DIGI_BAUD_600 6 -#define DIGI_BAUD_1200 7 -#define DIGI_BAUD_1800 8 -#define DIGI_BAUD_2400 9 -#define DIGI_BAUD_4800 10 -#define DIGI_BAUD_7200 11 -#define DIGI_BAUD_9600 12 -#define DIGI_BAUD_14400 13 -#define DIGI_BAUD_19200 14 -#define DIGI_BAUD_28800 15 -#define DIGI_BAUD_38400 16 -#define DIGI_BAUD_57600 17 -#define DIGI_BAUD_76800 18 -#define DIGI_BAUD_115200 19 -#define DIGI_BAUD_153600 20 -#define DIGI_BAUD_230400 21 -#define DIGI_BAUD_460800 22 - -/* arguments */ -#define DIGI_WORD_SIZE_5 0 -#define DIGI_WORD_SIZE_6 1 -#define DIGI_WORD_SIZE_7 2 -#define DIGI_WORD_SIZE_8 3 - -#define DIGI_PARITY_NONE 0 -#define DIGI_PARITY_ODD 1 -#define DIGI_PARITY_EVEN 2 -#define DIGI_PARITY_MARK 3 -#define DIGI_PARITY_SPACE 4 - -#define DIGI_STOP_BITS_1 0 -#define DIGI_STOP_BITS_2 1 - -#define DIGI_INPUT_FLOW_CONTROL_XON_XOFF 1 -#define DIGI_INPUT_FLOW_CONTROL_RTS 2 -#define DIGI_INPUT_FLOW_CONTROL_DTR 4 - -#define DIGI_OUTPUT_FLOW_CONTROL_XON_XOFF 1 -#define DIGI_OUTPUT_FLOW_CONTROL_CTS 2 -#define DIGI_OUTPUT_FLOW_CONTROL_DSR 4 - -#define DIGI_DTR_INACTIVE 0 -#define DIGI_DTR_ACTIVE 1 -#define DIGI_DTR_INPUT_FLOW_CONTROL 2 - -#define DIGI_RTS_INACTIVE 0 -#define DIGI_RTS_ACTIVE 1 -#define DIGI_RTS_INPUT_FLOW_CONTROL 2 -#define DIGI_RTS_TOGGLE 3 - -#define DIGI_FLUSH_TX 1 -#define DIGI_FLUSH_RX 2 -#define DIGI_RESUME_TX 4 /* clears xoff condition */ - -#define DIGI_TRANSMIT_NOT_IDLE 0 -#define DIGI_TRANSMIT_IDLE 1 - -#define DIGI_DISABLE 0 -#define DIGI_ENABLE 1 - -#define DIGI_DEASSERT 0 -#define DIGI_ASSERT 1 - -/* in band status codes */ -#define DIGI_OVERRUN_ERROR 4 -#define DIGI_PARITY_ERROR 8 -#define DIGI_FRAMING_ERROR 16 -#define DIGI_BREAK_ERROR 32 - -/* out of band status */ -#define DIGI_NO_ERROR 0 -#define DIGI_BAD_FIRST_PARAMETER 1 -#define DIGI_BAD_SECOND_PARAMETER 2 -#define DIGI_INVALID_LINE 3 -#define DIGI_INVALID_OPCODE 4 - -/* input signals */ -#define DIGI_READ_INPUT_SIGNALS_SLOT 1 -#define DIGI_READ_INPUT_SIGNALS_ERR 2 -#define DIGI_READ_INPUT_SIGNALS_BUSY 4 -#define DIGI_READ_INPUT_SIGNALS_PE 8 -#define DIGI_READ_INPUT_SIGNALS_CTS 16 -#define DIGI_READ_INPUT_SIGNALS_DSR 32 -#define DIGI_READ_INPUT_SIGNALS_RI 64 -#define DIGI_READ_INPUT_SIGNALS_DCD 128 - - -/* Structures */ - -struct digi_serial { - spinlock_t ds_serial_lock; - struct usb_serial_port *ds_oob_port; /* out-of-band port */ - int ds_oob_port_num; /* index of out-of-band port */ - int ds_device_started; -}; - -struct digi_port { - spinlock_t dp_port_lock; - int dp_port_num; - int dp_out_buf_len; - unsigned char dp_out_buf[DIGI_OUT_BUF_SIZE]; - int dp_write_urb_in_use; - unsigned int dp_modem_signals; - wait_queue_head_t dp_modem_change_wait; - int dp_transmit_idle; - wait_queue_head_t dp_transmit_idle_wait; - int dp_throttled; - int dp_throttle_restart; - wait_queue_head_t dp_flush_wait; - wait_queue_head_t dp_close_wait; /* wait queue for close */ - struct work_struct dp_wakeup_work; - struct usb_serial_port *dp_port; -}; - - -/* Local Function Declarations */ - -static void digi_wakeup_write(struct usb_serial_port *port); -static void digi_wakeup_write_lock(struct work_struct *work); -static int digi_write_oob_command(struct usb_serial_port *port, - unsigned char *buf, int count, int interruptible); -static int digi_write_inb_command(struct usb_serial_port *port, - unsigned char *buf, int count, unsigned long timeout); -static int digi_set_modem_signals(struct usb_serial_port *port, - unsigned int modem_signals, int interruptible); -static int digi_transmit_idle(struct usb_serial_port *port, - unsigned long timeout); -static void digi_rx_throttle(struct tty_struct *tty); -static void digi_rx_unthrottle(struct tty_struct *tty); -static void digi_set_termios(struct tty_struct *tty, - struct usb_serial_port *port, struct ktermios *old_termios); -static void digi_break_ctl(struct tty_struct *tty, int break_state); -static int digi_tiocmget(struct tty_struct *tty); -static int digi_tiocmset(struct tty_struct *tty, unsigned int set, - unsigned int clear); -static int digi_write(struct tty_struct *tty, struct usb_serial_port *port, - const unsigned char *buf, int count); -static void digi_write_bulk_callback(struct urb *urb); -static int digi_write_room(struct tty_struct *tty); -static int digi_chars_in_buffer(struct tty_struct *tty); -static int digi_open(struct tty_struct *tty, struct usb_serial_port *port); -static void digi_close(struct usb_serial_port *port); -static void digi_dtr_rts(struct usb_serial_port *port, int on); -static int digi_startup_device(struct usb_serial *serial); -static int digi_startup(struct usb_serial *serial); -static void digi_disconnect(struct usb_serial *serial); -static void digi_release(struct usb_serial *serial); -static void digi_read_bulk_callback(struct urb *urb); -static int digi_read_inb_callback(struct urb *urb); -static int digi_read_oob_callback(struct urb *urb); - - -/* Statics */ - -static bool debug; - -static const struct usb_device_id id_table_combined[] = { - { USB_DEVICE(DIGI_VENDOR_ID, DIGI_2_ID) }, - { USB_DEVICE(DIGI_VENDOR_ID, DIGI_4_ID) }, - { } /* Terminating entry */ -}; - -static const struct usb_device_id id_table_2[] = { - { USB_DEVICE(DIGI_VENDOR_ID, DIGI_2_ID) }, - { } /* Terminating entry */ -}; - -static const struct usb_device_id id_table_4[] = { - { USB_DEVICE(DIGI_VENDOR_ID, DIGI_4_ID) }, - { } /* Terminating entry */ -}; - -MODULE_DEVICE_TABLE(usb, id_table_combined); - -static struct usb_driver digi_driver = { - .name = "digi_acceleport", - .probe = usb_serial_probe, - .disconnect = usb_serial_disconnect, - .id_table = id_table_combined, -}; - - -/* device info needed for the Digi serial converter */ - -static struct usb_serial_driver digi_acceleport_2_device = { - .driver = { - .owner = THIS_MODULE, - .name = "digi_2", - }, - .description = "Digi 2 port USB adapter", - .id_table = id_table_2, - .num_ports = 3, - .open = digi_open, - .close = digi_close, - .dtr_rts = digi_dtr_rts, - .write = digi_write, - .write_room = digi_write_room, - .write_bulk_callback = digi_write_bulk_callback, - .read_bulk_callback = digi_read_bulk_callback, - .chars_in_buffer = digi_chars_in_buffer, - .throttle = digi_rx_throttle, - .unthrottle = digi_rx_unthrottle, - .set_termios = digi_set_termios, - .break_ctl = digi_break_ctl, - .tiocmget = digi_tiocmget, - .tiocmset = digi_tiocmset, - .attach = digi_startup, - .disconnect = digi_disconnect, - .release = digi_release, -}; - -static struct usb_serial_driver digi_acceleport_4_device = { - .driver = { - .owner = THIS_MODULE, - .name = "digi_4", - }, - .description = "Digi 4 port USB adapter", - .id_table = id_table_4, - .num_ports = 4, - .open = digi_open, - .close = digi_close, - .write = digi_write, - .write_room = digi_write_room, - .write_bulk_callback = digi_write_bulk_callback, - .read_bulk_callback = digi_read_bulk_callback, - .chars_in_buffer = digi_chars_in_buffer, - .throttle = digi_rx_throttle, - .unthrottle = digi_rx_unthrottle, - .set_termios = digi_set_termios, - .break_ctl = digi_break_ctl, - .tiocmget = digi_tiocmget, - .tiocmset = digi_tiocmset, - .attach = digi_startup, - .disconnect = digi_disconnect, - .release = digi_release, -}; - -static struct usb_serial_driver * const serial_drivers[] = { - &digi_acceleport_2_device, &digi_acceleport_4_device, NULL -}; - -/* Functions */ - -/* - * Cond Wait Interruptible Timeout Irqrestore - * - * Do spin_unlock_irqrestore and interruptible_sleep_on_timeout - * so that wake ups are not lost if they occur between the unlock - * and the sleep. In other words, spin_unlock_irqrestore and - * interruptible_sleep_on_timeout are "atomic" with respect to - * wake ups. This is used to implement condition variables. - * - * interruptible_sleep_on_timeout is deprecated and has been replaced - * with the equivalent code. - */ - -static long cond_wait_interruptible_timeout_irqrestore( - wait_queue_head_t *q, long timeout, - spinlock_t *lock, unsigned long flags) -__releases(lock) -{ - DEFINE_WAIT(wait); - - prepare_to_wait(q, &wait, TASK_INTERRUPTIBLE); - spin_unlock_irqrestore(lock, flags); - timeout = schedule_timeout(timeout); - finish_wait(q, &wait); - - return timeout; -} - - -/* - * Digi Wakeup Write - * - * Wake up port, line discipline, and tty processes sleeping - * on writes. - */ - -static void digi_wakeup_write_lock(struct work_struct *work) -{ - struct digi_port *priv = - container_of(work, struct digi_port, dp_wakeup_work); - struct usb_serial_port *port = priv->dp_port; - unsigned long flags; - - spin_lock_irqsave(&priv->dp_port_lock, flags); - digi_wakeup_write(port); - spin_unlock_irqrestore(&priv->dp_port_lock, flags); -} - -static void digi_wakeup_write(struct usb_serial_port *port) -{ - struct tty_struct *tty = tty_port_tty_get(&port->port); - if (tty) { - tty_wakeup(tty); - tty_kref_put(tty); - } -} - - -/* - * Digi Write OOB Command - * - * Write commands on the out of band port. Commands are 4 - * bytes each, multiple commands can be sent at once, and - * no command will be split across USB packets. Returns 0 - * if successful, -EINTR if interrupted while sleeping and - * the interruptible flag is true, or a negative error - * returned by usb_submit_urb. - */ - -static int digi_write_oob_command(struct usb_serial_port *port, - unsigned char *buf, int count, int interruptible) -{ - - int ret = 0; - int len; - struct usb_serial_port *oob_port = (struct usb_serial_port *)((struct digi_serial *)(usb_get_serial_data(port->serial)))->ds_oob_port; - struct digi_port *oob_priv = usb_get_serial_port_data(oob_port); - unsigned long flags = 0; - - dbg("digi_write_oob_command: TOP: port=%d, count=%d", oob_priv->dp_port_num, count); - - spin_lock_irqsave(&oob_priv->dp_port_lock, flags); - while (count > 0) { - while (oob_priv->dp_write_urb_in_use) { - cond_wait_interruptible_timeout_irqrestore( - &oob_port->write_wait, DIGI_RETRY_TIMEOUT, - &oob_priv->dp_port_lock, flags); - if (interruptible && signal_pending(current)) - return -EINTR; - spin_lock_irqsave(&oob_priv->dp_port_lock, flags); - } - - /* len must be a multiple of 4, so commands are not split */ - len = min(count, oob_port->bulk_out_size); - if (len > 4) - len &= ~3; - memcpy(oob_port->write_urb->transfer_buffer, buf, len); - oob_port->write_urb->transfer_buffer_length = len; - ret = usb_submit_urb(oob_port->write_urb, GFP_ATOMIC); - if (ret == 0) { - oob_priv->dp_write_urb_in_use = 1; - count -= len; - buf += len; - } - } - spin_unlock_irqrestore(&oob_priv->dp_port_lock, flags); - if (ret) - dev_err(&port->dev, "%s: usb_submit_urb failed, ret=%d\n", - __func__, ret); - return ret; - -} - - -/* - * Digi Write In Band Command - * - * Write commands on the given port. Commands are 4 - * bytes each, multiple commands can be sent at once, and - * no command will be split across USB packets. If timeout - * is non-zero, write in band command will return after - * waiting unsuccessfully for the URB status to clear for - * timeout ticks. Returns 0 if successful, or a negative - * error returned by digi_write. - */ - -static int digi_write_inb_command(struct usb_serial_port *port, - unsigned char *buf, int count, unsigned long timeout) -{ - int ret = 0; - int len; - struct digi_port *priv = usb_get_serial_port_data(port); - unsigned char *data = port->write_urb->transfer_buffer; - unsigned long flags = 0; - - dbg("digi_write_inb_command: TOP: port=%d, count=%d", - priv->dp_port_num, count); - - if (timeout) - timeout += jiffies; - else - timeout = ULONG_MAX; - - spin_lock_irqsave(&priv->dp_port_lock, flags); - while (count > 0 && ret == 0) { - while (priv->dp_write_urb_in_use && - time_before(jiffies, timeout)) { - cond_wait_interruptible_timeout_irqrestore( - &port->write_wait, DIGI_RETRY_TIMEOUT, - &priv->dp_port_lock, flags); - if (signal_pending(current)) - return -EINTR; - spin_lock_irqsave(&priv->dp_port_lock, flags); - } - - /* len must be a multiple of 4 and small enough to */ - /* guarantee the write will send buffered data first, */ - /* so commands are in order with data and not split */ - len = min(count, port->bulk_out_size-2-priv->dp_out_buf_len); - if (len > 4) - len &= ~3; - - /* write any buffered data first */ - if (priv->dp_out_buf_len > 0) { - data[0] = DIGI_CMD_SEND_DATA; - data[1] = priv->dp_out_buf_len; - memcpy(data + 2, priv->dp_out_buf, - priv->dp_out_buf_len); - memcpy(data + 2 + priv->dp_out_buf_len, buf, len); - port->write_urb->transfer_buffer_length - = priv->dp_out_buf_len + 2 + len; - } else { - memcpy(data, buf, len); - port->write_urb->transfer_buffer_length = len; - } - - ret = usb_submit_urb(port->write_urb, GFP_ATOMIC); - if (ret == 0) { - priv->dp_write_urb_in_use = 1; - priv->dp_out_buf_len = 0; - count -= len; - buf += len; - } - - } - spin_unlock_irqrestore(&priv->dp_port_lock, flags); - - if (ret) - dev_err(&port->dev, - "%s: usb_submit_urb failed, ret=%d, port=%d\n", - __func__, ret, priv->dp_port_num); - return ret; -} - - -/* - * Digi Set Modem Signals - * - * Sets or clears DTR and RTS on the port, according to the - * modem_signals argument. Use TIOCM_DTR and TIOCM_RTS flags - * for the modem_signals argument. Returns 0 if successful, - * -EINTR if interrupted while sleeping, or a non-zero error - * returned by usb_submit_urb. - */ - -static int digi_set_modem_signals(struct usb_serial_port *port, - unsigned int modem_signals, int interruptible) -{ - - int ret; - struct digi_port *port_priv = usb_get_serial_port_data(port); - struct usb_serial_port *oob_port = (struct usb_serial_port *) ((struct digi_serial *)(usb_get_serial_data(port->serial)))->ds_oob_port; - struct digi_port *oob_priv = usb_get_serial_port_data(oob_port); - unsigned char *data = oob_port->write_urb->transfer_buffer; - unsigned long flags = 0; - - - dbg("digi_set_modem_signals: TOP: port=%d, modem_signals=0x%x", - port_priv->dp_port_num, modem_signals); - - spin_lock_irqsave(&oob_priv->dp_port_lock, flags); - spin_lock(&port_priv->dp_port_lock); - - while (oob_priv->dp_write_urb_in_use) { - spin_unlock(&port_priv->dp_port_lock); - cond_wait_interruptible_timeout_irqrestore( - &oob_port->write_wait, DIGI_RETRY_TIMEOUT, - &oob_priv->dp_port_lock, flags); - if (interruptible && signal_pending(current)) - return -EINTR; - spin_lock_irqsave(&oob_priv->dp_port_lock, flags); - spin_lock(&port_priv->dp_port_lock); - } - data[0] = DIGI_CMD_SET_DTR_SIGNAL; - data[1] = port_priv->dp_port_num; - data[2] = (modem_signals & TIOCM_DTR) ? - DIGI_DTR_ACTIVE : DIGI_DTR_INACTIVE; - data[3] = 0; - data[4] = DIGI_CMD_SET_RTS_SIGNAL; - data[5] = port_priv->dp_port_num; - data[6] = (modem_signals & TIOCM_RTS) ? - DIGI_RTS_ACTIVE : DIGI_RTS_INACTIVE; - data[7] = 0; - - oob_port->write_urb->transfer_buffer_length = 8; - - ret = usb_submit_urb(oob_port->write_urb, GFP_ATOMIC); - if (ret == 0) { - oob_priv->dp_write_urb_in_use = 1; - port_priv->dp_modem_signals = - (port_priv->dp_modem_signals&~(TIOCM_DTR|TIOCM_RTS)) - | (modem_signals&(TIOCM_DTR|TIOCM_RTS)); - } - spin_unlock(&port_priv->dp_port_lock); - spin_unlock_irqrestore(&oob_priv->dp_port_lock, flags); - if (ret) - dev_err(&port->dev, "%s: usb_submit_urb failed, ret=%d\n", - __func__, ret); - return ret; -} - -/* - * Digi Transmit Idle - * - * Digi transmit idle waits, up to timeout ticks, for the transmitter - * to go idle. It returns 0 if successful or a negative error. - * - * There are race conditions here if more than one process is calling - * digi_transmit_idle on the same port at the same time. However, this - * is only called from close, and only one process can be in close on a - * port at a time, so its ok. - */ - -static int digi_transmit_idle(struct usb_serial_port *port, - unsigned long timeout) -{ - int ret; - unsigned char buf[2]; - struct digi_port *priv = usb_get_serial_port_data(port); - unsigned long flags = 0; - - spin_lock_irqsave(&priv->dp_port_lock, flags); - priv->dp_transmit_idle = 0; - spin_unlock_irqrestore(&priv->dp_port_lock, flags); - - buf[0] = DIGI_CMD_TRANSMIT_IDLE; - buf[1] = 0; - - timeout += jiffies; - - ret = digi_write_inb_command(port, buf, 2, timeout - jiffies); - if (ret != 0) - return ret; - - spin_lock_irqsave(&priv->dp_port_lock, flags); - - while (time_before(jiffies, timeout) && !priv->dp_transmit_idle) { - cond_wait_interruptible_timeout_irqrestore( - &priv->dp_transmit_idle_wait, DIGI_RETRY_TIMEOUT, - &priv->dp_port_lock, flags); - if (signal_pending(current)) - return -EINTR; - spin_lock_irqsave(&priv->dp_port_lock, flags); - } - priv->dp_transmit_idle = 0; - spin_unlock_irqrestore(&priv->dp_port_lock, flags); - return 0; - -} - - -static void digi_rx_throttle(struct tty_struct *tty) -{ - unsigned long flags; - struct usb_serial_port *port = tty->driver_data; - struct digi_port *priv = usb_get_serial_port_data(port); - - - dbg("digi_rx_throttle: TOP: port=%d", priv->dp_port_num); - - /* stop receiving characters by not resubmitting the read urb */ - spin_lock_irqsave(&priv->dp_port_lock, flags); - priv->dp_throttled = 1; - priv->dp_throttle_restart = 0; - spin_unlock_irqrestore(&priv->dp_port_lock, flags); -} - - -static void digi_rx_unthrottle(struct tty_struct *tty) -{ - int ret = 0; - unsigned long flags; - struct usb_serial_port *port = tty->driver_data; - struct digi_port *priv = usb_get_serial_port_data(port); - - dbg("digi_rx_unthrottle: TOP: port=%d", priv->dp_port_num); - - spin_lock_irqsave(&priv->dp_port_lock, flags); - - /* restart read chain */ - if (priv->dp_throttle_restart) - ret = usb_submit_urb(port->read_urb, GFP_ATOMIC); - - /* turn throttle off */ - priv->dp_throttled = 0; - priv->dp_throttle_restart = 0; - - spin_unlock_irqrestore(&priv->dp_port_lock, flags); - - if (ret) - dev_err(&port->dev, - "%s: usb_submit_urb failed, ret=%d, port=%d\n", - __func__, ret, priv->dp_port_num); -} - - -static void digi_set_termios(struct tty_struct *tty, - struct usb_serial_port *port, struct ktermios *old_termios) -{ - struct digi_port *priv = usb_get_serial_port_data(port); - unsigned int iflag = tty->termios->c_iflag; - unsigned int cflag = tty->termios->c_cflag; - unsigned int old_iflag = old_termios->c_iflag; - unsigned int old_cflag = old_termios->c_cflag; - unsigned char buf[32]; - unsigned int modem_signals; - int arg, ret; - int i = 0; - speed_t baud; - - dbg("digi_set_termios: TOP: port=%d, iflag=0x%x, old_iflag=0x%x, cflag=0x%x, old_cflag=0x%x", priv->dp_port_num, iflag, old_iflag, cflag, old_cflag); - - /* set baud rate */ - baud = tty_get_baud_rate(tty); - if (baud != tty_termios_baud_rate(old_termios)) { - arg = -1; - - /* reassert DTR and (maybe) RTS on transition from B0 */ - if ((old_cflag&CBAUD) == B0) { - /* don't set RTS if using hardware flow control */ - /* and throttling input */ - modem_signals = TIOCM_DTR; - if (!(tty->termios->c_cflag & CRTSCTS) || - !test_bit(TTY_THROTTLED, &tty->flags)) - modem_signals |= TIOCM_RTS; - digi_set_modem_signals(port, modem_signals, 1); - } - switch (baud) { - /* drop DTR and RTS on transition to B0 */ - case 0: digi_set_modem_signals(port, 0, 1); break; - case 50: arg = DIGI_BAUD_50; break; - case 75: arg = DIGI_BAUD_75; break; - case 110: arg = DIGI_BAUD_110; break; - case 150: arg = DIGI_BAUD_150; break; - case 200: arg = DIGI_BAUD_200; break; - case 300: arg = DIGI_BAUD_300; break; - case 600: arg = DIGI_BAUD_600; break; - case 1200: arg = DIGI_BAUD_1200; break; - case 1800: arg = DIGI_BAUD_1800; break; - case 2400: arg = DIGI_BAUD_2400; break; - case 4800: arg = DIGI_BAUD_4800; break; - case 9600: arg = DIGI_BAUD_9600; break; - case 19200: arg = DIGI_BAUD_19200; break; - case 38400: arg = DIGI_BAUD_38400; break; - case 57600: arg = DIGI_BAUD_57600; break; - case 115200: arg = DIGI_BAUD_115200; break; - case 230400: arg = DIGI_BAUD_230400; break; - case 460800: arg = DIGI_BAUD_460800; break; - default: - arg = DIGI_BAUD_9600; - baud = 9600; - break; - } - if (arg != -1) { - buf[i++] = DIGI_CMD_SET_BAUD_RATE; - buf[i++] = priv->dp_port_num; - buf[i++] = arg; - buf[i++] = 0; - } - } - /* set parity */ - tty->termios->c_cflag &= ~CMSPAR; - - if ((cflag&(PARENB|PARODD)) != (old_cflag&(PARENB|PARODD))) { - if (cflag&PARENB) { - if (cflag&PARODD) - arg = DIGI_PARITY_ODD; - else - arg = DIGI_PARITY_EVEN; - } else { - arg = DIGI_PARITY_NONE; - } - buf[i++] = DIGI_CMD_SET_PARITY; - buf[i++] = priv->dp_port_num; - buf[i++] = arg; - buf[i++] = 0; - } - /* set word size */ - if ((cflag&CSIZE) != (old_cflag&CSIZE)) { - arg = -1; - switch (cflag&CSIZE) { - case CS5: arg = DIGI_WORD_SIZE_5; break; - case CS6: arg = DIGI_WORD_SIZE_6; break; - case CS7: arg = DIGI_WORD_SIZE_7; break; - case CS8: arg = DIGI_WORD_SIZE_8; break; - default: - dbg("digi_set_termios: can't handle word size %d", - (cflag&CSIZE)); - break; - } - - if (arg != -1) { - buf[i++] = DIGI_CMD_SET_WORD_SIZE; - buf[i++] = priv->dp_port_num; - buf[i++] = arg; - buf[i++] = 0; - } - - } - - /* set stop bits */ - if ((cflag&CSTOPB) != (old_cflag&CSTOPB)) { - - if ((cflag&CSTOPB)) - arg = DIGI_STOP_BITS_2; - else - arg = DIGI_STOP_BITS_1; - - buf[i++] = DIGI_CMD_SET_STOP_BITS; - buf[i++] = priv->dp_port_num; - buf[i++] = arg; - buf[i++] = 0; - - } - - /* set input flow control */ - if ((iflag&IXOFF) != (old_iflag&IXOFF) - || (cflag&CRTSCTS) != (old_cflag&CRTSCTS)) { - arg = 0; - if (iflag&IXOFF) - arg |= DIGI_INPUT_FLOW_CONTROL_XON_XOFF; - else - arg &= ~DIGI_INPUT_FLOW_CONTROL_XON_XOFF; - - if (cflag&CRTSCTS) { - arg |= DIGI_INPUT_FLOW_CONTROL_RTS; - - /* On USB-4 it is necessary to assert RTS prior */ - /* to selecting RTS input flow control. */ - buf[i++] = DIGI_CMD_SET_RTS_SIGNAL; - buf[i++] = priv->dp_port_num; - buf[i++] = DIGI_RTS_ACTIVE; - buf[i++] = 0; - - } else { - arg &= ~DIGI_INPUT_FLOW_CONTROL_RTS; - } - buf[i++] = DIGI_CMD_SET_INPUT_FLOW_CONTROL; - buf[i++] = priv->dp_port_num; - buf[i++] = arg; - buf[i++] = 0; - } - - /* set output flow control */ - if ((iflag & IXON) != (old_iflag & IXON) - || (cflag & CRTSCTS) != (old_cflag & CRTSCTS)) { - arg = 0; - if (iflag & IXON) - arg |= DIGI_OUTPUT_FLOW_CONTROL_XON_XOFF; - else - arg &= ~DIGI_OUTPUT_FLOW_CONTROL_XON_XOFF; - - if (cflag & CRTSCTS) { - arg |= DIGI_OUTPUT_FLOW_CONTROL_CTS; - } else { - arg &= ~DIGI_OUTPUT_FLOW_CONTROL_CTS; - tty->hw_stopped = 0; - } - - buf[i++] = DIGI_CMD_SET_OUTPUT_FLOW_CONTROL; - buf[i++] = priv->dp_port_num; - buf[i++] = arg; - buf[i++] = 0; - } - - /* set receive enable/disable */ - if ((cflag & CREAD) != (old_cflag & CREAD)) { - if (cflag & CREAD) - arg = DIGI_ENABLE; - else - arg = DIGI_DISABLE; - - buf[i++] = DIGI_CMD_RECEIVE_ENABLE; - buf[i++] = priv->dp_port_num; - buf[i++] = arg; - buf[i++] = 0; - } - ret = digi_write_oob_command(port, buf, i, 1); - if (ret != 0) - dbg("digi_set_termios: write oob failed, ret=%d", ret); - tty_encode_baud_rate(tty, baud, baud); -} - - -static void digi_break_ctl(struct tty_struct *tty, int break_state) -{ - struct usb_serial_port *port = tty->driver_data; - unsigned char buf[4]; - - buf[0] = DIGI_CMD_BREAK_CONTROL; - buf[1] = 2; /* length */ - buf[2] = break_state ? 1 : 0; - buf[3] = 0; /* pad */ - digi_write_inb_command(port, buf, 4, 0); -} - - -static int digi_tiocmget(struct tty_struct *tty) -{ - struct usb_serial_port *port = tty->driver_data; - struct digi_port *priv = usb_get_serial_port_data(port); - unsigned int val; - unsigned long flags; - - dbg("%s: TOP: port=%d", __func__, priv->dp_port_num); - - spin_lock_irqsave(&priv->dp_port_lock, flags); - val = priv->dp_modem_signals; - spin_unlock_irqrestore(&priv->dp_port_lock, flags); - return val; -} - - -static int digi_tiocmset(struct tty_struct *tty, - unsigned int set, unsigned int clear) -{ - struct usb_serial_port *port = tty->driver_data; - struct digi_port *priv = usb_get_serial_port_data(port); - unsigned int val; - unsigned long flags; - - dbg("%s: TOP: port=%d", __func__, priv->dp_port_num); - - spin_lock_irqsave(&priv->dp_port_lock, flags); - val = (priv->dp_modem_signals & ~clear) | set; - spin_unlock_irqrestore(&priv->dp_port_lock, flags); - return digi_set_modem_signals(port, val, 1); -} - - -static int digi_write(struct tty_struct *tty, struct usb_serial_port *port, - const unsigned char *buf, int count) -{ - - int ret, data_len, new_len; - struct digi_port *priv = usb_get_serial_port_data(port); - unsigned char *data = port->write_urb->transfer_buffer; - unsigned long flags = 0; - - dbg("digi_write: TOP: port=%d, count=%d, in_interrupt=%ld", - priv->dp_port_num, count, in_interrupt()); - - /* copy user data (which can sleep) before getting spin lock */ - count = min(count, port->bulk_out_size-2); - count = min(64, count); - - /* be sure only one write proceeds at a time */ - /* there are races on the port private buffer */ - spin_lock_irqsave(&priv->dp_port_lock, flags); - - /* wait for urb status clear to submit another urb */ - if (priv->dp_write_urb_in_use) { - /* buffer data if count is 1 (probably put_char) if possible */ - if (count == 1 && priv->dp_out_buf_len < DIGI_OUT_BUF_SIZE) { - priv->dp_out_buf[priv->dp_out_buf_len++] = *buf; - new_len = 1; - } else { - new_len = 0; - } - spin_unlock_irqrestore(&priv->dp_port_lock, flags); - return new_len; - } - - /* allow space for any buffered data and for new data, up to */ - /* transfer buffer size - 2 (for command and length bytes) */ - new_len = min(count, port->bulk_out_size-2-priv->dp_out_buf_len); - data_len = new_len + priv->dp_out_buf_len; - - if (data_len == 0) { - spin_unlock_irqrestore(&priv->dp_port_lock, flags); - return 0; - } - - port->write_urb->transfer_buffer_length = data_len+2; - - *data++ = DIGI_CMD_SEND_DATA; - *data++ = data_len; - - /* copy in buffered data first */ - memcpy(data, priv->dp_out_buf, priv->dp_out_buf_len); - data += priv->dp_out_buf_len; - - /* copy in new data */ - memcpy(data, buf, new_len); - - ret = usb_submit_urb(port->write_urb, GFP_ATOMIC); - if (ret == 0) { - priv->dp_write_urb_in_use = 1; - ret = new_len; - priv->dp_out_buf_len = 0; - } - - /* return length of new data written, or error */ - spin_unlock_irqrestore(&priv->dp_port_lock, flags); - if (ret < 0) - dev_err_console(port, - "%s: usb_submit_urb failed, ret=%d, port=%d\n", - __func__, ret, priv->dp_port_num); - dbg("digi_write: returning %d", ret); - return ret; - -} - -static void digi_write_bulk_callback(struct urb *urb) -{ - - struct usb_serial_port *port = urb->context; - struct usb_serial *serial; - struct digi_port *priv; - struct digi_serial *serial_priv; - int ret = 0; - int status = urb->status; - - dbg("digi_write_bulk_callback: TOP, status=%d", status); - - /* port and serial sanity check */ - if (port == NULL || (priv = usb_get_serial_port_data(port)) == NULL) { - pr_err("%s: port or port->private is NULL, status=%d\n", - __func__, status); - return; - } - serial = port->serial; - if (serial == NULL || (serial_priv = usb_get_serial_data(serial)) == NULL) { - dev_err(&port->dev, - "%s: serial or serial->private is NULL, status=%d\n", - __func__, status); - return; - } - - /* handle oob callback */ - if (priv->dp_port_num == serial_priv->ds_oob_port_num) { - dbg("digi_write_bulk_callback: oob callback"); - spin_lock(&priv->dp_port_lock); - priv->dp_write_urb_in_use = 0; - wake_up_interruptible(&port->write_wait); - spin_unlock(&priv->dp_port_lock); - return; - } - - /* try to send any buffered data on this port */ - spin_lock(&priv->dp_port_lock); - priv->dp_write_urb_in_use = 0; - if (priv->dp_out_buf_len > 0) { - *((unsigned char *)(port->write_urb->transfer_buffer)) - = (unsigned char)DIGI_CMD_SEND_DATA; - *((unsigned char *)(port->write_urb->transfer_buffer) + 1) - = (unsigned char)priv->dp_out_buf_len; - port->write_urb->transfer_buffer_length = - priv->dp_out_buf_len + 2; - memcpy(port->write_urb->transfer_buffer + 2, priv->dp_out_buf, - priv->dp_out_buf_len); - ret = usb_submit_urb(port->write_urb, GFP_ATOMIC); - if (ret == 0) { - priv->dp_write_urb_in_use = 1; - priv->dp_out_buf_len = 0; - } - } - /* wake up processes sleeping on writes immediately */ - digi_wakeup_write(port); - /* also queue up a wakeup at scheduler time, in case we */ - /* lost the race in write_chan(). */ - schedule_work(&priv->dp_wakeup_work); - - spin_unlock(&priv->dp_port_lock); - if (ret && ret != -EPERM) - dev_err_console(port, - "%s: usb_submit_urb failed, ret=%d, port=%d\n", - __func__, ret, priv->dp_port_num); -} - -static int digi_write_room(struct tty_struct *tty) -{ - struct usb_serial_port *port = tty->driver_data; - struct digi_port *priv = usb_get_serial_port_data(port); - int room; - unsigned long flags = 0; - - spin_lock_irqsave(&priv->dp_port_lock, flags); - - if (priv->dp_write_urb_in_use) - room = 0; - else - room = port->bulk_out_size - 2 - priv->dp_out_buf_len; - - spin_unlock_irqrestore(&priv->dp_port_lock, flags); - dbg("digi_write_room: port=%d, room=%d", priv->dp_port_num, room); - return room; - -} - -static int digi_chars_in_buffer(struct tty_struct *tty) -{ - struct usb_serial_port *port = tty->driver_data; - struct digi_port *priv = usb_get_serial_port_data(port); - - if (priv->dp_write_urb_in_use) { - dbg("digi_chars_in_buffer: port=%d, chars=%d", - priv->dp_port_num, port->bulk_out_size - 2); - /* return(port->bulk_out_size - 2); */ - return 256; - } else { - dbg("digi_chars_in_buffer: port=%d, chars=%d", - priv->dp_port_num, priv->dp_out_buf_len); - return priv->dp_out_buf_len; - } - -} - -static void digi_dtr_rts(struct usb_serial_port *port, int on) -{ - /* Adjust DTR and RTS */ - digi_set_modem_signals(port, on * (TIOCM_DTR|TIOCM_RTS), 1); -} - -static int digi_open(struct tty_struct *tty, struct usb_serial_port *port) -{ - int ret; - unsigned char buf[32]; - struct digi_port *priv = usb_get_serial_port_data(port); - struct ktermios not_termios; - - dbg("digi_open: TOP: port=%d", priv->dp_port_num); - - /* be sure the device is started up */ - if (digi_startup_device(port->serial) != 0) - return -ENXIO; - - /* read modem signals automatically whenever they change */ - buf[0] = DIGI_CMD_READ_INPUT_SIGNALS; - buf[1] = priv->dp_port_num; - buf[2] = DIGI_ENABLE; - buf[3] = 0; - - /* flush fifos */ - buf[4] = DIGI_CMD_IFLUSH_FIFO; - buf[5] = priv->dp_port_num; - buf[6] = DIGI_FLUSH_TX | DIGI_FLUSH_RX; - buf[7] = 0; - - ret = digi_write_oob_command(port, buf, 8, 1); - if (ret != 0) - dbg("digi_open: write oob failed, ret=%d", ret); - - /* set termios settings */ - if (tty) { - not_termios.c_cflag = ~tty->termios->c_cflag; - not_termios.c_iflag = ~tty->termios->c_iflag; - digi_set_termios(tty, port, ¬_termios); - } - return 0; -} - - -static void digi_close(struct usb_serial_port *port) -{ - DEFINE_WAIT(wait); - int ret; - unsigned char buf[32]; - struct digi_port *priv = usb_get_serial_port_data(port); - - dbg("digi_close: TOP: port=%d", priv->dp_port_num); - - mutex_lock(&port->serial->disc_mutex); - /* if disconnected, just clear flags */ - if (port->serial->disconnected) - goto exit; - - if (port->serial->dev) { - /* FIXME: Transmit idle belongs in the wait_unti_sent path */ - digi_transmit_idle(port, DIGI_CLOSE_TIMEOUT); - - /* disable input flow control */ - buf[0] = DIGI_CMD_SET_INPUT_FLOW_CONTROL; - buf[1] = priv->dp_port_num; - buf[2] = DIGI_DISABLE; - buf[3] = 0; - - /* disable output flow control */ - buf[4] = DIGI_CMD_SET_OUTPUT_FLOW_CONTROL; - buf[5] = priv->dp_port_num; - buf[6] = DIGI_DISABLE; - buf[7] = 0; - - /* disable reading modem signals automatically */ - buf[8] = DIGI_CMD_READ_INPUT_SIGNALS; - buf[9] = priv->dp_port_num; - buf[10] = DIGI_DISABLE; - buf[11] = 0; - - /* disable receive */ - buf[12] = DIGI_CMD_RECEIVE_ENABLE; - buf[13] = priv->dp_port_num; - buf[14] = DIGI_DISABLE; - buf[15] = 0; - - /* flush fifos */ - buf[16] = DIGI_CMD_IFLUSH_FIFO; - buf[17] = priv->dp_port_num; - buf[18] = DIGI_FLUSH_TX | DIGI_FLUSH_RX; - buf[19] = 0; - - ret = digi_write_oob_command(port, buf, 20, 0); - if (ret != 0) - dbg("digi_close: write oob failed, ret=%d", ret); - - /* wait for final commands on oob port to complete */ - prepare_to_wait(&priv->dp_flush_wait, &wait, - TASK_INTERRUPTIBLE); - schedule_timeout(DIGI_CLOSE_TIMEOUT); - finish_wait(&priv->dp_flush_wait, &wait); - - /* shutdown any outstanding bulk writes */ - usb_kill_urb(port->write_urb); - } -exit: - spin_lock_irq(&priv->dp_port_lock); - priv->dp_write_urb_in_use = 0; - wake_up_interruptible(&priv->dp_close_wait); - spin_unlock_irq(&priv->dp_port_lock); - mutex_unlock(&port->serial->disc_mutex); - dbg("digi_close: done"); -} - - -/* - * Digi Startup Device - * - * Starts reads on all ports. Must be called AFTER startup, with - * urbs initialized. Returns 0 if successful, non-zero error otherwise. - */ - -static int digi_startup_device(struct usb_serial *serial) -{ - int i, ret = 0; - struct digi_serial *serial_priv = usb_get_serial_data(serial); - struct usb_serial_port *port; - - /* be sure this happens exactly once */ - spin_lock(&serial_priv->ds_serial_lock); - if (serial_priv->ds_device_started) { - spin_unlock(&serial_priv->ds_serial_lock); - return 0; - } - serial_priv->ds_device_started = 1; - spin_unlock(&serial_priv->ds_serial_lock); - - /* start reading from each bulk in endpoint for the device */ - /* set USB_DISABLE_SPD flag for write bulk urbs */ - for (i = 0; i < serial->type->num_ports + 1; i++) { - port = serial->port[i]; - ret = usb_submit_urb(port->read_urb, GFP_KERNEL); - if (ret != 0) { - dev_err(&port->dev, - "%s: usb_submit_urb failed, ret=%d, port=%d\n", - __func__, ret, i); - break; - } - } - return ret; -} - - -static int digi_startup(struct usb_serial *serial) -{ - - int i; - struct digi_port *priv; - struct digi_serial *serial_priv; - - dbg("digi_startup: TOP"); - - /* allocate the private data structures for all ports */ - /* number of regular ports + 1 for the out-of-band port */ - for (i = 0; i < serial->type->num_ports + 1; i++) { - /* allocate port private structure */ - priv = kmalloc(sizeof(struct digi_port), GFP_KERNEL); - if (priv == NULL) { - while (--i >= 0) - kfree(usb_get_serial_port_data(serial->port[i])); - return 1; /* error */ - } - - /* initialize port private structure */ - spin_lock_init(&priv->dp_port_lock); - priv->dp_port_num = i; - priv->dp_out_buf_len = 0; - priv->dp_write_urb_in_use = 0; - priv->dp_modem_signals = 0; - init_waitqueue_head(&priv->dp_modem_change_wait); - priv->dp_transmit_idle = 0; - init_waitqueue_head(&priv->dp_transmit_idle_wait); - priv->dp_throttled = 0; - priv->dp_throttle_restart = 0; - init_waitqueue_head(&priv->dp_flush_wait); - init_waitqueue_head(&priv->dp_close_wait); - INIT_WORK(&priv->dp_wakeup_work, digi_wakeup_write_lock); - priv->dp_port = serial->port[i]; - /* initialize write wait queue for this port */ - init_waitqueue_head(&serial->port[i]->write_wait); - - usb_set_serial_port_data(serial->port[i], priv); - } - - /* allocate serial private structure */ - serial_priv = kmalloc(sizeof(struct digi_serial), GFP_KERNEL); - if (serial_priv == NULL) { - for (i = 0; i < serial->type->num_ports + 1; i++) - kfree(usb_get_serial_port_data(serial->port[i])); - return 1; /* error */ - } - - /* initialize serial private structure */ - spin_lock_init(&serial_priv->ds_serial_lock); - serial_priv->ds_oob_port_num = serial->type->num_ports; - serial_priv->ds_oob_port = serial->port[serial_priv->ds_oob_port_num]; - serial_priv->ds_device_started = 0; - usb_set_serial_data(serial, serial_priv); - - return 0; -} - - -static void digi_disconnect(struct usb_serial *serial) -{ - int i; - dbg("digi_disconnect: TOP, in_interrupt()=%ld", in_interrupt()); - - /* stop reads and writes on all ports */ - for (i = 0; i < serial->type->num_ports + 1; i++) { - usb_kill_urb(serial->port[i]->read_urb); - usb_kill_urb(serial->port[i]->write_urb); - } -} - - -static void digi_release(struct usb_serial *serial) -{ - int i; - dbg("digi_release: TOP, in_interrupt()=%ld", in_interrupt()); - - /* free the private data structures for all ports */ - /* number of regular ports + 1 for the out-of-band port */ - for (i = 0; i < serial->type->num_ports + 1; i++) - kfree(usb_get_serial_port_data(serial->port[i])); - kfree(usb_get_serial_data(serial)); -} - - -static void digi_read_bulk_callback(struct urb *urb) -{ - struct usb_serial_port *port = urb->context; - struct digi_port *priv; - struct digi_serial *serial_priv; - int ret; - int status = urb->status; - - dbg("digi_read_bulk_callback: TOP"); - - /* port sanity check, do not resubmit if port is not valid */ - if (port == NULL) - return; - priv = usb_get_serial_port_data(port); - if (priv == NULL) { - dev_err(&port->dev, "%s: port->private is NULL, status=%d\n", - __func__, status); - return; - } - if (port->serial == NULL || - (serial_priv = usb_get_serial_data(port->serial)) == NULL) { - dev_err(&port->dev, "%s: serial is bad or serial->private " - "is NULL, status=%d\n", __func__, status); - return; - } - - /* do not resubmit urb if it has any status error */ - if (status) { - dev_err(&port->dev, - "%s: nonzero read bulk status: status=%d, port=%d\n", - __func__, status, priv->dp_port_num); - return; - } - - /* handle oob or inb callback, do not resubmit if error */ - if (priv->dp_port_num == serial_priv->ds_oob_port_num) { - if (digi_read_oob_callback(urb) != 0) - return; - } else { - if (digi_read_inb_callback(urb) != 0) - return; - } - - /* continue read */ - ret = usb_submit_urb(urb, GFP_ATOMIC); - if (ret != 0 && ret != -EPERM) { - dev_err(&port->dev, - "%s: failed resubmitting urb, ret=%d, port=%d\n", - __func__, ret, priv->dp_port_num); - } - -} - -/* - * Digi Read INB Callback - * - * Digi Read INB Callback handles reads on the in band ports, sending - * the data on to the tty subsystem. When called we know port and - * port->private are not NULL and port->serial has been validated. - * It returns 0 if successful, 1 if successful but the port is - * throttled, and -1 if the sanity checks failed. - */ - -static int digi_read_inb_callback(struct urb *urb) -{ - - struct usb_serial_port *port = urb->context; - struct tty_struct *tty; - struct digi_port *priv = usb_get_serial_port_data(port); - int opcode = ((unsigned char *)urb->transfer_buffer)[0]; - int len = ((unsigned char *)urb->transfer_buffer)[1]; - int port_status = ((unsigned char *)urb->transfer_buffer)[2]; - unsigned char *data = ((unsigned char *)urb->transfer_buffer) + 3; - int flag, throttled; - int status = urb->status; - - /* do not process callbacks on closed ports */ - /* but do continue the read chain */ - if (urb->status == -ENOENT) - return 0; - - /* short/multiple packet check */ - if (urb->actual_length != len + 2) { - dev_err(&port->dev, "%s: INCOMPLETE OR MULTIPLE PACKET, " - "status=%d, port=%d, opcode=%d, len=%d, " - "actual_length=%d, status=%d\n", __func__, status, - priv->dp_port_num, opcode, len, urb->actual_length, - port_status); - return -1; - } - - tty = tty_port_tty_get(&port->port); - spin_lock(&priv->dp_port_lock); - - /* check for throttle; if set, do not resubmit read urb */ - /* indicate the read chain needs to be restarted on unthrottle */ - throttled = priv->dp_throttled; - if (throttled) - priv->dp_throttle_restart = 1; - - /* receive data */ - if (tty && opcode == DIGI_CMD_RECEIVE_DATA) { - /* get flag from port_status */ - flag = 0; - - /* overrun is special, not associated with a char */ - if (port_status & DIGI_OVERRUN_ERROR) - tty_insert_flip_char(tty, 0, TTY_OVERRUN); - - /* break takes precedence over parity, */ - /* which takes precedence over framing errors */ - if (port_status & DIGI_BREAK_ERROR) - flag = TTY_BREAK; - else if (port_status & DIGI_PARITY_ERROR) - flag = TTY_PARITY; - else if (port_status & DIGI_FRAMING_ERROR) - flag = TTY_FRAME; - - /* data length is len-1 (one byte of len is port_status) */ - --len; - if (len > 0) { - tty_insert_flip_string_fixed_flag(tty, data, flag, - len); - tty_flip_buffer_push(tty); - } - } - spin_unlock(&priv->dp_port_lock); - tty_kref_put(tty); - - if (opcode == DIGI_CMD_RECEIVE_DISABLE) - dbg("%s: got RECEIVE_DISABLE", __func__); - else if (opcode != DIGI_CMD_RECEIVE_DATA) - dbg("%s: unknown opcode: %d", __func__, opcode); - - return throttled ? 1 : 0; - -} - - -/* - * Digi Read OOB Callback - * - * Digi Read OOB Callback handles reads on the out of band port. - * When called we know port and port->private are not NULL and - * the port->serial is valid. It returns 0 if successful, and - * -1 if the sanity checks failed. - */ - -static int digi_read_oob_callback(struct urb *urb) -{ - - struct usb_serial_port *port = urb->context; - struct usb_serial *serial = port->serial; - struct tty_struct *tty; - struct digi_port *priv = usb_get_serial_port_data(port); - int opcode, line, status, val; - int i; - unsigned int rts; - - dbg("digi_read_oob_callback: port=%d, len=%d", - priv->dp_port_num, urb->actual_length); - - /* handle each oob command */ - for (i = 0; i < urb->actual_length - 3;) { - opcode = ((unsigned char *)urb->transfer_buffer)[i++]; - line = ((unsigned char *)urb->transfer_buffer)[i++]; - status = ((unsigned char *)urb->transfer_buffer)[i++]; - val = ((unsigned char *)urb->transfer_buffer)[i++]; - - dbg("digi_read_oob_callback: opcode=%d, line=%d, status=%d, val=%d", - opcode, line, status, val); - - if (status != 0 || line >= serial->type->num_ports) - continue; - - port = serial->port[line]; - - priv = usb_get_serial_port_data(port); - if (priv == NULL) - return -1; - - tty = tty_port_tty_get(&port->port); - - rts = 0; - if (tty) - rts = tty->termios->c_cflag & CRTSCTS; - - if (tty && opcode == DIGI_CMD_READ_INPUT_SIGNALS) { - spin_lock(&priv->dp_port_lock); - /* convert from digi flags to termiox flags */ - if (val & DIGI_READ_INPUT_SIGNALS_CTS) { - priv->dp_modem_signals |= TIOCM_CTS; - /* port must be open to use tty struct */ - if (rts) { - tty->hw_stopped = 0; - digi_wakeup_write(port); - } - } else { - priv->dp_modem_signals &= ~TIOCM_CTS; - /* port must be open to use tty struct */ - if (rts) - tty->hw_stopped = 1; - } - if (val & DIGI_READ_INPUT_SIGNALS_DSR) - priv->dp_modem_signals |= TIOCM_DSR; - else - priv->dp_modem_signals &= ~TIOCM_DSR; - if (val & DIGI_READ_INPUT_SIGNALS_RI) - priv->dp_modem_signals |= TIOCM_RI; - else - priv->dp_modem_signals &= ~TIOCM_RI; - if (val & DIGI_READ_INPUT_SIGNALS_DCD) - priv->dp_modem_signals |= TIOCM_CD; - else - priv->dp_modem_signals &= ~TIOCM_CD; - - wake_up_interruptible(&priv->dp_modem_change_wait); - spin_unlock(&priv->dp_port_lock); - } else if (opcode == DIGI_CMD_TRANSMIT_IDLE) { - spin_lock(&priv->dp_port_lock); - priv->dp_transmit_idle = 1; - wake_up_interruptible(&priv->dp_transmit_idle_wait); - spin_unlock(&priv->dp_port_lock); - } else if (opcode == DIGI_CMD_IFLUSH_FIFO) { - wake_up_interruptible(&priv->dp_flush_wait); - } - tty_kref_put(tty); - } - return 0; - -} - -module_usb_serial_driver(digi_driver, serial_drivers); - -MODULE_AUTHOR(DRIVER_AUTHOR); -MODULE_DESCRIPTION(DRIVER_DESC); -MODULE_LICENSE("GPL"); - -module_param(debug, bool, S_IRUGO | S_IWUSR); -MODULE_PARM_DESC(debug, "Debug enabled or not"); diff --git a/ANDROID_3.4.5/drivers/usb/serial/empeg.c b/ANDROID_3.4.5/drivers/usb/serial/empeg.c deleted file mode 100644 index 5b99fc09..00000000 --- a/ANDROID_3.4.5/drivers/usb/serial/empeg.c +++ /dev/null @@ -1,148 +0,0 @@ -/* - * USB Empeg empeg-car player driver - * - * Copyright (C) 2000, 2001 - * Gary Brubaker (xavyer@ix.netcom.com) - * - * Copyright (C) 1999 - 2001 - * Greg Kroah-Hartman (greg@kroah.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, version 2. - * - * See Documentation/usb/usb-serial.txt for more information on using this - * driver - */ - -#include <linux/kernel.h> -#include <linux/errno.h> -#include <linux/init.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/uaccess.h> -#include <linux/usb.h> -#include <linux/usb/serial.h> - -static bool debug; - -/* - * Version Information - */ -#define DRIVER_VERSION "v1.3" -#define DRIVER_AUTHOR "Greg Kroah-Hartman <greg@kroah.com>, Gary Brubaker <xavyer@ix.netcom.com>" -#define DRIVER_DESC "USB Empeg Mark I/II Driver" - -#define EMPEG_VENDOR_ID 0x084f -#define EMPEG_PRODUCT_ID 0x0001 - -/* function prototypes for an empeg-car player */ -static int empeg_startup(struct usb_serial *serial); -static void empeg_init_termios(struct tty_struct *tty); - -static const struct usb_device_id id_table[] = { - { USB_DEVICE(EMPEG_VENDOR_ID, EMPEG_PRODUCT_ID) }, - { } /* Terminating entry */ -}; - -MODULE_DEVICE_TABLE(usb, id_table); - -static struct usb_driver empeg_driver = { - .name = "empeg", - .probe = usb_serial_probe, - .disconnect = usb_serial_disconnect, - .id_table = id_table, -}; - -static struct usb_serial_driver empeg_device = { - .driver = { - .owner = THIS_MODULE, - .name = "empeg", - }, - .id_table = id_table, - .num_ports = 1, - .bulk_out_size = 256, - .throttle = usb_serial_generic_throttle, - .unthrottle = usb_serial_generic_unthrottle, - .attach = empeg_startup, - .init_termios = empeg_init_termios, -}; - -static struct usb_serial_driver * const serial_drivers[] = { - &empeg_device, NULL -}; - -static int empeg_startup(struct usb_serial *serial) -{ - int r; - - dbg("%s", __func__); - - if (serial->dev->actconfig->desc.bConfigurationValue != 1) { - dev_err(&serial->dev->dev, "active config #%d != 1 ??\n", - serial->dev->actconfig->desc.bConfigurationValue); - return -ENODEV; - } - dbg("%s - reset config", __func__); - r = usb_reset_configuration(serial->dev); - - /* continue on with initialization */ - return r; -} - -static void empeg_init_termios(struct tty_struct *tty) -{ - struct ktermios *termios = tty->termios; - - /* - * The empeg-car player wants these particular tty settings. - * You could, for example, change the baud rate, however the - * player only supports 115200 (currently), so there is really - * no point in support for changes to the tty settings. - * (at least for now) - * - * The default requirements for this device are: - */ - termios->c_iflag - &= ~(IGNBRK /* disable ignore break */ - | BRKINT /* disable break causes interrupt */ - | PARMRK /* disable mark parity errors */ - | ISTRIP /* disable clear high bit of input characters */ - | INLCR /* disable translate NL to CR */ - | IGNCR /* disable ignore CR */ - | ICRNL /* disable translate CR to NL */ - | IXON); /* disable enable XON/XOFF flow control */ - - termios->c_oflag - &= ~OPOST; /* disable postprocess output characters */ - - termios->c_lflag - &= ~(ECHO /* disable echo input characters */ - | ECHONL /* disable echo new line */ - | ICANON /* disable erase, kill, werase, and rprnt special characters */ - | ISIG /* disable interrupt, quit, and suspend special characters */ - | IEXTEN); /* disable non-POSIX special characters */ - - termios->c_cflag - &= ~(CSIZE /* no size */ - | PARENB /* disable parity bit */ - | CBAUD); /* clear current baud rate */ - - termios->c_cflag - |= CS8; /* character size 8 bits */ - - tty_encode_baud_rate(tty, 115200, 115200); -} - -module_usb_serial_driver(empeg_driver, serial_drivers); - -MODULE_AUTHOR(DRIVER_AUTHOR); -MODULE_DESCRIPTION(DRIVER_DESC); -MODULE_LICENSE("GPL"); - -module_param(debug, bool, S_IRUGO | S_IWUSR); -MODULE_PARM_DESC(debug, "Debug enabled or not"); diff --git a/ANDROID_3.4.5/drivers/usb/serial/ezusb.c b/ANDROID_3.4.5/drivers/usb/serial/ezusb.c deleted file mode 100644 index 3cfc762f..00000000 --- a/ANDROID_3.4.5/drivers/usb/serial/ezusb.c +++ /dev/null @@ -1,61 +0,0 @@ -/* - * EZ-USB specific functions used by some of the USB to Serial drivers. - * - * Copyright (C) 1999 - 2002 Greg Kroah-Hartman (greg@kroah.com) - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License version - * 2 as published by the Free Software Foundation. - */ - -#include <linux/kernel.h> -#include <linux/errno.h> -#include <linux/init.h> -#include <linux/slab.h> -#include <linux/tty.h> -#include <linux/module.h> -#include <linux/usb.h> -#include <linux/usb/serial.h> - -/* EZ-USB Control and Status Register. Bit 0 controls 8051 reset */ -#define CPUCS_REG 0x7F92 - -int ezusb_writememory(struct usb_serial *serial, int address, - unsigned char *data, int length, __u8 request) -{ - int result; - unsigned char *transfer_buffer; - - /* dbg("ezusb_writememory %x, %d", address, length); */ - if (!serial->dev) { - printk(KERN_ERR "ezusb: %s - no physical device present, " - "failing.\n", __func__); - return -ENODEV; - } - - transfer_buffer = kmemdup(data, length, GFP_KERNEL); - if (!transfer_buffer) { - dev_err(&serial->dev->dev, "%s - kmalloc(%d) failed.\n", - __func__, length); - return -ENOMEM; - } - result = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0), - request, 0x40, address, 0, transfer_buffer, length, 3000); - kfree(transfer_buffer); - return result; -} -EXPORT_SYMBOL_GPL(ezusb_writememory); - -int ezusb_set_reset(struct usb_serial *serial, unsigned char reset_bit) -{ - int response; - - /* dbg("%s - %d", __func__, reset_bit); */ - response = ezusb_writememory(serial, CPUCS_REG, &reset_bit, 1, 0xa0); - if (response < 0) - dev_err(&serial->dev->dev, "%s- %d failed\n", - __func__, reset_bit); - return response; -} -EXPORT_SYMBOL_GPL(ezusb_set_reset); - diff --git a/ANDROID_3.4.5/drivers/usb/serial/ezusb_convert.pl b/ANDROID_3.4.5/drivers/usb/serial/ezusb_convert.pl deleted file mode 100644 index 13f11469..00000000 --- a/ANDROID_3.4.5/drivers/usb/serial/ezusb_convert.pl +++ /dev/null @@ -1,50 +0,0 @@ -#! /usr/bin/perl -w - - -# convert an Intel HEX file into a set of C records usable by the firmware -# loading code in usb-serial.c (or others) - -# accepts the .hex file(s) on stdin, a basename (to name the initialized -# array) as an argument, and prints the .h file to stdout. Typical usage: -# perl ezusb_convert.pl foo <foo.hex >fw_foo.h - - -my $basename = $ARGV[0]; -die "no base name specified" unless $basename; - -while (<STDIN>) { - # ':' <len> <addr> <type> <len-data> <crc> '\r' - # len, type, crc are 2-char hex, addr is 4-char hex. type is 00 for - # normal records, 01 for EOF - my($lenstring, $addrstring, $typestring, $reststring, $doscrap) = - /^:(\w\w)(\w\w\w\w)(\w\w)(\w+)(\r?)$/; - die "malformed line: $_" unless $reststring; - last if $typestring eq '01'; - my($len) = hex($lenstring); - my($addr) = hex($addrstring); - my(@bytes) = unpack("C*", pack("H".(2*$len), $reststring)); - #pop(@bytes); # last byte is a CRC - push(@records, [$addr, \@bytes]); -} - -@sorted_records = sort { $a->[0] <=> $b->[0] } @records; - -print <<"EOF"; -/* - * ${basename}_fw.h - * - * Generated from ${basename}.s by ezusb_convert.pl - * This file is presumed to be under the same copyright as the source file - * from which it was derived. - */ - -EOF - -print "static const struct ezusb_hex_record ${basename}_firmware[] = {\n"; -foreach $r (@sorted_records) { - printf("{ 0x%04x,\t%d,\t{", $r->[0], scalar(@{$r->[1]})); - print join(", ", map {sprintf('0x%02x', $_);} @{$r->[1]}); - print "} },\n"; -} -print "{ 0xffff,\t0,\t{0x00} }\n"; -print "};\n"; diff --git a/ANDROID_3.4.5/drivers/usb/serial/f81232.c b/ANDROID_3.4.5/drivers/usb/serial/f81232.c deleted file mode 100644 index 88c0b196..00000000 --- a/ANDROID_3.4.5/drivers/usb/serial/f81232.c +++ /dev/null @@ -1,405 +0,0 @@ -/* - * Fintek F81232 USB to serial adaptor driver - * - * Copyright (C) 2012 Greg Kroah-Hartman (gregkh@linuxfoundation.org) - * Copyright (C) 2012 Linux Foundation - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 as published by - * the Free Software Foundation. - * - */ - -#include <linux/kernel.h> -#include <linux/errno.h> -#include <linux/init.h> -#include <linux/slab.h> -#include <linux/tty.h> -#include <linux/tty_driver.h> -#include <linux/tty_flip.h> -#include <linux/serial.h> -#include <linux/module.h> -#include <linux/moduleparam.h> -#include <linux/spinlock.h> -#include <linux/uaccess.h> -#include <linux/usb.h> -#include <linux/usb/serial.h> - -static bool debug; - -static const struct usb_device_id id_table[] = { - { USB_DEVICE(0x1934, 0x0706) }, - { } /* Terminating entry */ -}; -MODULE_DEVICE_TABLE(usb, id_table); - -#define CONTROL_DTR 0x01 -#define CONTROL_RTS 0x02 - -#define UART_STATE 0x08 -#define UART_STATE_TRANSIENT_MASK 0x74 -#define UART_DCD 0x01 -#define UART_DSR 0x02 -#define UART_BREAK_ERROR 0x04 -#define UART_RING 0x08 -#define UART_FRAME_ERROR 0x10 -#define UART_PARITY_ERROR 0x20 -#define UART_OVERRUN_ERROR 0x40 -#define UART_CTS 0x80 - -struct f81232_private { - spinlock_t lock; - wait_queue_head_t delta_msr_wait; - u8 line_control; - u8 line_status; -}; - -static void f81232_update_line_status(struct usb_serial_port *port, - unsigned char *data, - unsigned int actual_length) -{ -} - -static void f81232_read_int_callback(struct urb *urb) -{ - struct usb_serial_port *port = urb->context; - unsigned char *data = urb->transfer_buffer; - unsigned int actual_length = urb->actual_length; - int status = urb->status; - int retval; - - dbg("%s (%d)", __func__, port->number); - - switch (status) { - case 0: - /* success */ - break; - case -ECONNRESET: - case -ENOENT: - case -ESHUTDOWN: - /* this urb is terminated, clean up */ - dbg("%s - urb shutting down with status: %d", __func__, - status); - return; - default: - dbg("%s - nonzero urb status received: %d", __func__, - status); - goto exit; - } - - usb_serial_debug_data(debug, &port->dev, __func__, - urb->actual_length, urb->transfer_buffer); - - f81232_update_line_status(port, data, actual_length); - -exit: - retval = usb_submit_urb(urb, GFP_ATOMIC); - if (retval) - dev_err(&urb->dev->dev, - "%s - usb_submit_urb failed with result %d\n", - __func__, retval); -} - -static void f81232_process_read_urb(struct urb *urb) -{ - struct usb_serial_port *port = urb->context; - struct f81232_private *priv = usb_get_serial_port_data(port); - struct tty_struct *tty; - unsigned char *data = urb->transfer_buffer; - char tty_flag = TTY_NORMAL; - unsigned long flags; - u8 line_status; - int i; - - /* update line status */ - spin_lock_irqsave(&priv->lock, flags); - line_status = priv->line_status; - priv->line_status &= ~UART_STATE_TRANSIENT_MASK; - spin_unlock_irqrestore(&priv->lock, flags); - wake_up_interruptible(&priv->delta_msr_wait); - - if (!urb->actual_length) - return; - - tty = tty_port_tty_get(&port->port); - if (!tty) - return; - - /* break takes precedence over parity, */ - /* which takes precedence over framing errors */ - if (line_status & UART_BREAK_ERROR) - tty_flag = TTY_BREAK; - else if (line_status & UART_PARITY_ERROR) - tty_flag = TTY_PARITY; - else if (line_status & UART_FRAME_ERROR) - tty_flag = TTY_FRAME; - dbg("%s - tty_flag = %d", __func__, tty_flag); - - /* overrun is special, not associated with a char */ - if (line_status & UART_OVERRUN_ERROR) - tty_insert_flip_char(tty, 0, TTY_OVERRUN); - - if (port->port.console && port->sysrq) { - for (i = 0; i < urb->actual_length; ++i) - if (!usb_serial_handle_sysrq_char(port, data[i])) - tty_insert_flip_char(tty, data[i], tty_flag); - } else { - tty_insert_flip_string_fixed_flag(tty, data, tty_flag, - urb->actual_length); - } - - tty_flip_buffer_push(tty); - tty_kref_put(tty); -} - -static int set_control_lines(struct usb_device *dev, u8 value) -{ - /* FIXME - Stubbed out for now */ - return 0; -} - -static void f81232_break_ctl(struct tty_struct *tty, int break_state) -{ - /* FIXME - Stubbed out for now */ - - /* - * break_state = -1 to turn on break, and 0 to turn off break - * see drivers/char/tty_io.c to see it used. - * last_set_data_urb_value NEVER has the break bit set in it. - */ -} - -static void f81232_set_termios(struct tty_struct *tty, - struct usb_serial_port *port, struct ktermios *old_termios) -{ - /* FIXME - Stubbed out for now */ - - /* Don't change anything if nothing has changed */ - if (!tty_termios_hw_change(tty->termios, old_termios)) - return; - - /* Do the real work here... */ -} - -static int f81232_tiocmget(struct tty_struct *tty) -{ - /* FIXME - Stubbed out for now */ - return 0; -} - -static int f81232_tiocmset(struct tty_struct *tty, - unsigned int set, unsigned int clear) -{ - /* FIXME - Stubbed out for now */ - return 0; -} - -static int f81232_open(struct tty_struct *tty, struct usb_serial_port *port) -{ - struct ktermios tmp_termios; - int result; - - /* Setup termios */ - if (tty) - f81232_set_termios(tty, port, &tmp_termios); - - dbg("%s - submitting interrupt urb", __func__); - result = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL); - if (result) { - dev_err(&port->dev, "%s - failed submitting interrupt urb," - " error %d\n", __func__, result); - return result; - } - - result = usb_serial_generic_open(tty, port); - if (result) { - usb_kill_urb(port->interrupt_in_urb); - return result; - } - - port->port.drain_delay = 256; - return 0; -} - -static void f81232_close(struct usb_serial_port *port) -{ - usb_serial_generic_close(port); - usb_kill_urb(port->interrupt_in_urb); -} - -static void f81232_dtr_rts(struct usb_serial_port *port, int on) -{ - struct f81232_private *priv = usb_get_serial_port_data(port); - unsigned long flags; - u8 control; - - spin_lock_irqsave(&priv->lock, flags); - /* Change DTR and RTS */ - if (on) - priv->line_control |= (CONTROL_DTR | CONTROL_RTS); - else - priv->line_control &= ~(CONTROL_DTR | CONTROL_RTS); - control = priv->line_control; - spin_unlock_irqrestore(&priv->lock, flags); - set_control_lines(port->serial->dev, control); -} - -static int f81232_carrier_raised(struct usb_serial_port *port) -{ - struct f81232_private *priv = usb_get_serial_port_data(port); - if (priv->line_status & UART_DCD) - return 1; - return 0; -} - -static int wait_modem_info(struct usb_serial_port *port, unsigned int arg) -{ - struct f81232_private *priv = usb_get_serial_port_data(port); - unsigned long flags; - unsigned int prevstatus; - unsigned int status; - unsigned int changed; - - spin_lock_irqsave(&priv->lock, flags); - prevstatus = priv->line_status; - spin_unlock_irqrestore(&priv->lock, flags); - - while (1) { - interruptible_sleep_on(&priv->delta_msr_wait); - /* see if a signal did it */ - if (signal_pending(current)) - return -ERESTARTSYS; - - spin_lock_irqsave(&priv->lock, flags); - status = priv->line_status; - spin_unlock_irqrestore(&priv->lock, flags); - - changed = prevstatus ^ status; - - if (((arg & TIOCM_RNG) && (changed & UART_RING)) || - ((arg & TIOCM_DSR) && (changed & UART_DSR)) || - ((arg & TIOCM_CD) && (changed & UART_DCD)) || - ((arg & TIOCM_CTS) && (changed & UART_CTS))) { - return 0; - } - prevstatus = status; - } - /* NOTREACHED */ - return 0; -} - -static int f81232_ioctl(struct tty_struct *tty, - unsigned int cmd, unsigned long arg) -{ - struct serial_struct ser; - struct usb_serial_port *port = tty->driver_data; - dbg("%s (%d) cmd = 0x%04x", __func__, port->number, cmd); - - switch (cmd) { - case TIOCGSERIAL: - memset(&ser, 0, sizeof ser); - ser.type = PORT_16654; - ser.line = port->serial->minor; - ser.port = port->number; - ser.baud_base = 460800; - - if (copy_to_user((void __user *)arg, &ser, sizeof ser)) - return -EFAULT; - - return 0; - - case TIOCMIWAIT: - dbg("%s (%d) TIOCMIWAIT", __func__, port->number); - return wait_modem_info(port, arg); - default: - dbg("%s not supported = 0x%04x", __func__, cmd); - break; - } - return -ENOIOCTLCMD; -} - -static int f81232_startup(struct usb_serial *serial) -{ - struct f81232_private *priv; - int i; - - for (i = 0; i < serial->num_ports; ++i) { - priv = kzalloc(sizeof(struct f81232_private), GFP_KERNEL); - if (!priv) - goto cleanup; - spin_lock_init(&priv->lock); - init_waitqueue_head(&priv->delta_msr_wait); - usb_set_serial_port_data(serial->port[i], priv); - } - return 0; - -cleanup: - for (--i; i >= 0; --i) { - priv = usb_get_serial_port_data(serial->port[i]); - kfree(priv); - usb_set_serial_port_data(serial->port[i], NULL); - } - return -ENOMEM; -} - -static void f81232_release(struct usb_serial *serial) -{ - int i; - struct f81232_private *priv; - - for (i = 0; i < serial->num_ports; ++i) { - priv = usb_get_serial_port_data(serial->port[i]); - kfree(priv); - } -} - -static struct usb_driver f81232_driver = { - .name = "f81232", - .probe = usb_serial_probe, - .disconnect = usb_serial_disconnect, - .id_table = id_table, - .suspend = usb_serial_suspend, - .resume = usb_serial_resume, - .no_dynamic_id = 1, - .supports_autosuspend = 1, -}; - -static struct usb_serial_driver f81232_device = { - .driver = { - .owner = THIS_MODULE, - .name = "f81232", - }, - .id_table = id_table, - .usb_driver = &f81232_driver, - .num_ports = 1, - .bulk_in_size = 256, - .bulk_out_size = 256, - .open = f81232_open, - .close = f81232_close, - .dtr_rts = f81232_dtr_rts, - .carrier_raised = f81232_carrier_raised, - .ioctl = f81232_ioctl, - .break_ctl = f81232_break_ctl, - .set_termios = f81232_set_termios, - .tiocmget = f81232_tiocmget, - .tiocmset = f81232_tiocmset, - .process_read_urb = f81232_process_read_urb, - .read_int_callback = f81232_read_int_callback, - .attach = f81232_startup, - .release = f81232_release, -}; - -static struct usb_serial_driver * const serial_drivers[] = { - &f81232_device, - NULL, -}; - -module_usb_serial_driver(f81232_driver, serial_drivers); - -MODULE_DESCRIPTION("Fintek F81232 USB to serial adaptor driver"); -MODULE_AUTHOR("Greg Kroah-Hartman <gregkh@linuxfoundation.org"); -MODULE_LICENSE("GPL v2"); - -module_param(debug, bool, S_IRUGO | S_IWUSR); -MODULE_PARM_DESC(debug, "Debug enabled or not"); - diff --git a/ANDROID_3.4.5/drivers/usb/serial/ftdi_sio.c b/ANDROID_3.4.5/drivers/usb/serial/ftdi_sio.c deleted file mode 100644 index 53e3e2c5..00000000 --- a/ANDROID_3.4.5/drivers/usb/serial/ftdi_sio.c +++ /dev/null @@ -1,2481 +0,0 @@ -/* - * USB FTDI SIO driver - * - * 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) - * - * 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. - * - * See Documentation/usb/usb-serial.txt 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/init.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/usb/serial.h> -#include "ftdi_sio.h" -#include "ftdi_sio_ids.h" - -/* - * Version Information - */ -#define DRIVER_VERSION "v1.6.0" -#define DRIVER_AUTHOR "Greg Kroah-Hartman <greg@kroah.com>, Bill Ryder <bryder@sgi.com>, Kuba Ober <kuba@mareimbrium.org>, Andreas Mohr, Johan Hovold <jhovold@gmail.com>" -#define DRIVER_DESC "USB FTDI Serial Converters Driver" - -static bool debug; -static __u16 vendor = FTDI_VID; -static __u16 product; - -struct ftdi_private { - struct kref kref; - enum ftdi_chip_type chip_type; - /* type of device, either SIO or FT8U232AM */ - 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_urb_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 */ - struct async_icount icount; - wait_queue_head_t delta_msr_wait; /* Used for TIOCMIWAIT */ - char prev_status; /* Used for TIOCMIWAIT */ - bool dev_gone; /* Used to abort TIOCMIWAIT */ - char transmit_empty; /* If transmitter is empty or not */ - struct usb_serial_port *port; - __u16 interface; /* FT2232C, FT2232H or FT4232H port interface - (0 for FT232/245) */ - - 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() */ -}; - -/* struct ftdi_sio_quirk is used by devices requiring special attention. */ -struct ftdi_sio_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_mtxorb_hack_setup(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 struct ftdi_sio_quirk ftdi_jtag_quirk = { - .probe = ftdi_jtag_probe, -}; - -static struct ftdi_sio_quirk ftdi_mtxorb_hack_quirk = { - .probe = ftdi_mtxorb_hack_setup, -}; - -static struct ftdi_sio_quirk ftdi_NDI_device_quirk = { - .probe = ftdi_NDI_device_setup, -}; - -static struct ftdi_sio_quirk ftdi_USB_UIRT_quirk = { - .port_probe = ftdi_USB_UIRT_setup, -}; - -static struct ftdi_sio_quirk ftdi_HE_TIRA1_quirk = { - .port_probe = ftdi_HE_TIRA1_setup, -}; - -static struct ftdi_sio_quirk ftdi_stmclite_quirk = { - .probe = ftdi_stmclite_probe, -}; - -static struct ftdi_sio_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 via module params product/vendor or - * /sys/bus/usb/ftdi_sio/new_id, then send patch/report! - */ -static struct usb_device_id id_table_combined [] = { - { 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) , - .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_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), - .driver_info = (kernel_ulong_t)&ftdi_mtxorb_hack_quirk }, - { 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), - .driver_info = (kernel_ulong_t)&ftdi_mtxorb_hack_quirk }, - { 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), - .driver_info = (kernel_ulong_t)&ftdi_mtxorb_hack_quirk }, - { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0154_PID), - .driver_info = (kernel_ulong_t)&ftdi_mtxorb_hack_quirk }, - { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0155_PID), - .driver_info = (kernel_ulong_t)&ftdi_mtxorb_hack_quirk }, - { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0156_PID), - .driver_info = (kernel_ulong_t)&ftdi_mtxorb_hack_quirk }, - { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0157_PID), - .driver_info = (kernel_ulong_t)&ftdi_mtxorb_hack_quirk }, - { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0158_PID), - .driver_info = (kernel_ulong_t)&ftdi_mtxorb_hack_quirk }, - { 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), - .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) }, - /* - * 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(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), - .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(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), - .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, - { USB_DEVICE(OLIMEX_VID, OLIMEX_ARM_USB_OCD_H_PID), - .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, - { 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(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(MICROCHIP_VID, MICROCHIP_USB_BOARD_PID) }, - { 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(PI_VID, PI_E861_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_DOTEC_PID) }, - { USB_DEVICE(QIHARDWARE_VID, MILKYMISTONE_JTAGSERIAL_PID), - .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, - { USB_DEVICE(ST_VID, ST_STMCLT1030_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) }, - { }, /* Optional parameter entry */ - { } /* Terminating entry */ -}; - -MODULE_DEVICE_TABLE(usb, id_table_combined); - -static struct usb_driver ftdi_driver = { - .name = "ftdi_sio", - .probe = usb_serial_probe, - .disconnect = usb_serial_disconnect, - .id_table = id_table_combined, -}; - -static const char *ftdi_chip_name[] = { - [SIO] = "SIO", /* the serial part of FT8U100AX */ - [FT8U232AM] = "FT8U232AM", - [FT232BM] = "FT232BM", - [FT2232C] = "FT2232C", - [FT232RL] = "FT232RL", - [FT2232H] = "FT2232H", - [FT4232H] = "FT4232H", - [FT232H] = "FT232H", - [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 */ - -#define FTDI_IMPL_ASYNC_FLAGS = (ASYNC_SPD_HI | ASYNC_SPD_VHI \ - | ASYNC_SPD_CUST | ASYNC_SPD_SHI | ASYNC_SPD_WARP) - -/* function prototypes for a FTDI serial converter */ -static int ftdi_sio_probe(struct usb_serial *serial, - const struct usb_device_id *id); -static int ftdi_sio_port_probe(struct usb_serial_port *port); -static int ftdi_sio_port_remove(struct usb_serial_port *port); -static int ftdi_open(struct tty_struct *tty, struct usb_serial_port *port); -static void ftdi_close(struct usb_serial_port *port); -static void ftdi_dtr_rts(struct usb_serial_port *port, int on); -static void ftdi_process_read_urb(struct urb *urb); -static int ftdi_prepare_write_buffer(struct usb_serial_port *port, - void *dest, size_t size); -static void ftdi_set_termios(struct tty_struct *tty, - struct usb_serial_port *port, struct ktermios *old); -static int ftdi_tiocmget(struct tty_struct *tty); -static int ftdi_tiocmset(struct tty_struct *tty, - unsigned int set, unsigned int clear); -static int ftdi_get_icount(struct tty_struct *tty, - struct serial_icounter_struct *icount); -static int ftdi_ioctl(struct tty_struct *tty, - unsigned int cmd, unsigned long arg); -static void ftdi_break_ctl(struct tty_struct *tty, int break_state); - -static unsigned short int ftdi_232am_baud_base_to_divisor(int baud, int base); -static unsigned short int ftdi_232am_baud_to_divisor(int baud); -static __u32 ftdi_232bm_baud_base_to_divisor(int baud, int base); -static __u32 ftdi_232bm_baud_to_divisor(int baud); -static __u32 ftdi_2232h_baud_base_to_divisor(int baud, int base); -static __u32 ftdi_2232h_baud_to_divisor(int baud); - -static struct usb_serial_driver ftdi_sio_device = { - .driver = { - .owner = THIS_MODULE, - .name = "ftdi_sio", - }, - .description = "FTDI USB Serial Device", - .id_table = id_table_combined, - .num_ports = 1, - .bulk_in_size = 512, - .bulk_out_size = 256, - .probe = ftdi_sio_probe, - .port_probe = ftdi_sio_port_probe, - .port_remove = ftdi_sio_port_remove, - .open = ftdi_open, - .close = ftdi_close, - .dtr_rts = ftdi_dtr_rts, - .throttle = usb_serial_generic_throttle, - .unthrottle = usb_serial_generic_unthrottle, - .process_read_urb = ftdi_process_read_urb, - .prepare_write_buffer = ftdi_prepare_write_buffer, - .tiocmget = ftdi_tiocmget, - .tiocmset = ftdi_tiocmset, - .get_icount = ftdi_get_icount, - .ioctl = ftdi_ioctl, - .set_termios = ftdi_set_termios, - .break_ctl = ftdi_break_ctl, -}; - -static struct usb_serial_driver * const serial_drivers[] = { - &ftdi_sio_device, NULL -}; - - -#define WDR_TIMEOUT 5000 /* default urb timeout */ -#define WDR_SHORT_TIMEOUT 1000 /* shorter urb timeout */ - -/* High and low are for DTR, RTS etc etc */ -#define HIGH 1 -#define LOW 0 - -/* - * *************************************************************************** - * 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 = 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; - else if (divisor3 >= 4) - divisor |= 0x4000; - else if (divisor3 != 0) - divisor |= 0x8000; - 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 = base / 2 / baud; - divisor = divisor3 >> 3; - divisor |= (__u32)divfrac[divisor3 & 0x7] << 14; - /* Deal with special cases for highest baud rates. */ - if (divisor == 1) - divisor = 0; - else if (divisor == 0x4001) - 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 = base * 8 / (baud * 10); - - divisor = divisor3 >> 3; - divisor |= (__u32)divfrac[divisor3 & 0x7] << 14; - /* Deal with special cases for highest baud rates. */ - if (divisor == 1) - divisor = 0; - else if (divisor == 0x4001) - 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); - unsigned urb_value; - int rv; - - if (((set | clear) & (TIOCM_DTR | TIOCM_RTS)) == 0) { - dbg("%s - DTR|RTS not being set|cleared", __func__); - return 0; /* no change */ - } - - clear &= ~set; /* 'set' takes precedence over 'clear' */ - urb_value = 0; - if (clear & TIOCM_DTR) - urb_value |= FTDI_SIO_SET_DTR_LOW; - if (clear & TIOCM_RTS) - urb_value |= FTDI_SIO_SET_RTS_LOW; - if (set & TIOCM_DTR) - urb_value |= FTDI_SIO_SET_DTR_HIGH; - if (set & TIOCM_RTS) - urb_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, - urb_value, priv->interface, - NULL, 0, WDR_TIMEOUT); - if (rv < 0) { - dbg("%s Error from MODEM_CTRL urb: DTR %s, RTS %s", - __func__, - (set & TIOCM_DTR) ? "HIGH" : - (clear & TIOCM_DTR) ? "LOW" : "unchanged", - (set & TIOCM_RTS) ? "HIGH" : - (clear & TIOCM_RTS) ? "LOW" : "unchanged"); - } else { - dbg("%s - DTR %s, RTS %s", __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); - __u32 div_value = 0; - int div_okay = 1; - int baud; - - /* - * The logic involved in setting the baudrate can be cleanly split into - * 3 steps. - * 1. Standard baud rates are set in tty->termios->c_cflag - * 2. If these are not enough, you can set any speed using alt_speed as - * follows: - * - set tty->termios->c_cflag speed to B38400 - * - set your real speed in tty->alt_speed; it gets ignored when - * alt_speed==0, (or) - * - call TIOCSSERIAL ioctl with (struct serial_struct) set as - * follows: - * flags & ASYNC_SPD_MASK == ASYNC_SPD_[HI, VHI, SHI, WARP], - * this just sets alt_speed to (HI: 57600, VHI: 115200, - * SHI: 230400, WARP: 460800) - * ** Steps 1, 2 are done courtesy of tty_get_baud_rate - * 3. You can also set baud rate by setting custom divisor as follows - * - set tty->termios->c_cflag speed to B38400 - * - call TIOCSSERIAL ioctl with (struct serial_struct) set as - * follows: - * o flags & ASYNC_SPD_MASK == ASYNC_SPD_CUST - * o custom_divisor set to baud_base / your_new_baudrate - * ** Step 3 is done courtesy of code borrowed from serial.c - * I should really spend some time and separate + move this common - * code to serial.c, it is replicated in nearly every serial driver - * you see. - */ - - /* 1. Get the baud rate from the tty settings, this observes - alt_speed hack */ - - baud = tty_get_baud_rate(tty); - dbg("%s - tty_get_baud_rate reports speed %d", __func__, baud); - - /* 2. Observe 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; - dbg("%s - custom divisor %d sets baud rate to %d", - __func__, priv->custom_divisor, baud); - } - - /* 3. Convert baudrate to device-specific divisor */ - - if (!baud) - baud = 9600; - switch (priv->chip_type) { - case SIO: /* SIO chip */ - 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; - } /* baud */ - if (div_value == 0) { - dbg("%s - Baudrate (%d) requested is not supported", - __func__, baud); - div_value = ftdi_sio_b9600; - baud = 9600; - div_okay = 0; - } - break; - case FT8U232AM: /* 8U232AM chip */ - if (baud <= 3000000) { - div_value = ftdi_232am_baud_to_divisor(baud); - } else { - dbg("%s - Baud rate too high!", __func__); - baud = 9600; - div_value = ftdi_232am_baud_to_divisor(9600); - div_okay = 0; - } - break; - case FT232BM: /* FT232BM chip */ - case FT2232C: /* FT2232C chip */ - case FT232RL: /* FT232RL chip */ - case FTX: /* FT-X series */ - if (baud <= 3000000) { - __u16 product_id = le16_to_cpu( - port->serial->dev->descriptor.idProduct); - if (((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 == product_id)) && - (baud == 19200)) { - baud = 1200000; - } - div_value = ftdi_232bm_baud_to_divisor(baud); - } else { - dbg("%s - Baud rate too high!", __func__); - div_value = ftdi_232bm_baud_to_divisor(9600); - div_okay = 0; - baud = 9600; - } - break; - case FT2232H: /* FT2232H chip */ - case FT4232H: /* FT4232H chip */ - case FT232H: /* FT232H chip */ - 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 { - dbg("%s - Baud rate too high!", __func__); - div_value = ftdi_232bm_baud_to_divisor(9600); - div_okay = 0; - baud = 9600; - } - break; - } /* priv->chip_type */ - - if (div_okay) { - dbg("%s - Baud rate set to %d (divisor 0x%lX) on chip %s", - __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 urb_value; - __u16 urb_index; - __u32 urb_index_value; - int rv; - - urb_index_value = get_ftdi_divisor(tty, port); - urb_value = (__u16)urb_index_value; - urb_index = (__u16)(urb_index_value >> 16); - if ((priv->chip_type == FT2232C) || (priv->chip_type == FT2232H) || - (priv->chip_type == FT4232H) || (priv->chip_type == FT232H)) { - /* Probably the BM type needs the MSB of the encoded fractional - * divider also moved like for the chips above. Any infos? */ - urb_index = (__u16)((urb_index << 8) | priv->interface); - } - - rv = usb_control_msg(port->serial->dev, - usb_sndctrlpipe(port->serial->dev, 0), - FTDI_SIO_SET_BAUDRATE_REQUEST, - FTDI_SIO_SET_BAUDRATE_REQUEST_TYPE, - urb_value, urb_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->flags & ASYNC_LOW_LATENCY) - l = 1; - - dbg("%s: setting latency timer = %i", __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->interface, - 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; - unsigned char *buf; - int rv; - - dbg("%s", __func__); - - buf = kmalloc(1, GFP_KERNEL); - if (!buf) - return -ENOMEM; - - rv = usb_control_msg(udev, - usb_rcvctrlpipe(udev, 0), - FTDI_SIO_GET_LATENCY_TIMER_REQUEST, - FTDI_SIO_GET_LATENCY_TIMER_REQUEST_TYPE, - 0, priv->interface, - buf, 1, WDR_TIMEOUT); - if (rv < 0) - dev_err(&port->dev, "Unable to read latency timer: %i\n", rv); - else - priv->latency = buf[0]; - - kfree(buf); - - return rv; -} - -static int get_serial_info(struct usb_serial_port *port, - struct serial_struct __user *retinfo) -{ - struct ftdi_private *priv = usb_get_serial_port_data(port); - struct serial_struct tmp; - - if (!retinfo) - return -EFAULT; - memset(&tmp, 0, sizeof(tmp)); - tmp.flags = priv->flags; - tmp.baud_base = priv->baud_base; - tmp.custom_divisor = priv->custom_divisor; - if (copy_to_user(retinfo, &tmp, sizeof(*retinfo))) - return -EFAULT; - return 0; -} - -static int set_serial_info(struct tty_struct *tty, - struct usb_serial_port *port, struct serial_struct __user *newinfo) -{ - struct ftdi_private *priv = usb_get_serial_port_data(port); - struct serial_struct new_serial; - struct ftdi_private old_priv; - - if (copy_from_user(&new_serial, newinfo, sizeof(new_serial))) - return -EFAULT; - - mutex_lock(&priv->cfg_lock); - old_priv = *priv; - - /* Do error checking and permission checking */ - - if (!capable(CAP_SYS_ADMIN)) { - if (((new_serial.flags & ~ASYNC_USR_MASK) != - (priv->flags & ~ASYNC_USR_MASK))) { - mutex_unlock(&priv->cfg_lock); - return -EPERM; - } - priv->flags = ((priv->flags & ~ASYNC_USR_MASK) | - (new_serial.flags & ASYNC_USR_MASK)); - priv->custom_divisor = new_serial.custom_divisor; - goto check_and_exit; - } - - if (new_serial.baud_base != priv->baud_base) { - mutex_unlock(&priv->cfg_lock); - return -EINVAL; - } - - /* Make the changes - these are privileged changes! */ - - priv->flags = ((priv->flags & ~ASYNC_FLAGS) | - (new_serial.flags & ASYNC_FLAGS)); - priv->custom_divisor = new_serial.custom_divisor; - - write_latency_timer(port); - -check_and_exit: - if ((old_priv.flags & ASYNC_SPD_MASK) != - (priv->flags & ASYNC_SPD_MASK)) { - if ((priv->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI) - tty->alt_speed = 57600; - else if ((priv->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI) - tty->alt_speed = 115200; - else if ((priv->flags & ASYNC_SPD_MASK) == ASYNC_SPD_SHI) - tty->alt_speed = 230400; - else if ((priv->flags & ASYNC_SPD_MASK) == ASYNC_SPD_WARP) - tty->alt_speed = 460800; - else - tty->alt_speed = 0; - } - if (((old_priv.flags & ASYNC_SPD_MASK) != - (priv->flags & ASYNC_SPD_MASK)) || - (((priv->flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST) && - (old_priv.custom_divisor != priv->custom_divisor))) { - change_speed(tty, port); - mutex_unlock(&priv->cfg_lock); - } - else - mutex_unlock(&priv->cfg_lock); - return 0; -} - -static int get_lsr_info(struct usb_serial_port *port, - struct serial_struct __user *retinfo) -{ - struct ftdi_private *priv = usb_get_serial_port_data(port); - unsigned int result = 0; - - if (!retinfo) - return -EFAULT; - - if (priv->transmit_empty) - result = TIOCSER_TEMT; - - if (copy_to_user(retinfo, &result, sizeof(unsigned int))) - return -EFAULT; - return 0; -} - - -/* Determine type of FTDI chip based on USB config and descriptor. */ -static void 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; - unsigned version; - unsigned interfaces; - - /* Assume it is not the original SIO device for now. */ - priv->baud_base = 48000000 / 2; - - version = le16_to_cpu(udev->descriptor.bcdDevice); - interfaces = udev->actconfig->desc.bNumInterfaces; - dbg("%s: bcdDevice = 0x%x, bNumInterfaces = %u", __func__, - version, interfaces); - if (interfaces > 1) { - int inter; - - /* Multiple interfaces.*/ - if (version == 0x0800) { - priv->chip_type = FT4232H; - /* Hi-speed - baud clock runs at 120MHz */ - priv->baud_base = 120000000 / 2; - } else if (version == 0x0700) { - priv->chip_type = FT2232H; - /* Hi-speed - baud clock runs at 120MHz */ - priv->baud_base = 120000000 / 2; - } else - priv->chip_type = FT2232C; - - /* Determine interface code. */ - inter = serial->interface->altsetting->desc.bInterfaceNumber; - if (inter == 0) { - priv->interface = INTERFACE_A; - } else if (inter == 1) { - priv->interface = INTERFACE_B; - } else if (inter == 2) { - priv->interface = INTERFACE_C; - } else if (inter == 3) { - priv->interface = INTERFACE_D; - } - /* BM-type devices have a bug where bcdDevice gets set - * to 0x200 when iSerialNumber is 0. */ - if (version < 0x500) { - dbg("%s: something fishy - bcdDevice too low for multi-interface device", - __func__); - } - } else if (version < 0x200) { - /* Old device. Assume it's the original SIO. */ - priv->chip_type = SIO; - priv->baud_base = 12000000 / 16; - } else if (version < 0x400) { - /* Assume it's an FT8U232AM (or FT8U245AM) */ - /* (It might be a BM because of the iSerialNumber bug, - * but it will still work as an AM device.) */ - priv->chip_type = FT8U232AM; - } else if (version < 0x600) { - /* Assume it's an FT232BM (or FT245BM) */ - priv->chip_type = FT232BM; - } else if (version < 0x900) { - /* Assume it's an FT232RL */ - priv->chip_type = FT232RL; - } else if (version < 0x1000) { - /* Assume it's an FT232H */ - priv->chip_type = FT232H; - } else { - /* Assume it's an FT-X series device */ - priv->chip_type = FTX; - } - - dev_info(&udev->dev, "Detected %s\n", ftdi_chip_name[priv->chip_type]); -} - - -/* Determine the maximum packet size for the device. This depends on the chip - * type and the USB host capabilities. The value should be obtained from the - * device descriptor as the chip will use the appropriate values for the host.*/ -static void ftdi_set_max_packet_size(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; - - struct usb_interface *interface = serial->interface; - struct usb_endpoint_descriptor *ep_desc = &interface->cur_altsetting->endpoint[1].desc; - - unsigned num_endpoints; - int i; - - num_endpoints = interface->cur_altsetting->desc.bNumEndpoints; - dev_info(&udev->dev, "Number of endpoints %d\n", num_endpoints); - - /* NOTE: some customers have programmed FT232R/FT245R devices - * with an endpoint size of 0 - not good. In this case, we - * want to override the endpoint descriptor setting and use a - * value of 64 for wMaxPacketSize */ - for (i = 0; i < num_endpoints; i++) { - dev_info(&udev->dev, "Endpoint %d MaxPacketSize %d\n", i+1, - interface->cur_altsetting->endpoint[i].desc.wMaxPacketSize); - ep_desc = &interface->cur_altsetting->endpoint[i].desc; - if (ep_desc->wMaxPacketSize == 0) { - ep_desc->wMaxPacketSize = cpu_to_le16(0x40); - dev_info(&udev->dev, "Overriding wMaxPacketSize on endpoint %d\n", i); - } - } - - /* set max packet size based on descriptor */ - priv->max_packet_size = usb_endpoint_maxp(ep_desc); - - dev_info(&udev->dev, "Setting MaxPacketSize %d\n", priv->max_packet_size); -} - - -/* - * *************************************************************************** - * Sysfs Attribute - * *************************************************************************** - */ - -static ssize_t show_latency_timer(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct usb_serial_port *port = to_usb_serial_port(dev); - struct ftdi_private *priv = usb_get_serial_port_data(port); - if (priv->flags & ASYNC_LOW_LATENCY) - return sprintf(buf, "1\n"); - else - return sprintf(buf, "%i\n", priv->latency); -} - - -/* Write a new value of the latency timer, in units of milliseconds. */ -static ssize_t store_latency_timer(struct device *dev, - struct device_attribute *attr, const char *valbuf, - size_t count) -{ - struct usb_serial_port *port = to_usb_serial_port(dev); - struct ftdi_private *priv = usb_get_serial_port_data(port); - int v = simple_strtoul(valbuf, NULL, 10); - int rv; - - priv->latency = v; - rv = write_latency_timer(port); - if (rv < 0) - return -EIO; - return count; -} - -/* Write an event character directly to the FTDI register. The ASCII - value is in the low 8 bits, with the enable bit in the 9th bit. */ -static ssize_t store_event_char(struct device *dev, - struct device_attribute *attr, const char *valbuf, size_t count) -{ - struct usb_serial_port *port = to_usb_serial_port(dev); - struct ftdi_private *priv = usb_get_serial_port_data(port); - struct usb_device *udev = port->serial->dev; - int v = simple_strtoul(valbuf, NULL, 10); - int rv; - - dbg("%s: setting event char = %i", __func__, v); - - rv = usb_control_msg(udev, - usb_sndctrlpipe(udev, 0), - FTDI_SIO_SET_EVENT_CHAR_REQUEST, - FTDI_SIO_SET_EVENT_CHAR_REQUEST_TYPE, - v, priv->interface, - NULL, 0, WDR_TIMEOUT); - if (rv < 0) { - dbg("Unable to write event character: %i", rv); - return -EIO; - } - - return count; -} - -static DEVICE_ATTR(latency_timer, S_IWUSR | S_IRUGO, show_latency_timer, - store_latency_timer); -static DEVICE_ATTR(event_char, S_IWUSR, NULL, store_event_char); - -static int create_sysfs_attrs(struct usb_serial_port *port) -{ - struct ftdi_private *priv = usb_get_serial_port_data(port); - int retval = 0; - - dbg("%s", __func__); - - /* XXX I've no idea if the original SIO supports the event_char - * sysfs parameter, so I'm playing it safe. */ - if (priv->chip_type != SIO) { - dbg("sysfs attributes for %s", ftdi_chip_name[priv->chip_type]); - retval = device_create_file(&port->dev, &dev_attr_event_char); - if ((!retval) && - (priv->chip_type == FT232BM || - priv->chip_type == FT2232C || - priv->chip_type == FT232RL || - priv->chip_type == FT2232H || - priv->chip_type == FT4232H || - priv->chip_type == FT232H || - priv->chip_type == FTX)) { - retval = device_create_file(&port->dev, - &dev_attr_latency_timer); - } - } - return retval; -} - -static void remove_sysfs_attrs(struct usb_serial_port *port) -{ - struct ftdi_private *priv = usb_get_serial_port_data(port); - - dbg("%s", __func__); - - /* XXX see create_sysfs_attrs */ - if (priv->chip_type != SIO) { - device_remove_file(&port->dev, &dev_attr_event_char); - if (priv->chip_type == FT232BM || - priv->chip_type == FT2232C || - priv->chip_type == FT232RL || - priv->chip_type == FT2232H || - priv->chip_type == FT4232H || - priv->chip_type == FT232H || - priv->chip_type == FTX) { - device_remove_file(&port->dev, &dev_attr_latency_timer); - } - } - -} - -/* - * *************************************************************************** - * FTDI driver specific functions - * *************************************************************************** - */ - -/* Probe function to check for special devices */ -static int ftdi_sio_probe(struct usb_serial *serial, - const struct usb_device_id *id) -{ - struct ftdi_sio_quirk *quirk = - (struct ftdi_sio_quirk *)id->driver_info; - - if (quirk && quirk->probe) { - int ret = quirk->probe(serial); - if (ret != 0) - return ret; - } - - usb_set_serial_data(serial, (void *)id->driver_info); - - return 0; -} - -static int ftdi_sio_port_probe(struct usb_serial_port *port) -{ - struct ftdi_private *priv; - struct ftdi_sio_quirk *quirk = usb_get_serial_data(port->serial); - - - dbg("%s", __func__); - - priv = kzalloc(sizeof(struct ftdi_private), GFP_KERNEL); - if (!priv) { - dev_err(&port->dev, "%s- kmalloc(%Zd) failed.\n", __func__, - sizeof(struct ftdi_private)); - return -ENOMEM; - } - - kref_init(&priv->kref); - mutex_init(&priv->cfg_lock); - memset(&priv->icount, 0x00, sizeof(priv->icount)); - init_waitqueue_head(&priv->delta_msr_wait); - - priv->flags = ASYNC_LOW_LATENCY; - priv->dev_gone = false; - - if (quirk && quirk->port_probe) - quirk->port_probe(priv); - - priv->port = port; - usb_set_serial_port_data(port, priv); - - ftdi_determine_type(port); - ftdi_set_max_packet_size(port); - if (read_latency_timer(port) < 0) - priv->latency = 16; - write_latency_timer(port); - create_sysfs_attrs(port); - return 0; -} - -/* Setup for the USB-UIRT device, which requires hardwired - * baudrate (38400 gets mapped to 312500) */ -/* Called from usbserial:serial_probe */ -static void ftdi_USB_UIRT_setup(struct ftdi_private *priv) -{ - dbg("%s", __func__); - - priv->flags |= ASYNC_SPD_CUST; - priv->custom_divisor = 77; - priv->force_baud = 38400; -} - -/* Setup for the HE-TIRA1 device, which requires hardwired - * baudrate (38400 gets mapped to 100000) and RTS-CTS enabled. */ - -static void ftdi_HE_TIRA1_setup(struct ftdi_private *priv) -{ - dbg("%s", __func__); - - priv->flags |= ASYNC_SPD_CUST; - priv->custom_divisor = 240; - priv->force_baud = 38400; - priv->force_rtscts = 1; -} - -/* - * Module parameter to control latency timer for NDI FTDI-based USB devices. - * If this value is not set in /etc/modprobe.d/ its value will be set - * to 1ms. - */ -static int ndi_latency_timer = 1; - -/* Setup for the NDI FTDI-based USB devices, which requires hardwired - * baudrate (19200 gets mapped to 1200000). - * - * Called from usbserial:serial_probe. - */ -static int ftdi_NDI_device_setup(struct usb_serial *serial) -{ - struct usb_device *udev = serial->dev; - int latency = ndi_latency_timer; - - if (latency == 0) - latency = 1; - if (latency > 99) - latency = 99; - - dbg("%s setting NDI device latency to %d", __func__, latency); - dev_info(&udev->dev, "NDI device with a latency value of %d", latency); - - /* FIXME: errors are not returned */ - usb_control_msg(udev, usb_sndctrlpipe(udev, 0), - FTDI_SIO_SET_LATENCY_TIMER_REQUEST, - FTDI_SIO_SET_LATENCY_TIMER_REQUEST_TYPE, - latency, 0, NULL, 0, WDR_TIMEOUT); - return 0; -} - -/* - * First port on JTAG adaptors such as Olimex arm-usb-ocd or the FIC/OpenMoko - * Neo1973 Debug Board is reserved for JTAG interface and can be accessed from - * userspace using openocd. - */ -static int ftdi_jtag_probe(struct usb_serial *serial) -{ - struct usb_device *udev = serial->dev; - struct usb_interface *interface = serial->interface; - - dbg("%s", __func__); - - if (interface == udev->actconfig->interface[0]) { - dev_info(&udev->dev, - "Ignoring serial port reserved for JTAG\n"); - return -ENODEV; - } - - return 0; -} - -static int ftdi_8u2232c_probe(struct usb_serial *serial) -{ - struct usb_device *udev = serial->dev; - - dbg("%s", __func__); - - if ((udev->manufacturer && !strcmp(udev->manufacturer, "CALAO Systems")) || - (udev->product && !strcmp(udev->product, "BeagleBone/XDS100"))) - return ftdi_jtag_probe(serial); - - return 0; -} - -/* - * First and second port on STMCLiteadaptors is reserved for JTAG interface - * and the forth port for pio - */ -static int ftdi_stmclite_probe(struct usb_serial *serial) -{ - struct usb_device *udev = serial->dev; - struct usb_interface *interface = serial->interface; - - dbg("%s", __func__); - - if (interface == udev->actconfig->interface[2]) - return 0; - - dev_info(&udev->dev, "Ignoring serial port reserved for JTAG\n"); - - return -ENODEV; -} - -/* - * The Matrix Orbital VK204-25-USB has an invalid IN endpoint. - * We have to correct it if we want to read from it. - */ -static int ftdi_mtxorb_hack_setup(struct usb_serial *serial) -{ - struct usb_host_endpoint *ep = serial->dev->ep_in[1]; - struct usb_endpoint_descriptor *ep_desc = &ep->desc; - - if (ep->enabled && ep_desc->wMaxPacketSize == 0) { - ep_desc->wMaxPacketSize = cpu_to_le16(0x40); - dev_info(&serial->dev->dev, - "Fixing invalid wMaxPacketSize on read pipe\n"); - } - - return 0; -} - -static void ftdi_sio_priv_release(struct kref *k) -{ - struct ftdi_private *priv = container_of(k, struct ftdi_private, kref); - - kfree(priv); -} - -static int ftdi_sio_port_remove(struct usb_serial_port *port) -{ - struct ftdi_private *priv = usb_get_serial_port_data(port); - - dbg("%s", __func__); - - priv->dev_gone = true; - wake_up_interruptible_all(&priv->delta_msr_wait); - - remove_sysfs_attrs(port); - - kref_put(&priv->kref, ftdi_sio_priv_release); - - return 0; -} - -static int ftdi_open(struct tty_struct *tty, struct usb_serial_port *port) -{ - struct ktermios dummy; - struct usb_device *dev = port->serial->dev; - struct ftdi_private *priv = usb_get_serial_port_data(port); - int result; - - dbg("%s", __func__); - - /* No error checking for this (will get errors later anyway) */ - /* See ftdi_sio.h for description of what is reset */ - usb_control_msg(dev, usb_sndctrlpipe(dev, 0), - FTDI_SIO_RESET_REQUEST, FTDI_SIO_RESET_REQUEST_TYPE, - FTDI_SIO_RESET_SIO, - priv->interface, NULL, 0, WDR_TIMEOUT); - - /* Termios defaults are set by usb_serial_init. We don't change - port->tty->termios - this would lose speed settings, etc. - This is same behaviour as serial.c/rs_open() - Kuba */ - - /* ftdi_set_termios will send usb control messages */ - if (tty) { - memset(&dummy, 0, sizeof(dummy)); - ftdi_set_termios(tty, port, &dummy); - } - - /* Start reading from the device */ - result = usb_serial_generic_open(tty, port); - if (!result) - kref_get(&priv->kref); - - return result; -} - -static void ftdi_dtr_rts(struct usb_serial_port *port, int on) -{ - struct ftdi_private *priv = usb_get_serial_port_data(port); - - mutex_lock(&port->serial->disc_mutex); - if (!port->serial->disconnected) { - /* Disable flow control */ - if (!on && usb_control_msg(port->serial->dev, - usb_sndctrlpipe(port->serial->dev, 0), - FTDI_SIO_SET_FLOW_CTRL_REQUEST, - FTDI_SIO_SET_FLOW_CTRL_REQUEST_TYPE, - 0, priv->interface, NULL, 0, - WDR_TIMEOUT) < 0) { - dev_err(&port->dev, "error from flowcontrol urb\n"); - } - /* drop RTS and DTR */ - if (on) - set_mctrl(port, TIOCM_DTR | TIOCM_RTS); - else - clear_mctrl(port, TIOCM_DTR | TIOCM_RTS); - } - mutex_unlock(&port->serial->disc_mutex); -} - -/* - * usbserial:__serial_close only calls ftdi_close if the point is open - * - * This only gets called when it is the last close - */ -static void ftdi_close(struct usb_serial_port *port) -{ - struct ftdi_private *priv = usb_get_serial_port_data(port); - - dbg("%s", __func__); - - usb_serial_generic_close(port); - kref_put(&priv->kref, ftdi_sio_priv_release); -} - -/* The SIO requires the first byte to have: - * B0 1 - * B1 0 - * B2..7 length of message excluding byte 0 - * - * The new devices do not require this byte - */ -static int ftdi_prepare_write_buffer(struct usb_serial_port *port, - void *dest, size_t size) -{ - struct ftdi_private *priv; - int count; - unsigned long flags; - - priv = usb_get_serial_port_data(port); - - if (priv->chip_type == SIO) { - unsigned char *buffer = dest; - int i, len, c; - - count = 0; - spin_lock_irqsave(&port->lock, flags); - for (i = 0; i < size - 1; i += priv->max_packet_size) { - len = min_t(int, size - i, priv->max_packet_size) - 1; - c = kfifo_out(&port->write_fifo, &buffer[i + 1], len); - if (!c) - break; - priv->icount.tx += c; - buffer[i] = (c << 2) + 1; - count += c + 1; - } - spin_unlock_irqrestore(&port->lock, flags); - } else { - count = kfifo_out_locked(&port->write_fifo, dest, size, - &port->lock); - priv->icount.tx += count; - } - - return count; -} - -#define FTDI_RS_ERR_MASK (FTDI_RS_BI | FTDI_RS_PE | FTDI_RS_FE | FTDI_RS_OE) - -static int ftdi_process_packet(struct tty_struct *tty, - struct usb_serial_port *port, struct ftdi_private *priv, - char *packet, int len) -{ - int i; - char status; - char flag; - char *ch; - - dbg("%s - port %d", __func__, port->number); - - if (len < 2) { - dbg("malformed packet"); - return 0; - } - - /* Compare new line status to the old one, signal if different/ - N.B. packet may be processed more than once, but differences - are only processed once. */ - status = packet[0] & FTDI_STATUS_B0_MASK; - if (status != priv->prev_status) { - char diff_status = status ^ priv->prev_status; - - if (diff_status & FTDI_RS0_CTS) - priv->icount.cts++; - if (diff_status & FTDI_RS0_DSR) - priv->icount.dsr++; - if (diff_status & FTDI_RS0_RI) - priv->icount.rng++; - if (diff_status & FTDI_RS0_RLSD) - priv->icount.dcd++; - - wake_up_interruptible_all(&priv->delta_msr_wait); - priv->prev_status = status; - } - - flag = TTY_NORMAL; - if (packet[1] & FTDI_RS_ERR_MASK) { - /* Break takes precedence over parity, which takes precedence - * over framing errors */ - if (packet[1] & FTDI_RS_BI) { - flag = TTY_BREAK; - priv->icount.brk++; - usb_serial_handle_break(port); - } else if (packet[1] & FTDI_RS_PE) { - flag = TTY_PARITY; - priv->icount.parity++; - } else if (packet[1] & FTDI_RS_FE) { - flag = TTY_FRAME; - priv->icount.frame++; - } - /* Overrun is special, not associated with a char */ - if (packet[1] & FTDI_RS_OE) { - priv->icount.overrun++; - tty_insert_flip_char(tty, 0, TTY_OVERRUN); - } - } - - /* save if the transmitter is empty or not */ - if (packet[1] & FTDI_RS_TEMT) - priv->transmit_empty = 1; - else - priv->transmit_empty = 0; - - len -= 2; - if (!len) - return 0; /* status only */ - priv->icount.rx += len; - ch = packet + 2; - - if (port->port.console && port->sysrq) { - for (i = 0; i < len; i++, ch++) { - if (!usb_serial_handle_sysrq_char(port, *ch)) - tty_insert_flip_char(tty, *ch, flag); - } - } else { - tty_insert_flip_string_fixed_flag(tty, ch, flag, len); - } - - return len; -} - -static void ftdi_process_read_urb(struct urb *urb) -{ - struct usb_serial_port *port = urb->context; - struct tty_struct *tty; - struct ftdi_private *priv = usb_get_serial_port_data(port); - char *data = (char *)urb->transfer_buffer; - int i; - int len; - int count = 0; - - tty = tty_port_tty_get(&port->port); - if (!tty) - return; - - for (i = 0; i < urb->actual_length; i += priv->max_packet_size) { - len = min_t(int, urb->actual_length - i, priv->max_packet_size); - count += ftdi_process_packet(tty, port, priv, &data[i], len); - } - - if (count) - tty_flip_buffer_push(tty); - tty_kref_put(tty); -} - -static void ftdi_break_ctl(struct tty_struct *tty, int break_state) -{ - struct usb_serial_port *port = tty->driver_data; - struct ftdi_private *priv = usb_get_serial_port_data(port); - __u16 urb_value; - - /* break_state = -1 to turn on break, and 0 to turn off break */ - /* see drivers/char/tty_io.c to see it used */ - /* last_set_data_urb_value NEVER has the break bit set in it */ - - if (break_state) - urb_value = priv->last_set_data_urb_value | FTDI_SIO_SET_BREAK; - else - urb_value = priv->last_set_data_urb_value; - - if (usb_control_msg(port->serial->dev, - usb_sndctrlpipe(port->serial->dev, 0), - FTDI_SIO_SET_DATA_REQUEST, - FTDI_SIO_SET_DATA_REQUEST_TYPE, - urb_value , priv->interface, - NULL, 0, WDR_TIMEOUT) < 0) { - dev_err(&port->dev, "%s FAILED to enable/disable break state " - "(state was %d)\n", __func__, break_state); - } - - dbg("%s break state is %d - urb is %d", __func__, - break_state, urb_value); - -} - -/* old_termios contains the original termios settings and tty->termios contains - * the new setting to be used - * WARNING: set_termios calls this with old_termios in kernel space - */ -static void ftdi_set_termios(struct tty_struct *tty, - struct usb_serial_port *port, struct ktermios *old_termios) -{ - struct usb_device *dev = port->serial->dev; - struct ftdi_private *priv = usb_get_serial_port_data(port); - struct ktermios *termios = tty->termios; - unsigned int cflag = termios->c_cflag; - __u16 urb_value; /* will hold the new flags */ - - /* Added for xon/xoff support */ - unsigned int iflag = termios->c_iflag; - unsigned char vstop; - unsigned char vstart; - - dbg("%s", __func__); - - /* Force baud rate if this device requires it, unless it is set to - B0. */ - if (priv->force_baud && ((termios->c_cflag & CBAUD) != B0)) { - dbg("%s: forcing baud rate for this device", __func__); - tty_encode_baud_rate(tty, priv->force_baud, - priv->force_baud); - } - - /* Force RTS-CTS if this device requires it. */ - if (priv->force_rtscts) { - dbg("%s: forcing rtscts for this device", __func__); - termios->c_cflag |= CRTSCTS; - } - - cflag = termios->c_cflag; - - if (old_termios == 0) - goto no_skip; - - if (old_termios->c_cflag == termios->c_cflag - && old_termios->c_ispeed == termios->c_ispeed - && old_termios->c_ospeed == termios->c_ospeed) - goto no_c_cflag_changes; - - /* NOTE These routines can get interrupted by - ftdi_sio_read_bulk_callback - need to examine what this means - - don't see any problems yet */ - - if ((old_termios->c_cflag & (CSIZE|PARODD|PARENB|CMSPAR|CSTOPB)) == - (termios->c_cflag & (CSIZE|PARODD|PARENB|CMSPAR|CSTOPB))) - goto no_data_parity_stop_changes; - -no_skip: - /* Set number of data bits, parity, stop bits */ - - urb_value = 0; - urb_value |= (cflag & CSTOPB ? FTDI_SIO_SET_DATA_STOP_BITS_2 : - FTDI_SIO_SET_DATA_STOP_BITS_1); - if (cflag & PARENB) { - if (cflag & CMSPAR) - urb_value |= cflag & PARODD ? - FTDI_SIO_SET_DATA_PARITY_MARK : - FTDI_SIO_SET_DATA_PARITY_SPACE; - else - urb_value |= cflag & PARODD ? - FTDI_SIO_SET_DATA_PARITY_ODD : - FTDI_SIO_SET_DATA_PARITY_EVEN; - } else { - urb_value |= FTDI_SIO_SET_DATA_PARITY_NONE; - } - if (cflag & CSIZE) { - switch (cflag & CSIZE) { - case CS7: urb_value |= 7; dbg("Setting CS7"); break; - case CS8: urb_value |= 8; dbg("Setting CS8"); break; - default: - dev_err(&port->dev, "CSIZE was set but not CS7-CS8\n"); - } - } - - /* This is needed by the break command since it uses the same command - - but is or'ed with this value */ - priv->last_set_data_urb_value = urb_value; - - if (usb_control_msg(dev, usb_sndctrlpipe(dev, 0), - FTDI_SIO_SET_DATA_REQUEST, - FTDI_SIO_SET_DATA_REQUEST_TYPE, - urb_value , priv->interface, - NULL, 0, WDR_SHORT_TIMEOUT) < 0) { - dev_err(&port->dev, "%s FAILED to set " - "databits/stopbits/parity\n", __func__); - } - - /* Now do the baudrate */ -no_data_parity_stop_changes: - if ((cflag & CBAUD) == B0) { - /* Disable flow control */ - if (usb_control_msg(dev, usb_sndctrlpipe(dev, 0), - FTDI_SIO_SET_FLOW_CTRL_REQUEST, - FTDI_SIO_SET_FLOW_CTRL_REQUEST_TYPE, - 0, priv->interface, - NULL, 0, WDR_TIMEOUT) < 0) { - dev_err(&port->dev, - "%s error from disable flowcontrol urb\n", - __func__); - } - /* Drop RTS and DTR */ - clear_mctrl(port, TIOCM_DTR | TIOCM_RTS); - } else { - /* set the baudrate determined before */ - mutex_lock(&priv->cfg_lock); - if (change_speed(tty, port)) - dev_err(&port->dev, "%s urb failed to set baudrate\n", - __func__); - mutex_unlock(&priv->cfg_lock); - /* Ensure RTS and DTR are raised when baudrate changed from 0 */ - if (!old_termios || (old_termios->c_cflag & CBAUD) == B0) - set_mctrl(port, TIOCM_DTR | TIOCM_RTS); - } - - /* Set flow control */ - /* Note device also supports DTR/CD (ugh) and Xon/Xoff in hardware */ -no_c_cflag_changes: - if (cflag & CRTSCTS) { - dbg("%s Setting to CRTSCTS flow control", __func__); - if (usb_control_msg(dev, - usb_sndctrlpipe(dev, 0), - FTDI_SIO_SET_FLOW_CTRL_REQUEST, - FTDI_SIO_SET_FLOW_CTRL_REQUEST_TYPE, - 0 , (FTDI_SIO_RTS_CTS_HS | priv->interface), - NULL, 0, WDR_TIMEOUT) < 0) { - dev_err(&port->dev, - "urb failed to set to rts/cts flow control\n"); - } - - } else { - /* - * Xon/Xoff code - * - * Check the IXOFF status in the iflag component of the - * termios structure. If IXOFF is not set, the pre-xon/xoff - * code is executed. - */ - if (iflag & IXOFF) { - dbg("%s request to enable xonxoff iflag=%04x", - __func__, iflag); - /* Try to enable the XON/XOFF on the ftdi_sio - * Set the vstart and vstop -- could have been done up - * above where a lot of other dereferencing is done but - * that would be very inefficient as vstart and vstop - * are not always needed. - */ - vstart = termios->c_cc[VSTART]; - vstop = termios->c_cc[VSTOP]; - urb_value = (vstop << 8) | (vstart); - - if (usb_control_msg(dev, - usb_sndctrlpipe(dev, 0), - FTDI_SIO_SET_FLOW_CTRL_REQUEST, - FTDI_SIO_SET_FLOW_CTRL_REQUEST_TYPE, - urb_value , (FTDI_SIO_XON_XOFF_HS - | priv->interface), - NULL, 0, WDR_TIMEOUT) < 0) { - dev_err(&port->dev, "urb failed to set to " - "xon/xoff flow control\n"); - } - } else { - /* else clause to only run if cflag ! CRTSCTS and iflag - * ! XOFF. CHECKME Assuming XON/XOFF handled by tty - * stack - not by device */ - dbg("%s Turning off hardware flow control", __func__); - if (usb_control_msg(dev, - usb_sndctrlpipe(dev, 0), - FTDI_SIO_SET_FLOW_CTRL_REQUEST, - FTDI_SIO_SET_FLOW_CTRL_REQUEST_TYPE, - 0, priv->interface, - NULL, 0, WDR_TIMEOUT) < 0) { - dev_err(&port->dev, - "urb failed to clear flow control\n"); - } - } - - } -} - -static int ftdi_tiocmget(struct tty_struct *tty) -{ - struct usb_serial_port *port = tty->driver_data; - struct ftdi_private *priv = usb_get_serial_port_data(port); - unsigned char *buf; - int len; - int ret; - - dbg("%s TIOCMGET", __func__); - - buf = kmalloc(2, GFP_KERNEL); - if (!buf) - return -ENOMEM; - /* - * The 8U232AM returns a two byte value (the SIO a 1 byte value) in - * the same format as the data returned from the in point. - */ - switch (priv->chip_type) { - case SIO: - len = 1; - break; - case FT8U232AM: - case FT232BM: - case FT2232C: - case FT232RL: - case FT2232H: - case FT4232H: - case FT232H: - case FTX: - len = 2; - break; - default: - ret = -EFAULT; - goto out; - } - - ret = usb_control_msg(port->serial->dev, - usb_rcvctrlpipe(port->serial->dev, 0), - FTDI_SIO_GET_MODEM_STATUS_REQUEST, - FTDI_SIO_GET_MODEM_STATUS_REQUEST_TYPE, - 0, priv->interface, - buf, len, WDR_TIMEOUT); - if (ret < 0) - goto out; - - ret = (buf[0] & FTDI_SIO_DSR_MASK ? TIOCM_DSR : 0) | - (buf[0] & FTDI_SIO_CTS_MASK ? TIOCM_CTS : 0) | - (buf[0] & FTDI_SIO_RI_MASK ? TIOCM_RI : 0) | - (buf[0] & FTDI_SIO_RLSD_MASK ? TIOCM_CD : 0) | - priv->last_dtr_rts; -out: - kfree(buf); - return ret; -} - -static int ftdi_tiocmset(struct tty_struct *tty, - unsigned int set, unsigned int clear) -{ - struct usb_serial_port *port = tty->driver_data; - dbg("%s TIOCMSET", __func__); - return update_mctrl(port, set, clear); -} - -static int ftdi_get_icount(struct tty_struct *tty, - struct serial_icounter_struct *icount) -{ - struct usb_serial_port *port = tty->driver_data; - struct ftdi_private *priv = usb_get_serial_port_data(port); - struct async_icount *ic = &priv->icount; - - icount->cts = ic->cts; - icount->dsr = ic->dsr; - icount->rng = ic->rng; - icount->dcd = ic->dcd; - icount->tx = ic->tx; - icount->rx = ic->rx; - icount->frame = ic->frame; - icount->parity = ic->parity; - icount->overrun = ic->overrun; - icount->brk = ic->brk; - icount->buf_overrun = ic->buf_overrun; - return 0; -} - -static int ftdi_ioctl(struct tty_struct *tty, - unsigned int cmd, unsigned long arg) -{ - struct usb_serial_port *port = tty->driver_data; - struct ftdi_private *priv = usb_get_serial_port_data(port); - struct async_icount cnow; - struct async_icount cprev; - - dbg("%s cmd 0x%04x", __func__, cmd); - - /* Based on code from acm.c and others */ - switch (cmd) { - - case TIOCGSERIAL: /* gets serial port data */ - return get_serial_info(port, - (struct serial_struct __user *) arg); - - case TIOCSSERIAL: /* sets serial port data */ - return set_serial_info(tty, port, - (struct serial_struct __user *) arg); - - /* - * Wait for any of the 4 modem inputs (DCD,RI,DSR,CTS) to change - * - mask passed in arg for lines of interest - * (use |'ed TIOCM_RNG/DSR/CD/CTS for masking) - * Caller should use TIOCGICOUNT to see which one it was. - * - * This code is borrowed from linux/drivers/char/serial.c - */ - case TIOCMIWAIT: - cprev = priv->icount; - while (!priv->dev_gone) { - interruptible_sleep_on(&priv->delta_msr_wait); - /* see if a signal did it */ - if (signal_pending(current)) - return -ERESTARTSYS; - cnow = priv->icount; - if (((arg & TIOCM_RNG) && (cnow.rng != cprev.rng)) || - ((arg & TIOCM_DSR) && (cnow.dsr != cprev.dsr)) || - ((arg & TIOCM_CD) && (cnow.dcd != cprev.dcd)) || - ((arg & TIOCM_CTS) && (cnow.cts != cprev.cts))) { - return 0; - } - cprev = cnow; - } - return -EIO; - break; - case TIOCSERGETLSR: - return get_lsr_info(port, (struct serial_struct __user *)arg); - break; - default: - break; - } - /* This is not necessarily an error - turns out the higher layers - * will do some ioctls themselves (see comment above) - */ - dbg("%s arg not supported - it was 0x%04x - check /usr/include/asm/ioctls.h", __func__, cmd); - return -ENOIOCTLCMD; -} - -static int __init ftdi_init(void) -{ - int retval; - - dbg("%s", __func__); - if (vendor > 0 && product > 0) { - /* Add user specified VID/PID to reserved element of table. */ - int i; - for (i = 0; id_table_combined[i].idVendor; i++) - ; - id_table_combined[i].match_flags = USB_DEVICE_ID_MATCH_DEVICE; - id_table_combined[i].idVendor = vendor; - id_table_combined[i].idProduct = product; - } - retval = usb_serial_register_drivers(&ftdi_driver, serial_drivers); - if (retval == 0) - printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ":" - DRIVER_DESC "\n"); - return retval; -} - -static void __exit ftdi_exit(void) -{ - dbg("%s", __func__); - - usb_serial_deregister_drivers(&ftdi_driver, serial_drivers); -} - - -module_init(ftdi_init); -module_exit(ftdi_exit); - -MODULE_AUTHOR(DRIVER_AUTHOR); -MODULE_DESCRIPTION(DRIVER_DESC); -MODULE_LICENSE("GPL"); - -module_param(debug, bool, S_IRUGO | S_IWUSR); -MODULE_PARM_DESC(debug, "Debug enabled or not"); -module_param(vendor, ushort, 0); -MODULE_PARM_DESC(vendor, "User specified vendor ID (default=" - __MODULE_STRING(FTDI_VID)")"); -module_param(product, ushort, 0); -MODULE_PARM_DESC(product, "User specified product ID"); - -module_param(ndi_latency_timer, int, S_IRUGO | S_IWUSR); -MODULE_PARM_DESC(ndi_latency_timer, "NDI device latency timer override"); diff --git a/ANDROID_3.4.5/drivers/usb/serial/ftdi_sio.h b/ANDROID_3.4.5/drivers/usb/serial/ftdi_sio.h deleted file mode 100644 index ed58c6fa..00000000 --- a/ANDROID_3.4.5/drivers/usb/serial/ftdi_sio.h +++ /dev/null @@ -1,564 +0,0 @@ -/* - * Driver definitions for the FTDI USB Single Port Serial Converter - - * known as FTDI_SIO (Serial Input/Output application of the chipset) - * - * For USB vendor/product IDs (VID/PID), please see ftdi_sio_ids.h - * - * - * The example I have is known as the USC-1000 which is available from - * http://www.dse.co.nz - cat no XH4214 It looks similar to this: - * http://www.dansdata.com/usbser.htm but I can't be sure There are other - * USC-1000s which don't look like my device though so beware! - * - * The device is based on the FTDI FT8U100AX chip. It has a DB25 on one side, - * USB on the other. - * - * Thanx to FTDI (http://www.ftdichip.com) for so kindly providing details - * of the protocol required to talk to the device and ongoing assistence - * during development. - * - * Bill Ryder - bryder@sgi.com formerly of Silicon Graphics, Inc.- wrote the - * FTDI_SIO implementation. - * - */ - -/* Commands */ -#define FTDI_SIO_RESET 0 /* Reset the port */ -#define FTDI_SIO_MODEM_CTRL 1 /* Set the modem control register */ -#define FTDI_SIO_SET_FLOW_CTRL 2 /* Set flow control register */ -#define FTDI_SIO_SET_BAUD_RATE 3 /* Set baud rate */ -#define FTDI_SIO_SET_DATA 4 /* Set the data characteristics of - the port */ -#define FTDI_SIO_GET_MODEM_STATUS 5 /* Retrieve current value of modem - status register */ -#define FTDI_SIO_SET_EVENT_CHAR 6 /* Set the event character */ -#define FTDI_SIO_SET_ERROR_CHAR 7 /* Set the error character */ -#define FTDI_SIO_SET_LATENCY_TIMER 9 /* Set the latency timer */ -#define FTDI_SIO_GET_LATENCY_TIMER 10 /* Get the latency timer */ - -/* Interface indices for FT2232, FT2232H and FT4232H devices */ -#define INTERFACE_A 1 -#define INTERFACE_B 2 -#define INTERFACE_C 3 -#define INTERFACE_D 4 - - -/* - * BmRequestType: 1100 0000b - * bRequest: FTDI_E2_READ - * wValue: 0 - * wIndex: Address of word to read - * wLength: 2 - * Data: Will return a word of data from E2Address - * - */ - -/* Port Identifier Table */ -#define PIT_DEFAULT 0 /* SIOA */ -#define PIT_SIOA 1 /* SIOA */ -/* The device this driver is tested with one has only one port */ -#define PIT_SIOB 2 /* SIOB */ -#define PIT_PARALLEL 3 /* Parallel */ - -/* FTDI_SIO_RESET */ -#define FTDI_SIO_RESET_REQUEST FTDI_SIO_RESET -#define FTDI_SIO_RESET_REQUEST_TYPE 0x40 -#define FTDI_SIO_RESET_SIO 0 -#define FTDI_SIO_RESET_PURGE_RX 1 -#define FTDI_SIO_RESET_PURGE_TX 2 - -/* - * BmRequestType: 0100 0000B - * bRequest: FTDI_SIO_RESET - * wValue: Control Value - * 0 = Reset SIO - * 1 = Purge RX buffer - * 2 = Purge TX buffer - * wIndex: Port - * wLength: 0 - * Data: None - * - * The Reset SIO command has this effect: - * - * Sets flow control set to 'none' - * Event char = $0D - * Event trigger = disabled - * Purge RX buffer - * Purge TX buffer - * Clear DTR - * Clear RTS - * baud and data format not reset - * - * The Purge RX and TX buffer commands affect nothing except the buffers - * - */ - -/* FTDI_SIO_SET_BAUDRATE */ -#define FTDI_SIO_SET_BAUDRATE_REQUEST_TYPE 0x40 -#define FTDI_SIO_SET_BAUDRATE_REQUEST 3 - -/* - * BmRequestType: 0100 0000B - * bRequest: FTDI_SIO_SET_BAUDRATE - * wValue: BaudDivisor value - see below - * wIndex: Port - * wLength: 0 - * Data: None - * The BaudDivisor values are calculated as follows: - * - BaseClock is either 12000000 or 48000000 depending on the device. - * FIXME: I wish I knew how to detect old chips to select proper base clock! - * - BaudDivisor is a fixed point number encoded in a funny way. - * (--WRONG WAY OF THINKING--) - * BaudDivisor is a fixed point number encoded with following bit weighs: - * (-2)(-1)(13..0). It is a radical with a denominator of 4, so values - * end with 0.0 (00...), 0.25 (10...), 0.5 (01...), and 0.75 (11...). - * (--THE REALITY--) - * The both-bits-set has quite different meaning from 0.75 - the chip - * designers have decided it to mean 0.125 instead of 0.75. - * This info looked up in FTDI application note "FT8U232 DEVICES \ Data Rates - * and Flow Control Consideration for USB to RS232". - * - BaudDivisor = (BaseClock / 16) / BaudRate, where the (=) operation should - * automagically re-encode the resulting value to take fractions into - * consideration. - * As all values are integers, some bit twiddling is in order: - * BaudDivisor = (BaseClock / 16 / BaudRate) | - * (((BaseClock / 2 / BaudRate) & 4) ? 0x4000 // 0.5 - * : ((BaseClock / 2 / BaudRate) & 2) ? 0x8000 // 0.25 - * : ((BaseClock / 2 / BaudRate) & 1) ? 0xc000 // 0.125 - * : 0) - * - * For the FT232BM, a 17th divisor bit was introduced to encode the multiples - * of 0.125 missing from the FT8U232AM. Bits 16 to 14 are coded as follows - * (the first four codes are the same as for the FT8U232AM, where bit 16 is - * always 0): - * 000 - add .000 to divisor - * 001 - add .500 to divisor - * 010 - add .250 to divisor - * 011 - add .125 to divisor - * 100 - add .375 to divisor - * 101 - add .625 to divisor - * 110 - add .750 to divisor - * 111 - add .875 to divisor - * Bits 15 to 0 of the 17-bit divisor are placed in the urb value. Bit 16 is - * placed in bit 0 of the urb index. - * - * Note that there are a couple of special cases to support the highest baud - * rates. If the calculated divisor value is 1, this needs to be replaced with - * 0. Additionally for the FT232BM, if the calculated divisor value is 0x4001 - * (1.5), this needs to be replaced with 0x0001 (1) (but this divisor value is - * not supported by the FT8U232AM). - */ - -enum ftdi_chip_type { - SIO = 1, - FT8U232AM = 2, - FT232BM = 3, - FT2232C = 4, - FT232RL = 5, - FT2232H = 6, - FT4232H = 7, - FT232H = 8, - FTX = 9, -}; - -enum ftdi_sio_baudrate { - ftdi_sio_b300 = 0, - ftdi_sio_b600 = 1, - ftdi_sio_b1200 = 2, - ftdi_sio_b2400 = 3, - ftdi_sio_b4800 = 4, - ftdi_sio_b9600 = 5, - ftdi_sio_b19200 = 6, - ftdi_sio_b38400 = 7, - ftdi_sio_b57600 = 8, - ftdi_sio_b115200 = 9 -}; - -/* - * The ftdi_8U232AM_xxMHz_byyy constants have been removed. The encoded divisor - * values are calculated internally. - */ -#define FTDI_SIO_SET_DATA_REQUEST FTDI_SIO_SET_DATA -#define FTDI_SIO_SET_DATA_REQUEST_TYPE 0x40 -#define FTDI_SIO_SET_DATA_PARITY_NONE (0x0 << 8) -#define FTDI_SIO_SET_DATA_PARITY_ODD (0x1 << 8) -#define FTDI_SIO_SET_DATA_PARITY_EVEN (0x2 << 8) -#define FTDI_SIO_SET_DATA_PARITY_MARK (0x3 << 8) -#define FTDI_SIO_SET_DATA_PARITY_SPACE (0x4 << 8) -#define FTDI_SIO_SET_DATA_STOP_BITS_1 (0x0 << 11) -#define FTDI_SIO_SET_DATA_STOP_BITS_15 (0x1 << 11) -#define FTDI_SIO_SET_DATA_STOP_BITS_2 (0x2 << 11) -#define FTDI_SIO_SET_BREAK (0x1 << 14) -/* FTDI_SIO_SET_DATA */ - -/* - * BmRequestType: 0100 0000B - * bRequest: FTDI_SIO_SET_DATA - * wValue: Data characteristics (see below) - * wIndex: Port - * wLength: 0 - * Data: No - * - * Data characteristics - * - * B0..7 Number of data bits - * B8..10 Parity - * 0 = None - * 1 = Odd - * 2 = Even - * 3 = Mark - * 4 = Space - * B11..13 Stop Bits - * 0 = 1 - * 1 = 1.5 - * 2 = 2 - * B14 - * 1 = TX ON (break) - * 0 = TX OFF (normal state) - * B15 Reserved - * - */ - - - -/* FTDI_SIO_MODEM_CTRL */ -#define FTDI_SIO_SET_MODEM_CTRL_REQUEST_TYPE 0x40 -#define FTDI_SIO_SET_MODEM_CTRL_REQUEST FTDI_SIO_MODEM_CTRL - -/* - * BmRequestType: 0100 0000B - * bRequest: FTDI_SIO_MODEM_CTRL - * wValue: ControlValue (see below) - * wIndex: Port - * wLength: 0 - * Data: None - * - * NOTE: If the device is in RTS/CTS flow control, the RTS set by this - * command will be IGNORED without an error being returned - * Also - you can not set DTR and RTS with one control message - */ - -#define FTDI_SIO_SET_DTR_MASK 0x1 -#define FTDI_SIO_SET_DTR_HIGH (1 | (FTDI_SIO_SET_DTR_MASK << 8)) -#define FTDI_SIO_SET_DTR_LOW (0 | (FTDI_SIO_SET_DTR_MASK << 8)) -#define FTDI_SIO_SET_RTS_MASK 0x2 -#define FTDI_SIO_SET_RTS_HIGH (2 | (FTDI_SIO_SET_RTS_MASK << 8)) -#define FTDI_SIO_SET_RTS_LOW (0 | (FTDI_SIO_SET_RTS_MASK << 8)) - -/* - * ControlValue - * B0 DTR state - * 0 = reset - * 1 = set - * B1 RTS state - * 0 = reset - * 1 = set - * B2..7 Reserved - * B8 DTR state enable - * 0 = ignore - * 1 = use DTR state - * B9 RTS state enable - * 0 = ignore - * 1 = use RTS state - * B10..15 Reserved - */ - -/* FTDI_SIO_SET_FLOW_CTRL */ -#define FTDI_SIO_SET_FLOW_CTRL_REQUEST_TYPE 0x40 -#define FTDI_SIO_SET_FLOW_CTRL_REQUEST FTDI_SIO_SET_FLOW_CTRL -#define FTDI_SIO_DISABLE_FLOW_CTRL 0x0 -#define FTDI_SIO_RTS_CTS_HS (0x1 << 8) -#define FTDI_SIO_DTR_DSR_HS (0x2 << 8) -#define FTDI_SIO_XON_XOFF_HS (0x4 << 8) -/* - * BmRequestType: 0100 0000b - * bRequest: FTDI_SIO_SET_FLOW_CTRL - * wValue: Xoff/Xon - * wIndex: Protocol/Port - hIndex is protocol / lIndex is port - * wLength: 0 - * Data: None - * - * hIndex protocol is: - * B0 Output handshaking using RTS/CTS - * 0 = disabled - * 1 = enabled - * B1 Output handshaking using DTR/DSR - * 0 = disabled - * 1 = enabled - * B2 Xon/Xoff handshaking - * 0 = disabled - * 1 = enabled - * - * A value of zero in the hIndex field disables handshaking - * - * If Xon/Xoff handshaking is specified, the hValue field should contain the - * XOFF character and the lValue field contains the XON character. - */ - -/* - * FTDI_SIO_GET_LATENCY_TIMER - * - * Set the timeout interval. The FTDI collects data from the slave - * device, transmitting it to the host when either A) 62 bytes are - * received, or B) the timeout interval has elapsed and the buffer - * contains at least 1 byte. Setting this value to a small number - * can dramatically improve performance for applications which send - * small packets, since the default value is 16ms. - */ -#define FTDI_SIO_GET_LATENCY_TIMER_REQUEST FTDI_SIO_GET_LATENCY_TIMER -#define FTDI_SIO_GET_LATENCY_TIMER_REQUEST_TYPE 0xC0 - -/* - * BmRequestType: 1100 0000b - * bRequest: FTDI_SIO_GET_LATENCY_TIMER - * wValue: 0 - * wIndex: Port - * wLength: 0 - * Data: latency (on return) - */ - -/* - * FTDI_SIO_SET_LATENCY_TIMER - * - * Set the timeout interval. The FTDI collects data from the slave - * device, transmitting it to the host when either A) 62 bytes are - * received, or B) the timeout interval has elapsed and the buffer - * contains at least 1 byte. Setting this value to a small number - * can dramatically improve performance for applications which send - * small packets, since the default value is 16ms. - */ -#define FTDI_SIO_SET_LATENCY_TIMER_REQUEST FTDI_SIO_SET_LATENCY_TIMER -#define FTDI_SIO_SET_LATENCY_TIMER_REQUEST_TYPE 0x40 - -/* - * BmRequestType: 0100 0000b - * bRequest: FTDI_SIO_SET_LATENCY_TIMER - * wValue: Latency (milliseconds) - * wIndex: Port - * wLength: 0 - * Data: None - * - * wValue: - * B0..7 Latency timer - * B8..15 0 - * - */ - -/* - * FTDI_SIO_SET_EVENT_CHAR - * - * Set the special event character for the specified communications port. - * If the device sees this character it will immediately return the - * data read so far - rather than wait 40ms or until 62 bytes are read - * which is what normally happens. - */ - - -#define FTDI_SIO_SET_EVENT_CHAR_REQUEST FTDI_SIO_SET_EVENT_CHAR -#define FTDI_SIO_SET_EVENT_CHAR_REQUEST_TYPE 0x40 - - -/* - * BmRequestType: 0100 0000b - * bRequest: FTDI_SIO_SET_EVENT_CHAR - * wValue: EventChar - * wIndex: Port - * wLength: 0 - * Data: None - * - * wValue: - * B0..7 Event Character - * B8 Event Character Processing - * 0 = disabled - * 1 = enabled - * B9..15 Reserved - * - */ - -/* FTDI_SIO_SET_ERROR_CHAR */ - -/* - * Set the parity error replacement character for the specified communications - * port - */ - -/* - * BmRequestType: 0100 0000b - * bRequest: FTDI_SIO_SET_EVENT_CHAR - * wValue: Error Char - * wIndex: Port - * wLength: 0 - * Data: None - * - *Error Char - * B0..7 Error Character - * B8 Error Character Processing - * 0 = disabled - * 1 = enabled - * B9..15 Reserved - * - */ - -/* FTDI_SIO_GET_MODEM_STATUS */ -/* Retrieve the current value of the modem status register */ - -#define FTDI_SIO_GET_MODEM_STATUS_REQUEST_TYPE 0xc0 -#define FTDI_SIO_GET_MODEM_STATUS_REQUEST FTDI_SIO_GET_MODEM_STATUS -#define FTDI_SIO_CTS_MASK 0x10 -#define FTDI_SIO_DSR_MASK 0x20 -#define FTDI_SIO_RI_MASK 0x40 -#define FTDI_SIO_RLSD_MASK 0x80 -/* - * BmRequestType: 1100 0000b - * bRequest: FTDI_SIO_GET_MODEM_STATUS - * wValue: zero - * wIndex: Port - * wLength: 1 - * Data: Status - * - * One byte of data is returned - * B0..3 0 - * B4 CTS - * 0 = inactive - * 1 = active - * B5 DSR - * 0 = inactive - * 1 = active - * B6 Ring Indicator (RI) - * 0 = inactive - * 1 = active - * B7 Receive Line Signal Detect (RLSD) - * 0 = inactive - * 1 = active - */ - - - -/* Descriptors returned by the device - * - * Device Descriptor - * - * Offset Field Size Value Description - * 0 bLength 1 0x12 Size of descriptor in bytes - * 1 bDescriptorType 1 0x01 DEVICE Descriptor Type - * 2 bcdUSB 2 0x0110 USB Spec Release Number - * 4 bDeviceClass 1 0x00 Class Code - * 5 bDeviceSubClass 1 0x00 SubClass Code - * 6 bDeviceProtocol 1 0x00 Protocol Code - * 7 bMaxPacketSize0 1 0x08 Maximum packet size for endpoint 0 - * 8 idVendor 2 0x0403 Vendor ID - * 10 idProduct 2 0x8372 Product ID (FTDI_SIO_PID) - * 12 bcdDevice 2 0x0001 Device release number - * 14 iManufacturer 1 0x01 Index of man. string desc - * 15 iProduct 1 0x02 Index of prod string desc - * 16 iSerialNumber 1 0x02 Index of serial nmr string desc - * 17 bNumConfigurations 1 0x01 Number of possible configurations - * - * Configuration Descriptor - * - * Offset Field Size Value - * 0 bLength 1 0x09 Size of descriptor in bytes - * 1 bDescriptorType 1 0x02 CONFIGURATION Descriptor Type - * 2 wTotalLength 2 0x0020 Total length of data - * 4 bNumInterfaces 1 0x01 Number of interfaces supported - * 5 bConfigurationValue 1 0x01 Argument for SetCOnfiguration() req - * 6 iConfiguration 1 0x02 Index of config string descriptor - * 7 bmAttributes 1 0x20 Config characteristics Remote Wakeup - * 8 MaxPower 1 0x1E Max power consumption - * - * Interface Descriptor - * - * Offset Field Size Value - * 0 bLength 1 0x09 Size of descriptor in bytes - * 1 bDescriptorType 1 0x04 INTERFACE Descriptor Type - * 2 bInterfaceNumber 1 0x00 Number of interface - * 3 bAlternateSetting 1 0x00 Value used to select alternate - * 4 bNumEndpoints 1 0x02 Number of endpoints - * 5 bInterfaceClass 1 0xFF Class Code - * 6 bInterfaceSubClass 1 0xFF Subclass Code - * 7 bInterfaceProtocol 1 0xFF Protocol Code - * 8 iInterface 1 0x02 Index of interface string description - * - * IN Endpoint Descriptor - * - * Offset Field Size Value - * 0 bLength 1 0x07 Size of descriptor in bytes - * 1 bDescriptorType 1 0x05 ENDPOINT descriptor type - * 2 bEndpointAddress 1 0x82 Address of endpoint - * 3 bmAttributes 1 0x02 Endpoint attributes - Bulk - * 4 bNumEndpoints 2 0x0040 maximum packet size - * 5 bInterval 1 0x00 Interval for polling endpoint - * - * OUT Endpoint Descriptor - * - * Offset Field Size Value - * 0 bLength 1 0x07 Size of descriptor in bytes - * 1 bDescriptorType 1 0x05 ENDPOINT descriptor type - * 2 bEndpointAddress 1 0x02 Address of endpoint - * 3 bmAttributes 1 0x02 Endpoint attributes - Bulk - * 4 bNumEndpoints 2 0x0040 maximum packet size - * 5 bInterval 1 0x00 Interval for polling endpoint - * - * DATA FORMAT - * - * IN Endpoint - * - * The device reserves the first two bytes of data on this endpoint to contain - * the current values of the modem and line status registers. In the absence of - * data, the device generates a message consisting of these two status bytes - * every 40 ms - * - * Byte 0: Modem Status - * - * Offset Description - * B0 Reserved - must be 1 - * B1 Reserved - must be 0 - * B2 Reserved - must be 0 - * B3 Reserved - must be 0 - * B4 Clear to Send (CTS) - * B5 Data Set Ready (DSR) - * B6 Ring Indicator (RI) - * B7 Receive Line Signal Detect (RLSD) - * - * Byte 1: Line Status - * - * Offset Description - * B0 Data Ready (DR) - * B1 Overrun Error (OE) - * B2 Parity Error (PE) - * B3 Framing Error (FE) - * B4 Break Interrupt (BI) - * B5 Transmitter Holding Register (THRE) - * B6 Transmitter Empty (TEMT) - * B7 Error in RCVR FIFO - * - */ -#define FTDI_RS0_CTS (1 << 4) -#define FTDI_RS0_DSR (1 << 5) -#define FTDI_RS0_RI (1 << 6) -#define FTDI_RS0_RLSD (1 << 7) - -#define FTDI_RS_DR 1 -#define FTDI_RS_OE (1<<1) -#define FTDI_RS_PE (1<<2) -#define FTDI_RS_FE (1<<3) -#define FTDI_RS_BI (1<<4) -#define FTDI_RS_THRE (1<<5) -#define FTDI_RS_TEMT (1<<6) -#define FTDI_RS_FIFO (1<<7) - -/* - * OUT Endpoint - * - * This device reserves the first bytes of data on this endpoint contain the - * length and port identifier of the message. For the FTDI USB Serial converter - * the port identifier is always 1. - * - * Byte 0: Line Status - * - * Offset Description - * B0 Reserved - must be 1 - * B1 Reserved - must be 0 - * B2..7 Length of message - (not including Byte 0) - * - */ diff --git a/ANDROID_3.4.5/drivers/usb/serial/ftdi_sio_ids.h b/ANDROID_3.4.5/drivers/usb/serial/ftdi_sio_ids.h deleted file mode 100644 index 5661c7e2..00000000 --- a/ANDROID_3.4.5/drivers/usb/serial/ftdi_sio_ids.h +++ /dev/null @@ -1,1218 +0,0 @@ -/* - * vendor/product IDs (VID/PID) of devices using FTDI USB serial converters. - * Please keep numerically sorted within individual areas, thanks! - * - * Philipp Gühring - pg@futureware.at - added the Device ID of the USB relais - * from Rudolf Gugler - * - */ - - -/**********************************/ -/***** devices using FTDI VID *****/ -/**********************************/ - - -#define FTDI_VID 0x0403 /* Vendor Id */ - - -/*** "original" FTDI device PIDs ***/ - -#define FTDI_8U232AM_PID 0x6001 /* Similar device to SIO above */ -#define FTDI_8U232AM_ALT_PID 0x6006 /* FTDI's alternate PID for above */ -#define FTDI_8U2232C_PID 0x6010 /* Dual channel device */ -#define FTDI_4232H_PID 0x6011 /* Quad channel hi-speed device */ -#define FTDI_232H_PID 0x6014 /* Single channel hi-speed device */ -#define FTDI_FTX_PID 0x6015 /* FT-X series (FT201X, FT230X, FT231X, etc) */ -#define FTDI_SIO_PID 0x8372 /* Product Id SIO application of 8U100AX */ -#define FTDI_232RL_PID 0xFBFA /* Product ID for FT232RL */ - - -/*** third-party PIDs (using FTDI_VID) ***/ - -#define FTDI_LUMEL_PD12_PID 0x6002 - -/* - * Marvell OpenRD Base, Client - * http://www.open-rd.org - * OpenRD Base, Client use VID 0x0403 - */ -#define MARVELL_OPENRD_PID 0x9e90 - -/* www.candapter.com Ewert Energy Systems CANdapter device */ -#define FTDI_CANDAPTER_PID 0x9F80 /* Product Id */ - -/* - * Texas Instruments XDS100v2 JTAG / BeagleBone A3 - * http://processors.wiki.ti.com/index.php/XDS100 - * http://beagleboard.org/bone - */ -#define TI_XDS100V2_PID 0xa6d0 - -#define FTDI_NXTCAM_PID 0xABB8 /* NXTCam for Mindstorms NXT */ - -/* US Interface Navigator (http://www.usinterface.com/) */ -#define FTDI_USINT_CAT_PID 0xb810 /* Navigator CAT and 2nd PTT lines */ -#define FTDI_USINT_WKEY_PID 0xb811 /* Navigator WKEY and FSK lines */ -#define FTDI_USINT_RS232_PID 0xb812 /* Navigator RS232 and CONFIG lines */ - -/* OOCDlink by Joern Kaipf <joernk@web.de> - * (http://www.joernonline.de/) */ -#define FTDI_OOCDLINK_PID 0xbaf8 /* Amontec JTAGkey */ - -/* Luminary Micro Stellaris Boards, VID = FTDI_VID */ -/* FTDI 2332C Dual channel device, side A=245 FIFO (JTAG), Side B=RS232 UART */ -#define LMI_LM3S_DEVEL_BOARD_PID 0xbcd8 -#define LMI_LM3S_EVAL_BOARD_PID 0xbcd9 -#define LMI_LM3S_ICDI_BOARD_PID 0xbcda - -#define FTDI_TURTELIZER_PID 0xBDC8 /* JTAG/RS-232 adapter by egnite GmbH */ - -/* OpenDCC (www.opendcc.de) product id */ -#define FTDI_OPENDCC_PID 0xBFD8 -#define FTDI_OPENDCC_SNIFFER_PID 0xBFD9 -#define FTDI_OPENDCC_THROTTLE_PID 0xBFDA -#define FTDI_OPENDCC_GATEWAY_PID 0xBFDB -#define FTDI_OPENDCC_GBM_PID 0xBFDC - -/* - * RR-CirKits LocoBuffer USB (http://www.rr-cirkits.com) - */ -#define FTDI_RRCIRKITS_LOCOBUFFER_PID 0xc7d0 /* LocoBuffer USB */ - -/* DMX4ALL DMX Interfaces */ -#define FTDI_DMX4ALL 0xC850 - -/* - * ASK.fr devices - */ -#define FTDI_ASK_RDR400_PID 0xC991 /* ASK RDR 400 series card reader */ - -/* www.starting-point-systems.com µChameleon device */ -#define FTDI_MICRO_CHAMELEON_PID 0xCAA0 /* Product Id */ - -/* - * Tactrix OpenPort (ECU) devices. - * OpenPort 1.3M submitted by Donour Sizemore. - * OpenPort 1.3S and 1.3U submitted by Ian Abbott. - */ -#define FTDI_TACTRIX_OPENPORT_13M_PID 0xCC48 /* OpenPort 1.3 Mitsubishi */ -#define FTDI_TACTRIX_OPENPORT_13S_PID 0xCC49 /* OpenPort 1.3 Subaru */ -#define FTDI_TACTRIX_OPENPORT_13U_PID 0xCC4A /* OpenPort 1.3 Universal */ - -#define FTDI_DISTORTEC_JTAG_LOCK_PICK_PID 0xCFF8 - -/* SCS HF Radio Modems PID's (http://www.scs-ptc.com) */ -/* the VID is the standard ftdi vid (FTDI_VID) */ -#define FTDI_SCS_DEVICE_0_PID 0xD010 /* SCS PTC-IIusb */ -#define FTDI_SCS_DEVICE_1_PID 0xD011 /* SCS Tracker / DSP TNC */ -#define FTDI_SCS_DEVICE_2_PID 0xD012 -#define FTDI_SCS_DEVICE_3_PID 0xD013 -#define FTDI_SCS_DEVICE_4_PID 0xD014 -#define FTDI_SCS_DEVICE_5_PID 0xD015 -#define FTDI_SCS_DEVICE_6_PID 0xD016 -#define FTDI_SCS_DEVICE_7_PID 0xD017 - -/* iPlus device */ -#define FTDI_IPLUS_PID 0xD070 /* Product Id */ -#define FTDI_IPLUS2_PID 0xD071 /* Product Id */ - -/* - * Gamma Scout (http://gamma-scout.com/). Submitted by rsc@runtux.com. - */ -#define FTDI_GAMMA_SCOUT_PID 0xD678 /* Gamma Scout online */ - -/* Propox devices */ -#define FTDI_PROPOX_JTAGCABLEII_PID 0xD738 -#define FTDI_PROPOX_ISPCABLEIII_PID 0xD739 - -/* Lenz LI-USB Computer Interface. */ -#define FTDI_LENZ_LIUSB_PID 0xD780 - -/* Vardaan Enterprises Serial Interface VEUSB422R3 */ -#define FTDI_VARDAAN_PID 0xF070 - -/* - * Xsens Technologies BV products (http://www.xsens.com). - */ -#define XSENS_CONVERTER_0_PID 0xD388 -#define XSENS_CONVERTER_1_PID 0xD389 -#define XSENS_CONVERTER_2_PID 0xD38A -#define XSENS_CONVERTER_3_PID 0xD38B -#define XSENS_CONVERTER_4_PID 0xD38C -#define XSENS_CONVERTER_5_PID 0xD38D -#define XSENS_CONVERTER_6_PID 0xD38E -#define XSENS_CONVERTER_7_PID 0xD38F - -/* - * NDI (www.ndigital.com) product ids - */ -#define FTDI_NDI_HUC_PID 0xDA70 /* NDI Host USB Converter */ -#define FTDI_NDI_SPECTRA_SCU_PID 0xDA71 /* NDI Spectra SCU */ -#define FTDI_NDI_FUTURE_2_PID 0xDA72 /* NDI future device #2 */ -#define FTDI_NDI_FUTURE_3_PID 0xDA73 /* NDI future device #3 */ -#define FTDI_NDI_AURORA_SCU_PID 0xDA74 /* NDI Aurora SCU */ - -/* - * ChamSys Limited (www.chamsys.co.uk) USB wing/interface product IDs - */ -#define FTDI_CHAMSYS_24_MASTER_WING_PID 0xDAF8 -#define FTDI_CHAMSYS_PC_WING_PID 0xDAF9 -#define FTDI_CHAMSYS_USB_DMX_PID 0xDAFA -#define FTDI_CHAMSYS_MIDI_TIMECODE_PID 0xDAFB -#define FTDI_CHAMSYS_MINI_WING_PID 0xDAFC -#define FTDI_CHAMSYS_MAXI_WING_PID 0xDAFD -#define FTDI_CHAMSYS_MEDIA_WING_PID 0xDAFE -#define FTDI_CHAMSYS_WING_PID 0xDAFF - -/* - * Westrex International devices submitted by Cory Lee - */ -#define FTDI_WESTREX_MODEL_777_PID 0xDC00 /* Model 777 */ -#define FTDI_WESTREX_MODEL_8900F_PID 0xDC01 /* Model 8900F */ - -/* - * ACG Identification Technologies GmbH products (http://www.acg.de/). - * Submitted by anton -at- goto10 -dot- org. - */ -#define FTDI_ACG_HFDUAL_PID 0xDD20 /* HF Dual ISO Reader (RFID) */ - -/* - * Definitions for Artemis astronomical USB based cameras - * Check it at http://www.artemisccd.co.uk/ - */ -#define FTDI_ARTEMIS_PID 0xDF28 /* All Artemis Cameras */ - -/* - * Definitions for ATIK Instruments astronomical USB based cameras - * Check it at http://www.atik-instruments.com/ - */ -#define FTDI_ATIK_ATK16_PID 0xDF30 /* ATIK ATK-16 Grayscale Camera */ -#define FTDI_ATIK_ATK16C_PID 0xDF32 /* ATIK ATK-16C Colour Camera */ -#define FTDI_ATIK_ATK16HR_PID 0xDF31 /* ATIK ATK-16HR Grayscale Camera */ -#define FTDI_ATIK_ATK16HRC_PID 0xDF33 /* ATIK ATK-16HRC Colour Camera */ -#define FTDI_ATIK_ATK16IC_PID 0xDF35 /* ATIK ATK-16IC Grayscale Camera */ - -/* - * Yost Engineering, Inc. products (www.yostengineering.com). - * PID 0xE050 submitted by Aaron Prose. - */ -#define FTDI_YEI_SERVOCENTER31_PID 0xE050 /* YEI ServoCenter3.1 USB */ - -/* - * ELV USB devices submitted by Christian Abt of ELV (www.elv.de). - * All of these devices use FTDI's vendor ID (0x0403). - * Further IDs taken from ELV Windows .inf file. - * - * The previously included PID for the UO 100 module was incorrect. - * In fact, that PID was for ELV's UR 100 USB-RS232 converter (0xFB58). - * - * Armin Laeuger originally sent the PID for the UM 100 module. - */ -#define FTDI_ELV_USR_PID 0xE000 /* ELV Universal-Sound-Recorder */ -#define FTDI_ELV_MSM1_PID 0xE001 /* ELV Mini-Sound-Modul */ -#define FTDI_ELV_KL100_PID 0xE002 /* ELV Kfz-Leistungsmesser KL 100 */ -#define FTDI_ELV_WS550_PID 0xE004 /* WS 550 */ -#define FTDI_ELV_EC3000_PID 0xE006 /* ENERGY CONTROL 3000 USB */ -#define FTDI_ELV_WS888_PID 0xE008 /* WS 888 */ -#define FTDI_ELV_TWS550_PID 0xE009 /* Technoline WS 550 */ -#define FTDI_ELV_FEM_PID 0xE00A /* Funk Energie Monitor */ -#define FTDI_ELV_FHZ1300PC_PID 0xE0E8 /* FHZ 1300 PC */ -#define FTDI_ELV_WS500_PID 0xE0E9 /* PC-Wetterstation (WS 500) */ -#define FTDI_ELV_HS485_PID 0xE0EA /* USB to RS-485 adapter */ -#define FTDI_ELV_UMS100_PID 0xE0EB /* ELV USB Master-Slave Schaltsteckdose UMS 100 */ -#define FTDI_ELV_TFD128_PID 0xE0EC /* ELV Temperatur-Feuchte-Datenlogger TFD 128 */ -#define FTDI_ELV_FM3RX_PID 0xE0ED /* ELV Messwertuebertragung FM3 RX */ -#define FTDI_ELV_WS777_PID 0xE0EE /* Conrad WS 777 */ -#define FTDI_ELV_EM1010PC_PID 0xE0EF /* Energy monitor EM 1010 PC */ -#define FTDI_ELV_CSI8_PID 0xE0F0 /* Computer-Schalt-Interface (CSI 8) */ -#define FTDI_ELV_EM1000DL_PID 0xE0F1 /* PC-Datenlogger fuer Energiemonitor (EM 1000 DL) */ -#define FTDI_ELV_PCK100_PID 0xE0F2 /* PC-Kabeltester (PCK 100) */ -#define FTDI_ELV_RFP500_PID 0xE0F3 /* HF-Leistungsmesser (RFP 500) */ -#define FTDI_ELV_FS20SIG_PID 0xE0F4 /* Signalgeber (FS 20 SIG) */ -#define FTDI_ELV_UTP8_PID 0xE0F5 /* ELV UTP 8 */ -#define FTDI_ELV_WS300PC_PID 0xE0F6 /* PC-Wetterstation (WS 300 PC) */ -#define FTDI_ELV_WS444PC_PID 0xE0F7 /* Conrad WS 444 PC */ -#define FTDI_PHI_FISCO_PID 0xE40B /* PHI Fisco USB to Serial cable */ -#define FTDI_ELV_UAD8_PID 0xF068 /* USB-AD-Wandler (UAD 8) */ -#define FTDI_ELV_UDA7_PID 0xF069 /* USB-DA-Wandler (UDA 7) */ -#define FTDI_ELV_USI2_PID 0xF06A /* USB-Schrittmotoren-Interface (USI 2) */ -#define FTDI_ELV_T1100_PID 0xF06B /* Thermometer (T 1100) */ -#define FTDI_ELV_PCD200_PID 0xF06C /* PC-Datenlogger (PCD 200) */ -#define FTDI_ELV_ULA200_PID 0xF06D /* USB-LCD-Ansteuerung (ULA 200) */ -#define FTDI_ELV_ALC8500_PID 0xF06E /* ALC 8500 Expert */ -#define FTDI_ELV_FHZ1000PC_PID 0xF06F /* FHZ 1000 PC */ -#define FTDI_ELV_UR100_PID 0xFB58 /* USB-RS232-Umsetzer (UR 100) */ -#define FTDI_ELV_UM100_PID 0xFB5A /* USB-Modul UM 100 */ -#define FTDI_ELV_UO100_PID 0xFB5B /* USB-Modul UO 100 */ -/* Additional ELV PIDs that default to using the FTDI D2XX drivers on - * MS Windows, rather than the FTDI Virtual Com Port drivers. - * Maybe these will be easier to use with the libftdi/libusb user-space - * drivers, or possibly the Comedi drivers in some cases. */ -#define FTDI_ELV_CLI7000_PID 0xFB59 /* Computer-Light-Interface (CLI 7000) */ -#define FTDI_ELV_PPS7330_PID 0xFB5C /* Processor-Power-Supply (PPS 7330) */ -#define FTDI_ELV_TFM100_PID 0xFB5D /* Temperatur-Feuchte-Messgeraet (TFM 100) */ -#define FTDI_ELV_UDF77_PID 0xFB5E /* USB DCF Funkuhr (UDF 77) */ -#define FTDI_ELV_UIO88_PID 0xFB5F /* USB-I/O Interface (UIO 88) */ - -/* - * EVER Eco Pro UPS (http://www.ever.com.pl/) - */ - -#define EVER_ECO_PRO_CDS 0xe520 /* RS-232 converter */ - -/* - * Active Robots product ids. - */ -#define FTDI_ACTIVE_ROBOTS_PID 0xE548 /* USB comms board */ - -/* Pyramid Computer GmbH */ -#define FTDI_PYRAMID_PID 0xE6C8 /* Pyramid Appliance Display */ - -/* www.elsterelectricity.com Elster Unicom III Optical Probe */ -#define FTDI_ELSTER_UNICOM_PID 0xE700 /* Product Id */ - -/* - * Gude Analog- und Digitalsysteme GmbH - */ -#define FTDI_GUDEADS_E808_PID 0xE808 -#define FTDI_GUDEADS_E809_PID 0xE809 -#define FTDI_GUDEADS_E80A_PID 0xE80A -#define FTDI_GUDEADS_E80B_PID 0xE80B -#define FTDI_GUDEADS_E80C_PID 0xE80C -#define FTDI_GUDEADS_E80D_PID 0xE80D -#define FTDI_GUDEADS_E80E_PID 0xE80E -#define FTDI_GUDEADS_E80F_PID 0xE80F -#define FTDI_GUDEADS_E888_PID 0xE888 /* Expert ISDN Control USB */ -#define FTDI_GUDEADS_E889_PID 0xE889 /* USB RS-232 OptoBridge */ -#define FTDI_GUDEADS_E88A_PID 0xE88A -#define FTDI_GUDEADS_E88B_PID 0xE88B -#define FTDI_GUDEADS_E88C_PID 0xE88C -#define FTDI_GUDEADS_E88D_PID 0xE88D -#define FTDI_GUDEADS_E88E_PID 0xE88E -#define FTDI_GUDEADS_E88F_PID 0xE88F - -/* - * Eclo (http://www.eclo.pt/) product IDs. - * PID 0xEA90 submitted by Martin Grill. - */ -#define FTDI_ECLO_COM_1WIRE_PID 0xEA90 /* COM to 1-Wire USB adaptor */ - -/* TNC-X USB-to-packet-radio adapter, versions prior to 3.0 (DLP module) */ -#define FTDI_TNC_X_PID 0xEBE0 - -/* - * Teratronik product ids. - * Submitted by O. Wölfelschneider. - */ -#define FTDI_TERATRONIK_VCP_PID 0xEC88 /* Teratronik device (preferring VCP driver on windows) */ -#define FTDI_TERATRONIK_D2XX_PID 0xEC89 /* Teratronik device (preferring D2XX driver on windows) */ - -/* Rig Expert Ukraine devices */ -#define FTDI_REU_TINY_PID 0xED22 /* RigExpert Tiny */ - -/* - * Hameg HO820 and HO870 interface (using VID 0x0403) - */ -#define HAMEG_HO820_PID 0xed74 -#define HAMEG_HO730_PID 0xed73 -#define HAMEG_HO720_PID 0xed72 -#define HAMEG_HO870_PID 0xed71 - -/* - * MaxStream devices www.maxstream.net - */ -#define FTDI_MAXSTREAM_PID 0xEE18 /* Xbee PKG-U Module */ - -/* - * microHAM product IDs (http://www.microham.com). - * Submitted by Justin Burket (KL1RL) <zorton@jtan.com> - * and Mike Studer (K6EEP) <k6eep@hamsoftware.org>. - * Ian Abbott <abbotti@mev.co.uk> added a few more from the driver INF file. - */ -#define FTDI_MHAM_KW_PID 0xEEE8 /* USB-KW interface */ -#define FTDI_MHAM_YS_PID 0xEEE9 /* USB-YS interface */ -#define FTDI_MHAM_Y6_PID 0xEEEA /* USB-Y6 interface */ -#define FTDI_MHAM_Y8_PID 0xEEEB /* USB-Y8 interface */ -#define FTDI_MHAM_IC_PID 0xEEEC /* USB-IC interface */ -#define FTDI_MHAM_DB9_PID 0xEEED /* USB-DB9 interface */ -#define FTDI_MHAM_RS232_PID 0xEEEE /* USB-RS232 interface */ -#define FTDI_MHAM_Y9_PID 0xEEEF /* USB-Y9 interface */ - -/* Domintell products http://www.domintell.com */ -#define FTDI_DOMINTELL_DGQG_PID 0xEF50 /* Master */ -#define FTDI_DOMINTELL_DUSB_PID 0xEF51 /* DUSB01 module */ - -/* - * The following are the values for the Perle Systems - * UltraPort USB serial converters - */ -#define FTDI_PERLE_ULTRAPORT_PID 0xF0C0 /* Perle UltraPort Product Id */ - -/* Sprog II (Andrew Crosland's SprogII DCC interface) */ -#define FTDI_SPROG_II 0xF0C8 - -/* an infrared receiver for user access control with IR tags */ -#define FTDI_PIEGROUP_PID 0xF208 /* Product Id */ - -/* ACT Solutions HomePro ZWave interface - (http://www.act-solutions.com/HomePro-Product-Matrix.html) */ -#define FTDI_ACTZWAVE_PID 0xF2D0 - -/* - * 4N-GALAXY.DE PIDs for CAN-USB, USB-RS232, USB-RS422, USB-RS485, - * USB-TTY aktiv, USB-TTY passiv. Some PIDs are used by several devices - * and I'm not entirely sure which are used by which. - */ -#define FTDI_4N_GALAXY_DE_1_PID 0xF3C0 -#define FTDI_4N_GALAXY_DE_2_PID 0xF3C1 -#define FTDI_4N_GALAXY_DE_3_PID 0xF3C2 - -/* - * Linx Technologies product ids - */ -#define LINX_SDMUSBQSS_PID 0xF448 /* Linx SDM-USB-QS-S */ -#define LINX_MASTERDEVEL2_PID 0xF449 /* Linx Master Development 2.0 */ -#define LINX_FUTURE_0_PID 0xF44A /* Linx future device */ -#define LINX_FUTURE_1_PID 0xF44B /* Linx future device */ -#define LINX_FUTURE_2_PID 0xF44C /* Linx future device */ - -/* - * Oceanic product ids - */ -#define FTDI_OCEANIC_PID 0xF460 /* Oceanic dive instrument */ - -/* - * SUUNTO product ids - */ -#define FTDI_SUUNTO_SPORTS_PID 0xF680 /* Suunto Sports instrument */ - -/* USB-UIRT - An infrared receiver and transmitter using the 8U232AM chip */ -/* http://www.usbuirt.com/ */ -#define FTDI_USB_UIRT_PID 0xF850 /* Product Id */ - -/* CCS Inc. ICDU/ICDU40 product ID - - * the FT232BM is used in an in-circuit-debugger unit for PIC16's/PIC18's */ -#define FTDI_CCSICDU20_0_PID 0xF9D0 -#define FTDI_CCSICDU40_1_PID 0xF9D1 -#define FTDI_CCSMACHX_2_PID 0xF9D2 -#define FTDI_CCSLOAD_N_GO_3_PID 0xF9D3 -#define FTDI_CCSICDU64_4_PID 0xF9D4 -#define FTDI_CCSPRIME8_5_PID 0xF9D5 - -/* - * The following are the values for the Matrix Orbital LCD displays, - * which are the FT232BM ( similar to the 8U232AM ) - */ -#define FTDI_MTXORB_0_PID 0xFA00 /* Matrix Orbital Product Id */ -#define FTDI_MTXORB_1_PID 0xFA01 /* Matrix Orbital Product Id */ -#define FTDI_MTXORB_2_PID 0xFA02 /* Matrix Orbital Product Id */ -#define FTDI_MTXORB_3_PID 0xFA03 /* Matrix Orbital Product Id */ -#define FTDI_MTXORB_4_PID 0xFA04 /* Matrix Orbital Product Id */ -#define FTDI_MTXORB_5_PID 0xFA05 /* Matrix Orbital Product Id */ -#define FTDI_MTXORB_6_PID 0xFA06 /* Matrix Orbital Product Id */ - -/* - * Home Electronics (www.home-electro.com) USB gadgets - */ -#define FTDI_HE_TIRA1_PID 0xFA78 /* Tira-1 IR transceiver */ - -/* Inside Accesso contactless reader (http://www.insidecontactless.com/) */ -#define INSIDE_ACCESSO 0xFAD0 - -/* - * ThorLabs USB motor drivers - */ -#define FTDI_THORLABS_PID 0xfaf0 /* ThorLabs USB motor drivers */ - -/* - * Protego product ids - */ -#define PROTEGO_SPECIAL_1 0xFC70 /* special/unknown device */ -#define PROTEGO_R2X0 0xFC71 /* R200-USB TRNG unit (R210, R220, and R230) */ -#define PROTEGO_SPECIAL_3 0xFC72 /* special/unknown device */ -#define PROTEGO_SPECIAL_4 0xFC73 /* special/unknown device */ - -/* - * Sony Ericsson product ids - */ -#define FTDI_DSS20_PID 0xFC82 /* DSS-20 Sync Station for Sony Ericsson P800 */ -#define FTDI_URBAN_0_PID 0xFC8A /* Sony Ericsson Urban, uart #0 */ -#define FTDI_URBAN_1_PID 0xFC8B /* Sony Ericsson Urban, uart #1 */ - -/* www.irtrans.de device */ -#define FTDI_IRTRANS_PID 0xFC60 /* Product Id */ - -/* - * RM Michaelides CANview USB (http://www.rmcan.com) (FTDI_VID) - * CAN fieldbus interface adapter, added by port GmbH www.port.de) - * Ian Abbott changed the macro names for consistency. - */ -#define FTDI_RM_CANVIEW_PID 0xfd60 /* Product Id */ -/* www.thoughttechnology.com/ TT-USB provide with procomp use ftdi_sio */ -#define FTDI_TTUSB_PID 0xFF20 /* Product Id */ - -#define FTDI_USBX_707_PID 0xF857 /* ADSTech IR Blaster USBX-707 (FTDI_VID) */ - -#define FTDI_RELAIS_PID 0xFA10 /* Relais device from Rudolf Gugler */ - -/* - * PCDJ use ftdi based dj-controllers. The following PID is - * for their DAC-2 device http://www.pcdjhardware.com/DAC2.asp - * (the VID is the standard ftdi vid (FTDI_VID), PID sent by Wouter Paesen) - */ -#define FTDI_PCDJ_DAC2_PID 0xFA88 - -#define FTDI_R2000KU_TRUE_RNG 0xFB80 /* R2000KU TRUE RNG (FTDI_VID) */ - -/* - * DIEBOLD BCS SE923 (FTDI_VID) - */ -#define DIEBOLD_BCS_SE923_PID 0xfb99 - -/* www.crystalfontz.com devices - * - thanx for providing free devices for evaluation ! - * they use the ftdi chipset for the USB interface - * and the vendor id is the same - */ -#define FTDI_XF_632_PID 0xFC08 /* 632: 16x2 Character Display */ -#define FTDI_XF_634_PID 0xFC09 /* 634: 20x4 Character Display */ -#define FTDI_XF_547_PID 0xFC0A /* 547: Two line Display */ -#define FTDI_XF_633_PID 0xFC0B /* 633: 16x2 Character Display with Keys */ -#define FTDI_XF_631_PID 0xFC0C /* 631: 20x2 Character Display */ -#define FTDI_XF_635_PID 0xFC0D /* 635: 20x4 Character Display */ -#define FTDI_XF_640_PID 0xFC0E /* 640: Two line Display */ -#define FTDI_XF_642_PID 0xFC0F /* 642: Two line Display */ - -/* - * Video Networks Limited / Homechoice in the UK use an ftdi-based device - * for their 1Mb broadband internet service. The following PID is exhibited - * by the usb device supplied (the VID is the standard ftdi vid (FTDI_VID) - */ -#define FTDI_VNHCPCUSB_D_PID 0xfe38 /* Product Id */ - -/* AlphaMicro Components AMC-232USB01 device (FTDI_VID) */ -#define FTDI_AMC232_PID 0xFF00 /* Product Id */ - -/* - * IBS elektronik product ids (FTDI_VID) - * Submitted by Thomas Schleusener - */ -#define FTDI_IBS_US485_PID 0xff38 /* IBS US485 (USB<-->RS422/485 interface) */ -#define FTDI_IBS_PICPRO_PID 0xff39 /* IBS PIC-Programmer */ -#define FTDI_IBS_PCMCIA_PID 0xff3a /* IBS Card reader for PCMCIA SRAM-cards */ -#define FTDI_IBS_PK1_PID 0xff3b /* IBS PK1 - Particel counter */ -#define FTDI_IBS_RS232MON_PID 0xff3c /* IBS RS232 - Monitor */ -#define FTDI_IBS_APP70_PID 0xff3d /* APP 70 (dust monitoring system) */ -#define FTDI_IBS_PEDO_PID 0xff3e /* IBS PEDO-Modem (RF modem 868.35 MHz) */ -#define FTDI_IBS_PROD_PID 0xff3f /* future device */ -/* www.canusb.com Lawicel CANUSB device (FTDI_VID) */ -#define FTDI_CANUSB_PID 0xFFA8 /* Product Id */ - -/* - * TavIR AVR product ids (FTDI_VID) - */ -#define FTDI_TAVIR_STK500_PID 0xFA33 /* STK500 AVR programmer */ - - - -/********************************/ -/** third-party VID/PID combos **/ -/********************************/ - - - -/* - * Atmel STK541 - */ -#define ATMEL_VID 0x03eb /* Vendor ID */ -#define STK541_PID 0x2109 /* Zigbee Controller */ - -/* - * Blackfin gnICE JTAG - * http://docs.blackfin.uclinux.org/doku.php?id=hw:jtag:gnice - */ -#define ADI_VID 0x0456 -#define ADI_GNICE_PID 0xF000 -#define ADI_GNICEPLUS_PID 0xF001 - -/* - * Microchip Technology, Inc. - * - * MICROCHIP_VID (0x04D8) and MICROCHIP_USB_BOARD_PID (0x000A) are also used by: - * Hornby Elite - Digital Command Control Console - * http://www.hornby.com/hornby-dcc/controllers/ - */ -#define MICROCHIP_VID 0x04D8 -#define MICROCHIP_USB_BOARD_PID 0x000A /* CDC RS-232 Emulation Demo */ - -/* - * RATOC REX-USB60F - */ -#define RATOC_VENDOR_ID 0x0584 -#define RATOC_PRODUCT_ID_USB60F 0xb020 - -/* - * Acton Research Corp. - */ -#define ACTON_VID 0x0647 /* Vendor ID */ -#define ACTON_SPECTRAPRO_PID 0x0100 - -/* - * Contec products (http://www.contec.com) - * Submitted by Daniel Sangorrin - */ -#define CONTEC_VID 0x06CE /* Vendor ID */ -#define CONTEC_COM1USBH_PID 0x8311 /* COM-1(USB)H */ - -/* - * Definitions for B&B Electronics products. - */ -#define BANDB_VID 0x0856 /* B&B Electronics Vendor ID */ -#define BANDB_USOTL4_PID 0xAC01 /* USOTL4 Isolated RS-485 Converter */ -#define BANDB_USTL4_PID 0xAC02 /* USTL4 RS-485 Converter */ -#define BANDB_USO9ML2_PID 0xAC03 /* USO9ML2 Isolated RS-232 Converter */ -#define BANDB_USOPTL4_PID 0xAC11 -#define BANDB_USPTL4_PID 0xAC12 -#define BANDB_USO9ML2DR_2_PID 0xAC16 -#define BANDB_USO9ML2DR_PID 0xAC17 -#define BANDB_USOPTL4DR2_PID 0xAC18 /* USOPTL4R-2 2-port Isolated RS-232 Converter */ -#define BANDB_USOPTL4DR_PID 0xAC19 -#define BANDB_485USB9F_2W_PID 0xAC25 -#define BANDB_485USB9F_4W_PID 0xAC26 -#define BANDB_232USB9M_PID 0xAC27 -#define BANDB_485USBTB_2W_PID 0xAC33 -#define BANDB_485USBTB_4W_PID 0xAC34 -#define BANDB_TTL5USB9M_PID 0xAC49 -#define BANDB_TTL3USB9M_PID 0xAC50 -#define BANDB_ZZ_PROG1_USB_PID 0xBA02 - -/* - * Intrepid Control Systems (http://www.intrepidcs.com/) ValueCAN and NeoVI - */ -#define INTREPID_VID 0x093C -#define INTREPID_VALUECAN_PID 0x0601 -#define INTREPID_NEOVI_PID 0x0701 - -/* - * Definitions for ID TECH (www.idt-net.com) devices - */ -#define IDTECH_VID 0x0ACD /* ID TECH Vendor ID */ -#define IDTECH_IDT1221U_PID 0x0300 /* IDT1221U USB to RS-232 adapter */ - -/* - * Definitions for Omnidirectional Control Technology, Inc. devices - */ -#define OCT_VID 0x0B39 /* OCT vendor ID */ -/* Note: OCT US101 is also rebadged as Dick Smith Electronics (NZ) XH6381 */ -/* Also rebadged as Dick Smith Electronics (Aus) XH6451 */ -/* Also rebadged as SIIG Inc. model US2308 hardware version 1 */ -#define OCT_DK201_PID 0x0103 /* OCT DK201 USB docking station */ -#define OCT_US101_PID 0x0421 /* OCT US101 USB to RS-232 */ - -/* - * Definitions for Icom Inc. devices - */ -#define ICOM_VID 0x0C26 /* Icom vendor ID */ -/* Note: ID-1 is a communications tranceiver for HAM-radio operators */ -#define ICOM_ID_1_PID 0x0004 /* ID-1 USB to RS-232 */ -/* Note: OPC is an Optional cable to connect an Icom Tranceiver */ -#define ICOM_OPC_U_UC_PID 0x0018 /* OPC-478UC, OPC-1122U cloning cable */ -/* Note: ID-RP* devices are Icom Repeater Devices for HAM-radio */ -#define ICOM_ID_RP2C1_PID 0x0009 /* ID-RP2C Asset 1 to RS-232 */ -#define ICOM_ID_RP2C2_PID 0x000A /* ID-RP2C Asset 2 to RS-232 */ -#define ICOM_ID_RP2D_PID 0x000B /* ID-RP2D configuration port*/ -#define ICOM_ID_RP2VT_PID 0x000C /* ID-RP2V Transmit config port */ -#define ICOM_ID_RP2VR_PID 0x000D /* ID-RP2V Receive config port */ -#define ICOM_ID_RP4KVT_PID 0x0010 /* ID-RP4000V Transmit config port */ -#define ICOM_ID_RP4KVR_PID 0x0011 /* ID-RP4000V Receive config port */ -#define ICOM_ID_RP2KVT_PID 0x0012 /* ID-RP2000V Transmit config port */ -#define ICOM_ID_RP2KVR_PID 0x0013 /* ID-RP2000V Receive config port */ - -/* - * GN Otometrics (http://www.otometrics.com) - * Submitted by Ville Sundberg. - */ -#define GN_OTOMETRICS_VID 0x0c33 /* Vendor ID */ -#define AURICAL_USB_PID 0x0010 /* Aurical USB Audiometer */ - -/* - * The following are the values for the Sealevel SeaLINK+ adapters. - * (Original list sent by Tuan Hoang. Ian Abbott renamed the macros and - * removed some PIDs that don't seem to match any existing products.) - */ -#define SEALEVEL_VID 0x0c52 /* Sealevel Vendor ID */ -#define SEALEVEL_2101_PID 0x2101 /* SeaLINK+232 (2101/2105) */ -#define SEALEVEL_2102_PID 0x2102 /* SeaLINK+485 (2102) */ -#define SEALEVEL_2103_PID 0x2103 /* SeaLINK+232I (2103) */ -#define SEALEVEL_2104_PID 0x2104 /* SeaLINK+485I (2104) */ -#define SEALEVEL_2106_PID 0x9020 /* SeaLINK+422 (2106) */ -#define SEALEVEL_2201_1_PID 0x2211 /* SeaPORT+2/232 (2201) Port 1 */ -#define SEALEVEL_2201_2_PID 0x2221 /* SeaPORT+2/232 (2201) Port 2 */ -#define SEALEVEL_2202_1_PID 0x2212 /* SeaPORT+2/485 (2202) Port 1 */ -#define SEALEVEL_2202_2_PID 0x2222 /* SeaPORT+2/485 (2202) Port 2 */ -#define SEALEVEL_2203_1_PID 0x2213 /* SeaPORT+2 (2203) Port 1 */ -#define SEALEVEL_2203_2_PID 0x2223 /* SeaPORT+2 (2203) Port 2 */ -#define SEALEVEL_2401_1_PID 0x2411 /* SeaPORT+4/232 (2401) Port 1 */ -#define SEALEVEL_2401_2_PID 0x2421 /* SeaPORT+4/232 (2401) Port 2 */ -#define SEALEVEL_2401_3_PID 0x2431 /* SeaPORT+4/232 (2401) Port 3 */ -#define SEALEVEL_2401_4_PID 0x2441 /* SeaPORT+4/232 (2401) Port 4 */ -#define SEALEVEL_2402_1_PID 0x2412 /* SeaPORT+4/485 (2402) Port 1 */ -#define SEALEVEL_2402_2_PID 0x2422 /* SeaPORT+4/485 (2402) Port 2 */ -#define SEALEVEL_2402_3_PID 0x2432 /* SeaPORT+4/485 (2402) Port 3 */ -#define SEALEVEL_2402_4_PID 0x2442 /* SeaPORT+4/485 (2402) Port 4 */ -#define SEALEVEL_2403_1_PID 0x2413 /* SeaPORT+4 (2403) Port 1 */ -#define SEALEVEL_2403_2_PID 0x2423 /* SeaPORT+4 (2403) Port 2 */ -#define SEALEVEL_2403_3_PID 0x2433 /* SeaPORT+4 (2403) Port 3 */ -#define SEALEVEL_2403_4_PID 0x2443 /* SeaPORT+4 (2403) Port 4 */ -#define SEALEVEL_2801_1_PID 0X2811 /* SeaLINK+8/232 (2801) Port 1 */ -#define SEALEVEL_2801_2_PID 0X2821 /* SeaLINK+8/232 (2801) Port 2 */ -#define SEALEVEL_2801_3_PID 0X2831 /* SeaLINK+8/232 (2801) Port 3 */ -#define SEALEVEL_2801_4_PID 0X2841 /* SeaLINK+8/232 (2801) Port 4 */ -#define SEALEVEL_2801_5_PID 0X2851 /* SeaLINK+8/232 (2801) Port 5 */ -#define SEALEVEL_2801_6_PID 0X2861 /* SeaLINK+8/232 (2801) Port 6 */ -#define SEALEVEL_2801_7_PID 0X2871 /* SeaLINK+8/232 (2801) Port 7 */ -#define SEALEVEL_2801_8_PID 0X2881 /* SeaLINK+8/232 (2801) Port 8 */ -#define SEALEVEL_2802_1_PID 0X2812 /* SeaLINK+8/485 (2802) Port 1 */ -#define SEALEVEL_2802_2_PID 0X2822 /* SeaLINK+8/485 (2802) Port 2 */ -#define SEALEVEL_2802_3_PID 0X2832 /* SeaLINK+8/485 (2802) Port 3 */ -#define SEALEVEL_2802_4_PID 0X2842 /* SeaLINK+8/485 (2802) Port 4 */ -#define SEALEVEL_2802_5_PID 0X2852 /* SeaLINK+8/485 (2802) Port 5 */ -#define SEALEVEL_2802_6_PID 0X2862 /* SeaLINK+8/485 (2802) Port 6 */ -#define SEALEVEL_2802_7_PID 0X2872 /* SeaLINK+8/485 (2802) Port 7 */ -#define SEALEVEL_2802_8_PID 0X2882 /* SeaLINK+8/485 (2802) Port 8 */ -#define SEALEVEL_2803_1_PID 0X2813 /* SeaLINK+8 (2803) Port 1 */ -#define SEALEVEL_2803_2_PID 0X2823 /* SeaLINK+8 (2803) Port 2 */ -#define SEALEVEL_2803_3_PID 0X2833 /* SeaLINK+8 (2803) Port 3 */ -#define SEALEVEL_2803_4_PID 0X2843 /* SeaLINK+8 (2803) Port 4 */ -#define SEALEVEL_2803_5_PID 0X2853 /* SeaLINK+8 (2803) Port 5 */ -#define SEALEVEL_2803_6_PID 0X2863 /* SeaLINK+8 (2803) Port 6 */ -#define SEALEVEL_2803_7_PID 0X2873 /* SeaLINK+8 (2803) Port 7 */ -#define SEALEVEL_2803_8_PID 0X2883 /* SeaLINK+8 (2803) Port 8 */ -#define SEALEVEL_2803R_1_PID 0Xa02a /* SeaLINK+8 (2803-ROHS) Port 1+2 */ -#define SEALEVEL_2803R_2_PID 0Xa02b /* SeaLINK+8 (2803-ROHS) Port 3+4 */ -#define SEALEVEL_2803R_3_PID 0Xa02c /* SeaLINK+8 (2803-ROHS) Port 5+6 */ -#define SEALEVEL_2803R_4_PID 0Xa02d /* SeaLINK+8 (2803-ROHS) Port 7+8 */ - -/* - * JETI SPECTROMETER SPECBOS 1201 - * http://www.jeti.com/cms/index.php/instruments/other-instruments/specbos-2101 - */ -#define JETI_VID 0x0c6c -#define JETI_SPC1201_PID 0x04b2 - -/* - * FTDI USB UART chips used in construction projects from the - * Elektor Electronics magazine (http://www.elektor.com/) - */ -#define ELEKTOR_VID 0x0C7D -#define ELEKTOR_FT323R_PID 0x0005 /* RFID-Reader, issue 09-2006 */ - -/* - * Posiflex inc retail equipment (http://www.posiflex.com.tw) - */ -#define POSIFLEX_VID 0x0d3a /* Vendor ID */ -#define POSIFLEX_PP7000_PID 0x0300 /* PP-7000II thermal printer */ - -/* - * The following are the values for two KOBIL chipcard terminals. - */ -#define KOBIL_VID 0x0d46 /* KOBIL Vendor ID */ -#define KOBIL_CONV_B1_PID 0x2020 /* KOBIL Konverter for B1 */ -#define KOBIL_CONV_KAAN_PID 0x2021 /* KOBIL_Konverter for KAAN */ - -#define FTDI_NF_RIC_VID 0x0DCD /* Vendor Id */ -#define FTDI_NF_RIC_PID 0x0001 /* Product Id */ - -/* - * Falcom Wireless Communications GmbH - */ -#define FALCOM_VID 0x0F94 /* Vendor Id */ -#define FALCOM_TWIST_PID 0x0001 /* Falcom Twist USB GPRS modem */ -#define FALCOM_SAMBA_PID 0x0005 /* Falcom Samba USB GPRS modem */ - -/* Larsen and Brusgaard AltiTrack/USBtrack */ -#define LARSENBRUSGAARD_VID 0x0FD8 -#define LB_ALTITRACK_PID 0x0001 - -/* - * TTi (Thurlby Thandar Instruments) - */ -#define TTI_VID 0x103E /* Vendor Id */ -#define TTI_QL355P_PID 0x03E8 /* TTi QL355P power supply */ - -/* Interbiometrics USB I/O Board */ -/* Developed for Interbiometrics by Rudolf Gugler */ -#define INTERBIOMETRICS_VID 0x1209 -#define INTERBIOMETRICS_IOBOARD_PID 0x1002 -#define INTERBIOMETRICS_MINI_IOBOARD_PID 0x1006 - -/* - * Testo products (http://www.testo.com/) - * Submitted by Colin Leroy - */ -#define TESTO_VID 0x128D -#define TESTO_USB_INTERFACE_PID 0x0001 - -/* - * Mobility Electronics products. - */ -#define MOBILITY_VID 0x1342 -#define MOBILITY_USB_SERIAL_PID 0x0202 /* EasiDock USB 200 serial */ - -/* - * FIC / OpenMoko, Inc. http://wiki.openmoko.org/wiki/Neo1973_Debug_Board_v3 - * Submitted by Harald Welte <laforge@openmoko.org> - */ -#define FIC_VID 0x1457 -#define FIC_NEO1973_DEBUG_PID 0x5118 - -/* Olimex */ -#define OLIMEX_VID 0x15BA -#define OLIMEX_ARM_USB_OCD_PID 0x0003 -#define OLIMEX_ARM_USB_OCD_H_PID 0x002b - -/* - * Telldus Technologies - */ -#define TELLDUS_VID 0x1781 /* Vendor ID */ -#define TELLDUS_TELLSTICK_PID 0x0C30 /* RF control dongle 433 MHz using FT232RL */ - -/* - * RT Systems programming cables for various ham radios - */ -#define RTSYSTEMS_VID 0x2100 /* Vendor ID */ -#define RTSYSTEMS_SERIAL_VX7_PID 0x9e52 /* Serial converter for VX-7 Radios using FT232RL */ -#define RTSYSTEMS_CT29B_PID 0x9e54 /* CT29B Radio Cable */ -#define RTSYSTEMS_RTS01_PID 0x9e57 /* USB-RTS01 Radio Cable */ - - -/* - * Physik Instrumente - * http://www.physikinstrumente.com/en/products/ - */ -#define PI_VID 0x1a72 /* Vendor ID */ -#define PI_E861_PID 0x1008 /* E-861 piezo controller USB connection */ - -/* - * Bayer Ascensia Contour blood glucose meter USB-converter cable. - * http://winglucofacts.com/cables/ - */ -#define BAYER_VID 0x1A79 -#define BAYER_CONTOUR_CABLE_PID 0x6001 - -/* - * The following are the values for the Matrix Orbital FTDI Range - * Anything in this range will use an FT232RL. - */ -#define MTXORB_VID 0x1B3D -#define MTXORB_FTDI_RANGE_0100_PID 0x0100 -#define MTXORB_FTDI_RANGE_0101_PID 0x0101 -#define MTXORB_FTDI_RANGE_0102_PID 0x0102 -#define MTXORB_FTDI_RANGE_0103_PID 0x0103 -#define MTXORB_FTDI_RANGE_0104_PID 0x0104 -#define MTXORB_FTDI_RANGE_0105_PID 0x0105 -#define MTXORB_FTDI_RANGE_0106_PID 0x0106 -#define MTXORB_FTDI_RANGE_0107_PID 0x0107 -#define MTXORB_FTDI_RANGE_0108_PID 0x0108 -#define MTXORB_FTDI_RANGE_0109_PID 0x0109 -#define MTXORB_FTDI_RANGE_010A_PID 0x010A -#define MTXORB_FTDI_RANGE_010B_PID 0x010B -#define MTXORB_FTDI_RANGE_010C_PID 0x010C -#define MTXORB_FTDI_RANGE_010D_PID 0x010D -#define MTXORB_FTDI_RANGE_010E_PID 0x010E -#define MTXORB_FTDI_RANGE_010F_PID 0x010F -#define MTXORB_FTDI_RANGE_0110_PID 0x0110 -#define MTXORB_FTDI_RANGE_0111_PID 0x0111 -#define MTXORB_FTDI_RANGE_0112_PID 0x0112 -#define MTXORB_FTDI_RANGE_0113_PID 0x0113 -#define MTXORB_FTDI_RANGE_0114_PID 0x0114 -#define MTXORB_FTDI_RANGE_0115_PID 0x0115 -#define MTXORB_FTDI_RANGE_0116_PID 0x0116 -#define MTXORB_FTDI_RANGE_0117_PID 0x0117 -#define MTXORB_FTDI_RANGE_0118_PID 0x0118 -#define MTXORB_FTDI_RANGE_0119_PID 0x0119 -#define MTXORB_FTDI_RANGE_011A_PID 0x011A -#define MTXORB_FTDI_RANGE_011B_PID 0x011B -#define MTXORB_FTDI_RANGE_011C_PID 0x011C -#define MTXORB_FTDI_RANGE_011D_PID 0x011D -#define MTXORB_FTDI_RANGE_011E_PID 0x011E -#define MTXORB_FTDI_RANGE_011F_PID 0x011F -#define MTXORB_FTDI_RANGE_0120_PID 0x0120 -#define MTXORB_FTDI_RANGE_0121_PID 0x0121 -#define MTXORB_FTDI_RANGE_0122_PID 0x0122 -#define MTXORB_FTDI_RANGE_0123_PID 0x0123 -#define MTXORB_FTDI_RANGE_0124_PID 0x0124 -#define MTXORB_FTDI_RANGE_0125_PID 0x0125 -#define MTXORB_FTDI_RANGE_0126_PID 0x0126 -#define MTXORB_FTDI_RANGE_0127_PID 0x0127 -#define MTXORB_FTDI_RANGE_0128_PID 0x0128 -#define MTXORB_FTDI_RANGE_0129_PID 0x0129 -#define MTXORB_FTDI_RANGE_012A_PID 0x012A -#define MTXORB_FTDI_RANGE_012B_PID 0x012B -#define MTXORB_FTDI_RANGE_012C_PID 0x012C -#define MTXORB_FTDI_RANGE_012D_PID 0x012D -#define MTXORB_FTDI_RANGE_012E_PID 0x012E -#define MTXORB_FTDI_RANGE_012F_PID 0x012F -#define MTXORB_FTDI_RANGE_0130_PID 0x0130 -#define MTXORB_FTDI_RANGE_0131_PID 0x0131 -#define MTXORB_FTDI_RANGE_0132_PID 0x0132 -#define MTXORB_FTDI_RANGE_0133_PID 0x0133 -#define MTXORB_FTDI_RANGE_0134_PID 0x0134 -#define MTXORB_FTDI_RANGE_0135_PID 0x0135 -#define MTXORB_FTDI_RANGE_0136_PID 0x0136 -#define MTXORB_FTDI_RANGE_0137_PID 0x0137 -#define MTXORB_FTDI_RANGE_0138_PID 0x0138 -#define MTXORB_FTDI_RANGE_0139_PID 0x0139 -#define MTXORB_FTDI_RANGE_013A_PID 0x013A -#define MTXORB_FTDI_RANGE_013B_PID 0x013B -#define MTXORB_FTDI_RANGE_013C_PID 0x013C -#define MTXORB_FTDI_RANGE_013D_PID 0x013D -#define MTXORB_FTDI_RANGE_013E_PID 0x013E -#define MTXORB_FTDI_RANGE_013F_PID 0x013F -#define MTXORB_FTDI_RANGE_0140_PID 0x0140 -#define MTXORB_FTDI_RANGE_0141_PID 0x0141 -#define MTXORB_FTDI_RANGE_0142_PID 0x0142 -#define MTXORB_FTDI_RANGE_0143_PID 0x0143 -#define MTXORB_FTDI_RANGE_0144_PID 0x0144 -#define MTXORB_FTDI_RANGE_0145_PID 0x0145 -#define MTXORB_FTDI_RANGE_0146_PID 0x0146 -#define MTXORB_FTDI_RANGE_0147_PID 0x0147 -#define MTXORB_FTDI_RANGE_0148_PID 0x0148 -#define MTXORB_FTDI_RANGE_0149_PID 0x0149 -#define MTXORB_FTDI_RANGE_014A_PID 0x014A -#define MTXORB_FTDI_RANGE_014B_PID 0x014B -#define MTXORB_FTDI_RANGE_014C_PID 0x014C -#define MTXORB_FTDI_RANGE_014D_PID 0x014D -#define MTXORB_FTDI_RANGE_014E_PID 0x014E -#define MTXORB_FTDI_RANGE_014F_PID 0x014F -#define MTXORB_FTDI_RANGE_0150_PID 0x0150 -#define MTXORB_FTDI_RANGE_0151_PID 0x0151 -#define MTXORB_FTDI_RANGE_0152_PID 0x0152 -#define MTXORB_FTDI_RANGE_0153_PID 0x0153 -#define MTXORB_FTDI_RANGE_0154_PID 0x0154 -#define MTXORB_FTDI_RANGE_0155_PID 0x0155 -#define MTXORB_FTDI_RANGE_0156_PID 0x0156 -#define MTXORB_FTDI_RANGE_0157_PID 0x0157 -#define MTXORB_FTDI_RANGE_0158_PID 0x0158 -#define MTXORB_FTDI_RANGE_0159_PID 0x0159 -#define MTXORB_FTDI_RANGE_015A_PID 0x015A -#define MTXORB_FTDI_RANGE_015B_PID 0x015B -#define MTXORB_FTDI_RANGE_015C_PID 0x015C -#define MTXORB_FTDI_RANGE_015D_PID 0x015D -#define MTXORB_FTDI_RANGE_015E_PID 0x015E -#define MTXORB_FTDI_RANGE_015F_PID 0x015F -#define MTXORB_FTDI_RANGE_0160_PID 0x0160 -#define MTXORB_FTDI_RANGE_0161_PID 0x0161 -#define MTXORB_FTDI_RANGE_0162_PID 0x0162 -#define MTXORB_FTDI_RANGE_0163_PID 0x0163 -#define MTXORB_FTDI_RANGE_0164_PID 0x0164 -#define MTXORB_FTDI_RANGE_0165_PID 0x0165 -#define MTXORB_FTDI_RANGE_0166_PID 0x0166 -#define MTXORB_FTDI_RANGE_0167_PID 0x0167 -#define MTXORB_FTDI_RANGE_0168_PID 0x0168 -#define MTXORB_FTDI_RANGE_0169_PID 0x0169 -#define MTXORB_FTDI_RANGE_016A_PID 0x016A -#define MTXORB_FTDI_RANGE_016B_PID 0x016B -#define MTXORB_FTDI_RANGE_016C_PID 0x016C -#define MTXORB_FTDI_RANGE_016D_PID 0x016D -#define MTXORB_FTDI_RANGE_016E_PID 0x016E -#define MTXORB_FTDI_RANGE_016F_PID 0x016F -#define MTXORB_FTDI_RANGE_0170_PID 0x0170 -#define MTXORB_FTDI_RANGE_0171_PID 0x0171 -#define MTXORB_FTDI_RANGE_0172_PID 0x0172 -#define MTXORB_FTDI_RANGE_0173_PID 0x0173 -#define MTXORB_FTDI_RANGE_0174_PID 0x0174 -#define MTXORB_FTDI_RANGE_0175_PID 0x0175 -#define MTXORB_FTDI_RANGE_0176_PID 0x0176 -#define MTXORB_FTDI_RANGE_0177_PID 0x0177 -#define MTXORB_FTDI_RANGE_0178_PID 0x0178 -#define MTXORB_FTDI_RANGE_0179_PID 0x0179 -#define MTXORB_FTDI_RANGE_017A_PID 0x017A -#define MTXORB_FTDI_RANGE_017B_PID 0x017B -#define MTXORB_FTDI_RANGE_017C_PID 0x017C -#define MTXORB_FTDI_RANGE_017D_PID 0x017D -#define MTXORB_FTDI_RANGE_017E_PID 0x017E -#define MTXORB_FTDI_RANGE_017F_PID 0x017F -#define MTXORB_FTDI_RANGE_0180_PID 0x0180 -#define MTXORB_FTDI_RANGE_0181_PID 0x0181 -#define MTXORB_FTDI_RANGE_0182_PID 0x0182 -#define MTXORB_FTDI_RANGE_0183_PID 0x0183 -#define MTXORB_FTDI_RANGE_0184_PID 0x0184 -#define MTXORB_FTDI_RANGE_0185_PID 0x0185 -#define MTXORB_FTDI_RANGE_0186_PID 0x0186 -#define MTXORB_FTDI_RANGE_0187_PID 0x0187 -#define MTXORB_FTDI_RANGE_0188_PID 0x0188 -#define MTXORB_FTDI_RANGE_0189_PID 0x0189 -#define MTXORB_FTDI_RANGE_018A_PID 0x018A -#define MTXORB_FTDI_RANGE_018B_PID 0x018B -#define MTXORB_FTDI_RANGE_018C_PID 0x018C -#define MTXORB_FTDI_RANGE_018D_PID 0x018D -#define MTXORB_FTDI_RANGE_018E_PID 0x018E -#define MTXORB_FTDI_RANGE_018F_PID 0x018F -#define MTXORB_FTDI_RANGE_0190_PID 0x0190 -#define MTXORB_FTDI_RANGE_0191_PID 0x0191 -#define MTXORB_FTDI_RANGE_0192_PID 0x0192 -#define MTXORB_FTDI_RANGE_0193_PID 0x0193 -#define MTXORB_FTDI_RANGE_0194_PID 0x0194 -#define MTXORB_FTDI_RANGE_0195_PID 0x0195 -#define MTXORB_FTDI_RANGE_0196_PID 0x0196 -#define MTXORB_FTDI_RANGE_0197_PID 0x0197 -#define MTXORB_FTDI_RANGE_0198_PID 0x0198 -#define MTXORB_FTDI_RANGE_0199_PID 0x0199 -#define MTXORB_FTDI_RANGE_019A_PID 0x019A -#define MTXORB_FTDI_RANGE_019B_PID 0x019B -#define MTXORB_FTDI_RANGE_019C_PID 0x019C -#define MTXORB_FTDI_RANGE_019D_PID 0x019D -#define MTXORB_FTDI_RANGE_019E_PID 0x019E -#define MTXORB_FTDI_RANGE_019F_PID 0x019F -#define MTXORB_FTDI_RANGE_01A0_PID 0x01A0 -#define MTXORB_FTDI_RANGE_01A1_PID 0x01A1 -#define MTXORB_FTDI_RANGE_01A2_PID 0x01A2 -#define MTXORB_FTDI_RANGE_01A3_PID 0x01A3 -#define MTXORB_FTDI_RANGE_01A4_PID 0x01A4 -#define MTXORB_FTDI_RANGE_01A5_PID 0x01A5 -#define MTXORB_FTDI_RANGE_01A6_PID 0x01A6 -#define MTXORB_FTDI_RANGE_01A7_PID 0x01A7 -#define MTXORB_FTDI_RANGE_01A8_PID 0x01A8 -#define MTXORB_FTDI_RANGE_01A9_PID 0x01A9 -#define MTXORB_FTDI_RANGE_01AA_PID 0x01AA -#define MTXORB_FTDI_RANGE_01AB_PID 0x01AB -#define MTXORB_FTDI_RANGE_01AC_PID 0x01AC -#define MTXORB_FTDI_RANGE_01AD_PID 0x01AD -#define MTXORB_FTDI_RANGE_01AE_PID 0x01AE -#define MTXORB_FTDI_RANGE_01AF_PID 0x01AF -#define MTXORB_FTDI_RANGE_01B0_PID 0x01B0 -#define MTXORB_FTDI_RANGE_01B1_PID 0x01B1 -#define MTXORB_FTDI_RANGE_01B2_PID 0x01B2 -#define MTXORB_FTDI_RANGE_01B3_PID 0x01B3 -#define MTXORB_FTDI_RANGE_01B4_PID 0x01B4 -#define MTXORB_FTDI_RANGE_01B5_PID 0x01B5 -#define MTXORB_FTDI_RANGE_01B6_PID 0x01B6 -#define MTXORB_FTDI_RANGE_01B7_PID 0x01B7 -#define MTXORB_FTDI_RANGE_01B8_PID 0x01B8 -#define MTXORB_FTDI_RANGE_01B9_PID 0x01B9 -#define MTXORB_FTDI_RANGE_01BA_PID 0x01BA -#define MTXORB_FTDI_RANGE_01BB_PID 0x01BB -#define MTXORB_FTDI_RANGE_01BC_PID 0x01BC -#define MTXORB_FTDI_RANGE_01BD_PID 0x01BD -#define MTXORB_FTDI_RANGE_01BE_PID 0x01BE -#define MTXORB_FTDI_RANGE_01BF_PID 0x01BF -#define MTXORB_FTDI_RANGE_01C0_PID 0x01C0 -#define MTXORB_FTDI_RANGE_01C1_PID 0x01C1 -#define MTXORB_FTDI_RANGE_01C2_PID 0x01C2 -#define MTXORB_FTDI_RANGE_01C3_PID 0x01C3 -#define MTXORB_FTDI_RANGE_01C4_PID 0x01C4 -#define MTXORB_FTDI_RANGE_01C5_PID 0x01C5 -#define MTXORB_FTDI_RANGE_01C6_PID 0x01C6 -#define MTXORB_FTDI_RANGE_01C7_PID 0x01C7 -#define MTXORB_FTDI_RANGE_01C8_PID 0x01C8 -#define MTXORB_FTDI_RANGE_01C9_PID 0x01C9 -#define MTXORB_FTDI_RANGE_01CA_PID 0x01CA -#define MTXORB_FTDI_RANGE_01CB_PID 0x01CB -#define MTXORB_FTDI_RANGE_01CC_PID 0x01CC -#define MTXORB_FTDI_RANGE_01CD_PID 0x01CD -#define MTXORB_FTDI_RANGE_01CE_PID 0x01CE -#define MTXORB_FTDI_RANGE_01CF_PID 0x01CF -#define MTXORB_FTDI_RANGE_01D0_PID 0x01D0 -#define MTXORB_FTDI_RANGE_01D1_PID 0x01D1 -#define MTXORB_FTDI_RANGE_01D2_PID 0x01D2 -#define MTXORB_FTDI_RANGE_01D3_PID 0x01D3 -#define MTXORB_FTDI_RANGE_01D4_PID 0x01D4 -#define MTXORB_FTDI_RANGE_01D5_PID 0x01D5 -#define MTXORB_FTDI_RANGE_01D6_PID 0x01D6 -#define MTXORB_FTDI_RANGE_01D7_PID 0x01D7 -#define MTXORB_FTDI_RANGE_01D8_PID 0x01D8 -#define MTXORB_FTDI_RANGE_01D9_PID 0x01D9 -#define MTXORB_FTDI_RANGE_01DA_PID 0x01DA -#define MTXORB_FTDI_RANGE_01DB_PID 0x01DB -#define MTXORB_FTDI_RANGE_01DC_PID 0x01DC -#define MTXORB_FTDI_RANGE_01DD_PID 0x01DD -#define MTXORB_FTDI_RANGE_01DE_PID 0x01DE -#define MTXORB_FTDI_RANGE_01DF_PID 0x01DF -#define MTXORB_FTDI_RANGE_01E0_PID 0x01E0 -#define MTXORB_FTDI_RANGE_01E1_PID 0x01E1 -#define MTXORB_FTDI_RANGE_01E2_PID 0x01E2 -#define MTXORB_FTDI_RANGE_01E3_PID 0x01E3 -#define MTXORB_FTDI_RANGE_01E4_PID 0x01E4 -#define MTXORB_FTDI_RANGE_01E5_PID 0x01E5 -#define MTXORB_FTDI_RANGE_01E6_PID 0x01E6 -#define MTXORB_FTDI_RANGE_01E7_PID 0x01E7 -#define MTXORB_FTDI_RANGE_01E8_PID 0x01E8 -#define MTXORB_FTDI_RANGE_01E9_PID 0x01E9 -#define MTXORB_FTDI_RANGE_01EA_PID 0x01EA -#define MTXORB_FTDI_RANGE_01EB_PID 0x01EB -#define MTXORB_FTDI_RANGE_01EC_PID 0x01EC -#define MTXORB_FTDI_RANGE_01ED_PID 0x01ED -#define MTXORB_FTDI_RANGE_01EE_PID 0x01EE -#define MTXORB_FTDI_RANGE_01EF_PID 0x01EF -#define MTXORB_FTDI_RANGE_01F0_PID 0x01F0 -#define MTXORB_FTDI_RANGE_01F1_PID 0x01F1 -#define MTXORB_FTDI_RANGE_01F2_PID 0x01F2 -#define MTXORB_FTDI_RANGE_01F3_PID 0x01F3 -#define MTXORB_FTDI_RANGE_01F4_PID 0x01F4 -#define MTXORB_FTDI_RANGE_01F5_PID 0x01F5 -#define MTXORB_FTDI_RANGE_01F6_PID 0x01F6 -#define MTXORB_FTDI_RANGE_01F7_PID 0x01F7 -#define MTXORB_FTDI_RANGE_01F8_PID 0x01F8 -#define MTXORB_FTDI_RANGE_01F9_PID 0x01F9 -#define MTXORB_FTDI_RANGE_01FA_PID 0x01FA -#define MTXORB_FTDI_RANGE_01FB_PID 0x01FB -#define MTXORB_FTDI_RANGE_01FC_PID 0x01FC -#define MTXORB_FTDI_RANGE_01FD_PID 0x01FD -#define MTXORB_FTDI_RANGE_01FE_PID 0x01FE -#define MTXORB_FTDI_RANGE_01FF_PID 0x01FF - - - -/* - * The Mobility Lab (TML) - * Submitted by Pierre Castella - */ -#define TML_VID 0x1B91 /* Vendor ID */ -#define TML_USB_SERIAL_PID 0x0064 /* USB - Serial Converter */ - -/* Alti-2 products http://www.alti-2.com */ -#define ALTI2_VID 0x1BC9 -#define ALTI2_N3_PID 0x6001 /* Neptune 3 */ - -/* - * Ionics PlugComputer - */ -#define IONICS_VID 0x1c0c -#define IONICS_PLUGCOMPUTER_PID 0x0102 - -/* - * Dresden Elektronik Sensor Terminal Board - */ -#define DE_VID 0x1cf1 /* Vendor ID */ -#define STB_PID 0x0001 /* Sensor Terminal Board */ -#define WHT_PID 0x0004 /* Wireless Handheld Terminal */ - -/* - * STMicroelectonics - */ -#define ST_VID 0x0483 -#define ST_STMCLT1030_PID 0x3747 /* ST Micro Connect Lite STMCLT1030 */ - -/* - * Papouch products (http://www.papouch.com/) - * Submitted by Folkert van Heusden - */ - -#define PAPOUCH_VID 0x5050 /* Vendor ID */ -#define PAPOUCH_SB485_PID 0x0100 /* Papouch SB485 USB-485/422 Converter */ -#define PAPOUCH_AP485_PID 0x0101 /* AP485 USB-RS485 Converter */ -#define PAPOUCH_SB422_PID 0x0102 /* Papouch SB422 USB-RS422 Converter */ -#define PAPOUCH_SB485_2_PID 0x0103 /* Papouch SB485 USB-485/422 Converter */ -#define PAPOUCH_AP485_2_PID 0x0104 /* AP485 USB-RS485 Converter */ -#define PAPOUCH_SB422_2_PID 0x0105 /* Papouch SB422 USB-RS422 Converter */ -#define PAPOUCH_SB485S_PID 0x0106 /* Papouch SB485S USB-485/422 Converter */ -#define PAPOUCH_SB485C_PID 0x0107 /* Papouch SB485C USB-485/422 Converter */ -#define PAPOUCH_LEC_PID 0x0300 /* LEC USB Converter */ -#define PAPOUCH_SB232_PID 0x0301 /* Papouch SB232 USB-RS232 Converter */ -#define PAPOUCH_TMU_PID 0x0400 /* TMU USB Thermometer */ -#define PAPOUCH_IRAMP_PID 0x0500 /* Papouch IRAmp Duplex */ -#define PAPOUCH_DRAK5_PID 0x0700 /* Papouch DRAK5 */ -#define PAPOUCH_QUIDO8x8_PID 0x0800 /* Papouch Quido 8/8 Module */ -#define PAPOUCH_QUIDO4x4_PID 0x0900 /* Papouch Quido 4/4 Module */ -#define PAPOUCH_QUIDO2x2_PID 0x0a00 /* Papouch Quido 2/2 Module */ -#define PAPOUCH_QUIDO10x1_PID 0x0b00 /* Papouch Quido 10/1 Module */ -#define PAPOUCH_QUIDO30x3_PID 0x0c00 /* Papouch Quido 30/3 Module */ -#define PAPOUCH_QUIDO60x3_PID 0x0d00 /* Papouch Quido 60(100)/3 Module */ -#define PAPOUCH_QUIDO2x16_PID 0x0e00 /* Papouch Quido 2/16 Module */ -#define PAPOUCH_QUIDO3x32_PID 0x0f00 /* Papouch Quido 3/32 Module */ -#define PAPOUCH_DRAK6_PID 0x1000 /* Papouch DRAK6 */ -#define PAPOUCH_UPSUSB_PID 0x8000 /* Papouch UPS-USB adapter */ -#define PAPOUCH_MU_PID 0x8001 /* MU controller */ -#define PAPOUCH_SIMUKEY_PID 0x8002 /* Papouch SimuKey */ -#define PAPOUCH_AD4USB_PID 0x8003 /* AD4USB Measurement Module */ -#define PAPOUCH_GMUX_PID 0x8004 /* Papouch GOLIATH MUX */ -#define PAPOUCH_GMSR_PID 0x8005 /* Papouch GOLIATH MSR */ - -/* - * Marvell SheevaPlug - */ -#define MARVELL_VID 0x9e88 -#define MARVELL_SHEEVAPLUG_PID 0x9e8f - -/* - * Evolution Robotics products (http://www.evolution.com/). - * Submitted by Shawn M. Lavelle. - */ -#define EVOLUTION_VID 0xDEEE /* Vendor ID */ -#define EVOLUTION_ER1_PID 0x0300 /* ER1 Control Module */ -#define EVO_8U232AM_PID 0x02FF /* Evolution robotics RCM2 (FT232AM)*/ -#define EVO_HYBRID_PID 0x0302 /* Evolution robotics RCM4 PID (FT232BM)*/ -#define EVO_RCM4_PID 0x0303 /* Evolution robotics RCM4 PID */ - -/* - * MJS Gadgets HD Radio / XM Radio / Sirius Radio interfaces (using VID 0x0403) - */ -#define MJSG_GENERIC_PID 0x9378 -#define MJSG_SR_RADIO_PID 0x9379 -#define MJSG_XM_RADIO_PID 0x937A -#define MJSG_HD_RADIO_PID 0x937C - -/* - * D.O.Tec products (http://www.directout.eu) - */ -#define FTDI_DOTEC_PID 0x9868 - -/* - * Xverve Signalyzer tools (http://www.signalyzer.com/) - */ -#define XVERVE_SIGNALYZER_ST_PID 0xBCA0 -#define XVERVE_SIGNALYZER_SLITE_PID 0xBCA1 -#define XVERVE_SIGNALYZER_SH2_PID 0xBCA2 -#define XVERVE_SIGNALYZER_SH4_PID 0xBCA4 - -/* - * Segway Robotic Mobility Platform USB interface (using VID 0x0403) - * Submitted by John G. Rogers - */ -#define SEGWAY_RMP200_PID 0xe729 - - -/* - * Accesio USB Data Acquisition products (http://www.accesio.com/) - */ -#define ACCESIO_COM4SM_PID 0xD578 - -/* www.sciencescope.co.uk educational dataloggers */ -#define FTDI_SCIENCESCOPE_LOGBOOKML_PID 0xFF18 -#define FTDI_SCIENCESCOPE_LS_LOGBOOK_PID 0xFF1C -#define FTDI_SCIENCESCOPE_HS_LOGBOOK_PID 0xFF1D - -/* - * Milkymist One JTAG/Serial - */ -#define QIHARDWARE_VID 0x20B7 -#define MILKYMISTONE_JTAGSERIAL_PID 0x0713 - -/* - * CTI GmbH RS485 Converter http://www.cti-lean.com/ - */ -/* USB-485-Mini*/ -#define FTDI_CTI_MINI_PID 0xF608 -/* USB-Nano-485*/ -#define FTDI_CTI_NANO_PID 0xF60B - -/* - * ZeitControl cardsystems GmbH rfid-readers http://zeitconrol.de - */ -/* TagTracer MIFARE*/ -#define FTDI_ZEITCONTROL_TAGTRACE_MIFARE_PID 0xF7C0 - -/* - * Rainforest Automation - */ -/* ZigBee controller */ -#define FTDI_RF_R106 0x8A28 - -/* - * Product: HCP HIT GPRS modem - * Manufacturer: HCP d.o.o. - * ATI command output: Cinterion MC55i - */ -#define FTDI_CINTERION_MC55I_PID 0xA951 diff --git a/ANDROID_3.4.5/drivers/usb/serial/funsoft.c b/ANDROID_3.4.5/drivers/usb/serial/funsoft.c deleted file mode 100644 index 4577b360..00000000 --- a/ANDROID_3.4.5/drivers/usb/serial/funsoft.c +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Funsoft Serial USB driver - * - * Copyright (C) 2006 Greg Kroah-Hartman <gregkh@suse.de> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License version - * 2 as published by the Free Software Foundation. - */ - -#include <linux/kernel.h> -#include <linux/init.h> -#include <linux/tty.h> -#include <linux/module.h> -#include <linux/usb.h> -#include <linux/usb/serial.h> -#include <linux/uaccess.h> - -static bool debug; - -static const struct usb_device_id id_table[] = { - { USB_DEVICE(0x1404, 0xcddc) }, - { }, -}; -MODULE_DEVICE_TABLE(usb, id_table); - -static struct usb_driver funsoft_driver = { - .name = "funsoft", - .probe = usb_serial_probe, - .disconnect = usb_serial_disconnect, - .id_table = id_table, -}; - -static struct usb_serial_driver funsoft_device = { - .driver = { - .owner = THIS_MODULE, - .name = "funsoft", - }, - .id_table = id_table, - .num_ports = 1, -}; - -static struct usb_serial_driver * const serial_drivers[] = { - &funsoft_device, NULL -}; - -module_usb_serial_driver(funsoft_driver, serial_drivers); - -MODULE_LICENSE("GPL"); - -module_param(debug, bool, S_IRUGO | S_IWUSR); -MODULE_PARM_DESC(debug, "Debug enabled or not"); diff --git a/ANDROID_3.4.5/drivers/usb/serial/garmin_gps.c b/ANDROID_3.4.5/drivers/usb/serial/garmin_gps.c deleted file mode 100644 index e8eb6347..00000000 --- a/ANDROID_3.4.5/drivers/usb/serial/garmin_gps.c +++ /dev/null @@ -1,1528 +0,0 @@ -/* - * Garmin GPS driver - * - * Copyright (C) 2006-2011 Hermann Kneissel herkne@gmx.de - * - * The latest version of the driver can be found at - * http://sourceforge.net/projects/garmin-gps/ - * - * This driver has been derived from v2.1 of the visor driver. - * - * 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. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA - */ - -#include <linux/kernel.h> -#include <linux/errno.h> -#include <linux/init.h> -#include <linux/slab.h> -#include <linux/timer.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/uaccess.h> -#include <linux/atomic.h> -#include <linux/usb.h> -#include <linux/usb/serial.h> - -/* the mode to be set when the port ist opened */ -static int initial_mode = 1; - -/* debug flag */ -static bool debug; - -#define GARMIN_VENDOR_ID 0x091E - -/* - * Version Information - */ - -#define VERSION_MAJOR 0 -#define VERSION_MINOR 36 - -#define _STR(s) #s -#define _DRIVER_VERSION(a, b) "v" _STR(a) "." _STR(b) -#define DRIVER_VERSION _DRIVER_VERSION(VERSION_MAJOR, VERSION_MINOR) -#define DRIVER_AUTHOR "hermann kneissel" -#define DRIVER_DESC "garmin gps driver" - -/* error codes returned by the driver */ -#define EINVPKT 1000 /* invalid packet structure */ - - -/* size of the header of a packet using the usb protocol */ -#define GARMIN_PKTHDR_LENGTH 12 - -/* max. possible size of a packet using the serial protocol */ -#define MAX_SERIAL_PKT_SIZ (3 + 255 + 3) - -/* max. possible size of a packet with worst case stuffing */ -#define MAX_SERIAL_PKT_SIZ_STUFFED (MAX_SERIAL_PKT_SIZ + 256) - -/* size of a buffer able to hold a complete (no stuffing) packet - * (the document protocol does not contain packets with a larger - * size, but in theory a packet may be 64k+12 bytes - if in - * later protocol versions larger packet sizes occur, this value - * should be increased accordingly, so the input buffer is always - * large enough the store a complete packet inclusive header) */ -#define GPS_IN_BUFSIZ (GARMIN_PKTHDR_LENGTH+MAX_SERIAL_PKT_SIZ) - -/* size of a buffer able to hold a complete (incl. stuffing) packet */ -#define GPS_OUT_BUFSIZ (GARMIN_PKTHDR_LENGTH+MAX_SERIAL_PKT_SIZ_STUFFED) - -/* where to place the packet id of a serial packet, so we can - * prepend the usb-packet header without the need to move the - * packets data */ -#define GSP_INITIAL_OFFSET (GARMIN_PKTHDR_LENGTH-2) - -/* max. size of incoming private packets (header+1 param) */ -#define PRIVPKTSIZ (GARMIN_PKTHDR_LENGTH+4) - -#define GARMIN_LAYERID_TRANSPORT 0 -#define GARMIN_LAYERID_APPL 20 -/* our own layer-id to use for some control mechanisms */ -#define GARMIN_LAYERID_PRIVATE 0x01106E4B - -#define GARMIN_PKTID_PVT_DATA 51 -#define GARMIN_PKTID_L001_COMMAND_DATA 10 - -#define CMND_ABORT_TRANSFER 0 - -/* packet ids used in private layer */ -#define PRIV_PKTID_SET_DEBUG 1 -#define PRIV_PKTID_SET_MODE 2 -#define PRIV_PKTID_INFO_REQ 3 -#define PRIV_PKTID_INFO_RESP 4 -#define PRIV_PKTID_RESET_REQ 5 -#define PRIV_PKTID_SET_DEF_MODE 6 - - -#define ETX 0x03 -#define DLE 0x10 -#define ACK 0x06 -#define NAK 0x15 - -/* structure used to queue incoming packets */ -struct garmin_packet { - struct list_head list; - int seq; - /* the real size of the data array, always > 0 */ - int size; - __u8 data[1]; -}; - -/* structure used to keep the current state of the driver */ -struct garmin_data { - __u8 state; - __u16 flags; - __u8 mode; - __u8 count; - __u8 pkt_id; - __u32 serial_num; - struct timer_list timer; - struct usb_serial_port *port; - int seq_counter; - int insize; - int outsize; - __u8 inbuffer [GPS_IN_BUFSIZ]; /* tty -> usb */ - __u8 outbuffer[GPS_OUT_BUFSIZ]; /* usb -> tty */ - __u8 privpkt[4*6]; - spinlock_t lock; - struct list_head pktlist; -}; - - -#define STATE_NEW 0 -#define STATE_INITIAL_DELAY 1 -#define STATE_TIMEOUT 2 -#define STATE_SESSION_REQ1 3 -#define STATE_SESSION_REQ2 4 -#define STATE_ACTIVE 5 - -#define STATE_RESET 8 -#define STATE_DISCONNECTED 9 -#define STATE_WAIT_TTY_ACK 10 -#define STATE_GSP_WAIT_DATA 11 - -#define MODE_NATIVE 0 -#define MODE_GARMIN_SERIAL 1 - -/* Flags used in garmin_data.flags: */ -#define FLAGS_SESSION_REPLY_MASK 0x00C0 -#define FLAGS_SESSION_REPLY1_SEEN 0x0080 -#define FLAGS_SESSION_REPLY2_SEEN 0x0040 -#define FLAGS_BULK_IN_ACTIVE 0x0020 -#define FLAGS_BULK_IN_RESTART 0x0010 -#define FLAGS_THROTTLED 0x0008 -#define APP_REQ_SEEN 0x0004 -#define APP_RESP_SEEN 0x0002 -#define CLEAR_HALT_REQUIRED 0x0001 - -#define FLAGS_QUEUING 0x0100 -#define FLAGS_DROP_DATA 0x0800 - -#define FLAGS_GSP_SKIP 0x1000 -#define FLAGS_GSP_DLESEEN 0x2000 - - - - - - -/* function prototypes */ -static int gsp_next_packet(struct garmin_data *garmin_data_p); -static int garmin_write_bulk(struct usb_serial_port *port, - const unsigned char *buf, int count, - int dismiss_ack); - -/* some special packets to be send or received */ -static unsigned char const GARMIN_START_SESSION_REQ[] - = { 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0 }; -static unsigned char const GARMIN_START_SESSION_REPLY[] - = { 0, 0, 0, 0, 6, 0, 0, 0, 4, 0, 0, 0 }; -static unsigned char const GARMIN_BULK_IN_AVAIL_REPLY[] - = { 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0 }; -static unsigned char const GARMIN_APP_LAYER_REPLY[] - = { 0x14, 0, 0, 0 }; -static unsigned char const GARMIN_START_PVT_REQ[] - = { 20, 0, 0, 0, 10, 0, 0, 0, 2, 0, 0, 0, 49, 0 }; -static unsigned char const GARMIN_STOP_PVT_REQ[] - = { 20, 0, 0, 0, 10, 0, 0, 0, 2, 0, 0, 0, 50, 0 }; -static unsigned char const GARMIN_STOP_TRANSFER_REQ[] - = { 20, 0, 0, 0, 10, 0, 0, 0, 2, 0, 0, 0, 0, 0 }; -static unsigned char const GARMIN_STOP_TRANSFER_REQ_V2[] - = { 20, 0, 0, 0, 10, 0, 0, 0, 1, 0, 0, 0, 0 }; -static unsigned char const PRIVATE_REQ[] - = { 0x4B, 0x6E, 0x10, 0x01, 0xFF, 0, 0, 0, 0xFF, 0, 0, 0 }; - - - -static const struct usb_device_id id_table[] = { - /* the same device id seems to be used by all - usb enabled GPS devices */ - { USB_DEVICE(GARMIN_VENDOR_ID, 3) }, - { } /* Terminating entry */ -}; - -MODULE_DEVICE_TABLE(usb, id_table); - -static struct usb_driver garmin_driver = { - .name = "garmin_gps", - .probe = usb_serial_probe, - .disconnect = usb_serial_disconnect, - .id_table = id_table, -}; - - -static inline int getLayerId(const __u8 *usbPacket) -{ - return __le32_to_cpup((__le32 *)(usbPacket)); -} - -static inline int getPacketId(const __u8 *usbPacket) -{ - return __le32_to_cpup((__le32 *)(usbPacket+4)); -} - -static inline int getDataLength(const __u8 *usbPacket) -{ - return __le32_to_cpup((__le32 *)(usbPacket+8)); -} - - -/* - * check if the usb-packet in buf contains an abort-transfer command. - * (if yes, all queued data will be dropped) - */ -static inline int isAbortTrfCmnd(const unsigned char *buf) -{ - if (0 == memcmp(buf, GARMIN_STOP_TRANSFER_REQ, - sizeof(GARMIN_STOP_TRANSFER_REQ)) || - 0 == memcmp(buf, GARMIN_STOP_TRANSFER_REQ_V2, - sizeof(GARMIN_STOP_TRANSFER_REQ_V2))) - return 1; - else - return 0; -} - - - -static void send_to_tty(struct usb_serial_port *port, - char *data, unsigned int actual_length) -{ - struct tty_struct *tty = tty_port_tty_get(&port->port); - - if (tty && actual_length) { - - usb_serial_debug_data(debug, &port->dev, - __func__, actual_length, data); - - tty_insert_flip_string(tty, data, actual_length); - tty_flip_buffer_push(tty); - } - tty_kref_put(tty); -} - - -/****************************************************************************** - * packet queue handling - ******************************************************************************/ - -/* - * queue a received (usb-)packet for later processing - */ -static int pkt_add(struct garmin_data *garmin_data_p, - unsigned char *data, unsigned int data_length) -{ - int state = 0; - int result = 0; - unsigned long flags; - struct garmin_packet *pkt; - - /* process only packets containg data ... */ - if (data_length) { - pkt = kmalloc(sizeof(struct garmin_packet)+data_length, - GFP_ATOMIC); - if (pkt == NULL) { - dev_err(&garmin_data_p->port->dev, "out of memory\n"); - return 0; - } - pkt->size = data_length; - memcpy(pkt->data, data, data_length); - - spin_lock_irqsave(&garmin_data_p->lock, flags); - garmin_data_p->flags |= FLAGS_QUEUING; - result = list_empty(&garmin_data_p->pktlist); - pkt->seq = garmin_data_p->seq_counter++; - list_add_tail(&pkt->list, &garmin_data_p->pktlist); - state = garmin_data_p->state; - spin_unlock_irqrestore(&garmin_data_p->lock, flags); - - dbg("%s - added: pkt: %d - %d bytes", - __func__, pkt->seq, data_length); - - /* in serial mode, if someone is waiting for data from - the device, convert and send the next packet to tty. */ - if (result && (state == STATE_GSP_WAIT_DATA)) - gsp_next_packet(garmin_data_p); - } - return result; -} - - -/* get the next pending packet */ -static struct garmin_packet *pkt_pop(struct garmin_data *garmin_data_p) -{ - unsigned long flags; - struct garmin_packet *result = NULL; - - spin_lock_irqsave(&garmin_data_p->lock, flags); - if (!list_empty(&garmin_data_p->pktlist)) { - result = (struct garmin_packet *)garmin_data_p->pktlist.next; - list_del(&result->list); - } - spin_unlock_irqrestore(&garmin_data_p->lock, flags); - return result; -} - - -/* free up all queued data */ -static void pkt_clear(struct garmin_data *garmin_data_p) -{ - unsigned long flags; - struct garmin_packet *result = NULL; - - dbg("%s", __func__); - - spin_lock_irqsave(&garmin_data_p->lock, flags); - while (!list_empty(&garmin_data_p->pktlist)) { - result = (struct garmin_packet *)garmin_data_p->pktlist.next; - list_del(&result->list); - kfree(result); - } - spin_unlock_irqrestore(&garmin_data_p->lock, flags); -} - - -/****************************************************************************** - * garmin serial protocol handling handling - ******************************************************************************/ - -/* send an ack packet back to the tty */ -static int gsp_send_ack(struct garmin_data *garmin_data_p, __u8 pkt_id) -{ - __u8 pkt[10]; - __u8 cksum = 0; - __u8 *ptr = pkt; - unsigned l = 0; - - dbg("%s - pkt-id: 0x%X.", __func__, 0xFF & pkt_id); - - *ptr++ = DLE; - *ptr++ = ACK; - cksum += ACK; - - *ptr++ = 2; - cksum += 2; - - *ptr++ = pkt_id; - cksum += pkt_id; - - if (pkt_id == DLE) - *ptr++ = DLE; - - *ptr++ = 0; - *ptr++ = 0xFF & (-cksum); - *ptr++ = DLE; - *ptr++ = ETX; - - l = ptr-pkt; - - send_to_tty(garmin_data_p->port, pkt, l); - return 0; -} - - - -/* - * called for a complete packet received from tty layer - * - * the complete packet (pktid ... cksum) is in garmin_data_p->inbuf starting - * at GSP_INITIAL_OFFSET. - * - * count - number of bytes in the input buffer including space reserved for - * the usb header: GSP_INITIAL_OFFSET + number of bytes in packet - * (including pkt-id, data-length a. cksum) - */ -static int gsp_rec_packet(struct garmin_data *garmin_data_p, int count) -{ - unsigned long flags; - const __u8 *recpkt = garmin_data_p->inbuffer+GSP_INITIAL_OFFSET; - __le32 *usbdata = (__le32 *) garmin_data_p->inbuffer; - - int cksum = 0; - int n = 0; - int pktid = recpkt[0]; - int size = recpkt[1]; - - usb_serial_debug_data(debug, &garmin_data_p->port->dev, - __func__, count-GSP_INITIAL_OFFSET, recpkt); - - if (size != (count-GSP_INITIAL_OFFSET-3)) { - dbg("%s - invalid size, expected %d bytes, got %d", - __func__, size, (count-GSP_INITIAL_OFFSET-3)); - return -EINVPKT; - } - - cksum += *recpkt++; - cksum += *recpkt++; - - /* sanity check, remove after test ... */ - if ((__u8 *)&(usbdata[3]) != recpkt) { - dbg("%s - ptr mismatch %p - %p", - __func__, &(usbdata[4]), recpkt); - return -EINVPKT; - } - - while (n < size) { - cksum += *recpkt++; - n++; - } - - if ((0xff & (cksum + *recpkt)) != 0) { - dbg("%s - invalid checksum, expected %02x, got %02x", - __func__, 0xff & -cksum, 0xff & *recpkt); - return -EINVPKT; - } - - usbdata[0] = __cpu_to_le32(GARMIN_LAYERID_APPL); - usbdata[1] = __cpu_to_le32(pktid); - usbdata[2] = __cpu_to_le32(size); - - garmin_write_bulk(garmin_data_p->port, garmin_data_p->inbuffer, - GARMIN_PKTHDR_LENGTH+size, 0); - - /* if this was an abort-transfer command, flush all - queued data. */ - if (isAbortTrfCmnd(garmin_data_p->inbuffer)) { - spin_lock_irqsave(&garmin_data_p->lock, flags); - garmin_data_p->flags |= FLAGS_DROP_DATA; - spin_unlock_irqrestore(&garmin_data_p->lock, flags); - pkt_clear(garmin_data_p); - } - - return count; -} - - - -/* - * Called for data received from tty - * - * buf contains the data read, it may span more than one packet or even - * incomplete packets - * - * input record should be a serial-record, but it may not be complete. - * Copy it into our local buffer, until an etx is seen (or an error - * occurs). - * Once the record is complete, convert into a usb packet and send it - * to the bulk pipe, send an ack back to the tty. - * - * If the input is an ack, just send the last queued packet to the - * tty layer. - * - * if the input is an abort command, drop all queued data. - */ - -static int gsp_receive(struct garmin_data *garmin_data_p, - const unsigned char *buf, int count) -{ - unsigned long flags; - int offs = 0; - int ack_or_nak_seen = 0; - __u8 *dest; - int size; - /* dleSeen: set if last byte read was a DLE */ - int dleSeen; - /* skip: if set, skip incoming data until possible start of - * new packet - */ - int skip; - __u8 data; - - spin_lock_irqsave(&garmin_data_p->lock, flags); - dest = garmin_data_p->inbuffer; - size = garmin_data_p->insize; - dleSeen = garmin_data_p->flags & FLAGS_GSP_DLESEEN; - skip = garmin_data_p->flags & FLAGS_GSP_SKIP; - spin_unlock_irqrestore(&garmin_data_p->lock, flags); - - /* dbg("%s - dle=%d skip=%d size=%d count=%d", - __func__, dleSeen, skip, size, count); */ - - if (size == 0) - size = GSP_INITIAL_OFFSET; - - while (offs < count) { - - data = *(buf+offs); - offs++; - - if (data == DLE) { - if (skip) { /* start of a new pkt */ - skip = 0; - size = GSP_INITIAL_OFFSET; - dleSeen = 1; - } else if (dleSeen) { - dest[size++] = data; - dleSeen = 0; - } else { - dleSeen = 1; - } - } else if (data == ETX) { - if (dleSeen) { - /* packet complete */ - - data = dest[GSP_INITIAL_OFFSET]; - - if (data == ACK) { - ack_or_nak_seen = ACK; - dbg("ACK packet complete."); - } else if (data == NAK) { - ack_or_nak_seen = NAK; - dbg("NAK packet complete."); - } else { - dbg("packet complete - id=0x%X.", - 0xFF & data); - gsp_rec_packet(garmin_data_p, size); - } - - skip = 1; - size = GSP_INITIAL_OFFSET; - dleSeen = 0; - } else { - dest[size++] = data; - } - } else if (!skip) { - - if (dleSeen) { - size = GSP_INITIAL_OFFSET; - dleSeen = 0; - } - - dest[size++] = data; - } - - if (size >= GPS_IN_BUFSIZ) { - dbg("%s - packet too large.", __func__); - skip = 1; - size = GSP_INITIAL_OFFSET; - dleSeen = 0; - } - } - - spin_lock_irqsave(&garmin_data_p->lock, flags); - - garmin_data_p->insize = size; - - /* copy flags back to structure */ - if (skip) - garmin_data_p->flags |= FLAGS_GSP_SKIP; - else - garmin_data_p->flags &= ~FLAGS_GSP_SKIP; - - if (dleSeen) - garmin_data_p->flags |= FLAGS_GSP_DLESEEN; - else - garmin_data_p->flags &= ~FLAGS_GSP_DLESEEN; - - spin_unlock_irqrestore(&garmin_data_p->lock, flags); - - if (ack_or_nak_seen) { - if (gsp_next_packet(garmin_data_p) > 0) - garmin_data_p->state = STATE_ACTIVE; - else - garmin_data_p->state = STATE_GSP_WAIT_DATA; - } - return count; -} - - - -/* - * Sends a usb packet to the tty - * - * Assumes, that all packages and at an usb-packet boundary. - * - * return <0 on error, 0 if packet is incomplete or > 0 if packet was sent - */ -static int gsp_send(struct garmin_data *garmin_data_p, - const unsigned char *buf, int count) -{ - const unsigned char *src; - unsigned char *dst; - int pktid = 0; - int datalen = 0; - int cksum = 0; - int i = 0; - int k; - - dbg("%s - state %d - %d bytes.", __func__, - garmin_data_p->state, count); - - k = garmin_data_p->outsize; - if ((k+count) > GPS_OUT_BUFSIZ) { - dbg("packet too large"); - garmin_data_p->outsize = 0; - return -4; - } - - memcpy(garmin_data_p->outbuffer+k, buf, count); - k += count; - garmin_data_p->outsize = k; - - if (k >= GARMIN_PKTHDR_LENGTH) { - pktid = getPacketId(garmin_data_p->outbuffer); - datalen = getDataLength(garmin_data_p->outbuffer); - i = GARMIN_PKTHDR_LENGTH + datalen; - if (k < i) - return 0; - } else { - return 0; - } - - dbg("%s - %d bytes in buffer, %d bytes in pkt.", __func__, k, i); - - /* garmin_data_p->outbuffer now contains a complete packet */ - - usb_serial_debug_data(debug, &garmin_data_p->port->dev, - __func__, k, garmin_data_p->outbuffer); - - garmin_data_p->outsize = 0; - - if (GARMIN_LAYERID_APPL != getLayerId(garmin_data_p->outbuffer)) { - dbg("not an application packet (%d)", - getLayerId(garmin_data_p->outbuffer)); - return -1; - } - - if (pktid > 255) { - dbg("packet-id %d too large", pktid); - return -2; - } - - if (datalen > 255) { - dbg("packet-size %d too large", datalen); - return -3; - } - - /* the serial protocol should be able to handle this packet */ - - k = 0; - src = garmin_data_p->outbuffer+GARMIN_PKTHDR_LENGTH; - for (i = 0; i < datalen; i++) { - if (*src++ == DLE) - k++; - } - - src = garmin_data_p->outbuffer+GARMIN_PKTHDR_LENGTH; - if (k > (GARMIN_PKTHDR_LENGTH-2)) { - /* can't add stuffing DLEs in place, move data to end - of buffer ... */ - dst = garmin_data_p->outbuffer+GPS_OUT_BUFSIZ-datalen; - memcpy(dst, src, datalen); - src = dst; - } - - dst = garmin_data_p->outbuffer; - - *dst++ = DLE; - *dst++ = pktid; - cksum += pktid; - *dst++ = datalen; - cksum += datalen; - if (datalen == DLE) - *dst++ = DLE; - - for (i = 0; i < datalen; i++) { - __u8 c = *src++; - *dst++ = c; - cksum += c; - if (c == DLE) - *dst++ = DLE; - } - - cksum = 0xFF & -cksum; - *dst++ = cksum; - if (cksum == DLE) - *dst++ = DLE; - *dst++ = DLE; - *dst++ = ETX; - - i = dst-garmin_data_p->outbuffer; - - send_to_tty(garmin_data_p->port, garmin_data_p->outbuffer, i); - - garmin_data_p->pkt_id = pktid; - garmin_data_p->state = STATE_WAIT_TTY_ACK; - - return i; -} - - -/* - * Process the next pending data packet - if there is one - */ -static int gsp_next_packet(struct garmin_data *garmin_data_p) -{ - int result = 0; - struct garmin_packet *pkt = NULL; - - while ((pkt = pkt_pop(garmin_data_p)) != NULL) { - dbg("%s - next pkt: %d", __func__, pkt->seq); - result = gsp_send(garmin_data_p, pkt->data, pkt->size); - if (result > 0) { - kfree(pkt); - return result; - } - kfree(pkt); - } - return result; -} - - - -/****************************************************************************** - * garmin native mode - ******************************************************************************/ - - -/* - * Called for data received from tty - * - * The input data is expected to be in garmin usb-packet format. - * - * buf contains the data read, it may span more than one packet - * or even incomplete packets - */ -static int nat_receive(struct garmin_data *garmin_data_p, - const unsigned char *buf, int count) -{ - unsigned long flags; - __u8 *dest; - int offs = 0; - int result = count; - int len; - - while (offs < count) { - /* if buffer contains header, copy rest of data */ - if (garmin_data_p->insize >= GARMIN_PKTHDR_LENGTH) - len = GARMIN_PKTHDR_LENGTH - +getDataLength(garmin_data_p->inbuffer); - else - len = GARMIN_PKTHDR_LENGTH; - - if (len >= GPS_IN_BUFSIZ) { - /* seems to be an invalid packet, ignore rest - of input */ - dbg("%s - packet size too large: %d", __func__, len); - garmin_data_p->insize = 0; - count = 0; - result = -EINVPKT; - } else { - len -= garmin_data_p->insize; - if (len > (count-offs)) - len = (count-offs); - if (len > 0) { - dest = garmin_data_p->inbuffer - + garmin_data_p->insize; - memcpy(dest, buf+offs, len); - garmin_data_p->insize += len; - offs += len; - } - } - - /* do we have a complete packet ? */ - if (garmin_data_p->insize >= GARMIN_PKTHDR_LENGTH) { - len = GARMIN_PKTHDR_LENGTH+ - getDataLength(garmin_data_p->inbuffer); - if (garmin_data_p->insize >= len) { - garmin_write_bulk(garmin_data_p->port, - garmin_data_p->inbuffer, - len, 0); - garmin_data_p->insize = 0; - - /* if this was an abort-transfer command, - flush all queued data. */ - if (isAbortTrfCmnd(garmin_data_p->inbuffer)) { - spin_lock_irqsave(&garmin_data_p->lock, - flags); - garmin_data_p->flags |= FLAGS_DROP_DATA; - spin_unlock_irqrestore( - &garmin_data_p->lock, flags); - pkt_clear(garmin_data_p); - } - } - } - } - return result; -} - - -/****************************************************************************** - * private packets - ******************************************************************************/ - -static void priv_status_resp(struct usb_serial_port *port) -{ - struct garmin_data *garmin_data_p = usb_get_serial_port_data(port); - __le32 *pkt = (__le32 *)garmin_data_p->privpkt; - - pkt[0] = __cpu_to_le32(GARMIN_LAYERID_PRIVATE); - pkt[1] = __cpu_to_le32(PRIV_PKTID_INFO_RESP); - pkt[2] = __cpu_to_le32(12); - pkt[3] = __cpu_to_le32(VERSION_MAJOR << 16 | VERSION_MINOR); - pkt[4] = __cpu_to_le32(garmin_data_p->mode); - pkt[5] = __cpu_to_le32(garmin_data_p->serial_num); - - send_to_tty(port, (__u8 *)pkt, 6 * 4); -} - - -/****************************************************************************** - * Garmin specific driver functions - ******************************************************************************/ - -static int process_resetdev_request(struct usb_serial_port *port) -{ - unsigned long flags; - int status; - struct garmin_data *garmin_data_p = usb_get_serial_port_data(port); - - spin_lock_irqsave(&garmin_data_p->lock, flags); - garmin_data_p->flags &= ~(CLEAR_HALT_REQUIRED); - garmin_data_p->state = STATE_RESET; - garmin_data_p->serial_num = 0; - spin_unlock_irqrestore(&garmin_data_p->lock, flags); - - usb_kill_urb(port->interrupt_in_urb); - dbg("%s - usb_reset_device", __func__); - status = usb_reset_device(port->serial->dev); - if (status) - dbg("%s - usb_reset_device failed: %d", - __func__, status); - return status; -} - - - -/* - * clear all cached data - */ -static int garmin_clear(struct garmin_data *garmin_data_p) -{ - unsigned long flags; - int status = 0; - - /* flush all queued data */ - pkt_clear(garmin_data_p); - - spin_lock_irqsave(&garmin_data_p->lock, flags); - garmin_data_p->insize = 0; - garmin_data_p->outsize = 0; - spin_unlock_irqrestore(&garmin_data_p->lock, flags); - - return status; -} - - -static int garmin_init_session(struct usb_serial_port *port) -{ - struct usb_serial *serial = port->serial; - struct garmin_data *garmin_data_p = usb_get_serial_port_data(port); - int status = 0; - int i = 0; - - if (status == 0) { - usb_kill_urb(port->interrupt_in_urb); - - dbg("%s - adding interrupt input", __func__); - status = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL); - if (status) - dev_err(&serial->dev->dev, - "%s - failed submitting interrupt urb, error %d\n", - __func__, status); - } - - /* - * using the initialization method from gpsbabel. See comments in - * gpsbabel/jeeps/gpslibusb.c gusb_reset_toggles() - */ - if (status == 0) { - dbg("%s - starting session ...", __func__); - garmin_data_p->state = STATE_ACTIVE; - - for (i = 0; i < 3; i++) { - status = garmin_write_bulk(port, - GARMIN_START_SESSION_REQ, - sizeof(GARMIN_START_SESSION_REQ), 0); - - if (status < 0) - break; - } - - if (status > 0) - status = 0; - } - - return status; -} - - - -static int garmin_open(struct tty_struct *tty, struct usb_serial_port *port) -{ - unsigned long flags; - int status = 0; - struct garmin_data *garmin_data_p = usb_get_serial_port_data(port); - - dbg("%s - port %d", __func__, port->number); - - spin_lock_irqsave(&garmin_data_p->lock, flags); - garmin_data_p->mode = initial_mode; - garmin_data_p->count = 0; - garmin_data_p->flags &= FLAGS_SESSION_REPLY1_SEEN; - spin_unlock_irqrestore(&garmin_data_p->lock, flags); - - /* shutdown any bulk reads that might be going on */ - usb_kill_urb(port->write_urb); - usb_kill_urb(port->read_urb); - - if (garmin_data_p->state == STATE_RESET) - status = garmin_init_session(port); - - garmin_data_p->state = STATE_ACTIVE; - return status; -} - - -static void garmin_close(struct usb_serial_port *port) -{ - struct usb_serial *serial = port->serial; - struct garmin_data *garmin_data_p = usb_get_serial_port_data(port); - - dbg("%s - port %d - mode=%d state=%d flags=0x%X", __func__, - port->number, garmin_data_p->mode, - garmin_data_p->state, garmin_data_p->flags); - - if (!serial) - return; - - mutex_lock(&port->serial->disc_mutex); - - if (!port->serial->disconnected) - garmin_clear(garmin_data_p); - - /* shutdown our urbs */ - usb_kill_urb(port->read_urb); - usb_kill_urb(port->write_urb); - - /* keep reset state so we know that we must start a new session */ - if (garmin_data_p->state != STATE_RESET) - garmin_data_p->state = STATE_DISCONNECTED; - - mutex_unlock(&port->serial->disc_mutex); -} - - -static void garmin_write_bulk_callback(struct urb *urb) -{ - struct usb_serial_port *port = urb->context; - - if (port) { - struct garmin_data *garmin_data_p = - usb_get_serial_port_data(port); - - dbg("%s - port %d", __func__, port->number); - - if (GARMIN_LAYERID_APPL == getLayerId(urb->transfer_buffer)) { - - if (garmin_data_p->mode == MODE_GARMIN_SERIAL) { - gsp_send_ack(garmin_data_p, - ((__u8 *)urb->transfer_buffer)[4]); - } - } - usb_serial_port_softint(port); - } - - /* Ignore errors that resulted from garmin_write_bulk with - dismiss_ack = 1 */ - - /* free up the transfer buffer, as usb_free_urb() does not do this */ - kfree(urb->transfer_buffer); -} - - -static int garmin_write_bulk(struct usb_serial_port *port, - const unsigned char *buf, int count, - int dismiss_ack) -{ - unsigned long flags; - struct usb_serial *serial = port->serial; - struct garmin_data *garmin_data_p = usb_get_serial_port_data(port); - struct urb *urb; - unsigned char *buffer; - int status; - - dbg("%s - port %d, state %d", __func__, port->number, - garmin_data_p->state); - - spin_lock_irqsave(&garmin_data_p->lock, flags); - garmin_data_p->flags &= ~FLAGS_DROP_DATA; - spin_unlock_irqrestore(&garmin_data_p->lock, flags); - - buffer = kmalloc(count, GFP_ATOMIC); - if (!buffer) { - dev_err(&port->dev, "out of memory\n"); - return -ENOMEM; - } - - urb = usb_alloc_urb(0, GFP_ATOMIC); - if (!urb) { - dev_err(&port->dev, "no more free urbs\n"); - kfree(buffer); - return -ENOMEM; - } - - memcpy(buffer, buf, count); - - usb_serial_debug_data(debug, &port->dev, __func__, count, buffer); - - usb_fill_bulk_urb(urb, serial->dev, - usb_sndbulkpipe(serial->dev, - port->bulk_out_endpointAddress), - buffer, count, - garmin_write_bulk_callback, - dismiss_ack ? NULL : port); - urb->transfer_flags |= URB_ZERO_PACKET; - - if (GARMIN_LAYERID_APPL == getLayerId(buffer)) { - - spin_lock_irqsave(&garmin_data_p->lock, flags); - garmin_data_p->flags |= APP_REQ_SEEN; - spin_unlock_irqrestore(&garmin_data_p->lock, flags); - - if (garmin_data_p->mode == MODE_GARMIN_SERIAL) { - pkt_clear(garmin_data_p); - garmin_data_p->state = STATE_GSP_WAIT_DATA; - } - } - - /* send it down the pipe */ - status = usb_submit_urb(urb, GFP_ATOMIC); - if (status) { - dev_err(&port->dev, - "%s - usb_submit_urb(write bulk) failed with status = %d\n", - __func__, status); - count = status; - } - - /* we are done with this urb, so let the host driver - * really free it when it is finished with it */ - usb_free_urb(urb); - - return count; -} - -static int garmin_write(struct tty_struct *tty, struct usb_serial_port *port, - const unsigned char *buf, int count) -{ - int pktid, pktsiz, len; - struct garmin_data *garmin_data_p = usb_get_serial_port_data(port); - __le32 *privpkt = (__le32 *)garmin_data_p->privpkt; - - usb_serial_debug_data(debug, &port->dev, __func__, count, buf); - - if (garmin_data_p->state == STATE_RESET) - return -EIO; - - /* check for our private packets */ - if (count >= GARMIN_PKTHDR_LENGTH) { - len = PRIVPKTSIZ; - if (count < len) - len = count; - - memcpy(garmin_data_p->privpkt, buf, len); - - pktsiz = getDataLength(garmin_data_p->privpkt); - pktid = getPacketId(garmin_data_p->privpkt); - - if (count == (GARMIN_PKTHDR_LENGTH+pktsiz) - && GARMIN_LAYERID_PRIVATE == - getLayerId(garmin_data_p->privpkt)) { - - dbg("%s - processing private request %d", - __func__, pktid); - - /* drop all unfinished transfers */ - garmin_clear(garmin_data_p); - - switch (pktid) { - - case PRIV_PKTID_SET_DEBUG: - if (pktsiz != 4) - return -EINVPKT; - debug = __le32_to_cpu(privpkt[3]); - dbg("%s - debug level set to 0x%X", - __func__, debug); - break; - - case PRIV_PKTID_SET_MODE: - if (pktsiz != 4) - return -EINVPKT; - garmin_data_p->mode = __le32_to_cpu(privpkt[3]); - dbg("%s - mode set to %d", - __func__, garmin_data_p->mode); - break; - - case PRIV_PKTID_INFO_REQ: - priv_status_resp(port); - break; - - case PRIV_PKTID_RESET_REQ: - process_resetdev_request(port); - break; - - case PRIV_PKTID_SET_DEF_MODE: - if (pktsiz != 4) - return -EINVPKT; - initial_mode = __le32_to_cpu(privpkt[3]); - dbg("%s - initial_mode set to %d", - __func__, - garmin_data_p->mode); - break; - } - return count; - } - } - - if (garmin_data_p->mode == MODE_GARMIN_SERIAL) { - return gsp_receive(garmin_data_p, buf, count); - } else { /* MODE_NATIVE */ - return nat_receive(garmin_data_p, buf, count); - } -} - - -static int garmin_write_room(struct tty_struct *tty) -{ - struct usb_serial_port *port = tty->driver_data; - /* - * Report back the bytes currently available in the output buffer. - */ - struct garmin_data *garmin_data_p = usb_get_serial_port_data(port); - return GPS_OUT_BUFSIZ-garmin_data_p->outsize; -} - - -static void garmin_read_process(struct garmin_data *garmin_data_p, - unsigned char *data, unsigned data_length, - int bulk_data) -{ - unsigned long flags; - - if (garmin_data_p->flags & FLAGS_DROP_DATA) { - /* abort-transfer cmd is actice */ - dbg("%s - pkt dropped", __func__); - } else if (garmin_data_p->state != STATE_DISCONNECTED && - garmin_data_p->state != STATE_RESET) { - - /* if throttling is active or postprecessing is required - put the received data in the input queue, otherwise - send it directly to the tty port */ - if (garmin_data_p->flags & FLAGS_QUEUING) { - pkt_add(garmin_data_p, data, data_length); - } else if (bulk_data || - getLayerId(data) == GARMIN_LAYERID_APPL) { - - spin_lock_irqsave(&garmin_data_p->lock, flags); - garmin_data_p->flags |= APP_RESP_SEEN; - spin_unlock_irqrestore(&garmin_data_p->lock, flags); - - if (garmin_data_p->mode == MODE_GARMIN_SERIAL) { - pkt_add(garmin_data_p, data, data_length); - } else { - send_to_tty(garmin_data_p->port, data, - data_length); - } - } - /* ignore system layer packets ... */ - } -} - - -static void garmin_read_bulk_callback(struct urb *urb) -{ - unsigned long flags; - struct usb_serial_port *port = urb->context; - struct usb_serial *serial = port->serial; - struct garmin_data *garmin_data_p = usb_get_serial_port_data(port); - unsigned char *data = urb->transfer_buffer; - int status = urb->status; - int retval; - - dbg("%s - port %d", __func__, port->number); - - if (!serial) { - dbg("%s - bad serial pointer, exiting", __func__); - return; - } - - if (status) { - dbg("%s - nonzero read bulk status received: %d", - __func__, status); - return; - } - - usb_serial_debug_data(debug, &port->dev, - __func__, urb->actual_length, data); - - garmin_read_process(garmin_data_p, data, urb->actual_length, 1); - - if (urb->actual_length == 0 && - 0 != (garmin_data_p->flags & FLAGS_BULK_IN_RESTART)) { - spin_lock_irqsave(&garmin_data_p->lock, flags); - garmin_data_p->flags &= ~FLAGS_BULK_IN_RESTART; - spin_unlock_irqrestore(&garmin_data_p->lock, flags); - retval = usb_submit_urb(port->read_urb, GFP_ATOMIC); - if (retval) - dev_err(&port->dev, - "%s - failed resubmitting read urb, error %d\n", - __func__, retval); - } else if (urb->actual_length > 0) { - /* Continue trying to read until nothing more is received */ - if (0 == (garmin_data_p->flags & FLAGS_THROTTLED)) { - retval = usb_submit_urb(port->read_urb, GFP_ATOMIC); - if (retval) - dev_err(&port->dev, - "%s - failed resubmitting read urb, " - "error %d\n", __func__, retval); - } - } else { - dbg("%s - end of bulk data", __func__); - spin_lock_irqsave(&garmin_data_p->lock, flags); - garmin_data_p->flags &= ~FLAGS_BULK_IN_ACTIVE; - spin_unlock_irqrestore(&garmin_data_p->lock, flags); - } -} - - -static void garmin_read_int_callback(struct urb *urb) -{ - unsigned long flags; - int retval; - struct usb_serial_port *port = urb->context; - struct garmin_data *garmin_data_p = usb_get_serial_port_data(port); - unsigned char *data = urb->transfer_buffer; - int status = urb->status; - - switch (status) { - case 0: - /* success */ - break; - case -ECONNRESET: - case -ENOENT: - case -ESHUTDOWN: - /* this urb is terminated, clean up */ - dbg("%s - urb shutting down with status: %d", - __func__, status); - return; - default: - dbg("%s - nonzero urb status received: %d", - __func__, status); - return; - } - - usb_serial_debug_data(debug, &port->dev, __func__, - urb->actual_length, urb->transfer_buffer); - - if (urb->actual_length == sizeof(GARMIN_BULK_IN_AVAIL_REPLY) && - 0 == memcmp(data, GARMIN_BULK_IN_AVAIL_REPLY, - sizeof(GARMIN_BULK_IN_AVAIL_REPLY))) { - - dbg("%s - bulk data available.", __func__); - - if (0 == (garmin_data_p->flags & FLAGS_BULK_IN_ACTIVE)) { - - /* bulk data available */ - retval = usb_submit_urb(port->read_urb, GFP_ATOMIC); - if (retval) { - dev_err(&port->dev, - "%s - failed submitting read urb, error %d\n", - __func__, retval); - } else { - spin_lock_irqsave(&garmin_data_p->lock, flags); - garmin_data_p->flags |= FLAGS_BULK_IN_ACTIVE; - spin_unlock_irqrestore(&garmin_data_p->lock, - flags); - } - } else { - /* bulk-in transfer still active */ - spin_lock_irqsave(&garmin_data_p->lock, flags); - garmin_data_p->flags |= FLAGS_BULK_IN_RESTART; - spin_unlock_irqrestore(&garmin_data_p->lock, flags); - } - - } else if (urb->actual_length == (4+sizeof(GARMIN_START_SESSION_REPLY)) - && 0 == memcmp(data, GARMIN_START_SESSION_REPLY, - sizeof(GARMIN_START_SESSION_REPLY))) { - - spin_lock_irqsave(&garmin_data_p->lock, flags); - garmin_data_p->flags |= FLAGS_SESSION_REPLY1_SEEN; - spin_unlock_irqrestore(&garmin_data_p->lock, flags); - - /* save the serial number */ - garmin_data_p->serial_num = __le32_to_cpup( - (__le32 *)(data+GARMIN_PKTHDR_LENGTH)); - - dbg("%s - start-of-session reply seen - serial %u.", - __func__, garmin_data_p->serial_num); - } - - garmin_read_process(garmin_data_p, data, urb->actual_length, 0); - - retval = usb_submit_urb(urb, GFP_ATOMIC); - if (retval) - dev_err(&urb->dev->dev, - "%s - Error %d submitting interrupt urb\n", - __func__, retval); -} - - -/* - * Sends the next queued packt to the tty port (garmin native mode only) - * and then sets a timer to call itself again until all queued data - * is sent. - */ -static int garmin_flush_queue(struct garmin_data *garmin_data_p) -{ - unsigned long flags; - struct garmin_packet *pkt; - - if ((garmin_data_p->flags & FLAGS_THROTTLED) == 0) { - pkt = pkt_pop(garmin_data_p); - if (pkt != NULL) { - send_to_tty(garmin_data_p->port, pkt->data, pkt->size); - kfree(pkt); - mod_timer(&garmin_data_p->timer, (1)+jiffies); - - } else { - spin_lock_irqsave(&garmin_data_p->lock, flags); - garmin_data_p->flags &= ~FLAGS_QUEUING; - spin_unlock_irqrestore(&garmin_data_p->lock, flags); - } - } - return 0; -} - - -static void garmin_throttle(struct tty_struct *tty) -{ - struct usb_serial_port *port = tty->driver_data; - struct garmin_data *garmin_data_p = usb_get_serial_port_data(port); - - dbg("%s - port %d", __func__, port->number); - /* set flag, data received will be put into a queue - for later processing */ - spin_lock_irq(&garmin_data_p->lock); - garmin_data_p->flags |= FLAGS_QUEUING|FLAGS_THROTTLED; - spin_unlock_irq(&garmin_data_p->lock); -} - - -static void garmin_unthrottle(struct tty_struct *tty) -{ - struct usb_serial_port *port = tty->driver_data; - struct garmin_data *garmin_data_p = usb_get_serial_port_data(port); - int status; - - dbg("%s - port %d", __func__, port->number); - spin_lock_irq(&garmin_data_p->lock); - garmin_data_p->flags &= ~FLAGS_THROTTLED; - spin_unlock_irq(&garmin_data_p->lock); - - /* in native mode send queued data to tty, in - serial mode nothing needs to be done here */ - if (garmin_data_p->mode == MODE_NATIVE) - garmin_flush_queue(garmin_data_p); - - if (0 != (garmin_data_p->flags & FLAGS_BULK_IN_ACTIVE)) { - status = usb_submit_urb(port->read_urb, GFP_KERNEL); - if (status) - dev_err(&port->dev, - "%s - failed resubmitting read urb, error %d\n", - __func__, status); - } -} - -/* - * The timer is currently only used to send queued packets to - * the tty in cases where the protocol provides no own handshaking - * to initiate the transfer. - */ -static void timeout_handler(unsigned long data) -{ - struct garmin_data *garmin_data_p = (struct garmin_data *) data; - - /* send the next queued packet to the tty port */ - if (garmin_data_p->mode == MODE_NATIVE) - if (garmin_data_p->flags & FLAGS_QUEUING) - garmin_flush_queue(garmin_data_p); -} - - - -static int garmin_attach(struct usb_serial *serial) -{ - int status = 0; - struct usb_serial_port *port = serial->port[0]; - struct garmin_data *garmin_data_p = NULL; - - dbg("%s", __func__); - - garmin_data_p = kzalloc(sizeof(struct garmin_data), GFP_KERNEL); - if (garmin_data_p == NULL) { - dev_err(&port->dev, "%s - Out of memory\n", __func__); - return -ENOMEM; - } - init_timer(&garmin_data_p->timer); - spin_lock_init(&garmin_data_p->lock); - INIT_LIST_HEAD(&garmin_data_p->pktlist); - /* garmin_data_p->timer.expires = jiffies + session_timeout; */ - garmin_data_p->timer.data = (unsigned long)garmin_data_p; - garmin_data_p->timer.function = timeout_handler; - garmin_data_p->port = port; - garmin_data_p->state = 0; - garmin_data_p->flags = 0; - garmin_data_p->count = 0; - usb_set_serial_port_data(port, garmin_data_p); - - status = garmin_init_session(port); - - return status; -} - - -static void garmin_disconnect(struct usb_serial *serial) -{ - struct usb_serial_port *port = serial->port[0]; - struct garmin_data *garmin_data_p = usb_get_serial_port_data(port); - - dbg("%s", __func__); - - usb_kill_urb(port->interrupt_in_urb); - del_timer_sync(&garmin_data_p->timer); -} - - -static void garmin_release(struct usb_serial *serial) -{ - struct usb_serial_port *port = serial->port[0]; - struct garmin_data *garmin_data_p = usb_get_serial_port_data(port); - - dbg("%s", __func__); - - kfree(garmin_data_p); -} - - -/* All of the device info needed */ -static struct usb_serial_driver garmin_device = { - .driver = { - .owner = THIS_MODULE, - .name = "garmin_gps", - }, - .description = "Garmin GPS usb/tty", - .id_table = id_table, - .num_ports = 1, - .open = garmin_open, - .close = garmin_close, - .throttle = garmin_throttle, - .unthrottle = garmin_unthrottle, - .attach = garmin_attach, - .disconnect = garmin_disconnect, - .release = garmin_release, - .write = garmin_write, - .write_room = garmin_write_room, - .write_bulk_callback = garmin_write_bulk_callback, - .read_bulk_callback = garmin_read_bulk_callback, - .read_int_callback = garmin_read_int_callback, -}; - -static struct usb_serial_driver * const serial_drivers[] = { - &garmin_device, NULL -}; - -module_usb_serial_driver(garmin_driver, serial_drivers); - -MODULE_AUTHOR(DRIVER_AUTHOR); -MODULE_DESCRIPTION(DRIVER_DESC); -MODULE_LICENSE("GPL"); - -module_param(debug, bool, S_IWUSR | S_IRUGO); -MODULE_PARM_DESC(debug, "Debug enabled or not"); -module_param(initial_mode, int, S_IRUGO); -MODULE_PARM_DESC(initial_mode, "Initial mode"); diff --git a/ANDROID_3.4.5/drivers/usb/serial/generic.c b/ANDROID_3.4.5/drivers/usb/serial/generic.c deleted file mode 100644 index 664deb63..00000000 --- a/ANDROID_3.4.5/drivers/usb/serial/generic.c +++ /dev/null @@ -1,580 +0,0 @@ -/* - * USB Serial Converter Generic functions - * - * Copyright (C) 2010 - 2011 Johan Hovold (jhovold@gmail.com) - * Copyright (C) 1999 - 2002 Greg Kroah-Hartman (greg@kroah.com) - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License version - * 2 as published by the Free Software Foundation. - * - */ - -#include <linux/kernel.h> -#include <linux/errno.h> -#include <linux/slab.h> -#include <linux/sysrq.h> -#include <linux/tty.h> -#include <linux/tty_flip.h> -#include <linux/module.h> -#include <linux/moduleparam.h> -#include <linux/usb.h> -#include <linux/usb/serial.h> -#include <linux/uaccess.h> -#include <linux/kfifo.h> -#include <linux/serial.h> - -static int debug; - -#ifdef CONFIG_USB_SERIAL_GENERIC - -static int generic_probe(struct usb_interface *interface, - const struct usb_device_id *id); - -static __u16 vendor = 0x05f9; -static __u16 product = 0xffff; - -module_param(vendor, ushort, 0); -MODULE_PARM_DESC(vendor, "User specified USB idVendor"); - -module_param(product, ushort, 0); -MODULE_PARM_DESC(product, "User specified USB idProduct"); - -static struct usb_device_id generic_device_ids[2]; /* Initially all zeroes. */ - -/* we want to look at all devices, as the vendor/product id can change - * depending on the command line argument */ -static const struct usb_device_id generic_serial_ids[] = { - {.driver_info = 42}, - {} -}; - -static struct usb_driver generic_driver = { - .name = "usbserial_generic", - .probe = generic_probe, - .disconnect = usb_serial_disconnect, - .id_table = generic_serial_ids, -}; - -/* All of the device info needed for the Generic Serial Converter */ -struct usb_serial_driver usb_serial_generic_device = { - .driver = { - .owner = THIS_MODULE, - .name = "generic", - }, - .id_table = generic_device_ids, - .num_ports = 1, - .disconnect = usb_serial_generic_disconnect, - .release = usb_serial_generic_release, - .throttle = usb_serial_generic_throttle, - .unthrottle = usb_serial_generic_unthrottle, - .resume = usb_serial_generic_resume, -}; - -static struct usb_serial_driver * const serial_drivers[] = { - &usb_serial_generic_device, NULL -}; - -static int generic_probe(struct usb_interface *interface, - const struct usb_device_id *id) -{ - const struct usb_device_id *id_pattern; - - id_pattern = usb_match_id(interface, generic_device_ids); - if (id_pattern != NULL) - return usb_serial_probe(interface, id); - return -ENODEV; -} -#endif - -int usb_serial_generic_register(int _debug) -{ - int retval = 0; - - debug = _debug; -#ifdef CONFIG_USB_SERIAL_GENERIC - generic_device_ids[0].idVendor = vendor; - generic_device_ids[0].idProduct = product; - generic_device_ids[0].match_flags = - USB_DEVICE_ID_MATCH_VENDOR | USB_DEVICE_ID_MATCH_PRODUCT; - - /* register our generic driver with ourselves */ - retval = usb_serial_register_drivers(&generic_driver, serial_drivers); -#endif - return retval; -} - -void usb_serial_generic_deregister(void) -{ -#ifdef CONFIG_USB_SERIAL_GENERIC - /* remove our generic driver */ - usb_serial_deregister_drivers(&generic_driver, serial_drivers); -#endif -} - -int usb_serial_generic_open(struct tty_struct *tty, struct usb_serial_port *port) -{ - int result = 0; - unsigned long flags; - - dbg("%s - port %d", __func__, port->number); - - /* clear the throttle flags */ - spin_lock_irqsave(&port->lock, flags); - port->throttled = 0; - port->throttle_req = 0; - spin_unlock_irqrestore(&port->lock, flags); - - /* if we have a bulk endpoint, start reading from it */ - if (port->bulk_in_size) - result = usb_serial_generic_submit_read_urbs(port, GFP_KERNEL); - - return result; -} -EXPORT_SYMBOL_GPL(usb_serial_generic_open); - -static void generic_cleanup(struct usb_serial_port *port) -{ - struct usb_serial *serial = port->serial; - unsigned long flags; - int i; - - dbg("%s - port %d", __func__, port->number); - - if (serial->dev) { - /* shutdown any bulk transfers that might be going on */ - if (port->bulk_out_size) { - usb_kill_urb(port->write_urb); - for (i = 0; i < ARRAY_SIZE(port->write_urbs); ++i) - usb_kill_urb(port->write_urbs[i]); - - spin_lock_irqsave(&port->lock, flags); - kfifo_reset_out(&port->write_fifo); - spin_unlock_irqrestore(&port->lock, flags); - } - if (port->bulk_in_size) { - for (i = 0; i < ARRAY_SIZE(port->read_urbs); ++i) - usb_kill_urb(port->read_urbs[i]); - } - } -} - -void usb_serial_generic_close(struct usb_serial_port *port) -{ - dbg("%s - port %d", __func__, port->number); - generic_cleanup(port); -} -EXPORT_SYMBOL_GPL(usb_serial_generic_close); - -int usb_serial_generic_prepare_write_buffer(struct usb_serial_port *port, - void *dest, size_t size) -{ - return kfifo_out_locked(&port->write_fifo, dest, size, &port->lock); -} - -/** - * usb_serial_generic_write_start - kick off an URB write - * @port: Pointer to the &struct usb_serial_port data - * - * Returns zero on success, or a negative errno value - */ -static int usb_serial_generic_write_start(struct usb_serial_port *port) -{ - struct urb *urb; - int count, result; - unsigned long flags; - int i; - - if (test_and_set_bit_lock(USB_SERIAL_WRITE_BUSY, &port->flags)) - return 0; -retry: - spin_lock_irqsave(&port->lock, flags); - if (!port->write_urbs_free || !kfifo_len(&port->write_fifo)) { - clear_bit_unlock(USB_SERIAL_WRITE_BUSY, &port->flags); - spin_unlock_irqrestore(&port->lock, flags); - return 0; - } - i = (int)find_first_bit(&port->write_urbs_free, - ARRAY_SIZE(port->write_urbs)); - spin_unlock_irqrestore(&port->lock, flags); - - urb = port->write_urbs[i]; - count = port->serial->type->prepare_write_buffer(port, - urb->transfer_buffer, - port->bulk_out_size); - urb->transfer_buffer_length = count; - usb_serial_debug_data(debug, &port->dev, __func__, count, - urb->transfer_buffer); - spin_lock_irqsave(&port->lock, flags); - port->tx_bytes += count; - spin_unlock_irqrestore(&port->lock, flags); - - clear_bit(i, &port->write_urbs_free); - result = usb_submit_urb(urb, GFP_ATOMIC); - if (result) { - dev_err_console(port, "%s - error submitting urb: %d\n", - __func__, result); - set_bit(i, &port->write_urbs_free); - spin_lock_irqsave(&port->lock, flags); - port->tx_bytes -= count; - spin_unlock_irqrestore(&port->lock, flags); - - clear_bit_unlock(USB_SERIAL_WRITE_BUSY, &port->flags); - return result; - } - - /* Try sending off another urb, unless in irq context (in which case - * there will be no free urb). */ - if (!in_irq()) - goto retry; - - clear_bit_unlock(USB_SERIAL_WRITE_BUSY, &port->flags); - - return 0; -} - -/** - * usb_serial_generic_write - generic write function for serial USB devices - * @tty: Pointer to &struct tty_struct for the device - * @port: Pointer to the &usb_serial_port structure for the device - * @buf: Pointer to the data to write - * @count: Number of bytes to write - * - * Returns the number of characters actually written, which may be anything - * from zero to @count. If an error occurs, it returns the negative errno - * value. - */ -int usb_serial_generic_write(struct tty_struct *tty, - struct usb_serial_port *port, const unsigned char *buf, int count) -{ - int result; - - dbg("%s - port %d", __func__, port->number); - - /* only do something if we have a bulk out endpoint */ - if (!port->bulk_out_size) - return -ENODEV; - - if (!count) - return 0; - - count = kfifo_in_locked(&port->write_fifo, buf, count, &port->lock); - result = usb_serial_generic_write_start(port); - if (result) - return result; - - return count; -} -EXPORT_SYMBOL_GPL(usb_serial_generic_write); - -int usb_serial_generic_write_room(struct tty_struct *tty) -{ - struct usb_serial_port *port = tty->driver_data; - unsigned long flags; - int room; - - dbg("%s - port %d", __func__, port->number); - - if (!port->bulk_out_size) - return 0; - - spin_lock_irqsave(&port->lock, flags); - room = kfifo_avail(&port->write_fifo); - spin_unlock_irqrestore(&port->lock, flags); - - dbg("%s - returns %d", __func__, room); - return room; -} - -int usb_serial_generic_chars_in_buffer(struct tty_struct *tty) -{ - struct usb_serial_port *port = tty->driver_data; - unsigned long flags; - int chars; - - dbg("%s - port %d", __func__, port->number); - - if (!port->bulk_out_size) - return 0; - - spin_lock_irqsave(&port->lock, flags); - chars = kfifo_len(&port->write_fifo) + port->tx_bytes; - spin_unlock_irqrestore(&port->lock, flags); - - dbg("%s - returns %d", __func__, chars); - return chars; -} - -static int usb_serial_generic_submit_read_urb(struct usb_serial_port *port, - int index, gfp_t mem_flags) -{ - int res; - - if (!test_and_clear_bit(index, &port->read_urbs_free)) - return 0; - - dbg("%s - port %d, urb %d\n", __func__, port->number, index); - - res = usb_submit_urb(port->read_urbs[index], mem_flags); - if (res) { - if (res != -EPERM) { - dev_err(&port->dev, - "%s - usb_submit_urb failed: %d\n", - __func__, res); - } - set_bit(index, &port->read_urbs_free); - return res; - } - - return 0; -} - -int usb_serial_generic_submit_read_urbs(struct usb_serial_port *port, - gfp_t mem_flags) -{ - int res; - int i; - - dbg("%s - port %d", __func__, port->number); - - for (i = 0; i < ARRAY_SIZE(port->read_urbs); ++i) { - res = usb_serial_generic_submit_read_urb(port, i, mem_flags); - if (res) - goto err; - } - - return 0; -err: - for (; i >= 0; --i) - usb_kill_urb(port->read_urbs[i]); - - return res; -} -EXPORT_SYMBOL_GPL(usb_serial_generic_submit_read_urbs); - -void usb_serial_generic_process_read_urb(struct urb *urb) -{ - struct usb_serial_port *port = urb->context; - struct tty_struct *tty; - char *ch = (char *)urb->transfer_buffer; - int i; - - if (!urb->actual_length) - return; - - tty = tty_port_tty_get(&port->port); - if (!tty) - return; - - /* The per character mucking around with sysrq path it too slow for - stuff like 3G modems, so shortcircuit it in the 99.9999999% of cases - where the USB serial is not a console anyway */ - if (!port->port.console || !port->sysrq) - tty_insert_flip_string(tty, ch, urb->actual_length); - else { - for (i = 0; i < urb->actual_length; i++, ch++) { - if (!usb_serial_handle_sysrq_char(port, *ch)) - tty_insert_flip_char(tty, *ch, TTY_NORMAL); - } - } - tty_flip_buffer_push(tty); - tty_kref_put(tty); -} -EXPORT_SYMBOL_GPL(usb_serial_generic_process_read_urb); - -void usb_serial_generic_read_bulk_callback(struct urb *urb) -{ - struct usb_serial_port *port = urb->context; - unsigned char *data = urb->transfer_buffer; - unsigned long flags; - int i; - - for (i = 0; i < ARRAY_SIZE(port->read_urbs); ++i) { - if (urb == port->read_urbs[i]) - break; - } - set_bit(i, &port->read_urbs_free); - - dbg("%s - port %d, urb %d, len %d\n", __func__, port->number, i, - urb->actual_length); - if (urb->status) { - dbg("%s - non-zero urb status: %d\n", __func__, urb->status); - return; - } - - usb_serial_debug_data(debug, &port->dev, __func__, - urb->actual_length, data); - port->serial->type->process_read_urb(urb); - - /* Throttle the device if requested by tty */ - spin_lock_irqsave(&port->lock, flags); - port->throttled = port->throttle_req; - if (!port->throttled) { - spin_unlock_irqrestore(&port->lock, flags); - usb_serial_generic_submit_read_urb(port, i, GFP_ATOMIC); - } else - spin_unlock_irqrestore(&port->lock, flags); -} -EXPORT_SYMBOL_GPL(usb_serial_generic_read_bulk_callback); - -void usb_serial_generic_write_bulk_callback(struct urb *urb) -{ - unsigned long flags; - struct usb_serial_port *port = urb->context; - int status = urb->status; - int i; - - dbg("%s - port %d", __func__, port->number); - - for (i = 0; i < ARRAY_SIZE(port->write_urbs); ++i) - if (port->write_urbs[i] == urb) - break; - - spin_lock_irqsave(&port->lock, flags); - port->tx_bytes -= urb->transfer_buffer_length; - set_bit(i, &port->write_urbs_free); - spin_unlock_irqrestore(&port->lock, flags); - - if (status) { - dbg("%s - non-zero urb status: %d", __func__, status); - - spin_lock_irqsave(&port->lock, flags); - kfifo_reset_out(&port->write_fifo); - spin_unlock_irqrestore(&port->lock, flags); - } else { - usb_serial_generic_write_start(port); - } - - usb_serial_port_softint(port); -} -EXPORT_SYMBOL_GPL(usb_serial_generic_write_bulk_callback); - -void usb_serial_generic_throttle(struct tty_struct *tty) -{ - struct usb_serial_port *port = tty->driver_data; - unsigned long flags; - - dbg("%s - port %d", __func__, port->number); - - /* Set the throttle request flag. It will be picked up - * by usb_serial_generic_read_bulk_callback(). */ - spin_lock_irqsave(&port->lock, flags); - port->throttle_req = 1; - spin_unlock_irqrestore(&port->lock, flags); -} -EXPORT_SYMBOL_GPL(usb_serial_generic_throttle); - -void usb_serial_generic_unthrottle(struct tty_struct *tty) -{ - struct usb_serial_port *port = tty->driver_data; - int was_throttled; - - dbg("%s - port %d", __func__, port->number); - - /* Clear the throttle flags */ - spin_lock_irq(&port->lock); - was_throttled = port->throttled; - port->throttled = port->throttle_req = 0; - spin_unlock_irq(&port->lock); - - if (was_throttled) - usb_serial_generic_submit_read_urbs(port, GFP_KERNEL); -} -EXPORT_SYMBOL_GPL(usb_serial_generic_unthrottle); - -#ifdef CONFIG_MAGIC_SYSRQ -int usb_serial_handle_sysrq_char(struct usb_serial_port *port, unsigned int ch) -{ - if (port->sysrq && port->port.console) { - if (ch && time_before(jiffies, port->sysrq)) { - handle_sysrq(ch); - port->sysrq = 0; - return 1; - } - port->sysrq = 0; - } - return 0; -} -#else -int usb_serial_handle_sysrq_char(struct usb_serial_port *port, unsigned int ch) -{ - return 0; -} -#endif -EXPORT_SYMBOL_GPL(usb_serial_handle_sysrq_char); - -int usb_serial_handle_break(struct usb_serial_port *port) -{ - if (!port->sysrq) { - port->sysrq = jiffies + HZ*5; - return 1; - } - port->sysrq = 0; - return 0; -} -EXPORT_SYMBOL_GPL(usb_serial_handle_break); - -/** - * usb_serial_handle_dcd_change - handle a change of carrier detect state - * @port: usb_serial_port structure for the open port - * @tty: tty_struct structure for the port - * @status: new carrier detect status, nonzero if active - */ -void usb_serial_handle_dcd_change(struct usb_serial_port *usb_port, - struct tty_struct *tty, unsigned int status) -{ - struct tty_port *port = &usb_port->port; - - dbg("%s - port %d, status %d", __func__, usb_port->number, status); - - if (status) - wake_up_interruptible(&port->open_wait); - else if (tty && !C_CLOCAL(tty)) - tty_hangup(tty); -} -EXPORT_SYMBOL_GPL(usb_serial_handle_dcd_change); - -int usb_serial_generic_resume(struct usb_serial *serial) -{ - struct usb_serial_port *port; - int i, c = 0, r; - - for (i = 0; i < serial->num_ports; i++) { - port = serial->port[i]; - if (!test_bit(ASYNCB_INITIALIZED, &port->port.flags)) - continue; - - if (port->bulk_in_size) { - r = usb_serial_generic_submit_read_urbs(port, - GFP_NOIO); - if (r < 0) - c++; - } - - if (port->bulk_out_size) { - r = usb_serial_generic_write_start(port); - if (r < 0) - c++; - } - } - - return c ? -EIO : 0; -} -EXPORT_SYMBOL_GPL(usb_serial_generic_resume); - -void usb_serial_generic_disconnect(struct usb_serial *serial) -{ - int i; - - dbg("%s", __func__); - - /* stop reads and writes on all ports */ - for (i = 0; i < serial->num_ports; ++i) - generic_cleanup(serial->port[i]); -} -EXPORT_SYMBOL_GPL(usb_serial_generic_disconnect); - -void usb_serial_generic_release(struct usb_serial *serial) -{ - dbg("%s", __func__); -} diff --git a/ANDROID_3.4.5/drivers/usb/serial/hp4x.c b/ANDROID_3.4.5/drivers/usb/serial/hp4x.c deleted file mode 100644 index 2563e788..00000000 --- a/ANDROID_3.4.5/drivers/usb/serial/hp4x.c +++ /dev/null @@ -1,63 +0,0 @@ -/* - * HP4x Calculators Serial USB driver - * - * Copyright (C) 2005 Arthur Huillet (ahuillet@users.sf.net) - * Copyright (C) 2001-2005 Greg Kroah-Hartman (greg@kroah.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. - * - * See Documentation/usb/usb-serial.txt for more information on using this - * driver - */ - -#include <linux/kernel.h> -#include <linux/init.h> -#include <linux/tty.h> -#include <linux/module.h> -#include <linux/usb.h> -#include <linux/usb/serial.h> - -/* - * Version Information - */ -#define DRIVER_VERSION "v1.00" -#define DRIVER_DESC "HP4x (48/49) Generic Serial driver" - -#define HP_VENDOR_ID 0x03f0 -#define HP49GP_PRODUCT_ID 0x0121 - -static const struct usb_device_id id_table[] = { - { USB_DEVICE(HP_VENDOR_ID, HP49GP_PRODUCT_ID) }, - { } /* Terminating entry */ -}; - -MODULE_DEVICE_TABLE(usb, id_table); - -static struct usb_driver hp49gp_driver = { - .name = "hp4X", - .probe = usb_serial_probe, - .disconnect = usb_serial_disconnect, - .id_table = id_table, -}; - -static struct usb_serial_driver hp49gp_device = { - .driver = { - .owner = THIS_MODULE, - .name = "hp4X", - }, - .id_table = id_table, - .num_ports = 1, -}; - -static struct usb_serial_driver * const serial_drivers[] = { - &hp49gp_device, NULL -}; - -module_usb_serial_driver(hp49gp_driver, serial_drivers); - -MODULE_DESCRIPTION(DRIVER_DESC); -MODULE_VERSION(DRIVER_VERSION); -MODULE_LICENSE("GPL"); diff --git a/ANDROID_3.4.5/drivers/usb/serial/io_16654.h b/ANDROID_3.4.5/drivers/usb/serial/io_16654.h deleted file mode 100644 index a53abc95..00000000 --- a/ANDROID_3.4.5/drivers/usb/serial/io_16654.h +++ /dev/null @@ -1,195 +0,0 @@ -/************************************************************************ - * - * 16654.H Definitions for 16C654 UART used on EdgePorts - * - * Copyright (C) 1998 Inside Out Networks, Inc. - * 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. - * - ************************************************************************/ - -#if !defined(_16654_H) -#define _16654_H - -/************************************************************************ - * - * D e f i n e s / T y p e d e f s - * - ************************************************************************/ - - // - // UART register numbers - // Numbers 0-7 are passed to the Edgeport directly. Numbers 8 and - // above are used internally to indicate that we must enable access - // to them via LCR bit 0x80 or LCR = 0xBF. - // The register number sent to the Edgeport is then (x & 0x7). - // - // Driver must not access registers that affect operation of the - // the EdgePort firmware -- that includes THR, RHR, IER, FCR. - - -#define THR 0 // ! Transmit Holding Register (Write) -#define RDR 0 // ! Receive Holding Register (Read) -#define IER 1 // ! Interrupt Enable Register -#define FCR 2 // ! Fifo Control Register (Write) -#define ISR 2 // Interrupt Status Register (Read) -#define LCR 3 // Line Control Register -#define MCR 4 // Modem Control Register -#define LSR 5 // Line Status Register -#define MSR 6 // Modem Status Register -#define SPR 7 // ScratchPad Register -#define DLL 8 // Bank2[ 0 ] Divisor Latch LSB -#define DLM 9 // Bank2[ 1 ] Divisor Latch MSB -#define EFR 10 // Bank2[ 2 ] Extended Function Register -//efine unused 11 // Bank2[ 3 ] -#define XON1 12 // Bank2[ 4 ] Xon-1 -#define XON2 13 // Bank2[ 5 ] Xon-2 -#define XOFF1 14 // Bank2[ 6 ] Xoff-1 -#define XOFF2 15 // Bank2[ 7 ] Xoff-2 - -#define NUM_16654_REGS 16 - -#define IS_REG_2ND_BANK(x) ((x) >= 8) - - // - // Bit definitions for each register - // - -#define IER_RX 0x01 // Enable receive interrupt -#define IER_TX 0x02 // Enable transmit interrupt -#define IER_RXS 0x04 // Enable receive status interrupt -#define IER_MDM 0x08 // Enable modem status interrupt -#define IER_SLEEP 0x10 // Enable sleep mode -#define IER_XOFF 0x20 // Enable s/w flow control (XOFF) interrupt -#define IER_RTS 0x40 // Enable RTS interrupt -#define IER_CTS 0x80 // Enable CTS interrupt -#define IER_ENABLE_ALL 0xFF // Enable all ints - - -#define FCR_FIFO_EN 0x01 // Enable FIFOs -#define FCR_RXCLR 0x02 // Reset Rx FIFO -#define FCR_TXCLR 0x04 // Reset Tx FIFO -#define FCR_DMA_BLK 0x08 // Enable DMA block mode -#define FCR_TX_LEVEL_MASK 0x30 // Mask for Tx FIFO Level -#define FCR_TX_LEVEL_8 0x00 // Tx FIFO Level = 8 bytes -#define FCR_TX_LEVEL_16 0x10 // Tx FIFO Level = 16 bytes -#define FCR_TX_LEVEL_32 0x20 // Tx FIFO Level = 32 bytes -#define FCR_TX_LEVEL_56 0x30 // Tx FIFO Level = 56 bytes -#define FCR_RX_LEVEL_MASK 0xC0 // Mask for Rx FIFO Level -#define FCR_RX_LEVEL_8 0x00 // Rx FIFO Level = 8 bytes -#define FCR_RX_LEVEL_16 0x40 // Rx FIFO Level = 16 bytes -#define FCR_RX_LEVEL_56 0x80 // Rx FIFO Level = 56 bytes -#define FCR_RX_LEVEL_60 0xC0 // Rx FIFO Level = 60 bytes - - -#define ISR_INT_MDM_STATUS 0x00 // Modem status int pending -#define ISR_INT_NONE 0x01 // No interrupt pending -#define ISR_INT_TXRDY 0x02 // Tx ready int pending -#define ISR_INT_RXRDY 0x04 // Rx ready int pending -#define ISR_INT_LINE_STATUS 0x06 // Line status int pending -#define ISR_INT_RX_TIMEOUT 0x0C // Rx timeout int pending -#define ISR_INT_RX_XOFF 0x10 // Rx Xoff int pending -#define ISR_INT_RTS_CTS 0x20 // RTS/CTS change int pending -#define ISR_FIFO_ENABLED 0xC0 // Bits set if FIFOs enabled -#define ISR_INT_BITS_MASK 0x3E // Mask to isolate valid int causes - - -#define LCR_BITS_5 0x00 // 5 bits/char -#define LCR_BITS_6 0x01 // 6 bits/char -#define LCR_BITS_7 0x02 // 7 bits/char -#define LCR_BITS_8 0x03 // 8 bits/char -#define LCR_BITS_MASK 0x03 // Mask for bits/char field - -#define LCR_STOP_1 0x00 // 1 stop bit -#define LCR_STOP_1_5 0x04 // 1.5 stop bits (if 5 bits/char) -#define LCR_STOP_2 0x04 // 2 stop bits (if 6-8 bits/char) -#define LCR_STOP_MASK 0x04 // Mask for stop bits field - -#define LCR_PAR_NONE 0x00 // No parity -#define LCR_PAR_ODD 0x08 // Odd parity -#define LCR_PAR_EVEN 0x18 // Even parity -#define LCR_PAR_MARK 0x28 // Force parity bit to 1 -#define LCR_PAR_SPACE 0x38 // Force parity bit to 0 -#define LCR_PAR_MASK 0x38 // Mask for parity field - -#define LCR_SET_BREAK 0x40 // Set Break condition -#define LCR_DL_ENABLE 0x80 // Enable access to divisor latch - -#define LCR_ACCESS_EFR 0xBF // Load this value to access DLL,DLM, - // and also the '654-only registers - // EFR, XON1, XON2, XOFF1, XOFF2 - - -#define MCR_DTR 0x01 // Assert DTR -#define MCR_RTS 0x02 // Assert RTS -#define MCR_OUT1 0x04 // Loopback only: Sets state of RI -#define MCR_MASTER_IE 0x08 // Enable interrupt outputs -#define MCR_LOOPBACK 0x10 // Set internal (digital) loopback mode -#define MCR_XON_ANY 0x20 // Enable any char to exit XOFF mode -#define MCR_IR_ENABLE 0x40 // Enable IrDA functions -#define MCR_BRG_DIV_4 0x80 // Divide baud rate clk by /4 instead of /1 - - -#define LSR_RX_AVAIL 0x01 // Rx data available -#define LSR_OVER_ERR 0x02 // Rx overrun -#define LSR_PAR_ERR 0x04 // Rx parity error -#define LSR_FRM_ERR 0x08 // Rx framing error -#define LSR_BREAK 0x10 // Rx break condition detected -#define LSR_TX_EMPTY 0x20 // Tx Fifo empty -#define LSR_TX_ALL_EMPTY 0x40 // Tx Fifo and shift register empty -#define LSR_FIFO_ERR 0x80 // Rx Fifo contains at least 1 erred char - - -#define EDGEPORT_MSR_DELTA_CTS 0x01 // CTS changed from last read -#define EDGEPORT_MSR_DELTA_DSR 0x02 // DSR changed from last read -#define EDGEPORT_MSR_DELTA_RI 0x04 // RI changed from 0 -> 1 -#define EDGEPORT_MSR_DELTA_CD 0x08 // CD changed from last read -#define EDGEPORT_MSR_CTS 0x10 // Current state of CTS -#define EDGEPORT_MSR_DSR 0x20 // Current state of DSR -#define EDGEPORT_MSR_RI 0x40 // Current state of RI -#define EDGEPORT_MSR_CD 0x80 // Current state of CD - - - - // Tx Rx - //------------------------------- -#define EFR_SWFC_NONE 0x00 // None None -#define EFR_SWFC_RX1 0x02 // None XOFF1 -#define EFR_SWFC_RX2 0x01 // None XOFF2 -#define EFR_SWFC_RX12 0x03 // None XOFF1 & XOFF2 -#define EFR_SWFC_TX1 0x08 // XOFF1 None -#define EFR_SWFC_TX1_RX1 0x0a // XOFF1 XOFF1 -#define EFR_SWFC_TX1_RX2 0x09 // XOFF1 XOFF2 -#define EFR_SWFC_TX1_RX12 0x0b // XOFF1 XOFF1 & XOFF2 -#define EFR_SWFC_TX2 0x04 // XOFF2 None -#define EFR_SWFC_TX2_RX1 0x06 // XOFF2 XOFF1 -#define EFR_SWFC_TX2_RX2 0x05 // XOFF2 XOFF2 -#define EFR_SWFC_TX2_RX12 0x07 // XOFF2 XOFF1 & XOFF2 -#define EFR_SWFC_TX12 0x0c // XOFF1 & XOFF2 None -#define EFR_SWFC_TX12_RX1 0x0e // XOFF1 & XOFF2 XOFF1 -#define EFR_SWFC_TX12_RX2 0x0d // XOFF1 & XOFF2 XOFF2 -#define EFR_SWFC_TX12_RX12 0x0f // XOFF1 & XOFF2 XOFF1 & XOFF2 - -#define EFR_TX_FC_MASK 0x0c // Mask to isolate Rx flow control -#define EFR_TX_FC_NONE 0x00 // No Tx Xon/Xoff flow control -#define EFR_TX_FC_X1 0x08 // Transmit Xon1/Xoff1 -#define EFR_TX_FC_X2 0x04 // Transmit Xon2/Xoff2 -#define EFR_TX_FC_X1_2 0x0c // Transmit Xon1&2/Xoff1&2 - -#define EFR_RX_FC_MASK 0x03 // Mask to isolate Rx flow control -#define EFR_RX_FC_NONE 0x00 // No Rx Xon/Xoff flow control -#define EFR_RX_FC_X1 0x02 // Receiver compares Xon1/Xoff1 -#define EFR_RX_FC_X2 0x01 // Receiver compares Xon2/Xoff2 -#define EFR_RX_FC_X1_2 0x03 // Receiver compares Xon1&2/Xoff1&2 - - -#define EFR_SWFC_MASK 0x0F // Mask for software flow control field -#define EFR_ENABLE_16654 0x10 // Enable 16C654 features -#define EFR_SPEC_DETECT 0x20 // Enable special character detect interrupt -#define EFR_AUTO_RTS 0x40 // Use RTS for Rx flow control -#define EFR_AUTO_CTS 0x80 // Use CTS for Tx flow control - -#endif // if !defined(_16654_H) - diff --git a/ANDROID_3.4.5/drivers/usb/serial/io_edgeport.c b/ANDROID_3.4.5/drivers/usb/serial/io_edgeport.c deleted file mode 100644 index 323e8723..00000000 --- a/ANDROID_3.4.5/drivers/usb/serial/io_edgeport.c +++ /dev/null @@ -1,3195 +0,0 @@ -/* - * Edgeport USB Serial Converter driver - * - * Copyright (C) 2000 Inside Out Networks, All rights reserved. - * Copyright (C) 2001-2002 Greg Kroah-Hartman <greg@kroah.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. - * - * Supports the following devices: - * Edgeport/4 - * Edgeport/4t - * Edgeport/2 - * Edgeport/4i - * Edgeport/2i - * Edgeport/421 - * Edgeport/21 - * Rapidport/4 - * Edgeport/8 - * Edgeport/2D8 - * Edgeport/4D8 - * Edgeport/8i - * - * For questions or problems with this driver, contact Inside Out - * Networks technical support, or Peter Berger <pberger@brimson.com>, - * or Al Borchers <alborchers@steinerpoint.com>. - * - */ - -#include <linux/kernel.h> -#include <linux/jiffies.h> -#include <linux/errno.h> -#include <linux/init.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/serial.h> -#include <linux/ioctl.h> -#include <linux/wait.h> -#include <linux/firmware.h> -#include <linux/ihex.h> -#include <linux/uaccess.h> -#include <linux/usb.h> -#include <linux/usb/serial.h> -#include "io_edgeport.h" -#include "io_ionsp.h" /* info for the iosp messages */ -#include "io_16654.h" /* 16654 UART defines */ - -/* - * Version Information - */ -#define DRIVER_VERSION "v2.7" -#define DRIVER_AUTHOR "Greg Kroah-Hartman <greg@kroah.com> and David Iacovelli" -#define DRIVER_DESC "Edgeport USB Serial Driver" - -#define MAX_NAME_LEN 64 - -#define CHASE_TIMEOUT (5*HZ) /* 5 seconds */ -#define OPEN_TIMEOUT (5*HZ) /* 5 seconds */ -#define COMMAND_TIMEOUT (5*HZ) /* 5 seconds */ - -/* receive port state */ -enum RXSTATE { - EXPECT_HDR1 = 0, /* Expect header byte 1 */ - EXPECT_HDR2 = 1, /* Expect header byte 2 */ - EXPECT_DATA = 2, /* Expect 'RxBytesRemaining' data */ - EXPECT_HDR3 = 3, /* Expect header byte 3 (for status hdrs only) */ -}; - - -/* Transmit Fifo - * This Transmit queue is an extension of the edgeport Rx buffer. - * The maximum amount of data buffered in both the edgeport - * Rx buffer (maxTxCredits) and this buffer will never exceed maxTxCredits. - */ -struct TxFifo { - unsigned int head; /* index to head pointer (write) */ - unsigned int tail; /* index to tail pointer (read) */ - unsigned int count; /* Bytes in queue */ - unsigned int size; /* Max size of queue (equal to Max number of TxCredits) */ - unsigned char *fifo; /* allocated Buffer */ -}; - -/* This structure holds all of the local port information */ -struct edgeport_port { - __u16 txCredits; /* our current credits for this port */ - __u16 maxTxCredits; /* the max size of the port */ - - struct TxFifo txfifo; /* transmit fifo -- size will be maxTxCredits */ - struct urb *write_urb; /* write URB for this port */ - bool write_in_progress; /* 'true' while a write URB is outstanding */ - spinlock_t ep_lock; - - __u8 shadowLCR; /* last LCR value received */ - __u8 shadowMCR; /* last MCR value received */ - __u8 shadowMSR; /* last MSR value received */ - __u8 shadowLSR; /* last LSR value received */ - __u8 shadowXonChar; /* last value set as XON char in Edgeport */ - __u8 shadowXoffChar; /* last value set as XOFF char in Edgeport */ - __u8 validDataMask; - __u32 baudRate; - - bool open; - bool openPending; - bool commandPending; - bool closePending; - bool chaseResponsePending; - - wait_queue_head_t wait_chase; /* for handling sleeping while waiting for chase to finish */ - wait_queue_head_t wait_open; /* for handling sleeping while waiting for open to finish */ - wait_queue_head_t wait_command; /* for handling sleeping while waiting for command to finish */ - wait_queue_head_t delta_msr_wait; /* for handling sleeping while waiting for msr change to happen */ - - struct async_icount icount; - struct usb_serial_port *port; /* loop back to the owner of this object */ -}; - - -/* This structure holds all of the individual device information */ -struct edgeport_serial { - char name[MAX_NAME_LEN+2]; /* string name of this device */ - - struct edge_manuf_descriptor manuf_descriptor; /* the manufacturer descriptor */ - struct edge_boot_descriptor boot_descriptor; /* the boot firmware descriptor */ - struct edgeport_product_info product_info; /* Product Info */ - struct edge_compatibility_descriptor epic_descriptor; /* Edgeport compatible descriptor */ - int is_epic; /* flag if EPiC device or not */ - - __u8 interrupt_in_endpoint; /* the interrupt endpoint handle */ - unsigned char *interrupt_in_buffer; /* the buffer we use for the interrupt endpoint */ - struct urb *interrupt_read_urb; /* our interrupt urb */ - - __u8 bulk_in_endpoint; /* the bulk in endpoint handle */ - unsigned char *bulk_in_buffer; /* the buffer we use for the bulk in endpoint */ - struct urb *read_urb; /* our bulk read urb */ - bool read_in_progress; - spinlock_t es_lock; - - __u8 bulk_out_endpoint; /* the bulk out endpoint handle */ - - __s16 rxBytesAvail; /* the number of bytes that we need to read from this device */ - - enum RXSTATE rxState; /* the current state of the bulk receive processor */ - __u8 rxHeader1; /* receive header byte 1 */ - __u8 rxHeader2; /* receive header byte 2 */ - __u8 rxHeader3; /* receive header byte 3 */ - __u8 rxPort; /* the port that we are currently receiving data for */ - __u8 rxStatusCode; /* the receive status code */ - __u8 rxStatusParam; /* the receive status paramater */ - __s16 rxBytesRemaining; /* the number of port bytes left to read */ - struct usb_serial *serial; /* loop back to the owner of this object */ -}; - -/* baud rate information */ -struct divisor_table_entry { - __u32 BaudRate; - __u16 Divisor; -}; - -/* - * Define table of divisors for Rev A EdgePort/4 hardware - * These assume a 3.6864MHz crystal, the standard /16, and - * MCR.7 = 0. - */ - -static const struct divisor_table_entry divisor_table[] = { - { 50, 4608}, - { 75, 3072}, - { 110, 2095}, /* 2094.545455 => 230450 => .0217 % over */ - { 134, 1713}, /* 1713.011152 => 230398.5 => .00065% under */ - { 150, 1536}, - { 300, 768}, - { 600, 384}, - { 1200, 192}, - { 1800, 128}, - { 2400, 96}, - { 4800, 48}, - { 7200, 32}, - { 9600, 24}, - { 14400, 16}, - { 19200, 12}, - { 38400, 6}, - { 57600, 4}, - { 115200, 2}, - { 230400, 1}, -}; - -/* local variables */ -static bool debug; - -/* Number of outstanding Command Write Urbs */ -static atomic_t CmdUrbs = ATOMIC_INIT(0); - - -/* local function prototypes */ - -/* function prototypes for all URB callbacks */ -static void edge_interrupt_callback(struct urb *urb); -static void edge_bulk_in_callback(struct urb *urb); -static void edge_bulk_out_data_callback(struct urb *urb); -static void edge_bulk_out_cmd_callback(struct urb *urb); - -/* function prototypes for the usbserial callbacks */ -static int edge_open(struct tty_struct *tty, struct usb_serial_port *port); -static void edge_close(struct usb_serial_port *port); -static int edge_write(struct tty_struct *tty, struct usb_serial_port *port, - const unsigned char *buf, int count); -static int edge_write_room(struct tty_struct *tty); -static int edge_chars_in_buffer(struct tty_struct *tty); -static void edge_throttle(struct tty_struct *tty); -static void edge_unthrottle(struct tty_struct *tty); -static void edge_set_termios(struct tty_struct *tty, - struct usb_serial_port *port, - struct ktermios *old_termios); -static int edge_ioctl(struct tty_struct *tty, - unsigned int cmd, unsigned long arg); -static void edge_break(struct tty_struct *tty, int break_state); -static int edge_tiocmget(struct tty_struct *tty); -static int edge_tiocmset(struct tty_struct *tty, - unsigned int set, unsigned int clear); -static int edge_get_icount(struct tty_struct *tty, - struct serial_icounter_struct *icount); -static int edge_startup(struct usb_serial *serial); -static void edge_disconnect(struct usb_serial *serial); -static void edge_release(struct usb_serial *serial); - -#include "io_tables.h" /* all of the devices that this driver supports */ - -/* function prototypes for all of our local functions */ - -static void process_rcvd_data(struct edgeport_serial *edge_serial, - unsigned char *buffer, __u16 bufferLength); -static void process_rcvd_status(struct edgeport_serial *edge_serial, - __u8 byte2, __u8 byte3); -static void edge_tty_recv(struct device *dev, struct tty_struct *tty, - unsigned char *data, int length); -static void handle_new_msr(struct edgeport_port *edge_port, __u8 newMsr); -static void handle_new_lsr(struct edgeport_port *edge_port, __u8 lsrData, - __u8 lsr, __u8 data); -static int send_iosp_ext_cmd(struct edgeport_port *edge_port, __u8 command, - __u8 param); -static int calc_baud_rate_divisor(int baud_rate, int *divisor); -static int send_cmd_write_baud_rate(struct edgeport_port *edge_port, - int baudRate); -static void change_port_settings(struct tty_struct *tty, - struct edgeport_port *edge_port, - struct ktermios *old_termios); -static int send_cmd_write_uart_register(struct edgeport_port *edge_port, - __u8 regNum, __u8 regValue); -static int write_cmd_usb(struct edgeport_port *edge_port, - unsigned char *buffer, int writeLength); -static void send_more_port_data(struct edgeport_serial *edge_serial, - struct edgeport_port *edge_port); - -static int sram_write(struct usb_serial *serial, __u16 extAddr, __u16 addr, - __u16 length, const __u8 *data); -static int rom_read(struct usb_serial *serial, __u16 extAddr, __u16 addr, - __u16 length, __u8 *data); -static int rom_write(struct usb_serial *serial, __u16 extAddr, __u16 addr, - __u16 length, const __u8 *data); -static void get_manufacturing_desc(struct edgeport_serial *edge_serial); -static void get_boot_desc(struct edgeport_serial *edge_serial); -static void load_application_firmware(struct edgeport_serial *edge_serial); - -static void unicode_to_ascii(char *string, int buflen, - __le16 *unicode, int unicode_size); - - -/* ************************************************************************ */ -/* ************************************************************************ */ -/* ************************************************************************ */ -/* ************************************************************************ */ - -/************************************************************************ - * * - * update_edgeport_E2PROM() Compare current versions of * - * Boot ROM and Manufacture * - * Descriptors with versions * - * embedded in this driver * - * * - ************************************************************************/ -static void update_edgeport_E2PROM(struct edgeport_serial *edge_serial) -{ - __u32 BootCurVer; - __u32 BootNewVer; - __u8 BootMajorVersion; - __u8 BootMinorVersion; - __u16 BootBuildNumber; - __u32 Bootaddr; - const struct ihex_binrec *rec; - const struct firmware *fw; - const char *fw_name; - int response; - - switch (edge_serial->product_info.iDownloadFile) { - case EDGE_DOWNLOAD_FILE_I930: - fw_name = "edgeport/boot.fw"; - break; - case EDGE_DOWNLOAD_FILE_80251: - fw_name = "edgeport/boot2.fw"; - break; - default: - return; - } - - response = request_ihex_firmware(&fw, fw_name, - &edge_serial->serial->dev->dev); - if (response) { - printk(KERN_ERR "Failed to load image \"%s\" err %d\n", - fw_name, response); - return; - } - - rec = (const struct ihex_binrec *)fw->data; - BootMajorVersion = rec->data[0]; - BootMinorVersion = rec->data[1]; - BootBuildNumber = (rec->data[2] << 8) | rec->data[3]; - - /* Check Boot Image Version */ - BootCurVer = (edge_serial->boot_descriptor.MajorVersion << 24) + - (edge_serial->boot_descriptor.MinorVersion << 16) + - le16_to_cpu(edge_serial->boot_descriptor.BuildNumber); - - BootNewVer = (BootMajorVersion << 24) + - (BootMinorVersion << 16) + - BootBuildNumber; - - dbg("Current Boot Image version %d.%d.%d", - edge_serial->boot_descriptor.MajorVersion, - edge_serial->boot_descriptor.MinorVersion, - le16_to_cpu(edge_serial->boot_descriptor.BuildNumber)); - - - if (BootNewVer > BootCurVer) { - dbg("**Update Boot Image from %d.%d.%d to %d.%d.%d", - edge_serial->boot_descriptor.MajorVersion, - edge_serial->boot_descriptor.MinorVersion, - le16_to_cpu(edge_serial->boot_descriptor.BuildNumber), - BootMajorVersion, BootMinorVersion, BootBuildNumber); - - dbg("Downloading new Boot Image"); - - for (rec = ihex_next_binrec(rec); rec; - rec = ihex_next_binrec(rec)) { - Bootaddr = be32_to_cpu(rec->addr); - response = rom_write(edge_serial->serial, - Bootaddr >> 16, - Bootaddr & 0xFFFF, - be16_to_cpu(rec->len), - &rec->data[0]); - if (response < 0) { - dev_err(&edge_serial->serial->dev->dev, - "rom_write failed (%x, %x, %d)\n", - Bootaddr >> 16, Bootaddr & 0xFFFF, - be16_to_cpu(rec->len)); - break; - } - } - } else { - dbg("Boot Image -- already up to date"); - } - release_firmware(fw); -} - -#if 0 -/************************************************************************ - * - * Get string descriptor from device - * - ************************************************************************/ -static int get_string_desc(struct usb_device *dev, int Id, - struct usb_string_descriptor **pRetDesc) -{ - struct usb_string_descriptor StringDesc; - struct usb_string_descriptor *pStringDesc; - - dbg("%s - USB String ID = %d", __func__, Id); - - if (!usb_get_descriptor(dev, USB_DT_STRING, Id, &StringDesc, - sizeof(StringDesc))) - return 0; - - pStringDesc = kmalloc(StringDesc.bLength, GFP_KERNEL); - if (!pStringDesc) - return -1; - - if (!usb_get_descriptor(dev, USB_DT_STRING, Id, pStringDesc, - StringDesc.bLength)) { - kfree(pStringDesc); - return -1; - } - - *pRetDesc = pStringDesc; - return 0; -} -#endif - -static void dump_product_info(struct edgeport_product_info *product_info) -{ - /* Dump Product Info structure */ - dbg("**Product Information:"); - dbg(" ProductId %x", product_info->ProductId); - dbg(" NumPorts %d", product_info->NumPorts); - dbg(" ProdInfoVer %d", product_info->ProdInfoVer); - dbg(" IsServer %d", product_info->IsServer); - dbg(" IsRS232 %d", product_info->IsRS232); - dbg(" IsRS422 %d", product_info->IsRS422); - dbg(" IsRS485 %d", product_info->IsRS485); - dbg(" RomSize %d", product_info->RomSize); - dbg(" RamSize %d", product_info->RamSize); - dbg(" CpuRev %x", product_info->CpuRev); - dbg(" BoardRev %x", product_info->BoardRev); - dbg(" BootMajorVersion %d.%d.%d", product_info->BootMajorVersion, - product_info->BootMinorVersion, - le16_to_cpu(product_info->BootBuildNumber)); - dbg(" FirmwareMajorVersion %d.%d.%d", - product_info->FirmwareMajorVersion, - product_info->FirmwareMinorVersion, - le16_to_cpu(product_info->FirmwareBuildNumber)); - dbg(" ManufactureDescDate %d/%d/%d", - product_info->ManufactureDescDate[0], - product_info->ManufactureDescDate[1], - product_info->ManufactureDescDate[2]+1900); - dbg(" iDownloadFile 0x%x", product_info->iDownloadFile); - dbg(" EpicVer %d", product_info->EpicVer); -} - -static void get_product_info(struct edgeport_serial *edge_serial) -{ - struct edgeport_product_info *product_info = &edge_serial->product_info; - - memset(product_info, 0, sizeof(struct edgeport_product_info)); - - product_info->ProductId = (__u16)(le16_to_cpu(edge_serial->serial->dev->descriptor.idProduct) & ~ION_DEVICE_ID_80251_NETCHIP); - product_info->NumPorts = edge_serial->manuf_descriptor.NumPorts; - product_info->ProdInfoVer = 0; - - product_info->RomSize = edge_serial->manuf_descriptor.RomSize; - product_info->RamSize = edge_serial->manuf_descriptor.RamSize; - product_info->CpuRev = edge_serial->manuf_descriptor.CpuRev; - product_info->BoardRev = edge_serial->manuf_descriptor.BoardRev; - - product_info->BootMajorVersion = - edge_serial->boot_descriptor.MajorVersion; - product_info->BootMinorVersion = - edge_serial->boot_descriptor.MinorVersion; - product_info->BootBuildNumber = - edge_serial->boot_descriptor.BuildNumber; - - memcpy(product_info->ManufactureDescDate, - edge_serial->manuf_descriptor.DescDate, - sizeof(edge_serial->manuf_descriptor.DescDate)); - - /* check if this is 2nd generation hardware */ - if (le16_to_cpu(edge_serial->serial->dev->descriptor.idProduct) - & ION_DEVICE_ID_80251_NETCHIP) - product_info->iDownloadFile = EDGE_DOWNLOAD_FILE_80251; - else - product_info->iDownloadFile = EDGE_DOWNLOAD_FILE_I930; - - /* Determine Product type and set appropriate flags */ - switch (DEVICE_ID_FROM_USB_PRODUCT_ID(product_info->ProductId)) { - case ION_DEVICE_ID_EDGEPORT_COMPATIBLE: - case ION_DEVICE_ID_EDGEPORT_4T: - case ION_DEVICE_ID_EDGEPORT_4: - case ION_DEVICE_ID_EDGEPORT_2: - case ION_DEVICE_ID_EDGEPORT_8_DUAL_CPU: - case ION_DEVICE_ID_EDGEPORT_8: - case ION_DEVICE_ID_EDGEPORT_421: - case ION_DEVICE_ID_EDGEPORT_21: - case ION_DEVICE_ID_EDGEPORT_2_DIN: - case ION_DEVICE_ID_EDGEPORT_4_DIN: - case ION_DEVICE_ID_EDGEPORT_16_DUAL_CPU: - product_info->IsRS232 = 1; - break; - - case ION_DEVICE_ID_EDGEPORT_2I: /* Edgeport/2 RS422/RS485 */ - product_info->IsRS422 = 1; - product_info->IsRS485 = 1; - break; - - case ION_DEVICE_ID_EDGEPORT_8I: /* Edgeport/4 RS422 */ - case ION_DEVICE_ID_EDGEPORT_4I: /* Edgeport/4 RS422 */ - product_info->IsRS422 = 1; - break; - } - - dump_product_info(product_info); -} - -static int get_epic_descriptor(struct edgeport_serial *ep) -{ - int result; - struct usb_serial *serial = ep->serial; - struct edgeport_product_info *product_info = &ep->product_info; - struct edge_compatibility_descriptor *epic = &ep->epic_descriptor; - struct edge_compatibility_bits *bits; - - ep->is_epic = 0; - result = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0), - USB_REQUEST_ION_GET_EPIC_DESC, - 0xC0, 0x00, 0x00, - &ep->epic_descriptor, - sizeof(struct edge_compatibility_descriptor), - 300); - - dbg("%s result = %d", __func__, result); - - if (result > 0) { - ep->is_epic = 1; - memset(product_info, 0, sizeof(struct edgeport_product_info)); - - product_info->NumPorts = epic->NumPorts; - product_info->ProdInfoVer = 0; - product_info->FirmwareMajorVersion = epic->MajorVersion; - product_info->FirmwareMinorVersion = epic->MinorVersion; - product_info->FirmwareBuildNumber = epic->BuildNumber; - product_info->iDownloadFile = epic->iDownloadFile; - product_info->EpicVer = epic->EpicVer; - product_info->Epic = epic->Supports; - product_info->ProductId = ION_DEVICE_ID_EDGEPORT_COMPATIBLE; - dump_product_info(product_info); - - bits = &ep->epic_descriptor.Supports; - dbg("**EPIC descriptor:"); - dbg(" VendEnableSuspend: %s", bits->VendEnableSuspend ? "TRUE": "FALSE"); - dbg(" IOSPOpen : %s", bits->IOSPOpen ? "TRUE": "FALSE"); - dbg(" IOSPClose : %s", bits->IOSPClose ? "TRUE": "FALSE"); - dbg(" IOSPChase : %s", bits->IOSPChase ? "TRUE": "FALSE"); - dbg(" IOSPSetRxFlow : %s", bits->IOSPSetRxFlow ? "TRUE": "FALSE"); - dbg(" IOSPSetTxFlow : %s", bits->IOSPSetTxFlow ? "TRUE": "FALSE"); - dbg(" IOSPSetXChar : %s", bits->IOSPSetXChar ? "TRUE": "FALSE"); - dbg(" IOSPRxCheck : %s", bits->IOSPRxCheck ? "TRUE": "FALSE"); - dbg(" IOSPSetClrBreak : %s", bits->IOSPSetClrBreak ? "TRUE": "FALSE"); - dbg(" IOSPWriteMCR : %s", bits->IOSPWriteMCR ? "TRUE": "FALSE"); - dbg(" IOSPWriteLCR : %s", bits->IOSPWriteLCR ? "TRUE": "FALSE"); - dbg(" IOSPSetBaudRate : %s", bits->IOSPSetBaudRate ? "TRUE": "FALSE"); - dbg(" TrueEdgeport : %s", bits->TrueEdgeport ? "TRUE": "FALSE"); - } - - return result; -} - - -/************************************************************************/ -/************************************************************************/ -/* U S B C A L L B A C K F U N C T I O N S */ -/* U S B C A L L B A C K F U N C T I O N S */ -/************************************************************************/ -/************************************************************************/ - -/***************************************************************************** - * edge_interrupt_callback - * this is the callback function for when we have received data on the - * interrupt endpoint. - *****************************************************************************/ -static void edge_interrupt_callback(struct urb *urb) -{ - struct edgeport_serial *edge_serial = urb->context; - struct edgeport_port *edge_port; - struct usb_serial_port *port; - struct tty_struct *tty; - unsigned char *data = urb->transfer_buffer; - int length = urb->actual_length; - int bytes_avail; - int position; - int txCredits; - int portNumber; - int result; - int status = urb->status; - - dbg("%s", __func__); - - switch (status) { - case 0: - /* success */ - break; - case -ECONNRESET: - case -ENOENT: - case -ESHUTDOWN: - /* this urb is terminated, clean up */ - dbg("%s - urb shutting down with status: %d", - __func__, status); - return; - default: - dbg("%s - nonzero urb status received: %d", __func__, status); - goto exit; - } - - /* process this interrupt-read even if there are no ports open */ - if (length) { - usb_serial_debug_data(debug, &edge_serial->serial->dev->dev, - __func__, length, data); - - if (length > 1) { - bytes_avail = data[0] | (data[1] << 8); - if (bytes_avail) { - spin_lock(&edge_serial->es_lock); - edge_serial->rxBytesAvail += bytes_avail; - dbg("%s - bytes_avail=%d, rxBytesAvail=%d, read_in_progress=%d", __func__, bytes_avail, edge_serial->rxBytesAvail, edge_serial->read_in_progress); - - if (edge_serial->rxBytesAvail > 0 && - !edge_serial->read_in_progress) { - dbg("%s - posting a read", __func__); - edge_serial->read_in_progress = true; - - /* we have pending bytes on the - bulk in pipe, send a request */ - result = usb_submit_urb(edge_serial->read_urb, GFP_ATOMIC); - if (result) { - dev_err(&edge_serial->serial->dev->dev, "%s - usb_submit_urb(read bulk) failed with result = %d\n", __func__, result); - edge_serial->read_in_progress = false; - } - } - spin_unlock(&edge_serial->es_lock); - } - } - /* grab the txcredits for the ports if available */ - position = 2; - portNumber = 0; - while ((position < length) && - (portNumber < edge_serial->serial->num_ports)) { - txCredits = data[position] | (data[position+1] << 8); - if (txCredits) { - port = edge_serial->serial->port[portNumber]; - edge_port = usb_get_serial_port_data(port); - if (edge_port->open) { - spin_lock(&edge_port->ep_lock); - edge_port->txCredits += txCredits; - spin_unlock(&edge_port->ep_lock); - dbg("%s - txcredits for port%d = %d", - __func__, portNumber, - edge_port->txCredits); - - /* tell the tty driver that something - has changed */ - tty = tty_port_tty_get( - &edge_port->port->port); - if (tty) { - tty_wakeup(tty); - tty_kref_put(tty); - } - /* Since we have more credit, check - if more data can be sent */ - send_more_port_data(edge_serial, - edge_port); - } - } - position += 2; - ++portNumber; - } - } - -exit: - result = usb_submit_urb(urb, GFP_ATOMIC); - if (result) - dev_err(&urb->dev->dev, - "%s - Error %d submitting control urb\n", - __func__, result); -} - - -/***************************************************************************** - * edge_bulk_in_callback - * this is the callback function for when we have received data on the - * bulk in endpoint. - *****************************************************************************/ -static void edge_bulk_in_callback(struct urb *urb) -{ - struct edgeport_serial *edge_serial = urb->context; - unsigned char *data = urb->transfer_buffer; - int retval; - __u16 raw_data_length; - int status = urb->status; - - dbg("%s", __func__); - - if (status) { - dbg("%s - nonzero read bulk status received: %d", - __func__, status); - edge_serial->read_in_progress = false; - return; - } - - if (urb->actual_length == 0) { - dbg("%s - read bulk callback with no data", __func__); - edge_serial->read_in_progress = false; - return; - } - - raw_data_length = urb->actual_length; - - usb_serial_debug_data(debug, &edge_serial->serial->dev->dev, - __func__, raw_data_length, data); - - spin_lock(&edge_serial->es_lock); - - /* decrement our rxBytes available by the number that we just got */ - edge_serial->rxBytesAvail -= raw_data_length; - - dbg("%s - Received = %d, rxBytesAvail %d", __func__, - raw_data_length, edge_serial->rxBytesAvail); - - process_rcvd_data(edge_serial, data, urb->actual_length); - - /* check to see if there's any more data for us to read */ - if (edge_serial->rxBytesAvail > 0) { - dbg("%s - posting a read", __func__); - retval = usb_submit_urb(edge_serial->read_urb, GFP_ATOMIC); - if (retval) { - dev_err(&urb->dev->dev, - "%s - usb_submit_urb(read bulk) failed, " - "retval = %d\n", __func__, retval); - edge_serial->read_in_progress = false; - } - } else { - edge_serial->read_in_progress = false; - } - - spin_unlock(&edge_serial->es_lock); -} - - -/***************************************************************************** - * edge_bulk_out_data_callback - * this is the callback function for when we have finished sending - * serial data on the bulk out endpoint. - *****************************************************************************/ -static void edge_bulk_out_data_callback(struct urb *urb) -{ - struct edgeport_port *edge_port = urb->context; - struct tty_struct *tty; - int status = urb->status; - - dbg("%s", __func__); - - if (status) { - dbg("%s - nonzero write bulk status received: %d", - __func__, status); - } - - tty = tty_port_tty_get(&edge_port->port->port); - - if (tty && edge_port->open) { - /* let the tty driver wakeup if it has a special - write_wakeup function */ - tty_wakeup(tty); - } - tty_kref_put(tty); - - /* Release the Write URB */ - edge_port->write_in_progress = false; - - /* Check if more data needs to be sent */ - send_more_port_data((struct edgeport_serial *) - (usb_get_serial_data(edge_port->port->serial)), edge_port); -} - - -/***************************************************************************** - * BulkOutCmdCallback - * this is the callback function for when we have finished sending a - * command on the bulk out endpoint. - *****************************************************************************/ -static void edge_bulk_out_cmd_callback(struct urb *urb) -{ - struct edgeport_port *edge_port = urb->context; - struct tty_struct *tty; - int status = urb->status; - - dbg("%s", __func__); - - atomic_dec(&CmdUrbs); - dbg("%s - FREE URB %p (outstanding %d)", __func__, - urb, atomic_read(&CmdUrbs)); - - - /* clean up the transfer buffer */ - kfree(urb->transfer_buffer); - - /* Free the command urb */ - usb_free_urb(urb); - - if (status) { - dbg("%s - nonzero write bulk status received: %d", - __func__, status); - return; - } - - /* Get pointer to tty */ - tty = tty_port_tty_get(&edge_port->port->port); - - /* tell the tty driver that something has changed */ - if (tty && edge_port->open) - tty_wakeup(tty); - tty_kref_put(tty); - - /* we have completed the command */ - edge_port->commandPending = false; - wake_up(&edge_port->wait_command); -} - - -/***************************************************************************** - * Driver tty interface functions - *****************************************************************************/ - -/***************************************************************************** - * SerialOpen - * this function is called by the tty driver when a port is opened - * If successful, we return 0 - * Otherwise we return a negative error number. - *****************************************************************************/ -static int edge_open(struct tty_struct *tty, struct usb_serial_port *port) -{ - struct edgeport_port *edge_port = usb_get_serial_port_data(port); - struct usb_serial *serial; - struct edgeport_serial *edge_serial; - int response; - - dbg("%s - port %d", __func__, port->number); - - if (edge_port == NULL) - return -ENODEV; - - /* see if we've set up our endpoint info yet (can't set it up - in edge_startup as the structures were not set up at that time.) */ - serial = port->serial; - edge_serial = usb_get_serial_data(serial); - if (edge_serial == NULL) - return -ENODEV; - if (edge_serial->interrupt_in_buffer == NULL) { - struct usb_serial_port *port0 = serial->port[0]; - - /* not set up yet, so do it now */ - edge_serial->interrupt_in_buffer = - port0->interrupt_in_buffer; - edge_serial->interrupt_in_endpoint = - port0->interrupt_in_endpointAddress; - edge_serial->interrupt_read_urb = port0->interrupt_in_urb; - edge_serial->bulk_in_buffer = port0->bulk_in_buffer; - edge_serial->bulk_in_endpoint = - port0->bulk_in_endpointAddress; - edge_serial->read_urb = port0->read_urb; - edge_serial->bulk_out_endpoint = - port0->bulk_out_endpointAddress; - - /* set up our interrupt urb */ - usb_fill_int_urb(edge_serial->interrupt_read_urb, - serial->dev, - usb_rcvintpipe(serial->dev, - port0->interrupt_in_endpointAddress), - port0->interrupt_in_buffer, - edge_serial->interrupt_read_urb->transfer_buffer_length, - edge_interrupt_callback, edge_serial, - edge_serial->interrupt_read_urb->interval); - - /* set up our bulk in urb */ - usb_fill_bulk_urb(edge_serial->read_urb, serial->dev, - usb_rcvbulkpipe(serial->dev, - port0->bulk_in_endpointAddress), - port0->bulk_in_buffer, - edge_serial->read_urb->transfer_buffer_length, - edge_bulk_in_callback, edge_serial); - edge_serial->read_in_progress = false; - - /* start interrupt read for this edgeport - * this interrupt will continue as long - * as the edgeport is connected */ - response = usb_submit_urb(edge_serial->interrupt_read_urb, - GFP_KERNEL); - if (response) { - dev_err(&port->dev, - "%s - Error %d submitting control urb\n", - __func__, response); - } - } - - /* initialize our wait queues */ - init_waitqueue_head(&edge_port->wait_open); - init_waitqueue_head(&edge_port->wait_chase); - init_waitqueue_head(&edge_port->delta_msr_wait); - init_waitqueue_head(&edge_port->wait_command); - - /* initialize our icount structure */ - memset(&(edge_port->icount), 0x00, sizeof(edge_port->icount)); - - /* initialize our port settings */ - edge_port->txCredits = 0; /* Can't send any data yet */ - /* Must always set this bit to enable ints! */ - edge_port->shadowMCR = MCR_MASTER_IE; - edge_port->chaseResponsePending = false; - - /* send a open port command */ - edge_port->openPending = true; - edge_port->open = false; - response = send_iosp_ext_cmd(edge_port, IOSP_CMD_OPEN_PORT, 0); - - if (response < 0) { - dev_err(&port->dev, "%s - error sending open port command\n", - __func__); - edge_port->openPending = false; - return -ENODEV; - } - - /* now wait for the port to be completely opened */ - wait_event_timeout(edge_port->wait_open, !edge_port->openPending, - OPEN_TIMEOUT); - - if (!edge_port->open) { - /* open timed out */ - dbg("%s - open timedout", __func__); - edge_port->openPending = false; - return -ENODEV; - } - - /* create the txfifo */ - edge_port->txfifo.head = 0; - edge_port->txfifo.tail = 0; - edge_port->txfifo.count = 0; - edge_port->txfifo.size = edge_port->maxTxCredits; - edge_port->txfifo.fifo = kmalloc(edge_port->maxTxCredits, GFP_KERNEL); - - if (!edge_port->txfifo.fifo) { - dbg("%s - no memory", __func__); - edge_close(port); - return -ENOMEM; - } - - /* Allocate a URB for the write */ - edge_port->write_urb = usb_alloc_urb(0, GFP_KERNEL); - edge_port->write_in_progress = false; - - if (!edge_port->write_urb) { - dbg("%s - no memory", __func__); - edge_close(port); - return -ENOMEM; - } - - dbg("%s(%d) - Initialize TX fifo to %d bytes", - __func__, port->number, edge_port->maxTxCredits); - - dbg("%s exited", __func__); - - return 0; -} - - -/************************************************************************ - * - * block_until_chase_response - * - * This function will block the close until one of the following: - * 1. Response to our Chase comes from Edgeport - * 2. A timeout of 10 seconds without activity has expired - * (1K of Edgeport data @ 2400 baud ==> 4 sec to empty) - * - ************************************************************************/ -static void block_until_chase_response(struct edgeport_port *edge_port) -{ - DEFINE_WAIT(wait); - __u16 lastCredits; - int timeout = 1*HZ; - int loop = 10; - - while (1) { - /* Save Last credits */ - lastCredits = edge_port->txCredits; - - /* Did we get our Chase response */ - if (!edge_port->chaseResponsePending) { - dbg("%s - Got Chase Response", __func__); - - /* did we get all of our credit back? */ - if (edge_port->txCredits == edge_port->maxTxCredits) { - dbg("%s - Got all credits", __func__); - return; - } - } - - /* Block the thread for a while */ - prepare_to_wait(&edge_port->wait_chase, &wait, - TASK_UNINTERRUPTIBLE); - schedule_timeout(timeout); - finish_wait(&edge_port->wait_chase, &wait); - - if (lastCredits == edge_port->txCredits) { - /* No activity.. count down. */ - loop--; - if (loop == 0) { - edge_port->chaseResponsePending = false; - dbg("%s - Chase TIMEOUT", __func__); - return; - } - } else { - /* Reset timeout value back to 10 seconds */ - dbg("%s - Last %d, Current %d", __func__, - lastCredits, edge_port->txCredits); - loop = 10; - } - } -} - - -/************************************************************************ - * - * block_until_tx_empty - * - * This function will block the close until one of the following: - * 1. TX count are 0 - * 2. The edgeport has stopped - * 3. A timeout of 3 seconds without activity has expired - * - ************************************************************************/ -static void block_until_tx_empty(struct edgeport_port *edge_port) -{ - DEFINE_WAIT(wait); - struct TxFifo *fifo = &edge_port->txfifo; - __u32 lastCount; - int timeout = HZ/10; - int loop = 30; - - while (1) { - /* Save Last count */ - lastCount = fifo->count; - - /* Is the Edgeport Buffer empty? */ - if (lastCount == 0) { - dbg("%s - TX Buffer Empty", __func__); - return; - } - - /* Block the thread for a while */ - prepare_to_wait(&edge_port->wait_chase, &wait, - TASK_UNINTERRUPTIBLE); - schedule_timeout(timeout); - finish_wait(&edge_port->wait_chase, &wait); - - dbg("%s wait", __func__); - - if (lastCount == fifo->count) { - /* No activity.. count down. */ - loop--; - if (loop == 0) { - dbg("%s - TIMEOUT", __func__); - return; - } - } else { - /* Reset timeout value back to seconds */ - loop = 30; - } - } -} - - -/***************************************************************************** - * edge_close - * this function is called by the tty driver when a port is closed - *****************************************************************************/ -static void edge_close(struct usb_serial_port *port) -{ - struct edgeport_serial *edge_serial; - struct edgeport_port *edge_port; - int status; - - dbg("%s - port %d", __func__, port->number); - - edge_serial = usb_get_serial_data(port->serial); - edge_port = usb_get_serial_port_data(port); - if (edge_serial == NULL || edge_port == NULL) - return; - - /* block until tx is empty */ - block_until_tx_empty(edge_port); - - edge_port->closePending = true; - - if ((!edge_serial->is_epic) || - ((edge_serial->is_epic) && - (edge_serial->epic_descriptor.Supports.IOSPChase))) { - /* flush and chase */ - edge_port->chaseResponsePending = true; - - dbg("%s - Sending IOSP_CMD_CHASE_PORT", __func__); - status = send_iosp_ext_cmd(edge_port, IOSP_CMD_CHASE_PORT, 0); - if (status == 0) - /* block until chase finished */ - block_until_chase_response(edge_port); - else - edge_port->chaseResponsePending = false; - } - - if ((!edge_serial->is_epic) || - ((edge_serial->is_epic) && - (edge_serial->epic_descriptor.Supports.IOSPClose))) { - /* close the port */ - dbg("%s - Sending IOSP_CMD_CLOSE_PORT", __func__); - send_iosp_ext_cmd(edge_port, IOSP_CMD_CLOSE_PORT, 0); - } - - /* port->close = true; */ - edge_port->closePending = false; - edge_port->open = false; - edge_port->openPending = false; - - usb_kill_urb(edge_port->write_urb); - - if (edge_port->write_urb) { - /* if this urb had a transfer buffer already - (old transfer) free it */ - kfree(edge_port->write_urb->transfer_buffer); - usb_free_urb(edge_port->write_urb); - edge_port->write_urb = NULL; - } - kfree(edge_port->txfifo.fifo); - edge_port->txfifo.fifo = NULL; - - dbg("%s exited", __func__); -} - -/***************************************************************************** - * SerialWrite - * this function is called by the tty driver when data should be written - * to the port. - * If successful, we return the number of bytes written, otherwise we - * return a negative error number. - *****************************************************************************/ -static int edge_write(struct tty_struct *tty, struct usb_serial_port *port, - const unsigned char *data, int count) -{ - struct edgeport_port *edge_port = usb_get_serial_port_data(port); - struct TxFifo *fifo; - int copySize; - int bytesleft; - int firsthalf; - int secondhalf; - unsigned long flags; - - dbg("%s - port %d", __func__, port->number); - - if (edge_port == NULL) - return -ENODEV; - - /* get a pointer to the Tx fifo */ - fifo = &edge_port->txfifo; - - spin_lock_irqsave(&edge_port->ep_lock, flags); - - /* calculate number of bytes to put in fifo */ - copySize = min((unsigned int)count, - (edge_port->txCredits - fifo->count)); - - dbg("%s(%d) of %d byte(s) Fifo room %d -- will copy %d bytes", - __func__, port->number, count, - edge_port->txCredits - fifo->count, copySize); - - /* catch writes of 0 bytes which the tty driver likes to give us, - and when txCredits is empty */ - if (copySize == 0) { - dbg("%s - copySize = Zero", __func__); - goto finish_write; - } - - /* queue the data - * since we can never overflow the buffer we do not have to check for a - * full condition - * - * the copy is done is two parts -- first fill to the end of the buffer - * then copy the reset from the start of the buffer - */ - bytesleft = fifo->size - fifo->head; - firsthalf = min(bytesleft, copySize); - dbg("%s - copy %d bytes of %d into fifo ", __func__, - firsthalf, bytesleft); - - /* now copy our data */ - memcpy(&fifo->fifo[fifo->head], data, firsthalf); - usb_serial_debug_data(debug, &port->dev, __func__, - firsthalf, &fifo->fifo[fifo->head]); - - /* update the index and size */ - fifo->head += firsthalf; - fifo->count += firsthalf; - - /* wrap the index */ - if (fifo->head == fifo->size) - fifo->head = 0; - - secondhalf = copySize-firsthalf; - - if (secondhalf) { - dbg("%s - copy rest of data %d", __func__, secondhalf); - memcpy(&fifo->fifo[fifo->head], &data[firsthalf], secondhalf); - usb_serial_debug_data(debug, &port->dev, __func__, - secondhalf, &fifo->fifo[fifo->head]); - /* update the index and size */ - fifo->count += secondhalf; - fifo->head += secondhalf; - /* No need to check for wrap since we can not get to end of - * the fifo in this part - */ - } - -finish_write: - spin_unlock_irqrestore(&edge_port->ep_lock, flags); - - send_more_port_data((struct edgeport_serial *) - usb_get_serial_data(port->serial), edge_port); - - dbg("%s wrote %d byte(s) TxCredits %d, Fifo %d", __func__, - copySize, edge_port->txCredits, fifo->count); - - return copySize; -} - - -/************************************************************************ - * - * send_more_port_data() - * - * This routine attempts to write additional UART transmit data - * to a port over the USB bulk pipe. It is called (1) when new - * data has been written to a port's TxBuffer from higher layers - * (2) when the peripheral sends us additional TxCredits indicating - * that it can accept more Tx data for a given port; and (3) when - * a bulk write completes successfully and we want to see if we - * can transmit more. - * - ************************************************************************/ -static void send_more_port_data(struct edgeport_serial *edge_serial, - struct edgeport_port *edge_port) -{ - struct TxFifo *fifo = &edge_port->txfifo; - struct urb *urb; - unsigned char *buffer; - int status; - int count; - int bytesleft; - int firsthalf; - int secondhalf; - unsigned long flags; - - dbg("%s(%d)", __func__, edge_port->port->number); - - spin_lock_irqsave(&edge_port->ep_lock, flags); - - if (edge_port->write_in_progress || - !edge_port->open || - (fifo->count == 0)) { - dbg("%s(%d) EXIT - fifo %d, PendingWrite = %d", - __func__, edge_port->port->number, - fifo->count, edge_port->write_in_progress); - goto exit_send; - } - - /* since the amount of data in the fifo will always fit into the - * edgeport buffer we do not need to check the write length - * - * Do we have enough credits for this port to make it worthwhile - * to bother queueing a write. If it's too small, say a few bytes, - * it's better to wait for more credits so we can do a larger write. - */ - if (edge_port->txCredits < EDGE_FW_GET_TX_CREDITS_SEND_THRESHOLD(edge_port->maxTxCredits, EDGE_FW_BULK_MAX_PACKET_SIZE)) { - dbg("%s(%d) Not enough credit - fifo %d TxCredit %d", - __func__, edge_port->port->number, fifo->count, - edge_port->txCredits); - goto exit_send; - } - - /* lock this write */ - edge_port->write_in_progress = true; - - /* get a pointer to the write_urb */ - urb = edge_port->write_urb; - - /* make sure transfer buffer is freed */ - kfree(urb->transfer_buffer); - urb->transfer_buffer = NULL; - - /* build the data header for the buffer and port that we are about - to send out */ - count = fifo->count; - buffer = kmalloc(count+2, GFP_ATOMIC); - if (buffer == NULL) { - dev_err_console(edge_port->port, - "%s - no more kernel memory...\n", __func__); - edge_port->write_in_progress = false; - goto exit_send; - } - buffer[0] = IOSP_BUILD_DATA_HDR1(edge_port->port->number - - edge_port->port->serial->minor, count); - buffer[1] = IOSP_BUILD_DATA_HDR2(edge_port->port->number - - edge_port->port->serial->minor, count); - - /* now copy our data */ - bytesleft = fifo->size - fifo->tail; - firsthalf = min(bytesleft, count); - memcpy(&buffer[2], &fifo->fifo[fifo->tail], firsthalf); - fifo->tail += firsthalf; - fifo->count -= firsthalf; - if (fifo->tail == fifo->size) - fifo->tail = 0; - - secondhalf = count-firsthalf; - if (secondhalf) { - memcpy(&buffer[2+firsthalf], &fifo->fifo[fifo->tail], - secondhalf); - fifo->tail += secondhalf; - fifo->count -= secondhalf; - } - - if (count) - usb_serial_debug_data(debug, &edge_port->port->dev, - __func__, count, &buffer[2]); - - /* fill up the urb with all of our data and submit it */ - usb_fill_bulk_urb(urb, edge_serial->serial->dev, - usb_sndbulkpipe(edge_serial->serial->dev, - edge_serial->bulk_out_endpoint), - buffer, count+2, - edge_bulk_out_data_callback, edge_port); - - /* decrement the number of credits we have by the number we just sent */ - edge_port->txCredits -= count; - edge_port->icount.tx += count; - - status = usb_submit_urb(urb, GFP_ATOMIC); - if (status) { - /* something went wrong */ - dev_err_console(edge_port->port, - "%s - usb_submit_urb(write bulk) failed, status = %d, data lost\n", - __func__, status); - edge_port->write_in_progress = false; - - /* revert the credits as something bad happened. */ - edge_port->txCredits += count; - edge_port->icount.tx -= count; - } - dbg("%s wrote %d byte(s) TxCredit %d, Fifo %d", - __func__, count, edge_port->txCredits, fifo->count); - -exit_send: - spin_unlock_irqrestore(&edge_port->ep_lock, flags); -} - - -/***************************************************************************** - * edge_write_room - * this function is called by the tty driver when it wants to know how - * many bytes of data we can accept for a specific port. If successful, - * we return the amount of room that we have for this port (the txCredits) - * otherwise we return a negative error number. - *****************************************************************************/ -static int edge_write_room(struct tty_struct *tty) -{ - struct usb_serial_port *port = tty->driver_data; - struct edgeport_port *edge_port = usb_get_serial_port_data(port); - int room; - unsigned long flags; - - dbg("%s", __func__); - - if (edge_port == NULL) - return 0; - if (edge_port->closePending) - return 0; - - dbg("%s - port %d", __func__, port->number); - - if (!edge_port->open) { - dbg("%s - port not opened", __func__); - return 0; - } - - /* total of both buffers is still txCredit */ - spin_lock_irqsave(&edge_port->ep_lock, flags); - room = edge_port->txCredits - edge_port->txfifo.count; - spin_unlock_irqrestore(&edge_port->ep_lock, flags); - - dbg("%s - returns %d", __func__, room); - return room; -} - - -/***************************************************************************** - * edge_chars_in_buffer - * this function is called by the tty driver when it wants to know how - * many bytes of data we currently have outstanding in the port (data that - * has been written, but hasn't made it out the port yet) - * If successful, we return the number of bytes left to be written in the - * system, - * Otherwise we return a negative error number. - *****************************************************************************/ -static int edge_chars_in_buffer(struct tty_struct *tty) -{ - struct usb_serial_port *port = tty->driver_data; - struct edgeport_port *edge_port = usb_get_serial_port_data(port); - int num_chars; - unsigned long flags; - - dbg("%s", __func__); - - if (edge_port == NULL) - return 0; - if (edge_port->closePending) - return 0; - - if (!edge_port->open) { - dbg("%s - port not opened", __func__); - return 0; - } - - spin_lock_irqsave(&edge_port->ep_lock, flags); - num_chars = edge_port->maxTxCredits - edge_port->txCredits + - edge_port->txfifo.count; - spin_unlock_irqrestore(&edge_port->ep_lock, flags); - if (num_chars) { - dbg("%s(port %d) - returns %d", __func__, - port->number, num_chars); - } - - return num_chars; -} - - -/***************************************************************************** - * SerialThrottle - * this function is called by the tty driver when it wants to stop the data - * being read from the port. - *****************************************************************************/ -static void edge_throttle(struct tty_struct *tty) -{ - struct usb_serial_port *port = tty->driver_data; - struct edgeport_port *edge_port = usb_get_serial_port_data(port); - int status; - - dbg("%s - port %d", __func__, port->number); - - if (edge_port == NULL) - return; - - if (!edge_port->open) { - dbg("%s - port not opened", __func__); - return; - } - - /* if we are implementing XON/XOFF, send the stop character */ - if (I_IXOFF(tty)) { - unsigned char stop_char = STOP_CHAR(tty); - status = edge_write(tty, port, &stop_char, 1); - if (status <= 0) - return; - } - - /* if we are implementing RTS/CTS, toggle that line */ - if (tty->termios->c_cflag & CRTSCTS) { - edge_port->shadowMCR &= ~MCR_RTS; - status = send_cmd_write_uart_register(edge_port, MCR, - edge_port->shadowMCR); - if (status != 0) - return; - } -} - - -/***************************************************************************** - * edge_unthrottle - * this function is called by the tty driver when it wants to resume the - * data being read from the port (called after SerialThrottle is called) - *****************************************************************************/ -static void edge_unthrottle(struct tty_struct *tty) -{ - struct usb_serial_port *port = tty->driver_data; - struct edgeport_port *edge_port = usb_get_serial_port_data(port); - int status; - - dbg("%s - port %d", __func__, port->number); - - if (edge_port == NULL) - return; - - if (!edge_port->open) { - dbg("%s - port not opened", __func__); - return; - } - - /* if we are implementing XON/XOFF, send the start character */ - if (I_IXOFF(tty)) { - unsigned char start_char = START_CHAR(tty); - status = edge_write(tty, port, &start_char, 1); - if (status <= 0) - return; - } - /* if we are implementing RTS/CTS, toggle that line */ - if (tty->termios->c_cflag & CRTSCTS) { - edge_port->shadowMCR |= MCR_RTS; - send_cmd_write_uart_register(edge_port, MCR, - edge_port->shadowMCR); - } -} - - -/***************************************************************************** - * SerialSetTermios - * this function is called by the tty driver when it wants to change - * the termios structure - *****************************************************************************/ -static void edge_set_termios(struct tty_struct *tty, - struct usb_serial_port *port, struct ktermios *old_termios) -{ - struct edgeport_port *edge_port = usb_get_serial_port_data(port); - unsigned int cflag; - - cflag = tty->termios->c_cflag; - dbg("%s - clfag %08x iflag %08x", __func__, - tty->termios->c_cflag, tty->termios->c_iflag); - dbg("%s - old clfag %08x old iflag %08x", __func__, - old_termios->c_cflag, old_termios->c_iflag); - - dbg("%s - port %d", __func__, port->number); - - if (edge_port == NULL) - return; - - if (!edge_port->open) { - dbg("%s - port not opened", __func__); - return; - } - - /* change the port settings to the new ones specified */ - change_port_settings(tty, edge_port, old_termios); -} - - -/***************************************************************************** - * get_lsr_info - get line status register info - * - * Purpose: Let user call ioctl() to get info when the UART physically - * is emptied. On bus types like RS485, the transmitter must - * release the bus after transmitting. This must be done when - * the transmit shift register is empty, not be done when the - * transmit holding register is empty. This functionality - * allows an RS485 driver to be written in user space. - *****************************************************************************/ -static int get_lsr_info(struct edgeport_port *edge_port, - unsigned int __user *value) -{ - unsigned int result = 0; - unsigned long flags; - - spin_lock_irqsave(&edge_port->ep_lock, flags); - if (edge_port->maxTxCredits == edge_port->txCredits && - edge_port->txfifo.count == 0) { - dbg("%s -- Empty", __func__); - result = TIOCSER_TEMT; - } - spin_unlock_irqrestore(&edge_port->ep_lock, flags); - - if (copy_to_user(value, &result, sizeof(int))) - return -EFAULT; - return 0; -} - -static int edge_tiocmset(struct tty_struct *tty, - unsigned int set, unsigned int clear) -{ - struct usb_serial_port *port = tty->driver_data; - struct edgeport_port *edge_port = usb_get_serial_port_data(port); - unsigned int mcr; - - dbg("%s - port %d", __func__, port->number); - - mcr = edge_port->shadowMCR; - if (set & TIOCM_RTS) - mcr |= MCR_RTS; - if (set & TIOCM_DTR) - mcr |= MCR_DTR; - if (set & TIOCM_LOOP) - mcr |= MCR_LOOPBACK; - - if (clear & TIOCM_RTS) - mcr &= ~MCR_RTS; - if (clear & TIOCM_DTR) - mcr &= ~MCR_DTR; - if (clear & TIOCM_LOOP) - mcr &= ~MCR_LOOPBACK; - - edge_port->shadowMCR = mcr; - - send_cmd_write_uart_register(edge_port, MCR, edge_port->shadowMCR); - - return 0; -} - -static int edge_tiocmget(struct tty_struct *tty) -{ - struct usb_serial_port *port = tty->driver_data; - struct edgeport_port *edge_port = usb_get_serial_port_data(port); - unsigned int result = 0; - unsigned int msr; - unsigned int mcr; - - dbg("%s - port %d", __func__, port->number); - - msr = edge_port->shadowMSR; - mcr = edge_port->shadowMCR; - result = ((mcr & MCR_DTR) ? TIOCM_DTR: 0) /* 0x002 */ - | ((mcr & MCR_RTS) ? TIOCM_RTS: 0) /* 0x004 */ - | ((msr & EDGEPORT_MSR_CTS) ? TIOCM_CTS: 0) /* 0x020 */ - | ((msr & EDGEPORT_MSR_CD) ? TIOCM_CAR: 0) /* 0x040 */ - | ((msr & EDGEPORT_MSR_RI) ? TIOCM_RI: 0) /* 0x080 */ - | ((msr & EDGEPORT_MSR_DSR) ? TIOCM_DSR: 0); /* 0x100 */ - - - dbg("%s -- %x", __func__, result); - - return result; -} - -static int edge_get_icount(struct tty_struct *tty, - struct serial_icounter_struct *icount) -{ - struct usb_serial_port *port = tty->driver_data; - struct edgeport_port *edge_port = usb_get_serial_port_data(port); - struct async_icount cnow; - cnow = edge_port->icount; - - icount->cts = cnow.cts; - icount->dsr = cnow.dsr; - icount->rng = cnow.rng; - icount->dcd = cnow.dcd; - icount->rx = cnow.rx; - icount->tx = cnow.tx; - icount->frame = cnow.frame; - icount->overrun = cnow.overrun; - icount->parity = cnow.parity; - icount->brk = cnow.brk; - icount->buf_overrun = cnow.buf_overrun; - - dbg("%s (%d) TIOCGICOUNT RX=%d, TX=%d", - __func__, port->number, icount->rx, icount->tx); - return 0; -} - -static int get_serial_info(struct edgeport_port *edge_port, - struct serial_struct __user *retinfo) -{ - struct serial_struct tmp; - - if (!retinfo) - return -EFAULT; - - memset(&tmp, 0, sizeof(tmp)); - - tmp.type = PORT_16550A; - tmp.line = edge_port->port->serial->minor; - tmp.port = edge_port->port->number; - tmp.irq = 0; - tmp.flags = ASYNC_SKIP_TEST | ASYNC_AUTO_IRQ; - tmp.xmit_fifo_size = edge_port->maxTxCredits; - tmp.baud_base = 9600; - tmp.close_delay = 5*HZ; - tmp.closing_wait = 30*HZ; - - if (copy_to_user(retinfo, &tmp, sizeof(*retinfo))) - return -EFAULT; - return 0; -} - - -/***************************************************************************** - * SerialIoctl - * this function handles any ioctl calls to the driver - *****************************************************************************/ -static int edge_ioctl(struct tty_struct *tty, - unsigned int cmd, unsigned long arg) -{ - struct usb_serial_port *port = tty->driver_data; - DEFINE_WAIT(wait); - struct edgeport_port *edge_port = usb_get_serial_port_data(port); - struct async_icount cnow; - struct async_icount cprev; - - dbg("%s - port %d, cmd = 0x%x", __func__, port->number, cmd); - - switch (cmd) { - case TIOCSERGETLSR: - dbg("%s (%d) TIOCSERGETLSR", __func__, port->number); - return get_lsr_info(edge_port, (unsigned int __user *) arg); - - case TIOCGSERIAL: - dbg("%s (%d) TIOCGSERIAL", __func__, port->number); - return get_serial_info(edge_port, (struct serial_struct __user *) arg); - - case TIOCMIWAIT: - dbg("%s (%d) TIOCMIWAIT", __func__, port->number); - cprev = edge_port->icount; - while (1) { - prepare_to_wait(&edge_port->delta_msr_wait, - &wait, TASK_INTERRUPTIBLE); - schedule(); - finish_wait(&edge_port->delta_msr_wait, &wait); - /* see if a signal did it */ - if (signal_pending(current)) - return -ERESTARTSYS; - cnow = edge_port->icount; - if (cnow.rng == cprev.rng && cnow.dsr == cprev.dsr && - cnow.dcd == cprev.dcd && cnow.cts == cprev.cts) - return -EIO; /* no change => error */ - if (((arg & TIOCM_RNG) && (cnow.rng != cprev.rng)) || - ((arg & TIOCM_DSR) && (cnow.dsr != cprev.dsr)) || - ((arg & TIOCM_CD) && (cnow.dcd != cprev.dcd)) || - ((arg & TIOCM_CTS) && (cnow.cts != cprev.cts))) { - return 0; - } - cprev = cnow; - } - /* NOTREACHED */ - break; - - } - return -ENOIOCTLCMD; -} - - -/***************************************************************************** - * SerialBreak - * this function sends a break to the port - *****************************************************************************/ -static void edge_break(struct tty_struct *tty, int break_state) -{ - struct usb_serial_port *port = tty->driver_data; - struct edgeport_port *edge_port = usb_get_serial_port_data(port); - struct edgeport_serial *edge_serial = usb_get_serial_data(port->serial); - int status; - - if ((!edge_serial->is_epic) || - ((edge_serial->is_epic) && - (edge_serial->epic_descriptor.Supports.IOSPChase))) { - /* flush and chase */ - edge_port->chaseResponsePending = true; - - dbg("%s - Sending IOSP_CMD_CHASE_PORT", __func__); - status = send_iosp_ext_cmd(edge_port, IOSP_CMD_CHASE_PORT, 0); - if (status == 0) { - /* block until chase finished */ - block_until_chase_response(edge_port); - } else { - edge_port->chaseResponsePending = false; - } - } - - if ((!edge_serial->is_epic) || - ((edge_serial->is_epic) && - (edge_serial->epic_descriptor.Supports.IOSPSetClrBreak))) { - if (break_state == -1) { - dbg("%s - Sending IOSP_CMD_SET_BREAK", __func__); - status = send_iosp_ext_cmd(edge_port, - IOSP_CMD_SET_BREAK, 0); - } else { - dbg("%s - Sending IOSP_CMD_CLEAR_BREAK", __func__); - status = send_iosp_ext_cmd(edge_port, - IOSP_CMD_CLEAR_BREAK, 0); - } - if (status) - dbg("%s - error sending break set/clear command.", - __func__); - } -} - - -/***************************************************************************** - * process_rcvd_data - * this function handles the data received on the bulk in pipe. - *****************************************************************************/ -static void process_rcvd_data(struct edgeport_serial *edge_serial, - unsigned char *buffer, __u16 bufferLength) -{ - struct usb_serial_port *port; - struct edgeport_port *edge_port; - struct tty_struct *tty; - __u16 lastBufferLength; - __u16 rxLen; - - dbg("%s", __func__); - - lastBufferLength = bufferLength + 1; - - while (bufferLength > 0) { - /* failsafe incase we get a message that we don't understand */ - if (lastBufferLength == bufferLength) { - dbg("%s - stuck in loop, exiting it.", __func__); - break; - } - lastBufferLength = bufferLength; - - switch (edge_serial->rxState) { - case EXPECT_HDR1: - edge_serial->rxHeader1 = *buffer; - ++buffer; - --bufferLength; - - if (bufferLength == 0) { - edge_serial->rxState = EXPECT_HDR2; - break; - } - /* otherwise, drop on through */ - case EXPECT_HDR2: - edge_serial->rxHeader2 = *buffer; - ++buffer; - --bufferLength; - - dbg("%s - Hdr1=%02X Hdr2=%02X", __func__, - edge_serial->rxHeader1, edge_serial->rxHeader2); - /* Process depending on whether this header is - * data or status */ - - if (IS_CMD_STAT_HDR(edge_serial->rxHeader1)) { - /* Decode this status header and go to - * EXPECT_HDR1 (if we can process the status - * with only 2 bytes), or go to EXPECT_HDR3 to - * get the third byte. */ - edge_serial->rxPort = - IOSP_GET_HDR_PORT(edge_serial->rxHeader1); - edge_serial->rxStatusCode = - IOSP_GET_STATUS_CODE( - edge_serial->rxHeader1); - - if (!IOSP_STATUS_IS_2BYTE( - edge_serial->rxStatusCode)) { - /* This status needs additional bytes. - * Save what we have and then wait for - * more data. - */ - edge_serial->rxStatusParam - = edge_serial->rxHeader2; - edge_serial->rxState = EXPECT_HDR3; - break; - } - /* We have all the header bytes, process the - status now */ - process_rcvd_status(edge_serial, - edge_serial->rxHeader2, 0); - edge_serial->rxState = EXPECT_HDR1; - break; - } else { - edge_serial->rxPort = - IOSP_GET_HDR_PORT(edge_serial->rxHeader1); - edge_serial->rxBytesRemaining = - IOSP_GET_HDR_DATA_LEN( - edge_serial->rxHeader1, - edge_serial->rxHeader2); - dbg("%s - Data for Port %u Len %u", - __func__, - edge_serial->rxPort, - edge_serial->rxBytesRemaining); - - /* ASSERT(DevExt->RxPort < DevExt->NumPorts); - * ASSERT(DevExt->RxBytesRemaining < - * IOSP_MAX_DATA_LENGTH); - */ - - if (bufferLength == 0) { - edge_serial->rxState = EXPECT_DATA; - break; - } - /* Else, drop through */ - } - case EXPECT_DATA: /* Expect data */ - if (bufferLength < edge_serial->rxBytesRemaining) { - rxLen = bufferLength; - /* Expect data to start next buffer */ - edge_serial->rxState = EXPECT_DATA; - } else { - /* BufLen >= RxBytesRemaining */ - rxLen = edge_serial->rxBytesRemaining; - /* Start another header next time */ - edge_serial->rxState = EXPECT_HDR1; - } - - bufferLength -= rxLen; - edge_serial->rxBytesRemaining -= rxLen; - - /* spit this data back into the tty driver if this - port is open */ - if (rxLen) { - port = edge_serial->serial->port[ - edge_serial->rxPort]; - edge_port = usb_get_serial_port_data(port); - if (edge_port->open) { - tty = tty_port_tty_get( - &edge_port->port->port); - if (tty) { - dbg("%s - Sending %d bytes to TTY for port %d", - __func__, rxLen, edge_serial->rxPort); - edge_tty_recv(&edge_serial->serial->dev->dev, tty, buffer, rxLen); - tty_kref_put(tty); - } - edge_port->icount.rx += rxLen; - } - buffer += rxLen; - } - break; - - case EXPECT_HDR3: /* Expect 3rd byte of status header */ - edge_serial->rxHeader3 = *buffer; - ++buffer; - --bufferLength; - - /* We have all the header bytes, process the - status now */ - process_rcvd_status(edge_serial, - edge_serial->rxStatusParam, - edge_serial->rxHeader3); - edge_serial->rxState = EXPECT_HDR1; - break; - } - } -} - - -/***************************************************************************** - * process_rcvd_status - * this function handles the any status messages received on the - * bulk in pipe. - *****************************************************************************/ -static void process_rcvd_status(struct edgeport_serial *edge_serial, - __u8 byte2, __u8 byte3) -{ - struct usb_serial_port *port; - struct edgeport_port *edge_port; - struct tty_struct *tty; - __u8 code = edge_serial->rxStatusCode; - - /* switch the port pointer to the one being currently talked about */ - port = edge_serial->serial->port[edge_serial->rxPort]; - edge_port = usb_get_serial_port_data(port); - if (edge_port == NULL) { - dev_err(&edge_serial->serial->dev->dev, - "%s - edge_port == NULL for port %d\n", - __func__, edge_serial->rxPort); - return; - } - - dbg("%s - port %d", __func__, edge_serial->rxPort); - - if (code == IOSP_EXT_STATUS) { - switch (byte2) { - case IOSP_EXT_STATUS_CHASE_RSP: - /* we want to do EXT status regardless of port - * open/closed */ - dbg("%s - Port %u EXT CHASE_RSP Data = %02x", - __func__, edge_serial->rxPort, byte3); - /* Currently, the only EXT_STATUS is Chase, so process - * here instead of one more call to one more subroutine - * If/when more EXT_STATUS, there'll be more work to do - * Also, we currently clear flag and close the port - * regardless of content of above's Byte3. - * We could choose to do something else when Byte3 says - * Timeout on Chase from Edgeport, like wait longer in - * block_until_chase_response, but for now we don't. - */ - edge_port->chaseResponsePending = false; - wake_up(&edge_port->wait_chase); - return; - - case IOSP_EXT_STATUS_RX_CHECK_RSP: - dbg("%s ========== Port %u CHECK_RSP Sequence = %02x =============", __func__, edge_serial->rxPort, byte3); - /* Port->RxCheckRsp = true; */ - return; - } - } - - if (code == IOSP_STATUS_OPEN_RSP) { - edge_port->txCredits = GET_TX_BUFFER_SIZE(byte3); - edge_port->maxTxCredits = edge_port->txCredits; - dbg("%s - Port %u Open Response Initial MSR = %02x TxBufferSize = %d", __func__, edge_serial->rxPort, byte2, edge_port->txCredits); - handle_new_msr(edge_port, byte2); - - /* send the current line settings to the port so we are - in sync with any further termios calls */ - tty = tty_port_tty_get(&edge_port->port->port); - if (tty) { - change_port_settings(tty, - edge_port, tty->termios); - tty_kref_put(tty); - } - - /* we have completed the open */ - edge_port->openPending = false; - edge_port->open = true; - wake_up(&edge_port->wait_open); - return; - } - - /* If port is closed, silently discard all rcvd status. We can - * have cases where buffered status is received AFTER the close - * port command is sent to the Edgeport. - */ - if (!edge_port->open || edge_port->closePending) - return; - - switch (code) { - /* Not currently sent by Edgeport */ - case IOSP_STATUS_LSR: - dbg("%s - Port %u LSR Status = %02x", - __func__, edge_serial->rxPort, byte2); - handle_new_lsr(edge_port, false, byte2, 0); - break; - - case IOSP_STATUS_LSR_DATA: - dbg("%s - Port %u LSR Status = %02x, Data = %02x", - __func__, edge_serial->rxPort, byte2, byte3); - /* byte2 is LSR Register */ - /* byte3 is broken data byte */ - handle_new_lsr(edge_port, true, byte2, byte3); - break; - /* - * case IOSP_EXT_4_STATUS: - * dbg("%s - Port %u LSR Status = %02x Data = %02x", - * __func__, edge_serial->rxPort, byte2, byte3); - * break; - */ - case IOSP_STATUS_MSR: - dbg("%s - Port %u MSR Status = %02x", - __func__, edge_serial->rxPort, byte2); - /* - * Process this new modem status and generate appropriate - * events, etc, based on the new status. This routine - * also saves the MSR in Port->ShadowMsr. - */ - handle_new_msr(edge_port, byte2); - break; - - default: - dbg("%s - Unrecognized IOSP status code %u", __func__, code); - break; - } -} - - -/***************************************************************************** - * edge_tty_recv - * this function passes data on to the tty flip buffer - *****************************************************************************/ -static void edge_tty_recv(struct device *dev, struct tty_struct *tty, - unsigned char *data, int length) -{ - int cnt; - - cnt = tty_insert_flip_string(tty, data, length); - if (cnt < length) { - dev_err(dev, "%s - dropping data, %d bytes lost\n", - __func__, length - cnt); - } - data += cnt; - length -= cnt; - - tty_flip_buffer_push(tty); -} - - -/***************************************************************************** - * handle_new_msr - * this function handles any change to the msr register for a port. - *****************************************************************************/ -static void handle_new_msr(struct edgeport_port *edge_port, __u8 newMsr) -{ - struct async_icount *icount; - - dbg("%s %02x", __func__, newMsr); - - if (newMsr & (EDGEPORT_MSR_DELTA_CTS | EDGEPORT_MSR_DELTA_DSR | - EDGEPORT_MSR_DELTA_RI | EDGEPORT_MSR_DELTA_CD)) { - icount = &edge_port->icount; - - /* update input line counters */ - if (newMsr & EDGEPORT_MSR_DELTA_CTS) - icount->cts++; - if (newMsr & EDGEPORT_MSR_DELTA_DSR) - icount->dsr++; - if (newMsr & EDGEPORT_MSR_DELTA_CD) - icount->dcd++; - if (newMsr & EDGEPORT_MSR_DELTA_RI) - icount->rng++; - wake_up_interruptible(&edge_port->delta_msr_wait); - } - - /* Save the new modem status */ - edge_port->shadowMSR = newMsr & 0xf0; -} - - -/***************************************************************************** - * handle_new_lsr - * this function handles any change to the lsr register for a port. - *****************************************************************************/ -static void handle_new_lsr(struct edgeport_port *edge_port, __u8 lsrData, - __u8 lsr, __u8 data) -{ - __u8 newLsr = (__u8) (lsr & (__u8) - (LSR_OVER_ERR | LSR_PAR_ERR | LSR_FRM_ERR | LSR_BREAK)); - struct async_icount *icount; - - dbg("%s - %02x", __func__, newLsr); - - edge_port->shadowLSR = lsr; - - if (newLsr & LSR_BREAK) { - /* - * Parity and Framing errors only count if they - * occur exclusive of a break being - * received. - */ - newLsr &= (__u8)(LSR_OVER_ERR | LSR_BREAK); - } - - /* Place LSR data byte into Rx buffer */ - if (lsrData) { - struct tty_struct *tty = - tty_port_tty_get(&edge_port->port->port); - if (tty) { - edge_tty_recv(&edge_port->port->dev, tty, &data, 1); - tty_kref_put(tty); - } - } - /* update input line counters */ - icount = &edge_port->icount; - if (newLsr & LSR_BREAK) - icount->brk++; - if (newLsr & LSR_OVER_ERR) - icount->overrun++; - if (newLsr & LSR_PAR_ERR) - icount->parity++; - if (newLsr & LSR_FRM_ERR) - icount->frame++; -} - - -/**************************************************************************** - * sram_write - * writes a number of bytes to the Edgeport device's sram starting at the - * given address. - * If successful returns the number of bytes written, otherwise it returns - * a negative error number of the problem. - ****************************************************************************/ -static int sram_write(struct usb_serial *serial, __u16 extAddr, __u16 addr, - __u16 length, const __u8 *data) -{ - int result; - __u16 current_length; - unsigned char *transfer_buffer; - - dbg("%s - %x, %x, %d", __func__, extAddr, addr, length); - - transfer_buffer = kmalloc(64, GFP_KERNEL); - if (!transfer_buffer) { - dev_err(&serial->dev->dev, "%s - kmalloc(%d) failed.\n", - __func__, 64); - return -ENOMEM; - } - - /* need to split these writes up into 64 byte chunks */ - result = 0; - while (length > 0) { - if (length > 64) - current_length = 64; - else - current_length = length; - -/* dbg("%s - writing %x, %x, %d", __func__, - extAddr, addr, current_length); */ - memcpy(transfer_buffer, data, current_length); - result = usb_control_msg(serial->dev, - usb_sndctrlpipe(serial->dev, 0), - USB_REQUEST_ION_WRITE_RAM, - 0x40, addr, extAddr, transfer_buffer, - current_length, 300); - if (result < 0) - break; - length -= current_length; - addr += current_length; - data += current_length; - } - - kfree(transfer_buffer); - return result; -} - - -/**************************************************************************** - * rom_write - * writes a number of bytes to the Edgeport device's ROM starting at the - * given address. - * If successful returns the number of bytes written, otherwise it returns - * a negative error number of the problem. - ****************************************************************************/ -static int rom_write(struct usb_serial *serial, __u16 extAddr, __u16 addr, - __u16 length, const __u8 *data) -{ - int result; - __u16 current_length; - unsigned char *transfer_buffer; - -/* dbg("%s - %x, %x, %d", __func__, extAddr, addr, length); */ - - transfer_buffer = kmalloc(64, GFP_KERNEL); - if (!transfer_buffer) { - dev_err(&serial->dev->dev, "%s - kmalloc(%d) failed.\n", - __func__, 64); - return -ENOMEM; - } - - /* need to split these writes up into 64 byte chunks */ - result = 0; - while (length > 0) { - if (length > 64) - current_length = 64; - else - current_length = length; -/* dbg("%s - writing %x, %x, %d", __func__, - extAddr, addr, current_length); */ - memcpy(transfer_buffer, data, current_length); - result = usb_control_msg(serial->dev, - usb_sndctrlpipe(serial->dev, 0), - USB_REQUEST_ION_WRITE_ROM, 0x40, - addr, extAddr, - transfer_buffer, current_length, 300); - if (result < 0) - break; - length -= current_length; - addr += current_length; - data += current_length; - } - - kfree(transfer_buffer); - return result; -} - - -/**************************************************************************** - * rom_read - * reads a number of bytes from the Edgeport device starting at the given - * address. - * If successful returns the number of bytes read, otherwise it returns - * a negative error number of the problem. - ****************************************************************************/ -static int rom_read(struct usb_serial *serial, __u16 extAddr, - __u16 addr, __u16 length, __u8 *data) -{ - int result; - __u16 current_length; - unsigned char *transfer_buffer; - - dbg("%s - %x, %x, %d", __func__, extAddr, addr, length); - - transfer_buffer = kmalloc(64, GFP_KERNEL); - if (!transfer_buffer) { - dev_err(&serial->dev->dev, - "%s - kmalloc(%d) failed.\n", __func__, 64); - return -ENOMEM; - } - - /* need to split these reads up into 64 byte chunks */ - result = 0; - while (length > 0) { - if (length > 64) - current_length = 64; - else - current_length = length; -/* dbg("%s - %x, %x, %d", __func__, - extAddr, addr, current_length); */ - result = usb_control_msg(serial->dev, - usb_rcvctrlpipe(serial->dev, 0), - USB_REQUEST_ION_READ_ROM, - 0xC0, addr, extAddr, transfer_buffer, - current_length, 300); - if (result < 0) - break; - memcpy(data, transfer_buffer, current_length); - length -= current_length; - addr += current_length; - data += current_length; - } - - kfree(transfer_buffer); - return result; -} - - -/**************************************************************************** - * send_iosp_ext_cmd - * Is used to send a IOSP message to the Edgeport device - ****************************************************************************/ -static int send_iosp_ext_cmd(struct edgeport_port *edge_port, - __u8 command, __u8 param) -{ - unsigned char *buffer; - unsigned char *currentCommand; - int length = 0; - int status = 0; - - dbg("%s - %d, %d", __func__, command, param); - - buffer = kmalloc(10, GFP_ATOMIC); - if (!buffer) { - dev_err(&edge_port->port->dev, - "%s - kmalloc(%d) failed.\n", __func__, 10); - return -ENOMEM; - } - - currentCommand = buffer; - - MAKE_CMD_EXT_CMD(¤tCommand, &length, - edge_port->port->number - edge_port->port->serial->minor, - command, param); - - status = write_cmd_usb(edge_port, buffer, length); - if (status) { - /* something bad happened, let's free up the memory */ - kfree(buffer); - } - - return status; -} - - -/***************************************************************************** - * write_cmd_usb - * this function writes the given buffer out to the bulk write endpoint. - *****************************************************************************/ -static int write_cmd_usb(struct edgeport_port *edge_port, - unsigned char *buffer, int length) -{ - struct edgeport_serial *edge_serial = - usb_get_serial_data(edge_port->port->serial); - int status = 0; - struct urb *urb; - - usb_serial_debug_data(debug, &edge_port->port->dev, - __func__, length, buffer); - - /* Allocate our next urb */ - urb = usb_alloc_urb(0, GFP_ATOMIC); - if (!urb) - return -ENOMEM; - - atomic_inc(&CmdUrbs); - dbg("%s - ALLOCATE URB %p (outstanding %d)", - __func__, urb, atomic_read(&CmdUrbs)); - - usb_fill_bulk_urb(urb, edge_serial->serial->dev, - usb_sndbulkpipe(edge_serial->serial->dev, - edge_serial->bulk_out_endpoint), - buffer, length, edge_bulk_out_cmd_callback, edge_port); - - edge_port->commandPending = true; - status = usb_submit_urb(urb, GFP_ATOMIC); - - if (status) { - /* something went wrong */ - dev_err(&edge_port->port->dev, - "%s - usb_submit_urb(write command) failed, status = %d\n", - __func__, status); - usb_kill_urb(urb); - usb_free_urb(urb); - atomic_dec(&CmdUrbs); - return status; - } - -#if 0 - wait_event(&edge_port->wait_command, !edge_port->commandPending); - - if (edge_port->commandPending) { - /* command timed out */ - dbg("%s - command timed out", __func__); - status = -EINVAL; - } -#endif - return status; -} - - -/***************************************************************************** - * send_cmd_write_baud_rate - * this function sends the proper command to change the baud rate of the - * specified port. - *****************************************************************************/ -static int send_cmd_write_baud_rate(struct edgeport_port *edge_port, - int baudRate) -{ - struct edgeport_serial *edge_serial = - usb_get_serial_data(edge_port->port->serial); - unsigned char *cmdBuffer; - unsigned char *currCmd; - int cmdLen = 0; - int divisor; - int status; - unsigned char number = - edge_port->port->number - edge_port->port->serial->minor; - - if (edge_serial->is_epic && - !edge_serial->epic_descriptor.Supports.IOSPSetBaudRate) { - dbg("SendCmdWriteBaudRate - NOT Setting baud rate for port = %d, baud = %d", - edge_port->port->number, baudRate); - return 0; - } - - dbg("%s - port = %d, baud = %d", __func__, - edge_port->port->number, baudRate); - - status = calc_baud_rate_divisor(baudRate, &divisor); - if (status) { - dev_err(&edge_port->port->dev, "%s - bad baud rate\n", - __func__); - return status; - } - - /* Alloc memory for the string of commands. */ - cmdBuffer = kmalloc(0x100, GFP_ATOMIC); - if (!cmdBuffer) { - dev_err(&edge_port->port->dev, - "%s - kmalloc(%d) failed.\n", __func__, 0x100); - return -ENOMEM; - } - currCmd = cmdBuffer; - - /* Enable access to divisor latch */ - MAKE_CMD_WRITE_REG(&currCmd, &cmdLen, number, LCR, LCR_DL_ENABLE); - - /* Write the divisor itself */ - MAKE_CMD_WRITE_REG(&currCmd, &cmdLen, number, DLL, LOW8(divisor)); - MAKE_CMD_WRITE_REG(&currCmd, &cmdLen, number, DLM, HIGH8(divisor)); - - /* Restore original value to disable access to divisor latch */ - MAKE_CMD_WRITE_REG(&currCmd, &cmdLen, number, LCR, - edge_port->shadowLCR); - - status = write_cmd_usb(edge_port, cmdBuffer, cmdLen); - if (status) { - /* something bad happened, let's free up the memory */ - kfree(cmdBuffer); - } - - return status; -} - - -/***************************************************************************** - * calc_baud_rate_divisor - * this function calculates the proper baud rate divisor for the specified - * baud rate. - *****************************************************************************/ -static int calc_baud_rate_divisor(int baudrate, int *divisor) -{ - int i; - __u16 custom; - - - dbg("%s - %d", __func__, baudrate); - - for (i = 0; i < ARRAY_SIZE(divisor_table); i++) { - if (divisor_table[i].BaudRate == baudrate) { - *divisor = divisor_table[i].Divisor; - return 0; - } - } - - /* We have tried all of the standard baud rates - * lets try to calculate the divisor for this baud rate - * Make sure the baud rate is reasonable */ - if (baudrate > 50 && baudrate < 230400) { - /* get divisor */ - custom = (__u16)((230400L + baudrate/2) / baudrate); - - *divisor = custom; - - dbg("%s - Baud %d = %d", __func__, baudrate, custom); - return 0; - } - - return -1; -} - - -/***************************************************************************** - * send_cmd_write_uart_register - * this function builds up a uart register message and sends to the device. - *****************************************************************************/ -static int send_cmd_write_uart_register(struct edgeport_port *edge_port, - __u8 regNum, __u8 regValue) -{ - struct edgeport_serial *edge_serial = - usb_get_serial_data(edge_port->port->serial); - unsigned char *cmdBuffer; - unsigned char *currCmd; - unsigned long cmdLen = 0; - int status; - - dbg("%s - write to %s register 0x%02x", - (regNum == MCR) ? "MCR" : "LCR", __func__, regValue); - - if (edge_serial->is_epic && - !edge_serial->epic_descriptor.Supports.IOSPWriteMCR && - regNum == MCR) { - dbg("SendCmdWriteUartReg - Not writing to MCR Register"); - return 0; - } - - if (edge_serial->is_epic && - !edge_serial->epic_descriptor.Supports.IOSPWriteLCR && - regNum == LCR) { - dbg("SendCmdWriteUartReg - Not writing to LCR Register"); - return 0; - } - - /* Alloc memory for the string of commands. */ - cmdBuffer = kmalloc(0x10, GFP_ATOMIC); - if (cmdBuffer == NULL) - return -ENOMEM; - - currCmd = cmdBuffer; - - /* Build a cmd in the buffer to write the given register */ - MAKE_CMD_WRITE_REG(&currCmd, &cmdLen, - edge_port->port->number - edge_port->port->serial->minor, - regNum, regValue); - - status = write_cmd_usb(edge_port, cmdBuffer, cmdLen); - if (status) { - /* something bad happened, let's free up the memory */ - kfree(cmdBuffer); - } - - return status; -} - - -/***************************************************************************** - * change_port_settings - * This routine is called to set the UART on the device to match the - * specified new settings. - *****************************************************************************/ - -static void change_port_settings(struct tty_struct *tty, - struct edgeport_port *edge_port, struct ktermios *old_termios) -{ - struct edgeport_serial *edge_serial = - usb_get_serial_data(edge_port->port->serial); - int baud; - unsigned cflag; - __u8 mask = 0xff; - __u8 lData; - __u8 lParity; - __u8 lStop; - __u8 rxFlow; - __u8 txFlow; - int status; - - dbg("%s - port %d", __func__, edge_port->port->number); - - if (!edge_port->open && - !edge_port->openPending) { - dbg("%s - port not opened", __func__); - return; - } - - cflag = tty->termios->c_cflag; - - switch (cflag & CSIZE) { - case CS5: - lData = LCR_BITS_5; mask = 0x1f; - dbg("%s - data bits = 5", __func__); - break; - case CS6: - lData = LCR_BITS_6; mask = 0x3f; - dbg("%s - data bits = 6", __func__); - break; - case CS7: - lData = LCR_BITS_7; mask = 0x7f; - dbg("%s - data bits = 7", __func__); - break; - default: - case CS8: - lData = LCR_BITS_8; - dbg("%s - data bits = 8", __func__); - break; - } - - lParity = LCR_PAR_NONE; - if (cflag & PARENB) { - if (cflag & CMSPAR) { - if (cflag & PARODD) { - lParity = LCR_PAR_MARK; - dbg("%s - parity = mark", __func__); - } else { - lParity = LCR_PAR_SPACE; - dbg("%s - parity = space", __func__); - } - } else if (cflag & PARODD) { - lParity = LCR_PAR_ODD; - dbg("%s - parity = odd", __func__); - } else { - lParity = LCR_PAR_EVEN; - dbg("%s - parity = even", __func__); - } - } else { - dbg("%s - parity = none", __func__); - } - - if (cflag & CSTOPB) { - lStop = LCR_STOP_2; - dbg("%s - stop bits = 2", __func__); - } else { - lStop = LCR_STOP_1; - dbg("%s - stop bits = 1", __func__); - } - - /* figure out the flow control settings */ - rxFlow = txFlow = 0x00; - if (cflag & CRTSCTS) { - rxFlow |= IOSP_RX_FLOW_RTS; - txFlow |= IOSP_TX_FLOW_CTS; - dbg("%s - RTS/CTS is enabled", __func__); - } else { - dbg("%s - RTS/CTS is disabled", __func__); - } - - /* if we are implementing XON/XOFF, set the start and stop character - in the device */ - if (I_IXOFF(tty) || I_IXON(tty)) { - unsigned char stop_char = STOP_CHAR(tty); - unsigned char start_char = START_CHAR(tty); - - if ((!edge_serial->is_epic) || - ((edge_serial->is_epic) && - (edge_serial->epic_descriptor.Supports.IOSPSetXChar))) { - send_iosp_ext_cmd(edge_port, - IOSP_CMD_SET_XON_CHAR, start_char); - send_iosp_ext_cmd(edge_port, - IOSP_CMD_SET_XOFF_CHAR, stop_char); - } - - /* if we are implementing INBOUND XON/XOFF */ - if (I_IXOFF(tty)) { - rxFlow |= IOSP_RX_FLOW_XON_XOFF; - dbg("%s - INBOUND XON/XOFF is enabled, XON = %2x, XOFF = %2x", - __func__, start_char, stop_char); - } else { - dbg("%s - INBOUND XON/XOFF is disabled", __func__); - } - - /* if we are implementing OUTBOUND XON/XOFF */ - if (I_IXON(tty)) { - txFlow |= IOSP_TX_FLOW_XON_XOFF; - dbg("%s - OUTBOUND XON/XOFF is enabled, XON = %2x, XOFF = %2x", - __func__, start_char, stop_char); - } else { - dbg("%s - OUTBOUND XON/XOFF is disabled", __func__); - } - } - - /* Set flow control to the configured value */ - if ((!edge_serial->is_epic) || - ((edge_serial->is_epic) && - (edge_serial->epic_descriptor.Supports.IOSPSetRxFlow))) - send_iosp_ext_cmd(edge_port, IOSP_CMD_SET_RX_FLOW, rxFlow); - if ((!edge_serial->is_epic) || - ((edge_serial->is_epic) && - (edge_serial->epic_descriptor.Supports.IOSPSetTxFlow))) - send_iosp_ext_cmd(edge_port, IOSP_CMD_SET_TX_FLOW, txFlow); - - - edge_port->shadowLCR &= ~(LCR_BITS_MASK | LCR_STOP_MASK | LCR_PAR_MASK); - edge_port->shadowLCR |= (lData | lParity | lStop); - - edge_port->validDataMask = mask; - - /* Send the updated LCR value to the EdgePort */ - status = send_cmd_write_uart_register(edge_port, LCR, - edge_port->shadowLCR); - if (status != 0) - return; - - /* set up the MCR register and send it to the EdgePort */ - edge_port->shadowMCR = MCR_MASTER_IE; - if (cflag & CBAUD) - edge_port->shadowMCR |= (MCR_DTR | MCR_RTS); - - status = send_cmd_write_uart_register(edge_port, MCR, - edge_port->shadowMCR); - if (status != 0) - return; - - /* Determine divisor based on baud rate */ - baud = tty_get_baud_rate(tty); - if (!baud) { - /* pick a default, any default... */ - baud = 9600; - } - - dbg("%s - baud rate = %d", __func__, baud); - status = send_cmd_write_baud_rate(edge_port, baud); - if (status == -1) { - /* Speed change was not possible - put back the old speed */ - baud = tty_termios_baud_rate(old_termios); - tty_encode_baud_rate(tty, baud, baud); - } -} - - -/**************************************************************************** - * unicode_to_ascii - * Turns a string from Unicode into ASCII. - * Doesn't do a good job with any characters that are outside the normal - * ASCII range, but it's only for debugging... - * NOTE: expects the unicode in LE format - ****************************************************************************/ -static void unicode_to_ascii(char *string, int buflen, - __le16 *unicode, int unicode_size) -{ - int i; - - if (buflen <= 0) /* never happens, but... */ - return; - --buflen; /* space for nul */ - - for (i = 0; i < unicode_size; i++) { - if (i >= buflen) - break; - string[i] = (char)(le16_to_cpu(unicode[i])); - } - string[i] = 0x00; -} - - -/**************************************************************************** - * get_manufacturing_desc - * reads in the manufacturing descriptor and stores it into the serial - * structure. - ****************************************************************************/ -static void get_manufacturing_desc(struct edgeport_serial *edge_serial) -{ - int response; - - dbg("getting manufacturer descriptor"); - - response = rom_read(edge_serial->serial, - (EDGE_MANUF_DESC_ADDR & 0xffff0000) >> 16, - (__u16)(EDGE_MANUF_DESC_ADDR & 0x0000ffff), - EDGE_MANUF_DESC_LEN, - (__u8 *)(&edge_serial->manuf_descriptor)); - - if (response < 1) - dev_err(&edge_serial->serial->dev->dev, - "error in getting manufacturer descriptor\n"); - else { - char string[30]; - dbg("**Manufacturer Descriptor"); - dbg(" RomSize: %dK", - edge_serial->manuf_descriptor.RomSize); - dbg(" RamSize: %dK", - edge_serial->manuf_descriptor.RamSize); - dbg(" CpuRev: %d", - edge_serial->manuf_descriptor.CpuRev); - dbg(" BoardRev: %d", - edge_serial->manuf_descriptor.BoardRev); - dbg(" NumPorts: %d", - edge_serial->manuf_descriptor.NumPorts); - dbg(" DescDate: %d/%d/%d", - edge_serial->manuf_descriptor.DescDate[0], - edge_serial->manuf_descriptor.DescDate[1], - edge_serial->manuf_descriptor.DescDate[2]+1900); - unicode_to_ascii(string, sizeof(string), - edge_serial->manuf_descriptor.SerialNumber, - edge_serial->manuf_descriptor.SerNumLength/2); - dbg(" SerialNumber: %s", string); - unicode_to_ascii(string, sizeof(string), - edge_serial->manuf_descriptor.AssemblyNumber, - edge_serial->manuf_descriptor.AssemblyNumLength/2); - dbg(" AssemblyNumber: %s", string); - unicode_to_ascii(string, sizeof(string), - edge_serial->manuf_descriptor.OemAssyNumber, - edge_serial->manuf_descriptor.OemAssyNumLength/2); - dbg(" OemAssyNumber: %s", string); - dbg(" UartType: %d", - edge_serial->manuf_descriptor.UartType); - dbg(" IonPid: %d", - edge_serial->manuf_descriptor.IonPid); - dbg(" IonConfig: %d", - edge_serial->manuf_descriptor.IonConfig); - } -} - - -/**************************************************************************** - * get_boot_desc - * reads in the bootloader descriptor and stores it into the serial - * structure. - ****************************************************************************/ -static void get_boot_desc(struct edgeport_serial *edge_serial) -{ - int response; - - dbg("getting boot descriptor"); - - response = rom_read(edge_serial->serial, - (EDGE_BOOT_DESC_ADDR & 0xffff0000) >> 16, - (__u16)(EDGE_BOOT_DESC_ADDR & 0x0000ffff), - EDGE_BOOT_DESC_LEN, - (__u8 *)(&edge_serial->boot_descriptor)); - - if (response < 1) - dev_err(&edge_serial->serial->dev->dev, - "error in getting boot descriptor\n"); - else { - dbg("**Boot Descriptor:"); - dbg(" BootCodeLength: %d", - le16_to_cpu(edge_serial->boot_descriptor.BootCodeLength)); - dbg(" MajorVersion: %d", - edge_serial->boot_descriptor.MajorVersion); - dbg(" MinorVersion: %d", - edge_serial->boot_descriptor.MinorVersion); - dbg(" BuildNumber: %d", - le16_to_cpu(edge_serial->boot_descriptor.BuildNumber)); - dbg(" Capabilities: 0x%x", - le16_to_cpu(edge_serial->boot_descriptor.Capabilities)); - dbg(" UConfig0: %d", - edge_serial->boot_descriptor.UConfig0); - dbg(" UConfig1: %d", - edge_serial->boot_descriptor.UConfig1); - } -} - - -/**************************************************************************** - * load_application_firmware - * This is called to load the application firmware to the device - ****************************************************************************/ -static void load_application_firmware(struct edgeport_serial *edge_serial) -{ - const struct ihex_binrec *rec; - const struct firmware *fw; - const char *fw_name; - const char *fw_info; - int response; - __u32 Operaddr; - __u16 build; - - switch (edge_serial->product_info.iDownloadFile) { - case EDGE_DOWNLOAD_FILE_I930: - fw_info = "downloading firmware version (930)"; - fw_name = "edgeport/down.fw"; - break; - - case EDGE_DOWNLOAD_FILE_80251: - fw_info = "downloading firmware version (80251)"; - fw_name = "edgeport/down2.fw"; - break; - - case EDGE_DOWNLOAD_FILE_NONE: - dbg("No download file specified, skipping download"); - return; - - default: - return; - } - - response = request_ihex_firmware(&fw, fw_name, - &edge_serial->serial->dev->dev); - if (response) { - printk(KERN_ERR "Failed to load image \"%s\" err %d\n", - fw_name, response); - return; - } - - rec = (const struct ihex_binrec *)fw->data; - build = (rec->data[2] << 8) | rec->data[3]; - - dbg("%s %d.%d.%d", fw_info, rec->data[0], rec->data[1], build); - - edge_serial->product_info.FirmwareMajorVersion = rec->data[0]; - edge_serial->product_info.FirmwareMinorVersion = rec->data[1]; - edge_serial->product_info.FirmwareBuildNumber = cpu_to_le16(build); - - for (rec = ihex_next_binrec(rec); rec; - rec = ihex_next_binrec(rec)) { - Operaddr = be32_to_cpu(rec->addr); - response = sram_write(edge_serial->serial, - Operaddr >> 16, - Operaddr & 0xFFFF, - be16_to_cpu(rec->len), - &rec->data[0]); - if (response < 0) { - dev_err(&edge_serial->serial->dev->dev, - "sram_write failed (%x, %x, %d)\n", - Operaddr >> 16, Operaddr & 0xFFFF, - be16_to_cpu(rec->len)); - break; - } - } - - dbg("sending exec_dl_code"); - response = usb_control_msg (edge_serial->serial->dev, - usb_sndctrlpipe(edge_serial->serial->dev, 0), - USB_REQUEST_ION_EXEC_DL_CODE, - 0x40, 0x4000, 0x0001, NULL, 0, 3000); - - release_firmware(fw); -} - - -/**************************************************************************** - * edge_startup - ****************************************************************************/ -static int edge_startup(struct usb_serial *serial) -{ - struct edgeport_serial *edge_serial; - struct edgeport_port *edge_port; - struct usb_device *dev; - int i, j; - int response; - bool interrupt_in_found; - bool bulk_in_found; - bool bulk_out_found; - static __u32 descriptor[3] = { EDGE_COMPATIBILITY_MASK0, - EDGE_COMPATIBILITY_MASK1, - EDGE_COMPATIBILITY_MASK2 }; - - dev = serial->dev; - - /* create our private serial structure */ - edge_serial = kzalloc(sizeof(struct edgeport_serial), GFP_KERNEL); - if (edge_serial == NULL) { - dev_err(&serial->dev->dev, "%s - Out of memory\n", __func__); - return -ENOMEM; - } - spin_lock_init(&edge_serial->es_lock); - edge_serial->serial = serial; - usb_set_serial_data(serial, edge_serial); - - /* get the name for the device from the device */ - i = usb_string(dev, dev->descriptor.iManufacturer, - &edge_serial->name[0], MAX_NAME_LEN+1); - if (i < 0) - i = 0; - edge_serial->name[i++] = ' '; - usb_string(dev, dev->descriptor.iProduct, - &edge_serial->name[i], MAX_NAME_LEN+2 - i); - - dev_info(&serial->dev->dev, "%s detected\n", edge_serial->name); - - /* Read the epic descriptor */ - if (get_epic_descriptor(edge_serial) <= 0) { - /* memcpy descriptor to Supports structures */ - memcpy(&edge_serial->epic_descriptor.Supports, descriptor, - sizeof(struct edge_compatibility_bits)); - - /* get the manufacturing descriptor for this device */ - get_manufacturing_desc(edge_serial); - - /* get the boot descriptor */ - get_boot_desc(edge_serial); - - get_product_info(edge_serial); - } - - /* set the number of ports from the manufacturing description */ - /* serial->num_ports = serial->product_info.NumPorts; */ - if ((!edge_serial->is_epic) && - (edge_serial->product_info.NumPorts != serial->num_ports)) { - dev_warn(&serial->dev->dev, "Device Reported %d serial ports " - "vs. core thinking we have %d ports, email " - "greg@kroah.com this information.\n", - edge_serial->product_info.NumPorts, - serial->num_ports); - } - - dbg("%s - time 1 %ld", __func__, jiffies); - - /* If not an EPiC device */ - if (!edge_serial->is_epic) { - /* now load the application firmware into this device */ - load_application_firmware(edge_serial); - - dbg("%s - time 2 %ld", __func__, jiffies); - - /* Check current Edgeport EEPROM and update if necessary */ - update_edgeport_E2PROM(edge_serial); - - dbg("%s - time 3 %ld", __func__, jiffies); - - /* set the configuration to use #1 */ -/* dbg("set_configuration 1"); */ -/* usb_set_configuration (dev, 1); */ - } - dbg(" FirmwareMajorVersion %d.%d.%d", - edge_serial->product_info.FirmwareMajorVersion, - edge_serial->product_info.FirmwareMinorVersion, - le16_to_cpu(edge_serial->product_info.FirmwareBuildNumber)); - - /* we set up the pointers to the endpoints in the edge_open function, - * as the structures aren't created yet. */ - - /* set up our port private structures */ - for (i = 0; i < serial->num_ports; ++i) { - edge_port = kzalloc(sizeof(struct edgeport_port), GFP_KERNEL); - if (edge_port == NULL) { - dev_err(&serial->dev->dev, "%s - Out of memory\n", - __func__); - for (j = 0; j < i; ++j) { - kfree(usb_get_serial_port_data(serial->port[j])); - usb_set_serial_port_data(serial->port[j], - NULL); - } - usb_set_serial_data(serial, NULL); - kfree(edge_serial); - return -ENOMEM; - } - spin_lock_init(&edge_port->ep_lock); - edge_port->port = serial->port[i]; - usb_set_serial_port_data(serial->port[i], edge_port); - } - - response = 0; - - if (edge_serial->is_epic) { - /* EPIC thing, set up our interrupt polling now and our read - * urb, so that the device knows it really is connected. */ - interrupt_in_found = bulk_in_found = bulk_out_found = false; - for (i = 0; i < serial->interface->altsetting[0] - .desc.bNumEndpoints; ++i) { - struct usb_endpoint_descriptor *endpoint; - int buffer_size; - - endpoint = &serial->interface->altsetting[0]. - endpoint[i].desc; - buffer_size = usb_endpoint_maxp(endpoint); - if (!interrupt_in_found && - (usb_endpoint_is_int_in(endpoint))) { - /* we found a interrupt in endpoint */ - dbg("found interrupt in"); - - /* not set up yet, so do it now */ - edge_serial->interrupt_read_urb = - usb_alloc_urb(0, GFP_KERNEL); - if (!edge_serial->interrupt_read_urb) { - dev_err(&dev->dev, "out of memory\n"); - return -ENOMEM; - } - edge_serial->interrupt_in_buffer = - kmalloc(buffer_size, GFP_KERNEL); - if (!edge_serial->interrupt_in_buffer) { - dev_err(&dev->dev, "out of memory\n"); - usb_free_urb(edge_serial->interrupt_read_urb); - return -ENOMEM; - } - edge_serial->interrupt_in_endpoint = - endpoint->bEndpointAddress; - - /* set up our interrupt urb */ - usb_fill_int_urb( - edge_serial->interrupt_read_urb, - dev, - usb_rcvintpipe(dev, - endpoint->bEndpointAddress), - edge_serial->interrupt_in_buffer, - buffer_size, - edge_interrupt_callback, - edge_serial, - endpoint->bInterval); - - interrupt_in_found = true; - } - - if (!bulk_in_found && - (usb_endpoint_is_bulk_in(endpoint))) { - /* we found a bulk in endpoint */ - dbg("found bulk in"); - - /* not set up yet, so do it now */ - edge_serial->read_urb = - usb_alloc_urb(0, GFP_KERNEL); - if (!edge_serial->read_urb) { - dev_err(&dev->dev, "out of memory\n"); - return -ENOMEM; - } - edge_serial->bulk_in_buffer = - kmalloc(buffer_size, GFP_KERNEL); - if (!edge_serial->bulk_in_buffer) { - dev_err(&dev->dev, "out of memory\n"); - usb_free_urb(edge_serial->read_urb); - return -ENOMEM; - } - edge_serial->bulk_in_endpoint = - endpoint->bEndpointAddress; - - /* set up our bulk in urb */ - usb_fill_bulk_urb(edge_serial->read_urb, dev, - usb_rcvbulkpipe(dev, - endpoint->bEndpointAddress), - edge_serial->bulk_in_buffer, - usb_endpoint_maxp(endpoint), - edge_bulk_in_callback, - edge_serial); - bulk_in_found = true; - } - - if (!bulk_out_found && - (usb_endpoint_is_bulk_out(endpoint))) { - /* we found a bulk out endpoint */ - dbg("found bulk out"); - edge_serial->bulk_out_endpoint = - endpoint->bEndpointAddress; - bulk_out_found = true; - } - } - - if (!interrupt_in_found || !bulk_in_found || !bulk_out_found) { - dev_err(&dev->dev, "Error - the proper endpoints " - "were not found!\n"); - return -ENODEV; - } - - /* start interrupt read for this edgeport this interrupt will - * continue as long as the edgeport is connected */ - response = usb_submit_urb(edge_serial->interrupt_read_urb, - GFP_KERNEL); - if (response) - dev_err(&dev->dev, - "%s - Error %d submitting control urb\n", - __func__, response); - } - return response; -} - - -/**************************************************************************** - * edge_disconnect - * This function is called whenever the device is removed from the usb bus. - ****************************************************************************/ -static void edge_disconnect(struct usb_serial *serial) -{ - struct edgeport_serial *edge_serial = usb_get_serial_data(serial); - - dbg("%s", __func__); - - /* stop reads and writes on all ports */ - /* free up our endpoint stuff */ - if (edge_serial->is_epic) { - usb_kill_urb(edge_serial->interrupt_read_urb); - usb_free_urb(edge_serial->interrupt_read_urb); - kfree(edge_serial->interrupt_in_buffer); - - usb_kill_urb(edge_serial->read_urb); - usb_free_urb(edge_serial->read_urb); - kfree(edge_serial->bulk_in_buffer); - } -} - - -/**************************************************************************** - * edge_release - * This function is called when the device structure is deallocated. - ****************************************************************************/ -static void edge_release(struct usb_serial *serial) -{ - struct edgeport_serial *edge_serial = usb_get_serial_data(serial); - int i; - - dbg("%s", __func__); - - for (i = 0; i < serial->num_ports; ++i) - kfree(usb_get_serial_port_data(serial->port[i])); - - kfree(edge_serial); -} - -module_usb_serial_driver(io_driver, serial_drivers); - -MODULE_AUTHOR(DRIVER_AUTHOR); -MODULE_DESCRIPTION(DRIVER_DESC); -MODULE_LICENSE("GPL"); -MODULE_FIRMWARE("edgeport/boot.fw"); -MODULE_FIRMWARE("edgeport/boot2.fw"); -MODULE_FIRMWARE("edgeport/down.fw"); -MODULE_FIRMWARE("edgeport/down2.fw"); - -module_param(debug, bool, S_IRUGO | S_IWUSR); -MODULE_PARM_DESC(debug, "Debug enabled or not"); diff --git a/ANDROID_3.4.5/drivers/usb/serial/io_edgeport.h b/ANDROID_3.4.5/drivers/usb/serial/io_edgeport.h deleted file mode 100644 index ad9c1d47..00000000 --- a/ANDROID_3.4.5/drivers/usb/serial/io_edgeport.h +++ /dev/null @@ -1,134 +0,0 @@ -/************************************************************************ - * - * io_edgeport.h Edgeport Linux Interface definitions - * - * Copyright (C) 2000 Inside Out Networks, Inc. - * - * 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. - * - * - ************************************************************************/ - -#if !defined(_IO_EDGEPORT_H_) -#define _IO_EDGEPORT_H_ - - -#define MAX_RS232_PORTS 8 /* Max # of RS-232 ports per device */ - -/* typedefs that the insideout headers need */ -#ifndef LOW8 - #define LOW8(a) ((unsigned char)(a & 0xff)) -#endif -#ifndef HIGH8 - #define HIGH8(a) ((unsigned char)((a & 0xff00) >> 8)) -#endif - -#ifndef __KERNEL__ -#define __KERNEL__ -#endif - -#include "io_usbvend.h" - - - -/* The following table is used to map the USBx port number to - * the device serial number (or physical USB path), */ -#define MAX_EDGEPORTS 64 - -struct comMapper { - char SerialNumber[MAX_SERIALNUMBER_LEN+1]; /* Serial number/usb path */ - int numPorts; /* Number of ports */ - int Original[MAX_RS232_PORTS]; /* Port numbers set by IOCTL */ - int Port[MAX_RS232_PORTS]; /* Actual used port numbers */ -}; - - -#define EDGEPORT_CONFIG_DEVICE "/proc/edgeport" - -/* /proc/edgeport Interface - * This interface uses read/write/lseek interface to talk to the edgeport driver - * the following read functions are supported: */ -#define PROC_GET_MAPPING_TO_PATH 1 -#define PROC_GET_COM_ENTRY 2 -#define PROC_GET_EDGE_MANUF_DESCRIPTOR 3 -#define PROC_GET_BOOT_DESCRIPTOR 4 -#define PROC_GET_PRODUCT_INFO 5 -#define PROC_GET_STRINGS 6 -#define PROC_GET_CURRENT_COM_MAPPING 7 - -/* The parameters to the lseek() for the read is: */ -#define PROC_READ_SETUP(Command, Argument) ((Command) + ((Argument)<<8)) - - -/* the following write functions are supported: */ -#define PROC_SET_COM_MAPPING 1 -#define PROC_SET_COM_ENTRY 2 - - -/* The following structure is passed to the write */ -struct procWrite { - int Command; - union { - struct comMapper Entry; - int ComMappingBasedOnUSBPort; /* Boolean value */ - } u; -}; - -/* - * Product information read from the Edgeport - */ -struct edgeport_product_info { - __u16 ProductId; /* Product Identifier */ - __u8 NumPorts; /* Number of ports on edgeport */ - __u8 ProdInfoVer; /* What version of structure is this? */ - - __u32 IsServer :1; /* Set if Server */ - __u32 IsRS232 :1; /* Set if RS-232 ports exist */ - __u32 IsRS422 :1; /* Set if RS-422 ports exist */ - __u32 IsRS485 :1; /* Set if RS-485 ports exist */ - __u32 IsReserved :28; /* Reserved for later expansion */ - - __u8 RomSize; /* Size of ROM/E2PROM in K */ - __u8 RamSize; /* Size of external RAM in K */ - __u8 CpuRev; /* CPU revision level (chg only if s/w visible) */ - __u8 BoardRev; /* PCB revision level (chg only if s/w visible) */ - - __u8 BootMajorVersion; /* Boot Firmware version: xx. */ - __u8 BootMinorVersion; /* yy. */ - __le16 BootBuildNumber; /* zzzz (LE format) */ - - __u8 FirmwareMajorVersion; /* Operational Firmware version:xx. */ - __u8 FirmwareMinorVersion; /* yy. */ - __le16 FirmwareBuildNumber; /* zzzz (LE format) */ - - __u8 ManufactureDescDate[3]; /* MM/DD/YY when descriptor template was compiled */ - __u8 HardwareType; - - __u8 iDownloadFile; /* What to download to EPiC device */ - __u8 EpicVer; /* What version of EPiC spec this device supports */ - - struct edge_compatibility_bits Epic; -}; - -/* - * Edgeport Stringblock String locations - */ -#define EDGESTRING_MANUFNAME 1 /* Manufacture Name */ -#define EDGESTRING_PRODNAME 2 /* Product Name */ -#define EDGESTRING_SERIALNUM 3 /* Serial Number */ -#define EDGESTRING_ASSEMNUM 4 /* Assembly Number */ -#define EDGESTRING_OEMASSEMNUM 5 /* OEM Assembly Number */ -#define EDGESTRING_MANUFDATE 6 /* Manufacture Date */ -#define EDGESTRING_ORIGSERIALNUM 7 /* Serial Number */ - -struct string_block { - __u16 NumStrings; /* Number of strings in block */ - __u16 Strings[1]; /* Start of string block */ -}; - - - -#endif diff --git a/ANDROID_3.4.5/drivers/usb/serial/io_ionsp.h b/ANDROID_3.4.5/drivers/usb/serial/io_ionsp.h deleted file mode 100644 index 5cc591ba..00000000 --- a/ANDROID_3.4.5/drivers/usb/serial/io_ionsp.h +++ /dev/null @@ -1,455 +0,0 @@ -/************************************************************************ - * - * IONSP.H Definitions for I/O Networks Serial Protocol - * - * Copyright (C) 1997-1998 Inside Out Networks, Inc. - * - * 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. - * - * These definitions are used by both kernel-mode driver and the - * peripheral firmware and MUST be kept in sync. - * - ************************************************************************/ - -/************************************************************************ - -The data to and from all ports on the peripheral is multiplexed -through a single endpoint pair (EP1 since it supports 64-byte -MaxPacketSize). Therefore, the data, commands, and status for -each port must be preceded by a short header identifying the -destination port. The header also identifies the bytes that follow -as data or as command/status info. - -Header format, first byte: - - CLLLLPPP - -------- - | | |------ Port Number: 0-7 - | |--------- Length: MSB bits of length - |----------- Data/Command: 0 = Data header - 1 = Cmd / Status (Cmd if OUT, Status if IN) - -This gives 2 possible formats: - - - Data header: 0LLLLPPP LLLLLLLL - ============ - - Where (LLLL,LLLLLLL) is 12-bit length of data that follows for - port number (PPP). The length is 0-based (0-FFF means 0-4095 - bytes). The ~4K limit allows the host driver (which deals in - transfer requests instead of individual packets) to write a - large chunk of data in a single request. Note, however, that - the length must always be <= the current TxCredits for a given - port due to buffering limitations on the peripheral. - - - Cmd/Status header: 1ccccPPP [ CCCCCCCC, Params ]... - ================== - - Where (cccc) or (cccc,CCCCCCCC) is the cmd or status identifier. - Frequently-used values are encoded as (cccc), longer ones using - (cccc,CCCCCCCC). Subsequent bytes are optional parameters and are - specific to the cmd or status code. This may include a length - for command and status codes that need variable-length parameters. - - -In addition, we use another interrupt pipe (endpoint) which the host polls -periodically for flow control information. The peripheral, when there has -been a change, sends the following 10-byte packet: - - RRRRRRRRRRRRRRRR - T0T0T0T0T0T0T0T0 - T1T1T1T1T1T1T1T1 - T2T2T2T2T2T2T2T2 - T3T3T3T3T3T3T3T3 - -The first field is the 16-bit RxBytesAvail field, which indicates the -number of bytes which may be read by the host from EP1. This is necessary: -(a) because OSR2.1 has a bug which causes data loss if the peripheral returns -fewer bytes than the host expects to read, and (b) because, on Microsoft -platforms at least, an outstanding read posted on EP1 consumes about 35% of -the CPU just polling the device for data. - -The next 4 fields are the 16-bit TxCredits for each port, which indicate how -many bytes the host is allowed to send on EP1 for transmit to a given port. -After an OPEN_PORT command, the Edgeport sends the initial TxCredits for that -port. - -All 16-bit fields are sent in little-endian (Intel) format. - -************************************************************************/ - -// -// Define format of InterruptStatus packet returned from the -// Interrupt pipe -// - -struct int_status_pkt { - __u16 RxBytesAvail; // Additional bytes available to - // be read from Bulk IN pipe - __u16 TxCredits[MAX_RS232_PORTS]; // Additional space available in - // given port's TxBuffer -}; - - -#define GET_INT_STATUS_SIZE(NumPorts) (sizeof(__u16) + (sizeof(__u16) * (NumPorts))) - - - -// -// Define cmd/status header values and macros to extract them. -// -// Data: 0LLLLPPP LLLLLLLL -// Cmd/Stat: 1ccccPPP CCCCCCCC - -#define IOSP_DATA_HDR_SIZE 2 -#define IOSP_CMD_HDR_SIZE 2 - -#define IOSP_MAX_DATA_LENGTH 0x0FFF // 12 bits -> 4K - -#define IOSP_PORT_MASK 0x07 // Mask to isolate port number -#define IOSP_CMD_STAT_BIT 0x80 // If set, this is command/status header - -#define IS_CMD_STAT_HDR(Byte1) ((Byte1) & IOSP_CMD_STAT_BIT) -#define IS_DATA_HDR(Byte1) (!IS_CMD_STAT_HDR(Byte1)) - -#define IOSP_GET_HDR_PORT(Byte1) ((__u8) ((Byte1) & IOSP_PORT_MASK)) -#define IOSP_GET_HDR_DATA_LEN(Byte1, Byte2) ((__u16) (((__u16)((Byte1) & 0x78)) << 5) | (Byte2)) -#define IOSP_GET_STATUS_CODE(Byte1) ((__u8) (((Byte1) & 0x78) >> 3)) - - -// -// These macros build the 1st and 2nd bytes for a data header -// -#define IOSP_BUILD_DATA_HDR1(Port, Len) ((__u8) (((Port) | ((__u8) (((__u16) (Len)) >> 5) & 0x78)))) -#define IOSP_BUILD_DATA_HDR2(Port, Len) ((__u8) (Len)) - - -// -// These macros build the 1st and 2nd bytes for a command header -// -#define IOSP_BUILD_CMD_HDR1(Port, Cmd) ((__u8) (IOSP_CMD_STAT_BIT | (Port) | ((__u8) ((Cmd) << 3)))) - - -//-------------------------------------------------------------- -// -// Define values for commands and command parameters -// (sent from Host to Edgeport) -// -// 1ccccPPP P1P1P1P1 [ P2P2P2P2P2 ]... -// -// cccc: 00-07 2-byte commands. Write UART register 0-7 with -// value in P1. See 16650.H for definitions of -// UART register numbers and contents. -// -// 08-0B 3-byte commands: ==== P1 ==== ==== P2 ==== -// 08 available for expansion -// 09 1-param commands Command Code Param -// 0A available for expansion -// 0B available for expansion -// -// 0C-0D 4-byte commands. P1 = extended cmd and P2,P3 = params -// Currently unimplemented. -// -// 0E-0F N-byte commands: P1 = num bytes after P1 (ie, TotalLen - 2) -// P2 = extended cmd, P3..Pn = parameters. -// Currently unimplemented. -// - -#define IOSP_WRITE_UART_REG(n) ((n) & 0x07) // UartReg[ n ] := P1 - -// Register numbers and contents -// defined in 16554.H. - -// 0x08 // Available for expansion. -#define IOSP_EXT_CMD 0x09 // P1 = Command code (defined below) - -// P2 = Parameter - -// -// Extended Command values, used with IOSP_EXT_CMD, may -// or may not use parameter P2. -// - -#define IOSP_CMD_OPEN_PORT 0x00 // Enable ints, init UART. (NO PARAM) -#define IOSP_CMD_CLOSE_PORT 0x01 // Disable ints, flush buffers. (NO PARAM) -#define IOSP_CMD_CHASE_PORT 0x02 // Wait for Edgeport TX buffers to empty. (NO PARAM) -#define IOSP_CMD_SET_RX_FLOW 0x03 // Set Rx Flow Control in Edgeport -#define IOSP_CMD_SET_TX_FLOW 0x04 // Set Tx Flow Control in Edgeport -#define IOSP_CMD_SET_XON_CHAR 0x05 // Set XON Character in Edgeport -#define IOSP_CMD_SET_XOFF_CHAR 0x06 // Set XOFF Character in Edgeport -#define IOSP_CMD_RX_CHECK_REQ 0x07 // Request Edgeport to insert a Checkpoint into - -// the receive data stream (Parameter = 1 byte sequence number) - -#define IOSP_CMD_SET_BREAK 0x08 // Turn on the BREAK (LCR bit 6) -#define IOSP_CMD_CLEAR_BREAK 0x09 // Turn off the BREAK (LCR bit 6) - - -// -// Define macros to simplify building of IOSP cmds -// - -#define MAKE_CMD_WRITE_REG(ppBuf, pLen, Port, Reg, Val) \ -do { \ - (*(ppBuf))[0] = IOSP_BUILD_CMD_HDR1((Port), \ - IOSP_WRITE_UART_REG(Reg)); \ - (*(ppBuf))[1] = (Val); \ - \ - *ppBuf += 2; \ - *pLen += 2; \ -} while (0) - -#define MAKE_CMD_EXT_CMD(ppBuf, pLen, Port, ExtCmd, Param) \ -do { \ - (*(ppBuf))[0] = IOSP_BUILD_CMD_HDR1((Port), IOSP_EXT_CMD); \ - (*(ppBuf))[1] = (ExtCmd); \ - (*(ppBuf))[2] = (Param); \ - \ - *ppBuf += 3; \ - *pLen += 3; \ -} while (0) - - - -//-------------------------------------------------------------- -// -// Define format of flow control commands -// (sent from Host to Edgeport) -// -// 11001PPP FlowCmd FlowTypes -// -// Note that the 'FlowTypes' parameter is a bit mask; that is, -// more than one flow control type can be active at the same time. -// FlowTypes = 0 means 'no flow control'. -// - -// -// IOSP_CMD_SET_RX_FLOW -// -// Tells Edgeport how it can stop incoming UART data -// -// Example for Port 0 -// P0 = 11001000 -// P1 = IOSP_CMD_SET_RX_FLOW -// P2 = Bit mask as follows: - -#define IOSP_RX_FLOW_RTS 0x01 // Edgeport drops RTS to stop incoming data -#define IOSP_RX_FLOW_DTR 0x02 // Edgeport drops DTR to stop incoming data -#define IOSP_RX_FLOW_DSR_SENSITIVITY 0x04 // Ignores Rx data unless DSR high - -// Not currently implemented by firmware. -#define IOSP_RX_FLOW_XON_XOFF 0x08 // Edgeport sends XOFF char to stop incoming data. - -// Host must have previously programmed the -// XON/XOFF values with SET_XON/SET_XOFF -// before enabling this bit. - -// -// IOSP_CMD_SET_TX_FLOW -// -// Tells Edgeport what signal(s) will stop it from transmitting UART data -// -// Example for Port 0 -// P0 = 11001000 -// P1 = IOSP_CMD_SET_TX_FLOW -// P2 = Bit mask as follows: - -#define IOSP_TX_FLOW_CTS 0x01 // Edgeport stops Tx if CTS low -#define IOSP_TX_FLOW_DSR 0x02 // Edgeport stops Tx if DSR low -#define IOSP_TX_FLOW_DCD 0x04 // Edgeport stops Tx if DCD low -#define IOSP_TX_FLOW_XON_XOFF 0x08 // Edgeport stops Tx upon receiving XOFF char. - -// Host must have previously programmed the -// XON/XOFF values with SET_XON/SET_XOFF -// before enabling this bit. -#define IOSP_TX_FLOW_XOFF_CONTINUE 0x10 // If not set, Edgeport stops Tx when - -// sending XOFF in order to fix broken -// systems that interpret the next -// received char as XON. -// If set, Edgeport continues Tx -// normally after transmitting XOFF. -// Not currently implemented by firmware. -#define IOSP_TX_TOGGLE_RTS 0x20 // Edgeport drives RTS as a true half-duplex - -// Request-to-Send signal: it is raised before -// beginning transmission and lowered after -// the last Tx char leaves the UART. -// Not currently implemented by firmware. - -// -// IOSP_CMD_SET_XON_CHAR -// -// Sets the character which Edgeport transmits/interprets as XON. -// Note: This command MUST be sent before sending a SET_RX_FLOW or -// SET_TX_FLOW with the XON_XOFF bit set. -// -// Example for Port 0 -// P0 = 11001000 -// P1 = IOSP_CMD_SET_XON_CHAR -// P2 = 0x11 - - -// -// IOSP_CMD_SET_XOFF_CHAR -// -// Sets the character which Edgeport transmits/interprets as XOFF. -// Note: This command must be sent before sending a SET_RX_FLOW or -// SET_TX_FLOW with the XON_XOFF bit set. -// -// Example for Port 0 -// P0 = 11001000 -// P1 = IOSP_CMD_SET_XOFF_CHAR -// P2 = 0x13 - - -// -// IOSP_CMD_RX_CHECK_REQ -// -// This command is used to assist in the implementation of the -// IOCTL_SERIAL_PURGE Windows IOCTL. -// This IOSP command tries to place a marker at the end of the RX -// queue in the Edgeport. If the Edgeport RX queue is full then -// the Check will be discarded. -// It is up to the device driver to timeout waiting for the -// RX_CHECK_RSP. If a RX_CHECK_RSP is received, the driver is -// sure that all data has been received from the edgeport and -// may now purge any internal RX buffers. -// Note tat the sequence numbers may be used to detect lost -// CHECK_REQs. - -// Example for Port 0 -// P0 = 11001000 -// P1 = IOSP_CMD_RX_CHECK_REQ -// P2 = Sequence number - - -// Response will be: -// P1 = IOSP_EXT_RX_CHECK_RSP -// P2 = Request Sequence number - - - -//-------------------------------------------------------------- -// -// Define values for status and status parameters -// (received by Host from Edgeport) -// -// 1ssssPPP P1P1P1P1 [ P2P2P2P2P2 ]... -// -// ssss: 00-07 2-byte status. ssss identifies which UART register -// has changed value, and the new value is in P1. -// Note that the ssss values do not correspond to the -// 16554 register numbers given in 16554.H. Instead, -// see below for definitions of the ssss numbers -// used in this status message. -// -// 08-0B 3-byte status: ==== P1 ==== ==== P2 ==== -// 08 LSR_DATA: New LSR Errored byte -// 09 1-param responses Response Code Param -// 0A OPEN_RSP: InitialMsr TxBufferSize -// 0B available for expansion -// -// 0C-0D 4-byte status. P1 = extended status code and P2,P3 = params -// Not currently implemented. -// -// 0E-0F N-byte status: P1 = num bytes after P1 (ie, TotalLen - 2) -// P2 = extended status, P3..Pn = parameters. -// Not currently implemented. -// - -/**************************************************** - * SSSS values for 2-byte status messages (0-8) - ****************************************************/ - -#define IOSP_STATUS_LSR 0x00 // P1 is new value of LSR register. - -// Bits defined in 16554.H. Edgeport -// returns this in order to report -// line status errors (overrun, -// parity, framing, break). This form -// is used when a errored receive data -// character was NOT present in the -// UART when the LSR error occurred -// (ie, when LSR bit 0 = 0). - -#define IOSP_STATUS_MSR 0x01 // P1 is new value of MSR register. - -// Bits defined in 16554.H. Edgeport -// returns this in order to report -// changes in modem status lines -// (CTS, DSR, RI, CD) -// - -// 0x02 // Available for future expansion -// 0x03 // -// 0x04 // -// 0x05 // -// 0x06 // -// 0x07 // - - -/**************************************************** - * SSSS values for 3-byte status messages (8-A) - ****************************************************/ - -#define IOSP_STATUS_LSR_DATA 0x08 // P1 is new value of LSR register (same as STATUS_LSR) - -// P2 is errored character read from -// RxFIFO after LSR reported an error. - -#define IOSP_EXT_STATUS 0x09 // P1 is status/response code, param in P2. - - -// Response Codes (P1 values) for 3-byte status messages - -#define IOSP_EXT_STATUS_CHASE_RSP 0 // Reply to CHASE_PORT cmd. P2 is outcome: -#define IOSP_EXT_STATUS_CHASE_PASS 0 // P2 = 0: All Tx data drained successfully -#define IOSP_EXT_STATUS_CHASE_FAIL 1 // P2 = 1: Timed out (stuck due to flow - -// control from remote device). - -#define IOSP_EXT_STATUS_RX_CHECK_RSP 1 // Reply to RX_CHECK cmd. P2 is sequence number - - -#define IOSP_STATUS_OPEN_RSP 0x0A // Reply to OPEN_PORT cmd. - -// P1 is Initial MSR value -// P2 is encoded TxBuffer Size: -// TxBufferSize = (P2 + 1) * 64 - -// 0x0B // Available for future expansion - -#define GET_TX_BUFFER_SIZE(P2) (((P2) + 1) * 64) - - - - -/**************************************************** - * SSSS values for 4-byte status messages - ****************************************************/ - -#define IOSP_EXT4_STATUS 0x0C // Extended status code in P1, - -// Params in P2, P3 -// Currently unimplemented. - -// 0x0D // Currently unused, available. - - - -// -// Macros to parse status messages -// - -#define IOSP_GET_STATUS_LEN(code) ((code) < 8 ? 2 : ((code) < 0x0A ? 3 : 4)) - -#define IOSP_STATUS_IS_2BYTE(code) ((code) < 0x08) -#define IOSP_STATUS_IS_3BYTE(code) (((code) >= 0x08) && ((code) <= 0x0B)) -#define IOSP_STATUS_IS_4BYTE(code) (((code) >= 0x0C) && ((code) <= 0x0D)) - diff --git a/ANDROID_3.4.5/drivers/usb/serial/io_tables.h b/ANDROID_3.4.5/drivers/usb/serial/io_tables.h deleted file mode 100644 index d0e7c9af..00000000 --- a/ANDROID_3.4.5/drivers/usb/serial/io_tables.h +++ /dev/null @@ -1,227 +0,0 @@ -/* - * IO Edgeport Driver tables - * - * Copyright (C) 2001 - * Greg Kroah-Hartman (greg@kroah.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. - * - */ - -#ifndef IO_TABLES_H -#define IO_TABLES_H - -static const struct usb_device_id edgeport_2port_id_table[] = { - { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_EDGEPORT_2) }, - { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_EDGEPORT_2I) }, - { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_EDGEPORT_421) }, - { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_EDGEPORT_21) }, - { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_EDGEPORT_2_DIN) }, - { } -}; - -static const struct usb_device_id edgeport_4port_id_table[] = { - { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_EDGEPORT_4) }, - { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_RAPIDPORT_4) }, - { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_EDGEPORT_4T) }, - { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_MT4X56USB) }, - { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_EDGEPORT_4I) }, - { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_EDGEPORT_8_DUAL_CPU) }, - { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_EDGEPORT_4_DIN) }, - { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_EDGEPORT_22I) }, - { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_EDGEPORT_412_4) }, - { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_EDGEPORT_COMPATIBLE) }, - { } -}; - -static const struct usb_device_id edgeport_8port_id_table[] = { - { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_EDGEPORT_8) }, - { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_EDGEPORT_16_DUAL_CPU) }, - { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_EDGEPORT_8I) }, - { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_EDGEPORT_8R) }, - { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_EDGEPORT_8RR) }, - { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_EDGEPORT_412_8) }, - { } -}; - -static const struct usb_device_id Epic_port_id_table[] = { - { USB_DEVICE(USB_VENDOR_ID_NCR, NCR_DEVICE_ID_EPIC_0202) }, - { USB_DEVICE(USB_VENDOR_ID_NCR, NCR_DEVICE_ID_EPIC_0203) }, - { USB_DEVICE(USB_VENDOR_ID_NCR, NCR_DEVICE_ID_EPIC_0310) }, - { USB_DEVICE(USB_VENDOR_ID_NCR, NCR_DEVICE_ID_EPIC_0311) }, - { USB_DEVICE(USB_VENDOR_ID_NCR, NCR_DEVICE_ID_EPIC_0312) }, - { USB_DEVICE(USB_VENDOR_ID_AXIOHM, AXIOHM_DEVICE_ID_EPIC_A758) }, - { USB_DEVICE(USB_VENDOR_ID_AXIOHM, AXIOHM_DEVICE_ID_EPIC_A794) }, - { USB_DEVICE(USB_VENDOR_ID_AXIOHM, AXIOHM_DEVICE_ID_EPIC_A225) }, - { } -}; - -/* Devices that this driver supports */ -static const struct usb_device_id id_table_combined[] = { - { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_EDGEPORT_4) }, - { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_RAPIDPORT_4) }, - { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_EDGEPORT_4T) }, - { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_MT4X56USB) }, - { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_EDGEPORT_2) }, - { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_EDGEPORT_4I) }, - { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_EDGEPORT_2I) }, - { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_EDGEPORT_421) }, - { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_EDGEPORT_21) }, - { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_EDGEPORT_8_DUAL_CPU) }, - { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_EDGEPORT_8) }, - { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_EDGEPORT_2_DIN) }, - { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_EDGEPORT_4_DIN) }, - { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_EDGEPORT_16_DUAL_CPU) }, - { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_EDGEPORT_22I) }, - { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_EDGEPORT_412_4) }, - { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_EDGEPORT_COMPATIBLE) }, - { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_EDGEPORT_8I) }, - { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_EDGEPORT_8R) }, - { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_EDGEPORT_8RR) }, - { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_EDGEPORT_412_8) }, - { USB_DEVICE(USB_VENDOR_ID_NCR, NCR_DEVICE_ID_EPIC_0202) }, - { USB_DEVICE(USB_VENDOR_ID_NCR, NCR_DEVICE_ID_EPIC_0203) }, - { USB_DEVICE(USB_VENDOR_ID_NCR, NCR_DEVICE_ID_EPIC_0310) }, - { USB_DEVICE(USB_VENDOR_ID_NCR, NCR_DEVICE_ID_EPIC_0311) }, - { USB_DEVICE(USB_VENDOR_ID_NCR, NCR_DEVICE_ID_EPIC_0312) }, - { USB_DEVICE(USB_VENDOR_ID_AXIOHM, AXIOHM_DEVICE_ID_EPIC_A758) }, - { USB_DEVICE(USB_VENDOR_ID_AXIOHM, AXIOHM_DEVICE_ID_EPIC_A794) }, - { USB_DEVICE(USB_VENDOR_ID_AXIOHM, AXIOHM_DEVICE_ID_EPIC_A225) }, - { } /* Terminating entry */ -}; - -MODULE_DEVICE_TABLE(usb, id_table_combined); - -static struct usb_driver io_driver = { - .name = "io_edgeport", - .probe = usb_serial_probe, - .disconnect = usb_serial_disconnect, - .id_table = id_table_combined, -}; - -static struct usb_serial_driver edgeport_2port_device = { - .driver = { - .owner = THIS_MODULE, - .name = "edgeport_2", - }, - .description = "Edgeport 2 port adapter", - .id_table = edgeport_2port_id_table, - .num_ports = 2, - .open = edge_open, - .close = edge_close, - .throttle = edge_throttle, - .unthrottle = edge_unthrottle, - .attach = edge_startup, - .disconnect = edge_disconnect, - .release = edge_release, - .ioctl = edge_ioctl, - .set_termios = edge_set_termios, - .tiocmget = edge_tiocmget, - .tiocmset = edge_tiocmset, - .get_icount = edge_get_icount, - .write = edge_write, - .write_room = edge_write_room, - .chars_in_buffer = edge_chars_in_buffer, - .break_ctl = edge_break, - .read_int_callback = edge_interrupt_callback, - .read_bulk_callback = edge_bulk_in_callback, - .write_bulk_callback = edge_bulk_out_data_callback, -}; - -static struct usb_serial_driver edgeport_4port_device = { - .driver = { - .owner = THIS_MODULE, - .name = "edgeport_4", - }, - .description = "Edgeport 4 port adapter", - .id_table = edgeport_4port_id_table, - .num_ports = 4, - .open = edge_open, - .close = edge_close, - .throttle = edge_throttle, - .unthrottle = edge_unthrottle, - .attach = edge_startup, - .disconnect = edge_disconnect, - .release = edge_release, - .ioctl = edge_ioctl, - .set_termios = edge_set_termios, - .tiocmget = edge_tiocmget, - .tiocmset = edge_tiocmset, - .get_icount = edge_get_icount, - .write = edge_write, - .write_room = edge_write_room, - .chars_in_buffer = edge_chars_in_buffer, - .break_ctl = edge_break, - .read_int_callback = edge_interrupt_callback, - .read_bulk_callback = edge_bulk_in_callback, - .write_bulk_callback = edge_bulk_out_data_callback, -}; - -static struct usb_serial_driver edgeport_8port_device = { - .driver = { - .owner = THIS_MODULE, - .name = "edgeport_8", - }, - .description = "Edgeport 8 port adapter", - .id_table = edgeport_8port_id_table, - .num_ports = 8, - .open = edge_open, - .close = edge_close, - .throttle = edge_throttle, - .unthrottle = edge_unthrottle, - .attach = edge_startup, - .disconnect = edge_disconnect, - .release = edge_release, - .ioctl = edge_ioctl, - .set_termios = edge_set_termios, - .tiocmget = edge_tiocmget, - .tiocmset = edge_tiocmset, - .get_icount = edge_get_icount, - .write = edge_write, - .write_room = edge_write_room, - .chars_in_buffer = edge_chars_in_buffer, - .break_ctl = edge_break, - .read_int_callback = edge_interrupt_callback, - .read_bulk_callback = edge_bulk_in_callback, - .write_bulk_callback = edge_bulk_out_data_callback, -}; - -static struct usb_serial_driver epic_device = { - .driver = { - .owner = THIS_MODULE, - .name = "epic", - }, - .description = "EPiC device", - .id_table = Epic_port_id_table, - .num_ports = 1, - .open = edge_open, - .close = edge_close, - .throttle = edge_throttle, - .unthrottle = edge_unthrottle, - .attach = edge_startup, - .disconnect = edge_disconnect, - .release = edge_release, - .ioctl = edge_ioctl, - .set_termios = edge_set_termios, - .tiocmget = edge_tiocmget, - .tiocmset = edge_tiocmset, - .get_icount = edge_get_icount, - .write = edge_write, - .write_room = edge_write_room, - .chars_in_buffer = edge_chars_in_buffer, - .break_ctl = edge_break, - .read_int_callback = edge_interrupt_callback, - .read_bulk_callback = edge_bulk_in_callback, - .write_bulk_callback = edge_bulk_out_data_callback, -}; - -static struct usb_serial_driver * const serial_drivers[] = { - &edgeport_2port_device, &edgeport_4port_device, - &edgeport_8port_device, &epic_device, NULL -}; - -#endif - diff --git a/ANDROID_3.4.5/drivers/usb/serial/io_ti.c b/ANDROID_3.4.5/drivers/usb/serial/io_ti.c deleted file mode 100644 index 40a95a7f..00000000 --- a/ANDROID_3.4.5/drivers/usb/serial/io_ti.c +++ /dev/null @@ -1,2804 +0,0 @@ -/* - * Edgeport USB Serial Converter driver - * - * Copyright (C) 2000-2002 Inside Out Networks, All rights reserved. - * Copyright (C) 2001-2002 Greg Kroah-Hartman <greg@kroah.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. - * - * Supports the following devices: - * EP/1 EP/2 EP/4 EP/21 EP/22 EP/221 EP/42 EP/421 WATCHPORT - * - * For questions or problems with this driver, contact Inside Out - * Networks technical support, or Peter Berger <pberger@brimson.com>, - * or Al Borchers <alborchers@steinerpoint.com>. - */ - -#include <linux/kernel.h> -#include <linux/jiffies.h> -#include <linux/errno.h> -#include <linux/init.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/serial.h> -#include <linux/kfifo.h> -#include <linux/ioctl.h> -#include <linux/firmware.h> -#include <linux/uaccess.h> -#include <linux/usb.h> -#include <linux/usb/serial.h> - -#include "io_16654.h" -#include "io_usbvend.h" -#include "io_ti.h" - -/* - * Version Information - */ -#define DRIVER_VERSION "v0.7mode043006" -#define DRIVER_AUTHOR "Greg Kroah-Hartman <greg@kroah.com> and David Iacovelli" -#define DRIVER_DESC "Edgeport USB Serial Driver" - -#define EPROM_PAGE_SIZE 64 - - -/* different hardware types */ -#define HARDWARE_TYPE_930 0 -#define HARDWARE_TYPE_TIUMP 1 - -/* IOCTL_PRIVATE_TI_GET_MODE Definitions */ -#define TI_MODE_CONFIGURING 0 /* Device has not entered start device */ -#define TI_MODE_BOOT 1 /* Staying in boot mode */ -#define TI_MODE_DOWNLOAD 2 /* Made it to download mode */ -#define TI_MODE_TRANSITIONING 3 /* Currently in boot mode but - transitioning to download mode */ - -/* read urb state */ -#define EDGE_READ_URB_RUNNING 0 -#define EDGE_READ_URB_STOPPING 1 -#define EDGE_READ_URB_STOPPED 2 - -#define EDGE_CLOSING_WAIT 4000 /* in .01 sec */ - -#define EDGE_OUT_BUF_SIZE 1024 - - -/* Product information read from the Edgeport */ -struct product_info { - int TiMode; /* Current TI Mode */ - __u8 hardware_type; /* Type of hardware */ -} __attribute__((packed)); - -struct edgeport_port { - __u16 uart_base; - __u16 dma_address; - __u8 shadow_msr; - __u8 shadow_mcr; - __u8 shadow_lsr; - __u8 lsr_mask; - __u32 ump_read_timeout; /* Number of milliseconds the UMP will - wait without data before completing - a read short */ - int baud_rate; - int close_pending; - int lsr_event; - struct async_icount icount; - wait_queue_head_t delta_msr_wait; /* for handling sleeping while - waiting for msr change to - happen */ - struct edgeport_serial *edge_serial; - struct usb_serial_port *port; - __u8 bUartMode; /* Port type, 0: RS232, etc. */ - spinlock_t ep_lock; - int ep_read_urb_state; - int ep_write_urb_in_use; - struct kfifo write_fifo; -}; - -struct edgeport_serial { - struct product_info product_info; - u8 TI_I2C_Type; /* Type of I2C in UMP */ - u8 TiReadI2C; /* Set to TRUE if we have read the - I2c in Boot Mode */ - struct mutex es_lock; - int num_ports_open; - struct usb_serial *serial; -}; - - -/* Devices that this driver supports */ -static const struct usb_device_id edgeport_1port_id_table[] = { - { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_EDGEPORT_1) }, - { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_TI3410_EDGEPORT_1) }, - { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_TI3410_EDGEPORT_1I) }, - { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_WP_PROXIMITY) }, - { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_WP_MOTION) }, - { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_WP_MOISTURE) }, - { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_WP_TEMPERATURE) }, - { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_WP_HUMIDITY) }, - { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_WP_POWER) }, - { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_WP_LIGHT) }, - { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_WP_RADIATION) }, - { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_WP_DISTANCE) }, - { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_WP_ACCELERATION) }, - { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_WP_PROX_DIST) }, - { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_PLUS_PWR_HP4CD) }, - { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_PLUS_PWR_PCI) }, - { } -}; - -static const struct usb_device_id edgeport_2port_id_table[] = { - { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_EDGEPORT_2) }, - { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_EDGEPORT_2C) }, - { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_EDGEPORT_2I) }, - { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_EDGEPORT_421) }, - { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_EDGEPORT_21) }, - { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_EDGEPORT_42) }, - { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_EDGEPORT_4) }, - { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_EDGEPORT_4I) }, - { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_EDGEPORT_22I) }, - { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_EDGEPORT_221C) }, - { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_EDGEPORT_22C) }, - { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_EDGEPORT_21C) }, - /* The 4, 8 and 16 port devices show up as multiple 2 port devices */ - { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_EDGEPORT_4S) }, - { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_EDGEPORT_8) }, - { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_EDGEPORT_8S) }, - { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_EDGEPORT_416) }, - { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_EDGEPORT_416B) }, - { } -}; - -/* Devices that this driver supports */ -static const struct usb_device_id id_table_combined[] = { - { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_EDGEPORT_1) }, - { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_TI3410_EDGEPORT_1) }, - { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_TI3410_EDGEPORT_1I) }, - { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_WP_PROXIMITY) }, - { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_WP_MOTION) }, - { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_WP_MOISTURE) }, - { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_WP_TEMPERATURE) }, - { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_WP_HUMIDITY) }, - { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_WP_POWER) }, - { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_WP_LIGHT) }, - { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_WP_RADIATION) }, - { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_WP_DISTANCE) }, - { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_WP_ACCELERATION) }, - { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_WP_PROX_DIST) }, - { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_PLUS_PWR_HP4CD) }, - { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_PLUS_PWR_PCI) }, - { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_EDGEPORT_2) }, - { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_EDGEPORT_2C) }, - { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_EDGEPORT_2I) }, - { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_EDGEPORT_421) }, - { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_EDGEPORT_21) }, - { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_EDGEPORT_42) }, - { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_EDGEPORT_4) }, - { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_EDGEPORT_4I) }, - { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_EDGEPORT_22I) }, - { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_EDGEPORT_221C) }, - { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_EDGEPORT_22C) }, - { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_EDGEPORT_21C) }, - { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_EDGEPORT_4S) }, - { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_EDGEPORT_8) }, - { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_EDGEPORT_8S) }, - { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_EDGEPORT_416) }, - { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_EDGEPORT_416B) }, - { } -}; - -MODULE_DEVICE_TABLE(usb, id_table_combined); - -static struct usb_driver io_driver = { - .name = "io_ti", - .probe = usb_serial_probe, - .disconnect = usb_serial_disconnect, - .id_table = id_table_combined, -}; - - -static unsigned char OperationalMajorVersion; -static unsigned char OperationalMinorVersion; -static unsigned short OperationalBuildNumber; - -static bool debug; - -static int closing_wait = EDGE_CLOSING_WAIT; -static bool ignore_cpu_rev; -static int default_uart_mode; /* RS232 */ - -static void edge_tty_recv(struct device *dev, struct tty_struct *tty, - unsigned char *data, int length); - -static void stop_read(struct edgeport_port *edge_port); -static int restart_read(struct edgeport_port *edge_port); - -static void edge_set_termios(struct tty_struct *tty, - struct usb_serial_port *port, struct ktermios *old_termios); -static void edge_send(struct tty_struct *tty); - -/* sysfs attributes */ -static int edge_create_sysfs_attrs(struct usb_serial_port *port); -static int edge_remove_sysfs_attrs(struct usb_serial_port *port); - - -static int ti_vread_sync(struct usb_device *dev, __u8 request, - __u16 value, __u16 index, u8 *data, int size) -{ - int status; - - status = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), request, - (USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN), - value, index, data, size, 1000); - if (status < 0) - return status; - if (status != size) { - dbg("%s - wanted to write %d, but only wrote %d", - __func__, size, status); - return -ECOMM; - } - return 0; -} - -static int ti_vsend_sync(struct usb_device *dev, __u8 request, - __u16 value, __u16 index, u8 *data, int size) -{ - int status; - - status = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), request, - (USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_OUT), - value, index, data, size, 1000); - if (status < 0) - return status; - if (status != size) { - dbg("%s - wanted to write %d, but only wrote %d", - __func__, size, status); - return -ECOMM; - } - return 0; -} - -static int send_cmd(struct usb_device *dev, __u8 command, - __u8 moduleid, __u16 value, u8 *data, - int size) -{ - return ti_vsend_sync(dev, command, value, moduleid, data, size); -} - -/* clear tx/rx buffers and fifo in TI UMP */ -static int purge_port(struct usb_serial_port *port, __u16 mask) -{ - int port_number = port->number - port->serial->minor; - - dbg("%s - port %d, mask %x", __func__, port_number, mask); - - return send_cmd(port->serial->dev, - UMPC_PURGE_PORT, - (__u8)(UMPM_UART1_PORT + port_number), - mask, - NULL, - 0); -} - -/** - * read_download_mem - Read edgeport memory from TI chip - * @dev: usb device pointer - * @start_address: Device CPU address at which to read - * @length: Length of above data - * @address_type: Can read both XDATA and I2C - * @buffer: pointer to input data buffer - */ -static int read_download_mem(struct usb_device *dev, int start_address, - int length, __u8 address_type, __u8 *buffer) -{ - int status = 0; - __u8 read_length; - __be16 be_start_address; - - dbg("%s - @ %x for %d", __func__, start_address, length); - - /* Read in blocks of 64 bytes - * (TI firmware can't handle more than 64 byte reads) - */ - while (length) { - if (length > 64) - read_length = 64; - else - read_length = (__u8)length; - - if (read_length > 1) { - dbg("%s - @ %x for %d", __func__, - start_address, read_length); - } - be_start_address = cpu_to_be16(start_address); - status = ti_vread_sync(dev, UMPC_MEMORY_READ, - (__u16)address_type, - (__force __u16)be_start_address, - buffer, read_length); - - if (status) { - dbg("%s - ERROR %x", __func__, status); - return status; - } - - if (read_length > 1) - usb_serial_debug_data(debug, &dev->dev, __func__, - read_length, buffer); - - /* Update pointers/length */ - start_address += read_length; - buffer += read_length; - length -= read_length; - } - - return status; -} - -static int read_ram(struct usb_device *dev, int start_address, - int length, __u8 *buffer) -{ - return read_download_mem(dev, start_address, length, - DTK_ADDR_SPACE_XDATA, buffer); -} - -/* Read edgeport memory to a given block */ -static int read_boot_mem(struct edgeport_serial *serial, - int start_address, int length, __u8 *buffer) -{ - int status = 0; - int i; - - for (i = 0; i < length; i++) { - status = ti_vread_sync(serial->serial->dev, - UMPC_MEMORY_READ, serial->TI_I2C_Type, - (__u16)(start_address+i), &buffer[i], 0x01); - if (status) { - dbg("%s - ERROR %x", __func__, status); - return status; - } - } - - dbg("%s - start_address = %x, length = %d", - __func__, start_address, length); - usb_serial_debug_data(debug, &serial->serial->dev->dev, - __func__, length, buffer); - - serial->TiReadI2C = 1; - - return status; -} - -/* Write given block to TI EPROM memory */ -static int write_boot_mem(struct edgeport_serial *serial, - int start_address, int length, __u8 *buffer) -{ - int status = 0; - int i; - u8 *temp; - - /* Must do a read before write */ - if (!serial->TiReadI2C) { - temp = kmalloc(1, GFP_KERNEL); - if (!temp) { - dev_err(&serial->serial->dev->dev, - "%s - out of memory\n", __func__); - return -ENOMEM; - } - status = read_boot_mem(serial, 0, 1, temp); - kfree(temp); - if (status) - return status; - } - - for (i = 0; i < length; ++i) { - status = ti_vsend_sync(serial->serial->dev, - UMPC_MEMORY_WRITE, buffer[i], - (__u16)(i + start_address), NULL, 0); - if (status) - return status; - } - - dbg("%s - start_sddr = %x, length = %d", - __func__, start_address, length); - usb_serial_debug_data(debug, &serial->serial->dev->dev, - __func__, length, buffer); - - return status; -} - - -/* Write edgeport I2C memory to TI chip */ -static int write_i2c_mem(struct edgeport_serial *serial, - int start_address, int length, __u8 address_type, __u8 *buffer) -{ - int status = 0; - int write_length; - __be16 be_start_address; - - /* We can only send a maximum of 1 aligned byte page at a time */ - - /* calculate the number of bytes left in the first page */ - write_length = EPROM_PAGE_SIZE - - (start_address & (EPROM_PAGE_SIZE - 1)); - - if (write_length > length) - write_length = length; - - dbg("%s - BytesInFirstPage Addr = %x, length = %d", - __func__, start_address, write_length); - usb_serial_debug_data(debug, &serial->serial->dev->dev, - __func__, write_length, buffer); - - /* Write first page */ - be_start_address = cpu_to_be16(start_address); - status = ti_vsend_sync(serial->serial->dev, - UMPC_MEMORY_WRITE, (__u16)address_type, - (__force __u16)be_start_address, - buffer, write_length); - if (status) { - dbg("%s - ERROR %d", __func__, status); - return status; - } - - length -= write_length; - start_address += write_length; - buffer += write_length; - - /* We should be aligned now -- can write - max page size bytes at a time */ - while (length) { - if (length > EPROM_PAGE_SIZE) - write_length = EPROM_PAGE_SIZE; - else - write_length = length; - - dbg("%s - Page Write Addr = %x, length = %d", - __func__, start_address, write_length); - usb_serial_debug_data(debug, &serial->serial->dev->dev, - __func__, write_length, buffer); - - /* Write next page */ - be_start_address = cpu_to_be16(start_address); - status = ti_vsend_sync(serial->serial->dev, UMPC_MEMORY_WRITE, - (__u16)address_type, - (__force __u16)be_start_address, - buffer, write_length); - if (status) { - dev_err(&serial->serial->dev->dev, "%s - ERROR %d\n", - __func__, status); - return status; - } - - length -= write_length; - start_address += write_length; - buffer += write_length; - } - return status; -} - -/* Examine the UMP DMA registers and LSR - * - * Check the MSBit of the X and Y DMA byte count registers. - * A zero in this bit indicates that the TX DMA buffers are empty - * then check the TX Empty bit in the UART. - */ -static int tx_active(struct edgeport_port *port) -{ - int status; - struct out_endpoint_desc_block *oedb; - __u8 *lsr; - int bytes_left = 0; - - oedb = kmalloc(sizeof(*oedb), GFP_KERNEL); - if (!oedb) { - dev_err(&port->port->dev, "%s - out of memory\n", __func__); - return -ENOMEM; - } - - lsr = kmalloc(1, GFP_KERNEL); /* Sigh, that's right, just one byte, - as not all platforms can do DMA - from stack */ - if (!lsr) { - kfree(oedb); - return -ENOMEM; - } - /* Read the DMA Count Registers */ - status = read_ram(port->port->serial->dev, port->dma_address, - sizeof(*oedb), (void *)oedb); - if (status) - goto exit_is_tx_active; - - dbg("%s - XByteCount 0x%X", __func__, oedb->XByteCount); - - /* and the LSR */ - status = read_ram(port->port->serial->dev, - port->uart_base + UMPMEM_OFFS_UART_LSR, 1, lsr); - - if (status) - goto exit_is_tx_active; - dbg("%s - LSR = 0x%X", __func__, *lsr); - - /* If either buffer has data or we are transmitting then return TRUE */ - if ((oedb->XByteCount & 0x80) != 0) - bytes_left += 64; - - if ((*lsr & UMP_UART_LSR_TX_MASK) == 0) - bytes_left += 1; - - /* We return Not Active if we get any kind of error */ -exit_is_tx_active: - dbg("%s - return %d", __func__, bytes_left); - - kfree(lsr); - kfree(oedb); - return bytes_left; -} - -static void chase_port(struct edgeport_port *port, unsigned long timeout, - int flush) -{ - int baud_rate; - struct tty_struct *tty = tty_port_tty_get(&port->port->port); - wait_queue_t wait; - unsigned long flags; - - if (!timeout) - timeout = (HZ * EDGE_CLOSING_WAIT)/100; - - /* wait for data to drain from the buffer */ - spin_lock_irqsave(&port->ep_lock, flags); - init_waitqueue_entry(&wait, current); - add_wait_queue(&tty->write_wait, &wait); - for (;;) { - set_current_state(TASK_INTERRUPTIBLE); - if (kfifo_len(&port->write_fifo) == 0 - || timeout == 0 || signal_pending(current) - || !usb_get_intfdata(port->port->serial->interface)) - /* disconnect */ - break; - spin_unlock_irqrestore(&port->ep_lock, flags); - timeout = schedule_timeout(timeout); - spin_lock_irqsave(&port->ep_lock, flags); - } - set_current_state(TASK_RUNNING); - remove_wait_queue(&tty->write_wait, &wait); - if (flush) - kfifo_reset_out(&port->write_fifo); - spin_unlock_irqrestore(&port->ep_lock, flags); - tty_kref_put(tty); - - /* wait for data to drain from the device */ - timeout += jiffies; - while ((long)(jiffies - timeout) < 0 && !signal_pending(current) - && usb_get_intfdata(port->port->serial->interface)) { - /* not disconnected */ - if (!tx_active(port)) - break; - msleep(10); - } - - /* disconnected */ - if (!usb_get_intfdata(port->port->serial->interface)) - return; - - /* wait one more character time, based on baud rate */ - /* (tx_active doesn't seem to wait for the last byte) */ - baud_rate = port->baud_rate; - if (baud_rate == 0) - baud_rate = 50; - msleep(max(1, DIV_ROUND_UP(10000, baud_rate))); -} - -static int choose_config(struct usb_device *dev) -{ - /* - * There may be multiple configurations on this device, in which case - * we would need to read and parse all of them to find out which one - * we want. However, we just support one config at this point, - * configuration # 1, which is Config Descriptor 0. - */ - - dbg("%s - Number of Interfaces = %d", - __func__, dev->config->desc.bNumInterfaces); - dbg("%s - MAX Power = %d", - __func__, dev->config->desc.bMaxPower * 2); - - if (dev->config->desc.bNumInterfaces != 1) { - dev_err(&dev->dev, "%s - bNumInterfaces is not 1, ERROR!\n", - __func__); - return -ENODEV; - } - - return 0; -} - -static int read_rom(struct edgeport_serial *serial, - int start_address, int length, __u8 *buffer) -{ - int status; - - if (serial->product_info.TiMode == TI_MODE_DOWNLOAD) { - status = read_download_mem(serial->serial->dev, - start_address, - length, - serial->TI_I2C_Type, - buffer); - } else { - status = read_boot_mem(serial, start_address, length, - buffer); - } - return status; -} - -static int write_rom(struct edgeport_serial *serial, int start_address, - int length, __u8 *buffer) -{ - if (serial->product_info.TiMode == TI_MODE_BOOT) - return write_boot_mem(serial, start_address, length, - buffer); - - if (serial->product_info.TiMode == TI_MODE_DOWNLOAD) - return write_i2c_mem(serial, start_address, length, - serial->TI_I2C_Type, buffer); - return -EINVAL; -} - - - -/* Read a descriptor header from I2C based on type */ -static int get_descriptor_addr(struct edgeport_serial *serial, - int desc_type, struct ti_i2c_desc *rom_desc) -{ - int start_address; - int status; - - /* Search for requested descriptor in I2C */ - start_address = 2; - do { - status = read_rom(serial, - start_address, - sizeof(struct ti_i2c_desc), - (__u8 *)rom_desc); - if (status) - return 0; - - if (rom_desc->Type == desc_type) - return start_address; - - start_address = start_address + sizeof(struct ti_i2c_desc) - + rom_desc->Size; - - } while ((start_address < TI_MAX_I2C_SIZE) && rom_desc->Type); - - return 0; -} - -/* Validate descriptor checksum */ -static int valid_csum(struct ti_i2c_desc *rom_desc, __u8 *buffer) -{ - __u16 i; - __u8 cs = 0; - - for (i = 0; i < rom_desc->Size; i++) - cs = (__u8)(cs + buffer[i]); - - if (cs != rom_desc->CheckSum) { - dbg("%s - Mismatch %x - %x", __func__, rom_desc->CheckSum, cs); - return -EINVAL; - } - return 0; -} - -/* Make sure that the I2C image is good */ -static int check_i2c_image(struct edgeport_serial *serial) -{ - struct device *dev = &serial->serial->dev->dev; - int status = 0; - struct ti_i2c_desc *rom_desc; - int start_address = 2; - __u8 *buffer; - __u16 ttype; - - rom_desc = kmalloc(sizeof(*rom_desc), GFP_KERNEL); - if (!rom_desc) { - dev_err(dev, "%s - out of memory\n", __func__); - return -ENOMEM; - } - buffer = kmalloc(TI_MAX_I2C_SIZE, GFP_KERNEL); - if (!buffer) { - dev_err(dev, "%s - out of memory when allocating buffer\n", - __func__); - kfree(rom_desc); - return -ENOMEM; - } - - /* Read the first byte (Signature0) must be 0x52 or 0x10 */ - status = read_rom(serial, 0, 1, buffer); - if (status) - goto out; - - if (*buffer != UMP5152 && *buffer != UMP3410) { - dev_err(dev, "%s - invalid buffer signature\n", __func__); - status = -ENODEV; - goto out; - } - - do { - /* Validate the I2C */ - status = read_rom(serial, - start_address, - sizeof(struct ti_i2c_desc), - (__u8 *)rom_desc); - if (status) - break; - - if ((start_address + sizeof(struct ti_i2c_desc) + - rom_desc->Size) > TI_MAX_I2C_SIZE) { - status = -ENODEV; - dbg("%s - structure too big, erroring out.", __func__); - break; - } - - dbg("%s Type = 0x%x", __func__, rom_desc->Type); - - /* Skip type 2 record */ - ttype = rom_desc->Type & 0x0f; - if (ttype != I2C_DESC_TYPE_FIRMWARE_BASIC - && ttype != I2C_DESC_TYPE_FIRMWARE_AUTO) { - /* Read the descriptor data */ - status = read_rom(serial, start_address + - sizeof(struct ti_i2c_desc), - rom_desc->Size, buffer); - if (status) - break; - - status = valid_csum(rom_desc, buffer); - if (status) - break; - } - start_address = start_address + sizeof(struct ti_i2c_desc) + - rom_desc->Size; - - } while ((rom_desc->Type != I2C_DESC_TYPE_ION) && - (start_address < TI_MAX_I2C_SIZE)); - - if ((rom_desc->Type != I2C_DESC_TYPE_ION) || - (start_address > TI_MAX_I2C_SIZE)) - status = -ENODEV; - -out: - kfree(buffer); - kfree(rom_desc); - return status; -} - -static int get_manuf_info(struct edgeport_serial *serial, __u8 *buffer) -{ - int status; - int start_address; - struct ti_i2c_desc *rom_desc; - struct edge_ti_manuf_descriptor *desc; - - rom_desc = kmalloc(sizeof(*rom_desc), GFP_KERNEL); - if (!rom_desc) { - dev_err(&serial->serial->dev->dev, "%s - out of memory\n", - __func__); - return -ENOMEM; - } - start_address = get_descriptor_addr(serial, I2C_DESC_TYPE_ION, - rom_desc); - - if (!start_address) { - dbg("%s - Edge Descriptor not found in I2C", __func__); - status = -ENODEV; - goto exit; - } - - /* Read the descriptor data */ - status = read_rom(serial, start_address+sizeof(struct ti_i2c_desc), - rom_desc->Size, buffer); - if (status) - goto exit; - - status = valid_csum(rom_desc, buffer); - - desc = (struct edge_ti_manuf_descriptor *)buffer; - dbg("%s - IonConfig 0x%x", __func__, desc->IonConfig); - dbg("%s - Version %d", __func__, desc->Version); - dbg("%s - Cpu/Board 0x%x", __func__, desc->CpuRev_BoardRev); - dbg("%s - NumPorts %d", __func__, desc->NumPorts); - dbg("%s - NumVirtualPorts %d", __func__, desc->NumVirtualPorts); - dbg("%s - TotalPorts %d", __func__, desc->TotalPorts); - -exit: - kfree(rom_desc); - return status; -} - -/* Build firmware header used for firmware update */ -static int build_i2c_fw_hdr(__u8 *header, struct device *dev) -{ - __u8 *buffer; - int buffer_size; - int i; - int err; - __u8 cs = 0; - struct ti_i2c_desc *i2c_header; - struct ti_i2c_image_header *img_header; - struct ti_i2c_firmware_rec *firmware_rec; - const struct firmware *fw; - const char *fw_name = "edgeport/down3.bin"; - - /* In order to update the I2C firmware we must change the type 2 record - * to type 0xF2. This will force the UMP to come up in Boot Mode. - * Then while in boot mode, the driver will download the latest - * firmware (padded to 15.5k) into the UMP ram. And finally when the - * device comes back up in download mode the driver will cause the new - * firmware to be copied from the UMP Ram to I2C and the firmware will - * update the record type from 0xf2 to 0x02. - */ - - /* Allocate a 15.5k buffer + 2 bytes for version number - * (Firmware Record) */ - buffer_size = (((1024 * 16) - 512 ) + - sizeof(struct ti_i2c_firmware_rec)); - - buffer = kmalloc(buffer_size, GFP_KERNEL); - if (!buffer) { - dev_err(dev, "%s - out of memory\n", __func__); - return -ENOMEM; - } - - // Set entire image of 0xffs - memset(buffer, 0xff, buffer_size); - - err = request_firmware(&fw, fw_name, dev); - if (err) { - printk(KERN_ERR "Failed to load image \"%s\" err %d\n", - fw_name, err); - kfree(buffer); - return err; - } - - /* Save Download Version Number */ - OperationalMajorVersion = fw->data[0]; - OperationalMinorVersion = fw->data[1]; - OperationalBuildNumber = fw->data[2] | (fw->data[3] << 8); - - /* Copy version number into firmware record */ - firmware_rec = (struct ti_i2c_firmware_rec *)buffer; - - firmware_rec->Ver_Major = OperationalMajorVersion; - firmware_rec->Ver_Minor = OperationalMinorVersion; - - /* Pointer to fw_down memory image */ - img_header = (struct ti_i2c_image_header *)&fw->data[4]; - - memcpy(buffer + sizeof(struct ti_i2c_firmware_rec), - &fw->data[4 + sizeof(struct ti_i2c_image_header)], - le16_to_cpu(img_header->Length)); - - release_firmware(fw); - - for (i=0; i < buffer_size; i++) { - cs = (__u8)(cs + buffer[i]); - } - - kfree(buffer); - - /* Build new header */ - i2c_header = (struct ti_i2c_desc *)header; - firmware_rec = (struct ti_i2c_firmware_rec*)i2c_header->Data; - - i2c_header->Type = I2C_DESC_TYPE_FIRMWARE_BLANK; - i2c_header->Size = (__u16)buffer_size; - i2c_header->CheckSum = cs; - firmware_rec->Ver_Major = OperationalMajorVersion; - firmware_rec->Ver_Minor = OperationalMinorVersion; - - return 0; -} - -/* Try to figure out what type of I2c we have */ -static int i2c_type_bootmode(struct edgeport_serial *serial) -{ - int status; - u8 *data; - - data = kmalloc(1, GFP_KERNEL); - if (!data) { - dev_err(&serial->serial->dev->dev, - "%s - out of memory\n", __func__); - return -ENOMEM; - } - - /* Try to read type 2 */ - status = ti_vread_sync(serial->serial->dev, UMPC_MEMORY_READ, - DTK_ADDR_SPACE_I2C_TYPE_II, 0, data, 0x01); - if (status) - dbg("%s - read 2 status error = %d", __func__, status); - else - dbg("%s - read 2 data = 0x%x", __func__, *data); - if ((!status) && (*data == UMP5152 || *data == UMP3410)) { - dbg("%s - ROM_TYPE_II", __func__); - serial->TI_I2C_Type = DTK_ADDR_SPACE_I2C_TYPE_II; - goto out; - } - - /* Try to read type 3 */ - status = ti_vread_sync(serial->serial->dev, UMPC_MEMORY_READ, - DTK_ADDR_SPACE_I2C_TYPE_III, 0, data, 0x01); - if (status) - dbg("%s - read 3 status error = %d", __func__, status); - else - dbg("%s - read 2 data = 0x%x", __func__, *data); - if ((!status) && (*data == UMP5152 || *data == UMP3410)) { - dbg("%s - ROM_TYPE_III", __func__); - serial->TI_I2C_Type = DTK_ADDR_SPACE_I2C_TYPE_III; - goto out; - } - - dbg("%s - Unknown", __func__); - serial->TI_I2C_Type = DTK_ADDR_SPACE_I2C_TYPE_II; - status = -ENODEV; -out: - kfree(data); - return status; -} - -static int bulk_xfer(struct usb_serial *serial, void *buffer, - int length, int *num_sent) -{ - int status; - - status = usb_bulk_msg(serial->dev, - usb_sndbulkpipe(serial->dev, - serial->port[0]->bulk_out_endpointAddress), - buffer, length, num_sent, 1000); - return status; -} - -/* Download given firmware image to the device (IN BOOT MODE) */ -static int download_code(struct edgeport_serial *serial, __u8 *image, - int image_length) -{ - int status = 0; - int pos; - int transfer; - int done; - - /* Transfer firmware image */ - for (pos = 0; pos < image_length; ) { - /* Read the next buffer from file */ - transfer = image_length - pos; - if (transfer > EDGE_FW_BULK_MAX_PACKET_SIZE) - transfer = EDGE_FW_BULK_MAX_PACKET_SIZE; - - /* Transfer data */ - status = bulk_xfer(serial->serial, &image[pos], - transfer, &done); - if (status) - break; - /* Advance buffer pointer */ - pos += done; - } - - return status; -} - -/* FIXME!!! */ -static int config_boot_dev(struct usb_device *dev) -{ - return 0; -} - -static int ti_cpu_rev(struct edge_ti_manuf_descriptor *desc) -{ - return TI_GET_CPU_REVISION(desc->CpuRev_BoardRev); -} - -/** - * DownloadTIFirmware - Download run-time operating firmware to the TI5052 - * - * This routine downloads the main operating code into the TI5052, using the - * boot code already burned into E2PROM or ROM. - */ -static int download_fw(struct edgeport_serial *serial) -{ - struct device *dev = &serial->serial->dev->dev; - int status = 0; - int start_address; - struct edge_ti_manuf_descriptor *ti_manuf_desc; - struct usb_interface_descriptor *interface; - int download_cur_ver; - int download_new_ver; - - /* This routine is entered by both the BOOT mode and the Download mode - * We can determine which code is running by the reading the config - * descriptor and if we have only one bulk pipe it is in boot mode - */ - serial->product_info.hardware_type = HARDWARE_TYPE_TIUMP; - - /* Default to type 2 i2c */ - serial->TI_I2C_Type = DTK_ADDR_SPACE_I2C_TYPE_II; - - status = choose_config(serial->serial->dev); - if (status) - return status; - - interface = &serial->serial->interface->cur_altsetting->desc; - if (!interface) { - dev_err(dev, "%s - no interface set, error!\n", __func__); - return -ENODEV; - } - - /* - * Setup initial mode -- the default mode 0 is TI_MODE_CONFIGURING - * if we have more than one endpoint we are definitely in download - * mode - */ - if (interface->bNumEndpoints > 1) - serial->product_info.TiMode = TI_MODE_DOWNLOAD; - else - /* Otherwise we will remain in configuring mode */ - serial->product_info.TiMode = TI_MODE_CONFIGURING; - - /********************************************************************/ - /* Download Mode */ - /********************************************************************/ - if (serial->product_info.TiMode == TI_MODE_DOWNLOAD) { - struct ti_i2c_desc *rom_desc; - - dbg("%s - RUNNING IN DOWNLOAD MODE", __func__); - - status = check_i2c_image(serial); - if (status) { - dbg("%s - DOWNLOAD MODE -- BAD I2C", __func__); - return status; - } - - /* Validate Hardware version number - * Read Manufacturing Descriptor from TI Based Edgeport - */ - ti_manuf_desc = kmalloc(sizeof(*ti_manuf_desc), GFP_KERNEL); - if (!ti_manuf_desc) { - dev_err(dev, "%s - out of memory.\n", __func__); - return -ENOMEM; - } - status = get_manuf_info(serial, (__u8 *)ti_manuf_desc); - if (status) { - kfree(ti_manuf_desc); - return status; - } - - /* Check version number of ION descriptor */ - if (!ignore_cpu_rev && ti_cpu_rev(ti_manuf_desc) < 2) { - dbg("%s - Wrong CPU Rev %d (Must be 2)", - __func__, ti_cpu_rev(ti_manuf_desc)); - kfree(ti_manuf_desc); - return -EINVAL; - } - - rom_desc = kmalloc(sizeof(*rom_desc), GFP_KERNEL); - if (!rom_desc) { - dev_err(dev, "%s - out of memory.\n", __func__); - kfree(ti_manuf_desc); - return -ENOMEM; - } - - /* Search for type 2 record (firmware record) */ - start_address = get_descriptor_addr(serial, - I2C_DESC_TYPE_FIRMWARE_BASIC, rom_desc); - if (start_address != 0) { - struct ti_i2c_firmware_rec *firmware_version; - u8 *record; - - dbg("%s - Found Type FIRMWARE (Type 2) record", - __func__); - - firmware_version = kmalloc(sizeof(*firmware_version), - GFP_KERNEL); - if (!firmware_version) { - dev_err(dev, "%s - out of memory.\n", __func__); - kfree(rom_desc); - kfree(ti_manuf_desc); - return -ENOMEM; - } - - /* Validate version number - * Read the descriptor data - */ - status = read_rom(serial, start_address + - sizeof(struct ti_i2c_desc), - sizeof(struct ti_i2c_firmware_rec), - (__u8 *)firmware_version); - if (status) { - kfree(firmware_version); - kfree(rom_desc); - kfree(ti_manuf_desc); - return status; - } - - /* Check version number of download with current - version in I2c */ - download_cur_ver = (firmware_version->Ver_Major << 8) + - (firmware_version->Ver_Minor); - download_new_ver = (OperationalMajorVersion << 8) + - (OperationalMinorVersion); - - dbg("%s - >> FW Versions Device %d.%d Driver %d.%d", - __func__, - firmware_version->Ver_Major, - firmware_version->Ver_Minor, - OperationalMajorVersion, - OperationalMinorVersion); - - /* Check if we have an old version in the I2C and - update if necessary */ - if (download_cur_ver < download_new_ver) { - dbg("%s - Update I2C dld from %d.%d to %d.%d", - __func__, - firmware_version->Ver_Major, - firmware_version->Ver_Minor, - OperationalMajorVersion, - OperationalMinorVersion); - - record = kmalloc(1, GFP_KERNEL); - if (!record) { - dev_err(dev, "%s - out of memory.\n", - __func__); - kfree(firmware_version); - kfree(rom_desc); - kfree(ti_manuf_desc); - return -ENOMEM; - } - /* In order to update the I2C firmware we must - * change the type 2 record to type 0xF2. This - * will force the UMP to come up in Boot Mode. - * Then while in boot mode, the driver will - * download the latest firmware (padded to - * 15.5k) into the UMP ram. Finally when the - * device comes back up in download mode the - * driver will cause the new firmware to be - * copied from the UMP Ram to I2C and the - * firmware will update the record type from - * 0xf2 to 0x02. - */ - *record = I2C_DESC_TYPE_FIRMWARE_BLANK; - - /* Change the I2C Firmware record type to - 0xf2 to trigger an update */ - status = write_rom(serial, start_address, - sizeof(*record), record); - if (status) { - kfree(record); - kfree(firmware_version); - kfree(rom_desc); - kfree(ti_manuf_desc); - return status; - } - - /* verify the write -- must do this in order - * for write to complete before we do the - * hardware reset - */ - status = read_rom(serial, - start_address, - sizeof(*record), - record); - if (status) { - kfree(record); - kfree(firmware_version); - kfree(rom_desc); - kfree(ti_manuf_desc); - return status; - } - - if (*record != I2C_DESC_TYPE_FIRMWARE_BLANK) { - dev_err(dev, - "%s - error resetting device\n", - __func__); - kfree(record); - kfree(firmware_version); - kfree(rom_desc); - kfree(ti_manuf_desc); - return -ENODEV; - } - - dbg("%s - HARDWARE RESET", __func__); - - /* Reset UMP -- Back to BOOT MODE */ - status = ti_vsend_sync(serial->serial->dev, - UMPC_HARDWARE_RESET, - 0, 0, NULL, 0); - - dbg("%s - HARDWARE RESET return %d", - __func__, status); - - /* return an error on purpose. */ - kfree(record); - kfree(firmware_version); - kfree(rom_desc); - kfree(ti_manuf_desc); - return -ENODEV; - } - kfree(firmware_version); - } - /* Search for type 0xF2 record (firmware blank record) */ - else if ((start_address = get_descriptor_addr(serial, I2C_DESC_TYPE_FIRMWARE_BLANK, rom_desc)) != 0) { -#define HEADER_SIZE (sizeof(struct ti_i2c_desc) + \ - sizeof(struct ti_i2c_firmware_rec)) - __u8 *header; - __u8 *vheader; - - header = kmalloc(HEADER_SIZE, GFP_KERNEL); - if (!header) { - dev_err(dev, "%s - out of memory.\n", __func__); - kfree(rom_desc); - kfree(ti_manuf_desc); - return -ENOMEM; - } - - vheader = kmalloc(HEADER_SIZE, GFP_KERNEL); - if (!vheader) { - dev_err(dev, "%s - out of memory.\n", __func__); - kfree(header); - kfree(rom_desc); - kfree(ti_manuf_desc); - return -ENOMEM; - } - - dbg("%s - Found Type BLANK FIRMWARE (Type F2) record", - __func__); - - /* - * In order to update the I2C firmware we must change - * the type 2 record to type 0xF2. This will force the - * UMP to come up in Boot Mode. Then while in boot - * mode, the driver will download the latest firmware - * (padded to 15.5k) into the UMP ram. Finally when the - * device comes back up in download mode the driver - * will cause the new firmware to be copied from the - * UMP Ram to I2C and the firmware will update the - * record type from 0xf2 to 0x02. - */ - status = build_i2c_fw_hdr(header, dev); - if (status) { - kfree(vheader); - kfree(header); - kfree(rom_desc); - kfree(ti_manuf_desc); - return -EINVAL; - } - - /* Update I2C with type 0xf2 record with correct - size and checksum */ - status = write_rom(serial, - start_address, - HEADER_SIZE, - header); - if (status) { - kfree(vheader); - kfree(header); - kfree(rom_desc); - kfree(ti_manuf_desc); - return -EINVAL; - } - - /* verify the write -- must do this in order for - write to complete before we do the hardware reset */ - status = read_rom(serial, start_address, - HEADER_SIZE, vheader); - - if (status) { - dbg("%s - can't read header back", __func__); - kfree(vheader); - kfree(header); - kfree(rom_desc); - kfree(ti_manuf_desc); - return status; - } - if (memcmp(vheader, header, HEADER_SIZE)) { - dbg("%s - write download record failed", - __func__); - kfree(vheader); - kfree(header); - kfree(rom_desc); - kfree(ti_manuf_desc); - return -EINVAL; - } - - kfree(vheader); - kfree(header); - - dbg("%s - Start firmware update", __func__); - - /* Tell firmware to copy download image into I2C */ - status = ti_vsend_sync(serial->serial->dev, - UMPC_COPY_DNLD_TO_I2C, 0, 0, NULL, 0); - - dbg("%s - Update complete 0x%x", __func__, status); - if (status) { - dev_err(dev, - "%s - UMPC_COPY_DNLD_TO_I2C failed\n", - __func__); - kfree(rom_desc); - kfree(ti_manuf_desc); - return status; - } - } - - // The device is running the download code - kfree(rom_desc); - kfree(ti_manuf_desc); - return 0; - } - - /********************************************************************/ - /* Boot Mode */ - /********************************************************************/ - dbg("%s - RUNNING IN BOOT MODE", __func__); - - /* Configure the TI device so we can use the BULK pipes for download */ - status = config_boot_dev(serial->serial->dev); - if (status) - return status; - - if (le16_to_cpu(serial->serial->dev->descriptor.idVendor) - != USB_VENDOR_ID_ION) { - dbg("%s - VID = 0x%x", __func__, - le16_to_cpu(serial->serial->dev->descriptor.idVendor)); - serial->TI_I2C_Type = DTK_ADDR_SPACE_I2C_TYPE_II; - goto stayinbootmode; - } - - /* We have an ION device (I2c Must be programmed) - Determine I2C image type */ - if (i2c_type_bootmode(serial)) - goto stayinbootmode; - - /* Check for ION Vendor ID and that the I2C is valid */ - if (!check_i2c_image(serial)) { - struct ti_i2c_image_header *header; - int i; - __u8 cs = 0; - __u8 *buffer; - int buffer_size; - int err; - const struct firmware *fw; - const char *fw_name = "edgeport/down3.bin"; - - /* Validate Hardware version number - * Read Manufacturing Descriptor from TI Based Edgeport - */ - ti_manuf_desc = kmalloc(sizeof(*ti_manuf_desc), GFP_KERNEL); - if (!ti_manuf_desc) { - dev_err(dev, "%s - out of memory.\n", __func__); - return -ENOMEM; - } - status = get_manuf_info(serial, (__u8 *)ti_manuf_desc); - if (status) { - kfree(ti_manuf_desc); - goto stayinbootmode; - } - - /* Check for version 2 */ - if (!ignore_cpu_rev && ti_cpu_rev(ti_manuf_desc) < 2) { - dbg("%s - Wrong CPU Rev %d (Must be 2)", - __func__, ti_cpu_rev(ti_manuf_desc)); - kfree(ti_manuf_desc); - goto stayinbootmode; - } - - kfree(ti_manuf_desc); - - /* - * In order to update the I2C firmware we must change the type - * 2 record to type 0xF2. This will force the UMP to come up - * in Boot Mode. Then while in boot mode, the driver will - * download the latest firmware (padded to 15.5k) into the - * UMP ram. Finally when the device comes back up in download - * mode the driver will cause the new firmware to be copied - * from the UMP Ram to I2C and the firmware will update the - * record type from 0xf2 to 0x02. - * - * Do we really have to copy the whole firmware image, - * or could we do this in place! - */ - - /* Allocate a 15.5k buffer + 3 byte header */ - buffer_size = (((1024 * 16) - 512) + - sizeof(struct ti_i2c_image_header)); - buffer = kmalloc(buffer_size, GFP_KERNEL); - if (!buffer) { - dev_err(dev, "%s - out of memory\n", __func__); - return -ENOMEM; - } - - /* Initialize the buffer to 0xff (pad the buffer) */ - memset(buffer, 0xff, buffer_size); - - err = request_firmware(&fw, fw_name, dev); - if (err) { - printk(KERN_ERR "Failed to load image \"%s\" err %d\n", - fw_name, err); - kfree(buffer); - return err; - } - memcpy(buffer, &fw->data[4], fw->size - 4); - release_firmware(fw); - - for (i = sizeof(struct ti_i2c_image_header); - i < buffer_size; i++) { - cs = (__u8)(cs + buffer[i]); - } - - header = (struct ti_i2c_image_header *)buffer; - - /* update length and checksum after padding */ - header->Length = cpu_to_le16((__u16)(buffer_size - - sizeof(struct ti_i2c_image_header))); - header->CheckSum = cs; - - /* Download the operational code */ - dbg("%s - Downloading operational code image (TI UMP)", - __func__); - status = download_code(serial, buffer, buffer_size); - - kfree(buffer); - - if (status) { - dbg("%s - Error downloading operational code image", - __func__); - return status; - } - - /* Device will reboot */ - serial->product_info.TiMode = TI_MODE_TRANSITIONING; - - dbg("%s - Download successful -- Device rebooting...", - __func__); - - /* return an error on purpose */ - return -ENODEV; - } - -stayinbootmode: - /* Eprom is invalid or blank stay in boot mode */ - dbg("%s - STAYING IN BOOT MODE", __func__); - serial->product_info.TiMode = TI_MODE_BOOT; - - return 0; -} - - -static int ti_do_config(struct edgeport_port *port, int feature, int on) -{ - int port_number = port->port->number - port->port->serial->minor; - on = !!on; /* 1 or 0 not bitmask */ - return send_cmd(port->port->serial->dev, - feature, (__u8)(UMPM_UART1_PORT + port_number), - on, NULL, 0); -} - - -static int restore_mcr(struct edgeport_port *port, __u8 mcr) -{ - int status = 0; - - dbg("%s - %x", __func__, mcr); - - status = ti_do_config(port, UMPC_SET_CLR_DTR, mcr & MCR_DTR); - if (status) - return status; - status = ti_do_config(port, UMPC_SET_CLR_RTS, mcr & MCR_RTS); - if (status) - return status; - return ti_do_config(port, UMPC_SET_CLR_LOOPBACK, mcr & MCR_LOOPBACK); -} - -/* Convert TI LSR to standard UART flags */ -static __u8 map_line_status(__u8 ti_lsr) -{ - __u8 lsr = 0; - -#define MAP_FLAG(flagUmp, flagUart) \ - if (ti_lsr & flagUmp) \ - lsr |= flagUart; - - MAP_FLAG(UMP_UART_LSR_OV_MASK, LSR_OVER_ERR) /* overrun */ - MAP_FLAG(UMP_UART_LSR_PE_MASK, LSR_PAR_ERR) /* parity error */ - MAP_FLAG(UMP_UART_LSR_FE_MASK, LSR_FRM_ERR) /* framing error */ - MAP_FLAG(UMP_UART_LSR_BR_MASK, LSR_BREAK) /* break detected */ - MAP_FLAG(UMP_UART_LSR_RX_MASK, LSR_RX_AVAIL) /* rx data available */ - MAP_FLAG(UMP_UART_LSR_TX_MASK, LSR_TX_EMPTY) /* tx hold reg empty */ - -#undef MAP_FLAG - - return lsr; -} - -static void handle_new_msr(struct edgeport_port *edge_port, __u8 msr) -{ - struct async_icount *icount; - struct tty_struct *tty; - - dbg("%s - %02x", __func__, msr); - - if (msr & (EDGEPORT_MSR_DELTA_CTS | EDGEPORT_MSR_DELTA_DSR | - EDGEPORT_MSR_DELTA_RI | EDGEPORT_MSR_DELTA_CD)) { - icount = &edge_port->icount; - - /* update input line counters */ - if (msr & EDGEPORT_MSR_DELTA_CTS) - icount->cts++; - if (msr & EDGEPORT_MSR_DELTA_DSR) - icount->dsr++; - if (msr & EDGEPORT_MSR_DELTA_CD) - icount->dcd++; - if (msr & EDGEPORT_MSR_DELTA_RI) - icount->rng++; - wake_up_interruptible(&edge_port->delta_msr_wait); - } - - /* Save the new modem status */ - edge_port->shadow_msr = msr & 0xf0; - - tty = tty_port_tty_get(&edge_port->port->port); - /* handle CTS flow control */ - if (tty && C_CRTSCTS(tty)) { - if (msr & EDGEPORT_MSR_CTS) { - tty->hw_stopped = 0; - tty_wakeup(tty); - } else { - tty->hw_stopped = 1; - } - } - tty_kref_put(tty); -} - -static void handle_new_lsr(struct edgeport_port *edge_port, int lsr_data, - __u8 lsr, __u8 data) -{ - struct async_icount *icount; - __u8 new_lsr = (__u8)(lsr & (__u8)(LSR_OVER_ERR | LSR_PAR_ERR | - LSR_FRM_ERR | LSR_BREAK)); - struct tty_struct *tty; - - dbg("%s - %02x", __func__, new_lsr); - - edge_port->shadow_lsr = lsr; - - if (new_lsr & LSR_BREAK) - /* - * Parity and Framing errors only count if they - * occur exclusive of a break being received. - */ - new_lsr &= (__u8)(LSR_OVER_ERR | LSR_BREAK); - - /* Place LSR data byte into Rx buffer */ - if (lsr_data) { - tty = tty_port_tty_get(&edge_port->port->port); - if (tty) { - edge_tty_recv(&edge_port->port->dev, tty, &data, 1); - tty_kref_put(tty); - } - } - - /* update input line counters */ - icount = &edge_port->icount; - if (new_lsr & LSR_BREAK) - icount->brk++; - if (new_lsr & LSR_OVER_ERR) - icount->overrun++; - if (new_lsr & LSR_PAR_ERR) - icount->parity++; - if (new_lsr & LSR_FRM_ERR) - icount->frame++; -} - - -static void edge_interrupt_callback(struct urb *urb) -{ - struct edgeport_serial *edge_serial = urb->context; - struct usb_serial_port *port; - struct edgeport_port *edge_port; - unsigned char *data = urb->transfer_buffer; - int length = urb->actual_length; - int port_number; - int function; - int retval; - __u8 lsr; - __u8 msr; - int status = urb->status; - - dbg("%s", __func__); - - switch (status) { - case 0: - /* success */ - break; - case -ECONNRESET: - case -ENOENT: - case -ESHUTDOWN: - /* this urb is terminated, clean up */ - dbg("%s - urb shutting down with status: %d", - __func__, status); - return; - default: - dev_err(&urb->dev->dev, "%s - nonzero urb status received: " - "%d\n", __func__, status); - goto exit; - } - - if (!length) { - dbg("%s - no data in urb", __func__); - goto exit; - } - - usb_serial_debug_data(debug, &edge_serial->serial->dev->dev, - __func__, length, data); - - if (length != 2) { - dbg("%s - expecting packet of size 2, got %d", - __func__, length); - goto exit; - } - - port_number = TIUMP_GET_PORT_FROM_CODE(data[0]); - function = TIUMP_GET_FUNC_FROM_CODE(data[0]); - dbg("%s - port_number %d, function %d, info 0x%x", - __func__, port_number, function, data[1]); - port = edge_serial->serial->port[port_number]; - edge_port = usb_get_serial_port_data(port); - if (!edge_port) { - dbg("%s - edge_port not found", __func__); - return; - } - switch (function) { - case TIUMP_INTERRUPT_CODE_LSR: - lsr = map_line_status(data[1]); - if (lsr & UMP_UART_LSR_DATA_MASK) { - /* Save the LSR event for bulk read - completion routine */ - dbg("%s - LSR Event Port %u LSR Status = %02x", - __func__, port_number, lsr); - edge_port->lsr_event = 1; - edge_port->lsr_mask = lsr; - } else { - dbg("%s - ===== Port %d LSR Status = %02x ======", - __func__, port_number, lsr); - handle_new_lsr(edge_port, 0, lsr, 0); - } - break; - - case TIUMP_INTERRUPT_CODE_MSR: /* MSR */ - /* Copy MSR from UMP */ - msr = data[1]; - dbg("%s - ===== Port %u MSR Status = %02x ======", - __func__, port_number, msr); - handle_new_msr(edge_port, msr); - break; - - default: - dev_err(&urb->dev->dev, - "%s - Unknown Interrupt code from UMP %x\n", - __func__, data[1]); - break; - - } - -exit: - retval = usb_submit_urb(urb, GFP_ATOMIC); - if (retval) - dev_err(&urb->dev->dev, - "%s - usb_submit_urb failed with result %d\n", - __func__, retval); -} - -static void edge_bulk_in_callback(struct urb *urb) -{ - struct edgeport_port *edge_port = urb->context; - unsigned char *data = urb->transfer_buffer; - struct tty_struct *tty; - int retval = 0; - int port_number; - int status = urb->status; - - dbg("%s", __func__); - - switch (status) { - case 0: - /* success */ - break; - case -ECONNRESET: - case -ENOENT: - case -ESHUTDOWN: - /* this urb is terminated, clean up */ - dbg("%s - urb shutting down with status: %d", - __func__, status); - return; - default: - dev_err(&urb->dev->dev, - "%s - nonzero read bulk status received: %d\n", - __func__, status); - } - - if (status == -EPIPE) - goto exit; - - if (status) { - dev_err(&urb->dev->dev, "%s - stopping read!\n", __func__); - return; - } - - port_number = edge_port->port->number - edge_port->port->serial->minor; - - if (edge_port->lsr_event) { - edge_port->lsr_event = 0; - dbg("%s ===== Port %u LSR Status = %02x, Data = %02x ======", - __func__, port_number, edge_port->lsr_mask, *data); - handle_new_lsr(edge_port, 1, edge_port->lsr_mask, *data); - /* Adjust buffer length/pointer */ - --urb->actual_length; - ++data; - } - - tty = tty_port_tty_get(&edge_port->port->port); - if (tty && urb->actual_length) { - usb_serial_debug_data(debug, &edge_port->port->dev, - __func__, urb->actual_length, data); - if (edge_port->close_pending) - dbg("%s - close pending, dropping data on the floor", - __func__); - else - edge_tty_recv(&edge_port->port->dev, tty, data, - urb->actual_length); - edge_port->icount.rx += urb->actual_length; - } - tty_kref_put(tty); - -exit: - /* continue read unless stopped */ - spin_lock(&edge_port->ep_lock); - if (edge_port->ep_read_urb_state == EDGE_READ_URB_RUNNING) - retval = usb_submit_urb(urb, GFP_ATOMIC); - else if (edge_port->ep_read_urb_state == EDGE_READ_URB_STOPPING) - edge_port->ep_read_urb_state = EDGE_READ_URB_STOPPED; - - spin_unlock(&edge_port->ep_lock); - if (retval) - dev_err(&urb->dev->dev, - "%s - usb_submit_urb failed with result %d\n", - __func__, retval); -} - -static void edge_tty_recv(struct device *dev, struct tty_struct *tty, - unsigned char *data, int length) -{ - int queued; - - queued = tty_insert_flip_string(tty, data, length); - if (queued < length) - dev_err(dev, "%s - dropping data, %d bytes lost\n", - __func__, length - queued); - tty_flip_buffer_push(tty); -} - -static void edge_bulk_out_callback(struct urb *urb) -{ - struct usb_serial_port *port = urb->context; - struct edgeport_port *edge_port = usb_get_serial_port_data(port); - int status = urb->status; - struct tty_struct *tty; - - dbg("%s - port %d", __func__, port->number); - - edge_port->ep_write_urb_in_use = 0; - - switch (status) { - case 0: - /* success */ - break; - case -ECONNRESET: - case -ENOENT: - case -ESHUTDOWN: - /* this urb is terminated, clean up */ - dbg("%s - urb shutting down with status: %d", - __func__, status); - return; - default: - dev_err_console(port, "%s - nonzero write bulk status " - "received: %d\n", __func__, status); - } - - /* send any buffered data */ - tty = tty_port_tty_get(&port->port); - edge_send(tty); - tty_kref_put(tty); -} - -static int edge_open(struct tty_struct *tty, struct usb_serial_port *port) -{ - struct edgeport_port *edge_port = usb_get_serial_port_data(port); - struct edgeport_serial *edge_serial; - struct usb_device *dev; - struct urb *urb; - int port_number; - int status; - u16 open_settings; - u8 transaction_timeout; - - dbg("%s - port %d", __func__, port->number); - - if (edge_port == NULL) - return -ENODEV; - - port_number = port->number - port->serial->minor; - switch (port_number) { - case 0: - edge_port->uart_base = UMPMEM_BASE_UART1; - edge_port->dma_address = UMPD_OEDB1_ADDRESS; - break; - case 1: - edge_port->uart_base = UMPMEM_BASE_UART2; - edge_port->dma_address = UMPD_OEDB2_ADDRESS; - break; - default: - dev_err(&port->dev, "Unknown port number!!!\n"); - return -ENODEV; - } - - dbg("%s - port_number = %d, uart_base = %04x, dma_address = %04x", - __func__, port_number, edge_port->uart_base, - edge_port->dma_address); - - dev = port->serial->dev; - - memset(&(edge_port->icount), 0x00, sizeof(edge_port->icount)); - init_waitqueue_head(&edge_port->delta_msr_wait); - - /* turn off loopback */ - status = ti_do_config(edge_port, UMPC_SET_CLR_LOOPBACK, 0); - if (status) { - dev_err(&port->dev, - "%s - cannot send clear loopback command, %d\n", - __func__, status); - return status; - } - - /* set up the port settings */ - if (tty) - edge_set_termios(tty, port, tty->termios); - - /* open up the port */ - - /* milliseconds to timeout for DMA transfer */ - transaction_timeout = 2; - - edge_port->ump_read_timeout = - max(20, ((transaction_timeout * 3) / 2)); - - /* milliseconds to timeout for DMA transfer */ - open_settings = (u8)(UMP_DMA_MODE_CONTINOUS | - UMP_PIPE_TRANS_TIMEOUT_ENA | - (transaction_timeout << 2)); - - dbg("%s - Sending UMPC_OPEN_PORT", __func__); - - /* Tell TI to open and start the port */ - status = send_cmd(dev, UMPC_OPEN_PORT, - (u8)(UMPM_UART1_PORT + port_number), open_settings, NULL, 0); - if (status) { - dev_err(&port->dev, "%s - cannot send open command, %d\n", - __func__, status); - return status; - } - - /* Start the DMA? */ - status = send_cmd(dev, UMPC_START_PORT, - (u8)(UMPM_UART1_PORT + port_number), 0, NULL, 0); - if (status) { - dev_err(&port->dev, "%s - cannot send start DMA command, %d\n", - __func__, status); - return status; - } - - /* Clear TX and RX buffers in UMP */ - status = purge_port(port, UMP_PORT_DIR_OUT | UMP_PORT_DIR_IN); - if (status) { - dev_err(&port->dev, - "%s - cannot send clear buffers command, %d\n", - __func__, status); - return status; - } - - /* Read Initial MSR */ - status = ti_vread_sync(dev, UMPC_READ_MSR, 0, - (__u16)(UMPM_UART1_PORT + port_number), - &edge_port->shadow_msr, 1); - if (status) { - dev_err(&port->dev, "%s - cannot send read MSR command, %d\n", - __func__, status); - return status; - } - - dbg("ShadowMSR 0x%X", edge_port->shadow_msr); - - /* Set Initial MCR */ - edge_port->shadow_mcr = MCR_RTS | MCR_DTR; - dbg("ShadowMCR 0x%X", edge_port->shadow_mcr); - - edge_serial = edge_port->edge_serial; - if (mutex_lock_interruptible(&edge_serial->es_lock)) - return -ERESTARTSYS; - if (edge_serial->num_ports_open == 0) { - /* we are the first port to open, post the interrupt urb */ - urb = edge_serial->serial->port[0]->interrupt_in_urb; - if (!urb) { - dev_err(&port->dev, - "%s - no interrupt urb present, exiting\n", - __func__); - status = -EINVAL; - goto release_es_lock; - } - urb->context = edge_serial; - status = usb_submit_urb(urb, GFP_KERNEL); - if (status) { - dev_err(&port->dev, - "%s - usb_submit_urb failed with value %d\n", - __func__, status); - goto release_es_lock; - } - } - - /* - * reset the data toggle on the bulk endpoints to work around bug in - * host controllers where things get out of sync some times - */ - usb_clear_halt(dev, port->write_urb->pipe); - usb_clear_halt(dev, port->read_urb->pipe); - - /* start up our bulk read urb */ - urb = port->read_urb; - if (!urb) { - dev_err(&port->dev, "%s - no read urb present, exiting\n", - __func__); - status = -EINVAL; - goto unlink_int_urb; - } - edge_port->ep_read_urb_state = EDGE_READ_URB_RUNNING; - urb->context = edge_port; - status = usb_submit_urb(urb, GFP_KERNEL); - if (status) { - dev_err(&port->dev, - "%s - read bulk usb_submit_urb failed with value %d\n", - __func__, status); - goto unlink_int_urb; - } - - ++edge_serial->num_ports_open; - - dbg("%s - exited", __func__); - - goto release_es_lock; - -unlink_int_urb: - if (edge_port->edge_serial->num_ports_open == 0) - usb_kill_urb(port->serial->port[0]->interrupt_in_urb); -release_es_lock: - mutex_unlock(&edge_serial->es_lock); - return status; -} - -static void edge_close(struct usb_serial_port *port) -{ - struct edgeport_serial *edge_serial; - struct edgeport_port *edge_port; - int port_number; - int status; - - dbg("%s - port %d", __func__, port->number); - - edge_serial = usb_get_serial_data(port->serial); - edge_port = usb_get_serial_port_data(port); - if (edge_serial == NULL || edge_port == NULL) - return; - - /* The bulkreadcompletion routine will check - * this flag and dump add read data */ - edge_port->close_pending = 1; - - /* chase the port close and flush */ - chase_port(edge_port, (HZ * closing_wait) / 100, 1); - - usb_kill_urb(port->read_urb); - usb_kill_urb(port->write_urb); - edge_port->ep_write_urb_in_use = 0; - - /* assuming we can still talk to the device, - * send a close port command to it */ - dbg("%s - send umpc_close_port", __func__); - port_number = port->number - port->serial->minor; - status = send_cmd(port->serial->dev, - UMPC_CLOSE_PORT, - (__u8)(UMPM_UART1_PORT + port_number), - 0, - NULL, - 0); - mutex_lock(&edge_serial->es_lock); - --edge_port->edge_serial->num_ports_open; - if (edge_port->edge_serial->num_ports_open <= 0) { - /* last port is now closed, let's shut down our interrupt urb */ - usb_kill_urb(port->serial->port[0]->interrupt_in_urb); - edge_port->edge_serial->num_ports_open = 0; - } - mutex_unlock(&edge_serial->es_lock); - edge_port->close_pending = 0; - - dbg("%s - exited", __func__); -} - -static int edge_write(struct tty_struct *tty, struct usb_serial_port *port, - const unsigned char *data, int count) -{ - struct edgeport_port *edge_port = usb_get_serial_port_data(port); - - dbg("%s - port %d", __func__, port->number); - - if (count == 0) { - dbg("%s - write request of 0 bytes", __func__); - return 0; - } - - if (edge_port == NULL) - return -ENODEV; - if (edge_port->close_pending == 1) - return -ENODEV; - - count = kfifo_in_locked(&edge_port->write_fifo, data, count, - &edge_port->ep_lock); - edge_send(tty); - - return count; -} - -static void edge_send(struct tty_struct *tty) -{ - struct usb_serial_port *port = tty->driver_data; - int count, result; - struct edgeport_port *edge_port = usb_get_serial_port_data(port); - unsigned long flags; - - - dbg("%s - port %d", __func__, port->number); - - spin_lock_irqsave(&edge_port->ep_lock, flags); - - if (edge_port->ep_write_urb_in_use) { - spin_unlock_irqrestore(&edge_port->ep_lock, flags); - return; - } - - count = kfifo_out(&edge_port->write_fifo, - port->write_urb->transfer_buffer, - port->bulk_out_size); - - if (count == 0) { - spin_unlock_irqrestore(&edge_port->ep_lock, flags); - return; - } - - edge_port->ep_write_urb_in_use = 1; - - spin_unlock_irqrestore(&edge_port->ep_lock, flags); - - usb_serial_debug_data(debug, &port->dev, __func__, count, - port->write_urb->transfer_buffer); - - /* set up our urb */ - port->write_urb->transfer_buffer_length = count; - - /* send the data out the bulk port */ - result = usb_submit_urb(port->write_urb, GFP_ATOMIC); - if (result) { - dev_err_console(port, - "%s - failed submitting write urb, error %d\n", - __func__, result); - edge_port->ep_write_urb_in_use = 0; - /* TODO: reschedule edge_send */ - } else - edge_port->icount.tx += count; - - /* wakeup any process waiting for writes to complete */ - /* there is now more room in the buffer for new writes */ - if (tty) - tty_wakeup(tty); -} - -static int edge_write_room(struct tty_struct *tty) -{ - struct usb_serial_port *port = tty->driver_data; - struct edgeport_port *edge_port = usb_get_serial_port_data(port); - int room = 0; - unsigned long flags; - - dbg("%s - port %d", __func__, port->number); - - if (edge_port == NULL) - return 0; - if (edge_port->close_pending == 1) - return 0; - - spin_lock_irqsave(&edge_port->ep_lock, flags); - room = kfifo_avail(&edge_port->write_fifo); - spin_unlock_irqrestore(&edge_port->ep_lock, flags); - - dbg("%s - returns %d", __func__, room); - return room; -} - -static int edge_chars_in_buffer(struct tty_struct *tty) -{ - struct usb_serial_port *port = tty->driver_data; - struct edgeport_port *edge_port = usb_get_serial_port_data(port); - int chars = 0; - unsigned long flags; - - dbg("%s - port %d", __func__, port->number); - - if (edge_port == NULL) - return 0; - if (edge_port->close_pending == 1) - return 0; - - spin_lock_irqsave(&edge_port->ep_lock, flags); - chars = kfifo_len(&edge_port->write_fifo); - spin_unlock_irqrestore(&edge_port->ep_lock, flags); - - dbg("%s - returns %d", __func__, chars); - return chars; -} - -static void edge_throttle(struct tty_struct *tty) -{ - struct usb_serial_port *port = tty->driver_data; - struct edgeport_port *edge_port = usb_get_serial_port_data(port); - int status; - - dbg("%s - port %d", __func__, port->number); - - if (edge_port == NULL) - return; - - /* if we are implementing XON/XOFF, send the stop character */ - if (I_IXOFF(tty)) { - unsigned char stop_char = STOP_CHAR(tty); - status = edge_write(tty, port, &stop_char, 1); - if (status <= 0) { - dev_err(&port->dev, "%s - failed to write stop character, %d\n", __func__, status); - } - } - - /* if we are implementing RTS/CTS, stop reads */ - /* and the Edgeport will clear the RTS line */ - if (C_CRTSCTS(tty)) - stop_read(edge_port); - -} - -static void edge_unthrottle(struct tty_struct *tty) -{ - struct usb_serial_port *port = tty->driver_data; - struct edgeport_port *edge_port = usb_get_serial_port_data(port); - int status; - - dbg("%s - port %d", __func__, port->number); - - if (edge_port == NULL) - return; - - /* if we are implementing XON/XOFF, send the start character */ - if (I_IXOFF(tty)) { - unsigned char start_char = START_CHAR(tty); - status = edge_write(tty, port, &start_char, 1); - if (status <= 0) { - dev_err(&port->dev, "%s - failed to write start character, %d\n", __func__, status); - } - } - /* if we are implementing RTS/CTS, restart reads */ - /* are the Edgeport will assert the RTS line */ - if (C_CRTSCTS(tty)) { - status = restart_read(edge_port); - if (status) - dev_err(&port->dev, - "%s - read bulk usb_submit_urb failed: %d\n", - __func__, status); - } - -} - -static void stop_read(struct edgeport_port *edge_port) -{ - unsigned long flags; - - spin_lock_irqsave(&edge_port->ep_lock, flags); - - if (edge_port->ep_read_urb_state == EDGE_READ_URB_RUNNING) - edge_port->ep_read_urb_state = EDGE_READ_URB_STOPPING; - edge_port->shadow_mcr &= ~MCR_RTS; - - spin_unlock_irqrestore(&edge_port->ep_lock, flags); -} - -static int restart_read(struct edgeport_port *edge_port) -{ - struct urb *urb; - int status = 0; - unsigned long flags; - - spin_lock_irqsave(&edge_port->ep_lock, flags); - - if (edge_port->ep_read_urb_state == EDGE_READ_URB_STOPPED) { - urb = edge_port->port->read_urb; - status = usb_submit_urb(urb, GFP_ATOMIC); - } - edge_port->ep_read_urb_state = EDGE_READ_URB_RUNNING; - edge_port->shadow_mcr |= MCR_RTS; - - spin_unlock_irqrestore(&edge_port->ep_lock, flags); - - return status; -} - -static void change_port_settings(struct tty_struct *tty, - struct edgeport_port *edge_port, struct ktermios *old_termios) -{ - struct ump_uart_config *config; - int baud; - unsigned cflag; - int status; - int port_number = edge_port->port->number - - edge_port->port->serial->minor; - - dbg("%s - port %d", __func__, edge_port->port->number); - - config = kmalloc (sizeof (*config), GFP_KERNEL); - if (!config) { - *tty->termios = *old_termios; - dev_err(&edge_port->port->dev, "%s - out of memory\n", - __func__); - return; - } - - cflag = tty->termios->c_cflag; - - config->wFlags = 0; - - /* These flags must be set */ - config->wFlags |= UMP_MASK_UART_FLAGS_RECEIVE_MS_INT; - config->wFlags |= UMP_MASK_UART_FLAGS_AUTO_START_ON_ERR; - config->bUartMode = (__u8)(edge_port->bUartMode); - - switch (cflag & CSIZE) { - case CS5: - config->bDataBits = UMP_UART_CHAR5BITS; - dbg("%s - data bits = 5", __func__); - break; - case CS6: - config->bDataBits = UMP_UART_CHAR6BITS; - dbg("%s - data bits = 6", __func__); - break; - case CS7: - config->bDataBits = UMP_UART_CHAR7BITS; - dbg("%s - data bits = 7", __func__); - break; - default: - case CS8: - config->bDataBits = UMP_UART_CHAR8BITS; - dbg("%s - data bits = 8", __func__); - break; - } - - if (cflag & PARENB) { - if (cflag & PARODD) { - config->wFlags |= UMP_MASK_UART_FLAGS_PARITY; - config->bParity = UMP_UART_ODDPARITY; - dbg("%s - parity = odd", __func__); - } else { - config->wFlags |= UMP_MASK_UART_FLAGS_PARITY; - config->bParity = UMP_UART_EVENPARITY; - dbg("%s - parity = even", __func__); - } - } else { - config->bParity = UMP_UART_NOPARITY; - dbg("%s - parity = none", __func__); - } - - if (cflag & CSTOPB) { - config->bStopBits = UMP_UART_STOPBIT2; - dbg("%s - stop bits = 2", __func__); - } else { - config->bStopBits = UMP_UART_STOPBIT1; - dbg("%s - stop bits = 1", __func__); - } - - /* figure out the flow control settings */ - if (cflag & CRTSCTS) { - config->wFlags |= UMP_MASK_UART_FLAGS_OUT_X_CTS_FLOW; - config->wFlags |= UMP_MASK_UART_FLAGS_RTS_FLOW; - dbg("%s - RTS/CTS is enabled", __func__); - } else { - dbg("%s - RTS/CTS is disabled", __func__); - tty->hw_stopped = 0; - restart_read(edge_port); - } - - /* if we are implementing XON/XOFF, set the start and stop - character in the device */ - config->cXon = START_CHAR(tty); - config->cXoff = STOP_CHAR(tty); - - /* if we are implementing INBOUND XON/XOFF */ - if (I_IXOFF(tty)) { - config->wFlags |= UMP_MASK_UART_FLAGS_IN_X; - dbg("%s - INBOUND XON/XOFF is enabled, XON = %2x, XOFF = %2x", - __func__, config->cXon, config->cXoff); - } else - dbg("%s - INBOUND XON/XOFF is disabled", __func__); - - /* if we are implementing OUTBOUND XON/XOFF */ - if (I_IXON(tty)) { - config->wFlags |= UMP_MASK_UART_FLAGS_OUT_X; - dbg("%s - OUTBOUND XON/XOFF is enabled, XON = %2x, XOFF = %2x", - __func__, config->cXon, config->cXoff); - } else - dbg("%s - OUTBOUND XON/XOFF is disabled", __func__); - - tty->termios->c_cflag &= ~CMSPAR; - - /* Round the baud rate */ - baud = tty_get_baud_rate(tty); - if (!baud) { - /* pick a default, any default... */ - baud = 9600; - } else - tty_encode_baud_rate(tty, baud, baud); - - edge_port->baud_rate = baud; - config->wBaudRate = (__u16)((461550L + baud/2) / baud); - - /* FIXME: Recompute actual baud from divisor here */ - - dbg("%s - baud rate = %d, wBaudRate = %d", __func__, baud, - config->wBaudRate); - - dbg("wBaudRate: %d", (int)(461550L / config->wBaudRate)); - dbg("wFlags: 0x%x", config->wFlags); - dbg("bDataBits: %d", config->bDataBits); - dbg("bParity: %d", config->bParity); - dbg("bStopBits: %d", config->bStopBits); - dbg("cXon: %d", config->cXon); - dbg("cXoff: %d", config->cXoff); - dbg("bUartMode: %d", config->bUartMode); - - /* move the word values into big endian mode */ - cpu_to_be16s(&config->wFlags); - cpu_to_be16s(&config->wBaudRate); - - status = send_cmd(edge_port->port->serial->dev, UMPC_SET_CONFIG, - (__u8)(UMPM_UART1_PORT + port_number), - 0, (__u8 *)config, sizeof(*config)); - if (status) - dbg("%s - error %d when trying to write config to device", - __func__, status); - kfree(config); -} - -static void edge_set_termios(struct tty_struct *tty, - struct usb_serial_port *port, struct ktermios *old_termios) -{ - struct edgeport_port *edge_port = usb_get_serial_port_data(port); - unsigned int cflag; - - cflag = tty->termios->c_cflag; - - dbg("%s - clfag %08x iflag %08x", __func__, - tty->termios->c_cflag, tty->termios->c_iflag); - dbg("%s - old clfag %08x old iflag %08x", __func__, - old_termios->c_cflag, old_termios->c_iflag); - dbg("%s - port %d", __func__, port->number); - - if (edge_port == NULL) - return; - /* change the port settings to the new ones specified */ - change_port_settings(tty, edge_port, old_termios); -} - -static int edge_tiocmset(struct tty_struct *tty, - unsigned int set, unsigned int clear) -{ - struct usb_serial_port *port = tty->driver_data; - struct edgeport_port *edge_port = usb_get_serial_port_data(port); - unsigned int mcr; - unsigned long flags; - - dbg("%s - port %d", __func__, port->number); - - spin_lock_irqsave(&edge_port->ep_lock, flags); - mcr = edge_port->shadow_mcr; - if (set & TIOCM_RTS) - mcr |= MCR_RTS; - if (set & TIOCM_DTR) - mcr |= MCR_DTR; - if (set & TIOCM_LOOP) - mcr |= MCR_LOOPBACK; - - if (clear & TIOCM_RTS) - mcr &= ~MCR_RTS; - if (clear & TIOCM_DTR) - mcr &= ~MCR_DTR; - if (clear & TIOCM_LOOP) - mcr &= ~MCR_LOOPBACK; - - edge_port->shadow_mcr = mcr; - spin_unlock_irqrestore(&edge_port->ep_lock, flags); - - restore_mcr(edge_port, mcr); - return 0; -} - -static int edge_tiocmget(struct tty_struct *tty) -{ - struct usb_serial_port *port = tty->driver_data; - struct edgeport_port *edge_port = usb_get_serial_port_data(port); - unsigned int result = 0; - unsigned int msr; - unsigned int mcr; - unsigned long flags; - - dbg("%s - port %d", __func__, port->number); - - spin_lock_irqsave(&edge_port->ep_lock, flags); - - msr = edge_port->shadow_msr; - mcr = edge_port->shadow_mcr; - result = ((mcr & MCR_DTR) ? TIOCM_DTR: 0) /* 0x002 */ - | ((mcr & MCR_RTS) ? TIOCM_RTS: 0) /* 0x004 */ - | ((msr & EDGEPORT_MSR_CTS) ? TIOCM_CTS: 0) /* 0x020 */ - | ((msr & EDGEPORT_MSR_CD) ? TIOCM_CAR: 0) /* 0x040 */ - | ((msr & EDGEPORT_MSR_RI) ? TIOCM_RI: 0) /* 0x080 */ - | ((msr & EDGEPORT_MSR_DSR) ? TIOCM_DSR: 0); /* 0x100 */ - - - dbg("%s -- %x", __func__, result); - spin_unlock_irqrestore(&edge_port->ep_lock, flags); - - return result; -} - -static int edge_get_icount(struct tty_struct *tty, - struct serial_icounter_struct *icount) -{ - struct usb_serial_port *port = tty->driver_data; - struct edgeport_port *edge_port = usb_get_serial_port_data(port); - struct async_icount *ic = &edge_port->icount; - - icount->cts = ic->cts; - icount->dsr = ic->dsr; - icount->rng = ic->rng; - icount->dcd = ic->dcd; - icount->tx = ic->tx; - icount->rx = ic->rx; - icount->frame = ic->frame; - icount->parity = ic->parity; - icount->overrun = ic->overrun; - icount->brk = ic->brk; - icount->buf_overrun = ic->buf_overrun; - return 0; -} - -static int get_serial_info(struct edgeport_port *edge_port, - struct serial_struct __user *retinfo) -{ - struct serial_struct tmp; - - if (!retinfo) - return -EFAULT; - - memset(&tmp, 0, sizeof(tmp)); - - tmp.type = PORT_16550A; - tmp.line = edge_port->port->serial->minor; - tmp.port = edge_port->port->number; - tmp.irq = 0; - tmp.flags = ASYNC_SKIP_TEST | ASYNC_AUTO_IRQ; - tmp.xmit_fifo_size = edge_port->port->bulk_out_size; - tmp.baud_base = 9600; - tmp.close_delay = 5*HZ; - tmp.closing_wait = closing_wait; - - if (copy_to_user(retinfo, &tmp, sizeof(*retinfo))) - return -EFAULT; - return 0; -} - -static int edge_ioctl(struct tty_struct *tty, - unsigned int cmd, unsigned long arg) -{ - struct usb_serial_port *port = tty->driver_data; - struct edgeport_port *edge_port = usb_get_serial_port_data(port); - struct async_icount cnow; - struct async_icount cprev; - - dbg("%s - port %d, cmd = 0x%x", __func__, port->number, cmd); - - switch (cmd) { - case TIOCGSERIAL: - dbg("%s - (%d) TIOCGSERIAL", __func__, port->number); - return get_serial_info(edge_port, - (struct serial_struct __user *) arg); - case TIOCMIWAIT: - dbg("%s - (%d) TIOCMIWAIT", __func__, port->number); - cprev = edge_port->icount; - while (1) { - interruptible_sleep_on(&edge_port->delta_msr_wait); - /* see if a signal did it */ - if (signal_pending(current)) - return -ERESTARTSYS; - cnow = edge_port->icount; - if (cnow.rng == cprev.rng && cnow.dsr == cprev.dsr && - cnow.dcd == cprev.dcd && cnow.cts == cprev.cts) - return -EIO; /* no change => error */ - if (((arg & TIOCM_RNG) && (cnow.rng != cprev.rng)) || - ((arg & TIOCM_DSR) && (cnow.dsr != cprev.dsr)) || - ((arg & TIOCM_CD) && (cnow.dcd != cprev.dcd)) || - ((arg & TIOCM_CTS) && (cnow.cts != cprev.cts))) { - return 0; - } - cprev = cnow; - } - /* not reached */ - break; - } - return -ENOIOCTLCMD; -} - -static void edge_break(struct tty_struct *tty, int break_state) -{ - struct usb_serial_port *port = tty->driver_data; - struct edgeport_port *edge_port = usb_get_serial_port_data(port); - int status; - int bv = 0; /* Off */ - - dbg("%s - state = %d", __func__, break_state); - - /* chase the port close */ - chase_port(edge_port, 0, 0); - - if (break_state == -1) - bv = 1; /* On */ - status = ti_do_config(edge_port, UMPC_SET_CLR_BREAK, bv); - if (status) - dbg("%s - error %d sending break set/clear command.", - __func__, status); -} - -static int edge_startup(struct usb_serial *serial) -{ - struct edgeport_serial *edge_serial; - struct edgeport_port *edge_port; - struct usb_device *dev; - int status; - int i; - - dev = serial->dev; - - /* create our private serial structure */ - edge_serial = kzalloc(sizeof(struct edgeport_serial), GFP_KERNEL); - if (edge_serial == NULL) { - dev_err(&serial->dev->dev, "%s - Out of memory\n", __func__); - return -ENOMEM; - } - mutex_init(&edge_serial->es_lock); - edge_serial->serial = serial; - usb_set_serial_data(serial, edge_serial); - - status = download_fw(edge_serial); - if (status) { - kfree(edge_serial); - return status; - } - - /* set up our port private structures */ - for (i = 0; i < serial->num_ports; ++i) { - edge_port = kzalloc(sizeof(struct edgeport_port), GFP_KERNEL); - if (edge_port == NULL) { - dev_err(&serial->dev->dev, "%s - Out of memory\n", - __func__); - goto cleanup; - } - spin_lock_init(&edge_port->ep_lock); - if (kfifo_alloc(&edge_port->write_fifo, EDGE_OUT_BUF_SIZE, - GFP_KERNEL)) { - dev_err(&serial->dev->dev, "%s - Out of memory\n", - __func__); - kfree(edge_port); - goto cleanup; - } - edge_port->port = serial->port[i]; - edge_port->edge_serial = edge_serial; - usb_set_serial_port_data(serial->port[i], edge_port); - edge_port->bUartMode = default_uart_mode; - } - - return 0; - -cleanup: - for (--i; i >= 0; --i) { - edge_port = usb_get_serial_port_data(serial->port[i]); - kfifo_free(&edge_port->write_fifo); - kfree(edge_port); - usb_set_serial_port_data(serial->port[i], NULL); - } - kfree(edge_serial); - usb_set_serial_data(serial, NULL); - return -ENOMEM; -} - -static void edge_disconnect(struct usb_serial *serial) -{ - dbg("%s", __func__); -} - -static void edge_release(struct usb_serial *serial) -{ - int i; - struct edgeport_port *edge_port; - - dbg("%s", __func__); - - for (i = 0; i < serial->num_ports; ++i) { - edge_port = usb_get_serial_port_data(serial->port[i]); - kfifo_free(&edge_port->write_fifo); - kfree(edge_port); - } - kfree(usb_get_serial_data(serial)); -} - - -/* Sysfs Attributes */ - -static ssize_t show_uart_mode(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct usb_serial_port *port = to_usb_serial_port(dev); - struct edgeport_port *edge_port = usb_get_serial_port_data(port); - - return sprintf(buf, "%d\n", edge_port->bUartMode); -} - -static ssize_t store_uart_mode(struct device *dev, - struct device_attribute *attr, const char *valbuf, size_t count) -{ - struct usb_serial_port *port = to_usb_serial_port(dev); - struct edgeport_port *edge_port = usb_get_serial_port_data(port); - unsigned int v = simple_strtoul(valbuf, NULL, 0); - - dbg("%s: setting uart_mode = %d", __func__, v); - - if (v < 256) - edge_port->bUartMode = v; - else - dev_err(dev, "%s - uart_mode %d is invalid\n", __func__, v); - - return count; -} - -static DEVICE_ATTR(uart_mode, S_IWUSR | S_IRUGO, show_uart_mode, - store_uart_mode); - -static int edge_create_sysfs_attrs(struct usb_serial_port *port) -{ - return device_create_file(&port->dev, &dev_attr_uart_mode); -} - -static int edge_remove_sysfs_attrs(struct usb_serial_port *port) -{ - device_remove_file(&port->dev, &dev_attr_uart_mode); - return 0; -} - - -static struct usb_serial_driver edgeport_1port_device = { - .driver = { - .owner = THIS_MODULE, - .name = "edgeport_ti_1", - }, - .description = "Edgeport TI 1 port adapter", - .id_table = edgeport_1port_id_table, - .num_ports = 1, - .open = edge_open, - .close = edge_close, - .throttle = edge_throttle, - .unthrottle = edge_unthrottle, - .attach = edge_startup, - .disconnect = edge_disconnect, - .release = edge_release, - .port_probe = edge_create_sysfs_attrs, - .port_remove = edge_remove_sysfs_attrs, - .ioctl = edge_ioctl, - .set_termios = edge_set_termios, - .tiocmget = edge_tiocmget, - .tiocmset = edge_tiocmset, - .get_icount = edge_get_icount, - .write = edge_write, - .write_room = edge_write_room, - .chars_in_buffer = edge_chars_in_buffer, - .break_ctl = edge_break, - .read_int_callback = edge_interrupt_callback, - .read_bulk_callback = edge_bulk_in_callback, - .write_bulk_callback = edge_bulk_out_callback, -}; - -static struct usb_serial_driver edgeport_2port_device = { - .driver = { - .owner = THIS_MODULE, - .name = "edgeport_ti_2", - }, - .description = "Edgeport TI 2 port adapter", - .id_table = edgeport_2port_id_table, - .num_ports = 2, - .open = edge_open, - .close = edge_close, - .throttle = edge_throttle, - .unthrottle = edge_unthrottle, - .attach = edge_startup, - .disconnect = edge_disconnect, - .release = edge_release, - .port_probe = edge_create_sysfs_attrs, - .port_remove = edge_remove_sysfs_attrs, - .ioctl = edge_ioctl, - .set_termios = edge_set_termios, - .tiocmget = edge_tiocmget, - .tiocmset = edge_tiocmset, - .write = edge_write, - .write_room = edge_write_room, - .chars_in_buffer = edge_chars_in_buffer, - .break_ctl = edge_break, - .read_int_callback = edge_interrupt_callback, - .read_bulk_callback = edge_bulk_in_callback, - .write_bulk_callback = edge_bulk_out_callback, -}; - -static struct usb_serial_driver * const serial_drivers[] = { - &edgeport_1port_device, &edgeport_2port_device, NULL -}; - -module_usb_serial_driver(io_driver, serial_drivers); - -MODULE_AUTHOR(DRIVER_AUTHOR); -MODULE_DESCRIPTION(DRIVER_DESC); -MODULE_LICENSE("GPL"); -MODULE_FIRMWARE("edgeport/down3.bin"); - -module_param(debug, bool, S_IRUGO | S_IWUSR); -MODULE_PARM_DESC(debug, "Debug enabled or not"); - -module_param(closing_wait, int, S_IRUGO | S_IWUSR); -MODULE_PARM_DESC(closing_wait, "Maximum wait for data to drain, in .01 secs"); - -module_param(ignore_cpu_rev, bool, S_IRUGO | S_IWUSR); -MODULE_PARM_DESC(ignore_cpu_rev, - "Ignore the cpu revision when connecting to a device"); - -module_param(default_uart_mode, int, S_IRUGO | S_IWUSR); -MODULE_PARM_DESC(default_uart_mode, "Default uart_mode, 0=RS232, ..."); diff --git a/ANDROID_3.4.5/drivers/usb/serial/io_ti.h b/ANDROID_3.4.5/drivers/usb/serial/io_ti.h deleted file mode 100644 index 1bd67b24..00000000 --- a/ANDROID_3.4.5/drivers/usb/serial/io_ti.h +++ /dev/null @@ -1,186 +0,0 @@ -/***************************************************************************** - * - * Copyright (C) 1997-2002 Inside Out Networks, Inc. - * - * 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. - * - * - * Feb-16-2001 DMI Added I2C structure definitions - * May-29-2002 gkh Ported to Linux - * - * - ******************************************************************************/ - -#ifndef _IO_TI_H_ -#define _IO_TI_H_ - -/* Address Space */ -#define DTK_ADDR_SPACE_XDATA 0x03 /* Addr is placed in XDATA space */ -#define DTK_ADDR_SPACE_I2C_TYPE_II 0x82 /* Addr is placed in I2C area */ -#define DTK_ADDR_SPACE_I2C_TYPE_III 0x83 /* Addr is placed in I2C area */ - -/* UART Defines */ -#define UMPMEM_BASE_UART1 0xFFA0 /* UMP UART1 base address */ -#define UMPMEM_BASE_UART2 0xFFB0 /* UMP UART2 base address */ -#define UMPMEM_OFFS_UART_LSR 0x05 /* UMP UART LSR register offset */ - -/* Bits per character */ -#define UMP_UART_CHAR5BITS 0x00 -#define UMP_UART_CHAR6BITS 0x01 -#define UMP_UART_CHAR7BITS 0x02 -#define UMP_UART_CHAR8BITS 0x03 - -/* Parity */ -#define UMP_UART_NOPARITY 0x00 -#define UMP_UART_ODDPARITY 0x01 -#define UMP_UART_EVENPARITY 0x02 -#define UMP_UART_MARKPARITY 0x03 -#define UMP_UART_SPACEPARITY 0x04 - -/* Stop bits */ -#define UMP_UART_STOPBIT1 0x00 -#define UMP_UART_STOPBIT15 0x01 -#define UMP_UART_STOPBIT2 0x02 - -/* Line status register masks */ -#define UMP_UART_LSR_OV_MASK 0x01 -#define UMP_UART_LSR_PE_MASK 0x02 -#define UMP_UART_LSR_FE_MASK 0x04 -#define UMP_UART_LSR_BR_MASK 0x08 -#define UMP_UART_LSR_ER_MASK 0x0F -#define UMP_UART_LSR_RX_MASK 0x10 -#define UMP_UART_LSR_TX_MASK 0x20 - -#define UMP_UART_LSR_DATA_MASK (LSR_PAR_ERR | LSR_FRM_ERR | LSR_BREAK) - -/* Port Settings Constants) */ -#define UMP_MASK_UART_FLAGS_RTS_FLOW 0x0001 -#define UMP_MASK_UART_FLAGS_RTS_DISABLE 0x0002 -#define UMP_MASK_UART_FLAGS_PARITY 0x0008 -#define UMP_MASK_UART_FLAGS_OUT_X_DSR_FLOW 0x0010 -#define UMP_MASK_UART_FLAGS_OUT_X_CTS_FLOW 0x0020 -#define UMP_MASK_UART_FLAGS_OUT_X 0x0040 -#define UMP_MASK_UART_FLAGS_OUT_XA 0x0080 -#define UMP_MASK_UART_FLAGS_IN_X 0x0100 -#define UMP_MASK_UART_FLAGS_DTR_FLOW 0x0800 -#define UMP_MASK_UART_FLAGS_DTR_DISABLE 0x1000 -#define UMP_MASK_UART_FLAGS_RECEIVE_MS_INT 0x2000 -#define UMP_MASK_UART_FLAGS_AUTO_START_ON_ERR 0x4000 - -#define UMP_DMA_MODE_CONTINOUS 0x01 -#define UMP_PIPE_TRANS_TIMEOUT_ENA 0x80 -#define UMP_PIPE_TRANSFER_MODE_MASK 0x03 -#define UMP_PIPE_TRANS_TIMEOUT_MASK 0x7C - -/* Purge port Direction Mask Bits */ -#define UMP_PORT_DIR_OUT 0x01 -#define UMP_PORT_DIR_IN 0x02 - -/* Address of Port 0 */ -#define UMPM_UART1_PORT 0x03 - -/* Commands */ -#define UMPC_SET_CONFIG 0x05 -#define UMPC_OPEN_PORT 0x06 -#define UMPC_CLOSE_PORT 0x07 -#define UMPC_START_PORT 0x08 -#define UMPC_STOP_PORT 0x09 -#define UMPC_TEST_PORT 0x0A -#define UMPC_PURGE_PORT 0x0B - -/* Force the Firmware to complete the current Read */ -#define UMPC_COMPLETE_READ 0x80 -/* Force UMP back into BOOT Mode */ -#define UMPC_HARDWARE_RESET 0x81 -/* - * Copy current download image to type 0xf2 record in 16k I2C - * firmware will change 0xff record to type 2 record when complete - */ -#define UMPC_COPY_DNLD_TO_I2C 0x82 - -/* - * Special function register commands - * wIndex is register address - * wValue is MSB/LSB mask/data - */ -#define UMPC_WRITE_SFR 0x83 /* Write SFR Register */ - -/* wIndex is register address */ -#define UMPC_READ_SFR 0x84 /* Read SRF Register */ - -/* Set or Clear DTR (wValue bit 0 Set/Clear) wIndex ModuleID (port) */ -#define UMPC_SET_CLR_DTR 0x85 - -/* Set or Clear RTS (wValue bit 0 Set/Clear) wIndex ModuleID (port) */ -#define UMPC_SET_CLR_RTS 0x86 - -/* Set or Clear LOOPBACK (wValue bit 0 Set/Clear) wIndex ModuleID (port) */ -#define UMPC_SET_CLR_LOOPBACK 0x87 - -/* Set or Clear BREAK (wValue bit 0 Set/Clear) wIndex ModuleID (port) */ -#define UMPC_SET_CLR_BREAK 0x88 - -/* Read MSR wIndex ModuleID (port) */ -#define UMPC_READ_MSR 0x89 - -/* Toolkit commands */ -/* Read-write group */ -#define UMPC_MEMORY_READ 0x92 -#define UMPC_MEMORY_WRITE 0x93 - -/* - * UMP DMA Definitions - */ -#define UMPD_OEDB1_ADDRESS 0xFF08 -#define UMPD_OEDB2_ADDRESS 0xFF10 - -struct out_endpoint_desc_block { - __u8 Configuration; - __u8 XBufAddr; - __u8 XByteCount; - __u8 Unused1; - __u8 Unused2; - __u8 YBufAddr; - __u8 YByteCount; - __u8 BufferSize; -} __attribute__((packed)); - - -/* - * TYPE DEFINITIONS - * Structures for Firmware commands - */ -/* UART settings */ -struct ump_uart_config { - __u16 wBaudRate; /* Baud rate */ - __u16 wFlags; /* Bitmap mask of flags */ - __u8 bDataBits; /* 5..8 - data bits per character */ - __u8 bParity; /* Parity settings */ - __u8 bStopBits; /* Stop bits settings */ - char cXon; /* XON character */ - char cXoff; /* XOFF character */ - __u8 bUartMode; /* Will be updated when a user */ - /* interface is defined */ -} __attribute__((packed)); - - -/* - * TYPE DEFINITIONS - * Structures for USB interrupts - */ -/* Interrupt packet structure */ -struct ump_interrupt { - __u8 bICode; /* Interrupt code (interrupt num) */ - __u8 bIInfo; /* Interrupt information */ -} __attribute__((packed)); - - -#define TIUMP_GET_PORT_FROM_CODE(c) (((c) >> 4) - 3) -#define TIUMP_GET_FUNC_FROM_CODE(c) ((c) & 0x0f) -#define TIUMP_INTERRUPT_CODE_LSR 0x03 -#define TIUMP_INTERRUPT_CODE_MSR 0x04 - -#endif diff --git a/ANDROID_3.4.5/drivers/usb/serial/io_usbvend.h b/ANDROID_3.4.5/drivers/usb/serial/io_usbvend.h deleted file mode 100644 index 51f83fbb..00000000 --- a/ANDROID_3.4.5/drivers/usb/serial/io_usbvend.h +++ /dev/null @@ -1,683 +0,0 @@ -/************************************************************************ - * - * USBVEND.H Vendor-specific USB definitions - * - * NOTE: This must be kept in sync with the Edgeport firmware and - * must be kept backward-compatible with older firmware. - * - ************************************************************************ - * - * Copyright (C) 1998 Inside Out Networks, Inc. - * 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. - * - ************************************************************************/ - -#if !defined(_USBVEND_H) -#define _USBVEND_H - -/************************************************************************ - * - * D e f i n e s / T y p e d e f s - * - ************************************************************************/ - -// -// Definitions of USB product IDs -// - -#define USB_VENDOR_ID_ION 0x1608 // Our VID -#define USB_VENDOR_ID_TI 0x0451 // TI VID -#define USB_VENDOR_ID_AXIOHM 0x05D9 /* Axiohm VID */ - -// -// Definitions of USB product IDs (PID) -// We break the USB-defined PID into an OEM Id field (upper 6 bits) -// and a Device Id (bottom 10 bits). The Device Id defines what -// device this actually is regardless of what the OEM wants to -// call it. -// - -// ION-device OEM IDs -#define ION_OEM_ID_ION 0 // 00h Inside Out Networks -#define ION_OEM_ID_NLYNX 1 // 01h NLynx Systems -#define ION_OEM_ID_GENERIC 2 // 02h Generic OEM -#define ION_OEM_ID_MAC 3 // 03h Mac Version -#define ION_OEM_ID_MEGAWOLF 4 // 04h Lupusb OEM Mac version (MegaWolf) -#define ION_OEM_ID_MULTITECH 5 // 05h Multitech Rapidports -#define ION_OEM_ID_AGILENT 6 // 06h AGILENT board - - -// ION-device Device IDs -// Product IDs - assigned to match middle digit of serial number (No longer true) - -#define ION_DEVICE_ID_80251_NETCHIP 0x020 // This bit is set in the PID if this edgeport hardware$ - // is based on the 80251+Netchip. - -#define ION_DEVICE_ID_GENERATION_1 0x00 // Value for 930 based edgeports -#define ION_DEVICE_ID_GENERATION_2 0x01 // Value for 80251+Netchip. -#define ION_DEVICE_ID_GENERATION_3 0x02 // Value for Texas Instruments TUSB5052 chip -#define ION_DEVICE_ID_GENERATION_4 0x03 // Watchport Family of products -#define ION_GENERATION_MASK 0x03 - -#define ION_DEVICE_ID_HUB_MASK 0x0080 // This bit in the PID designates a HUB device - // for example 8C would be a 421 4 port hub - // and 8D would be a 2 port embedded hub - -#define EDGEPORT_DEVICE_ID_MASK 0x0ff // Not including OEM or GENERATION fields - -#define ION_DEVICE_ID_UNCONFIGURED_EDGE_DEVICE 0x000 // In manufacturing only -#define ION_DEVICE_ID_EDGEPORT_4 0x001 // Edgeport/4 RS232 -#define ION_DEVICE_ID_EDGEPORT_8R 0x002 // Edgeport with RJ45 no Ring -#define ION_DEVICE_ID_RAPIDPORT_4 0x003 // Rapidport/4 -#define ION_DEVICE_ID_EDGEPORT_4T 0x004 // Edgeport/4 RS232 for Telxon (aka "Fleetport") -#define ION_DEVICE_ID_EDGEPORT_2 0x005 // Edgeport/2 RS232 -#define ION_DEVICE_ID_EDGEPORT_4I 0x006 // Edgeport/4 RS422 -#define ION_DEVICE_ID_EDGEPORT_2I 0x007 // Edgeport/2 RS422/RS485 -#define ION_DEVICE_ID_EDGEPORT_8RR 0x008 // Edgeport with RJ45 with Data and RTS/CTS only -// ION_DEVICE_ID_EDGEPORT_8_HANDBUILT 0x009 // Hand-built Edgeport/8 (Placeholder, used in middle digit of serial number only!) -// ION_DEVICE_ID_MULTIMODEM_4X56 0x00A // MultiTech version of RP/4 (Placeholder, used in middle digit of serial number only!) -#define ION_DEVICE_ID_EDGEPORT_PARALLEL_PORT 0x00B // Edgeport/(4)21 Parallel port (USS720) -#define ION_DEVICE_ID_EDGEPORT_421 0x00C // Edgeport/421 Hub+RS232+Parallel -#define ION_DEVICE_ID_EDGEPORT_21 0x00D // Edgeport/21 RS232+Parallel -#define ION_DEVICE_ID_EDGEPORT_8_DUAL_CPU 0x00E // Half of an Edgeport/8 (the kind with 2 EP/4s on 1 PCB) -#define ION_DEVICE_ID_EDGEPORT_8 0x00F // Edgeport/8 (single-CPU) -#define ION_DEVICE_ID_EDGEPORT_2_DIN 0x010 // Edgeport/2 RS232 with Apple DIN connector -#define ION_DEVICE_ID_EDGEPORT_4_DIN 0x011 // Edgeport/4 RS232 with Apple DIN connector -#define ION_DEVICE_ID_EDGEPORT_16_DUAL_CPU 0x012 // Half of an Edgeport/16 (the kind with 2 EP/8s) -#define ION_DEVICE_ID_EDGEPORT_COMPATIBLE 0x013 // Edgeport Compatible, for NCR, Axiohm etc. testing -#define ION_DEVICE_ID_EDGEPORT_8I 0x014 // Edgeport/8 RS422 (single-CPU) -#define ION_DEVICE_ID_EDGEPORT_1 0x015 // Edgeport/1 RS232 -#define ION_DEVICE_ID_EPOS44 0x016 // Half of an EPOS/44 (TIUMP BASED) -#define ION_DEVICE_ID_EDGEPORT_42 0x017 // Edgeport/42 -#define ION_DEVICE_ID_EDGEPORT_412_8 0x018 // Edgeport/412 8 port part -#define ION_DEVICE_ID_EDGEPORT_412_4 0x019 // Edgeport/412 4 port part -#define ION_DEVICE_ID_EDGEPORT_22I 0x01A // Edgeport/22I is an Edgeport/4 with ports 1&2 RS422 and ports 3&4 RS232 - -// Compact Form factor TI based devices 2c, 21c, 22c, 221c -#define ION_DEVICE_ID_EDGEPORT_2C 0x01B // Edgeport/2c is a TI based Edgeport/2 - Small I2c -#define ION_DEVICE_ID_EDGEPORT_221C 0x01C // Edgeport/221c is a TI based Edgeport/2 with lucent chip and - // 2 external hub ports - Large I2C -#define ION_DEVICE_ID_EDGEPORT_22C 0x01D // Edgeport/22c is a TI based Edgeport/2 with - // 2 external hub ports - Large I2C -#define ION_DEVICE_ID_EDGEPORT_21C 0x01E // Edgeport/21c is a TI based Edgeport/2 with lucent chip - // Small I2C - - -/* - * DANGER DANGER The 0x20 bit was used to indicate a 8251/netchip GEN 2 device. - * Since the MAC, Linux, and Optimal drivers still used the old code - * I suggest that you skip the 0x20 bit when creating new PIDs - */ - - -// Generation 3 devices -- 3410 based edgport/1 (256 byte I2C) -#define ION_DEVICE_ID_TI3410_EDGEPORT_1 0x040 // Edgeport/1 RS232 -#define ION_DEVICE_ID_TI3410_EDGEPORT_1I 0x041 // Edgeport/1i- RS422 model - -// Ti based software switchable RS232/RS422/RS485 devices -#define ION_DEVICE_ID_EDGEPORT_4S 0x042 // Edgeport/4s - software switchable model -#define ION_DEVICE_ID_EDGEPORT_8S 0x043 // Edgeport/8s - software switchable model - -// Usb to Ethernet dongle -#define ION_DEVICE_ID_EDGEPORT_E 0x0E0 // Edgeport/E Usb to Ethernet - -// Edgeport TI based devices -#define ION_DEVICE_ID_TI_EDGEPORT_4 0x0201 // Edgeport/4 RS232 -#define ION_DEVICE_ID_TI_EDGEPORT_2 0x0205 // Edgeport/2 RS232 -#define ION_DEVICE_ID_TI_EDGEPORT_4I 0x0206 // Edgeport/4i RS422 -#define ION_DEVICE_ID_TI_EDGEPORT_2I 0x0207 // Edgeport/2i RS422/RS485 -#define ION_DEVICE_ID_TI_EDGEPORT_421 0x020C // Edgeport/421 4 hub 2 RS232 + Parallel (lucent on a different hub port) -#define ION_DEVICE_ID_TI_EDGEPORT_21 0x020D // Edgeport/21 2 RS232 + Parallel (lucent on a different hub port) -#define ION_DEVICE_ID_TI_EDGEPORT_416 0x0212 // Edgeport/416 -#define ION_DEVICE_ID_TI_EDGEPORT_1 0x0215 // Edgeport/1 RS232 -#define ION_DEVICE_ID_TI_EDGEPORT_42 0x0217 // Edgeport/42 4 hub 2 RS232 -#define ION_DEVICE_ID_TI_EDGEPORT_22I 0x021A // Edgeport/22I is an Edgeport/4 with ports 1&2 RS422 and ports 3&4 RS232 -#define ION_DEVICE_ID_TI_EDGEPORT_2C 0x021B // Edgeport/2c RS232 -#define ION_DEVICE_ID_TI_EDGEPORT_221C 0x021C // Edgeport/221c is a TI based Edgeport/2 with lucent chip and - // 2 external hub ports - Large I2C -#define ION_DEVICE_ID_TI_EDGEPORT_22C 0x021D // Edgeport/22c is a TI based Edgeport/2 with - // 2 external hub ports - Large I2C -#define ION_DEVICE_ID_TI_EDGEPORT_21C 0x021E // Edgeport/21c is a TI based Edgeport/2 with lucent chip - -// Generation 3 devices -- 3410 based edgport/1 (256 byte I2C) -#define ION_DEVICE_ID_TI_TI3410_EDGEPORT_1 0x0240 // Edgeport/1 RS232 -#define ION_DEVICE_ID_TI_TI3410_EDGEPORT_1I 0x0241 // Edgeport/1i- RS422 model - -// Ti based software switchable RS232/RS422/RS485 devices -#define ION_DEVICE_ID_TI_EDGEPORT_4S 0x0242 // Edgeport/4s - software switchable model -#define ION_DEVICE_ID_TI_EDGEPORT_8S 0x0243 // Edgeport/8s - software switchable model -#define ION_DEVICE_ID_TI_EDGEPORT_8 0x0244 // Edgeport/8 (single-CPU) -#define ION_DEVICE_ID_TI_EDGEPORT_416B 0x0247 // Edgeport/416 - - -/************************************************************************ - * - * Generation 4 devices - * - ************************************************************************/ - -// Watchport based on 3410 both 1-wire and binary products (16K I2C) -#define ION_DEVICE_ID_WP_UNSERIALIZED 0x300 // Watchport based on 3410 both 1-wire and binary products -#define ION_DEVICE_ID_WP_PROXIMITY 0x301 // Watchport/P Discontinued -#define ION_DEVICE_ID_WP_MOTION 0x302 // Watchport/M -#define ION_DEVICE_ID_WP_MOISTURE 0x303 // Watchport/W -#define ION_DEVICE_ID_WP_TEMPERATURE 0x304 // Watchport/T -#define ION_DEVICE_ID_WP_HUMIDITY 0x305 // Watchport/H - -#define ION_DEVICE_ID_WP_POWER 0x306 // Watchport -#define ION_DEVICE_ID_WP_LIGHT 0x307 // Watchport -#define ION_DEVICE_ID_WP_RADIATION 0x308 // Watchport -#define ION_DEVICE_ID_WP_ACCELERATION 0x309 // Watchport/A -#define ION_DEVICE_ID_WP_DISTANCE 0x30A // Watchport/D Discontinued -#define ION_DEVICE_ID_WP_PROX_DIST 0x30B // Watchport/D uses distance sensor - // Default to /P function - -#define ION_DEVICE_ID_PLUS_PWR_HP4CD 0x30C // 5052 Plus Power HubPort/4CD+ (for Dell) -#define ION_DEVICE_ID_PLUS_PWR_HP4C 0x30D // 5052 Plus Power HubPort/4C+ -#define ION_DEVICE_ID_PLUS_PWR_PCI 0x30E // 3410 Plus Power PCI Host Controller 4 port - - -// -// Definitions for AXIOHM USB product IDs -// -#define USB_VENDOR_ID_AXIOHM 0x05D9 // Axiohm VID - -#define AXIOHM_DEVICE_ID_MASK 0xffff -#define AXIOHM_DEVICE_ID_EPIC_A758 0xA758 -#define AXIOHM_DEVICE_ID_EPIC_A794 0xA794 -#define AXIOHM_DEVICE_ID_EPIC_A225 0xA225 - - -// -// Definitions for NCR USB product IDs -// -#define USB_VENDOR_ID_NCR 0x0404 // NCR VID - -#define NCR_DEVICE_ID_MASK 0xffff -#define NCR_DEVICE_ID_EPIC_0202 0x0202 -#define NCR_DEVICE_ID_EPIC_0203 0x0203 -#define NCR_DEVICE_ID_EPIC_0310 0x0310 -#define NCR_DEVICE_ID_EPIC_0311 0x0311 -#define NCR_DEVICE_ID_EPIC_0312 0x0312 - - -// -// Definitions for SYMBOL USB product IDs -// -#define USB_VENDOR_ID_SYMBOL 0x05E0 // Symbol VID -#define SYMBOL_DEVICE_ID_MASK 0xffff -#define SYMBOL_DEVICE_ID_KEYFOB 0x0700 - - -// -// Definitions for other product IDs -#define ION_DEVICE_ID_MT4X56USB 0x1403 // OEM device - - -#define GENERATION_ID_FROM_USB_PRODUCT_ID(ProductId) \ - ((__u16) ((ProductId >> 8) & (ION_GENERATION_MASK))) - -#define MAKE_USB_PRODUCT_ID(OemId, DeviceId) \ - ((__u16) (((OemId) << 10) || (DeviceId))) - -#define DEVICE_ID_FROM_USB_PRODUCT_ID(ProductId) \ - ((__u16) ((ProductId) & (EDGEPORT_DEVICE_ID_MASK))) - -#define OEM_ID_FROM_USB_PRODUCT_ID(ProductId) \ - ((__u16) (((ProductId) >> 10) & 0x3F)) - -// -// Definitions of parameters for download code. Note that these are -// specific to a given version of download code and must change if the -// corresponding download code changes. -// - -// TxCredits value below which driver won't bother sending (to prevent too many small writes). -// Send only if above 25% -#define EDGE_FW_GET_TX_CREDITS_SEND_THRESHOLD(InitialCredit, MaxPacketSize) (max(((InitialCredit) / 4), (MaxPacketSize))) - -#define EDGE_FW_BULK_MAX_PACKET_SIZE 64 // Max Packet Size for Bulk In Endpoint (EP1) -#define EDGE_FW_BULK_READ_BUFFER_SIZE 1024 // Size to use for Bulk reads - -#define EDGE_FW_INT_MAX_PACKET_SIZE 32 // Max Packet Size for Interrupt In Endpoint - // Note that many units were shipped with MPS=16, we - // force an upgrade to this value). -#define EDGE_FW_INT_INTERVAL 2 // 2ms polling on IntPipe - - -// -// Definitions of I/O Networks vendor-specific requests -// for default endpoint -// -// bmRequestType = 01000000 Set vendor-specific, to device -// bmRequestType = 11000000 Get vendor-specific, to device -// -// These are the definitions for the bRequest field for the -// above bmRequestTypes. -// -// For the read/write Edgeport memory commands, the parameters -// are as follows: -// wValue = 16-bit address -// wIndex = unused (though we could put segment 00: or FF: here) -// wLength = # bytes to read/write (max 64) -// - -#define USB_REQUEST_ION_RESET_DEVICE 0 // Warm reboot Edgeport, retaining USB address -#define USB_REQUEST_ION_GET_EPIC_DESC 1 // Get Edgeport Compatibility Descriptor -// unused 2 // Unused, available -#define USB_REQUEST_ION_READ_RAM 3 // Read EdgePort RAM at specified addr -#define USB_REQUEST_ION_WRITE_RAM 4 // Write EdgePort RAM at specified addr -#define USB_REQUEST_ION_READ_ROM 5 // Read EdgePort ROM at specified addr -#define USB_REQUEST_ION_WRITE_ROM 6 // Write EdgePort ROM at specified addr -#define USB_REQUEST_ION_EXEC_DL_CODE 7 // Begin execution of RAM-based download - // code by jumping to address in wIndex:wValue -// 8 // Unused, available -#define USB_REQUEST_ION_ENABLE_SUSPEND 9 // Enable/Disable suspend feature - // (wValue != 0: Enable; wValue = 0: Disable) - -#define USB_REQUEST_ION_SEND_IOSP 10 // Send an IOSP command to the edgeport over the control pipe -#define USB_REQUEST_ION_RECV_IOSP 11 // Receive an IOSP command from the edgeport over the control pipe - - -#define USB_REQUEST_ION_DIS_INT_TIMER 0x80 // Sent to Axiohm to enable/ disable - // interrupt token timer - // wValue = 1, enable (default) - // wValue = 0, disable - -// -// Define parameter values for our vendor-specific commands -// - -// -// Edgeport Compatibility Descriptor -// -// This descriptor is only returned by Edgeport-compatible devices -// supporting the EPiC spec. True ION devices do not return this -// descriptor, but instead return STALL on receipt of the -// GET_EPIC_DESC command. The driver interprets a STALL to mean that -// this is a "real" Edgeport. -// - -struct edge_compatibility_bits { - // This __u32 defines which Vendor-specific commands/functionality - // the device supports on the default EP0 pipe. - - __u32 VendEnableSuspend : 1; // 0001 Set if device supports ION_ENABLE_SUSPEND - __u32 VendUnused : 31; // Available for future expansion, must be 0 - - // This __u32 defines which IOSP commands are supported over the - // bulk pipe EP1. - - // xxxx Set if device supports: - __u32 IOSPOpen : 1; // 0001 OPEN / OPEN_RSP (Currently must be 1) - __u32 IOSPClose : 1; // 0002 CLOSE - __u32 IOSPChase : 1; // 0004 CHASE / CHASE_RSP - __u32 IOSPSetRxFlow : 1; // 0008 SET_RX_FLOW - __u32 IOSPSetTxFlow : 1; // 0010 SET_TX_FLOW - __u32 IOSPSetXChar : 1; // 0020 SET_XON_CHAR/SET_XOFF_CHAR - __u32 IOSPRxCheck : 1; // 0040 RX_CHECK_REQ/RX_CHECK_RSP - __u32 IOSPSetClrBreak : 1; // 0080 SET_BREAK/CLEAR_BREAK - __u32 IOSPWriteMCR : 1; // 0100 MCR register writes (set/clr DTR/RTS) - __u32 IOSPWriteLCR : 1; // 0200 LCR register writes (wordlen/stop/parity) - __u32 IOSPSetBaudRate : 1; // 0400 setting Baud rate (writes to LCR.80h and DLL/DLM register) - __u32 IOSPDisableIntPipe : 1; // 0800 Do not use the interrupt pipe for TxCredits or RxButesAvailable - __u32 IOSPRxDataAvail : 1; // 1000 Return status of RX Fifo (Data available in Fifo) - __u32 IOSPTxPurge : 1; // 2000 Purge TXBuffer and/or Fifo in Edgeport hardware - __u32 IOSPUnused : 18; // Available for future expansion, must be 0 - - // This __u32 defines which 'general' features are supported - - __u32 TrueEdgeport : 1; // 0001 Set if device is a 'real' Edgeport - // (Used only by driver, NEVER set by an EPiC device) - __u32 GenUnused : 31; // Available for future expansion, must be 0 -}; - -#define EDGE_COMPATIBILITY_MASK0 0x0001 -#define EDGE_COMPATIBILITY_MASK1 0x3FFF -#define EDGE_COMPATIBILITY_MASK2 0x0001 - -struct edge_compatibility_descriptor { - __u8 Length; // Descriptor Length (per USB spec) - __u8 DescType; // Descriptor Type (per USB spec, =DEVICE type) - __u8 EpicVer; // Version of EPiC spec supported - // (Currently must be 1) - __u8 NumPorts; // Number of serial ports supported - __u8 iDownloadFile; // Index of string containing download code filename - // 0=no download, FF=download compiled into driver. - __u8 Unused[3]; // Available for future expansion, must be 0 - // (Currently must be 0). - __u8 MajorVersion; // Firmware version: xx. - __u8 MinorVersion; // yy. - __le16 BuildNumber; // zzzz (LE format) - - // The following structure contains __u32s, with each bit - // specifying whether the EPiC device supports the given - // command or functionality. - struct edge_compatibility_bits Supports; -}; - -// Values for iDownloadFile -#define EDGE_DOWNLOAD_FILE_NONE 0 // No download requested -#define EDGE_DOWNLOAD_FILE_INTERNAL 0xFF // Download the file compiled into driver (930 version) -#define EDGE_DOWNLOAD_FILE_I930 0xFF // Download the file compiled into driver (930 version) -#define EDGE_DOWNLOAD_FILE_80251 0xFE // Download the file compiled into driver (80251 version) - - - -/* - * Special addresses for READ/WRITE_RAM/ROM - */ - -// Version 1 (original) format of DeviceParams -#define EDGE_MANUF_DESC_ADDR_V1 0x00FF7F00 -#define EDGE_MANUF_DESC_LEN_V1 sizeof(EDGE_MANUF_DESCRIPTOR_V1) - -// Version 2 format of DeviceParams. This format is longer (3C0h) -// and starts lower in memory, at the uppermost 1K in ROM. -#define EDGE_MANUF_DESC_ADDR 0x00FF7C00 -#define EDGE_MANUF_DESC_LEN sizeof(struct edge_manuf_descriptor) - -// Boot params descriptor -#define EDGE_BOOT_DESC_ADDR 0x00FF7FC0 -#define EDGE_BOOT_DESC_LEN sizeof(struct edge_boot_descriptor) - -// Define the max block size that may be read or written -// in a read/write RAM/ROM command. -#define MAX_SIZE_REQ_ION_READ_MEM ((__u16)64) -#define MAX_SIZE_REQ_ION_WRITE_MEM ((__u16)64) - - -// -// Notes for the following two ION vendor-specific param descriptors: -// -// 1. These have a standard USB descriptor header so they look like a -// normal descriptor. -// 2. Any strings in the structures are in USB-defined string -// descriptor format, so that they may be separately retrieved, -// if necessary, with a minimum of work on the 930. This also -// requires them to be in UNICODE format, which, for English at -// least, simply means extending each __u8 into a __u16. -// 3. For all fields, 00 means 'uninitialized'. -// 4. All unused areas should be set to 00 for future expansion. -// - -// This structure is ver 2 format. It contains ALL USB descriptors as -// well as the configuration parameters that were in the original V1 -// structure. It is NOT modified when new boot code is downloaded; rather, -// these values are set or modified by manufacturing. It is located at -// xC00-xFBF (length 3C0h) in the ROM. -// This structure is a superset of the v1 structure and is arranged so -// that all of the v1 fields remain at the same address. We are just -// adding more room to the front of the structure to hold the descriptors. -// -// The actual contents of this structure are defined in a 930 assembly -// file, converted to a binary image, and then written by the serialization -// program. The C definition of this structure just defines a dummy -// area for general USB descriptors and the descriptor tables (the root -// descriptor starts at xC00). At the bottom of the structure are the -// fields inherited from the v1 structure. - -#define MAX_SERIALNUMBER_LEN 12 -#define MAX_ASSEMBLYNUMBER_LEN 14 - -struct edge_manuf_descriptor { - - __u16 RootDescTable[0x10]; // C00 Root of descriptor tables (just a placeholder) - __u8 DescriptorArea[0x2E0]; // C20 Descriptors go here, up to 2E0h (just a placeholder) - - // Start of v1-compatible section - __u8 Length; // F00 Desc length for what follows, per USB (= C0h ) - __u8 DescType; // F01 Desc type, per USB (=DEVICE type) - __u8 DescVer; // F02 Desc version/format (currently 2) - __u8 NumRootDescEntries; // F03 # entries in RootDescTable - - __u8 RomSize; // F04 Size of ROM/E2PROM in K - __u8 RamSize; // F05 Size of external RAM in K - __u8 CpuRev; // F06 CPU revision level (chg only if s/w visible) - __u8 BoardRev; // F07 PCB revision level (chg only if s/w visible) - - __u8 NumPorts; // F08 Number of ports - __u8 DescDate[3]; // F09 MM/DD/YY when descriptor template was compiler, - // so host can track changes to USB-only descriptors. - - __u8 SerNumLength; // F0C USB string descriptor len - __u8 SerNumDescType; // F0D USB descriptor type (=STRING type) - __le16 SerialNumber[MAX_SERIALNUMBER_LEN]; // F0E "01-01-000100" Unicode Serial Number - - __u8 AssemblyNumLength; // F26 USB string descriptor len - __u8 AssemblyNumDescType; // F27 USB descriptor type (=STRING type) - __le16 AssemblyNumber[MAX_ASSEMBLYNUMBER_LEN]; // F28 "350-1000-01-A " assembly number - - __u8 OemAssyNumLength; // F44 USB string descriptor len - __u8 OemAssyNumDescType; // F45 USB descriptor type (=STRING type) - __le16 OemAssyNumber[MAX_ASSEMBLYNUMBER_LEN]; // F46 "xxxxxxxxxxxxxx" OEM assembly number - - __u8 ManufDateLength; // F62 USB string descriptor len - __u8 ManufDateDescType; // F63 USB descriptor type (=STRING type) - __le16 ManufDate[6]; // F64 "MMDDYY" manufacturing date - - __u8 Reserved3[0x4D]; // F70 -- unused, set to 0 -- - - __u8 UartType; // FBD Uart Type - __u8 IonPid; // FBE Product ID, == LSB of USB DevDesc.PID - // (Note: Edgeport/4s before 11/98 will have - // 00 here instead of 01) - __u8 IonConfig; // FBF Config byte for ION manufacturing use - // FBF end of structure, total len = 3C0h - -}; - - -#define MANUF_DESC_VER_1 1 // Original definition of MANUF_DESC -#define MANUF_DESC_VER_2 2 // Ver 2, starts at xC00h len 3C0h - - -// Uart Types -// Note: Since this field was added only recently, all Edgeport/4 units -// shipped before 11/98 will have 00 in this field. Therefore, -// both 00 and 01 values mean '654. -#define MANUF_UART_EXAR_654_EARLY 0 // Exar 16C654 in Edgeport/4s before 11/98 -#define MANUF_UART_EXAR_654 1 // Exar 16C654 -#define MANUF_UART_EXAR_2852 2 // Exar 16C2852 - -// -// Note: The CpuRev and BoardRev values do not conform to manufacturing -// revisions; they are to be incremented only when the CPU or hardware -// changes in a software-visible way, such that the 930 software or -// the host driver needs to handle the hardware differently. -// - -// Values of bottom 5 bits of CpuRev & BoardRev for -// Implementation 0 (ie, 930-based) -#define MANUF_CPU_REV_AD4 1 // 930 AD4, with EP1 Rx bug (needs RXSPM) -#define MANUF_CPU_REV_AD5 2 // 930 AD5, with above bug (supposedly) fixed -#define MANUF_CPU_80251 0x20 // Intel 80251 - - -#define MANUF_BOARD_REV_A 1 // Original version, == Manuf Rev A -#define MANUF_BOARD_REV_B 2 // Manuf Rev B, wakeup interrupt works -#define MANUF_BOARD_REV_C 3 // Manuf Rev C, 2/4 ports, rs232/rs422 -#define MANUF_BOARD_REV_GENERATION_2 0x20 // Second generaiton edgeport - - -// Values of bottom 5 bits of CpuRev & BoardRev for -// Implementation 1 (ie, 251+Netchip-based) -#define MANUF_CPU_REV_1 1 // C251TB Rev 1 (Need actual Intel rev here) - -#define MANUF_BOARD_REV_A 1 // First rev of 251+Netchip design - -#define MANUF_SERNUM_LENGTH sizeof(((struct edge_manuf_descriptor *)0)->SerialNumber) -#define MANUF_ASSYNUM_LENGTH sizeof(((struct edge_manuf_descriptor *)0)->AssemblyNumber) -#define MANUF_OEMASSYNUM_LENGTH sizeof(((struct edge_manuf_descriptor *)0)->OemAssyNumber) -#define MANUF_MANUFDATE_LENGTH sizeof(((struct edge_manuf_descriptor *)0)->ManufDate) - -#define MANUF_ION_CONFIG_DIAG_NO_LOOP 0x20 // As below but no ext loopback test -#define MANUF_ION_CONFIG_DIAG 0x40 // 930 based device: 1=Run h/w diags, 0=norm - // TIUMP Device : 1=IONSERIAL needs to run Final Test -#define MANUF_ION_CONFIG_MASTER 0x80 // 930 based device: 1=Master mode, 0=Normal - // TIUMP Device : 1=First device on a multi TIUMP Device - -// -// This structure describes parameters for the boot code, and -// is programmed along with new boot code. These are values -// which are specific to a given build of the boot code. It -// is exactly 64 bytes long and is fixed at address FF:xFC0 -// - FF:xFFF. Note that the 930-mandated UCONFIG bytes are -// included in this structure. -// -struct edge_boot_descriptor { - __u8 Length; // C0 Desc length, per USB (= 40h) - __u8 DescType; // C1 Desc type, per USB (= DEVICE type) - __u8 DescVer; // C2 Desc version/format - __u8 Reserved1; // C3 -- unused, set to 0 -- - - __le16 BootCodeLength; // C4 Boot code goes from FF:0000 to FF:(len-1) - // (LE format) - - __u8 MajorVersion; // C6 Firmware version: xx. - __u8 MinorVersion; // C7 yy. - __le16 BuildNumber; // C8 zzzz (LE format) - - __u16 EnumRootDescTable; // CA Root of ROM-based descriptor table - __u8 NumDescTypes; // CC Number of supported descriptor types - - __u8 Reserved4; // CD Fix Compiler Packing - - __le16 Capabilities; // CE-CF Capabilities flags (LE format) - __u8 Reserved2[0x28]; // D0 -- unused, set to 0 -- - __u8 UConfig0; // F8 930-defined CPU configuration byte 0 - __u8 UConfig1; // F9 930-defined CPU configuration byte 1 - __u8 Reserved3[6]; // FA -- unused, set to 0 -- - // FF end of structure, total len = 80 -}; - - -#define BOOT_DESC_VER_1 1 // Original definition of BOOT_PARAMS -#define BOOT_DESC_VER_2 2 // 2nd definition, descriptors not included in boot - - - // Capabilities flags - -#define BOOT_CAP_RESET_CMD 0x0001 // If set, boot correctly supports ION_RESET_DEVICE - - -/************************************************************************ - T I U M P D E F I N I T I O N S - ***********************************************************************/ - -// Chip definitions in I2C -#define UMP5152 0x52 -#define UMP3410 0x10 - - -//************************************************************************ -// TI I2C Format Definitions -//************************************************************************ -#define I2C_DESC_TYPE_INFO_BASIC 0x01 -#define I2C_DESC_TYPE_FIRMWARE_BASIC 0x02 -#define I2C_DESC_TYPE_DEVICE 0x03 -#define I2C_DESC_TYPE_CONFIG 0x04 -#define I2C_DESC_TYPE_STRING 0x05 -#define I2C_DESC_TYPE_FIRMWARE_AUTO 0x07 // for 3410 download -#define I2C_DESC_TYPE_CONFIG_KLUDGE 0x14 // for 3410 -#define I2C_DESC_TYPE_WATCHPORT_VERSION 0x15 // firmware version number for watchport -#define I2C_DESC_TYPE_WATCHPORT_CALIBRATION_DATA 0x16 // Watchport Calibration Data - -#define I2C_DESC_TYPE_FIRMWARE_BLANK 0xf2 - -// Special section defined by ION -#define I2C_DESC_TYPE_ION 0 // Not defined by TI - - -struct ti_i2c_desc { - __u8 Type; // Type of descriptor - __u16 Size; // Size of data only not including header - __u8 CheckSum; // Checksum (8 bit sum of data only) - __u8 Data[0]; // Data starts here -} __attribute__((packed)); - -// for 5152 devices only (type 2 record) -// for 3410 the version is stored in the WATCHPORT_FIRMWARE_VERSION descriptor -struct ti_i2c_firmware_rec { - __u8 Ver_Major; // Firmware Major version number - __u8 Ver_Minor; // Firmware Minor version number - __u8 Data[0]; // Download starts here -} __attribute__((packed)); - - -struct watchport_firmware_version { -// Added 2 bytes for version number - __u8 Version_Major; // Download Version (for Watchport) - __u8 Version_Minor; -} __attribute__((packed)); - - -// Structure of header of download image in fw_down.h -struct ti_i2c_image_header { - __le16 Length; - __u8 CheckSum; -} __attribute__((packed)); - -struct ti_basic_descriptor { - __u8 Power; // Self powered - // bit 7: 1 - power switching supported - // 0 - power switching not supported - // - // bit 0: 1 - self powered - // 0 - bus powered - // - // - __u16 HubVid; // VID HUB - __u16 HubPid; // PID HUB - __u16 DevPid; // PID Edgeport - __u8 HubTime; // Time for power on to power good - __u8 HubCurrent; // HUB Current = 100ma -} __attribute__((packed)); - - -// CPU / Board Rev Definitions -#define TI_CPU_REV_5052 2 // 5052 based edgeports -#define TI_CPU_REV_3410 3 // 3410 based edgeports - -#define TI_BOARD_REV_TI_EP 0 // Basic ti based edgeport -#define TI_BOARD_REV_COMPACT 1 // Compact board -#define TI_BOARD_REV_WATCHPORT 2 // Watchport - - -#define TI_GET_CPU_REVISION(x) (__u8)((((x)>>4)&0x0f)) -#define TI_GET_BOARD_REVISION(x) (__u8)(((x)&0x0f)) - -#define TI_I2C_SIZE_MASK 0x1f // 5 bits -#define TI_GET_I2C_SIZE(x) ((((x) & TI_I2C_SIZE_MASK)+1)*256) - -#define TI_MAX_I2C_SIZE (16 * 1024) - -#define TI_MANUF_VERSION_0 0 - -// IonConig2 flags -#define TI_CONFIG2_RS232 0x01 -#define TI_CONFIG2_RS422 0x02 -#define TI_CONFIG2_RS485 0x04 -#define TI_CONFIG2_SWITCHABLE 0x08 - -#define TI_CONFIG2_WATCHPORT 0x10 - - -struct edge_ti_manuf_descriptor { - __u8 IonConfig; // Config byte for ION manufacturing use - __u8 IonConfig2; // Expansion - __u8 Version; // Version - __u8 CpuRev_BoardRev; // CPU revision level (0xF0) and Board Rev Level (0x0F) - __u8 NumPorts; // Number of ports for this UMP - __u8 NumVirtualPorts; // Number of Virtual ports - __u8 HubConfig1; // Used to configure the Hub - __u8 HubConfig2; // Used to configure the Hub - __u8 TotalPorts; // Total Number of Com Ports for the entire device (All UMPs) - __u8 Reserved; // Reserved -} __attribute__((packed)); - - -#endif // if !defined(_USBVEND_H) diff --git a/ANDROID_3.4.5/drivers/usb/serial/ipaq.c b/ANDROID_3.4.5/drivers/usb/serial/ipaq.c deleted file mode 100644 index 10c02b8b..00000000 --- a/ANDROID_3.4.5/drivers/usb/serial/ipaq.c +++ /dev/null @@ -1,670 +0,0 @@ -/* - * USB Compaq iPAQ driver - * - * Copyright (C) 2001 - 2002 - * Ganesh Varadarajan <ganesh@veritas.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 <linux/kernel.h> -#include <linux/errno.h> -#include <linux/init.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/uaccess.h> -#include <linux/usb.h> -#include <linux/usb/serial.h> - -#define KP_RETRIES 100 - -/* - * Version Information - */ - -#define DRIVER_VERSION "v1.0" -#define DRIVER_AUTHOR "Ganesh Varadarajan <ganesh@veritas.com>" -#define DRIVER_DESC "USB PocketPC PDA driver" - -static __u16 product, vendor; -static bool debug; -static int connect_retries = KP_RETRIES; -static int initial_wait; - -/* Function prototypes for an ipaq */ -static int ipaq_open(struct tty_struct *tty, - struct usb_serial_port *port); -static int ipaq_calc_num_ports(struct usb_serial *serial); -static int ipaq_startup(struct usb_serial *serial); - -static struct usb_device_id ipaq_id_table [] = { - /* The first entry is a placeholder for the insmod-specified device */ - { USB_DEVICE(0x049F, 0x0003) }, - { USB_DEVICE(0x0104, 0x00BE) }, /* Socket USB Sync */ - { USB_DEVICE(0x03F0, 0x1016) }, /* HP USB Sync */ - { USB_DEVICE(0x03F0, 0x1116) }, /* HP USB Sync 1611 */ - { USB_DEVICE(0x03F0, 0x1216) }, /* HP USB Sync 1612 */ - { USB_DEVICE(0x03F0, 0x2016) }, /* HP USB Sync 1620 */ - { USB_DEVICE(0x03F0, 0x2116) }, /* HP USB Sync 1621 */ - { USB_DEVICE(0x03F0, 0x2216) }, /* HP USB Sync 1622 */ - { USB_DEVICE(0x03F0, 0x3016) }, /* HP USB Sync 1630 */ - { USB_DEVICE(0x03F0, 0x3116) }, /* HP USB Sync 1631 */ - { USB_DEVICE(0x03F0, 0x3216) }, /* HP USB Sync 1632 */ - { USB_DEVICE(0x03F0, 0x4016) }, /* HP USB Sync 1640 */ - { USB_DEVICE(0x03F0, 0x4116) }, /* HP USB Sync 1641 */ - { USB_DEVICE(0x03F0, 0x4216) }, /* HP USB Sync 1642 */ - { USB_DEVICE(0x03F0, 0x5016) }, /* HP USB Sync 1650 */ - { USB_DEVICE(0x03F0, 0x5116) }, /* HP USB Sync 1651 */ - { USB_DEVICE(0x03F0, 0x5216) }, /* HP USB Sync 1652 */ - { USB_DEVICE(0x0409, 0x00D5) }, /* NEC USB Sync */ - { USB_DEVICE(0x0409, 0x00D6) }, /* NEC USB Sync */ - { USB_DEVICE(0x0409, 0x00D7) }, /* NEC USB Sync */ - { USB_DEVICE(0x0409, 0x8024) }, /* NEC USB Sync */ - { USB_DEVICE(0x0409, 0x8025) }, /* NEC USB Sync */ - { USB_DEVICE(0x043E, 0x9C01) }, /* LGE USB Sync */ - { USB_DEVICE(0x045E, 0x00CE) }, /* Microsoft USB Sync */ - { USB_DEVICE(0x045E, 0x0400) }, /* Windows Powered Pocket PC 2002 */ - { USB_DEVICE(0x045E, 0x0401) }, /* Windows Powered Pocket PC 2002 */ - { USB_DEVICE(0x045E, 0x0402) }, /* Windows Powered Pocket PC 2002 */ - { USB_DEVICE(0x045E, 0x0403) }, /* Windows Powered Pocket PC 2002 */ - { USB_DEVICE(0x045E, 0x0404) }, /* Windows Powered Pocket PC 2002 */ - { USB_DEVICE(0x045E, 0x0405) }, /* Windows Powered Pocket PC 2002 */ - { USB_DEVICE(0x045E, 0x0406) }, /* Windows Powered Pocket PC 2002 */ - { USB_DEVICE(0x045E, 0x0407) }, /* Windows Powered Pocket PC 2002 */ - { USB_DEVICE(0x045E, 0x0408) }, /* Windows Powered Pocket PC 2002 */ - { USB_DEVICE(0x045E, 0x0409) }, /* Windows Powered Pocket PC 2002 */ - { USB_DEVICE(0x045E, 0x040A) }, /* Windows Powered Pocket PC 2002 */ - { USB_DEVICE(0x045E, 0x040B) }, /* Windows Powered Pocket PC 2002 */ - { USB_DEVICE(0x045E, 0x040C) }, /* Windows Powered Pocket PC 2002 */ - { USB_DEVICE(0x045E, 0x040D) }, /* Windows Powered Pocket PC 2002 */ - { USB_DEVICE(0x045E, 0x040E) }, /* Windows Powered Pocket PC 2002 */ - { USB_DEVICE(0x045E, 0x040F) }, /* Windows Powered Pocket PC 2002 */ - { USB_DEVICE(0x045E, 0x0410) }, /* Windows Powered Pocket PC 2002 */ - { USB_DEVICE(0x045E, 0x0411) }, /* Windows Powered Pocket PC 2002 */ - { USB_DEVICE(0x045E, 0x0412) }, /* Windows Powered Pocket PC 2002 */ - { USB_DEVICE(0x045E, 0x0413) }, /* Windows Powered Pocket PC 2002 */ - { USB_DEVICE(0x045E, 0x0414) }, /* Windows Powered Pocket PC 2002 */ - { USB_DEVICE(0x045E, 0x0415) }, /* Windows Powered Pocket PC 2002 */ - { USB_DEVICE(0x045E, 0x0416) }, /* Windows Powered Pocket PC 2002 */ - { USB_DEVICE(0x045E, 0x0417) }, /* Windows Powered Pocket PC 2002 */ - { USB_DEVICE(0x045E, 0x0432) }, /* Windows Powered Pocket PC 2003 */ - { USB_DEVICE(0x045E, 0x0433) }, /* Windows Powered Pocket PC 2003 */ - { USB_DEVICE(0x045E, 0x0434) }, /* Windows Powered Pocket PC 2003 */ - { USB_DEVICE(0x045E, 0x0435) }, /* Windows Powered Pocket PC 2003 */ - { USB_DEVICE(0x045E, 0x0436) }, /* Windows Powered Pocket PC 2003 */ - { USB_DEVICE(0x045E, 0x0437) }, /* Windows Powered Pocket PC 2003 */ - { USB_DEVICE(0x045E, 0x0438) }, /* Windows Powered Pocket PC 2003 */ - { USB_DEVICE(0x045E, 0x0439) }, /* Windows Powered Pocket PC 2003 */ - { USB_DEVICE(0x045E, 0x043A) }, /* Windows Powered Pocket PC 2003 */ - { USB_DEVICE(0x045E, 0x043B) }, /* Windows Powered Pocket PC 2003 */ - { USB_DEVICE(0x045E, 0x043C) }, /* Windows Powered Pocket PC 2003 */ - { USB_DEVICE(0x045E, 0x043D) }, /* Windows Powered Pocket PC 2003 */ - { USB_DEVICE(0x045E, 0x043E) }, /* Windows Powered Pocket PC 2003 */ - { USB_DEVICE(0x045E, 0x043F) }, /* Windows Powered Pocket PC 2003 */ - { USB_DEVICE(0x045E, 0x0440) }, /* Windows Powered Pocket PC 2003 */ - { USB_DEVICE(0x045E, 0x0441) }, /* Windows Powered Pocket PC 2003 */ - { USB_DEVICE(0x045E, 0x0442) }, /* Windows Powered Pocket PC 2003 */ - { USB_DEVICE(0x045E, 0x0443) }, /* Windows Powered Pocket PC 2003 */ - { USB_DEVICE(0x045E, 0x0444) }, /* Windows Powered Pocket PC 2003 */ - { USB_DEVICE(0x045E, 0x0445) }, /* Windows Powered Pocket PC 2003 */ - { USB_DEVICE(0x045E, 0x0446) }, /* Windows Powered Pocket PC 2003 */ - { USB_DEVICE(0x045E, 0x0447) }, /* Windows Powered Pocket PC 2003 */ - { USB_DEVICE(0x045E, 0x0448) }, /* Windows Powered Pocket PC 2003 */ - { USB_DEVICE(0x045E, 0x0449) }, /* Windows Powered Pocket PC 2003 */ - { USB_DEVICE(0x045E, 0x044A) }, /* Windows Powered Pocket PC 2003 */ - { USB_DEVICE(0x045E, 0x044B) }, /* Windows Powered Pocket PC 2003 */ - { USB_DEVICE(0x045E, 0x044C) }, /* Windows Powered Pocket PC 2003 */ - { USB_DEVICE(0x045E, 0x044D) }, /* Windows Powered Pocket PC 2003 */ - { USB_DEVICE(0x045E, 0x044E) }, /* Windows Powered Pocket PC 2003 */ - { USB_DEVICE(0x045E, 0x044F) }, /* Windows Powered Pocket PC 2003 */ - { USB_DEVICE(0x045E, 0x0450) }, /* Windows Powered Pocket PC 2003 */ - { USB_DEVICE(0x045E, 0x0451) }, /* Windows Powered Pocket PC 2003 */ - { USB_DEVICE(0x045E, 0x0452) }, /* Windows Powered Pocket PC 2003 */ - { USB_DEVICE(0x045E, 0x0453) }, /* Windows Powered Pocket PC 2003 */ - { USB_DEVICE(0x045E, 0x0454) }, /* Windows Powered Pocket PC 2003 */ - { USB_DEVICE(0x045E, 0x0455) }, /* Windows Powered Pocket PC 2003 */ - { USB_DEVICE(0x045E, 0x0456) }, /* Windows Powered Pocket PC 2003 */ - { USB_DEVICE(0x045E, 0x0457) }, /* Windows Powered Pocket PC 2003 */ - { USB_DEVICE(0x045E, 0x0458) }, /* Windows Powered Pocket PC 2003 */ - { USB_DEVICE(0x045E, 0x0459) }, /* Windows Powered Pocket PC 2003 */ - { USB_DEVICE(0x045E, 0x045A) }, /* Windows Powered Pocket PC 2003 */ - { USB_DEVICE(0x045E, 0x045B) }, /* Windows Powered Pocket PC 2003 */ - { USB_DEVICE(0x045E, 0x045C) }, /* Windows Powered Pocket PC 2003 */ - { USB_DEVICE(0x045E, 0x045D) }, /* Windows Powered Pocket PC 2003 */ - { USB_DEVICE(0x045E, 0x045E) }, /* Windows Powered Pocket PC 2003 */ - { USB_DEVICE(0x045E, 0x045F) }, /* Windows Powered Pocket PC 2003 */ - { USB_DEVICE(0x045E, 0x0460) }, /* Windows Powered Pocket PC 2003 */ - { USB_DEVICE(0x045E, 0x0461) }, /* Windows Powered Pocket PC 2003 */ - { USB_DEVICE(0x045E, 0x0462) }, /* Windows Powered Pocket PC 2003 */ - { USB_DEVICE(0x045E, 0x0463) }, /* Windows Powered Pocket PC 2003 */ - { USB_DEVICE(0x045E, 0x0464) }, /* Windows Powered Pocket PC 2003 */ - { USB_DEVICE(0x045E, 0x0465) }, /* Windows Powered Pocket PC 2003 */ - { USB_DEVICE(0x045E, 0x0466) }, /* Windows Powered Pocket PC 2003 */ - { USB_DEVICE(0x045E, 0x0467) }, /* Windows Powered Pocket PC 2003 */ - { USB_DEVICE(0x045E, 0x0468) }, /* Windows Powered Pocket PC 2003 */ - { USB_DEVICE(0x045E, 0x0469) }, /* Windows Powered Pocket PC 2003 */ - { USB_DEVICE(0x045E, 0x046A) }, /* Windows Powered Pocket PC 2003 */ - { USB_DEVICE(0x045E, 0x046B) }, /* Windows Powered Pocket PC 2003 */ - { USB_DEVICE(0x045E, 0x046C) }, /* Windows Powered Pocket PC 2003 */ - { USB_DEVICE(0x045E, 0x046D) }, /* Windows Powered Pocket PC 2003 */ - { USB_DEVICE(0x045E, 0x046E) }, /* Windows Powered Pocket PC 2003 */ - { USB_DEVICE(0x045E, 0x046F) }, /* Windows Powered Pocket PC 2003 */ - { USB_DEVICE(0x045E, 0x0470) }, /* Windows Powered Pocket PC 2003 */ - { USB_DEVICE(0x045E, 0x0471) }, /* Windows Powered Pocket PC 2003 */ - { USB_DEVICE(0x045E, 0x0472) }, /* Windows Powered Pocket PC 2003 */ - { USB_DEVICE(0x045E, 0x0473) }, /* Windows Powered Pocket PC 2003 */ - { USB_DEVICE(0x045E, 0x0474) }, /* Windows Powered Pocket PC 2003 */ - { USB_DEVICE(0x045E, 0x0475) }, /* Windows Powered Pocket PC 2003 */ - { USB_DEVICE(0x045E, 0x0476) }, /* Windows Powered Pocket PC 2003 */ - { USB_DEVICE(0x045E, 0x0477) }, /* Windows Powered Pocket PC 2003 */ - { USB_DEVICE(0x045E, 0x0478) }, /* Windows Powered Pocket PC 2003 */ - { USB_DEVICE(0x045E, 0x0479) }, /* Windows Powered Pocket PC 2003 */ - { USB_DEVICE(0x045E, 0x047A) }, /* Windows Powered Pocket PC 2003 */ - { USB_DEVICE(0x045E, 0x047B) }, /* Windows Powered Pocket PC 2003 */ - { USB_DEVICE(0x045E, 0x04C8) }, /* Windows Powered Smartphone 2002 */ - { USB_DEVICE(0x045E, 0x04C9) }, /* Windows Powered Smartphone 2002 */ - { USB_DEVICE(0x045E, 0x04CA) }, /* Windows Powered Smartphone 2002 */ - { USB_DEVICE(0x045E, 0x04CB) }, /* Windows Powered Smartphone 2002 */ - { USB_DEVICE(0x045E, 0x04CC) }, /* Windows Powered Smartphone 2002 */ - { USB_DEVICE(0x045E, 0x04CD) }, /* Windows Powered Smartphone 2002 */ - { USB_DEVICE(0x045E, 0x04CE) }, /* Windows Powered Smartphone 2002 */ - { USB_DEVICE(0x045E, 0x04D7) }, /* Windows Powered Smartphone 2003 */ - { USB_DEVICE(0x045E, 0x04D8) }, /* Windows Powered Smartphone 2003 */ - { USB_DEVICE(0x045E, 0x04D9) }, /* Windows Powered Smartphone 2003 */ - { USB_DEVICE(0x045E, 0x04DA) }, /* Windows Powered Smartphone 2003 */ - { USB_DEVICE(0x045E, 0x04DB) }, /* Windows Powered Smartphone 2003 */ - { USB_DEVICE(0x045E, 0x04DC) }, /* Windows Powered Smartphone 2003 */ - { USB_DEVICE(0x045E, 0x04DD) }, /* Windows Powered Smartphone 2003 */ - { USB_DEVICE(0x045E, 0x04DE) }, /* Windows Powered Smartphone 2003 */ - { USB_DEVICE(0x045E, 0x04DF) }, /* Windows Powered Smartphone 2003 */ - { USB_DEVICE(0x045E, 0x04E0) }, /* Windows Powered Smartphone 2003 */ - { USB_DEVICE(0x045E, 0x04E1) }, /* Windows Powered Smartphone 2003 */ - { USB_DEVICE(0x045E, 0x04E2) }, /* Windows Powered Smartphone 2003 */ - { USB_DEVICE(0x045E, 0x04E3) }, /* Windows Powered Smartphone 2003 */ - { USB_DEVICE(0x045E, 0x04E4) }, /* Windows Powered Smartphone 2003 */ - { USB_DEVICE(0x045E, 0x04E5) }, /* Windows Powered Smartphone 2003 */ - { USB_DEVICE(0x045E, 0x04E6) }, /* Windows Powered Smartphone 2003 */ - { USB_DEVICE(0x045E, 0x04E7) }, /* Windows Powered Smartphone 2003 */ - { USB_DEVICE(0x045E, 0x04E8) }, /* Windows Powered Smartphone 2003 */ - { USB_DEVICE(0x045E, 0x04E9) }, /* Windows Powered Smartphone 2003 */ - { USB_DEVICE(0x045E, 0x04EA) }, /* Windows Powered Smartphone 2003 */ - { USB_DEVICE(0x049F, 0x0003) }, /* Compaq iPAQ USB Sync */ - { USB_DEVICE(0x049F, 0x0032) }, /* Compaq iPAQ USB Sync */ - { USB_DEVICE(0x04A4, 0x0014) }, /* Hitachi USB Sync */ - { USB_DEVICE(0x04AD, 0x0301) }, /* USB Sync 0301 */ - { USB_DEVICE(0x04AD, 0x0302) }, /* USB Sync 0302 */ - { USB_DEVICE(0x04AD, 0x0303) }, /* USB Sync 0303 */ - { USB_DEVICE(0x04AD, 0x0306) }, /* GPS Pocket PC USB Sync */ - { USB_DEVICE(0x04B7, 0x0531) }, /* MyGuide 7000 XL USB Sync */ - { USB_DEVICE(0x04C5, 0x1058) }, /* FUJITSU USB Sync */ - { USB_DEVICE(0x04C5, 0x1079) }, /* FUJITSU USB Sync */ - { USB_DEVICE(0x04DA, 0x2500) }, /* Panasonic USB Sync */ - { USB_DEVICE(0x04DD, 0x9102) }, /* SHARP WS003SH USB Modem */ - { USB_DEVICE(0x04DD, 0x9121) }, /* SHARP WS004SH USB Modem */ - { USB_DEVICE(0x04DD, 0x9123) }, /* SHARP WS007SH USB Modem */ - { USB_DEVICE(0x04DD, 0x9151) }, /* SHARP S01SH USB Modem */ - { USB_DEVICE(0x04DD, 0x91AC) }, /* SHARP WS011SH USB Modem */ - { USB_DEVICE(0x04E8, 0x5F00) }, /* Samsung NEXiO USB Sync */ - { USB_DEVICE(0x04E8, 0x5F01) }, /* Samsung NEXiO USB Sync */ - { USB_DEVICE(0x04E8, 0x5F02) }, /* Samsung NEXiO USB Sync */ - { USB_DEVICE(0x04E8, 0x5F03) }, /* Samsung NEXiO USB Sync */ - { USB_DEVICE(0x04E8, 0x5F04) }, /* Samsung NEXiO USB Sync */ - { USB_DEVICE(0x04E8, 0x6611) }, /* Samsung MITs USB Sync */ - { USB_DEVICE(0x04E8, 0x6613) }, /* Samsung MITs USB Sync */ - { USB_DEVICE(0x04E8, 0x6615) }, /* Samsung MITs USB Sync */ - { USB_DEVICE(0x04E8, 0x6617) }, /* Samsung MITs USB Sync */ - { USB_DEVICE(0x04E8, 0x6619) }, /* Samsung MITs USB Sync */ - { USB_DEVICE(0x04E8, 0x661B) }, /* Samsung MITs USB Sync */ - { USB_DEVICE(0x04E8, 0x662E) }, /* Samsung MITs USB Sync */ - { USB_DEVICE(0x04E8, 0x6630) }, /* Samsung MITs USB Sync */ - { USB_DEVICE(0x04E8, 0x6632) }, /* Samsung MITs USB Sync */ - { USB_DEVICE(0x04f1, 0x3011) }, /* JVC USB Sync */ - { USB_DEVICE(0x04F1, 0x3012) }, /* JVC USB Sync */ - { USB_DEVICE(0x0502, 0x1631) }, /* c10 Series */ - { USB_DEVICE(0x0502, 0x1632) }, /* c20 Series */ - { USB_DEVICE(0x0502, 0x16E1) }, /* Acer n10 Handheld USB Sync */ - { USB_DEVICE(0x0502, 0x16E2) }, /* Acer n20 Handheld USB Sync */ - { USB_DEVICE(0x0502, 0x16E3) }, /* Acer n30 Handheld USB Sync */ - { USB_DEVICE(0x0536, 0x01A0) }, /* HHP PDT */ - { USB_DEVICE(0x0543, 0x0ED9) }, /* ViewSonic Color Pocket PC V35 */ - { USB_DEVICE(0x0543, 0x1527) }, /* ViewSonic Color Pocket PC V36 */ - { USB_DEVICE(0x0543, 0x1529) }, /* ViewSonic Color Pocket PC V37 */ - { USB_DEVICE(0x0543, 0x152B) }, /* ViewSonic Color Pocket PC V38 */ - { USB_DEVICE(0x0543, 0x152E) }, /* ViewSonic Pocket PC */ - { USB_DEVICE(0x0543, 0x1921) }, /* ViewSonic Communicator Pocket PC */ - { USB_DEVICE(0x0543, 0x1922) }, /* ViewSonic Smartphone */ - { USB_DEVICE(0x0543, 0x1923) }, /* ViewSonic Pocket PC V30 */ - { USB_DEVICE(0x05E0, 0x2000) }, /* Symbol USB Sync */ - { USB_DEVICE(0x05E0, 0x2001) }, /* Symbol USB Sync 0x2001 */ - { USB_DEVICE(0x05E0, 0x2002) }, /* Symbol USB Sync 0x2002 */ - { USB_DEVICE(0x05E0, 0x2003) }, /* Symbol USB Sync 0x2003 */ - { USB_DEVICE(0x05E0, 0x2004) }, /* Symbol USB Sync 0x2004 */ - { USB_DEVICE(0x05E0, 0x2005) }, /* Symbol USB Sync 0x2005 */ - { USB_DEVICE(0x05E0, 0x2006) }, /* Symbol USB Sync 0x2006 */ - { USB_DEVICE(0x05E0, 0x2007) }, /* Symbol USB Sync 0x2007 */ - { USB_DEVICE(0x05E0, 0x2008) }, /* Symbol USB Sync 0x2008 */ - { USB_DEVICE(0x05E0, 0x2009) }, /* Symbol USB Sync 0x2009 */ - { USB_DEVICE(0x05E0, 0x200A) }, /* Symbol USB Sync 0x200A */ - { USB_DEVICE(0x067E, 0x1001) }, /* Intermec Mobile Computer */ - { USB_DEVICE(0x07CF, 0x2001) }, /* CASIO USB Sync 2001 */ - { USB_DEVICE(0x07CF, 0x2002) }, /* CASIO USB Sync 2002 */ - { USB_DEVICE(0x07CF, 0x2003) }, /* CASIO USB Sync 2003 */ - { USB_DEVICE(0x0930, 0x0700) }, /* TOSHIBA USB Sync 0700 */ - { USB_DEVICE(0x0930, 0x0705) }, /* TOSHIBA Pocket PC e310 */ - { USB_DEVICE(0x0930, 0x0706) }, /* TOSHIBA Pocket PC e740 */ - { USB_DEVICE(0x0930, 0x0707) }, /* TOSHIBA Pocket PC e330 Series */ - { USB_DEVICE(0x0930, 0x0708) }, /* TOSHIBA Pocket PC e350 Series */ - { USB_DEVICE(0x0930, 0x0709) }, /* TOSHIBA Pocket PC e750 Series */ - { USB_DEVICE(0x0930, 0x070A) }, /* TOSHIBA Pocket PC e400 Series */ - { USB_DEVICE(0x0930, 0x070B) }, /* TOSHIBA Pocket PC e800 Series */ - { USB_DEVICE(0x094B, 0x0001) }, /* Linkup Systems USB Sync */ - { USB_DEVICE(0x0960, 0x0065) }, /* BCOM USB Sync 0065 */ - { USB_DEVICE(0x0960, 0x0066) }, /* BCOM USB Sync 0066 */ - { USB_DEVICE(0x0960, 0x0067) }, /* BCOM USB Sync 0067 */ - { USB_DEVICE(0x0961, 0x0010) }, /* Portatec USB Sync */ - { USB_DEVICE(0x099E, 0x0052) }, /* Trimble GeoExplorer */ - { USB_DEVICE(0x099E, 0x4000) }, /* TDS Data Collector */ - { USB_DEVICE(0x0B05, 0x4200) }, /* ASUS USB Sync */ - { USB_DEVICE(0x0B05, 0x4201) }, /* ASUS USB Sync */ - { USB_DEVICE(0x0B05, 0x4202) }, /* ASUS USB Sync */ - { USB_DEVICE(0x0B05, 0x420F) }, /* ASUS USB Sync */ - { USB_DEVICE(0x0B05, 0x9200) }, /* ASUS USB Sync */ - { USB_DEVICE(0x0B05, 0x9202) }, /* ASUS USB Sync */ - { USB_DEVICE(0x0BB4, 0x00CE) }, /* HTC USB Sync */ - { USB_DEVICE(0x0BB4, 0x00CF) }, /* HTC USB Modem */ - { USB_DEVICE(0x0BB4, 0x0A01) }, /* PocketPC USB Sync */ - { USB_DEVICE(0x0BB4, 0x0A02) }, /* PocketPC USB Sync */ - { USB_DEVICE(0x0BB4, 0x0A03) }, /* PocketPC USB Sync */ - { USB_DEVICE(0x0BB4, 0x0A04) }, /* PocketPC USB Sync */ - { USB_DEVICE(0x0BB4, 0x0A05) }, /* PocketPC USB Sync */ - { USB_DEVICE(0x0BB4, 0x0A06) }, /* PocketPC USB Sync */ - { USB_DEVICE(0x0BB4, 0x0A07) }, /* PocketPC USB Sync */ - { USB_DEVICE(0x0BB4, 0x0A08) }, /* PocketPC USB Sync */ - { USB_DEVICE(0x0BB4, 0x0A09) }, /* PocketPC USB Sync */ - { USB_DEVICE(0x0BB4, 0x0A0A) }, /* PocketPC USB Sync */ - { USB_DEVICE(0x0BB4, 0x0A0B) }, /* PocketPC USB Sync */ - { USB_DEVICE(0x0BB4, 0x0A0C) }, /* PocketPC USB Sync */ - { USB_DEVICE(0x0BB4, 0x0A0D) }, /* PocketPC USB Sync */ - { USB_DEVICE(0x0BB4, 0x0A0E) }, /* PocketPC USB Sync */ - { USB_DEVICE(0x0BB4, 0x0A0F) }, /* PocketPC USB Sync */ - { USB_DEVICE(0x0BB4, 0x0A10) }, /* PocketPC USB Sync */ - { USB_DEVICE(0x0BB4, 0x0A11) }, /* PocketPC USB Sync */ - { USB_DEVICE(0x0BB4, 0x0A12) }, /* PocketPC USB Sync */ - { USB_DEVICE(0x0BB4, 0x0A13) }, /* PocketPC USB Sync */ - { USB_DEVICE(0x0BB4, 0x0A14) }, /* PocketPC USB Sync */ - { USB_DEVICE(0x0BB4, 0x0A15) }, /* PocketPC USB Sync */ - { USB_DEVICE(0x0BB4, 0x0A16) }, /* PocketPC USB Sync */ - { USB_DEVICE(0x0BB4, 0x0A17) }, /* PocketPC USB Sync */ - { USB_DEVICE(0x0BB4, 0x0A18) }, /* PocketPC USB Sync */ - { USB_DEVICE(0x0BB4, 0x0A19) }, /* PocketPC USB Sync */ - { USB_DEVICE(0x0BB4, 0x0A1A) }, /* PocketPC USB Sync */ - { USB_DEVICE(0x0BB4, 0x0A1B) }, /* PocketPC USB Sync */ - { USB_DEVICE(0x0BB4, 0x0A1C) }, /* PocketPC USB Sync */ - { USB_DEVICE(0x0BB4, 0x0A1D) }, /* PocketPC USB Sync */ - { USB_DEVICE(0x0BB4, 0x0A1E) }, /* PocketPC USB Sync */ - { USB_DEVICE(0x0BB4, 0x0A1F) }, /* PocketPC USB Sync */ - { USB_DEVICE(0x0BB4, 0x0A20) }, /* PocketPC USB Sync */ - { USB_DEVICE(0x0BB4, 0x0A21) }, /* PocketPC USB Sync */ - { USB_DEVICE(0x0BB4, 0x0A22) }, /* PocketPC USB Sync */ - { USB_DEVICE(0x0BB4, 0x0A23) }, /* PocketPC USB Sync */ - { USB_DEVICE(0x0BB4, 0x0A24) }, /* PocketPC USB Sync */ - { USB_DEVICE(0x0BB4, 0x0A25) }, /* PocketPC USB Sync */ - { USB_DEVICE(0x0BB4, 0x0A26) }, /* PocketPC USB Sync */ - { USB_DEVICE(0x0BB4, 0x0A27) }, /* PocketPC USB Sync */ - { USB_DEVICE(0x0BB4, 0x0A28) }, /* PocketPC USB Sync */ - { USB_DEVICE(0x0BB4, 0x0A29) }, /* PocketPC USB Sync */ - { USB_DEVICE(0x0BB4, 0x0A2A) }, /* PocketPC USB Sync */ - { USB_DEVICE(0x0BB4, 0x0A2B) }, /* PocketPC USB Sync */ - { USB_DEVICE(0x0BB4, 0x0A2C) }, /* PocketPC USB Sync */ - { USB_DEVICE(0x0BB4, 0x0A2D) }, /* PocketPC USB Sync */ - { USB_DEVICE(0x0BB4, 0x0A2E) }, /* PocketPC USB Sync */ - { USB_DEVICE(0x0BB4, 0x0A2F) }, /* PocketPC USB Sync */ - { USB_DEVICE(0x0BB4, 0x0A30) }, /* PocketPC USB Sync */ - { USB_DEVICE(0x0BB4, 0x0A31) }, /* PocketPC USB Sync */ - { USB_DEVICE(0x0BB4, 0x0A32) }, /* PocketPC USB Sync */ - { USB_DEVICE(0x0BB4, 0x0A33) }, /* PocketPC USB Sync */ - { USB_DEVICE(0x0BB4, 0x0A34) }, /* PocketPC USB Sync */ - { USB_DEVICE(0x0BB4, 0x0A35) }, /* PocketPC USB Sync */ - { USB_DEVICE(0x0BB4, 0x0A36) }, /* PocketPC USB Sync */ - { USB_DEVICE(0x0BB4, 0x0A37) }, /* PocketPC USB Sync */ - { USB_DEVICE(0x0BB4, 0x0A38) }, /* PocketPC USB Sync */ - { USB_DEVICE(0x0BB4, 0x0A39) }, /* PocketPC USB Sync */ - { USB_DEVICE(0x0BB4, 0x0A3A) }, /* PocketPC USB Sync */ - { USB_DEVICE(0x0BB4, 0x0A3B) }, /* PocketPC USB Sync */ - { USB_DEVICE(0x0BB4, 0x0A3C) }, /* PocketPC USB Sync */ - { USB_DEVICE(0x0BB4, 0x0A3D) }, /* PocketPC USB Sync */ - { USB_DEVICE(0x0BB4, 0x0A3E) }, /* PocketPC USB Sync */ - { USB_DEVICE(0x0BB4, 0x0A3F) }, /* PocketPC USB Sync */ - { USB_DEVICE(0x0BB4, 0x0A40) }, /* PocketPC USB Sync */ - { USB_DEVICE(0x0BB4, 0x0A41) }, /* PocketPC USB Sync */ - { USB_DEVICE(0x0BB4, 0x0A42) }, /* PocketPC USB Sync */ - { USB_DEVICE(0x0BB4, 0x0A43) }, /* PocketPC USB Sync */ - { USB_DEVICE(0x0BB4, 0x0A44) }, /* PocketPC USB Sync */ - { USB_DEVICE(0x0BB4, 0x0A45) }, /* PocketPC USB Sync */ - { USB_DEVICE(0x0BB4, 0x0A46) }, /* PocketPC USB Sync */ - { USB_DEVICE(0x0BB4, 0x0A47) }, /* PocketPC USB Sync */ - { USB_DEVICE(0x0BB4, 0x0A48) }, /* PocketPC USB Sync */ - { USB_DEVICE(0x0BB4, 0x0A49) }, /* PocketPC USB Sync */ - { USB_DEVICE(0x0BB4, 0x0A4A) }, /* PocketPC USB Sync */ - { USB_DEVICE(0x0BB4, 0x0A4B) }, /* PocketPC USB Sync */ - { USB_DEVICE(0x0BB4, 0x0A4C) }, /* PocketPC USB Sync */ - { USB_DEVICE(0x0BB4, 0x0A4D) }, /* PocketPC USB Sync */ - { USB_DEVICE(0x0BB4, 0x0A4E) }, /* PocketPC USB Sync */ - { USB_DEVICE(0x0BB4, 0x0A4F) }, /* PocketPC USB Sync */ - { USB_DEVICE(0x0BB4, 0x0A50) }, /* HTC SmartPhone USB Sync */ - { USB_DEVICE(0x0BB4, 0x0A51) }, /* SmartPhone USB Sync */ - { USB_DEVICE(0x0BB4, 0x0A52) }, /* SmartPhone USB Sync */ - { USB_DEVICE(0x0BB4, 0x0A53) }, /* SmartPhone USB Sync */ - { USB_DEVICE(0x0BB4, 0x0A54) }, /* SmartPhone USB Sync */ - { USB_DEVICE(0x0BB4, 0x0A55) }, /* SmartPhone USB Sync */ - { USB_DEVICE(0x0BB4, 0x0A56) }, /* SmartPhone USB Sync */ - { USB_DEVICE(0x0BB4, 0x0A57) }, /* SmartPhone USB Sync */ - { USB_DEVICE(0x0BB4, 0x0A58) }, /* SmartPhone USB Sync */ - { USB_DEVICE(0x0BB4, 0x0A59) }, /* SmartPhone USB Sync */ - { USB_DEVICE(0x0BB4, 0x0A5A) }, /* SmartPhone USB Sync */ - { USB_DEVICE(0x0BB4, 0x0A5B) }, /* SmartPhone USB Sync */ - { USB_DEVICE(0x0BB4, 0x0A5C) }, /* SmartPhone USB Sync */ - { USB_DEVICE(0x0BB4, 0x0A5D) }, /* SmartPhone USB Sync */ - { USB_DEVICE(0x0BB4, 0x0A5E) }, /* SmartPhone USB Sync */ - { USB_DEVICE(0x0BB4, 0x0A5F) }, /* SmartPhone USB Sync */ - { USB_DEVICE(0x0BB4, 0x0A60) }, /* SmartPhone USB Sync */ - { USB_DEVICE(0x0BB4, 0x0A61) }, /* SmartPhone USB Sync */ - { USB_DEVICE(0x0BB4, 0x0A62) }, /* SmartPhone USB Sync */ - { USB_DEVICE(0x0BB4, 0x0A63) }, /* SmartPhone USB Sync */ - { USB_DEVICE(0x0BB4, 0x0A64) }, /* SmartPhone USB Sync */ - { USB_DEVICE(0x0BB4, 0x0A65) }, /* SmartPhone USB Sync */ - { USB_DEVICE(0x0BB4, 0x0A66) }, /* SmartPhone USB Sync */ - { USB_DEVICE(0x0BB4, 0x0A67) }, /* SmartPhone USB Sync */ - { USB_DEVICE(0x0BB4, 0x0A68) }, /* SmartPhone USB Sync */ - { USB_DEVICE(0x0BB4, 0x0A69) }, /* SmartPhone USB Sync */ - { USB_DEVICE(0x0BB4, 0x0A6A) }, /* SmartPhone USB Sync */ - { USB_DEVICE(0x0BB4, 0x0A6B) }, /* SmartPhone USB Sync */ - { USB_DEVICE(0x0BB4, 0x0A6C) }, /* SmartPhone USB Sync */ - { USB_DEVICE(0x0BB4, 0x0A6D) }, /* SmartPhone USB Sync */ - { USB_DEVICE(0x0BB4, 0x0A6E) }, /* SmartPhone USB Sync */ - { USB_DEVICE(0x0BB4, 0x0A6F) }, /* SmartPhone USB Sync */ - { USB_DEVICE(0x0BB4, 0x0A70) }, /* SmartPhone USB Sync */ - { USB_DEVICE(0x0BB4, 0x0A71) }, /* SmartPhone USB Sync */ - { USB_DEVICE(0x0BB4, 0x0A72) }, /* SmartPhone USB Sync */ - { USB_DEVICE(0x0BB4, 0x0A73) }, /* SmartPhone USB Sync */ - { USB_DEVICE(0x0BB4, 0x0A74) }, /* SmartPhone USB Sync */ - { USB_DEVICE(0x0BB4, 0x0A75) }, /* SmartPhone USB Sync */ - { USB_DEVICE(0x0BB4, 0x0A76) }, /* SmartPhone USB Sync */ - { USB_DEVICE(0x0BB4, 0x0A77) }, /* SmartPhone USB Sync */ - { USB_DEVICE(0x0BB4, 0x0A78) }, /* SmartPhone USB Sync */ - { USB_DEVICE(0x0BB4, 0x0A79) }, /* SmartPhone USB Sync */ - { USB_DEVICE(0x0BB4, 0x0A7A) }, /* SmartPhone USB Sync */ - { USB_DEVICE(0x0BB4, 0x0A7B) }, /* SmartPhone USB Sync */ - { USB_DEVICE(0x0BB4, 0x0A7C) }, /* SmartPhone USB Sync */ - { USB_DEVICE(0x0BB4, 0x0A7D) }, /* SmartPhone USB Sync */ - { USB_DEVICE(0x0BB4, 0x0A7E) }, /* SmartPhone USB Sync */ - { USB_DEVICE(0x0BB4, 0x0A7F) }, /* SmartPhone USB Sync */ - { USB_DEVICE(0x0BB4, 0x0A80) }, /* SmartPhone USB Sync */ - { USB_DEVICE(0x0BB4, 0x0A81) }, /* SmartPhone USB Sync */ - { USB_DEVICE(0x0BB4, 0x0A82) }, /* SmartPhone USB Sync */ - { USB_DEVICE(0x0BB4, 0x0A83) }, /* SmartPhone USB Sync */ - { USB_DEVICE(0x0BB4, 0x0A84) }, /* SmartPhone USB Sync */ - { USB_DEVICE(0x0BB4, 0x0A85) }, /* SmartPhone USB Sync */ - { USB_DEVICE(0x0BB4, 0x0A86) }, /* SmartPhone USB Sync */ - { USB_DEVICE(0x0BB4, 0x0A87) }, /* SmartPhone USB Sync */ - { USB_DEVICE(0x0BB4, 0x0A88) }, /* SmartPhone USB Sync */ - { USB_DEVICE(0x0BB4, 0x0A89) }, /* SmartPhone USB Sync */ - { USB_DEVICE(0x0BB4, 0x0A8A) }, /* SmartPhone USB Sync */ - { USB_DEVICE(0x0BB4, 0x0A8B) }, /* SmartPhone USB Sync */ - { USB_DEVICE(0x0BB4, 0x0A8C) }, /* SmartPhone USB Sync */ - { USB_DEVICE(0x0BB4, 0x0A8D) }, /* SmartPhone USB Sync */ - { USB_DEVICE(0x0BB4, 0x0A8E) }, /* SmartPhone USB Sync */ - { USB_DEVICE(0x0BB4, 0x0A8F) }, /* SmartPhone USB Sync */ - { USB_DEVICE(0x0BB4, 0x0A90) }, /* SmartPhone USB Sync */ - { USB_DEVICE(0x0BB4, 0x0A91) }, /* SmartPhone USB Sync */ - { USB_DEVICE(0x0BB4, 0x0A92) }, /* SmartPhone USB Sync */ - { USB_DEVICE(0x0BB4, 0x0A93) }, /* SmartPhone USB Sync */ - { USB_DEVICE(0x0BB4, 0x0A94) }, /* SmartPhone USB Sync */ - { USB_DEVICE(0x0BB4, 0x0A95) }, /* SmartPhone USB Sync */ - { USB_DEVICE(0x0BB4, 0x0A96) }, /* SmartPhone USB Sync */ - { USB_DEVICE(0x0BB4, 0x0A97) }, /* SmartPhone USB Sync */ - { USB_DEVICE(0x0BB4, 0x0A98) }, /* SmartPhone USB Sync */ - { USB_DEVICE(0x0BB4, 0x0A99) }, /* SmartPhone USB Sync */ - { USB_DEVICE(0x0BB4, 0x0A9A) }, /* SmartPhone USB Sync */ - { USB_DEVICE(0x0BB4, 0x0A9B) }, /* SmartPhone USB Sync */ - { USB_DEVICE(0x0BB4, 0x0A9C) }, /* SmartPhone USB Sync */ - { USB_DEVICE(0x0BB4, 0x0A9D) }, /* SmartPhone USB Sync */ - { USB_DEVICE(0x0BB4, 0x0A9E) }, /* SmartPhone USB Sync */ - { USB_DEVICE(0x0BB4, 0x0A9F) }, /* SmartPhone USB Sync */ - { USB_DEVICE(0x0BB4, 0x0BCE) }, /* "High Tech Computer Corp" */ - { USB_DEVICE(0x0BF8, 0x1001) }, /* Fujitsu Siemens Computers USB Sync */ - { USB_DEVICE(0x0C44, 0x03A2) }, /* Motorola iDEN Smartphone */ - { USB_DEVICE(0x0C8E, 0x6000) }, /* Cesscom Luxian Series */ - { USB_DEVICE(0x0CAD, 0x9001) }, /* Motorola PowerPad Pocket PC Device */ - { USB_DEVICE(0x0F4E, 0x0200) }, /* Freedom Scientific USB Sync */ - { USB_DEVICE(0x0F98, 0x0201) }, /* Cyberbank USB Sync */ - { USB_DEVICE(0x0FB8, 0x3001) }, /* Wistron USB Sync */ - { USB_DEVICE(0x0FB8, 0x3002) }, /* Wistron USB Sync */ - { USB_DEVICE(0x0FB8, 0x3003) }, /* Wistron USB Sync */ - { USB_DEVICE(0x0FB8, 0x4001) }, /* Wistron USB Sync */ - { USB_DEVICE(0x1066, 0x00CE) }, /* E-TEN USB Sync */ - { USB_DEVICE(0x1066, 0x0300) }, /* E-TEN P3XX Pocket PC */ - { USB_DEVICE(0x1066, 0x0500) }, /* E-TEN P5XX Pocket PC */ - { USB_DEVICE(0x1066, 0x0600) }, /* E-TEN P6XX Pocket PC */ - { USB_DEVICE(0x1066, 0x0700) }, /* E-TEN P7XX Pocket PC */ - { USB_DEVICE(0x1114, 0x0001) }, /* Psion Teklogix Sync 753x */ - { USB_DEVICE(0x1114, 0x0004) }, /* Psion Teklogix Sync netBookPro */ - { USB_DEVICE(0x1114, 0x0006) }, /* Psion Teklogix Sync 7525 */ - { USB_DEVICE(0x1182, 0x1388) }, /* VES USB Sync */ - { USB_DEVICE(0x11D9, 0x1002) }, /* Rugged Pocket PC 2003 */ - { USB_DEVICE(0x11D9, 0x1003) }, /* Rugged Pocket PC 2003 */ - { USB_DEVICE(0x1231, 0xCE01) }, /* USB Sync 03 */ - { USB_DEVICE(0x1231, 0xCE02) }, /* USB Sync 03 */ - { USB_DEVICE(0x1690, 0x0601) }, /* Askey USB Sync */ - { USB_DEVICE(0x22B8, 0x4204) }, /* Motorola MPx200 Smartphone */ - { USB_DEVICE(0x22B8, 0x4214) }, /* Motorola MPc GSM */ - { USB_DEVICE(0x22B8, 0x4224) }, /* Motorola MPx220 Smartphone */ - { USB_DEVICE(0x22B8, 0x4234) }, /* Motorola MPc CDMA */ - { USB_DEVICE(0x22B8, 0x4244) }, /* Motorola MPx100 Smartphone */ - { USB_DEVICE(0x3340, 0x011C) }, /* Mio DigiWalker PPC StrongARM */ - { USB_DEVICE(0x3340, 0x0326) }, /* Mio DigiWalker 338 */ - { USB_DEVICE(0x3340, 0x0426) }, /* Mio DigiWalker 338 */ - { USB_DEVICE(0x3340, 0x043A) }, /* Mio DigiWalker USB Sync */ - { USB_DEVICE(0x3340, 0x051C) }, /* MiTAC USB Sync 528 */ - { USB_DEVICE(0x3340, 0x053A) }, /* Mio DigiWalker SmartPhone USB Sync */ - { USB_DEVICE(0x3340, 0x071C) }, /* MiTAC USB Sync */ - { USB_DEVICE(0x3340, 0x0B1C) }, /* Generic PPC StrongARM */ - { USB_DEVICE(0x3340, 0x0E3A) }, /* Generic PPC USB Sync */ - { USB_DEVICE(0x3340, 0x0F1C) }, /* Itautec USB Sync */ - { USB_DEVICE(0x3340, 0x0F3A) }, /* Generic SmartPhone USB Sync */ - { USB_DEVICE(0x3340, 0x1326) }, /* Itautec USB Sync */ - { USB_DEVICE(0x3340, 0x191C) }, /* YAKUMO USB Sync */ - { USB_DEVICE(0x3340, 0x2326) }, /* Vobis USB Sync */ - { USB_DEVICE(0x3340, 0x3326) }, /* MEDION Winodws Moble USB Sync */ - { USB_DEVICE(0x3708, 0x20CE) }, /* Legend USB Sync */ - { USB_DEVICE(0x3708, 0x21CE) }, /* Lenovo USB Sync */ - { USB_DEVICE(0x4113, 0x0210) }, /* Mobile Media Technology USB Sync */ - { USB_DEVICE(0x4113, 0x0211) }, /* Mobile Media Technology USB Sync */ - { USB_DEVICE(0x4113, 0x0400) }, /* Mobile Media Technology USB Sync */ - { USB_DEVICE(0x4113, 0x0410) }, /* Mobile Media Technology USB Sync */ - { USB_DEVICE(0x413C, 0x4001) }, /* Dell Axim USB Sync */ - { USB_DEVICE(0x413C, 0x4002) }, /* Dell Axim USB Sync */ - { USB_DEVICE(0x413C, 0x4003) }, /* Dell Axim USB Sync */ - { USB_DEVICE(0x413C, 0x4004) }, /* Dell Axim USB Sync */ - { USB_DEVICE(0x413C, 0x4005) }, /* Dell Axim USB Sync */ - { USB_DEVICE(0x413C, 0x4006) }, /* Dell Axim USB Sync */ - { USB_DEVICE(0x413C, 0x4007) }, /* Dell Axim USB Sync */ - { USB_DEVICE(0x413C, 0x4008) }, /* Dell Axim USB Sync */ - { USB_DEVICE(0x413C, 0x4009) }, /* Dell Axim USB Sync */ - { USB_DEVICE(0x4505, 0x0010) }, /* Smartphone */ - { USB_DEVICE(0x5E04, 0xCE00) }, /* SAGEM Wireless Assistant */ - { } /* Terminating entry */ -}; - -MODULE_DEVICE_TABLE(usb, ipaq_id_table); - -static struct usb_driver ipaq_driver = { - .name = "ipaq", - .probe = usb_serial_probe, - .disconnect = usb_serial_disconnect, - .id_table = ipaq_id_table, -}; - - -/* All of the device info needed for the Compaq iPAQ */ -static struct usb_serial_driver ipaq_device = { - .driver = { - .owner = THIS_MODULE, - .name = "ipaq", - }, - .description = "PocketPC PDA", - .id_table = ipaq_id_table, - .bulk_in_size = 256, - .bulk_out_size = 256, - .open = ipaq_open, - .attach = ipaq_startup, - .calc_num_ports = ipaq_calc_num_ports, -}; - -static struct usb_serial_driver * const serial_drivers[] = { - &ipaq_device, NULL -}; - -static int ipaq_open(struct tty_struct *tty, - struct usb_serial_port *port) -{ - struct usb_serial *serial = port->serial; - int result = 0; - int retries = connect_retries; - - dbg("%s - port %d", __func__, port->number); - - msleep(1000*initial_wait); - - /* - * Send out control message observed in win98 sniffs. Not sure what - * it does, but from empirical observations, it seems that the device - * will start the chat sequence once one of these messages gets - * through. Since this has a reasonably high failure rate, we retry - * several times. - */ - while (retries--) { - result = usb_control_msg(serial->dev, - usb_sndctrlpipe(serial->dev, 0), 0x22, 0x21, - 0x1, 0, NULL, 0, 100); - if (!result) - break; - - msleep(1000); - } - if (!retries && result) { - dev_err(&port->dev, "%s - failed doing control urb, error %d\n", - __func__, result); - return result; - } - - return usb_serial_generic_open(tty, port); -} - -static int ipaq_calc_num_ports(struct usb_serial *serial) -{ - /* - * some devices have 3 endpoints, the 3rd of which - * must be ignored as it would make the core - * create a second port which oopses when used - */ - int ipaq_num_ports = 1; - - dbg("%s - numberofendpoints: %d", __FUNCTION__, - (int)serial->interface->cur_altsetting->desc.bNumEndpoints); - - /* - * a few devices have 4 endpoints, seemingly Yakuma devices, - * and we need the second pair, so let them have 2 ports - * - * TODO: can we drop port 1 ? - */ - if (serial->interface->cur_altsetting->desc.bNumEndpoints > 3) { - ipaq_num_ports = 2; - } - - return ipaq_num_ports; -} - - -static int ipaq_startup(struct usb_serial *serial) -{ - dbg("%s", __func__); - - /* Some of the devices in ipaq_id_table[] are composite, and we - * shouldn't bind to all the interfaces. This test will rule out - * some obviously invalid possibilities. - */ - if (serial->num_bulk_in < serial->num_ports || - serial->num_bulk_out < serial->num_ports) - return -ENODEV; - - if (serial->dev->actconfig->desc.bConfigurationValue != 1) { - /* - * FIXME: HP iPaq rx3715, possibly others, have 1 config that - * is labeled as 2 - */ - - dev_err(&serial->dev->dev, "active config #%d != 1 ??\n", - serial->dev->actconfig->desc.bConfigurationValue); - return -ENODEV; - } - - dbg("%s - iPAQ module configured for %d ports", - __FUNCTION__, serial->num_ports); - - return usb_reset_configuration(serial->dev); -} - -static int __init ipaq_init(void) -{ - int retval; - - if (vendor) { - ipaq_id_table[0].idVendor = vendor; - ipaq_id_table[0].idProduct = product; - } - - retval = usb_serial_register_drivers(&ipaq_driver, serial_drivers); - if (retval == 0) - printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ":" - DRIVER_DESC "\n"); - return retval; -} - -static void __exit ipaq_exit(void) -{ - usb_serial_deregister_drivers(&ipaq_driver, serial_drivers); -} - - -module_init(ipaq_init); -module_exit(ipaq_exit); - -MODULE_AUTHOR(DRIVER_AUTHOR); -MODULE_DESCRIPTION(DRIVER_DESC); -MODULE_LICENSE("GPL"); - -module_param(debug, bool, S_IRUGO | S_IWUSR); -MODULE_PARM_DESC(debug, "Debug enabled or not"); - -module_param(vendor, ushort, 0); -MODULE_PARM_DESC(vendor, "User specified USB idVendor"); - -module_param(product, ushort, 0); -MODULE_PARM_DESC(product, "User specified USB idProduct"); - -module_param(connect_retries, int, S_IRUGO|S_IWUSR); -MODULE_PARM_DESC(connect_retries, - "Maximum number of connect retries (one second each)"); - -module_param(initial_wait, int, S_IRUGO|S_IWUSR); -MODULE_PARM_DESC(initial_wait, - "Time to wait before attempting a connection (in seconds)"); diff --git a/ANDROID_3.4.5/drivers/usb/serial/ipw.c b/ANDROID_3.4.5/drivers/usb/serial/ipw.c deleted file mode 100644 index 76a06406..00000000 --- a/ANDROID_3.4.5/drivers/usb/serial/ipw.c +++ /dev/null @@ -1,344 +0,0 @@ -/* - * IPWireless 3G UMTS TDD Modem driver (USB connected) - * - * Copyright (C) 2004 Roelf Diedericks <roelfd@inet.co.za> - * Copyright (C) 2004 Greg Kroah-Hartman <greg@kroah.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. - * - * All information about the device was acquired using SnoopyPro - * on MSFT's O/S, and examing the MSFT drivers' debug output - * (insanely left _on_ in the enduser version) - * - * It was written out of frustration with the IPWireless USB modem - * supplied by Axity3G/Sentech South Africa not supporting - * Linux whatsoever. - * - * Nobody provided any proprietary information that was not already - * available for this device. - * - * The modem adheres to the "3GPP TS 27.007 AT command set for 3G - * User Equipment (UE)" standard, available from - * http://www.3gpp.org/ftp/Specs/html-info/27007.htm - * - * The code was only tested the IPWireless handheld modem distributed - * in South Africa by Sentech. - * - * It may work for Woosh Inc in .nz too, as it appears they use the - * same kit. - * - * There is still some work to be done in terms of handling - * DCD, DTR, RTS, CTS which are currently faked. - * It's good enough for PPP at this point. It's based off all kinds of - * code found in usb/serial and usb/class - */ - -#include <linux/kernel.h> -#include <linux/errno.h> -#include <linux/init.h> -#include <linux/slab.h> -#include <linux/tty.h> -#include <linux/tty_flip.h> -#include <linux/module.h> -#include <linux/spinlock.h> -#include <linux/usb.h> -#include <linux/usb/serial.h> -#include <linux/uaccess.h> -#include "usb-wwan.h" - -/* - * Version Information - */ -#define DRIVER_VERSION "v0.4" -#define DRIVER_AUTHOR "Roelf Diedericks" -#define DRIVER_DESC "IPWireless tty driver" - -#define IPW_TTY_MAJOR 240 /* real device node major id, experimental range */ -#define IPW_TTY_MINORS 256 /* we support 256 devices, dunno why, it'd be insane :) */ - -#define USB_IPW_MAGIC 0x6d02 /* magic number for ipw struct */ - - -/* Message sizes */ -#define EVENT_BUFFER_SIZE 0xFF -#define CHAR2INT16(c1, c0) (((u32)((c1) & 0xff) << 8) + (u32)((c0) & 0xff)) - -/* vendor/product pairs that are known work with this driver*/ -#define IPW_VID 0x0bc3 -#define IPW_PID 0x0001 - - -/* Vendor commands: */ - -/* baud rates */ -enum { - ipw_sio_b256000 = 0x000e, - ipw_sio_b128000 = 0x001d, - ipw_sio_b115200 = 0x0020, - ipw_sio_b57600 = 0x0040, - ipw_sio_b56000 = 0x0042, - ipw_sio_b38400 = 0x0060, - ipw_sio_b19200 = 0x00c0, - ipw_sio_b14400 = 0x0100, - ipw_sio_b9600 = 0x0180, - ipw_sio_b4800 = 0x0300, - ipw_sio_b2400 = 0x0600, - ipw_sio_b1200 = 0x0c00, - ipw_sio_b600 = 0x1800 -}; - -/* data bits */ -#define ipw_dtb_7 0x700 -#define ipw_dtb_8 0x810 /* ok so the define is misleading, I know, but forces 8,n,1 */ - /* I mean, is there a point to any other setting these days? :) */ - -/* usb control request types : */ -#define IPW_SIO_RXCTL 0x00 /* control bulk rx channel transmissions, value=1/0 (on/off) */ -#define IPW_SIO_SET_BAUD 0x01 /* set baud, value=requested ipw_sio_bxxxx */ -#define IPW_SIO_SET_LINE 0x03 /* set databits, parity. value=ipw_dtb_x */ -#define IPW_SIO_SET_PIN 0x03 /* set/clear dtr/rts value=ipw_pin_xxx */ -#define IPW_SIO_POLL 0x08 /* get serial port status byte, call with value=0 */ -#define IPW_SIO_INIT 0x11 /* initializes ? value=0 (appears as first thing todo on open) */ -#define IPW_SIO_PURGE 0x12 /* purge all transmissions?, call with value=numchar_to_purge */ -#define IPW_SIO_HANDFLOW 0x13 /* set xon/xoff limits value=0, and a buffer of 0x10 bytes */ -#define IPW_SIO_SETCHARS 0x13 /* set the flowcontrol special chars, value=0, buf=6 bytes, */ - /* last 2 bytes contain flowcontrol chars e.g. 00 00 00 00 11 13 */ - -/* values used for request IPW_SIO_SET_PIN */ -#define IPW_PIN_SETDTR 0x101 -#define IPW_PIN_SETRTS 0x202 -#define IPW_PIN_CLRDTR 0x100 -#define IPW_PIN_CLRRTS 0x200 /* unconfirmed */ - -/* values used for request IPW_SIO_RXCTL */ -#define IPW_RXBULK_ON 1 -#define IPW_RXBULK_OFF 0 - -/* various 16 byte hardcoded transferbuffers used by flow control */ -#define IPW_BYTES_FLOWINIT { 0x01, 0, 0, 0, 0x40, 0, 0, 0, \ - 0, 0, 0, 0, 0, 0, 0, 0 } - -/* Interpretation of modem status lines */ -/* These need sorting out by individually connecting pins and checking - * results. FIXME! - * When data is being sent we see 0x30 in the lower byte; this must - * contain DSR and CTS ... - */ -#define IPW_DSR ((1<<4) | (1<<5)) -#define IPW_CTS ((1<<5) | (1<<4)) - -#define IPW_WANTS_TO_SEND 0x30 - -static const struct usb_device_id usb_ipw_ids[] = { - { USB_DEVICE(IPW_VID, IPW_PID) }, - { }, -}; - -MODULE_DEVICE_TABLE(usb, usb_ipw_ids); - -static struct usb_driver usb_ipw_driver = { - .name = "ipwtty", - .probe = usb_serial_probe, - .disconnect = usb_serial_disconnect, - .id_table = usb_ipw_ids, -}; - -static bool debug; - -static int ipw_open(struct tty_struct *tty, struct usb_serial_port *port) -{ - struct usb_device *dev = port->serial->dev; - u8 buf_flow_static[16] = IPW_BYTES_FLOWINIT; - u8 *buf_flow_init; - int result; - - dbg("%s", __func__); - - buf_flow_init = kmemdup(buf_flow_static, 16, GFP_KERNEL); - if (!buf_flow_init) - return -ENOMEM; - - /* --1: Tell the modem to initialize (we think) From sniffs this is - * always the first thing that gets sent to the modem during - * opening of the device */ - dbg("%s: Sending SIO_INIT (we guess)", __func__); - result = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), - IPW_SIO_INIT, - USB_TYPE_VENDOR | USB_RECIP_INTERFACE | USB_DIR_OUT, - 0, - 0, /* index */ - NULL, - 0, - 100000); - if (result < 0) - dev_err(&port->dev, - "Init of modem failed (error = %d)\n", result); - - /* reset the bulk pipes */ - usb_clear_halt(dev, - usb_rcvbulkpipe(dev, port->bulk_in_endpointAddress)); - usb_clear_halt(dev, - usb_sndbulkpipe(dev, port->bulk_out_endpointAddress)); - - /*--2: Start reading from the device */ - dbg("%s: setting up bulk read callback", __func__); - usb_wwan_open(tty, port); - - /*--3: Tell the modem to open the floodgates on the rx bulk channel */ - dbg("%s:asking modem for RxRead (RXBULK_ON)", __func__); - result = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), - IPW_SIO_RXCTL, - USB_TYPE_VENDOR | USB_RECIP_INTERFACE | USB_DIR_OUT, - IPW_RXBULK_ON, - 0, /* index */ - NULL, - 0, - 100000); - if (result < 0) - dev_err(&port->dev, - "Enabling bulk RxRead failed (error = %d)\n", result); - - /*--4: setup the initial flowcontrol */ - dbg("%s:setting init flowcontrol (%s)", __func__, buf_flow_init); - result = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), - IPW_SIO_HANDFLOW, - USB_TYPE_VENDOR | USB_RECIP_INTERFACE | USB_DIR_OUT, - 0, - 0, - buf_flow_init, - 0x10, - 200000); - if (result < 0) - dev_err(&port->dev, - "initial flowcontrol failed (error = %d)\n", result); - - kfree(buf_flow_init); - return 0; -} - -/* fake probe - only to allocate data structures */ -static int ipw_probe(struct usb_serial *serial, const struct usb_device_id *id) -{ - struct usb_wwan_intf_private *data; - - data = kzalloc(sizeof(struct usb_wwan_intf_private), GFP_KERNEL); - if (!data) - return -ENOMEM; - - spin_lock_init(&data->susp_lock); - usb_set_serial_data(serial, data); - return 0; -} - -static void ipw_release(struct usb_serial *serial) -{ - struct usb_wwan_intf_private *data = usb_get_serial_data(serial); - - usb_wwan_release(serial); - usb_set_serial_data(serial, NULL); - kfree(data); -} - -static void ipw_dtr_rts(struct usb_serial_port *port, int on) -{ - struct usb_device *dev = port->serial->dev; - int result; - - dbg("%s: on = %d", __func__, on); - - result = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), - IPW_SIO_SET_PIN, - USB_TYPE_VENDOR | USB_RECIP_INTERFACE | USB_DIR_OUT, - on ? IPW_PIN_SETDTR : IPW_PIN_CLRDTR, - 0, - NULL, - 0, - 200000); - if (result < 0) - dev_err(&port->dev, "setting dtr failed (error = %d)\n", - result); - - result = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), - IPW_SIO_SET_PIN, USB_TYPE_VENDOR | - USB_RECIP_INTERFACE | USB_DIR_OUT, - on ? IPW_PIN_SETRTS : IPW_PIN_CLRRTS, - 0, - NULL, - 0, - 200000); - if (result < 0) - dev_err(&port->dev, "setting rts failed (error = %d)\n", - result); -} - -static void ipw_close(struct usb_serial_port *port) -{ - struct usb_device *dev = port->serial->dev; - int result; - - /*--3: purge */ - dbg("%s:sending purge", __func__); - result = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), - IPW_SIO_PURGE, USB_TYPE_VENDOR | - USB_RECIP_INTERFACE | USB_DIR_OUT, - 0x03, - 0, - NULL, - 0, - 200000); - if (result < 0) - dev_err(&port->dev, "purge failed (error = %d)\n", result); - - - /* send RXBULK_off (tell modem to stop transmitting bulk data on - rx chan) */ - result = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), - IPW_SIO_RXCTL, - USB_TYPE_VENDOR | USB_RECIP_INTERFACE | USB_DIR_OUT, - IPW_RXBULK_OFF, - 0, /* index */ - NULL, - 0, - 100000); - - if (result < 0) - dev_err(&port->dev, - "Disabling bulk RxRead failed (error = %d)\n", result); - - usb_wwan_close(port); -} - -static struct usb_serial_driver ipw_device = { - .driver = { - .owner = THIS_MODULE, - .name = "ipw", - }, - .description = "IPWireless converter", - .id_table = usb_ipw_ids, - .num_ports = 1, - .disconnect = usb_wwan_disconnect, - .open = ipw_open, - .close = ipw_close, - .probe = ipw_probe, - .attach = usb_wwan_startup, - .release = ipw_release, - .dtr_rts = ipw_dtr_rts, - .write = usb_wwan_write, -}; - -static struct usb_serial_driver * const serial_drivers[] = { - &ipw_device, NULL -}; - -module_usb_serial_driver(usb_ipw_driver, serial_drivers); - -/* Module information */ -MODULE_AUTHOR(DRIVER_AUTHOR); -MODULE_DESCRIPTION(DRIVER_DESC); -MODULE_LICENSE("GPL"); - -module_param(debug, bool, S_IRUGO | S_IWUSR); -MODULE_PARM_DESC(debug, "Debug enabled or not"); diff --git a/ANDROID_3.4.5/drivers/usb/serial/ir-usb.c b/ANDROID_3.4.5/drivers/usb/serial/ir-usb.c deleted file mode 100644 index 84965cd6..00000000 --- a/ANDROID_3.4.5/drivers/usb/serial/ir-usb.c +++ /dev/null @@ -1,476 +0,0 @@ -/* - * USB IR Dongle driver - * - * Copyright (C) 2001-2002 Greg Kroah-Hartman (greg@kroah.com) - * Copyright (C) 2002 Gary Brubaker (xavyer@ix.netcom.com) - * Copyright (C) 2010 Johan Hovold (jhovold@gmail.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. - * - * This driver allows a USB IrDA device to be used as a "dumb" serial device. - * This can be useful if you do not have access to a full IrDA stack on the - * other side of the connection. If you do have an IrDA stack on both devices, - * please use the usb-irda driver, as it contains the proper error checking and - * other goodness of a full IrDA stack. - * - * Portions of this driver were taken from drivers/net/irda/irda-usb.c, which - * was written by Roman Weissgaerber <weissg@vienna.at>, Dag Brattli - * <dag@brattli.net>, and Jean Tourrilhes <jt@hpl.hp.com> - * - * See Documentation/usb/usb-serial.txt for more information on using this - * driver - */ - -#include <linux/kernel.h> -#include <linux/errno.h> -#include <linux/init.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/uaccess.h> -#include <linux/usb.h> -#include <linux/usb/serial.h> -#include <linux/usb/irda.h> - -/* - * Version Information - */ -#define DRIVER_VERSION "v0.5" -#define DRIVER_AUTHOR "Greg Kroah-Hartman <greg@kroah.com>, Johan Hovold <jhovold@gmail.com>" -#define DRIVER_DESC "USB IR Dongle driver" - -static bool debug; - -/* if overridden by the user, then use their value for the size of the read and - * write urbs */ -static int buffer_size; - -/* if overridden by the user, then use the specified number of XBOFs */ -static int xbof = -1; - -static int ir_startup (struct usb_serial *serial); -static int ir_open(struct tty_struct *tty, struct usb_serial_port *port); -static int ir_prepare_write_buffer(struct usb_serial_port *port, - void *dest, size_t size); -static void ir_process_read_urb(struct urb *urb); -static void ir_set_termios(struct tty_struct *tty, - struct usb_serial_port *port, struct ktermios *old_termios); - -/* Not that this lot means you can only have one per system */ -static u8 ir_baud; -static u8 ir_xbof; -static u8 ir_add_bof; - -static const struct usb_device_id ir_id_table[] = { - { USB_DEVICE(0x050f, 0x0180) }, /* KC Technology, KC-180 */ - { USB_DEVICE(0x08e9, 0x0100) }, /* XTNDAccess */ - { USB_DEVICE(0x09c4, 0x0011) }, /* ACTiSys ACT-IR2000U */ - { USB_INTERFACE_INFO(USB_CLASS_APP_SPEC, USB_SUBCLASS_IRDA, 0) }, - { } /* Terminating entry */ -}; - -MODULE_DEVICE_TABLE(usb, ir_id_table); - -static struct usb_driver ir_driver = { - .name = "ir-usb", - .probe = usb_serial_probe, - .disconnect = usb_serial_disconnect, - .id_table = ir_id_table, -}; - -static struct usb_serial_driver ir_device = { - .driver = { - .owner = THIS_MODULE, - .name = "ir-usb", - }, - .description = "IR Dongle", - .id_table = ir_id_table, - .num_ports = 1, - .set_termios = ir_set_termios, - .attach = ir_startup, - .open = ir_open, - .prepare_write_buffer = ir_prepare_write_buffer, - .process_read_urb = ir_process_read_urb, -}; - -static struct usb_serial_driver * const serial_drivers[] = { - &ir_device, NULL -}; - -static inline void irda_usb_dump_class_desc(struct usb_irda_cs_descriptor *desc) -{ - dbg("bLength=%x", desc->bLength); - dbg("bDescriptorType=%x", desc->bDescriptorType); - dbg("bcdSpecRevision=%x", __le16_to_cpu(desc->bcdSpecRevision)); - dbg("bmDataSize=%x", desc->bmDataSize); - dbg("bmWindowSize=%x", desc->bmWindowSize); - dbg("bmMinTurnaroundTime=%d", desc->bmMinTurnaroundTime); - dbg("wBaudRate=%x", __le16_to_cpu(desc->wBaudRate)); - dbg("bmAdditionalBOFs=%x", desc->bmAdditionalBOFs); - dbg("bIrdaRateSniff=%x", desc->bIrdaRateSniff); - dbg("bMaxUnicastList=%x", desc->bMaxUnicastList); -} - -/*------------------------------------------------------------------*/ -/* - * Function irda_usb_find_class_desc(dev, ifnum) - * - * Returns instance of IrDA class descriptor, or NULL if not found - * - * The class descriptor is some extra info that IrDA USB devices will - * offer to us, describing their IrDA characteristics. We will use that in - * irda_usb_init_qos() - * - * Based on the same function in drivers/net/irda/irda-usb.c - */ -static struct usb_irda_cs_descriptor * -irda_usb_find_class_desc(struct usb_device *dev, unsigned int ifnum) -{ - struct usb_irda_cs_descriptor *desc; - int ret; - - desc = kzalloc(sizeof(*desc), GFP_KERNEL); - if (!desc) - return NULL; - - ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), - USB_REQ_CS_IRDA_GET_CLASS_DESC, - USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE, - 0, ifnum, desc, sizeof(*desc), 1000); - - dbg("%s - ret=%d", __func__, ret); - if (ret < sizeof(*desc)) { - dbg("%s - class descriptor read %s (%d)", - __func__, - (ret < 0) ? "failed" : "too short", - ret); - goto error; - } - if (desc->bDescriptorType != USB_DT_CS_IRDA) { - dbg("%s - bad class descriptor type", __func__); - goto error; - } - - irda_usb_dump_class_desc(desc); - return desc; - -error: - kfree(desc); - return NULL; -} - -static u8 ir_xbof_change(u8 xbof) -{ - u8 result; - - /* reference irda-usb.c */ - switch (xbof) { - case 48: - result = 0x10; - break; - case 28: - case 24: - result = 0x20; - break; - default: - case 12: - result = 0x30; - break; - case 5: - case 6: - result = 0x40; - break; - case 3: - result = 0x50; - break; - case 2: - result = 0x60; - break; - case 1: - result = 0x70; - break; - case 0: - result = 0x80; - break; - } - - return(result); -} - -static int ir_startup(struct usb_serial *serial) -{ - struct usb_irda_cs_descriptor *irda_desc; - - irda_desc = irda_usb_find_class_desc(serial->dev, 0); - if (!irda_desc) { - dev_err(&serial->dev->dev, - "IRDA class descriptor not found, device not bound\n"); - return -ENODEV; - } - - dbg("%s - Baud rates supported:%s%s%s%s%s%s%s%s%s", - __func__, - (irda_desc->wBaudRate & USB_IRDA_BR_2400) ? " 2400" : "", - (irda_desc->wBaudRate & USB_IRDA_BR_9600) ? " 9600" : "", - (irda_desc->wBaudRate & USB_IRDA_BR_19200) ? " 19200" : "", - (irda_desc->wBaudRate & USB_IRDA_BR_38400) ? " 38400" : "", - (irda_desc->wBaudRate & USB_IRDA_BR_57600) ? " 57600" : "", - (irda_desc->wBaudRate & USB_IRDA_BR_115200) ? " 115200" : "", - (irda_desc->wBaudRate & USB_IRDA_BR_576000) ? " 576000" : "", - (irda_desc->wBaudRate & USB_IRDA_BR_1152000) ? " 1152000" : "", - (irda_desc->wBaudRate & USB_IRDA_BR_4000000) ? " 4000000" : ""); - - switch (irda_desc->bmAdditionalBOFs) { - case USB_IRDA_AB_48: - ir_add_bof = 48; - break; - case USB_IRDA_AB_24: - ir_add_bof = 24; - break; - case USB_IRDA_AB_12: - ir_add_bof = 12; - break; - case USB_IRDA_AB_6: - ir_add_bof = 6; - break; - case USB_IRDA_AB_3: - ir_add_bof = 3; - break; - case USB_IRDA_AB_2: - ir_add_bof = 2; - break; - case USB_IRDA_AB_1: - ir_add_bof = 1; - break; - case USB_IRDA_AB_0: - ir_add_bof = 0; - break; - default: - break; - } - - kfree(irda_desc); - - return 0; -} - -static int ir_open(struct tty_struct *tty, struct usb_serial_port *port) -{ - int i; - - dbg("%s - port %d", __func__, port->number); - - for (i = 0; i < ARRAY_SIZE(port->write_urbs); ++i) - port->write_urbs[i]->transfer_flags = URB_ZERO_PACKET; - - /* Start reading from the device */ - return usb_serial_generic_open(tty, port); -} - -static int ir_prepare_write_buffer(struct usb_serial_port *port, - void *dest, size_t size) -{ - unsigned char *buf = dest; - int count; - - /* - * The first byte of the packet we send to the device contains an - * inbound header which indicates an additional number of BOFs and - * a baud rate change. - * - * See section 5.4.2.2 of the USB IrDA spec. - */ - *buf = ir_xbof | ir_baud; - - count = kfifo_out_locked(&port->write_fifo, buf + 1, size - 1, - &port->lock); - return count + 1; -} - -static void ir_process_read_urb(struct urb *urb) -{ - struct usb_serial_port *port = urb->context; - unsigned char *data = urb->transfer_buffer; - struct tty_struct *tty; - - if (!urb->actual_length) - return; - /* - * The first byte of the packet we get from the device - * contains a busy indicator and baud rate change. - * See section 5.4.1.2 of the USB IrDA spec. - */ - if (*data & 0x0f) - ir_baud = *data & 0x0f; - - if (urb->actual_length == 1) - return; - - tty = tty_port_tty_get(&port->port); - if (!tty) - return; - tty_insert_flip_string(tty, data + 1, urb->actual_length - 1); - tty_flip_buffer_push(tty); - tty_kref_put(tty); -} - -static void ir_set_termios_callback(struct urb *urb) -{ - struct usb_serial_port *port = urb->context; - int status = urb->status; - - dbg("%s - port %d", __func__, port->number); - - kfree(urb->transfer_buffer); - - if (status) - dbg("%s - non-zero urb status: %d", __func__, status); -} - -static void ir_set_termios(struct tty_struct *tty, - struct usb_serial_port *port, struct ktermios *old_termios) -{ - struct urb *urb; - unsigned char *transfer_buffer; - int result; - speed_t baud; - int ir_baud; - - dbg("%s - port %d", __func__, port->number); - - baud = tty_get_baud_rate(tty); - - /* - * FIXME, we should compare the baud request against the - * capability stated in the IR header that we got in the - * startup function. - */ - - switch (baud) { - case 2400: - ir_baud = USB_IRDA_BR_2400; - break; - case 9600: - ir_baud = USB_IRDA_BR_9600; - break; - case 19200: - ir_baud = USB_IRDA_BR_19200; - break; - case 38400: - ir_baud = USB_IRDA_BR_38400; - break; - case 57600: - ir_baud = USB_IRDA_BR_57600; - break; - case 115200: - ir_baud = USB_IRDA_BR_115200; - break; - case 576000: - ir_baud = USB_IRDA_BR_576000; - break; - case 1152000: - ir_baud = USB_IRDA_BR_1152000; - break; - case 4000000: - ir_baud = USB_IRDA_BR_4000000; - break; - default: - ir_baud = USB_IRDA_BR_9600; - baud = 9600; - } - - if (xbof == -1) - ir_xbof = ir_xbof_change(ir_add_bof); - else - ir_xbof = ir_xbof_change(xbof) ; - - /* Only speed changes are supported */ - tty_termios_copy_hw(tty->termios, old_termios); - tty_encode_baud_rate(tty, baud, baud); - - /* - * send the baud change out on an "empty" data packet - */ - urb = usb_alloc_urb(0, GFP_KERNEL); - if (!urb) { - dev_err(&port->dev, "%s - no more urbs\n", __func__); - return; - } - transfer_buffer = kmalloc(1, GFP_KERNEL); - if (!transfer_buffer) { - dev_err(&port->dev, "%s - out of memory\n", __func__); - goto err_buf; - } - - *transfer_buffer = ir_xbof | ir_baud; - - usb_fill_bulk_urb( - urb, - port->serial->dev, - usb_sndbulkpipe(port->serial->dev, - port->bulk_out_endpointAddress), - transfer_buffer, - 1, - ir_set_termios_callback, - port); - - urb->transfer_flags = URB_ZERO_PACKET; - - result = usb_submit_urb(urb, GFP_KERNEL); - if (result) { - dev_err(&port->dev, "%s - failed to submit urb: %d\n", - __func__, result); - goto err_subm; - } - - usb_free_urb(urb); - - return; -err_subm: - kfree(transfer_buffer); -err_buf: - usb_free_urb(urb); -} - -static int __init ir_init(void) -{ - int retval; - - if (buffer_size) { - ir_device.bulk_in_size = buffer_size; - ir_device.bulk_out_size = buffer_size; - } - - retval = usb_serial_register_drivers(&ir_driver, serial_drivers); - if (retval == 0) - printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ":" - DRIVER_DESC "\n"); - return retval; -} - -static void __exit ir_exit(void) -{ - usb_serial_deregister_drivers(&ir_driver, serial_drivers); -} - - -module_init(ir_init); -module_exit(ir_exit); - -MODULE_AUTHOR(DRIVER_AUTHOR); -MODULE_DESCRIPTION(DRIVER_DESC); -MODULE_LICENSE("GPL"); - -module_param(debug, bool, S_IRUGO | S_IWUSR); -MODULE_PARM_DESC(debug, "Debug enabled or not"); -module_param(xbof, int, 0); -MODULE_PARM_DESC(xbof, "Force specific number of XBOFs"); -module_param(buffer_size, int, 0); -MODULE_PARM_DESC(buffer_size, "Size of the transfer buffers"); - diff --git a/ANDROID_3.4.5/drivers/usb/serial/iuu_phoenix.c b/ANDROID_3.4.5/drivers/usb/serial/iuu_phoenix.c deleted file mode 100644 index f2192d52..00000000 --- a/ANDROID_3.4.5/drivers/usb/serial/iuu_phoenix.c +++ /dev/null @@ -1,1324 +0,0 @@ -/* - * Infinity Unlimited USB Phoenix driver - * - * Copyright (C) 2010 James Courtier-Dutton (James@superbug.co.uk) - - * Copyright (C) 2007 Alain Degreffe (eczema@ecze.com) - * - * Original code taken from iuutool (Copyright (C) 2006 Juan Carlos Borrás) - * - * 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. - * - * And tested with help of WB Electronics - * - */ -#include <linux/kernel.h> -#include <linux/errno.h> -#include <linux/init.h> -#include <linux/slab.h> -#include <linux/tty.h> -#include <linux/tty_driver.h> -#include <linux/tty_flip.h> -#include <linux/serial.h> -#include <linux/module.h> -#include <linux/moduleparam.h> -#include <linux/spinlock.h> -#include <linux/uaccess.h> -#include <linux/usb.h> -#include <linux/usb/serial.h> -#include "iuu_phoenix.h" -#include <linux/random.h> - - -#ifdef CONFIG_USB_SERIAL_DEBUG -static bool debug = 1; -#else -static bool debug; -#endif - -/* - * Version Information - */ -#define DRIVER_VERSION "v0.12" -#define DRIVER_DESC "Infinity USB Unlimited Phoenix driver" - -static const struct usb_device_id id_table[] = { - {USB_DEVICE(IUU_USB_VENDOR_ID, IUU_USB_PRODUCT_ID)}, - {} /* Terminating entry */ -}; -MODULE_DEVICE_TABLE(usb, id_table); - -static struct usb_driver iuu_driver = { - .name = "iuu_phoenix", - .probe = usb_serial_probe, - .disconnect = usb_serial_disconnect, - .id_table = id_table, -}; - -/* turbo parameter */ -static int boost = 100; -static int clockmode = 1; -static int cdmode = 1; -static int iuu_cardin; -static int iuu_cardout; -static bool xmas; -static int vcc_default = 5; - -static void read_rxcmd_callback(struct urb *urb); - -struct iuu_private { - spinlock_t lock; /* store irq state */ - wait_queue_head_t delta_msr_wait; - u8 line_status; - int tiostatus; /* store IUART SIGNAL for tiocmget call */ - u8 reset; /* if 1 reset is needed */ - int poll; /* number of poll */ - u8 *writebuf; /* buffer for writing to device */ - int writelen; /* num of byte to write to device */ - u8 *buf; /* used for initialize speed */ - u8 *dbgbuf; /* debug buffer */ - u8 len; - int vcc; /* vcc (either 3 or 5 V) */ - u32 baud; - u32 boost; - u32 clk; -}; - - -static void iuu_free_buf(struct iuu_private *priv) -{ - kfree(priv->buf); - kfree(priv->dbgbuf); - kfree(priv->writebuf); -} - -static int iuu_alloc_buf(struct iuu_private *priv) -{ - priv->buf = kzalloc(256, GFP_KERNEL); - priv->dbgbuf = kzalloc(256, GFP_KERNEL); - priv->writebuf = kzalloc(256, GFP_KERNEL); - if (!priv->buf || !priv->dbgbuf || !priv->writebuf) { - iuu_free_buf(priv); - dbg("%s problem allocation buffer", __func__); - return -ENOMEM; - } - dbg("%s - Privates buffers allocation success", __func__); - return 0; -} - -static int iuu_startup(struct usb_serial *serial) -{ - struct iuu_private *priv; - priv = kzalloc(sizeof(struct iuu_private), GFP_KERNEL); - dbg("%s- priv allocation success", __func__); - if (!priv) - return -ENOMEM; - if (iuu_alloc_buf(priv)) { - kfree(priv); - return -ENOMEM; - } - priv->vcc = vcc_default; - spin_lock_init(&priv->lock); - init_waitqueue_head(&priv->delta_msr_wait); - usb_set_serial_port_data(serial->port[0], priv); - return 0; -} - -/* Release function */ -static void iuu_release(struct usb_serial *serial) -{ - struct usb_serial_port *port = serial->port[0]; - struct iuu_private *priv = usb_get_serial_port_data(port); - if (!port) - return; - - dbg("%s", __func__); - - if (priv) { - iuu_free_buf(priv); - dbg("%s - I will free all", __func__); - usb_set_serial_port_data(port, NULL); - - dbg("%s - priv is not anymore in port structure", __func__); - kfree(priv); - - dbg("%s priv is now kfree", __func__); - } -} - -static int iuu_tiocmset(struct tty_struct *tty, - unsigned int set, unsigned int clear) -{ - struct usb_serial_port *port = tty->driver_data; - struct iuu_private *priv = usb_get_serial_port_data(port); - unsigned long flags; - - /* FIXME: locking on tiomstatus */ - dbg("%s (%d) msg : SET = 0x%04x, CLEAR = 0x%04x ", __func__, - port->number, set, clear); - - spin_lock_irqsave(&priv->lock, flags); - - if ((set & TIOCM_RTS) && !(priv->tiostatus == TIOCM_RTS)) { - dbg("%s TIOCMSET RESET called !!!", __func__); - priv->reset = 1; - } - if (set & TIOCM_RTS) - priv->tiostatus = TIOCM_RTS; - - spin_unlock_irqrestore(&priv->lock, flags); - return 0; -} - -/* This is used to provide a carrier detect mechanism - * When a card is present, the response is 0x00 - * When no card , the reader respond with TIOCM_CD - * This is known as CD autodetect mechanism - */ -static int iuu_tiocmget(struct tty_struct *tty) -{ - struct usb_serial_port *port = tty->driver_data; - struct iuu_private *priv = usb_get_serial_port_data(port); - unsigned long flags; - int rc; - - spin_lock_irqsave(&priv->lock, flags); - rc = priv->tiostatus; - spin_unlock_irqrestore(&priv->lock, flags); - - return rc; -} - -static void iuu_rxcmd(struct urb *urb) -{ - struct usb_serial_port *port = urb->context; - int result; - int status = urb->status; - - dbg("%s - enter", __func__); - - if (status) { - dbg("%s - status = %d", __func__, status); - /* error stop all */ - return; - } - - - memset(port->write_urb->transfer_buffer, IUU_UART_RX, 1); - usb_fill_bulk_urb(port->write_urb, port->serial->dev, - usb_sndbulkpipe(port->serial->dev, - port->bulk_out_endpointAddress), - port->write_urb->transfer_buffer, 1, - read_rxcmd_callback, port); - result = usb_submit_urb(port->write_urb, GFP_ATOMIC); -} - -static int iuu_reset(struct usb_serial_port *port, u8 wt) -{ - struct iuu_private *priv = usb_get_serial_port_data(port); - int result; - char *buf_ptr = port->write_urb->transfer_buffer; - dbg("%s - enter", __func__); - - /* Prepare the reset sequence */ - - *buf_ptr++ = IUU_RST_SET; - *buf_ptr++ = IUU_DELAY_MS; - *buf_ptr++ = wt; - *buf_ptr = IUU_RST_CLEAR; - - /* send the sequence */ - - usb_fill_bulk_urb(port->write_urb, - port->serial->dev, - usb_sndbulkpipe(port->serial->dev, - port->bulk_out_endpointAddress), - port->write_urb->transfer_buffer, 4, iuu_rxcmd, port); - result = usb_submit_urb(port->write_urb, GFP_ATOMIC); - priv->reset = 0; - return result; -} - -/* Status Function - * Return value is - * 0x00 = no card - * 0x01 = smartcard - * 0x02 = sim card - */ -static void iuu_update_status_callback(struct urb *urb) -{ - struct usb_serial_port *port = urb->context; - struct iuu_private *priv = usb_get_serial_port_data(port); - u8 *st; - int status = urb->status; - - dbg("%s - enter", __func__); - - if (status) { - dbg("%s - status = %d", __func__, status); - /* error stop all */ - return; - } - - st = urb->transfer_buffer; - dbg("%s - enter", __func__); - if (urb->actual_length == 1) { - switch (st[0]) { - case 0x1: - priv->tiostatus = iuu_cardout; - break; - case 0x0: - priv->tiostatus = iuu_cardin; - break; - default: - priv->tiostatus = iuu_cardin; - } - } - iuu_rxcmd(urb); -} - -static void iuu_status_callback(struct urb *urb) -{ - struct usb_serial_port *port = urb->context; - int result; - int status = urb->status; - - dbg("%s - status = %d", __func__, status); - usb_fill_bulk_urb(port->read_urb, port->serial->dev, - usb_rcvbulkpipe(port->serial->dev, - port->bulk_in_endpointAddress), - port->read_urb->transfer_buffer, 256, - iuu_update_status_callback, port); - result = usb_submit_urb(port->read_urb, GFP_ATOMIC); -} - -static int iuu_status(struct usb_serial_port *port) -{ - int result; - - dbg("%s - enter", __func__); - - memset(port->write_urb->transfer_buffer, IUU_GET_STATE_REGISTER, 1); - usb_fill_bulk_urb(port->write_urb, port->serial->dev, - usb_sndbulkpipe(port->serial->dev, - port->bulk_out_endpointAddress), - port->write_urb->transfer_buffer, 1, - iuu_status_callback, port); - result = usb_submit_urb(port->write_urb, GFP_ATOMIC); - return result; - -} - -static int bulk_immediate(struct usb_serial_port *port, u8 *buf, u8 count) -{ - int status; - struct usb_serial *serial = port->serial; - int actual = 0; - - dbg("%s - enter", __func__); - - /* send the data out the bulk port */ - - status = - usb_bulk_msg(serial->dev, - usb_sndbulkpipe(serial->dev, - port->bulk_out_endpointAddress), buf, - count, &actual, HZ * 1); - - if (status != IUU_OPERATION_OK) - dbg("%s - error = %2x", __func__, status); - else - dbg("%s - write OK !", __func__); - return status; -} - -static int read_immediate(struct usb_serial_port *port, u8 *buf, u8 count) -{ - int status; - struct usb_serial *serial = port->serial; - int actual = 0; - - dbg("%s - enter", __func__); - - /* send the data out the bulk port */ - - status = - usb_bulk_msg(serial->dev, - usb_rcvbulkpipe(serial->dev, - port->bulk_in_endpointAddress), buf, - count, &actual, HZ * 1); - - if (status != IUU_OPERATION_OK) - dbg("%s - error = %2x", __func__, status); - else - dbg("%s - read OK !", __func__); - return status; -} - -static int iuu_led(struct usb_serial_port *port, unsigned int R, - unsigned int G, unsigned int B, u8 f) -{ - int status; - u8 *buf; - buf = kmalloc(8, GFP_KERNEL); - if (!buf) - return -ENOMEM; - - dbg("%s - enter", __func__); - - buf[0] = IUU_SET_LED; - buf[1] = R & 0xFF; - buf[2] = (R >> 8) & 0xFF; - buf[3] = G & 0xFF; - buf[4] = (G >> 8) & 0xFF; - buf[5] = B & 0xFF; - buf[6] = (B >> 8) & 0xFF; - buf[7] = f; - status = bulk_immediate(port, buf, 8); - kfree(buf); - if (status != IUU_OPERATION_OK) - dbg("%s - led error status = %2x", __func__, status); - else - dbg("%s - led OK !", __func__); - return IUU_OPERATION_OK; -} - -static void iuu_rgbf_fill_buffer(u8 *buf, u8 r1, u8 r2, u8 g1, u8 g2, u8 b1, - u8 b2, u8 freq) -{ - *buf++ = IUU_SET_LED; - *buf++ = r1; - *buf++ = r2; - *buf++ = g1; - *buf++ = g2; - *buf++ = b1; - *buf++ = b2; - *buf = freq; -} - -static void iuu_led_activity_on(struct urb *urb) -{ - struct usb_serial_port *port = urb->context; - int result; - char *buf_ptr = port->write_urb->transfer_buffer; - *buf_ptr++ = IUU_SET_LED; - if (xmas == 1) { - get_random_bytes(buf_ptr, 6); - *(buf_ptr+7) = 1; - } else { - iuu_rgbf_fill_buffer(buf_ptr, 255, 255, 0, 0, 0, 0, 255); - } - - usb_fill_bulk_urb(port->write_urb, port->serial->dev, - usb_sndbulkpipe(port->serial->dev, - port->bulk_out_endpointAddress), - port->write_urb->transfer_buffer, 8 , - iuu_rxcmd, port); - result = usb_submit_urb(port->write_urb, GFP_ATOMIC); -} - -static void iuu_led_activity_off(struct urb *urb) -{ - struct usb_serial_port *port = urb->context; - int result; - char *buf_ptr = port->write_urb->transfer_buffer; - if (xmas == 1) { - iuu_rxcmd(urb); - return; - } else { - *buf_ptr++ = IUU_SET_LED; - iuu_rgbf_fill_buffer(buf_ptr, 0, 0, 255, 255, 0, 0, 255); - } - usb_fill_bulk_urb(port->write_urb, port->serial->dev, - usb_sndbulkpipe(port->serial->dev, - port->bulk_out_endpointAddress), - port->write_urb->transfer_buffer, 8 , - iuu_rxcmd, port); - result = usb_submit_urb(port->write_urb, GFP_ATOMIC); -} - - - -static int iuu_clk(struct usb_serial_port *port, int dwFrq) -{ - int status; - struct iuu_private *priv = usb_get_serial_port_data(port); - int Count = 0; - u8 FrqGenAdr = 0x69; - u8 DIV = 0; /* 8bit */ - u8 XDRV = 0; /* 8bit */ - u8 PUMP = 0; /* 3bit */ - u8 PBmsb = 0; /* 2bit */ - u8 PBlsb = 0; /* 8bit */ - u8 PO = 0; /* 1bit */ - u8 Q = 0; /* 7bit */ - /* 24bit = 3bytes */ - unsigned int P = 0; - unsigned int P2 = 0; - int frq = (int)dwFrq; - - dbg("%s - enter", __func__); - - if (frq == 0) { - priv->buf[Count++] = IUU_UART_WRITE_I2C; - priv->buf[Count++] = FrqGenAdr << 1; - priv->buf[Count++] = 0x09; - priv->buf[Count++] = 0x00; - - status = bulk_immediate(port, (u8 *) priv->buf, Count); - if (status != 0) { - dbg("%s - write error ", __func__); - return status; - } - } else if (frq == 3579000) { - DIV = 100; - P = 1193; - Q = 40; - XDRV = 0; - } else if (frq == 3680000) { - DIV = 105; - P = 161; - Q = 5; - XDRV = 0; - } else if (frq == 6000000) { - DIV = 66; - P = 66; - Q = 2; - XDRV = 0x28; - } else { - unsigned int result = 0; - unsigned int tmp = 0; - unsigned int check; - unsigned int check2; - char found = 0x00; - unsigned int lQ = 2; - unsigned int lP = 2055; - unsigned int lDiv = 4; - - for (lQ = 2; lQ <= 47 && !found; lQ++) - for (lP = 2055; lP >= 8 && !found; lP--) - for (lDiv = 4; lDiv <= 127 && !found; lDiv++) { - tmp = (12000000 / lDiv) * (lP / lQ); - if (abs((int)(tmp - frq)) < - abs((int)(frq - result))) { - check2 = (12000000 / lQ); - if (check2 < 250000) - continue; - check = (12000000 / lQ) * lP; - if (check > 400000000) - continue; - if (check < 100000000) - continue; - if (lDiv < 4 || lDiv > 127) - continue; - result = tmp; - P = lP; - DIV = lDiv; - Q = lQ; - if (result == frq) - found = 0x01; - } - } - } - P2 = ((P - PO) / 2) - 4; - DIV = DIV; - PUMP = 0x04; - PBmsb = (P2 >> 8 & 0x03); - PBlsb = P2 & 0xFF; - PO = (P >> 10) & 0x01; - Q = Q - 2; - - priv->buf[Count++] = IUU_UART_WRITE_I2C; /* 0x4C */ - priv->buf[Count++] = FrqGenAdr << 1; - priv->buf[Count++] = 0x09; - priv->buf[Count++] = 0x20; /* Adr = 0x09 */ - priv->buf[Count++] = IUU_UART_WRITE_I2C; /* 0x4C */ - priv->buf[Count++] = FrqGenAdr << 1; - priv->buf[Count++] = 0x0C; - priv->buf[Count++] = DIV; /* Adr = 0x0C */ - priv->buf[Count++] = IUU_UART_WRITE_I2C; /* 0x4C */ - priv->buf[Count++] = FrqGenAdr << 1; - priv->buf[Count++] = 0x12; - priv->buf[Count++] = XDRV; /* Adr = 0x12 */ - priv->buf[Count++] = IUU_UART_WRITE_I2C; /* 0x4C */ - priv->buf[Count++] = FrqGenAdr << 1; - priv->buf[Count++] = 0x13; - priv->buf[Count++] = 0x6B; /* Adr = 0x13 */ - priv->buf[Count++] = IUU_UART_WRITE_I2C; /* 0x4C */ - priv->buf[Count++] = FrqGenAdr << 1; - priv->buf[Count++] = 0x40; - priv->buf[Count++] = (0xC0 | ((PUMP & 0x07) << 2)) | - (PBmsb & 0x03); /* Adr = 0x40 */ - priv->buf[Count++] = IUU_UART_WRITE_I2C; /* 0x4C */ - priv->buf[Count++] = FrqGenAdr << 1; - priv->buf[Count++] = 0x41; - priv->buf[Count++] = PBlsb; /* Adr = 0x41 */ - priv->buf[Count++] = IUU_UART_WRITE_I2C; /* 0x4C */ - priv->buf[Count++] = FrqGenAdr << 1; - priv->buf[Count++] = 0x42; - priv->buf[Count++] = Q | (((PO & 0x01) << 7)); /* Adr = 0x42 */ - priv->buf[Count++] = IUU_UART_WRITE_I2C; /* 0x4C */ - priv->buf[Count++] = FrqGenAdr << 1; - priv->buf[Count++] = 0x44; - priv->buf[Count++] = (char)0xFF; /* Adr = 0x44 */ - priv->buf[Count++] = IUU_UART_WRITE_I2C; /* 0x4C */ - priv->buf[Count++] = FrqGenAdr << 1; - priv->buf[Count++] = 0x45; - priv->buf[Count++] = (char)0xFE; /* Adr = 0x45 */ - priv->buf[Count++] = IUU_UART_WRITE_I2C; /* 0x4C */ - priv->buf[Count++] = FrqGenAdr << 1; - priv->buf[Count++] = 0x46; - priv->buf[Count++] = 0x7F; /* Adr = 0x46 */ - priv->buf[Count++] = IUU_UART_WRITE_I2C; /* 0x4C */ - priv->buf[Count++] = FrqGenAdr << 1; - priv->buf[Count++] = 0x47; - priv->buf[Count++] = (char)0x84; /* Adr = 0x47 */ - - status = bulk_immediate(port, (u8 *) priv->buf, Count); - if (status != IUU_OPERATION_OK) - dbg("%s - write error ", __func__); - return status; -} - -static int iuu_uart_flush(struct usb_serial_port *port) -{ - int i; - int status; - u8 rxcmd = IUU_UART_RX; - struct iuu_private *priv = usb_get_serial_port_data(port); - - dbg("%s - enter", __func__); - - if (iuu_led(port, 0xF000, 0, 0, 0xFF) < 0) - return -EIO; - - for (i = 0; i < 2; i++) { - status = bulk_immediate(port, &rxcmd, 1); - if (status != IUU_OPERATION_OK) { - dbg("%s - uart_flush_write error", __func__); - return status; - } - - status = read_immediate(port, &priv->len, 1); - if (status != IUU_OPERATION_OK) { - dbg("%s - uart_flush_read error", __func__); - return status; - } - - if (priv->len > 0) { - dbg("%s - uart_flush datalen is : %i ", __func__, - priv->len); - status = read_immediate(port, priv->buf, priv->len); - if (status != IUU_OPERATION_OK) { - dbg("%s - uart_flush_read error", __func__); - return status; - } - } - } - dbg("%s - uart_flush_read OK!", __func__); - iuu_led(port, 0, 0xF000, 0, 0xFF); - return status; -} - -static void read_buf_callback(struct urb *urb) -{ - struct usb_serial_port *port = urb->context; - unsigned char *data = urb->transfer_buffer; - struct tty_struct *tty; - int status = urb->status; - - dbg("%s - status = %d", __func__, status); - - if (status) { - if (status == -EPROTO) { - /* reschedule needed */ - } - return; - } - - dbg("%s - %i chars to write", __func__, urb->actual_length); - tty = tty_port_tty_get(&port->port); - if (data == NULL) - dbg("%s - data is NULL !!!", __func__); - if (tty && urb->actual_length && data) { - tty_insert_flip_string(tty, data, urb->actual_length); - tty_flip_buffer_push(tty); - } - tty_kref_put(tty); - iuu_led_activity_on(urb); -} - -static int iuu_bulk_write(struct usb_serial_port *port) -{ - struct iuu_private *priv = usb_get_serial_port_data(port); - unsigned long flags; - int result; - int i; - int buf_len; - char *buf_ptr = port->write_urb->transfer_buffer; - dbg("%s - enter", __func__); - - spin_lock_irqsave(&priv->lock, flags); - *buf_ptr++ = IUU_UART_ESC; - *buf_ptr++ = IUU_UART_TX; - *buf_ptr++ = priv->writelen; - - memcpy(buf_ptr, priv->writebuf, priv->writelen); - buf_len = priv->writelen; - priv->writelen = 0; - spin_unlock_irqrestore(&priv->lock, flags); - if (debug == 1) { - for (i = 0; i < buf_len; i++) - sprintf(priv->dbgbuf + i*2 , - "%02X", priv->writebuf[i]); - priv->dbgbuf[buf_len+i*2] = 0; - dbg("%s - writing %i chars : %s", __func__, - buf_len, priv->dbgbuf); - } - usb_fill_bulk_urb(port->write_urb, port->serial->dev, - usb_sndbulkpipe(port->serial->dev, - port->bulk_out_endpointAddress), - port->write_urb->transfer_buffer, buf_len + 3, - iuu_rxcmd, port); - result = usb_submit_urb(port->write_urb, GFP_ATOMIC); - usb_serial_port_softint(port); - return result; -} - -static int iuu_read_buf(struct usb_serial_port *port, int len) -{ - int result; - dbg("%s - enter", __func__); - - usb_fill_bulk_urb(port->read_urb, port->serial->dev, - usb_rcvbulkpipe(port->serial->dev, - port->bulk_in_endpointAddress), - port->read_urb->transfer_buffer, len, - read_buf_callback, port); - result = usb_submit_urb(port->read_urb, GFP_ATOMIC); - return result; -} - -static void iuu_uart_read_callback(struct urb *urb) -{ - struct usb_serial_port *port = urb->context; - struct iuu_private *priv = usb_get_serial_port_data(port); - unsigned long flags; - int status = urb->status; - int error = 0; - int len = 0; - unsigned char *data = urb->transfer_buffer; - priv->poll++; - - dbg("%s - enter", __func__); - - if (status) { - dbg("%s - status = %d", __func__, status); - /* error stop all */ - return; - } - if (data == NULL) - dbg("%s - data is NULL !!!", __func__); - - if (urb->actual_length == 1 && data != NULL) - len = (int) data[0]; - - if (urb->actual_length > 1) { - dbg("%s - urb->actual_length = %i", __func__, - urb->actual_length); - error = 1; - return; - } - /* if len > 0 call readbuf */ - - if (len > 0 && error == 0) { - dbg("%s - call read buf - len to read is %i ", - __func__, len); - status = iuu_read_buf(port, len); - return; - } - /* need to update status ? */ - if (priv->poll > 99) { - status = iuu_status(port); - priv->poll = 0; - return; - } - - /* reset waiting ? */ - - if (priv->reset == 1) { - status = iuu_reset(port, 0xC); - return; - } - /* Writebuf is waiting */ - spin_lock_irqsave(&priv->lock, flags); - if (priv->writelen > 0) { - spin_unlock_irqrestore(&priv->lock, flags); - status = iuu_bulk_write(port); - return; - } - spin_unlock_irqrestore(&priv->lock, flags); - /* if nothing to write call again rxcmd */ - dbg("%s - rxcmd recall", __func__); - iuu_led_activity_off(urb); -} - -static int iuu_uart_write(struct tty_struct *tty, struct usb_serial_port *port, - const u8 *buf, int count) -{ - struct iuu_private *priv = usb_get_serial_port_data(port); - unsigned long flags; - dbg("%s - enter", __func__); - - if (count > 256) - return -ENOMEM; - - spin_lock_irqsave(&priv->lock, flags); - - /* fill the buffer */ - memcpy(priv->writebuf + priv->writelen, buf, count); - priv->writelen += count; - spin_unlock_irqrestore(&priv->lock, flags); - - return count; -} - -static void read_rxcmd_callback(struct urb *urb) -{ - struct usb_serial_port *port = urb->context; - int result; - int status = urb->status; - - dbg("%s - status = %d", __func__, status); - - if (status) { - /* error stop all */ - return; - } - - usb_fill_bulk_urb(port->read_urb, port->serial->dev, - usb_rcvbulkpipe(port->serial->dev, - port->bulk_in_endpointAddress), - port->read_urb->transfer_buffer, 256, - iuu_uart_read_callback, port); - result = usb_submit_urb(port->read_urb, GFP_ATOMIC); - dbg("%s - submit result = %d", __func__, result); -} - -static int iuu_uart_on(struct usb_serial_port *port) -{ - int status; - u8 *buf; - - buf = kmalloc(sizeof(u8) * 4, GFP_KERNEL); - - if (!buf) - return -ENOMEM; - - buf[0] = IUU_UART_ENABLE; - buf[1] = (u8) ((IUU_BAUD_9600 >> 8) & 0x00FF); - buf[2] = (u8) (0x00FF & IUU_BAUD_9600); - buf[3] = (u8) (0x0F0 & IUU_ONE_STOP_BIT) | (0x07 & IUU_PARITY_EVEN); - - status = bulk_immediate(port, buf, 4); - if (status != IUU_OPERATION_OK) { - dbg("%s - uart_on error", __func__); - goto uart_enable_failed; - } - /* iuu_reset() the card after iuu_uart_on() */ - status = iuu_uart_flush(port); - if (status != IUU_OPERATION_OK) - dbg("%s - uart_flush error", __func__); -uart_enable_failed: - kfree(buf); - return status; -} - -/* Diables the IUU UART (a.k.a. the Phoenix voiderface) */ -static int iuu_uart_off(struct usb_serial_port *port) -{ - int status; - u8 *buf; - buf = kmalloc(1, GFP_KERNEL); - if (!buf) - return -ENOMEM; - buf[0] = IUU_UART_DISABLE; - - status = bulk_immediate(port, buf, 1); - if (status != IUU_OPERATION_OK) - dbg("%s - uart_off error", __func__); - - kfree(buf); - return status; -} - -static int iuu_uart_baud(struct usb_serial_port *port, u32 baud_base, - u32 *actual, u8 parity) -{ - int status; - u32 baud; - u8 *dataout; - u8 DataCount = 0; - u8 T1Frekvens = 0; - u8 T1reload = 0; - unsigned int T1FrekvensHZ = 0; - - dbg("%s - enter baud_base=%d", __func__, baud_base); - dataout = kmalloc(sizeof(u8) * 5, GFP_KERNEL); - - if (!dataout) - return -ENOMEM; - /*baud = (((priv->clk / 35) * baud_base) / 100000); */ - baud = baud_base; - - if (baud < 1200 || baud > 230400) { - kfree(dataout); - return IUU_INVALID_PARAMETER; - } - if (baud > 977) { - T1Frekvens = 3; - T1FrekvensHZ = 500000; - } - - if (baud > 3906) { - T1Frekvens = 2; - T1FrekvensHZ = 2000000; - } - - if (baud > 11718) { - T1Frekvens = 1; - T1FrekvensHZ = 6000000; - } - - if (baud > 46875) { - T1Frekvens = 0; - T1FrekvensHZ = 24000000; - } - - T1reload = 256 - (u8) (T1FrekvensHZ / (baud * 2)); - - /* magic number here: ENTER_FIRMWARE_UPDATE; */ - dataout[DataCount++] = IUU_UART_ESC; - /* magic number here: CHANGE_BAUD; */ - dataout[DataCount++] = IUU_UART_CHANGE; - dataout[DataCount++] = T1Frekvens; - dataout[DataCount++] = T1reload; - - *actual = (T1FrekvensHZ / (256 - T1reload)) / 2; - - switch (parity & 0x0F) { - case IUU_PARITY_NONE: - dataout[DataCount++] = 0x00; - break; - case IUU_PARITY_EVEN: - dataout[DataCount++] = 0x01; - break; - case IUU_PARITY_ODD: - dataout[DataCount++] = 0x02; - break; - case IUU_PARITY_MARK: - dataout[DataCount++] = 0x03; - break; - case IUU_PARITY_SPACE: - dataout[DataCount++] = 0x04; - break; - default: - kfree(dataout); - return IUU_INVALID_PARAMETER; - break; - } - - switch (parity & 0xF0) { - case IUU_ONE_STOP_BIT: - dataout[DataCount - 1] |= IUU_ONE_STOP_BIT; - break; - - case IUU_TWO_STOP_BITS: - dataout[DataCount - 1] |= IUU_TWO_STOP_BITS; - break; - default: - kfree(dataout); - return IUU_INVALID_PARAMETER; - break; - } - - status = bulk_immediate(port, dataout, DataCount); - if (status != IUU_OPERATION_OK) - dbg("%s - uart_off error", __func__); - kfree(dataout); - return status; -} - -static void iuu_set_termios(struct tty_struct *tty, - struct usb_serial_port *port, struct ktermios *old_termios) -{ - const u32 supported_mask = CMSPAR|PARENB|PARODD; - struct iuu_private *priv = usb_get_serial_port_data(port); - unsigned int cflag = tty->termios->c_cflag; - int status; - u32 actual; - u32 parity; - int csize = CS7; - int baud; - u32 newval = cflag & supported_mask; - - /* Just use the ospeed. ispeed should be the same. */ - baud = tty->termios->c_ospeed; - - dbg("%s - enter c_ospeed or baud=%d", __func__, baud); - - /* compute the parity parameter */ - parity = 0; - if (cflag & CMSPAR) { /* Using mark space */ - if (cflag & PARODD) - parity |= IUU_PARITY_SPACE; - else - parity |= IUU_PARITY_MARK; - } else if (!(cflag & PARENB)) { - parity |= IUU_PARITY_NONE; - csize = CS8; - } else if (cflag & PARODD) - parity |= IUU_PARITY_ODD; - else - parity |= IUU_PARITY_EVEN; - - parity |= (cflag & CSTOPB ? IUU_TWO_STOP_BITS : IUU_ONE_STOP_BIT); - - /* set it */ - status = iuu_uart_baud(port, - baud * priv->boost / 100, - &actual, parity); - - /* set the termios value to the real one, so the user now what has - * changed. We support few fields so its easies to copy the old hw - * settings back over and then adjust them - */ - if (old_termios) - tty_termios_copy_hw(tty->termios, old_termios); - if (status != 0) /* Set failed - return old bits */ - return; - /* Re-encode speed, parity and csize */ - tty_encode_baud_rate(tty, baud, baud); - tty->termios->c_cflag &= ~(supported_mask|CSIZE); - tty->termios->c_cflag |= newval | csize; -} - -static void iuu_close(struct usb_serial_port *port) -{ - /* iuu_led (port,255,0,0,0); */ - struct usb_serial *serial; - - serial = port->serial; - if (!serial) - return; - - dbg("%s - port %d", __func__, port->number); - - iuu_uart_off(port); - if (serial->dev) { - /* free writebuf */ - /* shutdown our urbs */ - dbg("%s - shutting down urbs", __func__); - usb_kill_urb(port->write_urb); - usb_kill_urb(port->read_urb); - usb_kill_urb(port->interrupt_in_urb); - iuu_led(port, 0, 0, 0xF000, 0xFF); - } -} - -static void iuu_init_termios(struct tty_struct *tty) -{ - dbg("%s - enter", __func__); - *(tty->termios) = tty_std_termios; - tty->termios->c_cflag = CLOCAL | CREAD | CS8 | B9600 - | TIOCM_CTS | CSTOPB | PARENB; - tty->termios->c_ispeed = 9600; - tty->termios->c_ospeed = 9600; - tty->termios->c_lflag = 0; - tty->termios->c_oflag = 0; - tty->termios->c_iflag = 0; -} - -static int iuu_open(struct tty_struct *tty, struct usb_serial_port *port) -{ - struct usb_serial *serial = port->serial; - u8 *buf; - int result; - int baud; - u32 actual; - struct iuu_private *priv = usb_get_serial_port_data(port); - - baud = tty->termios->c_ospeed; - tty->termios->c_ispeed = baud; - /* Re-encode speed */ - tty_encode_baud_rate(tty, baud, baud); - - dbg("%s - port %d, baud %d", __func__, port->number, baud); - usb_clear_halt(serial->dev, port->write_urb->pipe); - usb_clear_halt(serial->dev, port->read_urb->pipe); - - buf = kmalloc(10, GFP_KERNEL); - if (buf == NULL) - return -ENOMEM; - - priv->poll = 0; - - /* initialize writebuf */ -#define FISH(a, b, c, d) do { \ - result = usb_control_msg(port->serial->dev, \ - usb_rcvctrlpipe(port->serial->dev, 0), \ - b, a, c, d, buf, 1, 1000); \ - dbg("0x%x:0x%x:0x%x:0x%x %d - %x", a, b, c, d, result, \ - buf[0]); } while (0); - -#define SOUP(a, b, c, d) do { \ - result = usb_control_msg(port->serial->dev, \ - usb_sndctrlpipe(port->serial->dev, 0), \ - b, a, c, d, NULL, 0, 1000); \ - dbg("0x%x:0x%x:0x%x:0x%x %d", a, b, c, d, result); } while (0) - - /* This is not UART related but IUU USB driver related or something */ - /* like that. Basically no IUU will accept any commands from the USB */ - /* host unless it has received the following message */ - /* sprintf(buf ,"%c%c%c%c",0x03,0x02,0x02,0x0); */ - - SOUP(0x03, 0x02, 0x02, 0x0); - kfree(buf); - iuu_led(port, 0xF000, 0xF000, 0, 0xFF); - iuu_uart_on(port); - if (boost < 100) - boost = 100; - priv->boost = boost; - priv->baud = baud; - switch (clockmode) { - case 2: /* 3.680 Mhz */ - priv->clk = IUU_CLK_3680000; - iuu_clk(port, IUU_CLK_3680000 * boost / 100); - result = - iuu_uart_baud(port, baud * boost / 100, &actual, - IUU_PARITY_EVEN); - break; - case 3: /* 6.00 Mhz */ - iuu_clk(port, IUU_CLK_6000000 * boost / 100); - priv->clk = IUU_CLK_6000000; - /* Ratio of 6000000 to 3500000 for baud 9600 */ - result = - iuu_uart_baud(port, 16457 * boost / 100, &actual, - IUU_PARITY_EVEN); - break; - default: /* 3.579 Mhz */ - iuu_clk(port, IUU_CLK_3579000 * boost / 100); - priv->clk = IUU_CLK_3579000; - result = - iuu_uart_baud(port, baud * boost / 100, &actual, - IUU_PARITY_EVEN); - } - - /* set the cardin cardout signals */ - switch (cdmode) { - case 0: - iuu_cardin = 0; - iuu_cardout = 0; - break; - case 1: - iuu_cardin = TIOCM_CD; - iuu_cardout = 0; - break; - case 2: - iuu_cardin = 0; - iuu_cardout = TIOCM_CD; - break; - case 3: - iuu_cardin = TIOCM_DSR; - iuu_cardout = 0; - break; - case 4: - iuu_cardin = 0; - iuu_cardout = TIOCM_DSR; - break; - case 5: - iuu_cardin = TIOCM_CTS; - iuu_cardout = 0; - break; - case 6: - iuu_cardin = 0; - iuu_cardout = TIOCM_CTS; - break; - case 7: - iuu_cardin = TIOCM_RNG; - iuu_cardout = 0; - break; - case 8: - iuu_cardin = 0; - iuu_cardout = TIOCM_RNG; - } - - iuu_uart_flush(port); - - dbg("%s - initialization done", __func__); - - memset(port->write_urb->transfer_buffer, IUU_UART_RX, 1); - usb_fill_bulk_urb(port->write_urb, port->serial->dev, - usb_sndbulkpipe(port->serial->dev, - port->bulk_out_endpointAddress), - port->write_urb->transfer_buffer, 1, - read_rxcmd_callback, port); - result = usb_submit_urb(port->write_urb, GFP_KERNEL); - if (result) { - dev_err(&port->dev, "%s - failed submitting read urb," - " error %d\n", __func__, result); - iuu_close(port); - } else { - dbg("%s - rxcmd OK", __func__); - } - - return result; -} - -/* how to change VCC */ -static int iuu_vcc_set(struct usb_serial_port *port, unsigned int vcc) -{ - int status; - u8 *buf; - - buf = kmalloc(5, GFP_KERNEL); - if (!buf) - return -ENOMEM; - - dbg("%s - enter", __func__); - - buf[0] = IUU_SET_VCC; - buf[1] = vcc & 0xFF; - buf[2] = (vcc >> 8) & 0xFF; - buf[3] = (vcc >> 16) & 0xFF; - buf[4] = (vcc >> 24) & 0xFF; - - status = bulk_immediate(port, buf, 5); - kfree(buf); - - if (status != IUU_OPERATION_OK) - dbg("%s - vcc error status = %2x", __func__, status); - else - dbg("%s - vcc OK !", __func__); - - return status; -} - -/* - * Sysfs Attributes - */ - -static ssize_t show_vcc_mode(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct usb_serial_port *port = to_usb_serial_port(dev); - struct iuu_private *priv = usb_get_serial_port_data(port); - - return sprintf(buf, "%d\n", priv->vcc); -} - -static ssize_t store_vcc_mode(struct device *dev, - struct device_attribute *attr, const char *buf, size_t count) -{ - struct usb_serial_port *port = to_usb_serial_port(dev); - struct iuu_private *priv = usb_get_serial_port_data(port); - unsigned long v; - - if (strict_strtoul(buf, 10, &v)) { - dev_err(dev, "%s - vcc_mode: %s is not a unsigned long\n", - __func__, buf); - goto fail_store_vcc_mode; - } - - dbg("%s: setting vcc_mode = %ld", __func__, v); - - if ((v != 3) && (v != 5)) { - dev_err(dev, "%s - vcc_mode %ld is invalid\n", __func__, v); - } else { - iuu_vcc_set(port, v); - priv->vcc = v; - } -fail_store_vcc_mode: - return count; -} - -static DEVICE_ATTR(vcc_mode, S_IRUSR | S_IWUSR, show_vcc_mode, - store_vcc_mode); - -static int iuu_create_sysfs_attrs(struct usb_serial_port *port) -{ - dbg("%s", __func__); - - return device_create_file(&port->dev, &dev_attr_vcc_mode); -} - -static int iuu_remove_sysfs_attrs(struct usb_serial_port *port) -{ - dbg("%s", __func__); - - device_remove_file(&port->dev, &dev_attr_vcc_mode); - return 0; -} - -/* - * End Sysfs Attributes - */ - -static struct usb_serial_driver iuu_device = { - .driver = { - .owner = THIS_MODULE, - .name = "iuu_phoenix", - }, - .id_table = id_table, - .num_ports = 1, - .bulk_in_size = 512, - .bulk_out_size = 512, - .port_probe = iuu_create_sysfs_attrs, - .port_remove = iuu_remove_sysfs_attrs, - .open = iuu_open, - .close = iuu_close, - .write = iuu_uart_write, - .read_bulk_callback = iuu_uart_read_callback, - .tiocmget = iuu_tiocmget, - .tiocmset = iuu_tiocmset, - .set_termios = iuu_set_termios, - .init_termios = iuu_init_termios, - .attach = iuu_startup, - .release = iuu_release, -}; - -static struct usb_serial_driver * const serial_drivers[] = { - &iuu_device, NULL -}; - -module_usb_serial_driver(iuu_driver, serial_drivers); - -MODULE_AUTHOR("Alain Degreffe eczema@ecze.com"); - -MODULE_DESCRIPTION(DRIVER_DESC); -MODULE_LICENSE("GPL"); - -MODULE_VERSION(DRIVER_VERSION); -module_param(debug, bool, S_IRUGO | S_IWUSR); -MODULE_PARM_DESC(debug, "Debug enabled or not"); - -module_param(xmas, bool, S_IRUGO | S_IWUSR); -MODULE_PARM_DESC(xmas, "Xmas colors enabled or not"); - -module_param(boost, int, S_IRUGO | S_IWUSR); -MODULE_PARM_DESC(boost, "Card overclock boost (in percent 100-500)"); - -module_param(clockmode, int, S_IRUGO | S_IWUSR); -MODULE_PARM_DESC(clockmode, "Card clock mode (1=3.579 MHz, 2=3.680 MHz, " - "3=6 Mhz)"); - -module_param(cdmode, int, S_IRUGO | S_IWUSR); -MODULE_PARM_DESC(cdmode, "Card detect mode (0=none, 1=CD, 2=!CD, 3=DSR, " - "4=!DSR, 5=CTS, 6=!CTS, 7=RING, 8=!RING)"); - -module_param(vcc_default, int, S_IRUGO | S_IWUSR); -MODULE_PARM_DESC(vcc_default, "Set default VCC (either 3 for 3.3V or 5 " - "for 5V). Default to 5."); diff --git a/ANDROID_3.4.5/drivers/usb/serial/iuu_phoenix.h b/ANDROID_3.4.5/drivers/usb/serial/iuu_phoenix.h deleted file mode 100644 index b82630a3..00000000 --- a/ANDROID_3.4.5/drivers/usb/serial/iuu_phoenix.h +++ /dev/null @@ -1,122 +0,0 @@ -/* - * Infinity Unlimited USB Phoenix driver - * - * Copyright (C) 2007 Alain Degreffe (eczema@ecze.com) - * - * - * Original code taken from iuutool ( Copyright (C) 2006 Juan Carlos Borrás ) - * - * 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. - * - * And tested with help of WB Electronics - * - */ - -#define IUU_USB_VENDOR_ID 0x104f -#define IUU_USB_PRODUCT_ID 0x0004 -#define IUU_USB_OP_TIMEOUT 0x0200 - -/* Programmer commands */ - -#define IUU_NO_OPERATION 0x00 -#define IUU_GET_FIRMWARE_VERSION 0x01 -#define IUU_GET_PRODUCT_NAME 0x02 -#define IUU_GET_STATE_REGISTER 0x03 -#define IUU_SET_LED 0x04 -#define IUU_WAIT_MUS 0x05 -#define IUU_WAIT_MS 0x06 -#define IUU_GET_LOADER_VERSION 0x50 -#define IUU_RST_SET 0x52 -#define IUU_RST_CLEAR 0x53 -#define IUU_SET_VCC 0x59 -#define IUU_UART_ENABLE 0x49 -#define IUU_UART_DISABLE 0x4A -#define IUU_UART_WRITE_I2C 0x4C -#define IUU_UART_ESC 0x5E -#define IUU_UART_TRAP 0x54 -#define IUU_UART_TRAP_BREAK 0x5B -#define IUU_UART_RX 0x56 -#define IUU_AVR_ON 0x21 -#define IUU_AVR_OFF 0x22 -#define IUU_AVR_1CLK 0x23 -#define IUU_AVR_RESET 0x24 -#define IUU_AVR_RESET_PC 0x25 -#define IUU_AVR_INC_PC 0x26 -#define IUU_AVR_INCN_PC 0x27 -#define IUU_AVR_PREAD 0x29 -#define IUU_AVR_PREADN 0x2A -#define IUU_AVR_PWRITE 0x28 -#define IUU_AVR_DREAD 0x2C -#define IUU_AVR_DREADN 0x2D -#define IUU_AVR_DWRITE 0x2B -#define IUU_AVR_PWRITEN 0x2E -#define IUU_EEPROM_ON 0x37 -#define IUU_EEPROM_OFF 0x38 -#define IUU_EEPROM_WRITE 0x39 -#define IUU_EEPROM_WRITEX 0x3A -#define IUU_EEPROM_WRITE8 0x3B -#define IUU_EEPROM_WRITE16 0x3C -#define IUU_EEPROM_WRITEX32 0x3D -#define IUU_EEPROM_WRITEX64 0x3E -#define IUU_EEPROM_READ 0x3F -#define IUU_EEPROM_READX 0x40 -#define IUU_EEPROM_BREAD 0x41 -#define IUU_EEPROM_BREADX 0x42 -#define IUU_PIC_CMD 0x0A -#define IUU_PIC_CMD_LOAD 0x0B -#define IUU_PIC_CMD_READ 0x0C -#define IUU_PIC_ON 0x0D -#define IUU_PIC_OFF 0x0E -#define IUU_PIC_RESET 0x16 -#define IUU_PIC_INC_PC 0x0F -#define IUU_PIC_INCN_PC 0x10 -#define IUU_PIC_PWRITE 0x11 -#define IUU_PIC_PREAD 0x12 -#define IUU_PIC_PREADN 0x13 -#define IUU_PIC_DWRITE 0x14 -#define IUU_PIC_DREAD 0x15 -#define IUU_UART_NOP 0x00 -#define IUU_UART_CHANGE 0x02 -#define IUU_UART_TX 0x04 -#define IUU_DELAY_MS 0x06 - -#define IUU_OPERATION_OK 0x00 -#define IUU_DEVICE_NOT_FOUND 0x01 -#define IUU_INVALID_HANDLE 0x02 -#define IUU_INVALID_PARAMETER 0x03 -#define IUU_INVALID_voidERFACE 0x04 -#define IUU_INVALID_REQUEST_LENGTH 0x05 -#define IUU_UART_NOT_ENABLED 0x06 -#define IUU_WRITE_ERROR 0x07 -#define IUU_READ_ERROR 0x08 -#define IUU_TX_ERROR 0x09 -#define IUU_RX_ERROR 0x0A - -#define IUU_PARITY_NONE 0x00 -#define IUU_PARITY_EVEN 0x01 -#define IUU_PARITY_ODD 0x02 -#define IUU_PARITY_MARK 0x03 -#define IUU_PARITY_SPACE 0x04 -#define IUU_SC_INSERTED 0x01 -#define IUU_VERIFY_ERROR 0x02 -#define IUU_SIM_INSERTED 0x04 -#define IUU_TWO_STOP_BITS 0x00 -#define IUU_ONE_STOP_BIT 0x20 -#define IUU_BAUD_2400 0x0398 -#define IUU_BAUD_9600 0x0298 -#define IUU_BAUD_19200 0x0164 -#define IUU_BAUD_28800 0x0198 -#define IUU_BAUD_38400 0x01B2 -#define IUU_BAUD_57600 0x0030 -#define IUU_BAUD_115200 0x0098 -#define IUU_CLK_3579000 3579000 -#define IUU_CLK_3680000 3680000 -#define IUU_CLK_6000000 6000000 -#define IUU_FULLCARD_IN 0x01 -#define IUU_DEV_ERROR 0x02 -#define IUU_MINICARD_IN 0x04 -#define IUU_VCC_5V 0x00 -#define IUU_VCC_3V 0x01 diff --git a/ANDROID_3.4.5/drivers/usb/serial/keyspan.c b/ANDROID_3.4.5/drivers/usb/serial/keyspan.c deleted file mode 100644 index a39ddd1b..00000000 --- a/ANDROID_3.4.5/drivers/usb/serial/keyspan.c +++ /dev/null @@ -1,2616 +0,0 @@ -/* - Keyspan USB to Serial Converter driver - - (C) Copyright (C) 2000-2001 Hugh Blemings <hugh@blemings.org> - (C) Copyright (C) 2002 Greg Kroah-Hartman <greg@kroah.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. - - See http://blemings.org/hugh/keyspan.html for more information. - - Code in this driver inspired by and in a number of places taken - from Brian Warner's original Keyspan-PDA driver. - - This driver has been put together with the support of Innosys, Inc. - and Keyspan, Inc the manufacturers of the Keyspan USB-serial products. - Thanks Guys :) - - Thanks to Paulus for miscellaneous tidy ups, some largish chunks - of much nicer and/or completely new code and (perhaps most uniquely) - having the patience to sit down and explain why and where he'd changed - stuff. - - Tip 'o the hat to IBM (and previously Linuxcare :) for supporting - staff in their work on open source projects. -*/ - - -#include <linux/kernel.h> -#include <linux/jiffies.h> -#include <linux/errno.h> -#include <linux/init.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/firmware.h> -#include <linux/ihex.h> -#include <linux/uaccess.h> -#include <linux/usb.h> -#include <linux/usb/serial.h> -#include "keyspan.h" - -static bool debug; - -/* - * Version Information - */ -#define DRIVER_VERSION "v1.1.5" -#define DRIVER_AUTHOR "Hugh Blemings <hugh@misc.nu" -#define DRIVER_DESC "Keyspan USB to Serial Converter Driver" - -#define INSTAT_BUFLEN 32 -#define GLOCONT_BUFLEN 64 -#define INDAT49W_BUFLEN 512 - - /* Per device and per port private data */ -struct keyspan_serial_private { - const struct keyspan_device_details *device_details; - - struct urb *instat_urb; - char instat_buf[INSTAT_BUFLEN]; - - /* added to support 49wg, where data from all 4 ports comes in - on 1 EP and high-speed supported */ - struct urb *indat_urb; - char indat_buf[INDAT49W_BUFLEN]; - - /* XXX this one probably will need a lock */ - struct urb *glocont_urb; - char glocont_buf[GLOCONT_BUFLEN]; - char ctrl_buf[8]; /* for EP0 control message */ -}; - -struct keyspan_port_private { - /* Keep track of which input & output endpoints to use */ - int in_flip; - int out_flip; - - /* Keep duplicate of device details in each port - structure as well - simplifies some of the - callback functions etc. */ - const struct keyspan_device_details *device_details; - - /* Input endpoints and buffer for this port */ - struct urb *in_urbs[2]; - char in_buffer[2][64]; - /* Output endpoints and buffer for this port */ - struct urb *out_urbs[2]; - char out_buffer[2][64]; - - /* Input ack endpoint */ - struct urb *inack_urb; - char inack_buffer[1]; - - /* Output control endpoint */ - struct urb *outcont_urb; - char outcont_buffer[64]; - - /* Settings for the port */ - int baud; - int old_baud; - unsigned int cflag; - unsigned int old_cflag; - enum {flow_none, flow_cts, flow_xon} flow_control; - int rts_state; /* Handshaking pins (outputs) */ - int dtr_state; - int cts_state; /* Handshaking pins (inputs) */ - int dsr_state; - int dcd_state; - int ri_state; - int break_on; - - unsigned long tx_start_time[2]; - int resend_cont; /* need to resend control packet */ -}; - -/* Include Keyspan message headers. All current Keyspan Adapters - make use of one of five message formats which are referred - to as USA-26, USA-28, USA-49, USA-90, USA-67 by Keyspan and - within this driver. */ -#include "keyspan_usa26msg.h" -#include "keyspan_usa28msg.h" -#include "keyspan_usa49msg.h" -#include "keyspan_usa90msg.h" -#include "keyspan_usa67msg.h" - - -module_usb_serial_driver(keyspan_driver, serial_drivers); - -static void keyspan_break_ctl(struct tty_struct *tty, int break_state) -{ - struct usb_serial_port *port = tty->driver_data; - struct keyspan_port_private *p_priv; - - dbg("%s", __func__); - - p_priv = usb_get_serial_port_data(port); - - if (break_state == -1) - p_priv->break_on = 1; - else - p_priv->break_on = 0; - - keyspan_send_setup(port, 0); -} - - -static void keyspan_set_termios(struct tty_struct *tty, - struct usb_serial_port *port, struct ktermios *old_termios) -{ - int baud_rate, device_port; - struct keyspan_port_private *p_priv; - const struct keyspan_device_details *d_details; - unsigned int cflag; - - dbg("%s", __func__); - - p_priv = usb_get_serial_port_data(port); - d_details = p_priv->device_details; - cflag = tty->termios->c_cflag; - device_port = port->number - port->serial->minor; - - /* Baud rate calculation takes baud rate as an integer - so other rates can be generated if desired. */ - baud_rate = tty_get_baud_rate(tty); - /* If no match or invalid, don't change */ - if (d_details->calculate_baud_rate(baud_rate, d_details->baudclk, - NULL, NULL, NULL, device_port) == KEYSPAN_BAUD_RATE_OK) { - /* FIXME - more to do here to ensure rate changes cleanly */ - /* FIXME - calcuate exact rate from divisor ? */ - p_priv->baud = baud_rate; - } else - baud_rate = tty_termios_baud_rate(old_termios); - - tty_encode_baud_rate(tty, baud_rate, baud_rate); - /* set CTS/RTS handshake etc. */ - p_priv->cflag = cflag; - p_priv->flow_control = (cflag & CRTSCTS)? flow_cts: flow_none; - - /* Mark/Space not supported */ - tty->termios->c_cflag &= ~CMSPAR; - - keyspan_send_setup(port, 0); -} - -static int keyspan_tiocmget(struct tty_struct *tty) -{ - struct usb_serial_port *port = tty->driver_data; - struct keyspan_port_private *p_priv = usb_get_serial_port_data(port); - unsigned int value; - - value = ((p_priv->rts_state) ? TIOCM_RTS : 0) | - ((p_priv->dtr_state) ? TIOCM_DTR : 0) | - ((p_priv->cts_state) ? TIOCM_CTS : 0) | - ((p_priv->dsr_state) ? TIOCM_DSR : 0) | - ((p_priv->dcd_state) ? TIOCM_CAR : 0) | - ((p_priv->ri_state) ? TIOCM_RNG : 0); - - return value; -} - -static int keyspan_tiocmset(struct tty_struct *tty, - unsigned int set, unsigned int clear) -{ - struct usb_serial_port *port = tty->driver_data; - struct keyspan_port_private *p_priv = usb_get_serial_port_data(port); - - if (set & TIOCM_RTS) - p_priv->rts_state = 1; - if (set & TIOCM_DTR) - p_priv->dtr_state = 1; - if (clear & TIOCM_RTS) - p_priv->rts_state = 0; - if (clear & TIOCM_DTR) - p_priv->dtr_state = 0; - keyspan_send_setup(port, 0); - return 0; -} - -/* Write function is similar for the four protocols used - with only a minor change for usa90 (usa19hs) required */ -static int keyspan_write(struct tty_struct *tty, - struct usb_serial_port *port, const unsigned char *buf, int count) -{ - struct keyspan_port_private *p_priv; - const struct keyspan_device_details *d_details; - int flip; - int left, todo; - struct urb *this_urb; - int err, maxDataLen, dataOffset; - - p_priv = usb_get_serial_port_data(port); - d_details = p_priv->device_details; - - if (d_details->msg_format == msg_usa90) { - maxDataLen = 64; - dataOffset = 0; - } else { - maxDataLen = 63; - dataOffset = 1; - } - - dbg("%s - for port %d (%d chars), flip=%d", - __func__, port->number, count, p_priv->out_flip); - - for (left = count; left > 0; left -= todo) { - todo = left; - if (todo > maxDataLen) - todo = maxDataLen; - - flip = p_priv->out_flip; - - /* Check we have a valid urb/endpoint before we use it... */ - this_urb = p_priv->out_urbs[flip]; - if (this_urb == NULL) { - /* no bulk out, so return 0 bytes written */ - dbg("%s - no output urb :(", __func__); - return count; - } - - dbg("%s - endpoint %d flip %d", - __func__, usb_pipeendpoint(this_urb->pipe), flip); - - if (this_urb->status == -EINPROGRESS) { - if (time_before(jiffies, - p_priv->tx_start_time[flip] + 10 * HZ)) - break; - usb_unlink_urb(this_urb); - break; - } - - /* First byte in buffer is "last flag" (except for usa19hx) - - unused so for now so set to zero */ - ((char *)this_urb->transfer_buffer)[0] = 0; - - memcpy(this_urb->transfer_buffer + dataOffset, buf, todo); - buf += todo; - - /* send the data out the bulk port */ - this_urb->transfer_buffer_length = todo + dataOffset; - - err = usb_submit_urb(this_urb, GFP_ATOMIC); - if (err != 0) - dbg("usb_submit_urb(write bulk) failed (%d)", err); - p_priv->tx_start_time[flip] = jiffies; - - /* Flip for next time if usa26 or usa28 interface - (not used on usa49) */ - p_priv->out_flip = (flip + 1) & d_details->outdat_endp_flip; - } - - return count - left; -} - -static void usa26_indat_callback(struct urb *urb) -{ - int i, err; - int endpoint; - struct usb_serial_port *port; - struct tty_struct *tty; - unsigned char *data = urb->transfer_buffer; - int status = urb->status; - - dbg("%s", __func__); - - endpoint = usb_pipeendpoint(urb->pipe); - - if (status) { - dbg("%s - nonzero status: %x on endpoint %d.", - __func__, status, endpoint); - return; - } - - port = urb->context; - tty = tty_port_tty_get(&port->port); - if (tty && urb->actual_length) { - /* 0x80 bit is error flag */ - if ((data[0] & 0x80) == 0) { - /* no errors on individual bytes, only - possible overrun err */ - if (data[0] & RXERROR_OVERRUN) - err = TTY_OVERRUN; - else - err = 0; - for (i = 1; i < urb->actual_length ; ++i) - tty_insert_flip_char(tty, data[i], err); - } else { - /* some bytes had errors, every byte has status */ - dbg("%s - RX error!!!!", __func__); - for (i = 0; i + 1 < urb->actual_length; i += 2) { - int stat = data[i], flag = 0; - if (stat & RXERROR_OVERRUN) - flag |= TTY_OVERRUN; - if (stat & RXERROR_FRAMING) - flag |= TTY_FRAME; - if (stat & RXERROR_PARITY) - flag |= TTY_PARITY; - /* XXX should handle break (0x10) */ - tty_insert_flip_char(tty, data[i+1], flag); - } - } - tty_flip_buffer_push(tty); - } - tty_kref_put(tty); - - /* Resubmit urb so we continue receiving */ - err = usb_submit_urb(urb, GFP_ATOMIC); - if (err != 0) - dbg("%s - resubmit read urb failed. (%d)", __func__, err); -} - -/* Outdat handling is common for all devices */ -static void usa2x_outdat_callback(struct urb *urb) -{ - struct usb_serial_port *port; - struct keyspan_port_private *p_priv; - - port = urb->context; - p_priv = usb_get_serial_port_data(port); - dbg("%s - urb %d", __func__, urb == p_priv->out_urbs[1]); - - usb_serial_port_softint(port); -} - -static void usa26_inack_callback(struct urb *urb) -{ - dbg("%s", __func__); - -} - -static void usa26_outcont_callback(struct urb *urb) -{ - struct usb_serial_port *port; - struct keyspan_port_private *p_priv; - - port = urb->context; - p_priv = usb_get_serial_port_data(port); - - if (p_priv->resend_cont) { - dbg("%s - sending setup", __func__); - keyspan_usa26_send_setup(port->serial, port, - p_priv->resend_cont - 1); - } -} - -static void usa26_instat_callback(struct urb *urb) -{ - unsigned char *data = urb->transfer_buffer; - struct keyspan_usa26_portStatusMessage *msg; - struct usb_serial *serial; - struct usb_serial_port *port; - struct keyspan_port_private *p_priv; - struct tty_struct *tty; - int old_dcd_state, err; - int status = urb->status; - - serial = urb->context; - - if (status) { - dbg("%s - nonzero status: %x", __func__, status); - return; - } - if (urb->actual_length != 9) { - dbg("%s - %d byte report??", __func__, urb->actual_length); - goto exit; - } - - msg = (struct keyspan_usa26_portStatusMessage *)data; - -#if 0 - dbg("%s - port status: port %d cts %d dcd %d dsr %d ri %d toff %d txoff %d rxen %d cr %d", - __func__, msg->port, msg->hskia_cts, msg->gpia_dcd, msg->dsr, msg->ri, msg->_txOff, - msg->_txXoff, msg->rxEnabled, msg->controlResponse); -#endif - - /* Now do something useful with the data */ - - - /* Check port number from message and retrieve private data */ - if (msg->port >= serial->num_ports) { - dbg("%s - Unexpected port number %d", __func__, msg->port); - goto exit; - } - port = serial->port[msg->port]; - p_priv = usb_get_serial_port_data(port); - - /* Update handshaking pin state information */ - old_dcd_state = p_priv->dcd_state; - p_priv->cts_state = ((msg->hskia_cts) ? 1 : 0); - p_priv->dsr_state = ((msg->dsr) ? 1 : 0); - p_priv->dcd_state = ((msg->gpia_dcd) ? 1 : 0); - p_priv->ri_state = ((msg->ri) ? 1 : 0); - - if (old_dcd_state != p_priv->dcd_state) { - tty = tty_port_tty_get(&port->port); - if (tty && !C_CLOCAL(tty)) - tty_hangup(tty); - tty_kref_put(tty); - } - - /* Resubmit urb so we continue receiving */ - err = usb_submit_urb(urb, GFP_ATOMIC); - if (err != 0) - dbg("%s - resubmit read urb failed. (%d)", __func__, err); -exit: ; -} - -static void usa26_glocont_callback(struct urb *urb) -{ - dbg("%s", __func__); -} - - -static void usa28_indat_callback(struct urb *urb) -{ - int err; - struct usb_serial_port *port; - struct tty_struct *tty; - unsigned char *data; - struct keyspan_port_private *p_priv; - int status = urb->status; - - dbg("%s", __func__); - - port = urb->context; - p_priv = usb_get_serial_port_data(port); - data = urb->transfer_buffer; - - if (urb != p_priv->in_urbs[p_priv->in_flip]) - return; - - do { - if (status) { - dbg("%s - nonzero status: %x on endpoint %d.", - __func__, status, usb_pipeendpoint(urb->pipe)); - return; - } - - port = urb->context; - p_priv = usb_get_serial_port_data(port); - data = urb->transfer_buffer; - - tty =tty_port_tty_get(&port->port); - if (tty && urb->actual_length) { - tty_insert_flip_string(tty, data, urb->actual_length); - tty_flip_buffer_push(tty); - } - tty_kref_put(tty); - - /* Resubmit urb so we continue receiving */ - err = usb_submit_urb(urb, GFP_ATOMIC); - if (err != 0) - dbg("%s - resubmit read urb failed. (%d)", - __func__, err); - p_priv->in_flip ^= 1; - - urb = p_priv->in_urbs[p_priv->in_flip]; - } while (urb->status != -EINPROGRESS); -} - -static void usa28_inack_callback(struct urb *urb) -{ - dbg("%s", __func__); -} - -static void usa28_outcont_callback(struct urb *urb) -{ - struct usb_serial_port *port; - struct keyspan_port_private *p_priv; - - port = urb->context; - p_priv = usb_get_serial_port_data(port); - - if (p_priv->resend_cont) { - dbg("%s - sending setup", __func__); - keyspan_usa28_send_setup(port->serial, port, - p_priv->resend_cont - 1); - } -} - -static void usa28_instat_callback(struct urb *urb) -{ - int err; - unsigned char *data = urb->transfer_buffer; - struct keyspan_usa28_portStatusMessage *msg; - struct usb_serial *serial; - struct usb_serial_port *port; - struct keyspan_port_private *p_priv; - struct tty_struct *tty; - int old_dcd_state; - int status = urb->status; - - serial = urb->context; - - if (status) { - dbg("%s - nonzero status: %x", __func__, status); - return; - } - - if (urb->actual_length != sizeof(struct keyspan_usa28_portStatusMessage)) { - dbg("%s - bad length %d", __func__, urb->actual_length); - goto exit; - } - - /*dbg("%s %x %x %x %x %x %x %x %x %x %x %x %x", __func__ - data[0], data[1], data[2], data[3], data[4], data[5], - data[6], data[7], data[8], data[9], data[10], data[11]);*/ - - /* Now do something useful with the data */ - msg = (struct keyspan_usa28_portStatusMessage *)data; - - /* Check port number from message and retrieve private data */ - if (msg->port >= serial->num_ports) { - dbg("%s - Unexpected port number %d", __func__, msg->port); - goto exit; - } - port = serial->port[msg->port]; - p_priv = usb_get_serial_port_data(port); - - /* Update handshaking pin state information */ - old_dcd_state = p_priv->dcd_state; - p_priv->cts_state = ((msg->cts) ? 1 : 0); - p_priv->dsr_state = ((msg->dsr) ? 1 : 0); - p_priv->dcd_state = ((msg->dcd) ? 1 : 0); - p_priv->ri_state = ((msg->ri) ? 1 : 0); - - if( old_dcd_state != p_priv->dcd_state && old_dcd_state) { - tty = tty_port_tty_get(&port->port); - if (tty && !C_CLOCAL(tty)) - tty_hangup(tty); - tty_kref_put(tty); - } - - /* Resubmit urb so we continue receiving */ - err = usb_submit_urb(urb, GFP_ATOMIC); - if (err != 0) - dbg("%s - resubmit read urb failed. (%d)", __func__, err); -exit: ; -} - -static void usa28_glocont_callback(struct urb *urb) -{ - dbg("%s", __func__); -} - - -static void usa49_glocont_callback(struct urb *urb) -{ - struct usb_serial *serial; - struct usb_serial_port *port; - struct keyspan_port_private *p_priv; - int i; - - dbg("%s", __func__); - - serial = urb->context; - for (i = 0; i < serial->num_ports; ++i) { - port = serial->port[i]; - p_priv = usb_get_serial_port_data(port); - - if (p_priv->resend_cont) { - dbg("%s - sending setup", __func__); - keyspan_usa49_send_setup(serial, port, - p_priv->resend_cont - 1); - break; - } - } -} - - /* This is actually called glostat in the Keyspan - doco */ -static void usa49_instat_callback(struct urb *urb) -{ - int err; - unsigned char *data = urb->transfer_buffer; - struct keyspan_usa49_portStatusMessage *msg; - struct usb_serial *serial; - struct usb_serial_port *port; - struct keyspan_port_private *p_priv; - int old_dcd_state; - int status = urb->status; - - dbg("%s", __func__); - - serial = urb->context; - - if (status) { - dbg("%s - nonzero status: %x", __func__, status); - return; - } - - if (urb->actual_length != - sizeof(struct keyspan_usa49_portStatusMessage)) { - dbg("%s - bad length %d", __func__, urb->actual_length); - goto exit; - } - - /*dbg(" %x %x %x %x %x %x %x %x %x %x %x", __func__, - data[0], data[1], data[2], data[3], data[4], data[5], - data[6], data[7], data[8], data[9], data[10]);*/ - - /* Now do something useful with the data */ - msg = (struct keyspan_usa49_portStatusMessage *)data; - - /* Check port number from message and retrieve private data */ - if (msg->portNumber >= serial->num_ports) { - dbg("%s - Unexpected port number %d", - __func__, msg->portNumber); - goto exit; - } - port = serial->port[msg->portNumber]; - p_priv = usb_get_serial_port_data(port); - - /* Update handshaking pin state information */ - old_dcd_state = p_priv->dcd_state; - p_priv->cts_state = ((msg->cts) ? 1 : 0); - p_priv->dsr_state = ((msg->dsr) ? 1 : 0); - p_priv->dcd_state = ((msg->dcd) ? 1 : 0); - p_priv->ri_state = ((msg->ri) ? 1 : 0); - - if (old_dcd_state != p_priv->dcd_state && old_dcd_state) { - struct tty_struct *tty = tty_port_tty_get(&port->port); - if (tty && !C_CLOCAL(tty)) - tty_hangup(tty); - tty_kref_put(tty); - } - - /* Resubmit urb so we continue receiving */ - err = usb_submit_urb(urb, GFP_ATOMIC); - if (err != 0) - dbg("%s - resubmit read urb failed. (%d)", __func__, err); -exit: ; -} - -static void usa49_inack_callback(struct urb *urb) -{ - dbg("%s", __func__); -} - -static void usa49_indat_callback(struct urb *urb) -{ - int i, err; - int endpoint; - struct usb_serial_port *port; - struct tty_struct *tty; - unsigned char *data = urb->transfer_buffer; - int status = urb->status; - - dbg("%s", __func__); - - endpoint = usb_pipeendpoint(urb->pipe); - - if (status) { - dbg("%s - nonzero status: %x on endpoint %d.", __func__, - status, endpoint); - return; - } - - port = urb->context; - tty = tty_port_tty_get(&port->port); - if (tty && urb->actual_length) { - /* 0x80 bit is error flag */ - if ((data[0] & 0x80) == 0) { - /* no error on any byte */ - tty_insert_flip_string(tty, data + 1, - urb->actual_length - 1); - } else { - /* some bytes had errors, every byte has status */ - for (i = 0; i + 1 < urb->actual_length; i += 2) { - int stat = data[i], flag = 0; - if (stat & RXERROR_OVERRUN) - flag |= TTY_OVERRUN; - if (stat & RXERROR_FRAMING) - flag |= TTY_FRAME; - if (stat & RXERROR_PARITY) - flag |= TTY_PARITY; - /* XXX should handle break (0x10) */ - tty_insert_flip_char(tty, data[i+1], flag); - } - } - tty_flip_buffer_push(tty); - } - tty_kref_put(tty); - - /* Resubmit urb so we continue receiving */ - err = usb_submit_urb(urb, GFP_ATOMIC); - if (err != 0) - dbg("%s - resubmit read urb failed. (%d)", __func__, err); -} - -static void usa49wg_indat_callback(struct urb *urb) -{ - int i, len, x, err; - struct usb_serial *serial; - struct usb_serial_port *port; - struct tty_struct *tty; - unsigned char *data = urb->transfer_buffer; - int status = urb->status; - - dbg("%s", __func__); - - serial = urb->context; - - if (status) { - dbg("%s - nonzero status: %x", __func__, status); - return; - } - - /* inbound data is in the form P#, len, status, data */ - i = 0; - len = 0; - - if (urb->actual_length) { - while (i < urb->actual_length) { - - /* Check port number from message*/ - if (data[i] >= serial->num_ports) { - dbg("%s - Unexpected port number %d", - __func__, data[i]); - return; - } - port = serial->port[data[i++]]; - tty = tty_port_tty_get(&port->port); - len = data[i++]; - - /* 0x80 bit is error flag */ - if ((data[i] & 0x80) == 0) { - /* no error on any byte */ - i++; - for (x = 1; x < len ; ++x) - tty_insert_flip_char(tty, data[i++], 0); - } else { - /* - * some bytes had errors, every byte has status - */ - for (x = 0; x + 1 < len; x += 2) { - int stat = data[i], flag = 0; - if (stat & RXERROR_OVERRUN) - flag |= TTY_OVERRUN; - if (stat & RXERROR_FRAMING) - flag |= TTY_FRAME; - if (stat & RXERROR_PARITY) - flag |= TTY_PARITY; - /* XXX should handle break (0x10) */ - tty_insert_flip_char(tty, - data[i+1], flag); - i += 2; - } - } - tty_flip_buffer_push(tty); - tty_kref_put(tty); - } - } - - /* Resubmit urb so we continue receiving */ - err = usb_submit_urb(urb, GFP_ATOMIC); - if (err != 0) - dbg("%s - resubmit read urb failed. (%d)", __func__, err); -} - -/* not used, usa-49 doesn't have per-port control endpoints */ -static void usa49_outcont_callback(struct urb *urb) -{ - dbg("%s", __func__); -} - -static void usa90_indat_callback(struct urb *urb) -{ - int i, err; - int endpoint; - struct usb_serial_port *port; - struct keyspan_port_private *p_priv; - struct tty_struct *tty; - unsigned char *data = urb->transfer_buffer; - int status = urb->status; - - dbg("%s", __func__); - - endpoint = usb_pipeendpoint(urb->pipe); - - if (status) { - dbg("%s - nonzero status: %x on endpoint %d.", - __func__, status, endpoint); - return; - } - - port = urb->context; - p_priv = usb_get_serial_port_data(port); - - if (urb->actual_length) { - tty = tty_port_tty_get(&port->port); - /* if current mode is DMA, looks like usa28 format - otherwise looks like usa26 data format */ - - if (p_priv->baud > 57600) - tty_insert_flip_string(tty, data, urb->actual_length); - else { - /* 0x80 bit is error flag */ - if ((data[0] & 0x80) == 0) { - /* no errors on individual bytes, only - possible overrun err*/ - if (data[0] & RXERROR_OVERRUN) - err = TTY_OVERRUN; - else - err = 0; - for (i = 1; i < urb->actual_length ; ++i) - tty_insert_flip_char(tty, data[i], - err); - } else { - /* some bytes had errors, every byte has status */ - dbg("%s - RX error!!!!", __func__); - for (i = 0; i + 1 < urb->actual_length; i += 2) { - int stat = data[i], flag = 0; - if (stat & RXERROR_OVERRUN) - flag |= TTY_OVERRUN; - if (stat & RXERROR_FRAMING) - flag |= TTY_FRAME; - if (stat & RXERROR_PARITY) - flag |= TTY_PARITY; - /* XXX should handle break (0x10) */ - tty_insert_flip_char(tty, data[i+1], - flag); - } - } - } - tty_flip_buffer_push(tty); - tty_kref_put(tty); - } - - /* Resubmit urb so we continue receiving */ - err = usb_submit_urb(urb, GFP_ATOMIC); - if (err != 0) - dbg("%s - resubmit read urb failed. (%d)", __func__, err); -} - - -static void usa90_instat_callback(struct urb *urb) -{ - unsigned char *data = urb->transfer_buffer; - struct keyspan_usa90_portStatusMessage *msg; - struct usb_serial *serial; - struct usb_serial_port *port; - struct keyspan_port_private *p_priv; - struct tty_struct *tty; - int old_dcd_state, err; - int status = urb->status; - - serial = urb->context; - - if (status) { - dbg("%s - nonzero status: %x", __func__, status); - return; - } - if (urb->actual_length < 14) { - dbg("%s - %d byte report??", __func__, urb->actual_length); - goto exit; - } - - msg = (struct keyspan_usa90_portStatusMessage *)data; - - /* Now do something useful with the data */ - - port = serial->port[0]; - p_priv = usb_get_serial_port_data(port); - - /* Update handshaking pin state information */ - old_dcd_state = p_priv->dcd_state; - p_priv->cts_state = ((msg->cts) ? 1 : 0); - p_priv->dsr_state = ((msg->dsr) ? 1 : 0); - p_priv->dcd_state = ((msg->dcd) ? 1 : 0); - p_priv->ri_state = ((msg->ri) ? 1 : 0); - - if (old_dcd_state != p_priv->dcd_state && old_dcd_state) { - tty = tty_port_tty_get(&port->port); - if (tty && !C_CLOCAL(tty)) - tty_hangup(tty); - tty_kref_put(tty); - } - - /* Resubmit urb so we continue receiving */ - err = usb_submit_urb(urb, GFP_ATOMIC); - if (err != 0) - dbg("%s - resubmit read urb failed. (%d)", __func__, err); -exit: - ; -} - -static void usa90_outcont_callback(struct urb *urb) -{ - struct usb_serial_port *port; - struct keyspan_port_private *p_priv; - - port = urb->context; - p_priv = usb_get_serial_port_data(port); - - if (p_priv->resend_cont) { - dbg("%s - sending setup", __func__); - keyspan_usa90_send_setup(port->serial, port, - p_priv->resend_cont - 1); - } -} - -/* Status messages from the 28xg */ -static void usa67_instat_callback(struct urb *urb) -{ - int err; - unsigned char *data = urb->transfer_buffer; - struct keyspan_usa67_portStatusMessage *msg; - struct usb_serial *serial; - struct usb_serial_port *port; - struct keyspan_port_private *p_priv; - int old_dcd_state; - int status = urb->status; - - dbg("%s", __func__); - - serial = urb->context; - - if (status) { - dbg("%s - nonzero status: %x", __func__, status); - return; - } - - if (urb->actual_length != - sizeof(struct keyspan_usa67_portStatusMessage)) { - dbg("%s - bad length %d", __func__, urb->actual_length); - return; - } - - - /* Now do something useful with the data */ - msg = (struct keyspan_usa67_portStatusMessage *)data; - - /* Check port number from message and retrieve private data */ - if (msg->port >= serial->num_ports) { - dbg("%s - Unexpected port number %d", __func__, msg->port); - return; - } - - port = serial->port[msg->port]; - p_priv = usb_get_serial_port_data(port); - - /* Update handshaking pin state information */ - old_dcd_state = p_priv->dcd_state; - p_priv->cts_state = ((msg->hskia_cts) ? 1 : 0); - p_priv->dcd_state = ((msg->gpia_dcd) ? 1 : 0); - - if (old_dcd_state != p_priv->dcd_state && old_dcd_state) { - struct tty_struct *tty = tty_port_tty_get(&port->port); - if (tty && !C_CLOCAL(tty)) - tty_hangup(tty); - tty_kref_put(tty); - } - - /* Resubmit urb so we continue receiving */ - err = usb_submit_urb(urb, GFP_ATOMIC); - if (err != 0) - dbg("%s - resubmit read urb failed. (%d)", __func__, err); -} - -static void usa67_glocont_callback(struct urb *urb) -{ - struct usb_serial *serial; - struct usb_serial_port *port; - struct keyspan_port_private *p_priv; - int i; - - dbg("%s", __func__); - - serial = urb->context; - for (i = 0; i < serial->num_ports; ++i) { - port = serial->port[i]; - p_priv = usb_get_serial_port_data(port); - - if (p_priv->resend_cont) { - dbg("%s - sending setup", __func__); - keyspan_usa67_send_setup(serial, port, - p_priv->resend_cont - 1); - break; - } - } -} - -static int keyspan_write_room(struct tty_struct *tty) -{ - struct usb_serial_port *port = tty->driver_data; - struct keyspan_port_private *p_priv; - const struct keyspan_device_details *d_details; - int flip; - int data_len; - struct urb *this_urb; - - dbg("%s", __func__); - p_priv = usb_get_serial_port_data(port); - d_details = p_priv->device_details; - - /* FIXME: locking */ - if (d_details->msg_format == msg_usa90) - data_len = 64; - else - data_len = 63; - - flip = p_priv->out_flip; - - /* Check both endpoints to see if any are available. */ - this_urb = p_priv->out_urbs[flip]; - if (this_urb != NULL) { - if (this_urb->status != -EINPROGRESS) - return data_len; - flip = (flip + 1) & d_details->outdat_endp_flip; - this_urb = p_priv->out_urbs[flip]; - if (this_urb != NULL) { - if (this_urb->status != -EINPROGRESS) - return data_len; - } - } - return 0; -} - - -static int keyspan_open(struct tty_struct *tty, struct usb_serial_port *port) -{ - struct keyspan_port_private *p_priv; - struct keyspan_serial_private *s_priv; - struct usb_serial *serial = port->serial; - const struct keyspan_device_details *d_details; - int i, err; - int baud_rate, device_port; - struct urb *urb; - unsigned int cflag = 0; - - s_priv = usb_get_serial_data(serial); - p_priv = usb_get_serial_port_data(port); - d_details = p_priv->device_details; - - dbg("%s - port%d.", __func__, port->number); - - /* Set some sane defaults */ - p_priv->rts_state = 1; - p_priv->dtr_state = 1; - p_priv->baud = 9600; - - /* force baud and lcr to be set on open */ - p_priv->old_baud = 0; - p_priv->old_cflag = 0; - - p_priv->out_flip = 0; - p_priv->in_flip = 0; - - /* Reset low level data toggle and start reading from endpoints */ - for (i = 0; i < 2; i++) { - urb = p_priv->in_urbs[i]; - if (urb == NULL) - continue; - - /* make sure endpoint data toggle is synchronized - with the device */ - usb_clear_halt(urb->dev, urb->pipe); - err = usb_submit_urb(urb, GFP_KERNEL); - if (err != 0) - dbg("%s - submit urb %d failed (%d)", - __func__, i, err); - } - - /* Reset low level data toggle on out endpoints */ - for (i = 0; i < 2; i++) { - urb = p_priv->out_urbs[i]; - if (urb == NULL) - continue; - /* usb_settoggle(urb->dev, usb_pipeendpoint(urb->pipe), - usb_pipeout(urb->pipe), 0); */ - } - - /* get the terminal config for the setup message now so we don't - * need to send 2 of them */ - - device_port = port->number - port->serial->minor; - if (tty) { - cflag = tty->termios->c_cflag; - /* Baud rate calculation takes baud rate as an integer - so other rates can be generated if desired. */ - baud_rate = tty_get_baud_rate(tty); - /* If no match or invalid, leave as default */ - if (baud_rate >= 0 - && d_details->calculate_baud_rate(baud_rate, d_details->baudclk, - NULL, NULL, NULL, device_port) == KEYSPAN_BAUD_RATE_OK) { - p_priv->baud = baud_rate; - } - } - /* set CTS/RTS handshake etc. */ - p_priv->cflag = cflag; - p_priv->flow_control = (cflag & CRTSCTS)? flow_cts: flow_none; - - keyspan_send_setup(port, 1); - /* mdelay(100); */ - /* keyspan_set_termios(port, NULL); */ - - return 0; -} - -static inline void stop_urb(struct urb *urb) -{ - if (urb && urb->status == -EINPROGRESS) - usb_kill_urb(urb); -} - -static void keyspan_dtr_rts(struct usb_serial_port *port, int on) -{ - struct keyspan_port_private *p_priv = usb_get_serial_port_data(port); - - p_priv->rts_state = on; - p_priv->dtr_state = on; - keyspan_send_setup(port, 0); -} - -static void keyspan_close(struct usb_serial_port *port) -{ - int i; - struct usb_serial *serial = port->serial; - struct keyspan_serial_private *s_priv; - struct keyspan_port_private *p_priv; - - dbg("%s", __func__); - s_priv = usb_get_serial_data(serial); - p_priv = usb_get_serial_port_data(port); - - p_priv->rts_state = 0; - p_priv->dtr_state = 0; - - if (serial->dev) { - keyspan_send_setup(port, 2); - /* pilot-xfer seems to work best with this delay */ - mdelay(100); - /* keyspan_set_termios(port, NULL); */ - } - - /*while (p_priv->outcont_urb->status == -EINPROGRESS) { - dbg("%s - urb in progress", __func__); - }*/ - - p_priv->out_flip = 0; - p_priv->in_flip = 0; - - if (serial->dev) { - /* Stop reading/writing urbs */ - stop_urb(p_priv->inack_urb); - /* stop_urb(p_priv->outcont_urb); */ - for (i = 0; i < 2; i++) { - stop_urb(p_priv->in_urbs[i]); - stop_urb(p_priv->out_urbs[i]); - } - } -} - -/* download the firmware to a pre-renumeration device */ -static int keyspan_fake_startup(struct usb_serial *serial) -{ - int response; - const struct ihex_binrec *record; - char *fw_name; - const struct firmware *fw; - - dbg("Keyspan startup version %04x product %04x", - le16_to_cpu(serial->dev->descriptor.bcdDevice), - le16_to_cpu(serial->dev->descriptor.idProduct)); - - if ((le16_to_cpu(serial->dev->descriptor.bcdDevice) & 0x8000) - != 0x8000) { - dbg("Firmware already loaded. Quitting."); - return 1; - } - - /* Select firmware image on the basis of idProduct */ - switch (le16_to_cpu(serial->dev->descriptor.idProduct)) { - case keyspan_usa28_pre_product_id: - fw_name = "keyspan/usa28.fw"; - break; - - case keyspan_usa28x_pre_product_id: - fw_name = "keyspan/usa28x.fw"; - break; - - case keyspan_usa28xa_pre_product_id: - fw_name = "keyspan/usa28xa.fw"; - break; - - case keyspan_usa28xb_pre_product_id: - fw_name = "keyspan/usa28xb.fw"; - break; - - case keyspan_usa19_pre_product_id: - fw_name = "keyspan/usa19.fw"; - break; - - case keyspan_usa19qi_pre_product_id: - fw_name = "keyspan/usa19qi.fw"; - break; - - case keyspan_mpr_pre_product_id: - fw_name = "keyspan/mpr.fw"; - break; - - case keyspan_usa19qw_pre_product_id: - fw_name = "keyspan/usa19qw.fw"; - break; - - case keyspan_usa18x_pre_product_id: - fw_name = "keyspan/usa18x.fw"; - break; - - case keyspan_usa19w_pre_product_id: - fw_name = "keyspan/usa19w.fw"; - break; - - case keyspan_usa49w_pre_product_id: - fw_name = "keyspan/usa49w.fw"; - break; - - case keyspan_usa49wlc_pre_product_id: - fw_name = "keyspan/usa49wlc.fw"; - break; - - default: - dev_err(&serial->dev->dev, "Unknown product ID (%04x)\n", - le16_to_cpu(serial->dev->descriptor.idProduct)); - return 1; - } - - if (request_ihex_firmware(&fw, fw_name, &serial->dev->dev)) { - dev_err(&serial->dev->dev, "Required keyspan firmware image (%s) unavailable.\n", fw_name); - return(1); - } - - dbg("Uploading Keyspan %s firmware.", fw_name); - - /* download the firmware image */ - response = ezusb_set_reset(serial, 1); - - record = (const struct ihex_binrec *)fw->data; - - while (record) { - response = ezusb_writememory(serial, be32_to_cpu(record->addr), - (unsigned char *)record->data, - be16_to_cpu(record->len), 0xa0); - if (response < 0) { - dev_err(&serial->dev->dev, "ezusb_writememory failed for Keyspan firmware (%d %04X %p %d)\n", - response, be32_to_cpu(record->addr), - record->data, be16_to_cpu(record->len)); - break; - } - record = ihex_next_binrec(record); - } - release_firmware(fw); - /* bring device out of reset. Renumeration will occur in a - moment and the new device will bind to the real driver */ - response = ezusb_set_reset(serial, 0); - - /* we don't want this device to have a driver assigned to it. */ - return 1; -} - -/* Helper functions used by keyspan_setup_urbs */ -static struct usb_endpoint_descriptor const *find_ep(struct usb_serial const *serial, - int endpoint) -{ - struct usb_host_interface *iface_desc; - struct usb_endpoint_descriptor *ep; - int i; - - iface_desc = serial->interface->cur_altsetting; - for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) { - ep = &iface_desc->endpoint[i].desc; - if (ep->bEndpointAddress == endpoint) - return ep; - } - dev_warn(&serial->interface->dev, "found no endpoint descriptor for " - "endpoint %x\n", endpoint); - return NULL; -} - -static struct urb *keyspan_setup_urb(struct usb_serial *serial, int endpoint, - int dir, void *ctx, char *buf, int len, - void (*callback)(struct urb *)) -{ - struct urb *urb; - struct usb_endpoint_descriptor const *ep_desc; - char const *ep_type_name; - - if (endpoint == -1) - return NULL; /* endpoint not needed */ - - dbg("%s - alloc for endpoint %d.", __func__, endpoint); - urb = usb_alloc_urb(0, GFP_KERNEL); /* No ISO */ - if (urb == NULL) { - dbg("%s - alloc for endpoint %d failed.", __func__, endpoint); - return NULL; - } - - if (endpoint == 0) { - /* control EP filled in when used */ - return urb; - } - - ep_desc = find_ep(serial, endpoint); - if (!ep_desc) { - /* leak the urb, something's wrong and the callers don't care */ - return urb; - } - if (usb_endpoint_xfer_int(ep_desc)) { - ep_type_name = "INT"; - usb_fill_int_urb(urb, serial->dev, - usb_sndintpipe(serial->dev, endpoint) | dir, - buf, len, callback, ctx, - ep_desc->bInterval); - } else if (usb_endpoint_xfer_bulk(ep_desc)) { - ep_type_name = "BULK"; - usb_fill_bulk_urb(urb, serial->dev, - usb_sndbulkpipe(serial->dev, endpoint) | dir, - buf, len, callback, ctx); - } else { - dev_warn(&serial->interface->dev, - "unsupported endpoint type %x\n", - usb_endpoint_type(ep_desc)); - usb_free_urb(urb); - return NULL; - } - - dbg("%s - using urb %p for %s endpoint %x", - __func__, urb, ep_type_name, endpoint); - return urb; -} - -static struct callbacks { - void (*instat_callback)(struct urb *); - void (*glocont_callback)(struct urb *); - void (*indat_callback)(struct urb *); - void (*outdat_callback)(struct urb *); - void (*inack_callback)(struct urb *); - void (*outcont_callback)(struct urb *); -} keyspan_callbacks[] = { - { - /* msg_usa26 callbacks */ - .instat_callback = usa26_instat_callback, - .glocont_callback = usa26_glocont_callback, - .indat_callback = usa26_indat_callback, - .outdat_callback = usa2x_outdat_callback, - .inack_callback = usa26_inack_callback, - .outcont_callback = usa26_outcont_callback, - }, { - /* msg_usa28 callbacks */ - .instat_callback = usa28_instat_callback, - .glocont_callback = usa28_glocont_callback, - .indat_callback = usa28_indat_callback, - .outdat_callback = usa2x_outdat_callback, - .inack_callback = usa28_inack_callback, - .outcont_callback = usa28_outcont_callback, - }, { - /* msg_usa49 callbacks */ - .instat_callback = usa49_instat_callback, - .glocont_callback = usa49_glocont_callback, - .indat_callback = usa49_indat_callback, - .outdat_callback = usa2x_outdat_callback, - .inack_callback = usa49_inack_callback, - .outcont_callback = usa49_outcont_callback, - }, { - /* msg_usa90 callbacks */ - .instat_callback = usa90_instat_callback, - .glocont_callback = usa28_glocont_callback, - .indat_callback = usa90_indat_callback, - .outdat_callback = usa2x_outdat_callback, - .inack_callback = usa28_inack_callback, - .outcont_callback = usa90_outcont_callback, - }, { - /* msg_usa67 callbacks */ - .instat_callback = usa67_instat_callback, - .glocont_callback = usa67_glocont_callback, - .indat_callback = usa26_indat_callback, - .outdat_callback = usa2x_outdat_callback, - .inack_callback = usa26_inack_callback, - .outcont_callback = usa26_outcont_callback, - } -}; - - /* Generic setup urbs function that uses - data in device_details */ -static void keyspan_setup_urbs(struct usb_serial *serial) -{ - int i, j; - struct keyspan_serial_private *s_priv; - const struct keyspan_device_details *d_details; - struct usb_serial_port *port; - struct keyspan_port_private *p_priv; - struct callbacks *cback; - int endp; - - dbg("%s", __func__); - - s_priv = usb_get_serial_data(serial); - d_details = s_priv->device_details; - - /* Setup values for the various callback routines */ - cback = &keyspan_callbacks[d_details->msg_format]; - - /* Allocate and set up urbs for each one that is in use, - starting with instat endpoints */ - s_priv->instat_urb = keyspan_setup_urb - (serial, d_details->instat_endpoint, USB_DIR_IN, - serial, s_priv->instat_buf, INSTAT_BUFLEN, - cback->instat_callback); - - s_priv->indat_urb = keyspan_setup_urb - (serial, d_details->indat_endpoint, USB_DIR_IN, - serial, s_priv->indat_buf, INDAT49W_BUFLEN, - usa49wg_indat_callback); - - s_priv->glocont_urb = keyspan_setup_urb - (serial, d_details->glocont_endpoint, USB_DIR_OUT, - serial, s_priv->glocont_buf, GLOCONT_BUFLEN, - cback->glocont_callback); - - /* Setup endpoints for each port specific thing */ - for (i = 0; i < d_details->num_ports; i++) { - port = serial->port[i]; - p_priv = usb_get_serial_port_data(port); - - /* Do indat endpoints first, once for each flip */ - endp = d_details->indat_endpoints[i]; - for (j = 0; j <= d_details->indat_endp_flip; ++j, ++endp) { - p_priv->in_urbs[j] = keyspan_setup_urb - (serial, endp, USB_DIR_IN, port, - p_priv->in_buffer[j], 64, - cback->indat_callback); - } - for (; j < 2; ++j) - p_priv->in_urbs[j] = NULL; - - /* outdat endpoints also have flip */ - endp = d_details->outdat_endpoints[i]; - for (j = 0; j <= d_details->outdat_endp_flip; ++j, ++endp) { - p_priv->out_urbs[j] = keyspan_setup_urb - (serial, endp, USB_DIR_OUT, port, - p_priv->out_buffer[j], 64, - cback->outdat_callback); - } - for (; j < 2; ++j) - p_priv->out_urbs[j] = NULL; - - /* inack endpoint */ - p_priv->inack_urb = keyspan_setup_urb - (serial, d_details->inack_endpoints[i], USB_DIR_IN, - port, p_priv->inack_buffer, 1, cback->inack_callback); - - /* outcont endpoint */ - p_priv->outcont_urb = keyspan_setup_urb - (serial, d_details->outcont_endpoints[i], USB_DIR_OUT, - port, p_priv->outcont_buffer, 64, - cback->outcont_callback); - } -} - -/* usa19 function doesn't require prescaler */ -static int keyspan_usa19_calc_baud(u32 baud_rate, u32 baudclk, u8 *rate_hi, - u8 *rate_low, u8 *prescaler, int portnum) -{ - u32 b16, /* baud rate times 16 (actual rate used internally) */ - div, /* divisor */ - cnt; /* inverse of divisor (programmed into 8051) */ - - dbg("%s - %d.", __func__, baud_rate); - - /* prevent divide by zero... */ - b16 = baud_rate * 16L; - if (b16 == 0) - return KEYSPAN_INVALID_BAUD_RATE; - /* Any "standard" rate over 57k6 is marginal on the USA-19 - as we run out of divisor resolution. */ - if (baud_rate > 57600) - return KEYSPAN_INVALID_BAUD_RATE; - - /* calculate the divisor and the counter (its inverse) */ - div = baudclk / b16; - if (div == 0) - return KEYSPAN_INVALID_BAUD_RATE; - else - cnt = 0 - div; - - if (div > 0xffff) - return KEYSPAN_INVALID_BAUD_RATE; - - /* return the counter values if non-null */ - if (rate_low) - *rate_low = (u8) (cnt & 0xff); - if (rate_hi) - *rate_hi = (u8) ((cnt >> 8) & 0xff); - if (rate_low && rate_hi) - dbg("%s - %d %02x %02x.", - __func__, baud_rate, *rate_hi, *rate_low); - return KEYSPAN_BAUD_RATE_OK; -} - -/* usa19hs function doesn't require prescaler */ -static int keyspan_usa19hs_calc_baud(u32 baud_rate, u32 baudclk, u8 *rate_hi, - u8 *rate_low, u8 *prescaler, int portnum) -{ - u32 b16, /* baud rate times 16 (actual rate used internally) */ - div; /* divisor */ - - dbg("%s - %d.", __func__, baud_rate); - - /* prevent divide by zero... */ - b16 = baud_rate * 16L; - if (b16 == 0) - return KEYSPAN_INVALID_BAUD_RATE; - - /* calculate the divisor */ - div = baudclk / b16; - if (div == 0) - return KEYSPAN_INVALID_BAUD_RATE; - - if (div > 0xffff) - return KEYSPAN_INVALID_BAUD_RATE; - - /* return the counter values if non-null */ - if (rate_low) - *rate_low = (u8) (div & 0xff); - - if (rate_hi) - *rate_hi = (u8) ((div >> 8) & 0xff); - - if (rate_low && rate_hi) - dbg("%s - %d %02x %02x.", - __func__, baud_rate, *rate_hi, *rate_low); - - return KEYSPAN_BAUD_RATE_OK; -} - -static int keyspan_usa19w_calc_baud(u32 baud_rate, u32 baudclk, u8 *rate_hi, - u8 *rate_low, u8 *prescaler, int portnum) -{ - u32 b16, /* baud rate times 16 (actual rate used internally) */ - clk, /* clock with 13/8 prescaler */ - div, /* divisor using 13/8 prescaler */ - res, /* resulting baud rate using 13/8 prescaler */ - diff, /* error using 13/8 prescaler */ - smallest_diff; - u8 best_prescaler; - int i; - - dbg("%s - %d.", __func__, baud_rate); - - /* prevent divide by zero */ - b16 = baud_rate * 16L; - if (b16 == 0) - return KEYSPAN_INVALID_BAUD_RATE; - - /* Calculate prescaler by trying them all and looking - for best fit */ - - /* start with largest possible difference */ - smallest_diff = 0xffffffff; - - /* 0 is an invalid prescaler, used as a flag */ - best_prescaler = 0; - - for (i = 8; i <= 0xff; ++i) { - clk = (baudclk * 8) / (u32) i; - - div = clk / b16; - if (div == 0) - continue; - - res = clk / div; - diff = (res > b16) ? (res-b16) : (b16-res); - - if (diff < smallest_diff) { - best_prescaler = i; - smallest_diff = diff; - } - } - - if (best_prescaler == 0) - return KEYSPAN_INVALID_BAUD_RATE; - - clk = (baudclk * 8) / (u32) best_prescaler; - div = clk / b16; - - /* return the divisor and prescaler if non-null */ - if (rate_low) - *rate_low = (u8) (div & 0xff); - if (rate_hi) - *rate_hi = (u8) ((div >> 8) & 0xff); - if (prescaler) { - *prescaler = best_prescaler; - /* dbg("%s - %d %d", __func__, *prescaler, div); */ - } - return KEYSPAN_BAUD_RATE_OK; -} - - /* USA-28 supports different maximum baud rates on each port */ -static int keyspan_usa28_calc_baud(u32 baud_rate, u32 baudclk, u8 *rate_hi, - u8 *rate_low, u8 *prescaler, int portnum) -{ - u32 b16, /* baud rate times 16 (actual rate used internally) */ - div, /* divisor */ - cnt; /* inverse of divisor (programmed into 8051) */ - - dbg("%s - %d.", __func__, baud_rate); - - /* prevent divide by zero */ - b16 = baud_rate * 16L; - if (b16 == 0) - return KEYSPAN_INVALID_BAUD_RATE; - - /* calculate the divisor and the counter (its inverse) */ - div = KEYSPAN_USA28_BAUDCLK / b16; - if (div == 0) - return KEYSPAN_INVALID_BAUD_RATE; - else - cnt = 0 - div; - - /* check for out of range, based on portnum, - and return result */ - if (portnum == 0) { - if (div > 0xffff) - return KEYSPAN_INVALID_BAUD_RATE; - } else { - if (portnum == 1) { - if (div > 0xff) - return KEYSPAN_INVALID_BAUD_RATE; - } else - return KEYSPAN_INVALID_BAUD_RATE; - } - - /* return the counter values if not NULL - (port 1 will ignore retHi) */ - if (rate_low) - *rate_low = (u8) (cnt & 0xff); - if (rate_hi) - *rate_hi = (u8) ((cnt >> 8) & 0xff); - dbg("%s - %d OK.", __func__, baud_rate); - return KEYSPAN_BAUD_RATE_OK; -} - -static int keyspan_usa26_send_setup(struct usb_serial *serial, - struct usb_serial_port *port, - int reset_port) -{ - struct keyspan_usa26_portControlMessage msg; - struct keyspan_serial_private *s_priv; - struct keyspan_port_private *p_priv; - const struct keyspan_device_details *d_details; - int outcont_urb; - struct urb *this_urb; - int device_port, err; - - dbg("%s reset=%d", __func__, reset_port); - - s_priv = usb_get_serial_data(serial); - p_priv = usb_get_serial_port_data(port); - d_details = s_priv->device_details; - device_port = port->number - port->serial->minor; - - outcont_urb = d_details->outcont_endpoints[port->number]; - this_urb = p_priv->outcont_urb; - - dbg("%s - endpoint %d", __func__, usb_pipeendpoint(this_urb->pipe)); - - /* Make sure we have an urb then send the message */ - if (this_urb == NULL) { - dbg("%s - oops no urb.", __func__); - return -1; - } - - /* Save reset port val for resend. - Don't overwrite resend for open/close condition. */ - if ((reset_port + 1) > p_priv->resend_cont) - p_priv->resend_cont = reset_port + 1; - if (this_urb->status == -EINPROGRESS) { - /* dbg("%s - already writing", __func__); */ - mdelay(5); - return -1; - } - - memset(&msg, 0, sizeof(struct keyspan_usa26_portControlMessage)); - - /* Only set baud rate if it's changed */ - if (p_priv->old_baud != p_priv->baud) { - p_priv->old_baud = p_priv->baud; - msg.setClocking = 0xff; - if (d_details->calculate_baud_rate - (p_priv->baud, d_details->baudclk, &msg.baudHi, - &msg.baudLo, &msg.prescaler, device_port) == KEYSPAN_INVALID_BAUD_RATE) { - dbg("%s - Invalid baud rate %d requested, using 9600.", - __func__, p_priv->baud); - msg.baudLo = 0; - msg.baudHi = 125; /* Values for 9600 baud */ - msg.prescaler = 10; - } - msg.setPrescaler = 0xff; - } - - msg.lcr = (p_priv->cflag & CSTOPB)? STOPBITS_678_2: STOPBITS_5678_1; - switch (p_priv->cflag & CSIZE) { - case CS5: - msg.lcr |= USA_DATABITS_5; - break; - case CS6: - msg.lcr |= USA_DATABITS_6; - break; - case CS7: - msg.lcr |= USA_DATABITS_7; - break; - case CS8: - msg.lcr |= USA_DATABITS_8; - break; - } - if (p_priv->cflag & PARENB) { - /* note USA_PARITY_NONE == 0 */ - msg.lcr |= (p_priv->cflag & PARODD)? - USA_PARITY_ODD : USA_PARITY_EVEN; - } - msg.setLcr = 0xff; - - msg.ctsFlowControl = (p_priv->flow_control == flow_cts); - msg.xonFlowControl = 0; - msg.setFlowControl = 0xff; - msg.forwardingLength = 16; - msg.xonChar = 17; - msg.xoffChar = 19; - - /* Opening port */ - if (reset_port == 1) { - msg._txOn = 1; - msg._txOff = 0; - msg.txFlush = 0; - msg.txBreak = 0; - msg.rxOn = 1; - msg.rxOff = 0; - msg.rxFlush = 1; - msg.rxForward = 0; - msg.returnStatus = 0; - msg.resetDataToggle = 0xff; - } - - /* Closing port */ - else if (reset_port == 2) { - msg._txOn = 0; - msg._txOff = 1; - msg.txFlush = 0; - msg.txBreak = 0; - msg.rxOn = 0; - msg.rxOff = 1; - msg.rxFlush = 1; - msg.rxForward = 0; - msg.returnStatus = 0; - msg.resetDataToggle = 0; - } - - /* Sending intermediate configs */ - else { - msg._txOn = (!p_priv->break_on); - msg._txOff = 0; - msg.txFlush = 0; - msg.txBreak = (p_priv->break_on); - msg.rxOn = 0; - msg.rxOff = 0; - msg.rxFlush = 0; - msg.rxForward = 0; - msg.returnStatus = 0; - msg.resetDataToggle = 0x0; - } - - /* Do handshaking outputs */ - msg.setTxTriState_setRts = 0xff; - msg.txTriState_rts = p_priv->rts_state; - - msg.setHskoa_setDtr = 0xff; - msg.hskoa_dtr = p_priv->dtr_state; - - p_priv->resend_cont = 0; - memcpy(this_urb->transfer_buffer, &msg, sizeof(msg)); - - /* send the data out the device on control endpoint */ - this_urb->transfer_buffer_length = sizeof(msg); - - err = usb_submit_urb(this_urb, GFP_ATOMIC); - if (err != 0) - dbg("%s - usb_submit_urb(setup) failed (%d)", __func__, err); -#if 0 - else { - dbg("%s - usb_submit_urb(%d) OK %d bytes (end %d)", __func__ - outcont_urb, this_urb->transfer_buffer_length, - usb_pipeendpoint(this_urb->pipe)); - } -#endif - - return 0; -} - -static int keyspan_usa28_send_setup(struct usb_serial *serial, - struct usb_serial_port *port, - int reset_port) -{ - struct keyspan_usa28_portControlMessage msg; - struct keyspan_serial_private *s_priv; - struct keyspan_port_private *p_priv; - const struct keyspan_device_details *d_details; - struct urb *this_urb; - int device_port, err; - - dbg("%s", __func__); - - s_priv = usb_get_serial_data(serial); - p_priv = usb_get_serial_port_data(port); - d_details = s_priv->device_details; - device_port = port->number - port->serial->minor; - - /* only do something if we have a bulk out endpoint */ - this_urb = p_priv->outcont_urb; - if (this_urb == NULL) { - dbg("%s - oops no urb.", __func__); - return -1; - } - - /* Save reset port val for resend. - Don't overwrite resend for open/close condition. */ - if ((reset_port + 1) > p_priv->resend_cont) - p_priv->resend_cont = reset_port + 1; - if (this_urb->status == -EINPROGRESS) { - dbg("%s already writing", __func__); - mdelay(5); - return -1; - } - - memset(&msg, 0, sizeof(struct keyspan_usa28_portControlMessage)); - - msg.setBaudRate = 1; - if (d_details->calculate_baud_rate(p_priv->baud, d_details->baudclk, - &msg.baudHi, &msg.baudLo, NULL, device_port) == KEYSPAN_INVALID_BAUD_RATE) { - dbg("%s - Invalid baud rate requested %d.", - __func__, p_priv->baud); - msg.baudLo = 0xff; - msg.baudHi = 0xb2; /* Values for 9600 baud */ - } - - /* If parity is enabled, we must calculate it ourselves. */ - msg.parity = 0; /* XXX for now */ - - msg.ctsFlowControl = (p_priv->flow_control == flow_cts); - msg.xonFlowControl = 0; - - /* Do handshaking outputs, DTR is inverted relative to RTS */ - msg.rts = p_priv->rts_state; - msg.dtr = p_priv->dtr_state; - - msg.forwardingLength = 16; - msg.forwardMs = 10; - msg.breakThreshold = 45; - msg.xonChar = 17; - msg.xoffChar = 19; - - /*msg.returnStatus = 1; - msg.resetDataToggle = 0xff;*/ - /* Opening port */ - if (reset_port == 1) { - msg._txOn = 1; - msg._txOff = 0; - msg.txFlush = 0; - msg.txForceXoff = 0; - msg.txBreak = 0; - msg.rxOn = 1; - msg.rxOff = 0; - msg.rxFlush = 1; - msg.rxForward = 0; - msg.returnStatus = 0; - msg.resetDataToggle = 0xff; - } - /* Closing port */ - else if (reset_port == 2) { - msg._txOn = 0; - msg._txOff = 1; - msg.txFlush = 0; - msg.txForceXoff = 0; - msg.txBreak = 0; - msg.rxOn = 0; - msg.rxOff = 1; - msg.rxFlush = 1; - msg.rxForward = 0; - msg.returnStatus = 0; - msg.resetDataToggle = 0; - } - /* Sending intermediate configs */ - else { - msg._txOn = (!p_priv->break_on); - msg._txOff = 0; - msg.txFlush = 0; - msg.txForceXoff = 0; - msg.txBreak = (p_priv->break_on); - msg.rxOn = 0; - msg.rxOff = 0; - msg.rxFlush = 0; - msg.rxForward = 0; - msg.returnStatus = 0; - msg.resetDataToggle = 0x0; - } - - p_priv->resend_cont = 0; - memcpy(this_urb->transfer_buffer, &msg, sizeof(msg)); - - /* send the data out the device on control endpoint */ - this_urb->transfer_buffer_length = sizeof(msg); - - err = usb_submit_urb(this_urb, GFP_ATOMIC); - if (err != 0) - dbg("%s - usb_submit_urb(setup) failed", __func__); -#if 0 - else { - dbg("%s - usb_submit_urb(setup) OK %d bytes", __func__, - this_urb->transfer_buffer_length); - } -#endif - - return 0; -} - -static int keyspan_usa49_send_setup(struct usb_serial *serial, - struct usb_serial_port *port, - int reset_port) -{ - struct keyspan_usa49_portControlMessage msg; - struct usb_ctrlrequest *dr = NULL; - struct keyspan_serial_private *s_priv; - struct keyspan_port_private *p_priv; - const struct keyspan_device_details *d_details; - struct urb *this_urb; - int err, device_port; - - dbg("%s", __func__); - - s_priv = usb_get_serial_data(serial); - p_priv = usb_get_serial_port_data(port); - d_details = s_priv->device_details; - - this_urb = s_priv->glocont_urb; - - /* Work out which port within the device is being setup */ - device_port = port->number - port->serial->minor; - - /* Make sure we have an urb then send the message */ - if (this_urb == NULL) { - dbg("%s - oops no urb for port %d.", __func__, port->number); - return -1; - } - - dbg("%s - endpoint %d port %d (%d)", - __func__, usb_pipeendpoint(this_urb->pipe), - port->number, device_port); - - /* Save reset port val for resend. - Don't overwrite resend for open/close condition. */ - if ((reset_port + 1) > p_priv->resend_cont) - p_priv->resend_cont = reset_port + 1; - - if (this_urb->status == -EINPROGRESS) { - /* dbg("%s - already writing", __func__); */ - mdelay(5); - return -1; - } - - memset(&msg, 0, sizeof(struct keyspan_usa49_portControlMessage)); - - /*msg.portNumber = port->number;*/ - msg.portNumber = device_port; - - /* Only set baud rate if it's changed */ - if (p_priv->old_baud != p_priv->baud) { - p_priv->old_baud = p_priv->baud; - msg.setClocking = 0xff; - if (d_details->calculate_baud_rate - (p_priv->baud, d_details->baudclk, &msg.baudHi, - &msg.baudLo, &msg.prescaler, device_port) == KEYSPAN_INVALID_BAUD_RATE) { - dbg("%s - Invalid baud rate %d requested, using 9600.", - __func__, p_priv->baud); - msg.baudLo = 0; - msg.baudHi = 125; /* Values for 9600 baud */ - msg.prescaler = 10; - } - /* msg.setPrescaler = 0xff; */ - } - - msg.lcr = (p_priv->cflag & CSTOPB)? STOPBITS_678_2: STOPBITS_5678_1; - switch (p_priv->cflag & CSIZE) { - case CS5: - msg.lcr |= USA_DATABITS_5; - break; - case CS6: - msg.lcr |= USA_DATABITS_6; - break; - case CS7: - msg.lcr |= USA_DATABITS_7; - break; - case CS8: - msg.lcr |= USA_DATABITS_8; - break; - } - if (p_priv->cflag & PARENB) { - /* note USA_PARITY_NONE == 0 */ - msg.lcr |= (p_priv->cflag & PARODD)? - USA_PARITY_ODD : USA_PARITY_EVEN; - } - msg.setLcr = 0xff; - - msg.ctsFlowControl = (p_priv->flow_control == flow_cts); - msg.xonFlowControl = 0; - msg.setFlowControl = 0xff; - - msg.forwardingLength = 16; - msg.xonChar = 17; - msg.xoffChar = 19; - - /* Opening port */ - if (reset_port == 1) { - msg._txOn = 1; - msg._txOff = 0; - msg.txFlush = 0; - msg.txBreak = 0; - msg.rxOn = 1; - msg.rxOff = 0; - msg.rxFlush = 1; - msg.rxForward = 0; - msg.returnStatus = 0; - msg.resetDataToggle = 0xff; - msg.enablePort = 1; - msg.disablePort = 0; - } - /* Closing port */ - else if (reset_port == 2) { - msg._txOn = 0; - msg._txOff = 1; - msg.txFlush = 0; - msg.txBreak = 0; - msg.rxOn = 0; - msg.rxOff = 1; - msg.rxFlush = 1; - msg.rxForward = 0; - msg.returnStatus = 0; - msg.resetDataToggle = 0; - msg.enablePort = 0; - msg.disablePort = 1; - } - /* Sending intermediate configs */ - else { - msg._txOn = (!p_priv->break_on); - msg._txOff = 0; - msg.txFlush = 0; - msg.txBreak = (p_priv->break_on); - msg.rxOn = 0; - msg.rxOff = 0; - msg.rxFlush = 0; - msg.rxForward = 0; - msg.returnStatus = 0; - msg.resetDataToggle = 0x0; - msg.enablePort = 0; - msg.disablePort = 0; - } - - /* Do handshaking outputs */ - msg.setRts = 0xff; - msg.rts = p_priv->rts_state; - - msg.setDtr = 0xff; - msg.dtr = p_priv->dtr_state; - - p_priv->resend_cont = 0; - - /* if the device is a 49wg, we send control message on usb - control EP 0 */ - - if (d_details->product_id == keyspan_usa49wg_product_id) { - dr = (void *)(s_priv->ctrl_buf); - dr->bRequestType = USB_TYPE_VENDOR | USB_DIR_OUT; - dr->bRequest = 0xB0; /* 49wg control message */; - dr->wValue = 0; - dr->wIndex = 0; - dr->wLength = cpu_to_le16(sizeof(msg)); - - memcpy(s_priv->glocont_buf, &msg, sizeof(msg)); - - usb_fill_control_urb(this_urb, serial->dev, - usb_sndctrlpipe(serial->dev, 0), - (unsigned char *)dr, s_priv->glocont_buf, - sizeof(msg), usa49_glocont_callback, serial); - - } else { - memcpy(this_urb->transfer_buffer, &msg, sizeof(msg)); - - /* send the data out the device on control endpoint */ - this_urb->transfer_buffer_length = sizeof(msg); - } - err = usb_submit_urb(this_urb, GFP_ATOMIC); - if (err != 0) - dbg("%s - usb_submit_urb(setup) failed (%d)", __func__, err); -#if 0 - else { - dbg("%s - usb_submit_urb(%d) OK %d bytes (end %d)", __func__, - outcont_urb, this_urb->transfer_buffer_length, - usb_pipeendpoint(this_urb->pipe)); - } -#endif - - return 0; -} - -static int keyspan_usa90_send_setup(struct usb_serial *serial, - struct usb_serial_port *port, - int reset_port) -{ - struct keyspan_usa90_portControlMessage msg; - struct keyspan_serial_private *s_priv; - struct keyspan_port_private *p_priv; - const struct keyspan_device_details *d_details; - struct urb *this_urb; - int err; - u8 prescaler; - - dbg("%s", __func__); - - s_priv = usb_get_serial_data(serial); - p_priv = usb_get_serial_port_data(port); - d_details = s_priv->device_details; - - /* only do something if we have a bulk out endpoint */ - this_urb = p_priv->outcont_urb; - if (this_urb == NULL) { - dbg("%s - oops no urb.", __func__); - return -1; - } - - /* Save reset port val for resend. - Don't overwrite resend for open/close condition. */ - if ((reset_port + 1) > p_priv->resend_cont) - p_priv->resend_cont = reset_port + 1; - if (this_urb->status == -EINPROGRESS) { - dbg("%s already writing", __func__); - mdelay(5); - return -1; - } - - memset(&msg, 0, sizeof(struct keyspan_usa90_portControlMessage)); - - /* Only set baud rate if it's changed */ - if (p_priv->old_baud != p_priv->baud) { - p_priv->old_baud = p_priv->baud; - msg.setClocking = 0x01; - if (d_details->calculate_baud_rate - (p_priv->baud, d_details->baudclk, &msg.baudHi, - &msg.baudLo, &prescaler, 0) == KEYSPAN_INVALID_BAUD_RATE) { - dbg("%s - Invalid baud rate %d requested, using 9600.", - __func__, p_priv->baud); - p_priv->baud = 9600; - d_details->calculate_baud_rate(p_priv->baud, d_details->baudclk, - &msg.baudHi, &msg.baudLo, &prescaler, 0); - } - msg.setRxMode = 1; - msg.setTxMode = 1; - } - - /* modes must always be correctly specified */ - if (p_priv->baud > 57600) { - msg.rxMode = RXMODE_DMA; - msg.txMode = TXMODE_DMA; - } else { - msg.rxMode = RXMODE_BYHAND; - msg.txMode = TXMODE_BYHAND; - } - - msg.lcr = (p_priv->cflag & CSTOPB)? STOPBITS_678_2: STOPBITS_5678_1; - switch (p_priv->cflag & CSIZE) { - case CS5: - msg.lcr |= USA_DATABITS_5; - break; - case CS6: - msg.lcr |= USA_DATABITS_6; - break; - case CS7: - msg.lcr |= USA_DATABITS_7; - break; - case CS8: - msg.lcr |= USA_DATABITS_8; - break; - } - if (p_priv->cflag & PARENB) { - /* note USA_PARITY_NONE == 0 */ - msg.lcr |= (p_priv->cflag & PARODD)? - USA_PARITY_ODD : USA_PARITY_EVEN; - } - if (p_priv->old_cflag != p_priv->cflag) { - p_priv->old_cflag = p_priv->cflag; - msg.setLcr = 0x01; - } - - if (p_priv->flow_control == flow_cts) - msg.txFlowControl = TXFLOW_CTS; - msg.setTxFlowControl = 0x01; - msg.setRxFlowControl = 0x01; - - msg.rxForwardingLength = 16; - msg.rxForwardingTimeout = 16; - msg.txAckSetting = 0; - msg.xonChar = 17; - msg.xoffChar = 19; - - /* Opening port */ - if (reset_port == 1) { - msg.portEnabled = 1; - msg.rxFlush = 1; - msg.txBreak = (p_priv->break_on); - } - /* Closing port */ - else if (reset_port == 2) - msg.portEnabled = 0; - /* Sending intermediate configs */ - else { - msg.portEnabled = 1; - msg.txBreak = (p_priv->break_on); - } - - /* Do handshaking outputs */ - msg.setRts = 0x01; - msg.rts = p_priv->rts_state; - - msg.setDtr = 0x01; - msg.dtr = p_priv->dtr_state; - - p_priv->resend_cont = 0; - memcpy(this_urb->transfer_buffer, &msg, sizeof(msg)); - - /* send the data out the device on control endpoint */ - this_urb->transfer_buffer_length = sizeof(msg); - - err = usb_submit_urb(this_urb, GFP_ATOMIC); - if (err != 0) - dbg("%s - usb_submit_urb(setup) failed (%d)", __func__, err); - return 0; -} - -static int keyspan_usa67_send_setup(struct usb_serial *serial, - struct usb_serial_port *port, - int reset_port) -{ - struct keyspan_usa67_portControlMessage msg; - struct keyspan_serial_private *s_priv; - struct keyspan_port_private *p_priv; - const struct keyspan_device_details *d_details; - struct urb *this_urb; - int err, device_port; - - dbg("%s", __func__); - - s_priv = usb_get_serial_data(serial); - p_priv = usb_get_serial_port_data(port); - d_details = s_priv->device_details; - - this_urb = s_priv->glocont_urb; - - /* Work out which port within the device is being setup */ - device_port = port->number - port->serial->minor; - - /* Make sure we have an urb then send the message */ - if (this_urb == NULL) { - dbg("%s - oops no urb for port %d.", __func__, - port->number); - return -1; - } - - /* Save reset port val for resend. - Don't overwrite resend for open/close condition. */ - if ((reset_port + 1) > p_priv->resend_cont) - p_priv->resend_cont = reset_port + 1; - if (this_urb->status == -EINPROGRESS) { - /* dbg("%s - already writing", __func__); */ - mdelay(5); - return -1; - } - - memset(&msg, 0, sizeof(struct keyspan_usa67_portControlMessage)); - - msg.port = device_port; - - /* Only set baud rate if it's changed */ - if (p_priv->old_baud != p_priv->baud) { - p_priv->old_baud = p_priv->baud; - msg.setClocking = 0xff; - if (d_details->calculate_baud_rate - (p_priv->baud, d_details->baudclk, &msg.baudHi, - &msg.baudLo, &msg.prescaler, device_port) == KEYSPAN_INVALID_BAUD_RATE) { - dbg("%s - Invalid baud rate %d requested, using 9600.", - __func__, p_priv->baud); - msg.baudLo = 0; - msg.baudHi = 125; /* Values for 9600 baud */ - msg.prescaler = 10; - } - msg.setPrescaler = 0xff; - } - - msg.lcr = (p_priv->cflag & CSTOPB) ? STOPBITS_678_2 : STOPBITS_5678_1; - switch (p_priv->cflag & CSIZE) { - case CS5: - msg.lcr |= USA_DATABITS_5; - break; - case CS6: - msg.lcr |= USA_DATABITS_6; - break; - case CS7: - msg.lcr |= USA_DATABITS_7; - break; - case CS8: - msg.lcr |= USA_DATABITS_8; - break; - } - if (p_priv->cflag & PARENB) { - /* note USA_PARITY_NONE == 0 */ - msg.lcr |= (p_priv->cflag & PARODD)? - USA_PARITY_ODD : USA_PARITY_EVEN; - } - msg.setLcr = 0xff; - - msg.ctsFlowControl = (p_priv->flow_control == flow_cts); - msg.xonFlowControl = 0; - msg.setFlowControl = 0xff; - msg.forwardingLength = 16; - msg.xonChar = 17; - msg.xoffChar = 19; - - if (reset_port == 1) { - /* Opening port */ - msg._txOn = 1; - msg._txOff = 0; - msg.txFlush = 0; - msg.txBreak = 0; - msg.rxOn = 1; - msg.rxOff = 0; - msg.rxFlush = 1; - msg.rxForward = 0; - msg.returnStatus = 0; - msg.resetDataToggle = 0xff; - } else if (reset_port == 2) { - /* Closing port */ - msg._txOn = 0; - msg._txOff = 1; - msg.txFlush = 0; - msg.txBreak = 0; - msg.rxOn = 0; - msg.rxOff = 1; - msg.rxFlush = 1; - msg.rxForward = 0; - msg.returnStatus = 0; - msg.resetDataToggle = 0; - } else { - /* Sending intermediate configs */ - msg._txOn = (!p_priv->break_on); - msg._txOff = 0; - msg.txFlush = 0; - msg.txBreak = (p_priv->break_on); - msg.rxOn = 0; - msg.rxOff = 0; - msg.rxFlush = 0; - msg.rxForward = 0; - msg.returnStatus = 0; - msg.resetDataToggle = 0x0; - } - - /* Do handshaking outputs */ - msg.setTxTriState_setRts = 0xff; - msg.txTriState_rts = p_priv->rts_state; - - msg.setHskoa_setDtr = 0xff; - msg.hskoa_dtr = p_priv->dtr_state; - - p_priv->resend_cont = 0; - - memcpy(this_urb->transfer_buffer, &msg, sizeof(msg)); - - /* send the data out the device on control endpoint */ - this_urb->transfer_buffer_length = sizeof(msg); - - err = usb_submit_urb(this_urb, GFP_ATOMIC); - if (err != 0) - dbg("%s - usb_submit_urb(setup) failed (%d)", __func__, - err); - return 0; -} - -static void keyspan_send_setup(struct usb_serial_port *port, int reset_port) -{ - struct usb_serial *serial = port->serial; - struct keyspan_serial_private *s_priv; - const struct keyspan_device_details *d_details; - - dbg("%s", __func__); - - s_priv = usb_get_serial_data(serial); - d_details = s_priv->device_details; - - switch (d_details->msg_format) { - case msg_usa26: - keyspan_usa26_send_setup(serial, port, reset_port); - break; - case msg_usa28: - keyspan_usa28_send_setup(serial, port, reset_port); - break; - case msg_usa49: - keyspan_usa49_send_setup(serial, port, reset_port); - break; - case msg_usa90: - keyspan_usa90_send_setup(serial, port, reset_port); - break; - case msg_usa67: - keyspan_usa67_send_setup(serial, port, reset_port); - break; - } -} - - -/* Gets called by the "real" driver (ie once firmware is loaded - and renumeration has taken place. */ -static int keyspan_startup(struct usb_serial *serial) -{ - int i, err; - struct usb_serial_port *port; - struct keyspan_serial_private *s_priv; - struct keyspan_port_private *p_priv; - const struct keyspan_device_details *d_details; - - dbg("%s", __func__); - - for (i = 0; (d_details = keyspan_devices[i]) != NULL; ++i) - if (d_details->product_id == - le16_to_cpu(serial->dev->descriptor.idProduct)) - break; - if (d_details == NULL) { - dev_err(&serial->dev->dev, "%s - unknown product id %x\n", - __func__, le16_to_cpu(serial->dev->descriptor.idProduct)); - return 1; - } - - /* Setup private data for serial driver */ - s_priv = kzalloc(sizeof(struct keyspan_serial_private), GFP_KERNEL); - if (!s_priv) { - dbg("%s - kmalloc for keyspan_serial_private failed.", - __func__); - return -ENOMEM; - } - - s_priv->device_details = d_details; - usb_set_serial_data(serial, s_priv); - - /* Now setup per port private data */ - for (i = 0; i < serial->num_ports; i++) { - port = serial->port[i]; - p_priv = kzalloc(sizeof(struct keyspan_port_private), - GFP_KERNEL); - if (!p_priv) { - dbg("%s - kmalloc for keyspan_port_private (%d) failed!.", __func__, i); - return 1; - } - p_priv->device_details = d_details; - usb_set_serial_port_data(port, p_priv); - } - - keyspan_setup_urbs(serial); - - if (s_priv->instat_urb != NULL) { - err = usb_submit_urb(s_priv->instat_urb, GFP_KERNEL); - if (err != 0) - dbg("%s - submit instat urb failed %d", __func__, - err); - } - if (s_priv->indat_urb != NULL) { - err = usb_submit_urb(s_priv->indat_urb, GFP_KERNEL); - if (err != 0) - dbg("%s - submit indat urb failed %d", __func__, - err); - } - - return 0; -} - -static void keyspan_disconnect(struct usb_serial *serial) -{ - int i, j; - struct usb_serial_port *port; - struct keyspan_serial_private *s_priv; - struct keyspan_port_private *p_priv; - - dbg("%s", __func__); - - s_priv = usb_get_serial_data(serial); - - /* Stop reading/writing urbs */ - stop_urb(s_priv->instat_urb); - stop_urb(s_priv->glocont_urb); - stop_urb(s_priv->indat_urb); - for (i = 0; i < serial->num_ports; ++i) { - port = serial->port[i]; - p_priv = usb_get_serial_port_data(port); - stop_urb(p_priv->inack_urb); - stop_urb(p_priv->outcont_urb); - for (j = 0; j < 2; j++) { - stop_urb(p_priv->in_urbs[j]); - stop_urb(p_priv->out_urbs[j]); - } - } - - /* Now free them */ - usb_free_urb(s_priv->instat_urb); - usb_free_urb(s_priv->indat_urb); - usb_free_urb(s_priv->glocont_urb); - for (i = 0; i < serial->num_ports; ++i) { - port = serial->port[i]; - p_priv = usb_get_serial_port_data(port); - usb_free_urb(p_priv->inack_urb); - usb_free_urb(p_priv->outcont_urb); - for (j = 0; j < 2; j++) { - usb_free_urb(p_priv->in_urbs[j]); - usb_free_urb(p_priv->out_urbs[j]); - } - } -} - -static void keyspan_release(struct usb_serial *serial) -{ - int i; - struct usb_serial_port *port; - struct keyspan_serial_private *s_priv; - - dbg("%s", __func__); - - s_priv = usb_get_serial_data(serial); - - /* dbg("Freeing serial->private."); */ - kfree(s_priv); - - /* dbg("Freeing port->private."); */ - /* Now free per port private data */ - for (i = 0; i < serial->num_ports; i++) { - port = serial->port[i]; - kfree(usb_get_serial_port_data(port)); - } -} - -MODULE_AUTHOR(DRIVER_AUTHOR); -MODULE_DESCRIPTION(DRIVER_DESC); -MODULE_LICENSE("GPL"); - -MODULE_FIRMWARE("keyspan/usa28.fw"); -MODULE_FIRMWARE("keyspan/usa28x.fw"); -MODULE_FIRMWARE("keyspan/usa28xa.fw"); -MODULE_FIRMWARE("keyspan/usa28xb.fw"); -MODULE_FIRMWARE("keyspan/usa19.fw"); -MODULE_FIRMWARE("keyspan/usa19qi.fw"); -MODULE_FIRMWARE("keyspan/mpr.fw"); -MODULE_FIRMWARE("keyspan/usa19qw.fw"); -MODULE_FIRMWARE("keyspan/usa18x.fw"); -MODULE_FIRMWARE("keyspan/usa19w.fw"); -MODULE_FIRMWARE("keyspan/usa49w.fw"); -MODULE_FIRMWARE("keyspan/usa49wlc.fw"); - -module_param(debug, bool, S_IRUGO | S_IWUSR); -MODULE_PARM_DESC(debug, "Debug enabled or not"); - diff --git a/ANDROID_3.4.5/drivers/usb/serial/keyspan.h b/ANDROID_3.4.5/drivers/usb/serial/keyspan.h deleted file mode 100644 index 622853c9..00000000 --- a/ANDROID_3.4.5/drivers/usb/serial/keyspan.h +++ /dev/null @@ -1,623 +0,0 @@ -/* - Keyspan USB to Serial Converter driver - - (C) Copyright (C) 2000-2001 - Hugh Blemings <hugh@blemings.org> - - 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. - - See http://blemings.org/hugh/keyspan.html for more information. - - Code in this driver inspired by and in a number of places taken - from Brian Warner's original Keyspan-PDA driver. - - This driver has been put together with the support of Innosys, Inc. - and Keyspan, Inc the manufacturers of the Keyspan USB-serial products. - Thanks Guys :) - - Thanks to Paulus for miscellaneous tidy ups, some largish chunks - of much nicer and/or completely new code and (perhaps most uniquely) - having the patience to sit down and explain why and where he'd changed - stuff. - - Tip 'o the hat to IBM (and previously Linuxcare :) for supporting - staff in their work on open source projects. - - See keyspan.c for update history. - -*/ - -#ifndef __LINUX_USB_SERIAL_KEYSPAN_H -#define __LINUX_USB_SERIAL_KEYSPAN_H - - -/* Function prototypes for Keyspan serial converter */ -static int keyspan_open (struct tty_struct *tty, - struct usb_serial_port *port); -static void keyspan_close (struct usb_serial_port *port); -static void keyspan_dtr_rts (struct usb_serial_port *port, int on); -static int keyspan_startup (struct usb_serial *serial); -static void keyspan_disconnect (struct usb_serial *serial); -static void keyspan_release (struct usb_serial *serial); -static int keyspan_write_room (struct tty_struct *tty); - -static int keyspan_write (struct tty_struct *tty, - struct usb_serial_port *port, - const unsigned char *buf, - int count); - -static void keyspan_send_setup (struct usb_serial_port *port, - int reset_port); - - -static void keyspan_set_termios (struct tty_struct *tty, - struct usb_serial_port *port, - struct ktermios *old); -static void keyspan_break_ctl (struct tty_struct *tty, - int break_state); -static int keyspan_tiocmget (struct tty_struct *tty); -static int keyspan_tiocmset (struct tty_struct *tty, - unsigned int set, - unsigned int clear); -static int keyspan_fake_startup (struct usb_serial *serial); - -static int keyspan_usa19_calc_baud (u32 baud_rate, u32 baudclk, - u8 *rate_hi, u8 *rate_low, - u8 *prescaler, int portnum); - -static int keyspan_usa19w_calc_baud (u32 baud_rate, u32 baudclk, - u8 *rate_hi, u8 *rate_low, - u8 *prescaler, int portnum); - -static int keyspan_usa28_calc_baud (u32 baud_rate, u32 baudclk, - u8 *rate_hi, u8 *rate_low, - u8 *prescaler, int portnum); - -static int keyspan_usa19hs_calc_baud (u32 baud_rate, u32 baudclk, - u8 *rate_hi, u8 *rate_low, - u8 *prescaler, int portnum); - -static int keyspan_usa28_send_setup (struct usb_serial *serial, - struct usb_serial_port *port, - int reset_port); -static int keyspan_usa26_send_setup (struct usb_serial *serial, - struct usb_serial_port *port, - int reset_port); -static int keyspan_usa49_send_setup (struct usb_serial *serial, - struct usb_serial_port *port, - int reset_port); - -static int keyspan_usa90_send_setup (struct usb_serial *serial, - struct usb_serial_port *port, - int reset_port); - -static int keyspan_usa67_send_setup (struct usb_serial *serial, - struct usb_serial_port *port, - int reset_port); - -/* Values used for baud rate calculation - device specific */ -#define KEYSPAN_INVALID_BAUD_RATE (-1) -#define KEYSPAN_BAUD_RATE_OK (0) -#define KEYSPAN_USA18X_BAUDCLK (12000000L) /* a guess */ -#define KEYSPAN_USA19_BAUDCLK (12000000L) -#define KEYSPAN_USA19W_BAUDCLK (24000000L) -#define KEYSPAN_USA19HS_BAUDCLK (14769231L) -#define KEYSPAN_USA28_BAUDCLK (1843200L) -#define KEYSPAN_USA28X_BAUDCLK (12000000L) -#define KEYSPAN_USA49W_BAUDCLK (48000000L) - -/* Some constants used to characterise each device. */ -#define KEYSPAN_MAX_NUM_PORTS (4) -#define KEYSPAN_MAX_FLIPS (2) - -/* Device info for the Keyspan serial converter, used - by the overall usb-serial probe function */ -#define KEYSPAN_VENDOR_ID (0x06cd) - -/* Product IDs for the products supported, pre-renumeration */ -#define keyspan_usa18x_pre_product_id 0x0105 -#define keyspan_usa19_pre_product_id 0x0103 -#define keyspan_usa19qi_pre_product_id 0x010b -#define keyspan_mpr_pre_product_id 0x011b -#define keyspan_usa19qw_pre_product_id 0x0118 -#define keyspan_usa19w_pre_product_id 0x0106 -#define keyspan_usa28_pre_product_id 0x0101 -#define keyspan_usa28x_pre_product_id 0x0102 -#define keyspan_usa28xa_pre_product_id 0x0114 -#define keyspan_usa28xb_pre_product_id 0x0113 -#define keyspan_usa49w_pre_product_id 0x0109 -#define keyspan_usa49wlc_pre_product_id 0x011a - -/* Product IDs post-renumeration. Note that the 28x and 28xb - have the same id's post-renumeration but behave identically - so it's not an issue. As such, the 28xb is not listed in any - of the device tables. */ -#define keyspan_usa18x_product_id 0x0112 -#define keyspan_usa19_product_id 0x0107 -#define keyspan_usa19qi_product_id 0x010c -#define keyspan_usa19hs_product_id 0x0121 -#define keyspan_mpr_product_id 0x011c -#define keyspan_usa19qw_product_id 0x0119 -#define keyspan_usa19w_product_id 0x0108 -#define keyspan_usa28_product_id 0x010f -#define keyspan_usa28x_product_id 0x0110 -#define keyspan_usa28xa_product_id 0x0115 -#define keyspan_usa28xb_product_id 0x0110 -#define keyspan_usa28xg_product_id 0x0135 -#define keyspan_usa49w_product_id 0x010a -#define keyspan_usa49wlc_product_id 0x012a -#define keyspan_usa49wg_product_id 0x0131 - -struct keyspan_device_details { - /* product ID value */ - int product_id; - - enum {msg_usa26, msg_usa28, msg_usa49, msg_usa90, msg_usa67} msg_format; - - /* Number of physical ports */ - int num_ports; - - /* 1 if endpoint flipping used on input, 0 if not */ - int indat_endp_flip; - - /* 1 if endpoint flipping used on output, 0 if not */ - int outdat_endp_flip; - - /* Table mapping input data endpoint IDs to physical - port number and flip if used */ - int indat_endpoints[KEYSPAN_MAX_NUM_PORTS]; - - /* Same for output endpoints */ - int outdat_endpoints[KEYSPAN_MAX_NUM_PORTS]; - - /* Input acknowledge endpoints */ - int inack_endpoints[KEYSPAN_MAX_NUM_PORTS]; - - /* Output control endpoints */ - int outcont_endpoints[KEYSPAN_MAX_NUM_PORTS]; - - /* Endpoint used for input status */ - int instat_endpoint; - - /* Endpoint used for input data 49WG only */ - int indat_endpoint; - - /* Endpoint used for global control functions */ - int glocont_endpoint; - - int (*calculate_baud_rate) (u32 baud_rate, u32 baudclk, - u8 *rate_hi, u8 *rate_low, u8 *prescaler, int portnum); - u32 baudclk; -}; - -/* Now for each device type we setup the device detail - structure with the appropriate information (provided - in Keyspan's documentation) */ - -static const struct keyspan_device_details usa18x_device_details = { - .product_id = keyspan_usa18x_product_id, - .msg_format = msg_usa26, - .num_ports = 1, - .indat_endp_flip = 0, - .outdat_endp_flip = 1, - .indat_endpoints = {0x81}, - .outdat_endpoints = {0x01}, - .inack_endpoints = {0x85}, - .outcont_endpoints = {0x05}, - .instat_endpoint = 0x87, - .indat_endpoint = -1, - .glocont_endpoint = 0x07, - .calculate_baud_rate = keyspan_usa19w_calc_baud, - .baudclk = KEYSPAN_USA18X_BAUDCLK, -}; - -static const struct keyspan_device_details usa19_device_details = { - .product_id = keyspan_usa19_product_id, - .msg_format = msg_usa28, - .num_ports = 1, - .indat_endp_flip = 1, - .outdat_endp_flip = 1, - .indat_endpoints = {0x81}, - .outdat_endpoints = {0x01}, - .inack_endpoints = {0x83}, - .outcont_endpoints = {0x03}, - .instat_endpoint = 0x84, - .indat_endpoint = -1, - .glocont_endpoint = -1, - .calculate_baud_rate = keyspan_usa19_calc_baud, - .baudclk = KEYSPAN_USA19_BAUDCLK, -}; - -static const struct keyspan_device_details usa19qi_device_details = { - .product_id = keyspan_usa19qi_product_id, - .msg_format = msg_usa28, - .num_ports = 1, - .indat_endp_flip = 1, - .outdat_endp_flip = 1, - .indat_endpoints = {0x81}, - .outdat_endpoints = {0x01}, - .inack_endpoints = {0x83}, - .outcont_endpoints = {0x03}, - .instat_endpoint = 0x84, - .indat_endpoint = -1, - .glocont_endpoint = -1, - .calculate_baud_rate = keyspan_usa28_calc_baud, - .baudclk = KEYSPAN_USA19_BAUDCLK, -}; - -static const struct keyspan_device_details mpr_device_details = { - .product_id = keyspan_mpr_product_id, - .msg_format = msg_usa28, - .num_ports = 1, - .indat_endp_flip = 1, - .outdat_endp_flip = 1, - .indat_endpoints = {0x81}, - .outdat_endpoints = {0x01}, - .inack_endpoints = {0x83}, - .outcont_endpoints = {0x03}, - .instat_endpoint = 0x84, - .indat_endpoint = -1, - .glocont_endpoint = -1, - .calculate_baud_rate = keyspan_usa28_calc_baud, - .baudclk = KEYSPAN_USA19_BAUDCLK, -}; - -static const struct keyspan_device_details usa19qw_device_details = { - .product_id = keyspan_usa19qw_product_id, - .msg_format = msg_usa26, - .num_ports = 1, - .indat_endp_flip = 0, - .outdat_endp_flip = 1, - .indat_endpoints = {0x81}, - .outdat_endpoints = {0x01}, - .inack_endpoints = {0x85}, - .outcont_endpoints = {0x05}, - .instat_endpoint = 0x87, - .indat_endpoint = -1, - .glocont_endpoint = 0x07, - .calculate_baud_rate = keyspan_usa19w_calc_baud, - .baudclk = KEYSPAN_USA19W_BAUDCLK, -}; - -static const struct keyspan_device_details usa19w_device_details = { - .product_id = keyspan_usa19w_product_id, - .msg_format = msg_usa26, - .num_ports = 1, - .indat_endp_flip = 0, - .outdat_endp_flip = 1, - .indat_endpoints = {0x81}, - .outdat_endpoints = {0x01}, - .inack_endpoints = {0x85}, - .outcont_endpoints = {0x05}, - .instat_endpoint = 0x87, - .indat_endpoint = -1, - .glocont_endpoint = 0x07, - .calculate_baud_rate = keyspan_usa19w_calc_baud, - .baudclk = KEYSPAN_USA19W_BAUDCLK, -}; - -static const struct keyspan_device_details usa19hs_device_details = { - .product_id = keyspan_usa19hs_product_id, - .msg_format = msg_usa90, - .num_ports = 1, - .indat_endp_flip = 0, - .outdat_endp_flip = 0, - .indat_endpoints = {0x81}, - .outdat_endpoints = {0x01}, - .inack_endpoints = {-1}, - .outcont_endpoints = {0x02}, - .instat_endpoint = 0x82, - .indat_endpoint = -1, - .glocont_endpoint = -1, - .calculate_baud_rate = keyspan_usa19hs_calc_baud, - .baudclk = KEYSPAN_USA19HS_BAUDCLK, -}; - -static const struct keyspan_device_details usa28_device_details = { - .product_id = keyspan_usa28_product_id, - .msg_format = msg_usa28, - .num_ports = 2, - .indat_endp_flip = 1, - .outdat_endp_flip = 1, - .indat_endpoints = {0x81, 0x83}, - .outdat_endpoints = {0x01, 0x03}, - .inack_endpoints = {0x85, 0x86}, - .outcont_endpoints = {0x05, 0x06}, - .instat_endpoint = 0x87, - .indat_endpoint = -1, - .glocont_endpoint = 0x07, - .calculate_baud_rate = keyspan_usa28_calc_baud, - .baudclk = KEYSPAN_USA28_BAUDCLK, -}; - -static const struct keyspan_device_details usa28x_device_details = { - .product_id = keyspan_usa28x_product_id, - .msg_format = msg_usa26, - .num_ports = 2, - .indat_endp_flip = 0, - .outdat_endp_flip = 1, - .indat_endpoints = {0x81, 0x83}, - .outdat_endpoints = {0x01, 0x03}, - .inack_endpoints = {0x85, 0x86}, - .outcont_endpoints = {0x05, 0x06}, - .instat_endpoint = 0x87, - .indat_endpoint = -1, - .glocont_endpoint = 0x07, - .calculate_baud_rate = keyspan_usa19w_calc_baud, - .baudclk = KEYSPAN_USA28X_BAUDCLK, -}; - -static const struct keyspan_device_details usa28xa_device_details = { - .product_id = keyspan_usa28xa_product_id, - .msg_format = msg_usa26, - .num_ports = 2, - .indat_endp_flip = 0, - .outdat_endp_flip = 1, - .indat_endpoints = {0x81, 0x83}, - .outdat_endpoints = {0x01, 0x03}, - .inack_endpoints = {0x85, 0x86}, - .outcont_endpoints = {0x05, 0x06}, - .instat_endpoint = 0x87, - .indat_endpoint = -1, - .glocont_endpoint = 0x07, - .calculate_baud_rate = keyspan_usa19w_calc_baud, - .baudclk = KEYSPAN_USA28X_BAUDCLK, -}; - -static const struct keyspan_device_details usa28xg_device_details = { - .product_id = keyspan_usa28xg_product_id, - .msg_format = msg_usa67, - .num_ports = 2, - .indat_endp_flip = 0, - .outdat_endp_flip = 0, - .indat_endpoints = {0x84, 0x88}, - .outdat_endpoints = {0x02, 0x06}, - .inack_endpoints = {-1, -1}, - .outcont_endpoints = {-1, -1}, - .instat_endpoint = 0x81, - .indat_endpoint = -1, - .glocont_endpoint = 0x01, - .calculate_baud_rate = keyspan_usa19w_calc_baud, - .baudclk = KEYSPAN_USA28X_BAUDCLK, -}; -/* We don't need a separate entry for the usa28xb as it appears as a 28x anyway */ - -static const struct keyspan_device_details usa49w_device_details = { - .product_id = keyspan_usa49w_product_id, - .msg_format = msg_usa49, - .num_ports = 4, - .indat_endp_flip = 0, - .outdat_endp_flip = 0, - .indat_endpoints = {0x81, 0x82, 0x83, 0x84}, - .outdat_endpoints = {0x01, 0x02, 0x03, 0x04}, - .inack_endpoints = {-1, -1, -1, -1}, - .outcont_endpoints = {-1, -1, -1, -1}, - .instat_endpoint = 0x87, - .indat_endpoint = -1, - .glocont_endpoint = 0x07, - .calculate_baud_rate = keyspan_usa19w_calc_baud, - .baudclk = KEYSPAN_USA49W_BAUDCLK, -}; - -static const struct keyspan_device_details usa49wlc_device_details = { - .product_id = keyspan_usa49wlc_product_id, - .msg_format = msg_usa49, - .num_ports = 4, - .indat_endp_flip = 0, - .outdat_endp_flip = 0, - .indat_endpoints = {0x81, 0x82, 0x83, 0x84}, - .outdat_endpoints = {0x01, 0x02, 0x03, 0x04}, - .inack_endpoints = {-1, -1, -1, -1}, - .outcont_endpoints = {-1, -1, -1, -1}, - .instat_endpoint = 0x87, - .indat_endpoint = -1, - .glocont_endpoint = 0x07, - .calculate_baud_rate = keyspan_usa19w_calc_baud, - .baudclk = KEYSPAN_USA19W_BAUDCLK, -}; - -static const struct keyspan_device_details usa49wg_device_details = { - .product_id = keyspan_usa49wg_product_id, - .msg_format = msg_usa49, - .num_ports = 4, - .indat_endp_flip = 0, - .outdat_endp_flip = 0, - .indat_endpoints = {-1, -1, -1, -1}, /* single 'global' data in EP */ - .outdat_endpoints = {0x01, 0x02, 0x04, 0x06}, - .inack_endpoints = {-1, -1, -1, -1}, - .outcont_endpoints = {-1, -1, -1, -1}, - .instat_endpoint = 0x81, - .indat_endpoint = 0x88, - .glocont_endpoint = 0x00, /* uses control EP */ - .calculate_baud_rate = keyspan_usa19w_calc_baud, - .baudclk = KEYSPAN_USA19W_BAUDCLK, -}; - -static const struct keyspan_device_details *keyspan_devices[] = { - &usa18x_device_details, - &usa19_device_details, - &usa19qi_device_details, - &mpr_device_details, - &usa19qw_device_details, - &usa19w_device_details, - &usa19hs_device_details, - &usa28_device_details, - &usa28x_device_details, - &usa28xa_device_details, - &usa28xg_device_details, - /* 28xb not required as it renumerates as a 28x */ - &usa49w_device_details, - &usa49wlc_device_details, - &usa49wg_device_details, - NULL, -}; - -static const struct usb_device_id keyspan_ids_combined[] = { - { USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa18x_pre_product_id) }, - { USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa19_pre_product_id) }, - { USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa19w_pre_product_id) }, - { USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa19qi_pre_product_id) }, - { USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa19qw_pre_product_id) }, - { USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_mpr_pre_product_id) }, - { USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa28_pre_product_id) }, - { USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa28x_pre_product_id) }, - { USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa28xa_pre_product_id) }, - { USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa28xb_pre_product_id) }, - { USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa49w_pre_product_id) }, - { USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa49wlc_pre_product_id) }, - { USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa18x_product_id) }, - { USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa19_product_id) }, - { USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa19w_product_id) }, - { USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa19qi_product_id) }, - { USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa19qw_product_id) }, - { USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa19hs_product_id) }, - { USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_mpr_product_id) }, - { USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa28_product_id) }, - { USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa28x_product_id) }, - { USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa28xa_product_id) }, - { USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa28xg_product_id) }, - { USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa49w_product_id)}, - { USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa49wlc_product_id)}, - { USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa49wg_product_id)}, - { } /* Terminating entry */ -}; - -MODULE_DEVICE_TABLE(usb, keyspan_ids_combined); - -static struct usb_driver keyspan_driver = { - .name = "keyspan", - .probe = usb_serial_probe, - .disconnect = usb_serial_disconnect, - .id_table = keyspan_ids_combined, -}; - -/* usb_device_id table for the pre-firmware download keyspan devices */ -static const struct usb_device_id keyspan_pre_ids[] = { - { USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa18x_pre_product_id) }, - { USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa19_pre_product_id) }, - { USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa19qi_pre_product_id) }, - { USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa19qw_pre_product_id) }, - { USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa19w_pre_product_id) }, - { USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_mpr_pre_product_id) }, - { USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa28_pre_product_id) }, - { USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa28x_pre_product_id) }, - { USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa28xa_pre_product_id) }, - { USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa28xb_pre_product_id) }, - { USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa49w_pre_product_id) }, - { USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa49wlc_pre_product_id) }, - { } /* Terminating entry */ -}; - -static const struct usb_device_id keyspan_1port_ids[] = { - { USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa18x_product_id) }, - { USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa19_product_id) }, - { USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa19qi_product_id) }, - { USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa19qw_product_id) }, - { USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa19w_product_id) }, - { USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa19hs_product_id) }, - { USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_mpr_product_id) }, - { } /* Terminating entry */ -}; - -static const struct usb_device_id keyspan_2port_ids[] = { - { USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa28_product_id) }, - { USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa28x_product_id) }, - { USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa28xa_product_id) }, - { USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa28xg_product_id) }, - { } /* Terminating entry */ -}; - -static const struct usb_device_id keyspan_4port_ids[] = { - { USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa49w_product_id) }, - { USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa49wlc_product_id)}, - { USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa49wg_product_id)}, - { } /* Terminating entry */ -}; - -/* Structs for the devices, pre and post renumeration. */ -static struct usb_serial_driver keyspan_pre_device = { - .driver = { - .owner = THIS_MODULE, - .name = "keyspan_no_firm", - }, - .description = "Keyspan - (without firmware)", - .id_table = keyspan_pre_ids, - .num_ports = 1, - .attach = keyspan_fake_startup, -}; - -static struct usb_serial_driver keyspan_1port_device = { - .driver = { - .owner = THIS_MODULE, - .name = "keyspan_1", - }, - .description = "Keyspan 1 port adapter", - .id_table = keyspan_1port_ids, - .num_ports = 1, - .open = keyspan_open, - .close = keyspan_close, - .dtr_rts = keyspan_dtr_rts, - .write = keyspan_write, - .write_room = keyspan_write_room, - .set_termios = keyspan_set_termios, - .break_ctl = keyspan_break_ctl, - .tiocmget = keyspan_tiocmget, - .tiocmset = keyspan_tiocmset, - .attach = keyspan_startup, - .disconnect = keyspan_disconnect, - .release = keyspan_release, -}; - -static struct usb_serial_driver keyspan_2port_device = { - .driver = { - .owner = THIS_MODULE, - .name = "keyspan_2", - }, - .description = "Keyspan 2 port adapter", - .id_table = keyspan_2port_ids, - .num_ports = 2, - .open = keyspan_open, - .close = keyspan_close, - .dtr_rts = keyspan_dtr_rts, - .write = keyspan_write, - .write_room = keyspan_write_room, - .set_termios = keyspan_set_termios, - .break_ctl = keyspan_break_ctl, - .tiocmget = keyspan_tiocmget, - .tiocmset = keyspan_tiocmset, - .attach = keyspan_startup, - .disconnect = keyspan_disconnect, - .release = keyspan_release, -}; - -static struct usb_serial_driver keyspan_4port_device = { - .driver = { - .owner = THIS_MODULE, - .name = "keyspan_4", - }, - .description = "Keyspan 4 port adapter", - .id_table = keyspan_4port_ids, - .num_ports = 4, - .open = keyspan_open, - .close = keyspan_close, - .dtr_rts = keyspan_dtr_rts, - .write = keyspan_write, - .write_room = keyspan_write_room, - .set_termios = keyspan_set_termios, - .break_ctl = keyspan_break_ctl, - .tiocmget = keyspan_tiocmget, - .tiocmset = keyspan_tiocmset, - .attach = keyspan_startup, - .disconnect = keyspan_disconnect, - .release = keyspan_release, -}; - -static struct usb_serial_driver * const serial_drivers[] = { - &keyspan_pre_device, &keyspan_1port_device, - &keyspan_2port_device, &keyspan_4port_device, NULL -}; - -#endif diff --git a/ANDROID_3.4.5/drivers/usb/serial/keyspan_pda.c b/ANDROID_3.4.5/drivers/usb/serial/keyspan_pda.c deleted file mode 100644 index 693bcdfc..00000000 --- a/ANDROID_3.4.5/drivers/usb/serial/keyspan_pda.c +++ /dev/null @@ -1,844 +0,0 @@ -/* - * USB Keyspan PDA / Xircom / Entregra Converter driver - * - * Copyright (C) 1999 - 2001 Greg Kroah-Hartman <greg@kroah.com> - * Copyright (C) 1999, 2000 Brian Warner <warner@lothar.com> - * Copyright (C) 2000 Al Borchers <borchers@steinerpoint.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. - * - * See Documentation/usb/usb-serial.txt for more information on using this - * driver - */ - - -#include <linux/kernel.h> -#include <linux/errno.h> -#include <linux/init.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/workqueue.h> -#include <linux/firmware.h> -#include <linux/ihex.h> -#include <linux/uaccess.h> -#include <linux/usb.h> -#include <linux/usb/serial.h> - -static bool debug; - -/* make a simple define to handle if we are compiling keyspan_pda or xircom support */ -#if defined(CONFIG_USB_SERIAL_KEYSPAN_PDA) || defined(CONFIG_USB_SERIAL_KEYSPAN_PDA_MODULE) - #define KEYSPAN -#else - #undef KEYSPAN -#endif -#if defined(CONFIG_USB_SERIAL_XIRCOM) || defined(CONFIG_USB_SERIAL_XIRCOM_MODULE) - #define XIRCOM -#else - #undef XIRCOM -#endif - -/* - * Version Information - */ -#define DRIVER_VERSION "v1.1" -#define DRIVER_AUTHOR "Brian Warner <warner@lothar.com>" -#define DRIVER_DESC "USB Keyspan PDA Converter driver" - -struct keyspan_pda_private { - int tx_room; - int tx_throttled; - struct work_struct wakeup_work; - struct work_struct unthrottle_work; - struct usb_serial *serial; - struct usb_serial_port *port; -}; - - -#define KEYSPAN_VENDOR_ID 0x06cd -#define KEYSPAN_PDA_FAKE_ID 0x0103 -#define KEYSPAN_PDA_ID 0x0104 /* no clue */ - -/* For Xircom PGSDB9 and older Entregra version of the same device */ -#define XIRCOM_VENDOR_ID 0x085a -#define XIRCOM_FAKE_ID 0x8027 -#define ENTREGRA_VENDOR_ID 0x1645 -#define ENTREGRA_FAKE_ID 0x8093 - -static const struct usb_device_id id_table_combined[] = { -#ifdef KEYSPAN - { USB_DEVICE(KEYSPAN_VENDOR_ID, KEYSPAN_PDA_FAKE_ID) }, -#endif -#ifdef XIRCOM - { USB_DEVICE(XIRCOM_VENDOR_ID, XIRCOM_FAKE_ID) }, - { USB_DEVICE(ENTREGRA_VENDOR_ID, ENTREGRA_FAKE_ID) }, -#endif - { USB_DEVICE(KEYSPAN_VENDOR_ID, KEYSPAN_PDA_ID) }, - { } /* Terminating entry */ -}; - -MODULE_DEVICE_TABLE(usb, id_table_combined); - -static struct usb_driver keyspan_pda_driver = { - .name = "keyspan_pda", - .probe = usb_serial_probe, - .disconnect = usb_serial_disconnect, - .id_table = id_table_combined, -}; - -static const struct usb_device_id id_table_std[] = { - { USB_DEVICE(KEYSPAN_VENDOR_ID, KEYSPAN_PDA_ID) }, - { } /* Terminating entry */ -}; - -#ifdef KEYSPAN -static const struct usb_device_id id_table_fake[] = { - { USB_DEVICE(KEYSPAN_VENDOR_ID, KEYSPAN_PDA_FAKE_ID) }, - { } /* Terminating entry */ -}; -#endif - -#ifdef XIRCOM -static const struct usb_device_id id_table_fake_xircom[] = { - { USB_DEVICE(XIRCOM_VENDOR_ID, XIRCOM_FAKE_ID) }, - { USB_DEVICE(ENTREGRA_VENDOR_ID, ENTREGRA_FAKE_ID) }, - { } -}; -#endif - -static void keyspan_pda_wakeup_write(struct work_struct *work) -{ - struct keyspan_pda_private *priv = - container_of(work, struct keyspan_pda_private, wakeup_work); - struct usb_serial_port *port = priv->port; - struct tty_struct *tty = tty_port_tty_get(&port->port); - if (tty) - tty_wakeup(tty); - tty_kref_put(tty); -} - -static void keyspan_pda_request_unthrottle(struct work_struct *work) -{ - struct keyspan_pda_private *priv = - container_of(work, struct keyspan_pda_private, unthrottle_work); - struct usb_serial *serial = priv->serial; - int result; - - dbg(" request_unthrottle"); - /* ask the device to tell us when the tx buffer becomes - sufficiently empty */ - result = usb_control_msg(serial->dev, - usb_sndctrlpipe(serial->dev, 0), - 7, /* request_unthrottle */ - USB_TYPE_VENDOR | USB_RECIP_INTERFACE - | USB_DIR_OUT, - 16, /* value: threshold */ - 0, /* index */ - NULL, - 0, - 2000); - if (result < 0) - dbg("%s - error %d from usb_control_msg", - __func__, result); -} - - -static void keyspan_pda_rx_interrupt(struct urb *urb) -{ - struct usb_serial_port *port = urb->context; - struct tty_struct *tty; - unsigned char *data = urb->transfer_buffer; - int retval; - int status = urb->status; - struct keyspan_pda_private *priv; - priv = usb_get_serial_port_data(port); - - switch (status) { - case 0: - /* success */ - break; - case -ECONNRESET: - case -ENOENT: - case -ESHUTDOWN: - /* this urb is terminated, clean up */ - dbg("%s - urb shutting down with status: %d", - __func__, status); - return; - default: - dbg("%s - nonzero urb status received: %d", - __func__, status); - goto exit; - } - - /* see if the message is data or a status interrupt */ - switch (data[0]) { - case 0: - tty = tty_port_tty_get(&port->port); - /* rest of message is rx data */ - if (tty && urb->actual_length) { - tty_insert_flip_string(tty, data + 1, - urb->actual_length - 1); - tty_flip_buffer_push(tty); - } - tty_kref_put(tty); - break; - case 1: - /* status interrupt */ - dbg(" rx int, d1=%d, d2=%d", data[1], data[2]); - switch (data[1]) { - case 1: /* modemline change */ - break; - case 2: /* tx unthrottle interrupt */ - priv->tx_throttled = 0; - /* queue up a wakeup at scheduler time */ - schedule_work(&priv->wakeup_work); - break; - default: - break; - } - break; - default: - break; - } - -exit: - retval = usb_submit_urb(urb, GFP_ATOMIC); - if (retval) - dev_err(&port->dev, - "%s - usb_submit_urb failed with result %d", - __func__, retval); -} - - -static void keyspan_pda_rx_throttle(struct tty_struct *tty) -{ - /* stop receiving characters. We just turn off the URB request, and - let chars pile up in the device. If we're doing hardware - flowcontrol, the device will signal the other end when its buffer - fills up. If we're doing XON/XOFF, this would be a good time to - send an XOFF, although it might make sense to foist that off - upon the device too. */ - struct usb_serial_port *port = tty->driver_data; - dbg("keyspan_pda_rx_throttle port %d", port->number); - usb_kill_urb(port->interrupt_in_urb); -} - - -static void keyspan_pda_rx_unthrottle(struct tty_struct *tty) -{ - struct usb_serial_port *port = tty->driver_data; - /* just restart the receive interrupt URB */ - dbg("keyspan_pda_rx_unthrottle port %d", port->number); - if (usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL)) - dbg(" usb_submit_urb(read urb) failed"); -} - - -static speed_t keyspan_pda_setbaud(struct usb_serial *serial, speed_t baud) -{ - int rc; - int bindex; - - switch (baud) { - case 110: - bindex = 0; - break; - case 300: - bindex = 1; - break; - case 1200: - bindex = 2; - break; - case 2400: - bindex = 3; - break; - case 4800: - bindex = 4; - break; - case 9600: - bindex = 5; - break; - case 19200: - bindex = 6; - break; - case 38400: - bindex = 7; - break; - case 57600: - bindex = 8; - break; - case 115200: - bindex = 9; - break; - default: - bindex = 5; /* Default to 9600 */ - baud = 9600; - } - - /* rather than figure out how to sleep while waiting for this - to complete, I just use the "legacy" API. */ - rc = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0), - 0, /* set baud */ - USB_TYPE_VENDOR - | USB_RECIP_INTERFACE - | USB_DIR_OUT, /* type */ - bindex, /* value */ - 0, /* index */ - NULL, /* &data */ - 0, /* size */ - 2000); /* timeout */ - if (rc < 0) - return 0; - return baud; -} - - -static void keyspan_pda_break_ctl(struct tty_struct *tty, int break_state) -{ - struct usb_serial_port *port = tty->driver_data; - struct usb_serial *serial = port->serial; - int value; - int result; - - if (break_state == -1) - value = 1; /* start break */ - else - value = 0; /* clear break */ - result = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0), - 4, /* set break */ - USB_TYPE_VENDOR | USB_RECIP_INTERFACE | USB_DIR_OUT, - value, 0, NULL, 0, 2000); - if (result < 0) - dbg("%s - error %d from usb_control_msg", - __func__, result); - /* there is something funky about this.. the TCSBRK that 'cu' performs - ought to translate into a break_ctl(-1),break_ctl(0) pair HZ/4 - seconds apart, but it feels like the break sent isn't as long as it - is on /dev/ttyS0 */ -} - - -static void keyspan_pda_set_termios(struct tty_struct *tty, - struct usb_serial_port *port, struct ktermios *old_termios) -{ - struct usb_serial *serial = port->serial; - speed_t speed; - - /* cflag specifies lots of stuff: number of stop bits, parity, number - of data bits, baud. What can the device actually handle?: - CSTOPB (1 stop bit or 2) - PARENB (parity) - CSIZE (5bit .. 8bit) - There is minimal hw support for parity (a PSW bit seems to hold the - parity of whatever is in the accumulator). The UART either deals - with 10 bits (start, 8 data, stop) or 11 bits (start, 8 data, - 1 special, stop). So, with firmware changes, we could do: - 8N1: 10 bit - 8N2: 11 bit, extra bit always (mark?) - 8[EOMS]1: 11 bit, extra bit is parity - 7[EOMS]1: 10 bit, b0/b7 is parity - 7[EOMS]2: 11 bit, b0/b7 is parity, extra bit always (mark?) - - HW flow control is dictated by the tty->termios->c_cflags & CRTSCTS - bit. - - For now, just do baud. */ - - speed = tty_get_baud_rate(tty); - speed = keyspan_pda_setbaud(serial, speed); - - if (speed == 0) { - dbg("can't handle requested baud rate"); - /* It hasn't changed so.. */ - speed = tty_termios_baud_rate(old_termios); - } - /* Only speed can change so copy the old h/w parameters - then encode the new speed */ - tty_termios_copy_hw(tty->termios, old_termios); - tty_encode_baud_rate(tty, speed, speed); -} - - -/* modem control pins: DTR and RTS are outputs and can be controlled. - DCD, RI, DSR, CTS are inputs and can be read. All outputs can also be - read. The byte passed is: DTR(b7) DCD RI DSR CTS RTS(b2) unused unused */ - -static int keyspan_pda_get_modem_info(struct usb_serial *serial, - unsigned char *value) -{ - int rc; - u8 *data; - - data = kmalloc(1, GFP_KERNEL); - if (!data) - return -ENOMEM; - - rc = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0), - 3, /* get pins */ - USB_TYPE_VENDOR|USB_RECIP_INTERFACE|USB_DIR_IN, - 0, 0, data, 1, 2000); - if (rc >= 0) - *value = *data; - - kfree(data); - return rc; -} - - -static int keyspan_pda_set_modem_info(struct usb_serial *serial, - unsigned char value) -{ - int rc; - rc = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0), - 3, /* set pins */ - USB_TYPE_VENDOR|USB_RECIP_INTERFACE|USB_DIR_OUT, - value, 0, NULL, 0, 2000); - return rc; -} - -static int keyspan_pda_tiocmget(struct tty_struct *tty) -{ - struct usb_serial_port *port = tty->driver_data; - struct usb_serial *serial = port->serial; - int rc; - unsigned char status; - int value; - - rc = keyspan_pda_get_modem_info(serial, &status); - if (rc < 0) - return rc; - value = - ((status & (1<<7)) ? TIOCM_DTR : 0) | - ((status & (1<<6)) ? TIOCM_CAR : 0) | - ((status & (1<<5)) ? TIOCM_RNG : 0) | - ((status & (1<<4)) ? TIOCM_DSR : 0) | - ((status & (1<<3)) ? TIOCM_CTS : 0) | - ((status & (1<<2)) ? TIOCM_RTS : 0); - return value; -} - -static int keyspan_pda_tiocmset(struct tty_struct *tty, - unsigned int set, unsigned int clear) -{ - struct usb_serial_port *port = tty->driver_data; - struct usb_serial *serial = port->serial; - int rc; - unsigned char status; - - rc = keyspan_pda_get_modem_info(serial, &status); - if (rc < 0) - return rc; - - if (set & TIOCM_RTS) - status |= (1<<2); - if (set & TIOCM_DTR) - status |= (1<<7); - - if (clear & TIOCM_RTS) - status &= ~(1<<2); - if (clear & TIOCM_DTR) - status &= ~(1<<7); - rc = keyspan_pda_set_modem_info(serial, status); - return rc; -} - -static int keyspan_pda_write(struct tty_struct *tty, - struct usb_serial_port *port, const unsigned char *buf, int count) -{ - struct usb_serial *serial = port->serial; - int request_unthrottle = 0; - int rc = 0; - struct keyspan_pda_private *priv; - - priv = usb_get_serial_port_data(port); - /* guess how much room is left in the device's ring buffer, and if we - want to send more than that, check first, updating our notion of - what is left. If our write will result in no room left, ask the - device to give us an interrupt when the room available rises above - a threshold, and hold off all writers (eventually, those using - select() or poll() too) until we receive that unthrottle interrupt. - Block if we can't write anything at all, otherwise write as much as - we can. */ - dbg("keyspan_pda_write(%d)", count); - if (count == 0) { - dbg(" write request of 0 bytes"); - return 0; - } - - /* we might block because of: - the TX urb is in-flight (wait until it completes) - the device is full (wait until it says there is room) - */ - spin_lock_bh(&port->lock); - if (!test_bit(0, &port->write_urbs_free) || priv->tx_throttled) { - spin_unlock_bh(&port->lock); - return 0; - } - clear_bit(0, &port->write_urbs_free); - spin_unlock_bh(&port->lock); - - /* At this point the URB is in our control, nobody else can submit it - again (the only sudden transition was the one from EINPROGRESS to - finished). Also, the tx process is not throttled. So we are - ready to write. */ - - count = (count > port->bulk_out_size) ? port->bulk_out_size : count; - - /* Check if we might overrun the Tx buffer. If so, ask the - device how much room it really has. This is done only on - scheduler time, since usb_control_msg() sleeps. */ - if (count > priv->tx_room && !in_interrupt()) { - u8 *room; - - room = kmalloc(1, GFP_KERNEL); - if (!room) { - rc = -ENOMEM; - goto exit; - } - - rc = usb_control_msg(serial->dev, - usb_rcvctrlpipe(serial->dev, 0), - 6, /* write_room */ - USB_TYPE_VENDOR | USB_RECIP_INTERFACE - | USB_DIR_IN, - 0, /* value: 0 means "remaining room" */ - 0, /* index */ - room, - 1, - 2000); - if (rc > 0) { - dbg(" roomquery says %d", *room); - priv->tx_room = *room; - } - kfree(room); - if (rc < 0) { - dbg(" roomquery failed"); - goto exit; - } - if (rc == 0) { - dbg(" roomquery returned 0 bytes"); - rc = -EIO; /* device didn't return any data */ - goto exit; - } - } - if (count > priv->tx_room) { - /* we're about to completely fill the Tx buffer, so - we'll be throttled afterwards. */ - count = priv->tx_room; - request_unthrottle = 1; - } - - if (count) { - /* now transfer data */ - memcpy(port->write_urb->transfer_buffer, buf, count); - /* send the data out the bulk port */ - port->write_urb->transfer_buffer_length = count; - - priv->tx_room -= count; - - rc = usb_submit_urb(port->write_urb, GFP_ATOMIC); - if (rc) { - dbg(" usb_submit_urb(write bulk) failed"); - goto exit; - } - } else { - /* There wasn't any room left, so we are throttled until - the buffer empties a bit */ - request_unthrottle = 1; - } - - if (request_unthrottle) { - priv->tx_throttled = 1; /* block writers */ - schedule_work(&priv->unthrottle_work); - } - - rc = count; -exit: - if (rc < 0) - set_bit(0, &port->write_urbs_free); - return rc; -} - - -static void keyspan_pda_write_bulk_callback(struct urb *urb) -{ - struct usb_serial_port *port = urb->context; - struct keyspan_pda_private *priv; - - set_bit(0, &port->write_urbs_free); - priv = usb_get_serial_port_data(port); - - /* queue up a wakeup at scheduler time */ - schedule_work(&priv->wakeup_work); -} - - -static int keyspan_pda_write_room(struct tty_struct *tty) -{ - struct usb_serial_port *port = tty->driver_data; - struct keyspan_pda_private *priv; - priv = usb_get_serial_port_data(port); - /* used by n_tty.c for processing of tabs and such. Giving it our - conservative guess is probably good enough, but needs testing by - running a console through the device. */ - return priv->tx_room; -} - - -static int keyspan_pda_chars_in_buffer(struct tty_struct *tty) -{ - struct usb_serial_port *port = tty->driver_data; - struct keyspan_pda_private *priv; - unsigned long flags; - int ret = 0; - - priv = usb_get_serial_port_data(port); - - /* when throttled, return at least WAKEUP_CHARS to tell select() (via - n_tty.c:normal_poll() ) that we're not writeable. */ - - spin_lock_irqsave(&port->lock, flags); - if (!test_bit(0, &port->write_urbs_free) || priv->tx_throttled) - ret = 256; - spin_unlock_irqrestore(&port->lock, flags); - return ret; -} - - -static void keyspan_pda_dtr_rts(struct usb_serial_port *port, int on) -{ - struct usb_serial *serial = port->serial; - - if (serial->dev) { - if (on) - keyspan_pda_set_modem_info(serial, (1<<7) | (1<< 2)); - else - keyspan_pda_set_modem_info(serial, 0); - } -} - - -static int keyspan_pda_open(struct tty_struct *tty, - struct usb_serial_port *port) -{ - struct usb_serial *serial = port->serial; - u8 *room; - int rc = 0; - struct keyspan_pda_private *priv; - - /* find out how much room is in the Tx ring */ - room = kmalloc(1, GFP_KERNEL); - if (!room) - return -ENOMEM; - - rc = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0), - 6, /* write_room */ - USB_TYPE_VENDOR | USB_RECIP_INTERFACE - | USB_DIR_IN, - 0, /* value */ - 0, /* index */ - room, - 1, - 2000); - if (rc < 0) { - dbg("%s - roomquery failed", __func__); - goto error; - } - if (rc == 0) { - dbg("%s - roomquery returned 0 bytes", __func__); - rc = -EIO; - goto error; - } - priv = usb_get_serial_port_data(port); - priv->tx_room = *room; - priv->tx_throttled = *room ? 0 : 1; - - /*Start reading from the device*/ - rc = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL); - if (rc) { - dbg("%s - usb_submit_urb(read int) failed", __func__); - goto error; - } -error: - kfree(room); - return rc; -} -static void keyspan_pda_close(struct usb_serial_port *port) -{ - struct usb_serial *serial = port->serial; - - if (serial->dev) { - /* shutdown our bulk reads and writes */ - usb_kill_urb(port->write_urb); - usb_kill_urb(port->interrupt_in_urb); - } -} - - -/* download the firmware to a "fake" device (pre-renumeration) */ -static int keyspan_pda_fake_startup(struct usb_serial *serial) -{ - int response; - const char *fw_name; - const struct ihex_binrec *record; - const struct firmware *fw; - - /* download the firmware here ... */ - response = ezusb_set_reset(serial, 1); - - if (0) { ; } -#ifdef KEYSPAN - else if (le16_to_cpu(serial->dev->descriptor.idVendor) == KEYSPAN_VENDOR_ID) - fw_name = "keyspan_pda/keyspan_pda.fw"; -#endif -#ifdef XIRCOM - else if ((le16_to_cpu(serial->dev->descriptor.idVendor) == XIRCOM_VENDOR_ID) || - (le16_to_cpu(serial->dev->descriptor.idVendor) == ENTREGRA_VENDOR_ID)) - fw_name = "keyspan_pda/xircom_pgs.fw"; -#endif - else { - dev_err(&serial->dev->dev, "%s: unknown vendor, aborting.\n", - __func__); - return -ENODEV; - } - if (request_ihex_firmware(&fw, fw_name, &serial->dev->dev)) { - dev_err(&serial->dev->dev, "failed to load firmware \"%s\"\n", - fw_name); - return -ENOENT; - } - record = (const struct ihex_binrec *)fw->data; - - while (record) { - response = ezusb_writememory(serial, be32_to_cpu(record->addr), - (unsigned char *)record->data, - be16_to_cpu(record->len), 0xa0); - if (response < 0) { - dev_err(&serial->dev->dev, "ezusb_writememory failed " - "for Keyspan PDA firmware (%d %04X %p %d)\n", - response, be32_to_cpu(record->addr), - record->data, be16_to_cpu(record->len)); - break; - } - record = ihex_next_binrec(record); - } - release_firmware(fw); - /* bring device out of reset. Renumeration will occur in a moment - and the new device will bind to the real driver */ - response = ezusb_set_reset(serial, 0); - - /* we want this device to fail to have a driver assigned to it. */ - return 1; -} - -#ifdef KEYSPAN -MODULE_FIRMWARE("keyspan_pda/keyspan_pda.fw"); -#endif -#ifdef XIRCOM -MODULE_FIRMWARE("keyspan_pda/xircom_pgs.fw"); -#endif - -static int keyspan_pda_startup(struct usb_serial *serial) -{ - - struct keyspan_pda_private *priv; - - /* allocate the private data structures for all ports. Well, for all - one ports. */ - - priv = kmalloc(sizeof(struct keyspan_pda_private), GFP_KERNEL); - if (!priv) - return 1; /* error */ - usb_set_serial_port_data(serial->port[0], priv); - init_waitqueue_head(&serial->port[0]->write_wait); - INIT_WORK(&priv->wakeup_work, keyspan_pda_wakeup_write); - INIT_WORK(&priv->unthrottle_work, keyspan_pda_request_unthrottle); - priv->serial = serial; - priv->port = serial->port[0]; - return 0; -} - -static void keyspan_pda_release(struct usb_serial *serial) -{ - dbg("%s", __func__); - - kfree(usb_get_serial_port_data(serial->port[0])); -} - -#ifdef KEYSPAN -static struct usb_serial_driver keyspan_pda_fake_device = { - .driver = { - .owner = THIS_MODULE, - .name = "keyspan_pda_pre", - }, - .description = "Keyspan PDA - (prerenumeration)", - .id_table = id_table_fake, - .num_ports = 1, - .attach = keyspan_pda_fake_startup, -}; -#endif - -#ifdef XIRCOM -static struct usb_serial_driver xircom_pgs_fake_device = { - .driver = { - .owner = THIS_MODULE, - .name = "xircom_no_firm", - }, - .description = "Xircom / Entregra PGS - (prerenumeration)", - .id_table = id_table_fake_xircom, - .num_ports = 1, - .attach = keyspan_pda_fake_startup, -}; -#endif - -static struct usb_serial_driver keyspan_pda_device = { - .driver = { - .owner = THIS_MODULE, - .name = "keyspan_pda", - }, - .description = "Keyspan PDA", - .id_table = id_table_std, - .num_ports = 1, - .dtr_rts = keyspan_pda_dtr_rts, - .open = keyspan_pda_open, - .close = keyspan_pda_close, - .write = keyspan_pda_write, - .write_room = keyspan_pda_write_room, - .write_bulk_callback = keyspan_pda_write_bulk_callback, - .read_int_callback = keyspan_pda_rx_interrupt, - .chars_in_buffer = keyspan_pda_chars_in_buffer, - .throttle = keyspan_pda_rx_throttle, - .unthrottle = keyspan_pda_rx_unthrottle, - .set_termios = keyspan_pda_set_termios, - .break_ctl = keyspan_pda_break_ctl, - .tiocmget = keyspan_pda_tiocmget, - .tiocmset = keyspan_pda_tiocmset, - .attach = keyspan_pda_startup, - .release = keyspan_pda_release, -}; - -static struct usb_serial_driver * const serial_drivers[] = { - &keyspan_pda_device, -#ifdef KEYSPAN - &keyspan_pda_fake_device, -#endif -#ifdef XIRCOM - &xircom_pgs_fake_device, -#endif - NULL -}; - -module_usb_serial_driver(keyspan_pda_driver, serial_drivers); - -MODULE_AUTHOR(DRIVER_AUTHOR); -MODULE_DESCRIPTION(DRIVER_DESC); -MODULE_LICENSE("GPL"); - -module_param(debug, bool, S_IRUGO | S_IWUSR); -MODULE_PARM_DESC(debug, "Debug enabled or not"); diff --git a/ANDROID_3.4.5/drivers/usb/serial/keyspan_usa26msg.h b/ANDROID_3.4.5/drivers/usb/serial/keyspan_usa26msg.h deleted file mode 100644 index 3808727d..00000000 --- a/ANDROID_3.4.5/drivers/usb/serial/keyspan_usa26msg.h +++ /dev/null @@ -1,260 +0,0 @@ -/* - usa26msg.h - - Copyright (C) 1998-2000 InnoSys Incorporated. All Rights Reserved - This file is available under a BSD-style copyright - - Keyspan USB Async Message Formats for the USA28X - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are - met: - - 1. Redistributions of source code must retain this licence text - without modification, this list of conditions, and the following - disclaimer. The following copyright notice must appear immediately at - the beginning of all source files: - - Copyright (C) 1998-2000 InnoSys Incorporated. All Rights Reserved - - This file is available under a BSD-style copyright - - 2. The name of InnoSys Incorporated may not be used to endorse or promote - products derived from this software without specific prior written - permission. - - THIS SOFTWARE IS PROVIDED BY INNOSYS CORP. ``AS IS'' AND ANY EXPRESS OR - IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN - NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - SUCH DAMAGE. - - Third revision: USA28X version (aka USA26) - - Buffer formats for RX/TX data messages are not defined by - a structure, but are described here: - - USB OUT (host -> USAxx, transmit) messages contain a - REQUEST_ACK indicator (set to 0xff to request an ACK at the - completion of transmit; 0x00 otherwise), followed by data: - - RQSTACK DAT DAT DAT ... - - with a total data length of 63. - - USB IN (USAxx -> host, receive) messages begin with a status - byte in which the 0x80 bit is either: - - (a) 0x80 bit clear - indicates that the bytes following it are all data - bytes: - - STAT DATA DATA DATA DATA DATA ... - - for a total of up to 63 DATA bytes, - - or: - - (b) 0x80 bit set - indiates that the bytes following alternate data and - status bytes: - - STAT DATA STAT DATA STAT DATA STAT DATA ... - - for a total of up to 32 DATA bytes. - - The valid bits in the STAT bytes are: - - OVERRUN 0x02 - PARITY 0x04 - FRAMING 0x08 - BREAK 0x10 - - Notes: - - (1) The OVERRUN bit can appear in either (a) or (b) format - messages, but the but the PARITY/FRAMING/BREAK bits - only appear in (b) format messages. - (2) For the host to determine the exact point at which the - overrun occurred (to identify the point in the data - stream at which the data was lost), it needs to count - 128 characters, starting at the first character of the - message in which OVERRUN was reported; the lost character(s) - would have been received between the 128th and 129th - characters. - (3) An RX data message in which the first byte has 0x80 clear - serves as a "break off" indicator. - - revision history: - - 1999feb10 add reportHskiaChanges to allow us to ignore them - 1999feb10 add txAckThreshold for fast+loose throughput enhancement - 1999mar30 beef up support for RX error reporting - 1999apr14 add resetDataToggle to control message - 2000jan04 merge with usa17msg.h - 2000jun01 add extended BSD-style copyright text - 2001jul05 change message format to improve OVERRUN case - - Note on shared names: - - In the case of fields which have been merged between the USA17 - and USA26 definitions, the USA26 definition is the first part - of the name and the USA17 definition is the second part of the - name; both meanings are described below. -*/ - -#ifndef __USA26MSG__ -#define __USA26MSG__ - - -struct keyspan_usa26_portControlMessage -{ - /* - there are three types of "commands" sent in the control message: - - 1. configuration changes which must be requested by setting - the corresponding "set" flag (and should only be requested - when necessary, to reduce overhead on the USA26): - */ - u8 setClocking, // BOTH: host requests baud rate be set - baudLo, // BOTH: host does baud divisor calculation - baudHi, // BOTH: baudHi is only used for first port (gives lower rates) - externalClock_txClocking, - // USA26: 0=internal, other=external - // USA17: 0=internal, other=external/RI - rxClocking, // USA17: 0=internal, 1=external/RI, other=external/DSR - - - setLcr, // BOTH: host requests lcr be set - lcr, // BOTH: use PARITY, STOPBITS, DATABITS below - - setFlowControl, // BOTH: host requests flow control be set - ctsFlowControl, // BOTH: 1=use CTS flow control, 0=don't - xonFlowControl, // BOTH: 1=use XON/XOFF flow control, 0=don't - xonChar, // BOTH: specified in current character format - xoffChar, // BOTH: specified in current character format - - setTxTriState_setRts, - // USA26: host requests TX tri-state be set - // USA17: host requests RTS output be set - txTriState_rts, // BOTH: 1=active (normal), 0=tristate (off) - - setHskoa_setDtr, - // USA26: host requests HSKOA output be set - // USA17: host requests DTR output be set - hskoa_dtr, // BOTH: 1=on, 0=off - - setPrescaler, // USA26: host requests prescalar be set (default: 13) - prescaler; // BOTH: specified as N/8; values 8-ff are valid - // must be set any time internal baud rate is set; - // must not be set when external clocking is used - // note: in USA17, prescaler is applied whenever - // setClocking is requested - - /* - 3. configuration data which is simply used as is (no overhead, - but must be specified correctly in every host message). - */ - u8 forwardingLength, // BOTH: forward when this number of chars available - reportHskiaChanges_dsrFlowControl, - // USA26: 1=normal; 0=ignore external clock - // USA17: 1=use DSR flow control, 0=don't - txAckThreshold, // BOTH: 0=not allowed, 1=normal, 2-255 deliver ACK faster - loopbackMode; // BOTH: 0=no loopback, 1=loopback enabled - - /* - 4. commands which are flags only; these are processed in order - (so that, e.g., if both _txOn and _txOff flags are set, the - port ends in a TX_OFF state); any non-zero value is respected - */ - u8 _txOn, // BOTH: enable transmitting (and continue if there's data) - _txOff, // BOTH: stop transmitting - txFlush, // BOTH: toss outbound data - txBreak, // BOTH: turn on break (cleared by _txOn) - rxOn, // BOTH: turn on receiver - rxOff, // BOTH: turn off receiver - rxFlush, // BOTH: toss inbound data - rxForward, // BOTH: forward all inbound data, NOW (as if fwdLen==1) - returnStatus, // BOTH: return current status (even if it hasn't changed) - resetDataToggle;// BOTH: reset data toggle state to DATA0 - -}; - -// defines for bits in lcr -#define USA_DATABITS_5 0x00 -#define USA_DATABITS_6 0x01 -#define USA_DATABITS_7 0x02 -#define USA_DATABITS_8 0x03 -#define STOPBITS_5678_1 0x00 // 1 stop bit for all byte sizes -#define STOPBITS_5_1p5 0x04 // 1.5 stop bits for 5-bit byte -#define STOPBITS_678_2 0x04 // 2 stop bits for 6/7/8-bit byte -#define USA_PARITY_NONE 0x00 -#define USA_PARITY_ODD 0x08 -#define USA_PARITY_EVEN 0x18 -#define PARITY_1 0x28 -#define PARITY_0 0x38 - -// all things called "StatusMessage" are sent on the status endpoint - -struct keyspan_usa26_portStatusMessage // one for each port -{ - u8 port, // BOTH: 0=first, 1=second, other=see below - hskia_cts, // USA26: reports HSKIA pin - // USA17: reports CTS pin - gpia_dcd, // USA26: reports GPIA pin - // USA17: reports DCD pin - dsr, // USA17: reports DSR pin - ri, // USA17: reports RI pin - _txOff, // port has been disabled (by host) - _txXoff, // port is in XOFF state (either host or RX XOFF) - rxEnabled, // as configured by rxOn/rxOff 1=on, 0=off - controlResponse;// 1=a control message has been processed -}; - -// bits in RX data message when STAT byte is included -#define RXERROR_OVERRUN 0x02 -#define RXERROR_PARITY 0x04 -#define RXERROR_FRAMING 0x08 -#define RXERROR_BREAK 0x10 - -struct keyspan_usa26_globalControlMessage -{ - u8 sendGlobalStatus, // 2=request for two status responses - resetStatusToggle, // 1=reset global status toggle - resetStatusCount; // a cycling value -}; - -struct keyspan_usa26_globalStatusMessage -{ - u8 port, // 3 - sendGlobalStatus, // from request, decremented - resetStatusCount; // as in request -}; - -struct keyspan_usa26_globalDebugMessage -{ - u8 port, // 2 - a, - b, - c, - d; -}; - -// ie: the maximum length of an EZUSB endpoint buffer -#define MAX_DATA_LEN 64 - -// update status approx. 60 times a second (16.6666 ms) -#define STATUS_UPDATE_INTERVAL 16 - -// status rationing tuning value (each port gets checked each n ms) -#define STATUS_RATION 10 - -#endif - - diff --git a/ANDROID_3.4.5/drivers/usb/serial/keyspan_usa28msg.h b/ANDROID_3.4.5/drivers/usb/serial/keyspan_usa28msg.h deleted file mode 100644 index dee454c4..00000000 --- a/ANDROID_3.4.5/drivers/usb/serial/keyspan_usa28msg.h +++ /dev/null @@ -1,201 +0,0 @@ -/* - usa28msg.h - - Copyright (C) 1998-2000 InnoSys Incorporated. All Rights Reserved - This file is available under a BSD-style copyright - - Keyspan USB Async Message Formats for the USA26X - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are - met: - - 1. Redistributions of source code must retain this licence text - without modification, this list of conditions, and the following - disclaimer. The following copyright notice must appear immediately at - the beginning of all source files: - - Copyright (C) 1998-2000 InnoSys Incorporated. All Rights Reserved - - This file is available under a BSD-style copyright - - 2. The name of InnoSys Incorporated may not be used to endorse or promote - products derived from this software without specific prior written - permission. - - THIS SOFTWARE IS PROVIDED BY INNOSYS CORP. ``AS IS'' AND ANY EXPRESS OR - IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN - NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - SUCH DAMAGE. - - Note: these message formats are common to USA18, USA19, and USA28; - (for USA28X, see usa26msg.h) - - Buffer formats for RX/TX data messages are not defined by - a structure, but are described here: - - USB OUT (host -> USA28, transmit) messages contain a - REQUEST_ACK indicator (set to 0xff to request an ACK at the - completion of transmit; 0x00 otherwise), followed by data. - If the port is configured for parity, the data will be an - alternating string of parity and data bytes, so the message - format will be: - - RQSTACK PAR DAT PAR DAT ... - - so the maximum length is 63 bytes (1 + 62, or 31 data bytes); - always an odd number for the total message length. - - If there is no parity, the format is simply: - - RQSTACK DAT DAT DAT ... - - with a total data length of 63. - - USB IN (USA28 -> host, receive) messages contain data and parity - if parity is configred, thusly: - - DAT PAR DAT PAR DAT PAR ... - - for a total of 32 data bytes; - - If parity is not configured, the format is: - - DAT DAT DAT ... - - for a total of 64 data bytes. - - In the TX messages (USB OUT), the 0x01 bit of the PARity byte is - the parity bit. In the RX messages (USB IN), the PARity byte is - the content of the 8051's status register; the parity bit - (RX_PARITY_BIT) is the 0x04 bit. - - revision history: - - 1999may06 add resetDataToggle to control message - 2000mar21 add rs232invalid to status response message - 2000apr04 add 230.4Kb definition to setBaudRate - 2000apr13 add/remove loopbackMode switch - 2000apr13 change definition of setBaudRate to cover 115.2Kb, too - 2000jun01 add extended BSD-style copyright text -*/ - -#ifndef __USA28MSG__ -#define __USA28MSG__ - - -struct keyspan_usa28_portControlMessage -{ - /* - there are four types of "commands" sent in the control message: - - 1. configuration changes which must be requested by setting - the corresponding "set" flag (and should only be requested - when necessary, to reduce overhead on the USA28): - */ - u8 setBaudRate, // 0=don't set, 1=baudLo/Hi, 2=115.2K, 3=230.4K - baudLo, // host does baud divisor calculation - baudHi; // baudHi is only used for first port (gives lower rates) - - /* - 2. configuration changes which are done every time (because it's - hardly more trouble to do them than to check whether to do them): - */ - u8 parity, // 1=use parity, 0=don't - ctsFlowControl, // all except 19Q: 1=use CTS flow control, 0=don't - // 19Q: 0x08:CTSflowControl 0x10:DSRflowControl - xonFlowControl, // 1=use XON/XOFF flow control, 0=don't - rts, // 1=on, 0=off - dtr; // 1=on, 0=off - - /* - 3. configuration data which is simply used as is (no overhead, - but must be correct in every host message). - */ - u8 forwardingLength, // forward when this number of chars available - forwardMs, // forward this many ms after last rx data - breakThreshold, // specified in ms, 1-255 (see note below) - xonChar, // specified in current character format - xoffChar; // specified in current character format - - /* - 4. commands which are flags only; these are processed in order - (so that, e.g., if both _txOn and _txOff flags are set, the - port ends in a TX_OFF state); any non-zero value is respected - */ - u8 _txOn, // enable transmitting (and continue if there's data) - _txOff, // stop transmitting - txFlush, // toss outbound data - txForceXoff, // pretend we've received XOFF - txBreak, // turn on break (leave on until txOn clears it) - rxOn, // turn on receiver - rxOff, // turn off receiver - rxFlush, // toss inbound data - rxForward, // forward all inbound data, NOW - returnStatus, // return current status n times (1 or 2) - resetDataToggle;// reset data toggle state to DATA0 - -}; - -struct keyspan_usa28_portStatusMessage -{ - u8 port, // 0=first, 1=second, 2=global (see below) - cts, - dsr, // (not used in all products) - dcd, - - ri, // (not used in all products) - _txOff, // port has been disabled (by host) - _txXoff, // port is in XOFF state (either host or RX XOFF) - dataLost, // count of lost chars; wraps; not guaranteed exact - - rxEnabled, // as configured by rxOn/rxOff 1=on, 0=off - rxBreak, // 1=we're in break state - rs232invalid, // 1=no valid signals on rs-232 inputs - controlResponse;// 1=a control messages has been processed -}; - -// bit defines in txState -#define TX_OFF 0x01 // requested by host txOff command -#define TX_XOFF 0x02 // either real, or simulated by host - -struct keyspan_usa28_globalControlMessage -{ - u8 sendGlobalStatus, // 2=request for two status responses - resetStatusToggle, // 1=reset global status toggle - resetStatusCount; // a cycling value -}; - -struct keyspan_usa28_globalStatusMessage -{ - u8 port, // 3 - sendGlobalStatus, // from request, decremented - resetStatusCount; // as in request -}; - -struct keyspan_usa28_globalDebugMessage -{ - u8 port, // 2 - n, // typically a count/status byte - b; // typically a data byte -}; - -// ie: the maximum length of an EZUSB endpoint buffer -#define MAX_DATA_LEN 64 - -// the parity bytes have only one significant bit -#define RX_PARITY_BIT 0x04 -#define TX_PARITY_BIT 0x01 - -// update status approx. 60 times a second (16.6666 ms) -#define STATUS_UPDATE_INTERVAL 16 - -#endif - diff --git a/ANDROID_3.4.5/drivers/usb/serial/keyspan_usa49msg.h b/ANDROID_3.4.5/drivers/usb/serial/keyspan_usa49msg.h deleted file mode 100644 index 163b2dea..00000000 --- a/ANDROID_3.4.5/drivers/usb/serial/keyspan_usa49msg.h +++ /dev/null @@ -1,282 +0,0 @@ -/* - usa49msg.h - - Copyright (C) 1998-2000 InnoSys Incorporated. All Rights Reserved - This file is available under a BSD-style copyright - - Keyspan USB Async Message Formats for the USA49W - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are - met: - - 1. Redistributions of source code must retain this licence text - without modification, this list of conditions, and the following - disclaimer. The following copyright notice must appear immediately at - the beginning of all source files: - - Copyright (C) 1998-2000 InnoSys Incorporated. All Rights Reserved - - This file is available under a BSD-style copyright - - 2. The name of InnoSys Incorporated may not be used to endorse or promote - products derived from this software without specific prior written - permission. - - THIS SOFTWARE IS PROVIDED BY INNOSYS CORP. ``AS IS'' AND ANY EXPRESS OR - IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN - NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - SUCH DAMAGE. - - 4th revision: USA49W version - - Buffer formats for RX/TX data messages are not defined by - a structure, but are described here: - - USB OUT (host -> USAxx, transmit) messages contain a - REQUEST_ACK indicator (set to 0xff to request an ACK at the - completion of transmit; 0x00 otherwise), followed by data: - - RQSTACK DAT DAT DAT ... - - with a total data length of 63. - - USB IN (USAxx -> host, receive) messages begin with a status - byte in which the 0x80 bit is either: - - (a) 0x80 bit clear - indicates that the bytes following it are all data - bytes: - - STAT DATA DATA DATA DATA DATA ... - - for a total of up to 63 DATA bytes, - - or: - - (b) 0x80 bit set - indiates that the bytes following alternate data and - status bytes: - - STAT DATA STAT DATA STAT DATA STAT DATA ... - - for a total of up to 32 DATA bytes. - - The valid bits in the STAT bytes are: - - OVERRUN 0x02 - PARITY 0x04 - FRAMING 0x08 - BREAK 0x10 - - Notes: - - (1) The OVERRUN bit can appear in either (a) or (b) format - messages, but the but the PARITY/FRAMING/BREAK bits - only appear in (b) format messages. - (2) For the host to determine the exact point at which the - overrun occurred (to identify the point in the data - stream at which the data was lost), it needs to count - 128 characters, starting at the first character of the - message in which OVERRUN was reported; the lost character(s) - would have been received between the 128th and 129th - characters. - (3) An RX data message in which the first byte has 0x80 clear - serves as a "break off" indicator. - (4) a control message specifying disablePort will be answered - with a status message, but no further status will be sent - until a control messages with enablePort is sent - - revision history: - - 1999feb10 add reportHskiaChanges to allow us to ignore them - 1999feb10 add txAckThreshold for fast+loose throughput enhancement - 1999mar30 beef up support for RX error reporting - 1999apr14 add resetDataToggle to control message - 2000jan04 merge with usa17msg.h - 2000mar08 clone from usa26msg.h -> usa49msg.h - 2000mar09 change to support 4 ports - 2000may03 change external clocking to match USA-49W hardware - 2000jun01 add extended BSD-style copyright text - 2001jul05 change message format to improve OVERRUN case -*/ - -#ifndef __USA49MSG__ -#define __USA49MSG__ - - -/* - Host->device messages sent on the global control endpoint: - - portNumber message - ---------- -------------------- - 0,1,2,3 portControlMessage - 0x80 globalControlMessage -*/ - -struct keyspan_usa49_portControlMessage -{ - /* - 0. 0/1/2/3 port control message follows - 0x80 set non-port control message follows - */ - u8 portNumber, - - /* - there are three types of "commands" sent in the control message: - - 1. configuration changes which must be requested by setting - the corresponding "set" flag (and should only be requested - when necessary, to reduce overhead on the USA26): - */ - setClocking, // host requests baud rate be set - baudLo, // host does baud divisor calculation - baudHi, // baudHi is only used for first port (gives lower rates) - prescaler, // specified as N/8; values 8-ff are valid - // must be set any time internal baud rate is set; - txClocking, // 0=internal, 1=external/DSR - rxClocking, // 0=internal, 1=external/DSR - - setLcr, // host requests lcr be set - lcr, // use PARITY, STOPBITS, DATABITS below - - setFlowControl, // host requests flow control be set - ctsFlowControl, // 1=use CTS flow control, 0=don't - xonFlowControl, // 1=use XON/XOFF flow control, 0=don't - xonChar, // specified in current character format - xoffChar, // specified in current character format - - setRts, // host requests RTS output be set - rts, // 1=active, 0=inactive - - setDtr, // host requests DTR output be set - dtr; // 1=on, 0=off - - - /* - 3. configuration data which is simply used as is (no overhead, - but must be specified correctly in every host message). - */ - u8 forwardingLength, // forward when this number of chars available - dsrFlowControl, // 1=use DSR flow control, 0=don't - txAckThreshold, // 0=not allowed, 1=normal, 2-255 deliver ACK faster - loopbackMode; // 0=no loopback, 1=loopback enabled - - /* - 4. commands which are flags only; these are processed in order - (so that, e.g., if both _txOn and _txOff flags are set, the - port ends in a TX_OFF state); any non-zero value is respected - */ - u8 _txOn, // enable transmitting (and continue if there's data) - _txOff, // stop transmitting - txFlush, // toss outbound data - txBreak, // turn on break (cleared by _txOn) - rxOn, // turn on receiver - rxOff, // turn off receiver - rxFlush, // toss inbound data - rxForward, // forward all inbound data, NOW (as if fwdLen==1) - returnStatus, // return current status (even if it hasn't changed) - resetDataToggle,// reset data toggle state to DATA0 - enablePort, // start servicing port (move data, check status) - disablePort; // stop servicing port (does implicit tx/rx flush/off) - -}; - -// defines for bits in lcr -#define USA_DATABITS_5 0x00 -#define USA_DATABITS_6 0x01 -#define USA_DATABITS_7 0x02 -#define USA_DATABITS_8 0x03 -#define STOPBITS_5678_1 0x00 // 1 stop bit for all byte sizes -#define STOPBITS_5_1p5 0x04 // 1.5 stop bits for 5-bit byte -#define STOPBITS_678_2 0x04 // 2 stop bits for 6/7/8-bit byte -#define USA_PARITY_NONE 0x00 -#define USA_PARITY_ODD 0x08 -#define USA_PARITY_EVEN 0x18 -#define PARITY_1 0x28 -#define PARITY_0 0x38 - -/* - during normal operation, status messages are returned - to the host whenever the board detects changes. In some - circumstances (e.g. Windows), status messages from the - device cause problems; to shut them off, the host issues - a control message with the disableStatusMessages flags - set (to any non-zero value). The device will respond to - this message, and then suppress further status messages; - it will resume sending status messages any time the host - sends any control message (either global or port-specific). -*/ - -struct keyspan_usa49_globalControlMessage -{ - u8 portNumber, // 0x80 - sendGlobalStatus, // 1/2=number of status responses requested - resetStatusToggle, // 1=reset global status toggle - resetStatusCount, // a cycling value - remoteWakeupEnable, // 0x10=P1, 0x20=P2, 0x40=P3, 0x80=P4 - disableStatusMessages; // 1=send no status until host talks -}; - -/* - Device->host messages send on the global status endpoint - - portNumber message - ---------- -------------------- - 0x00,0x01,0x02,0x03 portStatusMessage - 0x80 globalStatusMessage - 0x81 globalDebugMessage -*/ - -struct keyspan_usa49_portStatusMessage // one for each port -{ - u8 portNumber, // 0,1,2,3 - cts, // reports CTS pin - dcd, // reports DCD pin - dsr, // reports DSR pin - ri, // reports RI pin - _txOff, // transmit has been disabled (by host) - _txXoff, // transmit is in XOFF state (either host or RX XOFF) - rxEnabled, // as configured by rxOn/rxOff 1=on, 0=off - controlResponse,// 1=a control message has been processed - txAck, // ACK (data TX complete) - rs232valid; // RS-232 signal valid -}; - -// bits in RX data message when STAT byte is included -#define RXERROR_OVERRUN 0x02 -#define RXERROR_PARITY 0x04 -#define RXERROR_FRAMING 0x08 -#define RXERROR_BREAK 0x10 - -struct keyspan_usa49_globalStatusMessage -{ - u8 portNumber, // 0x80=globalStatusMessage - sendGlobalStatus, // from request, decremented - resetStatusCount; // as in request -}; - -struct keyspan_usa49_globalDebugMessage -{ - u8 portNumber, // 0x81=globalDebugMessage - n, // typically a count/status byte - b; // typically a data byte -}; - -// ie: the maximum length of an EZUSB endpoint buffer -#define MAX_DATA_LEN 64 - -// update status approx. 60 times a second (16.6666 ms) -#define STATUS_UPDATE_INTERVAL 16 - -// status rationing tuning value (each port gets checked each n ms) -#define STATUS_RATION 10 - -#endif diff --git a/ANDROID_3.4.5/drivers/usb/serial/keyspan_usa67msg.h b/ANDROID_3.4.5/drivers/usb/serial/keyspan_usa67msg.h deleted file mode 100644 index 20fa3e2f..00000000 --- a/ANDROID_3.4.5/drivers/usb/serial/keyspan_usa67msg.h +++ /dev/null @@ -1,254 +0,0 @@ -/* - usa67msg.h - - Copyright (c) 1998-2007 InnoSys Incorporated. All Rights Reserved - This file is available under a BSD-style copyright - - Keyspan USB Async Firmware to run on Anchor FX1 - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are - met: - - 1. Redistributions of source code must retain this licence text - without modification, this list of conditions, and the following - disclaimer. The following copyright notice must appear immediately at - the beginning of all source files: - - Copyright (c) 1998-2007 InnoSys Incorporated. All Rights Reserved - - This file is available under a BSD-style copyright - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - 3. The name of InnoSys Incorprated may not be used to endorse or promote - products derived from this software without specific prior written - permission. - - THIS SOFTWARE IS PROVIDED BY INNOSYS CORP. ``AS IS'' AND ANY EXPRESS OR - IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN - NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - SUCH DAMAGE. - - Fourth revision: This message format supports the USA28XG - - Buffer formats for RX/TX data messages are not defined by - a structure, but are described here: - - USB OUT (host -> USAxx, transmit) messages contain a - REQUEST_ACK indicator (set to 0xff to request an ACK at the - completion of transmit; 0x00 otherwise), followed by data: - - RQSTACK DAT DAT DAT ... - - with a total data length of up to 63. - - USB IN (USAxx -> host, receive) messages begin with a status - byte in which the 0x80 bit is either: - - (a) 0x80 bit clear - indicates that the bytes following it are all data - bytes: - - STAT DATA DATA DATA DATA DATA ... - - for a total of up to 63 DATA bytes, - - or: - - (b) 0x80 bit set - indiates that the bytes following alternate data and - status bytes: - - STAT DATA STAT DATA STAT DATA STAT DATA ... - - for a total of up to 32 DATA bytes. - - The valid bits in the STAT bytes are: - - OVERRUN 0x02 - PARITY 0x04 - FRAMING 0x08 - BREAK 0x10 - - Notes: - - (1) The OVERRUN bit can appear in either (a) or (b) format - messages, but the but the PARITY/FRAMING/BREAK bits - only appear in (b) format messages. - (2) For the host to determine the exact point at which the - overrun occurred (to identify the point in the data - stream at which the data was lost), it needs to count - 128 characters, starting at the first character of the - message in which OVERRUN was reported; the lost character(s) - would have been received between the 128th and 129th - characters. - (3) An RX data message in which the first byte has 0x80 clear - serves as a "break off" indicator. - - revision history: - - 1999feb10 add reportHskiaChanges to allow us to ignore them - 1999feb10 add txAckThreshold for fast+loose throughput enhancement - 1999mar30 beef up support for RX error reporting - 1999apr14 add resetDataToggle to control message - 2000jan04 merge with usa17msg.h - 2000jun01 add extended BSD-style copyright text - 2001jul05 change message format to improve OVERRUN case - 2002jun05 update copyright date, improve comments - 2006feb06 modify for FX1 chip - -*/ - -#ifndef __USA67MSG__ -#define __USA67MSG__ - - -// all things called "ControlMessage" are sent on the 'control' endpoint - -typedef struct keyspan_usa67_portControlMessage -{ - u8 port; // 0 or 1 (selects port) - /* - there are three types of "commands" sent in the control message: - - 1. configuration changes which must be requested by setting - the corresponding "set" flag (and should only be requested - when necessary, to reduce overhead on the device): - */ - u8 setClocking, // host requests baud rate be set - baudLo, // host does baud divisor calculation - baudHi, // baudHi is only used for first port (gives lower rates) - externalClock_txClocking, - // 0=internal, other=external - - setLcr, // host requests lcr be set - lcr, // use PARITY, STOPBITS, DATABITS below - - setFlowControl, // host requests flow control be set - ctsFlowControl, // 1=use CTS flow control, 0=don't - xonFlowControl, // 1=use XON/XOFF flow control, 0=don't - xonChar, // specified in current character format - xoffChar, // specified in current character format - - setTxTriState_setRts, - // host requests TX tri-state be set - txTriState_rts, // 1=active (normal), 0=tristate (off) - - setHskoa_setDtr, - // host requests HSKOA output be set - hskoa_dtr, // 1=on, 0=off - - setPrescaler, // host requests prescalar be set (default: 13) - prescaler; // specified as N/8; values 8-ff are valid - // must be set any time internal baud rate is set; - // must not be set when external clocking is used - - /* - 3. configuration data which is simply used as is (no overhead, - but must be specified correctly in every host message). - */ - u8 forwardingLength, // forward when this number of chars available - reportHskiaChanges_dsrFlowControl, - // 1=normal; 0=ignore external clock - // 1=use DSR flow control, 0=don't - txAckThreshold, // 0=not allowed, 1=normal, 2-255 deliver ACK faster - loopbackMode; // 0=no loopback, 1=loopback enabled - - /* - 4. commands which are flags only; these are processed in order - (so that, e.g., if both _txOn and _txOff flags are set, the - port ends in a TX_OFF state); any non-zero value is respected - */ - u8 _txOn, // enable transmitting (and continue if there's data) - _txOff, // stop transmitting - txFlush, // toss outbound data - txBreak, // turn on break (cleared by _txOn) - rxOn, // turn on receiver - rxOff, // turn off receiver - rxFlush, // toss inbound data - rxForward, // forward all inbound data, NOW (as if fwdLen==1) - returnStatus, // return current status (even if it hasn't changed) - resetDataToggle;// reset data toggle state to DATA0 - -} keyspan_usa67_portControlMessage; - -// defines for bits in lcr -#define USA_DATABITS_5 0x00 -#define USA_DATABITS_6 0x01 -#define USA_DATABITS_7 0x02 -#define USA_DATABITS_8 0x03 -#define STOPBITS_5678_1 0x00 // 1 stop bit for all byte sizes -#define STOPBITS_5_1p5 0x04 // 1.5 stop bits for 5-bit byte -#define STOPBITS_678_2 0x04 // 2 stop bits for 6/7/8-bit byte -#define USA_PARITY_NONE 0x00 -#define USA_PARITY_ODD 0x08 -#define USA_PARITY_EVEN 0x18 -#define PARITY_1 0x28 -#define PARITY_0 0x38 - -// all things called "StatusMessage" are sent on the status endpoint - -typedef struct keyspan_usa67_portStatusMessage // one for each port -{ - u8 port, // 0=first, 1=second, other=see below - hskia_cts, // reports HSKIA pin - gpia_dcd, // reports GPIA pin - _txOff, // port has been disabled (by host) - _txXoff, // port is in XOFF state (either host or RX XOFF) - txAck, // indicates a TX message acknowledgement - rxEnabled, // as configured by rxOn/rxOff 1=on, 0=off - controlResponse;// 1=a control message has been processed -} keyspan_usa67_portStatusMessage; - -// bits in RX data message when STAT byte is included -#define RXERROR_OVERRUN 0x02 -#define RXERROR_PARITY 0x04 -#define RXERROR_FRAMING 0x08 -#define RXERROR_BREAK 0x10 - -typedef struct keyspan_usa67_globalControlMessage -{ - u8 port, // 3 - sendGlobalStatus, // 2=request for two status responses - resetStatusToggle, // 1=reset global status toggle - resetStatusCount; // a cycling value -} keyspan_usa67_globalControlMessage; - -typedef struct keyspan_usa67_globalStatusMessage -{ - u8 port, // 3 - sendGlobalStatus, // from request, decremented - resetStatusCount; // as in request -} keyspan_usa67_globalStatusMessage; - -typedef struct keyspan_usa67_globalDebugMessage -{ - u8 port, // 2 - a, - b, - c, - d; -} keyspan_usa67_globalDebugMessage; - -// ie: the maximum length of an FX1 endpoint buffer -#define MAX_DATA_LEN 64 - -// update status approx. 60 times a second (16.6666 ms) -#define STATUS_UPDATE_INTERVAL 16 - -// status rationing tuning value (each port gets checked each n ms) -#define STATUS_RATION 10 - -#endif - - diff --git a/ANDROID_3.4.5/drivers/usb/serial/keyspan_usa90msg.h b/ANDROID_3.4.5/drivers/usb/serial/keyspan_usa90msg.h deleted file mode 100644 index 86708ecd..00000000 --- a/ANDROID_3.4.5/drivers/usb/serial/keyspan_usa90msg.h +++ /dev/null @@ -1,198 +0,0 @@ -/* - usa90msg.h - - Copyright (c) 1998-2003 InnoSys Incorporated. All Rights Reserved - This file is available under a BSD-style copyright - - Keyspan USB Async Message Formats for the USA19HS - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are - met: - - 1. Redistributions of source code must retain this licence text - without modification, this list of conditions, and the following - disclaimer. The following copyright notice must appear immediately at - the beginning of all source files: - - Copyright (c) 1998-2003 InnoSys Incorporated. All Rights Reserved - - This file is available under a BSD-style copyright - - 2. The name of InnoSys Incorporated may not be used to endorse or promote - products derived from this software without specific prior written - permission. - - THIS SOFTWARE IS PROVIDED BY INNOSYS CORP. ``AS IS'' AND ANY EXPRESS OR - IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN - NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - SUCH DAMAGE. - - Revisions: - - 2003feb14 add setTxMode/txMode and cancelRxXoff to portControl - 2003mar21 change name of PARITY_0/1 to add MARK/SPACE -*/ - -#ifndef __USA90MSG__ -#define __USA90MSG__ - -struct keyspan_usa90_portControlMessage -{ - /* - there are three types of "commands" sent in the control message: - - 1. configuration changes which must be requested by setting - the corresponding "set" flag (and should only be requested - when necessary, to reduce overhead on the device): - */ - - u8 setClocking, // host requests baud rate be set - baudLo, // host does baud divisor calculation - baudHi, // host does baud divisor calculation - - setLcr, // host requests lcr be set - lcr, // use PARITY, STOPBITS, DATABITS below - - setRxMode, // set receive mode - rxMode, // RXMODE_DMA or RXMODE_BYHAND - - setTxMode, // set transmit mode - txMode, // TXMODE_DMA or TXMODE_BYHAND - - setTxFlowControl, // host requests tx flow control be set - txFlowControl , // use TX_FLOW... bits below - setRxFlowControl, // host requests rx flow control be set - rxFlowControl, // use RX_FLOW... bits below - sendXoff, // host requests XOFF transmitted immediately - sendXon, // host requests XON char transmitted - xonChar, // specified in current character format - xoffChar, // specified in current character format - - sendChar, // host requests char transmitted immediately - txChar, // character to send - - setRts, // host requests RTS output be set - rts, // 1=on, 0=off - setDtr, // host requests DTR output be set - dtr; // 1=on, 0=off - - - /* - 2. configuration data which is simply used as is - and must be specified correctly in every host message. - */ - - u8 rxForwardingLength, // forward when this number of chars available - rxForwardingTimeout, // (1-31 in ms) - txAckSetting; // 0=don't ack, 1=normal, 2-255 TBD... - /* - 3. Firmware states which cause actions if they change - and must be specified correctly in every host message. - */ - - u8 portEnabled, // 0=disabled, 1=enabled - txFlush, // 0=normal, 1=toss outbound data - txBreak, // 0=break off, 1=break on - loopbackMode; // 0=no loopback, 1=loopback enabled - - /* - 4. commands which are flags only; these are processed in order - (so that, e.g., if rxFlush and rxForward flags are set, the - port will have no data to forward); any non-zero value - is respected - */ - - u8 rxFlush, // toss inbound data - rxForward, // forward all inbound data, NOW (as if fwdLen==1) - cancelRxXoff, // cancel any receive XOFF state (_txXoff) - returnStatus; // return current status NOW -}; - -// defines for bits in lcr -#define USA_DATABITS_5 0x00 -#define USA_DATABITS_6 0x01 -#define USA_DATABITS_7 0x02 -#define USA_DATABITS_8 0x03 -#define STOPBITS_5678_1 0x00 // 1 stop bit for all byte sizes -#define STOPBITS_5_1p5 0x04 // 1.5 stop bits for 5-bit byte -#define STOPBITS_678_2 0x04 // 2 stop bits for 6-8 bit byte -#define USA_PARITY_NONE 0x00 -#define USA_PARITY_ODD 0x08 -#define USA_PARITY_EVEN 0x18 -#define PARITY_MARK_1 0x28 // force parity MARK -#define PARITY_SPACE_0 0x38 // force parity SPACE - -#define TXFLOW_CTS 0x04 -#define TXFLOW_DSR 0x08 -#define TXFLOW_XOFF 0x01 -#define TXFLOW_XOFF_ANY 0x02 -#define TXFLOW_XOFF_BITS (TXFLOW_XOFF | TXFLOW_XOFF_ANY) - -#define RXFLOW_XOFF 0x10 -#define RXFLOW_RTS 0x20 -#define RXFLOW_DTR 0x40 -#define RXFLOW_DSR_SENSITIVITY 0x80 - -#define RXMODE_BYHAND 0x00 -#define RXMODE_DMA 0x02 - -#define TXMODE_BYHAND 0x00 -#define TXMODE_DMA 0x02 - - -// all things called "StatusMessage" are sent on the status endpoint - -struct keyspan_usa90_portStatusMessage -{ - u8 msr, // reports the actual MSR register - cts, // reports CTS pin - dcd, // reports DCD pin - dsr, // reports DSR pin - ri, // reports RI pin - _txXoff, // port is in XOFF state (we received XOFF) - rxBreak, // reports break state - rxOverrun, // count of overrun errors (since last reported) - rxParity, // count of parity errors (since last reported) - rxFrame, // count of frame errors (since last reported) - portState, // PORTSTATE_xxx bits (useful for debugging) - messageAck, // message acknowledgement - charAck, // character acknowledgement - controlResponse; // (value = returnStatus) a control message has been processed -}; - -// bits in RX data message when STAT byte is included - -#define RXERROR_OVERRUN 0x02 -#define RXERROR_PARITY 0x04 -#define RXERROR_FRAMING 0x08 -#define RXERROR_BREAK 0x10 - -#define PORTSTATE_ENABLED 0x80 -#define PORTSTATE_TXFLUSH 0x01 -#define PORTSTATE_TXBREAK 0x02 -#define PORTSTATE_LOOPBACK 0x04 - -// MSR bits - -#define USA_MSR_dCTS 0x01 // CTS has changed since last report -#define USA_MSR_dDSR 0x02 -#define USA_MSR_dRI 0x04 -#define USA_MSR_dDCD 0x08 - -#define USA_MSR_CTS 0x10 // current state of CTS -#define USA_MSR_DSR 0x20 -#define USA_USA_MSR_RI 0x40 -#define MSR_DCD 0x80 - -// ie: the maximum length of an endpoint buffer -#define MAX_DATA_LEN 64 - -#endif diff --git a/ANDROID_3.4.5/drivers/usb/serial/kl5kusb105.c b/ANDROID_3.4.5/drivers/usb/serial/kl5kusb105.c deleted file mode 100644 index 10f05407..00000000 --- a/ANDROID_3.4.5/drivers/usb/serial/kl5kusb105.c +++ /dev/null @@ -1,702 +0,0 @@ -/* - * KLSI KL5KUSB105 chip RS232 converter driver - * - * Copyright (C) 2010 Johan Hovold <jhovold@gmail.com> - * Copyright (C) 2001 Utz-Uwe Haus <haus@uuhaus.de> - * - * 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. - * - * All information about the device was acquired using SniffUSB ans snoopUSB - * on Windows98. - * It was written out of frustration with the PalmConnect USB Serial adapter - * sold by Palm Inc. - * Neither Palm, nor their contractor (MCCI) or their supplier (KLSI) provided - * information that was not already available. - * - * It seems that KLSI bought some silicon-design information from ScanLogic, - * whose SL11R processor is at the core of the KL5KUSB chipset from KLSI. - * KLSI has firmware available for their devices; it is probable that the - * firmware differs from that used by KLSI in their products. If you have an - * original KLSI device and can provide some information on it, I would be - * most interested in adding support for it here. If you have any information - * on the protocol used (or find errors in my reverse-engineered stuff), please - * let me know. - * - * The code was only tested with a PalmConnect USB adapter; if you - * are adventurous, try it with any KLSI-based device and let me know how it - * breaks so that I can fix it! - */ - -/* TODO: - * check modem line signals - * implement handshaking or decide that we do not support it - */ - -#include <linux/kernel.h> -#include <linux/errno.h> -#include <linux/init.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/uaccess.h> -#include <asm/unaligned.h> -#include <linux/usb.h> -#include <linux/usb/serial.h> -#include "kl5kusb105.h" - -static bool debug; - -/* - * Version Information - */ -#define DRIVER_VERSION "v0.4" -#define DRIVER_AUTHOR "Utz-Uwe Haus <haus@uuhaus.de>, Johan Hovold <jhovold@gmail.com>" -#define DRIVER_DESC "KLSI KL5KUSB105 chipset USB->Serial Converter driver" - - -/* - * Function prototypes - */ -static int klsi_105_startup(struct usb_serial *serial); -static void klsi_105_release(struct usb_serial *serial); -static int klsi_105_open(struct tty_struct *tty, struct usb_serial_port *port); -static void klsi_105_close(struct usb_serial_port *port); -static void klsi_105_set_termios(struct tty_struct *tty, - struct usb_serial_port *port, struct ktermios *old); -static int klsi_105_tiocmget(struct tty_struct *tty); -static int klsi_105_tiocmset(struct tty_struct *tty, - unsigned int set, unsigned int clear); -static void klsi_105_process_read_urb(struct urb *urb); -static int klsi_105_prepare_write_buffer(struct usb_serial_port *port, - void *dest, size_t size); - -/* - * All of the device info needed for the KLSI converters. - */ -static const struct usb_device_id id_table[] = { - { USB_DEVICE(PALMCONNECT_VID, PALMCONNECT_PID) }, - { USB_DEVICE(KLSI_VID, KLSI_KL5KUSB105D_PID) }, - { } /* Terminating entry */ -}; - -MODULE_DEVICE_TABLE(usb, id_table); - -static struct usb_driver kl5kusb105d_driver = { - .name = "kl5kusb105d", - .probe = usb_serial_probe, - .disconnect = usb_serial_disconnect, - .id_table = id_table, -}; - -static struct usb_serial_driver kl5kusb105d_device = { - .driver = { - .owner = THIS_MODULE, - .name = "kl5kusb105d", - }, - .description = "KL5KUSB105D / PalmConnect", - .id_table = id_table, - .num_ports = 1, - .bulk_out_size = 64, - .open = klsi_105_open, - .close = klsi_105_close, - .set_termios = klsi_105_set_termios, - /*.break_ctl = klsi_105_break_ctl,*/ - .tiocmget = klsi_105_tiocmget, - .tiocmset = klsi_105_tiocmset, - .attach = klsi_105_startup, - .release = klsi_105_release, - .throttle = usb_serial_generic_throttle, - .unthrottle = usb_serial_generic_unthrottle, - .process_read_urb = klsi_105_process_read_urb, - .prepare_write_buffer = klsi_105_prepare_write_buffer, -}; - -static struct usb_serial_driver * const serial_drivers[] = { - &kl5kusb105d_device, NULL -}; - -struct klsi_105_port_settings { - __u8 pktlen; /* always 5, it seems */ - __u8 baudrate; - __u8 databits; - __u8 unknown1; - __u8 unknown2; -} __attribute__ ((packed)); - -struct klsi_105_private { - struct klsi_105_port_settings cfg; - struct ktermios termios; - unsigned long line_state; /* modem line settings */ - spinlock_t lock; -}; - - -/* - * Handle vendor specific USB requests - */ - - -#define KLSI_TIMEOUT 5000 /* default urb timeout */ - -static int klsi_105_chg_port_settings(struct usb_serial_port *port, - struct klsi_105_port_settings *settings) -{ - int rc; - - rc = usb_control_msg(port->serial->dev, - usb_sndctrlpipe(port->serial->dev, 0), - KL5KUSB105A_SIO_SET_DATA, - USB_TYPE_VENDOR | USB_DIR_OUT | USB_RECIP_INTERFACE, - 0, /* value */ - 0, /* index */ - settings, - sizeof(struct klsi_105_port_settings), - KLSI_TIMEOUT); - if (rc < 0) - dev_err(&port->dev, - "Change port settings failed (error = %d)\n", rc); - dev_info(&port->serial->dev->dev, - "%d byte block, baudrate %x, databits %d, u1 %d, u2 %d\n", - settings->pktlen, settings->baudrate, settings->databits, - settings->unknown1, settings->unknown2); - return rc; -} - -/* translate a 16-bit status value from the device to linux's TIO bits */ -static unsigned long klsi_105_status2linestate(const __u16 status) -{ - unsigned long res = 0; - - res = ((status & KL5KUSB105A_DSR) ? TIOCM_DSR : 0) - | ((status & KL5KUSB105A_CTS) ? TIOCM_CTS : 0) - ; - - return res; -} - -/* - * Read line control via vendor command and return result through - * *line_state_p - */ -/* It seems that the status buffer has always only 2 bytes length */ -#define KLSI_STATUSBUF_LEN 2 -static int klsi_105_get_line_state(struct usb_serial_port *port, - unsigned long *line_state_p) -{ - int rc; - u8 *status_buf; - __u16 status; - - dev_info(&port->serial->dev->dev, "sending SIO Poll request\n"); - - status_buf = kmalloc(KLSI_STATUSBUF_LEN, GFP_KERNEL); - if (!status_buf) { - dev_err(&port->dev, "%s - out of memory for status buffer.\n", - __func__); - return -ENOMEM; - } - status_buf[0] = 0xff; - status_buf[1] = 0xff; - rc = usb_control_msg(port->serial->dev, - usb_rcvctrlpipe(port->serial->dev, 0), - KL5KUSB105A_SIO_POLL, - USB_TYPE_VENDOR | USB_DIR_IN, - 0, /* value */ - 0, /* index */ - status_buf, KLSI_STATUSBUF_LEN, - 10000 - ); - if (rc < 0) - dev_err(&port->dev, "Reading line status failed (error = %d)\n", - rc); - else { - status = get_unaligned_le16(status_buf); - - dev_info(&port->serial->dev->dev, "read status %x %x", - status_buf[0], status_buf[1]); - - *line_state_p = klsi_105_status2linestate(status); - } - - kfree(status_buf); - return rc; -} - - -/* - * Driver's tty interface functions - */ - -static int klsi_105_startup(struct usb_serial *serial) -{ - struct klsi_105_private *priv; - int i; - - /* check if we support the product id (see keyspan.c) - * FIXME - */ - - /* allocate the private data structure */ - for (i = 0; i < serial->num_ports; i++) { - priv = kmalloc(sizeof(struct klsi_105_private), - GFP_KERNEL); - if (!priv) { - dbg("%skmalloc for klsi_105_private failed.", __func__); - i--; - goto err_cleanup; - } - /* set initial values for control structures */ - priv->cfg.pktlen = 5; - priv->cfg.baudrate = kl5kusb105a_sio_b9600; - priv->cfg.databits = kl5kusb105a_dtb_8; - priv->cfg.unknown1 = 0; - priv->cfg.unknown2 = 1; - - priv->line_state = 0; - - usb_set_serial_port_data(serial->port[i], priv); - - spin_lock_init(&priv->lock); - - /* priv->termios is left uninitialized until port opening */ - init_waitqueue_head(&serial->port[i]->write_wait); - } - - return 0; - -err_cleanup: - for (; i >= 0; i--) { - priv = usb_get_serial_port_data(serial->port[i]); - kfree(priv); - usb_set_serial_port_data(serial->port[i], NULL); - } - return -ENOMEM; -} - -static void klsi_105_release(struct usb_serial *serial) -{ - int i; - - dbg("%s", __func__); - - for (i = 0; i < serial->num_ports; ++i) - kfree(usb_get_serial_port_data(serial->port[i])); -} - -static int klsi_105_open(struct tty_struct *tty, struct usb_serial_port *port) -{ - struct klsi_105_private *priv = usb_get_serial_port_data(port); - int retval = 0; - int rc; - int i; - unsigned long line_state; - struct klsi_105_port_settings *cfg; - unsigned long flags; - - dbg("%s port %d", __func__, port->number); - - /* Do a defined restart: - * Set up sane default baud rate and send the 'READ_ON' - * vendor command. - * FIXME: set modem line control (how?) - * Then read the modem line control and store values in - * priv->line_state. - */ - cfg = kmalloc(sizeof(*cfg), GFP_KERNEL); - if (!cfg) { - dev_err(&port->dev, "%s - out of memory for config buffer.\n", - __func__); - return -ENOMEM; - } - cfg->pktlen = 5; - cfg->baudrate = kl5kusb105a_sio_b9600; - cfg->databits = kl5kusb105a_dtb_8; - cfg->unknown1 = 0; - cfg->unknown2 = 1; - klsi_105_chg_port_settings(port, cfg); - - /* set up termios structure */ - spin_lock_irqsave(&priv->lock, flags); - priv->termios.c_iflag = tty->termios->c_iflag; - priv->termios.c_oflag = tty->termios->c_oflag; - priv->termios.c_cflag = tty->termios->c_cflag; - priv->termios.c_lflag = tty->termios->c_lflag; - for (i = 0; i < NCCS; i++) - priv->termios.c_cc[i] = tty->termios->c_cc[i]; - priv->cfg.pktlen = cfg->pktlen; - priv->cfg.baudrate = cfg->baudrate; - priv->cfg.databits = cfg->databits; - priv->cfg.unknown1 = cfg->unknown1; - priv->cfg.unknown2 = cfg->unknown2; - spin_unlock_irqrestore(&priv->lock, flags); - - /* READ_ON and urb submission */ - rc = usb_serial_generic_open(tty, port); - if (rc) { - retval = rc; - goto exit; - } - - rc = usb_control_msg(port->serial->dev, - usb_sndctrlpipe(port->serial->dev, 0), - KL5KUSB105A_SIO_CONFIGURE, - USB_TYPE_VENDOR|USB_DIR_OUT|USB_RECIP_INTERFACE, - KL5KUSB105A_SIO_CONFIGURE_READ_ON, - 0, /* index */ - NULL, - 0, - KLSI_TIMEOUT); - if (rc < 0) { - dev_err(&port->dev, "Enabling read failed (error = %d)\n", rc); - retval = rc; - } else - dbg("%s - enabled reading", __func__); - - rc = klsi_105_get_line_state(port, &line_state); - if (rc >= 0) { - spin_lock_irqsave(&priv->lock, flags); - priv->line_state = line_state; - spin_unlock_irqrestore(&priv->lock, flags); - dbg("%s - read line state 0x%lx", __func__, line_state); - retval = 0; - } else - retval = rc; - -exit: - kfree(cfg); - return retval; -} - -static void klsi_105_close(struct usb_serial_port *port) -{ - int rc; - - dbg("%s port %d", __func__, port->number); - - mutex_lock(&port->serial->disc_mutex); - if (!port->serial->disconnected) { - /* send READ_OFF */ - rc = usb_control_msg(port->serial->dev, - usb_sndctrlpipe(port->serial->dev, 0), - KL5KUSB105A_SIO_CONFIGURE, - USB_TYPE_VENDOR | USB_DIR_OUT, - KL5KUSB105A_SIO_CONFIGURE_READ_OFF, - 0, /* index */ - NULL, 0, - KLSI_TIMEOUT); - if (rc < 0) - dev_err(&port->dev, - "Disabling read failed (error = %d)\n", rc); - } - mutex_unlock(&port->serial->disc_mutex); - - /* shutdown our bulk reads and writes */ - usb_serial_generic_close(port); - - /* wgg - do I need this? I think so. */ - usb_kill_urb(port->interrupt_in_urb); -} - -/* We need to write a complete 64-byte data block and encode the - * number actually sent in the first double-byte, LSB-order. That - * leaves at most 62 bytes of payload. - */ -#define KLSI_HDR_LEN 2 -static int klsi_105_prepare_write_buffer(struct usb_serial_port *port, - void *dest, size_t size) -{ - unsigned char *buf = dest; - int count; - - count = kfifo_out_locked(&port->write_fifo, buf + KLSI_HDR_LEN, size, - &port->lock); - put_unaligned_le16(count, buf); - - return count + KLSI_HDR_LEN; -} - -/* The data received is preceded by a length double-byte in LSB-first order. - */ -static void klsi_105_process_read_urb(struct urb *urb) -{ - struct usb_serial_port *port = urb->context; - unsigned char *data = urb->transfer_buffer; - struct tty_struct *tty; - unsigned len; - - /* empty urbs seem to happen, we ignore them */ - if (!urb->actual_length) - return; - - if (urb->actual_length <= KLSI_HDR_LEN) { - dbg("%s - malformed packet", __func__); - return; - } - - tty = tty_port_tty_get(&port->port); - if (!tty) - return; - - len = get_unaligned_le16(data); - if (len > urb->actual_length - KLSI_HDR_LEN) { - dbg("%s - packet length mismatch", __func__); - len = urb->actual_length - KLSI_HDR_LEN; - } - - tty_insert_flip_string(tty, data + KLSI_HDR_LEN, len); - tty_flip_buffer_push(tty); - tty_kref_put(tty); -} - -static void klsi_105_set_termios(struct tty_struct *tty, - struct usb_serial_port *port, - struct ktermios *old_termios) -{ - struct klsi_105_private *priv = usb_get_serial_port_data(port); - unsigned int iflag = tty->termios->c_iflag; - unsigned int old_iflag = old_termios->c_iflag; - unsigned int cflag = tty->termios->c_cflag; - unsigned int old_cflag = old_termios->c_cflag; - struct klsi_105_port_settings *cfg; - unsigned long flags; - speed_t baud; - - cfg = kmalloc(sizeof(*cfg), GFP_KERNEL); - if (!cfg) { - dev_err(&port->dev, "%s - out of memory for config buffer.\n", - __func__); - return; - } - - /* lock while we are modifying the settings */ - spin_lock_irqsave(&priv->lock, flags); - - /* - * Update baud rate - */ - baud = tty_get_baud_rate(tty); - - if ((cflag & CBAUD) != (old_cflag & CBAUD)) { - /* reassert DTR and (maybe) RTS on transition from B0 */ - if ((old_cflag & CBAUD) == B0) { - dbg("%s: baud was B0", __func__); -#if 0 - priv->control_state |= TIOCM_DTR; - /* don't set RTS if using hardware flow control */ - if (!(old_cflag & CRTSCTS)) - priv->control_state |= TIOCM_RTS; - mct_u232_set_modem_ctrl(serial, priv->control_state); -#endif - } - } - switch (baud) { - case 0: /* handled below */ - break; - case 1200: - priv->cfg.baudrate = kl5kusb105a_sio_b1200; - break; - case 2400: - priv->cfg.baudrate = kl5kusb105a_sio_b2400; - break; - case 4800: - priv->cfg.baudrate = kl5kusb105a_sio_b4800; - break; - case 9600: - priv->cfg.baudrate = kl5kusb105a_sio_b9600; - break; - case 19200: - priv->cfg.baudrate = kl5kusb105a_sio_b19200; - break; - case 38400: - priv->cfg.baudrate = kl5kusb105a_sio_b38400; - break; - case 57600: - priv->cfg.baudrate = kl5kusb105a_sio_b57600; - break; - case 115200: - priv->cfg.baudrate = kl5kusb105a_sio_b115200; - break; - default: - dbg("KLSI USB->Serial converter:" - " unsupported baudrate request, using default of 9600"); - priv->cfg.baudrate = kl5kusb105a_sio_b9600; - baud = 9600; - break; - } - if ((cflag & CBAUD) == B0) { - dbg("%s: baud is B0", __func__); - /* Drop RTS and DTR */ - /* maybe this should be simulated by sending read - * disable and read enable messages? - */ - ; -#if 0 - priv->control_state &= ~(TIOCM_DTR | TIOCM_RTS); - mct_u232_set_modem_ctrl(serial, priv->control_state); -#endif - } - tty_encode_baud_rate(tty, baud, baud); - - if ((cflag & CSIZE) != (old_cflag & CSIZE)) { - /* set the number of data bits */ - switch (cflag & CSIZE) { - case CS5: - dbg("%s - 5 bits/byte not supported", __func__); - spin_unlock_irqrestore(&priv->lock, flags); - goto err; - case CS6: - dbg("%s - 6 bits/byte not supported", __func__); - spin_unlock_irqrestore(&priv->lock, flags); - goto err; - case CS7: - priv->cfg.databits = kl5kusb105a_dtb_7; - break; - case CS8: - priv->cfg.databits = kl5kusb105a_dtb_8; - break; - default: - dev_err(&port->dev, - "CSIZE was not CS5-CS8, using default of 8\n"); - priv->cfg.databits = kl5kusb105a_dtb_8; - break; - } - } - - /* - * Update line control register (LCR) - */ - if ((cflag & (PARENB|PARODD)) != (old_cflag & (PARENB|PARODD)) - || (cflag & CSTOPB) != (old_cflag & CSTOPB)) { - /* Not currently supported */ - tty->termios->c_cflag &= ~(PARENB|PARODD|CSTOPB); -#if 0 - priv->last_lcr = 0; - - /* set the parity */ - if (cflag & PARENB) - priv->last_lcr |= (cflag & PARODD) ? - MCT_U232_PARITY_ODD : MCT_U232_PARITY_EVEN; - else - priv->last_lcr |= MCT_U232_PARITY_NONE; - - /* set the number of stop bits */ - priv->last_lcr |= (cflag & CSTOPB) ? - MCT_U232_STOP_BITS_2 : MCT_U232_STOP_BITS_1; - - mct_u232_set_line_ctrl(serial, priv->last_lcr); -#endif - ; - } - /* - * Set flow control: well, I do not really now how to handle DTR/RTS. - * Just do what we have seen with SniffUSB on Win98. - */ - if ((iflag & IXOFF) != (old_iflag & IXOFF) - || (iflag & IXON) != (old_iflag & IXON) - || (cflag & CRTSCTS) != (old_cflag & CRTSCTS)) { - /* Not currently supported */ - tty->termios->c_cflag &= ~CRTSCTS; - /* Drop DTR/RTS if no flow control otherwise assert */ -#if 0 - if ((iflag & IXOFF) || (iflag & IXON) || (cflag & CRTSCTS)) - priv->control_state |= TIOCM_DTR | TIOCM_RTS; - else - priv->control_state &= ~(TIOCM_DTR | TIOCM_RTS); - mct_u232_set_modem_ctrl(serial, priv->control_state); -#endif - ; - } - memcpy(cfg, &priv->cfg, sizeof(*cfg)); - spin_unlock_irqrestore(&priv->lock, flags); - - /* now commit changes to device */ - klsi_105_chg_port_settings(port, cfg); -err: - kfree(cfg); -} - -#if 0 -static void mct_u232_break_ctl(struct tty_struct *tty, int break_state) -{ - struct usb_serial_port *port = tty->driver_data; - struct usb_serial *serial = port->serial; - struct mct_u232_private *priv = - (struct mct_u232_private *)port->private; - unsigned char lcr = priv->last_lcr; - - dbg("%sstate=%d", __func__, break_state); - - /* LOCKING */ - if (break_state) - lcr |= MCT_U232_SET_BREAK; - - mct_u232_set_line_ctrl(serial, lcr); -} -#endif - -static int klsi_105_tiocmget(struct tty_struct *tty) -{ - struct usb_serial_port *port = tty->driver_data; - struct klsi_105_private *priv = usb_get_serial_port_data(port); - unsigned long flags; - int rc; - unsigned long line_state; - dbg("%s - request, just guessing", __func__); - - rc = klsi_105_get_line_state(port, &line_state); - if (rc < 0) { - dev_err(&port->dev, - "Reading line control failed (error = %d)\n", rc); - /* better return value? EAGAIN? */ - return rc; - } - - spin_lock_irqsave(&priv->lock, flags); - priv->line_state = line_state; - spin_unlock_irqrestore(&priv->lock, flags); - dbg("%s - read line state 0x%lx", __func__, line_state); - return (int)line_state; -} - -static int klsi_105_tiocmset(struct tty_struct *tty, - unsigned int set, unsigned int clear) -{ - int retval = -EINVAL; - - dbg("%s", __func__); - -/* if this ever gets implemented, it should be done something like this: - struct usb_serial *serial = port->serial; - struct klsi_105_private *priv = usb_get_serial_port_data(port); - unsigned long flags; - int control; - - spin_lock_irqsave (&priv->lock, flags); - if (set & TIOCM_RTS) - priv->control_state |= TIOCM_RTS; - if (set & TIOCM_DTR) - priv->control_state |= TIOCM_DTR; - if (clear & TIOCM_RTS) - priv->control_state &= ~TIOCM_RTS; - if (clear & TIOCM_DTR) - priv->control_state &= ~TIOCM_DTR; - control = priv->control_state; - spin_unlock_irqrestore (&priv->lock, flags); - retval = mct_u232_set_modem_ctrl(serial, control); -*/ - return retval; -} - -module_usb_serial_driver(kl5kusb105d_driver, serial_drivers); - -MODULE_AUTHOR(DRIVER_AUTHOR); -MODULE_DESCRIPTION(DRIVER_DESC); -MODULE_LICENSE("GPL"); - -module_param(debug, bool, S_IRUGO | S_IWUSR); -MODULE_PARM_DESC(debug, "enable extensive debugging messages"); diff --git a/ANDROID_3.4.5/drivers/usb/serial/kl5kusb105.h b/ANDROID_3.4.5/drivers/usb/serial/kl5kusb105.h deleted file mode 100644 index 22a90bad..00000000 --- a/ANDROID_3.4.5/drivers/usb/serial/kl5kusb105.h +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Definitions for the KLSI KL5KUSB105 serial port adapter - */ - -/* vendor/product pairs that are known to contain this chipset */ -#define PALMCONNECT_VID 0x0830 -#define PALMCONNECT_PID 0x0080 - -#define KLSI_VID 0x05e9 -#define KLSI_KL5KUSB105D_PID 0x00c0 - -/* Vendor commands: */ - - -/* port table -- the chip supports up to 4 channels */ - -/* baud rates */ - -enum { - kl5kusb105a_sio_b115200 = 0, - kl5kusb105a_sio_b57600 = 1, - kl5kusb105a_sio_b38400 = 2, - kl5kusb105a_sio_b19200 = 4, - kl5kusb105a_sio_b14400 = 5, - kl5kusb105a_sio_b9600 = 6, - kl5kusb105a_sio_b4800 = 8, /* unchecked */ - kl5kusb105a_sio_b2400 = 9, /* unchecked */ - kl5kusb105a_sio_b1200 = 0xa, /* unchecked */ - kl5kusb105a_sio_b600 = 0xb /* unchecked */ -}; - -/* data bits */ -#define kl5kusb105a_dtb_7 7 -#define kl5kusb105a_dtb_8 8 - - - -/* requests: */ -#define KL5KUSB105A_SIO_SET_DATA 1 -#define KL5KUSB105A_SIO_POLL 2 -#define KL5KUSB105A_SIO_CONFIGURE 3 -/* values used for request KL5KUSB105A_SIO_CONFIGURE */ -#define KL5KUSB105A_SIO_CONFIGURE_READ_ON 3 -#define KL5KUSB105A_SIO_CONFIGURE_READ_OFF 2 - -/* Interpretation of modem status lines */ -/* These need sorting out by individually connecting pins and checking - * results. FIXME! - * When data is being sent we see 0x30 in the lower byte; this must - * contain DSR and CTS ... - */ -#define KL5KUSB105A_DSR ((1<<4) | (1<<5)) -#define KL5KUSB105A_CTS ((1<<5) | (1<<4)) - -#define KL5KUSB105A_WANTS_TO_SEND 0x30 -#if 0 -#define KL5KUSB105A_DTR /* Data Terminal Ready */ -#define KL5KUSB105A_CTS /* Clear To Send */ -#define KL5KUSB105A_CD /* Carrier Detect */ -#define KL5KUSB105A_DSR /* Data Set Ready */ -#define KL5KUSB105A_RxD /* Receive pin */ - -#define KL5KUSB105A_LE -#define KL5KUSB105A_RTS -#define KL5KUSB105A_ST -#define KL5KUSB105A_SR -#define KL5KUSB105A_RI /* Ring Indicator */ -#endif diff --git a/ANDROID_3.4.5/drivers/usb/serial/kobil_sct.c b/ANDROID_3.4.5/drivers/usb/serial/kobil_sct.c deleted file mode 100644 index 4a9a75eb..00000000 --- a/ANDROID_3.4.5/drivers/usb/serial/kobil_sct.c +++ /dev/null @@ -1,693 +0,0 @@ -/* - * KOBIL USB Smart Card Terminal Driver - * - * Copyright (C) 2002 KOBIL Systems GmbH - * Author: Thomas Wahrenbruch - * - * Contact: linuxusb@kobil.de - * - * This program is largely derived from work by the linux-usb group - * and associated source files. Please see the usb/serial files for - * individual credits and copyrights. - * - * 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. - * - * Thanks to Greg Kroah-Hartman (greg@kroah.com) for his help and - * patience. - * - * Supported readers: USB TWIN, KAAN Standard Plus and SecOVID Reader Plus - * (Adapter K), B1 Professional and KAAN Professional (Adapter B) - */ - - -#include <linux/kernel.h> -#include <linux/errno.h> -#include <linux/init.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/uaccess.h> -#include <linux/usb.h> -#include <linux/usb/serial.h> -#include <linux/ioctl.h> -#include "kobil_sct.h" - -static bool debug; - -/* Version Information */ -#define DRIVER_VERSION "21/05/2004" -#define DRIVER_AUTHOR "KOBIL Systems GmbH - http://www.kobil.com" -#define DRIVER_DESC "KOBIL USB Smart Card Terminal Driver (experimental)" - -#define KOBIL_VENDOR_ID 0x0D46 -#define KOBIL_ADAPTER_B_PRODUCT_ID 0x2011 -#define KOBIL_ADAPTER_K_PRODUCT_ID 0x2012 -#define KOBIL_USBTWIN_PRODUCT_ID 0x0078 -#define KOBIL_KAAN_SIM_PRODUCT_ID 0x0081 - -#define KOBIL_TIMEOUT 500 -#define KOBIL_BUF_LENGTH 300 - - -/* Function prototypes */ -static int kobil_startup(struct usb_serial *serial); -static void kobil_release(struct usb_serial *serial); -static int kobil_open(struct tty_struct *tty, struct usb_serial_port *port); -static void kobil_close(struct usb_serial_port *port); -static int kobil_write(struct tty_struct *tty, struct usb_serial_port *port, - const unsigned char *buf, int count); -static int kobil_write_room(struct tty_struct *tty); -static int kobil_ioctl(struct tty_struct *tty, - unsigned int cmd, unsigned long arg); -static int kobil_tiocmget(struct tty_struct *tty); -static int kobil_tiocmset(struct tty_struct *tty, - unsigned int set, unsigned int clear); -static void kobil_read_int_callback(struct urb *urb); -static void kobil_write_callback(struct urb *purb); -static void kobil_set_termios(struct tty_struct *tty, - struct usb_serial_port *port, struct ktermios *old); -static void kobil_init_termios(struct tty_struct *tty); - -static const struct usb_device_id id_table[] = { - { USB_DEVICE(KOBIL_VENDOR_ID, KOBIL_ADAPTER_B_PRODUCT_ID) }, - { USB_DEVICE(KOBIL_VENDOR_ID, KOBIL_ADAPTER_K_PRODUCT_ID) }, - { USB_DEVICE(KOBIL_VENDOR_ID, KOBIL_USBTWIN_PRODUCT_ID) }, - { USB_DEVICE(KOBIL_VENDOR_ID, KOBIL_KAAN_SIM_PRODUCT_ID) }, - { } /* Terminating entry */ -}; - - -MODULE_DEVICE_TABLE(usb, id_table); - -static struct usb_driver kobil_driver = { - .name = "kobil", - .probe = usb_serial_probe, - .disconnect = usb_serial_disconnect, - .id_table = id_table, -}; - - -static struct usb_serial_driver kobil_device = { - .driver = { - .owner = THIS_MODULE, - .name = "kobil", - }, - .description = "KOBIL USB smart card terminal", - .id_table = id_table, - .num_ports = 1, - .attach = kobil_startup, - .release = kobil_release, - .ioctl = kobil_ioctl, - .set_termios = kobil_set_termios, - .init_termios = kobil_init_termios, - .tiocmget = kobil_tiocmget, - .tiocmset = kobil_tiocmset, - .open = kobil_open, - .close = kobil_close, - .write = kobil_write, - .write_room = kobil_write_room, - .read_int_callback = kobil_read_int_callback, -}; - -static struct usb_serial_driver * const serial_drivers[] = { - &kobil_device, NULL -}; - -struct kobil_private { - int write_int_endpoint_address; - int read_int_endpoint_address; - unsigned char buf[KOBIL_BUF_LENGTH]; /* buffer for the APDU to send */ - int filled; /* index of the last char in buf */ - int cur_pos; /* index of the next char to send in buf */ - __u16 device_type; -}; - - -static int kobil_startup(struct usb_serial *serial) -{ - int i; - struct kobil_private *priv; - struct usb_device *pdev; - struct usb_host_config *actconfig; - struct usb_interface *interface; - struct usb_host_interface *altsetting; - struct usb_host_endpoint *endpoint; - - priv = kmalloc(sizeof(struct kobil_private), GFP_KERNEL); - if (!priv) - return -ENOMEM; - - priv->filled = 0; - priv->cur_pos = 0; - priv->device_type = le16_to_cpu(serial->dev->descriptor.idProduct); - - switch (priv->device_type) { - case KOBIL_ADAPTER_B_PRODUCT_ID: - printk(KERN_DEBUG "KOBIL B1 PRO / KAAN PRO detected\n"); - break; - case KOBIL_ADAPTER_K_PRODUCT_ID: - printk(KERN_DEBUG - "KOBIL KAAN Standard Plus / SecOVID Reader Plus detected\n"); - break; - case KOBIL_USBTWIN_PRODUCT_ID: - printk(KERN_DEBUG "KOBIL USBTWIN detected\n"); - break; - case KOBIL_KAAN_SIM_PRODUCT_ID: - printk(KERN_DEBUG "KOBIL KAAN SIM detected\n"); - break; - } - usb_set_serial_port_data(serial->port[0], priv); - - /* search for the necessary endpoints */ - pdev = serial->dev; - actconfig = pdev->actconfig; - interface = actconfig->interface[0]; - altsetting = interface->cur_altsetting; - endpoint = altsetting->endpoint; - - for (i = 0; i < altsetting->desc.bNumEndpoints; i++) { - endpoint = &altsetting->endpoint[i]; - if (usb_endpoint_is_int_out(&endpoint->desc)) { - dbg("%s Found interrupt out endpoint. Address: %d", - __func__, endpoint->desc.bEndpointAddress); - priv->write_int_endpoint_address = - endpoint->desc.bEndpointAddress; - } - if (usb_endpoint_is_int_in(&endpoint->desc)) { - dbg("%s Found interrupt in endpoint. Address: %d", - __func__, endpoint->desc.bEndpointAddress); - priv->read_int_endpoint_address = - endpoint->desc.bEndpointAddress; - } - } - return 0; -} - - -static void kobil_release(struct usb_serial *serial) -{ - int i; - dbg("%s - port %d", __func__, serial->port[0]->number); - - for (i = 0; i < serial->num_ports; ++i) - kfree(usb_get_serial_port_data(serial->port[i])); -} - -static void kobil_init_termios(struct tty_struct *tty) -{ - /* Default to echo off and other sane device settings */ - tty->termios->c_lflag = 0; - tty->termios->c_lflag &= ~(ISIG | ICANON | ECHO | IEXTEN | XCASE); - tty->termios->c_iflag = IGNBRK | IGNPAR | IXOFF; - /* do NOT translate CR to CR-NL (0x0A -> 0x0A 0x0D) */ - tty->termios->c_oflag &= ~ONLCR; -} - -static int kobil_open(struct tty_struct *tty, struct usb_serial_port *port) -{ - int result = 0; - struct kobil_private *priv; - unsigned char *transfer_buffer; - int transfer_buffer_length = 8; - int write_urb_transfer_buffer_length = 8; - - dbg("%s - port %d", __func__, port->number); - priv = usb_get_serial_port_data(port); - - /* allocate memory for transfer buffer */ - transfer_buffer = kzalloc(transfer_buffer_length, GFP_KERNEL); - if (!transfer_buffer) - return -ENOMEM; - - /* allocate write_urb */ - if (!port->write_urb) { - dbg("%s - port %d Allocating port->write_urb", - __func__, port->number); - port->write_urb = usb_alloc_urb(0, GFP_KERNEL); - if (!port->write_urb) { - dbg("%s - port %d usb_alloc_urb failed", - __func__, port->number); - kfree(transfer_buffer); - return -ENOMEM; - } - } - - /* allocate memory for write_urb transfer buffer */ - port->write_urb->transfer_buffer = - kmalloc(write_urb_transfer_buffer_length, GFP_KERNEL); - if (!port->write_urb->transfer_buffer) { - kfree(transfer_buffer); - usb_free_urb(port->write_urb); - port->write_urb = NULL; - return -ENOMEM; - } - - /* get hardware version */ - result = usb_control_msg(port->serial->dev, - usb_rcvctrlpipe(port->serial->dev, 0), - SUSBCRequest_GetMisc, - USB_TYPE_VENDOR | USB_RECIP_ENDPOINT | USB_DIR_IN, - SUSBCR_MSC_GetHWVersion, - 0, - transfer_buffer, - transfer_buffer_length, - KOBIL_TIMEOUT - ); - dbg("%s - port %d Send get_HW_version URB returns: %i", - __func__, port->number, result); - dbg("Harware version: %i.%i.%i", - transfer_buffer[0], transfer_buffer[1], transfer_buffer[2]); - - /* get firmware version */ - result = usb_control_msg(port->serial->dev, - usb_rcvctrlpipe(port->serial->dev, 0), - SUSBCRequest_GetMisc, - USB_TYPE_VENDOR | USB_RECIP_ENDPOINT | USB_DIR_IN, - SUSBCR_MSC_GetFWVersion, - 0, - transfer_buffer, - transfer_buffer_length, - KOBIL_TIMEOUT - ); - dbg("%s - port %d Send get_FW_version URB returns: %i", - __func__, port->number, result); - dbg("Firmware version: %i.%i.%i", - transfer_buffer[0], transfer_buffer[1], transfer_buffer[2]); - - if (priv->device_type == KOBIL_ADAPTER_B_PRODUCT_ID || - priv->device_type == KOBIL_ADAPTER_K_PRODUCT_ID) { - /* Setting Baudrate, Parity and Stopbits */ - result = usb_control_msg(port->serial->dev, - usb_rcvctrlpipe(port->serial->dev, 0), - SUSBCRequest_SetBaudRateParityAndStopBits, - USB_TYPE_VENDOR | USB_RECIP_ENDPOINT | USB_DIR_OUT, - SUSBCR_SBR_9600 | SUSBCR_SPASB_EvenParity | - SUSBCR_SPASB_1StopBit, - 0, - transfer_buffer, - 0, - KOBIL_TIMEOUT - ); - dbg("%s - port %d Send set_baudrate URB returns: %i", - __func__, port->number, result); - - /* reset all queues */ - result = usb_control_msg(port->serial->dev, - usb_rcvctrlpipe(port->serial->dev, 0), - SUSBCRequest_Misc, - USB_TYPE_VENDOR | USB_RECIP_ENDPOINT | USB_DIR_OUT, - SUSBCR_MSC_ResetAllQueues, - 0, - transfer_buffer, - 0, - KOBIL_TIMEOUT - ); - dbg("%s - port %d Send reset_all_queues URB returns: %i", - __func__, port->number, result); - } - if (priv->device_type == KOBIL_USBTWIN_PRODUCT_ID || - priv->device_type == KOBIL_ADAPTER_B_PRODUCT_ID || - priv->device_type == KOBIL_KAAN_SIM_PRODUCT_ID) { - /* start reading (Adapter B 'cause PNP string) */ - result = usb_submit_urb(port->interrupt_in_urb, GFP_ATOMIC); - dbg("%s - port %d Send read URB returns: %i", - __func__, port->number, result); - } - - kfree(transfer_buffer); - return 0; -} - - -static void kobil_close(struct usb_serial_port *port) -{ - dbg("%s - port %d", __func__, port->number); - - /* FIXME: Add rts/dtr methods */ - if (port->write_urb) { - usb_poison_urb(port->write_urb); - kfree(port->write_urb->transfer_buffer); - usb_free_urb(port->write_urb); - port->write_urb = NULL; - } - usb_kill_urb(port->interrupt_in_urb); -} - - -static void kobil_read_int_callback(struct urb *urb) -{ - int result; - struct usb_serial_port *port = urb->context; - struct tty_struct *tty; - unsigned char *data = urb->transfer_buffer; - int status = urb->status; -/* char *dbg_data; */ - - dbg("%s - port %d", __func__, port->number); - - if (status) { - dbg("%s - port %d Read int status not zero: %d", - __func__, port->number, status); - return; - } - - tty = tty_port_tty_get(&port->port); - if (tty && urb->actual_length) { - - /* BEGIN DEBUG */ - /* - dbg_data = kzalloc((3 * purb->actual_length + 10) - * sizeof(char), GFP_KERNEL); - if (! dbg_data) { - return; - } - for (i = 0; i < purb->actual_length; i++) { - sprintf(dbg_data +3*i, "%02X ", data[i]); - } - dbg(" <-- %s", dbg_data); - kfree(dbg_data); - */ - /* END DEBUG */ - - tty_insert_flip_string(tty, data, urb->actual_length); - tty_flip_buffer_push(tty); - } - tty_kref_put(tty); - - result = usb_submit_urb(port->interrupt_in_urb, GFP_ATOMIC); - dbg("%s - port %d Send read URB returns: %i", - __func__, port->number, result); -} - - -static void kobil_write_callback(struct urb *purb) -{ -} - - -static int kobil_write(struct tty_struct *tty, struct usb_serial_port *port, - const unsigned char *buf, int count) -{ - int length = 0; - int result = 0; - int todo = 0; - struct kobil_private *priv; - - if (count == 0) { - dbg("%s - port %d write request of 0 bytes", - __func__, port->number); - return 0; - } - - priv = usb_get_serial_port_data(port); - - if (count > (KOBIL_BUF_LENGTH - priv->filled)) { - dbg("%s - port %d Error: write request bigger than buffer size", __func__, port->number); - return -ENOMEM; - } - - /* Copy data to buffer */ - memcpy(priv->buf + priv->filled, buf, count); - usb_serial_debug_data(debug, &port->dev, __func__, count, - priv->buf + priv->filled); - priv->filled = priv->filled + count; - - /* only send complete block. TWIN, KAAN SIM and adapter K - use the same protocol. */ - if (((priv->device_type != KOBIL_ADAPTER_B_PRODUCT_ID) && (priv->filled > 2) && (priv->filled >= (priv->buf[1] + 3))) || - ((priv->device_type == KOBIL_ADAPTER_B_PRODUCT_ID) && (priv->filled > 3) && (priv->filled >= (priv->buf[2] + 4)))) { - /* stop reading (except TWIN and KAAN SIM) */ - if ((priv->device_type == KOBIL_ADAPTER_B_PRODUCT_ID) - || (priv->device_type == KOBIL_ADAPTER_K_PRODUCT_ID)) - usb_kill_urb(port->interrupt_in_urb); - - todo = priv->filled - priv->cur_pos; - - while (todo > 0) { - /* max 8 byte in one urb (endpoint size) */ - length = (todo < 8) ? todo : 8; - /* copy data to transfer buffer */ - memcpy(port->write_urb->transfer_buffer, - priv->buf + priv->cur_pos, length); - usb_fill_int_urb(port->write_urb, - port->serial->dev, - usb_sndintpipe(port->serial->dev, - priv->write_int_endpoint_address), - port->write_urb->transfer_buffer, - length, - kobil_write_callback, - port, - 8 - ); - - priv->cur_pos = priv->cur_pos + length; - result = usb_submit_urb(port->write_urb, GFP_NOIO); - dbg("%s - port %d Send write URB returns: %i", - __func__, port->number, result); - todo = priv->filled - priv->cur_pos; - - if (todo > 0) - msleep(24); - } - - priv->filled = 0; - priv->cur_pos = 0; - - /* start reading (except TWIN and KAAN SIM) */ - if (priv->device_type == KOBIL_ADAPTER_B_PRODUCT_ID || - priv->device_type == KOBIL_ADAPTER_K_PRODUCT_ID) { - result = usb_submit_urb(port->interrupt_in_urb, - GFP_NOIO); - dbg("%s - port %d Send read URB returns: %i", - __func__, port->number, result); - } - } - return count; -} - - -static int kobil_write_room(struct tty_struct *tty) -{ - /* dbg("%s - port %d", __func__, port->number); */ - /* FIXME */ - return 8; -} - - -static int kobil_tiocmget(struct tty_struct *tty) -{ - struct usb_serial_port *port = tty->driver_data; - struct kobil_private *priv; - int result; - unsigned char *transfer_buffer; - int transfer_buffer_length = 8; - - priv = usb_get_serial_port_data(port); - if (priv->device_type == KOBIL_USBTWIN_PRODUCT_ID - || priv->device_type == KOBIL_KAAN_SIM_PRODUCT_ID) { - /* This device doesn't support ioctl calls */ - return -EINVAL; - } - - /* allocate memory for transfer buffer */ - transfer_buffer = kzalloc(transfer_buffer_length, GFP_KERNEL); - if (!transfer_buffer) - return -ENOMEM; - - result = usb_control_msg(port->serial->dev, - usb_rcvctrlpipe(port->serial->dev, 0), - SUSBCRequest_GetStatusLineState, - USB_TYPE_VENDOR | USB_RECIP_ENDPOINT | USB_DIR_IN, - 0, - 0, - transfer_buffer, - transfer_buffer_length, - KOBIL_TIMEOUT); - - dbg("%s - port %d Send get_status_line_state URB returns: %i. Statusline: %02x", - __func__, port->number, result, transfer_buffer[0]); - - result = 0; - if ((transfer_buffer[0] & SUSBCR_GSL_DSR) != 0) - result = TIOCM_DSR; - kfree(transfer_buffer); - return result; -} - -static int kobil_tiocmset(struct tty_struct *tty, - unsigned int set, unsigned int clear) -{ - struct usb_serial_port *port = tty->driver_data; - struct kobil_private *priv; - int result; - int dtr = 0; - int rts = 0; - unsigned char *transfer_buffer; - int transfer_buffer_length = 8; - - /* FIXME: locking ? */ - priv = usb_get_serial_port_data(port); - if (priv->device_type == KOBIL_USBTWIN_PRODUCT_ID - || priv->device_type == KOBIL_KAAN_SIM_PRODUCT_ID) { - /* This device doesn't support ioctl calls */ - return -EINVAL; - } - - /* allocate memory for transfer buffer */ - transfer_buffer = kzalloc(transfer_buffer_length, GFP_KERNEL); - if (!transfer_buffer) - return -ENOMEM; - - if (set & TIOCM_RTS) - rts = 1; - if (set & TIOCM_DTR) - dtr = 1; - if (clear & TIOCM_RTS) - rts = 0; - if (clear & TIOCM_DTR) - dtr = 0; - - if (priv->device_type == KOBIL_ADAPTER_B_PRODUCT_ID) { - if (dtr != 0) - dbg("%s - port %d Setting DTR", - __func__, port->number); - else - dbg("%s - port %d Clearing DTR", - __func__, port->number); - result = usb_control_msg(port->serial->dev, - usb_rcvctrlpipe(port->serial->dev, 0), - SUSBCRequest_SetStatusLinesOrQueues, - USB_TYPE_VENDOR | USB_RECIP_ENDPOINT | USB_DIR_OUT, - ((dtr != 0) ? SUSBCR_SSL_SETDTR : SUSBCR_SSL_CLRDTR), - 0, - transfer_buffer, - 0, - KOBIL_TIMEOUT); - } else { - if (rts != 0) - dbg("%s - port %d Setting RTS", - __func__, port->number); - else - dbg("%s - port %d Clearing RTS", - __func__, port->number); - result = usb_control_msg(port->serial->dev, - usb_rcvctrlpipe(port->serial->dev, 0), - SUSBCRequest_SetStatusLinesOrQueues, - USB_TYPE_VENDOR | USB_RECIP_ENDPOINT | USB_DIR_OUT, - ((rts != 0) ? SUSBCR_SSL_SETRTS : SUSBCR_SSL_CLRRTS), - 0, - transfer_buffer, - 0, - KOBIL_TIMEOUT); - } - dbg("%s - port %d Send set_status_line URB returns: %i", - __func__, port->number, result); - kfree(transfer_buffer); - return (result < 0) ? result : 0; -} - -static void kobil_set_termios(struct tty_struct *tty, - struct usb_serial_port *port, struct ktermios *old) -{ - struct kobil_private *priv; - int result; - unsigned short urb_val = 0; - int c_cflag = tty->termios->c_cflag; - speed_t speed; - - priv = usb_get_serial_port_data(port); - if (priv->device_type == KOBIL_USBTWIN_PRODUCT_ID || - priv->device_type == KOBIL_KAAN_SIM_PRODUCT_ID) { - /* This device doesn't support ioctl calls */ - *tty->termios = *old; - return; - } - - speed = tty_get_baud_rate(tty); - switch (speed) { - case 1200: - urb_val = SUSBCR_SBR_1200; - break; - default: - speed = 9600; - case 9600: - urb_val = SUSBCR_SBR_9600; - break; - } - urb_val |= (c_cflag & CSTOPB) ? SUSBCR_SPASB_2StopBits : - SUSBCR_SPASB_1StopBit; - if (c_cflag & PARENB) { - if (c_cflag & PARODD) - urb_val |= SUSBCR_SPASB_OddParity; - else - urb_val |= SUSBCR_SPASB_EvenParity; - } else - urb_val |= SUSBCR_SPASB_NoParity; - tty->termios->c_cflag &= ~CMSPAR; - tty_encode_baud_rate(tty, speed, speed); - - result = usb_control_msg(port->serial->dev, - usb_rcvctrlpipe(port->serial->dev, 0), - SUSBCRequest_SetBaudRateParityAndStopBits, - USB_TYPE_VENDOR | USB_RECIP_ENDPOINT | USB_DIR_OUT, - urb_val, - 0, - NULL, - 0, - KOBIL_TIMEOUT - ); -} - -static int kobil_ioctl(struct tty_struct *tty, - unsigned int cmd, unsigned long arg) -{ - struct usb_serial_port *port = tty->driver_data; - struct kobil_private *priv = usb_get_serial_port_data(port); - unsigned char *transfer_buffer; - int transfer_buffer_length = 8; - int result; - - if (priv->device_type == KOBIL_USBTWIN_PRODUCT_ID || - priv->device_type == KOBIL_KAAN_SIM_PRODUCT_ID) - /* This device doesn't support ioctl calls */ - return -ENOIOCTLCMD; - - switch (cmd) { - case TCFLSH: - transfer_buffer = kmalloc(transfer_buffer_length, GFP_KERNEL); - if (!transfer_buffer) - return -ENOBUFS; - - result = usb_control_msg(port->serial->dev, - usb_rcvctrlpipe(port->serial->dev, 0), - SUSBCRequest_Misc, - USB_TYPE_VENDOR | USB_RECIP_ENDPOINT | USB_DIR_OUT, - SUSBCR_MSC_ResetAllQueues, - 0, - NULL, /* transfer_buffer, */ - 0, - KOBIL_TIMEOUT - ); - - dbg("%s - port %d Send reset_all_queues (FLUSH) URB returns: %i", __func__, port->number, result); - kfree(transfer_buffer); - return (result < 0) ? -EIO: 0; - default: - return -ENOIOCTLCMD; - } -} - -module_usb_serial_driver(kobil_driver, serial_drivers); - -MODULE_AUTHOR(DRIVER_AUTHOR); -MODULE_DESCRIPTION(DRIVER_DESC); -MODULE_LICENSE("GPL"); - -module_param(debug, bool, S_IRUGO | S_IWUSR); -MODULE_PARM_DESC(debug, "Debug enabled or not"); diff --git a/ANDROID_3.4.5/drivers/usb/serial/kobil_sct.h b/ANDROID_3.4.5/drivers/usb/serial/kobil_sct.h deleted file mode 100644 index be207f71..00000000 --- a/ANDROID_3.4.5/drivers/usb/serial/kobil_sct.h +++ /dev/null @@ -1,77 +0,0 @@ -#define SUSBCRequest_SetBaudRateParityAndStopBits 1 -#define SUSBCR_SBR_MASK 0xFF00 -#define SUSBCR_SBR_1200 0x0100 -#define SUSBCR_SBR_9600 0x0200 -#define SUSBCR_SBR_19200 0x0400 -#define SUSBCR_SBR_28800 0x0800 -#define SUSBCR_SBR_38400 0x1000 -#define SUSBCR_SBR_57600 0x2000 -#define SUSBCR_SBR_115200 0x4000 - -#define SUSBCR_SPASB_MASK 0x0070 -#define SUSBCR_SPASB_NoParity 0x0010 -#define SUSBCR_SPASB_OddParity 0x0020 -#define SUSBCR_SPASB_EvenParity 0x0040 - -#define SUSBCR_SPASB_STPMASK 0x0003 -#define SUSBCR_SPASB_1StopBit 0x0001 -#define SUSBCR_SPASB_2StopBits 0x0002 - -#define SUSBCRequest_SetStatusLinesOrQueues 2 -#define SUSBCR_SSL_SETRTS 0x0001 -#define SUSBCR_SSL_CLRRTS 0x0002 -#define SUSBCR_SSL_SETDTR 0x0004 -#define SUSBCR_SSL_CLRDTR 0x0010 - -/* Kill the pending/current writes to the comm port. */ -#define SUSBCR_SSL_PURGE_TXABORT 0x0100 -/* Kill the pending/current reads to the comm port. */ -#define SUSBCR_SSL_PURGE_RXABORT 0x0200 -/* Kill the transmit queue if there. */ -#define SUSBCR_SSL_PURGE_TXCLEAR 0x0400 -/* Kill the typeahead buffer if there. */ -#define SUSBCR_SSL_PURGE_RXCLEAR 0x0800 - -#define SUSBCRequest_GetStatusLineState 4 -/* Any Character received */ -#define SUSBCR_GSL_RXCHAR 0x0001 -/* Transmitt Queue Empty */ -#define SUSBCR_GSL_TXEMPTY 0x0004 -/* CTS changed state */ -#define SUSBCR_GSL_CTS 0x0008 -/* DSR changed state */ -#define SUSBCR_GSL_DSR 0x0010 -/* RLSD changed state */ -#define SUSBCR_GSL_RLSD 0x0020 -/* BREAK received */ -#define SUSBCR_GSL_BREAK 0x0040 -/* Line status error occurred */ -#define SUSBCR_GSL_ERR 0x0080 -/* Ring signal detected */ -#define SUSBCR_GSL_RING 0x0100 - -#define SUSBCRequest_Misc 8 -/* use a predefined reset sequence */ -#define SUSBCR_MSC_ResetReader 0x0001 -/* use a predefined sequence to reset the internal queues */ -#define SUSBCR_MSC_ResetAllQueues 0x0002 - -#define SUSBCRequest_GetMisc 0x10 - -/* - * get the firmware version from device, coded like this 0xHHLLBBPP with - * HH = Firmware Version High Byte - * LL = Firmware Version Low Byte - * BB = Build Number - * PP = Further Attributes - */ -#define SUSBCR_MSC_GetFWVersion 0x0001 - -/* - * get the hardware version from device coded like this 0xHHLLPPRR with - * HH = Software Version High Byte - * LL = Software Version Low Byte - * PP = Further Attributes - * RR = Reserved for the hardware ID - */ -#define SUSBCR_MSC_GetHWVersion 0x0002 diff --git a/ANDROID_3.4.5/drivers/usb/serial/mct_u232.c b/ANDROID_3.4.5/drivers/usb/serial/mct_u232.c deleted file mode 100644 index ef4d7adf..00000000 --- a/ANDROID_3.4.5/drivers/usb/serial/mct_u232.c +++ /dev/null @@ -1,919 +0,0 @@ -/* - * MCT (Magic Control Technology Corp.) USB RS232 Converter Driver - * - * Copyright (C) 2000 Wolfgang Grandegger (wolfgang@ces.ch) - * - * 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. - * - * This program is largely derived from the Belkin USB Serial Adapter Driver - * (see belkin_sa.[ch]). All of the information about the device was acquired - * by using SniffUSB on Windows98. For technical details see mct_u232.h. - * - * William G. Greathouse and Greg Kroah-Hartman provided great help on how to - * do the reverse engineering and how to write a USB serial device driver. - * - * TO BE DONE, TO BE CHECKED: - * DTR/RTS signal handling may be incomplete or incorrect. I have mainly - * implemented what I have seen with SniffUSB or found in belkin_sa.c. - * For further TODOs check also belkin_sa.c. - */ - -#include <linux/kernel.h> -#include <linux/errno.h> -#include <linux/init.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/uaccess.h> -#include <asm/unaligned.h> -#include <linux/usb.h> -#include <linux/usb/serial.h> -#include <linux/serial.h> -#include <linux/ioctl.h> -#include "mct_u232.h" - -/* - * Version Information - */ -#define DRIVER_VERSION "z2.1" /* Linux in-kernel version */ -#define DRIVER_AUTHOR "Wolfgang Grandegger <wolfgang@ces.ch>" -#define DRIVER_DESC "Magic Control Technology USB-RS232 converter driver" - -static bool debug; - -/* - * Function prototypes - */ -static int mct_u232_startup(struct usb_serial *serial); -static void mct_u232_release(struct usb_serial *serial); -static int mct_u232_open(struct tty_struct *tty, struct usb_serial_port *port); -static void mct_u232_close(struct usb_serial_port *port); -static void mct_u232_dtr_rts(struct usb_serial_port *port, int on); -static void mct_u232_read_int_callback(struct urb *urb); -static void mct_u232_set_termios(struct tty_struct *tty, - struct usb_serial_port *port, struct ktermios *old); -static void mct_u232_break_ctl(struct tty_struct *tty, int break_state); -static int mct_u232_tiocmget(struct tty_struct *tty); -static int mct_u232_tiocmset(struct tty_struct *tty, - unsigned int set, unsigned int clear); -static int mct_u232_ioctl(struct tty_struct *tty, - unsigned int cmd, unsigned long arg); -static int mct_u232_get_icount(struct tty_struct *tty, - struct serial_icounter_struct *icount); -static void mct_u232_throttle(struct tty_struct *tty); -static void mct_u232_unthrottle(struct tty_struct *tty); - - -/* - * All of the device info needed for the MCT USB-RS232 converter. - */ -static const struct usb_device_id id_table_combined[] = { - { USB_DEVICE(MCT_U232_VID, MCT_U232_PID) }, - { USB_DEVICE(MCT_U232_VID, MCT_U232_SITECOM_PID) }, - { USB_DEVICE(MCT_U232_VID, MCT_U232_DU_H3SP_PID) }, - { USB_DEVICE(MCT_U232_BELKIN_F5U109_VID, MCT_U232_BELKIN_F5U109_PID) }, - { } /* Terminating entry */ -}; - -MODULE_DEVICE_TABLE(usb, id_table_combined); - -static struct usb_driver mct_u232_driver = { - .name = "mct_u232", - .probe = usb_serial_probe, - .disconnect = usb_serial_disconnect, - .id_table = id_table_combined, -}; - -static struct usb_serial_driver mct_u232_device = { - .driver = { - .owner = THIS_MODULE, - .name = "mct_u232", - }, - .description = "MCT U232", - .id_table = id_table_combined, - .num_ports = 1, - .open = mct_u232_open, - .close = mct_u232_close, - .dtr_rts = mct_u232_dtr_rts, - .throttle = mct_u232_throttle, - .unthrottle = mct_u232_unthrottle, - .read_int_callback = mct_u232_read_int_callback, - .set_termios = mct_u232_set_termios, - .break_ctl = mct_u232_break_ctl, - .tiocmget = mct_u232_tiocmget, - .tiocmset = mct_u232_tiocmset, - .attach = mct_u232_startup, - .release = mct_u232_release, - .ioctl = mct_u232_ioctl, - .get_icount = mct_u232_get_icount, -}; - -static struct usb_serial_driver * const serial_drivers[] = { - &mct_u232_device, NULL -}; - -struct mct_u232_private { - spinlock_t lock; - unsigned int control_state; /* Modem Line Setting (TIOCM) */ - unsigned char last_lcr; /* Line Control Register */ - unsigned char last_lsr; /* Line Status Register */ - unsigned char last_msr; /* Modem Status Register */ - unsigned int rx_flags; /* Throttling flags */ - struct async_icount icount; - wait_queue_head_t msr_wait; /* for handling sleeping while waiting - for msr change to happen */ -}; - -#define THROTTLED 0x01 - -/* - * Handle vendor specific USB requests - */ - -#define WDR_TIMEOUT 5000 /* default urb timeout */ - -/* - * Later day 2.6.0-test kernels have new baud rates like B230400 which - * we do not know how to support. We ignore them for the moment. - */ -static int mct_u232_calculate_baud_rate(struct usb_serial *serial, - speed_t value, speed_t *result) -{ - *result = value; - - if (le16_to_cpu(serial->dev->descriptor.idProduct) == MCT_U232_SITECOM_PID - || le16_to_cpu(serial->dev->descriptor.idProduct) == MCT_U232_BELKIN_F5U109_PID) { - switch (value) { - case 300: - return 0x01; - case 600: - return 0x02; /* this one not tested */ - case 1200: - return 0x03; - case 2400: - return 0x04; - case 4800: - return 0x06; - case 9600: - return 0x08; - case 19200: - return 0x09; - case 38400: - return 0x0a; - case 57600: - return 0x0b; - case 115200: - return 0x0c; - default: - *result = 9600; - return 0x08; - } - } else { - /* FIXME: Can we use any divider - should we do - divider = 115200/value; - real baud = 115200/divider */ - switch (value) { - case 300: break; - case 600: break; - case 1200: break; - case 2400: break; - case 4800: break; - case 9600: break; - case 19200: break; - case 38400: break; - case 57600: break; - case 115200: break; - default: - value = 9600; - *result = 9600; - } - return 115200/value; - } -} - -static int mct_u232_set_baud_rate(struct tty_struct *tty, - struct usb_serial *serial, struct usb_serial_port *port, speed_t value) -{ - unsigned int divisor; - int rc; - unsigned char *buf; - unsigned char cts_enable_byte = 0; - speed_t speed; - - buf = kmalloc(MCT_U232_MAX_SIZE, GFP_KERNEL); - if (buf == NULL) - return -ENOMEM; - - divisor = mct_u232_calculate_baud_rate(serial, value, &speed); - put_unaligned_le32(cpu_to_le32(divisor), buf); - rc = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0), - MCT_U232_SET_BAUD_RATE_REQUEST, - MCT_U232_SET_REQUEST_TYPE, - 0, 0, buf, MCT_U232_SET_BAUD_RATE_SIZE, - WDR_TIMEOUT); - if (rc < 0) /*FIXME: What value speed results */ - dev_err(&port->dev, "Set BAUD RATE %d failed (error = %d)\n", - value, rc); - else - tty_encode_baud_rate(tty, speed, speed); - dbg("set_baud_rate: value: 0x%x, divisor: 0x%x", value, divisor); - - /* Mimic the MCT-supplied Windows driver (version 1.21P.0104), which - always sends two extra USB 'device request' messages after the - 'baud rate change' message. The actual functionality of the - request codes in these messages is not fully understood but these - particular codes are never seen in any operation besides a baud - rate change. Both of these messages send a single byte of data. - In the first message, the value of this byte is always zero. - - The second message has been determined experimentally to control - whether data will be transmitted to a device which is not asserting - the 'CTS' signal. If the second message's data byte is zero, data - will be transmitted even if 'CTS' is not asserted (i.e. no hardware - flow control). if the second message's data byte is nonzero (a - value of 1 is used by this driver), data will not be transmitted to - a device which is not asserting 'CTS'. - */ - - buf[0] = 0; - rc = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0), - MCT_U232_SET_UNKNOWN1_REQUEST, - MCT_U232_SET_REQUEST_TYPE, - 0, 0, buf, MCT_U232_SET_UNKNOWN1_SIZE, - WDR_TIMEOUT); - if (rc < 0) - dev_err(&port->dev, "Sending USB device request code %d " - "failed (error = %d)\n", MCT_U232_SET_UNKNOWN1_REQUEST, - rc); - - if (port && C_CRTSCTS(tty)) - cts_enable_byte = 1; - - dbg("set_baud_rate: send second control message, data = %02X", - cts_enable_byte); - buf[0] = cts_enable_byte; - rc = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0), - MCT_U232_SET_CTS_REQUEST, - MCT_U232_SET_REQUEST_TYPE, - 0, 0, buf, MCT_U232_SET_CTS_SIZE, - WDR_TIMEOUT); - if (rc < 0) - dev_err(&port->dev, "Sending USB device request code %d " - "failed (error = %d)\n", MCT_U232_SET_CTS_REQUEST, rc); - - kfree(buf); - return rc; -} /* mct_u232_set_baud_rate */ - -static int mct_u232_set_line_ctrl(struct usb_serial *serial, unsigned char lcr) -{ - int rc; - unsigned char *buf; - - buf = kmalloc(MCT_U232_MAX_SIZE, GFP_KERNEL); - if (buf == NULL) - return -ENOMEM; - - buf[0] = lcr; - rc = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0), - MCT_U232_SET_LINE_CTRL_REQUEST, - MCT_U232_SET_REQUEST_TYPE, - 0, 0, buf, MCT_U232_SET_LINE_CTRL_SIZE, - WDR_TIMEOUT); - if (rc < 0) - dev_err(&serial->dev->dev, - "Set LINE CTRL 0x%x failed (error = %d)\n", lcr, rc); - dbg("set_line_ctrl: 0x%x", lcr); - kfree(buf); - return rc; -} /* mct_u232_set_line_ctrl */ - -static int mct_u232_set_modem_ctrl(struct usb_serial *serial, - unsigned int control_state) -{ - int rc; - unsigned char mcr; - unsigned char *buf; - - buf = kmalloc(MCT_U232_MAX_SIZE, GFP_KERNEL); - if (buf == NULL) - return -ENOMEM; - - mcr = MCT_U232_MCR_NONE; - if (control_state & TIOCM_DTR) - mcr |= MCT_U232_MCR_DTR; - if (control_state & TIOCM_RTS) - mcr |= MCT_U232_MCR_RTS; - - buf[0] = mcr; - rc = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0), - MCT_U232_SET_MODEM_CTRL_REQUEST, - MCT_U232_SET_REQUEST_TYPE, - 0, 0, buf, MCT_U232_SET_MODEM_CTRL_SIZE, - WDR_TIMEOUT); - kfree(buf); - - dbg("set_modem_ctrl: state=0x%x ==> mcr=0x%x", control_state, mcr); - - if (rc < 0) { - dev_err(&serial->dev->dev, - "Set MODEM CTRL 0x%x failed (error = %d)\n", mcr, rc); - return rc; - } - return 0; -} /* mct_u232_set_modem_ctrl */ - -static int mct_u232_get_modem_stat(struct usb_serial *serial, - unsigned char *msr) -{ - int rc; - unsigned char *buf; - - buf = kmalloc(MCT_U232_MAX_SIZE, GFP_KERNEL); - if (buf == NULL) { - *msr = 0; - return -ENOMEM; - } - rc = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0), - MCT_U232_GET_MODEM_STAT_REQUEST, - MCT_U232_GET_REQUEST_TYPE, - 0, 0, buf, MCT_U232_GET_MODEM_STAT_SIZE, - WDR_TIMEOUT); - if (rc < 0) { - dev_err(&serial->dev->dev, - "Get MODEM STATus failed (error = %d)\n", rc); - *msr = 0; - } else { - *msr = buf[0]; - } - dbg("get_modem_stat: 0x%x", *msr); - kfree(buf); - return rc; -} /* mct_u232_get_modem_stat */ - -static void mct_u232_msr_to_icount(struct async_icount *icount, - unsigned char msr) -{ - /* Translate Control Line states */ - if (msr & MCT_U232_MSR_DDSR) - icount->dsr++; - if (msr & MCT_U232_MSR_DCTS) - icount->cts++; - if (msr & MCT_U232_MSR_DRI) - icount->rng++; - if (msr & MCT_U232_MSR_DCD) - icount->dcd++; -} /* mct_u232_msr_to_icount */ - -static void mct_u232_msr_to_state(unsigned int *control_state, - unsigned char msr) -{ - /* Translate Control Line states */ - if (msr & MCT_U232_MSR_DSR) - *control_state |= TIOCM_DSR; - else - *control_state &= ~TIOCM_DSR; - if (msr & MCT_U232_MSR_CTS) - *control_state |= TIOCM_CTS; - else - *control_state &= ~TIOCM_CTS; - if (msr & MCT_U232_MSR_RI) - *control_state |= TIOCM_RI; - else - *control_state &= ~TIOCM_RI; - if (msr & MCT_U232_MSR_CD) - *control_state |= TIOCM_CD; - else - *control_state &= ~TIOCM_CD; - dbg("msr_to_state: msr=0x%x ==> state=0x%x", msr, *control_state); -} /* mct_u232_msr_to_state */ - -/* - * Driver's tty interface functions - */ - -static int mct_u232_startup(struct usb_serial *serial) -{ - struct mct_u232_private *priv; - struct usb_serial_port *port, *rport; - - priv = kzalloc(sizeof(struct mct_u232_private), GFP_KERNEL); - if (!priv) - return -ENOMEM; - spin_lock_init(&priv->lock); - init_waitqueue_head(&priv->msr_wait); - usb_set_serial_port_data(serial->port[0], priv); - - init_waitqueue_head(&serial->port[0]->write_wait); - - /* Puh, that's dirty */ - port = serial->port[0]; - rport = serial->port[1]; - /* No unlinking, it wasn't submitted yet. */ - usb_free_urb(port->read_urb); - port->read_urb = rport->interrupt_in_urb; - rport->interrupt_in_urb = NULL; - port->read_urb->context = port; - - return 0; -} /* mct_u232_startup */ - - -static void mct_u232_release(struct usb_serial *serial) -{ - struct mct_u232_private *priv; - int i; - - dbg("%s", __func__); - - for (i = 0; i < serial->num_ports; ++i) { - /* My special items, the standard routines free my urbs */ - priv = usb_get_serial_port_data(serial->port[i]); - kfree(priv); - } -} /* mct_u232_release */ - -static int mct_u232_open(struct tty_struct *tty, struct usb_serial_port *port) -{ - struct usb_serial *serial = port->serial; - struct mct_u232_private *priv = usb_get_serial_port_data(port); - int retval = 0; - unsigned int control_state; - unsigned long flags; - unsigned char last_lcr; - unsigned char last_msr; - - dbg("%s port %d", __func__, port->number); - - /* Compensate for a hardware bug: although the Sitecom U232-P25 - * device reports a maximum output packet size of 32 bytes, - * it seems to be able to accept only 16 bytes (and that's what - * SniffUSB says too...) - */ - if (le16_to_cpu(serial->dev->descriptor.idProduct) - == MCT_U232_SITECOM_PID) - port->bulk_out_size = 16; - - /* Do a defined restart: the normal serial device seems to - * always turn on DTR and RTS here, so do the same. I'm not - * sure if this is really necessary. But it should not harm - * either. - */ - spin_lock_irqsave(&priv->lock, flags); - if (tty && (tty->termios->c_cflag & CBAUD)) - priv->control_state = TIOCM_DTR | TIOCM_RTS; - else - priv->control_state = 0; - - priv->last_lcr = (MCT_U232_DATA_BITS_8 | - MCT_U232_PARITY_NONE | - MCT_U232_STOP_BITS_1); - control_state = priv->control_state; - last_lcr = priv->last_lcr; - spin_unlock_irqrestore(&priv->lock, flags); - mct_u232_set_modem_ctrl(serial, control_state); - mct_u232_set_line_ctrl(serial, last_lcr); - - /* Read modem status and update control state */ - mct_u232_get_modem_stat(serial, &last_msr); - spin_lock_irqsave(&priv->lock, flags); - priv->last_msr = last_msr; - mct_u232_msr_to_state(&priv->control_state, priv->last_msr); - spin_unlock_irqrestore(&priv->lock, flags); - - retval = usb_submit_urb(port->read_urb, GFP_KERNEL); - if (retval) { - dev_err(&port->dev, - "usb_submit_urb(read bulk) failed pipe 0x%x err %d\n", - port->read_urb->pipe, retval); - goto error; - } - - retval = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL); - if (retval) { - usb_kill_urb(port->read_urb); - dev_err(&port->dev, - "usb_submit_urb(read int) failed pipe 0x%x err %d", - port->interrupt_in_urb->pipe, retval); - goto error; - } - return 0; - -error: - return retval; -} /* mct_u232_open */ - -static void mct_u232_dtr_rts(struct usb_serial_port *port, int on) -{ - unsigned int control_state; - struct mct_u232_private *priv = usb_get_serial_port_data(port); - - mutex_lock(&port->serial->disc_mutex); - if (!port->serial->disconnected) { - /* drop DTR and RTS */ - spin_lock_irq(&priv->lock); - if (on) - priv->control_state |= TIOCM_DTR | TIOCM_RTS; - else - priv->control_state &= ~(TIOCM_DTR | TIOCM_RTS); - control_state = priv->control_state; - spin_unlock_irq(&priv->lock); - mct_u232_set_modem_ctrl(port->serial, control_state); - } - mutex_unlock(&port->serial->disc_mutex); -} - -static void mct_u232_close(struct usb_serial_port *port) -{ - dbg("%s port %d", __func__, port->number); - - if (port->serial->dev) { - /* shutdown our urbs */ - usb_kill_urb(port->write_urb); - usb_kill_urb(port->read_urb); - usb_kill_urb(port->interrupt_in_urb); - } -} /* mct_u232_close */ - - -static void mct_u232_read_int_callback(struct urb *urb) -{ - struct usb_serial_port *port = urb->context; - struct mct_u232_private *priv = usb_get_serial_port_data(port); - struct usb_serial *serial = port->serial; - struct tty_struct *tty; - unsigned char *data = urb->transfer_buffer; - int retval; - int status = urb->status; - unsigned long flags; - - switch (status) { - case 0: - /* success */ - break; - case -ECONNRESET: - case -ENOENT: - case -ESHUTDOWN: - /* this urb is terminated, clean up */ - dbg("%s - urb shutting down with status: %d", - __func__, status); - return; - default: - dbg("%s - nonzero urb status received: %d", - __func__, status); - goto exit; - } - - if (!serial) { - dbg("%s - bad serial pointer, exiting", __func__); - return; - } - - dbg("%s - port %d", __func__, port->number); - usb_serial_debug_data(debug, &port->dev, __func__, - urb->actual_length, data); - - /* - * Work-a-round: handle the 'usual' bulk-in pipe here - */ - if (urb->transfer_buffer_length > 2) { - if (urb->actual_length) { - tty = tty_port_tty_get(&port->port); - if (tty) { - tty_insert_flip_string(tty, data, - urb->actual_length); - tty_flip_buffer_push(tty); - } - tty_kref_put(tty); - } - goto exit; - } - - /* - * The interrupt-in pipe signals exceptional conditions (modem line - * signal changes and errors). data[0] holds MSR, data[1] holds LSR. - */ - spin_lock_irqsave(&priv->lock, flags); - priv->last_msr = data[MCT_U232_MSR_INDEX]; - - /* Record Control Line states */ - mct_u232_msr_to_state(&priv->control_state, priv->last_msr); - - mct_u232_msr_to_icount(&priv->icount, priv->last_msr); - -#if 0 - /* Not yet handled. See belkin_sa.c for further information */ - /* Now to report any errors */ - priv->last_lsr = data[MCT_U232_LSR_INDEX]; - /* - * fill in the flip buffer here, but I do not know the relation - * to the current/next receive buffer or characters. I need - * to look in to this before committing any code. - */ - if (priv->last_lsr & MCT_U232_LSR_ERR) { - tty = tty_port_tty_get(&port->port); - /* Overrun Error */ - if (priv->last_lsr & MCT_U232_LSR_OE) { - } - /* Parity Error */ - if (priv->last_lsr & MCT_U232_LSR_PE) { - } - /* Framing Error */ - if (priv->last_lsr & MCT_U232_LSR_FE) { - } - /* Break Indicator */ - if (priv->last_lsr & MCT_U232_LSR_BI) { - } - tty_kref_put(tty); - } -#endif - wake_up_interruptible(&priv->msr_wait); - spin_unlock_irqrestore(&priv->lock, flags); -exit: - retval = usb_submit_urb(urb, GFP_ATOMIC); - if (retval) - dev_err(&port->dev, - "%s - usb_submit_urb failed with result %d\n", - __func__, retval); -} /* mct_u232_read_int_callback */ - -static void mct_u232_set_termios(struct tty_struct *tty, - struct usb_serial_port *port, - struct ktermios *old_termios) -{ - struct usb_serial *serial = port->serial; - struct mct_u232_private *priv = usb_get_serial_port_data(port); - struct ktermios *termios = tty->termios; - unsigned int cflag = termios->c_cflag; - unsigned int old_cflag = old_termios->c_cflag; - unsigned long flags; - unsigned int control_state; - unsigned char last_lcr; - - /* get a local copy of the current port settings */ - spin_lock_irqsave(&priv->lock, flags); - control_state = priv->control_state; - spin_unlock_irqrestore(&priv->lock, flags); - last_lcr = 0; - - /* - * Update baud rate. - * Do not attempt to cache old rates and skip settings, - * disconnects screw such tricks up completely. - * Premature optimization is the root of all evil. - */ - - /* reassert DTR and RTS on transition from B0 */ - if ((old_cflag & CBAUD) == B0) { - dbg("%s: baud was B0", __func__); - control_state |= TIOCM_DTR | TIOCM_RTS; - mct_u232_set_modem_ctrl(serial, control_state); - } - - mct_u232_set_baud_rate(tty, serial, port, tty_get_baud_rate(tty)); - - if ((cflag & CBAUD) == B0) { - dbg("%s: baud is B0", __func__); - /* Drop RTS and DTR */ - control_state &= ~(TIOCM_DTR | TIOCM_RTS); - mct_u232_set_modem_ctrl(serial, control_state); - } - - /* - * Update line control register (LCR) - */ - - /* set the parity */ - if (cflag & PARENB) - last_lcr |= (cflag & PARODD) ? - MCT_U232_PARITY_ODD : MCT_U232_PARITY_EVEN; - else - last_lcr |= MCT_U232_PARITY_NONE; - - /* set the number of data bits */ - switch (cflag & CSIZE) { - case CS5: - last_lcr |= MCT_U232_DATA_BITS_5; break; - case CS6: - last_lcr |= MCT_U232_DATA_BITS_6; break; - case CS7: - last_lcr |= MCT_U232_DATA_BITS_7; break; - case CS8: - last_lcr |= MCT_U232_DATA_BITS_8; break; - default: - dev_err(&port->dev, - "CSIZE was not CS5-CS8, using default of 8\n"); - last_lcr |= MCT_U232_DATA_BITS_8; - break; - } - - termios->c_cflag &= ~CMSPAR; - - /* set the number of stop bits */ - last_lcr |= (cflag & CSTOPB) ? - MCT_U232_STOP_BITS_2 : MCT_U232_STOP_BITS_1; - - mct_u232_set_line_ctrl(serial, last_lcr); - - /* save off the modified port settings */ - spin_lock_irqsave(&priv->lock, flags); - priv->control_state = control_state; - priv->last_lcr = last_lcr; - spin_unlock_irqrestore(&priv->lock, flags); -} /* mct_u232_set_termios */ - -static void mct_u232_break_ctl(struct tty_struct *tty, int break_state) -{ - struct usb_serial_port *port = tty->driver_data; - struct usb_serial *serial = port->serial; - struct mct_u232_private *priv = usb_get_serial_port_data(port); - unsigned char lcr; - unsigned long flags; - - dbg("%sstate=%d", __func__, break_state); - - spin_lock_irqsave(&priv->lock, flags); - lcr = priv->last_lcr; - - if (break_state) - lcr |= MCT_U232_SET_BREAK; - spin_unlock_irqrestore(&priv->lock, flags); - - mct_u232_set_line_ctrl(serial, lcr); -} /* mct_u232_break_ctl */ - - -static int mct_u232_tiocmget(struct tty_struct *tty) -{ - struct usb_serial_port *port = tty->driver_data; - struct mct_u232_private *priv = usb_get_serial_port_data(port); - unsigned int control_state; - unsigned long flags; - - dbg("%s", __func__); - - spin_lock_irqsave(&priv->lock, flags); - control_state = priv->control_state; - spin_unlock_irqrestore(&priv->lock, flags); - - return control_state; -} - -static int mct_u232_tiocmset(struct tty_struct *tty, - unsigned int set, unsigned int clear) -{ - struct usb_serial_port *port = tty->driver_data; - struct usb_serial *serial = port->serial; - struct mct_u232_private *priv = usb_get_serial_port_data(port); - unsigned int control_state; - unsigned long flags; - - dbg("%s", __func__); - - spin_lock_irqsave(&priv->lock, flags); - control_state = priv->control_state; - - if (set & TIOCM_RTS) - control_state |= TIOCM_RTS; - if (set & TIOCM_DTR) - control_state |= TIOCM_DTR; - if (clear & TIOCM_RTS) - control_state &= ~TIOCM_RTS; - if (clear & TIOCM_DTR) - control_state &= ~TIOCM_DTR; - - priv->control_state = control_state; - spin_unlock_irqrestore(&priv->lock, flags); - return mct_u232_set_modem_ctrl(serial, control_state); -} - -static void mct_u232_throttle(struct tty_struct *tty) -{ - struct usb_serial_port *port = tty->driver_data; - struct mct_u232_private *priv = usb_get_serial_port_data(port); - unsigned int control_state; - - dbg("%s - port %d", __func__, port->number); - - spin_lock_irq(&priv->lock); - priv->rx_flags |= THROTTLED; - if (C_CRTSCTS(tty)) { - priv->control_state &= ~TIOCM_RTS; - control_state = priv->control_state; - spin_unlock_irq(&priv->lock); - (void) mct_u232_set_modem_ctrl(port->serial, control_state); - } else { - spin_unlock_irq(&priv->lock); - } -} - -static void mct_u232_unthrottle(struct tty_struct *tty) -{ - struct usb_serial_port *port = tty->driver_data; - struct mct_u232_private *priv = usb_get_serial_port_data(port); - unsigned int control_state; - - dbg("%s - port %d", __func__, port->number); - - spin_lock_irq(&priv->lock); - if ((priv->rx_flags & THROTTLED) && C_CRTSCTS(tty)) { - priv->rx_flags &= ~THROTTLED; - priv->control_state |= TIOCM_RTS; - control_state = priv->control_state; - spin_unlock_irq(&priv->lock); - (void) mct_u232_set_modem_ctrl(port->serial, control_state); - } else { - spin_unlock_irq(&priv->lock); - } -} - -static int mct_u232_ioctl(struct tty_struct *tty, - unsigned int cmd, unsigned long arg) -{ - DEFINE_WAIT(wait); - struct usb_serial_port *port = tty->driver_data; - struct mct_u232_private *mct_u232_port = usb_get_serial_port_data(port); - struct async_icount cnow, cprev; - unsigned long flags; - - dbg("%s - port %d, cmd = 0x%x", __func__, port->number, cmd); - - switch (cmd) { - - case TIOCMIWAIT: - - dbg("%s (%d) TIOCMIWAIT", __func__, port->number); - - spin_lock_irqsave(&mct_u232_port->lock, flags); - cprev = mct_u232_port->icount; - spin_unlock_irqrestore(&mct_u232_port->lock, flags); - for ( ; ; ) { - prepare_to_wait(&mct_u232_port->msr_wait, - &wait, TASK_INTERRUPTIBLE); - schedule(); - finish_wait(&mct_u232_port->msr_wait, &wait); - /* see if a signal did it */ - if (signal_pending(current)) - return -ERESTARTSYS; - spin_lock_irqsave(&mct_u232_port->lock, flags); - cnow = mct_u232_port->icount; - spin_unlock_irqrestore(&mct_u232_port->lock, flags); - if (cnow.rng == cprev.rng && cnow.dsr == cprev.dsr && - cnow.dcd == cprev.dcd && cnow.cts == cprev.cts) - return -EIO; /* no change => error */ - if (((arg & TIOCM_RNG) && (cnow.rng != cprev.rng)) || - ((arg & TIOCM_DSR) && (cnow.dsr != cprev.dsr)) || - ((arg & TIOCM_CD) && (cnow.dcd != cprev.dcd)) || - ((arg & TIOCM_CTS) && (cnow.cts != cprev.cts))) { - return 0; - } - cprev = cnow; - } - - } - return -ENOIOCTLCMD; -} - -static int mct_u232_get_icount(struct tty_struct *tty, - struct serial_icounter_struct *icount) -{ - struct usb_serial_port *port = tty->driver_data; - struct mct_u232_private *mct_u232_port = usb_get_serial_port_data(port); - struct async_icount *ic = &mct_u232_port->icount; - unsigned long flags; - - spin_lock_irqsave(&mct_u232_port->lock, flags); - - icount->cts = ic->cts; - icount->dsr = ic->dsr; - icount->rng = ic->rng; - icount->dcd = ic->dcd; - icount->rx = ic->rx; - icount->tx = ic->tx; - icount->frame = ic->frame; - icount->overrun = ic->overrun; - icount->parity = ic->parity; - icount->brk = ic->brk; - icount->buf_overrun = ic->buf_overrun; - - spin_unlock_irqrestore(&mct_u232_port->lock, flags); - - dbg("%s (%d) TIOCGICOUNT RX=%d, TX=%d", - __func__, port->number, icount->rx, icount->tx); - return 0; -} - -module_usb_serial_driver(mct_u232_driver, serial_drivers); - -MODULE_AUTHOR(DRIVER_AUTHOR); -MODULE_DESCRIPTION(DRIVER_DESC); -MODULE_LICENSE("GPL"); - -module_param(debug, bool, S_IRUGO | S_IWUSR); -MODULE_PARM_DESC(debug, "Debug enabled or not"); diff --git a/ANDROID_3.4.5/drivers/usb/serial/mct_u232.h b/ANDROID_3.4.5/drivers/usb/serial/mct_u232.h deleted file mode 100644 index d325bb8c..00000000 --- a/ANDROID_3.4.5/drivers/usb/serial/mct_u232.h +++ /dev/null @@ -1,467 +0,0 @@ -/* - * Definitions for MCT (Magic Control Technology) USB-RS232 Converter Driver - * - * Copyright (C) 2000 Wolfgang Grandegger (wolfgang@ces.ch) - * - * 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. - * - * This driver is for the device MCT USB-RS232 Converter (25 pin, Model No. - * U232-P25) from Magic Control Technology Corp. (there is also a 9 pin - * Model No. U232-P9). See http://www.mct.com.tw/products/product_us232.html - * for further information. The properties of this device are listed at the end - * of this file. This device was used in the Dlink DSB-S25. - * - * All of the information about the device was acquired by using SniffUSB - * on Windows98. The technical details of the reverse engineering are - * summarized at the end of this file. - */ - -#ifndef __LINUX_USB_SERIAL_MCT_U232_H -#define __LINUX_USB_SERIAL_MCT_U232_H - -#define MCT_U232_VID 0x0711 /* Vendor Id */ -#define MCT_U232_PID 0x0210 /* Original MCT Product Id */ - -/* U232-P25, Sitecom */ -#define MCT_U232_SITECOM_PID 0x0230 /* Sitecom Product Id */ - -/* DU-H3SP USB BAY hub */ -#define MCT_U232_DU_H3SP_PID 0x0200 /* D-Link DU-H3SP USB BAY */ - -/* Belkin badge the MCT U232-P9 as the F5U109 */ -#define MCT_U232_BELKIN_F5U109_VID 0x050d /* Vendor Id */ -#define MCT_U232_BELKIN_F5U109_PID 0x0109 /* Product Id */ - -/* - * Vendor Request Interface - */ -#define MCT_U232_SET_REQUEST_TYPE 0x40 -#define MCT_U232_GET_REQUEST_TYPE 0xc0 - -/* Get Modem Status Register (MSR) */ -#define MCT_U232_GET_MODEM_STAT_REQUEST 2 -#define MCT_U232_GET_MODEM_STAT_SIZE 1 - -/* Get Line Control Register (LCR) */ -/* ... not used by this driver */ -#define MCT_U232_GET_LINE_CTRL_REQUEST 6 -#define MCT_U232_GET_LINE_CTRL_SIZE 1 - -/* Set Baud Rate Divisor */ -#define MCT_U232_SET_BAUD_RATE_REQUEST 5 -#define MCT_U232_SET_BAUD_RATE_SIZE 4 - -/* Set Line Control Register (LCR) */ -#define MCT_U232_SET_LINE_CTRL_REQUEST 7 -#define MCT_U232_SET_LINE_CTRL_SIZE 1 - -/* Set Modem Control Register (MCR) */ -#define MCT_U232_SET_MODEM_CTRL_REQUEST 10 -#define MCT_U232_SET_MODEM_CTRL_SIZE 1 - -/* - * This USB device request code is not well understood. It is transmitted by - * the MCT-supplied Windows driver whenever the baud rate changes. - */ -#define MCT_U232_SET_UNKNOWN1_REQUEST 11 /* Unknown functionality */ -#define MCT_U232_SET_UNKNOWN1_SIZE 1 - -/* - * This USB device request code appears to control whether CTS is required - * during transmission. - * - * Sending a zero byte allows data transmission to a device which is not - * asserting CTS. Sending a '1' byte will cause transmission to be deferred - * until the device asserts CTS. - */ -#define MCT_U232_SET_CTS_REQUEST 12 -#define MCT_U232_SET_CTS_SIZE 1 - -#define MCT_U232_MAX_SIZE 4 /* of MCT_XXX_SIZE */ - -/* - * Baud rate (divisor) - * Actually, there are two of them, MCT website calls them "Philips solution" - * and "Intel solution". They are the regular MCT and "Sitecom" for us. - * This is pointless to document in the header, see the code for the bits. - */ -static int mct_u232_calculate_baud_rate(struct usb_serial *serial, - speed_t value, speed_t *result); - -/* - * Line Control Register (LCR) - */ -#define MCT_U232_SET_BREAK 0x40 - -#define MCT_U232_PARITY_SPACE 0x38 -#define MCT_U232_PARITY_MARK 0x28 -#define MCT_U232_PARITY_EVEN 0x18 -#define MCT_U232_PARITY_ODD 0x08 -#define MCT_U232_PARITY_NONE 0x00 - -#define MCT_U232_DATA_BITS_5 0x00 -#define MCT_U232_DATA_BITS_6 0x01 -#define MCT_U232_DATA_BITS_7 0x02 -#define MCT_U232_DATA_BITS_8 0x03 - -#define MCT_U232_STOP_BITS_2 0x04 -#define MCT_U232_STOP_BITS_1 0x00 - -/* - * Modem Control Register (MCR) - */ -#define MCT_U232_MCR_NONE 0x8 /* Deactivate DTR and RTS */ -#define MCT_U232_MCR_RTS 0xa /* Activate RTS */ -#define MCT_U232_MCR_DTR 0x9 /* Activate DTR */ - -/* - * Modem Status Register (MSR) - */ -#define MCT_U232_MSR_INDEX 0x0 /* data[index] */ -#define MCT_U232_MSR_CD 0x80 /* Current CD */ -#define MCT_U232_MSR_RI 0x40 /* Current RI */ -#define MCT_U232_MSR_DSR 0x20 /* Current DSR */ -#define MCT_U232_MSR_CTS 0x10 /* Current CTS */ -#define MCT_U232_MSR_DCD 0x08 /* Delta CD */ -#define MCT_U232_MSR_DRI 0x04 /* Delta RI */ -#define MCT_U232_MSR_DDSR 0x02 /* Delta DSR */ -#define MCT_U232_MSR_DCTS 0x01 /* Delta CTS */ - -/* - * Line Status Register (LSR) - */ -#define MCT_U232_LSR_INDEX 1 /* data[index] */ -#define MCT_U232_LSR_ERR 0x80 /* OE | PE | FE | BI */ -#define MCT_U232_LSR_TEMT 0x40 /* transmit register empty */ -#define MCT_U232_LSR_THRE 0x20 /* transmit holding register empty */ -#define MCT_U232_LSR_BI 0x10 /* break indicator */ -#define MCT_U232_LSR_FE 0x08 /* framing error */ -#define MCT_U232_LSR_OE 0x02 /* overrun error */ -#define MCT_U232_LSR_PE 0x04 /* parity error */ -#define MCT_U232_LSR_OE 0x02 /* overrun error */ -#define MCT_U232_LSR_DR 0x01 /* receive data ready */ - - -/* ----------------------------------------------------------------------------- - * Technical Specification reverse engineered with SniffUSB on Windows98 - * ===================================================================== - * - * The technical details of the device have been acquired be using "SniffUSB" - * and the vendor-supplied device driver (version 2.3A) under Windows98. To - * identify the USB vendor-specific requests and to assign them to terminal - * settings (flow control, baud rate, etc.) the program "SerialSettings" from - * William G. Greathouse has been proven to be very useful. I also used the - * Win98 "HyperTerminal" and "usb-robot" on Linux for testing. The results and - * observations are summarized below: - * - * The USB requests seem to be directly mapped to the registers of a 8250, - * 16450 or 16550 UART. The FreeBSD handbook (appendix F.4 "Input/Output - * devices") contains a comprehensive description of UARTs and its registers. - * The bit descriptions are actually taken from there. - * - * - * Baud rate (divisor) - * ------------------- - * - * BmRequestType: 0x40 (0100 0000B) - * bRequest: 0x05 - * wValue: 0x0000 - * wIndex: 0x0000 - * wLength: 0x0004 - * Data: divisor = 115200 / baud_rate - * - * SniffUSB observations (Nov 2003): Contrary to the 'wLength' value of 4 - * shown above, observations with a Belkin F5U109 adapter, using the - * MCT-supplied Windows98 driver (U2SPORT.VXD, "File version: 1.21P.0104 for - * Win98/Me"), show this request has a length of 1 byte, presumably because - * of the fact that the Belkin adapter and the 'Sitecom U232-P25' adapter - * use a baud-rate code instead of a conventional RS-232 baud rate divisor. - * The current source code for this driver does not reflect this fact, but - * the driver works fine with this adapter/driver combination nonetheless. - * - * - * Line Control Register (LCR) - * --------------------------- - * - * BmRequestType: 0x40 (0100 0000B) 0xc0 (1100 0000B) - * bRequest: 0x07 0x06 - * wValue: 0x0000 - * wIndex: 0x0000 - * wLength: 0x0001 - * Data: LCR (see below) - * - * Bit 7: Divisor Latch Access Bit (DLAB). When set, access to the data - * transmit/receive register (THR/RBR) and the Interrupt Enable Register - * (IER) is disabled. Any access to these ports is now redirected to the - * Divisor Latch Registers. Setting this bit, loading the Divisor - * Registers, and clearing DLAB should be done with interrupts disabled. - * Bit 6: Set Break. When set to "1", the transmitter begins to transmit - * continuous Spacing until this bit is set to "0". This overrides any - * bits of characters that are being transmitted. - * Bit 5: Stick Parity. When parity is enabled, setting this bit causes parity - * to always be "1" or "0", based on the value of Bit 4. - * Bit 4: Even Parity Select (EPS). When parity is enabled and Bit 5 is "0", - * setting this bit causes even parity to be transmitted and expected. - * Otherwise, odd parity is used. - * Bit 3: Parity Enable (PEN). When set to "1", a parity bit is inserted - * between the last bit of the data and the Stop Bit. The UART will also - * expect parity to be present in the received data. - * Bit 2: Number of Stop Bits (STB). If set to "1" and using 5-bit data words, - * 1.5 Stop Bits are transmitted and expected in each data word. For - * 6, 7 and 8-bit data words, 2 Stop Bits are transmitted and expected. - * When this bit is set to "0", one Stop Bit is used on each data word. - * Bit 1: Word Length Select Bit #1 (WLSB1) - * Bit 0: Word Length Select Bit #0 (WLSB0) - * Together these bits specify the number of bits in each data word. - * 1 0 Word Length - * 0 0 5 Data Bits - * 0 1 6 Data Bits - * 1 0 7 Data Bits - * 1 1 8 Data Bits - * - * SniffUSB observations: Bit 7 seems not to be used. There seem to be two bugs - * in the Win98 driver: the break does not work (bit 6 is not asserted) and the - * stick parity bit is not cleared when set once. The LCR can also be read - * back with USB request 6 but this has never been observed with SniffUSB. - * - * - * Modem Control Register (MCR) - * ---------------------------- - * - * BmRequestType: 0x40 (0100 0000B) - * bRequest: 0x0a - * wValue: 0x0000 - * wIndex: 0x0000 - * wLength: 0x0001 - * Data: MCR (Bit 4..7, see below) - * - * Bit 7: Reserved, always 0. - * Bit 6: Reserved, always 0. - * Bit 5: Reserved, always 0. - * Bit 4: Loop-Back Enable. When set to "1", the UART transmitter and receiver - * are internally connected together to allow diagnostic operations. In - * addition, the UART modem control outputs are connected to the UART - * modem control inputs. CTS is connected to RTS, DTR is connected to - * DSR, OUT1 is connected to RI, and OUT 2 is connected to DCD. - * Bit 3: OUT 2. An auxiliary output that the host processor may set high or - * low. In the IBM PC serial adapter (and most clones), OUT 2 is used - * to tri-state (disable) the interrupt signal from the - * 8250/16450/16550 UART. - * Bit 2: OUT 1. An auxiliary output that the host processor may set high or - * low. This output is not used on the IBM PC serial adapter. - * Bit 1: Request to Send (RTS). When set to "1", the output of the UART -RTS - * line is Low (Active). - * Bit 0: Data Terminal Ready (DTR). When set to "1", the output of the UART - * -DTR line is Low (Active). - * - * SniffUSB observations: Bit 2 and 4 seem not to be used but bit 3 has been - * seen _always_ set. - * - * - * Modem Status Register (MSR) - * --------------------------- - * - * BmRequestType: 0xc0 (1100 0000B) - * bRequest: 0x02 - * wValue: 0x0000 - * wIndex: 0x0000 - * wLength: 0x0001 - * Data: MSR (see below) - * - * Bit 7: Data Carrier Detect (CD). Reflects the state of the DCD line on the - * UART. - * Bit 6: Ring Indicator (RI). Reflects the state of the RI line on the UART. - * Bit 5: Data Set Ready (DSR). Reflects the state of the DSR line on the UART. - * Bit 4: Clear To Send (CTS). Reflects the state of the CTS line on the UART. - * Bit 3: Delta Data Carrier Detect (DDCD). Set to "1" if the -DCD line has - * changed state one more more times since the last time the MSR was - * read by the host. - * Bit 2: Trailing Edge Ring Indicator (TERI). Set to "1" if the -RI line has - * had a low to high transition since the last time the MSR was read by - * the host. - * Bit 1: Delta Data Set Ready (DDSR). Set to "1" if the -DSR line has changed - * state one more more times since the last time the MSR was read by the - * host. - * Bit 0: Delta Clear To Send (DCTS). Set to "1" if the -CTS line has changed - * state one more times since the last time the MSR was read by the - * host. - * - * SniffUSB observations: the MSR is also returned as first byte on the - * interrupt-in endpoint 0x83 to signal changes of modem status lines. The USB - * request to read MSR cannot be applied during normal device operation. - * - * - * Line Status Register (LSR) - * -------------------------- - * - * Bit 7 Error in Receiver FIFO. On the 8250/16450 UART, this bit is zero. - * This bit is set to "1" when any of the bytes in the FIFO have one - * or more of the following error conditions: PE, FE, or BI. - * Bit 6 Transmitter Empty (TEMT). When set to "1", there are no words - * remaining in the transmit FIFO or the transmit shift register. The - * transmitter is completely idle. - * Bit 5 Transmitter Holding Register Empty (THRE). When set to "1", the - * FIFO (or holding register) now has room for at least one additional - * word to transmit. The transmitter may still be transmitting when - * this bit is set to "1". - * Bit 4 Break Interrupt (BI). The receiver has detected a Break signal. - * Bit 3 Framing Error (FE). A Start Bit was detected but the Stop Bit did - * not appear at the expected time. The received word is probably - * garbled. - * Bit 2 Parity Error (PE). The parity bit was incorrect for the word - * received. - * Bit 1 Overrun Error (OE). A new word was received and there was no room - * in the receive buffer. The newly-arrived word in the shift register - * is discarded. On 8250/16450 UARTs, the word in the holding register - * is discarded and the newly- arrived word is put in the holding - * register. - * Bit 0 Data Ready (DR). One or more words are in the receive FIFO that the - * host may read. A word must be completely received and moved from - * the shift register into the FIFO (or holding register for - * 8250/16450 designs) before this bit is set. - * - * SniffUSB observations: the LSR is returned as second byte on the - * interrupt-in endpoint 0x83 to signal error conditions. Such errors have - * been seen with minicom/zmodem transfers (CRC errors). - * - * - * Unknown #1 - * ------------------- - * - * BmRequestType: 0x40 (0100 0000B) - * bRequest: 0x0b - * wValue: 0x0000 - * wIndex: 0x0000 - * wLength: 0x0001 - * Data: 0x00 - * - * SniffUSB observations (Nov 2003): With the MCT-supplied Windows98 driver - * (U2SPORT.VXD, "File version: 1.21P.0104 for Win98/Me"), this request - * occurs immediately after a "Baud rate (divisor)" message. It was not - * observed at any other time. It is unclear what purpose this message - * serves. - * - * - * Unknown #2 - * ------------------- - * - * BmRequestType: 0x40 (0100 0000B) - * bRequest: 0x0c - * wValue: 0x0000 - * wIndex: 0x0000 - * wLength: 0x0001 - * Data: 0x00 - * - * SniffUSB observations (Nov 2003): With the MCT-supplied Windows98 driver - * (U2SPORT.VXD, "File version: 1.21P.0104 for Win98/Me"), this request - * occurs immediately after the 'Unknown #1' message (see above). It was - * not observed at any other time. It is unclear what other purpose (if - * any) this message might serve, but without it, the USB/RS-232 adapter - * will not write to RS-232 devices which do not assert the 'CTS' signal. - * - * - * Flow control - * ------------ - * - * SniffUSB observations: no flow control specific requests have been realized - * apart from DTR/RTS settings. Both signals are dropped for no flow control - * but asserted for hardware or software flow control. - * - * - * Endpoint usage - * -------------- - * - * SniffUSB observations: the bulk-out endpoint 0x1 and interrupt-in endpoint - * 0x81 is used to transmit and receive characters. The second interrupt-in - * endpoint 0x83 signals exceptional conditions like modem line changes and - * errors. The first byte returned is the MSR and the second byte the LSR. - * - * - * Other observations - * ------------------ - * - * Queued bulk transfers like used in visor.c did not work. - * - * - * Properties of the USB device used (as found in /var/log/messages) - * ----------------------------------------------------------------- - * - * Manufacturer: MCT Corporation. - * Product: USB-232 Interfact Controller - * SerialNumber: U2S22050 - * - * Length = 18 - * DescriptorType = 01 - * USB version = 1.00 - * Vendor:Product = 0711:0210 - * MaxPacketSize0 = 8 - * NumConfigurations = 1 - * Device version = 1.02 - * Device Class:SubClass:Protocol = 00:00:00 - * Per-interface classes - * Configuration: - * bLength = 9 - * bDescriptorType = 02 - * wTotalLength = 0027 - * bNumInterfaces = 01 - * bConfigurationValue = 01 - * iConfiguration = 00 - * bmAttributes = c0 - * MaxPower = 100mA - * - * Interface: 0 - * Alternate Setting: 0 - * bLength = 9 - * bDescriptorType = 04 - * bInterfaceNumber = 00 - * bAlternateSetting = 00 - * bNumEndpoints = 03 - * bInterface Class:SubClass:Protocol = 00:00:00 - * iInterface = 00 - * Endpoint: - * bLength = 7 - * bDescriptorType = 05 - * bEndpointAddress = 81 (in) - * bmAttributes = 03 (Interrupt) - * wMaxPacketSize = 0040 - * bInterval = 02 - * Endpoint: - * bLength = 7 - * bDescriptorType = 05 - * bEndpointAddress = 01 (out) - * bmAttributes = 02 (Bulk) - * wMaxPacketSize = 0040 - * bInterval = 00 - * Endpoint: - * bLength = 7 - * bDescriptorType = 05 - * bEndpointAddress = 83 (in) - * bmAttributes = 03 (Interrupt) - * wMaxPacketSize = 0002 - * bInterval = 02 - * - * - * Hardware details (added by Martin Hamilton, 2001/12/06) - * ----------------------------------------------------------------- - * - * This info was gleaned from opening a Belkin F5U109 DB9 USB serial - * adaptor, which turns out to simply be a re-badged U232-P9. We - * know this because there is a sticky label on the circuit board - * which says "U232-P9" ;-) - * - * The circuit board inside the adaptor contains a Philips PDIUSBD12 - * USB endpoint chip and a Philips P87C52UBAA microcontroller with - * embedded UART. Exhaustive documentation for these is available at: - * - * http://www.semiconductors.philips.com/pip/p87c52ubaa - * http://www.nxp.com/acrobat_download/various/PDIUSBD12_PROGRAMMING_GUIDE.pdf - * - * Thanks to Julian Highfield for the pointer to the Philips database. - * - */ - -#endif /* __LINUX_USB_SERIAL_MCT_U232_H */ - diff --git a/ANDROID_3.4.5/drivers/usb/serial/metro-usb.c b/ANDROID_3.4.5/drivers/usb/serial/metro-usb.c deleted file mode 100644 index 7c14671d..00000000 --- a/ANDROID_3.4.5/drivers/usb/serial/metro-usb.c +++ /dev/null @@ -1,394 +0,0 @@ -/* - Some of this code is credited to Linux USB open source files that are - distributed with Linux. - - Copyright: 2007 Metrologic Instruments. All rights reserved. - Copyright: 2011 Azimut Ltd. <http://azimutrzn.ru/> -*/ - -#include <linux/kernel.h> -#include <linux/init.h> -#include <linux/tty.h> -#include <linux/module.h> -#include <linux/usb.h> -#include <linux/errno.h> -#include <linux/slab.h> -#include <linux/tty_driver.h> -#include <linux/tty_flip.h> -#include <linux/moduleparam.h> -#include <linux/spinlock.h> -#include <linux/errno.h> -#include <linux/uaccess.h> -#include <linux/usb/serial.h> - -/* Version Information */ -#define DRIVER_VERSION "v1.2.0.0" -#define DRIVER_DESC "Metrologic Instruments Inc. - USB-POS driver" - -/* Product information. */ -#define FOCUS_VENDOR_ID 0x0C2E -#define FOCUS_PRODUCT_ID_BI 0x0720 -#define FOCUS_PRODUCT_ID_UNI 0x0700 - -#define METROUSB_SET_REQUEST_TYPE 0x40 -#define METROUSB_SET_MODEM_CTRL_REQUEST 10 -#define METROUSB_SET_BREAK_REQUEST 0x40 -#define METROUSB_MCR_NONE 0x08 /* Deactivate DTR and RTS. */ -#define METROUSB_MCR_RTS 0x0a /* Activate RTS. */ -#define METROUSB_MCR_DTR 0x09 /* Activate DTR. */ -#define WDR_TIMEOUT 5000 /* default urb timeout. */ - -/* Private data structure. */ -struct metrousb_private { - spinlock_t lock; - int throttled; - unsigned long control_state; -}; - -/* Device table list. */ -static struct usb_device_id id_table[] = { - { USB_DEVICE(FOCUS_VENDOR_ID, FOCUS_PRODUCT_ID_BI) }, - { USB_DEVICE(FOCUS_VENDOR_ID, FOCUS_PRODUCT_ID_UNI) }, - { }, /* Terminating entry. */ -}; -MODULE_DEVICE_TABLE(usb, id_table); - -/* Input parameter constants. */ -static bool debug; - -static void metrousb_read_int_callback(struct urb *urb) -{ - struct usb_serial_port *port = urb->context; - struct metrousb_private *metro_priv = usb_get_serial_port_data(port); - struct tty_struct *tty; - unsigned char *data = urb->transfer_buffer; - int throttled = 0; - int result = 0; - unsigned long flags = 0; - - dev_dbg(&port->dev, "%s\n", __func__); - - switch (urb->status) { - case 0: - /* Success status, read from the port. */ - break; - case -ECONNRESET: - case -ENOENT: - case -ESHUTDOWN: - /* urb has been terminated. */ - dev_dbg(&port->dev, - "%s - urb shutting down, error code=%d\n", - __func__, result); - return; - default: - dev_dbg(&port->dev, - "%s - non-zero urb received, error code=%d\n", - __func__, result); - goto exit; - } - - - /* Set the data read from the usb port into the serial port buffer. */ - tty = tty_port_tty_get(&port->port); - if (!tty) { - dev_dbg(&port->dev, "%s - bad tty pointer - exiting\n", - __func__); - return; - } - - if (tty && urb->actual_length) { - /* Loop through the data copying each byte to the tty layer. */ - tty_insert_flip_string(tty, data, urb->actual_length); - - /* Force the data to the tty layer. */ - tty_flip_buffer_push(tty); - } - tty_kref_put(tty); - - /* Set any port variables. */ - spin_lock_irqsave(&metro_priv->lock, flags); - throttled = metro_priv->throttled; - spin_unlock_irqrestore(&metro_priv->lock, flags); - - /* Continue trying to read if set. */ - if (!throttled) { - usb_fill_int_urb(port->interrupt_in_urb, port->serial->dev, - usb_rcvintpipe(port->serial->dev, port->interrupt_in_endpointAddress), - port->interrupt_in_urb->transfer_buffer, - port->interrupt_in_urb->transfer_buffer_length, - metrousb_read_int_callback, port, 1); - - result = usb_submit_urb(port->interrupt_in_urb, GFP_ATOMIC); - - if (result) - dev_dbg(&port->dev, - "%s - failed submitting interrupt in urb, error code=%d\n", - __func__, result); - } - return; - -exit: - /* Try to resubmit the urb. */ - result = usb_submit_urb(urb, GFP_ATOMIC); - if (result) - dev_dbg(&port->dev, - "%s - failed submitting interrupt in urb, error code=%d\n", - __func__, result); -} - -static void metrousb_cleanup(struct usb_serial_port *port) -{ - dev_dbg(&port->dev, "%s\n", __func__); - - if (port->serial->dev) { - /* Shutdown any interrupt in urbs. */ - if (port->interrupt_in_urb) { - usb_unlink_urb(port->interrupt_in_urb); - usb_kill_urb(port->interrupt_in_urb); - } - } -} - -static int metrousb_open(struct tty_struct *tty, struct usb_serial_port *port) -{ - struct usb_serial *serial = port->serial; - struct metrousb_private *metro_priv = usb_get_serial_port_data(port); - unsigned long flags = 0; - int result = 0; - - dev_dbg(&port->dev, "%s\n", __func__); - - /* Make sure the urb is initialized. */ - if (!port->interrupt_in_urb) { - dev_dbg(&port->dev, "%s - interrupt urb not initialized\n", - __func__); - return -ENODEV; - } - - /* Set the private data information for the port. */ - spin_lock_irqsave(&metro_priv->lock, flags); - metro_priv->control_state = 0; - metro_priv->throttled = 0; - spin_unlock_irqrestore(&metro_priv->lock, flags); - - /* Clear the urb pipe. */ - usb_clear_halt(serial->dev, port->interrupt_in_urb->pipe); - - /* Start reading from the device */ - usb_fill_int_urb(port->interrupt_in_urb, serial->dev, - usb_rcvintpipe(serial->dev, port->interrupt_in_endpointAddress), - port->interrupt_in_urb->transfer_buffer, - port->interrupt_in_urb->transfer_buffer_length, - metrousb_read_int_callback, port, 1); - result = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL); - - if (result) { - dev_dbg(&port->dev, - "%s - failed submitting interrupt in urb, error code=%d\n", - __func__, result); - goto exit; - } - - dev_dbg(&port->dev, "%s - port open\n", __func__); -exit: - return result; -} - -static int metrousb_set_modem_ctrl(struct usb_serial *serial, unsigned int control_state) -{ - int retval = 0; - unsigned char mcr = METROUSB_MCR_NONE; - - dev_dbg(&serial->dev->dev, "%s - control state = %d\n", - __func__, control_state); - - /* Set the modem control value. */ - if (control_state & TIOCM_DTR) - mcr |= METROUSB_MCR_DTR; - if (control_state & TIOCM_RTS) - mcr |= METROUSB_MCR_RTS; - - /* Send the command to the usb port. */ - retval = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0), - METROUSB_SET_REQUEST_TYPE, METROUSB_SET_MODEM_CTRL_REQUEST, - control_state, 0, NULL, 0, WDR_TIMEOUT); - if (retval < 0) - dev_dbg(&serial->dev->dev, - "%s - set modem ctrl=0x%x failed, error code=%d\n", - __func__, mcr, retval); - - return retval; -} - -static void metrousb_shutdown(struct usb_serial *serial) -{ - int i = 0; - - dev_dbg(&serial->dev->dev, "%s\n", __func__); - - /* Stop reading and writing on all ports. */ - for (i = 0; i < serial->num_ports; ++i) { - /* Close any open urbs. */ - metrousb_cleanup(serial->port[i]); - - /* Free memory. */ - kfree(usb_get_serial_port_data(serial->port[i])); - usb_set_serial_port_data(serial->port[i], NULL); - - dev_dbg(&serial->dev->dev, "%s - freed port number=%d\n", - __func__, serial->port[i]->number); - } -} - -static int metrousb_startup(struct usb_serial *serial) -{ - struct metrousb_private *metro_priv; - struct usb_serial_port *port; - int i = 0; - - dev_dbg(&serial->dev->dev, "%s\n", __func__); - - /* Loop through the serial ports setting up the private structures. - * Currently we only use one port. */ - for (i = 0; i < serial->num_ports; ++i) { - port = serial->port[i]; - - /* Declare memory. */ - metro_priv = kzalloc(sizeof(struct metrousb_private), GFP_KERNEL); - if (!metro_priv) - return -ENOMEM; - - /* Initialize memory. */ - spin_lock_init(&metro_priv->lock); - usb_set_serial_port_data(port, metro_priv); - - dev_dbg(&serial->dev->dev, "%s - port number=%d\n ", - __func__, port->number); - } - - return 0; -} - -static void metrousb_throttle(struct tty_struct *tty) -{ - struct usb_serial_port *port = tty->driver_data; - struct metrousb_private *metro_priv = usb_get_serial_port_data(port); - unsigned long flags = 0; - - dev_dbg(tty->dev, "%s\n", __func__); - - /* Set the private information for the port to stop reading data. */ - spin_lock_irqsave(&metro_priv->lock, flags); - metro_priv->throttled = 1; - spin_unlock_irqrestore(&metro_priv->lock, flags); -} - -static int metrousb_tiocmget(struct tty_struct *tty) -{ - unsigned long control_state = 0; - struct usb_serial_port *port = tty->driver_data; - struct metrousb_private *metro_priv = usb_get_serial_port_data(port); - unsigned long flags = 0; - - dev_dbg(tty->dev, "%s\n", __func__); - - spin_lock_irqsave(&metro_priv->lock, flags); - control_state = metro_priv->control_state; - spin_unlock_irqrestore(&metro_priv->lock, flags); - - return control_state; -} - -static int metrousb_tiocmset(struct tty_struct *tty, - unsigned int set, unsigned int clear) -{ - struct usb_serial_port *port = tty->driver_data; - struct usb_serial *serial = port->serial; - struct metrousb_private *metro_priv = usb_get_serial_port_data(port); - unsigned long flags = 0; - unsigned long control_state = 0; - - dev_dbg(tty->dev, "%s - set=%d, clear=%d\n", __func__, set, clear); - - spin_lock_irqsave(&metro_priv->lock, flags); - control_state = metro_priv->control_state; - - /* Set the RTS and DTR values. */ - if (set & TIOCM_RTS) - control_state |= TIOCM_RTS; - if (set & TIOCM_DTR) - control_state |= TIOCM_DTR; - if (clear & TIOCM_RTS) - control_state &= ~TIOCM_RTS; - if (clear & TIOCM_DTR) - control_state &= ~TIOCM_DTR; - - metro_priv->control_state = control_state; - spin_unlock_irqrestore(&metro_priv->lock, flags); - return metrousb_set_modem_ctrl(serial, control_state); -} - -static void metrousb_unthrottle(struct tty_struct *tty) -{ - struct usb_serial_port *port = tty->driver_data; - struct metrousb_private *metro_priv = usb_get_serial_port_data(port); - unsigned long flags = 0; - int result = 0; - - dev_dbg(tty->dev, "%s\n", __func__); - - /* Set the private information for the port to resume reading data. */ - spin_lock_irqsave(&metro_priv->lock, flags); - metro_priv->throttled = 0; - spin_unlock_irqrestore(&metro_priv->lock, flags); - - /* Submit the urb to read from the port. */ - port->interrupt_in_urb->dev = port->serial->dev; - result = usb_submit_urb(port->interrupt_in_urb, GFP_ATOMIC); - if (result) - dev_dbg(tty->dev, - "failed submitting interrupt in urb error code=%d\n", - result); -} - -static struct usb_driver metrousb_driver = { - .name = "metro-usb", - .probe = usb_serial_probe, - .disconnect = usb_serial_disconnect, - .id_table = id_table -}; - -static struct usb_serial_driver metrousb_device = { - .driver = { - .owner = THIS_MODULE, - .name = "metro-usb", - }, - .description = "Metrologic USB to serial converter.", - .id_table = id_table, - .num_ports = 1, - .open = metrousb_open, - .close = metrousb_cleanup, - .read_int_callback = metrousb_read_int_callback, - .attach = metrousb_startup, - .release = metrousb_shutdown, - .throttle = metrousb_throttle, - .unthrottle = metrousb_unthrottle, - .tiocmget = metrousb_tiocmget, - .tiocmset = metrousb_tiocmset, -}; - -static struct usb_serial_driver * const serial_drivers[] = { - &metrousb_device, - NULL, -}; - -module_usb_serial_driver(metrousb_driver, serial_drivers); - -MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Philip Nicastro"); -MODULE_AUTHOR("Aleksey Babahin <tamerlan311@gmail.com>"); -MODULE_DESCRIPTION(DRIVER_DESC); - -/* Module input parameters */ -module_param(debug, bool, S_IRUGO | S_IWUSR); -MODULE_PARM_DESC(debug, "Print debug info (bool 1=on, 0=off)"); diff --git a/ANDROID_3.4.5/drivers/usb/serial/mos7720.c b/ANDROID_3.4.5/drivers/usb/serial/mos7720.c deleted file mode 100644 index bdce8203..00000000 --- a/ANDROID_3.4.5/drivers/usb/serial/mos7720.c +++ /dev/null @@ -1,2213 +0,0 @@ -/* - * mos7720.c - * Controls the Moschip 7720 usb to dual port serial convertor - * - * Copyright 2006 Moschip Semiconductor Tech. Ltd. - * - * 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, version 2 of the License. - * - * Developed by: - * Vijaya Kumar <vijaykumar.gn@gmail.com> - * Ajay Kumar <naanuajay@yahoo.com> - * Gurudeva <ngurudeva@yahoo.com> - * - * Cleaned up from the original by: - * Greg Kroah-Hartman <gregkh@suse.de> - * - * Originally based on drivers/usb/serial/io_edgeport.c which is: - * Copyright (C) 2000 Inside Out Networks, All rights reserved. - * Copyright (C) 2001-2002 Greg Kroah-Hartman <greg@kroah.com> - */ -#include <linux/kernel.h> -#include <linux/errno.h> -#include <linux/init.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/serial.h> -#include <linux/serial_reg.h> -#include <linux/usb.h> -#include <linux/usb/serial.h> -#include <linux/uaccess.h> -#include <linux/parport.h> - -/* - * Version Information - */ -#define DRIVER_VERSION "2.1" -#define DRIVER_AUTHOR "Aspire Communications pvt Ltd." -#define DRIVER_DESC "Moschip USB Serial Driver" - -/* default urb timeout */ -#define MOS_WDR_TIMEOUT (HZ * 5) - -#define MOS_MAX_PORT 0x02 -#define MOS_WRITE 0x0E -#define MOS_READ 0x0D - -/* Interrupt Rotinue Defines */ -#define SERIAL_IIR_RLS 0x06 -#define SERIAL_IIR_RDA 0x04 -#define SERIAL_IIR_CTI 0x0c -#define SERIAL_IIR_THR 0x02 -#define SERIAL_IIR_MS 0x00 - -#define NUM_URBS 16 /* URB Count */ -#define URB_TRANSFER_BUFFER_SIZE 32 /* URB Size */ - -/* This structure holds all of the local serial port information */ -struct moschip_port { - __u8 shadowLCR; /* last LCR value received */ - __u8 shadowMCR; /* last MCR value received */ - __u8 shadowMSR; /* last MSR value received */ - char open; - struct async_icount icount; - struct usb_serial_port *port; /* loop back to the owner */ - struct urb *write_urb_pool[NUM_URBS]; -}; - -static bool debug; - -static struct usb_serial_driver moschip7720_2port_driver; - -#define USB_VENDOR_ID_MOSCHIP 0x9710 -#define MOSCHIP_DEVICE_ID_7720 0x7720 -#define MOSCHIP_DEVICE_ID_7715 0x7715 - -static const struct usb_device_id moschip_port_id_table[] = { - { USB_DEVICE(USB_VENDOR_ID_MOSCHIP, MOSCHIP_DEVICE_ID_7720) }, - { USB_DEVICE(USB_VENDOR_ID_MOSCHIP, MOSCHIP_DEVICE_ID_7715) }, - { } /* terminating entry */ -}; -MODULE_DEVICE_TABLE(usb, moschip_port_id_table); - -#ifdef CONFIG_USB_SERIAL_MOS7715_PARPORT - -/* initial values for parport regs */ -#define DCR_INIT_VAL 0x0c /* SLCTIN, nINIT */ -#define ECR_INIT_VAL 0x00 /* SPP mode */ - -struct urbtracker { - struct mos7715_parport *mos_parport; - struct list_head urblist_entry; - struct kref ref_count; - struct urb *urb; -}; - -enum mos7715_pp_modes { - SPP = 0<<5, - PS2 = 1<<5, /* moschip calls this 'NIBBLE' mode */ - PPF = 2<<5, /* moschip calls this 'CB-FIFO mode */ -}; - -struct mos7715_parport { - struct parport *pp; /* back to containing struct */ - struct kref ref_count; /* to instance of this struct */ - struct list_head deferred_urbs; /* list deferred async urbs */ - struct list_head active_urbs; /* list async urbs in flight */ - spinlock_t listlock; /* protects list access */ - bool msg_pending; /* usb sync call pending */ - struct completion syncmsg_compl; /* usb sync call completed */ - struct tasklet_struct urb_tasklet; /* for sending deferred urbs */ - struct usb_serial *serial; /* back to containing struct */ - __u8 shadowECR; /* parallel port regs... */ - __u8 shadowDCR; - atomic_t shadowDSR; /* updated in int-in callback */ -}; - -/* lock guards against dereferencing NULL ptr in parport ops callbacks */ -static DEFINE_SPINLOCK(release_lock); - -#endif /* CONFIG_USB_SERIAL_MOS7715_PARPORT */ - -static const unsigned int dummy; /* for clarity in register access fns */ - -enum mos_regs { - THR, /* serial port regs */ - RHR, - IER, - FCR, - ISR, - LCR, - MCR, - LSR, - MSR, - SPR, - DLL, - DLM, - DPR, /* parallel port regs */ - DSR, - DCR, - ECR, - SP1_REG, /* device control regs */ - SP2_REG, /* serial port 2 (7720 only) */ - PP_REG, - SP_CONTROL_REG, -}; - -/* - * Return the correct value for the Windex field of the setup packet - * for a control endpoint message. See the 7715 datasheet. - */ -static inline __u16 get_reg_index(enum mos_regs reg) -{ - static const __u16 mos7715_index_lookup_table[] = { - 0x00, /* THR */ - 0x00, /* RHR */ - 0x01, /* IER */ - 0x02, /* FCR */ - 0x02, /* ISR */ - 0x03, /* LCR */ - 0x04, /* MCR */ - 0x05, /* LSR */ - 0x06, /* MSR */ - 0x07, /* SPR */ - 0x00, /* DLL */ - 0x01, /* DLM */ - 0x00, /* DPR */ - 0x01, /* DSR */ - 0x02, /* DCR */ - 0x0a, /* ECR */ - 0x01, /* SP1_REG */ - 0x02, /* SP2_REG (7720 only) */ - 0x04, /* PP_REG (7715 only) */ - 0x08, /* SP_CONTROL_REG */ - }; - return mos7715_index_lookup_table[reg]; -} - -/* - * Return the correct value for the upper byte of the Wvalue field of - * the setup packet for a control endpoint message. - */ -static inline __u16 get_reg_value(enum mos_regs reg, - unsigned int serial_portnum) -{ - if (reg >= SP1_REG) /* control reg */ - return 0x0000; - - else if (reg >= DPR) /* parallel port reg (7715 only) */ - return 0x0100; - - else /* serial port reg */ - return (serial_portnum + 2) << 8; -} - -/* - * Write data byte to the specified device register. The data is embedded in - * the value field of the setup packet. serial_portnum is ignored for registers - * not specific to a particular serial port. - */ -static int write_mos_reg(struct usb_serial *serial, unsigned int serial_portnum, - enum mos_regs reg, __u8 data) -{ - struct usb_device *usbdev = serial->dev; - unsigned int pipe = usb_sndctrlpipe(usbdev, 0); - __u8 request = (__u8)0x0e; - __u8 requesttype = (__u8)0x40; - __u16 index = get_reg_index(reg); - __u16 value = get_reg_value(reg, serial_portnum) + data; - int status = usb_control_msg(usbdev, pipe, request, requesttype, value, - index, NULL, 0, MOS_WDR_TIMEOUT); - if (status < 0) - dev_err(&usbdev->dev, - "mos7720: usb_control_msg() failed: %d", status); - return status; -} - -/* - * Read data byte from the specified device register. The data returned by the - * device is embedded in the value field of the setup packet. serial_portnum is - * ignored for registers that are not specific to a particular serial port. - */ -static int read_mos_reg(struct usb_serial *serial, unsigned int serial_portnum, - enum mos_regs reg, __u8 *data) -{ - struct usb_device *usbdev = serial->dev; - unsigned int pipe = usb_rcvctrlpipe(usbdev, 0); - __u8 request = (__u8)0x0d; - __u8 requesttype = (__u8)0xc0; - __u16 index = get_reg_index(reg); - __u16 value = get_reg_value(reg, serial_portnum); - int status = usb_control_msg(usbdev, pipe, request, requesttype, value, - index, data, 1, MOS_WDR_TIMEOUT); - if (status < 0) - dev_err(&usbdev->dev, - "mos7720: usb_control_msg() failed: %d", status); - return status; -} - -#ifdef CONFIG_USB_SERIAL_MOS7715_PARPORT - -static inline int mos7715_change_mode(struct mos7715_parport *mos_parport, - enum mos7715_pp_modes mode) -{ - mos_parport->shadowECR = mode; - write_mos_reg(mos_parport->serial, dummy, ECR, mos_parport->shadowECR); - return 0; -} - -static void destroy_mos_parport(struct kref *kref) -{ - struct mos7715_parport *mos_parport = - container_of(kref, struct mos7715_parport, ref_count); - - dbg("%s called", __func__); - kfree(mos_parport); -} - -static void destroy_urbtracker(struct kref *kref) -{ - struct urbtracker *urbtrack = - container_of(kref, struct urbtracker, ref_count); - struct mos7715_parport *mos_parport = urbtrack->mos_parport; - dbg("%s called", __func__); - usb_free_urb(urbtrack->urb); - kfree(urbtrack); - kref_put(&mos_parport->ref_count, destroy_mos_parport); -} - -/* - * This runs as a tasklet when sending an urb in a non-blocking parallel - * port callback had to be deferred because the disconnect mutex could not be - * obtained at the time. - */ -static void send_deferred_urbs(unsigned long _mos_parport) -{ - int ret_val; - unsigned long flags; - struct mos7715_parport *mos_parport = (void *)_mos_parport; - struct urbtracker *urbtrack; - struct list_head *cursor, *next; - - dbg("%s called", __func__); - - /* if release function ran, game over */ - if (unlikely(mos_parport->serial == NULL)) - return; - - /* try again to get the mutex */ - if (!mutex_trylock(&mos_parport->serial->disc_mutex)) { - dbg("%s: rescheduling tasklet", __func__); - tasklet_schedule(&mos_parport->urb_tasklet); - return; - } - - /* if device disconnected, game over */ - if (unlikely(mos_parport->serial->disconnected)) { - mutex_unlock(&mos_parport->serial->disc_mutex); - return; - } - - spin_lock_irqsave(&mos_parport->listlock, flags); - if (list_empty(&mos_parport->deferred_urbs)) { - spin_unlock_irqrestore(&mos_parport->listlock, flags); - mutex_unlock(&mos_parport->serial->disc_mutex); - dbg("%s: deferred_urbs list empty", __func__); - return; - } - - /* move contents of deferred_urbs list to active_urbs list and submit */ - list_for_each_safe(cursor, next, &mos_parport->deferred_urbs) - list_move_tail(cursor, &mos_parport->active_urbs); - list_for_each_entry(urbtrack, &mos_parport->active_urbs, - urblist_entry) { - ret_val = usb_submit_urb(urbtrack->urb, GFP_ATOMIC); - dbg("%s: urb submitted", __func__); - if (ret_val) { - dev_err(&mos_parport->serial->dev->dev, - "usb_submit_urb() failed: %d", ret_val); - list_del(&urbtrack->urblist_entry); - kref_put(&urbtrack->ref_count, destroy_urbtracker); - } - } - spin_unlock_irqrestore(&mos_parport->listlock, flags); - mutex_unlock(&mos_parport->serial->disc_mutex); -} - -/* callback for parallel port control urbs submitted asynchronously */ -static void async_complete(struct urb *urb) -{ - struct urbtracker *urbtrack = urb->context; - int status = urb->status; - dbg("%s called", __func__); - if (unlikely(status)) - dbg("%s - nonzero urb status received: %d", __func__, status); - - /* remove the urbtracker from the active_urbs list */ - spin_lock(&urbtrack->mos_parport->listlock); - list_del(&urbtrack->urblist_entry); - spin_unlock(&urbtrack->mos_parport->listlock); - kref_put(&urbtrack->ref_count, destroy_urbtracker); -} - -static int write_parport_reg_nonblock(struct mos7715_parport *mos_parport, - enum mos_regs reg, __u8 data) -{ - struct urbtracker *urbtrack; - int ret_val; - unsigned long flags; - struct usb_ctrlrequest setup; - struct usb_serial *serial = mos_parport->serial; - struct usb_device *usbdev = serial->dev; - dbg("%s called", __func__); - - /* create and initialize the control urb and containing urbtracker */ - urbtrack = kmalloc(sizeof(struct urbtracker), GFP_ATOMIC); - if (urbtrack == NULL) { - dev_err(&usbdev->dev, "out of memory"); - return -ENOMEM; - } - kref_get(&mos_parport->ref_count); - urbtrack->mos_parport = mos_parport; - urbtrack->urb = usb_alloc_urb(0, GFP_ATOMIC); - if (urbtrack->urb == NULL) { - dev_err(&usbdev->dev, "out of urbs"); - kfree(urbtrack); - return -ENOMEM; - } - setup.bRequestType = (__u8)0x40; - setup.bRequest = (__u8)0x0e; - setup.wValue = get_reg_value(reg, dummy); - setup.wIndex = get_reg_index(reg); - setup.wLength = 0; - usb_fill_control_urb(urbtrack->urb, usbdev, - usb_sndctrlpipe(usbdev, 0), - (unsigned char *)&setup, - NULL, 0, async_complete, urbtrack); - kref_init(&urbtrack->ref_count); - INIT_LIST_HEAD(&urbtrack->urblist_entry); - - /* - * get the disconnect mutex, or add tracker to the deferred_urbs list - * and schedule a tasklet to try again later - */ - if (!mutex_trylock(&serial->disc_mutex)) { - spin_lock_irqsave(&mos_parport->listlock, flags); - list_add_tail(&urbtrack->urblist_entry, - &mos_parport->deferred_urbs); - spin_unlock_irqrestore(&mos_parport->listlock, flags); - tasklet_schedule(&mos_parport->urb_tasklet); - dbg("tasklet scheduled"); - return 0; - } - - /* bail if device disconnected */ - if (serial->disconnected) { - kref_put(&urbtrack->ref_count, destroy_urbtracker); - mutex_unlock(&serial->disc_mutex); - return -ENODEV; - } - - /* add the tracker to the active_urbs list and submit */ - spin_lock_irqsave(&mos_parport->listlock, flags); - list_add_tail(&urbtrack->urblist_entry, &mos_parport->active_urbs); - spin_unlock_irqrestore(&mos_parport->listlock, flags); - ret_val = usb_submit_urb(urbtrack->urb, GFP_ATOMIC); - mutex_unlock(&serial->disc_mutex); - if (ret_val) { - dev_err(&usbdev->dev, - "%s: submit_urb() failed: %d", __func__, ret_val); - spin_lock_irqsave(&mos_parport->listlock, flags); - list_del(&urbtrack->urblist_entry); - spin_unlock_irqrestore(&mos_parport->listlock, flags); - kref_put(&urbtrack->ref_count, destroy_urbtracker); - return ret_val; - } - return 0; -} - -/* - * This is the the common top part of all parallel port callback operations that - * send synchronous messages to the device. This implements convoluted locking - * that avoids two scenarios: (1) a port operation is called after usbserial - * has called our release function, at which point struct mos7715_parport has - * been destroyed, and (2) the device has been disconnected, but usbserial has - * not called the release function yet because someone has a serial port open. - * The shared release_lock prevents the first, and the mutex and disconnected - * flag maintained by usbserial covers the second. We also use the msg_pending - * flag to ensure that all synchronous usb messgage calls have completed before - * our release function can return. - */ -static int parport_prologue(struct parport *pp) -{ - struct mos7715_parport *mos_parport; - - spin_lock(&release_lock); - mos_parport = pp->private_data; - if (unlikely(mos_parport == NULL)) { - /* release fn called, port struct destroyed */ - spin_unlock(&release_lock); - return -1; - } - mos_parport->msg_pending = true; /* synch usb call pending */ - INIT_COMPLETION(mos_parport->syncmsg_compl); - spin_unlock(&release_lock); - - mutex_lock(&mos_parport->serial->disc_mutex); - if (mos_parport->serial->disconnected) { - /* device disconnected */ - mutex_unlock(&mos_parport->serial->disc_mutex); - mos_parport->msg_pending = false; - complete(&mos_parport->syncmsg_compl); - return -1; - } - - return 0; -} - -/* - * This is the the common bottom part of all parallel port functions that send - * synchronous messages to the device. - */ -static inline void parport_epilogue(struct parport *pp) -{ - struct mos7715_parport *mos_parport = pp->private_data; - mutex_unlock(&mos_parport->serial->disc_mutex); - mos_parport->msg_pending = false; - complete(&mos_parport->syncmsg_compl); -} - -static void parport_mos7715_write_data(struct parport *pp, unsigned char d) -{ - struct mos7715_parport *mos_parport = pp->private_data; - dbg("%s called: %2.2x", __func__, d); - if (parport_prologue(pp) < 0) - return; - mos7715_change_mode(mos_parport, SPP); - write_mos_reg(mos_parport->serial, dummy, DPR, (__u8)d); - parport_epilogue(pp); -} - -static unsigned char parport_mos7715_read_data(struct parport *pp) -{ - struct mos7715_parport *mos_parport = pp->private_data; - unsigned char d; - dbg("%s called", __func__); - if (parport_prologue(pp) < 0) - return 0; - read_mos_reg(mos_parport->serial, dummy, DPR, &d); - parport_epilogue(pp); - return d; -} - -static void parport_mos7715_write_control(struct parport *pp, unsigned char d) -{ - struct mos7715_parport *mos_parport = pp->private_data; - __u8 data; - dbg("%s called: %2.2x", __func__, d); - if (parport_prologue(pp) < 0) - return; - data = ((__u8)d & 0x0f) | (mos_parport->shadowDCR & 0xf0); - write_mos_reg(mos_parport->serial, dummy, DCR, data); - mos_parport->shadowDCR = data; - parport_epilogue(pp); -} - -static unsigned char parport_mos7715_read_control(struct parport *pp) -{ - struct mos7715_parport *mos_parport = pp->private_data; - __u8 dcr; - dbg("%s called", __func__); - spin_lock(&release_lock); - mos_parport = pp->private_data; - if (unlikely(mos_parport == NULL)) { - spin_unlock(&release_lock); - return 0; - } - dcr = mos_parport->shadowDCR & 0x0f; - spin_unlock(&release_lock); - return dcr; -} - -static unsigned char parport_mos7715_frob_control(struct parport *pp, - unsigned char mask, - unsigned char val) -{ - struct mos7715_parport *mos_parport = pp->private_data; - __u8 dcr; - dbg("%s called", __func__); - mask &= 0x0f; - val &= 0x0f; - if (parport_prologue(pp) < 0) - return 0; - mos_parport->shadowDCR = (mos_parport->shadowDCR & (~mask)) ^ val; - write_mos_reg(mos_parport->serial, dummy, DCR, mos_parport->shadowDCR); - dcr = mos_parport->shadowDCR & 0x0f; - parport_epilogue(pp); - return dcr; -} - -static unsigned char parport_mos7715_read_status(struct parport *pp) -{ - unsigned char status; - struct mos7715_parport *mos_parport = pp->private_data; - dbg("%s called", __func__); - spin_lock(&release_lock); - mos_parport = pp->private_data; - if (unlikely(mos_parport == NULL)) { /* release called */ - spin_unlock(&release_lock); - return 0; - } - status = atomic_read(&mos_parport->shadowDSR) & 0xf8; - spin_unlock(&release_lock); - return status; -} - -static void parport_mos7715_enable_irq(struct parport *pp) -{ - dbg("%s called", __func__); -} -static void parport_mos7715_disable_irq(struct parport *pp) -{ - dbg("%s called", __func__); -} - -static void parport_mos7715_data_forward(struct parport *pp) -{ - struct mos7715_parport *mos_parport = pp->private_data; - dbg("%s called", __func__); - if (parport_prologue(pp) < 0) - return; - mos7715_change_mode(mos_parport, PS2); - mos_parport->shadowDCR &= ~0x20; - write_mos_reg(mos_parport->serial, dummy, DCR, mos_parport->shadowDCR); - parport_epilogue(pp); -} - -static void parport_mos7715_data_reverse(struct parport *pp) -{ - struct mos7715_parport *mos_parport = pp->private_data; - dbg("%s called", __func__); - if (parport_prologue(pp) < 0) - return; - mos7715_change_mode(mos_parport, PS2); - mos_parport->shadowDCR |= 0x20; - write_mos_reg(mos_parport->serial, dummy, DCR, mos_parport->shadowDCR); - parport_epilogue(pp); -} - -static void parport_mos7715_init_state(struct pardevice *dev, - struct parport_state *s) -{ - dbg("%s called", __func__); - s->u.pc.ctr = DCR_INIT_VAL; - s->u.pc.ecr = ECR_INIT_VAL; -} - -/* N.B. Parport core code requires that this function not block */ -static void parport_mos7715_save_state(struct parport *pp, - struct parport_state *s) -{ - struct mos7715_parport *mos_parport; - dbg("%s called", __func__); - spin_lock(&release_lock); - mos_parport = pp->private_data; - if (unlikely(mos_parport == NULL)) { /* release called */ - spin_unlock(&release_lock); - return; - } - s->u.pc.ctr = mos_parport->shadowDCR; - s->u.pc.ecr = mos_parport->shadowECR; - spin_unlock(&release_lock); -} - -/* N.B. Parport core code requires that this function not block */ -static void parport_mos7715_restore_state(struct parport *pp, - struct parport_state *s) -{ - struct mos7715_parport *mos_parport; - dbg("%s called", __func__); - spin_lock(&release_lock); - mos_parport = pp->private_data; - if (unlikely(mos_parport == NULL)) { /* release called */ - spin_unlock(&release_lock); - return; - } - write_parport_reg_nonblock(mos_parport, DCR, mos_parport->shadowDCR); - write_parport_reg_nonblock(mos_parport, ECR, mos_parport->shadowECR); - spin_unlock(&release_lock); -} - -static size_t parport_mos7715_write_compat(struct parport *pp, - const void *buffer, - size_t len, int flags) -{ - int retval; - struct mos7715_parport *mos_parport = pp->private_data; - int actual_len; - dbg("%s called: %u chars", __func__, (unsigned int)len); - if (parport_prologue(pp) < 0) - return 0; - mos7715_change_mode(mos_parport, PPF); - retval = usb_bulk_msg(mos_parport->serial->dev, - usb_sndbulkpipe(mos_parport->serial->dev, 2), - (void *)buffer, len, &actual_len, - MOS_WDR_TIMEOUT); - parport_epilogue(pp); - if (retval) { - dev_err(&mos_parport->serial->dev->dev, - "mos7720: usb_bulk_msg() failed: %d", retval); - return 0; - } - return actual_len; -} - -static struct parport_operations parport_mos7715_ops = { - .owner = THIS_MODULE, - .write_data = parport_mos7715_write_data, - .read_data = parport_mos7715_read_data, - - .write_control = parport_mos7715_write_control, - .read_control = parport_mos7715_read_control, - .frob_control = parport_mos7715_frob_control, - - .read_status = parport_mos7715_read_status, - - .enable_irq = parport_mos7715_enable_irq, - .disable_irq = parport_mos7715_disable_irq, - - .data_forward = parport_mos7715_data_forward, - .data_reverse = parport_mos7715_data_reverse, - - .init_state = parport_mos7715_init_state, - .save_state = parport_mos7715_save_state, - .restore_state = parport_mos7715_restore_state, - - .compat_write_data = parport_mos7715_write_compat, - - .nibble_read_data = parport_ieee1284_read_nibble, - .byte_read_data = parport_ieee1284_read_byte, -}; - -/* - * Allocate and initialize parallel port control struct, initialize - * the parallel port hardware device, and register with the parport subsystem. - */ -static int mos7715_parport_init(struct usb_serial *serial) -{ - struct mos7715_parport *mos_parport; - - /* allocate and initialize parallel port control struct */ - mos_parport = kzalloc(sizeof(struct mos7715_parport), GFP_KERNEL); - if (mos_parport == NULL) { - dbg("mos7715_parport_init: kzalloc failed"); - return -ENOMEM; - } - mos_parport->msg_pending = false; - kref_init(&mos_parport->ref_count); - spin_lock_init(&mos_parport->listlock); - INIT_LIST_HEAD(&mos_parport->active_urbs); - INIT_LIST_HEAD(&mos_parport->deferred_urbs); - usb_set_serial_data(serial, mos_parport); /* hijack private pointer */ - mos_parport->serial = serial; - tasklet_init(&mos_parport->urb_tasklet, send_deferred_urbs, - (unsigned long) mos_parport); - init_completion(&mos_parport->syncmsg_compl); - - /* cycle parallel port reset bit */ - write_mos_reg(mos_parport->serial, dummy, PP_REG, (__u8)0x80); - write_mos_reg(mos_parport->serial, dummy, PP_REG, (__u8)0x00); - - /* initialize device registers */ - mos_parport->shadowDCR = DCR_INIT_VAL; - write_mos_reg(mos_parport->serial, dummy, DCR, mos_parport->shadowDCR); - mos_parport->shadowECR = ECR_INIT_VAL; - write_mos_reg(mos_parport->serial, dummy, ECR, mos_parport->shadowECR); - - /* register with parport core */ - mos_parport->pp = parport_register_port(0, PARPORT_IRQ_NONE, - PARPORT_DMA_NONE, - &parport_mos7715_ops); - if (mos_parport->pp == NULL) { - dev_err(&serial->interface->dev, - "Could not register parport\n"); - kref_put(&mos_parport->ref_count, destroy_mos_parport); - return -EIO; - } - mos_parport->pp->private_data = mos_parport; - mos_parport->pp->modes = PARPORT_MODE_COMPAT | PARPORT_MODE_PCSPP; - mos_parport->pp->dev = &serial->interface->dev; - parport_announce_port(mos_parport->pp); - - return 0; -} -#endif /* CONFIG_USB_SERIAL_MOS7715_PARPORT */ - -/* - * mos7720_interrupt_callback - * this is the callback function for when we have received data on the - * interrupt endpoint. - */ -static void mos7720_interrupt_callback(struct urb *urb) -{ - int result; - int length; - int status = urb->status; - __u8 *data; - __u8 sp1; - __u8 sp2; - - switch (status) { - case 0: - /* success */ - break; - case -ECONNRESET: - case -ENOENT: - case -ESHUTDOWN: - /* this urb is terminated, clean up */ - dbg("%s - urb shutting down with status: %d", __func__, - status); - return; - default: - dbg("%s - nonzero urb status received: %d", __func__, - status); - goto exit; - } - - length = urb->actual_length; - data = urb->transfer_buffer; - - /* Moschip get 4 bytes - * Byte 1 IIR Port 1 (port.number is 0) - * Byte 2 IIR Port 2 (port.number is 1) - * Byte 3 -------------- - * Byte 4 FIFO status for both */ - - /* the above description is inverted - * oneukum 2007-03-14 */ - - if (unlikely(length != 4)) { - dbg("Wrong data !!!"); - return; - } - - sp1 = data[3]; - sp2 = data[2]; - - if ((sp1 | sp2) & 0x01) { - /* No Interrupt Pending in both the ports */ - dbg("No Interrupt !!!"); - } else { - switch (sp1 & 0x0f) { - case SERIAL_IIR_RLS: - dbg("Serial Port 1: Receiver status error or address " - "bit detected in 9-bit mode\n"); - break; - case SERIAL_IIR_CTI: - dbg("Serial Port 1: Receiver time out"); - break; - case SERIAL_IIR_MS: - /* dbg("Serial Port 1: Modem status change"); */ - break; - } - - switch (sp2 & 0x0f) { - case SERIAL_IIR_RLS: - dbg("Serial Port 2: Receiver status error or address " - "bit detected in 9-bit mode"); - break; - case SERIAL_IIR_CTI: - dbg("Serial Port 2: Receiver time out"); - break; - case SERIAL_IIR_MS: - /* dbg("Serial Port 2: Modem status change"); */ - break; - } - } - -exit: - result = usb_submit_urb(urb, GFP_ATOMIC); - if (result) - dev_err(&urb->dev->dev, - "%s - Error %d submitting control urb\n", - __func__, result); -} - -/* - * mos7715_interrupt_callback - * this is the 7715's callback function for when we have received data on - * the interrupt endpoint. - */ -static void mos7715_interrupt_callback(struct urb *urb) -{ - int result; - int length; - int status = urb->status; - __u8 *data; - __u8 iir; - - switch (status) { - case 0: - /* success */ - break; - case -ECONNRESET: - case -ENOENT: - case -ESHUTDOWN: - case -ENODEV: - /* this urb is terminated, clean up */ - dbg("%s - urb shutting down with status: %d", __func__, - status); - return; - default: - dbg("%s - nonzero urb status received: %d", __func__, - status); - goto exit; - } - - length = urb->actual_length; - data = urb->transfer_buffer; - - /* Structure of data from 7715 device: - * Byte 1: IIR serial Port - * Byte 2: unused - * Byte 2: DSR parallel port - * Byte 4: FIFO status for both */ - - if (unlikely(length != 4)) { - dbg("Wrong data !!!"); - return; - } - - iir = data[0]; - if (!(iir & 0x01)) { /* serial port interrupt pending */ - switch (iir & 0x0f) { - case SERIAL_IIR_RLS: - dbg("Serial Port: Receiver status error or address " - "bit detected in 9-bit mode\n"); - break; - case SERIAL_IIR_CTI: - dbg("Serial Port: Receiver time out"); - break; - case SERIAL_IIR_MS: - /* dbg("Serial Port: Modem status change"); */ - break; - } - } - -#ifdef CONFIG_USB_SERIAL_MOS7715_PARPORT - { /* update local copy of DSR reg */ - struct usb_serial_port *port = urb->context; - struct mos7715_parport *mos_parport = port->serial->private; - if (unlikely(mos_parport == NULL)) - return; - atomic_set(&mos_parport->shadowDSR, data[2]); - } -#endif - -exit: - result = usb_submit_urb(urb, GFP_ATOMIC); - if (result) - dev_err(&urb->dev->dev, - "%s - Error %d submitting control urb\n", - __func__, result); -} - -/* - * mos7720_bulk_in_callback - * this is the callback function for when we have received data on the - * bulk in endpoint. - */ -static void mos7720_bulk_in_callback(struct urb *urb) -{ - int retval; - unsigned char *data ; - struct usb_serial_port *port; - struct tty_struct *tty; - int status = urb->status; - - if (status) { - dbg("nonzero read bulk status received: %d", status); - return; - } - - port = urb->context; - - dbg("Entering...%s", __func__); - - data = urb->transfer_buffer; - - tty = tty_port_tty_get(&port->port); - if (tty && urb->actual_length) { - tty_insert_flip_string(tty, data, urb->actual_length); - tty_flip_buffer_push(tty); - } - tty_kref_put(tty); - - if (port->read_urb->status != -EINPROGRESS) { - retval = usb_submit_urb(port->read_urb, GFP_ATOMIC); - if (retval) - dbg("usb_submit_urb(read bulk) failed, retval = %d", - retval); - } -} - -/* - * mos7720_bulk_out_data_callback - * this is the callback function for when we have finished sending serial - * data on the bulk out endpoint. - */ -static void mos7720_bulk_out_data_callback(struct urb *urb) -{ - struct moschip_port *mos7720_port; - struct tty_struct *tty; - int status = urb->status; - - if (status) { - dbg("nonzero write bulk status received:%d", status); - return; - } - - mos7720_port = urb->context; - if (!mos7720_port) { - dbg("NULL mos7720_port pointer"); - return ; - } - - tty = tty_port_tty_get(&mos7720_port->port->port); - - if (tty && mos7720_port->open) - tty_wakeup(tty); - tty_kref_put(tty); -} - -/* - * mos77xx_probe - * this function installs the appropriate read interrupt endpoint callback - * depending on whether the device is a 7720 or 7715, thus avoiding costly - * run-time checks in the high-frequency callback routine itself. - */ -static int mos77xx_probe(struct usb_serial *serial, - const struct usb_device_id *id) -{ - if (id->idProduct == MOSCHIP_DEVICE_ID_7715) - moschip7720_2port_driver.read_int_callback = - mos7715_interrupt_callback; - else - moschip7720_2port_driver.read_int_callback = - mos7720_interrupt_callback; - - return 0; -} - -static int mos77xx_calc_num_ports(struct usb_serial *serial) -{ - u16 product = le16_to_cpu(serial->dev->descriptor.idProduct); - if (product == MOSCHIP_DEVICE_ID_7715) - return 1; - - return 2; -} - -static int mos7720_open(struct tty_struct *tty, struct usb_serial_port *port) -{ - struct usb_serial *serial; - struct urb *urb; - struct moschip_port *mos7720_port; - int response; - int port_number; - __u8 data; - int allocated_urbs = 0; - int j; - - serial = port->serial; - - mos7720_port = usb_get_serial_port_data(port); - if (mos7720_port == NULL) - return -ENODEV; - - usb_clear_halt(serial->dev, port->write_urb->pipe); - usb_clear_halt(serial->dev, port->read_urb->pipe); - - /* Initialising the write urb pool */ - for (j = 0; j < NUM_URBS; ++j) { - urb = usb_alloc_urb(0, GFP_KERNEL); - mos7720_port->write_urb_pool[j] = urb; - - if (urb == NULL) { - dev_err(&port->dev, "No more urbs???\n"); - continue; - } - - urb->transfer_buffer = kmalloc(URB_TRANSFER_BUFFER_SIZE, - GFP_KERNEL); - if (!urb->transfer_buffer) { - dev_err(&port->dev, - "%s-out of memory for urb buffers.\n", - __func__); - usb_free_urb(mos7720_port->write_urb_pool[j]); - mos7720_port->write_urb_pool[j] = NULL; - continue; - } - allocated_urbs++; - } - - if (!allocated_urbs) - return -ENOMEM; - - /* Initialize MCS7720 -- Write Init values to corresponding Registers - * - * Register Index - * 0 : THR/RHR - * 1 : IER - * 2 : FCR - * 3 : LCR - * 4 : MCR - * 5 : LSR - * 6 : MSR - * 7 : SPR - * - * 0x08 : SP1/2 Control Reg - */ - port_number = port->number - port->serial->minor; - read_mos_reg(serial, port_number, LSR, &data); - - dbg("SS::%p LSR:%x", mos7720_port, data); - - dbg("Check:Sending Command .........."); - - write_mos_reg(serial, dummy, SP1_REG, 0x02); - write_mos_reg(serial, dummy, SP2_REG, 0x02); - - write_mos_reg(serial, port_number, IER, 0x00); - write_mos_reg(serial, port_number, FCR, 0x00); - - write_mos_reg(serial, port_number, FCR, 0xcf); - mos7720_port->shadowLCR = 0x03; - write_mos_reg(serial, port_number, LCR, mos7720_port->shadowLCR); - mos7720_port->shadowMCR = 0x0b; - write_mos_reg(serial, port_number, MCR, mos7720_port->shadowMCR); - - write_mos_reg(serial, port_number, SP_CONTROL_REG, 0x00); - read_mos_reg(serial, dummy, SP_CONTROL_REG, &data); - data = data | (port->number - port->serial->minor + 1); - write_mos_reg(serial, dummy, SP_CONTROL_REG, data); - mos7720_port->shadowLCR = 0x83; - write_mos_reg(serial, port_number, LCR, mos7720_port->shadowLCR); - write_mos_reg(serial, port_number, THR, 0x0c); - write_mos_reg(serial, port_number, IER, 0x00); - mos7720_port->shadowLCR = 0x03; - write_mos_reg(serial, port_number, LCR, mos7720_port->shadowLCR); - write_mos_reg(serial, port_number, IER, 0x0c); - - response = usb_submit_urb(port->read_urb, GFP_KERNEL); - if (response) - dev_err(&port->dev, "%s - Error %d submitting read urb\n", - __func__, response); - - /* initialize our icount structure */ - memset(&(mos7720_port->icount), 0x00, sizeof(mos7720_port->icount)); - - /* initialize our port settings */ - mos7720_port->shadowMCR = UART_MCR_OUT2; /* Must set to enable ints! */ - - /* send a open port command */ - mos7720_port->open = 1; - - return 0; -} - -/* - * mos7720_chars_in_buffer - * this function is called by the tty driver when it wants to know how many - * bytes of data we currently have outstanding in the port (data that has - * been written, but hasn't made it out the port yet) - * If successful, we return the number of bytes left to be written in the - * system, - * Otherwise we return a negative error number. - */ -static int mos7720_chars_in_buffer(struct tty_struct *tty) -{ - struct usb_serial_port *port = tty->driver_data; - int i; - int chars = 0; - struct moschip_port *mos7720_port; - - dbg("%s:entering ...........", __func__); - - mos7720_port = usb_get_serial_port_data(port); - if (mos7720_port == NULL) { - dbg("%s:leaving ...........", __func__); - return 0; - } - - for (i = 0; i < NUM_URBS; ++i) { - if (mos7720_port->write_urb_pool[i] && - mos7720_port->write_urb_pool[i]->status == -EINPROGRESS) - chars += URB_TRANSFER_BUFFER_SIZE; - } - dbg("%s - returns %d", __func__, chars); - return chars; -} - -static void mos7720_close(struct usb_serial_port *port) -{ - struct usb_serial *serial; - struct moschip_port *mos7720_port; - int j; - - dbg("mos7720_close:entering..."); - - serial = port->serial; - - mos7720_port = usb_get_serial_port_data(port); - if (mos7720_port == NULL) - return; - - for (j = 0; j < NUM_URBS; ++j) - usb_kill_urb(mos7720_port->write_urb_pool[j]); - - /* Freeing Write URBs */ - for (j = 0; j < NUM_URBS; ++j) { - if (mos7720_port->write_urb_pool[j]) { - kfree(mos7720_port->write_urb_pool[j]->transfer_buffer); - usb_free_urb(mos7720_port->write_urb_pool[j]); - } - } - - /* While closing port, shutdown all bulk read, write * - * and interrupt read if they exists, otherwise nop */ - dbg("Shutdown bulk write"); - usb_kill_urb(port->write_urb); - dbg("Shutdown bulk read"); - usb_kill_urb(port->read_urb); - - mutex_lock(&serial->disc_mutex); - /* these commands must not be issued if the device has - * been disconnected */ - if (!serial->disconnected) { - write_mos_reg(serial, port->number - port->serial->minor, - MCR, 0x00); - write_mos_reg(serial, port->number - port->serial->minor, - IER, 0x00); - } - mutex_unlock(&serial->disc_mutex); - mos7720_port->open = 0; - - dbg("Leaving %s", __func__); -} - -static void mos7720_break(struct tty_struct *tty, int break_state) -{ - struct usb_serial_port *port = tty->driver_data; - unsigned char data; - struct usb_serial *serial; - struct moschip_port *mos7720_port; - - dbg("Entering %s", __func__); - - serial = port->serial; - - mos7720_port = usb_get_serial_port_data(port); - if (mos7720_port == NULL) - return; - - if (break_state == -1) - data = mos7720_port->shadowLCR | UART_LCR_SBC; - else - data = mos7720_port->shadowLCR & ~UART_LCR_SBC; - - mos7720_port->shadowLCR = data; - write_mos_reg(serial, port->number - port->serial->minor, - LCR, mos7720_port->shadowLCR); -} - -/* - * mos7720_write_room - * this function is called by the tty driver when it wants to know how many - * bytes of data we can accept for a specific port. - * If successful, we return the amount of room that we have for this port - * Otherwise we return a negative error number. - */ -static int mos7720_write_room(struct tty_struct *tty) -{ - struct usb_serial_port *port = tty->driver_data; - struct moschip_port *mos7720_port; - int room = 0; - int i; - - dbg("%s:entering ...........", __func__); - - mos7720_port = usb_get_serial_port_data(port); - if (mos7720_port == NULL) { - dbg("%s:leaving ...........", __func__); - return -ENODEV; - } - - /* FIXME: Locking */ - for (i = 0; i < NUM_URBS; ++i) { - if (mos7720_port->write_urb_pool[i] && - mos7720_port->write_urb_pool[i]->status != -EINPROGRESS) - room += URB_TRANSFER_BUFFER_SIZE; - } - - dbg("%s - returns %d", __func__, room); - return room; -} - -static int mos7720_write(struct tty_struct *tty, struct usb_serial_port *port, - const unsigned char *data, int count) -{ - int status; - int i; - int bytes_sent = 0; - int transfer_size; - - struct moschip_port *mos7720_port; - struct usb_serial *serial; - struct urb *urb; - const unsigned char *current_position = data; - - dbg("%s:entering ...........", __func__); - - serial = port->serial; - - mos7720_port = usb_get_serial_port_data(port); - if (mos7720_port == NULL) { - dbg("mos7720_port is NULL"); - return -ENODEV; - } - - /* try to find a free urb in the list */ - urb = NULL; - - for (i = 0; i < NUM_URBS; ++i) { - if (mos7720_port->write_urb_pool[i] && - mos7720_port->write_urb_pool[i]->status != -EINPROGRESS) { - urb = mos7720_port->write_urb_pool[i]; - dbg("URB:%d", i); - break; - } - } - - if (urb == NULL) { - dbg("%s - no more free urbs", __func__); - goto exit; - } - - if (urb->transfer_buffer == NULL) { - urb->transfer_buffer = kmalloc(URB_TRANSFER_BUFFER_SIZE, - GFP_KERNEL); - if (urb->transfer_buffer == NULL) { - dev_err_console(port, "%s no more kernel memory...\n", - __func__); - goto exit; - } - } - transfer_size = min(count, URB_TRANSFER_BUFFER_SIZE); - - memcpy(urb->transfer_buffer, current_position, transfer_size); - usb_serial_debug_data(debug, &port->dev, __func__, transfer_size, - urb->transfer_buffer); - - /* fill urb with data and submit */ - usb_fill_bulk_urb(urb, serial->dev, - usb_sndbulkpipe(serial->dev, - port->bulk_out_endpointAddress), - urb->transfer_buffer, transfer_size, - mos7720_bulk_out_data_callback, mos7720_port); - - /* send it down the pipe */ - status = usb_submit_urb(urb, GFP_ATOMIC); - if (status) { - dev_err_console(port, "%s - usb_submit_urb(write bulk) failed " - "with status = %d\n", __func__, status); - bytes_sent = status; - goto exit; - } - bytes_sent = transfer_size; - -exit: - return bytes_sent; -} - -static void mos7720_throttle(struct tty_struct *tty) -{ - struct usb_serial_port *port = tty->driver_data; - struct moschip_port *mos7720_port; - int status; - - dbg("%s- port %d", __func__, port->number); - - mos7720_port = usb_get_serial_port_data(port); - - if (mos7720_port == NULL) - return; - - if (!mos7720_port->open) { - dbg("port not opened"); - return; - } - - dbg("%s: Entering ..........", __func__); - - /* if we are implementing XON/XOFF, send the stop character */ - if (I_IXOFF(tty)) { - unsigned char stop_char = STOP_CHAR(tty); - status = mos7720_write(tty, port, &stop_char, 1); - if (status <= 0) - return; - } - - /* if we are implementing RTS/CTS, toggle that line */ - if (tty->termios->c_cflag & CRTSCTS) { - mos7720_port->shadowMCR &= ~UART_MCR_RTS; - write_mos_reg(port->serial, port->number - port->serial->minor, - MCR, mos7720_port->shadowMCR); - if (status != 0) - return; - } -} - -static void mos7720_unthrottle(struct tty_struct *tty) -{ - struct usb_serial_port *port = tty->driver_data; - struct moschip_port *mos7720_port = usb_get_serial_port_data(port); - int status; - - if (mos7720_port == NULL) - return; - - if (!mos7720_port->open) { - dbg("%s - port not opened", __func__); - return; - } - - dbg("%s: Entering ..........", __func__); - - /* if we are implementing XON/XOFF, send the start character */ - if (I_IXOFF(tty)) { - unsigned char start_char = START_CHAR(tty); - status = mos7720_write(tty, port, &start_char, 1); - if (status <= 0) - return; - } - - /* if we are implementing RTS/CTS, toggle that line */ - if (tty->termios->c_cflag & CRTSCTS) { - mos7720_port->shadowMCR |= UART_MCR_RTS; - write_mos_reg(port->serial, port->number - port->serial->minor, - MCR, mos7720_port->shadowMCR); - if (status != 0) - return; - } -} - -/* FIXME: this function does not work */ -static int set_higher_rates(struct moschip_port *mos7720_port, - unsigned int baud) -{ - struct usb_serial_port *port; - struct usb_serial *serial; - int port_number; - enum mos_regs sp_reg; - if (mos7720_port == NULL) - return -EINVAL; - - port = mos7720_port->port; - serial = port->serial; - - /*********************************************** - * Init Sequence for higher rates - ***********************************************/ - dbg("Sending Setting Commands .........."); - port_number = port->number - port->serial->minor; - - write_mos_reg(serial, port_number, IER, 0x00); - write_mos_reg(serial, port_number, FCR, 0x00); - write_mos_reg(serial, port_number, FCR, 0xcf); - mos7720_port->shadowMCR = 0x0b; - write_mos_reg(serial, port_number, MCR, mos7720_port->shadowMCR); - write_mos_reg(serial, dummy, SP_CONTROL_REG, 0x00); - - /*********************************************** - * Set for higher rates * - ***********************************************/ - /* writing baud rate verbatum into uart clock field clearly not right */ - if (port_number == 0) - sp_reg = SP1_REG; - else - sp_reg = SP2_REG; - write_mos_reg(serial, dummy, sp_reg, baud * 0x10); - write_mos_reg(serial, dummy, SP_CONTROL_REG, 0x03); - mos7720_port->shadowMCR = 0x2b; - write_mos_reg(serial, port_number, MCR, mos7720_port->shadowMCR); - - /*********************************************** - * Set DLL/DLM - ***********************************************/ - mos7720_port->shadowLCR = mos7720_port->shadowLCR | UART_LCR_DLAB; - write_mos_reg(serial, port_number, LCR, mos7720_port->shadowLCR); - write_mos_reg(serial, port_number, DLL, 0x01); - write_mos_reg(serial, port_number, DLM, 0x00); - mos7720_port->shadowLCR = mos7720_port->shadowLCR & ~UART_LCR_DLAB; - write_mos_reg(serial, port_number, LCR, mos7720_port->shadowLCR); - - return 0; -} - -/* baud rate information */ -struct divisor_table_entry { - __u32 baudrate; - __u16 divisor; -}; - -/* Define table of divisors for moschip 7720 hardware * - * These assume a 3.6864MHz crystal, the standard /16, and * - * MCR.7 = 0. */ -static struct divisor_table_entry divisor_table[] = { - { 50, 2304}, - { 110, 1047}, /* 2094.545455 => 230450 => .0217 % over */ - { 134, 857}, /* 1713.011152 => 230398.5 => .00065% under */ - { 150, 768}, - { 300, 384}, - { 600, 192}, - { 1200, 96}, - { 1800, 64}, - { 2400, 48}, - { 4800, 24}, - { 7200, 16}, - { 9600, 12}, - { 19200, 6}, - { 38400, 3}, - { 57600, 2}, - { 115200, 1}, -}; - -/***************************************************************************** - * calc_baud_rate_divisor - * this function calculates the proper baud rate divisor for the specified - * baud rate. - *****************************************************************************/ -static int calc_baud_rate_divisor(int baudrate, int *divisor) -{ - int i; - __u16 custom; - __u16 round1; - __u16 round; - - - dbg("%s - %d", __func__, baudrate); - - for (i = 0; i < ARRAY_SIZE(divisor_table); i++) { - if (divisor_table[i].baudrate == baudrate) { - *divisor = divisor_table[i].divisor; - return 0; - } - } - - /* After trying for all the standard baud rates * - * Try calculating the divisor for this baud rate */ - if (baudrate > 75 && baudrate < 230400) { - /* get the divisor */ - custom = (__u16)(230400L / baudrate); - - /* Check for round off */ - round1 = (__u16)(2304000L / baudrate); - round = (__u16)(round1 - (custom * 10)); - if (round > 4) - custom++; - *divisor = custom; - - dbg("Baud %d = %d", baudrate, custom); - return 0; - } - - dbg("Baud calculation Failed..."); - return -EINVAL; -} - -/* - * send_cmd_write_baud_rate - * this function sends the proper command to change the baud rate of the - * specified port. - */ -static int send_cmd_write_baud_rate(struct moschip_port *mos7720_port, - int baudrate) -{ - struct usb_serial_port *port; - struct usb_serial *serial; - int divisor; - int status; - unsigned char number; - - if (mos7720_port == NULL) - return -1; - - port = mos7720_port->port; - serial = port->serial; - - dbg("%s: Entering ..........", __func__); - - number = port->number - port->serial->minor; - dbg("%s - port = %d, baud = %d", __func__, port->number, baudrate); - - /* Calculate the Divisor */ - status = calc_baud_rate_divisor(baudrate, &divisor); - if (status) { - dev_err(&port->dev, "%s - bad baud rate\n", __func__); - return status; - } - - /* Enable access to divisor latch */ - mos7720_port->shadowLCR = mos7720_port->shadowLCR | UART_LCR_DLAB; - write_mos_reg(serial, number, LCR, mos7720_port->shadowLCR); - - /* Write the divisor */ - write_mos_reg(serial, number, DLL, (__u8)(divisor & 0xff)); - write_mos_reg(serial, number, DLM, (__u8)((divisor & 0xff00) >> 8)); - - /* Disable access to divisor latch */ - mos7720_port->shadowLCR = mos7720_port->shadowLCR & ~UART_LCR_DLAB; - write_mos_reg(serial, number, LCR, mos7720_port->shadowLCR); - - return status; -} - -/* - * change_port_settings - * This routine is called to set the UART on the device to match - * the specified new settings. - */ -static void change_port_settings(struct tty_struct *tty, - struct moschip_port *mos7720_port, - struct ktermios *old_termios) -{ - struct usb_serial_port *port; - struct usb_serial *serial; - int baud; - unsigned cflag; - unsigned iflag; - __u8 mask = 0xff; - __u8 lData; - __u8 lParity; - __u8 lStop; - int status; - int port_number; - - if (mos7720_port == NULL) - return ; - - port = mos7720_port->port; - serial = port->serial; - port_number = port->number - port->serial->minor; - - dbg("%s - port %d", __func__, port->number); - - if (!mos7720_port->open) { - dbg("%s - port not opened", __func__); - return; - } - - dbg("%s: Entering ..........", __func__); - - lData = UART_LCR_WLEN8; - lStop = 0x00; /* 1 stop bit */ - lParity = 0x00; /* No parity */ - - cflag = tty->termios->c_cflag; - iflag = tty->termios->c_iflag; - - /* Change the number of bits */ - switch (cflag & CSIZE) { - case CS5: - lData = UART_LCR_WLEN5; - mask = 0x1f; - break; - - case CS6: - lData = UART_LCR_WLEN6; - mask = 0x3f; - break; - - case CS7: - lData = UART_LCR_WLEN7; - mask = 0x7f; - break; - default: - case CS8: - lData = UART_LCR_WLEN8; - break; - } - - /* Change the Parity bit */ - if (cflag & PARENB) { - if (cflag & PARODD) { - lParity = UART_LCR_PARITY; - dbg("%s - parity = odd", __func__); - } else { - lParity = (UART_LCR_EPAR | UART_LCR_PARITY); - dbg("%s - parity = even", __func__); - } - - } else { - dbg("%s - parity = none", __func__); - } - - if (cflag & CMSPAR) - lParity = lParity | 0x20; - - /* Change the Stop bit */ - if (cflag & CSTOPB) { - lStop = UART_LCR_STOP; - dbg("%s - stop bits = 2", __func__); - } else { - lStop = 0x00; - dbg("%s - stop bits = 1", __func__); - } - -#define LCR_BITS_MASK 0x03 /* Mask for bits/char field */ -#define LCR_STOP_MASK 0x04 /* Mask for stop bits field */ -#define LCR_PAR_MASK 0x38 /* Mask for parity field */ - - /* Update the LCR with the correct value */ - mos7720_port->shadowLCR &= - ~(LCR_BITS_MASK | LCR_STOP_MASK | LCR_PAR_MASK); - mos7720_port->shadowLCR |= (lData | lParity | lStop); - - - /* Disable Interrupts */ - write_mos_reg(serial, port_number, IER, 0x00); - write_mos_reg(serial, port_number, FCR, 0x00); - write_mos_reg(serial, port_number, FCR, 0xcf); - - /* Send the updated LCR value to the mos7720 */ - write_mos_reg(serial, port_number, LCR, mos7720_port->shadowLCR); - mos7720_port->shadowMCR = 0x0b; - write_mos_reg(serial, port_number, MCR, mos7720_port->shadowMCR); - - /* set up the MCR register and send it to the mos7720 */ - mos7720_port->shadowMCR = UART_MCR_OUT2; - if (cflag & CBAUD) - mos7720_port->shadowMCR |= (UART_MCR_DTR | UART_MCR_RTS); - - if (cflag & CRTSCTS) { - mos7720_port->shadowMCR |= (UART_MCR_XONANY); - /* To set hardware flow control to the specified * - * serial port, in SP1/2_CONTROL_REG */ - if (port->number) - write_mos_reg(serial, dummy, SP_CONTROL_REG, 0x01); - else - write_mos_reg(serial, dummy, SP_CONTROL_REG, 0x02); - - } else - mos7720_port->shadowMCR &= ~(UART_MCR_XONANY); - - write_mos_reg(serial, port_number, MCR, mos7720_port->shadowMCR); - - /* Determine divisor based on baud rate */ - baud = tty_get_baud_rate(tty); - if (!baud) { - /* pick a default, any default... */ - dbg("Picked default baud..."); - baud = 9600; - } - - if (baud >= 230400) { - set_higher_rates(mos7720_port, baud); - /* Enable Interrupts */ - write_mos_reg(serial, port_number, IER, 0x0c); - return; - } - - dbg("%s - baud rate = %d", __func__, baud); - status = send_cmd_write_baud_rate(mos7720_port, baud); - /* FIXME: needs to write actual resulting baud back not just - blindly do so */ - if (cflag & CBAUD) - tty_encode_baud_rate(tty, baud, baud); - /* Enable Interrupts */ - write_mos_reg(serial, port_number, IER, 0x0c); - - if (port->read_urb->status != -EINPROGRESS) { - status = usb_submit_urb(port->read_urb, GFP_ATOMIC); - if (status) - dbg("usb_submit_urb(read bulk) failed, status = %d", - status); - } -} - -/* - * mos7720_set_termios - * this function is called by the tty driver when it wants to change the - * termios structure. - */ -static void mos7720_set_termios(struct tty_struct *tty, - struct usb_serial_port *port, struct ktermios *old_termios) -{ - int status; - unsigned int cflag; - struct usb_serial *serial; - struct moschip_port *mos7720_port; - - serial = port->serial; - - mos7720_port = usb_get_serial_port_data(port); - - if (mos7720_port == NULL) - return; - - if (!mos7720_port->open) { - dbg("%s - port not opened", __func__); - return; - } - - dbg("%s\n", "setting termios - ASPIRE"); - - cflag = tty->termios->c_cflag; - - dbg("%s - cflag %08x iflag %08x", __func__, - tty->termios->c_cflag, - RELEVANT_IFLAG(tty->termios->c_iflag)); - - dbg("%s - old cflag %08x old iflag %08x", __func__, - old_termios->c_cflag, - RELEVANT_IFLAG(old_termios->c_iflag)); - - dbg("%s - port %d", __func__, port->number); - - /* change the port settings to the new ones specified */ - change_port_settings(tty, mos7720_port, old_termios); - - if (port->read_urb->status != -EINPROGRESS) { - status = usb_submit_urb(port->read_urb, GFP_ATOMIC); - if (status) - dbg("usb_submit_urb(read bulk) failed, status = %d", - status); - } -} - -/* - * get_lsr_info - get line status register info - * - * Purpose: Let user call ioctl() to get info when the UART physically - * is emptied. On bus types like RS485, the transmitter must - * release the bus after transmitting. This must be done when - * the transmit shift register is empty, not be done when the - * transmit holding register is empty. This functionality - * allows an RS485 driver to be written in user space. - */ -static int get_lsr_info(struct tty_struct *tty, - struct moschip_port *mos7720_port, unsigned int __user *value) -{ - struct usb_serial_port *port = tty->driver_data; - unsigned int result = 0; - unsigned char data = 0; - int port_number = port->number - port->serial->minor; - int count; - - count = mos7720_chars_in_buffer(tty); - if (count == 0) { - read_mos_reg(port->serial, port_number, LSR, &data); - if ((data & (UART_LSR_TEMT | UART_LSR_THRE)) - == (UART_LSR_TEMT | UART_LSR_THRE)) { - dbg("%s -- Empty", __func__); - result = TIOCSER_TEMT; - } - } - if (copy_to_user(value, &result, sizeof(int))) - return -EFAULT; - return 0; -} - -static int mos7720_tiocmget(struct tty_struct *tty) -{ - struct usb_serial_port *port = tty->driver_data; - struct moschip_port *mos7720_port = usb_get_serial_port_data(port); - unsigned int result = 0; - unsigned int mcr ; - unsigned int msr ; - - dbg("%s - port %d", __func__, port->number); - - mcr = mos7720_port->shadowMCR; - msr = mos7720_port->shadowMSR; - - result = ((mcr & UART_MCR_DTR) ? TIOCM_DTR : 0) /* 0x002 */ - | ((mcr & UART_MCR_RTS) ? TIOCM_RTS : 0) /* 0x004 */ - | ((msr & UART_MSR_CTS) ? TIOCM_CTS : 0) /* 0x020 */ - | ((msr & UART_MSR_DCD) ? TIOCM_CAR : 0) /* 0x040 */ - | ((msr & UART_MSR_RI) ? TIOCM_RI : 0) /* 0x080 */ - | ((msr & UART_MSR_DSR) ? TIOCM_DSR : 0); /* 0x100 */ - - dbg("%s -- %x", __func__, result); - - return result; -} - -static int mos7720_tiocmset(struct tty_struct *tty, - unsigned int set, unsigned int clear) -{ - struct usb_serial_port *port = tty->driver_data; - struct moschip_port *mos7720_port = usb_get_serial_port_data(port); - unsigned int mcr ; - dbg("%s - port %d", __func__, port->number); - dbg("he was at tiocmset"); - - mcr = mos7720_port->shadowMCR; - - if (set & TIOCM_RTS) - mcr |= UART_MCR_RTS; - if (set & TIOCM_DTR) - mcr |= UART_MCR_DTR; - if (set & TIOCM_LOOP) - mcr |= UART_MCR_LOOP; - - if (clear & TIOCM_RTS) - mcr &= ~UART_MCR_RTS; - if (clear & TIOCM_DTR) - mcr &= ~UART_MCR_DTR; - if (clear & TIOCM_LOOP) - mcr &= ~UART_MCR_LOOP; - - mos7720_port->shadowMCR = mcr; - write_mos_reg(port->serial, port->number - port->serial->minor, - MCR, mos7720_port->shadowMCR); - - return 0; -} - -static int mos7720_get_icount(struct tty_struct *tty, - struct serial_icounter_struct *icount) -{ - struct usb_serial_port *port = tty->driver_data; - struct moschip_port *mos7720_port; - struct async_icount cnow; - - mos7720_port = usb_get_serial_port_data(port); - cnow = mos7720_port->icount; - - icount->cts = cnow.cts; - icount->dsr = cnow.dsr; - icount->rng = cnow.rng; - icount->dcd = cnow.dcd; - icount->rx = cnow.rx; - icount->tx = cnow.tx; - icount->frame = cnow.frame; - icount->overrun = cnow.overrun; - icount->parity = cnow.parity; - icount->brk = cnow.brk; - icount->buf_overrun = cnow.buf_overrun; - - dbg("%s (%d) TIOCGICOUNT RX=%d, TX=%d", __func__, - port->number, icount->rx, icount->tx); - return 0; -} - -static int set_modem_info(struct moschip_port *mos7720_port, unsigned int cmd, - unsigned int __user *value) -{ - unsigned int mcr; - unsigned int arg; - - struct usb_serial_port *port; - - if (mos7720_port == NULL) - return -1; - - port = (struct usb_serial_port *)mos7720_port->port; - mcr = mos7720_port->shadowMCR; - - if (copy_from_user(&arg, value, sizeof(int))) - return -EFAULT; - - switch (cmd) { - case TIOCMBIS: - if (arg & TIOCM_RTS) - mcr |= UART_MCR_RTS; - if (arg & TIOCM_DTR) - mcr |= UART_MCR_RTS; - if (arg & TIOCM_LOOP) - mcr |= UART_MCR_LOOP; - break; - - case TIOCMBIC: - if (arg & TIOCM_RTS) - mcr &= ~UART_MCR_RTS; - if (arg & TIOCM_DTR) - mcr &= ~UART_MCR_RTS; - if (arg & TIOCM_LOOP) - mcr &= ~UART_MCR_LOOP; - break; - - } - - mos7720_port->shadowMCR = mcr; - write_mos_reg(port->serial, port->number - port->serial->minor, - MCR, mos7720_port->shadowMCR); - - return 0; -} - -static int get_serial_info(struct moschip_port *mos7720_port, - struct serial_struct __user *retinfo) -{ - struct serial_struct tmp; - - if (!retinfo) - return -EFAULT; - - memset(&tmp, 0, sizeof(tmp)); - - tmp.type = PORT_16550A; - tmp.line = mos7720_port->port->serial->minor; - tmp.port = mos7720_port->port->number; - tmp.irq = 0; - tmp.flags = ASYNC_SKIP_TEST | ASYNC_AUTO_IRQ; - tmp.xmit_fifo_size = NUM_URBS * URB_TRANSFER_BUFFER_SIZE; - tmp.baud_base = 9600; - tmp.close_delay = 5*HZ; - tmp.closing_wait = 30*HZ; - - if (copy_to_user(retinfo, &tmp, sizeof(*retinfo))) - return -EFAULT; - return 0; -} - -static int mos7720_ioctl(struct tty_struct *tty, - unsigned int cmd, unsigned long arg) -{ - struct usb_serial_port *port = tty->driver_data; - struct moschip_port *mos7720_port; - struct async_icount cnow; - struct async_icount cprev; - - mos7720_port = usb_get_serial_port_data(port); - if (mos7720_port == NULL) - return -ENODEV; - - dbg("%s - port %d, cmd = 0x%x", __func__, port->number, cmd); - - switch (cmd) { - case TIOCSERGETLSR: - dbg("%s (%d) TIOCSERGETLSR", __func__, port->number); - return get_lsr_info(tty, mos7720_port, - (unsigned int __user *)arg); - - /* FIXME: These should be using the mode methods */ - case TIOCMBIS: - case TIOCMBIC: - dbg("%s (%d) TIOCMSET/TIOCMBIC/TIOCMSET", - __func__, port->number); - return set_modem_info(mos7720_port, cmd, - (unsigned int __user *)arg); - - case TIOCGSERIAL: - dbg("%s (%d) TIOCGSERIAL", __func__, port->number); - return get_serial_info(mos7720_port, - (struct serial_struct __user *)arg); - - case TIOCMIWAIT: - dbg("%s (%d) TIOCMIWAIT", __func__, port->number); - cprev = mos7720_port->icount; - while (1) { - if (signal_pending(current)) - return -ERESTARTSYS; - cnow = mos7720_port->icount; - if (cnow.rng == cprev.rng && cnow.dsr == cprev.dsr && - cnow.dcd == cprev.dcd && cnow.cts == cprev.cts) - return -EIO; /* no change => error */ - if (((arg & TIOCM_RNG) && (cnow.rng != cprev.rng)) || - ((arg & TIOCM_DSR) && (cnow.dsr != cprev.dsr)) || - ((arg & TIOCM_CD) && (cnow.dcd != cprev.dcd)) || - ((arg & TIOCM_CTS) && (cnow.cts != cprev.cts))) { - return 0; - } - cprev = cnow; - } - /* NOTREACHED */ - break; - } - - return -ENOIOCTLCMD; -} - -static int mos7720_startup(struct usb_serial *serial) -{ - struct moschip_port *mos7720_port; - struct usb_device *dev; - int i; - char data; - u16 product; - int ret_val; - - dbg("%s: Entering ..........", __func__); - - if (!serial) { - dbg("Invalid Handler"); - return -ENODEV; - } - - product = le16_to_cpu(serial->dev->descriptor.idProduct); - dev = serial->dev; - - /* - * The 7715 uses the first bulk in/out endpoint pair for the parallel - * port, and the second for the serial port. Because the usbserial core - * assumes both pairs are serial ports, we must engage in a bit of - * subterfuge and swap the pointers for ports 0 and 1 in order to make - * port 0 point to the serial port. However, both moschip devices use a - * single interrupt-in endpoint for both ports (as mentioned a little - * further down), and this endpoint was assigned to port 0. So after - * the swap, we must copy the interrupt endpoint elements from port 1 - * (as newly assigned) to port 0, and null out port 1 pointers. - */ - if (product == MOSCHIP_DEVICE_ID_7715) { - struct usb_serial_port *tmp = serial->port[0]; - serial->port[0] = serial->port[1]; - serial->port[1] = tmp; - serial->port[0]->interrupt_in_urb = tmp->interrupt_in_urb; - serial->port[0]->interrupt_in_buffer = tmp->interrupt_in_buffer; - serial->port[0]->interrupt_in_endpointAddress = - tmp->interrupt_in_endpointAddress; - serial->port[1]->interrupt_in_urb = NULL; - serial->port[1]->interrupt_in_buffer = NULL; - } - - - /* set up serial port private structures */ - for (i = 0; i < serial->num_ports; ++i) { - mos7720_port = kzalloc(sizeof(struct moschip_port), GFP_KERNEL); - if (mos7720_port == NULL) { - dev_err(&dev->dev, "%s - Out of memory\n", __func__); - return -ENOMEM; - } - - /* Initialize all port interrupt end point to port 0 int - * endpoint. Our device has only one interrupt endpoint - * common to all ports */ - serial->port[i]->interrupt_in_endpointAddress = - serial->port[0]->interrupt_in_endpointAddress; - - mos7720_port->port = serial->port[i]; - usb_set_serial_port_data(serial->port[i], mos7720_port); - - dbg("port number is %d", serial->port[i]->number); - dbg("serial number is %d", serial->minor); - } - - - /* setting configuration feature to one */ - usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0), - (__u8)0x03, 0x00, 0x01, 0x00, NULL, 0x00, 5*HZ); - - /* start the interrupt urb */ - ret_val = usb_submit_urb(serial->port[0]->interrupt_in_urb, GFP_KERNEL); - if (ret_val) - dev_err(&dev->dev, - "%s - Error %d submitting control urb\n", - __func__, ret_val); - -#ifdef CONFIG_USB_SERIAL_MOS7715_PARPORT - if (product == MOSCHIP_DEVICE_ID_7715) { - ret_val = mos7715_parport_init(serial); - if (ret_val < 0) - return ret_val; - } -#endif - /* LSR For Port 1 */ - read_mos_reg(serial, 0, LSR, &data); - dbg("LSR:%x", data); - - return 0; -} - -static void mos7720_release(struct usb_serial *serial) -{ - int i; - -#ifdef CONFIG_USB_SERIAL_MOS7715_PARPORT - /* close the parallel port */ - - if (le16_to_cpu(serial->dev->descriptor.idProduct) - == MOSCHIP_DEVICE_ID_7715) { - struct urbtracker *urbtrack; - unsigned long flags; - struct mos7715_parport *mos_parport = - usb_get_serial_data(serial); - - /* prevent NULL ptr dereference in port callbacks */ - spin_lock(&release_lock); - mos_parport->pp->private_data = NULL; - spin_unlock(&release_lock); - - /* wait for synchronous usb calls to return */ - if (mos_parport->msg_pending) - wait_for_completion_timeout(&mos_parport->syncmsg_compl, - MOS_WDR_TIMEOUT); - - parport_remove_port(mos_parport->pp); - usb_set_serial_data(serial, NULL); - mos_parport->serial = NULL; - - /* if tasklet currently scheduled, wait for it to complete */ - tasklet_kill(&mos_parport->urb_tasklet); - - /* unlink any urbs sent by the tasklet */ - spin_lock_irqsave(&mos_parport->listlock, flags); - list_for_each_entry(urbtrack, - &mos_parport->active_urbs, - urblist_entry) - usb_unlink_urb(urbtrack->urb); - spin_unlock_irqrestore(&mos_parport->listlock, flags); - - kref_put(&mos_parport->ref_count, destroy_mos_parport); - } -#endif - /* free private structure allocated for serial port */ - for (i = 0; i < serial->num_ports; ++i) - kfree(usb_get_serial_port_data(serial->port[i])); -} - -static struct usb_driver usb_driver = { - .name = "moschip7720", - .probe = usb_serial_probe, - .disconnect = usb_serial_disconnect, - .id_table = moschip_port_id_table, -}; - -static struct usb_serial_driver moschip7720_2port_driver = { - .driver = { - .owner = THIS_MODULE, - .name = "moschip7720", - }, - .description = "Moschip 2 port adapter", - .id_table = moschip_port_id_table, - .calc_num_ports = mos77xx_calc_num_ports, - .open = mos7720_open, - .close = mos7720_close, - .throttle = mos7720_throttle, - .unthrottle = mos7720_unthrottle, - .probe = mos77xx_probe, - .attach = mos7720_startup, - .release = mos7720_release, - .ioctl = mos7720_ioctl, - .tiocmget = mos7720_tiocmget, - .tiocmset = mos7720_tiocmset, - .get_icount = mos7720_get_icount, - .set_termios = mos7720_set_termios, - .write = mos7720_write, - .write_room = mos7720_write_room, - .chars_in_buffer = mos7720_chars_in_buffer, - .break_ctl = mos7720_break, - .read_bulk_callback = mos7720_bulk_in_callback, - .read_int_callback = NULL /* dynamically assigned in probe() */ -}; - -static struct usb_serial_driver * const serial_drivers[] = { - &moschip7720_2port_driver, NULL -}; - -module_usb_serial_driver(usb_driver, serial_drivers); - -MODULE_AUTHOR(DRIVER_AUTHOR); -MODULE_DESCRIPTION(DRIVER_DESC); -MODULE_LICENSE("GPL"); - -module_param(debug, bool, S_IRUGO | S_IWUSR); -MODULE_PARM_DESC(debug, "Debug enabled or not"); diff --git a/ANDROID_3.4.5/drivers/usb/serial/mos7840.c b/ANDROID_3.4.5/drivers/usb/serial/mos7840.c deleted file mode 100644 index 62739ff5..00000000 --- a/ANDROID_3.4.5/drivers/usb/serial/mos7840.c +++ /dev/null @@ -1,2716 +0,0 @@ -/* - * 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. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * Clean ups from Moschip version and a few ioctl implementations by: - * Paul B Schroeder <pschroeder "at" uplogix "dot" com> - * - * Originally based on drivers/usb/serial/io_edgeport.c which is: - * Copyright (C) 2000 Inside Out Networks, All rights reserved. - * Copyright (C) 2001-2002 Greg Kroah-Hartman <greg@kroah.com> - * - */ - -#include <linux/kernel.h> -#include <linux/errno.h> -#include <linux/init.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/serial.h> -#include <linux/usb.h> -#include <linux/usb/serial.h> -#include <linux/uaccess.h> - -/* - * Version Information - */ -#define DRIVER_VERSION "1.3.2" -#define DRIVER_DESC "Moschip 7840/7820 USB Serial Driver" - -/* - * 16C50 UART register defines - */ - -#define LCR_BITS_5 0x00 /* 5 bits/char */ -#define LCR_BITS_6 0x01 /* 6 bits/char */ -#define LCR_BITS_7 0x02 /* 7 bits/char */ -#define LCR_BITS_8 0x03 /* 8 bits/char */ -#define LCR_BITS_MASK 0x03 /* Mask for bits/char field */ - -#define LCR_STOP_1 0x00 /* 1 stop bit */ -#define LCR_STOP_1_5 0x04 /* 1.5 stop bits (if 5 bits/char) */ -#define LCR_STOP_2 0x04 /* 2 stop bits (if 6-8 bits/char) */ -#define LCR_STOP_MASK 0x04 /* Mask for stop bits field */ - -#define LCR_PAR_NONE 0x00 /* No parity */ -#define LCR_PAR_ODD 0x08 /* Odd parity */ -#define LCR_PAR_EVEN 0x18 /* Even parity */ -#define LCR_PAR_MARK 0x28 /* Force parity bit to 1 */ -#define LCR_PAR_SPACE 0x38 /* Force parity bit to 0 */ -#define LCR_PAR_MASK 0x38 /* Mask for parity field */ - -#define LCR_SET_BREAK 0x40 /* Set Break condition */ -#define LCR_DL_ENABLE 0x80 /* Enable access to divisor latch */ - -#define MCR_DTR 0x01 /* Assert DTR */ -#define MCR_RTS 0x02 /* Assert RTS */ -#define MCR_OUT1 0x04 /* Loopback only: Sets state of RI */ -#define MCR_MASTER_IE 0x08 /* Enable interrupt outputs */ -#define MCR_LOOPBACK 0x10 /* Set internal (digital) loopback mode */ -#define MCR_XON_ANY 0x20 /* Enable any char to exit XOFF mode */ - -#define MOS7840_MSR_CTS 0x10 /* Current state of CTS */ -#define MOS7840_MSR_DSR 0x20 /* Current state of DSR */ -#define MOS7840_MSR_RI 0x40 /* Current state of RI */ -#define MOS7840_MSR_CD 0x80 /* Current state of CD */ - -/* - * Defines used for sending commands to port - */ - -#define WAIT_FOR_EVER (HZ * 0) /* timeout urb is wait for ever */ -#define MOS_WDR_TIMEOUT (HZ * 5) /* default urb timeout */ - -#define MOS_PORT1 0x0200 -#define MOS_PORT2 0x0300 -#define MOS_VENREG 0x0000 -#define MOS_MAX_PORT 0x02 -#define MOS_WRITE 0x0E -#define MOS_READ 0x0D - -/* Requests */ -#define MCS_RD_RTYPE 0xC0 -#define MCS_WR_RTYPE 0x40 -#define MCS_RDREQ 0x0D -#define MCS_WRREQ 0x0E -#define MCS_CTRL_TIMEOUT 500 -#define VENDOR_READ_LENGTH (0x01) - -#define MAX_NAME_LEN 64 - -#define ZLP_REG1 0x3A /* Zero_Flag_Reg1 58 */ -#define ZLP_REG5 0x3E /* Zero_Flag_Reg5 62 */ - -/* For higher baud Rates use TIOCEXBAUD */ -#define TIOCEXBAUD 0x5462 - -/* vendor id and device id defines */ - -/* The native mos7840/7820 component */ -#define USB_VENDOR_ID_MOSCHIP 0x9710 -#define MOSCHIP_DEVICE_ID_7840 0x7840 -#define MOSCHIP_DEVICE_ID_7820 0x7820 -/* The native component can have its vendor/device id's overridden - * in vendor-specific implementations. Such devices can be handled - * by making a change here, in moschip_port_id_table, and in - * moschip_id_table_combined - */ -#define USB_VENDOR_ID_BANDB 0x0856 -#define BANDB_DEVICE_ID_USO9ML2_2 0xAC22 -#define BANDB_DEVICE_ID_USO9ML2_2P 0xBC00 -#define BANDB_DEVICE_ID_USO9ML2_4 0xAC24 -#define BANDB_DEVICE_ID_USO9ML2_4P 0xBC01 -#define BANDB_DEVICE_ID_US9ML2_2 0xAC29 -#define BANDB_DEVICE_ID_US9ML2_4 0xAC30 -#define BANDB_DEVICE_ID_USPTL4_2 0xAC31 -#define BANDB_DEVICE_ID_USPTL4_4 0xAC32 -#define BANDB_DEVICE_ID_USOPTL4_2 0xAC42 -#define BANDB_DEVICE_ID_USOPTL4_2P 0xBC02 -#define BANDB_DEVICE_ID_USOPTL4_4 0xAC44 -#define BANDB_DEVICE_ID_USOPTL4_4P 0xBC03 -#define BANDB_DEVICE_ID_USOPTL2_4 0xAC24 - -/* This driver also supports - * ATEN UC2324 device using Moschip MCS7840 - * ATEN UC2322 device using Moschip MCS7820 - */ -#define USB_VENDOR_ID_ATENINTL 0x0557 -#define ATENINTL_DEVICE_ID_UC2324 0x2011 -#define ATENINTL_DEVICE_ID_UC2322 0x7820 - -/* Interrupt Routine Defines */ - -#define SERIAL_IIR_RLS 0x06 -#define SERIAL_IIR_MS 0x00 - -/* - * Emulation of the bit mask on the LINE STATUS REGISTER. - */ -#define SERIAL_LSR_DR 0x0001 -#define SERIAL_LSR_OE 0x0002 -#define SERIAL_LSR_PE 0x0004 -#define SERIAL_LSR_FE 0x0008 -#define SERIAL_LSR_BI 0x0010 - -#define MOS_MSR_DELTA_CTS 0x10 -#define MOS_MSR_DELTA_DSR 0x20 -#define MOS_MSR_DELTA_RI 0x40 -#define MOS_MSR_DELTA_CD 0x80 - -/* Serial Port register Address */ -#define INTERRUPT_ENABLE_REGISTER ((__u16)(0x01)) -#define FIFO_CONTROL_REGISTER ((__u16)(0x02)) -#define LINE_CONTROL_REGISTER ((__u16)(0x03)) -#define MODEM_CONTROL_REGISTER ((__u16)(0x04)) -#define LINE_STATUS_REGISTER ((__u16)(0x05)) -#define MODEM_STATUS_REGISTER ((__u16)(0x06)) -#define SCRATCH_PAD_REGISTER ((__u16)(0x07)) -#define DIVISOR_LATCH_LSB ((__u16)(0x00)) -#define DIVISOR_LATCH_MSB ((__u16)(0x01)) - -#define CLK_MULTI_REGISTER ((__u16)(0x02)) -#define CLK_START_VALUE_REGISTER ((__u16)(0x03)) -#define GPIO_REGISTER ((__u16)(0x07)) - -#define SERIAL_LCR_DLAB ((__u16)(0x0080)) - -/* - * URB POOL related defines - */ -#define NUM_URBS 16 /* URB Count */ -#define URB_TRANSFER_BUFFER_SIZE 32 /* URB Size */ - - -static const struct usb_device_id moschip_port_id_table[] = { - {USB_DEVICE(USB_VENDOR_ID_MOSCHIP, MOSCHIP_DEVICE_ID_7840)}, - {USB_DEVICE(USB_VENDOR_ID_MOSCHIP, MOSCHIP_DEVICE_ID_7820)}, - {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USO9ML2_2)}, - {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USO9ML2_2P)}, - {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USO9ML2_4)}, - {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USO9ML2_4P)}, - {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_US9ML2_2)}, - {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_US9ML2_4)}, - {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USPTL4_2)}, - {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USPTL4_4)}, - {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USOPTL4_2)}, - {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USOPTL4_2P)}, - {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USOPTL4_4)}, - {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USOPTL4_4P)}, - {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USOPTL2_4)}, - {USB_DEVICE(USB_VENDOR_ID_ATENINTL, ATENINTL_DEVICE_ID_UC2324)}, - {USB_DEVICE(USB_VENDOR_ID_ATENINTL, ATENINTL_DEVICE_ID_UC2322)}, - {} /* terminating entry */ -}; - -static const struct usb_device_id moschip_id_table_combined[] = { - {USB_DEVICE(USB_VENDOR_ID_MOSCHIP, MOSCHIP_DEVICE_ID_7840)}, - {USB_DEVICE(USB_VENDOR_ID_MOSCHIP, MOSCHIP_DEVICE_ID_7820)}, - {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USO9ML2_2)}, - {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USO9ML2_2P)}, - {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USO9ML2_4)}, - {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USO9ML2_4P)}, - {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_US9ML2_2)}, - {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_US9ML2_4)}, - {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USPTL4_2)}, - {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USPTL4_4)}, - {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USOPTL4_2)}, - {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USOPTL4_2P)}, - {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USOPTL4_4)}, - {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USOPTL4_4P)}, - {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USOPTL2_4)}, - {USB_DEVICE(USB_VENDOR_ID_ATENINTL, ATENINTL_DEVICE_ID_UC2324)}, - {USB_DEVICE(USB_VENDOR_ID_ATENINTL, ATENINTL_DEVICE_ID_UC2322)}, - {} /* terminating entry */ -}; - -MODULE_DEVICE_TABLE(usb, moschip_id_table_combined); - -/* This structure holds all of the local port information */ - -struct moschip_port { - int port_num; /*Actual port number in the device(1,2,etc) */ - struct urb *write_urb; /* write URB for this port */ - struct urb *read_urb; /* read URB for this port */ - struct urb *int_urb; - __u8 shadowLCR; /* last LCR value received */ - __u8 shadowMCR; /* last MCR value received */ - char open; - char open_ports; - char zombie; - wait_queue_head_t wait_chase; /* for handling sleeping while waiting for chase to finish */ - wait_queue_head_t delta_msr_wait; /* for handling sleeping while waiting for msr change to happen */ - int delta_msr_cond; - struct async_icount icount; - struct usb_serial_port *port; /* loop back to the owner of this object */ - - /* Offsets */ - __u8 SpRegOffset; - __u8 ControlRegOffset; - __u8 DcrRegOffset; - /* for processing control URBS in interrupt context */ - struct urb *control_urb; - struct usb_ctrlrequest *dr; - char *ctrl_buf; - int MsrLsr; - - spinlock_t pool_lock; - struct urb *write_urb_pool[NUM_URBS]; - char busy[NUM_URBS]; - bool read_urb_busy; -}; - - -static bool debug; - -/* - * mos7840_set_reg_sync - * To set the Control register by calling usb_fill_control_urb function - * by passing usb_sndctrlpipe function as parameter. - */ - -static int mos7840_set_reg_sync(struct usb_serial_port *port, __u16 reg, - __u16 val) -{ - struct usb_device *dev = port->serial->dev; - val = val & 0x00ff; - dbg("mos7840_set_reg_sync offset is %x, value %x", reg, val); - - return usb_control_msg(dev, usb_sndctrlpipe(dev, 0), MCS_WRREQ, - MCS_WR_RTYPE, val, reg, NULL, 0, - MOS_WDR_TIMEOUT); -} - -/* - * mos7840_get_reg_sync - * To set the Uart register by calling usb_fill_control_urb function by - * passing usb_rcvctrlpipe function as parameter. - */ - -static int mos7840_get_reg_sync(struct usb_serial_port *port, __u16 reg, - __u16 *val) -{ - struct usb_device *dev = port->serial->dev; - int ret = 0; - u8 *buf; - - buf = kmalloc(VENDOR_READ_LENGTH, GFP_KERNEL); - if (!buf) - return -ENOMEM; - - ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), MCS_RDREQ, - MCS_RD_RTYPE, 0, reg, buf, VENDOR_READ_LENGTH, - MOS_WDR_TIMEOUT); - *val = buf[0]; - dbg("mos7840_get_reg_sync offset is %x, return val %x", reg, *val); - - kfree(buf); - return ret; -} - -/* - * mos7840_set_uart_reg - * To set the Uart register by calling usb_fill_control_urb function by - * passing usb_sndctrlpipe function as parameter. - */ - -static int mos7840_set_uart_reg(struct usb_serial_port *port, __u16 reg, - __u16 val) -{ - - struct usb_device *dev = port->serial->dev; - val = val & 0x00ff; - /* For the UART control registers, the application number need - to be Or'ed */ - if (port->serial->num_ports == 4) { - val |= (((__u16) port->number - - (__u16) (port->serial->minor)) + 1) << 8; - dbg("mos7840_set_uart_reg application number is %x", val); - } else { - if (((__u16) port->number - (__u16) (port->serial->minor)) == 0) { - val |= (((__u16) port->number - - (__u16) (port->serial->minor)) + 1) << 8; - dbg("mos7840_set_uart_reg application number is %x", - val); - } else { - val |= - (((__u16) port->number - - (__u16) (port->serial->minor)) + 2) << 8; - dbg("mos7840_set_uart_reg application number is %x", - val); - } - } - return usb_control_msg(dev, usb_sndctrlpipe(dev, 0), MCS_WRREQ, - MCS_WR_RTYPE, val, reg, NULL, 0, - MOS_WDR_TIMEOUT); - -} - -/* - * mos7840_get_uart_reg - * To set the Control register by calling usb_fill_control_urb function - * by passing usb_rcvctrlpipe function as parameter. - */ -static int mos7840_get_uart_reg(struct usb_serial_port *port, __u16 reg, - __u16 *val) -{ - struct usb_device *dev = port->serial->dev; - int ret = 0; - __u16 Wval; - u8 *buf; - - buf = kmalloc(VENDOR_READ_LENGTH, GFP_KERNEL); - if (!buf) - return -ENOMEM; - - /* dbg("application number is %4x", - (((__u16)port->number - (__u16)(port->serial->minor))+1)<<8); */ - /* Wval is same as application number */ - if (port->serial->num_ports == 4) { - Wval = - (((__u16) port->number - (__u16) (port->serial->minor)) + - 1) << 8; - dbg("mos7840_get_uart_reg application number is %x", Wval); - } else { - if (((__u16) port->number - (__u16) (port->serial->minor)) == 0) { - Wval = (((__u16) port->number - - (__u16) (port->serial->minor)) + 1) << 8; - dbg("mos7840_get_uart_reg application number is %x", - Wval); - } else { - Wval = (((__u16) port->number - - (__u16) (port->serial->minor)) + 2) << 8; - dbg("mos7840_get_uart_reg application number is %x", - Wval); - } - } - ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), MCS_RDREQ, - MCS_RD_RTYPE, Wval, reg, buf, VENDOR_READ_LENGTH, - MOS_WDR_TIMEOUT); - *val = buf[0]; - - kfree(buf); - return ret; -} - -static void mos7840_dump_serial_port(struct moschip_port *mos7840_port) -{ - - dbg("***************************************"); - dbg("SpRegOffset is %2x", mos7840_port->SpRegOffset); - dbg("ControlRegOffset is %2x", mos7840_port->ControlRegOffset); - dbg("DCRRegOffset is %2x", mos7840_port->DcrRegOffset); - dbg("***************************************"); - -} - -/************************************************************************/ -/************************************************************************/ -/* I N T E R F A C E F U N C T I O N S */ -/* I N T E R F A C E F U N C T I O N S */ -/************************************************************************/ -/************************************************************************/ - -static inline void mos7840_set_port_private(struct usb_serial_port *port, - struct moschip_port *data) -{ - usb_set_serial_port_data(port, (void *)data); -} - -static inline struct moschip_port *mos7840_get_port_private(struct - usb_serial_port - *port) -{ - return (struct moschip_port *)usb_get_serial_port_data(port); -} - -static void mos7840_handle_new_msr(struct moschip_port *port, __u8 new_msr) -{ - struct moschip_port *mos7840_port; - struct async_icount *icount; - mos7840_port = port; - icount = &mos7840_port->icount; - if (new_msr & - (MOS_MSR_DELTA_CTS | MOS_MSR_DELTA_DSR | MOS_MSR_DELTA_RI | - MOS_MSR_DELTA_CD)) { - icount = &mos7840_port->icount; - - /* update input line counters */ - if (new_msr & MOS_MSR_DELTA_CTS) { - icount->cts++; - smp_wmb(); - } - if (new_msr & MOS_MSR_DELTA_DSR) { - icount->dsr++; - smp_wmb(); - } - if (new_msr & MOS_MSR_DELTA_CD) { - icount->dcd++; - smp_wmb(); - } - if (new_msr & MOS_MSR_DELTA_RI) { - icount->rng++; - smp_wmb(); - } - } -} - -static void mos7840_handle_new_lsr(struct moschip_port *port, __u8 new_lsr) -{ - struct async_icount *icount; - - dbg("%s - %02x", __func__, new_lsr); - - if (new_lsr & SERIAL_LSR_BI) { - /* - * Parity and Framing errors only count if they - * occur exclusive of a break being - * received. - */ - new_lsr &= (__u8) (SERIAL_LSR_OE | SERIAL_LSR_BI); - } - - /* update input line counters */ - icount = &port->icount; - if (new_lsr & SERIAL_LSR_BI) { - icount->brk++; - smp_wmb(); - } - if (new_lsr & SERIAL_LSR_OE) { - icount->overrun++; - smp_wmb(); - } - if (new_lsr & SERIAL_LSR_PE) { - icount->parity++; - smp_wmb(); - } - if (new_lsr & SERIAL_LSR_FE) { - icount->frame++; - smp_wmb(); - } -} - -/************************************************************************/ -/************************************************************************/ -/* U S B C A L L B A C K F U N C T I O N S */ -/* U S B C A L L B A C K F U N C T I O N S */ -/************************************************************************/ -/************************************************************************/ - -static void mos7840_control_callback(struct urb *urb) -{ - unsigned char *data; - struct moschip_port *mos7840_port; - __u8 regval = 0x0; - int result = 0; - int status = urb->status; - - mos7840_port = urb->context; - - switch (status) { - case 0: - /* success */ - break; - case -ECONNRESET: - case -ENOENT: - case -ESHUTDOWN: - /* this urb is terminated, clean up */ - dbg("%s - urb shutting down with status: %d", __func__, - status); - return; - default: - dbg("%s - nonzero urb status received: %d", __func__, - status); - goto exit; - } - - dbg("%s urb buffer size is %d", __func__, urb->actual_length); - dbg("%s mos7840_port->MsrLsr is %d port %d", __func__, - mos7840_port->MsrLsr, mos7840_port->port_num); - data = urb->transfer_buffer; - regval = (__u8) data[0]; - dbg("%s data is %x", __func__, regval); - if (mos7840_port->MsrLsr == 0) - mos7840_handle_new_msr(mos7840_port, regval); - else if (mos7840_port->MsrLsr == 1) - mos7840_handle_new_lsr(mos7840_port, regval); - -exit: - spin_lock(&mos7840_port->pool_lock); - if (!mos7840_port->zombie) - result = usb_submit_urb(mos7840_port->int_urb, GFP_ATOMIC); - spin_unlock(&mos7840_port->pool_lock); - if (result) { - dev_err(&urb->dev->dev, - "%s - Error %d submitting interrupt urb\n", - __func__, result); - } -} - -static int mos7840_get_reg(struct moschip_port *mcs, __u16 Wval, __u16 reg, - __u16 *val) -{ - struct usb_device *dev = mcs->port->serial->dev; - struct usb_ctrlrequest *dr = mcs->dr; - unsigned char *buffer = mcs->ctrl_buf; - int ret; - - dr->bRequestType = MCS_RD_RTYPE; - dr->bRequest = MCS_RDREQ; - dr->wValue = cpu_to_le16(Wval); /* 0 */ - dr->wIndex = cpu_to_le16(reg); - dr->wLength = cpu_to_le16(2); - - usb_fill_control_urb(mcs->control_urb, dev, usb_rcvctrlpipe(dev, 0), - (unsigned char *)dr, buffer, 2, - mos7840_control_callback, mcs); - mcs->control_urb->transfer_buffer_length = 2; - ret = usb_submit_urb(mcs->control_urb, GFP_ATOMIC); - return ret; -} - -/***************************************************************************** - * mos7840_interrupt_callback - * this is the callback function for when we have received data on the - * interrupt endpoint. - *****************************************************************************/ - -static void mos7840_interrupt_callback(struct urb *urb) -{ - int result; - int length; - struct moschip_port *mos7840_port; - struct usb_serial *serial; - __u16 Data; - unsigned char *data; - __u8 sp[5], st; - int i, rv = 0; - __u16 wval, wreg = 0; - int status = urb->status; - - dbg("%s", " : Entering"); - - switch (status) { - case 0: - /* success */ - break; - case -ECONNRESET: - case -ENOENT: - case -ESHUTDOWN: - /* this urb is terminated, clean up */ - dbg("%s - urb shutting down with status: %d", __func__, - status); - return; - default: - dbg("%s - nonzero urb status received: %d", __func__, - status); - goto exit; - } - - length = urb->actual_length; - data = urb->transfer_buffer; - - serial = urb->context; - - /* Moschip get 5 bytes - * Byte 1 IIR Port 1 (port.number is 0) - * Byte 2 IIR Port 2 (port.number is 1) - * Byte 3 IIR Port 3 (port.number is 2) - * Byte 4 IIR Port 4 (port.number is 3) - * Byte 5 FIFO status for both */ - - if (length && length > 5) { - dbg("%s", "Wrong data !!!"); - return; - } - - sp[0] = (__u8) data[0]; - sp[1] = (__u8) data[1]; - sp[2] = (__u8) data[2]; - sp[3] = (__u8) data[3]; - st = (__u8) data[4]; - - for (i = 0; i < serial->num_ports; i++) { - mos7840_port = mos7840_get_port_private(serial->port[i]); - wval = - (((__u16) serial->port[i]->number - - (__u16) (serial->minor)) + 1) << 8; - if (mos7840_port->open) { - if (sp[i] & 0x01) { - dbg("SP%d No Interrupt !!!", i); - } else { - switch (sp[i] & 0x0f) { - case SERIAL_IIR_RLS: - dbg("Serial Port %d: Receiver status error or ", i); - dbg("address bit detected in 9-bit mode"); - mos7840_port->MsrLsr = 1; - wreg = LINE_STATUS_REGISTER; - break; - case SERIAL_IIR_MS: - dbg("Serial Port %d: Modem status change", i); - mos7840_port->MsrLsr = 0; - wreg = MODEM_STATUS_REGISTER; - break; - } - spin_lock(&mos7840_port->pool_lock); - if (!mos7840_port->zombie) { - rv = mos7840_get_reg(mos7840_port, wval, wreg, &Data); - } else { - spin_unlock(&mos7840_port->pool_lock); - return; - } - spin_unlock(&mos7840_port->pool_lock); - } - } - } - if (!(rv < 0)) - /* the completion handler for the control urb will resubmit */ - return; -exit: - result = usb_submit_urb(urb, GFP_ATOMIC); - if (result) { - dev_err(&urb->dev->dev, - "%s - Error %d submitting interrupt urb\n", - __func__, result); - } -} - -static int mos7840_port_paranoia_check(struct usb_serial_port *port, - const char *function) -{ - if (!port) { - dbg("%s - port == NULL", function); - return -1; - } - if (!port->serial) { - dbg("%s - port->serial == NULL", function); - return -1; - } - - return 0; -} - -/* Inline functions to check the sanity of a pointer that is passed to us */ -static int mos7840_serial_paranoia_check(struct usb_serial *serial, - const char *function) -{ - if (!serial) { - dbg("%s - serial == NULL", function); - return -1; - } - if (!serial->type) { - dbg("%s - serial->type == NULL!", function); - return -1; - } - - return 0; -} - -static struct usb_serial *mos7840_get_usb_serial(struct usb_serial_port *port, - const char *function) -{ - /* if no port was specified, or it fails a paranoia check */ - if (!port || - mos7840_port_paranoia_check(port, function) || - mos7840_serial_paranoia_check(port->serial, function)) { - /* then say that we don't have a valid usb_serial thing, - * which will end up genrating -ENODEV return values */ - return NULL; - } - - return port->serial; -} - -/***************************************************************************** - * mos7840_bulk_in_callback - * this is the callback function for when we have received data on the - * bulk in endpoint. - *****************************************************************************/ - -static void mos7840_bulk_in_callback(struct urb *urb) -{ - int retval; - unsigned char *data; - struct usb_serial *serial; - struct usb_serial_port *port; - struct moschip_port *mos7840_port; - struct tty_struct *tty; - int status = urb->status; - - mos7840_port = urb->context; - if (!mos7840_port) { - dbg("%s", "NULL mos7840_port pointer"); - return; - } - - if (status) { - dbg("nonzero read bulk status received: %d", status); - mos7840_port->read_urb_busy = false; - return; - } - - port = (struct usb_serial_port *)mos7840_port->port; - if (mos7840_port_paranoia_check(port, __func__)) { - dbg("%s", "Port Paranoia failed"); - mos7840_port->read_urb_busy = false; - return; - } - - serial = mos7840_get_usb_serial(port, __func__); - if (!serial) { - dbg("%s", "Bad serial pointer"); - mos7840_port->read_urb_busy = false; - return; - } - - dbg("%s", "Entering... "); - - data = urb->transfer_buffer; - - dbg("%s", "Entering ..........."); - - if (urb->actual_length) { - tty = tty_port_tty_get(&mos7840_port->port->port); - if (tty) { - tty_insert_flip_string(tty, data, urb->actual_length); - dbg(" %s ", data); - tty_flip_buffer_push(tty); - tty_kref_put(tty); - } - mos7840_port->icount.rx += urb->actual_length; - smp_wmb(); - dbg("mos7840_port->icount.rx is %d:", - mos7840_port->icount.rx); - } - - if (!mos7840_port->read_urb) { - dbg("%s", "URB KILLED !!!"); - mos7840_port->read_urb_busy = false; - return; - } - - - mos7840_port->read_urb_busy = true; - retval = usb_submit_urb(mos7840_port->read_urb, GFP_ATOMIC); - - if (retval) { - dbg("usb_submit_urb(read bulk) failed, retval = %d", retval); - mos7840_port->read_urb_busy = false; - } -} - -/***************************************************************************** - * mos7840_bulk_out_data_callback - * this is the callback function for when we have finished sending - * serial data on the bulk out endpoint. - *****************************************************************************/ - -static void mos7840_bulk_out_data_callback(struct urb *urb) -{ - struct moschip_port *mos7840_port; - struct tty_struct *tty; - int status = urb->status; - int i; - - mos7840_port = urb->context; - spin_lock(&mos7840_port->pool_lock); - for (i = 0; i < NUM_URBS; i++) { - if (urb == mos7840_port->write_urb_pool[i]) { - mos7840_port->busy[i] = 0; - break; - } - } - spin_unlock(&mos7840_port->pool_lock); - - if (status) { - dbg("nonzero write bulk status received:%d", status); - return; - } - - if (mos7840_port_paranoia_check(mos7840_port->port, __func__)) { - dbg("%s", "Port Paranoia failed"); - return; - } - - dbg("%s", "Entering ........."); - - tty = tty_port_tty_get(&mos7840_port->port->port); - if (tty && mos7840_port->open) - tty_wakeup(tty); - tty_kref_put(tty); - -} - -/************************************************************************/ -/* D R I V E R T T Y I N T E R F A C E F U N C T I O N S */ -/************************************************************************/ -#ifdef MCSSerialProbe -static int mos7840_serial_probe(struct usb_serial *serial, - const struct usb_device_id *id) -{ - - /*need to implement the mode_reg reading and updating\ - structures usb_serial_ device_type\ - (i.e num_ports, num_bulkin,bulkout etc) */ - /* Also we can update the changes attach */ - return 1; -} -#endif - -/***************************************************************************** - * mos7840_open - * this function is called by the tty driver when a port is opened - * If successful, we return 0 - * Otherwise we return a negative error number. - *****************************************************************************/ - -static int mos7840_open(struct tty_struct *tty, struct usb_serial_port *port) -{ - int response; - int j; - struct usb_serial *serial; - struct urb *urb; - __u16 Data; - int status; - struct moschip_port *mos7840_port; - struct moschip_port *port0; - - dbg ("%s enter", __func__); - - if (mos7840_port_paranoia_check(port, __func__)) { - dbg("%s", "Port Paranoia failed"); - return -ENODEV; - } - - serial = port->serial; - - if (mos7840_serial_paranoia_check(serial, __func__)) { - dbg("%s", "Serial Paranoia failed"); - return -ENODEV; - } - - mos7840_port = mos7840_get_port_private(port); - port0 = mos7840_get_port_private(serial->port[0]); - - if (mos7840_port == NULL || port0 == NULL) - return -ENODEV; - - usb_clear_halt(serial->dev, port->write_urb->pipe); - usb_clear_halt(serial->dev, port->read_urb->pipe); - port0->open_ports++; - - /* Initialising the write urb pool */ - for (j = 0; j < NUM_URBS; ++j) { - urb = usb_alloc_urb(0, GFP_KERNEL); - mos7840_port->write_urb_pool[j] = urb; - - if (urb == NULL) { - dev_err(&port->dev, "No more urbs???\n"); - continue; - } - - urb->transfer_buffer = kmalloc(URB_TRANSFER_BUFFER_SIZE, - GFP_KERNEL); - if (!urb->transfer_buffer) { - usb_free_urb(urb); - mos7840_port->write_urb_pool[j] = NULL; - dev_err(&port->dev, - "%s-out of memory for urb buffers.\n", - __func__); - continue; - } - } - -/***************************************************************************** - * Initialize MCS7840 -- Write Init values to corresponding Registers - * - * Register Index - * 1 : IER - * 2 : FCR - * 3 : LCR - * 4 : MCR - * - * 0x08 : SP1/2 Control Reg - *****************************************************************************/ - - /* NEED to check the following Block */ - - Data = 0x0; - status = mos7840_get_reg_sync(port, mos7840_port->SpRegOffset, &Data); - if (status < 0) { - dbg("Reading Spreg failed"); - return -1; - } - Data |= 0x80; - status = mos7840_set_reg_sync(port, mos7840_port->SpRegOffset, Data); - if (status < 0) { - dbg("writing Spreg failed"); - return -1; - } - - Data &= ~0x80; - status = mos7840_set_reg_sync(port, mos7840_port->SpRegOffset, Data); - if (status < 0) { - dbg("writing Spreg failed"); - return -1; - } - /* End of block to be checked */ - - Data = 0x0; - status = mos7840_get_reg_sync(port, mos7840_port->ControlRegOffset, - &Data); - if (status < 0) { - dbg("Reading Controlreg failed"); - return -1; - } - Data |= 0x08; /* Driver done bit */ - Data |= 0x20; /* rx_disable */ - status = mos7840_set_reg_sync(port, - mos7840_port->ControlRegOffset, Data); - if (status < 0) { - dbg("writing Controlreg failed"); - return -1; - } - /* do register settings here */ - /* Set all regs to the device default values. */ - /*********************************** - * First Disable all interrupts. - ***********************************/ - Data = 0x00; - status = mos7840_set_uart_reg(port, INTERRUPT_ENABLE_REGISTER, Data); - if (status < 0) { - dbg("disabling interrupts failed"); - return -1; - } - /* Set FIFO_CONTROL_REGISTER to the default value */ - Data = 0x00; - status = mos7840_set_uart_reg(port, FIFO_CONTROL_REGISTER, Data); - if (status < 0) { - dbg("Writing FIFO_CONTROL_REGISTER failed"); - return -1; - } - - Data = 0xcf; - status = mos7840_set_uart_reg(port, FIFO_CONTROL_REGISTER, Data); - if (status < 0) { - dbg("Writing FIFO_CONTROL_REGISTER failed"); - return -1; - } - - Data = 0x03; - status = mos7840_set_uart_reg(port, LINE_CONTROL_REGISTER, Data); - mos7840_port->shadowLCR = Data; - - Data = 0x0b; - status = mos7840_set_uart_reg(port, MODEM_CONTROL_REGISTER, Data); - mos7840_port->shadowMCR = Data; - - Data = 0x00; - status = mos7840_get_uart_reg(port, LINE_CONTROL_REGISTER, &Data); - mos7840_port->shadowLCR = Data; - - Data |= SERIAL_LCR_DLAB; /* data latch enable in LCR 0x80 */ - status = mos7840_set_uart_reg(port, LINE_CONTROL_REGISTER, Data); - - Data = 0x0c; - status = mos7840_set_uart_reg(port, DIVISOR_LATCH_LSB, Data); - - Data = 0x0; - status = mos7840_set_uart_reg(port, DIVISOR_LATCH_MSB, Data); - - Data = 0x00; - status = mos7840_get_uart_reg(port, LINE_CONTROL_REGISTER, &Data); - - Data = Data & ~SERIAL_LCR_DLAB; - status = mos7840_set_uart_reg(port, LINE_CONTROL_REGISTER, Data); - mos7840_port->shadowLCR = Data; - - /* clearing Bulkin and Bulkout Fifo */ - Data = 0x0; - status = mos7840_get_reg_sync(port, mos7840_port->SpRegOffset, &Data); - - Data = Data | 0x0c; - status = mos7840_set_reg_sync(port, mos7840_port->SpRegOffset, Data); - - Data = Data & ~0x0c; - status = mos7840_set_reg_sync(port, mos7840_port->SpRegOffset, Data); - /* Finally enable all interrupts */ - Data = 0x0c; - status = mos7840_set_uart_reg(port, INTERRUPT_ENABLE_REGISTER, Data); - - /* clearing rx_disable */ - Data = 0x0; - status = mos7840_get_reg_sync(port, mos7840_port->ControlRegOffset, - &Data); - Data = Data & ~0x20; - status = mos7840_set_reg_sync(port, mos7840_port->ControlRegOffset, - Data); - - /* rx_negate */ - Data = 0x0; - status = mos7840_get_reg_sync(port, mos7840_port->ControlRegOffset, - &Data); - Data = Data | 0x10; - status = mos7840_set_reg_sync(port, mos7840_port->ControlRegOffset, - Data); - - /* Check to see if we've set up our endpoint info yet * - * (can't set it up in mos7840_startup as the structures * - * were not set up at that time.) */ - if (port0->open_ports == 1) { - if (serial->port[0]->interrupt_in_buffer == NULL) { - /* set up interrupt urb */ - usb_fill_int_urb(serial->port[0]->interrupt_in_urb, - serial->dev, - usb_rcvintpipe(serial->dev, - serial->port[0]->interrupt_in_endpointAddress), - serial->port[0]->interrupt_in_buffer, - serial->port[0]->interrupt_in_urb-> - transfer_buffer_length, - mos7840_interrupt_callback, - serial, - serial->port[0]->interrupt_in_urb->interval); - - /* start interrupt read for mos7840 * - * will continue as long as mos7840 is connected */ - - response = - usb_submit_urb(serial->port[0]->interrupt_in_urb, - GFP_KERNEL); - if (response) { - dev_err(&port->dev, "%s - Error %d submitting " - "interrupt urb\n", __func__, response); - } - - } - - } - - /* see if we've set up our endpoint info yet * - * (can't set it up in mos7840_startup as the * - * structures were not set up at that time.) */ - - dbg("port number is %d", port->number); - dbg("serial number is %d", port->serial->minor); - dbg("Bulkin endpoint is %d", port->bulk_in_endpointAddress); - dbg("BulkOut endpoint is %d", port->bulk_out_endpointAddress); - dbg("Interrupt endpoint is %d", port->interrupt_in_endpointAddress); - dbg("port's number in the device is %d", mos7840_port->port_num); - mos7840_port->read_urb = port->read_urb; - - /* set up our bulk in urb */ - if ((serial->num_ports == 2) - && ((((__u16)port->number - - (__u16)(port->serial->minor)) % 2) != 0)) { - usb_fill_bulk_urb(mos7840_port->read_urb, - serial->dev, - usb_rcvbulkpipe(serial->dev, - (port->bulk_in_endpointAddress) + 2), - port->bulk_in_buffer, - mos7840_port->read_urb->transfer_buffer_length, - mos7840_bulk_in_callback, mos7840_port); - } else { - usb_fill_bulk_urb(mos7840_port->read_urb, - serial->dev, - usb_rcvbulkpipe(serial->dev, - port->bulk_in_endpointAddress), - port->bulk_in_buffer, - mos7840_port->read_urb->transfer_buffer_length, - mos7840_bulk_in_callback, mos7840_port); - } - - dbg("mos7840_open: bulkin endpoint is %d", - port->bulk_in_endpointAddress); - mos7840_port->read_urb_busy = true; - response = usb_submit_urb(mos7840_port->read_urb, GFP_KERNEL); - if (response) { - dev_err(&port->dev, "%s - Error %d submitting control urb\n", - __func__, response); - mos7840_port->read_urb_busy = false; - } - - /* initialize our wait queues */ - init_waitqueue_head(&mos7840_port->wait_chase); - init_waitqueue_head(&mos7840_port->delta_msr_wait); - - /* initialize our icount structure */ - memset(&(mos7840_port->icount), 0x00, sizeof(mos7840_port->icount)); - - /* initialize our port settings */ - /* Must set to enable ints! */ - mos7840_port->shadowMCR = MCR_MASTER_IE; - /* send a open port command */ - mos7840_port->open = 1; - /* mos7840_change_port_settings(mos7840_port,old_termios); */ - mos7840_port->icount.tx = 0; - mos7840_port->icount.rx = 0; - - dbg("usb_serial serial:%p mos7840_port:%p\n usb_serial_port port:%p", - serial, mos7840_port, port); - - dbg ("%s leave", __func__); - - return 0; - -} - -/***************************************************************************** - * mos7840_chars_in_buffer - * this function is called by the tty driver when it wants to know how many - * bytes of data we currently have outstanding in the port (data that has - * been written, but hasn't made it out the port yet) - * If successful, we return the number of bytes left to be written in the - * system, - * Otherwise we return zero. - *****************************************************************************/ - -static int mos7840_chars_in_buffer(struct tty_struct *tty) -{ - struct usb_serial_port *port = tty->driver_data; - int i; - int chars = 0; - unsigned long flags; - struct moschip_port *mos7840_port; - - dbg("%s", " mos7840_chars_in_buffer:entering ..........."); - - if (mos7840_port_paranoia_check(port, __func__)) { - dbg("%s", "Invalid port"); - return 0; - } - - mos7840_port = mos7840_get_port_private(port); - if (mos7840_port == NULL) { - dbg("%s", "mos7840_break:leaving ..........."); - return 0; - } - - spin_lock_irqsave(&mos7840_port->pool_lock, flags); - for (i = 0; i < NUM_URBS; ++i) - if (mos7840_port->busy[i]) - chars += URB_TRANSFER_BUFFER_SIZE; - spin_unlock_irqrestore(&mos7840_port->pool_lock, flags); - dbg("%s - returns %d", __func__, chars); - return chars; - -} - -/***************************************************************************** - * mos7840_close - * this function is called by the tty driver when a port is closed - *****************************************************************************/ - -static void mos7840_close(struct usb_serial_port *port) -{ - struct usb_serial *serial; - struct moschip_port *mos7840_port; - struct moschip_port *port0; - int j; - __u16 Data; - - dbg("%s", "mos7840_close:entering..."); - - if (mos7840_port_paranoia_check(port, __func__)) { - dbg("%s", "Port Paranoia failed"); - return; - } - - serial = mos7840_get_usb_serial(port, __func__); - if (!serial) { - dbg("%s", "Serial Paranoia failed"); - return; - } - - mos7840_port = mos7840_get_port_private(port); - port0 = mos7840_get_port_private(serial->port[0]); - - if (mos7840_port == NULL || port0 == NULL) - return; - - for (j = 0; j < NUM_URBS; ++j) - usb_kill_urb(mos7840_port->write_urb_pool[j]); - - /* Freeing Write URBs */ - for (j = 0; j < NUM_URBS; ++j) { - if (mos7840_port->write_urb_pool[j]) { - if (mos7840_port->write_urb_pool[j]->transfer_buffer) - kfree(mos7840_port->write_urb_pool[j]-> - transfer_buffer); - - usb_free_urb(mos7840_port->write_urb_pool[j]); - } - } - - /* While closing port, shutdown all bulk read, write * - * and interrupt read if they exists */ - if (serial->dev) { - if (mos7840_port->write_urb) { - dbg("%s", "Shutdown bulk write"); - usb_kill_urb(mos7840_port->write_urb); - } - if (mos7840_port->read_urb) { - dbg("%s", "Shutdown bulk read"); - usb_kill_urb(mos7840_port->read_urb); - mos7840_port->read_urb_busy = false; - } - if ((&mos7840_port->control_urb)) { - dbg("%s", "Shutdown control read"); - /*/ usb_kill_urb (mos7840_port->control_urb); */ - } - } -/* if(mos7840_port->ctrl_buf != NULL) */ -/* kfree(mos7840_port->ctrl_buf); */ - port0->open_ports--; - dbg("mos7840_num_open_ports in close%d:in port%d", - port0->open_ports, port->number); - if (port0->open_ports == 0) { - if (serial->port[0]->interrupt_in_urb) { - dbg("%s", "Shutdown interrupt_in_urb"); - usb_kill_urb(serial->port[0]->interrupt_in_urb); - } - } - - if (mos7840_port->write_urb) { - /* if this urb had a transfer buffer already (old tx) free it */ - if (mos7840_port->write_urb->transfer_buffer != NULL) - kfree(mos7840_port->write_urb->transfer_buffer); - usb_free_urb(mos7840_port->write_urb); - } - - Data = 0x0; - mos7840_set_uart_reg(port, MODEM_CONTROL_REGISTER, Data); - - Data = 0x00; - mos7840_set_uart_reg(port, INTERRUPT_ENABLE_REGISTER, Data); - - mos7840_port->open = 0; - - dbg("%s", "Leaving ............"); -} - -/************************************************************************ - * - * mos7840_block_until_chase_response - * - * This function will block the close until one of the following: - * 1. Response to our Chase comes from mos7840 - * 2. A timeout of 10 seconds without activity has expired - * (1K of mos7840 data @ 2400 baud ==> 4 sec to empty) - * - ************************************************************************/ - -static void mos7840_block_until_chase_response(struct tty_struct *tty, - struct moschip_port *mos7840_port) -{ - int timeout = 1 * HZ; - int wait = 10; - int count; - - while (1) { - count = mos7840_chars_in_buffer(tty); - - /* Check for Buffer status */ - if (count <= 0) - return; - - /* Block the thread for a while */ - interruptible_sleep_on_timeout(&mos7840_port->wait_chase, - timeout); - /* No activity.. count down section */ - wait--; - if (wait == 0) { - dbg("%s - TIMEOUT", __func__); - return; - } else { - /* Reset timeout value back to seconds */ - wait = 10; - } - } - -} - -/***************************************************************************** - * mos7840_break - * this function sends a break to the port - *****************************************************************************/ -static void mos7840_break(struct tty_struct *tty, int break_state) -{ - struct usb_serial_port *port = tty->driver_data; - unsigned char data; - struct usb_serial *serial; - struct moschip_port *mos7840_port; - - dbg("%s", "Entering ..........."); - dbg("mos7840_break: Start"); - - if (mos7840_port_paranoia_check(port, __func__)) { - dbg("%s", "Port Paranoia failed"); - return; - } - - serial = mos7840_get_usb_serial(port, __func__); - if (!serial) { - dbg("%s", "Serial Paranoia failed"); - return; - } - - mos7840_port = mos7840_get_port_private(port); - - if (mos7840_port == NULL) - return; - - if (serial->dev) - /* flush and block until tx is empty */ - mos7840_block_until_chase_response(tty, mos7840_port); - - if (break_state == -1) - data = mos7840_port->shadowLCR | LCR_SET_BREAK; - else - data = mos7840_port->shadowLCR & ~LCR_SET_BREAK; - - /* FIXME: no locking on shadowLCR anywhere in driver */ - mos7840_port->shadowLCR = data; - dbg("mcs7840_break mos7840_port->shadowLCR is %x", - mos7840_port->shadowLCR); - mos7840_set_uart_reg(port, LINE_CONTROL_REGISTER, - mos7840_port->shadowLCR); -} - -/***************************************************************************** - * mos7840_write_room - * this function is called by the tty driver when it wants to know how many - * bytes of data we can accept for a specific port. - * If successful, we return the amount of room that we have for this port - * Otherwise we return a negative error number. - *****************************************************************************/ - -static int mos7840_write_room(struct tty_struct *tty) -{ - struct usb_serial_port *port = tty->driver_data; - int i; - int room = 0; - unsigned long flags; - struct moschip_port *mos7840_port; - - dbg("%s", " mos7840_write_room:entering ..........."); - - if (mos7840_port_paranoia_check(port, __func__)) { - dbg("%s", "Invalid port"); - dbg("%s", " mos7840_write_room:leaving ..........."); - return -1; - } - - mos7840_port = mos7840_get_port_private(port); - if (mos7840_port == NULL) { - dbg("%s", "mos7840_break:leaving ..........."); - return -1; - } - - spin_lock_irqsave(&mos7840_port->pool_lock, flags); - for (i = 0; i < NUM_URBS; ++i) { - if (!mos7840_port->busy[i]) - room += URB_TRANSFER_BUFFER_SIZE; - } - spin_unlock_irqrestore(&mos7840_port->pool_lock, flags); - - room = (room == 0) ? 0 : room - URB_TRANSFER_BUFFER_SIZE + 1; - dbg("%s - returns %d", __func__, room); - return room; - -} - -/***************************************************************************** - * mos7840_write - * this function is called by the tty driver when data should be written to - * the port. - * If successful, we return the number of bytes written, otherwise we - * return a negative error number. - *****************************************************************************/ - -static int mos7840_write(struct tty_struct *tty, struct usb_serial_port *port, - const unsigned char *data, int count) -{ - int status; - int i; - int bytes_sent = 0; - int transfer_size; - unsigned long flags; - - struct moschip_port *mos7840_port; - struct usb_serial *serial; - struct urb *urb; - /* __u16 Data; */ - const unsigned char *current_position = data; - unsigned char *data1; - dbg("%s", "entering ..........."); - /* dbg("mos7840_write: mos7840_port->shadowLCR is %x", - mos7840_port->shadowLCR); */ - -#ifdef NOTMOS7840 - Data = 0x00; - status = mos7840_get_uart_reg(port, LINE_CONTROL_REGISTER, &Data); - mos7840_port->shadowLCR = Data; - dbg("mos7840_write: LINE_CONTROL_REGISTER is %x", Data); - dbg("mos7840_write: mos7840_port->shadowLCR is %x", - mos7840_port->shadowLCR); - - /* Data = 0x03; */ - /* status = mos7840_set_uart_reg(port,LINE_CONTROL_REGISTER,Data); */ - /* mos7840_port->shadowLCR=Data;//Need to add later */ - - Data |= SERIAL_LCR_DLAB; /* data latch enable in LCR 0x80 */ - status = mos7840_set_uart_reg(port, LINE_CONTROL_REGISTER, Data); - - /* Data = 0x0c; */ - /* status = mos7840_set_uart_reg(port,DIVISOR_LATCH_LSB,Data); */ - Data = 0x00; - status = mos7840_get_uart_reg(port, DIVISOR_LATCH_LSB, &Data); - dbg("mos7840_write:DLL value is %x", Data); - - Data = 0x0; - status = mos7840_get_uart_reg(port, DIVISOR_LATCH_MSB, &Data); - dbg("mos7840_write:DLM value is %x", Data); - - Data = Data & ~SERIAL_LCR_DLAB; - dbg("mos7840_write: mos7840_port->shadowLCR is %x", - mos7840_port->shadowLCR); - status = mos7840_set_uart_reg(port, LINE_CONTROL_REGISTER, Data); -#endif - - if (mos7840_port_paranoia_check(port, __func__)) { - dbg("%s", "Port Paranoia failed"); - return -1; - } - - serial = port->serial; - if (mos7840_serial_paranoia_check(serial, __func__)) { - dbg("%s", "Serial Paranoia failed"); - return -1; - } - - mos7840_port = mos7840_get_port_private(port); - if (mos7840_port == NULL) { - dbg("%s", "mos7840_port is NULL"); - return -1; - } - - /* try to find a free urb in the list */ - urb = NULL; - - spin_lock_irqsave(&mos7840_port->pool_lock, flags); - for (i = 0; i < NUM_URBS; ++i) { - if (!mos7840_port->busy[i]) { - mos7840_port->busy[i] = 1; - urb = mos7840_port->write_urb_pool[i]; - dbg("URB:%d", i); - break; - } - } - spin_unlock_irqrestore(&mos7840_port->pool_lock, flags); - - if (urb == NULL) { - dbg("%s - no more free urbs", __func__); - goto exit; - } - - if (urb->transfer_buffer == NULL) { - urb->transfer_buffer = - kmalloc(URB_TRANSFER_BUFFER_SIZE, GFP_KERNEL); - - if (urb->transfer_buffer == NULL) { - dev_err_console(port, "%s no more kernel memory...\n", - __func__); - goto exit; - } - } - transfer_size = min(count, URB_TRANSFER_BUFFER_SIZE); - - memcpy(urb->transfer_buffer, current_position, transfer_size); - - /* fill urb with data and submit */ - if ((serial->num_ports == 2) - && ((((__u16)port->number - - (__u16)(port->serial->minor)) % 2) != 0)) { - usb_fill_bulk_urb(urb, - serial->dev, - usb_sndbulkpipe(serial->dev, - (port->bulk_out_endpointAddress) + 2), - urb->transfer_buffer, - transfer_size, - mos7840_bulk_out_data_callback, mos7840_port); - } else { - usb_fill_bulk_urb(urb, - serial->dev, - usb_sndbulkpipe(serial->dev, - port->bulk_out_endpointAddress), - urb->transfer_buffer, - transfer_size, - mos7840_bulk_out_data_callback, mos7840_port); - } - - data1 = urb->transfer_buffer; - dbg("bulkout endpoint is %d", port->bulk_out_endpointAddress); - - /* send it down the pipe */ - status = usb_submit_urb(urb, GFP_ATOMIC); - - if (status) { - mos7840_port->busy[i] = 0; - dev_err_console(port, "%s - usb_submit_urb(write bulk) failed " - "with status = %d\n", __func__, status); - bytes_sent = status; - goto exit; - } - bytes_sent = transfer_size; - mos7840_port->icount.tx += transfer_size; - smp_wmb(); - dbg("mos7840_port->icount.tx is %d:", mos7840_port->icount.tx); -exit: - return bytes_sent; - -} - -/***************************************************************************** - * mos7840_throttle - * this function is called by the tty driver when it wants to stop the data - * being read from the port. - *****************************************************************************/ - -static void mos7840_throttle(struct tty_struct *tty) -{ - struct usb_serial_port *port = tty->driver_data; - struct moschip_port *mos7840_port; - int status; - - if (mos7840_port_paranoia_check(port, __func__)) { - dbg("%s", "Invalid port"); - return; - } - - dbg("- port %d", port->number); - - mos7840_port = mos7840_get_port_private(port); - - if (mos7840_port == NULL) - return; - - if (!mos7840_port->open) { - dbg("%s", "port not opened"); - return; - } - - dbg("%s", "Entering .........."); - - /* if we are implementing XON/XOFF, send the stop character */ - if (I_IXOFF(tty)) { - unsigned char stop_char = STOP_CHAR(tty); - status = mos7840_write(tty, port, &stop_char, 1); - if (status <= 0) - return; - } - /* if we are implementing RTS/CTS, toggle that line */ - if (tty->termios->c_cflag & CRTSCTS) { - mos7840_port->shadowMCR &= ~MCR_RTS; - status = mos7840_set_uart_reg(port, MODEM_CONTROL_REGISTER, - mos7840_port->shadowMCR); - if (status < 0) - return; - } -} - -/***************************************************************************** - * mos7840_unthrottle - * this function is called by the tty driver when it wants to resume - * the data being read from the port (called after mos7840_throttle is - * called) - *****************************************************************************/ -static void mos7840_unthrottle(struct tty_struct *tty) -{ - struct usb_serial_port *port = tty->driver_data; - int status; - struct moschip_port *mos7840_port = mos7840_get_port_private(port); - - if (mos7840_port_paranoia_check(port, __func__)) { - dbg("%s", "Invalid port"); - return; - } - - if (mos7840_port == NULL) - return; - - if (!mos7840_port->open) { - dbg("%s - port not opened", __func__); - return; - } - - dbg("%s", "Entering .........."); - - /* if we are implementing XON/XOFF, send the start character */ - if (I_IXOFF(tty)) { - unsigned char start_char = START_CHAR(tty); - status = mos7840_write(tty, port, &start_char, 1); - if (status <= 0) - return; - } - - /* if we are implementing RTS/CTS, toggle that line */ - if (tty->termios->c_cflag & CRTSCTS) { - mos7840_port->shadowMCR |= MCR_RTS; - status = mos7840_set_uart_reg(port, MODEM_CONTROL_REGISTER, - mos7840_port->shadowMCR); - if (status < 0) - return; - } -} - -static int mos7840_tiocmget(struct tty_struct *tty) -{ - struct usb_serial_port *port = tty->driver_data; - struct moschip_port *mos7840_port; - unsigned int result; - __u16 msr; - __u16 mcr; - int status; - mos7840_port = mos7840_get_port_private(port); - - dbg("%s - port %d", __func__, port->number); - - if (mos7840_port == NULL) - return -ENODEV; - - status = mos7840_get_uart_reg(port, MODEM_STATUS_REGISTER, &msr); - status = mos7840_get_uart_reg(port, MODEM_CONTROL_REGISTER, &mcr); - result = ((mcr & MCR_DTR) ? TIOCM_DTR : 0) - | ((mcr & MCR_RTS) ? TIOCM_RTS : 0) - | ((mcr & MCR_LOOPBACK) ? TIOCM_LOOP : 0) - | ((msr & MOS7840_MSR_CTS) ? TIOCM_CTS : 0) - | ((msr & MOS7840_MSR_CD) ? TIOCM_CAR : 0) - | ((msr & MOS7840_MSR_RI) ? TIOCM_RI : 0) - | ((msr & MOS7840_MSR_DSR) ? TIOCM_DSR : 0); - - dbg("%s - 0x%04X", __func__, result); - - return result; -} - -static int mos7840_tiocmset(struct tty_struct *tty, - unsigned int set, unsigned int clear) -{ - struct usb_serial_port *port = tty->driver_data; - struct moschip_port *mos7840_port; - unsigned int mcr; - int status; - - dbg("%s - port %d", __func__, port->number); - - mos7840_port = mos7840_get_port_private(port); - - if (mos7840_port == NULL) - return -ENODEV; - - /* FIXME: What locks the port registers ? */ - mcr = mos7840_port->shadowMCR; - if (clear & TIOCM_RTS) - mcr &= ~MCR_RTS; - if (clear & TIOCM_DTR) - mcr &= ~MCR_DTR; - if (clear & TIOCM_LOOP) - mcr &= ~MCR_LOOPBACK; - - if (set & TIOCM_RTS) - mcr |= MCR_RTS; - if (set & TIOCM_DTR) - mcr |= MCR_DTR; - if (set & TIOCM_LOOP) - mcr |= MCR_LOOPBACK; - - mos7840_port->shadowMCR = mcr; - - status = mos7840_set_uart_reg(port, MODEM_CONTROL_REGISTER, mcr); - if (status < 0) { - dbg("setting MODEM_CONTROL_REGISTER Failed"); - return status; - } - - return 0; -} - -/***************************************************************************** - * mos7840_calc_baud_rate_divisor - * this function calculates the proper baud rate divisor for the specified - * baud rate. - *****************************************************************************/ -static int mos7840_calc_baud_rate_divisor(int baudRate, int *divisor, - __u16 *clk_sel_val) -{ - - dbg("%s - %d", __func__, baudRate); - - if (baudRate <= 115200) { - *divisor = 115200 / baudRate; - *clk_sel_val = 0x0; - } - if ((baudRate > 115200) && (baudRate <= 230400)) { - *divisor = 230400 / baudRate; - *clk_sel_val = 0x10; - } else if ((baudRate > 230400) && (baudRate <= 403200)) { - *divisor = 403200 / baudRate; - *clk_sel_val = 0x20; - } else if ((baudRate > 403200) && (baudRate <= 460800)) { - *divisor = 460800 / baudRate; - *clk_sel_val = 0x30; - } else if ((baudRate > 460800) && (baudRate <= 806400)) { - *divisor = 806400 / baudRate; - *clk_sel_val = 0x40; - } else if ((baudRate > 806400) && (baudRate <= 921600)) { - *divisor = 921600 / baudRate; - *clk_sel_val = 0x50; - } else if ((baudRate > 921600) && (baudRate <= 1572864)) { - *divisor = 1572864 / baudRate; - *clk_sel_val = 0x60; - } else if ((baudRate > 1572864) && (baudRate <= 3145728)) { - *divisor = 3145728 / baudRate; - *clk_sel_val = 0x70; - } - return 0; - -#ifdef NOTMCS7840 - - for (i = 0; i < ARRAY_SIZE(mos7840_divisor_table); i++) { - if (mos7840_divisor_table[i].BaudRate == baudrate) { - *divisor = mos7840_divisor_table[i].Divisor; - return 0; - } - } - - /* After trying for all the standard baud rates * - * Try calculating the divisor for this baud rate */ - - if (baudrate > 75 && baudrate < 230400) { - /* get the divisor */ - custom = (__u16) (230400L / baudrate); - - /* Check for round off */ - round1 = (__u16) (2304000L / baudrate); - round = (__u16) (round1 - (custom * 10)); - if (round > 4) - custom++; - *divisor = custom; - - dbg(" Baud %d = %d", baudrate, custom); - return 0; - } - - dbg("%s", " Baud calculation Failed..."); - return -1; -#endif -} - -/***************************************************************************** - * mos7840_send_cmd_write_baud_rate - * this function sends the proper command to change the baud rate of the - * specified port. - *****************************************************************************/ - -static int mos7840_send_cmd_write_baud_rate(struct moschip_port *mos7840_port, - int baudRate) -{ - int divisor = 0; - int status; - __u16 Data; - unsigned char number; - __u16 clk_sel_val; - struct usb_serial_port *port; - - if (mos7840_port == NULL) - return -1; - - port = (struct usb_serial_port *)mos7840_port->port; - if (mos7840_port_paranoia_check(port, __func__)) { - dbg("%s", "Invalid port"); - return -1; - } - - if (mos7840_serial_paranoia_check(port->serial, __func__)) { - dbg("%s", "Invalid Serial"); - return -1; - } - - dbg("%s", "Entering .........."); - - number = mos7840_port->port->number - mos7840_port->port->serial->minor; - - dbg("%s - port = %d, baud = %d", __func__, - mos7840_port->port->number, baudRate); - /* reset clk_uart_sel in spregOffset */ - if (baudRate > 115200) { -#ifdef HW_flow_control - /* NOTE: need to see the pther register to modify */ - /* setting h/w flow control bit to 1 */ - Data = 0x2b; - mos7840_port->shadowMCR = Data; - status = mos7840_set_uart_reg(port, MODEM_CONTROL_REGISTER, - Data); - if (status < 0) { - dbg("Writing spreg failed in set_serial_baud"); - return -1; - } -#endif - - } else { -#ifdef HW_flow_control - /* setting h/w flow control bit to 0 */ - Data = 0xb; - mos7840_port->shadowMCR = Data; - status = mos7840_set_uart_reg(port, MODEM_CONTROL_REGISTER, - Data); - if (status < 0) { - dbg("Writing spreg failed in set_serial_baud"); - return -1; - } -#endif - - } - - if (1) { /* baudRate <= 115200) */ - clk_sel_val = 0x0; - Data = 0x0; - status = mos7840_calc_baud_rate_divisor(baudRate, &divisor, - &clk_sel_val); - status = mos7840_get_reg_sync(port, mos7840_port->SpRegOffset, - &Data); - if (status < 0) { - dbg("reading spreg failed in set_serial_baud"); - return -1; - } - Data = (Data & 0x8f) | clk_sel_val; - status = mos7840_set_reg_sync(port, mos7840_port->SpRegOffset, - Data); - if (status < 0) { - dbg("Writing spreg failed in set_serial_baud"); - return -1; - } - /* Calculate the Divisor */ - - if (status) { - dev_err(&port->dev, "%s - bad baud rate\n", __func__); - return status; - } - /* Enable access to divisor latch */ - Data = mos7840_port->shadowLCR | SERIAL_LCR_DLAB; - mos7840_port->shadowLCR = Data; - mos7840_set_uart_reg(port, LINE_CONTROL_REGISTER, Data); - - /* Write the divisor */ - Data = (unsigned char)(divisor & 0xff); - dbg("set_serial_baud Value to write DLL is %x", Data); - mos7840_set_uart_reg(port, DIVISOR_LATCH_LSB, Data); - - Data = (unsigned char)((divisor & 0xff00) >> 8); - dbg("set_serial_baud Value to write DLM is %x", Data); - mos7840_set_uart_reg(port, DIVISOR_LATCH_MSB, Data); - - /* Disable access to divisor latch */ - Data = mos7840_port->shadowLCR & ~SERIAL_LCR_DLAB; - mos7840_port->shadowLCR = Data; - mos7840_set_uart_reg(port, LINE_CONTROL_REGISTER, Data); - - } - return status; -} - -/***************************************************************************** - * mos7840_change_port_settings - * This routine is called to set the UART on the device to match - * the specified new settings. - *****************************************************************************/ - -static void mos7840_change_port_settings(struct tty_struct *tty, - struct moschip_port *mos7840_port, struct ktermios *old_termios) -{ - int baud; - unsigned cflag; - unsigned iflag; - __u8 lData; - __u8 lParity; - __u8 lStop; - int status; - __u16 Data; - struct usb_serial_port *port; - struct usb_serial *serial; - - if (mos7840_port == NULL) - return; - - port = (struct usb_serial_port *)mos7840_port->port; - - if (mos7840_port_paranoia_check(port, __func__)) { - dbg("%s", "Invalid port"); - return; - } - - if (mos7840_serial_paranoia_check(port->serial, __func__)) { - dbg("%s", "Invalid Serial"); - return; - } - - serial = port->serial; - - dbg("%s - port %d", __func__, mos7840_port->port->number); - - if (!mos7840_port->open) { - dbg("%s - port not opened", __func__); - return; - } - - dbg("%s", "Entering .........."); - - lData = LCR_BITS_8; - lStop = LCR_STOP_1; - lParity = LCR_PAR_NONE; - - cflag = tty->termios->c_cflag; - iflag = tty->termios->c_iflag; - - /* Change the number of bits */ - if (cflag & CSIZE) { - switch (cflag & CSIZE) { - case CS5: - lData = LCR_BITS_5; - break; - - case CS6: - lData = LCR_BITS_6; - break; - - case CS7: - lData = LCR_BITS_7; - break; - default: - case CS8: - lData = LCR_BITS_8; - break; - } - } - /* Change the Parity bit */ - if (cflag & PARENB) { - if (cflag & PARODD) { - lParity = LCR_PAR_ODD; - dbg("%s - parity = odd", __func__); - } else { - lParity = LCR_PAR_EVEN; - dbg("%s - parity = even", __func__); - } - - } else { - dbg("%s - parity = none", __func__); - } - - if (cflag & CMSPAR) - lParity = lParity | 0x20; - - /* Change the Stop bit */ - if (cflag & CSTOPB) { - lStop = LCR_STOP_2; - dbg("%s - stop bits = 2", __func__); - } else { - lStop = LCR_STOP_1; - dbg("%s - stop bits = 1", __func__); - } - - /* Update the LCR with the correct value */ - mos7840_port->shadowLCR &= - ~(LCR_BITS_MASK | LCR_STOP_MASK | LCR_PAR_MASK); - mos7840_port->shadowLCR |= (lData | lParity | lStop); - - dbg("mos7840_change_port_settings mos7840_port->shadowLCR is %x", - mos7840_port->shadowLCR); - /* Disable Interrupts */ - Data = 0x00; - mos7840_set_uart_reg(port, INTERRUPT_ENABLE_REGISTER, Data); - - Data = 0x00; - mos7840_set_uart_reg(port, FIFO_CONTROL_REGISTER, Data); - - Data = 0xcf; - mos7840_set_uart_reg(port, FIFO_CONTROL_REGISTER, Data); - - /* Send the updated LCR value to the mos7840 */ - Data = mos7840_port->shadowLCR; - - mos7840_set_uart_reg(port, LINE_CONTROL_REGISTER, Data); - - Data = 0x00b; - mos7840_port->shadowMCR = Data; - mos7840_set_uart_reg(port, MODEM_CONTROL_REGISTER, Data); - Data = 0x00b; - mos7840_set_uart_reg(port, MODEM_CONTROL_REGISTER, Data); - - /* set up the MCR register and send it to the mos7840 */ - - mos7840_port->shadowMCR = MCR_MASTER_IE; - if (cflag & CBAUD) - mos7840_port->shadowMCR |= (MCR_DTR | MCR_RTS); - - if (cflag & CRTSCTS) - mos7840_port->shadowMCR |= (MCR_XON_ANY); - else - mos7840_port->shadowMCR &= ~(MCR_XON_ANY); - - Data = mos7840_port->shadowMCR; - mos7840_set_uart_reg(port, MODEM_CONTROL_REGISTER, Data); - - /* Determine divisor based on baud rate */ - baud = tty_get_baud_rate(tty); - - if (!baud) { - /* pick a default, any default... */ - dbg("%s", "Picked default baud..."); - baud = 9600; - } - - dbg("%s - baud rate = %d", __func__, baud); - status = mos7840_send_cmd_write_baud_rate(mos7840_port, baud); - - /* Enable Interrupts */ - Data = 0x0c; - mos7840_set_uart_reg(port, INTERRUPT_ENABLE_REGISTER, Data); - - if (mos7840_port->read_urb_busy == false) { - mos7840_port->read_urb_busy = true; - status = usb_submit_urb(mos7840_port->read_urb, GFP_ATOMIC); - if (status) { - dbg("usb_submit_urb(read bulk) failed, status = %d", - status); - mos7840_port->read_urb_busy = false; - } - } - wake_up(&mos7840_port->delta_msr_wait); - mos7840_port->delta_msr_cond = 1; - dbg("mos7840_change_port_settings mos7840_port->shadowLCR is End %x", - mos7840_port->shadowLCR); -} - -/***************************************************************************** - * mos7840_set_termios - * this function is called by the tty driver when it wants to change - * the termios structure - *****************************************************************************/ - -static void mos7840_set_termios(struct tty_struct *tty, - struct usb_serial_port *port, - struct ktermios *old_termios) -{ - int status; - unsigned int cflag; - struct usb_serial *serial; - struct moschip_port *mos7840_port; - dbg("mos7840_set_termios: START"); - if (mos7840_port_paranoia_check(port, __func__)) { - dbg("%s", "Invalid port"); - return; - } - - serial = port->serial; - - if (mos7840_serial_paranoia_check(serial, __func__)) { - dbg("%s", "Invalid Serial"); - return; - } - - mos7840_port = mos7840_get_port_private(port); - - if (mos7840_port == NULL) - return; - - if (!mos7840_port->open) { - dbg("%s - port not opened", __func__); - return; - } - - dbg("%s", "setting termios - "); - - cflag = tty->termios->c_cflag; - - dbg("%s - clfag %08x iflag %08x", __func__, - tty->termios->c_cflag, RELEVANT_IFLAG(tty->termios->c_iflag)); - dbg("%s - old clfag %08x old iflag %08x", __func__, - old_termios->c_cflag, RELEVANT_IFLAG(old_termios->c_iflag)); - dbg("%s - port %d", __func__, port->number); - - /* change the port settings to the new ones specified */ - - mos7840_change_port_settings(tty, mos7840_port, old_termios); - - if (!mos7840_port->read_urb) { - dbg("%s", "URB KILLED !!!!!"); - return; - } - - if (mos7840_port->read_urb_busy == false) { - mos7840_port->read_urb_busy = true; - status = usb_submit_urb(mos7840_port->read_urb, GFP_ATOMIC); - if (status) { - dbg("usb_submit_urb(read bulk) failed, status = %d", - status); - mos7840_port->read_urb_busy = false; - } - } -} - -/***************************************************************************** - * mos7840_get_lsr_info - get line status register info - * - * Purpose: Let user call ioctl() to get info when the UART physically - * is emptied. On bus types like RS485, the transmitter must - * release the bus after transmitting. This must be done when - * the transmit shift register is empty, not be done when the - * transmit holding register is empty. This functionality - * allows an RS485 driver to be written in user space. - *****************************************************************************/ - -static int mos7840_get_lsr_info(struct tty_struct *tty, - unsigned int __user *value) -{ - int count; - unsigned int result = 0; - - count = mos7840_chars_in_buffer(tty); - if (count == 0) { - dbg("%s -- Empty", __func__); - result = TIOCSER_TEMT; - } - - if (copy_to_user(value, &result, sizeof(int))) - return -EFAULT; - return 0; -} - -/***************************************************************************** - * mos7840_get_serial_info - * function to get information about serial port - *****************************************************************************/ - -static int mos7840_get_serial_info(struct moschip_port *mos7840_port, - struct serial_struct __user *retinfo) -{ - struct serial_struct tmp; - - if (mos7840_port == NULL) - return -1; - - if (!retinfo) - return -EFAULT; - - memset(&tmp, 0, sizeof(tmp)); - - tmp.type = PORT_16550A; - tmp.line = mos7840_port->port->serial->minor; - tmp.port = mos7840_port->port->number; - tmp.irq = 0; - tmp.flags = ASYNC_SKIP_TEST | ASYNC_AUTO_IRQ; - tmp.xmit_fifo_size = NUM_URBS * URB_TRANSFER_BUFFER_SIZE; - tmp.baud_base = 9600; - tmp.close_delay = 5 * HZ; - tmp.closing_wait = 30 * HZ; - - if (copy_to_user(retinfo, &tmp, sizeof(*retinfo))) - return -EFAULT; - return 0; -} - -static int mos7840_get_icount(struct tty_struct *tty, - struct serial_icounter_struct *icount) -{ - struct usb_serial_port *port = tty->driver_data; - struct moschip_port *mos7840_port; - struct async_icount cnow; - - mos7840_port = mos7840_get_port_private(port); - cnow = mos7840_port->icount; - - smp_rmb(); - icount->cts = cnow.cts; - icount->dsr = cnow.dsr; - icount->rng = cnow.rng; - icount->dcd = cnow.dcd; - icount->rx = cnow.rx; - icount->tx = cnow.tx; - icount->frame = cnow.frame; - icount->overrun = cnow.overrun; - icount->parity = cnow.parity; - icount->brk = cnow.brk; - icount->buf_overrun = cnow.buf_overrun; - - dbg("%s (%d) TIOCGICOUNT RX=%d, TX=%d", __func__, - port->number, icount->rx, icount->tx); - return 0; -} - -/***************************************************************************** - * SerialIoctl - * this function handles any ioctl calls to the driver - *****************************************************************************/ - -static int mos7840_ioctl(struct tty_struct *tty, - unsigned int cmd, unsigned long arg) -{ - struct usb_serial_port *port = tty->driver_data; - void __user *argp = (void __user *)arg; - struct moschip_port *mos7840_port; - - struct async_icount cnow; - struct async_icount cprev; - - if (mos7840_port_paranoia_check(port, __func__)) { - dbg("%s", "Invalid port"); - return -1; - } - - mos7840_port = mos7840_get_port_private(port); - - if (mos7840_port == NULL) - return -1; - - dbg("%s - port %d, cmd = 0x%x", __func__, port->number, cmd); - - switch (cmd) { - /* return number of bytes available */ - - case TIOCSERGETLSR: - dbg("%s (%d) TIOCSERGETLSR", __func__, port->number); - return mos7840_get_lsr_info(tty, argp); - - case TIOCGSERIAL: - dbg("%s (%d) TIOCGSERIAL", __func__, port->number); - return mos7840_get_serial_info(mos7840_port, argp); - - case TIOCSSERIAL: - dbg("%s (%d) TIOCSSERIAL", __func__, port->number); - break; - - case TIOCMIWAIT: - dbg("%s (%d) TIOCMIWAIT", __func__, port->number); - cprev = mos7840_port->icount; - while (1) { - /* interruptible_sleep_on(&mos7840_port->delta_msr_wait); */ - mos7840_port->delta_msr_cond = 0; - wait_event_interruptible(mos7840_port->delta_msr_wait, - (mos7840_port-> - delta_msr_cond == 1)); - - /* see if a signal did it */ - if (signal_pending(current)) - return -ERESTARTSYS; - cnow = mos7840_port->icount; - smp_rmb(); - if (cnow.rng == cprev.rng && cnow.dsr == cprev.dsr && - cnow.dcd == cprev.dcd && cnow.cts == cprev.cts) - return -EIO; /* no change => error */ - if (((arg & TIOCM_RNG) && (cnow.rng != cprev.rng)) || - ((arg & TIOCM_DSR) && (cnow.dsr != cprev.dsr)) || - ((arg & TIOCM_CD) && (cnow.dcd != cprev.dcd)) || - ((arg & TIOCM_CTS) && (cnow.cts != cprev.cts))) { - return 0; - } - cprev = cnow; - } - /* NOTREACHED */ - break; - - default: - break; - } - return -ENOIOCTLCMD; -} - -static int mos7840_calc_num_ports(struct usb_serial *serial) -{ - __u16 Data = 0x00; - int ret = 0; - int mos7840_num_ports; - - ret = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0), - MCS_RDREQ, MCS_RD_RTYPE, 0, GPIO_REGISTER, &Data, - VENDOR_READ_LENGTH, MOS_WDR_TIMEOUT); - - if ((Data & 0x01) == 0) { - mos7840_num_ports = 2; - serial->num_bulk_in = 2; - serial->num_bulk_out = 2; - serial->num_ports = 2; - } else { - mos7840_num_ports = 4; - serial->num_bulk_in = 4; - serial->num_bulk_out = 4; - serial->num_ports = 4; - } - - return mos7840_num_ports; -} - -/**************************************************************************** - * mos7840_startup - ****************************************************************************/ - -static int mos7840_startup(struct usb_serial *serial) -{ - struct moschip_port *mos7840_port; - struct usb_device *dev; - int i, status; - - __u16 Data; - dbg("%s", "mos7840_startup :Entering.........."); - - if (!serial) { - dbg("%s", "Invalid Handler"); - return -1; - } - - dev = serial->dev; - - dbg("%s", "Entering..."); - dbg ("mos7840_startup: serial = %p", serial); - - /* we set up the pointers to the endpoints in the mos7840_open * - * function, as the structures aren't created yet. */ - - /* set up port private structures */ - for (i = 0; i < serial->num_ports; ++i) { - dbg ("mos7840_startup: configuring port %d............", i); - mos7840_port = kzalloc(sizeof(struct moschip_port), GFP_KERNEL); - if (mos7840_port == NULL) { - dev_err(&dev->dev, "%s - Out of memory\n", __func__); - status = -ENOMEM; - i--; /* don't follow NULL pointer cleaning up */ - goto error; - } - - /* Initialize all port interrupt end point to port 0 int - * endpoint. Our device has only one interrupt end point - * common to all port */ - - mos7840_port->port = serial->port[i]; - mos7840_set_port_private(serial->port[i], mos7840_port); - spin_lock_init(&mos7840_port->pool_lock); - - /* minor is not initialised until later by - * usb-serial.c:get_free_serial() and cannot therefore be used - * to index device instances */ - mos7840_port->port_num = i + 1; - dbg ("serial->port[i]->number = %d", serial->port[i]->number); - dbg ("serial->port[i]->serial->minor = %d", serial->port[i]->serial->minor); - dbg ("mos7840_port->port_num = %d", mos7840_port->port_num); - dbg ("serial->minor = %d", serial->minor); - - if (mos7840_port->port_num == 1) { - mos7840_port->SpRegOffset = 0x0; - mos7840_port->ControlRegOffset = 0x1; - mos7840_port->DcrRegOffset = 0x4; - } else if ((mos7840_port->port_num == 2) - && (serial->num_ports == 4)) { - mos7840_port->SpRegOffset = 0x8; - mos7840_port->ControlRegOffset = 0x9; - mos7840_port->DcrRegOffset = 0x16; - } else if ((mos7840_port->port_num == 2) - && (serial->num_ports == 2)) { - mos7840_port->SpRegOffset = 0xa; - mos7840_port->ControlRegOffset = 0xb; - mos7840_port->DcrRegOffset = 0x19; - } else if ((mos7840_port->port_num == 3) - && (serial->num_ports == 4)) { - mos7840_port->SpRegOffset = 0xa; - mos7840_port->ControlRegOffset = 0xb; - mos7840_port->DcrRegOffset = 0x19; - } else if ((mos7840_port->port_num == 4) - && (serial->num_ports == 4)) { - mos7840_port->SpRegOffset = 0xc; - mos7840_port->ControlRegOffset = 0xd; - mos7840_port->DcrRegOffset = 0x1c; - } - mos7840_dump_serial_port(mos7840_port); - mos7840_set_port_private(serial->port[i], mos7840_port); - - /* enable rx_disable bit in control register */ - status = mos7840_get_reg_sync(serial->port[i], - mos7840_port->ControlRegOffset, &Data); - if (status < 0) { - dbg("Reading ControlReg failed status-0x%x", status); - break; - } else - dbg("ControlReg Reading success val is %x, status%d", - Data, status); - Data |= 0x08; /* setting driver done bit */ - Data |= 0x04; /* sp1_bit to have cts change reflect in - modem status reg */ - - /* Data |= 0x20; //rx_disable bit */ - status = mos7840_set_reg_sync(serial->port[i], - mos7840_port->ControlRegOffset, Data); - if (status < 0) { - dbg("Writing ControlReg failed(rx_disable) status-0x%x", status); - break; - } else - dbg("ControlReg Writing success(rx_disable) status%d", - status); - - /* Write default values in DCR (i.e 0x01 in DCR0, 0x05 in DCR2 - and 0x24 in DCR3 */ - Data = 0x01; - status = mos7840_set_reg_sync(serial->port[i], - (__u16) (mos7840_port->DcrRegOffset + 0), Data); - if (status < 0) { - dbg("Writing DCR0 failed status-0x%x", status); - break; - } else - dbg("DCR0 Writing success status%d", status); - - Data = 0x05; - status = mos7840_set_reg_sync(serial->port[i], - (__u16) (mos7840_port->DcrRegOffset + 1), Data); - if (status < 0) { - dbg("Writing DCR1 failed status-0x%x", status); - break; - } else - dbg("DCR1 Writing success status%d", status); - - Data = 0x24; - status = mos7840_set_reg_sync(serial->port[i], - (__u16) (mos7840_port->DcrRegOffset + 2), Data); - if (status < 0) { - dbg("Writing DCR2 failed status-0x%x", status); - break; - } else - dbg("DCR2 Writing success status%d", status); - - /* write values in clkstart0x0 and clkmulti 0x20 */ - Data = 0x0; - status = mos7840_set_reg_sync(serial->port[i], - CLK_START_VALUE_REGISTER, Data); - if (status < 0) { - dbg("Writing CLK_START_VALUE_REGISTER failed status-0x%x", status); - break; - } else - dbg("CLK_START_VALUE_REGISTER Writing success status%d", status); - - Data = 0x20; - status = mos7840_set_reg_sync(serial->port[i], - CLK_MULTI_REGISTER, Data); - if (status < 0) { - dbg("Writing CLK_MULTI_REGISTER failed status-0x%x", - status); - goto error; - } else - dbg("CLK_MULTI_REGISTER Writing success status%d", - status); - - /* write value 0x0 to scratchpad register */ - Data = 0x00; - status = mos7840_set_uart_reg(serial->port[i], - SCRATCH_PAD_REGISTER, Data); - if (status < 0) { - dbg("Writing SCRATCH_PAD_REGISTER failed status-0x%x", - status); - break; - } else - dbg("SCRATCH_PAD_REGISTER Writing success status%d", - status); - - /* Zero Length flag register */ - if ((mos7840_port->port_num != 1) - && (serial->num_ports == 2)) { - - Data = 0xff; - status = mos7840_set_reg_sync(serial->port[i], - (__u16) (ZLP_REG1 + - ((__u16)mos7840_port->port_num)), Data); - dbg("ZLIP offset %x", - (__u16) (ZLP_REG1 + - ((__u16) mos7840_port->port_num))); - if (status < 0) { - dbg("Writing ZLP_REG%d failed status-0x%x", - i + 2, status); - break; - } else - dbg("ZLP_REG%d Writing success status%d", - i + 2, status); - } else { - Data = 0xff; - status = mos7840_set_reg_sync(serial->port[i], - (__u16) (ZLP_REG1 + - ((__u16)mos7840_port->port_num) - 0x1), Data); - dbg("ZLIP offset %x", - (__u16) (ZLP_REG1 + - ((__u16) mos7840_port->port_num) - 0x1)); - if (status < 0) { - dbg("Writing ZLP_REG%d failed status-0x%x", - i + 1, status); - break; - } else - dbg("ZLP_REG%d Writing success status%d", - i + 1, status); - - } - mos7840_port->control_urb = usb_alloc_urb(0, GFP_KERNEL); - mos7840_port->ctrl_buf = kmalloc(16, GFP_KERNEL); - mos7840_port->dr = kmalloc(sizeof(struct usb_ctrlrequest), - GFP_KERNEL); - if (!mos7840_port->control_urb || !mos7840_port->ctrl_buf || - !mos7840_port->dr) { - status = -ENOMEM; - goto error; - } - } - dbg ("mos7840_startup: all ports configured..........."); - - /* Zero Length flag enable */ - Data = 0x0f; - status = mos7840_set_reg_sync(serial->port[0], ZLP_REG5, Data); - if (status < 0) { - dbg("Writing ZLP_REG5 failed status-0x%x", status); - goto error; - } else - dbg("ZLP_REG5 Writing success status%d", status); - - /* setting configuration feature to one */ - usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0), - (__u8) 0x03, 0x00, 0x01, 0x00, NULL, 0x00, 5 * HZ); - return 0; -error: - for (/* nothing */; i >= 0; i--) { - mos7840_port = mos7840_get_port_private(serial->port[i]); - - kfree(mos7840_port->dr); - kfree(mos7840_port->ctrl_buf); - usb_free_urb(mos7840_port->control_urb); - kfree(mos7840_port); - serial->port[i] = NULL; - } - return status; -} - -/**************************************************************************** - * mos7840_disconnect - * This function is called whenever the device is removed from the usb bus. - ****************************************************************************/ - -static void mos7840_disconnect(struct usb_serial *serial) -{ - int i; - unsigned long flags; - struct moschip_port *mos7840_port; - dbg("%s", " disconnect :entering.........."); - - if (!serial) { - dbg("%s", "Invalid Handler"); - return; - } - - /* check for the ports to be closed,close the ports and disconnect */ - - /* free private structure allocated for serial port * - * stop reads and writes on all ports */ - - for (i = 0; i < serial->num_ports; ++i) { - mos7840_port = mos7840_get_port_private(serial->port[i]); - dbg ("mos7840_port %d = %p", i, mos7840_port); - if (mos7840_port) { - spin_lock_irqsave(&mos7840_port->pool_lock, flags); - mos7840_port->zombie = 1; - spin_unlock_irqrestore(&mos7840_port->pool_lock, flags); - usb_kill_urb(mos7840_port->control_urb); - } - } - - dbg("%s", "Thank u :: "); - -} - -/**************************************************************************** - * mos7840_release - * This function is called when the usb_serial structure is freed. - ****************************************************************************/ - -static void mos7840_release(struct usb_serial *serial) -{ - int i; - struct moschip_port *mos7840_port; - dbg("%s", " release :entering.........."); - - if (!serial) { - dbg("%s", "Invalid Handler"); - return; - } - - /* check for the ports to be closed,close the ports and disconnect */ - - /* free private structure allocated for serial port * - * stop reads and writes on all ports */ - - for (i = 0; i < serial->num_ports; ++i) { - mos7840_port = mos7840_get_port_private(serial->port[i]); - dbg("mos7840_port %d = %p", i, mos7840_port); - if (mos7840_port) { - kfree(mos7840_port->ctrl_buf); - kfree(mos7840_port->dr); - kfree(mos7840_port); - } - } - - dbg("%s", "Thank u :: "); - -} - -static struct usb_driver io_driver = { - .name = "mos7840", - .probe = usb_serial_probe, - .disconnect = usb_serial_disconnect, - .id_table = moschip_id_table_combined, -}; - -static struct usb_serial_driver moschip7840_4port_device = { - .driver = { - .owner = THIS_MODULE, - .name = "mos7840", - }, - .description = DRIVER_DESC, - .id_table = moschip_port_id_table, - .num_ports = 4, - .open = mos7840_open, - .close = mos7840_close, - .write = mos7840_write, - .write_room = mos7840_write_room, - .chars_in_buffer = mos7840_chars_in_buffer, - .throttle = mos7840_throttle, - .unthrottle = mos7840_unthrottle, - .calc_num_ports = mos7840_calc_num_ports, -#ifdef MCSSerialProbe - .probe = mos7840_serial_probe, -#endif - .ioctl = mos7840_ioctl, - .set_termios = mos7840_set_termios, - .break_ctl = mos7840_break, - .tiocmget = mos7840_tiocmget, - .tiocmset = mos7840_tiocmset, - .get_icount = mos7840_get_icount, - .attach = mos7840_startup, - .disconnect = mos7840_disconnect, - .release = mos7840_release, - .read_bulk_callback = mos7840_bulk_in_callback, - .read_int_callback = mos7840_interrupt_callback, -}; - -static struct usb_serial_driver * const serial_drivers[] = { - &moschip7840_4port_device, NULL -}; - -module_usb_serial_driver(io_driver, serial_drivers); - -MODULE_DESCRIPTION(DRIVER_DESC); -MODULE_LICENSE("GPL"); - -module_param(debug, bool, S_IRUGO | S_IWUSR); -MODULE_PARM_DESC(debug, "Debug enabled or not"); diff --git a/ANDROID_3.4.5/drivers/usb/serial/moto_modem.c b/ANDROID_3.4.5/drivers/usb/serial/moto_modem.c deleted file mode 100644 index 3ab6214b..00000000 --- a/ANDROID_3.4.5/drivers/usb/serial/moto_modem.c +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Motorola USB Phone driver - * - * Copyright (C) 2008 Greg Kroah-Hartman <greg@kroah.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * {sigh} - * Motorola should be using the CDC ACM USB spec, but instead - * they try to just "do their own thing"... This driver should handle a - * few phones in which a basic "dumb serial connection" is needed to be - * able to get a connection through to them. - */ - -#include <linux/kernel.h> -#include <linux/init.h> -#include <linux/tty.h> -#include <linux/module.h> -#include <linux/usb.h> -#include <linux/usb/serial.h> - -static const struct usb_device_id id_table[] = { - { USB_DEVICE(0x05c6, 0x3197) }, /* unknown Motorola phone */ - { USB_DEVICE(0x0c44, 0x0022) }, /* unknown Mororola phone */ - { USB_DEVICE(0x22b8, 0x2a64) }, /* Motorola KRZR K1m */ - { USB_DEVICE(0x22b8, 0x2c84) }, /* Motorola VE240 phone */ - { USB_DEVICE(0x22b8, 0x2c64) }, /* Motorola V950 phone */ - { }, -}; -MODULE_DEVICE_TABLE(usb, id_table); - -static struct usb_driver moto_driver = { - .name = "moto-modem", - .probe = usb_serial_probe, - .disconnect = usb_serial_disconnect, - .id_table = id_table, -}; - -static struct usb_serial_driver moto_device = { - .driver = { - .owner = THIS_MODULE, - .name = "moto-modem", - }, - .id_table = id_table, - .num_ports = 1, -}; - -static struct usb_serial_driver * const serial_drivers[] = { - &moto_device, NULL -}; - -module_usb_serial_driver(moto_driver, serial_drivers); -MODULE_LICENSE("GPL"); diff --git a/ANDROID_3.4.5/drivers/usb/serial/navman.c b/ANDROID_3.4.5/drivers/usb/serial/navman.c deleted file mode 100644 index 29ab6eb5..00000000 --- a/ANDROID_3.4.5/drivers/usb/serial/navman.c +++ /dev/null @@ -1,140 +0,0 @@ -/* - * Navman Serial USB driver - * - * Copyright (C) 2006 Greg Kroah-Hartman <gregkh@suse.de> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * version 2 as published by the Free Software Foundation. - * - * TODO: - * Add termios method that uses copy_hw but also kills all echo - * flags as the navman is rx only so cannot echo. - */ - -#include <linux/gfp.h> -#include <linux/kernel.h> -#include <linux/init.h> -#include <linux/tty.h> -#include <linux/tty_flip.h> -#include <linux/module.h> -#include <linux/usb.h> -#include <linux/usb/serial.h> - -static bool debug; - -static const struct usb_device_id id_table[] = { - { USB_DEVICE(0x0a99, 0x0001) }, /* Talon Technology device */ - { USB_DEVICE(0x0df7, 0x0900) }, /* Mobile Action i-gotU */ - { }, -}; -MODULE_DEVICE_TABLE(usb, id_table); - -static struct usb_driver navman_driver = { - .name = "navman", - .probe = usb_serial_probe, - .disconnect = usb_serial_disconnect, - .id_table = id_table, -}; - -static void navman_read_int_callback(struct urb *urb) -{ - struct usb_serial_port *port = urb->context; - unsigned char *data = urb->transfer_buffer; - struct tty_struct *tty; - int status = urb->status; - int result; - - switch (status) { - case 0: - /* success */ - break; - case -ECONNRESET: - case -ENOENT: - case -ESHUTDOWN: - /* this urb is terminated, clean up */ - dbg("%s - urb shutting down with status: %d", - __func__, status); - return; - default: - dbg("%s - nonzero urb status received: %d", - __func__, status); - goto exit; - } - - usb_serial_debug_data(debug, &port->dev, __func__, - urb->actual_length, data); - - tty = tty_port_tty_get(&port->port); - if (tty && urb->actual_length) { - tty_insert_flip_string(tty, data, urb->actual_length); - tty_flip_buffer_push(tty); - } - tty_kref_put(tty); - -exit: - result = usb_submit_urb(urb, GFP_ATOMIC); - if (result) - dev_err(&urb->dev->dev, - "%s - Error %d submitting interrupt urb\n", - __func__, result); -} - -static int navman_open(struct tty_struct *tty, struct usb_serial_port *port) -{ - int result = 0; - - dbg("%s - port %d", __func__, port->number); - - if (port->interrupt_in_urb) { - dbg("%s - adding interrupt input for treo", __func__); - result = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL); - if (result) - dev_err(&port->dev, - "%s - failed submitting interrupt urb, error %d\n", - __func__, result); - } - return result; -} - -static void navman_close(struct usb_serial_port *port) -{ - dbg("%s - port %d", __func__, port->number); - - usb_kill_urb(port->interrupt_in_urb); -} - -static int navman_write(struct tty_struct *tty, struct usb_serial_port *port, - const unsigned char *buf, int count) -{ - dbg("%s - port %d", __func__, port->number); - - /* - * This device can't write any data, only read from the device - */ - return -EOPNOTSUPP; -} - -static struct usb_serial_driver navman_device = { - .driver = { - .owner = THIS_MODULE, - .name = "navman", - }, - .id_table = id_table, - .num_ports = 1, - .open = navman_open, - .close = navman_close, - .write = navman_write, - .read_int_callback = navman_read_int_callback, -}; - -static struct usb_serial_driver * const serial_drivers[] = { - &navman_device, NULL -}; - -module_usb_serial_driver(navman_driver, serial_drivers); - -MODULE_LICENSE("GPL"); - -module_param(debug, bool, S_IRUGO | S_IWUSR); -MODULE_PARM_DESC(debug, "Debug enabled or not"); diff --git a/ANDROID_3.4.5/drivers/usb/serial/omninet.c b/ANDROID_3.4.5/drivers/usb/serial/omninet.c deleted file mode 100644 index 88dc785b..00000000 --- a/ANDROID_3.4.5/drivers/usb/serial/omninet.c +++ /dev/null @@ -1,331 +0,0 @@ -/* - * USB ZyXEL omni.net LCD PLUS driver - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License version - * 2 as published by the Free Software Foundation. - * - * See Documentation/usb/usb-serial.txt for more information on using this - * driver - * - * Please report both successes and troubles to the author at omninet@kroah.com - */ - -#include <linux/kernel.h> -#include <linux/errno.h> -#include <linux/init.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/uaccess.h> -#include <linux/usb.h> -#include <linux/usb/serial.h> - -static bool debug; - -/* - * Version Information - */ -#define DRIVER_VERSION "v1.1" -#define DRIVER_AUTHOR "Alessandro Zummo" -#define DRIVER_DESC "USB ZyXEL omni.net LCD PLUS Driver" - -#define ZYXEL_VENDOR_ID 0x0586 -#define ZYXEL_OMNINET_ID 0x1000 -/* This one seems to be a re-branded ZyXEL device */ -#define BT_IGNITIONPRO_ID 0x2000 - -/* function prototypes */ -static int omninet_open(struct tty_struct *tty, struct usb_serial_port *port); -static void omninet_close(struct usb_serial_port *port); -static void omninet_read_bulk_callback(struct urb *urb); -static void omninet_write_bulk_callback(struct urb *urb); -static int omninet_write(struct tty_struct *tty, struct usb_serial_port *port, - const unsigned char *buf, int count); -static int omninet_write_room(struct tty_struct *tty); -static void omninet_disconnect(struct usb_serial *serial); -static void omninet_release(struct usb_serial *serial); -static int omninet_attach(struct usb_serial *serial); - -static const struct usb_device_id id_table[] = { - { USB_DEVICE(ZYXEL_VENDOR_ID, ZYXEL_OMNINET_ID) }, - { USB_DEVICE(ZYXEL_VENDOR_ID, BT_IGNITIONPRO_ID) }, - { } /* Terminating entry */ -}; - -MODULE_DEVICE_TABLE(usb, id_table); - -static struct usb_driver omninet_driver = { - .name = "omninet", - .probe = usb_serial_probe, - .disconnect = usb_serial_disconnect, - .id_table = id_table, -}; - - -static struct usb_serial_driver zyxel_omninet_device = { - .driver = { - .owner = THIS_MODULE, - .name = "omninet", - }, - .description = "ZyXEL - omni.net lcd plus usb", - .id_table = id_table, - .num_ports = 1, - .attach = omninet_attach, - .open = omninet_open, - .close = omninet_close, - .write = omninet_write, - .write_room = omninet_write_room, - .read_bulk_callback = omninet_read_bulk_callback, - .write_bulk_callback = omninet_write_bulk_callback, - .disconnect = omninet_disconnect, - .release = omninet_release, -}; - -static struct usb_serial_driver * const serial_drivers[] = { - &zyxel_omninet_device, NULL -}; - - -/* The protocol. - * - * The omni.net always exchange 64 bytes of data with the host. The first - * four bytes are the control header, you can see it in the above structure. - * - * oh_seq is a sequence number. Don't know if/how it's used. - * oh_len is the length of the data bytes in the packet. - * oh_xxx Bit-mapped, related to handshaking and status info. - * I normally set it to 0x03 in trasmitted frames. - * 7: Active when the TA is in a CONNECTed state. - * 6: unknown - * 5: handshaking, unknown - * 4: handshaking, unknown - * 3: unknown, usually 0 - * 2: unknown, usually 0 - * 1: handshaking, unknown, usually set to 1 in trasmitted frames - * 0: handshaking, unknown, usually set to 1 in trasmitted frames - * oh_pad Probably a pad byte. - * - * After the header you will find data bytes if oh_len was greater than zero. - * - */ - -struct omninet_header { - __u8 oh_seq; - __u8 oh_len; - __u8 oh_xxx; - __u8 oh_pad; -}; - -struct omninet_data { - __u8 od_outseq; /* Sequence number for bulk_out URBs */ -}; - -static int omninet_attach(struct usb_serial *serial) -{ - struct omninet_data *od; - struct usb_serial_port *port = serial->port[0]; - - od = kmalloc(sizeof(struct omninet_data), GFP_KERNEL); - if (!od) { - dev_err(&port->dev, "%s- kmalloc(%Zd) failed.\n", - __func__, sizeof(struct omninet_data)); - return -ENOMEM; - } - usb_set_serial_port_data(port, od); - return 0; -} - -static int omninet_open(struct tty_struct *tty, struct usb_serial_port *port) -{ - struct usb_serial *serial = port->serial; - struct usb_serial_port *wport; - int result = 0; - - dbg("%s - port %d", __func__, port->number); - - wport = serial->port[1]; - tty_port_tty_set(&wport->port, tty); - - /* Start reading from the device */ - result = usb_submit_urb(port->read_urb, GFP_KERNEL); - if (result) - dev_err(&port->dev, - "%s - failed submitting read urb, error %d\n", - __func__, result); - return result; -} - -static void omninet_close(struct usb_serial_port *port) -{ - dbg("%s - port %d", __func__, port->number); - usb_kill_urb(port->read_urb); -} - - -#define OMNINET_DATAOFFSET 0x04 -#define OMNINET_HEADERLEN sizeof(struct omninet_header) -#define OMNINET_BULKOUTSIZE (64 - OMNINET_HEADERLEN) - -static void omninet_read_bulk_callback(struct urb *urb) -{ - struct usb_serial_port *port = urb->context; - unsigned char *data = urb->transfer_buffer; - struct omninet_header *header = (struct omninet_header *) &data[0]; - int status = urb->status; - int result; - int i; - - dbg("%s - port %d", __func__, port->number); - - if (status) { - dbg("%s - nonzero read bulk status received: %d", - __func__, status); - return; - } - - if (debug && header->oh_xxx != 0x30) { - if (urb->actual_length) { - printk(KERN_DEBUG "%s: omninet_read %d: ", - __FILE__, header->oh_len); - for (i = 0; i < (header->oh_len + - OMNINET_HEADERLEN); i++) - printk("%.2x ", data[i]); - printk("\n"); - } - } - - if (urb->actual_length && header->oh_len) { - struct tty_struct *tty = tty_port_tty_get(&port->port); - tty_insert_flip_string(tty, data + OMNINET_DATAOFFSET, - header->oh_len); - tty_flip_buffer_push(tty); - tty_kref_put(tty); - } - - /* Continue trying to always read */ - result = usb_submit_urb(urb, GFP_ATOMIC); - if (result) - dev_err(&port->dev, - "%s - failed resubmitting read urb, error %d\n", - __func__, result); -} - -static int omninet_write(struct tty_struct *tty, struct usb_serial_port *port, - const unsigned char *buf, int count) -{ - struct usb_serial *serial = port->serial; - struct usb_serial_port *wport = serial->port[1]; - - struct omninet_data *od = usb_get_serial_port_data(port); - struct omninet_header *header = (struct omninet_header *) - wport->write_urb->transfer_buffer; - - int result; - - dbg("%s - port %d", __func__, port->number); - - if (count == 0) { - dbg("%s - write request of 0 bytes", __func__); - return 0; - } - - if (!test_and_clear_bit(0, &port->write_urbs_free)) { - dbg("%s - already writing", __func__); - return 0; - } - - count = (count > OMNINET_BULKOUTSIZE) ? OMNINET_BULKOUTSIZE : count; - - memcpy(wport->write_urb->transfer_buffer + OMNINET_DATAOFFSET, - buf, count); - - usb_serial_debug_data(debug, &port->dev, __func__, count, - wport->write_urb->transfer_buffer); - - header->oh_seq = od->od_outseq++; - header->oh_len = count; - header->oh_xxx = 0x03; - header->oh_pad = 0x00; - - /* send the data out the bulk port, always 64 bytes */ - wport->write_urb->transfer_buffer_length = 64; - - result = usb_submit_urb(wport->write_urb, GFP_ATOMIC); - if (result) { - set_bit(0, &wport->write_urbs_free); - dev_err_console(port, - "%s - failed submitting write urb, error %d\n", - __func__, result); - } else - result = count; - - return result; -} - - -static int omninet_write_room(struct tty_struct *tty) -{ - struct usb_serial_port *port = tty->driver_data; - struct usb_serial *serial = port->serial; - struct usb_serial_port *wport = serial->port[1]; - - int room = 0; /* Default: no room */ - - if (test_bit(0, &wport->write_urbs_free)) - room = wport->bulk_out_size - OMNINET_HEADERLEN; - - dbg("%s - returns %d", __func__, room); - - return room; -} - -static void omninet_write_bulk_callback(struct urb *urb) -{ -/* struct omninet_header *header = (struct omninet_header *) - urb->transfer_buffer; */ - struct usb_serial_port *port = urb->context; - int status = urb->status; - - dbg("%s - port %0x", __func__, port->number); - - set_bit(0, &port->write_urbs_free); - if (status) { - dbg("%s - nonzero write bulk status received: %d", - __func__, status); - return; - } - - usb_serial_port_softint(port); -} - - -static void omninet_disconnect(struct usb_serial *serial) -{ - struct usb_serial_port *wport = serial->port[1]; - - dbg("%s", __func__); - - usb_kill_urb(wport->write_urb); -} - - -static void omninet_release(struct usb_serial *serial) -{ - struct usb_serial_port *port = serial->port[0]; - - dbg("%s", __func__); - - kfree(usb_get_serial_port_data(port)); -} - -module_usb_serial_driver(omninet_driver, serial_drivers); - -MODULE_AUTHOR(DRIVER_AUTHOR); -MODULE_DESCRIPTION(DRIVER_DESC); -MODULE_LICENSE("GPL"); - -module_param(debug, bool, S_IRUGO | S_IWUSR); -MODULE_PARM_DESC(debug, "Debug enabled or not"); diff --git a/ANDROID_3.4.5/drivers/usb/serial/opticon.c b/ANDROID_3.4.5/drivers/usb/serial/opticon.c deleted file mode 100644 index 82cc9d20..00000000 --- a/ANDROID_3.4.5/drivers/usb/serial/opticon.c +++ /dev/null @@ -1,640 +0,0 @@ -/* - * Opticon USB barcode to serial driver - * - * Copyright (C) 2011 Martin Jansen <martin.jansen@opticon.com> - * Copyright (C) 2008 - 2009 Greg Kroah-Hartman <gregkh@suse.de> - * Copyright (C) 2008 - 2009 Novell Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License version - * 2 as published by the Free Software Foundation. - */ - -#include <linux/kernel.h> -#include <linux/init.h> -#include <linux/tty.h> -#include <linux/tty_driver.h> -#include <linux/slab.h> -#include <linux/tty_flip.h> -#include <linux/serial.h> -#include <linux/module.h> -#include <linux/usb.h> -#include <linux/usb/serial.h> -#include <linux/uaccess.h> - -#define CONTROL_RTS 0x02 -#define RESEND_CTS_STATE 0x03 - -/* max number of write urbs in flight */ -#define URB_UPPER_LIMIT 8 - -/* This driver works for the Opticon 1D barcode reader - * an examples of 1D barcode types are EAN, UPC, Code39, IATA etc.. */ -#define DRIVER_DESC "Opticon USB barcode to serial driver (1D)" - -static bool debug; - -static const struct usb_device_id id_table[] = { - { USB_DEVICE(0x065a, 0x0009) }, - { }, -}; -MODULE_DEVICE_TABLE(usb, id_table); - -/* This structure holds all of the individual device information */ -struct opticon_private { - struct usb_device *udev; - struct usb_serial *serial; - struct usb_serial_port *port; - unsigned char *bulk_in_buffer; - struct urb *bulk_read_urb; - int buffer_size; - u8 bulk_address; - spinlock_t lock; /* protects the following flags */ - bool throttled; - bool actually_throttled; - bool rts; - bool cts; - int outstanding_urbs; -}; - - - -static void opticon_read_bulk_callback(struct urb *urb) -{ - struct opticon_private *priv = urb->context; - unsigned char *data = urb->transfer_buffer; - struct usb_serial_port *port = priv->port; - int status = urb->status; - struct tty_struct *tty; - int result; - int data_length; - unsigned long flags; - - dbg("%s - port %d", __func__, port->number); - - switch (status) { - case 0: - /* success */ - break; - case -ECONNRESET: - case -ENOENT: - case -ESHUTDOWN: - /* this urb is terminated, clean up */ - dbg("%s - urb shutting down with status: %d", - __func__, status); - return; - default: - dbg("%s - nonzero urb status received: %d", - __func__, status); - goto exit; - } - - usb_serial_debug_data(debug, &port->dev, __func__, urb->actual_length, - data); - - if (urb->actual_length > 2) { - data_length = urb->actual_length - 2; - - /* - * Data from the device comes with a 2 byte header: - * - * <0x00><0x00>data... - * This is real data to be sent to the tty layer - * <0x00><0x01)level - * This is a CTS level change, the third byte is the CTS - * value (0 for low, 1 for high). - */ - if ((data[0] == 0x00) && (data[1] == 0x00)) { - /* real data, send it to the tty layer */ - tty = tty_port_tty_get(&port->port); - if (tty) { - tty_insert_flip_string(tty, data + 2, - data_length); - tty_flip_buffer_push(tty); - tty_kref_put(tty); - } - } else { - if ((data[0] == 0x00) && (data[1] == 0x01)) { - spin_lock_irqsave(&priv->lock, flags); - /* CTS status information package */ - if (data[2] == 0x00) - priv->cts = false; - else - priv->cts = true; - spin_unlock_irqrestore(&priv->lock, flags); - } else { - dev_dbg(&priv->udev->dev, - "Unknown data packet received from the device:" - " %2x %2x\n", - data[0], data[1]); - } - } - } else { - dev_dbg(&priv->udev->dev, - "Improper amount of data received from the device, " - "%d bytes", urb->actual_length); - } - -exit: - spin_lock(&priv->lock); - - /* Continue trying to always read if we should */ - if (!priv->throttled) { - usb_fill_bulk_urb(priv->bulk_read_urb, priv->udev, - usb_rcvbulkpipe(priv->udev, - priv->bulk_address), - priv->bulk_in_buffer, priv->buffer_size, - opticon_read_bulk_callback, priv); - result = usb_submit_urb(priv->bulk_read_urb, GFP_ATOMIC); - if (result) - dev_err(&port->dev, - "%s - failed resubmitting read urb, error %d\n", - __func__, result); - } else - priv->actually_throttled = true; - spin_unlock(&priv->lock); -} - -static int send_control_msg(struct usb_serial_port *port, u8 requesttype, - u8 val) -{ - struct usb_serial *serial = port->serial; - int retval; - u8 buffer[2]; - - buffer[0] = val; - /* Send the message to the vendor control endpoint - * of the connected device */ - retval = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0), - requesttype, - USB_DIR_OUT|USB_TYPE_VENDOR|USB_RECIP_INTERFACE, - 0, 0, buffer, 1, 0); - - return retval; -} - -static int opticon_open(struct tty_struct *tty, struct usb_serial_port *port) -{ - struct opticon_private *priv = usb_get_serial_data(port->serial); - unsigned long flags; - int result = 0; - - dbg("%s - port %d", __func__, port->number); - - spin_lock_irqsave(&priv->lock, flags); - priv->throttled = false; - priv->actually_throttled = false; - priv->port = port; - priv->rts = false; - spin_unlock_irqrestore(&priv->lock, flags); - - /* Clear RTS line */ - send_control_msg(port, CONTROL_RTS, 0); - - /* Setup the read URB and start reading from the device */ - usb_fill_bulk_urb(priv->bulk_read_urb, priv->udev, - usb_rcvbulkpipe(priv->udev, - priv->bulk_address), - priv->bulk_in_buffer, priv->buffer_size, - opticon_read_bulk_callback, priv); - - /* clear the halt status of the enpoint */ - usb_clear_halt(priv->udev, priv->bulk_read_urb->pipe); - - result = usb_submit_urb(priv->bulk_read_urb, GFP_KERNEL); - if (result) - dev_err(&port->dev, - "%s - failed resubmitting read urb, error %d\n", - __func__, result); - /* Request CTS line state, sometimes during opening the current - * CTS state can be missed. */ - send_control_msg(port, RESEND_CTS_STATE, 1); - return result; -} - -static void opticon_close(struct usb_serial_port *port) -{ - struct opticon_private *priv = usb_get_serial_data(port->serial); - - dbg("%s - port %d", __func__, port->number); - - /* shutdown our urbs */ - usb_kill_urb(priv->bulk_read_urb); -} - -static void opticon_write_control_callback(struct urb *urb) -{ - struct opticon_private *priv = urb->context; - int status = urb->status; - unsigned long flags; - - /* free up the transfer buffer, as usb_free_urb() does not do this */ - kfree(urb->transfer_buffer); - - /* setup packet may be set if we're using it for writing */ - kfree(urb->setup_packet); - - if (status) - dbg("%s - nonzero write bulk status received: %d", - __func__, status); - - spin_lock_irqsave(&priv->lock, flags); - --priv->outstanding_urbs; - spin_unlock_irqrestore(&priv->lock, flags); - - usb_serial_port_softint(priv->port); -} - -static int opticon_write(struct tty_struct *tty, struct usb_serial_port *port, - const unsigned char *buf, int count) -{ - struct opticon_private *priv = usb_get_serial_data(port->serial); - struct usb_serial *serial = port->serial; - struct urb *urb; - unsigned char *buffer; - unsigned long flags; - int status; - struct usb_ctrlrequest *dr; - - dbg("%s - port %d", __func__, port->number); - - spin_lock_irqsave(&priv->lock, flags); - if (priv->outstanding_urbs > URB_UPPER_LIMIT) { - spin_unlock_irqrestore(&priv->lock, flags); - dbg("%s - write limit hit", __func__); - return 0; - } - priv->outstanding_urbs++; - spin_unlock_irqrestore(&priv->lock, flags); - - buffer = kmalloc(count, GFP_ATOMIC); - if (!buffer) { - dev_err(&port->dev, "out of memory\n"); - count = -ENOMEM; - - goto error_no_buffer; - } - - urb = usb_alloc_urb(0, GFP_ATOMIC); - if (!urb) { - dev_err(&port->dev, "no more free urbs\n"); - count = -ENOMEM; - goto error_no_urb; - } - - memcpy(buffer, buf, count); - - usb_serial_debug_data(debug, &port->dev, __func__, count, buffer); - - /* The conncected devices do not have a bulk write endpoint, - * to transmit data to de barcode device the control endpoint is used */ - dr = kmalloc(sizeof(struct usb_ctrlrequest), GFP_NOIO); - if (!dr) { - dev_err(&port->dev, "out of memory\n"); - count = -ENOMEM; - goto error; - } - - dr->bRequestType = USB_TYPE_VENDOR | USB_RECIP_INTERFACE | USB_DIR_OUT; - dr->bRequest = 0x01; - dr->wValue = 0; - dr->wIndex = 0; - dr->wLength = cpu_to_le16(count); - - usb_fill_control_urb(urb, serial->dev, - usb_sndctrlpipe(serial->dev, 0), - (unsigned char *)dr, buffer, count, - opticon_write_control_callback, priv); - - /* send it down the pipe */ - status = usb_submit_urb(urb, GFP_ATOMIC); - if (status) { - dev_err(&port->dev, - "%s - usb_submit_urb(write endpoint) failed status = %d\n", - __func__, status); - count = status; - goto error; - } - - /* we are done with this urb, so let the host driver - * really free it when it is finished with it */ - usb_free_urb(urb); - - return count; -error: - usb_free_urb(urb); -error_no_urb: - kfree(buffer); -error_no_buffer: - spin_lock_irqsave(&priv->lock, flags); - --priv->outstanding_urbs; - spin_unlock_irqrestore(&priv->lock, flags); - return count; -} - -static int opticon_write_room(struct tty_struct *tty) -{ - struct usb_serial_port *port = tty->driver_data; - struct opticon_private *priv = usb_get_serial_data(port->serial); - unsigned long flags; - - dbg("%s - port %d", __func__, port->number); - - /* - * We really can take almost anything the user throws at us - * but let's pick a nice big number to tell the tty - * layer that we have lots of free space, unless we don't. - */ - spin_lock_irqsave(&priv->lock, flags); - if (priv->outstanding_urbs > URB_UPPER_LIMIT * 2 / 3) { - spin_unlock_irqrestore(&priv->lock, flags); - dbg("%s - write limit hit", __func__); - return 0; - } - spin_unlock_irqrestore(&priv->lock, flags); - - return 2048; -} - -static void opticon_throttle(struct tty_struct *tty) -{ - struct usb_serial_port *port = tty->driver_data; - struct opticon_private *priv = usb_get_serial_data(port->serial); - unsigned long flags; - - dbg("%s - port %d", __func__, port->number); - spin_lock_irqsave(&priv->lock, flags); - priv->throttled = true; - spin_unlock_irqrestore(&priv->lock, flags); -} - - -static void opticon_unthrottle(struct tty_struct *tty) -{ - struct usb_serial_port *port = tty->driver_data; - struct opticon_private *priv = usb_get_serial_data(port->serial); - unsigned long flags; - int result, was_throttled; - - dbg("%s - port %d", __func__, port->number); - - spin_lock_irqsave(&priv->lock, flags); - priv->throttled = false; - was_throttled = priv->actually_throttled; - priv->actually_throttled = false; - spin_unlock_irqrestore(&priv->lock, flags); - - if (was_throttled) { - result = usb_submit_urb(priv->bulk_read_urb, GFP_ATOMIC); - if (result) - dev_err(&port->dev, - "%s - failed submitting read urb, error %d\n", - __func__, result); - } -} - -static int opticon_tiocmget(struct tty_struct *tty) -{ - struct usb_serial_port *port = tty->driver_data; - struct opticon_private *priv = usb_get_serial_data(port->serial); - unsigned long flags; - int result = 0; - - dbg("%s - port %d", __func__, port->number); - if (!usb_get_intfdata(port->serial->interface)) - return -ENODEV; - - spin_lock_irqsave(&priv->lock, flags); - if (priv->rts) - result |= TIOCM_RTS; - if (priv->cts) - result |= TIOCM_CTS; - spin_unlock_irqrestore(&priv->lock, flags); - - dbg("%s - %x", __func__, result); - return result; -} - -static int opticon_tiocmset(struct tty_struct *tty, - unsigned int set, unsigned int clear) -{ - struct usb_serial_port *port = tty->driver_data; - struct opticon_private *priv = usb_get_serial_data(port->serial); - unsigned long flags; - bool rts; - bool changed = false; - - if (!usb_get_intfdata(port->serial->interface)) - return -ENODEV; - /* We only support RTS so we only handle that */ - spin_lock_irqsave(&priv->lock, flags); - - rts = priv->rts; - if (set & TIOCM_RTS) - priv->rts = true; - if (clear & TIOCM_RTS) - priv->rts = false; - changed = rts ^ priv->rts; - spin_unlock_irqrestore(&priv->lock, flags); - - if (!changed) - return 0; - - /* Send the new RTS state to the connected device */ - return send_control_msg(port, CONTROL_RTS, !rts); -} - -static int get_serial_info(struct opticon_private *priv, - struct serial_struct __user *serial) -{ - struct serial_struct tmp; - - if (!serial) - return -EFAULT; - - memset(&tmp, 0x00, sizeof(tmp)); - - /* fake emulate a 16550 uart to make userspace code happy */ - tmp.type = PORT_16550A; - tmp.line = priv->serial->minor; - tmp.port = 0; - tmp.irq = 0; - tmp.flags = ASYNC_SKIP_TEST | ASYNC_AUTO_IRQ; - tmp.xmit_fifo_size = 1024; - tmp.baud_base = 9600; - tmp.close_delay = 5*HZ; - tmp.closing_wait = 30*HZ; - - if (copy_to_user(serial, &tmp, sizeof(*serial))) - return -EFAULT; - return 0; -} - -static int opticon_ioctl(struct tty_struct *tty, - unsigned int cmd, unsigned long arg) -{ - struct usb_serial_port *port = tty->driver_data; - struct opticon_private *priv = usb_get_serial_data(port->serial); - - dbg("%s - port %d, cmd = 0x%x", __func__, port->number, cmd); - - switch (cmd) { - case TIOCGSERIAL: - return get_serial_info(priv, - (struct serial_struct __user *)arg); - } - - return -ENOIOCTLCMD; -} - -static int opticon_startup(struct usb_serial *serial) -{ - struct opticon_private *priv; - struct usb_host_interface *intf; - int i; - int retval = -ENOMEM; - bool bulk_in_found = false; - - /* create our private serial structure */ - priv = kzalloc(sizeof(*priv), GFP_KERNEL); - if (priv == NULL) { - dev_err(&serial->dev->dev, "%s - Out of memory\n", __func__); - return -ENOMEM; - } - spin_lock_init(&priv->lock); - priv->serial = serial; - priv->port = serial->port[0]; - priv->udev = serial->dev; - priv->outstanding_urbs = 0; /* Init the outstanding urbs */ - - /* find our bulk endpoint */ - intf = serial->interface->altsetting; - for (i = 0; i < intf->desc.bNumEndpoints; ++i) { - struct usb_endpoint_descriptor *endpoint; - - endpoint = &intf->endpoint[i].desc; - if (!usb_endpoint_is_bulk_in(endpoint)) - continue; - - priv->bulk_read_urb = usb_alloc_urb(0, GFP_KERNEL); - if (!priv->bulk_read_urb) { - dev_err(&priv->udev->dev, "out of memory\n"); - goto error; - } - - priv->buffer_size = usb_endpoint_maxp(endpoint) * 2; - priv->bulk_in_buffer = kmalloc(priv->buffer_size, GFP_KERNEL); - if (!priv->bulk_in_buffer) { - dev_err(&priv->udev->dev, "out of memory\n"); - goto error; - } - - priv->bulk_address = endpoint->bEndpointAddress; - - bulk_in_found = true; - break; - } - - if (!bulk_in_found) { - dev_err(&priv->udev->dev, - "Error - the proper endpoints were not found!\n"); - goto error; - } - - usb_set_serial_data(serial, priv); - return 0; - -error: - usb_free_urb(priv->bulk_read_urb); - kfree(priv->bulk_in_buffer); - kfree(priv); - return retval; -} - -static void opticon_disconnect(struct usb_serial *serial) -{ - struct opticon_private *priv = usb_get_serial_data(serial); - - dbg("%s", __func__); - - usb_kill_urb(priv->bulk_read_urb); - usb_free_urb(priv->bulk_read_urb); -} - -static void opticon_release(struct usb_serial *serial) -{ - struct opticon_private *priv = usb_get_serial_data(serial); - - dbg("%s", __func__); - - kfree(priv->bulk_in_buffer); - kfree(priv); -} - -static int opticon_suspend(struct usb_interface *intf, pm_message_t message) -{ - struct usb_serial *serial = usb_get_intfdata(intf); - struct opticon_private *priv = usb_get_serial_data(serial); - - usb_kill_urb(priv->bulk_read_urb); - return 0; -} - -static int opticon_resume(struct usb_interface *intf) -{ - struct usb_serial *serial = usb_get_intfdata(intf); - struct opticon_private *priv = usb_get_serial_data(serial); - struct usb_serial_port *port = serial->port[0]; - int result; - - mutex_lock(&port->port.mutex); - /* This is protected by the port mutex against close/open */ - if (test_bit(ASYNCB_INITIALIZED, &port->port.flags)) - result = usb_submit_urb(priv->bulk_read_urb, GFP_NOIO); - else - result = 0; - mutex_unlock(&port->port.mutex); - return result; -} - -static struct usb_driver opticon_driver = { - .name = "opticon", - .probe = usb_serial_probe, - .disconnect = usb_serial_disconnect, - .suspend = opticon_suspend, - .resume = opticon_resume, - .id_table = id_table, -}; - -static struct usb_serial_driver opticon_device = { - .driver = { - .owner = THIS_MODULE, - .name = "opticon", - }, - .id_table = id_table, - .num_ports = 1, - .attach = opticon_startup, - .open = opticon_open, - .close = opticon_close, - .write = opticon_write, - .write_room = opticon_write_room, - .disconnect = opticon_disconnect, - .release = opticon_release, - .throttle = opticon_throttle, - .unthrottle = opticon_unthrottle, - .ioctl = opticon_ioctl, - .tiocmget = opticon_tiocmget, - .tiocmset = opticon_tiocmset, -}; - -static struct usb_serial_driver * const serial_drivers[] = { - &opticon_device, NULL -}; - -module_usb_serial_driver(opticon_driver, serial_drivers); - -MODULE_DESCRIPTION(DRIVER_DESC); -MODULE_LICENSE("GPL"); - -module_param(debug, bool, S_IRUGO | S_IWUSR); -MODULE_PARM_DESC(debug, "Debug enabled or not"); diff --git a/ANDROID_3.4.5/drivers/usb/serial/option.c b/ANDROID_3.4.5/drivers/usb/serial/option.c deleted file mode 100644 index 82d5ecf9..00000000 --- a/ANDROID_3.4.5/drivers/usb/serial/option.c +++ /dev/null @@ -1,1556 +0,0 @@ -/* - USB Driver for GSM modems - - Copyright (C) 2005 Matthias Urlichs <smurf@smurf.noris.de> - - This driver is free software; you can redistribute it and/or modify - it under the terms of Version 2 of the GNU General Public License as - published by the Free Software Foundation. - - Portions copied from the Keyspan driver by Hugh Blemings <hugh@blemings.org> - - History: see the git log. - - Work sponsored by: Sigos GmbH, Germany <info@sigos.de> - - This driver exists because the "normal" serial driver doesn't work too well - with GSM modems. Issues: - - data loss -- one single Receive URB is not nearly enough - - nonstandard flow (Option devices) control - - controlling the baud rate doesn't make sense - - This driver is named "option" because the most common device it's - used for is a PC-Card (with an internal OHCI-USB interface, behind - which the GSM interface sits), made by Option Inc. - - Some of the "one port" devices actually exhibit multiple USB instances - on the USB bus. This is not a bug, these ports are used for different - device features. -*/ - -#define DRIVER_VERSION "v0.7.2" -#define DRIVER_AUTHOR "Matthias Urlichs <smurf@smurf.noris.de>" -#define DRIVER_DESC "USB Driver for GSM modems" - -#include <linux/kernel.h> -#include <linux/jiffies.h> -#include <linux/errno.h> -#include <linux/tty.h> -#include <linux/tty_flip.h> -#include <linux/slab.h> -#include <linux/module.h> -#include <linux/bitops.h> -#include <linux/usb.h> -#include <linux/usb/serial.h> -#include "usb-wwan.h" - -/* Function prototypes */ -static int option_probe(struct usb_serial *serial, - const struct usb_device_id *id); -static void option_release(struct usb_serial *serial); -static int option_send_setup(struct usb_serial_port *port); -static void option_instat_callback(struct urb *urb); -/* VIA-Telecom CBP(Non-CDC version) IDs */ -#define VIATELECOM_VENDOR_ID 0x15EB -#define VIATELECOM_PRODUCT_ID 0x0001 -#define BORA9380_VENDOR_ID 0x16d8 -#define BORA9380_PRODUCT_ID 0x4000 - -/* Vendor and product IDs */ -#define OPTION_VENDOR_ID 0x0AF0 -#define OPTION_PRODUCT_COLT 0x5000 -#define OPTION_PRODUCT_RICOLA 0x6000 -#define OPTION_PRODUCT_RICOLA_LIGHT 0x6100 -#define OPTION_PRODUCT_RICOLA_QUAD 0x6200 -#define OPTION_PRODUCT_RICOLA_QUAD_LIGHT 0x6300 -#define OPTION_PRODUCT_RICOLA_NDIS 0x6050 -#define OPTION_PRODUCT_RICOLA_NDIS_LIGHT 0x6150 -#define OPTION_PRODUCT_RICOLA_NDIS_QUAD 0x6250 -#define OPTION_PRODUCT_RICOLA_NDIS_QUAD_LIGHT 0x6350 -#define OPTION_PRODUCT_COBRA 0x6500 -#define OPTION_PRODUCT_COBRA_BUS 0x6501 -#define OPTION_PRODUCT_VIPER 0x6600 -#define OPTION_PRODUCT_VIPER_BUS 0x6601 -#define OPTION_PRODUCT_GT_MAX_READY 0x6701 -#define OPTION_PRODUCT_FUJI_MODEM_LIGHT 0x6721 -#define OPTION_PRODUCT_FUJI_MODEM_GT 0x6741 -#define OPTION_PRODUCT_FUJI_MODEM_EX 0x6761 -#define OPTION_PRODUCT_KOI_MODEM 0x6800 -#define OPTION_PRODUCT_SCORPION_MODEM 0x6901 -#define OPTION_PRODUCT_ETNA_MODEM 0x7001 -#define OPTION_PRODUCT_ETNA_MODEM_LITE 0x7021 -#define OPTION_PRODUCT_ETNA_MODEM_GT 0x7041 -#define OPTION_PRODUCT_ETNA_MODEM_EX 0x7061 -#define OPTION_PRODUCT_ETNA_KOI_MODEM 0x7100 -#define OPTION_PRODUCT_GTM380_MODEM 0x7201 - -#define HUAWEI_VENDOR_ID 0x12D1 -#define HUAWEI_PRODUCT_E600 0x1001 -#define HUAWEI_PRODUCT_E220 0x1003 -#define HUAWEI_PRODUCT_E220BIS 0x1004 -#define HUAWEI_PRODUCT_E1401 0x1401 -#define HUAWEI_PRODUCT_E1402 0x1402 -#define HUAWEI_PRODUCT_E1403 0x1403 -#define HUAWEI_PRODUCT_E1404 0x1404 -#define HUAWEI_PRODUCT_E1405 0x1405 -#define HUAWEI_PRODUCT_E1406 0x1406 -#define HUAWEI_PRODUCT_E1407 0x1407 -#define HUAWEI_PRODUCT_E1408 0x1408 -#define HUAWEI_PRODUCT_E1409 0x1409 -#define HUAWEI_PRODUCT_E140A 0x140A -#define HUAWEI_PRODUCT_E140B 0x140B -#define HUAWEI_PRODUCT_E140C 0x140C -#define HUAWEI_PRODUCT_E140D 0x140D -#define HUAWEI_PRODUCT_E140E 0x140E -#define HUAWEI_PRODUCT_E140F 0x140F -#define HUAWEI_PRODUCT_E1410 0x1410 -#define HUAWEI_PRODUCT_E1411 0x1411 -#define HUAWEI_PRODUCT_E1412 0x1412 -#define HUAWEI_PRODUCT_E1413 0x1413 -#define HUAWEI_PRODUCT_E1414 0x1414 -#define HUAWEI_PRODUCT_E1415 0x1415 -#define HUAWEI_PRODUCT_E1416 0x1416 -#define HUAWEI_PRODUCT_E1417 0x1417 -#define HUAWEI_PRODUCT_E1418 0x1418 -#define HUAWEI_PRODUCT_E1419 0x1419 -#define HUAWEI_PRODUCT_E141A 0x141A -#define HUAWEI_PRODUCT_E141B 0x141B -#define HUAWEI_PRODUCT_E141C 0x141C -#define HUAWEI_PRODUCT_E141D 0x141D -#define HUAWEI_PRODUCT_E141E 0x141E -#define HUAWEI_PRODUCT_E141F 0x141F -#define HUAWEI_PRODUCT_E1420 0x1420 -#define HUAWEI_PRODUCT_E1421 0x1421 -#define HUAWEI_PRODUCT_E1422 0x1422 -#define HUAWEI_PRODUCT_E1423 0x1423 -#define HUAWEI_PRODUCT_E1424 0x1424 -#define HUAWEI_PRODUCT_E1425 0x1425 -#define HUAWEI_PRODUCT_E1426 0x1426 -#define HUAWEI_PRODUCT_E1427 0x1427 -#define HUAWEI_PRODUCT_E1428 0x1428 -#define HUAWEI_PRODUCT_E1429 0x1429 -#define HUAWEI_PRODUCT_E142A 0x142A -#define HUAWEI_PRODUCT_E142B 0x142B -#define HUAWEI_PRODUCT_E142C 0x142C -#define HUAWEI_PRODUCT_E142D 0x142D -#define HUAWEI_PRODUCT_E142E 0x142E -#define HUAWEI_PRODUCT_E142F 0x142F -#define HUAWEI_PRODUCT_E1430 0x1430 -#define HUAWEI_PRODUCT_E1431 0x1431 -#define HUAWEI_PRODUCT_E1432 0x1432 -#define HUAWEI_PRODUCT_E1433 0x1433 -#define HUAWEI_PRODUCT_E1434 0x1434 -#define HUAWEI_PRODUCT_E1435 0x1435 -#define HUAWEI_PRODUCT_E1436 0x1436 -#define HUAWEI_PRODUCT_E1437 0x1437 -#define HUAWEI_PRODUCT_E1438 0x1438 -#define HUAWEI_PRODUCT_E1439 0x1439 -#define HUAWEI_PRODUCT_E143A 0x143A -#define HUAWEI_PRODUCT_E143B 0x143B -#define HUAWEI_PRODUCT_E143C 0x143C -#define HUAWEI_PRODUCT_E143D 0x143D -#define HUAWEI_PRODUCT_E143E 0x143E -#define HUAWEI_PRODUCT_E143F 0x143F -#define HUAWEI_PRODUCT_K4505 0x1464 -#define HUAWEI_PRODUCT_K3765 0x1465 -#define HUAWEI_PRODUCT_E14AC 0x14AC -#define HUAWEI_PRODUCT_K3806 0x14AE -#define HUAWEI_PRODUCT_K4605 0x14C6 -#define HUAWEI_PRODUCT_K5005 0x14C8 -#define HUAWEI_PRODUCT_K3770 0x14C9 -#define HUAWEI_PRODUCT_K3771 0x14CA -#define HUAWEI_PRODUCT_K4510 0x14CB -#define HUAWEI_PRODUCT_K4511 0x14CC -#define HUAWEI_PRODUCT_ETS1220 0x1803 -#define HUAWEI_PRODUCT_E353 0x1506 -//aron add-------- -#define HUAWEI_PRODUCT_E153 0x1446 -#define HUAWEI_PRODUCT_E173 0x1C05 -//---------- -#define QUANTA_VENDOR_ID 0x0408 -#define QUANTA_PRODUCT_Q101 0xEA02 -#define QUANTA_PRODUCT_Q111 0xEA03 -#define QUANTA_PRODUCT_GLX 0xEA04 -#define QUANTA_PRODUCT_GKE 0xEA05 -#define QUANTA_PRODUCT_GLE 0xEA06 - -#define NOVATELWIRELESS_VENDOR_ID 0x1410 - -/* YISO PRODUCTS */ - -#define YISO_VENDOR_ID 0x0EAB -#define YISO_PRODUCT_U893 0xC893 - -/* - * NOVATEL WIRELESS PRODUCTS - * - * Note from Novatel Wireless: - * If your Novatel modem does not work on linux, don't - * change the option module, but check our website. If - * that does not help, contact ddeschepper@nvtl.com -*/ -/* MERLIN EVDO PRODUCTS */ -#define NOVATELWIRELESS_PRODUCT_V640 0x1100 -#define NOVATELWIRELESS_PRODUCT_V620 0x1110 -#define NOVATELWIRELESS_PRODUCT_V740 0x1120 -#define NOVATELWIRELESS_PRODUCT_V720 0x1130 - -/* MERLIN HSDPA/HSPA PRODUCTS */ -#define NOVATELWIRELESS_PRODUCT_U730 0x1400 -#define NOVATELWIRELESS_PRODUCT_U740 0x1410 -#define NOVATELWIRELESS_PRODUCT_U870 0x1420 -#define NOVATELWIRELESS_PRODUCT_XU870 0x1430 -#define NOVATELWIRELESS_PRODUCT_X950D 0x1450 - -/* EXPEDITE PRODUCTS */ -#define NOVATELWIRELESS_PRODUCT_EV620 0x2100 -#define NOVATELWIRELESS_PRODUCT_ES720 0x2110 -#define NOVATELWIRELESS_PRODUCT_E725 0x2120 -#define NOVATELWIRELESS_PRODUCT_ES620 0x2130 -#define NOVATELWIRELESS_PRODUCT_EU730 0x2400 -#define NOVATELWIRELESS_PRODUCT_EU740 0x2410 -#define NOVATELWIRELESS_PRODUCT_EU870D 0x2420 -/* OVATION PRODUCTS */ -#define NOVATELWIRELESS_PRODUCT_MC727 0x4100 -#define NOVATELWIRELESS_PRODUCT_MC950D 0x4400 -/* - * Note from Novatel Wireless: - * All PID in the 5xxx range are currently reserved for - * auto-install CDROMs, and should not be added to this - * module. - * - * #define NOVATELWIRELESS_PRODUCT_U727 0x5010 - * #define NOVATELWIRELESS_PRODUCT_MC727_NEW 0x5100 -*/ -#define NOVATELWIRELESS_PRODUCT_OVMC760 0x6002 -#define NOVATELWIRELESS_PRODUCT_MC780 0x6010 -#define NOVATELWIRELESS_PRODUCT_EVDO_FULLSPEED 0x6000 -#define NOVATELWIRELESS_PRODUCT_EVDO_HIGHSPEED 0x6001 -#define NOVATELWIRELESS_PRODUCT_HSPA_FULLSPEED 0x7000 -#define NOVATELWIRELESS_PRODUCT_HSPA_HIGHSPEED 0x7001 -#define NOVATELWIRELESS_PRODUCT_HSPA_HIGHSPEED3 0x7003 -#define NOVATELWIRELESS_PRODUCT_HSPA_HIGHSPEED4 0x7004 -#define NOVATELWIRELESS_PRODUCT_HSPA_HIGHSPEED5 0x7005 -#define NOVATELWIRELESS_PRODUCT_HSPA_HIGHSPEED6 0x7006 -#define NOVATELWIRELESS_PRODUCT_HSPA_HIGHSPEED7 0x7007 -#define NOVATELWIRELESS_PRODUCT_MC996D 0x7030 -#define NOVATELWIRELESS_PRODUCT_MF3470 0x7041 -#define NOVATELWIRELESS_PRODUCT_MC547 0x7042 -#define NOVATELWIRELESS_PRODUCT_EVDO_EMBEDDED_FULLSPEED 0x8000 -#define NOVATELWIRELESS_PRODUCT_EVDO_EMBEDDED_HIGHSPEED 0x8001 -#define NOVATELWIRELESS_PRODUCT_HSPA_EMBEDDED_FULLSPEED 0x9000 -#define NOVATELWIRELESS_PRODUCT_HSPA_EMBEDDED_HIGHSPEED 0x9001 -#define NOVATELWIRELESS_PRODUCT_G1 0xA001 -#define NOVATELWIRELESS_PRODUCT_G1_M 0xA002 -#define NOVATELWIRELESS_PRODUCT_G2 0xA010 -#define NOVATELWIRELESS_PRODUCT_MC551 0xB001 - -/* AMOI PRODUCTS */ -#define AMOI_VENDOR_ID 0x1614 -#define AMOI_PRODUCT_H01 0x0800 -#define AMOI_PRODUCT_H01A 0x7002 -#define AMOI_PRODUCT_H02 0x0802 -#define AMOI_PRODUCT_SKYPEPHONE_S2 0x0407 - -#define DELL_VENDOR_ID 0x413C - -/* Dell modems */ -#define DELL_PRODUCT_5700_MINICARD 0x8114 -#define DELL_PRODUCT_5500_MINICARD 0x8115 -#define DELL_PRODUCT_5505_MINICARD 0x8116 -#define DELL_PRODUCT_5700_EXPRESSCARD 0x8117 -#define DELL_PRODUCT_5510_EXPRESSCARD 0x8118 - -#define DELL_PRODUCT_5700_MINICARD_SPRINT 0x8128 -#define DELL_PRODUCT_5700_MINICARD_TELUS 0x8129 - -#define DELL_PRODUCT_5720_MINICARD_VZW 0x8133 -#define DELL_PRODUCT_5720_MINICARD_SPRINT 0x8134 -#define DELL_PRODUCT_5720_MINICARD_TELUS 0x8135 -#define DELL_PRODUCT_5520_MINICARD_CINGULAR 0x8136 -#define DELL_PRODUCT_5520_MINICARD_GENERIC_L 0x8137 -#define DELL_PRODUCT_5520_MINICARD_GENERIC_I 0x8138 - -#define DELL_PRODUCT_5730_MINICARD_SPRINT 0x8180 -#define DELL_PRODUCT_5730_MINICARD_TELUS 0x8181 -#define DELL_PRODUCT_5730_MINICARD_VZW 0x8182 - -#define KYOCERA_VENDOR_ID 0x0c88 -#define KYOCERA_PRODUCT_KPC650 0x17da -#define KYOCERA_PRODUCT_KPC680 0x180a - -#define ANYDATA_VENDOR_ID 0x16d5 -#define ANYDATA_PRODUCT_ADU_620UW 0x6202 -#define ANYDATA_PRODUCT_ADU_E100A 0x6501 -#define ANYDATA_PRODUCT_ADU_500A 0x6502 - -#define AXESSTEL_VENDOR_ID 0x1726 -#define AXESSTEL_PRODUCT_MV110H 0x1000 - -#define BANDRICH_VENDOR_ID 0x1A8D -#define BANDRICH_PRODUCT_C100_1 0x1002 -#define BANDRICH_PRODUCT_C100_2 0x1003 -#define BANDRICH_PRODUCT_1004 0x1004 -#define BANDRICH_PRODUCT_1005 0x1005 -#define BANDRICH_PRODUCT_1006 0x1006 -#define BANDRICH_PRODUCT_1007 0x1007 -#define BANDRICH_PRODUCT_1008 0x1008 -#define BANDRICH_PRODUCT_1009 0x1009 -#define BANDRICH_PRODUCT_100A 0x100a - -#define BANDRICH_PRODUCT_100B 0x100b -#define BANDRICH_PRODUCT_100C 0x100c -#define BANDRICH_PRODUCT_100D 0x100d -#define BANDRICH_PRODUCT_100E 0x100e - -#define BANDRICH_PRODUCT_100F 0x100f -#define BANDRICH_PRODUCT_1010 0x1010 -#define BANDRICH_PRODUCT_1011 0x1011 -#define BANDRICH_PRODUCT_1012 0x1012 - -#define QUALCOMM_VENDOR_ID 0x05C6 - -#define CMOTECH_VENDOR_ID 0x16d8 -#define CMOTECH_PRODUCT_6008 0x6008 -#define CMOTECH_PRODUCT_6280 0x6280 - -#define TELIT_VENDOR_ID 0x1bc7 -#define TELIT_PRODUCT_UC864E 0x1003 -#define TELIT_PRODUCT_UC864G 0x1004 -#define TELIT_PRODUCT_CC864_DUAL 0x1005 -#define TELIT_PRODUCT_CC864_SINGLE 0x1006 -#define TELIT_PRODUCT_DE910_DUAL 0x1010 - -/* ZTE PRODUCTS */ -#define ZTE_VENDOR_ID 0x19d2 -#define ZTE_PRODUCT_MF622 0x0001 -#define ZTE_PRODUCT_MF628 0x0015 -#define ZTE_PRODUCT_MF626 0x0031 -#define ZTE_PRODUCT_CDMA_TECH 0xfffe -#define ZTE_PRODUCT_AC8710 0xfff1 -#define ZTE_PRODUCT_AC2726 0xfff5 -#define ZTE_PRODUCT_AC8710T 0xffff -#define ZTE_PRODUCT_MC2718 0xffe8 -#define ZTE_PRODUCT_AD3812 0xffeb -#define ZTE_PRODUCT_MC2716 0xffed - -#define BENQ_VENDOR_ID 0x04a5 -#define BENQ_PRODUCT_H10 0x4068 - -#define DLINK_VENDOR_ID 0x1186 -#define DLINK_PRODUCT_DWM_652 0x3e04 -#define DLINK_PRODUCT_DWM_652_U5 0xce16 -#define DLINK_PRODUCT_DWM_652_U5A 0xce1e - -#define QISDA_VENDOR_ID 0x1da5 -#define QISDA_PRODUCT_H21_4512 0x4512 -#define QISDA_PRODUCT_H21_4523 0x4523 -#define QISDA_PRODUCT_H20_4515 0x4515 -#define QISDA_PRODUCT_H20_4518 0x4518 -#define QISDA_PRODUCT_H20_4519 0x4519 - -/* TLAYTECH PRODUCTS */ -#define TLAYTECH_VENDOR_ID 0x20B9 -#define TLAYTECH_PRODUCT_TEU800 0x1682 - -/* TOSHIBA PRODUCTS */ -#define TOSHIBA_VENDOR_ID 0x0930 -#define TOSHIBA_PRODUCT_HSDPA_MINICARD 0x1302 -#define TOSHIBA_PRODUCT_G450 0x0d45 - -#define ALINK_VENDOR_ID 0x1e0e -#define ALINK_PRODUCT_PH300 0x9100 -#define ALINK_PRODUCT_3GU 0x9200 - -/* ALCATEL PRODUCTS */ -#define ALCATEL_VENDOR_ID 0x1bbb -#define ALCATEL_PRODUCT_X060S_X200 0x0000 - -#define PIRELLI_VENDOR_ID 0x1266 -#define PIRELLI_PRODUCT_C100_1 0x1002 -#define PIRELLI_PRODUCT_C100_2 0x1003 -#define PIRELLI_PRODUCT_1004 0x1004 -#define PIRELLI_PRODUCT_1005 0x1005 -#define PIRELLI_PRODUCT_1006 0x1006 -#define PIRELLI_PRODUCT_1007 0x1007 -#define PIRELLI_PRODUCT_1008 0x1008 -#define PIRELLI_PRODUCT_1009 0x1009 -#define PIRELLI_PRODUCT_100A 0x100a -#define PIRELLI_PRODUCT_100B 0x100b -#define PIRELLI_PRODUCT_100C 0x100c -#define PIRELLI_PRODUCT_100D 0x100d -#define PIRELLI_PRODUCT_100E 0x100e -#define PIRELLI_PRODUCT_100F 0x100f -#define PIRELLI_PRODUCT_1011 0x1011 -#define PIRELLI_PRODUCT_1012 0x1012 - -/* Airplus products */ -#define AIRPLUS_VENDOR_ID 0x1011 -#define AIRPLUS_PRODUCT_MCD650 0x3198 - -/* Longcheer/Longsung vendor ID; makes whitelabel devices that - * many other vendors like 4G Systems, Alcatel, ChinaBird, - * Mobidata, etc sell under their own brand names. - */ -#define LONGCHEER_VENDOR_ID 0x1c9e - -/* 4G Systems products */ -/* This is the 4G XS Stick W14 a.k.a. Mobilcom Debitel Surf-Stick * - * It seems to contain a Qualcomm QSC6240/6290 chipset */ -#define FOUR_G_SYSTEMS_PRODUCT_W14 0x9603 - -/* Zoom */ -#define ZOOM_PRODUCT_4597 0x9607 - -/* Haier products */ -#define HAIER_VENDOR_ID 0x201e -#define HAIER_PRODUCT_CE100 0x2009 - -/* Cinterion (formerly Siemens) products */ -#define SIEMENS_VENDOR_ID 0x0681 -#define CINTERION_VENDOR_ID 0x1e2d -#define CINTERION_PRODUCT_HC25_MDM 0x0047 -#define CINTERION_PRODUCT_HC25_MDMNET 0x0040 -#define CINTERION_PRODUCT_HC28_MDM 0x004C -#define CINTERION_PRODUCT_HC28_MDMNET 0x004A /* same for HC28J */ -#define CINTERION_PRODUCT_EU3_E 0x0051 -#define CINTERION_PRODUCT_EU3_P 0x0052 -#define CINTERION_PRODUCT_PH8 0x0053 - -/* Olivetti products */ -#define OLIVETTI_VENDOR_ID 0x0b3c -#define OLIVETTI_PRODUCT_OLICARD100 0xc000 - -/* Celot products */ -#define CELOT_VENDOR_ID 0x211f -#define CELOT_PRODUCT_CT680M 0x6801 - -/* ONDA Communication vendor id */ -#define ONDA_VENDOR_ID 0x1ee8 - -/* ONDA MT825UP HSDPA 14.2 modem */ -#define ONDA_MT825UP 0x000b - -/* Samsung products */ -#define SAMSUNG_VENDOR_ID 0x04e8 -#define SAMSUNG_PRODUCT_GT_B3730 0x6889 - -/* YUGA products www.yuga-info.com gavin.kx@qq.com */ -#define YUGA_VENDOR_ID 0x257A -#define YUGA_PRODUCT_CEM600 0x1601 -#define YUGA_PRODUCT_CEM610 0x1602 -#define YUGA_PRODUCT_CEM500 0x1603 -#define YUGA_PRODUCT_CEM510 0x1604 -#define YUGA_PRODUCT_CEM800 0x1605 -#define YUGA_PRODUCT_CEM900 0x1606 - -#define YUGA_PRODUCT_CEU818 0x1607 -#define YUGA_PRODUCT_CEU816 0x1608 -#define YUGA_PRODUCT_CEU828 0x1609 -#define YUGA_PRODUCT_CEU826 0x160A -#define YUGA_PRODUCT_CEU518 0x160B -#define YUGA_PRODUCT_CEU516 0x160C -#define YUGA_PRODUCT_CEU528 0x160D -#define YUGA_PRODUCT_CEU526 0x160F -#define YUGA_PRODUCT_CEU881 0x161F -#define YUGA_PRODUCT_CEU882 0x162F - -#define YUGA_PRODUCT_CWM600 0x2601 -#define YUGA_PRODUCT_CWM610 0x2602 -#define YUGA_PRODUCT_CWM500 0x2603 -#define YUGA_PRODUCT_CWM510 0x2604 -#define YUGA_PRODUCT_CWM800 0x2605 -#define YUGA_PRODUCT_CWM900 0x2606 - -#define YUGA_PRODUCT_CWU718 0x2607 -#define YUGA_PRODUCT_CWU716 0x2608 -#define YUGA_PRODUCT_CWU728 0x2609 -#define YUGA_PRODUCT_CWU726 0x260A -#define YUGA_PRODUCT_CWU518 0x260B -#define YUGA_PRODUCT_CWU516 0x260C -#define YUGA_PRODUCT_CWU528 0x260D -#define YUGA_PRODUCT_CWU581 0x260E -#define YUGA_PRODUCT_CWU526 0x260F -#define YUGA_PRODUCT_CWU582 0x261F -#define YUGA_PRODUCT_CWU583 0x262F - -#define YUGA_PRODUCT_CLM600 0x3601 -#define YUGA_PRODUCT_CLM610 0x3602 -#define YUGA_PRODUCT_CLM500 0x3603 -#define YUGA_PRODUCT_CLM510 0x3604 -#define YUGA_PRODUCT_CLM800 0x3605 -#define YUGA_PRODUCT_CLM900 0x3606 - -#define YUGA_PRODUCT_CLU718 0x3607 -#define YUGA_PRODUCT_CLU716 0x3608 -#define YUGA_PRODUCT_CLU728 0x3609 -#define YUGA_PRODUCT_CLU726 0x360A -#define YUGA_PRODUCT_CLU518 0x360B -#define YUGA_PRODUCT_CLU516 0x360C -#define YUGA_PRODUCT_CLU528 0x360D -#define YUGA_PRODUCT_CLU526 0x360F - -/* Viettel products */ -#define VIETTEL_VENDOR_ID 0x2262 -#define VIETTEL_PRODUCT_VT1000 0x0002 - -/* ZD Incorporated */ -#define ZD_VENDOR_ID 0x0685 -#define ZD_PRODUCT_7000 0x7000 - -/* LG products */ -#define LG_VENDOR_ID 0x1004 -#define LG_PRODUCT_L02C 0x618f - -/* MediaTek products */ -#define MEDIATEK_VENDOR_ID 0x0e8d -#define MEDIATEK_PRODUCT_DC_1COM 0x00a0 -#define MEDIATEK_PRODUCT_DC_4COM 0x00a5 -#define MEDIATEK_PRODUCT_DC_5COM 0x00a4 -#define MEDIATEK_PRODUCT_7208_1COM 0x7101 -#define MEDIATEK_PRODUCT_7208_2COM 0x7102 -#define MEDIATEK_PRODUCT_FP_1COM 0x0003 -#define MEDIATEK_PRODUCT_FP_2COM 0x0023 -#define MEDIATEK_PRODUCT_FPDC_1COM 0x0043 -#define MEDIATEK_PRODUCT_FPDC_2COM 0x0033 - -/* Cellient products */ -#define CELLIENT_VENDOR_ID 0x2692 -#define CELLIENT_PRODUCT_MEN200 0x9005 - -/* some devices interfaces need special handling due to a number of reasons */ -enum option_blacklist_reason { - OPTION_BLACKLIST_NONE = 0, - OPTION_BLACKLIST_SENDSETUP = 1, - OPTION_BLACKLIST_RESERVED_IF = 2 -}; - -#define MAX_BL_NUM 8 -struct option_blacklist_info { - /* bitfield of interface numbers for OPTION_BLACKLIST_SENDSETUP */ - const unsigned long sendsetup; - /* bitfield of interface numbers for OPTION_BLACKLIST_RESERVED_IF */ - const unsigned long reserved; -}; - -static const struct option_blacklist_info four_g_w14_blacklist = { - .sendsetup = BIT(0) | BIT(1), -}; - -static const struct option_blacklist_info alcatel_x200_blacklist = { - .sendsetup = BIT(0) | BIT(1), -}; - -static const struct option_blacklist_info zte_0037_blacklist = { - .sendsetup = BIT(0) | BIT(1), -}; - -static const struct option_blacklist_info zte_k3765_z_blacklist = { - .sendsetup = BIT(0) | BIT(1) | BIT(2), - .reserved = BIT(4), -}; - -static const struct option_blacklist_info zte_ad3812_z_blacklist = { - .sendsetup = BIT(0) | BIT(1) | BIT(2), -}; - -static const struct option_blacklist_info zte_mc2718_z_blacklist = { - .sendsetup = BIT(1) | BIT(2) | BIT(3) | BIT(4), -}; - -static const struct option_blacklist_info zte_mc2716_z_blacklist = { - .sendsetup = BIT(1) | BIT(2) | BIT(3), -}; - -static const struct option_blacklist_info huawei_cdc12_blacklist = { - .reserved = BIT(1) | BIT(2), -}; - -static const struct option_blacklist_info net_intf1_blacklist = { - .reserved = BIT(1), -}; - -static const struct option_blacklist_info net_intf2_blacklist = { - .reserved = BIT(2), -}; - -static const struct option_blacklist_info net_intf3_blacklist = { - .reserved = BIT(3), -}; - -static const struct option_blacklist_info net_intf4_blacklist = { - .reserved = BIT(4), -}; - -static const struct option_blacklist_info net_intf5_blacklist = { - .reserved = BIT(5), -}; - -static const struct option_blacklist_info zte_mf626_blacklist = { - .sendsetup = BIT(0) | BIT(1), - .reserved = BIT(4), -}; - -static const struct usb_device_id option_ids[] = { - { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COLT) }, - { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_RICOLA) }, - { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_RICOLA_LIGHT) }, - { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_RICOLA_QUAD) }, - { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_RICOLA_QUAD_LIGHT) }, - { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_RICOLA_NDIS) }, - { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_RICOLA_NDIS_LIGHT) }, - { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_RICOLA_NDIS_QUAD) }, - { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_RICOLA_NDIS_QUAD_LIGHT) }, - { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COBRA) }, - { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COBRA_BUS) }, - { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_VIPER) }, - { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_VIPER_BUS) }, - { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_GT_MAX_READY) }, - { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_FUJI_MODEM_LIGHT) }, - { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_FUJI_MODEM_GT) }, - { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_FUJI_MODEM_EX) }, - { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_KOI_MODEM) }, - { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_SCORPION_MODEM) }, - { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_ETNA_MODEM) }, - { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_ETNA_MODEM_LITE) }, - { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_ETNA_MODEM_GT) }, - { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_ETNA_MODEM_EX) }, - { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_ETNA_KOI_MODEM) }, - { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_GTM380_MODEM) }, - { USB_DEVICE(QUANTA_VENDOR_ID, QUANTA_PRODUCT_Q101) }, - { USB_DEVICE(QUANTA_VENDOR_ID, QUANTA_PRODUCT_Q111) }, - { USB_DEVICE(QUANTA_VENDOR_ID, QUANTA_PRODUCT_GLX) }, - { USB_DEVICE(QUANTA_VENDOR_ID, QUANTA_PRODUCT_GKE) }, - { USB_DEVICE(QUANTA_VENDOR_ID, QUANTA_PRODUCT_GLE) }, - { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E600, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E220, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E220BIS, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1401, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1402, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1403, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1404, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1405, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1406, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1407, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1408, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1409, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E140A, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E140B, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E140C, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E140D, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E140E, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E140F, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1410, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1411, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1412, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1413, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1414, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1415, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1416, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1417, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1418, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1419, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E141A, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E141B, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E141C, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E141D, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E141E, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E141F, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1420, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1421, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1422, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1423, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1424, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1425, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1426, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1427, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1428, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1429, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E142A, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E142B, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E142C, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E142D, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E142E, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E142F, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1430, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1431, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1432, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1433, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1434, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1435, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1436, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1437, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1438, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1439, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E143A, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E143B, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E143C, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E143D, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E143E, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E143F, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E173, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K4505, 0xff, 0xff, 0xff), - .driver_info = (kernel_ulong_t) &huawei_cdc12_blacklist }, - { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K3765, 0xff, 0xff, 0xff), - .driver_info = (kernel_ulong_t) &huawei_cdc12_blacklist }, - { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_ETS1220, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E14AC, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K3806, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K4605, 0xff, 0xff, 0xff), - .driver_info = (kernel_ulong_t) &huawei_cdc12_blacklist }, - { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K4605, 0xff, 0x01, 0x31) }, - { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K4605, 0xff, 0x01, 0x32) }, - { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K5005, 0xff, 0x01, 0x31) }, - { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K5005, 0xff, 0x01, 0x32) }, - { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K5005, 0xff, 0x01, 0x33) }, - { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K3770, 0xff, 0x02, 0x31) }, - { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K3770, 0xff, 0x02, 0x32) }, - { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K3771, 0xff, 0x02, 0x31) }, - { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K3771, 0xff, 0x02, 0x32) }, - { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K4510, 0xff, 0x01, 0x31) }, - { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K4510, 0xff, 0x01, 0x32) }, - { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K4511, 0xff, 0x01, 0x31) }, - { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K4511, 0xff, 0x01, 0x32) }, - { USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E153) }, //aaron add - { USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E173) },//aron add - { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E353, 0xff, 0x01, 0x01) }, - { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E353, 0xff, 0x01, 0x02) }, - { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E353, 0xff, 0x01, 0x03) }, - { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E353, 0xff, 0x01, 0x10) }, - { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E353, 0xff, 0x01, 0x12) }, - { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E353, 0xff, 0x01, 0x13) }, - { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E353, 0xff, 0x02, 0x01) }, /* E398 3G Modem */ - { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E353, 0xff, 0x02, 0x02) }, /* E398 3G PC UI Interface */ - { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E353, 0xff, 0x02, 0x03) }, /* E398 3G Application Interface */ - { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_V640) }, - { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_V620) }, - { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_V740) }, - { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_V720) }, - { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_U730) }, - { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_U740) }, - { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_U870) }, - { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_XU870) }, - { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_X950D) }, - { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_EV620) }, - { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_ES720) }, - { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_E725) }, - { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_ES620) }, - { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_EU730) }, - { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_EU740) }, - { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_EU870D) }, - { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_MC950D) }, - { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_MC727) }, - { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_OVMC760) }, - { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_MC780) }, - { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_EVDO_FULLSPEED) }, - { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_HSPA_FULLSPEED) }, - { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_EVDO_EMBEDDED_FULLSPEED) }, - { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_HSPA_EMBEDDED_FULLSPEED) }, - { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_EVDO_HIGHSPEED) }, - { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_HSPA_HIGHSPEED) }, - { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_HSPA_HIGHSPEED3) }, - { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_HSPA_HIGHSPEED4) }, - { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_HSPA_HIGHSPEED5) }, - { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_HSPA_HIGHSPEED6) }, - { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_HSPA_HIGHSPEED7) }, - { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_MC996D) }, - { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_MF3470) }, - { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_MC547) }, - { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_EVDO_EMBEDDED_HIGHSPEED) }, - { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_HSPA_EMBEDDED_HIGHSPEED) }, - { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_G1) }, - { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_G1_M) }, - { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_G2) }, - /* Novatel Ovation MC551 a.k.a. Verizon USB551L */ - { USB_DEVICE_AND_INTERFACE_INFO(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_MC551, 0xff, 0xff, 0xff) }, - - { USB_DEVICE(AMOI_VENDOR_ID, AMOI_PRODUCT_H01) }, - { USB_DEVICE(AMOI_VENDOR_ID, AMOI_PRODUCT_H01A) }, - { USB_DEVICE(AMOI_VENDOR_ID, AMOI_PRODUCT_H02) }, - { USB_DEVICE(AMOI_VENDOR_ID, AMOI_PRODUCT_SKYPEPHONE_S2) }, - - { USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5700_MINICARD) }, /* Dell Wireless 5700 Mobile Broadband CDMA/EVDO Mini-Card == Novatel Expedite EV620 CDMA/EV-DO */ - { USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5500_MINICARD) }, /* Dell Wireless 5500 Mobile Broadband HSDPA Mini-Card == Novatel Expedite EU740 HSDPA/3G */ - { USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5505_MINICARD) }, /* Dell Wireless 5505 Mobile Broadband HSDPA Mini-Card == Novatel Expedite EU740 HSDPA/3G */ - { USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5700_EXPRESSCARD) }, /* Dell Wireless 5700 Mobile Broadband CDMA/EVDO ExpressCard == Novatel Merlin XV620 CDMA/EV-DO */ - { USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5510_EXPRESSCARD) }, /* Dell Wireless 5510 Mobile Broadband HSDPA ExpressCard == Novatel Merlin XU870 HSDPA/3G */ - { USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5700_MINICARD_SPRINT) }, /* Dell Wireless 5700 Mobile Broadband CDMA/EVDO Mini-Card == Novatel Expedite E720 CDMA/EV-DO */ - { USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5700_MINICARD_TELUS) }, /* Dell Wireless 5700 Mobile Broadband CDMA/EVDO Mini-Card == Novatel Expedite ET620 CDMA/EV-DO */ - { USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5720_MINICARD_VZW) }, /* Dell Wireless 5720 == Novatel EV620 CDMA/EV-DO */ - { USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5720_MINICARD_SPRINT) }, /* Dell Wireless 5720 == Novatel EV620 CDMA/EV-DO */ - { USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5720_MINICARD_TELUS) }, /* Dell Wireless 5720 == Novatel EV620 CDMA/EV-DO */ - { USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5520_MINICARD_CINGULAR) }, /* Dell Wireless HSDPA 5520 == Novatel Expedite EU860D */ - { USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5520_MINICARD_GENERIC_L) }, /* Dell Wireless HSDPA 5520 */ - { USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5520_MINICARD_GENERIC_I) }, /* Dell Wireless 5520 Voda I Mobile Broadband (3G HSDPA) Minicard */ - { USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5730_MINICARD_SPRINT) }, /* Dell Wireless 5730 Mobile Broadband EVDO/HSPA Mini-Card */ - { USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5730_MINICARD_TELUS) }, /* Dell Wireless 5730 Mobile Broadband EVDO/HSPA Mini-Card */ - { USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5730_MINICARD_VZW) }, /* Dell Wireless 5730 Mobile Broadband EVDO/HSPA Mini-Card */ - { USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ADU_E100A) }, /* ADU-E100, ADU-310 */ - { USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ADU_500A) }, - { USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ADU_620UW) }, - { USB_DEVICE(AXESSTEL_VENDOR_ID, AXESSTEL_PRODUCT_MV110H) }, - { USB_DEVICE(YISO_VENDOR_ID, YISO_PRODUCT_U893) }, - { USB_DEVICE(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_C100_1) }, - { USB_DEVICE(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_C100_2) }, - { USB_DEVICE(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_1004) }, - { USB_DEVICE(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_1005) }, - { USB_DEVICE(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_1006) }, - { USB_DEVICE(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_1007) }, - { USB_DEVICE(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_1008) }, - { USB_DEVICE(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_1009) }, - { USB_DEVICE(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_100A) }, - { USB_DEVICE(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_100B) }, - { USB_DEVICE(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_100C) }, - { USB_DEVICE(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_100D) }, - { USB_DEVICE(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_100E) }, - { USB_DEVICE(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_100F) }, - { USB_DEVICE(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_1010) }, - { USB_DEVICE(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_1011) }, - { USB_DEVICE(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_1012) }, - { USB_DEVICE(KYOCERA_VENDOR_ID, KYOCERA_PRODUCT_KPC650) }, - { USB_DEVICE(KYOCERA_VENDOR_ID, KYOCERA_PRODUCT_KPC680) }, - { USB_DEVICE(QUALCOMM_VENDOR_ID, 0x6000)}, /* ZTE AC8700 */ - { USB_DEVICE(QUALCOMM_VENDOR_ID, 0x6613)}, /* Onda H600/ZTE MF330 */ - { USB_DEVICE(QUALCOMM_VENDOR_ID, 0x9000)}, /* SIMCom SIM5218 */ - { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_6280) }, /* BP3-USB & BP3-EXT HSDPA */ - { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_6008) }, - { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_UC864E) }, - { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_UC864G) }, - { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_CC864_DUAL) }, - { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_CC864_SINGLE) }, - { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_DE910_DUAL) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_MF622, 0xff, 0xff, 0xff) }, /* ZTE WCDMA products */ - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0002, 0xff, 0xff, 0xff), - .driver_info = (kernel_ulong_t)&net_intf1_blacklist }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0003, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0004, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0005, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0006, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0008, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0009, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x000a, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x000b, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x000c, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x000d, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x000e, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x000f, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0010, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0011, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0012, 0xff, 0xff, 0xff), - .driver_info = (kernel_ulong_t)&net_intf1_blacklist }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0013, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_MF628, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0016, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0017, 0xff, 0xff, 0xff), - .driver_info = (kernel_ulong_t)&net_intf3_blacklist }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0018, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0019, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0020, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0021, 0xff, 0xff, 0xff), - .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0022, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0023, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0024, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0025, 0xff, 0xff, 0xff), - .driver_info = (kernel_ulong_t)&net_intf1_blacklist }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0028, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0029, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0030, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_MF626, 0xff, - 0xff, 0xff), .driver_info = (kernel_ulong_t)&zte_mf626_blacklist }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0032, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0033, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0034, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0037, 0xff, 0xff, 0xff), - .driver_info = (kernel_ulong_t)&zte_0037_blacklist }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0038, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0039, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0040, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0042, 0xff, 0xff, 0xff), - .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0043, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0044, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0048, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0049, 0xff, 0xff, 0xff), - .driver_info = (kernel_ulong_t)&net_intf5_blacklist }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0050, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0051, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0052, 0xff, 0xff, 0xff), - .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0054, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0055, 0xff, 0xff, 0xff), - .driver_info = (kernel_ulong_t)&net_intf1_blacklist }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0056, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0057, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0058, 0xff, 0xff, 0xff), - .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0061, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0062, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0063, 0xff, 0xff, 0xff), - .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0064, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0065, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0066, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0067, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0069, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0076, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0077, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0078, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0079, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0082, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0083, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0086, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0087, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0088, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0089, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0090, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0091, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0092, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0093, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0094, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0095, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0096, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0097, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0104, 0xff, 0xff, 0xff), - .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0105, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0106, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0108, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0113, 0xff, 0xff, 0xff), - .driver_info = (kernel_ulong_t)&net_intf5_blacklist }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0117, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0118, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0121, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0122, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0123, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0124, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0125, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0126, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0128, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0142, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0143, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0144, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0145, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0148, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0151, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0153, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0155, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0156, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0157, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0158, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0159, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0161, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0162, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0164, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0165, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0167, 0xff, 0xff, 0xff), - .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1008, 0xff, 0xff, 0xff), - .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1010, 0xff, 0xff, 0xff), - .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1012, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1057, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1058, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1059, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1060, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1061, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1062, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1063, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1064, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1065, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1066, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1067, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1068, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1069, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1070, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1071, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1072, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1073, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1074, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1075, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1076, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1077, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1078, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1079, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1080, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1081, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1082, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1083, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1084, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1085, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1086, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1087, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1088, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1089, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1090, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1091, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1092, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1093, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1094, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1095, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1096, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1097, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1098, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1099, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1100, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1101, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1102, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1103, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1104, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1105, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1106, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1107, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1108, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1109, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1110, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1111, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1112, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1113, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1114, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1115, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1116, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1117, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1118, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1119, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1120, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1121, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1122, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1123, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1124, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1125, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1126, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1127, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1128, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1129, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1130, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1131, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1132, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1133, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1134, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1135, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1136, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1137, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1138, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1139, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1140, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1141, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1142, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1143, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1144, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1145, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1146, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1147, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1148, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1149, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1150, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1151, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1152, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1153, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1154, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1155, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1156, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1157, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1158, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1159, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1160, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1161, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1162, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1163, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1164, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1165, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1166, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1167, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1168, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1169, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1170, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1244, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1245, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1246, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1247, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1248, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1249, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1250, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1251, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1252, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1253, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1254, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1255, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1256, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1257, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1258, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1259, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1260, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1261, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1262, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1263, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1264, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1265, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1266, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1267, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1268, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1269, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1270, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1271, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1272, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1273, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1274, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1275, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1276, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1277, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1278, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1279, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1280, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1281, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1282, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1283, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1284, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1285, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1286, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1287, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1288, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1289, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1290, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1291, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1292, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1293, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1294, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1295, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1296, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1297, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1298, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1299, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1300, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1402, 0xff, 0xff, 0xff), - .driver_info = (kernel_ulong_t)&net_intf2_blacklist }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x2002, 0xff, - 0xff, 0xff), .driver_info = (kernel_ulong_t)&zte_k3765_z_blacklist }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x2003, 0xff, 0xff, 0xff) }, - - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0014, 0xff, 0xff, 0xff) }, /* ZTE CDMA products */ - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0027, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0059, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0060, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0070, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0073, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0094, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0130, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0133, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0141, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x2000, 0xff, 0xff, 0xff) }, //aron add. - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0152, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0168, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0170, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0176, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0178, 0xff, 0xff, 0xff) }, - - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_CDMA_TECH, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_AC8710, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_AC2726, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_AC8710T, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_MC2718, 0xff, 0xff, 0xff), - .driver_info = (kernel_ulong_t)&zte_mc2718_z_blacklist }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_AD3812, 0xff, 0xff, 0xff), - .driver_info = (kernel_ulong_t)&zte_ad3812_z_blacklist }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_MC2716, 0xff, 0xff, 0xff), - .driver_info = (kernel_ulong_t)&zte_mc2716_z_blacklist }, - { USB_DEVICE(BENQ_VENDOR_ID, BENQ_PRODUCT_H10) }, - { USB_DEVICE(DLINK_VENDOR_ID, DLINK_PRODUCT_DWM_652) }, - { USB_DEVICE(ALINK_VENDOR_ID, DLINK_PRODUCT_DWM_652_U5) }, /* Yes, ALINK_VENDOR_ID */ - { USB_DEVICE(ALINK_VENDOR_ID, DLINK_PRODUCT_DWM_652_U5A) }, - { USB_DEVICE(QISDA_VENDOR_ID, QISDA_PRODUCT_H21_4512) }, - { USB_DEVICE(QISDA_VENDOR_ID, QISDA_PRODUCT_H21_4523) }, - { USB_DEVICE(QISDA_VENDOR_ID, QISDA_PRODUCT_H20_4515) }, - { USB_DEVICE(QISDA_VENDOR_ID, QISDA_PRODUCT_H20_4518) }, - { USB_DEVICE(QISDA_VENDOR_ID, QISDA_PRODUCT_H20_4519) }, - { USB_DEVICE(TOSHIBA_VENDOR_ID, TOSHIBA_PRODUCT_G450) }, - { USB_DEVICE(TOSHIBA_VENDOR_ID, TOSHIBA_PRODUCT_HSDPA_MINICARD ) }, /* Toshiba 3G HSDPA == Novatel Expedite EU870D MiniCard */ - { USB_DEVICE(ALINK_VENDOR_ID, 0x9000) }, - { USB_DEVICE(ALINK_VENDOR_ID, ALINK_PRODUCT_PH300) }, - { USB_DEVICE_AND_INTERFACE_INFO(ALINK_VENDOR_ID, ALINK_PRODUCT_3GU, 0xff, 0xff, 0xff) }, - { USB_DEVICE(ALCATEL_VENDOR_ID, ALCATEL_PRODUCT_X060S_X200), - .driver_info = (kernel_ulong_t)&alcatel_x200_blacklist - }, - { USB_DEVICE(AIRPLUS_VENDOR_ID, AIRPLUS_PRODUCT_MCD650) }, - { USB_DEVICE(TLAYTECH_VENDOR_ID, TLAYTECH_PRODUCT_TEU800) }, - { USB_DEVICE(LONGCHEER_VENDOR_ID, FOUR_G_SYSTEMS_PRODUCT_W14), - .driver_info = (kernel_ulong_t)&four_g_w14_blacklist - }, - { USB_DEVICE(LONGCHEER_VENDOR_ID, ZOOM_PRODUCT_4597) }, - { USB_DEVICE(HAIER_VENDOR_ID, HAIER_PRODUCT_CE100) }, - /* Pirelli */ - { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_C100_1)}, - { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_C100_2)}, - { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_1004)}, - { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_1005)}, - { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_1006)}, - { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_1007)}, - { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_1008)}, - { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_1009)}, - { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_100A)}, - { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_100B) }, - { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_100C) }, - { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_100D) }, - { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_100E) }, - { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_100F) }, - { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_1011)}, - { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_1012)}, - /* Cinterion */ - { USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_EU3_E) }, - { USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_EU3_P) }, - { USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_PH8) }, - { USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_HC28_MDM) }, - { USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_HC28_MDMNET) }, - { USB_DEVICE(SIEMENS_VENDOR_ID, CINTERION_PRODUCT_HC25_MDM) }, - { USB_DEVICE(SIEMENS_VENDOR_ID, CINTERION_PRODUCT_HC25_MDMNET) }, - { USB_DEVICE(SIEMENS_VENDOR_ID, CINTERION_PRODUCT_HC28_MDM) }, /* HC28 enumerates with Siemens or Cinterion VID depending on FW revision */ - { USB_DEVICE(SIEMENS_VENDOR_ID, CINTERION_PRODUCT_HC28_MDMNET) }, - - { USB_DEVICE(OLIVETTI_VENDOR_ID, OLIVETTI_PRODUCT_OLICARD100) }, - { USB_DEVICE(CELOT_VENDOR_ID, CELOT_PRODUCT_CT680M) }, /* CT-650 CDMA 450 1xEVDO modem */ - { USB_DEVICE(ONDA_VENDOR_ID, ONDA_MT825UP) }, /* ONDA MT825UP modem */ - { USB_DEVICE_AND_INTERFACE_INFO(SAMSUNG_VENDOR_ID, SAMSUNG_PRODUCT_GT_B3730, USB_CLASS_CDC_DATA, 0x00, 0x00) }, /* Samsung GT-B3730 LTE USB modem.*/ - { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CEM600) }, - { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CEM610) }, - { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CEM500) }, - { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CEM510) }, - { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CEM800) }, - { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CEM900) }, - { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CEU818) }, - { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CEU816) }, - { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CEU828) }, - { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CEU826) }, - { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CEU518) }, - { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CEU516) }, - { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CEU528) }, - { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CEU526) }, - { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CWM600) }, - { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CWM610) }, - { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CWM500) }, - { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CWM510) }, - { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CWM800) }, - { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CWM900) }, - { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CWU718) }, - { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CWU716) }, - { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CWU728) }, - { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CWU726) }, - { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CWU518) }, - { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CWU516) }, - { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CWU528) }, - { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CWU526) }, - { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CLM600) }, - { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CLM610) }, - { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CLM500) }, - { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CLM510) }, - { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CLM800) }, - { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CLM900) }, - { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CLU718) }, - { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CLU716) }, - { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CLU728) }, - { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CLU726) }, - { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CLU518) }, - { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CLU516) }, - { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CLU528) }, - { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CLU526) }, - { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CEU881) }, - { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CEU882) }, - { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CWU581) }, - { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CWU582) }, - { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CWU583) }, - { USB_DEVICE_AND_INTERFACE_INFO(VIETTEL_VENDOR_ID, VIETTEL_PRODUCT_VT1000, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZD_VENDOR_ID, ZD_PRODUCT_7000, 0xff, 0xff, 0xff) }, - { USB_DEVICE(LG_VENDOR_ID, LG_PRODUCT_L02C) }, /* docomo L-02C modem */ - { USB_DEVICE_AND_INTERFACE_INFO(MEDIATEK_VENDOR_ID, 0x00a1, 0xff, 0x00, 0x00) }, - { USB_DEVICE_AND_INTERFACE_INFO(MEDIATEK_VENDOR_ID, 0x00a1, 0xff, 0x02, 0x01) }, - { USB_DEVICE_AND_INTERFACE_INFO(MEDIATEK_VENDOR_ID, 0x00a2, 0xff, 0x00, 0x00) }, - { USB_DEVICE_AND_INTERFACE_INFO(MEDIATEK_VENDOR_ID, 0x00a2, 0xff, 0x02, 0x01) }, /* MediaTek MT6276M modem & app port */ - { USB_DEVICE_AND_INTERFACE_INFO(MEDIATEK_VENDOR_ID, MEDIATEK_PRODUCT_DC_1COM, 0x0a, 0x00, 0x00) }, - { USB_DEVICE_AND_INTERFACE_INFO(MEDIATEK_VENDOR_ID, MEDIATEK_PRODUCT_DC_5COM, 0xff, 0x02, 0x01) }, - { USB_DEVICE_AND_INTERFACE_INFO(MEDIATEK_VENDOR_ID, MEDIATEK_PRODUCT_DC_5COM, 0xff, 0x00, 0x00) }, - { USB_DEVICE_AND_INTERFACE_INFO(MEDIATEK_VENDOR_ID, MEDIATEK_PRODUCT_DC_4COM, 0xff, 0x02, 0x01) }, - { USB_DEVICE_AND_INTERFACE_INFO(MEDIATEK_VENDOR_ID, MEDIATEK_PRODUCT_DC_4COM, 0xff, 0x00, 0x00) }, - { USB_DEVICE_AND_INTERFACE_INFO(MEDIATEK_VENDOR_ID, MEDIATEK_PRODUCT_7208_1COM, 0x02, 0x00, 0x00) }, - { USB_DEVICE_AND_INTERFACE_INFO(MEDIATEK_VENDOR_ID, MEDIATEK_PRODUCT_7208_2COM, 0x02, 0x02, 0x01) }, - { USB_DEVICE_AND_INTERFACE_INFO(MEDIATEK_VENDOR_ID, MEDIATEK_PRODUCT_FP_1COM, 0x0a, 0x00, 0x00) }, - { USB_DEVICE_AND_INTERFACE_INFO(MEDIATEK_VENDOR_ID, MEDIATEK_PRODUCT_FP_2COM, 0x0a, 0x00, 0x00) }, - { USB_DEVICE_AND_INTERFACE_INFO(MEDIATEK_VENDOR_ID, MEDIATEK_PRODUCT_FPDC_1COM, 0x0a, 0x00, 0x00) }, - { USB_DEVICE_AND_INTERFACE_INFO(MEDIATEK_VENDOR_ID, MEDIATEK_PRODUCT_FPDC_2COM, 0x0a, 0x00, 0x00) }, - { USB_DEVICE(CELLIENT_VENDOR_ID, CELLIENT_PRODUCT_MEN200) }, - { USB_DEVICE(VIATELECOM_VENDOR_ID, VIATELECOM_PRODUCT_ID) },/* VIA-Telecom CBP CDC Version*/ - { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0x1c05, 0xff, 0xff, 0xff) }, /*huawei E173*/ - { USB_DEVICE_AND_INTERFACE_INFO(0x05c6, 0x1000, 0xff, 0xff, 0xff) }, /*´´¾°SCV SEV759 */ - { USB_DEVICE_AND_INTERFACE_INFO(0x05c6, 0x6000, 0xff, 0xff, 0xff) }, /*´´¾°SCV SEV759 */ - { USB_DEVICE_AND_INTERFACE_INFO(0x20a6, 0xf00e, 0xff, 0xff, 0xff) }, /*´´¾°SCV SEW868 */ - { USB_DEVICE_AND_INTERFACE_INFO(0x20a6, 0x1105, 0xff, 0xff, 0xff) }, /*´´¾°SCV SEW868 */ - { USB_DEVICE(0x19f5, 0x9909) }, /*UW100 */ - { USB_DEVICE(0x19f5, 0x9013) }, /*UW100 */ - { USB_DEVICE_AND_INTERFACE_INFO(0x05c6, 0x0015, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1176, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1008, 0xff, 0xff, 0xff) }, - { USB_DEVICE(BORA9380_VENDOR_ID, BORA9380_PRODUCT_ID) },/* ²¨ÀÖ9380*/ - { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0x14a8, 0xff, 0xff, 0xff) }, - - { USB_DEVICE(0x1c9e, 0x9605) }, /*a dongle without brand */ - { USB_DEVICE(0x231e, 0x0036) }, /*CYIT TD/GSM modem*/ - { USB_DEVICE(ZTE_VENDOR_ID, 0x1176) }, /*vodafone k3770-z*/ - { USB_DEVICE(HUAWEI_VENDOR_ID, 0x1506) }, /*hw e1731*/ - { USB_DEVICE(HUAWEI_VENDOR_ID, 0x1573) }, /*hw mu609*/ - { USB_DEVICE(0x1782, 0x0002) }, /*spectrum G3 3g modem*/
- { USB_DEVICE(HUAWEI_VENDOR_ID, 0x1c25) }, /*hw mu709*/ - { USB_DEVICE(0x2001, 0x7d01) }, /*dlink dwm156*/ - { } /* Terminating entry */ -}; -MODULE_DEVICE_TABLE(usb, option_ids); - -static struct usb_driver option_driver = { - .name = "option", - .probe = usb_serial_probe, - .disconnect = usb_serial_disconnect, -#ifdef CONFIG_PM - .suspend = usb_serial_suspend, - .resume = usb_serial_resume, - .supports_autosuspend = 1, -#endif - .id_table = option_ids, -}; - -/* The card has three separate interfaces, which the serial driver - * recognizes separately, thus num_port=1. - */ - -static struct usb_serial_driver option_1port_device = { - .driver = { - .owner = THIS_MODULE, - .name = "option1", - }, - .description = "GSM modem (1-port)", - .id_table = option_ids, - .num_ports = 1, - .probe = option_probe, - .open = usb_wwan_open, - .close = usb_wwan_close, - .dtr_rts = usb_wwan_dtr_rts, - .write = usb_wwan_write, - .write_room = usb_wwan_write_room, - .chars_in_buffer = usb_wwan_chars_in_buffer, - .set_termios = usb_wwan_set_termios, - .tiocmget = usb_wwan_tiocmget, - .tiocmset = usb_wwan_tiocmset, - .ioctl = usb_wwan_ioctl, - .attach = usb_wwan_startup, - .disconnect = usb_wwan_disconnect, - .release = option_release, - .read_int_callback = option_instat_callback, -#ifdef CONFIG_PM - .suspend = usb_wwan_suspend, - .resume = usb_wwan_resume, -#endif -}; - -static struct usb_serial_driver * const serial_drivers[] = { - &option_1port_device, NULL -}; - -static bool debug; - -module_usb_serial_driver(option_driver, serial_drivers); - -static bool is_blacklisted(const u8 ifnum, enum option_blacklist_reason reason, - const struct option_blacklist_info *blacklist) -{ - unsigned long num; - const unsigned long *intf_list; - - if (blacklist) { - if (reason == OPTION_BLACKLIST_SENDSETUP) - intf_list = &blacklist->sendsetup; - else if (reason == OPTION_BLACKLIST_RESERVED_IF) - intf_list = &blacklist->reserved; - else { - BUG_ON(reason); - return false; - } - - for_each_set_bit(num, intf_list, MAX_BL_NUM + 1) { - if (num == ifnum) - return true; - } - } - return false; -} -static int viatelecom_send_setup(struct usb_serial_port *port) -{ - struct usb_serial *serial = port->serial; - struct usb_wwan_port_private *portdata = usb_get_serial_port_data(port); - int ifNum = serial->interface->cur_altsetting->desc.bInterfaceNumber; - - /* VIA-Telecom CBP DTR format */ - return usb_control_msg(serial->dev, - usb_sndctrlpipe(serial->dev, 0), - 0x01, 0x40, portdata->dtr_state? 1: 0, ifNum, - NULL, 0, USB_CTRL_SET_TIMEOUT); - - -} - - -static int option_probe(struct usb_serial *serial, - const struct usb_device_id *id) -{ - struct usb_wwan_intf_private *data; - - /* D-Link DWM 652 still exposes CD-Rom emulation interface in modem mode */ - if (serial->dev->descriptor.idVendor == DLINK_VENDOR_ID && - serial->dev->descriptor.idProduct == DLINK_PRODUCT_DWM_652 && - serial->interface->cur_altsetting->desc.bInterfaceClass == 0x8) - return -ENODEV; - - /* Bandrich modem and AT command interface is 0xff */ - if ((serial->dev->descriptor.idVendor == BANDRICH_VENDOR_ID || - serial->dev->descriptor.idVendor == PIRELLI_VENDOR_ID) && - serial->interface->cur_altsetting->desc.bInterfaceClass != 0xff) - return -ENODEV; - - /* Don't bind reserved interfaces (like network ones) which often have - * the same class/subclass/protocol as the serial interfaces. Look at - * the Windows driver .INF files for reserved interface numbers. - */ - if (is_blacklisted( - serial->interface->cur_altsetting->desc.bInterfaceNumber, - OPTION_BLACKLIST_RESERVED_IF, - (const struct option_blacklist_info *) id->driver_info)) - return -ENODEV; - - /* Don't bind network interface on Samsung GT-B3730, it is handled by a separate module */ - if (serial->dev->descriptor.idVendor == SAMSUNG_VENDOR_ID && - serial->dev->descriptor.idProduct == SAMSUNG_PRODUCT_GT_B3730 && - serial->interface->cur_altsetting->desc.bInterfaceClass != USB_CLASS_CDC_DATA) - return -ENODEV; - - - if(serial->dev->descriptor.idVendor == HUAWEI_VENDOR_ID){ - if(0!=(serial->dev->config->desc.bmAttributes&0x20)){ - usb_enable_autosuspend(serial->dev); - } - } - - data = serial->private = kzalloc(sizeof(struct usb_wwan_intf_private), GFP_KERNEL); - if (!data) - return -ENOMEM; - - if ((serial->dev->descriptor.idVendor == BORA9380_VENDOR_ID && - serial->dev->descriptor.idProduct == BORA9380_PRODUCT_ID)) { - data->send_setup = viatelecom_send_setup; - } else - data->send_setup = option_send_setup; - spin_lock_init(&data->susp_lock); - data->private = (void *)id->driver_info; - return 0; -} - -static void option_release(struct usb_serial *serial) -{ - struct usb_wwan_intf_private *priv = usb_get_serial_data(serial); - - usb_wwan_release(serial); - - kfree(priv); -} - -static void option_instat_callback(struct urb *urb) -{ - int err; - int status = urb->status; - struct usb_serial_port *port = urb->context; - struct usb_wwan_port_private *portdata = - usb_get_serial_port_data(port); - - dbg("%s", __func__); - dbg("%s: urb %p port %p has data %p", __func__, urb, port, portdata); - - if (status == 0) { - struct usb_ctrlrequest *req_pkt = - (struct usb_ctrlrequest *)urb->transfer_buffer; - - if (!req_pkt) { - dbg("%s: NULL req_pkt", __func__); - return; - } - if ((req_pkt->bRequestType == 0xA1) && - (req_pkt->bRequest == 0x20)) { - int old_dcd_state; - unsigned char signals = *((unsigned char *) - urb->transfer_buffer + - sizeof(struct usb_ctrlrequest)); - - dbg("%s: signal x%x", __func__, signals); - - old_dcd_state = portdata->dcd_state; - portdata->cts_state = 1; - portdata->dcd_state = ((signals & 0x01) ? 1 : 0); - portdata->dsr_state = ((signals & 0x02) ? 1 : 0); - portdata->ri_state = ((signals & 0x08) ? 1 : 0); - - if (old_dcd_state && !portdata->dcd_state) { - struct tty_struct *tty = - tty_port_tty_get(&port->port); - if (tty && !C_CLOCAL(tty)) - tty_hangup(tty); - tty_kref_put(tty); - } - } else { - dbg("%s: type %x req %x", __func__, - req_pkt->bRequestType, req_pkt->bRequest); - } - } else - err("%s: error %d", __func__, status); - - /* Resubmit urb so we continue receiving IRQ data */ - if (status != -ESHUTDOWN && status != -ENOENT) { - err = usb_submit_urb(urb, GFP_ATOMIC); - if (err) - dbg("%s: resubmit intr urb failed. (%d)", - __func__, err); - } -} - -/** send RTS/DTR state to the port. - * - * This is exactly the same as SET_CONTROL_LINE_STATE from the PSTN - * CDC. -*/ -static int option_send_setup(struct usb_serial_port *port) -{ - struct usb_serial *serial = port->serial; - struct usb_wwan_intf_private *intfdata = - (struct usb_wwan_intf_private *) serial->private; - struct usb_wwan_port_private *portdata; - int ifNum = serial->interface->cur_altsetting->desc.bInterfaceNumber; - int val = 0; - dbg("%s", __func__); - - if (is_blacklisted(ifNum, OPTION_BLACKLIST_SENDSETUP, - (struct option_blacklist_info *) intfdata->private)) { - dbg("No send_setup on blacklisted interface #%d\n", ifNum); - return -EIO; - } - - portdata = usb_get_serial_port_data(port); - - if (portdata->dtr_state) - val |= 0x01; - if (portdata->rts_state) - val |= 0x02; - - return usb_control_msg(serial->dev, - usb_rcvctrlpipe(serial->dev, 0), - 0x22, 0x21, val, ifNum, NULL, 0, USB_CTRL_SET_TIMEOUT); -} - -MODULE_AUTHOR(DRIVER_AUTHOR); -MODULE_DESCRIPTION(DRIVER_DESC); -MODULE_VERSION(DRIVER_VERSION); -MODULE_LICENSE("GPL"); - -module_param(debug, bool, S_IRUGO | S_IWUSR); -MODULE_PARM_DESC(debug, "Debug messages"); diff --git a/ANDROID_3.4.5/drivers/usb/serial/oti6858.c b/ANDROID_3.4.5/drivers/usb/serial/oti6858.c deleted file mode 100644 index 5fdc33c6..00000000 --- a/ANDROID_3.4.5/drivers/usb/serial/oti6858.c +++ /dev/null @@ -1,970 +0,0 @@ -/* - * Ours Technology Inc. OTi-6858 USB to serial adapter driver. - * - * Copyleft (C) 2007 Kees Lemmens (adapted for kernel 2.6.20) - * Copyright (C) 2006 Tomasz Michal Lukaszewski (FIXME: add e-mail) - * Copyright (C) 2001-2004 Greg Kroah-Hartman (greg@kroah.com) - * Copyright (C) 2003 IBM Corp. - * - * Many thanks to the authors of pl2303 driver: all functions in this file - * are heavily based on pl2303 code, buffering code is a 1-to-1 copy. - * - * Warning! You use this driver on your own risk! The only official - * description of this device I have is datasheet from manufacturer, - * and it doesn't contain almost any information needed to write a driver. - * Almost all knowlegde used while writing this driver was gathered by: - * - analyzing traffic between device and the M$ Windows 2000 driver, - * - trying different bit combinations and checking pin states - * with a voltmeter, - * - receiving malformed frames and producing buffer overflows - * to learn how errors are reported, - * So, THIS CODE CAN DESTROY OTi-6858 AND ANY OTHER DEVICES, THAT ARE - * CONNECTED TO IT! - * - * 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. - * - * See Documentation/usb/usb-serial.txt for more information on using this - * driver - * - * TODO: - * - implement correct flushing for ioctls and oti6858_close() - * - check how errors (rx overflow, parity error, framing error) are reported - * - implement oti6858_break_ctl() - * - implement more ioctls - * - test/implement flow control - * - allow setting custom baud rates - */ - -#include <linux/kernel.h> -#include <linux/errno.h> -#include <linux/init.h> -#include <linux/slab.h> -#include <linux/tty.h> -#include <linux/tty_driver.h> -#include <linux/tty_flip.h> -#include <linux/serial.h> -#include <linux/module.h> -#include <linux/moduleparam.h> -#include <linux/spinlock.h> -#include <linux/usb.h> -#include <linux/usb/serial.h> -#include <linux/uaccess.h> -#include <linux/kfifo.h> -#include "oti6858.h" - -#define OTI6858_DESCRIPTION \ - "Ours Technology Inc. OTi-6858 USB to serial adapter driver" -#define OTI6858_AUTHOR "Tomasz Michal Lukaszewski <FIXME@FIXME>" -#define OTI6858_VERSION "0.2" - -static const struct usb_device_id id_table[] = { - { USB_DEVICE(OTI6858_VENDOR_ID, OTI6858_PRODUCT_ID) }, - { } -}; - -MODULE_DEVICE_TABLE(usb, id_table); - -static struct usb_driver oti6858_driver = { - .name = "oti6858", - .probe = usb_serial_probe, - .disconnect = usb_serial_disconnect, - .id_table = id_table, -}; - -static bool debug; - -/* requests */ -#define OTI6858_REQ_GET_STATUS (USB_DIR_IN | USB_TYPE_VENDOR | 0x00) -#define OTI6858_REQ_T_GET_STATUS 0x01 - -#define OTI6858_REQ_SET_LINE (USB_DIR_OUT | USB_TYPE_VENDOR | 0x00) -#define OTI6858_REQ_T_SET_LINE 0x00 - -#define OTI6858_REQ_CHECK_TXBUFF (USB_DIR_IN | USB_TYPE_VENDOR | 0x01) -#define OTI6858_REQ_T_CHECK_TXBUFF 0x00 - -/* format of the control packet */ -struct oti6858_control_pkt { - __le16 divisor; /* baud rate = 96000000 / (16 * divisor), LE */ -#define OTI6858_MAX_BAUD_RATE 3000000 - u8 frame_fmt; -#define FMT_STOP_BITS_MASK 0xc0 -#define FMT_STOP_BITS_1 0x00 -#define FMT_STOP_BITS_2 0x40 /* 1.5 stop bits if FMT_DATA_BITS_5 */ -#define FMT_PARITY_MASK 0x38 -#define FMT_PARITY_NONE 0x00 -#define FMT_PARITY_ODD 0x08 -#define FMT_PARITY_EVEN 0x18 -#define FMT_PARITY_MARK 0x28 -#define FMT_PARITY_SPACE 0x38 -#define FMT_DATA_BITS_MASK 0x03 -#define FMT_DATA_BITS_5 0x00 -#define FMT_DATA_BITS_6 0x01 -#define FMT_DATA_BITS_7 0x02 -#define FMT_DATA_BITS_8 0x03 - u8 something; /* always equals 0x43 */ - u8 control; /* settings of flow control lines */ -#define CONTROL_MASK 0x0c -#define CONTROL_DTR_HIGH 0x08 -#define CONTROL_RTS_HIGH 0x04 - u8 tx_status; -#define TX_BUFFER_EMPTIED 0x09 - u8 pin_state; -#define PIN_MASK 0x3f -#define PIN_RTS 0x20 /* output pin */ -#define PIN_CTS 0x10 /* input pin, active low */ -#define PIN_DSR 0x08 /* input pin, active low */ -#define PIN_DTR 0x04 /* output pin */ -#define PIN_RI 0x02 /* input pin, active low */ -#define PIN_DCD 0x01 /* input pin, active low */ - u8 rx_bytes_avail; /* number of bytes in rx buffer */; -}; - -#define OTI6858_CTRL_PKT_SIZE sizeof(struct oti6858_control_pkt) -#define OTI6858_CTRL_EQUALS_PENDING(a, priv) \ - (((a)->divisor == (priv)->pending_setup.divisor) \ - && ((a)->control == (priv)->pending_setup.control) \ - && ((a)->frame_fmt == (priv)->pending_setup.frame_fmt)) - -/* function prototypes */ -static int oti6858_open(struct tty_struct *tty, struct usb_serial_port *port); -static void oti6858_close(struct usb_serial_port *port); -static void oti6858_set_termios(struct tty_struct *tty, - struct usb_serial_port *port, struct ktermios *old); -static void oti6858_init_termios(struct tty_struct *tty); -static int oti6858_ioctl(struct tty_struct *tty, - unsigned int cmd, unsigned long arg); -static void oti6858_read_int_callback(struct urb *urb); -static void oti6858_read_bulk_callback(struct urb *urb); -static void oti6858_write_bulk_callback(struct urb *urb); -static int oti6858_write(struct tty_struct *tty, struct usb_serial_port *port, - const unsigned char *buf, int count); -static int oti6858_write_room(struct tty_struct *tty); -static int oti6858_chars_in_buffer(struct tty_struct *tty); -static int oti6858_tiocmget(struct tty_struct *tty); -static int oti6858_tiocmset(struct tty_struct *tty, - unsigned int set, unsigned int clear); -static int oti6858_startup(struct usb_serial *serial); -static void oti6858_release(struct usb_serial *serial); - -/* device info */ -static struct usb_serial_driver oti6858_device = { - .driver = { - .owner = THIS_MODULE, - .name = "oti6858", - }, - .id_table = id_table, - .num_ports = 1, - .open = oti6858_open, - .close = oti6858_close, - .write = oti6858_write, - .ioctl = oti6858_ioctl, - .set_termios = oti6858_set_termios, - .init_termios = oti6858_init_termios, - .tiocmget = oti6858_tiocmget, - .tiocmset = oti6858_tiocmset, - .read_bulk_callback = oti6858_read_bulk_callback, - .read_int_callback = oti6858_read_int_callback, - .write_bulk_callback = oti6858_write_bulk_callback, - .write_room = oti6858_write_room, - .chars_in_buffer = oti6858_chars_in_buffer, - .attach = oti6858_startup, - .release = oti6858_release, -}; - -static struct usb_serial_driver * const serial_drivers[] = { - &oti6858_device, NULL -}; - -struct oti6858_private { - spinlock_t lock; - - struct oti6858_control_pkt status; - - struct { - u8 read_urb_in_use; - u8 write_urb_in_use; - } flags; - struct delayed_work delayed_write_work; - - struct { - __le16 divisor; - u8 frame_fmt; - u8 control; - } pending_setup; - u8 transient; - u8 setup_done; - struct delayed_work delayed_setup_work; - - wait_queue_head_t intr_wait; - struct usb_serial_port *port; /* USB port with which associated */ -}; - -static void setup_line(struct work_struct *work) -{ - struct oti6858_private *priv = container_of(work, - struct oti6858_private, delayed_setup_work.work); - struct usb_serial_port *port = priv->port; - struct oti6858_control_pkt *new_setup; - unsigned long flags; - int result; - - dbg("%s(port = %d)", __func__, port->number); - - new_setup = kmalloc(OTI6858_CTRL_PKT_SIZE, GFP_KERNEL); - if (new_setup == NULL) { - dev_err(&port->dev, "%s(): out of memory!\n", __func__); - /* we will try again */ - schedule_delayed_work(&priv->delayed_setup_work, - msecs_to_jiffies(2)); - return; - } - - result = usb_control_msg(port->serial->dev, - usb_rcvctrlpipe(port->serial->dev, 0), - OTI6858_REQ_T_GET_STATUS, - OTI6858_REQ_GET_STATUS, - 0, 0, - new_setup, OTI6858_CTRL_PKT_SIZE, - 100); - - if (result != OTI6858_CTRL_PKT_SIZE) { - dev_err(&port->dev, "%s(): error reading status\n", __func__); - kfree(new_setup); - /* we will try again */ - schedule_delayed_work(&priv->delayed_setup_work, - msecs_to_jiffies(2)); - return; - } - - spin_lock_irqsave(&priv->lock, flags); - if (!OTI6858_CTRL_EQUALS_PENDING(new_setup, priv)) { - new_setup->divisor = priv->pending_setup.divisor; - new_setup->control = priv->pending_setup.control; - new_setup->frame_fmt = priv->pending_setup.frame_fmt; - - spin_unlock_irqrestore(&priv->lock, flags); - result = usb_control_msg(port->serial->dev, - usb_sndctrlpipe(port->serial->dev, 0), - OTI6858_REQ_T_SET_LINE, - OTI6858_REQ_SET_LINE, - 0, 0, - new_setup, OTI6858_CTRL_PKT_SIZE, - 100); - } else { - spin_unlock_irqrestore(&priv->lock, flags); - result = 0; - } - kfree(new_setup); - - spin_lock_irqsave(&priv->lock, flags); - if (result != OTI6858_CTRL_PKT_SIZE) - priv->transient = 0; - priv->setup_done = 1; - spin_unlock_irqrestore(&priv->lock, flags); - - dbg("%s(): submitting interrupt urb", __func__); - result = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL); - if (result != 0) { - dev_err(&port->dev, "%s(): usb_submit_urb() failed" - " with error %d\n", __func__, result); - } -} - -static void send_data(struct work_struct *work) -{ - struct oti6858_private *priv = container_of(work, - struct oti6858_private, delayed_write_work.work); - struct usb_serial_port *port = priv->port; - int count = 0, result; - unsigned long flags; - u8 *allow; - - dbg("%s(port = %d)", __func__, port->number); - - spin_lock_irqsave(&priv->lock, flags); - if (priv->flags.write_urb_in_use) { - spin_unlock_irqrestore(&priv->lock, flags); - schedule_delayed_work(&priv->delayed_write_work, - msecs_to_jiffies(2)); - return; - } - priv->flags.write_urb_in_use = 1; - spin_unlock_irqrestore(&priv->lock, flags); - - spin_lock_irqsave(&port->lock, flags); - count = kfifo_len(&port->write_fifo); - spin_unlock_irqrestore(&port->lock, flags); - - if (count > port->bulk_out_size) - count = port->bulk_out_size; - - if (count != 0) { - allow = kmalloc(1, GFP_KERNEL); - if (!allow) { - dev_err_console(port, "%s(): kmalloc failed\n", - __func__); - return; - } - result = usb_control_msg(port->serial->dev, - usb_rcvctrlpipe(port->serial->dev, 0), - OTI6858_REQ_T_CHECK_TXBUFF, - OTI6858_REQ_CHECK_TXBUFF, - count, 0, allow, 1, 100); - if (result != 1 || *allow != 0) - count = 0; - kfree(allow); - } - - if (count == 0) { - priv->flags.write_urb_in_use = 0; - - dbg("%s(): submitting interrupt urb", __func__); - result = usb_submit_urb(port->interrupt_in_urb, GFP_NOIO); - if (result != 0) { - dev_err(&port->dev, "%s(): usb_submit_urb() failed" - " with error %d\n", __func__, result); - } - return; - } - - count = kfifo_out_locked(&port->write_fifo, - port->write_urb->transfer_buffer, - count, &port->lock); - port->write_urb->transfer_buffer_length = count; - result = usb_submit_urb(port->write_urb, GFP_NOIO); - if (result != 0) { - dev_err_console(port, "%s(): usb_submit_urb() failed" - " with error %d\n", __func__, result); - priv->flags.write_urb_in_use = 0; - } - - usb_serial_port_softint(port); -} - -static int oti6858_startup(struct usb_serial *serial) -{ - struct usb_serial_port *port = serial->port[0]; - struct oti6858_private *priv; - int i; - - for (i = 0; i < serial->num_ports; ++i) { - priv = kzalloc(sizeof(struct oti6858_private), GFP_KERNEL); - if (!priv) - break; - - spin_lock_init(&priv->lock); - init_waitqueue_head(&priv->intr_wait); -/* INIT_WORK(&priv->setup_work, setup_line, serial->port[i]); */ -/* INIT_WORK(&priv->write_work, send_data, serial->port[i]); */ - priv->port = port; - INIT_DELAYED_WORK(&priv->delayed_setup_work, setup_line); - INIT_DELAYED_WORK(&priv->delayed_write_work, send_data); - - usb_set_serial_port_data(serial->port[i], priv); - } - if (i == serial->num_ports) - return 0; - - for (--i; i >= 0; --i) { - priv = usb_get_serial_port_data(serial->port[i]); - kfree(priv); - usb_set_serial_port_data(serial->port[i], NULL); - } - return -ENOMEM; -} - -static int oti6858_write(struct tty_struct *tty, struct usb_serial_port *port, - const unsigned char *buf, int count) -{ - dbg("%s(port = %d, count = %d)", __func__, port->number, count); - - if (!count) - return count; - - count = kfifo_in_locked(&port->write_fifo, buf, count, &port->lock); - - return count; -} - -static int oti6858_write_room(struct tty_struct *tty) -{ - struct usb_serial_port *port = tty->driver_data; - int room = 0; - unsigned long flags; - - dbg("%s(port = %d)", __func__, port->number); - - spin_lock_irqsave(&port->lock, flags); - room = kfifo_avail(&port->write_fifo); - spin_unlock_irqrestore(&port->lock, flags); - - return room; -} - -static int oti6858_chars_in_buffer(struct tty_struct *tty) -{ - struct usb_serial_port *port = tty->driver_data; - int chars = 0; - unsigned long flags; - - dbg("%s(port = %d)", __func__, port->number); - - spin_lock_irqsave(&port->lock, flags); - chars = kfifo_len(&port->write_fifo); - spin_unlock_irqrestore(&port->lock, flags); - - return chars; -} - -static void oti6858_init_termios(struct tty_struct *tty) -{ - *(tty->termios) = tty_std_termios; - tty->termios->c_cflag = B38400 | CS8 | CREAD | HUPCL | CLOCAL; - tty->termios->c_ispeed = 38400; - tty->termios->c_ospeed = 38400; -} - -static void oti6858_set_termios(struct tty_struct *tty, - struct usb_serial_port *port, struct ktermios *old_termios) -{ - struct oti6858_private *priv = usb_get_serial_port_data(port); - unsigned long flags; - unsigned int cflag; - u8 frame_fmt, control; - __le16 divisor; - int br; - - dbg("%s(port = %d)", __func__, port->number); - - if (!tty) { - dbg("%s(): no tty structures", __func__); - return; - } - - cflag = tty->termios->c_cflag; - - spin_lock_irqsave(&priv->lock, flags); - divisor = priv->pending_setup.divisor; - frame_fmt = priv->pending_setup.frame_fmt; - control = priv->pending_setup.control; - spin_unlock_irqrestore(&priv->lock, flags); - - frame_fmt &= ~FMT_DATA_BITS_MASK; - switch (cflag & CSIZE) { - case CS5: - frame_fmt |= FMT_DATA_BITS_5; - break; - case CS6: - frame_fmt |= FMT_DATA_BITS_6; - break; - case CS7: - frame_fmt |= FMT_DATA_BITS_7; - break; - default: - case CS8: - frame_fmt |= FMT_DATA_BITS_8; - break; - } - - /* manufacturer claims that this device can work with baud rates - * up to 3 Mbps; I've tested it only on 115200 bps, so I can't - * guarantee that any other baud rate will work (especially - * the higher ones) - */ - br = tty_get_baud_rate(tty); - if (br == 0) { - divisor = 0; - } else { - int real_br; - int new_divisor; - br = min(br, OTI6858_MAX_BAUD_RATE); - - new_divisor = (96000000 + 8 * br) / (16 * br); - real_br = 96000000 / (16 * new_divisor); - divisor = cpu_to_le16(new_divisor); - tty_encode_baud_rate(tty, real_br, real_br); - } - - frame_fmt &= ~FMT_STOP_BITS_MASK; - if ((cflag & CSTOPB) != 0) - frame_fmt |= FMT_STOP_BITS_2; - else - frame_fmt |= FMT_STOP_BITS_1; - - frame_fmt &= ~FMT_PARITY_MASK; - if ((cflag & PARENB) != 0) { - if ((cflag & PARODD) != 0) - frame_fmt |= FMT_PARITY_ODD; - else - frame_fmt |= FMT_PARITY_EVEN; - } else { - frame_fmt |= FMT_PARITY_NONE; - } - - control &= ~CONTROL_MASK; - if ((cflag & CRTSCTS) != 0) - control |= (CONTROL_DTR_HIGH | CONTROL_RTS_HIGH); - - /* change control lines if we are switching to or from B0 */ - /* FIXME: - spin_lock_irqsave(&priv->lock, flags); - control = priv->line_control; - if ((cflag & CBAUD) == B0) - priv->line_control &= ~(CONTROL_DTR | CONTROL_RTS); - else - priv->line_control |= (CONTROL_DTR | CONTROL_RTS); - if (control != priv->line_control) { - control = priv->line_control; - spin_unlock_irqrestore(&priv->lock, flags); - set_control_lines(serial->dev, control); - } else { - spin_unlock_irqrestore(&priv->lock, flags); - } - */ - - spin_lock_irqsave(&priv->lock, flags); - if (divisor != priv->pending_setup.divisor - || control != priv->pending_setup.control - || frame_fmt != priv->pending_setup.frame_fmt) { - priv->pending_setup.divisor = divisor; - priv->pending_setup.control = control; - priv->pending_setup.frame_fmt = frame_fmt; - } - spin_unlock_irqrestore(&priv->lock, flags); -} - -static int oti6858_open(struct tty_struct *tty, struct usb_serial_port *port) -{ - struct oti6858_private *priv = usb_get_serial_port_data(port); - struct ktermios tmp_termios; - struct usb_serial *serial = port->serial; - struct oti6858_control_pkt *buf; - unsigned long flags; - int result; - - dbg("%s(port = %d)", __func__, port->number); - - usb_clear_halt(serial->dev, port->write_urb->pipe); - usb_clear_halt(serial->dev, port->read_urb->pipe); - - buf = kmalloc(OTI6858_CTRL_PKT_SIZE, GFP_KERNEL); - if (buf == NULL) { - dev_err(&port->dev, "%s(): out of memory!\n", __func__); - return -ENOMEM; - } - - result = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0), - OTI6858_REQ_T_GET_STATUS, - OTI6858_REQ_GET_STATUS, - 0, 0, - buf, OTI6858_CTRL_PKT_SIZE, - 100); - if (result != OTI6858_CTRL_PKT_SIZE) { - /* assume default (after power-on reset) values */ - buf->divisor = cpu_to_le16(0x009c); /* 38400 bps */ - buf->frame_fmt = 0x03; /* 8N1 */ - buf->something = 0x43; - buf->control = 0x4c; /* DTR, RTS */ - buf->tx_status = 0x00; - buf->pin_state = 0x5b; /* RTS, CTS, DSR, DTR, RI, DCD */ - buf->rx_bytes_avail = 0x00; - } - - spin_lock_irqsave(&priv->lock, flags); - memcpy(&priv->status, buf, OTI6858_CTRL_PKT_SIZE); - priv->pending_setup.divisor = buf->divisor; - priv->pending_setup.frame_fmt = buf->frame_fmt; - priv->pending_setup.control = buf->control; - spin_unlock_irqrestore(&priv->lock, flags); - kfree(buf); - - dbg("%s(): submitting interrupt urb", __func__); - result = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL); - if (result != 0) { - dev_err(&port->dev, "%s(): usb_submit_urb() failed" - " with error %d\n", __func__, result); - oti6858_close(port); - return result; - } - - /* setup termios */ - if (tty) - oti6858_set_termios(tty, port, &tmp_termios); - port->port.drain_delay = 256; /* FIXME: check the FIFO length */ - return 0; -} - -static void oti6858_close(struct usb_serial_port *port) -{ - struct oti6858_private *priv = usb_get_serial_port_data(port); - unsigned long flags; - - dbg("%s(port = %d)", __func__, port->number); - - spin_lock_irqsave(&port->lock, flags); - /* clear out any remaining data in the buffer */ - kfifo_reset_out(&port->write_fifo); - spin_unlock_irqrestore(&port->lock, flags); - - dbg("%s(): after buf_clear()", __func__); - - /* cancel scheduled setup */ - cancel_delayed_work_sync(&priv->delayed_setup_work); - cancel_delayed_work_sync(&priv->delayed_write_work); - - /* shutdown our urbs */ - dbg("%s(): shutting down urbs", __func__); - usb_kill_urb(port->write_urb); - usb_kill_urb(port->read_urb); - usb_kill_urb(port->interrupt_in_urb); -} - -static int oti6858_tiocmset(struct tty_struct *tty, - unsigned int set, unsigned int clear) -{ - struct usb_serial_port *port = tty->driver_data; - struct oti6858_private *priv = usb_get_serial_port_data(port); - unsigned long flags; - u8 control; - - dbg("%s(port = %d, set = 0x%08x, clear = 0x%08x)", - __func__, port->number, set, clear); - - if (!usb_get_intfdata(port->serial->interface)) - return -ENODEV; - - /* FIXME: check if this is correct (active high/low) */ - spin_lock_irqsave(&priv->lock, flags); - control = priv->pending_setup.control; - if ((set & TIOCM_RTS) != 0) - control |= CONTROL_RTS_HIGH; - if ((set & TIOCM_DTR) != 0) - control |= CONTROL_DTR_HIGH; - if ((clear & TIOCM_RTS) != 0) - control &= ~CONTROL_RTS_HIGH; - if ((clear & TIOCM_DTR) != 0) - control &= ~CONTROL_DTR_HIGH; - - if (control != priv->pending_setup.control) - priv->pending_setup.control = control; - - spin_unlock_irqrestore(&priv->lock, flags); - return 0; -} - -static int oti6858_tiocmget(struct tty_struct *tty) -{ - struct usb_serial_port *port = tty->driver_data; - struct oti6858_private *priv = usb_get_serial_port_data(port); - unsigned long flags; - unsigned pin_state; - unsigned result = 0; - - dbg("%s(port = %d)", __func__, port->number); - - if (!usb_get_intfdata(port->serial->interface)) - return -ENODEV; - - spin_lock_irqsave(&priv->lock, flags); - pin_state = priv->status.pin_state & PIN_MASK; - spin_unlock_irqrestore(&priv->lock, flags); - - /* FIXME: check if this is correct (active high/low) */ - if ((pin_state & PIN_RTS) != 0) - result |= TIOCM_RTS; - if ((pin_state & PIN_CTS) != 0) - result |= TIOCM_CTS; - if ((pin_state & PIN_DSR) != 0) - result |= TIOCM_DSR; - if ((pin_state & PIN_DTR) != 0) - result |= TIOCM_DTR; - if ((pin_state & PIN_RI) != 0) - result |= TIOCM_RI; - if ((pin_state & PIN_DCD) != 0) - result |= TIOCM_CD; - - dbg("%s() = 0x%08x", __func__, result); - - return result; -} - -static int wait_modem_info(struct usb_serial_port *port, unsigned int arg) -{ - struct oti6858_private *priv = usb_get_serial_port_data(port); - unsigned long flags; - unsigned int prev, status; - unsigned int changed; - - spin_lock_irqsave(&priv->lock, flags); - prev = priv->status.pin_state; - spin_unlock_irqrestore(&priv->lock, flags); - - while (1) { - wait_event_interruptible(priv->intr_wait, - priv->status.pin_state != prev); - if (signal_pending(current)) - return -ERESTARTSYS; - - spin_lock_irqsave(&priv->lock, flags); - status = priv->status.pin_state & PIN_MASK; - spin_unlock_irqrestore(&priv->lock, flags); - - changed = prev ^ status; - /* FIXME: check if this is correct (active high/low) */ - if (((arg & TIOCM_RNG) && (changed & PIN_RI)) || - ((arg & TIOCM_DSR) && (changed & PIN_DSR)) || - ((arg & TIOCM_CD) && (changed & PIN_DCD)) || - ((arg & TIOCM_CTS) && (changed & PIN_CTS))) - return 0; - prev = status; - } - - /* NOTREACHED */ - return 0; -} - -static int oti6858_ioctl(struct tty_struct *tty, - unsigned int cmd, unsigned long arg) -{ - struct usb_serial_port *port = tty->driver_data; - - dbg("%s(port = %d, cmd = 0x%04x, arg = 0x%08lx)", - __func__, port->number, cmd, arg); - - switch (cmd) { - case TIOCMIWAIT: - dbg("%s(): TIOCMIWAIT", __func__); - return wait_modem_info(port, arg); - default: - dbg("%s(): 0x%04x not supported", __func__, cmd); - break; - } - return -ENOIOCTLCMD; -} - - -static void oti6858_release(struct usb_serial *serial) -{ - int i; - - dbg("%s()", __func__); - - for (i = 0; i < serial->num_ports; ++i) - kfree(usb_get_serial_port_data(serial->port[i])); -} - -static void oti6858_read_int_callback(struct urb *urb) -{ - struct usb_serial_port *port = urb->context; - struct oti6858_private *priv = usb_get_serial_port_data(port); - int transient = 0, can_recv = 0, resubmit = 1; - int status = urb->status; - - dbg("%s(port = %d, status = %d)", - __func__, port->number, status); - - switch (status) { - case 0: - /* success */ - break; - case -ECONNRESET: - case -ENOENT: - case -ESHUTDOWN: - /* this urb is terminated, clean up */ - dbg("%s(): urb shutting down with status: %d", - __func__, status); - return; - default: - dbg("%s(): nonzero urb status received: %d", - __func__, status); - break; - } - - if (status == 0 && urb->actual_length == OTI6858_CTRL_PKT_SIZE) { - struct oti6858_control_pkt *xs = urb->transfer_buffer; - unsigned long flags; - - spin_lock_irqsave(&priv->lock, flags); - - if (!priv->transient) { - if (!OTI6858_CTRL_EQUALS_PENDING(xs, priv)) { - if (xs->rx_bytes_avail == 0) { - priv->transient = 4; - priv->setup_done = 0; - resubmit = 0; - dbg("%s(): scheduling setup_line()", - __func__); - schedule_delayed_work(&priv->delayed_setup_work, 0); - } - } - } else { - if (OTI6858_CTRL_EQUALS_PENDING(xs, priv)) { - priv->transient = 0; - } else if (!priv->setup_done) { - resubmit = 0; - } else if (--priv->transient == 0) { - if (xs->rx_bytes_avail == 0) { - priv->transient = 4; - priv->setup_done = 0; - resubmit = 0; - dbg("%s(): scheduling setup_line()", - __func__); - schedule_delayed_work(&priv->delayed_setup_work, 0); - } - } - } - - if (!priv->transient) { - if (xs->pin_state != priv->status.pin_state) - wake_up_interruptible(&priv->intr_wait); - memcpy(&priv->status, xs, OTI6858_CTRL_PKT_SIZE); - } - - if (!priv->transient && xs->rx_bytes_avail != 0) { - can_recv = xs->rx_bytes_avail; - priv->flags.read_urb_in_use = 1; - } - - transient = priv->transient; - spin_unlock_irqrestore(&priv->lock, flags); - } - - if (can_recv) { - int result; - - result = usb_submit_urb(port->read_urb, GFP_ATOMIC); - if (result != 0) { - priv->flags.read_urb_in_use = 0; - dev_err(&port->dev, "%s(): usb_submit_urb() failed," - " error %d\n", __func__, result); - } else { - resubmit = 0; - } - } else if (!transient) { - unsigned long flags; - int count; - - spin_lock_irqsave(&port->lock, flags); - count = kfifo_len(&port->write_fifo); - spin_unlock_irqrestore(&port->lock, flags); - - spin_lock_irqsave(&priv->lock, flags); - if (priv->flags.write_urb_in_use == 0 && count != 0) { - schedule_delayed_work(&priv->delayed_write_work, 0); - resubmit = 0; - } - spin_unlock_irqrestore(&priv->lock, flags); - } - - if (resubmit) { - int result; - -/* dbg("%s(): submitting interrupt urb", __func__); */ - result = usb_submit_urb(urb, GFP_ATOMIC); - if (result != 0) { - dev_err(&urb->dev->dev, - "%s(): usb_submit_urb() failed with" - " error %d\n", __func__, result); - } - } -} - -static void oti6858_read_bulk_callback(struct urb *urb) -{ - struct usb_serial_port *port = urb->context; - struct oti6858_private *priv = usb_get_serial_port_data(port); - struct tty_struct *tty; - unsigned char *data = urb->transfer_buffer; - unsigned long flags; - int status = urb->status; - int result; - - dbg("%s(port = %d, status = %d)", - __func__, port->number, status); - - spin_lock_irqsave(&priv->lock, flags); - priv->flags.read_urb_in_use = 0; - spin_unlock_irqrestore(&priv->lock, flags); - - if (status != 0) { - dbg("%s(): unable to handle the error, exiting", __func__); - return; - } - - tty = tty_port_tty_get(&port->port); - if (tty != NULL && urb->actual_length > 0) { - tty_insert_flip_string(tty, data, urb->actual_length); - tty_flip_buffer_push(tty); - } - tty_kref_put(tty); - - /* schedule the interrupt urb */ - result = usb_submit_urb(port->interrupt_in_urb, GFP_ATOMIC); - if (result != 0 && result != -EPERM) { - dev_err(&port->dev, "%s(): usb_submit_urb() failed," - " error %d\n", __func__, result); - } -} - -static void oti6858_write_bulk_callback(struct urb *urb) -{ - struct usb_serial_port *port = urb->context; - struct oti6858_private *priv = usb_get_serial_port_data(port); - int status = urb->status; - int result; - - dbg("%s(port = %d, status = %d)", - __func__, port->number, status); - - switch (status) { - case 0: - /* success */ - break; - case -ECONNRESET: - case -ENOENT: - case -ESHUTDOWN: - /* this urb is terminated, clean up */ - dbg("%s(): urb shutting down with status: %d", - __func__, status); - priv->flags.write_urb_in_use = 0; - return; - default: - /* error in the urb, so we have to resubmit it */ - dbg("%s(): nonzero write bulk status received: %d", - __func__, status); - dbg("%s(): overflow in write", __func__); - - port->write_urb->transfer_buffer_length = 1; - result = usb_submit_urb(port->write_urb, GFP_ATOMIC); - if (result) { - dev_err_console(port, "%s(): usb_submit_urb() failed," - " error %d\n", __func__, result); - } else { - return; - } - } - - priv->flags.write_urb_in_use = 0; - - /* schedule the interrupt urb if we are still open */ - dbg("%s(): submitting interrupt urb", __func__); - result = usb_submit_urb(port->interrupt_in_urb, GFP_ATOMIC); - if (result != 0) { - dev_err(&port->dev, "%s(): failed submitting int urb," - " error %d\n", __func__, result); - } -} - -module_usb_serial_driver(oti6858_driver, serial_drivers); - -MODULE_DESCRIPTION(OTI6858_DESCRIPTION); -MODULE_AUTHOR(OTI6858_AUTHOR); -MODULE_VERSION(OTI6858_VERSION); -MODULE_LICENSE("GPL"); - -module_param(debug, bool, S_IRUGO | S_IWUSR); -MODULE_PARM_DESC(debug, "enable debug output"); - diff --git a/ANDROID_3.4.5/drivers/usb/serial/oti6858.h b/ANDROID_3.4.5/drivers/usb/serial/oti6858.h deleted file mode 100644 index 704ac3a5..00000000 --- a/ANDROID_3.4.5/drivers/usb/serial/oti6858.h +++ /dev/null @@ -1,15 +0,0 @@ -/* - * Ours Technology Inc. OTi-6858 USB to serial adapter driver. - * - * 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. - */ -#ifndef __LINUX_USB_SERIAL_OTI6858_H -#define __LINUX_USB_SERIAL_OTI6858_H - -#define OTI6858_VENDOR_ID 0x0ea0 -#define OTI6858_PRODUCT_ID 0x6858 - -#endif diff --git a/ANDROID_3.4.5/drivers/usb/serial/pl2303.c b/ANDROID_3.4.5/drivers/usb/serial/pl2303.c deleted file mode 100644 index a1a90629..00000000 --- a/ANDROID_3.4.5/drivers/usb/serial/pl2303.c +++ /dev/null @@ -1,865 +0,0 @@ -/* - * Prolific PL2303 USB to serial adaptor driver - * - * Copyright (C) 2001-2007 Greg Kroah-Hartman (greg@kroah.com) - * Copyright (C) 2003 IBM Corp. - * - * Original driver for 2.2.x by anonymous - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License version - * 2 as published by the Free Software Foundation. - * - * See Documentation/usb/usb-serial.txt for more information on using this - * driver - * - */ - -#include <linux/kernel.h> -#include <linux/errno.h> -#include <linux/init.h> -#include <linux/slab.h> -#include <linux/tty.h> -#include <linux/tty_driver.h> -#include <linux/tty_flip.h> -#include <linux/serial.h> -#include <linux/module.h> -#include <linux/moduleparam.h> -#include <linux/spinlock.h> -#include <linux/uaccess.h> -#include <linux/usb.h> -#include <linux/usb/serial.h> -#include "pl2303.h" - -/* - * Version Information - */ -#define DRIVER_DESC "Prolific PL2303 USB to serial adaptor driver" - -static bool debug; - -#define PL2303_CLOSING_WAIT (30*HZ) - -static const struct usb_device_id id_table[] = { - { 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) }, - { } /* Terminating entry */ -}; - -MODULE_DEVICE_TABLE(usb, id_table); - -static struct usb_driver pl2303_driver = { - .name = "pl2303", - .probe = usb_serial_probe, - .disconnect = usb_serial_disconnect, - .id_table = id_table, - .suspend = usb_serial_suspend, - .resume = usb_serial_resume, - .supports_autosuspend = 1, -}; - -#define SET_LINE_REQUEST_TYPE 0x21 -#define SET_LINE_REQUEST 0x20 - -#define SET_CONTROL_REQUEST_TYPE 0x21 -#define SET_CONTROL_REQUEST 0x22 -#define CONTROL_DTR 0x01 -#define CONTROL_RTS 0x02 - -#define BREAK_REQUEST_TYPE 0x21 -#define BREAK_REQUEST 0x23 -#define BREAK_ON 0xffff -#define BREAK_OFF 0x0000 - -#define GET_LINE_REQUEST_TYPE 0xa1 -#define GET_LINE_REQUEST 0x21 - -#define VENDOR_WRITE_REQUEST_TYPE 0x40 -#define VENDOR_WRITE_REQUEST 0x01 - -#define VENDOR_READ_REQUEST_TYPE 0xc0 -#define VENDOR_READ_REQUEST 0x01 - -#define UART_STATE 0x08 -#define UART_STATE_TRANSIENT_MASK 0x74 -#define UART_DCD 0x01 -#define UART_DSR 0x02 -#define UART_BREAK_ERROR 0x04 -#define UART_RING 0x08 -#define UART_FRAME_ERROR 0x10 -#define UART_PARITY_ERROR 0x20 -#define UART_OVERRUN_ERROR 0x40 -#define UART_CTS 0x80 - - -enum pl2303_type { - type_0, /* don't know the difference between type 0 and */ - type_1, /* type 1, until someone from prolific tells us... */ - HX, /* HX version of the pl2303 chip */ -}; - -struct pl2303_private { - spinlock_t lock; - wait_queue_head_t delta_msr_wait; - u8 line_control; - u8 line_status; - enum pl2303_type type; -}; - -static int pl2303_vendor_read(__u16 value, __u16 index, - struct usb_serial *serial, unsigned char *buf) -{ - int res = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0), - VENDOR_READ_REQUEST, VENDOR_READ_REQUEST_TYPE, - value, index, buf, 1, 100); - dbg("0x%x:0x%x:0x%x:0x%x %d - %x", VENDOR_READ_REQUEST_TYPE, - VENDOR_READ_REQUEST, value, index, res, buf[0]); - return res; -} - -static int pl2303_vendor_write(__u16 value, __u16 index, - struct usb_serial *serial) -{ - int res = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0), - VENDOR_WRITE_REQUEST, VENDOR_WRITE_REQUEST_TYPE, - value, index, NULL, 0, 100); - dbg("0x%x:0x%x:0x%x:0x%x %d", VENDOR_WRITE_REQUEST_TYPE, - VENDOR_WRITE_REQUEST, value, index, res); - return res; -} - -static int pl2303_startup(struct usb_serial *serial) -{ - struct pl2303_private *priv; - enum pl2303_type type = type_0; - unsigned char *buf; - int i; - - buf = kmalloc(10, GFP_KERNEL); - if (buf == NULL) - return -ENOMEM; - - if (serial->dev->descriptor.bDeviceClass == 0x02) - type = type_0; - else if (serial->dev->descriptor.bMaxPacketSize0 == 0x40) - type = HX; - else if (serial->dev->descriptor.bDeviceClass == 0x00) - type = type_1; - else if (serial->dev->descriptor.bDeviceClass == 0xFF) - type = type_1; - dbg("device type: %d", type); - - for (i = 0; i < serial->num_ports; ++i) { - priv = kzalloc(sizeof(struct pl2303_private), GFP_KERNEL); - if (!priv) - goto cleanup; - spin_lock_init(&priv->lock); - init_waitqueue_head(&priv->delta_msr_wait); - priv->type = type; - usb_set_serial_port_data(serial->port[i], priv); - } - - pl2303_vendor_read(0x8484, 0, serial, buf); - pl2303_vendor_write(0x0404, 0, serial); - pl2303_vendor_read(0x8484, 0, serial, buf); - pl2303_vendor_read(0x8383, 0, serial, buf); - pl2303_vendor_read(0x8484, 0, serial, buf); - pl2303_vendor_write(0x0404, 1, serial); - pl2303_vendor_read(0x8484, 0, serial, buf); - pl2303_vendor_read(0x8383, 0, serial, buf); - pl2303_vendor_write(0, 1, serial); - pl2303_vendor_write(1, 0, serial); - if (type == HX) - pl2303_vendor_write(2, 0x44, serial); - else - pl2303_vendor_write(2, 0x24, serial); - - kfree(buf); - return 0; - -cleanup: - kfree(buf); - for (--i; i >= 0; --i) { - priv = usb_get_serial_port_data(serial->port[i]); - kfree(priv); - usb_set_serial_port_data(serial->port[i], NULL); - } - return -ENOMEM; -} - -static int set_control_lines(struct usb_device *dev, u8 value) -{ - int retval; - - retval = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), - SET_CONTROL_REQUEST, SET_CONTROL_REQUEST_TYPE, - value, 0, NULL, 0, 100); - dbg("%s - value = %d, retval = %d", __func__, value, retval); - return retval; -} - -static void pl2303_set_termios(struct tty_struct *tty, - struct usb_serial_port *port, struct ktermios *old_termios) -{ - struct usb_serial *serial = port->serial; - struct pl2303_private *priv = usb_get_serial_port_data(port); - unsigned long flags; - unsigned int cflag; - unsigned char *buf; - int baud; - int i; - u8 control; - const int baud_sup[] = { 75, 150, 300, 600, 1200, 1800, 2400, 3600, - 4800, 7200, 9600, 14400, 19200, 28800, 38400, - 57600, 115200, 230400, 460800, 614400, - 921600, 1228800, 2457600, 3000000, 6000000 }; - int baud_floor, baud_ceil; - int k; - - dbg("%s - port %d", __func__, port->number); - - /* The PL2303 is reported to lose bytes if you change - serial settings even to the same values as before. Thus - we actually need to filter in this specific case */ - - if (!tty_termios_hw_change(tty->termios, old_termios)) - return; - - cflag = tty->termios->c_cflag; - - buf = kzalloc(7, GFP_KERNEL); - if (!buf) { - dev_err(&port->dev, "%s - out of memory.\n", __func__); - /* Report back no change occurred */ - *tty->termios = *old_termios; - return; - } - - i = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0), - GET_LINE_REQUEST, GET_LINE_REQUEST_TYPE, - 0, 0, buf, 7, 100); - dbg("0xa1:0x21:0:0 %d - %x %x %x %x %x %x %x", i, - buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], buf[6]); - - if (cflag & CSIZE) { - switch (cflag & CSIZE) { - case CS5: - buf[6] = 5; - break; - case CS6: - buf[6] = 6; - break; - case CS7: - buf[6] = 7; - break; - default: - case CS8: - buf[6] = 8; - break; - } - dbg("%s - data bits = %d", __func__, buf[6]); - } - - /* For reference buf[0]:buf[3] baud rate value */ - /* NOTE: Only the values defined in baud_sup are supported ! - * => if unsupported values are set, the PL2303 seems to use - * 9600 baud (at least my PL2303X always does) - */ - baud = tty_get_baud_rate(tty); - dbg("%s - baud requested = %d", __func__, baud); - if (baud) { - /* Set baudrate to nearest supported value */ - for (k=0; k<ARRAY_SIZE(baud_sup); k++) { - if (baud_sup[k] / baud) { - baud_ceil = baud_sup[k]; - if (k==0) { - baud = baud_ceil; - } else { - baud_floor = baud_sup[k-1]; - if ((baud_ceil % baud) - > (baud % baud_floor)) - baud = baud_floor; - else - baud = baud_ceil; - } - break; - } - } - if (baud > 1228800) { - /* type_0, type_1 only support up to 1228800 baud */ - if (priv->type != HX) - baud = 1228800; - else if (baud > 6000000) - baud = 6000000; - } - dbg("%s - baud set = %d", __func__, baud); - if (baud <= 115200) { - buf[0] = baud & 0xff; - buf[1] = (baud >> 8) & 0xff; - buf[2] = (baud >> 16) & 0xff; - buf[3] = (baud >> 24) & 0xff; - } else { - /* apparently the formula for higher speeds is: - * baudrate = 12M * 32 / (2^buf[1]) / buf[0] - */ - unsigned tmp = 12*1000*1000*32 / baud; - buf[3] = 0x80; - buf[2] = 0; - buf[1] = (tmp >= 256); - while (tmp >= 256) { - tmp >>= 2; - buf[1] <<= 1; - } - buf[0] = tmp; - } - } - - /* For reference buf[4]=0 is 1 stop bits */ - /* For reference buf[4]=1 is 1.5 stop bits */ - /* For reference buf[4]=2 is 2 stop bits */ - if (cflag & CSTOPB) { - /* NOTE: Comply with "real" UARTs / RS232: - * use 1.5 instead of 2 stop bits with 5 data bits - */ - if ((cflag & CSIZE) == CS5) { - buf[4] = 1; - dbg("%s - stop bits = 1.5", __func__); - } else { - buf[4] = 2; - dbg("%s - stop bits = 2", __func__); - } - } else { - buf[4] = 0; - dbg("%s - stop bits = 1", __func__); - } - - if (cflag & PARENB) { - /* For reference buf[5]=0 is none parity */ - /* For reference buf[5]=1 is odd parity */ - /* For reference buf[5]=2 is even parity */ - /* For reference buf[5]=3 is mark parity */ - /* For reference buf[5]=4 is space parity */ - if (cflag & PARODD) { - if (cflag & CMSPAR) { - buf[5] = 3; - dbg("%s - parity = mark", __func__); - } else { - buf[5] = 1; - dbg("%s - parity = odd", __func__); - } - } else { - if (cflag & CMSPAR) { - buf[5] = 4; - dbg("%s - parity = space", __func__); - } else { - buf[5] = 2; - dbg("%s - parity = even", __func__); - } - } - } else { - buf[5] = 0; - dbg("%s - parity = none", __func__); - } - - i = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0), - SET_LINE_REQUEST, SET_LINE_REQUEST_TYPE, - 0, 0, buf, 7, 100); - dbg("0x21:0x20:0:0 %d", i); - - /* change control lines if we are switching to or from B0 */ - spin_lock_irqsave(&priv->lock, flags); - control = priv->line_control; - if ((cflag & CBAUD) == B0) - priv->line_control &= ~(CONTROL_DTR | CONTROL_RTS); - else if ((old_termios->c_cflag & CBAUD) == B0) - priv->line_control |= (CONTROL_DTR | CONTROL_RTS); - if (control != priv->line_control) { - control = priv->line_control; - spin_unlock_irqrestore(&priv->lock, flags); - set_control_lines(serial->dev, control); - } else { - spin_unlock_irqrestore(&priv->lock, flags); - } - - buf[0] = buf[1] = buf[2] = buf[3] = buf[4] = buf[5] = buf[6] = 0; - - i = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0), - GET_LINE_REQUEST, GET_LINE_REQUEST_TYPE, - 0, 0, buf, 7, 100); - dbg("0xa1:0x21:0:0 %d - %x %x %x %x %x %x %x", i, - buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], buf[6]); - - if (cflag & CRTSCTS) { - if (priv->type == HX) - pl2303_vendor_write(0x0, 0x61, serial); - else - pl2303_vendor_write(0x0, 0x41, serial); - } else { - pl2303_vendor_write(0x0, 0x0, serial); - } - - /* Save resulting baud rate */ - if (baud) - tty_encode_baud_rate(tty, baud, baud); - - kfree(buf); -} - -static void pl2303_dtr_rts(struct usb_serial_port *port, int on) -{ - struct pl2303_private *priv = usb_get_serial_port_data(port); - unsigned long flags; - u8 control; - - spin_lock_irqsave(&priv->lock, flags); - /* Change DTR and RTS */ - if (on) - priv->line_control |= (CONTROL_DTR | CONTROL_RTS); - else - priv->line_control &= ~(CONTROL_DTR | CONTROL_RTS); - control = priv->line_control; - spin_unlock_irqrestore(&priv->lock, flags); - set_control_lines(port->serial->dev, control); -} - -static void pl2303_close(struct usb_serial_port *port) -{ - dbg("%s - port %d", __func__, port->number); - - usb_serial_generic_close(port); - usb_kill_urb(port->interrupt_in_urb); -} - -static int pl2303_open(struct tty_struct *tty, struct usb_serial_port *port) -{ - struct ktermios tmp_termios; - struct usb_serial *serial = port->serial; - struct pl2303_private *priv = usb_get_serial_port_data(port); - int result; - - dbg("%s - port %d", __func__, port->number); - - if (priv->type != HX) { - usb_clear_halt(serial->dev, port->write_urb->pipe); - usb_clear_halt(serial->dev, port->read_urb->pipe); - } else { - /* reset upstream data pipes */ - pl2303_vendor_write(8, 0, serial); - pl2303_vendor_write(9, 0, serial); - } - - /* Setup termios */ - if (tty) - pl2303_set_termios(tty, port, &tmp_termios); - - dbg("%s - submitting interrupt urb", __func__); - result = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL); - if (result) { - dev_err(&port->dev, "%s - failed submitting interrupt urb," - " error %d\n", __func__, result); - return result; - } - - result = usb_serial_generic_open(tty, port); - if (result) { - usb_kill_urb(port->interrupt_in_urb); - return result; - } - - port->port.drain_delay = 256; - return 0; -} - -static int pl2303_tiocmset(struct tty_struct *tty, - unsigned int set, unsigned int clear) -{ - struct usb_serial_port *port = tty->driver_data; - struct pl2303_private *priv = usb_get_serial_port_data(port); - unsigned long flags; - u8 control; - - if (!usb_get_intfdata(port->serial->interface)) - return -ENODEV; - - spin_lock_irqsave(&priv->lock, flags); - if (set & TIOCM_RTS) - priv->line_control |= CONTROL_RTS; - if (set & TIOCM_DTR) - priv->line_control |= CONTROL_DTR; - if (clear & TIOCM_RTS) - priv->line_control &= ~CONTROL_RTS; - if (clear & TIOCM_DTR) - priv->line_control &= ~CONTROL_DTR; - control = priv->line_control; - spin_unlock_irqrestore(&priv->lock, flags); - - return set_control_lines(port->serial->dev, control); -} - -static int pl2303_tiocmget(struct tty_struct *tty) -{ - struct usb_serial_port *port = tty->driver_data; - struct pl2303_private *priv = usb_get_serial_port_data(port); - unsigned long flags; - unsigned int mcr; - unsigned int status; - unsigned int result; - - dbg("%s (%d)", __func__, port->number); - - if (!usb_get_intfdata(port->serial->interface)) - return -ENODEV; - - spin_lock_irqsave(&priv->lock, flags); - mcr = priv->line_control; - status = priv->line_status; - spin_unlock_irqrestore(&priv->lock, flags); - - result = ((mcr & CONTROL_DTR) ? TIOCM_DTR : 0) - | ((mcr & CONTROL_RTS) ? TIOCM_RTS : 0) - | ((status & UART_CTS) ? TIOCM_CTS : 0) - | ((status & UART_DSR) ? TIOCM_DSR : 0) - | ((status & UART_RING) ? TIOCM_RI : 0) - | ((status & UART_DCD) ? TIOCM_CD : 0); - - dbg("%s - result = %x", __func__, result); - - return result; -} - -static int pl2303_carrier_raised(struct usb_serial_port *port) -{ - struct pl2303_private *priv = usb_get_serial_port_data(port); - if (priv->line_status & UART_DCD) - return 1; - return 0; -} - -static int wait_modem_info(struct usb_serial_port *port, unsigned int arg) -{ - struct pl2303_private *priv = usb_get_serial_port_data(port); - unsigned long flags; - unsigned int prevstatus; - unsigned int status; - unsigned int changed; - - spin_lock_irqsave(&priv->lock, flags); - prevstatus = priv->line_status; - spin_unlock_irqrestore(&priv->lock, flags); - - while (1) { - interruptible_sleep_on(&priv->delta_msr_wait); - /* see if a signal did it */ - if (signal_pending(current)) - return -ERESTARTSYS; - - spin_lock_irqsave(&priv->lock, flags); - status = priv->line_status; - spin_unlock_irqrestore(&priv->lock, flags); - - changed = prevstatus ^ status; - - if (((arg & TIOCM_RNG) && (changed & UART_RING)) || - ((arg & TIOCM_DSR) && (changed & UART_DSR)) || - ((arg & TIOCM_CD) && (changed & UART_DCD)) || - ((arg & TIOCM_CTS) && (changed & UART_CTS))) { - return 0; - } - prevstatus = status; - } - /* NOTREACHED */ - return 0; -} - -static int pl2303_ioctl(struct tty_struct *tty, - unsigned int cmd, unsigned long arg) -{ - struct serial_struct ser; - struct usb_serial_port *port = tty->driver_data; - dbg("%s (%d) cmd = 0x%04x", __func__, port->number, cmd); - - switch (cmd) { - case TIOCGSERIAL: - memset(&ser, 0, sizeof ser); - ser.type = PORT_16654; - ser.line = port->serial->minor; - ser.port = port->number; - ser.baud_base = 460800; - - if (copy_to_user((void __user *)arg, &ser, sizeof ser)) - return -EFAULT; - - return 0; - - case TIOCMIWAIT: - dbg("%s (%d) TIOCMIWAIT", __func__, port->number); - return wait_modem_info(port, arg); - default: - dbg("%s not supported = 0x%04x", __func__, cmd); - break; - } - return -ENOIOCTLCMD; -} - -static void pl2303_break_ctl(struct tty_struct *tty, int break_state) -{ - struct usb_serial_port *port = tty->driver_data; - struct usb_serial *serial = port->serial; - u16 state; - int result; - - dbg("%s - port %d", __func__, port->number); - - if (break_state == 0) - state = BREAK_OFF; - else - state = BREAK_ON; - dbg("%s - turning break %s", __func__, - state == BREAK_OFF ? "off" : "on"); - - result = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0), - BREAK_REQUEST, BREAK_REQUEST_TYPE, state, - 0, NULL, 0, 100); - if (result) - dbg("%s - error sending break = %d", __func__, result); -} - -static void pl2303_release(struct usb_serial *serial) -{ - int i; - struct pl2303_private *priv; - - dbg("%s", __func__); - - for (i = 0; i < serial->num_ports; ++i) { - priv = usb_get_serial_port_data(serial->port[i]); - kfree(priv); - } -} - -static void pl2303_update_line_status(struct usb_serial_port *port, - unsigned char *data, - unsigned int actual_length) -{ - - struct pl2303_private *priv = usb_get_serial_port_data(port); - struct tty_struct *tty; - unsigned long flags; - u8 status_idx = UART_STATE; - u8 length = UART_STATE + 1; - u8 prev_line_status; - u16 idv, idp; - - idv = le16_to_cpu(port->serial->dev->descriptor.idVendor); - idp = le16_to_cpu(port->serial->dev->descriptor.idProduct); - - - if (idv == SIEMENS_VENDOR_ID) { - if (idp == SIEMENS_PRODUCT_ID_X65 || - idp == SIEMENS_PRODUCT_ID_SX1 || - idp == SIEMENS_PRODUCT_ID_X75) { - - length = 1; - status_idx = 0; - } - } - - if (actual_length < length) - return; - - /* Save off the uart status for others to look at */ - spin_lock_irqsave(&priv->lock, flags); - prev_line_status = priv->line_status; - priv->line_status = data[status_idx]; - spin_unlock_irqrestore(&priv->lock, flags); - if (priv->line_status & UART_BREAK_ERROR) - usb_serial_handle_break(port); - wake_up_interruptible(&priv->delta_msr_wait); - - tty = tty_port_tty_get(&port->port); - if (!tty) - return; - if ((priv->line_status ^ prev_line_status) & UART_DCD) - usb_serial_handle_dcd_change(port, tty, - priv->line_status & UART_DCD); - tty_kref_put(tty); -} - -static void pl2303_read_int_callback(struct urb *urb) -{ - struct usb_serial_port *port = urb->context; - unsigned char *data = urb->transfer_buffer; - unsigned int actual_length = urb->actual_length; - int status = urb->status; - int retval; - - dbg("%s (%d)", __func__, port->number); - - switch (status) { - case 0: - /* success */ - break; - case -ECONNRESET: - case -ENOENT: - case -ESHUTDOWN: - /* this urb is terminated, clean up */ - dbg("%s - urb shutting down with status: %d", __func__, - status); - return; - default: - dbg("%s - nonzero urb status received: %d", __func__, - status); - goto exit; - } - - usb_serial_debug_data(debug, &port->dev, __func__, - urb->actual_length, urb->transfer_buffer); - - pl2303_update_line_status(port, data, actual_length); - -exit: - retval = usb_submit_urb(urb, GFP_ATOMIC); - if (retval) - dev_err(&urb->dev->dev, - "%s - usb_submit_urb failed with result %d\n", - __func__, retval); -} - -static void pl2303_process_read_urb(struct urb *urb) -{ - struct usb_serial_port *port = urb->context; - struct pl2303_private *priv = usb_get_serial_port_data(port); - struct tty_struct *tty; - unsigned char *data = urb->transfer_buffer; - char tty_flag = TTY_NORMAL; - unsigned long flags; - u8 line_status; - int i; - - /* update line status */ - spin_lock_irqsave(&priv->lock, flags); - line_status = priv->line_status; - priv->line_status &= ~UART_STATE_TRANSIENT_MASK; - spin_unlock_irqrestore(&priv->lock, flags); - wake_up_interruptible(&priv->delta_msr_wait); - - if (!urb->actual_length) - return; - - tty = tty_port_tty_get(&port->port); - if (!tty) - return; - - /* break takes precedence over parity, */ - /* which takes precedence over framing errors */ - if (line_status & UART_BREAK_ERROR) - tty_flag = TTY_BREAK; - else if (line_status & UART_PARITY_ERROR) - tty_flag = TTY_PARITY; - else if (line_status & UART_FRAME_ERROR) - tty_flag = TTY_FRAME; - dbg("%s - tty_flag = %d", __func__, tty_flag); - - /* overrun is special, not associated with a char */ - if (line_status & UART_OVERRUN_ERROR) - tty_insert_flip_char(tty, 0, TTY_OVERRUN); - - if (port->port.console && port->sysrq) { - for (i = 0; i < urb->actual_length; ++i) - if (!usb_serial_handle_sysrq_char(port, data[i])) - tty_insert_flip_char(tty, data[i], tty_flag); - } else { - tty_insert_flip_string_fixed_flag(tty, data, tty_flag, - urb->actual_length); - } - - tty_flip_buffer_push(tty); - tty_kref_put(tty); -} - -/* All of the device info needed for the PL2303 SIO serial converter */ -static struct usb_serial_driver pl2303_device = { - .driver = { - .owner = THIS_MODULE, - .name = "pl2303", - }, - .id_table = id_table, - .num_ports = 1, - .bulk_in_size = 256, - .bulk_out_size = 256, - .open = pl2303_open, - .close = pl2303_close, - .dtr_rts = pl2303_dtr_rts, - .carrier_raised = pl2303_carrier_raised, - .ioctl = pl2303_ioctl, - .break_ctl = pl2303_break_ctl, - .set_termios = pl2303_set_termios, - .tiocmget = pl2303_tiocmget, - .tiocmset = pl2303_tiocmset, - .process_read_urb = pl2303_process_read_urb, - .read_int_callback = pl2303_read_int_callback, - .attach = pl2303_startup, - .release = pl2303_release, -}; - -static struct usb_serial_driver * const serial_drivers[] = { - &pl2303_device, NULL -}; - -module_usb_serial_driver(pl2303_driver, serial_drivers); - -MODULE_DESCRIPTION(DRIVER_DESC); -MODULE_LICENSE("GPL"); - -module_param(debug, bool, S_IRUGO | S_IWUSR); -MODULE_PARM_DESC(debug, "Debug enabled or not"); - diff --git a/ANDROID_3.4.5/drivers/usb/serial/pl2303.h b/ANDROID_3.4.5/drivers/usb/serial/pl2303.h deleted file mode 100644 index c38b8c00..00000000 --- a/ANDROID_3.4.5/drivers/usb/serial/pl2303.h +++ /dev/null @@ -1,151 +0,0 @@ -/* - * 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 - diff --git a/ANDROID_3.4.5/drivers/usb/serial/qcaux.c b/ANDROID_3.4.5/drivers/usb/serial/qcaux.c deleted file mode 100644 index 96624568..00000000 --- a/ANDROID_3.4.5/drivers/usb/serial/qcaux.c +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Qualcomm USB Auxiliary Serial Port driver - * - * Copyright (C) 2008 Greg Kroah-Hartman <greg@kroah.com> - * Copyright (C) 2010 Dan Williams <dcbw@redhat.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * Devices listed here usually provide a CDC ACM port on which normal modem - * AT commands and PPP can be used. But when that port is in-use by PPP it - * cannot be used simultaneously for status or signal strength. Instead, the - * ports here can be queried for that information using the Qualcomm DM - * protocol. - */ - -#include <linux/kernel.h> -#include <linux/init.h> -#include <linux/tty.h> -#include <linux/module.h> -#include <linux/usb.h> -#include <linux/usb/serial.h> - -/* NOTE: for now, only use this driver for devices that provide a CDC-ACM port - * for normal AT commands, but also provide secondary USB interfaces for the - * QCDM-capable ports. Devices that do not provide a CDC-ACM port should - * probably be driven by option.ko. - */ - -/* UTStarcom/Pantech/Curitel devices */ -#define UTSTARCOM_VENDOR_ID 0x106c -#define UTSTARCOM_PRODUCT_PC5740 0x3701 -#define UTSTARCOM_PRODUCT_PC5750 0x3702 /* aka Pantech PX-500 */ -#define UTSTARCOM_PRODUCT_UM150 0x3711 -#define UTSTARCOM_PRODUCT_UM175_V1 0x3712 -#define UTSTARCOM_PRODUCT_UM175_V2 0x3714 -#define UTSTARCOM_PRODUCT_UM175_ALLTEL 0x3715 -#define PANTECH_PRODUCT_UML190_VZW 0x3716 -#define PANTECH_PRODUCT_UML290_VZW 0x3718 - -/* CMOTECH devices */ -#define CMOTECH_VENDOR_ID 0x16d8 -#define CMOTECH_PRODUCT_CDU550 0x5553 -#define CMOTECH_PRODUCT_CDX650 0x6512 - -/* LG devices */ -#define LG_VENDOR_ID 0x1004 -#define LG_PRODUCT_VX4400_6000 0x6000 /* VX4400/VX6000/Rumor */ - -/* Sanyo devices */ -#define SANYO_VENDOR_ID 0x0474 -#define SANYO_PRODUCT_KATANA_LX 0x0754 /* SCP-3800 (Katana LX) */ - -/* Samsung devices */ -#define SAMSUNG_VENDOR_ID 0x04e8 -#define SAMSUNG_PRODUCT_U520 0x6640 /* SCH-U520 */ - -static struct usb_device_id id_table[] = { - { USB_DEVICE_AND_INTERFACE_INFO(UTSTARCOM_VENDOR_ID, UTSTARCOM_PRODUCT_PC5740, 0xff, 0x00, 0x00) }, - { USB_DEVICE_AND_INTERFACE_INFO(UTSTARCOM_VENDOR_ID, UTSTARCOM_PRODUCT_PC5750, 0xff, 0x00, 0x00) }, - { USB_DEVICE_AND_INTERFACE_INFO(UTSTARCOM_VENDOR_ID, UTSTARCOM_PRODUCT_UM150, 0xff, 0x00, 0x00) }, - { USB_DEVICE_AND_INTERFACE_INFO(UTSTARCOM_VENDOR_ID, UTSTARCOM_PRODUCT_UM175_V1, 0xff, 0x00, 0x00) }, - { USB_DEVICE_AND_INTERFACE_INFO(UTSTARCOM_VENDOR_ID, UTSTARCOM_PRODUCT_UM175_V2, 0xff, 0x00, 0x00) }, - { USB_DEVICE_AND_INTERFACE_INFO(UTSTARCOM_VENDOR_ID, UTSTARCOM_PRODUCT_UM175_ALLTEL, 0xff, 0x00, 0x00) }, - { USB_DEVICE_AND_INTERFACE_INFO(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_CDU550, 0xff, 0xff, 0x00) }, - { USB_DEVICE_AND_INTERFACE_INFO(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_CDX650, 0xff, 0xff, 0x00) }, - { USB_DEVICE_AND_INTERFACE_INFO(LG_VENDOR_ID, LG_PRODUCT_VX4400_6000, 0xff, 0xff, 0x00) }, - { USB_DEVICE_AND_INTERFACE_INFO(SANYO_VENDOR_ID, SANYO_PRODUCT_KATANA_LX, 0xff, 0xff, 0x00) }, - { USB_DEVICE_AND_INTERFACE_INFO(SAMSUNG_VENDOR_ID, SAMSUNG_PRODUCT_U520, 0xff, 0x00, 0x00) }, - { USB_DEVICE_AND_INTERFACE_INFO(UTSTARCOM_VENDOR_ID, PANTECH_PRODUCT_UML190_VZW, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(UTSTARCOM_VENDOR_ID, PANTECH_PRODUCT_UML190_VZW, 0xff, 0xfe, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(UTSTARCOM_VENDOR_ID, PANTECH_PRODUCT_UML290_VZW, 0xff, 0xfd, 0xff) }, /* NMEA */ - { USB_DEVICE_AND_INTERFACE_INFO(UTSTARCOM_VENDOR_ID, PANTECH_PRODUCT_UML290_VZW, 0xff, 0xfe, 0xff) }, /* WMC */ - { USB_DEVICE_AND_INTERFACE_INFO(UTSTARCOM_VENDOR_ID, PANTECH_PRODUCT_UML290_VZW, 0xff, 0xff, 0xff) }, /* DIAG */ - { }, -}; -MODULE_DEVICE_TABLE(usb, id_table); - -static struct usb_driver qcaux_driver = { - .name = "qcaux", - .probe = usb_serial_probe, - .disconnect = usb_serial_disconnect, - .id_table = id_table, -}; - -static struct usb_serial_driver qcaux_device = { - .driver = { - .owner = THIS_MODULE, - .name = "qcaux", - }, - .id_table = id_table, - .num_ports = 1, -}; - -static struct usb_serial_driver * const serial_drivers[] = { - &qcaux_device, NULL -}; - -module_usb_serial_driver(qcaux_driver, serial_drivers); -MODULE_LICENSE("GPL"); diff --git a/ANDROID_3.4.5/drivers/usb/serial/qcserial.c b/ANDROID_3.4.5/drivers/usb/serial/qcserial.c deleted file mode 100644 index 50b53717..00000000 --- a/ANDROID_3.4.5/drivers/usb/serial/qcserial.c +++ /dev/null @@ -1,301 +0,0 @@ -/* - * Qualcomm Serial USB driver - * - * Copyright (c) 2008 QUALCOMM Incorporated. - * Copyright (c) 2009 Greg Kroah-Hartman <gregkh@suse.de> - * Copyright (c) 2009 Novell Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License version - * 2 as published by the Free Software Foundation. - * - */ - -#include <linux/tty.h> -#include <linux/tty_flip.h> -#include <linux/module.h> -#include <linux/usb.h> -#include <linux/usb/serial.h> -#include <linux/slab.h> -#include "usb-wwan.h" - -#define DRIVER_AUTHOR "Qualcomm Inc" -#define DRIVER_DESC "Qualcomm USB Serial driver" - -static bool debug; - -#define DEVICE_G1K(v, p) \ - USB_DEVICE(v, p), .driver_info = 1 - -static const struct usb_device_id id_table[] = { - /* Gobi 1000 devices */ - {DEVICE_G1K(0x05c6, 0x9211)}, /* Acer Gobi QDL device */ - {DEVICE_G1K(0x05c6, 0x9212)}, /* Acer Gobi Modem Device */ - {DEVICE_G1K(0x03f0, 0x1f1d)}, /* HP un2400 Gobi Modem Device */ - {DEVICE_G1K(0x03f0, 0x201d)}, /* HP un2400 Gobi QDL Device */ - {DEVICE_G1K(0x04da, 0x250d)}, /* Panasonic Gobi Modem device */ - {DEVICE_G1K(0x04da, 0x250c)}, /* Panasonic Gobi QDL device */ - {DEVICE_G1K(0x413c, 0x8172)}, /* Dell Gobi Modem device */ - {DEVICE_G1K(0x413c, 0x8171)}, /* Dell Gobi QDL device */ - {DEVICE_G1K(0x1410, 0xa001)}, /* Novatel Gobi Modem device */ - {DEVICE_G1K(0x1410, 0xa008)}, /* Novatel Gobi QDL device */ - {DEVICE_G1K(0x0b05, 0x1776)}, /* Asus Gobi Modem device */ - {DEVICE_G1K(0x0b05, 0x1774)}, /* Asus Gobi QDL device */ - {DEVICE_G1K(0x19d2, 0xfff3)}, /* ONDA Gobi Modem device */ - {DEVICE_G1K(0x19d2, 0xfff2)}, /* ONDA Gobi QDL device */ - {DEVICE_G1K(0x1557, 0x0a80)}, /* OQO Gobi QDL device */ - {DEVICE_G1K(0x05c6, 0x9001)}, /* Generic Gobi Modem device */ - {DEVICE_G1K(0x05c6, 0x9002)}, /* Generic Gobi Modem device */ - {DEVICE_G1K(0x05c6, 0x9202)}, /* Generic Gobi Modem device */ - {DEVICE_G1K(0x05c6, 0x9203)}, /* Generic Gobi Modem device */ - {DEVICE_G1K(0x05c6, 0x9222)}, /* Generic Gobi Modem device */ - {DEVICE_G1K(0x05c6, 0x9008)}, /* Generic Gobi QDL device */ - {DEVICE_G1K(0x05c6, 0x9009)}, /* Generic Gobi Modem device */ - {DEVICE_G1K(0x05c6, 0x9201)}, /* Generic Gobi QDL device */ - {DEVICE_G1K(0x05c6, 0x9221)}, /* Generic Gobi QDL device */ - {DEVICE_G1K(0x05c6, 0x9231)}, /* Generic Gobi QDL device */ - {DEVICE_G1K(0x1f45, 0x0001)}, /* Unknown Gobi QDL device */ - - /* Gobi 2000 devices */ - {USB_DEVICE(0x1410, 0xa010)}, /* Novatel Gobi 2000 QDL device */ - {USB_DEVICE(0x1410, 0xa011)}, /* Novatel Gobi 2000 QDL device */ - {USB_DEVICE(0x1410, 0xa012)}, /* Novatel Gobi 2000 QDL device */ - {USB_DEVICE(0x1410, 0xa013)}, /* Novatel Gobi 2000 QDL device */ - {USB_DEVICE(0x1410, 0xa014)}, /* Novatel Gobi 2000 QDL device */ - {USB_DEVICE(0x413c, 0x8185)}, /* Dell Gobi 2000 QDL device (N0218, VU936) */ - {USB_DEVICE(0x413c, 0x8186)}, /* Dell Gobi 2000 Modem device (N0218, VU936) */ - {USB_DEVICE(0x05c6, 0x9208)}, /* Generic Gobi 2000 QDL device */ - {USB_DEVICE(0x05c6, 0x920b)}, /* Generic Gobi 2000 Modem device */ - {USB_DEVICE(0x05c6, 0x9224)}, /* Sony Gobi 2000 QDL device (N0279, VU730) */ - {USB_DEVICE(0x05c6, 0x9225)}, /* Sony Gobi 2000 Modem device (N0279, VU730) */ - {USB_DEVICE(0x05c6, 0x9244)}, /* Samsung Gobi 2000 QDL device (VL176) */ - {USB_DEVICE(0x05c6, 0x9245)}, /* Samsung Gobi 2000 Modem device (VL176) */ - {USB_DEVICE(0x03f0, 0x241d)}, /* HP Gobi 2000 QDL device (VP412) */ - {USB_DEVICE(0x03f0, 0x251d)}, /* HP Gobi 2000 Modem device (VP412) */ - {USB_DEVICE(0x05c6, 0x9214)}, /* Acer Gobi 2000 QDL device (VP413) */ - {USB_DEVICE(0x05c6, 0x9215)}, /* Acer Gobi 2000 Modem device (VP413) */ - {USB_DEVICE(0x05c6, 0x9264)}, /* Asus Gobi 2000 QDL device (VR305) */ - {USB_DEVICE(0x05c6, 0x9265)}, /* Asus Gobi 2000 Modem device (VR305) */ - {USB_DEVICE(0x05c6, 0x9234)}, /* Top Global Gobi 2000 QDL device (VR306) */ - {USB_DEVICE(0x05c6, 0x9235)}, /* Top Global Gobi 2000 Modem device (VR306) */ - {USB_DEVICE(0x05c6, 0x9274)}, /* iRex Technologies Gobi 2000 QDL device (VR307) */ - {USB_DEVICE(0x05c6, 0x9275)}, /* iRex Technologies Gobi 2000 Modem device (VR307) */ - {USB_DEVICE(0x1199, 0x9000)}, /* Sierra Wireless Gobi 2000 QDL device (VT773) */ - {USB_DEVICE(0x1199, 0x9001)}, /* Sierra Wireless Gobi 2000 Modem device (VT773) */ - {USB_DEVICE(0x1199, 0x9002)}, /* Sierra Wireless Gobi 2000 Modem device (VT773) */ - {USB_DEVICE(0x1199, 0x9003)}, /* Sierra Wireless Gobi 2000 Modem device (VT773) */ - {USB_DEVICE(0x1199, 0x9004)}, /* Sierra Wireless Gobi 2000 Modem device (VT773) */ - {USB_DEVICE(0x1199, 0x9005)}, /* Sierra Wireless Gobi 2000 Modem device (VT773) */ - {USB_DEVICE(0x1199, 0x9006)}, /* Sierra Wireless Gobi 2000 Modem device (VT773) */ - {USB_DEVICE(0x1199, 0x9007)}, /* Sierra Wireless Gobi 2000 Modem device (VT773) */ - {USB_DEVICE(0x1199, 0x9008)}, /* Sierra Wireless Gobi 2000 Modem device (VT773) */ - {USB_DEVICE(0x1199, 0x9009)}, /* Sierra Wireless Gobi 2000 Modem device (VT773) */ - {USB_DEVICE(0x1199, 0x900a)}, /* Sierra Wireless Gobi 2000 Modem device (VT773) */ - {USB_DEVICE(0x1199, 0x9011)}, /* Sierra Wireless Gobi 2000 Modem device (MC8305) */ - {USB_DEVICE(0x16d8, 0x8001)}, /* CMDTech Gobi 2000 QDL device (VU922) */ - {USB_DEVICE(0x16d8, 0x8002)}, /* CMDTech Gobi 2000 Modem device (VU922) */ - {USB_DEVICE(0x05c6, 0x9204)}, /* Gobi 2000 QDL device */ - {USB_DEVICE(0x05c6, 0x9205)}, /* Gobi 2000 Modem device */ - - /* Gobi 3000 devices */ - {USB_DEVICE(0x03f0, 0x371d)}, /* HP un2430 Gobi 3000 QDL */ - {USB_DEVICE(0x05c6, 0x920c)}, /* Gobi 3000 QDL */ - {USB_DEVICE(0x05c6, 0x920d)}, /* Gobi 3000 Composite */ - {USB_DEVICE(0x1410, 0xa020)}, /* Novatel Gobi 3000 QDL */ - {USB_DEVICE(0x1410, 0xa021)}, /* Novatel Gobi 3000 Composite */ - {USB_DEVICE(0x413c, 0x8193)}, /* Dell Gobi 3000 QDL */ - {USB_DEVICE(0x413c, 0x8194)}, /* Dell Gobi 3000 Composite */ - {USB_DEVICE(0x1199, 0x9010)}, /* Sierra Wireless Gobi 3000 QDL */ - {USB_DEVICE(0x1199, 0x9012)}, /* Sierra Wireless Gobi 3000 QDL */ - {USB_DEVICE(0x1199, 0x9013)}, /* Sierra Wireless Gobi 3000 Modem device (MC8355) */ - {USB_DEVICE(0x1199, 0x9014)}, /* Sierra Wireless Gobi 3000 QDL */ - {USB_DEVICE(0x1199, 0x9015)}, /* Sierra Wireless Gobi 3000 Modem device */ - {USB_DEVICE(0x1199, 0x9018)}, /* Sierra Wireless Gobi 3000 QDL */ - {USB_DEVICE(0x1199, 0x9019)}, /* Sierra Wireless Gobi 3000 Modem device */ - {USB_DEVICE(0x12D1, 0x14F0)}, /* Sony Gobi 3000 QDL */ - {USB_DEVICE(0x12D1, 0x14F1)}, /* Sony Gobi 3000 Composite */ - { } /* Terminating entry */ -}; -MODULE_DEVICE_TABLE(usb, id_table); - -static struct usb_driver qcdriver = { - .name = "qcserial", - .probe = usb_serial_probe, - .disconnect = usb_serial_disconnect, - .id_table = id_table, - .suspend = usb_serial_suspend, - .resume = usb_serial_resume, - .supports_autosuspend = true, -}; - -static int qcprobe(struct usb_serial *serial, const struct usb_device_id *id) -{ - struct usb_wwan_intf_private *data; - struct usb_host_interface *intf = serial->interface->cur_altsetting; - int retval = -ENODEV; - __u8 nintf; - __u8 ifnum; - bool is_gobi1k = id->driver_info ? true : false; - - dbg("%s", __func__); - dbg("Is Gobi 1000 = %d", is_gobi1k); - - nintf = serial->dev->actconfig->desc.bNumInterfaces; - dbg("Num Interfaces = %d", nintf); - ifnum = intf->desc.bInterfaceNumber; - dbg("This Interface = %d", ifnum); - - data = kzalloc(sizeof(struct usb_wwan_intf_private), - GFP_KERNEL); - if (!data) - return -ENOMEM; - - spin_lock_init(&data->susp_lock); - - switch (nintf) { - case 1: - /* QDL mode */ - /* Gobi 2000 has a single altsetting, older ones have two */ - if (serial->interface->num_altsetting == 2) - intf = &serial->interface->altsetting[1]; - else if (serial->interface->num_altsetting > 2) - break; - - if (intf->desc.bNumEndpoints == 2 && - usb_endpoint_is_bulk_in(&intf->endpoint[0].desc) && - usb_endpoint_is_bulk_out(&intf->endpoint[1].desc)) { - dbg("QDL port found"); - - if (serial->interface->num_altsetting == 1) { - retval = 0; /* Success */ - break; - } - - retval = usb_set_interface(serial->dev, ifnum, 1); - if (retval < 0) { - dev_err(&serial->dev->dev, - "Could not set interface, error %d\n", - retval); - retval = -ENODEV; - kfree(data); - } - } - break; - - case 3: - case 4: - /* Composite mode; don't bind to the QMI/net interface as that - * gets handled by other drivers. - */ - - /* Gobi 1K USB layout: - * 0: serial port (doesn't respond) - * 1: serial port (doesn't respond) - * 2: AT-capable modem port - * 3: QMI/net - * - * Gobi 2K+ USB layout: - * 0: QMI/net - * 1: DM/DIAG (use libqcdm from ModemManager for communication) - * 2: AT-capable modem port - * 3: NMEA - */ - - if (ifnum == 1 && !is_gobi1k) { - dbg("Gobi 2K+ DM/DIAG interface found"); - retval = usb_set_interface(serial->dev, ifnum, 0); - if (retval < 0) { - dev_err(&serial->dev->dev, - "Could not set interface, error %d\n", - retval); - retval = -ENODEV; - kfree(data); - } - } else if (ifnum == 2) { - dbg("Modem port found"); - retval = usb_set_interface(serial->dev, ifnum, 0); - if (retval < 0) { - dev_err(&serial->dev->dev, - "Could not set interface, error %d\n", - retval); - retval = -ENODEV; - kfree(data); - } - } else if (ifnum==3 && !is_gobi1k) { - /* - * NMEA (serial line 9600 8N1) - * # echo "\$GPS_START" > /dev/ttyUSBx - * # echo "\$GPS_STOP" > /dev/ttyUSBx - */ - dbg("Gobi 2K+ NMEA GPS interface found"); - retval = usb_set_interface(serial->dev, ifnum, 0); - if (retval < 0) { - dev_err(&serial->dev->dev, - "Could not set interface, error %d\n", - retval); - retval = -ENODEV; - kfree(data); - } - } - break; - - default: - dev_err(&serial->dev->dev, - "unknown number of interfaces: %d\n", nintf); - kfree(data); - retval = -ENODEV; - } - - /* Set serial->private if not returning -ENODEV */ - if (retval != -ENODEV) - usb_set_serial_data(serial, data); - return retval; -} - -static void qc_release(struct usb_serial *serial) -{ - struct usb_wwan_intf_private *priv = usb_get_serial_data(serial); - - dbg("%s", __func__); - - /* Call usb_wwan release & free the private data allocated in qcprobe */ - usb_wwan_release(serial); - usb_set_serial_data(serial, NULL); - kfree(priv); -} - -static struct usb_serial_driver qcdevice = { - .driver = { - .owner = THIS_MODULE, - .name = "qcserial", - }, - .description = "Qualcomm USB modem", - .id_table = id_table, - .num_ports = 1, - .probe = qcprobe, - .open = usb_wwan_open, - .close = usb_wwan_close, - .write = usb_wwan_write, - .write_room = usb_wwan_write_room, - .chars_in_buffer = usb_wwan_chars_in_buffer, - .attach = usb_wwan_startup, - .disconnect = usb_wwan_disconnect, - .release = qc_release, -#ifdef CONFIG_PM - .suspend = usb_wwan_suspend, - .resume = usb_wwan_resume, -#endif -}; - -static struct usb_serial_driver * const serial_drivers[] = { - &qcdevice, NULL -}; - -module_usb_serial_driver(qcdriver, serial_drivers); - -MODULE_AUTHOR(DRIVER_AUTHOR); -MODULE_DESCRIPTION(DRIVER_DESC); -MODULE_LICENSE("GPL v2"); - -module_param(debug, bool, S_IRUGO | S_IWUSR); -MODULE_PARM_DESC(debug, "Debug enabled or not"); diff --git a/ANDROID_3.4.5/drivers/usb/serial/safe_serial.c b/ANDROID_3.4.5/drivers/usb/serial/safe_serial.c deleted file mode 100644 index ae4ee30c..00000000 --- a/ANDROID_3.4.5/drivers/usb/serial/safe_serial.c +++ /dev/null @@ -1,351 +0,0 @@ -/* - * Safe Encapsulated USB Serial Driver - * - * Copyright (C) 2010 Johan Hovold <jhovold@gmail.com> - * Copyright (C) 2001 Lineo - * Copyright (C) 2001 Hewlett-Packard - * - * 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. - * - * By: - * Stuart Lynne <sl@lineo.com>, Tom Rushworth <tbr@lineo.com> - */ - -/* - * The encapsultaion is designed to overcome difficulties with some USB - * hardware. - * - * While the USB protocol has a CRC over the data while in transit, i.e. while - * being carried over the bus, there is no end to end protection. If the - * hardware has any problems getting the data into or out of the USB transmit - * and receive FIFO's then data can be lost. - * - * This protocol adds a two byte trailer to each USB packet to specify the - * number of bytes of valid data and a 10 bit CRC that will allow the receiver - * to verify that the entire USB packet was received without error. - * - * Because in this case the sender and receiver are the class and function - * drivers there is now end to end protection. - * - * There is an additional option that can be used to force all transmitted - * packets to be padded to the maximum packet size. This provides a work - * around for some devices which have problems with small USB packets. - * - * Assuming a packetsize of N: - * - * 0..N-2 data and optional padding - * - * N-2 bits 7-2 - number of bytes of valid data - * bits 1-0 top two bits of 10 bit CRC - * N-1 bottom 8 bits of 10 bit CRC - * - * - * | Data Length | 10 bit CRC | - * + 7 . 6 . 5 . 4 . 3 . 2 . 1 . 0 | 7 . 6 . 5 . 4 . 3 . 2 . 1 . 0 + - * - * The 10 bit CRC is computed across the sent data, followed by the trailer - * with the length set and the CRC set to zero. The CRC is then OR'd into - * the trailer. - * - * When received a 10 bit CRC is computed over the entire frame including - * the trailer and should be equal to zero. - * - * Two module parameters are used to control the encapsulation, if both are - * turned of the module works as a simple serial device with NO - * encapsulation. - * - * See linux/drivers/usbd/serial_fd for a device function driver - * implementation of this. - * - */ - - -#include <linux/kernel.h> -#include <linux/errno.h> -#include <linux/gfp.h> -#include <linux/init.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/uaccess.h> -#include <linux/usb.h> -#include <linux/usb/serial.h> - - -#ifndef CONFIG_USB_SERIAL_SAFE_PADDED -#define CONFIG_USB_SERIAL_SAFE_PADDED 0 -#endif - -static bool debug; -static bool safe = 1; -static bool padded = CONFIG_USB_SERIAL_SAFE_PADDED; - -#define DRIVER_VERSION "v0.1" -#define DRIVER_AUTHOR "sl@lineo.com, tbr@lineo.com, Johan Hovold <jhovold@gmail.com>" -#define DRIVER_DESC "USB Safe Encapsulated Serial" - -MODULE_AUTHOR(DRIVER_AUTHOR); -MODULE_DESCRIPTION(DRIVER_DESC); -MODULE_LICENSE("GPL"); - -static __u16 vendor; /* no default */ -static __u16 product; /* no default */ -module_param(vendor, ushort, 0); -MODULE_PARM_DESC(vendor, "User specified USB idVendor (required)"); -module_param(product, ushort, 0); -MODULE_PARM_DESC(product, "User specified USB idProduct (required)"); - -module_param(debug, bool, S_IRUGO | S_IWUSR); -MODULE_PARM_DESC(debug, "Debug enabled or not"); - -module_param(safe, bool, 0); -MODULE_PARM_DESC(safe, "Turn Safe Encapsulation On/Off"); - -module_param(padded, bool, 0); -MODULE_PARM_DESC(padded, "Pad to full wMaxPacketSize On/Off"); - -#define CDC_DEVICE_CLASS 0x02 - -#define CDC_INTERFACE_CLASS 0x02 -#define CDC_INTERFACE_SUBCLASS 0x06 - -#define LINEO_INTERFACE_CLASS 0xff - -#define LINEO_INTERFACE_SUBCLASS_SAFENET 0x01 -#define LINEO_SAFENET_CRC 0x01 -#define LINEO_SAFENET_CRC_PADDED 0x02 - -#define LINEO_INTERFACE_SUBCLASS_SAFESERIAL 0x02 -#define LINEO_SAFESERIAL_CRC 0x01 -#define LINEO_SAFESERIAL_CRC_PADDED 0x02 - - -#define MY_USB_DEVICE(vend, prod, dc, ic, isc) \ - .match_flags = USB_DEVICE_ID_MATCH_DEVICE | \ - USB_DEVICE_ID_MATCH_DEV_CLASS | \ - USB_DEVICE_ID_MATCH_INT_CLASS | \ - USB_DEVICE_ID_MATCH_INT_SUBCLASS, \ - .idVendor = (vend), \ - .idProduct = (prod),\ - .bDeviceClass = (dc),\ - .bInterfaceClass = (ic), \ - .bInterfaceSubClass = (isc), - -static struct usb_device_id id_table[] = { - {MY_USB_DEVICE(0x49f, 0xffff, CDC_DEVICE_CLASS, LINEO_INTERFACE_CLASS, LINEO_INTERFACE_SUBCLASS_SAFESERIAL)}, /* Itsy */ - {MY_USB_DEVICE(0x3f0, 0x2101, CDC_DEVICE_CLASS, LINEO_INTERFACE_CLASS, LINEO_INTERFACE_SUBCLASS_SAFESERIAL)}, /* Calypso */ - {MY_USB_DEVICE(0x4dd, 0x8001, CDC_DEVICE_CLASS, LINEO_INTERFACE_CLASS, LINEO_INTERFACE_SUBCLASS_SAFESERIAL)}, /* Iris */ - {MY_USB_DEVICE(0x4dd, 0x8002, CDC_DEVICE_CLASS, LINEO_INTERFACE_CLASS, LINEO_INTERFACE_SUBCLASS_SAFESERIAL)}, /* Collie */ - {MY_USB_DEVICE(0x4dd, 0x8003, CDC_DEVICE_CLASS, LINEO_INTERFACE_CLASS, LINEO_INTERFACE_SUBCLASS_SAFESERIAL)}, /* Collie */ - {MY_USB_DEVICE(0x4dd, 0x8004, CDC_DEVICE_CLASS, LINEO_INTERFACE_CLASS, LINEO_INTERFACE_SUBCLASS_SAFESERIAL)}, /* Collie */ - {MY_USB_DEVICE(0x5f9, 0xffff, CDC_DEVICE_CLASS, LINEO_INTERFACE_CLASS, LINEO_INTERFACE_SUBCLASS_SAFESERIAL)}, /* Sharp tmp */ - /* extra null entry for module vendor/produc parameters */ - {MY_USB_DEVICE(0, 0, CDC_DEVICE_CLASS, LINEO_INTERFACE_CLASS, LINEO_INTERFACE_SUBCLASS_SAFESERIAL)}, - {} /* terminating entry */ -}; - -MODULE_DEVICE_TABLE(usb, id_table); - -static struct usb_driver safe_driver = { - .name = "safe_serial", - .probe = usb_serial_probe, - .disconnect = usb_serial_disconnect, - .id_table = id_table, -}; - -static const __u16 crc10_table[256] = { - 0x000, 0x233, 0x255, 0x066, 0x299, 0x0aa, 0x0cc, 0x2ff, - 0x301, 0x132, 0x154, 0x367, 0x198, 0x3ab, 0x3cd, 0x1fe, - 0x031, 0x202, 0x264, 0x057, 0x2a8, 0x09b, 0x0fd, 0x2ce, - 0x330, 0x103, 0x165, 0x356, 0x1a9, 0x39a, 0x3fc, 0x1cf, - 0x062, 0x251, 0x237, 0x004, 0x2fb, 0x0c8, 0x0ae, 0x29d, - 0x363, 0x150, 0x136, 0x305, 0x1fa, 0x3c9, 0x3af, 0x19c, - 0x053, 0x260, 0x206, 0x035, 0x2ca, 0x0f9, 0x09f, 0x2ac, - 0x352, 0x161, 0x107, 0x334, 0x1cb, 0x3f8, 0x39e, 0x1ad, - 0x0c4, 0x2f7, 0x291, 0x0a2, 0x25d, 0x06e, 0x008, 0x23b, - 0x3c5, 0x1f6, 0x190, 0x3a3, 0x15c, 0x36f, 0x309, 0x13a, - 0x0f5, 0x2c6, 0x2a0, 0x093, 0x26c, 0x05f, 0x039, 0x20a, - 0x3f4, 0x1c7, 0x1a1, 0x392, 0x16d, 0x35e, 0x338, 0x10b, - 0x0a6, 0x295, 0x2f3, 0x0c0, 0x23f, 0x00c, 0x06a, 0x259, - 0x3a7, 0x194, 0x1f2, 0x3c1, 0x13e, 0x30d, 0x36b, 0x158, - 0x097, 0x2a4, 0x2c2, 0x0f1, 0x20e, 0x03d, 0x05b, 0x268, - 0x396, 0x1a5, 0x1c3, 0x3f0, 0x10f, 0x33c, 0x35a, 0x169, - 0x188, 0x3bb, 0x3dd, 0x1ee, 0x311, 0x122, 0x144, 0x377, - 0x289, 0x0ba, 0x0dc, 0x2ef, 0x010, 0x223, 0x245, 0x076, - 0x1b9, 0x38a, 0x3ec, 0x1df, 0x320, 0x113, 0x175, 0x346, - 0x2b8, 0x08b, 0x0ed, 0x2de, 0x021, 0x212, 0x274, 0x047, - 0x1ea, 0x3d9, 0x3bf, 0x18c, 0x373, 0x140, 0x126, 0x315, - 0x2eb, 0x0d8, 0x0be, 0x28d, 0x072, 0x241, 0x227, 0x014, - 0x1db, 0x3e8, 0x38e, 0x1bd, 0x342, 0x171, 0x117, 0x324, - 0x2da, 0x0e9, 0x08f, 0x2bc, 0x043, 0x270, 0x216, 0x025, - 0x14c, 0x37f, 0x319, 0x12a, 0x3d5, 0x1e6, 0x180, 0x3b3, - 0x24d, 0x07e, 0x018, 0x22b, 0x0d4, 0x2e7, 0x281, 0x0b2, - 0x17d, 0x34e, 0x328, 0x11b, 0x3e4, 0x1d7, 0x1b1, 0x382, - 0x27c, 0x04f, 0x029, 0x21a, 0x0e5, 0x2d6, 0x2b0, 0x083, - 0x12e, 0x31d, 0x37b, 0x148, 0x3b7, 0x184, 0x1e2, 0x3d1, - 0x22f, 0x01c, 0x07a, 0x249, 0x0b6, 0x285, 0x2e3, 0x0d0, - 0x11f, 0x32c, 0x34a, 0x179, 0x386, 0x1b5, 0x1d3, 0x3e0, - 0x21e, 0x02d, 0x04b, 0x278, 0x087, 0x2b4, 0x2d2, 0x0e1, -}; - -#define CRC10_INITFCS 0x000 /* Initial FCS value */ -#define CRC10_GOODFCS 0x000 /* Good final FCS value */ -#define CRC10_FCS(fcs, c) ((((fcs) << 8) & 0x3ff) ^ crc10_table[((fcs) >> 2) & 0xff] ^ (c)) - -/** - * fcs_compute10 - memcpy and calculate 10 bit CRC across buffer - * @sp: pointer to buffer - * @len: number of bytes - * @fcs: starting FCS - * - * Perform a memcpy and calculate fcs using ppp 10bit CRC algorithm. Return - * new 10 bit FCS. - */ -static __u16 __inline__ fcs_compute10(unsigned char *sp, int len, __u16 fcs) -{ - for (; len-- > 0; fcs = CRC10_FCS(fcs, *sp++)); - return fcs; -} - -static void safe_process_read_urb(struct urb *urb) -{ - struct usb_serial_port *port = urb->context; - unsigned char *data = urb->transfer_buffer; - unsigned char length = urb->actual_length; - int actual_length; - struct tty_struct *tty; - __u16 fcs; - - if (!length) - return; - - tty = tty_port_tty_get(&port->port); - if (!tty) - return; - - if (!safe) - goto out; - - fcs = fcs_compute10(data, length, CRC10_INITFCS); - if (fcs) { - dev_err(&port->dev, "%s - bad CRC %x\n", __func__, fcs); - goto err; - } - - actual_length = data[length - 2] >> 2; - if (actual_length > (length - 2)) { - dev_err(&port->dev, "%s - inconsistent lengths %d:%d\n", - __func__, actual_length, length); - goto err; - } - dev_info(&urb->dev->dev, "%s - actual: %d\n", __func__, actual_length); - length = actual_length; -out: - tty_insert_flip_string(tty, data, length); - tty_flip_buffer_push(tty); -err: - tty_kref_put(tty); -} - -static int safe_prepare_write_buffer(struct usb_serial_port *port, - void *dest, size_t size) -{ - unsigned char *buf = dest; - int count; - int trailer_len; - int pkt_len; - __u16 fcs; - - trailer_len = safe ? 2 : 0; - - count = kfifo_out_locked(&port->write_fifo, buf, size - trailer_len, - &port->lock); - if (!safe) - return count; - - /* pad if necessary */ - if (padded) { - pkt_len = size; - memset(buf + count, '0', pkt_len - count - trailer_len); - } else { - pkt_len = count + trailer_len; - } - - /* set count */ - buf[pkt_len - 2] = count << 2; - buf[pkt_len - 1] = 0; - - /* compute fcs and insert into trailer */ - fcs = fcs_compute10(buf, pkt_len, CRC10_INITFCS); - buf[pkt_len - 2] |= fcs >> 8; - buf[pkt_len - 1] |= fcs & 0xff; - - return pkt_len; -} - -static int safe_startup(struct usb_serial *serial) -{ - switch (serial->interface->cur_altsetting->desc.bInterfaceProtocol) { - case LINEO_SAFESERIAL_CRC: - break; - case LINEO_SAFESERIAL_CRC_PADDED: - padded = 1; - break; - default: - return -EINVAL; - } - return 0; -} - -static struct usb_serial_driver safe_device = { - .driver = { - .owner = THIS_MODULE, - .name = "safe_serial", - }, - .id_table = id_table, - .num_ports = 1, - .process_read_urb = safe_process_read_urb, - .prepare_write_buffer = safe_prepare_write_buffer, - .attach = safe_startup, -}; - -static struct usb_serial_driver * const serial_drivers[] = { - &safe_device, NULL -}; - -static int __init safe_init(void) -{ - int i; - - printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ":" - DRIVER_DESC "\n"); - - /* if we have vendor / product parameters patch them into id list */ - if (vendor || product) { - printk(KERN_INFO KBUILD_MODNAME ": vendor: %x product: %x\n", - vendor, product); - - for (i = 0; i < ARRAY_SIZE(id_table); i++) { - if (!id_table[i].idVendor && !id_table[i].idProduct) { - id_table[i].idVendor = vendor; - id_table[i].idProduct = product; - break; - } - } - } - - return usb_serial_register_drivers(&safe_driver, serial_drivers); -} - -static void __exit safe_exit(void) -{ - usb_serial_deregister_drivers(&safe_driver, serial_drivers); -} - -module_init(safe_init); -module_exit(safe_exit); diff --git a/ANDROID_3.4.5/drivers/usb/serial/siemens_mpi.c b/ANDROID_3.4.5/drivers/usb/serial/siemens_mpi.c deleted file mode 100644 index 46c0430f..00000000 --- a/ANDROID_3.4.5/drivers/usb/serial/siemens_mpi.c +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Siemens USB-MPI Serial USB driver - * - * Copyright (C) 2005 Thomas Hergenhahn <thomas.hergenhahn@suse.de> - * Copyright (C) 2005,2008 Greg Kroah-Hartman <gregkh@suse.de> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License version - * 2 as published by the Free Software Foundation. - */ - -#include <linux/kernel.h> -#include <linux/init.h> -#include <linux/tty.h> -#include <linux/module.h> -#include <linux/usb.h> -#include <linux/usb/serial.h> - -/* Version Information */ -#define DRIVER_VERSION "Version 0.1 09/26/2005" -#define DRIVER_AUTHOR "Thomas Hergenhahn@web.de http://libnodave.sf.net" -#define DRIVER_DESC "Driver for Siemens USB/MPI adapter" - - -static const struct usb_device_id id_table[] = { - /* Vendor and product id for 6ES7-972-0CB20-0XA0 */ - { USB_DEVICE(0x908, 0x0004) }, - { }, -}; -MODULE_DEVICE_TABLE(usb, id_table); - -static struct usb_driver siemens_usb_mpi_driver = { - .name = "siemens_mpi", - .probe = usb_serial_probe, - .disconnect = usb_serial_disconnect, - .id_table = id_table, -}; - -static struct usb_serial_driver siemens_usb_mpi_device = { - .driver = { - .owner = THIS_MODULE, - .name = "siemens_mpi", - }, - .id_table = id_table, - .num_ports = 1, -}; - -static struct usb_serial_driver * const serial_drivers[] = { - &siemens_usb_mpi_device, NULL -}; - -module_usb_serial_driver(siemens_usb_mpi_driver, serial_drivers); - -MODULE_AUTHOR(DRIVER_AUTHOR); -MODULE_DESCRIPTION(DRIVER_DESC); -MODULE_LICENSE("GPL"); diff --git a/ANDROID_3.4.5/drivers/usb/serial/sierra.c b/ANDROID_3.4.5/drivers/usb/serial/sierra.c deleted file mode 100644 index 449bf6d3..00000000 --- a/ANDROID_3.4.5/drivers/usb/serial/sierra.c +++ /dev/null @@ -1,1136 +0,0 @@ -/* - USB Driver for Sierra Wireless - - Copyright (C) 2006, 2007, 2008 Kevin Lloyd <klloyd@sierrawireless.com>, - - Copyright (C) 2008, 2009 Elina Pasheva, Matthew Safar, Rory Filer - <linux@sierrawireless.com> - - IMPORTANT DISCLAIMER: This driver is not commercially supported by - Sierra Wireless. Use at your own risk. - - This driver is free software; you can redistribute it and/or modify - it under the terms of Version 2 of the GNU General Public License as - published by the Free Software Foundation. - - Portions based on the option driver by Matthias Urlichs <smurf@smurf.noris.de> - Whom based his on the Keyspan driver by Hugh Blemings <hugh@blemings.org> -*/ -/* Uncomment to log function calls */ -/* #define DEBUG */ -#define DRIVER_VERSION "v.1.7.16" -#define DRIVER_AUTHOR "Kevin Lloyd, Elina Pasheva, Matthew Safar, Rory Filer" -#define DRIVER_DESC "USB Driver for Sierra Wireless USB modems" - -#include <linux/kernel.h> -#include <linux/jiffies.h> -#include <linux/errno.h> -#include <linux/tty.h> -#include <linux/slab.h> -#include <linux/tty_flip.h> -#include <linux/module.h> -#include <linux/usb.h> -#include <linux/usb/serial.h> - -#define SWIMS_USB_REQUEST_SetPower 0x00 -#define SWIMS_USB_REQUEST_SetNmea 0x07 - -#define N_IN_URB_HM 8 -#define N_OUT_URB_HM 64 -#define N_IN_URB 4 -#define N_OUT_URB 4 -#define IN_BUFLEN 4096 - -#define MAX_TRANSFER (PAGE_SIZE - 512) -/* MAX_TRANSFER is chosen so that the VM is not stressed by - allocations > PAGE_SIZE and the number of packets in a page - is an integer 512 is the largest possible packet on EHCI */ - -static bool debug; -static bool nmea; - -/* Used in interface blacklisting */ -struct sierra_iface_info { - const u32 infolen; /* number of interface numbers on blacklist */ - const u8 *ifaceinfo; /* pointer to the array holding the numbers */ -}; - -struct sierra_intf_private { - spinlock_t susp_lock; - unsigned int suspended:1; - int in_flight; -}; - -static int sierra_set_power_state(struct usb_device *udev, __u16 swiState) -{ - int result; - dev_dbg(&udev->dev, "%s\n", __func__); - result = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), - SWIMS_USB_REQUEST_SetPower, /* __u8 request */ - USB_TYPE_VENDOR, /* __u8 request type */ - swiState, /* __u16 value */ - 0, /* __u16 index */ - NULL, /* void *data */ - 0, /* __u16 size */ - USB_CTRL_SET_TIMEOUT); /* int timeout */ - return result; -} - -static int sierra_vsc_set_nmea(struct usb_device *udev, __u16 enable) -{ - int result; - dev_dbg(&udev->dev, "%s\n", __func__); - result = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), - SWIMS_USB_REQUEST_SetNmea, /* __u8 request */ - USB_TYPE_VENDOR, /* __u8 request type */ - enable, /* __u16 value */ - 0x0000, /* __u16 index */ - NULL, /* void *data */ - 0, /* __u16 size */ - USB_CTRL_SET_TIMEOUT); /* int timeout */ - return result; -} - -static int sierra_calc_num_ports(struct usb_serial *serial) -{ - int num_ports = 0; - u8 ifnum, numendpoints; - - dev_dbg(&serial->dev->dev, "%s\n", __func__); - - ifnum = serial->interface->cur_altsetting->desc.bInterfaceNumber; - numendpoints = serial->interface->cur_altsetting->desc.bNumEndpoints; - - /* Dummy interface present on some SKUs should be ignored */ - if (ifnum == 0x99) - num_ports = 0; - else if (numendpoints <= 3) - num_ports = 1; - else - num_ports = (numendpoints-1)/2; - return num_ports; -} - -static int is_blacklisted(const u8 ifnum, - const struct sierra_iface_info *blacklist) -{ - const u8 *info; - int i; - - if (blacklist) { - info = blacklist->ifaceinfo; - - for (i = 0; i < blacklist->infolen; i++) { - if (info[i] == ifnum) - return 1; - } - } - return 0; -} - -static int is_himemory(const u8 ifnum, - const struct sierra_iface_info *himemorylist) -{ - const u8 *info; - int i; - - if (himemorylist) { - info = himemorylist->ifaceinfo; - - for (i=0; i < himemorylist->infolen; i++) { - if (info[i] == ifnum) - return 1; - } - } - return 0; -} - -static int sierra_calc_interface(struct usb_serial *serial) -{ - int interface; - struct usb_interface *p_interface; - struct usb_host_interface *p_host_interface; - dev_dbg(&serial->dev->dev, "%s\n", __func__); - - /* Get the interface structure pointer from the serial struct */ - p_interface = serial->interface; - - /* Get a pointer to the host interface structure */ - p_host_interface = p_interface->cur_altsetting; - - /* read the interface descriptor for this active altsetting - * to find out the interface number we are on - */ - interface = p_host_interface->desc.bInterfaceNumber; - - return interface; -} - -static int sierra_probe(struct usb_serial *serial, - const struct usb_device_id *id) -{ - int result = 0; - struct usb_device *udev; - struct sierra_intf_private *data; - u8 ifnum; - - udev = serial->dev; - dev_dbg(&udev->dev, "%s\n", __func__); - - ifnum = sierra_calc_interface(serial); - /* - * If this interface supports more than 1 alternate - * select the 2nd one - */ - if (serial->interface->num_altsetting == 2) { - dev_dbg(&udev->dev, "Selecting alt setting for interface %d\n", - ifnum); - /* We know the alternate setting is 1 for the MC8785 */ - usb_set_interface(udev, ifnum, 1); - } - - /* ifnum could have changed - by calling usb_set_interface */ - ifnum = sierra_calc_interface(serial); - - if (is_blacklisted(ifnum, - (struct sierra_iface_info *)id->driver_info)) { - dev_dbg(&serial->dev->dev, - "Ignoring blacklisted interface #%d\n", ifnum); - return -ENODEV; - } - - data = serial->private = kzalloc(sizeof(struct sierra_intf_private), GFP_KERNEL); - if (!data) - return -ENOMEM; - spin_lock_init(&data->susp_lock); - - return result; -} - -/* interfaces with higher memory requirements */ -static const u8 hi_memory_typeA_ifaces[] = { 0, 2 }; -static const struct sierra_iface_info typeA_interface_list = { - .infolen = ARRAY_SIZE(hi_memory_typeA_ifaces), - .ifaceinfo = hi_memory_typeA_ifaces, -}; - -static const u8 hi_memory_typeB_ifaces[] = { 3, 4, 5, 6 }; -static const struct sierra_iface_info typeB_interface_list = { - .infolen = ARRAY_SIZE(hi_memory_typeB_ifaces), - .ifaceinfo = hi_memory_typeB_ifaces, -}; - -/* 'blacklist' of interfaces not served by this driver */ -static const u8 direct_ip_non_serial_ifaces[] = { 7, 8, 9, 10, 11, 19, 20 }; -static const struct sierra_iface_info direct_ip_interface_blacklist = { - .infolen = ARRAY_SIZE(direct_ip_non_serial_ifaces), - .ifaceinfo = direct_ip_non_serial_ifaces, -}; - -static const struct usb_device_id id_table[] = { - { USB_DEVICE(0x0F3D, 0x0112) }, /* Airprime/Sierra PC 5220 */ - { USB_DEVICE(0x03F0, 0x1B1D) }, /* HP ev2200 a.k.a MC5720 */ - { USB_DEVICE(0x03F0, 0x211D) }, /* HP ev2210 a.k.a MC5725 */ - { USB_DEVICE(0x03F0, 0x1E1D) }, /* HP hs2300 a.k.a MC8775 */ - - { USB_DEVICE(0x1199, 0x0017) }, /* Sierra Wireless EM5625 */ - { USB_DEVICE(0x1199, 0x0018) }, /* Sierra Wireless MC5720 */ - { USB_DEVICE(0x1199, 0x0218) }, /* Sierra Wireless MC5720 */ - { USB_DEVICE(0x1199, 0x0020) }, /* Sierra Wireless MC5725 */ - { USB_DEVICE(0x1199, 0x0220) }, /* Sierra Wireless MC5725 */ - { USB_DEVICE(0x1199, 0x0022) }, /* Sierra Wireless EM5725 */ - { USB_DEVICE(0x1199, 0x0024) }, /* Sierra Wireless MC5727 */ - { USB_DEVICE(0x1199, 0x0224) }, /* Sierra Wireless MC5727 */ - { USB_DEVICE(0x1199, 0x0019) }, /* Sierra Wireless AirCard 595 */ - { USB_DEVICE(0x1199, 0x0021) }, /* Sierra Wireless AirCard 597E */ - { USB_DEVICE(0x1199, 0x0112) }, /* Sierra Wireless AirCard 580 */ - { USB_DEVICE(0x1199, 0x0120) }, /* Sierra Wireless USB Dongle 595U */ - { USB_DEVICE(0x1199, 0x0301) }, /* Sierra Wireless USB Dongle 250U */ - /* Sierra Wireless C597 */ - { USB_DEVICE_AND_INTERFACE_INFO(0x1199, 0x0023, 0xFF, 0xFF, 0xFF) }, - /* Sierra Wireless T598 */ - { USB_DEVICE_AND_INTERFACE_INFO(0x1199, 0x0025, 0xFF, 0xFF, 0xFF) }, - { USB_DEVICE(0x1199, 0x0026) }, /* Sierra Wireless T11 */ - { USB_DEVICE(0x1199, 0x0027) }, /* Sierra Wireless AC402 */ - { USB_DEVICE(0x1199, 0x0028) }, /* Sierra Wireless MC5728 */ - { USB_DEVICE(0x1199, 0x0029) }, /* Sierra Wireless Device */ - - { USB_DEVICE(0x1199, 0x6802) }, /* Sierra Wireless MC8755 */ - { USB_DEVICE(0x1199, 0x6803) }, /* Sierra Wireless MC8765 */ - { USB_DEVICE(0x1199, 0x6804) }, /* Sierra Wireless MC8755 */ - { USB_DEVICE(0x1199, 0x6805) }, /* Sierra Wireless MC8765 */ - { USB_DEVICE(0x1199, 0x6808) }, /* Sierra Wireless MC8755 */ - { USB_DEVICE(0x1199, 0x6809) }, /* Sierra Wireless MC8765 */ - { USB_DEVICE(0x1199, 0x6812) }, /* Sierra Wireless MC8775 & AC 875U */ - { USB_DEVICE(0x1199, 0x6813) }, /* Sierra Wireless MC8775 */ - { USB_DEVICE(0x1199, 0x6815) }, /* Sierra Wireless MC8775 */ - { USB_DEVICE(0x1199, 0x6816) }, /* Sierra Wireless MC8775 */ - { USB_DEVICE(0x1199, 0x6820) }, /* Sierra Wireless AirCard 875 */ - { USB_DEVICE(0x1199, 0x6821) }, /* Sierra Wireless AirCard 875U */ - { USB_DEVICE(0x1199, 0x6822) }, /* Sierra Wireless AirCard 875E */ - { USB_DEVICE(0x1199, 0x6832) }, /* Sierra Wireless MC8780 */ - { USB_DEVICE(0x1199, 0x6833) }, /* Sierra Wireless MC8781 */ - { USB_DEVICE(0x1199, 0x6834) }, /* Sierra Wireless MC8780 */ - { USB_DEVICE(0x1199, 0x6835) }, /* Sierra Wireless MC8781 */ - { USB_DEVICE(0x1199, 0x6838) }, /* Sierra Wireless MC8780 */ - { USB_DEVICE(0x1199, 0x6839) }, /* Sierra Wireless MC8781 */ - { USB_DEVICE(0x1199, 0x683A) }, /* Sierra Wireless MC8785 */ - { USB_DEVICE(0x1199, 0x683B) }, /* Sierra Wireless MC8785 Composite */ - /* Sierra Wireless MC8790, MC8791, MC8792 Composite */ - { USB_DEVICE(0x1199, 0x683C) }, - { USB_DEVICE(0x1199, 0x683D) }, /* Sierra Wireless MC8791 Composite */ - /* Sierra Wireless MC8790, MC8791, MC8792 */ - { USB_DEVICE(0x1199, 0x683E) }, - { USB_DEVICE(0x1199, 0x6850) }, /* Sierra Wireless AirCard 880 */ - { USB_DEVICE(0x1199, 0x6851) }, /* Sierra Wireless AirCard 881 */ - { USB_DEVICE(0x1199, 0x6852) }, /* Sierra Wireless AirCard 880 E */ - { USB_DEVICE(0x1199, 0x6853) }, /* Sierra Wireless AirCard 881 E */ - { USB_DEVICE(0x1199, 0x6855) }, /* Sierra Wireless AirCard 880 U */ - { USB_DEVICE(0x1199, 0x6856) }, /* Sierra Wireless AirCard 881 U */ - { USB_DEVICE(0x1199, 0x6859) }, /* Sierra Wireless AirCard 885 E */ - { USB_DEVICE(0x1199, 0x685A) }, /* Sierra Wireless AirCard 885 E */ - /* Sierra Wireless C885 */ - { USB_DEVICE_AND_INTERFACE_INFO(0x1199, 0x6880, 0xFF, 0xFF, 0xFF)}, - /* Sierra Wireless C888, Air Card 501, USB 303, USB 304 */ - { USB_DEVICE_AND_INTERFACE_INFO(0x1199, 0x6890, 0xFF, 0xFF, 0xFF)}, - /* Sierra Wireless C22/C33 */ - { USB_DEVICE_AND_INTERFACE_INFO(0x1199, 0x6891, 0xFF, 0xFF, 0xFF)}, - /* Sierra Wireless HSPA Non-Composite Device */ - { USB_DEVICE_AND_INTERFACE_INFO(0x1199, 0x6892, 0xFF, 0xFF, 0xFF)}, - { USB_DEVICE(0x1199, 0x6893) }, /* Sierra Wireless Device */ - { USB_DEVICE(0x1199, 0x68A2), /* Sierra Wireless MC77xx in QMI mode */ - .driver_info = (kernel_ulong_t)&direct_ip_interface_blacklist - }, - { USB_DEVICE(0x1199, 0x68A3), /* Sierra Wireless Direct IP modems */ - .driver_info = (kernel_ulong_t)&direct_ip_interface_blacklist - }, - /* AT&T Direct IP LTE modems */ - { USB_DEVICE_AND_INTERFACE_INFO(0x0F3D, 0x68AA, 0xFF, 0xFF, 0xFF), - .driver_info = (kernel_ulong_t)&direct_ip_interface_blacklist - }, - { USB_DEVICE(0x0f3d, 0x68A3), /* Airprime/Sierra Wireless Direct IP modems */ - .driver_info = (kernel_ulong_t)&direct_ip_interface_blacklist - }, - { USB_DEVICE(0x413C, 0x08133) }, /* Dell Computer Corp. Wireless 5720 VZW Mobile Broadband (EVDO Rev-A) Minicard GPS Port */ - - { } -}; -MODULE_DEVICE_TABLE(usb, id_table); - - -struct sierra_port_private { - spinlock_t lock; /* lock the structure */ - int outstanding_urbs; /* number of out urbs in flight */ - struct usb_anchor active; - struct usb_anchor delayed; - - int num_out_urbs; - int num_in_urbs; - /* Input endpoints and buffers for this port */ - struct urb *in_urbs[N_IN_URB_HM]; - - /* Settings for the port */ - int rts_state; /* Handshaking pins (outputs) */ - int dtr_state; - int cts_state; /* Handshaking pins (inputs) */ - int dsr_state; - int dcd_state; - int ri_state; - unsigned int opened:1; -}; - -static int sierra_send_setup(struct usb_serial_port *port) -{ - struct usb_serial *serial = port->serial; - struct sierra_port_private *portdata; - __u16 interface = 0; - int val = 0; - int do_send = 0; - int retval; - - dev_dbg(&port->dev, "%s\n", __func__); - - portdata = usb_get_serial_port_data(port); - - if (portdata->dtr_state) - val |= 0x01; - if (portdata->rts_state) - val |= 0x02; - - /* If composite device then properly report interface */ - if (serial->num_ports == 1) { - interface = sierra_calc_interface(serial); - /* Control message is sent only to interfaces with - * interrupt_in endpoints - */ - if (port->interrupt_in_urb) { - /* send control message */ - do_send = 1; - } - } - - /* Otherwise the need to do non-composite mapping */ - else { - if (port->bulk_out_endpointAddress == 2) - interface = 0; - else if (port->bulk_out_endpointAddress == 4) - interface = 1; - else if (port->bulk_out_endpointAddress == 5) - interface = 2; - - do_send = 1; - } - if (!do_send) - return 0; - - retval = usb_autopm_get_interface(serial->interface); - if (retval < 0) - return retval; - - retval = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0), - 0x22, 0x21, val, interface, NULL, 0, USB_CTRL_SET_TIMEOUT); - usb_autopm_put_interface(serial->interface); - - return retval; -} - -static void sierra_set_termios(struct tty_struct *tty, - struct usb_serial_port *port, struct ktermios *old_termios) -{ - dev_dbg(&port->dev, "%s\n", __func__); - tty_termios_copy_hw(tty->termios, old_termios); - sierra_send_setup(port); -} - -static int sierra_tiocmget(struct tty_struct *tty) -{ - struct usb_serial_port *port = tty->driver_data; - unsigned int value; - struct sierra_port_private *portdata; - - dev_dbg(&port->dev, "%s\n", __func__); - portdata = usb_get_serial_port_data(port); - - value = ((portdata->rts_state) ? TIOCM_RTS : 0) | - ((portdata->dtr_state) ? TIOCM_DTR : 0) | - ((portdata->cts_state) ? TIOCM_CTS : 0) | - ((portdata->dsr_state) ? TIOCM_DSR : 0) | - ((portdata->dcd_state) ? TIOCM_CAR : 0) | - ((portdata->ri_state) ? TIOCM_RNG : 0); - - return value; -} - -static int sierra_tiocmset(struct tty_struct *tty, - unsigned int set, unsigned int clear) -{ - struct usb_serial_port *port = tty->driver_data; - struct sierra_port_private *portdata; - - portdata = usb_get_serial_port_data(port); - - if (set & TIOCM_RTS) - portdata->rts_state = 1; - if (set & TIOCM_DTR) - portdata->dtr_state = 1; - - if (clear & TIOCM_RTS) - portdata->rts_state = 0; - if (clear & TIOCM_DTR) - portdata->dtr_state = 0; - return sierra_send_setup(port); -} - -static void sierra_release_urb(struct urb *urb) -{ - struct usb_serial_port *port; - if (urb) { - port = urb->context; - dev_dbg(&port->dev, "%s: %p\n", __func__, urb); - kfree(urb->transfer_buffer); - usb_free_urb(urb); - } -} - -static void sierra_outdat_callback(struct urb *urb) -{ - struct usb_serial_port *port = urb->context; - struct sierra_port_private *portdata = usb_get_serial_port_data(port); - struct sierra_intf_private *intfdata; - int status = urb->status; - - dev_dbg(&port->dev, "%s - port %d\n", __func__, port->number); - intfdata = port->serial->private; - - /* free up the transfer buffer, as usb_free_urb() does not do this */ - kfree(urb->transfer_buffer); - usb_autopm_put_interface_async(port->serial->interface); - if (status) - dev_dbg(&port->dev, "%s - nonzero write bulk status " - "received: %d\n", __func__, status); - - spin_lock(&portdata->lock); - --portdata->outstanding_urbs; - spin_unlock(&portdata->lock); - spin_lock(&intfdata->susp_lock); - --intfdata->in_flight; - spin_unlock(&intfdata->susp_lock); - - usb_serial_port_softint(port); -} - -/* Write */ -static int sierra_write(struct tty_struct *tty, struct usb_serial_port *port, - const unsigned char *buf, int count) -{ - struct sierra_port_private *portdata; - struct sierra_intf_private *intfdata; - struct usb_serial *serial = port->serial; - unsigned long flags; - unsigned char *buffer; - struct urb *urb; - size_t writesize = min((size_t)count, (size_t)MAX_TRANSFER); - int retval = 0; - - /* verify that we actually have some data to write */ - if (count == 0) - return 0; - - portdata = usb_get_serial_port_data(port); - intfdata = serial->private; - - dev_dbg(&port->dev, "%s: write (%zd bytes)\n", __func__, writesize); - spin_lock_irqsave(&portdata->lock, flags); - dev_dbg(&port->dev, "%s - outstanding_urbs: %d\n", __func__, - portdata->outstanding_urbs); - if (portdata->outstanding_urbs > portdata->num_out_urbs) { - spin_unlock_irqrestore(&portdata->lock, flags); - dev_dbg(&port->dev, "%s - write limit hit\n", __func__); - return 0; - } - portdata->outstanding_urbs++; - dev_dbg(&port->dev, "%s - 1, outstanding_urbs: %d\n", __func__, - portdata->outstanding_urbs); - spin_unlock_irqrestore(&portdata->lock, flags); - - retval = usb_autopm_get_interface_async(serial->interface); - if (retval < 0) { - spin_lock_irqsave(&portdata->lock, flags); - portdata->outstanding_urbs--; - spin_unlock_irqrestore(&portdata->lock, flags); - goto error_simple; - } - - buffer = kmalloc(writesize, GFP_ATOMIC); - if (!buffer) { - dev_err(&port->dev, "out of memory\n"); - retval = -ENOMEM; - goto error_no_buffer; - } - - urb = usb_alloc_urb(0, GFP_ATOMIC); - if (!urb) { - dev_err(&port->dev, "no more free urbs\n"); - retval = -ENOMEM; - goto error_no_urb; - } - - memcpy(buffer, buf, writesize); - - usb_serial_debug_data(debug, &port->dev, __func__, writesize, buffer); - - usb_fill_bulk_urb(urb, serial->dev, - usb_sndbulkpipe(serial->dev, - port->bulk_out_endpointAddress), - buffer, writesize, sierra_outdat_callback, port); - - /* Handle the need to send a zero length packet */ - urb->transfer_flags |= URB_ZERO_PACKET; - - spin_lock_irqsave(&intfdata->susp_lock, flags); - - if (intfdata->suspended) { - usb_anchor_urb(urb, &portdata->delayed); - spin_unlock_irqrestore(&intfdata->susp_lock, flags); - goto skip_power; - } else { - usb_anchor_urb(urb, &portdata->active); - } - /* send it down the pipe */ - retval = usb_submit_urb(urb, GFP_ATOMIC); - if (retval) { - usb_unanchor_urb(urb); - spin_unlock_irqrestore(&intfdata->susp_lock, flags); - dev_err(&port->dev, "%s - usb_submit_urb(write bulk) failed " - "with status = %d\n", __func__, retval); - goto error; - } else { - intfdata->in_flight++; - spin_unlock_irqrestore(&intfdata->susp_lock, flags); - } - -skip_power: - /* we are done with this urb, so let the host driver - * really free it when it is finished with it */ - usb_free_urb(urb); - - return writesize; -error: - usb_free_urb(urb); -error_no_urb: - kfree(buffer); -error_no_buffer: - spin_lock_irqsave(&portdata->lock, flags); - --portdata->outstanding_urbs; - dev_dbg(&port->dev, "%s - 2. outstanding_urbs: %d\n", __func__, - portdata->outstanding_urbs); - spin_unlock_irqrestore(&portdata->lock, flags); - usb_autopm_put_interface_async(serial->interface); -error_simple: - return retval; -} - -static void sierra_indat_callback(struct urb *urb) -{ - int err; - int endpoint; - struct usb_serial_port *port; - struct tty_struct *tty; - unsigned char *data = urb->transfer_buffer; - int status = urb->status; - - endpoint = usb_pipeendpoint(urb->pipe); - port = urb->context; - - dev_dbg(&port->dev, "%s: %p\n", __func__, urb); - - if (status) { - dev_dbg(&port->dev, "%s: nonzero status: %d on" - " endpoint %02x\n", __func__, status, endpoint); - } else { - if (urb->actual_length) { - tty = tty_port_tty_get(&port->port); - if (tty) { - tty_insert_flip_string(tty, data, - urb->actual_length); - tty_flip_buffer_push(tty); - - tty_kref_put(tty); - usb_serial_debug_data(debug, &port->dev, - __func__, urb->actual_length, data); - } - } else { - dev_dbg(&port->dev, "%s: empty read urb" - " received\n", __func__); - } - } - - /* Resubmit urb so we continue receiving */ - if (status != -ESHUTDOWN && status != -EPERM) { - usb_mark_last_busy(port->serial->dev); - err = usb_submit_urb(urb, GFP_ATOMIC); - if (err && err != -EPERM) - dev_err(&port->dev, "resubmit read urb failed." - "(%d)\n", err); - } -} - -static void sierra_instat_callback(struct urb *urb) -{ - int err; - int status = urb->status; - struct usb_serial_port *port = urb->context; - struct sierra_port_private *portdata = usb_get_serial_port_data(port); - struct usb_serial *serial = port->serial; - - dev_dbg(&port->dev, "%s: urb %p port %p has data %p\n", __func__, - urb, port, portdata); - - if (status == 0) { - struct usb_ctrlrequest *req_pkt = - (struct usb_ctrlrequest *)urb->transfer_buffer; - - if (!req_pkt) { - dev_dbg(&port->dev, "%s: NULL req_pkt\n", - __func__); - return; - } - if ((req_pkt->bRequestType == 0xA1) && - (req_pkt->bRequest == 0x20)) { - int old_dcd_state; - unsigned char signals = *((unsigned char *) - urb->transfer_buffer + - sizeof(struct usb_ctrlrequest)); - struct tty_struct *tty; - - dev_dbg(&port->dev, "%s: signal x%x\n", __func__, - signals); - - old_dcd_state = portdata->dcd_state; - portdata->cts_state = 1; - portdata->dcd_state = ((signals & 0x01) ? 1 : 0); - portdata->dsr_state = ((signals & 0x02) ? 1 : 0); - portdata->ri_state = ((signals & 0x08) ? 1 : 0); - - tty = tty_port_tty_get(&port->port); - if (tty && !C_CLOCAL(tty) && - old_dcd_state && !portdata->dcd_state) - tty_hangup(tty); - tty_kref_put(tty); - } else { - dev_dbg(&port->dev, "%s: type %x req %x\n", - __func__, req_pkt->bRequestType, - req_pkt->bRequest); - } - } else - dev_dbg(&port->dev, "%s: error %d\n", __func__, status); - - /* Resubmit urb so we continue receiving IRQ data */ - if (status != -ESHUTDOWN && status != -ENOENT) { - usb_mark_last_busy(serial->dev); - err = usb_submit_urb(urb, GFP_ATOMIC); - if (err && err != -EPERM) - dev_err(&port->dev, "%s: resubmit intr urb " - "failed. (%d)\n", __func__, err); - } -} - -static int sierra_write_room(struct tty_struct *tty) -{ - struct usb_serial_port *port = tty->driver_data; - struct sierra_port_private *portdata = usb_get_serial_port_data(port); - unsigned long flags; - - dev_dbg(&port->dev, "%s - port %d\n", __func__, port->number); - - /* try to give a good number back based on if we have any free urbs at - * this point in time */ - spin_lock_irqsave(&portdata->lock, flags); - if (portdata->outstanding_urbs > (portdata->num_out_urbs * 2) / 3) { - spin_unlock_irqrestore(&portdata->lock, flags); - dev_dbg(&port->dev, "%s - write limit hit\n", __func__); - return 0; - } - spin_unlock_irqrestore(&portdata->lock, flags); - - return 2048; -} - -static void sierra_stop_rx_urbs(struct usb_serial_port *port) -{ - int i; - struct sierra_port_private *portdata = usb_get_serial_port_data(port); - - for (i = 0; i < portdata->num_in_urbs; i++) - usb_kill_urb(portdata->in_urbs[i]); - - usb_kill_urb(port->interrupt_in_urb); -} - -static int sierra_submit_rx_urbs(struct usb_serial_port *port, gfp_t mem_flags) -{ - int ok_cnt; - int err = -EINVAL; - int i; - struct urb *urb; - struct sierra_port_private *portdata = usb_get_serial_port_data(port); - - ok_cnt = 0; - for (i = 0; i < portdata->num_in_urbs; i++) { - urb = portdata->in_urbs[i]; - if (!urb) - continue; - err = usb_submit_urb(urb, mem_flags); - if (err) { - dev_err(&port->dev, "%s: submit urb failed: %d\n", - __func__, err); - } else { - ok_cnt++; - } - } - - if (ok_cnt && port->interrupt_in_urb) { - err = usb_submit_urb(port->interrupt_in_urb, mem_flags); - if (err) { - dev_err(&port->dev, "%s: submit intr urb failed: %d\n", - __func__, err); - } - } - - if (ok_cnt > 0) /* at least one rx urb submitted */ - return 0; - else - return err; -} - -static struct urb *sierra_setup_urb(struct usb_serial *serial, int endpoint, - int dir, void *ctx, int len, - gfp_t mem_flags, - usb_complete_t callback) -{ - struct urb *urb; - u8 *buf; - - if (endpoint == -1) - return NULL; - - urb = usb_alloc_urb(0, mem_flags); - if (urb == NULL) { - dev_dbg(&serial->dev->dev, "%s: alloc for endpoint %d failed\n", - __func__, endpoint); - return NULL; - } - - buf = kmalloc(len, mem_flags); - if (buf) { - /* Fill URB using supplied data */ - usb_fill_bulk_urb(urb, serial->dev, - usb_sndbulkpipe(serial->dev, endpoint) | dir, - buf, len, callback, ctx); - - /* debug */ - dev_dbg(&serial->dev->dev, "%s %c u : %p d:%p\n", __func__, - dir == USB_DIR_IN ? 'i' : 'o', urb, buf); - } else { - dev_dbg(&serial->dev->dev, "%s %c u:%p d:%p\n", __func__, - dir == USB_DIR_IN ? 'i' : 'o', urb, buf); - - sierra_release_urb(urb); - urb = NULL; - } - - return urb; -} - -static void sierra_close(struct usb_serial_port *port) -{ - int i; - struct usb_serial *serial = port->serial; - struct sierra_port_private *portdata; - struct sierra_intf_private *intfdata = port->serial->private; - - - dev_dbg(&port->dev, "%s\n", __func__); - portdata = usb_get_serial_port_data(port); - - portdata->rts_state = 0; - portdata->dtr_state = 0; - - if (serial->dev) { - mutex_lock(&serial->disc_mutex); - if (!serial->disconnected) { - serial->interface->needs_remote_wakeup = 0; - /* odd error handling due to pm counters */ - if (!usb_autopm_get_interface(serial->interface)) - sierra_send_setup(port); - else - usb_autopm_get_interface_no_resume(serial->interface); - - } - mutex_unlock(&serial->disc_mutex); - spin_lock_irq(&intfdata->susp_lock); - portdata->opened = 0; - spin_unlock_irq(&intfdata->susp_lock); - - - /* Stop reading urbs */ - sierra_stop_rx_urbs(port); - /* .. and release them */ - for (i = 0; i < portdata->num_in_urbs; i++) { - sierra_release_urb(portdata->in_urbs[i]); - portdata->in_urbs[i] = NULL; - } - } -} - -static int sierra_open(struct tty_struct *tty, struct usb_serial_port *port) -{ - struct sierra_port_private *portdata; - struct usb_serial *serial = port->serial; - struct sierra_intf_private *intfdata = serial->private; - int i; - int err; - int endpoint; - struct urb *urb; - - portdata = usb_get_serial_port_data(port); - - dev_dbg(&port->dev, "%s\n", __func__); - - /* Set some sane defaults */ - portdata->rts_state = 1; - portdata->dtr_state = 1; - - - endpoint = port->bulk_in_endpointAddress; - for (i = 0; i < portdata->num_in_urbs; i++) { - urb = sierra_setup_urb(serial, endpoint, USB_DIR_IN, port, - IN_BUFLEN, GFP_KERNEL, - sierra_indat_callback); - portdata->in_urbs[i] = urb; - } - /* clear halt condition */ - usb_clear_halt(serial->dev, - usb_sndbulkpipe(serial->dev, endpoint) | USB_DIR_IN); - - err = sierra_submit_rx_urbs(port, GFP_KERNEL); - if (err) { - /* get rid of everything as in close */ - sierra_close(port); - /* restore balance for autopm */ - if (!serial->disconnected) - usb_autopm_put_interface(serial->interface); - return err; - } - sierra_send_setup(port); - - serial->interface->needs_remote_wakeup = 1; - spin_lock_irq(&intfdata->susp_lock); - portdata->opened = 1; - spin_unlock_irq(&intfdata->susp_lock); - usb_autopm_put_interface(serial->interface); - - return 0; -} - - -static void sierra_dtr_rts(struct usb_serial_port *port, int on) -{ - struct usb_serial *serial = port->serial; - struct sierra_port_private *portdata; - - portdata = usb_get_serial_port_data(port); - portdata->rts_state = on; - portdata->dtr_state = on; - - if (serial->dev) { - mutex_lock(&serial->disc_mutex); - if (!serial->disconnected) - sierra_send_setup(port); - mutex_unlock(&serial->disc_mutex); - } -} - -static int sierra_startup(struct usb_serial *serial) -{ - struct usb_serial_port *port; - struct sierra_port_private *portdata; - struct sierra_iface_info *himemoryp = NULL; - int i; - u8 ifnum; - - dev_dbg(&serial->dev->dev, "%s\n", __func__); - - /* Set Device mode to D0 */ - sierra_set_power_state(serial->dev, 0x0000); - - /* Check NMEA and set */ - if (nmea) - sierra_vsc_set_nmea(serial->dev, 1); - - /* Now setup per port private data */ - for (i = 0; i < serial->num_ports; i++) { - port = serial->port[i]; - portdata = kzalloc(sizeof(*portdata), GFP_KERNEL); - if (!portdata) { - dev_dbg(&port->dev, "%s: kmalloc for " - "sierra_port_private (%d) failed!\n", - __func__, i); - return -ENOMEM; - } - spin_lock_init(&portdata->lock); - init_usb_anchor(&portdata->active); - init_usb_anchor(&portdata->delayed); - ifnum = i; - /* Assume low memory requirements */ - portdata->num_out_urbs = N_OUT_URB; - portdata->num_in_urbs = N_IN_URB; - - /* Determine actual memory requirements */ - if (serial->num_ports == 1) { - /* Get interface number for composite device */ - ifnum = sierra_calc_interface(serial); - himemoryp = - (struct sierra_iface_info *)&typeB_interface_list; - if (is_himemory(ifnum, himemoryp)) { - portdata->num_out_urbs = N_OUT_URB_HM; - portdata->num_in_urbs = N_IN_URB_HM; - } - } - else { - himemoryp = - (struct sierra_iface_info *)&typeA_interface_list; - if (is_himemory(i, himemoryp)) { - portdata->num_out_urbs = N_OUT_URB_HM; - portdata->num_in_urbs = N_IN_URB_HM; - } - } - dev_dbg(&serial->dev->dev, - "Memory usage (urbs) interface #%d, in=%d, out=%d\n", - ifnum,portdata->num_in_urbs, portdata->num_out_urbs ); - /* Set the port private data pointer */ - usb_set_serial_port_data(port, portdata); - } - - return 0; -} - -static void sierra_release(struct usb_serial *serial) -{ - int i; - struct usb_serial_port *port; - struct sierra_port_private *portdata; - - dev_dbg(&serial->dev->dev, "%s\n", __func__); - - for (i = 0; i < serial->num_ports; ++i) { - port = serial->port[i]; - if (!port) - continue; - portdata = usb_get_serial_port_data(port); - if (!portdata) - continue; - kfree(portdata); - } -} - -#ifdef CONFIG_PM -static void stop_read_write_urbs(struct usb_serial *serial) -{ - int i; - struct usb_serial_port *port; - struct sierra_port_private *portdata; - - /* Stop reading/writing urbs */ - for (i = 0; i < serial->num_ports; ++i) { - port = serial->port[i]; - portdata = usb_get_serial_port_data(port); - sierra_stop_rx_urbs(port); - usb_kill_anchored_urbs(&portdata->active); - } -} - -static int sierra_suspend(struct usb_serial *serial, pm_message_t message) -{ - struct sierra_intf_private *intfdata; - int b; - - if (PMSG_IS_AUTO(message)) { - intfdata = serial->private; - spin_lock_irq(&intfdata->susp_lock); - b = intfdata->in_flight; - - if (b) { - spin_unlock_irq(&intfdata->susp_lock); - return -EBUSY; - } else { - intfdata->suspended = 1; - spin_unlock_irq(&intfdata->susp_lock); - } - } - stop_read_write_urbs(serial); - - return 0; -} - -static int sierra_resume(struct usb_serial *serial) -{ - struct usb_serial_port *port; - struct sierra_intf_private *intfdata = serial->private; - struct sierra_port_private *portdata; - struct urb *urb; - int ec = 0; - int i, err; - - spin_lock_irq(&intfdata->susp_lock); - for (i = 0; i < serial->num_ports; i++) { - port = serial->port[i]; - portdata = usb_get_serial_port_data(port); - - while ((urb = usb_get_from_anchor(&portdata->delayed))) { - usb_anchor_urb(urb, &portdata->active); - intfdata->in_flight++; - err = usb_submit_urb(urb, GFP_ATOMIC); - if (err < 0) { - intfdata->in_flight--; - usb_unanchor_urb(urb); - usb_scuttle_anchored_urbs(&portdata->delayed); - break; - } - } - - if (portdata->opened) { - err = sierra_submit_rx_urbs(port, GFP_ATOMIC); - if (err) - ec++; - } - } - intfdata->suspended = 0; - spin_unlock_irq(&intfdata->susp_lock); - - return ec ? -EIO : 0; -} - -static int sierra_reset_resume(struct usb_interface *intf) -{ - struct usb_serial *serial = usb_get_intfdata(intf); - dev_err(&serial->dev->dev, "%s\n", __func__); - return usb_serial_resume(intf); -} -#else -#define sierra_suspend NULL -#define sierra_resume NULL -#define sierra_reset_resume NULL -#endif - -static struct usb_driver sierra_driver = { - .name = "sierra", - .probe = usb_serial_probe, - .disconnect = usb_serial_disconnect, - .suspend = usb_serial_suspend, - .resume = usb_serial_resume, - .reset_resume = sierra_reset_resume, - .id_table = id_table, - .supports_autosuspend = 1, -}; - -static struct usb_serial_driver sierra_device = { - .driver = { - .owner = THIS_MODULE, - .name = "sierra", - }, - .description = "Sierra USB modem", - .id_table = id_table, - .calc_num_ports = sierra_calc_num_ports, - .probe = sierra_probe, - .open = sierra_open, - .close = sierra_close, - .dtr_rts = sierra_dtr_rts, - .write = sierra_write, - .write_room = sierra_write_room, - .set_termios = sierra_set_termios, - .tiocmget = sierra_tiocmget, - .tiocmset = sierra_tiocmset, - .attach = sierra_startup, - .release = sierra_release, - .suspend = sierra_suspend, - .resume = sierra_resume, - .read_int_callback = sierra_instat_callback, -}; - -static struct usb_serial_driver * const serial_drivers[] = { - &sierra_device, NULL -}; - -module_usb_serial_driver(sierra_driver, serial_drivers); - -MODULE_AUTHOR(DRIVER_AUTHOR); -MODULE_DESCRIPTION(DRIVER_DESC); -MODULE_VERSION(DRIVER_VERSION); -MODULE_LICENSE("GPL"); - -module_param(nmea, bool, S_IRUGO | S_IWUSR); -MODULE_PARM_DESC(nmea, "NMEA streaming"); - -module_param(debug, bool, S_IRUGO | S_IWUSR); -MODULE_PARM_DESC(debug, "Debug messages"); diff --git a/ANDROID_3.4.5/drivers/usb/serial/spcp8x5.c b/ANDROID_3.4.5/drivers/usb/serial/spcp8x5.c deleted file mode 100644 index f06c9a8f..00000000 --- a/ANDROID_3.4.5/drivers/usb/serial/spcp8x5.c +++ /dev/null @@ -1,676 +0,0 @@ -/* - * spcp8x5 USB to serial adaptor driver - * - * Copyright (C) 2010 Johan Hovold (jhovold@gmail.com) - * Copyright (C) 2006 Linxb (xubin.lin@worldplus.com.cn) - * Copyright (C) 2006 S1 Corp. - * - * Original driver for 2.6.10 pl2303 driver by - * Greg Kroah-Hartman (greg@kroah.com) - * Changes for 2.6.20 by Harald Klein <hari@vt100.at> - * - * 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 <linux/kernel.h> -#include <linux/errno.h> -#include <linux/init.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/usb.h> -#include <linux/usb/serial.h> - - -/* Version Information */ -#define DRIVER_VERSION "v0.10" -#define DRIVER_DESC "SPCP8x5 USB to serial adaptor driver" - -static bool debug; - -#define SPCP8x5_007_VID 0x04FC -#define SPCP8x5_007_PID 0x0201 -#define SPCP8x5_008_VID 0x04fc -#define SPCP8x5_008_PID 0x0235 -#define SPCP8x5_PHILIPS_VID 0x0471 -#define SPCP8x5_PHILIPS_PID 0x081e -#define SPCP8x5_INTERMATIC_VID 0x04FC -#define SPCP8x5_INTERMATIC_PID 0x0204 -#define SPCP8x5_835_VID 0x04fc -#define SPCP8x5_835_PID 0x0231 - -static const struct usb_device_id id_table[] = { - { USB_DEVICE(SPCP8x5_PHILIPS_VID , SPCP8x5_PHILIPS_PID)}, - { USB_DEVICE(SPCP8x5_INTERMATIC_VID, SPCP8x5_INTERMATIC_PID)}, - { USB_DEVICE(SPCP8x5_835_VID, SPCP8x5_835_PID)}, - { USB_DEVICE(SPCP8x5_008_VID, SPCP8x5_008_PID)}, - { USB_DEVICE(SPCP8x5_007_VID, SPCP8x5_007_PID)}, - { } /* Terminating entry */ -}; -MODULE_DEVICE_TABLE(usb, id_table); - -struct spcp8x5_usb_ctrl_arg { - u8 type; - u8 cmd; - u8 cmd_type; - u16 value; - u16 index; - u16 length; -}; - - -/* spcp8x5 spec register define */ -#define MCR_CONTROL_LINE_RTS 0x02 -#define MCR_CONTROL_LINE_DTR 0x01 -#define MCR_DTR 0x01 -#define MCR_RTS 0x02 - -#define MSR_STATUS_LINE_DCD 0x80 -#define MSR_STATUS_LINE_RI 0x40 -#define MSR_STATUS_LINE_DSR 0x20 -#define MSR_STATUS_LINE_CTS 0x10 - -/* verdor command here , we should define myself */ -#define SET_DEFAULT 0x40 -#define SET_DEFAULT_TYPE 0x20 - -#define SET_UART_FORMAT 0x40 -#define SET_UART_FORMAT_TYPE 0x21 -#define SET_UART_FORMAT_SIZE_5 0x00 -#define SET_UART_FORMAT_SIZE_6 0x01 -#define SET_UART_FORMAT_SIZE_7 0x02 -#define SET_UART_FORMAT_SIZE_8 0x03 -#define SET_UART_FORMAT_STOP_1 0x00 -#define SET_UART_FORMAT_STOP_2 0x04 -#define SET_UART_FORMAT_PAR_NONE 0x00 -#define SET_UART_FORMAT_PAR_ODD 0x10 -#define SET_UART_FORMAT_PAR_EVEN 0x30 -#define SET_UART_FORMAT_PAR_MASK 0xD0 -#define SET_UART_FORMAT_PAR_SPACE 0x90 - -#define GET_UART_STATUS_TYPE 0xc0 -#define GET_UART_STATUS 0x22 -#define GET_UART_STATUS_MSR 0x06 - -#define SET_UART_STATUS 0x40 -#define SET_UART_STATUS_TYPE 0x23 -#define SET_UART_STATUS_MCR 0x0004 -#define SET_UART_STATUS_MCR_DTR 0x01 -#define SET_UART_STATUS_MCR_RTS 0x02 -#define SET_UART_STATUS_MCR_LOOP 0x10 - -#define SET_WORKING_MODE 0x40 -#define SET_WORKING_MODE_TYPE 0x24 -#define SET_WORKING_MODE_U2C 0x00 -#define SET_WORKING_MODE_RS485 0x01 -#define SET_WORKING_MODE_PDMA 0x02 -#define SET_WORKING_MODE_SPP 0x03 - -#define SET_FLOWCTL_CHAR 0x40 -#define SET_FLOWCTL_CHAR_TYPE 0x25 - -#define GET_VERSION 0xc0 -#define GET_VERSION_TYPE 0x26 - -#define SET_REGISTER 0x40 -#define SET_REGISTER_TYPE 0x27 - -#define GET_REGISTER 0xc0 -#define GET_REGISTER_TYPE 0x28 - -#define SET_RAM 0x40 -#define SET_RAM_TYPE 0x31 - -#define GET_RAM 0xc0 -#define GET_RAM_TYPE 0x32 - -/* how come ??? */ -#define UART_STATE 0x08 -#define UART_STATE_TRANSIENT_MASK 0x75 -#define UART_DCD 0x01 -#define UART_DSR 0x02 -#define UART_BREAK_ERROR 0x04 -#define UART_RING 0x08 -#define UART_FRAME_ERROR 0x10 -#define UART_PARITY_ERROR 0x20 -#define UART_OVERRUN_ERROR 0x40 -#define UART_CTS 0x80 - -enum spcp8x5_type { - SPCP825_007_TYPE, - SPCP825_008_TYPE, - SPCP825_PHILIP_TYPE, - SPCP825_INTERMATIC_TYPE, - SPCP835_TYPE, -}; - -static struct usb_driver spcp8x5_driver = { - .name = "spcp8x5", - .probe = usb_serial_probe, - .disconnect = usb_serial_disconnect, - .id_table = id_table, -}; - - -struct spcp8x5_private { - spinlock_t lock; - enum spcp8x5_type type; - wait_queue_head_t delta_msr_wait; - u8 line_control; - u8 line_status; -}; - -/* desc : when device plug in,this function would be called. - * thanks to usb_serial subsystem,then do almost every things for us. And what - * we should do just alloc the buffer */ -static int spcp8x5_startup(struct usb_serial *serial) -{ - struct spcp8x5_private *priv; - int i; - enum spcp8x5_type type = SPCP825_007_TYPE; - u16 product = le16_to_cpu(serial->dev->descriptor.idProduct); - - if (product == 0x0201) - type = SPCP825_007_TYPE; - else if (product == 0x0231) - type = SPCP835_TYPE; - else if (product == 0x0235) - type = SPCP825_008_TYPE; - else if (product == 0x0204) - type = SPCP825_INTERMATIC_TYPE; - else if (product == 0x0471 && - serial->dev->descriptor.idVendor == cpu_to_le16(0x081e)) - type = SPCP825_PHILIP_TYPE; - dev_dbg(&serial->dev->dev, "device type = %d\n", (int)type); - - for (i = 0; i < serial->num_ports; ++i) { - priv = kzalloc(sizeof(struct spcp8x5_private), GFP_KERNEL); - if (!priv) - goto cleanup; - - spin_lock_init(&priv->lock); - init_waitqueue_head(&priv->delta_msr_wait); - priv->type = type; - usb_set_serial_port_data(serial->port[i] , priv); - } - - return 0; -cleanup: - for (--i; i >= 0; --i) { - priv = usb_get_serial_port_data(serial->port[i]); - kfree(priv); - usb_set_serial_port_data(serial->port[i] , NULL); - } - return -ENOMEM; -} - -/* call when the device plug out. free all the memory alloced by probe */ -static void spcp8x5_release(struct usb_serial *serial) -{ - int i; - - for (i = 0; i < serial->num_ports; i++) - kfree(usb_get_serial_port_data(serial->port[i])); -} - -/* set the modem control line of the device. - * NOTE spcp825-007 not supported this */ -static int spcp8x5_set_ctrlLine(struct usb_device *dev, u8 value, - enum spcp8x5_type type) -{ - int retval; - u8 mcr = 0 ; - - if (type == SPCP825_007_TYPE) - return -EPERM; - - mcr = (unsigned short)value; - retval = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), - SET_UART_STATUS_TYPE, SET_UART_STATUS, - mcr, 0x04, NULL, 0, 100); - if (retval != 0) - dev_dbg(&dev->dev, "usb_control_msg return %#x\n", retval); - return retval; -} - -/* get the modem status register of the device - * NOTE spcp825-007 not supported this */ -static int spcp8x5_get_msr(struct usb_device *dev, u8 *status, - enum spcp8x5_type type) -{ - u8 *status_buffer; - int ret; - - /* I return Permited not support here but seem inval device - * is more fix */ - if (type == SPCP825_007_TYPE) - return -EPERM; - if (status == NULL) - return -EINVAL; - - status_buffer = kmalloc(1, GFP_KERNEL); - if (!status_buffer) - return -ENOMEM; - status_buffer[0] = status[0]; - - ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), - GET_UART_STATUS, GET_UART_STATUS_TYPE, - 0, GET_UART_STATUS_MSR, status_buffer, 1, 100); - if (ret < 0) - dev_dbg(&dev->dev, "Get MSR = 0x%p failed (error = %d)", - status_buffer, ret); - - dev_dbg(&dev->dev, "0xc0:0x22:0:6 %d - 0x%p ", ret, status_buffer); - status[0] = status_buffer[0]; - kfree(status_buffer); - - return ret; -} - -/* select the work mode. - * NOTE this function not supported by spcp825-007 */ -static void spcp8x5_set_workMode(struct usb_device *dev, u16 value, - u16 index, enum spcp8x5_type type) -{ - int ret; - - /* I return Permited not support here but seem inval device - * is more fix */ - if (type == SPCP825_007_TYPE) - return; - - ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), - SET_WORKING_MODE_TYPE, SET_WORKING_MODE, - value, index, NULL, 0, 100); - dev_dbg(&dev->dev, "value = %#x , index = %#x\n", value, index); - if (ret < 0) - dev_dbg(&dev->dev, - "RTSCTS usb_control_msg(enable flowctrl) = %d\n", ret); -} - -static int spcp8x5_carrier_raised(struct usb_serial_port *port) -{ - struct spcp8x5_private *priv = usb_get_serial_port_data(port); - if (priv->line_status & MSR_STATUS_LINE_DCD) - return 1; - return 0; -} - -static void spcp8x5_dtr_rts(struct usb_serial_port *port, int on) -{ - struct spcp8x5_private *priv = usb_get_serial_port_data(port); - unsigned long flags; - u8 control; - - spin_lock_irqsave(&priv->lock, flags); - if (on) - priv->line_control = MCR_CONTROL_LINE_DTR - | MCR_CONTROL_LINE_RTS; - else - priv->line_control &= ~ (MCR_CONTROL_LINE_DTR - | MCR_CONTROL_LINE_RTS); - control = priv->line_control; - spin_unlock_irqrestore(&priv->lock, flags); - spcp8x5_set_ctrlLine(port->serial->dev, control , priv->type); -} - -static void spcp8x5_init_termios(struct tty_struct *tty) -{ - /* for the 1st time call this function */ - *(tty->termios) = tty_std_termios; - tty->termios->c_cflag = B115200 | CS8 | CREAD | HUPCL | CLOCAL; - tty->termios->c_ispeed = 115200; - tty->termios->c_ospeed = 115200; -} - -/* set the serial param for transfer. we should check if we really need to - * transfer. if we set flow control we should do this too. */ -static void spcp8x5_set_termios(struct tty_struct *tty, - struct usb_serial_port *port, struct ktermios *old_termios) -{ - struct usb_serial *serial = port->serial; - struct spcp8x5_private *priv = usb_get_serial_port_data(port); - unsigned long flags; - unsigned int cflag = tty->termios->c_cflag; - unsigned int old_cflag = old_termios->c_cflag; - unsigned short uartdata; - unsigned char buf[2] = {0, 0}; - int baud; - int i; - u8 control; - - - /* check that they really want us to change something */ - if (!tty_termios_hw_change(tty->termios, old_termios)) - return; - - /* set DTR/RTS active */ - spin_lock_irqsave(&priv->lock, flags); - control = priv->line_control; - if ((old_cflag & CBAUD) == B0) { - priv->line_control |= MCR_DTR; - if (!(old_cflag & CRTSCTS)) - priv->line_control |= MCR_RTS; - } - if (control != priv->line_control) { - control = priv->line_control; - spin_unlock_irqrestore(&priv->lock, flags); - spcp8x5_set_ctrlLine(serial->dev, control , priv->type); - } else { - spin_unlock_irqrestore(&priv->lock, flags); - } - - /* Set Baud Rate */ - baud = tty_get_baud_rate(tty); - switch (baud) { - case 300: buf[0] = 0x00; break; - case 600: buf[0] = 0x01; break; - case 1200: buf[0] = 0x02; break; - case 2400: buf[0] = 0x03; break; - case 4800: buf[0] = 0x04; break; - case 9600: buf[0] = 0x05; break; - case 19200: buf[0] = 0x07; break; - case 38400: buf[0] = 0x09; break; - case 57600: buf[0] = 0x0a; break; - case 115200: buf[0] = 0x0b; break; - case 230400: buf[0] = 0x0c; break; - case 460800: buf[0] = 0x0d; break; - case 921600: buf[0] = 0x0e; break; -/* case 1200000: buf[0] = 0x0f; break; */ -/* case 2400000: buf[0] = 0x10; break; */ - case 3000000: buf[0] = 0x11; break; -/* case 6000000: buf[0] = 0x12; break; */ - case 0: - case 1000000: - buf[0] = 0x0b; break; - default: - dev_err(&port->dev, "spcp825 driver does not support the " - "baudrate requested, using default of 9600.\n"); - } - - /* Set Data Length : 00:5bit, 01:6bit, 10:7bit, 11:8bit */ - if (cflag & CSIZE) { - switch (cflag & CSIZE) { - case CS5: - buf[1] |= SET_UART_FORMAT_SIZE_5; - break; - case CS6: - buf[1] |= SET_UART_FORMAT_SIZE_6; - break; - case CS7: - buf[1] |= SET_UART_FORMAT_SIZE_7; - break; - default: - case CS8: - buf[1] |= SET_UART_FORMAT_SIZE_8; - break; - } - } - - /* Set Stop bit2 : 0:1bit 1:2bit */ - buf[1] |= (cflag & CSTOPB) ? SET_UART_FORMAT_STOP_2 : - SET_UART_FORMAT_STOP_1; - - /* Set Parity bit3-4 01:Odd 11:Even */ - if (cflag & PARENB) { - buf[1] |= (cflag & PARODD) ? - SET_UART_FORMAT_PAR_ODD : SET_UART_FORMAT_PAR_EVEN ; - } else - buf[1] |= SET_UART_FORMAT_PAR_NONE; - - uartdata = buf[0] | buf[1]<<8; - - i = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0), - SET_UART_FORMAT_TYPE, SET_UART_FORMAT, - uartdata, 0, NULL, 0, 100); - if (i < 0) - dev_err(&port->dev, "Set UART format %#x failed (error = %d)\n", - uartdata, i); - dbg("0x21:0x40:0:0 %d", i); - - if (cflag & CRTSCTS) { - /* enable hardware flow control */ - spcp8x5_set_workMode(serial->dev, 0x000a, - SET_WORKING_MODE_U2C, priv->type); - } -} - -/* open the serial port. do some usb system call. set termios and get the line - * status of the device. */ -static int spcp8x5_open(struct tty_struct *tty, struct usb_serial_port *port) -{ - struct ktermios tmp_termios; - struct usb_serial *serial = port->serial; - struct spcp8x5_private *priv = usb_get_serial_port_data(port); - int ret; - unsigned long flags; - u8 status = 0x30; - /* status 0x30 means DSR and CTS = 1 other CDC RI and delta = 0 */ - - dbg("%s - port %d", __func__, port->number); - - usb_clear_halt(serial->dev, port->write_urb->pipe); - usb_clear_halt(serial->dev, port->read_urb->pipe); - - ret = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0), - 0x09, 0x00, - 0x01, 0x00, NULL, 0x00, 100); - if (ret) - return ret; - - spcp8x5_set_ctrlLine(serial->dev, priv->line_control , priv->type); - - /* Setup termios */ - if (tty) - spcp8x5_set_termios(tty, port, &tmp_termios); - - spcp8x5_get_msr(serial->dev, &status, priv->type); - - /* may be we should update uart status here but now we did not do */ - spin_lock_irqsave(&priv->lock, flags); - priv->line_status = status & 0xf0 ; - spin_unlock_irqrestore(&priv->lock, flags); - - port->port.drain_delay = 256; - - return usb_serial_generic_open(tty, port); -} - -static void spcp8x5_process_read_urb(struct urb *urb) -{ - struct usb_serial_port *port = urb->context; - struct spcp8x5_private *priv = usb_get_serial_port_data(port); - struct tty_struct *tty; - unsigned char *data = urb->transfer_buffer; - unsigned long flags; - u8 status; - char tty_flag; - - /* get tty_flag from status */ - tty_flag = TTY_NORMAL; - - spin_lock_irqsave(&priv->lock, flags); - status = priv->line_status; - priv->line_status &= ~UART_STATE_TRANSIENT_MASK; - spin_unlock_irqrestore(&priv->lock, flags); - /* wake up the wait for termios */ - wake_up_interruptible(&priv->delta_msr_wait); - - if (!urb->actual_length) - return; - - tty = tty_port_tty_get(&port->port); - if (!tty) - return; - - if (status & UART_STATE_TRANSIENT_MASK) { - /* break takes precedence over parity, which takes precedence - * over framing errors */ - if (status & UART_BREAK_ERROR) - tty_flag = TTY_BREAK; - else if (status & UART_PARITY_ERROR) - tty_flag = TTY_PARITY; - else if (status & UART_FRAME_ERROR) - tty_flag = TTY_FRAME; - dev_dbg(&port->dev, "tty_flag = %d\n", tty_flag); - - /* overrun is special, not associated with a char */ - if (status & UART_OVERRUN_ERROR) - tty_insert_flip_char(tty, 0, TTY_OVERRUN); - - if (status & UART_DCD) - usb_serial_handle_dcd_change(port, tty, - priv->line_status & MSR_STATUS_LINE_DCD); - } - - tty_insert_flip_string_fixed_flag(tty, data, tty_flag, - urb->actual_length); - tty_flip_buffer_push(tty); - tty_kref_put(tty); -} - -static int spcp8x5_wait_modem_info(struct usb_serial_port *port, - unsigned int arg) -{ - struct spcp8x5_private *priv = usb_get_serial_port_data(port); - unsigned long flags; - unsigned int prevstatus; - unsigned int status; - unsigned int changed; - - spin_lock_irqsave(&priv->lock, flags); - prevstatus = priv->line_status; - spin_unlock_irqrestore(&priv->lock, flags); - - while (1) { - /* wake up in bulk read */ - interruptible_sleep_on(&priv->delta_msr_wait); - - /* see if a signal did it */ - if (signal_pending(current)) - return -ERESTARTSYS; - - spin_lock_irqsave(&priv->lock, flags); - status = priv->line_status; - spin_unlock_irqrestore(&priv->lock, flags); - - changed = prevstatus^status; - - if (((arg & TIOCM_RNG) && (changed & MSR_STATUS_LINE_RI)) || - ((arg & TIOCM_DSR) && (changed & MSR_STATUS_LINE_DSR)) || - ((arg & TIOCM_CD) && (changed & MSR_STATUS_LINE_DCD)) || - ((arg & TIOCM_CTS) && (changed & MSR_STATUS_LINE_CTS))) - return 0; - - prevstatus = status; - } - /* NOTREACHED */ - return 0; -} - -static int spcp8x5_ioctl(struct tty_struct *tty, - unsigned int cmd, unsigned long arg) -{ - struct usb_serial_port *port = tty->driver_data; - dbg("%s (%d) cmd = 0x%04x", __func__, port->number, cmd); - - switch (cmd) { - case TIOCMIWAIT: - dbg("%s (%d) TIOCMIWAIT", __func__, port->number); - return spcp8x5_wait_modem_info(port, arg); - - default: - dbg("%s not supported = 0x%04x", __func__, cmd); - break; - } - - return -ENOIOCTLCMD; -} - -static int spcp8x5_tiocmset(struct tty_struct *tty, - unsigned int set, unsigned int clear) -{ - struct usb_serial_port *port = tty->driver_data; - struct spcp8x5_private *priv = usb_get_serial_port_data(port); - unsigned long flags; - u8 control; - - spin_lock_irqsave(&priv->lock, flags); - if (set & TIOCM_RTS) - priv->line_control |= MCR_RTS; - if (set & TIOCM_DTR) - priv->line_control |= MCR_DTR; - if (clear & TIOCM_RTS) - priv->line_control &= ~MCR_RTS; - if (clear & TIOCM_DTR) - priv->line_control &= ~MCR_DTR; - control = priv->line_control; - spin_unlock_irqrestore(&priv->lock, flags); - - return spcp8x5_set_ctrlLine(port->serial->dev, control , priv->type); -} - -static int spcp8x5_tiocmget(struct tty_struct *tty) -{ - struct usb_serial_port *port = tty->driver_data; - struct spcp8x5_private *priv = usb_get_serial_port_data(port); - unsigned long flags; - unsigned int mcr; - unsigned int status; - unsigned int result; - - spin_lock_irqsave(&priv->lock, flags); - mcr = priv->line_control; - status = priv->line_status; - spin_unlock_irqrestore(&priv->lock, flags); - - result = ((mcr & MCR_DTR) ? TIOCM_DTR : 0) - | ((mcr & MCR_RTS) ? TIOCM_RTS : 0) - | ((status & MSR_STATUS_LINE_CTS) ? TIOCM_CTS : 0) - | ((status & MSR_STATUS_LINE_DSR) ? TIOCM_DSR : 0) - | ((status & MSR_STATUS_LINE_RI) ? TIOCM_RI : 0) - | ((status & MSR_STATUS_LINE_DCD) ? TIOCM_CD : 0); - - return result; -} - -/* All of the device info needed for the spcp8x5 SIO serial converter */ -static struct usb_serial_driver spcp8x5_device = { - .driver = { - .owner = THIS_MODULE, - .name = "SPCP8x5", - }, - .id_table = id_table, - .num_ports = 1, - .open = spcp8x5_open, - .dtr_rts = spcp8x5_dtr_rts, - .carrier_raised = spcp8x5_carrier_raised, - .set_termios = spcp8x5_set_termios, - .init_termios = spcp8x5_init_termios, - .ioctl = spcp8x5_ioctl, - .tiocmget = spcp8x5_tiocmget, - .tiocmset = spcp8x5_tiocmset, - .attach = spcp8x5_startup, - .release = spcp8x5_release, - .process_read_urb = spcp8x5_process_read_urb, -}; - -static struct usb_serial_driver * const serial_drivers[] = { - &spcp8x5_device, NULL -}; - -module_usb_serial_driver(spcp8x5_driver, serial_drivers); - -MODULE_DESCRIPTION(DRIVER_DESC); -MODULE_VERSION(DRIVER_VERSION); -MODULE_LICENSE("GPL"); - -module_param(debug, bool, S_IRUGO | S_IWUSR); -MODULE_PARM_DESC(debug, "Debug enabled or not"); diff --git a/ANDROID_3.4.5/drivers/usb/serial/ssu100.c b/ANDROID_3.4.5/drivers/usb/serial/ssu100.c deleted file mode 100644 index 3cdc8a52..00000000 --- a/ANDROID_3.4.5/drivers/usb/serial/ssu100.c +++ /dev/null @@ -1,704 +0,0 @@ -/* - * usb-serial driver for Quatech SSU-100 - * - * based on ftdi_sio.c and the original serqt_usb.c from Quatech - * - */ - -#include <linux/errno.h> -#include <linux/init.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/serial.h> -#include <linux/usb.h> -#include <linux/usb/serial.h> -#include <linux/serial_reg.h> -#include <linux/uaccess.h> - -#define QT_OPEN_CLOSE_CHANNEL 0xca -#define QT_SET_GET_DEVICE 0xc2 -#define QT_SET_GET_REGISTER 0xc0 -#define QT_GET_SET_PREBUF_TRIG_LVL 0xcc -#define QT_SET_ATF 0xcd -#define QT_GET_SET_UART 0xc1 -#define QT_TRANSFER_IN 0xc0 -#define QT_HW_FLOW_CONTROL_MASK 0xc5 -#define QT_SW_FLOW_CONTROL_MASK 0xc6 - -#define SERIAL_MSR_MASK 0xf0 - -#define SERIAL_CRTSCTS ((UART_MCR_RTS << 8) | UART_MSR_CTS) - -#define SERIAL_EVEN_PARITY (UART_LCR_PARITY | UART_LCR_EPAR) - -#define MAX_BAUD_RATE 460800 - -#define ATC_DISABLED 0x00 -#define DUPMODE_BITS 0xc0 -#define RR_BITS 0x03 -#define LOOPMODE_BITS 0x41 -#define RS232_MODE 0x00 -#define RTSCTS_TO_CONNECTOR 0x40 -#define CLKS_X4 0x02 -#define FULLPWRBIT 0x00000080 -#define NEXT_BOARD_POWER_BIT 0x00000004 - -static bool debug; - -/* Version Information */ -#define DRIVER_VERSION "v0.1" -#define DRIVER_DESC "Quatech SSU-100 USB to Serial Driver" - -#define USB_VENDOR_ID_QUATECH 0x061d /* Quatech VID */ -#define QUATECH_SSU100 0xC020 /* SSU100 */ - -static const struct usb_device_id id_table[] = { - {USB_DEVICE(USB_VENDOR_ID_QUATECH, QUATECH_SSU100)}, - {} /* Terminating entry */ -}; - -MODULE_DEVICE_TABLE(usb, id_table); - - -static struct usb_driver ssu100_driver = { - .name = "ssu100", - .probe = usb_serial_probe, - .disconnect = usb_serial_disconnect, - .id_table = id_table, - .suspend = usb_serial_suspend, - .resume = usb_serial_resume, - .supports_autosuspend = 1, -}; - -struct ssu100_port_private { - spinlock_t status_lock; - u8 shadowLSR; - u8 shadowMSR; - wait_queue_head_t delta_msr_wait; /* Used for TIOCMIWAIT */ - struct async_icount icount; -}; - -static void ssu100_release(struct usb_serial *serial) -{ - struct ssu100_port_private *priv = usb_get_serial_port_data(*serial->port); - - dbg("%s", __func__); - kfree(priv); -} - -static inline int ssu100_control_msg(struct usb_device *dev, - u8 request, u16 data, u16 index) -{ - return usb_control_msg(dev, usb_sndctrlpipe(dev, 0), - request, 0x40, data, index, - NULL, 0, 300); -} - -static inline int ssu100_setdevice(struct usb_device *dev, u8 *data) -{ - u16 x = ((u16)(data[1] << 8) | (u16)(data[0])); - - return ssu100_control_msg(dev, QT_SET_GET_DEVICE, x, 0); -} - - -static inline int ssu100_getdevice(struct usb_device *dev, u8 *data) -{ - return usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), - QT_SET_GET_DEVICE, 0xc0, 0, 0, - data, 3, 300); -} - -static inline int ssu100_getregister(struct usb_device *dev, - unsigned short uart, - unsigned short reg, - u8 *data) -{ - return usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), - QT_SET_GET_REGISTER, 0xc0, reg, - uart, data, sizeof(*data), 300); - -} - - -static inline int ssu100_setregister(struct usb_device *dev, - unsigned short uart, - unsigned short reg, - u16 data) -{ - u16 value = (data << 8) | reg; - - return usb_control_msg(dev, usb_sndctrlpipe(dev, 0), - QT_SET_GET_REGISTER, 0x40, value, uart, - NULL, 0, 300); - -} - -#define set_mctrl(dev, set) update_mctrl((dev), (set), 0) -#define clear_mctrl(dev, clear) update_mctrl((dev), 0, (clear)) - -/* these do not deal with device that have more than 1 port */ -static inline int update_mctrl(struct usb_device *dev, unsigned int set, - unsigned int clear) -{ - unsigned urb_value; - int result; - - if (((set | clear) & (TIOCM_DTR | TIOCM_RTS)) == 0) { - dbg("%s - DTR|RTS not being set|cleared", __func__); - return 0; /* no change */ - } - - clear &= ~set; /* 'set' takes precedence over 'clear' */ - urb_value = 0; - if (set & TIOCM_DTR) - urb_value |= UART_MCR_DTR; - if (set & TIOCM_RTS) - urb_value |= UART_MCR_RTS; - - result = ssu100_setregister(dev, 0, UART_MCR, urb_value); - if (result < 0) - dbg("%s Error from MODEM_CTRL urb", __func__); - - return result; -} - -static int ssu100_initdevice(struct usb_device *dev) -{ - u8 *data; - int result = 0; - - dbg("%s", __func__); - - data = kzalloc(3, GFP_KERNEL); - if (!data) - return -ENOMEM; - - result = ssu100_getdevice(dev, data); - if (result < 0) { - dbg("%s - get_device failed %i", __func__, result); - goto out; - } - - data[1] &= ~FULLPWRBIT; - - result = ssu100_setdevice(dev, data); - if (result < 0) { - dbg("%s - setdevice failed %i", __func__, result); - goto out; - } - - result = ssu100_control_msg(dev, QT_GET_SET_PREBUF_TRIG_LVL, 128, 0); - if (result < 0) { - dbg("%s - set prebuffer level failed %i", __func__, result); - goto out; - } - - result = ssu100_control_msg(dev, QT_SET_ATF, ATC_DISABLED, 0); - if (result < 0) { - dbg("%s - set ATFprebuffer level failed %i", __func__, result); - goto out; - } - - result = ssu100_getdevice(dev, data); - if (result < 0) { - dbg("%s - get_device failed %i", __func__, result); - goto out; - } - - data[0] &= ~(RR_BITS | DUPMODE_BITS); - data[0] |= CLKS_X4; - data[1] &= ~(LOOPMODE_BITS); - data[1] |= RS232_MODE; - - result = ssu100_setdevice(dev, data); - if (result < 0) { - dbg("%s - setdevice failed %i", __func__, result); - goto out; - } - -out: kfree(data); - return result; - -} - - -static void ssu100_set_termios(struct tty_struct *tty, - struct usb_serial_port *port, - struct ktermios *old_termios) -{ - struct usb_device *dev = port->serial->dev; - struct ktermios *termios = tty->termios; - u16 baud, divisor, remainder; - unsigned int cflag = termios->c_cflag; - u16 urb_value = 0; /* will hold the new flags */ - int result; - - dbg("%s", __func__); - - if (cflag & PARENB) { - if (cflag & PARODD) - urb_value |= UART_LCR_PARITY; - else - urb_value |= SERIAL_EVEN_PARITY; - } - - switch (cflag & CSIZE) { - case CS5: - urb_value |= UART_LCR_WLEN5; - break; - case CS6: - urb_value |= UART_LCR_WLEN6; - break; - case CS7: - urb_value |= UART_LCR_WLEN7; - break; - default: - case CS8: - urb_value |= UART_LCR_WLEN8; - break; - } - - baud = tty_get_baud_rate(tty); - if (!baud) - baud = 9600; - - dbg("%s - got baud = %d\n", __func__, baud); - - - divisor = MAX_BAUD_RATE / baud; - remainder = MAX_BAUD_RATE % baud; - if (((remainder * 2) >= baud) && (baud != 110)) - divisor++; - - urb_value = urb_value << 8; - - result = ssu100_control_msg(dev, QT_GET_SET_UART, divisor, urb_value); - if (result < 0) - dbg("%s - set uart failed", __func__); - - if (cflag & CRTSCTS) - result = ssu100_control_msg(dev, QT_HW_FLOW_CONTROL_MASK, - SERIAL_CRTSCTS, 0); - else - result = ssu100_control_msg(dev, QT_HW_FLOW_CONTROL_MASK, - 0, 0); - if (result < 0) - dbg("%s - set HW flow control failed", __func__); - - if (I_IXOFF(tty) || I_IXON(tty)) { - u16 x = ((u16)(START_CHAR(tty) << 8) | (u16)(STOP_CHAR(tty))); - - result = ssu100_control_msg(dev, QT_SW_FLOW_CONTROL_MASK, - x, 0); - } else - result = ssu100_control_msg(dev, QT_SW_FLOW_CONTROL_MASK, - 0, 0); - - if (result < 0) - dbg("%s - set SW flow control failed", __func__); - -} - - -static int ssu100_open(struct tty_struct *tty, struct usb_serial_port *port) -{ - struct usb_device *dev = port->serial->dev; - struct ssu100_port_private *priv = usb_get_serial_port_data(port); - u8 *data; - int result; - unsigned long flags; - - dbg("%s - port %d", __func__, port->number); - - data = kzalloc(2, GFP_KERNEL); - if (!data) - return -ENOMEM; - - result = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), - QT_OPEN_CLOSE_CHANNEL, - QT_TRANSFER_IN, 0x01, - 0, data, 2, 300); - if (result < 0) { - dbg("%s - open failed %i", __func__, result); - kfree(data); - return result; - } - - spin_lock_irqsave(&priv->status_lock, flags); - priv->shadowLSR = data[0]; - priv->shadowMSR = data[1]; - spin_unlock_irqrestore(&priv->status_lock, flags); - - kfree(data); - -/* set to 9600 */ - result = ssu100_control_msg(dev, QT_GET_SET_UART, 0x30, 0x0300); - if (result < 0) - dbg("%s - set uart failed", __func__); - - if (tty) - ssu100_set_termios(tty, port, tty->termios); - - return usb_serial_generic_open(tty, port); -} - -static void ssu100_close(struct usb_serial_port *port) -{ - dbg("%s", __func__); - usb_serial_generic_close(port); -} - -static int get_serial_info(struct usb_serial_port *port, - struct serial_struct __user *retinfo) -{ - struct serial_struct tmp; - - if (!retinfo) - return -EFAULT; - - memset(&tmp, 0, sizeof(tmp)); - tmp.line = port->serial->minor; - tmp.port = 0; - tmp.irq = 0; - tmp.flags = ASYNC_SKIP_TEST | ASYNC_AUTO_IRQ; - tmp.xmit_fifo_size = port->bulk_out_size; - tmp.baud_base = 9600; - tmp.close_delay = 5*HZ; - tmp.closing_wait = 30*HZ; - - if (copy_to_user(retinfo, &tmp, sizeof(*retinfo))) - return -EFAULT; - return 0; -} - -static int wait_modem_info(struct usb_serial_port *port, unsigned int arg) -{ - struct ssu100_port_private *priv = usb_get_serial_port_data(port); - struct async_icount prev, cur; - unsigned long flags; - - spin_lock_irqsave(&priv->status_lock, flags); - prev = priv->icount; - spin_unlock_irqrestore(&priv->status_lock, flags); - - while (1) { - wait_event_interruptible(priv->delta_msr_wait, - ((priv->icount.rng != prev.rng) || - (priv->icount.dsr != prev.dsr) || - (priv->icount.dcd != prev.dcd) || - (priv->icount.cts != prev.cts))); - - if (signal_pending(current)) - return -ERESTARTSYS; - - spin_lock_irqsave(&priv->status_lock, flags); - cur = priv->icount; - spin_unlock_irqrestore(&priv->status_lock, flags); - - if ((prev.rng == cur.rng) && - (prev.dsr == cur.dsr) && - (prev.dcd == cur.dcd) && - (prev.cts == cur.cts)) - return -EIO; - - if ((arg & TIOCM_RNG && (prev.rng != cur.rng)) || - (arg & TIOCM_DSR && (prev.dsr != cur.dsr)) || - (arg & TIOCM_CD && (prev.dcd != cur.dcd)) || - (arg & TIOCM_CTS && (prev.cts != cur.cts))) - return 0; - } - return 0; -} - -static int ssu100_get_icount(struct tty_struct *tty, - struct serial_icounter_struct *icount) -{ - struct usb_serial_port *port = tty->driver_data; - struct ssu100_port_private *priv = usb_get_serial_port_data(port); - struct async_icount cnow = priv->icount; - - icount->cts = cnow.cts; - icount->dsr = cnow.dsr; - icount->rng = cnow.rng; - icount->dcd = cnow.dcd; - icount->rx = cnow.rx; - icount->tx = cnow.tx; - icount->frame = cnow.frame; - icount->overrun = cnow.overrun; - icount->parity = cnow.parity; - icount->brk = cnow.brk; - icount->buf_overrun = cnow.buf_overrun; - - return 0; -} - - - -static int ssu100_ioctl(struct tty_struct *tty, - unsigned int cmd, unsigned long arg) -{ - struct usb_serial_port *port = tty->driver_data; - - dbg("%s cmd 0x%04x", __func__, cmd); - - switch (cmd) { - case TIOCGSERIAL: - return get_serial_info(port, - (struct serial_struct __user *) arg); - - case TIOCMIWAIT: - return wait_modem_info(port, arg); - - default: - break; - } - - dbg("%s arg not supported", __func__); - - return -ENOIOCTLCMD; -} - -static int ssu100_attach(struct usb_serial *serial) -{ - struct ssu100_port_private *priv; - struct usb_serial_port *port = *serial->port; - - dbg("%s", __func__); - - priv = kzalloc(sizeof(*priv), GFP_KERNEL); - if (!priv) { - dev_err(&port->dev, "%s- kmalloc(%Zd) failed.\n", __func__, - sizeof(*priv)); - return -ENOMEM; - } - - spin_lock_init(&priv->status_lock); - init_waitqueue_head(&priv->delta_msr_wait); - usb_set_serial_port_data(port, priv); - - return ssu100_initdevice(serial->dev); -} - -static int ssu100_tiocmget(struct tty_struct *tty) -{ - struct usb_serial_port *port = tty->driver_data; - struct usb_device *dev = port->serial->dev; - u8 *d; - int r; - - dbg("%s\n", __func__); - - d = kzalloc(2, GFP_KERNEL); - if (!d) - return -ENOMEM; - - r = ssu100_getregister(dev, 0, UART_MCR, d); - if (r < 0) - goto mget_out; - - r = ssu100_getregister(dev, 0, UART_MSR, d+1); - if (r < 0) - goto mget_out; - - r = (d[0] & UART_MCR_DTR ? TIOCM_DTR : 0) | - (d[0] & UART_MCR_RTS ? TIOCM_RTS : 0) | - (d[1] & UART_MSR_CTS ? TIOCM_CTS : 0) | - (d[1] & UART_MSR_DCD ? TIOCM_CAR : 0) | - (d[1] & UART_MSR_RI ? TIOCM_RI : 0) | - (d[1] & UART_MSR_DSR ? TIOCM_DSR : 0); - -mget_out: - kfree(d); - return r; -} - -static int ssu100_tiocmset(struct tty_struct *tty, - unsigned int set, unsigned int clear) -{ - struct usb_serial_port *port = tty->driver_data; - struct usb_device *dev = port->serial->dev; - - dbg("%s\n", __func__); - return update_mctrl(dev, set, clear); -} - -static void ssu100_dtr_rts(struct usb_serial_port *port, int on) -{ - struct usb_device *dev = port->serial->dev; - - dbg("%s\n", __func__); - - mutex_lock(&port->serial->disc_mutex); - if (!port->serial->disconnected) { - /* Disable flow control */ - if (!on && - ssu100_setregister(dev, 0, UART_MCR, 0) < 0) - dev_err(&port->dev, "error from flowcontrol urb\n"); - /* drop RTS and DTR */ - if (on) - set_mctrl(dev, TIOCM_DTR | TIOCM_RTS); - else - clear_mctrl(dev, TIOCM_DTR | TIOCM_RTS); - } - mutex_unlock(&port->serial->disc_mutex); -} - -static void ssu100_update_msr(struct usb_serial_port *port, u8 msr) -{ - struct ssu100_port_private *priv = usb_get_serial_port_data(port); - unsigned long flags; - - spin_lock_irqsave(&priv->status_lock, flags); - priv->shadowMSR = msr; - spin_unlock_irqrestore(&priv->status_lock, flags); - - if (msr & UART_MSR_ANY_DELTA) { - /* update input line counters */ - if (msr & UART_MSR_DCTS) - priv->icount.cts++; - if (msr & UART_MSR_DDSR) - priv->icount.dsr++; - if (msr & UART_MSR_DDCD) - priv->icount.dcd++; - if (msr & UART_MSR_TERI) - priv->icount.rng++; - wake_up_interruptible(&priv->delta_msr_wait); - } -} - -static void ssu100_update_lsr(struct usb_serial_port *port, u8 lsr, - char *tty_flag) -{ - struct ssu100_port_private *priv = usb_get_serial_port_data(port); - unsigned long flags; - - spin_lock_irqsave(&priv->status_lock, flags); - priv->shadowLSR = lsr; - spin_unlock_irqrestore(&priv->status_lock, flags); - - *tty_flag = TTY_NORMAL; - if (lsr & UART_LSR_BRK_ERROR_BITS) { - /* we always want to update icount, but we only want to - * update tty_flag for one case */ - if (lsr & UART_LSR_BI) { - priv->icount.brk++; - *tty_flag = TTY_BREAK; - usb_serial_handle_break(port); - } - if (lsr & UART_LSR_PE) { - priv->icount.parity++; - if (*tty_flag == TTY_NORMAL) - *tty_flag = TTY_PARITY; - } - if (lsr & UART_LSR_FE) { - priv->icount.frame++; - if (*tty_flag == TTY_NORMAL) - *tty_flag = TTY_FRAME; - } - if (lsr & UART_LSR_OE){ - priv->icount.overrun++; - if (*tty_flag == TTY_NORMAL) - *tty_flag = TTY_OVERRUN; - } - } - -} - -static int ssu100_process_packet(struct urb *urb, - struct tty_struct *tty) -{ - struct usb_serial_port *port = urb->context; - char *packet = (char *)urb->transfer_buffer; - char flag = TTY_NORMAL; - u32 len = urb->actual_length; - int i; - char *ch; - - dbg("%s - port %d", __func__, port->number); - - if ((len >= 4) && - (packet[0] == 0x1b) && (packet[1] == 0x1b) && - ((packet[2] == 0x00) || (packet[2] == 0x01))) { - if (packet[2] == 0x00) { - ssu100_update_lsr(port, packet[3], &flag); - if (flag == TTY_OVERRUN) - tty_insert_flip_char(tty, 0, TTY_OVERRUN); - } - if (packet[2] == 0x01) - ssu100_update_msr(port, packet[3]); - - len -= 4; - ch = packet + 4; - } else - ch = packet; - - if (!len) - return 0; /* status only */ - - if (port->port.console && port->sysrq) { - for (i = 0; i < len; i++, ch++) { - if (!usb_serial_handle_sysrq_char(port, *ch)) - tty_insert_flip_char(tty, *ch, flag); - } - } else - tty_insert_flip_string_fixed_flag(tty, ch, flag, len); - - return len; -} - -static void ssu100_process_read_urb(struct urb *urb) -{ - struct usb_serial_port *port = urb->context; - struct tty_struct *tty; - int count; - - dbg("%s", __func__); - - tty = tty_port_tty_get(&port->port); - if (!tty) - return; - - count = ssu100_process_packet(urb, tty); - - if (count) - tty_flip_buffer_push(tty); - tty_kref_put(tty); -} - -static struct usb_serial_driver ssu100_device = { - .driver = { - .owner = THIS_MODULE, - .name = "ssu100", - }, - .description = DRIVER_DESC, - .id_table = id_table, - .num_ports = 1, - .open = ssu100_open, - .close = ssu100_close, - .attach = ssu100_attach, - .release = ssu100_release, - .dtr_rts = ssu100_dtr_rts, - .process_read_urb = ssu100_process_read_urb, - .tiocmget = ssu100_tiocmget, - .tiocmset = ssu100_tiocmset, - .get_icount = ssu100_get_icount, - .ioctl = ssu100_ioctl, - .set_termios = ssu100_set_termios, - .disconnect = usb_serial_generic_disconnect, -}; - -static struct usb_serial_driver * const serial_drivers[] = { - &ssu100_device, NULL -}; - -module_usb_serial_driver(ssu100_driver, serial_drivers); - -MODULE_DESCRIPTION(DRIVER_DESC); -MODULE_LICENSE("GPL"); - -module_param(debug, bool, S_IRUGO | S_IWUSR); -MODULE_PARM_DESC(debug, "Debug enabled or not"); diff --git a/ANDROID_3.4.5/drivers/usb/serial/symbolserial.c b/ANDROID_3.4.5/drivers/usb/serial/symbolserial.c deleted file mode 100644 index 1a5be136..00000000 --- a/ANDROID_3.4.5/drivers/usb/serial/symbolserial.c +++ /dev/null @@ -1,317 +0,0 @@ -/* - * Symbol USB barcode to serial driver - * - * Copyright (C) 2009 Greg Kroah-Hartman <gregkh@suse.de> - * Copyright (C) 2009 Novell Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License version - * 2 as published by the Free Software Foundation. - */ - -#include <linux/kernel.h> -#include <linux/init.h> -#include <linux/tty.h> -#include <linux/slab.h> -#include <linux/tty_driver.h> -#include <linux/tty_flip.h> -#include <linux/module.h> -#include <linux/usb.h> -#include <linux/usb/serial.h> -#include <linux/uaccess.h> - -static bool debug; - -static const struct usb_device_id id_table[] = { - { USB_DEVICE(0x05e0, 0x0600) }, - { }, -}; -MODULE_DEVICE_TABLE(usb, id_table); - -/* This structure holds all of the individual device information */ -struct symbol_private { - struct usb_device *udev; - struct usb_serial *serial; - struct usb_serial_port *port; - unsigned char *int_buffer; - struct urb *int_urb; - int buffer_size; - u8 bInterval; - u8 int_address; - spinlock_t lock; /* protects the following flags */ - bool throttled; - bool actually_throttled; - bool rts; -}; - -static void symbol_int_callback(struct urb *urb) -{ - struct symbol_private *priv = urb->context; - unsigned char *data = urb->transfer_buffer; - struct usb_serial_port *port = priv->port; - int status = urb->status; - struct tty_struct *tty; - int result; - int data_length; - - dbg("%s - port %d", __func__, port->number); - - switch (status) { - case 0: - /* success */ - break; - case -ECONNRESET: - case -ENOENT: - case -ESHUTDOWN: - /* this urb is terminated, clean up */ - dbg("%s - urb shutting down with status: %d", - __func__, status); - return; - default: - dbg("%s - nonzero urb status received: %d", - __func__, status); - goto exit; - } - - usb_serial_debug_data(debug, &port->dev, __func__, urb->actual_length, - data); - - if (urb->actual_length > 1) { - data_length = urb->actual_length - 1; - - /* - * Data from the device comes with a 1 byte header: - * - * <size of data>data... - * This is real data to be sent to the tty layer - * we pretty much just ignore the size and send everything - * else to the tty layer. - */ - tty = tty_port_tty_get(&port->port); - if (tty) { - tty_insert_flip_string(tty, &data[1], data_length); - tty_flip_buffer_push(tty); - tty_kref_put(tty); - } - } else { - dev_dbg(&priv->udev->dev, - "Improper amount of data received from the device, " - "%d bytes", urb->actual_length); - } - -exit: - spin_lock(&priv->lock); - - /* Continue trying to always read if we should */ - if (!priv->throttled) { - usb_fill_int_urb(priv->int_urb, priv->udev, - usb_rcvintpipe(priv->udev, - priv->int_address), - priv->int_buffer, priv->buffer_size, - symbol_int_callback, priv, priv->bInterval); - result = usb_submit_urb(priv->int_urb, GFP_ATOMIC); - if (result) - dev_err(&port->dev, - "%s - failed resubmitting read urb, error %d\n", - __func__, result); - } else - priv->actually_throttled = true; - spin_unlock(&priv->lock); -} - -static int symbol_open(struct tty_struct *tty, struct usb_serial_port *port) -{ - struct symbol_private *priv = usb_get_serial_data(port->serial); - unsigned long flags; - int result = 0; - - dbg("%s - port %d", __func__, port->number); - - spin_lock_irqsave(&priv->lock, flags); - priv->throttled = false; - priv->actually_throttled = false; - priv->port = port; - spin_unlock_irqrestore(&priv->lock, flags); - - /* Start reading from the device */ - usb_fill_int_urb(priv->int_urb, priv->udev, - usb_rcvintpipe(priv->udev, priv->int_address), - priv->int_buffer, priv->buffer_size, - symbol_int_callback, priv, priv->bInterval); - result = usb_submit_urb(priv->int_urb, GFP_KERNEL); - if (result) - dev_err(&port->dev, - "%s - failed resubmitting read urb, error %d\n", - __func__, result); - return result; -} - -static void symbol_close(struct usb_serial_port *port) -{ - struct symbol_private *priv = usb_get_serial_data(port->serial); - - dbg("%s - port %d", __func__, port->number); - - /* shutdown our urbs */ - usb_kill_urb(priv->int_urb); -} - -static void symbol_throttle(struct tty_struct *tty) -{ - struct usb_serial_port *port = tty->driver_data; - struct symbol_private *priv = usb_get_serial_data(port->serial); - - dbg("%s - port %d", __func__, port->number); - spin_lock_irq(&priv->lock); - priv->throttled = true; - spin_unlock_irq(&priv->lock); -} - -static void symbol_unthrottle(struct tty_struct *tty) -{ - struct usb_serial_port *port = tty->driver_data; - struct symbol_private *priv = usb_get_serial_data(port->serial); - int result; - bool was_throttled; - - dbg("%s - port %d", __func__, port->number); - - spin_lock_irq(&priv->lock); - priv->throttled = false; - was_throttled = priv->actually_throttled; - priv->actually_throttled = false; - spin_unlock_irq(&priv->lock); - - if (was_throttled) { - result = usb_submit_urb(priv->int_urb, GFP_KERNEL); - if (result) - dev_err(&port->dev, - "%s - failed submitting read urb, error %d\n", - __func__, result); - } -} - -static int symbol_startup(struct usb_serial *serial) -{ - struct symbol_private *priv; - struct usb_host_interface *intf; - int i; - int retval = -ENOMEM; - bool int_in_found = false; - - /* create our private serial structure */ - priv = kzalloc(sizeof(*priv), GFP_KERNEL); - if (priv == NULL) { - dev_err(&serial->dev->dev, "%s - Out of memory\n", __func__); - return -ENOMEM; - } - spin_lock_init(&priv->lock); - priv->serial = serial; - priv->port = serial->port[0]; - priv->udev = serial->dev; - - /* find our interrupt endpoint */ - intf = serial->interface->altsetting; - for (i = 0; i < intf->desc.bNumEndpoints; ++i) { - struct usb_endpoint_descriptor *endpoint; - - endpoint = &intf->endpoint[i].desc; - if (!usb_endpoint_is_int_in(endpoint)) - continue; - - priv->int_urb = usb_alloc_urb(0, GFP_KERNEL); - if (!priv->int_urb) { - dev_err(&priv->udev->dev, "out of memory\n"); - goto error; - } - - priv->buffer_size = usb_endpoint_maxp(endpoint) * 2; - priv->int_buffer = kmalloc(priv->buffer_size, GFP_KERNEL); - if (!priv->int_buffer) { - dev_err(&priv->udev->dev, "out of memory\n"); - goto error; - } - - priv->int_address = endpoint->bEndpointAddress; - priv->bInterval = endpoint->bInterval; - - /* set up our int urb */ - usb_fill_int_urb(priv->int_urb, priv->udev, - usb_rcvintpipe(priv->udev, - endpoint->bEndpointAddress), - priv->int_buffer, priv->buffer_size, - symbol_int_callback, priv, priv->bInterval); - - int_in_found = true; - break; - } - - if (!int_in_found) { - dev_err(&priv->udev->dev, - "Error - the proper endpoints were not found!\n"); - goto error; - } - - usb_set_serial_data(serial, priv); - return 0; - -error: - usb_free_urb(priv->int_urb); - kfree(priv->int_buffer); - kfree(priv); - return retval; -} - -static void symbol_disconnect(struct usb_serial *serial) -{ - struct symbol_private *priv = usb_get_serial_data(serial); - - dbg("%s", __func__); - - usb_kill_urb(priv->int_urb); - usb_free_urb(priv->int_urb); -} - -static void symbol_release(struct usb_serial *serial) -{ - struct symbol_private *priv = usb_get_serial_data(serial); - - dbg("%s", __func__); - - kfree(priv->int_buffer); - kfree(priv); -} - -static struct usb_driver symbol_driver = { - .name = "symbol", - .probe = usb_serial_probe, - .disconnect = usb_serial_disconnect, - .id_table = id_table, -}; - -static struct usb_serial_driver symbol_device = { - .driver = { - .owner = THIS_MODULE, - .name = "symbol", - }, - .id_table = id_table, - .num_ports = 1, - .attach = symbol_startup, - .open = symbol_open, - .close = symbol_close, - .disconnect = symbol_disconnect, - .release = symbol_release, - .throttle = symbol_throttle, - .unthrottle = symbol_unthrottle, -}; - -static struct usb_serial_driver * const serial_drivers[] = { - &symbol_device, NULL -}; - -module_usb_serial_driver(symbol_driver, serial_drivers); - -MODULE_LICENSE("GPL"); - -module_param(debug, bool, S_IRUGO | S_IWUSR); -MODULE_PARM_DESC(debug, "Debug enabled or not"); diff --git a/ANDROID_3.4.5/drivers/usb/serial/ti_usb_3410_5052.c b/ANDROID_3.4.5/drivers/usb/serial/ti_usb_3410_5052.c deleted file mode 100644 index 33774375..00000000 --- a/ANDROID_3.4.5/drivers/usb/serial/ti_usb_3410_5052.c +++ /dev/null @@ -1,1750 +0,0 @@ -/* vi: ts=8 sw=8 - * - * TI 3410/5052 USB Serial Driver - * - * Copyright (C) 2004 Texas Instruments - * - * This driver is based on the Linux io_ti driver, which is - * Copyright (C) 2000-2002 Inside Out Networks - * Copyright (C) 2001-2002 Greg Kroah-Hartman - * - * 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. - * - * For questions or problems with this driver, contact Texas Instruments - * technical support, or Al Borchers <alborchers@steinerpoint.com>, or - * Peter Berger <pberger@brimson.com>. - */ - -#include <linux/kernel.h> -#include <linux/errno.h> -#include <linux/firmware.h> -#include <linux/init.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/ioctl.h> -#include <linux/serial.h> -#include <linux/kfifo.h> -#include <linux/mutex.h> -#include <linux/uaccess.h> -#include <linux/usb.h> -#include <linux/usb/serial.h> - -#include "ti_usb_3410_5052.h" - -/* Defines */ - -#define TI_DRIVER_VERSION "v0.10" -#define TI_DRIVER_AUTHOR "Al Borchers <alborchers@steinerpoint.com>" -#define TI_DRIVER_DESC "TI USB 3410/5052 Serial Driver" - -#define TI_FIRMWARE_BUF_SIZE 16284 - -#define TI_WRITE_BUF_SIZE 1024 - -#define TI_TRANSFER_TIMEOUT 2 - -#define TI_DEFAULT_CLOSING_WAIT 4000 /* in .01 secs */ - -/* supported setserial flags */ -#define TI_SET_SERIAL_FLAGS 0 - -/* read urb states */ -#define TI_READ_URB_RUNNING 0 -#define TI_READ_URB_STOPPING 1 -#define TI_READ_URB_STOPPED 2 - -#define TI_EXTRA_VID_PID_COUNT 5 - - -/* Structures */ - -struct ti_port { - int tp_is_open; - __u8 tp_msr; - __u8 tp_lsr; - __u8 tp_shadow_mcr; - __u8 tp_uart_mode; /* 232 or 485 modes */ - unsigned int tp_uart_base_addr; - int tp_flags; - int tp_closing_wait;/* in .01 secs */ - struct async_icount tp_icount; - wait_queue_head_t tp_msr_wait; /* wait for msr change */ - wait_queue_head_t tp_write_wait; - struct ti_device *tp_tdev; - struct usb_serial_port *tp_port; - spinlock_t tp_lock; - int tp_read_urb_state; - int tp_write_urb_in_use; - struct kfifo write_fifo; -}; - -struct ti_device { - struct mutex td_open_close_lock; - int td_open_port_count; - struct usb_serial *td_serial; - int td_is_3410; - int td_urb_error; -}; - - -/* Function Declarations */ - -static int ti_startup(struct usb_serial *serial); -static void ti_release(struct usb_serial *serial); -static int ti_open(struct tty_struct *tty, struct usb_serial_port *port); -static void ti_close(struct usb_serial_port *port); -static int ti_write(struct tty_struct *tty, struct usb_serial_port *port, - const unsigned char *data, int count); -static int ti_write_room(struct tty_struct *tty); -static int ti_chars_in_buffer(struct tty_struct *tty); -static void ti_throttle(struct tty_struct *tty); -static void ti_unthrottle(struct tty_struct *tty); -static int ti_ioctl(struct tty_struct *tty, - unsigned int cmd, unsigned long arg); -static int ti_get_icount(struct tty_struct *tty, - struct serial_icounter_struct *icount); -static void ti_set_termios(struct tty_struct *tty, - struct usb_serial_port *port, struct ktermios *old_termios); -static int ti_tiocmget(struct tty_struct *tty); -static int ti_tiocmset(struct tty_struct *tty, - unsigned int set, unsigned int clear); -static void ti_break(struct tty_struct *tty, int break_state); -static void ti_interrupt_callback(struct urb *urb); -static void ti_bulk_in_callback(struct urb *urb); -static void ti_bulk_out_callback(struct urb *urb); - -static void ti_recv(struct device *dev, struct tty_struct *tty, - unsigned char *data, int length); -static void ti_send(struct ti_port *tport); -static int ti_set_mcr(struct ti_port *tport, unsigned int mcr); -static int ti_get_lsr(struct ti_port *tport); -static int ti_get_serial_info(struct ti_port *tport, - struct serial_struct __user *ret_arg); -static int ti_set_serial_info(struct tty_struct *tty, struct ti_port *tport, - struct serial_struct __user *new_arg); -static void ti_handle_new_msr(struct ti_port *tport, __u8 msr); - -static void ti_drain(struct ti_port *tport, unsigned long timeout, int flush); - -static void ti_stop_read(struct ti_port *tport, struct tty_struct *tty); -static int ti_restart_read(struct ti_port *tport, struct tty_struct *tty); - -static int ti_command_out_sync(struct ti_device *tdev, __u8 command, - __u16 moduleid, __u16 value, __u8 *data, int size); -static int ti_command_in_sync(struct ti_device *tdev, __u8 command, - __u16 moduleid, __u16 value, __u8 *data, int size); - -static int ti_write_byte(struct ti_device *tdev, unsigned long addr, - __u8 mask, __u8 byte); - -static int ti_download_firmware(struct ti_device *tdev); - - -/* Data */ - -/* module parameters */ -static bool debug; -static int closing_wait = TI_DEFAULT_CLOSING_WAIT; -static ushort vendor_3410[TI_EXTRA_VID_PID_COUNT]; -static unsigned int vendor_3410_count; -static ushort product_3410[TI_EXTRA_VID_PID_COUNT]; -static unsigned int product_3410_count; -static ushort vendor_5052[TI_EXTRA_VID_PID_COUNT]; -static unsigned int vendor_5052_count; -static ushort product_5052[TI_EXTRA_VID_PID_COUNT]; -static unsigned int product_5052_count; - -/* supported devices */ -/* the array dimension is the number of default entries plus */ -/* TI_EXTRA_VID_PID_COUNT user defined entries plus 1 terminating */ -/* null entry */ -static struct usb_device_id ti_id_table_3410[15+TI_EXTRA_VID_PID_COUNT+1] = { - { USB_DEVICE(TI_VENDOR_ID, TI_3410_PRODUCT_ID) }, - { USB_DEVICE(TI_VENDOR_ID, TI_3410_EZ430_ID) }, - { USB_DEVICE(MTS_VENDOR_ID, MTS_GSM_NO_FW_PRODUCT_ID) }, - { USB_DEVICE(MTS_VENDOR_ID, MTS_CDMA_NO_FW_PRODUCT_ID) }, - { USB_DEVICE(MTS_VENDOR_ID, MTS_CDMA_PRODUCT_ID) }, - { USB_DEVICE(MTS_VENDOR_ID, MTS_GSM_PRODUCT_ID) }, - { USB_DEVICE(MTS_VENDOR_ID, MTS_EDGE_PRODUCT_ID) }, - { USB_DEVICE(MTS_VENDOR_ID, MTS_MT9234MU_PRODUCT_ID) }, - { USB_DEVICE(MTS_VENDOR_ID, MTS_MT9234ZBA_PRODUCT_ID) }, - { USB_DEVICE(MTS_VENDOR_ID, MTS_MT9234ZBAOLD_PRODUCT_ID) }, - { USB_DEVICE(IBM_VENDOR_ID, IBM_4543_PRODUCT_ID) }, - { USB_DEVICE(IBM_VENDOR_ID, IBM_454B_PRODUCT_ID) }, - { USB_DEVICE(IBM_VENDOR_ID, IBM_454C_PRODUCT_ID) }, - { USB_DEVICE(ABBOTT_VENDOR_ID, ABBOTT_PRODUCT_ID) }, - { USB_DEVICE(TI_VENDOR_ID, FRI2_PRODUCT_ID) }, -}; - -static struct usb_device_id ti_id_table_5052[5+TI_EXTRA_VID_PID_COUNT+1] = { - { USB_DEVICE(TI_VENDOR_ID, TI_5052_BOOT_PRODUCT_ID) }, - { USB_DEVICE(TI_VENDOR_ID, TI_5152_BOOT_PRODUCT_ID) }, - { USB_DEVICE(TI_VENDOR_ID, TI_5052_EEPROM_PRODUCT_ID) }, - { USB_DEVICE(TI_VENDOR_ID, TI_5052_FIRMWARE_PRODUCT_ID) }, -}; - -static struct usb_device_id ti_id_table_combined[19+2*TI_EXTRA_VID_PID_COUNT+1] = { - { USB_DEVICE(TI_VENDOR_ID, TI_3410_PRODUCT_ID) }, - { USB_DEVICE(TI_VENDOR_ID, TI_3410_EZ430_ID) }, - { USB_DEVICE(MTS_VENDOR_ID, MTS_GSM_NO_FW_PRODUCT_ID) }, - { USB_DEVICE(MTS_VENDOR_ID, MTS_CDMA_NO_FW_PRODUCT_ID) }, - { USB_DEVICE(MTS_VENDOR_ID, MTS_CDMA_PRODUCT_ID) }, - { USB_DEVICE(MTS_VENDOR_ID, MTS_GSM_PRODUCT_ID) }, - { USB_DEVICE(MTS_VENDOR_ID, MTS_EDGE_PRODUCT_ID) }, - { USB_DEVICE(MTS_VENDOR_ID, MTS_MT9234MU_PRODUCT_ID) }, - { USB_DEVICE(MTS_VENDOR_ID, MTS_MT9234ZBA_PRODUCT_ID) }, - { USB_DEVICE(MTS_VENDOR_ID, MTS_MT9234ZBAOLD_PRODUCT_ID) }, - { USB_DEVICE(TI_VENDOR_ID, TI_5052_BOOT_PRODUCT_ID) }, - { USB_DEVICE(TI_VENDOR_ID, TI_5152_BOOT_PRODUCT_ID) }, - { USB_DEVICE(TI_VENDOR_ID, TI_5052_EEPROM_PRODUCT_ID) }, - { USB_DEVICE(TI_VENDOR_ID, TI_5052_FIRMWARE_PRODUCT_ID) }, - { USB_DEVICE(IBM_VENDOR_ID, IBM_4543_PRODUCT_ID) }, - { USB_DEVICE(IBM_VENDOR_ID, IBM_454B_PRODUCT_ID) }, - { USB_DEVICE(IBM_VENDOR_ID, IBM_454C_PRODUCT_ID) }, - { USB_DEVICE(ABBOTT_VENDOR_ID, ABBOTT_PRODUCT_ID) }, - { USB_DEVICE(TI_VENDOR_ID, FRI2_PRODUCT_ID) }, - { } -}; - -static struct usb_driver ti_usb_driver = { - .name = "ti_usb_3410_5052", - .probe = usb_serial_probe, - .disconnect = usb_serial_disconnect, - .id_table = ti_id_table_combined, -}; - -static struct usb_serial_driver ti_1port_device = { - .driver = { - .owner = THIS_MODULE, - .name = "ti_usb_3410_5052_1", - }, - .description = "TI USB 3410 1 port adapter", - .id_table = ti_id_table_3410, - .num_ports = 1, - .attach = ti_startup, - .release = ti_release, - .open = ti_open, - .close = ti_close, - .write = ti_write, - .write_room = ti_write_room, - .chars_in_buffer = ti_chars_in_buffer, - .throttle = ti_throttle, - .unthrottle = ti_unthrottle, - .ioctl = ti_ioctl, - .set_termios = ti_set_termios, - .tiocmget = ti_tiocmget, - .tiocmset = ti_tiocmset, - .get_icount = ti_get_icount, - .break_ctl = ti_break, - .read_int_callback = ti_interrupt_callback, - .read_bulk_callback = ti_bulk_in_callback, - .write_bulk_callback = ti_bulk_out_callback, -}; - -static struct usb_serial_driver ti_2port_device = { - .driver = { - .owner = THIS_MODULE, - .name = "ti_usb_3410_5052_2", - }, - .description = "TI USB 5052 2 port adapter", - .id_table = ti_id_table_5052, - .num_ports = 2, - .attach = ti_startup, - .release = ti_release, - .open = ti_open, - .close = ti_close, - .write = ti_write, - .write_room = ti_write_room, - .chars_in_buffer = ti_chars_in_buffer, - .throttle = ti_throttle, - .unthrottle = ti_unthrottle, - .ioctl = ti_ioctl, - .set_termios = ti_set_termios, - .tiocmget = ti_tiocmget, - .tiocmset = ti_tiocmset, - .get_icount = ti_get_icount, - .break_ctl = ti_break, - .read_int_callback = ti_interrupt_callback, - .read_bulk_callback = ti_bulk_in_callback, - .write_bulk_callback = ti_bulk_out_callback, -}; - -static struct usb_serial_driver * const serial_drivers[] = { - &ti_1port_device, &ti_2port_device, NULL -}; - -/* Module */ - -MODULE_AUTHOR(TI_DRIVER_AUTHOR); -MODULE_DESCRIPTION(TI_DRIVER_DESC); -MODULE_VERSION(TI_DRIVER_VERSION); -MODULE_LICENSE("GPL"); - -MODULE_FIRMWARE("ti_3410.fw"); -MODULE_FIRMWARE("ti_5052.fw"); -MODULE_FIRMWARE("mts_cdma.fw"); -MODULE_FIRMWARE("mts_gsm.fw"); -MODULE_FIRMWARE("mts_edge.fw"); -MODULE_FIRMWARE("mts_mt9234mu.fw"); -MODULE_FIRMWARE("mts_mt9234zba.fw"); - -module_param(debug, bool, S_IRUGO | S_IWUSR); -MODULE_PARM_DESC(debug, "Enable debugging, 0=no, 1=yes"); - -module_param(closing_wait, int, S_IRUGO | S_IWUSR); -MODULE_PARM_DESC(closing_wait, - "Maximum wait for data to drain in close, in .01 secs, default is 4000"); - -module_param_array(vendor_3410, ushort, &vendor_3410_count, S_IRUGO); -MODULE_PARM_DESC(vendor_3410, - "Vendor ids for 3410 based devices, 1-5 short integers"); -module_param_array(product_3410, ushort, &product_3410_count, S_IRUGO); -MODULE_PARM_DESC(product_3410, - "Product ids for 3410 based devices, 1-5 short integers"); -module_param_array(vendor_5052, ushort, &vendor_5052_count, S_IRUGO); -MODULE_PARM_DESC(vendor_5052, - "Vendor ids for 5052 based devices, 1-5 short integers"); -module_param_array(product_5052, ushort, &product_5052_count, S_IRUGO); -MODULE_PARM_DESC(product_5052, - "Product ids for 5052 based devices, 1-5 short integers"); - -MODULE_DEVICE_TABLE(usb, ti_id_table_combined); - - -/* Functions */ - -static int __init ti_init(void) -{ - int i, j, c; - int ret; - - /* insert extra vendor and product ids */ - c = ARRAY_SIZE(ti_id_table_combined) - 2 * TI_EXTRA_VID_PID_COUNT - 1; - j = ARRAY_SIZE(ti_id_table_3410) - TI_EXTRA_VID_PID_COUNT - 1; - for (i = 0; i < min(vendor_3410_count, product_3410_count); i++, j++, c++) { - ti_id_table_3410[j].idVendor = vendor_3410[i]; - ti_id_table_3410[j].idProduct = product_3410[i]; - ti_id_table_3410[j].match_flags = USB_DEVICE_ID_MATCH_DEVICE; - ti_id_table_combined[c].idVendor = vendor_3410[i]; - ti_id_table_combined[c].idProduct = product_3410[i]; - ti_id_table_combined[c].match_flags = USB_DEVICE_ID_MATCH_DEVICE; - } - j = ARRAY_SIZE(ti_id_table_5052) - TI_EXTRA_VID_PID_COUNT - 1; - for (i = 0; i < min(vendor_5052_count, product_5052_count); i++, j++, c++) { - ti_id_table_5052[j].idVendor = vendor_5052[i]; - ti_id_table_5052[j].idProduct = product_5052[i]; - ti_id_table_5052[j].match_flags = USB_DEVICE_ID_MATCH_DEVICE; - ti_id_table_combined[c].idVendor = vendor_5052[i]; - ti_id_table_combined[c].idProduct = product_5052[i]; - ti_id_table_combined[c].match_flags = USB_DEVICE_ID_MATCH_DEVICE; - } - - ret = usb_serial_register_drivers(&ti_usb_driver, serial_drivers); - if (ret == 0) - printk(KERN_INFO KBUILD_MODNAME ": " TI_DRIVER_VERSION ":" - TI_DRIVER_DESC "\n"); - return ret; -} - - -static void __exit ti_exit(void) -{ - usb_serial_deregister_drivers(&ti_usb_driver, serial_drivers); -} - - -module_init(ti_init); -module_exit(ti_exit); - - -static int ti_startup(struct usb_serial *serial) -{ - struct ti_device *tdev; - struct ti_port *tport; - struct usb_device *dev = serial->dev; - int status; - int i; - - - dbg("%s - product 0x%4X, num configurations %d, configuration value %d", - __func__, le16_to_cpu(dev->descriptor.idProduct), - dev->descriptor.bNumConfigurations, - dev->actconfig->desc.bConfigurationValue); - - /* create device structure */ - tdev = kzalloc(sizeof(struct ti_device), GFP_KERNEL); - if (tdev == NULL) { - dev_err(&dev->dev, "%s - out of memory\n", __func__); - return -ENOMEM; - } - mutex_init(&tdev->td_open_close_lock); - tdev->td_serial = serial; - usb_set_serial_data(serial, tdev); - - /* determine device type */ - if (usb_match_id(serial->interface, ti_id_table_3410)) - tdev->td_is_3410 = 1; - dbg("%s - device type is %s", __func__, - tdev->td_is_3410 ? "3410" : "5052"); - - /* if we have only 1 configuration, download firmware */ - if (dev->descriptor.bNumConfigurations == 1) { - if ((status = ti_download_firmware(tdev)) != 0) - goto free_tdev; - - /* 3410 must be reset, 5052 resets itself */ - if (tdev->td_is_3410) { - msleep_interruptible(100); - usb_reset_device(dev); - } - - status = -ENODEV; - goto free_tdev; - } - - /* the second configuration must be set */ - if (dev->actconfig->desc.bConfigurationValue == TI_BOOT_CONFIG) { - status = usb_driver_set_configuration(dev, TI_ACTIVE_CONFIG); - status = status ? status : -ENODEV; - goto free_tdev; - } - - /* set up port structures */ - for (i = 0; i < serial->num_ports; ++i) { - tport = kzalloc(sizeof(struct ti_port), GFP_KERNEL); - if (tport == NULL) { - dev_err(&dev->dev, "%s - out of memory\n", __func__); - status = -ENOMEM; - goto free_tports; - } - spin_lock_init(&tport->tp_lock); - tport->tp_uart_base_addr = (i == 0 ? - TI_UART1_BASE_ADDR : TI_UART2_BASE_ADDR); - tport->tp_closing_wait = closing_wait; - init_waitqueue_head(&tport->tp_msr_wait); - init_waitqueue_head(&tport->tp_write_wait); - if (kfifo_alloc(&tport->write_fifo, TI_WRITE_BUF_SIZE, - GFP_KERNEL)) { - dev_err(&dev->dev, "%s - out of memory\n", __func__); - kfree(tport); - status = -ENOMEM; - goto free_tports; - } - tport->tp_port = serial->port[i]; - tport->tp_tdev = tdev; - usb_set_serial_port_data(serial->port[i], tport); - tport->tp_uart_mode = 0; /* default is RS232 */ - } - - return 0; - -free_tports: - for (--i; i >= 0; --i) { - tport = usb_get_serial_port_data(serial->port[i]); - kfifo_free(&tport->write_fifo); - kfree(tport); - usb_set_serial_port_data(serial->port[i], NULL); - } -free_tdev: - kfree(tdev); - usb_set_serial_data(serial, NULL); - return status; -} - - -static void ti_release(struct usb_serial *serial) -{ - int i; - struct ti_device *tdev = usb_get_serial_data(serial); - struct ti_port *tport; - - dbg("%s", __func__); - - for (i = 0; i < serial->num_ports; ++i) { - tport = usb_get_serial_port_data(serial->port[i]); - if (tport) { - kfifo_free(&tport->write_fifo); - kfree(tport); - } - } - - kfree(tdev); -} - - -static int ti_open(struct tty_struct *tty, struct usb_serial_port *port) -{ - struct ti_port *tport = usb_get_serial_port_data(port); - struct ti_device *tdev; - struct usb_device *dev; - struct urb *urb; - int port_number; - int status; - __u16 open_settings = (__u8)(TI_PIPE_MODE_CONTINOUS | - TI_PIPE_TIMEOUT_ENABLE | - (TI_TRANSFER_TIMEOUT << 2)); - - dbg("%s - port %d", __func__, port->number); - - if (tport == NULL) - return -ENODEV; - - dev = port->serial->dev; - tdev = tport->tp_tdev; - - /* only one open on any port on a device at a time */ - if (mutex_lock_interruptible(&tdev->td_open_close_lock)) - return -ERESTARTSYS; - - port_number = port->number - port->serial->minor; - - memset(&(tport->tp_icount), 0x00, sizeof(tport->tp_icount)); - - tport->tp_msr = 0; - tport->tp_shadow_mcr |= (TI_MCR_RTS | TI_MCR_DTR); - - /* start interrupt urb the first time a port is opened on this device */ - if (tdev->td_open_port_count == 0) { - dbg("%s - start interrupt in urb", __func__); - urb = tdev->td_serial->port[0]->interrupt_in_urb; - if (!urb) { - dev_err(&port->dev, "%s - no interrupt urb\n", - __func__); - status = -EINVAL; - goto release_lock; - } - urb->context = tdev; - status = usb_submit_urb(urb, GFP_KERNEL); - if (status) { - dev_err(&port->dev, - "%s - submit interrupt urb failed, %d\n", - __func__, status); - goto release_lock; - } - } - - if (tty) - ti_set_termios(tty, port, tty->termios); - - dbg("%s - sending TI_OPEN_PORT", __func__); - status = ti_command_out_sync(tdev, TI_OPEN_PORT, - (__u8)(TI_UART1_PORT + port_number), open_settings, NULL, 0); - if (status) { - dev_err(&port->dev, "%s - cannot send open command, %d\n", - __func__, status); - goto unlink_int_urb; - } - - dbg("%s - sending TI_START_PORT", __func__); - status = ti_command_out_sync(tdev, TI_START_PORT, - (__u8)(TI_UART1_PORT + port_number), 0, NULL, 0); - if (status) { - dev_err(&port->dev, "%s - cannot send start command, %d\n", - __func__, status); - goto unlink_int_urb; - } - - dbg("%s - sending TI_PURGE_PORT", __func__); - status = ti_command_out_sync(tdev, TI_PURGE_PORT, - (__u8)(TI_UART1_PORT + port_number), TI_PURGE_INPUT, NULL, 0); - if (status) { - dev_err(&port->dev, "%s - cannot clear input buffers, %d\n", - __func__, status); - goto unlink_int_urb; - } - status = ti_command_out_sync(tdev, TI_PURGE_PORT, - (__u8)(TI_UART1_PORT + port_number), TI_PURGE_OUTPUT, NULL, 0); - if (status) { - dev_err(&port->dev, "%s - cannot clear output buffers, %d\n", - __func__, status); - goto unlink_int_urb; - } - - /* reset the data toggle on the bulk endpoints to work around bug in - * host controllers where things get out of sync some times */ - usb_clear_halt(dev, port->write_urb->pipe); - usb_clear_halt(dev, port->read_urb->pipe); - - if (tty) - ti_set_termios(tty, port, tty->termios); - - dbg("%s - sending TI_OPEN_PORT (2)", __func__); - status = ti_command_out_sync(tdev, TI_OPEN_PORT, - (__u8)(TI_UART1_PORT + port_number), open_settings, NULL, 0); - if (status) { - dev_err(&port->dev, "%s - cannot send open command (2), %d\n", - __func__, status); - goto unlink_int_urb; - } - - dbg("%s - sending TI_START_PORT (2)", __func__); - status = ti_command_out_sync(tdev, TI_START_PORT, - (__u8)(TI_UART1_PORT + port_number), 0, NULL, 0); - if (status) { - dev_err(&port->dev, "%s - cannot send start command (2), %d\n", - __func__, status); - goto unlink_int_urb; - } - - /* start read urb */ - dbg("%s - start read urb", __func__); - urb = port->read_urb; - if (!urb) { - dev_err(&port->dev, "%s - no read urb\n", __func__); - status = -EINVAL; - goto unlink_int_urb; - } - tport->tp_read_urb_state = TI_READ_URB_RUNNING; - urb->context = tport; - status = usb_submit_urb(urb, GFP_KERNEL); - if (status) { - dev_err(&port->dev, "%s - submit read urb failed, %d\n", - __func__, status); - goto unlink_int_urb; - } - - tport->tp_is_open = 1; - ++tdev->td_open_port_count; - - goto release_lock; - -unlink_int_urb: - if (tdev->td_open_port_count == 0) - usb_kill_urb(port->serial->port[0]->interrupt_in_urb); -release_lock: - mutex_unlock(&tdev->td_open_close_lock); - dbg("%s - exit %d", __func__, status); - return status; -} - - -static void ti_close(struct usb_serial_port *port) -{ - struct ti_device *tdev; - struct ti_port *tport; - int port_number; - int status; - int do_unlock; - - dbg("%s - port %d", __func__, port->number); - - tdev = usb_get_serial_data(port->serial); - tport = usb_get_serial_port_data(port); - if (tdev == NULL || tport == NULL) - return; - - tport->tp_is_open = 0; - - ti_drain(tport, (tport->tp_closing_wait*HZ)/100, 1); - - usb_kill_urb(port->read_urb); - usb_kill_urb(port->write_urb); - tport->tp_write_urb_in_use = 0; - - port_number = port->number - port->serial->minor; - - dbg("%s - sending TI_CLOSE_PORT", __func__); - status = ti_command_out_sync(tdev, TI_CLOSE_PORT, - (__u8)(TI_UART1_PORT + port_number), 0, NULL, 0); - if (status) - dev_err(&port->dev, - "%s - cannot send close port command, %d\n" - , __func__, status); - - /* if mutex_lock is interrupted, continue anyway */ - do_unlock = !mutex_lock_interruptible(&tdev->td_open_close_lock); - --tport->tp_tdev->td_open_port_count; - if (tport->tp_tdev->td_open_port_count <= 0) { - /* last port is closed, shut down interrupt urb */ - usb_kill_urb(port->serial->port[0]->interrupt_in_urb); - tport->tp_tdev->td_open_port_count = 0; - } - if (do_unlock) - mutex_unlock(&tdev->td_open_close_lock); - - dbg("%s - exit", __func__); -} - - -static int ti_write(struct tty_struct *tty, struct usb_serial_port *port, - const unsigned char *data, int count) -{ - struct ti_port *tport = usb_get_serial_port_data(port); - - dbg("%s - port %d", __func__, port->number); - - if (count == 0) { - dbg("%s - write request of 0 bytes", __func__); - return 0; - } - - if (tport == NULL || !tport->tp_is_open) - return -ENODEV; - - count = kfifo_in_locked(&tport->write_fifo, data, count, - &tport->tp_lock); - ti_send(tport); - - return count; -} - - -static int ti_write_room(struct tty_struct *tty) -{ - struct usb_serial_port *port = tty->driver_data; - struct ti_port *tport = usb_get_serial_port_data(port); - int room = 0; - unsigned long flags; - - dbg("%s - port %d", __func__, port->number); - - if (tport == NULL) - return 0; - - spin_lock_irqsave(&tport->tp_lock, flags); - room = kfifo_avail(&tport->write_fifo); - spin_unlock_irqrestore(&tport->tp_lock, flags); - - dbg("%s - returns %d", __func__, room); - return room; -} - - -static int ti_chars_in_buffer(struct tty_struct *tty) -{ - struct usb_serial_port *port = tty->driver_data; - struct ti_port *tport = usb_get_serial_port_data(port); - int chars = 0; - unsigned long flags; - - dbg("%s - port %d", __func__, port->number); - - if (tport == NULL) - return 0; - - spin_lock_irqsave(&tport->tp_lock, flags); - chars = kfifo_len(&tport->write_fifo); - spin_unlock_irqrestore(&tport->tp_lock, flags); - - dbg("%s - returns %d", __func__, chars); - return chars; -} - - -static void ti_throttle(struct tty_struct *tty) -{ - struct usb_serial_port *port = tty->driver_data; - struct ti_port *tport = usb_get_serial_port_data(port); - - dbg("%s - port %d", __func__, port->number); - - if (tport == NULL) - return; - - if (I_IXOFF(tty) || C_CRTSCTS(tty)) - ti_stop_read(tport, tty); - -} - - -static void ti_unthrottle(struct tty_struct *tty) -{ - struct usb_serial_port *port = tty->driver_data; - struct ti_port *tport = usb_get_serial_port_data(port); - int status; - - dbg("%s - port %d", __func__, port->number); - - if (tport == NULL) - return; - - if (I_IXOFF(tty) || C_CRTSCTS(tty)) { - status = ti_restart_read(tport, tty); - if (status) - dev_err(&port->dev, "%s - cannot restart read, %d\n", - __func__, status); - } -} - -static int ti_get_icount(struct tty_struct *tty, - struct serial_icounter_struct *icount) -{ - struct usb_serial_port *port = tty->driver_data; - struct ti_port *tport = usb_get_serial_port_data(port); - struct async_icount cnow = tport->tp_icount; - - dbg("%s - (%d) TIOCGICOUNT RX=%d, TX=%d", - __func__, port->number, - cnow.rx, cnow.tx); - - icount->cts = cnow.cts; - icount->dsr = cnow.dsr; - icount->rng = cnow.rng; - icount->dcd = cnow.dcd; - icount->rx = cnow.rx; - icount->tx = cnow.tx; - icount->frame = cnow.frame; - icount->overrun = cnow.overrun; - icount->parity = cnow.parity; - icount->brk = cnow.brk; - icount->buf_overrun = cnow.buf_overrun; - - return 0; -} - -static int ti_ioctl(struct tty_struct *tty, - unsigned int cmd, unsigned long arg) -{ - struct usb_serial_port *port = tty->driver_data; - struct ti_port *tport = usb_get_serial_port_data(port); - struct async_icount cnow; - struct async_icount cprev; - - dbg("%s - port %d, cmd = 0x%04X", __func__, port->number, cmd); - - if (tport == NULL) - return -ENODEV; - - switch (cmd) { - case TIOCGSERIAL: - dbg("%s - (%d) TIOCGSERIAL", __func__, port->number); - return ti_get_serial_info(tport, - (struct serial_struct __user *)arg); - case TIOCSSERIAL: - dbg("%s - (%d) TIOCSSERIAL", __func__, port->number); - return ti_set_serial_info(tty, tport, - (struct serial_struct __user *)arg); - case TIOCMIWAIT: - dbg("%s - (%d) TIOCMIWAIT", __func__, port->number); - cprev = tport->tp_icount; - while (1) { - interruptible_sleep_on(&tport->tp_msr_wait); - if (signal_pending(current)) - return -ERESTARTSYS; - cnow = tport->tp_icount; - if (cnow.rng == cprev.rng && cnow.dsr == cprev.dsr && - cnow.dcd == cprev.dcd && cnow.cts == cprev.cts) - return -EIO; /* no change => error */ - if (((arg & TIOCM_RNG) && (cnow.rng != cprev.rng)) || - ((arg & TIOCM_DSR) && (cnow.dsr != cprev.dsr)) || - ((arg & TIOCM_CD) && (cnow.dcd != cprev.dcd)) || - ((arg & TIOCM_CTS) && (cnow.cts != cprev.cts))) - return 0; - cprev = cnow; - } - break; - } - return -ENOIOCTLCMD; -} - - -static void ti_set_termios(struct tty_struct *tty, - struct usb_serial_port *port, struct ktermios *old_termios) -{ - struct ti_port *tport = usb_get_serial_port_data(port); - struct ti_uart_config *config; - tcflag_t cflag, iflag; - int baud; - int status; - int port_number = port->number - port->serial->minor; - unsigned int mcr; - - dbg("%s - port %d", __func__, port->number); - - cflag = tty->termios->c_cflag; - iflag = tty->termios->c_iflag; - - dbg("%s - cflag %08x, iflag %08x", __func__, cflag, iflag); - dbg("%s - old clfag %08x, old iflag %08x", __func__, - old_termios->c_cflag, old_termios->c_iflag); - - if (tport == NULL) - return; - - config = kmalloc(sizeof(*config), GFP_KERNEL); - if (!config) { - dev_err(&port->dev, "%s - out of memory\n", __func__); - return; - } - - config->wFlags = 0; - - /* these flags must be set */ - config->wFlags |= TI_UART_ENABLE_MS_INTS; - config->wFlags |= TI_UART_ENABLE_AUTO_START_DMA; - config->bUartMode = (__u8)(tport->tp_uart_mode); - - switch (cflag & CSIZE) { - case CS5: - config->bDataBits = TI_UART_5_DATA_BITS; - break; - case CS6: - config->bDataBits = TI_UART_6_DATA_BITS; - break; - case CS7: - config->bDataBits = TI_UART_7_DATA_BITS; - break; - default: - case CS8: - config->bDataBits = TI_UART_8_DATA_BITS; - break; - } - - /* CMSPAR isn't supported by this driver */ - tty->termios->c_cflag &= ~CMSPAR; - - if (cflag & PARENB) { - if (cflag & PARODD) { - config->wFlags |= TI_UART_ENABLE_PARITY_CHECKING; - config->bParity = TI_UART_ODD_PARITY; - } else { - config->wFlags |= TI_UART_ENABLE_PARITY_CHECKING; - config->bParity = TI_UART_EVEN_PARITY; - } - } else { - config->wFlags &= ~TI_UART_ENABLE_PARITY_CHECKING; - config->bParity = TI_UART_NO_PARITY; - } - - if (cflag & CSTOPB) - config->bStopBits = TI_UART_2_STOP_BITS; - else - config->bStopBits = TI_UART_1_STOP_BITS; - - if (cflag & CRTSCTS) { - /* RTS flow control must be off to drop RTS for baud rate B0 */ - if ((cflag & CBAUD) != B0) - config->wFlags |= TI_UART_ENABLE_RTS_IN; - config->wFlags |= TI_UART_ENABLE_CTS_OUT; - } else { - tty->hw_stopped = 0; - ti_restart_read(tport, tty); - } - - if (I_IXOFF(tty) || I_IXON(tty)) { - config->cXon = START_CHAR(tty); - config->cXoff = STOP_CHAR(tty); - - if (I_IXOFF(tty)) - config->wFlags |= TI_UART_ENABLE_X_IN; - else - ti_restart_read(tport, tty); - - if (I_IXON(tty)) - config->wFlags |= TI_UART_ENABLE_X_OUT; - } - - baud = tty_get_baud_rate(tty); - if (!baud) - baud = 9600; - if (tport->tp_tdev->td_is_3410) - config->wBaudRate = (__u16)((923077 + baud/2) / baud); - else - config->wBaudRate = (__u16)((461538 + baud/2) / baud); - - /* FIXME: Should calculate resulting baud here and report it back */ - if ((cflag & CBAUD) != B0) - tty_encode_baud_rate(tty, baud, baud); - - dbg("%s - BaudRate=%d, wBaudRate=%d, wFlags=0x%04X, bDataBits=%d, bParity=%d, bStopBits=%d, cXon=%d, cXoff=%d, bUartMode=%d", - __func__, baud, config->wBaudRate, config->wFlags, config->bDataBits, config->bParity, config->bStopBits, config->cXon, config->cXoff, config->bUartMode); - - cpu_to_be16s(&config->wBaudRate); - cpu_to_be16s(&config->wFlags); - - status = ti_command_out_sync(tport->tp_tdev, TI_SET_CONFIG, - (__u8)(TI_UART1_PORT + port_number), 0, (__u8 *)config, - sizeof(*config)); - if (status) - dev_err(&port->dev, "%s - cannot set config on port %d, %d\n", - __func__, port_number, status); - - /* SET_CONFIG asserts RTS and DTR, reset them correctly */ - mcr = tport->tp_shadow_mcr; - /* if baud rate is B0, clear RTS and DTR */ - if ((cflag & CBAUD) == B0) - mcr &= ~(TI_MCR_DTR | TI_MCR_RTS); - status = ti_set_mcr(tport, mcr); - if (status) - dev_err(&port->dev, - "%s - cannot set modem control on port %d, %d\n", - __func__, port_number, status); - - kfree(config); -} - - -static int ti_tiocmget(struct tty_struct *tty) -{ - struct usb_serial_port *port = tty->driver_data; - struct ti_port *tport = usb_get_serial_port_data(port); - unsigned int result; - unsigned int msr; - unsigned int mcr; - unsigned long flags; - - dbg("%s - port %d", __func__, port->number); - - if (tport == NULL) - return -ENODEV; - - spin_lock_irqsave(&tport->tp_lock, flags); - msr = tport->tp_msr; - mcr = tport->tp_shadow_mcr; - spin_unlock_irqrestore(&tport->tp_lock, flags); - - result = ((mcr & TI_MCR_DTR) ? TIOCM_DTR : 0) - | ((mcr & TI_MCR_RTS) ? TIOCM_RTS : 0) - | ((mcr & TI_MCR_LOOP) ? TIOCM_LOOP : 0) - | ((msr & TI_MSR_CTS) ? TIOCM_CTS : 0) - | ((msr & TI_MSR_CD) ? TIOCM_CAR : 0) - | ((msr & TI_MSR_RI) ? TIOCM_RI : 0) - | ((msr & TI_MSR_DSR) ? TIOCM_DSR : 0); - - dbg("%s - 0x%04X", __func__, result); - - return result; -} - - -static int ti_tiocmset(struct tty_struct *tty, - unsigned int set, unsigned int clear) -{ - struct usb_serial_port *port = tty->driver_data; - struct ti_port *tport = usb_get_serial_port_data(port); - unsigned int mcr; - unsigned long flags; - - dbg("%s - port %d", __func__, port->number); - - if (tport == NULL) - return -ENODEV; - - spin_lock_irqsave(&tport->tp_lock, flags); - mcr = tport->tp_shadow_mcr; - - if (set & TIOCM_RTS) - mcr |= TI_MCR_RTS; - if (set & TIOCM_DTR) - mcr |= TI_MCR_DTR; - if (set & TIOCM_LOOP) - mcr |= TI_MCR_LOOP; - - if (clear & TIOCM_RTS) - mcr &= ~TI_MCR_RTS; - if (clear & TIOCM_DTR) - mcr &= ~TI_MCR_DTR; - if (clear & TIOCM_LOOP) - mcr &= ~TI_MCR_LOOP; - spin_unlock_irqrestore(&tport->tp_lock, flags); - - return ti_set_mcr(tport, mcr); -} - - -static void ti_break(struct tty_struct *tty, int break_state) -{ - struct usb_serial_port *port = tty->driver_data; - struct ti_port *tport = usb_get_serial_port_data(port); - int status; - - dbg("%s - state = %d", __func__, break_state); - - if (tport == NULL) - return; - - ti_drain(tport, (tport->tp_closing_wait*HZ)/100, 0); - - status = ti_write_byte(tport->tp_tdev, - tport->tp_uart_base_addr + TI_UART_OFFSET_LCR, - TI_LCR_BREAK, break_state == -1 ? TI_LCR_BREAK : 0); - - if (status) - dbg("%s - error setting break, %d", __func__, status); -} - - -static void ti_interrupt_callback(struct urb *urb) -{ - struct ti_device *tdev = urb->context; - struct usb_serial_port *port; - struct usb_serial *serial = tdev->td_serial; - struct ti_port *tport; - struct device *dev = &urb->dev->dev; - unsigned char *data = urb->transfer_buffer; - int length = urb->actual_length; - int port_number; - int function; - int status = urb->status; - int retval; - __u8 msr; - - dbg("%s", __func__); - - switch (status) { - case 0: - break; - case -ECONNRESET: - case -ENOENT: - case -ESHUTDOWN: - dbg("%s - urb shutting down, %d", __func__, status); - tdev->td_urb_error = 1; - return; - default: - dev_err(dev, "%s - nonzero urb status, %d\n", - __func__, status); - tdev->td_urb_error = 1; - goto exit; - } - - if (length != 2) { - dbg("%s - bad packet size, %d", __func__, length); - goto exit; - } - - if (data[0] == TI_CODE_HARDWARE_ERROR) { - dev_err(dev, "%s - hardware error, %d\n", __func__, data[1]); - goto exit; - } - - port_number = TI_GET_PORT_FROM_CODE(data[0]); - function = TI_GET_FUNC_FROM_CODE(data[0]); - - dbg("%s - port_number %d, function %d, data 0x%02X", - __func__, port_number, function, data[1]); - - if (port_number >= serial->num_ports) { - dev_err(dev, "%s - bad port number, %d\n", - __func__, port_number); - goto exit; - } - - port = serial->port[port_number]; - - tport = usb_get_serial_port_data(port); - if (!tport) - goto exit; - - switch (function) { - case TI_CODE_DATA_ERROR: - dev_err(dev, "%s - DATA ERROR, port %d, data 0x%02X\n", - __func__, port_number, data[1]); - break; - - case TI_CODE_MODEM_STATUS: - msr = data[1]; - dbg("%s - port %d, msr 0x%02X", __func__, port_number, msr); - ti_handle_new_msr(tport, msr); - break; - - default: - dev_err(dev, "%s - unknown interrupt code, 0x%02X\n", - __func__, data[1]); - break; - } - -exit: - retval = usb_submit_urb(urb, GFP_ATOMIC); - if (retval) - dev_err(dev, "%s - resubmit interrupt urb failed, %d\n", - __func__, retval); -} - - -static void ti_bulk_in_callback(struct urb *urb) -{ - struct ti_port *tport = urb->context; - struct usb_serial_port *port = tport->tp_port; - struct device *dev = &urb->dev->dev; - int status = urb->status; - int retval = 0; - struct tty_struct *tty; - - dbg("%s", __func__); - - switch (status) { - case 0: - break; - case -ECONNRESET: - case -ENOENT: - case -ESHUTDOWN: - dbg("%s - urb shutting down, %d", __func__, status); - tport->tp_tdev->td_urb_error = 1; - wake_up_interruptible(&tport->tp_write_wait); - return; - default: - dev_err(dev, "%s - nonzero urb status, %d\n", - __func__, status); - tport->tp_tdev->td_urb_error = 1; - wake_up_interruptible(&tport->tp_write_wait); - } - - if (status == -EPIPE) - goto exit; - - if (status) { - dev_err(dev, "%s - stopping read!\n", __func__); - return; - } - - tty = tty_port_tty_get(&port->port); - if (tty) { - if (urb->actual_length) { - usb_serial_debug_data(debug, dev, __func__, - urb->actual_length, urb->transfer_buffer); - - if (!tport->tp_is_open) - dbg("%s - port closed, dropping data", - __func__); - else - ti_recv(&urb->dev->dev, tty, - urb->transfer_buffer, - urb->actual_length); - spin_lock(&tport->tp_lock); - tport->tp_icount.rx += urb->actual_length; - spin_unlock(&tport->tp_lock); - } - tty_kref_put(tty); - } - -exit: - /* continue to read unless stopping */ - spin_lock(&tport->tp_lock); - if (tport->tp_read_urb_state == TI_READ_URB_RUNNING) - retval = usb_submit_urb(urb, GFP_ATOMIC); - else if (tport->tp_read_urb_state == TI_READ_URB_STOPPING) - tport->tp_read_urb_state = TI_READ_URB_STOPPED; - - spin_unlock(&tport->tp_lock); - if (retval) - dev_err(dev, "%s - resubmit read urb failed, %d\n", - __func__, retval); -} - - -static void ti_bulk_out_callback(struct urb *urb) -{ - struct ti_port *tport = urb->context; - struct usb_serial_port *port = tport->tp_port; - int status = urb->status; - - dbg("%s - port %d", __func__, port->number); - - tport->tp_write_urb_in_use = 0; - - switch (status) { - case 0: - break; - case -ECONNRESET: - case -ENOENT: - case -ESHUTDOWN: - dbg("%s - urb shutting down, %d", __func__, status); - tport->tp_tdev->td_urb_error = 1; - wake_up_interruptible(&tport->tp_write_wait); - return; - default: - dev_err_console(port, "%s - nonzero urb status, %d\n", - __func__, status); - tport->tp_tdev->td_urb_error = 1; - wake_up_interruptible(&tport->tp_write_wait); - } - - /* send any buffered data */ - ti_send(tport); -} - - -static void ti_recv(struct device *dev, struct tty_struct *tty, - unsigned char *data, int length) -{ - int cnt; - - do { - cnt = tty_insert_flip_string(tty, data, length); - if (cnt < length) { - dev_err(dev, "%s - dropping data, %d bytes lost\n", - __func__, length - cnt); - if (cnt == 0) - break; - } - tty_flip_buffer_push(tty); - data += cnt; - length -= cnt; - } while (length > 0); - -} - - -static void ti_send(struct ti_port *tport) -{ - int count, result; - struct usb_serial_port *port = tport->tp_port; - struct tty_struct *tty = tty_port_tty_get(&port->port); /* FIXME */ - unsigned long flags; - - - dbg("%s - port %d", __func__, port->number); - - spin_lock_irqsave(&tport->tp_lock, flags); - - if (tport->tp_write_urb_in_use) - goto unlock; - - count = kfifo_out(&tport->write_fifo, - port->write_urb->transfer_buffer, - port->bulk_out_size); - - if (count == 0) - goto unlock; - - tport->tp_write_urb_in_use = 1; - - spin_unlock_irqrestore(&tport->tp_lock, flags); - - usb_serial_debug_data(debug, &port->dev, __func__, count, - port->write_urb->transfer_buffer); - - usb_fill_bulk_urb(port->write_urb, port->serial->dev, - usb_sndbulkpipe(port->serial->dev, - port->bulk_out_endpointAddress), - port->write_urb->transfer_buffer, count, - ti_bulk_out_callback, tport); - - result = usb_submit_urb(port->write_urb, GFP_ATOMIC); - if (result) { - dev_err_console(port, "%s - submit write urb failed, %d\n", - __func__, result); - tport->tp_write_urb_in_use = 0; - /* TODO: reschedule ti_send */ - } else { - spin_lock_irqsave(&tport->tp_lock, flags); - tport->tp_icount.tx += count; - spin_unlock_irqrestore(&tport->tp_lock, flags); - } - - /* more room in the buffer for new writes, wakeup */ - if (tty) - tty_wakeup(tty); - tty_kref_put(tty); - wake_up_interruptible(&tport->tp_write_wait); - return; -unlock: - spin_unlock_irqrestore(&tport->tp_lock, flags); - tty_kref_put(tty); - return; -} - - -static int ti_set_mcr(struct ti_port *tport, unsigned int mcr) -{ - unsigned long flags; - int status; - - status = ti_write_byte(tport->tp_tdev, - tport->tp_uart_base_addr + TI_UART_OFFSET_MCR, - TI_MCR_RTS | TI_MCR_DTR | TI_MCR_LOOP, mcr); - - spin_lock_irqsave(&tport->tp_lock, flags); - if (!status) - tport->tp_shadow_mcr = mcr; - spin_unlock_irqrestore(&tport->tp_lock, flags); - - return status; -} - - -static int ti_get_lsr(struct ti_port *tport) -{ - int size, status; - struct ti_device *tdev = tport->tp_tdev; - struct usb_serial_port *port = tport->tp_port; - int port_number = port->number - port->serial->minor; - struct ti_port_status *data; - - dbg("%s - port %d", __func__, port->number); - - size = sizeof(struct ti_port_status); - data = kmalloc(size, GFP_KERNEL); - if (!data) { - dev_err(&port->dev, "%s - out of memory\n", __func__); - return -ENOMEM; - } - - status = ti_command_in_sync(tdev, TI_GET_PORT_STATUS, - (__u8)(TI_UART1_PORT+port_number), 0, (__u8 *)data, size); - if (status) { - dev_err(&port->dev, - "%s - get port status command failed, %d\n", - __func__, status); - goto free_data; - } - - dbg("%s - lsr 0x%02X", __func__, data->bLSR); - - tport->tp_lsr = data->bLSR; - -free_data: - kfree(data); - return status; -} - - -static int ti_get_serial_info(struct ti_port *tport, - struct serial_struct __user *ret_arg) -{ - struct usb_serial_port *port = tport->tp_port; - struct serial_struct ret_serial; - - if (!ret_arg) - return -EFAULT; - - memset(&ret_serial, 0, sizeof(ret_serial)); - - ret_serial.type = PORT_16550A; - ret_serial.line = port->serial->minor; - ret_serial.port = port->number - port->serial->minor; - ret_serial.flags = tport->tp_flags; - ret_serial.xmit_fifo_size = TI_WRITE_BUF_SIZE; - ret_serial.baud_base = tport->tp_tdev->td_is_3410 ? 921600 : 460800; - ret_serial.closing_wait = tport->tp_closing_wait; - - if (copy_to_user(ret_arg, &ret_serial, sizeof(*ret_arg))) - return -EFAULT; - - return 0; -} - - -static int ti_set_serial_info(struct tty_struct *tty, struct ti_port *tport, - struct serial_struct __user *new_arg) -{ - struct serial_struct new_serial; - - if (copy_from_user(&new_serial, new_arg, sizeof(new_serial))) - return -EFAULT; - - tport->tp_flags = new_serial.flags & TI_SET_SERIAL_FLAGS; - tport->tp_closing_wait = new_serial.closing_wait; - - return 0; -} - - -static void ti_handle_new_msr(struct ti_port *tport, __u8 msr) -{ - struct async_icount *icount; - struct tty_struct *tty; - unsigned long flags; - - dbg("%s - msr 0x%02X", __func__, msr); - - if (msr & TI_MSR_DELTA_MASK) { - spin_lock_irqsave(&tport->tp_lock, flags); - icount = &tport->tp_icount; - if (msr & TI_MSR_DELTA_CTS) - icount->cts++; - if (msr & TI_MSR_DELTA_DSR) - icount->dsr++; - if (msr & TI_MSR_DELTA_CD) - icount->dcd++; - if (msr & TI_MSR_DELTA_RI) - icount->rng++; - wake_up_interruptible(&tport->tp_msr_wait); - spin_unlock_irqrestore(&tport->tp_lock, flags); - } - - tport->tp_msr = msr & TI_MSR_MASK; - - /* handle CTS flow control */ - tty = tty_port_tty_get(&tport->tp_port->port); - if (tty && C_CRTSCTS(tty)) { - if (msr & TI_MSR_CTS) { - tty->hw_stopped = 0; - tty_wakeup(tty); - } else { - tty->hw_stopped = 1; - } - } - tty_kref_put(tty); -} - - -static void ti_drain(struct ti_port *tport, unsigned long timeout, int flush) -{ - struct ti_device *tdev = tport->tp_tdev; - struct usb_serial_port *port = tport->tp_port; - wait_queue_t wait; - - dbg("%s - port %d", __func__, port->number); - - spin_lock_irq(&tport->tp_lock); - - /* wait for data to drain from the buffer */ - tdev->td_urb_error = 0; - init_waitqueue_entry(&wait, current); - add_wait_queue(&tport->tp_write_wait, &wait); - for (;;) { - set_current_state(TASK_INTERRUPTIBLE); - if (kfifo_len(&tport->write_fifo) == 0 - || timeout == 0 || signal_pending(current) - || tdev->td_urb_error - || port->serial->disconnected) /* disconnect */ - break; - spin_unlock_irq(&tport->tp_lock); - timeout = schedule_timeout(timeout); - spin_lock_irq(&tport->tp_lock); - } - set_current_state(TASK_RUNNING); - remove_wait_queue(&tport->tp_write_wait, &wait); - - /* flush any remaining data in the buffer */ - if (flush) - kfifo_reset_out(&tport->write_fifo); - - spin_unlock_irq(&tport->tp_lock); - - mutex_lock(&port->serial->disc_mutex); - /* wait for data to drain from the device */ - /* wait for empty tx register, plus 20 ms */ - timeout += jiffies; - tport->tp_lsr &= ~TI_LSR_TX_EMPTY; - while ((long)(jiffies - timeout) < 0 && !signal_pending(current) - && !(tport->tp_lsr&TI_LSR_TX_EMPTY) && !tdev->td_urb_error - && !port->serial->disconnected) { - if (ti_get_lsr(tport)) - break; - mutex_unlock(&port->serial->disc_mutex); - msleep_interruptible(20); - mutex_lock(&port->serial->disc_mutex); - } - mutex_unlock(&port->serial->disc_mutex); -} - - -static void ti_stop_read(struct ti_port *tport, struct tty_struct *tty) -{ - unsigned long flags; - - spin_lock_irqsave(&tport->tp_lock, flags); - - if (tport->tp_read_urb_state == TI_READ_URB_RUNNING) - tport->tp_read_urb_state = TI_READ_URB_STOPPING; - - spin_unlock_irqrestore(&tport->tp_lock, flags); -} - - -static int ti_restart_read(struct ti_port *tport, struct tty_struct *tty) -{ - struct urb *urb; - int status = 0; - unsigned long flags; - - spin_lock_irqsave(&tport->tp_lock, flags); - - if (tport->tp_read_urb_state == TI_READ_URB_STOPPED) { - tport->tp_read_urb_state = TI_READ_URB_RUNNING; - urb = tport->tp_port->read_urb; - spin_unlock_irqrestore(&tport->tp_lock, flags); - urb->context = tport; - status = usb_submit_urb(urb, GFP_KERNEL); - } else { - tport->tp_read_urb_state = TI_READ_URB_RUNNING; - spin_unlock_irqrestore(&tport->tp_lock, flags); - } - - return status; -} - - -static int ti_command_out_sync(struct ti_device *tdev, __u8 command, - __u16 moduleid, __u16 value, __u8 *data, int size) -{ - int status; - - status = usb_control_msg(tdev->td_serial->dev, - usb_sndctrlpipe(tdev->td_serial->dev, 0), command, - (USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_OUT), - value, moduleid, data, size, 1000); - - if (status == size) - status = 0; - - if (status > 0) - status = -ECOMM; - - return status; -} - - -static int ti_command_in_sync(struct ti_device *tdev, __u8 command, - __u16 moduleid, __u16 value, __u8 *data, int size) -{ - int status; - - status = usb_control_msg(tdev->td_serial->dev, - usb_rcvctrlpipe(tdev->td_serial->dev, 0), command, - (USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN), - value, moduleid, data, size, 1000); - - if (status == size) - status = 0; - - if (status > 0) - status = -ECOMM; - - return status; -} - - -static int ti_write_byte(struct ti_device *tdev, unsigned long addr, - __u8 mask, __u8 byte) -{ - int status; - unsigned int size; - struct ti_write_data_bytes *data; - struct device *dev = &tdev->td_serial->dev->dev; - - dbg("%s - addr 0x%08lX, mask 0x%02X, byte 0x%02X", - __func__, addr, mask, byte); - - size = sizeof(struct ti_write_data_bytes) + 2; - data = kmalloc(size, GFP_KERNEL); - if (!data) { - dev_err(dev, "%s - out of memory\n", __func__); - return -ENOMEM; - } - - data->bAddrType = TI_RW_DATA_ADDR_XDATA; - data->bDataType = TI_RW_DATA_BYTE; - data->bDataCounter = 1; - data->wBaseAddrHi = cpu_to_be16(addr>>16); - data->wBaseAddrLo = cpu_to_be16(addr); - data->bData[0] = mask; - data->bData[1] = byte; - - status = ti_command_out_sync(tdev, TI_WRITE_DATA, TI_RAM_PORT, 0, - (__u8 *)data, size); - - if (status < 0) - dev_err(dev, "%s - failed, %d\n", __func__, status); - - kfree(data); - - return status; -} - -static int ti_do_download(struct usb_device *dev, int pipe, - u8 *buffer, int size) -{ - int pos; - u8 cs = 0; - int done; - struct ti_firmware_header *header; - int status = 0; - int len; - - for (pos = sizeof(struct ti_firmware_header); pos < size; pos++) - cs = (__u8)(cs + buffer[pos]); - - header = (struct ti_firmware_header *)buffer; - header->wLength = cpu_to_le16((__u16)(size - - sizeof(struct ti_firmware_header))); - header->bCheckSum = cs; - - dbg("%s - downloading firmware", __func__); - for (pos = 0; pos < size; pos += done) { - len = min(size - pos, TI_DOWNLOAD_MAX_PACKET_SIZE); - status = usb_bulk_msg(dev, pipe, buffer + pos, len, - &done, 1000); - if (status) - break; - } - return status; -} - -static int ti_download_firmware(struct ti_device *tdev) -{ - int status; - int buffer_size; - __u8 *buffer; - struct usb_device *dev = tdev->td_serial->dev; - unsigned int pipe = usb_sndbulkpipe(dev, - tdev->td_serial->port[0]->bulk_out_endpointAddress); - const struct firmware *fw_p; - char buf[32]; - - dbg("%s\n", __func__); - /* try ID specific firmware first, then try generic firmware */ - sprintf(buf, "ti_usb-v%04x-p%04x.fw", dev->descriptor.idVendor, - dev->descriptor.idProduct); - if ((status = request_firmware(&fw_p, buf, &dev->dev)) != 0) { - buf[0] = '\0'; - if (dev->descriptor.idVendor == MTS_VENDOR_ID) { - switch (dev->descriptor.idProduct) { - case MTS_CDMA_PRODUCT_ID: - strcpy(buf, "mts_cdma.fw"); - break; - case MTS_GSM_PRODUCT_ID: - strcpy(buf, "mts_gsm.fw"); - break; - case MTS_EDGE_PRODUCT_ID: - strcpy(buf, "mts_edge.fw"); - break; - case MTS_MT9234MU_PRODUCT_ID: - strcpy(buf, "mts_mt9234mu.fw"); - break; - case MTS_MT9234ZBA_PRODUCT_ID: - strcpy(buf, "mts_mt9234zba.fw"); - break; - case MTS_MT9234ZBAOLD_PRODUCT_ID: - strcpy(buf, "mts_mt9234zba.fw"); - break; } - } - if (buf[0] == '\0') { - if (tdev->td_is_3410) - strcpy(buf, "ti_3410.fw"); - else - strcpy(buf, "ti_5052.fw"); - } - status = request_firmware(&fw_p, buf, &dev->dev); - } - if (status) { - dev_err(&dev->dev, "%s - firmware not found\n", __func__); - return -ENOENT; - } - if (fw_p->size > TI_FIRMWARE_BUF_SIZE) { - dev_err(&dev->dev, "%s - firmware too large %zu\n", __func__, fw_p->size); - release_firmware(fw_p); - return -ENOENT; - } - - buffer_size = TI_FIRMWARE_BUF_SIZE + sizeof(struct ti_firmware_header); - buffer = kmalloc(buffer_size, GFP_KERNEL); - if (buffer) { - memcpy(buffer, fw_p->data, fw_p->size); - memset(buffer + fw_p->size, 0xff, buffer_size - fw_p->size); - status = ti_do_download(dev, pipe, buffer, fw_p->size); - kfree(buffer); - } else { - dbg("%s ENOMEM\n", __func__); - status = -ENOMEM; - } - release_firmware(fw_p); - if (status) { - dev_err(&dev->dev, "%s - error downloading firmware, %d\n", - __func__, status); - return status; - } - - dbg("%s - download successful", __func__); - - return 0; -} diff --git a/ANDROID_3.4.5/drivers/usb/serial/ti_usb_3410_5052.h b/ANDROID_3.4.5/drivers/usb/serial/ti_usb_3410_5052.h deleted file mode 100644 index b353e7e3..00000000 --- a/ANDROID_3.4.5/drivers/usb/serial/ti_usb_3410_5052.h +++ /dev/null @@ -1,245 +0,0 @@ -/* vi: ts=8 sw=8 - * - * TI 3410/5052 USB Serial Driver Header - * - * Copyright (C) 2004 Texas Instruments - * - * This driver is based on the Linux io_ti driver, which is - * Copyright (C) 2000-2002 Inside Out Networks - * Copyright (C) 2001-2002 Greg Kroah-Hartman - * - * 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. - * - * For questions or problems with this driver, contact Texas Instruments - * technical support, or Al Borchers <alborchers@steinerpoint.com>, or - * Peter Berger <pberger@brimson.com>. - */ - -#ifndef _TI_3410_5052_H_ -#define _TI_3410_5052_H_ - -/* Configuration ids */ -#define TI_BOOT_CONFIG 1 -#define TI_ACTIVE_CONFIG 2 - -/* Vendor and product ids */ -#define TI_VENDOR_ID 0x0451 -#define IBM_VENDOR_ID 0x04b3 -#define TI_3410_PRODUCT_ID 0x3410 -#define IBM_4543_PRODUCT_ID 0x4543 -#define IBM_454B_PRODUCT_ID 0x454b -#define IBM_454C_PRODUCT_ID 0x454c -#define TI_3410_EZ430_ID 0xF430 /* TI ez430 development tool */ -#define TI_5052_BOOT_PRODUCT_ID 0x5052 /* no EEPROM, no firmware */ -#define TI_5152_BOOT_PRODUCT_ID 0x5152 /* no EEPROM, no firmware */ -#define TI_5052_EEPROM_PRODUCT_ID 0x505A /* EEPROM, no firmware */ -#define TI_5052_FIRMWARE_PRODUCT_ID 0x505F /* firmware is running */ -#define FRI2_PRODUCT_ID 0x5053 /* Fish River Island II */ - -/* Multi-Tech vendor and product ids */ -#define MTS_VENDOR_ID 0x06E0 -#define MTS_GSM_NO_FW_PRODUCT_ID 0xF108 -#define MTS_CDMA_NO_FW_PRODUCT_ID 0xF109 -#define MTS_CDMA_PRODUCT_ID 0xF110 -#define MTS_GSM_PRODUCT_ID 0xF111 -#define MTS_EDGE_PRODUCT_ID 0xF112 -#define MTS_MT9234MU_PRODUCT_ID 0xF114 -#define MTS_MT9234ZBA_PRODUCT_ID 0xF115 -#define MTS_MT9234ZBAOLD_PRODUCT_ID 0x0319 - -/* Abbott Diabetics vendor and product ids */ -#define ABBOTT_VENDOR_ID 0x1a61 -#define ABBOTT_PRODUCT_ID 0x3410 - -/* Commands */ -#define TI_GET_VERSION 0x01 -#define TI_GET_PORT_STATUS 0x02 -#define TI_GET_PORT_DEV_INFO 0x03 -#define TI_GET_CONFIG 0x04 -#define TI_SET_CONFIG 0x05 -#define TI_OPEN_PORT 0x06 -#define TI_CLOSE_PORT 0x07 -#define TI_START_PORT 0x08 -#define TI_STOP_PORT 0x09 -#define TI_TEST_PORT 0x0A -#define TI_PURGE_PORT 0x0B -#define TI_RESET_EXT_DEVICE 0x0C -#define TI_WRITE_DATA 0x80 -#define TI_READ_DATA 0x81 -#define TI_REQ_TYPE_CLASS 0x82 - -/* Module identifiers */ -#define TI_I2C_PORT 0x01 -#define TI_IEEE1284_PORT 0x02 -#define TI_UART1_PORT 0x03 -#define TI_UART2_PORT 0x04 -#define TI_RAM_PORT 0x05 - -/* Modem status */ -#define TI_MSR_DELTA_CTS 0x01 -#define TI_MSR_DELTA_DSR 0x02 -#define TI_MSR_DELTA_RI 0x04 -#define TI_MSR_DELTA_CD 0x08 -#define TI_MSR_CTS 0x10 -#define TI_MSR_DSR 0x20 -#define TI_MSR_RI 0x40 -#define TI_MSR_CD 0x80 -#define TI_MSR_DELTA_MASK 0x0F -#define TI_MSR_MASK 0xF0 - -/* Line status */ -#define TI_LSR_OVERRUN_ERROR 0x01 -#define TI_LSR_PARITY_ERROR 0x02 -#define TI_LSR_FRAMING_ERROR 0x04 -#define TI_LSR_BREAK 0x08 -#define TI_LSR_ERROR 0x0F -#define TI_LSR_RX_FULL 0x10 -#define TI_LSR_TX_EMPTY 0x20 - -/* Line control */ -#define TI_LCR_BREAK 0x40 - -/* Modem control */ -#define TI_MCR_LOOP 0x04 -#define TI_MCR_DTR 0x10 -#define TI_MCR_RTS 0x20 - -/* Mask settings */ -#define TI_UART_ENABLE_RTS_IN 0x0001 -#define TI_UART_DISABLE_RTS 0x0002 -#define TI_UART_ENABLE_PARITY_CHECKING 0x0008 -#define TI_UART_ENABLE_DSR_OUT 0x0010 -#define TI_UART_ENABLE_CTS_OUT 0x0020 -#define TI_UART_ENABLE_X_OUT 0x0040 -#define TI_UART_ENABLE_XA_OUT 0x0080 -#define TI_UART_ENABLE_X_IN 0x0100 -#define TI_UART_ENABLE_DTR_IN 0x0800 -#define TI_UART_DISABLE_DTR 0x1000 -#define TI_UART_ENABLE_MS_INTS 0x2000 -#define TI_UART_ENABLE_AUTO_START_DMA 0x4000 - -/* Parity */ -#define TI_UART_NO_PARITY 0x00 -#define TI_UART_ODD_PARITY 0x01 -#define TI_UART_EVEN_PARITY 0x02 -#define TI_UART_MARK_PARITY 0x03 -#define TI_UART_SPACE_PARITY 0x04 - -/* Stop bits */ -#define TI_UART_1_STOP_BITS 0x00 -#define TI_UART_1_5_STOP_BITS 0x01 -#define TI_UART_2_STOP_BITS 0x02 - -/* Bits per character */ -#define TI_UART_5_DATA_BITS 0x00 -#define TI_UART_6_DATA_BITS 0x01 -#define TI_UART_7_DATA_BITS 0x02 -#define TI_UART_8_DATA_BITS 0x03 - -/* 232/485 modes */ -#define TI_UART_232 0x00 -#define TI_UART_485_RECEIVER_DISABLED 0x01 -#define TI_UART_485_RECEIVER_ENABLED 0x02 - -/* Pipe transfer mode and timeout */ -#define TI_PIPE_MODE_CONTINOUS 0x01 -#define TI_PIPE_MODE_MASK 0x03 -#define TI_PIPE_TIMEOUT_MASK 0x7C -#define TI_PIPE_TIMEOUT_ENABLE 0x80 - -/* Config struct */ -struct ti_uart_config { - __u16 wBaudRate; - __u16 wFlags; - __u8 bDataBits; - __u8 bParity; - __u8 bStopBits; - char cXon; - char cXoff; - __u8 bUartMode; -} __attribute__((packed)); - -/* Get port status */ -struct ti_port_status { - __u8 bCmdCode; - __u8 bModuleId; - __u8 bErrorCode; - __u8 bMSR; - __u8 bLSR; -} __attribute__((packed)); - -/* Purge modes */ -#define TI_PURGE_OUTPUT 0x00 -#define TI_PURGE_INPUT 0x80 - -/* Read/Write data */ -#define TI_RW_DATA_ADDR_SFR 0x10 -#define TI_RW_DATA_ADDR_IDATA 0x20 -#define TI_RW_DATA_ADDR_XDATA 0x30 -#define TI_RW_DATA_ADDR_CODE 0x40 -#define TI_RW_DATA_ADDR_GPIO 0x50 -#define TI_RW_DATA_ADDR_I2C 0x60 -#define TI_RW_DATA_ADDR_FLASH 0x70 -#define TI_RW_DATA_ADDR_DSP 0x80 - -#define TI_RW_DATA_UNSPECIFIED 0x00 -#define TI_RW_DATA_BYTE 0x01 -#define TI_RW_DATA_WORD 0x02 -#define TI_RW_DATA_DOUBLE_WORD 0x04 - -struct ti_write_data_bytes { - __u8 bAddrType; - __u8 bDataType; - __u8 bDataCounter; - __be16 wBaseAddrHi; - __be16 wBaseAddrLo; - __u8 bData[0]; -} __attribute__((packed)); - -struct ti_read_data_request { - __u8 bAddrType; - __u8 bDataType; - __u8 bDataCounter; - __be16 wBaseAddrHi; - __be16 wBaseAddrLo; -} __attribute__((packed)); - -struct ti_read_data_bytes { - __u8 bCmdCode; - __u8 bModuleId; - __u8 bErrorCode; - __u8 bData[0]; -} __attribute__((packed)); - -/* Interrupt struct */ -struct ti_interrupt { - __u8 bICode; - __u8 bIInfo; -} __attribute__((packed)); - -/* Interrupt codes */ -#define TI_GET_PORT_FROM_CODE(c) (((c) >> 4) - 3) -#define TI_GET_FUNC_FROM_CODE(c) ((c) & 0x0f) -#define TI_CODE_HARDWARE_ERROR 0xFF -#define TI_CODE_DATA_ERROR 0x03 -#define TI_CODE_MODEM_STATUS 0x04 - -/* Download firmware max packet size */ -#define TI_DOWNLOAD_MAX_PACKET_SIZE 64 - -/* Firmware image header */ -struct ti_firmware_header { - __le16 wLength; - __u8 bCheckSum; -} __attribute__((packed)); - -/* UART addresses */ -#define TI_UART1_BASE_ADDR 0xFFA0 /* UART 1 base address */ -#define TI_UART2_BASE_ADDR 0xFFB0 /* UART 2 base address */ -#define TI_UART_OFFSET_LCR 0x0002 /* UART MCR register offset */ -#define TI_UART_OFFSET_MCR 0x0004 /* UART MCR register offset */ - -#endif /* _TI_3410_5052_H_ */ diff --git a/ANDROID_3.4.5/drivers/usb/serial/usb-serial.c b/ANDROID_3.4.5/drivers/usb/serial/usb-serial.c deleted file mode 100644 index 03c117c9..00000000 --- a/ANDROID_3.4.5/drivers/usb/serial/usb-serial.c +++ /dev/null @@ -1,1455 +0,0 @@ -/* - * USB Serial Converter driver - * - * Copyright (C) 1999 - 2005 Greg Kroah-Hartman (greg@kroah.com) - * Copyright (C) 2000 Peter Berger (pberger@brimson.com) - * Copyright (C) 2000 Al Borchers (borchers@steinerpoint.com) - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License version - * 2 as published by the Free Software Foundation. - * - * This driver was originally based on the ACM driver by Armin Fuerst (which was - * based on a driver by Brad Keryan) - * - * See Documentation/usb/usb-serial.txt for more information on using this - * driver - * - */ - -#include <linux/kernel.h> -#include <linux/errno.h> -#include <linux/init.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/moduleparam.h> -#include <linux/seq_file.h> -#include <linux/spinlock.h> -#include <linux/mutex.h> -#include <linux/list.h> -#include <linux/uaccess.h> -#include <linux/serial.h> -#include <linux/usb.h> -#include <linux/usb/serial.h> -#include <linux/kfifo.h> -#include "pl2303.h" - -/* - * Version Information - */ -#define DRIVER_AUTHOR "Greg Kroah-Hartman, greg@kroah.com, http://www.kroah.com/linux/" -#define DRIVER_DESC "USB Serial Driver core" - -/* Driver structure we register with the USB core */ -static struct usb_driver usb_serial_driver = { - .name = "usbserial", - .probe = usb_serial_probe, - .disconnect = usb_serial_disconnect, - .suspend = usb_serial_suspend, - .resume = usb_serial_resume, - .no_dynamic_id = 1, - .supports_autosuspend = 1, -}; - -/* There is no MODULE_DEVICE_TABLE for usbserial.c. Instead - the MODULE_DEVICE_TABLE declarations in each serial driver - cause the "hotplug" program to pull in whatever module is necessary - via modprobe, and modprobe will load usbserial because the serial - drivers depend on it. -*/ - -static bool debug; -/* initially all NULL */ -static struct usb_serial *serial_table[SERIAL_TTY_MINORS]; -static DEFINE_MUTEX(table_lock); -static LIST_HEAD(usb_serial_driver_list); - -/* - * Look up the serial structure. If it is found and it hasn't been - * disconnected, return with its disc_mutex held and its refcount - * incremented. Otherwise return NULL. - */ -struct usb_serial *usb_serial_get_by_index(unsigned index) -{ - struct usb_serial *serial; - - mutex_lock(&table_lock); - serial = serial_table[index]; - - if (serial) { - mutex_lock(&serial->disc_mutex); - if (serial->disconnected) { - mutex_unlock(&serial->disc_mutex); - serial = NULL; - } else { - kref_get(&serial->kref); - } - } - mutex_unlock(&table_lock); - return serial; -} - -static struct usb_serial *get_free_serial(struct usb_serial *serial, - int num_ports, unsigned int *minor,int startIndex) -{ - unsigned int i, j; - int good_spot; - - dbg("%s %d", __func__, num_ports); - *minor = startIndex; - - mutex_lock(&table_lock); - for (i = startIndex; i < SERIAL_TTY_MINORS; ++i) { - if (serial_table[i]) - continue; - - good_spot = 1; - for (j = 1; j <= num_ports-1; ++j) - if ((i+j >= SERIAL_TTY_MINORS) || (serial_table[i+j])) { - good_spot = 0; - i += j; - break; - } - if (good_spot == 0) - continue; - - *minor = i; - j = 0; - dbg("%s - minor base = %d", __func__, *minor); - for (i = *minor; (i < (*minor + num_ports)) && (i < SERIAL_TTY_MINORS); ++i) { - serial_table[i] = serial; - serial->port[j++]->number = i; - } - mutex_unlock(&table_lock); - return serial; - } - mutex_unlock(&table_lock); - return NULL; -} - -static void return_serial(struct usb_serial *serial) -{ - int i; - - dbg("%s", __func__); - - mutex_lock(&table_lock); - for (i = 0; i < serial->num_ports; ++i) - serial_table[serial->minor + i] = NULL; - mutex_unlock(&table_lock); -} - -static void destroy_serial(struct kref *kref) -{ - struct usb_serial *serial; - struct usb_serial_port *port; - int i; - - serial = to_usb_serial(kref); - - dbg("%s - %s", __func__, serial->type->description); - - /* return the minor range that this device had */ - if (serial->minor != SERIAL_TTY_NO_MINOR) - return_serial(serial); - - if (serial->attached) - serial->type->release(serial); - - /* Now that nothing is using the ports, they can be freed */ - for (i = 0; i < serial->num_port_pointers; ++i) { - port = serial->port[i]; - if (port) { - port->serial = NULL; - put_device(&port->dev); - } - } - - usb_put_dev(serial->dev); - kfree(serial); -} - -void usb_serial_put(struct usb_serial *serial) -{ - kref_put(&serial->kref, destroy_serial); -} - -/***************************************************************************** - * Driver tty interface functions - *****************************************************************************/ - -/** - * serial_install - install tty - * @driver: the driver (USB in our case) - * @tty: the tty being created - * - * Create the termios objects for this tty. We use the default - * USB serial settings but permit them to be overridden by - * serial->type->init_termios. - * - * This is the first place a new tty gets used. Hence this is where we - * acquire references to the usb_serial structure and the driver module, - * where we store a pointer to the port, and where we do an autoresume. - * All these actions are reversed in serial_cleanup(). - */ -static int serial_install(struct tty_driver *driver, struct tty_struct *tty) -{ - int idx = tty->index; - struct usb_serial *serial; - struct usb_serial_port *port; - int retval = -ENODEV; - - dbg("%s", __func__); - - serial = usb_serial_get_by_index(idx); - if (!serial) - return retval; - - port = serial->port[idx - serial->minor]; - if (!port) - goto error_no_port; - if (!try_module_get(serial->type->driver.owner)) - goto error_module_get; - - retval = usb_autopm_get_interface(serial->interface); - if (retval) - goto error_get_interface; - - retval = tty_standard_install(driver, tty); - if (retval) - goto error_init_termios; - - mutex_unlock(&serial->disc_mutex); - - /* allow the driver to update the settings */ - if (serial->type->init_termios) - serial->type->init_termios(tty); - - tty->driver_data = port; - - return retval; - - error_init_termios: - usb_autopm_put_interface(serial->interface); - error_get_interface: - module_put(serial->type->driver.owner); - error_module_get: - error_no_port: - usb_serial_put(serial); - mutex_unlock(&serial->disc_mutex); - return retval; -} - -static int serial_activate(struct tty_port *tport, struct tty_struct *tty) -{ - struct usb_serial_port *port = - container_of(tport, struct usb_serial_port, port); - struct usb_serial *serial = port->serial; - int retval; - - mutex_lock(&serial->disc_mutex); - if (serial->disconnected) - retval = -ENODEV; - else - retval = port->serial->type->open(tty, port); - mutex_unlock(&serial->disc_mutex); - - if (retval < 0) - retval = usb_translate_errors(retval); - - return retval; -} - -static int serial_open(struct tty_struct *tty, struct file *filp) -{ - struct usb_serial_port *port = tty->driver_data; - - dbg("%s - port %d", __func__, port->number); - return tty_port_open(&port->port, tty, filp); -} - -/** - * serial_down - shut down hardware - * @tport: tty port to shut down - * - * Shut down a USB serial port unless it is the console. We never - * shut down the console hardware as it will always be in use. Serialized - * against activate by the tport mutex and kept to matching open/close pairs - * of calls by the ASYNCB_INITIALIZED flag. - */ -static void serial_down(struct tty_port *tport) -{ - struct usb_serial_port *port = - container_of(tport, struct usb_serial_port, port); - struct usb_serial_driver *drv = port->serial->type; - /* - * The console is magical. Do not hang up the console hardware - * or there will be tears. - */ - if (port->port.console) - return; - if (drv->close) - drv->close(port); -} - -static void serial_hangup(struct tty_struct *tty) -{ - struct usb_serial_port *port = tty->driver_data; - dbg("%s - port %d", __func__, port->number); - tty_port_hangup(&port->port); -} - -static void serial_close(struct tty_struct *tty, struct file *filp) -{ - struct usb_serial_port *port = tty->driver_data; - dbg("%s - port %d", __func__, port->number); - tty_port_close(&port->port, tty, filp); -} - -/** - * serial_cleanup - free resources post close/hangup - * @port: port to free up - * - * Do the resource freeing and refcount dropping for the port. - * Avoid freeing the console. - * - * Called asynchronously after the last tty kref is dropped, - * and the tty layer has already done the tty_shutdown(tty); - */ -static void serial_cleanup(struct tty_struct *tty) -{ - struct usb_serial_port *port = tty->driver_data; - struct usb_serial *serial; - struct module *owner; - - /* The console is magical. Do not hang up the console hardware - * or there will be tears. - */ - if (port->port.console) - return; - - dbg("%s - port %d", __func__, port->number); - - tty->driver_data = NULL; - - serial = port->serial; - owner = serial->type->driver.owner; - - mutex_lock(&serial->disc_mutex); - if (!serial->disconnected) - usb_autopm_put_interface(serial->interface); - mutex_unlock(&serial->disc_mutex); - - usb_serial_put(serial); - module_put(owner); -} - -static int serial_write(struct tty_struct *tty, const unsigned char *buf, - int count) -{ - struct usb_serial_port *port = tty->driver_data; - int retval = -ENODEV; - - if (port->serial->dev->state == USB_STATE_NOTATTACHED) - goto exit; - - dbg("%s - port %d, %d byte(s)", __func__, port->number, count); - - /* pass on to the driver specific version of this function */ - retval = port->serial->type->write(tty, port, buf, count); - if (retval < 0) - retval = usb_translate_errors(retval); -exit: - return retval; -} - -static int serial_write_room(struct tty_struct *tty) -{ - struct usb_serial_port *port = tty->driver_data; - dbg("%s - port %d", __func__, port->number); - /* pass on to the driver specific version of this function */ - return port->serial->type->write_room(tty); -} - -static int serial_chars_in_buffer(struct tty_struct *tty) -{ - struct usb_serial_port *port = tty->driver_data; - dbg("%s - port %d", __func__, port->number); - - /* if the device was unplugged then any remaining characters - fell out of the connector ;) */ - if (port->serial->disconnected) - return 0; - /* pass on to the driver specific version of this function */ - return port->serial->type->chars_in_buffer(tty); -} - -static void serial_throttle(struct tty_struct *tty) -{ - struct usb_serial_port *port = tty->driver_data; - dbg("%s - port %d", __func__, port->number); - - /* pass on to the driver specific version of this function */ - if (port->serial->type->throttle) - port->serial->type->throttle(tty); -} - -static void serial_unthrottle(struct tty_struct *tty) -{ - struct usb_serial_port *port = tty->driver_data; - dbg("%s - port %d", __func__, port->number); - - /* pass on to the driver specific version of this function */ - if (port->serial->type->unthrottle) - port->serial->type->unthrottle(tty); -} - -static int serial_ioctl(struct tty_struct *tty, - unsigned int cmd, unsigned long arg) -{ - struct usb_serial_port *port = tty->driver_data; - int retval = -ENODEV; - - dbg("%s - port %d, cmd 0x%.4x", __func__, port->number, cmd); - - /* pass on to the driver specific version of this function - if it is available */ - if (port->serial->type->ioctl) { - retval = port->serial->type->ioctl(tty, cmd, arg); - } else - retval = -ENOIOCTLCMD; - return retval; -} - -static void serial_set_termios(struct tty_struct *tty, struct ktermios *old) -{ - struct usb_serial_port *port = tty->driver_data; - dbg("%s - port %d", __func__, port->number); - - /* pass on to the driver specific version of this function - if it is available */ - if (port->serial->type->set_termios) - port->serial->type->set_termios(tty, port, old); - else - tty_termios_copy_hw(tty->termios, old); -} - -static int serial_break(struct tty_struct *tty, int break_state) -{ - struct usb_serial_port *port = tty->driver_data; - - dbg("%s - port %d", __func__, port->number); - - /* pass on to the driver specific version of this function - if it is available */ - if (port->serial->type->break_ctl) - port->serial->type->break_ctl(tty, break_state); - return 0; -} - -static int serial_proc_show(struct seq_file *m, void *v) -{ - struct usb_serial *serial; - int i; - char tmp[40]; - - dbg("%s", __func__); - seq_puts(m, "usbserinfo:1.0 driver:2.0\n"); - for (i = 0; i < SERIAL_TTY_MINORS; ++i) { - serial = usb_serial_get_by_index(i); - if (serial == NULL) - continue; - - seq_printf(m, "%d:", i); - if (serial->type->driver.owner) - seq_printf(m, " module:%s", - module_name(serial->type->driver.owner)); - seq_printf(m, " name:\"%s\"", - serial->type->description); - seq_printf(m, " vendor:%04x product:%04x", - le16_to_cpu(serial->dev->descriptor.idVendor), - le16_to_cpu(serial->dev->descriptor.idProduct)); - seq_printf(m, " num_ports:%d", serial->num_ports); - seq_printf(m, " port:%d", i - serial->minor + 1); - usb_make_path(serial->dev, tmp, sizeof(tmp)); - seq_printf(m, " path:%s", tmp); - - seq_putc(m, '\n'); - usb_serial_put(serial); - mutex_unlock(&serial->disc_mutex); - } - return 0; -} - -static int serial_proc_open(struct inode *inode, struct file *file) -{ - return single_open(file, serial_proc_show, NULL); -} - -static const struct file_operations serial_proc_fops = { - .owner = THIS_MODULE, - .open = serial_proc_open, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, -}; - -static int serial_tiocmget(struct tty_struct *tty) -{ - struct usb_serial_port *port = tty->driver_data; - - dbg("%s - port %d", __func__, port->number); - - if (port->serial->type->tiocmget) - return port->serial->type->tiocmget(tty); - return -EINVAL; -} - -static int serial_tiocmset(struct tty_struct *tty, - unsigned int set, unsigned int clear) -{ - struct usb_serial_port *port = tty->driver_data; - - dbg("%s - port %d", __func__, port->number); - - if (port->serial->type->tiocmset) - return port->serial->type->tiocmset(tty, set, clear); - return -EINVAL; -} - -static int serial_get_icount(struct tty_struct *tty, - struct serial_icounter_struct *icount) -{ - struct usb_serial_port *port = tty->driver_data; - - dbg("%s - port %d", __func__, port->number); - - if (port->serial->type->get_icount) - return port->serial->type->get_icount(tty, icount); - return -EINVAL; -} - -/* - * We would be calling tty_wakeup here, but unfortunately some line - * disciplines have an annoying habit of calling tty->write from - * the write wakeup callback (e.g. n_hdlc.c). - */ -void usb_serial_port_softint(struct usb_serial_port *port) -{ - schedule_work(&port->work); -} -EXPORT_SYMBOL_GPL(usb_serial_port_softint); - -static void usb_serial_port_work(struct work_struct *work) -{ - struct usb_serial_port *port = - container_of(work, struct usb_serial_port, work); - struct tty_struct *tty; - - dbg("%s - port %d", __func__, port->number); - - tty = tty_port_tty_get(&port->port); - if (!tty) - return; - - tty_wakeup(tty); - tty_kref_put(tty); -} - -static void kill_traffic(struct usb_serial_port *port) -{ - int i; - - for (i = 0; i < ARRAY_SIZE(port->read_urbs); ++i) - usb_kill_urb(port->read_urbs[i]); - for (i = 0; i < ARRAY_SIZE(port->write_urbs); ++i) - usb_kill_urb(port->write_urbs[i]); - /* - * This is tricky. - * Some drivers submit the read_urb in the - * handler for the write_urb or vice versa - * this order determines the order in which - * usb_kill_urb() must be used to reliably - * kill the URBs. As it is unknown here, - * both orders must be used in turn. - * The call below is not redundant. - */ - usb_kill_urb(port->read_urb); - usb_kill_urb(port->interrupt_in_urb); - usb_kill_urb(port->interrupt_out_urb); -} - -static void port_release(struct device *dev) -{ - struct usb_serial_port *port = to_usb_serial_port(dev); - int i; - - dbg ("%s - %s", __func__, dev_name(dev)); - - /* - * Stop all the traffic before cancelling the work, so that - * nobody will restart it by calling usb_serial_port_softint. - */ - kill_traffic(port); - cancel_work_sync(&port->work); - - usb_free_urb(port->interrupt_in_urb); - usb_free_urb(port->interrupt_out_urb); - for (i = 0; i < ARRAY_SIZE(port->read_urbs); ++i) { - usb_free_urb(port->read_urbs[i]); - kfree(port->bulk_in_buffers[i]); - } - for (i = 0; i < ARRAY_SIZE(port->write_urbs); ++i) { - usb_free_urb(port->write_urbs[i]); - kfree(port->bulk_out_buffers[i]); - } - kfifo_free(&port->write_fifo); - kfree(port->interrupt_in_buffer); - kfree(port->interrupt_out_buffer); - kfree(port); -} - -static struct usb_serial *create_serial(struct usb_device *dev, - struct usb_interface *interface, - struct usb_serial_driver *driver) -{ - struct usb_serial *serial; - - serial = kzalloc(sizeof(*serial), GFP_KERNEL); - if (!serial) { - dev_err(&dev->dev, "%s - out of memory\n", __func__); - return NULL; - } - serial->dev = usb_get_dev(dev); - serial->type = driver; - serial->interface = interface; - kref_init(&serial->kref); - mutex_init(&serial->disc_mutex); - serial->minor = SERIAL_TTY_NO_MINOR; - - return serial; -} - -static const struct usb_device_id *match_dynamic_id(struct usb_interface *intf, - struct usb_serial_driver *drv) -{ - struct usb_dynid *dynid; - - spin_lock(&drv->dynids.lock); - list_for_each_entry(dynid, &drv->dynids.list, node) { - if (usb_match_one_id(intf, &dynid->id)) { - spin_unlock(&drv->dynids.lock); - return &dynid->id; - } - } - spin_unlock(&drv->dynids.lock); - return NULL; -} - -static const struct usb_device_id *get_iface_id(struct usb_serial_driver *drv, - struct usb_interface *intf) -{ - const struct usb_device_id *id; - - id = usb_match_id(intf, drv->id_table); - if (id) { - dbg("static descriptor matches"); - goto exit; - } - id = match_dynamic_id(intf, drv); - if (id) - dbg("dynamic descriptor matches"); -exit: - return id; -} - -/* Caller must hold table_lock */ -static struct usb_serial_driver *search_serial_device( - struct usb_interface *iface) -{ - const struct usb_device_id *id = NULL; - struct usb_serial_driver *drv; - struct usb_driver *driver = to_usb_driver(iface->dev.driver); - - /* Check if the usb id matches a known device */ - list_for_each_entry(drv, &usb_serial_driver_list, driver_list) { - if (drv->usb_driver == driver) - id = get_iface_id(drv, iface); - if (id) - return drv; - } - - return NULL; -} - -static int serial_carrier_raised(struct tty_port *port) -{ - struct usb_serial_port *p = container_of(port, struct usb_serial_port, port); - struct usb_serial_driver *drv = p->serial->type; - - if (drv->carrier_raised) - return drv->carrier_raised(p); - /* No carrier control - don't block */ - return 1; -} - -static void serial_dtr_rts(struct tty_port *port, int on) -{ - struct usb_serial_port *p = container_of(port, struct usb_serial_port, port); - struct usb_serial_driver *drv = p->serial->type; - - if (drv->dtr_rts) - drv->dtr_rts(p, on); -} - -static const struct tty_port_operations serial_port_ops = { - .carrier_raised = serial_carrier_raised, - .dtr_rts = serial_dtr_rts, - .activate = serial_activate, - .shutdown = serial_down, -}; - -int usb_serial_probe(struct usb_interface *interface, - const struct usb_device_id *id) -{ - struct usb_device *dev = interface_to_usbdev(interface); - struct usb_serial *serial = NULL; - struct usb_serial_port *port; - struct usb_host_interface *iface_desc; - struct usb_endpoint_descriptor *endpoint; - struct usb_endpoint_descriptor *interrupt_in_endpoint[MAX_NUM_PORTS]; - struct usb_endpoint_descriptor *interrupt_out_endpoint[MAX_NUM_PORTS]; - struct usb_endpoint_descriptor *bulk_in_endpoint[MAX_NUM_PORTS]; - struct usb_endpoint_descriptor *bulk_out_endpoint[MAX_NUM_PORTS]; - struct usb_serial_driver *type = NULL; - int retval; - unsigned int minor; - int buffer_size; - int i; - int j; - int num_interrupt_in = 0; - int num_interrupt_out = 0; - int num_bulk_in = 0; - int num_bulk_out = 0; - int num_ports = 0; - int max_endpoints; - int startIndex = 0; - mutex_lock(&table_lock); - type = search_serial_device(interface); - if (!type) { - mutex_unlock(&table_lock); - dbg("none matched"); - return -ENODEV; - } - - if (!try_module_get(type->driver.owner)) { - mutex_unlock(&table_lock); - dev_err(&interface->dev, "module get failed, exiting\n"); - return -EIO; - } - mutex_unlock(&table_lock); - - serial = create_serial(dev, interface, type); - if (!serial) { - module_put(type->driver.owner); - dev_err(&interface->dev, "%s - out of memory\n", __func__); - return -ENOMEM; - } - - /* if this device type has a probe function, call it */ - if (type->probe) { - const struct usb_device_id *id; - - id = get_iface_id(type, interface); - retval = type->probe(serial, id); - - if (retval) { - dbg("sub driver rejected device"); - kfree(serial); - module_put(type->driver.owner); - return retval; - } - } - - /* descriptor matches, let's find the endpoints needed */ - /* check out the endpoints */ - iface_desc = interface->cur_altsetting; - for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) { - endpoint = &iface_desc->endpoint[i].desc; - - if (usb_endpoint_is_bulk_in(endpoint)) { - /* we found a bulk in endpoint */ - dbg("found bulk in on endpoint %d", i); - bulk_in_endpoint[num_bulk_in] = endpoint; - ++num_bulk_in; - } - - if (usb_endpoint_is_bulk_out(endpoint)) { - /* we found a bulk out endpoint */ - dbg("found bulk out on endpoint %d", i); - bulk_out_endpoint[num_bulk_out] = endpoint; - ++num_bulk_out; - } - - if (usb_endpoint_is_int_in(endpoint)) { - /* we found a interrupt in endpoint */ - dbg("found interrupt in on endpoint %d", i); - interrupt_in_endpoint[num_interrupt_in] = endpoint; - ++num_interrupt_in; - } - - if (usb_endpoint_is_int_out(endpoint)) { - /* we found an interrupt out endpoint */ - dbg("found interrupt out on endpoint %d", i); - interrupt_out_endpoint[num_interrupt_out] = endpoint; - ++num_interrupt_out; - } - } - -#if defined(CONFIG_USB_SERIAL_PL2303) || defined(CONFIG_USB_SERIAL_PL2303_MODULE) - /* BEGIN HORRIBLE HACK FOR PL2303 */ - /* this is needed due to the looney way its endpoints are set up */ - if (((le16_to_cpu(dev->descriptor.idVendor) == PL2303_VENDOR_ID) && - (le16_to_cpu(dev->descriptor.idProduct) == PL2303_PRODUCT_ID)) || - ((le16_to_cpu(dev->descriptor.idVendor) == ATEN_VENDOR_ID) && - (le16_to_cpu(dev->descriptor.idProduct) == ATEN_PRODUCT_ID)) || - ((le16_to_cpu(dev->descriptor.idVendor) == ALCOR_VENDOR_ID) && - (le16_to_cpu(dev->descriptor.idProduct) == ALCOR_PRODUCT_ID)) || - ((le16_to_cpu(dev->descriptor.idVendor) == SIEMENS_VENDOR_ID) && - (le16_to_cpu(dev->descriptor.idProduct) == SIEMENS_PRODUCT_ID_EF81))) { - if (interface != dev->actconfig->interface[0]) { - /* check out the endpoints of the other interface*/ - iface_desc = dev->actconfig->interface[0]->cur_altsetting; - for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) { - endpoint = &iface_desc->endpoint[i].desc; - if (usb_endpoint_is_int_in(endpoint)) { - /* we found a interrupt in endpoint */ - dbg("found interrupt in for Prolific device on separate interface"); - interrupt_in_endpoint[num_interrupt_in] = endpoint; - ++num_interrupt_in; - } - } - } - - /* Now make sure the PL-2303 is configured correctly. - * If not, give up now and hope this hack will work - * properly during a later invocation of usb_serial_probe - */ - if (num_bulk_in == 0 || num_bulk_out == 0) { - dev_info(&interface->dev, "PL-2303 hack: descriptors matched but endpoints did not\n"); - kfree(serial); - module_put(type->driver.owner); - return -ENODEV; - } - } - /* END HORRIBLE HACK FOR PL2303 */ -#endif - -#ifdef CONFIG_USB_SERIAL_GENERIC - if (type == &usb_serial_generic_device) { - num_ports = num_bulk_out; - if (num_ports == 0) { - dev_err(&interface->dev, - "Generic device with no bulk out, not allowed.\n"); - kfree(serial); - module_put(type->driver.owner); - return -EIO; - } - } -#endif - if (!num_ports) { - /* if this device type has a calc_num_ports function, call it */ - if (type->calc_num_ports) - num_ports = type->calc_num_ports(serial); - if (!num_ports) - num_ports = type->num_ports; - } - - serial->num_ports = num_ports; - serial->num_bulk_in = num_bulk_in; - serial->num_bulk_out = num_bulk_out; - serial->num_interrupt_in = num_interrupt_in; - serial->num_interrupt_out = num_interrupt_out; - - /* found all that we need */ - dev_info(&interface->dev, "%s converter detected\n", - type->description); - - /* create our ports, we need as many as the max endpoints */ - /* we don't use num_ports here because some devices have more - endpoint pairs than ports */ - max_endpoints = max(num_bulk_in, num_bulk_out); - max_endpoints = max(max_endpoints, num_interrupt_in); - max_endpoints = max(max_endpoints, num_interrupt_out); - max_endpoints = max(max_endpoints, (int)serial->num_ports); - serial->num_port_pointers = max_endpoints; - - dbg("%s - setting up %d port structures for this device", - __func__, max_endpoints); - for (i = 0; i < max_endpoints; ++i) { - port = kzalloc(sizeof(struct usb_serial_port), GFP_KERNEL); - if (!port) - goto probe_error; - tty_port_init(&port->port); - port->port.ops = &serial_port_ops; - port->serial = serial; - spin_lock_init(&port->lock); - /* Keep this for private driver use for the moment but - should probably go away */ - INIT_WORK(&port->work, usb_serial_port_work); - serial->port[i] = port; - port->dev.parent = &interface->dev; - port->dev.driver = NULL; - port->dev.bus = &usb_serial_bus_type; - port->dev.release = &port_release; - device_initialize(&port->dev); - } - - /* set up the endpoint information */ - for (i = 0; i < num_bulk_in; ++i) { - endpoint = bulk_in_endpoint[i]; - port = serial->port[i]; - buffer_size = max_t(int, serial->type->bulk_in_size, - usb_endpoint_maxp(endpoint)); - port->bulk_in_size = buffer_size; - port->bulk_in_endpointAddress = endpoint->bEndpointAddress; - - for (j = 0; j < ARRAY_SIZE(port->read_urbs); ++j) { - set_bit(j, &port->read_urbs_free); - port->read_urbs[j] = usb_alloc_urb(0, GFP_KERNEL); - if (!port->read_urbs[j]) { - dev_err(&interface->dev, - "No free urbs available\n"); - goto probe_error; - } - port->bulk_in_buffers[j] = kmalloc(buffer_size, - GFP_KERNEL); - if (!port->bulk_in_buffers[j]) { - dev_err(&interface->dev, - "Couldn't allocate bulk_in_buffer\n"); - goto probe_error; - } - usb_fill_bulk_urb(port->read_urbs[j], dev, - usb_rcvbulkpipe(dev, - endpoint->bEndpointAddress), - port->bulk_in_buffers[j], buffer_size, - serial->type->read_bulk_callback, - port); - } - - port->read_urb = port->read_urbs[0]; - port->bulk_in_buffer = port->bulk_in_buffers[0]; - } - - for (i = 0; i < num_bulk_out; ++i) { - endpoint = bulk_out_endpoint[i]; - port = serial->port[i]; - if (kfifo_alloc(&port->write_fifo, PAGE_SIZE, GFP_KERNEL)) - goto probe_error; - buffer_size = serial->type->bulk_out_size; - if (!buffer_size) - buffer_size = usb_endpoint_maxp(endpoint); - port->bulk_out_size = buffer_size; - port->bulk_out_endpointAddress = endpoint->bEndpointAddress; - - for (j = 0; j < ARRAY_SIZE(port->write_urbs); ++j) { - set_bit(j, &port->write_urbs_free); - port->write_urbs[j] = usb_alloc_urb(0, GFP_KERNEL); - if (!port->write_urbs[j]) { - dev_err(&interface->dev, - "No free urbs available\n"); - goto probe_error; - } - port->bulk_out_buffers[j] = kmalloc(buffer_size, - GFP_KERNEL); - if (!port->bulk_out_buffers[j]) { - dev_err(&interface->dev, - "Couldn't allocate bulk_out_buffer\n"); - goto probe_error; - } - usb_fill_bulk_urb(port->write_urbs[j], dev, - usb_sndbulkpipe(dev, - endpoint->bEndpointAddress), - port->bulk_out_buffers[j], buffer_size, - serial->type->write_bulk_callback, - port); - } - - port->write_urb = port->write_urbs[0]; - port->bulk_out_buffer = port->bulk_out_buffers[0]; - } - - if (serial->type->read_int_callback) { - for (i = 0; i < num_interrupt_in; ++i) { - endpoint = interrupt_in_endpoint[i]; - port = serial->port[i]; - port->interrupt_in_urb = usb_alloc_urb(0, GFP_KERNEL); - if (!port->interrupt_in_urb) { - dev_err(&interface->dev, - "No free urbs available\n"); - goto probe_error; - } - buffer_size = usb_endpoint_maxp(endpoint); - port->interrupt_in_endpointAddress = - endpoint->bEndpointAddress; - port->interrupt_in_buffer = kmalloc(buffer_size, - GFP_KERNEL); - if (!port->interrupt_in_buffer) { - dev_err(&interface->dev, - "Couldn't allocate interrupt_in_buffer\n"); - goto probe_error; - } - usb_fill_int_urb(port->interrupt_in_urb, dev, - usb_rcvintpipe(dev, - endpoint->bEndpointAddress), - port->interrupt_in_buffer, buffer_size, - serial->type->read_int_callback, port, - endpoint->bInterval); - } - } else if (num_interrupt_in) { - dbg("the device claims to support interrupt in transfers, but read_int_callback is not defined"); - } - - if (serial->type->write_int_callback) { - for (i = 0; i < num_interrupt_out; ++i) { - endpoint = interrupt_out_endpoint[i]; - port = serial->port[i]; - port->interrupt_out_urb = usb_alloc_urb(0, GFP_KERNEL); - if (!port->interrupt_out_urb) { - dev_err(&interface->dev, - "No free urbs available\n"); - goto probe_error; - } - buffer_size = usb_endpoint_maxp(endpoint); - port->interrupt_out_size = buffer_size; - port->interrupt_out_endpointAddress = - endpoint->bEndpointAddress; - port->interrupt_out_buffer = kmalloc(buffer_size, - GFP_KERNEL); - if (!port->interrupt_out_buffer) { - dev_err(&interface->dev, - "Couldn't allocate interrupt_out_buffer\n"); - goto probe_error; - } - usb_fill_int_urb(port->interrupt_out_urb, dev, - usb_sndintpipe(dev, - endpoint->bEndpointAddress), - port->interrupt_out_buffer, buffer_size, - serial->type->write_int_callback, port, - endpoint->bInterval); - } - } else if (num_interrupt_out) { - dbg("the device claims to support interrupt out transfers, but write_int_callback is not defined"); - } - - /* if this device type has an attach function, call it */ - if (type->attach) { - retval = type->attach(serial); - if (retval < 0) - goto probe_error; - serial->attached = 1; - if (retval > 0) { - /* quietly accept this device, but don't bind to a - serial port as it's about to disappear */ - serial->num_ports = 0; - goto exit; - } - } else { - serial->attached = 1; - } - - /* Avoid race with tty_open and serial_install by setting the - * disconnected flag and not clearing it until all ports have been - * registered. - */ - serial->disconnected = 1; - if(!strcmp(type->driver.name,"pl2303")||!strcmp(type->driver.name,"ftdi_sio")||!strcmp(type->driver.name,"cp210x")) - startIndex = 5; - - if (get_free_serial(serial, num_ports, &minor, startIndex) == NULL) { - dev_err(&interface->dev, "No more free serial devices\n"); - goto probe_error; - } - serial->minor = minor; - - /* register all of the individual ports with the driver core */ - for (i = 0; i < num_ports; ++i) { - port = serial->port[i]; - dev_set_name(&port->dev, "ttyUSB%d", port->number); - dbg ("%s - registering %s", __func__, dev_name(&port->dev)); - device_enable_async_suspend(&port->dev); - - retval = device_add(&port->dev); - if (retval) - dev_err(&port->dev, "Error registering port device, " - "continuing\n"); - } - - serial->disconnected = 0; - - usb_serial_console_init(debug, minor); - -exit: - /* success */ - usb_set_intfdata(interface, serial); - module_put(type->driver.owner); - return 0; - -probe_error: - usb_serial_put(serial); - module_put(type->driver.owner); - return -EIO; -} -EXPORT_SYMBOL_GPL(usb_serial_probe); - -void usb_serial_disconnect(struct usb_interface *interface) -{ - int i; - struct usb_serial *serial = usb_get_intfdata(interface); - struct device *dev = &interface->dev; - struct usb_serial_port *port; - - usb_serial_console_disconnect(serial); - dbg("%s", __func__); - - mutex_lock(&serial->disc_mutex); - usb_set_intfdata(interface, NULL); - /* must set a flag, to signal subdrivers */ - serial->disconnected = 1; - mutex_unlock(&serial->disc_mutex); - - for (i = 0; i < serial->num_ports; ++i) { - port = serial->port[i]; - if (port) { - struct tty_struct *tty = tty_port_tty_get(&port->port); - if (tty) { - tty_vhangup(tty); - tty_kref_put(tty); - } - kill_traffic(port); - cancel_work_sync(&port->work); - if (device_is_registered(&port->dev)) - device_del(&port->dev); - } - } - serial->type->disconnect(serial); - - /* let the last holder of this object cause it to be cleaned up */ - usb_serial_put(serial); - dev_info(dev, "device disconnected\n"); -} -EXPORT_SYMBOL_GPL(usb_serial_disconnect); - -int usb_serial_suspend(struct usb_interface *intf, pm_message_t message) -{ - struct usb_serial *serial = usb_get_intfdata(intf); - struct usb_serial_port *port; - int i, r = 0; - - serial->suspending = 1; - - if (serial->type->suspend) { - r = serial->type->suspend(serial, message); - if (r < 0) { - serial->suspending = 0; - goto err_out; - } - } - - for (i = 0; i < serial->num_ports; ++i) { - port = serial->port[i]; - if (port) - kill_traffic(port); - } - -err_out: - return r; -} -EXPORT_SYMBOL(usb_serial_suspend); - -int usb_serial_resume(struct usb_interface *intf) -{ - struct usb_serial *serial = usb_get_intfdata(intf); - int rv; - - serial->suspending = 0; - if (serial->type->resume) - rv = serial->type->resume(serial); - else - rv = usb_serial_generic_resume(serial); - - return rv; -} -EXPORT_SYMBOL(usb_serial_resume); - -static const struct tty_operations serial_ops = { - .open = serial_open, - .close = serial_close, - .write = serial_write, - .hangup = serial_hangup, - .write_room = serial_write_room, - .ioctl = serial_ioctl, - .set_termios = serial_set_termios, - .throttle = serial_throttle, - .unthrottle = serial_unthrottle, - .break_ctl = serial_break, - .chars_in_buffer = serial_chars_in_buffer, - .tiocmget = serial_tiocmget, - .tiocmset = serial_tiocmset, - .get_icount = serial_get_icount, - .cleanup = serial_cleanup, - .install = serial_install, - .proc_fops = &serial_proc_fops, -}; - - -struct tty_driver *usb_serial_tty_driver; - -static int __init usb_serial_init(void) -{ - int i; - int result; - - usb_serial_tty_driver = alloc_tty_driver(SERIAL_TTY_MINORS); - if (!usb_serial_tty_driver) - return -ENOMEM; - - /* Initialize our global data */ - for (i = 0; i < SERIAL_TTY_MINORS; ++i) - serial_table[i] = NULL; - - result = bus_register(&usb_serial_bus_type); - if (result) { - printk(KERN_ERR "usb-serial: %s - registering bus driver " - "failed\n", __func__); - goto exit_bus; - } - - usb_serial_tty_driver->driver_name = "usbserial"; - usb_serial_tty_driver->name = "ttyUSB"; - usb_serial_tty_driver->major = SERIAL_TTY_MAJOR; - usb_serial_tty_driver->minor_start = 0; - usb_serial_tty_driver->type = TTY_DRIVER_TYPE_SERIAL; - usb_serial_tty_driver->subtype = SERIAL_TYPE_NORMAL; - usb_serial_tty_driver->flags = TTY_DRIVER_REAL_RAW | - TTY_DRIVER_DYNAMIC_DEV; - usb_serial_tty_driver->init_termios = tty_std_termios; - usb_serial_tty_driver->init_termios.c_cflag = B9600 | CS8 | CREAD - | HUPCL | CLOCAL; - usb_serial_tty_driver->init_termios.c_ispeed = 9600; - usb_serial_tty_driver->init_termios.c_ospeed = 9600; - tty_set_operations(usb_serial_tty_driver, &serial_ops); - result = tty_register_driver(usb_serial_tty_driver); - if (result) { - printk(KERN_ERR "usb-serial: %s - tty_register_driver failed\n", - __func__); - goto exit_reg_driver; - } - - /* register the USB driver */ - result = usb_register(&usb_serial_driver); - if (result < 0) { - printk(KERN_ERR "usb-serial: %s - usb_register failed\n", - __func__); - goto exit_tty; - } - - /* register the generic driver, if we should */ - result = usb_serial_generic_register(debug); - if (result < 0) { - printk(KERN_ERR "usb-serial: %s - registering generic " - "driver failed\n", __func__); - goto exit_generic; - } - - printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_DESC "\n"); - - return result; - -exit_generic: - usb_deregister(&usb_serial_driver); - -exit_tty: - tty_unregister_driver(usb_serial_tty_driver); - -exit_reg_driver: - bus_unregister(&usb_serial_bus_type); - -exit_bus: - printk(KERN_ERR "usb-serial: %s - returning with error %d\n", - __func__, result); - put_tty_driver(usb_serial_tty_driver); - return result; -} - - -static void __exit usb_serial_exit(void) -{ - usb_serial_console_exit(); - - usb_serial_generic_deregister(); - - usb_deregister(&usb_serial_driver); - tty_unregister_driver(usb_serial_tty_driver); - put_tty_driver(usb_serial_tty_driver); - bus_unregister(&usb_serial_bus_type); -} - - -module_init(usb_serial_init); -module_exit(usb_serial_exit); - -#define set_to_generic_if_null(type, function) \ - do { \ - if (!type->function) { \ - type->function = usb_serial_generic_##function; \ - dbg("Had to override the " #function \ - " usb serial operation with the generic one.");\ - } \ - } while (0) - -static void fixup_generic(struct usb_serial_driver *device) -{ - set_to_generic_if_null(device, open); - set_to_generic_if_null(device, write); - set_to_generic_if_null(device, close); - set_to_generic_if_null(device, write_room); - set_to_generic_if_null(device, chars_in_buffer); - set_to_generic_if_null(device, read_bulk_callback); - set_to_generic_if_null(device, write_bulk_callback); - set_to_generic_if_null(device, disconnect); - set_to_generic_if_null(device, release); - set_to_generic_if_null(device, process_read_urb); - set_to_generic_if_null(device, prepare_write_buffer); -} - -static int usb_serial_register(struct usb_serial_driver *driver) -{ - int retval; - - if (usb_disabled()) - return -ENODEV; - - fixup_generic(driver); - - if (!driver->description) - driver->description = driver->driver.name; - if (!driver->usb_driver) { - WARN(1, "Serial driver %s has no usb_driver\n", - driver->description); - return -EINVAL; - } - - /* Add this device to our list of devices */ - mutex_lock(&table_lock); - list_add(&driver->driver_list, &usb_serial_driver_list); - - retval = usb_serial_bus_register(driver); - if (retval) { - printk(KERN_ERR "usb-serial: problem %d when registering " - "driver %s\n", retval, driver->description); - list_del(&driver->driver_list); - } else - printk(KERN_INFO "USB Serial support registered for %s\n", - driver->description); - - mutex_unlock(&table_lock); - return retval; -} - -static void usb_serial_deregister(struct usb_serial_driver *device) -{ - printk(KERN_INFO "USB Serial deregistering driver %s\n", - device->description); - mutex_lock(&table_lock); - list_del(&device->driver_list); - usb_serial_bus_deregister(device); - mutex_unlock(&table_lock); -} - -/** - * usb_serial_register_drivers - register drivers for a usb-serial module - * @udriver: usb_driver used for matching devices/interfaces - * @serial_drivers: NULL-terminated array of pointers to drivers to be registered - * - * Registers @udriver and all the drivers in the @serial_drivers array. - * Automatically fills in the .no_dynamic_id and PM fields in @udriver and - * the .usb_driver field in each serial driver. - */ -int usb_serial_register_drivers(struct usb_driver *udriver, - struct usb_serial_driver * const serial_drivers[]) -{ - int rc; - const struct usb_device_id *saved_id_table; - struct usb_serial_driver * const *sd; - - /* - * udriver must be registered before any of the serial drivers, - * because the store_new_id() routine for the serial drivers (in - * bus.c) probes udriver. - * - * Performance hack: We don't want udriver to be probed until - * the serial drivers are registered, because the probe would - * simply fail for lack of a matching serial driver. - * Therefore save off udriver's id_table until we are all set. - * - * Suspend/resume support is implemented in the usb-serial core, - * so fill in the PM-related fields in udriver. - */ - saved_id_table = udriver->id_table; - udriver->id_table = NULL; - - udriver->no_dynamic_id = 1; - udriver->supports_autosuspend = 1; - udriver->suspend = usb_serial_suspend; - udriver->resume = usb_serial_resume; - rc = usb_register(udriver); - if (rc) - return rc; - - for (sd = serial_drivers; *sd; ++sd) { - (*sd)->usb_driver = udriver; - rc = usb_serial_register(*sd); - if (rc) - goto failed; - } - - /* Now restore udriver's id_table and look for matches */ - udriver->id_table = saved_id_table; - rc = driver_attach(&udriver->drvwrap.driver); - return 0; - - failed: - while (sd-- > serial_drivers) - usb_serial_deregister(*sd); - usb_deregister(udriver); - return rc; -} -EXPORT_SYMBOL_GPL(usb_serial_register_drivers); - -/** - * usb_serial_deregister_drivers - deregister drivers for a usb-serial module - * @udriver: usb_driver to unregister - * @serial_drivers: NULL-terminated array of pointers to drivers to be deregistered - * - * Deregisters @udriver and all the drivers in the @serial_drivers array. - */ -void usb_serial_deregister_drivers(struct usb_driver *udriver, - struct usb_serial_driver * const serial_drivers[]) -{ - for (; *serial_drivers; ++serial_drivers) - usb_serial_deregister(*serial_drivers); - usb_deregister(udriver); -} -EXPORT_SYMBOL_GPL(usb_serial_deregister_drivers); - -/* Module information */ -MODULE_AUTHOR(DRIVER_AUTHOR); -MODULE_DESCRIPTION(DRIVER_DESC); -MODULE_LICENSE("GPL"); - -module_param(debug, bool, S_IRUGO | S_IWUSR); -MODULE_PARM_DESC(debug, "Debug enabled or not"); diff --git a/ANDROID_3.4.5/drivers/usb/serial/usb-wwan.h b/ANDROID_3.4.5/drivers/usb/serial/usb-wwan.h deleted file mode 100644 index c47b6ec0..00000000 --- a/ANDROID_3.4.5/drivers/usb/serial/usb-wwan.h +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Definitions for USB serial mobile broadband cards - */ - -#ifndef __LINUX_USB_USB_WWAN -#define __LINUX_USB_USB_WWAN - -extern void usb_wwan_dtr_rts(struct usb_serial_port *port, int on); -extern int usb_wwan_open(struct tty_struct *tty, struct usb_serial_port *port); -extern void usb_wwan_close(struct usb_serial_port *port); -extern int usb_wwan_startup(struct usb_serial *serial); -extern void usb_wwan_disconnect(struct usb_serial *serial); -extern void usb_wwan_release(struct usb_serial *serial); -extern int usb_wwan_write_room(struct tty_struct *tty); -extern void usb_wwan_set_termios(struct tty_struct *tty, - struct usb_serial_port *port, - struct ktermios *old); -extern int usb_wwan_tiocmget(struct tty_struct *tty); -extern int usb_wwan_tiocmset(struct tty_struct *tty, - unsigned int set, unsigned int clear); -extern int usb_wwan_ioctl(struct tty_struct *tty, - unsigned int cmd, unsigned long arg); -extern int usb_wwan_send_setup(struct usb_serial_port *port); -extern int usb_wwan_write(struct tty_struct *tty, struct usb_serial_port *port, - const unsigned char *buf, int count); -extern int usb_wwan_chars_in_buffer(struct tty_struct *tty); -#ifdef CONFIG_PM -extern int usb_wwan_suspend(struct usb_serial *serial, pm_message_t message); -extern int usb_wwan_resume(struct usb_serial *serial); -#endif - -/* per port private data */ - -#define N_IN_URB 4 -#define N_OUT_URB 4 -#define IN_BUFLEN 4096 -#define OUT_BUFLEN 4096 - -struct usb_wwan_intf_private { - spinlock_t susp_lock; - unsigned int suspended:1; - int in_flight; - int (*send_setup) (struct usb_serial_port *port); - void *private; -}; - -struct usb_wwan_port_private { - /* Input endpoints and buffer for this port */ - struct urb *in_urbs[N_IN_URB]; - u8 *in_buffer[N_IN_URB]; - /* Output endpoints and buffer for this port */ - struct urb *out_urbs[N_OUT_URB]; - u8 *out_buffer[N_OUT_URB]; - unsigned long out_busy; /* Bit vector of URBs in use */ - int opened; - struct usb_anchor delayed; - - /* Settings for the port */ - int rts_state; /* Handshaking pins (outputs) */ - int dtr_state; - int cts_state; /* Handshaking pins (inputs) */ - int dsr_state; - int dcd_state; - int ri_state; - - unsigned long tx_start_time[N_OUT_URB]; -}; - -#endif /* __LINUX_USB_USB_WWAN */ diff --git a/ANDROID_3.4.5/drivers/usb/serial/usb_debug.c b/ANDROID_3.4.5/drivers/usb/serial/usb_debug.c deleted file mode 100644 index e3e8995a..00000000 --- a/ANDROID_3.4.5/drivers/usb/serial/usb_debug.c +++ /dev/null @@ -1,87 +0,0 @@ -/* - * USB Debug cable driver - * - * Copyright (C) 2006 Greg Kroah-Hartman <greg@kroah.com> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License version - * 2 as published by the Free Software Foundation. - */ - -#include <linux/gfp.h> -#include <linux/kernel.h> -#include <linux/init.h> -#include <linux/tty.h> -#include <linux/module.h> -#include <linux/usb.h> -#include <linux/usb/serial.h> - -#define USB_DEBUG_MAX_PACKET_SIZE 8 -#define USB_DEBUG_BRK_SIZE 8 -static char USB_DEBUG_BRK[USB_DEBUG_BRK_SIZE] = { - 0x00, - 0xff, - 0x01, - 0xfe, - 0x00, - 0xfe, - 0x01, - 0xff, -}; - -static const struct usb_device_id id_table[] = { - { USB_DEVICE(0x0525, 0x127a) }, - { }, -}; -MODULE_DEVICE_TABLE(usb, id_table); - -static struct usb_driver debug_driver = { - .name = "debug", - .probe = usb_serial_probe, - .disconnect = usb_serial_disconnect, - .id_table = id_table, -}; - -/* This HW really does not support a serial break, so one will be - * emulated when ever the break state is set to true. - */ -static void usb_debug_break_ctl(struct tty_struct *tty, int break_state) -{ - struct usb_serial_port *port = tty->driver_data; - if (!break_state) - return; - usb_serial_generic_write(tty, port, USB_DEBUG_BRK, USB_DEBUG_BRK_SIZE); -} - -static void usb_debug_process_read_urb(struct urb *urb) -{ - struct usb_serial_port *port = urb->context; - - if (urb->actual_length == USB_DEBUG_BRK_SIZE && - memcmp(urb->transfer_buffer, USB_DEBUG_BRK, - USB_DEBUG_BRK_SIZE) == 0) { - usb_serial_handle_break(port); - return; - } - - usb_serial_generic_process_read_urb(urb); -} - -static struct usb_serial_driver debug_device = { - .driver = { - .owner = THIS_MODULE, - .name = "debug", - }, - .id_table = id_table, - .num_ports = 1, - .bulk_out_size = USB_DEBUG_MAX_PACKET_SIZE, - .break_ctl = usb_debug_break_ctl, - .process_read_urb = usb_debug_process_read_urb, -}; - -static struct usb_serial_driver * const serial_drivers[] = { - &debug_device, NULL -}; - -module_usb_serial_driver(debug_driver, serial_drivers); -MODULE_LICENSE("GPL"); diff --git a/ANDROID_3.4.5/drivers/usb/serial/usb_wwan.c b/ANDROID_3.4.5/drivers/usb/serial/usb_wwan.c deleted file mode 100644 index c88657dd..00000000 --- a/ANDROID_3.4.5/drivers/usb/serial/usb_wwan.c +++ /dev/null @@ -1,774 +0,0 @@ -/* - USB Driver layer for GSM modems - - Copyright (C) 2005 Matthias Urlichs <smurf@smurf.noris.de> - - This driver is free software; you can redistribute it and/or modify - it under the terms of Version 2 of the GNU General Public License as - published by the Free Software Foundation. - - Portions copied from the Keyspan driver by Hugh Blemings <hugh@blemings.org> - - History: see the git log. - - Work sponsored by: Sigos GmbH, Germany <info@sigos.de> - - This driver exists because the "normal" serial driver doesn't work too well - with GSM modems. Issues: - - data loss -- one single Receive URB is not nearly enough - - controlling the baud rate doesn't make sense -*/ - -#define DRIVER_VERSION "v0.7.2" -#define DRIVER_AUTHOR "Matthias Urlichs <smurf@smurf.noris.de>" -#define DRIVER_DESC "USB Driver for GSM modems" - -#include <linux/kernel.h> -#include <linux/jiffies.h> -#include <linux/errno.h> -#include <linux/slab.h> -#include <linux/tty.h> -#include <linux/tty_flip.h> -#include <linux/module.h> -#include <linux/bitops.h> -#include <linux/uaccess.h> -#include <linux/usb.h> -#include <linux/usb/serial.h> -#include <linux/serial.h> -#include "usb-wwan.h" - -static bool debug; - -void usb_wwan_dtr_rts(struct usb_serial_port *port, int on) -{ - struct usb_serial *serial = port->serial; - struct usb_wwan_port_private *portdata; - - struct usb_wwan_intf_private *intfdata; - - dbg("%s", __func__); - - intfdata = port->serial->private; - - if (!intfdata->send_setup) - return; - - portdata = usb_get_serial_port_data(port); - mutex_lock(&serial->disc_mutex); - portdata->rts_state = on; - portdata->dtr_state = on; - if (serial->dev) - intfdata->send_setup(port); - mutex_unlock(&serial->disc_mutex); -} -EXPORT_SYMBOL(usb_wwan_dtr_rts); - -void usb_wwan_set_termios(struct tty_struct *tty, - struct usb_serial_port *port, - struct ktermios *old_termios) -{ - struct usb_wwan_intf_private *intfdata = port->serial->private; - - dbg("%s", __func__); - - /* Doesn't support option setting */ - tty_termios_copy_hw(tty->termios, old_termios); - - if (intfdata->send_setup) - intfdata->send_setup(port); -} -EXPORT_SYMBOL(usb_wwan_set_termios); - -int usb_wwan_tiocmget(struct tty_struct *tty) -{ - struct usb_serial_port *port = tty->driver_data; - unsigned int value; - struct usb_wwan_port_private *portdata; - - portdata = usb_get_serial_port_data(port); - - value = ((portdata->rts_state) ? TIOCM_RTS : 0) | - ((portdata->dtr_state) ? TIOCM_DTR : 0) | - ((portdata->cts_state) ? TIOCM_CTS : 0) | - ((portdata->dsr_state) ? TIOCM_DSR : 0) | - ((portdata->dcd_state) ? TIOCM_CAR : 0) | - ((portdata->ri_state) ? TIOCM_RNG : 0); - - return value; -} -EXPORT_SYMBOL(usb_wwan_tiocmget); - -int usb_wwan_tiocmset(struct tty_struct *tty, - unsigned int set, unsigned int clear) -{ - struct usb_serial_port *port = tty->driver_data; - struct usb_wwan_port_private *portdata; - struct usb_wwan_intf_private *intfdata; - - portdata = usb_get_serial_port_data(port); - intfdata = port->serial->private; - - if (!intfdata->send_setup) - return -EINVAL; - - /* FIXME: what locks portdata fields ? */ - if (set & TIOCM_RTS) - portdata->rts_state = 1; - if (set & TIOCM_DTR) - portdata->dtr_state = 1; - - if (clear & TIOCM_RTS) - portdata->rts_state = 0; - if (clear & TIOCM_DTR) - portdata->dtr_state = 0; - return intfdata->send_setup(port); -} -EXPORT_SYMBOL(usb_wwan_tiocmset); - -static int get_serial_info(struct usb_serial_port *port, - struct serial_struct __user *retinfo) -{ - struct serial_struct tmp; - - if (!retinfo) - return -EFAULT; - - memset(&tmp, 0, sizeof(tmp)); - tmp.line = port->serial->minor; - tmp.port = port->number; - tmp.baud_base = tty_get_baud_rate(port->port.tty); - tmp.close_delay = port->port.close_delay / 10; - tmp.closing_wait = port->port.closing_wait == ASYNC_CLOSING_WAIT_NONE ? - ASYNC_CLOSING_WAIT_NONE : - port->port.closing_wait / 10; - - if (copy_to_user(retinfo, &tmp, sizeof(*retinfo))) - return -EFAULT; - return 0; -} - -static int set_serial_info(struct usb_serial_port *port, - struct serial_struct __user *newinfo) -{ - struct serial_struct new_serial; - unsigned int closing_wait, close_delay; - int retval = 0; - - if (copy_from_user(&new_serial, newinfo, sizeof(new_serial))) - return -EFAULT; - - close_delay = new_serial.close_delay * 10; - closing_wait = new_serial.closing_wait == ASYNC_CLOSING_WAIT_NONE ? - ASYNC_CLOSING_WAIT_NONE : new_serial.closing_wait * 10; - - mutex_lock(&port->port.mutex); - - if (!capable(CAP_SYS_ADMIN)) { - if ((close_delay != port->port.close_delay) || - (closing_wait != port->port.closing_wait)) - retval = -EPERM; - else - retval = -EOPNOTSUPP; - } else { - port->port.close_delay = close_delay; - port->port.closing_wait = closing_wait; - } - - mutex_unlock(&port->port.mutex); - return retval; -} - -int usb_wwan_ioctl(struct tty_struct *tty, - unsigned int cmd, unsigned long arg) -{ - struct usb_serial_port *port = tty->driver_data; - - dbg("%s cmd 0x%04x", __func__, cmd); - - switch (cmd) { - case TIOCGSERIAL: - return get_serial_info(port, - (struct serial_struct __user *) arg); - case TIOCSSERIAL: - return set_serial_info(port, - (struct serial_struct __user *) arg); - default: - break; - } - - dbg("%s arg not supported", __func__); - - return -ENOIOCTLCMD; -} -EXPORT_SYMBOL(usb_wwan_ioctl); - -/* Write */ -int usb_wwan_write(struct tty_struct *tty, struct usb_serial_port *port, - const unsigned char *buf, int count) -{ - struct usb_wwan_port_private *portdata; - struct usb_wwan_intf_private *intfdata; - int i; - int left, todo; - struct urb *this_urb = NULL; /* spurious */ - int err; - unsigned long flags; - - portdata = usb_get_serial_port_data(port); - intfdata = port->serial->private; - - dbg("%s: write (%d chars)", __func__, count); - - i = 0; - left = count; - for (i = 0; left > 0 && i < N_OUT_URB; i++) { - todo = left; - if (todo > OUT_BUFLEN) - todo = OUT_BUFLEN; - - this_urb = portdata->out_urbs[i]; - if (test_and_set_bit(i, &portdata->out_busy)) { - if (time_before(jiffies, - portdata->tx_start_time[i] + 10 * HZ)) - continue; - usb_unlink_urb(this_urb); - continue; - } - dbg("%s: endpoint %d buf %d", __func__, - usb_pipeendpoint(this_urb->pipe), i); - - err = usb_autopm_get_interface_async(port->serial->interface); - if (err < 0) - break; - - /* send the data */ - memcpy(this_urb->transfer_buffer, buf, todo); - this_urb->transfer_buffer_length = todo; - - spin_lock_irqsave(&intfdata->susp_lock, flags); - if (intfdata->suspended) { - usb_anchor_urb(this_urb, &portdata->delayed); - spin_unlock_irqrestore(&intfdata->susp_lock, flags); - } else { - intfdata->in_flight++; - spin_unlock_irqrestore(&intfdata->susp_lock, flags); - err = usb_submit_urb(this_urb, GFP_ATOMIC); - if (err) { - dbg("usb_submit_urb %p (write bulk) failed " - "(%d)", this_urb, err); - clear_bit(i, &portdata->out_busy); - spin_lock_irqsave(&intfdata->susp_lock, flags); - intfdata->in_flight--; - spin_unlock_irqrestore(&intfdata->susp_lock, - flags); - usb_autopm_put_interface_async(port->serial->interface); - break; - } - } - - portdata->tx_start_time[i] = jiffies; - buf += todo; - left -= todo; - } - - count -= left; - dbg("%s: wrote (did %d)", __func__, count); - return count; -} -EXPORT_SYMBOL(usb_wwan_write); - -static void usb_wwan_indat_callback(struct urb *urb) -{ - int err; - int endpoint; - struct usb_serial_port *port; - struct tty_struct *tty; - unsigned char *data = urb->transfer_buffer; - int status = urb->status; - - dbg("%s: %p", __func__, urb); - - endpoint = usb_pipeendpoint(urb->pipe); - port = urb->context; - - if (status) { - dbg("%s: nonzero status: %d on endpoint %02x.", - __func__, status, endpoint); - } else { - tty = tty_port_tty_get(&port->port); - if (tty) { - if (urb->actual_length) { - tty_insert_flip_string(tty, data, - urb->actual_length); - tty_flip_buffer_push(tty); - } else - dbg("%s: empty read urb received", __func__); - tty_kref_put(tty); - } - - /* Resubmit urb so we continue receiving */ - if (status != -ESHUTDOWN) { - err = usb_submit_urb(urb, GFP_ATOMIC); - if (err) { - if (err != -EPERM) { - printk(KERN_ERR "%s: resubmit read urb failed. " - "(%d)", __func__, err); - /* busy also in error unless we are killed */ - usb_mark_last_busy(port->serial->dev); - } - } else { - usb_mark_last_busy(port->serial->dev); - } - } - - } -} - -static void usb_wwan_outdat_callback(struct urb *urb) -{ - struct usb_serial_port *port; - struct usb_wwan_port_private *portdata; - struct usb_wwan_intf_private *intfdata; - int i; - - dbg("%s", __func__); - - port = urb->context; - intfdata = port->serial->private; - - usb_serial_port_softint(port); - usb_autopm_put_interface_async(port->serial->interface); - portdata = usb_get_serial_port_data(port); - spin_lock(&intfdata->susp_lock); - intfdata->in_flight--; - spin_unlock(&intfdata->susp_lock); - - for (i = 0; i < N_OUT_URB; ++i) { - if (portdata->out_urbs[i] == urb) { - smp_mb__before_clear_bit(); - clear_bit(i, &portdata->out_busy); - break; - } - } -} - -int usb_wwan_write_room(struct tty_struct *tty) -{ - struct usb_serial_port *port = tty->driver_data; - struct usb_wwan_port_private *portdata; - int i; - int data_len = 0; - struct urb *this_urb; - - portdata = usb_get_serial_port_data(port); - - for (i = 0; i < N_OUT_URB; i++) { - this_urb = portdata->out_urbs[i]; - if (this_urb && !test_bit(i, &portdata->out_busy)) - data_len += OUT_BUFLEN; - } - - dbg("%s: %d", __func__, data_len); - return data_len; -} -EXPORT_SYMBOL(usb_wwan_write_room); - -int usb_wwan_chars_in_buffer(struct tty_struct *tty) -{ - struct usb_serial_port *port = tty->driver_data; - struct usb_wwan_port_private *portdata; - int i; - int data_len = 0; - struct urb *this_urb; - - portdata = usb_get_serial_port_data(port); - - for (i = 0; i < N_OUT_URB; i++) { - this_urb = portdata->out_urbs[i]; - /* FIXME: This locking is insufficient as this_urb may - go unused during the test */ - if (this_urb && test_bit(i, &portdata->out_busy)) - data_len += this_urb->transfer_buffer_length; - } - dbg("%s: %d", __func__, data_len); - return data_len; -} -EXPORT_SYMBOL(usb_wwan_chars_in_buffer); - -int usb_wwan_open(struct tty_struct *tty, struct usb_serial_port *port) -{ - struct usb_wwan_port_private *portdata; - struct usb_wwan_intf_private *intfdata; - struct usb_serial *serial = port->serial; - int i, err; - struct urb *urb; - - portdata = usb_get_serial_port_data(port); - intfdata = serial->private; - - dbg("%s", __func__); - - /* Start reading from the IN endpoint */ - for (i = 0; i < N_IN_URB; i++) { - urb = portdata->in_urbs[i]; - if (!urb) - continue; - err = usb_submit_urb(urb, GFP_KERNEL); - if (err) { - dbg("%s: submit urb %d failed (%d) %d", - __func__, i, err, urb->transfer_buffer_length); - } - } - - if (intfdata->send_setup) - intfdata->send_setup(port); - - serial->interface->needs_remote_wakeup = 1; - spin_lock_irq(&intfdata->susp_lock); - portdata->opened = 1; - spin_unlock_irq(&intfdata->susp_lock); - /* this balances a get in the generic USB serial code */ - usb_autopm_put_interface(serial->interface); - - return 0; -} -EXPORT_SYMBOL(usb_wwan_open); - -void usb_wwan_close(struct usb_serial_port *port) -{ - int i; - struct usb_serial *serial = port->serial; - struct usb_wwan_port_private *portdata; - struct usb_wwan_intf_private *intfdata = port->serial->private; - - dbg("%s", __func__); - portdata = usb_get_serial_port_data(port); - - if (serial->dev) { - /* Stop reading/writing urbs */ - spin_lock_irq(&intfdata->susp_lock); - portdata->opened = 0; - spin_unlock_irq(&intfdata->susp_lock); - - for (i = 0; i < N_IN_URB; i++) - usb_kill_urb(portdata->in_urbs[i]); - for (i = 0; i < N_OUT_URB; i++) - usb_kill_urb(portdata->out_urbs[i]); - /* balancing - important as an error cannot be handled*/ - usb_autopm_get_interface_no_resume(serial->interface); - serial->interface->needs_remote_wakeup = 0; - } -} -EXPORT_SYMBOL(usb_wwan_close); - -/* Helper functions used by usb_wwan_setup_urbs */ -static struct urb *usb_wwan_setup_urb(struct usb_serial *serial, int endpoint, - int dir, void *ctx, char *buf, int len, - void (*callback) (struct urb *)) -{ - struct urb *urb; - - if (endpoint == -1) - return NULL; /* endpoint not needed */ - - urb = usb_alloc_urb(0, GFP_KERNEL); /* No ISO */ - if (urb == NULL) { - dbg("%s: alloc for endpoint %d failed.", __func__, endpoint); - return NULL; - } - - /* Fill URB using supplied data. */ - usb_fill_bulk_urb(urb, serial->dev, - usb_sndbulkpipe(serial->dev, endpoint) | dir, - buf, len, callback, ctx); - - return urb; -} - -/* Setup urbs */ -static void usb_wwan_setup_urbs(struct usb_serial *serial) -{ - int i, j; - struct usb_serial_port *port; - struct usb_wwan_port_private *portdata; - - dbg("%s", __func__); - - for (i = 0; i < serial->num_ports; i++) { - port = serial->port[i]; - portdata = usb_get_serial_port_data(port); - - /* Do indat endpoints first */ - for (j = 0; j < N_IN_URB; ++j) { - portdata->in_urbs[j] = usb_wwan_setup_urb(serial, - port-> - bulk_in_endpointAddress, - USB_DIR_IN, - port, - portdata-> - in_buffer[j], - IN_BUFLEN, - usb_wwan_indat_callback); - } - - /* outdat endpoints */ - for (j = 0; j < N_OUT_URB; ++j) { - portdata->out_urbs[j] = usb_wwan_setup_urb(serial, - port-> - bulk_out_endpointAddress, - USB_DIR_OUT, - port, - portdata-> - out_buffer - [j], - OUT_BUFLEN, - usb_wwan_outdat_callback); - } - } -} - -int usb_wwan_startup(struct usb_serial *serial) -{ - int i, j, err; - struct usb_serial_port *port; - struct usb_wwan_port_private *portdata; - u8 *buffer; - - dbg("%s", __func__); - - /* Now setup per port private data */ - for (i = 0; i < serial->num_ports; i++) { - port = serial->port[i]; - portdata = kzalloc(sizeof(*portdata), GFP_KERNEL); - if (!portdata) { - dbg("%s: kmalloc for usb_wwan_port_private (%d) failed!.", - __func__, i); - return 1; - } - init_usb_anchor(&portdata->delayed); - - for (j = 0; j < N_IN_URB; j++) { - buffer = (u8 *) __get_free_page(GFP_KERNEL); - if (!buffer) - goto bail_out_error; - portdata->in_buffer[j] = buffer; - } - - for (j = 0; j < N_OUT_URB; j++) { - buffer = kmalloc(OUT_BUFLEN, GFP_KERNEL); - if (!buffer) - goto bail_out_error2; - portdata->out_buffer[j] = buffer; - } - - usb_set_serial_port_data(port, portdata); - - if (!port->interrupt_in_urb) - continue; - err = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL); - if (err) - dbg("%s: submit irq_in urb failed %d", __func__, err); - } - usb_wwan_setup_urbs(serial); - return 0; - -bail_out_error2: - for (j = 0; j < N_OUT_URB; j++) - kfree(portdata->out_buffer[j]); -bail_out_error: - for (j = 0; j < N_IN_URB; j++) - if (portdata->in_buffer[j]) - free_page((unsigned long)portdata->in_buffer[j]); - kfree(portdata); - return 1; -} -EXPORT_SYMBOL(usb_wwan_startup); - -static void stop_read_write_urbs(struct usb_serial *serial) -{ - int i, j; - struct usb_serial_port *port; - struct usb_wwan_port_private *portdata; - - /* Stop reading/writing urbs */ - for (i = 0; i < serial->num_ports; ++i) { - port = serial->port[i]; - portdata = usb_get_serial_port_data(port); - for (j = 0; j < N_IN_URB; j++) - usb_kill_urb(portdata->in_urbs[j]); - for (j = 0; j < N_OUT_URB; j++) - usb_kill_urb(portdata->out_urbs[j]); - } -} - -void usb_wwan_disconnect(struct usb_serial *serial) -{ - dbg("%s", __func__); - - stop_read_write_urbs(serial); -} -EXPORT_SYMBOL(usb_wwan_disconnect); - -void usb_wwan_release(struct usb_serial *serial) -{ - int i, j; - struct usb_serial_port *port; - struct usb_wwan_port_private *portdata; - - dbg("%s", __func__); - - /* Now free them */ - for (i = 0; i < serial->num_ports; ++i) { - port = serial->port[i]; - portdata = usb_get_serial_port_data(port); - - for (j = 0; j < N_IN_URB; j++) { - usb_free_urb(portdata->in_urbs[j]); - free_page((unsigned long) - portdata->in_buffer[j]); - portdata->in_urbs[j] = NULL; - } - for (j = 0; j < N_OUT_URB; j++) { - usb_free_urb(portdata->out_urbs[j]); - kfree(portdata->out_buffer[j]); - portdata->out_urbs[j] = NULL; - } - } - - /* Now free per port private data */ - for (i = 0; i < serial->num_ports; i++) { - port = serial->port[i]; - kfree(usb_get_serial_port_data(port)); - } -} -EXPORT_SYMBOL(usb_wwan_release); - -#ifdef CONFIG_PM -int usb_wwan_suspend(struct usb_serial *serial, pm_message_t message) -{ - struct usb_wwan_intf_private *intfdata = serial->private; - int b; - - dbg("%s entered", __func__); - - if (PMSG_IS_AUTO(message)) { - spin_lock_irq(&intfdata->susp_lock); - b = intfdata->in_flight; - spin_unlock_irq(&intfdata->susp_lock); - - if (b) - return -EBUSY; - } - - spin_lock_irq(&intfdata->susp_lock); - intfdata->suspended = 1; - spin_unlock_irq(&intfdata->susp_lock); - stop_read_write_urbs(serial); - - return 0; -} -EXPORT_SYMBOL(usb_wwan_suspend); - -static void unbusy_queued_urb(struct urb *urb, struct usb_wwan_port_private *portdata) -{ - int i; - - for (i = 0; i < N_OUT_URB; i++) { - if (urb == portdata->out_urbs[i]) { - clear_bit(i, &portdata->out_busy); - break; - } - } -} - -static void play_delayed(struct usb_serial_port *port) -{ - struct usb_wwan_intf_private *data; - struct usb_wwan_port_private *portdata; - struct urb *urb; - int err; - - portdata = usb_get_serial_port_data(port); - data = port->serial->private; - while ((urb = usb_get_from_anchor(&portdata->delayed))) { - err = usb_submit_urb(urb, GFP_ATOMIC); - if (!err) { - data->in_flight++; - } else { - /* we have to throw away the rest */ - do { - unbusy_queued_urb(urb, portdata); - usb_autopm_put_interface_no_suspend(port->serial->interface); - } while ((urb = usb_get_from_anchor(&portdata->delayed))); - break; - } - } -} - -int usb_wwan_resume(struct usb_serial *serial) -{ - int i, j; - struct usb_serial_port *port; - struct usb_wwan_intf_private *intfdata = serial->private; - struct usb_wwan_port_private *portdata; - struct urb *urb; - int err = 0; - - dbg("%s entered", __func__); - /* get the interrupt URBs resubmitted unconditionally */ - for (i = 0; i < serial->num_ports; i++) { - port = serial->port[i]; - if (!port->interrupt_in_urb) { - dbg("%s: No interrupt URB for port %d", __func__, i); - continue; - } - err = usb_submit_urb(port->interrupt_in_urb, GFP_NOIO); - dbg("Submitted interrupt URB for port %d (result %d)", i, err); - if (err < 0) { - err("%s: Error %d for interrupt URB of port%d", - __func__, err, i); - goto err_out; - } - } - - for (i = 0; i < serial->num_ports; i++) { - /* walk all ports */ - port = serial->port[i]; - portdata = usb_get_serial_port_data(port); - - /* skip closed ports */ - spin_lock_irq(&intfdata->susp_lock); - if (!portdata->opened) { - spin_unlock_irq(&intfdata->susp_lock); - continue; - } - - for (j = 0; j < N_IN_URB; j++) { - urb = portdata->in_urbs[j]; - err = usb_submit_urb(urb, GFP_ATOMIC); - if (err < 0) { - err("%s: Error %d for bulk URB %d", - __func__, err, i); - spin_unlock_irq(&intfdata->susp_lock); - goto err_out; - } - } - play_delayed(port); - spin_unlock_irq(&intfdata->susp_lock); - } - spin_lock_irq(&intfdata->susp_lock); - intfdata->suspended = 0; - spin_unlock_irq(&intfdata->susp_lock); -err_out: - return err; -} -EXPORT_SYMBOL(usb_wwan_resume); -#endif - -MODULE_AUTHOR(DRIVER_AUTHOR); -MODULE_DESCRIPTION(DRIVER_DESC); -MODULE_VERSION(DRIVER_VERSION); -MODULE_LICENSE("GPL"); - -module_param(debug, bool, S_IRUGO | S_IWUSR); -MODULE_PARM_DESC(debug, "Debug messages"); diff --git a/ANDROID_3.4.5/drivers/usb/serial/via_option.c b/ANDROID_3.4.5/drivers/usb/serial/via_option.c deleted file mode 100755 index 2c8a84f3..00000000 --- a/ANDROID_3.4.5/drivers/usb/serial/via_option.c +++ /dev/null @@ -1,1218 +0,0 @@ -/* - USB Driver for GSM modems - - Copyright (C) 2005 Matthias Urlichs <smurf@smurf.noris.de> - - This driver is free software; you can redistribute it and/or modify - it under the terms of Version 2 of the GNU General Public License as - published by the Free Software Foundation. - - Portions copied from the Keyspan driver by Hugh Blemings <hugh@blemings.org> - - History: see the git log. - - Work sponsored by: Sigos GmbH, Germany <info@sigos.de> - - This driver exists because the "normal" serial driver doesn't work too well - with GSM modems. Issues: - - data loss -- one single Receive URB is not nearly enough - - nonstandard flow (Option devices) control - - controlling the baud rate doesn't make sense - - This driver is named "option" because the most common device it's - used for is a PC-Card (with an internal OHCI-USB interface, behind - which the GSM interface sits), made by Option Inc. - - Some of the "one port" devices actually exhibit multiple USB instances - on the USB bus. This is not a bug, these ports are used for different - device features. -*/ - -#define DRIVER_VERSION "v0.7.2" -#define DRIVER_AUTHOR "Matthias Urlichs <smurf@smurf.noris.de>" -#define DRIVER_DESC "USB Driver for GSM modems" - -#include <linux/kernel.h> -#include <linux/jiffies.h> -#include <linux/errno.h> -#include <linux/tty.h> -#include <linux/tty_flip.h> -#include <linux/slab.h> -#include <linux/module.h> -#include <linux/bitops.h> -#include <linux/usb.h> -#include <linux/usb/serial.h> -#include <linux/usb/rawbulk.h> -#include <linux/suspend.h> -#include "via_usb-wwan.h" -#include "via_usb_wwan.c" - -#if defined(CONFIG_VIATELECOM_SYNC_CBP) -#include <mach/viatel.h> -//#include "../drivers/usb/core/usb.h" -#endif - -/* Function prototypes */ -static int option_probe(struct usb_serial *serial, - const struct usb_device_id *id); -static void option_release(struct usb_serial *serial); -static int option_send_setup(struct usb_serial_port *port); -static void option_instat_callback(struct urb *urb); -/* VIA-Telecom CBP(Non-CDC version) IDs */ -struct wake_lock ets_wake_lock; -int ets_wake_lock_init = 0; -#define VIATELECOM_VENDOR_ID 0x15EB -#define VIATELECOM_PRODUCT_ID 0x0001 -#define BORA9380_VENDOR_ID 0x16d8 -#define BORA9380_PRODUCT_ID 0x4000 - -/* Vendor and product IDs */ -#define OPTION_VENDOR_ID 0x0AF0 -#define OPTION_PRODUCT_COLT 0x5000 -#define OPTION_PRODUCT_RICOLA 0x6000 -#define OPTION_PRODUCT_RICOLA_LIGHT 0x6100 -#define OPTION_PRODUCT_RICOLA_QUAD 0x6200 -#define OPTION_PRODUCT_RICOLA_QUAD_LIGHT 0x6300 -#define OPTION_PRODUCT_RICOLA_NDIS 0x6050 -#define OPTION_PRODUCT_RICOLA_NDIS_LIGHT 0x6150 -#define OPTION_PRODUCT_RICOLA_NDIS_QUAD 0x6250 -#define OPTION_PRODUCT_RICOLA_NDIS_QUAD_LIGHT 0x6350 -#define OPTION_PRODUCT_COBRA 0x6500 -#define OPTION_PRODUCT_COBRA_BUS 0x6501 -#define OPTION_PRODUCT_VIPER 0x6600 -#define OPTION_PRODUCT_VIPER_BUS 0x6601 -#define OPTION_PRODUCT_GT_MAX_READY 0x6701 -#define OPTION_PRODUCT_FUJI_MODEM_LIGHT 0x6721 -#define OPTION_PRODUCT_FUJI_MODEM_GT 0x6741 -#define OPTION_PRODUCT_FUJI_MODEM_EX 0x6761 -#define OPTION_PRODUCT_KOI_MODEM 0x6800 -#define OPTION_PRODUCT_SCORPION_MODEM 0x6901 -#define OPTION_PRODUCT_ETNA_MODEM 0x7001 -#define OPTION_PRODUCT_ETNA_MODEM_LITE 0x7021 -#define OPTION_PRODUCT_ETNA_MODEM_GT 0x7041 -#define OPTION_PRODUCT_ETNA_MODEM_EX 0x7061 -#define OPTION_PRODUCT_ETNA_KOI_MODEM 0x7100 -#define OPTION_PRODUCT_GTM380_MODEM 0x7201 - -#define HUAWEI_VENDOR_ID 0x12D1 -#define HUAWEI_PRODUCT_E600 0x1001 -#define HUAWEI_PRODUCT_E220 0x1003 -#define HUAWEI_PRODUCT_E220BIS 0x1004 -#define HUAWEI_PRODUCT_E1401 0x1401 -#define HUAWEI_PRODUCT_E1402 0x1402 -#define HUAWEI_PRODUCT_E1403 0x1403 -#define HUAWEI_PRODUCT_E1404 0x1404 -#define HUAWEI_PRODUCT_E1405 0x1405 -#define HUAWEI_PRODUCT_E1406 0x1406 -#define HUAWEI_PRODUCT_E1407 0x1407 -#define HUAWEI_PRODUCT_E1408 0x1408 -#define HUAWEI_PRODUCT_E1409 0x1409 -#define HUAWEI_PRODUCT_E140A 0x140A -#define HUAWEI_PRODUCT_E140B 0x140B -#define HUAWEI_PRODUCT_E140C 0x140C -#define HUAWEI_PRODUCT_E140D 0x140D -#define HUAWEI_PRODUCT_E140E 0x140E -#define HUAWEI_PRODUCT_E140F 0x140F -#define HUAWEI_PRODUCT_E1410 0x1410 -#define HUAWEI_PRODUCT_E1411 0x1411 -#define HUAWEI_PRODUCT_E1412 0x1412 -#define HUAWEI_PRODUCT_E1413 0x1413 -#define HUAWEI_PRODUCT_E1414 0x1414 -#define HUAWEI_PRODUCT_E1415 0x1415 -#define HUAWEI_PRODUCT_E1416 0x1416 -#define HUAWEI_PRODUCT_E1417 0x1417 -#define HUAWEI_PRODUCT_E1418 0x1418 -#define HUAWEI_PRODUCT_E1419 0x1419 -#define HUAWEI_PRODUCT_E141A 0x141A -#define HUAWEI_PRODUCT_E141B 0x141B -#define HUAWEI_PRODUCT_E141C 0x141C -#define HUAWEI_PRODUCT_E141D 0x141D -#define HUAWEI_PRODUCT_E141E 0x141E -#define HUAWEI_PRODUCT_E141F 0x141F -#define HUAWEI_PRODUCT_E1420 0x1420 -#define HUAWEI_PRODUCT_E1421 0x1421 -#define HUAWEI_PRODUCT_E1422 0x1422 -#define HUAWEI_PRODUCT_E1423 0x1423 -#define HUAWEI_PRODUCT_E1424 0x1424 -#define HUAWEI_PRODUCT_E1425 0x1425 -#define HUAWEI_PRODUCT_E1426 0x1426 -#define HUAWEI_PRODUCT_E1427 0x1427 -#define HUAWEI_PRODUCT_E1428 0x1428 -#define HUAWEI_PRODUCT_E1429 0x1429 -#define HUAWEI_PRODUCT_E142A 0x142A -#define HUAWEI_PRODUCT_E142B 0x142B -#define HUAWEI_PRODUCT_E142C 0x142C -#define HUAWEI_PRODUCT_E142D 0x142D -#define HUAWEI_PRODUCT_E142E 0x142E -#define HUAWEI_PRODUCT_E142F 0x142F -#define HUAWEI_PRODUCT_E1430 0x1430 -#define HUAWEI_PRODUCT_E1431 0x1431 -#define HUAWEI_PRODUCT_E1432 0x1432 -#define HUAWEI_PRODUCT_E1433 0x1433 -#define HUAWEI_PRODUCT_E1434 0x1434 -#define HUAWEI_PRODUCT_E1435 0x1435 -#define HUAWEI_PRODUCT_E1436 0x1436 -#define HUAWEI_PRODUCT_E1437 0x1437 -#define HUAWEI_PRODUCT_E1438 0x1438 -#define HUAWEI_PRODUCT_E1439 0x1439 -#define HUAWEI_PRODUCT_E143A 0x143A -#define HUAWEI_PRODUCT_E143B 0x143B -#define HUAWEI_PRODUCT_E143C 0x143C -#define HUAWEI_PRODUCT_E143D 0x143D -#define HUAWEI_PRODUCT_E143E 0x143E -#define HUAWEI_PRODUCT_E143F 0x143F -#define HUAWEI_PRODUCT_K4505 0x1464 -#define HUAWEI_PRODUCT_K3765 0x1465 -#define HUAWEI_PRODUCT_E14AC 0x14AC -#define HUAWEI_PRODUCT_K3806 0x14AE -#define HUAWEI_PRODUCT_K4605 0x14C6 -#define HUAWEI_PRODUCT_K5005 0x14C8 -#define HUAWEI_PRODUCT_K3770 0x14C9 -#define HUAWEI_PRODUCT_K3771 0x14CA -#define HUAWEI_PRODUCT_K4510 0x14CB -#define HUAWEI_PRODUCT_K4511 0x14CC -#define HUAWEI_PRODUCT_ETS1220 0x1803 -#define HUAWEI_PRODUCT_E353 0x1506 -//aron add-------- -#define HUAWEI_PRODUCT_E153 0x1446 -#define HUAWEI_PRODUCT_E173 0x1C05 -//---------- -#define QUANTA_VENDOR_ID 0x0408 -#define QUANTA_PRODUCT_Q101 0xEA02 -#define QUANTA_PRODUCT_Q111 0xEA03 -#define QUANTA_PRODUCT_GLX 0xEA04 -#define QUANTA_PRODUCT_GKE 0xEA05 -#define QUANTA_PRODUCT_GLE 0xEA06 - -#define NOVATELWIRELESS_VENDOR_ID 0x1410 - -/* YISO PRODUCTS */ - -#define YISO_VENDOR_ID 0x0EAB -#define YISO_PRODUCT_U893 0xC893 - -/* - * NOVATEL WIRELESS PRODUCTS - * - * Note from Novatel Wireless: - * If your Novatel modem does not work on linux, don't - * change the option module, but check our website. If - * that does not help, contact ddeschepper@nvtl.com -*/ -/* MERLIN EVDO PRODUCTS */ -#define NOVATELWIRELESS_PRODUCT_V640 0x1100 -#define NOVATELWIRELESS_PRODUCT_V620 0x1110 -#define NOVATELWIRELESS_PRODUCT_V740 0x1120 -#define NOVATELWIRELESS_PRODUCT_V720 0x1130 - -/* MERLIN HSDPA/HSPA PRODUCTS */ -#define NOVATELWIRELESS_PRODUCT_U730 0x1400 -#define NOVATELWIRELESS_PRODUCT_U740 0x1410 -#define NOVATELWIRELESS_PRODUCT_U870 0x1420 -#define NOVATELWIRELESS_PRODUCT_XU870 0x1430 -#define NOVATELWIRELESS_PRODUCT_X950D 0x1450 - -/* EXPEDITE PRODUCTS */ -#define NOVATELWIRELESS_PRODUCT_EV620 0x2100 -#define NOVATELWIRELESS_PRODUCT_ES720 0x2110 -#define NOVATELWIRELESS_PRODUCT_E725 0x2120 -#define NOVATELWIRELESS_PRODUCT_ES620 0x2130 -#define NOVATELWIRELESS_PRODUCT_EU730 0x2400 -#define NOVATELWIRELESS_PRODUCT_EU740 0x2410 -#define NOVATELWIRELESS_PRODUCT_EU870D 0x2420 -/* OVATION PRODUCTS */ -#define NOVATELWIRELESS_PRODUCT_MC727 0x4100 -#define NOVATELWIRELESS_PRODUCT_MC950D 0x4400 -/* - * Note from Novatel Wireless: - * All PID in the 5xxx range are currently reserved for - * auto-install CDROMs, and should not be added to this - * module. - * - * #define NOVATELWIRELESS_PRODUCT_U727 0x5010 - * #define NOVATELWIRELESS_PRODUCT_MC727_NEW 0x5100 -*/ -#define NOVATELWIRELESS_PRODUCT_OVMC760 0x6002 -#define NOVATELWIRELESS_PRODUCT_MC780 0x6010 -#define NOVATELWIRELESS_PRODUCT_EVDO_FULLSPEED 0x6000 -#define NOVATELWIRELESS_PRODUCT_EVDO_HIGHSPEED 0x6001 -#define NOVATELWIRELESS_PRODUCT_HSPA_FULLSPEED 0x7000 -#define NOVATELWIRELESS_PRODUCT_HSPA_HIGHSPEED 0x7001 -#define NOVATELWIRELESS_PRODUCT_HSPA_HIGHSPEED3 0x7003 -#define NOVATELWIRELESS_PRODUCT_HSPA_HIGHSPEED4 0x7004 -#define NOVATELWIRELESS_PRODUCT_HSPA_HIGHSPEED5 0x7005 -#define NOVATELWIRELESS_PRODUCT_HSPA_HIGHSPEED6 0x7006 -#define NOVATELWIRELESS_PRODUCT_HSPA_HIGHSPEED7 0x7007 -#define NOVATELWIRELESS_PRODUCT_MC996D 0x7030 -#define NOVATELWIRELESS_PRODUCT_MF3470 0x7041 -#define NOVATELWIRELESS_PRODUCT_MC547 0x7042 -#define NOVATELWIRELESS_PRODUCT_EVDO_EMBEDDED_FULLSPEED 0x8000 -#define NOVATELWIRELESS_PRODUCT_EVDO_EMBEDDED_HIGHSPEED 0x8001 -#define NOVATELWIRELESS_PRODUCT_HSPA_EMBEDDED_FULLSPEED 0x9000 -#define NOVATELWIRELESS_PRODUCT_HSPA_EMBEDDED_HIGHSPEED 0x9001 -#define NOVATELWIRELESS_PRODUCT_G1 0xA001 -#define NOVATELWIRELESS_PRODUCT_G1_M 0xA002 -#define NOVATELWIRELESS_PRODUCT_G2 0xA010 -#define NOVATELWIRELESS_PRODUCT_MC551 0xB001 - -/* AMOI PRODUCTS */ -#define AMOI_VENDOR_ID 0x1614 -#define AMOI_PRODUCT_H01 0x0800 -#define AMOI_PRODUCT_H01A 0x7002 -#define AMOI_PRODUCT_H02 0x0802 -#define AMOI_PRODUCT_SKYPEPHONE_S2 0x0407 - -#define DELL_VENDOR_ID 0x413C - -/* Dell modems */ -#define DELL_PRODUCT_5700_MINICARD 0x8114 -#define DELL_PRODUCT_5500_MINICARD 0x8115 -#define DELL_PRODUCT_5505_MINICARD 0x8116 -#define DELL_PRODUCT_5700_EXPRESSCARD 0x8117 -#define DELL_PRODUCT_5510_EXPRESSCARD 0x8118 - -#define DELL_PRODUCT_5700_MINICARD_SPRINT 0x8128 -#define DELL_PRODUCT_5700_MINICARD_TELUS 0x8129 - -#define DELL_PRODUCT_5720_MINICARD_VZW 0x8133 -#define DELL_PRODUCT_5720_MINICARD_SPRINT 0x8134 -#define DELL_PRODUCT_5720_MINICARD_TELUS 0x8135 -#define DELL_PRODUCT_5520_MINICARD_CINGULAR 0x8136 -#define DELL_PRODUCT_5520_MINICARD_GENERIC_L 0x8137 -#define DELL_PRODUCT_5520_MINICARD_GENERIC_I 0x8138 - -#define DELL_PRODUCT_5730_MINICARD_SPRINT 0x8180 -#define DELL_PRODUCT_5730_MINICARD_TELUS 0x8181 -#define DELL_PRODUCT_5730_MINICARD_VZW 0x8182 - -#define KYOCERA_VENDOR_ID 0x0c88 -#define KYOCERA_PRODUCT_KPC650 0x17da -#define KYOCERA_PRODUCT_KPC680 0x180a - -#define ANYDATA_VENDOR_ID 0x16d5 -#define ANYDATA_PRODUCT_ADU_620UW 0x6202 -#define ANYDATA_PRODUCT_ADU_E100A 0x6501 -#define ANYDATA_PRODUCT_ADU_500A 0x6502 - -#define AXESSTEL_VENDOR_ID 0x1726 -#define AXESSTEL_PRODUCT_MV110H 0x1000 - -#define BANDRICH_VENDOR_ID 0x1A8D -#define BANDRICH_PRODUCT_C100_1 0x1002 -#define BANDRICH_PRODUCT_C100_2 0x1003 -#define BANDRICH_PRODUCT_1004 0x1004 -#define BANDRICH_PRODUCT_1005 0x1005 -#define BANDRICH_PRODUCT_1006 0x1006 -#define BANDRICH_PRODUCT_1007 0x1007 -#define BANDRICH_PRODUCT_1008 0x1008 -#define BANDRICH_PRODUCT_1009 0x1009 -#define BANDRICH_PRODUCT_100A 0x100a - -#define BANDRICH_PRODUCT_100B 0x100b -#define BANDRICH_PRODUCT_100C 0x100c -#define BANDRICH_PRODUCT_100D 0x100d -#define BANDRICH_PRODUCT_100E 0x100e - -#define BANDRICH_PRODUCT_100F 0x100f -#define BANDRICH_PRODUCT_1010 0x1010 -#define BANDRICH_PRODUCT_1011 0x1011 -#define BANDRICH_PRODUCT_1012 0x1012 - -#define QUALCOMM_VENDOR_ID 0x05C6 - -#define CMOTECH_VENDOR_ID 0x16d8 -#define CMOTECH_PRODUCT_6008 0x6008 -#define CMOTECH_PRODUCT_6280 0x6280 - -#define TELIT_VENDOR_ID 0x1bc7 -#define TELIT_PRODUCT_UC864E 0x1003 -#define TELIT_PRODUCT_UC864G 0x1004 -#define TELIT_PRODUCT_CC864_DUAL 0x1005 -#define TELIT_PRODUCT_CC864_SINGLE 0x1006 -#define TELIT_PRODUCT_DE910_DUAL 0x1010 - -/* ZTE PRODUCTS */ -#define ZTE_VENDOR_ID 0x19d2 -#define ZTE_PRODUCT_MF622 0x0001 -#define ZTE_PRODUCT_MF628 0x0015 -#define ZTE_PRODUCT_MF626 0x0031 -#define ZTE_PRODUCT_CDMA_TECH 0xfffe -#define ZTE_PRODUCT_AC8710 0xfff1 -#define ZTE_PRODUCT_AC2726 0xfff5 -#define ZTE_PRODUCT_AC8710T 0xffff -#define ZTE_PRODUCT_MC2718 0xffe8 -#define ZTE_PRODUCT_AD3812 0xffeb -#define ZTE_PRODUCT_MC2716 0xffed - -#define BENQ_VENDOR_ID 0x04a5 -#define BENQ_PRODUCT_H10 0x4068 - -#define DLINK_VENDOR_ID 0x1186 -#define DLINK_PRODUCT_DWM_652 0x3e04 -#define DLINK_PRODUCT_DWM_652_U5 0xce16 -#define DLINK_PRODUCT_DWM_652_U5A 0xce1e - -#define QISDA_VENDOR_ID 0x1da5 -#define QISDA_PRODUCT_H21_4512 0x4512 -#define QISDA_PRODUCT_H21_4523 0x4523 -#define QISDA_PRODUCT_H20_4515 0x4515 -#define QISDA_PRODUCT_H20_4518 0x4518 -#define QISDA_PRODUCT_H20_4519 0x4519 - -/* TLAYTECH PRODUCTS */ -#define TLAYTECH_VENDOR_ID 0x20B9 -#define TLAYTECH_PRODUCT_TEU800 0x1682 - -/* TOSHIBA PRODUCTS */ -#define TOSHIBA_VENDOR_ID 0x0930 -#define TOSHIBA_PRODUCT_HSDPA_MINICARD 0x1302 -#define TOSHIBA_PRODUCT_G450 0x0d45 - -#define ALINK_VENDOR_ID 0x1e0e -#define ALINK_PRODUCT_PH300 0x9100 -#define ALINK_PRODUCT_3GU 0x9200 - -/* ALCATEL PRODUCTS */ -#define ALCATEL_VENDOR_ID 0x1bbb -#define ALCATEL_PRODUCT_X060S_X200 0x0000 - -#define PIRELLI_VENDOR_ID 0x1266 -#define PIRELLI_PRODUCT_C100_1 0x1002 -#define PIRELLI_PRODUCT_C100_2 0x1003 -#define PIRELLI_PRODUCT_1004 0x1004 -#define PIRELLI_PRODUCT_1005 0x1005 -#define PIRELLI_PRODUCT_1006 0x1006 -#define PIRELLI_PRODUCT_1007 0x1007 -#define PIRELLI_PRODUCT_1008 0x1008 -#define PIRELLI_PRODUCT_1009 0x1009 -#define PIRELLI_PRODUCT_100A 0x100a -#define PIRELLI_PRODUCT_100B 0x100b -#define PIRELLI_PRODUCT_100C 0x100c -#define PIRELLI_PRODUCT_100D 0x100d -#define PIRELLI_PRODUCT_100E 0x100e -#define PIRELLI_PRODUCT_100F 0x100f -#define PIRELLI_PRODUCT_1011 0x1011 -#define PIRELLI_PRODUCT_1012 0x1012 - -/* Airplus products */ -#define AIRPLUS_VENDOR_ID 0x1011 -#define AIRPLUS_PRODUCT_MCD650 0x3198 - -/* Longcheer/Longsung vendor ID; makes whitelabel devices that - * many other vendors like 4G Systems, Alcatel, ChinaBird, - * Mobidata, etc sell under their own brand names. - */ -#define LONGCHEER_VENDOR_ID 0x1c9e - -/* 4G Systems products */ -/* This is the 4G XS Stick W14 a.k.a. Mobilcom Debitel Surf-Stick * - * It seems to contain a Qualcomm QSC6240/6290 chipset */ -#define FOUR_G_SYSTEMS_PRODUCT_W14 0x9603 - -/* Zoom */ -#define ZOOM_PRODUCT_4597 0x9607 - -/* Haier products */ -#define HAIER_VENDOR_ID 0x201e -#define HAIER_PRODUCT_CE100 0x2009 - -/* Cinterion (formerly Siemens) products */ -#define SIEMENS_VENDOR_ID 0x0681 -#define CINTERION_VENDOR_ID 0x1e2d -#define CINTERION_PRODUCT_HC25_MDM 0x0047 -#define CINTERION_PRODUCT_HC25_MDMNET 0x0040 -#define CINTERION_PRODUCT_HC28_MDM 0x004C -#define CINTERION_PRODUCT_HC28_MDMNET 0x004A /* same for HC28J */ -#define CINTERION_PRODUCT_EU3_E 0x0051 -#define CINTERION_PRODUCT_EU3_P 0x0052 -#define CINTERION_PRODUCT_PH8 0x0053 - -/* Olivetti products */ -#define OLIVETTI_VENDOR_ID 0x0b3c -#define OLIVETTI_PRODUCT_OLICARD100 0xc000 - -/* Celot products */ -#define CELOT_VENDOR_ID 0x211f -#define CELOT_PRODUCT_CT680M 0x6801 - -/* ONDA Communication vendor id */ -#define ONDA_VENDOR_ID 0x1ee8 - -/* ONDA MT825UP HSDPA 14.2 modem */ -#define ONDA_MT825UP 0x000b - -/* Samsung products */ -#define SAMSUNG_VENDOR_ID 0x04e8 -#define SAMSUNG_PRODUCT_GT_B3730 0x6889 - -/* YUGA products www.yuga-info.com gavin.kx@qq.com */ -#define YUGA_VENDOR_ID 0x257A -#define YUGA_PRODUCT_CEM600 0x1601 -#define YUGA_PRODUCT_CEM610 0x1602 -#define YUGA_PRODUCT_CEM500 0x1603 -#define YUGA_PRODUCT_CEM510 0x1604 -#define YUGA_PRODUCT_CEM800 0x1605 -#define YUGA_PRODUCT_CEM900 0x1606 - -#define YUGA_PRODUCT_CEU818 0x1607 -#define YUGA_PRODUCT_CEU816 0x1608 -#define YUGA_PRODUCT_CEU828 0x1609 -#define YUGA_PRODUCT_CEU826 0x160A -#define YUGA_PRODUCT_CEU518 0x160B -#define YUGA_PRODUCT_CEU516 0x160C -#define YUGA_PRODUCT_CEU528 0x160D -#define YUGA_PRODUCT_CEU526 0x160F -#define YUGA_PRODUCT_CEU881 0x161F -#define YUGA_PRODUCT_CEU882 0x162F - -#define YUGA_PRODUCT_CWM600 0x2601 -#define YUGA_PRODUCT_CWM610 0x2602 -#define YUGA_PRODUCT_CWM500 0x2603 -#define YUGA_PRODUCT_CWM510 0x2604 -#define YUGA_PRODUCT_CWM800 0x2605 -#define YUGA_PRODUCT_CWM900 0x2606 - -#define YUGA_PRODUCT_CWU718 0x2607 -#define YUGA_PRODUCT_CWU716 0x2608 -#define YUGA_PRODUCT_CWU728 0x2609 -#define YUGA_PRODUCT_CWU726 0x260A -#define YUGA_PRODUCT_CWU518 0x260B -#define YUGA_PRODUCT_CWU516 0x260C -#define YUGA_PRODUCT_CWU528 0x260D -#define YUGA_PRODUCT_CWU581 0x260E -#define YUGA_PRODUCT_CWU526 0x260F -#define YUGA_PRODUCT_CWU582 0x261F -#define YUGA_PRODUCT_CWU583 0x262F - -#define YUGA_PRODUCT_CLM600 0x3601 -#define YUGA_PRODUCT_CLM610 0x3602 -#define YUGA_PRODUCT_CLM500 0x3603 -#define YUGA_PRODUCT_CLM510 0x3604 -#define YUGA_PRODUCT_CLM800 0x3605 -#define YUGA_PRODUCT_CLM900 0x3606 - -#define YUGA_PRODUCT_CLU718 0x3607 -#define YUGA_PRODUCT_CLU716 0x3608 -#define YUGA_PRODUCT_CLU728 0x3609 -#define YUGA_PRODUCT_CLU726 0x360A -#define YUGA_PRODUCT_CLU518 0x360B -#define YUGA_PRODUCT_CLU516 0x360C -#define YUGA_PRODUCT_CLU528 0x360D -#define YUGA_PRODUCT_CLU526 0x360F - -/* Viettel products */ -#define VIETTEL_VENDOR_ID 0x2262 -#define VIETTEL_PRODUCT_VT1000 0x0002 - -/* ZD Incorporated */ -#define ZD_VENDOR_ID 0x0685 -#define ZD_PRODUCT_7000 0x7000 - -/* LG products */ -#define LG_VENDOR_ID 0x1004 -#define LG_PRODUCT_L02C 0x618f - -/* MediaTek products */ -#define MEDIATEK_VENDOR_ID 0x0e8d -#define MEDIATEK_PRODUCT_DC_1COM 0x00a0 -#define MEDIATEK_PRODUCT_DC_4COM 0x00a5 -#define MEDIATEK_PRODUCT_DC_5COM 0x00a4 -#define MEDIATEK_PRODUCT_7208_1COM 0x7101 -#define MEDIATEK_PRODUCT_7208_2COM 0x7102 -#define MEDIATEK_PRODUCT_FP_1COM 0x0003 -#define MEDIATEK_PRODUCT_FP_2COM 0x0023 -#define MEDIATEK_PRODUCT_FPDC_1COM 0x0043 -#define MEDIATEK_PRODUCT_FPDC_2COM 0x0033 - -/* Cellient products */ -#define CELLIENT_VENDOR_ID 0x2692 -#define CELLIENT_PRODUCT_MEN200 0x9005 - -/* some devices interfaces need special handling due to a number of reasons */ -enum option_blacklist_reason { - OPTION_BLACKLIST_NONE = 0, - OPTION_BLACKLIST_SENDSETUP = 1, - OPTION_BLACKLIST_RESERVED_IF = 2 -}; - -#define MAX_BL_NUM 8 -struct option_blacklist_info { - /* bitfield of interface numbers for OPTION_BLACKLIST_SENDSETUP */ - const unsigned long sendsetup; - /* bitfield of interface numbers for OPTION_BLACKLIST_RESERVED_IF */ - const unsigned long reserved; -}; - -static const struct option_blacklist_info four_g_w14_blacklist = { - .sendsetup = BIT(0) | BIT(1), -}; - -static const struct option_blacklist_info alcatel_x200_blacklist = { - .sendsetup = BIT(0) | BIT(1), -}; - -static const struct option_blacklist_info zte_0037_blacklist = { - .sendsetup = BIT(0) | BIT(1), -}; - -static const struct option_blacklist_info zte_k3765_z_blacklist = { - .sendsetup = BIT(0) | BIT(1) | BIT(2), - .reserved = BIT(4), -}; - -static const struct option_blacklist_info zte_ad3812_z_blacklist = { - .sendsetup = BIT(0) | BIT(1) | BIT(2), -}; - -static const struct option_blacklist_info zte_mc2718_z_blacklist = { - .sendsetup = BIT(1) | BIT(2) | BIT(3) | BIT(4), -}; - -static const struct option_blacklist_info zte_mc2716_z_blacklist = { - .sendsetup = BIT(1) | BIT(2) | BIT(3), -}; - -static const struct option_blacklist_info huawei_cdc12_blacklist = { - .reserved = BIT(1) | BIT(2), -}; - -static const struct option_blacklist_info net_intf1_blacklist = { - .reserved = BIT(1), -}; - -static const struct option_blacklist_info net_intf2_blacklist = { - .reserved = BIT(2), -}; - -static const struct option_blacklist_info net_intf3_blacklist = { - .reserved = BIT(3), -}; - -static const struct option_blacklist_info net_intf4_blacklist = { - .reserved = BIT(4), -}; - -static const struct option_blacklist_info net_intf5_blacklist = { - .reserved = BIT(5), -}; - -static const struct option_blacklist_info zte_mf626_blacklist = { - .sendsetup = BIT(0) | BIT(1), - .reserved = BIT(4), -}; - -static const struct usb_device_id option_ids[] = { - { USB_DEVICE(VIATELECOM_VENDOR_ID, VIATELECOM_PRODUCT_ID) }, - { USB_DEVICE(0x201e, 0x1022) }, - { } /* Terminating entry */ -}; -MODULE_DEVICE_TABLE(usb, option_ids); - - -/* add rawbulk suspend support */ -static int usb_serial_option_suspend(struct usb_interface *intf, pm_message_t message) -{ - int rc = 0; - - rc = usb_serial_suspend(intf, message); - if(rc < 0) - { - err("usb_serial_suspend return error, errno=%d\n", rc); - return rc; - } -#ifdef CONFIG_USB_ANDROID_RAWBULK - return rawbulk_suspend_host_interface(intf->cur_altsetting->desc.bInterfaceNumber, message); -#else - return rc; -#endif -} - -static int usb_serial_option_resume(struct usb_interface *intf) -{ - int rc = 0; - - rc = usb_serial_resume(intf); - if(rc < 0) - { - err("usb_serial_resume return error, errno=%d\n", rc); - return rc; - } - -#ifdef CONFIG_USB_ANDROID_RAWBULK - return rawbulk_resume_host_interface(intf->cur_altsetting->desc.bInterfaceNumber); -#else - return rc; -#endif -} -/* End of temp added */ - -static int usb_serial_option_probe(struct usb_interface *interface, - const struct usb_device_id *id); -static void usb_serial_option_disconnect(struct usb_interface *interface); -static struct usb_driver option_driver = { - .name = "via_option", - .probe = usb_serial_option_probe, - .disconnect = usb_serial_option_disconnect, -#ifdef CONFIG_PM - .suspend = usb_serial_option_suspend, - .resume = usb_serial_option_resume, - .supports_autosuspend = 1, -#endif - .id_table = option_ids, -}; - -static int usb_wwan_option_write(struct tty_struct *tty, struct usb_serial_port - *port, const unsigned char *buf, int count); - - -/* The card has three separate interfaces, which the serial driver - * recognizes separately, thus num_port=1. - */ - -static struct usb_serial_driver option_1port_device = { - .driver = { - .owner = THIS_MODULE, - .name = "via_option1", - }, - .description = "GSM modem (1-port)", - .id_table = option_ids, - .num_ports = 1, - .probe = option_probe, - .open = usb_wwan_open, - .close = usb_wwan_close, - .dtr_rts = usb_wwan_dtr_rts, - .write = usb_wwan_option_write, - .write_room = usb_wwan_write_room, - .chars_in_buffer = usb_wwan_chars_in_buffer, - .set_termios = usb_wwan_set_termios, - .tiocmget = usb_wwan_tiocmget, - .tiocmset = usb_wwan_tiocmset, - .ioctl = usb_wwan_ioctl, - .attach = usb_wwan_startup, - .disconnect = usb_wwan_disconnect, - .release = usb_wwan_release, - .read_int_callback = option_instat_callback, -#ifdef CONFIG_PM - .suspend = usb_wwan_suspend, - .resume = usb_wwan_resume, -#endif -}; - -static struct usb_serial_driver * const serial_drivers[] = { - &option_1port_device, NULL -}; - -//static bool debug; - -//module_usb_serial_driver(option_driver, serial_drivers); - -static bool is_blacklisted(const u8 ifnum, enum option_blacklist_reason reason, - const struct option_blacklist_info *blacklist) -{ - unsigned long num; - const unsigned long *intf_list; - - if (blacklist) { - if (reason == OPTION_BLACKLIST_SENDSETUP) - intf_list = &blacklist->sendsetup; - else if (reason == OPTION_BLACKLIST_RESERVED_IF) - intf_list = &blacklist->reserved; - else { - BUG_ON(reason); - return false; - } - - for_each_set_bit(num, intf_list, MAX_BL_NUM + 1) { - if (num == ifnum) - return true; - } - } - return false; -} - - -static int usb_wwan_option_write(struct tty_struct *tty, struct usb_serial_port *port, - const unsigned char *buf, int count) -{ -#ifdef CONFIG_USB_ANDROID_RAWBULK - int inception; - struct usb_wwan_port_private *portdata = usb_get_serial_port_data(port); - spin_lock_irq(&portdata->incept_lock); - inception = portdata->inception; - spin_unlock_irq(&portdata->incept_lock); - - if (inception) - return 0; -#endif - - return usb_wwan_write(tty, port, buf, count); -} - -#ifdef CONFIG_USB_ANDROID_RAWBULK -#if defined(CONFIG_USB_SUSPEND) && defined(CONFIG_AP2MODEM_VIATELECOM) -extern void ap_wake_modem(void); -extern void ap_sleep_modem(void); -#endif - -#ifdef CONFIG_VIATELECOM_SYNC_CBP -static int option_rawbulk_asc_notifier(int msg, void *data) { - int opened; - struct usb_serial *serial = data; - struct usb_serial_port *port = serial->port[0]; - struct usb_wwan_port_private *portdata = usb_get_serial_port_data(port); - struct usb_wwan_intf_private *intfdata = serial->private; - - spin_lock_irq(&intfdata->susp_lock); - opened = portdata->opened; - spin_unlock_irq(&intfdata->susp_lock); - - if (!opened && msg == ASC_NTF_RX_PREPARE) - asc_rx_confirm_ready(USB_RX_HD_NAME, 1); - return 0; -} -#endif - -static int option_rawbulk_intercept(struct usb_interface *interface, unsigned int flags) { - int rc = 0; - struct usb_serial *serial = usb_get_intfdata(interface); - struct usb_serial_port *port = serial->port[0]; - struct usb_wwan_port_private *portdata = usb_get_serial_port_data(port); - struct usb_wwan_intf_private *intfdata = serial->private; - int nif = interface->cur_altsetting->desc.bInterfaceNumber; - int enable = flags & RAWBULK_INCEPT_FLAG_ENABLE; - int opened; - int n; - - spin_lock_irq(&portdata->incept_lock); - if (portdata->inception == !!enable) { - spin_unlock_irq(&portdata->incept_lock); - return -ENOENT; - } - spin_unlock_irq(&portdata->incept_lock); - - spin_lock_irq(&intfdata->susp_lock); - opened = portdata->opened; - spin_unlock_irq(&intfdata->susp_lock); - - printk(KERN_DEBUG "rawbulk do %s on port %d (%s)\n", enable? "incept": - "unincept", port->number, opened? "opened": "not-in-use"); - - if (enable) { -#if defined(CONFIG_VIATELECOM_SYNC_CBP) - struct asc_infor user = { - .notifier = option_rawbulk_asc_notifier, - .data = serial, - }; - snprintf(user.name, ASC_NAME_LEN, "%s%d", RAWBULK_RX_USER_NAME, nif); - asc_rx_add_user(USB_RX_HD_NAME, &user); - asc_tx_auto_ready(USB_TX_HD_NAME, 0); -#endif - -#ifdef CONFIG_PM - rc = usb_autopm_get_interface(interface); - if (rc < 0) - printk(KERN_ERR "incept failed while geting interface#%d\n", nif); -#endif - /* Stop reading/writing urbs */ - if (opened) { - if (!(flags & RAWBULK_INCEPT_FLAG_PUSH_WAY)) - for (n = 0; n < portdata->n_in_urb; n++) - usb_kill_urb(portdata->in_urbs[n]); - for (n = 0; n < portdata->n_out_urb; n++) - usb_kill_urb(portdata->out_urbs[n]); - } - /* Start urb for push-way */ - if (flags & RAWBULK_INCEPT_FLAG_PUSH_WAY) { - for (n = 0; n < portdata->n_in_urb; n ++) { - struct urb *urb = portdata->in_urbs[n]; - if (!urb || !urb->dev) - continue; - /* reset urb */ - usb_kill_urb(urb); - usb_clear_halt(urb->dev, urb->pipe); - rc = usb_submit_urb(urb, GFP_KERNEL); - if (rc < 0) - break; - } - if (rc < 0) - printk(KERN_ERR "incept %d while re-submitting " \ - "pushable urbs %d\n", nif, rc); - } - } else { -#if defined(CONFIG_VIATELECOM_SYNC_CBP) - char asc_user[ASC_NAME_LEN]; -#endif - rc = usb_autopm_get_interface(interface); - if (rc < 0) - printk(KERN_ERR "unincept while get interface#%d\n", nif); - if (!intfdata->suspended && opened) { - for (n = 0; n < portdata->n_in_urb; n ++) { - struct urb *urb = portdata->in_urbs[n]; - if (!urb || !urb->dev) - continue; - /* reset urb */ - usb_kill_urb(urb); - usb_clear_halt(urb->dev, urb->pipe); - rc = usb_submit_urb(urb, GFP_KERNEL); - if (rc < 0) - break; - } - if (rc < 0) - printk(KERN_ERR "unincept %d while reseting " \ - "bulk IN urbs %d\n", nif, rc); - } -#ifdef CONFIG_PM - usb_autopm_put_interface(interface); -#endif -#if defined(CONFIG_VIATELECOM_SYNC_CBP) - snprintf(asc_user, ASC_NAME_LEN, "%s%d", ASC_PATH(USB_RX_HD_NAME, RAWBULK_RX_USER_NAME), nif); - asc_rx_del_user(asc_user); -#endif - } - - if (!rc) { - spin_lock_irq(&portdata->incept_lock); - portdata->inception = !!enable; - spin_unlock_irq(&portdata->incept_lock); - } else - printk(KERN_ERR "failed(%d) to %s inception on interface#%d\n", - rc, enable? "enable": "disable", nif); - - return rc; -} - -#endif - -int serial_ntcall(struct notifier_block *nb, unsigned long val, void *nodata) -{ - struct usb_wwan_intf_private *data = container_of(nb,struct usb_wwan_intf_private,pm_nb); - - switch (val) { - case PM_SUSPEND_PREPARE: - usb_disable_autosuspend(data->udev); - return NOTIFY_DONE; - case PM_POST_SUSPEND: - usb_enable_autosuspend(data->udev); - return NOTIFY_DONE; - } - return NOTIFY_DONE; -} - -static int viatelecom_send_setup(struct usb_serial_port *port) -{ - struct usb_serial *serial = port->serial; - struct usb_wwan_port_private *portdata = usb_get_serial_port_data(port); - int ifNum = serial->interface->cur_altsetting->desc.bInterfaceNumber; - - /* VIA-Telecom CBP DTR format */ - return usb_control_msg(serial->dev, - usb_sndctrlpipe(serial->dev, 0), - 0x01, 0x40, portdata->dtr_state? 1: 0, ifNum, - NULL, 0, USB_CTRL_SET_TIMEOUT); - - -} -static int option_probe(struct usb_serial *serial, - const struct usb_device_id *id) -{ - struct usb_wwan_intf_private *data; - - /* D-Link DWM 652 still exposes CD-Rom emulation interface in modem mode */ - if (serial->dev->descriptor.idVendor == DLINK_VENDOR_ID && - serial->dev->descriptor.idProduct == DLINK_PRODUCT_DWM_652 && - serial->interface->cur_altsetting->desc.bInterfaceClass == 0x8) - return -ENODEV; - - /* Bandrich modem and AT command interface is 0xff */ - if ((serial->dev->descriptor.idVendor == BANDRICH_VENDOR_ID || - serial->dev->descriptor.idVendor == PIRELLI_VENDOR_ID) && - serial->interface->cur_altsetting->desc.bInterfaceClass != 0xff) - return -ENODEV; - - /* Don't bind reserved interfaces (like network ones) which often have - * the same class/subclass/protocol as the serial interfaces. Look at - * the Windows driver .INF files for reserved interface numbers. - */ - if (is_blacklisted( - serial->interface->cur_altsetting->desc.bInterfaceNumber, - OPTION_BLACKLIST_RESERVED_IF, - (const struct option_blacklist_info *) id->driver_info)) - return -ENODEV; - - /* Don't bind network interface on Samsung GT-B3730, it is handled by a separate module */ - if (serial->dev->descriptor.idVendor == SAMSUNG_VENDOR_ID && - serial->dev->descriptor.idProduct == SAMSUNG_PRODUCT_GT_B3730 && - serial->interface->cur_altsetting->desc.bInterfaceClass != USB_CLASS_CDC_DATA) - return -ENODEV; - - data = serial->private = kzalloc(sizeof(struct usb_wwan_intf_private), GFP_KERNEL); - if (!data) - return -ENOMEM; - - - //kevin modify for viatel modem - data->send_setup = viatelecom_send_setup; - //data->send_setup = option_send_setup; - - spin_lock_init(&data->susp_lock); - data->private = (void *)id->driver_info; - return 0; -} - -static void option_release(struct usb_serial *serial) -{ - struct usb_wwan_intf_private *priv = usb_get_serial_data(serial); - - usb_wwan_release(serial); - - kfree(priv); -} - -#define USB_CBP_TESTMODE_ENABLE 0x1 -#define USB_CBP_TESTMODE_QUERY 0x2 -#define USB_CBP_TESTMODE_UNSOLICTED 0x3 -static ssize_t option_port_testmode_show(struct device *dev, struct device_attribute - *attr, char *buf) -{ - int rc; - struct usb_serial_port *port0 = container_of(dev, struct usb_serial_port, dev); - struct usb_device *udev = port0->serial->dev; - struct usb_interface *interface = port0->serial->interface; - int ifnum = interface->cur_altsetting->desc.bInterfaceNumber; - int feedback = -1; - rc = usb_autopm_get_interface(interface); - if (rc < 0) { - printk(KERN_ERR "failed to awake cp-usb when query testmode. %d\n", rc); - return -ENODEV; - } - rc = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), USB_CBP_TESTMODE_QUERY, - USB_DIR_IN|USB_TYPE_VENDOR|USB_RECIP_INTERFACE, - 0, ifnum, &feedback, 2, USB_CTRL_GET_TIMEOUT * 5); - usb_autopm_put_interface(interface); - if ((feedback & 0xff) == 0x1) - return sprintf(buf, "%s", "enabled"); - if ((feedback & 0xff) == 0x0) - return sprintf(buf, "%s", "disabled"); - printk(KERN_ERR "connot query cp testmode %d, feedback %04x\n", rc, feedback & 0xffff); - return -EOPNOTSUPP; -} - -static ssize_t option_port_testmode_store(struct device *dev, struct device_attribute - *attr, const char *buf, size_t count) -{ - int rc = 0; - int enable = -1; - struct usb_serial_port *port0 = container_of(dev, struct usb_serial_port, dev); - struct usb_device *udev = port0->serial->dev; - struct usb_interface *interface = port0->serial->interface; - int ifnum = interface->cur_altsetting->desc.bInterfaceNumber; - - if (!strncmp(buf, "enable", 6)) - enable = 1; - else if (!strncmp(buf, "disable", 7)) - enable = 0; - if (enable >= 0) { - rc = usb_autopm_get_interface(interface); - if (rc < 0) { - printk(KERN_ERR "failed to awake cp-usb when set testmode. %d\n", rc); - return -ENODEV; - } - rc = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), - USB_CBP_TESTMODE_ENABLE, - USB_DIR_OUT|USB_TYPE_VENDOR|USB_RECIP_INTERFACE, - enable, ifnum, NULL, 0, USB_CTRL_SET_TIMEOUT); - usb_autopm_put_interface(interface); - if (rc < 0) { - printk(KERN_DEBUG "failed to sent testmode contorl msg %d\n", rc); - return rc; - } - } else if (!strncmp(buf, "unsolited", 9)) { - /* rc = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), - USB_CBP_TESTMODE_UNSOLICTED, - USB_DIR_OUT|USB_TYPE_VENDOR|USB_RECIP_INTERFACE, - 0, ifnum, ¶m, sizeof(param), USB_CTRL_SET_TIMEOUT); */ - printk(KERN_DEBUG "unsolited test mode for cp does not supported yet.\n"); - } - - return count; -} - -static DEVICE_ATTR(testmode, S_IRUGO | S_IWUSR, - option_port_testmode_show, - option_port_testmode_store); - -static int usb_serial_option_probe(struct usb_interface *interface, - const struct usb_device_id *id) { - struct usb_serial *serial; - int ret = usb_serial_probe(interface, id); - if (ret < 0) - return ret; - -#ifdef CONFIG_USB_ANDROID_RAWBULK - ret = rawbulk_bind_host_interface(interface, option_rawbulk_intercept); - if (ret < 0) - return ret; -#endif - - - - - serial = usb_get_intfdata(interface); - return sysfs_create_file(&serial->port[0]->dev.kobj, - &dev_attr_testmode.attr); -} - -static void usb_serial_option_disconnect(struct usb_interface *interface) { - struct usb_serial *serial = usb_get_intfdata(interface); - struct usb_wwan_intf_private *data = serial->private; - - - - unregister_pm_notifier(&data->pm_nb); - - sysfs_remove_file(&serial->port[0]->dev.kobj, &dev_attr_testmode.attr); -#ifdef CONFIG_USB_ANDROID_RAWBULK - rawbulk_unbind_host_interface(interface); -#endif - - usb_serial_disconnect(interface); -} - - -static void option_instat_callback(struct urb *urb) -{ - int err; - int status = urb->status; - struct usb_serial_port *port = urb->context; - struct usb_wwan_port_private *portdata = - usb_get_serial_port_data(port); - - dbg("%s", __func__); - dbg("%s: urb %p port %p has data %p", __func__, urb, port, portdata); - - if (status == 0) { - struct usb_ctrlrequest *req_pkt = - (struct usb_ctrlrequest *)urb->transfer_buffer; - - if (!req_pkt) { - dbg("%s: NULL req_pkt", __func__); - return; - } - if ((req_pkt->bRequestType == 0xA1) && - (req_pkt->bRequest == 0x20)) { - int old_dcd_state; - unsigned char signals = *((unsigned char *) - urb->transfer_buffer + - sizeof(struct usb_ctrlrequest)); - - dbg("%s: signal x%x", __func__, signals); - - old_dcd_state = portdata->dcd_state; - portdata->cts_state = 1; - portdata->dcd_state = ((signals & 0x01) ? 1 : 0); - portdata->dsr_state = ((signals & 0x02) ? 1 : 0); - portdata->ri_state = ((signals & 0x08) ? 1 : 0); - - if (old_dcd_state && !portdata->dcd_state) { - struct tty_struct *tty = - tty_port_tty_get(&port->port); - if (tty && !C_CLOCAL(tty)) - tty_hangup(tty); - tty_kref_put(tty); - } - } else { - dbg("%s: type %x req %x", __func__, - req_pkt->bRequestType, req_pkt->bRequest); - } - } else - err("%s: error %d", __func__, status); - - /* Resubmit urb so we continue receiving IRQ data */ - if (status != -ESHUTDOWN && status != -ENOENT) { - err = usb_submit_urb(urb, GFP_ATOMIC); - if (err) - dbg("%s: resubmit intr urb failed. (%d)", - __func__, err); - } -} - -/** send RTS/DTR state to the port. - * - * This is exactly the same as SET_CONTROL_LINE_STATE from the PSTN - * CDC. -*/ -static int option_send_setup(struct usb_serial_port *port) -{ - struct usb_serial *serial = port->serial; - struct usb_wwan_intf_private *intfdata = - (struct usb_wwan_intf_private *) serial->private; - struct usb_wwan_port_private *portdata; - int ifNum = serial->interface->cur_altsetting->desc.bInterfaceNumber; - int val = 0; - dbg("%s", __func__); - - if (is_blacklisted(ifNum, OPTION_BLACKLIST_SENDSETUP, - (struct option_blacklist_info *) intfdata->private)) { - dbg("No send_setup on blacklisted interface #%d\n", ifNum); - return -EIO; - } - - portdata = usb_get_serial_port_data(port); - - if (portdata->dtr_state) - val |= 0x01; - if (portdata->rts_state) - val |= 0x02; - - return usb_control_msg(serial->dev, - usb_rcvctrlpipe(serial->dev, 0), - 0x22, 0x21, val, ifNum, NULL, 0, USB_CTRL_SET_TIMEOUT); -} - - - - -static int __init via_option_init(void) -{ - int retval; - - - retval = usb_serial_register_drivers(&option_driver, serial_drivers); - if (retval) - goto failed_driver_register; - - printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_DESC "\n"); - - - - wake_lock_init(&ets_wake_lock, WAKE_LOCK_SUSPEND, "ETS_Prevent_Suspend"); - usb_ap_sync_cbp_init(); - return 0; - -failed_driver_register: - - - return retval; -} - - -static void __exit via_option_exit (void) -{ - - wake_lock_destroy(&ets_wake_lock); - - usb_serial_deregister_drivers(&option_driver, serial_drivers); -} - - -module_init(via_option_init); -module_exit(via_option_exit); - - -MODULE_AUTHOR(DRIVER_AUTHOR); -MODULE_DESCRIPTION(DRIVER_DESC); -MODULE_VERSION(DRIVER_VERSION); -MODULE_LICENSE("GPL"); - -//module_param(debug, bool, S_IRUGO | S_IWUSR); -//MODULE_PARM_DESC(debug, "Debug messages"); diff --git a/ANDROID_3.4.5/drivers/usb/serial/via_usb-wwan.h b/ANDROID_3.4.5/drivers/usb/serial/via_usb-wwan.h deleted file mode 100755 index 415b74c6..00000000 --- a/ANDROID_3.4.5/drivers/usb/serial/via_usb-wwan.h +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Definitions for USB serial mobile broadband cards - */ - -#ifndef __LINUX_USB_USB_WWAN -#define __LINUX_USB_USB_WWAN - -#define CONFIG_VIATELECOM_SYNC_CBP 1 -#define CONFIG_USB_ANDROID_RAWBULK 1 - - - -extern void usb_wwan_dtr_rts(struct usb_serial_port *port, int on); -extern int usb_wwan_open(struct tty_struct *tty, struct usb_serial_port *port); -extern void usb_wwan_close(struct usb_serial_port *port); -extern int usb_wwan_startup(struct usb_serial *serial); -extern void usb_wwan_disconnect(struct usb_serial *serial); -extern void usb_wwan_release(struct usb_serial *serial); -extern int usb_wwan_write_room(struct tty_struct *tty); -extern void usb_wwan_set_termios(struct tty_struct *tty, - struct usb_serial_port *port, - struct ktermios *old); -extern int usb_wwan_tiocmget(struct tty_struct *tty); -extern int usb_wwan_tiocmset(struct tty_struct *tty, - unsigned int set, unsigned int clear); -extern int usb_wwan_ioctl(struct tty_struct *tty, - unsigned int cmd, unsigned long arg); -extern int usb_wwan_send_setup(struct usb_serial_port *port); -extern int usb_wwan_write(struct tty_struct *tty, struct usb_serial_port *port, - const unsigned char *buf, int count); -extern int usb_wwan_chars_in_buffer(struct tty_struct *tty); -#ifdef CONFIG_PM -extern int usb_wwan_suspend(struct usb_serial *serial, pm_message_t message); -extern int usb_wwan_resume(struct usb_serial *serial); -#endif - -/* per port private data */ - -#define N_IN_URB 8 -#define N_OUT_URB 16 -#define IN_BUFLEN 4096 -#define OUT_BUFLEN 4096 - -#define MAX_IN_URBS 16 -#define MAX_OUT_URBS 16 - -struct usb_wwan_intf_private { - spinlock_t susp_lock; - struct usb_device *udev; - struct notifier_block pm_nb; - unsigned int suspended:1; - int in_flight; - int (*send_setup) (struct usb_serial_port *port); - void *private; -}; - -struct usb_wwan_port_private { - /* Input endpoints and buffer for this port */ - unsigned int n_in_urb; - unsigned int in_buflen; - struct urb *in_urbs[MAX_IN_URBS]; - u8 *in_buffer[MAX_IN_URBS]; - /* Output endpoints and buffer for this port */ - unsigned int n_out_urb; - unsigned int out_buflen; - struct urb *out_urbs[MAX_OUT_URBS]; - u8 *out_buffer[MAX_OUT_URBS]; - unsigned long out_busy; /* Bit vector of URBs in use */ - int opened; - struct usb_anchor delayed; - - /* Settings for the port */ - int rts_state; /* Handshaking pins (outputs) */ - int dtr_state; - int cts_state; /* Handshaking pins (inputs) */ - int dsr_state; - int dcd_state; - int ri_state; - - unsigned long tx_start_time[MAX_OUT_URBS]; - -#ifdef CONFIG_USB_ANDROID_RAWBULK - spinlock_t incept_lock; - unsigned int inception:1; -#endif -}; - -#endif /* __LINUX_USB_USB_WWAN */ diff --git a/ANDROID_3.4.5/drivers/usb/serial/via_usb_wwan.c b/ANDROID_3.4.5/drivers/usb/serial/via_usb_wwan.c deleted file mode 100755 index 56c11455..00000000 --- a/ANDROID_3.4.5/drivers/usb/serial/via_usb_wwan.c +++ /dev/null @@ -1,1013 +0,0 @@ -/* - USB Driver layer for GSM modems - - Copyright (C) 2005 Matthias Urlichs <smurf@smurf.noris.de> - - This driver is free software; you can redistribute it and/or modify - it under the terms of Version 2 of the GNU General Public License as - published by the Free Software Foundation. - - Portions copied from the Keyspan driver by Hugh Blemings <hugh@blemings.org> - - History: see the git log. - - Work sponsored by: Sigos GmbH, Germany <info@sigos.de> - - This driver exists because the "normal" serial driver doesn't work too well - with GSM modems. Issues: - - data loss -- one single Receive URB is not nearly enough - - controlling the baud rate doesn't make sense -*/ - -#define DRIVER_VERSION "v0.7.2" -#define DRIVER_AUTHOR "Matthias Urlichs <smurf@smurf.noris.de>" -#define DRIVER_DESC "USB Driver for GSM modems" - -#include <linux/kernel.h> -#include <linux/jiffies.h> -#include <linux/errno.h> -#include <linux/slab.h> -#include <linux/tty.h> -#include <linux/tty_flip.h> -#include <linux/module.h> -#include <linux/bitops.h> -#include <linux/uaccess.h> -#include <linux/usb.h> -#include <linux/usb/serial.h> -#include <linux/serial.h> -#include <linux/wakelock.h> -#include "via_usb-wwan.h" - -#ifdef CONFIG_USB_ANDROID_RAWBULK -#include <linux/usb/rawbulk.h> -#endif - -#ifdef CONFIG_VIATELECOM_SYNC_CBP -#include <mach/viatel.h> -#define ASC_INTF_NUM (10) -atomic_t intf_pm_count[ASC_INTF_NUM]; - -#define EXPORT_SYMBOL(x) - - -static struct asc_config usb_tx_handle = { - .name = USB_TX_HD_NAME, - .gpio_wake = GPIO_VIATEL_USB_AP_WAKE_MDM, - .gpio_ready = GPIO_VIATEL_USB_MDM_RDY, - .polar = 1, -}; - -struct asc_config usb_rx_handle = { - .name = USB_RX_HD_NAME, - .gpio_wake = GPIO_VIATEL_USB_MDM_WAKE_AP, - .gpio_ready = GPIO_VIATEL_USB_AP_RDY, - .polar = 1, -}; - -static int usb_ap_sync_cbp_init(void) -{ - int i, ret = 0; - for(i = 0; i < ASC_INTF_NUM; i++){ - atomic_set(&intf_pm_count[i], 0); - } - asc_tx_register_handle(&usb_tx_handle); - asc_rx_register_handle(&usb_rx_handle); - return ret; -} - -//late_initcall(usb_ap_sync_cbp_init); - -static int cbp_usb_interface_notifier(int msg, void *data) - { - int index, ret = 0; - struct usb_interface * intf = (struct usb_interface *)data; - - if(!intf) { - printk(KERN_ERR "%s - usb find device interface error\n", __func__); - return -ENODEV; - } - - index = (int)intf->cur_altsetting->desc.bInterfaceNumber; - if(index < 0 || index > ASC_INTF_NUM){ - printk(KERN_ERR "%s - error interface index %d.\n", __func__, index); - return -ENODEV; - } - switch(msg){ - case ASC_NTF_RX_PREPARE: - //printk("%s:inft%d get cnt=%d", __FUNCTION__, index, atomic_read(&intf_pm_count[index])); - if(!atomic_read(&intf_pm_count[index])){ - if(!usb_autopm_get_interface(intf)){ - atomic_set(&intf_pm_count[index], 1); - } - } - asc_rx_confirm_ready(USB_RX_HD_NAME, !ret); - break; - - case ASC_NTF_RX_POST: - //printk("%s:inft%d put cnt=%d", __FUNCTION__, index, atomic_read(&intf_pm_count[index])); - if(atomic_read(&intf_pm_count[index])){ - usb_autopm_put_interface(intf); - atomic_set(&intf_pm_count[index], 0); - } - break; - default: - printk("%s unknow message %d\n", __FUNCTION__, msg); - } - - return ret; -} -static int cbp_usb_interface_add_user(struct usb_interface * intf) -{ - int index; - struct asc_infor user; - - if(!intf){ - return -EINVAL; - } - - index = (int)intf->cur_altsetting->desc.bInterfaceNumber; - memset(&user, 0, sizeof(user)); - user.notifier = cbp_usb_interface_notifier; - user.data = intf; - snprintf(user.name, ASC_NAME_LEN, "%s%d", USB_RX_USER_NAME, index); - return asc_rx_add_user(USB_RX_HD_NAME, &user); -} - -static void cbp_usb_interface_del_user(struct usb_interface * intf) -{ - int index; - char path[ASC_NAME_LEN]; - - if(!intf){ - return ; - } - - index = (int)intf->cur_altsetting->desc.bInterfaceNumber; - if(atomic_read(&intf_pm_count[index])){ - usb_autopm_put_interface_no_suspend(intf); - atomic_set(&intf_pm_count[index], 0); - } - memset(path, 0, ASC_NAME_LEN); - snprintf(path, ASC_NAME_LEN, "%s%d", ASC_PATH(USB_RX_HD_NAME, USB_RX_USER_NAME), index); - return asc_rx_del_user(path); -} -#endif - -static int debug; -extern struct wake_lock ets_wake_lock; - -static unsigned int dump_mask = 0; -module_param(dump_mask, uint, S_IRUGO | S_IWUSR); -MODULE_PARM_DESC(dump_mask, "Set data dump mask for each interface"); - -static void usb_wwan_dump_data(struct usb_interface *interface, - const char *str, const unsigned char *data, int size) { - int i; - int no_chars = 0; - int n = interface->cur_altsetting->desc.bInterfaceNumber; - - if (!(dump_mask & (1 << n))) - return; - - printk(KERN_DEBUG "usb_wwan: dump on interface#%d, %s: len = %d, chars = \"", - n, str, size); - for (i = 0; i < size; ++i) { - char c = data[i]; - if (c > 0x20 && c < 0x7e) { - printk("%c", c); - } else { - printk("."); - no_chars ++; - } - } - printk("\", data = "); - for (i = 0; i < size; ++i) { - printk("%.2x ", data[i]); - if (i > 7) - break; - } - if (size < 8) { - printk("\n"); - return; - } else if (i < size - 8) { - printk("... "); - i = size - 8; - } - for (; i < size; ++i) - printk("%.2x ", data[i]); - printk("\n"); -} - -void usb_wwan_dtr_rts(struct usb_serial_port *port, int on) -{ - struct usb_serial *serial = port->serial; - struct usb_wwan_port_private *portdata; - - struct usb_wwan_intf_private *intfdata; - - dbg("%s", __func__); - - intfdata = port->serial->private; - - if (!intfdata->send_setup) - return; - - portdata = usb_get_serial_port_data(port); - mutex_lock(&serial->disc_mutex); - portdata->rts_state = on; - portdata->dtr_state = on; - if (serial->dev) - intfdata->send_setup(port); - mutex_unlock(&serial->disc_mutex); -} -EXPORT_SYMBOL(usb_wwan_dtr_rts); - -void usb_wwan_set_termios(struct tty_struct *tty, - struct usb_serial_port *port, - struct ktermios *old_termios) -{ - struct usb_wwan_intf_private *intfdata = port->serial->private; - - dbg("%s", __func__); - - /* Doesn't support option setting */ - tty_termios_copy_hw(tty->termios, old_termios); - - if (intfdata->send_setup) - intfdata->send_setup(port); -} -EXPORT_SYMBOL(usb_wwan_set_termios); - -int usb_wwan_tiocmget(struct tty_struct *tty) -{ - struct usb_serial_port *port = tty->driver_data; - unsigned int value; - struct usb_wwan_port_private *portdata; - - portdata = usb_get_serial_port_data(port); - - value = ((portdata->rts_state) ? TIOCM_RTS : 0) | - ((portdata->dtr_state) ? TIOCM_DTR : 0) | - ((portdata->cts_state) ? TIOCM_CTS : 0) | - ((portdata->dsr_state) ? TIOCM_DSR : 0) | - ((portdata->dcd_state) ? TIOCM_CAR : 0) | - ((portdata->ri_state) ? TIOCM_RNG : 0); - - return value; -} -EXPORT_SYMBOL(usb_wwan_tiocmget); - -int usb_wwan_tiocmset(struct tty_struct *tty, - unsigned int set, unsigned int clear) -{ - struct usb_serial_port *port = tty->driver_data; - struct usb_wwan_port_private *portdata; - struct usb_wwan_intf_private *intfdata; - - portdata = usb_get_serial_port_data(port); - intfdata = port->serial->private; - - if (!intfdata->send_setup) - return -EINVAL; - - /* FIXME: what locks portdata fields ? */ - if (set & TIOCM_RTS) - portdata->rts_state = 1; - if (set & TIOCM_DTR) - portdata->dtr_state = 1; - - if (clear & TIOCM_RTS) - portdata->rts_state = 0; - if (clear & TIOCM_DTR) - portdata->dtr_state = 0; - return intfdata->send_setup(port); -} -EXPORT_SYMBOL(usb_wwan_tiocmset); - -static int get_serial_info(struct usb_serial_port *port, - struct serial_struct __user *retinfo) -{ - struct serial_struct tmp; - - if (!retinfo) - return -EFAULT; - - memset(&tmp, 0, sizeof(tmp)); - tmp.line = port->serial->minor; - tmp.port = port->number; - tmp.baud_base = tty_get_baud_rate(port->port.tty); - tmp.close_delay = port->port.close_delay / 10; - tmp.closing_wait = port->port.closing_wait == ASYNC_CLOSING_WAIT_NONE ? - ASYNC_CLOSING_WAIT_NONE : - port->port.closing_wait / 10; - - if (copy_to_user(retinfo, &tmp, sizeof(*retinfo))) - return -EFAULT; - return 0; -} - -static int set_serial_info(struct usb_serial_port *port, - struct serial_struct __user *newinfo) -{ - struct serial_struct new_serial; - unsigned int closing_wait, close_delay; - int retval = 0; - - if (copy_from_user(&new_serial, newinfo, sizeof(new_serial))) - return -EFAULT; - - close_delay = new_serial.close_delay * 10; - closing_wait = new_serial.closing_wait == ASYNC_CLOSING_WAIT_NONE ? - ASYNC_CLOSING_WAIT_NONE : new_serial.closing_wait * 10; - - mutex_lock(&port->port.mutex); - - if (!capable(CAP_SYS_ADMIN)) { - if ((close_delay != port->port.close_delay) || - (closing_wait != port->port.closing_wait)) - retval = -EPERM; - else - retval = -EOPNOTSUPP; - } else { - port->port.close_delay = close_delay; - port->port.closing_wait = closing_wait; - } - - mutex_unlock(&port->port.mutex); - return retval; -} - -int usb_wwan_ioctl(struct tty_struct *tty, - unsigned int cmd, unsigned long arg) -{ - struct usb_serial_port *port = tty->driver_data; - - dbg("%s cmd 0x%04x", __func__, cmd); - - switch (cmd) { - case TIOCGSERIAL: - return get_serial_info(port, - (struct serial_struct __user *) arg); - case TIOCSSERIAL: - return set_serial_info(port, - (struct serial_struct __user *) arg); - default: - break; - } - - dbg("%s arg not supported", __func__); - - return -ENOIOCTLCMD; -} -EXPORT_SYMBOL(usb_wwan_ioctl); - -/* Write */ -int usb_wwan_write(struct tty_struct *tty, struct usb_serial_port *port, - const unsigned char *buf, int count) -{ - struct usb_wwan_port_private *portdata; - struct usb_wwan_intf_private *intfdata; - int i; - int left, todo; - struct urb *this_urb = NULL; /* spurious */ - int err; - unsigned long flags; - - portdata = usb_get_serial_port_data(port); - intfdata = port->serial->private; - - dbg("%s: write (%d chars)", __func__, count); - -#ifdef CONFIG_VIATELECOM_SYNC_CBP - asc_tx_auto_ready(USB_TX_HD_NAME, 0); -#endif - - i = 0; - left = count; - for (i = 0; left > 0 && i < portdata->n_out_urb; i++) { - todo = left; - if (todo > portdata->out_buflen) - todo = portdata->out_buflen; - - this_urb = portdata->out_urbs[i]; - if (test_and_set_bit(i, &portdata->out_busy)) { - if (time_before(jiffies, - portdata->tx_start_time[i] + 10 * HZ)) - continue; - usb_unlink_urb(this_urb); - continue; - } - dbg("%s: endpoint %d buf %d", __func__, - usb_pipeendpoint(this_urb->pipe), i); - - err = usb_autopm_get_interface_async(port->serial->interface); - if (err < 0) - break; - - /* send the data */ - memcpy(this_urb->transfer_buffer, buf, todo); - this_urb->transfer_buffer_length = todo; - - spin_lock_irqsave(&intfdata->susp_lock, flags); - if (intfdata->suspended) { - usb_anchor_urb(this_urb, &portdata->delayed); - spin_unlock_irqrestore(&intfdata->susp_lock, flags); - } else { - intfdata->in_flight++; - spin_unlock_irqrestore(&intfdata->susp_lock, flags); - err = usb_submit_urb(this_urb, GFP_ATOMIC); - if (err) { - dbg("usb_submit_urb %p (write bulk) failed " - "(%d)", this_urb, err); - clear_bit(i, &portdata->out_busy); - spin_lock_irqsave(&intfdata->susp_lock, flags); - intfdata->in_flight--; - spin_unlock_irqrestore(&intfdata->susp_lock, - flags); - usb_autopm_put_interface_async(port->serial->interface); - break; - } - } - - portdata->tx_start_time[i] = jiffies; - buf += todo; - left -= todo; - } - - count -= left; - dbg("%s: wrote (did %d)", __func__, count); - return count; -} -EXPORT_SYMBOL(usb_wwan_write); - -static void usb_wwan_indat_callback(struct urb *urb) -{ - int err; - int endpoint; - struct usb_serial_port *port; - struct tty_struct *tty; - unsigned char *data = urb->transfer_buffer; - int status = urb->status; - - dbg("%s: %p", __func__, urb); - - endpoint = usb_pipeendpoint(urb->pipe); - port = urb->context; - - if (status) { - dbg("%s: nonzero status: %d on endpoint %02x.", - __func__, status, endpoint); - } else { - int inception = 0; - struct usb_wwan_port_private *portdata = usb_get_serial_port_data(port); -#ifdef CONFIG_USB_ANDROID_RAWBULK - spin_lock(&portdata->incept_lock); - inception = portdata->inception; - spin_unlock(&portdata->incept_lock); -#endif - if (inception) { -#ifdef CONFIG_USB_ANDROID_RAWBULK - struct usb_interface *interface = port->serial->interface; - int tid = interface->cur_altsetting->desc.bInterfaceNumber; - err = rawbulk_push_upstream_buffer(tid, data, urb->actual_length); - if (err < 0) - printk(KERN_DEBUG "failed to push data to rawbulk(%d) %d\n", tid, err); -#endif - } else { - usb_wwan_dump_data(port->serial->interface, "from device", data, - urb->actual_length); - tty = tty_port_tty_get(&port->port); - if (tty) { - if (urb->actual_length) { - tty_insert_flip_string(tty, data, - urb->actual_length); - tty_flip_buffer_push(tty); - } else - dbg("%s: empty read urb received", __func__); - tty_kref_put(tty); - } - } - - /* Resubmit urb so we continue receiving */ - if (status != -ESHUTDOWN) { - err = usb_submit_urb(urb, GFP_ATOMIC); - if (err) { - if (err != -EPERM) { - printk(KERN_ERR "%s: resubmit read urb failed. " - "(%d)", __func__, err); - /* busy also in error unless we are killed */ - usb_mark_last_busy(port->serial->dev); - } - } else { - usb_mark_last_busy(port->serial->dev); - } - } - - } -} - -static void usb_wwan_outdat_callback(struct urb *urb) -{ - struct usb_serial_port *port; - struct usb_wwan_port_private *portdata; - struct usb_wwan_intf_private *intfdata; - int i; - - dbg("%s", __func__); - - port = urb->context; - intfdata = port->serial->private; - usb_wwan_dump_data(port->serial->interface, urb->status < 0? - "failed sent to device": "to device", - urb->transfer_buffer, urb->transfer_buffer_length); - usb_serial_port_softint(port); - usb_autopm_put_interface_async(port->serial->interface); - portdata = usb_get_serial_port_data(port); - spin_lock(&intfdata->susp_lock); - intfdata->in_flight--; - spin_unlock(&intfdata->susp_lock); - - for (i = 0; i < portdata->n_out_urb; ++i) { - if (portdata->out_urbs[i] == urb) { - smp_mb__before_clear_bit(); - clear_bit(i, &portdata->out_busy); - break; - } - } -} - -int usb_wwan_write_room(struct tty_struct *tty) -{ - struct usb_serial_port *port = tty->driver_data; - struct usb_wwan_port_private *portdata; - int i; - int data_len = 0; - struct urb *this_urb; - - portdata = usb_get_serial_port_data(port); - - for (i = 0; i < portdata->n_out_urb; i++) { - this_urb = portdata->out_urbs[i]; - if (this_urb && !test_bit(i, &portdata->out_busy)) - data_len += portdata->out_buflen; - } - - dbg("%s: %d", __func__, data_len); - return data_len; -} -EXPORT_SYMBOL(usb_wwan_write_room); - -int usb_wwan_chars_in_buffer(struct tty_struct *tty) -{ - struct usb_serial_port *port = tty->driver_data; - struct usb_wwan_port_private *portdata; - int i; - int data_len = 0; - struct urb *this_urb; - - portdata = usb_get_serial_port_data(port); - - for (i = 0; i < portdata->n_out_urb; i++) { - this_urb = portdata->out_urbs[i]; - /* FIXME: This locking is insufficient as this_urb may - go unused during the test */ - if (this_urb && test_bit(i, &portdata->out_busy)) - data_len += this_urb->transfer_buffer_length; - } - dbg("%s: %d", __func__, data_len); - return data_len; -} -EXPORT_SYMBOL(usb_wwan_chars_in_buffer); - -static int port_to_infnum(struct usb_serial_port *port) -{ - struct usb_interface *interface = port->serial->interface; - int tid = interface->cur_altsetting->desc.bInterfaceNumber; - return tid; -} - -int usb_wwan_open(struct tty_struct *tty, struct usb_serial_port *port) -{ - struct usb_wwan_port_private *portdata; - struct usb_wwan_intf_private *intfdata; - struct usb_serial *serial = port->serial; - int i, err; - struct urb *urb; - - portdata = usb_get_serial_port_data(port); - intfdata = serial->private; - - dbg("%s", __func__); - -#if defined(CONFIG_VIATELECOM_SYNC_CBP) - cbp_usb_interface_add_user(serial->interface); -#endif - - /* Start reading from the IN endpoint */ - for (i = 0; i < portdata->n_in_urb; i++) { - urb = portdata->in_urbs[i]; - if (!urb) - continue; - err = usb_submit_urb(urb, GFP_KERNEL); - if (err) { - dbg("%s: submit urb %d failed (%d) %d", - __func__, i, err, urb->transfer_buffer_length); - } - } - - if (intfdata->send_setup) - intfdata->send_setup(port); - - serial->interface->needs_remote_wakeup = 0; - spin_lock_irq(&intfdata->susp_lock); - portdata->opened = 1; - spin_unlock_irq(&intfdata->susp_lock); - /* this balances a get in the generic USB serial code */ - if(port_to_infnum(port) == 1) - { - usb_autopm_get_interface(serial->interface); - wake_lock(&ets_wake_lock); - } - else - usb_autopm_put_interface(serial->interface); - - return 0; -} -EXPORT_SYMBOL(usb_wwan_open); - -void usb_wwan_close(struct usb_serial_port *port) -{ - int i; - struct usb_serial *serial = port->serial; - struct usb_wwan_port_private *portdata; - struct usb_wwan_intf_private *intfdata = port->serial->private; - - dbg("%s", __func__); - portdata = usb_get_serial_port_data(port); - - if (serial->dev) { -#if defined(CONFIG_VIATELECOM_SYNC_CBP) - cbp_usb_interface_del_user(serial->interface); -#endif - /* Stop reading/writing urbs */ - spin_lock_irq(&intfdata->susp_lock); - portdata->opened = 0; - spin_unlock_irq(&intfdata->susp_lock); - - for (i = 0; i < portdata->n_in_urb; i++) - usb_kill_urb(portdata->in_urbs[i]); - for (i = 0; i < portdata->n_out_urb; i++) - usb_kill_urb(portdata->out_urbs[i]); - /* balancing - important as an error cannot be handled*/ - if(port_to_infnum(port) == 1) - { - usb_autopm_put_interface(serial->interface); - wake_unlock(&ets_wake_lock); - } - else - usb_autopm_get_interface_no_resume(serial->interface); - serial->interface->needs_remote_wakeup = 0; - } -} -EXPORT_SYMBOL(usb_wwan_close); - -/* Helper functions used by usb_wwan_setup_urbs */ -static struct urb *usb_wwan_setup_urb(struct usb_serial *serial, int endpoint, - int dir, void *ctx, char *buf, int len, - void (*callback) (struct urb *)) -{ - struct urb *urb; - - if (endpoint == -1) - return NULL; /* endpoint not needed */ - - urb = usb_alloc_urb(0, GFP_KERNEL); /* No ISO */ - if (urb == NULL) { - dbg("%s: alloc for endpoint %d failed.", __func__, endpoint); - return NULL; - } - - /* Fill URB using supplied data. */ - usb_fill_bulk_urb(urb, serial->dev, - usb_sndbulkpipe(serial->dev, endpoint) | dir, - buf, len, callback, ctx); - - return urb; -} - -/* Setup urbs */ -static void usb_wwan_setup_urbs(struct usb_serial *serial) -{ - int i, j; - struct usb_serial_port *port; - struct usb_wwan_port_private *portdata; - - dbg("%s", __func__); - - for (i = 0; i < serial->num_ports; i++) { - port = serial->port[i]; - portdata = usb_get_serial_port_data(port); - - /* Do indat endpoints first */ - for (j = 0; j < portdata->n_in_urb; ++j) { - portdata->in_urbs[j] = usb_wwan_setup_urb(serial, - port-> - bulk_in_endpointAddress, - USB_DIR_IN, - port, - portdata->in_buffer[j], - portdata->in_buflen, - usb_wwan_indat_callback); - } - - /* outdat endpoints */ - for (j = 0; j < portdata->n_out_urb; ++j) { - portdata->out_urbs[j] = usb_wwan_setup_urb(serial, - port-> - bulk_out_endpointAddress, - USB_DIR_OUT, - port, - portdata->out_buffer[j], - portdata->out_buflen, - usb_wwan_outdat_callback); - } - } -} - -static struct _via_cbp_port_init_params { - unsigned int n_in_urb; - unsigned int n_out_urb; - unsigned int in_buflen; - unsigned int out_buflen; -} _cbp_init_params[] = { - { 16, 16, 4096, 4096 }, /* Data Port */ - { 4, 4, 4096, 4096 }, /* ETS */ - { 1, 1, 4096, 4096 }, /* AT Channel */ - { 1, 1, 4096, 4096 }, /* PCV */ - { 1, 1, 4096, 4096 }, /* GPS */ - { }, -}; - -int usb_wwan_startup(struct usb_serial *serial) -{ - int i, j, err; - struct usb_serial_port *port; - struct usb_wwan_port_private *portdata; - u8 *buffer; - - dbg("%s", __func__); - - /* Now setup per port private data */ - for (i = 0; i < serial->num_ports; i++) { - int nr; - port = serial->port[i]; - portdata = kzalloc(sizeof(*portdata), GFP_KERNEL); - if (!portdata) { - dbg("%s: kmalloc for usb_wwan_port_private (%d) failed!.", - __func__, i); - return 1; - } - init_usb_anchor(&portdata->delayed); - - //if (__le16_to_cpu(serial->dev->descriptor.idVendor) == 0x15eb && - // __le16_to_cpu(serial->dev->descriptor.idProduct) == 0x0001) { - nr = serial->interface->cur_altsetting->desc.bInterfaceNumber; - portdata->n_in_urb = min((int)_cbp_init_params[nr].n_in_urb, MAX_IN_URBS); - portdata->n_out_urb = min((int)_cbp_init_params[nr].n_out_urb, MAX_OUT_URBS); - portdata->in_buflen = _cbp_init_params[nr].in_buflen; - portdata->out_buflen = _cbp_init_params[nr].out_buflen; - //} else { - // portdata->n_in_urb = N_IN_URB; - // portdata->n_out_urb = N_OUT_URB; - // portdata->in_buflen = IN_BUFLEN; - // portdata->out_buflen = OUT_BUFLEN; - //} - - for (j = 0; j < portdata->n_in_urb; j++) { - buffer = (u8 *) __get_free_page(GFP_KERNEL); - if (!buffer) - goto bail_out_error; - portdata->in_buffer[j] = buffer; - portdata->in_buflen = PAGE_SIZE; - } - - for (j = 0; j < portdata->n_out_urb; j++) { - buffer = kmalloc(portdata->out_buflen, GFP_KERNEL); - if (!buffer) - goto bail_out_error2; - portdata->out_buffer[j] = buffer; - } - - usb_set_serial_port_data(port, portdata); - - if (!port->interrupt_in_urb) - continue; - err = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL); - if (err) - dbg("%s: submit irq_in urb failed %d", __func__, err); - } - usb_wwan_setup_urbs(serial); - return 0; - -bail_out_error2: - for (j = 0; j < portdata->n_out_urb; j++) - kfree(portdata->out_buffer[j]); -bail_out_error: - for (j = 0; j < portdata->n_in_urb; j++) - if (portdata->in_buffer[j]) - free_page((unsigned long)portdata->in_buffer[j]); - kfree(portdata); - return 1; -} -EXPORT_SYMBOL(usb_wwan_startup); - -static void stop_read_write_urbs(struct usb_serial *serial) -{ - int i, j; - struct usb_serial_port *port; - struct usb_wwan_port_private *portdata; - - /* Stop reading/writing urbs */ - for (i = 0; i < serial->num_ports; ++i) { - port = serial->port[i]; - portdata = usb_get_serial_port_data(port); - for (j = 0; j < portdata->n_in_urb; j++) - usb_kill_urb(portdata->in_urbs[j]); - for (j = 0; j < portdata->n_out_urb; j++) - usb_kill_urb(portdata->out_urbs[j]); - } -} - -void usb_wwan_disconnect(struct usb_serial *serial) -{ - dbg("%s", __func__); - stop_read_write_urbs(serial); -#if defined(CONFIG_VIATELECOM_SYNC_CBP) - cbp_usb_interface_del_user(serial->interface); -#endif -} -EXPORT_SYMBOL(usb_wwan_disconnect); - -void usb_wwan_release(struct usb_serial *serial) -{ - int i, j; - struct usb_serial_port *port; - struct usb_wwan_port_private *portdata; - - dbg("%s", __func__); - - /* Now free them */ - for (i = 0; i < serial->num_ports; ++i) { - port = serial->port[i]; - portdata = usb_get_serial_port_data(port); - - for (j = 0; j < portdata->n_in_urb; j++) { - usb_free_urb(portdata->in_urbs[j]); - free_page((unsigned long) - portdata->in_buffer[j]); - portdata->in_urbs[j] = NULL; - } - for (j = 0; j < portdata->n_out_urb; j++) { - usb_free_urb(portdata->out_urbs[j]); - kfree(portdata->out_buffer[j]); - portdata->out_urbs[j] = NULL; - } - } - - /* Now free per port private data */ - for (i = 0; i < serial->num_ports; i++) { - port = serial->port[i]; - kfree(usb_get_serial_port_data(port)); - } -} -EXPORT_SYMBOL(usb_wwan_release); - -#ifdef CONFIG_PM -int usb_wwan_suspend(struct usb_serial *serial, pm_message_t message) -{ - struct usb_wwan_intf_private *intfdata = serial->private; - int b; - - dbg("%s entered", __func__); - - if (PMSG_IS_AUTO(message)) { - spin_lock_irq(&intfdata->susp_lock); - b = intfdata->in_flight; - spin_unlock_irq(&intfdata->susp_lock); - - if (b) - return -EBUSY; - } - - spin_lock_irq(&intfdata->susp_lock); - intfdata->suspended = 1; - spin_unlock_irq(&intfdata->susp_lock); - stop_read_write_urbs(serial); - - return 0; -} -EXPORT_SYMBOL(usb_wwan_suspend); - -static void unbusy_queued_urb(struct urb *urb, struct usb_wwan_port_private *portdata) -{ - int i; - - for (i = 0; i < portdata->n_out_urb; i++) { - if (urb == portdata->out_urbs[i]) { - clear_bit(i, &portdata->out_busy); - break; - } - } -} - -static void play_delayed(struct usb_serial_port *port) -{ - struct usb_wwan_intf_private *data; - struct usb_wwan_port_private *portdata; - struct urb *urb; - int err; - - portdata = usb_get_serial_port_data(port); - data = port->serial->private; - while ((urb = usb_get_from_anchor(&portdata->delayed))) { - err = usb_submit_urb(urb, GFP_ATOMIC); - if (!err) { - data->in_flight++; - } else { - /* we have to throw away the rest */ - do { - unbusy_queued_urb(urb, portdata); - usb_autopm_put_interface_no_suspend(port->serial->interface); - } while ((urb = usb_get_from_anchor(&portdata->delayed))); - break; - } - } -} - -int usb_wwan_resume(struct usb_serial *serial) -{ - int i, j; - struct usb_serial_port *port; - struct usb_wwan_intf_private *intfdata = serial->private; - struct usb_wwan_port_private *portdata; - struct urb *urb; - int err = 0; - - dbg("%s entered", __func__); - /* get the interrupt URBs resubmitted unconditionally */ - for (i = 0; i < serial->num_ports; i++) { - port = serial->port[i]; - if (!port->interrupt_in_urb) { - dbg("%s: No interrupt URB for port %d", __func__, i); - continue; - } - err = usb_submit_urb(port->interrupt_in_urb, GFP_NOIO); - dbg("Submitted interrupt URB for port %d (result %d)", i, err); - if (err < 0) { - err("%s: Error %d for interrupt URB of port%d", - __func__, err, i); - goto err_out; - } - } - - for (i = 0; i < serial->num_ports; i++) { - /* walk all ports */ - port = serial->port[i]; - portdata = usb_get_serial_port_data(port); - - /* skip closed ports */ - spin_lock_irq(&intfdata->susp_lock); - if (!portdata->opened) { - spin_unlock_irq(&intfdata->susp_lock); - continue; - } - - for (j = 0; j < portdata->n_in_urb; j++) { - urb = portdata->in_urbs[j]; - err = usb_submit_urb(urb, GFP_ATOMIC); - if (err < 0) { - err("%s: Error %d for bulk URB %d", - __func__, err, i); - spin_unlock_irq(&intfdata->susp_lock); - goto err_out; - } - } - play_delayed(port); - spin_unlock_irq(&intfdata->susp_lock); - } - spin_lock_irq(&intfdata->susp_lock); - intfdata->suspended = 0; - spin_unlock_irq(&intfdata->susp_lock); -err_out: - return err; -} -EXPORT_SYMBOL(usb_wwan_resume); -#endif - -MODULE_AUTHOR(DRIVER_AUTHOR); -MODULE_DESCRIPTION(DRIVER_DESC); -MODULE_VERSION(DRIVER_VERSION); -MODULE_LICENSE("GPL"); - -module_param(debug, bool, S_IRUGO | S_IWUSR); -MODULE_PARM_DESC(debug, "Debug messages"); diff --git a/ANDROID_3.4.5/drivers/usb/serial/visor.c b/ANDROID_3.4.5/drivers/usb/serial/visor.c deleted file mode 100644 index 71d69647..00000000 --- a/ANDROID_3.4.5/drivers/usb/serial/visor.c +++ /dev/null @@ -1,716 +0,0 @@ -/* - * USB HandSpring Visor, Palm m50x, and Sony Clie driver - * (supports all of the Palm OS USB devices) - * - * Copyright (C) 1999 - 2004 - * Greg Kroah-Hartman (greg@kroah.com) - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License version - * 2 as published by the Free Software Foundation. - * - * See Documentation/usb/usb-serial.txt for more information on using this - * driver - * - */ - -#include <linux/kernel.h> -#include <linux/errno.h> -#include <linux/init.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/moduleparam.h> -#include <linux/spinlock.h> -#include <linux/uaccess.h> -#include <linux/usb.h> -#include <linux/usb/serial.h> -#include <linux/usb/cdc.h> -#include "visor.h" - -/* - * Version Information - */ -#define DRIVER_AUTHOR "Greg Kroah-Hartman <greg@kroah.com>" -#define DRIVER_DESC "USB HandSpring Visor / Palm OS driver" - -/* function prototypes for a handspring visor */ -static int visor_open(struct tty_struct *tty, struct usb_serial_port *port); -static void visor_close(struct usb_serial_port *port); -static int visor_probe(struct usb_serial *serial, - const struct usb_device_id *id); -static int visor_calc_num_ports(struct usb_serial *serial); -static void visor_read_int_callback(struct urb *urb); -static int clie_3_5_startup(struct usb_serial *serial); -static int treo_attach(struct usb_serial *serial); -static int clie_5_attach(struct usb_serial *serial); -static int palm_os_3_probe(struct usb_serial *serial, - const struct usb_device_id *id); -static int palm_os_4_probe(struct usb_serial *serial, - const struct usb_device_id *id); - -/* Parameters that may be passed into the module. */ -static bool debug; -static __u16 vendor; -static __u16 product; - -static struct usb_device_id id_table [] = { - { USB_DEVICE(HANDSPRING_VENDOR_ID, HANDSPRING_VISOR_ID), - .driver_info = (kernel_ulong_t)&palm_os_3_probe }, - { USB_DEVICE(HANDSPRING_VENDOR_ID, HANDSPRING_TREO_ID), - .driver_info = (kernel_ulong_t)&palm_os_4_probe }, - { USB_DEVICE(HANDSPRING_VENDOR_ID, HANDSPRING_TREO600_ID), - .driver_info = (kernel_ulong_t)&palm_os_4_probe }, - { USB_DEVICE(GSPDA_VENDOR_ID, GSPDA_XPLORE_M68_ID), - .driver_info = (kernel_ulong_t)&palm_os_4_probe }, - { USB_DEVICE(PALM_VENDOR_ID, PALM_M500_ID), - .driver_info = (kernel_ulong_t)&palm_os_4_probe }, - { USB_DEVICE(PALM_VENDOR_ID, PALM_M505_ID), - .driver_info = (kernel_ulong_t)&palm_os_4_probe }, - { USB_DEVICE(PALM_VENDOR_ID, PALM_M515_ID), - .driver_info = (kernel_ulong_t)&palm_os_4_probe }, - { USB_DEVICE(PALM_VENDOR_ID, PALM_I705_ID), - .driver_info = (kernel_ulong_t)&palm_os_4_probe }, - { USB_DEVICE(PALM_VENDOR_ID, PALM_M100_ID), - .driver_info = (kernel_ulong_t)&palm_os_4_probe }, - { USB_DEVICE(PALM_VENDOR_ID, PALM_M125_ID), - .driver_info = (kernel_ulong_t)&palm_os_4_probe }, - { USB_DEVICE(PALM_VENDOR_ID, PALM_M130_ID), - .driver_info = (kernel_ulong_t)&palm_os_4_probe }, - { USB_DEVICE(PALM_VENDOR_ID, PALM_TUNGSTEN_T_ID), - .driver_info = (kernel_ulong_t)&palm_os_4_probe }, - { USB_DEVICE(PALM_VENDOR_ID, PALM_TREO_650), - .driver_info = (kernel_ulong_t)&palm_os_4_probe }, - { USB_DEVICE(PALM_VENDOR_ID, PALM_TUNGSTEN_Z_ID), - .driver_info = (kernel_ulong_t)&palm_os_4_probe }, - { USB_DEVICE(PALM_VENDOR_ID, PALM_ZIRE_ID), - .driver_info = (kernel_ulong_t)&palm_os_4_probe }, - { USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_4_0_ID), - .driver_info = (kernel_ulong_t)&palm_os_4_probe }, - { USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_S360_ID), - .driver_info = (kernel_ulong_t)&palm_os_4_probe }, - { USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_4_1_ID), - .driver_info = (kernel_ulong_t)&palm_os_4_probe }, - { USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_NX60_ID), - .driver_info = (kernel_ulong_t)&palm_os_4_probe }, - { USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_NZ90V_ID), - .driver_info = (kernel_ulong_t)&palm_os_4_probe }, - { USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_TJ25_ID), - .driver_info = (kernel_ulong_t)&palm_os_4_probe }, - { USB_DEVICE(ACER_VENDOR_ID, ACER_S10_ID), - .driver_info = (kernel_ulong_t)&palm_os_4_probe }, - { USB_DEVICE(SAMSUNG_VENDOR_ID, SAMSUNG_SCH_I330_ID), - .driver_info = (kernel_ulong_t)&palm_os_4_probe }, - { USB_DEVICE(SAMSUNG_VENDOR_ID, SAMSUNG_SPH_I500_ID), - .driver_info = (kernel_ulong_t)&palm_os_4_probe }, - { USB_DEVICE(TAPWAVE_VENDOR_ID, TAPWAVE_ZODIAC_ID), - .driver_info = (kernel_ulong_t)&palm_os_4_probe }, - { USB_DEVICE(GARMIN_VENDOR_ID, GARMIN_IQUE_3600_ID), - .driver_info = (kernel_ulong_t)&palm_os_4_probe }, - { USB_DEVICE(ACEECA_VENDOR_ID, ACEECA_MEZ1000_ID), - .driver_info = (kernel_ulong_t)&palm_os_4_probe }, - { USB_DEVICE(KYOCERA_VENDOR_ID, KYOCERA_7135_ID), - .driver_info = (kernel_ulong_t)&palm_os_4_probe }, - { USB_DEVICE(FOSSIL_VENDOR_ID, FOSSIL_ABACUS_ID), - .driver_info = (kernel_ulong_t)&palm_os_4_probe }, - { }, /* optional parameter entry */ - { } /* Terminating entry */ -}; - -static struct usb_device_id clie_id_5_table [] = { - { USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_UX50_ID), - .driver_info = (kernel_ulong_t)&palm_os_4_probe }, - { }, /* optional parameter entry */ - { } /* Terminating entry */ -}; - -static struct usb_device_id clie_id_3_5_table [] = { - { USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_3_5_ID) }, - { } /* Terminating entry */ -}; - -static struct usb_device_id id_table_combined [] = { - { USB_DEVICE(HANDSPRING_VENDOR_ID, HANDSPRING_VISOR_ID) }, - { USB_DEVICE(HANDSPRING_VENDOR_ID, HANDSPRING_TREO_ID) }, - { USB_DEVICE(HANDSPRING_VENDOR_ID, HANDSPRING_TREO600_ID) }, - { USB_DEVICE(GSPDA_VENDOR_ID, GSPDA_XPLORE_M68_ID) }, - { USB_DEVICE(PALM_VENDOR_ID, PALM_M500_ID) }, - { USB_DEVICE(PALM_VENDOR_ID, PALM_M505_ID) }, - { USB_DEVICE(PALM_VENDOR_ID, PALM_M515_ID) }, - { USB_DEVICE(PALM_VENDOR_ID, PALM_I705_ID) }, - { USB_DEVICE(PALM_VENDOR_ID, PALM_M100_ID) }, - { USB_DEVICE(PALM_VENDOR_ID, PALM_M125_ID) }, - { USB_DEVICE(PALM_VENDOR_ID, PALM_M130_ID) }, - { USB_DEVICE(PALM_VENDOR_ID, PALM_TUNGSTEN_T_ID) }, - { USB_DEVICE(PALM_VENDOR_ID, PALM_TREO_650) }, - { USB_DEVICE(PALM_VENDOR_ID, PALM_TUNGSTEN_Z_ID) }, - { USB_DEVICE(PALM_VENDOR_ID, PALM_ZIRE_ID) }, - { USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_3_5_ID) }, - { USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_4_0_ID) }, - { USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_S360_ID) }, - { USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_4_1_ID) }, - { USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_NX60_ID) }, - { USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_NZ90V_ID) }, - { USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_UX50_ID) }, - { USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_TJ25_ID) }, - { USB_DEVICE(SAMSUNG_VENDOR_ID, SAMSUNG_SCH_I330_ID) }, - { USB_DEVICE(SAMSUNG_VENDOR_ID, SAMSUNG_SPH_I500_ID) }, - { USB_DEVICE(TAPWAVE_VENDOR_ID, TAPWAVE_ZODIAC_ID) }, - { USB_DEVICE(GARMIN_VENDOR_ID, GARMIN_IQUE_3600_ID) }, - { USB_DEVICE(ACEECA_VENDOR_ID, ACEECA_MEZ1000_ID) }, - { USB_DEVICE(KYOCERA_VENDOR_ID, KYOCERA_7135_ID) }, - { USB_DEVICE(FOSSIL_VENDOR_ID, FOSSIL_ABACUS_ID) }, - { }, /* optional parameter entry */ - { } /* Terminating entry */ -}; - -MODULE_DEVICE_TABLE(usb, id_table_combined); - -static struct usb_driver visor_driver = { - .name = "visor", - .probe = usb_serial_probe, - .disconnect = usb_serial_disconnect, - .id_table = id_table_combined, -}; - -/* All of the device info needed for the Handspring Visor, - and Palm 4.0 devices */ -static struct usb_serial_driver handspring_device = { - .driver = { - .owner = THIS_MODULE, - .name = "visor", - }, - .description = "Handspring Visor / Palm OS", - .id_table = id_table, - .num_ports = 2, - .bulk_out_size = 256, - .open = visor_open, - .close = visor_close, - .throttle = usb_serial_generic_throttle, - .unthrottle = usb_serial_generic_unthrottle, - .attach = treo_attach, - .probe = visor_probe, - .calc_num_ports = visor_calc_num_ports, - .read_int_callback = visor_read_int_callback, -}; - -/* All of the device info needed for the Clie UX50, TH55 Palm 5.0 devices */ -static struct usb_serial_driver clie_5_device = { - .driver = { - .owner = THIS_MODULE, - .name = "clie_5", - }, - .description = "Sony Clie 5.0", - .id_table = clie_id_5_table, - .num_ports = 2, - .bulk_out_size = 256, - .open = visor_open, - .close = visor_close, - .throttle = usb_serial_generic_throttle, - .unthrottle = usb_serial_generic_unthrottle, - .attach = clie_5_attach, - .probe = visor_probe, - .calc_num_ports = visor_calc_num_ports, - .read_int_callback = visor_read_int_callback, -}; - -/* device info for the Sony Clie OS version 3.5 */ -static struct usb_serial_driver clie_3_5_device = { - .driver = { - .owner = THIS_MODULE, - .name = "clie_3.5", - }, - .description = "Sony Clie 3.5", - .id_table = clie_id_3_5_table, - .num_ports = 1, - .bulk_out_size = 256, - .open = visor_open, - .close = visor_close, - .throttle = usb_serial_generic_throttle, - .unthrottle = usb_serial_generic_unthrottle, - .attach = clie_3_5_startup, -}; - -static struct usb_serial_driver * const serial_drivers[] = { - &handspring_device, &clie_5_device, &clie_3_5_device, NULL -}; - -/****************************************************************************** - * Handspring Visor specific driver functions - ******************************************************************************/ -static int visor_open(struct tty_struct *tty, struct usb_serial_port *port) -{ - int result = 0; - - dbg("%s - port %d", __func__, port->number); - - if (!port->read_urb) { - /* this is needed for some brain dead Sony devices */ - dev_err(&port->dev, "Device lied about number of ports, please use a lower one.\n"); - return -ENODEV; - } - - /* Start reading from the device */ - result = usb_serial_generic_open(tty, port); - if (result) - goto exit; - - if (port->interrupt_in_urb) { - dbg("%s - adding interrupt input for treo", __func__); - result = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL); - if (result) - dev_err(&port->dev, - "%s - failed submitting interrupt urb, error %d\n", - __func__, result); - } -exit: - return result; -} - - -static void visor_close(struct usb_serial_port *port) -{ - unsigned char *transfer_buffer; - - dbg("%s - port %d", __func__, port->number); - - /* shutdown our urbs */ - usb_serial_generic_close(port); - usb_kill_urb(port->interrupt_in_urb); - - mutex_lock(&port->serial->disc_mutex); - if (!port->serial->disconnected) { - /* Try to send shutdown message, unless the device is gone */ - transfer_buffer = kmalloc(0x12, GFP_KERNEL); - if (transfer_buffer) { - usb_control_msg(port->serial->dev, - usb_rcvctrlpipe(port->serial->dev, 0), - VISOR_CLOSE_NOTIFICATION, 0xc2, - 0x0000, 0x0000, - transfer_buffer, 0x12, 300); - kfree(transfer_buffer); - } - } - mutex_unlock(&port->serial->disc_mutex); -} - -static void visor_read_int_callback(struct urb *urb) -{ - struct usb_serial_port *port = urb->context; - int status = urb->status; - int result; - - switch (status) { - case 0: - /* success */ - break; - case -ECONNRESET: - case -ENOENT: - case -ESHUTDOWN: - /* this urb is terminated, clean up */ - dbg("%s - urb shutting down with status: %d", - __func__, status); - return; - default: - dbg("%s - nonzero urb status received: %d", - __func__, status); - goto exit; - } - - /* - * This information is still unknown what it can be used for. - * If anyone has an idea, please let the author know... - * - * Rumor has it this endpoint is used to notify when data - * is ready to be read from the bulk ones. - */ - usb_serial_debug_data(debug, &port->dev, __func__, - urb->actual_length, urb->transfer_buffer); - -exit: - result = usb_submit_urb(urb, GFP_ATOMIC); - if (result) - dev_err(&urb->dev->dev, - "%s - Error %d submitting interrupt urb\n", - __func__, result); -} - -static int palm_os_3_probe(struct usb_serial *serial, - const struct usb_device_id *id) -{ - struct device *dev = &serial->dev->dev; - struct visor_connection_info *connection_info; - unsigned char *transfer_buffer; - char *string; - int retval = 0; - int i; - int num_ports = 0; - - dbg("%s", __func__); - - transfer_buffer = kmalloc(sizeof(*connection_info), GFP_KERNEL); - if (!transfer_buffer) { - dev_err(dev, "%s - kmalloc(%Zd) failed.\n", __func__, - sizeof(*connection_info)); - return -ENOMEM; - } - - /* send a get connection info request */ - retval = usb_control_msg(serial->dev, - usb_rcvctrlpipe(serial->dev, 0), - VISOR_GET_CONNECTION_INFORMATION, - 0xc2, 0x0000, 0x0000, transfer_buffer, - sizeof(*connection_info), 300); - if (retval < 0) { - dev_err(dev, "%s - error %d getting connection information\n", - __func__, retval); - goto exit; - } - - if (retval == sizeof(*connection_info)) { - connection_info = (struct visor_connection_info *) - transfer_buffer; - - num_ports = le16_to_cpu(connection_info->num_ports); - for (i = 0; i < num_ports; ++i) { - switch ( - connection_info->connections[i].port_function_id) { - case VISOR_FUNCTION_GENERIC: - string = "Generic"; - break; - case VISOR_FUNCTION_DEBUGGER: - string = "Debugger"; - break; - case VISOR_FUNCTION_HOTSYNC: - string = "HotSync"; - break; - case VISOR_FUNCTION_CONSOLE: - string = "Console"; - break; - case VISOR_FUNCTION_REMOTE_FILE_SYS: - string = "Remote File System"; - break; - default: - string = "unknown"; - break; - } - dev_info(dev, "%s: port %d, is for %s use\n", - serial->type->description, - connection_info->connections[i].port, string); - } - } - /* - * Handle devices that report invalid stuff here. - */ - if (num_ports == 0 || num_ports > 2) { - dev_warn(dev, "%s: No valid connect info available\n", - serial->type->description); - num_ports = 2; - } - - dev_info(dev, "%s: Number of ports: %d\n", serial->type->description, - num_ports); - - /* - * save off our num_ports info so that we can use it in the - * calc_num_ports callback - */ - usb_set_serial_data(serial, (void *)(long)num_ports); - - /* ask for the number of bytes available, but ignore the - response as it is broken */ - retval = usb_control_msg(serial->dev, - usb_rcvctrlpipe(serial->dev, 0), - VISOR_REQUEST_BYTES_AVAILABLE, - 0xc2, 0x0000, 0x0005, transfer_buffer, - 0x02, 300); - if (retval < 0) - dev_err(dev, "%s - error %d getting bytes available request\n", - __func__, retval); - retval = 0; - -exit: - kfree(transfer_buffer); - - return retval; -} - -static int palm_os_4_probe(struct usb_serial *serial, - const struct usb_device_id *id) -{ - struct device *dev = &serial->dev->dev; - struct palm_ext_connection_info *connection_info; - unsigned char *transfer_buffer; - int retval; - - dbg("%s", __func__); - - transfer_buffer = kmalloc(sizeof(*connection_info), GFP_KERNEL); - if (!transfer_buffer) { - dev_err(dev, "%s - kmalloc(%Zd) failed.\n", __func__, - sizeof(*connection_info)); - return -ENOMEM; - } - - retval = usb_control_msg(serial->dev, - usb_rcvctrlpipe(serial->dev, 0), - PALM_GET_EXT_CONNECTION_INFORMATION, - 0xc2, 0x0000, 0x0000, transfer_buffer, - sizeof(*connection_info), 300); - if (retval < 0) - dev_err(dev, "%s - error %d getting connection info\n", - __func__, retval); - else - usb_serial_debug_data(debug, &serial->dev->dev, __func__, - retval, transfer_buffer); - - kfree(transfer_buffer); - return 0; -} - - -static int visor_probe(struct usb_serial *serial, - const struct usb_device_id *id) -{ - int retval = 0; - int (*startup)(struct usb_serial *serial, - const struct usb_device_id *id); - - dbg("%s", __func__); - - /* - * some Samsung Android phones in modem mode have the same ID - * as SPH-I500, but they are ACM devices, so dont bind to them - */ - if (id->idVendor == SAMSUNG_VENDOR_ID && - id->idProduct == SAMSUNG_SPH_I500_ID && - serial->dev->descriptor.bDeviceClass == USB_CLASS_COMM && - serial->dev->descriptor.bDeviceSubClass == - USB_CDC_SUBCLASS_ACM) - return -ENODEV; - - if (serial->dev->actconfig->desc.bConfigurationValue != 1) { - dev_err(&serial->dev->dev, "active config #%d != 1 ??\n", - serial->dev->actconfig->desc.bConfigurationValue); - return -ENODEV; - } - - if (id->driver_info) { - startup = (void *)id->driver_info; - retval = startup(serial, id); - } - - return retval; -} - -static int visor_calc_num_ports(struct usb_serial *serial) -{ - int num_ports = (int)(long)(usb_get_serial_data(serial)); - - if (num_ports) - usb_set_serial_data(serial, NULL); - - return num_ports; -} - -static int clie_3_5_startup(struct usb_serial *serial) -{ - struct device *dev = &serial->dev->dev; - int result; - u8 *data; - - dbg("%s", __func__); - - data = kmalloc(1, GFP_KERNEL); - if (!data) - return -ENOMEM; - - /* - * Note that PEG-300 series devices expect the following two calls. - */ - - /* get the config number */ - result = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0), - USB_REQ_GET_CONFIGURATION, USB_DIR_IN, - 0, 0, data, 1, 3000); - if (result < 0) { - dev_err(dev, "%s: get config number failed: %d\n", - __func__, result); - goto out; - } - if (result != 1) { - dev_err(dev, "%s: get config number bad return length: %d\n", - __func__, result); - result = -EIO; - goto out; - } - - /* get the interface number */ - result = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0), - USB_REQ_GET_INTERFACE, - USB_DIR_IN | USB_RECIP_INTERFACE, - 0, 0, data, 1, 3000); - if (result < 0) { - dev_err(dev, "%s: get interface number failed: %d\n", - __func__, result); - goto out; - } - if (result != 1) { - dev_err(dev, - "%s: get interface number bad return length: %d\n", - __func__, result); - result = -EIO; - goto out; - } - - result = 0; -out: - kfree(data); - - return result; -} - -static int treo_attach(struct usb_serial *serial) -{ - struct usb_serial_port *swap_port; - - /* Only do this endpoint hack for the Handspring devices with - * interrupt in endpoints, which for now are the Treo devices. */ - if (!((le16_to_cpu(serial->dev->descriptor.idVendor) - == HANDSPRING_VENDOR_ID) || - (le16_to_cpu(serial->dev->descriptor.idVendor) - == KYOCERA_VENDOR_ID)) || - (serial->num_interrupt_in == 0)) - return 0; - - dbg("%s", __func__); - - /* - * It appears that Treos and Kyoceras want to use the - * 1st bulk in endpoint to communicate with the 2nd bulk out endpoint, - * so let's swap the 1st and 2nd bulk in and interrupt endpoints. - * Note that swapping the bulk out endpoints would break lots of - * apps that want to communicate on the second port. - */ -#define COPY_PORT(dest, src) \ - do { \ - dest->read_urb = src->read_urb; \ - dest->bulk_in_endpointAddress = src->bulk_in_endpointAddress;\ - dest->bulk_in_buffer = src->bulk_in_buffer; \ - dest->interrupt_in_urb = src->interrupt_in_urb; \ - dest->interrupt_in_endpointAddress = \ - src->interrupt_in_endpointAddress;\ - dest->interrupt_in_buffer = src->interrupt_in_buffer; \ - } while (0); - - swap_port = kmalloc(sizeof(*swap_port), GFP_KERNEL); - if (!swap_port) - return -ENOMEM; - COPY_PORT(swap_port, serial->port[0]); - COPY_PORT(serial->port[0], serial->port[1]); - COPY_PORT(serial->port[1], swap_port); - kfree(swap_port); - - return 0; -} - -static int clie_5_attach(struct usb_serial *serial) -{ - struct usb_serial_port *port; - unsigned int pipe; - int j; - - dbg("%s", __func__); - - /* TH55 registers 2 ports. - Communication in from the UX50/TH55 uses bulk_in_endpointAddress - from port 0. Communication out to the UX50/TH55 uses - bulk_out_endpointAddress from port 1 - - Lets do a quick and dirty mapping - */ - - /* some sanity check */ - if (serial->num_ports < 2) - return -1; - - /* port 0 now uses the modified endpoint Address */ - port = serial->port[0]; - port->bulk_out_endpointAddress = - serial->port[1]->bulk_out_endpointAddress; - - pipe = usb_sndbulkpipe(serial->dev, port->bulk_out_endpointAddress); - for (j = 0; j < ARRAY_SIZE(port->write_urbs); ++j) - port->write_urbs[j]->pipe = pipe; - - return 0; -} - -static int __init visor_init(void) -{ - int i, retval; - /* Only if parameters were passed to us */ - if (vendor > 0 && product > 0) { - struct usb_device_id usb_dev_temp[] = { - { - USB_DEVICE(vendor, product), - .driver_info = - (kernel_ulong_t) &palm_os_4_probe - } - }; - - /* Find the last entry in id_table */ - for (i = 0;; i++) { - if (id_table[i].idVendor == 0) { - id_table[i] = usb_dev_temp[0]; - break; - } - } - /* Find the last entry in id_table_combined */ - for (i = 0;; i++) { - if (id_table_combined[i].idVendor == 0) { - id_table_combined[i] = usb_dev_temp[0]; - break; - } - } - printk(KERN_INFO KBUILD_MODNAME - ": Untested USB device specified at time of module insertion\n"); - printk(KERN_INFO KBUILD_MODNAME - ": Warning: This is not guaranteed to work\n"); - printk(KERN_INFO KBUILD_MODNAME - ": Using a newer kernel is preferred to this method\n"); - printk(KERN_INFO KBUILD_MODNAME - ": Adding Palm OS protocol 4.x support for unknown device: 0x%x/0x%x\n", - vendor, product); - } - - retval = usb_serial_register_drivers(&visor_driver, serial_drivers); - if (retval == 0) - printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_DESC "\n"); - return retval; -} - - -static void __exit visor_exit (void) -{ - usb_serial_deregister_drivers(&visor_driver, serial_drivers); -} - - -module_init(visor_init); -module_exit(visor_exit); - -MODULE_AUTHOR(DRIVER_AUTHOR); -MODULE_DESCRIPTION(DRIVER_DESC); -MODULE_LICENSE("GPL"); - -module_param(debug, bool, S_IRUGO | S_IWUSR); -MODULE_PARM_DESC(debug, "Debug enabled or not"); - -module_param(vendor, ushort, 0); -MODULE_PARM_DESC(vendor, "User specified vendor ID"); -module_param(product, ushort, 0); -MODULE_PARM_DESC(product, "User specified product ID"); - diff --git a/ANDROID_3.4.5/drivers/usb/serial/visor.h b/ANDROID_3.4.5/drivers/usb/serial/visor.h deleted file mode 100644 index 88db4d06..00000000 --- a/ANDROID_3.4.5/drivers/usb/serial/visor.h +++ /dev/null @@ -1,161 +0,0 @@ -/* - * USB HandSpring Visor driver - * - * Copyright (C) 1999 - 2003 - * Greg Kroah-Hartman (greg@kroah.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. - * - * See Documentation/usb/usb-serial.txt for more information on using this - * driver. - * - */ - -#ifndef __LINUX_USB_SERIAL_VISOR_H -#define __LINUX_USB_SERIAL_VISOR_H - - -#define HANDSPRING_VENDOR_ID 0x082d -#define HANDSPRING_VISOR_ID 0x0100 -#define HANDSPRING_TREO_ID 0x0200 -#define HANDSPRING_TREO600_ID 0x0300 - -#define PALM_VENDOR_ID 0x0830 -#define PALM_M500_ID 0x0001 -#define PALM_M505_ID 0x0002 -#define PALM_M515_ID 0x0003 -#define PALM_I705_ID 0x0020 -#define PALM_M125_ID 0x0040 -#define PALM_M130_ID 0x0050 -#define PALM_TUNGSTEN_T_ID 0x0060 -#define PALM_TREO_650 0x0061 -#define PALM_TUNGSTEN_Z_ID 0x0031 -#define PALM_ZIRE_ID 0x0070 -#define PALM_M100_ID 0x0080 - -#define GSPDA_VENDOR_ID 0x115e -#define GSPDA_XPLORE_M68_ID 0xf100 - -#define SONY_VENDOR_ID 0x054C -#define SONY_CLIE_3_5_ID 0x0038 -#define SONY_CLIE_4_0_ID 0x0066 -#define SONY_CLIE_S360_ID 0x0095 -#define SONY_CLIE_4_1_ID 0x009A -#define SONY_CLIE_NX60_ID 0x00DA -#define SONY_CLIE_NZ90V_ID 0x00E9 -#define SONY_CLIE_UX50_ID 0x0144 -#define SONY_CLIE_TJ25_ID 0x0169 - -#define ACER_VENDOR_ID 0x0502 -#define ACER_S10_ID 0x0001 - -#define SAMSUNG_VENDOR_ID 0x04E8 -#define SAMSUNG_SCH_I330_ID 0x8001 -#define SAMSUNG_SPH_I500_ID 0x6601 - -#define TAPWAVE_VENDOR_ID 0x12EF -#define TAPWAVE_ZODIAC_ID 0x0100 - -#define GARMIN_VENDOR_ID 0x091E -#define GARMIN_IQUE_3600_ID 0x0004 - -#define ACEECA_VENDOR_ID 0x4766 -#define ACEECA_MEZ1000_ID 0x0001 - -#define KYOCERA_VENDOR_ID 0x0C88 -#define KYOCERA_7135_ID 0x0021 - -#define FOSSIL_VENDOR_ID 0x0E67 -#define FOSSIL_ABACUS_ID 0x0002 - -/**************************************************************************** - * Handspring Visor Vendor specific request codes (bRequest values) - * A big thank you to Handspring for providing the following information. - * If anyone wants the original file where these values and structures came - * from, send email to <greg@kroah.com>. - ****************************************************************************/ - -/**************************************************************************** - * VISOR_REQUEST_BYTES_AVAILABLE asks the visor for the number of bytes that - * are available to be transferred to the host for the specified endpoint. - * Currently this is not used, and always returns 0x0001 - ****************************************************************************/ -#define VISOR_REQUEST_BYTES_AVAILABLE 0x01 - -/**************************************************************************** - * VISOR_CLOSE_NOTIFICATION is set to the device to notify it that the host - * is now closing the pipe. An empty packet is sent in response. - ****************************************************************************/ -#define VISOR_CLOSE_NOTIFICATION 0x02 - -/**************************************************************************** - * VISOR_GET_CONNECTION_INFORMATION is sent by the host during enumeration to - * get the endpoints used by the connection. - ****************************************************************************/ -#define VISOR_GET_CONNECTION_INFORMATION 0x03 - - -/**************************************************************************** - * VISOR_GET_CONNECTION_INFORMATION returns data in the following format - ****************************************************************************/ -struct visor_connection_info { - __le16 num_ports; - struct { - __u8 port_function_id; - __u8 port; - } connections[2]; -}; - - -/* struct visor_connection_info.connection[x].port defines: */ -#define VISOR_ENDPOINT_1 0x01 -#define VISOR_ENDPOINT_2 0x02 - -/* struct visor_connection_info.connection[x].port_function_id defines: */ -#define VISOR_FUNCTION_GENERIC 0x00 -#define VISOR_FUNCTION_DEBUGGER 0x01 -#define VISOR_FUNCTION_HOTSYNC 0x02 -#define VISOR_FUNCTION_CONSOLE 0x03 -#define VISOR_FUNCTION_REMOTE_FILE_SYS 0x04 - - -/**************************************************************************** - * PALM_GET_SOME_UNKNOWN_INFORMATION is sent by the host during enumeration to - * get some information from the M series devices, that is currently unknown. - ****************************************************************************/ -#define PALM_GET_EXT_CONNECTION_INFORMATION 0x04 - -/** - * struct palm_ext_connection_info - return data from a PALM_GET_EXT_CONNECTION_INFORMATION request - * @num_ports: maximum number of functions/connections in use - * @endpoint_numbers_different: will be 1 if in and out endpoints numbers are - * different, otherwise it is 0. If value is 1, then - * connections.end_point_info is non-zero. If value is 0, then - * connections.port contains the endpoint number, which is the same for in - * and out. - * @port_function_id: contains the creator id of the applicaton that opened - * this connection. - * @port: contains the in/out endpoint number. Is 0 if in and out endpoint - * numbers are different. - * @end_point_info: high nubbe is in endpoint and low nibble will indicate out - * endpoint. Is 0 if in and out endpoints are the same. - * - * The maximum number of connections currently supported is 2 - */ -struct palm_ext_connection_info { - __u8 num_ports; - __u8 endpoint_numbers_different; - __le16 reserved1; - struct { - __u32 port_function_id; - __u8 port; - __u8 end_point_info; - __le16 reserved; - } connections[2]; -}; - -#endif - diff --git a/ANDROID_3.4.5/drivers/usb/serial/vivopay-serial.c b/ANDROID_3.4.5/drivers/usb/serial/vivopay-serial.c deleted file mode 100644 index 078f338b..00000000 --- a/ANDROID_3.4.5/drivers/usb/serial/vivopay-serial.c +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright (C) 2001-2005 Greg Kroah-Hartman (greg@kroah.com) - * Copyright (C) 2009 Outpost Embedded, LLC - */ - -#include <linux/kernel.h> -#include <linux/init.h> -#include <linux/tty.h> -#include <linux/module.h> -#include <linux/usb.h> -#include <linux/usb/serial.h> - - -#define DRIVER_VERSION "v1.0" -#define DRIVER_DESC "ViVOpay USB Serial Driver" - -#define VIVOPAY_VENDOR_ID 0x1d5f - - -static struct usb_device_id id_table [] = { - /* ViVOpay 8800 */ - { USB_DEVICE(VIVOPAY_VENDOR_ID, 0x1004) }, - { }, -}; - -MODULE_DEVICE_TABLE(usb, id_table); - -static struct usb_driver vivopay_serial_driver = { - .name = "vivopay-serial", - .probe = usb_serial_probe, - .disconnect = usb_serial_disconnect, - .id_table = id_table, -}; - -static struct usb_serial_driver vivopay_serial_device = { - .driver = { - .owner = THIS_MODULE, - .name = "vivopay-serial", - }, - .id_table = id_table, - .num_ports = 1, -}; - -static struct usb_serial_driver * const serial_drivers[] = { - &vivopay_serial_device, NULL -}; - -module_usb_serial_driver(vivopay_serial_driver, serial_drivers); - -MODULE_AUTHOR("Forest Bond <forest.bond@outpostembedded.com>"); -MODULE_DESCRIPTION(DRIVER_DESC); -MODULE_VERSION(DRIVER_VERSION); -MODULE_LICENSE("GPL"); diff --git a/ANDROID_3.4.5/drivers/usb/serial/whiteheat.c b/ANDROID_3.4.5/drivers/usb/serial/whiteheat.c deleted file mode 100644 index 407e23c8..00000000 --- a/ANDROID_3.4.5/drivers/usb/serial/whiteheat.c +++ /dev/null @@ -1,1470 +0,0 @@ -/* - * USB ConnectTech WhiteHEAT driver - * - * Copyright (C) 2002 - * Connect Tech Inc. - * - * Copyright (C) 1999 - 2001 - * Greg Kroah-Hartman (greg@kroah.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. - * - * See Documentation/usb/usb-serial.txt for more information on using this - * driver - */ - -#include <linux/kernel.h> -#include <linux/errno.h> -#include <linux/init.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 <asm/termbits.h> -#include <linux/usb.h> -#include <linux/serial_reg.h> -#include <linux/serial.h> -#include <linux/usb/serial.h> -#include <linux/firmware.h> -#include <linux/ihex.h> -#include "whiteheat.h" /* WhiteHEAT specific commands */ - -static bool debug; - -#ifndef CMSPAR -#define CMSPAR 0 -#endif - -/* - * Version Information - */ -#define DRIVER_VERSION "v2.0" -#define DRIVER_AUTHOR "Greg Kroah-Hartman <greg@kroah.com>, Stuart MacDonald <stuartm@connecttech.com>" -#define DRIVER_DESC "USB ConnectTech WhiteHEAT driver" - -#define CONNECT_TECH_VENDOR_ID 0x0710 -#define CONNECT_TECH_FAKE_WHITE_HEAT_ID 0x0001 -#define CONNECT_TECH_WHITE_HEAT_ID 0x8001 - -/* - ID tables for whiteheat are unusual, because we want to different - things for different versions of the device. Eventually, this - will be doable from a single table. But, for now, we define two - separate ID tables, and then a third table that combines them - just for the purpose of exporting the autoloading information. -*/ -static const struct usb_device_id id_table_std[] = { - { USB_DEVICE(CONNECT_TECH_VENDOR_ID, CONNECT_TECH_WHITE_HEAT_ID) }, - { } /* Terminating entry */ -}; - -static const struct usb_device_id id_table_prerenumeration[] = { - { USB_DEVICE(CONNECT_TECH_VENDOR_ID, CONNECT_TECH_FAKE_WHITE_HEAT_ID) }, - { } /* Terminating entry */ -}; - -static const struct usb_device_id id_table_combined[] = { - { USB_DEVICE(CONNECT_TECH_VENDOR_ID, CONNECT_TECH_WHITE_HEAT_ID) }, - { USB_DEVICE(CONNECT_TECH_VENDOR_ID, CONNECT_TECH_FAKE_WHITE_HEAT_ID) }, - { } /* Terminating entry */ -}; - -MODULE_DEVICE_TABLE(usb, id_table_combined); - -static struct usb_driver whiteheat_driver = { - .name = "whiteheat", - .probe = usb_serial_probe, - .disconnect = usb_serial_disconnect, - .id_table = id_table_combined, -}; - -/* function prototypes for the Connect Tech WhiteHEAT prerenumeration device */ -static int whiteheat_firmware_download(struct usb_serial *serial, - const struct usb_device_id *id); -static int whiteheat_firmware_attach(struct usb_serial *serial); - -/* function prototypes for the Connect Tech WhiteHEAT serial converter */ -static int whiteheat_attach(struct usb_serial *serial); -static void whiteheat_release(struct usb_serial *serial); -static int whiteheat_open(struct tty_struct *tty, - struct usb_serial_port *port); -static void whiteheat_close(struct usb_serial_port *port); -static int whiteheat_write(struct tty_struct *tty, - struct usb_serial_port *port, - const unsigned char *buf, int count); -static int whiteheat_write_room(struct tty_struct *tty); -static int whiteheat_ioctl(struct tty_struct *tty, - unsigned int cmd, unsigned long arg); -static void whiteheat_set_termios(struct tty_struct *tty, - struct usb_serial_port *port, struct ktermios *old); -static int whiteheat_tiocmget(struct tty_struct *tty); -static int whiteheat_tiocmset(struct tty_struct *tty, - unsigned int set, unsigned int clear); -static void whiteheat_break_ctl(struct tty_struct *tty, int break_state); -static int whiteheat_chars_in_buffer(struct tty_struct *tty); -static void whiteheat_throttle(struct tty_struct *tty); -static void whiteheat_unthrottle(struct tty_struct *tty); -static void whiteheat_read_callback(struct urb *urb); -static void whiteheat_write_callback(struct urb *urb); - -static struct usb_serial_driver whiteheat_fake_device = { - .driver = { - .owner = THIS_MODULE, - .name = "whiteheatnofirm", - }, - .description = "Connect Tech - WhiteHEAT - (prerenumeration)", - .id_table = id_table_prerenumeration, - .num_ports = 1, - .probe = whiteheat_firmware_download, - .attach = whiteheat_firmware_attach, -}; - -static struct usb_serial_driver whiteheat_device = { - .driver = { - .owner = THIS_MODULE, - .name = "whiteheat", - }, - .description = "Connect Tech - WhiteHEAT", - .id_table = id_table_std, - .num_ports = 4, - .attach = whiteheat_attach, - .release = whiteheat_release, - .open = whiteheat_open, - .close = whiteheat_close, - .write = whiteheat_write, - .write_room = whiteheat_write_room, - .ioctl = whiteheat_ioctl, - .set_termios = whiteheat_set_termios, - .break_ctl = whiteheat_break_ctl, - .tiocmget = whiteheat_tiocmget, - .tiocmset = whiteheat_tiocmset, - .chars_in_buffer = whiteheat_chars_in_buffer, - .throttle = whiteheat_throttle, - .unthrottle = whiteheat_unthrottle, - .read_bulk_callback = whiteheat_read_callback, - .write_bulk_callback = whiteheat_write_callback, -}; - -static struct usb_serial_driver * const serial_drivers[] = { - &whiteheat_fake_device, &whiteheat_device, NULL -}; - -struct whiteheat_command_private { - struct mutex mutex; - __u8 port_running; - __u8 command_finished; - wait_queue_head_t wait_command; /* for handling sleeping whilst - waiting for a command to - finish */ - __u8 result_buffer[64]; -}; - - -#define THROTTLED 0x01 -#define ACTUALLY_THROTTLED 0x02 - -static int urb_pool_size = 8; - -struct whiteheat_urb_wrap { - struct list_head list; - struct urb *urb; -}; - -struct whiteheat_private { - spinlock_t lock; - __u8 flags; - __u8 mcr; /* FIXME: no locking on mcr */ - struct list_head rx_urbs_free; - struct list_head rx_urbs_submitted; - struct list_head rx_urb_q; - struct work_struct rx_work; - struct usb_serial_port *port; - struct list_head tx_urbs_free; - struct list_head tx_urbs_submitted; - struct mutex deathwarrant; -}; - - -/* local function prototypes */ -static int start_command_port(struct usb_serial *serial); -static void stop_command_port(struct usb_serial *serial); -static void command_port_write_callback(struct urb *urb); -static void command_port_read_callback(struct urb *urb); - -static int start_port_read(struct usb_serial_port *port); -static struct whiteheat_urb_wrap *urb_to_wrap(struct urb *urb, - struct list_head *head); -static struct list_head *list_first(struct list_head *head); -static void rx_data_softint(struct work_struct *work); - -static int firm_send_command(struct usb_serial_port *port, __u8 command, - __u8 *data, __u8 datasize); -static int firm_open(struct usb_serial_port *port); -static int firm_close(struct usb_serial_port *port); -static void firm_setup_port(struct tty_struct *tty); -static int firm_set_rts(struct usb_serial_port *port, __u8 onoff); -static int firm_set_dtr(struct usb_serial_port *port, __u8 onoff); -static int firm_set_break(struct usb_serial_port *port, __u8 onoff); -static int firm_purge(struct usb_serial_port *port, __u8 rxtx); -static int firm_get_dtr_rts(struct usb_serial_port *port); -static int firm_report_tx_done(struct usb_serial_port *port); - - -#define COMMAND_PORT 4 -#define COMMAND_TIMEOUT (2*HZ) /* 2 second timeout for a command */ -#define COMMAND_TIMEOUT_MS 2000 -#define CLOSING_DELAY (30 * HZ) - - -/***************************************************************************** - * Connect Tech's White Heat prerenumeration driver functions - *****************************************************************************/ - -/* steps to download the firmware to the WhiteHEAT device: - - hold the reset (by writing to the reset bit of the CPUCS register) - - download the VEND_AX.HEX file to the chip using VENDOR_REQUEST-ANCHOR_LOAD - - release the reset (by writing to the CPUCS register) - - download the WH.HEX file for all addresses greater than 0x1b3f using - VENDOR_REQUEST-ANCHOR_EXTERNAL_RAM_LOAD - - hold the reset - - download the WH.HEX file for all addresses less than 0x1b40 using - VENDOR_REQUEST_ANCHOR_LOAD - - release the reset - - device renumerated itself and comes up as new device id with all - firmware download completed. -*/ -static int whiteheat_firmware_download(struct usb_serial *serial, - const struct usb_device_id *id) -{ - int response, ret = -ENOENT; - const struct firmware *loader_fw = NULL, *firmware_fw = NULL; - const struct ihex_binrec *record; - - dbg("%s", __func__); - - if (request_ihex_firmware(&firmware_fw, "whiteheat.fw", - &serial->dev->dev)) { - dev_err(&serial->dev->dev, - "%s - request \"whiteheat.fw\" failed\n", __func__); - goto out; - } - if (request_ihex_firmware(&loader_fw, "whiteheat_loader.fw", - &serial->dev->dev)) { - dev_err(&serial->dev->dev, - "%s - request \"whiteheat_loader.fw\" failed\n", - __func__); - goto out; - } - ret = 0; - response = ezusb_set_reset (serial, 1); - - record = (const struct ihex_binrec *)loader_fw->data; - while (record) { - response = ezusb_writememory (serial, be32_to_cpu(record->addr), - (unsigned char *)record->data, - be16_to_cpu(record->len), 0xa0); - if (response < 0) { - dev_err(&serial->dev->dev, "%s - ezusb_writememory " - "failed for loader (%d %04X %p %d)\n", - __func__, response, be32_to_cpu(record->addr), - record->data, be16_to_cpu(record->len)); - break; - } - record = ihex_next_binrec(record); - } - - response = ezusb_set_reset(serial, 0); - - record = (const struct ihex_binrec *)firmware_fw->data; - while (record && be32_to_cpu(record->addr) < 0x1b40) - record = ihex_next_binrec(record); - while (record) { - response = ezusb_writememory (serial, be32_to_cpu(record->addr), - (unsigned char *)record->data, - be16_to_cpu(record->len), 0xa3); - if (response < 0) { - dev_err(&serial->dev->dev, "%s - ezusb_writememory " - "failed for first firmware step " - "(%d %04X %p %d)\n", __func__, response, - be32_to_cpu(record->addr), record->data, - be16_to_cpu(record->len)); - break; - } - ++record; - } - - response = ezusb_set_reset(serial, 1); - - record = (const struct ihex_binrec *)firmware_fw->data; - while (record && be32_to_cpu(record->addr) < 0x1b40) { - response = ezusb_writememory (serial, be32_to_cpu(record->addr), - (unsigned char *)record->data, - be16_to_cpu(record->len), 0xa0); - if (response < 0) { - dev_err(&serial->dev->dev, "%s - ezusb_writememory " - "failed for second firmware step " - "(%d %04X %p %d)\n", __func__, response, - be32_to_cpu(record->addr), record->data, - be16_to_cpu(record->len)); - break; - } - ++record; - } - ret = 0; - response = ezusb_set_reset (serial, 0); - out: - release_firmware(loader_fw); - release_firmware(firmware_fw); - return ret; -} - - -static int whiteheat_firmware_attach(struct usb_serial *serial) -{ - /* We want this device to fail to have a driver assigned to it */ - return 1; -} - - -/***************************************************************************** - * Connect Tech's White Heat serial driver functions - *****************************************************************************/ -static int whiteheat_attach(struct usb_serial *serial) -{ - struct usb_serial_port *command_port; - struct whiteheat_command_private *command_info; - struct usb_serial_port *port; - struct whiteheat_private *info; - struct whiteheat_hw_info *hw_info; - int pipe; - int ret; - int alen; - __u8 *command; - __u8 *result; - int i; - int j; - struct urb *urb; - int buf_size; - struct whiteheat_urb_wrap *wrap; - struct list_head *tmp; - - command_port = serial->port[COMMAND_PORT]; - - pipe = usb_sndbulkpipe(serial->dev, - command_port->bulk_out_endpointAddress); - command = kmalloc(2, GFP_KERNEL); - if (!command) - goto no_command_buffer; - command[0] = WHITEHEAT_GET_HW_INFO; - command[1] = 0; - - result = kmalloc(sizeof(*hw_info) + 1, GFP_KERNEL); - if (!result) - goto no_result_buffer; - /* - * When the module is reloaded the firmware is still there and - * the endpoints are still in the usb core unchanged. This is the - * unlinking bug in disguise. Same for the call below. - */ - usb_clear_halt(serial->dev, pipe); - ret = usb_bulk_msg(serial->dev, pipe, command, 2, - &alen, COMMAND_TIMEOUT_MS); - if (ret) { - dev_err(&serial->dev->dev, "%s: Couldn't send command [%d]\n", - serial->type->description, ret); - goto no_firmware; - } else if (alen != 2) { - dev_err(&serial->dev->dev, "%s: Send command incomplete [%d]\n", - serial->type->description, alen); - goto no_firmware; - } - - pipe = usb_rcvbulkpipe(serial->dev, - command_port->bulk_in_endpointAddress); - /* See the comment on the usb_clear_halt() above */ - usb_clear_halt(serial->dev, pipe); - ret = usb_bulk_msg(serial->dev, pipe, result, - sizeof(*hw_info) + 1, &alen, COMMAND_TIMEOUT_MS); - if (ret) { - dev_err(&serial->dev->dev, "%s: Couldn't get results [%d]\n", - serial->type->description, ret); - goto no_firmware; - } else if (alen != sizeof(*hw_info) + 1) { - dev_err(&serial->dev->dev, "%s: Get results incomplete [%d]\n", - serial->type->description, alen); - goto no_firmware; - } else if (result[0] != command[0]) { - dev_err(&serial->dev->dev, "%s: Command failed [%d]\n", - serial->type->description, result[0]); - goto no_firmware; - } - - hw_info = (struct whiteheat_hw_info *)&result[1]; - - dev_info(&serial->dev->dev, "%s: Driver %s: Firmware v%d.%02d\n", - serial->type->description, DRIVER_VERSION, - hw_info->sw_major_rev, hw_info->sw_minor_rev); - - for (i = 0; i < serial->num_ports; i++) { - port = serial->port[i]; - - info = kmalloc(sizeof(struct whiteheat_private), GFP_KERNEL); - if (info == NULL) { - dev_err(&port->dev, - "%s: Out of memory for port structures\n", - serial->type->description); - goto no_private; - } - - spin_lock_init(&info->lock); - mutex_init(&info->deathwarrant); - info->flags = 0; - info->mcr = 0; - INIT_WORK(&info->rx_work, rx_data_softint); - info->port = port; - - INIT_LIST_HEAD(&info->rx_urbs_free); - INIT_LIST_HEAD(&info->rx_urbs_submitted); - INIT_LIST_HEAD(&info->rx_urb_q); - INIT_LIST_HEAD(&info->tx_urbs_free); - INIT_LIST_HEAD(&info->tx_urbs_submitted); - - for (j = 0; j < urb_pool_size; j++) { - urb = usb_alloc_urb(0, GFP_KERNEL); - if (!urb) { - dev_err(&port->dev, "No free urbs available\n"); - goto no_rx_urb; - } - buf_size = port->read_urb->transfer_buffer_length; - urb->transfer_buffer = kmalloc(buf_size, GFP_KERNEL); - if (!urb->transfer_buffer) { - dev_err(&port->dev, - "Couldn't allocate urb buffer\n"); - goto no_rx_buf; - } - wrap = kmalloc(sizeof(*wrap), GFP_KERNEL); - if (!wrap) { - dev_err(&port->dev, - "Couldn't allocate urb wrapper\n"); - goto no_rx_wrap; - } - usb_fill_bulk_urb(urb, serial->dev, - usb_rcvbulkpipe(serial->dev, - port->bulk_in_endpointAddress), - urb->transfer_buffer, buf_size, - whiteheat_read_callback, port); - wrap->urb = urb; - list_add(&wrap->list, &info->rx_urbs_free); - - urb = usb_alloc_urb(0, GFP_KERNEL); - if (!urb) { - dev_err(&port->dev, "No free urbs available\n"); - goto no_tx_urb; - } - buf_size = port->write_urb->transfer_buffer_length; - urb->transfer_buffer = kmalloc(buf_size, GFP_KERNEL); - if (!urb->transfer_buffer) { - dev_err(&port->dev, - "Couldn't allocate urb buffer\n"); - goto no_tx_buf; - } - wrap = kmalloc(sizeof(*wrap), GFP_KERNEL); - if (!wrap) { - dev_err(&port->dev, - "Couldn't allocate urb wrapper\n"); - goto no_tx_wrap; - } - usb_fill_bulk_urb(urb, serial->dev, - usb_sndbulkpipe(serial->dev, - port->bulk_out_endpointAddress), - urb->transfer_buffer, buf_size, - whiteheat_write_callback, port); - wrap->urb = urb; - list_add(&wrap->list, &info->tx_urbs_free); - } - - usb_set_serial_port_data(port, info); - } - - command_info = kmalloc(sizeof(struct whiteheat_command_private), - GFP_KERNEL); - if (command_info == NULL) { - dev_err(&serial->dev->dev, - "%s: Out of memory for port structures\n", - serial->type->description); - goto no_command_private; - } - - mutex_init(&command_info->mutex); - command_info->port_running = 0; - init_waitqueue_head(&command_info->wait_command); - usb_set_serial_port_data(command_port, command_info); - command_port->write_urb->complete = command_port_write_callback; - command_port->read_urb->complete = command_port_read_callback; - kfree(result); - kfree(command); - - return 0; - -no_firmware: - /* Firmware likely not running */ - dev_err(&serial->dev->dev, - "%s: Unable to retrieve firmware version, try replugging\n", - serial->type->description); - dev_err(&serial->dev->dev, - "%s: If the firmware is not running (status led not blinking)\n", - serial->type->description); - dev_err(&serial->dev->dev, - "%s: please contact support@connecttech.com\n", - serial->type->description); - kfree(result); - return -ENODEV; - -no_command_private: - for (i = serial->num_ports - 1; i >= 0; i--) { - port = serial->port[i]; - info = usb_get_serial_port_data(port); - for (j = urb_pool_size - 1; j >= 0; j--) { - tmp = list_first(&info->tx_urbs_free); - list_del(tmp); - wrap = list_entry(tmp, struct whiteheat_urb_wrap, list); - urb = wrap->urb; - kfree(wrap); -no_tx_wrap: - kfree(urb->transfer_buffer); -no_tx_buf: - usb_free_urb(urb); -no_tx_urb: - tmp = list_first(&info->rx_urbs_free); - list_del(tmp); - wrap = list_entry(tmp, struct whiteheat_urb_wrap, list); - urb = wrap->urb; - kfree(wrap); -no_rx_wrap: - kfree(urb->transfer_buffer); -no_rx_buf: - usb_free_urb(urb); -no_rx_urb: - ; - } - kfree(info); -no_private: - ; - } - kfree(result); -no_result_buffer: - kfree(command); -no_command_buffer: - return -ENOMEM; -} - - -static void whiteheat_release(struct usb_serial *serial) -{ - struct usb_serial_port *command_port; - struct usb_serial_port *port; - struct whiteheat_private *info; - struct whiteheat_urb_wrap *wrap; - struct urb *urb; - struct list_head *tmp; - struct list_head *tmp2; - int i; - - dbg("%s", __func__); - - /* free up our private data for our command port */ - command_port = serial->port[COMMAND_PORT]; - kfree(usb_get_serial_port_data(command_port)); - - for (i = 0; i < serial->num_ports; i++) { - port = serial->port[i]; - info = usb_get_serial_port_data(port); - list_for_each_safe(tmp, tmp2, &info->rx_urbs_free) { - list_del(tmp); - wrap = list_entry(tmp, struct whiteheat_urb_wrap, list); - urb = wrap->urb; - kfree(wrap); - kfree(urb->transfer_buffer); - usb_free_urb(urb); - } - list_for_each_safe(tmp, tmp2, &info->tx_urbs_free) { - list_del(tmp); - wrap = list_entry(tmp, struct whiteheat_urb_wrap, list); - urb = wrap->urb; - kfree(wrap); - kfree(urb->transfer_buffer); - usb_free_urb(urb); - } - kfree(info); - } -} - -static int whiteheat_open(struct tty_struct *tty, struct usb_serial_port *port) -{ - int retval = 0; - - dbg("%s - port %d", __func__, port->number); - - retval = start_command_port(port->serial); - if (retval) - goto exit; - - if (tty) - tty->low_latency = 1; - - /* send an open port command */ - retval = firm_open(port); - if (retval) { - stop_command_port(port->serial); - goto exit; - } - - retval = firm_purge(port, WHITEHEAT_PURGE_RX | WHITEHEAT_PURGE_TX); - if (retval) { - firm_close(port); - stop_command_port(port->serial); - goto exit; - } - - if (tty) - firm_setup_port(tty); - - /* Work around HCD bugs */ - usb_clear_halt(port->serial->dev, port->read_urb->pipe); - usb_clear_halt(port->serial->dev, port->write_urb->pipe); - - /* Start reading from the device */ - retval = start_port_read(port); - if (retval) { - dev_err(&port->dev, - "%s - failed submitting read urb, error %d\n", - __func__, retval); - firm_close(port); - stop_command_port(port->serial); - goto exit; - } - -exit: - dbg("%s - exit, retval = %d", __func__, retval); - return retval; -} - - -static void whiteheat_close(struct usb_serial_port *port) -{ - struct whiteheat_private *info = usb_get_serial_port_data(port); - struct whiteheat_urb_wrap *wrap; - struct urb *urb; - struct list_head *tmp; - struct list_head *tmp2; - - dbg("%s - port %d", __func__, port->number); - - firm_report_tx_done(port); - firm_close(port); - - /* shutdown our bulk reads and writes */ - mutex_lock(&info->deathwarrant); - spin_lock_irq(&info->lock); - list_for_each_safe(tmp, tmp2, &info->rx_urbs_submitted) { - wrap = list_entry(tmp, struct whiteheat_urb_wrap, list); - urb = wrap->urb; - list_del(tmp); - spin_unlock_irq(&info->lock); - usb_kill_urb(urb); - spin_lock_irq(&info->lock); - list_add(tmp, &info->rx_urbs_free); - } - list_for_each_safe(tmp, tmp2, &info->rx_urb_q) - list_move(tmp, &info->rx_urbs_free); - list_for_each_safe(tmp, tmp2, &info->tx_urbs_submitted) { - wrap = list_entry(tmp, struct whiteheat_urb_wrap, list); - urb = wrap->urb; - list_del(tmp); - spin_unlock_irq(&info->lock); - usb_kill_urb(urb); - spin_lock_irq(&info->lock); - list_add(tmp, &info->tx_urbs_free); - } - spin_unlock_irq(&info->lock); - mutex_unlock(&info->deathwarrant); - stop_command_port(port->serial); -} - - -static int whiteheat_write(struct tty_struct *tty, - struct usb_serial_port *port, const unsigned char *buf, int count) -{ - struct whiteheat_private *info = usb_get_serial_port_data(port); - struct whiteheat_urb_wrap *wrap; - struct urb *urb; - int result; - int bytes; - int sent = 0; - unsigned long flags; - struct list_head *tmp; - - dbg("%s - port %d", __func__, port->number); - - if (count == 0) { - dbg("%s - write request of 0 bytes", __func__); - return (0); - } - - while (count) { - spin_lock_irqsave(&info->lock, flags); - if (list_empty(&info->tx_urbs_free)) { - spin_unlock_irqrestore(&info->lock, flags); - break; - } - tmp = list_first(&info->tx_urbs_free); - list_del(tmp); - spin_unlock_irqrestore(&info->lock, flags); - - wrap = list_entry(tmp, struct whiteheat_urb_wrap, list); - urb = wrap->urb; - bytes = (count > port->bulk_out_size) ? - port->bulk_out_size : count; - memcpy(urb->transfer_buffer, buf + sent, bytes); - - usb_serial_debug_data(debug, &port->dev, - __func__, bytes, urb->transfer_buffer); - - urb->transfer_buffer_length = bytes; - result = usb_submit_urb(urb, GFP_ATOMIC); - if (result) { - dev_err_console(port, - "%s - failed submitting write urb, error %d\n", - __func__, result); - sent = result; - spin_lock_irqsave(&info->lock, flags); - list_add(tmp, &info->tx_urbs_free); - spin_unlock_irqrestore(&info->lock, flags); - break; - } else { - sent += bytes; - count -= bytes; - spin_lock_irqsave(&info->lock, flags); - list_add(tmp, &info->tx_urbs_submitted); - spin_unlock_irqrestore(&info->lock, flags); - } - } - - return sent; -} - -static int whiteheat_write_room(struct tty_struct *tty) -{ - struct usb_serial_port *port = tty->driver_data; - struct whiteheat_private *info = usb_get_serial_port_data(port); - struct list_head *tmp; - int room = 0; - unsigned long flags; - - dbg("%s - port %d", __func__, port->number); - - spin_lock_irqsave(&info->lock, flags); - list_for_each(tmp, &info->tx_urbs_free) - room++; - spin_unlock_irqrestore(&info->lock, flags); - room *= port->bulk_out_size; - - dbg("%s - returns %d", __func__, room); - return (room); -} - -static int whiteheat_tiocmget(struct tty_struct *tty) -{ - struct usb_serial_port *port = tty->driver_data; - struct whiteheat_private *info = usb_get_serial_port_data(port); - unsigned int modem_signals = 0; - - dbg("%s - port %d", __func__, port->number); - - firm_get_dtr_rts(port); - if (info->mcr & UART_MCR_DTR) - modem_signals |= TIOCM_DTR; - if (info->mcr & UART_MCR_RTS) - modem_signals |= TIOCM_RTS; - - return modem_signals; -} - -static int whiteheat_tiocmset(struct tty_struct *tty, - unsigned int set, unsigned int clear) -{ - struct usb_serial_port *port = tty->driver_data; - struct whiteheat_private *info = usb_get_serial_port_data(port); - - dbg("%s - port %d", __func__, port->number); - - if (set & TIOCM_RTS) - info->mcr |= UART_MCR_RTS; - if (set & TIOCM_DTR) - info->mcr |= UART_MCR_DTR; - - if (clear & TIOCM_RTS) - info->mcr &= ~UART_MCR_RTS; - if (clear & TIOCM_DTR) - info->mcr &= ~UART_MCR_DTR; - - firm_set_dtr(port, info->mcr & UART_MCR_DTR); - firm_set_rts(port, info->mcr & UART_MCR_RTS); - return 0; -} - - -static int whiteheat_ioctl(struct tty_struct *tty, - unsigned int cmd, unsigned long arg) -{ - struct usb_serial_port *port = tty->driver_data; - struct serial_struct serstruct; - void __user *user_arg = (void __user *)arg; - - dbg("%s - port %d, cmd 0x%.4x", __func__, port->number, cmd); - - switch (cmd) { - case TIOCGSERIAL: - memset(&serstruct, 0, sizeof(serstruct)); - serstruct.type = PORT_16654; - serstruct.line = port->serial->minor; - serstruct.port = port->number; - serstruct.flags = ASYNC_SKIP_TEST | ASYNC_AUTO_IRQ; - serstruct.xmit_fifo_size = port->bulk_out_size; - serstruct.custom_divisor = 0; - serstruct.baud_base = 460800; - serstruct.close_delay = CLOSING_DELAY; - serstruct.closing_wait = CLOSING_DELAY; - - if (copy_to_user(user_arg, &serstruct, sizeof(serstruct))) - return -EFAULT; - break; - default: - break; - } - - return -ENOIOCTLCMD; -} - - -static void whiteheat_set_termios(struct tty_struct *tty, - struct usb_serial_port *port, struct ktermios *old_termios) -{ - firm_setup_port(tty); -} - -static void whiteheat_break_ctl(struct tty_struct *tty, int break_state) -{ - struct usb_serial_port *port = tty->driver_data; - firm_set_break(port, break_state); -} - - -static int whiteheat_chars_in_buffer(struct tty_struct *tty) -{ - struct usb_serial_port *port = tty->driver_data; - struct whiteheat_private *info = usb_get_serial_port_data(port); - struct list_head *tmp; - struct whiteheat_urb_wrap *wrap; - int chars = 0; - unsigned long flags; - - dbg("%s - port %d", __func__, port->number); - - spin_lock_irqsave(&info->lock, flags); - list_for_each(tmp, &info->tx_urbs_submitted) { - wrap = list_entry(tmp, struct whiteheat_urb_wrap, list); - chars += wrap->urb->transfer_buffer_length; - } - spin_unlock_irqrestore(&info->lock, flags); - - dbg("%s - returns %d", __func__, chars); - return chars; -} - - -static void whiteheat_throttle(struct tty_struct *tty) -{ - struct usb_serial_port *port = tty->driver_data; - struct whiteheat_private *info = usb_get_serial_port_data(port); - - dbg("%s - port %d", __func__, port->number); - - spin_lock_irq(&info->lock); - info->flags |= THROTTLED; - spin_unlock_irq(&info->lock); -} - - -static void whiteheat_unthrottle(struct tty_struct *tty) -{ - struct usb_serial_port *port = tty->driver_data; - struct whiteheat_private *info = usb_get_serial_port_data(port); - int actually_throttled; - - dbg("%s - port %d", __func__, port->number); - - spin_lock_irq(&info->lock); - actually_throttled = info->flags & ACTUALLY_THROTTLED; - info->flags &= ~(THROTTLED | ACTUALLY_THROTTLED); - spin_unlock_irq(&info->lock); - - if (actually_throttled) - rx_data_softint(&info->rx_work); -} - - -/***************************************************************************** - * Connect Tech's White Heat callback routines - *****************************************************************************/ -static void command_port_write_callback(struct urb *urb) -{ - int status = urb->status; - - dbg("%s", __func__); - - if (status) { - dbg("nonzero urb status: %d", status); - return; - } -} - - -static void command_port_read_callback(struct urb *urb) -{ - struct usb_serial_port *command_port = urb->context; - struct whiteheat_command_private *command_info; - int status = urb->status; - unsigned char *data = urb->transfer_buffer; - int result; - - dbg("%s", __func__); - - command_info = usb_get_serial_port_data(command_port); - if (!command_info) { - dbg("%s - command_info is NULL, exiting.", __func__); - return; - } - if (status) { - dbg("%s - nonzero urb status: %d", __func__, status); - if (status != -ENOENT) - command_info->command_finished = WHITEHEAT_CMD_FAILURE; - wake_up(&command_info->wait_command); - return; - } - - usb_serial_debug_data(debug, &command_port->dev, - __func__, urb->actual_length, data); - - if (data[0] == WHITEHEAT_CMD_COMPLETE) { - command_info->command_finished = WHITEHEAT_CMD_COMPLETE; - wake_up(&command_info->wait_command); - } else if (data[0] == WHITEHEAT_CMD_FAILURE) { - command_info->command_finished = WHITEHEAT_CMD_FAILURE; - wake_up(&command_info->wait_command); - } else if (data[0] == WHITEHEAT_EVENT) { - /* These are unsolicited reports from the firmware, hence no - waiting command to wakeup */ - dbg("%s - event received", __func__); - } else if (data[0] == WHITEHEAT_GET_DTR_RTS) { - memcpy(command_info->result_buffer, &data[1], - urb->actual_length - 1); - command_info->command_finished = WHITEHEAT_CMD_COMPLETE; - wake_up(&command_info->wait_command); - } else - dbg("%s - bad reply from firmware", __func__); - - /* Continue trying to always read */ - result = usb_submit_urb(command_port->read_urb, GFP_ATOMIC); - if (result) - dbg("%s - failed resubmitting read urb, error %d", - __func__, result); -} - - -static void whiteheat_read_callback(struct urb *urb) -{ - struct usb_serial_port *port = urb->context; - struct whiteheat_urb_wrap *wrap; - unsigned char *data = urb->transfer_buffer; - struct whiteheat_private *info = usb_get_serial_port_data(port); - int status = urb->status; - - dbg("%s - port %d", __func__, port->number); - - spin_lock(&info->lock); - wrap = urb_to_wrap(urb, &info->rx_urbs_submitted); - if (!wrap) { - spin_unlock(&info->lock); - dev_err(&port->dev, "%s - Not my urb!\n", __func__); - return; - } - list_del(&wrap->list); - spin_unlock(&info->lock); - - if (status) { - dbg("%s - nonzero read bulk status received: %d", - __func__, status); - spin_lock(&info->lock); - list_add(&wrap->list, &info->rx_urbs_free); - spin_unlock(&info->lock); - return; - } - - usb_serial_debug_data(debug, &port->dev, - __func__, urb->actual_length, data); - - spin_lock(&info->lock); - list_add_tail(&wrap->list, &info->rx_urb_q); - if (info->flags & THROTTLED) { - info->flags |= ACTUALLY_THROTTLED; - spin_unlock(&info->lock); - return; - } - spin_unlock(&info->lock); - - schedule_work(&info->rx_work); -} - - -static void whiteheat_write_callback(struct urb *urb) -{ - struct usb_serial_port *port = urb->context; - struct whiteheat_private *info = usb_get_serial_port_data(port); - struct whiteheat_urb_wrap *wrap; - int status = urb->status; - - dbg("%s - port %d", __func__, port->number); - - spin_lock(&info->lock); - wrap = urb_to_wrap(urb, &info->tx_urbs_submitted); - if (!wrap) { - spin_unlock(&info->lock); - dev_err(&port->dev, "%s - Not my urb!\n", __func__); - return; - } - list_move(&wrap->list, &info->tx_urbs_free); - spin_unlock(&info->lock); - - if (status) { - dbg("%s - nonzero write bulk status received: %d", - __func__, status); - return; - } - - usb_serial_port_softint(port); -} - - -/***************************************************************************** - * Connect Tech's White Heat firmware interface - *****************************************************************************/ -static int firm_send_command(struct usb_serial_port *port, __u8 command, - __u8 *data, __u8 datasize) -{ - struct usb_serial_port *command_port; - struct whiteheat_command_private *command_info; - struct whiteheat_private *info; - __u8 *transfer_buffer; - int retval = 0; - int t; - - dbg("%s - command %d", __func__, command); - - command_port = port->serial->port[COMMAND_PORT]; - command_info = usb_get_serial_port_data(command_port); - mutex_lock(&command_info->mutex); - command_info->command_finished = false; - - transfer_buffer = (__u8 *)command_port->write_urb->transfer_buffer; - transfer_buffer[0] = command; - memcpy(&transfer_buffer[1], data, datasize); - command_port->write_urb->transfer_buffer_length = datasize + 1; - retval = usb_submit_urb(command_port->write_urb, GFP_NOIO); - if (retval) { - dbg("%s - submit urb failed", __func__); - goto exit; - } - - /* wait for the command to complete */ - t = wait_event_timeout(command_info->wait_command, - (bool)command_info->command_finished, COMMAND_TIMEOUT); - if (!t) - usb_kill_urb(command_port->write_urb); - - if (command_info->command_finished == false) { - dbg("%s - command timed out.", __func__); - retval = -ETIMEDOUT; - goto exit; - } - - if (command_info->command_finished == WHITEHEAT_CMD_FAILURE) { - dbg("%s - command failed.", __func__); - retval = -EIO; - goto exit; - } - - if (command_info->command_finished == WHITEHEAT_CMD_COMPLETE) { - dbg("%s - command completed.", __func__); - switch (command) { - case WHITEHEAT_GET_DTR_RTS: - info = usb_get_serial_port_data(port); - memcpy(&info->mcr, command_info->result_buffer, - sizeof(struct whiteheat_dr_info)); - break; - } - } -exit: - mutex_unlock(&command_info->mutex); - return retval; -} - - -static int firm_open(struct usb_serial_port *port) -{ - struct whiteheat_simple open_command; - - open_command.port = port->number - port->serial->minor + 1; - return firm_send_command(port, WHITEHEAT_OPEN, - (__u8 *)&open_command, sizeof(open_command)); -} - - -static int firm_close(struct usb_serial_port *port) -{ - struct whiteheat_simple close_command; - - close_command.port = port->number - port->serial->minor + 1; - return firm_send_command(port, WHITEHEAT_CLOSE, - (__u8 *)&close_command, sizeof(close_command)); -} - - -static void firm_setup_port(struct tty_struct *tty) -{ - struct usb_serial_port *port = tty->driver_data; - struct whiteheat_port_settings port_settings; - unsigned int cflag = tty->termios->c_cflag; - - port_settings.port = port->number + 1; - - /* get the byte size */ - switch (cflag & CSIZE) { - case CS5: port_settings.bits = 5; break; - case CS6: port_settings.bits = 6; break; - case CS7: port_settings.bits = 7; break; - default: - case CS8: port_settings.bits = 8; break; - } - dbg("%s - data bits = %d", __func__, port_settings.bits); - - /* determine the parity */ - if (cflag & PARENB) - if (cflag & CMSPAR) - if (cflag & PARODD) - port_settings.parity = WHITEHEAT_PAR_MARK; - else - port_settings.parity = WHITEHEAT_PAR_SPACE; - else - if (cflag & PARODD) - port_settings.parity = WHITEHEAT_PAR_ODD; - else - port_settings.parity = WHITEHEAT_PAR_EVEN; - else - port_settings.parity = WHITEHEAT_PAR_NONE; - dbg("%s - parity = %c", __func__, port_settings.parity); - - /* figure out the stop bits requested */ - if (cflag & CSTOPB) - port_settings.stop = 2; - else - port_settings.stop = 1; - dbg("%s - stop bits = %d", __func__, port_settings.stop); - - /* figure out the flow control settings */ - if (cflag & CRTSCTS) - port_settings.hflow = (WHITEHEAT_HFLOW_CTS | - WHITEHEAT_HFLOW_RTS); - else - port_settings.hflow = WHITEHEAT_HFLOW_NONE; - dbg("%s - hardware flow control = %s %s %s %s", __func__, - (port_settings.hflow & WHITEHEAT_HFLOW_CTS) ? "CTS" : "", - (port_settings.hflow & WHITEHEAT_HFLOW_RTS) ? "RTS" : "", - (port_settings.hflow & WHITEHEAT_HFLOW_DSR) ? "DSR" : "", - (port_settings.hflow & WHITEHEAT_HFLOW_DTR) ? "DTR" : ""); - - /* determine software flow control */ - if (I_IXOFF(tty)) - port_settings.sflow = WHITEHEAT_SFLOW_RXTX; - else - port_settings.sflow = WHITEHEAT_SFLOW_NONE; - dbg("%s - software flow control = %c", __func__, port_settings.sflow); - - port_settings.xon = START_CHAR(tty); - port_settings.xoff = STOP_CHAR(tty); - dbg("%s - XON = %2x, XOFF = %2x", - __func__, port_settings.xon, port_settings.xoff); - - /* get the baud rate wanted */ - port_settings.baud = tty_get_baud_rate(tty); - dbg("%s - baud rate = %d", __func__, port_settings.baud); - - /* fixme: should set validated settings */ - tty_encode_baud_rate(tty, port_settings.baud, port_settings.baud); - /* handle any settings that aren't specified in the tty structure */ - port_settings.lloop = 0; - - /* now send the message to the device */ - firm_send_command(port, WHITEHEAT_SETUP_PORT, - (__u8 *)&port_settings, sizeof(port_settings)); -} - - -static int firm_set_rts(struct usb_serial_port *port, __u8 onoff) -{ - struct whiteheat_set_rdb rts_command; - - rts_command.port = port->number - port->serial->minor + 1; - rts_command.state = onoff; - return firm_send_command(port, WHITEHEAT_SET_RTS, - (__u8 *)&rts_command, sizeof(rts_command)); -} - - -static int firm_set_dtr(struct usb_serial_port *port, __u8 onoff) -{ - struct whiteheat_set_rdb dtr_command; - - dtr_command.port = port->number - port->serial->minor + 1; - dtr_command.state = onoff; - return firm_send_command(port, WHITEHEAT_SET_DTR, - (__u8 *)&dtr_command, sizeof(dtr_command)); -} - - -static int firm_set_break(struct usb_serial_port *port, __u8 onoff) -{ - struct whiteheat_set_rdb break_command; - - break_command.port = port->number - port->serial->minor + 1; - break_command.state = onoff; - return firm_send_command(port, WHITEHEAT_SET_BREAK, - (__u8 *)&break_command, sizeof(break_command)); -} - - -static int firm_purge(struct usb_serial_port *port, __u8 rxtx) -{ - struct whiteheat_purge purge_command; - - purge_command.port = port->number - port->serial->minor + 1; - purge_command.what = rxtx; - return firm_send_command(port, WHITEHEAT_PURGE, - (__u8 *)&purge_command, sizeof(purge_command)); -} - - -static int firm_get_dtr_rts(struct usb_serial_port *port) -{ - struct whiteheat_simple get_dr_command; - - get_dr_command.port = port->number - port->serial->minor + 1; - return firm_send_command(port, WHITEHEAT_GET_DTR_RTS, - (__u8 *)&get_dr_command, sizeof(get_dr_command)); -} - - -static int firm_report_tx_done(struct usb_serial_port *port) -{ - struct whiteheat_simple close_command; - - close_command.port = port->number - port->serial->minor + 1; - return firm_send_command(port, WHITEHEAT_REPORT_TX_DONE, - (__u8 *)&close_command, sizeof(close_command)); -} - - -/***************************************************************************** - * Connect Tech's White Heat utility functions - *****************************************************************************/ -static int start_command_port(struct usb_serial *serial) -{ - struct usb_serial_port *command_port; - struct whiteheat_command_private *command_info; - int retval = 0; - - command_port = serial->port[COMMAND_PORT]; - command_info = usb_get_serial_port_data(command_port); - mutex_lock(&command_info->mutex); - if (!command_info->port_running) { - /* Work around HCD bugs */ - usb_clear_halt(serial->dev, command_port->read_urb->pipe); - - retval = usb_submit_urb(command_port->read_urb, GFP_KERNEL); - if (retval) { - dev_err(&serial->dev->dev, - "%s - failed submitting read urb, error %d\n", - __func__, retval); - goto exit; - } - } - command_info->port_running++; - -exit: - mutex_unlock(&command_info->mutex); - return retval; -} - - -static void stop_command_port(struct usb_serial *serial) -{ - struct usb_serial_port *command_port; - struct whiteheat_command_private *command_info; - - command_port = serial->port[COMMAND_PORT]; - command_info = usb_get_serial_port_data(command_port); - mutex_lock(&command_info->mutex); - command_info->port_running--; - if (!command_info->port_running) - usb_kill_urb(command_port->read_urb); - mutex_unlock(&command_info->mutex); -} - - -static int start_port_read(struct usb_serial_port *port) -{ - struct whiteheat_private *info = usb_get_serial_port_data(port); - struct whiteheat_urb_wrap *wrap; - struct urb *urb; - int retval = 0; - unsigned long flags; - struct list_head *tmp; - struct list_head *tmp2; - - spin_lock_irqsave(&info->lock, flags); - - list_for_each_safe(tmp, tmp2, &info->rx_urbs_free) { - list_del(tmp); - wrap = list_entry(tmp, struct whiteheat_urb_wrap, list); - urb = wrap->urb; - spin_unlock_irqrestore(&info->lock, flags); - retval = usb_submit_urb(urb, GFP_KERNEL); - if (retval) { - spin_lock_irqsave(&info->lock, flags); - list_add(tmp, &info->rx_urbs_free); - list_for_each_safe(tmp, tmp2, &info->rx_urbs_submitted) { - wrap = list_entry(tmp, struct whiteheat_urb_wrap, list); - urb = wrap->urb; - list_del(tmp); - spin_unlock_irqrestore(&info->lock, flags); - usb_kill_urb(urb); - spin_lock_irqsave(&info->lock, flags); - list_add(tmp, &info->rx_urbs_free); - } - break; - } - spin_lock_irqsave(&info->lock, flags); - list_add(tmp, &info->rx_urbs_submitted); - } - - spin_unlock_irqrestore(&info->lock, flags); - - return retval; -} - - -static struct whiteheat_urb_wrap *urb_to_wrap(struct urb *urb, - struct list_head *head) -{ - struct whiteheat_urb_wrap *wrap; - struct list_head *tmp; - - list_for_each(tmp, head) { - wrap = list_entry(tmp, struct whiteheat_urb_wrap, list); - if (wrap->urb == urb) - return wrap; - } - - return NULL; -} - - -static struct list_head *list_first(struct list_head *head) -{ - return head->next; -} - - -static void rx_data_softint(struct work_struct *work) -{ - struct whiteheat_private *info = - container_of(work, struct whiteheat_private, rx_work); - struct usb_serial_port *port = info->port; - struct tty_struct *tty = tty_port_tty_get(&port->port); - struct whiteheat_urb_wrap *wrap; - struct urb *urb; - unsigned long flags; - struct list_head *tmp; - struct list_head *tmp2; - int result; - int sent = 0; - - spin_lock_irqsave(&info->lock, flags); - if (info->flags & THROTTLED) { - spin_unlock_irqrestore(&info->lock, flags); - goto out; - } - - list_for_each_safe(tmp, tmp2, &info->rx_urb_q) { - list_del(tmp); - spin_unlock_irqrestore(&info->lock, flags); - - wrap = list_entry(tmp, struct whiteheat_urb_wrap, list); - urb = wrap->urb; - - if (tty && urb->actual_length) - sent += tty_insert_flip_string(tty, - urb->transfer_buffer, urb->actual_length); - - result = usb_submit_urb(urb, GFP_ATOMIC); - if (result) { - dev_err(&port->dev, - "%s - failed resubmitting read urb, error %d\n", - __func__, result); - spin_lock_irqsave(&info->lock, flags); - list_add(tmp, &info->rx_urbs_free); - continue; - } - - spin_lock_irqsave(&info->lock, flags); - list_add(tmp, &info->rx_urbs_submitted); - } - spin_unlock_irqrestore(&info->lock, flags); - - if (sent) - tty_flip_buffer_push(tty); -out: - tty_kref_put(tty); -} - -module_usb_serial_driver(whiteheat_driver, serial_drivers); - -MODULE_AUTHOR(DRIVER_AUTHOR); -MODULE_DESCRIPTION(DRIVER_DESC); -MODULE_LICENSE("GPL"); - -MODULE_FIRMWARE("whiteheat.fw"); -MODULE_FIRMWARE("whiteheat_loader.fw"); - -module_param(urb_pool_size, int, 0); -MODULE_PARM_DESC(urb_pool_size, "Number of urbs to use for buffering"); - -module_param(debug, bool, S_IRUGO | S_IWUSR); -MODULE_PARM_DESC(debug, "Debug enabled or not"); diff --git a/ANDROID_3.4.5/drivers/usb/serial/whiteheat.h b/ANDROID_3.4.5/drivers/usb/serial/whiteheat.h deleted file mode 100644 index 38065df4..00000000 --- a/ANDROID_3.4.5/drivers/usb/serial/whiteheat.h +++ /dev/null @@ -1,302 +0,0 @@ -/* - * USB ConnectTech WhiteHEAT driver - * - * Copyright (C) 2002 - * Connect Tech Inc. - * - * Copyright (C) 1999, 2000 - * Greg Kroah-Hartman (greg@kroah.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. - * - * See Documentation/usb/usb-serial.txt for more information on using this - * driver - * - */ - -#ifndef __LINUX_USB_SERIAL_WHITEHEAT_H -#define __LINUX_USB_SERIAL_WHITEHEAT_H - - -/* WhiteHEAT commands */ -#define WHITEHEAT_OPEN 1 /* open the port */ -#define WHITEHEAT_CLOSE 2 /* close the port */ -#define WHITEHEAT_SETUP_PORT 3 /* change port settings */ -#define WHITEHEAT_SET_RTS 4 /* turn RTS on or off */ -#define WHITEHEAT_SET_DTR 5 /* turn DTR on or off */ -#define WHITEHEAT_SET_BREAK 6 /* turn BREAK on or off */ -#define WHITEHEAT_DUMP 7 /* dump memory */ -#define WHITEHEAT_STATUS 8 /* get status */ -#define WHITEHEAT_PURGE 9 /* clear the UART fifos */ -#define WHITEHEAT_GET_DTR_RTS 10 /* get the state of DTR and RTS - for a port */ -#define WHITEHEAT_GET_HW_INFO 11 /* get EEPROM info and - hardware ID */ -#define WHITEHEAT_REPORT_TX_DONE 12 /* get the next TX done */ -#define WHITEHEAT_EVENT 13 /* unsolicited status events */ -#define WHITEHEAT_ECHO 14 /* send data to the indicated - IN endpoint */ -#define WHITEHEAT_DO_TEST 15 /* perform specified test */ -#define WHITEHEAT_CMD_COMPLETE 16 /* reply for some commands */ -#define WHITEHEAT_CMD_FAILURE 17 /* reply for failed commands */ - - -/* - * Commands to the firmware - */ - - -/* - * WHITEHEAT_OPEN - * WHITEHEAT_CLOSE - * WHITEHEAT_STATUS - * WHITEHEAT_GET_DTR_RTS - * WHITEHEAT_REPORT_TX_DONE -*/ -struct whiteheat_simple { - __u8 port; /* port number (1 to N) */ -}; - - -/* - * WHITEHEAT_SETUP_PORT - */ -#define WHITEHEAT_PAR_NONE 'n' /* no parity */ -#define WHITEHEAT_PAR_EVEN 'e' /* even parity */ -#define WHITEHEAT_PAR_ODD 'o' /* odd parity */ -#define WHITEHEAT_PAR_SPACE '0' /* space (force 0) parity */ -#define WHITEHEAT_PAR_MARK '1' /* mark (force 1) parity */ - -#define WHITEHEAT_SFLOW_NONE 'n' /* no software flow control */ -#define WHITEHEAT_SFLOW_RX 'r' /* XOFF/ON is sent when RX - fills/empties */ -#define WHITEHEAT_SFLOW_TX 't' /* when received XOFF/ON will - stop/start TX */ -#define WHITEHEAT_SFLOW_RXTX 'b' /* both SFLOW_RX and SFLOW_TX */ - -#define WHITEHEAT_HFLOW_NONE 0x00 /* no hardware flow control */ -#define WHITEHEAT_HFLOW_RTS_TOGGLE 0x01 /* RTS is on during transmit, - off otherwise */ -#define WHITEHEAT_HFLOW_DTR 0x02 /* DTR is off/on when RX - fills/empties */ -#define WHITEHEAT_HFLOW_CTS 0x08 /* when received CTS off/on - will stop/start TX */ -#define WHITEHEAT_HFLOW_DSR 0x10 /* when received DSR off/on - will stop/start TX */ -#define WHITEHEAT_HFLOW_RTS 0x80 /* RTS is off/on when RX - fills/empties */ - -struct whiteheat_port_settings { - __u8 port; /* port number (1 to N) */ - __u32 baud; /* any value 7 - 460800, firmware calculates - best fit; arrives little endian */ - __u8 bits; /* 5, 6, 7, or 8 */ - __u8 stop; /* 1 or 2, default 1 (2 = 1.5 if bits = 5) */ - __u8 parity; /* see WHITEHEAT_PAR_* above */ - __u8 sflow; /* see WHITEHEAT_SFLOW_* above */ - __u8 xoff; /* XOFF byte value */ - __u8 xon; /* XON byte value */ - __u8 hflow; /* see WHITEHEAT_HFLOW_* above */ - __u8 lloop; /* 0/1 turns local loopback mode off/on */ -} __attribute__ ((packed)); - - -/* - * WHITEHEAT_SET_RTS - * WHITEHEAT_SET_DTR - * WHITEHEAT_SET_BREAK - */ -#define WHITEHEAT_RTS_OFF 0x00 -#define WHITEHEAT_RTS_ON 0x01 -#define WHITEHEAT_DTR_OFF 0x00 -#define WHITEHEAT_DTR_ON 0x01 -#define WHITEHEAT_BREAK_OFF 0x00 -#define WHITEHEAT_BREAK_ON 0x01 - -struct whiteheat_set_rdb { - __u8 port; /* port number (1 to N) */ - __u8 state; /* 0/1 turns signal off/on */ -}; - - -/* - * WHITEHEAT_DUMP - */ -#define WHITEHEAT_DUMP_MEM_DATA 'd' /* data */ -#define WHITEHEAT_DUMP_MEM_IDATA 'i' /* idata */ -#define WHITEHEAT_DUMP_MEM_BDATA 'b' /* bdata */ -#define WHITEHEAT_DUMP_MEM_XDATA 'x' /* xdata */ - -/* - * Allowable address ranges (firmware checks address): - * Type DATA: 0x00 - 0xff - * Type IDATA: 0x80 - 0xff - * Type BDATA: 0x20 - 0x2f - * Type XDATA: 0x0000 - 0xffff - * - * B/I/DATA all read the local memory space - * XDATA reads the external memory space - * BDATA returns bits as bytes - * - * NOTE: 0x80 - 0xff (local space) are the Special Function Registers - * of the 8051, and some have on-read side-effects. - */ - -struct whiteheat_dump { - __u8 mem_type; /* see WHITEHEAT_DUMP_* above */ - __u16 addr; /* address, see restrictions above */ - __u16 length; /* number of bytes to dump, max 63 bytes */ -}; - - -/* - * WHITEHEAT_PURGE - */ -#define WHITEHEAT_PURGE_RX 0x01 /* purge rx fifos */ -#define WHITEHEAT_PURGE_TX 0x02 /* purge tx fifos */ - -struct whiteheat_purge { - __u8 port; /* port number (1 to N) */ - __u8 what; /* bit pattern of what to purge */ -}; - - -/* - * WHITEHEAT_ECHO - */ -struct whiteheat_echo { - __u8 port; /* port number (1 to N) */ - __u8 length; /* length of message to echo, max 61 bytes */ - __u8 echo_data[61]; /* data to echo */ -}; - - -/* - * WHITEHEAT_DO_TEST - */ -#define WHITEHEAT_TEST_UART_RW 0x01 /* read/write uart registers */ -#define WHITEHEAT_TEST_UART_INTR 0x02 /* uart interrupt */ -#define WHITEHEAT_TEST_SETUP_CONT 0x03 /* setup for - PORT_CONT/PORT_DISCONT */ -#define WHITEHEAT_TEST_PORT_CONT 0x04 /* port connect */ -#define WHITEHEAT_TEST_PORT_DISCONT 0x05 /* port disconnect */ -#define WHITEHEAT_TEST_UART_CLK_START 0x06 /* uart clock test start */ -#define WHITEHEAT_TEST_UART_CLK_STOP 0x07 /* uart clock test stop */ -#define WHITEHEAT_TEST_MODEM_FT 0x08 /* modem signals, requires a - loopback cable/connector */ -#define WHITEHEAT_TEST_ERASE_EEPROM 0x09 /* erase eeprom */ -#define WHITEHEAT_TEST_READ_EEPROM 0x0a /* read eeprom */ -#define WHITEHEAT_TEST_PROGRAM_EEPROM 0x0b /* program eeprom */ - -struct whiteheat_test { - __u8 port; /* port number (1 to n) */ - __u8 test; /* see WHITEHEAT_TEST_* above*/ - __u8 info[32]; /* additional info */ -}; - - -/* - * Replies from the firmware - */ - - -/* - * WHITEHEAT_STATUS - */ -#define WHITEHEAT_EVENT_MODEM 0x01 /* modem field is valid */ -#define WHITEHEAT_EVENT_ERROR 0x02 /* error field is valid */ -#define WHITEHEAT_EVENT_FLOW 0x04 /* flow field is valid */ -#define WHITEHEAT_EVENT_CONNECT 0x08 /* connect field is valid */ - -#define WHITEHEAT_FLOW_NONE 0x00 /* no flow control active */ -#define WHITEHEAT_FLOW_HARD_OUT 0x01 /* TX is stopped by CTS - (waiting for CTS to go on) */ -#define WHITEHEAT_FLOW_HARD_IN 0x02 /* remote TX is stopped - by RTS */ -#define WHITEHEAT_FLOW_SOFT_OUT 0x04 /* TX is stopped by XOFF - received (waiting for XON) */ -#define WHITEHEAT_FLOW_SOFT_IN 0x08 /* remote TX is stopped by XOFF - transmitted */ -#define WHITEHEAT_FLOW_TX_DONE 0x80 /* TX has completed */ - -struct whiteheat_status_info { - __u8 port; /* port number (1 to N) */ - __u8 event; /* indicates what the current event is, - see WHITEHEAT_EVENT_* above */ - __u8 modem; /* modem signal status (copy of uart's - MSR register) */ - __u8 error; /* line status (copy of uart's LSR register) */ - __u8 flow; /* flow control state, see WHITEHEAT_FLOW_* - above */ - __u8 connect; /* 0 means not connected, non-zero means - connected */ -}; - - -/* - * WHITEHEAT_GET_DTR_RTS - */ -struct whiteheat_dr_info { - __u8 mcr; /* copy of uart's MCR register */ -}; - - -/* - * WHITEHEAT_GET_HW_INFO - */ -struct whiteheat_hw_info { - __u8 hw_id; /* hardware id number, WhiteHEAT = 0 */ - __u8 sw_major_rev; /* major version number */ - __u8 sw_minor_rev; /* minor version number */ - struct whiteheat_hw_eeprom_info { - __u8 b0; /* B0 */ - __u8 vendor_id_low; /* vendor id (low byte) */ - __u8 vendor_id_high; /* vendor id (high byte) */ - __u8 product_id_low; /* product id (low byte) */ - __u8 product_id_high; /* product id (high byte) */ - __u8 device_id_low; /* device id (low byte) */ - __u8 device_id_high; /* device id (high byte) */ - __u8 not_used_1; - __u8 serial_number_0; /* serial number (low byte) */ - __u8 serial_number_1; /* serial number */ - __u8 serial_number_2; /* serial number */ - __u8 serial_number_3; /* serial number (high byte) */ - __u8 not_used_2; - __u8 not_used_3; - __u8 checksum_low; /* checksum (low byte) */ - __u8 checksum_high; /* checksum (high byte */ - } hw_eeprom_info; /* EEPROM contents */ -}; - - -/* - * WHITEHEAT_EVENT - */ -struct whiteheat_event_info { - __u8 port; /* port number (1 to N) */ - __u8 event; /* see whiteheat_status_info.event */ - __u8 info; /* see whiteheat_status_info.modem, .error, - .flow, .connect */ -}; - - -/* - * WHITEHEAT_DO_TEST - */ -#define WHITEHEAT_TEST_FAIL 0x00 /* test failed */ -#define WHITEHEAT_TEST_UNKNOWN 0x01 /* unknown test requested */ -#define WHITEHEAT_TEST_PASS 0xff /* test passed */ - -struct whiteheat_test_info { - __u8 port; /* port number (1 to N) */ - __u8 test; /* indicates which test this is a response for, - see WHITEHEAT_DO_TEST above */ - __u8 status; /* see WHITEHEAT_TEST_* above */ - __u8 results[32]; /* test-dependent results */ -}; - - -#endif diff --git a/ANDROID_3.4.5/drivers/usb/serial/zio.c b/ANDROID_3.4.5/drivers/usb/serial/zio.c deleted file mode 100644 index 9d0bb375..00000000 --- a/ANDROID_3.4.5/drivers/usb/serial/zio.c +++ /dev/null @@ -1,46 +0,0 @@ -/* - * ZIO Motherboard USB driver - * - * Copyright (C) 2010 Zilogic Systems <code@zilogic.com> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License version - * 2 as published by the Free Software Foundation. - */ - -#include <linux/kernel.h> -#include <linux/init.h> -#include <linux/tty.h> -#include <linux/module.h> -#include <linux/usb.h> -#include <linux/usb/serial.h> -#include <linux/uaccess.h> - -static const struct usb_device_id id_table[] = { - { USB_DEVICE(0x1CBE, 0x0103) }, - { }, -}; -MODULE_DEVICE_TABLE(usb, id_table); - -static struct usb_driver zio_driver = { - .name = "zio", - .probe = usb_serial_probe, - .disconnect = usb_serial_disconnect, - .id_table = id_table, -}; - -static struct usb_serial_driver zio_device = { - .driver = { - .owner = THIS_MODULE, - .name = "zio", - }, - .id_table = id_table, - .num_ports = 1, -}; - -static struct usb_serial_driver * const serial_drivers[] = { - &zio_device, NULL -}; - -module_usb_serial_driver(zio_driver, serial_drivers); -MODULE_LICENSE("GPL"); |