1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28#include <linux/kernel.h>
29#include <linux/errno.h>
30#include <linux/init.h>
31#include <linux/slab.h>
32#include <linux/tty.h>
33#include <linux/tty_driver.h>
34#include <linux/tty_flip.h>
35#include <linux/module.h>
36#include <linux/moduleparam.h>
37#include <linux/spinlock.h>
38#include <linux/usb.h>
39#include <linux/usb/serial.h>
40#include <linux/serial.h>
41#include <linux/kfifo.h>
42#include <linux/delay.h>
43#include <linux/uaccess.h>
44#include <asm/unaligned.h>
45
46#include "cypress_m8.h"
47
48
49static bool stats;
50static int interval;
51static bool unstable_bauds;
52
53#define DRIVER_AUTHOR "Lonnie Mendez <dignome@gmail.com>, Neil Whelchel <koyama@firstlight.net>"
54#define DRIVER_DESC "Cypress USB to Serial Driver"
55
56
57#define CYPRESS_BUF_SIZE 1024
58
59static const struct usb_device_id id_table_earthmate[] = {
60 { USB_DEVICE(VENDOR_ID_DELORME, PRODUCT_ID_EARTHMATEUSB) },
61 { USB_DEVICE(VENDOR_ID_DELORME, PRODUCT_ID_EARTHMATEUSB_LT20) },
62 { }
63};
64
65static const struct usb_device_id id_table_cyphidcomrs232[] = {
66 { USB_DEVICE(VENDOR_ID_CYPRESS, PRODUCT_ID_CYPHIDCOM) },
67 { USB_DEVICE(VENDOR_ID_POWERCOM, PRODUCT_ID_UPS) },
68 { USB_DEVICE(VENDOR_ID_FRWD, PRODUCT_ID_CYPHIDCOM_FRWD) },
69 { }
70};
71
72static const struct usb_device_id id_table_nokiaca42v2[] = {
73 { USB_DEVICE(VENDOR_ID_DAZZLE, PRODUCT_ID_CA42) },
74 { }
75};
76
77static const struct usb_device_id id_table_combined[] = {
78 { USB_DEVICE(VENDOR_ID_DELORME, PRODUCT_ID_EARTHMATEUSB) },
79 { USB_DEVICE(VENDOR_ID_DELORME, PRODUCT_ID_EARTHMATEUSB_LT20) },
80 { USB_DEVICE(VENDOR_ID_CYPRESS, PRODUCT_ID_CYPHIDCOM) },
81 { USB_DEVICE(VENDOR_ID_POWERCOM, PRODUCT_ID_UPS) },
82 { USB_DEVICE(VENDOR_ID_FRWD, PRODUCT_ID_CYPHIDCOM_FRWD) },
83 { USB_DEVICE(VENDOR_ID_DAZZLE, PRODUCT_ID_CA42) },
84 { }
85};
86
87MODULE_DEVICE_TABLE(usb, id_table_combined);
88
89enum packet_format {
90 packet_format_1,
91 packet_format_2
92};
93
94struct cypress_private {
95 spinlock_t lock;
96 int chiptype;
97 int bytes_in;
98 int bytes_out;
99 int cmd_count;
100 int cmd_ctrl;
101 struct kfifo write_fifo;
102 int write_urb_in_use;
103 int write_urb_interval;
104 int read_urb_interval;
105 int comm_is_ok;
106 int termios_initialized;
107 __u8 line_control;
108 __u8 current_status;
109 __u8 current_config;
110 __u8 rx_flags;
111 enum packet_format pkt_fmt;
112 int get_cfg_unsafe;
113 int baud_rate;
114
115 int isthrottled;
116 char prev_status, diff_status;
117
118
119 struct ktermios tmp_termios;
120};
121
122
123static int cypress_earthmate_port_probe(struct usb_serial_port *port);
124static int cypress_hidcom_port_probe(struct usb_serial_port *port);
125static int cypress_ca42v2_port_probe(struct usb_serial_port *port);
126static int cypress_port_remove(struct usb_serial_port *port);
127static int cypress_open(struct tty_struct *tty, struct usb_serial_port *port);
128static void cypress_close(struct usb_serial_port *port);
129static void cypress_dtr_rts(struct usb_serial_port *port, int on);
130static int cypress_write(struct tty_struct *tty, struct usb_serial_port *port,
131 const unsigned char *buf, int count);
132static void cypress_send(struct usb_serial_port *port);
133static int cypress_write_room(struct tty_struct *tty);
134static int cypress_ioctl(struct tty_struct *tty,
135 unsigned int cmd, unsigned long arg);
136static void cypress_set_termios(struct tty_struct *tty,
137 struct usb_serial_port *port, struct ktermios *old);
138static int cypress_tiocmget(struct tty_struct *tty);
139static int cypress_tiocmset(struct tty_struct *tty,
140 unsigned int set, unsigned int clear);
141static int cypress_chars_in_buffer(struct tty_struct *tty);
142static void cypress_throttle(struct tty_struct *tty);
143static void cypress_unthrottle(struct tty_struct *tty);
144static void cypress_set_dead(struct usb_serial_port *port);
145static void cypress_read_int_callback(struct urb *urb);
146static void cypress_write_int_callback(struct urb *urb);
147
148static struct usb_serial_driver cypress_earthmate_device = {
149 .driver = {
150 .owner = THIS_MODULE,
151 .name = "earthmate",
152 },
153 .description = "DeLorme Earthmate USB",
154 .id_table = id_table_earthmate,
155 .num_ports = 1,
156 .port_probe = cypress_earthmate_port_probe,
157 .port_remove = cypress_port_remove,
158 .open = cypress_open,
159 .close = cypress_close,
160 .dtr_rts = cypress_dtr_rts,
161 .write = cypress_write,
162 .write_room = cypress_write_room,
163 .ioctl = cypress_ioctl,
164 .set_termios = cypress_set_termios,
165 .tiocmget = cypress_tiocmget,
166 .tiocmset = cypress_tiocmset,
167 .chars_in_buffer = cypress_chars_in_buffer,
168 .throttle = cypress_throttle,
169 .unthrottle = cypress_unthrottle,
170 .read_int_callback = cypress_read_int_callback,
171 .write_int_callback = cypress_write_int_callback,
172};
173
174static struct usb_serial_driver cypress_hidcom_device = {
175 .driver = {
176 .owner = THIS_MODULE,
177 .name = "cyphidcom",
178 },
179 .description = "HID->COM RS232 Adapter",
180 .id_table = id_table_cyphidcomrs232,
181 .num_ports = 1,
182 .port_probe = cypress_hidcom_port_probe,
183 .port_remove = cypress_port_remove,
184 .open = cypress_open,
185 .close = cypress_close,
186 .dtr_rts = cypress_dtr_rts,
187 .write = cypress_write,
188 .write_room = cypress_write_room,
189 .ioctl = cypress_ioctl,
190 .set_termios = cypress_set_termios,
191 .tiocmget = cypress_tiocmget,
192 .tiocmset = cypress_tiocmset,
193 .chars_in_buffer = cypress_chars_in_buffer,
194 .throttle = cypress_throttle,
195 .unthrottle = cypress_unthrottle,
196 .read_int_callback = cypress_read_int_callback,
197 .write_int_callback = cypress_write_int_callback,
198};
199
200static struct usb_serial_driver cypress_ca42v2_device = {
201 .driver = {
202 .owner = THIS_MODULE,
203 .name = "nokiaca42v2",
204 },
205 .description = "Nokia CA-42 V2 Adapter",
206 .id_table = id_table_nokiaca42v2,
207 .num_ports = 1,
208 .port_probe = cypress_ca42v2_port_probe,
209 .port_remove = cypress_port_remove,
210 .open = cypress_open,
211 .close = cypress_close,
212 .dtr_rts = cypress_dtr_rts,
213 .write = cypress_write,
214 .write_room = cypress_write_room,
215 .ioctl = cypress_ioctl,
216 .set_termios = cypress_set_termios,
217 .tiocmget = cypress_tiocmget,
218 .tiocmset = cypress_tiocmset,
219 .chars_in_buffer = cypress_chars_in_buffer,
220 .throttle = cypress_throttle,
221 .unthrottle = cypress_unthrottle,
222 .read_int_callback = cypress_read_int_callback,
223 .write_int_callback = cypress_write_int_callback,
224};
225
226static struct usb_serial_driver * const serial_drivers[] = {
227 &cypress_earthmate_device, &cypress_hidcom_device,
228 &cypress_ca42v2_device, NULL
229};
230
231
232
233
234
235
236static inline bool is_frwd(struct usb_device *dev)
237{
238 return ((le16_to_cpu(dev->descriptor.idVendor) == VENDOR_ID_FRWD) &&
239 (le16_to_cpu(dev->descriptor.idProduct) == PRODUCT_ID_CYPHIDCOM_FRWD));
240}
241
242static int analyze_baud_rate(struct usb_serial_port *port, speed_t new_rate)
243{
244 struct cypress_private *priv;
245 priv = usb_get_serial_port_data(port);
246
247 if (unstable_bauds)
248 return new_rate;
249
250
251 if (is_frwd(port->serial->dev))
252 return new_rate;
253
254
255
256
257
258
259
260
261
262
263 if (port->serial->dev->speed == USB_SPEED_LOW) {
264
265
266
267
268
269
270
271 if (new_rate > 4800) {
272 dev_dbg(&port->dev,
273 "%s - failed setting baud rate, device incapable speed %d\n",
274 __func__, new_rate);
275 return -1;
276 }
277 }
278 switch (priv->chiptype) {
279 case CT_EARTHMATE:
280 if (new_rate <= 600) {
281
282
283
284 dev_dbg(&port->dev,
285 "%s - failed setting baud rate, unsupported speed of %d on Earthmate GPS",
286 __func__, new_rate);
287 return -1;
288 }
289 break;
290 default:
291 break;
292 }
293 return new_rate;
294}
295
296
297
298static int cypress_serial_control(struct tty_struct *tty,
299 struct usb_serial_port *port, speed_t baud_rate, int data_bits,
300 int stop_bits, int parity_enable, int parity_type, int reset,
301 int cypress_request_type)
302{
303 int new_baudrate = 0, retval = 0, tries = 0;
304 struct cypress_private *priv;
305 struct device *dev = &port->dev;
306 u8 *feature_buffer;
307 const unsigned int feature_len = 5;
308 unsigned long flags;
309
310 priv = usb_get_serial_port_data(port);
311
312 if (!priv->comm_is_ok)
313 return -ENODEV;
314
315 feature_buffer = kcalloc(feature_len, sizeof(u8), GFP_KERNEL);
316 if (!feature_buffer)
317 return -ENOMEM;
318
319 switch (cypress_request_type) {
320 case CYPRESS_SET_CONFIG:
321
322 new_baudrate = priv->baud_rate;
323 if (baud_rate && baud_rate != priv->baud_rate) {
324 dev_dbg(dev, "%s - baud rate is changing\n", __func__);
325 retval = analyze_baud_rate(port, baud_rate);
326 if (retval >= 0) {
327 new_baudrate = retval;
328 dev_dbg(dev, "%s - New baud rate set to %d\n",
329 __func__, new_baudrate);
330 }
331 }
332 dev_dbg(dev, "%s - baud rate is being sent as %d\n", __func__,
333 new_baudrate);
334
335
336 put_unaligned_le32(new_baudrate, feature_buffer);
337 feature_buffer[4] |= data_bits;
338
339 feature_buffer[4] |= (stop_bits << 3);
340 feature_buffer[4] |= (parity_enable << 4);
341 feature_buffer[4] |= (parity_type << 5);
342
343 feature_buffer[4] |= (reset << 7);
344
345 dev_dbg(dev, "%s - device is being sent this feature report:\n", __func__);
346 dev_dbg(dev, "%s - %02X - %02X - %02X - %02X - %02X\n", __func__,
347 feature_buffer[0], feature_buffer[1],
348 feature_buffer[2], feature_buffer[3],
349 feature_buffer[4]);
350
351 do {
352 retval = usb_control_msg(port->serial->dev,
353 usb_sndctrlpipe(port->serial->dev, 0),
354 HID_REQ_SET_REPORT,
355 USB_DIR_OUT | USB_RECIP_INTERFACE | USB_TYPE_CLASS,
356 0x0300, 0, feature_buffer,
357 feature_len, 500);
358
359 if (tries++ >= 3)
360 break;
361
362 } while (retval != feature_len &&
363 retval != -ENODEV);
364
365 if (retval != feature_len) {
366 dev_err(dev, "%s - failed sending serial line settings - %d\n",
367 __func__, retval);
368 cypress_set_dead(port);
369 } else {
370 spin_lock_irqsave(&priv->lock, flags);
371 priv->baud_rate = new_baudrate;
372 priv->current_config = feature_buffer[4];
373 spin_unlock_irqrestore(&priv->lock, flags);
374
375 if (baud_rate)
376 tty_encode_baud_rate(tty,
377 new_baudrate, new_baudrate);
378 }
379 break;
380 case CYPRESS_GET_CONFIG:
381 if (priv->get_cfg_unsafe) {
382
383
384
385 retval = -ENOTTY;
386 goto out;
387 }
388 dev_dbg(dev, "%s - retreiving serial line settings\n", __func__);
389 do {
390 retval = usb_control_msg(port->serial->dev,
391 usb_rcvctrlpipe(port->serial->dev, 0),
392 HID_REQ_GET_REPORT,
393 USB_DIR_IN | USB_RECIP_INTERFACE | USB_TYPE_CLASS,
394 0x0300, 0, feature_buffer,
395 feature_len, 500);
396
397 if (tries++ >= 3)
398 break;
399 } while (retval != feature_len
400 && retval != -ENODEV);
401
402 if (retval != feature_len) {
403 dev_err(dev, "%s - failed to retrieve serial line settings - %d\n",
404 __func__, retval);
405 cypress_set_dead(port);
406 goto out;
407 } else {
408 spin_lock_irqsave(&priv->lock, flags);
409
410
411 priv->current_config = feature_buffer[4];
412 priv->baud_rate = get_unaligned_le32(feature_buffer);
413 spin_unlock_irqrestore(&priv->lock, flags);
414 }
415 }
416 spin_lock_irqsave(&priv->lock, flags);
417 ++priv->cmd_count;
418 spin_unlock_irqrestore(&priv->lock, flags);
419out:
420 kfree(feature_buffer);
421 return retval;
422}
423
424
425static void cypress_set_dead(struct usb_serial_port *port)
426{
427 struct cypress_private *priv = usb_get_serial_port_data(port);
428 unsigned long flags;
429
430 spin_lock_irqsave(&priv->lock, flags);
431 if (!priv->comm_is_ok) {
432 spin_unlock_irqrestore(&priv->lock, flags);
433 return;
434 }
435 priv->comm_is_ok = 0;
436 spin_unlock_irqrestore(&priv->lock, flags);
437
438 dev_err(&port->dev, "cypress_m8 suspending failing port %d - "
439 "interval might be too short\n", port->number);
440}
441
442
443
444
445
446
447
448static int cypress_generic_port_probe(struct usb_serial_port *port)
449{
450 struct usb_serial *serial = port->serial;
451 struct cypress_private *priv;
452
453 priv = kzalloc(sizeof(struct cypress_private), GFP_KERNEL);
454 if (!priv)
455 return -ENOMEM;
456
457 priv->comm_is_ok = !0;
458 spin_lock_init(&priv->lock);
459 if (kfifo_alloc(&priv->write_fifo, CYPRESS_BUF_SIZE, GFP_KERNEL)) {
460 kfree(priv);
461 return -ENOMEM;
462 }
463
464
465
466
467 if (!is_frwd(serial->dev))
468 usb_reset_configuration(serial->dev);
469
470 priv->cmd_ctrl = 0;
471 priv->line_control = 0;
472 priv->termios_initialized = 0;
473 priv->rx_flags = 0;
474
475
476
477
478
479
480 if (port->interrupt_out_size > 9)
481 priv->pkt_fmt = packet_format_1;
482 else
483 priv->pkt_fmt = packet_format_2;
484
485 if (interval > 0) {
486 priv->write_urb_interval = interval;
487 priv->read_urb_interval = interval;
488 dev_dbg(&port->dev, "%s - read & write intervals forced to %d\n",
489 __func__, interval);
490 } else {
491 priv->write_urb_interval = port->interrupt_out_urb->interval;
492 priv->read_urb_interval = port->interrupt_in_urb->interval;
493 dev_dbg(&port->dev, "%s - intervals: read=%d write=%d\n",
494 __func__, priv->read_urb_interval,
495 priv->write_urb_interval);
496 }
497 usb_set_serial_port_data(port, priv);
498
499 return 0;
500}
501
502
503static int cypress_earthmate_port_probe(struct usb_serial_port *port)
504{
505 struct usb_serial *serial = port->serial;
506 struct cypress_private *priv;
507 int ret;
508
509 ret = cypress_generic_port_probe(port);
510 if (ret) {
511 dev_dbg(&port->dev, "%s - Failed setting up port\n", __func__);
512 return ret;
513 }
514
515 priv = usb_get_serial_port_data(port);
516 priv->chiptype = CT_EARTHMATE;
517
518
519 priv->pkt_fmt = packet_format_1;
520 if (serial->dev->descriptor.idProduct !=
521 cpu_to_le16(PRODUCT_ID_EARTHMATEUSB)) {
522
523
524
525
526 dev_dbg(&port->dev,
527 "%s - Marking this device as unsafe for GET_CONFIG commands\n",
528 __func__);
529 priv->get_cfg_unsafe = !0;
530 }
531
532 return 0;
533}
534
535static int cypress_hidcom_port_probe(struct usb_serial_port *port)
536{
537 struct cypress_private *priv;
538 int ret;
539
540 ret = cypress_generic_port_probe(port);
541 if (ret) {
542 dev_dbg(&port->dev, "%s - Failed setting up port\n", __func__);
543 return ret;
544 }
545
546 priv = usb_get_serial_port_data(port);
547 priv->chiptype = CT_CYPHIDCOM;
548
549 return 0;
550}
551
552static int cypress_ca42v2_port_probe(struct usb_serial_port *port)
553{
554 struct cypress_private *priv;
555 int ret;
556
557 ret = cypress_generic_port_probe(port);
558 if (ret) {
559 dev_dbg(&port->dev, "%s - Failed setting up port\n", __func__);
560 return ret;
561 }
562
563 priv = usb_get_serial_port_data(port);
564 priv->chiptype = CT_CA42V2;
565
566 return 0;
567}
568
569static int cypress_port_remove(struct usb_serial_port *port)
570{
571 struct cypress_private *priv;
572
573 priv = usb_get_serial_port_data(port);
574
575 kfifo_free(&priv->write_fifo);
576 kfree(priv);
577
578 return 0;
579}
580
581static int cypress_open(struct tty_struct *tty, struct usb_serial_port *port)
582{
583 struct cypress_private *priv = usb_get_serial_port_data(port);
584 struct usb_serial *serial = port->serial;
585 unsigned long flags;
586 int result = 0;
587
588 if (!priv->comm_is_ok)
589 return -EIO;
590
591
592 usb_clear_halt(serial->dev, 0x81);
593 usb_clear_halt(serial->dev, 0x02);
594
595 spin_lock_irqsave(&priv->lock, flags);
596
597 priv->bytes_in = 0;
598 priv->bytes_out = 0;
599 priv->cmd_count = 0;
600 priv->rx_flags = 0;
601 spin_unlock_irqrestore(&priv->lock, flags);
602
603
604 cypress_send(port);
605
606 if (tty)
607 cypress_set_termios(tty, port, &priv->tmp_termios);
608
609
610 if (!port->interrupt_in_urb) {
611 dev_err(&port->dev, "%s - interrupt_in_urb is empty!\n",
612 __func__);
613 return -1;
614 }
615
616 usb_fill_int_urb(port->interrupt_in_urb, serial->dev,
617 usb_rcvintpipe(serial->dev, port->interrupt_in_endpointAddress),
618 port->interrupt_in_urb->transfer_buffer,
619 port->interrupt_in_urb->transfer_buffer_length,
620 cypress_read_int_callback, port, priv->read_urb_interval);
621 result = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL);
622
623 if (result) {
624 dev_err(&port->dev,
625 "%s - failed submitting read urb, error %d\n",
626 __func__, result);
627 cypress_set_dead(port);
628 }
629 port->port.drain_delay = 256;
630 return result;
631}
632
633static void cypress_dtr_rts(struct usb_serial_port *port, int on)
634{
635 struct cypress_private *priv = usb_get_serial_port_data(port);
636
637 spin_lock_irq(&priv->lock);
638 if (on == 0)
639 priv->line_control = 0;
640 else
641 priv->line_control = CONTROL_DTR | CONTROL_RTS;
642 priv->cmd_ctrl = 1;
643 spin_unlock_irq(&priv->lock);
644 cypress_write(NULL, port, NULL, 0);
645}
646
647static void cypress_close(struct usb_serial_port *port)
648{
649 struct cypress_private *priv = usb_get_serial_port_data(port);
650 unsigned long flags;
651
652
653 mutex_lock(&port->serial->disc_mutex);
654 if (port->serial->disconnected) {
655 mutex_unlock(&port->serial->disc_mutex);
656 return;
657 }
658 spin_lock_irqsave(&priv->lock, flags);
659 kfifo_reset_out(&priv->write_fifo);
660 spin_unlock_irqrestore(&priv->lock, flags);
661
662 dev_dbg(&port->dev, "%s - stopping urbs\n", __func__);
663 usb_kill_urb(port->interrupt_in_urb);
664 usb_kill_urb(port->interrupt_out_urb);
665
666 if (stats)
667 dev_info(&port->dev, "Statistics: %d Bytes In | %d Bytes Out | %d Commands Issued\n",
668 priv->bytes_in, priv->bytes_out, priv->cmd_count);
669 mutex_unlock(&port->serial->disc_mutex);
670}
671
672
673static int cypress_write(struct tty_struct *tty, struct usb_serial_port *port,
674 const unsigned char *buf, int count)
675{
676 struct cypress_private *priv = usb_get_serial_port_data(port);
677
678 dev_dbg(&port->dev, "%s - port %d, %d bytes\n", __func__, port->number, count);
679
680
681
682
683 if (priv->cmd_ctrl) {
684 count = 0;
685 goto finish;
686 }
687
688 if (!count)
689 return count;
690
691 count = kfifo_in_locked(&priv->write_fifo, buf, count, &priv->lock);
692
693finish:
694 cypress_send(port);
695
696 return count;
697}
698
699
700static void cypress_send(struct usb_serial_port *port)
701{
702 int count = 0, result, offset, actual_size;
703 struct cypress_private *priv = usb_get_serial_port_data(port);
704 struct device *dev = &port->dev;
705 unsigned long flags;
706
707 if (!priv->comm_is_ok)
708 return;
709
710 dev_dbg(dev, "%s - interrupt out size is %d\n", __func__,
711 port->interrupt_out_size);
712
713 spin_lock_irqsave(&priv->lock, flags);
714 if (priv->write_urb_in_use) {
715 dev_dbg(dev, "%s - can't write, urb in use\n", __func__);
716 spin_unlock_irqrestore(&priv->lock, flags);
717 return;
718 }
719 spin_unlock_irqrestore(&priv->lock, flags);
720
721
722 memset(port->interrupt_out_urb->transfer_buffer, 0,
723 port->interrupt_out_size);
724
725 spin_lock_irqsave(&priv->lock, flags);
726 switch (priv->pkt_fmt) {
727 default:
728 case packet_format_1:
729
730 offset = 2;
731 port->interrupt_out_buffer[0] = priv->line_control;
732 break;
733 case packet_format_2:
734
735 offset = 1;
736 port->interrupt_out_buffer[0] = priv->line_control;
737 break;
738 }
739
740 if (priv->line_control & CONTROL_RESET)
741 priv->line_control &= ~CONTROL_RESET;
742
743 if (priv->cmd_ctrl) {
744 priv->cmd_count++;
745 dev_dbg(dev, "%s - line control command being issued\n", __func__);
746 spin_unlock_irqrestore(&priv->lock, flags);
747 goto send;
748 } else
749 spin_unlock_irqrestore(&priv->lock, flags);
750
751 count = kfifo_out_locked(&priv->write_fifo,
752 &port->interrupt_out_buffer[offset],
753 port->interrupt_out_size - offset,
754 &priv->lock);
755 if (count == 0)
756 return;
757
758 switch (priv->pkt_fmt) {
759 default:
760 case packet_format_1:
761 port->interrupt_out_buffer[1] = count;
762 break;
763 case packet_format_2:
764 port->interrupt_out_buffer[0] |= count;
765 }
766
767 dev_dbg(dev, "%s - count is %d\n", __func__, count);
768
769send:
770 spin_lock_irqsave(&priv->lock, flags);
771 priv->write_urb_in_use = 1;
772 spin_unlock_irqrestore(&priv->lock, flags);
773
774 if (priv->cmd_ctrl)
775 actual_size = 1;
776 else
777 actual_size = count +
778 (priv->pkt_fmt == packet_format_1 ? 2 : 1);
779
780 usb_serial_debug_data(dev, __func__, port->interrupt_out_size,
781 port->interrupt_out_urb->transfer_buffer);
782
783 usb_fill_int_urb(port->interrupt_out_urb, port->serial->dev,
784 usb_sndintpipe(port->serial->dev, port->interrupt_out_endpointAddress),
785 port->interrupt_out_buffer, port->interrupt_out_size,
786 cypress_write_int_callback, port, priv->write_urb_interval);
787 result = usb_submit_urb(port->interrupt_out_urb, GFP_ATOMIC);
788 if (result) {
789 dev_err_console(port,
790 "%s - failed submitting write urb, error %d\n",
791 __func__, result);
792 priv->write_urb_in_use = 0;
793 cypress_set_dead(port);
794 }
795
796 spin_lock_irqsave(&priv->lock, flags);
797 if (priv->cmd_ctrl)
798 priv->cmd_ctrl = 0;
799
800
801 priv->bytes_out += count;
802 spin_unlock_irqrestore(&priv->lock, flags);
803
804 usb_serial_port_softint(port);
805}
806
807
808
809static int cypress_write_room(struct tty_struct *tty)
810{
811 struct usb_serial_port *port = tty->driver_data;
812 struct cypress_private *priv = usb_get_serial_port_data(port);
813 int room = 0;
814 unsigned long flags;
815
816 spin_lock_irqsave(&priv->lock, flags);
817 room = kfifo_avail(&priv->write_fifo);
818 spin_unlock_irqrestore(&priv->lock, flags);
819
820 dev_dbg(&port->dev, "%s - returns %d\n", __func__, room);
821 return room;
822}
823
824
825static int cypress_tiocmget(struct tty_struct *tty)
826{
827 struct usb_serial_port *port = tty->driver_data;
828 struct cypress_private *priv = usb_get_serial_port_data(port);
829 __u8 status, control;
830 unsigned int result = 0;
831 unsigned long flags;
832
833 spin_lock_irqsave(&priv->lock, flags);
834 control = priv->line_control;
835 status = priv->current_status;
836 spin_unlock_irqrestore(&priv->lock, flags);
837
838 result = ((control & CONTROL_DTR) ? TIOCM_DTR : 0)
839 | ((control & CONTROL_RTS) ? TIOCM_RTS : 0)
840 | ((status & UART_CTS) ? TIOCM_CTS : 0)
841 | ((status & UART_DSR) ? TIOCM_DSR : 0)
842 | ((status & UART_RI) ? TIOCM_RI : 0)
843 | ((status & UART_CD) ? TIOCM_CD : 0);
844
845 dev_dbg(&port->dev, "%s - result = %x\n", __func__, result);
846
847 return result;
848}
849
850
851static int cypress_tiocmset(struct tty_struct *tty,
852 unsigned int set, unsigned int clear)
853{
854 struct usb_serial_port *port = tty->driver_data;
855 struct cypress_private *priv = usb_get_serial_port_data(port);
856 unsigned long flags;
857
858 spin_lock_irqsave(&priv->lock, flags);
859 if (set & TIOCM_RTS)
860 priv->line_control |= CONTROL_RTS;
861 if (set & TIOCM_DTR)
862 priv->line_control |= CONTROL_DTR;
863 if (clear & TIOCM_RTS)
864 priv->line_control &= ~CONTROL_RTS;
865 if (clear & TIOCM_DTR)
866 priv->line_control &= ~CONTROL_DTR;
867 priv->cmd_ctrl = 1;
868 spin_unlock_irqrestore(&priv->lock, flags);
869
870 return cypress_write(tty, port, NULL, 0);
871}
872
873
874static int cypress_ioctl(struct tty_struct *tty,
875 unsigned int cmd, unsigned long arg)
876{
877 struct usb_serial_port *port = tty->driver_data;
878 struct cypress_private *priv = usb_get_serial_port_data(port);
879
880 dev_dbg(&port->dev, "%s - port %d, cmd 0x%.4x\n", __func__, port->number, cmd);
881
882 switch (cmd) {
883
884 case TIOCMIWAIT:
885 for (;;) {
886 interruptible_sleep_on(&port->delta_msr_wait);
887
888 if (signal_pending(current))
889 return -ERESTARTSYS;
890
891 if (port->serial->disconnected)
892 return -EIO;
893
894 {
895 char diff = priv->diff_status;
896 if (diff == 0)
897 return -EIO;
898
899
900 priv->diff_status = 0;
901
902
903
904 if (((arg & TIOCM_RNG) && (diff & UART_RI)) ||
905 ((arg & TIOCM_DSR) && (diff & UART_DSR)) ||
906 ((arg & TIOCM_CD) && (diff & UART_CD)) ||
907 ((arg & TIOCM_CTS) && (diff & UART_CTS)))
908 return 0;
909
910
911
912
913 }
914 }
915 return 0;
916 default:
917 break;
918 }
919 dev_dbg(&port->dev, "%s - arg not supported - it was 0x%04x - check include/asm/ioctls.h\n", __func__, cmd);
920 return -ENOIOCTLCMD;
921}
922
923
924static void cypress_set_termios(struct tty_struct *tty,
925 struct usb_serial_port *port, struct ktermios *old_termios)
926{
927 struct cypress_private *priv = usb_get_serial_port_data(port);
928 struct device *dev = &port->dev;
929 int data_bits, stop_bits, parity_type, parity_enable;
930 unsigned cflag, iflag;
931 unsigned long flags;
932 __u8 oldlines;
933 int linechange = 0;
934
935 spin_lock_irqsave(&priv->lock, flags);
936
937
938 if (!priv->termios_initialized) {
939 if (priv->chiptype == CT_EARTHMATE) {
940 tty->termios = tty_std_termios;
941 tty->termios.c_cflag = B4800 | CS8 | CREAD | HUPCL |
942 CLOCAL;
943 tty->termios.c_ispeed = 4800;
944 tty->termios.c_ospeed = 4800;
945 } else if (priv->chiptype == CT_CYPHIDCOM) {
946 tty->termios = tty_std_termios;
947 tty->termios.c_cflag = B9600 | CS8 | CREAD | HUPCL |
948 CLOCAL;
949 tty->termios.c_ispeed = 9600;
950 tty->termios.c_ospeed = 9600;
951 } else if (priv->chiptype == CT_CA42V2) {
952 tty->termios = tty_std_termios;
953 tty->termios.c_cflag = B9600 | CS8 | CREAD | HUPCL |
954 CLOCAL;
955 tty->termios.c_ispeed = 9600;
956 tty->termios.c_ospeed = 9600;
957 }
958 priv->termios_initialized = 1;
959 }
960 spin_unlock_irqrestore(&priv->lock, flags);
961
962
963 tty->termios.c_cflag &= ~(CMSPAR|CRTSCTS);
964
965 cflag = tty->termios.c_cflag;
966 iflag = tty->termios.c_iflag;
967
968
969 if (old_termios) {
970 spin_lock_irqsave(&priv->lock, flags);
971 priv->tmp_termios = tty->termios;
972 spin_unlock_irqrestore(&priv->lock, flags);
973 }
974
975
976
977
978
979 stop_bits = cflag & CSTOPB ? 1 : 0;
980
981 if (cflag & PARENB) {
982 parity_enable = 1;
983
984 parity_type = cflag & PARODD ? 1 : 0;
985 } else
986 parity_enable = parity_type = 0;
987
988 switch (cflag & CSIZE) {
989 case CS5:
990 data_bits = 0;
991 break;
992 case CS6:
993 data_bits = 1;
994 break;
995 case CS7:
996 data_bits = 2;
997 break;
998 case CS8:
999 data_bits = 3;
1000 break;
1001 default:
1002 dev_err(dev, "%s - CSIZE was set, but not CS5-CS8\n", __func__);
1003 data_bits = 3;
1004 }
1005 spin_lock_irqsave(&priv->lock, flags);
1006 oldlines = priv->line_control;
1007 if ((cflag & CBAUD) == B0) {
1008
1009 dev_dbg(dev, "%s - dropping the lines, baud rate 0bps\n", __func__);
1010 priv->line_control &= ~(CONTROL_DTR | CONTROL_RTS);
1011 } else
1012 priv->line_control = (CONTROL_DTR | CONTROL_RTS);
1013 spin_unlock_irqrestore(&priv->lock, flags);
1014
1015 dev_dbg(dev, "%s - sending %d stop_bits, %d parity_enable, %d parity_type, %d data_bits (+5)\n",
1016 __func__, stop_bits, parity_enable, parity_type, data_bits);
1017
1018 cypress_serial_control(tty, port, tty_get_baud_rate(tty),
1019 data_bits, stop_bits,
1020 parity_enable, parity_type,
1021 0, CYPRESS_SET_CONFIG);
1022
1023
1024
1025
1026 cypress_serial_control(tty, port, 0, 0, 0, 0, 0, 0, CYPRESS_GET_CONFIG);
1027
1028
1029
1030
1031 spin_lock_irqsave(&priv->lock, flags);
1032 if (priv->chiptype == CT_EARTHMATE && priv->baud_rate == 4800) {
1033 dev_dbg(dev, "Using custom termios settings for a baud rate of 4800bps.\n");
1034
1035
1036 tty->termios.c_iflag
1037 &= ~(IGNBRK
1038 | BRKINT
1039 | PARMRK
1040 | ISTRIP
1041 | INLCR
1042 | IGNCR
1043 | ICRNL
1044 | IXON);
1045
1046 tty->termios.c_oflag
1047 &= ~OPOST;
1048
1049 tty->termios.c_lflag
1050 &= ~(ECHO
1051 | ECHONL
1052 | ICANON
1053
1054 | ISIG
1055
1056 | IEXTEN);
1057 }
1058
1059 linechange = (priv->line_control != oldlines);
1060 spin_unlock_irqrestore(&priv->lock, flags);
1061
1062
1063 if (linechange) {
1064 priv->cmd_ctrl = 1;
1065 cypress_write(tty, port, NULL, 0);
1066 }
1067}
1068
1069
1070
1071static int cypress_chars_in_buffer(struct tty_struct *tty)
1072{
1073 struct usb_serial_port *port = tty->driver_data;
1074 struct cypress_private *priv = usb_get_serial_port_data(port);
1075 int chars = 0;
1076 unsigned long flags;
1077
1078 spin_lock_irqsave(&priv->lock, flags);
1079 chars = kfifo_len(&priv->write_fifo);
1080 spin_unlock_irqrestore(&priv->lock, flags);
1081
1082 dev_dbg(&port->dev, "%s - returns %d\n", __func__, chars);
1083 return chars;
1084}
1085
1086
1087static void cypress_throttle(struct tty_struct *tty)
1088{
1089 struct usb_serial_port *port = tty->driver_data;
1090 struct cypress_private *priv = usb_get_serial_port_data(port);
1091
1092 spin_lock_irq(&priv->lock);
1093 priv->rx_flags = THROTTLED;
1094 spin_unlock_irq(&priv->lock);
1095}
1096
1097
1098static void cypress_unthrottle(struct tty_struct *tty)
1099{
1100 struct usb_serial_port *port = tty->driver_data;
1101 struct cypress_private *priv = usb_get_serial_port_data(port);
1102 int actually_throttled, result;
1103
1104 spin_lock_irq(&priv->lock);
1105 actually_throttled = priv->rx_flags & ACTUALLY_THROTTLED;
1106 priv->rx_flags = 0;
1107 spin_unlock_irq(&priv->lock);
1108
1109 if (!priv->comm_is_ok)
1110 return;
1111
1112 if (actually_throttled) {
1113 result = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL);
1114 if (result) {
1115 dev_err(&port->dev, "%s - failed submitting read urb, "
1116 "error %d\n", __func__, result);
1117 cypress_set_dead(port);
1118 }
1119 }
1120}
1121
1122
1123static void cypress_read_int_callback(struct urb *urb)
1124{
1125 struct usb_serial_port *port = urb->context;
1126 struct cypress_private *priv = usb_get_serial_port_data(port);
1127 struct device *dev = &urb->dev->dev;
1128 struct tty_struct *tty;
1129 unsigned char *data = urb->transfer_buffer;
1130 unsigned long flags;
1131 char tty_flag = TTY_NORMAL;
1132 int havedata = 0;
1133 int bytes = 0;
1134 int result;
1135 int i = 0;
1136 int status = urb->status;
1137
1138 switch (status) {
1139 case 0:
1140 break;
1141 case -ECONNRESET:
1142 case -ENOENT:
1143 case -ESHUTDOWN:
1144
1145 return;
1146 case -EPIPE:
1147
1148
1149 default:
1150
1151 dev_err(dev, "%s - unexpected nonzero read status received: %d\n",
1152 __func__, status);
1153 cypress_set_dead(port);
1154 return;
1155 }
1156
1157 spin_lock_irqsave(&priv->lock, flags);
1158 if (priv->rx_flags & THROTTLED) {
1159 dev_dbg(dev, "%s - now throttling\n", __func__);
1160 priv->rx_flags |= ACTUALLY_THROTTLED;
1161 spin_unlock_irqrestore(&priv->lock, flags);
1162 return;
1163 }
1164 spin_unlock_irqrestore(&priv->lock, flags);
1165
1166 tty = tty_port_tty_get(&port->port);
1167 if (!tty) {
1168 dev_dbg(dev, "%s - bad tty pointer - exiting\n", __func__);
1169 return;
1170 }
1171
1172 spin_lock_irqsave(&priv->lock, flags);
1173 result = urb->actual_length;
1174 switch (priv->pkt_fmt) {
1175 default:
1176 case packet_format_1:
1177
1178 priv->current_status = data[0] & 0xF8;
1179 bytes = data[1] + 2;
1180 i = 2;
1181 if (bytes > 2)
1182 havedata = 1;
1183 break;
1184 case packet_format_2:
1185
1186 priv->current_status = data[0] & 0xF8;
1187 bytes = (data[0] & 0x07) + 1;
1188 i = 1;
1189 if (bytes > 1)
1190 havedata = 1;
1191 break;
1192 }
1193 spin_unlock_irqrestore(&priv->lock, flags);
1194 if (result < bytes) {
1195 dev_dbg(dev,
1196 "%s - wrong packet size - received %d bytes but packet said %d bytes\n",
1197 __func__, result, bytes);
1198 goto continue_read;
1199 }
1200
1201 usb_serial_debug_data(&port->dev, __func__, urb->actual_length, data);
1202
1203 spin_lock_irqsave(&priv->lock, flags);
1204
1205 if (priv->current_status != priv->prev_status) {
1206 priv->diff_status |= priv->current_status ^
1207 priv->prev_status;
1208 wake_up_interruptible(&port->delta_msr_wait);
1209 priv->prev_status = priv->current_status;
1210 }
1211 spin_unlock_irqrestore(&priv->lock, flags);
1212
1213
1214
1215 if (tty && !(tty->termios.c_cflag & CLOCAL) &&
1216 !(priv->current_status & UART_CD)) {
1217 dev_dbg(dev, "%s - calling hangup\n", __func__);
1218 tty_hangup(tty);
1219 goto continue_read;
1220 }
1221
1222
1223
1224
1225
1226 spin_lock_irqsave(&priv->lock, flags);
1227 if (priv->current_status & CYP_ERROR) {
1228 spin_unlock_irqrestore(&priv->lock, flags);
1229 tty_flag = TTY_PARITY;
1230 dev_dbg(dev, "%s - Parity Error detected\n", __func__);
1231 } else
1232 spin_unlock_irqrestore(&priv->lock, flags);
1233
1234
1235 if (bytes > i) {
1236 tty_insert_flip_string_fixed_flag(&port->port, data + i,
1237 tty_flag, bytes - i);
1238 tty_flip_buffer_push(&port->port);
1239 }
1240
1241 spin_lock_irqsave(&priv->lock, flags);
1242
1243 priv->bytes_in += bytes;
1244 spin_unlock_irqrestore(&priv->lock, flags);
1245
1246continue_read:
1247 tty_kref_put(tty);
1248
1249
1250
1251 if (priv->comm_is_ok) {
1252 usb_fill_int_urb(port->interrupt_in_urb, port->serial->dev,
1253 usb_rcvintpipe(port->serial->dev,
1254 port->interrupt_in_endpointAddress),
1255 port->interrupt_in_urb->transfer_buffer,
1256 port->interrupt_in_urb->transfer_buffer_length,
1257 cypress_read_int_callback, port,
1258 priv->read_urb_interval);
1259 result = usb_submit_urb(port->interrupt_in_urb, GFP_ATOMIC);
1260 if (result && result != -EPERM) {
1261 dev_err(dev, "%s - failed resubmitting read urb, error %d\n",
1262 __func__, result);
1263 cypress_set_dead(port);
1264 }
1265 }
1266}
1267
1268
1269static void cypress_write_int_callback(struct urb *urb)
1270{
1271 struct usb_serial_port *port = urb->context;
1272 struct cypress_private *priv = usb_get_serial_port_data(port);
1273 struct device *dev = &urb->dev->dev;
1274 int result;
1275 int status = urb->status;
1276
1277 switch (status) {
1278 case 0:
1279
1280 break;
1281 case -ECONNRESET:
1282 case -ENOENT:
1283 case -ESHUTDOWN:
1284
1285 dev_dbg(dev, "%s - urb shutting down with status: %d\n",
1286 __func__, status);
1287 priv->write_urb_in_use = 0;
1288 return;
1289 case -EPIPE:
1290 if (!priv->comm_is_ok)
1291 break;
1292 usb_clear_halt(port->serial->dev, 0x02);
1293
1294 dev_dbg(dev, "%s - nonzero write bulk status received: %d\n",
1295 __func__, status);
1296 port->interrupt_out_urb->transfer_buffer_length = 1;
1297 result = usb_submit_urb(port->interrupt_out_urb, GFP_ATOMIC);
1298 if (!result)
1299 return;
1300 dev_err(dev, "%s - failed resubmitting write urb, error %d\n",
1301 __func__, result);
1302 cypress_set_dead(port);
1303 break;
1304 default:
1305 dev_err(dev, "%s - unexpected nonzero write status received: %d\n",
1306 __func__, status);
1307 cypress_set_dead(port);
1308 break;
1309 }
1310 priv->write_urb_in_use = 0;
1311
1312
1313 cypress_send(port);
1314}
1315
1316module_usb_serial_driver(serial_drivers, id_table_combined);
1317
1318MODULE_AUTHOR(DRIVER_AUTHOR);
1319MODULE_DESCRIPTION(DRIVER_DESC);
1320MODULE_LICENSE("GPL");
1321
1322module_param(stats, bool, S_IRUGO | S_IWUSR);
1323MODULE_PARM_DESC(stats, "Enable statistics or not");
1324module_param(interval, int, S_IRUGO | S_IWUSR);
1325MODULE_PARM_DESC(interval, "Overrides interrupt interval");
1326module_param(unstable_bauds, bool, S_IRUGO | S_IWUSR);
1327MODULE_PARM_DESC(unstable_bauds, "Allow unstable baud rates");
1328