Re: [PATCH] ata: libata-core: Allow capacity transition to zero for locked drives
From: Niklas Cassel
Date: Wed Jun 24 2026 - 10:26:43 EST
On Mon, Jun 22, 2026 at 11:28:44AM -0700, TJ Adams wrote:
> Commit 91842ed844a0 ("ata: libata-core: Set capacity to zero for a
> security locked drive") introduced setting the device capacity (n_sectors)
> to zero in ata_dev_configure() if the drive is security locked.
>
> However, during runtime revalidation, ata_dev_revalidate() compares the
> new capacity (now 0) with the old capacity (>0) and detects a mismatch.
> Since it does not consider the locked status, it returns -ENODEV.
When booting with a security locked drive (that is not the boot device):
ata_eh_revalidate_and_attach()
-> ata_dev_read_id()
-> ata_dev_configure() <- sets dev->n_sectors to 0
sets ATA_EHI_SETMODE
ata_dev_set_mode()
-> ata_dev_revalidate()
ata_dev_revalidate()
sets local variable n_sectors to dev->n_sectors
-> ata_dev_reread_id()
-> ata_dev_read_id()
-> ata_dev_configure() will one again set dev->n_sectors to 0
/* verify n_sectors hasn't changed */
if (dev->class != ATA_DEV_ATA || !n_sectors ||
dev->n_sectors == n_sectors)
return 0;
Please explain how you reproduce this.
As far as I can see the local n_sectors variable will be 0,
and the function call to ata_dev_configure() will set dev->n_sectors
to 0, so this should, AFAICT, never get a "n_sectors mismatch" print.
I even tried to reproduce with doing a suspend + resume (using QEMU),
such that ata_dev_revalidate() will be called again:
$ sudo dmesg | grep -E "locked|suspend|disable device|ata_dev_revalidate"
[ 0.988248] ata2.00: Security locked, setting capacity to zero
[ 0.993442] ata1.00: debug print: ata_dev_revalidate
[ 0.994729] ata2.00: debug print: ata_dev_revalidate
[ 0.995918] ata2.00: Security locked, setting capacity to zero
[ 40.239682] PM: suspend entry (deep)
[ 40.300128] PM: suspend devices took 0.020 seconds
[ 45.738412] PM: suspend exit
[ 45.985092] ata2.00: debug print: ata_dev_revalidate
[ 45.986698] ata2.00: Security locked, setting capacity to zero
[ 45.988530] ata1.00: debug print: ata_dev_revalidate
[ 45.993331] ata1.00: debug print: ata_dev_revalidate
[ 45.994525] ata2.00: debug print: ata_dev_revalidate
[ 45.995194] ata2.00: Security locked, setting capacity to zero
Since you seem to state that the old capacity (local variable n_sectors)
is > 0, it seems like the device wasn't locked during the initial boot /
ata_dev_configure() call.
Are you perhaps unlocking the device in firmware, so it is unlocked at
boot, and then when you suspend, you lose power to the drive, so when
you resume, the drive is locked?
Kind regards,
Niklas