serqt_usb2.c revision 20b9d17715017ae4dd4ec87fabc36d33b9de708e
1d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton/* 2d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton * This code was developed for the Quatech USB line for linux, it used 3d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton * much of the code developed by Greg Kroah-Hartman for USB serial devices 4d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton * 5d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton */ 6d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 7d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton#include <linux/errno.h> 8d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton#include <linux/init.h> 9d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton#include <linux/slab.h> 10d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton#include <linux/tty.h> 11d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton#include <linux/tty_driver.h> 12d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton#include <linux/tty_flip.h> 13d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton#include <linux/module.h> 14d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton#include <linux/serial.h> 15d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton#include <linux/usb.h> 16d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton#include <linux/usb/serial.h> 17d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton#include <linux/uaccess.h> 18d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 19d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pembertonstatic int debug; 20d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 21d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton/* Version Information */ 22d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton#define DRIVER_VERSION "v2.14" 23d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton#define DRIVER_AUTHOR "Tim Gobeli, Quatech, Inc" 24d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton#define DRIVER_DESC "Quatech USB to Serial Driver" 25d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 26d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton#define USB_VENDOR_ID_QUATECH 0x061d /* Quatech VID */ 27d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton#define QUATECH_SSU100 0xC020 /* SSU100 */ 28d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton#define QUATECH_SSU200 0xC030 /* SSU200 */ 29d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton#define QUATECH_DSU100 0xC040 /* DSU100 */ 30d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton#define QUATECH_DSU200 0xC050 /* DSU200 */ 31d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton#define QUATECH_QSU100 0xC060 /* QSU100 */ 32d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton#define QUATECH_QSU200 0xC070 /* QSU200 */ 33d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton#define QUATECH_ESU100A 0xC080 /* ESU100A */ 34d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton#define QUATECH_ESU100B 0xC081 /* ESU100B */ 35d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton#define QUATECH_ESU200A 0xC0A0 /* ESU200A */ 36d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton#define QUATECH_ESU200B 0xC0A1 /* ESU200B */ 37d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton#define QUATECH_HSU100A 0xC090 /* HSU100A */ 38d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton#define QUATECH_HSU100B 0xC091 /* HSU100B */ 39d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton#define QUATECH_HSU100C 0xC092 /* HSU100C */ 40d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton#define QUATECH_HSU100D 0xC093 /* HSU100D */ 41d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton#define QUATECH_HSU200A 0xC0B0 /* HSU200A */ 42d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton#define QUATECH_HSU200B 0xC0B1 /* HSU200B */ 43d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton#define QUATECH_HSU200C 0xC0B2 /* HSU200C */ 44d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton#define QUATECH_HSU200D 0xC0B3 /* HSU200D */ 45d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton#define QUATECH_SSU100_2 0xC120 /* SSU100_2 */ 46d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton#define QUATECH_DSU100_2 0xC140 /* DSU100_2 */ 47d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton#define QUATECH_DSU400_2 0xC150 /* DSU400_2 */ 48d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton#define QUATECH_QSU100_2 0xC160 /* QSU100_2 */ 49d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton#define QUATECH_QSU400_2 0xC170 /* QSU400_2 */ 50d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton#define QUATECH_ESU400_2 0xC180 /* ESU400_2 */ 51d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton#define QUATECH_ESU100_2 0xC1A0 /* ESU100_2 */ 52d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 53d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton#define QT_SET_GET_DEVICE 0xc2 54d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton#define QT_OPEN_CLOSE_CHANNEL 0xca 55d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton#define QT_GET_SET_PREBUF_TRIG_LVL 0xcc 56d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton#define QT_SET_ATF 0xcd 57d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton#define QT_GET_SET_REGISTER 0xc0 58d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton#define QT_GET_SET_UART 0xc1 59d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton#define QT_HW_FLOW_CONTROL_MASK 0xc5 60d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton#define QT_SW_FLOW_CONTROL_MASK 0xc6 61d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton#define QT_SW_FLOW_CONTROL_DISABLE 0xc7 62d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton#define QT_BREAK_CONTROL 0xc8 63d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 64d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton#define USBD_TRANSFER_DIRECTION_IN 0xc0 65d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton#define USBD_TRANSFER_DIRECTION_OUT 0x40 66d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 67d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton#define MAX_BAUD_RATE 460800 68d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton#define MAX_BAUD_REMAINDER 4608 69d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 70d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton#define DIV_LATCH_LS 0x00 71d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton#define XMT_HOLD_REGISTER 0x00 72d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton#define XVR_BUFFER_REGISTER 0x00 73d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton#define DIV_LATCH_MS 0x01 74d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton#define FIFO_CONTROL_REGISTER 0x02 75d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton#define LINE_CONTROL_REGISTER 0x03 76d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton#define MODEM_CONTROL_REGISTER 0x04 77d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton#define LINE_STATUS_REGISTER 0x05 78d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton#define MODEM_STATUS_REGISTER 0x06 79d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 80d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton#define SERIAL_MCR_DTR 0x01 81d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton#define SERIAL_MCR_RTS 0x02 82d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton#define SERIAL_MCR_LOOP 0x10 83d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 84d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton#define SERIAL_MSR_CTS 0x10 85d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton#define SERIAL_MSR_CD 0x80 86d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton#define SERIAL_MSR_RI 0x40 87d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton#define SERIAL_MSR_DSR 0x20 88d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton#define SERIAL_MSR_MASK 0xf0 89d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 90d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton#define SERIAL_8_DATA 0x03 91d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton#define SERIAL_7_DATA 0x02 92d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton#define SERIAL_6_DATA 0x01 93d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton#define SERIAL_5_DATA 0x00 94d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 95d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton#define SERIAL_ODD_PARITY 0X08 96d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton#define SERIAL_EVEN_PARITY 0X18 97d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton#define SERIAL_TWO_STOPB 0x04 98d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton#define SERIAL_ONE_STOPB 0x00 99d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 100d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton#define DEFAULT_DIVISOR 0x30 /* gives 9600 baud rate */ 101d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton#define DEFAULT_LCR SERIAL_8_DATA /* 8, none , 1 */ 102d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 103d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton#define FULLPWRBIT 0x00000080 104d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton#define NEXT_BOARD_POWER_BIT 0x00000004 105d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 106d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton#define SERIAL_LSR_OE 0x02 107d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton#define SERIAL_LSR_PE 0x04 108d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton#define SERIAL_LSR_FE 0x08 109d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton#define SERIAL_LSR_BI 0x10 110d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 111d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton#define SERIAL_MSR_CTS 0x10 112d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton#define SERIAL_MSR_CD 0x80 113d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton#define SERIAL_MSR_RI 0x40 114d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton#define SERIAL_MSR_DSR 0x20 115d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton#define SERIAL_MSR_MASK 0xf0 116d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 117d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton#define PREFUFF_LEVEL_CONSERVATIVE 128 118d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton#define ATC_DISABLED 0x0 119d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 120d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton#define RR_BITS 0x03 /* for clearing clock bits */ 121d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton#define DUPMODE_BITS 0xc0 122d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton#define CLKS_X4 0x02 123d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 124d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton#define LOOPMODE_BITS 0x41 /* LOOP1 = b6, LOOP0 = b0 (PORT B) */ 125d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton#define ALL_LOOPBACK 0x01 126d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton#define MODEM_CTRL 0x40 127d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton#define RS232_MODE 0x00 128d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 129a457732b836b970c82c7ba35b4cfc938c9c543f9Németh Mártonstatic const struct usb_device_id serqt_id_table[] = { 130d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton {USB_DEVICE(USB_VENDOR_ID_QUATECH, QUATECH_SSU100)}, 131d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton {USB_DEVICE(USB_VENDOR_ID_QUATECH, QUATECH_SSU200)}, 132d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton {USB_DEVICE(USB_VENDOR_ID_QUATECH, QUATECH_DSU100)}, 133d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton {USB_DEVICE(USB_VENDOR_ID_QUATECH, QUATECH_DSU200)}, 134d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton {USB_DEVICE(USB_VENDOR_ID_QUATECH, QUATECH_QSU100)}, 135d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton {USB_DEVICE(USB_VENDOR_ID_QUATECH, QUATECH_QSU200)}, 136d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton {USB_DEVICE(USB_VENDOR_ID_QUATECH, QUATECH_ESU100A)}, 137d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton {USB_DEVICE(USB_VENDOR_ID_QUATECH, QUATECH_ESU100B)}, 138d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton {USB_DEVICE(USB_VENDOR_ID_QUATECH, QUATECH_ESU200A)}, 139d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton {USB_DEVICE(USB_VENDOR_ID_QUATECH, QUATECH_ESU200B)}, 140d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton {USB_DEVICE(USB_VENDOR_ID_QUATECH, QUATECH_HSU100A)}, 141d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton {USB_DEVICE(USB_VENDOR_ID_QUATECH, QUATECH_HSU100B)}, 142d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton {USB_DEVICE(USB_VENDOR_ID_QUATECH, QUATECH_HSU100C)}, 143d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton {USB_DEVICE(USB_VENDOR_ID_QUATECH, QUATECH_HSU100D)}, 144d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton {USB_DEVICE(USB_VENDOR_ID_QUATECH, QUATECH_HSU200A)}, 145d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton {USB_DEVICE(USB_VENDOR_ID_QUATECH, QUATECH_HSU200B)}, 146d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton {USB_DEVICE(USB_VENDOR_ID_QUATECH, QUATECH_HSU200C)}, 147d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton {USB_DEVICE(USB_VENDOR_ID_QUATECH, QUATECH_HSU200D)}, 148d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton {USB_DEVICE(USB_VENDOR_ID_QUATECH, QUATECH_SSU100_2)}, 149d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton {USB_DEVICE(USB_VENDOR_ID_QUATECH, QUATECH_DSU100_2)}, 150d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton {USB_DEVICE(USB_VENDOR_ID_QUATECH, QUATECH_DSU400_2)}, 151d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton {USB_DEVICE(USB_VENDOR_ID_QUATECH, QUATECH_QSU100_2)}, 152d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton {USB_DEVICE(USB_VENDOR_ID_QUATECH, QUATECH_QSU400_2)}, 153d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton {USB_DEVICE(USB_VENDOR_ID_QUATECH, QUATECH_ESU400_2)}, 154d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton {USB_DEVICE(USB_VENDOR_ID_QUATECH, QUATECH_ESU100_2)}, 155d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton {} /* Terminating entry */ 156d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton}; 157d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 158d75662e164d5175c5e5f9339ff4d6f6980613d96Bill PembertonMODULE_DEVICE_TABLE(usb, serqt_id_table); 159d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 160d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pembertonstruct qt_get_device_data { 161d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton __u8 porta; 162d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton __u8 portb; 163d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton __u8 portc; 164d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton}; 165d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 166d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pembertonstruct qt_open_channel_data { 167d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton __u8 line_status; 168d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton __u8 modem_status; 169d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton}; 170d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 171d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pembertonstruct quatech_port { 172d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton int port_num; /* number of the port */ 173d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton struct urb *write_urb; /* write URB for this port */ 174d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton struct urb *read_urb; /* read URB for this port */ 175d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton struct urb *int_urb; 176d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 177d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton __u8 shadowLCR; /* last LCR value received */ 178d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton __u8 shadowMCR; /* last MCR value received */ 179d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton __u8 shadowMSR; /* last MSR value received */ 180d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton __u8 shadowLSR; /* last LSR value received */ 181d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton char open_ports; 182d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 183d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton /* Used for TIOCMIWAIT */ 184d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton wait_queue_head_t msr_wait; 185d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton char prev_status, diff_status; 186d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 187d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton wait_queue_head_t wait; 188d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 189d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton struct async_icount icount; 190d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 191d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton struct usb_serial_port *port; /* owner of this object */ 192d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton struct qt_get_device_data DeviceData; 193d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton spinlock_t lock; 194d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton bool read_urb_busy; 195d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton int RxHolding; 196d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton int ReadBulkStopped; 197d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton char closePending; 198d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton}; 199d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 200d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pembertonstatic struct usb_driver serqt_usb_driver = { 201d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton .name = "quatech-usb-serial", 202d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton .probe = usb_serial_probe, 203d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton .disconnect = usb_serial_disconnect, 204d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton .id_table = serqt_id_table, 205d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton .no_dynamic_id = 1, 206d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton}; 207d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 208d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pembertonstatic int port_paranoia_check(struct usb_serial_port *port, 209d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton const char *function) 210d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton{ 211d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton if (!port) { 212d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton dbg("%s - port == NULL", function); 213d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton return -1; 214d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton } 215d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton if (!port->serial) { 216d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton dbg("%s - port->serial == NULL\n", function); 217d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton return -1; 218d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton } 219d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 220d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton return 0; 221d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton} 222d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 223d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pembertonstatic int serial_paranoia_check(struct usb_serial *serial, 224d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton const char *function) 225d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton{ 226d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton if (!serial) { 227d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton dbg("%s - serial == NULL\n", function); 228d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton return -1; 229d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton } 230d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 231d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton if (!serial->type) { 232d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton dbg("%s - serial->type == NULL!", function); 233d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton return -1; 234d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton } 235d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 236d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton return 0; 237d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton} 238d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 239d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pembertonstatic inline struct quatech_port *qt_get_port_private(struct usb_serial_port 240d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton *port) 241d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton{ 242d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton return (struct quatech_port *)usb_get_serial_port_data(port); 243d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton} 244d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 245d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pembertonstatic inline void qt_set_port_private(struct usb_serial_port *port, 246d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton struct quatech_port *data) 247d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton{ 248d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton usb_set_serial_port_data(port, (void *)data); 249d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton} 250d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 251d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pembertonstatic struct usb_serial *get_usb_serial(struct usb_serial_port *port, 252d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton const char *function) 253d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton{ 254d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton /* if no port was specified, or it fails a paranoia check */ 255d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton if (!port || 256d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton port_paranoia_check(port, function) || 257d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton serial_paranoia_check(port->serial, function)) { 258d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton /* 259d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton * then say that we dont have a valid usb_serial thing, 260d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton * which will end up genrating -ENODEV return values 261d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton */ 262d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton return NULL; 263d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton } 264d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 265d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton return port->serial; 266d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton} 267d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 268d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pembertonstatic void ProcessLineStatus(struct quatech_port *qt_port, 269d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton unsigned char line_status) 270d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton{ 271d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 272d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton qt_port->shadowLSR = 273d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton line_status & (SERIAL_LSR_OE | SERIAL_LSR_PE | SERIAL_LSR_FE | 274d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton SERIAL_LSR_BI); 275d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton return; 276d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton} 277d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 278d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pembertonstatic void ProcessModemStatus(struct quatech_port *qt_port, 279d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton unsigned char modem_status) 280d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton{ 281d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 282d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton qt_port->shadowMSR = modem_status; 283d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton wake_up_interruptible(&qt_port->wait); 284d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton return; 285d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton} 286d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 28794362fd7fbad653c9517efa4aa7cd8fdadd527b1Alan Coxstatic void ProcessRxChar(struct tty_struct *tty, struct usb_serial_port *port, 28894362fd7fbad653c9517efa4aa7cd8fdadd527b1Alan Cox unsigned char data) 289d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton{ 290d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton struct urb *urb = port->read_urb; 29194362fd7fbad653c9517efa4aa7cd8fdadd527b1Alan Cox if (urb->actual_length) 29294362fd7fbad653c9517efa4aa7cd8fdadd527b1Alan Cox tty_insert_flip_char(tty, data, TTY_NORMAL); 293d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton} 294d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 295d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pembertonstatic void qt_write_bulk_callback(struct urb *urb) 296d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton{ 297d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton struct tty_struct *tty; 298d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton int status; 299d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton struct quatech_port *quatech_port; 300d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 301d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton status = urb->status; 302d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 303d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton if (status) { 304d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton dbg("nonzero write bulk status received:%d\n", status); 305d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton return; 306d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton } 307d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 308d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton quatech_port = urb->context; 309d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 310d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton dbg("%s - port %d\n", __func__, quatech_port->port_num); 311d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 312d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton tty = tty_port_tty_get(&quatech_port->port->port); 313d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 314d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton if (tty) 315d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton tty_wakeup(tty); 316d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton tty_kref_put(tty); 317d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton} 318d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 319d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pembertonstatic void qt_interrupt_callback(struct urb *urb) 320d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton{ 321d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton /* FIXME */ 322d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton} 323d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 324d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pembertonstatic void qt_read_bulk_callback(struct urb *urb) 325d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton{ 326d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 327d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton struct usb_serial_port *port = urb->context; 328d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton struct usb_serial *serial = get_usb_serial(port, __func__); 329d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton struct quatech_port *qt_port = qt_get_port_private(port); 330d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton unsigned char *data; 331d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton struct tty_struct *tty; 332d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton unsigned int index; 333d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton unsigned int RxCount; 334d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton int i, result; 335d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton int flag, flag_data; 336d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 337d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton if (urb->status) { 338d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton qt_port->ReadBulkStopped = 1; 339d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton dbg("%s - nonzero write bulk status received: %d\n", 340d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton __func__, urb->status); 341d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton return; 342d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton } 343d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 344d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton tty = tty_port_tty_get(&port->port); 345d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton if (!tty) { 346d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton dbg("%s - bad tty pointer - exiting", __func__); 347d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton return; 348d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton } 349d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 350d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton data = urb->transfer_buffer; 351d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 352d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton RxCount = urb->actual_length; 353d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 354d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton /* index = MINOR(port->tty->device) - serial->minor; */ 355d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton index = tty->index - serial->minor; 356d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 357d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton dbg("%s - port %d\n", __func__, port->number); 358d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton dbg("%s - port->RxHolding = %d\n", __func__, qt_port->RxHolding); 359d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 360d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton if (port_paranoia_check(port, __func__) != 0) { 361d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton dbg("%s - port_paranoia_check, exiting\n", __func__); 362d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton qt_port->ReadBulkStopped = 1; 363f3a756883ac028c536479e2eb283477fec80c828Bill Pemberton goto exit; 364d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton } 365d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 366d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton if (!serial) { 367d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton dbg("%s - bad serial pointer, exiting\n", __func__); 368f3a756883ac028c536479e2eb283477fec80c828Bill Pemberton goto exit; 369d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton } 370d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton if (qt_port->closePending == 1) { 371d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton /* Were closing , stop reading */ 372d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton dbg("%s - (qt_port->closepending == 1\n", __func__); 373d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton qt_port->ReadBulkStopped = 1; 374f3a756883ac028c536479e2eb283477fec80c828Bill Pemberton goto exit; 375d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton } 376d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 377d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton /* 378d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton * RxHolding is asserted by throttle, if we assert it, we're not 379d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton * receiving any more characters and let the box handle the flow 380d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton * control 381d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton */ 382d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton if (qt_port->RxHolding == 1) { 383d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton qt_port->ReadBulkStopped = 1; 384f3a756883ac028c536479e2eb283477fec80c828Bill Pemberton goto exit; 385d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton } 386d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 387d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton if (urb->status) { 388d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton qt_port->ReadBulkStopped = 1; 389d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 390d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton dbg("%s - nonzero read bulk status received: %d\n", 391d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton __func__, urb->status); 392f3a756883ac028c536479e2eb283477fec80c828Bill Pemberton goto exit; 393d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton } 394d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 395d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton if (tty && RxCount) { 396d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton flag_data = 0; 397d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton for (i = 0; i < RxCount; ++i) { 398d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton /* Look ahead code here */ 399d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton if ((i <= (RxCount - 3)) && (data[i] == 0x1b) 400d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton && (data[i + 1] == 0x1b)) { 401d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton flag = 0; 402d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton switch (data[i + 2]) { 403d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton case 0x00: 404d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton /* line status change 4th byte must follow */ 405d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton if (i > (RxCount - 4)) { 406d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton dbg("Illegal escape seuences in received data\n"); 407d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton break; 408d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton } 409d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton ProcessLineStatus(qt_port, data[i + 3]); 410d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton i += 3; 411d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton flag = 1; 412d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton break; 413d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 414d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton case 0x01: 415d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton /* Modem status status change 4th byte must follow */ 4161695eb36bf4616c6ec062d2dc2c3abe54d3aa313Ruslan Pisarev dbg("Modem status status.\n"); 417d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton if (i > (RxCount - 4)) { 418d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton dbg("Illegal escape sequences in received data\n"); 419d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton break; 420d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton } 421d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton ProcessModemStatus(qt_port, 422d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton data[i + 3]); 423d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton i += 3; 424d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton flag = 1; 425d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton break; 426d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton case 0xff: 4271695eb36bf4616c6ec062d2dc2c3abe54d3aa313Ruslan Pisarev dbg("No status sequence.\n"); 428d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 42994362fd7fbad653c9517efa4aa7cd8fdadd527b1Alan Cox if (tty) { 43094362fd7fbad653c9517efa4aa7cd8fdadd527b1Alan Cox ProcessRxChar(tty, port, data[i]); 43194362fd7fbad653c9517efa4aa7cd8fdadd527b1Alan Cox ProcessRxChar(tty, port, data[i + 1]); 43294362fd7fbad653c9517efa4aa7cd8fdadd527b1Alan Cox } 433d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton i += 2; 434d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton break; 435d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton } 436d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton if (flag == 1) 437d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton continue; 438d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton } 439d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 44094362fd7fbad653c9517efa4aa7cd8fdadd527b1Alan Cox if (tty && urb->actual_length) 44194362fd7fbad653c9517efa4aa7cd8fdadd527b1Alan Cox tty_insert_flip_char(tty, data[i], TTY_NORMAL); 442d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 443d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton } 444d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton tty_flip_buffer_push(tty); 445d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton } 446d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 447d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton /* Continue trying to always read */ 448d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton usb_fill_bulk_urb(port->read_urb, serial->dev, 449d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton usb_rcvbulkpipe(serial->dev, 450d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton port->bulk_in_endpointAddress), 451d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton port->read_urb->transfer_buffer, 452d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton port->read_urb->transfer_buffer_length, 453d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton qt_read_bulk_callback, port); 454d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton result = usb_submit_urb(port->read_urb, GFP_ATOMIC); 455d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton if (result) 456d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton dbg("%s - failed resubmitting read urb, error %d", 457d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton __func__, result); 458d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton else { 459d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton if (tty && RxCount) { 460d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton tty_flip_buffer_push(tty); 461d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton tty_schedule_flip(tty); 462d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton } 463d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton } 464d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 465d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton schedule_work(&port->work); 466f3a756883ac028c536479e2eb283477fec80c828Bill Pembertonexit: 467f3a756883ac028c536479e2eb283477fec80c828Bill Pemberton tty_kref_put(tty); 468d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton} 469d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 470d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton/* 471d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton * qt_get_device 472d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton * Issue a GET_DEVICE vendor-specific request on the default control pipe If 473d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton * successful, fills in the qt_get_device_data structure pointed to by 474d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton * device_data, otherwise return a negative error number of the problem. 475d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton */ 476d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 477d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pembertonstatic int qt_get_device(struct usb_serial *serial, 478d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton struct qt_get_device_data *device_data) 479d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton{ 480d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton int result; 481d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton unsigned char *transfer_buffer; 482d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 483d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton transfer_buffer = 484d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton kmalloc(sizeof(struct qt_get_device_data), GFP_KERNEL); 485d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton if (!transfer_buffer) 486d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton return -ENOMEM; 487d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 488d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton result = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0), 489d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton QT_SET_GET_DEVICE, 0xc0, 0, 0, 490d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton transfer_buffer, 491d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton sizeof(struct qt_get_device_data), 300); 492d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton if (result > 0) 493d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton memcpy(device_data, transfer_buffer, 494d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton sizeof(struct qt_get_device_data)); 495d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton kfree(transfer_buffer); 496d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 497d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton return result; 498d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton} 499d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 500d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton/**************************************************************************** 501d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton * BoxSetPrebufferLevel 502d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton TELLS BOX WHEN TO ASSERT FLOW CONTROL 503d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton ****************************************************************************/ 504d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pembertonstatic int BoxSetPrebufferLevel(struct usb_serial *serial) 505d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton{ 506d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton int result; 507d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton __u16 buffer_length; 508d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 509d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton buffer_length = PREFUFF_LEVEL_CONSERVATIVE; 510d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton result = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0), 511d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton QT_GET_SET_PREBUF_TRIG_LVL, 0x40, 512d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton buffer_length, 0, NULL, 0, 300); 513d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton return result; 514d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton} 515d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 516d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton/**************************************************************************** 517d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton * BoxSetATC 518d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton TELLS BOX WHEN TO ASSERT automatic transmitter control 519d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton ****************************************************************************/ 520d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pembertonstatic int BoxSetATC(struct usb_serial *serial, __u16 n_Mode) 521d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton{ 522d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton int result; 523d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton __u16 buffer_length; 524d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 525d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton buffer_length = PREFUFF_LEVEL_CONSERVATIVE; 526d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 527d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton result = 528d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0), 529d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton QT_SET_ATF, 0x40, n_Mode, 0, NULL, 0, 300); 530d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 531d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton return result; 532d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton} 533d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 534d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton/** 535d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton * qt_set_device 536d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton * Issue a SET_DEVICE vendor-specific request on the default control pipe If 537d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton * successful returns the number of bytes written, otherwise it returns a 538d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton * negative error number of the problem. 539d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton */ 540d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pembertonstatic int qt_set_device(struct usb_serial *serial, 541d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton struct qt_get_device_data *device_data) 542d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton{ 543d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton int result; 544d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton __u16 length; 545d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton __u16 PortSettings; 546d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 547d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton PortSettings = ((__u16) (device_data->portb)); 548d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton PortSettings = (PortSettings << 8); 549d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton PortSettings += ((__u16) (device_data->porta)); 550d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 551d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton length = sizeof(struct qt_get_device_data); 552d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton dbg("%s - PortSettings = 0x%x\n", __func__, PortSettings); 553d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 554d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton result = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0), 555d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton QT_SET_GET_DEVICE, 0x40, PortSettings, 556d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 0, NULL, 0, 300); 557d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton return result; 558d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton} 559d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 560d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pembertonstatic int qt_open_channel(struct usb_serial *serial, __u16 Uart_Number, 561d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton struct qt_open_channel_data *pDeviceData) 562d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton{ 563d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton int result; 564d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 565d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton result = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0), 566d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton QT_OPEN_CLOSE_CHANNEL, 567d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton USBD_TRANSFER_DIRECTION_IN, 1, Uart_Number, 568d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton pDeviceData, 569d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton sizeof(struct qt_open_channel_data), 300); 570d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 571d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton return result; 572d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 573d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton} 574d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 575d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pembertonstatic int qt_close_channel(struct usb_serial *serial, __u16 Uart_Number) 576d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton{ 577d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton int result; 578d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 579d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton result = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0), 580d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton QT_OPEN_CLOSE_CHANNEL, 581d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton USBD_TRANSFER_DIRECTION_OUT, 0, Uart_Number, 582d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton NULL, 0, 300); 583d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 584d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton return result; 585d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 586d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton} 587d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 588d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton/**************************************************************************** 589d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton* BoxGetRegister 590d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton* issuse a GET_REGISTER vendor-spcific request on the default control pipe 591d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton* If successful, fills in the pValue with the register value asked for 592d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton****************************************************************************/ 593d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pembertonstatic int BoxGetRegister(struct usb_serial *serial, unsigned short Uart_Number, 594d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton unsigned short Register_Num, __u8 *pValue) 595d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton{ 596d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton int result; 597d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton __u16 current_length; 598d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 599d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton current_length = sizeof(struct qt_get_device_data); 600d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 601d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton result = 602d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0), 603d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton QT_GET_SET_REGISTER, 0xC0, Register_Num, 604d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton Uart_Number, (void *)pValue, sizeof(*pValue), 300); 605d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 606d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton return result; 607d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton} 608d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 609d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton/**************************************************************************** 610d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton* BoxSetRegister 611d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton* issuse a GET_REGISTER vendor-spcific request on the default control pipe 612d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton* If successful, fills in the pValue with the register value asked for 613d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton****************************************************************************/ 614d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pembertonstatic int BoxSetRegister(struct usb_serial *serial, unsigned short Uart_Number, 615d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton unsigned short Register_Num, unsigned short Value) 616d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton{ 617d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton int result; 618d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton unsigned short RegAndByte; 619d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 620d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton RegAndByte = Value; 621d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton RegAndByte = RegAndByte << 8; 622d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton RegAndByte = RegAndByte + Register_Num; 623d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 624d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton/* 625d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton result = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0), 626d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton QT_GET_SET_REGISTER, 0xC0, Register_Num, 627d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton Uart_Number, NULL, 0, 300); 628d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton*/ 629d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 630d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton result = 631d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0), 632d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton QT_GET_SET_REGISTER, 0x40, RegAndByte, Uart_Number, 633d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton NULL, 0, 300); 634d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 635d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton return result; 636d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton} 637d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 638d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton/* 639d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton * qt_setuart 640d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton * issuse a SET_UART vendor-spcific request on the default control pipe 641d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton * If successful sets baud rate divisor and LCR value 642d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton */ 643d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pembertonstatic int qt_setuart(struct usb_serial *serial, unsigned short Uart_Number, 644d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton unsigned short default_divisor, unsigned char default_LCR) 645d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton{ 646d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton int result; 647d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton unsigned short UartNumandLCR; 648d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 649d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton UartNumandLCR = (default_LCR << 8) + Uart_Number; 650d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 651d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton result = 652d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0), 653d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton QT_GET_SET_UART, 0x40, default_divisor, 654d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton UartNumandLCR, NULL, 0, 300); 655d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 656d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton return result; 657d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton} 658d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 659d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pembertonstatic int BoxSetHW_FlowCtrl(struct usb_serial *serial, unsigned int index, 660d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton int bSet) 661d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton{ 662d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton __u8 mcr = 0; 663d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton __u8 msr = 0, MOUT_Value = 0; 664d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton unsigned int status; 665d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 666d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton if (bSet == 1) { 667d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton /* flow control, box will clear RTS line to prevent remote */ 668d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton mcr = SERIAL_MCR_RTS; 669d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton } /* device from xmitting more chars */ 670d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton else { 671d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton /* no flow control to remote device */ 672d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton mcr = 0; 673d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 674d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton } 675d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton MOUT_Value = mcr << 8; 676d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 677d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton if (bSet == 1) { 678d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton /* flow control, box will inhibit xmit data if CTS line is 679d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton * asserted */ 680d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton msr = SERIAL_MSR_CTS; 681d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton } else { 682d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton /* Box will not inhimbe xmit data due to CTS line */ 683d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton msr = 0; 684d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton } 685d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton MOUT_Value |= msr; 686d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 687d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton status = 688d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0), 689d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton QT_HW_FLOW_CONTROL_MASK, 0x40, MOUT_Value, 690d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton index, NULL, 0, 300); 691d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton return status; 692d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 693d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton} 694d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 695d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pembertonstatic int BoxSetSW_FlowCtrl(struct usb_serial *serial, __u16 index, 696d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton unsigned char stop_char, unsigned char start_char) 697d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton{ 698d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton __u16 nSWflowout; 699d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton int result; 700d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 701d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton nSWflowout = start_char << 8; 702d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton nSWflowout = (unsigned short)stop_char; 703d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 704d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton result = 705d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0), 706d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton QT_SW_FLOW_CONTROL_MASK, 0x40, nSWflowout, 707d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton index, NULL, 0, 300); 708d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton return result; 709d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 710d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton} 711d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 712d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pembertonstatic int BoxDisable_SW_FlowCtrl(struct usb_serial *serial, __u16 index) 713d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton{ 714d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton int result; 715d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 716d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton result = 717d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0), 718d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton QT_SW_FLOW_CONTROL_DISABLE, 0x40, 0, index, 719d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton NULL, 0, 300); 720d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton return result; 721d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 722d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton} 723d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 724d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pembertonstatic int qt_startup(struct usb_serial *serial) 725d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton{ 726d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton struct usb_serial_port *port; 727d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton struct quatech_port *qt_port; 728d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton struct qt_get_device_data DeviceData; 729d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton int i; 730d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton int status; 731d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 732d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton dbg("enterting %s", __func__); 733d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 734d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton /* Now setup per port private data */ 735d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton for (i = 0; i < serial->num_ports; i++) { 736d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton port = serial->port[i]; 737d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton qt_port = kzalloc(sizeof(*qt_port), GFP_KERNEL); 738d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton if (!qt_port) { 739d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton dbg("%s: kmalloc for quatech_port (%d) failed!.", 740d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton __func__, i); 7411695eb36bf4616c6ec062d2dc2c3abe54d3aa313Ruslan Pisarev for (--i; i >= 0; i--) { 742de8f8bd63334fe2014be7d9ab3a81ce9b96e5d19Oliver Neukum port = serial->port[i]; 743de8f8bd63334fe2014be7d9ab3a81ce9b96e5d19Oliver Neukum kfree(usb_get_serial_port_data(port)); 744de8f8bd63334fe2014be7d9ab3a81ce9b96e5d19Oliver Neukum usb_set_serial_port_data(port, NULL); 745de8f8bd63334fe2014be7d9ab3a81ce9b96e5d19Oliver Neukum } 746d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton return -ENOMEM; 747d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton } 748d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton spin_lock_init(&qt_port->lock); 749d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 750d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton usb_set_serial_port_data(port, qt_port); 751d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 752d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton } 753d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 754d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton status = qt_get_device(serial, &DeviceData); 755d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton if (status < 0) { 756d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton dbg(__FILE__ "box_get_device failed"); 757d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton goto startup_error; 758d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton } 759d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 760d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton dbg(__FILE__ "DeviceData.portb = 0x%x", DeviceData.portb); 761d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 762d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton DeviceData.portb &= ~FULLPWRBIT; 763d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton dbg(__FILE__ "Changing DeviceData.portb to 0x%x", DeviceData.portb); 764d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 765d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton status = qt_set_device(serial, &DeviceData); 766d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton if (status < 0) { 767d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton dbg(__FILE__ "qt_set_device failed\n"); 768d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton goto startup_error; 769d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton } 770d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 771d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton status = qt_get_device(serial, &DeviceData); 772d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton if (status < 0) { 773d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton dbg(__FILE__ "qt_get_device failed"); 774d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton goto startup_error; 775d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton } 776d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 777d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton switch (serial->dev->descriptor.idProduct) { 778d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton case QUATECH_SSU100: 779d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton case QUATECH_DSU100: 780d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton case QUATECH_QSU100: 781d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton case QUATECH_ESU100A: 782d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton case QUATECH_ESU100B: 783d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton case QUATECH_HSU100A: 784d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton case QUATECH_HSU100B: 785d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton case QUATECH_HSU100C: 786d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton case QUATECH_HSU100D: 787d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton DeviceData.porta &= ~(RR_BITS | DUPMODE_BITS); 788d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton DeviceData.porta |= CLKS_X4; 789d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton DeviceData.portb &= ~(LOOPMODE_BITS); 790d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton DeviceData.portb |= RS232_MODE; 791d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton break; 792d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 793d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton case QUATECH_SSU200: 794d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton case QUATECH_DSU200: 795d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton case QUATECH_QSU200: 796d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton case QUATECH_ESU200A: 797d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton case QUATECH_ESU200B: 798d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton case QUATECH_HSU200A: 799d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton case QUATECH_HSU200B: 800d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton case QUATECH_HSU200C: 801d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton case QUATECH_HSU200D: 802d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton DeviceData.porta &= ~(RR_BITS | DUPMODE_BITS); 803d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton DeviceData.porta |= CLKS_X4; 804d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton DeviceData.portb &= ~(LOOPMODE_BITS); 805d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton DeviceData.portb |= ALL_LOOPBACK; 806d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton break; 807d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton default: 808d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton DeviceData.porta &= ~(RR_BITS | DUPMODE_BITS); 809d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton DeviceData.porta |= CLKS_X4; 810d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton DeviceData.portb &= ~(LOOPMODE_BITS); 811d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton DeviceData.portb |= RS232_MODE; 812d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton break; 813d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 814d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton } 815d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 816d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton status = BoxSetPrebufferLevel(serial); /* sets to default value */ 817d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton if (status < 0) { 818d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton dbg(__FILE__ "BoxSetPrebufferLevel failed\n"); 819d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton goto startup_error; 820d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton } 821d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 822d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton status = BoxSetATC(serial, ATC_DISABLED); 823d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton if (status < 0) { 824d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton dbg(__FILE__ "BoxSetATC failed\n"); 825d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton goto startup_error; 826d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton } 827d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 828d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton dbg(__FILE__ "DeviceData.portb = 0x%x", DeviceData.portb); 829d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 830d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton DeviceData.portb |= NEXT_BOARD_POWER_BIT; 831d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton dbg(__FILE__ "Changing DeviceData.portb to 0x%x", DeviceData.portb); 832d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 833d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton status = qt_set_device(serial, &DeviceData); 834d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton if (status < 0) { 835d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton dbg(__FILE__ "qt_set_device failed\n"); 836d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton goto startup_error; 837d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton } 838d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 839d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton dbg("Exit Success %s\n", __func__); 840d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 841d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton return 0; 842d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 843d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pembertonstartup_error: 844d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton for (i = 0; i < serial->num_ports; i++) { 845d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton port = serial->port[i]; 846d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton qt_port = qt_get_port_private(port); 847d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton kfree(qt_port); 848d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton usb_set_serial_port_data(port, NULL); 849d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton } 850d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 851d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton dbg("Exit fail %s\n", __func__); 852d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 853d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton return -EIO; 854d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton} 855d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 856d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pembertonstatic void qt_release(struct usb_serial *serial) 857d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton{ 858d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton struct usb_serial_port *port; 859d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton struct quatech_port *qt_port; 860d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton int i; 861d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 862d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton dbg("enterting %s", __func__); 863d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 864d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton for (i = 0; i < serial->num_ports; i++) { 865d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton port = serial->port[i]; 866d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton if (!port) 867d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton continue; 868d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 869d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton qt_port = usb_get_serial_port_data(port); 870d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton kfree(qt_port); 871d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton usb_set_serial_port_data(port, NULL); 872d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton } 873d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 874d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton} 875d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 87635e2bed559ab80641f1764aae570d92711ddc2faBill Pembertonstatic int qt_open(struct tty_struct *tty, 8772386b331802b1b2664c35f9f4c7aef778aac725fBill Pemberton struct usb_serial_port *port) 878d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton{ 879d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton struct usb_serial *serial; 880d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton struct quatech_port *quatech_port; 881d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton struct quatech_port *port0; 882d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton struct qt_open_channel_data ChannelData; 883d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 884d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton int result; 885d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 886d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton if (port_paranoia_check(port, __func__)) 887d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton return -ENODEV; 888d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 889d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton dbg("%s - port %d\n", __func__, port->number); 890d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 891d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton serial = port->serial; 892d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 893d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton if (serial_paranoia_check(serial, __func__)) 894d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton return -ENODEV; 895d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 896d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton quatech_port = qt_get_port_private(port); 897d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton port0 = qt_get_port_private(serial->port[0]); 898d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 899d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton if (quatech_port == NULL || port0 == NULL) 900d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton return -ENODEV; 901d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 902d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton usb_clear_halt(serial->dev, port->write_urb->pipe); 903d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton usb_clear_halt(serial->dev, port->read_urb->pipe); 904d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton port0->open_ports++; 905d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 906d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton result = qt_get_device(serial, &port0->DeviceData); 907d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 908d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton /* Port specific setups */ 909d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton result = qt_open_channel(serial, port->number, &ChannelData); 910d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton if (result < 0) { 911d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton dbg(__FILE__ "qt_open_channel failed\n"); 912d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton return result; 913d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton } 914d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton dbg(__FILE__ "qt_open_channel completed.\n"); 915d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 916d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton/* FIXME: are these needed? Does it even do anything useful? */ 917d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton quatech_port->shadowLSR = ChannelData.line_status & 918d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton (SERIAL_LSR_OE | SERIAL_LSR_PE | SERIAL_LSR_FE | SERIAL_LSR_BI); 919d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 920d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton quatech_port->shadowMSR = ChannelData.modem_status & 921d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton (SERIAL_MSR_CTS | SERIAL_MSR_DSR | SERIAL_MSR_RI | SERIAL_MSR_CD); 922d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 923d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton /* Set Baud rate to default and turn off (default)flow control here */ 924d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton result = qt_setuart(serial, port->number, DEFAULT_DIVISOR, DEFAULT_LCR); 925d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton if (result < 0) { 926d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton dbg(__FILE__ "qt_setuart failed\n"); 927d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton return result; 928d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton } 929d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton dbg(__FILE__ "qt_setuart completed.\n"); 930d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 931d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton /* 932bbc9a9916bc1cd997f3bf303e7930d5f3c804d37André Goddard Rosa * Put this here to make it responsive to stty and defaults set by 933d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton * the tty layer 934d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton */ 935d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton /* FIXME: is this needed? */ 936d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton /* qt_set_termios(tty, port, NULL); */ 937d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 938d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton /* Check to see if we've set up our endpoint info yet */ 939d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton if (port0->open_ports == 1) { 940d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton if (serial->port[0]->interrupt_in_buffer == NULL) { 941d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton /* set up interrupt urb */ 942d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton usb_fill_int_urb(serial->port[0]->interrupt_in_urb, 943d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton serial->dev, 944d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton usb_rcvintpipe(serial->dev, 945d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton serial->port[0]->interrupt_in_endpointAddress), 946d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton serial->port[0]->interrupt_in_buffer, 947d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton serial->port[0]-> 948d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton interrupt_in_urb->transfer_buffer_length, 949d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton qt_interrupt_callback, serial, 950d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton serial->port[0]-> 951d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton interrupt_in_urb->interval); 952d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 953d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton result = 954d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton usb_submit_urb(serial->port[0]->interrupt_in_urb, 955d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton GFP_KERNEL); 956d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton if (result) { 957d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton dev_err(&port->dev, 958d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton "%s - Error %d submitting " 959d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton "interrupt urb\n", __func__, result); 960d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton } 961d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 962d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton } 963d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 964d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton } 965d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 9661695eb36bf4616c6ec062d2dc2c3abe54d3aa313Ruslan Pisarev dbg("port number is %d\n", port->number); 9671695eb36bf4616c6ec062d2dc2c3abe54d3aa313Ruslan Pisarev dbg("serial number is %d\n", port->serial->minor); 9681695eb36bf4616c6ec062d2dc2c3abe54d3aa313Ruslan Pisarev dbg("Bulkin endpoint is %d\n", port->bulk_in_endpointAddress); 9691695eb36bf4616c6ec062d2dc2c3abe54d3aa313Ruslan Pisarev dbg("BulkOut endpoint is %d\n", port->bulk_out_endpointAddress); 9701695eb36bf4616c6ec062d2dc2c3abe54d3aa313Ruslan Pisarev dbg("Interrupt endpoint is %d\n", port->interrupt_in_endpointAddress); 971d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton dbg("port's number in the device is %d\n", quatech_port->port_num); 972d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton quatech_port->read_urb = port->read_urb; 973d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 974d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton /* set up our bulk in urb */ 975d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 976d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton usb_fill_bulk_urb(quatech_port->read_urb, 977d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton serial->dev, 978d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton usb_rcvbulkpipe(serial->dev, 979d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton port->bulk_in_endpointAddress), 980d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton port->bulk_in_buffer, 981d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton quatech_port->read_urb->transfer_buffer_length, 982d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton qt_read_bulk_callback, quatech_port); 983d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 984d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton dbg("qt_open: bulkin endpoint is %d\n", port->bulk_in_endpointAddress); 985d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton quatech_port->read_urb_busy = true; 986d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton result = usb_submit_urb(quatech_port->read_urb, GFP_KERNEL); 987d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton if (result) { 988d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton dev_err(&port->dev, 989d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton "%s - Error %d submitting control urb\n", 990d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton __func__, result); 991d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton quatech_port->read_urb_busy = false; 992d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton } 993d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 994d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton /* initialize our wait queues */ 995d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton init_waitqueue_head(&quatech_port->wait); 996d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton init_waitqueue_head(&quatech_port->msr_wait); 997d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 998d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton /* initialize our icount structure */ 999d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton memset(&(quatech_port->icount), 0x00, sizeof(quatech_port->icount)); 1000d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 1001d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton return 0; 1002d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 1003d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton} 1004d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 1005d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pembertonstatic int qt_chars_in_buffer(struct tty_struct *tty) 1006d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton{ 1007d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton struct usb_serial_port *port = tty->driver_data; 1008d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton struct usb_serial *serial; 1009d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton int chars = 0; 1010d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 1011d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton serial = get_usb_serial(port, __func__); 1012d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 1013d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton dbg("%s - port %d\n", __func__, port->number); 1014d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 1015d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton if (serial->num_bulk_out) { 1016d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton if (port->write_urb->status == -EINPROGRESS) 1017d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton chars = port->write_urb->transfer_buffer_length; 1018d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton } 1019d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 1020d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton dbg("%s - returns %d\n", __func__, chars); 1021d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 1022d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton return chars; 1023d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton} 1024d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 1025d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pembertonstatic void qt_block_until_empty(struct tty_struct *tty, 1026d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton struct quatech_port *qt_port) 1027d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton{ 1028d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton int timeout = HZ / 10; 1029d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton int wait = 30; 1030d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton int count; 1031d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 1032d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton while (1) { 1033d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 1034d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton count = qt_chars_in_buffer(tty); 1035d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 1036d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton if (count <= 0) 1037d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton return; 1038d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 1039d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton interruptible_sleep_on_timeout(&qt_port->wait, timeout); 1040d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 1041d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton wait--; 1042d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton if (wait == 0) { 1043d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton dbg("%s - TIMEOUT", __func__); 1044d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton return; 1045d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton } else { 1046d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton wait = 30; 1047d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton } 1048d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton } 1049d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton} 1050d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 1051f3a756883ac028c536479e2eb283477fec80c828Bill Pembertonstatic void qt_close(struct usb_serial_port *port) 1052d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton{ 1053d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton struct usb_serial *serial = port->serial; 1054d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton struct quatech_port *qt_port; 1055d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton struct quatech_port *port0; 1056d9dea3c1c0814a87cc579b425e9776b8ed46b31fBill Pemberton struct tty_struct *tty; 1057d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton int status; 1058d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton unsigned int index; 1059d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton status = 0; 1060d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 1061d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton dbg("%s - port %d\n", __func__, port->number); 1062d9dea3c1c0814a87cc579b425e9776b8ed46b31fBill Pemberton 1063d9dea3c1c0814a87cc579b425e9776b8ed46b31fBill Pemberton tty = tty_port_tty_get(&port->port); 1064d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton index = tty->index - serial->minor; 1065d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 1066d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton qt_port = qt_get_port_private(port); 1067d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton port0 = qt_get_port_private(serial->port[0]); 1068d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 1069d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton /* shutdown any bulk reads that might be going on */ 1070d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton if (serial->num_bulk_out) 1071d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton usb_unlink_urb(port->write_urb); 1072d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton if (serial->num_bulk_in) 1073d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton usb_unlink_urb(port->read_urb); 1074d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 1075d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton /* wait up to for transmitter to empty */ 1076d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton if (serial->dev) 1077d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton qt_block_until_empty(tty, qt_port); 1078f3a756883ac028c536479e2eb283477fec80c828Bill Pemberton tty_kref_put(tty); 1079d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 1080d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton /* Close uart channel */ 1081d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton status = qt_close_channel(serial, index); 1082d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton if (status < 0) 1083d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton dbg("%s - port %d qt_close_channel failed.\n", 1084d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton __func__, port->number); 1085d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 1086d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton port0->open_ports--; 1087d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 1088d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton dbg("qt_num_open_ports in close%d:in port%d\n", 1089d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton port0->open_ports, port->number); 1090d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 1091d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton if (port0->open_ports == 0) { 1092d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton if (serial->port[0]->interrupt_in_urb) { 1093d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton dbg("%s", "Shutdown interrupt_in_urb\n"); 1094d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton usb_kill_urb(serial->port[0]->interrupt_in_urb); 1095d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton } 1096d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 1097d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton } 1098d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 1099d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton if (qt_port->write_urb) { 1100d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton /* if this urb had a transfer buffer already (old tx) free it */ 1101d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton if (qt_port->write_urb->transfer_buffer != NULL) 1102d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton kfree(qt_port->write_urb->transfer_buffer); 1103d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton usb_free_urb(qt_port->write_urb); 1104d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton } 1105d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 1106d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton} 1107d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 1108d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pembertonstatic int qt_write(struct tty_struct *tty, struct usb_serial_port *port, 1109d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton const unsigned char *buf, int count) 1110d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton{ 1111d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton int result; 1112d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton struct usb_serial *serial = get_usb_serial(port, __func__); 1113d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 1114d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton if (serial == NULL) 1115d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton return -ENODEV; 1116d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 1117d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton dbg("%s - port %d\n", __func__, port->number); 1118d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 1119d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton if (count == 0) { 1120d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton dbg("%s - write request of 0 bytes\n", __func__); 1121d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton return 0; 1122d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton } 1123d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 1124d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton /* only do something if we have a bulk out endpoint */ 1125d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton if (serial->num_bulk_out) { 1126d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton if (port->write_urb->status == -EINPROGRESS) { 1127d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton dbg("%s - already writing\n", __func__); 1128d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton return 0; 1129d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton } 1130d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 1131d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton count = 1132d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton (count > port->bulk_out_size) ? port->bulk_out_size : count; 1133d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton memcpy(port->write_urb->transfer_buffer, buf, count); 1134d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 1135d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton /* set up our urb */ 1136d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 1137d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton usb_fill_bulk_urb(port->write_urb, serial->dev, 1138d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton usb_sndbulkpipe(serial->dev, 1139d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton port-> 1140d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton bulk_out_endpointAddress), 1141d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton port->write_urb->transfer_buffer, count, 1142d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton qt_write_bulk_callback, port); 1143d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 1144d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton /* send the data out the bulk port */ 1145d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton result = usb_submit_urb(port->write_urb, GFP_ATOMIC); 1146d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton if (result) 1147d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton dbg("%s - failed submitting write urb, error %d\n", 1148d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton __func__, result); 1149d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton else 1150d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton result = count; 1151d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 1152d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton return result; 1153d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton } 1154d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 1155d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton /* no bulk out, so return 0 bytes written */ 1156d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton return 0; 1157d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton} 1158d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 1159d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pembertonstatic int qt_write_room(struct tty_struct *tty) 1160d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton{ 1161d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton struct usb_serial_port *port = tty->driver_data; 1162d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton struct usb_serial *serial; 1163d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton struct quatech_port *qt_port; 1164d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton unsigned long flags; 1165d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 1166d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton int retval = -EINVAL; 1167d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 1168d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton if (port_paranoia_check(port, __func__)) { 1169d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton dbg("%s", "Invalid port\n"); 1170d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton return -1; 1171d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton } 1172d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 1173d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton serial = get_usb_serial(port, __func__); 1174d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 1175d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton if (!serial) 1176d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton return -ENODEV; 1177d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 1178d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton qt_port = qt_get_port_private(port); 1179d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 1180d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton spin_lock_irqsave(&qt_port->lock, flags); 1181d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 1182d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton dbg("%s - port %d\n", __func__, port->number); 1183d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 1184d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton if (serial->num_bulk_out) { 1185d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton if (port->write_urb->status != -EINPROGRESS) 1186d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton retval = port->bulk_out_size; 1187d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton } 1188d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 1189d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton spin_unlock_irqrestore(&qt_port->lock, flags); 1190d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton return retval; 1191d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 1192d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton} 1193d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 1194d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pembertonstatic int qt_ioctl(struct tty_struct *tty, struct file *file, 1195d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton unsigned int cmd, unsigned long arg) 1196d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton{ 1197d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton struct usb_serial_port *port = tty->driver_data; 1198d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton struct quatech_port *qt_port = qt_get_port_private(port); 1199d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton struct usb_serial *serial = get_usb_serial(port, __func__); 1200d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton unsigned int index; 1201d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 1202d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton dbg("%s cmd 0x%04x", __func__, cmd); 1203d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 1204d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton index = tty->index - serial->minor; 1205d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 1206d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton if (cmd == TIOCMIWAIT) { 1207d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton while (qt_port != NULL) { 1208d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton interruptible_sleep_on(&qt_port->msr_wait); 1209d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton if (signal_pending(current)) 1210d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton return -ERESTARTSYS; 1211d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton else { 1212d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton char diff = qt_port->diff_status; 1213d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 1214d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton if (diff == 0) 1215d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton return -EIO; /* no change => error */ 1216d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 1217d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton /* Consume all events */ 1218d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton qt_port->diff_status = 0; 1219d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 1220d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton if (((arg & TIOCM_RNG) 1221d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton && (diff & SERIAL_MSR_RI)) 1222d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton || ((arg & TIOCM_DSR) 1223d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton && (diff & SERIAL_MSR_DSR)) 1224d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton || ((arg & TIOCM_CD) 1225d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton && (diff & SERIAL_MSR_CD)) 1226d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton || ((arg & TIOCM_CTS) 1227d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton && (diff & SERIAL_MSR_CTS))) { 1228d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton return 0; 1229d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton } 1230d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton } 1231d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton } 1232d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton return 0; 1233d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton } 1234d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 1235d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton dbg("%s -No ioctl for that one. port = %d\n", __func__, port->number); 1236d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton return -ENOIOCTLCMD; 1237d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton} 1238d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 1239d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pembertonstatic void qt_set_termios(struct tty_struct *tty, 1240d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton struct usb_serial_port *port, 1241d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton struct ktermios *old_termios) 1242d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton{ 1243d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton struct ktermios *termios = tty->termios; 1244d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton unsigned char new_LCR = 0; 1245d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton unsigned int cflag = termios->c_cflag; 1246d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton unsigned int index; 1247d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton int baud, divisor, remainder; 1248d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton int status; 1249d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 1250d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton dbg("%s", __func__); 1251d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 1252d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton index = tty->index - port->serial->minor; 1253d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 1254d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton switch (cflag) { 1255d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton case CS5: 1256d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton new_LCR |= SERIAL_5_DATA; 1257d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton break; 1258d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton case CS6: 1259d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton new_LCR |= SERIAL_6_DATA; 1260d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton break; 1261d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton case CS7: 1262d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton new_LCR |= SERIAL_7_DATA; 1263d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton break; 1264d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton default: 1265d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton case CS8: 1266d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton new_LCR |= SERIAL_8_DATA; 1267d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton break; 1268d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton } 1269d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 1270d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton /* Parity stuff */ 1271d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton if (cflag & PARENB) { 1272d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton if (cflag & PARODD) 1273d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton new_LCR |= SERIAL_ODD_PARITY; 1274d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton else 1275d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton new_LCR |= SERIAL_EVEN_PARITY; 1276d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton } 1277d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton if (cflag & CSTOPB) 1278d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton new_LCR |= SERIAL_TWO_STOPB; 1279d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton else 128035f077dca73132dcac2cac1706417229a68f38c3Roel Kluin new_LCR |= SERIAL_ONE_STOPB; 1281d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 1282d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton dbg("%s - 4\n", __func__); 1283d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 1284d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton /* Thats the LCR stuff, go ahead and set it */ 1285d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton baud = tty_get_baud_rate(tty); 1286d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton if (!baud) 1287d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton /* pick a default, any default... */ 1288d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton baud = 9600; 1289d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 1290d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton dbg("%s - got baud = %d\n", __func__, baud); 1291d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 1292d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton divisor = MAX_BAUD_RATE / baud; 1293d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton remainder = MAX_BAUD_RATE % baud; 1294d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton /* Round to nearest divisor */ 1295d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton if (((remainder * 2) >= baud) && (baud != 110)) 1296d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton divisor++; 1297d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 1298d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton /* 1299d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton * Set Baud rate to default and turn off (default)flow control here 1300d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton */ 1301d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton status = 1302d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton qt_setuart(port->serial, index, (unsigned short)divisor, new_LCR); 1303d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton if (status < 0) { 1304d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton dbg(__FILE__ "qt_setuart failed\n"); 1305d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton return; 1306d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton } 1307d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 1308d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton /* Now determine flow control */ 1309d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton if (cflag & CRTSCTS) { 1310d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton dbg("%s - Enabling HW flow control port %d\n", __func__, 1311d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton port->number); 1312d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 1313d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton /* Enable RTS/CTS flow control */ 1314d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton status = BoxSetHW_FlowCtrl(port->serial, index, 1); 1315d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 1316d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton if (status < 0) { 1317d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton dbg(__FILE__ "BoxSetHW_FlowCtrl failed\n"); 1318d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton return; 1319d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton } 1320d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton } else { 1321d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton /* Disable RTS/CTS flow control */ 1322d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton dbg("%s - disabling HW flow control port %d\n", __func__, 1323d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton port->number); 1324d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 1325d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton status = BoxSetHW_FlowCtrl(port->serial, index, 0); 1326d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton if (status < 0) { 1327d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton dbg(__FILE__ "BoxSetHW_FlowCtrl failed\n"); 1328d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton return; 1329d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton } 1330d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 1331d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton } 1332d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 1333d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton /* if we are implementing XON/XOFF, set the start and stop character in 1334d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton * the device */ 1335d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton if (I_IXOFF(tty) || I_IXON(tty)) { 1336d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton unsigned char stop_char = STOP_CHAR(tty); 1337d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton unsigned char start_char = START_CHAR(tty); 1338d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton status = 1339d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton BoxSetSW_FlowCtrl(port->serial, index, stop_char, 1340d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton start_char); 1341d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton if (status < 0) 1342d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton dbg(__FILE__ "BoxSetSW_FlowCtrl (enabled) failed\n"); 1343d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 1344d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton } else { 1345d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton /* disable SW flow control */ 1346d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton status = BoxDisable_SW_FlowCtrl(port->serial, index); 1347d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton if (status < 0) 1348d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton dbg(__FILE__ "BoxSetSW_FlowCtrl (diabling) failed\n"); 1349d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 1350d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton } 1351d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton tty->termios->c_cflag &= ~CMSPAR; 1352d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton /* FIXME: Error cases should be returning the actual bits changed only */ 1353d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton} 1354d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 1355d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pembertonstatic void qt_break(struct tty_struct *tty, int break_state) 1356d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton{ 1357d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton struct usb_serial_port *port = tty->driver_data; 1358d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton struct usb_serial *serial = get_usb_serial(port, __func__); 1359d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton struct quatech_port *qt_port; 1360d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton u16 index, onoff; 1361d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton unsigned int result; 1362d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton unsigned long flags; 1363d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 1364d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton index = tty->index - serial->minor; 1365d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 1366d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton qt_port = qt_get_port_private(port); 1367d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 1368d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton if (break_state == -1) 1369d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton onoff = 1; 1370d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton else 1371d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton onoff = 0; 1372d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 1373d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton spin_lock_irqsave(&qt_port->lock, flags); 1374d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 1375d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton dbg("%s - port %d\n", __func__, port->number); 1376d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 1377d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton result = 1378d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0), 1379d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton QT_BREAK_CONTROL, 0x40, onoff, index, NULL, 0, 300); 1380d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 1381d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton spin_unlock_irqrestore(&qt_port->lock, flags); 1382d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton} 1383d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 1384d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pembertonstatic inline int qt_real_tiocmget(struct tty_struct *tty, 1385d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton struct usb_serial_port *port, 138660b33c133ca0b7c0b6072c87234b63fee6e80558Alan Cox struct usb_serial *serial) 1387d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton{ 1388d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 1389d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton u8 mcr; 1390d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton u8 msr; 1391d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton unsigned int result = 0; 1392d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton int status; 1393d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton unsigned int index; 1394d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 1395d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton dbg("%s - port %d, tty =0x%p\n", __func__, port->number, tty); 1396d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 1397d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton index = tty->index - serial->minor; 1398d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton status = 1399d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton BoxGetRegister(port->serial, index, MODEM_CONTROL_REGISTER, &mcr); 1400d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton if (status >= 0) { 1401d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton status = 1402d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton BoxGetRegister(port->serial, index, 1403d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton MODEM_STATUS_REGISTER, &msr); 1404d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 1405d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton } 1406d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 1407d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton if (status >= 0) { 1408d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton result = ((mcr & SERIAL_MCR_DTR) ? TIOCM_DTR : 0) 1409d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton /* DTR IS SET */ 1410d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton | ((mcr & SERIAL_MCR_RTS) ? TIOCM_RTS : 0) 1411d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton /* RTS IS SET */ 1412d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton | ((msr & SERIAL_MSR_CTS) ? TIOCM_CTS : 0) 1413d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton /* CTS is set */ 1414d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton | ((msr & SERIAL_MSR_CD) ? TIOCM_CAR : 0) 1415d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton /* Carrier detect is set */ 1416d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton | ((msr & SERIAL_MSR_RI) ? TIOCM_RI : 0) 1417d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton /* Ring indicator set */ 1418d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton | ((msr & SERIAL_MSR_DSR) ? TIOCM_DSR : 0); 1419d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton /* DSR is set */ 1420d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton return result; 1421d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 1422d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton } else 1423d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton return -ESPIPE; 1424d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton} 1425d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 1426d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pembertonstatic inline int qt_real_tiocmset(struct tty_struct *tty, 1427d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton struct usb_serial_port *port, 1428d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton struct usb_serial *serial, 1429d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton unsigned int value) 1430d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton{ 1431d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 1432d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton u8 mcr; 1433d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton int status; 1434d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton unsigned int index; 1435d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 1436d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton dbg("%s - port %d\n", __func__, port->number); 1437d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 1438d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton index = tty->index - serial->minor; 1439d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton status = 1440d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton BoxGetRegister(port->serial, index, MODEM_CONTROL_REGISTER, &mcr); 1441d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton if (status < 0) 1442d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton return -ESPIPE; 1443d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 1444d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton /* 1445d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton * Turn off the RTS and DTR and loopbcck and then only turn on what was 1446d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton * asked for 1447d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton */ 1448d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton mcr &= ~(SERIAL_MCR_RTS | SERIAL_MCR_DTR | SERIAL_MCR_LOOP); 1449d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton if (value & TIOCM_RTS) 1450d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton mcr |= SERIAL_MCR_RTS; 1451d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton if (value & TIOCM_DTR) 1452d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton mcr |= SERIAL_MCR_DTR; 1453d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton if (value & TIOCM_LOOP) 1454d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton mcr |= SERIAL_MCR_LOOP; 1455d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 1456d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton status = 1457d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton BoxSetRegister(port->serial, index, MODEM_CONTROL_REGISTER, mcr); 1458d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton if (status < 0) 1459d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton return -ESPIPE; 1460d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton else 1461d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton return 0; 1462d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton} 1463d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 146460b33c133ca0b7c0b6072c87234b63fee6e80558Alan Coxstatic int qt_tiocmget(struct tty_struct *tty) 1465d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton{ 1466d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton struct usb_serial_port *port = tty->driver_data; 1467d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton struct usb_serial *serial = get_usb_serial(port, __func__); 1468d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton struct quatech_port *qt_port = qt_get_port_private(port); 1469d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton int retval = -ENODEV; 1470d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton unsigned long flags; 1471d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 14721695eb36bf4616c6ec062d2dc2c3abe54d3aa313Ruslan Pisarev dbg("In %s\n", __func__); 1473d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 1474d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton if (!serial) 1475d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton return -ENODEV; 1476d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 1477d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton spin_lock_irqsave(&qt_port->lock, flags); 1478d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 1479d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton dbg("%s - port %d\n", __func__, port->number); 1480d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton dbg("%s - port->RxHolding = %d\n", __func__, qt_port->RxHolding); 1481d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 148260b33c133ca0b7c0b6072c87234b63fee6e80558Alan Cox retval = qt_real_tiocmget(tty, port, serial); 1483d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 1484d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton spin_unlock_irqrestore(&qt_port->lock, flags); 1485d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton return retval; 1486d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton} 1487d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 148820b9d17715017ae4dd4ec87fabc36d33b9de708eAlan Coxstatic int qt_tiocmset(struct tty_struct *tty, 1489d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton unsigned int set, unsigned int clear) 1490d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton{ 1491d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 1492d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton struct usb_serial_port *port = tty->driver_data; 1493d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton struct usb_serial *serial = get_usb_serial(port, __func__); 1494d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton struct quatech_port *qt_port = qt_get_port_private(port); 1495d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton unsigned long flags; 1496d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton int retval = -ENODEV; 1497d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 14981695eb36bf4616c6ec062d2dc2c3abe54d3aa313Ruslan Pisarev dbg("In %s\n", __func__); 1499d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 1500d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton if (!serial) 1501d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton return -ENODEV; 1502d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 1503d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton spin_lock_irqsave(&qt_port->lock, flags); 1504d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 15051695eb36bf4616c6ec062d2dc2c3abe54d3aa313Ruslan Pisarev dbg("%s - port %d\n", __func__, port->number); 1506d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton dbg("%s - qt_port->RxHolding = %d\n", __func__, qt_port->RxHolding); 1507d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 150820b9d17715017ae4dd4ec87fabc36d33b9de708eAlan Cox retval = qt_real_tiocmset(tty, port, serial, set); 1509d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 1510d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton spin_unlock_irqrestore(&qt_port->lock, flags); 1511d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton return retval; 1512d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton} 1513d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 1514d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pembertonstatic void qt_throttle(struct tty_struct *tty) 1515d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton{ 1516d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton struct usb_serial_port *port = tty->driver_data; 1517d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton struct usb_serial *serial = get_usb_serial(port, __func__); 1518d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton struct quatech_port *qt_port; 1519d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton unsigned long flags; 1520d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 1521d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton dbg("%s - port %d\n", __func__, port->number); 1522d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 1523d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton if (!serial) 1524d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton return; 1525d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 1526d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton qt_port = qt_get_port_private(port); 1527d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 1528d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton spin_lock_irqsave(&qt_port->lock, flags); 1529d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 1530d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton /* pass on to the driver specific version of this function */ 1531d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton qt_port->RxHolding = 1; 1532d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton dbg("%s - port->RxHolding = 1\n", __func__); 1533d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 1534d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton spin_unlock_irqrestore(&qt_port->lock, flags); 1535d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton return; 1536d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton} 1537d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 1538d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pembertonstatic void qt_unthrottle(struct tty_struct *tty) 1539d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton{ 1540d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton struct usb_serial_port *port = tty->driver_data; 1541d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton struct usb_serial *serial = get_usb_serial(port, __func__); 1542d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton struct quatech_port *qt_port; 1543d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton unsigned long flags; 1544d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton unsigned int result; 1545d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 1546d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton if (!serial) 1547d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton return; 1548d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 1549d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton qt_port = qt_get_port_private(port); 1550d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 1551d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton spin_lock_irqsave(&qt_port->lock, flags); 1552d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 1553d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton dbg("%s - port %d\n", __func__, port->number); 1554d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 1555d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton if (qt_port->RxHolding == 1) { 1556d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton dbg("%s -qt_port->RxHolding == 1\n", __func__); 1557d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 1558d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton qt_port->RxHolding = 0; 1559d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton dbg("%s - qt_port->RxHolding = 0\n", __func__); 1560d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 1561d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton /* if we have a bulk endpoint, start it up */ 1562d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton if ((serial->num_bulk_in) && (qt_port->ReadBulkStopped == 1)) { 1563d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton /* Start reading from the device */ 1564d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton usb_fill_bulk_urb(port->read_urb, serial->dev, 1565d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton usb_rcvbulkpipe(serial->dev, 1566d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton port->bulk_in_endpointAddress), 1567d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton port->read_urb->transfer_buffer, 1568d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton port->read_urb-> 1569d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton transfer_buffer_length, 1570d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton qt_read_bulk_callback, port); 1571d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton result = usb_submit_urb(port->read_urb, GFP_ATOMIC); 1572d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton if (result) 1573d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton err("%s - failed restarting read urb, error %d", 1574d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton __func__, result); 1575d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton } 1576d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton } 1577d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton spin_unlock_irqrestore(&qt_port->lock, flags); 1578d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton return; 1579d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 1580d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton} 1581d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 1582d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pembertonstatic int qt_calc_num_ports(struct usb_serial *serial) 1583d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton{ 1584d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton int num_ports; 1585d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 15861695eb36bf4616c6ec062d2dc2c3abe54d3aa313Ruslan Pisarev dbg("numberofendpoints: %d\n", 1587d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton (int)serial->interface->cur_altsetting->desc.bNumEndpoints); 15881695eb36bf4616c6ec062d2dc2c3abe54d3aa313Ruslan Pisarev dbg("numberofendpoints: %d\n", 1589d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton (int)serial->interface->altsetting->desc.bNumEndpoints); 1590d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 1591d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton num_ports = 1592d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton (serial->interface->cur_altsetting->desc.bNumEndpoints - 1) / 2; 1593d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 1594d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton return num_ports; 1595d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton} 1596d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 1597d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pembertonstatic struct usb_serial_driver quatech_device = { 1598d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton .driver = { 1599d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton .owner = THIS_MODULE, 1600d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton .name = "serqt", 1601d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton }, 1602d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton .description = DRIVER_DESC, 1603d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton .usb_driver = &serqt_usb_driver, 1604d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton .id_table = serqt_id_table, 1605d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton .num_ports = 8, 1606d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton .open = qt_open, 1607d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton .close = qt_close, 1608d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton .write = qt_write, 1609d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton .write_room = qt_write_room, 1610d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton .chars_in_buffer = qt_chars_in_buffer, 1611d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton .throttle = qt_throttle, 1612d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton .unthrottle = qt_unthrottle, 1613d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton .calc_num_ports = qt_calc_num_ports, 1614d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton .ioctl = qt_ioctl, 1615d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton .set_termios = qt_set_termios, 1616d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton .break_ctl = qt_break, 1617d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton .tiocmget = qt_tiocmget, 1618d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton .tiocmset = qt_tiocmset, 1619d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton .attach = qt_startup, 1620d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton .release = qt_release, 1621d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton}; 1622d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 1623d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pembertonstatic int __init serqt_usb_init(void) 1624d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton{ 1625d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton int retval; 1626d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 1627d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton dbg("%s\n", __func__); 1628d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 1629d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton /* register with usb-serial */ 1630d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton retval = usb_serial_register(&quatech_device); 1631d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 1632d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton if (retval) 1633d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton goto failed_usb_serial_register; 1634d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 1635d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ":" 1636d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton DRIVER_DESC "\n"); 1637d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 1638d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton /* register with usb */ 1639d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 1640d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton retval = usb_register(&serqt_usb_driver); 1641d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton if (retval == 0) 1642d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton return 0; 1643d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 1644d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton /* if we're here, usb_register() failed */ 1645d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton usb_serial_deregister(&quatech_device); 1646d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pembertonfailed_usb_serial_register: 1647d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton return retval; 1648d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton} 1649d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 1650d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pembertonstatic void __exit serqt_usb_exit(void) 1651d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton{ 1652d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton usb_deregister(&serqt_usb_driver); 1653d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton usb_serial_deregister(&quatech_device); 1654d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton} 1655d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 1656d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pembertonmodule_init(serqt_usb_init); 1657d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pembertonmodule_exit(serqt_usb_exit); 1658d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 1659d75662e164d5175c5e5f9339ff4d6f6980613d96Bill PembertonMODULE_AUTHOR(DRIVER_AUTHOR); 1660d75662e164d5175c5e5f9339ff4d6f6980613d96Bill PembertonMODULE_DESCRIPTION(DRIVER_DESC); 1661d75662e164d5175c5e5f9339ff4d6f6980613d96Bill PembertonMODULE_LICENSE("GPL"); 1662d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pemberton 1663d75662e164d5175c5e5f9339ff4d6f6980613d96Bill Pembertonmodule_param(debug, bool, S_IRUGO | S_IWUSR); 1664d75662e164d5175c5e5f9339ff4d6f6980613d96Bill PembertonMODULE_PARM_DESC(debug, "Debug enabled or not"); 1665