xref: /OK3568_Linux_fs/kernel/drivers/usb/serial/digi_acceleport.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0+
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun *  Digi AccelePort USB-4 and USB-2 Serial Converters
4*4882a593Smuzhiyun *
5*4882a593Smuzhiyun *  Copyright 2000 by Digi International
6*4882a593Smuzhiyun *
7*4882a593Smuzhiyun *  Shamelessly based on Brian Warner's keyspan_pda.c and Greg Kroah-Hartman's
8*4882a593Smuzhiyun *  usb-serial driver.
9*4882a593Smuzhiyun *
10*4882a593Smuzhiyun *  Peter Berger (pberger@brimson.com)
11*4882a593Smuzhiyun *  Al Borchers (borchers@steinerpoint.com)
12*4882a593Smuzhiyun */
13*4882a593Smuzhiyun 
14*4882a593Smuzhiyun #include <linux/kernel.h>
15*4882a593Smuzhiyun #include <linux/errno.h>
16*4882a593Smuzhiyun #include <linux/slab.h>
17*4882a593Smuzhiyun #include <linux/tty.h>
18*4882a593Smuzhiyun #include <linux/tty_driver.h>
19*4882a593Smuzhiyun #include <linux/tty_flip.h>
20*4882a593Smuzhiyun #include <linux/module.h>
21*4882a593Smuzhiyun #include <linux/spinlock.h>
22*4882a593Smuzhiyun #include <linux/uaccess.h>
23*4882a593Smuzhiyun #include <linux/usb.h>
24*4882a593Smuzhiyun #include <linux/wait.h>
25*4882a593Smuzhiyun #include <linux/sched/signal.h>
26*4882a593Smuzhiyun #include <linux/usb/serial.h>
27*4882a593Smuzhiyun 
28*4882a593Smuzhiyun /* Defines */
29*4882a593Smuzhiyun 
30*4882a593Smuzhiyun #define DRIVER_AUTHOR "Peter Berger <pberger@brimson.com>, Al Borchers <borchers@steinerpoint.com>"
31*4882a593Smuzhiyun #define DRIVER_DESC "Digi AccelePort USB-2/USB-4 Serial Converter driver"
32*4882a593Smuzhiyun 
33*4882a593Smuzhiyun /* port output buffer length -- must be <= transfer buffer length - 2 */
34*4882a593Smuzhiyun /* so we can be sure to send the full buffer in one urb */
35*4882a593Smuzhiyun #define DIGI_OUT_BUF_SIZE		8
36*4882a593Smuzhiyun 
37*4882a593Smuzhiyun /* port input buffer length -- must be >= transfer buffer length - 3 */
38*4882a593Smuzhiyun /* so we can be sure to hold at least one full buffer from one urb */
39*4882a593Smuzhiyun #define DIGI_IN_BUF_SIZE		64
40*4882a593Smuzhiyun 
41*4882a593Smuzhiyun /* retry timeout while sleeping */
42*4882a593Smuzhiyun #define DIGI_RETRY_TIMEOUT		(HZ/10)
43*4882a593Smuzhiyun 
44*4882a593Smuzhiyun /* timeout while waiting for tty output to drain in close */
45*4882a593Smuzhiyun /* this delay is used twice in close, so the total delay could */
46*4882a593Smuzhiyun /* be twice this value */
47*4882a593Smuzhiyun #define DIGI_CLOSE_TIMEOUT		(5*HZ)
48*4882a593Smuzhiyun 
49*4882a593Smuzhiyun 
50*4882a593Smuzhiyun /* AccelePort USB Defines */
51*4882a593Smuzhiyun 
52*4882a593Smuzhiyun /* ids */
53*4882a593Smuzhiyun #define DIGI_VENDOR_ID			0x05c5
54*4882a593Smuzhiyun #define DIGI_2_ID			0x0002	/* USB-2 */
55*4882a593Smuzhiyun #define DIGI_4_ID			0x0004	/* USB-4 */
56*4882a593Smuzhiyun 
57*4882a593Smuzhiyun /* commands
58*4882a593Smuzhiyun  * "INB": can be used on the in-band endpoint
59*4882a593Smuzhiyun  * "OOB": can be used on the out-of-band endpoint
60*4882a593Smuzhiyun  */
61*4882a593Smuzhiyun #define DIGI_CMD_SET_BAUD_RATE			0	/* INB, OOB */
62*4882a593Smuzhiyun #define DIGI_CMD_SET_WORD_SIZE			1	/* INB, OOB */
63*4882a593Smuzhiyun #define DIGI_CMD_SET_PARITY			2	/* INB, OOB */
64*4882a593Smuzhiyun #define DIGI_CMD_SET_STOP_BITS			3	/* INB, OOB */
65*4882a593Smuzhiyun #define DIGI_CMD_SET_INPUT_FLOW_CONTROL		4	/* INB, OOB */
66*4882a593Smuzhiyun #define DIGI_CMD_SET_OUTPUT_FLOW_CONTROL	5	/* INB, OOB */
67*4882a593Smuzhiyun #define DIGI_CMD_SET_DTR_SIGNAL			6	/* INB, OOB */
68*4882a593Smuzhiyun #define DIGI_CMD_SET_RTS_SIGNAL			7	/* INB, OOB */
69*4882a593Smuzhiyun #define DIGI_CMD_READ_INPUT_SIGNALS		8	/*      OOB */
70*4882a593Smuzhiyun #define DIGI_CMD_IFLUSH_FIFO			9	/*      OOB */
71*4882a593Smuzhiyun #define DIGI_CMD_RECEIVE_ENABLE			10	/* INB, OOB */
72*4882a593Smuzhiyun #define DIGI_CMD_BREAK_CONTROL			11	/* INB, OOB */
73*4882a593Smuzhiyun #define DIGI_CMD_LOCAL_LOOPBACK			12	/* INB, OOB */
74*4882a593Smuzhiyun #define DIGI_CMD_TRANSMIT_IDLE			13	/* INB, OOB */
75*4882a593Smuzhiyun #define DIGI_CMD_READ_UART_REGISTER		14	/*      OOB */
76*4882a593Smuzhiyun #define DIGI_CMD_WRITE_UART_REGISTER		15	/* INB, OOB */
77*4882a593Smuzhiyun #define DIGI_CMD_AND_UART_REGISTER		16	/* INB, OOB */
78*4882a593Smuzhiyun #define DIGI_CMD_OR_UART_REGISTER		17	/* INB, OOB */
79*4882a593Smuzhiyun #define DIGI_CMD_SEND_DATA			18	/* INB      */
80*4882a593Smuzhiyun #define DIGI_CMD_RECEIVE_DATA			19	/* INB      */
81*4882a593Smuzhiyun #define DIGI_CMD_RECEIVE_DISABLE		20	/* INB      */
82*4882a593Smuzhiyun #define DIGI_CMD_GET_PORT_TYPE			21	/*      OOB */
83*4882a593Smuzhiyun 
84*4882a593Smuzhiyun /* baud rates */
85*4882a593Smuzhiyun #define DIGI_BAUD_50				0
86*4882a593Smuzhiyun #define DIGI_BAUD_75				1
87*4882a593Smuzhiyun #define DIGI_BAUD_110				2
88*4882a593Smuzhiyun #define DIGI_BAUD_150				3
89*4882a593Smuzhiyun #define DIGI_BAUD_200				4
90*4882a593Smuzhiyun #define DIGI_BAUD_300				5
91*4882a593Smuzhiyun #define DIGI_BAUD_600				6
92*4882a593Smuzhiyun #define DIGI_BAUD_1200				7
93*4882a593Smuzhiyun #define DIGI_BAUD_1800				8
94*4882a593Smuzhiyun #define DIGI_BAUD_2400				9
95*4882a593Smuzhiyun #define DIGI_BAUD_4800				10
96*4882a593Smuzhiyun #define DIGI_BAUD_7200				11
97*4882a593Smuzhiyun #define DIGI_BAUD_9600				12
98*4882a593Smuzhiyun #define DIGI_BAUD_14400				13
99*4882a593Smuzhiyun #define DIGI_BAUD_19200				14
100*4882a593Smuzhiyun #define DIGI_BAUD_28800				15
101*4882a593Smuzhiyun #define DIGI_BAUD_38400				16
102*4882a593Smuzhiyun #define DIGI_BAUD_57600				17
103*4882a593Smuzhiyun #define DIGI_BAUD_76800				18
104*4882a593Smuzhiyun #define DIGI_BAUD_115200			19
105*4882a593Smuzhiyun #define DIGI_BAUD_153600			20
106*4882a593Smuzhiyun #define DIGI_BAUD_230400			21
107*4882a593Smuzhiyun #define DIGI_BAUD_460800			22
108*4882a593Smuzhiyun 
109*4882a593Smuzhiyun /* arguments */
110*4882a593Smuzhiyun #define DIGI_WORD_SIZE_5			0
111*4882a593Smuzhiyun #define DIGI_WORD_SIZE_6			1
112*4882a593Smuzhiyun #define DIGI_WORD_SIZE_7			2
113*4882a593Smuzhiyun #define DIGI_WORD_SIZE_8			3
114*4882a593Smuzhiyun 
115*4882a593Smuzhiyun #define DIGI_PARITY_NONE			0
116*4882a593Smuzhiyun #define DIGI_PARITY_ODD				1
117*4882a593Smuzhiyun #define DIGI_PARITY_EVEN			2
118*4882a593Smuzhiyun #define DIGI_PARITY_MARK			3
119*4882a593Smuzhiyun #define DIGI_PARITY_SPACE			4
120*4882a593Smuzhiyun 
121*4882a593Smuzhiyun #define DIGI_STOP_BITS_1			0
122*4882a593Smuzhiyun #define DIGI_STOP_BITS_2			1
123*4882a593Smuzhiyun 
124*4882a593Smuzhiyun #define DIGI_INPUT_FLOW_CONTROL_XON_XOFF	1
125*4882a593Smuzhiyun #define DIGI_INPUT_FLOW_CONTROL_RTS		2
126*4882a593Smuzhiyun #define DIGI_INPUT_FLOW_CONTROL_DTR		4
127*4882a593Smuzhiyun 
128*4882a593Smuzhiyun #define DIGI_OUTPUT_FLOW_CONTROL_XON_XOFF	1
129*4882a593Smuzhiyun #define DIGI_OUTPUT_FLOW_CONTROL_CTS		2
130*4882a593Smuzhiyun #define DIGI_OUTPUT_FLOW_CONTROL_DSR		4
131*4882a593Smuzhiyun 
132*4882a593Smuzhiyun #define DIGI_DTR_INACTIVE			0
133*4882a593Smuzhiyun #define DIGI_DTR_ACTIVE				1
134*4882a593Smuzhiyun #define DIGI_DTR_INPUT_FLOW_CONTROL		2
135*4882a593Smuzhiyun 
136*4882a593Smuzhiyun #define DIGI_RTS_INACTIVE			0
137*4882a593Smuzhiyun #define DIGI_RTS_ACTIVE				1
138*4882a593Smuzhiyun #define DIGI_RTS_INPUT_FLOW_CONTROL		2
139*4882a593Smuzhiyun #define DIGI_RTS_TOGGLE				3
140*4882a593Smuzhiyun 
141*4882a593Smuzhiyun #define DIGI_FLUSH_TX				1
142*4882a593Smuzhiyun #define DIGI_FLUSH_RX				2
143*4882a593Smuzhiyun #define DIGI_RESUME_TX				4 /* clears xoff condition */
144*4882a593Smuzhiyun 
145*4882a593Smuzhiyun #define DIGI_TRANSMIT_NOT_IDLE			0
146*4882a593Smuzhiyun #define DIGI_TRANSMIT_IDLE			1
147*4882a593Smuzhiyun 
148*4882a593Smuzhiyun #define DIGI_DISABLE				0
149*4882a593Smuzhiyun #define DIGI_ENABLE				1
150*4882a593Smuzhiyun 
151*4882a593Smuzhiyun #define DIGI_DEASSERT				0
152*4882a593Smuzhiyun #define DIGI_ASSERT				1
153*4882a593Smuzhiyun 
154*4882a593Smuzhiyun /* in band status codes */
155*4882a593Smuzhiyun #define DIGI_OVERRUN_ERROR			4
156*4882a593Smuzhiyun #define DIGI_PARITY_ERROR			8
157*4882a593Smuzhiyun #define DIGI_FRAMING_ERROR			16
158*4882a593Smuzhiyun #define DIGI_BREAK_ERROR			32
159*4882a593Smuzhiyun 
160*4882a593Smuzhiyun /* out of band status */
161*4882a593Smuzhiyun #define DIGI_NO_ERROR				0
162*4882a593Smuzhiyun #define DIGI_BAD_FIRST_PARAMETER		1
163*4882a593Smuzhiyun #define DIGI_BAD_SECOND_PARAMETER		2
164*4882a593Smuzhiyun #define DIGI_INVALID_LINE			3
165*4882a593Smuzhiyun #define DIGI_INVALID_OPCODE			4
166*4882a593Smuzhiyun 
167*4882a593Smuzhiyun /* input signals */
168*4882a593Smuzhiyun #define DIGI_READ_INPUT_SIGNALS_SLOT		1
169*4882a593Smuzhiyun #define DIGI_READ_INPUT_SIGNALS_ERR		2
170*4882a593Smuzhiyun #define DIGI_READ_INPUT_SIGNALS_BUSY		4
171*4882a593Smuzhiyun #define DIGI_READ_INPUT_SIGNALS_PE		8
172*4882a593Smuzhiyun #define DIGI_READ_INPUT_SIGNALS_CTS		16
173*4882a593Smuzhiyun #define DIGI_READ_INPUT_SIGNALS_DSR		32
174*4882a593Smuzhiyun #define DIGI_READ_INPUT_SIGNALS_RI		64
175*4882a593Smuzhiyun #define DIGI_READ_INPUT_SIGNALS_DCD		128
176*4882a593Smuzhiyun 
177*4882a593Smuzhiyun 
178*4882a593Smuzhiyun /* Structures */
179*4882a593Smuzhiyun 
180*4882a593Smuzhiyun struct digi_serial {
181*4882a593Smuzhiyun 	spinlock_t ds_serial_lock;
182*4882a593Smuzhiyun 	struct usb_serial_port *ds_oob_port;	/* out-of-band port */
183*4882a593Smuzhiyun 	int ds_oob_port_num;			/* index of out-of-band port */
184*4882a593Smuzhiyun 	int ds_device_started;
185*4882a593Smuzhiyun };
186*4882a593Smuzhiyun 
187*4882a593Smuzhiyun struct digi_port {
188*4882a593Smuzhiyun 	spinlock_t dp_port_lock;
189*4882a593Smuzhiyun 	int dp_port_num;
190*4882a593Smuzhiyun 	int dp_out_buf_len;
191*4882a593Smuzhiyun 	unsigned char dp_out_buf[DIGI_OUT_BUF_SIZE];
192*4882a593Smuzhiyun 	int dp_write_urb_in_use;
193*4882a593Smuzhiyun 	unsigned int dp_modem_signals;
194*4882a593Smuzhiyun 	int dp_transmit_idle;
195*4882a593Smuzhiyun 	wait_queue_head_t dp_transmit_idle_wait;
196*4882a593Smuzhiyun 	int dp_throttled;
197*4882a593Smuzhiyun 	int dp_throttle_restart;
198*4882a593Smuzhiyun 	wait_queue_head_t dp_flush_wait;
199*4882a593Smuzhiyun 	wait_queue_head_t dp_close_wait;	/* wait queue for close */
200*4882a593Smuzhiyun 	struct usb_serial_port *dp_port;
201*4882a593Smuzhiyun };
202*4882a593Smuzhiyun 
203*4882a593Smuzhiyun 
204*4882a593Smuzhiyun /* Local Function Declarations */
205*4882a593Smuzhiyun 
206*4882a593Smuzhiyun static int digi_write_oob_command(struct usb_serial_port *port,
207*4882a593Smuzhiyun 	unsigned char *buf, int count, int interruptible);
208*4882a593Smuzhiyun static int digi_write_inb_command(struct usb_serial_port *port,
209*4882a593Smuzhiyun 	unsigned char *buf, int count, unsigned long timeout);
210*4882a593Smuzhiyun static int digi_set_modem_signals(struct usb_serial_port *port,
211*4882a593Smuzhiyun 	unsigned int modem_signals, int interruptible);
212*4882a593Smuzhiyun static int digi_transmit_idle(struct usb_serial_port *port,
213*4882a593Smuzhiyun 	unsigned long timeout);
214*4882a593Smuzhiyun static void digi_rx_throttle(struct tty_struct *tty);
215*4882a593Smuzhiyun static void digi_rx_unthrottle(struct tty_struct *tty);
216*4882a593Smuzhiyun static void digi_set_termios(struct tty_struct *tty,
217*4882a593Smuzhiyun 		struct usb_serial_port *port, struct ktermios *old_termios);
218*4882a593Smuzhiyun static void digi_break_ctl(struct tty_struct *tty, int break_state);
219*4882a593Smuzhiyun static int digi_tiocmget(struct tty_struct *tty);
220*4882a593Smuzhiyun static int digi_tiocmset(struct tty_struct *tty, unsigned int set,
221*4882a593Smuzhiyun 		unsigned int clear);
222*4882a593Smuzhiyun static int digi_write(struct tty_struct *tty, struct usb_serial_port *port,
223*4882a593Smuzhiyun 		const unsigned char *buf, int count);
224*4882a593Smuzhiyun static void digi_write_bulk_callback(struct urb *urb);
225*4882a593Smuzhiyun static int digi_write_room(struct tty_struct *tty);
226*4882a593Smuzhiyun static int digi_chars_in_buffer(struct tty_struct *tty);
227*4882a593Smuzhiyun static int digi_open(struct tty_struct *tty, struct usb_serial_port *port);
228*4882a593Smuzhiyun static void digi_close(struct usb_serial_port *port);
229*4882a593Smuzhiyun static void digi_dtr_rts(struct usb_serial_port *port, int on);
230*4882a593Smuzhiyun static int digi_startup_device(struct usb_serial *serial);
231*4882a593Smuzhiyun static int digi_startup(struct usb_serial *serial);
232*4882a593Smuzhiyun static void digi_disconnect(struct usb_serial *serial);
233*4882a593Smuzhiyun static void digi_release(struct usb_serial *serial);
234*4882a593Smuzhiyun static int digi_port_probe(struct usb_serial_port *port);
235*4882a593Smuzhiyun static int digi_port_remove(struct usb_serial_port *port);
236*4882a593Smuzhiyun static void digi_read_bulk_callback(struct urb *urb);
237*4882a593Smuzhiyun static int digi_read_inb_callback(struct urb *urb);
238*4882a593Smuzhiyun static int digi_read_oob_callback(struct urb *urb);
239*4882a593Smuzhiyun 
240*4882a593Smuzhiyun 
241*4882a593Smuzhiyun static const struct usb_device_id id_table_combined[] = {
242*4882a593Smuzhiyun 	{ USB_DEVICE(DIGI_VENDOR_ID, DIGI_2_ID) },
243*4882a593Smuzhiyun 	{ USB_DEVICE(DIGI_VENDOR_ID, DIGI_4_ID) },
244*4882a593Smuzhiyun 	{ }						/* Terminating entry */
245*4882a593Smuzhiyun };
246*4882a593Smuzhiyun 
247*4882a593Smuzhiyun static const struct usb_device_id id_table_2[] = {
248*4882a593Smuzhiyun 	{ USB_DEVICE(DIGI_VENDOR_ID, DIGI_2_ID) },
249*4882a593Smuzhiyun 	{ }						/* Terminating entry */
250*4882a593Smuzhiyun };
251*4882a593Smuzhiyun 
252*4882a593Smuzhiyun static const struct usb_device_id id_table_4[] = {
253*4882a593Smuzhiyun 	{ USB_DEVICE(DIGI_VENDOR_ID, DIGI_4_ID) },
254*4882a593Smuzhiyun 	{ }						/* Terminating entry */
255*4882a593Smuzhiyun };
256*4882a593Smuzhiyun 
257*4882a593Smuzhiyun MODULE_DEVICE_TABLE(usb, id_table_combined);
258*4882a593Smuzhiyun 
259*4882a593Smuzhiyun /* device info needed for the Digi serial converter */
260*4882a593Smuzhiyun 
261*4882a593Smuzhiyun static struct usb_serial_driver digi_acceleport_2_device = {
262*4882a593Smuzhiyun 	.driver = {
263*4882a593Smuzhiyun 		.owner =		THIS_MODULE,
264*4882a593Smuzhiyun 		.name =			"digi_2",
265*4882a593Smuzhiyun 	},
266*4882a593Smuzhiyun 	.description =			"Digi 2 port USB adapter",
267*4882a593Smuzhiyun 	.id_table =			id_table_2,
268*4882a593Smuzhiyun 	.num_ports =			3,
269*4882a593Smuzhiyun 	.num_bulk_in =			4,
270*4882a593Smuzhiyun 	.num_bulk_out =			4,
271*4882a593Smuzhiyun 	.open =				digi_open,
272*4882a593Smuzhiyun 	.close =			digi_close,
273*4882a593Smuzhiyun 	.dtr_rts =			digi_dtr_rts,
274*4882a593Smuzhiyun 	.write =			digi_write,
275*4882a593Smuzhiyun 	.write_room =			digi_write_room,
276*4882a593Smuzhiyun 	.write_bulk_callback = 		digi_write_bulk_callback,
277*4882a593Smuzhiyun 	.read_bulk_callback =		digi_read_bulk_callback,
278*4882a593Smuzhiyun 	.chars_in_buffer =		digi_chars_in_buffer,
279*4882a593Smuzhiyun 	.throttle =			digi_rx_throttle,
280*4882a593Smuzhiyun 	.unthrottle =			digi_rx_unthrottle,
281*4882a593Smuzhiyun 	.set_termios =			digi_set_termios,
282*4882a593Smuzhiyun 	.break_ctl =			digi_break_ctl,
283*4882a593Smuzhiyun 	.tiocmget =			digi_tiocmget,
284*4882a593Smuzhiyun 	.tiocmset =			digi_tiocmset,
285*4882a593Smuzhiyun 	.attach =			digi_startup,
286*4882a593Smuzhiyun 	.disconnect =			digi_disconnect,
287*4882a593Smuzhiyun 	.release =			digi_release,
288*4882a593Smuzhiyun 	.port_probe =			digi_port_probe,
289*4882a593Smuzhiyun 	.port_remove =			digi_port_remove,
290*4882a593Smuzhiyun };
291*4882a593Smuzhiyun 
292*4882a593Smuzhiyun static struct usb_serial_driver digi_acceleport_4_device = {
293*4882a593Smuzhiyun 	.driver = {
294*4882a593Smuzhiyun 		.owner =		THIS_MODULE,
295*4882a593Smuzhiyun 		.name =			"digi_4",
296*4882a593Smuzhiyun 	},
297*4882a593Smuzhiyun 	.description =			"Digi 4 port USB adapter",
298*4882a593Smuzhiyun 	.id_table =			id_table_4,
299*4882a593Smuzhiyun 	.num_ports =			4,
300*4882a593Smuzhiyun 	.num_bulk_in =			5,
301*4882a593Smuzhiyun 	.num_bulk_out =			5,
302*4882a593Smuzhiyun 	.open =				digi_open,
303*4882a593Smuzhiyun 	.close =			digi_close,
304*4882a593Smuzhiyun 	.write =			digi_write,
305*4882a593Smuzhiyun 	.write_room =			digi_write_room,
306*4882a593Smuzhiyun 	.write_bulk_callback = 		digi_write_bulk_callback,
307*4882a593Smuzhiyun 	.read_bulk_callback =		digi_read_bulk_callback,
308*4882a593Smuzhiyun 	.chars_in_buffer =		digi_chars_in_buffer,
309*4882a593Smuzhiyun 	.throttle =			digi_rx_throttle,
310*4882a593Smuzhiyun 	.unthrottle =			digi_rx_unthrottle,
311*4882a593Smuzhiyun 	.set_termios =			digi_set_termios,
312*4882a593Smuzhiyun 	.break_ctl =			digi_break_ctl,
313*4882a593Smuzhiyun 	.tiocmget =			digi_tiocmget,
314*4882a593Smuzhiyun 	.tiocmset =			digi_tiocmset,
315*4882a593Smuzhiyun 	.attach =			digi_startup,
316*4882a593Smuzhiyun 	.disconnect =			digi_disconnect,
317*4882a593Smuzhiyun 	.release =			digi_release,
318*4882a593Smuzhiyun 	.port_probe =			digi_port_probe,
319*4882a593Smuzhiyun 	.port_remove =			digi_port_remove,
320*4882a593Smuzhiyun };
321*4882a593Smuzhiyun 
322*4882a593Smuzhiyun static struct usb_serial_driver * const serial_drivers[] = {
323*4882a593Smuzhiyun 	&digi_acceleport_2_device, &digi_acceleport_4_device, NULL
324*4882a593Smuzhiyun };
325*4882a593Smuzhiyun 
326*4882a593Smuzhiyun /* Functions */
327*4882a593Smuzhiyun 
328*4882a593Smuzhiyun /*
329*4882a593Smuzhiyun  *  Cond Wait Interruptible Timeout Irqrestore
330*4882a593Smuzhiyun  *
331*4882a593Smuzhiyun  *  Do spin_unlock_irqrestore and interruptible_sleep_on_timeout
332*4882a593Smuzhiyun  *  so that wake ups are not lost if they occur between the unlock
333*4882a593Smuzhiyun  *  and the sleep.  In other words, spin_unlock_irqrestore and
334*4882a593Smuzhiyun  *  interruptible_sleep_on_timeout are "atomic" with respect to
335*4882a593Smuzhiyun  *  wake ups.  This is used to implement condition variables.
336*4882a593Smuzhiyun  *
337*4882a593Smuzhiyun  *  interruptible_sleep_on_timeout is deprecated and has been replaced
338*4882a593Smuzhiyun  *  with the equivalent code.
339*4882a593Smuzhiyun  */
340*4882a593Smuzhiyun 
cond_wait_interruptible_timeout_irqrestore(wait_queue_head_t * q,long timeout,spinlock_t * lock,unsigned long flags)341*4882a593Smuzhiyun static long cond_wait_interruptible_timeout_irqrestore(
342*4882a593Smuzhiyun 	wait_queue_head_t *q, long timeout,
343*4882a593Smuzhiyun 	spinlock_t *lock, unsigned long flags)
344*4882a593Smuzhiyun __releases(lock)
345*4882a593Smuzhiyun {
346*4882a593Smuzhiyun 	DEFINE_WAIT(wait);
347*4882a593Smuzhiyun 
348*4882a593Smuzhiyun 	prepare_to_wait(q, &wait, TASK_INTERRUPTIBLE);
349*4882a593Smuzhiyun 	spin_unlock_irqrestore(lock, flags);
350*4882a593Smuzhiyun 	timeout = schedule_timeout(timeout);
351*4882a593Smuzhiyun 	finish_wait(q, &wait);
352*4882a593Smuzhiyun 
353*4882a593Smuzhiyun 	return timeout;
354*4882a593Smuzhiyun }
355*4882a593Smuzhiyun 
356*4882a593Smuzhiyun /*
357*4882a593Smuzhiyun  *  Digi Write OOB Command
358*4882a593Smuzhiyun  *
359*4882a593Smuzhiyun  *  Write commands on the out of band port.  Commands are 4
360*4882a593Smuzhiyun  *  bytes each, multiple commands can be sent at once, and
361*4882a593Smuzhiyun  *  no command will be split across USB packets.  Returns 0
362*4882a593Smuzhiyun  *  if successful, -EINTR if interrupted while sleeping and
363*4882a593Smuzhiyun  *  the interruptible flag is true, or a negative error
364*4882a593Smuzhiyun  *  returned by usb_submit_urb.
365*4882a593Smuzhiyun  */
366*4882a593Smuzhiyun 
digi_write_oob_command(struct usb_serial_port * port,unsigned char * buf,int count,int interruptible)367*4882a593Smuzhiyun static int digi_write_oob_command(struct usb_serial_port *port,
368*4882a593Smuzhiyun 	unsigned char *buf, int count, int interruptible)
369*4882a593Smuzhiyun {
370*4882a593Smuzhiyun 	int ret = 0;
371*4882a593Smuzhiyun 	int len;
372*4882a593Smuzhiyun 	struct usb_serial_port *oob_port = (struct usb_serial_port *)((struct digi_serial *)(usb_get_serial_data(port->serial)))->ds_oob_port;
373*4882a593Smuzhiyun 	struct digi_port *oob_priv = usb_get_serial_port_data(oob_port);
374*4882a593Smuzhiyun 	unsigned long flags = 0;
375*4882a593Smuzhiyun 
376*4882a593Smuzhiyun 	dev_dbg(&port->dev,
377*4882a593Smuzhiyun 		"digi_write_oob_command: TOP: port=%d, count=%d\n",
378*4882a593Smuzhiyun 		oob_priv->dp_port_num, count);
379*4882a593Smuzhiyun 
380*4882a593Smuzhiyun 	spin_lock_irqsave(&oob_priv->dp_port_lock, flags);
381*4882a593Smuzhiyun 	while (count > 0) {
382*4882a593Smuzhiyun 		while (oob_priv->dp_write_urb_in_use) {
383*4882a593Smuzhiyun 			cond_wait_interruptible_timeout_irqrestore(
384*4882a593Smuzhiyun 				&oob_port->write_wait, DIGI_RETRY_TIMEOUT,
385*4882a593Smuzhiyun 				&oob_priv->dp_port_lock, flags);
386*4882a593Smuzhiyun 			if (interruptible && signal_pending(current))
387*4882a593Smuzhiyun 				return -EINTR;
388*4882a593Smuzhiyun 			spin_lock_irqsave(&oob_priv->dp_port_lock, flags);
389*4882a593Smuzhiyun 		}
390*4882a593Smuzhiyun 
391*4882a593Smuzhiyun 		/* len must be a multiple of 4, so commands are not split */
392*4882a593Smuzhiyun 		len = min(count, oob_port->bulk_out_size);
393*4882a593Smuzhiyun 		if (len > 4)
394*4882a593Smuzhiyun 			len &= ~3;
395*4882a593Smuzhiyun 		memcpy(oob_port->write_urb->transfer_buffer, buf, len);
396*4882a593Smuzhiyun 		oob_port->write_urb->transfer_buffer_length = len;
397*4882a593Smuzhiyun 		ret = usb_submit_urb(oob_port->write_urb, GFP_ATOMIC);
398*4882a593Smuzhiyun 		if (ret == 0) {
399*4882a593Smuzhiyun 			oob_priv->dp_write_urb_in_use = 1;
400*4882a593Smuzhiyun 			count -= len;
401*4882a593Smuzhiyun 			buf += len;
402*4882a593Smuzhiyun 		}
403*4882a593Smuzhiyun 	}
404*4882a593Smuzhiyun 	spin_unlock_irqrestore(&oob_priv->dp_port_lock, flags);
405*4882a593Smuzhiyun 	if (ret)
406*4882a593Smuzhiyun 		dev_err(&port->dev, "%s: usb_submit_urb failed, ret=%d\n",
407*4882a593Smuzhiyun 			__func__, ret);
408*4882a593Smuzhiyun 	return ret;
409*4882a593Smuzhiyun 
410*4882a593Smuzhiyun }
411*4882a593Smuzhiyun 
412*4882a593Smuzhiyun 
413*4882a593Smuzhiyun /*
414*4882a593Smuzhiyun  *  Digi Write In Band Command
415*4882a593Smuzhiyun  *
416*4882a593Smuzhiyun  *  Write commands on the given port.  Commands are 4
417*4882a593Smuzhiyun  *  bytes each, multiple commands can be sent at once, and
418*4882a593Smuzhiyun  *  no command will be split across USB packets.  If timeout
419*4882a593Smuzhiyun  *  is non-zero, write in band command will return after
420*4882a593Smuzhiyun  *  waiting unsuccessfully for the URB status to clear for
421*4882a593Smuzhiyun  *  timeout ticks.  Returns 0 if successful, or a negative
422*4882a593Smuzhiyun  *  error returned by digi_write.
423*4882a593Smuzhiyun  */
424*4882a593Smuzhiyun 
digi_write_inb_command(struct usb_serial_port * port,unsigned char * buf,int count,unsigned long timeout)425*4882a593Smuzhiyun static int digi_write_inb_command(struct usb_serial_port *port,
426*4882a593Smuzhiyun 	unsigned char *buf, int count, unsigned long timeout)
427*4882a593Smuzhiyun {
428*4882a593Smuzhiyun 	int ret = 0;
429*4882a593Smuzhiyun 	int len;
430*4882a593Smuzhiyun 	struct digi_port *priv = usb_get_serial_port_data(port);
431*4882a593Smuzhiyun 	unsigned char *data = port->write_urb->transfer_buffer;
432*4882a593Smuzhiyun 	unsigned long flags = 0;
433*4882a593Smuzhiyun 
434*4882a593Smuzhiyun 	dev_dbg(&port->dev, "digi_write_inb_command: TOP: port=%d, count=%d\n",
435*4882a593Smuzhiyun 		priv->dp_port_num, count);
436*4882a593Smuzhiyun 
437*4882a593Smuzhiyun 	if (timeout)
438*4882a593Smuzhiyun 		timeout += jiffies;
439*4882a593Smuzhiyun 	else
440*4882a593Smuzhiyun 		timeout = ULONG_MAX;
441*4882a593Smuzhiyun 
442*4882a593Smuzhiyun 	spin_lock_irqsave(&priv->dp_port_lock, flags);
443*4882a593Smuzhiyun 	while (count > 0 && ret == 0) {
444*4882a593Smuzhiyun 		while (priv->dp_write_urb_in_use &&
445*4882a593Smuzhiyun 		       time_before(jiffies, timeout)) {
446*4882a593Smuzhiyun 			cond_wait_interruptible_timeout_irqrestore(
447*4882a593Smuzhiyun 				&port->write_wait, DIGI_RETRY_TIMEOUT,
448*4882a593Smuzhiyun 				&priv->dp_port_lock, flags);
449*4882a593Smuzhiyun 			if (signal_pending(current))
450*4882a593Smuzhiyun 				return -EINTR;
451*4882a593Smuzhiyun 			spin_lock_irqsave(&priv->dp_port_lock, flags);
452*4882a593Smuzhiyun 		}
453*4882a593Smuzhiyun 
454*4882a593Smuzhiyun 		/* len must be a multiple of 4 and small enough to */
455*4882a593Smuzhiyun 		/* guarantee the write will send buffered data first, */
456*4882a593Smuzhiyun 		/* so commands are in order with data and not split */
457*4882a593Smuzhiyun 		len = min(count, port->bulk_out_size-2-priv->dp_out_buf_len);
458*4882a593Smuzhiyun 		if (len > 4)
459*4882a593Smuzhiyun 			len &= ~3;
460*4882a593Smuzhiyun 
461*4882a593Smuzhiyun 		/* write any buffered data first */
462*4882a593Smuzhiyun 		if (priv->dp_out_buf_len > 0) {
463*4882a593Smuzhiyun 			data[0] = DIGI_CMD_SEND_DATA;
464*4882a593Smuzhiyun 			data[1] = priv->dp_out_buf_len;
465*4882a593Smuzhiyun 			memcpy(data + 2, priv->dp_out_buf,
466*4882a593Smuzhiyun 				priv->dp_out_buf_len);
467*4882a593Smuzhiyun 			memcpy(data + 2 + priv->dp_out_buf_len, buf, len);
468*4882a593Smuzhiyun 			port->write_urb->transfer_buffer_length
469*4882a593Smuzhiyun 				= priv->dp_out_buf_len + 2 + len;
470*4882a593Smuzhiyun 		} else {
471*4882a593Smuzhiyun 			memcpy(data, buf, len);
472*4882a593Smuzhiyun 			port->write_urb->transfer_buffer_length = len;
473*4882a593Smuzhiyun 		}
474*4882a593Smuzhiyun 
475*4882a593Smuzhiyun 		ret = usb_submit_urb(port->write_urb, GFP_ATOMIC);
476*4882a593Smuzhiyun 		if (ret == 0) {
477*4882a593Smuzhiyun 			priv->dp_write_urb_in_use = 1;
478*4882a593Smuzhiyun 			priv->dp_out_buf_len = 0;
479*4882a593Smuzhiyun 			count -= len;
480*4882a593Smuzhiyun 			buf += len;
481*4882a593Smuzhiyun 		}
482*4882a593Smuzhiyun 
483*4882a593Smuzhiyun 	}
484*4882a593Smuzhiyun 	spin_unlock_irqrestore(&priv->dp_port_lock, flags);
485*4882a593Smuzhiyun 
486*4882a593Smuzhiyun 	if (ret)
487*4882a593Smuzhiyun 		dev_err(&port->dev,
488*4882a593Smuzhiyun 			"%s: usb_submit_urb failed, ret=%d, port=%d\n",
489*4882a593Smuzhiyun 			__func__, ret, priv->dp_port_num);
490*4882a593Smuzhiyun 	return ret;
491*4882a593Smuzhiyun }
492*4882a593Smuzhiyun 
493*4882a593Smuzhiyun 
494*4882a593Smuzhiyun /*
495*4882a593Smuzhiyun  *  Digi Set Modem Signals
496*4882a593Smuzhiyun  *
497*4882a593Smuzhiyun  *  Sets or clears DTR and RTS on the port, according to the
498*4882a593Smuzhiyun  *  modem_signals argument.  Use TIOCM_DTR and TIOCM_RTS flags
499*4882a593Smuzhiyun  *  for the modem_signals argument.  Returns 0 if successful,
500*4882a593Smuzhiyun  *  -EINTR if interrupted while sleeping, or a non-zero error
501*4882a593Smuzhiyun  *  returned by usb_submit_urb.
502*4882a593Smuzhiyun  */
503*4882a593Smuzhiyun 
digi_set_modem_signals(struct usb_serial_port * port,unsigned int modem_signals,int interruptible)504*4882a593Smuzhiyun static int digi_set_modem_signals(struct usb_serial_port *port,
505*4882a593Smuzhiyun 	unsigned int modem_signals, int interruptible)
506*4882a593Smuzhiyun {
507*4882a593Smuzhiyun 
508*4882a593Smuzhiyun 	int ret;
509*4882a593Smuzhiyun 	struct digi_port *port_priv = usb_get_serial_port_data(port);
510*4882a593Smuzhiyun 	struct usb_serial_port *oob_port = (struct usb_serial_port *) ((struct digi_serial *)(usb_get_serial_data(port->serial)))->ds_oob_port;
511*4882a593Smuzhiyun 	struct digi_port *oob_priv = usb_get_serial_port_data(oob_port);
512*4882a593Smuzhiyun 	unsigned char *data = oob_port->write_urb->transfer_buffer;
513*4882a593Smuzhiyun 	unsigned long flags = 0;
514*4882a593Smuzhiyun 
515*4882a593Smuzhiyun 
516*4882a593Smuzhiyun 	dev_dbg(&port->dev,
517*4882a593Smuzhiyun 		"digi_set_modem_signals: TOP: port=%d, modem_signals=0x%x\n",
518*4882a593Smuzhiyun 		port_priv->dp_port_num, modem_signals);
519*4882a593Smuzhiyun 
520*4882a593Smuzhiyun 	spin_lock_irqsave(&oob_priv->dp_port_lock, flags);
521*4882a593Smuzhiyun 	spin_lock(&port_priv->dp_port_lock);
522*4882a593Smuzhiyun 
523*4882a593Smuzhiyun 	while (oob_priv->dp_write_urb_in_use) {
524*4882a593Smuzhiyun 		spin_unlock(&port_priv->dp_port_lock);
525*4882a593Smuzhiyun 		cond_wait_interruptible_timeout_irqrestore(
526*4882a593Smuzhiyun 			&oob_port->write_wait, DIGI_RETRY_TIMEOUT,
527*4882a593Smuzhiyun 			&oob_priv->dp_port_lock, flags);
528*4882a593Smuzhiyun 		if (interruptible && signal_pending(current))
529*4882a593Smuzhiyun 			return -EINTR;
530*4882a593Smuzhiyun 		spin_lock_irqsave(&oob_priv->dp_port_lock, flags);
531*4882a593Smuzhiyun 		spin_lock(&port_priv->dp_port_lock);
532*4882a593Smuzhiyun 	}
533*4882a593Smuzhiyun 	data[0] = DIGI_CMD_SET_DTR_SIGNAL;
534*4882a593Smuzhiyun 	data[1] = port_priv->dp_port_num;
535*4882a593Smuzhiyun 	data[2] = (modem_signals & TIOCM_DTR) ?
536*4882a593Smuzhiyun 					DIGI_DTR_ACTIVE : DIGI_DTR_INACTIVE;
537*4882a593Smuzhiyun 	data[3] = 0;
538*4882a593Smuzhiyun 	data[4] = DIGI_CMD_SET_RTS_SIGNAL;
539*4882a593Smuzhiyun 	data[5] = port_priv->dp_port_num;
540*4882a593Smuzhiyun 	data[6] = (modem_signals & TIOCM_RTS) ?
541*4882a593Smuzhiyun 					DIGI_RTS_ACTIVE : DIGI_RTS_INACTIVE;
542*4882a593Smuzhiyun 	data[7] = 0;
543*4882a593Smuzhiyun 
544*4882a593Smuzhiyun 	oob_port->write_urb->transfer_buffer_length = 8;
545*4882a593Smuzhiyun 
546*4882a593Smuzhiyun 	ret = usb_submit_urb(oob_port->write_urb, GFP_ATOMIC);
547*4882a593Smuzhiyun 	if (ret == 0) {
548*4882a593Smuzhiyun 		oob_priv->dp_write_urb_in_use = 1;
549*4882a593Smuzhiyun 		port_priv->dp_modem_signals &= ~(TIOCM_DTR | TIOCM_RTS);
550*4882a593Smuzhiyun 		port_priv->dp_modem_signals |=
551*4882a593Smuzhiyun 				modem_signals & (TIOCM_DTR | TIOCM_RTS);
552*4882a593Smuzhiyun 	}
553*4882a593Smuzhiyun 	spin_unlock(&port_priv->dp_port_lock);
554*4882a593Smuzhiyun 	spin_unlock_irqrestore(&oob_priv->dp_port_lock, flags);
555*4882a593Smuzhiyun 	if (ret)
556*4882a593Smuzhiyun 		dev_err(&port->dev, "%s: usb_submit_urb failed, ret=%d\n",
557*4882a593Smuzhiyun 			__func__, ret);
558*4882a593Smuzhiyun 	return ret;
559*4882a593Smuzhiyun }
560*4882a593Smuzhiyun 
561*4882a593Smuzhiyun /*
562*4882a593Smuzhiyun  *  Digi Transmit Idle
563*4882a593Smuzhiyun  *
564*4882a593Smuzhiyun  *  Digi transmit idle waits, up to timeout ticks, for the transmitter
565*4882a593Smuzhiyun  *  to go idle.  It returns 0 if successful or a negative error.
566*4882a593Smuzhiyun  *
567*4882a593Smuzhiyun  *  There are race conditions here if more than one process is calling
568*4882a593Smuzhiyun  *  digi_transmit_idle on the same port at the same time.  However, this
569*4882a593Smuzhiyun  *  is only called from close, and only one process can be in close on a
570*4882a593Smuzhiyun  *  port at a time, so its ok.
571*4882a593Smuzhiyun  */
572*4882a593Smuzhiyun 
digi_transmit_idle(struct usb_serial_port * port,unsigned long timeout)573*4882a593Smuzhiyun static int digi_transmit_idle(struct usb_serial_port *port,
574*4882a593Smuzhiyun 	unsigned long timeout)
575*4882a593Smuzhiyun {
576*4882a593Smuzhiyun 	int ret;
577*4882a593Smuzhiyun 	unsigned char buf[2];
578*4882a593Smuzhiyun 	struct digi_port *priv = usb_get_serial_port_data(port);
579*4882a593Smuzhiyun 	unsigned long flags = 0;
580*4882a593Smuzhiyun 
581*4882a593Smuzhiyun 	spin_lock_irqsave(&priv->dp_port_lock, flags);
582*4882a593Smuzhiyun 	priv->dp_transmit_idle = 0;
583*4882a593Smuzhiyun 	spin_unlock_irqrestore(&priv->dp_port_lock, flags);
584*4882a593Smuzhiyun 
585*4882a593Smuzhiyun 	buf[0] = DIGI_CMD_TRANSMIT_IDLE;
586*4882a593Smuzhiyun 	buf[1] = 0;
587*4882a593Smuzhiyun 
588*4882a593Smuzhiyun 	timeout += jiffies;
589*4882a593Smuzhiyun 
590*4882a593Smuzhiyun 	ret = digi_write_inb_command(port, buf, 2, timeout - jiffies);
591*4882a593Smuzhiyun 	if (ret != 0)
592*4882a593Smuzhiyun 		return ret;
593*4882a593Smuzhiyun 
594*4882a593Smuzhiyun 	spin_lock_irqsave(&priv->dp_port_lock, flags);
595*4882a593Smuzhiyun 
596*4882a593Smuzhiyun 	while (time_before(jiffies, timeout) && !priv->dp_transmit_idle) {
597*4882a593Smuzhiyun 		cond_wait_interruptible_timeout_irqrestore(
598*4882a593Smuzhiyun 			&priv->dp_transmit_idle_wait, DIGI_RETRY_TIMEOUT,
599*4882a593Smuzhiyun 			&priv->dp_port_lock, flags);
600*4882a593Smuzhiyun 		if (signal_pending(current))
601*4882a593Smuzhiyun 			return -EINTR;
602*4882a593Smuzhiyun 		spin_lock_irqsave(&priv->dp_port_lock, flags);
603*4882a593Smuzhiyun 	}
604*4882a593Smuzhiyun 	priv->dp_transmit_idle = 0;
605*4882a593Smuzhiyun 	spin_unlock_irqrestore(&priv->dp_port_lock, flags);
606*4882a593Smuzhiyun 	return 0;
607*4882a593Smuzhiyun 
608*4882a593Smuzhiyun }
609*4882a593Smuzhiyun 
610*4882a593Smuzhiyun 
digi_rx_throttle(struct tty_struct * tty)611*4882a593Smuzhiyun static void digi_rx_throttle(struct tty_struct *tty)
612*4882a593Smuzhiyun {
613*4882a593Smuzhiyun 	unsigned long flags;
614*4882a593Smuzhiyun 	struct usb_serial_port *port = tty->driver_data;
615*4882a593Smuzhiyun 	struct digi_port *priv = usb_get_serial_port_data(port);
616*4882a593Smuzhiyun 
617*4882a593Smuzhiyun 	/* stop receiving characters by not resubmitting the read urb */
618*4882a593Smuzhiyun 	spin_lock_irqsave(&priv->dp_port_lock, flags);
619*4882a593Smuzhiyun 	priv->dp_throttled = 1;
620*4882a593Smuzhiyun 	priv->dp_throttle_restart = 0;
621*4882a593Smuzhiyun 	spin_unlock_irqrestore(&priv->dp_port_lock, flags);
622*4882a593Smuzhiyun }
623*4882a593Smuzhiyun 
624*4882a593Smuzhiyun 
digi_rx_unthrottle(struct tty_struct * tty)625*4882a593Smuzhiyun static void digi_rx_unthrottle(struct tty_struct *tty)
626*4882a593Smuzhiyun {
627*4882a593Smuzhiyun 	int ret = 0;
628*4882a593Smuzhiyun 	unsigned long flags;
629*4882a593Smuzhiyun 	struct usb_serial_port *port = tty->driver_data;
630*4882a593Smuzhiyun 	struct digi_port *priv = usb_get_serial_port_data(port);
631*4882a593Smuzhiyun 
632*4882a593Smuzhiyun 	spin_lock_irqsave(&priv->dp_port_lock, flags);
633*4882a593Smuzhiyun 
634*4882a593Smuzhiyun 	/* restart read chain */
635*4882a593Smuzhiyun 	if (priv->dp_throttle_restart)
636*4882a593Smuzhiyun 		ret = usb_submit_urb(port->read_urb, GFP_ATOMIC);
637*4882a593Smuzhiyun 
638*4882a593Smuzhiyun 	/* turn throttle off */
639*4882a593Smuzhiyun 	priv->dp_throttled = 0;
640*4882a593Smuzhiyun 	priv->dp_throttle_restart = 0;
641*4882a593Smuzhiyun 
642*4882a593Smuzhiyun 	spin_unlock_irqrestore(&priv->dp_port_lock, flags);
643*4882a593Smuzhiyun 
644*4882a593Smuzhiyun 	if (ret)
645*4882a593Smuzhiyun 		dev_err(&port->dev,
646*4882a593Smuzhiyun 			"%s: usb_submit_urb failed, ret=%d, port=%d\n",
647*4882a593Smuzhiyun 			__func__, ret, priv->dp_port_num);
648*4882a593Smuzhiyun }
649*4882a593Smuzhiyun 
650*4882a593Smuzhiyun 
digi_set_termios(struct tty_struct * tty,struct usb_serial_port * port,struct ktermios * old_termios)651*4882a593Smuzhiyun static void digi_set_termios(struct tty_struct *tty,
652*4882a593Smuzhiyun 		struct usb_serial_port *port, struct ktermios *old_termios)
653*4882a593Smuzhiyun {
654*4882a593Smuzhiyun 	struct digi_port *priv = usb_get_serial_port_data(port);
655*4882a593Smuzhiyun 	struct device *dev = &port->dev;
656*4882a593Smuzhiyun 	unsigned int iflag = tty->termios.c_iflag;
657*4882a593Smuzhiyun 	unsigned int cflag = tty->termios.c_cflag;
658*4882a593Smuzhiyun 	unsigned int old_iflag = old_termios->c_iflag;
659*4882a593Smuzhiyun 	unsigned int old_cflag = old_termios->c_cflag;
660*4882a593Smuzhiyun 	unsigned char buf[32];
661*4882a593Smuzhiyun 	unsigned int modem_signals;
662*4882a593Smuzhiyun 	int arg, ret;
663*4882a593Smuzhiyun 	int i = 0;
664*4882a593Smuzhiyun 	speed_t baud;
665*4882a593Smuzhiyun 
666*4882a593Smuzhiyun 	dev_dbg(dev,
667*4882a593Smuzhiyun 		"digi_set_termios: TOP: port=%d, iflag=0x%x, old_iflag=0x%x, cflag=0x%x, old_cflag=0x%x\n",
668*4882a593Smuzhiyun 		priv->dp_port_num, iflag, old_iflag, cflag, old_cflag);
669*4882a593Smuzhiyun 
670*4882a593Smuzhiyun 	/* set baud rate */
671*4882a593Smuzhiyun 	baud = tty_get_baud_rate(tty);
672*4882a593Smuzhiyun 	if (baud != tty_termios_baud_rate(old_termios)) {
673*4882a593Smuzhiyun 		arg = -1;
674*4882a593Smuzhiyun 
675*4882a593Smuzhiyun 		/* reassert DTR and (maybe) RTS on transition from B0 */
676*4882a593Smuzhiyun 		if ((old_cflag & CBAUD) == B0) {
677*4882a593Smuzhiyun 			/* don't set RTS if using hardware flow control */
678*4882a593Smuzhiyun 			/* and throttling input */
679*4882a593Smuzhiyun 			modem_signals = TIOCM_DTR;
680*4882a593Smuzhiyun 			if (!C_CRTSCTS(tty) || !tty_throttled(tty))
681*4882a593Smuzhiyun 				modem_signals |= TIOCM_RTS;
682*4882a593Smuzhiyun 			digi_set_modem_signals(port, modem_signals, 1);
683*4882a593Smuzhiyun 		}
684*4882a593Smuzhiyun 		switch (baud) {
685*4882a593Smuzhiyun 		/* drop DTR and RTS on transition to B0 */
686*4882a593Smuzhiyun 		case 0: digi_set_modem_signals(port, 0, 1); break;
687*4882a593Smuzhiyun 		case 50: arg = DIGI_BAUD_50; break;
688*4882a593Smuzhiyun 		case 75: arg = DIGI_BAUD_75; break;
689*4882a593Smuzhiyun 		case 110: arg = DIGI_BAUD_110; break;
690*4882a593Smuzhiyun 		case 150: arg = DIGI_BAUD_150; break;
691*4882a593Smuzhiyun 		case 200: arg = DIGI_BAUD_200; break;
692*4882a593Smuzhiyun 		case 300: arg = DIGI_BAUD_300; break;
693*4882a593Smuzhiyun 		case 600: arg = DIGI_BAUD_600; break;
694*4882a593Smuzhiyun 		case 1200: arg = DIGI_BAUD_1200; break;
695*4882a593Smuzhiyun 		case 1800: arg = DIGI_BAUD_1800; break;
696*4882a593Smuzhiyun 		case 2400: arg = DIGI_BAUD_2400; break;
697*4882a593Smuzhiyun 		case 4800: arg = DIGI_BAUD_4800; break;
698*4882a593Smuzhiyun 		case 9600: arg = DIGI_BAUD_9600; break;
699*4882a593Smuzhiyun 		case 19200: arg = DIGI_BAUD_19200; break;
700*4882a593Smuzhiyun 		case 38400: arg = DIGI_BAUD_38400; break;
701*4882a593Smuzhiyun 		case 57600: arg = DIGI_BAUD_57600; break;
702*4882a593Smuzhiyun 		case 115200: arg = DIGI_BAUD_115200; break;
703*4882a593Smuzhiyun 		case 230400: arg = DIGI_BAUD_230400; break;
704*4882a593Smuzhiyun 		case 460800: arg = DIGI_BAUD_460800; break;
705*4882a593Smuzhiyun 		default:
706*4882a593Smuzhiyun 			arg = DIGI_BAUD_9600;
707*4882a593Smuzhiyun 			baud = 9600;
708*4882a593Smuzhiyun 			break;
709*4882a593Smuzhiyun 		}
710*4882a593Smuzhiyun 		if (arg != -1) {
711*4882a593Smuzhiyun 			buf[i++] = DIGI_CMD_SET_BAUD_RATE;
712*4882a593Smuzhiyun 			buf[i++] = priv->dp_port_num;
713*4882a593Smuzhiyun 			buf[i++] = arg;
714*4882a593Smuzhiyun 			buf[i++] = 0;
715*4882a593Smuzhiyun 		}
716*4882a593Smuzhiyun 	}
717*4882a593Smuzhiyun 	/* set parity */
718*4882a593Smuzhiyun 	tty->termios.c_cflag &= ~CMSPAR;
719*4882a593Smuzhiyun 
720*4882a593Smuzhiyun 	if ((cflag & (PARENB | PARODD)) != (old_cflag & (PARENB | PARODD))) {
721*4882a593Smuzhiyun 		if (cflag & PARENB) {
722*4882a593Smuzhiyun 			if (cflag & PARODD)
723*4882a593Smuzhiyun 				arg = DIGI_PARITY_ODD;
724*4882a593Smuzhiyun 			else
725*4882a593Smuzhiyun 				arg = DIGI_PARITY_EVEN;
726*4882a593Smuzhiyun 		} else {
727*4882a593Smuzhiyun 			arg = DIGI_PARITY_NONE;
728*4882a593Smuzhiyun 		}
729*4882a593Smuzhiyun 		buf[i++] = DIGI_CMD_SET_PARITY;
730*4882a593Smuzhiyun 		buf[i++] = priv->dp_port_num;
731*4882a593Smuzhiyun 		buf[i++] = arg;
732*4882a593Smuzhiyun 		buf[i++] = 0;
733*4882a593Smuzhiyun 	}
734*4882a593Smuzhiyun 	/* set word size */
735*4882a593Smuzhiyun 	if ((cflag & CSIZE) != (old_cflag & CSIZE)) {
736*4882a593Smuzhiyun 		arg = -1;
737*4882a593Smuzhiyun 		switch (cflag & CSIZE) {
738*4882a593Smuzhiyun 		case CS5: arg = DIGI_WORD_SIZE_5; break;
739*4882a593Smuzhiyun 		case CS6: arg = DIGI_WORD_SIZE_6; break;
740*4882a593Smuzhiyun 		case CS7: arg = DIGI_WORD_SIZE_7; break;
741*4882a593Smuzhiyun 		case CS8: arg = DIGI_WORD_SIZE_8; break;
742*4882a593Smuzhiyun 		default:
743*4882a593Smuzhiyun 			dev_dbg(dev,
744*4882a593Smuzhiyun 				"digi_set_termios: can't handle word size %d\n",
745*4882a593Smuzhiyun 				cflag & CSIZE);
746*4882a593Smuzhiyun 			break;
747*4882a593Smuzhiyun 		}
748*4882a593Smuzhiyun 
749*4882a593Smuzhiyun 		if (arg != -1) {
750*4882a593Smuzhiyun 			buf[i++] = DIGI_CMD_SET_WORD_SIZE;
751*4882a593Smuzhiyun 			buf[i++] = priv->dp_port_num;
752*4882a593Smuzhiyun 			buf[i++] = arg;
753*4882a593Smuzhiyun 			buf[i++] = 0;
754*4882a593Smuzhiyun 		}
755*4882a593Smuzhiyun 
756*4882a593Smuzhiyun 	}
757*4882a593Smuzhiyun 
758*4882a593Smuzhiyun 	/* set stop bits */
759*4882a593Smuzhiyun 	if ((cflag & CSTOPB) != (old_cflag & CSTOPB)) {
760*4882a593Smuzhiyun 
761*4882a593Smuzhiyun 		if ((cflag & CSTOPB))
762*4882a593Smuzhiyun 			arg = DIGI_STOP_BITS_2;
763*4882a593Smuzhiyun 		else
764*4882a593Smuzhiyun 			arg = DIGI_STOP_BITS_1;
765*4882a593Smuzhiyun 
766*4882a593Smuzhiyun 		buf[i++] = DIGI_CMD_SET_STOP_BITS;
767*4882a593Smuzhiyun 		buf[i++] = priv->dp_port_num;
768*4882a593Smuzhiyun 		buf[i++] = arg;
769*4882a593Smuzhiyun 		buf[i++] = 0;
770*4882a593Smuzhiyun 
771*4882a593Smuzhiyun 	}
772*4882a593Smuzhiyun 
773*4882a593Smuzhiyun 	/* set input flow control */
774*4882a593Smuzhiyun 	if ((iflag & IXOFF) != (old_iflag & IXOFF) ||
775*4882a593Smuzhiyun 			(cflag & CRTSCTS) != (old_cflag & CRTSCTS)) {
776*4882a593Smuzhiyun 		arg = 0;
777*4882a593Smuzhiyun 		if (iflag & IXOFF)
778*4882a593Smuzhiyun 			arg |= DIGI_INPUT_FLOW_CONTROL_XON_XOFF;
779*4882a593Smuzhiyun 		else
780*4882a593Smuzhiyun 			arg &= ~DIGI_INPUT_FLOW_CONTROL_XON_XOFF;
781*4882a593Smuzhiyun 
782*4882a593Smuzhiyun 		if (cflag & CRTSCTS) {
783*4882a593Smuzhiyun 			arg |= DIGI_INPUT_FLOW_CONTROL_RTS;
784*4882a593Smuzhiyun 
785*4882a593Smuzhiyun 			/* On USB-4 it is necessary to assert RTS prior */
786*4882a593Smuzhiyun 			/* to selecting RTS input flow control.  */
787*4882a593Smuzhiyun 			buf[i++] = DIGI_CMD_SET_RTS_SIGNAL;
788*4882a593Smuzhiyun 			buf[i++] = priv->dp_port_num;
789*4882a593Smuzhiyun 			buf[i++] = DIGI_RTS_ACTIVE;
790*4882a593Smuzhiyun 			buf[i++] = 0;
791*4882a593Smuzhiyun 
792*4882a593Smuzhiyun 		} else {
793*4882a593Smuzhiyun 			arg &= ~DIGI_INPUT_FLOW_CONTROL_RTS;
794*4882a593Smuzhiyun 		}
795*4882a593Smuzhiyun 		buf[i++] = DIGI_CMD_SET_INPUT_FLOW_CONTROL;
796*4882a593Smuzhiyun 		buf[i++] = priv->dp_port_num;
797*4882a593Smuzhiyun 		buf[i++] = arg;
798*4882a593Smuzhiyun 		buf[i++] = 0;
799*4882a593Smuzhiyun 	}
800*4882a593Smuzhiyun 
801*4882a593Smuzhiyun 	/* set output flow control */
802*4882a593Smuzhiyun 	if ((iflag & IXON) != (old_iflag & IXON) ||
803*4882a593Smuzhiyun 			(cflag & CRTSCTS) != (old_cflag & CRTSCTS)) {
804*4882a593Smuzhiyun 		arg = 0;
805*4882a593Smuzhiyun 		if (iflag & IXON)
806*4882a593Smuzhiyun 			arg |= DIGI_OUTPUT_FLOW_CONTROL_XON_XOFF;
807*4882a593Smuzhiyun 		else
808*4882a593Smuzhiyun 			arg &= ~DIGI_OUTPUT_FLOW_CONTROL_XON_XOFF;
809*4882a593Smuzhiyun 
810*4882a593Smuzhiyun 		if (cflag & CRTSCTS)
811*4882a593Smuzhiyun 			arg |= DIGI_OUTPUT_FLOW_CONTROL_CTS;
812*4882a593Smuzhiyun 		else
813*4882a593Smuzhiyun 			arg &= ~DIGI_OUTPUT_FLOW_CONTROL_CTS;
814*4882a593Smuzhiyun 
815*4882a593Smuzhiyun 		buf[i++] = DIGI_CMD_SET_OUTPUT_FLOW_CONTROL;
816*4882a593Smuzhiyun 		buf[i++] = priv->dp_port_num;
817*4882a593Smuzhiyun 		buf[i++] = arg;
818*4882a593Smuzhiyun 		buf[i++] = 0;
819*4882a593Smuzhiyun 	}
820*4882a593Smuzhiyun 
821*4882a593Smuzhiyun 	/* set receive enable/disable */
822*4882a593Smuzhiyun 	if ((cflag & CREAD) != (old_cflag & CREAD)) {
823*4882a593Smuzhiyun 		if (cflag & CREAD)
824*4882a593Smuzhiyun 			arg = DIGI_ENABLE;
825*4882a593Smuzhiyun 		else
826*4882a593Smuzhiyun 			arg = DIGI_DISABLE;
827*4882a593Smuzhiyun 
828*4882a593Smuzhiyun 		buf[i++] = DIGI_CMD_RECEIVE_ENABLE;
829*4882a593Smuzhiyun 		buf[i++] = priv->dp_port_num;
830*4882a593Smuzhiyun 		buf[i++] = arg;
831*4882a593Smuzhiyun 		buf[i++] = 0;
832*4882a593Smuzhiyun 	}
833*4882a593Smuzhiyun 	ret = digi_write_oob_command(port, buf, i, 1);
834*4882a593Smuzhiyun 	if (ret != 0)
835*4882a593Smuzhiyun 		dev_dbg(dev, "digi_set_termios: write oob failed, ret=%d\n", ret);
836*4882a593Smuzhiyun 	tty_encode_baud_rate(tty, baud, baud);
837*4882a593Smuzhiyun }
838*4882a593Smuzhiyun 
839*4882a593Smuzhiyun 
digi_break_ctl(struct tty_struct * tty,int break_state)840*4882a593Smuzhiyun static void digi_break_ctl(struct tty_struct *tty, int break_state)
841*4882a593Smuzhiyun {
842*4882a593Smuzhiyun 	struct usb_serial_port *port = tty->driver_data;
843*4882a593Smuzhiyun 	unsigned char buf[4];
844*4882a593Smuzhiyun 
845*4882a593Smuzhiyun 	buf[0] = DIGI_CMD_BREAK_CONTROL;
846*4882a593Smuzhiyun 	buf[1] = 2;				/* length */
847*4882a593Smuzhiyun 	buf[2] = break_state ? 1 : 0;
848*4882a593Smuzhiyun 	buf[3] = 0;				/* pad */
849*4882a593Smuzhiyun 	digi_write_inb_command(port, buf, 4, 0);
850*4882a593Smuzhiyun }
851*4882a593Smuzhiyun 
852*4882a593Smuzhiyun 
digi_tiocmget(struct tty_struct * tty)853*4882a593Smuzhiyun static int digi_tiocmget(struct tty_struct *tty)
854*4882a593Smuzhiyun {
855*4882a593Smuzhiyun 	struct usb_serial_port *port = tty->driver_data;
856*4882a593Smuzhiyun 	struct digi_port *priv = usb_get_serial_port_data(port);
857*4882a593Smuzhiyun 	unsigned int val;
858*4882a593Smuzhiyun 	unsigned long flags;
859*4882a593Smuzhiyun 
860*4882a593Smuzhiyun 	spin_lock_irqsave(&priv->dp_port_lock, flags);
861*4882a593Smuzhiyun 	val = priv->dp_modem_signals;
862*4882a593Smuzhiyun 	spin_unlock_irqrestore(&priv->dp_port_lock, flags);
863*4882a593Smuzhiyun 	return val;
864*4882a593Smuzhiyun }
865*4882a593Smuzhiyun 
866*4882a593Smuzhiyun 
digi_tiocmset(struct tty_struct * tty,unsigned int set,unsigned int clear)867*4882a593Smuzhiyun static int digi_tiocmset(struct tty_struct *tty,
868*4882a593Smuzhiyun 					unsigned int set, unsigned int clear)
869*4882a593Smuzhiyun {
870*4882a593Smuzhiyun 	struct usb_serial_port *port = tty->driver_data;
871*4882a593Smuzhiyun 	struct digi_port *priv = usb_get_serial_port_data(port);
872*4882a593Smuzhiyun 	unsigned int val;
873*4882a593Smuzhiyun 	unsigned long flags;
874*4882a593Smuzhiyun 
875*4882a593Smuzhiyun 	spin_lock_irqsave(&priv->dp_port_lock, flags);
876*4882a593Smuzhiyun 	val = (priv->dp_modem_signals & ~clear) | set;
877*4882a593Smuzhiyun 	spin_unlock_irqrestore(&priv->dp_port_lock, flags);
878*4882a593Smuzhiyun 	return digi_set_modem_signals(port, val, 1);
879*4882a593Smuzhiyun }
880*4882a593Smuzhiyun 
881*4882a593Smuzhiyun 
digi_write(struct tty_struct * tty,struct usb_serial_port * port,const unsigned char * buf,int count)882*4882a593Smuzhiyun static int digi_write(struct tty_struct *tty, struct usb_serial_port *port,
883*4882a593Smuzhiyun 					const unsigned char *buf, int count)
884*4882a593Smuzhiyun {
885*4882a593Smuzhiyun 
886*4882a593Smuzhiyun 	int ret, data_len, new_len;
887*4882a593Smuzhiyun 	struct digi_port *priv = usb_get_serial_port_data(port);
888*4882a593Smuzhiyun 	unsigned char *data = port->write_urb->transfer_buffer;
889*4882a593Smuzhiyun 	unsigned long flags = 0;
890*4882a593Smuzhiyun 
891*4882a593Smuzhiyun 	dev_dbg(&port->dev,
892*4882a593Smuzhiyun 		"digi_write: TOP: port=%d, count=%d, in_interrupt=%ld\n",
893*4882a593Smuzhiyun 		priv->dp_port_num, count, in_interrupt());
894*4882a593Smuzhiyun 
895*4882a593Smuzhiyun 	/* copy user data (which can sleep) before getting spin lock */
896*4882a593Smuzhiyun 	count = min(count, port->bulk_out_size-2);
897*4882a593Smuzhiyun 	count = min(64, count);
898*4882a593Smuzhiyun 
899*4882a593Smuzhiyun 	/* be sure only one write proceeds at a time */
900*4882a593Smuzhiyun 	/* there are races on the port private buffer */
901*4882a593Smuzhiyun 	spin_lock_irqsave(&priv->dp_port_lock, flags);
902*4882a593Smuzhiyun 
903*4882a593Smuzhiyun 	/* wait for urb status clear to submit another urb */
904*4882a593Smuzhiyun 	if (priv->dp_write_urb_in_use) {
905*4882a593Smuzhiyun 		/* buffer data if count is 1 (probably put_char) if possible */
906*4882a593Smuzhiyun 		if (count == 1 && priv->dp_out_buf_len < DIGI_OUT_BUF_SIZE) {
907*4882a593Smuzhiyun 			priv->dp_out_buf[priv->dp_out_buf_len++] = *buf;
908*4882a593Smuzhiyun 			new_len = 1;
909*4882a593Smuzhiyun 		} else {
910*4882a593Smuzhiyun 			new_len = 0;
911*4882a593Smuzhiyun 		}
912*4882a593Smuzhiyun 		spin_unlock_irqrestore(&priv->dp_port_lock, flags);
913*4882a593Smuzhiyun 		return new_len;
914*4882a593Smuzhiyun 	}
915*4882a593Smuzhiyun 
916*4882a593Smuzhiyun 	/* allow space for any buffered data and for new data, up to */
917*4882a593Smuzhiyun 	/* transfer buffer size - 2 (for command and length bytes) */
918*4882a593Smuzhiyun 	new_len = min(count, port->bulk_out_size-2-priv->dp_out_buf_len);
919*4882a593Smuzhiyun 	data_len = new_len + priv->dp_out_buf_len;
920*4882a593Smuzhiyun 
921*4882a593Smuzhiyun 	if (data_len == 0) {
922*4882a593Smuzhiyun 		spin_unlock_irqrestore(&priv->dp_port_lock, flags);
923*4882a593Smuzhiyun 		return 0;
924*4882a593Smuzhiyun 	}
925*4882a593Smuzhiyun 
926*4882a593Smuzhiyun 	port->write_urb->transfer_buffer_length = data_len+2;
927*4882a593Smuzhiyun 
928*4882a593Smuzhiyun 	*data++ = DIGI_CMD_SEND_DATA;
929*4882a593Smuzhiyun 	*data++ = data_len;
930*4882a593Smuzhiyun 
931*4882a593Smuzhiyun 	/* copy in buffered data first */
932*4882a593Smuzhiyun 	memcpy(data, priv->dp_out_buf, priv->dp_out_buf_len);
933*4882a593Smuzhiyun 	data += priv->dp_out_buf_len;
934*4882a593Smuzhiyun 
935*4882a593Smuzhiyun 	/* copy in new data */
936*4882a593Smuzhiyun 	memcpy(data, buf, new_len);
937*4882a593Smuzhiyun 
938*4882a593Smuzhiyun 	ret = usb_submit_urb(port->write_urb, GFP_ATOMIC);
939*4882a593Smuzhiyun 	if (ret == 0) {
940*4882a593Smuzhiyun 		priv->dp_write_urb_in_use = 1;
941*4882a593Smuzhiyun 		ret = new_len;
942*4882a593Smuzhiyun 		priv->dp_out_buf_len = 0;
943*4882a593Smuzhiyun 	}
944*4882a593Smuzhiyun 
945*4882a593Smuzhiyun 	/* return length of new data written, or error */
946*4882a593Smuzhiyun 	spin_unlock_irqrestore(&priv->dp_port_lock, flags);
947*4882a593Smuzhiyun 	if (ret < 0)
948*4882a593Smuzhiyun 		dev_err_console(port,
949*4882a593Smuzhiyun 			"%s: usb_submit_urb failed, ret=%d, port=%d\n",
950*4882a593Smuzhiyun 			__func__, ret, priv->dp_port_num);
951*4882a593Smuzhiyun 	dev_dbg(&port->dev, "digi_write: returning %d\n", ret);
952*4882a593Smuzhiyun 	return ret;
953*4882a593Smuzhiyun 
954*4882a593Smuzhiyun }
955*4882a593Smuzhiyun 
digi_write_bulk_callback(struct urb * urb)956*4882a593Smuzhiyun static void digi_write_bulk_callback(struct urb *urb)
957*4882a593Smuzhiyun {
958*4882a593Smuzhiyun 
959*4882a593Smuzhiyun 	struct usb_serial_port *port = urb->context;
960*4882a593Smuzhiyun 	struct usb_serial *serial;
961*4882a593Smuzhiyun 	struct digi_port *priv;
962*4882a593Smuzhiyun 	struct digi_serial *serial_priv;
963*4882a593Smuzhiyun 	unsigned long flags;
964*4882a593Smuzhiyun 	int ret = 0;
965*4882a593Smuzhiyun 	int status = urb->status;
966*4882a593Smuzhiyun 	bool wakeup;
967*4882a593Smuzhiyun 
968*4882a593Smuzhiyun 	/* port and serial sanity check */
969*4882a593Smuzhiyun 	if (port == NULL || (priv = usb_get_serial_port_data(port)) == NULL) {
970*4882a593Smuzhiyun 		pr_err("%s: port or port->private is NULL, status=%d\n",
971*4882a593Smuzhiyun 			__func__, status);
972*4882a593Smuzhiyun 		return;
973*4882a593Smuzhiyun 	}
974*4882a593Smuzhiyun 	serial = port->serial;
975*4882a593Smuzhiyun 	if (serial == NULL || (serial_priv = usb_get_serial_data(serial)) == NULL) {
976*4882a593Smuzhiyun 		dev_err(&port->dev,
977*4882a593Smuzhiyun 			"%s: serial or serial->private is NULL, status=%d\n",
978*4882a593Smuzhiyun 			__func__, status);
979*4882a593Smuzhiyun 		return;
980*4882a593Smuzhiyun 	}
981*4882a593Smuzhiyun 
982*4882a593Smuzhiyun 	/* handle oob callback */
983*4882a593Smuzhiyun 	if (priv->dp_port_num == serial_priv->ds_oob_port_num) {
984*4882a593Smuzhiyun 		dev_dbg(&port->dev, "digi_write_bulk_callback: oob callback\n");
985*4882a593Smuzhiyun 		spin_lock_irqsave(&priv->dp_port_lock, flags);
986*4882a593Smuzhiyun 		priv->dp_write_urb_in_use = 0;
987*4882a593Smuzhiyun 		wake_up_interruptible(&port->write_wait);
988*4882a593Smuzhiyun 		spin_unlock_irqrestore(&priv->dp_port_lock, flags);
989*4882a593Smuzhiyun 		return;
990*4882a593Smuzhiyun 	}
991*4882a593Smuzhiyun 
992*4882a593Smuzhiyun 	/* try to send any buffered data on this port */
993*4882a593Smuzhiyun 	wakeup = true;
994*4882a593Smuzhiyun 	spin_lock_irqsave(&priv->dp_port_lock, flags);
995*4882a593Smuzhiyun 	priv->dp_write_urb_in_use = 0;
996*4882a593Smuzhiyun 	if (priv->dp_out_buf_len > 0) {
997*4882a593Smuzhiyun 		*((unsigned char *)(port->write_urb->transfer_buffer))
998*4882a593Smuzhiyun 			= (unsigned char)DIGI_CMD_SEND_DATA;
999*4882a593Smuzhiyun 		*((unsigned char *)(port->write_urb->transfer_buffer) + 1)
1000*4882a593Smuzhiyun 			= (unsigned char)priv->dp_out_buf_len;
1001*4882a593Smuzhiyun 		port->write_urb->transfer_buffer_length =
1002*4882a593Smuzhiyun 						priv->dp_out_buf_len + 2;
1003*4882a593Smuzhiyun 		memcpy(port->write_urb->transfer_buffer + 2, priv->dp_out_buf,
1004*4882a593Smuzhiyun 			priv->dp_out_buf_len);
1005*4882a593Smuzhiyun 		ret = usb_submit_urb(port->write_urb, GFP_ATOMIC);
1006*4882a593Smuzhiyun 		if (ret == 0) {
1007*4882a593Smuzhiyun 			priv->dp_write_urb_in_use = 1;
1008*4882a593Smuzhiyun 			priv->dp_out_buf_len = 0;
1009*4882a593Smuzhiyun 			wakeup = false;
1010*4882a593Smuzhiyun 		}
1011*4882a593Smuzhiyun 	}
1012*4882a593Smuzhiyun 	spin_unlock_irqrestore(&priv->dp_port_lock, flags);
1013*4882a593Smuzhiyun 
1014*4882a593Smuzhiyun 	if (ret && ret != -EPERM)
1015*4882a593Smuzhiyun 		dev_err_console(port,
1016*4882a593Smuzhiyun 			"%s: usb_submit_urb failed, ret=%d, port=%d\n",
1017*4882a593Smuzhiyun 			__func__, ret, priv->dp_port_num);
1018*4882a593Smuzhiyun 
1019*4882a593Smuzhiyun 	if (wakeup)
1020*4882a593Smuzhiyun 		tty_port_tty_wakeup(&port->port);
1021*4882a593Smuzhiyun }
1022*4882a593Smuzhiyun 
digi_write_room(struct tty_struct * tty)1023*4882a593Smuzhiyun static int digi_write_room(struct tty_struct *tty)
1024*4882a593Smuzhiyun {
1025*4882a593Smuzhiyun 	struct usb_serial_port *port = tty->driver_data;
1026*4882a593Smuzhiyun 	struct digi_port *priv = usb_get_serial_port_data(port);
1027*4882a593Smuzhiyun 	int room;
1028*4882a593Smuzhiyun 	unsigned long flags = 0;
1029*4882a593Smuzhiyun 
1030*4882a593Smuzhiyun 	spin_lock_irqsave(&priv->dp_port_lock, flags);
1031*4882a593Smuzhiyun 
1032*4882a593Smuzhiyun 	if (priv->dp_write_urb_in_use)
1033*4882a593Smuzhiyun 		room = 0;
1034*4882a593Smuzhiyun 	else
1035*4882a593Smuzhiyun 		room = port->bulk_out_size - 2 - priv->dp_out_buf_len;
1036*4882a593Smuzhiyun 
1037*4882a593Smuzhiyun 	spin_unlock_irqrestore(&priv->dp_port_lock, flags);
1038*4882a593Smuzhiyun 	dev_dbg(&port->dev, "digi_write_room: port=%d, room=%d\n", priv->dp_port_num, room);
1039*4882a593Smuzhiyun 	return room;
1040*4882a593Smuzhiyun 
1041*4882a593Smuzhiyun }
1042*4882a593Smuzhiyun 
digi_chars_in_buffer(struct tty_struct * tty)1043*4882a593Smuzhiyun static int digi_chars_in_buffer(struct tty_struct *tty)
1044*4882a593Smuzhiyun {
1045*4882a593Smuzhiyun 	struct usb_serial_port *port = tty->driver_data;
1046*4882a593Smuzhiyun 	struct digi_port *priv = usb_get_serial_port_data(port);
1047*4882a593Smuzhiyun 
1048*4882a593Smuzhiyun 	if (priv->dp_write_urb_in_use) {
1049*4882a593Smuzhiyun 		dev_dbg(&port->dev, "digi_chars_in_buffer: port=%d, chars=%d\n",
1050*4882a593Smuzhiyun 			priv->dp_port_num, port->bulk_out_size - 2);
1051*4882a593Smuzhiyun 		/* return(port->bulk_out_size - 2); */
1052*4882a593Smuzhiyun 		return 256;
1053*4882a593Smuzhiyun 	} else {
1054*4882a593Smuzhiyun 		dev_dbg(&port->dev, "digi_chars_in_buffer: port=%d, chars=%d\n",
1055*4882a593Smuzhiyun 			priv->dp_port_num, priv->dp_out_buf_len);
1056*4882a593Smuzhiyun 		return priv->dp_out_buf_len;
1057*4882a593Smuzhiyun 	}
1058*4882a593Smuzhiyun 
1059*4882a593Smuzhiyun }
1060*4882a593Smuzhiyun 
digi_dtr_rts(struct usb_serial_port * port,int on)1061*4882a593Smuzhiyun static void digi_dtr_rts(struct usb_serial_port *port, int on)
1062*4882a593Smuzhiyun {
1063*4882a593Smuzhiyun 	/* Adjust DTR and RTS */
1064*4882a593Smuzhiyun 	digi_set_modem_signals(port, on * (TIOCM_DTR | TIOCM_RTS), 1);
1065*4882a593Smuzhiyun }
1066*4882a593Smuzhiyun 
digi_open(struct tty_struct * tty,struct usb_serial_port * port)1067*4882a593Smuzhiyun static int digi_open(struct tty_struct *tty, struct usb_serial_port *port)
1068*4882a593Smuzhiyun {
1069*4882a593Smuzhiyun 	int ret;
1070*4882a593Smuzhiyun 	unsigned char buf[32];
1071*4882a593Smuzhiyun 	struct digi_port *priv = usb_get_serial_port_data(port);
1072*4882a593Smuzhiyun 	struct ktermios not_termios;
1073*4882a593Smuzhiyun 
1074*4882a593Smuzhiyun 	/* be sure the device is started up */
1075*4882a593Smuzhiyun 	if (digi_startup_device(port->serial) != 0)
1076*4882a593Smuzhiyun 		return -ENXIO;
1077*4882a593Smuzhiyun 
1078*4882a593Smuzhiyun 	/* read modem signals automatically whenever they change */
1079*4882a593Smuzhiyun 	buf[0] = DIGI_CMD_READ_INPUT_SIGNALS;
1080*4882a593Smuzhiyun 	buf[1] = priv->dp_port_num;
1081*4882a593Smuzhiyun 	buf[2] = DIGI_ENABLE;
1082*4882a593Smuzhiyun 	buf[3] = 0;
1083*4882a593Smuzhiyun 
1084*4882a593Smuzhiyun 	/* flush fifos */
1085*4882a593Smuzhiyun 	buf[4] = DIGI_CMD_IFLUSH_FIFO;
1086*4882a593Smuzhiyun 	buf[5] = priv->dp_port_num;
1087*4882a593Smuzhiyun 	buf[6] = DIGI_FLUSH_TX | DIGI_FLUSH_RX;
1088*4882a593Smuzhiyun 	buf[7] = 0;
1089*4882a593Smuzhiyun 
1090*4882a593Smuzhiyun 	ret = digi_write_oob_command(port, buf, 8, 1);
1091*4882a593Smuzhiyun 	if (ret != 0)
1092*4882a593Smuzhiyun 		dev_dbg(&port->dev, "digi_open: write oob failed, ret=%d\n", ret);
1093*4882a593Smuzhiyun 
1094*4882a593Smuzhiyun 	/* set termios settings */
1095*4882a593Smuzhiyun 	if (tty) {
1096*4882a593Smuzhiyun 		not_termios.c_cflag = ~tty->termios.c_cflag;
1097*4882a593Smuzhiyun 		not_termios.c_iflag = ~tty->termios.c_iflag;
1098*4882a593Smuzhiyun 		digi_set_termios(tty, port, &not_termios);
1099*4882a593Smuzhiyun 	}
1100*4882a593Smuzhiyun 	return 0;
1101*4882a593Smuzhiyun }
1102*4882a593Smuzhiyun 
1103*4882a593Smuzhiyun 
digi_close(struct usb_serial_port * port)1104*4882a593Smuzhiyun static void digi_close(struct usb_serial_port *port)
1105*4882a593Smuzhiyun {
1106*4882a593Smuzhiyun 	DEFINE_WAIT(wait);
1107*4882a593Smuzhiyun 	int ret;
1108*4882a593Smuzhiyun 	unsigned char buf[32];
1109*4882a593Smuzhiyun 	struct digi_port *priv = usb_get_serial_port_data(port);
1110*4882a593Smuzhiyun 
1111*4882a593Smuzhiyun 	mutex_lock(&port->serial->disc_mutex);
1112*4882a593Smuzhiyun 	/* if disconnected, just clear flags */
1113*4882a593Smuzhiyun 	if (port->serial->disconnected)
1114*4882a593Smuzhiyun 		goto exit;
1115*4882a593Smuzhiyun 
1116*4882a593Smuzhiyun 	/* FIXME: Transmit idle belongs in the wait_unti_sent path */
1117*4882a593Smuzhiyun 	digi_transmit_idle(port, DIGI_CLOSE_TIMEOUT);
1118*4882a593Smuzhiyun 
1119*4882a593Smuzhiyun 	/* disable input flow control */
1120*4882a593Smuzhiyun 	buf[0] = DIGI_CMD_SET_INPUT_FLOW_CONTROL;
1121*4882a593Smuzhiyun 	buf[1] = priv->dp_port_num;
1122*4882a593Smuzhiyun 	buf[2] = DIGI_DISABLE;
1123*4882a593Smuzhiyun 	buf[3] = 0;
1124*4882a593Smuzhiyun 
1125*4882a593Smuzhiyun 	/* disable output flow control */
1126*4882a593Smuzhiyun 	buf[4] = DIGI_CMD_SET_OUTPUT_FLOW_CONTROL;
1127*4882a593Smuzhiyun 	buf[5] = priv->dp_port_num;
1128*4882a593Smuzhiyun 	buf[6] = DIGI_DISABLE;
1129*4882a593Smuzhiyun 	buf[7] = 0;
1130*4882a593Smuzhiyun 
1131*4882a593Smuzhiyun 	/* disable reading modem signals automatically */
1132*4882a593Smuzhiyun 	buf[8] = DIGI_CMD_READ_INPUT_SIGNALS;
1133*4882a593Smuzhiyun 	buf[9] = priv->dp_port_num;
1134*4882a593Smuzhiyun 	buf[10] = DIGI_DISABLE;
1135*4882a593Smuzhiyun 	buf[11] = 0;
1136*4882a593Smuzhiyun 
1137*4882a593Smuzhiyun 	/* disable receive */
1138*4882a593Smuzhiyun 	buf[12] = DIGI_CMD_RECEIVE_ENABLE;
1139*4882a593Smuzhiyun 	buf[13] = priv->dp_port_num;
1140*4882a593Smuzhiyun 	buf[14] = DIGI_DISABLE;
1141*4882a593Smuzhiyun 	buf[15] = 0;
1142*4882a593Smuzhiyun 
1143*4882a593Smuzhiyun 	/* flush fifos */
1144*4882a593Smuzhiyun 	buf[16] = DIGI_CMD_IFLUSH_FIFO;
1145*4882a593Smuzhiyun 	buf[17] = priv->dp_port_num;
1146*4882a593Smuzhiyun 	buf[18] = DIGI_FLUSH_TX | DIGI_FLUSH_RX;
1147*4882a593Smuzhiyun 	buf[19] = 0;
1148*4882a593Smuzhiyun 
1149*4882a593Smuzhiyun 	ret = digi_write_oob_command(port, buf, 20, 0);
1150*4882a593Smuzhiyun 	if (ret != 0)
1151*4882a593Smuzhiyun 		dev_dbg(&port->dev, "digi_close: write oob failed, ret=%d\n",
1152*4882a593Smuzhiyun 									ret);
1153*4882a593Smuzhiyun 	/* wait for final commands on oob port to complete */
1154*4882a593Smuzhiyun 	prepare_to_wait(&priv->dp_flush_wait, &wait,
1155*4882a593Smuzhiyun 			TASK_INTERRUPTIBLE);
1156*4882a593Smuzhiyun 	schedule_timeout(DIGI_CLOSE_TIMEOUT);
1157*4882a593Smuzhiyun 	finish_wait(&priv->dp_flush_wait, &wait);
1158*4882a593Smuzhiyun 
1159*4882a593Smuzhiyun 	/* shutdown any outstanding bulk writes */
1160*4882a593Smuzhiyun 	usb_kill_urb(port->write_urb);
1161*4882a593Smuzhiyun exit:
1162*4882a593Smuzhiyun 	spin_lock_irq(&priv->dp_port_lock);
1163*4882a593Smuzhiyun 	priv->dp_write_urb_in_use = 0;
1164*4882a593Smuzhiyun 	wake_up_interruptible(&priv->dp_close_wait);
1165*4882a593Smuzhiyun 	spin_unlock_irq(&priv->dp_port_lock);
1166*4882a593Smuzhiyun 	mutex_unlock(&port->serial->disc_mutex);
1167*4882a593Smuzhiyun }
1168*4882a593Smuzhiyun 
1169*4882a593Smuzhiyun 
1170*4882a593Smuzhiyun /*
1171*4882a593Smuzhiyun  *  Digi Startup Device
1172*4882a593Smuzhiyun  *
1173*4882a593Smuzhiyun  *  Starts reads on all ports.  Must be called AFTER startup, with
1174*4882a593Smuzhiyun  *  urbs initialized.  Returns 0 if successful, non-zero error otherwise.
1175*4882a593Smuzhiyun  */
1176*4882a593Smuzhiyun 
digi_startup_device(struct usb_serial * serial)1177*4882a593Smuzhiyun static int digi_startup_device(struct usb_serial *serial)
1178*4882a593Smuzhiyun {
1179*4882a593Smuzhiyun 	int i, ret = 0;
1180*4882a593Smuzhiyun 	struct digi_serial *serial_priv = usb_get_serial_data(serial);
1181*4882a593Smuzhiyun 	struct usb_serial_port *port;
1182*4882a593Smuzhiyun 
1183*4882a593Smuzhiyun 	/* be sure this happens exactly once */
1184*4882a593Smuzhiyun 	spin_lock(&serial_priv->ds_serial_lock);
1185*4882a593Smuzhiyun 	if (serial_priv->ds_device_started) {
1186*4882a593Smuzhiyun 		spin_unlock(&serial_priv->ds_serial_lock);
1187*4882a593Smuzhiyun 		return 0;
1188*4882a593Smuzhiyun 	}
1189*4882a593Smuzhiyun 	serial_priv->ds_device_started = 1;
1190*4882a593Smuzhiyun 	spin_unlock(&serial_priv->ds_serial_lock);
1191*4882a593Smuzhiyun 
1192*4882a593Smuzhiyun 	/* start reading from each bulk in endpoint for the device */
1193*4882a593Smuzhiyun 	/* set USB_DISABLE_SPD flag for write bulk urbs */
1194*4882a593Smuzhiyun 	for (i = 0; i < serial->type->num_ports + 1; i++) {
1195*4882a593Smuzhiyun 		port = serial->port[i];
1196*4882a593Smuzhiyun 		ret = usb_submit_urb(port->read_urb, GFP_KERNEL);
1197*4882a593Smuzhiyun 		if (ret != 0) {
1198*4882a593Smuzhiyun 			dev_err(&port->dev,
1199*4882a593Smuzhiyun 				"%s: usb_submit_urb failed, ret=%d, port=%d\n",
1200*4882a593Smuzhiyun 				__func__, ret, i);
1201*4882a593Smuzhiyun 			break;
1202*4882a593Smuzhiyun 		}
1203*4882a593Smuzhiyun 	}
1204*4882a593Smuzhiyun 	return ret;
1205*4882a593Smuzhiyun }
1206*4882a593Smuzhiyun 
digi_port_init(struct usb_serial_port * port,unsigned port_num)1207*4882a593Smuzhiyun static int digi_port_init(struct usb_serial_port *port, unsigned port_num)
1208*4882a593Smuzhiyun {
1209*4882a593Smuzhiyun 	struct digi_port *priv;
1210*4882a593Smuzhiyun 
1211*4882a593Smuzhiyun 	priv = kzalloc(sizeof(*priv), GFP_KERNEL);
1212*4882a593Smuzhiyun 	if (!priv)
1213*4882a593Smuzhiyun 		return -ENOMEM;
1214*4882a593Smuzhiyun 
1215*4882a593Smuzhiyun 	spin_lock_init(&priv->dp_port_lock);
1216*4882a593Smuzhiyun 	priv->dp_port_num = port_num;
1217*4882a593Smuzhiyun 	init_waitqueue_head(&priv->dp_transmit_idle_wait);
1218*4882a593Smuzhiyun 	init_waitqueue_head(&priv->dp_flush_wait);
1219*4882a593Smuzhiyun 	init_waitqueue_head(&priv->dp_close_wait);
1220*4882a593Smuzhiyun 	priv->dp_port = port;
1221*4882a593Smuzhiyun 
1222*4882a593Smuzhiyun 	init_waitqueue_head(&port->write_wait);
1223*4882a593Smuzhiyun 
1224*4882a593Smuzhiyun 	usb_set_serial_port_data(port, priv);
1225*4882a593Smuzhiyun 
1226*4882a593Smuzhiyun 	return 0;
1227*4882a593Smuzhiyun }
1228*4882a593Smuzhiyun 
digi_startup(struct usb_serial * serial)1229*4882a593Smuzhiyun static int digi_startup(struct usb_serial *serial)
1230*4882a593Smuzhiyun {
1231*4882a593Smuzhiyun 	struct digi_serial *serial_priv;
1232*4882a593Smuzhiyun 	int ret;
1233*4882a593Smuzhiyun 
1234*4882a593Smuzhiyun 	serial_priv = kzalloc(sizeof(*serial_priv), GFP_KERNEL);
1235*4882a593Smuzhiyun 	if (!serial_priv)
1236*4882a593Smuzhiyun 		return -ENOMEM;
1237*4882a593Smuzhiyun 
1238*4882a593Smuzhiyun 	spin_lock_init(&serial_priv->ds_serial_lock);
1239*4882a593Smuzhiyun 	serial_priv->ds_oob_port_num = serial->type->num_ports;
1240*4882a593Smuzhiyun 	serial_priv->ds_oob_port = serial->port[serial_priv->ds_oob_port_num];
1241*4882a593Smuzhiyun 
1242*4882a593Smuzhiyun 	ret = digi_port_init(serial_priv->ds_oob_port,
1243*4882a593Smuzhiyun 						serial_priv->ds_oob_port_num);
1244*4882a593Smuzhiyun 	if (ret) {
1245*4882a593Smuzhiyun 		kfree(serial_priv);
1246*4882a593Smuzhiyun 		return ret;
1247*4882a593Smuzhiyun 	}
1248*4882a593Smuzhiyun 
1249*4882a593Smuzhiyun 	usb_set_serial_data(serial, serial_priv);
1250*4882a593Smuzhiyun 
1251*4882a593Smuzhiyun 	return 0;
1252*4882a593Smuzhiyun }
1253*4882a593Smuzhiyun 
1254*4882a593Smuzhiyun 
digi_disconnect(struct usb_serial * serial)1255*4882a593Smuzhiyun static void digi_disconnect(struct usb_serial *serial)
1256*4882a593Smuzhiyun {
1257*4882a593Smuzhiyun 	int i;
1258*4882a593Smuzhiyun 
1259*4882a593Smuzhiyun 	/* stop reads and writes on all ports */
1260*4882a593Smuzhiyun 	for (i = 0; i < serial->type->num_ports + 1; i++) {
1261*4882a593Smuzhiyun 		usb_kill_urb(serial->port[i]->read_urb);
1262*4882a593Smuzhiyun 		usb_kill_urb(serial->port[i]->write_urb);
1263*4882a593Smuzhiyun 	}
1264*4882a593Smuzhiyun }
1265*4882a593Smuzhiyun 
1266*4882a593Smuzhiyun 
digi_release(struct usb_serial * serial)1267*4882a593Smuzhiyun static void digi_release(struct usb_serial *serial)
1268*4882a593Smuzhiyun {
1269*4882a593Smuzhiyun 	struct digi_serial *serial_priv;
1270*4882a593Smuzhiyun 	struct digi_port *priv;
1271*4882a593Smuzhiyun 
1272*4882a593Smuzhiyun 	serial_priv = usb_get_serial_data(serial);
1273*4882a593Smuzhiyun 
1274*4882a593Smuzhiyun 	priv = usb_get_serial_port_data(serial_priv->ds_oob_port);
1275*4882a593Smuzhiyun 	kfree(priv);
1276*4882a593Smuzhiyun 
1277*4882a593Smuzhiyun 	kfree(serial_priv);
1278*4882a593Smuzhiyun }
1279*4882a593Smuzhiyun 
digi_port_probe(struct usb_serial_port * port)1280*4882a593Smuzhiyun static int digi_port_probe(struct usb_serial_port *port)
1281*4882a593Smuzhiyun {
1282*4882a593Smuzhiyun 	return digi_port_init(port, port->port_number);
1283*4882a593Smuzhiyun }
1284*4882a593Smuzhiyun 
digi_port_remove(struct usb_serial_port * port)1285*4882a593Smuzhiyun static int digi_port_remove(struct usb_serial_port *port)
1286*4882a593Smuzhiyun {
1287*4882a593Smuzhiyun 	struct digi_port *priv;
1288*4882a593Smuzhiyun 
1289*4882a593Smuzhiyun 	priv = usb_get_serial_port_data(port);
1290*4882a593Smuzhiyun 	kfree(priv);
1291*4882a593Smuzhiyun 
1292*4882a593Smuzhiyun 	return 0;
1293*4882a593Smuzhiyun }
1294*4882a593Smuzhiyun 
digi_read_bulk_callback(struct urb * urb)1295*4882a593Smuzhiyun static void digi_read_bulk_callback(struct urb *urb)
1296*4882a593Smuzhiyun {
1297*4882a593Smuzhiyun 	struct usb_serial_port *port = urb->context;
1298*4882a593Smuzhiyun 	struct digi_port *priv;
1299*4882a593Smuzhiyun 	struct digi_serial *serial_priv;
1300*4882a593Smuzhiyun 	int ret;
1301*4882a593Smuzhiyun 	int status = urb->status;
1302*4882a593Smuzhiyun 
1303*4882a593Smuzhiyun 	/* port sanity check, do not resubmit if port is not valid */
1304*4882a593Smuzhiyun 	if (port == NULL)
1305*4882a593Smuzhiyun 		return;
1306*4882a593Smuzhiyun 	priv = usb_get_serial_port_data(port);
1307*4882a593Smuzhiyun 	if (priv == NULL) {
1308*4882a593Smuzhiyun 		dev_err(&port->dev, "%s: port->private is NULL, status=%d\n",
1309*4882a593Smuzhiyun 			__func__, status);
1310*4882a593Smuzhiyun 		return;
1311*4882a593Smuzhiyun 	}
1312*4882a593Smuzhiyun 	if (port->serial == NULL ||
1313*4882a593Smuzhiyun 		(serial_priv = usb_get_serial_data(port->serial)) == NULL) {
1314*4882a593Smuzhiyun 		dev_err(&port->dev, "%s: serial is bad or serial->private "
1315*4882a593Smuzhiyun 			"is NULL, status=%d\n", __func__, status);
1316*4882a593Smuzhiyun 		return;
1317*4882a593Smuzhiyun 	}
1318*4882a593Smuzhiyun 
1319*4882a593Smuzhiyun 	/* do not resubmit urb if it has any status error */
1320*4882a593Smuzhiyun 	if (status) {
1321*4882a593Smuzhiyun 		dev_err(&port->dev,
1322*4882a593Smuzhiyun 			"%s: nonzero read bulk status: status=%d, port=%d\n",
1323*4882a593Smuzhiyun 			__func__, status, priv->dp_port_num);
1324*4882a593Smuzhiyun 		return;
1325*4882a593Smuzhiyun 	}
1326*4882a593Smuzhiyun 
1327*4882a593Smuzhiyun 	/* handle oob or inb callback, do not resubmit if error */
1328*4882a593Smuzhiyun 	if (priv->dp_port_num == serial_priv->ds_oob_port_num) {
1329*4882a593Smuzhiyun 		if (digi_read_oob_callback(urb) != 0)
1330*4882a593Smuzhiyun 			return;
1331*4882a593Smuzhiyun 	} else {
1332*4882a593Smuzhiyun 		if (digi_read_inb_callback(urb) != 0)
1333*4882a593Smuzhiyun 			return;
1334*4882a593Smuzhiyun 	}
1335*4882a593Smuzhiyun 
1336*4882a593Smuzhiyun 	/* continue read */
1337*4882a593Smuzhiyun 	ret = usb_submit_urb(urb, GFP_ATOMIC);
1338*4882a593Smuzhiyun 	if (ret != 0 && ret != -EPERM) {
1339*4882a593Smuzhiyun 		dev_err(&port->dev,
1340*4882a593Smuzhiyun 			"%s: failed resubmitting urb, ret=%d, port=%d\n",
1341*4882a593Smuzhiyun 			__func__, ret, priv->dp_port_num);
1342*4882a593Smuzhiyun 	}
1343*4882a593Smuzhiyun 
1344*4882a593Smuzhiyun }
1345*4882a593Smuzhiyun 
1346*4882a593Smuzhiyun /*
1347*4882a593Smuzhiyun  *  Digi Read INB Callback
1348*4882a593Smuzhiyun  *
1349*4882a593Smuzhiyun  *  Digi Read INB Callback handles reads on the in band ports, sending
1350*4882a593Smuzhiyun  *  the data on to the tty subsystem.  When called we know port and
1351*4882a593Smuzhiyun  *  port->private are not NULL and port->serial has been validated.
1352*4882a593Smuzhiyun  *  It returns 0 if successful, 1 if successful but the port is
1353*4882a593Smuzhiyun  *  throttled, and -1 if the sanity checks failed.
1354*4882a593Smuzhiyun  */
1355*4882a593Smuzhiyun 
digi_read_inb_callback(struct urb * urb)1356*4882a593Smuzhiyun static int digi_read_inb_callback(struct urb *urb)
1357*4882a593Smuzhiyun {
1358*4882a593Smuzhiyun 	struct usb_serial_port *port = urb->context;
1359*4882a593Smuzhiyun 	struct digi_port *priv = usb_get_serial_port_data(port);
1360*4882a593Smuzhiyun 	unsigned char *buf = urb->transfer_buffer;
1361*4882a593Smuzhiyun 	unsigned long flags;
1362*4882a593Smuzhiyun 	int opcode;
1363*4882a593Smuzhiyun 	int len;
1364*4882a593Smuzhiyun 	int port_status;
1365*4882a593Smuzhiyun 	unsigned char *data;
1366*4882a593Smuzhiyun 	int tty_flag, throttled;
1367*4882a593Smuzhiyun 
1368*4882a593Smuzhiyun 	/* short/multiple packet check */
1369*4882a593Smuzhiyun 	if (urb->actual_length < 2) {
1370*4882a593Smuzhiyun 		dev_warn(&port->dev, "short packet received\n");
1371*4882a593Smuzhiyun 		return -1;
1372*4882a593Smuzhiyun 	}
1373*4882a593Smuzhiyun 
1374*4882a593Smuzhiyun 	opcode = buf[0];
1375*4882a593Smuzhiyun 	len = buf[1];
1376*4882a593Smuzhiyun 
1377*4882a593Smuzhiyun 	if (urb->actual_length != len + 2) {
1378*4882a593Smuzhiyun 		dev_err(&port->dev, "malformed packet received: port=%d, opcode=%d, len=%d, actual_length=%u\n",
1379*4882a593Smuzhiyun 			priv->dp_port_num, opcode, len, urb->actual_length);
1380*4882a593Smuzhiyun 		return -1;
1381*4882a593Smuzhiyun 	}
1382*4882a593Smuzhiyun 
1383*4882a593Smuzhiyun 	if (opcode == DIGI_CMD_RECEIVE_DATA && len < 1) {
1384*4882a593Smuzhiyun 		dev_err(&port->dev, "malformed data packet received\n");
1385*4882a593Smuzhiyun 		return -1;
1386*4882a593Smuzhiyun 	}
1387*4882a593Smuzhiyun 
1388*4882a593Smuzhiyun 	spin_lock_irqsave(&priv->dp_port_lock, flags);
1389*4882a593Smuzhiyun 
1390*4882a593Smuzhiyun 	/* check for throttle; if set, do not resubmit read urb */
1391*4882a593Smuzhiyun 	/* indicate the read chain needs to be restarted on unthrottle */
1392*4882a593Smuzhiyun 	throttled = priv->dp_throttled;
1393*4882a593Smuzhiyun 	if (throttled)
1394*4882a593Smuzhiyun 		priv->dp_throttle_restart = 1;
1395*4882a593Smuzhiyun 
1396*4882a593Smuzhiyun 	/* receive data */
1397*4882a593Smuzhiyun 	if (opcode == DIGI_CMD_RECEIVE_DATA) {
1398*4882a593Smuzhiyun 		port_status = buf[2];
1399*4882a593Smuzhiyun 		data = &buf[3];
1400*4882a593Smuzhiyun 
1401*4882a593Smuzhiyun 		/* get flag from port_status */
1402*4882a593Smuzhiyun 		tty_flag = 0;
1403*4882a593Smuzhiyun 
1404*4882a593Smuzhiyun 		/* overrun is special, not associated with a char */
1405*4882a593Smuzhiyun 		if (port_status & DIGI_OVERRUN_ERROR)
1406*4882a593Smuzhiyun 			tty_insert_flip_char(&port->port, 0, TTY_OVERRUN);
1407*4882a593Smuzhiyun 
1408*4882a593Smuzhiyun 		/* break takes precedence over parity, */
1409*4882a593Smuzhiyun 		/* which takes precedence over framing errors */
1410*4882a593Smuzhiyun 		if (port_status & DIGI_BREAK_ERROR)
1411*4882a593Smuzhiyun 			tty_flag = TTY_BREAK;
1412*4882a593Smuzhiyun 		else if (port_status & DIGI_PARITY_ERROR)
1413*4882a593Smuzhiyun 			tty_flag = TTY_PARITY;
1414*4882a593Smuzhiyun 		else if (port_status & DIGI_FRAMING_ERROR)
1415*4882a593Smuzhiyun 			tty_flag = TTY_FRAME;
1416*4882a593Smuzhiyun 
1417*4882a593Smuzhiyun 		/* data length is len-1 (one byte of len is port_status) */
1418*4882a593Smuzhiyun 		--len;
1419*4882a593Smuzhiyun 		if (len > 0) {
1420*4882a593Smuzhiyun 			tty_insert_flip_string_fixed_flag(&port->port, data,
1421*4882a593Smuzhiyun 					tty_flag, len);
1422*4882a593Smuzhiyun 			tty_flip_buffer_push(&port->port);
1423*4882a593Smuzhiyun 		}
1424*4882a593Smuzhiyun 	}
1425*4882a593Smuzhiyun 	spin_unlock_irqrestore(&priv->dp_port_lock, flags);
1426*4882a593Smuzhiyun 
1427*4882a593Smuzhiyun 	if (opcode == DIGI_CMD_RECEIVE_DISABLE)
1428*4882a593Smuzhiyun 		dev_dbg(&port->dev, "%s: got RECEIVE_DISABLE\n", __func__);
1429*4882a593Smuzhiyun 	else if (opcode != DIGI_CMD_RECEIVE_DATA)
1430*4882a593Smuzhiyun 		dev_dbg(&port->dev, "%s: unknown opcode: %d\n", __func__, opcode);
1431*4882a593Smuzhiyun 
1432*4882a593Smuzhiyun 	return throttled ? 1 : 0;
1433*4882a593Smuzhiyun 
1434*4882a593Smuzhiyun }
1435*4882a593Smuzhiyun 
1436*4882a593Smuzhiyun 
1437*4882a593Smuzhiyun /*
1438*4882a593Smuzhiyun  *  Digi Read OOB Callback
1439*4882a593Smuzhiyun  *
1440*4882a593Smuzhiyun  *  Digi Read OOB Callback handles reads on the out of band port.
1441*4882a593Smuzhiyun  *  When called we know port and port->private are not NULL and
1442*4882a593Smuzhiyun  *  the port->serial is valid.  It returns 0 if successful, and
1443*4882a593Smuzhiyun  *  -1 if the sanity checks failed.
1444*4882a593Smuzhiyun  */
1445*4882a593Smuzhiyun 
digi_read_oob_callback(struct urb * urb)1446*4882a593Smuzhiyun static int digi_read_oob_callback(struct urb *urb)
1447*4882a593Smuzhiyun {
1448*4882a593Smuzhiyun 
1449*4882a593Smuzhiyun 	struct usb_serial_port *port = urb->context;
1450*4882a593Smuzhiyun 	struct usb_serial *serial = port->serial;
1451*4882a593Smuzhiyun 	struct tty_struct *tty;
1452*4882a593Smuzhiyun 	struct digi_port *priv;
1453*4882a593Smuzhiyun 	unsigned char *buf = urb->transfer_buffer;
1454*4882a593Smuzhiyun 	int opcode, line, status, val;
1455*4882a593Smuzhiyun 	unsigned long flags;
1456*4882a593Smuzhiyun 	int i;
1457*4882a593Smuzhiyun 	unsigned int rts;
1458*4882a593Smuzhiyun 
1459*4882a593Smuzhiyun 	if (urb->actual_length < 4)
1460*4882a593Smuzhiyun 		return -1;
1461*4882a593Smuzhiyun 
1462*4882a593Smuzhiyun 	/* handle each oob command */
1463*4882a593Smuzhiyun 	for (i = 0; i < urb->actual_length - 3; i += 4) {
1464*4882a593Smuzhiyun 		opcode = buf[i];
1465*4882a593Smuzhiyun 		line = buf[i + 1];
1466*4882a593Smuzhiyun 		status = buf[i + 2];
1467*4882a593Smuzhiyun 		val = buf[i + 3];
1468*4882a593Smuzhiyun 
1469*4882a593Smuzhiyun 		dev_dbg(&port->dev, "digi_read_oob_callback: opcode=%d, line=%d, status=%d, val=%d\n",
1470*4882a593Smuzhiyun 			opcode, line, status, val);
1471*4882a593Smuzhiyun 
1472*4882a593Smuzhiyun 		if (status != 0 || line >= serial->type->num_ports)
1473*4882a593Smuzhiyun 			continue;
1474*4882a593Smuzhiyun 
1475*4882a593Smuzhiyun 		port = serial->port[line];
1476*4882a593Smuzhiyun 
1477*4882a593Smuzhiyun 		priv = usb_get_serial_port_data(port);
1478*4882a593Smuzhiyun 		if (priv == NULL)
1479*4882a593Smuzhiyun 			return -1;
1480*4882a593Smuzhiyun 
1481*4882a593Smuzhiyun 		tty = tty_port_tty_get(&port->port);
1482*4882a593Smuzhiyun 
1483*4882a593Smuzhiyun 		rts = 0;
1484*4882a593Smuzhiyun 		if (tty)
1485*4882a593Smuzhiyun 			rts = C_CRTSCTS(tty);
1486*4882a593Smuzhiyun 
1487*4882a593Smuzhiyun 		if (tty && opcode == DIGI_CMD_READ_INPUT_SIGNALS) {
1488*4882a593Smuzhiyun 			bool wakeup = false;
1489*4882a593Smuzhiyun 
1490*4882a593Smuzhiyun 			spin_lock_irqsave(&priv->dp_port_lock, flags);
1491*4882a593Smuzhiyun 			/* convert from digi flags to termiox flags */
1492*4882a593Smuzhiyun 			if (val & DIGI_READ_INPUT_SIGNALS_CTS) {
1493*4882a593Smuzhiyun 				priv->dp_modem_signals |= TIOCM_CTS;
1494*4882a593Smuzhiyun 				if (rts)
1495*4882a593Smuzhiyun 					wakeup = true;
1496*4882a593Smuzhiyun 			} else {
1497*4882a593Smuzhiyun 				priv->dp_modem_signals &= ~TIOCM_CTS;
1498*4882a593Smuzhiyun 				/* port must be open to use tty struct */
1499*4882a593Smuzhiyun 			}
1500*4882a593Smuzhiyun 			if (val & DIGI_READ_INPUT_SIGNALS_DSR)
1501*4882a593Smuzhiyun 				priv->dp_modem_signals |= TIOCM_DSR;
1502*4882a593Smuzhiyun 			else
1503*4882a593Smuzhiyun 				priv->dp_modem_signals &= ~TIOCM_DSR;
1504*4882a593Smuzhiyun 			if (val & DIGI_READ_INPUT_SIGNALS_RI)
1505*4882a593Smuzhiyun 				priv->dp_modem_signals |= TIOCM_RI;
1506*4882a593Smuzhiyun 			else
1507*4882a593Smuzhiyun 				priv->dp_modem_signals &= ~TIOCM_RI;
1508*4882a593Smuzhiyun 			if (val & DIGI_READ_INPUT_SIGNALS_DCD)
1509*4882a593Smuzhiyun 				priv->dp_modem_signals |= TIOCM_CD;
1510*4882a593Smuzhiyun 			else
1511*4882a593Smuzhiyun 				priv->dp_modem_signals &= ~TIOCM_CD;
1512*4882a593Smuzhiyun 
1513*4882a593Smuzhiyun 			spin_unlock_irqrestore(&priv->dp_port_lock, flags);
1514*4882a593Smuzhiyun 
1515*4882a593Smuzhiyun 			if (wakeup)
1516*4882a593Smuzhiyun 				tty_port_tty_wakeup(&port->port);
1517*4882a593Smuzhiyun 		} else if (opcode == DIGI_CMD_TRANSMIT_IDLE) {
1518*4882a593Smuzhiyun 			spin_lock_irqsave(&priv->dp_port_lock, flags);
1519*4882a593Smuzhiyun 			priv->dp_transmit_idle = 1;
1520*4882a593Smuzhiyun 			wake_up_interruptible(&priv->dp_transmit_idle_wait);
1521*4882a593Smuzhiyun 			spin_unlock_irqrestore(&priv->dp_port_lock, flags);
1522*4882a593Smuzhiyun 		} else if (opcode == DIGI_CMD_IFLUSH_FIFO) {
1523*4882a593Smuzhiyun 			wake_up_interruptible(&priv->dp_flush_wait);
1524*4882a593Smuzhiyun 		}
1525*4882a593Smuzhiyun 		tty_kref_put(tty);
1526*4882a593Smuzhiyun 	}
1527*4882a593Smuzhiyun 	return 0;
1528*4882a593Smuzhiyun 
1529*4882a593Smuzhiyun }
1530*4882a593Smuzhiyun 
1531*4882a593Smuzhiyun module_usb_serial_driver(serial_drivers, id_table_combined);
1532*4882a593Smuzhiyun 
1533*4882a593Smuzhiyun MODULE_AUTHOR(DRIVER_AUTHOR);
1534*4882a593Smuzhiyun MODULE_DESCRIPTION(DRIVER_DESC);
1535*4882a593Smuzhiyun MODULE_LICENSE("GPL");
1536