diff --git a/qla2x00t-32gbit/qla_inline.h b/qla2x00t-32gbit/qla_inline.h index f56bc83c4..27b859fe9 100644 --- a/qla2x00t-32gbit/qla_inline.h +++ b/qla2x00t-32gbit/qla_inline.h @@ -111,6 +111,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) { diff --git a/qla2x00t-32gbit/qla_isr.c b/qla2x00t-32gbit/qla_isr.c index 4384db2db..272464b12 100644 --- a/qla2x00t-32gbit/qla_isr.c +++ b/qla2x00t-32gbit/qla_isr.c @@ -31,7 +31,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, @@ -243,8 +243,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; @@ -283,10 +288,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); @@ -294,10 +301,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; @@ -306,11 +313,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(); } @@ -856,13 +863,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; @@ -918,28 +927,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; @@ -947,12 +952,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(); } @@ -1156,8 +1161,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; @@ -1172,8 +1182,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); @@ -1184,7 +1194,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; @@ -1202,10 +1218,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); @@ -1213,11 +1231,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; @@ -1227,11 +1245,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(); } @@ -2941,7 +2959,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); @@ -3701,11 +3720,12 @@ out: * 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; @@ -3714,6 +3734,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; @@ -3730,15 +3751,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); @@ -4022,7 +4043,8 @@ process_err: 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, diff --git a/qla2x00t-32gbit/qla_os.c b/qla2x00t-32gbit/qla_os.c index cbb2541f3..52241ad09 100644 --- a/qla2x00t-32gbit/qla_os.c +++ b/qla2x00t-32gbit/qla_os.c @@ -8664,6 +8664,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);