Commit 96758117 authored by Luo bin's avatar Luo bin Committed by David S. Miller
Browse files

hinic: fix a bug of waitting for IO stopped



it's unreliable for fw to check whether IO is stopped, so driver
wait for enough time to ensure IO process is done in hw before
freeing resources

Signed-off-by: default avatarLuo bin <luobin9@huawei.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 07f8e4d0
Loading
Loading
Loading
Loading
+2 −49
Original line number Diff line number Diff line
@@ -360,50 +360,6 @@ static int wait_for_db_state(struct hinic_hwdev *hwdev)
	return -EFAULT;
}

static int wait_for_io_stopped(struct hinic_hwdev *hwdev)
{
	struct hinic_cmd_io_status cmd_io_status;
	struct hinic_hwif *hwif = hwdev->hwif;
	struct pci_dev *pdev = hwif->pdev;
	struct hinic_pfhwdev *pfhwdev;
	unsigned long end;
	u16 out_size;
	int err;

	if (!HINIC_IS_PF(hwif) && !HINIC_IS_PPF(hwif)) {
		dev_err(&pdev->dev, "Unsupported PCI Function type\n");
		return -EINVAL;
	}

	pfhwdev = container_of(hwdev, struct hinic_pfhwdev, hwdev);

	cmd_io_status.func_idx = HINIC_HWIF_FUNC_IDX(hwif);

	end = jiffies + msecs_to_jiffies(IO_STATUS_TIMEOUT);
	do {
		err = hinic_msg_to_mgmt(&pfhwdev->pf_to_mgmt, HINIC_MOD_COMM,
					HINIC_COMM_CMD_IO_STATUS_GET,
					&cmd_io_status, sizeof(cmd_io_status),
					&cmd_io_status, &out_size,
					HINIC_MGMT_MSG_SYNC);
		if ((err) || (out_size != sizeof(cmd_io_status))) {
			dev_err(&pdev->dev, "Failed to get IO status, ret = %d\n",
				err);
			return err;
		}

		if (cmd_io_status.status == IO_STOPPED) {
			dev_info(&pdev->dev, "IO stopped\n");
			return 0;
		}

		msleep(20);
	} while (time_before(jiffies, end));

	dev_err(&pdev->dev, "Wait for IO stopped - Timeout\n");
	return -ETIMEDOUT;
}

/**
 * clear_io_resource - set the IO resources as not active in the NIC
 * @hwdev: the NIC HW device
@@ -423,11 +379,8 @@ static int clear_io_resources(struct hinic_hwdev *hwdev)
		return -EINVAL;
	}

	err = wait_for_io_stopped(hwdev);
	if (err) {
		dev_err(&pdev->dev, "IO has not stopped yet\n");
		return err;
	}
	/* sleep 100ms to wait for firmware stopping I/O */
	msleep(100);

	cmd_clear_io_res.func_idx = HINIC_HWIF_FUNC_IDX(hwif);