Linux ATA/IDE development
 help / color / mirror / Atom feed
* [PATCH 0/8] ata: libata-scsi: MODE SELECT fixes and cleanups
@ 2026-11-03 20:54 Niklas Cassel
  2026-11-03 20:54 ` [PATCH 1/8] ata: libata-scsi: fix MODE SELECT handling of data after the mode page Niklas Cassel
                   ` (7 more replies)
  0 siblings, 8 replies; 17+ messages in thread
From: Niklas Cassel @ 2026-11-03 20:54 UTC (permalink / raw)
  To: Damien Le Moal
  Cc: linux-ide, Igor Pylypiv, Shao Mingyin, Hannes Reinecke,
	Niklas Cassel

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


^ permalink raw reply	[flat|nested] 17+ messages in thread

end of thread, other threads:[~2026-11-03 21:36 UTC | newest]

Thread overview: 17+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-11-03 20:54 [PATCH 0/8] ata: libata-scsi: MODE SELECT fixes and cleanups Niklas Cassel
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

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox