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

Commit 9cc791bd authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "usb: gadget: f_gsi: Fix memory leak in f_gsi driver"

parents 0235accc 4d150bc9
Loading
Loading
Loading
Loading
+19 −8
Original line number Original line Diff line number Diff line
@@ -618,6 +618,25 @@ static void ipa_disconnect_work_handler(struct gsi_data_port *d_port)


	if (gsi->d_port.out_ep)
	if (gsi->d_port.out_ep)
		usb_gsi_ep_op(gsi->d_port.out_ep, NULL, GSI_EP_OP_FREE_TRBS);
		usb_gsi_ep_op(gsi->d_port.out_ep, NULL, GSI_EP_OP_FREE_TRBS);

	/*
	 * Unconfig the gsi eps after freeing the trbs. If done in
	 * gsi_disable() then since gsi_disable() is called in interrupt context
	 * and the usb_gsi_ep_op() for GSI_EP_OP_FREE_TRBS which is called from
	 * ipa_disconnect_work_handler() a worker thread, can get delayed. So
	 * when gsi_disable() unconfigures the eps, usb_gsi_ep_op() will not be
	 * executed which leads to a memory leak.
	 * Also if this is done in gsi_unbind() then again this is executed in
	 * interrupt context and ipa_disconnect_work_handler() is a worker
	 * thread which can get delayed.
	 */
	if (gadget_is_dwc3(d_port->gadget)) {
		if (gsi->d_port.in_ep)
			msm_ep_unconfig(gsi->d_port.in_ep);
		if (gsi->d_port.out_ep)
			msm_ep_unconfig(gsi->d_port.out_ep);
	}

}
}


static int ipa_suspend_work_handler(struct gsi_data_port *d_port)
static int ipa_suspend_work_handler(struct gsi_data_port *d_port)
@@ -2015,7 +2034,6 @@ fail:
static void gsi_disable(struct usb_function *f)
static void gsi_disable(struct usb_function *f)
{
{
	struct f_gsi *gsi = func_to_gsi(f);
	struct f_gsi *gsi = func_to_gsi(f);
	struct usb_composite_dev *cdev = f->config->cdev;


	atomic_set(&gsi->connected, 0);
	atomic_set(&gsi->connected, 0);


@@ -2042,13 +2060,6 @@ static void gsi_disable(struct usb_function *f)
		return;
		return;
	}
	}


	if (gadget_is_dwc3(cdev->gadget)) {
		if (gsi->d_port.in_ep)
			msm_ep_unconfig(gsi->d_port.in_ep);
		if (gsi->d_port.out_ep)
			msm_ep_unconfig(gsi->d_port.out_ep);
	}

	gsi->data_interface_up = false;
	gsi->data_interface_up = false;


	pr_debug("%s deactivated\n", gsi->function.name);
	pr_debug("%s deactivated\n", gsi->function.name);