Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)   USB Driver layer for GSM modems
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)   Copyright (C) 2005  Matthias Urlichs <smurf@smurf.noris.de>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7)   Portions copied from the Keyspan driver by Hugh Blemings <hugh@blemings.org>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9)   History: see the git log.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11)   Work sponsored by: Sigos GmbH, Germany <info@sigos.de>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13)   This driver exists because the "normal" serial driver doesn't work too well
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14)   with GSM modems. Issues:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15)   - data loss -- one single Receive URB is not nearly enough
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16)   - controlling the baud rate doesn't make sense
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) #define DRIVER_AUTHOR "Matthias Urlichs <smurf@smurf.noris.de>"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) #define DRIVER_DESC "USB Driver for GSM modems"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) #include <linux/jiffies.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) #include <linux/errno.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) #include <linux/tty.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) #include <linux/tty_flip.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) #include <linux/bitops.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) #include <linux/uaccess.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) #include <linux/usb.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) #include <linux/usb/serial.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) #include <linux/serial.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) #include "usb-wwan.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37)  * Generate DTR/RTS signals on the port using the SET_CONTROL_LINE_STATE request
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38)  * in CDC ACM.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) static int usb_wwan_send_setup(struct usb_serial_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) 	struct usb_serial *serial = port->serial;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) 	struct usb_wwan_port_private *portdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) 	int val = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) 	int ifnum;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) 	int res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) 	portdata = usb_get_serial_port_data(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) 	if (portdata->dtr_state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) 		val |= 0x01;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) 	if (portdata->rts_state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) 		val |= 0x02;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) 	ifnum = serial->interface->cur_altsetting->desc.bInterfaceNumber;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) 	res = usb_autopm_get_interface(serial->interface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) 	if (res)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) 		return res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) 	res = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) 				0x22, 0x21, val, ifnum, NULL, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) 				USB_CTRL_SET_TIMEOUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) 	usb_autopm_put_interface(port->serial->interface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) 	return res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) void usb_wwan_dtr_rts(struct usb_serial_port *port, int on)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) 	struct usb_wwan_port_private *portdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) 	struct usb_wwan_intf_private *intfdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) 	intfdata = usb_get_serial_data(port->serial);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) 	if (!intfdata->use_send_setup)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) 	portdata = usb_get_serial_port_data(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 	/* FIXME: locking */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 	portdata->rts_state = on;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 	portdata->dtr_state = on;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 	usb_wwan_send_setup(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) EXPORT_SYMBOL(usb_wwan_dtr_rts);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) int usb_wwan_tiocmget(struct tty_struct *tty)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) 	struct usb_serial_port *port = tty->driver_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 	unsigned int value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 	struct usb_wwan_port_private *portdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 	portdata = usb_get_serial_port_data(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 	value = ((portdata->rts_state) ? TIOCM_RTS : 0) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 	    ((portdata->dtr_state) ? TIOCM_DTR : 0) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 	    ((portdata->cts_state) ? TIOCM_CTS : 0) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 	    ((portdata->dsr_state) ? TIOCM_DSR : 0) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 	    ((portdata->dcd_state) ? TIOCM_CAR : 0) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 	    ((portdata->ri_state) ? TIOCM_RNG : 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) 	return value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) EXPORT_SYMBOL(usb_wwan_tiocmget);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) int usb_wwan_tiocmset(struct tty_struct *tty,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 		      unsigned int set, unsigned int clear)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 	struct usb_serial_port *port = tty->driver_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 	struct usb_wwan_port_private *portdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 	struct usb_wwan_intf_private *intfdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 	portdata = usb_get_serial_port_data(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 	intfdata = usb_get_serial_data(port->serial);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 	if (!intfdata->use_send_setup)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 	/* FIXME: what locks portdata fields ? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 	if (set & TIOCM_RTS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) 		portdata->rts_state = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 	if (set & TIOCM_DTR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) 		portdata->dtr_state = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) 	if (clear & TIOCM_RTS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) 		portdata->rts_state = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) 	if (clear & TIOCM_DTR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) 		portdata->dtr_state = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) 	return usb_wwan_send_setup(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) EXPORT_SYMBOL(usb_wwan_tiocmset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) int usb_wwan_get_serial_info(struct tty_struct *tty,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) 			   struct serial_struct *ss)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) 	struct usb_serial_port *port = tty->driver_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) 	ss->line            = port->minor;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) 	ss->port            = port->port_number;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) 	ss->baud_base       = tty_get_baud_rate(port->port.tty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) 	ss->close_delay	    = jiffies_to_msecs(port->port.close_delay) / 10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) 	ss->closing_wait    = port->port.closing_wait == ASYNC_CLOSING_WAIT_NONE ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) 				 ASYNC_CLOSING_WAIT_NONE :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) 				 jiffies_to_msecs(port->port.closing_wait) / 10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) EXPORT_SYMBOL(usb_wwan_get_serial_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) int usb_wwan_set_serial_info(struct tty_struct *tty,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) 			   struct serial_struct *ss)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) 	struct usb_serial_port *port = tty->driver_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) 	unsigned int closing_wait, close_delay;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) 	int retval = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) 	close_delay = msecs_to_jiffies(ss->close_delay * 10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) 	closing_wait = ss->closing_wait == ASYNC_CLOSING_WAIT_NONE ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) 			ASYNC_CLOSING_WAIT_NONE :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) 			msecs_to_jiffies(ss->closing_wait * 10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) 	mutex_lock(&port->port.mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) 	if (!capable(CAP_SYS_ADMIN)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) 		if ((close_delay != port->port.close_delay) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) 		    (closing_wait != port->port.closing_wait))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) 			retval = -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) 			retval = -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) 		port->port.close_delay  = close_delay;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) 		port->port.closing_wait = closing_wait;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) 	mutex_unlock(&port->port.mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) 	return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) EXPORT_SYMBOL(usb_wwan_set_serial_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) int usb_wwan_write(struct tty_struct *tty, struct usb_serial_port *port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) 		   const unsigned char *buf, int count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) 	struct usb_wwan_port_private *portdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) 	struct usb_wwan_intf_private *intfdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) 	int left, todo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) 	struct urb *this_urb = NULL;	/* spurious */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) 	portdata = usb_get_serial_port_data(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) 	intfdata = usb_get_serial_data(port->serial);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) 	dev_dbg(&port->dev, "%s: write (%d chars)\n", __func__, count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) 	i = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) 	left = count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) 	for (i = 0; left > 0 && i < N_OUT_URB; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) 		todo = left;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) 		if (todo > OUT_BUFLEN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) 			todo = OUT_BUFLEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) 		this_urb = portdata->out_urbs[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) 		if (test_and_set_bit(i, &portdata->out_busy)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) 			if (time_before(jiffies,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) 					portdata->tx_start_time[i] + 10 * HZ))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) 				continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) 			usb_unlink_urb(this_urb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) 		dev_dbg(&port->dev, "%s: endpoint %d buf %d\n", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) 			usb_pipeendpoint(this_urb->pipe), i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) 		err = usb_autopm_get_interface_async(port->serial->interface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) 		if (err < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) 			clear_bit(i, &portdata->out_busy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) 		/* send the data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) 		memcpy(this_urb->transfer_buffer, buf, todo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) 		this_urb->transfer_buffer_length = todo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) 		spin_lock_irqsave(&intfdata->susp_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) 		if (intfdata->suspended) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) 			usb_anchor_urb(this_urb, &portdata->delayed);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) 			spin_unlock_irqrestore(&intfdata->susp_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) 			intfdata->in_flight++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) 			spin_unlock_irqrestore(&intfdata->susp_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) 			err = usb_submit_urb(this_urb, GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) 			if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) 				dev_err(&port->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) 					"%s: submit urb %d failed: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) 					__func__, i, err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) 				clear_bit(i, &portdata->out_busy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) 				spin_lock_irqsave(&intfdata->susp_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) 				intfdata->in_flight--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) 				spin_unlock_irqrestore(&intfdata->susp_lock,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) 						       flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) 				usb_autopm_put_interface_async(port->serial->interface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) 		portdata->tx_start_time[i] = jiffies;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) 		buf += todo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) 		left -= todo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) 	count -= left;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) 	dev_dbg(&port->dev, "%s: wrote (did %d)\n", __func__, count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) 	return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) EXPORT_SYMBOL(usb_wwan_write);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) static void usb_wwan_indat_callback(struct urb *urb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) 	int endpoint;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) 	struct usb_serial_port *port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) 	struct device *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) 	unsigned char *data = urb->transfer_buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) 	int status = urb->status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) 	endpoint = usb_pipeendpoint(urb->pipe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) 	port = urb->context;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) 	dev = &port->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) 	if (status) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) 		dev_dbg(dev, "%s: nonzero status: %d on endpoint %02x.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) 			__func__, status, endpoint);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) 		/* don't resubmit on fatal errors */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) 		if (status == -ESHUTDOWN || status == -ENOENT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) 			return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) 		if (urb->actual_length) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) 			tty_insert_flip_string(&port->port, data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) 					urb->actual_length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) 			tty_flip_buffer_push(&port->port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) 		} else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) 			dev_dbg(dev, "%s: empty read urb received\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) 	/* Resubmit urb so we continue receiving */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) 	err = usb_submit_urb(urb, GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) 	if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) 		if (err != -EPERM && err != -ENODEV) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) 			dev_err(dev, "%s: resubmit read urb failed. (%d)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) 				__func__, err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) 			/* busy also in error unless we are killed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) 			usb_mark_last_busy(port->serial->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) 		usb_mark_last_busy(port->serial->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) static void usb_wwan_outdat_callback(struct urb *urb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) 	struct usb_serial_port *port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) 	struct usb_wwan_port_private *portdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) 	struct usb_wwan_intf_private *intfdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) 	port = urb->context;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) 	intfdata = usb_get_serial_data(port->serial);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) 	usb_serial_port_softint(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) 	usb_autopm_put_interface_async(port->serial->interface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) 	portdata = usb_get_serial_port_data(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) 	spin_lock_irqsave(&intfdata->susp_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) 	intfdata->in_flight--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) 	spin_unlock_irqrestore(&intfdata->susp_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) 	for (i = 0; i < N_OUT_URB; ++i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) 		if (portdata->out_urbs[i] == urb) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) 			smp_mb__before_atomic();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) 			clear_bit(i, &portdata->out_busy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) int usb_wwan_write_room(struct tty_struct *tty)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) 	struct usb_serial_port *port = tty->driver_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) 	struct usb_wwan_port_private *portdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) 	int data_len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) 	struct urb *this_urb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) 	portdata = usb_get_serial_port_data(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) 	for (i = 0; i < N_OUT_URB; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) 		this_urb = portdata->out_urbs[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) 		if (this_urb && !test_bit(i, &portdata->out_busy))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) 			data_len += OUT_BUFLEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) 	dev_dbg(&port->dev, "%s: %d\n", __func__, data_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) 	return data_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) EXPORT_SYMBOL(usb_wwan_write_room);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) int usb_wwan_chars_in_buffer(struct tty_struct *tty)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) 	struct usb_serial_port *port = tty->driver_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) 	struct usb_wwan_port_private *portdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) 	int data_len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) 	struct urb *this_urb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) 	portdata = usb_get_serial_port_data(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) 	for (i = 0; i < N_OUT_URB; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) 		this_urb = portdata->out_urbs[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) 		/* FIXME: This locking is insufficient as this_urb may
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) 		   go unused during the test */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) 		if (this_urb && test_bit(i, &portdata->out_busy))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) 			data_len += this_urb->transfer_buffer_length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) 	dev_dbg(&port->dev, "%s: %d\n", __func__, data_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) 	return data_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) EXPORT_SYMBOL(usb_wwan_chars_in_buffer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) int usb_wwan_open(struct tty_struct *tty, struct usb_serial_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) 	struct usb_wwan_port_private *portdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) 	struct usb_wwan_intf_private *intfdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) 	struct usb_serial *serial = port->serial;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) 	int i, err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) 	struct urb *urb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) 	portdata = usb_get_serial_port_data(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) 	intfdata = usb_get_serial_data(serial);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) 	if (port->interrupt_in_urb) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) 		err = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) 		if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) 			dev_err(&port->dev, "%s: submit int urb failed: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) 				__func__, err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) 	/* Start reading from the IN endpoint */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) 	for (i = 0; i < N_IN_URB; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) 		urb = portdata->in_urbs[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) 		if (!urb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) 		err = usb_submit_urb(urb, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) 		if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) 			dev_err(&port->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) 				"%s: submit read urb %d failed: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) 				__func__, i, err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) 	spin_lock_irq(&intfdata->susp_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) 	if (++intfdata->open_ports == 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) 		serial->interface->needs_remote_wakeup = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) 	spin_unlock_irq(&intfdata->susp_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) 	/* this balances a get in the generic USB serial code */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) 	usb_autopm_put_interface(serial->interface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) EXPORT_SYMBOL(usb_wwan_open);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) static void unbusy_queued_urb(struct urb *urb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) 					struct usb_wwan_port_private *portdata)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) 	for (i = 0; i < N_OUT_URB; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) 		if (urb == portdata->out_urbs[i]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) 			clear_bit(i, &portdata->out_busy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) void usb_wwan_close(struct usb_serial_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) 	struct usb_serial *serial = port->serial;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) 	struct usb_wwan_port_private *portdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) 	struct usb_wwan_intf_private *intfdata = usb_get_serial_data(serial);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) 	struct urb *urb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) 	portdata = usb_get_serial_port_data(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) 	 * Need to take susp_lock to make sure port is not already being
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) 	 * resumed, but no need to hold it due to initialized
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) 	spin_lock_irq(&intfdata->susp_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) 	if (--intfdata->open_ports == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) 		serial->interface->needs_remote_wakeup = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) 	spin_unlock_irq(&intfdata->susp_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) 	for (;;) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) 		urb = usb_get_from_anchor(&portdata->delayed);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) 		if (!urb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) 		unbusy_queued_urb(urb, portdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) 		usb_autopm_put_interface_async(serial->interface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) 	for (i = 0; i < N_IN_URB; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) 		usb_kill_urb(portdata->in_urbs[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) 	for (i = 0; i < N_OUT_URB; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) 		usb_kill_urb(portdata->out_urbs[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) 	usb_kill_urb(port->interrupt_in_urb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) 	usb_autopm_get_interface_no_resume(serial->interface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) EXPORT_SYMBOL(usb_wwan_close);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) static struct urb *usb_wwan_setup_urb(struct usb_serial_port *port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) 				      int endpoint,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) 				      int dir, void *ctx, char *buf, int len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) 				      void (*callback) (struct urb *))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) 	struct usb_serial *serial = port->serial;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) 	struct usb_wwan_intf_private *intfdata = usb_get_serial_data(serial);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) 	struct urb *urb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) 	urb = usb_alloc_urb(0, GFP_KERNEL);	/* No ISO */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) 	if (!urb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) 		return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) 	usb_fill_bulk_urb(urb, serial->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) 			  usb_sndbulkpipe(serial->dev, endpoint) | dir,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) 			  buf, len, callback, ctx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) 	if (intfdata->use_zlp && dir == USB_DIR_OUT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) 		urb->transfer_flags |= URB_ZERO_PACKET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) 	return urb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) int usb_wwan_port_probe(struct usb_serial_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) 	struct usb_wwan_port_private *portdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) 	struct urb *urb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) 	u8 *buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) 	if (!port->bulk_in_size || !port->bulk_out_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) 		return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) 	portdata = kzalloc(sizeof(*portdata), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) 	if (!portdata)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) 	init_usb_anchor(&portdata->delayed);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) 	for (i = 0; i < N_IN_URB; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) 		buffer = (u8 *)__get_free_page(GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) 		if (!buffer)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) 			goto bail_out_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) 		portdata->in_buffer[i] = buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) 		urb = usb_wwan_setup_urb(port, port->bulk_in_endpointAddress,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) 						USB_DIR_IN, port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) 						buffer, IN_BUFLEN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) 						usb_wwan_indat_callback);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) 		portdata->in_urbs[i] = urb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) 	for (i = 0; i < N_OUT_URB; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) 		buffer = kmalloc(OUT_BUFLEN, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) 		if (!buffer)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) 			goto bail_out_error2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) 		portdata->out_buffer[i] = buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) 		urb = usb_wwan_setup_urb(port, port->bulk_out_endpointAddress,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) 						USB_DIR_OUT, port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) 						buffer, OUT_BUFLEN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) 						usb_wwan_outdat_callback);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) 		portdata->out_urbs[i] = urb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) 	usb_set_serial_port_data(port, portdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) bail_out_error2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) 	for (i = 0; i < N_OUT_URB; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) 		usb_free_urb(portdata->out_urbs[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) 		kfree(portdata->out_buffer[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) bail_out_error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) 	for (i = 0; i < N_IN_URB; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) 		usb_free_urb(portdata->in_urbs[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) 		free_page((unsigned long)portdata->in_buffer[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) 	kfree(portdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) 	return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) EXPORT_SYMBOL_GPL(usb_wwan_port_probe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) int usb_wwan_port_remove(struct usb_serial_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) 	struct usb_wwan_port_private *portdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) 	portdata = usb_get_serial_port_data(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) 	usb_set_serial_port_data(port, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) 	for (i = 0; i < N_IN_URB; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) 		usb_free_urb(portdata->in_urbs[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) 		free_page((unsigned long)portdata->in_buffer[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) 	for (i = 0; i < N_OUT_URB; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) 		usb_free_urb(portdata->out_urbs[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) 		kfree(portdata->out_buffer[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) 	kfree(portdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) EXPORT_SYMBOL(usb_wwan_port_remove);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) #ifdef CONFIG_PM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) static void stop_urbs(struct usb_serial *serial)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) 	int i, j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) 	struct usb_serial_port *port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) 	struct usb_wwan_port_private *portdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) 	for (i = 0; i < serial->num_ports; ++i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) 		port = serial->port[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) 		portdata = usb_get_serial_port_data(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) 		if (!portdata)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) 		for (j = 0; j < N_IN_URB; j++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) 			usb_kill_urb(portdata->in_urbs[j]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) 		for (j = 0; j < N_OUT_URB; j++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) 			usb_kill_urb(portdata->out_urbs[j]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) 		usb_kill_urb(port->interrupt_in_urb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) int usb_wwan_suspend(struct usb_serial *serial, pm_message_t message)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) 	struct usb_wwan_intf_private *intfdata = usb_get_serial_data(serial);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) 	spin_lock_irq(&intfdata->susp_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) 	if (PMSG_IS_AUTO(message)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) 		if (intfdata->in_flight) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) 			spin_unlock_irq(&intfdata->susp_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) 			return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) 	intfdata->suspended = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) 	spin_unlock_irq(&intfdata->susp_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) 	stop_urbs(serial);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) EXPORT_SYMBOL(usb_wwan_suspend);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) /* Caller must hold susp_lock. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) static int usb_wwan_submit_delayed_urbs(struct usb_serial_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) 	struct usb_serial *serial = port->serial;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) 	struct usb_wwan_intf_private *data = usb_get_serial_data(serial);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) 	struct usb_wwan_port_private *portdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) 	struct urb *urb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) 	int err_count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) 	portdata = usb_get_serial_port_data(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) 	for (;;) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) 		urb = usb_get_from_anchor(&portdata->delayed);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) 		if (!urb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) 		err = usb_submit_urb(urb, GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) 		if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) 			dev_err(&port->dev, "%s: submit urb failed: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) 					__func__, err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) 			err_count++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) 			unbusy_queued_urb(urb, portdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) 			usb_autopm_put_interface_async(serial->interface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) 		data->in_flight++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) 	if (err_count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) 		return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) int usb_wwan_resume(struct usb_serial *serial)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) 	int i, j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) 	struct usb_serial_port *port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) 	struct usb_wwan_intf_private *intfdata = usb_get_serial_data(serial);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) 	struct usb_wwan_port_private *portdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) 	struct urb *urb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) 	int err_count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) 	spin_lock_irq(&intfdata->susp_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) 	for (i = 0; i < serial->num_ports; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) 		port = serial->port[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) 		if (!tty_port_initialized(&port->port))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) 		portdata = usb_get_serial_port_data(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) 		if (port->interrupt_in_urb) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) 			err = usb_submit_urb(port->interrupt_in_urb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) 					GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) 			if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) 				dev_err(&port->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) 					"%s: submit int urb failed: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) 					__func__, err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) 				err_count++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) 		err = usb_wwan_submit_delayed_urbs(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) 		if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) 			err_count++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) 		for (j = 0; j < N_IN_URB; j++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) 			urb = portdata->in_urbs[j];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) 			err = usb_submit_urb(urb, GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) 			if (err < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) 				dev_err(&port->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) 					"%s: submit read urb %d failed: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) 					__func__, i, err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) 				err_count++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) 	intfdata->suspended = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) 	spin_unlock_irq(&intfdata->susp_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) 	if (err_count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) 		return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) EXPORT_SYMBOL(usb_wwan_resume);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) MODULE_AUTHOR(DRIVER_AUTHOR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) MODULE_DESCRIPTION(DRIVER_DESC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) MODULE_LICENSE("GPL v2");