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

Commit 363b019b authored by Tarun Gupta's avatar Tarun Gupta
Browse files

USB: f_mass_storage.c: Send CSW with correct residue



Incase the data size reported from host is more than
the data received in CBW, CSW hack may send residue
zero. But there might still be data left over from
host to be procssed.

If CSW hack is sent with residue zero, fill pointer
may get stuck to throw away data. Incase of multiple
LUNs, host may issue another command at this time.
This command gets stuck forever, because the buffer
head pointer is still not moved to next and the
throw away data is still not cleared.

Reporting correct residue in this particular case
will resolve the issue with command being stuck and
host also does not report it to be a residue mismatch.

CRs-Fixed: 699965
Change-Id: Ic921e561bb2747c4853ddda832abca6d7f4c5c1e
Signed-off-by: default avatarSujeet Kumar <ksujeet@codeaurora.org>
Signed-off-by: default avatarTarun Gupta <tarung@codeaurora.org>
parent a60b3733
Loading
Loading
Loading
Loading
+14 −1
Original line number Diff line number Diff line
@@ -262,6 +262,7 @@ module_param(msc_vfs_timer_period_ms, int, S_IRUGO | S_IWUSR);
MODULE_PARM_DESC(msc_vfs_timer_period_ms, "Set period for MSC VFS timer");

static int write_error_after_csw_sent;
static int must_report_residue;
static int csw_sent;

struct fsg_dev;
@@ -1001,6 +1002,16 @@ write_error:
			if ((nwritten == amount) && !csw_sent) {
				if (write_error_after_csw_sent)
					break;

				/*
				 * If residue still exists and nothing left to
				 * write, device must send correct residue to
				 * host in this case.
				 */
				if (!amount_left_to_write && common->residue) {
					must_report_residue = 1;
					break;
				}
				/*
				 * Check if any of the buffer is in the
				 * busy state, if any buffer is in busy state,
@@ -1771,8 +1782,10 @@ static int send_status(struct fsg_common *common)
	 * writing on to storage media, need to set
	 * residue to zero,assuming that write will succeed.
	 */
	if (write_error_after_csw_sent)
	if (write_error_after_csw_sent || must_report_residue) {
		write_error_after_csw_sent = 0;
		must_report_residue = 0;
	}
	else
		csw->Residue = 0;
	csw->Status = status;