[PATCH v2 1/2] scsi: libsas: Define sas_identify_frame_local via struct_group

From: Ronja Meyer

Date: Tue May 26 2026 - 10:41:00 EST


The pm80 drivers both need a variant of the sas_identify_frame struct
without the CRC struct member. The pm80xx driver previously duplicated
the struct, omitting this field, to sas_identify_frame_local in:
commit 5990fd57ebea ("scsi: pm80xx: redefine sas_identify_frame structure")

The pm8001 driver also needs the _local variant. Instead of duplicating
the struct again, let's define it as a struct group inside the main
sas_identify_frame struct and remove the duplicate in the pm80xx driver.

Sending to stable, as this change is required for the fortify-panic fix
later in this chain to apply cleanly.

Cc: stable@xxxxxxxxxxxxxxx
Fixes: dbf9bfe61571 ("[SCSI] pm8001: add SAS/SATA HBA driver")
Signed-off-by: Ronja Meyer <rnj@xxxxxxxxxx>
---
drivers/scsi/pm8001/pm80xx_hwi.h | 96 --------------------------
include/scsi/sas.h | 144 ++++++++++++++++++++-------------------
2 files changed, 74 insertions(+), 166 deletions(-)

diff --git a/drivers/scsi/pm8001/pm80xx_hwi.h b/drivers/scsi/pm8001/pm80xx_hwi.h
index d8a63b7fed6a..2fa54b901a2e 100644
--- a/drivers/scsi/pm8001/pm80xx_hwi.h
+++ b/drivers/scsi/pm8001/pm80xx_hwi.h
@@ -236,102 +236,6 @@
/* Port recovery timeout, 10000 ms for PM8006 controller */
#define CHIP_8006_PORT_RECOVERY_TIMEOUT 0x640000

-#ifdef __LITTLE_ENDIAN_BITFIELD
-struct sas_identify_frame_local {
- /* Byte 0 */
- u8 frame_type:4;
- u8 dev_type:3;
- u8 _un0:1;
-
- /* Byte 1 */
- u8 _un1;
-
- /* Byte 2 */
- union {
- struct {
- u8 _un20:1;
- u8 smp_iport:1;
- u8 stp_iport:1;
- u8 ssp_iport:1;
- u8 _un247:4;
- };
- u8 initiator_bits;
- };
-
- /* Byte 3 */
- union {
- struct {
- u8 _un30:1;
- u8 smp_tport:1;
- u8 stp_tport:1;
- u8 ssp_tport:1;
- u8 _un347:4;
- };
- u8 target_bits;
- };
-
- /* Byte 4 - 11 */
- u8 _un4_11[8];
-
- /* Byte 12 - 19 */
- u8 sas_addr[SAS_ADDR_SIZE];
-
- /* Byte 20 */
- u8 phy_id;
-
- u8 _un21_27[7];
-
-} __packed;
-
-#elif defined(__BIG_ENDIAN_BITFIELD)
-struct sas_identify_frame_local {
- /* Byte 0 */
- u8 _un0:1;
- u8 dev_type:3;
- u8 frame_type:4;
-
- /* Byte 1 */
- u8 _un1;
-
- /* Byte 2 */
- union {
- struct {
- u8 _un247:4;
- u8 ssp_iport:1;
- u8 stp_iport:1;
- u8 smp_iport:1;
- u8 _un20:1;
- };
- u8 initiator_bits;
- };
-
- /* Byte 3 */
- union {
- struct {
- u8 _un347:4;
- u8 ssp_tport:1;
- u8 stp_tport:1;
- u8 smp_tport:1;
- u8 _un30:1;
- };
- u8 target_bits;
- };
-
- /* Byte 4 - 11 */
- u8 _un4_11[8];
-
- /* Byte 12 - 19 */
- u8 sas_addr[SAS_ADDR_SIZE];
-
- /* Byte 20 */
- u8 phy_id;
-
- u8 _un21_27[7];
-} __packed;
-#else
-#error "Bitfield order not defined!"
-#endif
-
struct mpi_msg_hdr {
__le32 header; /* Bits [11:0] - Message operation code */
/* Bits [15:12] - Message Category */
diff --git a/include/scsi/sas.h b/include/scsi/sas.h
index 71b749bed3b0..90f3081a3270 100644
--- a/include/scsi/sas.h
+++ b/include/scsi/sas.h
@@ -252,48 +252,50 @@ struct host_to_dev_fis {
*/
#ifdef __LITTLE_ENDIAN_BITFIELD
struct sas_identify_frame {
- /* Byte 0 */
- u8 frame_type:4;
- u8 dev_type:3;
- u8 _un0:1;
-
- /* Byte 1 */
- u8 _un1;
-
- /* Byte 2 */
- union {
- struct {
- u8 _un20:1;
- u8 smp_iport:1;
- u8 stp_iport:1;
- u8 ssp_iport:1;
- u8 _un247:4;
+ __struct_group(sas_identify_frame_local, payload, __packed,
+ /* Byte 0 */
+ u8 frame_type:4;
+ u8 dev_type:3;
+ u8 _un0:1;
+
+ /* Byte 1 */
+ u8 _un1;
+
+ /* Byte 2 */
+ union {
+ struct {
+ u8 _un20:1;
+ u8 smp_iport:1;
+ u8 stp_iport:1;
+ u8 ssp_iport:1;
+ u8 _un247:4;
+ };
+ u8 initiator_bits;
};
- u8 initiator_bits;
- };

- /* Byte 3 */
- union {
- struct {
- u8 _un30:1;
- u8 smp_tport:1;
- u8 stp_tport:1;
- u8 ssp_tport:1;
- u8 _un347:4;
+ /* Byte 3 */
+ union {
+ struct {
+ u8 _un30:1;
+ u8 smp_tport:1;
+ u8 stp_tport:1;
+ u8 ssp_tport:1;
+ u8 _un347:4;
+ };
+ u8 target_bits;
};
- u8 target_bits;
- };

- /* Byte 4 - 11 */
- u8 _un4_11[8];
+ /* Byte 4 - 11 */
+ u8 _un4_11[8];

- /* Byte 12 - 19 */
- u8 sas_addr[SAS_ADDR_SIZE];
+ /* Byte 12 - 19 */
+ u8 sas_addr[SAS_ADDR_SIZE];

- /* Byte 20 */
- u8 phy_id;
+ /* Byte 20 */
+ u8 phy_id;

- u8 _un21_27[7];
+ u8 _un21_27[7];
+ );

__be32 crc;
} __attribute__ ((packed));
@@ -473,48 +475,50 @@ struct report_phy_sata_resp {

#elif defined(__BIG_ENDIAN_BITFIELD)
struct sas_identify_frame {
- /* Byte 0 */
- u8 _un0:1;
- u8 dev_type:3;
- u8 frame_type:4;
-
- /* Byte 1 */
- u8 _un1;
-
- /* Byte 2 */
- union {
- struct {
- u8 _un247:4;
- u8 ssp_iport:1;
- u8 stp_iport:1;
- u8 smp_iport:1;
- u8 _un20:1;
+ __struct_group(sas_identify_frame_local, payload, __packed,
+ /* Byte 0 */
+ u8 _un0:1;
+ u8 dev_type:3;
+ u8 frame_type:4;
+
+ /* Byte 1 */
+ u8 _un1;
+
+ /* Byte 2 */
+ union {
+ struct {
+ u8 _un247:4;
+ u8 ssp_iport:1;
+ u8 stp_iport:1;
+ u8 smp_iport:1;
+ u8 _un20:1;
+ };
+ u8 initiator_bits;
};
- u8 initiator_bits;
- };

- /* Byte 3 */
- union {
- struct {
- u8 _un347:4;
- u8 ssp_tport:1;
- u8 stp_tport:1;
- u8 smp_tport:1;
- u8 _un30:1;
+ /* Byte 3 */
+ union {
+ struct {
+ u8 _un347:4;
+ u8 ssp_tport:1;
+ u8 stp_tport:1;
+ u8 smp_tport:1;
+ u8 _un30:1;
+ };
+ u8 target_bits;
};
- u8 target_bits;
- };

- /* Byte 4 - 11 */
- u8 _un4_11[8];
+ /* Byte 4 - 11 */
+ u8 _un4_11[8];

- /* Byte 12 - 19 */
- u8 sas_addr[SAS_ADDR_SIZE];
+ /* Byte 12 - 19 */
+ u8 sas_addr[SAS_ADDR_SIZE];

- /* Byte 20 */
- u8 phy_id;
+ /* Byte 20 */
+ u8 phy_id;

- u8 _un21_27[7];
+ u8 _un21_27[7];
+ );

__be32 crc;
} __attribute__ ((packed));

--
2.54.0.746.g67dd491aae-goog