aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/staging/rdma/hfi1/chip.c56
1 files changed, 56 insertions, 0 deletions
diff --git a/drivers/staging/rdma/hfi1/chip.c b/drivers/staging/rdma/hfi1/chip.c
index fe73ebf077e4..7799652773d5 100644
--- a/drivers/staging/rdma/hfi1/chip.c
+++ b/drivers/staging/rdma/hfi1/chip.c
@@ -13943,6 +13943,50 @@ static int obtain_boardname(struct hfi1_devdata *dd)
13943 return 0; 13943 return 0;
13944} 13944}
13945 13945
13946/*
13947 * Check the interrupt registers to make sure that they are mapped correctly.
13948 * It is intended to help user identify any mismapping by VMM when the driver
13949 * is running in a VM. This function should only be called before interrupt
13950 * is set up properly.
13951 *
13952 * Return 0 on success, -EINVAL on failure.
13953 */
13954static int check_int_registers(struct hfi1_devdata *dd)
13955{
13956 u64 reg;
13957 u64 all_bits = ~(u64)0;
13958 u64 mask;
13959
13960 /* Clear CceIntMask[0] to avoid raising any interrupts */
13961 mask = read_csr(dd, CCE_INT_MASK);
13962 write_csr(dd, CCE_INT_MASK, 0ull);
13963 reg = read_csr(dd, CCE_INT_MASK);
13964 if (reg)
13965 goto err_exit;
13966
13967 /* Clear all interrupt status bits */
13968 write_csr(dd, CCE_INT_CLEAR, all_bits);
13969 reg = read_csr(dd, CCE_INT_STATUS);
13970 if (reg)
13971 goto err_exit;
13972
13973 /* Set all interrupt status bits */
13974 write_csr(dd, CCE_INT_FORCE, all_bits);
13975 reg = read_csr(dd, CCE_INT_STATUS);
13976 if (reg != all_bits)
13977 goto err_exit;
13978
13979 /* Restore the interrupt mask */
13980 write_csr(dd, CCE_INT_CLEAR, all_bits);
13981 write_csr(dd, CCE_INT_MASK, mask);
13982
13983 return 0;
13984err_exit:
13985 write_csr(dd, CCE_INT_MASK, mask);
13986 dd_dev_err(dd, "Interrupt registers not properly mapped by VMM\n");
13987 return -EINVAL;
13988}
13989
13946/** 13990/**
13947 * Allocate and initialize the device structure for the hfi. 13991 * Allocate and initialize the device structure for the hfi.
13948 * @dev: the pci_dev for hfi1_ib device 13992 * @dev: the pci_dev for hfi1_ib device
@@ -13967,6 +14011,7 @@ struct hfi1_devdata *hfi1_init_dd(struct pci_dev *pdev,
13967 "RTL FPGA emulation", 14011 "RTL FPGA emulation",
13968 "Functional simulator" 14012 "Functional simulator"
13969 }; 14013 };
14014 struct pci_dev *parent = pdev->bus->self;
13970 14015
13971 dd = hfi1_alloc_devdata(pdev, NUM_IB_PORTS * 14016 dd = hfi1_alloc_devdata(pdev, NUM_IB_PORTS *
13972 sizeof(struct hfi1_pportdata)); 14017 sizeof(struct hfi1_pportdata));
@@ -14046,6 +14091,17 @@ struct hfi1_devdata *hfi1_init_dd(struct pci_dev *pdev,
14046 & CCE_REVISION_CHIP_REV_MINOR_MASK; 14091 & CCE_REVISION_CHIP_REV_MINOR_MASK;
14047 14092
14048 /* 14093 /*
14094 * Check interrupt registers mapping if the driver has no access to
14095 * the upstream component. In this case, it is likely that the driver
14096 * is running in a VM.
14097 */
14098 if (!parent) {
14099 ret = check_int_registers(dd);
14100 if (ret)
14101 goto bail_cleanup;
14102 }
14103
14104 /*
14049 * obtain the hardware ID - NOT related to unit, which is a 14105 * obtain the hardware ID - NOT related to unit, which is a
14050 * software enumeration 14106 * software enumeration
14051 */ 14107 */