scsi: qla2xxx: Handle sts_cont_entry_ext_t for 29xx adapters

29xx adapters use 128-byte response queue entries (sts_cont_entry_ext_t)
instead of 64-byte (sts_cont_entry_t).  Update all status continuation
IOCB processing paths to branch on IS_QLA29XX() and use the correct
entry type and data payload size.

The affected functions are __qla_copy_purex_to_buffer(),
qla27xx_copy_multiple_pkt(), qla2x00_status_cont_entry(), and their call
sites in qla2x00_process_response_entry() and
qla24xx_process_response_queue().

Change qla2x00_status_cont_entry() to accept void * so callers no longer
need an explicit cast and the function can internally select the right
structure based on the adapter type.

Add BUILD_BUG_ON for sts_cont_entry_ext_t size (128 bytes).

Reported-by: kernel test robot <lkp@intel.com>
Closes: https://lore.kernel.org/oe-kbuild-all/202607142020.gqDaApes-lkp@intel.com/
Signed-off-by: Nilesh Javali <njavali@marvell.com>
Reviewed-by: Hannes Reinecke <hare@kernel.org>
Link: https://patch.msgid.link/20260723050413.3897522-26-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:42 +05:30
committed by Martin K. Petersen (Oracle)
parent 71037e82d2
commit 2eba3833a1
3 changed files with 87 additions and 48 deletions

View File

@@ -103,6 +103,22 @@ qla_rsp_entry_size(struct qla_hw_data *ha)
return IS_QLA29XX(ha) ? sizeof(struct response_ext) : sizeof(response_t);
}
/**
* qla_sts_cont_data_size() - status-continuation IOCB data payload size.
* @ha: HBA pointer
*
* sts_cont_entry_t and struct sts_cont_entry_ext share the same header and
* data offset; only the trailing data[] size differs (60 vs 124 bytes).
* Returns that size so callers need not branch on the adapter type.
*/
static inline u32
qla_sts_cont_data_size(struct qla_hw_data *ha)
{
return IS_QLA29XX(ha) ?
sizeof_field(struct sts_cont_entry_ext, data) :
sizeof_field(sts_cont_entry_t, data);
}
static inline void
qla2x00_poll(struct rsp_que *rsp)
{

View File

@@ -19,7 +19,7 @@
static void qla2x00_mbx_completion(scsi_qla_host_t *, uint16_t);
static void qla2x00_status_entry(scsi_qla_host_t *, struct rsp_que *, void *);
static void qla2x00_status_cont_entry(struct rsp_que *, sts_cont_entry_t *);
static void qla2x00_status_cont_entry(struct rsp_que *, void *, u32);
static int qla2x00_error_entry(scsi_qla_host_t *, struct rsp_que *,
sts_entry_t *);
static void qla27xx_process_purex_fpin(struct scsi_qla_host *vha,
@@ -231,8 +231,13 @@ int __qla_copy_purex_to_buffer(struct scsi_qla_host *vha,
void **pkt, struct rsp_que **rsp, u8 *buf, u32 buf_len)
{
struct purex_entry_24xx *purex = *pkt;
struct qla_hw_data *ha = vha->hw;
struct rsp_que *rsp_q = *rsp;
sts_cont_entry_t *new_pkt;
size_t payload_size = IS_QLA29XX(ha) ?
sizeof_field(struct purex_entry_24xx_ext, els_frame_payload) :
sizeof_field(struct purex_entry_24xx, els_frame_payload);
u8 *data;
u32 data_sz;
uint16_t no_bytes = 0, total_bytes = 0, pending_bytes = 0;
uint16_t buffer_copy_offset = 0;
uint16_t entry_count_remaining;
@@ -271,10 +276,12 @@ int __qla_copy_purex_to_buffer(struct scsi_qla_host *vha,
do {
while ((total_bytes > 0) && (entry_count_remaining > 0)) {
new_pkt = (sts_cont_entry_t *)rsp_q->ring_ptr;
*pkt = new_pkt;
*pkt = rsp_q->ring_ptr;
data = ((sts_cont_entry_t *)*pkt)->data;
data_sz = qla_sts_cont_data_size(ha);
if (new_pkt->entry_type != STATUS_CONT_TYPE) {
if (((sts_cont_entry_t *)*pkt)->entry_type !=
STATUS_CONT_TYPE) {
ql_log(ql_log_warn, vha, 0x507a,
"Unexpected IOCB type, partial data 0x%x\n",
buffer_copy_offset);
@@ -282,10 +289,10 @@ int __qla_copy_purex_to_buffer(struct scsi_qla_host *vha,
}
qla_rsp_ring_advance(rsp_q);
no_bytes = (pending_bytes > sizeof(new_pkt->data)) ?
sizeof(new_pkt->data) : pending_bytes;
no_bytes = (pending_bytes > data_sz) ?
data_sz : pending_bytes;
if ((buffer_copy_offset + no_bytes) <= total_bytes) {
memcpy((buf + buffer_copy_offset), new_pkt->data,
memcpy((buf + buffer_copy_offset), data,
no_bytes);
buffer_copy_offset += no_bytes;
pending_bytes -= no_bytes;
@@ -294,11 +301,11 @@ int __qla_copy_purex_to_buffer(struct scsi_qla_host *vha,
ql_log(ql_log_warn, vha, 0x5044,
"Attempt to copy more that we got, optimizing..%x\n",
buffer_copy_offset);
memcpy((buf + buffer_copy_offset), new_pkt->data,
memcpy((buf + buffer_copy_offset), data,
total_bytes - buffer_copy_offset);
}
((response_t *)new_pkt)->signature = RESPONSE_PROCESSED;
((response_t *)*pkt)->signature = RESPONSE_PROCESSED;
/* flush signature */
wmb();
}
@@ -844,13 +851,15 @@ qla27xx_copy_multiple_pkt(struct scsi_qla_host *vha, void **pkt,
{
struct purex_entry_24xx *purex = NULL;
struct pt_ls4_rx_unsol *purls = NULL;
struct qla_hw_data *ha = vha->hw;
struct rsp_que *rsp_q = *rsp;
sts_cont_entry_t *new_pkt;
uint16_t no_bytes = 0, total_bytes = 0, pending_bytes = 0;
uint16_t buffer_copy_offset = 0, payload_size = 0;
uint16_t entry_count, entry_count_remaining;
struct purex_item *item;
void *iocb_pkt = NULL;
u8 *data;
u32 data_sz;
if (is_purls) {
purls = *pkt;
@@ -906,28 +915,24 @@ qla27xx_copy_multiple_pkt(struct scsi_qla_host *vha, void **pkt,
continue;
}
new_pkt = (sts_cont_entry_t *)rsp_q->ring_ptr;
*pkt = new_pkt;
*pkt = rsp_q->ring_ptr;
data = ((sts_cont_entry_t *)*pkt)->data;
data_sz = qla_sts_cont_data_size(ha);
if (new_pkt->entry_type != STATUS_CONT_TYPE) {
if (((sts_cont_entry_t *)*pkt)->entry_type !=
STATUS_CONT_TYPE) {
ql_log(ql_log_warn, vha, 0x507a,
"Unexpected IOCB type, partial data 0x%x\n",
buffer_copy_offset);
break;
}
rsp_q->ring_index++;
if (rsp_q->ring_index == rsp_q->length) {
rsp_q->ring_index = 0;
rsp_q->ring_ptr = rsp_q->ring;
} else {
rsp_q->ring_ptr++;
}
no_bytes = (pending_bytes > sizeof(new_pkt->data)) ?
sizeof(new_pkt->data) : pending_bytes;
qla_rsp_ring_advance(rsp_q);
no_bytes = (pending_bytes > data_sz) ?
data_sz : pending_bytes;
if ((buffer_copy_offset + no_bytes) <= total_bytes) {
memcpy(((uint8_t *)iocb_pkt + buffer_copy_offset),
new_pkt->data, no_bytes);
memcpy(((uint8_t *)iocb_pkt +
buffer_copy_offset), data, no_bytes);
buffer_copy_offset += no_bytes;
pending_bytes -= no_bytes;
--entry_count_remaining;
@@ -935,12 +940,12 @@ qla27xx_copy_multiple_pkt(struct scsi_qla_host *vha, void **pkt,
ql_log(ql_log_warn, vha, 0x5044,
"Attempt to copy more that we got, optimizing..%x\n",
buffer_copy_offset);
memcpy(((uint8_t *)iocb_pkt + buffer_copy_offset),
new_pkt->data,
total_bytes - buffer_copy_offset);
memcpy(((uint8_t *)iocb_pkt +
buffer_copy_offset), data,
total_bytes - buffer_copy_offset);
}
((response_t *)new_pkt)->signature = RESPONSE_PROCESSED;
((response_t *)*pkt)->signature = RESPONSE_PROCESSED;
wmb();
}
@@ -1144,8 +1149,13 @@ qla27xx_copy_fpin_pkt(struct scsi_qla_host *vha, void **pkt,
struct rsp_que **rsp)
{
struct purex_entry_24xx *purex = *pkt;
struct qla_hw_data *ha = vha->hw;
struct rsp_que *rsp_q = *rsp;
sts_cont_entry_t *new_pkt;
size_t payload_size = IS_QLA29XX(ha) ?
sizeof_field(struct purex_entry_24xx_ext, els_frame_payload) :
sizeof_field(struct purex_entry_24xx, els_frame_payload);
u8 *data;
u32 data_sz;
uint16_t no_bytes = 0, total_bytes = 0, pending_bytes = 0;
uint16_t buffer_copy_offset = 0;
uint16_t entry_count, entry_count_remaining;
@@ -1160,8 +1170,8 @@ qla27xx_copy_fpin_pkt(struct scsi_qla_host *vha, void **pkt,
pending_bytes = total_bytes;
entry_count = entry_count_remaining = purex->entry_count;
no_bytes = (pending_bytes > sizeof(purex->els_frame_payload)) ?
sizeof(purex->els_frame_payload) : pending_bytes;
no_bytes = (pending_bytes > payload_size) ?
payload_size : pending_bytes;
ql_log(ql_log_info, vha, 0x509a,
"FPIN ELS, frame_size 0x%x, entry count %d\n",
total_bytes, entry_count);
@@ -1172,7 +1182,13 @@ qla27xx_copy_fpin_pkt(struct scsi_qla_host *vha, void **pkt,
fpin_pkt = &item->iocb;
memcpy(fpin_pkt, &purex->els_frame_payload[0], no_bytes);
if (IS_QLA29XX(ha)) {
struct purex_entry_24xx_ext *purex_ext = *pkt;
memcpy(fpin_pkt, &purex_ext->els_frame_payload[0], no_bytes);
} else {
memcpy(fpin_pkt, &purex->els_frame_payload[0], no_bytes);
}
buffer_copy_offset += no_bytes;
pending_bytes -= no_bytes;
--entry_count_remaining;
@@ -1190,10 +1206,12 @@ qla27xx_copy_fpin_pkt(struct scsi_qla_host *vha, void **pkt,
continue;
}
new_pkt = (sts_cont_entry_t *)rsp_q->ring_ptr;
*pkt = new_pkt;
*pkt = rsp_q->ring_ptr;
data = ((sts_cont_entry_t *)*pkt)->data;
data_sz = qla_sts_cont_data_size(ha);
if (new_pkt->entry_type != STATUS_CONT_TYPE) {
if (((sts_cont_entry_t *)*pkt)->entry_type !=
STATUS_CONT_TYPE) {
ql_log(ql_log_warn, vha, 0x507a,
"Unexpected IOCB type, partial data 0x%x\n",
buffer_copy_offset);
@@ -1201,11 +1219,11 @@ qla27xx_copy_fpin_pkt(struct scsi_qla_host *vha, void **pkt,
}
qla_rsp_ring_advance(rsp_q);
no_bytes = (pending_bytes > sizeof(new_pkt->data)) ?
sizeof(new_pkt->data) : pending_bytes;
no_bytes = (pending_bytes > data_sz) ?
data_sz : pending_bytes;
if ((buffer_copy_offset + no_bytes) <= total_bytes) {
memcpy(((uint8_t *)fpin_pkt +
buffer_copy_offset), new_pkt->data,
buffer_copy_offset), data,
no_bytes);
buffer_copy_offset += no_bytes;
pending_bytes -= no_bytes;
@@ -1215,11 +1233,11 @@ qla27xx_copy_fpin_pkt(struct scsi_qla_host *vha, void **pkt,
"Attempt to copy more that we got, optimizing..%x\n",
buffer_copy_offset);
memcpy(((uint8_t *)fpin_pkt +
buffer_copy_offset), new_pkt->data,
buffer_copy_offset), data,
total_bytes - buffer_copy_offset);
}
((response_t *)new_pkt)->signature = RESPONSE_PROCESSED;
((response_t *)*pkt)->signature = RESPONSE_PROCESSED;
wmb();
}
@@ -2918,7 +2936,8 @@ static void qla2x00_process_response_entry(struct scsi_qla_host *vha,
sts22_entry->handle[cnt]);
break;
case STATUS_CONT_TYPE:
qla2x00_status_cont_entry(rsp, (sts_cont_entry_t *)pkt);
qla2x00_status_cont_entry(rsp, pkt,
qla_sts_cont_data_size(rsp->hw));
break;
case MBX_IOCB_TYPE:
qla2x00_mbx_iocb_entry(vha, rsp->req, (struct mbx_entry *)pkt);
@@ -3678,11 +3697,12 @@ qla2x00_status_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, void *pkt)
* qla2x00_status_cont_entry() - Process a Status Continuations entry.
* @rsp: response queue
* @pkt: Entry pointer
* @data_sz: maximum sense-data payload size for this entry
*
* Extended sense data.
*/
static void
qla2x00_status_cont_entry(struct rsp_que *rsp, sts_cont_entry_t *pkt)
qla2x00_status_cont_entry(struct rsp_que *rsp, void *pkt, u32 data_sz)
{
uint8_t sense_sz = 0;
struct qla_hw_data *ha = rsp->hw;
@@ -3691,6 +3711,7 @@ qla2x00_status_cont_entry(struct rsp_que *rsp, sts_cont_entry_t *pkt)
struct scsi_cmnd *cp;
uint32_t sense_len;
uint8_t *sense_ptr;
u8 *data = ((sts_cont_entry_t *)pkt)->data;
if (!sp || !GET_CMD_SENSE_LEN(sp))
return;
@@ -3707,15 +3728,15 @@ qla2x00_status_cont_entry(struct rsp_que *rsp, sts_cont_entry_t *pkt)
return;
}
if (sense_len > sizeof(pkt->data))
sense_sz = sizeof(pkt->data);
if (sense_len > data_sz)
sense_sz = data_sz;
else
sense_sz = sense_len;
/* Move sense data. */
if (IS_FWI2_CAPABLE(ha))
host_to_fcp_swap(pkt->data, sizeof(pkt->data));
memcpy(sense_ptr, pkt->data, sense_sz);
host_to_fcp_swap(data, data_sz);
memcpy(sense_ptr, data, sense_sz);
ql_dump_buffer(ql_dbg_io + ql_dbg_buffer, vha, 0x302c,
sense_ptr, sense_sz);
@@ -3997,7 +4018,8 @@ void qla24xx_process_response_queue(struct scsi_qla_host *vha,
qla2x00_status_entry(vha, rsp, pkt);
break;
case STATUS_CONT_TYPE:
qla2x00_status_cont_entry(rsp, (sts_cont_entry_t *)pkt);
qla2x00_status_cont_entry(rsp, pkt,
qla_sts_cont_data_size(rsp->hw));
break;
case VP_RPT_ID_IOCB_TYPE:
qla24xx_report_id_acquisition(vha,

View File

@@ -8411,6 +8411,7 @@ qla2x00_module_init(void)
BUILD_BUG_ON(sizeof(sts21_entry_t) != 64);
BUILD_BUG_ON(sizeof(sts22_entry_t) != 64);
BUILD_BUG_ON(sizeof(sts_cont_entry_t) != 64);
BUILD_BUG_ON(sizeof(struct sts_cont_entry_ext) != 128);
BUILD_BUG_ON(sizeof(sts_entry_t) != 64);
BUILD_BUG_ON(sizeof(sw_info_t) != 32);
BUILD_BUG_ON(sizeof(target_id_t) != 2);