Reputation: 11
My usb storage device has a 64kB (limited by hardware) buffer used to cache reads/writes which means it can only cache up to 128 blocks(512B) of memory. The SCSI Write-10 command has a total-blocks field that can be up to 256 blocks (128kB). When originally testing the product on Windows 11 it never writes more than 128 blocks at a time but when tested on Linux it sometimes writes more than 128 blocks, which causes the microcontroller to crash.
Is there a way to tell the host OS not to request more than 128 blocks?
I have implemented block limit VPD page, and it works well on Windows 10/11. I even set the block limit to be 64 blocks, it's OK! However, on Linux or MacOS, the host does not appear to be running the block limits command. So what can I do?
Upvotes: 1
Views: 107
Reputation: 3205
Unfortunately, there really isn't great control over the max read and write sizes for USB storage devices. I think your best bet may be to override the unusual_devs
flags for your device by adding a quirk to the usb_storage
module. There's an existing flag US_FL_MAX_SECTORS_64
that limits it to 64 sectors, which, while not optimal, should make the device actually work. This winds up being implemented in drivers/usb/storage/scsiglue.c:slave_configure()
:
/*
* Many devices have trouble transferring more than 32KB at a time,
* while others have trouble with more than 64K. At this time we
* are limiting both to 32K (64 sectores).
*/
if (us->fflags & (US_FL_MAX_SECTORS_64 | US_FL_MAX_SECTORS_MIN)) {
unsigned int max_sectors = 64;
if (us->fflags & US_FL_MAX_SECTORS_MIN)
max_sectors = PAGE_SIZE >> 9;
if (queue_max_hw_sectors(sdev->request_queue) > max_sectors)
blk_queue_max_hw_sectors(sdev->request_queue,
max_sectors);
You set this flag by adding it into the quirks option in the module parameters. If your device's VID and PID are 0x1234 and 0x5678, then you'd do this:
echo 'options usb-storage quirks=1234:5678:m' | sudo tee -a /etc/modprobe.d/my-usb-device-quirks.conf
Then reload the module.
Upvotes: 0