scsi: fnic: Route completions and resets by initiator role

Dispatch FCPIO command, response, and ITMF completions to the FCP or NVMe
handlers based on the configured role.

Read the NVMe queue-depth and timeout retry fields from firmware config,
clean up NVMe I/O on firmware reset, and skip SCSI-only cleanup for
initiator roles that already reset firmware-owned requests.

Reviewed-by: Sesidhar Baddela <sebaddel@cisco.com>
Reviewed-by: Arulprabhu Ponnusamy <arulponn@cisco.com>
Reviewed-by: Gian Carlo Boffa <gcboffa@cisco.com>
Reviewed-by: Arun Easi <aeasi@cisco.com>
Reviewed-by: Lee Duncan <lduncan@suse.com>
Signed-off-by: Karan Tilak Kumar <kartilak@cisco.com>
Co-developed-by: Hannes Reinecke <hare@kernel.org>
Link: https://patch.msgid.link/20260724174811.5118-8-kartilak@cisco.com
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
This commit is contained in:
Karan Tilak Kumar 2026-07-24 10:48:05 -07:00 committed by Martin K. Petersen
parent 5efdd5cf92
commit b3f4bc0a7a
2 changed files with 30 additions and 4 deletions

View File

@ -57,6 +57,8 @@ int fnic_get_vnic_config(struct fnic *fnic)
GET_CONFIG(port_down_io_retries);
GET_CONFIG(luns_per_tgt);
GET_CONFIG(intr_mode);
GET_CONFIG(lun_queue_depth);
GET_CONFIG(io_timeout_retry);
GET_CONFIG(wq_copy_count);
role = c->flags & FNIC_ROLE_CONFIG_MASK;

View File

@ -145,8 +145,9 @@ unsigned int fnic_count_ioreqs(struct fnic *fnic, u32 portid)
{
unsigned int count = 0;
fnic_scsi_io_iter(fnic, fnic_count_portid_ioreqs_iter,
&portid, &count);
if (IS_FNIC_FCP_INITIATOR(fnic))
fnic_scsi_io_iter(fnic, fnic_count_portid_ioreqs_iter,
&portid, &count);
FNIC_SCSI_DBG(KERN_DEBUG, fnic,
"portid = 0x%x count = %u\n", portid, count);
@ -734,6 +735,8 @@ static int fnic_fcpio_fw_reset_cmpl_handler(struct fnic *fnic,
/* Clean up all outstanding io requests */
if (IS_FNIC_FCP_INITIATOR(fnic))
fnic_cleanup_io(fnic, SCSI_NO_TAG);
else if (IS_FNIC_NVME_INITIATOR(fnic))
nvfnic_cleanup_all_nvme_ios(fnic);
atomic64_set(&fnic->fnic_stats.fw_stats.active_fw_reqs, 0);
atomic64_set(&fnic->fnic_stats.io_stats.active_ios, 0);
@ -1443,6 +1446,7 @@ static int fnic_fcpio_cmpl_handler(struct vnic_dev *vdev,
case FCPIO_FLOGI_REG_CMPL: /* fw completed flogi_reg */
case FCPIO_FLOGI_FIP_REG_CMPL: /* fw completed flogi_fip_reg */
case FCPIO_RESET_CMPL: /* fw completed reset */
case FCPIO_NVME_ERSP_HW_CMPL: /* fw completed NVMe ERSP */
atomic64_dec(&fnic->fnic_stats.fw_stats.active_fw_reqs);
break;
default:
@ -1457,11 +1461,22 @@ static int fnic_fcpio_cmpl_handler(struct vnic_dev *vdev,
break;
case FCPIO_ICMND_CMPL: /* fw completed a command */
fnic_fcpio_icmnd_cmpl_handler(fnic, cq_index, desc);
if (IS_FNIC_FCP_INITIATOR(fnic))
fnic_fcpio_icmnd_cmpl_handler(fnic, cq_index, desc);
else if (IS_FNIC_NVME_INITIATOR(fnic))
nvfnic_fcpio_nvme_fast_cmpl_handler(fnic, desc);
break;
case FCPIO_NVME_ERSP_HW_CMPL: /* fw completed NVMe ERSP */
if (IS_FNIC_NVME_INITIATOR(fnic))
nvfnic_fcpio_ersp_cmpl_handler(fnic, desc, 1);
break;
case FCPIO_ITMF_CMPL: /* fw completed itmf (abort cmd, lun reset)*/
fnic_fcpio_itmf_cmpl_handler(fnic, cq_index, desc);
if (IS_FNIC_FCP_INITIATOR(fnic))
fnic_fcpio_itmf_cmpl_handler(fnic, cq_index, desc);
else if (IS_FNIC_NVME_INITIATOR(fnic))
nvfnic_fcpio_nvme_itmf_cmpl_handler(fnic, desc);
break;
case FCPIO_FLOGI_REG_CMPL: /* fw completed flogi_reg */
@ -1650,6 +1665,15 @@ void fnic_wq_copy_cleanup_handler(struct vnic_wq_copy *wq,
unsigned long start_time = 0;
uint16_t hwq;
/*
* Clean up outstanding NVMe requests if firmware reset did not
* complete them before WQ copy cleanup.
*/
if (IS_FNIC_NVME_INITIATOR(fnic)) {
nvfnic_cleanup_all_nvme_ios(fnic);
return;
}
/* get the tag reference */
fcpio_tag_id_dec(&desc->hdr.tag, &id);
id &= FNIC_TAG_MASK;