Open tmakatos opened 3 years ago
Side note: PCI_CAP_ID_HT is another cap that can have multiple instances
An example of the device needing a callback for a vendor cap:
21 #define vsc_read(dev, offset, val) \
22 pci_read_config_dword((dev)->pdev, (dev)->vsc_addr + (offset), (val))
58 dev->vsc_addr = pci_find_capability(dev->pdev,
59 PCI_CAP_ID_VNDR);
64 int mlx5_vsc_gw_lock(struct mlx5_core_dev *dev)
65 {
66 u32 counter = 0;
67 int retries = 0;
68 u32 lock_val;
69 int ret;
70
71 pci_cfg_access_lock(dev->pdev);
72 do {
73 if (retries > VSC_MAX_RETRIES) {
74 ret = -EBUSY;
75 goto pci_unlock;
76 }
77
78 /* Check if semaphore is already locked */
79 ret = vsc_read(dev, VSC_SEMAPHORE_OFFSET, &lock_val);
80 if (ret)
81 goto pci_unlock;
82
83 if (lock_val) {
84 retries++;
85 usleep_range(1000, 2000);
86 continue;
87 }
88
89 /* Read and write counter value, if written value is
90 * the same, semaphore was acquired successfully.
91 */
92 ret = vsc_read(dev, VSC_COUNTER_OFFSET, &counter);
93 if (ret)
94 goto pci_unlock;
95
96 ret = vsc_write(dev, VSC_SEMAPHORE_OFFSET, counter);
97 if (ret)
98 goto pci_unlock;
99
100 ret = vsc_read(dev, VSC_SEMAPHORE_OFFSET, &lock_val);
101 if (ret)
102 goto pci_unlock;
103
104 retries++;
105 } while (counter != lock_val);
106
107 return 0;
108
109 pci_unlock:
110 pci_cfg_access_unlock(dev->pdev);
111 return ret;
112 }
Progress on this based on our current understanding:
Here's a list of questions we need to answer in order to properly implement capabilities:
This might not be in the spec, QEMU might be a good place to start.