18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * QLogic Fibre Channel HBA Driver 48c2ecf20Sopenharmony_ci * Copyright (c) 2003-2014 QLogic Corporation 58c2ecf20Sopenharmony_ci */ 68c2ecf20Sopenharmony_ci#include "qla_def.h" 78c2ecf20Sopenharmony_ci 88c2ecf20Sopenharmony_ci#include <linux/debugfs.h> 98c2ecf20Sopenharmony_ci#include <linux/seq_file.h> 108c2ecf20Sopenharmony_ci 118c2ecf20Sopenharmony_cistatic struct dentry *qla2x00_dfs_root; 128c2ecf20Sopenharmony_cistatic atomic_t qla2x00_dfs_root_count; 138c2ecf20Sopenharmony_ci 148c2ecf20Sopenharmony_ci#define QLA_DFS_RPORT_DEVLOSS_TMO 1 158c2ecf20Sopenharmony_ci 168c2ecf20Sopenharmony_cistatic int 178c2ecf20Sopenharmony_ciqla_dfs_rport_get(struct fc_port *fp, int attr_id, u64 *val) 188c2ecf20Sopenharmony_ci{ 198c2ecf20Sopenharmony_ci switch (attr_id) { 208c2ecf20Sopenharmony_ci case QLA_DFS_RPORT_DEVLOSS_TMO: 218c2ecf20Sopenharmony_ci /* Only supported for FC-NVMe devices that are registered. */ 228c2ecf20Sopenharmony_ci if (!(fp->nvme_flag & NVME_FLAG_REGISTERED)) 238c2ecf20Sopenharmony_ci return -EIO; 248c2ecf20Sopenharmony_ci *val = fp->nvme_remote_port->dev_loss_tmo; 258c2ecf20Sopenharmony_ci break; 268c2ecf20Sopenharmony_ci default: 278c2ecf20Sopenharmony_ci return -EINVAL; 288c2ecf20Sopenharmony_ci } 298c2ecf20Sopenharmony_ci return 0; 308c2ecf20Sopenharmony_ci} 318c2ecf20Sopenharmony_ci 328c2ecf20Sopenharmony_cistatic int 338c2ecf20Sopenharmony_ciqla_dfs_rport_set(struct fc_port *fp, int attr_id, u64 val) 348c2ecf20Sopenharmony_ci{ 358c2ecf20Sopenharmony_ci switch (attr_id) { 368c2ecf20Sopenharmony_ci case QLA_DFS_RPORT_DEVLOSS_TMO: 378c2ecf20Sopenharmony_ci /* Only supported for FC-NVMe devices that are registered. */ 388c2ecf20Sopenharmony_ci if (!(fp->nvme_flag & NVME_FLAG_REGISTERED)) 398c2ecf20Sopenharmony_ci return -EIO; 408c2ecf20Sopenharmony_ci#if (IS_ENABLED(CONFIG_NVME_FC)) 418c2ecf20Sopenharmony_ci return nvme_fc_set_remoteport_devloss(fp->nvme_remote_port, 428c2ecf20Sopenharmony_ci val); 438c2ecf20Sopenharmony_ci#else /* CONFIG_NVME_FC */ 448c2ecf20Sopenharmony_ci return -EINVAL; 458c2ecf20Sopenharmony_ci#endif /* CONFIG_NVME_FC */ 468c2ecf20Sopenharmony_ci default: 478c2ecf20Sopenharmony_ci return -EINVAL; 488c2ecf20Sopenharmony_ci } 498c2ecf20Sopenharmony_ci return 0; 508c2ecf20Sopenharmony_ci} 518c2ecf20Sopenharmony_ci 528c2ecf20Sopenharmony_ci#define DEFINE_QLA_DFS_RPORT_RW_ATTR(_attr_id, _attr) \ 538c2ecf20Sopenharmony_cistatic int qla_dfs_rport_##_attr##_get(void *data, u64 *val) \ 548c2ecf20Sopenharmony_ci{ \ 558c2ecf20Sopenharmony_ci struct fc_port *fp = data; \ 568c2ecf20Sopenharmony_ci return qla_dfs_rport_get(fp, _attr_id, val); \ 578c2ecf20Sopenharmony_ci} \ 588c2ecf20Sopenharmony_cistatic int qla_dfs_rport_##_attr##_set(void *data, u64 val) \ 598c2ecf20Sopenharmony_ci{ \ 608c2ecf20Sopenharmony_ci struct fc_port *fp = data; \ 618c2ecf20Sopenharmony_ci return qla_dfs_rport_set(fp, _attr_id, val); \ 628c2ecf20Sopenharmony_ci} \ 638c2ecf20Sopenharmony_ciDEFINE_DEBUGFS_ATTRIBUTE(qla_dfs_rport_##_attr##_fops, \ 648c2ecf20Sopenharmony_ci qla_dfs_rport_##_attr##_get, \ 658c2ecf20Sopenharmony_ci qla_dfs_rport_##_attr##_set, "%llu\n") 668c2ecf20Sopenharmony_ci 678c2ecf20Sopenharmony_ci/* 688c2ecf20Sopenharmony_ci * Wrapper for getting fc_port fields. 698c2ecf20Sopenharmony_ci * 708c2ecf20Sopenharmony_ci * _attr : Attribute name. 718c2ecf20Sopenharmony_ci * _get_val : Accessor macro to retrieve the value. 728c2ecf20Sopenharmony_ci */ 738c2ecf20Sopenharmony_ci#define DEFINE_QLA_DFS_RPORT_FIELD_GET(_attr, _get_val) \ 748c2ecf20Sopenharmony_cistatic int qla_dfs_rport_field_##_attr##_get(void *data, u64 *val) \ 758c2ecf20Sopenharmony_ci{ \ 768c2ecf20Sopenharmony_ci struct fc_port *fp = data; \ 778c2ecf20Sopenharmony_ci *val = _get_val; \ 788c2ecf20Sopenharmony_ci return 0; \ 798c2ecf20Sopenharmony_ci} \ 808c2ecf20Sopenharmony_ciDEFINE_DEBUGFS_ATTRIBUTE(qla_dfs_rport_field_##_attr##_fops, \ 818c2ecf20Sopenharmony_ci qla_dfs_rport_field_##_attr##_get, \ 828c2ecf20Sopenharmony_ci NULL, "%llu\n") 838c2ecf20Sopenharmony_ci 848c2ecf20Sopenharmony_ci#define DEFINE_QLA_DFS_RPORT_ACCESS(_attr, _get_val) \ 858c2ecf20Sopenharmony_ci DEFINE_QLA_DFS_RPORT_FIELD_GET(_attr, _get_val) 868c2ecf20Sopenharmony_ci 878c2ecf20Sopenharmony_ci#define DEFINE_QLA_DFS_RPORT_FIELD(_attr) \ 888c2ecf20Sopenharmony_ci DEFINE_QLA_DFS_RPORT_FIELD_GET(_attr, fp->_attr) 898c2ecf20Sopenharmony_ci 908c2ecf20Sopenharmony_ciDEFINE_QLA_DFS_RPORT_RW_ATTR(QLA_DFS_RPORT_DEVLOSS_TMO, dev_loss_tmo); 918c2ecf20Sopenharmony_ci 928c2ecf20Sopenharmony_ciDEFINE_QLA_DFS_RPORT_FIELD(disc_state); 938c2ecf20Sopenharmony_ciDEFINE_QLA_DFS_RPORT_FIELD(scan_state); 948c2ecf20Sopenharmony_ciDEFINE_QLA_DFS_RPORT_FIELD(fw_login_state); 958c2ecf20Sopenharmony_ciDEFINE_QLA_DFS_RPORT_FIELD(login_pause); 968c2ecf20Sopenharmony_ciDEFINE_QLA_DFS_RPORT_FIELD(flags); 978c2ecf20Sopenharmony_ciDEFINE_QLA_DFS_RPORT_FIELD(nvme_flag); 988c2ecf20Sopenharmony_ciDEFINE_QLA_DFS_RPORT_FIELD(last_rscn_gen); 998c2ecf20Sopenharmony_ciDEFINE_QLA_DFS_RPORT_FIELD(rscn_gen); 1008c2ecf20Sopenharmony_ciDEFINE_QLA_DFS_RPORT_FIELD(login_gen); 1018c2ecf20Sopenharmony_ciDEFINE_QLA_DFS_RPORT_FIELD(loop_id); 1028c2ecf20Sopenharmony_ciDEFINE_QLA_DFS_RPORT_FIELD_GET(port_id, fp->d_id.b24); 1038c2ecf20Sopenharmony_ciDEFINE_QLA_DFS_RPORT_FIELD_GET(sess_kref, kref_read(&fp->sess_kref)); 1048c2ecf20Sopenharmony_ci 1058c2ecf20Sopenharmony_civoid 1068c2ecf20Sopenharmony_ciqla2x00_dfs_create_rport(scsi_qla_host_t *vha, struct fc_port *fp) 1078c2ecf20Sopenharmony_ci{ 1088c2ecf20Sopenharmony_ci char wwn[32]; 1098c2ecf20Sopenharmony_ci 1108c2ecf20Sopenharmony_ci#define QLA_CREATE_RPORT_FIELD_ATTR(_attr) \ 1118c2ecf20Sopenharmony_ci debugfs_create_file(#_attr, 0400, fp->dfs_rport_dir, \ 1128c2ecf20Sopenharmony_ci fp, &qla_dfs_rport_field_##_attr##_fops) 1138c2ecf20Sopenharmony_ci 1148c2ecf20Sopenharmony_ci if (!vha->dfs_rport_root || fp->dfs_rport_dir) 1158c2ecf20Sopenharmony_ci return; 1168c2ecf20Sopenharmony_ci 1178c2ecf20Sopenharmony_ci sprintf(wwn, "pn-%016llx", wwn_to_u64(fp->port_name)); 1188c2ecf20Sopenharmony_ci fp->dfs_rport_dir = debugfs_create_dir(wwn, vha->dfs_rport_root); 1198c2ecf20Sopenharmony_ci if (IS_ERR(fp->dfs_rport_dir)) 1208c2ecf20Sopenharmony_ci return; 1218c2ecf20Sopenharmony_ci if (NVME_TARGET(vha->hw, fp)) 1228c2ecf20Sopenharmony_ci debugfs_create_file("dev_loss_tmo", 0600, fp->dfs_rport_dir, 1238c2ecf20Sopenharmony_ci fp, &qla_dfs_rport_dev_loss_tmo_fops); 1248c2ecf20Sopenharmony_ci 1258c2ecf20Sopenharmony_ci QLA_CREATE_RPORT_FIELD_ATTR(disc_state); 1268c2ecf20Sopenharmony_ci QLA_CREATE_RPORT_FIELD_ATTR(scan_state); 1278c2ecf20Sopenharmony_ci QLA_CREATE_RPORT_FIELD_ATTR(fw_login_state); 1288c2ecf20Sopenharmony_ci QLA_CREATE_RPORT_FIELD_ATTR(login_pause); 1298c2ecf20Sopenharmony_ci QLA_CREATE_RPORT_FIELD_ATTR(flags); 1308c2ecf20Sopenharmony_ci QLA_CREATE_RPORT_FIELD_ATTR(nvme_flag); 1318c2ecf20Sopenharmony_ci QLA_CREATE_RPORT_FIELD_ATTR(last_rscn_gen); 1328c2ecf20Sopenharmony_ci QLA_CREATE_RPORT_FIELD_ATTR(rscn_gen); 1338c2ecf20Sopenharmony_ci QLA_CREATE_RPORT_FIELD_ATTR(login_gen); 1348c2ecf20Sopenharmony_ci QLA_CREATE_RPORT_FIELD_ATTR(loop_id); 1358c2ecf20Sopenharmony_ci QLA_CREATE_RPORT_FIELD_ATTR(port_id); 1368c2ecf20Sopenharmony_ci QLA_CREATE_RPORT_FIELD_ATTR(sess_kref); 1378c2ecf20Sopenharmony_ci} 1388c2ecf20Sopenharmony_ci 1398c2ecf20Sopenharmony_civoid 1408c2ecf20Sopenharmony_ciqla2x00_dfs_remove_rport(scsi_qla_host_t *vha, struct fc_port *fp) 1418c2ecf20Sopenharmony_ci{ 1428c2ecf20Sopenharmony_ci if (!vha->dfs_rport_root || !fp->dfs_rport_dir) 1438c2ecf20Sopenharmony_ci return; 1448c2ecf20Sopenharmony_ci debugfs_remove_recursive(fp->dfs_rport_dir); 1458c2ecf20Sopenharmony_ci fp->dfs_rport_dir = NULL; 1468c2ecf20Sopenharmony_ci} 1478c2ecf20Sopenharmony_ci 1488c2ecf20Sopenharmony_cistatic int 1498c2ecf20Sopenharmony_ciqla2x00_dfs_tgt_sess_show(struct seq_file *s, void *unused) 1508c2ecf20Sopenharmony_ci{ 1518c2ecf20Sopenharmony_ci scsi_qla_host_t *vha = s->private; 1528c2ecf20Sopenharmony_ci struct qla_hw_data *ha = vha->hw; 1538c2ecf20Sopenharmony_ci unsigned long flags; 1548c2ecf20Sopenharmony_ci struct fc_port *sess = NULL; 1558c2ecf20Sopenharmony_ci struct qla_tgt *tgt = vha->vha_tgt.qla_tgt; 1568c2ecf20Sopenharmony_ci 1578c2ecf20Sopenharmony_ci seq_printf(s, "%s\n", vha->host_str); 1588c2ecf20Sopenharmony_ci if (tgt) { 1598c2ecf20Sopenharmony_ci seq_puts(s, "Port ID Port Name Handle\n"); 1608c2ecf20Sopenharmony_ci 1618c2ecf20Sopenharmony_ci spin_lock_irqsave(&ha->tgt.sess_lock, flags); 1628c2ecf20Sopenharmony_ci list_for_each_entry(sess, &vha->vp_fcports, list) 1638c2ecf20Sopenharmony_ci seq_printf(s, "%02x:%02x:%02x %8phC %d\n", 1648c2ecf20Sopenharmony_ci sess->d_id.b.domain, sess->d_id.b.area, 1658c2ecf20Sopenharmony_ci sess->d_id.b.al_pa, sess->port_name, 1668c2ecf20Sopenharmony_ci sess->loop_id); 1678c2ecf20Sopenharmony_ci spin_unlock_irqrestore(&ha->tgt.sess_lock, flags); 1688c2ecf20Sopenharmony_ci } 1698c2ecf20Sopenharmony_ci 1708c2ecf20Sopenharmony_ci return 0; 1718c2ecf20Sopenharmony_ci} 1728c2ecf20Sopenharmony_ci 1738c2ecf20Sopenharmony_ciDEFINE_SHOW_ATTRIBUTE(qla2x00_dfs_tgt_sess); 1748c2ecf20Sopenharmony_ci 1758c2ecf20Sopenharmony_cistatic int 1768c2ecf20Sopenharmony_ciqla2x00_dfs_tgt_port_database_show(struct seq_file *s, void *unused) 1778c2ecf20Sopenharmony_ci{ 1788c2ecf20Sopenharmony_ci scsi_qla_host_t *vha = s->private; 1798c2ecf20Sopenharmony_ci struct qla_hw_data *ha = vha->hw; 1808c2ecf20Sopenharmony_ci struct gid_list_info *gid_list; 1818c2ecf20Sopenharmony_ci dma_addr_t gid_list_dma; 1828c2ecf20Sopenharmony_ci fc_port_t fc_port; 1838c2ecf20Sopenharmony_ci char *id_iter; 1848c2ecf20Sopenharmony_ci int rc, i; 1858c2ecf20Sopenharmony_ci uint16_t entries, loop_id; 1868c2ecf20Sopenharmony_ci 1878c2ecf20Sopenharmony_ci seq_printf(s, "%s\n", vha->host_str); 1888c2ecf20Sopenharmony_ci gid_list = dma_alloc_coherent(&ha->pdev->dev, 1898c2ecf20Sopenharmony_ci qla2x00_gid_list_size(ha), 1908c2ecf20Sopenharmony_ci &gid_list_dma, GFP_KERNEL); 1918c2ecf20Sopenharmony_ci if (!gid_list) { 1928c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_user, vha, 0x7018, 1938c2ecf20Sopenharmony_ci "DMA allocation failed for %u\n", 1948c2ecf20Sopenharmony_ci qla2x00_gid_list_size(ha)); 1958c2ecf20Sopenharmony_ci return 0; 1968c2ecf20Sopenharmony_ci } 1978c2ecf20Sopenharmony_ci 1988c2ecf20Sopenharmony_ci rc = qla24xx_gidlist_wait(vha, gid_list, gid_list_dma, 1998c2ecf20Sopenharmony_ci &entries); 2008c2ecf20Sopenharmony_ci if (rc != QLA_SUCCESS) 2018c2ecf20Sopenharmony_ci goto out_free_id_list; 2028c2ecf20Sopenharmony_ci 2038c2ecf20Sopenharmony_ci id_iter = (char *)gid_list; 2048c2ecf20Sopenharmony_ci 2058c2ecf20Sopenharmony_ci seq_puts(s, "Port Name Port ID Loop ID\n"); 2068c2ecf20Sopenharmony_ci 2078c2ecf20Sopenharmony_ci for (i = 0; i < entries; i++) { 2088c2ecf20Sopenharmony_ci struct gid_list_info *gid = 2098c2ecf20Sopenharmony_ci (struct gid_list_info *)id_iter; 2108c2ecf20Sopenharmony_ci loop_id = le16_to_cpu(gid->loop_id); 2118c2ecf20Sopenharmony_ci memset(&fc_port, 0, sizeof(fc_port_t)); 2128c2ecf20Sopenharmony_ci 2138c2ecf20Sopenharmony_ci fc_port.loop_id = loop_id; 2148c2ecf20Sopenharmony_ci 2158c2ecf20Sopenharmony_ci rc = qla24xx_gpdb_wait(vha, &fc_port, 0); 2168c2ecf20Sopenharmony_ci seq_printf(s, "%8phC %02x%02x%02x %d\n", 2178c2ecf20Sopenharmony_ci fc_port.port_name, fc_port.d_id.b.domain, 2188c2ecf20Sopenharmony_ci fc_port.d_id.b.area, fc_port.d_id.b.al_pa, 2198c2ecf20Sopenharmony_ci fc_port.loop_id); 2208c2ecf20Sopenharmony_ci id_iter += ha->gid_list_info_size; 2218c2ecf20Sopenharmony_ci } 2228c2ecf20Sopenharmony_ciout_free_id_list: 2238c2ecf20Sopenharmony_ci dma_free_coherent(&ha->pdev->dev, qla2x00_gid_list_size(ha), 2248c2ecf20Sopenharmony_ci gid_list, gid_list_dma); 2258c2ecf20Sopenharmony_ci 2268c2ecf20Sopenharmony_ci return 0; 2278c2ecf20Sopenharmony_ci} 2288c2ecf20Sopenharmony_ci 2298c2ecf20Sopenharmony_ciDEFINE_SHOW_ATTRIBUTE(qla2x00_dfs_tgt_port_database); 2308c2ecf20Sopenharmony_ci 2318c2ecf20Sopenharmony_cistatic int 2328c2ecf20Sopenharmony_ciqla_dfs_fw_resource_cnt_show(struct seq_file *s, void *unused) 2338c2ecf20Sopenharmony_ci{ 2348c2ecf20Sopenharmony_ci struct scsi_qla_host *vha = s->private; 2358c2ecf20Sopenharmony_ci uint16_t mb[MAX_IOCB_MB_REG]; 2368c2ecf20Sopenharmony_ci int rc; 2378c2ecf20Sopenharmony_ci struct qla_hw_data *ha = vha->hw; 2388c2ecf20Sopenharmony_ci u16 iocbs_used, i; 2398c2ecf20Sopenharmony_ci 2408c2ecf20Sopenharmony_ci rc = qla24xx_res_count_wait(vha, mb, SIZEOF_IOCB_MB_REG); 2418c2ecf20Sopenharmony_ci if (rc != QLA_SUCCESS) { 2428c2ecf20Sopenharmony_ci seq_printf(s, "Mailbox Command failed %d, mb %#x", rc, mb[0]); 2438c2ecf20Sopenharmony_ci } else { 2448c2ecf20Sopenharmony_ci seq_puts(s, "FW Resource count\n\n"); 2458c2ecf20Sopenharmony_ci seq_printf(s, "Original TGT exchg count[%d]\n", mb[1]); 2468c2ecf20Sopenharmony_ci seq_printf(s, "Current TGT exchg count[%d]\n", mb[2]); 2478c2ecf20Sopenharmony_ci seq_printf(s, "Current Initiator Exchange count[%d]\n", mb[3]); 2488c2ecf20Sopenharmony_ci seq_printf(s, "Original Initiator Exchange count[%d]\n", mb[6]); 2498c2ecf20Sopenharmony_ci seq_printf(s, "Current IOCB count[%d]\n", mb[7]); 2508c2ecf20Sopenharmony_ci seq_printf(s, "Original IOCB count[%d]\n", mb[10]); 2518c2ecf20Sopenharmony_ci seq_printf(s, "MAX VP count[%d]\n", mb[11]); 2528c2ecf20Sopenharmony_ci seq_printf(s, "MAX FCF count[%d]\n", mb[12]); 2538c2ecf20Sopenharmony_ci seq_printf(s, "Current free pageable XCB buffer cnt[%d]\n", 2548c2ecf20Sopenharmony_ci mb[20]); 2558c2ecf20Sopenharmony_ci seq_printf(s, "Original Initiator fast XCB buffer cnt[%d]\n", 2568c2ecf20Sopenharmony_ci mb[21]); 2578c2ecf20Sopenharmony_ci seq_printf(s, "Current free Initiator fast XCB buffer cnt[%d]\n", 2588c2ecf20Sopenharmony_ci mb[22]); 2598c2ecf20Sopenharmony_ci seq_printf(s, "Original Target fast XCB buffer cnt[%d]\n", 2608c2ecf20Sopenharmony_ci mb[23]); 2618c2ecf20Sopenharmony_ci } 2628c2ecf20Sopenharmony_ci 2638c2ecf20Sopenharmony_ci if (ql2xenforce_iocb_limit) { 2648c2ecf20Sopenharmony_ci /* lock is not require. It's an estimate. */ 2658c2ecf20Sopenharmony_ci iocbs_used = ha->base_qpair->fwres.iocbs_used; 2668c2ecf20Sopenharmony_ci for (i = 0; i < ha->max_qpairs; i++) { 2678c2ecf20Sopenharmony_ci if (ha->queue_pair_map[i]) 2688c2ecf20Sopenharmony_ci iocbs_used += ha->queue_pair_map[i]->fwres.iocbs_used; 2698c2ecf20Sopenharmony_ci } 2708c2ecf20Sopenharmony_ci 2718c2ecf20Sopenharmony_ci seq_printf(s, "Driver: estimate iocb used [%d] high water limit [%d]\n", 2728c2ecf20Sopenharmony_ci iocbs_used, ha->base_qpair->fwres.iocbs_limit); 2738c2ecf20Sopenharmony_ci } 2748c2ecf20Sopenharmony_ci 2758c2ecf20Sopenharmony_ci return 0; 2768c2ecf20Sopenharmony_ci} 2778c2ecf20Sopenharmony_ci 2788c2ecf20Sopenharmony_ciDEFINE_SHOW_ATTRIBUTE(qla_dfs_fw_resource_cnt); 2798c2ecf20Sopenharmony_ci 2808c2ecf20Sopenharmony_cistatic int 2818c2ecf20Sopenharmony_ciqla_dfs_tgt_counters_show(struct seq_file *s, void *unused) 2828c2ecf20Sopenharmony_ci{ 2838c2ecf20Sopenharmony_ci struct scsi_qla_host *vha = s->private; 2848c2ecf20Sopenharmony_ci struct qla_qpair *qpair = vha->hw->base_qpair; 2858c2ecf20Sopenharmony_ci uint64_t qla_core_sbt_cmd, core_qla_que_buf, qla_core_ret_ctio, 2868c2ecf20Sopenharmony_ci core_qla_snd_status, qla_core_ret_sta_ctio, core_qla_free_cmd, 2878c2ecf20Sopenharmony_ci num_q_full_sent, num_alloc_iocb_failed, num_term_xchg_sent; 2888c2ecf20Sopenharmony_ci u16 i; 2898c2ecf20Sopenharmony_ci 2908c2ecf20Sopenharmony_ci qla_core_sbt_cmd = qpair->tgt_counters.qla_core_sbt_cmd; 2918c2ecf20Sopenharmony_ci core_qla_que_buf = qpair->tgt_counters.core_qla_que_buf; 2928c2ecf20Sopenharmony_ci qla_core_ret_ctio = qpair->tgt_counters.qla_core_ret_ctio; 2938c2ecf20Sopenharmony_ci core_qla_snd_status = qpair->tgt_counters.core_qla_snd_status; 2948c2ecf20Sopenharmony_ci qla_core_ret_sta_ctio = qpair->tgt_counters.qla_core_ret_sta_ctio; 2958c2ecf20Sopenharmony_ci core_qla_free_cmd = qpair->tgt_counters.core_qla_free_cmd; 2968c2ecf20Sopenharmony_ci num_q_full_sent = qpair->tgt_counters.num_q_full_sent; 2978c2ecf20Sopenharmony_ci num_alloc_iocb_failed = qpair->tgt_counters.num_alloc_iocb_failed; 2988c2ecf20Sopenharmony_ci num_term_xchg_sent = qpair->tgt_counters.num_term_xchg_sent; 2998c2ecf20Sopenharmony_ci 3008c2ecf20Sopenharmony_ci for (i = 0; i < vha->hw->max_qpairs; i++) { 3018c2ecf20Sopenharmony_ci qpair = vha->hw->queue_pair_map[i]; 3028c2ecf20Sopenharmony_ci if (!qpair) 3038c2ecf20Sopenharmony_ci continue; 3048c2ecf20Sopenharmony_ci qla_core_sbt_cmd += qpair->tgt_counters.qla_core_sbt_cmd; 3058c2ecf20Sopenharmony_ci core_qla_que_buf += qpair->tgt_counters.core_qla_que_buf; 3068c2ecf20Sopenharmony_ci qla_core_ret_ctio += qpair->tgt_counters.qla_core_ret_ctio; 3078c2ecf20Sopenharmony_ci core_qla_snd_status += qpair->tgt_counters.core_qla_snd_status; 3088c2ecf20Sopenharmony_ci qla_core_ret_sta_ctio += 3098c2ecf20Sopenharmony_ci qpair->tgt_counters.qla_core_ret_sta_ctio; 3108c2ecf20Sopenharmony_ci core_qla_free_cmd += qpair->tgt_counters.core_qla_free_cmd; 3118c2ecf20Sopenharmony_ci num_q_full_sent += qpair->tgt_counters.num_q_full_sent; 3128c2ecf20Sopenharmony_ci num_alloc_iocb_failed += 3138c2ecf20Sopenharmony_ci qpair->tgt_counters.num_alloc_iocb_failed; 3148c2ecf20Sopenharmony_ci num_term_xchg_sent += qpair->tgt_counters.num_term_xchg_sent; 3158c2ecf20Sopenharmony_ci } 3168c2ecf20Sopenharmony_ci 3178c2ecf20Sopenharmony_ci seq_puts(s, "Target Counters\n"); 3188c2ecf20Sopenharmony_ci seq_printf(s, "qla_core_sbt_cmd = %lld\n", 3198c2ecf20Sopenharmony_ci qla_core_sbt_cmd); 3208c2ecf20Sopenharmony_ci seq_printf(s, "qla_core_ret_sta_ctio = %lld\n", 3218c2ecf20Sopenharmony_ci qla_core_ret_sta_ctio); 3228c2ecf20Sopenharmony_ci seq_printf(s, "qla_core_ret_ctio = %lld\n", 3238c2ecf20Sopenharmony_ci qla_core_ret_ctio); 3248c2ecf20Sopenharmony_ci seq_printf(s, "core_qla_que_buf = %lld\n", 3258c2ecf20Sopenharmony_ci core_qla_que_buf); 3268c2ecf20Sopenharmony_ci seq_printf(s, "core_qla_snd_status = %lld\n", 3278c2ecf20Sopenharmony_ci core_qla_snd_status); 3288c2ecf20Sopenharmony_ci seq_printf(s, "core_qla_free_cmd = %lld\n", 3298c2ecf20Sopenharmony_ci core_qla_free_cmd); 3308c2ecf20Sopenharmony_ci seq_printf(s, "num alloc iocb failed = %lld\n", 3318c2ecf20Sopenharmony_ci num_alloc_iocb_failed); 3328c2ecf20Sopenharmony_ci seq_printf(s, "num term exchange sent = %lld\n", 3338c2ecf20Sopenharmony_ci num_term_xchg_sent); 3348c2ecf20Sopenharmony_ci seq_printf(s, "num Q full sent = %lld\n", 3358c2ecf20Sopenharmony_ci num_q_full_sent); 3368c2ecf20Sopenharmony_ci 3378c2ecf20Sopenharmony_ci /* DIF stats */ 3388c2ecf20Sopenharmony_ci seq_printf(s, "DIF Inp Bytes = %lld\n", 3398c2ecf20Sopenharmony_ci vha->qla_stats.qla_dif_stats.dif_input_bytes); 3408c2ecf20Sopenharmony_ci seq_printf(s, "DIF Outp Bytes = %lld\n", 3418c2ecf20Sopenharmony_ci vha->qla_stats.qla_dif_stats.dif_output_bytes); 3428c2ecf20Sopenharmony_ci seq_printf(s, "DIF Inp Req = %lld\n", 3438c2ecf20Sopenharmony_ci vha->qla_stats.qla_dif_stats.dif_input_requests); 3448c2ecf20Sopenharmony_ci seq_printf(s, "DIF Outp Req = %lld\n", 3458c2ecf20Sopenharmony_ci vha->qla_stats.qla_dif_stats.dif_output_requests); 3468c2ecf20Sopenharmony_ci seq_printf(s, "DIF Guard err = %d\n", 3478c2ecf20Sopenharmony_ci vha->qla_stats.qla_dif_stats.dif_guard_err); 3488c2ecf20Sopenharmony_ci seq_printf(s, "DIF Ref tag err = %d\n", 3498c2ecf20Sopenharmony_ci vha->qla_stats.qla_dif_stats.dif_ref_tag_err); 3508c2ecf20Sopenharmony_ci seq_printf(s, "DIF App tag err = %d\n", 3518c2ecf20Sopenharmony_ci vha->qla_stats.qla_dif_stats.dif_app_tag_err); 3528c2ecf20Sopenharmony_ci return 0; 3538c2ecf20Sopenharmony_ci} 3548c2ecf20Sopenharmony_ci 3558c2ecf20Sopenharmony_ciDEFINE_SHOW_ATTRIBUTE(qla_dfs_tgt_counters); 3568c2ecf20Sopenharmony_ci 3578c2ecf20Sopenharmony_cistatic int 3588c2ecf20Sopenharmony_ciqla2x00_dfs_fce_show(struct seq_file *s, void *unused) 3598c2ecf20Sopenharmony_ci{ 3608c2ecf20Sopenharmony_ci scsi_qla_host_t *vha = s->private; 3618c2ecf20Sopenharmony_ci uint32_t cnt; 3628c2ecf20Sopenharmony_ci uint32_t *fce; 3638c2ecf20Sopenharmony_ci uint64_t fce_start; 3648c2ecf20Sopenharmony_ci struct qla_hw_data *ha = vha->hw; 3658c2ecf20Sopenharmony_ci 3668c2ecf20Sopenharmony_ci mutex_lock(&ha->fce_mutex); 3678c2ecf20Sopenharmony_ci 3688c2ecf20Sopenharmony_ci seq_puts(s, "FCE Trace Buffer\n"); 3698c2ecf20Sopenharmony_ci seq_printf(s, "In Pointer = %llx\n\n", (unsigned long long)ha->fce_wr); 3708c2ecf20Sopenharmony_ci seq_printf(s, "Base = %llx\n\n", (unsigned long long) ha->fce_dma); 3718c2ecf20Sopenharmony_ci seq_puts(s, "FCE Enable Registers\n"); 3728c2ecf20Sopenharmony_ci seq_printf(s, "%08x %08x %08x %08x %08x %08x\n", 3738c2ecf20Sopenharmony_ci ha->fce_mb[0], ha->fce_mb[2], ha->fce_mb[3], ha->fce_mb[4], 3748c2ecf20Sopenharmony_ci ha->fce_mb[5], ha->fce_mb[6]); 3758c2ecf20Sopenharmony_ci 3768c2ecf20Sopenharmony_ci fce = (uint32_t *) ha->fce; 3778c2ecf20Sopenharmony_ci fce_start = (unsigned long long) ha->fce_dma; 3788c2ecf20Sopenharmony_ci for (cnt = 0; cnt < fce_calc_size(ha->fce_bufs) / 4; cnt++) { 3798c2ecf20Sopenharmony_ci if (cnt % 8 == 0) 3808c2ecf20Sopenharmony_ci seq_printf(s, "\n%llx: ", 3818c2ecf20Sopenharmony_ci (unsigned long long)((cnt * 4) + fce_start)); 3828c2ecf20Sopenharmony_ci else 3838c2ecf20Sopenharmony_ci seq_putc(s, ' '); 3848c2ecf20Sopenharmony_ci seq_printf(s, "%08x", *fce++); 3858c2ecf20Sopenharmony_ci } 3868c2ecf20Sopenharmony_ci 3878c2ecf20Sopenharmony_ci seq_puts(s, "\nEnd\n"); 3888c2ecf20Sopenharmony_ci 3898c2ecf20Sopenharmony_ci mutex_unlock(&ha->fce_mutex); 3908c2ecf20Sopenharmony_ci 3918c2ecf20Sopenharmony_ci return 0; 3928c2ecf20Sopenharmony_ci} 3938c2ecf20Sopenharmony_ci 3948c2ecf20Sopenharmony_cistatic int 3958c2ecf20Sopenharmony_ciqla2x00_dfs_fce_open(struct inode *inode, struct file *file) 3968c2ecf20Sopenharmony_ci{ 3978c2ecf20Sopenharmony_ci scsi_qla_host_t *vha = inode->i_private; 3988c2ecf20Sopenharmony_ci struct qla_hw_data *ha = vha->hw; 3998c2ecf20Sopenharmony_ci int rval; 4008c2ecf20Sopenharmony_ci 4018c2ecf20Sopenharmony_ci if (!ha->flags.fce_enabled) 4028c2ecf20Sopenharmony_ci goto out; 4038c2ecf20Sopenharmony_ci 4048c2ecf20Sopenharmony_ci mutex_lock(&ha->fce_mutex); 4058c2ecf20Sopenharmony_ci 4068c2ecf20Sopenharmony_ci /* Pause tracing to flush FCE buffers. */ 4078c2ecf20Sopenharmony_ci rval = qla2x00_disable_fce_trace(vha, &ha->fce_wr, &ha->fce_rd); 4088c2ecf20Sopenharmony_ci if (rval) 4098c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_user, vha, 0x705c, 4108c2ecf20Sopenharmony_ci "DebugFS: Unable to disable FCE (%d).\n", rval); 4118c2ecf20Sopenharmony_ci 4128c2ecf20Sopenharmony_ci ha->flags.fce_enabled = 0; 4138c2ecf20Sopenharmony_ci 4148c2ecf20Sopenharmony_ci mutex_unlock(&ha->fce_mutex); 4158c2ecf20Sopenharmony_ciout: 4168c2ecf20Sopenharmony_ci return single_open(file, qla2x00_dfs_fce_show, vha); 4178c2ecf20Sopenharmony_ci} 4188c2ecf20Sopenharmony_ci 4198c2ecf20Sopenharmony_cistatic int 4208c2ecf20Sopenharmony_ciqla2x00_dfs_fce_release(struct inode *inode, struct file *file) 4218c2ecf20Sopenharmony_ci{ 4228c2ecf20Sopenharmony_ci scsi_qla_host_t *vha = inode->i_private; 4238c2ecf20Sopenharmony_ci struct qla_hw_data *ha = vha->hw; 4248c2ecf20Sopenharmony_ci int rval; 4258c2ecf20Sopenharmony_ci 4268c2ecf20Sopenharmony_ci if (ha->flags.fce_enabled) 4278c2ecf20Sopenharmony_ci goto out; 4288c2ecf20Sopenharmony_ci 4298c2ecf20Sopenharmony_ci mutex_lock(&ha->fce_mutex); 4308c2ecf20Sopenharmony_ci 4318c2ecf20Sopenharmony_ci /* Re-enable FCE tracing. */ 4328c2ecf20Sopenharmony_ci ha->flags.fce_enabled = 1; 4338c2ecf20Sopenharmony_ci memset(ha->fce, 0, fce_calc_size(ha->fce_bufs)); 4348c2ecf20Sopenharmony_ci rval = qla2x00_enable_fce_trace(vha, ha->fce_dma, ha->fce_bufs, 4358c2ecf20Sopenharmony_ci ha->fce_mb, &ha->fce_bufs); 4368c2ecf20Sopenharmony_ci if (rval) { 4378c2ecf20Sopenharmony_ci ql_dbg(ql_dbg_user, vha, 0x700d, 4388c2ecf20Sopenharmony_ci "DebugFS: Unable to reinitialize FCE (%d).\n", rval); 4398c2ecf20Sopenharmony_ci ha->flags.fce_enabled = 0; 4408c2ecf20Sopenharmony_ci } 4418c2ecf20Sopenharmony_ci 4428c2ecf20Sopenharmony_ci mutex_unlock(&ha->fce_mutex); 4438c2ecf20Sopenharmony_ciout: 4448c2ecf20Sopenharmony_ci return single_release(inode, file); 4458c2ecf20Sopenharmony_ci} 4468c2ecf20Sopenharmony_ci 4478c2ecf20Sopenharmony_cistatic const struct file_operations dfs_fce_ops = { 4488c2ecf20Sopenharmony_ci .open = qla2x00_dfs_fce_open, 4498c2ecf20Sopenharmony_ci .read = seq_read, 4508c2ecf20Sopenharmony_ci .llseek = seq_lseek, 4518c2ecf20Sopenharmony_ci .release = qla2x00_dfs_fce_release, 4528c2ecf20Sopenharmony_ci}; 4538c2ecf20Sopenharmony_ci 4548c2ecf20Sopenharmony_cistatic int 4558c2ecf20Sopenharmony_ciqla_dfs_naqp_show(struct seq_file *s, void *unused) 4568c2ecf20Sopenharmony_ci{ 4578c2ecf20Sopenharmony_ci struct scsi_qla_host *vha = s->private; 4588c2ecf20Sopenharmony_ci struct qla_hw_data *ha = vha->hw; 4598c2ecf20Sopenharmony_ci 4608c2ecf20Sopenharmony_ci seq_printf(s, "%d\n", ha->tgt.num_act_qpairs); 4618c2ecf20Sopenharmony_ci return 0; 4628c2ecf20Sopenharmony_ci} 4638c2ecf20Sopenharmony_ci 4648c2ecf20Sopenharmony_cistatic int 4658c2ecf20Sopenharmony_ciqla_dfs_naqp_open(struct inode *inode, struct file *file) 4668c2ecf20Sopenharmony_ci{ 4678c2ecf20Sopenharmony_ci struct scsi_qla_host *vha = inode->i_private; 4688c2ecf20Sopenharmony_ci 4698c2ecf20Sopenharmony_ci return single_open(file, qla_dfs_naqp_show, vha); 4708c2ecf20Sopenharmony_ci} 4718c2ecf20Sopenharmony_ci 4728c2ecf20Sopenharmony_cistatic ssize_t 4738c2ecf20Sopenharmony_ciqla_dfs_naqp_write(struct file *file, const char __user *buffer, 4748c2ecf20Sopenharmony_ci size_t count, loff_t *pos) 4758c2ecf20Sopenharmony_ci{ 4768c2ecf20Sopenharmony_ci struct seq_file *s = file->private_data; 4778c2ecf20Sopenharmony_ci struct scsi_qla_host *vha = s->private; 4788c2ecf20Sopenharmony_ci struct qla_hw_data *ha = vha->hw; 4798c2ecf20Sopenharmony_ci char *buf; 4808c2ecf20Sopenharmony_ci int rc = 0; 4818c2ecf20Sopenharmony_ci unsigned long num_act_qp; 4828c2ecf20Sopenharmony_ci 4838c2ecf20Sopenharmony_ci if (!(IS_QLA27XX(ha) || IS_QLA83XX(ha) || IS_QLA28XX(ha))) { 4848c2ecf20Sopenharmony_ci pr_err("host%ld: this adapter does not support Multi Q.", 4858c2ecf20Sopenharmony_ci vha->host_no); 4868c2ecf20Sopenharmony_ci return -EINVAL; 4878c2ecf20Sopenharmony_ci } 4888c2ecf20Sopenharmony_ci 4898c2ecf20Sopenharmony_ci if (!vha->flags.qpairs_available) { 4908c2ecf20Sopenharmony_ci pr_err("host%ld: Driver is not setup with Multi Q.", 4918c2ecf20Sopenharmony_ci vha->host_no); 4928c2ecf20Sopenharmony_ci return -EINVAL; 4938c2ecf20Sopenharmony_ci } 4948c2ecf20Sopenharmony_ci buf = memdup_user_nul(buffer, count); 4958c2ecf20Sopenharmony_ci if (IS_ERR(buf)) { 4968c2ecf20Sopenharmony_ci pr_err("host%ld: fail to copy user buffer.", 4978c2ecf20Sopenharmony_ci vha->host_no); 4988c2ecf20Sopenharmony_ci return PTR_ERR(buf); 4998c2ecf20Sopenharmony_ci } 5008c2ecf20Sopenharmony_ci 5018c2ecf20Sopenharmony_ci num_act_qp = simple_strtoul(buf, NULL, 0); 5028c2ecf20Sopenharmony_ci 5038c2ecf20Sopenharmony_ci if (num_act_qp >= vha->hw->max_qpairs) { 5048c2ecf20Sopenharmony_ci pr_err("User set invalid number of qpairs %lu. Max = %d", 5058c2ecf20Sopenharmony_ci num_act_qp, vha->hw->max_qpairs); 5068c2ecf20Sopenharmony_ci rc = -EINVAL; 5078c2ecf20Sopenharmony_ci goto out_free; 5088c2ecf20Sopenharmony_ci } 5098c2ecf20Sopenharmony_ci 5108c2ecf20Sopenharmony_ci if (num_act_qp != ha->tgt.num_act_qpairs) { 5118c2ecf20Sopenharmony_ci ha->tgt.num_act_qpairs = num_act_qp; 5128c2ecf20Sopenharmony_ci qlt_clr_qp_table(vha); 5138c2ecf20Sopenharmony_ci } 5148c2ecf20Sopenharmony_ci rc = count; 5158c2ecf20Sopenharmony_ciout_free: 5168c2ecf20Sopenharmony_ci kfree(buf); 5178c2ecf20Sopenharmony_ci return rc; 5188c2ecf20Sopenharmony_ci} 5198c2ecf20Sopenharmony_ci 5208c2ecf20Sopenharmony_cistatic const struct file_operations dfs_naqp_ops = { 5218c2ecf20Sopenharmony_ci .open = qla_dfs_naqp_open, 5228c2ecf20Sopenharmony_ci .read = seq_read, 5238c2ecf20Sopenharmony_ci .llseek = seq_lseek, 5248c2ecf20Sopenharmony_ci .release = single_release, 5258c2ecf20Sopenharmony_ci .write = qla_dfs_naqp_write, 5268c2ecf20Sopenharmony_ci}; 5278c2ecf20Sopenharmony_ci 5288c2ecf20Sopenharmony_ci 5298c2ecf20Sopenharmony_ciint 5308c2ecf20Sopenharmony_ciqla2x00_dfs_setup(scsi_qla_host_t *vha) 5318c2ecf20Sopenharmony_ci{ 5328c2ecf20Sopenharmony_ci struct qla_hw_data *ha = vha->hw; 5338c2ecf20Sopenharmony_ci 5348c2ecf20Sopenharmony_ci if (!IS_QLA25XX(ha) && !IS_QLA81XX(ha) && !IS_QLA83XX(ha) && 5358c2ecf20Sopenharmony_ci !IS_QLA27XX(ha) && !IS_QLA28XX(ha)) 5368c2ecf20Sopenharmony_ci goto out; 5378c2ecf20Sopenharmony_ci if (!ha->fce) 5388c2ecf20Sopenharmony_ci goto out; 5398c2ecf20Sopenharmony_ci 5408c2ecf20Sopenharmony_ci if (qla2x00_dfs_root) 5418c2ecf20Sopenharmony_ci goto create_dir; 5428c2ecf20Sopenharmony_ci 5438c2ecf20Sopenharmony_ci atomic_set(&qla2x00_dfs_root_count, 0); 5448c2ecf20Sopenharmony_ci qla2x00_dfs_root = debugfs_create_dir(QLA2XXX_DRIVER_NAME, NULL); 5458c2ecf20Sopenharmony_ci 5468c2ecf20Sopenharmony_cicreate_dir: 5478c2ecf20Sopenharmony_ci if (ha->dfs_dir) 5488c2ecf20Sopenharmony_ci goto create_nodes; 5498c2ecf20Sopenharmony_ci 5508c2ecf20Sopenharmony_ci mutex_init(&ha->fce_mutex); 5518c2ecf20Sopenharmony_ci ha->dfs_dir = debugfs_create_dir(vha->host_str, qla2x00_dfs_root); 5528c2ecf20Sopenharmony_ci 5538c2ecf20Sopenharmony_ci atomic_inc(&qla2x00_dfs_root_count); 5548c2ecf20Sopenharmony_ci 5558c2ecf20Sopenharmony_cicreate_nodes: 5568c2ecf20Sopenharmony_ci ha->dfs_fw_resource_cnt = debugfs_create_file("fw_resource_count", 5578c2ecf20Sopenharmony_ci S_IRUSR, ha->dfs_dir, vha, &qla_dfs_fw_resource_cnt_fops); 5588c2ecf20Sopenharmony_ci 5598c2ecf20Sopenharmony_ci ha->dfs_tgt_counters = debugfs_create_file("tgt_counters", S_IRUSR, 5608c2ecf20Sopenharmony_ci ha->dfs_dir, vha, &qla_dfs_tgt_counters_fops); 5618c2ecf20Sopenharmony_ci 5628c2ecf20Sopenharmony_ci ha->tgt.dfs_tgt_port_database = debugfs_create_file("tgt_port_database", 5638c2ecf20Sopenharmony_ci S_IRUSR, ha->dfs_dir, vha, &qla2x00_dfs_tgt_port_database_fops); 5648c2ecf20Sopenharmony_ci 5658c2ecf20Sopenharmony_ci ha->dfs_fce = debugfs_create_file("fce", S_IRUSR, ha->dfs_dir, vha, 5668c2ecf20Sopenharmony_ci &dfs_fce_ops); 5678c2ecf20Sopenharmony_ci 5688c2ecf20Sopenharmony_ci ha->tgt.dfs_tgt_sess = debugfs_create_file("tgt_sess", 5698c2ecf20Sopenharmony_ci S_IRUSR, ha->dfs_dir, vha, &qla2x00_dfs_tgt_sess_fops); 5708c2ecf20Sopenharmony_ci 5718c2ecf20Sopenharmony_ci if (IS_QLA27XX(ha) || IS_QLA83XX(ha) || IS_QLA28XX(ha)) { 5728c2ecf20Sopenharmony_ci ha->tgt.dfs_naqp = debugfs_create_file("naqp", 5738c2ecf20Sopenharmony_ci 0400, ha->dfs_dir, vha, &dfs_naqp_ops); 5748c2ecf20Sopenharmony_ci if (IS_ERR(ha->tgt.dfs_naqp)) { 5758c2ecf20Sopenharmony_ci ql_log(ql_log_warn, vha, 0xd011, 5768c2ecf20Sopenharmony_ci "Unable to create debugFS naqp node.\n"); 5778c2ecf20Sopenharmony_ci goto out; 5788c2ecf20Sopenharmony_ci } 5798c2ecf20Sopenharmony_ci } 5808c2ecf20Sopenharmony_ci vha->dfs_rport_root = debugfs_create_dir("rports", ha->dfs_dir); 5818c2ecf20Sopenharmony_ci if (IS_ERR(vha->dfs_rport_root)) { 5828c2ecf20Sopenharmony_ci ql_log(ql_log_warn, vha, 0xd012, 5838c2ecf20Sopenharmony_ci "Unable to create debugFS rports node.\n"); 5848c2ecf20Sopenharmony_ci goto out; 5858c2ecf20Sopenharmony_ci } 5868c2ecf20Sopenharmony_ciout: 5878c2ecf20Sopenharmony_ci return 0; 5888c2ecf20Sopenharmony_ci} 5898c2ecf20Sopenharmony_ci 5908c2ecf20Sopenharmony_ciint 5918c2ecf20Sopenharmony_ciqla2x00_dfs_remove(scsi_qla_host_t *vha) 5928c2ecf20Sopenharmony_ci{ 5938c2ecf20Sopenharmony_ci struct qla_hw_data *ha = vha->hw; 5948c2ecf20Sopenharmony_ci 5958c2ecf20Sopenharmony_ci if (ha->tgt.dfs_naqp) { 5968c2ecf20Sopenharmony_ci debugfs_remove(ha->tgt.dfs_naqp); 5978c2ecf20Sopenharmony_ci ha->tgt.dfs_naqp = NULL; 5988c2ecf20Sopenharmony_ci } 5998c2ecf20Sopenharmony_ci 6008c2ecf20Sopenharmony_ci if (ha->tgt.dfs_tgt_sess) { 6018c2ecf20Sopenharmony_ci debugfs_remove(ha->tgt.dfs_tgt_sess); 6028c2ecf20Sopenharmony_ci ha->tgt.dfs_tgt_sess = NULL; 6038c2ecf20Sopenharmony_ci } 6048c2ecf20Sopenharmony_ci 6058c2ecf20Sopenharmony_ci if (ha->tgt.dfs_tgt_port_database) { 6068c2ecf20Sopenharmony_ci debugfs_remove(ha->tgt.dfs_tgt_port_database); 6078c2ecf20Sopenharmony_ci ha->tgt.dfs_tgt_port_database = NULL; 6088c2ecf20Sopenharmony_ci } 6098c2ecf20Sopenharmony_ci 6108c2ecf20Sopenharmony_ci if (ha->dfs_fw_resource_cnt) { 6118c2ecf20Sopenharmony_ci debugfs_remove(ha->dfs_fw_resource_cnt); 6128c2ecf20Sopenharmony_ci ha->dfs_fw_resource_cnt = NULL; 6138c2ecf20Sopenharmony_ci } 6148c2ecf20Sopenharmony_ci 6158c2ecf20Sopenharmony_ci if (ha->dfs_tgt_counters) { 6168c2ecf20Sopenharmony_ci debugfs_remove(ha->dfs_tgt_counters); 6178c2ecf20Sopenharmony_ci ha->dfs_tgt_counters = NULL; 6188c2ecf20Sopenharmony_ci } 6198c2ecf20Sopenharmony_ci 6208c2ecf20Sopenharmony_ci if (ha->dfs_fce) { 6218c2ecf20Sopenharmony_ci debugfs_remove(ha->dfs_fce); 6228c2ecf20Sopenharmony_ci ha->dfs_fce = NULL; 6238c2ecf20Sopenharmony_ci } 6248c2ecf20Sopenharmony_ci 6258c2ecf20Sopenharmony_ci if (vha->dfs_rport_root) { 6268c2ecf20Sopenharmony_ci debugfs_remove_recursive(vha->dfs_rport_root); 6278c2ecf20Sopenharmony_ci vha->dfs_rport_root = NULL; 6288c2ecf20Sopenharmony_ci } 6298c2ecf20Sopenharmony_ci 6308c2ecf20Sopenharmony_ci if (ha->dfs_dir) { 6318c2ecf20Sopenharmony_ci debugfs_remove(ha->dfs_dir); 6328c2ecf20Sopenharmony_ci ha->dfs_dir = NULL; 6338c2ecf20Sopenharmony_ci atomic_dec(&qla2x00_dfs_root_count); 6348c2ecf20Sopenharmony_ci } 6358c2ecf20Sopenharmony_ci 6368c2ecf20Sopenharmony_ci if (atomic_read(&qla2x00_dfs_root_count) == 0 && 6378c2ecf20Sopenharmony_ci qla2x00_dfs_root) { 6388c2ecf20Sopenharmony_ci debugfs_remove(qla2x00_dfs_root); 6398c2ecf20Sopenharmony_ci qla2x00_dfs_root = NULL; 6408c2ecf20Sopenharmony_ci } 6418c2ecf20Sopenharmony_ci 6428c2ecf20Sopenharmony_ci return 0; 6438c2ecf20Sopenharmony_ci} 644