scsi: qla2xxx: Replace __le16 bitfields with scalar and accessors

C bitfield packing order is implementation-defined: GCC packs LSB-first
on little-endian targets and MSB-first on big-endian targets.  The
__le16 bitfield declarations for vp_index/sof_type in the 29xx extended
IOCB structures produce incorrect bit positions on big-endian hosts, and
Sparse cannot enforce endianness checks on bitfield members.

Replace the three sets of __le16 bitfields (in els_entry_24xx_ext,
els_sts_entry_24xx_ext, and abts_entry_24xx_ext) with a single __le16
scalar field and provide inline accessor functions that use proper
le16_to_cpu()/cpu_to_le16() with shift-and-mask operations.

Signed-off-by: Nilesh Javali <njavali@marvell.com>
Reviewed-by: Hannes Reinecke <hare@kernel.org>
Link: https://patch.msgid.link/20260723050413.3897522-42-njavali@marvell.com
Signed-off-by: Martin K. Petersen (Oracle) <mkp@kernel.org>
This commit is contained in:
Nilesh Javali 2026-07-23 10:33:58 +05:30 committed by Martin K. Petersen (Oracle)
parent 34a40e0dff
commit 3cfd2f74b1
3 changed files with 42 additions and 20 deletions

View File

@ -24,6 +24,33 @@
* Access on a host-endian value via le16_to_cpu(vp_index) & CMD_EXT_VP_INDEX_MASK.
*/
#define CMD_EXT_VP_INDEX_MASK 0x01ff
/*
* Combined vp_index/sof_type field layout (used by ELS and ABTS ext IOCBs):
* bits [8:0] - VP index (9 bits)
* bits [11:9] - reserved
* bits [15:12] - SOF type (4 bits)
*/
#define EXT_VP_SOF_VP_INDEX_MASK 0x01ff
#define EXT_VP_SOF_SOF_TYPE_SHIFT 12
#define EXT_VP_SOF_SOF_TYPE_MASK 0xf000
static inline u16 qla_ext_get_vp_index(__le16 vp_sof)
{
return le16_to_cpu(vp_sof) & EXT_VP_SOF_VP_INDEX_MASK;
}
static inline u16 qla_ext_get_sof_type(__le16 vp_sof)
{
return (le16_to_cpu(vp_sof) >> EXT_VP_SOF_SOF_TYPE_SHIFT) & 0xf;
}
static inline __le16 qla_ext_build_vp_sof(u16 vp_idx, u16 sof_type)
{
return cpu_to_le16((vp_idx & EXT_VP_SOF_VP_INDEX_MASK) |
((sof_type & 0xf) << EXT_VP_SOF_SOF_TYPE_SHIFT));
}
/*
* ISP queue - command entry structure definition.
*/
@ -393,9 +420,7 @@ struct els_entry_24xx_ext {
__le16 tx_dsd_count;
__le16 vp_index : 9; /* VP Index 9bits */
__le16 reserved_1_sof : 3;
__le16 sof_type : 4;
__le16 vp_index_sof; /* bits [8:0]=VP index, [15:12]=SOF type */
__le32 rx_xchg_address; /* Receive exchange address. */
__le16 rx_dsd_count;
@ -444,9 +469,7 @@ struct els_sts_entry_24xx_ext {
__le16 reserved_1;
__le16 vp_index : 9; /* VP Index 9bits */
__le16 reserved_1_sof : 3;
__le16 sof_type : 4;
__le16 vp_index_sof; /* bits [8:0]=VP index, [15:12]=SOF type */
__le32 rx_xchg_address; /* Receive exchange address. */
__le16 reserved_2;
@ -563,9 +586,7 @@ struct abts_entry_24xx_ext {
__le16 nport_handle; /* type 0x54 only */
__le16 control_flags; /* type 0x55 only */
__le16 vp_idx : 9; /* VP index 9 bits */
__le16 reserved_1_sof : 3;
__le16 sof_type : 4; /* sof_type is upper nibble */
__le16 vp_idx_sof; /* bits [8:0]=VP index, [15:12]=SOF type */
__le32 rx_xch_addr;

View File

@ -890,8 +890,8 @@ qla_sts_fwi2_extract(struct qla_hw_data *ha, void *pkt,
* Both layouts have the same 16-bit slot at offset 14, but it is encoded
* differently:
* - 24xx: separate u8 vp_index + u8 sof_type with EST_SOFI3 (1 << 4)
* - 29xx: __le16 with bitfields { vp_index:9, reserved_1_sof:3,
* sof_type:4 } and ELS_EXT_EST_SOFI3
* - 29xx: __le16 vp_index_sof with bits [8:0]=VP index, [15:12]=SOF type
* and ELS_EXT_EST_SOFI3
* so this is the single point in the driver that knows about that
* encoding split.
*/
@ -901,8 +901,8 @@ qla_els_set_vp_sof(struct scsi_qla_host *vha, void *pkt, u16 vp_idx)
if (IS_QLA29XX(vha->hw)) {
struct els_entry_24xx_ext *ext = pkt;
ext->vp_index = vp_idx;
ext->sof_type = ELS_EXT_EST_SOFI3;
ext->vp_index_sof =
qla_ext_build_vp_sof(vp_idx, ELS_EXT_EST_SOFI3);
} else {
struct els_entry_24xx *e = pkt;

View File

@ -90,13 +90,11 @@ static inline void display_Laser_info(scsi_qla_host_t *vha,
(uint8_t *)(abts_ptr), sizeof(*(abts_ptr))); \
} while (0)
#define QLA_BUILD_ABTS_BA_ACC(rsp, src, sof_val, fctl) do { \
#define QLA_BUILD_ABTS_BA_ACC(rsp, src, fctl) do { \
memset((rsp), 0, sizeof(*(rsp))); \
(rsp)->entry_type = ABTS_RSP_TYPE; \
(rsp)->entry_count = 1; \
(rsp)->nport_handle = (src)->nport_handle; \
(rsp)->vp_idx = (src)->vp_idx; \
(rsp)->sof_type = (sof_val); \
(rsp)->rx_xch_addr = (src)->rx_xch_addr; \
(rsp)->d_id[0] = (src)->s_id[0]; \
(rsp)->d_id[1] = (src)->s_id[1]; \
@ -215,14 +213,17 @@ qla24xx_process_abts(struct scsi_qla_host *vha, struct purex_item *pkt)
if (IS_QLA29XX(ha)) {
struct abts_entry_24xx_ext *rsp_ext = rsp_pkt;
QLA_BUILD_ABTS_BA_ACC(rsp_ext, abts_ext,
abts_ext->sof_type, fctl);
QLA_BUILD_ABTS_BA_ACC(rsp_ext, abts_ext, fctl);
rsp_ext->vp_idx_sof = qla_ext_build_vp_sof(
qla_ext_get_vp_index(abts_ext->vp_idx_sof),
qla_ext_get_sof_type(abts_ext->vp_idx_sof));
QLA_LOG_ISSUE_ABTS_RSP(vha, rsp_ext, dma, rval);
} else {
struct abts_entry_24xx *abts_rsp = rsp_pkt;
QLA_BUILD_ABTS_BA_ACC(abts_rsp, abts,
abts->sof_type & 0xf0, fctl);
QLA_BUILD_ABTS_BA_ACC(abts_rsp, abts, fctl);
abts_rsp->vp_idx = abts->vp_idx;
abts_rsp->sof_type = abts->sof_type & 0xf0;
QLA_LOG_ISSUE_ABTS_RSP(vha, abts_rsp, dma, rval);
}