diff --git a/drivers/net/ethernet/huawei/hinic/hinic_dbgtool_knl.c b/drivers/net/ethernet/huawei/hinic/hinic_dbgtool_knl.c index f65892c6273fec6640ac9d518092f3c5ab7c85c3..96fb8db6665657915dfabdd59456a158753ac6c0 100644 --- a/drivers/net/ethernet/huawei/hinic/hinic_dbgtool_knl.c +++ b/drivers/net/ethernet/huawei/hinic/hinic_dbgtool_knl.c @@ -56,6 +56,10 @@ u64 g_card_phy_addr[MAX_CARD_NUM] = {0}; /* lock for g_card_vir_addr */ struct mutex g_addr_lock; int card_id; +unsigned long card_id_flag; +enum hinic_card_id_status { + HINIC_CARD_ID_USE = BIT(0), +}; /* dbgtool character device name, class name, dev path*/ #define CHR_DEV_DBGTOOL "dbgtool_chr_dev" @@ -125,18 +129,20 @@ int hinic_mem_mmap(struct file *filp, struct vm_area_struct *vma) if (vmsize > (PAGE_SIZE * (1 << DBGTOOL_PAGE_ORDER))) { pr_err("Map size = %lu is bigger than alloc\n", vmsize); + clear_bit(HINIC_CARD_ID_USE, &card_id_flag); return -EAGAIN; } if (offset && !is_valid_phy_addr((u64)offset) && !hinic_is_valid_bar_addr((u64)offset)) { pr_err("offset is invalid\n"); + clear_bit(HINIC_CARD_ID_USE, &card_id_flag); return -EAGAIN; } /* old version of tool set vma->vm_pgoff to 0 */ phy_addr = offset ? offset : g_card_phy_addr[card_id]; - + clear_bit(HINIC_CARD_ID_USE, &card_id_flag); if (!phy_addr) { pr_err("Card_id = %d physical address is 0\n", card_id); return -EAGAIN; @@ -551,7 +557,7 @@ long dbgtool_knl_unlocked_ioctl(struct file *pfile, struct dbgtool_param param; struct dbgtool_k_glb_info *dbgtool_info; struct card_node *card_info = NULL; - int i; + int i, cnt = 0; (void)memset(¶m, 0, sizeof(param)); @@ -573,7 +579,22 @@ long dbgtool_knl_unlocked_ioctl(struct file *pfile, pr_err("Can't find this card %s\n", param.chip_name); return -EFAULT; } - card_id = i; + + while (cnt < 10) { + if (!test_and_set_bit(HINIC_CARD_ID_USE, &card_id_flag)) + break; + usleep_range(500, 1000); + cnt++; + } + + if (cnt < 10) { + card_id = i; + } else { + pr_err("Card id in using!\n"); + clear_bit(HINIC_CARD_ID_USE, &card_id_flag); + return -EFAULT; + } + dbgtool_info = (struct dbgtool_k_glb_info *)card_info->dbgtool_info; down(&dbgtool_info->dbgtool_sem);