mirror of
https://github.com/torvalds/linux.git
synced 2026-05-31 18:43:33 +02:00
Merge patch series "scsi: hisi_sas: Some fixes for hisi_sas"
Yihang Li <liyihang9@huawei.com> says: This series contains some fixes including: - Adjust priority of registering and exiting debugfs for security; - Create trigger_dump at the end of the debugfs initialization; - Add firmware information check; - Enable all PHYs that are not disabled by user during controller reset; - Reset PHY again if phyup timeout; - Check usage count only when the runtime PM status is RPM_SUSPENDING; - Add cond_resched() for no forced preemption model; - Default enable interrupt coalescing; - Update disk locked timeout to 7 seconds; - Add time interval between two H2D FIS following soft reset spec; - Update v3 hw STP_LINK_TIMER setting; - Create all dump files during debugfs initialization; - Add latest_dump for the debugfs dump; Link: https://lore.kernel.org/r/20241008021822.2617339-1-liyihang9@huawei.com Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
This commit is contained in:
commit
a3517717c3
|
|
@ -307,6 +307,7 @@ enum {
|
|||
|
||||
struct hisi_sas_hw {
|
||||
int (*hw_init)(struct hisi_hba *hisi_hba);
|
||||
int (*fw_info_check)(struct hisi_hba *hisi_hba);
|
||||
int (*interrupt_preinit)(struct hisi_hba *hisi_hba);
|
||||
void (*setup_itct)(struct hisi_hba *hisi_hba,
|
||||
struct hisi_sas_device *device);
|
||||
|
|
|
|||
|
|
@ -1321,6 +1321,7 @@ static int hisi_sas_softreset_ata_disk(struct domain_device *device)
|
|||
}
|
||||
|
||||
if (rc == TMF_RESP_FUNC_COMPLETE) {
|
||||
usleep_range(900, 1000);
|
||||
ata_for_each_link(link, ap, EDGE) {
|
||||
int pmp = sata_srst_pmp(link);
|
||||
|
||||
|
|
@ -1384,6 +1385,7 @@ static void hisi_sas_refresh_port_id(struct hisi_hba *hisi_hba)
|
|||
|
||||
static void hisi_sas_rescan_topology(struct hisi_hba *hisi_hba, u32 state)
|
||||
{
|
||||
u32 new_state = hisi_hba->hw->get_phys_state(hisi_hba);
|
||||
struct asd_sas_port *_sas_port = NULL;
|
||||
int phy_no;
|
||||
|
||||
|
|
@ -1397,7 +1399,7 @@ static void hisi_sas_rescan_topology(struct hisi_hba *hisi_hba, u32 state)
|
|||
continue;
|
||||
|
||||
/* Report PHY state change to libsas */
|
||||
if (state & BIT(phy_no)) {
|
||||
if (new_state & BIT(phy_no)) {
|
||||
if (do_port_check && sas_port && sas_port->port_dev) {
|
||||
struct domain_device *dev = sas_port->port_dev;
|
||||
|
||||
|
|
@ -1410,6 +1412,16 @@ static void hisi_sas_rescan_topology(struct hisi_hba *hisi_hba, u32 state)
|
|||
}
|
||||
} else {
|
||||
hisi_sas_phy_down(hisi_hba, phy_no, 0, GFP_KERNEL);
|
||||
|
||||
/*
|
||||
* The new_state is not ready but old_state is ready,
|
||||
* the two possible causes:
|
||||
* 1. The connected device is removed
|
||||
* 2. Device exists but phyup timed out
|
||||
*/
|
||||
if (state & BIT(phy_no))
|
||||
hisi_sas_notify_phy_event(phy,
|
||||
HISI_PHYE_LINK_RESET);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1545,10 +1557,16 @@ void hisi_sas_controller_reset_done(struct hisi_hba *hisi_hba)
|
|||
/* Init and wait for PHYs to come up and all libsas event finished. */
|
||||
for (phy_no = 0; phy_no < hisi_hba->n_phy; phy_no++) {
|
||||
struct hisi_sas_phy *phy = &hisi_hba->phy[phy_no];
|
||||
struct asd_sas_phy *sas_phy = &phy->sas_phy;
|
||||
|
||||
if (!(hisi_hba->phy_state & BIT(phy_no)))
|
||||
if (!sas_phy->phy->enabled)
|
||||
continue;
|
||||
|
||||
if (!(hisi_hba->phy_state & BIT(phy_no))) {
|
||||
hisi_sas_phy_enable(hisi_hba, phy_no, 1);
|
||||
continue;
|
||||
}
|
||||
|
||||
async_schedule_domain(hisi_sas_async_init_wait_phyup,
|
||||
phy, &async);
|
||||
}
|
||||
|
|
@ -2450,6 +2468,11 @@ static struct Scsi_Host *hisi_sas_shost_alloc(struct platform_device *pdev,
|
|||
if (hisi_sas_get_fw_info(hisi_hba) < 0)
|
||||
goto err_out;
|
||||
|
||||
if (hisi_hba->hw->fw_info_check) {
|
||||
if (hisi_hba->hw->fw_info_check(hisi_hba))
|
||||
goto err_out;
|
||||
}
|
||||
|
||||
error = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(64));
|
||||
if (error) {
|
||||
dev_err(dev, "No usable DMA addressing method\n");
|
||||
|
|
@ -2630,10 +2653,10 @@ static __init int hisi_sas_init(void)
|
|||
|
||||
static __exit void hisi_sas_exit(void)
|
||||
{
|
||||
sas_release_transport(hisi_sas_stt);
|
||||
|
||||
if (hisi_sas_debugfs_enable)
|
||||
debugfs_remove(hisi_sas_debugfs_dir);
|
||||
|
||||
sas_release_transport(hisi_sas_stt);
|
||||
}
|
||||
|
||||
module_init(hisi_sas_init);
|
||||
|
|
|
|||
|
|
@ -1734,6 +1734,23 @@ static struct attribute *host_v1_hw_attrs[] = {
|
|||
|
||||
ATTRIBUTE_GROUPS(host_v1_hw);
|
||||
|
||||
static int check_fw_info_v1_hw(struct hisi_hba *hisi_hba)
|
||||
{
|
||||
struct device *dev = hisi_hba->dev;
|
||||
|
||||
if (hisi_hba->n_phy < 0 || hisi_hba->n_phy > 9) {
|
||||
dev_err(dev, "invalid phy number from FW\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (hisi_hba->queue_count < 0 || hisi_hba->queue_count > 32) {
|
||||
dev_err(dev, "invalid queue count from FW\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct scsi_host_template sht_v1_hw = {
|
||||
LIBSAS_SHT_BASE_NO_SLAVE_INIT
|
||||
.device_configure = hisi_sas_device_configure,
|
||||
|
|
@ -1747,6 +1764,7 @@ static const struct scsi_host_template sht_v1_hw = {
|
|||
|
||||
static const struct hisi_sas_hw hisi_sas_v1_hw = {
|
||||
.hw_init = hisi_sas_v1_init,
|
||||
.fw_info_check = check_fw_info_v1_hw,
|
||||
.setup_itct = setup_itct_v1_hw,
|
||||
.sl_notify_ssp = sl_notify_ssp_v1_hw,
|
||||
.clear_itct = clear_itct_v1_hw,
|
||||
|
|
|
|||
|
|
@ -3566,6 +3566,23 @@ static void map_queues_v2_hw(struct Scsi_Host *shost)
|
|||
}
|
||||
}
|
||||
|
||||
static int check_fw_info_v2_hw(struct hisi_hba *hisi_hba)
|
||||
{
|
||||
struct device *dev = hisi_hba->dev;
|
||||
|
||||
if (hisi_hba->n_phy < 0 || hisi_hba->n_phy > 9) {
|
||||
dev_err(dev, "invalid phy number from FW\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (hisi_hba->queue_count < 0 || hisi_hba->queue_count > 16) {
|
||||
dev_err(dev, "invalid queue count from FW\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct scsi_host_template sht_v2_hw = {
|
||||
LIBSAS_SHT_BASE_NO_SLAVE_INIT
|
||||
.device_configure = hisi_sas_device_configure,
|
||||
|
|
@ -3582,6 +3599,7 @@ static const struct scsi_host_template sht_v2_hw = {
|
|||
|
||||
static const struct hisi_sas_hw hisi_sas_v2_hw = {
|
||||
.hw_init = hisi_sas_v2_init,
|
||||
.fw_info_check = check_fw_info_v2_hw,
|
||||
.interrupt_preinit = hisi_sas_v2_interrupt_preinit,
|
||||
.setup_itct = setup_itct_v2_hw,
|
||||
.slot_index_alloc = slot_index_alloc_quirk_v2_hw,
|
||||
|
|
|
|||
|
|
@ -43,6 +43,7 @@
|
|||
#define CQ_INT_CONVERGE_EN 0xb0
|
||||
#define CFG_AGING_TIME 0xbc
|
||||
#define HGC_DFX_CFG2 0xc0
|
||||
#define CFG_ICT_TIMER_STEP_TRSH 0xc8
|
||||
#define CFG_ABT_SET_QUERY_IPTT 0xd4
|
||||
#define CFG_SET_ABORTED_IPTT_OFF 0
|
||||
#define CFG_SET_ABORTED_IPTT_MSK (0xfff << CFG_SET_ABORTED_IPTT_OFF)
|
||||
|
|
@ -638,9 +639,12 @@ static void init_reg_v3_hw(struct hisi_hba *hisi_hba)
|
|||
hisi_sas_write32(hisi_hba, TRANS_LOCK_ICT_TIME, 0x4A817C80);
|
||||
hisi_sas_write32(hisi_hba, HGC_SAS_TXFAIL_RETRY_CTRL, 0x108);
|
||||
hisi_sas_write32(hisi_hba, CFG_AGING_TIME, 0x1);
|
||||
hisi_sas_write32(hisi_hba, INT_COAL_EN, 0x1);
|
||||
hisi_sas_write32(hisi_hba, OQ_INT_COAL_TIME, 0x1);
|
||||
hisi_sas_write32(hisi_hba, OQ_INT_COAL_CNT, 0x1);
|
||||
hisi_sas_write32(hisi_hba, CFG_ICT_TIMER_STEP_TRSH, 0xf4240);
|
||||
hisi_sas_write32(hisi_hba, INT_COAL_EN, 0x3);
|
||||
/* configure the interrupt coalescing timeout period 10us */
|
||||
hisi_sas_write32(hisi_hba, OQ_INT_COAL_TIME, 0xa);
|
||||
/* configure the count of CQ entries 10 */
|
||||
hisi_sas_write32(hisi_hba, OQ_INT_COAL_CNT, 0xa);
|
||||
hisi_sas_write32(hisi_hba, CQ_INT_CONVERGE_EN,
|
||||
hisi_sas_intr_conv);
|
||||
hisi_sas_write32(hisi_hba, OQ_INT_SRC, 0xffff);
|
||||
|
|
@ -682,7 +686,7 @@ static void init_reg_v3_hw(struct hisi_hba *hisi_hba)
|
|||
hisi_sas_phy_write32(hisi_hba, i, PHY_CTRL_RDY_MSK, 0x0);
|
||||
hisi_sas_phy_write32(hisi_hba, i, PHYCTRL_DWS_RESET_MSK, 0x0);
|
||||
hisi_sas_phy_write32(hisi_hba, i, PHYCTRL_OOB_RESTART_MSK, 0x1);
|
||||
hisi_sas_phy_write32(hisi_hba, i, STP_LINK_TIMER, 0x7f7a120);
|
||||
hisi_sas_phy_write32(hisi_hba, i, STP_LINK_TIMER, 0x7ffffff);
|
||||
hisi_sas_phy_write32(hisi_hba, i, CON_CFG_DRIVER, 0x2a0a01);
|
||||
hisi_sas_phy_write32(hisi_hba, i, SAS_EC_INT_COAL_TIME,
|
||||
0x30f4240);
|
||||
|
|
@ -2493,6 +2497,7 @@ static int complete_v3_hw(struct hisi_sas_cq *cq)
|
|||
/* update rd_point */
|
||||
cq->rd_point = rd_point;
|
||||
hisi_sas_write32(hisi_hba, COMPL_Q_0_RD_PTR + (0x14 * queue), rd_point);
|
||||
cond_resched();
|
||||
|
||||
return completed;
|
||||
}
|
||||
|
|
@ -2796,14 +2801,15 @@ static void config_intr_coal_v3_hw(struct hisi_hba *hisi_hba)
|
|||
{
|
||||
/* config those registers between enable and disable PHYs */
|
||||
hisi_sas_stop_phys(hisi_hba);
|
||||
hisi_sas_write32(hisi_hba, INT_COAL_EN, 0x3);
|
||||
|
||||
if (hisi_hba->intr_coal_ticks == 0 ||
|
||||
hisi_hba->intr_coal_count == 0) {
|
||||
hisi_sas_write32(hisi_hba, INT_COAL_EN, 0x1);
|
||||
hisi_sas_write32(hisi_hba, OQ_INT_COAL_TIME, 0x1);
|
||||
hisi_sas_write32(hisi_hba, OQ_INT_COAL_CNT, 0x1);
|
||||
/* configure the interrupt coalescing timeout period 10us */
|
||||
hisi_sas_write32(hisi_hba, OQ_INT_COAL_TIME, 0xa);
|
||||
/* configure the count of CQ entries 10 */
|
||||
hisi_sas_write32(hisi_hba, OQ_INT_COAL_CNT, 0xa);
|
||||
} else {
|
||||
hisi_sas_write32(hisi_hba, INT_COAL_EN, 0x3);
|
||||
hisi_sas_write32(hisi_hba, OQ_INT_COAL_TIME,
|
||||
hisi_hba->intr_coal_ticks);
|
||||
hisi_sas_write32(hisi_hba, OQ_INT_COAL_CNT,
|
||||
|
|
@ -3371,6 +3377,23 @@ static const struct hisi_sas_hw hisi_sas_v3_hw = {
|
|||
.debugfs_snapshot_regs = debugfs_snapshot_regs_v3_hw,
|
||||
};
|
||||
|
||||
static int check_fw_info_v3_hw(struct hisi_hba *hisi_hba)
|
||||
{
|
||||
struct device *dev = hisi_hba->dev;
|
||||
|
||||
if (hisi_hba->n_phy < 0 || hisi_hba->n_phy > 8) {
|
||||
dev_err(dev, "invalid phy number from FW\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (hisi_hba->queue_count < 0 || hisi_hba->queue_count > 16) {
|
||||
dev_err(dev, "invalid queue count from FW\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct Scsi_Host *
|
||||
hisi_sas_shost_alloc_pci(struct pci_dev *pdev)
|
||||
{
|
||||
|
|
@ -3401,6 +3424,9 @@ hisi_sas_shost_alloc_pci(struct pci_dev *pdev)
|
|||
if (hisi_sas_get_fw_info(hisi_hba) < 0)
|
||||
goto err_out;
|
||||
|
||||
if (check_fw_info_v3_hw(hisi_hba) < 0)
|
||||
goto err_out;
|
||||
|
||||
if (experimental_iopoll_q_cnt < 0 ||
|
||||
experimental_iopoll_q_cnt >= hisi_hba->queue_count)
|
||||
dev_err(dev, "iopoll queue count %d cannot exceed or equal 16, using default 0\n",
|
||||
|
|
@ -3550,6 +3576,11 @@ debugfs_to_reg_name_v3_hw(int off, int base_off,
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static bool debugfs_dump_is_generated_v3_hw(void *p)
|
||||
{
|
||||
return p ? true : false;
|
||||
}
|
||||
|
||||
static void debugfs_print_reg_v3_hw(u32 *regs_val, struct seq_file *s,
|
||||
const struct hisi_sas_debugfs_reg *reg)
|
||||
{
|
||||
|
|
@ -3575,6 +3606,9 @@ static int debugfs_global_v3_hw_show(struct seq_file *s, void *p)
|
|||
{
|
||||
struct hisi_sas_debugfs_regs *global = s->private;
|
||||
|
||||
if (!debugfs_dump_is_generated_v3_hw(global->data))
|
||||
return -EPERM;
|
||||
|
||||
debugfs_print_reg_v3_hw(global->data, s,
|
||||
&debugfs_global_reg);
|
||||
|
||||
|
|
@ -3586,6 +3620,9 @@ static int debugfs_axi_v3_hw_show(struct seq_file *s, void *p)
|
|||
{
|
||||
struct hisi_sas_debugfs_regs *axi = s->private;
|
||||
|
||||
if (!debugfs_dump_is_generated_v3_hw(axi->data))
|
||||
return -EPERM;
|
||||
|
||||
debugfs_print_reg_v3_hw(axi->data, s,
|
||||
&debugfs_axi_reg);
|
||||
|
||||
|
|
@ -3597,6 +3634,9 @@ static int debugfs_ras_v3_hw_show(struct seq_file *s, void *p)
|
|||
{
|
||||
struct hisi_sas_debugfs_regs *ras = s->private;
|
||||
|
||||
if (!debugfs_dump_is_generated_v3_hw(ras->data))
|
||||
return -EPERM;
|
||||
|
||||
debugfs_print_reg_v3_hw(ras->data, s,
|
||||
&debugfs_ras_reg);
|
||||
|
||||
|
|
@ -3609,6 +3649,9 @@ static int debugfs_port_v3_hw_show(struct seq_file *s, void *p)
|
|||
struct hisi_sas_debugfs_port *port = s->private;
|
||||
const struct hisi_sas_debugfs_reg *reg_port = &debugfs_port_reg;
|
||||
|
||||
if (!debugfs_dump_is_generated_v3_hw(port->data))
|
||||
return -EPERM;
|
||||
|
||||
debugfs_print_reg_v3_hw(port->data, s, reg_port);
|
||||
|
||||
return 0;
|
||||
|
|
@ -3664,6 +3707,9 @@ static int debugfs_cq_v3_hw_show(struct seq_file *s, void *p)
|
|||
struct hisi_sas_debugfs_cq *debugfs_cq = s->private;
|
||||
int slot;
|
||||
|
||||
if (!debugfs_dump_is_generated_v3_hw(debugfs_cq->complete_hdr))
|
||||
return -EPERM;
|
||||
|
||||
for (slot = 0; slot < HISI_SAS_QUEUE_SLOTS; slot++)
|
||||
debugfs_cq_show_slot_v3_hw(s, slot, debugfs_cq);
|
||||
|
||||
|
|
@ -3685,8 +3731,12 @@ static void debugfs_dq_show_slot_v3_hw(struct seq_file *s, int slot,
|
|||
|
||||
static int debugfs_dq_v3_hw_show(struct seq_file *s, void *p)
|
||||
{
|
||||
struct hisi_sas_debugfs_dq *debugfs_dq = s->private;
|
||||
int slot;
|
||||
|
||||
if (!debugfs_dump_is_generated_v3_hw(debugfs_dq->hdr))
|
||||
return -EPERM;
|
||||
|
||||
for (slot = 0; slot < HISI_SAS_QUEUE_SLOTS; slot++)
|
||||
debugfs_dq_show_slot_v3_hw(s, slot, s->private);
|
||||
|
||||
|
|
@ -3700,6 +3750,9 @@ static int debugfs_iost_v3_hw_show(struct seq_file *s, void *p)
|
|||
struct hisi_sas_iost *iost = debugfs_iost->iost;
|
||||
int i, max_command_entries = HISI_SAS_MAX_COMMANDS;
|
||||
|
||||
if (!debugfs_dump_is_generated_v3_hw(iost))
|
||||
return -EPERM;
|
||||
|
||||
for (i = 0; i < max_command_entries; i++, iost++) {
|
||||
__le64 *data = &iost->qw0;
|
||||
|
||||
|
|
@ -3719,6 +3772,9 @@ static int debugfs_iost_cache_v3_hw_show(struct seq_file *s, void *p)
|
|||
int i, tab_idx;
|
||||
__le64 *iost;
|
||||
|
||||
if (!debugfs_dump_is_generated_v3_hw(iost_cache))
|
||||
return -EPERM;
|
||||
|
||||
for (i = 0; i < HISI_SAS_IOST_ITCT_CACHE_NUM; i++, iost_cache++) {
|
||||
/*
|
||||
* Data struct of IOST cache:
|
||||
|
|
@ -3742,6 +3798,9 @@ static int debugfs_itct_v3_hw_show(struct seq_file *s, void *p)
|
|||
struct hisi_sas_debugfs_itct *debugfs_itct = s->private;
|
||||
struct hisi_sas_itct *itct = debugfs_itct->itct;
|
||||
|
||||
if (!debugfs_dump_is_generated_v3_hw(itct))
|
||||
return -EPERM;
|
||||
|
||||
for (i = 0; i < HISI_SAS_MAX_ITCT_ENTRIES; i++, itct++) {
|
||||
__le64 *data = &itct->qw0;
|
||||
|
||||
|
|
@ -3761,6 +3820,9 @@ static int debugfs_itct_cache_v3_hw_show(struct seq_file *s, void *p)
|
|||
int i, tab_idx;
|
||||
__le64 *itct;
|
||||
|
||||
if (!debugfs_dump_is_generated_v3_hw(itct_cache))
|
||||
return -EPERM;
|
||||
|
||||
for (i = 0; i < HISI_SAS_IOST_ITCT_CACHE_NUM; i++, itct_cache++) {
|
||||
/*
|
||||
* Data struct of ITCT cache:
|
||||
|
|
@ -3778,10 +3840,9 @@ static int debugfs_itct_cache_v3_hw_show(struct seq_file *s, void *p)
|
|||
}
|
||||
DEFINE_SHOW_ATTRIBUTE(debugfs_itct_cache_v3_hw);
|
||||
|
||||
static void debugfs_create_files_v3_hw(struct hisi_hba *hisi_hba)
|
||||
static void debugfs_create_files_v3_hw(struct hisi_hba *hisi_hba, int index)
|
||||
{
|
||||
u64 *debugfs_timestamp;
|
||||
int dump_index = hisi_hba->debugfs_dump_index;
|
||||
struct dentry *dump_dentry;
|
||||
struct dentry *dentry;
|
||||
char name[256];
|
||||
|
|
@ -3789,17 +3850,17 @@ static void debugfs_create_files_v3_hw(struct hisi_hba *hisi_hba)
|
|||
int c;
|
||||
int d;
|
||||
|
||||
snprintf(name, 256, "%d", dump_index);
|
||||
snprintf(name, 256, "%d", index);
|
||||
|
||||
dump_dentry = debugfs_create_dir(name, hisi_hba->debugfs_dump_dentry);
|
||||
|
||||
debugfs_timestamp = &hisi_hba->debugfs_timestamp[dump_index];
|
||||
debugfs_timestamp = &hisi_hba->debugfs_timestamp[index];
|
||||
|
||||
debugfs_create_u64("timestamp", 0400, dump_dentry,
|
||||
debugfs_timestamp);
|
||||
|
||||
debugfs_create_file("global", 0400, dump_dentry,
|
||||
&hisi_hba->debugfs_regs[dump_index][DEBUGFS_GLOBAL],
|
||||
&hisi_hba->debugfs_regs[index][DEBUGFS_GLOBAL],
|
||||
&debugfs_global_v3_hw_fops);
|
||||
|
||||
/* Create port dir and files */
|
||||
|
|
@ -3808,7 +3869,7 @@ static void debugfs_create_files_v3_hw(struct hisi_hba *hisi_hba)
|
|||
snprintf(name, 256, "%d", p);
|
||||
|
||||
debugfs_create_file(name, 0400, dentry,
|
||||
&hisi_hba->debugfs_port_reg[dump_index][p],
|
||||
&hisi_hba->debugfs_port_reg[index][p],
|
||||
&debugfs_port_v3_hw_fops);
|
||||
}
|
||||
|
||||
|
|
@ -3818,7 +3879,7 @@ static void debugfs_create_files_v3_hw(struct hisi_hba *hisi_hba)
|
|||
snprintf(name, 256, "%d", c);
|
||||
|
||||
debugfs_create_file(name, 0400, dentry,
|
||||
&hisi_hba->debugfs_cq[dump_index][c],
|
||||
&hisi_hba->debugfs_cq[index][c],
|
||||
&debugfs_cq_v3_hw_fops);
|
||||
}
|
||||
|
||||
|
|
@ -3828,32 +3889,32 @@ static void debugfs_create_files_v3_hw(struct hisi_hba *hisi_hba)
|
|||
snprintf(name, 256, "%d", d);
|
||||
|
||||
debugfs_create_file(name, 0400, dentry,
|
||||
&hisi_hba->debugfs_dq[dump_index][d],
|
||||
&hisi_hba->debugfs_dq[index][d],
|
||||
&debugfs_dq_v3_hw_fops);
|
||||
}
|
||||
|
||||
debugfs_create_file("iost", 0400, dump_dentry,
|
||||
&hisi_hba->debugfs_iost[dump_index],
|
||||
&hisi_hba->debugfs_iost[index],
|
||||
&debugfs_iost_v3_hw_fops);
|
||||
|
||||
debugfs_create_file("iost_cache", 0400, dump_dentry,
|
||||
&hisi_hba->debugfs_iost_cache[dump_index],
|
||||
&hisi_hba->debugfs_iost_cache[index],
|
||||
&debugfs_iost_cache_v3_hw_fops);
|
||||
|
||||
debugfs_create_file("itct", 0400, dump_dentry,
|
||||
&hisi_hba->debugfs_itct[dump_index],
|
||||
&hisi_hba->debugfs_itct[index],
|
||||
&debugfs_itct_v3_hw_fops);
|
||||
|
||||
debugfs_create_file("itct_cache", 0400, dump_dentry,
|
||||
&hisi_hba->debugfs_itct_cache[dump_index],
|
||||
&hisi_hba->debugfs_itct_cache[index],
|
||||
&debugfs_itct_cache_v3_hw_fops);
|
||||
|
||||
debugfs_create_file("axi", 0400, dump_dentry,
|
||||
&hisi_hba->debugfs_regs[dump_index][DEBUGFS_AXI],
|
||||
&hisi_hba->debugfs_regs[index][DEBUGFS_AXI],
|
||||
&debugfs_axi_v3_hw_fops);
|
||||
|
||||
debugfs_create_file("ras", 0400, dump_dentry,
|
||||
&hisi_hba->debugfs_regs[dump_index][DEBUGFS_RAS],
|
||||
&hisi_hba->debugfs_regs[index][DEBUGFS_RAS],
|
||||
&debugfs_ras_v3_hw_fops);
|
||||
}
|
||||
|
||||
|
|
@ -4516,22 +4577,34 @@ static void debugfs_release_v3_hw(struct hisi_hba *hisi_hba, int dump_index)
|
|||
int i;
|
||||
|
||||
devm_kfree(dev, hisi_hba->debugfs_iost_cache[dump_index].cache);
|
||||
hisi_hba->debugfs_iost_cache[dump_index].cache = NULL;
|
||||
devm_kfree(dev, hisi_hba->debugfs_itct_cache[dump_index].cache);
|
||||
hisi_hba->debugfs_itct_cache[dump_index].cache = NULL;
|
||||
devm_kfree(dev, hisi_hba->debugfs_iost[dump_index].iost);
|
||||
hisi_hba->debugfs_iost[dump_index].iost = NULL;
|
||||
devm_kfree(dev, hisi_hba->debugfs_itct[dump_index].itct);
|
||||
hisi_hba->debugfs_itct[dump_index].itct = NULL;
|
||||
|
||||
for (i = 0; i < hisi_hba->queue_count; i++)
|
||||
for (i = 0; i < hisi_hba->queue_count; i++) {
|
||||
devm_kfree(dev, hisi_hba->debugfs_dq[dump_index][i].hdr);
|
||||
hisi_hba->debugfs_dq[dump_index][i].hdr = NULL;
|
||||
}
|
||||
|
||||
for (i = 0; i < hisi_hba->queue_count; i++)
|
||||
for (i = 0; i < hisi_hba->queue_count; i++) {
|
||||
devm_kfree(dev,
|
||||
hisi_hba->debugfs_cq[dump_index][i].complete_hdr);
|
||||
hisi_hba->debugfs_cq[dump_index][i].complete_hdr = NULL;
|
||||
}
|
||||
|
||||
for (i = 0; i < DEBUGFS_REGS_NUM; i++)
|
||||
for (i = 0; i < DEBUGFS_REGS_NUM; i++) {
|
||||
devm_kfree(dev, hisi_hba->debugfs_regs[dump_index][i].data);
|
||||
hisi_hba->debugfs_regs[dump_index][i].data = NULL;
|
||||
}
|
||||
|
||||
for (i = 0; i < hisi_hba->n_phy; i++)
|
||||
for (i = 0; i < hisi_hba->n_phy; i++) {
|
||||
devm_kfree(dev, hisi_hba->debugfs_port_reg[dump_index][i].data);
|
||||
hisi_hba->debugfs_port_reg[dump_index][i].data = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static const struct hisi_sas_debugfs_reg *debugfs_reg_array_v3_hw[DEBUGFS_REGS_NUM] = {
|
||||
|
|
@ -4658,8 +4731,6 @@ static int debugfs_snapshot_regs_v3_hw(struct hisi_hba *hisi_hba)
|
|||
debugfs_snapshot_itct_reg_v3_hw(hisi_hba);
|
||||
debugfs_snapshot_iost_reg_v3_hw(hisi_hba);
|
||||
|
||||
debugfs_create_files_v3_hw(hisi_hba);
|
||||
|
||||
debugfs_snapshot_restore_v3_hw(hisi_hba);
|
||||
hisi_hba->debugfs_dump_index++;
|
||||
|
||||
|
|
@ -4743,6 +4814,34 @@ static void debugfs_bist_init_v3_hw(struct hisi_hba *hisi_hba)
|
|||
hisi_hba->debugfs_bist_linkrate = SAS_LINK_RATE_1_5_GBPS;
|
||||
}
|
||||
|
||||
static int debugfs_dump_index_v3_hw_show(struct seq_file *s, void *p)
|
||||
{
|
||||
int *debugfs_dump_index = s->private;
|
||||
|
||||
if (*debugfs_dump_index > 0)
|
||||
seq_printf(s, "%d\n", *debugfs_dump_index - 1);
|
||||
else
|
||||
seq_puts(s, "dump not triggered\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
DEFINE_SHOW_ATTRIBUTE(debugfs_dump_index_v3_hw);
|
||||
|
||||
static void debugfs_dump_init_v3_hw(struct hisi_hba *hisi_hba)
|
||||
{
|
||||
int i;
|
||||
|
||||
hisi_hba->debugfs_dump_dentry =
|
||||
debugfs_create_dir("dump", hisi_hba->debugfs_dir);
|
||||
|
||||
debugfs_create_file("latest_dump", 0400, hisi_hba->debugfs_dump_dentry,
|
||||
&hisi_hba->debugfs_dump_index,
|
||||
&debugfs_dump_index_v3_hw_fops);
|
||||
|
||||
for (i = 0; i < hisi_sas_debugfs_dump_count; i++)
|
||||
debugfs_create_files_v3_hw(hisi_hba, i);
|
||||
}
|
||||
|
||||
static void debugfs_exit_v3_hw(struct hisi_hba *hisi_hba)
|
||||
{
|
||||
debugfs_remove_recursive(hisi_hba->debugfs_dir);
|
||||
|
|
@ -4755,19 +4854,17 @@ static void debugfs_init_v3_hw(struct hisi_hba *hisi_hba)
|
|||
|
||||
hisi_hba->debugfs_dir = debugfs_create_dir(dev_name(dev),
|
||||
hisi_sas_debugfs_dir);
|
||||
/* create bist structures */
|
||||
debugfs_bist_init_v3_hw(hisi_hba);
|
||||
|
||||
debugfs_dump_init_v3_hw(hisi_hba);
|
||||
|
||||
debugfs_phy_down_cnt_init_v3_hw(hisi_hba);
|
||||
debugfs_fifo_init_v3_hw(hisi_hba);
|
||||
debugfs_create_file("trigger_dump", 0200,
|
||||
hisi_hba->debugfs_dir,
|
||||
hisi_hba,
|
||||
&debugfs_trigger_dump_v3_hw_fops);
|
||||
|
||||
/* create bist structures */
|
||||
debugfs_bist_init_v3_hw(hisi_hba);
|
||||
|
||||
hisi_hba->debugfs_dump_dentry =
|
||||
debugfs_create_dir("dump", hisi_hba->debugfs_dir);
|
||||
|
||||
debugfs_phy_down_cnt_init_v3_hw(hisi_hba);
|
||||
debugfs_fifo_init_v3_hw(hisi_hba);
|
||||
}
|
||||
|
||||
static int
|
||||
|
|
@ -4860,16 +4957,13 @@ hisi_sas_v3_probe(struct pci_dev *pdev, const struct pci_device_id *id)
|
|||
SHOST_DIX_GUARD_CRC);
|
||||
}
|
||||
|
||||
if (hisi_sas_debugfs_enable)
|
||||
debugfs_init_v3_hw(hisi_hba);
|
||||
|
||||
rc = interrupt_preinit_v3_hw(hisi_hba);
|
||||
if (rc)
|
||||
goto err_out_undo_debugfs;
|
||||
goto err_out_free_host;
|
||||
|
||||
rc = scsi_add_host(shost, dev);
|
||||
if (rc)
|
||||
goto err_out_undo_debugfs;
|
||||
goto err_out_free_host;
|
||||
|
||||
rc = sas_register_ha(sha);
|
||||
if (rc)
|
||||
|
|
@ -4880,6 +4974,8 @@ hisi_sas_v3_probe(struct pci_dev *pdev, const struct pci_device_id *id)
|
|||
goto err_out_unregister_ha;
|
||||
|
||||
scsi_scan_host(shost);
|
||||
if (hisi_sas_debugfs_enable)
|
||||
debugfs_init_v3_hw(hisi_hba);
|
||||
|
||||
pm_runtime_set_autosuspend_delay(dev, 5000);
|
||||
pm_runtime_use_autosuspend(dev);
|
||||
|
|
@ -4900,9 +4996,6 @@ hisi_sas_v3_probe(struct pci_dev *pdev, const struct pci_device_id *id)
|
|||
sas_unregister_ha(sha);
|
||||
err_out_remove_host:
|
||||
scsi_remove_host(shost);
|
||||
err_out_undo_debugfs:
|
||||
if (hisi_sas_debugfs_enable)
|
||||
debugfs_exit_v3_hw(hisi_hba);
|
||||
err_out_free_host:
|
||||
hisi_sas_free(hisi_hba);
|
||||
scsi_host_put(shost);
|
||||
|
|
@ -4934,6 +5027,8 @@ static void hisi_sas_v3_remove(struct pci_dev *pdev)
|
|||
struct Scsi_Host *shost = sha->shost;
|
||||
|
||||
pm_runtime_get_noresume(dev);
|
||||
if (hisi_sas_debugfs_enable)
|
||||
debugfs_exit_v3_hw(hisi_hba);
|
||||
|
||||
sas_unregister_ha(sha);
|
||||
flush_workqueue(hisi_hba->wq);
|
||||
|
|
@ -4941,9 +5036,6 @@ static void hisi_sas_v3_remove(struct pci_dev *pdev)
|
|||
|
||||
hisi_sas_v3_destroy_irqs(pdev, hisi_hba);
|
||||
hisi_sas_free(hisi_hba);
|
||||
if (hisi_sas_debugfs_enable)
|
||||
debugfs_exit_v3_hw(hisi_hba);
|
||||
|
||||
scsi_host_put(shost);
|
||||
}
|
||||
|
||||
|
|
@ -5034,7 +5126,8 @@ static int _suspend_v3_hw(struct device *device)
|
|||
interrupt_disable_v3_hw(hisi_hba);
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
if (atomic_read(&device->power.usage_count)) {
|
||||
if ((device->power.runtime_status == RPM_SUSPENDING) &&
|
||||
atomic_read(&device->power.usage_count)) {
|
||||
dev_err(dev, "PM suspend: host status cannot be suspended\n");
|
||||
rc = -EBUSY;
|
||||
goto err_out;
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user