Commit 845eaa9b authored by Jesse Barnes's avatar Jesse Barnes Committed by David Mosberger

[PATCH] ia64: SN update

David, here's a patch to update SN support in the ia64 tree.  I had to
make a few mods outside arch/ia64/sn and include/asm-ia64/sn to get
CONFIG_IA64_SGI_SN2 to compile.
parent 25a3d107
...@@ -42,8 +42,11 @@ core-$(CONFIG_IA64_DIG) += arch/$(ARCH)/dig/ ...@@ -42,8 +42,11 @@ core-$(CONFIG_IA64_DIG) += arch/$(ARCH)/dig/
core-$(CONFIG_IA64_GENERIC) += arch/$(ARCH)/dig/ arch/$(ARCH)/hp/common/ arch/$(ARCH)/hp/zx1/ \ core-$(CONFIG_IA64_GENERIC) += arch/$(ARCH)/dig/ arch/$(ARCH)/hp/common/ arch/$(ARCH)/hp/zx1/ \
arch/$(ARCH)/hp/sim/ arch/$(ARCH)/hp/sim/
core-$(CONFIG_IA64_HP_ZX1) += arch/$(ARCH)/dig/ core-$(CONFIG_IA64_HP_ZX1) += arch/$(ARCH)/dig/
core-$(CONFIG_IA64_SGI_SN) += arch/$(ARCH)/sn/kernel arch/$(ARCH)/sn/io \ core-$(CONFIG_IA64_SGI_SN) += arch/$(ARCH)/sn/kernel/ \
arch/$(ARCH)/sn/fakeprom arch/$(ARCH)/sn/io/ \
arch/$(ARCH)/sn/io/sn2/ \
arch/$(ARCH)/sn/io/sn2/pcibr/ \
arch/$(ARCH)/sn/kernel/sn2/
drivers-$(CONFIG_PCI) += arch/$(ARCH)/pci/ drivers-$(CONFIG_PCI) += arch/$(ARCH)/pci/
drivers-$(CONFIG_IA64_HP_SIM) += arch/$(ARCH)/hp/sim/ drivers-$(CONFIG_IA64_HP_SIM) += arch/$(ARCH)/hp/sim/
drivers-$(CONFIG_IA64_HP_ZX1) += arch/$(ARCH)/hp/common/ arch/$(ARCH)/hp/zx1/ drivers-$(CONFIG_IA64_HP_ZX1) += arch/$(ARCH)/hp/common/ arch/$(ARCH)/hp/zx1/
......
...@@ -77,7 +77,7 @@ ia64_sal_strerror (long status) ...@@ -77,7 +77,7 @@ ia64_sal_strerror (long status)
return str; return str;
} }
static void __init void __init
ia64_sal_handler_init (void *entry_point, void *gpval) ia64_sal_handler_init (void *entry_point, void *gpval)
{ {
/* fill in the SAL procedure descriptor and point ia64_sal to it: */ /* fill in the SAL procedure descriptor and point ia64_sal to it: */
......
...@@ -6,16 +6,16 @@ ...@@ -6,16 +6,16 @@
# Copyright (c) 2000-2001 Silicon Graphics, Inc. All rights reserved. # Copyright (c) 2000-2001 Silicon Graphics, Inc. All rights reserved.
# #
TOPDIR=../../../.. obj-y=fpromasm.o main.o fw-emu.o fpmem.o klgraph_init.o
LIB = ../../lib/lib.a
OBJ=fpromasm.o main.o fw-emu.o fpmem.o klgraph_init.o
obj-y=fprom
fprom: $(OBJ) fprom: $(OBJ)
$(LD) -static -Tfprom.lds -o fprom $(OBJ) $(LIB) $(LD) -static -Tfprom.lds -o fprom $(OBJ) $(LIB)
.S.o:
$(CC) -D__ASSEMBLY__ $(AFLAGS) $(AFLAGS_KERNEL) -c -o $*.o $<
.c.o:
$(CC) $(CFLAGS) $(CFLAGS_KERNEL) -c -o $*.o $<
clean: clean:
rm -f *.o fprom rm -f *.o fprom
......
...@@ -71,7 +71,7 @@ amount of memory present on nodes 0-3. ...@@ -71,7 +71,7 @@ amount of memory present on nodes 0-3.
1GB*<dn>, where dn is the digit number. The amount of memory 1GB*<dn>, where dn is the digit number. The amount of memory
is 8MB*2**<d>. (If <d> = 0, the memory size is 0). is 8MB*2**<d>. (If <d> = 0, the memory size is 0).
SN1 doesn't support dimms this small but small memory systems SN1 doesnt support dimms this small but small memory systems
boot faster on Medusa. boot faster on Medusa.
......
...@@ -54,10 +54,10 @@ sn_config_t *sn_config ; ...@@ -54,10 +54,10 @@ sn_config_t *sn_config ;
#define PROMRESERVED_SIZE (1*MB) #define PROMRESERVED_SIZE (1*MB)
#ifdef CONFIG_IA64_SGI_SN1 #ifdef CONFIG_IA64_SGI_SN1
#define PHYS_ADDRESS(_n, _x) (((long)_n<<33L) | (long)_x) #define PHYS_ADDRESS(_n, _x) (((long)_n<<33) | (long)_x)
#define MD_BANK_SHFT 30 #define MD_BANK_SHFT 30
#else #else
#define PHYS_ADDRESS(_n, _x) (((long)_n<<38L) | (long)_x | 0x3000000000UL) #define PHYS_ADDRESS(_n, _x) (((long)_n<<38) | (long)_x | 0x3000000000UL)
#define MD_BANK_SHFT 34 #define MD_BANK_SHFT 34
#endif #endif
...@@ -94,7 +94,7 @@ GetMemBankInfo(int index) ...@@ -94,7 +94,7 @@ GetMemBankInfo(int index)
int int
IsCpuPresent(int cnode, int cpu) IsCpuPresent(int cnode, int cpu)
{ {
return sn_memmap[cnode].cpuconfig & (1<<cpu); return sn_memmap[cnode].cpuconfig & (1UL<<cpu);
} }
...@@ -142,10 +142,10 @@ int ...@@ -142,10 +142,10 @@ int
IsBankPresent(int index, node_memmap_t nmemmap) IsBankPresent(int index, node_memmap_t nmemmap)
{ {
switch (index) { switch (index) {
case 0:return nmemmap.ena0; case 0:return BankPresent(nmemmap.b0size);
case 1:return nmemmap.ena1; case 1:return BankPresent(nmemmap.b1size);
case 2:return nmemmap.ena2; case 2:return BankPresent(nmemmap.b2size);
case 3:return nmemmap.ena3; case 3:return BankPresent(nmemmap.b3size);
default:return -1 ; default:return -1 ;
} }
} }
...@@ -153,11 +153,14 @@ IsBankPresent(int index, node_memmap_t nmemmap) ...@@ -153,11 +153,14 @@ IsBankPresent(int index, node_memmap_t nmemmap)
int int
GetBankSize(int index, node_memmap_t nmemmap) GetBankSize(int index, node_memmap_t nmemmap)
{ {
/*
* Add 2 because there are 4 dimms per bank.
*/
switch (index) { switch (index) {
case 0:return (long)nmemmap.b0size + nmemmap.b0dou; case 0:return 2 + ((long)nmemmap.b0size + nmemmap.b0dou);
case 1:return (long)nmemmap.b1size + nmemmap.b1dou; case 1:return 2 + ((long)nmemmap.b1size + nmemmap.b1dou);
case 2:return (long)nmemmap.b2size + nmemmap.b2dou; case 2:return 2 + ((long)nmemmap.b2size + nmemmap.b2dou);
case 3:return (long)nmemmap.b3size + nmemmap.b3dou; case 3:return 2 + ((long)nmemmap.b3size + nmemmap.b3dou);
default:return -1 ; default:return -1 ;
} }
} }
...@@ -189,14 +192,30 @@ build_efi_memmap(void *md, int mdsize) ...@@ -189,14 +192,30 @@ build_efi_memmap(void *md, int mdsize)
for (cnode=0;cnode<numnodes;cnode++) { for (cnode=0;cnode<numnodes;cnode++) {
nasid = GetNasid(cnode) ; nasid = GetNasid(cnode) ;
membank_info = GetMemBankInfo(cnode) ; membank_info = GetMemBankInfo(cnode) ;
for (bank=0;bank<PLAT_CLUMPS_PER_NODE;bank++) { for (bank=0;bank<NR_BANKS_PER_NODE;bank++) {
if (IsBankPresent(bank, membank_info)) { if (IsBankPresent(bank, membank_info)) {
bsize = GetBankSize(bank, membank_info) ; bsize = GetBankSize(bank, membank_info) ;
paddr = PHYS_ADDRESS(nasid, (long)bank<<MD_BANK_SHFT); paddr = PHYS_ADDRESS(nasid, (long)bank<<MD_BANK_SHFT);
numbytes = BankSizeBytes(bsize); numbytes = BankSizeBytes(bsize);
#ifdef CONFIG_IA64_SGI_SN2 #ifdef CONFIG_IA64_SGI_SN2
/*
* Ignore directory.
* Shorten memory chunk by 1 page - makes a better
* testcase & is more like the real PROM.
*/
numbytes = numbytes * 31 / 32; numbytes = numbytes * 31 / 32;
#endif #endif
/*
* Only emulate the memory prom grabs
* if we have lots of memory, to allow
* us to simulate smaller memory configs than
* we can actually run on h/w. Otherwise,
* linux throws away a whole "granule".
*/
if (cnode == 0 && bank == 0 &&
numbytes > 128*1024*1024) {
numbytes -= 1000;
}
/* /*
* Check for the node 0 hole. Since banks cant * Check for the node 0 hole. Since banks cant
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
* License. See the file "COPYING" in the main directory of this archive * License. See the file "COPYING" in the main directory of this archive
* for more details. * for more details.
* *
* Copyright (C) 2000-2001 Silicon Graphics, Inc. All rights reserved. * Copyright (C) 2000-2002 Silicon Graphics, Inc. All rights reserved.
*/ */
#include <linux/config.h> #include <linux/config.h>
...@@ -71,7 +71,8 @@ typedef struct node_memmap_s ...@@ -71,7 +71,8 @@ typedef struct node_memmap_s
} node_memmap_t ; } node_memmap_t ;
#define SN2_BANK_SIZE_SHIFT (MBSHIFT+6) /* 64 MB */ #define SN2_BANK_SIZE_SHIFT (MBSHIFT+6) /* 64 MB */
#define BankSizeBytes(bsize) (1UL<<((bsize)+SN2_BANK_SIZE_SHIFT)) #define BankPresent(bsize) (bsize<6)
#define BankSizeBytes(bsize) (BankPresent(bsize) ? 1UL<<((bsize)+SN2_BANK_SIZE_SHIFT) : 0)
#endif #endif
typedef struct sn_memmap_s typedef struct sn_memmap_s
......
...@@ -180,7 +180,7 @@ initx: ...@@ -180,7 +180,7 @@ initx:
// Now call main & pass it the current LID value. // Now call main & pass it the current LID value.
alloc r0=ar.pfs,0,0,2,0 alloc r2=ar.pfs,0,0,2,0
mov r32=r26 mov r32=r26
mov r33=r8;; mov r33=r8;;
br.call.sptk.few rp=fmain br.call.sptk.few rp=fmain
......
This diff is collapsed.
/* $Id: klgraph_init.c,v 1.2 2001/12/05 16:58:41 jh Exp $ /* $Id: klgraph_init.c,v 1.1 2002/02/28 17:31:25 marcelo Exp $
* *
* This file is subject to the terms and conditions of the GNU General Public * 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 * License. See the file "COPYING" in the main directory of this archive
...@@ -49,8 +49,9 @@ void ...@@ -49,8 +49,9 @@ void
klgraph_init(void) klgraph_init(void)
{ {
#ifdef CONFIG_IA64_SGI_SN1
u64 *temp; u64 *temp;
#endif
/* /*
* Initialize some hub/xbow registers that allows access to * Initialize some hub/xbow registers that allows access to
* Xbridge etc. These are normally done in PROM. * Xbridge etc. These are normally done in PROM.
...@@ -109,6 +110,8 @@ klgraph_init(void) ...@@ -109,6 +110,8 @@ klgraph_init(void)
// [PI] *(volatile u32 *)0xc00000080f000288L = 0xba98; // [PI] *(volatile u32 *)0xc00000080f000288L = 0xba98;
#endif /* CONFIG_IA64_SGI_SN1 */ #endif /* CONFIG_IA64_SGI_SN1 */
#ifdef CONFIG_IA64_SGI_SN1
/* /*
* kldir entries initialization - mankato * kldir entries initialization - mankato
*/ */
...@@ -282,6 +285,7 @@ klgraph_init(void) ...@@ -282,6 +285,7 @@ klgraph_init(void)
convert(0x8000000000002560, 0xffffffffffffffff, 0xffffffffffffffff); convert(0x8000000000002560, 0xffffffffffffffff, 0xffffffffffffffff);
convert(0x8000000000002570, 0xffffffffffffffff, 0xffffffffffffffff); convert(0x8000000000002570, 0xffffffffffffffff, 0xffffffffffffffff);
convert(0x8000000000002580, 0x000000000000ffff, 0x0000000000000000); convert(0x8000000000002580, 0x000000000000ffff, 0x0000000000000000);
#endif
} }
...@@ -98,7 +98,7 @@ synergy_init(int nasid, int syn) ...@@ -98,7 +98,7 @@ synergy_init(int nasid, int syn)
/* /*
* Enable all FSB flashed interrupts. * Enable all FSB flashed interrupts.
* ZZZ - I'd really like defines for this...... * I'd really like defines for this......
*/ */
base = (long*)0x80000e0000000000LL; /* base of synergy regs */ base = (long*)0x80000e0000000000LL; /* base of synergy regs */
for (off = 0x2a0; off < 0x2e0; off+=8) /* offset for VEC_MASK_{0-3}_A/B */ for (off = 0x2a0; off < 0x2e0; off+=8) /* offset for VEC_MASK_{0-3}_A/B */
......
...@@ -5,36 +5,21 @@ ...@@ -5,36 +5,21 @@
# #
# Copyright (C) 2000-2002 Silicon Graphics, Inc. All Rights Reserved. # Copyright (C) 2000-2002 Silicon Graphics, Inc. All Rights Reserved.
# #
# # Makefile for the sn kernel routines.
# Makefile for the linux kernel.
#
# Note! Dependencies are done automagically by 'make dep', which also
# removes any old dependencies. DON'T put your own dependencies here
# unless it's something special (ie not a .c file).
#
EXTRA_CFLAGS := -DLITTLE_ENDIAN EXTRA_CFLAGS := -DLITTLE_ENDIAN
export-objs = pciio.o hcl.o ifdef CONFIG_IA64_SGI_SN2
EXTRA_CFLAGS += -DSHUB_SWAP_WAR
obj-y := stubs.o sgi_if.o pciio.o xtalk.o xbow.o xswitch.o klgraph_hack.o \ endif
hcl.o labelcl.o invent.o klgraph.o klconflib.o sgi_io_sim.o \
module.o sgi_io_init.o klgraph_hack.o ml_SN_init.o \
ml_iograph.o hcl_util.o cdl.o hubdev.o hubspc.o \
alenlist.o pci_bus_cvlink.o \
eeprom.o pci.o pci_dma.o l1.o l1_command.o ate_utils.o \
ifconfig_net.o efi-rtc.o io.o
obj-$(CONFIG_IA64_SGI_SN1) += sn1/ml_SN_intr.o sn1/mem_refcnt.o sn1/hubcounters.o \ export-objs := hcl.o pci_dma.o
sn1/ip37.o sn1/huberror.o sn1/hub_intr.o sn1/pcibr.o
obj-$(CONFIG_IA64_SGI_SN2) += sn2/ml_SN_intr.o sn2/shub_intr.o sn2/shuberror.o \ obj-$(CONFIG_IA64_SGI_SN) += stubs.o sgi_if.o xswitch.o klgraph_hack.o \
sn2/bte_error.o \ hcl.o labelcl.o invent.o sgi_io_sim.o \
sn2/pcibr/pcibr_dvr.o sn2/pcibr/pcibr_ate.o \ klgraph_hack.o hcl_util.o cdl.o hubdev.o hubspc.o \
sn2/pcibr/pcibr_config.o sn2/pcibr/pcibr_dvr.o \ alenlist.o pci.o pci_dma.o ate_utils.o \
sn2/pcibr/pcibr_hints.o \ ifconfig_net.o io.o ifconfig_bus.o
sn2/pcibr/pcibr_idbg.o sn2/pcibr/pcibr_intr.o \
sn2/pcibr/pcibr_rrb.o sn2/pcibr/pcibr_slot.o
obj-$(CONFIG_PCIBA) += pciba.o obj-$(CONFIG_PCIBA) += pciba.o
......
...@@ -192,9 +192,9 @@ struct alenlist_s { ...@@ -192,9 +192,9 @@ struct alenlist_s {
#define AL_FIXED_SIZE 0x1 /* List is pre-allocated, and of fixed size */ #define AL_FIXED_SIZE 0x1 /* List is pre-allocated, and of fixed size */
zone_t *alenlist_zone = NULL; struct zone *alenlist_zone = NULL;
zone_t *alenlist_chunk_zone = NULL; struct zone *alenlist_chunk_zone = NULL;
zone_t *alenlist_cursor_zone = NULL; struct zone *alenlist_cursor_zone = NULL;
#if DEBUG #if DEBUG
int alenlist_count=0; /* Currently allocated Lists */ int alenlist_count=0; /* Currently allocated Lists */
......
/* $Id$ /* $Id: ate_utils.c,v 1.1 2002/02/28 17:31:25 marcelo Exp $
* *
* This file is subject to the terms and conditions of the GNU General Public * 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 * License. See the file "COPYING" in the main directory of this archive
......
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
* Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved. * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved.
*/ */
#include <linux/config.h>
#include <linux/types.h> #include <linux/types.h>
#include <asm/sn/sgi.h> #include <asm/sn/sgi.h>
#include <asm/io.h> #include <asm/io.h>
...@@ -19,6 +20,8 @@ ...@@ -19,6 +20,8 @@
/* these get called directly in cdl_add_connpt in fops bypass hack */ /* these get called directly in cdl_add_connpt in fops bypass hack */
extern int pcibr_attach(devfs_handle_t); extern int pcibr_attach(devfs_handle_t);
extern int xbow_attach(devfs_handle_t); extern int xbow_attach(devfs_handle_t);
extern int pic_attach(devfs_handle_t);
/* /*
* cdl: Connection and Driver List * cdl: Connection and Driver List
...@@ -35,13 +38,24 @@ struct cdl { ...@@ -35,13 +38,24 @@ struct cdl {
int (*attach) (devfs_handle_t); int (*attach) (devfs_handle_t);
} dummy_reg; } dummy_reg;
#ifdef CONFIG_IA64_SGI_SN1
#define MAX_SGI_IO_INFRA_DRVR 4 #define MAX_SGI_IO_INFRA_DRVR 4
struct cdl sgi_infrastructure_drivers[MAX_SGI_IO_INFRA_DRVR] = #else
#define MAX_SGI_IO_INFRA_DRVR 7
#endif
static struct cdl sgi_infrastructure_drivers[MAX_SGI_IO_INFRA_DRVR] =
{ {
{ XBRIDGE_WIDGET_PART_NUM, XBRIDGE_WIDGET_MFGR_NUM, pcibr_attach /* &pcibr_fops */}, { XBRIDGE_WIDGET_PART_NUM, XBRIDGE_WIDGET_MFGR_NUM, pcibr_attach /* &pcibr_fops */},
{ BRIDGE_WIDGET_PART_NUM, BRIDGE_WIDGET_MFGR_NUM, pcibr_attach /* &pcibr_fops */}, { BRIDGE_WIDGET_PART_NUM, BRIDGE_WIDGET_MFGR_NUM, pcibr_attach /* &pcibr_fops */},
#ifndef CONFIG_IA64_SGI_SN1
{ PIC_WIDGET_PART_NUM_BUS0, PIC_WIDGET_MFGR_NUM, pic_attach /* &pic_fops */},
{ PIC_WIDGET_PART_NUM_BUS1, PIC_WIDGET_MFGR_NUM, pic_attach /* &pic_fops */},
#endif
{ XXBOW_WIDGET_PART_NUM, XXBOW_WIDGET_MFGR_NUM, xbow_attach /* &xbow_fops */}, { XXBOW_WIDGET_PART_NUM, XXBOW_WIDGET_MFGR_NUM, xbow_attach /* &xbow_fops */},
{ XBOW_WIDGET_PART_NUM, XBOW_WIDGET_MFGR_NUM, xbow_attach /* &xbow_fops */}, { XBOW_WIDGET_PART_NUM, XBOW_WIDGET_MFGR_NUM, xbow_attach /* &xbow_fops */},
#ifndef CONFIG_IA64_SGI_SN1
{ PXBOW_WIDGET_PART_NUM, XXBOW_WIDGET_MFGR_NUM, xbow_attach /* &xbow_fops */},
#endif
}; };
/* /*
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
* *
* hcl - SGI's Hardware Graph compatibility layer. * hcl - SGI's Hardware Graph compatibility layer.
* *
* Copyright (C) 1992 - 1997, 2000-2001 Silicon Graphics, Inc. All rights reserved. * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved.
*/ */
#include <linux/types.h> #include <linux/types.h>
...@@ -155,7 +155,7 @@ int __init init_hcl(void) ...@@ -155,7 +155,7 @@ int __init init_hcl(void)
/* /*
* Create the hwgraph_root on devfs. * Create the hwgraph_root on devfs.
*/ */
rv = hwgraph_path_add(NULL, "hw", &hwgraph_root); rv = hwgraph_path_add(NULL, EDGE_LBL_HW, &hwgraph_root);
if (rv) if (rv)
printk ("WARNING: init_hcl: Failed to create hwgraph_root. Error = %d.\n", rv); printk ("WARNING: init_hcl: Failed to create hwgraph_root. Error = %d.\n", rv);
...@@ -183,9 +183,9 @@ int __init init_hcl(void) ...@@ -183,9 +183,9 @@ int __init init_hcl(void)
/* /*
* Create the directory that links Linux bus numbers to our Xwidget. * Create the directory that links Linux bus numbers to our Xwidget.
*/ */
rv = hwgraph_path_add(hwgraph_root, "linux/busnum", &linux_busnum); rv = hwgraph_path_add(hwgraph_root, EDGE_LBL_LINUX_BUS, &linux_busnum);
if (linux_busnum == NULL) { if (linux_busnum == NULL) {
panic("HCL: Unable to create hw/linux/busnum\n"); panic("HCL: Unable to create %s\n", EDGE_LBL_LINUX_BUS);
return(0); return(0);
} }
...@@ -673,9 +673,8 @@ hwgraph_edge_get(devfs_handle_t from, char *name, devfs_handle_t *toptr) ...@@ -673,9 +673,8 @@ hwgraph_edge_get(devfs_handle_t from, char *name, devfs_handle_t *toptr)
* Call devfs to get the devfs entry. * Call devfs to get the devfs entry.
*/ */
namelen = (int) strlen(name); namelen = (int) strlen(name);
target_handle = devfs_get_handle(from, name, 0, 0, target_handle = devfs_get_handle (from, name, 0, 0,
0, 1); /* Yes traverse symbolic links */ 0, 1); /* Yes traverse symbolic links */
devfs_put(target_handle); /* Assume we're the owner */
if (target_handle == NULL) if (target_handle == NULL)
return(-1); return(-1);
else else
...@@ -959,7 +958,6 @@ hwgraph_path_lookup( devfs_handle_t start_vertex_handle, ...@@ -959,7 +958,6 @@ hwgraph_path_lookup( devfs_handle_t start_vertex_handle,
0, /* minor */ 0, /* minor */
0, /* char | block */ 0, /* char | block */
1); /* traverse symlinks */ 1); /* traverse symlinks */
devfs_put(*vertex_handle_ptr); /* Assume we're the owner */
if (*vertex_handle_ptr == NULL) if (*vertex_handle_ptr == NULL)
return(-1); return(-1);
else else
...@@ -967,23 +965,22 @@ hwgraph_path_lookup( devfs_handle_t start_vertex_handle, ...@@ -967,23 +965,22 @@ hwgraph_path_lookup( devfs_handle_t start_vertex_handle,
} }
/* /*
* hwgraph_traverse - Find and return the devfs handle starting from dir. * hwgraph_traverse - Find and return the devfs handle starting from de.
* *
*/ */
graph_error_t graph_error_t
hwgraph_traverse(devfs_handle_t dir, char *path, devfs_handle_t *found) hwgraph_traverse(devfs_handle_t de, char *path, devfs_handle_t *found)
{ {
/* /*
* get the directory entry (path should end in a directory) * get the directory entry (path should end in a directory)
*/ */
*found = devfs_get_handle(dir, /* start dir */ *found = devfs_get_handle(de, /* start dir */
path, /* path */ path, /* path */
0, /* major */ 0, /* major */
0, /* minor */ 0, /* minor */
0, /* char | block */ 0, /* char | block */
1); /* traverse symlinks */ 1); /* traverse symlinks */
devfs_put(*found); /* Assume we're the owner */
if (*found == NULL) if (*found == NULL)
return(GRAPH_NOT_FOUND); return(GRAPH_NOT_FOUND);
else else
...@@ -997,16 +994,12 @@ hwgraph_traverse(devfs_handle_t dir, char *path, devfs_handle_t *found) ...@@ -997,16 +994,12 @@ hwgraph_traverse(devfs_handle_t dir, char *path, devfs_handle_t *found)
devfs_handle_t devfs_handle_t
hwgraph_path_to_vertex(char *path) hwgraph_path_to_vertex(char *path)
{ {
devfs_handle_t de; return(devfs_get_handle(NULL, /* start dir */
de = devfs_get_handle(NULL, /* start dir */
path, /* path */ path, /* path */
0, /* major */ 0, /* major */
0, /* minor */ 0, /* minor */
0, /* char | block */ 0, /* char | block */
1); 1)); /* traverse symlinks */
devfs_put(de); /* Assume we're the owner */
return(de);
} }
/* /*
...@@ -1024,40 +1017,32 @@ hwgraph_path_to_dev(char *path) ...@@ -1024,40 +1017,32 @@ hwgraph_path_to_dev(char *path)
/* /*
* hwgraph_block_device_get - return the handle of the block device file. * hwgraph_block_device_get - return the handle of the block device file.
* The assumption here is that dir is a directory. * The assumption here is that de is a directory.
*/ */
devfs_handle_t devfs_handle_t
hwgraph_block_device_get(devfs_handle_t dir) hwgraph_block_device_get(devfs_handle_t de)
{ {
devfs_handle_t de; return(devfs_get_handle(de, /* start dir */
de = devfs_get_handle(dir, /* start dir */
"block", /* path */ "block", /* path */
0, /* major */ 0, /* major */
0, /* minor */ 0, /* minor */
DEVFS_SPECIAL_BLK, /* char | block */ DEVFS_SPECIAL_BLK, /* char | block */
1); /* traverse symlinks */ 1)); /* traverse symlinks */
devfs_put(de); /* Assume we're the owner */
return(de);
} }
/* /*
* hwgraph_char_device_get - return the handle of the char device file. * hwgraph_char_device_get - return the handle of the char device file.
* The assumption here is that dir is a directory. * The assumption here is that de is a directory.
*/ */
devfs_handle_t devfs_handle_t
hwgraph_char_device_get(devfs_handle_t dir) hwgraph_char_device_get(devfs_handle_t de)
{ {
devfs_handle_t de; return(devfs_get_handle(de, /* start dir */
de = devfs_get_handle(dir, /* start dir */
"char", /* path */ "char", /* path */
0, /* major */ 0, /* major */
0, /* minor */ 0, /* minor */
DEVFS_SPECIAL_CHR, /* char | block */ DEVFS_SPECIAL_CHR, /* char | block */
1); /* traverse symlinks */ 1)); /* traverse symlinks */
devfs_put(de); /* Assume we're the owner */
return(de);
} }
/* /*
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
* License. See the file "COPYING" in the main directory of this archive * License. See the file "COPYING" in the main directory of this archive
* for more details. * for more details.
* *
* Copyright (C) 1992 - 1997, 2000-2001 Silicon Graphics, Inc. All rights reserved. * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved.
*/ */
#include <linux/types.h> #include <linux/types.h>
...@@ -96,6 +96,33 @@ master_node_get(devfs_handle_t vhdl) ...@@ -96,6 +96,33 @@ master_node_get(devfs_handle_t vhdl)
} }
} }
static devfs_handle_t hwgraph_all_cpuids = GRAPH_VERTEX_NONE;
extern int maxcpus;
void
mark_cpuvertex_as_cpu(devfs_handle_t vhdl, cpuid_t cpuid)
{
if (cpuid == CPU_NONE)
return;
(void)labelcl_info_add_LBL(vhdl, INFO_LBL_CPUID, INFO_DESC_EXPORT,
(arbitrary_info_t)cpuid);
{
char cpuid_buffer[10];
if (hwgraph_all_cpuids == GRAPH_VERTEX_NONE) {
(void)hwgraph_path_add( hwgraph_root,
EDGE_LBL_CPUNUM,
&hwgraph_all_cpuids);
}
sprintf(cpuid_buffer, "%ld", cpuid);
(void)hwgraph_edge_add( hwgraph_all_cpuids,
vhdl,
cpuid_buffer);
}
}
/* /*
** If the specified device represents a node, return its ** If the specified device represents a node, return its
** compact node ID; otherwise, return CNODEID_NONE. ** compact node ID; otherwise, return CNODEID_NONE.
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
* License. See the file "COPYING" in the main directory of this archive * License. See the file "COPYING" in the main directory of this archive
* for more details. * for more details.
* *
* Copyright (C) 1992 - 1997, 2000-2001 Silicon Graphics, Inc. All rights reserved. * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved.
*/ */
#include <linux/config.h> #include <linux/config.h>
......
...@@ -52,7 +52,7 @@ typedef struct cpuprom_info { ...@@ -52,7 +52,7 @@ typedef struct cpuprom_info {
}cpuprom_info_t; }cpuprom_info_t;
static cpuprom_info_t *cpuprom_head; static cpuprom_info_t *cpuprom_head;
spinlock_t cpuprom_spinlock; static spinlock_t cpuprom_spinlock;
#define PROM_LOCK() mutex_spinlock(&cpuprom_spinlock) #define PROM_LOCK() mutex_spinlock(&cpuprom_spinlock)
#define PROM_UNLOCK(s) mutex_spinunlock(&cpuprom_spinlock, (s)) #define PROM_UNLOCK(s) mutex_spinunlock(&cpuprom_spinlock, (s))
...@@ -161,69 +161,8 @@ cpuprom_detailed_inventory_info_add(devfs_handle_t prom_dev,devfs_handle_t node) ...@@ -161,69 +161,8 @@ cpuprom_detailed_inventory_info_add(devfs_handle_t prom_dev,devfs_handle_t node)
sizeof(invent_miscinfo_t)); sizeof(invent_miscinfo_t));
} }
#define FPROM_CONFIG_ADDR MD_JUNK_BUS_TIMING
#define FPROM_ENABLE_MASK MJT_FPROM_ENABLE_MASK
#define FPROM_ENABLE_SHFT MJT_FPROM_ENABLE_SHFT
#define FPROM_SETUP_MASK MJT_FPROM_SETUP_MASK
#define FPROM_SETUP_SHFT MJT_FPROM_SETUP_SHFT
/*ARGSUSED*/
int
cpuprom_map(devfs_handle_t dev, vhandl_t *vt, off_t addr, size_t len)
{
int errcode = 0;
caddr_t kvaddr;
devfs_handle_t node;
cnodeid_t cnode;
node = prominfo_nodeget(dev);
if (!node)
return EIO;
kvaddr = hubdev_prombase_get(node);
cnode = hubdev_cnodeid_get(node);
#ifdef HUBSPC_DEBUG
printk("cpuprom_map: hubnode %d kvaddr 0x%x\n", node, kvaddr);
#endif
if (len > RBOOT_SIZE)
len = RBOOT_SIZE;
/*
* Map in the prom space
*/
errcode = v_mapphys(vt, kvaddr, len);
if (errcode == 0 ){
/*
* Set the MD configuration registers suitably.
*/
nasid_t nasid;
uint64_t value;
volatile hubreg_t *regaddr;
nasid = COMPACT_TO_NASID_NODEID(cnode);
regaddr = REMOTE_HUB_ADDR(nasid, FPROM_CONFIG_ADDR);
value = HUB_L(regaddr);
value &= ~(FPROM_SETUP_MASK | FPROM_ENABLE_MASK);
{
value |= (((long)CONFIG_FPROM_SETUP << FPROM_SETUP_SHFT) |
((long)CONFIG_FPROM_ENABLE << FPROM_ENABLE_SHFT));
}
HUB_S(regaddr, value);
}
return (errcode);
}
#endif /* CONFIG_IA64_SGI_SN1 */ #endif /* CONFIG_IA64_SGI_SN1 */
/*ARGSUSED*/
int
cpuprom_unmap(devfs_handle_t dev, vhandl_t *vt)
{
return 0;
}
/***********************************************************************/ /***********************************************************************/
/* Base Hub Space Driver */ /* Base Hub Space Driver */
...@@ -245,15 +184,14 @@ hubspc_init(void) ...@@ -245,15 +184,14 @@ hubspc_init(void)
hubdev_register(mem_refcnt_attach); hubdev_register(mem_refcnt_attach);
#endif #endif
#if defined(CONFIG_SERIAL_SGI_L1_PROTOCOL) #ifdef CONFIG_IA64_SGI_SN1
/* L1 system controller link */ /* L1 system controller link */
if ( !IS_RUNNING_ON_SIMULATOR() ) { if ( !IS_RUNNING_ON_SIMULATOR() ) {
/* initialize the L1 link */ /* initialize the L1 link */
extern void l1_init(void); extern void l1_init(void);
l1_init(); l1_init();
} }
#endif #endif /* CONFIG_IA64_SGI_SN1 */
#ifdef HUBSPC_DEBUG #ifdef HUBSPC_DEBUG
printk("hubspc_init: Completed\n"); printk("hubspc_init: Completed\n");
#endif /* HUBSPC_DEBUG */ #endif /* HUBSPC_DEBUG */
...@@ -285,7 +223,7 @@ hubspc_map(devfs_handle_t dev, vhandl_t *vt, off_t off, size_t len, uint prot) ...@@ -285,7 +223,7 @@ hubspc_map(devfs_handle_t dev, vhandl_t *vt, off_t off, size_t len, uint prot)
/* check validity of request */ /* check validity of request */
if( len == 0 ) { if( len == 0 ) {
return ENXIO; return -ENXIO;
} }
return errcode; return errcode;
......
/* $Id$ /* $Id: ifconfig_net.c,v 1.1 2002/02/28 17:31:25 marcelo Exp $
* *
* This file is subject to the terms and conditions of the GNU General Public * 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 * License. See the file "COPYING" in the main directory of this archive
...@@ -202,30 +202,16 @@ static int ifconfig_net_ioctl(struct inode * inode, struct file * file, ...@@ -202,30 +202,16 @@ static int ifconfig_net_ioctl(struct inode * inode, struct file * file,
* Read in the header and see how big of a buffer we really need to * Read in the header and see how big of a buffer we really need to
* allocate. * allocate.
*/ */
ifname_num = kmalloc(sizeof(struct ifname_num), GFP_KERNEL); ifname_num = (struct ifname_num *) kmalloc(sizeof(struct ifname_num),
if (!ifname_num) GFP_KERNEL);
return -ENOMEM; copy_from_user( ifname_num, (char *) arg, sizeof(struct ifname_num));
if (copy_from_user(ifname_num, (char *)arg,
sizeof(struct ifname_num))) {
kfree(ifname_num);
return -EFAULT;
}
size = ifname_num->size; size = ifname_num->size;
kfree(ifname_num); kfree(ifname_num);
ifname_num = kmalloc(size, GFP_KERNEL); ifname_num = (struct ifname_num *) kmalloc(size, GFP_KERNEL);
if (!ifname_num)
return -ENOMEM;
ifname_MAC = (struct ifname_MAC *) ((char *)ifname_num + (sizeof(struct ifname_num)) ); ifname_MAC = (struct ifname_MAC *) ((char *)ifname_num + (sizeof(struct ifname_num)) );
if (copy_from_user(ifname_num, (char *)arg, size)) { copy_from_user( ifname_num, (char *) arg, size);
kfree(ifname_num);
return -EFAULT;
}
new_devices = kmalloc(size - sizeof(struct ifname_num), GFP_KERNEL); new_devices = kmalloc(size - sizeof(struct ifname_num), GFP_KERNEL);
if (!new_devices) {
kfree(ifname_num);
return -EFAULT;
}
temp_new_devices = new_devices; temp_new_devices = new_devices;
memset(new_devices, 0, size - sizeof(struct ifname_num)); memset(new_devices, 0, size - sizeof(struct ifname_num));
...@@ -271,17 +257,17 @@ static int ifconfig_net_ioctl(struct inode * inode, struct file * file, ...@@ -271,17 +257,17 @@ static int ifconfig_net_ioctl(struct inode * inode, struct file * file,
/* /*
* Copy back to the User Buffer area any new devices encountered. * Copy back to the User Buffer area any new devices encountered.
*/ */
if (copy_to_user((char *)arg + (sizeof(struct ifname_num)), copy_to_user((char *)arg + (sizeof(struct ifname_num)), new_devices,
new_devices, size - sizeof(struct ifname_num))) size - sizeof(struct ifname_num));
return -EFAULT;
return(0); return(0);
} }
struct file_operations ifconfig_net_fops = { struct file_operations ifconfig_net_fops = {
.ioctl =ifconfig_net_ioctl, /* ioctl */ ioctl:ifconfig_net_ioctl, /* ioctl */
.open =ifconfig_net_open, /* open */ open:ifconfig_net_open, /* open */
.release =ifconfig_net_close /* release */ release:ifconfig_net_close /* release */
}; };
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
* License. See the file "COPYING" in the main directory of this archive * License. See the file "COPYING" in the main directory of this archive
* for more details. * for more details.
* *
* Copyright (C) 1992 - 1997, 2000-2001 Silicon Graphics, Inc. All rights reserved. * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved.
*/ */
/* /*
......
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
* Copyright (C) 1992-1997, 2000-2002 Silicon Graphics, Inc. All Rights Reserved. * Copyright (C) 1992-1997, 2000-2002 Silicon Graphics, Inc. All Rights Reserved.
*/ */
#include <linux/config.h>
#include <linux/types.h> #include <linux/types.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <asm/sn/types.h> #include <asm/sn/types.h>
...@@ -31,21 +32,6 @@ extern xtalk_provider_t hub_provider; ...@@ -31,21 +32,6 @@ extern xtalk_provider_t hub_provider;
extern void hub_intr_init(devfs_handle_t hubv); extern void hub_intr_init(devfs_handle_t hubv);
/*
* hub_device_desc_update
* Update the passed in device descriptor with the actual the
* target cpu number and interrupt priority level.
* NOTE : These might be the same as the ones passed in thru
* the descriptor.
*/
void
hub_device_desc_update(device_desc_t dev_desc,
ilvl_t intr_swlevel,
cpuid_t cpu)
{
}
/* /*
* Perform any initializations needed to support hub-based I/O. * Perform any initializations needed to support hub-based I/O.
* Called once during startup. * Called once during startup.
...@@ -53,11 +39,6 @@ hub_device_desc_update(device_desc_t dev_desc, ...@@ -53,11 +39,6 @@ hub_device_desc_update(device_desc_t dev_desc,
void void
hubio_init(void) hubio_init(void)
{ {
#ifdef LATER
/* This isn't needed unless we port the entire sio driver ... */
extern void early_brl1_port_init( void );
early_brl1_port_init();
#endif
} }
/* /*
...@@ -149,6 +130,10 @@ hub_piomap_alloc(devfs_handle_t dev, /* set up mapping for this device */ ...@@ -149,6 +130,10 @@ hub_piomap_alloc(devfs_handle_t dev, /* set up mapping for this device */
nasid_t nasid; nasid_t nasid;
volatile hubreg_t junk; volatile hubreg_t junk;
unsigned long s; unsigned long s;
caddr_t kvaddr;
#ifdef PIOMAP_UNC_ACC_SPACE
uint64_t addr;
#endif
/* sanity check */ /* sanity check */
if (byte_count_max > byte_count) if (byte_count_max > byte_count)
...@@ -159,8 +144,19 @@ hub_piomap_alloc(devfs_handle_t dev, /* set up mapping for this device */ ...@@ -159,8 +144,19 @@ hub_piomap_alloc(devfs_handle_t dev, /* set up mapping for this device */
/* If xtalk_addr range is mapped by a small window, we don't have /* If xtalk_addr range is mapped by a small window, we don't have
* to do much * to do much
*/ */
if (xtalk_addr + byte_count <= SWIN_SIZE) if (xtalk_addr + byte_count <= SWIN_SIZE) {
return(hubinfo_swin_piomap_get(hubinfo, (int)widget)); hub_piomap_t piomap;
piomap = hubinfo_swin_piomap_get(hubinfo, (int)widget);
#ifdef PIOMAP_UNC_ACC_SPACE
if (flags & PIOMAP_UNC_ACC) {
addr = (uint64_t)piomap->hpio_xtalk_info.xp_kvaddr;
addr |= PIOMAP_UNC_ACC_SPACE;
piomap->hpio_xtalk_info.xp_kvaddr = (caddr_t)addr;
}
#endif
return piomap;
}
/* We need to use a big window mapping. */ /* We need to use a big window mapping. */
...@@ -257,7 +253,15 @@ hub_piomap_alloc(devfs_handle_t dev, /* set up mapping for this device */ ...@@ -257,7 +253,15 @@ hub_piomap_alloc(devfs_handle_t dev, /* set up mapping for this device */
bw_piomap->hpio_xtalk_info.xp_dev = dev; bw_piomap->hpio_xtalk_info.xp_dev = dev;
bw_piomap->hpio_xtalk_info.xp_target = widget; bw_piomap->hpio_xtalk_info.xp_target = widget;
bw_piomap->hpio_xtalk_info.xp_xtalk_addr = xtalk_addr; bw_piomap->hpio_xtalk_info.xp_xtalk_addr = xtalk_addr;
bw_piomap->hpio_xtalk_info.xp_kvaddr = (caddr_t)NODE_BWIN_BASE(nasid, free_bw_index); kvaddr = (caddr_t)NODE_BWIN_BASE(nasid, free_bw_index);
#ifdef PIOMAP_UNC_ACC_SPACE
if (flags & PIOMAP_UNC_ACC) {
addr = (uint64_t)kvaddr;
addr |= PIOMAP_UNC_ACC_SPACE;
kvaddr = (caddr_t)addr;
}
#endif
bw_piomap->hpio_xtalk_info.xp_kvaddr = kvaddr;
bw_piomap->hpio_holdcnt++; bw_piomap->hpio_holdcnt++;
bw_piomap->hpio_bigwin_num = free_bw_index; bw_piomap->hpio_bigwin_num = free_bw_index;
...@@ -378,12 +382,22 @@ hub_piotrans_addr( devfs_handle_t dev, /* translate to this device */ ...@@ -378,12 +382,22 @@ hub_piotrans_addr( devfs_handle_t dev, /* translate to this device */
devfs_handle_t hubv = xwidget_info_master_get(widget_info); devfs_handle_t hubv = xwidget_info_master_get(widget_info);
hub_piomap_t hub_piomap; hub_piomap_t hub_piomap;
hubinfo_t hubinfo; hubinfo_t hubinfo;
caddr_t addr;
hubinfo_get(hubv, &hubinfo); hubinfo_get(hubv, &hubinfo);
if (xtalk_addr + byte_count <= SWIN_SIZE) { if (xtalk_addr + byte_count <= SWIN_SIZE) {
hub_piomap = hubinfo_swin_piomap_get(hubinfo, (int)widget); hub_piomap = hubinfo_swin_piomap_get(hubinfo, (int)widget);
return(hub_piomap_addr(hub_piomap, xtalk_addr, byte_count)); addr = hub_piomap_addr(hub_piomap, xtalk_addr, byte_count);
#ifdef PIOMAP_UNC_ACC_SPACE
if (flags & PIOMAP_UNC_ACC) {
uint64_t iaddr;
iaddr = (uint64_t)addr;
iaddr |= PIOMAP_UNC_ACC_SPACE;
addr = (caddr_t)iaddr;
}
#endif
return(addr);
} else } else
return(0); return(0);
} }
...@@ -392,19 +406,6 @@ hub_piotrans_addr( devfs_handle_t dev, /* translate to this device */ ...@@ -392,19 +406,6 @@ hub_piotrans_addr( devfs_handle_t dev, /* translate to this device */
/* DMA MANAGEMENT */ /* DMA MANAGEMENT */
/* Mapping from crosstalk space to system physical space */ /* Mapping from crosstalk space to system physical space */
/*
* There's not really very much to do here, since crosstalk maps
* directly to system physical space. It's quite possible that this
* DMA layer will be bypassed in performance kernels.
*/
/* ARGSUSED */
void
hub_dma_init(devfs_handle_t hubv)
{
}
/* /*
* Allocate resources needed to set up DMA mappings up to a specified size * Allocate resources needed to set up DMA mappings up to a specified size
...@@ -478,7 +479,12 @@ hub_dmamap_addr( hub_dmamap_t dmamap, /* use these mapping resources */ ...@@ -478,7 +479,12 @@ hub_dmamap_addr( hub_dmamap_t dmamap, /* use these mapping resources */
} }
/* There isn't actually any DMA mapping hardware on the hub. */ /* There isn't actually any DMA mapping hardware on the hub. */
#ifdef CONFIG_IA64_SGI_SN2
return( (PHYS_TO_DMA(paddr)) );
#else
/* no translation needed */
return(paddr); return(paddr);
#endif
} }
/* /*
...@@ -549,8 +555,12 @@ hub_dmatrans_addr( devfs_handle_t dev, /* translate for this device */ ...@@ -549,8 +555,12 @@ hub_dmatrans_addr( devfs_handle_t dev, /* translate for this device */
size_t byte_count, /* length */ size_t byte_count, /* length */
unsigned flags) /* defined in dma.h */ unsigned flags) /* defined in dma.h */
{ {
#ifdef CONFIG_IA64_SGI_SN2
return( (PHYS_TO_DMA(paddr)) );
#else
/* no translation needed */ /* no translation needed */
return(paddr); return(paddr);
#endif
} }
/* /*
...@@ -565,6 +575,7 @@ hub_dmatrans_list( devfs_handle_t dev, /* translate for this device */ ...@@ -565,6 +575,7 @@ hub_dmatrans_list( devfs_handle_t dev, /* translate for this device */
alenlist_t palenlist, /* system address/length list */ alenlist_t palenlist, /* system address/length list */
unsigned flags) /* defined in dma.h */ unsigned flags) /* defined in dma.h */
{ {
BUG();
/* no translation needed */ /* no translation needed */
return(palenlist); return(palenlist);
} }
...@@ -603,11 +614,9 @@ hub_dmalist_drain( devfs_handle_t vhdl, ...@@ -603,11 +614,9 @@ hub_dmalist_drain( devfs_handle_t vhdl,
void void
hub_provider_startup(devfs_handle_t hubv) hub_provider_startup(devfs_handle_t hubv)
{ {
extern void hub_dma_init(devfs_handle_t hubv);
extern void hub_pio_init(devfs_handle_t hubv); extern void hub_pio_init(devfs_handle_t hubv);
hub_pio_init(hubv); hub_pio_init(hubv);
hub_dma_init(hubv);
hub_intr_init(hubv); hub_intr_init(hubv);
} }
...@@ -707,14 +716,12 @@ hub_setup_prb(nasid_t nasid, int prbnum, int credits, int conveyor) ...@@ -707,14 +716,12 @@ hub_setup_prb(nasid_t nasid, int prbnum, int credits, int conveyor)
{ {
iprb_t prb; iprb_t prb;
int prb_offset; int prb_offset;
#ifdef LATER
extern int force_fire_and_forget; extern int force_fire_and_forget;
extern volatile int ignore_conveyor_override; extern volatile int ignore_conveyor_override;
if (force_fire_and_forget && !ignore_conveyor_override) if (force_fire_and_forget && !ignore_conveyor_override)
if (conveyor == HUB_PIO_CONVEYOR) if (conveyor == HUB_PIO_CONVEYOR)
conveyor = HUB_PIO_FIRE_N_FORGET; conveyor = HUB_PIO_FIRE_N_FORGET;
#endif
/* /*
* Get the current register value. * Get the current register value.
......
This diff is collapsed.
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
* License. See the file "COPYING" in the main directory of this archive * License. See the file "COPYING" in the main directory of this archive
* for more details. * for more details.
* *
* Copyright (c) 2001 Silicon Graphics, Inc. All rights reserved. * Copyright (c) 2001-2002 Silicon Graphics, Inc. All rights reserved.
*/ */
#include <linux/types.h> #include <linux/types.h>
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
* License. See the file "COPYING" in the main directory of this archive * License. See the file "COPYING" in the main directory of this archive
* for more details. * for more details.
* *
* Copyright (c) 1997, 1998, 2000-2001 Silicon Graphics, Inc. All rights reserved. * Copyright (c) 1997, 1998, 2000-2002 Silicon Graphics, Inc. All rights reserved.
*/ */
#include <linux/init.h> #include <linux/init.h>
#include <linux/types.h> #include <linux/types.h>
...@@ -44,21 +44,22 @@ extern devfs_handle_t pci_bus_to_vertex(unsigned char); ...@@ -44,21 +44,22 @@ extern devfs_handle_t pci_bus_to_vertex(unsigned char);
extern devfs_handle_t devfn_to_vertex(unsigned char bus, unsigned char devfn); extern devfs_handle_t devfn_to_vertex(unsigned char bus, unsigned char devfn);
/* /*
* snia64_read - Read from the config area of the device. * snia64_read_config_byte - Read a byte from the config area of the device.
*/ */
static int snia64_read (struct pci_bus *bus, unsigned char devfn, static int snia64_read_config_byte (struct pci_dev *dev,
int where, int size, unsigned char *val) int where, unsigned char *val)
{ {
unsigned long res = 0; unsigned long res = 0;
unsigned size = 1;
devfs_handle_t device_vertex; devfs_handle_t device_vertex;
if ( (bus == NULL) || (val == (unsigned char *)0) ) { if ( (dev == (struct pci_dev *)0) || (val == (unsigned char *)0) ) {
return PCIBIOS_DEVICE_NOT_FOUND; return PCIBIOS_DEVICE_NOT_FOUND;
} }
device_vertex = devfn_to_vertex(bus->number, devfn); device_vertex = devfn_to_vertex(dev->bus->number, dev->devfn);
if (!device_vertex) { if (!device_vertex) {
DBG("%s : nonexistent device: bus= 0x%x slot= 0x%x func= 0x%x\n", DBG("%s : nonexistent device: bus= 0x%x slot= 0x%x func= 0x%x\n",
__FUNCTION__, bus->number, PCI_SLOT(devfn), PCI_FUNC(devfn)); __FUNCTION__, dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn));
return(-1); return(-1);
} }
res = pciio_config_get(device_vertex, (unsigned) where, size); res = pciio_config_get(device_vertex, (unsigned) where, size);
...@@ -67,49 +68,169 @@ static int snia64_read (struct pci_bus *bus, unsigned char devfn, ...@@ -67,49 +68,169 @@ static int snia64_read (struct pci_bus *bus, unsigned char devfn,
} }
/* /*
* snia64_write - Writes to the config area of the device. * snia64_read_config_word - Read 2 bytes from the config area of the device.
*/ */
static int snia64_write (struct pci_bus *bus, unsigned char devfn, static int snia64_read_config_word (struct pci_dev *dev,
int where, int size, unsigned char val) int where, unsigned short *val)
{ {
unsigned long res = 0;
unsigned size = 2; /* 2 bytes */
devfs_handle_t device_vertex; devfs_handle_t device_vertex;
if ( bus == NULL) { if ( (dev == (struct pci_dev *)0) || (val == (unsigned short *)0) ) {
return PCIBIOS_DEVICE_NOT_FOUND;
}
device_vertex = devfn_to_vertex(dev->bus->number, dev->devfn);
if (!device_vertex) {
DBG("%s : nonexistent device: bus= 0x%x slot= 0x%x func= 0x%x\n",
__FUNCTION__, dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn));
return(-1);
}
res = pciio_config_get(device_vertex, (unsigned) where, size);
*val = (unsigned short) res;
return PCIBIOS_SUCCESSFUL;
}
/*
* snia64_read_config_dword - Read 4 bytes from the config area of the device.
*/
static int snia64_read_config_dword (struct pci_dev *dev,
int where, unsigned int *val)
{
unsigned long res = 0;
unsigned size = 4; /* 4 bytes */
devfs_handle_t device_vertex;
if (where & 3) {
return PCIBIOS_BAD_REGISTER_NUMBER;
}
if ( (dev == (struct pci_dev *)0) || (val == (unsigned int *)0) ) {
return PCIBIOS_DEVICE_NOT_FOUND;
}
device_vertex = devfn_to_vertex(dev->bus->number, dev->devfn);
if (!device_vertex) {
DBG("%s : nonexistent device: bus= 0x%x slot= 0x%x func= 0x%x\n",
__FUNCTION__, dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn));
return(-1);
}
res = pciio_config_get(device_vertex, (unsigned) where, size);
*val = (unsigned int) res;
return PCIBIOS_SUCCESSFUL;
}
/*
* snia64_write_config_byte - Writes 1 byte to the config area of the device.
*/
static int snia64_write_config_byte (struct pci_dev *dev,
int where, unsigned char val)
{
devfs_handle_t device_vertex;
if ( dev == (struct pci_dev *)0 ) {
return PCIBIOS_DEVICE_NOT_FOUND; return PCIBIOS_DEVICE_NOT_FOUND;
} }
/* /*
* if it's an IOC3 then we bail out, we special * if it's an IOC3 then we bail out, we special
* case them with pci_fixup_ioc3 * case them with pci_fixup_ioc3
*/ */
/* Starting 2.5.32 struct pci_dev is not passed down */ if (dev->vendor == PCI_VENDOR_ID_SGI &&
/*if (dev->vendor == PCI_VENDOR_ID_SGI &&
dev->device == PCI_DEVICE_ID_SGI_IOC3 ) dev->device == PCI_DEVICE_ID_SGI_IOC3 )
return PCIBIOS_SUCCESSFUL; return PCIBIOS_SUCCESSFUL;
device_vertex = devfn_to_vertex(dev->bus->number, dev->devfn);
if (!device_vertex) {
DBG("%s : nonexistent device: bus= 0x%x slot= 0x%x func= 0x%x\n",
__FUNCTION__, dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn));
return(-1);
}
pciio_config_set( device_vertex, (unsigned)where, 1, (uint64_t) val);
return PCIBIOS_SUCCESSFUL;
}
/*
* snia64_write_config_word - Writes 2 bytes to the config area of the device.
*/
static int snia64_write_config_word (struct pci_dev *dev,
int where, unsigned short val)
{
devfs_handle_t device_vertex = NULL;
if (where & 1) {
return PCIBIOS_BAD_REGISTER_NUMBER;
}
if ( dev == (struct pci_dev *)0 ) {
return PCIBIOS_DEVICE_NOT_FOUND;
}
/*
* if it's an IOC3 then we bail out, we special
* case them with pci_fixup_ioc3
*/
if (dev->vendor == PCI_VENDOR_ID_SGI &&
dev->device == PCI_DEVICE_ID_SGI_IOC3)
return PCIBIOS_SUCCESSFUL;
device_vertex = devfn_to_vertex(dev->bus->number, dev->devfn);
if (!device_vertex) {
DBG("%s : nonexistent device: bus= 0x%x slot= 0x%x func= 0x%x\n",
__FUNCTION__, dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn));
return(-1);
}
pciio_config_set( device_vertex, (unsigned)where, 2, (uint64_t) val);
return PCIBIOS_SUCCESSFUL;
}
/*
* snia64_write_config_dword - Writes 4 bytes to the config area of the device.
*/
static int snia64_write_config_dword (struct pci_dev *dev,
int where, unsigned int val)
{
devfs_handle_t device_vertex;
if (where & 3) {
return PCIBIOS_BAD_REGISTER_NUMBER;
}
if ( dev == (struct pci_dev *)0 ) {
return PCIBIOS_DEVICE_NOT_FOUND;
}
/*
* if it's an IOC3 then we bail out, we special
* case them with pci_fixup_ioc3
*/ */
if (dev->vendor == PCI_VENDOR_ID_SGI &&
dev->device == PCI_DEVICE_ID_SGI_IOC3)
return PCIBIOS_SUCCESSFUL;
device_vertex = devfn_to_vertex(bus->number, devfn); device_vertex = devfn_to_vertex(dev->bus->number, dev->devfn);
if (!device_vertex) { if (!device_vertex) {
DBG("%s : nonexistent device: bus= 0x%x slot= 0x%x func= 0x%x\n", DBG("%s : nonexistent device: bus= 0x%x slot= 0x%x func= 0x%x\n",
__FUNCTION__, bus->number, PCI_SLOT(devfn), PCI_FUNC(devfn)); __FUNCTION__, dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn));
return(-1); return(-1);
} }
pciio_config_set( device_vertex, (unsigned)where, size, (uint64_t) val); pciio_config_set( device_vertex, (unsigned)where, 4, (uint64_t) val);
return PCIBIOS_SUCCESSFUL; return PCIBIOS_SUCCESSFUL;
} }
static struct pci_ops snia64_pci_ops = { static struct pci_ops snia64_pci_ops = {
.read = snia64_read, snia64_read_config_byte,
.write = snia64_write, snia64_read_config_word,
snia64_read_config_dword,
snia64_write_config_byte,
snia64_write_config_word,
snia64_write_config_dword
}; };
/* /*
* snia64_pci_find_bios - SNIA64 pci_find_bios() platform specific code. * snia64_pci_find_bios - SNIA64 pci_find_bios() platform specific code.
*/ */
void __init void __init
sn1_pci_find_bios(void) sn_pci_find_bios(void)
{ {
extern struct pci_ops pci_conf; extern struct pci_ops *pci_root_ops;
/* /*
* Go initialize our IO Infrastructure .. * Go initialize our IO Infrastructure ..
*/ */
...@@ -117,8 +238,8 @@ sn1_pci_find_bios(void) ...@@ -117,8 +238,8 @@ sn1_pci_find_bios(void)
sgi_master_io_infr_init(); sgi_master_io_infr_init();
/* sn1_io_infrastructure_init(); */ /* sn_io_infrastructure_init(); */
pci_conf = snia64_pci_ops; pci_root_ops = &snia64_pci_ops;
} }
void void
...@@ -155,22 +276,16 @@ pci_fixup_ioc3(struct pci_dev *d) ...@@ -155,22 +276,16 @@ pci_fixup_ioc3(struct pci_dev *d)
d->resource[i].flags = 0UL; d->resource[i].flags = 0UL;
} }
/* #ifdef CONFIG_IA64_SGI_SN1
* Hardcode Device 4 register(IOC3 is in Slot 4) to set the
* DEV_DIRECT bit. This will not work if IOC3 is not on Slot
* 4.
*/
DBG("pci_fixup_ioc3: FIXME .. need to take NASID into account when setting IOC3 devreg 0x%x\n", *(volatile u32 *)0xc0000a000f000220);
*(volatile u32 *)0xc0000a000f000220 |= 0x90000; *(volatile u32 *)0xc0000a000f000220 |= 0x90000;
#endif
d->subsystem_vendor = 0; d->subsystem_vendor = 0;
d->subsystem_device = 0; d->subsystem_device = 0;
} }
#else #else
void sn1_pci_find_bios(void) {} void sn_pci_find_bios(void) {}
void pci_fixup_ioc3(struct pci_dev *d) {} void pci_fixup_ioc3(struct pci_dev *d) {}
struct list_head pci_root_buses; struct list_head pci_root_buses;
struct list_head pci_root_buses; struct list_head pci_root_buses;
......
This diff is collapsed.
...@@ -210,31 +210,31 @@ static void dump_allocations(struct list_head * dalp); ...@@ -210,31 +210,31 @@ static void dump_allocations(struct list_head * dalp);
/* file operations for each type of node */ /* file operations for each type of node */
static struct file_operations rom_fops = { static struct file_operations rom_fops = {
.owner = THIS_MODULE, owner: THIS_MODULE,
.mmap = rom_mmap, mmap: rom_mmap,
.open = generic_open, open: generic_open,
.release = rom_release release: rom_release
}; };
static struct file_operations base_fops = { static struct file_operations base_fops = {
.owner = THIS_MODULE, owner: THIS_MODULE,
.mmap = base_mmap, mmap: base_mmap,
.open = generic_open open: generic_open
}; };
static struct file_operations config_fops = { static struct file_operations config_fops = {
.owner = THIS_MODULE, owner: THIS_MODULE,
.ioctl = config_ioctl, ioctl: config_ioctl,
.open = generic_open open: generic_open
}; };
static struct file_operations dma_fops = { static struct file_operations dma_fops = {
.owner = THIS_MODULE, owner: THIS_MODULE,
.ioctl = dma_ioctl, ioctl: dma_ioctl,
.mmap = dma_mmap, mmap: dma_mmap,
.open = generic_open open: generic_open
}; };
...@@ -285,45 +285,6 @@ free_nodes(void) ...@@ -285,45 +285,6 @@ free_nodes(void)
static devfs_handle_t pciba_devfs_handle; static devfs_handle_t pciba_devfs_handle;
#if !defined(CONFIG_IA64_SGI_SN1)
static status __init
register_with_devfs(void)
{
struct pci_dev * dev;
devfs_handle_t device_dir_handle;
char devfs_path[40];
TRACE();
pciba_devfs_handle = devfs_mk_dir(NULL, "pci", NULL);
if (pciba_devfs_handle == NULL)
return failure;
/* FIXME: don't forget /dev/pci/mem & /dev/pci/io */
pci_for_each_dev(dev) {
sprintf(devfs_path, "%02x/%02x.%x",
dev->bus->number,
PCI_SLOT(dev->devfn),
PCI_FUNC(dev->devfn));
device_dir_handle =
devfs_mk_dir(pciba_devfs_handle, devfs_path, NULL);
if (device_dir_handle == NULL)
return failure;
if (register_pci_device(device_dir_handle, dev) == failure) {
devfs_unregister(pciba_devfs_handle);
return failure;
}
}
return success;
}
#else
extern devfs_handle_t extern devfs_handle_t
devfn_to_vertex(unsigned char busnum, unsigned int devfn); devfn_to_vertex(unsigned char busnum, unsigned int devfn);
...@@ -352,9 +313,6 @@ register_with_devfs(void) ...@@ -352,9 +313,6 @@ register_with_devfs(void)
return success; return success;
} }
#endif /* CONFIG_IA64_SGI_SN1 */
static void __exit static void __exit
unregister_with_devfs(void) unregister_with_devfs(void)
{ {
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
* License. See the file "COPYING" in the main directory of this archive * License. See the file "COPYING" in the main directory of this archive
* for more details. * for more details.
* *
* Copyright (C) 1992 - 1997, 2000-2001 Silicon Graphics, Inc. All rights reserved. * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved.
*/ */
#include <linux/types.h> #include <linux/types.h>
...@@ -20,14 +20,50 @@ ...@@ -20,14 +20,50 @@
#include <asm/sn/pci/pciio.h> #include <asm/sn/pci/pciio.h>
#include <asm/sn/slotnum.h> #include <asm/sn/slotnum.h>
unsigned char Is_pic_on_this_nasid[512]; /* non-0 when this is a pic shub */
void * void *
snia_kmem_zalloc(size_t size, int flag) snia_kmem_zalloc(size_t size, int flag)
{ {
void *ptr = kmalloc(size, GFP_KERNEL); void *ptr = kmalloc(size, GFP_KERNEL);
if ( ptr )
BZERO(ptr, size); BZERO(ptr, size);
return ptr; return(ptr);
}
void
snia_kmem_free(void *ptr, size_t size)
{
kfree(ptr);
}
int
nic_vertex_info_match(devfs_handle_t v, char *s)
{
/* we don't support this */
return(0);
} }
/*
* the alloc/free_node routines do a simple kmalloc for now ..
*/
void *
snia_kmem_alloc_node(register size_t size, register int flags, cnodeid_t node)
{
/* someday will Allocate on node 'node' */
return(kmalloc(size, GFP_KERNEL));
}
void *
snia_kmem_zalloc_node(register size_t size, register int flags, cnodeid_t node)
{
void *ptr = kmalloc(size, GFP_KERNEL);
if ( ptr )
BZERO(ptr, size);
return(ptr);
}
#define xtod(c) ((c) <= '9' ? '0' - (c) : 'a' - (c) - 10) #define xtod(c) ((c) <= '9' ? '0' - (c) : 'a' - (c) - 10)
long long
atoi(register char *p) atoi(register char *p)
...@@ -67,3 +103,111 @@ atoi(register char *p) ...@@ -67,3 +103,111 @@ atoi(register char *p)
} }
return (neg ? n : -n); return (neg ? n : -n);
} }
char *
strtok_r(char *string, const char *sepset, char **lasts)
{
register char *q, *r;
/*first or subsequent call*/
if (string == NULL)
string = *lasts;
if(string == 0) /* return if no tokens remaining */
return(NULL);
q = string + strspn(string, sepset); /* skip leading separators */
if(*q == '\0') { /* return if no tokens remaining */
*lasts = 0; /* indicate this is last token */
return(NULL);
}
if((r = strpbrk(q, sepset)) == NULL) /* move past token */
*lasts = 0; /* indicate this is last token */
else {
*r = '\0';
*lasts = r+1;
}
return(q);
}
/*
* print_register() allows formatted printing of bit fields. individual
* bit fields are described by a struct reg_desc, multiple bit fields within
* a single word can be described by multiple reg_desc structures.
* %r outputs a string of the format "<bit field descriptions>"
* %R outputs a string of the format "0x%x<bit field descriptions>"
*
* The fields in a reg_desc are:
* unsigned long long rd_mask; An appropriate mask to isolate the bit field
* within a word, and'ed with val
*
* int rd_shift; A shift amount to be done to the isolated
* bit field. done before printing the isolate
* bit field with rd_format and before searching
* for symbolic value names in rd_values
*
* char *rd_name; If non-null, a bit field name to label any
* out from rd_format or searching rd_values.
* if neither rd_format or rd_values is non-null
* rd_name is printed only if the isolated
* bit field is non-null.
*
* char *rd_format; If non-null, the shifted bit field value
* is printed using this format.
*
* struct reg_values *rd_values; If non-null, a pointer to a table
* matching numeric values with symbolic names.
* rd_values are searched and the symbolic
* value is printed if a match is found, if no
* match is found "???" is printed.
*
*/
void
print_register(unsigned long long reg, struct reg_desc *addr)
{
register struct reg_desc *rd;
register struct reg_values *rv;
unsigned long long field;
int any;
printk("<");
any = 0;
for (rd = addr; rd->rd_mask; rd++) {
field = reg & rd->rd_mask;
field = (rd->rd_shift > 0) ? field << rd->rd_shift : field >> -rd->rd_shift;
if (any && (rd->rd_format || rd->rd_values || (rd->rd_name && field)))
printk(",");
if (rd->rd_name) {
if (rd->rd_format || rd->rd_values || field) {
printk("%s", rd->rd_name);
any = 1;
}
if (rd->rd_format || rd->rd_values) {
printk("=");
any = 1;
}
}
/* You can have any format so long as it is %x */
if (rd->rd_format) {
printk("%llx", field);
any = 1;
if (rd->rd_values)
printk(":");
}
if (rd->rd_values) {
any = 1;
for (rv = rd->rd_values; rv->rv_name; rv++) {
if (field == rv->rv_value) {
printk("%s", rv->rv_name);
break;
}
}
if (rv->rv_name == NULL)
printk("???");
}
}
printk(">\n");
}
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
* License. See the file "COPYING" in the main directory of this archive * License. See the file "COPYING" in the main directory of this archive
* for more details. * for more details.
* *
* Copyright (C) 1992 - 1997, 2000-2001 Silicon Graphics, Inc. All rights reserved. * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved.
*/ */
#include <linux/config.h> #include <linux/config.h>
...@@ -71,6 +71,9 @@ void initialize_io(void) ...@@ -71,6 +71,9 @@ void initialize_io(void)
*/ */
static __psunsigned_t master_bridge_base = (__psunsigned_t)NULL; static __psunsigned_t master_bridge_base = (__psunsigned_t)NULL;
nasid_t console_nasid = (nasid_t)-1; nasid_t console_nasid = (nasid_t)-1;
#if !defined(CONFIG_IA64_SGI_SN1)
char master_baseio_wid;
#endif
static char console_wid; static char console_wid;
static char console_pcislot; static char console_pcislot;
...@@ -92,6 +95,7 @@ check_nasid_equiv(nasid_t nasida, nasid_t nasidb) ...@@ -92,6 +95,7 @@ check_nasid_equiv(nasid_t nasida, nasid_t nasidb)
return 0; return 0;
} }
#if defined(CONFIG_IA64_SGI_SN1)
int int
is_master_nasid_widget(nasid_t test_nasid, xwidgetnum_t test_wid) is_master_nasid_widget(nasid_t test_nasid, xwidgetnum_t test_wid)
{ {
...@@ -111,6 +115,29 @@ is_master_nasid_widget(nasid_t test_nasid, xwidgetnum_t test_wid) ...@@ -111,6 +115,29 @@ is_master_nasid_widget(nasid_t test_nasid, xwidgetnum_t test_wid)
return 0; return 0;
} }
} }
#else
int
is_master_baseio_nasid_widget(nasid_t test_nasid, xwidgetnum_t test_wid)
{
extern nasid_t master_baseio_nasid;
/*
* If the widget numbers are different, we're not the master.
*/
if (test_wid != (xwidgetnum_t)master_baseio_wid) {
return 0;
}
/*
* If the NASIDs are the same or equivalent, we're the master.
*/
if (check_nasid_equiv(test_nasid, master_baseio_nasid)) {
return 1;
} else {
return 0;
}
}
#endif /* CONFIG_IA64_SGI_SN1 */
/* /*
* Routines provided by ml/SN/nvram.c * Routines provided by ml/SN/nvram.c
......
/* $Id: io.c,v 1.2 2001/06/26 14:02:43 pfg Exp $ /* $Id: hub_intr.c,v 1.1 2002/02/28 17:31:25 marcelo Exp $
* *
* This file is subject to the terms and conditions of the GNU General Public * 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 * License. See the file "COPYING" in the main directory of this archive
......
/* $Id:$ /* $Id: hubcounters.c,v 1.1 2002/02/28 17:31:25 marcelo Exp $
* *
* This file is subject to the terms and conditions of the GNU General Public * 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 * License. See the file "COPYING" in the main directory of this archive
* for more details. * for more details.
* *
* Copyright (C) 1992 - 1997, 2000 - 2001 Silicon Graphics, Inc. * Copyright (C) 1992-1997,2000-2002 Silicon Graphics, Inc.
* All rights reserved. * All rights reserved.
*/ */
#include <linux/kernel.h> #include <linux/kernel.h>
...@@ -24,7 +24,7 @@ extern void hubni_error_handler(char *, int); /* huberror.c */ ...@@ -24,7 +24,7 @@ extern void hubni_error_handler(char *, int); /* huberror.c */
static int hubstats_ioctl(struct inode *, struct file *, unsigned int, unsigned long); static int hubstats_ioctl(struct inode *, struct file *, unsigned int, unsigned long);
struct file_operations hub_mon_fops = { struct file_operations hub_mon_fops = {
.ioctl = hubstats_ioctl, ioctl: hubstats_ioctl,
}; };
#define HUB_CAPTURE_TICKS (2 * HZ) #define HUB_CAPTURE_TICKS (2 * HZ)
......
/* $Id$ /* $Id: huberror.c,v 1.1 2002/02/28 17:31:25 marcelo Exp $
* *
* This file is subject to the terms and conditions of the GNU General Public * 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 * License. See the file "COPYING" in the main directory of this archive
......
/* $Id$ /* $Id: mem_refcnt.c,v 1.1 2002/02/28 17:31:25 marcelo Exp $
* *
* This file is subject to the terms and conditions of the GNU General Public * 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 * License. See the file "COPYING" in the main directory of this archive
...@@ -7,7 +7,6 @@ ...@@ -7,7 +7,6 @@
* Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved. * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved.
*/ */
#include <linux/config.h>
#include <linux/types.h> #include <linux/types.h>
#include <asm/sn/arch.h> #include <asm/sn/arch.h>
#include <asm/sn/sgi.h> #include <asm/sn/sgi.h>
...@@ -43,7 +42,7 @@ ...@@ -43,7 +42,7 @@
int int
mem_refcnt_attach(devfs_handle_t hub) mem_refcnt_attach(devfs_handle_t hub)
{ {
#ifndef CONFIG_IA64_SGI_SN #if 0
devfs_handle_t refcnt_dev; devfs_handle_t refcnt_dev;
hwgraph_char_device_add(hub, hwgraph_char_device_add(hub,
......
/* $Id$ /* $Id: ml_SN_intr.c,v 1.1 2002/02/28 17:31:25 marcelo Exp $
* *
* This file is subject to the terms and conditions of the GNU General Public * 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 * License. See the file "COPYING" in the main directory of this archive
...@@ -13,7 +13,7 @@ ...@@ -13,7 +13,7 @@
* handle interrupts on an IP27 board. * handle interrupts on an IP27 board.
*/ */
#ident "$Revision: 1.167 $" #ident "$Revision: 1.1 $"
#include <linux/types.h> #include <linux/types.h>
#include <linux/config.h> #include <linux/config.h>
...@@ -987,13 +987,12 @@ intr_reserve_hardwired(cnodeid_t cnode) ...@@ -987,13 +987,12 @@ intr_reserve_hardwired(cnodeid_t cnode)
char subnode_done[NUM_SUBNODES]; char subnode_done[NUM_SUBNODES];
// cpu = cnodetocpu(cnode); // cpu = cnodetocpu(cnode);
for (cpu = 0; cpu < NR_CPUS; cpu++) { for (cpu = 0; cpu < smp_num_cpus; cpu++) {
if (!cpu_online(cpu)) continue;
if (cpuid_to_cnodeid(cpu) == cnode) { if (cpuid_to_cnodeid(cpu) == cnode) {
break; break;
} }
} }
if (cpu == NR_CPUS) cpu = CPU_NONE; if (cpu == smp_num_cpus) cpu = CPU_NONE;
if (cpu == CPU_NONE) { if (cpu == CPU_NONE) {
printk("Node %d has no CPUs", cnode); printk("Node %d has no CPUs", cnode);
return; return;
...@@ -1002,7 +1001,7 @@ intr_reserve_hardwired(cnodeid_t cnode) ...@@ -1002,7 +1001,7 @@ intr_reserve_hardwired(cnodeid_t cnode)
for (i=0; i<NUM_SUBNODES; i++) for (i=0; i<NUM_SUBNODES; i++)
subnode_done[i] = 0; subnode_done[i] = 0;
for (; cpu<NR_CPUS && cpu_enabled(cpu) && cpuid_to_cnodeid(cpu) == cnode; cpu++) { for (; cpu<smp_num_cpus && cpu_enabled(cpu) && cpuid_to_cnodeid(cpu) == cnode; cpu++) {
int which_subnode = cpuid_to_subnode(cpu); int which_subnode = cpuid_to_subnode(cpu);
if (subnode_done[which_subnode]) if (subnode_done[which_subnode])
continue; continue;
......
This diff is collapsed.
/* $Id$ /* $Id: bte_error.c,v 1.1 2002/02/28 17:31:25 marcelo Exp $
* *
* This file is subject to the terms and conditions of the GNU General Public * 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 * License. See the file "COPYING" in the main directory of this archive
...@@ -54,96 +54,14 @@ ...@@ -54,96 +54,14 @@
* * * *
************************************************************************/ ************************************************************************/
#ifdef BTE_ERROR
// This routine is not called. Yet. It may be someday. It probably
// *should* be someday. Until then, ifdef it out.
bte_result_t
bte_error_handler(bte_handle_t *bh)
/* /*
* Function: bte_error_handler * >>> bte_crb_error_handler needs to be broken into two parts. The
* Purpose: Process a BTE error after a transfer has failed. * first should cleanup the CRB. The second should wait until all bte
* Parameters: bh - bte handle of bte that failed. * related CRB's are complete and then do the error reset.
* Returns: The BTE error type.
* Notes:
*/
{
devfs_handle_t hub_v;
hubinfo_t hinfo;
int il;
hubreg_t iidsr, imem, ieclr;
hubreg_t bte_status;
bh->bh_bte->bte_error_count++;
/*
* Process any CRB logs - we know that the bte_context contains
* the BTE completion status, but to avoid a race with error
* processing, we force a call to pick up any CRB errors pending.
* After this call, we know that we have any CRB errors related to
* this BTE transfer in the context.
*/
hub_v = cnodeid_to_vertex(bh->bh_bte->bte_cnode);
hubinfo_get(hub_v, &hinfo);
(void)hubiio_crb_error_handler(hub_v, hinfo);
/* Be sure BTE is stopped */
(void)BTE_LOAD(bh->bh_bte->bte_base, BTEOFF_CTRL);
/*
* Now clear up the rest of the error - be sure to hold crblock
* to avoid race with other cpu on this node.
*/ */
imem = REMOTE_HUB_L(hinfo->h_nasid, IIO_IMEM);
ieclr = REMOTE_HUB_L(hinfo->h_nasid, IIO_IECLR);
if (bh->bh_bte->bte_num == 0) {
imem |= IIO_IMEM_W0ESD | IIO_IMEM_B0ESD;
ieclr|= IECLR_BTE0;
} else {
imem |= IIO_IMEM_W0ESD | IIO_IMEM_B1ESD;
ieclr|= IECLR_BTE1;
}
REMOTE_HUB_S(hinfo->h_nasid, IIO_IMEM, imem);
REMOTE_HUB_S(hinfo->h_nasid, IIO_IECLR, ieclr);
iidsr = REMOTE_HUB_L(hinfo->h_nasid, IIO_IIDSR);
iidsr &= ~IIO_IIDSR_SENT_MASK;
iidsr |= IIO_IIDSR_ENB_MASK;
REMOTE_HUB_S(hinfo->h_nasid, IIO_IIDSR, iidsr);
mutex_spinunlock(&hinfo->h_crblock, il);
bte_status = BTE_LOAD(bh->bh_bte->bte_base, BTEOFF_STAT);
BTE_STORE(bh->bh_bte->bte_base, BTEOFF_STAT, bte_status & ~IBLS_BUSY);
ASSERT(!BTE_IS_BUSY(BTE_LOAD(bh->bh_bte->bte_base, BTEOFF_STAT)));
switch(bh->bh_error) {
case IIO_ICRB_ECODE_PERR:
return(BTEFAIL_POISON);
case IIO_ICRB_ECODE_WERR:
return(BTEFAIL_PROT);
case IIO_ICRB_ECODE_AERR:
return(BTEFAIL_ACCESS);
case IIO_ICRB_ECODE_TOUT:
return(BTEFAIL_TOUT);
case IIO_ICRB_ECODE_XTERR:
return(BTEFAIL_ERROR);
case IIO_ICRB_ECODE_DERR:
return(BTEFAIL_DIR);
case IIO_ICRB_ECODE_PWERR:
case IIO_ICRB_ECODE_PRERR:
/* NO BREAK */
default:
printk("BTE failure (%d) unexpected\n",
bh->bh_error);
return(BTEFAIL_ERROR);
}
}
#endif // BTE_ERROR
void void
bte_crb_error_handler(devfs_handle_t hub_v, int btenum, bte_crb_error_handler(devfs_handle_t hub_v, int btenum,
int crbnum, ioerror_t *ioe) int crbnum, ioerror_t *ioe, int bteop)
/* /*
* Function: bte_crb_error_handler * Function: bte_crb_error_handler
* Purpose: Process a CRB for a specific HUB/BTE * Purpose: Process a CRB for a specific HUB/BTE
...@@ -162,29 +80,70 @@ bte_crb_error_handler(devfs_handle_t hub_v, int btenum, ...@@ -162,29 +80,70 @@ bte_crb_error_handler(devfs_handle_t hub_v, int btenum,
icrba_t crba; icrba_t crba;
icrbb_t crbb; icrbb_t crbb;
nasid_t n; nasid_t n;
hubreg_t iidsr, imem, ieclr;
hubinfo_get(hub_v, &hinfo); hubinfo_get(hub_v, &hinfo);
n = hinfo->h_nasid; n = hinfo->h_nasid;
/* Step 1 */
crba.ii_icrb0_a_regval = REMOTE_HUB_L(n, IIO_ICRB_A(crbnum));
crbb.ii_icrb0_b_regval = REMOTE_HUB_L(n, IIO_ICRB_B(crbnum));
/*
* The following 10 lines (or so) are adapted from IRIXs
* bte_crb_error function. No clear documentation tells
* why the crb needs to complete normally in order for
* the BTE to resume normal operations. This first step
* appears vital!
*/
/* Zero error and error code to prevent error_dump complaining /*
* about these CRBs. * Zero error and error code to prevent error_dump complaining
* about these CRBs. Copy the CRB to the notification line.
* The crb address is in shub format (physical address shifted
* right by cacheline size).
*/ */
crbb.ii_icrb0_b_regval = REMOTE_HUB_L(n, IIO_ICRB_B(crbnum));
crbb.b_error=0; crbb.b_error=0;
crbb.b_ecode=0; crbb.b_ecode=0;
REMOTE_HUB_S(n, IIO_ICRB_B(crbnum), crbb.ii_icrb0_b_regval);
/* Step 2 */ crba.ii_icrb0_a_regval = REMOTE_HUB_L(n, IIO_ICRB_A(crbnum));
crba.a_addr = TO_PHYS((u64)&nodepda->bte_if[btenum].notify) >> 3;
crba.a_valid = 1;
REMOTE_HUB_S(n, IIO_ICRB_A(crbnum), crba.ii_icrb0_a_regval); REMOTE_HUB_S(n, IIO_ICRB_A(crbnum), crba.ii_icrb0_a_regval);
/* Step 3 */
REMOTE_HUB_S(n, IIO_ICCR, REMOTE_HUB_S(n, IIO_ICCR,
IIO_ICCR_PENDING | IIO_ICCR_CMD_FLUSH | crbnum); IIO_ICCR_PENDING | IIO_ICCR_CMD_FLUSH | crbnum);
while (REMOTE_HUB_L(n, IIO_ICCR) & IIO_ICCR_PENDING) while (REMOTE_HUB_L(n, IIO_ICCR) & IIO_ICCR_PENDING)
; ;
/* Terminate the BTE. */
/* >>> The other bte transfer will need to be restarted. */
HUB_L((shubreg_t *)((nodepda->bte_if[btenum].bte_base_addr +
IIO_IBCT0 - IIO_IBLS0)));
imem = REMOTE_HUB_L(n, IIO_IMEM);
ieclr = REMOTE_HUB_L(n, IIO_IECLR);
if (btenum == 0) {
imem |= IIO_IMEM_W0ESD | IIO_IMEM_B0ESD;
ieclr|= IECLR_BTE0;
} else {
imem |= IIO_IMEM_W0ESD | IIO_IMEM_B1ESD;
ieclr|= IECLR_BTE1;
}
REMOTE_HUB_S(n, IIO_IMEM, imem);
REMOTE_HUB_S(n, IIO_IECLR, ieclr);
iidsr = REMOTE_HUB_L(n, IIO_IIDSR);
iidsr &= ~IIO_IIDSR_SENT_MASK;
iidsr |= IIO_IIDSR_ENB_MASK;
REMOTE_HUB_S(n, IIO_IIDSR, iidsr);
bte_reset_nasid(n);
*nodepda->bte_if[btenum].most_rcnt_na = IBLS_ERROR;
} }
/* $Id$ /* $Id: ml_SN_intr.c,v 1.1 2002/02/28 17:31:25 marcelo Exp $
* *
* This file is subject to the terms and conditions of the GNU General Public * 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 * License. See the file "COPYING" in the main directory of this archive
...@@ -13,7 +13,7 @@ ...@@ -13,7 +13,7 @@
* handle interrupts on an IPXX board. * handle interrupts on an IPXX board.
*/ */
#ident "$Revision: 1.167 $" #ident "$Revision: 1.1 $"
#include <linux/types.h> #include <linux/types.h>
#include <linux/slab.h> #include <linux/slab.h>
...@@ -36,6 +36,7 @@ ...@@ -36,6 +36,7 @@
#include <asm/sn/pci/pcibr_private.h> #include <asm/sn/pci/pcibr_private.h>
#include <asm/sn/intr.h> #include <asm/sn/intr.h>
#include <asm/sn/sn2/shub_mmr_t.h> #include <asm/sn/sn2/shub_mmr_t.h>
#include <asm/sn/sn2/shubio.h>
#include <asm/sal.h> #include <asm/sal.h>
#include <asm/sn/sn_sal.h> #include <asm/sn/sn_sal.h>
...@@ -51,24 +52,15 @@ intr_init_vecblk( nodepda_t *npda, ...@@ -51,24 +52,15 @@ intr_init_vecblk( nodepda_t *npda,
int sn) int sn)
{ {
int nasid = cnodeid_to_nasid(node); int nasid = cnodeid_to_nasid(node);
nasid_t console_nasid;
sh_ii_int0_config_u_t ii_int_config; sh_ii_int0_config_u_t ii_int_config;
cpuid_t cpu; cpuid_t cpu;
cpuid_t cpu0, cpu1; cpuid_t cpu0, cpu1;
nodepda_t *lnodepda; nodepda_t *lnodepda;
sh_ii_int0_enable_u_t ii_int_enable; sh_ii_int0_enable_u_t ii_int_enable;
sh_local_int0_config_u_t local_int_config;
sh_local_int0_enable_u_t local_int_enable;
sh_fsb_system_agent_config_u_t fsb_system_agent;
sh_int_node_id_config_u_t node_id_config; sh_int_node_id_config_u_t node_id_config;
int is_console; extern void sn_init_cpei_timer(void);
static int timer_added = 0;
console_nasid = get_console_nasid();
if (console_nasid < 0) {
console_nasid = master_nasid;
}
is_console = nasid == console_nasid;
if (is_headless_node(node) ) { if (is_headless_node(node) ) {
int cnode; int cnode;
...@@ -95,13 +87,15 @@ intr_init_vecblk( nodepda_t *npda, ...@@ -95,13 +87,15 @@ intr_init_vecblk( nodepda_t *npda,
} }
// Get the physical id's of the cpu's on this node. // Get the physical id's of the cpu's on this node.
cpu0 = id_eid_to_cpu_physical_id(nasid, 0); cpu0 = nasid_slice_to_cpu_physical_id(nasid, 0);
cpu1 = id_eid_to_cpu_physical_id(nasid, 1); cpu1 = nasid_slice_to_cpu_physical_id(nasid, 2);
HUB_S( (unsigned long *)GLOBAL_MMR_ADDR(nasid, SH_PI_ERROR_MASK), 0); HUB_S( (unsigned long *)GLOBAL_MMR_ADDR(nasid, SH_PI_ERROR_MASK), 0);
HUB_S( (unsigned long *)GLOBAL_MMR_ADDR(nasid, SH_PI_CRBP_ERROR_MASK), 0); HUB_S( (unsigned long *)GLOBAL_MMR_ADDR(nasid, SH_PI_CRBP_ERROR_MASK), 0);
// The II_INT_CONFIG register for cpu 0. // The II_INT_CONFIG register for cpu 0.
ii_int_config.sh_ii_int0_config_regval = 0;
ii_int_config.sh_ii_int0_config_s.type = 0; ii_int_config.sh_ii_int0_config_s.type = 0;
ii_int_config.sh_ii_int0_config_s.agt = 0; ii_int_config.sh_ii_int0_config_s.agt = 0;
ii_int_config.sh_ii_int0_config_s.pid = cpu0; ii_int_config.sh_ii_int0_config_s.pid = cpu0;
...@@ -110,7 +104,9 @@ intr_init_vecblk( nodepda_t *npda, ...@@ -110,7 +104,9 @@ intr_init_vecblk( nodepda_t *npda,
HUB_S((unsigned long *)GLOBAL_MMR_ADDR(nasid, SH_II_INT0_CONFIG), HUB_S((unsigned long *)GLOBAL_MMR_ADDR(nasid, SH_II_INT0_CONFIG),
ii_int_config.sh_ii_int0_config_regval); ii_int_config.sh_ii_int0_config_regval);
// The II_INT_CONFIG register for cpu 1. // The II_INT_CONFIG register for cpu 1.
ii_int_config.sh_ii_int0_config_regval = 0;
ii_int_config.sh_ii_int0_config_s.type = 0; ii_int_config.sh_ii_int0_config_s.type = 0;
ii_int_config.sh_ii_int0_config_s.agt = 0; ii_int_config.sh_ii_int0_config_s.agt = 0;
ii_int_config.sh_ii_int0_config_s.pid = cpu1; ii_int_config.sh_ii_int0_config_s.pid = cpu1;
...@@ -119,101 +115,28 @@ intr_init_vecblk( nodepda_t *npda, ...@@ -119,101 +115,28 @@ intr_init_vecblk( nodepda_t *npda,
HUB_S((unsigned long *)GLOBAL_MMR_ADDR(nasid, SH_II_INT1_CONFIG), HUB_S((unsigned long *)GLOBAL_MMR_ADDR(nasid, SH_II_INT1_CONFIG),
ii_int_config.sh_ii_int0_config_regval); ii_int_config.sh_ii_int0_config_regval);
// Enable interrupts for II_INT0 and 1. // Enable interrupts for II_INT0 and 1.
ii_int_enable.sh_ii_int0_enable_regval = 0;
ii_int_enable.sh_ii_int0_enable_s.ii_enable = 1; ii_int_enable.sh_ii_int0_enable_s.ii_enable = 1;
#ifdef BUS_INT_WAR
/* Dont enable any ints from II. We will poll for interrupts. */
ii_int_enable.sh_ii_int0_enable_s.ii_enable = 0;
/* Enable IPIs. We use them ONLY for send INITs to hung cpus */
*(volatile long*)GLOBAL_MMR_ADDR(nasid, SH_IPI_INT_ENABLE) = 1;
#endif
HUB_S((unsigned long *)GLOBAL_MMR_ADDR(nasid, SH_II_INT0_ENABLE), HUB_S((unsigned long *)GLOBAL_MMR_ADDR(nasid, SH_II_INT0_ENABLE),
ii_int_enable.sh_ii_int0_enable_regval); ii_int_enable.sh_ii_int0_enable_regval);
HUB_S((unsigned long *)GLOBAL_MMR_ADDR(nasid, SH_II_INT1_ENABLE), HUB_S((unsigned long *)GLOBAL_MMR_ADDR(nasid, SH_II_INT1_ENABLE),
ii_int_enable.sh_ii_int0_enable_regval); ii_int_enable.sh_ii_int0_enable_regval);
// init error regs
// LOCAL_INT0 is for the UART only.
local_int_config.sh_local_int0_config_s.type = 0;
local_int_config.sh_local_int0_config_s.agt = 0;
local_int_config.sh_local_int0_config_s.pid = cpu;
local_int_config.sh_local_int0_config_s.base = 0;
local_int_config.sh_local_int0_config_s.idx = SGI_UART_VECTOR;
HUB_S((unsigned long *)GLOBAL_MMR_ADDR(nasid, SH_LOCAL_INT0_CONFIG),
local_int_config.sh_local_int0_config_regval);
// LOCAL_INT1 is for all hardware errors.
// It will send a BERR, which will result in an MCA.
local_int_config.sh_local_int0_config_s.idx = 0;
HUB_S((unsigned long *)GLOBAL_MMR_ADDR(nasid, SH_LOCAL_INT1_CONFIG),
local_int_config.sh_local_int0_config_regval);
// Clear the LOCAL_INT_ENABLE register. if (!timer_added) { // can only init the timer once.
local_int_enable.sh_local_int0_enable_regval = 0; timer_added = 1;
sn_init_cpei_timer();
if (is_console) {
// Enable the UART interrupt. Only applies to the console nasid.
local_int_enable.sh_local_int0_enable_s.uart_int = 1;
HUB_S((unsigned long *)GLOBAL_MMR_ADDR(nasid, SH_LOCAL_INT0_ENABLE),
local_int_enable.sh_local_int0_enable_regval);
} }
// Enable all the error interrupts.
local_int_enable.sh_local_int0_enable_s.uart_int = 0;
local_int_enable.sh_local_int0_enable_s.pi_hw_int = 1;
local_int_enable.sh_local_int0_enable_s.md_hw_int = 1;
local_int_enable.sh_local_int0_enable_s.xn_hw_int = 1;
local_int_enable.sh_local_int0_enable_s.lb_hw_int = 1;
local_int_enable.sh_local_int0_enable_s.ii_hw_int = 1;
local_int_enable.sh_local_int0_enable_s.pi_uce_int = 1;
local_int_enable.sh_local_int0_enable_s.md_uce_int = 1;
local_int_enable.sh_local_int0_enable_s.xn_uce_int = 1;
local_int_enable.sh_local_int0_enable_s.system_shutdown_int = 1;
local_int_enable.sh_local_int0_enable_s.l1_nmi_int = 1;
local_int_enable.sh_local_int0_enable_s.stop_clock = 1;
// Send BERR, rather than an interrupt, for shub errors.
local_int_config.sh_local_int0_config_s.agt = 1;
HUB_S((unsigned long *)GLOBAL_MMR_ADDR(nasid, SH_LOCAL_INT1_CONFIG),
local_int_config.sh_local_int0_config_regval);
HUB_S((unsigned long *)GLOBAL_MMR_ADDR(nasid, SH_LOCAL_INT1_ENABLE),
local_int_enable.sh_local_int0_enable_regval);
// Make sure BERR is enabled.
fsb_system_agent.sh_fsb_system_agent_config_regval =
HUB_L( (unsigned long *)GLOBAL_MMR_ADDR(nasid, SH_FSB_SYSTEM_AGENT_CONFIG) );
fsb_system_agent.sh_fsb_system_agent_config_s.berr_assert_en = 1;
HUB_S((unsigned long *)GLOBAL_MMR_ADDR(nasid, SH_FSB_SYSTEM_AGENT_CONFIG),
fsb_system_agent.sh_fsb_system_agent_config_regval);
// Set LOCAL_INT2 to field CEs
local_int_enable.sh_local_int0_enable_regval = 0;
local_int_config.sh_local_int0_config_s.agt = 0;
local_int_config.sh_local_int0_config_s.idx = SGI_SHUB_ERROR_VECTOR;
HUB_S((unsigned long *)GLOBAL_MMR_ADDR(nasid, SH_LOCAL_INT2_CONFIG),
local_int_config.sh_local_int0_config_regval);
local_int_enable.sh_local_int0_enable_s.pi_ce_int = 1;
local_int_enable.sh_local_int0_enable_s.md_ce_int = 1;
local_int_enable.sh_local_int0_enable_s.xn_ce_int = 1;
HUB_S((unsigned long *)GLOBAL_MMR_ADDR(nasid, SH_LOCAL_INT2_ENABLE),
local_int_enable.sh_local_int0_enable_regval);
// Make sure all the rest of the LOCAL_INT regs are disabled.
local_int_enable.sh_local_int0_enable_regval = 0;
HUB_S((unsigned long *)GLOBAL_MMR_ADDR(nasid, SH_LOCAL_INT3_ENABLE),
local_int_enable.sh_local_int0_enable_regval);
HUB_S((unsigned long *)GLOBAL_MMR_ADDR(nasid, SH_LOCAL_INT4_ENABLE),
local_int_enable.sh_local_int0_enable_regval);
HUB_S((unsigned long *)GLOBAL_MMR_ADDR(nasid, SH_LOCAL_INT5_ENABLE),
local_int_enable.sh_local_int0_enable_regval);
} }
// (Un)Reserve an irq on this cpu. // (Un)Reserve an irq on this cpu.
...@@ -393,31 +316,40 @@ intr_heuristic(devfs_handle_t dev, ...@@ -393,31 +316,40 @@ intr_heuristic(devfs_handle_t dev,
int *resp_bit) int *resp_bit)
{ {
cpuid_t cpuid; cpuid_t cpuid;
cnodeid_t candidate = -1; cpuid_t candidate = CPU_NONE;
cnodeid_t candidate_node;
devfs_handle_t pconn_vhdl; devfs_handle_t pconn_vhdl;
pcibr_soft_t pcibr_soft; pcibr_soft_t pcibr_soft;
int bit;
/* SN2 + pcibr addressing limitation */ /* SN2 + pcibr addressing limitation */
/* Due to this limitation, all interrupts from a given bridge must go to the name node.*/ /* Due to this limitation, all interrupts from a given bridge must go to the name node.*/
/* The interrupt must also be targetted for the same processor. */
/* This limitation does not exist on PIC. */ /* This limitation does not exist on PIC. */
/* But, the processor limitation will stay. The limitation will be similar to */
/* the bedrock/xbridge limit regarding PI's */
if ( (hwgraph_edge_get(dev, EDGE_LBL_PCI, &pconn_vhdl) == GRAPH_SUCCESS) && if ( (hwgraph_edge_get(dev, EDGE_LBL_PCI, &pconn_vhdl) == GRAPH_SUCCESS) &&
( (pcibr_soft = pcibr_soft_get(pconn_vhdl) ) != NULL) ) { ( (pcibr_soft = pcibr_soft_get(pconn_vhdl) ) != NULL) ) {
if (pcibr_soft->bsi_err_intr) { if (pcibr_soft->bsi_err_intr) {
candidate = cpuid_to_cnodeid( ((hub_intr_t)pcibr_soft->bsi_err_intr)->i_cpuid); candidate = ((hub_intr_t)pcibr_soft->bsi_err_intr)->i_cpuid;
} }
} }
if (candidate >= 0) {
// The node was chosen already when we assigned the error interrupt. if (candidate != CPU_NONE) {
cpuid = intr_bit_reserve_test(CPU_NONE, // The cpu was chosen already when we assigned the error interrupt.
0, bit = intr_reserve_level(candidate,
candidate,
req_bit, req_bit,
0, resflags,
owner_dev, owner_dev,
name, name);
resp_bit); if (bit < 0) {
cpuid = CPU_NONE;
} else {
cpuid = candidate;
*resp_bit = bit;
}
} else { } else {
// Need to choose one. Try the controlling c-brick first. // Need to choose one. Try the controlling c-brick first.
cpuid = intr_bit_reserve_test(CPU_NONE, cpuid = intr_bit_reserve_test(CPU_NONE,
...@@ -434,10 +366,9 @@ intr_heuristic(devfs_handle_t dev, ...@@ -434,10 +366,9 @@ intr_heuristic(devfs_handle_t dev,
return cpuid; return cpuid;
} }
if (candidate >= 0) { if (candidate != CPU_NONE) {
printk("Cannot target interrupt to target node (%d).\n",candidate); printk("Cannot target interrupt to target node (%ld).\n",candidate);
return CPU_NONE; return CPU_NONE; } else {
} else {
printk("Cannot target interrupt to closest node (%d) 0x%p\n", printk("Cannot target interrupt to closest node (%d) 0x%p\n",
master_node_get(dev), (void *)owner_dev); master_node_get(dev), (void *)owner_dev);
} }
...@@ -448,11 +379,11 @@ intr_heuristic(devfs_handle_t dev, ...@@ -448,11 +379,11 @@ intr_heuristic(devfs_handle_t dev,
{ {
static cnodeid_t last_node = -1; static cnodeid_t last_node = -1;
if (last_node >= numnodes) last_node = 0; if (last_node >= numnodes) last_node = 0;
for (candidate = last_node + 1; candidate != last_node; candidate++) { for (candidate_node = last_node + 1; candidate_node != last_node; candidate_node++) {
if (candidate == numnodes) candidate = 0; if (candidate_node == numnodes) candidate_node = 0;
cpuid = intr_bit_reserve_test(CPU_NONE, cpuid = intr_bit_reserve_test(CPU_NONE,
0, 0,
candidate, candidate_node,
req_bit, req_bit,
0, 0,
owner_dev, owner_dev,
......
...@@ -44,24 +44,6 @@ struct map *atemapalloc(uint64_t mapsiz); ...@@ -44,24 +44,6 @@ struct map *atemapalloc(uint64_t mapsiz);
#endif #endif
#ifdef LATER
#if (PCIBR_FREEZE_TIME) || PCIBR_ATE_DEBUG
LOCAL struct reg_desc ate_bits[] =
{
{0xFFFF000000000000ull, -48, "RMF", "%x"},
{~(IOPGSIZE - 1) & /* may trim off some low bits */
0x0000FFFFFFFFF000ull, 0, "XIO", "%x"},
{0x0000000000000F00ull, -8, "port", "%x"},
{0x0000000000000010ull, 0, "Barrier"},
{0x0000000000000008ull, 0, "Prefetch"},
{0x0000000000000004ull, 0, "Precise"},
{0x0000000000000002ull, 0, "Coherent"},
{0x0000000000000001ull, 0, "Valid"},
{0}
};
#endif
#endif /* LATER */
#ifndef LOCAL #ifndef LOCAL
#define LOCAL static #define LOCAL static
#endif #endif
...@@ -79,7 +61,7 @@ unsigned ate_freeze(pcibr_dmamap_t pcibr_dmamap, ...@@ -79,7 +61,7 @@ unsigned ate_freeze(pcibr_dmamap_t pcibr_dmamap,
unsigned *freeze_time_ptr, unsigned *freeze_time_ptr,
#endif #endif
unsigned *cmd_regs); unsigned *cmd_regs);
void ate_write(bridge_ate_p ate_ptr, int ate_count, bridge_ate_t ate); void ate_write(pcibr_soft_t pcibr_soft, bridge_ate_p ate_ptr, int ate_count, bridge_ate_t ate);
void ate_thaw(pcibr_dmamap_t pcibr_dmamap, void ate_thaw(pcibr_dmamap_t pcibr_dmamap,
int ate_index, int ate_index,
#if PCIBR_FREEZE_TIME #if PCIBR_FREEZE_TIME
...@@ -119,26 +101,73 @@ pcibr_init_ext_ate_ram(bridge_t *bridge) ...@@ -119,26 +101,73 @@ pcibr_init_ext_ate_ram(bridge_t *bridge)
int i, j; int i, j;
bridgereg_t old_enable, new_enable; bridgereg_t old_enable, new_enable;
int s; int s;
int this_is_pic = is_pic(bridge);
/* Probe SSRAM to determine its size. */ /* Probe SSRAM to determine its size. */
if ( this_is_pic ) {
old_enable = bridge->b_int_enable; old_enable = bridge->b_int_enable;
new_enable = old_enable & ~BRIDGE_IMR_PCI_MST_TIMEOUT; new_enable = old_enable & ~BRIDGE_IMR_PCI_MST_TIMEOUT;
bridge->b_int_enable = new_enable; bridge->b_int_enable = new_enable;
}
else {
if (io_get_sh_swapper(NASID_GET(bridge))) {
old_enable = BRIDGE_REG_GET32((&bridge->b_int_enable));
new_enable = old_enable & ~BRIDGE_IMR_PCI_MST_TIMEOUT;
BRIDGE_REG_SET32((&bridge->b_int_enable)) = new_enable;
}
else {
old_enable = bridge->b_int_enable;
new_enable = old_enable & ~BRIDGE_IMR_PCI_MST_TIMEOUT;
bridge->b_int_enable = new_enable;
}
}
for (i = 1; i < ATE_NUM_SIZES; i++) { for (i = 1; i < ATE_NUM_SIZES; i++) {
/* Try writing a value */ /* Try writing a value */
if ( this_is_pic ) {
bridge->b_ext_ate_ram[ATE_NUM_ENTRIES(i) - 1] = ATE_PROBE_VALUE;
}
else {
if (io_get_sh_swapper(NASID_GET(bridge)))
bridge->b_ext_ate_ram[ATE_NUM_ENTRIES(i) - 1] = __swab64(ATE_PROBE_VALUE);
else
bridge->b_ext_ate_ram[ATE_NUM_ENTRIES(i) - 1] = ATE_PROBE_VALUE; bridge->b_ext_ate_ram[ATE_NUM_ENTRIES(i) - 1] = ATE_PROBE_VALUE;
}
/* Guard against wrap */ /* Guard against wrap */
for (j = 1; j < i; j++) for (j = 1; j < i; j++)
bridge->b_ext_ate_ram[ATE_NUM_ENTRIES(j) - 1] = 0; bridge->b_ext_ate_ram[ATE_NUM_ENTRIES(j) - 1] = 0;
/* See if value was written */ /* See if value was written */
if ( this_is_pic ) {
if (bridge->b_ext_ate_ram[ATE_NUM_ENTRIES(i) - 1] == ATE_PROBE_VALUE)
largest_working_size = i;
}
else {
if (io_get_sh_swapper(NASID_GET(bridge))) {
if (bridge->b_ext_ate_ram[ATE_NUM_ENTRIES(i) - 1] == __swab64(ATE_PROBE_VALUE))
largest_working_size = i;
else {
if (bridge->b_ext_ate_ram[ATE_NUM_ENTRIES(i) - 1] == ATE_PROBE_VALUE) if (bridge->b_ext_ate_ram[ATE_NUM_ENTRIES(i) - 1] == ATE_PROBE_VALUE)
largest_working_size = i; largest_working_size = i;
} }
}
}
}
if ( this_is_pic ) {
bridge->b_int_enable = old_enable; bridge->b_int_enable = old_enable;
bridge->b_wid_tflush; /* wait until Bridge PIO complete */ bridge->b_wid_tflush; /* wait until Bridge PIO complete */
}
else {
if (io_get_sh_swapper(NASID_GET(bridge))) {
BRIDGE_REG_SET32((&bridge->b_int_enable)) = old_enable;
BRIDGE_REG_GET32((&bridge->b_wid_tflush)); /* wait until Bridge PIO complete */
}
else {
bridge->b_int_enable = old_enable;
bridge->b_wid_tflush; /* wait until Bridge PIO complete */
}
}
/* /*
* ensure that we write and read without any interruption. * ensure that we write and read without any interruption.
...@@ -146,20 +175,41 @@ pcibr_init_ext_ate_ram(bridge_t *bridge) ...@@ -146,20 +175,41 @@ pcibr_init_ext_ate_ram(bridge_t *bridge)
*/ */
s = splhi(); s = splhi();
if ( this_is_pic ) {
bridge->b_wid_control = (bridge->b_wid_control bridge->b_wid_control = (bridge->b_wid_control
& ~BRIDGE_CTRL_SSRAM_SIZE_MASK) & ~BRIDGE_CTRL_SSRAM_SIZE_MASK)
| BRIDGE_CTRL_SSRAM_SIZE(largest_working_size); | BRIDGE_CTRL_SSRAM_SIZE(largest_working_size);
bridge->b_wid_control; /* inval addr bug war */ bridge->b_wid_control; /* inval addr bug war */
}
else {
if (io_get_sh_swapper(NASID_GET(bridge))) {
BRIDGE_REG_SET32((&(bridge->b_wid_control))) =
__swab32((BRIDGE_REG_GET32((&bridge->b_wid_control))
& ~BRIDGE_CTRL_SSRAM_SIZE_MASK)
| BRIDGE_CTRL_SSRAM_SIZE(largest_working_size));
BRIDGE_REG_GET32((&bridge->b_wid_control));/* inval addr bug war */
}
else {
bridge->b_wid_control = (bridge->b_wid_control & ~BRIDGE_CTRL_SSRAM_SIZE_MASK)
| BRIDGE_CTRL_SSRAM_SIZE(largest_working_size);
bridge->b_wid_control; /* inval addr bug war */
}
}
splx(s); splx(s);
num_entries = ATE_NUM_ENTRIES(largest_working_size); num_entries = ATE_NUM_ENTRIES(largest_working_size);
#if PCIBR_ATE_DEBUG if (pcibr_debug_mask & PCIBR_DEBUG_ATE) {
if (num_entries) if (num_entries) {
printk("bridge at 0x%x: clearing %d external ATEs\n", bridge, num_entries); PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_ATE, NULL,
else "bridge at 0x%x: clearing %d external ATEs\n",
printk("bridge at 0x%x: no external ATE RAM found\n", bridge); bridge, num_entries));
#endif } else {
PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_ATE, NULL,
"bridge at 0x%x: no external ATE RAM found\n",
bridge));
}
}
/* Initialize external mapping entries */ /* Initialize external mapping entries */
for (entry = 0; entry < num_entries; entry++) for (entry = 0; entry < num_entries; entry++)
...@@ -339,7 +389,8 @@ ate_freeze(pcibr_dmamap_t pcibr_dmamap, ...@@ -339,7 +389,8 @@ ate_freeze(pcibr_dmamap_t pcibr_dmamap,
#endif #endif
cmd_lwa = 0; cmd_lwa = 0;
for (slot = 0; slot < 8; ++slot) for (slot = pcibr_soft->bs_min_slot;
slot < PCIBR_NUM_SLOTS(pcibr_soft); ++slot)
if (atomic_read(&pcibr_soft->bs_slot[slot].bss_ext_ates_active)) { if (atomic_read(&pcibr_soft->bs_slot[slot].bss_ext_ates_active)) {
cmd_reg = pcibr_soft-> cmd_reg = pcibr_soft->
bs_slot[slot]. bs_slot[slot].
...@@ -366,28 +417,54 @@ ate_freeze(pcibr_dmamap_t pcibr_dmamap, ...@@ -366,28 +417,54 @@ ate_freeze(pcibr_dmamap_t pcibr_dmamap,
cmd_lwa[0]; cmd_lwa[0];
/* Flush all the write buffers in the bridge */ /* Flush all the write buffers in the bridge */
for (slot = 0; slot < 8; ++slot) for (slot = pcibr_soft->bs_min_slot;
slot < PCIBR_NUM_SLOTS(pcibr_soft); ++slot) {
if (atomic_read(&pcibr_soft->bs_slot[slot].bss_ext_ates_active)) { if (atomic_read(&pcibr_soft->bs_slot[slot].bss_ext_ates_active)) {
/* Flush the write buffer associated with this /* Flush the write buffer associated with this
* PCI device which might be using dma map RAM. * PCI device which might be using dma map RAM.
*/ */
if ( is_pic(bridge) ) {
bridge->b_wr_req_buf[slot].reg; bridge->b_wr_req_buf[slot].reg;
} }
else {
if (io_get_sh_swapper(NASID_GET(bridge)) ) {
BRIDGE_REG_GET32((&bridge->b_wr_req_buf[slot].reg));
}
else
bridge->b_wr_req_buf[slot].reg;
}
}
}
} }
return s; return s;
} }
#define ATE_WRITE() ate_write(ate_ptr, ate_count, ate)
void void
ate_write(bridge_ate_p ate_ptr, ate_write(pcibr_soft_t pcibr_soft,
bridge_ate_p ate_ptr,
int ate_count, int ate_count,
bridge_ate_t ate) bridge_ate_t ate)
{ {
if (IS_PIC_SOFT(pcibr_soft) ) {
while (ate_count-- > 0) { while (ate_count-- > 0) {
*ate_ptr++ = ate; *ate_ptr++ = ate;
ate += IOPGSIZE; ate += IOPGSIZE;
} }
}
else {
if (io_get_sh_swapper(NASID_GET(ate_ptr))) {
while (ate_count-- > 0) {
*ate_ptr++ = __swab64(ate);
ate += IOPGSIZE;
}
}
else {
while (ate_count-- > 0) {
*ate_ptr++ = ate;
ate += IOPGSIZE;
}
}
}
} }
#if PCIBR_FREEZE_TIME #if PCIBR_FREEZE_TIME
...@@ -425,10 +502,24 @@ ate_thaw(pcibr_dmamap_t pcibr_dmamap, ...@@ -425,10 +502,24 @@ ate_thaw(pcibr_dmamap_t pcibr_dmamap,
return; return;
/* restore cmd regs */ /* restore cmd regs */
for (slot = 0; slot < 8; ++slot) for (slot = pcibr_soft->bs_min_slot;
if ((cmd_reg = cmd_regs[slot]) & PCI_CMD_BUS_MASTER) slot < PCIBR_NUM_SLOTS(pcibr_soft); ++slot) {
bridge->b_type0_cfg_dev[slot].l[PCI_CFG_COMMAND / 4] = cmd_reg; if ((cmd_reg = cmd_regs[slot]) & PCI_CMD_BUS_MASTER) {
if ( IS_PIC_SOFT(pcibr_soft) ) {
pcibr_slot_config_set(bridge, slot, PCI_CFG_COMMAND/4, cmd_reg);
}
else {
if (io_get_sh_swapper(NASID_GET(bridge))) {
bridge->b_type0_cfg_dev[slot].l[PCI_CFG_COMMAND / 4] = __swab32(cmd_reg);
}
else {
// BUG(); /* Does this really work if called when io_get_sh_swapper = 0? */
// bridge->b_type0_cfg_dev[slot].l[PCI_CFG_COMMAND / 4] = cmd_reg;
pcibr_slot_config_set(bridge, slot, PCI_CFG_COMMAND/4, cmd_reg);
}
}
}
}
pcibr_dmamap->bd_flags |= PCIBR_DMAMAP_BUSY; pcibr_dmamap->bd_flags |= PCIBR_DMAMAP_BUSY;
atomic_inc(&(pcibr_soft->bs_slot[dma_slot]. bss_ext_ates_active)); atomic_inc(&(pcibr_soft->bs_slot[dma_slot]. bss_ext_ates_active));
...@@ -442,7 +533,7 @@ ate_thaw(pcibr_dmamap_t pcibr_dmamap, ...@@ -442,7 +533,7 @@ ate_thaw(pcibr_dmamap_t pcibr_dmamap,
if (max_ate_total < ate_total) if (max_ate_total < ate_total)
max_ate_total = ate_total; max_ate_total = ate_total;
pcibr_unlock(pcibr_soft, s); pcibr_unlock(pcibr_soft, s);
printk("%s: pci freeze time %d usec for %d ATEs\n" printk( "%s: pci freeze time %d usec for %d ATEs\n"
"\tfirst ate: %R\n", "\tfirst ate: %R\n",
pcibr_soft->bs_name, pcibr_soft->bs_name,
freeze_time * 1000 / 1250, freeze_time * 1000 / 1250,
......
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
#include <linux/types.h> #include <linux/types.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/byteorder/swab.h>
#include <asm/sn/sgi.h> #include <asm/sn/sgi.h>
#include <asm/sn/sn_cpuid.h> #include <asm/sn/sn_cpuid.h>
#include <asm/sn/addrs.h> #include <asm/sn/addrs.h>
...@@ -34,64 +35,233 @@ ...@@ -34,64 +35,233 @@
extern pcibr_info_t pcibr_info_get(devfs_handle_t); extern pcibr_info_t pcibr_info_get(devfs_handle_t);
uint64_t pcibr_config_get(devfs_handle_t, unsigned, unsigned); uint64_t pcibr_config_get(devfs_handle_t, unsigned, unsigned);
uint64_t do_pcibr_config_get(cfg_p, unsigned, unsigned); uint64_t do_pcibr_config_get(int, cfg_p, unsigned, unsigned);
void pcibr_config_set(devfs_handle_t, unsigned, unsigned, uint64_t); void pcibr_config_set(devfs_handle_t, unsigned, unsigned, uint64_t);
void do_pcibr_config_set(cfg_p, unsigned, unsigned, uint64_t); void do_pcibr_config_set(int, cfg_p, unsigned, unsigned, uint64_t);
static void swap_do_pcibr_config_set(cfg_p, unsigned, unsigned, uint64_t);
#ifdef LITTLE_ENDIAN
/*
* on sn-ia we need to twiddle the the addresses going out
* the pci bus because we use the unswizzled synergy space
* (the alternative is to use the swizzled synergy space
* and byte swap the data)
*/
#define CB(b,r) (((volatile uint8_t *) b)[((r)^4)])
#define CS(b,r) (((volatile uint16_t *) b)[((r^4)/2)])
#define CW(b,r) (((volatile uint32_t *) b)[((r^4)/4)])
#define CBP(b,r) (((volatile uint8_t *) b)[(r)^3])
#define CSP(b,r) (((volatile uint16_t *) b)[((r)/2)^1])
#define CWP(b,r) (((volatile uint32_t *) b)[(r)/4])
#define SCB(b,r) (((volatile uint8_t *) b)[((r)^3)])
#define SCS(b,r) (((volatile uint16_t *) b)[((r^2)/2)])
#define SCW(b,r) (((volatile uint32_t *) b)[((r)/4)])
#else
#define CB(b,r) (((volatile uint8_t *) cfgbase)[(r)^3]) #define CB(b,r) (((volatile uint8_t *) cfgbase)[(r)^3])
#define CS(b,r) (((volatile uint16_t *) cfgbase)[((r)/2)^1]) #define CS(b,r) (((volatile uint16_t *) cfgbase)[((r)/2)^1])
#define CW(b,r) (((volatile uint32_t *) cfgbase)[(r)/4]) #define CW(b,r) (((volatile uint32_t *) cfgbase)[(r)/4])
#endif
/*
* Return a config space address for given slot / func / offset. Note the
* returned pointer is a 32bit word (ie. cfg_p) aligned pointer pointing to
* the 32bit word that contains the "offset" byte.
*/
cfg_p
pcibr_func_config_addr(bridge_t *bridge, pciio_bus_t bus, pciio_slot_t slot,
pciio_function_t func, int offset)
{
/*
* Type 1 config space
*/
if (bus > 0) {
bridge->b_pci_cfg = ((bus << 16) | (slot << 11));
return &bridge->b_type1_cfg.f[func].l[(offset)];
}
/*
* Type 0 config space
*/
if (is_pic(bridge))
slot++;
return &bridge->b_type0_cfg_dev[slot].f[func].l[offset];
}
/*
* Return config space address for given slot / offset. Note the returned
* pointer is a 32bit word (ie. cfg_p) aligned pointer pointing to the
* 32bit word that contains the "offset" byte.
*/
cfg_p
pcibr_slot_config_addr(bridge_t *bridge, pciio_slot_t slot, int offset)
{
return pcibr_func_config_addr(bridge, 0, slot, 0, offset);
}
/*
* Return config space data for given slot / offset
*/
unsigned
pcibr_slot_config_get(bridge_t *bridge, pciio_slot_t slot, int offset)
{
cfg_p cfg_base;
cfg_base = pcibr_slot_config_addr(bridge, slot, 0);
return (do_pcibr_config_get(is_pic(bridge), cfg_base, offset, sizeof(unsigned)));
}
/*
* Return config space data for given slot / func / offset
*/
unsigned
pcibr_func_config_get(bridge_t *bridge, pciio_slot_t slot,
pciio_function_t func, int offset)
{
cfg_p cfg_base;
cfg_base = pcibr_func_config_addr(bridge, 0, slot, func, 0);
return (do_pcibr_config_get(is_pic(bridge), cfg_base, offset, sizeof(unsigned)));
}
/*
* Set config space data for given slot / offset
*/
void
pcibr_slot_config_set(bridge_t *bridge, pciio_slot_t slot,
int offset, unsigned val)
{
cfg_p cfg_base;
cfg_base = pcibr_slot_config_addr(bridge, slot, 0);
do_pcibr_config_set(is_pic(bridge), cfg_base, offset, sizeof(unsigned), val);
}
/*
* Set config space data for given slot / func / offset
*/
void
pcibr_func_config_set(bridge_t *bridge, pciio_slot_t slot,
pciio_function_t func, int offset, unsigned val)
{
cfg_p cfg_base;
cfg_base = pcibr_func_config_addr(bridge, 0, slot, func, 0);
do_pcibr_config_set(is_pic(bridge), cfg_base, offset, sizeof(unsigned), val);
}
int pcibr_config_debug = 0;
cfg_p cfg_p
pcibr_config_addr(devfs_handle_t conn, pcibr_config_addr(devfs_handle_t conn,
unsigned reg) unsigned reg)
{ {
pcibr_info_t pcibr_info; pcibr_info_t pcibr_info;
pciio_bus_t pciio_bus;
pciio_slot_t pciio_slot; pciio_slot_t pciio_slot;
pciio_function_t pciio_func; pciio_function_t pciio_func;
pcibr_soft_t pcibr_soft; pcibr_soft_t pcibr_soft;
bridge_t *bridge; bridge_t *bridge;
cfg_p cfgbase = (cfg_p)0; cfg_p cfgbase = (cfg_p)0;
pciio_info_t pciio_info;
pciio_info = pciio_info_get(conn);
pcibr_info = pcibr_info_get(conn); pcibr_info = pcibr_info_get(conn);
pciio_slot = pcibr_info->f_slot; /*
* Determine the PCI bus/slot/func to generate a config address for.
*/
if (pciio_info_type1_get(pciio_info)) {
/*
* Conn is a vhdl which uses TYPE 1 addressing explicitly passed
* in reg.
*/
pciio_bus = PCI_TYPE1_BUS(reg);
pciio_slot = PCI_TYPE1_SLOT(reg);
pciio_func = PCI_TYPE1_FUNC(reg);
ASSERT(pciio_bus != 0);
#if 0
} else if (conn != pciio_info_hostdev_get(pciio_info)) {
/*
* Conn is on a subordinate bus, so get bus/slot/func directly from
* its pciio_info_t structure.
*/
pciio_bus = pciio_info->c_bus;
pciio_slot = pciio_info->c_slot;
pciio_func = pciio_info->c_func;
if (pciio_func == PCIIO_FUNC_NONE) {
pciio_func = 0;
}
#endif
} else {
/*
* Conn is directly connected to the host bus. PCI bus number is
* hardcoded to 0 (even though it may have a logical bus number != 0)
* and slot/function are derived from the pcibr_info_t associated
* with the device.
*/
pciio_bus = 0;
pciio_slot = PCIBR_INFO_SLOT_GET_INT(pcibr_info);
if (pciio_slot == PCIIO_SLOT_NONE) if (pciio_slot == PCIIO_SLOT_NONE)
pciio_slot = PCI_TYPE1_SLOT(reg); pciio_slot = PCI_TYPE1_SLOT(reg);
pciio_func = pcibr_info->f_func; pciio_func = pcibr_info->f_func;
if (pciio_func == PCIIO_FUNC_NONE) if (pciio_func == PCIIO_FUNC_NONE)
pciio_func = PCI_TYPE1_FUNC(reg); pciio_func = PCI_TYPE1_FUNC(reg);
}
pcibr_soft = (pcibr_soft_t) pcibr_info->f_mfast; pcibr_soft = (pcibr_soft_t) pcibr_info->f_mfast;
bridge = pcibr_soft->bs_base; bridge = pcibr_soft->bs_base;
cfgbase = bridge->b_type0_cfg_dev[pciio_slot].f[pciio_func].l; cfgbase = pcibr_func_config_addr(bridge,
pciio_bus, pciio_slot, pciio_func, 0);
return cfgbase; return cfgbase;
} }
extern unsigned char Is_pic_on_this_nasid[];
uint64_t uint64_t
pcibr_config_get(devfs_handle_t conn, pcibr_config_get(devfs_handle_t conn,
unsigned reg, unsigned reg,
unsigned size) unsigned size)
{ {
return do_pcibr_config_get(pcibr_config_addr(conn, reg), if ( !Is_pic_on_this_nasid[ NASID_GET((pcibr_config_addr(conn, reg)))] )
return do_pcibr_config_get(0, pcibr_config_addr(conn, reg),
PCI_TYPE1_REG(reg), size);
else
return do_pcibr_config_get(1, pcibr_config_addr(conn, reg),
PCI_TYPE1_REG(reg), size); PCI_TYPE1_REG(reg), size);
} }
uint64_t uint64_t
do_pcibr_config_get( do_pcibr_config_get(
int pic,
cfg_p cfgbase, cfg_p cfgbase,
unsigned reg, unsigned reg,
unsigned size) unsigned size)
{ {
unsigned value; unsigned value;
if ( pic ) {
value = CWP(cfgbase, reg);
}
else {
if ( io_get_sh_swapper(NASID_GET(cfgbase)) ) {
/*
* Shub Swapper on - 0 returns PCI Offset 0 but byte swapped!
* Do not swizzle address and byte swap the result.
*/
value = SCW(cfgbase, reg);
value = __swab32(value);
} else {
value = CW(cfgbase, reg); value = CW(cfgbase, reg);
}
}
if (reg & 3) if (reg & 3)
value >>= 8 * (reg & 3); value >>= 8 * (reg & 3);
if (size < 4) if (size < 4)
...@@ -105,16 +275,48 @@ pcibr_config_set(devfs_handle_t conn, ...@@ -105,16 +275,48 @@ pcibr_config_set(devfs_handle_t conn,
unsigned size, unsigned size,
uint64_t value) uint64_t value)
{ {
do_pcibr_config_set(pcibr_config_addr(conn, reg), if ( Is_pic_on_this_nasid[ NASID_GET((pcibr_config_addr(conn, reg)))] )
do_pcibr_config_set(1, pcibr_config_addr(conn, reg),
PCI_TYPE1_REG(reg), size, value);
else
swap_do_pcibr_config_set(pcibr_config_addr(conn, reg),
PCI_TYPE1_REG(reg), size, value); PCI_TYPE1_REG(reg), size, value);
} }
void void
do_pcibr_config_set(cfg_p cfgbase, do_pcibr_config_set(int pic,
cfg_p cfgbase,
unsigned reg, unsigned reg,
unsigned size, unsigned size,
uint64_t value) uint64_t value)
{ {
if ( pic ) {
switch (size) {
case 1:
CBP(cfgbase, reg) = value;
break;
case 2:
if (reg & 1) {
CBP(cfgbase, reg) = value;
CBP(cfgbase, reg + 1) = value >> 8;
} else
CSP(cfgbase, reg) = value;
break;
case 3:
if (reg & 1) {
CBP(cfgbase, reg) = value;
CSP(cfgbase, (reg + 1)) = value >> 8;
} else {
CSP(cfgbase, reg) = value;
CBP(cfgbase, reg + 2) = value >> 16;
}
break;
case 4:
CWP(cfgbase, reg) = value;
break;
}
}
else {
switch (size) { switch (size) {
case 1: case 1:
CB(cfgbase, reg) = value; CB(cfgbase, reg) = value;
...@@ -135,9 +337,41 @@ do_pcibr_config_set(cfg_p cfgbase, ...@@ -135,9 +337,41 @@ do_pcibr_config_set(cfg_p cfgbase,
CB(cfgbase, reg + 2) = value >> 16; CB(cfgbase, reg + 2) = value >> 16;
} }
break; break;
case 4: case 4:
CW(cfgbase, reg) = value; CW(cfgbase, reg) = value;
break; break;
} }
}
}
void
swap_do_pcibr_config_set(cfg_p cfgbase,
unsigned reg,
unsigned size,
uint64_t value)
{
uint64_t temp_value = 0;
switch (size) {
case 1:
SCB(cfgbase, reg) = value;
break;
case 2:
temp_value = __swab16(value);
if (reg & 1) {
SCB(cfgbase, reg) = temp_value;
SCB(cfgbase, reg + 1) = temp_value >> 8;
} else
SCS(cfgbase, reg) = temp_value;
break;
case 3:
BUG();
break;
case 4:
temp_value = __swab32(value);
SCW(cfgbase, reg) = temp_value;
break;
}
} }
This diff is collapsed.
This diff is collapsed.
...@@ -85,11 +85,9 @@ pcibr_hints_fix_some_rrbs(devfs_handle_t xconn_vhdl, unsigned mask) ...@@ -85,11 +85,9 @@ pcibr_hints_fix_some_rrbs(devfs_handle_t xconn_vhdl, unsigned mask)
if (hint) if (hint)
hint->ph_rrb_fixed = mask; hint->ph_rrb_fixed = mask;
#if DEBUG
else else
printk("pcibr_hints_fix_rrbs: pcibr_hints_get failed at\n" PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_HINTS, xconn_vhdl,
"\t%p\n", xconn_vhdl); "pcibr_hints_fix_rrbs: pcibr_hints_get failed\n"));
#endif
} }
void void
...@@ -107,11 +105,9 @@ pcibr_hints_dualslot(devfs_handle_t xconn_vhdl, ...@@ -107,11 +105,9 @@ pcibr_hints_dualslot(devfs_handle_t xconn_vhdl,
if (hint) if (hint)
hint->ph_host_slot[guest] = host + 1; hint->ph_host_slot[guest] = host + 1;
#if DEBUG
else else
printk("pcibr_hints_dualslot: pcibr_hints_get failed at\n" PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_HINTS, xconn_vhdl,
"\t%p\n", xconn_vhdl); "pcibr_hints_dualslot: pcibr_hints_get failed\n"));
#endif
} }
void void
...@@ -122,11 +118,9 @@ pcibr_hints_intr_bits(devfs_handle_t xconn_vhdl, ...@@ -122,11 +118,9 @@ pcibr_hints_intr_bits(devfs_handle_t xconn_vhdl,
if (hint) if (hint)
hint->ph_intr_bits = xxx_intr_bits; hint->ph_intr_bits = xxx_intr_bits;
#if DEBUG
else else
printk("pcibr_hints_intr_bits: pcibr_hints_get failed at\n" PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_HINTS, xconn_vhdl,
"\t%p\n", xconn_vhdl); "pcibr_hints_intr_bits: pcibr_hints_get failed\n"));
#endif
} }
void void
...@@ -145,11 +139,9 @@ pcibr_hints_handsoff(devfs_handle_t xconn_vhdl) ...@@ -145,11 +139,9 @@ pcibr_hints_handsoff(devfs_handle_t xconn_vhdl)
if (hint) if (hint)
hint->ph_hands_off = 1; hint->ph_hands_off = 1;
#if DEBUG
else else
printk("pcibr_hints_handsoff: pcibr_hints_get failed at\n" PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_HINTS, xconn_vhdl,
"\t%p\n", xconn_vhdl); "pcibr_hints_handsoff: pcibr_hints_get failed\n"));
#endif
} }
void void
...@@ -161,13 +153,11 @@ pcibr_hints_subdevs(devfs_handle_t xconn_vhdl, ...@@ -161,13 +153,11 @@ pcibr_hints_subdevs(devfs_handle_t xconn_vhdl,
char sdname[16]; char sdname[16];
devfs_handle_t pconn_vhdl = GRAPH_VERTEX_NONE; devfs_handle_t pconn_vhdl = GRAPH_VERTEX_NONE;
sprintf(sdname, "pci/%d", slot); sprintf(sdname, "%s/%d", EDGE_LBL_PCI, slot);
(void) hwgraph_path_add(xconn_vhdl, sdname, &pconn_vhdl); (void) hwgraph_path_add(xconn_vhdl, sdname, &pconn_vhdl);
if (pconn_vhdl == GRAPH_VERTEX_NONE) { if (pconn_vhdl == GRAPH_VERTEX_NONE) {
#if DEBUG PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_HINTS, xconn_vhdl,
printk("pcibr_hints_subdevs: hwgraph_path_create failed at\n" "pcibr_hints_subdevs: hwgraph_path_create failed\n"));
"\t%p (seeking %s)\n", xconn_vhdl, sdname);
#endif
return; return;
} }
hwgraph_info_get_LBL(pconn_vhdl, INFO_LBL_SUBDEVS, &ainfo); hwgraph_info_get_LBL(pconn_vhdl, INFO_LBL_SUBDEVS, &ainfo);
...@@ -176,10 +166,8 @@ pcibr_hints_subdevs(devfs_handle_t xconn_vhdl, ...@@ -176,10 +166,8 @@ pcibr_hints_subdevs(devfs_handle_t xconn_vhdl,
NEW(subdevp); NEW(subdevp);
if (!subdevp) { if (!subdevp) {
#if DEBUG PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_HINTS, xconn_vhdl,
printk("pcibr_hints_subdevs: subdev ptr alloc failed at\n" "pcibr_hints_subdevs: subdev ptr alloc failed\n"));
"\t%p\n", pconn_vhdl);
#endif
return; return;
} }
*subdevp = subdevs; *subdevp = subdevs;
...@@ -189,16 +177,12 @@ pcibr_hints_subdevs(devfs_handle_t xconn_vhdl, ...@@ -189,16 +177,12 @@ pcibr_hints_subdevs(devfs_handle_t xconn_vhdl,
return; return;
DEL(subdevp); DEL(subdevp);
if (ainfo == (arbitrary_info_t) NULL) { if (ainfo == (arbitrary_info_t) NULL) {
#if DEBUG PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_HINTS, xconn_vhdl,
printk("pcibr_hints_subdevs: null subdevs ptr at\n" "pcibr_hints_subdevs: null subdevs ptr\n"));
"\t%p\n", pconn_vhdl);
#endif
return; return;
} }
#if DEBUG PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_HINTS, xconn_vhdl,
printk("pcibr_subdevs_get: dup subdev add_LBL at\n" "pcibr_subdevs_get: dup subdev add_LBL\n"));
"\t%p\n", pconn_vhdl);
#endif
} }
*(uint64_t *) ainfo = subdevs; *(uint64_t *) ainfo = subdevs;
} }
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
/* $Id: shub_intr.c,v 1.2 2001/06/26 14:02:43 pfg Exp $ /* $Id: shub_intr.c,v 1.1 2002/02/28 17:31:25 marcelo Exp $
* *
* This file is subject to the terms and conditions of the GNU General Public * 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 * License. See the file "COPYING" in the main directory of this archive
...@@ -25,21 +25,13 @@ ...@@ -25,21 +25,13 @@
#include <asm/sn/intr.h> #include <asm/sn/intr.h>
#include <asm/sn/xtalk/xtalkaddrs.h> #include <asm/sn/xtalk/xtalkaddrs.h>
#include <asm/sn/klconfig.h> #include <asm/sn/klconfig.h>
#include <asm/sn/sn2/shub_mmr.h>
#include <asm/sn/sn_cpuid.h> #include <asm/sn/sn_cpuid.h>
extern void hub_device_desc_update(device_desc_t, ilvl_t, cpuid_t);
/* ARGSUSED */ /* ARGSUSED */
void void
hub_intr_init(devfs_handle_t hubv) hub_intr_init(devfs_handle_t hubv)
{ {
extern void sn_cpei_handler(int, void *, struct pt_regs *);
extern void sn_init_cpei_timer(void);
if (request_irq(SGI_SHUB_ERROR_VECTOR, sn_cpei_handler, 0, "SN hub error", NULL) ) {
printk("hub_intr_init: Couldn't register SGI_SHUB_ERROR_VECTOR = %x\n",SGI_SHUB_ERROR_VECTOR);
}
sn_init_cpei_timer();
} }
xwidgetnum_t xwidgetnum_t
...@@ -79,14 +71,12 @@ do_hub_intr_alloc(devfs_handle_t dev, ...@@ -79,14 +71,12 @@ do_hub_intr_alloc(devfs_handle_t dev,
cpuphys = cpu_physical_id(cpu); cpuphys = cpu_physical_id(cpu);
slice = cpu_physical_id_to_slice(cpuphys); slice = cpu_physical_id_to_slice(cpuphys);
nasid = cpu_physical_id_to_nasid(cpuphys); nasid = cpu_physical_id_to_nasid(cpuphys);
cnode = cpuid_to_cnodeid(cpu); cnode = cpu_to_node_map[cpu];
if (slice) { if (slice) {
xtalk_addr = SH_II_INT1 | GLOBAL_MMR_SPACE | xtalk_addr = SH_II_INT1 | ((unsigned long)nasid << 36) | (1UL << 47);
((unsigned long)nasid << 36) | (1UL << 47);
} else { } else {
xtalk_addr = SH_II_INT0 | GLOBAL_MMR_SPACE | xtalk_addr = SH_II_INT0 | ((unsigned long)nasid << 36) | (1UL << 47);
((unsigned long)nasid << 36) | (1UL << 47);
} }
intr_hdl = snia_kmem_alloc_node(sizeof(struct hub_intr_s), KM_NOSLEEP, cnode); intr_hdl = snia_kmem_alloc_node(sizeof(struct hub_intr_s), KM_NOSLEEP, cnode);
...@@ -107,7 +97,6 @@ do_hub_intr_alloc(devfs_handle_t dev, ...@@ -107,7 +97,6 @@ do_hub_intr_alloc(devfs_handle_t dev,
intr_hdl->i_bit = vector; intr_hdl->i_bit = vector;
intr_hdl->i_flags |= HUB_INTR_IS_ALLOCED; intr_hdl->i_flags |= HUB_INTR_IS_ALLOCED;
hub_device_desc_update(dev_desc, intr_swlevel, cpu);
return(intr_hdl); return(intr_hdl);
} }
...@@ -136,7 +125,7 @@ hub_intr_free(hub_intr_t intr_hdl) ...@@ -136,7 +125,7 @@ hub_intr_free(hub_intr_t intr_hdl)
if (intr_hdl->i_flags & HUB_INTR_IS_CONNECTED) { if (intr_hdl->i_flags & HUB_INTR_IS_CONNECTED) {
xtalk_info = &intr_hdl->i_xtalk_info; xtalk_info = &intr_hdl->i_xtalk_info;
xtalk_info->xi_dev = NODEV; xtalk_info->xi_dev = 0;
xtalk_info->xi_vector = 0; xtalk_info->xi_vector = 0;
xtalk_info->xi_addr = 0; xtalk_info->xi_addr = 0;
hub_intr_disconnect(intr_hdl); hub_intr_disconnect(intr_hdl);
...@@ -150,6 +139,8 @@ hub_intr_free(hub_intr_t intr_hdl) ...@@ -150,6 +139,8 @@ hub_intr_free(hub_intr_t intr_hdl)
int int
hub_intr_connect(hub_intr_t intr_hdl, hub_intr_connect(hub_intr_t intr_hdl,
intr_func_t intr_func, /* xtalk intr handler */
void *intr_arg, /* arg to intr handler */
xtalk_intr_setfunc_t setfunc, xtalk_intr_setfunc_t setfunc,
void *setfunc_arg) void *setfunc_arg)
{ {
...@@ -160,7 +151,6 @@ hub_intr_connect(hub_intr_t intr_hdl, ...@@ -160,7 +151,6 @@ hub_intr_connect(hub_intr_t intr_hdl,
ASSERT(intr_hdl->i_flags & HUB_INTR_IS_ALLOCED); ASSERT(intr_hdl->i_flags & HUB_INTR_IS_ALLOCED);
rv = intr_connect_level(cpu, vector, intr_hdl->i_swlevel, NULL); rv = intr_connect_level(cpu, vector, intr_hdl->i_swlevel, NULL);
if (rv < 0) { if (rv < 0) {
return rv; return rv;
} }
......
/* $Id$ /* $Id: shuberror.c,v 1.1 2002/02/28 17:31:25 marcelo Exp $
* *
* This file is subject to the terms and conditions of the GNU General Public * 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 * License. See the file "COPYING" in the main directory of this archive
...@@ -10,6 +10,8 @@ ...@@ -10,6 +10,8 @@
#include <linux/types.h> #include <linux/types.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/irq.h>
#include <asm/irq.h>
#include <asm/smp.h> #include <asm/smp.h>
#include <asm/sn/sgi.h> #include <asm/sn/sgi.h>
#include <asm/sn/io.h> #include <asm/sn/io.h>
...@@ -34,12 +36,18 @@ extern void hubii_eint_init(cnodeid_t cnode); ...@@ -34,12 +36,18 @@ extern void hubii_eint_init(cnodeid_t cnode);
extern void hubii_eint_handler (int irq, void *arg, struct pt_regs *ep); extern void hubii_eint_handler (int irq, void *arg, struct pt_regs *ep);
int hubiio_crb_error_handler(devfs_handle_t hub_v, hubinfo_t hinfo); int hubiio_crb_error_handler(devfs_handle_t hub_v, hubinfo_t hinfo);
int hubiio_prb_error_handler(devfs_handle_t hub_v, hubinfo_t hinfo); int hubiio_prb_error_handler(devfs_handle_t hub_v, hubinfo_t hinfo);
extern void bte_crb_error_handler(devfs_handle_t hub_v, int btenum, int crbnum, ioerror_t *ioe); extern void bte_crb_error_handler(devfs_handle_t hub_v, int btenum, int crbnum, ioerror_t *ioe, int bteop);
extern int maxcpus; extern int maxcpus;
#define HUB_ERROR_PERIOD (120 * HZ) /* 2 minutes */ #define HUB_ERROR_PERIOD (120 * HZ) /* 2 minutes */
#ifdef BUS_INT_WAR
void sn_add_polled_interrupt(int irq, int interval);
void sn_delete_polled_interrupt(int irq);
extern int bus_int_war_ide_irq;
#endif
void void
hub_error_clear(nasid_t nasid) hub_error_clear(nasid_t nasid)
...@@ -118,9 +126,7 @@ hubii_eint_init(cnodeid_t cnode) ...@@ -118,9 +126,7 @@ hubii_eint_init(cnodeid_t cnode)
hubinfo_t hinfo; hubinfo_t hinfo;
cpuid_t intr_cpu; cpuid_t intr_cpu;
devfs_handle_t hub_v; devfs_handle_t hub_v;
ii_ilcsr_u_t ilcsr;
int bit_pos_to_irq(int bit); int bit_pos_to_irq(int bit);
int synergy_intr_connect(int bit, int cpuid);
hub_v = (devfs_handle_t)cnodeid_to_vertex(cnode); hub_v = (devfs_handle_t)cnodeid_to_vertex(cnode);
...@@ -130,17 +136,6 @@ hubii_eint_init(cnodeid_t cnode) ...@@ -130,17 +136,6 @@ hubii_eint_init(cnodeid_t cnode)
ASSERT(hinfo); ASSERT(hinfo);
ASSERT(hinfo->h_cnodeid == cnode); ASSERT(hinfo->h_cnodeid == cnode);
ilcsr.ii_ilcsr_regval = REMOTE_HUB_L(hinfo->h_nasid, IIO_ILCSR);
if ((ilcsr.ii_ilcsr_fld_s.i_llp_stat & 0x2) == 0) {
/*
* HUB II link is not up.
* Just disable LLP, and don't connect any interrupts.
*/
ilcsr.ii_ilcsr_fld_s.i_llp_en = 0;
REMOTE_HUB_S(hinfo->h_nasid, IIO_ILCSR, ilcsr.ii_ilcsr_regval);
return;
}
/* Select a possible interrupt target where there is a free interrupt /* Select a possible interrupt target where there is a free interrupt
* bit and also reserve the interrupt bit for this IO error interrupt * bit and also reserve the interrupt bit for this IO error interrupt
*/ */
...@@ -152,7 +147,11 @@ hubii_eint_init(cnodeid_t cnode) ...@@ -152,7 +147,11 @@ hubii_eint_init(cnodeid_t cnode)
} }
rv = intr_connect_level(intr_cpu, bit, 0, NULL); rv = intr_connect_level(intr_cpu, bit, 0, NULL);
request_irq(bit + (intr_cpu << 8), hubii_eint_handler, 0, "SN hub error", (void *)hub_v); request_irq(bit + (intr_cpu << 8), hubii_eint_handler, 0, "SN_hub_error", (void *)hub_v);
irq_desc(bit + (intr_cpu << 8))->status |= SN2_IRQ_PER_HUB;
#ifdef BUS_INT_WAR
sn_add_polled_interrupt(bit + (intr_cpu << 8), (0.01 * HZ));
#endif
ASSERT_ALWAYS(rv >= 0); ASSERT_ALWAYS(rv >= 0);
hubio_eint.ii_iidsr_regval = 0; hubio_eint.ii_iidsr_regval = 0;
hubio_eint.ii_iidsr_fld_s.i_enable = 1; hubio_eint.ii_iidsr_fld_s.i_enable = 1;
...@@ -257,15 +256,16 @@ hubii_eint_handler (int irq, void *arg, struct pt_regs *ep) ...@@ -257,15 +256,16 @@ hubii_eint_handler (int irq, void *arg, struct pt_regs *ep)
void void
hubiio_crb_free(hubinfo_t hinfo, int crbnum) hubiio_crb_free(hubinfo_t hinfo, int crbnum)
{ {
ii_icrb0_a_u_t icrba; ii_icrb0_b_u_t icrbb;
/* /*
* The hardware does NOT clear the mark bit, so it must get cleared * The hardware does NOT clear the mark bit, so it must get cleared
* here to be sure the error is not processed twice. * here to be sure the error is not processed twice.
*/ */
icrba.ii_icrb0_a_regval = REMOTE_HUB_L(hinfo->h_nasid, IIO_ICRB_A(crbnum)); icrbb.ii_icrb0_b_regval = REMOTE_HUB_L(hinfo->h_nasid, IIO_ICRB_B(crbnum));
icrba.a_valid = 0; icrbb.b_mark = 0;
REMOTE_HUB_S(hinfo->h_nasid, IIO_ICRB_A(crbnum), icrba.ii_icrb0_a_regval); REMOTE_HUB_S(hinfo->h_nasid, IIO_ICRB_B(crbnum), icrbb.ii_icrb0_b_regval);
/* /*
* Deallocate the register. * Deallocate the register.
*/ */
...@@ -325,9 +325,11 @@ hubiio_crb_error_handler(devfs_handle_t hub_v, hubinfo_t hinfo) ...@@ -325,9 +325,11 @@ hubiio_crb_error_handler(devfs_handle_t hub_v, hubinfo_t hinfo)
ii_icrb0_b_u_t icrbb; /* II CRB Register B */ ii_icrb0_b_u_t icrbb; /* II CRB Register B */
ii_icrb0_c_u_t icrbc; /* II CRB Register C */ ii_icrb0_c_u_t icrbc; /* II CRB Register C */
ii_icrb0_d_u_t icrbd; /* II CRB Register D */ ii_icrb0_d_u_t icrbd; /* II CRB Register D */
ii_icrb0_e_u_t icrbe; /* II CRB Register D */
int i; int i;
int num_errors = 0; /* Num of errors handled */ int num_errors = 0; /* Num of errors handled */
ioerror_t ioerror; ioerror_t ioerror;
int rc;
nasid = hinfo->h_nasid; nasid = hinfo->h_nasid;
cnode = NASID_TO_COMPACT_NODEID(nasid); cnode = NASID_TO_COMPACT_NODEID(nasid);
...@@ -337,16 +339,24 @@ hubiio_crb_error_handler(devfs_handle_t hub_v, hubinfo_t hinfo) ...@@ -337,16 +339,24 @@ hubiio_crb_error_handler(devfs_handle_t hub_v, hubinfo_t hinfo)
* in any of the CRBs marked. * in any of the CRBs marked.
*/ */
for (i = 0; i < IIO_NUM_CRBS; i++) { for (i = 0; i < IIO_NUM_CRBS; i++) {
/* Check this crb entry to see if it is in error. */
icrbb.ii_icrb0_b_regval = REMOTE_HUB_L(nasid, IIO_ICRB_B(i));
if (icrbb.b_mark == 0) {
continue;
}
icrba.ii_icrb0_a_regval = REMOTE_HUB_L(nasid, IIO_ICRB_A(i)); icrba.ii_icrb0_a_regval = REMOTE_HUB_L(nasid, IIO_ICRB_A(i));
IOERROR_INIT(&ioerror); IOERROR_INIT(&ioerror);
/* read other CRB error registers. */ /* read other CRB error registers. */
icrbb.ii_icrb0_b_regval = REMOTE_HUB_L(nasid, IIO_ICRB_B(i));
icrbc.ii_icrb0_c_regval = REMOTE_HUB_L(nasid, IIO_ICRB_C(i)); icrbc.ii_icrb0_c_regval = REMOTE_HUB_L(nasid, IIO_ICRB_C(i));
icrbd.ii_icrb0_d_regval = REMOTE_HUB_L(nasid, IIO_ICRB_D(i)); icrbd.ii_icrb0_d_regval = REMOTE_HUB_L(nasid, IIO_ICRB_D(i));
icrbe.ii_icrb0_e_regval = REMOTE_HUB_L(nasid, IIO_ICRB_E(i));
IOERROR_SETVALUE(&ioerror,errortype,icrbb.b_ecode); IOERROR_SETVALUE(&ioerror,errortype,icrbb.b_ecode);
/* Check if this error is due to BTE operation, /* Check if this error is due to BTE operation,
* and handle it separately. * and handle it separately.
*/ */
...@@ -363,8 +373,15 @@ hubiio_crb_error_handler(devfs_handle_t hub_v, hubinfo_t hinfo) ...@@ -363,8 +373,15 @@ hubiio_crb_error_handler(devfs_handle_t hub_v, hubinfo_t hinfo)
else /* b_initiator bit 2 gives BTE number */ else /* b_initiator bit 2 gives BTE number */
bte_num = (icrbb.b_initiator & 0x4) >> 2; bte_num = (icrbb.b_initiator & 0x4) >> 2;
/* >>> bte_crb_error_handler needs to be
* broken into two parts. The first should
* cleanup the CRB. The second should wait
* until all bte related CRB's are complete
* and then do the error reset.
*/
bte_crb_error_handler(hub_v, bte_num, bte_crb_error_handler(hub_v, bte_num,
i, &ioerror); i, &ioerror,
icrbd.d_bteop);
hubiio_crb_free(hinfo, i); hubiio_crb_free(hinfo, i);
num_errors++; num_errors++;
continue; continue;
...@@ -401,13 +418,144 @@ hubiio_crb_error_handler(devfs_handle_t hub_v, hubinfo_t hinfo) ...@@ -401,13 +418,144 @@ hubiio_crb_error_handler(devfs_handle_t hub_v, hubinfo_t hinfo)
*/ */
IOERROR_SETVALUE(&ioerror,widgetdev, IOERROR_SETVALUE(&ioerror,widgetdev,
TNUM_TO_WIDGET_DEV(icrba.a_tnum)); TNUM_TO_WIDGET_DEV(icrba.a_tnum));
/*
* The encoding of TNUM (see comments above) is
* different for PIC. So we'll save TNUM here and
* deal with the differences later when we can
* determine if we're using a Bridge or the PIC.
*
* XXX: We may be able to remove saving the widgetdev
* above and just sort it out of TNUM later.
*/
IOERROR_SETVALUE(&ioerror, tnum, icrba.a_tnum);
}
if (icrbb.b_error) {
/*
* CRB 'i' has some error. Identify the type of error,
* and try to handle it.
*/
switch(icrbb.b_ecode) {
case IIO_ICRB_ECODE_PERR:
case IIO_ICRB_ECODE_WERR:
case IIO_ICRB_ECODE_AERR:
case IIO_ICRB_ECODE_PWERR:
printk("%s on hub cnodeid: %d",
hubiio_crb_errors[icrbb.b_ecode], cnode);
/*
* Any sort of write error is mostly due
* bad programming (Note it's not a timeout.)
* So, invoke hub_iio_error_handler with
* appropriate information.
*/
IOERROR_SETVALUE(&ioerror,errortype,icrbb.b_ecode);
rc = hub_ioerror_handler(
hub_v,
DMA_WRITE_ERROR,
MODE_DEVERROR,
&ioerror);
if (rc == IOERROR_HANDLED) {
rc = hub_ioerror_handler(
hub_v,
DMA_WRITE_ERROR,
MODE_DEVREENABLE,
&ioerror);
ASSERT(rc == IOERROR_HANDLED);
}else {
panic("Unable to handle %s on hub %d",
hubiio_crb_errors[icrbb.b_ecode],
cnode);
/*NOTREACHED*/
}
/* Go to Next error */
hubiio_crb_free(hinfo, i);
continue;
case IIO_ICRB_ECODE_PRERR:
case IIO_ICRB_ECODE_TOUT:
case IIO_ICRB_ECODE_XTERR:
case IIO_ICRB_ECODE_DERR:
panic("Fatal %s on hub : %d",
hubiio_crb_errors[icrbb.b_ecode], cnode);
/*NOTREACHED*/
default:
panic("Fatal error (code : %d) on hub : %d",
cnode);
/*NOTREACHED*/
} }
} /* if (icrbb.b_error) */
/*
* Error is not indicated via the errcode field
* Check other error indications in this register.
*/
if (icrbb.b_xerr) {
panic("Xtalk Packet with error bit set to hub %d",
cnode);
/*NOTREACHED*/
}
if (icrbb.b_lnetuce) {
panic("Uncorrectable data error detected on data "
" from Craylink to node %d",
cnode);
/*NOTREACHED*/
}
} }
return num_errors; return num_errors;
} }
/*
* hubii_check_widget_disabled
*
* Check if PIO access to the specified widget is disabled due
* to any II errors that are currently set.
*
* The specific error bits checked are:
* IPRBx register: SPUR_RD (51)
* SPUR_WR (50)
* RD_TO (49)
* ERROR (48)
*
* WSTAT register: CRAZY (32)
*/
int
hubii_check_widget_disabled(nasid_t nasid, int wnum)
{
iprb_t iprb;
ii_wstat_u_t wstat;
iprb.iprb_regval = REMOTE_HUB_L(nasid, IIO_IOPRB(wnum));
if (iprb.iprb_regval & (IIO_PRB_SPUR_RD | IIO_PRB_SPUR_WR |
IIO_PRB_RD_TO | IIO_PRB_ERROR)) {
#ifdef DEBUG
printk(KERN_WARNING "II error, IPRB%x=0x%lx\n", wnum, iprb.iprb_regval);
#endif
return(1);
}
wstat.ii_wstat_regval = REMOTE_HUB_L(nasid, IIO_WSTAT);
if (wstat.ii_wstat_regval & IIO_WSTAT_ECRAZY) {
#ifdef DEBUG
printk(KERN_WARNING "II error, WSTAT=0x%lx\n", wstat.ii_wstat_regval);
#endif
return(1);
}
return(0);
}
/*ARGSUSED*/ /*ARGSUSED*/
/* /*
* hubii_prb_handler * hubii_prb_handler
......
...@@ -9,8 +9,9 @@ ...@@ -9,8 +9,9 @@
#include <linux/types.h> #include <linux/types.h>
#include <linux/ctype.h> #include <linux/ctype.h>
#include <linux/mm.h> #include <linux/mmzone.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <asm/sn/arch.h>
#include <asm/sn/sgi.h> #include <asm/sn/sgi.h>
#include <asm/sn/invent.h> #include <asm/sn/invent.h>
#include <asm/sn/hcl.h> #include <asm/sn/hcl.h>
...@@ -28,8 +29,8 @@ ...@@ -28,8 +29,8 @@
int pcibr_prefetch_enable_rev, pcibr_wg_enable_rev; int pcibr_prefetch_enable_rev, pcibr_wg_enable_rev;
int default_intr_pri; int default_intr_pri;
int force_fire_and_forget; int force_fire_and_forget = 1;
int ignore_conveyor_override; int ignore_conveyor_override = 0;
devfs_handle_t dummy_vrtx; /* Needed for cpuid_to_vertex() in hack.h */ devfs_handle_t dummy_vrtx; /* Needed for cpuid_to_vertex() in hack.h */
...@@ -53,54 +54,24 @@ is_sys_critical_vertex(devfs_handle_t x) ...@@ -53,54 +54,24 @@ is_sys_critical_vertex(devfs_handle_t x)
return(0); return(0);
} }
char *
nic_bridge_vertex_info(devfs_handle_t v, nic_data_t mcr)
{
FIXME("nic_bridge_vertex_info : returns NULL");
return((char *)0);
}
void *
snia_kmem_alloc_node(register size_t size, register int flags, cnodeid_t node)
{
/* Allocates on node 'node' */
FIXME("snia_kmem_alloc_node : use kmalloc");
return(kmalloc(size, GFP_KERNEL));
}
void *
snia_kmem_zalloc_node(register size_t size, register int flags, cnodeid_t node)
{
FIXME("snia_kmem_zalloc_node : use kmalloc");
return(kmalloc(size, GFP_KERNEL));
}
void
snia_kmem_free(void *where, int size)
{
FIXME("snia_kmem_free : use kfree");
return(kfree(where));
}
void * void *
snia_kmem_zone_alloc(register zone_t *zone, int flags) snia_kmem_zone_alloc(register struct zone *zone, int flags)
{ {
FIXME("snia_kmem_zone_alloc : return null"); FIXME("snia_kmem_zone_alloc : return null");
return((void *)0); return((void *)0);
} }
void void
snia_kmem_zone_free(register zone_t *zone, void *ptr) snia_kmem_zone_free(register struct zone *zone, void *ptr)
{ {
FIXME("snia_kmem_zone_free : no-op"); FIXME("snia_kmem_zone_free : no-op");
} }
zone_t * struct zone *
snia_kmem_zone_init(register int size, char *zone_name) snia_kmem_zone_init(register int size, char *zone_name)
{ {
FIXME("snia_kmem_zone_free : returns NULL"); FIXME("snia_kmem_zone_free : returns NULL");
return((zone_t *)0); return((struct zone *)0);
} }
int int
...@@ -115,13 +86,6 @@ compare_and_swap_ptr(void **location, void *old_ptr, void *new_ptr) ...@@ -115,13 +86,6 @@ compare_and_swap_ptr(void **location, void *old_ptr, void *new_ptr)
return(0); return(0);
} }
void *
swap_ptr(void **loc, void *new)
{
FIXME("swap_ptr : returns null");
return((void *)0);
}
/* For ml/SN/SN1/slots.c */ /* For ml/SN/SN1/slots.c */
/* ARGSUSED */ /* ARGSUSED */
slotid_t get_widget_slotnum(int xbow, int widget) slotid_t get_widget_slotnum(int xbow, int widget)
...@@ -153,10 +117,8 @@ nic_vmc_check(devfs_handle_t vhdl, char *nicinfo) ...@@ -153,10 +117,8 @@ nic_vmc_check(devfs_handle_t vhdl, char *nicinfo)
char * char *
nic_vertex_info_get(devfs_handle_t v) nic_vertex_info_get(devfs_handle_t v)
{ {
FIXME("nic_vertex_info_get\n"); FIXME("nic_vertex_info_get\n");
return(NULL); return(NULL);
} }
int int
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
* License. See the file "COPYING" in the main directory of this archive * License. See the file "COPYING" in the main directory of this archive
* for more details. * for more details.
* *
* Copyright (C) 1992 - 1997, 2000-2001 Silicon Graphics, Inc. All rights reserved. * Copyright (C) 1992-1997,2000-2002 Silicon Graphics, Inc. All rights reserved.
*/ */
#include <linux/types.h> #include <linux/types.h>
......
# arch/ia64/sn/Makefile # arch/ia64/sn/kernel/Makefile
# #
# Copyright (C) 1999,2001-2002 Silicon Graphics, Inc. All Rights Reserved. # Copyright (C) 1999,2001-2002 Silicon Graphics, Inc. All Rights Reserved.
# #
...@@ -33,14 +33,17 @@ ...@@ -33,14 +33,17 @@
EXTRA_CFLAGS := -DLITTLE_ENDIAN EXTRA_CFLAGS := -DLITTLE_ENDIAN
export-objs := sn_ksyms.o .S.s:
$(CPP) $(AFLAGS) $(AFLAGS_KERNEL) -o $*.s $<
.S.o:
$(CC) $(AFLAGS) $(AFLAGS_KERNEL) -c -o $*.o $<
obj-y = probe.o setup.o sn_asm.o sv.o bte.o export-objs = sn_ksyms.o iomv.o
obj-$(CONFIG_IA64_SGI_SN1) += irq.o mca.o sn1/
obj-$(CONFIG_IA64_SGI_SN2) += irq.o mca.o sn2/ obj-y = probe.o setup.o sn_asm.o sv.o bte.o iomv.o
obj-$(CONFIG_IA64_SGI_SN1) += irq.o mca.o
obj-$(CONFIG_IA64_SGI_SN2) += irq.o mca.o
obj-$(CONFIG_IA64_SGI_AUTOTEST) += llsc4.o misctest.o obj-$(CONFIG_IA64_SGI_AUTOTEST) += llsc4.o misctest.o
obj-$(CONFIG_IA64_GENERIC) += machvec.o obj-$(CONFIG_IA64_GENERIC) += machvec.o
obj-$(CONFIG_MODULES) += sn_ksyms.o obj-$(CONFIG_MODULES) += sn_ksyms.o
obj-$(CONFIG_IA64_SGI_SN_BRT) += bte_regr_test.o
include $(TOPDIR)/Rules.make
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
* License. See the file "COPYING" in the main directory of this archive * License. See the file "COPYING" in the main directory of this archive
* for more details. * for more details.
* *
* Copyright (C) 2000-2001 Silicon Graphics, Inc. All rights reserved. * Copyright (C) 2000-2002 Silicon Graphics, Inc. All rights reserved.
*/ */
#ifdef STANDALONE #ifdef STANDALONE
...@@ -103,5 +103,5 @@ typedef struct { ...@@ -103,5 +103,5 @@ typedef struct {
int llsc_main (int cpuid, long mbasex); int llsc_main (int cpuid);
/*
* Copyright (c) 2002 Silicon Graphics, Inc. All Rights Reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it would be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
* Further, this software is distributed without any warranty that it is
* free of the rightful claim of any third person regarding infringement
* or the like. Any license provided herein, whether implied or
* otherwise, applies only to this software file. Patent licenses, if
* any, provided herein do not apply to combinations of this program with
* other software, or any other product whatsoever.
*
* You should have received a copy of the GNU General Public
* License along with this program; if not, write the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
*
* Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
* Mountain View, CA 94043, or:
*
* http://www.sgi.com
*
* For further information regarding this notice, see:
*
* http://oss.sgi.com/projects/GenInfo/NoticeExplan
*/
#include <linux/config.h>
#ifdef CONFIG_IA64_SGI_SN1
#define MACHVEC_PLATFORM_NAME sn1 #define MACHVEC_PLATFORM_NAME sn1
#else CONFIG_IA64_SGI_SN1
#define MACHVEC_PLATFORM_NAME sn2
#else
#error "unknown platform"
#endif
#include <asm/machvec_init.h> #include <asm/machvec_init.h>
#include <asm/io.h> #include <asm/io.h>
#include <linux/pci.h> #include <linux/pci.h>
void* void*
sn1_mk_io_addr_MACRO sn_mk_io_addr_MACRO
dma_addr_t dma_addr_t
sn1_pci_map_single_MACRO sn_pci_map_single_MACRO
int int
sn1_pci_map_sg_MACRO sn_pci_map_sg_MACRO
unsigned long unsigned long
sn1_virt_to_phys_MACRO sn_virt_to_phys_MACRO
void * void *
sn1_phys_to_virt_MACRO sn_phys_to_virt_MACRO
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
...@@ -62,6 +62,8 @@ extern u8 numa_slit[NR_NODES * NR_NODES]; ...@@ -62,6 +62,8 @@ extern u8 numa_slit[NR_NODES * NR_NODES];
extern int paddr_to_nid(unsigned long paddr); extern int paddr_to_nid(unsigned long paddr);
#define local_nodeid (cpu_to_node_map[smp_processor_id()])
#endif /* CONFIG_NUMA */ #endif /* CONFIG_NUMA */
#endif /* _ASM_IA64_NUMA_H */ #endif /* _ASM_IA64_NUMA_H */
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment