Lines Matching +full:serial +full:- +full:dir
1 // SPDX-License-Identifier: GPL-2.0
13 This driver exists because the "normal" serial driver doesn't work too well
15 - data loss -- one single Receive URB is not nearly enough
16 - controlling the baud rate doesn't make sense
33 #include <linux/usb/serial.h>
34 #include <linux/serial.h>
35 #include "usb-wwan.h"
43 struct usb_serial *serial = port->serial; in usb_wwan_send_setup() local
51 if (portdata->dtr_state) in usb_wwan_send_setup()
53 if (portdata->rts_state) in usb_wwan_send_setup()
56 ifnum = serial->interface->cur_altsetting->desc.bInterfaceNumber; in usb_wwan_send_setup()
58 res = usb_autopm_get_interface(serial->interface); in usb_wwan_send_setup()
62 res = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0), in usb_wwan_send_setup()
67 usb_autopm_put_interface(port->serial->interface); in usb_wwan_send_setup()
77 intfdata = usb_get_serial_data(port->serial); in usb_wwan_dtr_rts()
79 if (!intfdata->use_send_setup) in usb_wwan_dtr_rts()
84 portdata->rts_state = on; in usb_wwan_dtr_rts()
85 portdata->dtr_state = on; in usb_wwan_dtr_rts()
93 struct usb_serial_port *port = tty->driver_data; in usb_wwan_tiocmget()
99 value = ((portdata->rts_state) ? TIOCM_RTS : 0) | in usb_wwan_tiocmget()
100 ((portdata->dtr_state) ? TIOCM_DTR : 0) | in usb_wwan_tiocmget()
101 ((portdata->cts_state) ? TIOCM_CTS : 0) | in usb_wwan_tiocmget()
102 ((portdata->dsr_state) ? TIOCM_DSR : 0) | in usb_wwan_tiocmget()
103 ((portdata->dcd_state) ? TIOCM_CAR : 0) | in usb_wwan_tiocmget()
104 ((portdata->ri_state) ? TIOCM_RNG : 0); in usb_wwan_tiocmget()
113 struct usb_serial_port *port = tty->driver_data; in usb_wwan_tiocmset()
118 intfdata = usb_get_serial_data(port->serial); in usb_wwan_tiocmset()
120 if (!intfdata->use_send_setup) in usb_wwan_tiocmset()
121 return -EINVAL; in usb_wwan_tiocmset()
125 portdata->rts_state = 1; in usb_wwan_tiocmset()
127 portdata->dtr_state = 1; in usb_wwan_tiocmset()
130 portdata->rts_state = 0; in usb_wwan_tiocmset()
132 portdata->dtr_state = 0; in usb_wwan_tiocmset()
149 intfdata = usb_get_serial_data(port->serial); in usb_wwan_write()
151 dev_dbg(&port->dev, "%s: write (%d chars)\n", __func__, count); in usb_wwan_write()
159 this_urb = portdata->out_urbs[i]; in usb_wwan_write()
160 if (test_and_set_bit(i, &portdata->out_busy)) { in usb_wwan_write()
162 portdata->tx_start_time[i] + 10 * HZ)) in usb_wwan_write()
167 dev_dbg(&port->dev, "%s: endpoint %d buf %d\n", __func__, in usb_wwan_write()
168 usb_pipeendpoint(this_urb->pipe), i); in usb_wwan_write()
170 err = usb_autopm_get_interface_async(port->serial->interface); in usb_wwan_write()
172 clear_bit(i, &portdata->out_busy); in usb_wwan_write()
177 memcpy(this_urb->transfer_buffer, buf, todo); in usb_wwan_write()
178 this_urb->transfer_buffer_length = todo; in usb_wwan_write()
180 spin_lock_irqsave(&intfdata->susp_lock, flags); in usb_wwan_write()
181 if (intfdata->suspended) { in usb_wwan_write()
182 usb_anchor_urb(this_urb, &portdata->delayed); in usb_wwan_write()
183 spin_unlock_irqrestore(&intfdata->susp_lock, flags); in usb_wwan_write()
185 intfdata->in_flight++; in usb_wwan_write()
186 spin_unlock_irqrestore(&intfdata->susp_lock, flags); in usb_wwan_write()
189 dev_err(&port->dev, in usb_wwan_write()
192 clear_bit(i, &portdata->out_busy); in usb_wwan_write()
193 spin_lock_irqsave(&intfdata->susp_lock, flags); in usb_wwan_write()
194 intfdata->in_flight--; in usb_wwan_write()
195 spin_unlock_irqrestore(&intfdata->susp_lock, in usb_wwan_write()
197 usb_autopm_put_interface_async(port->serial->interface); in usb_wwan_write()
202 portdata->tx_start_time[i] = jiffies; in usb_wwan_write()
204 left -= todo; in usb_wwan_write()
207 count -= left; in usb_wwan_write()
208 dev_dbg(&port->dev, "%s: wrote (did %d)\n", __func__, count); in usb_wwan_write()
219 unsigned char *data = urb->transfer_buffer; in usb_wwan_indat_callback()
220 int status = urb->status; in usb_wwan_indat_callback()
222 endpoint = usb_pipeendpoint(urb->pipe); in usb_wwan_indat_callback()
223 port = urb->context; in usb_wwan_indat_callback()
224 dev = &port->dev; in usb_wwan_indat_callback()
231 if (status == -ESHUTDOWN || status == -ENOENT) in usb_wwan_indat_callback()
234 if (urb->actual_length) { in usb_wwan_indat_callback()
235 tty_insert_flip_string(&port->port, data, in usb_wwan_indat_callback()
236 urb->actual_length); in usb_wwan_indat_callback()
237 tty_flip_buffer_push(&port->port); in usb_wwan_indat_callback()
244 if (err != -EPERM && err != -ENODEV) { in usb_wwan_indat_callback()
248 usb_mark_last_busy(port->serial->dev); in usb_wwan_indat_callback()
251 usb_mark_last_busy(port->serial->dev); in usb_wwan_indat_callback()
263 port = urb->context; in usb_wwan_outdat_callback()
264 intfdata = usb_get_serial_data(port->serial); in usb_wwan_outdat_callback()
267 usb_autopm_put_interface_async(port->serial->interface); in usb_wwan_outdat_callback()
269 spin_lock_irqsave(&intfdata->susp_lock, flags); in usb_wwan_outdat_callback()
270 intfdata->in_flight--; in usb_wwan_outdat_callback()
271 spin_unlock_irqrestore(&intfdata->susp_lock, flags); in usb_wwan_outdat_callback()
274 if (portdata->out_urbs[i] == urb) { in usb_wwan_outdat_callback()
276 clear_bit(i, &portdata->out_busy); in usb_wwan_outdat_callback()
284 struct usb_serial_port *port = tty->driver_data; in usb_wwan_write_room()
293 this_urb = portdata->out_urbs[i]; in usb_wwan_write_room()
294 if (this_urb && !test_bit(i, &portdata->out_busy)) in usb_wwan_write_room()
298 dev_dbg(&port->dev, "%s: %u\n", __func__, data_len); in usb_wwan_write_room()
305 struct usb_serial_port *port = tty->driver_data; in usb_wwan_chars_in_buffer()
314 this_urb = portdata->out_urbs[i]; in usb_wwan_chars_in_buffer()
317 if (this_urb && test_bit(i, &portdata->out_busy)) in usb_wwan_chars_in_buffer()
318 data_len += this_urb->transfer_buffer_length; in usb_wwan_chars_in_buffer()
320 dev_dbg(&port->dev, "%s: %u\n", __func__, data_len); in usb_wwan_chars_in_buffer()
329 struct usb_serial *serial = port->serial; in usb_wwan_open() local
334 intfdata = usb_get_serial_data(serial); in usb_wwan_open()
336 if (port->interrupt_in_urb) { in usb_wwan_open()
337 err = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL); in usb_wwan_open()
339 dev_err(&port->dev, "%s: submit int urb failed: %d\n", in usb_wwan_open()
346 urb = portdata->in_urbs[i]; in usb_wwan_open()
351 dev_err(&port->dev, in usb_wwan_open()
357 spin_lock_irq(&intfdata->susp_lock); in usb_wwan_open()
358 if (++intfdata->open_ports == 1) in usb_wwan_open()
359 serial->interface->needs_remote_wakeup = 1; in usb_wwan_open()
360 spin_unlock_irq(&intfdata->susp_lock); in usb_wwan_open()
361 /* this balances a get in the generic USB serial code */ in usb_wwan_open()
362 usb_autopm_put_interface(serial->interface); in usb_wwan_open()
374 if (urb == portdata->out_urbs[i]) { in unbusy_queued_urb()
375 clear_bit(i, &portdata->out_busy); in unbusy_queued_urb()
384 struct usb_serial *serial = port->serial; in usb_wwan_close() local
386 struct usb_wwan_intf_private *intfdata = usb_get_serial_data(serial); in usb_wwan_close()
393 * resumed, but no need to hold it due to the tty-port initialized in usb_wwan_close()
396 spin_lock_irq(&intfdata->susp_lock); in usb_wwan_close()
397 if (--intfdata->open_ports == 0) in usb_wwan_close()
398 serial->interface->needs_remote_wakeup = 0; in usb_wwan_close()
399 spin_unlock_irq(&intfdata->susp_lock); in usb_wwan_close()
402 urb = usb_get_from_anchor(&portdata->delayed); in usb_wwan_close()
406 usb_autopm_put_interface_async(serial->interface); in usb_wwan_close()
410 usb_kill_urb(portdata->in_urbs[i]); in usb_wwan_close()
412 usb_kill_urb(portdata->out_urbs[i]); in usb_wwan_close()
413 usb_kill_urb(port->interrupt_in_urb); in usb_wwan_close()
415 usb_autopm_get_interface_no_resume(serial->interface); in usb_wwan_close()
421 int dir, void *ctx, char *buf, int len, in usb_wwan_setup_urb() argument
424 struct usb_serial *serial = port->serial; in usb_wwan_setup_urb() local
425 struct usb_wwan_intf_private *intfdata = usb_get_serial_data(serial); in usb_wwan_setup_urb()
432 usb_fill_bulk_urb(urb, serial->dev, in usb_wwan_setup_urb()
433 usb_sndbulkpipe(serial->dev, endpoint) | dir, in usb_wwan_setup_urb()
436 if (intfdata->use_zlp && dir == USB_DIR_OUT) in usb_wwan_setup_urb()
437 urb->transfer_flags |= URB_ZERO_PACKET; in usb_wwan_setup_urb()
449 if (!port->bulk_in_size || !port->bulk_out_size) in usb_wwan_port_probe()
450 return -ENODEV; in usb_wwan_port_probe()
454 return -ENOMEM; in usb_wwan_port_probe()
456 init_usb_anchor(&portdata->delayed); in usb_wwan_port_probe()
462 portdata->in_buffer[i] = buffer; in usb_wwan_port_probe()
464 urb = usb_wwan_setup_urb(port, port->bulk_in_endpointAddress, in usb_wwan_port_probe()
468 portdata->in_urbs[i] = urb; in usb_wwan_port_probe()
475 portdata->out_buffer[i] = buffer; in usb_wwan_port_probe()
477 urb = usb_wwan_setup_urb(port, port->bulk_out_endpointAddress, in usb_wwan_port_probe()
481 portdata->out_urbs[i] = urb; in usb_wwan_port_probe()
490 usb_free_urb(portdata->out_urbs[i]); in usb_wwan_port_probe()
491 kfree(portdata->out_buffer[i]); in usb_wwan_port_probe()
495 usb_free_urb(portdata->in_urbs[i]); in usb_wwan_port_probe()
496 free_page((unsigned long)portdata->in_buffer[i]); in usb_wwan_port_probe()
500 return -ENOMEM; in usb_wwan_port_probe()
513 usb_free_urb(portdata->in_urbs[i]); in usb_wwan_port_remove()
514 free_page((unsigned long)portdata->in_buffer[i]); in usb_wwan_port_remove()
517 usb_free_urb(portdata->out_urbs[i]); in usb_wwan_port_remove()
518 kfree(portdata->out_buffer[i]); in usb_wwan_port_remove()
526 static void stop_urbs(struct usb_serial *serial) in stop_urbs() argument
532 for (i = 0; i < serial->num_ports; ++i) { in stop_urbs()
533 port = serial->port[i]; in stop_urbs()
538 usb_kill_urb(portdata->in_urbs[j]); in stop_urbs()
540 usb_kill_urb(portdata->out_urbs[j]); in stop_urbs()
541 usb_kill_urb(port->interrupt_in_urb); in stop_urbs()
545 int usb_wwan_suspend(struct usb_serial *serial, pm_message_t message) in usb_wwan_suspend() argument
547 struct usb_wwan_intf_private *intfdata = usb_get_serial_data(serial); in usb_wwan_suspend()
549 spin_lock_irq(&intfdata->susp_lock); in usb_wwan_suspend()
551 if (intfdata->in_flight) { in usb_wwan_suspend()
552 spin_unlock_irq(&intfdata->susp_lock); in usb_wwan_suspend()
553 return -EBUSY; in usb_wwan_suspend()
556 intfdata->suspended = 1; in usb_wwan_suspend()
557 spin_unlock_irq(&intfdata->susp_lock); in usb_wwan_suspend()
559 stop_urbs(serial); in usb_wwan_suspend()
568 struct usb_serial *serial = port->serial; in usb_wwan_submit_delayed_urbs() local
569 struct usb_wwan_intf_private *data = usb_get_serial_data(serial); in usb_wwan_submit_delayed_urbs()
578 urb = usb_get_from_anchor(&portdata->delayed); in usb_wwan_submit_delayed_urbs()
584 dev_err(&port->dev, "%s: submit urb failed: %d\n", in usb_wwan_submit_delayed_urbs()
588 usb_autopm_put_interface_async(serial->interface); in usb_wwan_submit_delayed_urbs()
591 data->in_flight++; in usb_wwan_submit_delayed_urbs()
595 return -EIO; in usb_wwan_submit_delayed_urbs()
600 int usb_wwan_resume(struct usb_serial *serial) in usb_wwan_resume() argument
604 struct usb_wwan_intf_private *intfdata = usb_get_serial_data(serial); in usb_wwan_resume()
610 spin_lock_irq(&intfdata->susp_lock); in usb_wwan_resume()
611 for (i = 0; i < serial->num_ports; i++) { in usb_wwan_resume()
612 port = serial->port[i]; in usb_wwan_resume()
614 if (!tty_port_initialized(&port->port)) in usb_wwan_resume()
619 if (port->interrupt_in_urb) { in usb_wwan_resume()
620 err = usb_submit_urb(port->interrupt_in_urb, in usb_wwan_resume()
623 dev_err(&port->dev, in usb_wwan_resume()
635 urb = portdata->in_urbs[j]; in usb_wwan_resume()
638 dev_err(&port->dev, in usb_wwan_resume()
645 intfdata->suspended = 0; in usb_wwan_resume()
646 spin_unlock_irq(&intfdata->susp_lock); in usb_wwan_resume()
649 return -EIO; in usb_wwan_resume()