Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 5e131d14 authored by Mayank Rana's avatar Mayank Rana Committed by Gerrit - the friendly Code Review server
Browse files

f_gsi: Send DTR status with GET_LINE_STATE ioctl for RMNET interface



If there is any pending TRB on IN/INT endpoint with USB device
controller, USB device controller doesn't go into USB host requested
L1 LPM. If USB RMNET GSI driver gets modem offline command or any
control data from modem through user space application while running
USB L1 suspend/resume compliance test case, this compliance test case
fails due to pending TRB. Currently driver is using connected flag
related value as line state instead of actual DTR status i.e. USB host
side RMNET driver state. This allows QTI application to write available
control packet notification towards host whereas host side driver is
not ready to perform I/O. Hence to fix this issue use actual DTR status
with GET_LINE_STATE ioctl for RMNET interface.

Change-Id: Ib2ed004407a8b9336cbbe42b3735750946e6c759
Signed-off-by: default avatarMayank Rana <mrana@codeaurora.org>
parent 285dbc85
Loading
Loading
Loading
Loading
+13 −4
Original line number Diff line number Diff line
@@ -1216,14 +1216,16 @@ static long gsi_ctrl_dev_ioctl(struct file *fp, unsigned int cmd,
		break;
	case QTI_CTRL_GET_LINE_STATE:
		val = atomic_read(&gsi->connected);
		if (gsi->prot_id == IPA_USB_RMNET)
			val = gsi->rmnet_dtr_status;

		ret = copy_to_user((void __user *)arg, &val, sizeof(val));
		if (ret) {
			log_event_err("copy_to_user fail LINE_STATE");
			ret = -EFAULT;
		}
		log_event_dbg("%s: Sent line_state: %d for prot id:%d",
				__func__,
				atomic_read(&gsi->connected), gsi->prot_id);
				__func__, val, gsi->prot_id);
		break;
	case QTI_CTRL_EP_LOOKUP:
	case GSI_MBIM_EP_LOOKUP:
@@ -1768,6 +1770,7 @@ gsi_setup(struct usb_function *f, const struct usb_ctrlrequest *ctrl)
	struct gsi_ctrl_pkt *cpkt;
	u8 *buf;
	u32 n;
	bool line_state;

	if (!atomic_read(&gsi->connected)) {
		log_event_dbg("usb cable is not connected");
@@ -1848,8 +1851,11 @@ gsi_setup(struct usb_function *f, const struct usb_ctrlrequest *ctrl)
		break;
	case ((USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE) << 8)
			| USB_CDC_REQ_SET_CONTROL_LINE_STATE:
		line_state = (w_value & GSI_CTRL_DTR ? true : false);
		if (gsi->prot_id == IPA_USB_RMNET)
			gsi->rmnet_dtr_status = line_state;
		log_event_dbg("%s: USB_CDC_REQ_SET_CONTROL_LINE_STATE DTR:%d\n",
				__func__, w_value & GSI_CTRL_DTR ? 1 : 0);
						__func__, line_state);
		gsi_ctrl_send_cpkt_tomodem(gsi, NULL, 0);
		value = 0;
		break;
@@ -2214,6 +2220,9 @@ static void gsi_disable(struct usb_function *f)
	if (gsi->prot_id == IPA_USB_RNDIS)
		rndis_uninit(gsi->params);

	if (gsi->prot_id == IPA_USB_RMNET)
		gsi->rmnet_dtr_status = false;

	/* Disable Control Path */
	if (gsi->c_port.notify &&
		gsi->c_port.notify->driver_data) {
+1 −0
Original line number Diff line number Diff line
@@ -261,6 +261,7 @@ struct f_gsi {
	struct gsi_data_port d_port;
	struct gsi_ctrl_port c_port;
	void *ipc_log_ctxt;
	bool rmnet_dtr_status;
};

static inline struct f_gsi *func_to_gsi(struct usb_function *f)