[HW] allow retrieving CA attributes with pageable memory
[mirror/winof/.git] / hw / mlx4 / kernel / bus / core / cache.c
index 75da405..382c658 100644 (file)
@@ -80,9 +80,9 @@ int ib_get_cached_gid(struct ib_device *device,
                      int               index,
                      union ib_gid     *gid)
 {
+       union ib_gid cgid;
        struct ib_gid_cache *cache;
        unsigned long flags;
-       int ret = 0;
 
        if (mlx4_is_barred(device->dma_device))
                return -EFAULT;
@@ -94,14 +94,16 @@ int ib_get_cached_gid(struct ib_device *device,
 
        cache = device->cache.gid_cache[port_num - start_port(device)];
 
-       if (index < 0 || index >= cache->table_len)
-               ret = -EINVAL;
-       else
-               *gid = cache->table[index];
-
+       if (index < 0 || index >= cache->table_len) {
+               read_unlock_irqrestore(&device->cache.lock, flags);
+               return -EINVAL;
+       }
+       
+       cgid = cache->table[index];
        read_unlock_irqrestore(&device->cache.lock, flags);
+       *gid = cgid;
 
-       return ret;
+       return 0;
 }
 EXPORT_SYMBOL(ib_get_cached_gid);
 
@@ -113,33 +115,34 @@ int ib_find_cached_gid(struct ib_device *device,
        struct ib_gid_cache *cache;
        unsigned long flags;
        int p, i;
-       int ret = -ENOENT;
 
        if (mlx4_is_barred(device->dma_device))
                return -EFAULT;
 
-       *port_num = (u8)-1;
-       if (index)
-               *index = (u16)-1;
-
        read_lock_irqsave(&device->cache.lock, &flags);
 
        for (p = 0; p <= end_port(device) - start_port(device); ++p) {
                cache = device->cache.gid_cache[p];
                for (i = 0; i < cache->table_len; ++i) {
                        if (!memcmp(gid, &cache->table[i], sizeof *gid)) {
-                               *port_num = (u8)(p + start_port(device));
-                               if (index)
-                                       *index = (u16)i;
-                               ret = 0;
                                goto found;
                        }
                }
        }
+
+       read_unlock_irqrestore(&device->cache.lock, flags);
+       *port_num = (u8)-1;
+       if (index)
+               *index = (u16)-1;
+       return -ENOENT;
+
 found:
        read_unlock_irqrestore(&device->cache.lock, flags);
+       *port_num = (u8)(p + start_port(device));
+       if (index)
+               *index = (u16)i;
 
-       return ret;
+       return 0;
 }
 EXPORT_SYMBOL(ib_find_cached_gid);
 
@@ -149,8 +152,8 @@ int ib_get_cached_pkey(struct ib_device *device,
                       __be16           *pkey)
 {
        struct ib_pkey_cache *cache;
+       __be16 cpkey;
        unsigned long flags;
-       int ret = 0;
 
        if (mlx4_is_barred(device->dma_device))
                return -EFAULT;
@@ -162,14 +165,16 @@ int ib_get_cached_pkey(struct ib_device *device,
 
        cache = device->cache.pkey_cache[port_num - start_port(device)];
 
-       if (index < 0 || index >= cache->table_len)
-               ret = -EINVAL;
-       else
-               *pkey = cache->table[index];
+       if (index < 0 || index >= cache->table_len) {
+               read_unlock_irqrestore(&device->cache.lock, flags);
+               return -EINVAL;
+       }
 
+       cpkey = cache->table[index];
        read_unlock_irqrestore(&device->cache.lock, flags);
+       *pkey = cpkey;
 
-       return ret;
+       return 0;
 }
 EXPORT_SYMBOL(ib_get_cached_pkey);
 
@@ -181,7 +186,6 @@ int ib_find_cached_pkey(struct ib_device *device,
        struct ib_pkey_cache *cache;
        unsigned long flags;
        int i;
-       int ret = -ENOENT;
 
        if (mlx4_is_barred(device->dma_device))
                return -EFAULT;
@@ -197,14 +201,17 @@ int ib_find_cached_pkey(struct ib_device *device,
 
        for (i = 0; i < cache->table_len; ++i)
                if ((cache->table[i] & 0x7fff) == (pkey & 0x7fff)) {
-                       *index = (u16)i;
-                       ret = 0;
-                       break;
+                       goto found;
                }
 
        read_unlock_irqrestore(&device->cache.lock, flags);
+       *index = (u16)-1;
+       return -ENOENT;
 
-       return ret;
+found:
+       read_unlock_irqrestore(&device->cache.lock, flags);
+       *index = (u16)i;
+       return 0;
 }
 EXPORT_SYMBOL(ib_find_cached_pkey);
 
@@ -213,14 +220,16 @@ int ib_get_cached_lmc(struct ib_device *device,
                      u8                *lmc)
 {
        unsigned long flags;
+       u8 clmc;
        int ret = 0;
 
        if (port_num < start_port(device) || port_num > end_port(device))
                return -EINVAL;
 
        read_lock_irqsave(&device->cache.lock, &flags);
-       *lmc = device->cache.lmc_cache[port_num - start_port(device)];
+       clmc = device->cache.lmc_cache[port_num - start_port(device)];
        read_unlock_irqrestore(&device->cache.lock, flags);
+       *lmc = clmc;
 
        return ret;
 }