[PATCH] USB: g_mass_storage: Hide caching mode page to improve write speed for Windows

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



If connect an UMS device (for example, an Android phone) to Linux PC and
Windows PC, then copy a big file (~500MB) to the device, you will find that
Linux PC's write speed is much faster than Windows PC. This issue can be fixed
by hiding the "caching mode page" on UMS device.

Previously in f_mass_storage.c: do_mode_sense(), caching mode page was the
only mode page, and it was configured as:
	Write cache enabled (WCE=1)
	Read cache not disabled
	No cache retention priorities

The "Write cache enable"(WCE) bit has different influence for Linux PC and
Windows PC.

For Linux PC, whether WCE is 0 or 1, the write speed from Linux PC to UMS
device has no difference. Linux PC just ignores this flag.

For Windows PC, if
	1. the UMS devices has a valid "caching mode page"
	2. the WCE bit in "caching mode page" is set to 1
	3. the "write-cache buffer flushing" on Windows PC is not turned off

With these three conditions together, Windows PC will send SCSI WRITE COMMAND
with FUA=1 (FUA, force unit access), and FUA=1 will cause UMS device to wait
until the blocks have been written onto the medium, which will drag down write
speed a lot. Unluckily, this is Windows PC's default behavior.

On Windows, the FUA=1 flag can be changed by turning off "write-cache buffer
flushing" under UMS device's properties, but if we do so, Windows will pop up
error message as following:

	Windows could not change the write-caching setting for the device.
	Your device might not support this feature or changing the setting.
								[ OK ]

Windows need to change UMS device's caching mode page, but this page is hard
coded and can't be changed, so there will be error pop up.

To fix this issue, we can just hide the "caching mode page". With this patch,
there will be no influence for Linux PC, because Linux PC does not handle UMS
device's caching mode page; for Windows PC, if it does see the "caching mode
page", it will not send SCSI WRITE COMMAND with FUA=1, and write speed will
become as fast as Linux PC.

Signed-off-by: Leo Song <liangs@xxxxxxxxxxx>
---
 drivers/usb/gadget/f_mass_storage.c |   27 +++------------------------
 1 files changed, 3 insertions(+), 24 deletions(-)

diff --git a/drivers/usb/gadget/f_mass_storage.c b/drivers/usb/gadget/f_mass_storage.c
index 4f1142e..70f3047 100644
--- a/drivers/usb/gadget/f_mass_storage.c
+++ b/drivers/usb/gadget/f_mass_storage.c
@@ -1296,30 +1296,9 @@ static int do_mode_sense(struct fsg_common *common, struct fsg_buffhd *bh)
 
 	/* No block descriptors */
 
-	/*
-	 * The mode pages, in numerical order.  The only page we support
-	 * is the Caching page.
-	 */
-	if (page_code == 0x08 || all_pages) {
-		valid_page = 1;
-		buf[0] = 0x08;		/* Page code */
-		buf[1] = 10;		/* Page length */
-		memset(buf+2, 0, 10);	/* None of the fields are changeable */
-
-		if (!changeable_values) {
-			buf[2] = 0x04;	/* Write cache enable, */
-					/* Read cache not disabled */
-					/* No cache retention priorities */
-			put_unaligned_be16(0xffff, &buf[4]);
-					/* Don't disable prefetch */
-					/* Minimum prefetch = 0 */
-			put_unaligned_be16(0xffff, &buf[8]);
-					/* Maximum prefetch */
-			put_unaligned_be16(0xffff, &buf[10]);
-					/* Maximum prefetch ceiling */
-		}
-		buf += 12;
-	}
+	/* No mode pages */
+
+	valid_page = 1;
 
 	/*
 	 * Check that a valid page was requested and the mode data length
-- 
1.7.1

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux