aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGreg Kroah-Hartman <gregkh@suse.de>2009-03-23 19:43:59 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2009-04-03 17:54:27 -0400
commit5ca0121ff24d2efba208a0f6df2cb6e372170d1d (patch)
treee90a086ca42dd28ef653e2eeb9eb57689281cc57
parent4e9bf410dc6006e95aba512272747bc8f30e7a20 (diff)
Staging: add USB serial Quatech driver
Add support for all Quatech usb to serial devices. Based on an original driver from Quatech. Cleaned up and forward ported by me. It's a mess, uses it's own tty layer interface, and the coding style is horrible. Cc: Tim Gobeli <tgobeli@quatech.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-rw-r--r--drivers/staging/Kconfig2
-rw-r--r--drivers/staging/Makefile1
-rw-r--r--drivers/staging/serqt_usb/Kconfig9
-rw-r--r--drivers/staging/serqt_usb/Makefile1
-rw-r--r--drivers/staging/serqt_usb/serqt_usb.c2983
5 files changed, 2996 insertions, 0 deletions
diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig
index 98dae044cbf5..7ea9d918387f 100644
--- a/drivers/staging/Kconfig
+++ b/drivers/staging/Kconfig
@@ -113,5 +113,7 @@ source "drivers/staging/heci/Kconfig"
113 113
114source "drivers/staging/line6/Kconfig" 114source "drivers/staging/line6/Kconfig"
115 115
116source "drivers/staging/serqt_usb/Kconfig"
117
116endif # !STAGING_EXCLUDE_BUILD 118endif # !STAGING_EXCLUDE_BUILD
117endif # STAGING 119endif # STAGING
diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile
index 2a859ee036da..47dfd5b4288b 100644
--- a/drivers/staging/Makefile
+++ b/drivers/staging/Makefile
@@ -39,3 +39,4 @@ obj-$(CONFIG_IDE_PHISON) += phison/
39obj-$(CONFIG_PLAN9AUTH) += p9auth/ 39obj-$(CONFIG_PLAN9AUTH) += p9auth/
40obj-$(CONFIG_HECI) += heci/ 40obj-$(CONFIG_HECI) += heci/
41obj-$(CONFIG_LINE6_USB) += line6/ 41obj-$(CONFIG_LINE6_USB) += line6/
42obj-$(CONFIG_USB_SERIAL_QUATECH_ESU100) += serqt_usb/
diff --git a/drivers/staging/serqt_usb/Kconfig b/drivers/staging/serqt_usb/Kconfig
new file mode 100644
index 000000000000..cc1af5df40d7
--- /dev/null
+++ b/drivers/staging/serqt_usb/Kconfig
@@ -0,0 +1,9 @@
1config USB_SERIAL_QUATECH_ESU100
2 tristate "USB Quatech ESU-100 8 Port Serial Driver"
3 depends on USB_SERIAL
4 help
5 Say Y here if you want to use the Quatech ESU-100 8 port usb to
6 serial adapter.
7
8 To compile this driver as a module, choose M here: the
9 module will be called serqt_usb.
diff --git a/drivers/staging/serqt_usb/Makefile b/drivers/staging/serqt_usb/Makefile
new file mode 100644
index 000000000000..4fd1da275e8d
--- /dev/null
+++ b/drivers/staging/serqt_usb/Makefile
@@ -0,0 +1 @@
obj-$(CONFIG_USB_SERIAL_QUATECH_ESU100) += serqt_usb.o
diff --git a/drivers/staging/serqt_usb/serqt_usb.c b/drivers/staging/serqt_usb/serqt_usb.c
new file mode 100644
index 000000000000..7ababa0dfa7b
--- /dev/null
+++ b/drivers/staging/serqt_usb/serqt_usb.c
@@ -0,0 +1,2983 @@
1/*
2 * This code was developed for the Quatech USB line for linux, it used
3 * much of the code developed by Greg Kroah-Hartman for USB serial devices
4 *
5 */
6
7#include <linux/sched.h>
8#include <linux/slab.h>
9#include <linux/tty.h>
10#include <linux/tty_flip.h>
11#include <linux/module.h>
12#include <linux/usb.h>
13#include <linux/wait.h>
14#include <linux/types.h>
15#include <linux/version.h>
16
17#include <asm/uaccess.h>
18
19/* Use our own dbg macro */
20//#define DEBUG_ON
21//#undef dbg
22#ifdef DEBUG_ON
23 #define mydbg(const...) printk(const)
24#else
25 #define mydbg(const...)
26#endif
27
28
29/* parity check flag */
30#define RELEVANT_IFLAG(iflag) (iflag & (IGNBRK|BRKINT|IGNPAR|PARMRK|INPCK))
31
32
33#define SERIAL_TTY_MAJOR 0 /* Nice legal number now */
34#define SERIAL_TTY_MINORS 255 /* loads of devices :) */
35#define MAX_NUM_PORTS 8 /* The maximum number of ports one device can grab at once */
36#define PREFUFF_LEVEL_CONSERVATIVE 128
37#define ATC_DISABLED 0x00
38
39#define RR_BITS 0x03 //for clearing clock bits
40#define DUPMODE_BITS 0xc0
41
42#define RS232_MODE 0x00
43#define RTSCTS_TO_CONNECTOR 0x40
44#define CLKS_X4 0x02 ///
45
46#define LOOPMODE_BITS 0x41 //LOOP1 = b6, LOOP0 = b0 (PORT B)
47#define ALL_LOOPBACK 0x01
48#define MODEM_CTRL 0x40
49
50
51#define THISCHAR data[i]
52#define NEXTCHAR data[i + 1]
53#define THIRDCHAR data[i + 2]
54#define FOURTHCHAR data[i + 3]
55
56//*************************************************
57// Useful defintions for port A, Port B and Port C
58#define FULLPWRBIT 0x00000080
59#define NEXT_BOARD_POWER_BIT 0x00000004
60
61
62#define SERIAL_LSR_OE 0x02
63#define SERIAL_LSR_PE 0x04
64#define SERIAL_LSR_FE 0x08
65#define SERIAL_LSR_BI 0x10
66
67#define SERIAL_LSR_TEMT 0x40
68
69#define DIV_LATCH_LS 0x00
70#define XMT_HOLD_REGISTER 0x00
71#define XVR_BUFFER_REGISTER 0x00
72#define DIV_LATCH_MS 0x01
73#define FIFO_CONTROL_REGISTER 0x02
74#define LINE_CONTROL_REGISTER 0x03
75#define MODEM_CONTROL_REGISTER 0x04
76#define LINE_STATUS_REGISTER 0x05
77#define MODEM_STATUS_REGISTER 0x06
78
79
80#define SERIAL_MCR_DTR 0x01
81#define SERIAL_MCR_RTS 0x02
82#define SERIAL_MCR_LOOP 0x10
83
84#define SERIAL_MSR_CTS 0x10
85#define SERIAL_MSR_CD 0x80
86#define SERIAL_MSR_RI 0x40
87#define SERIAL_MSR_DSR 0x20
88#define SERIAL_MSR_MASK 0xf0
89
90#define SERIAL_8_DATA 0x03
91#define SERIAL_7_DATA 0x02
92#define SERIAL_6_DATA 0x01
93#define SERIAL_5_DATA 0x00
94
95#define SERIAL_ODD_PARITY 0X08
96#define SERIAL_EVEN_PARITY 0X18
97#define SERIAL_TWO_STOPB 0x04
98#define SERIAL_ONE_STOPB 0x00
99
100#define MAX_BAUD_RATE 460800
101#define MAX_BAUD_REMAINDER 4608
102
103
104#define QT_SET_GET_DEVICE 0xc2
105#define QT_OPEN_CLOSE_CHANNEL 0xca
106#define QT_GET_SET_PREBUF_TRIG_LVL 0xcc
107#define QT_SET_ATF 0xcd
108#define QT_GET_SET_REGISTER 0xc0
109#define QT_GET_SET_UART 0xc1
110#define QT_HW_FLOW_CONTROL_MASK 0xc5
111#define QT_SW_FLOW_CONTROL_MASK 0xc6
112#define QT_SW_FLOW_CONTROL_DISABLE 0xc7
113#define QT_BREAK_CONTROL 0xc8
114
115#define SERIALQT_PCI_IOC_MAGIC 'k'
116#define SERIALQT_WRITE_QOPR _IOW(SERIALQT_PCI_IOC_MAGIC, 0, int)
117#define SERIALQT_WRITE_QMCR _IOW(SERIALQT_PCI_IOC_MAGIC, 1, int)
118#define SERIALQT_GET_NUMOF_UNITS _IOR(SERIALQT_PCI_IOC_MAGIC, 2, void *)
119#define SERIALQT_GET_THIS_UNIT _IOR(SERIALQT_PCI_IOC_MAGIC, 3, void *)
120#define SERIALQT_READ_QOPR _IOR(SERIALQT_PCI_IOC_MAGIC, 4, int)
121#define SERIALQT_READ_QMCR _IOR(SERIALQT_PCI_IOC_MAGIC, 5, int)
122#define SERIALQT_IS422_EXTENDED _IOR(SERIALQT_PCI_IOC_MAGIC, 6, int) //returns successful if 422 extended
123
124
125#define USBD_TRANSFER_DIRECTION_IN 0xc0
126#define USBD_TRANSFER_DIRECTION_OUT 0x40
127
128#define ATC_DISABLED 0x00
129#define ATC_RTS_ENABLED 0x02
130#define ATC_DTR_ENABLED 0x01
131
132#define RR_BITS 0x03 //for clearing clock bits
133#define DUPMODE_BITS 0xc0
134
135#define FULL_DUPLEX 0x00
136#define HALF_DUPLEX_RTS 0x40
137#define HALF_DUPLEX_DTR 0x80
138
139#define QMCR_FULL_DUPLEX 0x00
140#define QMCR_HALF_DUPLEX_RTS 0x02
141#define QMCR_HALF_DUPLEX_DTR 0x01
142#define QMCR_HALF_DUPLEX_MASK 0x03
143#define QMCR_CONNECTOR_MASK 0x1C
144
145#define QMCR_RX_EN_MASK 0x20
146
147#define QMCR_ALL_LOOPBACK 0x10
148#define QMCR_MODEM_CONTROL 0X00
149
150
151
152#define SERIALQT_IOC_MAXNR 6
153
154struct usb_serial_port {
155 struct usb_serial *serial; /* pointer back to the owner of this port */
156 struct tty_struct * tty; /* the coresponding tty for this port */
157 unsigned char number;
158 char active; /* someone has this device open */
159
160 unsigned char * interrupt_in_buffer;
161 struct urb * interrupt_in_urb;
162 __u8 interrupt_in_endpointAddress;
163
164 unsigned char * bulk_in_buffer;
165 unsigned char * xfer_to_tty_buffer;
166 struct urb * read_urb;
167 __u8 bulk_in_endpointAddress;
168
169 unsigned char * bulk_out_buffer;
170 int bulk_out_size;
171 struct urb * write_urb;
172 __u8 bulk_out_endpointAddress;
173
174 wait_queue_head_t write_wait;
175 wait_queue_head_t wait;
176 struct work_struct work;
177
178 int open_count; /* number of times this port has been opened */
179 struct semaphore sem; /* locks this structure */
180
181 __u8 shadowLCR; /* last LCR value received */
182 __u8 shadowMCR; /* last MCR value received */
183 __u8 shadowMSR; /* last MSR value received */
184 __u8 shadowLSR; /* last LSR value received */
185 int RxHolding;
186 char closePending;
187 int ReadBulkStopped;
188
189 void * private; /* data private to the specific port */
190};
191
192struct identity {
193 int index;
194 int n_identity;
195};
196
197struct usb_serial {
198 struct usb_device * dev;
199 struct usb_interface * interface; /* the interface for this device */
200 struct tty_driver * tty_driver; /* the tty_driver for this device */
201 unsigned char minor; /* the starting minor number for this device */
202 unsigned char num_ports; /* the number of ports this device has */
203 char num_interrupt_in; /* number of interrupt in endpoints we have */
204 char num_bulk_in; /* number of bulk in endpoints we have */
205 char num_bulk_out; /* number of bulk out endpoints we have */
206 unsigned char num_OpenCount; /* the number of ports this device has */
207
208
209 __u16 vendor; /* vendor id of this device */
210 __u16 product; /* product id of this device */
211 struct usb_serial_port port[MAX_NUM_PORTS];
212
213 void * private; /* data private to the specific driver */
214};
215
216
217
218static inline int port_paranoia_check (struct usb_serial_port *port, const char *function)
219{
220 if (!port) {
221 dbg("%s - port == NULL", function);
222 return -1;
223 }
224 if (!port->serial) {
225 dbg("%s - port->serial == NULL\n", function);
226 return -1;
227 }
228 if (!port->tty) {
229 dbg("%s - port->tty == NULL\n", function);
230 return -1;
231 }
232
233 return 0;
234}
235
236
237/* Inline functions to check the sanity of a pointer that is passed to us */
238static inline int serial_paranoia_check (struct usb_serial *serial, const char *function)
239{
240 if (!serial) {
241 dbg("%s - serial == NULL\n", function);
242 return -1;
243 }
244
245 return 0;
246}
247
248
249static inline struct usb_serial* get_usb_serial (struct usb_serial_port *port, const char *function)
250{
251 /* if no port was specified, or it fails a paranoia check */
252 if (!port ||
253 port_paranoia_check (port, function) ||
254 serial_paranoia_check (port->serial, function)) {
255 /* then say that we dont have a valid usb_serial thing, which will
256 * end up genrating -ENODEV return values */
257 return NULL;
258 }
259
260 return port->serial;
261}
262
263
264struct qt_get_device_data
265{
266 __u8 porta;
267 __u8 portb;
268 __u8 portc;
269};
270
271struct qt_open_channel_data
272{
273 __u8 line_status;
274 __u8 modem_status;
275};
276
277static void ProcessLineStatus(struct usb_serial_port *port, unsigned char line_status);
278static void ProcessModemStatus(struct usb_serial_port *port, unsigned char modem_status);
279static void ProcessRxChar(struct usb_serial_port *port, unsigned char Data);
280static struct usb_serial *get_free_serial (int num_ports, int *minor);
281
282
283static int serqt_probe(struct usb_interface *interface,
284 const struct usb_device_id *id);
285
286
287static void serqt_usb_disconnect(struct usb_interface *interface);
288static int box_set_device(struct usb_serial *serial, struct qt_get_device_data *pDeviceData);
289static int box_get_device(struct usb_serial *serial, struct qt_get_device_data *pDeviceData);
290static int serial_open (struct tty_struct *tty, struct file * filp);
291static void serial_close(struct tty_struct *tty, struct file * filp);
292static int serial_write_room (struct tty_struct *tty);
293static int serial_ioctl (struct tty_struct *tty, struct file * file, unsigned int cmd, unsigned long arg);
294static void serial_set_termios (struct tty_struct *tty, struct ktermios * old);
295static int serial_write (struct tty_struct * tty, const unsigned char *buf, int count);
296
297static void serial_throttle (struct tty_struct * tty);
298static void serial_unthrottle (struct tty_struct * tty);
299static int serial_break (struct tty_struct *tty, int break_state);
300static int serial_chars_in_buffer (struct tty_struct *tty);
301static int serial_read_proc (char *page, char **start, off_t off, int count, int *eof, void *data);
302
303static int qt_open (struct usb_serial_port *port, struct file *filp);
304static int BoxSetPrebufferLevel(struct usb_serial *serial);
305
306static int BoxSetATC(struct usb_serial *serial, __u16 n_Mode);
307static int BoxSetUart(struct usb_serial *serial, unsigned short Uart_Number, unsigned short default_divisor, unsigned char default_LCR );
308
309
310static int BoxOPenCloseChannel(struct usb_serial *serial, __u16 Uart_Number, __u16 OpenClose, struct qt_open_channel_data *pDeviceData);
311static void qt_close (struct usb_serial_port *port, struct file * filp);
312static int BoxGetRegister(struct usb_serial *serial, unsigned short Uart_Number,unsigned short Register_Num, __u8 *pValue);
313static int BoxSetRegister(struct usb_serial *serial, unsigned short Uart_Number, unsigned short Register_Num, unsigned short Value );
314static void qt_write_bulk_callback(struct urb *urb);
315static int qt_write (struct usb_serial_port *port, int from_user, const unsigned char *buf, int count);
316static void port_softint(struct work_struct *work);
317static int qt_write_room (struct usb_serial_port *port);
318static int qt_chars_in_buffer (struct usb_serial_port *port);
319static int qt_ioctl(struct usb_serial_port *port, struct file * file, unsigned int cmd, unsigned long arg);
320static void qt_set_termios(struct usb_serial_port *port, struct ktermios *old_termios);
321static int BoxSetHW_FlowCtrl(struct usb_serial *serial, unsigned int UartNumber, int bSet);
322static int BoxDisable_SW_FlowCtrl(struct usb_serial *serial, __u16 UartNumber);
323static int EmulateWriteQMCR_Reg(int index, unsigned uc_value);
324static int EmulateReadQMCR_Reg(int index, unsigned *uc_value);
325static struct usb_serial *find_the_box(unsigned int index);
326int ioctl_serial_usb (struct inode *innod, struct file *filp, unsigned int cmd, unsigned long arg);
327
328
329static int BoxSetSW_FlowCtrl(struct usb_serial *serial, __u16 Uart, unsigned char stop_char, unsigned char start_char);
330static void qt_read_bulk_callback(struct urb *urb);
331
332static void port_sofrint(void *private);
333
334static void return_serial(struct usb_serial *serial);
335
336
337static int serial_tiocmset (struct tty_struct *tty, struct file *file, unsigned int set, unsigned int clear);
338static int serial_tiocmget(struct tty_struct *tty, struct file *file);
339
340
341
342static int qt_tiocmset(struct usb_serial_port *port, struct file * file, unsigned int value);
343
344static int qt_tiocmget(struct usb_serial_port *port, struct file * file);
345
346
347
348/* Version Information */
349#define DRIVER_VERSION "v2.14"
350#define DRIVER_AUTHOR "Tim Gobeli, Quatech, Inc"
351#define DRIVER_DESC "Quatech USB to Serial Driver"
352
353#define USB_VENDOR_ID_QUATECH 0x061d // Quatech VID
354#define DEVICE_ID_QUATECH_RS232_SINGLE_PORT 0xC020 //SSU100
355#define DEVICE_ID_QUATECH_RS422_SINGLE_PORT 0xC030 //SSU200
356#define DEVICE_ID_QUATECH_RS232_DUAL_PORT 0xC040 //DSU100
357#define DEVICE_ID_QUATECH_RS422_DUAL_PORT 0xC050 //DSU200
358#define DEVICE_ID_QUATECH_RS232_FOUR_PORT 0xC060 //QSU100
359#define DEVICE_ID_QUATECH_RS422_FOUR_PORT 0xC070 //QSU200
360#define DEVICE_ID_QUATECH_RS232_EIGHT_PORT_A 0xC080 //ESU100A
361#define DEVICE_ID_QUATECH_RS232_EIGHT_PORT_B 0xC081 //ESU100B
362#define DEVICE_ID_QUATECH_RS422_EIGHT_PORT_A 0xC0A0 //ESU200A
363#define DEVICE_ID_QUATECH_RS422_EIGHT_PORT_B 0xC0A1 //ESU200B
364#define DEVICE_ID_QUATECH_RS232_16_PORT_A 0xC090 //HSU100A
365#define DEVICE_ID_QUATECH_RS232_16_PORT_B 0xC091 //HSU100B
366#define DEVICE_ID_QUATECH_RS232_16_PORT_C 0xC092 //HSU100C
367#define DEVICE_ID_QUATECH_RS232_16_PORT_D 0xC093 //HSU100D
368#define DEVICE_ID_QUATECH_RS422_16_PORT_A 0xC0B0 //HSU200A
369#define DEVICE_ID_QUATECH_RS422_16_PORT_B 0xC0B1 //HSU200B
370#define DEVICE_ID_QUATECH_RS422_16_PORT_C 0xC0B2 //HSU200C
371#define DEVICE_ID_QUATECH_RS422_16_PORT_D 0xC0B3 //HSU200D
372
373
374/* table of Quatech devices */
375static struct usb_device_id serqt_table [] = {
376 { USB_DEVICE(USB_VENDOR_ID_QUATECH, DEVICE_ID_QUATECH_RS232_SINGLE_PORT)},
377 { USB_DEVICE(USB_VENDOR_ID_QUATECH, DEVICE_ID_QUATECH_RS422_SINGLE_PORT)},
378 { USB_DEVICE(USB_VENDOR_ID_QUATECH, DEVICE_ID_QUATECH_RS232_DUAL_PORT)},
379 { USB_DEVICE(USB_VENDOR_ID_QUATECH, DEVICE_ID_QUATECH_RS422_DUAL_PORT)},
380 { USB_DEVICE(USB_VENDOR_ID_QUATECH, DEVICE_ID_QUATECH_RS232_FOUR_PORT)},
381 { USB_DEVICE(USB_VENDOR_ID_QUATECH, DEVICE_ID_QUATECH_RS422_FOUR_PORT)},
382 { USB_DEVICE(USB_VENDOR_ID_QUATECH, DEVICE_ID_QUATECH_RS232_EIGHT_PORT_A)},
383 { USB_DEVICE(USB_VENDOR_ID_QUATECH, DEVICE_ID_QUATECH_RS232_EIGHT_PORT_B)},
384 { USB_DEVICE(USB_VENDOR_ID_QUATECH, DEVICE_ID_QUATECH_RS422_EIGHT_PORT_A)},
385 { USB_DEVICE(USB_VENDOR_ID_QUATECH, DEVICE_ID_QUATECH_RS422_EIGHT_PORT_B)},
386 { USB_DEVICE(USB_VENDOR_ID_QUATECH, DEVICE_ID_QUATECH_RS232_16_PORT_A)},
387 { USB_DEVICE(USB_VENDOR_ID_QUATECH, DEVICE_ID_QUATECH_RS232_16_PORT_B)},
388 { USB_DEVICE(USB_VENDOR_ID_QUATECH, DEVICE_ID_QUATECH_RS232_16_PORT_C)},
389 { USB_DEVICE(USB_VENDOR_ID_QUATECH, DEVICE_ID_QUATECH_RS232_16_PORT_D)},
390 { USB_DEVICE(USB_VENDOR_ID_QUATECH, DEVICE_ID_QUATECH_RS422_16_PORT_A)},
391 { USB_DEVICE(USB_VENDOR_ID_QUATECH, DEVICE_ID_QUATECH_RS422_16_PORT_B)},
392 { USB_DEVICE(USB_VENDOR_ID_QUATECH, DEVICE_ID_QUATECH_RS422_16_PORT_C)},
393 { USB_DEVICE(USB_VENDOR_ID_QUATECH, DEVICE_ID_QUATECH_RS422_16_PORT_D)},
394 {} /* Terminating entry */
395};
396MODULE_DEVICE_TABLE(usb, serqt_table);
397
398static int major_number;
399static struct usb_serial *serial_table[SERIAL_TTY_MINORS]; /* initially all NULL */
400
401
402/* table of Quatech 422devices */
403static unsigned int serqt_422_table[] = {
404 DEVICE_ID_QUATECH_RS422_SINGLE_PORT,
405 DEVICE_ID_QUATECH_RS422_DUAL_PORT,
406 DEVICE_ID_QUATECH_RS422_FOUR_PORT,
407 DEVICE_ID_QUATECH_RS422_EIGHT_PORT_A,
408 DEVICE_ID_QUATECH_RS422_EIGHT_PORT_B,
409 DEVICE_ID_QUATECH_RS422_16_PORT_A,
410 DEVICE_ID_QUATECH_RS422_16_PORT_B,
411 DEVICE_ID_QUATECH_RS422_16_PORT_C,
412 DEVICE_ID_QUATECH_RS422_16_PORT_D,
413 0 /* terminate with zero */
414};
415
416
417
418/* usb specific object needed to register this driver with the usb subsystem */
419static struct usb_driver serqt_usb_driver = {
420 .name = "quatech-usb-serial",
421 .probe = serqt_probe,
422 .disconnect = serqt_usb_disconnect,
423 .id_table = serqt_table,
424};
425
426static struct ktermios *serial_termios[SERIAL_TTY_MINORS];
427static struct ktermios *serial_termios_locked[SERIAL_TTY_MINORS];
428
429static const struct tty_operations serial_ops = {
430 .open = serial_open,
431 .close = serial_close,
432 .write = serial_write,
433 .write_room = serial_write_room,
434 .ioctl = serial_ioctl,
435 .set_termios = serial_set_termios,
436 .throttle = serial_throttle,
437 .unthrottle = serial_unthrottle,
438 .break_ctl = serial_break,
439 .chars_in_buffer = serial_chars_in_buffer,
440 .read_proc = serial_read_proc,
441 .tiocmset = serial_tiocmset,
442 .tiocmget = serial_tiocmget,
443};
444
445static struct tty_driver serial_tty_driver = {
446 .magic = TTY_DRIVER_MAGIC,
447 .driver_name = "Quatech usb-serial",
448 .name = "ttyQT_USB",
449 .major = SERIAL_TTY_MAJOR,
450 .minor_start = 0,
451 .num = SERIAL_TTY_MINORS,
452 .type = TTY_DRIVER_TYPE_SERIAL,
453 .subtype = SERIAL_TYPE_NORMAL,
454 .flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV,
455
456 .termios = serial_termios,
457 .termios_locked = serial_termios_locked,
458 .init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL,
459
460 .init_termios.c_iflag = ICRNL | IXON,
461 .init_termios.c_oflag = OPOST,
462
463 .init_termios.c_lflag= ISIG | ICANON | ECHO | ECHOE | ECHOK | ECHOCTL | ECHOKE | IEXTEN,
464};
465
466//fops for parent device
467static struct file_operations serialqt_usb_fops = {
468 .ioctl = ioctl_serial_usb,
469
470};
471
472
473 /**
474 * serqt_probe
475 *
476 * Called by the usb core when a new device is connected that it thinks
477 * this driver might be interested in.
478 *
479 */
480static int serqt_probe(struct usb_interface *interface,
481 const struct usb_device_id *id)
482{
483 struct usb_device *dev = interface_to_usbdev(interface);
484 struct usb_serial *serial = NULL;
485 struct usb_serial_port *port;
486 struct usb_endpoint_descriptor *endpoint;
487 struct usb_endpoint_descriptor *interrupt_in_endpoint[MAX_NUM_PORTS];
488 struct usb_endpoint_descriptor *bulk_in_endpoint[MAX_NUM_PORTS];
489 struct usb_endpoint_descriptor *bulk_out_endpoint[MAX_NUM_PORTS];
490 int minor;
491 int buffer_size;
492 int i;
493 struct usb_host_interface *iface_desc;
494 int num_interrupt_in = 0;
495 int num_bulk_in = 0;
496 int num_bulk_out = 0;
497 int num_ports;
498 struct qt_get_device_data DeviceData;
499 int status;
500
501 mydbg("In %s\n", __FUNCTION__);
502
503 /* let's find the endpoints needed */
504 /* check out the endpoints */
505 iface_desc = interface->cur_altsetting;;
506 for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i)
507 {
508 endpoint = &iface_desc->endpoint[i].desc;
509
510 if ((endpoint->bEndpointAddress & 0x80) &&
511 ((endpoint->bmAttributes & 3) == 0x02))
512 {
513 /* we found a bulk in endpoint */
514 mydbg("found bulk in");
515 bulk_in_endpoint[num_bulk_in] = endpoint;
516 ++num_bulk_in;
517 }
518
519 if (((endpoint->bEndpointAddress & 0x80) == 0x00) &&
520 ((endpoint->bmAttributes & 3) == 0x02))
521 {
522 /* we found a bulk out endpoint */
523 mydbg("found bulk out\n");
524 bulk_out_endpoint[num_bulk_out] = endpoint;
525 ++num_bulk_out;
526 }
527
528 if ((endpoint->bEndpointAddress & 0x80) &&
529 ((endpoint->bmAttributes & 3) == 0x03))
530 {
531 /* we found a interrupt in endpoint */
532 mydbg("found interrupt in\n");
533 interrupt_in_endpoint[num_interrupt_in] = endpoint;
534 ++num_interrupt_in;
535 }
536 }
537
538 /* found all that we need */
539 dev_info(&interface->dev, "Quatech converter detected\n");
540 num_ports = num_bulk_out;
541 if (num_ports == 0)
542 {
543 err("Quatech device with no bulk out, not allowed.");
544 return -ENODEV;
545
546 }
547
548 serial = get_free_serial (num_ports, &minor);
549 if (serial == NULL)
550 {
551 err("No more free serial devices");
552 return -ENODEV;
553 }
554
555 serial->dev = dev;
556 serial->interface = interface;
557 serial->minor = minor;
558 serial->num_ports = num_ports;
559 serial->num_bulk_in = num_bulk_in;
560 serial->num_bulk_out = num_bulk_out;
561 serial->num_interrupt_in = num_interrupt_in;
562 serial->vendor = dev->descriptor.idVendor;
563 serial->product = dev->descriptor.idProduct;
564
565
566 /* set up the endpoint information */
567 for (i = 0; i < num_bulk_in; ++i)
568 {
569 endpoint = bulk_in_endpoint[i];
570 port = &serial->port[i];
571 port->read_urb = usb_alloc_urb (0, GFP_KERNEL);
572 if (!port->read_urb)
573 {
574 err("No free urbs available");
575 goto probe_error;
576 }
577 buffer_size = endpoint->wMaxPacketSize;
578 port->bulk_in_endpointAddress = endpoint->bEndpointAddress;
579 port->bulk_in_buffer = kmalloc (buffer_size, GFP_KERNEL);
580 port->xfer_to_tty_buffer = kmalloc (buffer_size, GFP_KERNEL);
581 if (!port->bulk_in_buffer)
582 {
583 err("Couldn't allocate bulk_in_buffer");
584 goto probe_error;
585 }
586 usb_fill_bulk_urb (port->read_urb, dev,
587 usb_rcvbulkpipe (dev,
588 endpoint->bEndpointAddress),
589 port->bulk_in_buffer, buffer_size,
590 qt_read_bulk_callback,
591 port);
592 }
593
594 for (i = 0; i < num_bulk_out; ++i)
595 {
596 endpoint = bulk_out_endpoint[i];
597 port = &serial->port[i];
598 port->write_urb = usb_alloc_urb (0, GFP_KERNEL);
599 if (!port->write_urb)
600 {
601 err("No free urbs available");
602 goto probe_error;
603 }
604 buffer_size = endpoint->wMaxPacketSize;
605 port->bulk_out_size = buffer_size;
606 port->bulk_out_endpointAddress = endpoint->bEndpointAddress;
607 port->bulk_out_buffer = kmalloc (buffer_size, GFP_KERNEL);
608 if (!port->bulk_out_buffer)
609 {
610 err("Couldn't allocate bulk_out_buffer");
611 goto probe_error;
612 }
613 usb_fill_bulk_urb (port->write_urb, dev,
614 usb_sndbulkpipe (dev,
615 endpoint->bEndpointAddress),
616 port->bulk_out_buffer, buffer_size,
617 qt_write_bulk_callback,
618 port);
619
620
621 }
622
623 //For us numb of bulkin or out = number of ports
624
625 mydbg("%s - setting up %d port structures for this device\n", __FUNCTION__, num_bulk_in);
626 for (i = 0; i < num_bulk_in; ++i)
627 {
628 port = &serial->port[i];
629 port->number = i + serial->minor;
630 port->serial = serial;
631
632 INIT_WORK(&port->work, port_softint);
633
634 init_MUTEX (&port->sem);
635
636
637
638 }
639 status = box_get_device(serial, &DeviceData);
640 if (status < 0)
641 {
642 mydbg(__FILE__"box_get_device failed");
643 goto probe_error;
644 }
645
646 mydbg(__FILE__"DeviceData.portb = 0x%x",DeviceData.portb);
647
648 DeviceData.portb &= ~FULLPWRBIT;
649 mydbg(__FILE__"Changing DeviceData.portb to 0x%x",DeviceData.portb);
650
651 status = box_set_device(serial, &DeviceData);
652 if (status < 0)
653 {
654 mydbg(__FILE__"box_set_device failed\n");
655 goto probe_error;
656 }
657
658
659
660 /* initialize the devfs nodes for this device and let the user know what ports we are bound to */
661 for (i = 0; i < serial->num_ports; ++i)
662 {
663 dev_info(&interface->dev, "Converter now attached to ttyUSB%d (or usb/tts/%d for devfs)",
664 serial->port[i].number, serial->port[i].number);
665 }
666
667 //usb_serial_console_init (debug, minor);
668
669 ///***********TAG add start next board here ****///
670 status = box_get_device(serial, &DeviceData);
671 if (status < 0)
672 {
673 mydbg(__FILE__"box_get_device failed");
674 goto probe_error;
675 }
676
677 //*****************and before we power up lets initialiaze parnent device stuff here before
678 //*****************we set thmem via any other method such as the property pages
679 switch (serial->product)
680 {
681 case DEVICE_ID_QUATECH_RS232_SINGLE_PORT:
682 case DEVICE_ID_QUATECH_RS232_DUAL_PORT:
683 case DEVICE_ID_QUATECH_RS232_FOUR_PORT:
684 case DEVICE_ID_QUATECH_RS232_EIGHT_PORT_A:
685 case DEVICE_ID_QUATECH_RS232_EIGHT_PORT_B:
686 case DEVICE_ID_QUATECH_RS232_16_PORT_A:
687 case DEVICE_ID_QUATECH_RS232_16_PORT_B:
688 case DEVICE_ID_QUATECH_RS232_16_PORT_C:
689 case DEVICE_ID_QUATECH_RS232_16_PORT_D:
690 DeviceData.porta &= ~(RR_BITS | DUPMODE_BITS);
691 DeviceData.porta |= CLKS_X4;
692 DeviceData.portb &= ~(LOOPMODE_BITS);
693 DeviceData.portb |= RS232_MODE;
694 break;
695
696
697 case DEVICE_ID_QUATECH_RS422_SINGLE_PORT:
698 case DEVICE_ID_QUATECH_RS422_DUAL_PORT:
699 case DEVICE_ID_QUATECH_RS422_FOUR_PORT:
700 case DEVICE_ID_QUATECH_RS422_EIGHT_PORT_A:
701 case DEVICE_ID_QUATECH_RS422_EIGHT_PORT_B:
702 case DEVICE_ID_QUATECH_RS422_16_PORT_A:
703 case DEVICE_ID_QUATECH_RS422_16_PORT_B:
704 case DEVICE_ID_QUATECH_RS422_16_PORT_C:
705 case DEVICE_ID_QUATECH_RS422_16_PORT_D:
706 DeviceData.porta &= ~(RR_BITS | DUPMODE_BITS);
707 DeviceData.porta |= CLKS_X4;
708 DeviceData.portb &= ~(LOOPMODE_BITS);
709 DeviceData.portb |= ALL_LOOPBACK;
710 break;
711 default:
712 DeviceData.porta &= ~(RR_BITS | DUPMODE_BITS);
713 DeviceData.porta |= CLKS_X4;
714 DeviceData.portb &= ~(LOOPMODE_BITS);
715 DeviceData.portb |= RS232_MODE;
716 break;
717
718 }
719 status = BoxSetPrebufferLevel(serial); //sets to default vaue
720 if (status < 0)
721 {
722 mydbg(__FILE__"BoxSetPrebufferLevel failed\n");
723 goto probe_error;
724 }
725
726 status = BoxSetATC(serial, ATC_DISABLED);
727 if (status < 0)
728 {
729 mydbg(__FILE__"BoxSetATC failed\n");
730 goto probe_error;
731 }
732 //****************************************************************************
733 mydbg(__FILE__"DeviceData.portb = 0x%x",DeviceData.portb);
734
735 DeviceData.portb |= NEXT_BOARD_POWER_BIT;
736 mydbg(__FILE__"Changing DeviceData.portb to 0x%x",DeviceData.portb);
737
738 status = box_set_device(serial, &DeviceData);
739 if (status < 0)
740 {
741 mydbg(__FILE__"box_set_device failed\n");
742 goto probe_error;
743 }
744
745
746 mydbg("Exit Success %s\n", __FUNCTION__);
747
748 usb_set_intfdata (interface, serial);
749 return 0;
750
751
752
753 probe_error:
754
755 for (i = 0; i < num_bulk_in; ++i)
756 {
757 port = &serial->port[i];
758 if (port->read_urb)
759 usb_free_urb (port->read_urb);
760 if (port->bulk_in_buffer)
761 kfree (port->bulk_in_buffer);
762 }
763 for (i = 0; i < num_bulk_out; ++i)
764 {
765 port = &serial->port[i];
766 if (port->write_urb)
767 usb_free_urb (port->write_urb);
768 if (port->bulk_out_buffer)
769 kfree (port->bulk_out_buffer);
770
771 if (port->xfer_to_tty_buffer)
772 kfree (port->xfer_to_tty_buffer);
773 }
774 for (i = 0; i < num_interrupt_in; ++i)
775 {
776 port = &serial->port[i];
777 if (port->interrupt_in_urb)
778 usb_free_urb (port->interrupt_in_urb);
779 if (port->interrupt_in_buffer)
780 kfree (port->interrupt_in_buffer);
781 }
782
783
784 /* return the minor range that this device had */
785 return_serial (serial);
786 mydbg("Exit fail %s\n", __FUNCTION__);
787
788 /* free up any memory that we allocated */
789 kfree (serial);
790 return -EIO;
791}
792
793
794
795
796
797
798//returns the serial_table array pointers that are taken
799//up in consecutive positions for each port to a common usb_serial structure
800//back to NULL
801static void return_serial(struct usb_serial *serial)
802{
803 int i;
804
805 mydbg("%s\n", __FUNCTION__);
806
807 if (serial == NULL)
808 return;
809
810 for (i = 0; i < serial->num_ports; ++i)
811 {
812 serial_table[serial->minor + i] = NULL;
813 }
814
815 return;
816}
817
818//Finds the first locatio int the serial_table array where it can fit
819//num_ports number of consecutive points to a common usb_serial structure
820//,allocates a stucture points to it in all the structures, and returns the index
821//to the first location in the array in the "minor" variable.
822
823static struct usb_serial *get_free_serial (int num_ports, int *minor)
824{
825 struct usb_serial *serial = NULL;
826 int i, j;
827 int good_spot;
828
829 mydbg("%s %d\n", __FUNCTION__, num_ports);
830
831 *minor = 0;
832 for (i = 0; i < SERIAL_TTY_MINORS; ++i)
833 {
834 if (serial_table[i])
835 continue;
836
837 good_spot = 1;
838 //find a spot in the array where you can fit consecutive positions
839 //to put the pointers to the usb_serail allocated structure for all
840 //the minor numbers (ie. ports)
841 for (j = 1; j <= num_ports-1; ++j)
842 if (serial_table[i+j])
843 good_spot = 0;
844 if (good_spot == 0)
845 continue;
846
847 if (!(serial = kmalloc(sizeof(struct usb_serial), GFP_KERNEL)))
848 {
849 err("%s - Out of memory", __FUNCTION__);
850 return NULL;
851 }
852 memset(serial, 0, sizeof(struct usb_serial));
853 serial_table[i] = serial;
854 *minor = i;
855 mydbg("%s - minor base = %d\n", __FUNCTION__, *minor);
856 //copy in the pointer into the array starting a the *minor position
857 //*minor is the index into the array
858 for (i = *minor+1; (i < (*minor + num_ports)) && (i < SERIAL_TTY_MINORS); ++i)
859 serial_table[i] = serial;
860 return serial;
861 }
862 return NULL;
863}
864
865static int flip_that( struct tty_struct *tty, __u16 UartNumber, struct usb_serial *serial)
866{
867 tty_flip_buffer_push(tty);
868 tty_schedule_flip(tty);
869 return 0;
870}
871
872//Handles processing and moving data to the tty layer
873static void port_sofrint(void *private)
874{
875 struct usb_serial_port *port = (struct usb_serial_port *)private;
876 struct usb_serial *serial = get_usb_serial (port, __FUNCTION__);
877 struct tty_struct *tty = port->tty;
878 unsigned char *data = port->read_urb->transfer_buffer;
879 unsigned int UartNumber;
880 struct urb *urb = port->read_urb;
881 unsigned int RxCount = urb->actual_length;
882 int i, result;
883 int flag, flag_data;
884
885 //UartNumber = MINOR(port->tty->device) - serial->minor;
886 UartNumber = tty->index - serial->minor;
887
888 mydbg("%s - port %d\n", __FUNCTION__, port->number);
889 mydbg ("%s - port->RxHolding = %d\n", __FUNCTION__, port->RxHolding);
890
891 if (port_paranoia_check (port, __FUNCTION__) != 0) {
892 mydbg("%s - port_paranoia_check, exiting\n", __FUNCTION__);
893 port->ReadBulkStopped = 1;
894 return;
895 }
896
897 if (!serial) {
898 mydbg("%s - bad serial pointer, exiting\n", __FUNCTION__);
899 return;
900 }
901 if (port->closePending == 1) //Were closing , stop reading
902 {
903 mydbg("%s - (port->closepending == 1\n", __FUNCTION__);
904 port->ReadBulkStopped = 1;
905 return;
906 }
907
908 //RxHolding is asserted by throttle, if we assert it, we're not receiving any more
909 //characters and let the box handle the flow control
910 if (port->RxHolding == 1) {
911 port->ReadBulkStopped = 1;
912 return;
913 }
914
915 if (urb->status) {
916 port->ReadBulkStopped = 1;
917
918 mydbg("%s - nonzero read bulk status received: %d\n", __FUNCTION__, urb->status);
919 return;
920 }
921
922
923 tty = port->tty;
924 mydbg("%s - port %d, tty =0x%p\n", __FUNCTION__, port->number, tty);
925
926
927 if (tty && RxCount) {
928 flag_data = 0;
929 for (i = 0; i < RxCount ; ++i) {
930 //Look ahead code here
931
932 if ((i <= (RxCount - 3)) && (THISCHAR == 0x1b) && (NEXTCHAR == 0x1b)) {
933 flag = 0;
934 switch (THIRDCHAR) {
935 case 0x00:
936 //Line status change 4th byte must follow
937 if (i > (RxCount - 4)) {
938 mydbg("Illegal escape sequences in received data\n");
939 break;
940 }
941 ProcessLineStatus(port, FOURTHCHAR);
942 i += 3;
943 flag = 1;
944 break;
945
946 case 0x01:
947 //Modem status status change 4th byte must follow
948 mydbg("Modem status status. \n");
949
950 if (i > (RxCount - 4)) {
951 mydbg("Illegal escape sequences in received data\n");
952 break;
953 }
954 ProcessModemStatus(port, FOURTHCHAR);
955 i += 3;
956 flag = 1;
957 break;
958 case 0xff:
959 mydbg("No status sequence. \n");
960
961 ProcessRxChar(port, THISCHAR);
962 ProcessRxChar(port, NEXTCHAR);
963 i += 2;
964 break;
965
966 }//end switch
967 if (flag == 1)
968 continue;
969 } //endif
970
971 if(tty && urb->actual_length) {
972 tty_buffer_request_room(tty, 1);
973 tty_insert_flip_string(tty, (data + i), 1);
974 }
975
976
977 }//endfor
978
979 tty_flip_buffer_push(tty);
980
981 }//endif
982
983 /* Continue trying to always read */
984 usb_fill_bulk_urb (port->read_urb, serial->dev,
985 usb_rcvbulkpipe (serial->dev,
986 port->bulk_in_endpointAddress),
987 port->read_urb->transfer_buffer,
988 port->read_urb->transfer_buffer_length,
989 qt_read_bulk_callback, port);
990 result = usb_submit_urb(port->read_urb, GFP_ATOMIC);
991 if (result)
992 mydbg("%s - failed resubmitting read urb, error %d", __FUNCTION__, result);
993 else
994 {
995 if (tty && RxCount)
996 flip_that(tty, UartNumber, serial);
997 }
998
999
1000 return;
1001
1002 }
1003
1004
1005
1006static void qt_read_bulk_callback(struct urb *urb)
1007{
1008
1009 struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
1010
1011
1012 if (urb->status)
1013 {
1014
1015 port->ReadBulkStopped = 1;
1016 mydbg("%s - nonzero write bulk status received: %d\n", __FUNCTION__, urb->status);
1017 return;
1018 }
1019
1020 port_sofrint((void *) port);
1021 schedule_work(&port->work);
1022}
1023
1024
1025static void ProcessRxChar(struct usb_serial_port *port, unsigned char Data){
1026 struct tty_struct *tty;
1027 struct urb *urb = port->read_urb;
1028 tty = port->tty;
1029 /* if we insert more than TTY_FLIPBUF_SIZE characters, we drop them. */
1030
1031 if(tty && urb->actual_length)
1032 {
1033 tty_buffer_request_room(tty, 1);
1034 tty_insert_flip_string(tty, &Data, 1);
1035 //tty_flip_buffer_push(tty);
1036
1037
1038 }
1039
1040 return;
1041}
1042
1043static void ProcessLineStatus(struct usb_serial_port *port, unsigned char line_status){
1044
1045 port->shadowLSR = line_status & (SERIAL_LSR_OE | SERIAL_LSR_PE | SERIAL_LSR_FE |
1046 SERIAL_LSR_BI);
1047 return;
1048}
1049
1050
1051static void ProcessModemStatus(struct usb_serial_port *port, unsigned char modem_status){
1052
1053 port->shadowMSR = modem_status;
1054 wake_up_interruptible(&port->wait);
1055 return;
1056}
1057
1058
1059
1060
1061
1062
1063static void serqt_usb_disconnect(struct usb_interface *interface){
1064 struct usb_serial *serial = usb_get_intfdata (interface);
1065 //struct device *dev = &interface->dev;
1066 struct usb_serial_port *port;
1067 int i;
1068
1069 mydbg ("%s\n", __FUNCTION__);
1070 if (serial)
1071 {
1072
1073 serial->dev = NULL;
1074
1075 for (i = 0; i < serial->num_ports; ++i)
1076 serial->port[i].open_count = 0;
1077
1078 for (i = 0; i < serial->num_bulk_in; ++i)
1079 {
1080 port = &serial->port[i];
1081 if (port->read_urb)
1082 {
1083 usb_unlink_urb (port->read_urb);
1084 usb_free_urb (port->read_urb);
1085 }
1086 if (port->bulk_in_buffer)
1087 kfree (port->bulk_in_buffer);
1088 }
1089 for (i = 0; i < serial->num_bulk_out; ++i)
1090 {
1091 port = &serial->port[i];
1092 if (port->write_urb)
1093 {
1094 usb_unlink_urb (port->write_urb);
1095 usb_free_urb (port->write_urb);
1096 }
1097 if (port->bulk_out_buffer)
1098 kfree (port->bulk_out_buffer);
1099 }
1100 for (i = 0; i < serial->num_interrupt_in; ++i)
1101 {
1102 port = &serial->port[i];
1103 if (port->interrupt_in_urb)
1104 {
1105 usb_unlink_urb (port->interrupt_in_urb);
1106 usb_free_urb (port->interrupt_in_urb);
1107 }
1108 if (port->interrupt_in_buffer)
1109 kfree (port->interrupt_in_buffer);
1110 }
1111
1112
1113 /* return the minor range that this device had */
1114 return_serial (serial);
1115
1116 /* free up any memory that we allocated */
1117 kfree (serial);
1118
1119
1120
1121 } else
1122 {
1123 dev_info(&interface->dev, "device disconnected");
1124 }
1125
1126
1127}
1128
1129
1130
1131
1132
1133
1134
1135static struct usb_serial *get_serial_by_minor (unsigned int minor)
1136{
1137 return serial_table[minor];
1138}
1139
1140/*****************************************************************************
1141 * Driver tty interface functions
1142 *****************************************************************************/
1143static int serial_open (struct tty_struct *tty, struct file * filp){
1144 struct usb_serial *serial;
1145 struct usb_serial_port *port;
1146 unsigned int portNumber;
1147 int retval = 0;
1148
1149 mydbg("%s\n", __FUNCTION__);
1150
1151 /* initialize the pointer incase something fails */
1152 tty->driver_data = NULL;
1153
1154 /* get the serial object associated with this tty pointer */
1155 //serial = get_serial_by_minor (MINOR(tty->device));
1156
1157 /* get the serial object associated with this tty pointer */
1158 serial = get_serial_by_minor(tty->index);
1159
1160
1161 if (serial_paranoia_check (serial, __FUNCTION__))
1162 return -ENODEV;
1163
1164
1165 /* set up our port structure making the tty driver remember our port object, and us it */
1166 portNumber = tty->index - serial->minor;
1167 port = &serial->port[portNumber];
1168 tty->driver_data = port;
1169
1170 down (&port->sem);
1171 port->tty = tty;
1172
1173
1174 ++port->open_count;
1175 if (port->open_count == 1)
1176 {
1177 port->closePending = 0;
1178 mydbg("%s port->closepending = 0\n", __FUNCTION__);
1179
1180 port->RxHolding = 0;
1181 mydbg("%s port->RxHolding = 0\n", __FUNCTION__);
1182
1183 retval = qt_open(port, filp);
1184 }
1185
1186 if (retval)
1187 {
1188 port->open_count = 0;
1189 }
1190 mydbg("%s returning port->closePending = %d\n", __FUNCTION__, port->closePending);
1191
1192 up (&port->sem);
1193 return retval;
1194}
1195/*****************************************************************************
1196 *device's specific driver functions
1197 *****************************************************************************/
1198static int qt_open (struct usb_serial_port *port, struct file *filp){
1199 struct usb_serial *serial = port->serial;
1200 int result = 0;
1201 unsigned int UartNumber;
1202 struct qt_get_device_data DeviceData;
1203 struct qt_open_channel_data ChannelData;
1204 unsigned short default_divisor = 0x30; //gives 9600 baud rate
1205 unsigned char default_LCR = SERIAL_8_DATA; // 8, none , 1
1206 int status = 0;
1207
1208
1209
1210
1211 if (port_paranoia_check (port, __FUNCTION__))
1212 return -ENODEV;
1213
1214 mydbg("%s - port %d\n", __FUNCTION__, port->number);
1215
1216 /* force low_latency on so that our tty_push actually forces the data through,
1217 otherwise it is scheduled, and with high data rates (like with OHCI) data
1218 can get lost. */
1219 if (port->tty)
1220 port->tty->low_latency = 0;
1221
1222
1223 UartNumber = port->tty->index - serial->minor;
1224
1225 status = box_get_device(serial, &DeviceData);
1226 if (status < 0)
1227 {
1228 mydbg(__FILE__"box_get_device failed\n");
1229 return status;
1230 }
1231 serial->num_OpenCount++;
1232 mydbg("%s serial->num_OpenCount = %d\n", __FUNCTION__, serial->num_OpenCount);
1233 //Open uart channel
1234
1235 //Port specific setups
1236 status = BoxOPenCloseChannel(serial, UartNumber, 1, &ChannelData);
1237 if (status < 0)
1238 {
1239 mydbg(__FILE__"BoxOPenCloseChannel failed\n");
1240 return status;
1241 }
1242 mydbg(__FILE__"BoxOPenCloseChannel completed.\n");
1243
1244 port->shadowLSR = ChannelData.line_status &
1245 (SERIAL_LSR_OE | SERIAL_LSR_PE | SERIAL_LSR_FE | SERIAL_LSR_BI);
1246
1247 port->shadowMSR = ChannelData.modem_status &
1248 (SERIAL_MSR_CTS | SERIAL_MSR_DSR | SERIAL_MSR_RI | SERIAL_MSR_CD);
1249
1250
1251 //Set Baud rate to default and turn off (default)flow control here
1252 status = BoxSetUart(serial, UartNumber, default_divisor, default_LCR);
1253 if (status < 0)
1254 {
1255 mydbg(__FILE__"BoxSetUart failed\n");
1256 return status;
1257 }
1258 mydbg(__FILE__"BoxSetUart completed.\n");
1259
1260
1261 //Put this here to make it responsive to stty and defauls set by the tty layer
1262 qt_set_termios(port, NULL);
1263
1264
1265 //Initialize the wait que head
1266 init_waitqueue_head(&(port->wait));
1267
1268 /* if we have a bulk endpoint, start reading from it */
1269 if (serial->num_bulk_in)
1270 {
1271 /* Start reading from the device */
1272 usb_fill_bulk_urb (port->read_urb, serial->dev,
1273 usb_rcvbulkpipe(serial->dev, port->bulk_in_endpointAddress),
1274 port->read_urb->transfer_buffer,
1275 port->read_urb->transfer_buffer_length,
1276 qt_read_bulk_callback,
1277 port);
1278
1279 port->ReadBulkStopped = 0;
1280
1281 result = usb_submit_urb(port->read_urb, GFP_ATOMIC);
1282
1283 if (result)
1284 {
1285 err("%s - failed resubmitting read urb, error %d\n", __FUNCTION__, result);
1286 port->ReadBulkStopped = 1;
1287 }
1288
1289 }
1290
1291 return result;
1292}
1293
1294static void serial_close(struct tty_struct *tty, struct file * filp){
1295 struct usb_serial_port *port = (struct usb_serial_port *) tty->driver_data;
1296 struct usb_serial *serial = get_usb_serial (port, __FUNCTION__);
1297
1298 if (!serial)
1299 return;
1300
1301 down (&port->sem);
1302
1303 mydbg("%s - port %d\n", __FUNCTION__, port->number);
1304
1305 /* if disconnect beat us to the punch here, there's nothing to do */
1306 if (tty->driver_data)
1307 {
1308 if (!port->open_count)
1309 {
1310 mydbg ("%s - port not opened\n", __FUNCTION__);
1311 goto exit;
1312 }
1313
1314 --port->open_count;
1315 if (port->open_count <= 0)
1316 {
1317 port->closePending = 1;
1318 mydbg ("%s - port->closePending = 1\n", __FUNCTION__);
1319
1320 if (serial->dev)
1321 {
1322 qt_close(port, filp);
1323 port->open_count = 0;
1324 }
1325 }
1326
1327 }
1328
1329 exit:
1330 up (&port->sem);
1331
1332 mydbg("%s - %d return\n", __FUNCTION__, port->number);
1333
1334
1335}
1336
1337static void qt_close (struct usb_serial_port *port, struct file *filp){
1338 unsigned long jift = jiffies + 10 * HZ;
1339 __u8 LSR_Value, MCR_Value;
1340 struct usb_serial *serial = port->serial;
1341 int status;
1342 unsigned int UartNumber;
1343
1344 struct qt_open_channel_data ChannelData;
1345 status = 0;
1346 LSR_Value = 0;
1347
1348
1349 mydbg("%s - port %d\n", __FUNCTION__, port->number);
1350 UartNumber = port->tty->index - serial->minor;
1351
1352 /* shutdown any bulk reads that might be going on */
1353 if (serial->num_bulk_out)
1354 usb_unlink_urb (port->write_urb);
1355 if (serial->num_bulk_in)
1356 usb_unlink_urb (port->read_urb);
1357
1358
1359 //wait up to 30 seconds for transmitter to empty
1360 do
1361 {
1362 status = BoxGetRegister(serial, UartNumber, LINE_STATUS_REGISTER, &LSR_Value);
1363 if (status < 0)
1364 {
1365 mydbg(__FILE__"box_get_device failed\n");
1366 break;
1367 }
1368
1369 if ((LSR_Value & SERIAL_LSR_TEMT) && (port->ReadBulkStopped == 1))
1370 break;
1371 schedule();
1372
1373
1374 }
1375 while (jiffies <= jift);
1376
1377 if(jiffies > jift)
1378 mydbg("%s - port %d timout of checking transmitter empty\n", __FUNCTION__, port->number);
1379 else
1380 mydbg("%s - port %d checking transmitter empty succeded\n", __FUNCTION__, port->number);
1381
1382
1383
1384 status = BoxGetRegister(serial, UartNumber, MODEM_CONTROL_REGISTER, &MCR_Value);
1385 mydbg(__FILE__"BoxGetRegister MCR = 0x%x.\n", MCR_Value);
1386
1387
1388 if (status >= 0)
1389 {
1390 MCR_Value &= ~(SERIAL_MCR_DTR | SERIAL_MCR_RTS);
1391// status = BoxSetRegister(serial, UartNumber, MODEM_CONTROL_REGISTER, MCR_Value);
1392 }
1393
1394
1395 //Close uart channel
1396 status = BoxOPenCloseChannel(serial, UartNumber, 0, &ChannelData);
1397 if(status < 0)
1398 mydbg("%s - port %d BoxOPenCloseChannel failed.\n", __FUNCTION__, port->number);
1399
1400 serial->num_OpenCount--;
1401
1402
1403}
1404
1405
1406
1407static int serial_write (struct tty_struct * tty, const unsigned char *buf, int count)
1408{
1409 struct usb_serial_port *port = (struct usb_serial_port *) tty->driver_data;
1410 struct usb_serial *serial;
1411 int retval = -EINVAL;
1412 unsigned int UartNumber;
1413 int from_user = 0;
1414
1415
1416 serial = get_usb_serial (port, __FUNCTION__);
1417 if(serial == NULL)
1418 return -ENODEV;
1419 //This can happen if we get disconnected a
1420 if (port->open_count == 0)
1421 {
1422 return -ENODEV;
1423 }
1424 UartNumber = port->tty->index - serial->minor;
1425
1426 mydbg("%s - port %d, %d byte(s)\n", __FUNCTION__, port->number, count);
1427 mydbg("%s - port->RxHolding = %d\n", __FUNCTION__, port->RxHolding);
1428
1429 if (!port->open_count)
1430 {
1431 mydbg("%s - port not opened\n", __FUNCTION__);
1432 goto exit;
1433 }
1434
1435 retval = qt_write(port, from_user, buf, count);
1436
1437 exit:
1438 return retval;
1439}
1440
1441
1442static int qt_write (struct usb_serial_port *port, int from_user, const unsigned char *buf, int count){
1443 int result;
1444 unsigned int UartNumber;
1445
1446 struct usb_serial *serial = get_usb_serial (port, __FUNCTION__);
1447 if(serial == NULL)
1448 return -ENODEV;
1449
1450
1451
1452 mydbg("%s - port %d\n", __FUNCTION__, port->number);
1453
1454 if (count == 0)
1455 {
1456 mydbg("%s - write request of 0 bytes\n", __FUNCTION__);
1457 return(0);
1458 }
1459
1460
1461 UartNumber = port->tty->index - serial->minor;
1462 /* only do something if we have a bulk out endpoint */
1463 if (serial->num_bulk_out)
1464 {
1465 if (port->write_urb->status == -EINPROGRESS)
1466 {
1467 mydbg("%s - already writing\n", __FUNCTION__);
1468 return(0);
1469 }
1470
1471 count = (count > port->bulk_out_size) ? port->bulk_out_size : count;
1472
1473 if (from_user)
1474 {
1475 if (copy_from_user(port->write_urb->transfer_buffer, buf, count))
1476 return -EFAULT;
1477 } else
1478 {
1479 memcpy (port->write_urb->transfer_buffer, buf, count);
1480 }
1481
1482 //usb_serial_debug_data(__FILE__, __FUNCTION__, count, port->write_urb->transfer_buffer);
1483
1484 /* set up our urb */
1485
1486
1487 usb_fill_bulk_urb (port->write_urb, serial->dev,
1488 usb_sndbulkpipe (serial->dev,
1489 port->bulk_out_endpointAddress),
1490 port->write_urb->transfer_buffer, count,
1491 qt_write_bulk_callback, port);
1492
1493
1494
1495
1496
1497 /* send the data out the bulk port */
1498 result = usb_submit_urb(port->write_urb, GFP_ATOMIC);
1499 if (result)
1500 mydbg("%s - failed submitting write urb, error %d\n", __FUNCTION__, result);
1501 else
1502 result = count;
1503
1504 return result;
1505 }
1506
1507 /* no bulk out, so return 0 bytes written */
1508 return(0);
1509}
1510
1511
1512
1513static void qt_write_bulk_callback(struct urb *urb)
1514{
1515 struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
1516 struct usb_serial *serial = get_usb_serial (port, __FUNCTION__);
1517
1518 mydbg("%s - port %d\n", __FUNCTION__, port->number);
1519
1520 if (!serial)
1521 {
1522 mydbg("%s - bad serial pointer, exiting\n", __FUNCTION__);
1523 return;
1524 }
1525
1526 if (urb->status)
1527 {
1528 mydbg("%s - nonzero write bulk status received: %d\n", __FUNCTION__, urb->status);
1529 return;
1530 }
1531 //
1532 port_softint(&port->work);
1533 schedule_work(&port->work);
1534
1535 return;
1536}
1537
1538
1539static void port_softint(struct work_struct *work)
1540{
1541 struct usb_serial_port *port =
1542 container_of(work, struct usb_serial_port, work);
1543 struct usb_serial *serial = get_usb_serial (port, __FUNCTION__);
1544 struct tty_struct *tty;
1545
1546
1547 mydbg("%s - port %d\n", __FUNCTION__, port->number);
1548
1549
1550
1551 if (!serial)
1552 return;
1553
1554
1555 tty = port->tty;
1556 if (!tty)
1557 return;
1558#if 0
1559 if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && tty->ldisc.write_wakeup)
1560 {
1561 mydbg("%s - write wakeup call.\n", __FUNCTION__);
1562 (tty->ldisc.write_wakeup)(tty);
1563 }
1564#endif
1565
1566 wake_up_interruptible(&tty->write_wait);
1567}
1568static int serial_write_room (struct tty_struct *tty)
1569{
1570 struct usb_serial_port *port = (struct usb_serial_port *) tty->driver_data;
1571 struct usb_serial *serial = get_usb_serial (port, __FUNCTION__);
1572 int retval = -EINVAL;
1573
1574 if (!serial)
1575 return -ENODEV;
1576
1577 down (&port->sem);
1578
1579 mydbg("%s - port %d\n", __FUNCTION__, port->number);
1580
1581 if (!port->open_count)
1582 {
1583 mydbg("%s - port not open\n", __FUNCTION__);
1584 goto exit;
1585 }
1586
1587 retval = qt_write_room(port);
1588
1589 exit:
1590 up (&port->sem);
1591 return retval;
1592}
1593static int qt_write_room (struct usb_serial_port *port)
1594{
1595 struct usb_serial *serial = port->serial;
1596 int room = 0;
1597 if (port->closePending == 1)
1598 {
1599 mydbg("%s - port->closePending == 1\n", __FUNCTION__);
1600 return -ENODEV;
1601 }
1602
1603
1604 mydbg("%s - port %d\n", __FUNCTION__, port->number);
1605
1606 if (serial->num_bulk_out)
1607 {
1608 if (port->write_urb->status != -EINPROGRESS)
1609 room = port->bulk_out_size;
1610 }
1611
1612 mydbg("%s - returns %d\n", __FUNCTION__, room);
1613 return(room);
1614}
1615static int serial_chars_in_buffer (struct tty_struct *tty)
1616{
1617 struct usb_serial_port *port = (struct usb_serial_port *) tty->driver_data;
1618 struct usb_serial *serial = get_usb_serial (port, __FUNCTION__);
1619 int retval = -EINVAL;
1620
1621 if (!serial)
1622 return -ENODEV;
1623
1624 down (&port->sem);
1625
1626 mydbg("%s = port %d\n", __FUNCTION__, port->number);
1627
1628 if (!port->open_count) {
1629 mydbg("%s - port not open\n", __FUNCTION__);
1630 goto exit;
1631 }
1632
1633 retval = qt_chars_in_buffer(port);
1634
1635exit:
1636 up (&port->sem);
1637 return retval;
1638}
1639
1640
1641
1642static int qt_chars_in_buffer (struct usb_serial_port *port)
1643{
1644 struct usb_serial *serial = port->serial;
1645 int chars = 0;
1646
1647 mydbg("%s - port %d\n", __FUNCTION__, port->number);
1648
1649 if (serial->num_bulk_out)
1650 {
1651 if (port->write_urb->status == -EINPROGRESS)
1652 chars = port->write_urb->transfer_buffer_length;
1653 }
1654
1655 mydbg("%s - returns %d\n", __FUNCTION__, chars);
1656 return(chars);
1657}
1658
1659
1660static int serial_tiocmset (struct tty_struct *tty, struct file *file, unsigned int set, unsigned int clear)
1661{
1662
1663 struct usb_serial_port *port = (struct usb_serial_port *) tty->driver_data;
1664 struct usb_serial *serial = get_usb_serial (port, __FUNCTION__);
1665 int retval = -ENODEV;
1666 unsigned int UartNumber;
1667 mydbg("In %s \n", __FUNCTION__);
1668
1669 if (!serial)
1670 return -ENODEV;
1671
1672
1673 UartNumber = port->tty->index - serial->minor;
1674
1675
1676 down (&port->sem);
1677
1678 mydbg("%s - port %d \n", __FUNCTION__, port->number);
1679 mydbg ("%s - port->RxHolding = %d\n", __FUNCTION__, port->RxHolding);
1680
1681 if (!port->open_count)
1682 {
1683 mydbg ("%s - port not open\n", __FUNCTION__);
1684 goto exit;
1685 }
1686
1687 retval = qt_tiocmset(port, file, set);
1688
1689 exit:
1690 up (&port->sem);
1691 return retval;
1692}
1693
1694
1695static int qt_tiocmset(struct usb_serial_port *port, struct file * file, unsigned int value)
1696{
1697
1698 __u8 MCR_Value;
1699 int status;
1700 unsigned int UartNumber;
1701
1702
1703 struct usb_serial *serial = get_usb_serial (port, __FUNCTION__);
1704 if(serial == NULL)
1705 return -ENODEV;
1706
1707 mydbg("%s - port %d\n", __FUNCTION__, port->number);
1708
1709 /**************************************************************************************/
1710 /** TIOCMGET
1711 */
1712 UartNumber = port->tty->index - serial->minor;
1713 status = BoxGetRegister(port->serial, UartNumber, MODEM_CONTROL_REGISTER, &MCR_Value);
1714 if (status < 0)
1715 return -ESPIPE;
1716
1717 //Turn off the RTS and DTR and loopbcck and then only
1718 //trun on what was asked for
1719 MCR_Value &= ~(SERIAL_MCR_RTS | SERIAL_MCR_DTR | SERIAL_MCR_LOOP);
1720 if (value & TIOCM_RTS)
1721 MCR_Value |= SERIAL_MCR_RTS;
1722 if (value & TIOCM_DTR)
1723 MCR_Value |= SERIAL_MCR_DTR;
1724 if (value & TIOCM_LOOP)
1725 MCR_Value |= SERIAL_MCR_LOOP;
1726
1727 status = BoxSetRegister(port->serial, UartNumber, MODEM_CONTROL_REGISTER, MCR_Value);
1728 if (status < 0)
1729 return -ESPIPE;
1730 else
1731 return 0;
1732}
1733
1734static int serial_tiocmget(struct tty_struct *tty, struct file *file)
1735{
1736
1737 struct usb_serial_port *port = (struct usb_serial_port *) tty->driver_data;
1738
1739 struct usb_serial *serial = get_usb_serial (port, __FUNCTION__);
1740 int retval = -ENODEV;
1741 unsigned int UartNumber;
1742 mydbg("In %s \n", __FUNCTION__);
1743
1744 if (!serial)
1745 return -ENODEV;
1746
1747
1748 UartNumber = port->tty->index - serial->minor;
1749
1750
1751 down (&port->sem);
1752
1753 mydbg("%s - port %d\n", __FUNCTION__, port->number);
1754 mydbg ("%s - port->RxHolding = %d\n", __FUNCTION__, port->RxHolding);
1755
1756 if (!port->open_count)
1757 {
1758 mydbg ("%s - port not open\n", __FUNCTION__);
1759 goto exit;
1760 }
1761
1762 retval = qt_tiocmget(port, file);
1763
1764 exit:
1765 up (&port->sem);
1766 return retval;
1767}
1768
1769
1770
1771static int qt_tiocmget(struct usb_serial_port *port, struct file * file)
1772{
1773
1774 __u8 MCR_Value;
1775 __u8 MSR_Value;
1776 unsigned int result = 0;
1777 int status;
1778 unsigned int UartNumber;
1779 struct tty_struct * tty;
1780
1781
1782 struct usb_serial *serial = get_usb_serial (port, __FUNCTION__);
1783 if(serial == NULL)
1784 return -ENODEV;
1785 tty = port->tty;
1786
1787 mydbg("%s - port %d, tty =0x%p\n", __FUNCTION__, port->number, tty);
1788
1789 /**************************************************************************************/
1790 /** TIOCMGET
1791 */
1792 UartNumber = port->tty->index - serial->minor;
1793 status = BoxGetRegister(port->serial, UartNumber, MODEM_CONTROL_REGISTER, &MCR_Value);
1794 if (status >= 0)
1795 {
1796 status = BoxGetRegister(port->serial, UartNumber, MODEM_STATUS_REGISTER, &MSR_Value);
1797
1798 }
1799
1800 if (status >= 0)
1801 {
1802 result = ((MCR_Value & SERIAL_MCR_DTR) ? TIOCM_DTR: 0)
1803 //DTR IS SET
1804 | ((MCR_Value & SERIAL_MCR_RTS) ? TIOCM_RTS: 0)
1805 //RTS IS SET
1806 | ((MSR_Value & SERIAL_MSR_CTS) ? TIOCM_CTS: 0)
1807 //CTS is set
1808 | ((MSR_Value & SERIAL_MSR_CD) ? TIOCM_CAR: 0)
1809 //Carrier detect is set
1810 | ((MSR_Value & SERIAL_MSR_RI) ? TIOCM_RI: 0)
1811 //Ring indicator set
1812 | ((MSR_Value & SERIAL_MSR_DSR) ? TIOCM_DSR: 0);
1813 //DSR is set
1814 return result;
1815
1816 }
1817 else
1818 return -ESPIPE;
1819 //endif tatus => 0
1820}
1821
1822
1823
1824static int serial_ioctl (struct tty_struct *tty, struct file * file, unsigned int cmd, unsigned long arg)
1825{
1826
1827 struct usb_serial_port *port = (struct usb_serial_port *) tty->driver_data;
1828 struct usb_serial *serial = get_usb_serial (port, __FUNCTION__);
1829 int retval = -ENODEV;
1830 unsigned int UartNumber;
1831 mydbg("In %s \n", __FUNCTION__);
1832
1833 if (!serial)
1834 return -ENODEV;
1835
1836
1837 UartNumber = port->tty->index - serial->minor;
1838
1839
1840 down (&port->sem);
1841
1842 mydbg("%s - port %d, cmd 0x%.4x\n", __FUNCTION__, port->number, cmd);
1843 mydbg ("%s - port->RxHolding = %d\n", __FUNCTION__, port->RxHolding);
1844
1845 if (!port->open_count)
1846 {
1847 mydbg ("%s - port not open\n", __FUNCTION__);
1848 goto exit;
1849 }
1850
1851 retval = qt_ioctl(port, file, cmd, arg);
1852
1853 exit:
1854 up (&port->sem);
1855 return retval;
1856}
1857static int qt_ioctl(struct usb_serial_port *port, struct file * file, unsigned int cmd, unsigned long arg)
1858{
1859 __u8 MCR_Value;
1860 __u8 MSR_Value;
1861 unsigned short Prev_MSR_Value;
1862 unsigned int value, result = 0;
1863 int status;
1864 unsigned int UartNumber;
1865 struct tty_struct * tty;
1866
1867
1868 struct usb_serial *serial = get_usb_serial (port, __FUNCTION__);
1869 if(serial == NULL)
1870 return -ENODEV;
1871 tty = port->tty;
1872
1873 mydbg("%s - port %d, tty =0x%p\n", __FUNCTION__, port->number, tty);
1874
1875 /**************************************************************************************/
1876 /** TIOCMGET
1877 */
1878 UartNumber = port->tty->index - serial->minor;
1879
1880 if(cmd == TIOCMGET)
1881 {
1882 MCR_Value = port->shadowMCR;
1883 MSR_Value = port->shadowMSR;
1884
1885 {
1886 result = ((MCR_Value & SERIAL_MCR_DTR) ? TIOCM_DTR: 0)
1887 //DTR IS SET
1888 | ((MCR_Value & SERIAL_MCR_RTS) ? TIOCM_RTS: 0)
1889 //RTS IS SET
1890 | ((MSR_Value & SERIAL_MSR_CTS) ? TIOCM_CTS: 0)
1891 //CTS is set
1892 | ((MSR_Value & SERIAL_MSR_CD) ? TIOCM_CAR: 0)
1893 //Carrier detect is set
1894 | ((MSR_Value & SERIAL_MSR_RI) ? TIOCM_RI: 0)
1895 //Ring indicator set
1896 | ((MSR_Value & SERIAL_MSR_DSR) ? TIOCM_DSR: 0);
1897 //DSR is set
1898 if(copy_to_user((unsigned int *)arg, &result, sizeof(unsigned int)))
1899 return -EFAULT;
1900 return 0;
1901
1902 }//endif tatus => 0
1903
1904 }//endif(cmd == TIOCMGET)
1905 /**************************************************************************************/
1906 /** End TIOCMGET
1907 */
1908 /**************************************************************************************/
1909 /** TIOCMBIS, TIOCMBIC, AND TIOCMSET */
1910
1911 /**************************************************************************************/
1912
1913 if(cmd == TIOCMBIS || cmd == TIOCMBIC || cmd == TIOCMSET)
1914 {
1915 status = BoxGetRegister(port->serial, UartNumber, MODEM_CONTROL_REGISTER, &MCR_Value);
1916 if (status < 0)
1917 return -ESPIPE;
1918 if (copy_from_user(&value, (unsigned int *)arg, sizeof(unsigned int)))
1919 return -EFAULT;
1920
1921 switch (cmd)
1922 {
1923 case TIOCMBIS:
1924 if (value & TIOCM_RTS)
1925 MCR_Value |= SERIAL_MCR_RTS;
1926 if (value & TIOCM_DTR)
1927 MCR_Value |= SERIAL_MCR_DTR;
1928 if (value & TIOCM_LOOP)
1929 MCR_Value |= SERIAL_MCR_LOOP;
1930 break;
1931 case TIOCMBIC:
1932 if (value & TIOCM_RTS)
1933 MCR_Value &= ~SERIAL_MCR_RTS;
1934 if (value & TIOCM_DTR)
1935 MCR_Value &= ~SERIAL_MCR_DTR;
1936 if (value & TIOCM_LOOP)
1937 MCR_Value &= ~SERIAL_MCR_LOOP;
1938 break;
1939 case TIOCMSET:
1940 //Turn off the RTS and DTR and loopbcck and then only
1941 //trun on what was asked for
1942 MCR_Value &= ~(SERIAL_MCR_RTS | SERIAL_MCR_DTR | SERIAL_MCR_LOOP);
1943 if (value & TIOCM_RTS)
1944 MCR_Value |= SERIAL_MCR_RTS;
1945 if (value & TIOCM_DTR)
1946 MCR_Value |= SERIAL_MCR_DTR;
1947 if (value & TIOCM_LOOP)
1948 MCR_Value |= SERIAL_MCR_LOOP;
1949 break;
1950 default:
1951 break;
1952
1953 }
1954 status = BoxSetRegister(port->serial, UartNumber, MODEM_CONTROL_REGISTER, MCR_Value);
1955 if (status < 0)
1956 return -ESPIPE;
1957 else
1958 {
1959 port->shadowMCR = MCR_Value;
1960 return 0;
1961 }
1962
1963
1964 }
1965 /**************************************************************************************/
1966 /** TIOCMBIS, TIOCMBIC, AND TIOCMSET end
1967 */
1968 /**************************************************************************************/
1969
1970 if(cmd == TIOCMIWAIT)
1971 {
1972 DECLARE_WAITQUEUE(wait, current);
1973 Prev_MSR_Value = port->shadowMSR & SERIAL_MSR_MASK;
1974 while(1)
1975 {
1976 add_wait_queue(&port->wait, &wait);
1977 set_current_state(TASK_INTERRUPTIBLE);
1978 schedule();
1979 remove_wait_queue(&port->wait, &wait);
1980 /* see if a signal woke us up */
1981 if(signal_pending(current))
1982 return -ERESTARTSYS;
1983 MSR_Value = port->shadowMSR & SERIAL_MSR_MASK;
1984 if(MSR_Value == Prev_MSR_Value)
1985 return -EIO; //no change error
1986
1987 if((arg & TIOCM_RNG && ((Prev_MSR_Value & SERIAL_MSR_RI) ==
1988 (MSR_Value & SERIAL_MSR_RI))) ||
1989 (arg & TIOCM_DSR && ((Prev_MSR_Value & SERIAL_MSR_DSR) ==
1990 (MSR_Value & SERIAL_MSR_DSR))) ||
1991 (arg & TIOCM_CD && ((Prev_MSR_Value & SERIAL_MSR_CD) ==
1992 (MSR_Value & SERIAL_MSR_CD))) ||
1993 (arg & TIOCM_CTS && ((Prev_MSR_Value & SERIAL_MSR_CTS) ==
1994 (MSR_Value & SERIAL_MSR_CTS))))
1995 {
1996 return 0;
1997 }
1998
1999 }//endwhile
2000
2001 }
2002 mydbg("%s -No ioctl for that one. port = %d\n", __FUNCTION__, port->number);
2003
2004
2005 return -ENOIOCTLCMD;
2006}
2007
2008static void serial_set_termios (struct tty_struct *tty, struct ktermios *old)
2009{
2010 struct usb_serial_port *port = (struct usb_serial_port *) tty->driver_data;
2011 struct usb_serial *serial = get_usb_serial (port, __FUNCTION__);
2012
2013 if (!serial)
2014 return;
2015
2016 down (&port->sem);
2017
2018 mydbg("%s - port %d\n", __FUNCTION__, port->number);
2019
2020 if (!port->open_count) {
2021 mydbg("%s - port not open\n", __FUNCTION__);
2022 goto exit;
2023 }
2024
2025 /* pass on to the driver specific version of this function if it is available */
2026 qt_set_termios(port, old);
2027
2028exit:
2029 up (&port->sem);
2030}
2031
2032static void qt_set_termios(struct usb_serial_port *port, struct ktermios *old_termios)
2033{
2034 unsigned int cflag;
2035 int baud, divisor, remainder;
2036 unsigned char LCR_change_to = 0;
2037 struct tty_struct *tty;
2038 int status;
2039 struct usb_serial *serial;
2040 __u16 UartNumber;
2041 __u16 tmp, tmp2;
2042
2043 mydbg("%s - port %d\n", __FUNCTION__, port->number);
2044
2045 tmp = port->tty->index;
2046 mydbg("%s - MINOR(port->tty->index) = %d\n", __FUNCTION__, tmp);
2047
2048
2049 serial = port->serial;
2050 tmp2 = serial->minor;
2051 mydbg("%s - serial->minor = %d\n", __FUNCTION__, tmp2);
2052
2053
2054
2055 UartNumber = port->tty->index - serial->minor;
2056
2057 tty = port->tty;
2058
2059 cflag = tty->termios->c_cflag;
2060
2061 if (old_termios)
2062 {
2063 if((cflag == old_termios->c_cflag) && (RELEVANT_IFLAG(tty->termios->c_iflag) ==
2064 RELEVANT_IFLAG(old_termios->c_iflag)))
2065 {
2066 mydbg("%s - Nothing to change\n", __FUNCTION__);
2067 return;
2068 }
2069
2070
2071 }
2072
2073 mydbg("%s - 3\n", __FUNCTION__);
2074
2075 switch(cflag)
2076 {
2077 case CS5:
2078 LCR_change_to |= SERIAL_5_DATA;
2079 break;
2080 case CS6:
2081 LCR_change_to |= SERIAL_6_DATA;
2082 break;
2083 case CS7:
2084 LCR_change_to |= SERIAL_7_DATA;
2085 break;
2086 default:
2087 case CS8:
2088 LCR_change_to |= SERIAL_8_DATA;
2089 break;
2090 }
2091
2092 //Parity stuff
2093 if(cflag & PARENB)
2094 {
2095 if(cflag & PARODD)
2096 LCR_change_to |= SERIAL_ODD_PARITY;
2097 else
2098 LCR_change_to |= SERIAL_EVEN_PARITY;
2099 }
2100 if(cflag & CSTOPB)
2101 LCR_change_to |= SERIAL_TWO_STOPB;
2102 else
2103 LCR_change_to |= SERIAL_TWO_STOPB;
2104
2105 mydbg("%s - 4\n", __FUNCTION__);
2106 //Thats the LCR stuff, go ahead and set it
2107 baud = tty_get_baud_rate(tty);
2108 if (!baud) {
2109 /* pick a default, any default... */
2110 baud = 9600;
2111 }
2112
2113 mydbg("%s - got baud = %d\n", __FUNCTION__, baud);
2114
2115
2116 divisor = MAX_BAUD_RATE / baud;
2117 remainder = MAX_BAUD_RATE % baud;
2118 //Round to nearest divisor
2119 if(((remainder * 2) >= baud) && (baud != 110))
2120 divisor++;
2121
2122 //Set Baud rate to default and turn off (default)flow control here
2123 status = BoxSetUart(serial, UartNumber, (unsigned short) divisor, LCR_change_to);
2124 if (status < 0)
2125 {
2126 mydbg(__FILE__"BoxSetUart failed\n");
2127 return;
2128 }
2129 //************************Now determine flow control
2130
2131 if(cflag & CRTSCTS)
2132 {
2133 mydbg("%s - Enabling HW flow control port %d\n", __FUNCTION__, port->number);
2134
2135 //Enable RTS/CTS flow control
2136 status = BoxSetHW_FlowCtrl(serial, UartNumber, 1);
2137
2138 if (status < 0)
2139 {
2140 mydbg(__FILE__"BoxSetHW_FlowCtrl failed\n");
2141 return;
2142 }
2143 }
2144 else
2145 {
2146 //Disable RTS/CTS flow control
2147 mydbg("%s - disabling HW flow control port %d\n", __FUNCTION__, port->number);
2148
2149 status = BoxSetHW_FlowCtrl(serial, UartNumber, 0);
2150 if (status < 0)
2151 {
2152 mydbg(__FILE__"BoxSetHW_FlowCtrl failed\n");
2153 return;
2154 }
2155
2156
2157 }
2158
2159 //*************************************************
2160 /* if we are implementing XON/XOFF, set the start and stop character in the device */
2161 if (I_IXOFF(tty) || I_IXON(tty))
2162 {
2163 unsigned char stop_char = STOP_CHAR(tty);
2164 unsigned char start_char = START_CHAR(tty);
2165 status = BoxSetSW_FlowCtrl(serial, UartNumber, stop_char, start_char);
2166 if(status < 0)
2167 mydbg(__FILE__"BoxSetSW_FlowCtrl (enabled) failed\n");
2168
2169 }
2170 else
2171 {
2172 //disable SW flow control
2173 status = BoxDisable_SW_FlowCtrl(serial, UartNumber);
2174 if(status < 0)
2175 mydbg(__FILE__"BoxSetSW_FlowCtrl (diabling) failed\n");
2176
2177 }
2178
2179
2180
2181}
2182/****************************************************************************
2183* BoxGetRegister
2184* issuse a GET_REGISTER vendor-spcific request on the default control pipe
2185* If successful, fills in the pValue with the register value asked for
2186****************************************************************************/
2187static int BoxGetRegister(struct usb_serial *serial, unsigned short Uart_Number,
2188 unsigned short Register_Num, __u8 *pValue )
2189{
2190 int result;
2191 __u16 current_length;
2192
2193
2194 current_length = sizeof(struct qt_get_device_data);
2195
2196 result = usb_control_msg (serial->dev, usb_rcvctrlpipe(serial->dev, 0), QT_GET_SET_REGISTER,
2197 0xC0, Register_Num, Uart_Number, (void *)pValue, sizeof(*pValue), 300);
2198
2199 return result;
2200}
2201/****************************************************************************
2202* BoxSetRegister
2203* issuse a GET_REGISTER vendor-spcific request on the default control pipe
2204* If successful, fills in the pValue with the register value asked for
2205****************************************************************************/
2206static int BoxSetRegister(struct usb_serial *serial, unsigned short Uart_Number,
2207 unsigned short Register_Num, unsigned short Value )
2208{
2209 int result;
2210 unsigned short RegAndByte;
2211
2212
2213 RegAndByte = Value;
2214 RegAndByte = RegAndByte << 8;
2215 RegAndByte = RegAndByte + Register_Num;
2216
2217// result = usb_control_msg (serial->dev, usb_sndctrlpipe(serial->dev, 0), QT_GET_SET_REGISTER,
2218// 0xC0, Register_Num, Uart_Number, NULL, 0, 300);
2219
2220
2221 result = usb_control_msg (serial->dev, usb_sndctrlpipe(serial->dev, 0), QT_GET_SET_REGISTER,
2222 0x40, RegAndByte, Uart_Number, NULL,0, 300);
2223
2224
2225 return result;
2226}
2227
2228
2229
2230/**
2231 * box_get_device
2232 * Issue a GET_DEVICE vendor-specific request on the default control pipe If
2233 * successful, fills in the qt_get_device_data structure pointed to by
2234 * device_data, otherwise return a negative error number of the problem.
2235 */
2236static int box_get_device(struct usb_serial *serial,
2237 struct qt_get_device_data *device_data)
2238{
2239 int result;
2240 __u16 current_length;
2241 unsigned char *transfer_buffer;
2242
2243 current_length = sizeof(struct qt_get_device_data);
2244 transfer_buffer = kmalloc(current_length, GFP_KERNEL);
2245 if (!transfer_buffer)
2246 return -ENOMEM;
2247
2248 result = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0),
2249 QT_SET_GET_DEVICE, 0xc0, 0, 0,
2250 transfer_buffer, current_length, 300);
2251 if (result > 0)
2252 memcpy(device_data, transfer_buffer, current_length);
2253 kfree(transfer_buffer);
2254
2255 return result;
2256}
2257
2258/**
2259 * box_set_device
2260 * Issue a SET_DEVICE vendor-specific request on the default control pipe If
2261 * successful returns the number of bytes written, otherwise it returns a
2262 * negative error number of the problem.
2263 */
2264static int box_set_device(struct usb_serial *serial, struct qt_get_device_data *device_data)
2265{
2266 int result;
2267 __u16 length;
2268 __u16 PortSettings;
2269
2270 PortSettings = ((__u16)(device_data->portb));
2271 PortSettings = (PortSettings << 8);
2272 PortSettings += ((__u16)(device_data->porta));
2273
2274 length = sizeof(struct qt_get_device_data);
2275 mydbg("%s - PortSettings = 0x%x\n", __FUNCTION__, PortSettings);
2276
2277 result = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
2278 QT_SET_GET_DEVICE, 0x40, PortSettings,
2279 0, NULL, 0, 300);
2280 return result;
2281}
2282
2283/****************************************************************************
2284 * BoxOPenCloseChannel
2285 * This funciotn notifies the device that the device driver wishes to open a particular UART channel. its
2286 * purpose is to allow the device driver and the device to synchronize state information.
2287 * OpenClose = 1 for open , 0 for close
2288 ****************************************************************************/
2289static int BoxOPenCloseChannel(struct usb_serial *serial, __u16 Uart_Number, __u16 OpenClose, struct qt_open_channel_data *pDeviceData)
2290{
2291 int result;
2292 __u16 length;
2293 __u8 Direcion;
2294 unsigned int pipe;
2295 length = sizeof(struct qt_open_channel_data);
2296
2297 if (OpenClose == 1) //IF OPENING
2298 {
2299 Direcion = USBD_TRANSFER_DIRECTION_IN;
2300 pipe = usb_rcvctrlpipe(serial->dev, 0);
2301 result = usb_control_msg (serial->dev, pipe, QT_OPEN_CLOSE_CHANNEL,
2302 Direcion, OpenClose, Uart_Number, pDeviceData, length, 300);
2303
2304
2305 }
2306 else
2307 {
2308 Direcion = USBD_TRANSFER_DIRECTION_OUT;
2309 pipe = usb_sndctrlpipe(serial->dev, 0);
2310 result = usb_control_msg (serial->dev, pipe, QT_OPEN_CLOSE_CHANNEL,
2311 Direcion, OpenClose, Uart_Number, NULL, 0, 300);
2312
2313 }
2314
2315
2316
2317 return result;
2318}
2319
2320/****************************************************************************
2321 * BoxSetPrebufferLevel
2322 TELLS BOX WHEN TO ASSERT FLOW CONTROL
2323 ****************************************************************************/
2324static int BoxSetPrebufferLevel(struct usb_serial *serial)
2325{
2326 int result;
2327 __u16 buffer_length;
2328
2329 buffer_length = PREFUFF_LEVEL_CONSERVATIVE;
2330 result = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
2331 QT_GET_SET_PREBUF_TRIG_LVL, 0x40,
2332 buffer_length, 0, NULL, 0, 300);
2333 return result;
2334}
2335
2336
2337
2338/****************************************************************************
2339 * BoxSetATC
2340 TELLS BOX WHEN TO ASSERT automatic transmitter control
2341 ****************************************************************************/
2342static int BoxSetATC(struct usb_serial *serial, __u16 n_Mode)
2343{
2344 int result;
2345 __u16 buffer_length;
2346
2347
2348 buffer_length = PREFUFF_LEVEL_CONSERVATIVE;
2349
2350 result = usb_control_msg (serial->dev, usb_sndctrlpipe(serial->dev, 0), QT_SET_ATF,
2351 0x40, n_Mode, 0, NULL, 0, 300);
2352
2353 return result;
2354}
2355
2356/****************************************************************************
2357* BoxSetUart
2358* issuse a SET_UART vendor-spcific request on the default control pipe
2359* If successful sets baud rate divisor and LCR value
2360****************************************************************************/
2361static int BoxSetUart(struct usb_serial *serial, unsigned short Uart_Number,
2362 unsigned short default_divisor, unsigned char default_LCR )
2363{
2364 int result;
2365 unsigned short UartNumandLCR;
2366
2367 UartNumandLCR = (default_LCR << 8) + Uart_Number;
2368
2369 result = usb_control_msg (serial->dev, usb_sndctrlpipe(serial->dev, 0), QT_GET_SET_UART,
2370 0x40, default_divisor, UartNumandLCR, NULL, 0, 300);
2371
2372 return result;
2373}
2374
2375
2376static int BoxSetHW_FlowCtrl(struct usb_serial *serial, unsigned int UartNumber, int bSet)
2377{
2378 __u8 MCR_Value = 0;
2379 __u8 MSR_Value = 0, MOUT_Value = 0;
2380 struct usb_serial_port *port;
2381 unsigned int status;
2382
2383 port = serial->port;
2384
2385 if (bSet == 1)
2386 {
2387 MCR_Value = SERIAL_MCR_RTS; //flow control, box will clear RTS line to prevent remote
2388 } //device from xmitting more chars
2389 else
2390 { //no flow control to remote device
2391 MCR_Value = 0;
2392
2393 }
2394 MOUT_Value = MCR_Value << 8;
2395
2396
2397 if(bSet == 1)
2398 {
2399 MSR_Value = SERIAL_MSR_CTS; //flow control, box will inhibit xmit data if CTS line is asserted
2400 }
2401 else
2402 {
2403 MSR_Value = 0; //Box will not inhimbe xmit data due to CTS line
2404 }
2405 MOUT_Value |= MSR_Value;
2406
2407
2408 status = usb_control_msg (serial->dev, usb_sndctrlpipe(serial->dev, 0), QT_HW_FLOW_CONTROL_MASK,
2409 0x40, MOUT_Value, UartNumber, NULL, 0, 300);
2410 return status;
2411
2412}
2413
2414static int BoxSetSW_FlowCtrl(struct usb_serial *serial, __u16 UartNumber, unsigned char stop_char, unsigned char start_char)
2415{
2416 __u16 nSWflowout;
2417 int result;
2418
2419 nSWflowout = start_char << 8;
2420 nSWflowout = (unsigned short)stop_char;
2421
2422 result = usb_control_msg (serial->dev, usb_sndctrlpipe(serial->dev, 0), QT_SW_FLOW_CONTROL_MASK,
2423 0x40, nSWflowout, UartNumber, NULL, 0, 300);
2424 return result;
2425
2426}
2427static int BoxDisable_SW_FlowCtrl(struct usb_serial *serial, __u16 UartNumber)
2428{
2429 int result;
2430
2431
2432 result = usb_control_msg (serial->dev, usb_sndctrlpipe(serial->dev, 0), QT_SW_FLOW_CONTROL_DISABLE,
2433 0x40, 0, UartNumber, NULL, 0, 300);
2434 return result;
2435
2436}
2437
2438
2439/*****************************************************************************
2440 * SerialThrottle
2441 * this function is called by the tty driver when it wants to stop the data
2442 * being read from the port.
2443 *****************************************************************************/
2444
2445
2446static void serial_throttle (struct tty_struct * tty)
2447{
2448 struct usb_serial_port *port = (struct usb_serial_port *) tty->driver_data;
2449 struct usb_serial *serial = get_usb_serial (port, __FUNCTION__);
2450 mydbg("%s - port %d\n", __FUNCTION__, port->number);
2451
2452 if (!serial)
2453 return;
2454
2455 down (&port->sem);
2456
2457
2458 if (!port->open_count) {
2459 mydbg ("%s - port not open\n", __FUNCTION__);
2460 goto exit;
2461 }
2462 //shut down any bulk reads that may be going on
2463// usb_unlink_urb (port->read_urb);
2464 /* pass on to the driver specific version of this function */
2465 port->RxHolding = 1;
2466 mydbg("%s - port->RxHolding = 1\n", __FUNCTION__);
2467
2468
2469exit:
2470 up (&port->sem);
2471 return;
2472}
2473
2474static void serial_unthrottle (struct tty_struct * tty)
2475{
2476 struct usb_serial_port *port = (struct usb_serial_port *) tty->driver_data;
2477 struct usb_serial *serial = get_usb_serial (port, __FUNCTION__);
2478 unsigned int result;
2479
2480 if (!serial)
2481 return;
2482 down (&port->sem);
2483
2484 mydbg("%s - port %d\n", __FUNCTION__, port->number);
2485
2486 if (!port->open_count) {
2487 mydbg ("%s - port not open\n", __FUNCTION__);
2488 goto exit;
2489 }
2490
2491 if(port->RxHolding == 1)
2492 {
2493 mydbg ("%s -port->RxHolding == 1\n", __FUNCTION__);
2494
2495 port->RxHolding = 0;
2496 mydbg ("%s - port->RxHolding = 0\n", __FUNCTION__);
2497
2498 /* if we have a bulk endpoint, start it up */
2499 if ((serial->num_bulk_in) && (port->ReadBulkStopped == 1))
2500 {
2501 /* Start reading from the device */
2502 usb_fill_bulk_urb (port->read_urb, serial->dev,
2503 usb_rcvbulkpipe(serial->dev, port->bulk_in_endpointAddress),
2504 port->read_urb->transfer_buffer,
2505 port->read_urb->transfer_buffer_length,
2506 qt_read_bulk_callback,
2507 port);
2508 result = usb_submit_urb(port->read_urb, GFP_ATOMIC);
2509 if (result)
2510 err("%s - failed restarting read urb, error %d", __FUNCTION__, result);
2511 }
2512 }
2513 exit:
2514 up (&port->sem);
2515 return;
2516
2517
2518
2519}
2520
2521
2522static int serial_break (struct tty_struct *tty, int break_state)
2523{
2524 struct usb_serial_port *port = (struct usb_serial_port *) tty->driver_data;
2525 struct usb_serial *serial = get_usb_serial (port, __FUNCTION__);
2526 __u16 UartNumber, Break_Value;
2527 unsigned int result;
2528
2529 UartNumber = port->tty->index - serial->minor;
2530 if (!serial)
2531 return -ENODEV;
2532
2533 if(break_state == -1)
2534 Break_Value = 1;
2535 else
2536 Break_Value = 0;
2537
2538 down (&port->sem);
2539
2540 mydbg("%s - port %d\n", __FUNCTION__, port->number);
2541
2542 if (!port->open_count) {
2543 mydbg("%s - port not open\n", __FUNCTION__);
2544 goto exit;
2545 }
2546
2547 result = usb_control_msg (serial->dev, usb_sndctrlpipe(serial->dev, 0), QT_BREAK_CONTROL,
2548 0x40, Break_Value, UartNumber, NULL, 0, 300);
2549
2550exit:
2551 up (&port->sem);
2552 return 0;
2553}
2554
2555
2556
2557
2558static int serial_read_proc (char *page, char **start, off_t off, int count, int *eof, void *data)
2559{
2560 struct usb_serial *serial;
2561 int length = 0;
2562 int i;
2563 off_t begin = 0;
2564
2565 mydbg("%s\n", __FUNCTION__);
2566 length += sprintf (page, "usbserinfo:1.0 driver:%s\n", DRIVER_VERSION);
2567 for (i = 0; i < SERIAL_TTY_MINORS && length < PAGE_SIZE; ++i) {
2568 serial = get_serial_by_minor(i);
2569 if (serial == NULL)
2570 continue;
2571
2572 length += sprintf (page+length, "%d:\n", i);
2573 length += sprintf (page+length, " vendor:%04x product:%04x\n", serial->vendor, serial->product);
2574 length += sprintf (page+length, " num_ports:%d\n", serial->num_ports);
2575 length += sprintf (page+length, " port:%d\n", i - serial->minor + 1);
2576
2577// usb_make_path(serial->dev, tmp, sizeof(tmp));
2578// length += sprintf (page+length, " path:%s", tmp);
2579
2580 length += sprintf (page+length, "\n");
2581 if ((length + begin) > (off + count))
2582 goto done;
2583 if ((length + begin) < off) {
2584 begin += length;
2585 length = 0;
2586 }
2587 }
2588 *eof = 1;
2589done:
2590 if (off >= (length + begin))
2591 return 0;
2592 *start = page + (off-begin);
2593 return ((count < begin+length-off) ? count : begin+length-off);
2594}
2595
2596
2597
2598int ioctl_serial_usb (struct inode *innod, struct file *filp, unsigned int cmd,
2599 unsigned long arg)
2600{
2601
2602 unsigned err;
2603 unsigned ucOPR_NewValue, uc_Value;
2604 int *p_Num_of_adapters, counts, index, *p_QMCR_Value;
2605 struct identity *p_Identity_of;
2606 struct identity Identity_of;
2607 struct usb_serial *lastserial, *serial;
2608
2609 mydbg(KERN_DEBUG"ioctl_serial_usb cmd =\n");
2610 if (_IOC_TYPE(cmd) != SERIALQT_PCI_IOC_MAGIC)
2611 return -ENOTTY;
2612 if (_IOC_NR(cmd) > SERIALQT_IOC_MAXNR)
2613 return -ENOTTY;
2614 mydbg(KERN_DEBUG"ioctl_serial_usb cmd = 0x%x\n", cmd);
2615 err = 0;
2616 switch (cmd)
2617 {
2618
2619
2620 case SERIALQT_WRITE_QMCR:
2621 err = -ENOTTY; //initialize as error so if we don't find this one we give//an error.
2622 index = arg >> 16;
2623 counts = 0;
2624
2625 ucOPR_NewValue = arg;
2626
2627
2628 err = EmulateWriteQMCR_Reg(index, ucOPR_NewValue);
2629 break;
2630
2631 case SERIALQT_READ_QMCR:
2632 err = -ENOTTY; //initialize as error so if we don't find this one we give
2633 //an error.
2634 p_QMCR_Value = (int *)arg;
2635 index = arg >> 16;
2636 counts = 0;
2637
2638
2639
2640 err = EmulateReadQMCR_Reg(index, &uc_Value);
2641 if (err == 0)
2642 {
2643 err = put_user(uc_Value, p_QMCR_Value);
2644 }
2645 break;
2646
2647 case SERIALQT_GET_NUMOF_UNITS:
2648 p_Num_of_adapters = (int *)arg;
2649 counts = 0; //Initialize counts to zero
2650 //struct usb_serial *lastserial = serial_table[0], *serial;
2651 lastserial = serial_table[0];
2652
2653 mydbg(KERN_DEBUG"SERIALQT_GET_NUMOF_UNITS \n");
2654 //if first pointer is nonull, we at least have one box
2655 if(lastserial)
2656 counts = 1; //we at least have one box
2657
2658 for (index = 1; index < SERIAL_TTY_MINORS ; index++)
2659 {
2660 serial = serial_table[index];
2661 if(serial)
2662 {
2663 if(serial != lastserial)
2664 {
2665 //we had a change in the array, hence another box is there
2666 lastserial = serial;
2667 counts++;
2668 }
2669 }
2670 else
2671 break;
2672 }
2673
2674 mydbg(KERN_DEBUG"ioctl_serial_usb writting counts = %d", counts);
2675
2676 err = put_user(counts, p_Num_of_adapters);
2677
2678
2679 break;
2680 case SERIALQT_GET_THIS_UNIT:
2681 counts = 0;
2682 p_Identity_of = (struct identity *)arg;
2683 //copy user structure to local variable
2684 get_user(Identity_of.index, &p_Identity_of->index);
2685 mydbg(KERN_DEBUG"SERIALQT_GET_THIS_UNIT Identity_of.index\n");
2686 mydbg(KERN_DEBUG"SERIALQT_GET_THIS_UNIT Identity_of.index= 0x%x\n", Identity_of.index);
2687
2688 err = -ENOTTY; //initialize as error so if we don't find this one we give
2689 //an error.
2690 serial = find_the_box(Identity_of.index);
2691 if(serial)
2692 {
2693 err = put_user(serial->product, &p_Identity_of->n_identity);
2694
2695 }
2696 break;
2697
2698 case SERIALQT_IS422_EXTENDED:
2699 err = -ENOTTY; //initialize as error so if we don't find this one we give
2700 mydbg(KERN_DEBUG"SERIALQT_IS422_EXTENDED \n");
2701 //an error.
2702 index = arg >> 16;
2703
2704
2705 counts = 0;
2706
2707 mydbg(KERN_DEBUG"SERIALQT_IS422_EXTENDED, looking Identity_of.indext = 0x%x\n",index);
2708 serial = find_the_box(index);
2709 if(serial)
2710 {
2711 mydbg("%s index = 0x%x, serial = 0x%p\n", __FUNCTION__, index, serial);
2712 for (counts = 0; serqt_422_table[counts] != 0; counts++)
2713 {
2714
2715 mydbg("%s serial->product = = 0x%x, serqt_422_table[counts] = 0x%x\n", __FUNCTION__, serial->product, serqt_422_table[counts]);
2716 if(serial->product == serqt_422_table[counts])
2717 {
2718 err = 0;
2719
2720 mydbg("%s found match for 422extended\n", __FUNCTION__);
2721 break;
2722 }
2723 }
2724 }
2725 break;
2726
2727
2728
2729
2730 default:
2731 err = -ENOTTY;
2732
2733
2734
2735
2736 } //End switch
2737
2738 mydbg("%s returning err = 0x%x\n", __FUNCTION__, err);
2739 return err;
2740}
2741
2742
2743
2744static struct usb_serial *find_the_box(unsigned int index)
2745{
2746 struct usb_serial *lastserial, *foundserial, *serial;
2747 int counts = 0, index2;
2748 lastserial = serial_table[0];
2749 foundserial = NULL;
2750 for (index2 = 0; index2 < SERIAL_TTY_MINORS ; index2++)
2751 {
2752 serial = serial_table[index2];
2753
2754 mydbg("%s index = 0x%x, index2 = 0x%x, serial = 0x%p\n", __FUNCTION__, index, index2, serial);
2755
2756 if(serial)
2757 {
2758 //first see if this is the unit we'er looking for
2759 mydbg("%s inside if(serial) counts = 0x%x , index = 0x%x\n", __FUNCTION__, counts, index);
2760 if(counts == index)
2761 {
2762 //we found the one we're looking for, copythe product Id to user
2763
2764 mydbg("%s we found the one we're looking for serial = 0x%p\n", __FUNCTION__, serial);
2765 foundserial = serial;
2766 break;
2767 }
2768
2769 if(serial != lastserial)
2770 {
2771 //when we have a change in the pointer
2772 lastserial = serial;
2773 counts++;
2774 }
2775 }
2776 else
2777 break; // no matches
2778 }
2779
2780 mydbg("%s returning foundserial = 0x%p\n", __FUNCTION__, foundserial);
2781 return foundserial;
2782}
2783
2784
2785
2786 static int EmulateWriteQMCR_Reg(int index, unsigned uc_value)
2787 {
2788
2789 __u16 ATC_Mode = 0;
2790 struct usb_serial *serial;
2791 int status;
2792 struct qt_get_device_data DeviceData;
2793 unsigned uc_temp = 0;
2794 mydbg("Inside %s, uc_value = 0x%x\n", __FUNCTION__, uc_value);
2795
2796 DeviceData.porta = 0;
2797 DeviceData.portb = 0;
2798 serial = find_the_box(index);
2799 //Determine Duplex mode
2800 if(!(serial))
2801 return -ENOTTY;
2802 status = box_get_device(serial, &DeviceData);
2803 if (status < 0)
2804 {
2805 mydbg(__FILE__"box_set_device failed\n");
2806 return status;
2807 }
2808
2809 uc_temp = uc_value & QMCR_HALF_DUPLEX_MASK;
2810 switch (uc_temp)
2811 {
2812 case QMCR_FULL_DUPLEX:
2813 DeviceData.porta &= ~DUPMODE_BITS;
2814 DeviceData.porta |= FULL_DUPLEX;
2815 ATC_Mode = ATC_DISABLED;
2816 break;
2817 case QMCR_HALF_DUPLEX_RTS:
2818 DeviceData.porta &= ~DUPMODE_BITS;
2819 DeviceData.porta |= HALF_DUPLEX_RTS;
2820 ATC_Mode = ATC_RTS_ENABLED;
2821 break;
2822 case QMCR_HALF_DUPLEX_DTR:
2823 DeviceData.porta &= ~DUPMODE_BITS;
2824 DeviceData.porta |= HALF_DUPLEX_DTR;
2825 ATC_Mode = ATC_DTR_ENABLED;
2826 break;
2827 default:
2828 break;
2829 }
2830
2831 uc_temp = uc_value & QMCR_CONNECTOR_MASK;
2832 switch (uc_temp)
2833 {
2834 case QMCR_MODEM_CONTROL:
2835 DeviceData.portb &= ~LOOPMODE_BITS; //reset connection bits
2836 DeviceData.portb |= MODEM_CTRL;
2837 break;
2838 case QMCR_ALL_LOOPBACK:
2839 DeviceData.portb &= ~LOOPMODE_BITS; //reset connection bits
2840 DeviceData.portb |= ALL_LOOPBACK;
2841 break;
2842 }
2843
2844 mydbg(__FILE__"Calling box_set_device with failed\n");
2845 status = box_set_device(serial, &DeviceData);
2846 if (status < 0)
2847 {
2848 mydbg(__FILE__"box_set_device failed\n");
2849 return status;
2850 }
2851
2852 if(uc_value & QMCR_RX_EN_MASK) //This bit (otherwise unused) i'll used to detect whether ATC is selected
2853 {
2854
2855 mydbg(__FILE__"calling BoxsetATC with DeviceData.porta = 0x%x and DeviceData.portb = 0x%x\n", DeviceData.porta, DeviceData.portb);
2856 status = BoxSetATC(serial, ATC_Mode);
2857 if (status < 0)
2858 {
2859 mydbg(__FILE__"BoxSetATC failed\n");
2860 return status;
2861 }
2862 }
2863 else
2864 {
2865
2866 mydbg(__FILE__"calling BoxsetATC with DeviceData.porta = 0x%x and DeviceData.portb = 0x%x\n", DeviceData.porta, DeviceData.portb);
2867 status = BoxSetATC(serial, ATC_DISABLED);
2868 if (status < 0)
2869 {
2870 mydbg(__FILE__"BoxSetATC failed\n");
2871 return status;
2872 }
2873 }
2874
2875
2876 return 0;
2877
2878 }
2879
2880
2881static int EmulateReadQMCR_Reg(int index, unsigned *uc_value)
2882{
2883 struct usb_serial *serial;
2884 int status;
2885 struct qt_get_device_data DeviceData;
2886 __u8 uc_temp;
2887
2888 *uc_value = 0;
2889
2890 serial = find_the_box(index);
2891 if(!(serial))
2892 return -ENOTTY;
2893
2894 status = box_get_device(serial, &DeviceData);
2895 if (status < 0)
2896 {
2897 mydbg(__FILE__"box_get_device failed\n");
2898 return status;
2899 }
2900 uc_temp = DeviceData.porta & DUPMODE_BITS;
2901 switch (uc_temp)
2902 {
2903 case FULL_DUPLEX:
2904 *uc_value |= QMCR_FULL_DUPLEX;
2905 break;
2906 case HALF_DUPLEX_RTS:
2907 *uc_value |= QMCR_HALF_DUPLEX_RTS;
2908 break;
2909 case HALF_DUPLEX_DTR:
2910 *uc_value |= QMCR_HALF_DUPLEX_DTR;
2911 break;
2912 default:
2913 break;
2914 }
2915
2916 uc_temp = DeviceData.portb & LOOPMODE_BITS; //I use this for ATC control se
2917
2918 switch (uc_temp)
2919 {
2920 case ALL_LOOPBACK:
2921 *uc_value |= QMCR_ALL_LOOPBACK;
2922 break;
2923 case MODEM_CTRL:
2924 *uc_value |= QMCR_MODEM_CONTROL;
2925 break;
2926 default:
2927 break;
2928
2929 }
2930 return 0;
2931
2932
2933 }
2934
2935static int __init serqt_usb_init(void)
2936{
2937 int i, result;
2938 int status = 0;
2939
2940 mydbg("%s\n", __FUNCTION__);
2941 tty_set_operations(&serial_tty_driver, &serial_ops);
2942 result = tty_register_driver(&serial_tty_driver);
2943 if (result) {
2944 mydbg("tty_register_driver failed error = 0x%x", result);
2945 return result;
2946 }
2947
2948 /* Initalize our global data */
2949 for (i = 0; i < SERIAL_TTY_MINORS; ++i)
2950 serial_table[i] = NULL;
2951
2952 /* register this driver with the USB subsystem */
2953 result = usb_register(&serqt_usb_driver);
2954 if (result < 0) {
2955 err("usb_register failed for the "__FILE__" driver. Error number %d", result);
2956 return result;
2957 }
2958 status = 0; // Dynamic assignment of major number
2959 major_number = register_chrdev(status, "SerialQT_USB", &serialqt_usb_fops);
2960 if (major_number < 0) {
2961 mydbg(KERN_DEBUG"No devices found \n\n");
2962 return -EBUSY;
2963 } else
2964 mydbg(KERN_DEBUG"SerQT_USB major number assignment = %d \n\n", major_number);
2965
2966 printk(KERN_INFO DRIVER_DESC " " DRIVER_VERSION);
2967 return 0;
2968}
2969
2970static void __exit serqt_usb_exit(void)
2971{
2972 /* deregister this driver with the USB subsystem */
2973 usb_deregister(&serqt_usb_driver);
2974 tty_unregister_driver(&serial_tty_driver);
2975 unregister_chrdev(major_number, "SerialQT_USB");
2976}
2977
2978module_init(serqt_usb_init);
2979module_exit(serqt_usb_exit);
2980
2981MODULE_AUTHOR(DRIVER_AUTHOR);
2982MODULE_DESCRIPTION(DRIVER_DESC);
2983MODULE_LICENSE("GPL");