mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-08-30 16:53:20 -04:00
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:
committed by
Martin K. Petersen (Oracle)
parent
71037e82d2
commit
2eba3833a1
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user