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

Commit aa860b5b authored by qctecmdr's avatar qctecmdr Committed by Gerrit - the friendly Code Review server
Browse files

Merge "usb: f_gsi: Send zero length packet for MBIM/GPS on cable connect"

parents fdf6a38b 640176fc
Loading
Loading
Loading
Loading
+43 −6
Original line number Diff line number Diff line
@@ -19,7 +19,7 @@ static struct gsi_inst_status {
	struct gsi_opts *opts;
} inst_status[IPA_USB_MAX_TETH_PROT_SIZE];

#define MAX_CDEV_INSTANCES		3
#define MAX_CDEV_INSTANCES		4

static int major;
static struct class *gsi_class;
@@ -1533,6 +1533,7 @@ static long gsi_ctrl_dev_ioctl(struct file *fp, unsigned int cmd,
		atomic_set(&c_port->ctrl_online, 1);
		break;
	case QTI_CTRL_GET_LINE_STATE:
	case GSI_MBIM_GPS_USB_STATUS:
		val = atomic_read(&gsi->connected);
		if (gsi->prot_id == IPA_USB_RMNET)
			val = gsi->rmnet_dtr_status;
@@ -1742,6 +1743,8 @@ static int gsi_function_ctrl_port_init(struct f_gsi *gsi)
		strlcat(gsi->c_port.name, GSI_MBIM_CTRL_NAME, sz);
	else if (gsi->prot_id == IPA_USB_DIAG)
		strlcat(gsi->c_port.name, GSI_DPL_CTRL_NAME, sz);
	else if (gsi->prot_id == IPA_USB_GPS)
		strlcat(gsi->c_port.name, GSI_GPS_CTRL_NAME, sz);
	else
		ctrl_dev_create = false;

@@ -2497,7 +2500,9 @@ static int gsi_set_alt(struct usb_function *f, unsigned int intf,
	atomic_set(&gsi->connected, 1);

	/* send 0 len pkt to qti to notify state change */
	if (gsi->prot_id == IPA_USB_DIAG)
	if (gsi->prot_id == IPA_USB_DIAG ||
			gsi->prot_id == IPA_USB_GPS ||
			gsi->prot_id == IPA_USB_MBIM)
		gsi_ctrl_send_cpkt_tomodem(gsi, NULL, 0);

	return ret;
@@ -2529,7 +2534,7 @@ static void gsi_disable(struct usb_function *f)
	}

	gsi_ctrl_clear_cpkt_queues(gsi, false);
	/* send 0 len pkt to qti/qbi to notify state change */
	/* send 0 len pkt to qti/qbi/gps to notify state change */
	gsi_ctrl_send_cpkt_tomodem(gsi, NULL, 0);
	gsi->c_port.notify_req_queued = false;
	/* Disable Data Path  - only if it was initialized already (alt=1) */
@@ -2559,6 +2564,11 @@ static void gsi_suspend(struct usb_function *f)
		return;
	}

	if (!gsi->data_interface_up) {
		log_event_dbg("%s: suspend done\n", __func__);
		return;
	}

	block_db = true;
	usb_gsi_ep_op(gsi->d_port.in_ep, (void *)&block_db,
			GSI_EP_OP_SET_CLR_BLOCK_DBL);
@@ -2588,6 +2598,11 @@ static void gsi_resume(struct usb_function *f)
	/* Check any pending cpkt, and queue immediately on resume */
	gsi_ctrl_send_notification(gsi);

	if (!gsi->data_interface_up) {
		log_event_dbg("%s: resume done\n", __func__);
		return;
	}

	/*
	 * Linux host does not send RNDIS_MSG_INIT or non-zero
	 * RNDIS_MESSAGE_PACKET_FILTER after performing bus resume.
@@ -2849,9 +2864,11 @@ static int gsi_bind(struct usb_configuration *c, struct usb_function *f)
			goto fail;
	}

	if (gsi->prot_id != IPA_USB_GPS) {
		status = gsi->data_id = usb_interface_id(c, f);
		if (status < 0)
			goto fail;
	}

	switch (gsi->prot_id) {
	case IPA_USB_RNDIS:
@@ -3137,6 +3154,18 @@ static int gsi_bind(struct usb_configuration *c, struct usb_function *f)
		info.in_req_num_buf = GSI_NUM_IN_BUFFERS;
		info.notify_buf_len = sizeof(struct usb_cdc_notification);
		break;
	case IPA_USB_GPS:
		info.string_defs = gps_string_defs;
		info.ctrl_str_idx = 0;
		info.ctrl_desc = &gps_interface_desc;
		info.fs_notify_desc = &gps_fs_notify_desc;
		info.hs_notify_desc = &gps_hs_notify_desc;
		info.ss_notify_desc = &gps_ss_notify_desc;
		info.fs_desc_hdr = gps_fs_function;
		info.hs_desc_hdr = gps_hs_function;
		info.ss_desc_hdr = gps_ss_function;
		info.notify_buf_len = sizeof(struct usb_cdc_notification);
		break;
	default:
		log_event_err("%s: Invalid prot id %d", __func__,
							gsi->prot_id);
@@ -3147,6 +3176,9 @@ static int gsi_bind(struct usb_configuration *c, struct usb_function *f)
	if (status)
		goto dereg_rndis;

	if (gsi->prot_id == IPA_USB_GPS)
		goto skip_ipa_init;

	status = ipa_register_ipa_ready_cb(ipa_ready_callback, gsi);
	if (!status) {
		log_event_info("%s: ipa is not ready", __func__);
@@ -3172,6 +3204,7 @@ static int gsi_bind(struct usb_configuration *c, struct usb_function *f)

	gsi->d_port.sm_state = STATE_INITIALIZED;

skip_ipa_init:
	DBG(cdev, "%s: %s speed IN/%s OUT/%s NOTIFY/%s\n",
			f->name,
			gadget_is_superspeed(c->cdev->gadget) ? "super" :
@@ -3265,6 +3298,10 @@ static int gsi_bind_config(struct f_gsi *gsi)
		gsi->function.name = "dpl";
		gsi->function.strings = qdss_gsi_strings;
		break;
	case IPA_USB_GPS:
		gsi->function.name = "gps";
		gsi->function.strings = gps_strings;
		break;
	default:
		log_event_err("%s: invalid prot id %d", __func__, prot_id);
		return -EINVAL;
+90 −1
Original line number Diff line number Diff line
@@ -24,6 +24,7 @@
#define GSI_RMNET_CTRL_NAME "rmnet_ctrl"
#define GSI_MBIM_CTRL_NAME "android_mbim"
#define GSI_DPL_CTRL_NAME "dpl_ctrl"
#define GSI_GPS_CTRL_NAME "gps"
#define GSI_CTRL_NAME_LEN (sizeof(GSI_MBIM_CTRL_NAME)+2)
#define GSI_MAX_CTRL_PKT_SIZE 8192
#define GSI_CTRL_DTR (1 << 0)
@@ -331,7 +332,8 @@ static enum ipa_usb_teth_prot name_to_prot_id(const char *name)
		return IPA_USB_MBIM;
	if (!strncasecmp(name, "dpl", strlen("dpl")))
		return IPA_USB_DIAG;

	if (!strncasecmp(name, "gps", strlen("gps")))
		return IPA_USB_GPS;
error:
	return -EINVAL;
}
@@ -1430,4 +1432,91 @@ static struct usb_gadget_strings *qdss_gsi_strings[] = {
	&qdss_gsi_string_table,
	NULL,
};

/* gps device descriptor */
static struct usb_interface_descriptor gps_interface_desc = {
	.bLength =		USB_DT_INTERFACE_SIZE,
	.bDescriptorType =	USB_DT_INTERFACE,
	.bNumEndpoints =	1,
	.bInterfaceClass =	USB_CLASS_VENDOR_SPEC,
	.bInterfaceSubClass =	USB_CLASS_VENDOR_SPEC,
	.bInterfaceProtocol =	USB_CLASS_VENDOR_SPEC,
	/* .iInterface = DYNAMIC */
};

/* Full speed support */
static struct usb_endpoint_descriptor gps_fs_notify_desc = {
	.bLength =		USB_DT_ENDPOINT_SIZE,
	.bDescriptorType =	USB_DT_ENDPOINT,
	.bEndpointAddress =	USB_DIR_IN,
	.bmAttributes =		USB_ENDPOINT_XFER_INT,
	.wMaxPacketSize =	cpu_to_le16(MAX_NOTIFY_SIZE),
	.bInterval =		1 << LOG2_STATUS_INTERVAL_MSEC,
};

static struct usb_descriptor_header *gps_fs_function[] = {
	(struct usb_descriptor_header *) &gps_interface_desc,
	(struct usb_descriptor_header *) &gps_fs_notify_desc,
	NULL,
};

/* High speed support */
static struct usb_endpoint_descriptor gps_hs_notify_desc  = {
	.bLength =		USB_DT_ENDPOINT_SIZE,
	.bDescriptorType =	USB_DT_ENDPOINT,
	.bEndpointAddress =	USB_DIR_IN,
	.bmAttributes =		USB_ENDPOINT_XFER_INT,
	.wMaxPacketSize =	cpu_to_le16(MAX_NOTIFY_SIZE),
	.bInterval =		LOG2_STATUS_INTERVAL_MSEC + 4,
};

static struct usb_descriptor_header *gps_hs_function[] = {
	(struct usb_descriptor_header *) &gps_interface_desc,
	(struct usb_descriptor_header *) &gps_hs_notify_desc,
	NULL,
};

/* Super speed support */
static struct usb_endpoint_descriptor gps_ss_notify_desc  = {
	.bLength =		USB_DT_ENDPOINT_SIZE,
	.bDescriptorType =	USB_DT_ENDPOINT,
	.bEndpointAddress =	USB_DIR_IN,
	.bmAttributes =		USB_ENDPOINT_XFER_INT,
	.wMaxPacketSize =	cpu_to_le16(MAX_NOTIFY_SIZE),
	.bInterval =		LOG2_STATUS_INTERVAL_MSEC + 4,
};

static struct usb_ss_ep_comp_descriptor gps_ss_notify_comp_desc = {
	.bLength =		sizeof(gps_ss_notify_comp_desc),
	.bDescriptorType =	USB_DT_SS_ENDPOINT_COMP,

	/* the following 3 values can be tweaked if necessary */
	/* .bMaxBurst =		0, */
	/* .bmAttributes =	0, */
	.wBytesPerInterval =	cpu_to_le16(MAX_NOTIFY_SIZE),
};

static struct usb_descriptor_header *gps_ss_function[] = {
	(struct usb_descriptor_header *) &gps_interface_desc,
	(struct usb_descriptor_header *) &gps_ss_notify_desc,
	(struct usb_descriptor_header *) &gps_ss_notify_comp_desc,
	NULL,
};

/* String descriptors */

static struct usb_string gps_string_defs[] = {
	[0].s = "GPS",
	{  } /* end of list */
};

static struct usb_gadget_strings gps_string_table = {
	.language =		0x0409,	/* en-us */
	.strings =		gps_string_defs,
};

static struct usb_gadget_strings *gps_strings[] = {
	&gps_string_table,
	NULL,
};
#endif
+1 −0
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@ enum ipa_usb_teth_prot {
	IPA_USB_MBIM = 3,
	IPA_USB_DIAG = 4,
	IPA_USB_RMNET_CV2X = 5,
	IPA_USB_GPS = 6,
	IPA_USB_MAX_TETH_PROT_SIZE
};