IB/hfi1: Guard against concurrent I2C access across all chains
authorDean Luick <dean.luick@intel.com>
Tue, 12 Apr 2016 18:26:21 +0000 (11:26 -0700)
committerDoug Ledford <dledford@redhat.com>
Thu, 28 Apr 2016 20:32:28 +0000 (16:32 -0400)
The discrete ASIC board design makes the two I2C chains not
independent of each other.  That is, only one chain can safely
be accessed at a time.  For discrete ASIC devices, adjust the
resource locking so that access to one I2C chain will lock both
of the chains.

Reviewed-by: Easwar Hariharan <easwar.hariharan@intel.com>
Signed-off-by: Dean Luick <dean.luick@intel.com>
Signed-off-by: Doug Ledford <dledford@redhat.com>
drivers/staging/rdma/hfi1/firmware.c

index 3040162cb3260828d3f0f9451232494489ab744b..ed680fda611dfdcee292e2613ee6e2d13fdfd891 100644 (file)
@@ -1413,8 +1413,15 @@ static int __acquire_chip_resource(struct hfi1_devdata *dd, u32 resource)
 
        if (resource & CR_DYN_MASK) {
                /* a dynamic resource is in use if either HFI has set the bit */
-               all_bits = resource_mask(0, resource) |
+               if (dd->pcidev->device == PCI_DEVICE_ID_INTEL0 &&
+                   (resource & (CR_I2C1 | CR_I2C2))) {
+                       /* discrete devices must serialize across both chains */
+                       all_bits = resource_mask(0, CR_I2C1 | CR_I2C2) |
+                                       resource_mask(1, CR_I2C1 | CR_I2C2);
+               } else {
+                       all_bits = resource_mask(0, resource) |
                                                resource_mask(1, resource);
+               }
                my_bit = resource_mask(dd->hfi1_id, resource);
        } else {
                /* non-dynamic resources are not split between HFIs */