1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun * USB Serial Converter Generic functions
4*4882a593Smuzhiyun *
5*4882a593Smuzhiyun * Copyright (C) 2010 - 2013 Johan Hovold (jhovold@gmail.com)
6*4882a593Smuzhiyun * Copyright (C) 1999 - 2002 Greg Kroah-Hartman (greg@kroah.com)
7*4882a593Smuzhiyun */
8*4882a593Smuzhiyun
9*4882a593Smuzhiyun #include <linux/kernel.h>
10*4882a593Smuzhiyun #include <linux/sched/signal.h>
11*4882a593Smuzhiyun #include <linux/errno.h>
12*4882a593Smuzhiyun #include <linux/slab.h>
13*4882a593Smuzhiyun #include <linux/sysrq.h>
14*4882a593Smuzhiyun #include <linux/tty.h>
15*4882a593Smuzhiyun #include <linux/tty_flip.h>
16*4882a593Smuzhiyun #include <linux/module.h>
17*4882a593Smuzhiyun #include <linux/moduleparam.h>
18*4882a593Smuzhiyun #include <linux/usb.h>
19*4882a593Smuzhiyun #include <linux/usb/serial.h>
20*4882a593Smuzhiyun #include <linux/uaccess.h>
21*4882a593Smuzhiyun #include <linux/kfifo.h>
22*4882a593Smuzhiyun #include <linux/serial.h>
23*4882a593Smuzhiyun
24*4882a593Smuzhiyun #ifdef CONFIG_USB_SERIAL_GENERIC
25*4882a593Smuzhiyun
26*4882a593Smuzhiyun static __u16 vendor = 0x05f9;
27*4882a593Smuzhiyun static __u16 product = 0xffff;
28*4882a593Smuzhiyun
29*4882a593Smuzhiyun module_param(vendor, ushort, 0);
30*4882a593Smuzhiyun MODULE_PARM_DESC(vendor, "User specified USB idVendor");
31*4882a593Smuzhiyun
32*4882a593Smuzhiyun module_param(product, ushort, 0);
33*4882a593Smuzhiyun MODULE_PARM_DESC(product, "User specified USB idProduct");
34*4882a593Smuzhiyun
35*4882a593Smuzhiyun static struct usb_device_id generic_device_ids[2]; /* Initially all zeroes. */
36*4882a593Smuzhiyun
usb_serial_generic_probe(struct usb_serial * serial,const struct usb_device_id * id)37*4882a593Smuzhiyun static int usb_serial_generic_probe(struct usb_serial *serial,
38*4882a593Smuzhiyun const struct usb_device_id *id)
39*4882a593Smuzhiyun {
40*4882a593Smuzhiyun struct device *dev = &serial->interface->dev;
41*4882a593Smuzhiyun
42*4882a593Smuzhiyun dev_info(dev, "The \"generic\" usb-serial driver is only for testing and one-off prototypes.\n");
43*4882a593Smuzhiyun dev_info(dev, "Tell linux-usb@vger.kernel.org to add your device to a proper driver.\n");
44*4882a593Smuzhiyun
45*4882a593Smuzhiyun return 0;
46*4882a593Smuzhiyun }
47*4882a593Smuzhiyun
usb_serial_generic_calc_num_ports(struct usb_serial * serial,struct usb_serial_endpoints * epds)48*4882a593Smuzhiyun static int usb_serial_generic_calc_num_ports(struct usb_serial *serial,
49*4882a593Smuzhiyun struct usb_serial_endpoints *epds)
50*4882a593Smuzhiyun {
51*4882a593Smuzhiyun struct device *dev = &serial->interface->dev;
52*4882a593Smuzhiyun int num_ports;
53*4882a593Smuzhiyun
54*4882a593Smuzhiyun num_ports = max(epds->num_bulk_in, epds->num_bulk_out);
55*4882a593Smuzhiyun
56*4882a593Smuzhiyun if (num_ports == 0) {
57*4882a593Smuzhiyun dev_err(dev, "device has no bulk endpoints\n");
58*4882a593Smuzhiyun return -ENODEV;
59*4882a593Smuzhiyun }
60*4882a593Smuzhiyun
61*4882a593Smuzhiyun return num_ports;
62*4882a593Smuzhiyun }
63*4882a593Smuzhiyun
64*4882a593Smuzhiyun static struct usb_serial_driver usb_serial_generic_device = {
65*4882a593Smuzhiyun .driver = {
66*4882a593Smuzhiyun .owner = THIS_MODULE,
67*4882a593Smuzhiyun .name = "generic",
68*4882a593Smuzhiyun },
69*4882a593Smuzhiyun .id_table = generic_device_ids,
70*4882a593Smuzhiyun .probe = usb_serial_generic_probe,
71*4882a593Smuzhiyun .calc_num_ports = usb_serial_generic_calc_num_ports,
72*4882a593Smuzhiyun .throttle = usb_serial_generic_throttle,
73*4882a593Smuzhiyun .unthrottle = usb_serial_generic_unthrottle,
74*4882a593Smuzhiyun .resume = usb_serial_generic_resume,
75*4882a593Smuzhiyun };
76*4882a593Smuzhiyun
77*4882a593Smuzhiyun static struct usb_serial_driver * const serial_drivers[] = {
78*4882a593Smuzhiyun &usb_serial_generic_device, NULL
79*4882a593Smuzhiyun };
80*4882a593Smuzhiyun
81*4882a593Smuzhiyun #endif
82*4882a593Smuzhiyun
usb_serial_generic_register(void)83*4882a593Smuzhiyun int usb_serial_generic_register(void)
84*4882a593Smuzhiyun {
85*4882a593Smuzhiyun int retval = 0;
86*4882a593Smuzhiyun
87*4882a593Smuzhiyun #ifdef CONFIG_USB_SERIAL_GENERIC
88*4882a593Smuzhiyun generic_device_ids[0].idVendor = vendor;
89*4882a593Smuzhiyun generic_device_ids[0].idProduct = product;
90*4882a593Smuzhiyun generic_device_ids[0].match_flags =
91*4882a593Smuzhiyun USB_DEVICE_ID_MATCH_VENDOR | USB_DEVICE_ID_MATCH_PRODUCT;
92*4882a593Smuzhiyun
93*4882a593Smuzhiyun retval = usb_serial_register_drivers(serial_drivers,
94*4882a593Smuzhiyun "usbserial_generic", generic_device_ids);
95*4882a593Smuzhiyun #endif
96*4882a593Smuzhiyun return retval;
97*4882a593Smuzhiyun }
98*4882a593Smuzhiyun
usb_serial_generic_deregister(void)99*4882a593Smuzhiyun void usb_serial_generic_deregister(void)
100*4882a593Smuzhiyun {
101*4882a593Smuzhiyun #ifdef CONFIG_USB_SERIAL_GENERIC
102*4882a593Smuzhiyun usb_serial_deregister_drivers(serial_drivers);
103*4882a593Smuzhiyun #endif
104*4882a593Smuzhiyun }
105*4882a593Smuzhiyun
usb_serial_generic_open(struct tty_struct * tty,struct usb_serial_port * port)106*4882a593Smuzhiyun int usb_serial_generic_open(struct tty_struct *tty, struct usb_serial_port *port)
107*4882a593Smuzhiyun {
108*4882a593Smuzhiyun int result = 0;
109*4882a593Smuzhiyun
110*4882a593Smuzhiyun clear_bit(USB_SERIAL_THROTTLED, &port->flags);
111*4882a593Smuzhiyun
112*4882a593Smuzhiyun if (port->bulk_in_size)
113*4882a593Smuzhiyun result = usb_serial_generic_submit_read_urbs(port, GFP_KERNEL);
114*4882a593Smuzhiyun
115*4882a593Smuzhiyun return result;
116*4882a593Smuzhiyun }
117*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(usb_serial_generic_open);
118*4882a593Smuzhiyun
usb_serial_generic_close(struct usb_serial_port * port)119*4882a593Smuzhiyun void usb_serial_generic_close(struct usb_serial_port *port)
120*4882a593Smuzhiyun {
121*4882a593Smuzhiyun unsigned long flags;
122*4882a593Smuzhiyun int i;
123*4882a593Smuzhiyun
124*4882a593Smuzhiyun if (port->bulk_out_size) {
125*4882a593Smuzhiyun for (i = 0; i < ARRAY_SIZE(port->write_urbs); ++i)
126*4882a593Smuzhiyun usb_kill_urb(port->write_urbs[i]);
127*4882a593Smuzhiyun
128*4882a593Smuzhiyun spin_lock_irqsave(&port->lock, flags);
129*4882a593Smuzhiyun kfifo_reset_out(&port->write_fifo);
130*4882a593Smuzhiyun spin_unlock_irqrestore(&port->lock, flags);
131*4882a593Smuzhiyun }
132*4882a593Smuzhiyun if (port->bulk_in_size) {
133*4882a593Smuzhiyun for (i = 0; i < ARRAY_SIZE(port->read_urbs); ++i)
134*4882a593Smuzhiyun usb_kill_urb(port->read_urbs[i]);
135*4882a593Smuzhiyun }
136*4882a593Smuzhiyun }
137*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(usb_serial_generic_close);
138*4882a593Smuzhiyun
usb_serial_generic_prepare_write_buffer(struct usb_serial_port * port,void * dest,size_t size)139*4882a593Smuzhiyun int usb_serial_generic_prepare_write_buffer(struct usb_serial_port *port,
140*4882a593Smuzhiyun void *dest, size_t size)
141*4882a593Smuzhiyun {
142*4882a593Smuzhiyun return kfifo_out_locked(&port->write_fifo, dest, size, &port->lock);
143*4882a593Smuzhiyun }
144*4882a593Smuzhiyun
145*4882a593Smuzhiyun /**
146*4882a593Smuzhiyun * usb_serial_generic_write_start - start writing buffered data
147*4882a593Smuzhiyun * @port: usb-serial port
148*4882a593Smuzhiyun * @mem_flags: flags to use for memory allocations
149*4882a593Smuzhiyun *
150*4882a593Smuzhiyun * Serialised using USB_SERIAL_WRITE_BUSY flag.
151*4882a593Smuzhiyun *
152*4882a593Smuzhiyun * Return: Zero on success or if busy, otherwise a negative errno value.
153*4882a593Smuzhiyun */
usb_serial_generic_write_start(struct usb_serial_port * port,gfp_t mem_flags)154*4882a593Smuzhiyun int usb_serial_generic_write_start(struct usb_serial_port *port,
155*4882a593Smuzhiyun gfp_t mem_flags)
156*4882a593Smuzhiyun {
157*4882a593Smuzhiyun struct urb *urb;
158*4882a593Smuzhiyun int count, result;
159*4882a593Smuzhiyun unsigned long flags;
160*4882a593Smuzhiyun int i;
161*4882a593Smuzhiyun
162*4882a593Smuzhiyun if (test_and_set_bit_lock(USB_SERIAL_WRITE_BUSY, &port->flags))
163*4882a593Smuzhiyun return 0;
164*4882a593Smuzhiyun retry:
165*4882a593Smuzhiyun spin_lock_irqsave(&port->lock, flags);
166*4882a593Smuzhiyun if (!port->write_urbs_free || !kfifo_len(&port->write_fifo)) {
167*4882a593Smuzhiyun clear_bit_unlock(USB_SERIAL_WRITE_BUSY, &port->flags);
168*4882a593Smuzhiyun spin_unlock_irqrestore(&port->lock, flags);
169*4882a593Smuzhiyun return 0;
170*4882a593Smuzhiyun }
171*4882a593Smuzhiyun i = (int)find_first_bit(&port->write_urbs_free,
172*4882a593Smuzhiyun ARRAY_SIZE(port->write_urbs));
173*4882a593Smuzhiyun spin_unlock_irqrestore(&port->lock, flags);
174*4882a593Smuzhiyun
175*4882a593Smuzhiyun urb = port->write_urbs[i];
176*4882a593Smuzhiyun count = port->serial->type->prepare_write_buffer(port,
177*4882a593Smuzhiyun urb->transfer_buffer,
178*4882a593Smuzhiyun port->bulk_out_size);
179*4882a593Smuzhiyun urb->transfer_buffer_length = count;
180*4882a593Smuzhiyun usb_serial_debug_data(&port->dev, __func__, count, urb->transfer_buffer);
181*4882a593Smuzhiyun spin_lock_irqsave(&port->lock, flags);
182*4882a593Smuzhiyun port->tx_bytes += count;
183*4882a593Smuzhiyun spin_unlock_irqrestore(&port->lock, flags);
184*4882a593Smuzhiyun
185*4882a593Smuzhiyun clear_bit(i, &port->write_urbs_free);
186*4882a593Smuzhiyun result = usb_submit_urb(urb, mem_flags);
187*4882a593Smuzhiyun if (result) {
188*4882a593Smuzhiyun dev_err_console(port, "%s - error submitting urb: %d\n",
189*4882a593Smuzhiyun __func__, result);
190*4882a593Smuzhiyun set_bit(i, &port->write_urbs_free);
191*4882a593Smuzhiyun spin_lock_irqsave(&port->lock, flags);
192*4882a593Smuzhiyun port->tx_bytes -= count;
193*4882a593Smuzhiyun spin_unlock_irqrestore(&port->lock, flags);
194*4882a593Smuzhiyun
195*4882a593Smuzhiyun clear_bit_unlock(USB_SERIAL_WRITE_BUSY, &port->flags);
196*4882a593Smuzhiyun return result;
197*4882a593Smuzhiyun }
198*4882a593Smuzhiyun
199*4882a593Smuzhiyun goto retry; /* try sending off another urb */
200*4882a593Smuzhiyun }
201*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(usb_serial_generic_write_start);
202*4882a593Smuzhiyun
203*4882a593Smuzhiyun /**
204*4882a593Smuzhiyun * usb_serial_generic_write - generic write function
205*4882a593Smuzhiyun * @tty: tty for the port
206*4882a593Smuzhiyun * @port: usb-serial port
207*4882a593Smuzhiyun * @buf: data to write
208*4882a593Smuzhiyun * @count: number of bytes to write
209*4882a593Smuzhiyun *
210*4882a593Smuzhiyun * Return: The number of characters buffered, which may be anything from
211*4882a593Smuzhiyun * zero to @count, or a negative errno value.
212*4882a593Smuzhiyun */
usb_serial_generic_write(struct tty_struct * tty,struct usb_serial_port * port,const unsigned char * buf,int count)213*4882a593Smuzhiyun int usb_serial_generic_write(struct tty_struct *tty,
214*4882a593Smuzhiyun struct usb_serial_port *port, const unsigned char *buf, int count)
215*4882a593Smuzhiyun {
216*4882a593Smuzhiyun int result;
217*4882a593Smuzhiyun
218*4882a593Smuzhiyun if (!port->bulk_out_size)
219*4882a593Smuzhiyun return -ENODEV;
220*4882a593Smuzhiyun
221*4882a593Smuzhiyun if (!count)
222*4882a593Smuzhiyun return 0;
223*4882a593Smuzhiyun
224*4882a593Smuzhiyun count = kfifo_in_locked(&port->write_fifo, buf, count, &port->lock);
225*4882a593Smuzhiyun result = usb_serial_generic_write_start(port, GFP_ATOMIC);
226*4882a593Smuzhiyun if (result)
227*4882a593Smuzhiyun return result;
228*4882a593Smuzhiyun
229*4882a593Smuzhiyun return count;
230*4882a593Smuzhiyun }
231*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(usb_serial_generic_write);
232*4882a593Smuzhiyun
usb_serial_generic_write_room(struct tty_struct * tty)233*4882a593Smuzhiyun int usb_serial_generic_write_room(struct tty_struct *tty)
234*4882a593Smuzhiyun {
235*4882a593Smuzhiyun struct usb_serial_port *port = tty->driver_data;
236*4882a593Smuzhiyun unsigned long flags;
237*4882a593Smuzhiyun int room;
238*4882a593Smuzhiyun
239*4882a593Smuzhiyun if (!port->bulk_out_size)
240*4882a593Smuzhiyun return 0;
241*4882a593Smuzhiyun
242*4882a593Smuzhiyun spin_lock_irqsave(&port->lock, flags);
243*4882a593Smuzhiyun room = kfifo_avail(&port->write_fifo);
244*4882a593Smuzhiyun spin_unlock_irqrestore(&port->lock, flags);
245*4882a593Smuzhiyun
246*4882a593Smuzhiyun dev_dbg(&port->dev, "%s - returns %d\n", __func__, room);
247*4882a593Smuzhiyun return room;
248*4882a593Smuzhiyun }
249*4882a593Smuzhiyun
usb_serial_generic_chars_in_buffer(struct tty_struct * tty)250*4882a593Smuzhiyun int usb_serial_generic_chars_in_buffer(struct tty_struct *tty)
251*4882a593Smuzhiyun {
252*4882a593Smuzhiyun struct usb_serial_port *port = tty->driver_data;
253*4882a593Smuzhiyun unsigned long flags;
254*4882a593Smuzhiyun int chars;
255*4882a593Smuzhiyun
256*4882a593Smuzhiyun if (!port->bulk_out_size)
257*4882a593Smuzhiyun return 0;
258*4882a593Smuzhiyun
259*4882a593Smuzhiyun spin_lock_irqsave(&port->lock, flags);
260*4882a593Smuzhiyun chars = kfifo_len(&port->write_fifo) + port->tx_bytes;
261*4882a593Smuzhiyun spin_unlock_irqrestore(&port->lock, flags);
262*4882a593Smuzhiyun
263*4882a593Smuzhiyun dev_dbg(&port->dev, "%s - returns %d\n", __func__, chars);
264*4882a593Smuzhiyun return chars;
265*4882a593Smuzhiyun }
266*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(usb_serial_generic_chars_in_buffer);
267*4882a593Smuzhiyun
usb_serial_generic_wait_until_sent(struct tty_struct * tty,long timeout)268*4882a593Smuzhiyun void usb_serial_generic_wait_until_sent(struct tty_struct *tty, long timeout)
269*4882a593Smuzhiyun {
270*4882a593Smuzhiyun struct usb_serial_port *port = tty->driver_data;
271*4882a593Smuzhiyun unsigned int bps;
272*4882a593Smuzhiyun unsigned long period;
273*4882a593Smuzhiyun unsigned long expire;
274*4882a593Smuzhiyun
275*4882a593Smuzhiyun bps = tty_get_baud_rate(tty);
276*4882a593Smuzhiyun if (!bps)
277*4882a593Smuzhiyun bps = 9600; /* B0 */
278*4882a593Smuzhiyun /*
279*4882a593Smuzhiyun * Use a poll-period of roughly the time it takes to send one
280*4882a593Smuzhiyun * character or at least one jiffy.
281*4882a593Smuzhiyun */
282*4882a593Smuzhiyun period = max_t(unsigned long, (10 * HZ / bps), 1);
283*4882a593Smuzhiyun if (timeout)
284*4882a593Smuzhiyun period = min_t(unsigned long, period, timeout);
285*4882a593Smuzhiyun
286*4882a593Smuzhiyun dev_dbg(&port->dev, "%s - timeout = %u ms, period = %u ms\n",
287*4882a593Smuzhiyun __func__, jiffies_to_msecs(timeout),
288*4882a593Smuzhiyun jiffies_to_msecs(period));
289*4882a593Smuzhiyun expire = jiffies + timeout;
290*4882a593Smuzhiyun while (!port->serial->type->tx_empty(port)) {
291*4882a593Smuzhiyun schedule_timeout_interruptible(period);
292*4882a593Smuzhiyun if (signal_pending(current))
293*4882a593Smuzhiyun break;
294*4882a593Smuzhiyun if (timeout && time_after(jiffies, expire))
295*4882a593Smuzhiyun break;
296*4882a593Smuzhiyun }
297*4882a593Smuzhiyun }
298*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(usb_serial_generic_wait_until_sent);
299*4882a593Smuzhiyun
usb_serial_generic_submit_read_urb(struct usb_serial_port * port,int index,gfp_t mem_flags)300*4882a593Smuzhiyun static int usb_serial_generic_submit_read_urb(struct usb_serial_port *port,
301*4882a593Smuzhiyun int index, gfp_t mem_flags)
302*4882a593Smuzhiyun {
303*4882a593Smuzhiyun int res;
304*4882a593Smuzhiyun
305*4882a593Smuzhiyun if (!test_and_clear_bit(index, &port->read_urbs_free))
306*4882a593Smuzhiyun return 0;
307*4882a593Smuzhiyun
308*4882a593Smuzhiyun dev_dbg(&port->dev, "%s - urb %d\n", __func__, index);
309*4882a593Smuzhiyun
310*4882a593Smuzhiyun res = usb_submit_urb(port->read_urbs[index], mem_flags);
311*4882a593Smuzhiyun if (res) {
312*4882a593Smuzhiyun if (res != -EPERM && res != -ENODEV) {
313*4882a593Smuzhiyun dev_err(&port->dev,
314*4882a593Smuzhiyun "%s - usb_submit_urb failed: %d\n",
315*4882a593Smuzhiyun __func__, res);
316*4882a593Smuzhiyun }
317*4882a593Smuzhiyun set_bit(index, &port->read_urbs_free);
318*4882a593Smuzhiyun return res;
319*4882a593Smuzhiyun }
320*4882a593Smuzhiyun
321*4882a593Smuzhiyun return 0;
322*4882a593Smuzhiyun }
323*4882a593Smuzhiyun
usb_serial_generic_submit_read_urbs(struct usb_serial_port * port,gfp_t mem_flags)324*4882a593Smuzhiyun int usb_serial_generic_submit_read_urbs(struct usb_serial_port *port,
325*4882a593Smuzhiyun gfp_t mem_flags)
326*4882a593Smuzhiyun {
327*4882a593Smuzhiyun int res;
328*4882a593Smuzhiyun int i;
329*4882a593Smuzhiyun
330*4882a593Smuzhiyun for (i = 0; i < ARRAY_SIZE(port->read_urbs); ++i) {
331*4882a593Smuzhiyun res = usb_serial_generic_submit_read_urb(port, i, mem_flags);
332*4882a593Smuzhiyun if (res)
333*4882a593Smuzhiyun goto err;
334*4882a593Smuzhiyun }
335*4882a593Smuzhiyun
336*4882a593Smuzhiyun return 0;
337*4882a593Smuzhiyun err:
338*4882a593Smuzhiyun for (; i >= 0; --i)
339*4882a593Smuzhiyun usb_kill_urb(port->read_urbs[i]);
340*4882a593Smuzhiyun
341*4882a593Smuzhiyun return res;
342*4882a593Smuzhiyun }
343*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(usb_serial_generic_submit_read_urbs);
344*4882a593Smuzhiyun
usb_serial_generic_process_read_urb(struct urb * urb)345*4882a593Smuzhiyun void usb_serial_generic_process_read_urb(struct urb *urb)
346*4882a593Smuzhiyun {
347*4882a593Smuzhiyun struct usb_serial_port *port = urb->context;
348*4882a593Smuzhiyun char *ch = urb->transfer_buffer;
349*4882a593Smuzhiyun int i;
350*4882a593Smuzhiyun
351*4882a593Smuzhiyun if (!urb->actual_length)
352*4882a593Smuzhiyun return;
353*4882a593Smuzhiyun /*
354*4882a593Smuzhiyun * The per character mucking around with sysrq path it too slow for
355*4882a593Smuzhiyun * stuff like 3G modems, so shortcircuit it in the 99.9999999% of
356*4882a593Smuzhiyun * cases where the USB serial is not a console anyway.
357*4882a593Smuzhiyun */
358*4882a593Smuzhiyun if (port->sysrq) {
359*4882a593Smuzhiyun for (i = 0; i < urb->actual_length; i++, ch++) {
360*4882a593Smuzhiyun if (!usb_serial_handle_sysrq_char(port, *ch))
361*4882a593Smuzhiyun tty_insert_flip_char(&port->port, *ch, TTY_NORMAL);
362*4882a593Smuzhiyun }
363*4882a593Smuzhiyun } else {
364*4882a593Smuzhiyun tty_insert_flip_string(&port->port, ch, urb->actual_length);
365*4882a593Smuzhiyun }
366*4882a593Smuzhiyun tty_flip_buffer_push(&port->port);
367*4882a593Smuzhiyun }
368*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(usb_serial_generic_process_read_urb);
369*4882a593Smuzhiyun
usb_serial_generic_read_bulk_callback(struct urb * urb)370*4882a593Smuzhiyun void usb_serial_generic_read_bulk_callback(struct urb *urb)
371*4882a593Smuzhiyun {
372*4882a593Smuzhiyun struct usb_serial_port *port = urb->context;
373*4882a593Smuzhiyun unsigned char *data = urb->transfer_buffer;
374*4882a593Smuzhiyun bool stopped = false;
375*4882a593Smuzhiyun int status = urb->status;
376*4882a593Smuzhiyun int i;
377*4882a593Smuzhiyun
378*4882a593Smuzhiyun for (i = 0; i < ARRAY_SIZE(port->read_urbs); ++i) {
379*4882a593Smuzhiyun if (urb == port->read_urbs[i])
380*4882a593Smuzhiyun break;
381*4882a593Smuzhiyun }
382*4882a593Smuzhiyun
383*4882a593Smuzhiyun dev_dbg(&port->dev, "%s - urb %d, len %d\n", __func__, i,
384*4882a593Smuzhiyun urb->actual_length);
385*4882a593Smuzhiyun switch (status) {
386*4882a593Smuzhiyun case 0:
387*4882a593Smuzhiyun usb_serial_debug_data(&port->dev, __func__, urb->actual_length,
388*4882a593Smuzhiyun data);
389*4882a593Smuzhiyun port->serial->type->process_read_urb(urb);
390*4882a593Smuzhiyun break;
391*4882a593Smuzhiyun case -ENOENT:
392*4882a593Smuzhiyun case -ECONNRESET:
393*4882a593Smuzhiyun case -ESHUTDOWN:
394*4882a593Smuzhiyun dev_dbg(&port->dev, "%s - urb stopped: %d\n",
395*4882a593Smuzhiyun __func__, status);
396*4882a593Smuzhiyun stopped = true;
397*4882a593Smuzhiyun break;
398*4882a593Smuzhiyun case -EPIPE:
399*4882a593Smuzhiyun dev_err(&port->dev, "%s - urb stopped: %d\n",
400*4882a593Smuzhiyun __func__, status);
401*4882a593Smuzhiyun stopped = true;
402*4882a593Smuzhiyun break;
403*4882a593Smuzhiyun default:
404*4882a593Smuzhiyun dev_dbg(&port->dev, "%s - nonzero urb status: %d\n",
405*4882a593Smuzhiyun __func__, status);
406*4882a593Smuzhiyun break;
407*4882a593Smuzhiyun }
408*4882a593Smuzhiyun
409*4882a593Smuzhiyun /*
410*4882a593Smuzhiyun * Make sure URB processing is done before marking as free to avoid
411*4882a593Smuzhiyun * racing with unthrottle() on another CPU. Matches the barriers
412*4882a593Smuzhiyun * implied by the test_and_clear_bit() in
413*4882a593Smuzhiyun * usb_serial_generic_submit_read_urb().
414*4882a593Smuzhiyun */
415*4882a593Smuzhiyun smp_mb__before_atomic();
416*4882a593Smuzhiyun set_bit(i, &port->read_urbs_free);
417*4882a593Smuzhiyun /*
418*4882a593Smuzhiyun * Make sure URB is marked as free before checking the throttled flag
419*4882a593Smuzhiyun * to avoid racing with unthrottle() on another CPU. Matches the
420*4882a593Smuzhiyun * smp_mb__after_atomic() in unthrottle().
421*4882a593Smuzhiyun */
422*4882a593Smuzhiyun smp_mb__after_atomic();
423*4882a593Smuzhiyun
424*4882a593Smuzhiyun if (stopped)
425*4882a593Smuzhiyun return;
426*4882a593Smuzhiyun
427*4882a593Smuzhiyun if (test_bit(USB_SERIAL_THROTTLED, &port->flags))
428*4882a593Smuzhiyun return;
429*4882a593Smuzhiyun
430*4882a593Smuzhiyun usb_serial_generic_submit_read_urb(port, i, GFP_ATOMIC);
431*4882a593Smuzhiyun }
432*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(usb_serial_generic_read_bulk_callback);
433*4882a593Smuzhiyun
usb_serial_generic_write_bulk_callback(struct urb * urb)434*4882a593Smuzhiyun void usb_serial_generic_write_bulk_callback(struct urb *urb)
435*4882a593Smuzhiyun {
436*4882a593Smuzhiyun unsigned long flags;
437*4882a593Smuzhiyun struct usb_serial_port *port = urb->context;
438*4882a593Smuzhiyun int status = urb->status;
439*4882a593Smuzhiyun int i;
440*4882a593Smuzhiyun
441*4882a593Smuzhiyun for (i = 0; i < ARRAY_SIZE(port->write_urbs); ++i) {
442*4882a593Smuzhiyun if (port->write_urbs[i] == urb)
443*4882a593Smuzhiyun break;
444*4882a593Smuzhiyun }
445*4882a593Smuzhiyun spin_lock_irqsave(&port->lock, flags);
446*4882a593Smuzhiyun port->tx_bytes -= urb->transfer_buffer_length;
447*4882a593Smuzhiyun set_bit(i, &port->write_urbs_free);
448*4882a593Smuzhiyun spin_unlock_irqrestore(&port->lock, flags);
449*4882a593Smuzhiyun
450*4882a593Smuzhiyun switch (status) {
451*4882a593Smuzhiyun case 0:
452*4882a593Smuzhiyun break;
453*4882a593Smuzhiyun case -ENOENT:
454*4882a593Smuzhiyun case -ECONNRESET:
455*4882a593Smuzhiyun case -ESHUTDOWN:
456*4882a593Smuzhiyun dev_dbg(&port->dev, "%s - urb stopped: %d\n",
457*4882a593Smuzhiyun __func__, status);
458*4882a593Smuzhiyun return;
459*4882a593Smuzhiyun case -EPIPE:
460*4882a593Smuzhiyun dev_err_console(port, "%s - urb stopped: %d\n",
461*4882a593Smuzhiyun __func__, status);
462*4882a593Smuzhiyun return;
463*4882a593Smuzhiyun default:
464*4882a593Smuzhiyun dev_err_console(port, "%s - nonzero urb status: %d\n",
465*4882a593Smuzhiyun __func__, status);
466*4882a593Smuzhiyun break;
467*4882a593Smuzhiyun }
468*4882a593Smuzhiyun
469*4882a593Smuzhiyun usb_serial_generic_write_start(port, GFP_ATOMIC);
470*4882a593Smuzhiyun usb_serial_port_softint(port);
471*4882a593Smuzhiyun }
472*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(usb_serial_generic_write_bulk_callback);
473*4882a593Smuzhiyun
usb_serial_generic_throttle(struct tty_struct * tty)474*4882a593Smuzhiyun void usb_serial_generic_throttle(struct tty_struct *tty)
475*4882a593Smuzhiyun {
476*4882a593Smuzhiyun struct usb_serial_port *port = tty->driver_data;
477*4882a593Smuzhiyun
478*4882a593Smuzhiyun set_bit(USB_SERIAL_THROTTLED, &port->flags);
479*4882a593Smuzhiyun }
480*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(usb_serial_generic_throttle);
481*4882a593Smuzhiyun
usb_serial_generic_unthrottle(struct tty_struct * tty)482*4882a593Smuzhiyun void usb_serial_generic_unthrottle(struct tty_struct *tty)
483*4882a593Smuzhiyun {
484*4882a593Smuzhiyun struct usb_serial_port *port = tty->driver_data;
485*4882a593Smuzhiyun
486*4882a593Smuzhiyun clear_bit(USB_SERIAL_THROTTLED, &port->flags);
487*4882a593Smuzhiyun
488*4882a593Smuzhiyun /*
489*4882a593Smuzhiyun * Matches the smp_mb__after_atomic() in
490*4882a593Smuzhiyun * usb_serial_generic_read_bulk_callback().
491*4882a593Smuzhiyun */
492*4882a593Smuzhiyun smp_mb__after_atomic();
493*4882a593Smuzhiyun
494*4882a593Smuzhiyun usb_serial_generic_submit_read_urbs(port, GFP_KERNEL);
495*4882a593Smuzhiyun }
496*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(usb_serial_generic_unthrottle);
497*4882a593Smuzhiyun
usb_serial_generic_msr_changed(struct tty_struct * tty,unsigned long arg,struct async_icount * cprev)498*4882a593Smuzhiyun static bool usb_serial_generic_msr_changed(struct tty_struct *tty,
499*4882a593Smuzhiyun unsigned long arg, struct async_icount *cprev)
500*4882a593Smuzhiyun {
501*4882a593Smuzhiyun struct usb_serial_port *port = tty->driver_data;
502*4882a593Smuzhiyun struct async_icount cnow;
503*4882a593Smuzhiyun unsigned long flags;
504*4882a593Smuzhiyun bool ret;
505*4882a593Smuzhiyun
506*4882a593Smuzhiyun /*
507*4882a593Smuzhiyun * Use tty-port initialised flag to detect all hangups including the
508*4882a593Smuzhiyun * one generated at USB-device disconnect.
509*4882a593Smuzhiyun */
510*4882a593Smuzhiyun if (!tty_port_initialized(&port->port))
511*4882a593Smuzhiyun return true;
512*4882a593Smuzhiyun
513*4882a593Smuzhiyun spin_lock_irqsave(&port->lock, flags);
514*4882a593Smuzhiyun cnow = port->icount; /* atomic copy*/
515*4882a593Smuzhiyun spin_unlock_irqrestore(&port->lock, flags);
516*4882a593Smuzhiyun
517*4882a593Smuzhiyun ret = ((arg & TIOCM_RNG) && (cnow.rng != cprev->rng)) ||
518*4882a593Smuzhiyun ((arg & TIOCM_DSR) && (cnow.dsr != cprev->dsr)) ||
519*4882a593Smuzhiyun ((arg & TIOCM_CD) && (cnow.dcd != cprev->dcd)) ||
520*4882a593Smuzhiyun ((arg & TIOCM_CTS) && (cnow.cts != cprev->cts));
521*4882a593Smuzhiyun
522*4882a593Smuzhiyun *cprev = cnow;
523*4882a593Smuzhiyun
524*4882a593Smuzhiyun return ret;
525*4882a593Smuzhiyun }
526*4882a593Smuzhiyun
usb_serial_generic_tiocmiwait(struct tty_struct * tty,unsigned long arg)527*4882a593Smuzhiyun int usb_serial_generic_tiocmiwait(struct tty_struct *tty, unsigned long arg)
528*4882a593Smuzhiyun {
529*4882a593Smuzhiyun struct usb_serial_port *port = tty->driver_data;
530*4882a593Smuzhiyun struct async_icount cnow;
531*4882a593Smuzhiyun unsigned long flags;
532*4882a593Smuzhiyun int ret;
533*4882a593Smuzhiyun
534*4882a593Smuzhiyun spin_lock_irqsave(&port->lock, flags);
535*4882a593Smuzhiyun cnow = port->icount; /* atomic copy */
536*4882a593Smuzhiyun spin_unlock_irqrestore(&port->lock, flags);
537*4882a593Smuzhiyun
538*4882a593Smuzhiyun ret = wait_event_interruptible(port->port.delta_msr_wait,
539*4882a593Smuzhiyun usb_serial_generic_msr_changed(tty, arg, &cnow));
540*4882a593Smuzhiyun if (!ret && !tty_port_initialized(&port->port))
541*4882a593Smuzhiyun ret = -EIO;
542*4882a593Smuzhiyun
543*4882a593Smuzhiyun return ret;
544*4882a593Smuzhiyun }
545*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(usb_serial_generic_tiocmiwait);
546*4882a593Smuzhiyun
usb_serial_generic_get_icount(struct tty_struct * tty,struct serial_icounter_struct * icount)547*4882a593Smuzhiyun int usb_serial_generic_get_icount(struct tty_struct *tty,
548*4882a593Smuzhiyun struct serial_icounter_struct *icount)
549*4882a593Smuzhiyun {
550*4882a593Smuzhiyun struct usb_serial_port *port = tty->driver_data;
551*4882a593Smuzhiyun struct async_icount cnow;
552*4882a593Smuzhiyun unsigned long flags;
553*4882a593Smuzhiyun
554*4882a593Smuzhiyun spin_lock_irqsave(&port->lock, flags);
555*4882a593Smuzhiyun cnow = port->icount; /* atomic copy */
556*4882a593Smuzhiyun spin_unlock_irqrestore(&port->lock, flags);
557*4882a593Smuzhiyun
558*4882a593Smuzhiyun icount->cts = cnow.cts;
559*4882a593Smuzhiyun icount->dsr = cnow.dsr;
560*4882a593Smuzhiyun icount->rng = cnow.rng;
561*4882a593Smuzhiyun icount->dcd = cnow.dcd;
562*4882a593Smuzhiyun icount->tx = cnow.tx;
563*4882a593Smuzhiyun icount->rx = cnow.rx;
564*4882a593Smuzhiyun icount->frame = cnow.frame;
565*4882a593Smuzhiyun icount->parity = cnow.parity;
566*4882a593Smuzhiyun icount->overrun = cnow.overrun;
567*4882a593Smuzhiyun icount->brk = cnow.brk;
568*4882a593Smuzhiyun icount->buf_overrun = cnow.buf_overrun;
569*4882a593Smuzhiyun
570*4882a593Smuzhiyun return 0;
571*4882a593Smuzhiyun }
572*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(usb_serial_generic_get_icount);
573*4882a593Smuzhiyun
574*4882a593Smuzhiyun #if defined(CONFIG_USB_SERIAL_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
usb_serial_handle_sysrq_char(struct usb_serial_port * port,unsigned int ch)575*4882a593Smuzhiyun int usb_serial_handle_sysrq_char(struct usb_serial_port *port, unsigned int ch)
576*4882a593Smuzhiyun {
577*4882a593Smuzhiyun if (port->sysrq) {
578*4882a593Smuzhiyun if (ch && time_before(jiffies, port->sysrq)) {
579*4882a593Smuzhiyun handle_sysrq(ch);
580*4882a593Smuzhiyun port->sysrq = 0;
581*4882a593Smuzhiyun return 1;
582*4882a593Smuzhiyun }
583*4882a593Smuzhiyun port->sysrq = 0;
584*4882a593Smuzhiyun }
585*4882a593Smuzhiyun return 0;
586*4882a593Smuzhiyun }
587*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(usb_serial_handle_sysrq_char);
588*4882a593Smuzhiyun
usb_serial_handle_break(struct usb_serial_port * port)589*4882a593Smuzhiyun int usb_serial_handle_break(struct usb_serial_port *port)
590*4882a593Smuzhiyun {
591*4882a593Smuzhiyun if (!port->port.console)
592*4882a593Smuzhiyun return 0;
593*4882a593Smuzhiyun
594*4882a593Smuzhiyun if (!port->sysrq) {
595*4882a593Smuzhiyun port->sysrq = jiffies + HZ*5;
596*4882a593Smuzhiyun return 1;
597*4882a593Smuzhiyun }
598*4882a593Smuzhiyun port->sysrq = 0;
599*4882a593Smuzhiyun return 0;
600*4882a593Smuzhiyun }
601*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(usb_serial_handle_break);
602*4882a593Smuzhiyun #endif
603*4882a593Smuzhiyun
604*4882a593Smuzhiyun /**
605*4882a593Smuzhiyun * usb_serial_handle_dcd_change - handle a change of carrier detect state
606*4882a593Smuzhiyun * @port: usb-serial port
607*4882a593Smuzhiyun * @tty: tty for the port
608*4882a593Smuzhiyun * @status: new carrier detect status, nonzero if active
609*4882a593Smuzhiyun */
usb_serial_handle_dcd_change(struct usb_serial_port * port,struct tty_struct * tty,unsigned int status)610*4882a593Smuzhiyun void usb_serial_handle_dcd_change(struct usb_serial_port *port,
611*4882a593Smuzhiyun struct tty_struct *tty, unsigned int status)
612*4882a593Smuzhiyun {
613*4882a593Smuzhiyun dev_dbg(&port->dev, "%s - status %d\n", __func__, status);
614*4882a593Smuzhiyun
615*4882a593Smuzhiyun if (tty) {
616*4882a593Smuzhiyun struct tty_ldisc *ld = tty_ldisc_ref(tty);
617*4882a593Smuzhiyun
618*4882a593Smuzhiyun if (ld) {
619*4882a593Smuzhiyun if (ld->ops->dcd_change)
620*4882a593Smuzhiyun ld->ops->dcd_change(tty, status);
621*4882a593Smuzhiyun tty_ldisc_deref(ld);
622*4882a593Smuzhiyun }
623*4882a593Smuzhiyun }
624*4882a593Smuzhiyun
625*4882a593Smuzhiyun if (status)
626*4882a593Smuzhiyun wake_up_interruptible(&port->port.open_wait);
627*4882a593Smuzhiyun else if (tty && !C_CLOCAL(tty))
628*4882a593Smuzhiyun tty_hangup(tty);
629*4882a593Smuzhiyun }
630*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(usb_serial_handle_dcd_change);
631*4882a593Smuzhiyun
usb_serial_generic_resume(struct usb_serial * serial)632*4882a593Smuzhiyun int usb_serial_generic_resume(struct usb_serial *serial)
633*4882a593Smuzhiyun {
634*4882a593Smuzhiyun struct usb_serial_port *port;
635*4882a593Smuzhiyun int i, c = 0, r;
636*4882a593Smuzhiyun
637*4882a593Smuzhiyun for (i = 0; i < serial->num_ports; i++) {
638*4882a593Smuzhiyun port = serial->port[i];
639*4882a593Smuzhiyun if (!tty_port_initialized(&port->port))
640*4882a593Smuzhiyun continue;
641*4882a593Smuzhiyun
642*4882a593Smuzhiyun if (port->bulk_in_size) {
643*4882a593Smuzhiyun r = usb_serial_generic_submit_read_urbs(port,
644*4882a593Smuzhiyun GFP_NOIO);
645*4882a593Smuzhiyun if (r < 0)
646*4882a593Smuzhiyun c++;
647*4882a593Smuzhiyun }
648*4882a593Smuzhiyun
649*4882a593Smuzhiyun if (port->bulk_out_size) {
650*4882a593Smuzhiyun r = usb_serial_generic_write_start(port, GFP_NOIO);
651*4882a593Smuzhiyun if (r < 0)
652*4882a593Smuzhiyun c++;
653*4882a593Smuzhiyun }
654*4882a593Smuzhiyun }
655*4882a593Smuzhiyun
656*4882a593Smuzhiyun return c ? -EIO : 0;
657*4882a593Smuzhiyun }
658*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(usb_serial_generic_resume);
659