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

Commit 2b8d8a02 authored by Jack Pham's avatar Jack Pham
Browse files

usb: f_gsi: Avoid starting transfer if disconnected



There is a possible race in which gsi_disable() is called
while ipa_work_handler() is still in the middle of handling
EVT_CONNECT_IN_PROGRESS event. This leads to an out-of-order
concurrency scenario in which GSI's EPs are first disabled
followed by ipa_connect_channels() proceeding to call GSI
ops to prepare TRBs and start the transfer. After this,
ipa_disconnect_work_handler() is called to free the TRBs
without stopping the transfer, and this results in the
controller hardware accessing stale unmapped DMA pointers.

Fix this specific scenario by avoiding calling
ipa_connect_channels() by peeking at the event queue to see
if EVT_DISCONNECTED was posted after EVT_CONNECT_IN_PROGRESS.

Change-Id: I66b8507eb48f4a994d3c372f1e7e92765abde1b4
Signed-off-by: default avatarJack Pham <jackp@codeaurora.org>
parent 2baec134
Loading
Loading
Loading
Loading
+3 −1
Original line number Diff line number Diff line
@@ -913,10 +913,12 @@ static void ipa_work_handler(struct work_struct *w)
								__func__);
				break;
			}
			ipa_connect_channels(d_port);

			d_port->sm_state = STATE_CONNECT_IN_PROGRESS;
			log_event_dbg("%s: ST_INIT_EVT_CONN_IN_PROG",
					__func__);
			if (peek_event(d_port) != EVT_DISCONNECTED)
				ipa_connect_channels(d_port);
		} else if (event == EVT_HOST_READY) {
			/*
			 * When in a composition such as RNDIS + ADB,