From: Niklas Cassel <cassel@kernel.org>
To: Damien Le Moal <dlemoal@kernel.org>
Cc: linux-ide@vger.kernel.org, Igor Pylypiv <ipylypiv@google.com>,
Shao Mingyin <shao.mingyin@zte.com.cn>,
Hannes Reinecke <hare@kernel.org>,
Niklas Cassel <cassel@kernel.org>
Subject: [PATCH 0/8] ata: libata-scsi: MODE SELECT fixes and cleanups
Date: Tue, 3 Nov 2026 21:54:49 +0100 [thread overview]
Message-ID: <20261103205448.931471-10-cassel@kernel.org> (raw)
This series fixes several problems in the MODE SELECT translation of
libata, most of them related to the FIELD POINTER reported in the sense
data when a MODE SELECT parameter list is rejected, and makes the MODE
SELECT mode page handlers significantly easier to follow.
Most of these bugs were caused by the code being more complicated than
it needs to be.
Each mode page has a fixed format, and may only be sent in that format:
Caching mode page: SPF=0, page_0 format (no SUBPAGE CODE)
Control mode page: SPF=0, page_0 format (no SUBPAGE CODE)
ATA Feature Control mode page: SPF=1, sub_page format (SUBPAGE CODE F2h)
SAT defines the SPF bit of the Caching and Control mode pages as not
changeable and set to zero, and requires it to be set to one for the ATA
Feature Control mode page. A MODE SELECT that sets the SPF bit to a value
that does not match the mode page must therefore be rejected with
INVALID FIELD IN PARAMETER LIST, as required by SPC.
This makes it possible to simplify the code significantly, by passing
the whole mode page, starting with its mode page header, to the
handlers, just like the ata_msense_*() functions generate the whole mode
page. Offsets in the mode page buffer are then the byte numbers of the
mode page, as used in the mode page definitions of SPC, SBC and SAT, the
handlers can compare it with the mode page generated by the matching
ata_msense_*() function without adjusting offsets, and the conversion
done by ata_scsi_mode_select_xlat() becomes correct. This also allows
reporting an invalid PAGE LENGTH at the PAGE LENGTH field, which was not
part of the buffer before.
The series was tested in QEMU, by sending MODE SELECT(6) and MODE
SELECT(10) parameter lists to an AHCI disk via SG_IO and checking the
returned sense data, and by switching the cache_type of the disk.
The FIELD POINTER reported before and after this series, for MODE
SELECT(10) parameter lists without block descriptors unless noted
otherwise:
Parameter list Before After Correct
Caching page, byte 3 changed 9 11 11
Caching page, byte 3 changed, MODE SELECT(6) 5 7 7
Control page, byte 3 changed 9 11 11
ATA Feature Control page, CDL_CTRL 01b 8 12 12
CDL enable while NCQ priority is enabled 7 12 12
Caching page, PAGE LENGTH too short 25 9 9
ATA Feature Control page, PAGE LENGTH too short 19 10 10
Caching page, SUBPAGE CODE 01h 8 9 9
Control page, SUBPAGE CODE FFh 8 9 9
BLOCK DESCRIPTOR LENGTH 16 30 6 6
BLOCK DESCRIPTOR LENGTH 16, MODE SELECT(6) 23 3 3
BLOCK DESCRIPTOR LENGTH 4 18 6 6
Caching page followed by Control page 65535 28 28
Control page followed by 1 byte accepted 20 20
ATA Feature Control page followed by 1 byte 65535 24 24
Caching page, SPF=1, SUBPAGE CODE 00h accepted 8 8
Caching page, SPF=1, SUBPAGE CODE FFh accepted 9 9
"accepted" means that the command completed without error. Before this
series, the Control mode page followed by 1 byte was applied, ignoring the
extra byte, and the ATA Feature Control mode page followed by 1 byte, which
requests enabling CDL, updated the CDL enabled flag of the device even
though the command was rejected. As only one mode page per command is
supported, data after the mode page is rejected at its first byte.
These patches were developed with the help of an AI coding assistant.
Niklas Cassel (7):
ata: libata-scsi: fix MODE SELECT handling of data after the mode page
ata: libata-scsi: do not accept subpage code FFh in MODE SELECT
ata: libata-scsi: reject MODE SELECT mode pages with a wrong SPF bit
ata: libata-scsi: fix MODE SELECT field pointer for unsupported
subpages
ata: libata-scsi: fix MODE SELECT field pointer for block descriptor
length
ata: libata-scsi: pass the whole mode page to the MODE SELECT handlers
ata: libata-scsi: document the MODE SENSE mode page functions
Shao Mingyin (1):
ata: libata-scsi: set the field pointer when rejecting CDL
drivers/ata/libata-scsi.c | 278 ++++++++++++++++++++++++++------------
1 file changed, 195 insertions(+), 83 deletions(-)
base-commit: 6ba53556f93f79e5273d9a5fcd39c3ba3b0ea391
--
2.56.0
next reply other threads:[~2026-11-03 20:54 UTC|newest]
Thread overview: 17+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-11-03 20:54 Niklas Cassel [this message]
2026-11-03 20:54 ` [PATCH 1/8] ata: libata-scsi: fix MODE SELECT handling of data after the mode page Niklas Cassel
2026-11-03 21:20 ` Damien Le Moal
2026-11-03 20:54 ` [PATCH 2/8] ata: libata-scsi: do not accept subpage code FFh in MODE SELECT Niklas Cassel
2026-11-03 21:20 ` Damien Le Moal
2026-11-03 20:54 ` [PATCH 3/8] ata: libata-scsi: reject MODE SELECT mode pages with a wrong SPF bit Niklas Cassel
2026-11-03 21:22 ` Damien Le Moal
2026-11-03 20:54 ` [PATCH 4/8] ata: libata-scsi: fix MODE SELECT field pointer for unsupported subpages Niklas Cassel
2026-11-03 21:23 ` Damien Le Moal
2026-11-03 20:54 ` [PATCH 5/8] ata: libata-scsi: fix MODE SELECT field pointer for block descriptor length Niklas Cassel
2026-11-03 21:24 ` Damien Le Moal
2026-11-03 20:54 ` [PATCH 6/8] ata: libata-scsi: pass the whole mode page to the MODE SELECT handlers Niklas Cassel
2026-11-03 21:33 ` Damien Le Moal
2026-11-03 20:54 ` [PATCH 7/8] ata: libata-scsi: set the field pointer when rejecting CDL Niklas Cassel
2026-11-03 21:34 ` Damien Le Moal
2026-11-03 20:54 ` [PATCH 8/8] ata: libata-scsi: document the MODE SENSE mode page functions Niklas Cassel
2026-11-03 21:36 ` Damien Le Moal
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20261103205448.931471-10-cassel@kernel.org \
--to=cassel@kernel.org \
--cc=dlemoal@kernel.org \
--cc=hare@kernel.org \
--cc=ipylypiv@google.com \
--cc=linux-ide@vger.kernel.org \
--cc=shao.mingyin@zte.com.cn \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox