|
@@ -20,34 +20,31 @@
|
|
|
//#define DEBUG_ON
|
|
|
//#undef dbg
|
|
|
#ifdef DEBUG_ON
|
|
|
- #define mydbg(const...) printk(const)
|
|
|
+#define mydbg(const...) printk(const)
|
|
|
#else
|
|
|
- #define mydbg(const...)
|
|
|
+#define mydbg(const...)
|
|
|
#endif
|
|
|
|
|
|
-
|
|
|
/* parity check flag */
|
|
|
#define RELEVANT_IFLAG(iflag) (iflag & (IGNBRK|BRKINT|IGNPAR|PARMRK|INPCK))
|
|
|
|
|
|
-
|
|
|
#define SERIAL_TTY_MAJOR 0 /* Nice legal number now */
|
|
|
#define SERIAL_TTY_MINORS 255 /* loads of devices :) */
|
|
|
#define MAX_NUM_PORTS 8 /* The maximum number of ports one device can grab at once */
|
|
|
#define PREFUFF_LEVEL_CONSERVATIVE 128
|
|
|
#define ATC_DISABLED 0x00
|
|
|
|
|
|
-#define RR_BITS 0x03 //for clearing clock bits
|
|
|
+#define RR_BITS 0x03 //for clearing clock bits
|
|
|
#define DUPMODE_BITS 0xc0
|
|
|
|
|
|
#define RS232_MODE 0x00
|
|
|
#define RTSCTS_TO_CONNECTOR 0x40
|
|
|
-#define CLKS_X4 0x02 ///
|
|
|
+#define CLKS_X4 0x02 ///
|
|
|
|
|
|
-#define LOOPMODE_BITS 0x41 //LOOP1 = b6, LOOP0 = b0 (PORT B)
|
|
|
+#define LOOPMODE_BITS 0x41 //LOOP1 = b6, LOOP0 = b0 (PORT B)
|
|
|
#define ALL_LOOPBACK 0x01
|
|
|
#define MODEM_CTRL 0x40
|
|
|
|
|
|
-
|
|
|
#define THISCHAR data[i]
|
|
|
#define NEXTCHAR data[i + 1]
|
|
|
#define THIRDCHAR data[i + 2]
|
|
@@ -58,7 +55,6 @@
|
|
|
#define FULLPWRBIT 0x00000080
|
|
|
#define NEXT_BOARD_POWER_BIT 0x00000004
|
|
|
|
|
|
-
|
|
|
#define SERIAL_LSR_OE 0x02
|
|
|
#define SERIAL_LSR_PE 0x04
|
|
|
#define SERIAL_LSR_FE 0x08
|
|
@@ -76,7 +72,6 @@
|
|
|
#define LINE_STATUS_REGISTER 0x05
|
|
|
#define MODEM_STATUS_REGISTER 0x06
|
|
|
|
|
|
-
|
|
|
#define SERIAL_MCR_DTR 0x01
|
|
|
#define SERIAL_MCR_RTS 0x02
|
|
|
#define SERIAL_MCR_LOOP 0x10
|
|
@@ -100,7 +95,6 @@
|
|
|
#define MAX_BAUD_RATE 460800
|
|
|
#define MAX_BAUD_REMAINDER 4608
|
|
|
|
|
|
-
|
|
|
#define QT_SET_GET_DEVICE 0xc2
|
|
|
#define QT_OPEN_CLOSE_CHANNEL 0xca
|
|
|
#define QT_GET_SET_PREBUF_TRIG_LVL 0xcc
|
|
@@ -119,8 +113,7 @@
|
|
|
#define SERIALQT_GET_THIS_UNIT _IOR(SERIALQT_PCI_IOC_MAGIC, 3, void *)
|
|
|
#define SERIALQT_READ_QOPR _IOR(SERIALQT_PCI_IOC_MAGIC, 4, int)
|
|
|
#define SERIALQT_READ_QMCR _IOR(SERIALQT_PCI_IOC_MAGIC, 5, int)
|
|
|
-#define SERIALQT_IS422_EXTENDED _IOR(SERIALQT_PCI_IOC_MAGIC, 6, int) //returns successful if 422 extended
|
|
|
-
|
|
|
+#define SERIALQT_IS422_EXTENDED _IOR(SERIALQT_PCI_IOC_MAGIC, 6, int) //returns successful if 422 extended
|
|
|
|
|
|
#define USBD_TRANSFER_DIRECTION_IN 0xc0
|
|
|
#define USBD_TRANSFER_DIRECTION_OUT 0x40
|
|
@@ -129,7 +122,7 @@
|
|
|
#define ATC_RTS_ENABLED 0x02
|
|
|
#define ATC_DTR_ENABLED 0x01
|
|
|
|
|
|
-#define RR_BITS 0x03 //for clearing clock bits
|
|
|
+#define RR_BITS 0x03 //for clearing clock bits
|
|
|
#define DUPMODE_BITS 0xc0
|
|
|
|
|
|
#define FULL_DUPLEX 0x00
|
|
@@ -147,75 +140,71 @@
|
|
|
#define QMCR_ALL_LOOPBACK 0x10
|
|
|
#define QMCR_MODEM_CONTROL 0X00
|
|
|
|
|
|
-
|
|
|
-
|
|
|
#define SERIALQT_IOC_MAXNR 6
|
|
|
|
|
|
struct usb_serial_port {
|
|
|
- struct usb_serial *serial; /* pointer back to the owner of this port */
|
|
|
- struct tty_struct * tty; /* the coresponding tty for this port */
|
|
|
- unsigned char number;
|
|
|
- char active; /* someone has this device open */
|
|
|
-
|
|
|
- unsigned char * interrupt_in_buffer;
|
|
|
- struct urb * interrupt_in_urb;
|
|
|
- __u8 interrupt_in_endpointAddress;
|
|
|
-
|
|
|
- unsigned char * bulk_in_buffer;
|
|
|
- unsigned char * xfer_to_tty_buffer;
|
|
|
- struct urb * read_urb;
|
|
|
- __u8 bulk_in_endpointAddress;
|
|
|
-
|
|
|
- unsigned char * bulk_out_buffer;
|
|
|
- int bulk_out_size;
|
|
|
- struct urb * write_urb;
|
|
|
- __u8 bulk_out_endpointAddress;
|
|
|
-
|
|
|
- wait_queue_head_t write_wait;
|
|
|
- wait_queue_head_t wait;
|
|
|
- struct work_struct work;
|
|
|
-
|
|
|
- int open_count; /* number of times this port has been opened */
|
|
|
- struct semaphore sem; /* locks this structure */
|
|
|
-
|
|
|
- __u8 shadowLCR; /* last LCR value received */
|
|
|
- __u8 shadowMCR; /* last MCR value received */
|
|
|
- __u8 shadowMSR; /* last MSR value received */
|
|
|
- __u8 shadowLSR; /* last LSR value received */
|
|
|
- int RxHolding;
|
|
|
- char closePending;
|
|
|
- int ReadBulkStopped;
|
|
|
-
|
|
|
- void * private; /* data private to the specific port */
|
|
|
+ struct usb_serial *serial; /* pointer back to the owner of this port */
|
|
|
+ struct tty_struct *tty; /* the coresponding tty for this port */
|
|
|
+ unsigned char number;
|
|
|
+ char active; /* someone has this device open */
|
|
|
+
|
|
|
+ unsigned char *interrupt_in_buffer;
|
|
|
+ struct urb *interrupt_in_urb;
|
|
|
+ __u8 interrupt_in_endpointAddress;
|
|
|
+
|
|
|
+ unsigned char *bulk_in_buffer;
|
|
|
+ unsigned char *xfer_to_tty_buffer;
|
|
|
+ struct urb *read_urb;
|
|
|
+ __u8 bulk_in_endpointAddress;
|
|
|
+
|
|
|
+ unsigned char *bulk_out_buffer;
|
|
|
+ int bulk_out_size;
|
|
|
+ struct urb *write_urb;
|
|
|
+ __u8 bulk_out_endpointAddress;
|
|
|
+
|
|
|
+ wait_queue_head_t write_wait;
|
|
|
+ wait_queue_head_t wait;
|
|
|
+ struct work_struct work;
|
|
|
+
|
|
|
+ int open_count; /* number of times this port has been opened */
|
|
|
+ struct semaphore sem; /* locks this structure */
|
|
|
+
|
|
|
+ __u8 shadowLCR; /* last LCR value received */
|
|
|
+ __u8 shadowMCR; /* last MCR value received */
|
|
|
+ __u8 shadowMSR; /* last MSR value received */
|
|
|
+ __u8 shadowLSR; /* last LSR value received */
|
|
|
+ int RxHolding;
|
|
|
+ char closePending;
|
|
|
+ int ReadBulkStopped;
|
|
|
+
|
|
|
+ void *private; /* data private to the specific port */
|
|
|
};
|
|
|
|
|
|
struct identity {
|
|
|
- int index;
|
|
|
- int n_identity;
|
|
|
+ int index;
|
|
|
+ int n_identity;
|
|
|
};
|
|
|
|
|
|
struct usb_serial {
|
|
|
- struct usb_device * dev;
|
|
|
- struct usb_interface * interface; /* the interface for this device */
|
|
|
- struct tty_driver * tty_driver; /* the tty_driver for this device */
|
|
|
- unsigned char minor; /* the starting minor number for this device */
|
|
|
- unsigned char num_ports; /* the number of ports this device has */
|
|
|
- char num_interrupt_in; /* number of interrupt in endpoints we have */
|
|
|
- char num_bulk_in; /* number of bulk in endpoints we have */
|
|
|
- char num_bulk_out; /* number of bulk out endpoints we have */
|
|
|
- unsigned char num_OpenCount; /* the number of ports this device has */
|
|
|
-
|
|
|
-
|
|
|
- __u16 vendor; /* vendor id of this device */
|
|
|
- __u16 product; /* product id of this device */
|
|
|
- struct usb_serial_port port[MAX_NUM_PORTS];
|
|
|
-
|
|
|
- void * private; /* data private to the specific driver */
|
|
|
+ struct usb_device *dev;
|
|
|
+ struct usb_interface *interface; /* the interface for this device */
|
|
|
+ struct tty_driver *tty_driver; /* the tty_driver for this device */
|
|
|
+ unsigned char minor; /* the starting minor number for this device */
|
|
|
+ unsigned char num_ports; /* the number of ports this device has */
|
|
|
+ char num_interrupt_in; /* number of interrupt in endpoints we have */
|
|
|
+ char num_bulk_in; /* number of bulk in endpoints we have */
|
|
|
+ char num_bulk_out; /* number of bulk out endpoints we have */
|
|
|
+ unsigned char num_OpenCount; /* the number of ports this device has */
|
|
|
+
|
|
|
+ __u16 vendor; /* vendor id of this device */
|
|
|
+ __u16 product; /* product id of this device */
|
|
|
+ struct usb_serial_port port[MAX_NUM_PORTS];
|
|
|
+
|
|
|
+ void *private; /* data private to the specific driver */
|
|
|
};
|
|
|
|
|
|
-
|
|
|
-
|
|
|
-static inline int port_paranoia_check (struct usb_serial_port *port, const char *function)
|
|
|
+static inline int port_paranoia_check(struct usb_serial_port *port,
|
|
|
+ const char *function)
|
|
|
{
|
|
|
if (!port) {
|
|
|
dbg("%s - port == NULL", function);
|
|
@@ -233,9 +222,9 @@ static inline int port_paranoia_check (struct usb_serial_port *port, const char
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
-
|
|
|
/* Inline functions to check the sanity of a pointer that is passed to us */
|
|
|
-static inline int serial_paranoia_check (struct usb_serial *serial, const char *function)
|
|
|
+static inline int serial_paranoia_check(struct usb_serial *serial,
|
|
|
+ const char *function)
|
|
|
{
|
|
|
if (!serial) {
|
|
|
dbg("%s - serial == NULL\n", function);
|
|
@@ -245,13 +234,13 @@ static inline int serial_paranoia_check (struct usb_serial *serial, const char *
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
-
|
|
|
-static inline struct usb_serial* get_usb_serial (struct usb_serial_port *port, const char *function)
|
|
|
+static inline struct usb_serial *get_usb_serial(struct usb_serial_port *port,
|
|
|
+ const char *function)
|
|
|
{
|
|
|
/* if no port was specified, or it fails a paranoia check */
|
|
|
if (!port ||
|
|
|
- port_paranoia_check (port, function) ||
|
|
|
- serial_paranoia_check (port->serial, function)) {
|
|
|
+ port_paranoia_check(port, function) ||
|
|
|
+ serial_paranoia_check(port->serial, function)) {
|
|
|
/* then say that we dont have a valid usb_serial thing, which will
|
|
|
* end up genrating -ENODEV return values */
|
|
|
return NULL;
|
|
@@ -260,90 +249,99 @@ static inline struct usb_serial* get_usb_serial (struct usb_serial_port *port, c
|
|
|
return port->serial;
|
|
|
}
|
|
|
|
|
|
-
|
|
|
-struct qt_get_device_data
|
|
|
-{
|
|
|
+struct qt_get_device_data {
|
|
|
__u8 porta;
|
|
|
__u8 portb;
|
|
|
__u8 portc;
|
|
|
};
|
|
|
|
|
|
-struct qt_open_channel_data
|
|
|
-{
|
|
|
+struct qt_open_channel_data {
|
|
|
__u8 line_status;
|
|
|
__u8 modem_status;
|
|
|
};
|
|
|
|
|
|
-static void ProcessLineStatus(struct usb_serial_port *port, unsigned char line_status);
|
|
|
-static void ProcessModemStatus(struct usb_serial_port *port, unsigned char modem_status);
|
|
|
+static void ProcessLineStatus(struct usb_serial_port *port,
|
|
|
+ unsigned char line_status);
|
|
|
+static void ProcessModemStatus(struct usb_serial_port *port,
|
|
|
+ unsigned char modem_status);
|
|
|
static void ProcessRxChar(struct usb_serial_port *port, unsigned char Data);
|
|
|
-static struct usb_serial *get_free_serial (int num_ports, int *minor);
|
|
|
-
|
|
|
+static struct usb_serial *get_free_serial(int num_ports, int *minor);
|
|
|
|
|
|
static int serqt_probe(struct usb_interface *interface,
|
|
|
- const struct usb_device_id *id);
|
|
|
-
|
|
|
+ const struct usb_device_id *id);
|
|
|
|
|
|
static void serqt_usb_disconnect(struct usb_interface *interface);
|
|
|
-static int box_set_device(struct usb_serial *serial, struct qt_get_device_data *pDeviceData);
|
|
|
-static int box_get_device(struct usb_serial *serial, struct qt_get_device_data *pDeviceData);
|
|
|
-static int serial_open (struct tty_struct *tty, struct file * filp);
|
|
|
-static void serial_close(struct tty_struct *tty, struct file * filp);
|
|
|
-static int serial_write_room (struct tty_struct *tty);
|
|
|
-static int serial_ioctl (struct tty_struct *tty, struct file * file, unsigned int cmd, unsigned long arg);
|
|
|
-static void serial_set_termios (struct tty_struct *tty, struct ktermios * old);
|
|
|
-static int serial_write (struct tty_struct * tty, const unsigned char *buf, int count);
|
|
|
-
|
|
|
-static void serial_throttle (struct tty_struct * tty);
|
|
|
-static void serial_unthrottle (struct tty_struct * tty);
|
|
|
-static int serial_break (struct tty_struct *tty, int break_state);
|
|
|
-static int serial_chars_in_buffer (struct tty_struct *tty);
|
|
|
-static int serial_read_proc (char *page, char **start, off_t off, int count, int *eof, void *data);
|
|
|
-
|
|
|
-static int qt_open (struct usb_serial_port *port, struct file *filp);
|
|
|
+static int box_set_device(struct usb_serial *serial,
|
|
|
+ struct qt_get_device_data *pDeviceData);
|
|
|
+static int box_get_device(struct usb_serial *serial,
|
|
|
+ struct qt_get_device_data *pDeviceData);
|
|
|
+static int serial_open(struct tty_struct *tty, struct file *filp);
|
|
|
+static void serial_close(struct tty_struct *tty, struct file *filp);
|
|
|
+static int serial_write_room(struct tty_struct *tty);
|
|
|
+static int serial_ioctl(struct tty_struct *tty, struct file *file,
|
|
|
+ unsigned int cmd, unsigned long arg);
|
|
|
+static void serial_set_termios(struct tty_struct *tty, struct ktermios *old);
|
|
|
+static int serial_write(struct tty_struct *tty, const unsigned char *buf,
|
|
|
+ int count);
|
|
|
+
|
|
|
+static void serial_throttle(struct tty_struct *tty);
|
|
|
+static void serial_unthrottle(struct tty_struct *tty);
|
|
|
+static int serial_break(struct tty_struct *tty, int break_state);
|
|
|
+static int serial_chars_in_buffer(struct tty_struct *tty);
|
|
|
+static int serial_read_proc(char *page, char **start, off_t off, int count,
|
|
|
+ int *eof, void *data);
|
|
|
+
|
|
|
+static int qt_open(struct usb_serial_port *port, struct file *filp);
|
|
|
static int BoxSetPrebufferLevel(struct usb_serial *serial);
|
|
|
|
|
|
static int BoxSetATC(struct usb_serial *serial, __u16 n_Mode);
|
|
|
-static int BoxSetUart(struct usb_serial *serial, unsigned short Uart_Number, unsigned short default_divisor, unsigned char default_LCR );
|
|
|
-
|
|
|
-
|
|
|
-static int BoxOPenCloseChannel(struct usb_serial *serial, __u16 Uart_Number, __u16 OpenClose, struct qt_open_channel_data *pDeviceData);
|
|
|
-static void qt_close (struct usb_serial_port *port, struct file * filp);
|
|
|
-static int BoxGetRegister(struct usb_serial *serial, unsigned short Uart_Number,unsigned short Register_Num, __u8 *pValue);
|
|
|
-static int BoxSetRegister(struct usb_serial *serial, unsigned short Uart_Number, unsigned short Register_Num, unsigned short Value );
|
|
|
+static int BoxSetUart(struct usb_serial *serial, unsigned short Uart_Number,
|
|
|
+ unsigned short default_divisor,
|
|
|
+ unsigned char default_LCR);
|
|
|
+
|
|
|
+static int BoxOPenCloseChannel(struct usb_serial *serial, __u16 Uart_Number,
|
|
|
+ __u16 OpenClose,
|
|
|
+ struct qt_open_channel_data *pDeviceData);
|
|
|
+static void qt_close(struct usb_serial_port *port, struct file *filp);
|
|
|
+static int BoxGetRegister(struct usb_serial *serial, unsigned short Uart_Number,
|
|
|
+ unsigned short Register_Num, __u8 * pValue);
|
|
|
+static int BoxSetRegister(struct usb_serial *serial, unsigned short Uart_Number,
|
|
|
+ unsigned short Register_Num, unsigned short Value);
|
|
|
static void qt_write_bulk_callback(struct urb *urb);
|
|
|
-static int qt_write (struct usb_serial_port *port, int from_user, const unsigned char *buf, int count);
|
|
|
+static int qt_write(struct usb_serial_port *port, int from_user,
|
|
|
+ const unsigned char *buf, int count);
|
|
|
static void port_softint(struct work_struct *work);
|
|
|
-static int qt_write_room (struct usb_serial_port *port);
|
|
|
-static int qt_chars_in_buffer (struct usb_serial_port *port);
|
|
|
-static int qt_ioctl(struct usb_serial_port *port, struct file * file, unsigned int cmd, unsigned long arg);
|
|
|
-static void qt_set_termios(struct usb_serial_port *port, struct ktermios *old_termios);
|
|
|
-static int BoxSetHW_FlowCtrl(struct usb_serial *serial, unsigned int UartNumber, int bSet);
|
|
|
+static int qt_write_room(struct usb_serial_port *port);
|
|
|
+static int qt_chars_in_buffer(struct usb_serial_port *port);
|
|
|
+static int qt_ioctl(struct usb_serial_port *port, struct file *file,
|
|
|
+ unsigned int cmd, unsigned long arg);
|
|
|
+static void qt_set_termios(struct usb_serial_port *port,
|
|
|
+ struct ktermios *old_termios);
|
|
|
+static int BoxSetHW_FlowCtrl(struct usb_serial *serial, unsigned int UartNumber,
|
|
|
+ int bSet);
|
|
|
static int BoxDisable_SW_FlowCtrl(struct usb_serial *serial, __u16 UartNumber);
|
|
|
static int EmulateWriteQMCR_Reg(int index, unsigned uc_value);
|
|
|
static int EmulateReadQMCR_Reg(int index, unsigned *uc_value);
|
|
|
static struct usb_serial *find_the_box(unsigned int index);
|
|
|
-int ioctl_serial_usb (struct inode *innod, struct file *filp, unsigned int cmd, unsigned long arg);
|
|
|
+int ioctl_serial_usb(struct inode *innod, struct file *filp, unsigned int cmd,
|
|
|
+ unsigned long arg);
|
|
|
|
|
|
-
|
|
|
-static int BoxSetSW_FlowCtrl(struct usb_serial *serial, __u16 Uart, unsigned char stop_char, unsigned char start_char);
|
|
|
+static int BoxSetSW_FlowCtrl(struct usb_serial *serial, __u16 Uart,
|
|
|
+ unsigned char stop_char, unsigned char start_char);
|
|
|
static void qt_read_bulk_callback(struct urb *urb);
|
|
|
|
|
|
static void port_sofrint(void *private);
|
|
|
|
|
|
static void return_serial(struct usb_serial *serial);
|
|
|
|
|
|
-
|
|
|
-static int serial_tiocmset (struct tty_struct *tty, struct file *file, unsigned int set, unsigned int clear);
|
|
|
+static int serial_tiocmset(struct tty_struct *tty, struct file *file,
|
|
|
+ unsigned int set, unsigned int clear);
|
|
|
static int serial_tiocmget(struct tty_struct *tty, struct file *file);
|
|
|
|
|
|
+static int qt_tiocmset(struct usb_serial_port *port, struct file *file,
|
|
|
+ unsigned int value);
|
|
|
|
|
|
-
|
|
|
-static int qt_tiocmset(struct usb_serial_port *port, struct file * file, unsigned int value);
|
|
|
-
|
|
|
-static int qt_tiocmget(struct usb_serial_port *port, struct file * file);
|
|
|
-
|
|
|
-
|
|
|
+static int qt_tiocmget(struct usb_serial_port *port, struct file *file);
|
|
|
|
|
|
/* Version Information */
|
|
|
#define DRIVER_VERSION "v2.14"
|
|
@@ -370,34 +368,39 @@ static int qt_tiocmget(struct usb_serial_port *port, struct file * file);
|
|
|
#define DEVICE_ID_QUATECH_RS422_16_PORT_C 0xC0B2 //HSU200C
|
|
|
#define DEVICE_ID_QUATECH_RS422_16_PORT_D 0xC0B3 //HSU200D
|
|
|
|
|
|
-
|
|
|
/* table of Quatech devices */
|
|
|
-static struct usb_device_id serqt_table [] = {
|
|
|
- { USB_DEVICE(USB_VENDOR_ID_QUATECH, DEVICE_ID_QUATECH_RS232_SINGLE_PORT)},
|
|
|
- { USB_DEVICE(USB_VENDOR_ID_QUATECH, DEVICE_ID_QUATECH_RS422_SINGLE_PORT)},
|
|
|
- { USB_DEVICE(USB_VENDOR_ID_QUATECH, DEVICE_ID_QUATECH_RS232_DUAL_PORT)},
|
|
|
- { USB_DEVICE(USB_VENDOR_ID_QUATECH, DEVICE_ID_QUATECH_RS422_DUAL_PORT)},
|
|
|
- { USB_DEVICE(USB_VENDOR_ID_QUATECH, DEVICE_ID_QUATECH_RS232_FOUR_PORT)},
|
|
|
- { USB_DEVICE(USB_VENDOR_ID_QUATECH, DEVICE_ID_QUATECH_RS422_FOUR_PORT)},
|
|
|
- { USB_DEVICE(USB_VENDOR_ID_QUATECH, DEVICE_ID_QUATECH_RS232_EIGHT_PORT_A)},
|
|
|
- { USB_DEVICE(USB_VENDOR_ID_QUATECH, DEVICE_ID_QUATECH_RS232_EIGHT_PORT_B)},
|
|
|
- { USB_DEVICE(USB_VENDOR_ID_QUATECH, DEVICE_ID_QUATECH_RS422_EIGHT_PORT_A)},
|
|
|
- { USB_DEVICE(USB_VENDOR_ID_QUATECH, DEVICE_ID_QUATECH_RS422_EIGHT_PORT_B)},
|
|
|
- { USB_DEVICE(USB_VENDOR_ID_QUATECH, DEVICE_ID_QUATECH_RS232_16_PORT_A)},
|
|
|
- { USB_DEVICE(USB_VENDOR_ID_QUATECH, DEVICE_ID_QUATECH_RS232_16_PORT_B)},
|
|
|
- { USB_DEVICE(USB_VENDOR_ID_QUATECH, DEVICE_ID_QUATECH_RS232_16_PORT_C)},
|
|
|
- { USB_DEVICE(USB_VENDOR_ID_QUATECH, DEVICE_ID_QUATECH_RS232_16_PORT_D)},
|
|
|
- { USB_DEVICE(USB_VENDOR_ID_QUATECH, DEVICE_ID_QUATECH_RS422_16_PORT_A)},
|
|
|
- { USB_DEVICE(USB_VENDOR_ID_QUATECH, DEVICE_ID_QUATECH_RS422_16_PORT_B)},
|
|
|
- { USB_DEVICE(USB_VENDOR_ID_QUATECH, DEVICE_ID_QUATECH_RS422_16_PORT_C)},
|
|
|
- { USB_DEVICE(USB_VENDOR_ID_QUATECH, DEVICE_ID_QUATECH_RS422_16_PORT_D)},
|
|
|
- {} /* Terminating entry */
|
|
|
+static struct usb_device_id serqt_table[] = {
|
|
|
+ {USB_DEVICE
|
|
|
+ (USB_VENDOR_ID_QUATECH, DEVICE_ID_QUATECH_RS232_SINGLE_PORT)},
|
|
|
+ {USB_DEVICE
|
|
|
+ (USB_VENDOR_ID_QUATECH, DEVICE_ID_QUATECH_RS422_SINGLE_PORT)},
|
|
|
+ {USB_DEVICE(USB_VENDOR_ID_QUATECH, DEVICE_ID_QUATECH_RS232_DUAL_PORT)},
|
|
|
+ {USB_DEVICE(USB_VENDOR_ID_QUATECH, DEVICE_ID_QUATECH_RS422_DUAL_PORT)},
|
|
|
+ {USB_DEVICE(USB_VENDOR_ID_QUATECH, DEVICE_ID_QUATECH_RS232_FOUR_PORT)},
|
|
|
+ {USB_DEVICE(USB_VENDOR_ID_QUATECH, DEVICE_ID_QUATECH_RS422_FOUR_PORT)},
|
|
|
+ {USB_DEVICE
|
|
|
+ (USB_VENDOR_ID_QUATECH, DEVICE_ID_QUATECH_RS232_EIGHT_PORT_A)},
|
|
|
+ {USB_DEVICE
|
|
|
+ (USB_VENDOR_ID_QUATECH, DEVICE_ID_QUATECH_RS232_EIGHT_PORT_B)},
|
|
|
+ {USB_DEVICE
|
|
|
+ (USB_VENDOR_ID_QUATECH, DEVICE_ID_QUATECH_RS422_EIGHT_PORT_A)},
|
|
|
+ {USB_DEVICE
|
|
|
+ (USB_VENDOR_ID_QUATECH, DEVICE_ID_QUATECH_RS422_EIGHT_PORT_B)},
|
|
|
+ {USB_DEVICE(USB_VENDOR_ID_QUATECH, DEVICE_ID_QUATECH_RS232_16_PORT_A)},
|
|
|
+ {USB_DEVICE(USB_VENDOR_ID_QUATECH, DEVICE_ID_QUATECH_RS232_16_PORT_B)},
|
|
|
+ {USB_DEVICE(USB_VENDOR_ID_QUATECH, DEVICE_ID_QUATECH_RS232_16_PORT_C)},
|
|
|
+ {USB_DEVICE(USB_VENDOR_ID_QUATECH, DEVICE_ID_QUATECH_RS232_16_PORT_D)},
|
|
|
+ {USB_DEVICE(USB_VENDOR_ID_QUATECH, DEVICE_ID_QUATECH_RS422_16_PORT_A)},
|
|
|
+ {USB_DEVICE(USB_VENDOR_ID_QUATECH, DEVICE_ID_QUATECH_RS422_16_PORT_B)},
|
|
|
+ {USB_DEVICE(USB_VENDOR_ID_QUATECH, DEVICE_ID_QUATECH_RS422_16_PORT_C)},
|
|
|
+ {USB_DEVICE(USB_VENDOR_ID_QUATECH, DEVICE_ID_QUATECH_RS422_16_PORT_D)},
|
|
|
+ {} /* Terminating entry */
|
|
|
};
|
|
|
+
|
|
|
MODULE_DEVICE_TABLE(usb, serqt_table);
|
|
|
|
|
|
static int major_number;
|
|
|
-static struct usb_serial *serial_table[SERIAL_TTY_MINORS]; /* initially all NULL */
|
|
|
-
|
|
|
+static struct usb_serial *serial_table[SERIAL_TTY_MINORS]; /* initially all NULL */
|
|
|
|
|
|
/* table of Quatech 422devices */
|
|
|
static unsigned int serqt_422_table[] = {
|
|
@@ -410,66 +413,64 @@ static unsigned int serqt_422_table[] = {
|
|
|
DEVICE_ID_QUATECH_RS422_16_PORT_B,
|
|
|
DEVICE_ID_QUATECH_RS422_16_PORT_C,
|
|
|
DEVICE_ID_QUATECH_RS422_16_PORT_D,
|
|
|
- 0 /* terminate with zero */
|
|
|
+ 0 /* terminate with zero */
|
|
|
};
|
|
|
|
|
|
-
|
|
|
-
|
|
|
/* usb specific object needed to register this driver with the usb subsystem */
|
|
|
static struct usb_driver serqt_usb_driver = {
|
|
|
- .name = "quatech-usb-serial",
|
|
|
- .probe = serqt_probe,
|
|
|
- .disconnect = serqt_usb_disconnect,
|
|
|
- .id_table = serqt_table,
|
|
|
+ .name = "quatech-usb-serial",
|
|
|
+ .probe = serqt_probe,
|
|
|
+ .disconnect = serqt_usb_disconnect,
|
|
|
+ .id_table = serqt_table,
|
|
|
};
|
|
|
|
|
|
static struct ktermios *serial_termios[SERIAL_TTY_MINORS];
|
|
|
static struct ktermios *serial_termios_locked[SERIAL_TTY_MINORS];
|
|
|
|
|
|
static const struct tty_operations serial_ops = {
|
|
|
- .open = serial_open,
|
|
|
- .close = serial_close,
|
|
|
- .write = serial_write,
|
|
|
- .write_room = serial_write_room,
|
|
|
- .ioctl = serial_ioctl,
|
|
|
- .set_termios = serial_set_termios,
|
|
|
- .throttle = serial_throttle,
|
|
|
- .unthrottle = serial_unthrottle,
|
|
|
- .break_ctl = serial_break,
|
|
|
- .chars_in_buffer = serial_chars_in_buffer,
|
|
|
- .read_proc = serial_read_proc,
|
|
|
- .tiocmset = serial_tiocmset,
|
|
|
- .tiocmget = serial_tiocmget,
|
|
|
+ .open = serial_open,
|
|
|
+ .close = serial_close,
|
|
|
+ .write = serial_write,
|
|
|
+ .write_room = serial_write_room,
|
|
|
+ .ioctl = serial_ioctl,
|
|
|
+ .set_termios = serial_set_termios,
|
|
|
+ .throttle = serial_throttle,
|
|
|
+ .unthrottle = serial_unthrottle,
|
|
|
+ .break_ctl = serial_break,
|
|
|
+ .chars_in_buffer = serial_chars_in_buffer,
|
|
|
+ .read_proc = serial_read_proc,
|
|
|
+ .tiocmset = serial_tiocmset,
|
|
|
+ .tiocmget = serial_tiocmget,
|
|
|
};
|
|
|
|
|
|
static struct tty_driver serial_tty_driver = {
|
|
|
- .magic = TTY_DRIVER_MAGIC,
|
|
|
- .driver_name = "Quatech usb-serial",
|
|
|
- .name = "ttyQT_USB",
|
|
|
- .major = SERIAL_TTY_MAJOR,
|
|
|
- .minor_start = 0,
|
|
|
- .num = SERIAL_TTY_MINORS,
|
|
|
- .type = TTY_DRIVER_TYPE_SERIAL,
|
|
|
- .subtype = SERIAL_TYPE_NORMAL,
|
|
|
- .flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV,
|
|
|
-
|
|
|
- .termios = serial_termios,
|
|
|
- .termios_locked = serial_termios_locked,
|
|
|
- .init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL,
|
|
|
-
|
|
|
- .init_termios.c_iflag = ICRNL | IXON,
|
|
|
- .init_termios.c_oflag = OPOST,
|
|
|
-
|
|
|
- .init_termios.c_lflag= ISIG | ICANON | ECHO | ECHOE | ECHOK | ECHOCTL | ECHOKE | IEXTEN,
|
|
|
+ .magic = TTY_DRIVER_MAGIC,
|
|
|
+ .driver_name = "Quatech usb-serial",
|
|
|
+ .name = "ttyQT_USB",
|
|
|
+ .major = SERIAL_TTY_MAJOR,
|
|
|
+ .minor_start = 0,
|
|
|
+ .num = SERIAL_TTY_MINORS,
|
|
|
+ .type = TTY_DRIVER_TYPE_SERIAL,
|
|
|
+ .subtype = SERIAL_TYPE_NORMAL,
|
|
|
+ .flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV,
|
|
|
+
|
|
|
+ .termios = serial_termios,
|
|
|
+ .termios_locked = serial_termios_locked,
|
|
|
+ .init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL,
|
|
|
+
|
|
|
+ .init_termios.c_iflag = ICRNL | IXON,
|
|
|
+ .init_termios.c_oflag = OPOST,
|
|
|
+
|
|
|
+ .init_termios.c_lflag =
|
|
|
+ ISIG | ICANON | ECHO | ECHOE | ECHOK | ECHOCTL | ECHOKE | IEXTEN,
|
|
|
};
|
|
|
|
|
|
//fops for parent device
|
|
|
static struct file_operations serialqt_usb_fops = {
|
|
|
- .ioctl = ioctl_serial_usb,
|
|
|
+ .ioctl = ioctl_serial_usb,
|
|
|
|
|
|
};
|
|
|
|
|
|
-
|
|
|
/**
|
|
|
* serqt_probe
|
|
|
*
|
|
@@ -478,341 +479,299 @@ static struct file_operations serialqt_usb_fops = {
|
|
|
*
|
|
|
*/
|
|
|
static int serqt_probe(struct usb_interface *interface,
|
|
|
- const struct usb_device_id *id)
|
|
|
+ const struct usb_device_id *id)
|
|
|
{
|
|
|
- struct usb_device *dev = interface_to_usbdev(interface);
|
|
|
- struct usb_serial *serial = NULL;
|
|
|
- struct usb_serial_port *port;
|
|
|
- struct usb_endpoint_descriptor *endpoint;
|
|
|
- struct usb_endpoint_descriptor *interrupt_in_endpoint[MAX_NUM_PORTS];
|
|
|
- struct usb_endpoint_descriptor *bulk_in_endpoint[MAX_NUM_PORTS];
|
|
|
- struct usb_endpoint_descriptor *bulk_out_endpoint[MAX_NUM_PORTS];
|
|
|
- int minor;
|
|
|
- int buffer_size;
|
|
|
- int i;
|
|
|
- struct usb_host_interface *iface_desc;
|
|
|
- int num_interrupt_in = 0;
|
|
|
- int num_bulk_in = 0;
|
|
|
- int num_bulk_out = 0;
|
|
|
- int num_ports;
|
|
|
- struct qt_get_device_data DeviceData;
|
|
|
- int status;
|
|
|
+ struct usb_device *dev = interface_to_usbdev(interface);
|
|
|
+ struct usb_serial *serial = NULL;
|
|
|
+ struct usb_serial_port *port;
|
|
|
+ struct usb_endpoint_descriptor *endpoint;
|
|
|
+ struct usb_endpoint_descriptor *interrupt_in_endpoint[MAX_NUM_PORTS];
|
|
|
+ struct usb_endpoint_descriptor *bulk_in_endpoint[MAX_NUM_PORTS];
|
|
|
+ struct usb_endpoint_descriptor *bulk_out_endpoint[MAX_NUM_PORTS];
|
|
|
+ int minor;
|
|
|
+ int buffer_size;
|
|
|
+ int i;
|
|
|
+ struct usb_host_interface *iface_desc;
|
|
|
+ int num_interrupt_in = 0;
|
|
|
+ int num_bulk_in = 0;
|
|
|
+ int num_bulk_out = 0;
|
|
|
+ int num_ports;
|
|
|
+ struct qt_get_device_data DeviceData;
|
|
|
+ int status;
|
|
|
|
|
|
mydbg("In %s\n", __FUNCTION__);
|
|
|
|
|
|
- /* let's find the endpoints needed */
|
|
|
- /* check out the endpoints */
|
|
|
- iface_desc = interface->cur_altsetting;;
|
|
|
- for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i)
|
|
|
- {
|
|
|
- endpoint = &iface_desc->endpoint[i].desc;
|
|
|
-
|
|
|
- if ((endpoint->bEndpointAddress & 0x80) &&
|
|
|
- ((endpoint->bmAttributes & 3) == 0x02))
|
|
|
- {
|
|
|
- /* we found a bulk in endpoint */
|
|
|
- mydbg("found bulk in");
|
|
|
- bulk_in_endpoint[num_bulk_in] = endpoint;
|
|
|
- ++num_bulk_in;
|
|
|
- }
|
|
|
-
|
|
|
- if (((endpoint->bEndpointAddress & 0x80) == 0x00) &&
|
|
|
- ((endpoint->bmAttributes & 3) == 0x02))
|
|
|
- {
|
|
|
- /* we found a bulk out endpoint */
|
|
|
- mydbg("found bulk out\n");
|
|
|
- bulk_out_endpoint[num_bulk_out] = endpoint;
|
|
|
- ++num_bulk_out;
|
|
|
- }
|
|
|
-
|
|
|
- if ((endpoint->bEndpointAddress & 0x80) &&
|
|
|
- ((endpoint->bmAttributes & 3) == 0x03))
|
|
|
- {
|
|
|
- /* we found a interrupt in endpoint */
|
|
|
- mydbg("found interrupt in\n");
|
|
|
- interrupt_in_endpoint[num_interrupt_in] = endpoint;
|
|
|
- ++num_interrupt_in;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- /* found all that we need */
|
|
|
- dev_info(&interface->dev, "Quatech converter detected\n");
|
|
|
- num_ports = num_bulk_out;
|
|
|
- if (num_ports == 0)
|
|
|
- {
|
|
|
- err("Quatech device with no bulk out, not allowed.");
|
|
|
- return -ENODEV;
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- serial = get_free_serial (num_ports, &minor);
|
|
|
- if (serial == NULL)
|
|
|
- {
|
|
|
- err("No more free serial devices");
|
|
|
- return -ENODEV;
|
|
|
- }
|
|
|
-
|
|
|
- serial->dev = dev;
|
|
|
- serial->interface = interface;
|
|
|
- serial->minor = minor;
|
|
|
- serial->num_ports = num_ports;
|
|
|
- serial->num_bulk_in = num_bulk_in;
|
|
|
- serial->num_bulk_out = num_bulk_out;
|
|
|
- serial->num_interrupt_in = num_interrupt_in;
|
|
|
- serial->vendor = dev->descriptor.idVendor;
|
|
|
- serial->product = dev->descriptor.idProduct;
|
|
|
-
|
|
|
-
|
|
|
- /* set up the endpoint information */
|
|
|
- for (i = 0; i < num_bulk_in; ++i)
|
|
|
- {
|
|
|
- endpoint = bulk_in_endpoint[i];
|
|
|
- port = &serial->port[i];
|
|
|
- port->read_urb = usb_alloc_urb (0, GFP_KERNEL);
|
|
|
- if (!port->read_urb)
|
|
|
- {
|
|
|
- err("No free urbs available");
|
|
|
- goto probe_error;
|
|
|
- }
|
|
|
- buffer_size = endpoint->wMaxPacketSize;
|
|
|
- port->bulk_in_endpointAddress = endpoint->bEndpointAddress;
|
|
|
- port->bulk_in_buffer = kmalloc (buffer_size, GFP_KERNEL);
|
|
|
- port->xfer_to_tty_buffer = kmalloc (buffer_size, GFP_KERNEL);
|
|
|
- if (!port->bulk_in_buffer)
|
|
|
- {
|
|
|
- err("Couldn't allocate bulk_in_buffer");
|
|
|
- goto probe_error;
|
|
|
- }
|
|
|
- usb_fill_bulk_urb (port->read_urb, dev,
|
|
|
- usb_rcvbulkpipe (dev,
|
|
|
- endpoint->bEndpointAddress),
|
|
|
- port->bulk_in_buffer, buffer_size,
|
|
|
- qt_read_bulk_callback,
|
|
|
- port);
|
|
|
- }
|
|
|
-
|
|
|
- for (i = 0; i < num_bulk_out; ++i)
|
|
|
- {
|
|
|
- endpoint = bulk_out_endpoint[i];
|
|
|
- port = &serial->port[i];
|
|
|
- port->write_urb = usb_alloc_urb (0, GFP_KERNEL);
|
|
|
- if (!port->write_urb)
|
|
|
- {
|
|
|
- err("No free urbs available");
|
|
|
- goto probe_error;
|
|
|
- }
|
|
|
- buffer_size = endpoint->wMaxPacketSize;
|
|
|
- port->bulk_out_size = buffer_size;
|
|
|
- port->bulk_out_endpointAddress = endpoint->bEndpointAddress;
|
|
|
- port->bulk_out_buffer = kmalloc (buffer_size, GFP_KERNEL);
|
|
|
- if (!port->bulk_out_buffer)
|
|
|
- {
|
|
|
- err("Couldn't allocate bulk_out_buffer");
|
|
|
- goto probe_error;
|
|
|
- }
|
|
|
- usb_fill_bulk_urb (port->write_urb, dev,
|
|
|
- usb_sndbulkpipe (dev,
|
|
|
- endpoint->bEndpointAddress),
|
|
|
- port->bulk_out_buffer, buffer_size,
|
|
|
- qt_write_bulk_callback,
|
|
|
- port);
|
|
|
-
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- //For us numb of bulkin or out = number of ports
|
|
|
-
|
|
|
- mydbg("%s - setting up %d port structures for this device\n", __FUNCTION__, num_bulk_in);
|
|
|
- for (i = 0; i < num_bulk_in; ++i)
|
|
|
- {
|
|
|
- port = &serial->port[i];
|
|
|
- port->number = i + serial->minor;
|
|
|
- port->serial = serial;
|
|
|
-
|
|
|
- INIT_WORK(&port->work, port_softint);
|
|
|
-
|
|
|
- init_MUTEX (&port->sem);
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
- }
|
|
|
- status = box_get_device(serial, &DeviceData);
|
|
|
- if (status < 0)
|
|
|
- {
|
|
|
- mydbg(__FILE__"box_get_device failed");
|
|
|
- goto probe_error;
|
|
|
- }
|
|
|
-
|
|
|
- mydbg(__FILE__"DeviceData.portb = 0x%x",DeviceData.portb);
|
|
|
-
|
|
|
- DeviceData.portb &= ~FULLPWRBIT;
|
|
|
- mydbg(__FILE__"Changing DeviceData.portb to 0x%x",DeviceData.portb);
|
|
|
-
|
|
|
- status = box_set_device(serial, &DeviceData);
|
|
|
- if (status < 0)
|
|
|
- {
|
|
|
- mydbg(__FILE__"box_set_device failed\n");
|
|
|
- goto probe_error;
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
- /* initialize the devfs nodes for this device and let the user know what ports we are bound to */
|
|
|
- for (i = 0; i < serial->num_ports; ++i)
|
|
|
- {
|
|
|
- dev_info(&interface->dev, "Converter now attached to ttyUSB%d (or usb/tts/%d for devfs)",
|
|
|
- serial->port[i].number, serial->port[i].number);
|
|
|
- }
|
|
|
+ /* let's find the endpoints needed */
|
|
|
+ /* check out the endpoints */
|
|
|
+ iface_desc = interface->cur_altsetting;;
|
|
|
+ for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) {
|
|
|
+ endpoint = &iface_desc->endpoint[i].desc;
|
|
|
+
|
|
|
+ if ((endpoint->bEndpointAddress & 0x80) &&
|
|
|
+ ((endpoint->bmAttributes & 3) == 0x02)) {
|
|
|
+ /* we found a bulk in endpoint */
|
|
|
+ mydbg("found bulk in");
|
|
|
+ bulk_in_endpoint[num_bulk_in] = endpoint;
|
|
|
+ ++num_bulk_in;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (((endpoint->bEndpointAddress & 0x80) == 0x00) &&
|
|
|
+ ((endpoint->bmAttributes & 3) == 0x02)) {
|
|
|
+ /* we found a bulk out endpoint */
|
|
|
+ mydbg("found bulk out\n");
|
|
|
+ bulk_out_endpoint[num_bulk_out] = endpoint;
|
|
|
+ ++num_bulk_out;
|
|
|
+ }
|
|
|
+
|
|
|
+ if ((endpoint->bEndpointAddress & 0x80) &&
|
|
|
+ ((endpoint->bmAttributes & 3) == 0x03)) {
|
|
|
+ /* we found a interrupt in endpoint */
|
|
|
+ mydbg("found interrupt in\n");
|
|
|
+ interrupt_in_endpoint[num_interrupt_in] = endpoint;
|
|
|
+ ++num_interrupt_in;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /* found all that we need */
|
|
|
+ dev_info(&interface->dev, "Quatech converter detected\n");
|
|
|
+ num_ports = num_bulk_out;
|
|
|
+ if (num_ports == 0) {
|
|
|
+ err("Quatech device with no bulk out, not allowed.");
|
|
|
+ return -ENODEV;
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ serial = get_free_serial(num_ports, &minor);
|
|
|
+ if (serial == NULL) {
|
|
|
+ err("No more free serial devices");
|
|
|
+ return -ENODEV;
|
|
|
+ }
|
|
|
+
|
|
|
+ serial->dev = dev;
|
|
|
+ serial->interface = interface;
|
|
|
+ serial->minor = minor;
|
|
|
+ serial->num_ports = num_ports;
|
|
|
+ serial->num_bulk_in = num_bulk_in;
|
|
|
+ serial->num_bulk_out = num_bulk_out;
|
|
|
+ serial->num_interrupt_in = num_interrupt_in;
|
|
|
+ serial->vendor = dev->descriptor.idVendor;
|
|
|
+ serial->product = dev->descriptor.idProduct;
|
|
|
+
|
|
|
+ /* set up the endpoint information */
|
|
|
+ for (i = 0; i < num_bulk_in; ++i) {
|
|
|
+ endpoint = bulk_in_endpoint[i];
|
|
|
+ port = &serial->port[i];
|
|
|
+ port->read_urb = usb_alloc_urb(0, GFP_KERNEL);
|
|
|
+ if (!port->read_urb) {
|
|
|
+ err("No free urbs available");
|
|
|
+ goto probe_error;
|
|
|
+ }
|
|
|
+ buffer_size = endpoint->wMaxPacketSize;
|
|
|
+ port->bulk_in_endpointAddress = endpoint->bEndpointAddress;
|
|
|
+ port->bulk_in_buffer = kmalloc(buffer_size, GFP_KERNEL);
|
|
|
+ port->xfer_to_tty_buffer = kmalloc(buffer_size, GFP_KERNEL);
|
|
|
+ if (!port->bulk_in_buffer) {
|
|
|
+ err("Couldn't allocate bulk_in_buffer");
|
|
|
+ goto probe_error;
|
|
|
+ }
|
|
|
+ usb_fill_bulk_urb(port->read_urb, dev,
|
|
|
+ usb_rcvbulkpipe(dev,
|
|
|
+ endpoint->bEndpointAddress),
|
|
|
+ port->bulk_in_buffer, buffer_size,
|
|
|
+ qt_read_bulk_callback, port);
|
|
|
+ }
|
|
|
+
|
|
|
+ for (i = 0; i < num_bulk_out; ++i) {
|
|
|
+ endpoint = bulk_out_endpoint[i];
|
|
|
+ port = &serial->port[i];
|
|
|
+ port->write_urb = usb_alloc_urb(0, GFP_KERNEL);
|
|
|
+ if (!port->write_urb) {
|
|
|
+ err("No free urbs available");
|
|
|
+ goto probe_error;
|
|
|
+ }
|
|
|
+ buffer_size = endpoint->wMaxPacketSize;
|
|
|
+ port->bulk_out_size = buffer_size;
|
|
|
+ port->bulk_out_endpointAddress = endpoint->bEndpointAddress;
|
|
|
+ port->bulk_out_buffer = kmalloc(buffer_size, GFP_KERNEL);
|
|
|
+ if (!port->bulk_out_buffer) {
|
|
|
+ err("Couldn't allocate bulk_out_buffer");
|
|
|
+ goto probe_error;
|
|
|
+ }
|
|
|
+ usb_fill_bulk_urb(port->write_urb, dev,
|
|
|
+ usb_sndbulkpipe(dev,
|
|
|
+ endpoint->bEndpointAddress),
|
|
|
+ port->bulk_out_buffer, buffer_size,
|
|
|
+ qt_write_bulk_callback, port);
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ //For us numb of bulkin or out = number of ports
|
|
|
+
|
|
|
+ mydbg("%s - setting up %d port structures for this device\n",
|
|
|
+ __FUNCTION__, num_bulk_in);
|
|
|
+ for (i = 0; i < num_bulk_in; ++i) {
|
|
|
+ port = &serial->port[i];
|
|
|
+ port->number = i + serial->minor;
|
|
|
+ port->serial = serial;
|
|
|
+
|
|
|
+ INIT_WORK(&port->work, port_softint);
|
|
|
+
|
|
|
+ init_MUTEX(&port->sem);
|
|
|
+
|
|
|
+ }
|
|
|
+ status = box_get_device(serial, &DeviceData);
|
|
|
+ if (status < 0) {
|
|
|
+ mydbg(__FILE__ "box_get_device failed");
|
|
|
+ goto probe_error;
|
|
|
+ }
|
|
|
+
|
|
|
+ mydbg(__FILE__ "DeviceData.portb = 0x%x", DeviceData.portb);
|
|
|
+
|
|
|
+ DeviceData.portb &= ~FULLPWRBIT;
|
|
|
+ mydbg(__FILE__ "Changing DeviceData.portb to 0x%x", DeviceData.portb);
|
|
|
+
|
|
|
+ status = box_set_device(serial, &DeviceData);
|
|
|
+ if (status < 0) {
|
|
|
+ mydbg(__FILE__ "box_set_device failed\n");
|
|
|
+ goto probe_error;
|
|
|
+ }
|
|
|
+
|
|
|
+ /* initialize the devfs nodes for this device and let the user know what ports we are bound to */
|
|
|
+ for (i = 0; i < serial->num_ports; ++i) {
|
|
|
+ dev_info(&interface->dev,
|
|
|
+ "Converter now attached to ttyUSB%d (or usb/tts/%d for devfs)",
|
|
|
+ serial->port[i].number, serial->port[i].number);
|
|
|
+ }
|
|
|
|
|
|
//usb_serial_console_init (debug, minor);
|
|
|
|
|
|
- ///***********TAG add start next board here ****///
|
|
|
- status = box_get_device(serial, &DeviceData);
|
|
|
- if (status < 0)
|
|
|
- {
|
|
|
- mydbg(__FILE__"box_get_device failed");
|
|
|
- goto probe_error;
|
|
|
- }
|
|
|
-
|
|
|
- //*****************and before we power up lets initialiaze parnent device stuff here before
|
|
|
- //*****************we set thmem via any other method such as the property pages
|
|
|
- switch (serial->product)
|
|
|
- {
|
|
|
- case DEVICE_ID_QUATECH_RS232_SINGLE_PORT:
|
|
|
- case DEVICE_ID_QUATECH_RS232_DUAL_PORT:
|
|
|
- case DEVICE_ID_QUATECH_RS232_FOUR_PORT:
|
|
|
- case DEVICE_ID_QUATECH_RS232_EIGHT_PORT_A:
|
|
|
- case DEVICE_ID_QUATECH_RS232_EIGHT_PORT_B:
|
|
|
- case DEVICE_ID_QUATECH_RS232_16_PORT_A:
|
|
|
- case DEVICE_ID_QUATECH_RS232_16_PORT_B:
|
|
|
- case DEVICE_ID_QUATECH_RS232_16_PORT_C:
|
|
|
- case DEVICE_ID_QUATECH_RS232_16_PORT_D:
|
|
|
- DeviceData.porta &= ~(RR_BITS | DUPMODE_BITS);
|
|
|
- DeviceData.porta |= CLKS_X4;
|
|
|
- DeviceData.portb &= ~(LOOPMODE_BITS);
|
|
|
- DeviceData.portb |= RS232_MODE;
|
|
|
- break;
|
|
|
-
|
|
|
-
|
|
|
- case DEVICE_ID_QUATECH_RS422_SINGLE_PORT:
|
|
|
- case DEVICE_ID_QUATECH_RS422_DUAL_PORT:
|
|
|
- case DEVICE_ID_QUATECH_RS422_FOUR_PORT:
|
|
|
- case DEVICE_ID_QUATECH_RS422_EIGHT_PORT_A:
|
|
|
- case DEVICE_ID_QUATECH_RS422_EIGHT_PORT_B:
|
|
|
- case DEVICE_ID_QUATECH_RS422_16_PORT_A:
|
|
|
- case DEVICE_ID_QUATECH_RS422_16_PORT_B:
|
|
|
- case DEVICE_ID_QUATECH_RS422_16_PORT_C:
|
|
|
- case DEVICE_ID_QUATECH_RS422_16_PORT_D:
|
|
|
- DeviceData.porta &= ~(RR_BITS | DUPMODE_BITS);
|
|
|
- DeviceData.porta |= CLKS_X4;
|
|
|
- DeviceData.portb &= ~(LOOPMODE_BITS);
|
|
|
- DeviceData.portb |= ALL_LOOPBACK;
|
|
|
- break;
|
|
|
- default:
|
|
|
- DeviceData.porta &= ~(RR_BITS | DUPMODE_BITS);
|
|
|
- DeviceData.porta |= CLKS_X4;
|
|
|
- DeviceData.portb &= ~(LOOPMODE_BITS);
|
|
|
- DeviceData.portb |= RS232_MODE;
|
|
|
- break;
|
|
|
-
|
|
|
- }
|
|
|
- status = BoxSetPrebufferLevel(serial); //sets to default vaue
|
|
|
- if (status < 0)
|
|
|
- {
|
|
|
- mydbg(__FILE__"BoxSetPrebufferLevel failed\n");
|
|
|
- goto probe_error;
|
|
|
- }
|
|
|
-
|
|
|
- status = BoxSetATC(serial, ATC_DISABLED);
|
|
|
- if (status < 0)
|
|
|
- {
|
|
|
- mydbg(__FILE__"BoxSetATC failed\n");
|
|
|
- goto probe_error;
|
|
|
- }
|
|
|
- //****************************************************************************
|
|
|
- mydbg(__FILE__"DeviceData.portb = 0x%x",DeviceData.portb);
|
|
|
-
|
|
|
- DeviceData.portb |= NEXT_BOARD_POWER_BIT;
|
|
|
- mydbg(__FILE__"Changing DeviceData.portb to 0x%x",DeviceData.portb);
|
|
|
-
|
|
|
- status = box_set_device(serial, &DeviceData);
|
|
|
- if (status < 0)
|
|
|
- {
|
|
|
- mydbg(__FILE__"box_set_device failed\n");
|
|
|
- goto probe_error;
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
- mydbg("Exit Success %s\n", __FUNCTION__);
|
|
|
-
|
|
|
- usb_set_intfdata (interface, serial);
|
|
|
- return 0;
|
|
|
+ ///***********TAG add start next board here ****///
|
|
|
+ status = box_get_device(serial, &DeviceData);
|
|
|
+ if (status < 0) {
|
|
|
+ mydbg(__FILE__ "box_get_device failed");
|
|
|
+ goto probe_error;
|
|
|
+ }
|
|
|
+ //*****************and before we power up lets initialiaze parnent device stuff here before
|
|
|
+ //*****************we set thmem via any other method such as the property pages
|
|
|
+ switch (serial->product) {
|
|
|
+ case DEVICE_ID_QUATECH_RS232_SINGLE_PORT:
|
|
|
+ case DEVICE_ID_QUATECH_RS232_DUAL_PORT:
|
|
|
+ case DEVICE_ID_QUATECH_RS232_FOUR_PORT:
|
|
|
+ case DEVICE_ID_QUATECH_RS232_EIGHT_PORT_A:
|
|
|
+ case DEVICE_ID_QUATECH_RS232_EIGHT_PORT_B:
|
|
|
+ case DEVICE_ID_QUATECH_RS232_16_PORT_A:
|
|
|
+ case DEVICE_ID_QUATECH_RS232_16_PORT_B:
|
|
|
+ case DEVICE_ID_QUATECH_RS232_16_PORT_C:
|
|
|
+ case DEVICE_ID_QUATECH_RS232_16_PORT_D:
|
|
|
+ DeviceData.porta &= ~(RR_BITS | DUPMODE_BITS);
|
|
|
+ DeviceData.porta |= CLKS_X4;
|
|
|
+ DeviceData.portb &= ~(LOOPMODE_BITS);
|
|
|
+ DeviceData.portb |= RS232_MODE;
|
|
|
+ break;
|
|
|
+
|
|
|
+ case DEVICE_ID_QUATECH_RS422_SINGLE_PORT:
|
|
|
+ case DEVICE_ID_QUATECH_RS422_DUAL_PORT:
|
|
|
+ case DEVICE_ID_QUATECH_RS422_FOUR_PORT:
|
|
|
+ case DEVICE_ID_QUATECH_RS422_EIGHT_PORT_A:
|
|
|
+ case DEVICE_ID_QUATECH_RS422_EIGHT_PORT_B:
|
|
|
+ case DEVICE_ID_QUATECH_RS422_16_PORT_A:
|
|
|
+ case DEVICE_ID_QUATECH_RS422_16_PORT_B:
|
|
|
+ case DEVICE_ID_QUATECH_RS422_16_PORT_C:
|
|
|
+ case DEVICE_ID_QUATECH_RS422_16_PORT_D:
|
|
|
+ DeviceData.porta &= ~(RR_BITS | DUPMODE_BITS);
|
|
|
+ DeviceData.porta |= CLKS_X4;
|
|
|
+ DeviceData.portb &= ~(LOOPMODE_BITS);
|
|
|
+ DeviceData.portb |= ALL_LOOPBACK;
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ DeviceData.porta &= ~(RR_BITS | DUPMODE_BITS);
|
|
|
+ DeviceData.porta |= CLKS_X4;
|
|
|
+ DeviceData.portb &= ~(LOOPMODE_BITS);
|
|
|
+ DeviceData.portb |= RS232_MODE;
|
|
|
+ break;
|
|
|
|
|
|
+ }
|
|
|
+ status = BoxSetPrebufferLevel(serial); //sets to default vaue
|
|
|
+ if (status < 0) {
|
|
|
+ mydbg(__FILE__ "BoxSetPrebufferLevel failed\n");
|
|
|
+ goto probe_error;
|
|
|
+ }
|
|
|
|
|
|
+ status = BoxSetATC(serial, ATC_DISABLED);
|
|
|
+ if (status < 0) {
|
|
|
+ mydbg(__FILE__ "BoxSetATC failed\n");
|
|
|
+ goto probe_error;
|
|
|
+ }
|
|
|
+ //****************************************************************************
|
|
|
+ mydbg(__FILE__ "DeviceData.portb = 0x%x", DeviceData.portb);
|
|
|
|
|
|
- probe_error:
|
|
|
-
|
|
|
- for (i = 0; i < num_bulk_in; ++i)
|
|
|
- {
|
|
|
- port = &serial->port[i];
|
|
|
- if (port->read_urb)
|
|
|
- usb_free_urb (port->read_urb);
|
|
|
- if (port->bulk_in_buffer)
|
|
|
- kfree (port->bulk_in_buffer);
|
|
|
- }
|
|
|
- for (i = 0; i < num_bulk_out; ++i)
|
|
|
- {
|
|
|
- port = &serial->port[i];
|
|
|
- if (port->write_urb)
|
|
|
- usb_free_urb (port->write_urb);
|
|
|
- if (port->bulk_out_buffer)
|
|
|
- kfree (port->bulk_out_buffer);
|
|
|
-
|
|
|
- if (port->xfer_to_tty_buffer)
|
|
|
- kfree (port->xfer_to_tty_buffer);
|
|
|
- }
|
|
|
- for (i = 0; i < num_interrupt_in; ++i)
|
|
|
- {
|
|
|
- port = &serial->port[i];
|
|
|
- if (port->interrupt_in_urb)
|
|
|
- usb_free_urb (port->interrupt_in_urb);
|
|
|
- if (port->interrupt_in_buffer)
|
|
|
- kfree (port->interrupt_in_buffer);
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
- /* return the minor range that this device had */
|
|
|
- return_serial (serial);
|
|
|
- mydbg("Exit fail %s\n", __FUNCTION__);
|
|
|
-
|
|
|
- /* free up any memory that we allocated */
|
|
|
- kfree (serial);
|
|
|
- return -EIO;
|
|
|
-}
|
|
|
+ DeviceData.portb |= NEXT_BOARD_POWER_BIT;
|
|
|
+ mydbg(__FILE__ "Changing DeviceData.portb to 0x%x", DeviceData.portb);
|
|
|
+
|
|
|
+ status = box_set_device(serial, &DeviceData);
|
|
|
+ if (status < 0) {
|
|
|
+ mydbg(__FILE__ "box_set_device failed\n");
|
|
|
+ goto probe_error;
|
|
|
+ }
|
|
|
|
|
|
+ mydbg("Exit Success %s\n", __FUNCTION__);
|
|
|
|
|
|
+ usb_set_intfdata(interface, serial);
|
|
|
+ return 0;
|
|
|
|
|
|
+probe_error:
|
|
|
+
|
|
|
+ for (i = 0; i < num_bulk_in; ++i) {
|
|
|
+ port = &serial->port[i];
|
|
|
+ if (port->read_urb)
|
|
|
+ usb_free_urb(port->read_urb);
|
|
|
+ if (port->bulk_in_buffer)
|
|
|
+ kfree(port->bulk_in_buffer);
|
|
|
+ }
|
|
|
+ for (i = 0; i < num_bulk_out; ++i) {
|
|
|
+ port = &serial->port[i];
|
|
|
+ if (port->write_urb)
|
|
|
+ usb_free_urb(port->write_urb);
|
|
|
+ if (port->bulk_out_buffer)
|
|
|
+ kfree(port->bulk_out_buffer);
|
|
|
+
|
|
|
+ if (port->xfer_to_tty_buffer)
|
|
|
+ kfree(port->xfer_to_tty_buffer);
|
|
|
+ }
|
|
|
+ for (i = 0; i < num_interrupt_in; ++i) {
|
|
|
+ port = &serial->port[i];
|
|
|
+ if (port->interrupt_in_urb)
|
|
|
+ usb_free_urb(port->interrupt_in_urb);
|
|
|
+ if (port->interrupt_in_buffer)
|
|
|
+ kfree(port->interrupt_in_buffer);
|
|
|
+ }
|
|
|
|
|
|
+ /* return the minor range that this device had */
|
|
|
+ return_serial(serial);
|
|
|
+ mydbg("Exit fail %s\n", __FUNCTION__);
|
|
|
|
|
|
+ /* free up any memory that we allocated */
|
|
|
+ kfree(serial);
|
|
|
+ return -EIO;
|
|
|
+}
|
|
|
|
|
|
//returns the serial_table array pointers that are taken
|
|
|
//up in consecutive positions for each port to a common usb_serial structure
|
|
|
//back to NULL
|
|
|
static void return_serial(struct usb_serial *serial)
|
|
|
{
|
|
|
- int i;
|
|
|
+ int i;
|
|
|
|
|
|
- mydbg("%s\n", __FUNCTION__);
|
|
|
+ mydbg("%s\n", __FUNCTION__);
|
|
|
|
|
|
- if (serial == NULL)
|
|
|
- return;
|
|
|
+ if (serial == NULL)
|
|
|
+ return;
|
|
|
|
|
|
- for (i = 0; i < serial->num_ports; ++i)
|
|
|
- {
|
|
|
- serial_table[serial->minor + i] = NULL;
|
|
|
- }
|
|
|
+ for (i = 0; i < serial->num_ports; ++i) {
|
|
|
+ serial_table[serial->minor + i] = NULL;
|
|
|
+ }
|
|
|
|
|
|
- return;
|
|
|
+ return;
|
|
|
}
|
|
|
|
|
|
//Finds the first locatio int the serial_table array where it can fit
|
|
@@ -820,808 +779,748 @@ static void return_serial(struct usb_serial *serial)
|
|
|
//,allocates a stucture points to it in all the structures, and returns the index
|
|
|
//to the first location in the array in the "minor" variable.
|
|
|
|
|
|
-static struct usb_serial *get_free_serial (int num_ports, int *minor)
|
|
|
+static struct usb_serial *get_free_serial(int num_ports, int *minor)
|
|
|
{
|
|
|
- struct usb_serial *serial = NULL;
|
|
|
- int i, j;
|
|
|
- int good_spot;
|
|
|
-
|
|
|
- mydbg("%s %d\n", __FUNCTION__, num_ports);
|
|
|
-
|
|
|
- *minor = 0;
|
|
|
- for (i = 0; i < SERIAL_TTY_MINORS; ++i)
|
|
|
- {
|
|
|
- if (serial_table[i])
|
|
|
- continue;
|
|
|
-
|
|
|
- good_spot = 1;
|
|
|
- //find a spot in the array where you can fit consecutive positions
|
|
|
- //to put the pointers to the usb_serail allocated structure for all
|
|
|
- //the minor numbers (ie. ports)
|
|
|
- for (j = 1; j <= num_ports-1; ++j)
|
|
|
- if (serial_table[i+j])
|
|
|
- good_spot = 0;
|
|
|
- if (good_spot == 0)
|
|
|
- continue;
|
|
|
-
|
|
|
- if (!(serial = kmalloc(sizeof(struct usb_serial), GFP_KERNEL)))
|
|
|
- {
|
|
|
- err("%s - Out of memory", __FUNCTION__);
|
|
|
- return NULL;
|
|
|
- }
|
|
|
- memset(serial, 0, sizeof(struct usb_serial));
|
|
|
- serial_table[i] = serial;
|
|
|
- *minor = i;
|
|
|
- mydbg("%s - minor base = %d\n", __FUNCTION__, *minor);
|
|
|
- //copy in the pointer into the array starting a the *minor position
|
|
|
- //*minor is the index into the array
|
|
|
- for (i = *minor+1; (i < (*minor + num_ports)) && (i < SERIAL_TTY_MINORS); ++i)
|
|
|
- serial_table[i] = serial;
|
|
|
- return serial;
|
|
|
- }
|
|
|
- return NULL;
|
|
|
+ struct usb_serial *serial = NULL;
|
|
|
+ int i, j;
|
|
|
+ int good_spot;
|
|
|
+
|
|
|
+ mydbg("%s %d\n", __FUNCTION__, num_ports);
|
|
|
+
|
|
|
+ *minor = 0;
|
|
|
+ for (i = 0; i < SERIAL_TTY_MINORS; ++i) {
|
|
|
+ if (serial_table[i])
|
|
|
+ continue;
|
|
|
+
|
|
|
+ good_spot = 1;
|
|
|
+ //find a spot in the array where you can fit consecutive positions
|
|
|
+ //to put the pointers to the usb_serail allocated structure for all
|
|
|
+ //the minor numbers (ie. ports)
|
|
|
+ for (j = 1; j <= num_ports - 1; ++j)
|
|
|
+ if (serial_table[i + j])
|
|
|
+ good_spot = 0;
|
|
|
+ if (good_spot == 0)
|
|
|
+ continue;
|
|
|
+
|
|
|
+ if (!(serial = kmalloc(sizeof(struct usb_serial), GFP_KERNEL))) {
|
|
|
+ err("%s - Out of memory", __FUNCTION__);
|
|
|
+ return NULL;
|
|
|
+ }
|
|
|
+ memset(serial, 0, sizeof(struct usb_serial));
|
|
|
+ serial_table[i] = serial;
|
|
|
+ *minor = i;
|
|
|
+ mydbg("%s - minor base = %d\n", __FUNCTION__, *minor);
|
|
|
+ //copy in the pointer into the array starting a the *minor position
|
|
|
+ //*minor is the index into the array
|
|
|
+ for (i = *minor + 1;
|
|
|
+ (i < (*minor + num_ports)) && (i < SERIAL_TTY_MINORS); ++i)
|
|
|
+ serial_table[i] = serial;
|
|
|
+ return serial;
|
|
|
+ }
|
|
|
+ return NULL;
|
|
|
}
|
|
|
|
|
|
-static int flip_that( struct tty_struct *tty, __u16 UartNumber, struct usb_serial *serial)
|
|
|
+static int flip_that(struct tty_struct *tty, __u16 UartNumber,
|
|
|
+ struct usb_serial *serial)
|
|
|
{
|
|
|
- tty_flip_buffer_push(tty);
|
|
|
- tty_schedule_flip(tty);
|
|
|
- return 0;
|
|
|
+ tty_flip_buffer_push(tty);
|
|
|
+ tty_schedule_flip(tty);
|
|
|
+ return 0;
|
|
|
}
|
|
|
|
|
|
//Handles processing and moving data to the tty layer
|
|
|
static void port_sofrint(void *private)
|
|
|
{
|
|
|
- struct usb_serial_port *port = (struct usb_serial_port *)private;
|
|
|
- struct usb_serial *serial = get_usb_serial (port, __FUNCTION__);
|
|
|
- struct tty_struct *tty = port->tty;
|
|
|
- unsigned char *data = port->read_urb->transfer_buffer;
|
|
|
- unsigned int UartNumber;
|
|
|
- struct urb *urb = port->read_urb;
|
|
|
- unsigned int RxCount = urb->actual_length;
|
|
|
- int i, result;
|
|
|
- int flag, flag_data;
|
|
|
-
|
|
|
- //UartNumber = MINOR(port->tty->device) - serial->minor;
|
|
|
- UartNumber = tty->index - serial->minor;
|
|
|
-
|
|
|
- mydbg("%s - port %d\n", __FUNCTION__, port->number);
|
|
|
- mydbg ("%s - port->RxHolding = %d\n", __FUNCTION__, port->RxHolding);
|
|
|
-
|
|
|
- if (port_paranoia_check (port, __FUNCTION__) != 0) {
|
|
|
- mydbg("%s - port_paranoia_check, exiting\n", __FUNCTION__);
|
|
|
- port->ReadBulkStopped = 1;
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
- if (!serial) {
|
|
|
- mydbg("%s - bad serial pointer, exiting\n", __FUNCTION__);
|
|
|
- return;
|
|
|
- }
|
|
|
- if (port->closePending == 1) //Were closing , stop reading
|
|
|
- {
|
|
|
- mydbg("%s - (port->closepending == 1\n", __FUNCTION__);
|
|
|
- port->ReadBulkStopped = 1;
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
- //RxHolding is asserted by throttle, if we assert it, we're not receiving any more
|
|
|
- //characters and let the box handle the flow control
|
|
|
- if (port->RxHolding == 1) {
|
|
|
- port->ReadBulkStopped = 1;
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
- if (urb->status) {
|
|
|
- port->ReadBulkStopped = 1;
|
|
|
-
|
|
|
- mydbg("%s - nonzero read bulk status received: %d\n", __FUNCTION__, urb->status);
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
- tty = port->tty;
|
|
|
- mydbg("%s - port %d, tty =0x%p\n", __FUNCTION__, port->number, tty);
|
|
|
-
|
|
|
-
|
|
|
- if (tty && RxCount) {
|
|
|
- flag_data = 0;
|
|
|
- for (i = 0; i < RxCount ; ++i) {
|
|
|
- //Look ahead code here
|
|
|
-
|
|
|
- if ((i <= (RxCount - 3)) && (THISCHAR == 0x1b) && (NEXTCHAR == 0x1b)) {
|
|
|
- flag = 0;
|
|
|
- switch (THIRDCHAR) {
|
|
|
- case 0x00:
|
|
|
- //Line status change 4th byte must follow
|
|
|
- if (i > (RxCount - 4)) {
|
|
|
- mydbg("Illegal escape sequences in received data\n");
|
|
|
- break;
|
|
|
- }
|
|
|
- ProcessLineStatus(port, FOURTHCHAR);
|
|
|
- i += 3;
|
|
|
- flag = 1;
|
|
|
- break;
|
|
|
-
|
|
|
- case 0x01:
|
|
|
- //Modem status status change 4th byte must follow
|
|
|
- mydbg("Modem status status. \n");
|
|
|
-
|
|
|
- if (i > (RxCount - 4)) {
|
|
|
- mydbg("Illegal escape sequences in received data\n");
|
|
|
- break;
|
|
|
- }
|
|
|
- ProcessModemStatus(port, FOURTHCHAR);
|
|
|
- i += 3;
|
|
|
- flag = 1;
|
|
|
- break;
|
|
|
- case 0xff:
|
|
|
- mydbg("No status sequence. \n");
|
|
|
-
|
|
|
- ProcessRxChar(port, THISCHAR);
|
|
|
- ProcessRxChar(port, NEXTCHAR);
|
|
|
- i += 2;
|
|
|
- break;
|
|
|
-
|
|
|
- }//end switch
|
|
|
- if (flag == 1)
|
|
|
- continue;
|
|
|
- } //endif
|
|
|
-
|
|
|
- if(tty && urb->actual_length) {
|
|
|
- tty_buffer_request_room(tty, 1);
|
|
|
- tty_insert_flip_string(tty, (data + i), 1);
|
|
|
- }
|
|
|
-
|
|
|
+ struct usb_serial_port *port = (struct usb_serial_port *)private;
|
|
|
+ struct usb_serial *serial = get_usb_serial(port, __FUNCTION__);
|
|
|
+ struct tty_struct *tty = port->tty;
|
|
|
+ unsigned char *data = port->read_urb->transfer_buffer;
|
|
|
+ unsigned int UartNumber;
|
|
|
+ struct urb *urb = port->read_urb;
|
|
|
+ unsigned int RxCount = urb->actual_length;
|
|
|
+ int i, result;
|
|
|
+ int flag, flag_data;
|
|
|
|
|
|
- }//endfor
|
|
|
+ //UartNumber = MINOR(port->tty->device) - serial->minor;
|
|
|
+ UartNumber = tty->index - serial->minor;
|
|
|
|
|
|
- tty_flip_buffer_push(tty);
|
|
|
+ mydbg("%s - port %d\n", __FUNCTION__, port->number);
|
|
|
+ mydbg("%s - port->RxHolding = %d\n", __FUNCTION__, port->RxHolding);
|
|
|
|
|
|
- }//endif
|
|
|
+ if (port_paranoia_check(port, __FUNCTION__) != 0) {
|
|
|
+ mydbg("%s - port_paranoia_check, exiting\n", __FUNCTION__);
|
|
|
+ port->ReadBulkStopped = 1;
|
|
|
+ return;
|
|
|
+ }
|
|
|
|
|
|
- /* Continue trying to always read */
|
|
|
- usb_fill_bulk_urb (port->read_urb, serial->dev,
|
|
|
- usb_rcvbulkpipe (serial->dev,
|
|
|
- port->bulk_in_endpointAddress),
|
|
|
- port->read_urb->transfer_buffer,
|
|
|
- port->read_urb->transfer_buffer_length,
|
|
|
- qt_read_bulk_callback, port);
|
|
|
- result = usb_submit_urb(port->read_urb, GFP_ATOMIC);
|
|
|
- if (result)
|
|
|
- mydbg("%s - failed resubmitting read urb, error %d", __FUNCTION__, result);
|
|
|
- else
|
|
|
- {
|
|
|
- if (tty && RxCount)
|
|
|
- flip_that(tty, UartNumber, serial);
|
|
|
- }
|
|
|
+ if (!serial) {
|
|
|
+ mydbg("%s - bad serial pointer, exiting\n", __FUNCTION__);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ if (port->closePending == 1) //Were closing , stop reading
|
|
|
+ {
|
|
|
+ mydbg("%s - (port->closepending == 1\n", __FUNCTION__);
|
|
|
+ port->ReadBulkStopped = 1;
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ //RxHolding is asserted by throttle, if we assert it, we're not receiving any more
|
|
|
+ //characters and let the box handle the flow control
|
|
|
+ if (port->RxHolding == 1) {
|
|
|
+ port->ReadBulkStopped = 1;
|
|
|
+ return;
|
|
|
+ }
|
|
|
|
|
|
+ if (urb->status) {
|
|
|
+ port->ReadBulkStopped = 1;
|
|
|
|
|
|
- return;
|
|
|
+ mydbg("%s - nonzero read bulk status received: %d\n",
|
|
|
+ __FUNCTION__, urb->status);
|
|
|
+ return;
|
|
|
+ }
|
|
|
|
|
|
- }
|
|
|
+ tty = port->tty;
|
|
|
+ mydbg("%s - port %d, tty =0x%p\n", __FUNCTION__, port->number, tty);
|
|
|
+
|
|
|
+ if (tty && RxCount) {
|
|
|
+ flag_data = 0;
|
|
|
+ for (i = 0; i < RxCount; ++i) {
|
|
|
+ //Look ahead code here
|
|
|
+
|
|
|
+ if ((i <= (RxCount - 3)) && (THISCHAR == 0x1b)
|
|
|
+ && (NEXTCHAR == 0x1b)) {
|
|
|
+ flag = 0;
|
|
|
+ switch (THIRDCHAR) {
|
|
|
+ case 0x00:
|
|
|
+ //Line status change 4th byte must follow
|
|
|
+ if (i > (RxCount - 4)) {
|
|
|
+ mydbg
|
|
|
+ ("Illegal escape sequences in received data\n");
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ ProcessLineStatus(port, FOURTHCHAR);
|
|
|
+ i += 3;
|
|
|
+ flag = 1;
|
|
|
+ break;
|
|
|
+
|
|
|
+ case 0x01:
|
|
|
+ //Modem status status change 4th byte must follow
|
|
|
+ mydbg("Modem status status. \n");
|
|
|
+
|
|
|
+ if (i > (RxCount - 4)) {
|
|
|
+ mydbg
|
|
|
+ ("Illegal escape sequences in received data\n");
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ ProcessModemStatus(port, FOURTHCHAR);
|
|
|
+ i += 3;
|
|
|
+ flag = 1;
|
|
|
+ break;
|
|
|
+ case 0xff:
|
|
|
+ mydbg("No status sequence. \n");
|
|
|
+
|
|
|
+ ProcessRxChar(port, THISCHAR);
|
|
|
+ ProcessRxChar(port, NEXTCHAR);
|
|
|
+ i += 2;
|
|
|
+ break;
|
|
|
+
|
|
|
+ } //end switch
|
|
|
+ if (flag == 1)
|
|
|
+ continue;
|
|
|
+ } //endif
|
|
|
+
|
|
|
+ if (tty && urb->actual_length) {
|
|
|
+ tty_buffer_request_room(tty, 1);
|
|
|
+ tty_insert_flip_string(tty, (data + i), 1);
|
|
|
+ }
|
|
|
+
|
|
|
+ } //endfor
|
|
|
+
|
|
|
+ tty_flip_buffer_push(tty);
|
|
|
+
|
|
|
+ } //endif
|
|
|
+
|
|
|
+ /* Continue trying to always read */
|
|
|
+ usb_fill_bulk_urb(port->read_urb, serial->dev,
|
|
|
+ usb_rcvbulkpipe(serial->dev,
|
|
|
+ port->bulk_in_endpointAddress),
|
|
|
+ port->read_urb->transfer_buffer,
|
|
|
+ port->read_urb->transfer_buffer_length,
|
|
|
+ qt_read_bulk_callback, port);
|
|
|
+ result = usb_submit_urb(port->read_urb, GFP_ATOMIC);
|
|
|
+ if (result)
|
|
|
+ mydbg("%s - failed resubmitting read urb, error %d",
|
|
|
+ __FUNCTION__, result);
|
|
|
+ else {
|
|
|
+ if (tty && RxCount)
|
|
|
+ flip_that(tty, UartNumber, serial);
|
|
|
+ }
|
|
|
|
|
|
+ return;
|
|
|
|
|
|
+}
|
|
|
|
|
|
static void qt_read_bulk_callback(struct urb *urb)
|
|
|
{
|
|
|
|
|
|
- struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
|
|
|
+ struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
|
|
|
|
|
|
+ if (urb->status) {
|
|
|
|
|
|
- if (urb->status)
|
|
|
- {
|
|
|
-
|
|
|
- port->ReadBulkStopped = 1;
|
|
|
- mydbg("%s - nonzero write bulk status received: %d\n", __FUNCTION__, urb->status);
|
|
|
- return;
|
|
|
- }
|
|
|
+ port->ReadBulkStopped = 1;
|
|
|
+ mydbg("%s - nonzero write bulk status received: %d\n",
|
|
|
+ __FUNCTION__, urb->status);
|
|
|
+ return;
|
|
|
+ }
|
|
|
|
|
|
- port_sofrint((void *) port);
|
|
|
- schedule_work(&port->work);
|
|
|
+ port_sofrint((void *)port);
|
|
|
+ schedule_work(&port->work);
|
|
|
}
|
|
|
|
|
|
+static void ProcessRxChar(struct usb_serial_port *port, unsigned char Data)
|
|
|
+{
|
|
|
+ struct tty_struct *tty;
|
|
|
+ struct urb *urb = port->read_urb;
|
|
|
+ tty = port->tty;
|
|
|
+ /* if we insert more than TTY_FLIPBUF_SIZE characters, we drop them. */
|
|
|
|
|
|
-static void ProcessRxChar(struct usb_serial_port *port, unsigned char Data){
|
|
|
- struct tty_struct *tty;
|
|
|
- struct urb *urb = port->read_urb;
|
|
|
- tty = port->tty;
|
|
|
- /* if we insert more than TTY_FLIPBUF_SIZE characters, we drop them. */
|
|
|
-
|
|
|
- if(tty && urb->actual_length)
|
|
|
- {
|
|
|
+ if (tty && urb->actual_length) {
|
|
|
tty_buffer_request_room(tty, 1);
|
|
|
tty_insert_flip_string(tty, &Data, 1);
|
|
|
//tty_flip_buffer_push(tty);
|
|
|
|
|
|
-
|
|
|
}
|
|
|
|
|
|
- return;
|
|
|
+ return;
|
|
|
}
|
|
|
|
|
|
-static void ProcessLineStatus(struct usb_serial_port *port, unsigned char line_status){
|
|
|
+static void ProcessLineStatus(struct usb_serial_port *port,
|
|
|
+ unsigned char line_status)
|
|
|
+{
|
|
|
|
|
|
- port->shadowLSR = line_status & (SERIAL_LSR_OE | SERIAL_LSR_PE | SERIAL_LSR_FE |
|
|
|
- SERIAL_LSR_BI);
|
|
|
- return;
|
|
|
+ port->shadowLSR =
|
|
|
+ line_status & (SERIAL_LSR_OE | SERIAL_LSR_PE | SERIAL_LSR_FE |
|
|
|
+ SERIAL_LSR_BI);
|
|
|
+ return;
|
|
|
}
|
|
|
|
|
|
+static void ProcessModemStatus(struct usb_serial_port *port,
|
|
|
+ unsigned char modem_status)
|
|
|
+{
|
|
|
|
|
|
-static void ProcessModemStatus(struct usb_serial_port *port, unsigned char modem_status){
|
|
|
-
|
|
|
- port->shadowMSR = modem_status;
|
|
|
- wake_up_interruptible(&port->wait);
|
|
|
- return;
|
|
|
+ port->shadowMSR = modem_status;
|
|
|
+ wake_up_interruptible(&port->wait);
|
|
|
+ return;
|
|
|
}
|
|
|
|
|
|
+static void serqt_usb_disconnect(struct usb_interface *interface)
|
|
|
+{
|
|
|
+ struct usb_serial *serial = usb_get_intfdata(interface);
|
|
|
+ //struct device *dev = &interface->dev;
|
|
|
+ struct usb_serial_port *port;
|
|
|
+ int i;
|
|
|
|
|
|
+ mydbg("%s\n", __FUNCTION__);
|
|
|
+ if (serial) {
|
|
|
|
|
|
+ serial->dev = NULL;
|
|
|
|
|
|
+ for (i = 0; i < serial->num_ports; ++i)
|
|
|
+ serial->port[i].open_count = 0;
|
|
|
|
|
|
+ for (i = 0; i < serial->num_bulk_in; ++i) {
|
|
|
+ port = &serial->port[i];
|
|
|
+ if (port->read_urb) {
|
|
|
+ usb_unlink_urb(port->read_urb);
|
|
|
+ usb_free_urb(port->read_urb);
|
|
|
+ }
|
|
|
+ if (port->bulk_in_buffer)
|
|
|
+ kfree(port->bulk_in_buffer);
|
|
|
+ }
|
|
|
+ for (i = 0; i < serial->num_bulk_out; ++i) {
|
|
|
+ port = &serial->port[i];
|
|
|
+ if (port->write_urb) {
|
|
|
+ usb_unlink_urb(port->write_urb);
|
|
|
+ usb_free_urb(port->write_urb);
|
|
|
+ }
|
|
|
+ if (port->bulk_out_buffer)
|
|
|
+ kfree(port->bulk_out_buffer);
|
|
|
+ }
|
|
|
+ for (i = 0; i < serial->num_interrupt_in; ++i) {
|
|
|
+ port = &serial->port[i];
|
|
|
+ if (port->interrupt_in_urb) {
|
|
|
+ usb_unlink_urb(port->interrupt_in_urb);
|
|
|
+ usb_free_urb(port->interrupt_in_urb);
|
|
|
+ }
|
|
|
+ if (port->interrupt_in_buffer)
|
|
|
+ kfree(port->interrupt_in_buffer);
|
|
|
+ }
|
|
|
|
|
|
-static void serqt_usb_disconnect(struct usb_interface *interface){
|
|
|
- struct usb_serial *serial = usb_get_intfdata (interface);
|
|
|
- //struct device *dev = &interface->dev;
|
|
|
- struct usb_serial_port *port;
|
|
|
- int i;
|
|
|
-
|
|
|
- mydbg ("%s\n", __FUNCTION__);
|
|
|
- if (serial)
|
|
|
- {
|
|
|
-
|
|
|
- serial->dev = NULL;
|
|
|
-
|
|
|
- for (i = 0; i < serial->num_ports; ++i)
|
|
|
- serial->port[i].open_count = 0;
|
|
|
-
|
|
|
- for (i = 0; i < serial->num_bulk_in; ++i)
|
|
|
- {
|
|
|
- port = &serial->port[i];
|
|
|
- if (port->read_urb)
|
|
|
- {
|
|
|
- usb_unlink_urb (port->read_urb);
|
|
|
- usb_free_urb (port->read_urb);
|
|
|
- }
|
|
|
- if (port->bulk_in_buffer)
|
|
|
- kfree (port->bulk_in_buffer);
|
|
|
- }
|
|
|
- for (i = 0; i < serial->num_bulk_out; ++i)
|
|
|
- {
|
|
|
- port = &serial->port[i];
|
|
|
- if (port->write_urb)
|
|
|
- {
|
|
|
- usb_unlink_urb (port->write_urb);
|
|
|
- usb_free_urb (port->write_urb);
|
|
|
- }
|
|
|
- if (port->bulk_out_buffer)
|
|
|
- kfree (port->bulk_out_buffer);
|
|
|
- }
|
|
|
- for (i = 0; i < serial->num_interrupt_in; ++i)
|
|
|
- {
|
|
|
- port = &serial->port[i];
|
|
|
- if (port->interrupt_in_urb)
|
|
|
- {
|
|
|
- usb_unlink_urb (port->interrupt_in_urb);
|
|
|
- usb_free_urb (port->interrupt_in_urb);
|
|
|
- }
|
|
|
- if (port->interrupt_in_buffer)
|
|
|
- kfree (port->interrupt_in_buffer);
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
- /* return the minor range that this device had */
|
|
|
- return_serial (serial);
|
|
|
-
|
|
|
- /* free up any memory that we allocated */
|
|
|
- kfree (serial);
|
|
|
-
|
|
|
-
|
|
|
+ /* return the minor range that this device had */
|
|
|
+ return_serial(serial);
|
|
|
|
|
|
- } else
|
|
|
- {
|
|
|
- dev_info(&interface->dev, "device disconnected");
|
|
|
- }
|
|
|
+ /* free up any memory that we allocated */
|
|
|
+ kfree(serial);
|
|
|
|
|
|
+ } else {
|
|
|
+ dev_info(&interface->dev, "device disconnected");
|
|
|
+ }
|
|
|
|
|
|
}
|
|
|
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-static struct usb_serial *get_serial_by_minor (unsigned int minor)
|
|
|
+static struct usb_serial *get_serial_by_minor(unsigned int minor)
|
|
|
{
|
|
|
- return serial_table[minor];
|
|
|
+ return serial_table[minor];
|
|
|
}
|
|
|
|
|
|
/*****************************************************************************
|
|
|
* Driver tty interface functions
|
|
|
*****************************************************************************/
|
|
|
-static int serial_open (struct tty_struct *tty, struct file * filp){
|
|
|
- struct usb_serial *serial;
|
|
|
- struct usb_serial_port *port;
|
|
|
- unsigned int portNumber;
|
|
|
- int retval = 0;
|
|
|
+static int serial_open(struct tty_struct *tty, struct file *filp)
|
|
|
+{
|
|
|
+ struct usb_serial *serial;
|
|
|
+ struct usb_serial_port *port;
|
|
|
+ unsigned int portNumber;
|
|
|
+ int retval = 0;
|
|
|
|
|
|
- mydbg("%s\n", __FUNCTION__);
|
|
|
+ mydbg("%s\n", __FUNCTION__);
|
|
|
|
|
|
- /* initialize the pointer incase something fails */
|
|
|
- tty->driver_data = NULL;
|
|
|
+ /* initialize the pointer incase something fails */
|
|
|
+ tty->driver_data = NULL;
|
|
|
|
|
|
- /* get the serial object associated with this tty pointer */
|
|
|
- //serial = get_serial_by_minor (MINOR(tty->device));
|
|
|
+ /* get the serial object associated with this tty pointer */
|
|
|
+ //serial = get_serial_by_minor (MINOR(tty->device));
|
|
|
|
|
|
- /* get the serial object associated with this tty pointer */
|
|
|
+ /* get the serial object associated with this tty pointer */
|
|
|
serial = get_serial_by_minor(tty->index);
|
|
|
|
|
|
+ if (serial_paranoia_check(serial, __FUNCTION__))
|
|
|
+ return -ENODEV;
|
|
|
|
|
|
- if (serial_paranoia_check (serial, __FUNCTION__))
|
|
|
- return -ENODEV;
|
|
|
-
|
|
|
-
|
|
|
- /* set up our port structure making the tty driver remember our port object, and us it */
|
|
|
- portNumber = tty->index - serial->minor;
|
|
|
- port = &serial->port[portNumber];
|
|
|
- tty->driver_data = port;
|
|
|
-
|
|
|
- down (&port->sem);
|
|
|
- port->tty = tty;
|
|
|
+ /* set up our port structure making the tty driver remember our port object, and us it */
|
|
|
+ portNumber = tty->index - serial->minor;
|
|
|
+ port = &serial->port[portNumber];
|
|
|
+ tty->driver_data = port;
|
|
|
|
|
|
+ down(&port->sem);
|
|
|
+ port->tty = tty;
|
|
|
|
|
|
- ++port->open_count;
|
|
|
- if (port->open_count == 1)
|
|
|
- {
|
|
|
- port->closePending = 0;
|
|
|
- mydbg("%s port->closepending = 0\n", __FUNCTION__);
|
|
|
+ ++port->open_count;
|
|
|
+ if (port->open_count == 1) {
|
|
|
+ port->closePending = 0;
|
|
|
+ mydbg("%s port->closepending = 0\n", __FUNCTION__);
|
|
|
|
|
|
- port->RxHolding = 0;
|
|
|
- mydbg("%s port->RxHolding = 0\n", __FUNCTION__);
|
|
|
+ port->RxHolding = 0;
|
|
|
+ mydbg("%s port->RxHolding = 0\n", __FUNCTION__);
|
|
|
|
|
|
- retval = qt_open(port, filp);
|
|
|
- }
|
|
|
+ retval = qt_open(port, filp);
|
|
|
+ }
|
|
|
|
|
|
- if (retval)
|
|
|
- {
|
|
|
- port->open_count = 0;
|
|
|
- }
|
|
|
- mydbg("%s returning port->closePending = %d\n", __FUNCTION__, port->closePending);
|
|
|
+ if (retval) {
|
|
|
+ port->open_count = 0;
|
|
|
+ }
|
|
|
+ mydbg("%s returning port->closePending = %d\n", __FUNCTION__,
|
|
|
+ port->closePending);
|
|
|
|
|
|
- up (&port->sem);
|
|
|
- return retval;
|
|
|
+ up(&port->sem);
|
|
|
+ return retval;
|
|
|
}
|
|
|
+
|
|
|
/*****************************************************************************
|
|
|
*device's specific driver functions
|
|
|
*****************************************************************************/
|
|
|
-static int qt_open (struct usb_serial_port *port, struct file *filp){
|
|
|
- struct usb_serial *serial = port->serial;
|
|
|
- int result = 0;
|
|
|
- unsigned int UartNumber;
|
|
|
- struct qt_get_device_data DeviceData;
|
|
|
- struct qt_open_channel_data ChannelData;
|
|
|
- unsigned short default_divisor = 0x30; //gives 9600 baud rate
|
|
|
- unsigned char default_LCR = SERIAL_8_DATA; // 8, none , 1
|
|
|
- int status = 0;
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
- if (port_paranoia_check (port, __FUNCTION__))
|
|
|
- return -ENODEV;
|
|
|
-
|
|
|
- mydbg("%s - port %d\n", __FUNCTION__, port->number);
|
|
|
-
|
|
|
- /* force low_latency on so that our tty_push actually forces the data through,
|
|
|
- otherwise it is scheduled, and with high data rates (like with OHCI) data
|
|
|
- can get lost. */
|
|
|
- if (port->tty)
|
|
|
- port->tty->low_latency = 0;
|
|
|
-
|
|
|
-
|
|
|
- UartNumber = port->tty->index - serial->minor;
|
|
|
+static int qt_open(struct usb_serial_port *port, struct file *filp)
|
|
|
+{
|
|
|
+ struct usb_serial *serial = port->serial;
|
|
|
+ int result = 0;
|
|
|
+ unsigned int UartNumber;
|
|
|
+ struct qt_get_device_data DeviceData;
|
|
|
+ struct qt_open_channel_data ChannelData;
|
|
|
+ unsigned short default_divisor = 0x30; //gives 9600 baud rate
|
|
|
+ unsigned char default_LCR = SERIAL_8_DATA; // 8, none , 1
|
|
|
+ int status = 0;
|
|
|
|
|
|
- status = box_get_device(serial, &DeviceData);
|
|
|
- if (status < 0)
|
|
|
- {
|
|
|
- mydbg(__FILE__"box_get_device failed\n");
|
|
|
- return status;
|
|
|
- }
|
|
|
- serial->num_OpenCount++;
|
|
|
- mydbg("%s serial->num_OpenCount = %d\n", __FUNCTION__, serial->num_OpenCount);
|
|
|
- //Open uart channel
|
|
|
+ if (port_paranoia_check(port, __FUNCTION__))
|
|
|
+ return -ENODEV;
|
|
|
|
|
|
- //Port specific setups
|
|
|
- status = BoxOPenCloseChannel(serial, UartNumber, 1, &ChannelData);
|
|
|
- if (status < 0)
|
|
|
- {
|
|
|
- mydbg(__FILE__"BoxOPenCloseChannel failed\n");
|
|
|
- return status;
|
|
|
- }
|
|
|
- mydbg(__FILE__"BoxOPenCloseChannel completed.\n");
|
|
|
+ mydbg("%s - port %d\n", __FUNCTION__, port->number);
|
|
|
|
|
|
- port->shadowLSR = ChannelData.line_status &
|
|
|
- (SERIAL_LSR_OE | SERIAL_LSR_PE | SERIAL_LSR_FE | SERIAL_LSR_BI);
|
|
|
+ /* force low_latency on so that our tty_push actually forces the data through,
|
|
|
+ otherwise it is scheduled, and with high data rates (like with OHCI) data
|
|
|
+ can get lost. */
|
|
|
+ if (port->tty)
|
|
|
+ port->tty->low_latency = 0;
|
|
|
|
|
|
- port->shadowMSR = ChannelData.modem_status &
|
|
|
- (SERIAL_MSR_CTS | SERIAL_MSR_DSR | SERIAL_MSR_RI | SERIAL_MSR_CD);
|
|
|
+ UartNumber = port->tty->index - serial->minor;
|
|
|
|
|
|
+ status = box_get_device(serial, &DeviceData);
|
|
|
+ if (status < 0) {
|
|
|
+ mydbg(__FILE__ "box_get_device failed\n");
|
|
|
+ return status;
|
|
|
+ }
|
|
|
+ serial->num_OpenCount++;
|
|
|
+ mydbg("%s serial->num_OpenCount = %d\n", __FUNCTION__,
|
|
|
+ serial->num_OpenCount);
|
|
|
+ //Open uart channel
|
|
|
+
|
|
|
+ //Port specific setups
|
|
|
+ status = BoxOPenCloseChannel(serial, UartNumber, 1, &ChannelData);
|
|
|
+ if (status < 0) {
|
|
|
+ mydbg(__FILE__ "BoxOPenCloseChannel failed\n");
|
|
|
+ return status;
|
|
|
+ }
|
|
|
+ mydbg(__FILE__ "BoxOPenCloseChannel completed.\n");
|
|
|
|
|
|
- //Set Baud rate to default and turn off (default)flow control here
|
|
|
- status = BoxSetUart(serial, UartNumber, default_divisor, default_LCR);
|
|
|
- if (status < 0)
|
|
|
- {
|
|
|
- mydbg(__FILE__"BoxSetUart failed\n");
|
|
|
- return status;
|
|
|
- }
|
|
|
- mydbg(__FILE__"BoxSetUart completed.\n");
|
|
|
+ port->shadowLSR = ChannelData.line_status &
|
|
|
+ (SERIAL_LSR_OE | SERIAL_LSR_PE | SERIAL_LSR_FE | SERIAL_LSR_BI);
|
|
|
|
|
|
+ port->shadowMSR = ChannelData.modem_status &
|
|
|
+ (SERIAL_MSR_CTS | SERIAL_MSR_DSR | SERIAL_MSR_RI | SERIAL_MSR_CD);
|
|
|
|
|
|
- //Put this here to make it responsive to stty and defauls set by the tty layer
|
|
|
- qt_set_termios(port, NULL);
|
|
|
+ //Set Baud rate to default and turn off (default)flow control here
|
|
|
+ status = BoxSetUart(serial, UartNumber, default_divisor, default_LCR);
|
|
|
+ if (status < 0) {
|
|
|
+ mydbg(__FILE__ "BoxSetUart failed\n");
|
|
|
+ return status;
|
|
|
+ }
|
|
|
+ mydbg(__FILE__ "BoxSetUart completed.\n");
|
|
|
|
|
|
+ //Put this here to make it responsive to stty and defauls set by the tty layer
|
|
|
+ qt_set_termios(port, NULL);
|
|
|
|
|
|
- //Initialize the wait que head
|
|
|
- init_waitqueue_head(&(port->wait));
|
|
|
+ //Initialize the wait que head
|
|
|
+ init_waitqueue_head(&(port->wait));
|
|
|
|
|
|
- /* if we have a bulk endpoint, start reading from it */
|
|
|
- if (serial->num_bulk_in)
|
|
|
- {
|
|
|
- /* Start reading from the device */
|
|
|
- usb_fill_bulk_urb (port->read_urb, serial->dev,
|
|
|
- usb_rcvbulkpipe(serial->dev, port->bulk_in_endpointAddress),
|
|
|
- port->read_urb->transfer_buffer,
|
|
|
- port->read_urb->transfer_buffer_length,
|
|
|
- qt_read_bulk_callback,
|
|
|
- port);
|
|
|
+ /* if we have a bulk endpoint, start reading from it */
|
|
|
+ if (serial->num_bulk_in) {
|
|
|
+ /* Start reading from the device */
|
|
|
+ usb_fill_bulk_urb(port->read_urb, serial->dev,
|
|
|
+ usb_rcvbulkpipe(serial->dev,
|
|
|
+ port->
|
|
|
+ bulk_in_endpointAddress),
|
|
|
+ port->read_urb->transfer_buffer,
|
|
|
+ port->read_urb->transfer_buffer_length,
|
|
|
+ qt_read_bulk_callback, port);
|
|
|
|
|
|
- port->ReadBulkStopped = 0;
|
|
|
+ port->ReadBulkStopped = 0;
|
|
|
|
|
|
- result = usb_submit_urb(port->read_urb, GFP_ATOMIC);
|
|
|
+ result = usb_submit_urb(port->read_urb, GFP_ATOMIC);
|
|
|
|
|
|
- if (result)
|
|
|
- {
|
|
|
- err("%s - failed resubmitting read urb, error %d\n", __FUNCTION__, result);
|
|
|
- port->ReadBulkStopped = 1;
|
|
|
- }
|
|
|
+ if (result) {
|
|
|
+ err("%s - failed resubmitting read urb, error %d\n",
|
|
|
+ __FUNCTION__, result);
|
|
|
+ port->ReadBulkStopped = 1;
|
|
|
+ }
|
|
|
|
|
|
- }
|
|
|
+ }
|
|
|
|
|
|
- return result;
|
|
|
+ return result;
|
|
|
}
|
|
|
|
|
|
-static void serial_close(struct tty_struct *tty, struct file * filp){
|
|
|
- struct usb_serial_port *port = (struct usb_serial_port *) tty->driver_data;
|
|
|
- struct usb_serial *serial = get_usb_serial (port, __FUNCTION__);
|
|
|
-
|
|
|
- if (!serial)
|
|
|
- return;
|
|
|
+static void serial_close(struct tty_struct *tty, struct file *filp)
|
|
|
+{
|
|
|
+ struct usb_serial_port *port =
|
|
|
+ (struct usb_serial_port *)tty->driver_data;
|
|
|
+ struct usb_serial *serial = get_usb_serial(port, __FUNCTION__);
|
|
|
|
|
|
- down (&port->sem);
|
|
|
+ if (!serial)
|
|
|
+ return;
|
|
|
|
|
|
- mydbg("%s - port %d\n", __FUNCTION__, port->number);
|
|
|
+ down(&port->sem);
|
|
|
|
|
|
- /* if disconnect beat us to the punch here, there's nothing to do */
|
|
|
- if (tty->driver_data)
|
|
|
- {
|
|
|
- if (!port->open_count)
|
|
|
- {
|
|
|
- mydbg ("%s - port not opened\n", __FUNCTION__);
|
|
|
- goto exit;
|
|
|
- }
|
|
|
+ mydbg("%s - port %d\n", __FUNCTION__, port->number);
|
|
|
|
|
|
- --port->open_count;
|
|
|
- if (port->open_count <= 0)
|
|
|
- {
|
|
|
- port->closePending = 1;
|
|
|
- mydbg ("%s - port->closePending = 1\n", __FUNCTION__);
|
|
|
+ /* if disconnect beat us to the punch here, there's nothing to do */
|
|
|
+ if (tty->driver_data) {
|
|
|
+ if (!port->open_count) {
|
|
|
+ mydbg("%s - port not opened\n", __FUNCTION__);
|
|
|
+ goto exit;
|
|
|
+ }
|
|
|
|
|
|
- if (serial->dev)
|
|
|
- {
|
|
|
- qt_close(port, filp);
|
|
|
- port->open_count = 0;
|
|
|
- }
|
|
|
- }
|
|
|
+ --port->open_count;
|
|
|
+ if (port->open_count <= 0) {
|
|
|
+ port->closePending = 1;
|
|
|
+ mydbg("%s - port->closePending = 1\n", __FUNCTION__);
|
|
|
|
|
|
- }
|
|
|
+ if (serial->dev) {
|
|
|
+ qt_close(port, filp);
|
|
|
+ port->open_count = 0;
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
- exit:
|
|
|
- up (&port->sem);
|
|
|
+ }
|
|
|
|
|
|
- mydbg("%s - %d return\n", __FUNCTION__, port->number);
|
|
|
+exit:
|
|
|
+ up(&port->sem);
|
|
|
|
|
|
+ mydbg("%s - %d return\n", __FUNCTION__, port->number);
|
|
|
|
|
|
}
|
|
|
|
|
|
-static void qt_close (struct usb_serial_port *port, struct file *filp){
|
|
|
- unsigned long jift = jiffies + 10 * HZ;
|
|
|
- __u8 LSR_Value, MCR_Value;
|
|
|
- struct usb_serial *serial = port->serial;
|
|
|
- int status;
|
|
|
- unsigned int UartNumber;
|
|
|
-
|
|
|
- struct qt_open_channel_data ChannelData;
|
|
|
- status = 0;
|
|
|
- LSR_Value = 0;
|
|
|
-
|
|
|
-
|
|
|
- mydbg("%s - port %d\n", __FUNCTION__, port->number);
|
|
|
- UartNumber = port->tty->index - serial->minor;
|
|
|
-
|
|
|
- /* shutdown any bulk reads that might be going on */
|
|
|
- if (serial->num_bulk_out)
|
|
|
- usb_unlink_urb (port->write_urb);
|
|
|
- if (serial->num_bulk_in)
|
|
|
- usb_unlink_urb (port->read_urb);
|
|
|
-
|
|
|
-
|
|
|
- //wait up to 30 seconds for transmitter to empty
|
|
|
- do
|
|
|
- {
|
|
|
- status = BoxGetRegister(serial, UartNumber, LINE_STATUS_REGISTER, &LSR_Value);
|
|
|
- if (status < 0)
|
|
|
- {
|
|
|
- mydbg(__FILE__"box_get_device failed\n");
|
|
|
- break;
|
|
|
- }
|
|
|
-
|
|
|
- if ((LSR_Value & SERIAL_LSR_TEMT) && (port->ReadBulkStopped == 1))
|
|
|
- break;
|
|
|
- schedule();
|
|
|
-
|
|
|
-
|
|
|
- }
|
|
|
- while (jiffies <= jift);
|
|
|
-
|
|
|
- if(jiffies > jift)
|
|
|
- mydbg("%s - port %d timout of checking transmitter empty\n", __FUNCTION__, port->number);
|
|
|
- else
|
|
|
- mydbg("%s - port %d checking transmitter empty succeded\n", __FUNCTION__, port->number);
|
|
|
-
|
|
|
+static void qt_close(struct usb_serial_port *port, struct file *filp)
|
|
|
+{
|
|
|
+ unsigned long jift = jiffies + 10 * HZ;
|
|
|
+ __u8 LSR_Value, MCR_Value;
|
|
|
+ struct usb_serial *serial = port->serial;
|
|
|
+ int status;
|
|
|
+ unsigned int UartNumber;
|
|
|
|
|
|
+ struct qt_open_channel_data ChannelData;
|
|
|
+ status = 0;
|
|
|
+ LSR_Value = 0;
|
|
|
|
|
|
- status = BoxGetRegister(serial, UartNumber, MODEM_CONTROL_REGISTER, &MCR_Value);
|
|
|
- mydbg(__FILE__"BoxGetRegister MCR = 0x%x.\n", MCR_Value);
|
|
|
+ mydbg("%s - port %d\n", __FUNCTION__, port->number);
|
|
|
+ UartNumber = port->tty->index - serial->minor;
|
|
|
+
|
|
|
+ /* shutdown any bulk reads that might be going on */
|
|
|
+ if (serial->num_bulk_out)
|
|
|
+ usb_unlink_urb(port->write_urb);
|
|
|
+ if (serial->num_bulk_in)
|
|
|
+ usb_unlink_urb(port->read_urb);
|
|
|
+
|
|
|
+ //wait up to 30 seconds for transmitter to empty
|
|
|
+ do {
|
|
|
+ status =
|
|
|
+ BoxGetRegister(serial, UartNumber, LINE_STATUS_REGISTER,
|
|
|
+ &LSR_Value);
|
|
|
+ if (status < 0) {
|
|
|
+ mydbg(__FILE__ "box_get_device failed\n");
|
|
|
+ break;
|
|
|
+ }
|
|
|
|
|
|
+ if ((LSR_Value & SERIAL_LSR_TEMT)
|
|
|
+ && (port->ReadBulkStopped == 1))
|
|
|
+ break;
|
|
|
+ schedule();
|
|
|
|
|
|
- if (status >= 0)
|
|
|
- {
|
|
|
- MCR_Value &= ~(SERIAL_MCR_DTR | SERIAL_MCR_RTS);
|
|
|
+ }
|
|
|
+ while (jiffies <= jift);
|
|
|
+
|
|
|
+ if (jiffies > jift)
|
|
|
+ mydbg("%s - port %d timout of checking transmitter empty\n",
|
|
|
+ __FUNCTION__, port->number);
|
|
|
+ else
|
|
|
+ mydbg("%s - port %d checking transmitter empty succeded\n",
|
|
|
+ __FUNCTION__, port->number);
|
|
|
+
|
|
|
+ status =
|
|
|
+ BoxGetRegister(serial, UartNumber, MODEM_CONTROL_REGISTER,
|
|
|
+ &MCR_Value);
|
|
|
+ mydbg(__FILE__ "BoxGetRegister MCR = 0x%x.\n", MCR_Value);
|
|
|
+
|
|
|
+ if (status >= 0) {
|
|
|
+ MCR_Value &= ~(SERIAL_MCR_DTR | SERIAL_MCR_RTS);
|
|
|
// status = BoxSetRegister(serial, UartNumber, MODEM_CONTROL_REGISTER, MCR_Value);
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
- //Close uart channel
|
|
|
- status = BoxOPenCloseChannel(serial, UartNumber, 0, &ChannelData);
|
|
|
- if(status < 0)
|
|
|
- mydbg("%s - port %d BoxOPenCloseChannel failed.\n", __FUNCTION__, port->number);
|
|
|
+ }
|
|
|
|
|
|
- serial->num_OpenCount--;
|
|
|
+ //Close uart channel
|
|
|
+ status = BoxOPenCloseChannel(serial, UartNumber, 0, &ChannelData);
|
|
|
+ if (status < 0)
|
|
|
+ mydbg("%s - port %d BoxOPenCloseChannel failed.\n",
|
|
|
+ __FUNCTION__, port->number);
|
|
|
|
|
|
+ serial->num_OpenCount--;
|
|
|
|
|
|
}
|
|
|
|
|
|
-
|
|
|
-
|
|
|
-static int serial_write (struct tty_struct * tty, const unsigned char *buf, int count)
|
|
|
+static int serial_write(struct tty_struct *tty, const unsigned char *buf,
|
|
|
+ int count)
|
|
|
{
|
|
|
- struct usb_serial_port *port = (struct usb_serial_port *) tty->driver_data;
|
|
|
- struct usb_serial *serial;
|
|
|
- int retval = -EINVAL;
|
|
|
- unsigned int UartNumber;
|
|
|
- int from_user = 0;
|
|
|
-
|
|
|
-
|
|
|
- serial = get_usb_serial (port, __FUNCTION__);
|
|
|
- if(serial == NULL)
|
|
|
- return -ENODEV;
|
|
|
- //This can happen if we get disconnected a
|
|
|
- if (port->open_count == 0)
|
|
|
- {
|
|
|
- return -ENODEV;
|
|
|
- }
|
|
|
- UartNumber = port->tty->index - serial->minor;
|
|
|
-
|
|
|
- mydbg("%s - port %d, %d byte(s)\n", __FUNCTION__, port->number, count);
|
|
|
- mydbg("%s - port->RxHolding = %d\n", __FUNCTION__, port->RxHolding);
|
|
|
-
|
|
|
- if (!port->open_count)
|
|
|
- {
|
|
|
- mydbg("%s - port not opened\n", __FUNCTION__);
|
|
|
- goto exit;
|
|
|
- }
|
|
|
-
|
|
|
- retval = qt_write(port, from_user, buf, count);
|
|
|
-
|
|
|
- exit:
|
|
|
- return retval;
|
|
|
-}
|
|
|
-
|
|
|
-
|
|
|
-static int qt_write (struct usb_serial_port *port, int from_user, const unsigned char *buf, int count){
|
|
|
- int result;
|
|
|
- unsigned int UartNumber;
|
|
|
-
|
|
|
- struct usb_serial *serial = get_usb_serial (port, __FUNCTION__);
|
|
|
- if(serial == NULL)
|
|
|
- return -ENODEV;
|
|
|
-
|
|
|
+ struct usb_serial_port *port =
|
|
|
+ (struct usb_serial_port *)tty->driver_data;
|
|
|
+ struct usb_serial *serial;
|
|
|
+ int retval = -EINVAL;
|
|
|
+ unsigned int UartNumber;
|
|
|
+ int from_user = 0;
|
|
|
|
|
|
+ serial = get_usb_serial(port, __FUNCTION__);
|
|
|
+ if (serial == NULL)
|
|
|
+ return -ENODEV;
|
|
|
+ //This can happen if we get disconnected a
|
|
|
+ if (port->open_count == 0) {
|
|
|
+ return -ENODEV;
|
|
|
+ }
|
|
|
+ UartNumber = port->tty->index - serial->minor;
|
|
|
|
|
|
- mydbg("%s - port %d\n", __FUNCTION__, port->number);
|
|
|
+ mydbg("%s - port %d, %d byte(s)\n", __FUNCTION__, port->number, count);
|
|
|
+ mydbg("%s - port->RxHolding = %d\n", __FUNCTION__, port->RxHolding);
|
|
|
|
|
|
- if (count == 0)
|
|
|
- {
|
|
|
- mydbg("%s - write request of 0 bytes\n", __FUNCTION__);
|
|
|
- return(0);
|
|
|
- }
|
|
|
+ if (!port->open_count) {
|
|
|
+ mydbg("%s - port not opened\n", __FUNCTION__);
|
|
|
+ goto exit;
|
|
|
+ }
|
|
|
|
|
|
+ retval = qt_write(port, from_user, buf, count);
|
|
|
|
|
|
- UartNumber = port->tty->index - serial->minor;
|
|
|
- /* only do something if we have a bulk out endpoint */
|
|
|
- if (serial->num_bulk_out)
|
|
|
- {
|
|
|
- if (port->write_urb->status == -EINPROGRESS)
|
|
|
- {
|
|
|
- mydbg("%s - already writing\n", __FUNCTION__);
|
|
|
- return(0);
|
|
|
- }
|
|
|
+exit:
|
|
|
+ return retval;
|
|
|
+}
|
|
|
|
|
|
- count = (count > port->bulk_out_size) ? port->bulk_out_size : count;
|
|
|
+static int qt_write(struct usb_serial_port *port, int from_user,
|
|
|
+ const unsigned char *buf, int count)
|
|
|
+{
|
|
|
+ int result;
|
|
|
+ unsigned int UartNumber;
|
|
|
|
|
|
- if (from_user)
|
|
|
- {
|
|
|
- if (copy_from_user(port->write_urb->transfer_buffer, buf, count))
|
|
|
- return -EFAULT;
|
|
|
- } else
|
|
|
- {
|
|
|
- memcpy (port->write_urb->transfer_buffer, buf, count);
|
|
|
- }
|
|
|
+ struct usb_serial *serial = get_usb_serial(port, __FUNCTION__);
|
|
|
+ if (serial == NULL)
|
|
|
+ return -ENODEV;
|
|
|
|
|
|
- //usb_serial_debug_data(__FILE__, __FUNCTION__, count, port->write_urb->transfer_buffer);
|
|
|
+ mydbg("%s - port %d\n", __FUNCTION__, port->number);
|
|
|
|
|
|
- /* set up our urb */
|
|
|
+ if (count == 0) {
|
|
|
+ mydbg("%s - write request of 0 bytes\n", __FUNCTION__);
|
|
|
+ return (0);
|
|
|
+ }
|
|
|
|
|
|
+ UartNumber = port->tty->index - serial->minor;
|
|
|
+ /* only do something if we have a bulk out endpoint */
|
|
|
+ if (serial->num_bulk_out) {
|
|
|
+ if (port->write_urb->status == -EINPROGRESS) {
|
|
|
+ mydbg("%s - already writing\n", __FUNCTION__);
|
|
|
+ return (0);
|
|
|
+ }
|
|
|
|
|
|
- usb_fill_bulk_urb (port->write_urb, serial->dev,
|
|
|
- usb_sndbulkpipe (serial->dev,
|
|
|
- port->bulk_out_endpointAddress),
|
|
|
- port->write_urb->transfer_buffer, count,
|
|
|
- qt_write_bulk_callback, port);
|
|
|
+ count =
|
|
|
+ (count > port->bulk_out_size) ? port->bulk_out_size : count;
|
|
|
|
|
|
+ if (from_user) {
|
|
|
+ if (copy_from_user
|
|
|
+ (port->write_urb->transfer_buffer, buf, count))
|
|
|
+ return -EFAULT;
|
|
|
+ } else {
|
|
|
+ memcpy(port->write_urb->transfer_buffer, buf, count);
|
|
|
+ }
|
|
|
|
|
|
+ //usb_serial_debug_data(__FILE__, __FUNCTION__, count, port->write_urb->transfer_buffer);
|
|
|
|
|
|
+ /* set up our urb */
|
|
|
|
|
|
+ usb_fill_bulk_urb(port->write_urb, serial->dev,
|
|
|
+ usb_sndbulkpipe(serial->dev,
|
|
|
+ port->
|
|
|
+ bulk_out_endpointAddress),
|
|
|
+ port->write_urb->transfer_buffer, count,
|
|
|
+ qt_write_bulk_callback, port);
|
|
|
|
|
|
- /* send the data out the bulk port */
|
|
|
- result = usb_submit_urb(port->write_urb, GFP_ATOMIC);
|
|
|
- if (result)
|
|
|
- mydbg("%s - failed submitting write urb, error %d\n", __FUNCTION__, result);
|
|
|
- else
|
|
|
- result = count;
|
|
|
+ /* send the data out the bulk port */
|
|
|
+ result = usb_submit_urb(port->write_urb, GFP_ATOMIC);
|
|
|
+ if (result)
|
|
|
+ mydbg("%s - failed submitting write urb, error %d\n",
|
|
|
+ __FUNCTION__, result);
|
|
|
+ else
|
|
|
+ result = count;
|
|
|
|
|
|
- return result;
|
|
|
- }
|
|
|
+ return result;
|
|
|
+ }
|
|
|
|
|
|
- /* no bulk out, so return 0 bytes written */
|
|
|
- return(0);
|
|
|
+ /* no bulk out, so return 0 bytes written */
|
|
|
+ return (0);
|
|
|
}
|
|
|
|
|
|
-
|
|
|
-
|
|
|
static void qt_write_bulk_callback(struct urb *urb)
|
|
|
{
|
|
|
- struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
|
|
|
- struct usb_serial *serial = get_usb_serial (port, __FUNCTION__);
|
|
|
-
|
|
|
- mydbg("%s - port %d\n", __FUNCTION__, port->number);
|
|
|
-
|
|
|
- if (!serial)
|
|
|
- {
|
|
|
- mydbg("%s - bad serial pointer, exiting\n", __FUNCTION__);
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
- if (urb->status)
|
|
|
- {
|
|
|
- mydbg("%s - nonzero write bulk status received: %d\n", __FUNCTION__, urb->status);
|
|
|
- return;
|
|
|
- }
|
|
|
- //
|
|
|
- port_softint(&port->work);
|
|
|
- schedule_work(&port->work);
|
|
|
-
|
|
|
- return;
|
|
|
-}
|
|
|
-
|
|
|
+ struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
|
|
|
+ struct usb_serial *serial = get_usb_serial(port, __FUNCTION__);
|
|
|
|
|
|
-static void port_softint(struct work_struct *work)
|
|
|
-{
|
|
|
- struct usb_serial_port *port =
|
|
|
- container_of(work, struct usb_serial_port, work);
|
|
|
- struct usb_serial *serial = get_usb_serial (port, __FUNCTION__);
|
|
|
- struct tty_struct *tty;
|
|
|
+ mydbg("%s - port %d\n", __FUNCTION__, port->number);
|
|
|
|
|
|
+ if (!serial) {
|
|
|
+ mydbg("%s - bad serial pointer, exiting\n", __FUNCTION__);
|
|
|
+ return;
|
|
|
+ }
|
|
|
|
|
|
- mydbg("%s - port %d\n", __FUNCTION__, port->number);
|
|
|
+ if (urb->status) {
|
|
|
+ mydbg("%s - nonzero write bulk status received: %d\n",
|
|
|
+ __FUNCTION__, urb->status);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ //
|
|
|
+ port_softint(&port->work);
|
|
|
+ schedule_work(&port->work);
|
|
|
|
|
|
+ return;
|
|
|
+}
|
|
|
|
|
|
+static void port_softint(struct work_struct *work)
|
|
|
+{
|
|
|
+ struct usb_serial_port *port =
|
|
|
+ container_of(work, struct usb_serial_port, work);
|
|
|
+ struct usb_serial *serial = get_usb_serial(port, __FUNCTION__);
|
|
|
+ struct tty_struct *tty;
|
|
|
|
|
|
- if (!serial)
|
|
|
- return;
|
|
|
+ mydbg("%s - port %d\n", __FUNCTION__, port->number);
|
|
|
|
|
|
+ if (!serial)
|
|
|
+ return;
|
|
|
|
|
|
- tty = port->tty;
|
|
|
- if (!tty)
|
|
|
- return;
|
|
|
+ tty = port->tty;
|
|
|
+ if (!tty)
|
|
|
+ return;
|
|
|
#if 0
|
|
|
- if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && tty->ldisc.write_wakeup)
|
|
|
- {
|
|
|
- mydbg("%s - write wakeup call.\n", __FUNCTION__);
|
|
|
- (tty->ldisc.write_wakeup)(tty);
|
|
|
- }
|
|
|
+ if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP))
|
|
|
+ && tty->ldisc.write_wakeup) {
|
|
|
+ mydbg("%s - write wakeup call.\n", __FUNCTION__);
|
|
|
+ (tty->ldisc.write_wakeup) (tty);
|
|
|
+ }
|
|
|
#endif
|
|
|
|
|
|
- wake_up_interruptible(&tty->write_wait);
|
|
|
+ wake_up_interruptible(&tty->write_wait);
|
|
|
}
|
|
|
-static int serial_write_room (struct tty_struct *tty)
|
|
|
+static int serial_write_room(struct tty_struct *tty)
|
|
|
{
|
|
|
- struct usb_serial_port *port = (struct usb_serial_port *) tty->driver_data;
|
|
|
- struct usb_serial *serial = get_usb_serial (port, __FUNCTION__);
|
|
|
- int retval = -EINVAL;
|
|
|
+ struct usb_serial_port *port =
|
|
|
+ (struct usb_serial_port *)tty->driver_data;
|
|
|
+ struct usb_serial *serial = get_usb_serial(port, __FUNCTION__);
|
|
|
+ int retval = -EINVAL;
|
|
|
|
|
|
- if (!serial)
|
|
|
- return -ENODEV;
|
|
|
+ if (!serial)
|
|
|
+ return -ENODEV;
|
|
|
|
|
|
- down (&port->sem);
|
|
|
+ down(&port->sem);
|
|
|
|
|
|
- mydbg("%s - port %d\n", __FUNCTION__, port->number);
|
|
|
+ mydbg("%s - port %d\n", __FUNCTION__, port->number);
|
|
|
|
|
|
- if (!port->open_count)
|
|
|
- {
|
|
|
- mydbg("%s - port not open\n", __FUNCTION__);
|
|
|
- goto exit;
|
|
|
- }
|
|
|
+ if (!port->open_count) {
|
|
|
+ mydbg("%s - port not open\n", __FUNCTION__);
|
|
|
+ goto exit;
|
|
|
+ }
|
|
|
|
|
|
- retval = qt_write_room(port);
|
|
|
+ retval = qt_write_room(port);
|
|
|
|
|
|
- exit:
|
|
|
- up (&port->sem);
|
|
|
- return retval;
|
|
|
+exit:
|
|
|
+ up(&port->sem);
|
|
|
+ return retval;
|
|
|
}
|
|
|
-static int qt_write_room (struct usb_serial_port *port)
|
|
|
+static int qt_write_room(struct usb_serial_port *port)
|
|
|
{
|
|
|
- struct usb_serial *serial = port->serial;
|
|
|
- int room = 0;
|
|
|
- if (port->closePending == 1)
|
|
|
- {
|
|
|
- mydbg("%s - port->closePending == 1\n", __FUNCTION__);
|
|
|
- return -ENODEV;
|
|
|
- }
|
|
|
-
|
|
|
+ struct usb_serial *serial = port->serial;
|
|
|
+ int room = 0;
|
|
|
+ if (port->closePending == 1) {
|
|
|
+ mydbg("%s - port->closePending == 1\n", __FUNCTION__);
|
|
|
+ return -ENODEV;
|
|
|
+ }
|
|
|
|
|
|
- mydbg("%s - port %d\n", __FUNCTION__, port->number);
|
|
|
+ mydbg("%s - port %d\n", __FUNCTION__, port->number);
|
|
|
|
|
|
- if (serial->num_bulk_out)
|
|
|
- {
|
|
|
- if (port->write_urb->status != -EINPROGRESS)
|
|
|
- room = port->bulk_out_size;
|
|
|
- }
|
|
|
+ if (serial->num_bulk_out) {
|
|
|
+ if (port->write_urb->status != -EINPROGRESS)
|
|
|
+ room = port->bulk_out_size;
|
|
|
+ }
|
|
|
|
|
|
- mydbg("%s - returns %d\n", __FUNCTION__, room);
|
|
|
- return(room);
|
|
|
+ mydbg("%s - returns %d\n", __FUNCTION__, room);
|
|
|
+ return (room);
|
|
|
}
|
|
|
-static int serial_chars_in_buffer (struct tty_struct *tty)
|
|
|
+static int serial_chars_in_buffer(struct tty_struct *tty)
|
|
|
{
|
|
|
- struct usb_serial_port *port = (struct usb_serial_port *) tty->driver_data;
|
|
|
- struct usb_serial *serial = get_usb_serial (port, __FUNCTION__);
|
|
|
+ struct usb_serial_port *port =
|
|
|
+ (struct usb_serial_port *)tty->driver_data;
|
|
|
+ struct usb_serial *serial = get_usb_serial(port, __FUNCTION__);
|
|
|
int retval = -EINVAL;
|
|
|
|
|
|
if (!serial)
|
|
|
return -ENODEV;
|
|
|
|
|
|
- down (&port->sem);
|
|
|
+ down(&port->sem);
|
|
|
|
|
|
mydbg("%s = port %d\n", __FUNCTION__, port->number);
|
|
|
|
|
@@ -1633,275 +1532,267 @@ static int serial_chars_in_buffer (struct tty_struct *tty)
|
|
|
retval = qt_chars_in_buffer(port);
|
|
|
|
|
|
exit:
|
|
|
- up (&port->sem);
|
|
|
+ up(&port->sem);
|
|
|
return retval;
|
|
|
}
|
|
|
|
|
|
-
|
|
|
-
|
|
|
-static int qt_chars_in_buffer (struct usb_serial_port *port)
|
|
|
+static int qt_chars_in_buffer(struct usb_serial_port *port)
|
|
|
{
|
|
|
- struct usb_serial *serial = port->serial;
|
|
|
- int chars = 0;
|
|
|
+ struct usb_serial *serial = port->serial;
|
|
|
+ int chars = 0;
|
|
|
|
|
|
- mydbg("%s - port %d\n", __FUNCTION__, port->number);
|
|
|
+ mydbg("%s - port %d\n", __FUNCTION__, port->number);
|
|
|
|
|
|
- if (serial->num_bulk_out)
|
|
|
- {
|
|
|
- if (port->write_urb->status == -EINPROGRESS)
|
|
|
- chars = port->write_urb->transfer_buffer_length;
|
|
|
- }
|
|
|
+ if (serial->num_bulk_out) {
|
|
|
+ if (port->write_urb->status == -EINPROGRESS)
|
|
|
+ chars = port->write_urb->transfer_buffer_length;
|
|
|
+ }
|
|
|
|
|
|
- mydbg("%s - returns %d\n", __FUNCTION__, chars);
|
|
|
- return(chars);
|
|
|
+ mydbg("%s - returns %d\n", __FUNCTION__, chars);
|
|
|
+ return (chars);
|
|
|
}
|
|
|
|
|
|
-
|
|
|
-static int serial_tiocmset (struct tty_struct *tty, struct file *file, unsigned int set, unsigned int clear)
|
|
|
+static int serial_tiocmset(struct tty_struct *tty, struct file *file,
|
|
|
+ unsigned int set, unsigned int clear)
|
|
|
{
|
|
|
|
|
|
- struct usb_serial_port *port = (struct usb_serial_port *) tty->driver_data;
|
|
|
- struct usb_serial *serial = get_usb_serial (port, __FUNCTION__);
|
|
|
- int retval = -ENODEV;
|
|
|
- unsigned int UartNumber;
|
|
|
- mydbg("In %s \n", __FUNCTION__);
|
|
|
-
|
|
|
- if (!serial)
|
|
|
- return -ENODEV;
|
|
|
+ struct usb_serial_port *port =
|
|
|
+ (struct usb_serial_port *)tty->driver_data;
|
|
|
+ struct usb_serial *serial = get_usb_serial(port, __FUNCTION__);
|
|
|
+ int retval = -ENODEV;
|
|
|
+ unsigned int UartNumber;
|
|
|
+ mydbg("In %s \n", __FUNCTION__);
|
|
|
|
|
|
+ if (!serial)
|
|
|
+ return -ENODEV;
|
|
|
|
|
|
- UartNumber = port->tty->index - serial->minor;
|
|
|
-
|
|
|
+ UartNumber = port->tty->index - serial->minor;
|
|
|
|
|
|
- down (&port->sem);
|
|
|
+ down(&port->sem);
|
|
|
|
|
|
- mydbg("%s - port %d \n", __FUNCTION__, port->number);
|
|
|
- mydbg ("%s - port->RxHolding = %d\n", __FUNCTION__, port->RxHolding);
|
|
|
+ mydbg("%s - port %d \n", __FUNCTION__, port->number);
|
|
|
+ mydbg("%s - port->RxHolding = %d\n", __FUNCTION__, port->RxHolding);
|
|
|
|
|
|
- if (!port->open_count)
|
|
|
- {
|
|
|
- mydbg ("%s - port not open\n", __FUNCTION__);
|
|
|
- goto exit;
|
|
|
- }
|
|
|
+ if (!port->open_count) {
|
|
|
+ mydbg("%s - port not open\n", __FUNCTION__);
|
|
|
+ goto exit;
|
|
|
+ }
|
|
|
|
|
|
- retval = qt_tiocmset(port, file, set);
|
|
|
+ retval = qt_tiocmset(port, file, set);
|
|
|
|
|
|
- exit:
|
|
|
- up (&port->sem);
|
|
|
- return retval;
|
|
|
+exit:
|
|
|
+ up(&port->sem);
|
|
|
+ return retval;
|
|
|
}
|
|
|
|
|
|
-
|
|
|
-static int qt_tiocmset(struct usb_serial_port *port, struct file * file, unsigned int value)
|
|
|
+static int qt_tiocmset(struct usb_serial_port *port, struct file *file,
|
|
|
+ unsigned int value)
|
|
|
{
|
|
|
|
|
|
- __u8 MCR_Value;
|
|
|
- int status;
|
|
|
- unsigned int UartNumber;
|
|
|
-
|
|
|
+ __u8 MCR_Value;
|
|
|
+ int status;
|
|
|
+ unsigned int UartNumber;
|
|
|
|
|
|
- struct usb_serial *serial = get_usb_serial (port, __FUNCTION__);
|
|
|
- if(serial == NULL)
|
|
|
- return -ENODEV;
|
|
|
+ struct usb_serial *serial = get_usb_serial(port, __FUNCTION__);
|
|
|
+ if (serial == NULL)
|
|
|
+ return -ENODEV;
|
|
|
|
|
|
- mydbg("%s - port %d\n", __FUNCTION__, port->number);
|
|
|
+ mydbg("%s - port %d\n", __FUNCTION__, port->number);
|
|
|
|
|
|
/**************************************************************************************/
|
|
|
/** TIOCMGET
|
|
|
*/
|
|
|
- UartNumber = port->tty->index - serial->minor;
|
|
|
- status = BoxGetRegister(port->serial, UartNumber, MODEM_CONTROL_REGISTER, &MCR_Value);
|
|
|
- if (status < 0)
|
|
|
- return -ESPIPE;
|
|
|
-
|
|
|
- //Turn off the RTS and DTR and loopbcck and then only
|
|
|
- //trun on what was asked for
|
|
|
- MCR_Value &= ~(SERIAL_MCR_RTS | SERIAL_MCR_DTR | SERIAL_MCR_LOOP);
|
|
|
- if (value & TIOCM_RTS)
|
|
|
- MCR_Value |= SERIAL_MCR_RTS;
|
|
|
- if (value & TIOCM_DTR)
|
|
|
- MCR_Value |= SERIAL_MCR_DTR;
|
|
|
- if (value & TIOCM_LOOP)
|
|
|
- MCR_Value |= SERIAL_MCR_LOOP;
|
|
|
-
|
|
|
- status = BoxSetRegister(port->serial, UartNumber, MODEM_CONTROL_REGISTER, MCR_Value);
|
|
|
- if (status < 0)
|
|
|
- return -ESPIPE;
|
|
|
- else
|
|
|
- return 0;
|
|
|
+ UartNumber = port->tty->index - serial->minor;
|
|
|
+ status =
|
|
|
+ BoxGetRegister(port->serial, UartNumber, MODEM_CONTROL_REGISTER,
|
|
|
+ &MCR_Value);
|
|
|
+ if (status < 0)
|
|
|
+ return -ESPIPE;
|
|
|
+
|
|
|
+ //Turn off the RTS and DTR and loopbcck and then only
|
|
|
+ //trun on what was asked for
|
|
|
+ MCR_Value &= ~(SERIAL_MCR_RTS | SERIAL_MCR_DTR | SERIAL_MCR_LOOP);
|
|
|
+ if (value & TIOCM_RTS)
|
|
|
+ MCR_Value |= SERIAL_MCR_RTS;
|
|
|
+ if (value & TIOCM_DTR)
|
|
|
+ MCR_Value |= SERIAL_MCR_DTR;
|
|
|
+ if (value & TIOCM_LOOP)
|
|
|
+ MCR_Value |= SERIAL_MCR_LOOP;
|
|
|
+
|
|
|
+ status =
|
|
|
+ BoxSetRegister(port->serial, UartNumber, MODEM_CONTROL_REGISTER,
|
|
|
+ MCR_Value);
|
|
|
+ if (status < 0)
|
|
|
+ return -ESPIPE;
|
|
|
+ else
|
|
|
+ return 0;
|
|
|
}
|
|
|
|
|
|
static int serial_tiocmget(struct tty_struct *tty, struct file *file)
|
|
|
{
|
|
|
|
|
|
- struct usb_serial_port *port = (struct usb_serial_port *) tty->driver_data;
|
|
|
+ struct usb_serial_port *port =
|
|
|
+ (struct usb_serial_port *)tty->driver_data;
|
|
|
|
|
|
- struct usb_serial *serial = get_usb_serial (port, __FUNCTION__);
|
|
|
- int retval = -ENODEV;
|
|
|
- unsigned int UartNumber;
|
|
|
- mydbg("In %s \n", __FUNCTION__);
|
|
|
+ struct usb_serial *serial = get_usb_serial(port, __FUNCTION__);
|
|
|
+ int retval = -ENODEV;
|
|
|
+ unsigned int UartNumber;
|
|
|
+ mydbg("In %s \n", __FUNCTION__);
|
|
|
|
|
|
- if (!serial)
|
|
|
- return -ENODEV;
|
|
|
-
|
|
|
-
|
|
|
- UartNumber = port->tty->index - serial->minor;
|
|
|
+ if (!serial)
|
|
|
+ return -ENODEV;
|
|
|
|
|
|
+ UartNumber = port->tty->index - serial->minor;
|
|
|
|
|
|
- down (&port->sem);
|
|
|
+ down(&port->sem);
|
|
|
|
|
|
- mydbg("%s - port %d\n", __FUNCTION__, port->number);
|
|
|
- mydbg ("%s - port->RxHolding = %d\n", __FUNCTION__, port->RxHolding);
|
|
|
+ mydbg("%s - port %d\n", __FUNCTION__, port->number);
|
|
|
+ mydbg("%s - port->RxHolding = %d\n", __FUNCTION__, port->RxHolding);
|
|
|
|
|
|
- if (!port->open_count)
|
|
|
- {
|
|
|
- mydbg ("%s - port not open\n", __FUNCTION__);
|
|
|
- goto exit;
|
|
|
- }
|
|
|
+ if (!port->open_count) {
|
|
|
+ mydbg("%s - port not open\n", __FUNCTION__);
|
|
|
+ goto exit;
|
|
|
+ }
|
|
|
|
|
|
- retval = qt_tiocmget(port, file);
|
|
|
+ retval = qt_tiocmget(port, file);
|
|
|
|
|
|
- exit:
|
|
|
- up (&port->sem);
|
|
|
- return retval;
|
|
|
+exit:
|
|
|
+ up(&port->sem);
|
|
|
+ return retval;
|
|
|
}
|
|
|
|
|
|
-
|
|
|
-
|
|
|
-static int qt_tiocmget(struct usb_serial_port *port, struct file * file)
|
|
|
+static int qt_tiocmget(struct usb_serial_port *port, struct file *file)
|
|
|
{
|
|
|
|
|
|
- __u8 MCR_Value;
|
|
|
- __u8 MSR_Value;
|
|
|
- unsigned int result = 0;
|
|
|
- int status;
|
|
|
- unsigned int UartNumber;
|
|
|
- struct tty_struct * tty;
|
|
|
+ __u8 MCR_Value;
|
|
|
+ __u8 MSR_Value;
|
|
|
+ unsigned int result = 0;
|
|
|
+ int status;
|
|
|
+ unsigned int UartNumber;
|
|
|
+ struct tty_struct *tty;
|
|
|
|
|
|
+ struct usb_serial *serial = get_usb_serial(port, __FUNCTION__);
|
|
|
+ if (serial == NULL)
|
|
|
+ return -ENODEV;
|
|
|
+ tty = port->tty;
|
|
|
|
|
|
- struct usb_serial *serial = get_usb_serial (port, __FUNCTION__);
|
|
|
- if(serial == NULL)
|
|
|
- return -ENODEV;
|
|
|
- tty = port->tty;
|
|
|
-
|
|
|
- mydbg("%s - port %d, tty =0x%p\n", __FUNCTION__, port->number, tty);
|
|
|
+ mydbg("%s - port %d, tty =0x%p\n", __FUNCTION__, port->number, tty);
|
|
|
|
|
|
/**************************************************************************************/
|
|
|
/** TIOCMGET
|
|
|
*/
|
|
|
- UartNumber = port->tty->index - serial->minor;
|
|
|
- status = BoxGetRegister(port->serial, UartNumber, MODEM_CONTROL_REGISTER, &MCR_Value);
|
|
|
- if (status >= 0)
|
|
|
- {
|
|
|
- status = BoxGetRegister(port->serial, UartNumber, MODEM_STATUS_REGISTER, &MSR_Value);
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- if (status >= 0)
|
|
|
- {
|
|
|
- result = ((MCR_Value & SERIAL_MCR_DTR) ? TIOCM_DTR: 0)
|
|
|
- //DTR IS SET
|
|
|
- | ((MCR_Value & SERIAL_MCR_RTS) ? TIOCM_RTS: 0)
|
|
|
- //RTS IS SET
|
|
|
- | ((MSR_Value & SERIAL_MSR_CTS) ? TIOCM_CTS: 0)
|
|
|
- //CTS is set
|
|
|
- | ((MSR_Value & SERIAL_MSR_CD) ? TIOCM_CAR: 0)
|
|
|
- //Carrier detect is set
|
|
|
- | ((MSR_Value & SERIAL_MSR_RI) ? TIOCM_RI: 0)
|
|
|
- //Ring indicator set
|
|
|
- | ((MSR_Value & SERIAL_MSR_DSR) ? TIOCM_DSR: 0);
|
|
|
- //DSR is set
|
|
|
- return result;
|
|
|
-
|
|
|
- }
|
|
|
- else
|
|
|
- return -ESPIPE;
|
|
|
- //endif tatus => 0
|
|
|
-}
|
|
|
-
|
|
|
+ UartNumber = port->tty->index - serial->minor;
|
|
|
+ status =
|
|
|
+ BoxGetRegister(port->serial, UartNumber, MODEM_CONTROL_REGISTER,
|
|
|
+ &MCR_Value);
|
|
|
+ if (status >= 0) {
|
|
|
+ status =
|
|
|
+ BoxGetRegister(port->serial, UartNumber,
|
|
|
+ MODEM_STATUS_REGISTER, &MSR_Value);
|
|
|
|
|
|
+ }
|
|
|
|
|
|
-static int serial_ioctl (struct tty_struct *tty, struct file * file, unsigned int cmd, unsigned long arg)
|
|
|
-{
|
|
|
+ if (status >= 0) {
|
|
|
+ result = ((MCR_Value & SERIAL_MCR_DTR) ? TIOCM_DTR : 0)
|
|
|
+ //DTR IS SET
|
|
|
+ | ((MCR_Value & SERIAL_MCR_RTS) ? TIOCM_RTS : 0)
|
|
|
+ //RTS IS SET
|
|
|
+ | ((MSR_Value & SERIAL_MSR_CTS) ? TIOCM_CTS : 0)
|
|
|
+ //CTS is set
|
|
|
+ | ((MSR_Value & SERIAL_MSR_CD) ? TIOCM_CAR : 0)
|
|
|
+ //Carrier detect is set
|
|
|
+ | ((MSR_Value & SERIAL_MSR_RI) ? TIOCM_RI : 0)
|
|
|
+ //Ring indicator set
|
|
|
+ | ((MSR_Value & SERIAL_MSR_DSR) ? TIOCM_DSR : 0);
|
|
|
+ //DSR is set
|
|
|
+ return result;
|
|
|
|
|
|
- struct usb_serial_port *port = (struct usb_serial_port *) tty->driver_data;
|
|
|
- struct usb_serial *serial = get_usb_serial (port, __FUNCTION__);
|
|
|
- int retval = -ENODEV;
|
|
|
- unsigned int UartNumber;
|
|
|
- mydbg("In %s \n", __FUNCTION__);
|
|
|
+ } else
|
|
|
+ return -ESPIPE;
|
|
|
+ //endif tatus => 0
|
|
|
+}
|
|
|
|
|
|
- if (!serial)
|
|
|
- return -ENODEV;
|
|
|
+static int serial_ioctl(struct tty_struct *tty, struct file *file,
|
|
|
+ unsigned int cmd, unsigned long arg)
|
|
|
+{
|
|
|
|
|
|
+ struct usb_serial_port *port =
|
|
|
+ (struct usb_serial_port *)tty->driver_data;
|
|
|
+ struct usb_serial *serial = get_usb_serial(port, __FUNCTION__);
|
|
|
+ int retval = -ENODEV;
|
|
|
+ unsigned int UartNumber;
|
|
|
+ mydbg("In %s \n", __FUNCTION__);
|
|
|
|
|
|
- UartNumber = port->tty->index - serial->minor;
|
|
|
+ if (!serial)
|
|
|
+ return -ENODEV;
|
|
|
|
|
|
+ UartNumber = port->tty->index - serial->minor;
|
|
|
|
|
|
- down (&port->sem);
|
|
|
+ down(&port->sem);
|
|
|
|
|
|
- mydbg("%s - port %d, cmd 0x%.4x\n", __FUNCTION__, port->number, cmd);
|
|
|
- mydbg ("%s - port->RxHolding = %d\n", __FUNCTION__, port->RxHolding);
|
|
|
+ mydbg("%s - port %d, cmd 0x%.4x\n", __FUNCTION__, port->number, cmd);
|
|
|
+ mydbg("%s - port->RxHolding = %d\n", __FUNCTION__, port->RxHolding);
|
|
|
|
|
|
- if (!port->open_count)
|
|
|
- {
|
|
|
- mydbg ("%s - port not open\n", __FUNCTION__);
|
|
|
- goto exit;
|
|
|
- }
|
|
|
+ if (!port->open_count) {
|
|
|
+ mydbg("%s - port not open\n", __FUNCTION__);
|
|
|
+ goto exit;
|
|
|
+ }
|
|
|
|
|
|
- retval = qt_ioctl(port, file, cmd, arg);
|
|
|
+ retval = qt_ioctl(port, file, cmd, arg);
|
|
|
|
|
|
- exit:
|
|
|
- up (&port->sem);
|
|
|
- return retval;
|
|
|
+exit:
|
|
|
+ up(&port->sem);
|
|
|
+ return retval;
|
|
|
}
|
|
|
-static int qt_ioctl(struct usb_serial_port *port, struct file * file, unsigned int cmd, unsigned long arg)
|
|
|
+static int qt_ioctl(struct usb_serial_port *port, struct file *file,
|
|
|
+ unsigned int cmd, unsigned long arg)
|
|
|
{
|
|
|
- __u8 MCR_Value;
|
|
|
- __u8 MSR_Value;
|
|
|
- unsigned short Prev_MSR_Value;
|
|
|
- unsigned int value, result = 0;
|
|
|
- int status;
|
|
|
- unsigned int UartNumber;
|
|
|
- struct tty_struct * tty;
|
|
|
-
|
|
|
-
|
|
|
- struct usb_serial *serial = get_usb_serial (port, __FUNCTION__);
|
|
|
- if(serial == NULL)
|
|
|
- return -ENODEV;
|
|
|
- tty = port->tty;
|
|
|
+ __u8 MCR_Value;
|
|
|
+ __u8 MSR_Value;
|
|
|
+ unsigned short Prev_MSR_Value;
|
|
|
+ unsigned int value, result = 0;
|
|
|
+ int status;
|
|
|
+ unsigned int UartNumber;
|
|
|
+ struct tty_struct *tty;
|
|
|
+
|
|
|
+ struct usb_serial *serial = get_usb_serial(port, __FUNCTION__);
|
|
|
+ if (serial == NULL)
|
|
|
+ return -ENODEV;
|
|
|
+ tty = port->tty;
|
|
|
|
|
|
- mydbg("%s - port %d, tty =0x%p\n", __FUNCTION__, port->number, tty);
|
|
|
+ mydbg("%s - port %d, tty =0x%p\n", __FUNCTION__, port->number, tty);
|
|
|
|
|
|
/**************************************************************************************/
|
|
|
/** TIOCMGET
|
|
|
*/
|
|
|
- UartNumber = port->tty->index - serial->minor;
|
|
|
-
|
|
|
- if(cmd == TIOCMGET)
|
|
|
- {
|
|
|
- MCR_Value = port->shadowMCR;
|
|
|
- MSR_Value = port->shadowMSR;
|
|
|
-
|
|
|
- {
|
|
|
- result = ((MCR_Value & SERIAL_MCR_DTR) ? TIOCM_DTR: 0)
|
|
|
- //DTR IS SET
|
|
|
- | ((MCR_Value & SERIAL_MCR_RTS) ? TIOCM_RTS: 0)
|
|
|
- //RTS IS SET
|
|
|
- | ((MSR_Value & SERIAL_MSR_CTS) ? TIOCM_CTS: 0)
|
|
|
- //CTS is set
|
|
|
- | ((MSR_Value & SERIAL_MSR_CD) ? TIOCM_CAR: 0)
|
|
|
- //Carrier detect is set
|
|
|
- | ((MSR_Value & SERIAL_MSR_RI) ? TIOCM_RI: 0)
|
|
|
- //Ring indicator set
|
|
|
- | ((MSR_Value & SERIAL_MSR_DSR) ? TIOCM_DSR: 0);
|
|
|
- //DSR is set
|
|
|
- if(copy_to_user((unsigned int *)arg, &result, sizeof(unsigned int)))
|
|
|
- return -EFAULT;
|
|
|
- return 0;
|
|
|
-
|
|
|
- }//endif tatus => 0
|
|
|
-
|
|
|
- }//endif(cmd == TIOCMGET)
|
|
|
+ UartNumber = port->tty->index - serial->minor;
|
|
|
+
|
|
|
+ if (cmd == TIOCMGET) {
|
|
|
+ MCR_Value = port->shadowMCR;
|
|
|
+ MSR_Value = port->shadowMSR;
|
|
|
+
|
|
|
+ {
|
|
|
+ result = ((MCR_Value & SERIAL_MCR_DTR) ? TIOCM_DTR : 0)
|
|
|
+ //DTR IS SET
|
|
|
+ | ((MCR_Value & SERIAL_MCR_RTS) ? TIOCM_RTS : 0)
|
|
|
+ //RTS IS SET
|
|
|
+ | ((MSR_Value & SERIAL_MSR_CTS) ? TIOCM_CTS : 0)
|
|
|
+ //CTS is set
|
|
|
+ | ((MSR_Value & SERIAL_MSR_CD) ? TIOCM_CAR : 0)
|
|
|
+ //Carrier detect is set
|
|
|
+ | ((MSR_Value & SERIAL_MSR_RI) ? TIOCM_RI : 0)
|
|
|
+ //Ring indicator set
|
|
|
+ | ((MSR_Value & SERIAL_MSR_DSR) ? TIOCM_DSR : 0);
|
|
|
+ //DSR is set
|
|
|
+ if (copy_to_user
|
|
|
+ ((unsigned int *)arg, &result,
|
|
|
+ sizeof(unsigned int)))
|
|
|
+ return -EFAULT;
|
|
|
+ return 0;
|
|
|
+
|
|
|
+ } //endif tatus => 0
|
|
|
+
|
|
|
+ } //endif(cmd == TIOCMGET)
|
|
|
/**************************************************************************************/
|
|
|
/** End TIOCMGET
|
|
|
*/
|
|
@@ -1910,110 +1801,115 @@ static int qt_ioctl(struct usb_serial_port *port, struct file * file, unsigned i
|
|
|
|
|
|
/**************************************************************************************/
|
|
|
|
|
|
- if(cmd == TIOCMBIS || cmd == TIOCMBIC || cmd == TIOCMSET)
|
|
|
- {
|
|
|
- status = BoxGetRegister(port->serial, UartNumber, MODEM_CONTROL_REGISTER, &MCR_Value);
|
|
|
- if (status < 0)
|
|
|
- return -ESPIPE;
|
|
|
- if (copy_from_user(&value, (unsigned int *)arg, sizeof(unsigned int)))
|
|
|
- return -EFAULT;
|
|
|
-
|
|
|
- switch (cmd)
|
|
|
- {
|
|
|
- case TIOCMBIS:
|
|
|
- if (value & TIOCM_RTS)
|
|
|
- MCR_Value |= SERIAL_MCR_RTS;
|
|
|
- if (value & TIOCM_DTR)
|
|
|
- MCR_Value |= SERIAL_MCR_DTR;
|
|
|
- if (value & TIOCM_LOOP)
|
|
|
- MCR_Value |= SERIAL_MCR_LOOP;
|
|
|
- break;
|
|
|
- case TIOCMBIC:
|
|
|
- if (value & TIOCM_RTS)
|
|
|
- MCR_Value &= ~SERIAL_MCR_RTS;
|
|
|
- if (value & TIOCM_DTR)
|
|
|
- MCR_Value &= ~SERIAL_MCR_DTR;
|
|
|
- if (value & TIOCM_LOOP)
|
|
|
- MCR_Value &= ~SERIAL_MCR_LOOP;
|
|
|
- break;
|
|
|
- case TIOCMSET:
|
|
|
- //Turn off the RTS and DTR and loopbcck and then only
|
|
|
- //trun on what was asked for
|
|
|
- MCR_Value &= ~(SERIAL_MCR_RTS | SERIAL_MCR_DTR | SERIAL_MCR_LOOP);
|
|
|
- if (value & TIOCM_RTS)
|
|
|
- MCR_Value |= SERIAL_MCR_RTS;
|
|
|
- if (value & TIOCM_DTR)
|
|
|
- MCR_Value |= SERIAL_MCR_DTR;
|
|
|
- if (value & TIOCM_LOOP)
|
|
|
- MCR_Value |= SERIAL_MCR_LOOP;
|
|
|
- break;
|
|
|
- default:
|
|
|
- break;
|
|
|
-
|
|
|
- }
|
|
|
- status = BoxSetRegister(port->serial, UartNumber, MODEM_CONTROL_REGISTER, MCR_Value);
|
|
|
- if (status < 0)
|
|
|
- return -ESPIPE;
|
|
|
- else
|
|
|
- {
|
|
|
- port->shadowMCR = MCR_Value;
|
|
|
- return 0;
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
- }
|
|
|
+ if (cmd == TIOCMBIS || cmd == TIOCMBIC || cmd == TIOCMSET) {
|
|
|
+ status =
|
|
|
+ BoxGetRegister(port->serial, UartNumber,
|
|
|
+ MODEM_CONTROL_REGISTER, &MCR_Value);
|
|
|
+ if (status < 0)
|
|
|
+ return -ESPIPE;
|
|
|
+ if (copy_from_user
|
|
|
+ (&value, (unsigned int *)arg, sizeof(unsigned int)))
|
|
|
+ return -EFAULT;
|
|
|
+
|
|
|
+ switch (cmd) {
|
|
|
+ case TIOCMBIS:
|
|
|
+ if (value & TIOCM_RTS)
|
|
|
+ MCR_Value |= SERIAL_MCR_RTS;
|
|
|
+ if (value & TIOCM_DTR)
|
|
|
+ MCR_Value |= SERIAL_MCR_DTR;
|
|
|
+ if (value & TIOCM_LOOP)
|
|
|
+ MCR_Value |= SERIAL_MCR_LOOP;
|
|
|
+ break;
|
|
|
+ case TIOCMBIC:
|
|
|
+ if (value & TIOCM_RTS)
|
|
|
+ MCR_Value &= ~SERIAL_MCR_RTS;
|
|
|
+ if (value & TIOCM_DTR)
|
|
|
+ MCR_Value &= ~SERIAL_MCR_DTR;
|
|
|
+ if (value & TIOCM_LOOP)
|
|
|
+ MCR_Value &= ~SERIAL_MCR_LOOP;
|
|
|
+ break;
|
|
|
+ case TIOCMSET:
|
|
|
+ //Turn off the RTS and DTR and loopbcck and then only
|
|
|
+ //trun on what was asked for
|
|
|
+ MCR_Value &=
|
|
|
+ ~(SERIAL_MCR_RTS | SERIAL_MCR_DTR |
|
|
|
+ SERIAL_MCR_LOOP);
|
|
|
+ if (value & TIOCM_RTS)
|
|
|
+ MCR_Value |= SERIAL_MCR_RTS;
|
|
|
+ if (value & TIOCM_DTR)
|
|
|
+ MCR_Value |= SERIAL_MCR_DTR;
|
|
|
+ if (value & TIOCM_LOOP)
|
|
|
+ MCR_Value |= SERIAL_MCR_LOOP;
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ break;
|
|
|
+
|
|
|
+ }
|
|
|
+ status =
|
|
|
+ BoxSetRegister(port->serial, UartNumber,
|
|
|
+ MODEM_CONTROL_REGISTER, MCR_Value);
|
|
|
+ if (status < 0)
|
|
|
+ return -ESPIPE;
|
|
|
+ else {
|
|
|
+ port->shadowMCR = MCR_Value;
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
/**************************************************************************************/
|
|
|
/** TIOCMBIS, TIOCMBIC, AND TIOCMSET end
|
|
|
*/
|
|
|
/**************************************************************************************/
|
|
|
|
|
|
- if(cmd == TIOCMIWAIT)
|
|
|
- {
|
|
|
- DECLARE_WAITQUEUE(wait, current);
|
|
|
- Prev_MSR_Value = port->shadowMSR & SERIAL_MSR_MASK;
|
|
|
- while(1)
|
|
|
- {
|
|
|
- add_wait_queue(&port->wait, &wait);
|
|
|
- set_current_state(TASK_INTERRUPTIBLE);
|
|
|
- schedule();
|
|
|
- remove_wait_queue(&port->wait, &wait);
|
|
|
- /* see if a signal woke us up */
|
|
|
- if(signal_pending(current))
|
|
|
- return -ERESTARTSYS;
|
|
|
- MSR_Value = port->shadowMSR & SERIAL_MSR_MASK;
|
|
|
- if(MSR_Value == Prev_MSR_Value)
|
|
|
- return -EIO; //no change error
|
|
|
-
|
|
|
- if((arg & TIOCM_RNG && ((Prev_MSR_Value & SERIAL_MSR_RI) ==
|
|
|
- (MSR_Value & SERIAL_MSR_RI))) ||
|
|
|
- (arg & TIOCM_DSR && ((Prev_MSR_Value & SERIAL_MSR_DSR) ==
|
|
|
- (MSR_Value & SERIAL_MSR_DSR))) ||
|
|
|
- (arg & TIOCM_CD && ((Prev_MSR_Value & SERIAL_MSR_CD) ==
|
|
|
- (MSR_Value & SERIAL_MSR_CD))) ||
|
|
|
- (arg & TIOCM_CTS && ((Prev_MSR_Value & SERIAL_MSR_CTS) ==
|
|
|
- (MSR_Value & SERIAL_MSR_CTS))))
|
|
|
- {
|
|
|
- return 0;
|
|
|
- }
|
|
|
-
|
|
|
- }//endwhile
|
|
|
-
|
|
|
- }
|
|
|
- mydbg("%s -No ioctl for that one. port = %d\n", __FUNCTION__, port->number);
|
|
|
-
|
|
|
-
|
|
|
- return -ENOIOCTLCMD;
|
|
|
+ if (cmd == TIOCMIWAIT) {
|
|
|
+ DECLARE_WAITQUEUE(wait, current);
|
|
|
+ Prev_MSR_Value = port->shadowMSR & SERIAL_MSR_MASK;
|
|
|
+ while (1) {
|
|
|
+ add_wait_queue(&port->wait, &wait);
|
|
|
+ set_current_state(TASK_INTERRUPTIBLE);
|
|
|
+ schedule();
|
|
|
+ remove_wait_queue(&port->wait, &wait);
|
|
|
+ /* see if a signal woke us up */
|
|
|
+ if (signal_pending(current))
|
|
|
+ return -ERESTARTSYS;
|
|
|
+ MSR_Value = port->shadowMSR & SERIAL_MSR_MASK;
|
|
|
+ if (MSR_Value == Prev_MSR_Value)
|
|
|
+ return -EIO; //no change error
|
|
|
+
|
|
|
+ if ((arg & TIOCM_RNG
|
|
|
+ && ((Prev_MSR_Value & SERIAL_MSR_RI) ==
|
|
|
+ (MSR_Value & SERIAL_MSR_RI)))
|
|
|
+ || (arg & TIOCM_DSR
|
|
|
+ && ((Prev_MSR_Value & SERIAL_MSR_DSR) ==
|
|
|
+ (MSR_Value & SERIAL_MSR_DSR)))
|
|
|
+ || (arg & TIOCM_CD
|
|
|
+ && ((Prev_MSR_Value & SERIAL_MSR_CD) ==
|
|
|
+ (MSR_Value & SERIAL_MSR_CD)))
|
|
|
+ || (arg & TIOCM_CTS
|
|
|
+ && ((Prev_MSR_Value & SERIAL_MSR_CTS) ==
|
|
|
+ (MSR_Value & SERIAL_MSR_CTS)))) {
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ } //endwhile
|
|
|
+
|
|
|
+ }
|
|
|
+ mydbg("%s -No ioctl for that one. port = %d\n", __FUNCTION__,
|
|
|
+ port->number);
|
|
|
+
|
|
|
+ return -ENOIOCTLCMD;
|
|
|
}
|
|
|
|
|
|
-static void serial_set_termios (struct tty_struct *tty, struct ktermios *old)
|
|
|
+static void serial_set_termios(struct tty_struct *tty, struct ktermios *old)
|
|
|
{
|
|
|
- struct usb_serial_port *port = (struct usb_serial_port *) tty->driver_data;
|
|
|
- struct usb_serial *serial = get_usb_serial (port, __FUNCTION__);
|
|
|
+ struct usb_serial_port *port =
|
|
|
+ (struct usb_serial_port *)tty->driver_data;
|
|
|
+ struct usb_serial *serial = get_usb_serial(port, __FUNCTION__);
|
|
|
|
|
|
if (!serial)
|
|
|
return;
|
|
|
|
|
|
- down (&port->sem);
|
|
|
+ down(&port->sem);
|
|
|
|
|
|
mydbg("%s - port %d\n", __FUNCTION__, port->number);
|
|
|
|
|
@@ -2023,210 +1919,197 @@ static void serial_set_termios (struct tty_struct *tty, struct ktermios *old)
|
|
|
}
|
|
|
|
|
|
/* pass on to the driver specific version of this function if it is available */
|
|
|
- qt_set_termios(port, old);
|
|
|
+ qt_set_termios(port, old);
|
|
|
|
|
|
exit:
|
|
|
- up (&port->sem);
|
|
|
+ up(&port->sem);
|
|
|
}
|
|
|
|
|
|
-static void qt_set_termios(struct usb_serial_port *port, struct ktermios *old_termios)
|
|
|
+static void qt_set_termios(struct usb_serial_port *port,
|
|
|
+ struct ktermios *old_termios)
|
|
|
{
|
|
|
- unsigned int cflag;
|
|
|
- int baud, divisor, remainder;
|
|
|
- unsigned char LCR_change_to = 0;
|
|
|
- struct tty_struct *tty;
|
|
|
- int status;
|
|
|
- struct usb_serial *serial;
|
|
|
- __u16 UartNumber;
|
|
|
- __u16 tmp, tmp2;
|
|
|
-
|
|
|
- mydbg("%s - port %d\n", __FUNCTION__, port->number);
|
|
|
-
|
|
|
- tmp = port->tty->index;
|
|
|
- mydbg("%s - MINOR(port->tty->index) = %d\n", __FUNCTION__, tmp);
|
|
|
-
|
|
|
-
|
|
|
- serial = port->serial;
|
|
|
- tmp2 = serial->minor;
|
|
|
- mydbg("%s - serial->minor = %d\n", __FUNCTION__, tmp2);
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
- UartNumber = port->tty->index - serial->minor;
|
|
|
-
|
|
|
- tty = port->tty;
|
|
|
-
|
|
|
- cflag = tty->termios->c_cflag;
|
|
|
-
|
|
|
- if (old_termios)
|
|
|
- {
|
|
|
- if((cflag == old_termios->c_cflag) && (RELEVANT_IFLAG(tty->termios->c_iflag) ==
|
|
|
- RELEVANT_IFLAG(old_termios->c_iflag)))
|
|
|
- {
|
|
|
- mydbg("%s - Nothing to change\n", __FUNCTION__);
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- mydbg("%s - 3\n", __FUNCTION__);
|
|
|
-
|
|
|
- switch(cflag)
|
|
|
- {
|
|
|
- case CS5:
|
|
|
- LCR_change_to |= SERIAL_5_DATA;
|
|
|
- break;
|
|
|
- case CS6:
|
|
|
- LCR_change_to |= SERIAL_6_DATA;
|
|
|
- break;
|
|
|
- case CS7:
|
|
|
- LCR_change_to |= SERIAL_7_DATA;
|
|
|
- break;
|
|
|
- default:
|
|
|
- case CS8:
|
|
|
- LCR_change_to |= SERIAL_8_DATA;
|
|
|
- break;
|
|
|
- }
|
|
|
-
|
|
|
- //Parity stuff
|
|
|
- if(cflag & PARENB)
|
|
|
- {
|
|
|
- if(cflag & PARODD)
|
|
|
- LCR_change_to |= SERIAL_ODD_PARITY;
|
|
|
- else
|
|
|
- LCR_change_to |= SERIAL_EVEN_PARITY;
|
|
|
- }
|
|
|
- if(cflag & CSTOPB)
|
|
|
- LCR_change_to |= SERIAL_TWO_STOPB;
|
|
|
- else
|
|
|
- LCR_change_to |= SERIAL_TWO_STOPB;
|
|
|
-
|
|
|
- mydbg("%s - 4\n", __FUNCTION__);
|
|
|
- //Thats the LCR stuff, go ahead and set it
|
|
|
- baud = tty_get_baud_rate(tty);
|
|
|
- if (!baud) {
|
|
|
- /* pick a default, any default... */
|
|
|
- baud = 9600;
|
|
|
- }
|
|
|
-
|
|
|
- mydbg("%s - got baud = %d\n", __FUNCTION__, baud);
|
|
|
-
|
|
|
-
|
|
|
- divisor = MAX_BAUD_RATE / baud;
|
|
|
- remainder = MAX_BAUD_RATE % baud;
|
|
|
- //Round to nearest divisor
|
|
|
- if(((remainder * 2) >= baud) && (baud != 110))
|
|
|
- divisor++;
|
|
|
-
|
|
|
- //Set Baud rate to default and turn off (default)flow control here
|
|
|
- status = BoxSetUart(serial, UartNumber, (unsigned short) divisor, LCR_change_to);
|
|
|
- if (status < 0)
|
|
|
- {
|
|
|
- mydbg(__FILE__"BoxSetUart failed\n");
|
|
|
- return;
|
|
|
- }
|
|
|
- //************************Now determine flow control
|
|
|
-
|
|
|
- if(cflag & CRTSCTS)
|
|
|
- {
|
|
|
- mydbg("%s - Enabling HW flow control port %d\n", __FUNCTION__, port->number);
|
|
|
-
|
|
|
- //Enable RTS/CTS flow control
|
|
|
- status = BoxSetHW_FlowCtrl(serial, UartNumber, 1);
|
|
|
-
|
|
|
- if (status < 0)
|
|
|
- {
|
|
|
- mydbg(__FILE__"BoxSetHW_FlowCtrl failed\n");
|
|
|
- return;
|
|
|
- }
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- //Disable RTS/CTS flow control
|
|
|
- mydbg("%s - disabling HW flow control port %d\n", __FUNCTION__, port->number);
|
|
|
-
|
|
|
- status = BoxSetHW_FlowCtrl(serial, UartNumber, 0);
|
|
|
- if (status < 0)
|
|
|
- {
|
|
|
- mydbg(__FILE__"BoxSetHW_FlowCtrl failed\n");
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- //*************************************************
|
|
|
- /* if we are implementing XON/XOFF, set the start and stop character in the device */
|
|
|
- if (I_IXOFF(tty) || I_IXON(tty))
|
|
|
- {
|
|
|
- unsigned char stop_char = STOP_CHAR(tty);
|
|
|
- unsigned char start_char = START_CHAR(tty);
|
|
|
- status = BoxSetSW_FlowCtrl(serial, UartNumber, stop_char, start_char);
|
|
|
- if(status < 0)
|
|
|
- mydbg(__FILE__"BoxSetSW_FlowCtrl (enabled) failed\n");
|
|
|
+ unsigned int cflag;
|
|
|
+ int baud, divisor, remainder;
|
|
|
+ unsigned char LCR_change_to = 0;
|
|
|
+ struct tty_struct *tty;
|
|
|
+ int status;
|
|
|
+ struct usb_serial *serial;
|
|
|
+ __u16 UartNumber;
|
|
|
+ __u16 tmp, tmp2;
|
|
|
+
|
|
|
+ mydbg("%s - port %d\n", __FUNCTION__, port->number);
|
|
|
+
|
|
|
+ tmp = port->tty->index;
|
|
|
+ mydbg("%s - MINOR(port->tty->index) = %d\n", __FUNCTION__, tmp);
|
|
|
+
|
|
|
+ serial = port->serial;
|
|
|
+ tmp2 = serial->minor;
|
|
|
+ mydbg("%s - serial->minor = %d\n", __FUNCTION__, tmp2);
|
|
|
+
|
|
|
+ UartNumber = port->tty->index - serial->minor;
|
|
|
+
|
|
|
+ tty = port->tty;
|
|
|
+
|
|
|
+ cflag = tty->termios->c_cflag;
|
|
|
+
|
|
|
+ if (old_termios) {
|
|
|
+ if ((cflag == old_termios->c_cflag)
|
|
|
+ && (RELEVANT_IFLAG(tty->termios->c_iflag) ==
|
|
|
+ RELEVANT_IFLAG(old_termios->c_iflag))) {
|
|
|
+ mydbg("%s - Nothing to change\n", __FUNCTION__);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ mydbg("%s - 3\n", __FUNCTION__);
|
|
|
+
|
|
|
+ switch (cflag) {
|
|
|
+ case CS5:
|
|
|
+ LCR_change_to |= SERIAL_5_DATA;
|
|
|
+ break;
|
|
|
+ case CS6:
|
|
|
+ LCR_change_to |= SERIAL_6_DATA;
|
|
|
+ break;
|
|
|
+ case CS7:
|
|
|
+ LCR_change_to |= SERIAL_7_DATA;
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ case CS8:
|
|
|
+ LCR_change_to |= SERIAL_8_DATA;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ //Parity stuff
|
|
|
+ if (cflag & PARENB) {
|
|
|
+ if (cflag & PARODD)
|
|
|
+ LCR_change_to |= SERIAL_ODD_PARITY;
|
|
|
+ else
|
|
|
+ LCR_change_to |= SERIAL_EVEN_PARITY;
|
|
|
+ }
|
|
|
+ if (cflag & CSTOPB)
|
|
|
+ LCR_change_to |= SERIAL_TWO_STOPB;
|
|
|
+ else
|
|
|
+ LCR_change_to |= SERIAL_TWO_STOPB;
|
|
|
+
|
|
|
+ mydbg("%s - 4\n", __FUNCTION__);
|
|
|
+ //Thats the LCR stuff, go ahead and set it
|
|
|
+ baud = tty_get_baud_rate(tty);
|
|
|
+ if (!baud) {
|
|
|
+ /* pick a default, any default... */
|
|
|
+ baud = 9600;
|
|
|
+ }
|
|
|
+
|
|
|
+ mydbg("%s - got baud = %d\n", __FUNCTION__, baud);
|
|
|
+
|
|
|
+ divisor = MAX_BAUD_RATE / baud;
|
|
|
+ remainder = MAX_BAUD_RATE % baud;
|
|
|
+ //Round to nearest divisor
|
|
|
+ if (((remainder * 2) >= baud) && (baud != 110))
|
|
|
+ divisor++;
|
|
|
+
|
|
|
+ //Set Baud rate to default and turn off (default)flow control here
|
|
|
+ status =
|
|
|
+ BoxSetUart(serial, UartNumber, (unsigned short)divisor,
|
|
|
+ LCR_change_to);
|
|
|
+ if (status < 0) {
|
|
|
+ mydbg(__FILE__ "BoxSetUart failed\n");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ //************************Now determine flow control
|
|
|
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- //disable SW flow control
|
|
|
- status = BoxDisable_SW_FlowCtrl(serial, UartNumber);
|
|
|
- if(status < 0)
|
|
|
- mydbg(__FILE__"BoxSetSW_FlowCtrl (diabling) failed\n");
|
|
|
+ if (cflag & CRTSCTS) {
|
|
|
+ mydbg("%s - Enabling HW flow control port %d\n", __FUNCTION__,
|
|
|
+ port->number);
|
|
|
|
|
|
- }
|
|
|
+ //Enable RTS/CTS flow control
|
|
|
+ status = BoxSetHW_FlowCtrl(serial, UartNumber, 1);
|
|
|
|
|
|
+ if (status < 0) {
|
|
|
+ mydbg(__FILE__ "BoxSetHW_FlowCtrl failed\n");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ //Disable RTS/CTS flow control
|
|
|
+ mydbg("%s - disabling HW flow control port %d\n", __FUNCTION__,
|
|
|
+ port->number);
|
|
|
+
|
|
|
+ status = BoxSetHW_FlowCtrl(serial, UartNumber, 0);
|
|
|
+ if (status < 0) {
|
|
|
+ mydbg(__FILE__ "BoxSetHW_FlowCtrl failed\n");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
|
|
|
+ //*************************************************
|
|
|
+ /* if we are implementing XON/XOFF, set the start and stop character in the device */
|
|
|
+ if (I_IXOFF(tty) || I_IXON(tty)) {
|
|
|
+ unsigned char stop_char = STOP_CHAR(tty);
|
|
|
+ unsigned char start_char = START_CHAR(tty);
|
|
|
+ status =
|
|
|
+ BoxSetSW_FlowCtrl(serial, UartNumber, stop_char,
|
|
|
+ start_char);
|
|
|
+ if (status < 0)
|
|
|
+ mydbg(__FILE__ "BoxSetSW_FlowCtrl (enabled) failed\n");
|
|
|
+
|
|
|
+ } else {
|
|
|
+ //disable SW flow control
|
|
|
+ status = BoxDisable_SW_FlowCtrl(serial, UartNumber);
|
|
|
+ if (status < 0)
|
|
|
+ mydbg(__FILE__ "BoxSetSW_FlowCtrl (diabling) failed\n");
|
|
|
+
|
|
|
+ }
|
|
|
|
|
|
}
|
|
|
+
|
|
|
/****************************************************************************
|
|
|
* BoxGetRegister
|
|
|
* issuse a GET_REGISTER vendor-spcific request on the default control pipe
|
|
|
* If successful, fills in the pValue with the register value asked for
|
|
|
****************************************************************************/
|
|
|
-static int BoxGetRegister(struct usb_serial *serial, unsigned short Uart_Number,
|
|
|
- unsigned short Register_Num, __u8 *pValue )
|
|
|
+static int BoxGetRegister(struct usb_serial *serial, unsigned short Uart_Number,
|
|
|
+ unsigned short Register_Num, __u8 * pValue)
|
|
|
{
|
|
|
- int result;
|
|
|
- __u16 current_length;
|
|
|
-
|
|
|
+ int result;
|
|
|
+ __u16 current_length;
|
|
|
|
|
|
- current_length = sizeof(struct qt_get_device_data);
|
|
|
+ current_length = sizeof(struct qt_get_device_data);
|
|
|
|
|
|
- result = usb_control_msg (serial->dev, usb_rcvctrlpipe(serial->dev, 0), QT_GET_SET_REGISTER,
|
|
|
- 0xC0, Register_Num, Uart_Number, (void *)pValue, sizeof(*pValue), 300);
|
|
|
+ result =
|
|
|
+ usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0),
|
|
|
+ QT_GET_SET_REGISTER, 0xC0, Register_Num,
|
|
|
+ Uart_Number, (void *)pValue, sizeof(*pValue), 300);
|
|
|
|
|
|
- return result;
|
|
|
+ return result;
|
|
|
}
|
|
|
+
|
|
|
/****************************************************************************
|
|
|
* BoxSetRegister
|
|
|
* issuse a GET_REGISTER vendor-spcific request on the default control pipe
|
|
|
* If successful, fills in the pValue with the register value asked for
|
|
|
****************************************************************************/
|
|
|
-static int BoxSetRegister(struct usb_serial *serial, unsigned short Uart_Number,
|
|
|
- unsigned short Register_Num, unsigned short Value )
|
|
|
+static int BoxSetRegister(struct usb_serial *serial, unsigned short Uart_Number,
|
|
|
+ unsigned short Register_Num, unsigned short Value)
|
|
|
{
|
|
|
- int result;
|
|
|
- unsigned short RegAndByte;
|
|
|
-
|
|
|
+ int result;
|
|
|
+ unsigned short RegAndByte;
|
|
|
|
|
|
- RegAndByte = Value;
|
|
|
- RegAndByte = RegAndByte << 8;
|
|
|
- RegAndByte = RegAndByte + Register_Num;
|
|
|
+ RegAndByte = Value;
|
|
|
+ RegAndByte = RegAndByte << 8;
|
|
|
+ RegAndByte = RegAndByte + Register_Num;
|
|
|
|
|
|
// result = usb_control_msg (serial->dev, usb_sndctrlpipe(serial->dev, 0), QT_GET_SET_REGISTER,
|
|
|
// 0xC0, Register_Num, Uart_Number, NULL, 0, 300);
|
|
|
|
|
|
+ result =
|
|
|
+ usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
|
|
|
+ QT_GET_SET_REGISTER, 0x40, RegAndByte, Uart_Number,
|
|
|
+ NULL, 0, 300);
|
|
|
|
|
|
- result = usb_control_msg (serial->dev, usb_sndctrlpipe(serial->dev, 0), QT_GET_SET_REGISTER,
|
|
|
- 0x40, RegAndByte, Uart_Number, NULL,0, 300);
|
|
|
-
|
|
|
-
|
|
|
- return result;
|
|
|
+ return result;
|
|
|
}
|
|
|
|
|
|
-
|
|
|
-
|
|
|
/**
|
|
|
* box_get_device
|
|
|
* Issue a GET_DEVICE vendor-specific request on the default control pipe If
|
|
@@ -2261,15 +2144,16 @@ static int box_get_device(struct usb_serial *serial,
|
|
|
* successful returns the number of bytes written, otherwise it returns a
|
|
|
* negative error number of the problem.
|
|
|
*/
|
|
|
-static int box_set_device(struct usb_serial *serial, struct qt_get_device_data *device_data)
|
|
|
+static int box_set_device(struct usb_serial *serial,
|
|
|
+ struct qt_get_device_data *device_data)
|
|
|
{
|
|
|
int result;
|
|
|
__u16 length;
|
|
|
__u16 PortSettings;
|
|
|
|
|
|
- PortSettings = ((__u16)(device_data->portb));
|
|
|
+ PortSettings = ((__u16) (device_data->portb));
|
|
|
PortSettings = (PortSettings << 8);
|
|
|
- PortSettings += ((__u16)(device_data->porta));
|
|
|
+ PortSettings += ((__u16) (device_data->porta));
|
|
|
|
|
|
length = sizeof(struct qt_get_device_data);
|
|
|
mydbg("%s - PortSettings = 0x%x\n", __FUNCTION__, PortSettings);
|
|
@@ -2286,35 +2170,36 @@ static int box_set_device(struct usb_serial *serial, struct qt_get_device_data *
|
|
|
* purpose is to allow the device driver and the device to synchronize state information.
|
|
|
* OpenClose = 1 for open , 0 for close
|
|
|
****************************************************************************/
|
|
|
-static int BoxOPenCloseChannel(struct usb_serial *serial, __u16 Uart_Number, __u16 OpenClose, struct qt_open_channel_data *pDeviceData)
|
|
|
+static int BoxOPenCloseChannel(struct usb_serial *serial, __u16 Uart_Number,
|
|
|
+ __u16 OpenClose,
|
|
|
+ struct qt_open_channel_data *pDeviceData)
|
|
|
{
|
|
|
- int result;
|
|
|
- __u16 length;
|
|
|
- __u8 Direcion;
|
|
|
- unsigned int pipe;
|
|
|
- length = sizeof(struct qt_open_channel_data);
|
|
|
-
|
|
|
- if (OpenClose == 1) //IF OPENING
|
|
|
- {
|
|
|
- Direcion = USBD_TRANSFER_DIRECTION_IN;
|
|
|
- pipe = usb_rcvctrlpipe(serial->dev, 0);
|
|
|
- result = usb_control_msg (serial->dev, pipe, QT_OPEN_CLOSE_CHANNEL,
|
|
|
- Direcion, OpenClose, Uart_Number, pDeviceData, length, 300);
|
|
|
-
|
|
|
-
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- Direcion = USBD_TRANSFER_DIRECTION_OUT;
|
|
|
- pipe = usb_sndctrlpipe(serial->dev, 0);
|
|
|
- result = usb_control_msg (serial->dev, pipe, QT_OPEN_CLOSE_CHANNEL,
|
|
|
- Direcion, OpenClose, Uart_Number, NULL, 0, 300);
|
|
|
-
|
|
|
- }
|
|
|
+ int result;
|
|
|
+ __u16 length;
|
|
|
+ __u8 Direcion;
|
|
|
+ unsigned int pipe;
|
|
|
+ length = sizeof(struct qt_open_channel_data);
|
|
|
|
|
|
+ if (OpenClose == 1) //IF OPENING
|
|
|
+ {
|
|
|
+ Direcion = USBD_TRANSFER_DIRECTION_IN;
|
|
|
+ pipe = usb_rcvctrlpipe(serial->dev, 0);
|
|
|
+ result =
|
|
|
+ usb_control_msg(serial->dev, pipe, QT_OPEN_CLOSE_CHANNEL,
|
|
|
+ Direcion, OpenClose, Uart_Number,
|
|
|
+ pDeviceData, length, 300);
|
|
|
+
|
|
|
+ } else {
|
|
|
+ Direcion = USBD_TRANSFER_DIRECTION_OUT;
|
|
|
+ pipe = usb_sndctrlpipe(serial->dev, 0);
|
|
|
+ result =
|
|
|
+ usb_control_msg(serial->dev, pipe, QT_OPEN_CLOSE_CHANNEL,
|
|
|
+ Direcion, OpenClose, Uart_Number, NULL, 0,
|
|
|
+ 300);
|
|
|
|
|
|
+ }
|
|
|
|
|
|
- return result;
|
|
|
+ return result;
|
|
|
}
|
|
|
|
|
|
/****************************************************************************
|
|
@@ -2333,24 +2218,22 @@ static int BoxSetPrebufferLevel(struct usb_serial *serial)
|
|
|
return result;
|
|
|
}
|
|
|
|
|
|
-
|
|
|
-
|
|
|
/****************************************************************************
|
|
|
* BoxSetATC
|
|
|
TELLS BOX WHEN TO ASSERT automatic transmitter control
|
|
|
****************************************************************************/
|
|
|
static int BoxSetATC(struct usb_serial *serial, __u16 n_Mode)
|
|
|
{
|
|
|
- int result;
|
|
|
- __u16 buffer_length;
|
|
|
-
|
|
|
+ int result;
|
|
|
+ __u16 buffer_length;
|
|
|
|
|
|
- buffer_length = PREFUFF_LEVEL_CONSERVATIVE;
|
|
|
+ buffer_length = PREFUFF_LEVEL_CONSERVATIVE;
|
|
|
|
|
|
- result = usb_control_msg (serial->dev, usb_sndctrlpipe(serial->dev, 0), QT_SET_ATF,
|
|
|
- 0x40, n_Mode, 0, NULL, 0, 300);
|
|
|
+ result =
|
|
|
+ usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
|
|
|
+ QT_SET_ATF, 0x40, n_Mode, 0, NULL, 0, 300);
|
|
|
|
|
|
- return result;
|
|
|
+ return result;
|
|
|
}
|
|
|
|
|
|
/****************************************************************************
|
|
@@ -2358,184 +2241,182 @@ static int BoxSetATC(struct usb_serial *serial, __u16 n_Mode)
|
|
|
* issuse a SET_UART vendor-spcific request on the default control pipe
|
|
|
* If successful sets baud rate divisor and LCR value
|
|
|
****************************************************************************/
|
|
|
-static int BoxSetUart(struct usb_serial *serial, unsigned short Uart_Number,
|
|
|
- unsigned short default_divisor, unsigned char default_LCR )
|
|
|
+static int BoxSetUart(struct usb_serial *serial, unsigned short Uart_Number,
|
|
|
+ unsigned short default_divisor, unsigned char default_LCR)
|
|
|
{
|
|
|
- int result;
|
|
|
- unsigned short UartNumandLCR;
|
|
|
+ int result;
|
|
|
+ unsigned short UartNumandLCR;
|
|
|
|
|
|
- UartNumandLCR = (default_LCR << 8) + Uart_Number;
|
|
|
+ UartNumandLCR = (default_LCR << 8) + Uart_Number;
|
|
|
|
|
|
- result = usb_control_msg (serial->dev, usb_sndctrlpipe(serial->dev, 0), QT_GET_SET_UART,
|
|
|
- 0x40, default_divisor, UartNumandLCR, NULL, 0, 300);
|
|
|
+ result =
|
|
|
+ usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
|
|
|
+ QT_GET_SET_UART, 0x40, default_divisor,
|
|
|
+ UartNumandLCR, NULL, 0, 300);
|
|
|
|
|
|
- return result;
|
|
|
+ return result;
|
|
|
}
|
|
|
|
|
|
-
|
|
|
-static int BoxSetHW_FlowCtrl(struct usb_serial *serial, unsigned int UartNumber, int bSet)
|
|
|
+static int BoxSetHW_FlowCtrl(struct usb_serial *serial, unsigned int UartNumber,
|
|
|
+ int bSet)
|
|
|
{
|
|
|
- __u8 MCR_Value = 0;
|
|
|
- __u8 MSR_Value = 0, MOUT_Value = 0;
|
|
|
- struct usb_serial_port *port;
|
|
|
- unsigned int status;
|
|
|
+ __u8 MCR_Value = 0;
|
|
|
+ __u8 MSR_Value = 0, MOUT_Value = 0;
|
|
|
+ struct usb_serial_port *port;
|
|
|
+ unsigned int status;
|
|
|
|
|
|
- port = serial->port;
|
|
|
+ port = serial->port;
|
|
|
|
|
|
- if (bSet == 1)
|
|
|
- {
|
|
|
- MCR_Value = SERIAL_MCR_RTS; //flow control, box will clear RTS line to prevent remote
|
|
|
- } //device from xmitting more chars
|
|
|
- else
|
|
|
- { //no flow control to remote device
|
|
|
- MCR_Value = 0;
|
|
|
+ if (bSet == 1) {
|
|
|
+ MCR_Value = SERIAL_MCR_RTS; //flow control, box will clear RTS line to prevent remote
|
|
|
+ } //device from xmitting more chars
|
|
|
+ else { //no flow control to remote device
|
|
|
+ MCR_Value = 0;
|
|
|
|
|
|
- }
|
|
|
- MOUT_Value = MCR_Value << 8;
|
|
|
-
|
|
|
-
|
|
|
- if(bSet == 1)
|
|
|
- {
|
|
|
- MSR_Value = SERIAL_MSR_CTS; //flow control, box will inhibit xmit data if CTS line is asserted
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- MSR_Value = 0; //Box will not inhimbe xmit data due to CTS line
|
|
|
- }
|
|
|
- MOUT_Value |= MSR_Value;
|
|
|
+ }
|
|
|
+ MOUT_Value = MCR_Value << 8;
|
|
|
|
|
|
+ if (bSet == 1) {
|
|
|
+ MSR_Value = SERIAL_MSR_CTS; //flow control, box will inhibit xmit data if CTS line is asserted
|
|
|
+ } else {
|
|
|
+ MSR_Value = 0; //Box will not inhimbe xmit data due to CTS line
|
|
|
+ }
|
|
|
+ MOUT_Value |= MSR_Value;
|
|
|
|
|
|
- status = usb_control_msg (serial->dev, usb_sndctrlpipe(serial->dev, 0), QT_HW_FLOW_CONTROL_MASK,
|
|
|
- 0x40, MOUT_Value, UartNumber, NULL, 0, 300);
|
|
|
- return status;
|
|
|
+ status =
|
|
|
+ usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
|
|
|
+ QT_HW_FLOW_CONTROL_MASK, 0x40, MOUT_Value,
|
|
|
+ UartNumber, NULL, 0, 300);
|
|
|
+ return status;
|
|
|
|
|
|
}
|
|
|
|
|
|
-static int BoxSetSW_FlowCtrl(struct usb_serial *serial, __u16 UartNumber, unsigned char stop_char, unsigned char start_char)
|
|
|
+static int BoxSetSW_FlowCtrl(struct usb_serial *serial, __u16 UartNumber,
|
|
|
+ unsigned char stop_char, unsigned char start_char)
|
|
|
{
|
|
|
- __u16 nSWflowout;
|
|
|
- int result;
|
|
|
+ __u16 nSWflowout;
|
|
|
+ int result;
|
|
|
|
|
|
- nSWflowout = start_char << 8;
|
|
|
- nSWflowout = (unsigned short)stop_char;
|
|
|
+ nSWflowout = start_char << 8;
|
|
|
+ nSWflowout = (unsigned short)stop_char;
|
|
|
|
|
|
- result = usb_control_msg (serial->dev, usb_sndctrlpipe(serial->dev, 0), QT_SW_FLOW_CONTROL_MASK,
|
|
|
- 0x40, nSWflowout, UartNumber, NULL, 0, 300);
|
|
|
- return result;
|
|
|
+ result =
|
|
|
+ usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
|
|
|
+ QT_SW_FLOW_CONTROL_MASK, 0x40, nSWflowout,
|
|
|
+ UartNumber, NULL, 0, 300);
|
|
|
+ return result;
|
|
|
|
|
|
}
|
|
|
static int BoxDisable_SW_FlowCtrl(struct usb_serial *serial, __u16 UartNumber)
|
|
|
{
|
|
|
- int result;
|
|
|
-
|
|
|
+ int result;
|
|
|
|
|
|
- result = usb_control_msg (serial->dev, usb_sndctrlpipe(serial->dev, 0), QT_SW_FLOW_CONTROL_DISABLE,
|
|
|
- 0x40, 0, UartNumber, NULL, 0, 300);
|
|
|
- return result;
|
|
|
+ result =
|
|
|
+ usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
|
|
|
+ QT_SW_FLOW_CONTROL_DISABLE, 0x40, 0, UartNumber,
|
|
|
+ NULL, 0, 300);
|
|
|
+ return result;
|
|
|
|
|
|
}
|
|
|
|
|
|
-
|
|
|
/*****************************************************************************
|
|
|
* SerialThrottle
|
|
|
* this function is called by the tty driver when it wants to stop the data
|
|
|
* being read from the port.
|
|
|
*****************************************************************************/
|
|
|
|
|
|
-
|
|
|
-static void serial_throttle (struct tty_struct * tty)
|
|
|
+static void serial_throttle(struct tty_struct *tty)
|
|
|
{
|
|
|
- struct usb_serial_port *port = (struct usb_serial_port *) tty->driver_data;
|
|
|
- struct usb_serial *serial = get_usb_serial (port, __FUNCTION__);
|
|
|
- mydbg("%s - port %d\n", __FUNCTION__, port->number);
|
|
|
+ struct usb_serial_port *port =
|
|
|
+ (struct usb_serial_port *)tty->driver_data;
|
|
|
+ struct usb_serial *serial = get_usb_serial(port, __FUNCTION__);
|
|
|
+ mydbg("%s - port %d\n", __FUNCTION__, port->number);
|
|
|
|
|
|
if (!serial)
|
|
|
return;
|
|
|
|
|
|
- down (&port->sem);
|
|
|
-
|
|
|
+ down(&port->sem);
|
|
|
|
|
|
if (!port->open_count) {
|
|
|
- mydbg ("%s - port not open\n", __FUNCTION__);
|
|
|
+ mydbg("%s - port not open\n", __FUNCTION__);
|
|
|
goto exit;
|
|
|
}
|
|
|
- //shut down any bulk reads that may be going on
|
|
|
-// usb_unlink_urb (port->read_urb);
|
|
|
+ //shut down any bulk reads that may be going on
|
|
|
+// usb_unlink_urb (port->read_urb);
|
|
|
/* pass on to the driver specific version of this function */
|
|
|
- port->RxHolding = 1;
|
|
|
- mydbg("%s - port->RxHolding = 1\n", __FUNCTION__);
|
|
|
-
|
|
|
+ port->RxHolding = 1;
|
|
|
+ mydbg("%s - port->RxHolding = 1\n", __FUNCTION__);
|
|
|
|
|
|
exit:
|
|
|
- up (&port->sem);
|
|
|
- return;
|
|
|
+ up(&port->sem);
|
|
|
+ return;
|
|
|
}
|
|
|
|
|
|
-static void serial_unthrottle (struct tty_struct * tty)
|
|
|
+static void serial_unthrottle(struct tty_struct *tty)
|
|
|
{
|
|
|
- struct usb_serial_port *port = (struct usb_serial_port *) tty->driver_data;
|
|
|
- struct usb_serial *serial = get_usb_serial (port, __FUNCTION__);
|
|
|
- unsigned int result;
|
|
|
+ struct usb_serial_port *port =
|
|
|
+ (struct usb_serial_port *)tty->driver_data;
|
|
|
+ struct usb_serial *serial = get_usb_serial(port, __FUNCTION__);
|
|
|
+ unsigned int result;
|
|
|
|
|
|
if (!serial)
|
|
|
return;
|
|
|
- down (&port->sem);
|
|
|
+ down(&port->sem);
|
|
|
|
|
|
mydbg("%s - port %d\n", __FUNCTION__, port->number);
|
|
|
|
|
|
if (!port->open_count) {
|
|
|
- mydbg ("%s - port not open\n", __FUNCTION__);
|
|
|
+ mydbg("%s - port not open\n", __FUNCTION__);
|
|
|
goto exit;
|
|
|
}
|
|
|
|
|
|
- if(port->RxHolding == 1)
|
|
|
- {
|
|
|
- mydbg ("%s -port->RxHolding == 1\n", __FUNCTION__);
|
|
|
-
|
|
|
- port->RxHolding = 0;
|
|
|
- mydbg ("%s - port->RxHolding = 0\n", __FUNCTION__);
|
|
|
-
|
|
|
- /* if we have a bulk endpoint, start it up */
|
|
|
- if ((serial->num_bulk_in) && (port->ReadBulkStopped == 1))
|
|
|
- {
|
|
|
- /* Start reading from the device */
|
|
|
- usb_fill_bulk_urb (port->read_urb, serial->dev,
|
|
|
- usb_rcvbulkpipe(serial->dev, port->bulk_in_endpointAddress),
|
|
|
- port->read_urb->transfer_buffer,
|
|
|
- port->read_urb->transfer_buffer_length,
|
|
|
- qt_read_bulk_callback,
|
|
|
- port);
|
|
|
- result = usb_submit_urb(port->read_urb, GFP_ATOMIC);
|
|
|
- if (result)
|
|
|
- err("%s - failed restarting read urb, error %d", __FUNCTION__, result);
|
|
|
- }
|
|
|
- }
|
|
|
- exit:
|
|
|
- up (&port->sem);
|
|
|
- return;
|
|
|
-
|
|
|
-
|
|
|
+ if (port->RxHolding == 1) {
|
|
|
+ mydbg("%s -port->RxHolding == 1\n", __FUNCTION__);
|
|
|
+
|
|
|
+ port->RxHolding = 0;
|
|
|
+ mydbg("%s - port->RxHolding = 0\n", __FUNCTION__);
|
|
|
+
|
|
|
+ /* if we have a bulk endpoint, start it up */
|
|
|
+ if ((serial->num_bulk_in) && (port->ReadBulkStopped == 1)) {
|
|
|
+ /* Start reading from the device */
|
|
|
+ usb_fill_bulk_urb(port->read_urb, serial->dev,
|
|
|
+ usb_rcvbulkpipe(serial->dev,
|
|
|
+ port->
|
|
|
+ bulk_in_endpointAddress),
|
|
|
+ port->read_urb->transfer_buffer,
|
|
|
+ port->read_urb->
|
|
|
+ transfer_buffer_length,
|
|
|
+ qt_read_bulk_callback, port);
|
|
|
+ result = usb_submit_urb(port->read_urb, GFP_ATOMIC);
|
|
|
+ if (result)
|
|
|
+ err("%s - failed restarting read urb, error %d",
|
|
|
+ __FUNCTION__, result);
|
|
|
+ }
|
|
|
+ }
|
|
|
+exit:
|
|
|
+ up(&port->sem);
|
|
|
+ return;
|
|
|
|
|
|
}
|
|
|
|
|
|
-
|
|
|
-static int serial_break (struct tty_struct *tty, int break_state)
|
|
|
+static int serial_break(struct tty_struct *tty, int break_state)
|
|
|
{
|
|
|
- struct usb_serial_port *port = (struct usb_serial_port *) tty->driver_data;
|
|
|
- struct usb_serial *serial = get_usb_serial (port, __FUNCTION__);
|
|
|
- __u16 UartNumber, Break_Value;
|
|
|
- unsigned int result;
|
|
|
+ struct usb_serial_port *port =
|
|
|
+ (struct usb_serial_port *)tty->driver_data;
|
|
|
+ struct usb_serial *serial = get_usb_serial(port, __FUNCTION__);
|
|
|
+ __u16 UartNumber, Break_Value;
|
|
|
+ unsigned int result;
|
|
|
|
|
|
- UartNumber = port->tty->index - serial->minor;
|
|
|
+ UartNumber = port->tty->index - serial->minor;
|
|
|
if (!serial)
|
|
|
return -ENODEV;
|
|
|
|
|
|
- if(break_state == -1)
|
|
|
- Break_Value = 1;
|
|
|
- else
|
|
|
- Break_Value = 0;
|
|
|
+ if (break_state == -1)
|
|
|
+ Break_Value = 1;
|
|
|
+ else
|
|
|
+ Break_Value = 0;
|
|
|
|
|
|
- down (&port->sem);
|
|
|
+ down(&port->sem);
|
|
|
|
|
|
mydbg("%s - port %d\n", __FUNCTION__, port->number);
|
|
|
|
|
@@ -2544,18 +2425,18 @@ static int serial_break (struct tty_struct *tty, int break_state)
|
|
|
goto exit;
|
|
|
}
|
|
|
|
|
|
- result = usb_control_msg (serial->dev, usb_sndctrlpipe(serial->dev, 0), QT_BREAK_CONTROL,
|
|
|
- 0x40, Break_Value, UartNumber, NULL, 0, 300);
|
|
|
+ result =
|
|
|
+ usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
|
|
|
+ QT_BREAK_CONTROL, 0x40, Break_Value, UartNumber,
|
|
|
+ NULL, 0, 300);
|
|
|
|
|
|
exit:
|
|
|
- up (&port->sem);
|
|
|
+ up(&port->sem);
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-static int serial_read_proc (char *page, char **start, off_t off, int count, int *eof, void *data)
|
|
|
+static int serial_read_proc(char *page, char **start, off_t off, int count,
|
|
|
+ int *eof, void *data)
|
|
|
{
|
|
|
struct usb_serial *serial;
|
|
|
int length = 0;
|
|
@@ -2563,21 +2444,26 @@ static int serial_read_proc (char *page, char **start, off_t off, int count, int
|
|
|
off_t begin = 0;
|
|
|
|
|
|
mydbg("%s\n", __FUNCTION__);
|
|
|
- length += sprintf (page, "usbserinfo:1.0 driver:%s\n", DRIVER_VERSION);
|
|
|
+ length += sprintf(page, "usbserinfo:1.0 driver:%s\n", DRIVER_VERSION);
|
|
|
for (i = 0; i < SERIAL_TTY_MINORS && length < PAGE_SIZE; ++i) {
|
|
|
serial = get_serial_by_minor(i);
|
|
|
if (serial == NULL)
|
|
|
continue;
|
|
|
|
|
|
- length += sprintf (page+length, "%d:\n", i);
|
|
|
- length += sprintf (page+length, " vendor:%04x product:%04x\n", serial->vendor, serial->product);
|
|
|
- length += sprintf (page+length, " num_ports:%d\n", serial->num_ports);
|
|
|
- length += sprintf (page+length, " port:%d\n", i - serial->minor + 1);
|
|
|
+ length += sprintf(page + length, "%d:\n", i);
|
|
|
+ length +=
|
|
|
+ sprintf(page + length, " vendor:%04x product:%04x\n",
|
|
|
+ serial->vendor, serial->product);
|
|
|
+ length +=
|
|
|
+ sprintf(page + length, " num_ports:%d\n",
|
|
|
+ serial->num_ports);
|
|
|
+ length +=
|
|
|
+ sprintf(page + length, " port:%d\n", i - serial->minor + 1);
|
|
|
|
|
|
-// usb_make_path(serial->dev, tmp, sizeof(tmp));
|
|
|
-// length += sprintf (page+length, " path:%s", tmp);
|
|
|
+// usb_make_path(serial->dev, tmp, sizeof(tmp));
|
|
|
+// length += sprintf (page+length, " path:%s", tmp);
|
|
|
|
|
|
- length += sprintf (page+length, "\n");
|
|
|
+ length += sprintf(page + length, "\n");
|
|
|
if ((length + begin) > (off + count))
|
|
|
goto done;
|
|
|
if ((length + begin) < off) {
|
|
@@ -2589,348 +2475,323 @@ static int serial_read_proc (char *page, char **start, off_t off, int count, int
|
|
|
done:
|
|
|
if (off >= (length + begin))
|
|
|
return 0;
|
|
|
- *start = page + (off-begin);
|
|
|
- return ((count < begin+length-off) ? count : begin+length-off);
|
|
|
+ *start = page + (off - begin);
|
|
|
+ return ((count < begin + length - off) ? count : begin + length - off);
|
|
|
}
|
|
|
|
|
|
-
|
|
|
-
|
|
|
-int ioctl_serial_usb (struct inode *innod, struct file *filp, unsigned int cmd,
|
|
|
- unsigned long arg)
|
|
|
+int ioctl_serial_usb(struct inode *innod, struct file *filp, unsigned int cmd,
|
|
|
+ unsigned long arg)
|
|
|
{
|
|
|
|
|
|
- unsigned err;
|
|
|
- unsigned ucOPR_NewValue, uc_Value;
|
|
|
- int *p_Num_of_adapters, counts, index, *p_QMCR_Value;
|
|
|
- struct identity *p_Identity_of;
|
|
|
- struct identity Identity_of;
|
|
|
- struct usb_serial *lastserial, *serial;
|
|
|
-
|
|
|
- mydbg(KERN_DEBUG"ioctl_serial_usb cmd =\n");
|
|
|
- if (_IOC_TYPE(cmd) != SERIALQT_PCI_IOC_MAGIC)
|
|
|
- return -ENOTTY;
|
|
|
- if (_IOC_NR(cmd) > SERIALQT_IOC_MAXNR)
|
|
|
- return -ENOTTY;
|
|
|
- mydbg(KERN_DEBUG"ioctl_serial_usb cmd = 0x%x\n", cmd);
|
|
|
- err = 0;
|
|
|
- switch (cmd)
|
|
|
- {
|
|
|
-
|
|
|
-
|
|
|
- case SERIALQT_WRITE_QMCR:
|
|
|
- err = -ENOTTY; //initialize as error so if we don't find this one we give//an error.
|
|
|
- index = arg >> 16;
|
|
|
- counts = 0;
|
|
|
-
|
|
|
- ucOPR_NewValue = arg;
|
|
|
-
|
|
|
-
|
|
|
- err = EmulateWriteQMCR_Reg(index, ucOPR_NewValue);
|
|
|
- break;
|
|
|
-
|
|
|
- case SERIALQT_READ_QMCR:
|
|
|
- err = -ENOTTY; //initialize as error so if we don't find this one we give
|
|
|
- //an error.
|
|
|
- p_QMCR_Value = (int *)arg;
|
|
|
- index = arg >> 16;
|
|
|
- counts = 0;
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
- err = EmulateReadQMCR_Reg(index, &uc_Value);
|
|
|
- if (err == 0)
|
|
|
- {
|
|
|
- err = put_user(uc_Value, p_QMCR_Value);
|
|
|
- }
|
|
|
- break;
|
|
|
-
|
|
|
- case SERIALQT_GET_NUMOF_UNITS:
|
|
|
- p_Num_of_adapters = (int *)arg;
|
|
|
- counts = 0; //Initialize counts to zero
|
|
|
- //struct usb_serial *lastserial = serial_table[0], *serial;
|
|
|
- lastserial = serial_table[0];
|
|
|
-
|
|
|
- mydbg(KERN_DEBUG"SERIALQT_GET_NUMOF_UNITS \n");
|
|
|
- //if first pointer is nonull, we at least have one box
|
|
|
- if(lastserial)
|
|
|
- counts = 1; //we at least have one box
|
|
|
-
|
|
|
- for (index = 1; index < SERIAL_TTY_MINORS ; index++)
|
|
|
- {
|
|
|
- serial = serial_table[index];
|
|
|
- if(serial)
|
|
|
- {
|
|
|
- if(serial != lastserial)
|
|
|
- {
|
|
|
- //we had a change in the array, hence another box is there
|
|
|
- lastserial = serial;
|
|
|
- counts++;
|
|
|
- }
|
|
|
- }
|
|
|
- else
|
|
|
- break;
|
|
|
- }
|
|
|
-
|
|
|
- mydbg(KERN_DEBUG"ioctl_serial_usb writting counts = %d", counts);
|
|
|
-
|
|
|
- err = put_user(counts, p_Num_of_adapters);
|
|
|
-
|
|
|
-
|
|
|
- break;
|
|
|
- case SERIALQT_GET_THIS_UNIT:
|
|
|
- counts = 0;
|
|
|
- p_Identity_of = (struct identity *)arg;
|
|
|
- //copy user structure to local variable
|
|
|
- get_user(Identity_of.index, &p_Identity_of->index);
|
|
|
- mydbg(KERN_DEBUG"SERIALQT_GET_THIS_UNIT Identity_of.index\n");
|
|
|
- mydbg(KERN_DEBUG"SERIALQT_GET_THIS_UNIT Identity_of.index= 0x%x\n", Identity_of.index);
|
|
|
-
|
|
|
- err = -ENOTTY; //initialize as error so if we don't find this one we give
|
|
|
- //an error.
|
|
|
- serial = find_the_box(Identity_of.index);
|
|
|
- if(serial)
|
|
|
- {
|
|
|
- err = put_user(serial->product, &p_Identity_of->n_identity);
|
|
|
+ unsigned err;
|
|
|
+ unsigned ucOPR_NewValue, uc_Value;
|
|
|
+ int *p_Num_of_adapters, counts, index, *p_QMCR_Value;
|
|
|
+ struct identity *p_Identity_of;
|
|
|
+ struct identity Identity_of;
|
|
|
+ struct usb_serial *lastserial, *serial;
|
|
|
+
|
|
|
+ mydbg(KERN_DEBUG "ioctl_serial_usb cmd =\n");
|
|
|
+ if (_IOC_TYPE(cmd) != SERIALQT_PCI_IOC_MAGIC)
|
|
|
+ return -ENOTTY;
|
|
|
+ if (_IOC_NR(cmd) > SERIALQT_IOC_MAXNR)
|
|
|
+ return -ENOTTY;
|
|
|
+ mydbg(KERN_DEBUG "ioctl_serial_usb cmd = 0x%x\n", cmd);
|
|
|
+ err = 0;
|
|
|
+ switch (cmd) {
|
|
|
+
|
|
|
+ case SERIALQT_WRITE_QMCR:
|
|
|
+ err = -ENOTTY; //initialize as error so if we don't find this one we give//an error.
|
|
|
+ index = arg >> 16;
|
|
|
+ counts = 0;
|
|
|
+
|
|
|
+ ucOPR_NewValue = arg;
|
|
|
+
|
|
|
+ err = EmulateWriteQMCR_Reg(index, ucOPR_NewValue);
|
|
|
+ break;
|
|
|
+
|
|
|
+ case SERIALQT_READ_QMCR:
|
|
|
+ err = -ENOTTY; //initialize as error so if we don't find this one we give
|
|
|
+ //an error.
|
|
|
+ p_QMCR_Value = (int *)arg;
|
|
|
+ index = arg >> 16;
|
|
|
+ counts = 0;
|
|
|
+
|
|
|
+ err = EmulateReadQMCR_Reg(index, &uc_Value);
|
|
|
+ if (err == 0) {
|
|
|
+ err = put_user(uc_Value, p_QMCR_Value);
|
|
|
+ }
|
|
|
+ break;
|
|
|
+
|
|
|
+ case SERIALQT_GET_NUMOF_UNITS:
|
|
|
+ p_Num_of_adapters = (int *)arg;
|
|
|
+ counts = 0; //Initialize counts to zero
|
|
|
+ //struct usb_serial *lastserial = serial_table[0], *serial;
|
|
|
+ lastserial = serial_table[0];
|
|
|
+
|
|
|
+ mydbg(KERN_DEBUG "SERIALQT_GET_NUMOF_UNITS \n");
|
|
|
+ //if first pointer is nonull, we at least have one box
|
|
|
+ if (lastserial)
|
|
|
+ counts = 1; //we at least have one box
|
|
|
+
|
|
|
+ for (index = 1; index < SERIAL_TTY_MINORS; index++) {
|
|
|
+ serial = serial_table[index];
|
|
|
+ if (serial) {
|
|
|
+ if (serial != lastserial) {
|
|
|
+ //we had a change in the array, hence another box is there
|
|
|
+ lastserial = serial;
|
|
|
+ counts++;
|
|
|
+ }
|
|
|
+ } else
|
|
|
+ break;
|
|
|
+ }
|
|
|
|
|
|
- }
|
|
|
- break;
|
|
|
+ mydbg(KERN_DEBUG "ioctl_serial_usb writting counts = %d",
|
|
|
+ counts);
|
|
|
+
|
|
|
+ err = put_user(counts, p_Num_of_adapters);
|
|
|
+
|
|
|
+ break;
|
|
|
+ case SERIALQT_GET_THIS_UNIT:
|
|
|
+ counts = 0;
|
|
|
+ p_Identity_of = (struct identity *)arg;
|
|
|
+ //copy user structure to local variable
|
|
|
+ get_user(Identity_of.index, &p_Identity_of->index);
|
|
|
+ mydbg(KERN_DEBUG "SERIALQT_GET_THIS_UNIT Identity_of.index\n");
|
|
|
+ mydbg(KERN_DEBUG
|
|
|
+ "SERIALQT_GET_THIS_UNIT Identity_of.index= 0x%x\n",
|
|
|
+ Identity_of.index);
|
|
|
+
|
|
|
+ err = -ENOTTY; //initialize as error so if we don't find this one we give
|
|
|
+ //an error.
|
|
|
+ serial = find_the_box(Identity_of.index);
|
|
|
+ if (serial) {
|
|
|
+ err =
|
|
|
+ put_user(serial->product,
|
|
|
+ &p_Identity_of->n_identity);
|
|
|
|
|
|
- case SERIALQT_IS422_EXTENDED:
|
|
|
- err = -ENOTTY; //initialize as error so if we don't find this one we give
|
|
|
- mydbg(KERN_DEBUG"SERIALQT_IS422_EXTENDED \n");
|
|
|
- //an error.
|
|
|
- index = arg >> 16;
|
|
|
+ }
|
|
|
+ break;
|
|
|
+
|
|
|
+ case SERIALQT_IS422_EXTENDED:
|
|
|
+ err = -ENOTTY; //initialize as error so if we don't find this one we give
|
|
|
+ mydbg(KERN_DEBUG "SERIALQT_IS422_EXTENDED \n");
|
|
|
+ //an error.
|
|
|
+ index = arg >> 16;
|
|
|
+
|
|
|
+ counts = 0;
|
|
|
+
|
|
|
+ mydbg(KERN_DEBUG
|
|
|
+ "SERIALQT_IS422_EXTENDED, looking Identity_of.indext = 0x%x\n",
|
|
|
+ index);
|
|
|
+ serial = find_the_box(index);
|
|
|
+ if (serial) {
|
|
|
+ mydbg("%s index = 0x%x, serial = 0x%p\n", __FUNCTION__,
|
|
|
+ index, serial);
|
|
|
+ for (counts = 0; serqt_422_table[counts] != 0; counts++) {
|
|
|
+
|
|
|
+ mydbg
|
|
|
+ ("%s serial->product = = 0x%x, serqt_422_table[counts] = 0x%x\n",
|
|
|
+ __FUNCTION__, serial->product,
|
|
|
+ serqt_422_table[counts]);
|
|
|
+ if (serial->product == serqt_422_table[counts]) {
|
|
|
+ err = 0;
|
|
|
+
|
|
|
+ mydbg
|
|
|
+ ("%s found match for 422extended\n",
|
|
|
+ __FUNCTION__);
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ break;
|
|
|
|
|
|
+ default:
|
|
|
+ err = -ENOTTY;
|
|
|
|
|
|
- counts = 0;
|
|
|
+ } //End switch
|
|
|
|
|
|
- mydbg(KERN_DEBUG"SERIALQT_IS422_EXTENDED, looking Identity_of.indext = 0x%x\n",index);
|
|
|
- serial = find_the_box(index);
|
|
|
- if(serial)
|
|
|
- {
|
|
|
- mydbg("%s index = 0x%x, serial = 0x%p\n", __FUNCTION__, index, serial);
|
|
|
- for (counts = 0; serqt_422_table[counts] != 0; counts++)
|
|
|
- {
|
|
|
+ mydbg("%s returning err = 0x%x\n", __FUNCTION__, err);
|
|
|
+ return err;
|
|
|
+}
|
|
|
|
|
|
- mydbg("%s serial->product = = 0x%x, serqt_422_table[counts] = 0x%x\n", __FUNCTION__, serial->product, serqt_422_table[counts]);
|
|
|
- if(serial->product == serqt_422_table[counts])
|
|
|
- {
|
|
|
- err = 0;
|
|
|
+static struct usb_serial *find_the_box(unsigned int index)
|
|
|
+{
|
|
|
+ struct usb_serial *lastserial, *foundserial, *serial;
|
|
|
+ int counts = 0, index2;
|
|
|
+ lastserial = serial_table[0];
|
|
|
+ foundserial = NULL;
|
|
|
+ for (index2 = 0; index2 < SERIAL_TTY_MINORS; index2++) {
|
|
|
+ serial = serial_table[index2];
|
|
|
+
|
|
|
+ mydbg("%s index = 0x%x, index2 = 0x%x, serial = 0x%p\n",
|
|
|
+ __FUNCTION__, index, index2, serial);
|
|
|
+
|
|
|
+ if (serial) {
|
|
|
+ //first see if this is the unit we'er looking for
|
|
|
+ mydbg
|
|
|
+ ("%s inside if(serial) counts = 0x%x , index = 0x%x\n",
|
|
|
+ __FUNCTION__, counts, index);
|
|
|
+ if (counts == index) {
|
|
|
+ //we found the one we're looking for, copythe product Id to user
|
|
|
+
|
|
|
+ mydbg
|
|
|
+ ("%s we found the one we're looking for serial = 0x%p\n",
|
|
|
+ __FUNCTION__, serial);
|
|
|
+ foundserial = serial;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (serial != lastserial) {
|
|
|
+ //when we have a change in the pointer
|
|
|
+ lastserial = serial;
|
|
|
+ counts++;
|
|
|
+ }
|
|
|
+ } else
|
|
|
+ break; // no matches
|
|
|
+ }
|
|
|
|
|
|
- mydbg("%s found match for 422extended\n", __FUNCTION__);
|
|
|
- break;
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- break;
|
|
|
+ mydbg("%s returning foundserial = 0x%p\n", __FUNCTION__, foundserial);
|
|
|
+ return foundserial;
|
|
|
+}
|
|
|
|
|
|
+static int EmulateWriteQMCR_Reg(int index, unsigned uc_value)
|
|
|
+{
|
|
|
|
|
|
+ __u16 ATC_Mode = 0;
|
|
|
+ struct usb_serial *serial;
|
|
|
+ int status;
|
|
|
+ struct qt_get_device_data DeviceData;
|
|
|
+ unsigned uc_temp = 0;
|
|
|
+ mydbg("Inside %s, uc_value = 0x%x\n", __FUNCTION__, uc_value);
|
|
|
+
|
|
|
+ DeviceData.porta = 0;
|
|
|
+ DeviceData.portb = 0;
|
|
|
+ serial = find_the_box(index);
|
|
|
+ //Determine Duplex mode
|
|
|
+ if (!(serial))
|
|
|
+ return -ENOTTY;
|
|
|
+ status = box_get_device(serial, &DeviceData);
|
|
|
+ if (status < 0) {
|
|
|
+ mydbg(__FILE__ "box_set_device failed\n");
|
|
|
+ return status;
|
|
|
+ }
|
|
|
|
|
|
+ uc_temp = uc_value & QMCR_HALF_DUPLEX_MASK;
|
|
|
+ switch (uc_temp) {
|
|
|
+ case QMCR_FULL_DUPLEX:
|
|
|
+ DeviceData.porta &= ~DUPMODE_BITS;
|
|
|
+ DeviceData.porta |= FULL_DUPLEX;
|
|
|
+ ATC_Mode = ATC_DISABLED;
|
|
|
+ break;
|
|
|
+ case QMCR_HALF_DUPLEX_RTS:
|
|
|
+ DeviceData.porta &= ~DUPMODE_BITS;
|
|
|
+ DeviceData.porta |= HALF_DUPLEX_RTS;
|
|
|
+ ATC_Mode = ATC_RTS_ENABLED;
|
|
|
+ break;
|
|
|
+ case QMCR_HALF_DUPLEX_DTR:
|
|
|
+ DeviceData.porta &= ~DUPMODE_BITS;
|
|
|
+ DeviceData.porta |= HALF_DUPLEX_DTR;
|
|
|
+ ATC_Mode = ATC_DTR_ENABLED;
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ break;
|
|
|
+ }
|
|
|
|
|
|
- default:
|
|
|
- err = -ENOTTY;
|
|
|
+ uc_temp = uc_value & QMCR_CONNECTOR_MASK;
|
|
|
+ switch (uc_temp) {
|
|
|
+ case QMCR_MODEM_CONTROL:
|
|
|
+ DeviceData.portb &= ~LOOPMODE_BITS; //reset connection bits
|
|
|
+ DeviceData.portb |= MODEM_CTRL;
|
|
|
+ break;
|
|
|
+ case QMCR_ALL_LOOPBACK:
|
|
|
+ DeviceData.portb &= ~LOOPMODE_BITS; //reset connection bits
|
|
|
+ DeviceData.portb |= ALL_LOOPBACK;
|
|
|
+ break;
|
|
|
+ }
|
|
|
|
|
|
+ mydbg(__FILE__ "Calling box_set_device with failed\n");
|
|
|
+ status = box_set_device(serial, &DeviceData);
|
|
|
+ if (status < 0) {
|
|
|
+ mydbg(__FILE__ "box_set_device failed\n");
|
|
|
+ return status;
|
|
|
+ }
|
|
|
|
|
|
+ if (uc_value & QMCR_RX_EN_MASK) //This bit (otherwise unused) i'll used to detect whether ATC is selected
|
|
|
+ {
|
|
|
|
|
|
+ mydbg(__FILE__
|
|
|
+ "calling BoxsetATC with DeviceData.porta = 0x%x and DeviceData.portb = 0x%x\n",
|
|
|
+ DeviceData.porta, DeviceData.portb);
|
|
|
+ status = BoxSetATC(serial, ATC_Mode);
|
|
|
+ if (status < 0) {
|
|
|
+ mydbg(__FILE__ "BoxSetATC failed\n");
|
|
|
+ return status;
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+
|
|
|
+ mydbg(__FILE__
|
|
|
+ "calling BoxsetATC with DeviceData.porta = 0x%x and DeviceData.portb = 0x%x\n",
|
|
|
+ DeviceData.porta, DeviceData.portb);
|
|
|
+ status = BoxSetATC(serial, ATC_DISABLED);
|
|
|
+ if (status < 0) {
|
|
|
+ mydbg(__FILE__ "BoxSetATC failed\n");
|
|
|
+ return status;
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
- } //End switch
|
|
|
+ return 0;
|
|
|
|
|
|
- mydbg("%s returning err = 0x%x\n", __FUNCTION__, err);
|
|
|
- return err;
|
|
|
}
|
|
|
|
|
|
+static int EmulateReadQMCR_Reg(int index, unsigned *uc_value)
|
|
|
+{
|
|
|
+ struct usb_serial *serial;
|
|
|
+ int status;
|
|
|
+ struct qt_get_device_data DeviceData;
|
|
|
+ __u8 uc_temp;
|
|
|
|
|
|
+ *uc_value = 0;
|
|
|
|
|
|
-static struct usb_serial *find_the_box(unsigned int index)
|
|
|
-{
|
|
|
- struct usb_serial *lastserial, *foundserial, *serial;
|
|
|
- int counts = 0, index2;
|
|
|
- lastserial = serial_table[0];
|
|
|
- foundserial = NULL;
|
|
|
- for (index2 = 0; index2 < SERIAL_TTY_MINORS ; index2++)
|
|
|
- {
|
|
|
- serial = serial_table[index2];
|
|
|
-
|
|
|
- mydbg("%s index = 0x%x, index2 = 0x%x, serial = 0x%p\n", __FUNCTION__, index, index2, serial);
|
|
|
-
|
|
|
- if(serial)
|
|
|
- {
|
|
|
- //first see if this is the unit we'er looking for
|
|
|
- mydbg("%s inside if(serial) counts = 0x%x , index = 0x%x\n", __FUNCTION__, counts, index);
|
|
|
- if(counts == index)
|
|
|
- {
|
|
|
- //we found the one we're looking for, copythe product Id to user
|
|
|
-
|
|
|
- mydbg("%s we found the one we're looking for serial = 0x%p\n", __FUNCTION__, serial);
|
|
|
- foundserial = serial;
|
|
|
- break;
|
|
|
- }
|
|
|
-
|
|
|
- if(serial != lastserial)
|
|
|
- {
|
|
|
- //when we have a change in the pointer
|
|
|
- lastserial = serial;
|
|
|
- counts++;
|
|
|
- }
|
|
|
- }
|
|
|
- else
|
|
|
- break; // no matches
|
|
|
- }
|
|
|
-
|
|
|
- mydbg("%s returning foundserial = 0x%p\n", __FUNCTION__, foundserial);
|
|
|
- return foundserial;
|
|
|
-}
|
|
|
+ serial = find_the_box(index);
|
|
|
+ if (!(serial))
|
|
|
+ return -ENOTTY;
|
|
|
|
|
|
+ status = box_get_device(serial, &DeviceData);
|
|
|
+ if (status < 0) {
|
|
|
+ mydbg(__FILE__ "box_get_device failed\n");
|
|
|
+ return status;
|
|
|
+ }
|
|
|
+ uc_temp = DeviceData.porta & DUPMODE_BITS;
|
|
|
+ switch (uc_temp) {
|
|
|
+ case FULL_DUPLEX:
|
|
|
+ *uc_value |= QMCR_FULL_DUPLEX;
|
|
|
+ break;
|
|
|
+ case HALF_DUPLEX_RTS:
|
|
|
+ *uc_value |= QMCR_HALF_DUPLEX_RTS;
|
|
|
+ break;
|
|
|
+ case HALF_DUPLEX_DTR:
|
|
|
+ *uc_value |= QMCR_HALF_DUPLEX_DTR;
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ break;
|
|
|
+ }
|
|
|
|
|
|
+ uc_temp = DeviceData.portb & LOOPMODE_BITS; //I use this for ATC control se
|
|
|
|
|
|
- static int EmulateWriteQMCR_Reg(int index, unsigned uc_value)
|
|
|
- {
|
|
|
-
|
|
|
- __u16 ATC_Mode = 0;
|
|
|
- struct usb_serial *serial;
|
|
|
- int status;
|
|
|
- struct qt_get_device_data DeviceData;
|
|
|
- unsigned uc_temp = 0;
|
|
|
- mydbg("Inside %s, uc_value = 0x%x\n", __FUNCTION__, uc_value);
|
|
|
-
|
|
|
- DeviceData.porta = 0;
|
|
|
- DeviceData.portb = 0;
|
|
|
- serial = find_the_box(index);
|
|
|
- //Determine Duplex mode
|
|
|
- if(!(serial))
|
|
|
- return -ENOTTY;
|
|
|
- status = box_get_device(serial, &DeviceData);
|
|
|
- if (status < 0)
|
|
|
- {
|
|
|
- mydbg(__FILE__"box_set_device failed\n");
|
|
|
- return status;
|
|
|
- }
|
|
|
-
|
|
|
- uc_temp = uc_value & QMCR_HALF_DUPLEX_MASK;
|
|
|
- switch (uc_temp)
|
|
|
- {
|
|
|
- case QMCR_FULL_DUPLEX:
|
|
|
- DeviceData.porta &= ~DUPMODE_BITS;
|
|
|
- DeviceData.porta |= FULL_DUPLEX;
|
|
|
- ATC_Mode = ATC_DISABLED;
|
|
|
- break;
|
|
|
- case QMCR_HALF_DUPLEX_RTS:
|
|
|
- DeviceData.porta &= ~DUPMODE_BITS;
|
|
|
- DeviceData.porta |= HALF_DUPLEX_RTS;
|
|
|
- ATC_Mode = ATC_RTS_ENABLED;
|
|
|
- break;
|
|
|
- case QMCR_HALF_DUPLEX_DTR:
|
|
|
- DeviceData.porta &= ~DUPMODE_BITS;
|
|
|
- DeviceData.porta |= HALF_DUPLEX_DTR;
|
|
|
- ATC_Mode = ATC_DTR_ENABLED;
|
|
|
- break;
|
|
|
- default:
|
|
|
- break;
|
|
|
- }
|
|
|
-
|
|
|
- uc_temp = uc_value & QMCR_CONNECTOR_MASK;
|
|
|
- switch (uc_temp)
|
|
|
- {
|
|
|
- case QMCR_MODEM_CONTROL:
|
|
|
- DeviceData.portb &= ~LOOPMODE_BITS; //reset connection bits
|
|
|
- DeviceData.portb |= MODEM_CTRL;
|
|
|
- break;
|
|
|
- case QMCR_ALL_LOOPBACK:
|
|
|
- DeviceData.portb &= ~LOOPMODE_BITS; //reset connection bits
|
|
|
- DeviceData.portb |= ALL_LOOPBACK;
|
|
|
- break;
|
|
|
- }
|
|
|
-
|
|
|
- mydbg(__FILE__"Calling box_set_device with failed\n");
|
|
|
- status = box_set_device(serial, &DeviceData);
|
|
|
- if (status < 0)
|
|
|
- {
|
|
|
- mydbg(__FILE__"box_set_device failed\n");
|
|
|
- return status;
|
|
|
- }
|
|
|
-
|
|
|
- if(uc_value & QMCR_RX_EN_MASK) //This bit (otherwise unused) i'll used to detect whether ATC is selected
|
|
|
- {
|
|
|
-
|
|
|
- mydbg(__FILE__"calling BoxsetATC with DeviceData.porta = 0x%x and DeviceData.portb = 0x%x\n", DeviceData.porta, DeviceData.portb);
|
|
|
- status = BoxSetATC(serial, ATC_Mode);
|
|
|
- if (status < 0)
|
|
|
- {
|
|
|
- mydbg(__FILE__"BoxSetATC failed\n");
|
|
|
- return status;
|
|
|
- }
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
-
|
|
|
- mydbg(__FILE__"calling BoxsetATC with DeviceData.porta = 0x%x and DeviceData.portb = 0x%x\n", DeviceData.porta, DeviceData.portb);
|
|
|
- status = BoxSetATC(serial, ATC_DISABLED);
|
|
|
- if (status < 0)
|
|
|
- {
|
|
|
- mydbg(__FILE__"BoxSetATC failed\n");
|
|
|
- return status;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
- return 0;
|
|
|
-
|
|
|
- }
|
|
|
+ switch (uc_temp) {
|
|
|
+ case ALL_LOOPBACK:
|
|
|
+ *uc_value |= QMCR_ALL_LOOPBACK;
|
|
|
+ break;
|
|
|
+ case MODEM_CTRL:
|
|
|
+ *uc_value |= QMCR_MODEM_CONTROL;
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ break;
|
|
|
|
|
|
+ }
|
|
|
+ return 0;
|
|
|
|
|
|
-static int EmulateReadQMCR_Reg(int index, unsigned *uc_value)
|
|
|
-{
|
|
|
- struct usb_serial *serial;
|
|
|
- int status;
|
|
|
- struct qt_get_device_data DeviceData;
|
|
|
- __u8 uc_temp;
|
|
|
-
|
|
|
- *uc_value = 0;
|
|
|
-
|
|
|
- serial = find_the_box(index);
|
|
|
- if(!(serial))
|
|
|
- return -ENOTTY;
|
|
|
-
|
|
|
- status = box_get_device(serial, &DeviceData);
|
|
|
- if (status < 0)
|
|
|
- {
|
|
|
- mydbg(__FILE__"box_get_device failed\n");
|
|
|
- return status;
|
|
|
- }
|
|
|
- uc_temp = DeviceData.porta & DUPMODE_BITS;
|
|
|
- switch (uc_temp)
|
|
|
- {
|
|
|
- case FULL_DUPLEX:
|
|
|
- *uc_value |= QMCR_FULL_DUPLEX;
|
|
|
- break;
|
|
|
- case HALF_DUPLEX_RTS:
|
|
|
- *uc_value |= QMCR_HALF_DUPLEX_RTS;
|
|
|
- break;
|
|
|
- case HALF_DUPLEX_DTR:
|
|
|
- *uc_value |= QMCR_HALF_DUPLEX_DTR;
|
|
|
- break;
|
|
|
- default:
|
|
|
- break;
|
|
|
- }
|
|
|
-
|
|
|
- uc_temp = DeviceData.portb & LOOPMODE_BITS; //I use this for ATC control se
|
|
|
-
|
|
|
- switch (uc_temp)
|
|
|
- {
|
|
|
- case ALL_LOOPBACK:
|
|
|
- *uc_value |= QMCR_ALL_LOOPBACK;
|
|
|
- break;
|
|
|
- case MODEM_CTRL:
|
|
|
- *uc_value |= QMCR_MODEM_CONTROL;
|
|
|
- break;
|
|
|
- default:
|
|
|
- break;
|
|
|
-
|
|
|
- }
|
|
|
- return 0;
|
|
|
-
|
|
|
-
|
|
|
- }
|
|
|
+}
|
|
|
|
|
|
static int __init serqt_usb_init(void)
|
|
|
{
|
|
@@ -2952,16 +2813,19 @@ static int __init serqt_usb_init(void)
|
|
|
/* register this driver with the USB subsystem */
|
|
|
result = usb_register(&serqt_usb_driver);
|
|
|
if (result < 0) {
|
|
|
- err("usb_register failed for the "__FILE__" driver. Error number %d", result);
|
|
|
+ err("usb_register failed for the " __FILE__
|
|
|
+ " driver. Error number %d", result);
|
|
|
return result;
|
|
|
}
|
|
|
- status = 0; // Dynamic assignment of major number
|
|
|
- major_number = register_chrdev(status, "SerialQT_USB", &serialqt_usb_fops);
|
|
|
+ status = 0; // Dynamic assignment of major number
|
|
|
+ major_number =
|
|
|
+ register_chrdev(status, "SerialQT_USB", &serialqt_usb_fops);
|
|
|
if (major_number < 0) {
|
|
|
- mydbg(KERN_DEBUG"No devices found \n\n");
|
|
|
+ mydbg(KERN_DEBUG "No devices found \n\n");
|
|
|
return -EBUSY;
|
|
|
} else
|
|
|
- mydbg(KERN_DEBUG"SerQT_USB major number assignment = %d \n\n", major_number);
|
|
|
+ mydbg(KERN_DEBUG "SerQT_USB major number assignment = %d \n\n",
|
|
|
+ major_number);
|
|
|
|
|
|
printk(KERN_INFO DRIVER_DESC " " DRIVER_VERSION);
|
|
|
return 0;
|
|
@@ -2969,10 +2833,10 @@ static int __init serqt_usb_init(void)
|
|
|
|
|
|
static void __exit serqt_usb_exit(void)
|
|
|
{
|
|
|
- /* deregister this driver with the USB subsystem */
|
|
|
- usb_deregister(&serqt_usb_driver);
|
|
|
- tty_unregister_driver(&serial_tty_driver);
|
|
|
- unregister_chrdev(major_number, "SerialQT_USB");
|
|
|
+ /* deregister this driver with the USB subsystem */
|
|
|
+ usb_deregister(&serqt_usb_driver);
|
|
|
+ tty_unregister_driver(&serial_tty_driver);
|
|
|
+ unregister_chrdev(major_number, "SerialQT_USB");
|
|
|
}
|
|
|
|
|
|
module_init(serqt_usb_init);
|