[MTHCA] improve the time of handling events like port state change
[mirror/winof/.git] / hw / mthca / kernel / mthca_provider.c
index c5ed497..2d20462 100644 (file)
@@ -216,8 +216,8 @@ out:
        return err;
 }
 
-int mthca_query_pkey(struct ib_device *ibdev,
-                           u8 port, u16 index, u16 *pkey)
+int mthca_query_pkey_chunk(struct ib_device *ibdev,
+                           u8 port, u16 index, u16 pkey[32])
 {
        struct ib_smp *in_mad  = NULL;
        struct ib_smp *out_mad = NULL;
@@ -243,7 +243,12 @@ int mthca_query_pkey(struct ib_device *ibdev,
                goto out;
        }
 
-       *pkey = cl_ntoh16(((__be16 *) out_mad->data)[index % 32]);
+       { // copy the results
+               int i;
+               __be16 *pkey_chunk = (__be16 *)out_mad->data;
+               for (i=0; i<32; ++i) 
+                       pkey[i] = cl_ntoh16(pkey_chunk[i]);
+       }
 
  out:
        kfree(in_mad);
@@ -251,13 +256,14 @@ int mthca_query_pkey(struct ib_device *ibdev,
        return err;
 }
 
-int mthca_query_gid(struct ib_device *ibdev, u8 port,
-                          int index, union ib_gid *gid)
+int mthca_query_gid_chunk(struct ib_device *ibdev, u8 port,
+                          int index, union ib_gid gid[8])
 {
        struct ib_smp *in_mad  = NULL;
        struct ib_smp *out_mad = NULL;
        int err = -ENOMEM;
        u8 status;
+       __be64  subnet_prefix;
 
        in_mad  = kzalloc(sizeof *in_mad, GFP_KERNEL);
        out_mad = kmalloc(sizeof *out_mad, GFP_KERNEL);
@@ -278,7 +284,7 @@ int mthca_query_gid(struct ib_device *ibdev, u8 port,
                goto out;
        }
 
-       memcpy(gid->raw, out_mad->data + 8, 8);
+       memcpy(&subnet_prefix, out_mad->data + 8, 8);
 
        init_query_mad(in_mad);
        in_mad->attr_id  = IB_SMP_ATTR_GUID_INFO;
@@ -294,7 +300,14 @@ int mthca_query_gid(struct ib_device *ibdev, u8 port,
                goto out;
        }
 
-       memcpy(gid->raw + 8, out_mad->data + (index % 8) * 16, 8);
+       { // copy the results
+               int i;
+               __be64 *guid = (__be64 *)out_mad->data;
+               for (i=0; i<8; ++i) {
+                       gid[i].global.subnet_prefix = subnet_prefix;
+                       gid[i].global.interface_id = guid[i];
+               }
+       }
 
  out:
        kfree(in_mad);
@@ -1169,8 +1182,8 @@ int mthca_register_device(struct mthca_dev *dev)
        dev->ib_dev.query_device         = mthca_query_device;
        dev->ib_dev.query_port           = mthca_query_port;
        dev->ib_dev.modify_port          = mthca_modify_port;
-       dev->ib_dev.query_pkey           = mthca_query_pkey;
-       dev->ib_dev.query_gid            = mthca_query_gid;
+       dev->ib_dev.query_pkey_chunk           = mthca_query_pkey_chunk;
+       dev->ib_dev.query_gid_chunk            = mthca_query_gid_chunk;
        dev->ib_dev.alloc_ucontext       = mthca_alloc_ucontext;
        dev->ib_dev.dealloc_ucontext     = mthca_dealloc_ucontext;
        dev->ib_dev.alloc_pd             = mthca_alloc_pd;