1*52af9545SBill Pemberton /* 2*52af9545SBill Pemberton * usb-serial driver for Quatech SSU-100 3*52af9545SBill Pemberton * 4*52af9545SBill Pemberton * based on ftdi_sio.c and the original serqt_usb.c from Quatech 5*52af9545SBill Pemberton * 6*52af9545SBill Pemberton */ 7*52af9545SBill Pemberton 8*52af9545SBill Pemberton #include <linux/errno.h> 9*52af9545SBill Pemberton #include <linux/init.h> 10*52af9545SBill Pemberton #include <linux/slab.h> 11*52af9545SBill Pemberton #include <linux/tty.h> 12*52af9545SBill Pemberton #include <linux/tty_driver.h> 13*52af9545SBill Pemberton #include <linux/tty_flip.h> 14*52af9545SBill Pemberton #include <linux/module.h> 15*52af9545SBill Pemberton #include <linux/serial.h> 16*52af9545SBill Pemberton #include <linux/usb.h> 17*52af9545SBill Pemberton #include <linux/usb/serial.h> 18*52af9545SBill Pemberton #include <linux/uaccess.h> 19*52af9545SBill Pemberton 20*52af9545SBill Pemberton #define QT_OPEN_CLOSE_CHANNEL 0xca 21*52af9545SBill Pemberton #define QT_SET_GET_DEVICE 0xc2 22*52af9545SBill Pemberton #define QT_SET_GET_REGISTER 0xc0 23*52af9545SBill Pemberton #define QT_GET_SET_PREBUF_TRIG_LVL 0xcc 24*52af9545SBill Pemberton #define QT_SET_ATF 0xcd 25*52af9545SBill Pemberton #define QT_GET_SET_UART 0xc1 26*52af9545SBill Pemberton #define QT_TRANSFER_IN 0xc0 27*52af9545SBill Pemberton #define QT_HW_FLOW_CONTROL_MASK 0xc5 28*52af9545SBill Pemberton #define QT_SW_FLOW_CONTROL_MASK 0xc6 29*52af9545SBill Pemberton 30*52af9545SBill Pemberton #define MODEM_CTL_REGISTER 0x04 31*52af9545SBill Pemberton #define MODEM_STATUS_REGISTER 0x06 32*52af9545SBill Pemberton 33*52af9545SBill Pemberton 34*52af9545SBill Pemberton #define SERIAL_LSR_OE 0x02 35*52af9545SBill Pemberton #define SERIAL_LSR_PE 0x04 36*52af9545SBill Pemberton #define SERIAL_LSR_FE 0x08 37*52af9545SBill Pemberton #define SERIAL_LSR_BI 0x10 38*52af9545SBill Pemberton 39*52af9545SBill Pemberton #define SERIAL_LSR_TEMT 0x40 40*52af9545SBill Pemberton 41*52af9545SBill Pemberton #define SERIAL_MCR_DTR 0x01 42*52af9545SBill Pemberton #define SERIAL_MCR_RTS 0x02 43*52af9545SBill Pemberton #define SERIAL_MCR_LOOP 0x10 44*52af9545SBill Pemberton 45*52af9545SBill Pemberton #define SERIAL_MSR_CTS 0x10 46*52af9545SBill Pemberton #define SERIAL_MSR_CD 0x80 47*52af9545SBill Pemberton #define SERIAL_MSR_RI 0x40 48*52af9545SBill Pemberton #define SERIAL_MSR_DSR 0x20 49*52af9545SBill Pemberton #define SERIAL_MSR_MASK 0xf0 50*52af9545SBill Pemberton 51*52af9545SBill Pemberton #define SERIAL_CRTSCTS ((SERIAL_MCR_RTS << 8) | SERIAL_MSR_CTS) 52*52af9545SBill Pemberton 53*52af9545SBill Pemberton #define SERIAL_8_DATA 0x03 54*52af9545SBill Pemberton #define SERIAL_7_DATA 0x02 55*52af9545SBill Pemberton #define SERIAL_6_DATA 0x01 56*52af9545SBill Pemberton #define SERIAL_5_DATA 0x00 57*52af9545SBill Pemberton 58*52af9545SBill Pemberton #define SERIAL_ODD_PARITY 0X08 59*52af9545SBill Pemberton #define SERIAL_EVEN_PARITY 0X18 60*52af9545SBill Pemberton 61*52af9545SBill Pemberton #define MAX_BAUD_RATE 460800 62*52af9545SBill Pemberton 63*52af9545SBill Pemberton #define ATC_DISABLED 0x00 64*52af9545SBill Pemberton #define DUPMODE_BITS 0xc0 65*52af9545SBill Pemberton #define RR_BITS 0x03 66*52af9545SBill Pemberton #define LOOPMODE_BITS 0x41 67*52af9545SBill Pemberton #define RS232_MODE 0x00 68*52af9545SBill Pemberton #define RTSCTS_TO_CONNECTOR 0x40 69*52af9545SBill Pemberton #define CLKS_X4 0x02 70*52af9545SBill Pemberton #define FULLPWRBIT 0x00000080 71*52af9545SBill Pemberton #define NEXT_BOARD_POWER_BIT 0x00000004 72*52af9545SBill Pemberton 73*52af9545SBill Pemberton static int debug = 1; 74*52af9545SBill Pemberton 75*52af9545SBill Pemberton /* Version Information */ 76*52af9545SBill Pemberton #define DRIVER_VERSION "v0.1" 77*52af9545SBill Pemberton #define DRIVER_DESC "Quatech SSU-100 USB to Serial Driver" 78*52af9545SBill Pemberton 79*52af9545SBill Pemberton #define USB_VENDOR_ID_QUATECH 0x061d /* Quatech VID */ 80*52af9545SBill Pemberton #define QUATECH_SSU100 0xC020 /* SSU100 */ 81*52af9545SBill Pemberton 82*52af9545SBill Pemberton static const struct usb_device_id id_table[] = { 83*52af9545SBill Pemberton {USB_DEVICE(USB_VENDOR_ID_QUATECH, QUATECH_SSU100)}, 84*52af9545SBill Pemberton {} /* Terminating entry */ 85*52af9545SBill Pemberton }; 86*52af9545SBill Pemberton 87*52af9545SBill Pemberton MODULE_DEVICE_TABLE(usb, id_table); 88*52af9545SBill Pemberton 89*52af9545SBill Pemberton 90*52af9545SBill Pemberton static struct usb_driver ssu100_driver = { 91*52af9545SBill Pemberton .name = "ssu100", 92*52af9545SBill Pemberton .probe = usb_serial_probe, 93*52af9545SBill Pemberton .disconnect = usb_serial_disconnect, 94*52af9545SBill Pemberton .id_table = id_table, 95*52af9545SBill Pemberton .suspend = usb_serial_suspend, 96*52af9545SBill Pemberton .resume = usb_serial_resume, 97*52af9545SBill Pemberton .no_dynamic_id = 1, 98*52af9545SBill Pemberton .supports_autosuspend = 1, 99*52af9545SBill Pemberton }; 100*52af9545SBill Pemberton 101*52af9545SBill Pemberton struct ssu100_port_private { 102*52af9545SBill Pemberton u8 shadowLSR; 103*52af9545SBill Pemberton u8 shadowMSR; 104*52af9545SBill Pemberton wait_queue_head_t delta_msr_wait; /* Used for TIOCMIWAIT */ 105*52af9545SBill Pemberton unsigned short max_packet_size; 106*52af9545SBill Pemberton }; 107*52af9545SBill Pemberton 108*52af9545SBill Pemberton static void ssu100_release(struct usb_serial *serial) 109*52af9545SBill Pemberton { 110*52af9545SBill Pemberton struct ssu100_port_private *priv = usb_get_serial_port_data(*serial->port); 111*52af9545SBill Pemberton 112*52af9545SBill Pemberton dbg("%s", __func__); 113*52af9545SBill Pemberton kfree(priv); 114*52af9545SBill Pemberton } 115*52af9545SBill Pemberton 116*52af9545SBill Pemberton static inline int ssu100_control_msg(struct usb_device *dev, 117*52af9545SBill Pemberton u8 request, u16 data, u16 index) 118*52af9545SBill Pemberton { 119*52af9545SBill Pemberton return usb_control_msg(dev, usb_sndctrlpipe(dev, 0), 120*52af9545SBill Pemberton request, 0x40, data, index, 121*52af9545SBill Pemberton NULL, 0, 300); 122*52af9545SBill Pemberton } 123*52af9545SBill Pemberton 124*52af9545SBill Pemberton static inline int ssu100_setdevice(struct usb_device *dev, u8 *data) 125*52af9545SBill Pemberton { 126*52af9545SBill Pemberton u16 x = ((u16)(data[1] << 8) | (u16)(data[0])); 127*52af9545SBill Pemberton 128*52af9545SBill Pemberton return ssu100_control_msg(dev, QT_SET_GET_DEVICE, x, 0); 129*52af9545SBill Pemberton } 130*52af9545SBill Pemberton 131*52af9545SBill Pemberton 132*52af9545SBill Pemberton static inline int ssu100_getdevice(struct usb_device *dev, u8 *data) 133*52af9545SBill Pemberton { 134*52af9545SBill Pemberton return usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), 135*52af9545SBill Pemberton QT_SET_GET_DEVICE, 0xc0, 0, 0, 136*52af9545SBill Pemberton data, 3, 300); 137*52af9545SBill Pemberton } 138*52af9545SBill Pemberton 139*52af9545SBill Pemberton static inline int ssu100_getregister(struct usb_device *dev, 140*52af9545SBill Pemberton unsigned short uart, 141*52af9545SBill Pemberton unsigned short reg, 142*52af9545SBill Pemberton u8 *data) 143*52af9545SBill Pemberton { 144*52af9545SBill Pemberton return usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), 145*52af9545SBill Pemberton QT_SET_GET_REGISTER, 0xc0, reg, 146*52af9545SBill Pemberton uart, data, sizeof(*data), 300); 147*52af9545SBill Pemberton 148*52af9545SBill Pemberton } 149*52af9545SBill Pemberton 150*52af9545SBill Pemberton 151*52af9545SBill Pemberton static inline int ssu100_setregister(struct usb_device *dev, 152*52af9545SBill Pemberton unsigned short uart, 153*52af9545SBill Pemberton u16 data) 154*52af9545SBill Pemberton { 155*52af9545SBill Pemberton u16 value = (data << 8) | MODEM_CTL_REGISTER; 156*52af9545SBill Pemberton 157*52af9545SBill Pemberton return usb_control_msg(dev, usb_sndctrlpipe(dev, 0), 158*52af9545SBill Pemberton QT_SET_GET_REGISTER, 0x40, value, uart, 159*52af9545SBill Pemberton NULL, 0, 300); 160*52af9545SBill Pemberton 161*52af9545SBill Pemberton } 162*52af9545SBill Pemberton 163*52af9545SBill Pemberton #define set_mctrl(dev, set) update_mctrl((dev), (set), 0) 164*52af9545SBill Pemberton #define clear_mctrl(dev, clear) update_mctrl((dev), 0, (clear)) 165*52af9545SBill Pemberton 166*52af9545SBill Pemberton /* these do not deal with device that have more than 1 port */ 167*52af9545SBill Pemberton static inline int update_mctrl(struct usb_device *dev, unsigned int set, 168*52af9545SBill Pemberton unsigned int clear) 169*52af9545SBill Pemberton { 170*52af9545SBill Pemberton unsigned urb_value; 171*52af9545SBill Pemberton int result; 172*52af9545SBill Pemberton 173*52af9545SBill Pemberton if (((set | clear) & (TIOCM_DTR | TIOCM_RTS)) == 0) { 174*52af9545SBill Pemberton dbg("%s - DTR|RTS not being set|cleared", __func__); 175*52af9545SBill Pemberton return 0; /* no change */ 176*52af9545SBill Pemberton } 177*52af9545SBill Pemberton 178*52af9545SBill Pemberton clear &= ~set; /* 'set' takes precedence over 'clear' */ 179*52af9545SBill Pemberton urb_value = 0; 180*52af9545SBill Pemberton if (set & TIOCM_DTR) 181*52af9545SBill Pemberton urb_value |= SERIAL_MCR_DTR; 182*52af9545SBill Pemberton if (set & TIOCM_RTS) 183*52af9545SBill Pemberton urb_value |= SERIAL_MCR_RTS; 184*52af9545SBill Pemberton 185*52af9545SBill Pemberton result = ssu100_setregister(dev, 0, urb_value); 186*52af9545SBill Pemberton if (result < 0) 187*52af9545SBill Pemberton dbg("%s Error from MODEM_CTRL urb", __func__); 188*52af9545SBill Pemberton 189*52af9545SBill Pemberton return result; 190*52af9545SBill Pemberton } 191*52af9545SBill Pemberton 192*52af9545SBill Pemberton static int ssu100_initdevice(struct usb_device *dev) 193*52af9545SBill Pemberton { 194*52af9545SBill Pemberton u8 *data; 195*52af9545SBill Pemberton int result = 0; 196*52af9545SBill Pemberton 197*52af9545SBill Pemberton dbg("%s", __func__); 198*52af9545SBill Pemberton 199*52af9545SBill Pemberton data = kzalloc(3, GFP_KERNEL); 200*52af9545SBill Pemberton if (!data) 201*52af9545SBill Pemberton return -ENOMEM; 202*52af9545SBill Pemberton 203*52af9545SBill Pemberton result = ssu100_getdevice(dev, data); 204*52af9545SBill Pemberton if (result < 0) { 205*52af9545SBill Pemberton dbg("%s - get_device failed %i", __func__, result); 206*52af9545SBill Pemberton goto out; 207*52af9545SBill Pemberton } 208*52af9545SBill Pemberton 209*52af9545SBill Pemberton data[1] &= ~FULLPWRBIT; 210*52af9545SBill Pemberton 211*52af9545SBill Pemberton result = ssu100_setdevice(dev, data); 212*52af9545SBill Pemberton if (result < 0) { 213*52af9545SBill Pemberton dbg("%s - setdevice failed %i", __func__, result); 214*52af9545SBill Pemberton goto out; 215*52af9545SBill Pemberton } 216*52af9545SBill Pemberton 217*52af9545SBill Pemberton result = ssu100_control_msg(dev, QT_GET_SET_PREBUF_TRIG_LVL, 128, 0); 218*52af9545SBill Pemberton if (result < 0) { 219*52af9545SBill Pemberton dbg("%s - set prebuffer level failed %i", __func__, result); 220*52af9545SBill Pemberton goto out; 221*52af9545SBill Pemberton } 222*52af9545SBill Pemberton 223*52af9545SBill Pemberton result = ssu100_control_msg(dev, QT_SET_ATF, ATC_DISABLED, 0); 224*52af9545SBill Pemberton if (result < 0) { 225*52af9545SBill Pemberton dbg("%s - set ATFprebuffer level failed %i", __func__, result); 226*52af9545SBill Pemberton goto out; 227*52af9545SBill Pemberton } 228*52af9545SBill Pemberton 229*52af9545SBill Pemberton result = ssu100_getdevice(dev, data); 230*52af9545SBill Pemberton if (result < 0) { 231*52af9545SBill Pemberton dbg("%s - get_device failed %i", __func__, result); 232*52af9545SBill Pemberton goto out; 233*52af9545SBill Pemberton } 234*52af9545SBill Pemberton 235*52af9545SBill Pemberton data[0] &= ~(RR_BITS | DUPMODE_BITS); 236*52af9545SBill Pemberton data[0] |= CLKS_X4; 237*52af9545SBill Pemberton data[1] &= ~(LOOPMODE_BITS); 238*52af9545SBill Pemberton data[1] |= RS232_MODE; 239*52af9545SBill Pemberton 240*52af9545SBill Pemberton result = ssu100_setdevice(dev, data); 241*52af9545SBill Pemberton if (result < 0) { 242*52af9545SBill Pemberton dbg("%s - setdevice failed %i", __func__, result); 243*52af9545SBill Pemberton goto out; 244*52af9545SBill Pemberton } 245*52af9545SBill Pemberton 246*52af9545SBill Pemberton out: kfree(data); 247*52af9545SBill Pemberton return result; 248*52af9545SBill Pemberton 249*52af9545SBill Pemberton } 250*52af9545SBill Pemberton 251*52af9545SBill Pemberton 252*52af9545SBill Pemberton static void ssu100_set_termios(struct tty_struct *tty, 253*52af9545SBill Pemberton struct usb_serial_port *port, 254*52af9545SBill Pemberton struct ktermios *old_termios) 255*52af9545SBill Pemberton { 256*52af9545SBill Pemberton struct usb_device *dev = port->serial->dev; 257*52af9545SBill Pemberton struct ktermios *termios = tty->termios; 258*52af9545SBill Pemberton u16 baud, divisor, remainder; 259*52af9545SBill Pemberton unsigned int cflag = termios->c_cflag; 260*52af9545SBill Pemberton u16 urb_value = 0; /* will hold the new flags */ 261*52af9545SBill Pemberton int result; 262*52af9545SBill Pemberton 263*52af9545SBill Pemberton dbg("%s", __func__); 264*52af9545SBill Pemberton 265*52af9545SBill Pemberton if (cflag & PARENB) { 266*52af9545SBill Pemberton if (cflag & PARODD) 267*52af9545SBill Pemberton urb_value |= SERIAL_ODD_PARITY; 268*52af9545SBill Pemberton else 269*52af9545SBill Pemberton urb_value |= SERIAL_EVEN_PARITY; 270*52af9545SBill Pemberton } 271*52af9545SBill Pemberton 272*52af9545SBill Pemberton switch (cflag & CSIZE) { 273*52af9545SBill Pemberton case CS5: 274*52af9545SBill Pemberton urb_value |= SERIAL_5_DATA; 275*52af9545SBill Pemberton break; 276*52af9545SBill Pemberton case CS6: 277*52af9545SBill Pemberton urb_value |= SERIAL_6_DATA; 278*52af9545SBill Pemberton break; 279*52af9545SBill Pemberton case CS7: 280*52af9545SBill Pemberton urb_value |= SERIAL_7_DATA; 281*52af9545SBill Pemberton break; 282*52af9545SBill Pemberton default: 283*52af9545SBill Pemberton case CS8: 284*52af9545SBill Pemberton urb_value |= SERIAL_8_DATA; 285*52af9545SBill Pemberton break; 286*52af9545SBill Pemberton } 287*52af9545SBill Pemberton 288*52af9545SBill Pemberton baud = tty_get_baud_rate(tty); 289*52af9545SBill Pemberton if (!baud) 290*52af9545SBill Pemberton baud = 9600; 291*52af9545SBill Pemberton 292*52af9545SBill Pemberton dbg("%s - got baud = %d\n", __func__, baud); 293*52af9545SBill Pemberton 294*52af9545SBill Pemberton 295*52af9545SBill Pemberton divisor = MAX_BAUD_RATE / baud; 296*52af9545SBill Pemberton remainder = MAX_BAUD_RATE % baud; 297*52af9545SBill Pemberton if (((remainder * 2) >= baud) && (baud != 110)) 298*52af9545SBill Pemberton divisor++; 299*52af9545SBill Pemberton 300*52af9545SBill Pemberton urb_value = urb_value << 8; 301*52af9545SBill Pemberton 302*52af9545SBill Pemberton result = ssu100_control_msg(dev, QT_GET_SET_UART, divisor, urb_value); 303*52af9545SBill Pemberton if (result < 0) 304*52af9545SBill Pemberton dbg("%s - set uart failed", __func__); 305*52af9545SBill Pemberton 306*52af9545SBill Pemberton if (cflag & CRTSCTS) 307*52af9545SBill Pemberton result = ssu100_control_msg(dev, QT_HW_FLOW_CONTROL_MASK, 308*52af9545SBill Pemberton SERIAL_CRTSCTS, 0); 309*52af9545SBill Pemberton else 310*52af9545SBill Pemberton result = ssu100_control_msg(dev, QT_HW_FLOW_CONTROL_MASK, 311*52af9545SBill Pemberton 0, 0); 312*52af9545SBill Pemberton if (result < 0) 313*52af9545SBill Pemberton dbg("%s - set HW flow control failed", __func__); 314*52af9545SBill Pemberton 315*52af9545SBill Pemberton if (I_IXOFF(tty) || I_IXON(tty)) { 316*52af9545SBill Pemberton u16 x = ((u16)(START_CHAR(tty) << 8) | (u16)(STOP_CHAR(tty))); 317*52af9545SBill Pemberton 318*52af9545SBill Pemberton result = ssu100_control_msg(dev, QT_SW_FLOW_CONTROL_MASK, 319*52af9545SBill Pemberton x, 0); 320*52af9545SBill Pemberton } else 321*52af9545SBill Pemberton result = ssu100_control_msg(dev, QT_SW_FLOW_CONTROL_MASK, 322*52af9545SBill Pemberton 0, 0); 323*52af9545SBill Pemberton 324*52af9545SBill Pemberton if (result < 0) 325*52af9545SBill Pemberton dbg("%s - set SW flow control failed", __func__); 326*52af9545SBill Pemberton 327*52af9545SBill Pemberton } 328*52af9545SBill Pemberton 329*52af9545SBill Pemberton 330*52af9545SBill Pemberton static int ssu100_open(struct tty_struct *tty, struct usb_serial_port *port) 331*52af9545SBill Pemberton { 332*52af9545SBill Pemberton struct usb_device *dev = port->serial->dev; 333*52af9545SBill Pemberton struct ssu100_port_private *priv = usb_get_serial_port_data(port); 334*52af9545SBill Pemberton u8 *data; 335*52af9545SBill Pemberton int result; 336*52af9545SBill Pemberton 337*52af9545SBill Pemberton dbg("%s - port %d", __func__, port->number); 338*52af9545SBill Pemberton 339*52af9545SBill Pemberton data = kzalloc(2, GFP_KERNEL); 340*52af9545SBill Pemberton if (!data) 341*52af9545SBill Pemberton return -ENOMEM; 342*52af9545SBill Pemberton 343*52af9545SBill Pemberton result = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), 344*52af9545SBill Pemberton QT_OPEN_CLOSE_CHANNEL, 345*52af9545SBill Pemberton QT_TRANSFER_IN, 0x01, 346*52af9545SBill Pemberton 0, data, 2, 300); 347*52af9545SBill Pemberton if (result < 0) { 348*52af9545SBill Pemberton dbg("%s - open failed %i", __func__, result); 349*52af9545SBill Pemberton kfree(data); 350*52af9545SBill Pemberton return result; 351*52af9545SBill Pemberton } 352*52af9545SBill Pemberton 353*52af9545SBill Pemberton priv->shadowLSR = data[0] & (SERIAL_LSR_OE | SERIAL_LSR_PE | 354*52af9545SBill Pemberton SERIAL_LSR_FE | SERIAL_LSR_BI); 355*52af9545SBill Pemberton 356*52af9545SBill Pemberton priv->shadowMSR = data[1] & (SERIAL_MSR_CTS | SERIAL_MSR_DSR | 357*52af9545SBill Pemberton SERIAL_MSR_RI | SERIAL_MSR_CD); 358*52af9545SBill Pemberton 359*52af9545SBill Pemberton kfree(data); 360*52af9545SBill Pemberton 361*52af9545SBill Pemberton /* set to 9600 */ 362*52af9545SBill Pemberton result = ssu100_control_msg(dev, QT_GET_SET_UART, 0x30, 0x0300); 363*52af9545SBill Pemberton if (result < 0) 364*52af9545SBill Pemberton dbg("%s - set uart failed", __func__); 365*52af9545SBill Pemberton 366*52af9545SBill Pemberton if (tty) 367*52af9545SBill Pemberton ssu100_set_termios(tty, port, tty->termios); 368*52af9545SBill Pemberton 369*52af9545SBill Pemberton return usb_serial_generic_open(tty, port); 370*52af9545SBill Pemberton } 371*52af9545SBill Pemberton 372*52af9545SBill Pemberton static void ssu100_close(struct usb_serial_port *port) 373*52af9545SBill Pemberton { 374*52af9545SBill Pemberton dbg("%s", __func__); 375*52af9545SBill Pemberton usb_serial_generic_close(port); 376*52af9545SBill Pemberton } 377*52af9545SBill Pemberton 378*52af9545SBill Pemberton static int get_serial_info(struct usb_serial_port *port, 379*52af9545SBill Pemberton struct serial_struct __user *retinfo) 380*52af9545SBill Pemberton { 381*52af9545SBill Pemberton struct serial_struct tmp; 382*52af9545SBill Pemberton 383*52af9545SBill Pemberton if (!retinfo) 384*52af9545SBill Pemberton return -EFAULT; 385*52af9545SBill Pemberton 386*52af9545SBill Pemberton memset(&tmp, 0, sizeof(tmp)); 387*52af9545SBill Pemberton tmp.line = port->serial->minor; 388*52af9545SBill Pemberton tmp.port = 0; 389*52af9545SBill Pemberton tmp.irq = 0; 390*52af9545SBill Pemberton tmp.flags = ASYNC_SKIP_TEST | ASYNC_AUTO_IRQ; 391*52af9545SBill Pemberton tmp.xmit_fifo_size = port->bulk_out_size; 392*52af9545SBill Pemberton tmp.baud_base = 9600; 393*52af9545SBill Pemberton tmp.close_delay = 5*HZ; 394*52af9545SBill Pemberton tmp.closing_wait = 30*HZ; 395*52af9545SBill Pemberton 396*52af9545SBill Pemberton if (copy_to_user(retinfo, &tmp, sizeof(*retinfo))) 397*52af9545SBill Pemberton return -EFAULT; 398*52af9545SBill Pemberton return 0; 399*52af9545SBill Pemberton } 400*52af9545SBill Pemberton 401*52af9545SBill Pemberton static int ssu100_ioctl(struct tty_struct *tty, struct file *file, 402*52af9545SBill Pemberton unsigned int cmd, unsigned long arg) 403*52af9545SBill Pemberton { 404*52af9545SBill Pemberton struct usb_serial_port *port = tty->driver_data; 405*52af9545SBill Pemberton struct ssu100_port_private *priv = usb_get_serial_port_data(port); 406*52af9545SBill Pemberton 407*52af9545SBill Pemberton dbg("%s cmd 0x%04x", __func__, cmd); 408*52af9545SBill Pemberton 409*52af9545SBill Pemberton switch (cmd) { 410*52af9545SBill Pemberton case TIOCGSERIAL: 411*52af9545SBill Pemberton return get_serial_info(port, 412*52af9545SBill Pemberton (struct serial_struct __user *) arg); 413*52af9545SBill Pemberton 414*52af9545SBill Pemberton case TIOCMIWAIT: 415*52af9545SBill Pemberton while (priv != NULL) { 416*52af9545SBill Pemberton u8 prevMSR = priv->shadowMSR & SERIAL_MSR_MASK; 417*52af9545SBill Pemberton interruptible_sleep_on(&priv->delta_msr_wait); 418*52af9545SBill Pemberton /* see if a signal did it */ 419*52af9545SBill Pemberton if (signal_pending(current)) 420*52af9545SBill Pemberton return -ERESTARTSYS; 421*52af9545SBill Pemberton else { 422*52af9545SBill Pemberton u8 diff = (priv->shadowMSR & SERIAL_MSR_MASK) ^ prevMSR; 423*52af9545SBill Pemberton if (!diff) 424*52af9545SBill Pemberton return -EIO; /* no change => error */ 425*52af9545SBill Pemberton 426*52af9545SBill Pemberton /* Return 0 if caller wanted to know about 427*52af9545SBill Pemberton these bits */ 428*52af9545SBill Pemberton 429*52af9545SBill Pemberton if (((arg & TIOCM_RNG) && (diff & SERIAL_MSR_RI)) || 430*52af9545SBill Pemberton ((arg & TIOCM_DSR) && (diff & SERIAL_MSR_DSR)) || 431*52af9545SBill Pemberton ((arg & TIOCM_CD) && (diff & SERIAL_MSR_CD)) || 432*52af9545SBill Pemberton ((arg & TIOCM_CTS) && (diff & SERIAL_MSR_CTS))) 433*52af9545SBill Pemberton return 0; 434*52af9545SBill Pemberton } 435*52af9545SBill Pemberton } 436*52af9545SBill Pemberton return 0; 437*52af9545SBill Pemberton 438*52af9545SBill Pemberton default: 439*52af9545SBill Pemberton break; 440*52af9545SBill Pemberton } 441*52af9545SBill Pemberton 442*52af9545SBill Pemberton dbg("%s arg not supported", __func__); 443*52af9545SBill Pemberton 444*52af9545SBill Pemberton return -ENOIOCTLCMD; 445*52af9545SBill Pemberton } 446*52af9545SBill Pemberton 447*52af9545SBill Pemberton static void ssu100_set_max_packet_size(struct usb_serial_port *port) 448*52af9545SBill Pemberton { 449*52af9545SBill Pemberton struct ssu100_port_private *priv = usb_get_serial_port_data(port); 450*52af9545SBill Pemberton struct usb_serial *serial = port->serial; 451*52af9545SBill Pemberton struct usb_device *udev = serial->dev; 452*52af9545SBill Pemberton 453*52af9545SBill Pemberton struct usb_interface *interface = serial->interface; 454*52af9545SBill Pemberton struct usb_endpoint_descriptor *ep_desc = &interface->cur_altsetting->endpoint[1].desc; 455*52af9545SBill Pemberton 456*52af9545SBill Pemberton unsigned num_endpoints; 457*52af9545SBill Pemberton int i; 458*52af9545SBill Pemberton 459*52af9545SBill Pemberton num_endpoints = interface->cur_altsetting->desc.bNumEndpoints; 460*52af9545SBill Pemberton dev_info(&udev->dev, "Number of endpoints %d\n", num_endpoints); 461*52af9545SBill Pemberton 462*52af9545SBill Pemberton for (i = 0; i < num_endpoints; i++) { 463*52af9545SBill Pemberton dev_info(&udev->dev, "Endpoint %d MaxPacketSize %d\n", i+1, 464*52af9545SBill Pemberton interface->cur_altsetting->endpoint[i].desc.wMaxPacketSize); 465*52af9545SBill Pemberton ep_desc = &interface->cur_altsetting->endpoint[i].desc; 466*52af9545SBill Pemberton } 467*52af9545SBill Pemberton 468*52af9545SBill Pemberton /* set max packet size based on descriptor */ 469*52af9545SBill Pemberton priv->max_packet_size = ep_desc->wMaxPacketSize; 470*52af9545SBill Pemberton 471*52af9545SBill Pemberton dev_info(&udev->dev, "Setting MaxPacketSize %d\n", priv->max_packet_size); 472*52af9545SBill Pemberton } 473*52af9545SBill Pemberton 474*52af9545SBill Pemberton static int ssu100_attach(struct usb_serial *serial) 475*52af9545SBill Pemberton { 476*52af9545SBill Pemberton struct ssu100_port_private *priv; 477*52af9545SBill Pemberton struct usb_serial_port *port = *serial->port; 478*52af9545SBill Pemberton 479*52af9545SBill Pemberton dbg("%s", __func__); 480*52af9545SBill Pemberton 481*52af9545SBill Pemberton priv = kzalloc(sizeof(*priv), GFP_KERNEL); 482*52af9545SBill Pemberton if (!priv) { 483*52af9545SBill Pemberton dev_err(&port->dev, "%s- kmalloc(%Zd) failed.\n", __func__, 484*52af9545SBill Pemberton sizeof(*priv)); 485*52af9545SBill Pemberton return -ENOMEM; 486*52af9545SBill Pemberton } 487*52af9545SBill Pemberton 488*52af9545SBill Pemberton init_waitqueue_head(&priv->delta_msr_wait); 489*52af9545SBill Pemberton usb_set_serial_port_data(port, priv); 490*52af9545SBill Pemberton 491*52af9545SBill Pemberton ssu100_set_max_packet_size(port); 492*52af9545SBill Pemberton 493*52af9545SBill Pemberton return ssu100_initdevice(serial->dev); 494*52af9545SBill Pemberton } 495*52af9545SBill Pemberton 496*52af9545SBill Pemberton static int ssu100_tiocmget(struct tty_struct *tty, struct file *file) 497*52af9545SBill Pemberton { 498*52af9545SBill Pemberton struct usb_serial_port *port = tty->driver_data; 499*52af9545SBill Pemberton struct usb_device *dev = port->serial->dev; 500*52af9545SBill Pemberton u8 *d; 501*52af9545SBill Pemberton int r; 502*52af9545SBill Pemberton 503*52af9545SBill Pemberton dbg("%s\n", __func__); 504*52af9545SBill Pemberton 505*52af9545SBill Pemberton d = kzalloc(2, GFP_KERNEL); 506*52af9545SBill Pemberton if (!d) 507*52af9545SBill Pemberton return -ENOMEM; 508*52af9545SBill Pemberton 509*52af9545SBill Pemberton r = ssu100_getregister(dev, 0, MODEM_CTL_REGISTER, d); 510*52af9545SBill Pemberton if (r < 0) 511*52af9545SBill Pemberton goto mget_out; 512*52af9545SBill Pemberton 513*52af9545SBill Pemberton r = ssu100_getregister(dev, 0, MODEM_STATUS_REGISTER, d+1); 514*52af9545SBill Pemberton if (r < 0) 515*52af9545SBill Pemberton goto mget_out; 516*52af9545SBill Pemberton 517*52af9545SBill Pemberton r = (d[0] & SERIAL_MCR_DTR ? TIOCM_DTR : 0) | 518*52af9545SBill Pemberton (d[0] & SERIAL_MCR_RTS ? TIOCM_RTS : 0) | 519*52af9545SBill Pemberton (d[1] & SERIAL_MSR_CTS ? TIOCM_CTS : 0) | 520*52af9545SBill Pemberton (d[1] & SERIAL_MSR_CD ? TIOCM_CAR : 0) | 521*52af9545SBill Pemberton (d[1] & SERIAL_MSR_RI ? TIOCM_RI : 0) | 522*52af9545SBill Pemberton (d[1] & SERIAL_MSR_DSR ? TIOCM_DSR : 0); 523*52af9545SBill Pemberton 524*52af9545SBill Pemberton mget_out: 525*52af9545SBill Pemberton kfree(d); 526*52af9545SBill Pemberton return r; 527*52af9545SBill Pemberton } 528*52af9545SBill Pemberton 529*52af9545SBill Pemberton static int ssu100_tiocmset(struct tty_struct *tty, struct file *file, 530*52af9545SBill Pemberton unsigned int set, unsigned int clear) 531*52af9545SBill Pemberton { 532*52af9545SBill Pemberton struct usb_serial_port *port = tty->driver_data; 533*52af9545SBill Pemberton struct usb_device *dev = port->serial->dev; 534*52af9545SBill Pemberton 535*52af9545SBill Pemberton dbg("%s\n", __func__); 536*52af9545SBill Pemberton return update_mctrl(dev, set, clear); 537*52af9545SBill Pemberton } 538*52af9545SBill Pemberton 539*52af9545SBill Pemberton static void ssu100_dtr_rts(struct usb_serial_port *port, int on) 540*52af9545SBill Pemberton { 541*52af9545SBill Pemberton struct usb_device *dev = port->serial->dev; 542*52af9545SBill Pemberton 543*52af9545SBill Pemberton dbg("%s\n", __func__); 544*52af9545SBill Pemberton 545*52af9545SBill Pemberton mutex_lock(&port->serial->disc_mutex); 546*52af9545SBill Pemberton if (!port->serial->disconnected) { 547*52af9545SBill Pemberton /* Disable flow control */ 548*52af9545SBill Pemberton if (!on && 549*52af9545SBill Pemberton ssu100_setregister(dev, 0, 0) < 0) 550*52af9545SBill Pemberton dev_err(&port->dev, "error from flowcontrol urb\n"); 551*52af9545SBill Pemberton /* drop RTS and DTR */ 552*52af9545SBill Pemberton if (on) 553*52af9545SBill Pemberton set_mctrl(dev, TIOCM_DTR | TIOCM_RTS); 554*52af9545SBill Pemberton else 555*52af9545SBill Pemberton clear_mctrl(dev, TIOCM_DTR | TIOCM_RTS); 556*52af9545SBill Pemberton } 557*52af9545SBill Pemberton mutex_unlock(&port->serial->disc_mutex); 558*52af9545SBill Pemberton } 559*52af9545SBill Pemberton 560*52af9545SBill Pemberton static int ssu100_process_packet(struct tty_struct *tty, 561*52af9545SBill Pemberton struct usb_serial_port *port, 562*52af9545SBill Pemberton struct ssu100_port_private *priv, 563*52af9545SBill Pemberton char *packet, int len) 564*52af9545SBill Pemberton { 565*52af9545SBill Pemberton int i; 566*52af9545SBill Pemberton char flag; 567*52af9545SBill Pemberton char *ch; 568*52af9545SBill Pemberton 569*52af9545SBill Pemberton dbg("%s - port %d", __func__, port->number); 570*52af9545SBill Pemberton 571*52af9545SBill Pemberton if (len < 4) { 572*52af9545SBill Pemberton dbg("%s - malformed packet", __func__); 573*52af9545SBill Pemberton return 0; 574*52af9545SBill Pemberton } 575*52af9545SBill Pemberton 576*52af9545SBill Pemberton if ((packet[0] == 0x1b) && (packet[1] == 0x1b) && 577*52af9545SBill Pemberton ((packet[2] == 0x00) || (packet[2] == 0x01))) { 578*52af9545SBill Pemberton if (packet[2] == 0x00) 579*52af9545SBill Pemberton priv->shadowLSR = packet[3] & (SERIAL_LSR_OE | 580*52af9545SBill Pemberton SERIAL_LSR_PE | 581*52af9545SBill Pemberton SERIAL_LSR_FE | 582*52af9545SBill Pemberton SERIAL_LSR_BI); 583*52af9545SBill Pemberton 584*52af9545SBill Pemberton if (packet[2] == 0x01) { 585*52af9545SBill Pemberton priv->shadowMSR = packet[3]; 586*52af9545SBill Pemberton wake_up_interruptible(&priv->delta_msr_wait); 587*52af9545SBill Pemberton } 588*52af9545SBill Pemberton 589*52af9545SBill Pemberton len -= 4; 590*52af9545SBill Pemberton ch = packet + 4; 591*52af9545SBill Pemberton } else 592*52af9545SBill Pemberton ch = packet; 593*52af9545SBill Pemberton 594*52af9545SBill Pemberton if (!len) 595*52af9545SBill Pemberton return 0; /* status only */ 596*52af9545SBill Pemberton 597*52af9545SBill Pemberton if (port->port.console && port->sysrq) { 598*52af9545SBill Pemberton for (i = 0; i < len; i++, ch++) { 599*52af9545SBill Pemberton if (!usb_serial_handle_sysrq_char(tty, port, *ch)) 600*52af9545SBill Pemberton tty_insert_flip_char(tty, *ch, flag); 601*52af9545SBill Pemberton } 602*52af9545SBill Pemberton } else 603*52af9545SBill Pemberton tty_insert_flip_string_fixed_flag(tty, ch, flag, len); 604*52af9545SBill Pemberton 605*52af9545SBill Pemberton return len; 606*52af9545SBill Pemberton } 607*52af9545SBill Pemberton 608*52af9545SBill Pemberton static void ssu100_process_read_urb(struct urb *urb) 609*52af9545SBill Pemberton { 610*52af9545SBill Pemberton struct usb_serial_port *port = urb->context; 611*52af9545SBill Pemberton struct ssu100_port_private *priv = usb_get_serial_port_data(port); 612*52af9545SBill Pemberton char *data = (char *)urb->transfer_buffer; 613*52af9545SBill Pemberton struct tty_struct *tty; 614*52af9545SBill Pemberton int count = 0; 615*52af9545SBill Pemberton int i; 616*52af9545SBill Pemberton int len; 617*52af9545SBill Pemberton 618*52af9545SBill Pemberton dbg("%s", __func__); 619*52af9545SBill Pemberton 620*52af9545SBill Pemberton tty = tty_port_tty_get(&port->port); 621*52af9545SBill Pemberton if (!tty) 622*52af9545SBill Pemberton return; 623*52af9545SBill Pemberton 624*52af9545SBill Pemberton for (i = 0; i < urb->actual_length; i += priv->max_packet_size) { 625*52af9545SBill Pemberton len = min_t(int, urb->actual_length - i, priv->max_packet_size); 626*52af9545SBill Pemberton count += ssu100_process_packet(tty, port, priv, &data[i], len); 627*52af9545SBill Pemberton } 628*52af9545SBill Pemberton 629*52af9545SBill Pemberton if (count) 630*52af9545SBill Pemberton tty_flip_buffer_push(tty); 631*52af9545SBill Pemberton tty_kref_put(tty); 632*52af9545SBill Pemberton } 633*52af9545SBill Pemberton 634*52af9545SBill Pemberton 635*52af9545SBill Pemberton static struct usb_serial_driver ssu100_device = { 636*52af9545SBill Pemberton .driver = { 637*52af9545SBill Pemberton .owner = THIS_MODULE, 638*52af9545SBill Pemberton .name = "ssu100", 639*52af9545SBill Pemberton }, 640*52af9545SBill Pemberton .description = DRIVER_DESC, 641*52af9545SBill Pemberton .id_table = id_table, 642*52af9545SBill Pemberton .usb_driver = &ssu100_driver, 643*52af9545SBill Pemberton .num_ports = 1, 644*52af9545SBill Pemberton .bulk_in_size = 256, 645*52af9545SBill Pemberton .bulk_out_size = 256, 646*52af9545SBill Pemberton .open = ssu100_open, 647*52af9545SBill Pemberton .close = ssu100_close, 648*52af9545SBill Pemberton .attach = ssu100_attach, 649*52af9545SBill Pemberton .release = ssu100_release, 650*52af9545SBill Pemberton .dtr_rts = ssu100_dtr_rts, 651*52af9545SBill Pemberton .process_read_urb = ssu100_process_read_urb, 652*52af9545SBill Pemberton .tiocmget = ssu100_tiocmget, 653*52af9545SBill Pemberton .tiocmset = ssu100_tiocmset, 654*52af9545SBill Pemberton .ioctl = ssu100_ioctl, 655*52af9545SBill Pemberton .set_termios = ssu100_set_termios, 656*52af9545SBill Pemberton }; 657*52af9545SBill Pemberton 658*52af9545SBill Pemberton static int __init ssu100_init(void) 659*52af9545SBill Pemberton { 660*52af9545SBill Pemberton int retval; 661*52af9545SBill Pemberton 662*52af9545SBill Pemberton dbg("%s", __func__); 663*52af9545SBill Pemberton 664*52af9545SBill Pemberton /* register with usb-serial */ 665*52af9545SBill Pemberton retval = usb_serial_register(&ssu100_device); 666*52af9545SBill Pemberton 667*52af9545SBill Pemberton if (retval) 668*52af9545SBill Pemberton goto failed_usb_sio_register; 669*52af9545SBill Pemberton 670*52af9545SBill Pemberton retval = usb_register(&ssu100_driver); 671*52af9545SBill Pemberton if (retval) 672*52af9545SBill Pemberton goto failed_usb_register; 673*52af9545SBill Pemberton 674*52af9545SBill Pemberton printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ":" 675*52af9545SBill Pemberton DRIVER_DESC "\n"); 676*52af9545SBill Pemberton 677*52af9545SBill Pemberton return 0; 678*52af9545SBill Pemberton 679*52af9545SBill Pemberton failed_usb_register: 680*52af9545SBill Pemberton usb_serial_deregister(&ssu100_device); 681*52af9545SBill Pemberton failed_usb_sio_register: 682*52af9545SBill Pemberton return retval; 683*52af9545SBill Pemberton } 684*52af9545SBill Pemberton 685*52af9545SBill Pemberton static void __exit ssu100_exit(void) 686*52af9545SBill Pemberton { 687*52af9545SBill Pemberton usb_deregister(&ssu100_driver); 688*52af9545SBill Pemberton usb_serial_deregister(&ssu100_device); 689*52af9545SBill Pemberton } 690*52af9545SBill Pemberton 691*52af9545SBill Pemberton module_init(ssu100_init); 692*52af9545SBill Pemberton module_exit(ssu100_exit); 693*52af9545SBill Pemberton 694*52af9545SBill Pemberton MODULE_DESCRIPTION(DRIVER_DESC); 695*52af9545SBill Pemberton MODULE_LICENSE("GPL"); 696*52af9545SBill Pemberton 697*52af9545SBill Pemberton module_param(debug, bool, S_IRUGO | S_IWUSR); 698*52af9545SBill Pemberton MODULE_PARM_DESC(debug, "Debug enabled or not"); 699