xref: /openbmc/linux/drivers/usb/serial/cypress_m8.c (revision c21b37f6)
1 /*
2  * USB Cypress M8 driver
3  *
4  * 	Copyright (C) 2004
5  * 	    Lonnie Mendez (dignome@gmail.com)
6  *	Copyright (C) 2003,2004
7  *	    Neil Whelchel (koyama@firstlight.net)
8  *
9  * 	This program is free software; you can redistribute it and/or modify
10  * 	it under the terms of the GNU General Public License as published by
11  * 	the Free Software Foundation; either version 2 of the License, or
12  * 	(at your option) any later version.
13  *
14  * See Documentation/usb/usb-serial.txt for more information on using this driver
15  *
16  * See http://geocities.com/i0xox0i for information on this driver and the
17  * earthmate usb device.
18  *
19  *  Lonnie Mendez <dignome@gmail.com>
20  *  4-29-2005
21  *	Fixed problem where setting or retreiving the serial config would fail with
22  * 	EPIPE.  Removed CRTS toggling so the driver behaves more like other usbserial
23  * 	adapters.  Issued new interval of 1ms instead of the default 10ms.  As a
24  * 	result, transfer speed has been substantially increased.  From avg. 850bps to
25  * 	avg. 3300bps.  initial termios has also been modified.  Cleaned up code and
26  * 	formatting issues so it is more readable.  Replaced the C++ style comments.
27  *
28  *  Lonnie Mendez <dignome@gmail.com>
29  *  12-15-2004
30  *	Incorporated write buffering from pl2303 driver.  Fixed bug with line
31  *	handling so both lines are raised in cypress_open. (was dropping rts)
32  *      Various code cleanups made as well along with other misc bug fixes.
33  *
34  *  Lonnie Mendez <dignome@gmail.com>
35  *  04-10-2004
36  *	Driver modified to support dynamic line settings.  Various improvments
37  *      and features.
38  *
39  *  Neil Whelchel
40  *  10-2003
41  *	Driver first released.
42  *
43  */
44 
45 /* Thanks to Neil Whelchel for writing the first cypress m8 implementation for linux. */
46 /* Thanks to cypress for providing references for the hid reports. */
47 /* Thanks to Jiang Zhang for providing links and for general help. */
48 /* Code originates and was built up from ftdi_sio, belkin, pl2303 and others. */
49 
50 
51 #include <linux/kernel.h>
52 #include <linux/errno.h>
53 #include <linux/init.h>
54 #include <linux/slab.h>
55 #include <linux/tty.h>
56 #include <linux/tty_driver.h>
57 #include <linux/tty_flip.h>
58 #include <linux/module.h>
59 #include <linux/moduleparam.h>
60 #include <linux/spinlock.h>
61 #include <linux/usb.h>
62 #include <linux/usb/serial.h>
63 #include <linux/serial.h>
64 #include <linux/delay.h>
65 #include <asm/uaccess.h>
66 
67 #include "cypress_m8.h"
68 
69 
70 #ifdef CONFIG_USB_SERIAL_DEBUG
71 	static int debug = 1;
72 #else
73 	static int debug;
74 #endif
75 static int stats;
76 static int interval;
77 
78 /*
79  * Version Information
80  */
81 #define DRIVER_VERSION "v1.09"
82 #define DRIVER_AUTHOR "Lonnie Mendez <dignome@gmail.com>, Neil Whelchel <koyama@firstlight.net>"
83 #define DRIVER_DESC "Cypress USB to Serial Driver"
84 
85 /* write buffer size defines */
86 #define CYPRESS_BUF_SIZE	1024
87 #define CYPRESS_CLOSING_WAIT	(30*HZ)
88 
89 static struct usb_device_id id_table_earthmate [] = {
90 	{ USB_DEVICE(VENDOR_ID_DELORME, PRODUCT_ID_EARTHMATEUSB) },
91 	{ USB_DEVICE(VENDOR_ID_DELORME, PRODUCT_ID_EARTHMATEUSB_LT20) },
92 	{ }						/* Terminating entry */
93 };
94 
95 static struct usb_device_id id_table_cyphidcomrs232 [] = {
96 	{ USB_DEVICE(VENDOR_ID_CYPRESS, PRODUCT_ID_CYPHIDCOM) },
97 	{ }						/* Terminating entry */
98 };
99 
100 static struct usb_device_id id_table_nokiaca42v2 [] = {
101 	{ USB_DEVICE(VENDOR_ID_DAZZLE, PRODUCT_ID_CA42) },
102 	{ }						/* Terminating entry */
103 };
104 
105 static struct usb_device_id id_table_combined [] = {
106 	{ USB_DEVICE(VENDOR_ID_DELORME, PRODUCT_ID_EARTHMATEUSB) },
107 	{ USB_DEVICE(VENDOR_ID_DELORME, PRODUCT_ID_EARTHMATEUSB_LT20) },
108 	{ USB_DEVICE(VENDOR_ID_CYPRESS, PRODUCT_ID_CYPHIDCOM) },
109 	{ USB_DEVICE(VENDOR_ID_DAZZLE, PRODUCT_ID_CA42) },
110 	{ }						/* Terminating entry */
111 };
112 
113 MODULE_DEVICE_TABLE (usb, id_table_combined);
114 
115 static struct usb_driver cypress_driver = {
116 	.name =		"cypress",
117 	.probe =	usb_serial_probe,
118 	.disconnect =	usb_serial_disconnect,
119 	.id_table =	id_table_combined,
120 	.no_dynamic_id = 	1,
121 };
122 
123 struct cypress_private {
124 	spinlock_t lock;		   /* private lock */
125 	int chiptype;			   /* identifier of device, for quirks/etc */
126 	int bytes_in;			   /* used for statistics */
127 	int bytes_out;			   /* used for statistics */
128 	int cmd_count;			   /* used for statistics */
129 	int cmd_ctrl;			   /* always set this to 1 before issuing a command */
130 	struct cypress_buf *buf;	   /* write buffer */
131 	int write_urb_in_use;		   /* write urb in use indicator */
132 	int write_urb_interval;            /* interval to use for write urb */
133 	int read_urb_interval;             /* interval to use for read urb */
134 	int comm_is_ok;                    /* true if communication is (still) ok */
135 	int termios_initialized;
136 	__u8 line_control;	   	   /* holds dtr / rts value */
137 	__u8 current_status;	   	   /* received from last read - info on dsr,cts,cd,ri,etc */
138 	__u8 current_config;	   	   /* stores the current configuration byte */
139 	__u8 rx_flags;			   /* throttling - used from whiteheat/ftdi_sio */
140 	int baud_rate;			   /* stores current baud rate in integer form */
141 	int cbr_mask;			   /* stores current baud rate in masked form */
142 	int isthrottled;		   /* if throttled, discard reads */
143 	wait_queue_head_t delta_msr_wait;  /* used for TIOCMIWAIT */
144 	char prev_status, diff_status;	   /* used for TIOCMIWAIT */
145 	/* we pass a pointer to this as the arguement sent to cypress_set_termios old_termios */
146 	struct ktermios tmp_termios; 	   /* stores the old termios settings */
147 };
148 
149 /* write buffer structure */
150 struct cypress_buf {
151 	unsigned int	buf_size;
152 	char		*buf_buf;
153 	char		*buf_get;
154 	char		*buf_put;
155 };
156 
157 /* function prototypes for the Cypress USB to serial device */
158 static int  cypress_earthmate_startup	(struct usb_serial *serial);
159 static int  cypress_hidcom_startup	(struct usb_serial *serial);
160 static int  cypress_ca42v2_startup	(struct usb_serial *serial);
161 static void cypress_shutdown		(struct usb_serial *serial);
162 static int  cypress_open		(struct usb_serial_port *port, struct file *filp);
163 static void cypress_close		(struct usb_serial_port *port, struct file *filp);
164 static int  cypress_write		(struct usb_serial_port *port, const unsigned char *buf, int count);
165 static void cypress_send		(struct usb_serial_port *port);
166 static int  cypress_write_room		(struct usb_serial_port *port);
167 static int  cypress_ioctl		(struct usb_serial_port *port, struct file * file, unsigned int cmd, unsigned long arg);
168 static void cypress_set_termios		(struct usb_serial_port *port, struct ktermios * old);
169 static int  cypress_tiocmget		(struct usb_serial_port *port, struct file *file);
170 static int  cypress_tiocmset		(struct usb_serial_port *port, struct file *file, unsigned int set, unsigned int clear);
171 static int  cypress_chars_in_buffer	(struct usb_serial_port *port);
172 static void cypress_throttle		(struct usb_serial_port *port);
173 static void cypress_unthrottle		(struct usb_serial_port *port);
174 static void cypress_set_dead		(struct usb_serial_port *port);
175 static void cypress_read_int_callback	(struct urb *urb);
176 static void cypress_write_int_callback	(struct urb *urb);
177 /* baud helper functions */
178 static int	 mask_to_rate		(unsigned mask);
179 static unsigned  rate_to_mask		(int rate);
180 /* write buffer functions */
181 static struct cypress_buf *cypress_buf_alloc(unsigned int size);
182 static void 		  cypress_buf_free(struct cypress_buf *cb);
183 static void		  cypress_buf_clear(struct cypress_buf *cb);
184 static unsigned int	  cypress_buf_data_avail(struct cypress_buf *cb);
185 static unsigned int	  cypress_buf_space_avail(struct cypress_buf *cb);
186 static unsigned int	  cypress_buf_put(struct cypress_buf *cb, const char *buf, unsigned int count);
187 static unsigned int	  cypress_buf_get(struct cypress_buf *cb, char *buf, unsigned int count);
188 
189 
190 static struct usb_serial_driver cypress_earthmate_device = {
191 	.driver = {
192 		.owner =		THIS_MODULE,
193 		.name =			"earthmate",
194 	},
195 	.description =			"DeLorme Earthmate USB",
196 	.usb_driver = 			&cypress_driver,
197 	.id_table =			id_table_earthmate,
198 	.num_interrupt_in = 		1,
199 	.num_interrupt_out =		1,
200 	.num_bulk_in =			NUM_DONT_CARE,
201 	.num_bulk_out =			NUM_DONT_CARE,
202 	.num_ports =			1,
203 	.attach =			cypress_earthmate_startup,
204 	.shutdown =			cypress_shutdown,
205 	.open =				cypress_open,
206 	.close =			cypress_close,
207 	.write =			cypress_write,
208 	.write_room =			cypress_write_room,
209 	.ioctl =			cypress_ioctl,
210 	.set_termios =			cypress_set_termios,
211 	.tiocmget =			cypress_tiocmget,
212 	.tiocmset =			cypress_tiocmset,
213 	.chars_in_buffer =		cypress_chars_in_buffer,
214 	.throttle =		 	cypress_throttle,
215 	.unthrottle =			cypress_unthrottle,
216 	.read_int_callback =		cypress_read_int_callback,
217 	.write_int_callback =		cypress_write_int_callback,
218 };
219 
220 static struct usb_serial_driver cypress_hidcom_device = {
221 	.driver = {
222 		.owner =		THIS_MODULE,
223 		.name =			"cyphidcom",
224 	},
225 	.description =			"HID->COM RS232 Adapter",
226 	.usb_driver = 			&cypress_driver,
227 	.id_table =			id_table_cyphidcomrs232,
228 	.num_interrupt_in =		1,
229 	.num_interrupt_out =		1,
230 	.num_bulk_in =			NUM_DONT_CARE,
231 	.num_bulk_out =			NUM_DONT_CARE,
232 	.num_ports =			1,
233 	.attach =			cypress_hidcom_startup,
234 	.shutdown =			cypress_shutdown,
235 	.open =				cypress_open,
236 	.close =			cypress_close,
237 	.write =			cypress_write,
238 	.write_room =			cypress_write_room,
239 	.ioctl =			cypress_ioctl,
240 	.set_termios =			cypress_set_termios,
241 	.tiocmget =			cypress_tiocmget,
242 	.tiocmset =			cypress_tiocmset,
243 	.chars_in_buffer =		cypress_chars_in_buffer,
244 	.throttle =			cypress_throttle,
245 	.unthrottle =			cypress_unthrottle,
246 	.read_int_callback =		cypress_read_int_callback,
247 	.write_int_callback =		cypress_write_int_callback,
248 };
249 
250 static struct usb_serial_driver cypress_ca42v2_device = {
251 	.driver = {
252 		.owner =		THIS_MODULE,
253                 .name =			"nokiaca42v2",
254 	},
255 	.description =			"Nokia CA-42 V2 Adapter",
256 	.usb_driver = 			&cypress_driver,
257 	.id_table =			id_table_nokiaca42v2,
258 	.num_interrupt_in =		1,
259 	.num_interrupt_out =		1,
260 	.num_bulk_in =			NUM_DONT_CARE,
261 	.num_bulk_out =			NUM_DONT_CARE,
262 	.num_ports =			1,
263 	.attach =			cypress_ca42v2_startup,
264 	.shutdown =			cypress_shutdown,
265 	.open =				cypress_open,
266 	.close =			cypress_close,
267 	.write =			cypress_write,
268 	.write_room =			cypress_write_room,
269 	.ioctl =			cypress_ioctl,
270 	.set_termios =			cypress_set_termios,
271 	.tiocmget =			cypress_tiocmget,
272 	.tiocmset =			cypress_tiocmset,
273 	.chars_in_buffer =		cypress_chars_in_buffer,
274 	.throttle =			cypress_throttle,
275 	.unthrottle =			cypress_unthrottle,
276 	.read_int_callback =		cypress_read_int_callback,
277 	.write_int_callback =		cypress_write_int_callback,
278 };
279 
280 /*****************************************************************************
281  * Cypress serial helper functions
282  *****************************************************************************/
283 
284 
285 /* This function can either set or retrieve the current serial line settings */
286 static int cypress_serial_control (struct usb_serial_port *port, unsigned baud_mask, int data_bits, int stop_bits,
287 				   int parity_enable, int parity_type, int reset, int cypress_request_type)
288 {
289 	int new_baudrate = 0, retval = 0, tries = 0;
290 	struct cypress_private *priv;
291 	__u8 feature_buffer[8];
292 	unsigned long flags;
293 
294 	dbg("%s", __FUNCTION__);
295 
296 	priv = usb_get_serial_port_data(port);
297 
298 	if (!priv->comm_is_ok)
299 		return -ENODEV;
300 
301 	switch(cypress_request_type) {
302 		case CYPRESS_SET_CONFIG:
303 
304 			/*
305 			 * The general purpose firmware for the Cypress M8 allows for a maximum speed
306  			 * of 57600bps (I have no idea whether DeLorme chose to use the general purpose
307 			 * firmware or not), if you need to modify this speed setting for your own
308 			 * project please add your own chiptype and modify the code likewise.  The
309 			 * Cypress HID->COM device will work successfully up to 115200bps (but the
310 			 * actual throughput is around 3kBps).
311 			 */
312 			if (baud_mask != priv->cbr_mask) {
313 				dbg("%s - baud rate is changing", __FUNCTION__);
314 				if ( priv->chiptype == CT_EARTHMATE ) {
315 					/* 300 and 600 baud rates are supported under the generic firmware,
316 					 * but are not used with NMEA and SiRF protocols */
317 
318 					if ( (baud_mask == B300) || (baud_mask == B600) ) {
319 						err("%s - failed setting baud rate, unsupported speed",
320 						    __FUNCTION__);
321 						new_baudrate = priv->baud_rate;
322 					} else if ( (new_baudrate = mask_to_rate(baud_mask)) == -1) {
323 						err("%s - failed setting baud rate, unsupported speed",
324 						    __FUNCTION__);
325 						new_baudrate = priv->baud_rate;
326 					}
327 				} else if (priv->chiptype == CT_CYPHIDCOM) {
328 					if ( (new_baudrate = mask_to_rate(baud_mask)) == -1) {
329 						err("%s - failed setting baud rate, unsupported speed",
330 						    __FUNCTION__);
331 						new_baudrate = priv->baud_rate;
332 					}
333 				} else if (priv->chiptype == CT_CA42V2) {
334 					if ( (new_baudrate = mask_to_rate(baud_mask)) == -1) {
335 						err("%s - failed setting baud rate, unsupported speed",
336 						    __FUNCTION__);
337 						new_baudrate = priv->baud_rate;
338 					}
339 				} else if (priv->chiptype == CT_GENERIC) {
340 					if ( (new_baudrate = mask_to_rate(baud_mask)) == -1) {
341 						err("%s - failed setting baud rate, unsupported speed",
342 						    __FUNCTION__);
343 						new_baudrate = priv->baud_rate;
344 					}
345 				} else {
346 					info("%s - please define your chiptype", __FUNCTION__);
347 					new_baudrate = priv->baud_rate;
348 				}
349 			} else {  /* baud rate not changing, keep the old */
350 				new_baudrate = priv->baud_rate;
351 			}
352 			dbg("%s - baud rate is being sent as %d", __FUNCTION__, new_baudrate);
353 
354 			memset(feature_buffer, 0, 8);
355 			/* fill the feature_buffer with new configuration */
356 			*((u_int32_t *)feature_buffer) = new_baudrate;
357 
358 			feature_buffer[4] |= data_bits;   /* assign data bits in 2 bit space ( max 3 ) */
359 			/* 1 bit gap */
360 			feature_buffer[4] |= (stop_bits << 3);   /* assign stop bits in 1 bit space */
361 			feature_buffer[4] |= (parity_enable << 4);   /* assign parity flag in 1 bit space */
362 			feature_buffer[4] |= (parity_type << 5);   /* assign parity type in 1 bit space */
363 			/* 1 bit gap */
364 			feature_buffer[4] |= (reset << 7);   /* assign reset at end of byte, 1 bit space */
365 
366 			dbg("%s - device is being sent this feature report:", __FUNCTION__);
367 			dbg("%s - %02X - %02X - %02X - %02X - %02X", __FUNCTION__, feature_buffer[0], feature_buffer[1],
368 		            feature_buffer[2], feature_buffer[3], feature_buffer[4]);
369 
370 			do {
371 			retval = usb_control_msg (port->serial->dev, usb_sndctrlpipe(port->serial->dev, 0),
372 					  	  HID_REQ_SET_REPORT, USB_DIR_OUT | USB_RECIP_INTERFACE | USB_TYPE_CLASS,
373 						  	  0x0300, 0, feature_buffer, 8, 500);
374 
375 				if (tries++ >= 3)
376 					break;
377 
378 			} while (retval != 8 && retval != -ENODEV);
379 
380 			if (retval != 8) {
381 				err("%s - failed sending serial line settings - %d", __FUNCTION__, retval);
382 				cypress_set_dead(port);
383 			} else {
384 				spin_lock_irqsave(&priv->lock, flags);
385 				priv->baud_rate = new_baudrate;
386 				priv->cbr_mask = baud_mask;
387 				priv->current_config = feature_buffer[4];
388 				spin_unlock_irqrestore(&priv->lock, flags);
389 			}
390 		break;
391 		case CYPRESS_GET_CONFIG:
392 			dbg("%s - retreiving serial line settings", __FUNCTION__);
393 			/* set initial values in feature buffer */
394 			memset(feature_buffer, 0, 8);
395 
396 			do {
397 			retval = usb_control_msg (port->serial->dev, usb_rcvctrlpipe(port->serial->dev, 0),
398 						  HID_REQ_GET_REPORT, USB_DIR_IN | USB_RECIP_INTERFACE | USB_TYPE_CLASS,
399 							  0x0300, 0, feature_buffer, 8, 500);
400 
401 				if (tries++ >= 3)
402 					break;
403 
404 			} while (retval != 5 && retval != -ENODEV);
405 
406 			if (retval != 5) {
407 				err("%s - failed to retrieve serial line settings - %d", __FUNCTION__, retval);
408 				cypress_set_dead(port);
409 				return retval;
410 			} else {
411 				spin_lock_irqsave(&priv->lock, flags);
412 
413 				/* store the config in one byte, and later use bit masks to check values */
414 				priv->current_config = feature_buffer[4];
415 				priv->baud_rate = *((u_int32_t *)feature_buffer);
416 
417 				if ( (priv->cbr_mask = rate_to_mask(priv->baud_rate)) == 0x40)
418 					dbg("%s - failed setting the baud mask (not defined)", __FUNCTION__);
419 				spin_unlock_irqrestore(&priv->lock, flags);
420 			}
421 	}
422 	spin_lock_irqsave(&priv->lock, flags);
423 	++priv->cmd_count;
424 	spin_unlock_irqrestore(&priv->lock, flags);
425 
426 	return retval;
427 } /* cypress_serial_control */
428 
429 
430 static void cypress_set_dead(struct usb_serial_port *port)
431 {
432 	struct cypress_private *priv = usb_get_serial_port_data(port);
433 	unsigned long flags;
434 
435 	spin_lock_irqsave(&priv->lock, flags);
436 	if (!priv->comm_is_ok) {
437 		spin_unlock_irqrestore(&priv->lock, flags);
438 		return;
439 	}
440 	priv->comm_is_ok = 0;
441 	spin_unlock_irqrestore(&priv->lock, flags);
442 
443 	err("cypress_m8 suspending failing port %d - interval might be too short",
444 	    port->number);
445 }
446 
447 
448 /* given a baud mask, it will return integer baud on success */
449 static int mask_to_rate (unsigned mask)
450 {
451 	int rate;
452 
453 	switch (mask) {
454 		case B0: rate = 0; break;
455 		case B300: rate = 300; break;
456 		case B600: rate = 600; break;
457 		case B1200: rate = 1200; break;
458 		case B2400: rate = 2400; break;
459 		case B4800: rate = 4800; break;
460 		case B9600: rate = 9600; break;
461 		case B19200: rate = 19200; break;
462 		case B38400: rate = 38400; break;
463 		case B57600: rate = 57600; break;
464 		case B115200: rate = 115200; break;
465 		default: rate = -1;
466 	}
467 
468 	return rate;
469 }
470 
471 
472 static unsigned rate_to_mask (int rate)
473 {
474 	unsigned mask;
475 
476 	switch (rate) {
477 		case 0: mask = B0; break;
478 		case 300: mask = B300; break;
479 		case 600: mask = B600; break;
480 		case 1200: mask = B1200; break;
481 		case 2400: mask = B2400; break;
482 		case 4800: mask = B4800; break;
483 		case 9600: mask = B9600; break;
484 		case 19200: mask = B19200; break;
485 		case 38400: mask = B38400; break;
486 		case 57600: mask = B57600; break;
487 		case 115200: mask = B115200; break;
488 		default: mask = 0x40;
489 	}
490 
491 	return mask;
492 }
493 /*****************************************************************************
494  * Cypress serial driver functions
495  *****************************************************************************/
496 
497 
498 static int generic_startup (struct usb_serial *serial)
499 {
500 	struct cypress_private *priv;
501 	struct usb_serial_port *port = serial->port[0];
502 
503 	dbg("%s - port %d", __FUNCTION__, port->number);
504 
505 	priv = kzalloc(sizeof (struct cypress_private), GFP_KERNEL);
506 	if (!priv)
507 		return -ENOMEM;
508 
509 	priv->comm_is_ok = !0;
510 	spin_lock_init(&priv->lock);
511 	priv->buf = cypress_buf_alloc(CYPRESS_BUF_SIZE);
512 	if (priv->buf == NULL) {
513 		kfree(priv);
514 		return -ENOMEM;
515 	}
516 	init_waitqueue_head(&priv->delta_msr_wait);
517 
518 	usb_reset_configuration (serial->dev);
519 
520 	priv->cmd_ctrl = 0;
521 	priv->line_control = 0;
522 	priv->termios_initialized = 0;
523 	priv->rx_flags = 0;
524 	priv->cbr_mask = B300;
525 	if (interval > 0) {
526 		priv->write_urb_interval = interval;
527 		priv->read_urb_interval = interval;
528 		dbg("%s - port %d read & write intervals forced to %d",
529 		    __FUNCTION__,port->number,interval);
530 	} else {
531 		priv->write_urb_interval = port->interrupt_out_urb->interval;
532 		priv->read_urb_interval = port->interrupt_in_urb->interval;
533 		dbg("%s - port %d intervals: read=%d write=%d",
534 		    __FUNCTION__,port->number,
535 		    priv->read_urb_interval,priv->write_urb_interval);
536 	}
537 	usb_set_serial_port_data(port, priv);
538 
539 	return 0;
540 }
541 
542 
543 static int cypress_earthmate_startup (struct usb_serial *serial)
544 {
545 	struct cypress_private *priv;
546 
547 	dbg("%s", __FUNCTION__);
548 
549 	if (generic_startup(serial)) {
550 		dbg("%s - Failed setting up port %d", __FUNCTION__,
551 				serial->port[0]->number);
552 		return 1;
553 	}
554 
555 	priv = usb_get_serial_port_data(serial->port[0]);
556 	priv->chiptype = CT_EARTHMATE;
557 
558 	return 0;
559 } /* cypress_earthmate_startup */
560 
561 
562 static int cypress_hidcom_startup (struct usb_serial *serial)
563 {
564 	struct cypress_private *priv;
565 
566 	dbg("%s", __FUNCTION__);
567 
568 	if (generic_startup(serial)) {
569 		dbg("%s - Failed setting up port %d", __FUNCTION__,
570 				serial->port[0]->number);
571 		return 1;
572 	}
573 
574 	priv = usb_get_serial_port_data(serial->port[0]);
575 	priv->chiptype = CT_CYPHIDCOM;
576 
577 	return 0;
578 } /* cypress_hidcom_startup */
579 
580 
581 static int cypress_ca42v2_startup (struct usb_serial *serial)
582 {
583 	struct cypress_private *priv;
584 
585 	dbg("%s", __FUNCTION__);
586 
587 	if (generic_startup(serial)) {
588 		dbg("%s - Failed setting up port %d", __FUNCTION__,
589 				serial->port[0]->number);
590 		return 1;
591 	}
592 
593 	priv = usb_get_serial_port_data(serial->port[0]);
594 	priv->chiptype = CT_CA42V2;
595 
596 	return 0;
597 } /* cypress_ca42v2_startup */
598 
599 
600 static void cypress_shutdown (struct usb_serial *serial)
601 {
602 	struct cypress_private *priv;
603 
604 	dbg ("%s - port %d", __FUNCTION__, serial->port[0]->number);
605 
606 	/* all open ports are closed at this point */
607 
608 	priv = usb_get_serial_port_data(serial->port[0]);
609 
610 	if (priv) {
611 		cypress_buf_free(priv->buf);
612 		kfree(priv);
613 		usb_set_serial_port_data(serial->port[0], NULL);
614 	}
615 }
616 
617 
618 static int cypress_open (struct usb_serial_port *port, struct file *filp)
619 {
620 	struct cypress_private *priv = usb_get_serial_port_data(port);
621 	struct usb_serial *serial = port->serial;
622 	unsigned long flags;
623 	int result = 0;
624 
625 	dbg("%s - port %d", __FUNCTION__, port->number);
626 
627 	if (!priv->comm_is_ok)
628 		return -EIO;
629 
630 	/* clear halts before open */
631 	usb_clear_halt(serial->dev, 0x81);
632 	usb_clear_halt(serial->dev, 0x02);
633 
634 	spin_lock_irqsave(&priv->lock, flags);
635 	/* reset read/write statistics */
636 	priv->bytes_in = 0;
637 	priv->bytes_out = 0;
638 	priv->cmd_count = 0;
639 	priv->rx_flags = 0;
640 	spin_unlock_irqrestore(&priv->lock, flags);
641 
642 	/* setting to zero could cause data loss */
643 	port->tty->low_latency = 1;
644 
645 	/* raise both lines and set termios */
646 	spin_lock_irqsave(&priv->lock, flags);
647 	priv->line_control = CONTROL_DTR | CONTROL_RTS;
648 	priv->cmd_ctrl = 1;
649 	spin_unlock_irqrestore(&priv->lock, flags);
650 	result = cypress_write(port, NULL, 0);
651 
652 	if (result) {
653 		dev_err(&port->dev, "%s - failed setting the control lines - error %d\n", __FUNCTION__, result);
654 		return result;
655 	} else
656 		dbg("%s - success setting the control lines", __FUNCTION__);
657 
658 	cypress_set_termios(port, &priv->tmp_termios);
659 
660 	/* setup the port and start reading from the device */
661 	if(!port->interrupt_in_urb){
662 		err("%s - interrupt_in_urb is empty!", __FUNCTION__);
663 		return(-1);
664 	}
665 
666 	usb_fill_int_urb(port->interrupt_in_urb, serial->dev,
667 		usb_rcvintpipe(serial->dev, port->interrupt_in_endpointAddress),
668 		port->interrupt_in_urb->transfer_buffer, port->interrupt_in_urb->transfer_buffer_length,
669 		cypress_read_int_callback, port, priv->read_urb_interval);
670 	result = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL);
671 
672 	if (result){
673 		dev_err(&port->dev, "%s - failed submitting read urb, error %d\n", __FUNCTION__, result);
674 		cypress_set_dead(port);
675 	}
676 
677 	return result;
678 } /* cypress_open */
679 
680 
681 static void cypress_close(struct usb_serial_port *port, struct file * filp)
682 {
683 	struct cypress_private *priv = usb_get_serial_port_data(port);
684 	unsigned int c_cflag;
685 	unsigned long flags;
686 	int bps;
687 	long timeout;
688 	wait_queue_t wait;
689 
690 	dbg("%s - port %d", __FUNCTION__, port->number);
691 
692 	/* wait for data to drain from buffer */
693 	spin_lock_irqsave(&priv->lock, flags);
694 	timeout = CYPRESS_CLOSING_WAIT;
695 	init_waitqueue_entry(&wait, current);
696 	add_wait_queue(&port->tty->write_wait, &wait);
697 	for (;;) {
698 		set_current_state(TASK_INTERRUPTIBLE);
699 		if (cypress_buf_data_avail(priv->buf) == 0
700 		|| timeout == 0 || signal_pending(current)
701 		|| !usb_get_intfdata(port->serial->interface))
702 			break;
703 		spin_unlock_irqrestore(&priv->lock, flags);
704 		timeout = schedule_timeout(timeout);
705 		spin_lock_irqsave(&priv->lock, flags);
706 	}
707 	set_current_state(TASK_RUNNING);
708 	remove_wait_queue(&port->tty->write_wait, &wait);
709 	/* clear out any remaining data in the buffer */
710 	cypress_buf_clear(priv->buf);
711 	spin_unlock_irqrestore(&priv->lock, flags);
712 
713 	/* wait for characters to drain from device */
714 	bps = tty_get_baud_rate(port->tty);
715 	if (bps > 1200)
716 		timeout = max((HZ*2560)/bps,HZ/10);
717 	else
718 		timeout = 2*HZ;
719 	schedule_timeout_interruptible(timeout);
720 
721 	dbg("%s - stopping urbs", __FUNCTION__);
722 	usb_kill_urb (port->interrupt_in_urb);
723 	usb_kill_urb (port->interrupt_out_urb);
724 
725 	if (port->tty) {
726 		c_cflag = port->tty->termios->c_cflag;
727 		if (c_cflag & HUPCL) {
728 			/* drop dtr and rts */
729 			priv = usb_get_serial_port_data(port);
730 			spin_lock_irqsave(&priv->lock, flags);
731 			priv->line_control = 0;
732 			priv->cmd_ctrl = 1;
733 			spin_unlock_irqrestore(&priv->lock, flags);
734 			cypress_write(port, NULL, 0);
735 		}
736 	}
737 
738 	if (stats)
739 		dev_info (&port->dev, "Statistics: %d Bytes In | %d Bytes Out | %d Commands Issued\n",
740 		          priv->bytes_in, priv->bytes_out, priv->cmd_count);
741 } /* cypress_close */
742 
743 
744 static int cypress_write(struct usb_serial_port *port, const unsigned char *buf, int count)
745 {
746 	struct cypress_private *priv = usb_get_serial_port_data(port);
747 	unsigned long flags;
748 
749 	dbg("%s - port %d, %d bytes", __FUNCTION__, port->number, count);
750 
751 	/* line control commands, which need to be executed immediately,
752 	   are not put into the buffer for obvious reasons.
753 	 */
754 	if (priv->cmd_ctrl) {
755 		count = 0;
756 		goto finish;
757 	}
758 
759 	if (!count)
760 		return count;
761 
762 	spin_lock_irqsave(&priv->lock, flags);
763 	count = cypress_buf_put(priv->buf, buf, count);
764 	spin_unlock_irqrestore(&priv->lock, flags);
765 
766 finish:
767 	cypress_send(port);
768 
769 	return count;
770 } /* cypress_write */
771 
772 
773 static void cypress_send(struct usb_serial_port *port)
774 {
775 	int count = 0, result, offset, actual_size;
776 	struct cypress_private *priv = usb_get_serial_port_data(port);
777 	unsigned long flags;
778 
779 	if (!priv->comm_is_ok)
780 		return;
781 
782 	dbg("%s - port %d", __FUNCTION__, port->number);
783 	dbg("%s - interrupt out size is %d", __FUNCTION__, port->interrupt_out_size);
784 
785 	spin_lock_irqsave(&priv->lock, flags);
786 	if (priv->write_urb_in_use) {
787 		dbg("%s - can't write, urb in use", __FUNCTION__);
788 		spin_unlock_irqrestore(&priv->lock, flags);
789 		return;
790 	}
791 	spin_unlock_irqrestore(&priv->lock, flags);
792 
793 	/* clear buffer */
794 	memset(port->interrupt_out_urb->transfer_buffer, 0, port->interrupt_out_size);
795 
796 	spin_lock_irqsave(&priv->lock, flags);
797 	switch (port->interrupt_out_size) {
798 		case 32:
799 			/* this is for the CY7C64013... */
800 			offset = 2;
801 			port->interrupt_out_buffer[0] = priv->line_control;
802 			break;
803 		case 8:
804 			/* this is for the CY7C63743... */
805 			offset = 1;
806 			port->interrupt_out_buffer[0] = priv->line_control;
807 			break;
808 		default:
809 			dbg("%s - wrong packet size", __FUNCTION__);
810 			spin_unlock_irqrestore(&priv->lock, flags);
811 			return;
812 	}
813 
814 	if (priv->line_control & CONTROL_RESET)
815 		priv->line_control &= ~CONTROL_RESET;
816 
817 	if (priv->cmd_ctrl) {
818 		priv->cmd_count++;
819 		dbg("%s - line control command being issued", __FUNCTION__);
820 		spin_unlock_irqrestore(&priv->lock, flags);
821 		goto send;
822 	} else
823 		spin_unlock_irqrestore(&priv->lock, flags);
824 
825 	count = cypress_buf_get(priv->buf, &port->interrupt_out_buffer[offset],
826 				port->interrupt_out_size-offset);
827 
828 	if (count == 0) {
829 		return;
830 	}
831 
832 	switch (port->interrupt_out_size) {
833 		case 32:
834 			port->interrupt_out_buffer[1] = count;
835 			break;
836 		case 8:
837 			port->interrupt_out_buffer[0] |= count;
838 	}
839 
840 	dbg("%s - count is %d", __FUNCTION__, count);
841 
842 send:
843 	spin_lock_irqsave(&priv->lock, flags);
844 	priv->write_urb_in_use = 1;
845 	spin_unlock_irqrestore(&priv->lock, flags);
846 
847 	if (priv->cmd_ctrl)
848 		actual_size = 1;
849 	else
850 		actual_size = count + (port->interrupt_out_size == 32 ? 2 : 1);
851 
852 	usb_serial_debug_data(debug, &port->dev, __FUNCTION__, port->interrupt_out_size,
853 			      port->interrupt_out_urb->transfer_buffer);
854 
855 	usb_fill_int_urb(port->interrupt_out_urb, port->serial->dev,
856 		usb_sndintpipe(port->serial->dev, port->interrupt_out_endpointAddress),
857 		port->interrupt_out_buffer, port->interrupt_out_size,
858 		cypress_write_int_callback, port, priv->write_urb_interval);
859 	result = usb_submit_urb (port->interrupt_out_urb, GFP_ATOMIC);
860 	if (result) {
861 		dev_err(&port->dev, "%s - failed submitting write urb, error %d\n", __FUNCTION__,
862 			result);
863 		priv->write_urb_in_use = 0;
864 		cypress_set_dead(port);
865 	}
866 
867 	spin_lock_irqsave(&priv->lock, flags);
868 	if (priv->cmd_ctrl) {
869 		priv->cmd_ctrl = 0;
870 	}
871 	priv->bytes_out += count; /* do not count the line control and size bytes */
872 	spin_unlock_irqrestore(&priv->lock, flags);
873 
874 	usb_serial_port_softint(port);
875 } /* cypress_send */
876 
877 
878 /* returns how much space is available in the soft buffer */
879 static int cypress_write_room(struct usb_serial_port *port)
880 {
881 	struct cypress_private *priv = usb_get_serial_port_data(port);
882 	int room = 0;
883 	unsigned long flags;
884 
885 	dbg("%s - port %d", __FUNCTION__, port->number);
886 
887 	spin_lock_irqsave(&priv->lock, flags);
888 	room = cypress_buf_space_avail(priv->buf);
889 	spin_unlock_irqrestore(&priv->lock, flags);
890 
891 	dbg("%s - returns %d", __FUNCTION__, room);
892 	return room;
893 }
894 
895 
896 static int cypress_tiocmget (struct usb_serial_port *port, struct file *file)
897 {
898 	struct cypress_private *priv = usb_get_serial_port_data(port);
899 	__u8 status, control;
900 	unsigned int result = 0;
901 	unsigned long flags;
902 
903 	dbg("%s - port %d", __FUNCTION__, port->number);
904 
905 	spin_lock_irqsave(&priv->lock, flags);
906 	control = priv->line_control;
907 	status = priv->current_status;
908 	spin_unlock_irqrestore(&priv->lock, flags);
909 
910 	result = ((control & CONTROL_DTR)        ? TIOCM_DTR : 0)
911 		| ((control & CONTROL_RTS)       ? TIOCM_RTS : 0)
912 		| ((status & UART_CTS)        ? TIOCM_CTS : 0)
913 		| ((status & UART_DSR)        ? TIOCM_DSR : 0)
914 		| ((status & UART_RI)         ? TIOCM_RI  : 0)
915 		| ((status & UART_CD)         ? TIOCM_CD  : 0);
916 
917 	dbg("%s - result = %x", __FUNCTION__, result);
918 
919 	return result;
920 }
921 
922 
923 static int cypress_tiocmset (struct usb_serial_port *port, struct file *file,
924 			       unsigned int set, unsigned int clear)
925 {
926 	struct cypress_private *priv = usb_get_serial_port_data(port);
927 	unsigned long flags;
928 
929 	dbg("%s - port %d", __FUNCTION__, port->number);
930 
931 	spin_lock_irqsave(&priv->lock, flags);
932 	if (set & TIOCM_RTS)
933 		priv->line_control |= CONTROL_RTS;
934 	if (set & TIOCM_DTR)
935 		priv->line_control |= CONTROL_DTR;
936 	if (clear & TIOCM_RTS)
937 		priv->line_control &= ~CONTROL_RTS;
938 	if (clear & TIOCM_DTR)
939 		priv->line_control &= ~CONTROL_DTR;
940 	spin_unlock_irqrestore(&priv->lock, flags);
941 
942 	priv->cmd_ctrl = 1;
943 	return cypress_write(port, NULL, 0);
944 }
945 
946 
947 static int cypress_ioctl (struct usb_serial_port *port, struct file * file, unsigned int cmd, unsigned long arg)
948 {
949 	struct cypress_private *priv = usb_get_serial_port_data(port);
950 
951 	dbg("%s - port %d, cmd 0x%.4x", __FUNCTION__, port->number, cmd);
952 
953 	switch (cmd) {
954 		case TIOCGSERIAL:
955 			if (copy_to_user((void __user *)arg, port->tty->termios, sizeof(struct ktermios))) {
956 				return -EFAULT;
957 			}
958 			return (0);
959 			break;
960 		case TIOCSSERIAL:
961 			if (copy_from_user(port->tty->termios, (void __user *)arg, sizeof(struct ktermios))) {
962 				return -EFAULT;
963 			}
964 			/* here we need to call cypress_set_termios to invoke the new settings */
965 			cypress_set_termios(port, &priv->tmp_termios);
966 			return (0);
967 			break;
968 		/* This code comes from drivers/char/serial.c and ftdi_sio.c */
969 		case TIOCMIWAIT:
970 			while (priv != NULL) {
971 				interruptible_sleep_on(&priv->delta_msr_wait);
972 				/* see if a signal did it */
973 				if (signal_pending(current))
974 					return -ERESTARTSYS;
975 				else {
976 					char diff = priv->diff_status;
977 
978 					if (diff == 0) {
979 						return -EIO; /* no change => error */
980 					}
981 
982 					/* consume all events */
983 					priv->diff_status = 0;
984 
985 					/* return 0 if caller wanted to know about these bits */
986 					if ( ((arg & TIOCM_RNG) && (diff & UART_RI)) ||
987 					     ((arg & TIOCM_DSR) && (diff & UART_DSR)) ||
988 					     ((arg & TIOCM_CD) && (diff & UART_CD)) ||
989 					     ((arg & TIOCM_CTS) && (diff & UART_CTS)) ) {
990 						return 0;
991 					}
992 					/* otherwise caller can't care less about what happened,
993 					 * and so we continue to wait for more events.
994 					 */
995 				}
996 			}
997 			return 0;
998 			break;
999 		default:
1000 			break;
1001 	}
1002 
1003 	dbg("%s - arg not supported - it was 0x%04x - check include/asm/ioctls.h", __FUNCTION__, cmd);
1004 
1005 	return -ENOIOCTLCMD;
1006 } /* cypress_ioctl */
1007 
1008 
1009 static void cypress_set_termios (struct usb_serial_port *port,
1010 		struct ktermios *old_termios)
1011 {
1012 	struct cypress_private *priv = usb_get_serial_port_data(port);
1013 	struct tty_struct *tty;
1014 	int data_bits, stop_bits, parity_type, parity_enable;
1015 	unsigned cflag, iflag, baud_mask;
1016 	unsigned long flags;
1017 	__u8 oldlines;
1018 	int linechange = 0;
1019 
1020 	dbg("%s - port %d", __FUNCTION__, port->number);
1021 
1022 	tty = port->tty;
1023 	if ((!tty) || (!tty->termios)) {
1024 		dbg("%s - no tty structures", __FUNCTION__);
1025 		return;
1026 	}
1027 
1028 	spin_lock_irqsave(&priv->lock, flags);
1029 	if (!priv->termios_initialized) {
1030 		if (priv->chiptype == CT_EARTHMATE) {
1031 			*(tty->termios) = tty_std_termios;
1032 			tty->termios->c_cflag = B4800 | CS8 | CREAD | HUPCL |
1033 				CLOCAL;
1034 		} else if (priv->chiptype == CT_CYPHIDCOM) {
1035 			*(tty->termios) = tty_std_termios;
1036 			tty->termios->c_cflag = B9600 | CS8 | CREAD | HUPCL |
1037 				CLOCAL;
1038 		} else if (priv->chiptype == CT_CA42V2) {
1039 			*(tty->termios) = tty_std_termios;
1040 			tty->termios->c_cflag = B9600 | CS8 | CREAD | HUPCL |
1041 				CLOCAL;
1042 		}
1043 		priv->termios_initialized = 1;
1044 	}
1045 	spin_unlock_irqrestore(&priv->lock, flags);
1046 
1047 	cflag = tty->termios->c_cflag;
1048 	iflag = tty->termios->c_iflag;
1049 
1050 	/* check if there are new settings */
1051 	if (old_termios) {
1052 		if ((cflag != old_termios->c_cflag) ||
1053 			(RELEVANT_IFLAG(iflag) !=
1054 			 RELEVANT_IFLAG(old_termios->c_iflag))) {
1055 			dbg("%s - attempting to set new termios settings",
1056 					__FUNCTION__);
1057 			/* should make a copy of this in case something goes
1058 			 * wrong in the function, we can restore it */
1059 			spin_lock_irqsave(&priv->lock, flags);
1060 			priv->tmp_termios = *(tty->termios);
1061 			spin_unlock_irqrestore(&priv->lock, flags);
1062 		} else {
1063 			dbg("%s - nothing to do, exiting", __FUNCTION__);
1064 			return;
1065 		}
1066 	} else
1067 		return;
1068 
1069 	/* set number of data bits, parity, stop bits */
1070 	/* when parity is disabled the parity type bit is ignored */
1071 
1072 	/* 1 means 2 stop bits, 0 means 1 stop bit */
1073 	stop_bits = cflag & CSTOPB ? 1 : 0;
1074 
1075 	if (cflag & PARENB) {
1076 		parity_enable = 1;
1077 		/* 1 means odd parity, 0 means even parity */
1078 		parity_type = cflag & PARODD ? 1 : 0;
1079 	} else
1080 		parity_enable = parity_type = 0;
1081 
1082 	if (cflag & CSIZE) {
1083 		switch (cflag & CSIZE) {
1084 			case CS5:
1085 				data_bits = 0;
1086 				break;
1087 			case CS6:
1088 				data_bits = 1;
1089 				break;
1090 			case CS7:
1091 				data_bits = 2;
1092 				break;
1093 			case CS8:
1094 				data_bits = 3;
1095 				break;
1096 			default:
1097 				err("%s - CSIZE was set, but not CS5-CS8",
1098 						__FUNCTION__);
1099 				data_bits = 3;
1100 		}
1101 	} else
1102 		data_bits = 3;
1103 
1104 	spin_lock_irqsave(&priv->lock, flags);
1105 	oldlines = priv->line_control;
1106 	if ((cflag & CBAUD) == B0) {
1107 		/* drop dtr and rts */
1108 		dbg("%s - dropping the lines, baud rate 0bps", __FUNCTION__);
1109 		baud_mask = B0;
1110 		priv->line_control &= ~(CONTROL_DTR | CONTROL_RTS);
1111 	} else {
1112 		baud_mask = (cflag & CBAUD);
1113 		switch(baud_mask) {
1114 			case B300:
1115 				dbg("%s - setting baud 300bps", __FUNCTION__);
1116 				break;
1117 			case B600:
1118 				dbg("%s - setting baud 600bps", __FUNCTION__);
1119 				break;
1120 			case B1200:
1121 				dbg("%s - setting baud 1200bps", __FUNCTION__);
1122 				break;
1123 			case B2400:
1124 				dbg("%s - setting baud 2400bps", __FUNCTION__);
1125 				break;
1126 			case B4800:
1127 				dbg("%s - setting baud 4800bps", __FUNCTION__);
1128 				break;
1129 			case B9600:
1130 				dbg("%s - setting baud 9600bps", __FUNCTION__);
1131 				break;
1132 			case B19200:
1133 				dbg("%s - setting baud 19200bps", __FUNCTION__);
1134 				break;
1135 			case B38400:
1136 				dbg("%s - setting baud 38400bps", __FUNCTION__);
1137 				break;
1138 			case B57600:
1139 				dbg("%s - setting baud 57600bps", __FUNCTION__);
1140 				break;
1141 			case B115200:
1142 				dbg("%s - setting baud 115200bps", __FUNCTION__);
1143 				break;
1144 			default:
1145 				dbg("%s - unknown masked baud rate", __FUNCTION__);
1146 		}
1147 		priv->line_control = (CONTROL_DTR | CONTROL_RTS);
1148 	}
1149 	spin_unlock_irqrestore(&priv->lock, flags);
1150 
1151 	dbg("%s - sending %d stop_bits, %d parity_enable, %d parity_type, "
1152 			"%d data_bits (+5)", __FUNCTION__, stop_bits,
1153 			parity_enable, parity_type, data_bits);
1154 
1155 	cypress_serial_control(port, baud_mask, data_bits, stop_bits,
1156 			parity_enable, parity_type, 0, CYPRESS_SET_CONFIG);
1157 
1158 	/* we perform a CYPRESS_GET_CONFIG so that the current settings are
1159 	 * filled into the private structure this should confirm that all is
1160 	 * working if it returns what we just set */
1161 	cypress_serial_control(port, 0, 0, 0, 0, 0, 0, CYPRESS_GET_CONFIG);
1162 
1163 	/* Here we can define custom tty settings for devices; the main tty
1164 	 * termios flag base comes from empeg.c */
1165 
1166 	spin_lock_irqsave(&priv->lock, flags);
1167 	if ( (priv->chiptype == CT_EARTHMATE) && (priv->baud_rate == 4800) ) {
1168 		dbg("Using custom termios settings for a baud rate of "
1169 				"4800bps.");
1170 		/* define custom termios settings for NMEA protocol */
1171 
1172 		tty->termios->c_iflag /* input modes - */
1173 			&= ~(IGNBRK  /* disable ignore break */
1174 			| BRKINT     /* disable break causes interrupt */
1175 			| PARMRK     /* disable mark parity errors */
1176 			| ISTRIP     /* disable clear high bit of input char */
1177 			| INLCR      /* disable translate NL to CR */
1178 			| IGNCR      /* disable ignore CR */
1179 			| ICRNL      /* disable translate CR to NL */
1180 			| IXON);     /* disable enable XON/XOFF flow control */
1181 
1182 		tty->termios->c_oflag /* output modes */
1183 			&= ~OPOST;    /* disable postprocess output char */
1184 
1185 		tty->termios->c_lflag /* line discipline modes */
1186 			&= ~(ECHO     /* disable echo input characters */
1187 			| ECHONL      /* disable echo new line */
1188 			| ICANON      /* disable erase, kill, werase, and rprnt
1189 					 special characters */
1190 			| ISIG        /* disable interrupt, quit, and suspend
1191 					 special characters */
1192 			| IEXTEN);    /* disable non-POSIX special characters */
1193 	} /* CT_CYPHIDCOM: Application should handle this for device */
1194 
1195 	linechange = (priv->line_control != oldlines);
1196 	spin_unlock_irqrestore(&priv->lock, flags);
1197 
1198 	/* if necessary, set lines */
1199 	if (linechange) {
1200 		priv->cmd_ctrl = 1;
1201 		cypress_write(port, NULL, 0);
1202 	}
1203 } /* cypress_set_termios */
1204 
1205 
1206 /* returns amount of data still left in soft buffer */
1207 static int cypress_chars_in_buffer(struct usb_serial_port *port)
1208 {
1209 	struct cypress_private *priv = usb_get_serial_port_data(port);
1210 	int chars = 0;
1211 	unsigned long flags;
1212 
1213 	dbg("%s - port %d", __FUNCTION__, port->number);
1214 
1215 	spin_lock_irqsave(&priv->lock, flags);
1216 	chars = cypress_buf_data_avail(priv->buf);
1217 	spin_unlock_irqrestore(&priv->lock, flags);
1218 
1219 	dbg("%s - returns %d", __FUNCTION__, chars);
1220 	return chars;
1221 }
1222 
1223 
1224 static void cypress_throttle (struct usb_serial_port *port)
1225 {
1226 	struct cypress_private *priv = usb_get_serial_port_data(port);
1227 	unsigned long flags;
1228 
1229 	dbg("%s - port %d", __FUNCTION__, port->number);
1230 
1231 	spin_lock_irqsave(&priv->lock, flags);
1232 	priv->rx_flags = THROTTLED;
1233 	spin_unlock_irqrestore(&priv->lock, flags);
1234 }
1235 
1236 
1237 static void cypress_unthrottle (struct usb_serial_port *port)
1238 {
1239 	struct cypress_private *priv = usb_get_serial_port_data(port);
1240 	int actually_throttled, result;
1241 	unsigned long flags;
1242 
1243 	dbg("%s - port %d", __FUNCTION__, port->number);
1244 
1245 	spin_lock_irqsave(&priv->lock, flags);
1246 	actually_throttled = priv->rx_flags & ACTUALLY_THROTTLED;
1247 	priv->rx_flags = 0;
1248 	spin_unlock_irqrestore(&priv->lock, flags);
1249 
1250 	if (!priv->comm_is_ok)
1251 		return;
1252 
1253 	if (actually_throttled) {
1254 		port->interrupt_in_urb->dev = port->serial->dev;
1255 
1256 		result = usb_submit_urb(port->interrupt_in_urb, GFP_ATOMIC);
1257 		if (result) {
1258 			dev_err(&port->dev, "%s - failed submitting read urb, "
1259 					"error %d\n", __FUNCTION__, result);
1260 			cypress_set_dead(port);
1261 		}
1262 	}
1263 }
1264 
1265 
1266 static void cypress_read_int_callback(struct urb *urb)
1267 {
1268 	struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
1269 	struct cypress_private *priv = usb_get_serial_port_data(port);
1270 	struct tty_struct *tty;
1271 	unsigned char *data = urb->transfer_buffer;
1272 	unsigned long flags;
1273 	char tty_flag = TTY_NORMAL;
1274 	int havedata = 0;
1275 	int bytes = 0;
1276 	int result;
1277 	int i = 0;
1278 	int status = urb->status;
1279 
1280 	dbg("%s - port %d", __FUNCTION__, port->number);
1281 
1282 	switch (status) {
1283 	case 0: /* success */
1284 		break;
1285 	case -ECONNRESET:
1286 	case -ENOENT:
1287 	case -ESHUTDOWN:
1288 		/* precursor to disconnect so just go away */
1289 		return;
1290 	case -EPIPE:
1291 		usb_clear_halt(port->serial->dev,0x81);
1292 		break;
1293 	default:
1294 		/* something ugly is going on... */
1295 		dev_err(&urb->dev->dev,"%s - unexpected nonzero read status received: %d\n",
1296 			__FUNCTION__, status);
1297 		cypress_set_dead(port);
1298 		return;
1299 	}
1300 
1301 	spin_lock_irqsave(&priv->lock, flags);
1302 	if (priv->rx_flags & THROTTLED) {
1303 		dbg("%s - now throttling", __FUNCTION__);
1304 		priv->rx_flags |= ACTUALLY_THROTTLED;
1305 		spin_unlock_irqrestore(&priv->lock, flags);
1306 		return;
1307 	}
1308 	spin_unlock_irqrestore(&priv->lock, flags);
1309 
1310 	tty = port->tty;
1311 	if (!tty) {
1312 		dbg("%s - bad tty pointer - exiting", __FUNCTION__);
1313 		return;
1314 	}
1315 
1316 	spin_lock_irqsave(&priv->lock, flags);
1317 	switch(urb->actual_length) {
1318 		case 32:
1319 			/* This is for the CY7C64013... */
1320 			priv->current_status = data[0] & 0xF8;
1321 			bytes = data[1] + 2;
1322 			i = 2;
1323 			if (bytes > 2)
1324 				havedata = 1;
1325 			break;
1326 		case 8:
1327 			/* This is for the CY7C63743... */
1328 			priv->current_status = data[0] & 0xF8;
1329 			bytes = (data[0] & 0x07) + 1;
1330 			i = 1;
1331 			if (bytes > 1)
1332 				havedata = 1;
1333 			break;
1334 		default:
1335 			dbg("%s - wrong packet size - received %d bytes",
1336 					__FUNCTION__, urb->actual_length);
1337 			spin_unlock_irqrestore(&priv->lock, flags);
1338 			goto continue_read;
1339 	}
1340 	spin_unlock_irqrestore(&priv->lock, flags);
1341 
1342 	usb_serial_debug_data (debug, &port->dev, __FUNCTION__,
1343 			urb->actual_length, data);
1344 
1345 	spin_lock_irqsave(&priv->lock, flags);
1346 	/* check to see if status has changed */
1347 	if (priv != NULL) {
1348 		if (priv->current_status != priv->prev_status) {
1349 			priv->diff_status |= priv->current_status ^
1350 				priv->prev_status;
1351 			wake_up_interruptible(&priv->delta_msr_wait);
1352 			priv->prev_status = priv->current_status;
1353 		}
1354 	}
1355 	spin_unlock_irqrestore(&priv->lock, flags);
1356 
1357 	/* hangup, as defined in acm.c... this might be a bad place for it
1358 	 * though */
1359 	if (tty && !(tty->termios->c_cflag & CLOCAL) &&
1360 			!(priv->current_status & UART_CD)) {
1361 		dbg("%s - calling hangup", __FUNCTION__);
1362 		tty_hangup(tty);
1363 		goto continue_read;
1364 	}
1365 
1366 	/* There is one error bit... I'm assuming it is a parity error
1367 	 * indicator as the generic firmware will set this bit to 1 if a
1368 	 * parity error occurs.
1369 	 * I can not find reference to any other error events. */
1370 	spin_lock_irqsave(&priv->lock, flags);
1371 	if (priv->current_status & CYP_ERROR) {
1372 		spin_unlock_irqrestore(&priv->lock, flags);
1373 		tty_flag = TTY_PARITY;
1374 		dbg("%s - Parity Error detected", __FUNCTION__);
1375 	} else
1376 		spin_unlock_irqrestore(&priv->lock, flags);
1377 
1378 	/* process read if there is data other than line status */
1379 	if (tty && (bytes > i)) {
1380 		bytes = tty_buffer_request_room(tty, bytes);
1381 		for (; i < bytes ; ++i) {
1382 			dbg("pushing byte number %d - %d - %c", i, data[i],
1383 					data[i]);
1384 			tty_insert_flip_char(tty, data[i], tty_flag);
1385 		}
1386 		tty_flip_buffer_push(port->tty);
1387 	}
1388 
1389 	spin_lock_irqsave(&priv->lock, flags);
1390 	/* control and status byte(s) are also counted */
1391 	priv->bytes_in += bytes;
1392 	spin_unlock_irqrestore(&priv->lock, flags);
1393 
1394 continue_read:
1395 
1396 	/* Continue trying to always read... unless the port has closed. */
1397 
1398 	if (port->open_count > 0 && priv->comm_is_ok) {
1399 		usb_fill_int_urb(port->interrupt_in_urb, port->serial->dev,
1400 				usb_rcvintpipe(port->serial->dev,
1401 					port->interrupt_in_endpointAddress),
1402 				port->interrupt_in_urb->transfer_buffer,
1403 				port->interrupt_in_urb->transfer_buffer_length,
1404 				cypress_read_int_callback, port, priv->read_urb_interval);
1405 		result = usb_submit_urb(port->interrupt_in_urb, GFP_ATOMIC);
1406 		if (result) {
1407 			dev_err(&urb->dev->dev, "%s - failed resubmitting "
1408 					"read urb, error %d\n", __FUNCTION__,
1409 					result);
1410 			cypress_set_dead(port);
1411 		}
1412 	}
1413 
1414 	return;
1415 } /* cypress_read_int_callback */
1416 
1417 
1418 static void cypress_write_int_callback(struct urb *urb)
1419 {
1420 	struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
1421 	struct cypress_private *priv = usb_get_serial_port_data(port);
1422 	int result;
1423 	int status = urb->status;
1424 
1425 	dbg("%s - port %d", __FUNCTION__, port->number);
1426 
1427 	switch (status) {
1428 		case 0:
1429 			/* success */
1430 			break;
1431 		case -ECONNRESET:
1432 		case -ENOENT:
1433 		case -ESHUTDOWN:
1434 			/* this urb is terminated, clean up */
1435 			dbg("%s - urb shutting down with status: %d",
1436 			    __FUNCTION__, status);
1437 			priv->write_urb_in_use = 0;
1438 			return;
1439 		case -EPIPE: /* no break needed; clear halt and resubmit */
1440 			if (!priv->comm_is_ok)
1441 				break;
1442 			usb_clear_halt(port->serial->dev, 0x02);
1443 			/* error in the urb, so we have to resubmit it */
1444 			dbg("%s - nonzero write bulk status received: %d",
1445 			    __FUNCTION__, status);
1446 			port->interrupt_out_urb->transfer_buffer_length = 1;
1447 			port->interrupt_out_urb->dev = port->serial->dev;
1448 			result = usb_submit_urb(port->interrupt_out_urb, GFP_ATOMIC);
1449 			if (!result)
1450 				return;
1451 			dev_err(&urb->dev->dev, "%s - failed resubmitting write urb, error %d\n",
1452 				__FUNCTION__, result);
1453 			cypress_set_dead(port);
1454 			break;
1455 		default:
1456 			dev_err(&urb->dev->dev,"%s - unexpected nonzero write status received: %d\n",
1457 				__FUNCTION__, status);
1458 			cypress_set_dead(port);
1459 			break;
1460 	}
1461 
1462 	priv->write_urb_in_use = 0;
1463 
1464 	/* send any buffered data */
1465 	cypress_send(port);
1466 }
1467 
1468 
1469 /*****************************************************************************
1470  * Write buffer functions - buffering code from pl2303 used
1471  *****************************************************************************/
1472 
1473 /*
1474  * cypress_buf_alloc
1475  *
1476  * Allocate a circular buffer and all associated memory.
1477  */
1478 
1479 static struct cypress_buf *cypress_buf_alloc(unsigned int size)
1480 {
1481 
1482 	struct cypress_buf *cb;
1483 
1484 
1485 	if (size == 0)
1486 		return NULL;
1487 
1488 	cb = kmalloc(sizeof(struct cypress_buf), GFP_KERNEL);
1489 	if (cb == NULL)
1490 		return NULL;
1491 
1492 	cb->buf_buf = kmalloc(size, GFP_KERNEL);
1493 	if (cb->buf_buf == NULL) {
1494 		kfree(cb);
1495 		return NULL;
1496 	}
1497 
1498 	cb->buf_size = size;
1499 	cb->buf_get = cb->buf_put = cb->buf_buf;
1500 
1501 	return cb;
1502 
1503 }
1504 
1505 
1506 /*
1507  * cypress_buf_free
1508  *
1509  * Free the buffer and all associated memory.
1510  */
1511 
1512 static void cypress_buf_free(struct cypress_buf *cb)
1513 {
1514 	if (cb) {
1515 		kfree(cb->buf_buf);
1516 		kfree(cb);
1517 	}
1518 }
1519 
1520 
1521 /*
1522  * cypress_buf_clear
1523  *
1524  * Clear out all data in the circular buffer.
1525  */
1526 
1527 static void cypress_buf_clear(struct cypress_buf *cb)
1528 {
1529 	if (cb != NULL)
1530 		cb->buf_get = cb->buf_put;
1531 		/* equivalent to a get of all data available */
1532 }
1533 
1534 
1535 /*
1536  * cypress_buf_data_avail
1537  *
1538  * Return the number of bytes of data available in the circular
1539  * buffer.
1540  */
1541 
1542 static unsigned int cypress_buf_data_avail(struct cypress_buf *cb)
1543 {
1544 	if (cb != NULL)
1545 		return ((cb->buf_size + cb->buf_put - cb->buf_get) % cb->buf_size);
1546 	else
1547 		return 0;
1548 }
1549 
1550 
1551 /*
1552  * cypress_buf_space_avail
1553  *
1554  * Return the number of bytes of space available in the circular
1555  * buffer.
1556  */
1557 
1558 static unsigned int cypress_buf_space_avail(struct cypress_buf *cb)
1559 {
1560 	if (cb != NULL)
1561 		return ((cb->buf_size + cb->buf_get - cb->buf_put - 1) % cb->buf_size);
1562 	else
1563 		return 0;
1564 }
1565 
1566 
1567 /*
1568  * cypress_buf_put
1569  *
1570  * Copy data data from a user buffer and put it into the circular buffer.
1571  * Restrict to the amount of space available.
1572  *
1573  * Return the number of bytes copied.
1574  */
1575 
1576 static unsigned int cypress_buf_put(struct cypress_buf *cb, const char *buf,
1577 	unsigned int count)
1578 {
1579 
1580 	unsigned int len;
1581 
1582 
1583 	if (cb == NULL)
1584 		return 0;
1585 
1586 	len  = cypress_buf_space_avail(cb);
1587 	if (count > len)
1588 		count = len;
1589 
1590 	if (count == 0)
1591 		return 0;
1592 
1593 	len = cb->buf_buf + cb->buf_size - cb->buf_put;
1594 	if (count > len) {
1595 		memcpy(cb->buf_put, buf, len);
1596 		memcpy(cb->buf_buf, buf+len, count - len);
1597 		cb->buf_put = cb->buf_buf + count - len;
1598 	} else {
1599 		memcpy(cb->buf_put, buf, count);
1600 		if (count < len)
1601 			cb->buf_put += count;
1602 		else /* count == len */
1603 			cb->buf_put = cb->buf_buf;
1604 	}
1605 
1606 	return count;
1607 
1608 }
1609 
1610 
1611 /*
1612  * cypress_buf_get
1613  *
1614  * Get data from the circular buffer and copy to the given buffer.
1615  * Restrict to the amount of data available.
1616  *
1617  * Return the number of bytes copied.
1618  */
1619 
1620 static unsigned int cypress_buf_get(struct cypress_buf *cb, char *buf,
1621 	unsigned int count)
1622 {
1623 
1624 	unsigned int len;
1625 
1626 
1627 	if (cb == NULL)
1628 		return 0;
1629 
1630 	len = cypress_buf_data_avail(cb);
1631 	if (count > len)
1632 		count = len;
1633 
1634 	if (count == 0)
1635 		return 0;
1636 
1637 	len = cb->buf_buf + cb->buf_size - cb->buf_get;
1638 	if (count > len) {
1639 		memcpy(buf, cb->buf_get, len);
1640 		memcpy(buf+len, cb->buf_buf, count - len);
1641 		cb->buf_get = cb->buf_buf + count - len;
1642 	} else {
1643 		memcpy(buf, cb->buf_get, count);
1644 		if (count < len)
1645 			cb->buf_get += count;
1646 		else /* count == len */
1647 			cb->buf_get = cb->buf_buf;
1648 	}
1649 
1650 	return count;
1651 
1652 }
1653 
1654 /*****************************************************************************
1655  * Module functions
1656  *****************************************************************************/
1657 
1658 static int __init cypress_init(void)
1659 {
1660 	int retval;
1661 
1662 	dbg("%s", __FUNCTION__);
1663 
1664 	retval = usb_serial_register(&cypress_earthmate_device);
1665 	if (retval)
1666 		goto failed_em_register;
1667 	retval = usb_serial_register(&cypress_hidcom_device);
1668 	if (retval)
1669 		goto failed_hidcom_register;
1670 	retval = usb_serial_register(&cypress_ca42v2_device);
1671 	if (retval)
1672 		goto failed_ca42v2_register;
1673 	retval = usb_register(&cypress_driver);
1674 	if (retval)
1675 		goto failed_usb_register;
1676 
1677 	info(DRIVER_DESC " " DRIVER_VERSION);
1678 	return 0;
1679 
1680 failed_usb_register:
1681 	usb_serial_deregister(&cypress_ca42v2_device);
1682 failed_ca42v2_register:
1683 	usb_serial_deregister(&cypress_hidcom_device);
1684 failed_hidcom_register:
1685 	usb_serial_deregister(&cypress_earthmate_device);
1686 failed_em_register:
1687 	return retval;
1688 }
1689 
1690 
1691 static void __exit cypress_exit (void)
1692 {
1693 	dbg("%s", __FUNCTION__);
1694 
1695 	usb_deregister (&cypress_driver);
1696 	usb_serial_deregister (&cypress_earthmate_device);
1697 	usb_serial_deregister (&cypress_hidcom_device);
1698 	usb_serial_deregister (&cypress_ca42v2_device);
1699 }
1700 
1701 
1702 module_init(cypress_init);
1703 module_exit(cypress_exit);
1704 
1705 MODULE_AUTHOR( DRIVER_AUTHOR );
1706 MODULE_DESCRIPTION( DRIVER_DESC );
1707 MODULE_VERSION( DRIVER_VERSION );
1708 MODULE_LICENSE("GPL");
1709 
1710 module_param(debug, bool, S_IRUGO | S_IWUSR);
1711 MODULE_PARM_DESC(debug, "Debug enabled or not");
1712 module_param(stats, bool, S_IRUGO | S_IWUSR);
1713 MODULE_PARM_DESC(stats, "Enable statistics or not");
1714 module_param(interval, int, S_IRUGO | S_IWUSR);
1715 MODULE_PARM_DESC(interval, "Overrides interrupt interval");
1716