Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 107052
b: refs/heads/master
c: bc63d38
h: refs/heads/master
v: v3
  • Loading branch information
Dean Nelson authored and Linus Torvalds committed Jul 30, 2008
1 parent c39946a commit b1a9955
Show file tree
Hide file tree
Showing 11 changed files with 267 additions and 152 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 78ce1bbe446e9b46dcd6c1e60a4768448a8ce355
refs/heads/master: bc63d387e4f5dbbe4ea0c5ade862c38073fd7fa3
3 changes: 2 additions & 1 deletion trunk/drivers/misc/sgi-xp/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@
#

obj-$(CONFIG_SGI_XP) += xp.o
xp-y := xp_main.o xp_nofault.o
xp-y := xp_main.o xp_uv.o
xp-$(CONFIG_IA64) += xp_sn2.o xp_nofault.o

obj-$(CONFIG_SGI_XP) += xpc.o
xpc-y := xpc_main.o xpc_channel.o xpc_partition.o
Expand Down
53 changes: 35 additions & 18 deletions trunk/drivers/misc/sgi-xp/xp.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@
#include <linux/mutex.h>
#include <asm/sn/types.h>
#include <asm/sn/bte.h>
#ifdef CONFIG_IA64
#include <asm/sn/arch.h>
#endif

/* >>> Add this #define to some linux header file some day. */
#define BYTES_PER_WORD sizeof(void *)
Expand Down Expand Up @@ -45,17 +48,18 @@
#endif

/*
* Define the maximum number of logically defined partitions the system
* can support. It is constrained by the maximum number of hardware
* partitionable regions. The term 'region' in this context refers to the
* minimum number of nodes that can comprise an access protection grouping.
* The access protection is in regards to memory, IPI and IOI.
* Define the maximum number of partitions the system can possibly support.
* It is based on the maximum number of hardware partitionable regions. The
* term 'region' in this context refers to the minimum number of nodes that
* can comprise an access protection grouping. The access protection is in
* regards to memory, IPI and IOI.
*
* The maximum number of hardware partitionable regions is equal to the
* maximum number of nodes in the entire system divided by the minimum number
* of nodes that comprise an access protection grouping.
*/
#define XP_MAX_PARTITIONS 64
#define XP_MAX_NPARTITIONS_SN2 64
#define XP_MAX_NPARTITIONS_UV 256

/*
* Define the number of u64s required to represent all the C-brick nasids
Expand Down Expand Up @@ -112,24 +116,28 @@ xp_bte_copy(u64 src, u64 vdst, u64 len, u64 mode, void *notification)
* other partition that is currently up. Over these channels, kernel-level
* `users' can communicate with their counterparts on the other partitions.
*
* The maxinum number of channels is limited to eight. For performance reasons,
* the internal cross partition structures require sixteen bytes per channel,
* and eight allows all of this interface-shared info to fit in one cache line.
>>> The following described limitation of a max of eight channels possible
>>> pertains only to ia64-sn2. THIS ISN'T TRUE SINCE I'M PLANNING TO JUST
>>> TIE INTO THE EXISTING MECHANISM ONCE THE CHANNEL MESSAGES ARE RECEIVED.
>>> THE 128-BYTE CACHELINE PERFORMANCE ISSUE IS TIED TO IA64-SN2.
*
* XPC_NCHANNELS reflects the total number of channels currently defined.
* If the need for additional channels arises, one can simply increase
* XPC_NCHANNELS accordingly. If the day should come where that number
* exceeds the MAXIMUM number of channels allowed (eight), then one will need
* to make changes to the XPC code to allow for this.
* XPC_MAX_NCHANNELS accordingly. If the day should come where that number
* exceeds the absolute MAXIMUM number of channels possible (eight), then one
* will need to make changes to the XPC code to accommodate for this.
*
* The absolute maximum number of channels possible is currently limited to
* eight for performance reasons. The internal cross partition structures
* require sixteen bytes per channel, and eight allows all of this
* interface-shared info to fit in one 128-byte cacheline.
*/
#define XPC_MEM_CHANNEL 0 /* memory channel number */
#define XPC_NET_CHANNEL 1 /* network channel number */

#define XPC_NCHANNELS 2 /* #of defined channels */
#define XPC_MAX_NCHANNELS 8 /* max #of channels allowed */
#define XPC_MAX_NCHANNELS 2 /* max #of channels allowed */

#if XPC_NCHANNELS > XPC_MAX_NCHANNELS
#error XPC_NCHANNELS exceeds MAXIMUM allowed.
#if XPC_MAX_NCHANNELS > 8
#error XPC_MAX_NCHANNELS exceeds absolute MAXIMUM possible.
#endif

/*
Expand Down Expand Up @@ -254,7 +262,8 @@ enum xp_retval {
xpBteCopyError, /* 52: bte_copy() returned error */
xpSalError, /* 53: sn SAL error */

xpUnknownReason /* 54: unknown reason - must be last in enum */
xpUnsupported, /* 54: unsupported functionality or resource */
xpUnknownReason /* 55: unknown reason - must be last in enum */
};

/*
Expand Down Expand Up @@ -397,8 +406,16 @@ xpc_partid_to_nasids(short partid, void *nasids)
return xpc_interface.partid_to_nasids(partid, nasids);
}

extern short xp_max_npartitions;

extern u64 xp_nofault_PIOR_target;
extern int xp_nofault_PIOR(void *);
extern int xp_error_PIOR(void);

extern struct device *xp;
extern enum xp_retval xp_init_sn2(void);
extern enum xp_retval xp_init_uv(void);
extern void xp_exit_sn2(void);
extern void xp_exit_uv(void);

#endif /* _DRIVERS_MISC_SGIXP_XP_H */
84 changes: 34 additions & 50 deletions trunk/drivers/misc/sgi-xp/xp_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,28 +15,32 @@
*/

#include <linux/kernel.h>
#include <linux/interrupt.h>
#include <linux/module.h>
#include <linux/mutex.h>
#include <asm/sn/intr.h>
#include <asm/sn/sn_sal.h>
#include <linux/device.h>
#include "xp.h"

/*
* The export of xp_nofault_PIOR needs to happen here since it is defined
* in drivers/misc/sgi-xp/xp_nofault.S. The target of the nofault read is
* defined here.
*/
EXPORT_SYMBOL_GPL(xp_nofault_PIOR);
/* define the XP debug device structures to be used with dev_dbg() et al */

u64 xp_nofault_PIOR_target;
EXPORT_SYMBOL_GPL(xp_nofault_PIOR_target);
struct device_driver xp_dbg_name = {
.name = "xp"
};

struct device xp_dbg_subname = {
.bus_id = {0}, /* set to "" */
.driver = &xp_dbg_name
};

struct device *xp = &xp_dbg_subname;

/* max #of partitions possible */
short xp_max_npartitions;
EXPORT_SYMBOL_GPL(xp_max_npartitions);

/*
* xpc_registrations[] keeps track of xpc_connect()'s done by the kernel-level
* users of XPC.
*/
struct xpc_registration xpc_registrations[XPC_NCHANNELS];
struct xpc_registration xpc_registrations[XPC_MAX_NCHANNELS];
EXPORT_SYMBOL_GPL(xpc_registrations);

/*
Expand Down Expand Up @@ -135,7 +139,7 @@ xpc_connect(int ch_number, xpc_channel_func func, void *key, u16 payload_size,
{
struct xpc_registration *registration;

DBUG_ON(ch_number < 0 || ch_number >= XPC_NCHANNELS);
DBUG_ON(ch_number < 0 || ch_number >= XPC_MAX_NCHANNELS);
DBUG_ON(payload_size == 0 || nentries == 0);
DBUG_ON(func == NULL);
DBUG_ON(assigned_limit == 0 || idle_limit > assigned_limit);
Expand Down Expand Up @@ -185,7 +189,7 @@ xpc_disconnect(int ch_number)
{
struct xpc_registration *registration;

DBUG_ON(ch_number < 0 || ch_number >= XPC_NCHANNELS);
DBUG_ON(ch_number < 0 || ch_number >= XPC_MAX_NCHANNELS);

registration = &xpc_registrations[ch_number];

Expand Down Expand Up @@ -221,39 +225,21 @@ EXPORT_SYMBOL_GPL(xpc_disconnect);
int __init
xp_init(void)
{
int ret, ch_number;
u64 func_addr = *(u64 *)xp_nofault_PIOR;
u64 err_func_addr = *(u64 *)xp_error_PIOR;

if (!ia64_platform_is("sn2"))
return -ENODEV;
enum xp_retval ret;
int ch_number;

/*
* Register a nofault code region which performs a cross-partition
* PIO read. If the PIO read times out, the MCA handler will consume
* the error and return to a kernel-provided instruction to indicate
* an error. This PIO read exists because it is guaranteed to timeout
* if the destination is down (AMO operations do not timeout on at
* least some CPUs on Shubs <= v1.2, which unfortunately we have to
* work around).
*/
ret = sn_register_nofault_code(func_addr, err_func_addr, err_func_addr,
1, 1);
if (ret != 0) {
printk(KERN_ERR "XP: can't register nofault code, error=%d\n",
ret);
}
/*
* Setup the nofault PIO read target. (There is no special reason why
* SH_IPI_ACCESS was selected.)
*/
if (is_shub2())
xp_nofault_PIOR_target = SH2_IPI_ACCESS0;
if (is_shub())
ret = xp_init_sn2();
else if (is_uv())
ret = xp_init_uv();
else
xp_nofault_PIOR_target = SH1_IPI_ACCESS;
ret = xpUnsupported;

if (ret != xpSuccess)
return -ENODEV;

/* initialize the connection registration mutex */
for (ch_number = 0; ch_number < XPC_NCHANNELS; ch_number++)
for (ch_number = 0; ch_number < XPC_MAX_NCHANNELS; ch_number++)
mutex_init(&xpc_registrations[ch_number].mutex);

return 0;
Expand All @@ -264,12 +250,10 @@ module_init(xp_init);
void __exit
xp_exit(void)
{
u64 func_addr = *(u64 *)xp_nofault_PIOR;
u64 err_func_addr = *(u64 *)xp_error_PIOR;

/* unregister the PIO read nofault code region */
(void)sn_register_nofault_code(func_addr, err_func_addr,
err_func_addr, 1, 0);
if (is_shub())
xp_exit_sn2();
else if (is_uv())
xp_exit_uv();
}

module_exit(xp_exit);
Expand Down
92 changes: 92 additions & 0 deletions trunk/drivers/misc/sgi-xp/xp_sn2.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
/*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file "COPYING" in the main directory of this archive
* for more details.
*
* Copyright (c) 2008 Silicon Graphics, Inc. All Rights Reserved.
*/

/*
* Cross Partition (XP) sn2-based functions.
*
* Architecture specific implementation of common functions.
*/

#include <linux/device.h>
#include <asm/sn/sn_sal.h>
#include "xp.h"

/*
* The export of xp_nofault_PIOR needs to happen here since it is defined
* in drivers/misc/sgi-xp/xp_nofault.S. The target of the nofault read is
* defined here.
*/
EXPORT_SYMBOL_GPL(xp_nofault_PIOR);

u64 xp_nofault_PIOR_target;
EXPORT_SYMBOL_GPL(xp_nofault_PIOR_target);

/*
* Register a nofault code region which performs a cross-partition PIO read.
* If the PIO read times out, the MCA handler will consume the error and
* return to a kernel-provided instruction to indicate an error. This PIO read
* exists because it is guaranteed to timeout if the destination is down
* (AMO operations do not timeout on at least some CPUs on Shubs <= v1.2,
* which unfortunately we have to work around).
*/
static enum xp_retval
xp_register_nofault_code_sn2(void)
{
int ret;
u64 func_addr;
u64 err_func_addr;

func_addr = *(u64 *)xp_nofault_PIOR;
err_func_addr = *(u64 *)xp_error_PIOR;
ret = sn_register_nofault_code(func_addr, err_func_addr, err_func_addr,
1, 1);
if (ret != 0) {
dev_err(xp, "can't register nofault code, error=%d\n", ret);
return xpSalError;
}
/*
* Setup the nofault PIO read target. (There is no special reason why
* SH_IPI_ACCESS was selected.)
*/
if (is_shub1())
xp_nofault_PIOR_target = SH1_IPI_ACCESS;
else if (is_shub2())
xp_nofault_PIOR_target = SH2_IPI_ACCESS0;

return xpSuccess;
}

void
xp_unregister_nofault_code_sn2(void)
{
u64 func_addr = *(u64 *)xp_nofault_PIOR;
u64 err_func_addr = *(u64 *)xp_error_PIOR;

/* unregister the PIO read nofault code region */
(void)sn_register_nofault_code(func_addr, err_func_addr,
err_func_addr, 1, 0);
}

enum xp_retval
xp_init_sn2(void)
{
BUG_ON(!is_shub());

xp_max_npartitions = XP_MAX_NPARTITIONS_SN2;

return xp_register_nofault_code_sn2();
}

void
xp_exit_sn2(void)
{
BUG_ON(!is_shub());

xp_unregister_nofault_code_sn2();
}

30 changes: 30 additions & 0 deletions trunk/drivers/misc/sgi-xp/xp_uv.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file "COPYING" in the main directory of this archive
* for more details.
*
* Copyright (c) 2008 Silicon Graphics, Inc. All Rights Reserved.
*/

/*
* Cross Partition (XP) uv-based functions.
*
* Architecture specific implementation of common functions.
*
*/

#include "xp.h"

enum xp_retval
xp_init_uv(void)
{
BUG_ON(!is_uv());

xp_max_npartitions = XP_MAX_NPARTITIONS_UV;
}

void
xp_exit_uv(void)
{
BUG_ON(!is_uv());
}
Loading

0 comments on commit b1a9955

Please sign in to comment.