user26314708
user26314708

Reputation: 11

How to limit the number of blocks written or read in a Write_10 or Read command in Linux?

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

Answers (1)

Mike Andrews
Mike Andrews

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

Related Questions