https://wiki.archlinux.org/title/Solid_state_drive#External_SSD_with_TRIM_support
I'm reading this one more time more carefully. So, first they check sg_readcap to get the LBPME bit, which is 0. Next, they check sg_vpd, which reports the "Unmap Command Supported (LBPU)" bit. In this example, it's 1, so we know that it's actually supported, and can enable it manually. In my case, it's also 0.
So seems like my original understanding was correct:
- When LBPME is set to 1, it gets picked up by the kernel and "just works"
- When LBPME is set to 0, the kernel does not enable UNMAP
- If LBPU is 1, then UNMAP is actually supported, so we switch it on manually in provisioning_mode (a fairly common situation)
- If LBPU is 0, then UNMAP is really not supported (my situation)
So not only does Windows ignore LBPME, but it also ignores LBPU. Probably because the driver was also made by the chip manufacturer, to they simply decided to ignore any bits as long as they have identified the device and know what it should be actually capable of. Or maybe it's because Linux treats the device as JMS561, which indeed does not have UNMAP.
Here is what makes me think this:
$ sudo sg_vpd -a /dev/sdc
Supported VPD pages VPD page:
Supported VPD pages [sv]
Unit serial number [sn]
Device identification [di]
Block limits (SBC) [bl]
Logical block provisioning (SBC) [lbpv]
0xde
0xdf
Unit serial number VPD page:
Unit serial number: DB98765432146
Device Identification VPD page:
Addressed logical unit:
designator type: NAA, code set: Binary
0x3042987654321460
designator type: T10 vendor identification, code set: ASCII
vendor id: SABRENT
vendor specific: DISK03
Block limits VPD page (SBC):
Write same non-zero (WSNZ): 0
Maximum compare and write length: 0 blocks [Command not implemented]
Optimal transfer length granularity: 1 blocks
Maximum transfer length: 65535 blocks
Optimal transfer length: 65535 blocks
Maximum prefetch transfer length: 65535 blocks
Maximum unmap LBA count: 0 [Unmap command not implemented]
Maximum unmap block descriptor count: 0 [Unmap command not implemented]
Optimal unmap granularity: 0 blocks [not reported]
Unmap granularity alignment valid: false
Unmap granularity alignment: 0 [invalid]
Maximum write same length: 0 blocks [not reported]
Maximum atomic transfer length: 0 blocks [not reported]
Atomic alignment: 0 [unaligned atomic writes permitted]
Atomic transfer length granularity: 0 [no granularity requirement
Maximum atomic transfer length with atomic boundary: 0 blocks [not
reported]
Maximum atomic boundary size: 0 blocks [can only write atomic 1 block]
Logical block provisioning VPD page (SBC):
Unmap command supported (LBPU): 0
Write same (16) with unmap bit supported (LBPWS): 0
Write same (10) with unmap bit supported (LBPWS10): 0
Logical block provisioning read zeros (LBPRZ): 0
Anchored LBAs supported (ANC_SUP): 0
Threshold exponent: 1
Descriptor present (DP): 0
Minimum percentage: 0 [not reported]
Provisioning type: 0 (not known or fully provisioned)
Threshold percentage: 0 [percentages not supported]
It says "not implemented" - which could mean "in the driver", or in the firmware. Either way, it's not the common and fixable situation of one bit not set correctly. It's a problem on a whole another level.
Oh, those chip manufacturers. Who needs SCSI specifications when it "works on Windows (R)"? x_x