^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Ours Technology Inc. OTi-6858 USB to serial adapter driver.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyleft (C) 2007 Kees Lemmens (adapted for kernel 2.6.20)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Copyright (C) 2006 Tomasz Michal Lukaszewski (FIXME: add e-mail)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * Copyright (C) 2001-2004 Greg Kroah-Hartman (greg@kroah.com)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * Copyright (C) 2003 IBM Corp.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) * Many thanks to the authors of pl2303 driver: all functions in this file
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) * are heavily based on pl2303 code, buffering code is a 1-to-1 copy.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) * Warning! You use this driver on your own risk! The only official
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) * description of this device I have is datasheet from manufacturer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) * and it doesn't contain almost any information needed to write a driver.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) * Almost all knowlegde used while writing this driver was gathered by:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) * - analyzing traffic between device and the M$ Windows 2000 driver,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) * - trying different bit combinations and checking pin states
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) * with a voltmeter,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) * - receiving malformed frames and producing buffer overflows
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) * to learn how errors are reported,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) * So, THIS CODE CAN DESTROY OTi-6858 AND ANY OTHER DEVICES, THAT ARE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) * CONNECTED TO IT!
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) * See Documentation/usb/usb-serial.rst for more information on using this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) * driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) * TODO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) * - implement correct flushing for ioctls and oti6858_close()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) * - check how errors (rx overflow, parity error, framing error) are reported
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) * - implement oti6858_break_ctl()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) * - implement more ioctls
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) * - test/implement flow control
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) * - allow setting custom baud rates
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #include <linux/errno.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #include <linux/tty.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #include <linux/tty_driver.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) #include <linux/tty_flip.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) #include <linux/serial.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) #include <linux/moduleparam.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) #include <linux/spinlock.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) #include <linux/usb.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) #include <linux/usb/serial.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) #include <linux/uaccess.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) #include <linux/kfifo.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) #include "oti6858.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) #define OTI6858_DESCRIPTION \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) "Ours Technology Inc. OTi-6858 USB to serial adapter driver"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) #define OTI6858_AUTHOR "Tomasz Michal Lukaszewski <FIXME@FIXME>"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) static const struct usb_device_id id_table[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) { USB_DEVICE(OTI6858_VENDOR_ID, OTI6858_PRODUCT_ID) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) { }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) MODULE_DEVICE_TABLE(usb, id_table);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) /* requests */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) #define OTI6858_REQ_GET_STATUS (USB_DIR_IN | USB_TYPE_VENDOR | 0x00)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) #define OTI6858_REQ_T_GET_STATUS 0x01
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) #define OTI6858_REQ_SET_LINE (USB_DIR_OUT | USB_TYPE_VENDOR | 0x00)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) #define OTI6858_REQ_T_SET_LINE 0x00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) #define OTI6858_REQ_CHECK_TXBUFF (USB_DIR_IN | USB_TYPE_VENDOR | 0x01)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) #define OTI6858_REQ_T_CHECK_TXBUFF 0x00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) /* format of the control packet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) struct oti6858_control_pkt {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) __le16 divisor; /* baud rate = 96000000 / (16 * divisor), LE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) #define OTI6858_MAX_BAUD_RATE 3000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) u8 frame_fmt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) #define FMT_STOP_BITS_MASK 0xc0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) #define FMT_STOP_BITS_1 0x00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) #define FMT_STOP_BITS_2 0x40 /* 1.5 stop bits if FMT_DATA_BITS_5 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) #define FMT_PARITY_MASK 0x38
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) #define FMT_PARITY_NONE 0x00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) #define FMT_PARITY_ODD 0x08
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) #define FMT_PARITY_EVEN 0x18
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) #define FMT_PARITY_MARK 0x28
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) #define FMT_PARITY_SPACE 0x38
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) #define FMT_DATA_BITS_MASK 0x03
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) #define FMT_DATA_BITS_5 0x00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) #define FMT_DATA_BITS_6 0x01
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) #define FMT_DATA_BITS_7 0x02
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) #define FMT_DATA_BITS_8 0x03
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) u8 something; /* always equals 0x43 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) u8 control; /* settings of flow control lines */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) #define CONTROL_MASK 0x0c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) #define CONTROL_DTR_HIGH 0x08
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) #define CONTROL_RTS_HIGH 0x04
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) u8 tx_status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) #define TX_BUFFER_EMPTIED 0x09
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) u8 pin_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) #define PIN_MASK 0x3f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) #define PIN_MSR_MASK 0x1b
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) #define PIN_RTS 0x20 /* output pin */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) #define PIN_CTS 0x10 /* input pin, active low */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) #define PIN_DSR 0x08 /* input pin, active low */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) #define PIN_DTR 0x04 /* output pin */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) #define PIN_RI 0x02 /* input pin, active low */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) #define PIN_DCD 0x01 /* input pin, active low */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) u8 rx_bytes_avail; /* number of bytes in rx buffer */;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) #define OTI6858_CTRL_PKT_SIZE sizeof(struct oti6858_control_pkt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) #define OTI6858_CTRL_EQUALS_PENDING(a, priv) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) (((a)->divisor == (priv)->pending_setup.divisor) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) && ((a)->control == (priv)->pending_setup.control) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) && ((a)->frame_fmt == (priv)->pending_setup.frame_fmt))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) /* function prototypes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) static int oti6858_open(struct tty_struct *tty, struct usb_serial_port *port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) static void oti6858_close(struct usb_serial_port *port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) static void oti6858_set_termios(struct tty_struct *tty,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) struct usb_serial_port *port, struct ktermios *old);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) static void oti6858_init_termios(struct tty_struct *tty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) static void oti6858_read_int_callback(struct urb *urb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) static void oti6858_read_bulk_callback(struct urb *urb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) static void oti6858_write_bulk_callback(struct urb *urb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) static int oti6858_write(struct tty_struct *tty, struct usb_serial_port *port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) const unsigned char *buf, int count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) static int oti6858_write_room(struct tty_struct *tty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) static int oti6858_chars_in_buffer(struct tty_struct *tty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) static int oti6858_tiocmget(struct tty_struct *tty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) static int oti6858_tiocmset(struct tty_struct *tty,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) unsigned int set, unsigned int clear);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) static int oti6858_port_probe(struct usb_serial_port *port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) static int oti6858_port_remove(struct usb_serial_port *port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) /* device info */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) static struct usb_serial_driver oti6858_device = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) .owner = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) .name = "oti6858",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) .id_table = id_table,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) .num_ports = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) .num_bulk_in = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) .num_bulk_out = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) .num_interrupt_in = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) .open = oti6858_open,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) .close = oti6858_close,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) .write = oti6858_write,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) .set_termios = oti6858_set_termios,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) .init_termios = oti6858_init_termios,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) .tiocmget = oti6858_tiocmget,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) .tiocmset = oti6858_tiocmset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) .tiocmiwait = usb_serial_generic_tiocmiwait,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) .read_bulk_callback = oti6858_read_bulk_callback,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) .read_int_callback = oti6858_read_int_callback,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) .write_bulk_callback = oti6858_write_bulk_callback,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) .write_room = oti6858_write_room,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) .chars_in_buffer = oti6858_chars_in_buffer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) .port_probe = oti6858_port_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) .port_remove = oti6858_port_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) static struct usb_serial_driver * const serial_drivers[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) &oti6858_device, NULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) struct oti6858_private {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) spinlock_t lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) struct oti6858_control_pkt status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) struct {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) u8 read_urb_in_use;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) u8 write_urb_in_use;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) } flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) struct delayed_work delayed_write_work;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) struct {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) __le16 divisor;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) u8 frame_fmt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) u8 control;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) } pending_setup;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) u8 transient;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) u8 setup_done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) struct delayed_work delayed_setup_work;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) struct usb_serial_port *port; /* USB port with which associated */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) static void setup_line(struct work_struct *work)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) struct oti6858_private *priv = container_of(work,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) struct oti6858_private, delayed_setup_work.work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) struct usb_serial_port *port = priv->port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) struct oti6858_control_pkt *new_setup;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) int result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) new_setup = kmalloc(OTI6858_CTRL_PKT_SIZE, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) if (!new_setup) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) /* we will try again */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) schedule_delayed_work(&priv->delayed_setup_work,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) msecs_to_jiffies(2));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) result = usb_control_msg(port->serial->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) usb_rcvctrlpipe(port->serial->dev, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) OTI6858_REQ_T_GET_STATUS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) OTI6858_REQ_GET_STATUS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) 0, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) new_setup, OTI6858_CTRL_PKT_SIZE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) 100);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) if (result != OTI6858_CTRL_PKT_SIZE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) dev_err(&port->dev, "%s(): error reading status\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) kfree(new_setup);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) /* we will try again */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) schedule_delayed_work(&priv->delayed_setup_work,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) msecs_to_jiffies(2));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) spin_lock_irqsave(&priv->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) if (!OTI6858_CTRL_EQUALS_PENDING(new_setup, priv)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) new_setup->divisor = priv->pending_setup.divisor;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) new_setup->control = priv->pending_setup.control;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) new_setup->frame_fmt = priv->pending_setup.frame_fmt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) spin_unlock_irqrestore(&priv->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) result = usb_control_msg(port->serial->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) usb_sndctrlpipe(port->serial->dev, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) OTI6858_REQ_T_SET_LINE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) OTI6858_REQ_SET_LINE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) 0, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) new_setup, OTI6858_CTRL_PKT_SIZE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) 100);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) spin_unlock_irqrestore(&priv->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) result = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) kfree(new_setup);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) spin_lock_irqsave(&priv->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) if (result != OTI6858_CTRL_PKT_SIZE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) priv->transient = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) priv->setup_done = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) spin_unlock_irqrestore(&priv->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) dev_dbg(&port->dev, "%s(): submitting interrupt urb\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) result = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) if (result != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) dev_err(&port->dev, "%s(): usb_submit_urb() failed with error %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) __func__, result);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) static void send_data(struct work_struct *work)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) struct oti6858_private *priv = container_of(work,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) struct oti6858_private, delayed_write_work.work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) struct usb_serial_port *port = priv->port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) int count = 0, result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) u8 *allow;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) spin_lock_irqsave(&priv->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) if (priv->flags.write_urb_in_use) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) spin_unlock_irqrestore(&priv->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) schedule_delayed_work(&priv->delayed_write_work,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) msecs_to_jiffies(2));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) priv->flags.write_urb_in_use = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) spin_unlock_irqrestore(&priv->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) spin_lock_irqsave(&port->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) count = kfifo_len(&port->write_fifo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) spin_unlock_irqrestore(&port->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) if (count > port->bulk_out_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) count = port->bulk_out_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) if (count != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) allow = kmalloc(1, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) if (!allow)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) result = usb_control_msg(port->serial->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) usb_rcvctrlpipe(port->serial->dev, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) OTI6858_REQ_T_CHECK_TXBUFF,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) OTI6858_REQ_CHECK_TXBUFF,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) count, 0, allow, 1, 100);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) if (result != 1 || *allow != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) kfree(allow);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) if (count == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) priv->flags.write_urb_in_use = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) dev_dbg(&port->dev, "%s(): submitting interrupt urb\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) result = usb_submit_urb(port->interrupt_in_urb, GFP_NOIO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) if (result != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) dev_err(&port->dev, "%s(): usb_submit_urb() failed with error %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) __func__, result);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) count = kfifo_out_locked(&port->write_fifo,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) port->write_urb->transfer_buffer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) count, &port->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) port->write_urb->transfer_buffer_length = count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) result = usb_submit_urb(port->write_urb, GFP_NOIO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) if (result != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) dev_err_console(port, "%s(): usb_submit_urb() failed with error %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) __func__, result);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) priv->flags.write_urb_in_use = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) usb_serial_port_softint(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) static int oti6858_port_probe(struct usb_serial_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) struct oti6858_private *priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) priv = kzalloc(sizeof(*priv), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) if (!priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) spin_lock_init(&priv->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) priv->port = port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) INIT_DELAYED_WORK(&priv->delayed_setup_work, setup_line);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) INIT_DELAYED_WORK(&priv->delayed_write_work, send_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) usb_set_serial_port_data(port, priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) port->port.drain_delay = 256; /* FIXME: check the FIFO length */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) static int oti6858_port_remove(struct usb_serial_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) struct oti6858_private *priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) priv = usb_get_serial_port_data(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) kfree(priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) static int oti6858_write(struct tty_struct *tty, struct usb_serial_port *port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) const unsigned char *buf, int count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) if (!count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) count = kfifo_in_locked(&port->write_fifo, buf, count, &port->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) static int oti6858_write_room(struct tty_struct *tty)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) struct usb_serial_port *port = tty->driver_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) int room = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) spin_lock_irqsave(&port->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) room = kfifo_avail(&port->write_fifo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) spin_unlock_irqrestore(&port->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) return room;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) static int oti6858_chars_in_buffer(struct tty_struct *tty)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) struct usb_serial_port *port = tty->driver_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) int chars = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) spin_lock_irqsave(&port->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) chars = kfifo_len(&port->write_fifo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) spin_unlock_irqrestore(&port->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) return chars;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) static void oti6858_init_termios(struct tty_struct *tty)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) tty_encode_baud_rate(tty, 38400, 38400);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) static void oti6858_set_termios(struct tty_struct *tty,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) struct usb_serial_port *port, struct ktermios *old_termios)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) struct oti6858_private *priv = usb_get_serial_port_data(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) unsigned int cflag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) u8 frame_fmt, control;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) __le16 divisor;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) int br;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) cflag = tty->termios.c_cflag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) spin_lock_irqsave(&priv->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) divisor = priv->pending_setup.divisor;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) frame_fmt = priv->pending_setup.frame_fmt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) control = priv->pending_setup.control;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) spin_unlock_irqrestore(&priv->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) frame_fmt &= ~FMT_DATA_BITS_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) switch (cflag & CSIZE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) case CS5:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) frame_fmt |= FMT_DATA_BITS_5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) case CS6:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) frame_fmt |= FMT_DATA_BITS_6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) case CS7:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) frame_fmt |= FMT_DATA_BITS_7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) case CS8:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) frame_fmt |= FMT_DATA_BITS_8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) /* manufacturer claims that this device can work with baud rates
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) * up to 3 Mbps; I've tested it only on 115200 bps, so I can't
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) * guarantee that any other baud rate will work (especially
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) * the higher ones)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) br = tty_get_baud_rate(tty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) if (br == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) divisor = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) int real_br;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) int new_divisor;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) br = min(br, OTI6858_MAX_BAUD_RATE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) new_divisor = (96000000 + 8 * br) / (16 * br);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) real_br = 96000000 / (16 * new_divisor);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) divisor = cpu_to_le16(new_divisor);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) tty_encode_baud_rate(tty, real_br, real_br);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) frame_fmt &= ~FMT_STOP_BITS_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) if ((cflag & CSTOPB) != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) frame_fmt |= FMT_STOP_BITS_2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) frame_fmt |= FMT_STOP_BITS_1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) frame_fmt &= ~FMT_PARITY_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) if ((cflag & PARENB) != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) if ((cflag & PARODD) != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) frame_fmt |= FMT_PARITY_ODD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) frame_fmt |= FMT_PARITY_EVEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) frame_fmt |= FMT_PARITY_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) control &= ~CONTROL_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) if ((cflag & CRTSCTS) != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) control |= (CONTROL_DTR_HIGH | CONTROL_RTS_HIGH);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) /* change control lines if we are switching to or from B0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) /* FIXME:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) spin_lock_irqsave(&priv->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) control = priv->line_control;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) if ((cflag & CBAUD) == B0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) priv->line_control &= ~(CONTROL_DTR | CONTROL_RTS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) priv->line_control |= (CONTROL_DTR | CONTROL_RTS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) if (control != priv->line_control) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) control = priv->line_control;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) spin_unlock_irqrestore(&priv->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) set_control_lines(serial->dev, control);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) spin_unlock_irqrestore(&priv->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) spin_lock_irqsave(&priv->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) if (divisor != priv->pending_setup.divisor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) || control != priv->pending_setup.control
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) || frame_fmt != priv->pending_setup.frame_fmt) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) priv->pending_setup.divisor = divisor;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) priv->pending_setup.control = control;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) priv->pending_setup.frame_fmt = frame_fmt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) spin_unlock_irqrestore(&priv->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) static int oti6858_open(struct tty_struct *tty, struct usb_serial_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) struct oti6858_private *priv = usb_get_serial_port_data(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) struct usb_serial *serial = port->serial;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) struct oti6858_control_pkt *buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) int result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) usb_clear_halt(serial->dev, port->write_urb->pipe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) usb_clear_halt(serial->dev, port->read_urb->pipe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) buf = kmalloc(OTI6858_CTRL_PKT_SIZE, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) if (!buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) result = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) OTI6858_REQ_T_GET_STATUS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) OTI6858_REQ_GET_STATUS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) 0, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) buf, OTI6858_CTRL_PKT_SIZE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) 100);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) if (result != OTI6858_CTRL_PKT_SIZE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) /* assume default (after power-on reset) values */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) buf->divisor = cpu_to_le16(0x009c); /* 38400 bps */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) buf->frame_fmt = 0x03; /* 8N1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) buf->something = 0x43;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) buf->control = 0x4c; /* DTR, RTS */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) buf->tx_status = 0x00;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) buf->pin_state = 0x5b; /* RTS, CTS, DSR, DTR, RI, DCD */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) buf->rx_bytes_avail = 0x00;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) spin_lock_irqsave(&priv->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) memcpy(&priv->status, buf, OTI6858_CTRL_PKT_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) priv->pending_setup.divisor = buf->divisor;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) priv->pending_setup.frame_fmt = buf->frame_fmt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) priv->pending_setup.control = buf->control;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) spin_unlock_irqrestore(&priv->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) kfree(buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) dev_dbg(&port->dev, "%s(): submitting interrupt urb\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) result = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) if (result != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) dev_err(&port->dev, "%s(): usb_submit_urb() failed with error %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) __func__, result);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) oti6858_close(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) return result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) /* setup termios */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) if (tty)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) oti6858_set_termios(tty, port, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) static void oti6858_close(struct usb_serial_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) struct oti6858_private *priv = usb_get_serial_port_data(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) spin_lock_irqsave(&port->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) /* clear out any remaining data in the buffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) kfifo_reset_out(&port->write_fifo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) spin_unlock_irqrestore(&port->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) dev_dbg(&port->dev, "%s(): after buf_clear()\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) /* cancel scheduled setup */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) cancel_delayed_work_sync(&priv->delayed_setup_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) cancel_delayed_work_sync(&priv->delayed_write_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) /* shutdown our urbs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) dev_dbg(&port->dev, "%s(): shutting down urbs\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) usb_kill_urb(port->write_urb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) usb_kill_urb(port->read_urb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) usb_kill_urb(port->interrupt_in_urb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) static int oti6858_tiocmset(struct tty_struct *tty,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) unsigned int set, unsigned int clear)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) struct usb_serial_port *port = tty->driver_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) struct oti6858_private *priv = usb_get_serial_port_data(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) u8 control;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) dev_dbg(&port->dev, "%s(set = 0x%08x, clear = 0x%08x)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) __func__, set, clear);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) /* FIXME: check if this is correct (active high/low) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) spin_lock_irqsave(&priv->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) control = priv->pending_setup.control;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) if ((set & TIOCM_RTS) != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) control |= CONTROL_RTS_HIGH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) if ((set & TIOCM_DTR) != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) control |= CONTROL_DTR_HIGH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) if ((clear & TIOCM_RTS) != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) control &= ~CONTROL_RTS_HIGH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) if ((clear & TIOCM_DTR) != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) control &= ~CONTROL_DTR_HIGH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) if (control != priv->pending_setup.control)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) priv->pending_setup.control = control;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) spin_unlock_irqrestore(&priv->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) static int oti6858_tiocmget(struct tty_struct *tty)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) struct usb_serial_port *port = tty->driver_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) struct oti6858_private *priv = usb_get_serial_port_data(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) unsigned pin_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) unsigned result = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) spin_lock_irqsave(&priv->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) pin_state = priv->status.pin_state & PIN_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) spin_unlock_irqrestore(&priv->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) /* FIXME: check if this is correct (active high/low) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) if ((pin_state & PIN_RTS) != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) result |= TIOCM_RTS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) if ((pin_state & PIN_CTS) != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) result |= TIOCM_CTS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) if ((pin_state & PIN_DSR) != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) result |= TIOCM_DSR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) if ((pin_state & PIN_DTR) != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) result |= TIOCM_DTR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) if ((pin_state & PIN_RI) != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) result |= TIOCM_RI;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) if ((pin_state & PIN_DCD) != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) result |= TIOCM_CD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) dev_dbg(&port->dev, "%s() = 0x%08x\n", __func__, result);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) return result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) static void oti6858_read_int_callback(struct urb *urb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) struct usb_serial_port *port = urb->context;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) struct oti6858_private *priv = usb_get_serial_port_data(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) int transient = 0, can_recv = 0, resubmit = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) int status = urb->status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) switch (status) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) /* success */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) case -ECONNRESET:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) case -ENOENT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) case -ESHUTDOWN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) /* this urb is terminated, clean up */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) dev_dbg(&urb->dev->dev, "%s(): urb shutting down with status: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) __func__, status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) dev_dbg(&urb->dev->dev, "%s(): nonzero urb status received: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) __func__, status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) if (status == 0 && urb->actual_length == OTI6858_CTRL_PKT_SIZE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) struct oti6858_control_pkt *xs = urb->transfer_buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) spin_lock_irqsave(&priv->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) if (!priv->transient) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) if (!OTI6858_CTRL_EQUALS_PENDING(xs, priv)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) if (xs->rx_bytes_avail == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) priv->transient = 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) priv->setup_done = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) resubmit = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) dev_dbg(&port->dev, "%s(): scheduling setup_line()\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) schedule_delayed_work(&priv->delayed_setup_work, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) if (OTI6858_CTRL_EQUALS_PENDING(xs, priv)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) priv->transient = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) } else if (!priv->setup_done) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) resubmit = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) } else if (--priv->transient == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) if (xs->rx_bytes_avail == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) priv->transient = 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) priv->setup_done = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) resubmit = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) dev_dbg(&port->dev, "%s(): scheduling setup_line()\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) schedule_delayed_work(&priv->delayed_setup_work, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) if (!priv->transient) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) u8 delta = xs->pin_state ^ priv->status.pin_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) if (delta & PIN_MSR_MASK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) if (delta & PIN_CTS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) port->icount.cts++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) if (delta & PIN_DSR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) port->icount.dsr++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) if (delta & PIN_RI)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) port->icount.rng++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) if (delta & PIN_DCD)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) port->icount.dcd++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) wake_up_interruptible(&port->port.delta_msr_wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) memcpy(&priv->status, xs, OTI6858_CTRL_PKT_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) if (!priv->transient && xs->rx_bytes_avail != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) can_recv = xs->rx_bytes_avail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) priv->flags.read_urb_in_use = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) transient = priv->transient;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) spin_unlock_irqrestore(&priv->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) if (can_recv) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) int result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) result = usb_submit_urb(port->read_urb, GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) if (result != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) priv->flags.read_urb_in_use = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) dev_err(&port->dev, "%s(): usb_submit_urb() failed,"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) " error %d\n", __func__, result);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) resubmit = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) } else if (!transient) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) int count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) spin_lock_irqsave(&port->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) count = kfifo_len(&port->write_fifo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) spin_unlock_irqrestore(&port->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) spin_lock_irqsave(&priv->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) if (priv->flags.write_urb_in_use == 0 && count != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) schedule_delayed_work(&priv->delayed_write_work, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) resubmit = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) spin_unlock_irqrestore(&priv->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) if (resubmit) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) int result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) /* dev_dbg(&urb->dev->dev, "%s(): submitting interrupt urb\n", __func__); */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) result = usb_submit_urb(urb, GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) if (result != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) dev_err(&urb->dev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) "%s(): usb_submit_urb() failed with"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) " error %d\n", __func__, result);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) static void oti6858_read_bulk_callback(struct urb *urb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) struct usb_serial_port *port = urb->context;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) struct oti6858_private *priv = usb_get_serial_port_data(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) unsigned char *data = urb->transfer_buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) int status = urb->status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) int result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) spin_lock_irqsave(&priv->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) priv->flags.read_urb_in_use = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) spin_unlock_irqrestore(&priv->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) if (status != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) dev_dbg(&urb->dev->dev, "%s(): unable to handle the error, exiting\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) if (urb->actual_length > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) tty_insert_flip_string(&port->port, data, urb->actual_length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) tty_flip_buffer_push(&port->port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) /* schedule the interrupt urb */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) result = usb_submit_urb(port->interrupt_in_urb, GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) if (result != 0 && result != -EPERM) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) dev_err(&port->dev, "%s(): usb_submit_urb() failed,"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) " error %d\n", __func__, result);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) static void oti6858_write_bulk_callback(struct urb *urb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) struct usb_serial_port *port = urb->context;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) struct oti6858_private *priv = usb_get_serial_port_data(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) int status = urb->status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) int result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) switch (status) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) /* success */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) case -ECONNRESET:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) case -ENOENT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) case -ESHUTDOWN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) /* this urb is terminated, clean up */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) dev_dbg(&urb->dev->dev, "%s(): urb shutting down with status: %d\n", __func__, status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) priv->flags.write_urb_in_use = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) /* error in the urb, so we have to resubmit it */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) dev_dbg(&urb->dev->dev, "%s(): nonzero write bulk status received: %d\n", __func__, status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) dev_dbg(&urb->dev->dev, "%s(): overflow in write\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) port->write_urb->transfer_buffer_length = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) result = usb_submit_urb(port->write_urb, GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) if (result) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) dev_err_console(port, "%s(): usb_submit_urb() failed,"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) " error %d\n", __func__, result);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) priv->flags.write_urb_in_use = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) /* schedule the interrupt urb if we are still open */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) dev_dbg(&port->dev, "%s(): submitting interrupt urb\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) result = usb_submit_urb(port->interrupt_in_urb, GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) if (result != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) dev_err(&port->dev, "%s(): failed submitting int urb,"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) " error %d\n", __func__, result);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) module_usb_serial_driver(serial_drivers, id_table);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) MODULE_DESCRIPTION(OTI6858_DESCRIPTION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) MODULE_AUTHOR(OTI6858_AUTHOR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) MODULE_LICENSE("GPL v2");