mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2026-09-22 09:34:56 +02:00
scsi: qla2xxx: Fix endianness annotations in vp_rpt_id_entry structures
The vp_rpt_id_entry_24xx and vp_rpt_id_entry_24xx_ext DMA structures use
plain uint16_t for fip_flags and bbcr fields that the firmware writes in
little-endian format. On big-endian hosts, reading bbcr without
le16_to_cpu() produces an incorrect value, breaking the buffer-to-buffer
credit enable detection.
Additionally, the 29xx ext struct uses __le16 bitfields for
vp_idx:9/vp_status:7 which suffer from architecture-dependent bit
packing order (same class of bug fixed in the ELS/ABTS extended IOCBs).
Fix by:
- Changing uint16_t fip_flags/bbcr to __le16 in both qla_fw.h
and qla_fw29.h (enables Sparse endianness checking)
- Replacing the __le16 bitfields with a scalar __le16 vp_idx_status
and defined shift/mask constants
- Adding le16_to_cpu() at the bbcr and vp_idx_status access sites
in qla_mbx.c
Signed-off-by: Nilesh Javali <njavali@marvell.com>
Reviewed-by: Hannes Reinecke <hare@kernel.org>
Link: https://patch.msgid.link/20260723050413.3897522-43-njavali@marvell.com
Signed-off-by: Martin K. Petersen (Oracle) <mkp@kernel.org>
This commit is contained in:
committed by
Martin K. Petersen (Oracle)
parent
3cfd2f74b1
commit
53fc489ad3
@@ -1538,7 +1538,7 @@ struct vp_rpt_id_entry_24xx {
|
||||
#define TOPO_N2N 0x4
|
||||
#define TOPO_F 0x6
|
||||
|
||||
uint16_t fip_flags;
|
||||
__le16 fip_flags;
|
||||
uint8_t rsv2[12];
|
||||
|
||||
uint8_t ls_rjt_vendor;
|
||||
@@ -1548,13 +1548,13 @@ struct vp_rpt_id_entry_24xx {
|
||||
|
||||
uint8_t port_name[8];
|
||||
uint8_t node_name[8];
|
||||
uint16_t bbcr;
|
||||
__le16 bbcr;
|
||||
uint8_t reserved_5[6];
|
||||
} f1;
|
||||
struct _f2 { /* format 2: N2N direct connect */
|
||||
uint8_t vpstat1_subcode;
|
||||
uint8_t flags;
|
||||
uint16_t fip_flags;
|
||||
__le16 fip_flags;
|
||||
uint8_t rsv2[12];
|
||||
|
||||
uint8_t ls_rjt_vendor;
|
||||
@@ -1564,7 +1564,7 @@ struct vp_rpt_id_entry_24xx {
|
||||
|
||||
uint8_t port_name[8];
|
||||
uint8_t node_name[8];
|
||||
uint16_t bbcr;
|
||||
__le16 bbcr;
|
||||
uint8_t reserved_5[2];
|
||||
uint8_t remote_nport_id[4];
|
||||
} f2;
|
||||
|
||||
@@ -51,6 +51,15 @@ static inline __le16 qla_ext_build_vp_sof(u16 vp_idx, u16 sof_type)
|
||||
((sof_type & 0xf) << EXT_VP_SOF_SOF_TYPE_SHIFT));
|
||||
}
|
||||
|
||||
/*
|
||||
* Combined vp_idx/vp_status field layout (vp_rpt_id_entry_24xx_ext):
|
||||
* bits [8:0] - VP index (9 bits)
|
||||
* bits [15:9] - VP status (7 bits)
|
||||
*/
|
||||
#define EXT_VP_STATUS_VP_INDEX_MASK 0x01ff
|
||||
#define EXT_VP_STATUS_VP_STATUS_SHIFT 9
|
||||
#define EXT_VP_STATUS_VP_STATUS_MASK 0xfe00
|
||||
|
||||
/*
|
||||
* ISP queue - command entry structure definition.
|
||||
*/
|
||||
@@ -708,8 +717,7 @@ struct vp_rpt_id_entry_24xx_ext {
|
||||
__le32 resv1;
|
||||
uint8_t vp_acquired;
|
||||
uint8_t vp_setup;
|
||||
__le16 vp_idx : 9; /* VP Index 9bits */
|
||||
__le16 vp_status : 7; /* VP Status 7bits */
|
||||
__le16 vp_idx_status; /* bits [8:0]=VP index, [15:9]=VP status */
|
||||
|
||||
uint8_t port_id[3];
|
||||
uint8_t format;
|
||||
@@ -719,7 +727,7 @@ struct vp_rpt_id_entry_24xx_ext {
|
||||
uint8_t vpstat1_subcode; /* vp_status=1 subcode */
|
||||
uint8_t flags;
|
||||
|
||||
uint16_t fip_flags;
|
||||
__le16 fip_flags;
|
||||
uint8_t rsv2[12];
|
||||
|
||||
uint8_t ls_rjt_vendor;
|
||||
@@ -730,13 +738,13 @@ struct vp_rpt_id_entry_24xx_ext {
|
||||
__le16 flogi_acc_payload_size; /* bits [8:0] meaningful */
|
||||
uint8_t port_name[8];
|
||||
uint8_t node_name[8];
|
||||
uint16_t bbcr;
|
||||
__le16 bbcr;
|
||||
uint8_t reserved_5[6];
|
||||
} f1;
|
||||
struct vp_rpt_id_ext_f2 { /* format 2: N2N direct connect */
|
||||
uint8_t vpstat1_subcode;
|
||||
uint8_t flags;
|
||||
uint16_t fip_flags;
|
||||
__le16 fip_flags;
|
||||
uint8_t rsv2[12];
|
||||
|
||||
uint8_t ls_rjt_vendor;
|
||||
@@ -746,7 +754,7 @@ struct vp_rpt_id_entry_24xx_ext {
|
||||
|
||||
uint8_t port_name[8];
|
||||
uint8_t node_name[8];
|
||||
uint16_t bbcr;
|
||||
__le16 bbcr;
|
||||
uint8_t reserved_5[2];
|
||||
uint8_t remote_nport_id[4];
|
||||
} f2;
|
||||
|
||||
@@ -4106,8 +4106,10 @@ qla24xx_report_id_acquisition(scsi_qla_host_t *vha, void *pkt)
|
||||
return;
|
||||
|
||||
if (IS_QLA29XX(ha)) {
|
||||
vp_idx = rptid_entry_ext->vp_idx;
|
||||
vp_status = rptid_entry_ext->vp_status;
|
||||
vp_idx = le16_to_cpu(rptid_entry_ext->vp_idx_status) &
|
||||
EXT_VP_STATUS_VP_INDEX_MASK;
|
||||
vp_status = (le16_to_cpu(rptid_entry_ext->vp_idx_status) >>
|
||||
EXT_VP_STATUS_VP_STATUS_SHIFT) & 0x7f;
|
||||
} else {
|
||||
vp_idx = rptid_entry->vp_idx;
|
||||
vp_status = rptid_entry->vp_status;
|
||||
@@ -4231,7 +4233,8 @@ qla24xx_report_id_acquisition(scsi_qla_host_t *vha, void *pkt)
|
||||
ha->flags.gpsc_supported = 1;
|
||||
ha->current_topology = ISP_CFG_F;
|
||||
/* buffer to buffer credit flag */
|
||||
vha->flags.bbcr_enable = (rptid_entry->u.f1.bbcr & 0xf) != 0;
|
||||
vha->flags.bbcr_enable =
|
||||
(le16_to_cpu(rptid_entry->u.f1.bbcr) & 0xf) != 0;
|
||||
|
||||
if (vp_idx == 0) {
|
||||
if (vp_status == VP_STAT_COMPL) {
|
||||
|
||||
Reference in New Issue
Block a user