Merge mulgrave-w:git/scsi-misc-2.6
[linux-2.6-microblaze.git] / arch / ia64 / sn / kernel / xpc_partition.c
index 6bc0409..57c723f 100644 (file)
@@ -3,7 +3,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (c) 2004-2005 Silicon Graphics, Inc.  All Rights Reserved.
+ * Copyright (c) 2004-2006 Silicon Graphics, Inc.  All Rights Reserved.
  */
 
 
@@ -28,7 +28,7 @@
 #include <asm/sn/sn_sal.h>
 #include <asm/sn/nodepda.h>
 #include <asm/sn/addrs.h>
-#include "xpc.h"
+#include <asm/sn/xpc.h>
 
 
 /* XPC is exiting flag */
@@ -71,13 +71,34 @@ struct xpc_partition xpc_partitions[XP_MAX_PARTITIONS + 1];
  * Generic buffer used to store a local copy of portions of a remote
  * partition's reserved page (either its header and part_nasids mask,
  * or its vars).
- *
- * xpc_discovery runs only once and is a seperate thread that is
- * very likely going to be processing in parallel with receiving
- * interrupts.
  */
-char ____cacheline_aligned xpc_remote_copy_buffer[XPC_RP_HEADER_SIZE +
-                                                       XP_NASID_MASK_BYTES];
+char *xpc_remote_copy_buffer;
+void *xpc_remote_copy_buffer_base;
+
+
+/*
+ * Guarantee that the kmalloc'd memory is cacheline aligned.
+ */
+void *
+xpc_kmalloc_cacheline_aligned(size_t size, gfp_t flags, void **base)
+{
+       /* see if kmalloc will give us cachline aligned memory by default */
+       *base = kmalloc(size, flags);
+       if (*base == NULL) {
+               return NULL;
+       }
+       if ((u64) *base == L1_CACHE_ALIGN((u64) *base)) {
+               return *base;
+       }
+       kfree(*base);
+
+       /* nope, we'll have to do it ourselves */
+       *base = kmalloc(size + L1_CACHE_BYTES, flags);
+       if (*base == NULL) {
+               return NULL;
+       }
+       return (void *) L1_CACHE_ALIGN((u64) *base);
+}
 
 
 /*
@@ -111,9 +132,7 @@ xpc_get_rsvd_page_pa(int nasid)
                }
 
                if (L1_CACHE_ALIGN(len) > buf_len) {
-                       if (buf_base != NULL) {
-                               kfree(buf_base);
-                       }
+                       kfree(buf_base);
                        buf_len = L1_CACHE_ALIGN(len);
                        buf = (u64) xpc_kmalloc_cacheline_aligned(buf_len,
                                                        GFP_KERNEL, &buf_base);
@@ -125,7 +144,7 @@ xpc_get_rsvd_page_pa(int nasid)
                        }
                }
 
-               bte_res = xp_bte_copy(rp_pa, ia64_tpa(buf), buf_len,
+               bte_res = xp_bte_copy(rp_pa, buf, buf_len,
                                        (BTE_NOTIFY | BTE_WACQUIRE), NULL);
                if (bte_res != BTE_SUCCESS) {
                        dev_dbg(xpc_part, "xp_bte_copy failed %i\n", bte_res);
@@ -134,9 +153,7 @@ xpc_get_rsvd_page_pa(int nasid)
                }
        }
 
-       if (buf_base != NULL) {
-               kfree(buf_base);
-       }
+       kfree(buf_base);
 
        if (status != SALRET_OK) {
                rp_pa = 0;
@@ -426,7 +443,7 @@ xpc_check_remote_hb(void)
 
                /* pull the remote_hb cache line */
                bres = xp_bte_copy(part->remote_vars_pa,
-                                       ia64_tpa((u64) remote_vars),
+                                       (u64) remote_vars,
                                        XPC_RP_VARS_SIZE,
                                        (BTE_NOTIFY | BTE_WACQUIRE), NULL);
                if (bres != BTE_SUCCESS) {
@@ -477,8 +494,7 @@ xpc_get_remote_rp(int nasid, u64 *discovered_nasids,
 
 
        /* pull over the reserved page header and part_nasids mask */
-
-       bres = xp_bte_copy(*remote_rp_pa, ia64_tpa((u64) remote_rp),
+       bres = xp_bte_copy(*remote_rp_pa, (u64) remote_rp,
                                XPC_RP_HEADER_SIZE + xp_nasid_mask_bytes,
                                (BTE_NOTIFY | BTE_WACQUIRE), NULL);
        if (bres != BTE_SUCCESS) {
@@ -533,11 +549,8 @@ xpc_get_remote_vars(u64 remote_vars_pa, struct xpc_vars *remote_vars)
                return xpcVarsNotSet;
        }
 
-
        /* pull over the cross partition variables */
-
-       bres = xp_bte_copy(remote_vars_pa, ia64_tpa((u64) remote_vars),
-                               XPC_RP_VARS_SIZE,
+       bres = xp_bte_copy(remote_vars_pa, (u64) remote_vars, XPC_RP_VARS_SIZE,
                                (BTE_NOTIFY | BTE_WACQUIRE), NULL);
        if (bres != BTE_SUCCESS) {
                return xpc_map_bte_errors(bres);
@@ -1038,13 +1051,12 @@ xpc_discovery(void)
        remote_vars = (struct xpc_vars *) remote_rp;
 
 
-       discovered_nasids = kmalloc(sizeof(u64) * xp_nasid_mask_words,
+       discovered_nasids = kzalloc(sizeof(u64) * xp_nasid_mask_words,
                                                        GFP_KERNEL);
        if (discovered_nasids == NULL) {
                kfree(remote_rp_base);
                return;
        }
-       memset(discovered_nasids, 0, sizeof(u64) * xp_nasid_mask_words);
 
        rp = (struct xpc_rsvd_page *) xpc_rsvd_page;
 
@@ -1219,7 +1231,7 @@ xpc_initiate_partid_to_nasids(partid_t partid, void *nasid_mask)
 
        part_nasid_pa = (u64) XPC_RP_PART_NASIDS(part->remote_rp_pa);
 
-       bte_res = xp_bte_copy(part_nasid_pa, ia64_tpa((u64) nasid_mask),
+       bte_res = xp_bte_copy(part_nasid_pa, (u64) nasid_mask,
                        xp_nasid_mask_bytes, (BTE_NOTIFY | BTE_WACQUIRE), NULL);
 
        return xpc_map_bte_errors(bte_res);