diff options
author | Bill Pemberton <wfp5p@virginia.edu> | 2012-05-10 15:36:02 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2012-05-10 15:46:20 -0400 |
commit | f7a33e608d9ae022b7f49307921627e34e9484ed (patch) | |
tree | 3a79bab96780a9bfffa9bcd774587f3438ce2c46 | |
parent | 1fbfeff9274561d110eb796e60726bc54e95db97 (diff) |
USB: serial: add quatech2 usb to serial driver
This supports the Quatech USB 2 usb to serial adapters.
Signed-off-by: Bill Pemberton <wfp5p@virginia.edu>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r-- | drivers/usb/serial/Kconfig | 9 | ||||
-rw-r--r-- | drivers/usb/serial/Makefile | 1 | ||||
-rw-r--r-- | drivers/usb/serial/quatech2.c | 1149 |
3 files changed, 1159 insertions, 0 deletions
diff --git a/drivers/usb/serial/Kconfig b/drivers/usb/serial/Kconfig index 7141d6599060..325d2910f9f9 100644 --- a/drivers/usb/serial/Kconfig +++ b/drivers/usb/serial/Kconfig | |||
@@ -669,6 +669,15 @@ config USB_SERIAL_SSU100 | |||
669 | To compile this driver as a module, choose M here: the | 669 | To compile this driver as a module, choose M here: the |
670 | module will be called ssu100. | 670 | module will be called ssu100. |
671 | 671 | ||
672 | config USB_SERIAL_QT2 | ||
673 | tristate "USB Quatech Serial Driver for USB 2 devices" | ||
674 | help | ||
675 | Say Y here if you want to use the Quatech USB 2 | ||
676 | serial adapters. | ||
677 | |||
678 | To compile this driver as a module, choose M here: the | ||
679 | module will be called quatech-serial. | ||
680 | |||
672 | config USB_SERIAL_DEBUG | 681 | config USB_SERIAL_DEBUG |
673 | tristate "USB Debugging Device" | 682 | tristate "USB Debugging Device" |
674 | help | 683 | help |
diff --git a/drivers/usb/serial/Makefile b/drivers/usb/serial/Makefile index 07f198ee0486..1dc483a8bfc7 100644 --- a/drivers/usb/serial/Makefile +++ b/drivers/usb/serial/Makefile | |||
@@ -49,6 +49,7 @@ obj-$(CONFIG_USB_SERIAL_OTI6858) += oti6858.o | |||
49 | obj-$(CONFIG_USB_SERIAL_PL2303) += pl2303.o | 49 | obj-$(CONFIG_USB_SERIAL_PL2303) += pl2303.o |
50 | obj-$(CONFIG_USB_SERIAL_QCAUX) += qcaux.o | 50 | obj-$(CONFIG_USB_SERIAL_QCAUX) += qcaux.o |
51 | obj-$(CONFIG_USB_SERIAL_QUALCOMM) += qcserial.o | 51 | obj-$(CONFIG_USB_SERIAL_QUALCOMM) += qcserial.o |
52 | obj-$(CONFIG_USB_SERIAL_QT2) += quatech2.o | ||
52 | obj-$(CONFIG_USB_SERIAL_SAFE) += safe_serial.o | 53 | obj-$(CONFIG_USB_SERIAL_SAFE) += safe_serial.o |
53 | obj-$(CONFIG_USB_SERIAL_SIEMENS_MPI) += siemens_mpi.o | 54 | obj-$(CONFIG_USB_SERIAL_SIEMENS_MPI) += siemens_mpi.o |
54 | obj-$(CONFIG_USB_SERIAL_SIERRAWIRELESS) += sierra.o | 55 | obj-$(CONFIG_USB_SERIAL_SIERRAWIRELESS) += sierra.o |
diff --git a/drivers/usb/serial/quatech2.c b/drivers/usb/serial/quatech2.c new file mode 100644 index 000000000000..3aa63f1f6dfe --- /dev/null +++ b/drivers/usb/serial/quatech2.c | |||
@@ -0,0 +1,1149 @@ | |||
1 | /* | ||
2 | * usb-serial driver for Quatech USB 2 devices | ||
3 | * | ||
4 | * | ||
5 | * These devices all have only 1 bulk in and 1 bulk out that is shared | ||
6 | * for all serial ports. | ||
7 | * | ||
8 | */ | ||
9 | |||
10 | #include <asm/unaligned.h> | ||
11 | #include <linux/errno.h> | ||
12 | #include <linux/init.h> | ||
13 | #include <linux/slab.h> | ||
14 | #include <linux/tty.h> | ||
15 | #include <linux/tty_driver.h> | ||
16 | #include <linux/tty_flip.h> | ||
17 | #include <linux/module.h> | ||
18 | #include <linux/serial.h> | ||
19 | #include <linux/usb.h> | ||
20 | #include <linux/usb/serial.h> | ||
21 | #include <linux/serial_reg.h> | ||
22 | #include <linux/uaccess.h> | ||
23 | |||
24 | static bool debug; | ||
25 | |||
26 | /* default urb timeout for usb operations */ | ||
27 | #define QT2_USB_TIMEOUT USB_CTRL_SET_TIMEOUT | ||
28 | |||
29 | #define QT_OPEN_CLOSE_CHANNEL 0xca | ||
30 | #define QT_SET_GET_DEVICE 0xc2 | ||
31 | #define QT_SET_GET_REGISTER 0xc0 | ||
32 | #define QT_GET_SET_PREBUF_TRIG_LVL 0xcc | ||
33 | #define QT_SET_ATF 0xcd | ||
34 | #define QT_TRANSFER_IN 0xc0 | ||
35 | #define QT_HW_FLOW_CONTROL_MASK 0xc5 | ||
36 | #define QT_SW_FLOW_CONTROL_MASK 0xc6 | ||
37 | #define QT2_BREAK_CONTROL 0xc8 | ||
38 | #define QT2_GET_SET_UART 0xc1 | ||
39 | #define QT2_FLUSH_DEVICE 0xc4 | ||
40 | #define QT2_GET_SET_QMCR 0xe1 | ||
41 | #define QT2_QMCR_RS232 0x40 | ||
42 | #define QT2_QMCR_RS422 0x10 | ||
43 | |||
44 | #define SERIAL_CRTSCTS ((UART_MCR_RTS << 8) | UART_MSR_CTS) | ||
45 | |||
46 | #define SERIAL_EVEN_PARITY (UART_LCR_PARITY | UART_LCR_EPAR) | ||
47 | |||
48 | /* status bytes for the device */ | ||
49 | #define QT2_CONTROL_BYTE 0x1b | ||
50 | #define QT2_LINE_STATUS 0x00 /* following 1 byte is line status */ | ||
51 | #define QT2_MODEM_STATUS 0x01 /* following 1 byte is modem status */ | ||
52 | #define QT2_XMIT_HOLD 0x02 /* following 2 bytes are ?? */ | ||
53 | #define QT2_CHANGE_PORT 0x03 /* following 1 byte is port to change to */ | ||
54 | #define QT2_REC_FLUSH 0x04 /* no following info */ | ||
55 | #define QT2_XMIT_FLUSH 0x05 /* no following info */ | ||
56 | #define QT2_CONTROL_ESCAPE 0xff /* pass through previous 2 control bytes */ | ||
57 | |||
58 | #define MAX_BAUD_RATE 921600 | ||
59 | #define DEFAULT_BAUD_RATE 9600 | ||
60 | |||
61 | #define QT2_WRITE_BUFFER_SIZE 512 /* size of write buffer */ | ||
62 | #define QT2_WRITE_CONTROL_SIZE 5 /* control bytes used for a write */ | ||
63 | |||
64 | /* Version Information */ | ||
65 | #define DRIVER_VERSION "v0.1" | ||
66 | #define DRIVER_DESC "Quatech 2nd gen USB to Serial Driver" | ||
67 | |||
68 | #define USB_VENDOR_ID_QUATECH 0x061d | ||
69 | #define QUATECH_SSU2_100 0xC120 /* RS232 single port */ | ||
70 | #define QUATECH_DSU2_100 0xC140 /* RS232 dual port */ | ||
71 | #define QUATECH_DSU2_400 0xC150 /* RS232/422/485 dual port */ | ||
72 | #define QUATECH_QSU2_100 0xC160 /* RS232 four port */ | ||
73 | #define QUATECH_QSU2_400 0xC170 /* RS232/422/485 four port */ | ||
74 | #define QUATECH_ESU2_100 0xC1A0 /* RS232 eight port */ | ||
75 | #define QUATECH_ESU2_400 0xC180 /* RS232/422/485 eight port */ | ||
76 | |||
77 | struct qt2_device_detail { | ||
78 | int product_id; | ||
79 | int num_ports; | ||
80 | }; | ||
81 | |||
82 | #define QT_DETAILS(prod, ports) \ | ||
83 | .product_id = (prod), \ | ||
84 | .num_ports = (ports) | ||
85 | |||
86 | static const struct qt2_device_detail qt2_device_details[] = { | ||
87 | {QT_DETAILS(QUATECH_SSU2_100, 1)}, | ||
88 | {QT_DETAILS(QUATECH_DSU2_400, 2)}, | ||
89 | {QT_DETAILS(QUATECH_DSU2_100, 2)}, | ||
90 | {QT_DETAILS(QUATECH_QSU2_400, 4)}, | ||
91 | {QT_DETAILS(QUATECH_QSU2_100, 4)}, | ||
92 | {QT_DETAILS(QUATECH_ESU2_400, 8)}, | ||
93 | {QT_DETAILS(QUATECH_ESU2_100, 8)}, | ||
94 | {QT_DETAILS(0, 0)} /* Terminating entry */ | ||
95 | }; | ||
96 | |||
97 | static const struct usb_device_id id_table[] = { | ||
98 | {USB_DEVICE(USB_VENDOR_ID_QUATECH, QUATECH_SSU2_100)}, | ||
99 | {USB_DEVICE(USB_VENDOR_ID_QUATECH, QUATECH_DSU2_100)}, | ||
100 | {USB_DEVICE(USB_VENDOR_ID_QUATECH, QUATECH_DSU2_400)}, | ||
101 | {USB_DEVICE(USB_VENDOR_ID_QUATECH, QUATECH_QSU2_100)}, | ||
102 | {USB_DEVICE(USB_VENDOR_ID_QUATECH, QUATECH_QSU2_400)}, | ||
103 | {USB_DEVICE(USB_VENDOR_ID_QUATECH, QUATECH_ESU2_100)}, | ||
104 | {USB_DEVICE(USB_VENDOR_ID_QUATECH, QUATECH_ESU2_400)}, | ||
105 | {} /* Terminating entry */ | ||
106 | }; | ||
107 | MODULE_DEVICE_TABLE(usb, id_table); | ||
108 | |||
109 | struct qt2_serial_private { | ||
110 | unsigned char current_port; /* current port for incoming data */ | ||
111 | |||
112 | struct urb *read_urb; /* shared among all ports */ | ||
113 | char read_buffer[512]; | ||
114 | }; | ||
115 | |||
116 | struct qt2_port_private { | ||
117 | bool is_open; | ||
118 | u8 device_port; | ||
119 | |||
120 | spinlock_t urb_lock; | ||
121 | bool urb_in_use; | ||
122 | struct urb *write_urb; | ||
123 | char write_buffer[QT2_WRITE_BUFFER_SIZE]; | ||
124 | |||
125 | spinlock_t lock; | ||
126 | u8 shadowLSR; | ||
127 | u8 shadowMSR; | ||
128 | |||
129 | wait_queue_head_t delta_msr_wait; /* Used for TIOCMIWAIT */ | ||
130 | struct async_icount icount; | ||
131 | |||
132 | struct usb_serial_port *port; | ||
133 | }; | ||
134 | |||
135 | static void qt2_update_lsr(struct usb_serial_port *port, unsigned char *ch); | ||
136 | static void qt2_update_msr(struct usb_serial_port *port, unsigned char *ch); | ||
137 | static void qt2_write_bulk_callback(struct urb *urb); | ||
138 | static void qt2_read_bulk_callback(struct urb *urb); | ||
139 | |||
140 | static void qt2_release(struct usb_serial *serial) | ||
141 | { | ||
142 | int i; | ||
143 | |||
144 | kfree(usb_get_serial_data(serial)); | ||
145 | |||
146 | for (i = 0; i < serial->num_ports; i++) | ||
147 | kfree(usb_get_serial_port_data(serial->port[i])); | ||
148 | } | ||
149 | |||
150 | static inline int calc_baud_divisor(int baudrate) | ||
151 | { | ||
152 | int divisor, rem; | ||
153 | |||
154 | divisor = MAX_BAUD_RATE / baudrate; | ||
155 | rem = MAX_BAUD_RATE % baudrate; | ||
156 | /* Round to nearest divisor */ | ||
157 | if (((rem * 2) >= baudrate) && (baudrate != 110)) | ||
158 | divisor++; | ||
159 | |||
160 | return divisor; | ||
161 | } | ||
162 | |||
163 | static inline int qt2_set_port_config(struct usb_device *dev, | ||
164 | unsigned char port_number, | ||
165 | u16 baudrate, u16 lcr) | ||
166 | { | ||
167 | int divisor = calc_baud_divisor(baudrate); | ||
168 | u16 index = ((u16) (lcr << 8) | (u16) (port_number)); | ||
169 | |||
170 | return usb_control_msg(dev, usb_sndctrlpipe(dev, 0), | ||
171 | QT2_GET_SET_UART, 0x40, | ||
172 | divisor, index, NULL, 0, QT2_USB_TIMEOUT); | ||
173 | } | ||
174 | |||
175 | static inline int qt2_control_msg(struct usb_device *dev, | ||
176 | u8 request, u16 data, u16 index) | ||
177 | { | ||
178 | return usb_control_msg(dev, usb_sndctrlpipe(dev, 0), | ||
179 | request, 0x40, data, index, | ||
180 | NULL, 0, QT2_USB_TIMEOUT); | ||
181 | } | ||
182 | |||
183 | static inline int qt2_setdevice(struct usb_device *dev, u8 *data) | ||
184 | { | ||
185 | u16 x = ((u16) (data[1] << 8) | (u16) (data[0])); | ||
186 | |||
187 | return qt2_control_msg(dev, QT_SET_GET_DEVICE, x, 0); | ||
188 | } | ||
189 | |||
190 | |||
191 | static inline int qt2_getdevice(struct usb_device *dev, u8 *data) | ||
192 | { | ||
193 | return usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), | ||
194 | QT_SET_GET_DEVICE, 0xc0, 0, 0, | ||
195 | data, 3, QT2_USB_TIMEOUT); | ||
196 | } | ||
197 | |||
198 | static inline int qt2_getregister(struct usb_device *dev, | ||
199 | u8 uart, | ||
200 | u8 reg, | ||
201 | u8 *data) | ||
202 | { | ||
203 | return usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), | ||
204 | QT_SET_GET_REGISTER, 0xc0, reg, | ||
205 | uart, data, sizeof(*data), QT2_USB_TIMEOUT); | ||
206 | |||
207 | } | ||
208 | |||
209 | static inline int qt2_setregister(struct usb_device *dev, | ||
210 | u8 uart, u8 reg, u16 data) | ||
211 | { | ||
212 | u16 value = (data << 8) | reg; | ||
213 | |||
214 | return usb_control_msg(dev, usb_sndctrlpipe(dev, 0), | ||
215 | QT_SET_GET_REGISTER, 0x40, value, uart, | ||
216 | NULL, 0, QT2_USB_TIMEOUT); | ||
217 | } | ||
218 | |||
219 | static inline int update_mctrl(struct qt2_port_private *port_priv, | ||
220 | unsigned int set, unsigned int clear) | ||
221 | { | ||
222 | struct usb_serial_port *port = port_priv->port; | ||
223 | struct usb_device *dev = port->serial->dev; | ||
224 | unsigned urb_value; | ||
225 | int status; | ||
226 | |||
227 | if (((set | clear) & (TIOCM_DTR | TIOCM_RTS)) == 0) { | ||
228 | dev_dbg(&port->dev, | ||
229 | "update_mctrl - DTR|RTS not being set|cleared\n"); | ||
230 | return 0; /* no change */ | ||
231 | } | ||
232 | |||
233 | clear &= ~set; /* 'set' takes precedence over 'clear' */ | ||
234 | urb_value = 0; | ||
235 | if (set & TIOCM_DTR) | ||
236 | urb_value |= UART_MCR_DTR; | ||
237 | if (set & TIOCM_RTS) | ||
238 | urb_value |= UART_MCR_RTS; | ||
239 | |||
240 | status = qt2_setregister(dev, port_priv->device_port, UART_MCR, | ||
241 | urb_value); | ||
242 | if (status < 0) | ||
243 | dev_err(&port->dev, | ||
244 | "update_mctrl - Error from MODEM_CTRL urb: %i\n", | ||
245 | status); | ||
246 | return status; | ||
247 | } | ||
248 | |||
249 | static int qt2_calc_num_ports(struct usb_serial *serial) | ||
250 | { | ||
251 | struct qt2_device_detail d; | ||
252 | int i; | ||
253 | |||
254 | for (i = 0; d = qt2_device_details[i], d.product_id != 0; i++) { | ||
255 | if (d.product_id == le16_to_cpu(serial->dev->descriptor.idProduct)) | ||
256 | return d.num_ports; | ||
257 | } | ||
258 | |||
259 | /* we didn't recognize the device */ | ||
260 | dev_err(&serial->dev->dev, | ||
261 | "don't know the number of ports, assuming 1\n"); | ||
262 | |||
263 | return 1; | ||
264 | } | ||
265 | |||
266 | static void qt2_set_termios(struct tty_struct *tty, | ||
267 | struct usb_serial_port *port, | ||
268 | struct ktermios *old_termios) | ||
269 | { | ||
270 | struct usb_device *dev = port->serial->dev; | ||
271 | struct qt2_port_private *port_priv; | ||
272 | struct ktermios *termios = tty->termios; | ||
273 | u16 baud; | ||
274 | unsigned int cflag = termios->c_cflag; | ||
275 | u16 new_lcr = 0; | ||
276 | int status; | ||
277 | |||
278 | port_priv = usb_get_serial_port_data(port); | ||
279 | |||
280 | if (cflag & PARENB) { | ||
281 | if (cflag & PARODD) | ||
282 | new_lcr |= UART_LCR_PARITY; | ||
283 | else | ||
284 | new_lcr |= SERIAL_EVEN_PARITY; | ||
285 | } | ||
286 | |||
287 | switch (cflag & CSIZE) { | ||
288 | case CS5: | ||
289 | new_lcr |= UART_LCR_WLEN5; | ||
290 | break; | ||
291 | case CS6: | ||
292 | new_lcr |= UART_LCR_WLEN6; | ||
293 | break; | ||
294 | case CS7: | ||
295 | new_lcr |= UART_LCR_WLEN7; | ||
296 | break; | ||
297 | default: | ||
298 | case CS8: | ||
299 | new_lcr |= UART_LCR_WLEN8; | ||
300 | break; | ||
301 | } | ||
302 | |||
303 | baud = tty_get_baud_rate(tty); | ||
304 | if (!baud) | ||
305 | baud = 9600; | ||
306 | |||
307 | status = qt2_set_port_config(dev, port_priv->device_port, baud, | ||
308 | new_lcr); | ||
309 | if (status < 0) | ||
310 | dev_err(&port->dev, "%s - qt2_set_port_config failed: %i\n", | ||
311 | __func__, status); | ||
312 | |||
313 | if (cflag & CRTSCTS) | ||
314 | status = qt2_control_msg(dev, QT_HW_FLOW_CONTROL_MASK, | ||
315 | SERIAL_CRTSCTS, | ||
316 | port_priv->device_port); | ||
317 | else | ||
318 | status = qt2_control_msg(dev, QT_HW_FLOW_CONTROL_MASK, | ||
319 | 0, port_priv->device_port); | ||
320 | if (status < 0) | ||
321 | dev_err(&port->dev, "%s - set HW flow control failed: %i\n", | ||
322 | __func__, status); | ||
323 | |||
324 | if (I_IXOFF(tty) || I_IXON(tty)) { | ||
325 | u16 x = ((u16) (START_CHAR(tty) << 8) | (u16) (STOP_CHAR(tty))); | ||
326 | |||
327 | status = qt2_control_msg(dev, QT_SW_FLOW_CONTROL_MASK, | ||
328 | x, port_priv->device_port); | ||
329 | } else | ||
330 | status = qt2_control_msg(dev, QT_SW_FLOW_CONTROL_MASK, | ||
331 | 0, port_priv->device_port); | ||
332 | |||
333 | if (status < 0) | ||
334 | dev_err(&port->dev, "%s - set SW flow control failed: %i\n", | ||
335 | __func__, status); | ||
336 | |||
337 | } | ||
338 | |||
339 | static int qt2_open(struct tty_struct *tty, struct usb_serial_port *port) | ||
340 | { | ||
341 | struct usb_serial *serial; | ||
342 | struct qt2_serial_private *serial_priv; | ||
343 | struct qt2_port_private *port_priv; | ||
344 | u8 *data; | ||
345 | u16 device_port; | ||
346 | int status; | ||
347 | unsigned long flags; | ||
348 | |||
349 | device_port = (u16) (port->number - port->serial->minor); | ||
350 | |||
351 | serial = port->serial; | ||
352 | |||
353 | port_priv = usb_get_serial_port_data(port); | ||
354 | serial_priv = usb_get_serial_data(serial); | ||
355 | |||
356 | /* set the port to RS232 mode */ | ||
357 | status = qt2_control_msg(serial->dev, QT2_GET_SET_QMCR, | ||
358 | QT2_QMCR_RS232, device_port); | ||
359 | if (status < 0) { | ||
360 | dev_err(&port->dev, | ||
361 | "%s failed to set RS232 mode for port %i error %i\n", | ||
362 | __func__, device_port, status); | ||
363 | return status; | ||
364 | } | ||
365 | |||
366 | data = kzalloc(2, GFP_KERNEL); | ||
367 | if (!data) | ||
368 | return -ENOMEM; | ||
369 | |||
370 | /* open the port */ | ||
371 | status = usb_control_msg(serial->dev, | ||
372 | usb_rcvctrlpipe(serial->dev, 0), | ||
373 | QT_OPEN_CLOSE_CHANNEL, | ||
374 | 0xc0, 0, | ||
375 | device_port, data, 2, QT2_USB_TIMEOUT); | ||
376 | |||
377 | if (status < 0) { | ||
378 | dev_err(&port->dev, "%s - open port failed %i", __func__, | ||
379 | status); | ||
380 | kfree(data); | ||
381 | return status; | ||
382 | } | ||
383 | |||
384 | spin_lock_irqsave(&port_priv->lock, flags); | ||
385 | port_priv->shadowLSR = data[0]; | ||
386 | port_priv->shadowMSR = data[1]; | ||
387 | spin_unlock_irqrestore(&port_priv->lock, flags); | ||
388 | |||
389 | kfree(data); | ||
390 | |||
391 | /* set to default speed and 8bit word size */ | ||
392 | status = qt2_set_port_config(serial->dev, device_port, | ||
393 | DEFAULT_BAUD_RATE, UART_LCR_WLEN8); | ||
394 | if (status < 0) { | ||
395 | dev_err(&port->dev, | ||
396 | "%s - initial setup failed for port %i (%i)\n", | ||
397 | __func__, port->number, device_port); | ||
398 | return status; | ||
399 | } | ||
400 | |||
401 | port_priv->is_open = true; | ||
402 | port_priv->device_port = (u8) device_port; | ||
403 | |||
404 | if (tty) | ||
405 | qt2_set_termios(tty, port, tty->termios); | ||
406 | |||
407 | return 0; | ||
408 | |||
409 | } | ||
410 | |||
411 | static void qt2_close(struct usb_serial_port *port) | ||
412 | { | ||
413 | struct usb_serial *serial; | ||
414 | struct qt2_serial_private *serial_priv; | ||
415 | struct qt2_port_private *port_priv; | ||
416 | unsigned long flags; | ||
417 | int i; | ||
418 | |||
419 | serial = port->serial; | ||
420 | serial_priv = usb_get_serial_data(serial); | ||
421 | port_priv = usb_get_serial_port_data(port); | ||
422 | |||
423 | port_priv->is_open = false; | ||
424 | |||
425 | spin_lock_irqsave(&port_priv->urb_lock, flags); | ||
426 | if (port_priv->write_urb->status == -EINPROGRESS) | ||
427 | usb_kill_urb(port_priv->write_urb); | ||
428 | port_priv->urb_in_use = false; | ||
429 | spin_unlock_irqrestore(&port_priv->urb_lock, flags); | ||
430 | |||
431 | /* flush the port transmit buffer */ | ||
432 | i = usb_control_msg(serial->dev, | ||
433 | usb_rcvctrlpipe(serial->dev, 0), | ||
434 | QT2_FLUSH_DEVICE, 0x40, 1, | ||
435 | port_priv->device_port, NULL, 0, QT2_USB_TIMEOUT); | ||
436 | |||
437 | if (i < 0) | ||
438 | dev_err(&port->dev, "%s - transmit buffer flush failed: %i\n", | ||
439 | __func__, i); | ||
440 | |||
441 | /* flush the port receive buffer */ | ||
442 | i = usb_control_msg(serial->dev, | ||
443 | usb_rcvctrlpipe(serial->dev, 0), | ||
444 | QT2_FLUSH_DEVICE, 0x40, 0, | ||
445 | port_priv->device_port, NULL, 0, QT2_USB_TIMEOUT); | ||
446 | |||
447 | if (i < 0) | ||
448 | dev_err(&port->dev, "%s - receive buffer flush failed: %i\n", | ||
449 | __func__, i); | ||
450 | |||
451 | /* close the port */ | ||
452 | i = usb_control_msg(serial->dev, | ||
453 | usb_sndctrlpipe(serial->dev, 0), | ||
454 | QT_OPEN_CLOSE_CHANNEL, | ||
455 | 0x40, 0, | ||
456 | port_priv->device_port, NULL, 0, QT2_USB_TIMEOUT); | ||
457 | |||
458 | if (i < 0) | ||
459 | dev_err(&port->dev, "%s - close port failed %i\n", | ||
460 | __func__, i); | ||
461 | |||
462 | } | ||
463 | |||
464 | static void qt2_disconnect(struct usb_serial *serial) | ||
465 | { | ||
466 | struct qt2_serial_private *serial_priv = usb_get_serial_data(serial); | ||
467 | struct qt2_port_private *port_priv; | ||
468 | int i; | ||
469 | |||
470 | if (serial_priv->read_urb->status == -EINPROGRESS) | ||
471 | usb_kill_urb(serial_priv->read_urb); | ||
472 | |||
473 | usb_free_urb(serial_priv->read_urb); | ||
474 | |||
475 | for (i = 0; i < serial->num_ports; i++) { | ||
476 | port_priv = usb_get_serial_port_data(serial->port[i]); | ||
477 | |||
478 | if (port_priv->write_urb->status == -EINPROGRESS) | ||
479 | usb_kill_urb(port_priv->write_urb); | ||
480 | usb_free_urb(port_priv->write_urb); | ||
481 | } | ||
482 | } | ||
483 | |||
484 | static int get_serial_info(struct usb_serial_port *port, | ||
485 | struct serial_struct __user *retinfo) | ||
486 | { | ||
487 | struct serial_struct tmp; | ||
488 | |||
489 | if (!retinfo) | ||
490 | return -EFAULT; | ||
491 | |||
492 | memset(&tmp, 0, sizeof(tmp)); | ||
493 | tmp.line = port->serial->minor; | ||
494 | tmp.port = 0; | ||
495 | tmp.irq = 0; | ||
496 | tmp.flags = ASYNC_SKIP_TEST | ASYNC_AUTO_IRQ; | ||
497 | tmp.xmit_fifo_size = port->bulk_out_size; | ||
498 | tmp.baud_base = 9600; | ||
499 | tmp.close_delay = 5*HZ; | ||
500 | tmp.closing_wait = 30*HZ; | ||
501 | |||
502 | if (copy_to_user(retinfo, &tmp, sizeof(*retinfo))) | ||
503 | return -EFAULT; | ||
504 | return 0; | ||
505 | } | ||
506 | |||
507 | static int wait_modem_info(struct usb_serial_port *port, unsigned int arg) | ||
508 | { | ||
509 | struct qt2_port_private *priv = usb_get_serial_port_data(port); | ||
510 | struct async_icount prev, cur; | ||
511 | unsigned long flags; | ||
512 | |||
513 | spin_lock_irqsave(&priv->lock, flags); | ||
514 | prev = priv->icount; | ||
515 | spin_unlock_irqrestore(&priv->lock, flags); | ||
516 | |||
517 | while (1) { | ||
518 | wait_event_interruptible(priv->delta_msr_wait, | ||
519 | ((priv->icount.rng != prev.rng) || | ||
520 | (priv->icount.dsr != prev.dsr) || | ||
521 | (priv->icount.dcd != prev.dcd) || | ||
522 | (priv->icount.cts != prev.cts))); | ||
523 | |||
524 | if (signal_pending(current)) | ||
525 | return -ERESTARTSYS; | ||
526 | |||
527 | spin_lock_irqsave(&priv->lock, flags); | ||
528 | cur = priv->icount; | ||
529 | spin_unlock_irqrestore(&priv->lock, flags); | ||
530 | |||
531 | if ((prev.rng == cur.rng) && | ||
532 | (prev.dsr == cur.dsr) && | ||
533 | (prev.dcd == cur.dcd) && | ||
534 | (prev.cts == cur.cts)) | ||
535 | return -EIO; | ||
536 | |||
537 | if ((arg & TIOCM_RNG && (prev.rng != cur.rng)) || | ||
538 | (arg & TIOCM_DSR && (prev.dsr != cur.dsr)) || | ||
539 | (arg & TIOCM_CD && (prev.dcd != cur.dcd)) || | ||
540 | (arg & TIOCM_CTS && (prev.cts != cur.cts))) | ||
541 | return 0; | ||
542 | } | ||
543 | return 0; | ||
544 | } | ||
545 | |||
546 | static int qt2_get_icount(struct tty_struct *tty, | ||
547 | struct serial_icounter_struct *icount) | ||
548 | { | ||
549 | struct usb_serial_port *port = tty->driver_data; | ||
550 | struct qt2_port_private *priv = usb_get_serial_port_data(port); | ||
551 | struct async_icount cnow = priv->icount; | ||
552 | |||
553 | icount->cts = cnow.cts; | ||
554 | icount->dsr = cnow.dsr; | ||
555 | icount->rng = cnow.rng; | ||
556 | icount->dcd = cnow.dcd; | ||
557 | icount->rx = cnow.rx; | ||
558 | icount->tx = cnow.tx; | ||
559 | icount->frame = cnow.frame; | ||
560 | icount->overrun = cnow.overrun; | ||
561 | icount->parity = cnow.parity; | ||
562 | icount->brk = cnow.brk; | ||
563 | icount->buf_overrun = cnow.buf_overrun; | ||
564 | |||
565 | return 0; | ||
566 | } | ||
567 | |||
568 | static int qt2_ioctl(struct tty_struct *tty, | ||
569 | unsigned int cmd, unsigned long arg) | ||
570 | { | ||
571 | struct usb_serial_port *port = tty->driver_data; | ||
572 | |||
573 | switch (cmd) { | ||
574 | case TIOCGSERIAL: | ||
575 | return get_serial_info(port, | ||
576 | (struct serial_struct __user *)arg); | ||
577 | |||
578 | case TIOCMIWAIT: | ||
579 | return wait_modem_info(port, arg); | ||
580 | |||
581 | default: | ||
582 | break; | ||
583 | } | ||
584 | |||
585 | return -ENOIOCTLCMD; | ||
586 | } | ||
587 | |||
588 | static void qt2_process_status(struct usb_serial_port *port, unsigned char *ch) | ||
589 | { | ||
590 | switch (*ch) { | ||
591 | case QT2_LINE_STATUS: | ||
592 | qt2_update_lsr(port, ch + 1); | ||
593 | break; | ||
594 | case QT2_MODEM_STATUS: | ||
595 | qt2_update_msr(port, ch + 1); | ||
596 | break; | ||
597 | } | ||
598 | } | ||
599 | |||
600 | /* not needed, kept to document functionality */ | ||
601 | static void qt2_process_xmit_empty(struct usb_serial_port *port, | ||
602 | unsigned char *ch) | ||
603 | { | ||
604 | int bytes_written; | ||
605 | |||
606 | bytes_written = (int)(*ch) + (int)(*(ch + 1) << 4); | ||
607 | } | ||
608 | |||
609 | /* not needed, kept to document functionality */ | ||
610 | static void qt2_process_flush(struct usb_serial_port *port, unsigned char *ch) | ||
611 | { | ||
612 | return; | ||
613 | } | ||
614 | |||
615 | void qt2_process_read_urb(struct urb *urb) | ||
616 | { | ||
617 | struct usb_serial *serial; | ||
618 | struct qt2_serial_private *serial_priv; | ||
619 | struct usb_serial_port *port; | ||
620 | struct qt2_port_private *port_priv; | ||
621 | struct tty_struct *tty; | ||
622 | bool escapeflag; | ||
623 | unsigned char *ch; | ||
624 | int i; | ||
625 | unsigned char newport; | ||
626 | int len = urb->actual_length; | ||
627 | |||
628 | if (!len) | ||
629 | return; | ||
630 | |||
631 | ch = urb->transfer_buffer; | ||
632 | tty = NULL; | ||
633 | serial = urb->context; | ||
634 | serial_priv = usb_get_serial_data(serial); | ||
635 | port = serial->port[serial_priv->current_port]; | ||
636 | port_priv = usb_get_serial_port_data(port); | ||
637 | |||
638 | if (port_priv->is_open) | ||
639 | tty = tty_port_tty_get(&port->port); | ||
640 | |||
641 | for (i = 0; i < urb->actual_length; i++) { | ||
642 | ch = (unsigned char *)urb->transfer_buffer + i; | ||
643 | if ((i <= (len - 3)) && | ||
644 | (*ch == QT2_CONTROL_BYTE) && | ||
645 | (*(ch + 1) == QT2_CONTROL_BYTE)) { | ||
646 | escapeflag = false; | ||
647 | switch (*(ch + 2)) { | ||
648 | case QT2_LINE_STATUS: | ||
649 | case QT2_MODEM_STATUS: | ||
650 | if (i > (len - 4)) { | ||
651 | dev_warn(&port->dev, | ||
652 | "%s - status message too short\n", | ||
653 | __func__); | ||
654 | break; | ||
655 | } | ||
656 | qt2_process_status(port, ch + 2); | ||
657 | i += 3; | ||
658 | escapeflag = true; | ||
659 | break; | ||
660 | case QT2_XMIT_HOLD: | ||
661 | if (i > (len - 5)) { | ||
662 | dev_warn(&port->dev, | ||
663 | "%s - xmit_empty message too short\n", | ||
664 | __func__); | ||
665 | break; | ||
666 | } | ||
667 | qt2_process_xmit_empty(port, ch + 3); | ||
668 | i += 4; | ||
669 | escapeflag = true; | ||
670 | break; | ||
671 | case QT2_CHANGE_PORT: | ||
672 | if (i > (len - 4)) { | ||
673 | dev_warn(&port->dev, | ||
674 | "%s - change_port message too short\n", | ||
675 | __func__); | ||
676 | break; | ||
677 | } | ||
678 | if (tty) { | ||
679 | tty_flip_buffer_push(tty); | ||
680 | tty_kref_put(tty); | ||
681 | } | ||
682 | |||
683 | newport = *(ch + 3); | ||
684 | |||
685 | if (newport > serial->num_ports) { | ||
686 | dev_err(&port->dev, | ||
687 | "%s - port change to invalid port: %i\n", | ||
688 | __func__, newport); | ||
689 | break; | ||
690 | } | ||
691 | |||
692 | serial_priv->current_port = newport; | ||
693 | port = serial->port[serial_priv->current_port]; | ||
694 | port_priv = usb_get_serial_port_data(port); | ||
695 | if (port_priv->is_open) | ||
696 | tty = tty_port_tty_get(&port->port); | ||
697 | else | ||
698 | tty = NULL; | ||
699 | i += 3; | ||
700 | escapeflag = true; | ||
701 | break; | ||
702 | case QT2_REC_FLUSH: | ||
703 | case QT2_XMIT_FLUSH: | ||
704 | qt2_process_flush(port, ch + 2); | ||
705 | i += 2; | ||
706 | escapeflag = true; | ||
707 | break; | ||
708 | case QT2_CONTROL_ESCAPE: | ||
709 | tty_buffer_request_room(tty, 2); | ||
710 | tty_insert_flip_string(tty, ch, 2); | ||
711 | i += 2; | ||
712 | escapeflag = true; | ||
713 | break; | ||
714 | default: | ||
715 | dev_warn(&port->dev, | ||
716 | "%s - unsupported command %i\n", | ||
717 | __func__, *(ch + 2)); | ||
718 | break; | ||
719 | } | ||
720 | if (escapeflag) | ||
721 | continue; | ||
722 | } | ||
723 | |||
724 | if (tty) { | ||
725 | tty_buffer_request_room(tty, 1); | ||
726 | tty_insert_flip_string(tty, ch, 1); | ||
727 | } | ||
728 | } | ||
729 | |||
730 | if (tty) { | ||
731 | tty_flip_buffer_push(tty); | ||
732 | tty_kref_put(tty); | ||
733 | } | ||
734 | } | ||
735 | |||
736 | static void qt2_write_bulk_callback(struct urb *urb) | ||
737 | { | ||
738 | struct usb_serial_port *port; | ||
739 | struct qt2_port_private *port_priv; | ||
740 | |||
741 | port = urb->context; | ||
742 | port_priv = usb_get_serial_port_data(port); | ||
743 | |||
744 | spin_lock(&port_priv->urb_lock); | ||
745 | |||
746 | port_priv->urb_in_use = false; | ||
747 | usb_serial_port_softint(port); | ||
748 | |||
749 | spin_unlock(&port_priv->urb_lock); | ||
750 | |||
751 | } | ||
752 | |||
753 | static void qt2_read_bulk_callback(struct urb *urb) | ||
754 | { | ||
755 | struct usb_serial *serial = urb->context; | ||
756 | int status; | ||
757 | |||
758 | if (urb->status) { | ||
759 | dev_warn(&serial->dev->dev, | ||
760 | "%s - non-zero urb status: %i\n", __func__, | ||
761 | urb->status); | ||
762 | return; | ||
763 | } | ||
764 | |||
765 | qt2_process_read_urb(urb); | ||
766 | |||
767 | status = usb_submit_urb(urb, GFP_ATOMIC); | ||
768 | if (status != 0) | ||
769 | dev_err(&serial->dev->dev, | ||
770 | "%s - resubmit read urb failed: %i\n", | ||
771 | __func__, status); | ||
772 | } | ||
773 | |||
774 | static int qt2_setup_urbs(struct usb_serial *serial) | ||
775 | { | ||
776 | struct usb_serial_port *port; | ||
777 | struct usb_serial_port *port0; | ||
778 | struct qt2_serial_private *serial_priv; | ||
779 | struct qt2_port_private *port_priv; | ||
780 | int pcount, status; | ||
781 | |||
782 | port0 = serial->port[0]; | ||
783 | |||
784 | serial_priv = usb_get_serial_data(serial); | ||
785 | serial_priv->read_urb = usb_alloc_urb(0, GFP_KERNEL); | ||
786 | if (!serial_priv->read_urb) { | ||
787 | dev_err(&serial->dev->dev, "No free urbs available\n"); | ||
788 | return -ENOMEM; | ||
789 | } | ||
790 | |||
791 | usb_fill_bulk_urb(serial_priv->read_urb, serial->dev, | ||
792 | usb_rcvbulkpipe(serial->dev, | ||
793 | port0->bulk_in_endpointAddress), | ||
794 | serial_priv->read_buffer, | ||
795 | sizeof(serial_priv->read_buffer), | ||
796 | qt2_read_bulk_callback, serial); | ||
797 | |||
798 | /* setup write_urb for each port */ | ||
799 | for (pcount = 0; pcount < serial->num_ports; pcount++) { | ||
800 | |||
801 | port = serial->port[pcount]; | ||
802 | port_priv = usb_get_serial_port_data(port); | ||
803 | |||
804 | port_priv->write_urb = usb_alloc_urb(0, GFP_KERNEL); | ||
805 | if (!port_priv->write_urb) { | ||
806 | dev_err(&serial->dev->dev, | ||
807 | "failed to alloc write_urb for port %i\n", | ||
808 | pcount); | ||
809 | return -ENOMEM; | ||
810 | } | ||
811 | |||
812 | usb_fill_bulk_urb(port_priv->write_urb, | ||
813 | serial->dev, | ||
814 | usb_sndbulkpipe(serial->dev, | ||
815 | port0-> | ||
816 | bulk_out_endpointAddress), | ||
817 | port_priv->write_buffer, | ||
818 | sizeof(port_priv->write_buffer), | ||
819 | qt2_write_bulk_callback, port); | ||
820 | } | ||
821 | |||
822 | status = usb_submit_urb(serial_priv->read_urb, GFP_KERNEL); | ||
823 | if (status != 0) { | ||
824 | dev_err(&serial->dev->dev, | ||
825 | "%s - submit read urb failed %i\n", __func__, status); | ||
826 | return status; | ||
827 | } | ||
828 | |||
829 | return 0; | ||
830 | |||
831 | } | ||
832 | |||
833 | static int qt2_attach(struct usb_serial *serial) | ||
834 | { | ||
835 | struct qt2_serial_private *serial_priv; | ||
836 | struct qt2_port_private *port_priv; | ||
837 | int status, pcount; | ||
838 | |||
839 | /* power on unit */ | ||
840 | status = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0), | ||
841 | 0xc2, 0x40, 0x8000, 0, NULL, 0, | ||
842 | QT2_USB_TIMEOUT); | ||
843 | if (status < 0) { | ||
844 | dev_err(&serial->dev->dev, | ||
845 | "%s - failed to power on unit: %i\n", __func__, status); | ||
846 | return status; | ||
847 | } | ||
848 | |||
849 | serial_priv = kzalloc(sizeof(*serial_priv), GFP_KERNEL); | ||
850 | if (!serial_priv) { | ||
851 | dev_err(&serial->dev->dev, "%s - Out of memory\n", __func__); | ||
852 | return -ENOMEM; | ||
853 | } | ||
854 | |||
855 | usb_set_serial_data(serial, serial_priv); | ||
856 | |||
857 | for (pcount = 0; pcount < serial->num_ports; pcount++) { | ||
858 | port_priv = kzalloc(sizeof(*port_priv), GFP_KERNEL); | ||
859 | if (!port_priv) { | ||
860 | dev_err(&serial->dev->dev, | ||
861 | "%s- kmalloc(%Zd) failed.\n", __func__, | ||
862 | sizeof(*port_priv)); | ||
863 | pcount--; | ||
864 | status = -ENOMEM; | ||
865 | goto attach_failed; | ||
866 | } | ||
867 | |||
868 | spin_lock_init(&port_priv->lock); | ||
869 | spin_lock_init(&port_priv->urb_lock); | ||
870 | init_waitqueue_head(&port_priv->delta_msr_wait); | ||
871 | |||
872 | port_priv->port = serial->port[pcount]; | ||
873 | |||
874 | usb_set_serial_port_data(serial->port[pcount], port_priv); | ||
875 | } | ||
876 | |||
877 | status = qt2_setup_urbs(serial); | ||
878 | if (status != 0) | ||
879 | goto attach_failed; | ||
880 | |||
881 | return 0; | ||
882 | |||
883 | attach_failed: | ||
884 | for (/* empty */; pcount >= 0; pcount--) { | ||
885 | port_priv = usb_get_serial_port_data(serial->port[pcount]); | ||
886 | kfree(port_priv); | ||
887 | } | ||
888 | kfree(serial_priv); | ||
889 | return status; | ||
890 | } | ||
891 | |||
892 | static int qt2_tiocmget(struct tty_struct *tty) | ||
893 | { | ||
894 | struct usb_serial_port *port = tty->driver_data; | ||
895 | struct usb_device *dev = port->serial->dev; | ||
896 | struct qt2_port_private *port_priv = usb_get_serial_port_data(port); | ||
897 | u8 *d; | ||
898 | int r; | ||
899 | |||
900 | d = kzalloc(2, GFP_KERNEL); | ||
901 | if (!d) | ||
902 | return -ENOMEM; | ||
903 | |||
904 | r = qt2_getregister(dev, port_priv->device_port, UART_MCR, d); | ||
905 | if (r < 0) | ||
906 | goto mget_out; | ||
907 | |||
908 | r = qt2_getregister(dev, port_priv->device_port, UART_MSR, d + 1); | ||
909 | if (r < 0) | ||
910 | goto mget_out; | ||
911 | |||
912 | r = (d[0] & UART_MCR_DTR ? TIOCM_DTR : 0) | | ||
913 | (d[0] & UART_MCR_RTS ? TIOCM_RTS : 0) | | ||
914 | (d[1] & UART_MSR_CTS ? TIOCM_CTS : 0) | | ||
915 | (d[1] & UART_MSR_DCD ? TIOCM_CAR : 0) | | ||
916 | (d[1] & UART_MSR_RI ? TIOCM_RI : 0) | | ||
917 | (d[1] & UART_MSR_DSR ? TIOCM_DSR : 0); | ||
918 | |||
919 | mget_out: | ||
920 | kfree(d); | ||
921 | return r; | ||
922 | } | ||
923 | |||
924 | static int qt2_tiocmset(struct tty_struct *tty, | ||
925 | unsigned int set, unsigned int clear) | ||
926 | { | ||
927 | struct qt2_port_private *port_priv; | ||
928 | |||
929 | port_priv = usb_get_serial_port_data(tty->driver_data); | ||
930 | return update_mctrl(port_priv, set, clear); | ||
931 | } | ||
932 | |||
933 | static void qt2_break_ctl(struct tty_struct *tty, int break_state) | ||
934 | { | ||
935 | struct usb_serial_port *port = tty->driver_data; | ||
936 | struct qt2_port_private *port_priv; | ||
937 | int status; | ||
938 | u16 val; | ||
939 | |||
940 | port_priv = usb_get_serial_port_data(port); | ||
941 | |||
942 | if (!port_priv->is_open) { | ||
943 | dev_err(&port->dev, | ||
944 | "%s - port is not open\n", __func__); | ||
945 | return; | ||
946 | } | ||
947 | |||
948 | val = (break_state == -1) ? 1 : 0; | ||
949 | |||
950 | status = qt2_control_msg(port->serial->dev, QT2_BREAK_CONTROL, | ||
951 | val, port_priv->device_port); | ||
952 | if (status < 0) | ||
953 | dev_warn(&port->dev, | ||
954 | "%s - failed to send control message: %i\n", __func__, | ||
955 | status); | ||
956 | } | ||
957 | |||
958 | |||
959 | |||
960 | static void qt2_dtr_rts(struct usb_serial_port *port, int on) | ||
961 | { | ||
962 | struct usb_device *dev = port->serial->dev; | ||
963 | struct qt2_port_private *port_priv = usb_get_serial_port_data(port); | ||
964 | |||
965 | mutex_lock(&port->serial->disc_mutex); | ||
966 | if (!port->serial->disconnected) { | ||
967 | /* Disable flow control */ | ||
968 | if (!on && qt2_setregister(dev, port_priv->device_port, | ||
969 | UART_MCR, 0) < 0) | ||
970 | dev_warn(&port->dev, "error from flowcontrol urb\n"); | ||
971 | /* drop RTS and DTR */ | ||
972 | if (on) | ||
973 | update_mctrl(port_priv, TIOCM_DTR | TIOCM_RTS, 0); | ||
974 | else | ||
975 | update_mctrl(port_priv, 0, TIOCM_DTR | TIOCM_RTS); | ||
976 | } | ||
977 | mutex_unlock(&port->serial->disc_mutex); | ||
978 | } | ||
979 | |||
980 | static void qt2_update_msr(struct usb_serial_port *port, unsigned char *ch) | ||
981 | { | ||
982 | struct qt2_port_private *port_priv; | ||
983 | u8 newMSR = (u8) *ch; | ||
984 | unsigned long flags; | ||
985 | |||
986 | port_priv = usb_get_serial_port_data(port); | ||
987 | |||
988 | spin_lock_irqsave(&port_priv->lock, flags); | ||
989 | port_priv->shadowMSR = newMSR; | ||
990 | spin_unlock_irqrestore(&port_priv->lock, flags); | ||
991 | |||
992 | if (newMSR & UART_MSR_ANY_DELTA) { | ||
993 | /* update input line counters */ | ||
994 | if (newMSR & UART_MSR_DCTS) | ||
995 | port_priv->icount.cts++; | ||
996 | |||
997 | if (newMSR & UART_MSR_DDSR) | ||
998 | port_priv->icount.dsr++; | ||
999 | |||
1000 | if (newMSR & UART_MSR_DDCD) | ||
1001 | port_priv->icount.dcd++; | ||
1002 | |||
1003 | if (newMSR & UART_MSR_TERI) | ||
1004 | port_priv->icount.rng++; | ||
1005 | |||
1006 | wake_up_interruptible(&port_priv->delta_msr_wait); | ||
1007 | } | ||
1008 | } | ||
1009 | |||
1010 | static void qt2_update_lsr(struct usb_serial_port *port, unsigned char *ch) | ||
1011 | { | ||
1012 | struct qt2_port_private *port_priv; | ||
1013 | struct async_icount *icount; | ||
1014 | unsigned long flags; | ||
1015 | u8 newLSR = (u8) *ch; | ||
1016 | |||
1017 | port_priv = usb_get_serial_port_data(port); | ||
1018 | |||
1019 | if (newLSR & UART_LSR_BI) | ||
1020 | newLSR &= (u8) (UART_LSR_OE | UART_LSR_BI); | ||
1021 | |||
1022 | spin_lock_irqsave(&port_priv->lock, flags); | ||
1023 | port_priv->shadowLSR = newLSR; | ||
1024 | spin_unlock_irqrestore(&port_priv->lock, flags); | ||
1025 | |||
1026 | icount = &port_priv->icount; | ||
1027 | |||
1028 | if (newLSR & UART_LSR_BRK_ERROR_BITS) { | ||
1029 | |||
1030 | if (newLSR & UART_LSR_BI) | ||
1031 | icount->brk++; | ||
1032 | |||
1033 | if (newLSR & UART_LSR_OE) | ||
1034 | icount->overrun++; | ||
1035 | |||
1036 | if (newLSR & UART_LSR_PE) | ||
1037 | icount->parity++; | ||
1038 | |||
1039 | if (newLSR & UART_LSR_FE) | ||
1040 | icount->frame++; | ||
1041 | } | ||
1042 | |||
1043 | } | ||
1044 | |||
1045 | static int qt2_write_room(struct tty_struct *tty) | ||
1046 | { | ||
1047 | struct usb_serial_port *port = tty->driver_data; | ||
1048 | struct qt2_port_private *port_priv; | ||
1049 | unsigned long flags = 0; | ||
1050 | int r; | ||
1051 | |||
1052 | port_priv = usb_get_serial_port_data(port); | ||
1053 | |||
1054 | spin_lock_irqsave(&port_priv->urb_lock, flags); | ||
1055 | |||
1056 | if (port_priv->urb_in_use) | ||
1057 | r = 0; | ||
1058 | else | ||
1059 | r = QT2_WRITE_BUFFER_SIZE - QT2_WRITE_CONTROL_SIZE; | ||
1060 | |||
1061 | spin_unlock_irqrestore(&port_priv->urb_lock, flags); | ||
1062 | |||
1063 | return r; | ||
1064 | } | ||
1065 | |||
1066 | static int qt2_write(struct tty_struct *tty, | ||
1067 | struct usb_serial_port *port, | ||
1068 | const unsigned char *buf, int count) | ||
1069 | { | ||
1070 | struct qt2_port_private *port_priv; | ||
1071 | struct urb *write_urb; | ||
1072 | unsigned char *data; | ||
1073 | unsigned long flags; | ||
1074 | int status; | ||
1075 | int bytes_out = 0; | ||
1076 | |||
1077 | port_priv = usb_get_serial_port_data(port); | ||
1078 | |||
1079 | if (port_priv->write_urb == NULL) { | ||
1080 | dev_err(&port->dev, "%s - no output urb\n", __func__); | ||
1081 | return 0; | ||
1082 | } | ||
1083 | write_urb = port_priv->write_urb; | ||
1084 | |||
1085 | count = min(count, QT2_WRITE_BUFFER_SIZE - QT2_WRITE_CONTROL_SIZE); | ||
1086 | |||
1087 | data = write_urb->transfer_buffer; | ||
1088 | spin_lock_irqsave(&port_priv->urb_lock, flags); | ||
1089 | if (port_priv->urb_in_use == true) { | ||
1090 | printk(KERN_INFO "qt2_write - urb is in use\n"); | ||
1091 | goto write_out; | ||
1092 | } | ||
1093 | |||
1094 | *data++ = QT2_CONTROL_BYTE; | ||
1095 | *data++ = QT2_CONTROL_BYTE; | ||
1096 | *data++ = port_priv->device_port; | ||
1097 | put_unaligned_le16(count, data); | ||
1098 | data += 2; | ||
1099 | memcpy(data, buf, count); | ||
1100 | |||
1101 | write_urb->transfer_buffer_length = count + QT2_WRITE_CONTROL_SIZE; | ||
1102 | |||
1103 | status = usb_submit_urb(write_urb, GFP_ATOMIC); | ||
1104 | if (status == 0) { | ||
1105 | port_priv->urb_in_use = true; | ||
1106 | bytes_out += count; | ||
1107 | } | ||
1108 | |||
1109 | write_out: | ||
1110 | spin_unlock_irqrestore(&port_priv->urb_lock, flags); | ||
1111 | return bytes_out; | ||
1112 | } | ||
1113 | |||
1114 | |||
1115 | static struct usb_serial_driver qt2_device = { | ||
1116 | .driver = { | ||
1117 | .owner = THIS_MODULE, | ||
1118 | .name = "quatech-serial", | ||
1119 | }, | ||
1120 | .description = DRIVER_DESC, | ||
1121 | .id_table = id_table, | ||
1122 | .open = qt2_open, | ||
1123 | .close = qt2_close, | ||
1124 | .write = qt2_write, | ||
1125 | .write_room = qt2_write_room, | ||
1126 | .calc_num_ports = qt2_calc_num_ports, | ||
1127 | .attach = qt2_attach, | ||
1128 | .release = qt2_release, | ||
1129 | .disconnect = qt2_disconnect, | ||
1130 | .dtr_rts = qt2_dtr_rts, | ||
1131 | .break_ctl = qt2_break_ctl, | ||
1132 | .tiocmget = qt2_tiocmget, | ||
1133 | .tiocmset = qt2_tiocmset, | ||
1134 | .get_icount = qt2_get_icount, | ||
1135 | .ioctl = qt2_ioctl, | ||
1136 | .set_termios = qt2_set_termios, | ||
1137 | }; | ||
1138 | |||
1139 | static struct usb_serial_driver *const serial_drivers[] = { | ||
1140 | &qt2_device, NULL | ||
1141 | }; | ||
1142 | |||
1143 | module_usb_serial_driver(serial_drivers, id_table); | ||
1144 | |||
1145 | MODULE_DESCRIPTION(DRIVER_DESC); | ||
1146 | MODULE_LICENSE("GPL"); | ||
1147 | |||
1148 | module_param(debug, bool, S_IRUGO | S_IWUSR); | ||
1149 | MODULE_PARM_DESC(debug, "Debug enabled or not"); | ||