diff options
Diffstat (limited to 'drivers/misc/sgi-xp')
-rw-r--r-- | drivers/misc/sgi-xp/xp.h | 7 | ||||
-rw-r--r-- | drivers/misc/sgi-xp/xp_main.c | 9 | ||||
-rw-r--r-- | drivers/misc/sgi-xp/xp_sn2.c | 34 | ||||
-rw-r--r-- | drivers/misc/sgi-xp/xp_uv.c | 70 | ||||
-rw-r--r-- | drivers/misc/sgi-xp/xpc.h | 12 | ||||
-rw-r--r-- | drivers/misc/sgi-xp/xpc_main.c | 8 | ||||
-rw-r--r-- | drivers/misc/sgi-xp/xpc_sn2.c | 17 | ||||
-rw-r--r-- | drivers/misc/sgi-xp/xpc_uv.c | 290 | ||||
-rw-r--r-- | drivers/misc/sgi-xp/xpnet.c | 75 |
9 files changed, 392 insertions, 130 deletions
diff --git a/drivers/misc/sgi-xp/xp.h b/drivers/misc/sgi-xp/xp.h index ed1722e5004..7b4cbd5e03e 100644 --- a/drivers/misc/sgi-xp/xp.h +++ b/drivers/misc/sgi-xp/xp.h @@ -194,9 +194,10 @@ enum xp_retval { xpGruSendMqError, /* 59: gru send message queue related error */ xpBadChannelNumber, /* 60: invalid channel number */ - xpBadMsgType, /* 60: invalid message type */ + xpBadMsgType, /* 61: invalid message type */ + xpBiosError, /* 62: BIOS error */ - xpUnknownReason /* 61: unknown reason - must be last in enum */ + xpUnknownReason /* 63: unknown reason - must be last in enum */ }; /* @@ -345,6 +346,8 @@ extern unsigned long (*xp_pa) (void *); extern enum xp_retval (*xp_remote_memcpy) (unsigned long, const unsigned long, size_t); extern int (*xp_cpu_to_nasid) (int); +extern enum xp_retval (*xp_expand_memprotect) (unsigned long, unsigned long); +extern enum xp_retval (*xp_restrict_memprotect) (unsigned long, unsigned long); extern u64 xp_nofault_PIOR_target; extern int xp_nofault_PIOR(void *); diff --git a/drivers/misc/sgi-xp/xp_main.c b/drivers/misc/sgi-xp/xp_main.c index 66a1d19e08a..16f8dcab2da 100644 --- a/drivers/misc/sgi-xp/xp_main.c +++ b/drivers/misc/sgi-xp/xp_main.c @@ -25,7 +25,7 @@ struct device_driver xp_dbg_name = { }; struct device xp_dbg_subname = { - .bus_id = {0}, /* set to "" */ + .init_name = "", /* set to "" */ .driver = &xp_dbg_name }; @@ -51,6 +51,13 @@ EXPORT_SYMBOL_GPL(xp_remote_memcpy); int (*xp_cpu_to_nasid) (int cpuid); EXPORT_SYMBOL_GPL(xp_cpu_to_nasid); +enum xp_retval (*xp_expand_memprotect) (unsigned long phys_addr, + unsigned long size); +EXPORT_SYMBOL_GPL(xp_expand_memprotect); +enum xp_retval (*xp_restrict_memprotect) (unsigned long phys_addr, + unsigned long size); +EXPORT_SYMBOL_GPL(xp_restrict_memprotect); + /* * xpc_registrations[] keeps track of xpc_connect()'s done by the kernel-level * users of XPC. diff --git a/drivers/misc/sgi-xp/xp_sn2.c b/drivers/misc/sgi-xp/xp_sn2.c index 1440134caf3..fb3ec9d735a 100644 --- a/drivers/misc/sgi-xp/xp_sn2.c +++ b/drivers/misc/sgi-xp/xp_sn2.c @@ -120,6 +120,38 @@ xp_cpu_to_nasid_sn2(int cpuid) return cpuid_to_nasid(cpuid); } +static enum xp_retval +xp_expand_memprotect_sn2(unsigned long phys_addr, unsigned long size) +{ + u64 nasid_array = 0; + int ret; + + ret = sn_change_memprotect(phys_addr, size, SN_MEMPROT_ACCESS_CLASS_1, + &nasid_array); + if (ret != 0) { + dev_err(xp, "sn_change_memprotect(,, " + "SN_MEMPROT_ACCESS_CLASS_1,) failed ret=%d\n", ret); + return xpSalError; + } + return xpSuccess; +} + +static enum xp_retval +xp_restrict_memprotect_sn2(unsigned long phys_addr, unsigned long size) +{ + u64 nasid_array = 0; + int ret; + + ret = sn_change_memprotect(phys_addr, size, SN_MEMPROT_ACCESS_CLASS_0, + &nasid_array); + if (ret != 0) { + dev_err(xp, "sn_change_memprotect(,, " + "SN_MEMPROT_ACCESS_CLASS_0,) failed ret=%d\n", ret); + return xpSalError; + } + return xpSuccess; +} + enum xp_retval xp_init_sn2(void) { @@ -132,6 +164,8 @@ xp_init_sn2(void) xp_pa = xp_pa_sn2; xp_remote_memcpy = xp_remote_memcpy_sn2; xp_cpu_to_nasid = xp_cpu_to_nasid_sn2; + xp_expand_memprotect = xp_expand_memprotect_sn2; + xp_restrict_memprotect = xp_restrict_memprotect_sn2; return xp_register_nofault_code_sn2(); } diff --git a/drivers/misc/sgi-xp/xp_uv.c b/drivers/misc/sgi-xp/xp_uv.c index d9f7ce2510b..d238576b26f 100644 --- a/drivers/misc/sgi-xp/xp_uv.c +++ b/drivers/misc/sgi-xp/xp_uv.c @@ -15,6 +15,11 @@ #include <linux/device.h> #include <asm/uv/uv_hub.h> +#if defined CONFIG_X86_64 +#include <asm/uv/bios.h> +#elif defined CONFIG_IA64_GENERIC || defined CONFIG_IA64_SGI_UV +#include <asm/sn/sn_sal.h> +#endif #include "../sgi-gru/grukservices.h" #include "xp.h" @@ -49,18 +54,79 @@ xp_cpu_to_nasid_uv(int cpuid) return UV_PNODE_TO_NASID(uv_cpu_to_pnode(cpuid)); } +static enum xp_retval +xp_expand_memprotect_uv(unsigned long phys_addr, unsigned long size) +{ + int ret; + +#if defined CONFIG_X86_64 + ret = uv_bios_change_memprotect(phys_addr, size, UV_MEMPROT_ALLOW_RW); + if (ret != BIOS_STATUS_SUCCESS) { + dev_err(xp, "uv_bios_change_memprotect(,, " + "UV_MEMPROT_ALLOW_RW) failed, ret=%d\n", ret); + return xpBiosError; + } + +#elif defined CONFIG_IA64_GENERIC || defined CONFIG_IA64_SGI_UV + u64 nasid_array; + + ret = sn_change_memprotect(phys_addr, size, SN_MEMPROT_ACCESS_CLASS_1, + &nasid_array); + if (ret != 0) { + dev_err(xp, "sn_change_memprotect(,, " + "SN_MEMPROT_ACCESS_CLASS_1,) failed ret=%d\n", ret); + return xpSalError; + } +#else + #error not a supported configuration +#endif + return xpSuccess; +} + +static enum xp_retval +xp_restrict_memprotect_uv(unsigned long phys_addr, unsigned long size) +{ + int ret; + +#if defined CONFIG_X86_64 + ret = uv_bios_change_memprotect(phys_addr, size, + UV_MEMPROT_RESTRICT_ACCESS); + if (ret != BIOS_STATUS_SUCCESS) { + dev_err(xp, "uv_bios_change_memprotect(,, " + "UV_MEMPROT_RESTRICT_ACCESS) failed, ret=%d\n", ret); + return xpBiosError; + } + +#elif defined CONFIG_IA64_GENERIC || defined CONFIG_IA64_SGI_UV + u64 nasid_array; + + ret = sn_change_memprotect(phys_addr, size, SN_MEMPROT_ACCESS_CLASS_0, + &nasid_array); + if (ret != 0) { + dev_err(xp, "sn_change_memprotect(,, " + "SN_MEMPROT_ACCESS_CLASS_0,) failed ret=%d\n", ret); + return xpSalError; + } +#else + #error not a supported configuration +#endif + return xpSuccess; +} + enum xp_retval xp_init_uv(void) { BUG_ON(!is_uv()); xp_max_npartitions = XP_MAX_NPARTITIONS_UV; - xp_partition_id = 0; /* !!! not correct value */ - xp_region_size = 0; /* !!! not correct value */ + xp_partition_id = sn_partition_id; + xp_region_size = sn_region_size; xp_pa = xp_pa_uv; xp_remote_memcpy = xp_remote_memcpy_uv; xp_cpu_to_nasid = xp_cpu_to_nasid_uv; + xp_expand_memprotect = xp_expand_memprotect_uv; + xp_restrict_memprotect = xp_restrict_memprotect_uv; return xpSuccess; } diff --git a/drivers/misc/sgi-xp/xpc.h b/drivers/misc/sgi-xp/xpc.h index 619208d6186..a5bd658c2e8 100644 --- a/drivers/misc/sgi-xp/xpc.h +++ b/drivers/misc/sgi-xp/xpc.h @@ -181,6 +181,18 @@ struct xpc_vars_part_sn2 { xpc_nasid_mask_nlongs)) /* + * Info pertinent to a GRU message queue using a watch list for irq generation. + */ +struct xpc_gru_mq_uv { + void *address; /* address of GRU message queue */ + unsigned int order; /* size of GRU message queue as a power of 2 */ + int irq; /* irq raised when message is received in mq */ + int mmr_blade; /* blade where watchlist was allocated from */ + unsigned long mmr_offset; /* offset of irq mmr located on mmr_blade */ + int watchlist_num; /* number of watchlist allocatd by BIOS */ +}; + +/* * The activate_mq is used to send/receive GRU messages that affect XPC's * heartbeat, partition active state, and channel state. This is UV only. */ diff --git a/drivers/misc/sgi-xp/xpc_main.c b/drivers/misc/sgi-xp/xpc_main.c index e8d5cfbd32c..89218f7cfaa 100644 --- a/drivers/misc/sgi-xp/xpc_main.c +++ b/drivers/misc/sgi-xp/xpc_main.c @@ -59,12 +59,12 @@ struct device_driver xpc_dbg_name = { }; struct device xpc_part_dbg_subname = { - .bus_id = {0}, /* set to "part" at xpc_init() time */ + .init_name = "", /* set to "part" at xpc_init() time */ .driver = &xpc_dbg_name }; struct device xpc_chan_dbg_subname = { - .bus_id = {0}, /* set to "chan" at xpc_init() time */ + .init_name = "", /* set to "chan" at xpc_init() time */ .driver = &xpc_dbg_name }; @@ -1258,8 +1258,8 @@ xpc_init(void) int ret; struct task_struct *kthread; - snprintf(xpc_part->bus_id, BUS_ID_SIZE, "part"); - snprintf(xpc_chan->bus_id, BUS_ID_SIZE, "chan"); + dev_set_name(xpc_part, "part"); + dev_set_name(xpc_chan, "chan"); if (is_shub()) { /* diff --git a/drivers/misc/sgi-xp/xpc_sn2.c b/drivers/misc/sgi-xp/xpc_sn2.c index b4882ccf634..82fb9958f22 100644 --- a/drivers/misc/sgi-xp/xpc_sn2.c +++ b/drivers/misc/sgi-xp/xpc_sn2.c @@ -553,22 +553,17 @@ static u64 xpc_prot_vec_sn2[MAX_NUMNODES]; static enum xp_retval xpc_allow_amo_ops_sn2(struct amo *amos_page) { - u64 nasid_array = 0; - int ret; + enum xp_retval ret = xpSuccess; /* * On SHUB 1.1, we cannot call sn_change_memprotect() since the BIST * collides with memory operations. On those systems we call * xpc_allow_amo_ops_shub_wars_1_1_sn2() instead. */ - if (!enable_shub_wars_1_1()) { - ret = sn_change_memprotect(ia64_tpa((u64)amos_page), PAGE_SIZE, - SN_MEMPROT_ACCESS_CLASS_1, - &nasid_array); - if (ret != 0) - return xpSalError; - } - return xpSuccess; + if (!enable_shub_wars_1_1()) + ret = xp_expand_memprotect(ia64_tpa((u64)amos_page), PAGE_SIZE); + + return ret; } /* @@ -904,7 +899,7 @@ xpc_update_partition_info_sn2(struct xpc_partition *part, u8 remote_rp_version, dev_dbg(xpc_part, " remote_vars_pa = 0x%016lx\n", part_sn2->remote_vars_pa); - part->last_heartbeat = remote_vars->heartbeat; + part->last_heartbeat = remote_vars->heartbeat - 1; dev_dbg(xpc_part, " last_heartbeat = 0x%016lx\n", part->last_heartbeat); diff --git a/drivers/misc/sgi-xp/xpc_uv.c b/drivers/misc/sgi-xp/xpc_uv.c index 1ac694c0162..91a55b1b103 100644 --- a/drivers/misc/sgi-xp/xpc_uv.c +++ b/drivers/misc/sgi-xp/xpc_uv.c @@ -18,7 +18,15 @@ #include <linux/interrupt.h> #include <linux/delay.h> #include <linux/device.h> +#include <linux/err.h> #include <asm/uv/uv_hub.h> +#if defined CONFIG_X86_64 +#include <asm/uv/bios.h> +#include <asm/uv/uv_irq.h> +#elif defined CONFIG_IA64_GENERIC || defined CONFIG_IA64_SGI_UV +#include <asm/sn/intr.h> +#include <asm/sn/sn_sal.h> +#endif #include "../sgi-gru/gru.h" #include "../sgi-gru/grukservices.h" #include "xpc.h" @@ -27,15 +35,17 @@ static atomic64_t xpc_heartbeat_uv; static DECLARE_BITMAP(xpc_heartbeating_to_mask_uv, XP_MAX_NPARTITIONS_UV); #define XPC_ACTIVATE_MSG_SIZE_UV (1 * GRU_CACHE_LINE_BYTES) -#define XPC_NOTIFY_MSG_SIZE_UV (2 * GRU_CACHE_LINE_BYTES) +#define XPC_ACTIVATE_MQ_SIZE_UV (4 * XP_MAX_NPARTITIONS_UV * \ + XPC_ACTIVATE_MSG_SIZE_UV) +#define XPC_ACTIVATE_IRQ_NAME "xpc_activate" -#define XPC_ACTIVATE_MQ_SIZE_UV (4 * XP_MAX_NPARTITIONS_UV * \ - XPC_ACTIVATE_MSG_SIZE_UV) -#define XPC_NOTIFY_MQ_SIZE_UV (4 * XP_MAX_NPARTITIONS_UV * \ - XPC_NOTIFY_MSG_SIZE_UV) +#define XPC_NOTIFY_MSG_SIZE_UV (2 * GRU_CACHE_LINE_BYTES) +#define XPC_NOTIFY_MQ_SIZE_UV (4 * XP_MAX_NPARTITIONS_UV * \ + XPC_NOTIFY_MSG_SIZE_UV) +#define XPC_NOTIFY_IRQ_NAME "xpc_notify" -static void *xpc_activate_mq_uv; -static void *xpc_notify_mq_uv; +static struct xpc_gru_mq_uv *xpc_activate_mq_uv; +static struct xpc_gru_mq_uv *xpc_notify_mq_uv; static int xpc_setup_partitions_sn_uv(void) @@ -52,62 +62,209 @@ xpc_setup_partitions_sn_uv(void) return 0; } -static void * -xpc_create_gru_mq_uv(unsigned int mq_size, int cpuid, unsigned int irq, +static int +xpc_get_gru_mq_irq_uv(struct xpc_gru_mq_uv *mq, int cpu, char *irq_name) +{ +#if defined CONFIG_X86_64 + mq->irq = uv_setup_irq(irq_name, cpu, mq->mmr_blade, mq->mmr_offset); + if (mq->irq < 0) { + dev_err(xpc_part, "uv_setup_irq() returned error=%d\n", + mq->irq); + } + +#elif defined CONFIG_IA64_GENERIC || defined CONFIG_IA64_SGI_UV + int mmr_pnode; + unsigned long mmr_value; + + if (strcmp(irq_name, XPC_ACTIVATE_IRQ_NAME) == 0) + mq->irq = SGI_XPC_ACTIVATE; + else if (strcmp(irq_name, XPC_NOTIFY_IRQ_NAME) == 0) + mq->irq = SGI_XPC_NOTIFY; + else + return -EINVAL; + + mmr_pnode = uv_blade_to_pnode(mq->mmr_blade); + mmr_value = (unsigned long)cpu_physical_id(cpu) << 32 | mq->irq; + + uv_write_global_mmr64(mmr_pnode, mq->mmr_offset, mmr_value); +#else + #error not a supported configuration +#endif + + return 0; +} + +static void +xpc_release_gru_mq_irq_uv(struct xpc_gru_mq_uv *mq) +{ +#if defined CONFIG_X86_64 + uv_teardown_irq(mq->irq, mq->mmr_blade, mq->mmr_offset); + +#elif defined CONFIG_IA64_GENERIC || defined CONFIG_IA64_SGI_UV + int mmr_pnode; + unsigned long mmr_value; + + mmr_pnode = uv_blade_to_pnode(mq->mmr_blade); + mmr_value = 1UL << 16; + + uv_write_global_mmr64(mmr_pnode, mq->mmr_offset, mmr_value); +#else + #error not a supported configuration +#endif +} + +static int +xpc_gru_mq_watchlist_alloc_uv(struct xpc_gru_mq_uv *mq) +{ + int ret; + +#if defined CONFIG_X86_64 + ret = uv_bios_mq_watchlist_alloc(mq->mmr_blade, uv_gpa(mq->address), + mq->order, &mq->mmr_offset); + if (ret < 0) { + dev_err(xpc_part, "uv_bios_mq_watchlist_alloc() failed, " + "ret=%d\n", ret); + return ret; + } +#elif defined CONFIG_IA64_GENERIC || defined CONFIG_IA64_SGI_UV + ret = sn_mq_watchlist_alloc(mq->mmr_blade, uv_gpa(mq->address), + mq->order, &mq->mmr_offset); + if (ret < 0) { + dev_err(xpc_part, "sn_mq_watchlist_alloc() failed, ret=%d\n", + ret); + return -EBUSY; + } +#else + #error not a supported configuration +#endif + + mq->watchlist_num = ret; + return 0; +} + +static void +xpc_gru_mq_watchlist_free_uv(struct xpc_gru_mq_uv *mq) +{ + int ret; + +#if defined CONFIG_X86_64 + ret = uv_bios_mq_watchlist_free(mq->mmr_blade, mq->watchlist_num); + BUG_ON(ret != BIOS_STATUS_SUCCESS); +#elif defined CONFIG_IA64_GENERIC || defined CONFIG_IA64_SGI_UV + ret = sn_mq_watchlist_free(mq->mmr_blade, mq->watchlist_num); + BUG_ON(ret != SALRET_OK); +#else + #error not a supported configuration +#endif +} + +static struct xpc_gru_mq_uv * +xpc_create_gru_mq_uv(unsigned int mq_size, int cpu, char *irq_name, irq_handler_t irq_handler) { + enum xp_retval xp_ret; int ret; int nid; - int mq_order; + int pg_order; struct page *page; - void *mq; + struct xpc_gru_mq_uv *mq; + + mq = kmalloc(sizeof(struct xpc_gru_mq_uv), GFP_KERNEL); + if (mq == NULL) { + dev_err(xpc_part, "xpc_create_gru_mq_uv() failed to kmalloc() " + "a xpc_gru_mq_uv structure\n"); + ret = -ENOMEM; + goto out_1; + } + + pg_order = get_order(mq_size); + mq->order = pg_order + PAGE_SHIFT; + mq_size = 1UL << mq->order; + + mq->mmr_blade = uv_cpu_to_blade_id(cpu); - nid = cpu_to_node(cpuid); - mq_order = get_order(mq_size); + nid = cpu_to_node(cpu); page = alloc_pages_node(nid, GFP_KERNEL | __GFP_ZERO | GFP_THISNODE, - mq_order); + pg_order); if (page == NULL) { dev_err(xpc_part, "xpc_create_gru_mq_uv() failed to alloc %d " "bytes of memory on nid=%d for GRU mq\n", mq_size, nid); - return NULL; + ret = -ENOMEM; + goto out_2; } + mq->address = page_address(page); - mq = page_address(page); - ret = gru_create_message_queue(mq, mq_size); + ret = gru_create_message_queue(mq->address, mq_size); if (ret != 0) { dev_err(xpc_part, "gru_create_message_queue() returned " "error=%d\n", ret); - free_pages((unsigned long)mq, mq_order); - return NULL; + ret = -EINVAL; + goto out_3; } - /* !!! Need to do some other things to set up IRQ */ + /* enable generation of irq when GRU mq operation occurs to this mq */ + ret = xpc_gru_mq_watchlist_alloc_uv(mq); + if (ret != 0) + goto out_3; - ret = request_irq(irq, irq_handler, 0, "xpc", NULL); + ret = xpc_get_gru_mq_irq_uv(mq, cpu, irq_name); + if (ret != 0) + goto out_4; + + ret = request_irq(mq->irq, irq_handler, 0, irq_name, NULL); if (ret != 0) { dev_err(xpc_part, "request_irq(irq=%d) returned error=%d\n", - irq, ret); - free_pages((unsigned long)mq, mq_order); - return NULL; + mq->irq, ret); + goto out_5; } - /* !!! enable generation of irq when GRU mq op occurs to this mq */ - - /* ??? allow other partitions to access GRU mq? */ + /* allow other partitions to access this GRU mq */ + xp_ret = xp_expand_memprotect(xp_pa(mq->address), mq_size); + if (xp_ret != xpSuccess) { + ret = -EACCES; + goto out_6; + } return mq; + + /* something went wrong */ +out_6: + free_irq(mq->irq, NULL); +out_5: + xpc_release_gru_mq_irq_uv(mq); +out_4: + xpc_gru_mq_watchlist_free_uv(mq); +out_3: + free_pages((unsigned long)mq->address, pg_order); +out_2: + kfree(mq); +out_1: + return ERR_PTR(ret); } static void -xpc_destroy_gru_mq_uv(void *mq, unsigned int mq_size, unsigned int irq) +xpc_destroy_gru_mq_uv(struct xpc_gru_mq_uv *mq) { - /* ??? disallow other partitions to access GRU mq? */ + unsigned int mq_size; + int pg_order; + int ret; + + /* disallow other partitions to access GRU mq */ + mq_size = 1UL << mq->order; + ret = xp_restrict_memprotect(xp_pa(mq->address), mq_size); + BUG_ON(ret != xpSuccess); - /* !!! disable generation of irq when GRU mq op occurs to this mq */ + /* unregister irq handler and release mq irq/vector mapping */ + free_irq(mq->irq, NULL); + xpc_release_gru_mq_irq_uv(mq); - free_irq(irq, NULL); + /* disable generation of irq when GRU mq op occurs to this mq */ + xpc_gru_mq_watchlist_free_uv(mq); - free_pages((unsigned long)mq, get_order(mq_size)); + pg_order = mq->order - PAGE_SHIFT; + free_pages((unsigned long)mq->address, pg_order); + + kfree(mq); } static enum xp_retval @@ -402,7 +559,10 @@ xpc_handle_activate_IRQ_uv(int irq, void *dev_id) struct xpc_partition *part; int wakeup_hb_checker = 0; - while ((msg_hdr = gru_get_next_message(xpc_activate_mq_uv)) != NULL) { + while (1) { + msg_hdr = gru_get_next_message(xpc_activate_mq_uv->address); + if (msg_hdr == NULL) + break; partid = msg_hdr->partid; if (partid < 0 || partid >= XP_MAX_NPARTITIONS_UV) { @@ -418,7 +578,7 @@ xpc_handle_activate_IRQ_uv(int irq, void *dev_id) } } - gru_free_message(xpc_activate_mq_uv, msg_hdr); + gru_free_message(xpc_activate_mq_uv->address, msg_hdr); } if (wakeup_hb_checker) @@ -482,7 +642,7 @@ xpc_send_local_activate_IRQ_uv(struct xpc_partition *part, int act_state_req) struct xpc_partition_uv *part_uv = &part->sn.uv; /* - * !!! Make our side think that the remote parition sent an activate + * !!! Make our side think that the remote partition sent an activate * !!! message our way by doing what the activate IRQ handler would * !!! do had one really been sent. */ @@ -500,14 +660,39 @@ static enum xp_retval xpc_get_partition_rsvd_page_pa_uv(void *buf, u64 *cookie, unsigned long *rp_pa, size_t *len) { - /* !!! call the UV version of sn_partition_reserved_page_pa() */ - return xpUnsupported; + s64 status; + enum xp_retval ret; + +#if defined CONFIG_X86_64 + status = uv_bios_reserved_page_pa((u64)buf, cookie, (u64 *)rp_pa, + (u64 *)len); + if (status == BIOS_STATUS_SUCCESS) + ret = xpSuccess; + else if (status == BIOS_STATUS_MORE_PASSES) + ret = xpNeedMoreInfo; + else + ret = xpBiosError; + +#elif defined CONFIG_IA64_GENERIC || defined CONFIG_IA64_SGI_UV + status = sn_partition_reserved_page_pa((u64)buf, cookie, rp_pa, len); + if (status == SALRET_OK) + ret = xpSuccess; + else if (status == SALRET_MORE_PASSES) + ret = xpNeedMoreInfo; + else + ret = xpSalError; + +#else + #error not a supported configuration +#endif + + return ret; } static int xpc_setup_rsvd_page_sn_uv(struct xpc_rsvd_page *rp) { - rp->sn.activate_mq_gpa = uv_gpa(xpc_activate_mq_uv); + rp->sn.activate_mq_gpa = uv_gpa(xpc_activate_mq_uv->address); return 0; } @@ -1411,22 +1596,18 @@ xpc_init_uv(void) return -E2BIG; } - /* ??? The cpuid argument's value is 0, is that what we want? */ - /* !!! The irq argument's value isn't correct. */ - xpc_activate_mq_uv = xpc_create_gru_mq_uv(XPC_ACTIVATE_MQ_SIZE_UV, 0, 0, + xpc_activate_mq_uv = xpc_create_gru_mq_uv(XPC_ACTIVATE_MQ_SIZE_UV, 0, + XPC_ACTIVATE_IRQ_NAME, xpc_handle_activate_IRQ_uv); - if (xpc_activate_mq_uv == NULL) - return -ENOMEM; + if (IS_ERR(xpc_activate_mq_uv)) + return PTR_ERR(xpc_activate_mq_uv); - /* ??? The cpuid argument's value is 0, is that what we want? */ - /* !!! The irq argument's value isn't correct. */ - xpc_notify_mq_uv = xpc_create_gru_mq_uv(XPC_NOTIFY_MQ_SIZE_UV, 0, 0, + xpc_notify_mq_uv = xpc_create_gru_mq_uv(XPC_NOTIFY_MQ_SIZE_UV, 0, + XPC_NOTIFY_IRQ_NAME, xpc_handle_notify_IRQ_uv); - if (xpc_notify_mq_uv == NULL) { - /* !!! The irq argument's value isn't correct. */ - xpc_destroy_gru_mq_uv(xpc_activate_mq_uv, - XPC_ACTIVATE_MQ_SIZE_UV, 0); - return -ENOMEM; + if (IS_ERR(xpc_notify_mq_uv)) { + xpc_destroy_gru_mq_uv(xpc_activate_mq_uv); + return PTR_ERR(xpc_notify_mq_uv); } return 0; @@ -1435,9 +1616,6 @@ xpc_init_uv(void) void xpc_exit_uv(void) { - /* !!! The irq argument's value isn't correct. */ - xpc_destroy_gru_mq_uv(xpc_notify_mq_uv, XPC_NOTIFY_MQ_SIZE_UV, 0); - - /* !!! The irq argument's value isn't correct. */ - xpc_destroy_gru_mq_uv(xpc_activate_mq_uv, XPC_ACTIVATE_MQ_SIZE_UV, 0); + xpc_destroy_gru_mq_uv(xpc_notify_mq_uv); + xpc_destroy_gru_mq_uv(xpc_activate_mq_uv); } diff --git a/drivers/misc/sgi-xp/xpnet.c b/drivers/misc/sgi-xp/xpnet.c index 71513b3af70..7957f525b2f 100644 --- a/drivers/misc/sgi-xp/xpnet.c +++ b/drivers/misc/sgi-xp/xpnet.c @@ -95,11 +95,6 @@ struct xpnet_pending_msg { atomic_t use_count; }; -/* driver specific structure pointed to by the device structure */ -struct xpnet_dev_private { - struct net_device_stats stats; -}; - struct net_device *xpnet_device; /* @@ -138,7 +133,7 @@ struct device_driver xpnet_dbg_name = { }; struct device xpnet_dbg_subname = { - .bus_id = {0}, /* set to "" */ + .init_name = "", /* set to "" */ .driver = &xpnet_dbg_name }; @@ -153,8 +148,6 @@ xpnet_receive(short partid, int channel, struct xpnet_message *msg) struct sk_buff *skb; void *dst; enum xp_retval ret; - struct xpnet_dev_private *priv = - (struct xpnet_dev_private *)xpnet_device->priv; if (!XPNET_VALID_MSG(msg)) { /* @@ -162,7 +155,7 @@ xpnet_receive(short partid, int channel, struct xpnet_message *msg) */ xpc_received(partid, channel, (void *)msg); - priv->stats.rx_errors++; + xpnet_device->stats.rx_errors++; return; } @@ -177,7 +170,7 @@ xpnet_receive(short partid, int channel, struct xpnet_message *msg) xpc_received(partid, channel, (void *)msg); - priv->stats.rx_errors++; + xpnet_device->stats.rx_errors++; return; } @@ -227,7 +220,7 @@ xpnet_receive(short partid, int channel, struct xpnet_message *msg) xpc_received(partid, channel, (void *)msg); - priv->stats.rx_errors++; + xpnet_device->stats.rx_errors++; return; } @@ -248,8 +241,8 @@ xpnet_receive(short partid, int channel, struct xpnet_message *msg) skb_end_pointer(skb), skb->len); xpnet_device->last_rx = jiffies; - priv->stats.rx_packets++; - priv->stats.rx_bytes += skb->len + ETH_HLEN; + xpnet_device->stats.rx_packets++; + xpnet_device->stats.rx_bytes += skb->len + ETH_HLEN; netif_rx_ni(skb); xpc_received(partid, channel, (void *)msg); @@ -354,28 +347,6 @@ xpnet_dev_change_mtu(struct net_device *dev, int new_mtu) } /* - * Required for the net_device structure. - */ -static int -xpnet_dev_set_config(struct net_device *dev, struct ifmap *new_map) -{ - return 0; -} - -/* - * Return statistics to the caller. - */ -static struct net_device_stats * -xpnet_dev_get_stats(struct net_device *dev) -{ - struct xpnet_dev_private *priv; - - priv = (struct xpnet_dev_private *)dev->priv; - - return &priv->stats; -} - -/* * Notification that the other end has received the message and * DMA'd the skb information. At this point, they are done with * our side. When all recipients are done processing, we @@ -456,7 +427,6 @@ xpnet_dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) struct xpnet_pending_msg *queued_msg; u64 start_addr, end_addr; short dest_partid; - struct xpnet_dev_private *priv = (struct xpnet_dev_private *)dev->priv; u16 embedded_bytes = 0; dev_dbg(xpnet, ">skb->head=0x%p skb->data=0x%p skb->tail=0x%p " @@ -479,7 +449,7 @@ xpnet_dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) dev_warn(xpnet, "failed to kmalloc %ld bytes; dropping " "packet\n", sizeof(struct xpnet_pending_msg)); - priv->stats.tx_errors++; + dev->stats.tx_errors++; return -ENOMEM; } @@ -529,8 +499,8 @@ xpnet_dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) kfree(queued_msg); } - priv->stats.tx_packets++; - priv->stats.tx_bytes += skb->len; + dev->stats.tx_packets++; + dev->stats.tx_bytes += skb->len; return 0; } @@ -541,14 +511,19 @@ xpnet_dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) static void xpnet_dev_tx_timeout(struct net_device *dev) { - struct xpnet_dev_private *priv; - - priv = (struct xpnet_dev_private *)dev->priv; - - priv->stats.tx_errors++; - return; + dev->stats.tx_errors++; } +static const struct net_device_ops xpnet_netdev_ops = { + .ndo_open = xpnet_dev_open, + .ndo_stop = xpnet_dev_stop, + .ndo_start_xmit = xpnet_dev_hard_start_xmit, + .ndo_change_mtu = xpnet_dev_change_mtu, + .ndo_tx_timeout = xpnet_dev_tx_timeout, + .ndo_set_mac_address = eth_mac_addr, + .ndo_validate_addr = eth_validate_addr, +}; + static int __init xpnet_init(void) { @@ -568,8 +543,7 @@ xpnet_init(void) * use ether_setup() to init the majority of our device * structure and then override the necessary pieces. */ - xpnet_device = alloc_netdev(sizeof(struct xpnet_dev_private), - XPNET_DEVICE_NAME, ether_setup); + xpnet_device = alloc_netdev(0, XPNET_DEVICE_NAME, ether_setup); if (xpnet_device == NULL) { kfree(xpnet_broadcast_partitions); return -ENOMEM; @@ -578,13 +552,6 @@ xpnet_init(void) netif_carrier_off(xpnet_device); xpnet_device->mtu = XPNET_DEF_MTU; - xpnet_device->change_mtu = xpnet_dev_change_mtu; - xpnet_device->open = xpnet_dev_open; - xpnet_device->get_stats = xpnet_dev_get_stats; - xpnet_device->stop = xpnet_dev_stop; - xpnet_device->hard_start_xmit = xpnet_dev_hard_start_xmit; - xpnet_device->tx_timeout = xpnet_dev_tx_timeout; - xpnet_device->set_config = xpnet_dev_set_config; /* * Multicast assumes the LSB of the first octet is set for multicast |