diff options
Diffstat (limited to 'arch/ia64/sn/io/sn2')
31 files changed, 2086 insertions, 4907 deletions
diff --git a/arch/ia64/sn/io/sn2/Makefile b/arch/ia64/sn/io/sn2/Makefile index 106bd31b96db69..f8521c8bcea3fb 100644 --- a/arch/ia64/sn/io/sn2/Makefile +++ b/arch/ia64/sn/io/sn2/Makefile @@ -11,10 +11,9 @@ EXTRA_CFLAGS := -DLITTLE_ENDIAN -obj-y += pcibr/ bte_error.o geo_op.o klconflib.o klgraph.o l1.o \ - l1_command.o ml_iograph.o ml_SN_init.o ml_SN_intr.o module.o \ - pci_bus_cvlink.o pciio.o pic.o sgi_io_init.o shub.o shuberror.o \ - shub_intr.o shubio.o xbow.o xtalk.o +obj-y += pcibr/ ml_SN_intr.o shub_intr.o shuberror.o shub.o bte_error.o \ + pic.o geo_op.o l1.o l1_command.o klconflib.o klgraph.o ml_SN_init.o \ + ml_iograph.o module.o pciio.o xbow.o xtalk.o shubio.o obj-$(CONFIG_KDB) += kdba_io.o obj-$(CONFIG_SHUB_1_0_SPECIFIC) += efi-rtc.o diff --git a/arch/ia64/sn/io/sn2/bte_error.c b/arch/ia64/sn/io/sn2/bte_error.c index 8e086e1c1b4f09..4ab2cb0e9938ca 100644 --- a/arch/ia64/sn/io/sn2/bte_error.c +++ b/arch/ia64/sn/io/sn2/bte_error.c @@ -1,10 +1,35 @@ -/* $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 - * License. See the file "COPYING" in the main directory of this archive - * for more details. * - * Copyright (C) 1992 - 1997, 2000,2002 Silicon Graphics, Inc. All rights reserved. + * Copyright (c) 2000-2003 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 */ @@ -29,121 +54,208 @@ #include <asm/sn/sn2/shubio.h> #include <asm/sn/bte.h> -/************************************************************************ - * * - * BTE ERROR RECOVERY * - * * - * Given a BTE error, the node causing the error must do the following: * - * a) Clear all crbs relating to that BTE * - * 1) Read CRBA value for crb in question * - * 2) Mark CRB as VALID, store local physical * - * address known to be good in the address field * - * (bte_notification_targ is a known good local * - * address). * - * 3) Write CRBA * - * 4) Using ICCR, FLUSH the CRB, and wait for it to * - * complete. * - * ... BTE BUSY bit should now be clear (or at least * - * should be after ALL CRBs associated with the * - * transfer are complete. * - * * - * b) Re-enable BTE * - * 1) Write IMEM with BTE Enable + XXX bits - * 2) Write IECLR with BTE clear bits - * 3) Clear IIDSR INT_SENT bits. - * * - ************************************************************************/ - -/* - * >>> 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 error handling is done in two parts. The first captures + * any crb related errors. Since there can be multiple crbs per + * interface and multiple interfaces active, we need to wait until + * all active crbs are completed. This is the first job of the + * second part error handler. When all bte related CRBs are cleanly + * completed, it resets the interfaces and gets them ready for new + * transfers to be queued. */ -void -bte_crb_error_handler(devfs_handle_t hub_v, int btenum, - int crbnum, ioerror_t *ioe, int bteop) + + +void bte_error_handler(unsigned long); + + /* - * Function: bte_crb_error_handler - * Purpose: Process a CRB for a specific HUB/BTE - * Parameters: hub_v - vertex of hub in HW graph - * btenum - bte number on hub (0 == a, 1 == b) - * crbnum - crb number being processed - * Notes: - * This routine assumes serialization at a higher level. A CRB - * should not be processed more than once. The error recovery - * follows the following sequence - if you change this, be real - * sure about what you are doing. - * + * First part error handler. This is called whenever any error CRB interrupt + * is generated by the II. */ +void +bte_crb_error_handler(vertex_hdl_t hub_v, int btenum, + int crbnum, ioerror_t * ioe, int bteop) { - hubinfo_t hinfo; - icrba_t crba; - icrbb_t crbb; - nasid_t n; - hubreg_t iidsr, imem, ieclr; + hubinfo_t hinfo; + struct bteinfo_s *bte; + hubinfo_get(hub_v, &hinfo); + bte = &hinfo->h_nodepda->bte_if[btenum]; + + /* + * The caller has already figured out the error type, we save that + * in the bte handle structure for the thread excercising the + * interface to consume. + */ + switch (ioe->ie_errortype) { + case IIO_ICRB_ECODE_PERR: + bte->bh_error = BTEFAIL_POISON; + break; + case IIO_ICRB_ECODE_WERR: + bte->bh_error = BTEFAIL_PROT; + break; + case IIO_ICRB_ECODE_AERR: + bte->bh_error = BTEFAIL_ACCESS; + break; + case IIO_ICRB_ECODE_TOUT: + bte->bh_error = BTEFAIL_TOUT; + break; + case IIO_ICRB_ECODE_XTERR: + bte->bh_error = BTEFAIL_XTERR; + break; + case IIO_ICRB_ECODE_DERR: + bte->bh_error = BTEFAIL_DIR; + break; + case IIO_ICRB_ECODE_PWERR: + case IIO_ICRB_ECODE_PRERR: + /* NO BREAK */ + default: + bte->bh_error = BTEFAIL_ERROR; + } + bte->bte_error_count++; + + BTE_PRINTK(("Got an error on cnode %d bte %d\n", + bte->bte_cnode, bte->bte_num)); + bte_error_handler((unsigned long) hinfo->h_nodepda); +} - n = hinfo->h_nasid; - +/* + * Second part error handler. Wait until all BTE related CRBs are completed + * and then reset the interfaces. + */ +void +bte_error_handler(unsigned long _nodepda) +{ + struct nodepda_s *err_nodepda = (struct nodepda_s *) _nodepda; + spinlock_t *recovery_lock = &err_nodepda->bte_recovery_lock; + struct timer_list *recovery_timer = &err_nodepda->bte_recovery_timer; + nasid_t nasid; + int i; + int valid_crbs; + unsigned long irq_flags; + volatile u64 *notify; + bte_result_t bh_error; + ii_imem_u_t imem; /* II IMEM Register */ + ii_icrb0_d_u_t icrbd; /* II CRB Register D */ + ii_ibcr_u_t ibcr; + ii_icmr_u_t icmr; + + + BTE_PRINTK(("bte_error_handler(%p) - %d\n", err_nodepda, + smp_processor_id())); + + spin_lock_irqsave(recovery_lock, irq_flags); + + if ((err_nodepda->bte_if[0].bh_error == BTE_SUCCESS) && + (err_nodepda->bte_if[1].bh_error == BTE_SUCCESS)) { + BTE_PRINTK(("eh:%p:%d Nothing to do.\n", err_nodepda, + smp_processor_id())); + spin_unlock_irqrestore(recovery_lock, irq_flags); + return; + } /* - * 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! + * Lock all interfaces on this node to prevent new transfers + * from being queued. */ + for (i = 0; i < BTES_PER_NODE; i++) { + if (err_nodepda->bte_if[i].cleanup_active) { + continue; + } + spin_lock(&err_nodepda->bte_if[i].spinlock); + BTE_PRINTK(("eh:%p:%d locked %d\n", err_nodepda, + smp_processor_id(), i)); + err_nodepda->bte_if[i].cleanup_active = 1; + } + + /* Determine information about our hub */ + nasid = cnodeid_to_nasid(err_nodepda->bte_if[0].bte_cnode); + /* - * 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). + * A BTE transfer can use multiple CRBs. We need to make sure + * that all the BTE CRBs are complete (or timed out) before + * attempting to clean up the error. Resetting the BTE while + * there are still BTE CRBs active will hang the BTE. + * We should look at all the CRBs to see if they are allocated + * to the BTE and see if they are still active. When none + * are active, we can continue with the cleanup. + * + * We also want to make sure that the local NI port is up. + * When a router resets the NI port can go down, while it + * goes through the LLP handshake, but then comes back up. */ - crbb.ii_icrb0_b_regval = REMOTE_HUB_L(n, IIO_ICRB_B(crbnum)); - crbb.b_error=0; - crbb.b_ecode=0; - REMOTE_HUB_S(n, IIO_ICRB_B(crbnum), crbb.ii_icrb0_b_regval); - - 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_ICCR, - IIO_ICCR_PENDING | IIO_ICCR_CMD_FLUSH | crbnum); - - 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; + icmr.ii_icmr_regval = REMOTE_HUB_L(nasid, IIO_ICMR); + if (icmr.ii_icmr_fld_s.i_crb_mark != 0) { + /* + * There are errors which still need to be cleaned up by + * hubiio_crb_error_handler + */ + mod_timer(recovery_timer, HZ * 5); + BTE_PRINTK(("eh:%p:%d Marked Giving up\n", err_nodepda, + smp_processor_id())); + spin_unlock_irqrestore(recovery_lock, irq_flags); + return; } - 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); + if (icmr.ii_icmr_fld_s.i_crb_vld != 0) { + valid_crbs = icmr.ii_icmr_fld_s.i_crb_vld; - bte_reset_nasid(n); + for (i = 0; i < IIO_NUM_CRBS; i++) { + if (!((1 << i) & valid_crbs)) { + /* This crb was not marked as valid, ignore */ + continue; + } + icrbd.ii_icrb0_d_regval = + REMOTE_HUB_L(nasid, IIO_ICRB_D(i)); + if (icrbd.d_bteop) { + mod_timer(recovery_timer, HZ * 5); + BTE_PRINTK(("eh:%p:%d Valid %d, Giving up\n", + err_nodepda, smp_processor_id(), i)); + spin_unlock_irqrestore(recovery_lock, + irq_flags); + return; + } + } + } - *nodepda->bte_if[btenum].most_rcnt_na = IBLS_ERROR; -} + BTE_PRINTK(("eh:%p:%d Cleaning up\n", err_nodepda, + smp_processor_id())); + /* Reenable both bte interfaces */ + imem.ii_imem_regval = REMOTE_HUB_L(nasid, IIO_IMEM); + imem.ii_imem_fld_s.i_b0_esd = imem.ii_imem_fld_s.i_b1_esd = 1; + REMOTE_HUB_S(nasid, IIO_IMEM, imem.ii_imem_regval); + + /* Reinitialize both BTE state machines. */ + ibcr.ii_ibcr_regval = REMOTE_HUB_L(nasid, IIO_IBCR); + ibcr.ii_ibcr_fld_s.i_soft_reset = 1; + REMOTE_HUB_S(nasid, IIO_IBCR, ibcr.ii_ibcr_regval); + + + for (i = 0; i < BTES_PER_NODE; i++) { + bh_error = err_nodepda->bte_if[i].bh_error; + if (bh_error != BTE_SUCCESS) { + /* There is an error which needs to be notified */ + notify = err_nodepda->bte_if[i].most_rcnt_na; + BTE_PRINTK(("cnode %d bte %d error=0x%lx\n", + err_nodepda->bte_if[i].bte_cnode, + err_nodepda->bte_if[i].bte_num, + IBLS_ERROR | (u64) bh_error)); + *notify = IBLS_ERROR | bh_error; + err_nodepda->bte_if[i].bh_error = BTE_SUCCESS; + } + + err_nodepda->bte_if[i].cleanup_active = 0; + BTE_PRINTK(("eh:%p:%d Unlocked %d\n", err_nodepda, + smp_processor_id(), i)); + spin_unlock(&pda->cpu_bte_if[i]->spinlock); + } + + del_timer(recovery_timer); + + spin_unlock_irqrestore(recovery_lock, irq_flags); +} diff --git a/arch/ia64/sn/io/sn2/kdba_io.c b/arch/ia64/sn/io/sn2/kdba_io.c new file mode 100644 index 00000000000000..51f03577f8e081 --- /dev/null +++ b/arch/ia64/sn/io/sn2/kdba_io.c @@ -0,0 +1,76 @@ +/* + * Kernel Debugger Architecture Dependent POD functions. + * + * Copyright (C) 1999-2003 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/types.h> +#include <linux/kdb.h> +//#include <linux/kdbprivate.h> + +/** + * kdba_io - enter POD mode from kdb + * @argc: arg count + * @argv: arg values + * @envp: kdb env. vars + * @regs: current register state + * + * Enter POD mode from kdb using SGI SN specific SAL function call. + */ +static int +kdba_io(int argc, const char **argv, const char **envp, struct pt_regs *regs) +{ + kdb_printf("kdba_io entered with addr 0x%p\n", (void *) regs); + + return(0); +} + +/** + * kdba_io_init - register 'io' command with kdb + * + * Register the 'io' command with kdb at load time. + */ +void +kdba_io_init(void) +{ + kdb_register("io", kdba_io, "<vaddr>", "Display IO Contents", 0); +} + +/** + * kdba_io_exit - unregister the 'io' command + * + * Tell kdb that the 'io' command is no longer available. + */ +static void __exit +kdba_exit(void) +{ + kdb_unregister("io"); +} diff --git a/arch/ia64/sn/io/sn2/klconflib.c b/arch/ia64/sn/io/sn2/klconflib.c index 4d1a92a00ed7db..d3a48ada4ad815 100644 --- a/arch/ia64/sn/io/sn2/klconflib.c +++ b/arch/ia64/sn/io/sn2/klconflib.c @@ -24,8 +24,6 @@ #include <asm/sn/router.h> #include <asm/sn/xtalk/xbow.h> -#define printf printk -int hasmetarouter; #define LDEBUG 0 #define NIC_UNKNOWN ((nic_t) -1) @@ -37,10 +35,11 @@ int hasmetarouter; #define DBG(x...) #endif /* DEBUG_KLGRAPH */ -static void sort_nic_names(lboard_t *) ; - u64 klgraph_addr[MAX_COMPACT_NODES]; -int module_number = 0; +static int hasmetarouter; + + +char brick_types[MAX_BRICK_TYPES + 1] = "crikxdpn%#=012345"; lboard_t * find_lboard(lboard_t *start, unsigned char brd_type) @@ -135,23 +134,6 @@ find_lboard_module(lboard_t *start, geoid_t geoid) return (lboard_t *)NULL; } -lboard_t * -find_lboard_module_class(lboard_t *start, geoid_t geoid, - unsigned char brd_type) -{ - while (start) { - DBG("find_lboard_module_class: lboard 0x%p, start->brd_geoid 0x%x, mod 0x%x, start->brd_type 0x%x, brd_type 0x%x\n", start, start->brd_geoid, geoid, start->brd_type, brd_type); - - if (geo_cmp(start->brd_geoid, geoid) && - (KLCLASS(start->brd_type) == KLCLASS(brd_type))) - return start; - start = KLCF_NEXT(start); - } - - /* Didn't find it. */ - return (lboard_t *)NULL; -} - /* * Convert a NIC name to a name for use in the hardware graph. */ @@ -205,63 +187,6 @@ nic_name_convert(char *old_name, char *new_name) } /* - * Find the lboard structure and get the board name. - * If we can't find the structure or it's too low a revision, - * use default name. - */ -lboard_t * -get_board_name(nasid_t nasid, geoid_t geoid, slotid_t slot, char *name) -{ - lboard_t *brd; - - brd = find_lboard_modslot((lboard_t *)KL_CONFIG_INFO(nasid), - geoid); - -#ifndef _STANDALONE - { - cnodeid_t cnode = NASID_TO_COMPACT_NODEID(nasid); - - if (!brd && (NODEPDA(cnode)->xbow_peer != INVALID_NASID)) - brd = find_lboard_modslot((lboard_t *) - KL_CONFIG_INFO(NODEPDA(cnode)->xbow_peer), - geoid); - } -#endif - - if (!brd || (brd->brd_sversion < 2)) { - strcpy(name, EDGE_LBL_XWIDGET); - } else { - nic_name_convert(brd->brd_name, name); - } - - /* - * PV # 540860 - * If the name is not 'baseio' - * get the lowest of all the names in the nic string. - * This is needed for boards like divo, which can have - * a bunch of daughter cards, but would like to be called - * divo. We could do this for baseio - * but it has some special case names that we would not - * like to disturb at this point. - */ - - /* gfx boards don't need any of this name scrambling */ - if (brd && (KLCLASS(brd->brd_type) == KLCLASS_GFX)) { - return(brd); - } - - if (!(!strcmp(name, "baseio") )) { - if (brd) { - sort_nic_names(brd) ; - /* Convert to small case, '-' to '_' etc */ - nic_name_convert(brd->brd_name, name) ; - } - } - - return(brd); -} - -/* * get_actual_nasid * * Completely disabled brds have their klconfig on @@ -341,12 +266,20 @@ board_to_path(lboard_t *brd, char *path) board_name = EDGE_LBL_IO; break; case KLCLASS_IOBRICK: - if (brd->brd_type == KLTYPE_PBRICK) + if (brd->brd_type == KLTYPE_PXBRICK) + board_name = EDGE_LBL_PXBRICK; + else if (brd->brd_type == KLTYPE_IXBRICK) + board_name = EDGE_LBL_IXBRICK; + else if (brd->brd_type == KLTYPE_PBRICK) board_name = EDGE_LBL_PBRICK; else if (brd->brd_type == KLTYPE_IBRICK) board_name = EDGE_LBL_IBRICK; else if (brd->brd_type == KLTYPE_XBRICK) board_name = EDGE_LBL_XBRICK; + else if (brd->brd_type == KLTYPE_PEBRICK) + board_name = EDGE_LBL_PEBRICK; + else if (brd->brd_type == KLTYPE_CGBRICK) + board_name = EDGE_LBL_CGBRICK; else board_name = EDGE_LBL_IOBRICK; break; @@ -623,185 +556,6 @@ board_serial_number_get(lboard_t *board,char *serial_number) #include "asm/sn/sn_private.h" -xwidgetnum_t -nodevertex_widgetnum_get(devfs_handle_t node_vtx) -{ - hubinfo_t hubinfo_p; - - hwgraph_info_get_LBL(node_vtx, INFO_LBL_NODE_INFO, - (arbitrary_info_t *) &hubinfo_p); - return(hubinfo_p->h_widgetid); -} - -devfs_handle_t -nodevertex_xbow_peer_get(devfs_handle_t node_vtx) -{ - hubinfo_t hubinfo_p; - nasid_t xbow_peer_nasid; - cnodeid_t xbow_peer; - - hwgraph_info_get_LBL(node_vtx, INFO_LBL_NODE_INFO, - (arbitrary_info_t *) &hubinfo_p); - xbow_peer_nasid = hubinfo_p->h_nodepda->xbow_peer; - if(xbow_peer_nasid == INVALID_NASID) - return ( (devfs_handle_t)-1); - xbow_peer = NASID_TO_COMPACT_NODEID(xbow_peer_nasid); - return(NODEPDA(xbow_peer)->node_vertex); -} - -/* NIC Sorting Support */ - -#define MAX_NICS_PER_STRING 32 -#define MAX_NIC_NAME_LEN 32 - -static char * -get_nic_string(lboard_t *lb) -{ - int i; - klinfo_t *k = NULL ; - klconf_off_t mfg_off = 0 ; - char *mfg_nic = NULL ; - - for (i = 0; i < KLCF_NUM_COMPS(lb); i++) { - k = KLCF_COMP(lb, i) ; - switch(k->struct_type) { - case KLSTRUCT_BRI: - mfg_off = ((klbri_t *)k)->bri_mfg_nic ; - break ; - - case KLSTRUCT_HUB: - mfg_off = ((klhub_t *)k)->hub_mfg_nic ; - break ; - - case KLSTRUCT_ROU: - mfg_off = ((klrou_t *)k)->rou_mfg_nic ; - break ; - - case KLSTRUCT_GFX: - mfg_off = ((klgfx_t *)k)->gfx_mfg_nic ; - break ; - - case KLSTRUCT_TPU: - mfg_off = ((kltpu_t *)k)->tpu_mfg_nic ; - break ; - - case KLSTRUCT_GSN_A: - case KLSTRUCT_GSN_B: - mfg_off = ((klgsn_t *)k)->gsn_mfg_nic ; - break ; - - case KLSTRUCT_XTHD: - mfg_off = ((klxthd_t *)k)->xthd_mfg_nic ; - break; - - default: - mfg_off = 0 ; - break ; - } - if (mfg_off) - break ; - } - - if ((mfg_off) && (k)) - mfg_nic = (char *)NODE_OFFSET_TO_K0(k->nasid, mfg_off) ; - - return mfg_nic ; -} - -char * -get_first_string(char **ptrs, int n) -{ - int i ; - char *tmpptr ; - - if ((ptrs == NULL) || (n == 0)) - return NULL ; - - tmpptr = ptrs[0] ; - - if (n == 1) - return tmpptr ; - - for (i = 0 ; i < n ; i++) { - if (strcmp(tmpptr, ptrs[i]) > 0) - tmpptr = ptrs[i] ; - } - - return tmpptr ; -} - -int -get_ptrs(char *idata, char **ptrs, int n, char *label) -{ - int i = 0 ; - char *tmp = idata ; - - if ((ptrs == NULL) || (idata == NULL) || (label == NULL) || (n == 0)) - return 0 ; - - while ( (tmp = strstr(tmp, label)) ){ - tmp += strlen(label) ; - /* check for empty name field, and last NULL ptr */ - if ((i < (n-1)) && (*tmp != ';')) { - ptrs[i++] = tmp ; - } - } - - ptrs[i] = NULL ; - - return i ; -} - -/* - * sort_nic_names - * - * Does not really do sorting. Find the alphabetically lowest - * name among all the nic names found in a nic string. - * - * Return: - * Nothing - * - * Side Effects: - * - * lb->brd_name gets the new name found - */ - -static void -sort_nic_names(lboard_t *lb) -{ - char *nic_str ; - char *ptrs[MAX_NICS_PER_STRING] ; - char name[MAX_NIC_NAME_LEN] ; - char *tmp, *tmp1 ; - - *name = 0 ; - - /* Get the nic pointer from the lb */ - - if ((nic_str = get_nic_string(lb)) == NULL) - return ; - - tmp = get_first_string(ptrs, - get_ptrs(nic_str, ptrs, MAX_NICS_PER_STRING, "Name:")) ; - - if (tmp == NULL) - return ; - - if ( (tmp1 = strchr(tmp, ';')) ){ - strncpy(name, tmp, tmp1-tmp) ; - name[tmp1-tmp] = 0 ; - } else { - strncpy(name, tmp, (sizeof(name) -1)) ; - name[sizeof(name)-1] = 0 ; - } - - strcpy(lb->brd_name, name) ; -} - - - -char brick_types[MAX_BRICK_TYPES + 1] = "crikxdpn%#012345"; - /* * Format a module id for printing. */ @@ -814,6 +568,7 @@ format_module_id(char *buffer, moduleid_t m, int fmt) rack = MODULE_GET_RACK(m); ASSERT(MODULE_GET_BTYPE(m) < MAX_BRICK_TYPES); brickchar = MODULE_GET_BTCHAR(m); + position = MODULE_GET_BPOS(m); if (fmt == MODULE_FORMAT_BRIEF) { diff --git a/arch/ia64/sn/io/sn2/klgraph.c b/arch/ia64/sn/io/sn2/klgraph.c index 532a8a73693b0e..010b06956bf383 100644 --- a/arch/ia64/sn/io/sn2/klgraph.c +++ b/arch/ia64/sn/io/sn2/klgraph.c @@ -23,7 +23,6 @@ #include <asm/sn/hcl.h> #include <asm/sn/labelcl.h> #include <asm/sn/kldir.h> -#include <asm/sn/gda.h> #include <asm/sn/klconfig.h> #include <asm/sn/router.h> #include <asm/sn/xtalk/xbow.h> @@ -42,7 +41,7 @@ extern char arg_maxnodes[]; extern u64 klgraph_addr[]; -void mark_cpuvertex_as_cpu(devfs_handle_t vhdl, cpuid_t cpuid); +void mark_cpuvertex_as_cpu(vertex_hdl_t vhdl, cpuid_t cpuid); /* @@ -69,7 +68,7 @@ klhwg_invent_alloc(cnodeid_t cnode, int class, int size) * Add detailed disabled cpu inventory info to the hardware graph. */ void -klhwg_disabled_cpu_invent_info(devfs_handle_t cpuv, +klhwg_disabled_cpu_invent_info(vertex_hdl_t cpuv, cnodeid_t cnode, klcpu_t *cpu, slotid_t slot) { @@ -118,7 +117,7 @@ klhwg_disabled_cpu_invent_info(devfs_handle_t cpuv, * Add detailed cpu inventory info to the hardware graph. */ void -klhwg_cpu_invent_info(devfs_handle_t cpuv, +klhwg_cpu_invent_info(vertex_hdl_t cpuv, cnodeid_t cnode, klcpu_t *cpu) { @@ -153,7 +152,7 @@ klhwg_cpu_invent_info(devfs_handle_t cpuv, * as a part of detailed inventory info in the hwgraph. */ void -klhwg_baseio_inventory_add(devfs_handle_t baseio_vhdl,cnodeid_t cnode) +klhwg_baseio_inventory_add(vertex_hdl_t baseio_vhdl,cnodeid_t cnode) { invent_miscinfo_t *baseio_inventory; unsigned char version = 0,revision = 0; @@ -177,20 +176,11 @@ klhwg_baseio_inventory_add(devfs_handle_t baseio_vhdl,cnodeid_t cnode) sizeof(invent_miscinfo_t)); } -char *hub_rev[] = { - "0.0", - "1.0", - "2.0", - "2.1", - "2.2", - "2.3" -}; - /* * Add detailed cpu inventory info to the hardware graph. */ void -klhwg_hub_invent_info(devfs_handle_t hubv, +klhwg_hub_invent_info(vertex_hdl_t hubv, cnodeid_t cnode, klhub_t *hub) { @@ -215,10 +205,10 @@ klhwg_hub_invent_info(devfs_handle_t hubv, /* ARGSUSED */ void -klhwg_add_hub(devfs_handle_t node_vertex, klhub_t *hub, cnodeid_t cnode) +klhwg_add_hub(vertex_hdl_t node_vertex, klhub_t *hub, cnodeid_t cnode) { - devfs_handle_t myhubv; - devfs_handle_t hub_mon; + vertex_hdl_t myhubv; + vertex_hdl_t hub_mon; int rc; extern struct file_operations shub_mon_fops; @@ -234,9 +224,9 @@ klhwg_add_hub(devfs_handle_t node_vertex, klhub_t *hub, cnodeid_t cnode) /* ARGSUSED */ void -klhwg_add_disabled_cpu(devfs_handle_t node_vertex, cnodeid_t cnode, klcpu_t *cpu, slotid_t slot) +klhwg_add_disabled_cpu(vertex_hdl_t node_vertex, cnodeid_t cnode, klcpu_t *cpu, slotid_t slot) { - devfs_handle_t my_cpu; + vertex_hdl_t my_cpu; char name[120]; cpuid_t cpu_id; nasid_t nasid; @@ -257,9 +247,9 @@ klhwg_add_disabled_cpu(devfs_handle_t node_vertex, cnodeid_t cnode, klcpu_t *cpu /* ARGSUSED */ void -klhwg_add_cpu(devfs_handle_t node_vertex, cnodeid_t cnode, klcpu_t *cpu) +klhwg_add_cpu(vertex_hdl_t node_vertex, cnodeid_t cnode, klcpu_t *cpu) { - devfs_handle_t my_cpu, cpu_dir; + vertex_hdl_t my_cpu, cpu_dir; char name[120]; cpuid_t cpu_id; nasid_t nasid; @@ -295,7 +285,7 @@ klhwg_add_xbow(cnodeid_t cnode, nasid_t nasid) nasid_t hub_nasid; cnodeid_t hub_cnode; int widgetnum; - devfs_handle_t xbow_v, hubv; + vertex_hdl_t xbow_v, hubv; /*REFERENCED*/ graph_error_t err; @@ -363,12 +353,12 @@ klhwg_add_xbow(cnodeid_t cnode, nasid_t nasid) /* ARGSUSED */ void -klhwg_add_node(devfs_handle_t hwgraph_root, cnodeid_t cnode, gda_t *gdap) +klhwg_add_node(vertex_hdl_t hwgraph_root, cnodeid_t cnode) { nasid_t nasid; lboard_t *brd; klhub_t *hub; - devfs_handle_t node_vertex = NULL; + vertex_hdl_t node_vertex = NULL; char path_buffer[100]; int rv; char *s; @@ -382,7 +372,7 @@ klhwg_add_node(devfs_handle_t hwgraph_root, cnodeid_t cnode, gda_t *gdap) ASSERT(brd); do { - devfs_handle_t cpu_dir; + vertex_hdl_t cpu_dir; /* Generate a hardware graph path for this board. */ board_to_path(brd, path_buffer); @@ -443,7 +433,7 @@ klhwg_add_node(devfs_handle_t hwgraph_root, cnodeid_t cnode, gda_t *gdap) while (cpu) { cpuid_t cpu_id; cpu_id = nasid_slice_to_cpuid(nasid,cpu->cpu_info.physid); - if (cpu_enabled(cpu_id)) + if (cpu_online(cpu_id)) klhwg_add_cpu(node_vertex, cnode, cpu); else klhwg_add_disabled_cpu(node_vertex, cnode, cpu, brd->brd_slot); @@ -466,12 +456,12 @@ klhwg_add_node(devfs_handle_t hwgraph_root, cnodeid_t cnode, gda_t *gdap) /* ARGSUSED */ void -klhwg_add_all_routers(devfs_handle_t hwgraph_root) +klhwg_add_all_routers(vertex_hdl_t hwgraph_root) { nasid_t nasid; cnodeid_t cnode; lboard_t *brd; - devfs_handle_t node_vertex; + vertex_hdl_t node_vertex; char path_buffer[100]; int rv; @@ -525,14 +515,14 @@ klhwg_add_all_routers(devfs_handle_t hwgraph_root) /* ARGSUSED */ void -klhwg_connect_one_router(devfs_handle_t hwgraph_root, lboard_t *brd, +klhwg_connect_one_router(vertex_hdl_t hwgraph_root, lboard_t *brd, cnodeid_t cnode, nasid_t nasid) { klrou_t *router; char path_buffer[50]; char dest_path[50]; - devfs_handle_t router_hndl; - devfs_handle_t dest_hndl; + vertex_hdl_t router_hndl; + vertex_hdl_t dest_hndl; int rc; int port; lboard_t *dest_brd; @@ -619,7 +609,7 @@ klhwg_connect_one_router(devfs_handle_t hwgraph_root, lboard_t *brd, void -klhwg_connect_routers(devfs_handle_t hwgraph_root) +klhwg_connect_routers(vertex_hdl_t hwgraph_root) { nasid_t nasid; cnodeid_t cnode; @@ -652,15 +642,15 @@ klhwg_connect_routers(devfs_handle_t hwgraph_root) void -klhwg_connect_hubs(devfs_handle_t hwgraph_root) +klhwg_connect_hubs(vertex_hdl_t hwgraph_root) { nasid_t nasid; cnodeid_t cnode; lboard_t *brd; klhub_t *hub; lboard_t *dest_brd; - devfs_handle_t hub_hndl; - devfs_handle_t dest_hndl; + vertex_hdl_t hub_hndl; + vertex_hdl_t dest_hndl; char path_buffer[50]; char dest_path[50]; graph_error_t rc; @@ -796,12 +786,12 @@ klhwg_device_disable_hints_add(void) } void -klhwg_add_all_modules(devfs_handle_t hwgraph_root) +klhwg_add_all_modules(vertex_hdl_t hwgraph_root) { cmoduleid_t cm; char name[128]; - devfs_handle_t vhdl; - devfs_handle_t module_vhdl; + vertex_hdl_t vhdl; + vertex_hdl_t module_vhdl; int rc; char buffer[16]; @@ -837,12 +827,12 @@ klhwg_add_all_modules(devfs_handle_t hwgraph_root) } void -klhwg_add_all_nodes(devfs_handle_t hwgraph_root) +klhwg_add_all_nodes(vertex_hdl_t hwgraph_root) { cnodeid_t cnode; for (cnode = 0; cnode < numnodes; cnode++) { - klhwg_add_node(hwgraph_root, cnode, NULL); + klhwg_add_node(hwgraph_root, cnode); } for (cnode = 0; cnode < numnodes; cnode++) { diff --git a/arch/ia64/sn/io/sn2/l1.c b/arch/ia64/sn/io/sn2/l1.c index c83e1c0ade72fc..6576b4ca0947e9 100644 --- a/arch/ia64/sn/io/sn2/l1.c +++ b/arch/ia64/sn/io/sn2/l1.c @@ -29,6 +29,7 @@ #include <linux/slab.h> #include <linux/spinlock.h> #include <linux/delay.h> +#include <asm/io.h> #include <asm/sn/sgi.h> #include <asm/sn/io.h> #include <asm/sn/iograph.h> @@ -36,7 +37,6 @@ #include <asm/sn/hcl.h> #include <asm/sn/hcl_util.h> #include <asm/sn/labelcl.h> -#include <asm/sn/eeprom.h> #include <asm/sn/router.h> #include <asm/sn/module.h> #include <asm/sn/ksys/l1.h> @@ -50,6 +50,9 @@ #define UART_BAUD_RATE 57600 +static int L1_connected; /* non-zero when interrupts are enabled */ + + int get_L1_baud(void) { @@ -62,7 +65,23 @@ get_L1_baud(void) int l1_get_intr_value( void ) { - return(0); + cpuid_t intr_cpuid; + nasid_t console_nasid; + int major, minor; + extern nasid_t get_console_nasid(void); + + /* if it is an old prom, run in poll mode */ + + major = sn_sal_rev_major(); + minor = sn_sal_rev_minor(); + if ( (major < 1) || ((major == 1) && (minor < 10)) ) { + /* before version 1.10 doesn't work */ + return (0); + } + + console_nasid = get_console_nasid(); + intr_cpuid = NODEPDA(NASID_TO_COMPACT_NODEID(console_nasid))->node_first_cpu; + return CPU_VECTOR_TO_IRQ(intr_cpuid, SGI_UART_VECTOR); } /* Disconnect the callup functions - throw away interrupts */ @@ -74,19 +93,45 @@ l1_unconnect_intr(void) /* Set up uart interrupt handling for this node's uart */ -void -l1_connect_intr(void *rx_notify, void *tx_notify) +int +l1_connect_intr(void *intr_func, void *arg, struct pt_regs *ep) { -#if 0 - // Will need code here for sn2 - something like this - console_nodepda = NODEPDA(NASID_TO_COMPACT_NODEID(get_master_nasid()); - intr_connect_level(console_nodepda->node_first_cpu, - SGI_UART_VECTOR, INTPEND0_MAXMASK, - dummy_intr_func); - request_irq(SGI_UART_VECTOR | (console_nodepda->node_first_cpu << 8), - intr_func, SA_INTERRUPT | SA_SHIRQ, - "l1_protocol_driver", (void *)sc); -#endif + cpuid_t intr_cpuid; + nasid_t console_nasid; + unsigned int console_irq; + int result; + extern int intr_connect_level(cpuid_t, int, ilvl_t, intr_func_t); + extern nasid_t get_console_nasid(void); + + + /* don't call to connect multiple times - we DON'T support changing the handler */ + + if ( !L1_connected ) { + L1_connected++; + console_nasid = get_console_nasid(); + intr_cpuid = NODEPDA(NASID_TO_COMPACT_NODEID(console_nasid))->node_first_cpu; + console_irq = CPU_VECTOR_TO_IRQ(intr_cpuid, SGI_UART_VECTOR); + result = intr_connect_level(intr_cpuid, SGI_UART_VECTOR, + 0 /*not used*/, 0 /*not used*/); + if (result != SGI_UART_VECTOR) { + if (result < 0) + printk(KERN_WARNING "L1 console driver : intr_connect_level failed %d\n", result); + else + printk(KERN_WARNING "L1 console driver : intr_connect_level returns wrong bit %d\n", result); + return (-1); + } + + result = request_irq(console_irq, intr_func, SA_INTERRUPT, + "SGI L1 console driver", (void *)arg); + if (result < 0) { + printk(KERN_WARNING "L1 console driver : request_irq failed %d\n", result); + return (-1); + } + + /* ask SAL to turn on interrupts in the UART itself */ + ia64_sn_console_intr_enable(SAL_CONSOLE_INTR_RECV); + } + return (0); } @@ -195,7 +240,7 @@ l1_serial_in_local(void) int l1_serial_out( char *str, int len ) { - int counter = len; + int tmp; /* Ignore empty messages */ if ( len == 0 ) @@ -216,6 +261,8 @@ l1_serial_out( char *str, int len ) if ( IS_RUNNING_ON_SIMULATOR() ) { extern u64 master_node_bedrock_address; void early_sn_setup(void); + int counter = len; + if (!master_node_bedrock_address) early_sn_setup(); if ( master_node_bedrock_address != (u64)0 ) { @@ -237,8 +284,9 @@ l1_serial_out( char *str, int len ) } /* Attempt to write things out thru the sal */ - if ( ia64_sn_console_putb(str, len) ) - return(0); - - return((counter <= 0) ? 0 : (len - counter)); + if ( L1_connected ) + tmp = ia64_sn_console_xmit_chars(str, len); + else + tmp = ia64_sn_console_putb(str, len); + return ((tmp < 0) ? 0 : tmp); } diff --git a/arch/ia64/sn/io/sn2/l1_command.c b/arch/ia64/sn/io/sn2/l1_command.c index 9826308a6edea8..280d2bb2ad02b3 100644 --- a/arch/ia64/sn/io/sn2/l1_command.c +++ b/arch/ia64/sn/io/sn2/l1_command.c @@ -16,7 +16,6 @@ #include <asm/sn/hcl.h> #include <asm/sn/hcl_util.h> #include <asm/sn/labelcl.h> -#include <asm/sn/eeprom.h> #include <asm/sn/router.h> #include <asm/sn/module.h> #include <asm/sn/ksys/l1.h> @@ -26,37 +25,6 @@ #include <asm/sn/sn_sal.h> #include <linux/ctype.h> -#define ELSC_TIMEOUT 1000000 /* ELSC response timeout (usec) */ -#define LOCK_TIMEOUT 5000000 /* Hub lock timeout (usec) */ - -#define hub_cpu_get() 0 - -#define LBYTE(caddr) (*(char *) caddr) - -extern char *bcopy(const char * src, char * dest, int count); - -#define LDEBUG 0 - -/* - * ELSC data is in NVRAM page 7 at the following offsets. - */ - -#define NVRAM_MAGIC_AD 0x700 /* magic number used for init */ -#define NVRAM_PASS_WD 0x701 /* password (4 bytes in length) */ -#define NVRAM_DBG1 0x705 /* virtual XOR debug switches */ -#define NVRAM_DBG2 0x706 /* physical XOR debug switches */ -#define NVRAM_CFG 0x707 /* ELSC Configuration info */ -#define NVRAM_MODULE 0x708 /* system module number */ -#define NVRAM_BIST_FLG 0x709 /* BIST flags (2 bits per nodeboard) */ -#define NVRAM_PARTITION 0x70a /* module's partition id */ -#define NVRAM_DOMAIN 0x70b /* module's domain id */ -#define NVRAM_CLUSTER 0x70c /* module's cluster id */ -#define NVRAM_CELL 0x70d /* module's cellid */ - -#define NVRAM_MAGIC_NO 0x37 /* value of magic number */ -#define NVRAM_SIZE 16 /* 16 bytes in nvram */ - - /* elsc_display_line writes up to 12 characters to either the top or bottom * line of the L1 display. line points to a buffer containing the message * to be displayed. The zero-based line number is specified by lnum (so @@ -69,6 +37,7 @@ int elsc_display_line(nasid_t nasid, char *line, int lnum) return 0; } + /* * iobrick routines */ @@ -88,9 +57,9 @@ int iobrick_rack_bay_type_get( nasid_t nasid, uint *rack, if ( ia64_sn_sysctl_iobrick_module_get(nasid, &result) ) return( ELSC_ERROR_CMD_SEND ); - *rack = (result & L1_ADDR_RACK_MASK) >> L1_ADDR_RACK_SHFT; - *bay = (result & L1_ADDR_BAY_MASK) >> L1_ADDR_BAY_SHFT; - *brick_type = (result & L1_ADDR_TYPE_MASK) >> L1_ADDR_TYPE_SHFT; + *rack = (result & MODULE_RACK_MASK) >> MODULE_RACK_SHFT; + *bay = (result & MODULE_BPOS_MASK) >> MODULE_BPOS_SHFT; + *brick_type = (result & MODULE_BTYPE_MASK) >> MODULE_BTYPE_SHFT; *brick_type = toupper(*brick_type); return 0; @@ -99,14 +68,12 @@ int iobrick_rack_bay_type_get( nasid_t nasid, uint *rack, int iomoduleid_get(nasid_t nasid) { - int result = 0; if ( ia64_sn_sysctl_iobrick_module_get(nasid, &result) ) return( ELSC_ERROR_CMD_SEND ); return result; - } int iobrick_module_get(nasid_t nasid) @@ -142,11 +109,15 @@ int iobrick_module_get(nasid_t nasid) RACK_ADD_NUM(rack, t); switch( brick_type ) { - case 'I': + case L1_BRICKTYPE_IX: + brick_type = MODULE_IXBRICK; break; + case L1_BRICKTYPE_PX: + brick_type = MODULE_PXBRICK; break; + case L1_BRICKTYPE_I: brick_type = MODULE_IBRICK; break; - case 'P': + case L1_BRICKTYPE_P: brick_type = MODULE_PBRICK; break; - case 'X': + case L1_BRICKTYPE_X: brick_type = MODULE_XBRICK; break; } @@ -154,7 +125,7 @@ int iobrick_module_get(nasid_t nasid) return ret; } -#ifdef CONFIG_PCI + /* * iobrick_module_get_nasid() returns a module_id which has the brick * type encoded in bits 15-12, but this is not the true brick type... @@ -179,29 +150,54 @@ iobrick_type_get_nasid(nasid_t nasid) /* convert to a module.h brick type */ for( t = 0; t < MAX_BRICK_TYPES; t++ ) { - if( brick_types[t] == type ) + if( brick_types[t] == type ) { return t; + } } return -1; /* unknown brick */ } -#endif + int iobrick_module_get_nasid(nasid_t nasid) { int io_moduleid; -#ifdef PIC_LATER - uint rack, bay; + io_moduleid = iobrick_module_get(nasid); + return io_moduleid; +} + +/* + * given a L1 bricktype, return a bricktype string. This string is the + * string that will be used in the hwpath for I/O bricks + */ +char * +iobrick_L1bricktype_to_name(int type) +{ + switch (type) + { + default: + return("Unknown"); + + case L1_BRICKTYPE_X: + return("Xbrick"); - if (PEBRICK_NODE(nasid)) { - if (peer_iobrick_rack_bay_get(nasid, &rack, &bay)) { - printf("Could not read rack and bay location " - "of PEBrick at nasid %d\n", nasid); - } + case L1_BRICKTYPE_I: + return("Ibrick"); - io_moduleid = peer_iobrick_module_get(sc, rack, bay); + case L1_BRICKTYPE_P: + return("Pbrick"); + + case L1_BRICKTYPE_PX: + return("PXbrick"); + + case L1_BRICKTYPE_IX: + return("IXbrick"); + + case L1_BRICKTYPE_C: + return("Cbrick"); + + case L1_BRICKTYPE_R: + return("Rbrick"); } -#endif /* PIC_LATER */ - io_moduleid = iobrick_module_get(nasid); - return io_moduleid; } + diff --git a/arch/ia64/sn/io/sn2/ml_SN_init.c b/arch/ia64/sn/io/sn2/ml_SN_init.c index 51829ce6e02ed3..f085fceadd9b1f 100644 --- a/arch/ia64/sn/io/sn2/ml_SN_init.c +++ b/arch/ia64/sn/io/sn2/ml_SN_init.c @@ -19,25 +19,12 @@ #include <asm/sn/sn_private.h> #include <asm/sn/klconfig.h> #include <asm/sn/sn_cpuid.h> -#include <asm/sn/snconfig.h> -extern int numcpus; -extern char arg_maxnodes[]; extern cpuid_t master_procid; - -extern int hasmetarouter; - int maxcpus; -cpumask_t boot_cpumask; -hubreg_t region_mask = 0; - extern xwidgetnum_t hub_widget_id(nasid_t); -extern int valid_icache_reasons; /* Reasons to flush the icache */ -extern int valid_dcache_reasons; /* Reasons to flush the dcache */ -extern u_char miniroot; -extern volatile int need_utlbmiss_patch; extern void iograph_early_init(void); nasid_t master_nasid = INVALID_NASID; /* This is the partition master nasid */ @@ -123,16 +110,6 @@ void init_platform_nodepda(nodepda_t *npda, cnodeid_t node) mutex_init_locked(&npda->xbow_sema); /* init it locked? */ } -/* XXX - Move the interrupt stuff to intr.c ? */ -/* - * Set up the platform-dependent fields in the processor pda. - * Must be done _after_ init_platform_nodepda(). - * If we need a lock here, something else is wrong! - */ -void init_platform_pda(cpuid_t cpu) -{ -} - void update_node_information(cnodeid_t cnodeid) { diff --git a/arch/ia64/sn/io/sn2/ml_SN_intr.c b/arch/ia64/sn/io/sn2/ml_SN_intr.c index e42a347cac05e0..31da1ccb1bc552 100644 --- a/arch/ia64/sn/io/sn2/ml_SN_intr.c +++ b/arch/ia64/sn/io/sn2/ml_SN_intr.c @@ -4,7 +4,7 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. * - * Copyright (C) 1992-1997, 2000-2002 Silicon Graphics, Inc. All Rights Reserved. + * Copyright (C) 1992-1997, 2000-2003 Silicon Graphics, Inc. All Rights Reserved. */ /* @@ -40,11 +40,14 @@ #include <asm/sal.h> #include <asm/sn/sn_sal.h> -extern irqpda_t *irqpdaindr[]; -extern cnodeid_t master_node_get(devfs_handle_t vhdl); +extern irqpda_t *irqpdaindr; +extern cnodeid_t master_node_get(vertex_hdl_t vhdl); extern nasid_t master_nasid; // Initialize some shub registers for interrupts, both IO and error. +// + + void intr_init_vecblk( nodepda_t *npda, @@ -58,6 +61,8 @@ intr_init_vecblk( nodepda_t *npda, nodepda_t *lnodepda; sh_ii_int0_enable_u_t ii_int_enable; sh_int_node_id_config_u_t node_id_config; + sh_local_int5_config_u_t local5_config; + sh_local_int5_enable_u_t local5_enable; extern void sn_init_cpei_timer(void); static int timer_added = 0; @@ -93,6 +98,19 @@ intr_init_vecblk( nodepda_t *npda, 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); + // Config and enable UART interrupt, all nodes. + + local5_config.sh_local_int5_config_regval = 0; + local5_config.sh_local_int5_config_s.idx = SGI_UART_VECTOR; + local5_config.sh_local_int5_config_s.pid = cpu0; + HUB_S( (unsigned long *)GLOBAL_MMR_ADDR(nasid, SH_LOCAL_INT5_CONFIG), + local5_config.sh_local_int5_config_regval); + + local5_enable.sh_local_int5_enable_regval = 0; + local5_enable.sh_local_int5_enable_s.uart_int = 1; + HUB_S( (unsigned long *)GLOBAL_MMR_ADDR(nasid, SH_LOCAL_INT5_ENABLE), + local5_enable.sh_local_int5_enable_regval); + // The II_INT_CONFIG register for cpu 0. ii_int_config.sh_ii_int0_config_regval = 0; @@ -119,13 +137,6 @@ intr_init_vecblk( nodepda_t *npda, // 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; -#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), ii_int_enable.sh_ii_int0_enable_regval); @@ -147,7 +158,8 @@ do_intr_reserve_level(cpuid_t cpu, int reserve) { int i; - irqpda_t *irqs = irqpdaindr[cpu]; + irqpda_t *irqs = irqpdaindr; + int min_shared; if (reserve) { if (bit < 0) { @@ -158,8 +170,32 @@ do_intr_reserve_level(cpuid_t cpu, } } } - if (bit < 0) { - return -1; + if (bit < 0) { /* ran out of irqs. Have to share. This will be rare. */ + min_shared = 256; + for (i=IA64_SN2_FIRST_DEVICE_VECTOR; i < IA64_SN2_LAST_DEVICE_VECTOR; i++) { + /* Share with the same device class */ + if (irqpdaindr->current->vendor == irqpdaindr->device_dev[i]->vendor && + irqpdaindr->current->device == irqpdaindr->device_dev[i]->device && + irqpdaindr->share_count[i] < min_shared) { + min_shared = irqpdaindr->share_count[i]; + bit = i; + } + } + min_shared = 256; + if (bit < 0) { /* didn't find a matching device, just pick one. This will be */ + /* exceptionally rare. */ + for (i=IA64_SN2_FIRST_DEVICE_VECTOR; i < IA64_SN2_LAST_DEVICE_VECTOR; i++) { + if (irqpdaindr->share_count[i] < min_shared) { + min_shared = irqpdaindr->share_count[i]; + bit = i; + } + } + } + irqpdaindr->share_count[bit]++; + } + if (irqs->irq_flags[bit] & SN2_IRQ_SHARED) { + irqs->irq_flags[bit] |= SN2_IRQ_RESERVED; + return bit; } if (irqs->irq_flags[bit] & SN2_IRQ_RESERVED) { return -1; @@ -183,7 +219,7 @@ int intr_reserve_level(cpuid_t cpu, int bit, int resflags, - devfs_handle_t owner_dev, + vertex_hdl_t owner_dev, char *name) { return(do_intr_reserve_level(cpu, bit, 1)); @@ -203,9 +239,13 @@ do_intr_connect_level(cpuid_t cpu, int bit, int connect) { - irqpda_t *irqs = irqpdaindr[cpu]; + irqpda_t *irqs = irqpdaindr; if (connect) { + if (irqs->irq_flags[bit] & SN2_IRQ_SHARED) { + irqs->irq_flags[bit] |= SN2_IRQ_CONNECTED; + return bit; + } if (irqs->irq_flags[bit] & SN2_IRQ_CONNECTED) { return -1; } else { @@ -248,24 +288,29 @@ do_intr_cpu_choose(cnodeid_t cnode) { int slice, min_count = 1000; irqpda_t *irqs; - for (slice = 0; slice < CPUS_PER_NODE; slice++) { + for (slice = CPUS_PER_NODE - 1; slice >= 0; slice--) { int intrs; cpu = cnode_slice_to_cpuid(cnode, slice); - if (cpu == CPU_NONE) { + if (cpu == num_online_cpus()) { continue; } - if (!cpu_enabled(cpu)) { + if (!cpu_online(cpu)) { continue; } - irqs = irqpdaindr[cpu]; + irqs = irqpdaindr; intrs = irqs->num_irq_used; if (min_count > intrs) { min_count = intrs; best_cpu = cpu; + if ( enable_shub_wars_1_1() ) { + /* Rather than finding the best cpu, always return the first cpu*/ + /* This forces all interrupts to the same cpu */ + break; + } } } return best_cpu; @@ -285,7 +330,7 @@ intr_bit_reserve_test(cpuid_t cpu, cnodeid_t cnode, int req_bit, int resflags, - devfs_handle_t owner_dev, + vertex_hdl_t owner_dev, char *name, int *resp_bit) { @@ -307,18 +352,18 @@ intr_bit_reserve_test(cpuid_t cpu, // Find the node to assign for this interrupt. cpuid_t -intr_heuristic(devfs_handle_t dev, +intr_heuristic(vertex_hdl_t dev, device_desc_t dev_desc, int req_bit, int resflags, - devfs_handle_t owner_dev, + vertex_hdl_t owner_dev, char *name, int *resp_bit) { cpuid_t cpuid; cpuid_t candidate = CPU_NONE; cnodeid_t candidate_node; - devfs_handle_t pconn_vhdl; + vertex_hdl_t pconn_vhdl; pcibr_soft_t pcibr_soft; int bit; @@ -369,8 +414,8 @@ intr_heuristic(devfs_handle_t dev, if (candidate != CPU_NONE) { printk("Cannot target interrupt to target node (%ld).\n",candidate); return CPU_NONE; } else { - printk("Cannot target interrupt to closest node (%d) 0x%p\n", - master_node_get(dev), (void *)owner_dev); + /* printk("Cannot target interrupt to closest node (%d) 0x%p\n", + master_node_get(dev), (void *)owner_dev); */ } // We couldn't put it on the closest node. Try to find another one. diff --git a/arch/ia64/sn/io/sn2/ml_iograph.c b/arch/ia64/sn/io/sn2/ml_iograph.c index 83599fafa98cb6..3af17cd392afe6 100644 --- a/arch/ia64/sn/io/sn2/ml_iograph.c +++ b/arch/ia64/sn/io/sn2/ml_iograph.c @@ -22,7 +22,6 @@ #include <asm/sn/xtalk/xbow.h> #include <asm/sn/pci/bridge.h> #include <asm/sn/klconfig.h> -#include <asm/sn/eeprom.h> #include <asm/sn/sn_private.h> #include <asm/sn/pci/pcibr.h> #include <asm/sn/xtalk/xtalk.h> @@ -43,8 +42,6 @@ /* At most 2 hubs can be connected to an xswitch */ #define NUM_XSWITCH_VOLUNTEER 2 -extern unsigned char Is_pic_on_this_nasid[512]; - /* * Track which hubs have volunteered to manage devices hanging off of * a Crosstalk Switch (e.g. xbow). This structure is allocated, @@ -54,11 +51,11 @@ extern unsigned char Is_pic_on_this_nasid[512]; typedef struct xswitch_vol_s { mutex_t xswitch_volunteer_mutex; int xswitch_volunteer_count; - devfs_handle_t xswitch_volunteer[NUM_XSWITCH_VOLUNTEER]; + vertex_hdl_t xswitch_volunteer[NUM_XSWITCH_VOLUNTEER]; } *xswitch_vol_t; void -xswitch_vertex_init(devfs_handle_t xswitch) +xswitch_vertex_init(vertex_hdl_t xswitch) { xswitch_vol_t xvolinfo; int rc; @@ -78,7 +75,7 @@ xswitch_vertex_init(devfs_handle_t xswitch) * xswitch volunteer structure hanging around. Destroy it. */ static void -xswitch_volunteer_delete(devfs_handle_t xswitch) +xswitch_volunteer_delete(vertex_hdl_t xswitch) { xswitch_vol_t xvolinfo; int rc; @@ -94,10 +91,10 @@ xswitch_volunteer_delete(devfs_handle_t xswitch) */ /* ARGSUSED */ static void -volunteer_for_widgets(devfs_handle_t xswitch, devfs_handle_t master) +volunteer_for_widgets(vertex_hdl_t xswitch, vertex_hdl_t master) { xswitch_vol_t xvolinfo = NULL; - devfs_handle_t hubv; + vertex_hdl_t hubv; hubinfo_t hubinfo; (void)hwgraph_info_get_LBL(xswitch, @@ -140,7 +137,7 @@ extern int xbow_port_io_enabled(nasid_t nasid, int widgetnum); */ /* ARGSUSED */ static void -assign_widgets_to_volunteers(devfs_handle_t xswitch, devfs_handle_t hubv) +assign_widgets_to_volunteers(vertex_hdl_t xswitch, vertex_hdl_t hubv) { xswitch_info_t xswitch_info; xswitch_vol_t xvolinfo = NULL; @@ -223,18 +220,6 @@ assign_widgets_to_volunteers(devfs_handle_t xswitch, devfs_handle_t hubv) bt = iobrick_type_get_nasid(nasid); if (bt >= 0) { - /* - * PXBRICK has two busses per widget so this - * algorithm wouldn't work (all busses would - * be assigned to one volunteer). Change the - * bricktype to PBRICK whose mapping is setup - * suchthat 2 of the PICs will be assigned to - * one volunteer and the other one will be - * assigned to the other volunteer. - */ - if (bt == MODULE_PXBRICK) - bt = MODULE_PBRICK; - i = io_brick_map_widget(bt, widgetnum) & 1; } } @@ -281,8 +266,6 @@ iograph_early_init(void) DBG("iograph_early_init: Found board 0x%p\n", board); } } - - hubio_init(); } /* @@ -307,7 +290,7 @@ io_init_done(cnodeid_t cnodeid,cpu_cookie_t c) * hwid for our use. */ static void -early_probe_for_widget(devfs_handle_t hubv, xwidget_hwid_t hwid) +early_probe_for_widget(vertex_hdl_t hubv, xwidget_hwid_t hwid) { hubreg_t llp_csr_reg; nasid_t nasid; @@ -351,7 +334,7 @@ early_probe_for_widget(devfs_handle_t hubv, xwidget_hwid_t hwid) * added as inventory information. */ static void -xwidget_inventory_add(devfs_handle_t widgetv, +xwidget_inventory_add(vertex_hdl_t widgetv, lboard_t *board, struct xwidget_hwid_s hwid) { @@ -374,14 +357,13 @@ xwidget_inventory_add(devfs_handle_t widgetv, */ void -io_xswitch_widget_init(devfs_handle_t xswitchv, - devfs_handle_t hubv, - xwidgetnum_t widgetnum, - async_attach_t aa) +io_xswitch_widget_init(vertex_hdl_t xswitchv, + vertex_hdl_t hubv, + xwidgetnum_t widgetnum) { xswitch_info_t xswitch_info; xwidgetnum_t hub_widgetid; - devfs_handle_t widgetv; + vertex_hdl_t widgetv; cnodeid_t cnode; widgetreg_t widget_id; nasid_t nasid, peer_nasid; @@ -427,6 +409,7 @@ io_xswitch_widget_init(devfs_handle_t xswitchv, char name[4]; lboard_t dummy; + /* * If the current hub is not supposed to be the master * for this widgetnum, then skip this widget. @@ -470,12 +453,15 @@ io_xswitch_widget_init(devfs_handle_t xswitchv, memset(buffer, 0, 16); format_module_id(buffer, geo_module(board->brd_geoid), MODULE_FORMAT_BRIEF); - sprintf(pathname, EDGE_LBL_MODULE "/%s/" EDGE_LBL_SLAB "/%d" "/%cbrick" "/%s/%d", + + sprintf(pathname, EDGE_LBL_MODULE "/%s/" EDGE_LBL_SLAB "/%d" "/%s" "/%s/%d", buffer, geo_slab(board->brd_geoid), - (board->brd_type == KLTYPE_IBRICK) ? 'I' : - (board->brd_type == KLTYPE_PBRICK) ? 'P' : - (board->brd_type == KLTYPE_XBRICK) ? 'X' : '?', + (board->brd_type == KLTYPE_IBRICK) ? EDGE_LBL_IBRICK : + (board->brd_type == KLTYPE_PBRICK) ? EDGE_LBL_PBRICK : + (board->brd_type == KLTYPE_PXBRICK) ? EDGE_LBL_PXBRICK : + (board->brd_type == KLTYPE_IXBRICK) ? EDGE_LBL_IXBRICK : + (board->brd_type == KLTYPE_XBRICK) ? EDGE_LBL_XBRICK : "?brick", EDGE_LBL_XTALK, widgetnum); DBG("io_xswitch_widget_init: path= %s\n", pathname); @@ -514,36 +500,46 @@ io_xswitch_widget_init(devfs_handle_t xswitchv, xwidget_inventory_add(widgetv,board,hwid); (void)xwidget_register(&hwid, widgetv, widgetnum, - hubv, hub_widgetid, - aa); + hubv, hub_widgetid); ia64_sn_sysctl_iobrick_module_get(nasid, &io_module); if (io_module >= 0) { char buffer[16]; - devfs_handle_t to, from; + vertex_hdl_t to, from; + char *brick_name; + extern char *iobrick_L1bricktype_to_name(int type); + memset(buffer, 0, 16); format_module_id(buffer, geo_module(board->brd_geoid), MODULE_FORMAT_BRIEF); - bt = toupper(MODULE_GET_BTCHAR(io_module)); + if ( islower(MODULE_GET_BTCHAR(io_module)) ) { + bt = toupper(MODULE_GET_BTCHAR(io_module)); + } + else { + bt = MODULE_GET_BTCHAR(io_module); + } + + brick_name = iobrick_L1bricktype_to_name(bt); + /* Add a helper vertex so xbow monitoring * can identify the brick type. It's simply * an edge from the widget 0 vertex to the * brick vertex. */ - sprintf(pathname, "/dev/hw/" EDGE_LBL_MODULE "/%s/" + sprintf(pathname, EDGE_LBL_HW "/" EDGE_LBL_MODULE "/%s/" EDGE_LBL_SLAB "/%d/" EDGE_LBL_NODE "/" EDGE_LBL_XTALK "/" "0", buffer, geo_slab(board->brd_geoid)); from = hwgraph_path_to_vertex(pathname); ASSERT_ALWAYS(from); - sprintf(pathname, "/dev/hw/" EDGE_LBL_MODULE "/%s/" + sprintf(pathname, EDGE_LBL_HW "/" EDGE_LBL_MODULE "/%s/" EDGE_LBL_SLAB "/%d/" - "%cbrick", - buffer, geo_slab(board->brd_geoid), bt); + "%s", + buffer, geo_slab(board->brd_geoid), brick_name); to = hwgraph_path_to_vertex(pathname); ASSERT_ALWAYS(to); @@ -566,12 +562,9 @@ link_done: static void -io_init_xswitch_widgets(devfs_handle_t xswitchv, cnodeid_t cnode) +io_init_xswitch_widgets(vertex_hdl_t xswitchv, cnodeid_t cnode) { xwidgetnum_t widgetnum; - async_attach_t aa; - - aa = async_attach_new(); DBG("io_init_xswitch_widgets: xswitchv 0x%p for cnode %d\n", xswitchv, cnode); @@ -579,13 +572,8 @@ io_init_xswitch_widgets(devfs_handle_t xswitchv, cnodeid_t cnode) widgetnum++) { io_xswitch_widget_init(xswitchv, cnodeid_to_vertex(cnode), - widgetnum, aa); + widgetnum); } - /* - * Wait for parallel attach threads, if any, to complete. - */ - async_attach_waitall(aa); - async_attach_free(aa); } /* @@ -595,11 +583,11 @@ io_init_xswitch_widgets(devfs_handle_t xswitchv, cnodeid_t cnode) * graph and risking hangs. */ static void -io_link_xswitch_widgets(devfs_handle_t xswitchv, cnodeid_t cnodeid) +io_link_xswitch_widgets(vertex_hdl_t xswitchv, cnodeid_t cnodeid) { xwidgetnum_t widgetnum; char pathname[128]; - devfs_handle_t vhdl; + vertex_hdl_t vhdl; nasid_t nasid, peer_nasid; lboard_t *board; @@ -638,21 +626,12 @@ io_link_xswitch_widgets(devfs_handle_t xswitchv, cnodeid_t cnodeid) return; } - if ( Is_pic_on_this_nasid[nasid] ) { - /* Check both buses */ - sprintf(pathname, "%d/"EDGE_LBL_PCIX_0, widgetnum); - if (hwgraph_traverse(xswitchv, pathname, &vhdl) == GRAPH_SUCCESS) - board->brd_graph_link = vhdl; - else { - sprintf(pathname, "%d/"EDGE_LBL_PCIX_1, widgetnum); - if (hwgraph_traverse(xswitchv, pathname, &vhdl) == GRAPH_SUCCESS) - board->brd_graph_link = vhdl; - else - board->brd_graph_link = GRAPH_VERTEX_NONE; - } - } + /* Check both buses */ + sprintf(pathname, "%d/"EDGE_LBL_PCIX_0, widgetnum); + if (hwgraph_traverse(xswitchv, pathname, &vhdl) == GRAPH_SUCCESS) + board->brd_graph_link = vhdl; else { - sprintf(pathname, "%d/"EDGE_LBL_PCI, widgetnum); + sprintf(pathname, "%d/"EDGE_LBL_PCIX_1, widgetnum); if (hwgraph_traverse(xswitchv, pathname, &vhdl) == GRAPH_SUCCESS) board->brd_graph_link = vhdl; else @@ -668,16 +647,15 @@ static void io_init_node(cnodeid_t cnodeid) { /*REFERENCED*/ - devfs_handle_t hubv, switchv, widgetv; + vertex_hdl_t hubv, switchv, widgetv; struct xwidget_hwid_s hwid; hubinfo_t hubinfo; int is_xswitch; nodepda_t *npdap; struct semaphore *peer_sema = 0; uint32_t widget_partnum; - nodepda_router_info_t *npda_rip; cpu_cookie_t c = 0; - extern int hubdev_docallouts(devfs_handle_t); + extern int hubdev_docallouts(vertex_hdl_t); npdap = NODEPDA(cnodeid); @@ -696,21 +674,6 @@ io_init_node(cnodeid_t cnodeid) hubdev_docallouts(hubv); /* - * Set up the dependent routers if we have any. - */ - npda_rip = npdap->npda_rip_first; - - while(npda_rip) { - /* If the router info has not been initialized - * then we need to do the router initialization - */ - if (!npda_rip->router_infop) { - router_init(cnodeid,0,npda_rip); - } - npda_rip = npda_rip->router_next; - } - - /* * Read mfg info on this hub */ @@ -833,7 +796,7 @@ io_init_node(cnodeid_t cnodeid) */ hubinfo_get(hubv, &hubinfo); - (void)xwidget_register(&hwid, widgetv, npdap->basew_id, hubv, hubinfo->h_widgetid, NULL); + (void)xwidget_register(&hwid, widgetv, npdap->basew_id, hubv, hubinfo->h_widgetid); if (!is_xswitch) { /* io_init_done takes cpu cookie as 2nd argument @@ -915,231 +878,9 @@ io_init_node(cnodeid_t cnodeid) * XXX Irix legacy..controller numbering should be part of devfsd's job */ int num_base_io_scsi_ctlr = 2; /* used by syssgi */ -devfs_handle_t base_io_scsi_ctlr_vhdl[NUM_BASE_IO_SCSI_CTLR]; -static devfs_handle_t baseio_enet_vhdl,baseio_console_vhdl; - -/* - * Put the logical controller number information in the - * scsi controller vertices for each scsi controller that - * is in a "fixed position". - */ -static void -scsi_ctlr_nums_add(devfs_handle_t pci_vhdl) -{ - { - int i; - - num_base_io_scsi_ctlr = NUM_BASE_IO_SCSI_CTLR; - - /* Initialize base_io_scsi_ctlr_vhdl array */ - for (i=0; i<num_base_io_scsi_ctlr; i++) - base_io_scsi_ctlr_vhdl[i] = GRAPH_VERTEX_NONE; - } - { - /* - * May want to consider changing the SN0 code, above, to work more like - * the way this works. - */ - devfs_handle_t base_ibrick_xbridge_vhdl; - devfs_handle_t base_ibrick_xtalk_widget_vhdl; - devfs_handle_t scsi_ctlr_vhdl; - int i; - graph_error_t rv; - - /* - * This is a table of "well-known" SCSI controllers and their well-known - * controller numbers. The names in the table start from the base IBrick's - * Xbridge vertex, so the first component is the xtalk widget number. - */ - static struct { - char *base_ibrick_scsi_path; - int controller_number; - } hardwired_scsi_controllers[] = { - {"15/" EDGE_LBL_PCI "/1/" EDGE_LBL_SCSI_CTLR "/0", 0}, - {"15/" EDGE_LBL_PCI "/2/" EDGE_LBL_SCSI_CTLR "/0", 1}, - {"15/" EDGE_LBL_PCI "/3/" EDGE_LBL_SCSI_CTLR "/0", 2}, - {"14/" EDGE_LBL_PCI "/1/" EDGE_LBL_SCSI_CTLR "/0", 3}, - {"14/" EDGE_LBL_PCI "/2/" EDGE_LBL_SCSI_CTLR "/0", 4}, - {"15/" EDGE_LBL_PCI "/6/ohci/0/" EDGE_LBL_SCSI_CTLR "/0", 5}, - {NULL, -1} /* must be last */ - }; - - base_ibrick_xtalk_widget_vhdl = hwgraph_connectpt_get(pci_vhdl); - ASSERT_ALWAYS(base_ibrick_xtalk_widget_vhdl != GRAPH_VERTEX_NONE); - - base_ibrick_xbridge_vhdl = hwgraph_connectpt_get(base_ibrick_xtalk_widget_vhdl); - ASSERT_ALWAYS(base_ibrick_xbridge_vhdl != GRAPH_VERTEX_NONE); - hwgraph_vertex_unref(base_ibrick_xtalk_widget_vhdl); - - /* - * Iterate through the list of well-known SCSI controllers. - * For each controller found, set it's controller number according - * to the table. - */ - for (i=0; hardwired_scsi_controllers[i].base_ibrick_scsi_path != NULL; i++) { - rv = hwgraph_path_lookup(base_ibrick_xbridge_vhdl, - hardwired_scsi_controllers[i].base_ibrick_scsi_path, &scsi_ctlr_vhdl, NULL); - - if (rv != GRAPH_SUCCESS) /* No SCSI at this path */ - continue; - - ASSERT(hardwired_scsi_controllers[i].controller_number < NUM_BASE_IO_SCSI_CTLR); - base_io_scsi_ctlr_vhdl[hardwired_scsi_controllers[i].controller_number] = scsi_ctlr_vhdl; - device_controller_num_set(scsi_ctlr_vhdl, hardwired_scsi_controllers[i].controller_number); - hwgraph_vertex_unref(scsi_ctlr_vhdl); /* (even though we're actually keeping a reference) */ - } - - hwgraph_vertex_unref(base_ibrick_xbridge_vhdl); - } -} - +vertex_hdl_t base_io_scsi_ctlr_vhdl[NUM_BASE_IO_SCSI_CTLR]; #include <asm/sn/ioerror_handling.h> -devfs_handle_t sys_critical_graph_root = GRAPH_VERTEX_NONE; - -/* Define the system critical vertices and connect them through - * a canonical parent-child relationships for easy traversal - * during io error handling. - */ -static void -sys_critical_graph_init(void) -{ - devfs_handle_t bridge_vhdl,master_node_vhdl; - devfs_handle_t xbow_vhdl = GRAPH_VERTEX_NONE; - extern devfs_handle_t hwgraph_root; - devfs_handle_t pci_slot_conn; - int slot; - devfs_handle_t baseio_console_conn; - - DBG("sys_critical_graph_init: FIXME.\n"); - baseio_console_conn = hwgraph_connectpt_get(baseio_console_vhdl); - - if (baseio_console_conn == NULL) { - return; - } - - /* Get the vertex handle for the baseio bridge */ - bridge_vhdl = device_master_get(baseio_console_conn); - - /* Get the master node of the baseio card */ - master_node_vhdl = cnodeid_to_vertex( - master_node_get(baseio_console_vhdl)); - - /* Add the "root->node" part of the system critical graph */ - - sys_critical_graph_vertex_add(hwgraph_root,master_node_vhdl); - - /* Check if we have a crossbow */ - if (hwgraph_traverse(master_node_vhdl, - EDGE_LBL_XTALK"/0", - &xbow_vhdl) == GRAPH_SUCCESS) { - /* We have a crossbow.Add "node->xbow" part of the system - * critical graph. - */ - sys_critical_graph_vertex_add(master_node_vhdl,xbow_vhdl); - - /* Add "xbow->baseio bridge" of the system critical graph */ - sys_critical_graph_vertex_add(xbow_vhdl,bridge_vhdl); - - hwgraph_vertex_unref(xbow_vhdl); - } else - /* We donot have a crossbow. Add "node->baseio_bridge" - * part of the system critical graph. - */ - sys_critical_graph_vertex_add(master_node_vhdl,bridge_vhdl); - - /* Add all the populated PCI slot vertices to the system critical - * graph with the bridge vertex as the parent. - */ - for (slot = 0 ; slot < 8; slot++) { - char slot_edge[10]; - - sprintf(slot_edge,"%d",slot); - if (hwgraph_traverse(bridge_vhdl,slot_edge, &pci_slot_conn) - != GRAPH_SUCCESS) - continue; - sys_critical_graph_vertex_add(bridge_vhdl,pci_slot_conn); - hwgraph_vertex_unref(pci_slot_conn); - } - - hwgraph_vertex_unref(bridge_vhdl); - - /* Add the "ioc3 pci connection point -> console ioc3" part - * of the system critical graph - */ - - if (hwgraph_traverse(baseio_console_vhdl,"..",&pci_slot_conn) == - GRAPH_SUCCESS) { - sys_critical_graph_vertex_add(pci_slot_conn, - baseio_console_vhdl); - hwgraph_vertex_unref(pci_slot_conn); - } - - /* Add the "ethernet pci connection point -> base ethernet" part of - * the system critical graph - */ - if (hwgraph_traverse(baseio_enet_vhdl,"..",&pci_slot_conn) == - GRAPH_SUCCESS) { - sys_critical_graph_vertex_add(pci_slot_conn, - baseio_enet_vhdl); - hwgraph_vertex_unref(pci_slot_conn); - } - - /* Add the "scsi controller pci connection point -> base scsi - * controller" part of the system critical graph - */ - if (hwgraph_traverse(base_io_scsi_ctlr_vhdl[0], - "../..",&pci_slot_conn) == GRAPH_SUCCESS) { - sys_critical_graph_vertex_add(pci_slot_conn, - base_io_scsi_ctlr_vhdl[0]); - hwgraph_vertex_unref(pci_slot_conn); - } - if (hwgraph_traverse(base_io_scsi_ctlr_vhdl[1], - "../..",&pci_slot_conn) == GRAPH_SUCCESS) { - sys_critical_graph_vertex_add(pci_slot_conn, - base_io_scsi_ctlr_vhdl[1]); - hwgraph_vertex_unref(pci_slot_conn); - } - hwgraph_vertex_unref(baseio_console_conn); - -} - -static void -baseio_ctlr_num_set(void) -{ - char name[MAXDEVNAME]; - devfs_handle_t console_vhdl, pci_vhdl, enet_vhdl; - devfs_handle_t ioc3_console_vhdl_get(void); - - - DBG("baseio_ctlr_num_set; FIXME\n"); - console_vhdl = ioc3_console_vhdl_get(); - if (console_vhdl == GRAPH_VERTEX_NONE) - return; - /* Useful for setting up the system critical graph */ - baseio_console_vhdl = console_vhdl; - - vertex_to_name(console_vhdl,name,MAXDEVNAME); - - strcat(name,__DEVSTR1); - pci_vhdl = hwgraph_path_to_vertex(name); - scsi_ctlr_nums_add(pci_vhdl); - /* Unref the pci_vhdl due to the reference by hwgraph_path_to_vertex - */ - hwgraph_vertex_unref(pci_vhdl); - - vertex_to_name(console_vhdl, name, MAXDEVNAME); - strcat(name, __DEVSTR4); - enet_vhdl = hwgraph_path_to_vertex(name); - - /* Useful for setting up the system critical graph */ - baseio_enet_vhdl = enet_vhdl; - - device_controller_num_set(enet_vhdl, 0); - /* Unref the enet_vhdl due to the reference by hwgraph_path_to_vertex - */ - hwgraph_vertex_unref(enet_vhdl); -} /* #endif */ /* @@ -1168,13 +909,6 @@ init_all_devices(void) */ update_node_information(cnodeid); - baseio_ctlr_num_set(); - /* Setup the system critical graph (which is a subgraph of the - * main hwgraph). This information is useful during io error - * handling. - */ - sys_critical_graph_init(); - #if HWG_PRINT hwgraph_print(); #endif @@ -1300,6 +1034,20 @@ struct io_brick_map_s io_brick_tab[] = { } }, +/* IXbrick widget number to PCI bus number map */ + { MODULE_IXBRICK, /* IXbrick type */ + /* PCI Bus # Widget # */ + { 0, 0, 0, 0, 0, 0, 0, 0, /* 0x0 - 0x7 */ + 0, /* 0x8 */ + 0, /* 0x9 */ + 0, 0, /* 0xa - 0xb */ + 1, /* 0xc */ + 5, /* 0xd */ + 0, /* 0xe */ + 3 /* 0xf */ + } + }, + /* Xbrick widget to XIO slot map */ { MODULE_XBRICK, /* Xbrick type */ /* XIO Slot # Widget # */ @@ -1335,61 +1083,3 @@ io_brick_map_widget(int brick_type, int widget_num) return 0; } - -/* - * Use the device's vertex to map the device's widget to a meaningful int - */ -int -io_path_map_widget(devfs_handle_t vertex) -{ - char hw_path_name[MAXDEVNAME]; - char *wp, *bp, *sp = NULL; - int widget_num; - long atoi(char *); - int hwgraph_vertex_name_get(devfs_handle_t vhdl, char *buf, uint buflen); - - - /* Get the full path name of the vertex */ - if (GRAPH_SUCCESS != hwgraph_vertex_name_get(vertex, hw_path_name, - MAXDEVNAME)) - return 0; - - /* Find the widget number in the path name */ - wp = strstr(hw_path_name, "/"EDGE_LBL_XTALK"/"); - if (wp == NULL) - return 0; - widget_num = atoi(wp+7); - if (widget_num < XBOW_PORT_8 || widget_num > XBOW_PORT_F) - return 0; - - /* Find "brick" in the path name */ - bp = strstr(hw_path_name, "brick"); - if (bp == NULL) - return 0; - - /* Find preceding slash */ - sp = bp; - while (sp > hw_path_name) { - sp--; - if (*sp == '/') - break; - } - - /* Invalid if no preceding slash */ - if (!sp) - return 0; - - /* Bump slash pointer to "brick" prefix */ - sp++; - /* - * Verify "brick" prefix length; valid exaples: - * 'I' from "/Ibrick" - * 'P' from "/Pbrick" - * 'X' from "/Xbrick" - */ - if ((bp - sp) != 1) - return 0; - - return (io_brick_map_widget((int)*sp, widget_num)); - -} diff --git a/arch/ia64/sn/io/sn2/module.c b/arch/ia64/sn/io/sn2/module.c index 9b01b6144f307c..4679cf22e69812 100644 --- a/arch/ia64/sn/io/sn2/module.c +++ b/arch/ia64/sn/io/sn2/module.c @@ -18,7 +18,6 @@ #include <asm/sn/xtalk/xbow.h> #include <asm/sn/pci/bridge.h> #include <asm/sn/klconfig.h> -#include <asm/sn/sn1/hubdev.h> #include <asm/sn/module.h> #include <asm/sn/pci/pcibr.h> #include <asm/sn/xtalk/xswitch.h> diff --git a/arch/ia64/sn/io/sn2/pci_bus_cvlink.c b/arch/ia64/sn/io/sn2/pci_bus_cvlink.c deleted file mode 100644 index 586786bc9c3286..00000000000000 --- a/arch/ia64/sn/io/sn2/pci_bus_cvlink.c +++ /dev/null @@ -1,719 +0,0 @@ -/* $Id$ - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 1992 - 1997, 2000-2003 Silicon Graphics, Inc. All rights reserved. - */ - -#include <linux/config.h> -#include <linux/init.h> -#include <linux/types.h> -#include <linux/pci.h> -#include <linux/pci_ids.h> -#include <linux/sched.h> -#include <linux/ioport.h> -#include <asm/sn/types.h> -#include <asm/sn/hack.h> -#include <asm/sn/sgi.h> -#include <asm/sn/io.h> -#include <asm/sn/driver.h> -#include <asm/sn/iograph.h> -#include <asm/param.h> -#include <asm/sn/pio.h> -#include <asm/sn/xtalk/xwidget.h> -#include <asm/sn/sn_private.h> -#include <asm/sn/addrs.h> -#include <asm/sn/invent.h> -#include <asm/sn/hcl.h> -#include <asm/sn/hcl_util.h> -#include <asm/sn/intr.h> -#include <asm/sn/xtalk/xtalkaddrs.h> -#include <asm/sn/klconfig.h> -#include <asm/sn/nodepda.h> -#include <asm/sn/pci/pciio.h> -#include <asm/sn/pci/pcibr.h> -#include <asm/sn/pci/pcibr_private.h> -#include <asm/sn/pci/pci_bus_cvlink.h> -#include <asm/sn/simulator.h> -#include <asm/sn/sn_cpuid.h> - -extern int bridge_rev_b_data_check_disable; - -devfs_handle_t busnum_to_pcibr_vhdl[MAX_PCI_XWIDGET]; -nasid_t busnum_to_nid[MAX_PCI_XWIDGET]; -void * busnum_to_atedmamaps[MAX_PCI_XWIDGET]; -unsigned char num_bridges; -static int done_probing = 0; - -static int pci_bus_map_create(devfs_handle_t xtalk, char * io_moduleid); -devfs_handle_t devfn_to_vertex(unsigned char busnum, unsigned int devfn); - -extern unsigned char Is_pic_on_this_nasid[512]; - -extern void sn_init_irq_desc(void); -extern void register_pcibr_intr(int irq, pcibr_intr_t intr); - - -/* - * For the given device, initialize whether it is a PIC device. - */ -static void -set_isPIC(struct sn_device_sysdata *device_sysdata) -{ - pciio_info_t pciio_info = pciio_info_get(device_sysdata->vhdl); - pcibr_soft_t pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info); - - device_sysdata->isPIC = IS_PIC_SOFT(pcibr_soft);; -} - -/* - * pci_bus_cvlink_init() - To be called once during initialization before - * SGI IO Infrastructure init is called. - */ -void -pci_bus_cvlink_init(void) -{ - - extern void ioconfig_bus_init(void); - - memset(busnum_to_pcibr_vhdl, 0x0, sizeof(devfs_handle_t) * MAX_PCI_XWIDGET); - memset(busnum_to_nid, 0x0, sizeof(nasid_t) * MAX_PCI_XWIDGET); - - memset(busnum_to_atedmamaps, 0x0, sizeof(void *) * MAX_PCI_XWIDGET); - - num_bridges = 0; - - ioconfig_bus_init(); -} - -/* - * pci_bus_to_vertex() - Given a logical Linux Bus Number returns the associated - * pci bus vertex from the SGI IO Infrastructure. - */ -devfs_handle_t -pci_bus_to_vertex(unsigned char busnum) -{ - - devfs_handle_t pci_bus = NULL; - - - /* - * First get the xwidget vertex. - */ - pci_bus = busnum_to_pcibr_vhdl[busnum]; - return(pci_bus); -} - -/* - * devfn_to_vertex() - returns the vertex of the device given the bus, slot, - * and function numbers. - */ -devfs_handle_t -devfn_to_vertex(unsigned char busnum, unsigned int devfn) -{ - - int slot = 0; - int func = 0; - char name[16]; - devfs_handle_t pci_bus = NULL; - devfs_handle_t device_vertex = (devfs_handle_t)NULL; - - /* - * Go get the pci bus vertex. - */ - pci_bus = pci_bus_to_vertex(busnum); - if (!pci_bus) { - /* - * During probing, the Linux pci code invents non existant - * bus numbers and pci_dev structures and tries to access - * them to determine existance. Don't crib during probing. - */ - if (done_probing) - printk("devfn_to_vertex: Invalid bus number %d given.\n", busnum); - return(NULL); - } - - - /* - * Go get the slot&function vertex. - * Should call pciio_slot_func_to_name() when ready. - */ - slot = PCI_SLOT(devfn); - func = PCI_FUNC(devfn); - - /* - * For a NON Multi-function card the name of the device looks like: - * ../pci/1, ../pci/2 .. - */ - if (func == 0) { - sprintf(name, "%d", slot); - if (hwgraph_traverse(pci_bus, name, &device_vertex) == - GRAPH_SUCCESS) { - if (device_vertex) { - return(device_vertex); - } - } - } - - /* - * This maybe a multifunction card. It's names look like: - * ../pci/1a, ../pci/1b, etc. - */ - sprintf(name, "%d%c", slot, 'a'+func); - if (hwgraph_traverse(pci_bus, name, &device_vertex) != GRAPH_SUCCESS) { - if (!device_vertex) { - return(NULL); - } - } - - return(device_vertex); -} - -/* - * For the given device, initialize the addresses for both the Device(x) Flush - * Write Buffer register and the Xbow Flush Register for the port the PCI bus - * is connected. - */ -static void -set_flush_addresses(struct pci_dev *device_dev, - struct sn_device_sysdata *device_sysdata) -{ - pciio_info_t pciio_info = pciio_info_get(device_sysdata->vhdl); - pciio_slot_t pciio_slot = pciio_info_slot_get(pciio_info); - pcibr_soft_t pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info); - bridge_t *bridge = pcibr_soft->bs_base; - nasid_t nasid; - - /* - * Get the nasid from the bridge. - */ - nasid = NASID_GET(device_sysdata->dma_buf_sync); - if (IS_PIC_DEVICE(device_dev)) { - device_sysdata->dma_buf_sync = (volatile unsigned int *) - &bridge->b_wr_req_buf[pciio_slot].reg; - device_sysdata->xbow_buf_sync = (volatile unsigned int *) - XBOW_PRIO_LINKREGS_PTR(NODE_SWIN_BASE(nasid, 0), - pcibr_soft->bs_xid); - } else { - /* - * Accessing Xbridge and Xbow register when SHUB swapoper is on!. - */ - device_sysdata->dma_buf_sync = (volatile unsigned int *) - ((uint64_t)&(bridge->b_wr_req_buf[pciio_slot].reg)^4); - device_sysdata->xbow_buf_sync = (volatile unsigned int *) - ((uint64_t)(XBOW_PRIO_LINKREGS_PTR( - NODE_SWIN_BASE(nasid, 0), pcibr_soft->bs_xid)) ^ 4); - } - -#ifdef DEBUG - printk("set_flush_addresses: dma_buf_sync %p xbow_buf_sync %p\n", - device_sysdata->dma_buf_sync, device_sysdata->xbow_buf_sync); - -printk("set_flush_addresses: dma_buf_sync\n"); - while((volatile unsigned int )*device_sysdata->dma_buf_sync); -printk("set_flush_addresses: xbow_buf_sync\n"); - while((volatile unsigned int )*device_sysdata->xbow_buf_sync); -#endif - -} - -/* - * Most drivers currently do not properly tell the arch specific pci dma - * interfaces whether they can handle A64. Here is where we privately - * keep track of this. - */ -static void __init -set_sn_pci64(struct pci_dev *dev) -{ - unsigned short vendor = dev->vendor; - unsigned short device = dev->device; - - if (vendor == PCI_VENDOR_ID_QLOGIC) { - if ((device == PCI_DEVICE_ID_QLOGIC_ISP2100) || - (device == PCI_DEVICE_ID_QLOGIC_ISP2200)) { - SET_PCIA64(dev); - return; - } - } - - if (vendor == PCI_VENDOR_ID_SGI) { - if (device == PCI_DEVICE_ID_SGI_IOC3) { - SET_PCIA64(dev); - return; - } - } - -} - -/* - * sn_pci_fixup() - This routine is called when platform_pci_fixup() is - * invoked at the end of pcibios_init() to link the Linux pci - * infrastructure to SGI IO Infrasturcture - ia64/kernel/pci.c - * - * Other platform specific fixup can also be done here. - */ -void -sn_pci_fixup(int arg) -{ - struct list_head *ln; - struct pci_bus *pci_bus = NULL; - struct pci_dev *device_dev = NULL; - struct sn_widget_sysdata *widget_sysdata; - struct sn_device_sysdata *device_sysdata; - pciio_intr_t intr_handle; - int cpuid, bit; - devfs_handle_t device_vertex; - pciio_intr_line_t lines; - extern void sn_pci_find_bios(void); - extern int numnodes; - int cnode; - extern void io_sh_swapper(int, int); - - for (cnode = 0; cnode < numnodes; cnode++) { - if ( !Is_pic_on_this_nasid[cnodeid_to_nasid(cnode)] ) - io_sh_swapper((cnodeid_to_nasid(cnode)), 0); - } - - if (arg == 0) { -#ifdef CONFIG_PROC_FS - extern void register_sn_procfs(void); -#endif - - sn_init_irq_desc(); - sn_pci_find_bios(); - for (cnode = 0; cnode < numnodes; cnode++) { - extern void intr_init_vecblk(nodepda_t *npda, cnodeid_t, int); - intr_init_vecblk(NODEPDA(cnode), cnode, 0); - } - - /* - * When we return to generic Linux, Swapper is always on .. - */ - for (cnode = 0; cnode < numnodes; cnode++) { - if ( !Is_pic_on_this_nasid[cnodeid_to_nasid(cnode)] ) - io_sh_swapper((cnodeid_to_nasid(cnode)), 1); - } -#ifdef CONFIG_PROC_FS - register_sn_procfs(); -#endif - return; - } - - - done_probing = 1; - - /* - * Initialize the pci bus vertex in the pci_bus struct. - */ - for( ln = pci_root_buses.next; ln != &pci_root_buses; ln = ln->next) { - pci_bus = pci_bus_b(ln); - widget_sysdata = kmalloc(sizeof(struct sn_widget_sysdata), - GFP_KERNEL); - widget_sysdata->vhdl = pci_bus_to_vertex(pci_bus->number); - pci_bus->sysdata = (void *)widget_sysdata; - } - - /* - * set the root start and end so that drivers calling check_region() - * won't see a conflict - */ - ioport_resource.start = 0xc000000000000000; - ioport_resource.end = 0xcfffffffffffffff; - - /* - * Initialize the device vertex in the pci_dev struct. - */ - pci_for_each_dev(device_dev) { - unsigned int irq; - int idx; - u16 cmd; - devfs_handle_t vhdl; - unsigned long size; - extern int bit_pos_to_irq(int); - - if (device_dev->vendor == PCI_VENDOR_ID_SGI && - device_dev->device == PCI_DEVICE_ID_SGI_IOC3) { - extern void pci_fixup_ioc3(struct pci_dev *d); - pci_fixup_ioc3(device_dev); - } - - /* Set the device vertex */ - - device_sysdata = kmalloc(sizeof(struct sn_device_sysdata), - GFP_KERNEL); - device_sysdata->vhdl = devfn_to_vertex(device_dev->bus->number, device_dev->devfn); - device_sysdata->isa64 = 0; - /* - * Set the xbridge Device(X) Write Buffer Flush and Xbow Flush - * register addresses. - */ - (void) set_flush_addresses(device_dev, device_sysdata); - - device_dev->sysdata = (void *) device_sysdata; - set_sn_pci64(device_dev); - set_isPIC(device_sysdata); - - pci_read_config_word(device_dev, PCI_COMMAND, &cmd); - - /* - * Set the resources address correctly. The assumption here - * is that the addresses in the resource structure has been - * read from the card and it was set in the card by our - * Infrastructure .. - */ - vhdl = device_sysdata->vhdl; - for (idx = 0; idx < PCI_ROM_RESOURCE; idx++) { - size = 0; - size = device_dev->resource[idx].end - - device_dev->resource[idx].start; - if (size) { - device_dev->resource[idx].start = (unsigned long)pciio_pio_addr(vhdl, 0, PCIIO_SPACE_WIN(idx), 0, size, 0, (IS_PIC_DEVICE(device_dev)) ? 0 : PCIIO_BYTE_STREAM); - device_dev->resource[idx].start |= __IA64_UNCACHED_OFFSET; - } - else - continue; - - device_dev->resource[idx].end = - device_dev->resource[idx].start + size; - - if (device_dev->resource[idx].flags & IORESOURCE_IO) - cmd |= PCI_COMMAND_IO; - - if (device_dev->resource[idx].flags & IORESOURCE_MEM) - cmd |= PCI_COMMAND_MEMORY; - } -#if 0 - /* - * Software WAR for a Software BUG. - * This is only temporary. - * See PV 872791 - */ - - /* - * Now handle the ROM resource .. - */ - size = device_dev->resource[PCI_ROM_RESOURCE].end - - device_dev->resource[PCI_ROM_RESOURCE].start; - - if (size) { - device_dev->resource[PCI_ROM_RESOURCE].start = - (unsigned long) pciio_pio_addr(vhdl, 0, PCIIO_SPACE_ROM, 0, - size, 0, (IS_PIC_DEVICE(device_dev)) ? 0 : PCIIO_BYTE_STREAM); - device_dev->resource[PCI_ROM_RESOURCE].start |= __IA64_UNCACHED_OFFSET; - device_dev->resource[PCI_ROM_RESOURCE].end = - device_dev->resource[PCI_ROM_RESOURCE].start + size; - } -#endif - - /* - * Update the Command Word on the Card. - */ - cmd |= PCI_COMMAND_MASTER; /* If the device doesn't support */ - /* bit gets dropped .. no harm */ - pci_write_config_word(device_dev, PCI_COMMAND, cmd); - - pci_read_config_byte(device_dev, PCI_INTERRUPT_PIN, (unsigned char *)&lines); - if (device_dev->vendor == PCI_VENDOR_ID_SGI && - device_dev->device == PCI_DEVICE_ID_SGI_IOC3 ) { - lines = 1; - } - - device_sysdata = (struct sn_device_sysdata *)device_dev->sysdata; - device_vertex = device_sysdata->vhdl; - - intr_handle = pciio_intr_alloc(device_vertex, NULL, lines, device_vertex); - - bit = intr_handle->pi_irq; - cpuid = intr_handle->pi_cpu; - irq = bit; - irq = irq + (cpuid << 8); - pciio_intr_connect(intr_handle, (intr_func_t)0, (intr_arg_t)0); - device_dev->irq = irq; - register_pcibr_intr(irq, (pcibr_intr_t)intr_handle); -#ifdef ajmtestintr - { - int slot = PCI_SLOT(device_dev->devfn); - static int timer_set = 0; - pcibr_intr_t pcibr_intr = (pcibr_intr_t)intr_handle; - pcibr_soft_t pcibr_soft = pcibr_intr->bi_soft; - extern void intr_test_handle_intr(int, void*, struct pt_regs *); - - if (!timer_set) { - intr_test_set_timer(); - timer_set = 1; - } - intr_test_register_irq(irq, pcibr_soft, slot); - request_irq(irq, intr_test_handle_intr,0,NULL, NULL); - } -#endif - - } - - for (cnode = 0; cnode < numnodes; cnode++) { - if ( !Is_pic_on_this_nasid[cnodeid_to_nasid(cnode)] ) - io_sh_swapper((cnodeid_to_nasid(cnode)), 1); - } -} - -/* - * linux_bus_cvlink() Creates a link between the Linux PCI Bus number - * to the actual hardware component that it represents: - * /dev/hw/linux/busnum/0 -> ../../../hw/module/001c01/slab/0/Ibrick/xtalk/15/pci - * - * The bus vertex, when called to devfs_generate_path() returns: - * hw/module/001c01/slab/0/Ibrick/xtalk/15/pci - * hw/module/001c01/slab/1/Pbrick/xtalk/12/pci-x/0 - * hw/module/001c01/slab/1/Pbrick/xtalk/12/pci-x/1 - */ -void -linux_bus_cvlink(void) -{ - char name[8]; - int index; - - for (index=0; index < MAX_PCI_XWIDGET; index++) { - if (!busnum_to_pcibr_vhdl[index]) - continue; - - sprintf(name, "%x", index); - (void) hwgraph_edge_add(linux_busnum, busnum_to_pcibr_vhdl[index], - name); - } -} - -/* - * pci_bus_map_create() - Called by pci_bus_to_hcl_cvlink() to finish the job. - * - * Linux PCI Bus numbers are assigned from lowest module_id numbers - * (rack/slot etc.) starting from HUB_WIDGET_ID_MAX down to - * HUB_WIDGET_ID_MIN: - * widgetnum 15 gets lower Bus Number than widgetnum 14 etc. - * - * Given 2 modules 001c01 and 001c02 we get the following mappings: - * 001c01, widgetnum 15 = Bus number 0 - * 001c01, widgetnum 14 = Bus number 1 - * 001c02, widgetnum 15 = Bus number 3 - * 001c02, widgetnum 14 = Bus number 4 - * etc. - * - * The rational for starting Bus Number 0 with Widget number 15 is because - * the system boot disks are always connected via Widget 15 Slot 0 of the - * I-brick. Linux creates /dev/sd* devices(naming) strating from Bus Number 0 - * Therefore, /dev/sda1 will be the first disk, on Widget 15 of the lowest - * module id(Master Cnode) of the system. - * - */ -static int -pci_bus_map_create(devfs_handle_t xtalk, char * io_moduleid) -{ - - devfs_handle_t master_node_vertex = NULL; - devfs_handle_t xwidget = NULL; - devfs_handle_t pci_bus = NULL; - hubinfo_t hubinfo = NULL; - xwidgetnum_t widgetnum; - char pathname[128]; - graph_error_t rv; - int bus; - int basebus_num; - int bus_number; - - /* - * Loop throught this vertex and get the Xwidgets .. - */ - - - /* PCI devices */ - - for (widgetnum = HUB_WIDGET_ID_MAX; widgetnum >= HUB_WIDGET_ID_MIN; widgetnum--) { - sprintf(pathname, "%d", widgetnum); - xwidget = NULL; - - /* - * Example - /hw/module/001c16/Pbrick/xtalk/8 is the xwidget - * /hw/module/001c16/Pbrick/xtalk/8/pci/1 is device - */ - rv = hwgraph_traverse(xtalk, pathname, &xwidget); - if ( (rv != GRAPH_SUCCESS) ) { - if (!xwidget) { - continue; - } - } - - sprintf(pathname, "%d/"EDGE_LBL_PCI, widgetnum); - pci_bus = NULL; - if (hwgraph_traverse(xtalk, pathname, &pci_bus) != GRAPH_SUCCESS) - if (!pci_bus) { - continue; -} - - /* - * Assign the correct bus number and also the nasid of this - * pci Xwidget. - * - * Should not be any race here ... - */ - num_bridges++; - busnum_to_pcibr_vhdl[num_bridges - 1] = pci_bus; - - /* - * Get the master node and from there get the NASID. - */ - master_node_vertex = device_master_get(xwidget); - if (!master_node_vertex) { - printk("WARNING: pci_bus_map_create: Unable to get .master for vertex 0x%p\n", (void *)xwidget); - } - - hubinfo_get(master_node_vertex, &hubinfo); - if (!hubinfo) { - printk("WARNING: pci_bus_map_create: Unable to get hubinfo for master node vertex 0x%p\n", (void *)master_node_vertex); - return(1); - } else { - busnum_to_nid[num_bridges - 1] = hubinfo->h_nasid; - } - - /* - * Pre assign DMA maps needed for 32 Bits Page Map DMA. - */ - busnum_to_atedmamaps[num_bridges - 1] = (void *) kmalloc( - sizeof(struct sn_dma_maps_s) * MAX_ATE_MAPS, GFP_KERNEL); - if (!busnum_to_atedmamaps[num_bridges - 1]) - printk("WARNING: pci_bus_map_create: Unable to precreate ATE DMA Maps for busnum %d vertex 0x%p\n", num_bridges - 1, (void *)xwidget); - - memset(busnum_to_atedmamaps[num_bridges - 1], 0x0, - sizeof(struct sn_dma_maps_s) * MAX_ATE_MAPS); - - } - - /* - * PCIX devices - * We number busses differently for PCI-X devices. - * We start from Lowest Widget on up .. - */ - - (void) ioconfig_get_busnum((char *)io_moduleid, &basebus_num); - - for (widgetnum = HUB_WIDGET_ID_MIN; widgetnum <= HUB_WIDGET_ID_MAX; widgetnum++) { - - /* Do both buses */ - for ( bus = 0; bus < 2; bus++ ) { - sprintf(pathname, "%d", widgetnum); - xwidget = NULL; - - /* - * Example - /hw/module/001c16/Pbrick/xtalk/8 is the xwidget - * /hw/module/001c16/Pbrick/xtalk/8/pci-x/0 is the bus - * /hw/module/001c16/Pbrick/xtalk/8/pci-x/0/1 is device - */ - rv = hwgraph_traverse(xtalk, pathname, &xwidget); - if ( (rv != GRAPH_SUCCESS) ) { - if (!xwidget) { - continue; - } - } - - if ( bus == 0 ) - sprintf(pathname, "%d/"EDGE_LBL_PCIX_0, widgetnum); - else - sprintf(pathname, "%d/"EDGE_LBL_PCIX_1, widgetnum); - pci_bus = NULL; - if (hwgraph_traverse(xtalk, pathname, &pci_bus) != GRAPH_SUCCESS) - if (!pci_bus) { - continue; - } - - /* - * Assign the correct bus number and also the nasid of this - * pci Xwidget. - * - * Should not be any race here ... - */ - bus_number = basebus_num + bus + io_brick_map_widget(MODULE_PXBRICK, widgetnum); -#ifdef DEBUG - printk("bus_number %d basebus_num %d bus %d io %d\n", - bus_number, basebus_num, bus, - io_brick_map_widget(MODULE_PXBRICK, widgetnum)); -#endif - busnum_to_pcibr_vhdl[bus_number] = pci_bus; - - /* - * Pre assign DMA maps needed for 32 Bits Page Map DMA. - */ - busnum_to_atedmamaps[bus_number] = (void *) kmalloc( - sizeof(struct sn_dma_maps_s) * MAX_ATE_MAPS, GFP_KERNEL); - if (!busnum_to_atedmamaps[bus_number]) - printk("WARNING: pci_bus_map_create: Unable to precreate ATE DMA Maps for busnum %d vertex 0x%p\n", num_bridges - 1, (void *)xwidget); - - memset(busnum_to_atedmamaps[bus_number], 0x0, - sizeof(struct sn_dma_maps_s) * MAX_ATE_MAPS); - } - } - - return(0); -} - -/* - * pci_bus_to_hcl_cvlink() - This routine is called after SGI IO Infrastructure - * initialization has completed to set up the mappings between Xbridge - * and logical pci bus numbers. We also set up the NASID for each of these - * xbridges. - * - * Must be called before pci_init() is invoked. - */ -int -pci_bus_to_hcl_cvlink(void) -{ - - devfs_handle_t devfs_hdl = NULL; - devfs_handle_t xtalk = NULL; - int rv = 0; - char name[256]; - char tmp_name[256]; - int i, ii; - - /* - * Figure out which IO Brick is connected to the Compute Bricks. - */ - for (i = 0; i < nummodules; i++) { - extern int iomoduleid_get(nasid_t); - moduleid_t iobrick_id; - nasid_t nasid = -1; - int nodecnt; - int n = 0; - - nodecnt = modules[i]->nodecnt; - for ( n = 0; n < nodecnt; n++ ) { - nasid = cnodeid_to_nasid(modules[i]->nodes[n]); - iobrick_id = iomoduleid_get(nasid); - if ((int)iobrick_id > 0) { /* Valid module id */ - char name[12]; - memset(name, 0, 12); - format_module_id((char *)&(modules[i]->io[n].moduleid), iobrick_id, MODULE_FORMAT_BRIEF); - } - } - } - - devfs_hdl = hwgraph_path_to_vertex("/dev/hw/module"); - for (i = 0; i < nummodules ; i++) { - for ( ii = 0; ii < 2 ; ii++ ) { - memset(name, 0, 256); - memset(tmp_name, 0, 256); - format_module_id(name, modules[i]->id, MODULE_FORMAT_BRIEF); - sprintf(tmp_name, "/slab/%d/Pbrick/xtalk", geo_slab(modules[i]->geoid[ii])); - strcat(name, tmp_name); - xtalk = NULL; - rv = hwgraph_edge_get(devfs_hdl, name, &xtalk); - pci_bus_map_create(xtalk, (char *)&(modules[i]->io[ii].moduleid)); - } - } - - /* - * Create the Linux PCI bus number vertex link. - */ - (void)linux_bus_cvlink(); - (void)ioconfig_bus_new_entries(); - - return(0); -} diff --git a/arch/ia64/sn/io/sn2/pcibr/Makefile b/arch/ia64/sn/io/sn2/pcibr/Makefile index 0b384ee57a066e..c7fdccba1ed1ae 100644 --- a/arch/ia64/sn/io/sn2/pcibr/Makefile +++ b/arch/ia64/sn/io/sn2/pcibr/Makefile @@ -9,13 +9,9 @@ # Makefile for the sn2 specific pci bridge routines. # -EXTRA_CFLAGS := -DLITTLE_ENDIAN +EXTRA_CFLAGS := -DLITTLE_ENDIAN -DSHUB_SWAP_WAR -ifdef CONFIG_IA64_SGI_SN2 -EXTRA_CFLAGS += -DSHUB_SWAP_WAR -endif - -obj-$(CONFIG_IA64_SGI_SN2) += pcibr_dvr.o pcibr_ate.o pcibr_config.o \ +obj-$(CONFIG_IA64_SGI_SN2) += pcibr_ate.o pcibr_config.o \ pcibr_dvr.o pcibr_hints.o \ pcibr_intr.o pcibr_rrb.o pcibr_slot.o \ pcibr_error.o diff --git a/arch/ia64/sn/io/sn2/pcibr/pcibr_ate.c b/arch/ia64/sn/io/sn2/pcibr/pcibr_ate.c index 5b8460ee01d124..ed31eedfab93c7 100644 --- a/arch/ia64/sn/io/sn2/pcibr/pcibr_ate.c +++ b/arch/ia64/sn/io/sn2/pcibr/pcibr_ate.c @@ -4,7 +4,7 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. * - * Copyright (C) 2001-2002 Silicon Graphics, Inc. All rights reserved. + * Copyright (C) 2001-2003 Silicon Graphics, Inc. All rights reserved. */ #include <linux/types.h> @@ -27,7 +27,6 @@ #include <asm/sn/prio.h> #include <asm/sn/xtalk/xbow.h> #include <asm/sn/ioc3.h> -#include <asm/sn/eeprom.h> #include <asm/sn/io.h> #include <asm/sn/sn_private.h> @@ -101,73 +100,26 @@ pcibr_init_ext_ate_ram(bridge_t *bridge) int i, j; bridgereg_t old_enable, new_enable; int s; - int this_is_pic = is_pic(bridge); /* Probe SSRAM to determine its size. */ - if ( this_is_pic ) { - old_enable = bridge->b_int_enable; - new_enable = old_enable & ~BRIDGE_IMR_PCI_MST_TIMEOUT; - 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; - } - } + 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++) { /* 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 */ for (j = 1; j < i; j++) bridge->b_ext_ate_ram[ATE_NUM_ENTRIES(j) - 1] = 0; /* See if value was written */ - if ( this_is_pic ) { - 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; - } - 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) - largest_working_size = i; - } - } - } - } - if ( this_is_pic ) { - bridge->b_int_enable = old_enable; - 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 */ - } } + bridge->b_int_enable = old_enable; + bridge->b_wid_tflush; /* wait until Bridge PIO complete */ /* * ensure that we write and read without any interruption. @@ -175,26 +127,10 @@ pcibr_init_ext_ate_ram(bridge_t *bridge) */ 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(largest_working_size); - 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 */ - } - } + bridge->b_wid_control; /* inval addr bug war */ splx(s); num_entries = ATE_NUM_ENTRIES(largest_working_size); @@ -423,16 +359,7 @@ ate_freeze(pcibr_dmamap_t pcibr_dmamap, /* Flush the write buffer associated with this * PCI device which might be using dma map RAM. */ - if ( is_pic(bridge) ) { - 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; - } + bridge->b_wr_req_buf[slot].reg; } } } diff --git a/arch/ia64/sn/io/sn2/pcibr/pcibr_config.c b/arch/ia64/sn/io/sn2/pcibr/pcibr_config.c index d3f3913b05de96..77a9f9a3686d94 100644 --- a/arch/ia64/sn/io/sn2/pcibr/pcibr_config.c +++ b/arch/ia64/sn/io/sn2/pcibr/pcibr_config.c @@ -4,7 +4,7 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. * - * Copyright (C) 2001-2002 Silicon Graphics, Inc. All rights reserved. + * Copyright (C) 2001-2003 Silicon Graphics, Inc. All rights reserved. */ #include <linux/types.h> @@ -28,19 +28,16 @@ #include <asm/sn/prio.h> #include <asm/sn/xtalk/xbow.h> #include <asm/sn/ioc3.h> -#include <asm/sn/eeprom.h> #include <asm/sn/io.h> #include <asm/sn/sn_private.h> -extern pcibr_info_t pcibr_info_get(devfs_handle_t); +extern pcibr_info_t pcibr_info_get(vertex_hdl_t); -uint64_t pcibr_config_get(devfs_handle_t, 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 do_pcibr_config_set(int, cfg_p, unsigned, unsigned, uint64_t); -static void swap_do_pcibr_config_set(cfg_p, unsigned, unsigned, uint64_t); +uint64_t pcibr_config_get(vertex_hdl_t, unsigned, unsigned); +uint64_t do_pcibr_config_get(cfg_p, unsigned, unsigned); +void pcibr_config_set(vertex_hdl_t, unsigned, unsigned, uint64_t); +void 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 @@ -51,18 +48,13 @@ static void swap_do_pcibr_config_set(cfg_p, unsigned, unsigned, uint64_t); #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 CBP(b,r) (((volatile uint8_t *) b)[(r)]) +#define CSP(b,r) (((volatile uint16_t *) b)[((r)/2)]) #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 CS(b,r) (((volatile uint16_t *) cfgbase)[((r)/2)^1]) -#define CW(b,r) (((volatile uint32_t *) cfgbase)[(r)/4]) -#endif /* * Return a config space address for given slot / func / offset. Note the @@ -84,8 +76,7 @@ pcibr_func_config_addr(bridge_t *bridge, pciio_bus_t bus, pciio_slot_t slot, /* * Type 0 config space */ - if (is_pic(bridge)) - slot++; + slot++; return &bridge->b_type0_cfg_dev[slot].f[func].l[offset]; } @@ -109,7 +100,7 @@ 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 (do_pcibr_config_get(cfg_base, offset, sizeof(unsigned))); } /* @@ -122,7 +113,7 @@ pcibr_func_config_get(bridge_t *bridge, pciio_slot_t slot, 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))); + return (do_pcibr_config_get(cfg_base, offset, sizeof(unsigned))); } /* @@ -135,7 +126,7 @@ pcibr_slot_config_set(bridge_t *bridge, pciio_slot_t slot, 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); + do_pcibr_config_set(cfg_base, offset, sizeof(unsigned), val); } /* @@ -148,13 +139,13 @@ pcibr_func_config_set(bridge_t *bridge, pciio_slot_t slot, 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); + do_pcibr_config_set(cfg_base, offset, sizeof(unsigned), val); } int pcibr_config_debug = 0; cfg_p -pcibr_config_addr(devfs_handle_t conn, +pcibr_config_addr(vertex_hdl_t conn, unsigned reg) { pcibr_info_t pcibr_info; @@ -183,19 +174,6 @@ pcibr_config_addr(devfs_handle_t conn, 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 @@ -224,44 +202,23 @@ pcibr_config_addr(devfs_handle_t conn, return cfgbase; } -extern unsigned char Is_pic_on_this_nasid[]; uint64_t -pcibr_config_get(devfs_handle_t conn, +pcibr_config_get(vertex_hdl_t conn, unsigned reg, unsigned size) { - 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), + return do_pcibr_config_get(pcibr_config_addr(conn, reg), PCI_TYPE1_REG(reg), size); } uint64_t -do_pcibr_config_get( - int pic, - cfg_p cfgbase, +do_pcibr_config_get(cfg_p cfgbase, unsigned reg, unsigned size) { 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 = CWP(cfgbase, reg); if (reg & 3) value >>= 8 * (reg & 3); if (size < 4) @@ -270,108 +227,43 @@ do_pcibr_config_get( } void -pcibr_config_set(devfs_handle_t conn, +pcibr_config_set(vertex_hdl_t conn, unsigned reg, unsigned size, uint64_t value) { - 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), + do_pcibr_config_set(pcibr_config_addr(conn, reg), PCI_TYPE1_REG(reg), size, value); } void -do_pcibr_config_set(int pic, - cfg_p cfgbase, +do_pcibr_config_set(cfg_p cfgbase, unsigned reg, unsigned size, uint64_t value) { - if ( pic ) { - switch (size) { - case 1: + switch (size) { + case 1: + CBP(cfgbase, reg) = value; + break; + case 2: + if (reg & 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) { - case 1: - CB(cfgbase, reg) = value; - break; - case 2: - if (reg & 1) { - CB(cfgbase, reg) = value; - CB(cfgbase, reg + 1) = value >> 8; - } else - CS(cfgbase, reg) = value; - break; - case 3: - if (reg & 1) { - CB(cfgbase, reg) = value; - CS(cfgbase, (reg + 1)) = value >> 8; - } else { - CS(cfgbase, reg) = value; - CB(cfgbase, reg + 2) = value >> 16; - } - break; - case 4: - CW(cfgbase, reg) = value; - 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; - } + 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; + } } diff --git a/arch/ia64/sn/io/sn2/pcibr/pcibr_dvr.c b/arch/ia64/sn/io/sn2/pcibr/pcibr_dvr.c index 9b2ce991d5f1f1..d5308e67667fc6 100644 --- a/arch/ia64/sn/io/sn2/pcibr/pcibr_dvr.c +++ b/arch/ia64/sn/io/sn2/pcibr/pcibr_dvr.c @@ -4,13 +4,16 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. * - * Copyright (C) 2001-2002 Silicon Graphics, Inc. All rights reserved. + * Copyright (C) 2001-2003 Silicon Graphics, Inc. All rights reserved. */ #include <linux/types.h> #include <linux/slab.h> #include <linux/module.h> +#include <linux/string.h> +#include <linux/interrupt.h> #include <asm/sn/sgi.h> +#include <asm/sn/sn_sal.h> #include <asm/sn/sn_cpuid.h> #include <asm/sn/addrs.h> #include <asm/sn/arch.h> @@ -18,6 +21,7 @@ #include <asm/sn/invent.h> #include <asm/sn/hcl.h> #include <asm/sn/labelcl.h> +#include <asm/sn/klconfig.h> #include <asm/sn/xtalk/xwidget.h> #include <asm/sn/pci/bridge.h> #include <asm/sn/pci/pciio.h> @@ -27,7 +31,6 @@ #include <asm/sn/prio.h> #include <asm/sn/xtalk/xbow.h> #include <asm/sn/ioc3.h> -#include <asm/sn/eeprom.h> #include <asm/sn/io.h> #include <asm/sn/sn_private.h> @@ -76,30 +79,6 @@ int pcibr_debug_slot = -1; /* '-1' for all slots */ int pcibr_devflag = D_MP; -/* - * This is the file operation table for the pcibr driver. - * As each of the functions are implemented, put the - * appropriate function name below. - */ -struct file_operations pcibr_fops = { - owner: THIS_MODULE, - llseek: NULL, - read: NULL, - write: NULL, - readdir: NULL, - poll: NULL, - ioctl: NULL, - mmap: NULL, - open: NULL, - flush: NULL, - release: NULL, - fsync: NULL, - fasync: NULL, - lock: NULL, - readv: NULL, - writev: NULL -}; - /* kbrick widgetnum-to-bus layout */ int p_busnum[MAX_PORT_NUM] = { /* widget# */ 0, 0, 0, 0, 0, 0, 0, 0, /* 0x0 - 0x7 */ @@ -116,17 +95,16 @@ int p_busnum[MAX_PORT_NUM] = { /* widget# */ pcibr_list_p pcibr_list = 0; #endif -extern int hwgraph_vertex_name_get(devfs_handle_t vhdl, char *buf, uint buflen); -extern int hub_device_flags_set(devfs_handle_t widget_dev, hub_widget_flags_t flags); +extern int hwgraph_vertex_name_get(vertex_hdl_t vhdl, char *buf, uint buflen); extern long atoi(register char *p); -extern cnodeid_t nodevertex_to_cnodeid(devfs_handle_t vhdl); -extern char *dev_to_name(devfs_handle_t dev, char *buf, uint buflen); +extern cnodeid_t nodevertex_to_cnodeid(vertex_hdl_t vhdl); +extern char *dev_to_name(vertex_hdl_t dev, char *buf, uint buflen); extern struct map *atemapalloc(uint64_t); extern void atefree(struct map *, size_t, uint64_t); extern void atemapfree(struct map *); -extern pciio_dmamap_t get_free_pciio_dmamap(devfs_handle_t); +extern pciio_dmamap_t get_free_pciio_dmamap(vertex_hdl_t); extern void free_pciio_dmamap(pcibr_dmamap_t); -extern void xwidget_error_register(devfs_handle_t, error_handler_f *, error_handler_arg_t); +extern void xwidget_error_register(vertex_hdl_t, error_handler_f *, error_handler_arg_t); #define ATE_WRITE() ate_write(pcibr_soft, ate_ptr, ate_count, ate) #if PCIBR_FREEZE_TIME @@ -153,9 +131,9 @@ extern void xwidget_error_register(devfs_handle_t, error_handler_f *, error_han extern int do_pcibr_rrb_free_all(pcibr_soft_t, bridge_t *, pciio_slot_t); extern void do_pcibr_rrb_autoalloc(pcibr_soft_t, int, int, int); -extern int pcibr_wrb_flush(devfs_handle_t); -extern int pcibr_rrb_alloc(devfs_handle_t, int *, int *); -extern void pcibr_rrb_flush(devfs_handle_t); +extern int pcibr_wrb_flush(vertex_hdl_t); +extern int pcibr_rrb_alloc(vertex_hdl_t, int *, int *); +extern void pcibr_rrb_flush(vertex_hdl_t); static int pcibr_try_set_device(pcibr_soft_t, pciio_slot_t, unsigned, bridgereg_t); void pcibr_release_device(pcibr_soft_t, pciio_slot_t, bridgereg_t); @@ -166,21 +144,19 @@ extern void pcibr_clearwidint(bridge_t *); extern iopaddr_t pcibr_bus_addr_alloc(pcibr_soft_t, pciio_win_info_t, pciio_space_t, int, int, int); -void pcibr_init(void); -int pcibr_attach(devfs_handle_t); -int pcibr_attach2(devfs_handle_t, bridge_t *, devfs_handle_t, +int pcibr_attach(vertex_hdl_t); +int pcibr_attach2(vertex_hdl_t, bridge_t *, vertex_hdl_t, int, pcibr_soft_t *); -int pcibr_detach(devfs_handle_t); -int pcibr_open(devfs_handle_t *, int, int, cred_t *); -int pcibr_close(devfs_handle_t, int, int, cred_t *); -int pcibr_map(devfs_handle_t, vhandl_t *, off_t, size_t, uint); -int pcibr_unmap(devfs_handle_t, vhandl_t *); -int pcibr_ioctl(devfs_handle_t, int, void *, int, struct cred *, int *); +int pcibr_detach(vertex_hdl_t); +int pcibr_close(vertex_hdl_t, int, int, cred_t *); +int pcibr_map(vertex_hdl_t, vhandl_t *, off_t, size_t, uint); +int pcibr_unmap(vertex_hdl_t, vhandl_t *); +int pcibr_ioctl(vertex_hdl_t, int, void *, int, struct cred *, int *); int pcibr_pcix_rbars_calc(pcibr_soft_t); extern int pcibr_init_ext_ate_ram(bridge_t *); extern int pcibr_ate_alloc(pcibr_soft_t, int); extern void pcibr_ate_free(pcibr_soft_t, int, int); -extern int pcibr_widget_to_bus(devfs_handle_t pcibr_vhdl); +extern int pcibr_widget_to_bus(vertex_hdl_t pcibr_vhdl); extern unsigned ate_freeze(pcibr_dmamap_t pcibr_dmamap, #if PCIBR_FREEZE_TIME @@ -197,45 +173,43 @@ extern void ate_thaw(pcibr_dmamap_t pcibr_dmamap, int ate_index, unsigned *cmd_regs, unsigned s); -pcibr_info_t pcibr_info_get(devfs_handle_t); +pcibr_info_t pcibr_info_get(vertex_hdl_t); -static iopaddr_t pcibr_addr_pci_to_xio(devfs_handle_t, pciio_slot_t, pciio_space_t, iopaddr_t, size_t, unsigned); +static iopaddr_t pcibr_addr_pci_to_xio(vertex_hdl_t, pciio_slot_t, pciio_space_t, iopaddr_t, size_t, unsigned); -pcibr_piomap_t pcibr_piomap_alloc(devfs_handle_t, device_desc_t, pciio_space_t, iopaddr_t, size_t, size_t, unsigned); +pcibr_piomap_t pcibr_piomap_alloc(vertex_hdl_t, device_desc_t, pciio_space_t, iopaddr_t, size_t, size_t, unsigned); void pcibr_piomap_free(pcibr_piomap_t); caddr_t pcibr_piomap_addr(pcibr_piomap_t, iopaddr_t, size_t); void pcibr_piomap_done(pcibr_piomap_t); -caddr_t pcibr_piotrans_addr(devfs_handle_t, device_desc_t, pciio_space_t, iopaddr_t, size_t, unsigned); -iopaddr_t pcibr_piospace_alloc(devfs_handle_t, device_desc_t, pciio_space_t, size_t, size_t); -void pcibr_piospace_free(devfs_handle_t, pciio_space_t, iopaddr_t, size_t); +caddr_t pcibr_piotrans_addr(vertex_hdl_t, device_desc_t, pciio_space_t, iopaddr_t, size_t, unsigned); +iopaddr_t pcibr_piospace_alloc(vertex_hdl_t, device_desc_t, pciio_space_t, size_t, size_t); +void pcibr_piospace_free(vertex_hdl_t, pciio_space_t, iopaddr_t, size_t); static iopaddr_t pcibr_flags_to_d64(unsigned, pcibr_soft_t); extern bridge_ate_t pcibr_flags_to_ate(unsigned); -pcibr_dmamap_t pcibr_dmamap_alloc(devfs_handle_t, device_desc_t, size_t, unsigned); +pcibr_dmamap_t pcibr_dmamap_alloc(vertex_hdl_t, device_desc_t, size_t, unsigned); void pcibr_dmamap_free(pcibr_dmamap_t); extern bridge_ate_p pcibr_ate_addr(pcibr_soft_t, int); static iopaddr_t pcibr_addr_xio_to_pci(pcibr_soft_t, iopaddr_t, size_t); iopaddr_t pcibr_dmamap_addr(pcibr_dmamap_t, paddr_t, size_t); -alenlist_t pcibr_dmamap_list(pcibr_dmamap_t, alenlist_t, unsigned); void pcibr_dmamap_done(pcibr_dmamap_t); -cnodeid_t pcibr_get_dmatrans_node(devfs_handle_t); -iopaddr_t pcibr_dmatrans_addr(devfs_handle_t, device_desc_t, paddr_t, size_t, unsigned); -alenlist_t pcibr_dmatrans_list(devfs_handle_t, device_desc_t, alenlist_t, unsigned); +cnodeid_t pcibr_get_dmatrans_node(vertex_hdl_t); +iopaddr_t pcibr_dmatrans_addr(vertex_hdl_t, device_desc_t, paddr_t, size_t, unsigned); void pcibr_dmamap_drain(pcibr_dmamap_t); -void pcibr_dmaaddr_drain(devfs_handle_t, paddr_t, size_t); -void pcibr_dmalist_drain(devfs_handle_t, alenlist_t); +void pcibr_dmaaddr_drain(vertex_hdl_t, paddr_t, size_t); +void pcibr_dmalist_drain(vertex_hdl_t, alenlist_t); iopaddr_t pcibr_dmamap_pciaddr_get(pcibr_dmamap_t); extern unsigned pcibr_intr_bits(pciio_info_t info, pciio_intr_line_t lines, int nslots); -extern pcibr_intr_t pcibr_intr_alloc(devfs_handle_t, device_desc_t, pciio_intr_line_t, devfs_handle_t); +extern pcibr_intr_t pcibr_intr_alloc(vertex_hdl_t, device_desc_t, pciio_intr_line_t, vertex_hdl_t); extern void pcibr_intr_free(pcibr_intr_t); extern void pcibr_setpciint(xtalk_intr_t); extern int pcibr_intr_connect(pcibr_intr_t, intr_func_t, intr_arg_t); extern void pcibr_intr_disconnect(pcibr_intr_t); -extern devfs_handle_t pcibr_intr_cpu_get(pcibr_intr_t); +extern vertex_hdl_t pcibr_intr_cpu_get(pcibr_intr_t); extern void pcibr_intr_func(intr_arg_t); extern void print_bridge_errcmd(uint32_t, char *); @@ -253,51 +227,76 @@ extern int pcibr_dmard_error(pcibr_soft_t, int, ioerror_mode_t, ioe extern int pcibr_dmawr_error(pcibr_soft_t, int, ioerror_mode_t, ioerror_t *); extern int pcibr_error_handler(error_handler_arg_t, int, ioerror_mode_t, ioerror_t *); extern int pcibr_error_handler_wrapper(error_handler_arg_t, int, ioerror_mode_t, ioerror_t *); -void pcibr_provider_startup(devfs_handle_t); -void pcibr_provider_shutdown(devfs_handle_t); +void pcibr_provider_startup(vertex_hdl_t); +void pcibr_provider_shutdown(vertex_hdl_t); -int pcibr_reset(devfs_handle_t); -pciio_endian_t pcibr_endian_set(devfs_handle_t, pciio_endian_t, pciio_endian_t); +int pcibr_reset(vertex_hdl_t); +pciio_endian_t pcibr_endian_set(vertex_hdl_t, pciio_endian_t, pciio_endian_t); int pcibr_priority_bits_set(pcibr_soft_t, pciio_slot_t, pciio_priority_t); -pciio_priority_t pcibr_priority_set(devfs_handle_t, pciio_priority_t); -int pcibr_device_flags_set(devfs_handle_t, pcibr_device_flags_t); - -extern cfg_p pcibr_config_addr(devfs_handle_t, unsigned); -extern uint64_t pcibr_config_get(devfs_handle_t, unsigned, unsigned); -extern void pcibr_config_set(devfs_handle_t, unsigned, unsigned, uint64_t); - -extern pcibr_hints_t pcibr_hints_get(devfs_handle_t, int); -extern void pcibr_hints_fix_rrbs(devfs_handle_t); -extern void pcibr_hints_dualslot(devfs_handle_t, pciio_slot_t, pciio_slot_t); -extern void pcibr_hints_intr_bits(devfs_handle_t, pcibr_intr_bits_f *); -extern void pcibr_set_rrb_callback(devfs_handle_t, rrb_alloc_funct_t); -extern void pcibr_hints_handsoff(devfs_handle_t); -extern void pcibr_hints_subdevs(devfs_handle_t, pciio_slot_t, uint64_t); - -extern int pcibr_slot_reset(devfs_handle_t,pciio_slot_t); -extern int pcibr_slot_info_init(devfs_handle_t,pciio_slot_t); -extern int pcibr_slot_info_free(devfs_handle_t,pciio_slot_t); +pciio_priority_t pcibr_priority_set(vertex_hdl_t, pciio_priority_t); +int pcibr_device_flags_set(vertex_hdl_t, pcibr_device_flags_t); + +extern cfg_p pcibr_config_addr(vertex_hdl_t, unsigned); +extern uint64_t pcibr_config_get(vertex_hdl_t, unsigned, unsigned); +extern void pcibr_config_set(vertex_hdl_t, unsigned, unsigned, uint64_t); + +extern pcibr_hints_t pcibr_hints_get(vertex_hdl_t, int); +extern void pcibr_hints_fix_rrbs(vertex_hdl_t); +extern void pcibr_hints_dualslot(vertex_hdl_t, pciio_slot_t, pciio_slot_t); +extern void pcibr_hints_intr_bits(vertex_hdl_t, pcibr_intr_bits_f *); +extern void pcibr_set_rrb_callback(vertex_hdl_t, rrb_alloc_funct_t); +extern void pcibr_hints_handsoff(vertex_hdl_t); +extern void pcibr_hints_subdevs(vertex_hdl_t, pciio_slot_t, uint64_t); + +extern int pcibr_slot_info_init(vertex_hdl_t,pciio_slot_t); +extern int pcibr_slot_info_free(vertex_hdl_t,pciio_slot_t); extern int pcibr_slot_info_return(pcibr_soft_t, pciio_slot_t, pcibr_slot_info_resp_t); extern void pcibr_slot_func_info_return(pcibr_info_h, int, pcibr_slot_func_info_resp_t); -extern int pcibr_slot_addr_space_init(devfs_handle_t,pciio_slot_t); +extern int pcibr_slot_addr_space_init(vertex_hdl_t,pciio_slot_t); extern int pcibr_slot_pcix_rbar_init(pcibr_soft_t, pciio_slot_t); -extern int pcibr_slot_device_init(devfs_handle_t, pciio_slot_t); -extern int pcibr_slot_guest_info_init(devfs_handle_t,pciio_slot_t); -extern int pcibr_slot_call_device_attach(devfs_handle_t, +extern int pcibr_slot_device_init(vertex_hdl_t, pciio_slot_t); +extern int pcibr_slot_guest_info_init(vertex_hdl_t,pciio_slot_t); +extern int pcibr_slot_call_device_attach(vertex_hdl_t, pciio_slot_t, int); -extern int pcibr_slot_call_device_detach(devfs_handle_t, +extern int pcibr_slot_call_device_detach(vertex_hdl_t, pciio_slot_t, int); -extern int pcibr_slot_attach(devfs_handle_t, pciio_slot_t, int, +extern int pcibr_slot_attach(vertex_hdl_t, pciio_slot_t, int, char *, int *); -extern int pcibr_slot_detach(devfs_handle_t, pciio_slot_t, int, +extern int pcibr_slot_detach(vertex_hdl_t, pciio_slot_t, int, char *, int *); -extern int pcibr_is_slot_sys_critical(devfs_handle_t, pciio_slot_t); -extern int pcibr_slot_initial_rrb_alloc(devfs_handle_t, pciio_slot_t); -extern int pcibr_initial_rrb(devfs_handle_t, pciio_slot_t, pciio_slot_t); +extern int pcibr_slot_initial_rrb_alloc(vertex_hdl_t, pciio_slot_t); +extern int pcibr_initial_rrb(vertex_hdl_t, pciio_slot_t, pciio_slot_t); +/* + * This is the file operation table for the pcibr driver. + * As each of the functions are implemented, put the + * appropriate function name below. + */ +static int pcibr_mmap(struct file * file, struct vm_area_struct * vma); +static int pcibr_open(struct inode *, struct file *); +struct file_operations pcibr_fops = { + owner: THIS_MODULE, + llseek: NULL, + read: NULL, + write: NULL, + readdir: NULL, + poll: NULL, + ioctl: NULL, + mmap: pcibr_mmap, + open: pcibr_open, + flush: NULL, + release: NULL, + fsync: NULL, + fasync: NULL, + lock: NULL, + readv: NULL, + writev: NULL, + sendpage: NULL, + get_unmapped_area: NULL +}; /* ===================================================================== * Device(x) register management @@ -624,30 +623,6 @@ pcibr_device_write_gather_flush(pcibr_soft_t pcibr_soft, /* - * pcibr_init: called once during system startup or - * when a loadable driver is loaded. - * - * The driver_register function should normally - * be in _reg, not _init. But the pcibr driver is - * required by devinit before the _reg routines - * are called, so this is an exception. - */ -void -pcibr_init(void) -{ - PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_INIT, NULL, "pcibr_init()\n")); - - xwidget_driver_register(XBRIDGE_WIDGET_PART_NUM, - XBRIDGE_WIDGET_MFGR_NUM, - "pcibr_", - 0); - xwidget_driver_register(BRIDGE_WIDGET_PART_NUM, - BRIDGE_WIDGET_MFGR_NUM, - "pcibr_", - 0); -} - -/* * open/close mmap/munmap interface would be used by processes * that plan to map the PCI bridge, and muck around with the * registers. This is dangerous to do, and will be allowed @@ -659,25 +634,50 @@ pcibr_init(void) */ /* ARGSUSED */ int -pcibr_open(devfs_handle_t *devp, int oflag, int otyp, cred_t *credp) +pcibr_open(struct inode *x, struct file *y) { return 0; } /*ARGSUSED */ int -pcibr_close(devfs_handle_t dev, int oflag, int otyp, cred_t *crp) +pcibr_close(vertex_hdl_t dev, int oflag, int otyp, cred_t *crp) { return 0; } +static int +pcibr_mmap(struct file * file, struct vm_area_struct * vma) +{ + vertex_hdl_t pcibr_vhdl; + pcibr_soft_t pcibr_soft; + bridge_t *bridge; + unsigned long phys_addr; + int error = 0; + +#ifdef CONFIG_HWGFS_FS + pcibr_vhdl = (vertex_hdl_t) file->f_dentry->d_fsdata; +#else + pcibr_vhdl = (vertex_hdl_t) file->private_data; +#endif + pcibr_soft = pcibr_soft_get(pcibr_vhdl); + bridge = pcibr_soft->bs_base; + phys_addr = (unsigned long)bridge & ~0xc000000000000000; /* Mask out the Uncache bits */ + vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); + vma->vm_flags |= VM_RESERVED | VM_IO; + error = io_remap_page_range(vma, phys_addr, vma->vm_start, + vma->vm_end - vma->vm_start, + vma->vm_page_prot); + return(error); +} + /*ARGSUSED */ int -pcibr_map(devfs_handle_t dev, vhandl_t *vt, off_t off, size_t len, uint prot) +pcibr_map(vertex_hdl_t dev, vhandl_t *vt, off_t off, size_t len, uint prot) { int error; - devfs_handle_t vhdl = dev_to_vhdl(dev); - devfs_handle_t pcibr_vhdl = hwgraph_connectpt_get(vhdl); + vertex_hdl_t vhdl = dev_to_vhdl(dev); + vertex_hdl_t pcibr_vhdl = hwgraph_connectpt_get(vhdl); pcibr_soft_t pcibr_soft = pcibr_soft_get(pcibr_vhdl); bridge_t *bridge = pcibr_soft->bs_base; @@ -721,9 +721,9 @@ pcibr_map(devfs_handle_t dev, vhandl_t *vt, off_t off, size_t len, uint prot) /*ARGSUSED */ int -pcibr_unmap(devfs_handle_t dev, vhandl_t *vt) +pcibr_unmap(vertex_hdl_t dev, vhandl_t *vt) { - devfs_handle_t pcibr_vhdl = hwgraph_connectpt_get((devfs_handle_t) dev); + vertex_hdl_t pcibr_vhdl = hwgraph_connectpt_get((vertex_hdl_t) dev); pcibr_soft_t pcibr_soft = pcibr_soft_get(pcibr_vhdl); bridge_t *bridge = pcibr_soft->bs_base; @@ -785,10 +785,10 @@ pcibr_unmap(devfs_handle_t dev, vhandl_t *vt) * be sufficient. */ pciio_slot_t -pcibr_device_slot_get(devfs_handle_t dev_vhdl) +pcibr_device_slot_get(vertex_hdl_t dev_vhdl) { char devname[MAXDEVNAME]; - devfs_handle_t tdev; + vertex_hdl_t tdev; pciio_info_t pciio_info; pciio_slot_t slot = PCIIO_SLOT_NONE; @@ -814,7 +814,7 @@ pcibr_device_slot_get(devfs_handle_t dev_vhdl) /*ARGSUSED */ int -pcibr_ioctl(devfs_handle_t dev, +pcibr_ioctl(vertex_hdl_t dev, int cmd, void *arg, int flag, @@ -825,7 +825,7 @@ pcibr_ioctl(devfs_handle_t dev, } pcibr_info_t -pcibr_info_get(devfs_handle_t vhdl) +pcibr_info_get(vertex_hdl_t vhdl) { return (pcibr_info_t) pciio_info_get(vhdl); } @@ -902,10 +902,10 @@ pcibr_device_info_new( * This is usually used at the time of shutting down of the PCI card. */ int -pcibr_device_unregister(devfs_handle_t pconn_vhdl) +pcibr_device_unregister(vertex_hdl_t pconn_vhdl) { pciio_info_t pciio_info; - devfs_handle_t pcibr_vhdl; + vertex_hdl_t pcibr_vhdl; pciio_slot_t slot; pcibr_soft_t pcibr_soft; bridge_t *bridge; @@ -982,12 +982,12 @@ pcibr_device_unregister(devfs_handle_t pconn_vhdl) * slot's device status to be set. */ void -pcibr_driver_reg_callback(devfs_handle_t pconn_vhdl, +pcibr_driver_reg_callback(vertex_hdl_t pconn_vhdl, int key1, int key2, int error) { pciio_info_t pciio_info; pcibr_info_t pcibr_info; - devfs_handle_t pcibr_vhdl; + vertex_hdl_t pcibr_vhdl; pciio_slot_t slot; pcibr_soft_t pcibr_soft; @@ -1033,12 +1033,12 @@ pcibr_driver_reg_callback(devfs_handle_t pconn_vhdl, * slot's device status to be set. */ void -pcibr_driver_unreg_callback(devfs_handle_t pconn_vhdl, +pcibr_driver_unreg_callback(vertex_hdl_t pconn_vhdl, int key1, int key2, int error) { pciio_info_t pciio_info; pcibr_info_t pcibr_info; - devfs_handle_t pcibr_vhdl; + vertex_hdl_t pcibr_vhdl; pciio_slot_t slot; pcibr_soft_t pcibr_soft; @@ -1084,14 +1084,14 @@ pcibr_driver_unreg_callback(devfs_handle_t pconn_vhdl, * depends on hwgraph separator == '/' */ int -pcibr_bus_cnvlink(devfs_handle_t f_c) +pcibr_bus_cnvlink(vertex_hdl_t f_c) { char dst[MAXDEVNAME]; char *dp = dst; char *cp, *xp; int widgetnum; char pcibus[8]; - devfs_handle_t nvtx, svtx; + vertex_hdl_t nvtx, svtx; int rv; PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_ATTACH, f_c, "pcibr_bus_cnvlink\n")); @@ -1145,11 +1145,11 @@ pcibr_bus_cnvlink(devfs_handle_t f_c) */ /*ARGSUSED */ int -pcibr_attach(devfs_handle_t xconn_vhdl) +pcibr_attach(vertex_hdl_t xconn_vhdl) { /* REFERENCED */ graph_error_t rc; - devfs_handle_t pcibr_vhdl; + vertex_hdl_t pcibr_vhdl; bridge_t *bridge; PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_ATTACH, xconn_vhdl, "pcibr_attach\n")); @@ -1180,11 +1180,11 @@ pcibr_attach(devfs_handle_t xconn_vhdl) /*ARGSUSED */ int -pcibr_attach2(devfs_handle_t xconn_vhdl, bridge_t *bridge, - devfs_handle_t pcibr_vhdl, int busnum, pcibr_soft_t *ret_softp) +pcibr_attach2(vertex_hdl_t xconn_vhdl, bridge_t *bridge, + vertex_hdl_t pcibr_vhdl, int busnum, pcibr_soft_t *ret_softp) { /* REFERENCED */ - devfs_handle_t ctlr_vhdl; + vertex_hdl_t ctlr_vhdl; bridgereg_t id; int rev; pcibr_soft_t pcibr_soft; @@ -1193,7 +1193,7 @@ pcibr_attach2(devfs_handle_t xconn_vhdl, bridge_t *bridge, xtalk_intr_t xtalk_intr; int slot; int ibit; - devfs_handle_t noslot_conn; + vertex_hdl_t noslot_conn; char devnm[MAXDEVNAME], *s; pcibr_hints_t pcibr_hints; uint64_t int_enable; @@ -1209,23 +1209,15 @@ pcibr_attach2(devfs_handle_t xconn_vhdl, bridge_t *bridge, nasid_t nasid; int iobrick_type_get_nasid(nasid_t nasid); int iobrick_module_get_nasid(nasid_t nasid); - extern unsigned char Is_pic_on_this_nasid[512]; - - - async_attach_t aa = NULL; PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_ATTACH, pcibr_vhdl, "pcibr_attach2: bridge=0x%p, busnum=%d\n", bridge, busnum)); - aa = async_attach_get_info(xconn_vhdl); - ctlr_vhdl = NULL; - ctlr_vhdl = hwgraph_register(pcibr_vhdl, EDGE_LBL_CONTROLLER, - 0, DEVFS_FL_AUTO_DEVNUM, - 0, 0, - S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP, 0, 0, - &pcibr_fops, NULL); - + ctlr_vhdl = hwgraph_register(pcibr_vhdl, EDGE_LBL_CONTROLLER, 0, + DEVFS_FL_AUTO_DEVNUM, 0, 0, + S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP, 0, 0, + (struct file_operations *)&pcibr_fops, (void *)pcibr_vhdl); ASSERT(ctlr_vhdl != NULL); /* @@ -1261,13 +1253,7 @@ pcibr_attach2(devfs_handle_t xconn_vhdl, bridge_t *bridge, pcibr_soft->bs_min_slot = 0; /* lowest possible slot# */ pcibr_soft->bs_max_slot = 7; /* highest possible slot# */ pcibr_soft->bs_busnum = busnum; - if (is_xbridge(bridge)) { - pcibr_soft->bs_bridge_type = PCIBR_BRIDGETYPE_XBRIDGE; - } else if (is_pic(bridge)) { - pcibr_soft->bs_bridge_type = PCIBR_BRIDGETYPE_PIC; - } else { - pcibr_soft->bs_bridge_type = PCIBR_BRIDGETYPE_BRIDGE; - } + pcibr_soft->bs_bridge_type = PCIBR_BRIDGETYPE_PIC; switch(pcibr_soft->bs_bridge_type) { case PCIBR_BRIDGETYPE_BRIDGE: pcibr_soft->bs_int_ate_size = BRIDGE_INTERNAL_ATES; @@ -1367,10 +1353,6 @@ pcibr_attach2(devfs_handle_t xconn_vhdl, bridge_t *bridge, nasid = NASID_GET(bridge); - /* set whether it is a PIC or not */ - Is_pic_on_this_nasid[nasid] = (IS_PIC_SOFT(pcibr_soft)) ? 1 : 0; - - if ((pcibr_soft->bs_bricktype = iobrick_type_get_nasid(nasid)) < 0) printk(KERN_WARNING "0x%p: Unknown bricktype : 0x%x\n", (void *)xconn_vhdl, (unsigned int)pcibr_soft->bs_bricktype); @@ -1380,11 +1362,27 @@ pcibr_attach2(devfs_handle_t xconn_vhdl, bridge_t *bridge, if (pcibr_soft->bs_bricktype > 0) { switch (pcibr_soft->bs_bricktype) { case MODULE_PXBRICK: + case MODULE_IXBRICK: pcibr_soft->bs_first_slot = 0; pcibr_soft->bs_last_slot = 1; pcibr_soft->bs_last_reset = 1; + + /* If Bus 1 has IO9 then there are 4 devices in that bus. Note + * we figure this out from klconfig since the kernel has yet to + * probe + */ + if (pcibr_widget_to_bus(pcibr_vhdl) == 1) { + lboard_t *brd = (lboard_t *)KL_CONFIG_INFO(nasid); + + while (brd) { + if (brd->brd_flags & LOCAL_MASTER_IO6) { + pcibr_soft->bs_last_slot = 3; + pcibr_soft->bs_last_reset = 3; + } + brd = KLCF_NEXT(brd); + } + } break; - case MODULE_PEBRICK: case MODULE_PBRICK: pcibr_soft->bs_first_slot = 1; pcibr_soft->bs_last_slot = 2; @@ -1527,7 +1525,7 @@ pcibr_attach2(devfs_handle_t xconn_vhdl, bridge_t *bridge, /* enable parity checking on PICs internal RAM */ pic_ctrl_reg |= PIC_CTRL_PAR_EN_RESP; pic_ctrl_reg |= PIC_CTRL_PAR_EN_ATE; - /* PIC BRINGUP WAR (PV# 862253): don't enable write request + /* PIC BRINGUP WAR (PV# 862253): dont enable write request * parity checking. */ if (!PCIBR_WAR_ENABLED(PV862253, pcibr_soft)) { @@ -1559,11 +1557,6 @@ pcibr_attach2(devfs_handle_t xconn_vhdl, bridge_t *bridge, int entry; cnodeid_t cnodeid; nasid_t nasid; -#ifdef PIC_LATER - char *node_val; - devfs_handle_t node_vhdl; - char vname[MAXDEVNAME]; -#endif /* Set the Bridge's 32-bit PCI to XTalk * Direct Map register to the most useful @@ -1582,30 +1575,6 @@ pcibr_attach2(devfs_handle_t xconn_vhdl, bridge_t *bridge, */ cnodeid = 0; /* default node id */ - /* - * Determine the base address node id to be used for all 32-bit - * Direct Mapping I/O. The default is node 0, but this can be changed - * via a DEVICE_ADMIN directive and the PCIBUS_DMATRANS_NODE - * attribute in the irix.sm config file. A device driver can obtain - * this node value via a call to pcibr_get_dmatrans_node(). - */ -#ifdef PIC_LATER -// This probably needs to be addressed - pfg - node_val = device_admin_info_get(pcibr_vhdl, ADMIN_LBL_DMATRANS_NODE); - if (node_val != NULL) { - node_vhdl = hwgraph_path_to_vertex(node_val); - if (node_vhdl != GRAPH_VERTEX_NONE) { - cnodeid = nodevertex_to_cnodeid(node_vhdl); - } - if ((node_vhdl == GRAPH_VERTEX_NONE) || (cnodeid == CNODEID_NONE)) { - cnodeid = 0; - vertex_to_name(pcibr_vhdl, vname, sizeof(vname)); - printk(KERN_WARNING "Invalid hwgraph node path specified:\n" - " DEVICE_ADMIN: %s %s=%s\n", - vname, ADMIN_LBL_DMATRANS_NODE, node_val); - } - } -#endif /* PIC_LATER */ nasid = COMPACT_TO_NASID_NODEID(cnodeid); paddr = NODE_OFFSET(nasid) + 0; @@ -1763,6 +1732,13 @@ pcibr_attach2(devfs_handle_t xconn_vhdl, bridge_t *bridge, */ xtalk_intr = xtalk_intr_alloc(xconn_vhdl, (device_desc_t)0, pcibr_vhdl); + { + int irq = ((hub_intr_t)xtalk_intr)->i_bit; + int cpu = ((hub_intr_t)xtalk_intr)->i_cpuid; + + intr_unreserve_level(cpu, irq); + ((hub_intr_t)xtalk_intr)->i_bit = SGI_PCIBR_ERROR; + } ASSERT(xtalk_intr != NULL); pcibr_soft->bsi_err_intr = xtalk_intr; @@ -1778,12 +1754,8 @@ pcibr_attach2(devfs_handle_t xconn_vhdl, bridge_t *bridge, xtalk_intr_connect(xtalk_intr, (intr_func_t) pcibr_error_intr_handler, (intr_arg_t) pcibr_soft, (xtalk_intr_setfunc_t)pcibr_setwidint, (void *)bridge); -#ifdef BUS_INT_WAR_NOT_YET - request_irq(CPU_VECTOR_TO_IRQ(((hub_intr_t)xtalk_intr)->i_cpuid, - ((hub_intr_t)xtalk_intr)->i_bit), - (intr_func_t)pcibr_error_intr_handler, 0, "PCIBR error", + request_irq(SGI_PCIBR_ERROR, (void *)pcibr_error_intr_handler, SA_SHIRQ, "PCIBR error", (intr_arg_t) pcibr_soft); -#endif PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_INTR_ALLOC, pcibr_vhdl, "pcibr_setwidint: b_wid_int_upper=0x%x, b_wid_int_lower=0x%x\n", @@ -1801,18 +1773,16 @@ pcibr_attach2(devfs_handle_t xconn_vhdl, bridge_t *bridge, if (IS_PIC_SOFT(pcibr_soft)) { int_enable_64 = bridge->p_int_enable_64 | BRIDGE_ISR_ERRORS; int_enable = (uint64_t)int_enable_64; +#ifdef PFG_TEST + int_enable = (uint64_t)0x7ffffeff7ffffeff; +#endif } else { int_enable_32 = bridge->b_int_enable | (BRIDGE_ISR_ERRORS & 0xffffffff); int_enable = ((uint64_t)int_enable_32 & 0xffffffff); - } -#ifdef BUS_INT_WAR_NOT_YET - { - extern void sn_add_polled_interrupt(int irq, int interval); - - sn_add_polled_interrupt(CPU_VECTOR_TO_IRQ(((hub_intr_t)xtalk_intr)->i_cpuid, - ((hub_intr_t)xtalk_intr)->i_bit), 20000); - } +#ifdef PFG_TEST + int_enable = (uint64_t)0x7ffffeff; #endif + } #if BRIDGE_ERROR_INTR_WAR @@ -1849,24 +1819,6 @@ pcibr_attach2(devfs_handle_t xconn_vhdl, bridge_t *bridge, } #endif -#ifdef BRIDGE_B_DATACORR_WAR - - /* WAR panic for Rev B silent data corruption. - * PIOERR turned off here because there is a problem - * with not re-arming it in pcibr_error_intr_handler. - * We don't get LLP error interrupts if we don't - * re-arm PIOERR interrupts! Just disable them here - */ - - if (pcibr_soft->bs_rev_num == BRIDGE_PART_REV_B) { - int_enable |= BRIDGE_IMR_LLP_REC_CBERR; - int_enable &= ~BRIDGE_ISR_PCIBUS_PIOERR; - - PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_ATTACH, pcibr_vhdl, - "Turning on LLP_REC_CBERR for Rev B Bridge.\n")); - } -#endif - /* PIC BRINGUP WAR (PV# 856864 & 856865): allow the tnums that are * locked out to be freed up sooner (by timing out) so that the * read tnums are never completely used up. @@ -1918,16 +1870,12 @@ pcibr_attach2(devfs_handle_t xconn_vhdl, bridge_t *bridge, if (pcibr_soft->bs_rev_num < BRIDGE_PART_REV_B) pcibr_soft->bs_dma_flags |= PCIBR_NOPREFETCH; else if (pcibr_soft->bs_rev_num < - (BRIDGE_WIDGET_PART_NUM << 4 | pcibr_prefetch_enable_rev)) + (BRIDGE_WIDGET_PART_NUM << 4)) pcibr_soft->bs_dma_flags |= PCIIO_NOPREFETCH; - /* WRITE_GATHER: - * Disabled up to but not including the - * rev number in pcibr_wg_enable_rev. There - * is no "WAR range" as with prefetch. - */ + /* WRITE_GATHER: Disabled */ if (pcibr_soft->bs_rev_num < - (BRIDGE_WIDGET_PART_NUM << 4 | pcibr_wg_enable_rev)) + (BRIDGE_WIDGET_PART_NUM << 4)) pcibr_soft->bs_dma_flags |= PCIBR_NOWRITE_GATHER; /* PIC only supports 64-bit direct mapping in PCI-X mode. Since @@ -2064,7 +2012,23 @@ pcibr_attach2(devfs_handle_t xconn_vhdl, bridge_t *bridge, */ if (pcibr_soft->bs_bricktype > 0) { switch (pcibr_soft->bs_bricktype) { + case MODULE_PBRICK: + do_pcibr_rrb_autoalloc(pcibr_soft, 1, VCHAN0, 8); + do_pcibr_rrb_autoalloc(pcibr_soft, 2, VCHAN0, 8); + break; + case MODULE_IBRICK: + /* port 0xe on the Ibrick only has slots 1 and 2 */ + if (pcibr_soft->bs_xid == 0xe) { + do_pcibr_rrb_autoalloc(pcibr_soft, 1, VCHAN0, 8); + do_pcibr_rrb_autoalloc(pcibr_soft, 2, VCHAN0, 8); + } + else { + /* allocate one RRB for the serial port */ + do_pcibr_rrb_autoalloc(pcibr_soft, 0, VCHAN0, 1); + } + break; case MODULE_PXBRICK: + case MODULE_IXBRICK: /* * If the IO9 is in the PXBrick (bus1, slot1) allocate * RRBs to all the devices @@ -2080,23 +2044,6 @@ pcibr_attach2(devfs_handle_t xconn_vhdl, bridge_t *bridge, do_pcibr_rrb_autoalloc(pcibr_soft, 0, VCHAN0, 8); do_pcibr_rrb_autoalloc(pcibr_soft, 1, VCHAN0, 8); } - - break; - case MODULE_PEBRICK: - case MODULE_PBRICK: - do_pcibr_rrb_autoalloc(pcibr_soft, 1, VCHAN0, 8); - do_pcibr_rrb_autoalloc(pcibr_soft, 2, VCHAN0, 8); - break; - case MODULE_IBRICK: - /* port 0xe on the Ibrick only has slots 1 and 2 */ - if (pcibr_soft->bs_xid == 0xe) { - do_pcibr_rrb_autoalloc(pcibr_soft, 1, VCHAN0, 8); - do_pcibr_rrb_autoalloc(pcibr_soft, 2, VCHAN0, 8); - } - else { - /* allocate one RRB for the serial port */ - do_pcibr_rrb_autoalloc(pcibr_soft, 0, VCHAN0, 1); - } break; } /* switch */ } @@ -2113,78 +2060,8 @@ pcibr_attach2(devfs_handle_t xconn_vhdl, bridge_t *bridge, /* Call the device attach */ (void)pcibr_slot_call_device_attach(pcibr_vhdl, slot, 0); -#ifdef PIC_LATER -#if (defined(USS302_TIMEOUT_WAR)) - /* - * If this bridge holds a Lucent USS-302 or USS-312 pci/usb controller, - * increase the Bridge PCI retry backoff interval. This part seems - * to go away for long periods of time if a DAC appears on the bus during - * a read command that is being retried. - */ - -{ - ii_ixtt_u_t ixtt; - - for (slot = pcibr_soft->bs_min_slot; - slot < PCIBR_NUM_SLOTS(pcibr_soft); ++slot) { - if (pcibr_soft->bs_slot[slot].bss_vendor_id == - LUCENT_USBHC_VENDOR_ID_NUM && - (pcibr_soft->bs_slot[slot].bss_device_id == - LUCENT_USBHC302_DEVICE_ID_NUM || - pcibr_soft->bs_slot[slot].bss_device_id == - LUCENT_USBHC312_DEVICE_ID_NUM)) { - printk(KERN_NOTICE - "pcibr_attach: %x Bus holds a usb part - setting" - "bridge PCI_RETRY_HLD to %d\n", - pcibr_vhdl, USS302_BRIDGE_TIMEOUT_HLD); - - bridge->b_bus_timeout &= ~BRIDGE_BUS_PCI_RETRY_HLD_MASK; - bridge->b_bus_timeout |= - BRIDGE_BUS_PCI_RETRY_HLD(USS302_BRIDGE_TIMEOUT_HLD); - - /* - * Have to consider the read response timer in the hub II as well - */ - - hubii_ixtt_get(xconn_vhdl, &ixtt); - - /* - * bump rrsp_ps to allow at least 1ms for read - * responses from this widget - */ - - ixtt.ii_ixtt_fld_s.i_rrsp_ps = 20000; - hubii_ixtt_set(xconn_vhdl, &ixtt); - - /* - * print the current setting - */ - - hubii_ixtt_get(xconn_vhdl, &ixtt); - printk( "Setting hub ixtt.rrsp_ps field to 0x%x\n", - ixtt.ii_ixtt_fld_s.i_rrsp_ps); - - break; /* only need to do it once */ - } - } -} -#endif /* (defined(USS302_TIMEOUT_WAR)) */ -#else - FIXME("pcibr_attach: Call do_pcibr_rrb_autoalloc nicinfo\n"); -#endif /* PIC_LATER */ - - if (aa) - async_attach_add_info(noslot_conn, aa); - pciio_device_attach(noslot_conn, (int)0); - /* - * Tear down pointer to async attach info -- async threads for - * bridge's descendants may be running but the bridge's work is done. - */ - if (aa) - async_attach_del_info(xconn_vhdl); - return 0; } @@ -2195,10 +2072,10 @@ pcibr_attach2(devfs_handle_t xconn_vhdl, bridge_t *bridge, */ int -pcibr_detach(devfs_handle_t xconn) +pcibr_detach(vertex_hdl_t xconn) { pciio_slot_t slot; - devfs_handle_t pcibr_vhdl; + vertex_hdl_t pcibr_vhdl; pcibr_soft_t pcibr_soft; bridge_t *bridge; unsigned s; @@ -2265,9 +2142,9 @@ pcibr_detach(devfs_handle_t xconn) } int -pcibr_asic_rev(devfs_handle_t pconn_vhdl) +pcibr_asic_rev(vertex_hdl_t pconn_vhdl) { - devfs_handle_t pcibr_vhdl; + vertex_hdl_t pcibr_vhdl; int tmp_vhdl; arbitrary_info_t ainfo; @@ -2294,7 +2171,7 @@ pcibr_asic_rev(devfs_handle_t pconn_vhdl) } int -pcibr_write_gather_flush(devfs_handle_t pconn_vhdl) +pcibr_write_gather_flush(vertex_hdl_t pconn_vhdl) { pciio_info_t pciio_info = pciio_info_get(pconn_vhdl); pcibr_soft_t pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info); @@ -2309,7 +2186,7 @@ pcibr_write_gather_flush(devfs_handle_t pconn_vhdl) */ static iopaddr_t -pcibr_addr_pci_to_xio(devfs_handle_t pconn_vhdl, +pcibr_addr_pci_to_xio(vertex_hdl_t pconn_vhdl, pciio_slot_t slot, pciio_space_t space, iopaddr_t pci_addr, @@ -2323,6 +2200,8 @@ pcibr_addr_pci_to_xio(devfs_handle_t pconn_vhdl, unsigned bar; /* which BASE reg on device is decoding */ iopaddr_t xio_addr = XIO_NOWHERE; + iopaddr_t base; /* base of devio(x) mapped area on PCI */ + iopaddr_t limit; /* base of devio(x) mapped area on PCI */ pciio_space_t wspace; /* which space device is decoding */ iopaddr_t wbase; /* base of device decode on PCI */ @@ -2533,8 +2412,6 @@ pcibr_addr_pci_to_xio(devfs_handle_t pconn_vhdl, PCIBR_DEBUG((PCIBR_DEBUG_DEVREG, pconn_vhdl, "pcibr_addr_pci_to_xio: Device(%d): %x\n", win, devreg, device_bits)); -#else - printk("pcibr_addr_pci_to_xio: Device(%d): %x\n", win, devreg); #endif } pcibr_soft->bs_slot[win].bss_devio.bssd_space = space; @@ -2620,18 +2497,46 @@ pcibr_addr_pci_to_xio(devfs_handle_t pconn_vhdl, */ case PCIIO_SPACE_MEM: /* "mem space" */ case PCIIO_SPACE_MEM32: /* "mem, use 32-bit-wide bus" */ - if ((pci_addr + BRIDGE_PCI_MEM32_BASE + req_size - 1) <= - BRIDGE_PCI_MEM32_LIMIT) - xio_addr = pci_addr + BRIDGE_PCI_MEM32_BASE; + if (IS_PIC_BUSNUM_SOFT(pcibr_soft, 0)) { /* PIC bus 0 */ + base = PICBRIDGE0_PCI_MEM32_BASE; + limit = PICBRIDGE0_PCI_MEM32_LIMIT; + } else if (IS_PIC_BUSNUM_SOFT(pcibr_soft, 1)) { /* PIC bus 1 */ + base = PICBRIDGE1_PCI_MEM32_BASE; + limit = PICBRIDGE1_PCI_MEM32_LIMIT; + } else { /* Bridge/Xbridge */ + base = BRIDGE_PCI_MEM32_BASE; + limit = BRIDGE_PCI_MEM32_LIMIT; + } + + if ((pci_addr + base + req_size - 1) <= limit) + xio_addr = pci_addr + base; break; case PCIIO_SPACE_MEM64: /* "mem, use 64-bit-wide bus" */ - if ((pci_addr + BRIDGE_PCI_MEM64_BASE + req_size - 1) <= - BRIDGE_PCI_MEM64_LIMIT) - xio_addr = pci_addr + BRIDGE_PCI_MEM64_BASE; + if (IS_PIC_BUSNUM_SOFT(pcibr_soft, 0)) { /* PIC bus 0 */ + base = PICBRIDGE0_PCI_MEM64_BASE; + limit = PICBRIDGE0_PCI_MEM64_LIMIT; + } else if (IS_PIC_BUSNUM_SOFT(pcibr_soft, 1)) { /* PIC bus 1 */ + base = PICBRIDGE1_PCI_MEM64_BASE; + limit = PICBRIDGE1_PCI_MEM64_LIMIT; + } else { /* Bridge/Xbridge */ + base = BRIDGE_PCI_MEM64_BASE; + limit = BRIDGE_PCI_MEM64_LIMIT; + } + + if ((pci_addr + base + req_size - 1) <= limit) + xio_addr = pci_addr + base; break; case PCIIO_SPACE_IO: /* "i/o space" */ + /* + * PIC bridges do not support big-window aliases into PCI I/O space + */ + if (IS_PIC_SOFT(pcibr_soft)) { + xio_addr = XIO_NOWHERE; + break; + } + /* Bridge Hardware Bug WAR #482741: * The 4G area that maps directly from * XIO space to PCI I/O space is busted @@ -2725,7 +2630,7 @@ pcibr_addr_pci_to_xio(devfs_handle_t pconn_vhdl, /*ARGSUSED6 */ pcibr_piomap_t -pcibr_piomap_alloc(devfs_handle_t pconn_vhdl, +pcibr_piomap_alloc(vertex_hdl_t pconn_vhdl, device_desc_t dev_desc, pciio_space_t space, iopaddr_t pci_addr, @@ -2737,7 +2642,7 @@ pcibr_piomap_alloc(devfs_handle_t pconn_vhdl, pciio_info_t pciio_info = &pcibr_info->f_c; pciio_slot_t pciio_slot = PCIBR_INFO_SLOT_GET_INT(pciio_info); pcibr_soft_t pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info); - devfs_handle_t xconn_vhdl = pcibr_soft->bs_conn; + vertex_hdl_t xconn_vhdl = pcibr_soft->bs_conn; pcibr_piomap_t *mapptr; pcibr_piomap_t maplist; @@ -2867,7 +2772,7 @@ pcibr_piomap_done(pcibr_piomap_t pcibr_piomap) /*ARGSUSED */ caddr_t -pcibr_piotrans_addr(devfs_handle_t pconn_vhdl, +pcibr_piotrans_addr(vertex_hdl_t pconn_vhdl, device_desc_t dev_desc, pciio_space_t space, iopaddr_t pci_addr, @@ -2877,7 +2782,7 @@ pcibr_piotrans_addr(devfs_handle_t pconn_vhdl, pciio_info_t pciio_info = pciio_info_get(pconn_vhdl); pciio_slot_t pciio_slot = PCIBR_INFO_SLOT_GET_INT(pciio_info); pcibr_soft_t pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info); - devfs_handle_t xconn_vhdl = pcibr_soft->bs_conn; + vertex_hdl_t xconn_vhdl = pcibr_soft->bs_conn; iopaddr_t xio_addr; caddr_t addr; @@ -2908,7 +2813,7 @@ pcibr_piotrans_addr(devfs_handle_t pconn_vhdl, /*ARGSUSED */ iopaddr_t -pcibr_piospace_alloc(devfs_handle_t pconn_vhdl, +pcibr_piospace_alloc(vertex_hdl_t pconn_vhdl, device_desc_t dev_desc, pciio_space_t space, size_t req_size, @@ -3010,7 +2915,7 @@ pcibr_piospace_alloc(devfs_handle_t pconn_vhdl, /*ARGSUSED */ void -pcibr_piospace_free(devfs_handle_t pconn_vhdl, +pcibr_piospace_free(vertex_hdl_t pconn_vhdl, pciio_space_t space, iopaddr_t pciaddr, size_t req_size) @@ -3161,14 +3066,14 @@ pcibr_flags_to_d64(unsigned flags, pcibr_soft_t pcibr_soft) /*ARGSUSED */ pcibr_dmamap_t -pcibr_dmamap_alloc(devfs_handle_t pconn_vhdl, +pcibr_dmamap_alloc(vertex_hdl_t pconn_vhdl, device_desc_t dev_desc, size_t req_size_max, unsigned flags) { pciio_info_t pciio_info = pciio_info_get(pconn_vhdl); pcibr_soft_t pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info); - devfs_handle_t xconn_vhdl = pcibr_soft->bs_conn; + vertex_hdl_t xconn_vhdl = pcibr_soft->bs_conn; pciio_slot_t slot; xwidgetnum_t xio_port; @@ -3454,6 +3359,29 @@ pcibr_addr_xio_to_pci(pcibr_soft_t soft, iopaddr_t pci_addr; pciio_slot_t slot; + if (IS_PIC_BUSNUM_SOFT(soft, 0)) { + if ((xio_addr >= PICBRIDGE0_PCI_MEM32_BASE) && + (xio_lim <= PICBRIDGE0_PCI_MEM32_LIMIT)) { + pci_addr = xio_addr - PICBRIDGE0_PCI_MEM32_BASE; + return pci_addr; + } + if ((xio_addr >= PICBRIDGE0_PCI_MEM64_BASE) && + (xio_lim <= PICBRIDGE0_PCI_MEM64_LIMIT)) { + pci_addr = xio_addr - PICBRIDGE0_PCI_MEM64_BASE; + return pci_addr; + } + } else if (IS_PIC_BUSNUM_SOFT(soft, 1)) { + if ((xio_addr >= PICBRIDGE1_PCI_MEM32_BASE) && + (xio_lim <= PICBRIDGE1_PCI_MEM32_LIMIT)) { + pci_addr = xio_addr - PICBRIDGE1_PCI_MEM32_BASE; + return pci_addr; + } + if ((xio_addr >= PICBRIDGE1_PCI_MEM64_BASE) && + (xio_lim <= PICBRIDGE1_PCI_MEM64_LIMIT)) { + pci_addr = xio_addr - PICBRIDGE1_PCI_MEM64_BASE; + return pci_addr; + } + } else { if ((xio_addr >= BRIDGE_PCI_MEM32_BASE) && (xio_lim <= BRIDGE_PCI_MEM32_LIMIT)) { pci_addr = xio_addr - BRIDGE_PCI_MEM32_BASE; @@ -3464,6 +3392,7 @@ pcibr_addr_xio_to_pci(pcibr_soft_t soft, pci_addr = xio_addr - BRIDGE_PCI_MEM64_BASE; return pci_addr; } + } for (slot = soft->bs_min_slot; slot < PCIBR_NUM_SLOTS(soft); ++slot) if ((xio_addr >= PCIBR_BRIDGE_DEVIO(soft, slot)) && (xio_lim < PCIBR_BRIDGE_DEVIO(soft, slot + 1))) { @@ -3644,243 +3573,6 @@ pcibr_dmamap_addr(pcibr_dmamap_t pcibr_dmamap, } /*ARGSUSED */ -alenlist_t -pcibr_dmamap_list(pcibr_dmamap_t pcibr_dmamap, - alenlist_t palenlist, - unsigned flags) -{ - pcibr_soft_t pcibr_soft; - bridge_t *bridge=NULL; - - unsigned al_flags = (flags & PCIIO_NOSLEEP) ? AL_NOSLEEP : 0; - int inplace = flags & PCIIO_INPLACE; - - alenlist_t pciio_alenlist = 0; - alenlist_t xtalk_alenlist; - size_t length; - iopaddr_t offset; - unsigned direct64; - int ate_index = 0; - int ate_count = 0; - int ate_total = 0; - bridge_ate_p ate_ptr = (bridge_ate_p)0; - bridge_ate_t ate_proto = (bridge_ate_t)0; - bridge_ate_t ate_prev; - bridge_ate_t ate; - alenaddr_t xio_addr; - xwidgetnum_t xio_port; - iopaddr_t pci_addr; - alenaddr_t new_addr; - unsigned cmd_regs[8]; - unsigned s = 0; - -#if PCIBR_FREEZE_TIME - unsigned freeze_time; -#endif - int ate_freeze_done = 0; /* To pair ATE_THAW - * with an ATE_FREEZE - */ - - pcibr_soft = pcibr_dmamap->bd_soft; - - xtalk_alenlist = xtalk_dmamap_list(pcibr_dmamap->bd_xtalk, palenlist, - flags & DMAMAP_FLAGS); - if (!xtalk_alenlist) { - PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_DMAMAP, pcibr_dmamap->bd_dev, - "pcibr_dmamap_list: xtalk_dmamap_list() failed, " - "pcibr_dmamap=0x%x\n", pcibr_dmamap)); - goto fail; - } - alenlist_cursor_init(xtalk_alenlist, 0, NULL); - - if (inplace) { - pciio_alenlist = xtalk_alenlist; - } else { - pciio_alenlist = alenlist_create(al_flags); - if (!pciio_alenlist) { - PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_DMAMAP, pcibr_dmamap->bd_dev, - "pcibr_dmamap_list: alenlist_create() failed, " - "pcibr_dmamap=0x%lx\n", (unsigned long)pcibr_dmamap)); - goto fail; - } - } - - direct64 = pcibr_dmamap->bd_flags & PCIIO_DMA_A64; - if (!direct64) { - bridge = pcibr_soft->bs_base; - ate_ptr = pcibr_dmamap->bd_ate_ptr; - ate_index = pcibr_dmamap->bd_ate_index; - ate_proto = pcibr_dmamap->bd_ate_proto; - ATE_FREEZE(); - ate_freeze_done = 1; /* Remember that we need to do an ATE_THAW */ - } - pci_addr = pcibr_dmamap->bd_pci_addr; - - ate_prev = 0; /* matches no valid ATEs */ - while (ALENLIST_SUCCESS == - alenlist_get(xtalk_alenlist, NULL, 0, - &xio_addr, &length, al_flags)) { - if (XIO_PACKED(xio_addr)) { - xio_port = XIO_PORT(xio_addr); - xio_addr = XIO_ADDR(xio_addr); - } else - xio_port = pcibr_dmamap->bd_xio_port; - - if (xio_port == pcibr_soft->bs_xid) { - new_addr = pcibr_addr_xio_to_pci(pcibr_soft, xio_addr, length); - if (new_addr == PCI_NOWHERE) { - PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_DMAMAP, pcibr_dmamap->bd_dev, - "pcibr_dmamap_list: pcibr_addr_xio_to_pci failed, " - "pcibr_dmamap=0x%x\n", pcibr_dmamap)); - goto fail; - } - } else if (direct64) { - new_addr = pci_addr | xio_addr - | ((uint64_t) xio_port << PCI64_ATTR_TARG_SHFT); - - /* Bridge Hardware WAR #482836: - * If the transfer is not cache aligned - * and the Bridge Rev is <= B, force - * prefetch to be off. - */ - if (flags & PCIBR_NOPREFETCH) - new_addr &= ~PCI64_ATTR_PREF; - - } else { - /* calculate the ate value for - * the first address. If it - * matches the previous - * ATE written (ie. we had - * multiple blocks in the - * same IOPG), then back up - * and reuse that ATE. - * - * We are NOT going to - * aggressively try to - * reuse any other ATEs. - */ - offset = IOPGOFF(xio_addr); - ate = ate_proto - | (xio_port << ATE_TIDSHIFT) - | (xio_addr - offset); - if (ate == ate_prev) { - PCIBR_DEBUG((PCIBR_DEBUG_ATE, pcibr_dmamap->bd_dev, - "pcibr_dmamap_list: ATE share\n")); - ate_ptr--; - ate_index--; - pci_addr -= IOPGSIZE; - } - new_addr = pci_addr + offset; - - /* Fill in the hardware ATEs - * that contain this block. - */ - ate_count = IOPG(offset + length - 1) + 1; - ate_total += ate_count; - - /* Ensure that this map contains enough ATE's */ - if (ate_total > pcibr_dmamap->bd_ate_count) { - PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_ATE, pcibr_dmamap->bd_dev, - "pcibr_dmamap_list :\n" - "\twanted xio_addr [0x%x..0x%x]\n" - "\tate_total 0x%x bd_ate_count 0x%x\n" - "\tATE's required > number allocated\n", - xio_addr, xio_addr + length - 1, - ate_total, pcibr_dmamap->bd_ate_count)); - goto fail; - } - - ATE_WRITE(); - - ate_index += ate_count; - ate_ptr += ate_count; - - ate_count <<= IOPFNSHIFT; - ate += ate_count; - pci_addr += ate_count; - } - - /* write the PCI DMA address - * out to the scatter-gather list. - */ - if (inplace) { - if (ALENLIST_SUCCESS != - alenlist_replace(pciio_alenlist, NULL, - &new_addr, &length, al_flags)) { - PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_DMAMAP, pcibr_dmamap->bd_dev, - "pcibr_dmamap_list: alenlist_replace() failed, " - "pcibr_dmamap=0x%x\n", pcibr_dmamap)); - - goto fail; - } - } else { - if (ALENLIST_SUCCESS != - alenlist_append(pciio_alenlist, - new_addr, length, al_flags)) { - PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_DMAMAP, pcibr_dmamap->bd_dev, - "pcibr_dmamap_list: alenlist_append() failed, " - "pcibr_dmamap=0x%x\n", pcibr_dmamap)); - goto fail; - } - } - } - if (!inplace) - alenlist_done(xtalk_alenlist); - - /* Reset the internal cursor of the alenlist to be returned back - * to the caller. - */ - alenlist_cursor_init(pciio_alenlist, 0, NULL); - - - /* In case an ATE_FREEZE was done do the ATE_THAW to unroll all the - * changes that ATE_FREEZE has done to implement the external SSRAM - * bug workaround. - */ - if (ate_freeze_done) { - ATE_THAW(); - if ( IS_PIC_SOFT(pcibr_soft) ) { - bridge->b_wid_tflush; /* wait until Bridge PIO complete */ - } - else { - if (io_get_sh_swapper(NASID_GET(bridge))) { - BRIDGE_REG_GET32((&bridge->b_wid_tflush)); - } else { - bridge->b_wid_tflush; - } - } - } - PCIBR_DEBUG((PCIBR_DEBUG_DMAMAP, pcibr_dmamap->bd_dev, - "pcibr_dmamap_list: pcibr_dmamap=0x%x, pciio_alenlist=0x%x\n", - pcibr_dmamap, pciio_alenlist)); - - return pciio_alenlist; - - fail: - /* There are various points of failure after doing an ATE_FREEZE - * We need to do an ATE_THAW. Otherwise the ATEs are locked forever. - * The decision to do an ATE_THAW needs to be based on whether a - * an ATE_FREEZE was done before. - */ - if (ate_freeze_done) { - ATE_THAW(); - if ( IS_PIC_SOFT(pcibr_soft) ) { - bridge->b_wid_tflush; - } - else { - if (io_get_sh_swapper(NASID_GET(bridge))) { - BRIDGE_REG_GET32((&bridge->b_wid_tflush)); - } else { - bridge->b_wid_tflush; - } - } - } - if (pciio_alenlist && !inplace) - alenlist_destroy(pciio_alenlist); - return 0; -} - -/*ARGSUSED */ void pcibr_dmamap_done(pcibr_dmamap_t pcibr_dmamap) { @@ -3917,7 +3609,7 @@ pcibr_dmamap_done(pcibr_dmamap_t pcibr_dmamap) /*ARGSUSED */ cnodeid_t -pcibr_get_dmatrans_node(devfs_handle_t pconn_vhdl) +pcibr_get_dmatrans_node(vertex_hdl_t pconn_vhdl) { pciio_info_t pciio_info = pciio_info_get(pconn_vhdl); @@ -3928,7 +3620,7 @@ pcibr_get_dmatrans_node(devfs_handle_t pconn_vhdl) /*ARGSUSED */ iopaddr_t -pcibr_dmatrans_addr(devfs_handle_t pconn_vhdl, +pcibr_dmatrans_addr(vertex_hdl_t pconn_vhdl, device_desc_t dev_desc, paddr_t paddr, size_t req_size, @@ -3936,7 +3628,7 @@ pcibr_dmatrans_addr(devfs_handle_t pconn_vhdl, { pciio_info_t pciio_info = pciio_info_get(pconn_vhdl); pcibr_soft_t pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info); - devfs_handle_t xconn_vhdl = pcibr_soft->bs_conn; + vertex_hdl_t xconn_vhdl = pcibr_soft->bs_conn; pciio_slot_t pciio_slot = PCIBR_INFO_SLOT_GET_INT(pciio_info); pcibr_soft_slot_t slotp = &pcibr_soft->bs_slot[pciio_slot]; @@ -4149,213 +3841,6 @@ pcibr_dmatrans_addr(devfs_handle_t pconn_vhdl, return 0; } -/*ARGSUSED */ -alenlist_t -pcibr_dmatrans_list(devfs_handle_t pconn_vhdl, - device_desc_t dev_desc, - alenlist_t palenlist, - unsigned flags) -{ - pciio_info_t pciio_info = pciio_info_get(pconn_vhdl); - pcibr_soft_t pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info); - devfs_handle_t xconn_vhdl = pcibr_soft->bs_conn; - pciio_slot_t pciio_slot = PCIBR_INFO_SLOT_GET_INT(pciio_info); - pcibr_soft_slot_t slotp = &pcibr_soft->bs_slot[pciio_slot]; - xwidgetnum_t xio_port; - - alenlist_t pciio_alenlist = 0; - alenlist_t xtalk_alenlist = 0; - - int inplace; - unsigned direct64; - unsigned al_flags; - - iopaddr_t xio_base; - alenaddr_t xio_addr; - size_t xio_size; - - size_t map_size; - iopaddr_t pci_base; - alenaddr_t pci_addr; - - unsigned relbits = 0; - - /* merge in forced flags */ - flags |= pcibr_soft->bs_dma_flags; - - inplace = flags & PCIIO_INPLACE; - direct64 = flags & PCIIO_DMA_A64; - al_flags = (flags & PCIIO_NOSLEEP) ? AL_NOSLEEP : 0; - - if (direct64) { - map_size = 1ull << 48; - xio_base = 0; - pci_base = slotp->bss_d64_base; - if ((pci_base != PCIBR_D64_BASE_UNSET) && - (flags == slotp->bss_d64_flags)) { - /* reuse previous base info */ - } else if (pcibr_try_set_device(pcibr_soft, pciio_slot, flags, BRIDGE_DEV_D64_BITS) < 0) { - /* DMA configuration conflict */ - PCIBR_DEBUG((PCIBR_DEBUG_DMADIR, pconn_vhdl, - "pcibr_dmatrans_list: DMA configuration conflict " - "for direct64, flags=0x%x\n", flags)); - goto fail; - } else { - relbits = BRIDGE_DEV_D64_BITS; - pci_base = - pcibr_flags_to_d64(flags, pcibr_soft); - } - } else { - xio_base = pcibr_soft->bs_dir_xbase; - map_size = 1ull << 31; - pci_base = slotp->bss_d32_base; - if ((pci_base != PCIBR_D32_BASE_UNSET) && - (flags == slotp->bss_d32_flags)) { - /* reuse previous base info */ - } else if (pcibr_try_set_device(pcibr_soft, pciio_slot, flags, BRIDGE_DEV_D32_BITS) < 0) { - /* DMA configuration conflict */ - PCIBR_DEBUG((PCIBR_DEBUG_DMADIR, pconn_vhdl, - "pcibr_dmatrans_list: DMA configuration conflict " - "for direct32, flags=0x%x\n", flags)); - goto fail; - } else { - relbits = BRIDGE_DEV_D32_BITS; - pci_base = PCI32_DIRECT_BASE; - } - } - - xtalk_alenlist = xtalk_dmatrans_list(xconn_vhdl, 0, palenlist, - flags & DMAMAP_FLAGS); - if (!xtalk_alenlist) { - PCIBR_DEBUG((PCIBR_DEBUG_DMADIR, pconn_vhdl, - "pcibr_dmatrans_list: xtalk_dmatrans_list failed " - "xtalk_alenlist=0x%x\n", xtalk_alenlist)); - goto fail; - } - - alenlist_cursor_init(xtalk_alenlist, 0, NULL); - - if (inplace) { - pciio_alenlist = xtalk_alenlist; - } else { - pciio_alenlist = alenlist_create(al_flags); - if (!pciio_alenlist) { - PCIBR_DEBUG((PCIBR_DEBUG_DMADIR, pconn_vhdl, - "pcibr_dmatrans_list: alenlist_create failed with " - " 0x%x\n", pciio_alenlist)); - goto fail; - } - } - - while (ALENLIST_SUCCESS == - alenlist_get(xtalk_alenlist, NULL, 0, - &xio_addr, &xio_size, al_flags)) { - - /* - * find which XIO port this goes to. - */ - if (XIO_PACKED(xio_addr)) { - if (xio_addr == XIO_NOWHERE) { - PCIBR_DEBUG((PCIBR_DEBUG_DMADIR, pconn_vhdl, - "pcibr_dmatrans_list: xio_addr == XIO_NOWHERE\n")); - return 0; - } - xio_port = XIO_PORT(xio_addr); - xio_addr = XIO_ADDR(xio_addr); - } else - xio_port = pcibr_soft->bs_mxid; - - /* - * If this DMA comes back to us, - * return the PCI MEM address on - * which it would land, or NULL - * if the target is something - * on bridge other than PCI MEM. - */ - if (xio_port == pcibr_soft->bs_xid) { - pci_addr = pcibr_addr_xio_to_pci(pcibr_soft, xio_addr, xio_size); - if (pci_addr == (alenaddr_t)NULL) { - PCIBR_DEBUG((PCIBR_DEBUG_DMADIR, pconn_vhdl, - "pcibr_dmatrans_list: pcibr_addr_xio_to_pci failed " - "xio_addr=0x%x, xio_size=0x%x\n", xio_addr, xio_size)); - goto fail; - } - } else if (direct64) { - ASSERT(xio_port != 0); - pci_addr = pci_base | xio_addr - | ((uint64_t) xio_port << PCI64_ATTR_TARG_SHFT); - } else { - iopaddr_t offset = xio_addr - xio_base; - iopaddr_t endoff = xio_size + offset; - - if ((xio_size > map_size) || - (xio_addr < xio_base) || - (xio_port != pcibr_soft->bs_dir_xport) || - (endoff > map_size)) { - PCIBR_DEBUG((PCIBR_DEBUG_DMADIR, pconn_vhdl, - "pcibr_dmatrans_list: xio_size > map_size fail\n" - "xio_addr=0x%x, xio_size=0x%x. map_size=0x%x, " - "xio_port=0x%x, endoff=0x%x\n", - xio_addr, xio_size, map_size, xio_port, endoff)); - goto fail; - } - - pci_addr = pci_base + (xio_addr - xio_base); - } - - /* write the PCI DMA address - * out to the scatter-gather list. - */ - if (inplace) { - if (ALENLIST_SUCCESS != - alenlist_replace(pciio_alenlist, NULL, - &pci_addr, &xio_size, al_flags)) { - PCIBR_DEBUG((PCIBR_DEBUG_DMADIR, pconn_vhdl, - "pcibr_dmatrans_list: alenlist_replace failed\n")); - goto fail; - } - } else { - if (ALENLIST_SUCCESS != - alenlist_append(pciio_alenlist, - pci_addr, xio_size, al_flags)) { - PCIBR_DEBUG((PCIBR_DEBUG_DMADIR, pconn_vhdl, - "pcibr_dmatrans_list: alenlist_append failed\n")); - goto fail; - } - } - } - - if (relbits) { - if (direct64) { - slotp->bss_d64_flags = flags; - slotp->bss_d64_base = pci_base; - } else { - slotp->bss_d32_flags = flags; - slotp->bss_d32_base = pci_base; - } - } - if (!inplace) - alenlist_done(xtalk_alenlist); - - /* Reset the internal cursor of the alenlist to be returned back - * to the caller. - */ - alenlist_cursor_init(pciio_alenlist, 0, NULL); - - PCIBR_DEBUG((PCIBR_DEBUG_DMADIR, pconn_vhdl, - "pcibr_dmatrans_list: pciio_alenlist=0x%x\n", - pciio_alenlist)); - - return pciio_alenlist; - - fail: - if (relbits) - pcibr_release_device(pcibr_soft, pciio_slot, relbits); - if (pciio_alenlist && !inplace) - alenlist_destroy(pciio_alenlist); - return 0; -} - void pcibr_dmamap_drain(pcibr_dmamap_t map) { @@ -4363,24 +3848,24 @@ pcibr_dmamap_drain(pcibr_dmamap_t map) } void -pcibr_dmaaddr_drain(devfs_handle_t pconn_vhdl, +pcibr_dmaaddr_drain(vertex_hdl_t pconn_vhdl, paddr_t paddr, size_t bytes) { pciio_info_t pciio_info = pciio_info_get(pconn_vhdl); pcibr_soft_t pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info); - devfs_handle_t xconn_vhdl = pcibr_soft->bs_conn; + vertex_hdl_t xconn_vhdl = pcibr_soft->bs_conn; xtalk_dmaaddr_drain(xconn_vhdl, paddr, bytes); } void -pcibr_dmalist_drain(devfs_handle_t pconn_vhdl, +pcibr_dmalist_drain(vertex_hdl_t pconn_vhdl, alenlist_t list) { pciio_info_t pciio_info = pciio_info_get(pconn_vhdl); pcibr_soft_t pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info); - devfs_handle_t xconn_vhdl = pcibr_soft->bs_conn; + vertex_hdl_t xconn_vhdl = pcibr_soft->bs_conn; xtalk_dmalist_drain(xconn_vhdl, list); } @@ -4402,18 +3887,18 @@ pcibr_dmamap_pciaddr_get(pcibr_dmamap_t pcibr_dmamap) */ /*ARGSUSED */ void -pcibr_provider_startup(devfs_handle_t pcibr) +pcibr_provider_startup(vertex_hdl_t pcibr) { } /*ARGSUSED */ void -pcibr_provider_shutdown(devfs_handle_t pcibr) +pcibr_provider_shutdown(vertex_hdl_t pcibr) { } int -pcibr_reset(devfs_handle_t conn) +pcibr_reset(vertex_hdl_t conn) { #ifdef PIC_LATER pciio_info_t pciio_info = pciio_info_get(conn); @@ -4484,7 +3969,7 @@ pcibr_reset(devfs_handle_t conn) } pciio_endian_t -pcibr_endian_set(devfs_handle_t pconn_vhdl, +pcibr_endian_set(vertex_hdl_t pconn_vhdl, pciio_endian_t device_end, pciio_endian_t desired_end) { @@ -4629,7 +4114,7 @@ pcibr_priority_bits_set(pcibr_soft_t pcibr_soft, } pciio_priority_t -pcibr_priority_set(devfs_handle_t pconn_vhdl, +pcibr_priority_set(vertex_hdl_t pconn_vhdl, pciio_priority_t device_prio) { pciio_info_t pciio_info = pciio_info_get(pconn_vhdl); @@ -4653,7 +4138,7 @@ pcibr_priority_set(devfs_handle_t pconn_vhdl, * Returns 0 on failure, 1 on success */ int -pcibr_device_flags_set(devfs_handle_t pconn_vhdl, +pcibr_device_flags_set(vertex_hdl_t pconn_vhdl, pcibr_device_flags_t flags) { pciio_info_t pciio_info = pciio_info_get(pconn_vhdl); @@ -4792,10 +4277,8 @@ pciio_provider_t pcibr_provider = (pciio_dmamap_alloc_f *) pcibr_dmamap_alloc, (pciio_dmamap_free_f *) pcibr_dmamap_free, (pciio_dmamap_addr_f *) pcibr_dmamap_addr, - (pciio_dmamap_list_f *) pcibr_dmamap_list, (pciio_dmamap_done_f *) pcibr_dmamap_done, (pciio_dmatrans_addr_f *) pcibr_dmatrans_addr, - (pciio_dmatrans_list_f *) pcibr_dmatrans_list, (pciio_dmamap_drain_f *) pcibr_dmamap_drain, (pciio_dmaaddr_drain_f *) pcibr_dmaaddr_drain, (pciio_dmalist_drain_f *) pcibr_dmalist_drain, @@ -4814,23 +4297,16 @@ pciio_provider_t pcibr_provider = (pciio_priority_set_f *) pcibr_priority_set, (pciio_config_get_f *) pcibr_config_get, (pciio_config_set_f *) pcibr_config_set, -#ifdef PIC_LATER - (pciio_error_devenable_f *) pcibr_error_devenable, - (pciio_error_extract_f *) pcibr_error_extract, - (pciio_driver_reg_callback_f *) pcibr_driver_reg_callback, - (pciio_driver_unreg_callback_f *) pcibr_driver_unreg_callback, -#else (pciio_error_devenable_f *) 0, (pciio_error_extract_f *) 0, (pciio_driver_reg_callback_f *) 0, (pciio_driver_unreg_callback_f *) 0, -#endif /* PIC_LATER */ (pciio_device_unregister_f *) pcibr_device_unregister, (pciio_dma_enabled_f *) pcibr_dma_enabled, }; int -pcibr_dma_enabled(devfs_handle_t pconn_vhdl) +pcibr_dma_enabled(vertex_hdl_t pconn_vhdl) { pciio_info_t pciio_info = pciio_info_get(pconn_vhdl); pcibr_soft_t pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info); @@ -4857,7 +4333,7 @@ pcibr_dma_enabled(devfs_handle_t pconn_vhdl) * parameter 'format' is sent to the console. */ void -pcibr_debug(uint32_t type, devfs_handle_t vhdl, char *format, ...) +pcibr_debug(uint32_t type, vertex_hdl_t vhdl, char *format, ...) { char hwpath[MAXDEVNAME] = "\0"; char copy_of_hwpath[MAXDEVNAME]; @@ -4865,7 +4341,6 @@ pcibr_debug(uint32_t type, devfs_handle_t vhdl, char *format, ...) short widget = -1; short slot = -1; va_list ap; - char *strtok_r(char *string, const char *sepset, char **lasts); if (pcibr_debug_mask & type) { if (vhdl) { @@ -4873,13 +4348,12 @@ pcibr_debug(uint32_t type, devfs_handle_t vhdl, char *format, ...) char *cp; if (strcmp(module, pcibr_debug_module)) { - /* strtok_r() wipes out string, use a copy */ + /* use a copy */ (void)strcpy(copy_of_hwpath, hwpath); cp = strstr(copy_of_hwpath, "/module/"); if (cp) { - char *last = NULL; cp += strlen("/module"); - module = strtok_r(cp, "/", &last); + module = strsep(&cp, "/"); } } if (pcibr_debug_widget != -1) { @@ -4918,3 +4392,26 @@ pcibr_debug(uint32_t type, devfs_handle_t vhdl, char *format, ...) } } } + +int +isIO9(nasid_t nasid) { + lboard_t *brd = (lboard_t *)KL_CONFIG_INFO(nasid); + + while (brd) { + if (brd->brd_flags & LOCAL_MASTER_IO6) { + return 1; + } + brd = KLCF_NEXT(brd); + } + /* if it's dual ported, check the peer also */ + nasid = NODEPDA(NASID_TO_COMPACT_NODEID(nasid))->xbow_peer; + if (nasid < 0) return 0; + brd = (lboard_t *)KL_CONFIG_INFO(nasid); + while (brd) { + if (brd->brd_flags & LOCAL_MASTER_IO6) { + return 1; + } + brd = KLCF_NEXT(brd); + } + return 0; +} diff --git a/arch/ia64/sn/io/sn2/pcibr/pcibr_error.c b/arch/ia64/sn/io/sn2/pcibr/pcibr_error.c index 4295a33e916df9..91ee03e14b352d 100644 --- a/arch/ia64/sn/io/sn2/pcibr/pcibr_error.c +++ b/arch/ia64/sn/io/sn2/pcibr/pcibr_error.c @@ -4,7 +4,7 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. * - * Copyright (C) 2001-2002 Silicon Graphics, Inc. All rights reserved. + * Copyright (C) 2001-2003 Silicon Graphics, Inc. All rights reserved. */ #include <linux/types.h> @@ -27,26 +27,11 @@ #include <asm/sn/prio.h> #include <asm/sn/xtalk/xbow.h> #include <asm/sn/ioc3.h> -#include <asm/sn/eeprom.h> #include <asm/sn/io.h> #include <asm/sn/sn_private.h> -#ifdef __ia64 -#define rmallocmap atemapalloc -#define rmfreemap atemapfree -#define rmfree atefree -#define rmalloc atealloc -#endif - extern int hubii_check_widget_disabled(nasid_t, int); -#ifdef BRIDGE_B_DATACORR_WAR -extern int ql_bridge_rev_b_war(devfs_handle_t); -extern int bridge_rev_b_data_check_disable; -char *rev_b_datacorr_warning = -"***************************** WARNING! ******************************\n"; -char *rev_b_datacorr_mesg = -"UNRECOVERABLE IO LINK ERROR. CONTACT SERVICE PROVIDER\n"; -#endif + /* ===================================================================== * ERROR HANDLING @@ -76,13 +61,9 @@ uint64_t bridge_errors_to_dump = BRIDGE_ISR_ERROR_FATAL | BRIDGE_ISR_PCIBUS_PIOERR; #endif -#if defined (PCIBR_LLP_CONTROL_WAR) -int pcibr_llp_control_war_cnt; -#endif /* PCIBR_LLP_CONTROL_WAR */ +int pcibr_llp_control_war_cnt; /* PCIBR_LLP_CONTROL_WAR */ -/* FIXME: can these arrays be local ? */ - -struct reg_values xio_cmd_pactyp[] = +static struct reg_values xio_cmd_pactyp[] = { {0x0, "RdReq"}, {0x1, "RdResp"}, @@ -103,7 +84,7 @@ struct reg_values xio_cmd_pactyp[] = {0} }; -struct reg_desc xio_cmd_bits[] = +static struct reg_desc xio_cmd_bits[] = { {WIDGET_DIDN, -28, "DIDN", "%x"}, {WIDGET_SIDN, -24, "SIDN", "%x"}, @@ -120,58 +101,7 @@ struct reg_desc xio_cmd_bits[] = #define F(s,n) { 1l<<(s),-(s), n } -struct reg_desc bridge_int_status_desc[] = -{ - F(45, "PCI_X_SPLIT_MES_PE"),/* PIC ONLY */ - F(44, "PCI_X_SPLIT_EMES"), /* PIC ONLY */ - F(43, "PCI_X_SPLIT_TO"), /* PIC ONLY */ - F(42, "PCI_X_UNEX_COMP"), /* PIC ONLY */ - F(41, "INT_RAM_PERR"), /* PIC ONLY */ - F(40, "PCI_X_ARB_ERR"), /* PIC ONLY */ - F(39, "PCI_X_REQ_TOUT"), /* PIC ONLY */ - F(38, "PCI_X_TABORT"), /* PIC ONLY */ - F(37, "PCI_X_PERR"), /* PIC ONLY */ - F(36, "PCI_X_SERR"), /* PIC ONLY */ - F(35, "PCI_X_MRETRY"), /* PIC ONLY */ - F(34, "PCI_X_MTOUT"), /* PIC ONLY */ - F(33, "PCI_X_DA_PARITY"), /* PIC ONLY */ - F(32, "PCI_X_AD_PARITY"), /* PIC ONLY */ - F(31, "MULTI_ERR"), /* BRIDGE ONLY */ - F(30, "PMU_ESIZE_EFAULT"), - F(29, "UNEXPECTED_RESP"), - F(28, "BAD_XRESP_PACKET"), - F(27, "BAD_XREQ_PACKET"), - F(26, "RESP_XTALK_ERROR"), - F(25, "REQ_XTALK_ERROR"), - F(24, "INVALID_ADDRESS"), - F(23, "UNSUPPORTED_XOP"), - F(22, "XREQ_FIFO_OFLOW"), - F(21, "LLP_REC_SNERROR"), - F(20, "LLP_REC_CBERROR"), - F(19, "LLP_RCTY"), - F(18, "LLP_TX_RETRY"), - F(17, "LLP_TCTY"), - F(16, "SSRAM_PERR"), /* BRIDGE ONLY */ - F(15, "PCI_ABORT"), - F(14, "PCI_PARITY"), - F(13, "PCI_SERR"), - F(12, "PCI_PERR"), - F(11, "PCI_MASTER_TOUT"), - F(10, "PCI_RETRY_CNT"), - F(9, "XREAD_REQ_TOUT"), - F(8, "GIO_BENABLE_ERR"), /* BRIDGE ONLY */ - F(7, "INT7"), - F(6, "INT6"), - F(5, "INT5"), - F(4, "INT4"), - F(3, "INT3"), - F(2, "INT2"), - F(1, "INT1"), - F(0, "INT0"), - {0} -}; - -struct reg_values space_v[] = +static struct reg_values space_v[] = { {PCIIO_SPACE_NONE, "none"}, {PCIIO_SPACE_ROM, "ROM"}, @@ -189,13 +119,13 @@ struct reg_values space_v[] = {PCIIO_SPACE_BAD, "BAD"}, {0} }; -struct reg_desc space_desc[] = +static struct reg_desc space_desc[] = { {0xFF, 0, "space", 0, space_v}, {0} }; #define device_desc device_bits -struct reg_desc device_bits[] = +static struct reg_desc device_bits[] = { {BRIDGE_DEV_ERR_LOCK_EN, 0, "ERR_LOCK_EN"}, {BRIDGE_DEV_PAGE_CHK_DIS, 0, "PAGE_CHK_DIS"}, @@ -218,14 +148,14 @@ struct reg_desc device_bits[] = {0} }; -void +static void print_bridge_errcmd(uint32_t cmdword, char *errtype) { printk("\t Bridge %s Error Command Word Register ", errtype); print_register(cmdword, xio_cmd_bits); } -char *pcibr_isr_errs[] = +static char *pcibr_isr_errs[] = { "", "", "", "", "", "", "", "", "08: GIO non-contiguous byte enable in crosstalk packet", /* BRIDGE ONLY */ @@ -279,7 +209,7 @@ char *pcibr_isr_errs[] = /* * display memory directory state */ -void +static void pcibr_show_dir_state(paddr_t paddr, char *prefix) { #ifdef LATER @@ -428,7 +358,6 @@ pcibr_error_dump(pcibr_soft_t pcibr_soft) break; case BRIDGE_ISR_PAGE_FAULT: /* bit30 PMU_PAGE_FAULT */ -/* case BRIDGE_ISR_PMU_ESIZE_FAULT: bit30 PMU_ESIZE_FAULT */ if (IS_XBRIDGE_OR_PIC_SOFT(pcibr_soft)) reg_desc = "Map Fault Address"; else @@ -592,31 +521,9 @@ pcibr_error_dump(pcibr_soft_t pcibr_soft) printk( "\t%s\n", pcibr_isr_errs[i]); } } - -#if BRIDGE_ERROR_INTR_WAR - if (pcibr_soft->bs_rev_num == BRIDGE_PART_REV_A) { /* known bridge bug */ - /* - * Should never receive interrupts for these reasons on Rev 1 bridge - * as they are not enabled. Assert for it. - */ - ASSERT((int_status & (BRIDGE_IMR_PCI_MST_TIMEOUT | - BRIDGE_ISR_RESP_XTLK_ERR | - BRIDGE_ISR_LLP_TX_RETRY)) == 0); - } - if (pcibr_soft->bs_rev_num < BRIDGE_PART_REV_C) { /* known bridge bug */ - /* - * This interrupt is turned off at init time. So, should never - * see this interrupt. - */ - ASSERT((int_status & BRIDGE_ISR_BAD_XRESP_PKT) == 0); - } -#endif } -#define PCIBR_ERRINTR_GROUP(error) \ - (( error & (BRIDGE_IRR_PCI_GRP|BRIDGE_IRR_GIO_GRP) - -uint32_t +static uint32_t pcibr_errintr_group(uint32_t error) { uint32_t group = BRIDGE_IRR_MULTI_CLR; @@ -741,15 +648,7 @@ pcibr_error_intr_handler(int irq, void *arg, struct pt_regs *ep) picreg_t int_status_64; int number_bits; int i; - - /* REFERENCED */ uint64_t disable_errintr_mask = 0; -#ifdef EHE_ENABLE - int rv; - int error_code = IOECODE_DMA | IOECODE_READ; - ioerror_mode_t mode = MODE_DEVERROR; - ioerror_t ioe; -#endif /* EHE_ENABLE */ nasid_t nasid; @@ -806,10 +705,6 @@ pcibr_error_intr_handler(int irq, void *arg, struct pt_regs *ep) pcibr_soft->bs_errinfo.bserr_toutcnt++; /* Let's go recursive */ return(pcibr_error_intr_handler(irq, arg, ep)); -#ifdef LATER - timeout(pcibr_error_intr_handler, pcibr_soft, BRIDGE_PIOERR_TIMEOUT); -#endif - return; } /* We read the INT_STATUS register as a 64bit picreg_t for PIC and a @@ -847,24 +742,6 @@ pcibr_error_intr_handler(int irq, void *arg, struct pt_regs *ep) pcibr_pioerr_check(pcibr_soft); } -#ifdef BRIDGE_B_DATACORR_WAR - if ((pcibr_soft->bs_rev_num == BRIDGE_PART_REV_B) && - (err_status & BRIDGE_IMR_LLP_REC_CBERR)) { - if (bridge_rev_b_data_check_disable) - printk(KERN_WARNING "\n%s%s: %s%s\n", rev_b_datacorr_warning, - pcibr_soft->bs_name, rev_b_datacorr_mesg, - rev_b_datacorr_warning); - else { - ql_bridge_rev_b_war(pcibr_soft->bs_vhdl); - PRINT_PANIC( "\n%s%s: %s%s\n", rev_b_datacorr_warning, - pcibr_soft->bs_name, rev_b_datacorr_mesg, - rev_b_datacorr_warning); - } - - err_status &= ~BRIDGE_IMR_LLP_REC_CBERR; - } -#endif /* BRIDGE_B_DATACORR_WAR */ - if (err_status) { struct bs_errintr_stat_s *bs_estat = pcibr_soft->bs_errintr_stat; @@ -1024,9 +901,8 @@ pcibr_error_intr_handler(int irq, void *arg, struct pt_regs *ep) (0x00402000 == (0x00F07F00 & bridge->b_wid_err_cmdword))) { err_status &= ~BRIDGE_ISR_INVLD_ADDR; } -#if defined (PCIBR_LLP_CONTROL_WAR) /* - * The bridge bug, where the llp_config or control registers + * The bridge bug (PCIBR_LLP_CONTROL_WAR), where the llp_config or control registers * need to be read back after being written, affects an MP * system since there could be small windows between writing * the register and reading it back on one cpu while another @@ -1039,40 +915,9 @@ pcibr_error_intr_handler(int irq, void *arg, struct pt_regs *ep) if ((err_status & BRIDGE_ISR_INVLD_ADDR) && ((((uint64_t) bridge->b_wid_err_upper << 32) | (bridge->b_wid_err_lower)) == (BRIDGE_INT_RST_STAT & 0xff0))) { -#if 0 - if (kdebug) - printk(KERN_NOTICE "%s bridge: ignoring llp/control address interrupt", - pcibr_soft->bs_name); -#endif pcibr_llp_control_war_cnt++; err_status &= ~BRIDGE_ISR_INVLD_ADDR; } -#endif /* PCIBR_LLP_CONTROL_WAR */ - -#ifdef EHE_ENABLE - /* Check if this is the RESP_XTALK_ERROR interrupt. - * This can happen due to a failed DMA READ operation. - */ - if (err_status & BRIDGE_ISR_RESP_XTLK_ERR) { - /* Phase 1 : Look at the error state in the bridge and further - * down in the device layers. - */ - (void)error_state_set(pcibr_soft->bs_conn, ERROR_STATE_LOOKUP); - IOERROR_SETVALUE(&ioe, widgetnum, pcibr_soft->bs_xid); - (void)pcibr_error_handler((error_handler_arg_t)pcibr_soft, - error_code, - mode, - &ioe); - /* Phase 2 : Perform the action agreed upon in phase 1. - */ - (void)error_state_set(pcibr_soft->bs_conn, ERROR_STATE_ACTION); - rv = pcibr_error_handler((error_handler_arg_t)pcibr_soft, - error_code, - mode, - &ioe); - } - if (rv != IOERROR_HANDLED) { -#endif /* EHE_ENABLE */ bridge_errors_to_dump |= BRIDGE_ISR_PCIBUS_PIOERR; @@ -1089,25 +934,16 @@ pcibr_error_intr_handler(int irq, void *arg, struct pt_regs *ep) */ if (IS_PIC_SOFT(pcibr_soft) && PCIBR_WAR_ENABLED(PV867308, pcibr_soft) && (err_status & (BRIDGE_ISR_LLP_REC_SNERR | BRIDGE_ISR_LLP_REC_CBERR))) { - printk("BRIDGE ERR_STATUS 0x%x\n", err_status); + printk("BRIDGE ERR_STATUS 0x%lx\n", err_status); pcibr_error_dump(pcibr_soft); -#ifdef LATER - machine_error_dump(""); -#endif PRINT_PANIC("PCI Bridge Error interrupt killed the system"); } if (err_status & BRIDGE_ISR_ERROR_FATAL) { -#ifdef LATER - machine_error_dump(""); -#endif PRINT_PANIC("PCI Bridge Error interrupt killed the system"); /*NOTREACHED */ } -#ifdef EHE_ENABLE - } -#endif /* * We can't return without re-enabling the interrupt, since @@ -1137,136 +973,6 @@ pcibr_error_intr_handler(int irq, void *arg, struct pt_regs *ep) pcibr_soft->bs_errinfo.bserr_intstat = 0; } -/* - * pcibr_addr_toslot - * Given the 'pciaddr' find out which slot this address is - * allocated to, and return the slot number. - * While we have the info handy, construct the - * function number, space code and offset as well. - * - * NOTE: if this routine is called, we don't know whether - * the address is in CFG, MEM, or I/O space. We have to guess. - * This will be the case on PIO stores, where the only way - * we have of getting the address is to check the Bridge, which - * stores the PCI address but not the space and not the xtalk - * address (from which we could get it). - */ -int -pcibr_addr_toslot(pcibr_soft_t pcibr_soft, - iopaddr_t pciaddr, - pciio_space_t *spacep, - iopaddr_t *offsetp, - pciio_function_t *funcp) -{ - int s, f = 0, w; - iopaddr_t base; - size_t size; - pciio_piospace_t piosp; - - /* - * Check if the address is in config space - */ - - if ((pciaddr >= BRIDGE_CONFIG_BASE) && (pciaddr < BRIDGE_CONFIG_END)) { - - if (pciaddr >= BRIDGE_CONFIG1_BASE) - pciaddr -= BRIDGE_CONFIG1_BASE; - else - pciaddr -= BRIDGE_CONFIG_BASE; - - s = pciaddr / BRIDGE_CONFIG_SLOT_SIZE; - pciaddr %= BRIDGE_CONFIG_SLOT_SIZE; - - if (funcp) { - f = pciaddr / 0x100; - pciaddr %= 0x100; - } - if (spacep) - *spacep = PCIIO_SPACE_CFG; - if (offsetp) - *offsetp = pciaddr; - if (funcp) - *funcp = f; - - return s; - } - for (s = pcibr_soft->bs_min_slot; s < PCIBR_NUM_SLOTS(pcibr_soft); ++s) { - int nf = pcibr_soft->bs_slot[s].bss_ninfo; - pcibr_info_h pcibr_infoh = pcibr_soft->bs_slot[s].bss_infos; - - for (f = 0; f < nf; f++) { - pcibr_info_t pcibr_info = pcibr_infoh[f]; - - if (!pcibr_info) - continue; - for (w = 0; w < 6; w++) { - if (pcibr_info->f_window[w].w_space == PCIIO_SPACE_NONE) { - continue; - } - base = pcibr_info->f_window[w].w_base; - size = pcibr_info->f_window[w].w_size; - - if ((pciaddr >= base) && (pciaddr < (base + size))) { - if (spacep) - *spacep = PCIIO_SPACE_WIN(w); - if (offsetp) - *offsetp = pciaddr - base; - if (funcp) - *funcp = f; - return s; - } /* endif match */ - } /* next window */ - } /* next func */ - } /* next slot */ - - /* - * Check if the address was allocated as part of the - * pcibr_piospace_alloc calls. - */ - for (s = pcibr_soft->bs_min_slot; s < PCIBR_NUM_SLOTS(pcibr_soft); ++s) { - int nf = pcibr_soft->bs_slot[s].bss_ninfo; - pcibr_info_h pcibr_infoh = pcibr_soft->bs_slot[s].bss_infos; - - for (f = 0; f < nf; f++) { - pcibr_info_t pcibr_info = pcibr_infoh[f]; - - if (!pcibr_info) - continue; - piosp = pcibr_info->f_piospace; - while (piosp) { - if ((piosp->start <= pciaddr) && - ((piosp->count + piosp->start) > pciaddr)) { - if (spacep) - *spacep = piosp->space; - if (offsetp) - *offsetp = pciaddr - piosp->start; - return s; - } /* endif match */ - piosp = piosp->next; - } /* next piosp */ - } /* next func */ - } /* next slot */ - - /* - * Some other random address on the PCI bus ... - * we have no way of knowing whether this was - * a MEM or I/O access; so, for now, we just - * assume that the low 1G is MEM, the next - * 3G is I/O, and anything above the 4G limit - * is obviously MEM. - */ - - if (spacep) - *spacep = ((pciaddr < (1ul << 30)) ? PCIIO_SPACE_MEM : - (pciaddr < (4ul << 30)) ? PCIIO_SPACE_IO : - PCIIO_SPACE_MEM); - if (offsetp) - *offsetp = pciaddr; - - return PCIIO_SLOT_NONE; - -} - void pcibr_error_cleanup(pcibr_soft_t pcibr_soft, int error_code) { @@ -1286,59 +992,6 @@ pcibr_error_cleanup(pcibr_soft_t pcibr_soft, int error_code) (void) bridge->b_wid_tflush; /* flushbus */ } -/* - * pcibr_error_extract - * Given the 'pcibr vertex handle' find out which slot - * the bridge status error address (from pcibr_soft info - * hanging off the vertex) - * allocated to, and return the slot number. - * While we have the info handy, construct the - * space code and offset as well. - * - * NOTE: if this routine is called, we don't know whether - * the address is in CFG, MEM, or I/O space. We have to guess. - * This will be the case on PIO stores, where the only way - * we have of getting the address is to check the Bridge, which - * stores the PCI address but not the space and not the xtalk - * address (from which we could get it). - * - * XXX- this interface has no way to return the function - * number on a multifunction card, even though that data - * is available. - */ - -pciio_slot_t -pcibr_error_extract(devfs_handle_t pcibr_vhdl, - pciio_space_t *spacep, - iopaddr_t *offsetp) -{ - pcibr_soft_t pcibr_soft = 0; - iopaddr_t bserr_addr; - bridge_t *bridge; - pciio_slot_t slot = PCIIO_SLOT_NONE; - arbitrary_info_t rev; - - /* Do a sanity check as to whether we really got a - * bridge vertex handle. - */ - if (hwgraph_info_get_LBL(pcibr_vhdl, INFO_LBL_PCIBR_ASIC_REV, &rev) != - GRAPH_SUCCESS) - return(slot); - - pcibr_soft = pcibr_soft_get(pcibr_vhdl); - if (pcibr_soft) { - bridge = pcibr_soft->bs_base; - bserr_addr = - bridge->b_pci_err_lower | - ((uint64_t) (bridge->b_pci_err_upper & - BRIDGE_ERRUPPR_ADDRMASK) << 32); - - slot = pcibr_addr_toslot(pcibr_soft, bserr_addr, - spacep, offsetp, NULL); - } - return slot; -} - /*ARGSUSED */ void pcibr_device_disable(pcibr_soft_t pcibr_soft, int devnum) @@ -1426,7 +1079,7 @@ pcibr_pioerror( { int retval = IOERROR_HANDLED; - devfs_handle_t pcibr_vhdl = pcibr_soft->bs_vhdl; + vertex_hdl_t pcibr_vhdl = pcibr_soft->bs_vhdl; bridge_t *bridge = pcibr_soft->bs_base; iopaddr_t bad_xaddr; @@ -1837,7 +1490,7 @@ pcibr_dmard_error( ioerror_mode_t mode, ioerror_t *ioe) { - devfs_handle_t pcibr_vhdl = pcibr_soft->bs_vhdl; + vertex_hdl_t pcibr_vhdl = pcibr_soft->bs_vhdl; bridge_t *bridge = pcibr_soft->bs_base; bridgereg_t bus_lowaddr, bus_uppraddr; int retval = 0; @@ -1946,7 +1599,7 @@ pcibr_dmawr_error( ioerror_mode_t mode, ioerror_t *ioe) { - devfs_handle_t pcibr_vhdl = pcibr_soft->bs_vhdl; + vertex_hdl_t pcibr_vhdl = pcibr_soft->bs_vhdl; int retval; retval = pciio_error_handler(pcibr_vhdl, error_code, mode, ioe); @@ -1982,34 +1635,12 @@ pcibr_error_handler( pcibr_soft_t pcibr_soft; int retval = IOERROR_BADERRORCODE; -#ifdef EHE_ENABLE - devfs_handle_t xconn_vhdl,pcibr_vhdl; - error_state_t e_state; -#endif /* EHE_ENABLE */ - pcibr_soft = (pcibr_soft_t) einfo; PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_ERROR_HDLR, pcibr_soft->bs_conn, "pcibr_error_handler: pcibr_soft=0x%x, error_code=0x%x\n", pcibr_soft, error_code)); -#ifdef EHE_ENABLE - xconn_vhdl = pcibr_soft->bs_conn; - pcibr_vhdl = pcibr_soft->bs_vhdl; - - e_state = error_state_get(xconn_vhdl); - - if (error_state_set(pcibr_vhdl, e_state) == - ERROR_RETURN_CODE_CANNOT_SET_STATE) - return(IOERROR_UNHANDLED); - - /* If we are in the action handling phase clean out the error state - * on the xswitch. - */ - if (e_state == ERROR_STATE_ACTION) - (void)error_state_set(xconn_vhdl, ERROR_STATE_NONE); -#endif /* EHE_ENABLE */ - #if DEBUG && ERROR_DEBUG printk( "%s: pcibr_error_handler\n", pcibr_soft->bs_name); #endif @@ -2086,11 +1717,6 @@ pcibr_error_handler_wrapper( * the error from the PIO address. */ -#if 0 - if (mode == MODE_DEVPROBE) - pio_retval = IOERROR_HANDLED; - else { -#endif if (error_code & IOECODE_PIO) { iopaddr_t bad_xaddr; /* @@ -2123,9 +1749,6 @@ pcibr_error_handler_wrapper( pio_retval = IOERROR_UNHANDLED; } } -#if 0 - } /* MODE_DEVPROBE */ -#endif /* * If the error was a result of a DMA Write, we tell what bus on the PIC @@ -2201,37 +1824,3 @@ pcibr_error_handler_wrapper( return IOERROR_HANDLED; } } - - -/* - * Reenable a device after handling the error. - * This is called by the lower layers when they wish to be reenabled - * after an error. - * Note that each layer would be calling the previous layer to reenable - * first, before going ahead with their own re-enabling. - */ - -int -pcibr_error_devenable(devfs_handle_t pconn_vhdl, int error_code) -{ - pciio_info_t pciio_info = pciio_info_get(pconn_vhdl); - pciio_slot_t pciio_slot = PCIBR_INFO_SLOT_GET_INT(pciio_info); - pcibr_soft_t pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info); - - ASSERT(error_code & IOECODE_PIO); - - /* If the error is not known to be a write, - * we have to call devenable. - * write errors are isolated to the bridge. - */ - if (!(error_code & IOECODE_WRITE)) { - devfs_handle_t xconn_vhdl = pcibr_soft->bs_conn; - int rc; - - rc = xtalk_error_devenable(xconn_vhdl, pciio_slot, error_code); - if (rc != IOERROR_HANDLED) - return rc; - } - pcibr_error_cleanup(pcibr_soft, error_code); - return IOERROR_HANDLED; -} diff --git a/arch/ia64/sn/io/sn2/pcibr/pcibr_hints.c b/arch/ia64/sn/io/sn2/pcibr/pcibr_hints.c index 657e2f855d3d5c..3b9344a36f5441 100644 --- a/arch/ia64/sn/io/sn2/pcibr/pcibr_hints.c +++ b/arch/ia64/sn/io/sn2/pcibr/pcibr_hints.c @@ -4,7 +4,7 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. * - * Copyright (C) 2001-2002 Silicon Graphics, Inc. All rights reserved. + * Copyright (C) 2001-2003 Silicon Graphics, Inc. All rights reserved. */ #include <linux/types.h> @@ -27,20 +27,19 @@ #include <asm/sn/prio.h> #include <asm/sn/xtalk/xbow.h> #include <asm/sn/ioc3.h> -#include <asm/sn/eeprom.h> #include <asm/sn/io.h> #include <asm/sn/sn_private.h> -pcibr_hints_t pcibr_hints_get(devfs_handle_t, int); -void pcibr_hints_fix_rrbs(devfs_handle_t); -void pcibr_hints_dualslot(devfs_handle_t, pciio_slot_t, pciio_slot_t); -void pcibr_hints_intr_bits(devfs_handle_t, pcibr_intr_bits_f *); -void pcibr_set_rrb_callback(devfs_handle_t, rrb_alloc_funct_t); -void pcibr_hints_handsoff(devfs_handle_t); -void pcibr_hints_subdevs(devfs_handle_t, pciio_slot_t, uint64_t); +pcibr_hints_t pcibr_hints_get(vertex_hdl_t, int); +void pcibr_hints_fix_rrbs(vertex_hdl_t); +void pcibr_hints_dualslot(vertex_hdl_t, pciio_slot_t, pciio_slot_t); +void pcibr_hints_intr_bits(vertex_hdl_t, pcibr_intr_bits_f *); +void pcibr_set_rrb_callback(vertex_hdl_t, rrb_alloc_funct_t); +void pcibr_hints_handsoff(vertex_hdl_t); +void pcibr_hints_subdevs(vertex_hdl_t, pciio_slot_t, uint64_t); pcibr_hints_t -pcibr_hints_get(devfs_handle_t xconn_vhdl, int alloc) +pcibr_hints_get(vertex_hdl_t xconn_vhdl, int alloc) { arbitrary_info_t ainfo = 0; graph_error_t rv; @@ -79,7 +78,7 @@ abnormal_exit: } void -pcibr_hints_fix_some_rrbs(devfs_handle_t xconn_vhdl, unsigned mask) +pcibr_hints_fix_some_rrbs(vertex_hdl_t xconn_vhdl, unsigned mask) { pcibr_hints_t hint = pcibr_hints_get(xconn_vhdl, 1); @@ -91,13 +90,13 @@ pcibr_hints_fix_some_rrbs(devfs_handle_t xconn_vhdl, unsigned mask) } void -pcibr_hints_fix_rrbs(devfs_handle_t xconn_vhdl) +pcibr_hints_fix_rrbs(vertex_hdl_t xconn_vhdl) { pcibr_hints_fix_some_rrbs(xconn_vhdl, 0xFF); } void -pcibr_hints_dualslot(devfs_handle_t xconn_vhdl, +pcibr_hints_dualslot(vertex_hdl_t xconn_vhdl, pciio_slot_t host, pciio_slot_t guest) { @@ -111,7 +110,7 @@ pcibr_hints_dualslot(devfs_handle_t xconn_vhdl, } void -pcibr_hints_intr_bits(devfs_handle_t xconn_vhdl, +pcibr_hints_intr_bits(vertex_hdl_t xconn_vhdl, pcibr_intr_bits_f *xxx_intr_bits) { pcibr_hints_t hint = pcibr_hints_get(xconn_vhdl, 1); @@ -124,7 +123,7 @@ pcibr_hints_intr_bits(devfs_handle_t xconn_vhdl, } void -pcibr_set_rrb_callback(devfs_handle_t xconn_vhdl, rrb_alloc_funct_t rrb_alloc_funct) +pcibr_set_rrb_callback(vertex_hdl_t xconn_vhdl, rrb_alloc_funct_t rrb_alloc_funct) { pcibr_hints_t hint = pcibr_hints_get(xconn_vhdl, 1); @@ -133,7 +132,7 @@ pcibr_set_rrb_callback(devfs_handle_t xconn_vhdl, rrb_alloc_funct_t rrb_alloc_fu } void -pcibr_hints_handsoff(devfs_handle_t xconn_vhdl) +pcibr_hints_handsoff(vertex_hdl_t xconn_vhdl) { pcibr_hints_t hint = pcibr_hints_get(xconn_vhdl, 1); @@ -145,13 +144,13 @@ pcibr_hints_handsoff(devfs_handle_t xconn_vhdl) } void -pcibr_hints_subdevs(devfs_handle_t xconn_vhdl, +pcibr_hints_subdevs(vertex_hdl_t xconn_vhdl, pciio_slot_t slot, uint64_t subdevs) { arbitrary_info_t ainfo = 0; char sdname[16]; - devfs_handle_t pconn_vhdl = GRAPH_VERTEX_NONE; + vertex_hdl_t pconn_vhdl = GRAPH_VERTEX_NONE; sprintf(sdname, "%s/%d", EDGE_LBL_PCI, slot); (void) hwgraph_path_add(xconn_vhdl, sdname, &pconn_vhdl); diff --git a/arch/ia64/sn/io/sn2/pcibr/pcibr_idbg.c b/arch/ia64/sn/io/sn2/pcibr/pcibr_idbg.c deleted file mode 100644 index 93c52e35a7c768..00000000000000 --- a/arch/ia64/sn/io/sn2/pcibr/pcibr_idbg.c +++ /dev/null @@ -1,147 +0,0 @@ -/* - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 2001-2002 Silicon Graphics, Inc. All rights reserved. - */ - -#include <linux/types.h> -#include <linux/slab.h> -#include <linux/module.h> -#include <asm/sn/sgi.h> -#include <asm/sn/sn_cpuid.h> -#include <asm/sn/addrs.h> -#include <asm/sn/arch.h> -#include <asm/sn/iograph.h> -#include <asm/sn/invent.h> -#include <asm/sn/hcl.h> -#include <asm/sn/labelcl.h> -#include <asm/sn/xtalk/xwidget.h> -#include <asm/sn/pci/bridge.h> -#include <asm/sn/pci/pciio.h> -#include <asm/sn/pci/pcibr.h> -#include <asm/sn/pci/pcibr_private.h> -#include <asm/sn/pci/pci_defs.h> -#include <asm/sn/prio.h> -#include <asm/sn/xtalk/xbow.h> -#include <asm/sn/ioc3.h> -#include <asm/sn/eeprom.h> -#include <asm/sn/io.h> -#include <asm/sn/sn_private.h> - -#ifdef LATER - -char *pci_space[] = {"NONE", - "ROM", - "IO", - "", - "MEM", - "MEM32", - "MEM64", - "CFG", - "WIN0", - "WIN1", - "WIN2", - "WIN3", - "WIN4", - "WIN5", - "", - "BAD"}; - -void -idbg_pss_func(pcibr_info_h pcibr_infoh, int func) -{ - pcibr_info_t pcibr_info = pcibr_infoh[func]; - char name[MAXDEVNAME]; - int win; - - if (!pcibr_info) - return; - qprintf("Per-slot Function Info\n"); - sprintf(name, "%v", pcibr_info->f_vertex); - qprintf("\tSlot Name : %s\n",name); - qprintf("\tPCI Bus : %d ",pcibr_info->f_bus); - qprintf("Slot : %d ", pcibr_info->f_slot); - qprintf("Function : %d ", pcibr_info->f_func); - qprintf("VendorId : 0x%x " , pcibr_info->f_vendor); - qprintf("DeviceId : 0x%x\n", pcibr_info->f_device); - sprintf(name, "%v", pcibr_info->f_master); - qprintf("\tBus provider : %s\n",name); - qprintf("\tProvider Fns : 0x%x ", pcibr_info->f_pops); - qprintf("Error Handler : 0x%x Arg 0x%x\n", - pcibr_info->f_efunc,pcibr_info->f_einfo); - for(win = 0 ; win < 6 ; win++) - qprintf("\tBase Reg #%d space %s base 0x%x size 0x%x\n", - win,pci_space[pcibr_info->f_window[win].w_space], - pcibr_info->f_window[win].w_base, - pcibr_info->f_window[win].w_size); - - qprintf("\tRom base 0x%x size 0x%x\n", - pcibr_info->f_rbase,pcibr_info->f_rsize); - - qprintf("\tInterrupt Bit Map\n"); - qprintf("\t\tPCI Int#\tBridge Pin#\n"); - for (win = 0 ; win < 4; win++) - qprintf("\t\tINT%c\t\t%d\n",win+'A',pcibr_info->f_ibit[win]); - qprintf("\n"); -} - - -void -idbg_pss_info(pcibr_soft_t pcibr_soft, pciio_slot_t slot) -{ - pcibr_soft_slot_t pss; - char slot_conn_name[MAXDEVNAME]; - int func; - - pss = &pcibr_soft->bs_slot[slot]; - qprintf("PCI INFRASTRUCTURAL INFO FOR SLOT %d\n", slot); - qprintf("\tHost Present ? %s ", pss->has_host ? "yes" : "no"); - qprintf("\tHost Slot : %d\n",pss->host_slot); - sprintf(slot_conn_name, "%v", pss->slot_conn); - qprintf("\tSlot Conn : %s\n",slot_conn_name); - qprintf("\t#Functions : %d\n",pss->bss_ninfo); - for (func = 0; func < pss->bss_ninfo; func++) - idbg_pss_func(pss->bss_infos,func); - qprintf("\tSpace : %s ",pci_space[pss->bss_devio.bssd_space]); - qprintf("\tBase : 0x%x ", pss->bss_devio.bssd_base); - qprintf("\tShadow Devreg : 0x%x\n", pss->bss_device); - qprintf("\tUsage counts : pmu %d d32 %d d64 %d\n", - pss->bss_pmu_uctr,pss->bss_d32_uctr,pss->bss_d64_uctr); - - qprintf("\tDirect Trans Info : d64_base 0x%x d64_flags 0x%x" - "d32_base 0x%x d32_flags 0x%x\n", - pss->bss_d64_base, pss->bss_d64_flags, - pss->bss_d32_base, pss->bss_d32_flags); - - qprintf("\tExt ATEs active ? %s", - pss->bss_ext_ates_active ? "yes" : "no"); - qprintf(" Command register : 0x%x ", pss->bss_cmd_pointer); - qprintf(" Shadow command val : 0x%x\n", pss->bss_cmd_shadow); - - qprintf("\tRRB Info : Valid %d+%d Reserved %d\n", - pcibr_soft->bs_rrb_valid[slot], - pcibr_soft->bs_rrb_valid[slot + PCIBR_RRB_SLOT_VIRTUAL], - pcibr_soft->bs_rrb_res[slot]); - -} - -int ips = 0; - -void -idbg_pss(pcibr_soft_t pcibr_soft) -{ - pciio_slot_t slot; - - - if (ips >= 0 && ips < 8) - idbg_pss_info(pcibr_soft,ips); - else if (ips < 0) - for (slot = 0; slot < 8; slot++) - idbg_pss_info(pcibr_soft,slot); - else - qprintf("Invalid ips %d\n",ips); -} -#endif /* LATER */ diff --git a/arch/ia64/sn/io/sn2/pcibr/pcibr_intr.c b/arch/ia64/sn/io/sn2/pcibr/pcibr_intr.c index 22b679e9d8ab13..211aec200f4b59 100644 --- a/arch/ia64/sn/io/sn2/pcibr/pcibr_intr.c +++ b/arch/ia64/sn/io/sn2/pcibr/pcibr_intr.c @@ -4,7 +4,7 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. * - * Copyright (C) 2001-2002 Silicon Graphics, Inc. All rights reserved. + * Copyright (C) 2001-2003 Silicon Graphics, Inc. All rights reserved. */ #include <linux/types.h> @@ -27,7 +27,6 @@ #include <asm/sn/prio.h> #include <asm/sn/xtalk/xbow.h> #include <asm/sn/ioc3.h> -#include <asm/sn/eeprom.h> #include <asm/sn/io.h> #include <asm/sn/sn_private.h> @@ -36,20 +35,32 @@ #define rmfreemap atemapfree #define rmfree atefree #define rmalloc atealloc + +inline int +compare_and_swap_ptr(void **location, void *old_ptr, void *new_ptr) +{ + FIXME("compare_and_swap_ptr : NOT ATOMIC"); + if (*location == old_ptr) { + *location = new_ptr; + return(1); + } + else + return(0); +} #endif unsigned pcibr_intr_bits(pciio_info_t info, pciio_intr_line_t lines, int nslots); -pcibr_intr_t pcibr_intr_alloc(devfs_handle_t, device_desc_t, pciio_intr_line_t, devfs_handle_t); +pcibr_intr_t pcibr_intr_alloc(vertex_hdl_t, device_desc_t, pciio_intr_line_t, vertex_hdl_t); void pcibr_intr_free(pcibr_intr_t); void pcibr_setpciint(xtalk_intr_t); int pcibr_intr_connect(pcibr_intr_t, intr_func_t, intr_arg_t); void pcibr_intr_disconnect(pcibr_intr_t); -devfs_handle_t pcibr_intr_cpu_get(pcibr_intr_t); +vertex_hdl_t pcibr_intr_cpu_get(pcibr_intr_t); void pcibr_xintr_preset(void *, int, xwidgetnum_t, iopaddr_t, xtalk_intr_vector_t); void pcibr_intr_func(intr_arg_t); -extern pcibr_info_t pcibr_info_get(devfs_handle_t); +extern pcibr_info_t pcibr_info_get(vertex_hdl_t); /* ===================================================================== * INTERRUPT MANAGEMENT @@ -132,6 +143,102 @@ pcibr_wrap_put(pcibr_intr_wrap_t wrap, pcibr_intr_cbuf_t cbuf) } /* + * On SN systems there is a race condition between a PIO read response + * and DMA's. In rare cases, the read response may beat the DMA, causing + * the driver to think that data in memory is complete and meaningful. + * This code eliminates that race. + * This routine is called by the PIO read routines after doing the read. + * This routine then forces a fake interrupt on another line, which + * is logically associated with the slot that the PIO is addressed to. + * (see sn_dma_flush_init() ) + * It then spins while watching the memory location that the interrupt + * is targetted to. When the interrupt response arrives, we are sure + * that the DMA has landed in memory and it is safe for the driver + * to proceed. + */ + +extern struct sn_flush_nasid_entry flush_nasid_list[MAX_NASIDS]; + +void +sn_dma_flush(unsigned long addr) { + nasid_t nasid; + int wid_num; + volatile struct sn_flush_device_list *p; + int i,j; + int bwin; + unsigned long flags; + + nasid = NASID_GET(addr); + wid_num = SWIN_WIDGETNUM(addr); + bwin = BWIN_WINDOWNUM(addr); + + if (flush_nasid_list[nasid].widget_p == NULL) return; + if (bwin > 0) { + bwin--; + switch (bwin) { + case 0: + wid_num = ((flush_nasid_list[nasid].iio_itte1) >> 8) & 0xf; + break; + case 1: + wid_num = ((flush_nasid_list[nasid].iio_itte2) >> 8) & 0xf; + break; + case 2: + wid_num = ((flush_nasid_list[nasid].iio_itte3) >> 8) & 0xf; + break; + case 3: + wid_num = ((flush_nasid_list[nasid].iio_itte4) >> 8) & 0xf; + break; + case 4: + wid_num = ((flush_nasid_list[nasid].iio_itte5) >> 8) & 0xf; + break; + case 5: + wid_num = ((flush_nasid_list[nasid].iio_itte6) >> 8) & 0xf; + break; + case 6: + wid_num = ((flush_nasid_list[nasid].iio_itte7) >> 8) & 0xf; + break; + } + } + if (flush_nasid_list[nasid].widget_p == NULL) return; + if (flush_nasid_list[nasid].widget_p[wid_num] == NULL) return; + p = &flush_nasid_list[nasid].widget_p[wid_num][0]; + + // find a matching BAR + + for (i=0; i<DEV_PER_WIDGET;i++) { + for (j=0; j<PCI_ROM_RESOURCE;j++) { + if (p->bar_list[j].start == 0) break; + if (addr >= p->bar_list[j].start && addr <= p->bar_list[j].end) break; + } + if (j < PCI_ROM_RESOURCE && p->bar_list[j].start != 0) break; + p++; + } + + // if no matching BAR, return without doing anything. + + if (i == DEV_PER_WIDGET) return; + + spin_lock_irqsave(&p->flush_lock, flags); + + p->flush_addr = 0; + + // force an interrupt. + + *(bridgereg_t *)(p->force_int_addr) = 1; + + // wait for the interrupt to come back. + + while (p->flush_addr != 0x10f); + + // okay, everything is synched up. + spin_unlock_irqrestore(&p->flush_lock, flags); + + return; +} + +EXPORT_SYMBOL(sn_dma_flush); + +/* * There are end cases where a deadlock can occur if interrupt * processing completes and the Bridge b_int_status bit is still set. * @@ -164,51 +271,42 @@ pcibr_wrap_put(pcibr_intr_wrap_t wrap, pcibr_intr_cbuf_t cbuf) * to check if a specific Bridge b_int_status bit is set, and if so, * cause the setting of the corresponding interrupt bit. * - * On a XBridge (SN1), we do this by writing the appropriate Bridge Force - * Interrupt register. On SN0, or SN1 with an older Bridge, the Bridge - * Force Interrupt register does not exist, so we write the Hub - * INT_PEND_MOD register directly. Likewise for Octane, where we write the - * Heart Set Interrupt Status register directly. + * On a XBridge (SN1) and PIC (SN2), we do this by writing the appropriate Bridge Force + * Interrupt register. */ void -pcibr_force_interrupt(pcibr_intr_wrap_t wrap) +pcibr_force_interrupt(pcibr_intr_t intr) { -#ifdef PIC_LATER unsigned bit; - pcibr_soft_t pcibr_soft = wrap->iw_soft; + unsigned bits; + pcibr_soft_t pcibr_soft = intr->bi_soft; bridge_t *bridge = pcibr_soft->bs_base; - bit = wrap->iw_ibit; + bits = intr->bi_ibits; + for (bit = 0; bit < 8; bit++) { + if (bits & (1 << bit)) { - PCIBR_DEBUG((PCIBR_DEBUG_INTR, pcibr_soft->bs_vhdl, - "pcibr_force_interrupt: bit=0x%x\n", bit)); + PCIBR_DEBUG((PCIBR_DEBUG_INTR, pcibr_soft->bs_vhdl, + "pcibr_force_interrupt: bit=0x%x\n", bit)); - if (IS_XBRIDGE_OR_PIC_SOFT(pcibr_soft)) { - bridge->b_force_pin[bit].intr = 1; - } else if ((1 << bit) & *wrap->iw_stat) { - cpuid_t cpu; - unsigned intr_bit; - xtalk_intr_t xtalk_intr = - pcibr_soft->bs_intr[bit].bsi_xtalk_intr; - - intr_bit = (short) xtalk_intr_vector_get(xtalk_intr); - cpu = xtalk_intr_cpuid_get(xtalk_intr); - REMOTE_CPU_SEND_INTR(cpu, intr_bit); + if (IS_XBRIDGE_OR_PIC_SOFT(pcibr_soft)) { + bridge->b_force_pin[bit].intr = 1; + } + } } -#endif /* PIC_LATER */ } /*ARGSUSED */ pcibr_intr_t -pcibr_intr_alloc(devfs_handle_t pconn_vhdl, +pcibr_intr_alloc(vertex_hdl_t pconn_vhdl, device_desc_t dev_desc, pciio_intr_line_t lines, - devfs_handle_t owner_dev) + vertex_hdl_t owner_dev) { pcibr_info_t pcibr_info = pcibr_info_get(pconn_vhdl); pciio_slot_t pciio_slot = PCIBR_INFO_SLOT_GET_INT(pcibr_info); pcibr_soft_t pcibr_soft = (pcibr_soft_t) pcibr_info->f_mfast; - devfs_handle_t xconn_vhdl = pcibr_soft->bs_conn; + vertex_hdl_t xconn_vhdl = pcibr_soft->bs_conn; bridge_t *bridge = pcibr_soft->bs_base; int is_threaded = 0; @@ -498,25 +596,18 @@ pcibr_setpciint(xtalk_intr_t xtalk_intr) { iopaddr_t addr; xtalk_intr_vector_t vect; - devfs_handle_t vhdl; + vertex_hdl_t vhdl; bridge_t *bridge; + picreg_t *int_addr; addr = xtalk_intr_addr_get(xtalk_intr); vect = xtalk_intr_vector_get(xtalk_intr); vhdl = xtalk_intr_dev_get(xtalk_intr); bridge = (bridge_t *)xtalk_piotrans_addr(vhdl, 0, 0, sizeof(bridge_t), 0); - if (is_pic(bridge)) { - picreg_t *int_addr; - int_addr = (picreg_t *)xtalk_intr_sfarg_get(xtalk_intr); - *int_addr = ((PIC_INT_ADDR_FLD & ((uint64_t)vect << 48)) | + int_addr = (picreg_t *)xtalk_intr_sfarg_get(xtalk_intr); + *int_addr = ((PIC_INT_ADDR_FLD & ((uint64_t)vect << 48)) | (PIC_INT_ADDR_HOST & addr)); - } else { - bridgereg_t *int_addr; - int_addr = (bridgereg_t *)xtalk_intr_sfarg_get(xtalk_intr); - *int_addr = ((BRIDGE_INT_ADDR_HOST & (addr >> 30)) | - (BRIDGE_INT_ADDR_FLD & vect)); - } } /*ARGSUSED */ @@ -582,8 +673,7 @@ pcibr_intr_connect(pcibr_intr_t pcibr_intr, intr_func_t intr_func, intr_arg_t in PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_INTR_ALLOC, pcibr_intr->bi_dev, "pcibr_setpciint: int_addr=0x%x, *int_addr=0x%x, " "pcibr_int_bit=0x%x\n", int_addr, - (is_pic(bridge) ? - *(picreg_t *)int_addr : *(bridgereg_t *)int_addr), + *(picreg_t *)int_addr, pcibr_int_bit)); } @@ -699,7 +789,7 @@ pcibr_intr_disconnect(pcibr_intr_t pcibr_intr) xtalk_intr_connect(pcibr_soft->bs_intr[pcibr_int_bit].bsi_xtalk_intr, pcibr_intr_func, (intr_arg_t) intr_wrap, (xtalk_intr_setfunc_t)pcibr_setpciint, - (void *)pcibr_int_bit); + (void *)(long)pcibr_int_bit); PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_INTR_ALLOC, pcibr_intr->bi_dev, "pcibr_intr_disconnect: now-sharing int_bits=0x%x\n", pcibr_int_bit)); @@ -707,7 +797,7 @@ pcibr_intr_disconnect(pcibr_intr_t pcibr_intr) } /*ARGSUSED */ -devfs_handle_t +vertex_hdl_t pcibr_intr_cpu_get(pcibr_intr_t pcibr_intr) { pcibr_soft_t pcibr_soft = pcibr_intr->bi_soft; @@ -780,9 +870,6 @@ pcibr_setwidint(xtalk_intr_t intr) bridge->b_wid_int_lower = NEW_b_wid_int_lower; bridge->b_int_host_err = vect; -printk("pcibr_setwidint: b_wid_int_upper 0x%x b_wid_int_lower 0x%x b_int_host_err 0x%x\n", - NEW_b_wid_int_upper, NEW_b_wid_int_lower, vect); - } /* @@ -957,7 +1044,7 @@ pcibr_intr_func(intr_arg_t arg) * interrupt to avoid a potential deadlock situation. */ if (wrap->iw_hdlrcnt == 0) { - pcibr_force_interrupt(wrap); + pcibr_force_interrupt((pcibr_intr_t) wrap); } } diff --git a/arch/ia64/sn/io/sn2/pcibr/pcibr_rrb.c b/arch/ia64/sn/io/sn2/pcibr/pcibr_rrb.c index 3febeecaa10220..bafa7d7d303305 100644 --- a/arch/ia64/sn/io/sn2/pcibr/pcibr_rrb.c +++ b/arch/ia64/sn/io/sn2/pcibr/pcibr_rrb.c @@ -4,7 +4,7 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. * - * Copyright (C) 2001-2002 Silicon Graphics, Inc. All rights reserved. + * Copyright (C) 2001-2003 Silicon Graphics, Inc. All rights reserved. */ #include <linux/types.h> @@ -27,7 +27,6 @@ #include <asm/sn/prio.h> #include <asm/sn/xtalk/xbow.h> #include <asm/sn/ioc3.h> -#include <asm/sn/eeprom.h> #include <asm/sn/io.h> #include <asm/sn/sn_private.h> @@ -41,11 +40,11 @@ void do_pcibr_rrb_free_all(pcibr_soft_t, bridge_t *, pciio_slot_t); void do_pcibr_rrb_autoalloc(pcibr_soft_t, int, int, int); -int pcibr_wrb_flush(devfs_handle_t); -int pcibr_rrb_alloc(devfs_handle_t, int *, int *); -int pcibr_rrb_check(devfs_handle_t, int *, int *, int *, int *); -void pcibr_rrb_flush(devfs_handle_t); -int pcibr_slot_initial_rrb_alloc(devfs_handle_t,pciio_slot_t); +int pcibr_wrb_flush(vertex_hdl_t); +int pcibr_rrb_alloc(vertex_hdl_t, int *, int *); +int pcibr_rrb_check(vertex_hdl_t, int *, int *, int *, int *); +void pcibr_rrb_flush(vertex_hdl_t); +int pcibr_slot_initial_rrb_alloc(vertex_hdl_t,pciio_slot_t); void pcibr_rrb_debug(char *, pcibr_soft_t); @@ -70,17 +69,15 @@ void pcibr_rrb_debug(char *, pcibr_soft_t); #define RRB_SIZE (4) /* sizeof rrb within reg (bits) */ #define RRB_ENABLE_BIT(bridge) (0x8) /* [BRIDGE | PIC]_RRB_EN */ -#define NUM_PDEV_BITS(bridge) (is_pic((bridge)) ? 1 : 2) -#define NUM_VDEV_BITS(bridge) (is_pic((bridge)) ? 2 : 1) -#define NUMBER_VCHANNELS(bridge) (is_pic((bridge)) ? 4 : 2) +#define NUM_PDEV_BITS(bridge) (1) +#define NUM_VDEV_BITS(bridge) (2) +#define NUMBER_VCHANNELS(bridge) (4) #define SLOT_2_PDEV(bridge, slot) ((slot) >> 1) #define SLOT_2_RRB_REG(bridge, slot) ((slot) & 0x1) /* validate that the slot and virtual channel are valid for a given bridge */ #define VALIDATE_SLOT_n_VCHAN(bridge, s, v) \ - (is_pic((bridge)) ? \ - (((((s) != PCIIO_SLOT_NONE) && ((s) <= (pciio_slot_t)3)) && (((v) >= 0) && ((v) <= 3))) ? 1 : 0) : \ - (((((s) != PCIIO_SLOT_NONE) && ((s) <= (pciio_slot_t)7)) && (((v) >= 0) && ((v) <= 1))) ? 1 : 0)) + (((((s) != PCIIO_SLOT_NONE) && ((s) <= (pciio_slot_t)3)) && (((v) >= 0) && ((v) <= 3))) ? 1 : 0) /* * Count how many RRBs are marked valid for the specified PCI slot @@ -105,16 +102,7 @@ do_pcibr_rrb_count_valid(bridge_t *bridge, pdev_bits = SLOT_2_PDEV(bridge, slot); rrb_bits = enable_bit | vchan_bits | pdev_bits; - if ( is_pic(bridge) ) { - tmp = bridge->b_rrb_map[SLOT_2_RRB_REG(bridge, slot)].reg; - } - else { - if (io_get_sh_swapper(NASID_GET(bridge))) { - tmp = BRIDGE_REG_GET32((&bridge->b_rrb_map[SLOT_2_RRB_REG(bridge, slot)].reg)); - } else { - tmp = bridge->b_rrb_map[SLOT_2_RRB_REG(bridge, slot)].reg; - } - } + tmp = bridge->b_rrb_map[SLOT_2_RRB_REG(bridge, slot)].reg; for (rrb_index = 0; rrb_index < 8; rrb_index++) { if ((tmp & RRB_MASK) == rrb_bits) @@ -144,16 +132,7 @@ do_pcibr_rrb_count_avail(bridge_t *bridge, enable_bit = RRB_ENABLE_BIT(bridge); - if ( is_pic(bridge) ) { - tmp = bridge->b_rrb_map[SLOT_2_RRB_REG(bridge, slot)].reg; - } - else { - if (io_get_sh_swapper(NASID_GET(bridge))) { - tmp = BRIDGE_REG_GET32((&bridge->b_rrb_map[SLOT_2_RRB_REG(bridge, slot)].reg)); - } else { - tmp = bridge->b_rrb_map[SLOT_2_RRB_REG(bridge, slot)].reg; - } - } + tmp = bridge->b_rrb_map[SLOT_2_RRB_REG(bridge, slot)].reg; for (rrb_index = 0; rrb_index < 8; rrb_index++) { if ((tmp & enable_bit) != enable_bit) @@ -192,17 +171,8 @@ do_pcibr_rrb_alloc(bridge_t *bridge, pdev_bits = SLOT_2_PDEV(bridge, slot); rrb_bits = enable_bit | vchan_bits | pdev_bits; - if ( is_pic(bridge) ) { - reg = tmp = bridge->b_rrb_map[SLOT_2_RRB_REG(bridge, slot)].reg; - } - else { - if (io_get_sh_swapper(NASID_GET(bridge))) { - reg = tmp = BRIDGE_REG_GET32((&bridge->b_rrb_map[SLOT_2_RRB_REG(bridge, slot)].reg)); - } else { - reg = tmp = bridge->b_rrb_map[SLOT_2_RRB_REG(bridge, slot)].reg; - } - } - + reg = tmp = bridge->b_rrb_map[SLOT_2_RRB_REG(bridge, slot)].reg; + for (rrb_index = 0; ((rrb_index < 8) && (more > 0)); rrb_index++) { if ((tmp & enable_bit) != enable_bit) { /* clear the rrb and OR in the new rrb into 'reg' */ @@ -213,16 +183,7 @@ do_pcibr_rrb_alloc(bridge_t *bridge, tmp = (tmp >> RRB_SIZE); } - if ( is_pic(bridge) ) { - bridge->b_rrb_map[SLOT_2_RRB_REG(bridge, slot)].reg = reg; - } - else { - if (io_get_sh_swapper(NASID_GET(bridge))) { - BRIDGE_REG_SET32((&bridge->b_rrb_map[SLOT_2_RRB_REG(bridge, slot)].reg)) = reg; - } else { - bridge->b_rrb_map[SLOT_2_RRB_REG(bridge, slot)].reg = reg; - } - } + bridge->b_rrb_map[SLOT_2_RRB_REG(bridge, slot)].reg = reg; return (more ? -1 : 0); } @@ -255,17 +216,8 @@ do_pcibr_rrb_free(bridge_t *bridge, pdev_bits = SLOT_2_PDEV(bridge, slot); rrb_bits = enable_bit | vchan_bits | pdev_bits; - if ( is_pic(bridge) ) { - reg = tmp = bridge->b_rrb_map[SLOT_2_RRB_REG(bridge, slot)].reg; - } - else { - if (io_get_sh_swapper(NASID_GET(bridge))) { - reg = BRIDGE_REG_GET32((&bridge->b_rrb_map[SLOT_2_RRB_REG(bridge, slot)].reg)); - } else { - reg = tmp = bridge->b_rrb_map[SLOT_2_RRB_REG(bridge, slot)].reg; - } - } - + reg = tmp = bridge->b_rrb_map[SLOT_2_RRB_REG(bridge, slot)].reg; + for (rrb_index = 0; ((rrb_index < 8) && (less > 0)); rrb_index++) { if ((tmp & RRB_MASK) == rrb_bits) { /* @@ -281,16 +233,7 @@ do_pcibr_rrb_free(bridge_t *bridge, tmp = (tmp >> RRB_SIZE); } - if ( is_pic(bridge) ) { - bridge->b_rrb_map[SLOT_2_RRB_REG(bridge, slot)].reg = reg; - } - else { - if (io_get_sh_swapper(NASID_GET(bridge))) { - BRIDGE_REG_SET32((&bridge->b_rrb_map[SLOT_2_RRB_REG(bridge, slot)].reg)) = reg; - } else { - bridge->b_rrb_map[SLOT_2_RRB_REG(bridge, slot)].reg = reg; - } - } + bridge->b_rrb_map[SLOT_2_RRB_REG(bridge, slot)].reg = reg; /* call do_pcibr_rrb_clear() for all the rrbs we've freed */ for (rrb_index = 0; rrb_index < 8; rrb_index++) { @@ -337,50 +280,18 @@ do_pcibr_rrb_clear(bridge_t *bridge, int rrb) * this RRB must be disabled. */ - if ( is_pic(bridge) ) { - /* wait until RRB has no outstanduing XIO packets. */ - while ((status = bridge->b_resp_status) & BRIDGE_RRB_INUSE(rrb)) { - ; /* XXX- beats on bridge. bad idea? */ - } + /* wait until RRB has no outstanduing XIO packets. */ + while ((status = bridge->b_resp_status) & BRIDGE_RRB_INUSE(rrb)) { + ; /* XXX- beats on bridge. bad idea? */ + } - /* if the RRB has data, drain it. */ - if (status & BRIDGE_RRB_VALID(rrb)) { - bridge->b_resp_clear = BRIDGE_RRB_CLEAR(rrb); + /* if the RRB has data, drain it. */ + if (status & BRIDGE_RRB_VALID(rrb)) { + bridge->b_resp_clear = BRIDGE_RRB_CLEAR(rrb); - /* wait until RRB is no longer valid. */ - while ((status = bridge->b_resp_status) & BRIDGE_RRB_VALID(rrb)) { - ; /* XXX- beats on bridge. bad idea? */ - } - } - } - else { - if (io_get_sh_swapper(NASID_GET(bridge))) { - while ((status = BRIDGE_REG_GET32((&bridge->b_resp_status))) & BRIDGE_RRB_INUSE(rrb)) { - ; /* XXX- beats on bridge. bad idea? */ - } - - /* if the RRB has data, drain it. */ - if (status & BRIDGE_RRB_VALID(rrb)) { - BRIDGE_REG_SET32((&bridge->b_resp_clear)) = __swab32(BRIDGE_RRB_CLEAR(rrb)); - - /* wait until RRB is no longer valid. */ - while ((status = BRIDGE_REG_GET32((&bridge->b_resp_status))) & BRIDGE_RRB_VALID(rrb)) { - ; /* XXX- beats on bridge. bad idea? */ - } - } - } else { /* io_get_sh_swapper(NASID_GET(bridge)) */ - while ((status = bridge->b_resp_status) & BRIDGE_RRB_INUSE(rrb)) { - ; /* XXX- beats on bridge. bad idea? */ - } - - /* if the RRB has data, drain it. */ - if (status & BRIDGE_RRB_VALID(rrb)) { - bridge->b_resp_clear = BRIDGE_RRB_CLEAR(rrb); - /* wait until RRB is no longer valid. */ - while ((status = bridge->b_resp_status) & BRIDGE_RRB_VALID(rrb)) { - ; /* XXX- beats on bridge. bad idea? */ - } - } + /* wait until RRB is no longer valid. */ + while ((status = bridge->b_resp_status) & BRIDGE_RRB_VALID(rrb)) { + ; /* XXX- beats on bridge. bad idea? */ } } } @@ -399,43 +310,16 @@ do_pcibr_rrb_flush(bridge_t *bridge, int rrbn) int shft = (RRB_SIZE * (rrbn >> 1)); unsigned long ebit = RRB_ENABLE_BIT(bridge) << shft; - if ( is_pic(bridge) ) { - rrbv = *rrbp; - } - else { - if (io_get_sh_swapper(NASID_GET(bridge))) { - rrbv = BRIDGE_REG_GET32((&rrbp)); - } else { - rrbv = *rrbp; - } - } + rrbv = *rrbp; if (rrbv & ebit) { - if ( is_pic(bridge) ) { - *rrbp = rrbv & ~ebit; - } - else { - if (io_get_sh_swapper(NASID_GET(bridge))) { - BRIDGE_REG_SET32((&rrbp)) = __swab32((rrbv & ~ebit)); - } else { - *rrbp = rrbv & ~ebit; - } - } + *rrbp = rrbv & ~ebit; } do_pcibr_rrb_clear(bridge, rrbn); if (rrbv & ebit) { - if ( is_pic(bridge) ) { - *rrbp = rrbv; - } - else { - if (io_get_sh_swapper(NASID_GET(bridge))) { - BRIDGE_REG_SET32((&rrbp)) = __swab32(rrbv); - } else { - *rrbp = rrbv; - } - } + *rrbp = rrbv; } } @@ -475,7 +359,7 @@ do_pcibr_rrb_autoalloc(pcibr_soft_t pcibr_soft, * Flush all the rrb's assigned to the specified connection point. */ void -pcibr_rrb_flush(devfs_handle_t pconn_vhdl) +pcibr_rrb_flush(vertex_hdl_t pconn_vhdl) { pciio_info_t pciio_info = pciio_info_get(pconn_vhdl); pcibr_soft_t pcibr_soft = (pcibr_soft_t)pciio_info_mfast_get(pciio_info); @@ -510,7 +394,7 @@ pcibr_rrb_flush(devfs_handle_t pconn_vhdl) * device hanging off the bridge. */ int -pcibr_wrb_flush(devfs_handle_t pconn_vhdl) +pcibr_wrb_flush(vertex_hdl_t pconn_vhdl) { pciio_info_t pciio_info = pciio_info_get(pconn_vhdl); pciio_slot_t pciio_slot = PCIBR_INFO_SLOT_GET_INT(pciio_info); @@ -546,7 +430,7 @@ pcibr_wrb_flush(devfs_handle_t pconn_vhdl) * as best we can and return 0. */ int -pcibr_rrb_alloc(devfs_handle_t pconn_vhdl, +pcibr_rrb_alloc(vertex_hdl_t pconn_vhdl, int *count_vchan0, int *count_vchan1) { @@ -753,7 +637,7 @@ pcibr_rrb_alloc(devfs_handle_t pconn_vhdl, */ int -pcibr_rrb_check(devfs_handle_t pconn_vhdl, +pcibr_rrb_check(vertex_hdl_t pconn_vhdl, int *count_vchan0, int *count_vchan1, int *count_reserved, @@ -802,7 +686,7 @@ pcibr_rrb_check(devfs_handle_t pconn_vhdl, */ int -pcibr_slot_initial_rrb_alloc(devfs_handle_t pcibr_vhdl, +pcibr_slot_initial_rrb_alloc(vertex_hdl_t pcibr_vhdl, pciio_slot_t slot) { pcibr_soft_t pcibr_soft; @@ -889,7 +773,7 @@ rrb_reserved_free(pcibr_soft_t pcibr_soft, int slot) */ int -pcibr_initial_rrb(devfs_handle_t pcibr_vhdl, +pcibr_initial_rrb(vertex_hdl_t pcibr_vhdl, pciio_slot_t first, pciio_slot_t last) { pcibr_soft_t pcibr_soft = pcibr_soft_get(pcibr_vhdl); diff --git a/arch/ia64/sn/io/sn2/pcibr/pcibr_slot.c b/arch/ia64/sn/io/sn2/pcibr/pcibr_slot.c index 3d3fda15c7b3ac..de8d9a19dd63f9 100644 --- a/arch/ia64/sn/io/sn2/pcibr/pcibr_slot.c +++ b/arch/ia64/sn/io/sn2/pcibr/pcibr_slot.c @@ -4,7 +4,7 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. * - * Copyright (C) 2001-2002 Silicon Graphics, Inc. All rights reserved. + * Copyright (C) 2001-2003 Silicon Graphics, Inc. All rights reserved. */ #include <linux/types.h> @@ -28,7 +28,6 @@ #include <asm/sn/prio.h> #include <asm/sn/xtalk/xbow.h> #include <asm/sn/ioc3.h> -#include <asm/sn/eeprom.h> #include <asm/sn/io.h> #include <asm/sn/sn_private.h> #include <asm/sn/ate_utils.h> @@ -41,42 +40,41 @@ #endif -extern pcibr_info_t pcibr_info_get(devfs_handle_t); -extern int pcibr_widget_to_bus(devfs_handle_t pcibr_vhdl); +extern pcibr_info_t pcibr_info_get(vertex_hdl_t); +extern int pcibr_widget_to_bus(vertex_hdl_t pcibr_vhdl); extern pcibr_info_t pcibr_device_info_new(pcibr_soft_t, pciio_slot_t, pciio_function_t, pciio_vendor_id_t, pciio_device_id_t); -extern int pcibr_slot_initial_rrb_alloc(devfs_handle_t,pciio_slot_t); +extern int pcibr_slot_initial_rrb_alloc(vertex_hdl_t,pciio_slot_t); extern int pcibr_pcix_rbars_calc(pcibr_soft_t); -int pcibr_slot_info_init(devfs_handle_t pcibr_vhdl, pciio_slot_t slot); -int pcibr_slot_info_free(devfs_handle_t pcibr_vhdl, pciio_slot_t slot); -int pcibr_slot_addr_space_init(devfs_handle_t pcibr_vhdl, pciio_slot_t slot); +int pcibr_slot_info_init(vertex_hdl_t pcibr_vhdl, pciio_slot_t slot); +int pcibr_slot_info_free(vertex_hdl_t pcibr_vhdl, pciio_slot_t slot); +int pcibr_slot_addr_space_init(vertex_hdl_t pcibr_vhdl, pciio_slot_t slot); int pcibr_slot_pcix_rbar_init(pcibr_soft_t pcibr_soft, pciio_slot_t slot); -int pcibr_slot_device_init(devfs_handle_t pcibr_vhdl, pciio_slot_t slot); -int pcibr_slot_guest_info_init(devfs_handle_t pcibr_vhdl, pciio_slot_t slot); -int pcibr_slot_call_device_attach(devfs_handle_t pcibr_vhdl, +int pcibr_slot_device_init(vertex_hdl_t pcibr_vhdl, pciio_slot_t slot); +int pcibr_slot_guest_info_init(vertex_hdl_t pcibr_vhdl, pciio_slot_t slot); +int pcibr_slot_call_device_attach(vertex_hdl_t pcibr_vhdl, pciio_slot_t slot, int drv_flags); -int pcibr_slot_call_device_detach(devfs_handle_t pcibr_vhdl, +int pcibr_slot_call_device_detach(vertex_hdl_t pcibr_vhdl, pciio_slot_t slot, int drv_flags); -int pcibr_slot_detach(devfs_handle_t pcibr_vhdl, pciio_slot_t slot, +int pcibr_slot_detach(vertex_hdl_t pcibr_vhdl, pciio_slot_t slot, int drv_flags, char *l1_msg, int *sub_errorp); -int pcibr_is_slot_sys_critical(devfs_handle_t pcibr_vhdl, pciio_slot_t slot); static int pcibr_probe_slot(bridge_t *, cfg_p, unsigned int *); -void pcibr_device_info_free(devfs_handle_t, pciio_slot_t); +void pcibr_device_info_free(vertex_hdl_t, pciio_slot_t); iopaddr_t pcibr_bus_addr_alloc(pcibr_soft_t, pciio_win_info_t, pciio_space_t, int, int, int); void pciibr_bus_addr_free(pcibr_soft_t, pciio_win_info_t); cfg_p pcibr_find_capability(cfg_p, unsigned); -extern uint64_t do_pcibr_config_get(int, cfg_p, unsigned, unsigned); -void do_pcibr_config_set(int, cfg_p, unsigned, unsigned, uint64_t); +extern uint64_t do_pcibr_config_get(cfg_p, unsigned, unsigned); +void do_pcibr_config_set(cfg_p, unsigned, unsigned, uint64_t); -int pcibr_slot_attach(devfs_handle_t pcibr_vhdl, pciio_slot_t slot, +int pcibr_slot_attach(vertex_hdl_t pcibr_vhdl, pciio_slot_t slot, int drv_flags, char *l1_msg, int *sub_errorp); int pcibr_slot_info_return(pcibr_soft_t pcibr_soft, pciio_slot_t slot, pcibr_slot_info_resp_t respp); -extern devfs_handle_t baseio_pci_vhdl; -int scsi_ctlr_nums_add(devfs_handle_t, devfs_handle_t); +extern vertex_hdl_t baseio_pci_vhdl; +int scsi_ctlr_nums_add(vertex_hdl_t, vertex_hdl_t); /* For now .... */ @@ -111,7 +109,7 @@ int max_readcount_to_bufsize[MAX_READCNT_TABLE] = {512, 1024, 2048, 4096 }; #ifdef PIC_LATER int -pcibr_slot_startup(devfs_handle_t pcibr_vhdl, pcibr_slot_req_t reqp) +pcibr_slot_startup(vertex_hdl_t pcibr_vhdl, pcibr_slot_req_t reqp) { pcibr_soft_t pcibr_soft = pcibr_soft_get(pcibr_vhdl); pciio_slot_t slot; @@ -127,11 +125,6 @@ pcibr_slot_startup(devfs_handle_t pcibr_vhdl, pcibr_slot_req_t reqp) /* req_slot is the 'external' slot number, convert for internal use */ slot = PCIBR_SLOT_TO_DEVICE(pcibr_soft, reqp->req_slot); - /* Do not allow start-up of a slot in a shoehorn */ - if(nic_vertex_info_match(pcibr_soft->bs_conn, XTALK_PCI_PART_NUM)) { - return(PCI_SLOT_IN_SHOEHORN); - } - /* Check for the valid slot */ if (!PCIBR_VALID_SLOT(pcibr_soft, slot)) return(PCI_NOT_A_SLOT); @@ -170,7 +163,7 @@ pcibr_slot_startup(devfs_handle_t pcibr_vhdl, pcibr_slot_req_t reqp) * Software shut-down the PCI slot */ int -pcibr_slot_shutdown(devfs_handle_t pcibr_vhdl, pcibr_slot_req_t reqp) +pcibr_slot_shutdown(vertex_hdl_t pcibr_vhdl, pcibr_slot_req_t reqp) { pcibr_soft_t pcibr_soft = pcibr_soft_get(pcibr_vhdl); bridge_t *bridge; @@ -194,11 +187,6 @@ pcibr_slot_shutdown(devfs_handle_t pcibr_vhdl, pcibr_slot_req_t reqp) if (!PCIBR_VALID_SLOT(pcibr_soft, slot)) return(PCI_NOT_A_SLOT); - /* Do not allow shut-down of a slot in a shoehorn */ - if(nic_vertex_info_match(pcibr_soft->bs_conn, XTALK_PCI_PART_NUM)) { - return(PCI_SLOT_IN_SHOEHORN); - } - #ifdef PIC_LATER /* Acquire update access to the bus */ mrlock(pcibr_soft->bs_bus_lock, MR_UPDATE, PZERO); @@ -284,7 +272,6 @@ pcibr_slot_func_info_return(pcibr_info_h pcibr_infoh, { pcibr_info_t pcibr_info = pcibr_infoh[func]; int win; - boolean_t is_sys_critical_vertex(devfs_handle_t); funcp->resp_f_status = 0; @@ -296,9 +283,6 @@ pcibr_slot_func_info_return(pcibr_info_h pcibr_infoh, #if defined(SUPPORT_PRINTING_V_FORMAT) sprintf(funcp->resp_f_slot_name, "%v", pcibr_info->f_vertex); #endif - if(is_sys_critical_vertex(pcibr_info->f_vertex)) { - funcp->resp_f_status |= FUNC_IS_SYS_CRITICAL; - } funcp->resp_f_bus = pcibr_info->f_bus; funcp->resp_f_slot = PCIBR_INFO_SLOT_GET_EXT(pcibr_info); @@ -345,7 +329,6 @@ pcibr_slot_info_return(pcibr_soft_t pcibr_soft, reg_p b_respp; pcibr_slot_info_resp_t slotp; pcibr_slot_func_info_resp_t funcp; - boolean_t is_sys_critical_vertex(devfs_handle_t); extern void snia_kmem_free(void *, int); slotp = snia_kmem_zalloc(sizeof(*slotp), 0); @@ -368,11 +351,6 @@ pcibr_slot_info_return(pcibr_soft_t pcibr_soft, slotp->resp_slot_status = pss->slot_status; slotp->resp_l1_bus_num = pcibr_widget_to_bus(pcibr_soft->bs_vhdl); - - if (is_sys_critical_vertex(pss->slot_conn)) { - slotp->resp_slot_status |= SLOT_IS_SYS_CRITICAL; - } - slotp->resp_bss_ninfo = pss->bss_ninfo; for (func = 0; func < pss->bss_ninfo; func++) { @@ -455,7 +433,7 @@ pcibr_slot_info_return(pcibr_soft_t pcibr_soft, * External SSRAM workaround info */ int -pcibr_slot_query(devfs_handle_t pcibr_vhdl, pcibr_slot_req_t reqp) +pcibr_slot_query(vertex_hdl_t pcibr_vhdl, pcibr_slot_req_t reqp) { pcibr_soft_t pcibr_soft = pcibr_soft_get(pcibr_vhdl); pciio_slot_t slot; @@ -481,11 +459,6 @@ pcibr_slot_query(devfs_handle_t pcibr_vhdl, pcibr_slot_req_t reqp) return(PCI_NOT_A_SLOT); } - /* Do not allow a query of a slot in a shoehorn */ - if(nic_vertex_info_match(pcibr_soft->bs_conn, XTALK_PCI_PART_NUM)) { - return(PCI_SLOT_IN_SHOEHORN); - } - /* Return information for the requested PCI slot */ if (slot != PCIIO_SLOT_NONE) { if (size < sizeof(*respp)) { @@ -534,88 +507,6 @@ pcibr_slot_query(devfs_handle_t pcibr_vhdl, pcibr_slot_req_t reqp) return(error); } -#if 0 -/* - * pcibr_slot_reset - * Reset the PCI device in the particular slot. - * - * The Xbridge does not comply with the PCI Specification - * when resetting an indiviaudl slot. An individual slot is - * is reset by toggling the slot's bit in the Xbridge Control - * Register. The Xbridge will assert the target slot's - * (non-bussed) RST signal, but does not assert the (bussed) - * REQ64 signal as required by the specification. As - * designed, the Xbridge cannot assert the REQ64 signal - * becuase it may interfere with a bus transaction in progress. - * The practical effects of this Xbridge implementation is - * device dependent; it probably will not adversely effect - * 32-bit cards, but may disable 64-bit data transfers by those - * cards that normally support 64-bit data transfers. - * - * The Xbridge will assert REQ64 when all four slots are reset - * by simultaneously toggling all four slot reset bits in the - * Xbridge Control Register. This is basically a PCI bus reset - * and asserting the (bussed) REQ64 signal will not interfere - * with any bus transactions in progress. - * - * The Xbridge (and the SN0 Bridge) support resetting only - * four PCI bus slots via the (X)bridge Control Register. - * - * To reset an individual slot for the PCI Hot-Plug feature - * use the L1 console commands to power-down and then - * power-up the slot, or use the kernel infrastructure - * functions to power-down/up the slot when they are - * implemented for SN1. - */ -int -pcibr_slot_reset(devfs_handle_t pcibr_vhdl, pciio_slot_t slot) -{ - pcibr_soft_t pcibr_soft = pcibr_soft_get(pcibr_vhdl); - bridge_t *bridge; - bridgereg_t ctrlreg,tmp; - volatile bridgereg_t *wrb_flush; - - if (!pcibr_soft) - return(EINVAL); - - if (!PCIBR_VALID_SLOT(pcibr_soft, slot)) - return(EINVAL); - - /* Enable the DMA operations from this device of the xtalk widget - * (PCI host bridge in this case). - */ - xtalk_widgetdev_enable(pcibr_soft->bs_conn, slot); - - /* Set the reset slot bit in the bridge's wid control register - * to reset the PCI slot - */ - bridge = pcibr_soft->bs_base; - - /* Read the bridge widget control and clear out the reset pin - * bit for the corresponding slot. - */ - tmp = ctrlreg = bridge->b_wid_control; - - tmp &= ~BRIDGE_CTRL_RST_PIN(slot); - - bridge->b_wid_control = tmp; - tmp = bridge->b_wid_control; - - /* Restore the old control register back. - * NOTE : PCI card gets reset when the reset pin bit - * changes from 0 (set above) to 1 (going to be set now). - */ - - bridge->b_wid_control = ctrlreg; - - /* Flush the write buffers if any !! */ - wrb_flush = &(bridge->b_wr_req_buf[slot].reg); - while (*wrb_flush); - - return(0); -} -#endif - #define PROBE_LOCK 0 /* FIXME: we're attempting to lock around accesses * to b_int_enable. This hangs pcibr_probe_slot() */ @@ -627,7 +518,7 @@ pcibr_slot_reset(devfs_handle_t pcibr_vhdl, pciio_slot_t slot) * information associated with this particular PCI device. */ int -pcibr_slot_info_init(devfs_handle_t pcibr_vhdl, +pcibr_slot_info_init(vertex_hdl_t pcibr_vhdl, pciio_slot_t slot) { pcibr_soft_t pcibr_soft; @@ -650,7 +541,7 @@ pcibr_slot_info_init(devfs_handle_t pcibr_vhdl, int nfunc; pciio_function_t rfunc; int func; - devfs_handle_t conn_vhdl; + vertex_hdl_t conn_vhdl; pcibr_soft_slot_t slotp; /* Get the basic software information required to proceed */ @@ -669,10 +560,6 @@ pcibr_slot_info_init(devfs_handle_t pcibr_vhdl, return(0); } - /* Check for a slot with any system critical functions */ - if (pcibr_is_slot_sys_critical(pcibr_vhdl, slot)) - return(EPERM); - /* Try to read the device-id/vendor-id from the config space */ cfgw = pcibr_slot_config_addr(bridge, slot, 0); @@ -701,7 +588,7 @@ pcibr_slot_info_init(devfs_handle_t pcibr_vhdl, if (vendor == 0xFFFF) return(ENODEV); - htype = do_pcibr_config_get(IS_PIC_SOFT(pcibr_soft), cfgw, PCI_CFG_HEADER_TYPE, 1); + htype = do_pcibr_config_get(cfgw, PCI_CFG_HEADER_TYPE, 1); nfunc = 1; rfunc = PCIIO_FUNC_NONE; pfail = 0; @@ -750,7 +637,7 @@ pcibr_slot_info_init(devfs_handle_t pcibr_vhdl, cfgw = pcibr_func_config_addr(bridge, 0, slot, func, 0); device = 0xFFFF & (idword >> 16); - htype = do_pcibr_config_get(IS_PIC_SOFT(pcibr_soft), cfgw, PCI_CFG_HEADER_TYPE, 1); + htype = do_pcibr_config_get(cfgw, PCI_CFG_HEADER_TYPE, 1); rfunc = func; } htype &= 0x7f; @@ -810,16 +697,10 @@ pcibr_slot_info_init(devfs_handle_t pcibr_vhdl, * Timer for these devices */ - lt_time = do_pcibr_config_get(IS_PIC_SOFT(pcibr_soft), cfgw, PCI_CFG_LATENCY_TIMER, 1); + lt_time = do_pcibr_config_get(cfgw, PCI_CFG_LATENCY_TIMER, 1); if ((lt_time == 0) && !(bridge->b_device[slot].reg & BRIDGE_DEV_RT) && - !((vendor == IOC3_VENDOR_ID_NUM) && - ( -#ifdef PIC_LATER - (device == IOC3_DEVICE_ID_NUM) || - (device == LINC_DEVICE_ID_NUM) || -#endif - (device == 0x5 /* RAD_DEV */)))) { + (device == 0x5 /* RAD_DEV */)) { unsigned min_gnt; unsigned min_gnt_mult; @@ -827,7 +708,7 @@ pcibr_slot_info_init(devfs_handle_t pcibr_vhdl, * needs in increments of 250ns. But latency timer is in * PCI clock cycles, so a conversion is needed. */ - min_gnt = do_pcibr_config_get(IS_PIC_SOFT(pcibr_soft), cfgw, PCI_MIN_GNT, 1); + min_gnt = do_pcibr_config_get(cfgw, PCI_MIN_GNT, 1); if (IS_133MHZ(pcibr_soft)) min_gnt_mult = 32; /* 250ns @ 133MHz in clocks */ @@ -843,7 +724,7 @@ pcibr_slot_info_init(devfs_handle_t pcibr_vhdl, else lt_time = 4 * min_gnt_mult; /* 1 micro second */ - do_pcibr_config_set(IS_PIC_SOFT(pcibr_soft), cfgw, PCI_CFG_LATENCY_TIMER, 1, lt_time); + do_pcibr_config_set(cfgw, PCI_CFG_LATENCY_TIMER, 1, lt_time); PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_CONFIG, pcibr_vhdl, "pcibr_slot_info_init: set Latency Timer for slot=%d, " @@ -851,12 +732,27 @@ pcibr_slot_info_init(devfs_handle_t pcibr_vhdl, PCIBR_DEVICE_TO_SLOT(pcibr_soft, slot), func, lt_time)); } - /* Get the PCI-X capability if running in PCI-X mode. If the func - * doesn't have a pcix capability, allocate a PCIIO_VENDOR_ID_NONE - * pcibr_info struct so the device driver for that function is not - * called. + + /* In our architecture the setting of the cacheline size isn't + * beneficial for cards in PCI mode, but in PCI-X mode devices + * can optionally use the cacheline size value for internal + * device optimizations (See 7.1.5 of the PCI-X v1.0 spec). + * NOTE: cachline size is in doubleword increments */ if (IS_PCIX(pcibr_soft)) { + if (!do_pcibr_config_get(cfgw, PCI_CFG_CACHE_LINE, 1)) { + do_pcibr_config_set(cfgw, PCI_CFG_CACHE_LINE, 1, 0x20); + PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_CONFIG, pcibr_vhdl, + "pcibr_slot_info_init: set CacheLine for slot=%d, " + "func=%d, to 0x20\n", + PCIBR_DEVICE_TO_SLOT(pcibr_soft, slot), func)); + } + + /* Get the PCI-X capability if running in PCI-X mode. If the func + * doesnt have a pcix capability, allocate a PCIIO_VENDOR_ID_NONE + * pcibr_info struct so the device driver for that function is not + * called. + */ if (!(pcix_cap = pcibr_find_capability(cfgw, PCI_CAP_PCIX))) { printk(KERN_WARNING #if defined(SUPPORT_PRINTING_V_FORMAT) @@ -898,7 +794,7 @@ pcibr_slot_info_init(devfs_handle_t pcibr_vhdl, if (func == 0) slotp->slot_conn = conn_vhdl; - cmd_reg = do_pcibr_config_get(IS_PIC_SOFT(pcibr_soft), cfgw, PCI_CFG_COMMAND, 4); + cmd_reg = do_pcibr_config_get(cfgw, PCI_CFG_COMMAND, 4); wptr = cfgw + PCI_CFG_BASE_ADDR_0 / 4; @@ -949,7 +845,7 @@ pcibr_slot_info_init(devfs_handle_t pcibr_vhdl, * this could be pushed up into pciio, when we * start supporting more PCI providers. */ - base = do_pcibr_config_get(IS_PIC_SOFT(pcibr_soft), wptr, (win * 4), 4); + base = do_pcibr_config_get(wptr, (win * 4), 4); if (base & PCI_BA_IO_SPACE) { /* BASE is in I/O space. */ @@ -975,7 +871,7 @@ pcibr_slot_info_init(devfs_handle_t pcibr_vhdl, } else if (base & 0xC0000000) { base = 0; /* outside permissable range */ } else if ((code == PCI_BA_MEM_64BIT) && - (do_pcibr_config_get(IS_PIC_SOFT(pcibr_soft), wptr, ((win + 1)*4), 4) != 0)) { + (do_pcibr_config_get(wptr, ((win + 1)*4), 4) != 0)) { base = 0; /* outside permissable range */ } } @@ -983,8 +879,8 @@ pcibr_slot_info_init(devfs_handle_t pcibr_vhdl, if (base != 0) { /* estimate size */ size = base & -base; } else { /* calculate size */ - do_pcibr_config_set(IS_PIC_SOFT(pcibr_soft), wptr, (win * 4), 4, ~0); /* write 1's */ - size = do_pcibr_config_get(IS_PIC_SOFT(pcibr_soft), wptr, (win * 4), 4); /* read back */ + do_pcibr_config_set(wptr, (win * 4), 4, ~0); /* write 1's */ + size = do_pcibr_config_get(wptr, (win * 4), 4); /* read back */ size &= mask; /* keep addr */ size &= -size; /* keep lsbit */ if (size == 0) @@ -995,45 +891,9 @@ pcibr_slot_info_init(devfs_handle_t pcibr_vhdl, pcibr_info->f_window[win].w_base = base; pcibr_info->f_window[win].w_size = size; -#if defined(IOC3_VENDOR_ID_NUM) && defined(IOC3_DEVICE_ID_NUM) - /* - * IOC3 BASE_ADDR* BUG WORKAROUND - * - - * If we write to BASE1 on the IOC3, the - * data in BASE0 is replaced. The - * original workaround was to remember - * the value of BASE0 and restore it - * when we ran off the end of the BASE - * registers; however, a later - * workaround was added (I think it was - * rev 1.44) to avoid setting up - * anything but BASE0, with the comment - * that writing all ones to BASE1 set - * the enable-parity-error test feature - * in IOC3's SCR bit 14. - * - * So, unless we defer doing any PCI - * space allocation until drivers - * attach, and set up a way for drivers - * (the IOC3 in paricular) to tell us - * generically to keep our hands off - * BASE registers, we gotta "know" about - * the IOC3 here. - * - * Too bad the PCI folks didn't reserve the - * all-zero value for 'no BASE here' (it is a - * valid code for an uninitialized BASE in - * 32-bit PCI memory space). - */ - - if ((vendor == IOC3_VENDOR_ID_NUM) && - (device == IOC3_DEVICE_ID_NUM)) - break; -#endif if (code == PCI_BA_MEM_64BIT) { win++; /* skip upper half */ - do_pcibr_config_set(IS_PIC_SOFT(pcibr_soft), wptr, (win * 4), 4, 0); /* must be zero */ + do_pcibr_config_set(wptr, (win * 4), 4, 0); /* must be zero */ } } /* next win */ } /* next func */ @@ -1056,7 +916,7 @@ pcibr_find_capability(cfg_p cfgw, int defend_against_circular_linkedlist = 0; /* Check to see if there is a capabilities pointer in the cfg header */ - if (!(do_pcibr_config_get(1, cfgw, PCI_CFG_STATUS, 2) & PCI_STAT_CAP_LIST)) { + if (!(do_pcibr_config_get(cfgw, PCI_CFG_STATUS, 2) & PCI_STAT_CAP_LIST)) { return (NULL); } @@ -1067,14 +927,14 @@ pcibr_find_capability(cfg_p cfgw, * significant bits of the next pointer must be ignored, so we mask * with 0xfc). */ - cap_nxt = (do_pcibr_config_get(1, cfgw, PCI_CAPABILITIES_PTR, 1) & 0xfc); + cap_nxt = (do_pcibr_config_get(cfgw, PCI_CAPABILITIES_PTR, 1) & 0xfc); while (cap_nxt && (defend_against_circular_linkedlist <= 48)) { - cap_id = do_pcibr_config_get(1, cfgw, cap_nxt, 1); + cap_id = do_pcibr_config_get(cfgw, cap_nxt, 1); if (cap_id == capability) { return ((cfg_p)((char *)cfgw + cap_nxt)); } - cap_nxt = (do_pcibr_config_get(1, cfgw, cap_nxt+1, 1) & 0xfc); + cap_nxt = (do_pcibr_config_get(cfgw, cap_nxt+1, 1) & 0xfc); defend_against_circular_linkedlist++; } @@ -1087,7 +947,7 @@ pcibr_find_capability(cfg_p cfgw, * with a particular PCI device. */ int -pcibr_slot_info_free(devfs_handle_t pcibr_vhdl, +pcibr_slot_info_free(vertex_hdl_t pcibr_vhdl, pciio_slot_t slot) { pcibr_soft_t pcibr_soft; @@ -1223,20 +1083,21 @@ int as_debug = 0; * the base registers in the card. */ int -pcibr_slot_addr_space_init(devfs_handle_t pcibr_vhdl, +pcibr_slot_addr_space_init(vertex_hdl_t pcibr_vhdl, pciio_slot_t slot) { pcibr_soft_t pcibr_soft; pcibr_info_h pcibr_infoh; pcibr_info_t pcibr_info; bridge_t *bridge; - size_t align_slot; iopaddr_t mask; int nbars; int nfunc; int func; int win; int rc = 0; + int align; + int align_slot; pcibr_soft = pcibr_soft_get(pcibr_vhdl); @@ -1275,7 +1136,8 @@ pcibr_slot_addr_space_init(devfs_handle_t pcibr_vhdl, * the entire "lo" area is only a * megabyte, total ... */ - align_slot = (slot < 2) ? 0x200000 : 0x100000; + align_slot = 0x100000; + align = align_slot; for (func = 0; func < nfunc; ++func) { cfg_p cfgw; @@ -1300,7 +1162,7 @@ pcibr_slot_addr_space_init(devfs_handle_t pcibr_vhdl, cfgw = pcibr_func_config_addr(bridge, 0, slot, func, 0); wptr = cfgw + PCI_CFG_BASE_ADDR_0 / 4; - if ((do_pcibr_config_get(IS_PIC_SOFT(pcibr_soft), cfgw, PCI_CFG_HEADER_TYPE, 1) & 0x7f) != 0) + if ((do_pcibr_config_get(cfgw, PCI_CFG_HEADER_TYPE, 1) & 0x7f) != 0) nbars = 2; else nbars = PCI_CFG_BASE_ADDRS; @@ -1333,23 +1195,24 @@ pcibr_slot_addr_space_init(devfs_handle_t pcibr_vhdl, continue; /* already allocated */ } + align = (win) ? size : align_slot; + + if (align < _PAGESZ) + align = _PAGESZ; /* ie. 0x00004000 */ + switch (space) { case PCIIO_SPACE_IO: base = pcibr_bus_addr_alloc(pcibr_soft, &pcibr_info->f_window[win], PCIIO_SPACE_IO, - 0, size, align_slot); + 0, size, align); if (!base) rc = ENOSPC; break; case PCIIO_SPACE_MEM: - if ((do_pcibr_config_get(IS_PIC_SOFT(pcibr_soft), wptr, (win * 4), 4) & + if ((do_pcibr_config_get(wptr, (win * 4), 4) & PCI_BA_MEM_LOCATION) == PCI_BA_MEM_1MEG) { - int align = size; /* ie. 0x00001000 */ - - if (align < _PAGESZ) - align = _PAGESZ; /* ie. 0x00004000 */ /* allocate from 20-bit PCI space */ base = pcibr_bus_addr_alloc(pcibr_soft, @@ -1363,7 +1226,7 @@ pcibr_slot_addr_space_init(devfs_handle_t pcibr_vhdl, base = pcibr_bus_addr_alloc(pcibr_soft, &pcibr_info->f_window[win], PCIIO_SPACE_MEM32, - 0, size, align_slot); + 0, size, align); if (!base) rc = ENOSPC; } @@ -1377,7 +1240,7 @@ pcibr_slot_addr_space_init(devfs_handle_t pcibr_vhdl, PCIBR_DEVICE_TO_SLOT(pcibr_soft,slot), win, space)); } pcibr_info->f_window[win].w_base = base; - do_pcibr_config_set(IS_PIC_SOFT(pcibr_soft), wptr, (win * 4), 4, base); + do_pcibr_config_set(wptr, (win * 4), 4, base); #if defined(SUPPORT_PRINTING_R_FORMAT) if (pcibr_debug_mask & PCIBR_DEBUG_BAR) { @@ -1405,26 +1268,22 @@ pcibr_slot_addr_space_init(devfs_handle_t pcibr_vhdl, /* * Allocate space for the EXPANSION ROM - * NOTE: DO NOT DO THIS ON AN IOC3, - * as it blows the system away. */ base = size = 0; - if ((pcibr_soft->bs_slot[slot].bss_vendor_id != IOC3_VENDOR_ID_NUM) || - (pcibr_soft->bs_slot[slot].bss_device_id != IOC3_DEVICE_ID_NUM)) { - + { wptr = cfgw + PCI_EXPANSION_ROM / 4; - do_pcibr_config_set(IS_PIC_SOFT(pcibr_soft), wptr, 0, 4, 0xFFFFF000); - mask = do_pcibr_config_get(IS_PIC_SOFT(pcibr_soft), wptr, 0, 4); + do_pcibr_config_set(wptr, 0, 4, 0xFFFFF000); + mask = do_pcibr_config_get(wptr, 0, 4); if (mask & 0xFFFFF000) { size = mask & -mask; base = pcibr_bus_addr_alloc(pcibr_soft, &pcibr_info->f_rwindow, PCIIO_SPACE_MEM32, - 0, size, align_slot); + 0, size, align); if (!base) rc = ENOSPC; else { - do_pcibr_config_set(IS_PIC_SOFT(pcibr_soft), wptr, 0, 4, base); + do_pcibr_config_set(wptr, 0, 4, base); PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_BAR, pcibr_vhdl, "pcibr_slot_addr_space_init: slot=%d, func=%d, " "ROM in [0x%X..0x%X], allocated by pcibr\n", @@ -1435,7 +1294,7 @@ pcibr_slot_addr_space_init(devfs_handle_t pcibr_vhdl, } pcibr_info->f_rbase = base; pcibr_info->f_rsize = size; - + /* * if necessary, update the board's * command register to enable decoding @@ -1463,7 +1322,7 @@ pcibr_slot_addr_space_init(devfs_handle_t pcibr_vhdl, pci_cfg_cmd_reg_add |= PCI_CMD_BUS_MASTER; - pci_cfg_cmd_reg = do_pcibr_config_get(IS_PIC_SOFT(pcibr_soft), cfgw, PCI_CFG_COMMAND, 4); + pci_cfg_cmd_reg = do_pcibr_config_get(cfgw, PCI_CFG_COMMAND, 4); #if PCI_FBBE /* XXX- check here to see if dev can do fast-back-to-back */ if (!((pci_cfg_cmd_reg >> 16) & PCI_STAT_F_BK_BK_CAP)) @@ -1471,7 +1330,7 @@ pcibr_slot_addr_space_init(devfs_handle_t pcibr_vhdl, #endif pci_cfg_cmd_reg &= 0xFFFF; if (pci_cfg_cmd_reg_add & ~pci_cfg_cmd_reg) - do_pcibr_config_set(IS_PIC_SOFT(pcibr_soft), cfgw, PCI_CFG_COMMAND, 4, + do_pcibr_config_set(cfgw, PCI_CFG_COMMAND, 4, pci_cfg_cmd_reg | pci_cfg_cmd_reg_add); } /* next func */ return(rc); @@ -1483,7 +1342,7 @@ pcibr_slot_addr_space_init(devfs_handle_t pcibr_vhdl, */ int -pcibr_slot_device_init(devfs_handle_t pcibr_vhdl, +pcibr_slot_device_init(vertex_hdl_t pcibr_vhdl, pciio_slot_t slot) { pcibr_soft_t pcibr_soft; @@ -1525,8 +1384,6 @@ pcibr_slot_device_init(devfs_handle_t pcibr_vhdl, PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_DEVREG, pcibr_vhdl, "pcibr_slot_device_init: Device(%d): %R\n", slot, devreg, device_bits)); -#else - printk("pcibr_slot_device_init: Device(%d) 0x%x\n", slot, devreg); #endif return(0); } @@ -1536,7 +1393,7 @@ pcibr_slot_device_init(devfs_handle_t pcibr_vhdl, * Setup the host/guest relations for a PCI slot. */ int -pcibr_slot_guest_info_init(devfs_handle_t pcibr_vhdl, +pcibr_slot_guest_info_init(vertex_hdl_t pcibr_vhdl, pciio_slot_t slot) { pcibr_soft_t pcibr_soft; @@ -1605,18 +1462,17 @@ pcibr_slot_guest_info_init(devfs_handle_t pcibr_vhdl, * card in this slot. */ int -pcibr_slot_call_device_attach(devfs_handle_t pcibr_vhdl, +pcibr_slot_call_device_attach(vertex_hdl_t pcibr_vhdl, pciio_slot_t slot, int drv_flags) { pcibr_soft_t pcibr_soft; pcibr_info_h pcibr_infoh; pcibr_info_t pcibr_info; - async_attach_t aa = NULL; int func; - devfs_handle_t xconn_vhdl, conn_vhdl; + vertex_hdl_t xconn_vhdl, conn_vhdl; #ifdef PIC_LATER - devfs_handle_t scsi_vhdl; + vertex_hdl_t scsi_vhdl; #endif int nfunc; int error_func; @@ -1639,7 +1495,6 @@ pcibr_slot_call_device_attach(devfs_handle_t pcibr_vhdl, } xconn_vhdl = pcibr_soft->bs_conn; - aa = async_attach_get_info(xconn_vhdl); nfunc = pcibr_soft->bs_slot[slot].bss_ninfo; pcibr_infoh = pcibr_soft->bs_slot[slot].bss_infos; @@ -1656,13 +1511,6 @@ pcibr_slot_call_device_attach(devfs_handle_t pcibr_vhdl, conn_vhdl = pcibr_info->f_vertex; -#ifdef LATER - /* - * Activate if and when we support cdl. - */ - if (aa) - async_attach_add_info(conn_vhdl, aa); -#endif /* LATER */ error_func = pciio_device_attach(conn_vhdl, drv_flags); @@ -1728,7 +1576,7 @@ pcibr_slot_call_device_attach(devfs_handle_t pcibr_vhdl, * card in this slot. */ int -pcibr_slot_call_device_detach(devfs_handle_t pcibr_vhdl, +pcibr_slot_call_device_detach(vertex_hdl_t pcibr_vhdl, pciio_slot_t slot, int drv_flags) { @@ -1736,7 +1584,7 @@ pcibr_slot_call_device_detach(devfs_handle_t pcibr_vhdl, pcibr_info_h pcibr_infoh; pcibr_info_t pcibr_info; int func; - devfs_handle_t conn_vhdl = GRAPH_VERTEX_NONE; + vertex_hdl_t conn_vhdl = GRAPH_VERTEX_NONE; int nfunc; int error_func; int error_slot = 0; @@ -1811,7 +1659,7 @@ pcibr_slot_call_device_detach(devfs_handle_t pcibr_vhdl, * PCI card on the bus. */ int -pcibr_slot_attach(devfs_handle_t pcibr_vhdl, +pcibr_slot_attach(vertex_hdl_t pcibr_vhdl, pciio_slot_t slot, int drv_flags, char *l1_msg, @@ -1850,7 +1698,7 @@ pcibr_slot_attach(devfs_handle_t pcibr_vhdl, * slot-specific freeing that needs to be done. */ int -pcibr_slot_detach(devfs_handle_t pcibr_vhdl, +pcibr_slot_detach(vertex_hdl_t pcibr_vhdl, pciio_slot_t slot, int drv_flags, char *l1_msg, @@ -1859,10 +1707,6 @@ pcibr_slot_detach(devfs_handle_t pcibr_vhdl, pcibr_soft_t pcibr_soft = pcibr_soft_get(pcibr_vhdl); int error; - /* Make sure that we do not detach a system critical function vertex */ - if(pcibr_is_slot_sys_critical(pcibr_vhdl, slot)) - return(PCI_IS_SYS_CRITICAL); - /* Call the device detach function */ error = (pcibr_slot_call_device_detach(pcibr_vhdl, slot, drv_flags)); if (error) { @@ -1892,61 +1736,6 @@ pcibr_slot_detach(devfs_handle_t pcibr_vhdl, } /* - * pcibr_is_slot_sys_critical - * Check slot for any functions that are system critical. - * Return 1 if any are system critical or 0 otherwise. - * - * This function will always return 0 when called by - * pcibr_attach() because the system critical vertices - * have not yet been set in the hwgraph. - */ -int -pcibr_is_slot_sys_critical(devfs_handle_t pcibr_vhdl, - pciio_slot_t slot) -{ - pcibr_soft_t pcibr_soft; - pcibr_info_h pcibr_infoh; - pcibr_info_t pcibr_info; - devfs_handle_t conn_vhdl = GRAPH_VERTEX_NONE; - int nfunc; - int func; - boolean_t is_sys_critical_vertex(devfs_handle_t); - - pcibr_soft = pcibr_soft_get(pcibr_vhdl); - if (!pcibr_soft) - return(EINVAL); - - if (!PCIBR_VALID_SLOT(pcibr_soft, slot)) - return(EINVAL); - - nfunc = pcibr_soft->bs_slot[slot].bss_ninfo; - pcibr_infoh = pcibr_soft->bs_slot[slot].bss_infos; - - for (func = 0; func < nfunc; ++func) { - - pcibr_info = pcibr_infoh[func]; - if (!pcibr_info) - continue; - - if (pcibr_info->f_vendor == PCIIO_VENDOR_ID_NONE) - continue; - - conn_vhdl = pcibr_info->f_vertex; - if (is_sys_critical_vertex(conn_vhdl)) { -#if defined(SUPPORT_PRINTING_V_FORMAT) - printk(KERN_WARNING "%v is a system critical device vertex\n", conn_vhdl); -#else - printk(KERN_WARNING "%p is a system critical device vertex\n", (void *)conn_vhdl); -#endif - return(1); - } - - } - - return(0); -} - -/* * pcibr_probe_slot_pic: read a config space word * while trapping any errors; return zero if * all went OK, or nonzero if there was an error. @@ -1984,57 +1773,6 @@ pcibr_probe_slot_pic(bridge_t *bridge, } /* - * pcibr_probe_slot_non_pic: read a config space word - * while trapping any errors; return zero if - * all went OK, or nonzero if there was an error. - * The value read, if any, is passed back - * through the valp parameter. - */ -static int -pcibr_probe_slot_non_pic(bridge_t *bridge, - cfg_p cfg, - unsigned *valp) -{ - int rv; - bridgereg_t b_old_enable = (bridgereg_t)0, b_new_enable = (bridgereg_t)0; - extern int badaddr_val(volatile void *, int, volatile void *); - - b_old_enable = bridge->b_int_enable; - b_new_enable = b_old_enable & ~BRIDGE_IMR_PCI_MST_TIMEOUT; - bridge->b_int_enable = b_new_enable; - - /* - * The xbridge doesn't clear b_err_int_view unless - * multi-err is cleared... - */ - if (is_xbridge(bridge)) { - if (bridge->b_err_int_view & BRIDGE_ISR_PCI_MST_TIMEOUT) - bridge->b_int_rst_stat = BRIDGE_IRR_MULTI_CLR; - } - - if (bridge->b_int_status & BRIDGE_IRR_PCI_GRP) { - bridge->b_int_rst_stat = BRIDGE_IRR_PCI_GRP_CLR; - (void) bridge->b_wid_tflush; /* flushbus */ - } - rv = badaddr_val((void *) (((uint64_t)cfg) ^ 4), 4, valp); - /* - * The xbridge doesn't set master timeout in b_int_status - * here. Fortunately it's in error_interrupt_view. - */ - if (is_xbridge(bridge)) { - if (bridge->b_err_int_view & BRIDGE_ISR_PCI_MST_TIMEOUT) { - bridge->b_int_rst_stat = BRIDGE_IRR_MULTI_CLR; - rv = 1; /* unoccupied slot */ - } - } - bridge->b_int_enable = b_old_enable; - bridge->b_wid_tflush; /* wait until Bridge PIO complete */ - - return(rv); -} - - -/* * pcibr_probe_slot: read a config space word * while trapping any errors; return zero if * all went OK, or nonzero if there was an error. @@ -2046,15 +1784,12 @@ pcibr_probe_slot(bridge_t *bridge, cfg_p cfg, unsigned *valp) { - if ( is_pic(bridge) ) - return(pcibr_probe_slot_pic(bridge, cfg, valp)); - else - return(pcibr_probe_slot_non_pic(bridge, cfg, valp)); + return(pcibr_probe_slot_pic(bridge, cfg, valp)); } void -pcibr_device_info_free(devfs_handle_t pcibr_vhdl, pciio_slot_t slot) +pcibr_device_info_free(vertex_hdl_t pcibr_vhdl, pciio_slot_t slot) { pcibr_soft_t pcibr_soft = pcibr_soft_get(pcibr_vhdl); pcibr_info_t pcibr_info; @@ -2079,9 +1814,9 @@ pcibr_device_info_free(devfs_handle_t pcibr_vhdl, pciio_slot_t slot) /* Disable memory and I/O BARs */ cfgw = pcibr_func_config_addr(bridge, 0, slot, func, 0); - cmd_reg = do_pcibr_config_get(IS_PIC_SOFT(pcibr_soft), cfgw, PCI_CFG_COMMAND, 4); + cmd_reg = do_pcibr_config_get(cfgw, PCI_CFG_COMMAND, 4); cmd_reg &= (PCI_CMD_MEM_SPACE | PCI_CMD_IO_SPACE); - do_pcibr_config_set(IS_PIC_SOFT(pcibr_soft), cfgw, PCI_CFG_COMMAND, 4, cmd_reg); + do_pcibr_config_set(cfgw, PCI_CFG_COMMAND, 4, cmd_reg); for (bar = 0; bar < PCI_CFG_BASE_ADDRS; bar++) { if (pcibr_info->f_window[bar].w_space == PCIIO_SPACE_NONE) @@ -2181,7 +1916,7 @@ pciibr_bus_addr_free(pcibr_soft_t pcibr_soft, pciio_win_info_t win_info_p) * io_brick_tab[] array defined in ml/SN/iograph.c */ int -pcibr_widget_to_bus(devfs_handle_t pcibr_vhdl) +pcibr_widget_to_bus(vertex_hdl_t pcibr_vhdl) { pcibr_soft_t pcibr_soft = pcibr_soft_get(pcibr_vhdl); xwidgetnum_t widget = pcibr_soft->bs_xid; diff --git a/arch/ia64/sn/io/sn2/pciio.c b/arch/ia64/sn/io/sn2/pciio.c index 5af418be3464f1..e0a147a57dc5dd 100644 --- a/arch/ia64/sn/io/sn2/pciio.c +++ b/arch/ia64/sn/io/sn2/pciio.c @@ -7,8 +7,6 @@ * Copyright (C) 1992 - 1997, 2000-2003 Silicon Graphics, Inc. All rights reserved. */ -#define USRPCI 0 - #include <linux/init.h> #include <linux/types.h> #include <linux/pci.h> @@ -44,13 +42,8 @@ #undef DEBUG_PCIIO /* turn this on for yet more console output */ -#define GET_NEW(ptr) (ptr = kmalloc(sizeof (*(ptr)), GFP_KERNEL)) -#define DO_DEL(ptr) (kfree(ptr)) - char pciio_info_fingerprint[] = "pciio_info"; -cdl_p pciio_registry = NULL; - int badaddr_val(volatile void *addr, int len, volatile void *ptr) { @@ -97,8 +90,6 @@ get_master_baseio_nasid(void) extern char master_baseio_wid; if (master_baseio_nasid < 0) { - nasid_t tmp; - master_baseio_nasid = ia64_sn_get_master_baseio_nasid(); if ( master_baseio_nasid >= 0 ) { @@ -109,13 +100,13 @@ get_master_baseio_nasid(void) } int -hub_dma_enabled(devfs_handle_t xconn_vhdl) +hub_dma_enabled(vertex_hdl_t xconn_vhdl) { return(0); } int -hub_error_devenable(devfs_handle_t xconn_vhdl, int devnum, int error_code) +hub_error_devenable(vertex_hdl_t xconn_vhdl, int devnum, int error_code) { return(0); } @@ -153,66 +144,64 @@ ioerror_dump(char *name, int error_code, int error_mode, ioerror_t *ioerror) */ #if !defined(DEV_FUNC) -static pciio_provider_t *pciio_to_provider_fns(devfs_handle_t dev); +static pciio_provider_t *pciio_to_provider_fns(vertex_hdl_t dev); #endif -pciio_piomap_t pciio_piomap_alloc(devfs_handle_t, device_desc_t, pciio_space_t, iopaddr_t, size_t, size_t, unsigned); +pciio_piomap_t pciio_piomap_alloc(vertex_hdl_t, device_desc_t, pciio_space_t, iopaddr_t, size_t, size_t, unsigned); void pciio_piomap_free(pciio_piomap_t); caddr_t pciio_piomap_addr(pciio_piomap_t, iopaddr_t, size_t); void pciio_piomap_done(pciio_piomap_t); -caddr_t pciio_piotrans_addr(devfs_handle_t, device_desc_t, pciio_space_t, iopaddr_t, size_t, unsigned); -caddr_t pciio_pio_addr(devfs_handle_t, device_desc_t, pciio_space_t, iopaddr_t, size_t, pciio_piomap_t *, unsigned); +caddr_t pciio_piotrans_addr(vertex_hdl_t, device_desc_t, pciio_space_t, iopaddr_t, size_t, unsigned); +caddr_t pciio_pio_addr(vertex_hdl_t, device_desc_t, pciio_space_t, iopaddr_t, size_t, pciio_piomap_t *, unsigned); -iopaddr_t pciio_piospace_alloc(devfs_handle_t, device_desc_t, pciio_space_t, size_t, size_t); -void pciio_piospace_free(devfs_handle_t, pciio_space_t, iopaddr_t, size_t); +iopaddr_t pciio_piospace_alloc(vertex_hdl_t, device_desc_t, pciio_space_t, size_t, size_t); +void pciio_piospace_free(vertex_hdl_t, pciio_space_t, iopaddr_t, size_t); -pciio_dmamap_t pciio_dmamap_alloc(devfs_handle_t, device_desc_t, size_t, unsigned); +pciio_dmamap_t pciio_dmamap_alloc(vertex_hdl_t, device_desc_t, size_t, unsigned); void pciio_dmamap_free(pciio_dmamap_t); iopaddr_t pciio_dmamap_addr(pciio_dmamap_t, paddr_t, size_t); -alenlist_t pciio_dmamap_list(pciio_dmamap_t, alenlist_t, unsigned); void pciio_dmamap_done(pciio_dmamap_t); -iopaddr_t pciio_dmatrans_addr(devfs_handle_t, device_desc_t, paddr_t, size_t, unsigned); -alenlist_t pciio_dmatrans_list(devfs_handle_t, device_desc_t, alenlist_t, unsigned); +iopaddr_t pciio_dmatrans_addr(vertex_hdl_t, device_desc_t, paddr_t, size_t, unsigned); void pciio_dmamap_drain(pciio_dmamap_t); -void pciio_dmaaddr_drain(devfs_handle_t, paddr_t, size_t); -void pciio_dmalist_drain(devfs_handle_t, alenlist_t); -iopaddr_t pciio_dma_addr(devfs_handle_t, device_desc_t, paddr_t, size_t, pciio_dmamap_t *, unsigned); +void pciio_dmaaddr_drain(vertex_hdl_t, paddr_t, size_t); +void pciio_dmalist_drain(vertex_hdl_t, alenlist_t); +iopaddr_t pciio_dma_addr(vertex_hdl_t, device_desc_t, paddr_t, size_t, pciio_dmamap_t *, unsigned); -pciio_intr_t pciio_intr_alloc(devfs_handle_t, device_desc_t, pciio_intr_line_t, devfs_handle_t); +pciio_intr_t pciio_intr_alloc(vertex_hdl_t, device_desc_t, pciio_intr_line_t, vertex_hdl_t); void pciio_intr_free(pciio_intr_t); int pciio_intr_connect(pciio_intr_t, intr_func_t, intr_arg_t); void pciio_intr_disconnect(pciio_intr_t); -devfs_handle_t pciio_intr_cpu_get(pciio_intr_t); +vertex_hdl_t pciio_intr_cpu_get(pciio_intr_t); void pciio_slot_func_to_name(char *, pciio_slot_t, pciio_function_t); -void pciio_provider_startup(devfs_handle_t); -void pciio_provider_shutdown(devfs_handle_t); +void pciio_provider_startup(vertex_hdl_t); +void pciio_provider_shutdown(vertex_hdl_t); -pciio_endian_t pciio_endian_set(devfs_handle_t, pciio_endian_t, pciio_endian_t); -pciio_priority_t pciio_priority_set(devfs_handle_t, pciio_priority_t); -devfs_handle_t pciio_intr_dev_get(pciio_intr_t); +pciio_endian_t pciio_endian_set(vertex_hdl_t, pciio_endian_t, pciio_endian_t); +pciio_priority_t pciio_priority_set(vertex_hdl_t, pciio_priority_t); +vertex_hdl_t pciio_intr_dev_get(pciio_intr_t); -devfs_handle_t pciio_pio_dev_get(pciio_piomap_t); +vertex_hdl_t pciio_pio_dev_get(pciio_piomap_t); pciio_slot_t pciio_pio_slot_get(pciio_piomap_t); pciio_space_t pciio_pio_space_get(pciio_piomap_t); iopaddr_t pciio_pio_pciaddr_get(pciio_piomap_t); ulong pciio_pio_mapsz_get(pciio_piomap_t); caddr_t pciio_pio_kvaddr_get(pciio_piomap_t); -devfs_handle_t pciio_dma_dev_get(pciio_dmamap_t); +vertex_hdl_t pciio_dma_dev_get(pciio_dmamap_t); pciio_slot_t pciio_dma_slot_get(pciio_dmamap_t); -pciio_info_t pciio_info_chk(devfs_handle_t); -pciio_info_t pciio_info_get(devfs_handle_t); -void pciio_info_set(devfs_handle_t, pciio_info_t); -devfs_handle_t pciio_info_dev_get(pciio_info_t); +pciio_info_t pciio_info_chk(vertex_hdl_t); +pciio_info_t pciio_info_get(vertex_hdl_t); +void pciio_info_set(vertex_hdl_t, pciio_info_t); +vertex_hdl_t pciio_info_dev_get(pciio_info_t); pciio_slot_t pciio_info_slot_get(pciio_info_t); pciio_function_t pciio_info_function_get(pciio_info_t); pciio_vendor_id_t pciio_info_vendor_id_get(pciio_info_t); pciio_device_id_t pciio_info_device_id_get(pciio_info_t); -devfs_handle_t pciio_info_master_get(pciio_info_t); +vertex_hdl_t pciio_info_master_get(pciio_info_t); arbitrary_info_t pciio_info_mfast_get(pciio_info_t); pciio_provider_t *pciio_info_pops_get(pciio_info_t); error_handler_f *pciio_info_efunc_get(pciio_info_t); @@ -223,30 +212,28 @@ size_t pciio_info_bar_size_get(pciio_info_t, int); iopaddr_t pciio_info_rom_base_get(pciio_info_t); size_t pciio_info_rom_size_get(pciio_info_t); -void pciio_init(void); -int pciio_attach(devfs_handle_t); +int pciio_attach(vertex_hdl_t); -void pciio_provider_register(devfs_handle_t, pciio_provider_t *pciio_fns); -void pciio_provider_unregister(devfs_handle_t); -pciio_provider_t *pciio_provider_fns_get(devfs_handle_t); +void pciio_provider_register(vertex_hdl_t, pciio_provider_t *pciio_fns); +void pciio_provider_unregister(vertex_hdl_t); +pciio_provider_t *pciio_provider_fns_get(vertex_hdl_t); int pciio_driver_register(pciio_vendor_id_t, pciio_device_id_t, char *driver_prefix, unsigned); -void pciio_driver_unregister(char *driver_prefix); -devfs_handle_t pciio_device_register(devfs_handle_t, devfs_handle_t, pciio_slot_t, pciio_function_t, pciio_vendor_id_t, pciio_device_id_t); +vertex_hdl_t pciio_device_register(vertex_hdl_t, vertex_hdl_t, pciio_slot_t, pciio_function_t, pciio_vendor_id_t, pciio_device_id_t); -void pciio_device_unregister(devfs_handle_t); -pciio_info_t pciio_device_info_new(pciio_info_t, devfs_handle_t, pciio_slot_t, pciio_function_t, pciio_vendor_id_t, pciio_device_id_t); +void pciio_device_unregister(vertex_hdl_t); +pciio_info_t pciio_device_info_new(pciio_info_t, vertex_hdl_t, pciio_slot_t, pciio_function_t, pciio_vendor_id_t, pciio_device_id_t); void pciio_device_info_free(pciio_info_t); -devfs_handle_t pciio_device_info_register(devfs_handle_t, pciio_info_t); -void pciio_device_info_unregister(devfs_handle_t, pciio_info_t); -int pciio_device_attach(devfs_handle_t, int); -int pciio_device_detach(devfs_handle_t, int); -void pciio_error_register(devfs_handle_t, error_handler_f *, error_handler_arg_t); +vertex_hdl_t pciio_device_info_register(vertex_hdl_t, pciio_info_t); +void pciio_device_info_unregister(vertex_hdl_t, pciio_info_t); +int pciio_device_attach(vertex_hdl_t, int); +int pciio_device_detach(vertex_hdl_t, int); +void pciio_error_register(vertex_hdl_t, error_handler_f *, error_handler_arg_t); -int pciio_reset(devfs_handle_t); -int pciio_write_gather_flush(devfs_handle_t); -int pciio_slot_inuse(devfs_handle_t); +int pciio_reset(vertex_hdl_t); +int pciio_write_gather_flush(vertex_hdl_t); +int pciio_slot_inuse(vertex_hdl_t); /* ===================================================================== * Provider Function Location @@ -261,7 +248,7 @@ int pciio_slot_inuse(devfs_handle_t); #if !defined(DEV_FUNC) static pciio_provider_t * -pciio_to_provider_fns(devfs_handle_t dev) +pciio_to_provider_fns(vertex_hdl_t dev) { pciio_info_t card_info; pciio_provider_t *provider_fns; @@ -316,7 +303,7 @@ pciio_to_provider_fns(devfs_handle_t dev) */ pciio_piomap_t -pciio_piomap_alloc(devfs_handle_t dev, /* set up mapping for this device */ +pciio_piomap_alloc(vertex_hdl_t dev, /* set up mapping for this device */ device_desc_t dev_desc, /* device descriptor */ pciio_space_t space, /* CFG, MEM, IO, or a device-decoded window */ iopaddr_t addr, /* lowest address (or offset in window) */ @@ -354,7 +341,7 @@ pciio_piomap_done(pciio_piomap_t pciio_piomap) } caddr_t -pciio_piotrans_addr(devfs_handle_t dev, /* translate for this device */ +pciio_piotrans_addr(vertex_hdl_t dev, /* translate for this device */ device_desc_t dev_desc, /* device descriptor */ pciio_space_t space, /* CFG, MEM, IO, or a device-decoded window */ iopaddr_t addr, /* starting address (or offset in window) */ @@ -366,7 +353,7 @@ pciio_piotrans_addr(devfs_handle_t dev, /* translate for this device */ } caddr_t -pciio_pio_addr(devfs_handle_t dev, /* translate for this device */ +pciio_pio_addr(vertex_hdl_t dev, /* translate for this device */ device_desc_t dev_desc, /* device descriptor */ pciio_space_t space, /* CFG, MEM, IO, or a device-decoded window */ iopaddr_t addr, /* starting address (or offset in window) */ @@ -410,7 +397,7 @@ pciio_pio_addr(devfs_handle_t dev, /* translate for this device */ } iopaddr_t -pciio_piospace_alloc(devfs_handle_t dev, /* Device requiring space */ +pciio_piospace_alloc(vertex_hdl_t dev, /* Device requiring space */ device_desc_t dev_desc, /* Device descriptor */ pciio_space_t space, /* MEM32/MEM64/IO */ size_t byte_count, /* Size of mapping */ @@ -423,7 +410,7 @@ pciio_piospace_alloc(devfs_handle_t dev, /* Device requiring space */ } void -pciio_piospace_free(devfs_handle_t dev, /* Device freeing space */ +pciio_piospace_free(vertex_hdl_t dev, /* Device freeing space */ pciio_space_t space, /* Type of space */ iopaddr_t pciaddr, /* starting address */ size_t byte_count) @@ -440,7 +427,7 @@ pciio_piospace_free(devfs_handle_t dev, /* Device freeing space */ */ pciio_dmamap_t -pciio_dmamap_alloc(devfs_handle_t dev, /* set up mappings for this device */ +pciio_dmamap_alloc(vertex_hdl_t dev, /* set up mappings for this device */ device_desc_t dev_desc, /* device descriptor */ size_t byte_count_max, /* max size of a mapping */ unsigned flags) @@ -465,15 +452,6 @@ pciio_dmamap_addr(pciio_dmamap_t pciio_dmamap, /* use these mapping resources */ (CAST_DMAMAP(pciio_dmamap), paddr, byte_count); } -alenlist_t -pciio_dmamap_list(pciio_dmamap_t pciio_dmamap, /* use these mapping resources */ - alenlist_t alenlist, /* map this Address/Length List */ - unsigned flags) -{ - return DMAMAP_FUNC(pciio_dmamap, dmamap_list) - (CAST_DMAMAP(pciio_dmamap), alenlist, flags); -} - void pciio_dmamap_done(pciio_dmamap_t pciio_dmamap) { @@ -482,7 +460,7 @@ pciio_dmamap_done(pciio_dmamap_t pciio_dmamap) } iopaddr_t -pciio_dmatrans_addr(devfs_handle_t dev, /* translate for this device */ +pciio_dmatrans_addr(vertex_hdl_t dev, /* translate for this device */ device_desc_t dev_desc, /* device descriptor */ paddr_t paddr, /* system physical address */ size_t byte_count, /* length */ @@ -492,18 +470,8 @@ pciio_dmatrans_addr(devfs_handle_t dev, /* translate for this device */ (dev, dev_desc, paddr, byte_count, flags); } -alenlist_t -pciio_dmatrans_list(devfs_handle_t dev, /* translate for this device */ - device_desc_t dev_desc, /* device descriptor */ - alenlist_t palenlist, /* system address/length list */ - unsigned flags) -{ /* defined in dma.h */ - return DEV_FUNC(dev, dmatrans_list) - (dev, dev_desc, palenlist, flags); -} - iopaddr_t -pciio_dma_addr(devfs_handle_t dev, /* translate for this device */ +pciio_dma_addr(vertex_hdl_t dev, /* translate for this device */ device_desc_t dev_desc, /* device descriptor */ paddr_t paddr, /* system physical address */ size_t byte_count, /* length */ @@ -553,14 +521,14 @@ pciio_dmamap_drain(pciio_dmamap_t map) } void -pciio_dmaaddr_drain(devfs_handle_t dev, paddr_t addr, size_t size) +pciio_dmaaddr_drain(vertex_hdl_t dev, paddr_t addr, size_t size) { DEV_FUNC(dev, dmaaddr_drain) (dev, addr, size); } void -pciio_dmalist_drain(devfs_handle_t dev, alenlist_t list) +pciio_dmalist_drain(vertex_hdl_t dev, alenlist_t list) { DEV_FUNC(dev, dmalist_drain) (dev, list); @@ -577,10 +545,10 @@ pciio_dmalist_drain(devfs_handle_t dev, alenlist_t list) * Return resource handle in intr_hdl. */ pciio_intr_t -pciio_intr_alloc(devfs_handle_t dev, /* which Crosstalk device */ +pciio_intr_alloc(vertex_hdl_t dev, /* which Crosstalk device */ device_desc_t dev_desc, /* device descriptor */ pciio_intr_line_t lines, /* INTR line(s) to attach */ - devfs_handle_t owner_dev) + vertex_hdl_t owner_dev) { /* owner of this interrupt */ return (pciio_intr_t) DEV_FUNC(dev, intr_alloc) (dev, dev_desc, lines, owner_dev); @@ -624,7 +592,7 @@ pciio_intr_disconnect(pciio_intr_t intr_hdl) * Return a hwgraph vertex that represents the CPU currently * targeted by an interrupt. */ -devfs_handle_t +vertex_hdl_t pciio_intr_cpu_get(pciio_intr_t intr_hdl) { return INTR_FUNC(intr_hdl, intr_cpu_get) @@ -663,12 +631,12 @@ pciio_slot_func_to_name(char *name, */ static pciio_info_t pciio_cardinfo_get( - devfs_handle_t pciio_vhdl, + vertex_hdl_t pciio_vhdl, pciio_slot_t pci_slot) { char namebuf[16]; pciio_info_t info = 0; - devfs_handle_t conn; + vertex_hdl_t conn; pciio_slot_func_to_name(namebuf, pci_slot, PCIIO_FUNC_NONE); if (GRAPH_SUCCESS == @@ -699,22 +667,16 @@ pciio_cardinfo_get( /*ARGSUSED */ int pciio_error_handler( - devfs_handle_t pciio_vhdl, + vertex_hdl_t pciio_vhdl, int error_code, ioerror_mode_t mode, ioerror_t *ioerror) { pciio_info_t pciio_info; - devfs_handle_t pconn_vhdl; -#if USRPCI - devfs_handle_t usrpci_v; -#endif + vertex_hdl_t pconn_vhdl; pciio_slot_t slot; int retval; -#ifdef EHE_ENABLE - error_state_t e_state; -#endif /* EHE_ENABLE */ #if DEBUG && ERROR_DEBUG printk("%v: pciio_error_handler\n", pciio_vhdl); @@ -733,16 +695,6 @@ pciio_error_handler( if (pciio_info && pciio_info->c_efunc) { pconn_vhdl = pciio_info_dev_get(pciio_info); -#ifdef EHE_ENABLE - e_state = error_state_get(pciio_vhdl); - - if (e_state == ERROR_STATE_ACTION) - (void)error_state_set(pciio_vhdl, ERROR_STATE_NONE); - - if (error_state_set(pconn_vhdl,e_state) == ERROR_RETURN_CODE_CANNOT_SET_STATE) - return(IOERROR_UNHANDLED); -#endif - retval = pciio_info->c_efunc (pciio_info->c_einfo, error_code, mode, ioerror); if (retval != IOERROR_UNHANDLED) @@ -770,49 +722,11 @@ pciio_error_handler( pconn_vhdl = pciio_info_dev_get(pciio_info); -#ifdef EHE_ENABLE - e_state = error_state_get(pciio_vhdl); - - if (e_state == ERROR_STATE_ACTION) - (void)error_state_set(pciio_vhdl, ERROR_STATE_NONE); - - if (error_state_set(pconn_vhdl,e_state) == - ERROR_RETURN_CODE_CANNOT_SET_STATE) - return(IOERROR_UNHANDLED); -#endif /* EHE_ENABLE */ - retval = pciio_info->c_efunc (pciio_info->c_einfo, error_code, mode, ioerror); if (retval != IOERROR_UNHANDLED) return retval; } - -#if USRPCI - /* If the USRPCI driver is available and - * knows about this connection point, - * deliver the error to it. - * - * OK to use pconn_vhdl here, even though we - * have already UNREF'd it, since we know that - * it is not going away. - */ - pconn_vhdl = pciio_info_dev_get(pciio_info); - if (GRAPH_SUCCESS == hwgraph_traverse(pconn_vhdl, EDGE_LBL_USRPCI, &usrpci_v)) { - iopaddr_t busaddr; - IOERROR_GETVALUE(busaddr, ioerror, busaddr); - retval = usrpci_error_handler (usrpci_v, error_code, busaddr); - hwgraph_vertex_unref(usrpci_v); - if (retval != IOERROR_UNHANDLED) { - /* - * This unref is not needed. If this code is called often enough, - * the system will crash, due to vertex reference count reaching 0, - * causing vertex to be unallocated. -jeremy - * hwgraph_vertex_unref(pconn_vhdl); - */ - return retval; - } - } -#endif } } @@ -829,7 +743,7 @@ pciio_error_handler( * Startup a crosstalk provider */ void -pciio_provider_startup(devfs_handle_t pciio_provider) +pciio_provider_startup(vertex_hdl_t pciio_provider) { DEV_FUNC(pciio_provider, provider_startup) (pciio_provider); @@ -839,7 +753,7 @@ pciio_provider_startup(devfs_handle_t pciio_provider) * Shutdown a crosstalk provider */ void -pciio_provider_shutdown(devfs_handle_t pciio_provider) +pciio_provider_shutdown(vertex_hdl_t pciio_provider) { DEV_FUNC(pciio_provider, provider_shutdown) (pciio_provider); @@ -851,7 +765,7 @@ pciio_provider_shutdown(devfs_handle_t pciio_provider) * how things will actually appear in memory. */ pciio_endian_t -pciio_endian_set(devfs_handle_t dev, +pciio_endian_set(vertex_hdl_t dev, pciio_endian_t device_end, pciio_endian_t desired_end) { @@ -880,7 +794,7 @@ pciio_endian_set(devfs_handle_t dev, * Specify PCI arbitration priority. */ pciio_priority_t -pciio_priority_set(devfs_handle_t dev, +pciio_priority_set(vertex_hdl_t dev, pciio_priority_t device_prio) { ASSERT((device_prio == PCI_PRIO_HIGH) || (device_prio == PCI_PRIO_LOW)); @@ -893,7 +807,7 @@ pciio_priority_set(devfs_handle_t dev, * Read value of configuration register */ uint64_t -pciio_config_get(devfs_handle_t dev, +pciio_config_get(vertex_hdl_t dev, unsigned reg, unsigned size) { @@ -923,7 +837,7 @@ pciio_config_get(devfs_handle_t dev, * Change value of configuration register */ void -pciio_config_set(devfs_handle_t dev, +pciio_config_set(vertex_hdl_t dev, unsigned reg, unsigned size, uint64_t value) @@ -953,7 +867,7 @@ pciio_config_set(devfs_handle_t dev, * Issue a hardware reset to a card. */ int -pciio_reset(devfs_handle_t dev) +pciio_reset(vertex_hdl_t dev) { return DEV_FUNC(dev, reset) (dev); } @@ -962,19 +876,19 @@ pciio_reset(devfs_handle_t dev) * flush write gather buffers */ int -pciio_write_gather_flush(devfs_handle_t dev) +pciio_write_gather_flush(vertex_hdl_t dev) { return DEV_FUNC(dev, write_gather_flush) (dev); } -devfs_handle_t +vertex_hdl_t pciio_intr_dev_get(pciio_intr_t pciio_intr) { return (pciio_intr->pi_dev); } /****** Generic crosstalk pio interfaces ******/ -devfs_handle_t +vertex_hdl_t pciio_pio_dev_get(pciio_piomap_t pciio_piomap) { return (pciio_piomap->pp_dev); @@ -1011,7 +925,7 @@ pciio_pio_kvaddr_get(pciio_piomap_t pciio_piomap) } /****** Generic crosstalk dma interfaces ******/ -devfs_handle_t +vertex_hdl_t pciio_dma_dev_get(pciio_dmamap_t pciio_dmamap) { return (pciio_dmamap->pd_dev); @@ -1026,7 +940,7 @@ pciio_dma_slot_get(pciio_dmamap_t pciio_dmamap) /****** Generic pci slot information interfaces ******/ pciio_info_t -pciio_info_chk(devfs_handle_t pciio) +pciio_info_chk(vertex_hdl_t pciio) { arbitrary_info_t ainfo = 0; @@ -1035,7 +949,7 @@ pciio_info_chk(devfs_handle_t pciio) } pciio_info_t -pciio_info_get(devfs_handle_t pciio) +pciio_info_get(vertex_hdl_t pciio) { pciio_info_t pciio_info; @@ -1051,18 +965,17 @@ pciio_info_get(devfs_handle_t pciio) #endif /* DEBUG_PCIIO */ if ((pciio_info != NULL) && - (pciio_info->c_fingerprint != pciio_info_fingerprint) - && (pciio_info->c_fingerprint != NULL)) { + (pciio_info->c_fingerprint != pciio_info_fingerprint) + && (pciio_info->c_fingerprint != NULL)) { - return((pciio_info_t)-1); /* Should panic .. */ + return((pciio_info_t)-1); /* Should panic .. */ } - return pciio_info; } void -pciio_info_set(devfs_handle_t pciio, pciio_info_t pciio_info) +pciio_info_set(vertex_hdl_t pciio, pciio_info_t pciio_info) { if (pciio_info != NULL) pciio_info->c_fingerprint = pciio_info_fingerprint; @@ -1076,7 +989,7 @@ pciio_info_set(devfs_handle_t pciio, pciio_info_t pciio_info) (arbitrary_info_t) pciio_info); } -devfs_handle_t +vertex_hdl_t pciio_info_dev_get(pciio_info_t pciio_info) { return (pciio_info->c_vertex); @@ -1106,7 +1019,7 @@ pciio_info_device_id_get(pciio_info_t pciio_info) return (pciio_info->c_device); } -devfs_handle_t +vertex_hdl_t pciio_info_master_get(pciio_info_t pciio_info) { return (pciio_info->c_master); @@ -1172,47 +1085,12 @@ pciio_info_rom_size_get(pciio_info_t info) */ /* - * pciioinit: called once during device driver - * initializtion if this driver is configured into - * the system. - */ -void -pciio_init(void) -{ - cdl_p cp; - -#if DEBUG && ATTACH_DEBUG - printf("pciio_init\n"); -#endif - /* Allocate the registry. - * We might already have one. - * If we don't, go get one. - * MPness: someone might have - * set one up for us while we - * were not looking; use an atomic - * compare-and-swap to commit to - * using the new registry if and - * only if nobody else did first. - * If someone did get there first, - * toss the one we allocated back - * into the pool. - */ - if (pciio_registry == NULL) { - cp = cdl_new(EDGE_LBL_PCI, "vendor", "device"); - if (!compare_and_swap_ptr((void **) &pciio_registry, NULL, (void *) cp)) { - cdl_del(cp); - } - } - ASSERT(pciio_registry != NULL); -} - -/* * pciioattach: called for each vertex in the graph * that is a PCI provider. */ /*ARGSUSED */ int -pciio_attach(devfs_handle_t pciio) +pciio_attach(vertex_hdl_t pciio) { #if DEBUG && ATTACH_DEBUG #if defined(SUPPORT_PRINTING_V_FORMAT) @@ -1228,7 +1106,7 @@ pciio_attach(devfs_handle_t pciio) * Associate a set of pciio_provider functions with a vertex. */ void -pciio_provider_register(devfs_handle_t provider, pciio_provider_t *pciio_fns) +pciio_provider_register(vertex_hdl_t provider, pciio_provider_t *pciio_fns) { hwgraph_info_add_LBL(provider, INFO_LBL_PFUNCS, (arbitrary_info_t) pciio_fns); } @@ -1237,7 +1115,7 @@ pciio_provider_register(devfs_handle_t provider, pciio_provider_t *pciio_fns) * Disassociate a set of pciio_provider functions with a vertex. */ void -pciio_provider_unregister(devfs_handle_t provider) +pciio_provider_unregister(vertex_hdl_t provider) { arbitrary_info_t ainfo; @@ -1249,7 +1127,7 @@ pciio_provider_unregister(devfs_handle_t provider) * provider. */ pciio_provider_t * -pciio_provider_fns_get(devfs_handle_t provider) +pciio_provider_fns_get(vertex_hdl_t provider) { arbitrary_info_t ainfo = 0; @@ -1265,86 +1143,13 @@ pciio_driver_register( char *driver_prefix, unsigned flags) { - /* a driver's init routine might call - * pciio_driver_register before the - * system calls pciio_init; so we - * make the init call ourselves here. - */ - if (pciio_registry == NULL) - pciio_init(); - - return cdl_add_driver(pciio_registry, - vendor_id, device_id, - driver_prefix, flags, NULL); -} - -/* - * Remove an initialization function. - */ -void -pciio_driver_unregister( - char *driver_prefix) -{ - /* before a driver calls unregister, - * it must have called register; so - * we can assume we have a registry here. - */ - ASSERT(pciio_registry != NULL); - - cdl_del_driver(pciio_registry, driver_prefix, NULL); -} - -/* - * Set the slot status for a device supported by the - * driver being registered. - */ -void -pciio_driver_reg_callback( - devfs_handle_t pconn_vhdl, - int key1, - int key2, - int error) -{ -} - -/* - * Set the slot status for a device supported by the - * driver being unregistered. - */ -void -pciio_driver_unreg_callback( - devfs_handle_t pconn_vhdl, - int key1, - int key2, - int error) -{ -} - -/* - * Call some function with each vertex that - * might be one of this driver's attach points. - */ -void -pciio_iterate(char *driver_prefix, - pciio_iter_f * func) -{ - /* a driver's init routine might call - * pciio_iterate before the - * system calls pciio_init; so we - * make the init call ourselves here. - */ - if (pciio_registry == NULL) - pciio_init(); - - ASSERT(pciio_registry != NULL); - - cdl_iterate(pciio_registry, driver_prefix, (cdl_iter_f *) func); + return(0); } -devfs_handle_t +vertex_hdl_t pciio_device_register( - devfs_handle_t connectpt, /* vertex for /hw/.../pciio/%d */ - devfs_handle_t master, /* card's master ASIC (PCI provider) */ + vertex_hdl_t connectpt, /* vertex for /hw/.../pciio/%d */ + vertex_hdl_t master, /* card's master ASIC (PCI provider) */ pciio_slot_t slot, /* card's slot */ pciio_function_t func, /* card's func */ pciio_vendor_id_t vendor_id, @@ -1356,7 +1161,7 @@ pciio_device_register( } void -pciio_device_unregister(devfs_handle_t pconn) +pciio_device_unregister(vertex_hdl_t pconn) { DEV_FUNC(pconn,device_unregister)(pconn); } @@ -1364,14 +1169,14 @@ pciio_device_unregister(devfs_handle_t pconn) pciio_info_t pciio_device_info_new( pciio_info_t pciio_info, - devfs_handle_t master, + vertex_hdl_t master, pciio_slot_t slot, pciio_function_t func, pciio_vendor_id_t vendor_id, pciio_device_id_t device_id) { if (!pciio_info) - GET_NEW(pciio_info); + NEW(pciio_info); ASSERT(pciio_info != NULL); pciio_info->c_slot = slot; @@ -1396,14 +1201,14 @@ pciio_device_info_free(pciio_info_t pciio_info) BZERO((char *)pciio_info,sizeof(pciio_info)); } -devfs_handle_t +vertex_hdl_t pciio_device_info_register( - devfs_handle_t connectpt, /* vertex at center of bus */ + vertex_hdl_t connectpt, /* vertex at center of bus */ pciio_info_t pciio_info) /* details about the connectpt */ { char name[32]; - devfs_handle_t pconn; - int device_master_set(devfs_handle_t, devfs_handle_t); + vertex_hdl_t pconn; + int device_master_set(vertex_hdl_t, vertex_hdl_t); pciio_slot_func_to_name(name, pciio_info->c_slot, @@ -1429,25 +1234,15 @@ pciio_device_info_register( */ device_master_set(pconn, pciio_info->c_master); - -#if USRPCI - /* - * Call into usrpci provider to let it initialize for - * the given slot. - */ - if (pciio_info->c_slot != PCIIO_SLOT_NONE) - usrpci_device_register(pconn, pciio_info->c_master, pciio_info->c_slot); -#endif - return pconn; } void -pciio_device_info_unregister(devfs_handle_t connectpt, +pciio_device_info_unregister(vertex_hdl_t connectpt, pciio_info_t pciio_info) { char name[32]; - devfs_handle_t pconn; + vertex_hdl_t pconn; if (!pciio_info) return; @@ -1470,7 +1265,7 @@ pciio_device_info_unregister(devfs_handle_t connectpt, /* Add the pci card inventory information to the hwgraph */ static void -pciio_device_inventory_add(devfs_handle_t pconn_vhdl) +pciio_device_inventory_add(vertex_hdl_t pconn_vhdl) { pciio_info_t pciio_info = pciio_info_get(pconn_vhdl); @@ -1488,7 +1283,7 @@ pciio_device_inventory_add(devfs_handle_t pconn_vhdl) /*ARGSUSED */ int -pciio_device_attach(devfs_handle_t pconn, +pciio_device_attach(vertex_hdl_t pconn, int drv_flags) { pciio_info_t pciio_info; @@ -1507,34 +1302,15 @@ pciio_device_attach(devfs_handle_t pconn, * pciio_init) have been called; so we * can assume here that we have a registry. */ - ASSERT(pciio_registry != NULL); - return(cdl_add_connpt(pciio_registry, vendor_id, device_id, pconn, drv_flags)); + return(cdl_add_connpt(vendor_id, device_id, pconn, drv_flags)); } int -pciio_device_detach(devfs_handle_t pconn, +pciio_device_detach(vertex_hdl_t pconn, int drv_flags) { - pciio_info_t pciio_info; - pciio_vendor_id_t vendor_id; - pciio_device_id_t device_id; - - pciio_info = pciio_info_get(pconn); - - vendor_id = pciio_info->c_vendor; - device_id = pciio_info->c_device; - - /* we don't start attaching things until - * all the driver init routines (including - * pciio_init) have been called; so we - * can assume here that we have a registry. - */ - ASSERT(pciio_registry != NULL); - - return(cdl_del_connpt(pciio_registry, vendor_id, device_id, - pconn, drv_flags)); - + return(0); } /* SN2 */ @@ -1728,7 +1504,7 @@ pciio_device_win_free(pciio_win_alloc_t win_alloc) * cooperating drivers, well, cooperate ... */ void -pciio_error_register(devfs_handle_t pconn, +pciio_error_register(vertex_hdl_t pconn, error_handler_f *efunc, error_handler_arg_t einfo) { @@ -1746,7 +1522,7 @@ pciio_error_register(devfs_handle_t pconn, * vhdl is the vertex for the slot */ int -pciio_slot_inuse(devfs_handle_t pconn_vhdl) +pciio_slot_inuse(vertex_hdl_t pconn_vhdl) { pciio_info_t pciio_info = pciio_info_get(pconn_vhdl); @@ -1763,7 +1539,7 @@ pciio_slot_inuse(devfs_handle_t pconn_vhdl) } int -pciio_dma_enabled(devfs_handle_t pconn_vhdl) +pciio_dma_enabled(vertex_hdl_t pconn_vhdl) { return DEV_FUNC(pconn_vhdl, dma_enabled)(pconn_vhdl); } @@ -1777,7 +1553,7 @@ pciio_info_type1_get(pciio_info_t pci_info) /* * These are complementary Linux interfaces that takes in a pci_dev * as the - * first arguement instead of devfs_handle_t. + * first arguement instead of vertex_hdl_t. */ iopaddr_t snia_pciio_dmatrans_addr(struct pci_dev *, device_desc_t, paddr_t, size_t, unsigned); pciio_dmamap_t snia_pciio_dmamap_alloc(struct pci_dev *, device_desc_t, size_t, unsigned); @@ -1800,7 +1576,7 @@ snia_pcibr_rrb_alloc(struct pci_dev *pci_dev, int *count_vchan0, int *count_vchan1) { - devfs_handle_t dev = PCIDEV_VERTEX(pci_dev); + vertex_hdl_t dev = PCIDEV_VERTEX(pci_dev); return pcibr_rrb_alloc(dev, count_vchan0, count_vchan1); } @@ -1811,7 +1587,7 @@ snia_pciio_endian_set(struct pci_dev *pci_dev, pciio_endian_t device_end, pciio_endian_t desired_end) { - devfs_handle_t dev = PCIDEV_VERTEX(pci_dev); + vertex_hdl_t dev = PCIDEV_VERTEX(pci_dev); return DEV_FUNC(dev, endian_set) (dev, device_end, desired_end); @@ -1825,7 +1601,7 @@ snia_pciio_dmatrans_addr(struct pci_dev *pci_dev, /* translate for this device * unsigned flags) { /* defined in dma.h */ - devfs_handle_t dev = PCIDEV_VERTEX(pci_dev); + vertex_hdl_t dev = PCIDEV_VERTEX(pci_dev); /* * If the device is not a PIC, we always want the PCIIO_BYTE_STREAM to be @@ -1842,7 +1618,7 @@ snia_pciio_dmamap_alloc(struct pci_dev *pci_dev, /* set up mappings for this de unsigned flags) { /* defined in dma.h */ - devfs_handle_t dev = PCIDEV_VERTEX(pci_dev); + vertex_hdl_t dev = PCIDEV_VERTEX(pci_dev); /* * If the device is not a PIC, we always want the PCIIO_BYTE_STREAM to be diff --git a/arch/ia64/sn/io/sn2/pic.c b/arch/ia64/sn/io/sn2/pic.c index 4dba132ca4caa6..ffa174762e74b1 100644 --- a/arch/ia64/sn/io/sn2/pic.c +++ b/arch/ia64/sn/io/sn2/pic.c @@ -27,7 +27,6 @@ #include <asm/sn/prio.h> #include <asm/sn/xtalk/xbow.h> #include <asm/sn/ioc3.h> -#include <asm/sn/eeprom.h> #include <asm/sn/io.h> #include <asm/sn/sn_private.h> @@ -38,27 +37,16 @@ extern char *bcopy(const char * src, char * dest, int count); int pic_devflag = D_MP; -extern int pcibr_attach2(devfs_handle_t, bridge_t *, devfs_handle_t, int, pcibr_soft_t *); -extern void pcibr_driver_reg_callback(devfs_handle_t, int, int, int); -extern void pcibr_driver_unreg_callback(devfs_handle_t, int, int, int); +extern int pcibr_attach2(vertex_hdl_t, bridge_t *, vertex_hdl_t, int, pcibr_soft_t *); +extern void pcibr_driver_reg_callback(vertex_hdl_t, int, int, int); +extern void pcibr_driver_unreg_callback(vertex_hdl_t, int, int, int); -void -pic_init(void) -{ - PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_INIT, NULL, "pic_init()\n")); - - xwidget_driver_register(PIC_WIDGET_PART_NUM_BUS0, - PIC_WIDGET_MFGR_NUM, - "pic_", - 0); -} - /* * copy inventory_t from conn_v to peer_conn_v */ int -pic_bus1_inventory_dup(devfs_handle_t conn_v, devfs_handle_t peer_conn_v) +pic_bus1_inventory_dup(vertex_hdl_t conn_v, vertex_hdl_t peer_conn_v) { inventory_t *pinv, *peer_pinv; @@ -66,7 +54,7 @@ pic_bus1_inventory_dup(devfs_handle_t conn_v, devfs_handle_t peer_conn_v) (arbitrary_info_t *)&pinv) == GRAPH_SUCCESS) { NEW(peer_pinv); - bcopy(pinv, peer_pinv, sizeof(inventory_t)); + bcopy((const char *)pinv, (char *)peer_pinv, sizeof(inventory_t)); if (hwgraph_info_add_LBL(peer_conn_v, INFO_LBL_INVENT, (arbitrary_info_t)peer_pinv) != GRAPH_SUCCESS) { DEL(peer_pinv); @@ -75,8 +63,7 @@ pic_bus1_inventory_dup(devfs_handle_t conn_v, devfs_handle_t peer_conn_v) return 1; } - printk("pic_bus1_inventory_dup: cannot get INFO_LBL_INVENT from 0x%lx\n ", - conn_v); + printk("pic_bus1_inventory_dup: cannot get INFO_LBL_INVENT from 0x%lx\n ", (uint64_t)conn_v); return 0; } @@ -84,13 +71,12 @@ pic_bus1_inventory_dup(devfs_handle_t conn_v, devfs_handle_t peer_conn_v) * copy xwidget_info_t from conn_v to peer_conn_v */ int -pic_bus1_widget_info_dup(devfs_handle_t conn_v, devfs_handle_t peer_conn_v, +pic_bus1_widget_info_dup(vertex_hdl_t conn_v, vertex_hdl_t peer_conn_v, cnodeid_t xbow_peer) { xwidget_info_t widget_info, peer_widget_info; char peer_path[256]; - char *p; - devfs_handle_t peer_hubv; + vertex_hdl_t peer_hubv; hubinfo_t peer_hub_info; /* get the peer hub's widgetid */ @@ -126,7 +112,7 @@ pic_bus1_widget_info_dup(devfs_handle_t conn_v, devfs_handle_t peer_conn_v, } printk("pic_bus1_widget_info_dup: " - "cannot get INFO_LBL_XWIDGET from 0x%lx\n", conn_v); + "cannot get INFO_LBL_XWIDGET from 0x%lx\n", (uint64_t)conn_v); return 0; } @@ -138,15 +124,15 @@ pic_bus1_widget_info_dup(devfs_handle_t conn_v, devfs_handle_t peer_conn_v, * If not successful, return zero and both buses will attach to the * vertex passed into pic_attach(). */ -devfs_handle_t -pic_bus1_redist(nasid_t nasid, devfs_handle_t conn_v) +vertex_hdl_t +pic_bus1_redist(nasid_t nasid, vertex_hdl_t conn_v) { cnodeid_t cnode = NASID_TO_COMPACT_NODEID(nasid); cnodeid_t xbow_peer = -1; char pathname[256], peer_path[256], tmpbuf[256]; char *p; int rc; - devfs_handle_t peer_conn_v; + vertex_hdl_t peer_conn_v; int pos; slabid_t slab; @@ -155,7 +141,7 @@ pic_bus1_redist(nasid_t nasid, devfs_handle_t conn_v) /* pcibr widget hw/module/001c11/slab/0/Pbrick/xtalk/12 */ /* sprintf(pathname, "%v", conn_v); */ xbow_peer = NASID_TO_COMPACT_NODEID(NODEPDA(cnode)->xbow_peer); - pos = devfs_generate_path(conn_v, tmpbuf, 256); + pos = hwgfs_generate_path(conn_v, tmpbuf, 256); strcpy(pathname, &tmpbuf[pos]); p = pathname + strlen("hw/module/001c01/slab/0/"); @@ -170,7 +156,7 @@ pic_bus1_redist(nasid_t nasid, devfs_handle_t conn_v) rc = hwgraph_traverse(hwgraph_root, peer_path, &peer_conn_v); if (GRAPH_SUCCESS == rc) printk("pic_attach: found unexpected vertex: 0x%lx\n", - peer_conn_v); + (uint64_t)peer_conn_v); else if (GRAPH_NOT_FOUND != rc) { printk("pic_attach: hwgraph_traverse unexpectedly" " returned 0x%x\n", rc); @@ -208,13 +194,13 @@ pic_bus1_redist(nasid_t nasid, devfs_handle_t conn_v) int -pic_attach(devfs_handle_t conn_v) +pic_attach(vertex_hdl_t conn_v) { int rc; bridge_t *bridge0, *bridge1 = (bridge_t *)0; - devfs_handle_t pcibr_vhdl0, pcibr_vhdl1 = (devfs_handle_t)0; + vertex_hdl_t pcibr_vhdl0, pcibr_vhdl1 = (vertex_hdl_t)0; pcibr_soft_t bus0_soft, bus1_soft = (pcibr_soft_t)0; - devfs_handle_t conn_v0, conn_v1, peer_conn_v; + vertex_hdl_t conn_v0, conn_v1, peer_conn_v; PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_ATTACH, conn_v, "pic_attach()\n")); @@ -229,11 +215,11 @@ pic_attach(devfs_handle_t conn_v) conn_v0 = conn_v1 = conn_v; /* If dual-ported then split the two PIC buses across both Cbricks */ - if (peer_conn_v = pic_bus1_redist(NASID_GET(bridge0), conn_v)) + if ((peer_conn_v = (pic_bus1_redist(NASID_GET(bridge0), conn_v)))) conn_v1 = peer_conn_v; /* - * Create the vertex for the PCI buses, which week + * Create the vertex for the PCI buses, which we * will also use to hold the pcibr_soft and * which will be the "master" vertex for all the * pciio connection points we will hang off it. @@ -266,7 +252,6 @@ pic_attach(devfs_handle_t conn_v) /* save a pointer to the PIC's other bus's soft struct */ bus0_soft->bs_peers_soft = bus1_soft; bus1_soft->bs_peers_soft = bus0_soft; - bus0_soft->bs_peers_soft = (pcibr_soft_t)0; PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_ATTACH, conn_v, "pic_attach: bus0_soft=0x%x, bus1_soft=0x%x\n", @@ -294,10 +279,8 @@ pciio_provider_t pci_pic_provider = (pciio_dmamap_alloc_f *) pcibr_dmamap_alloc, (pciio_dmamap_free_f *) pcibr_dmamap_free, (pciio_dmamap_addr_f *) pcibr_dmamap_addr, - (pciio_dmamap_list_f *) pcibr_dmamap_list, (pciio_dmamap_done_f *) pcibr_dmamap_done, (pciio_dmatrans_addr_f *) pcibr_dmatrans_addr, - (pciio_dmatrans_list_f *) pcibr_dmatrans_list, (pciio_dmamap_drain_f *) pcibr_dmamap_drain, (pciio_dmaaddr_drain_f *) pcibr_dmaaddr_drain, (pciio_dmalist_drain_f *) pcibr_dmalist_drain, diff --git a/arch/ia64/sn/io/sn2/sgi_io_init.c b/arch/ia64/sn/io/sn2/sgi_io_init.c deleted file mode 100644 index ed1417ed456747..00000000000000 --- a/arch/ia64/sn/io/sn2/sgi_io_init.c +++ /dev/null @@ -1,226 +0,0 @@ -/* $Id$ - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 1992 - 1997, 2000-2003 Silicon Graphics, Inc. All rights reserved. - */ - -#include <linux/types.h> -#include <linux/config.h> -#include <linux/slab.h> -#include <asm/sn/sgi.h> -#include <asm/sn/io.h> -#include <asm/sn/sn_cpuid.h> -#include <asm/sn/klconfig.h> -#include <asm/sn/sn_private.h> -#include <asm/sn/pci/pciba.h> -#include <linux/smp.h> - -extern void mlreset(void); -extern int init_hcl(void); -extern void klgraph_hack_init(void); -extern void hubspc_init(void); -extern void pciio_init(void); -extern void pcibr_init(void); -extern void xtalk_init(void); -extern void xbow_init(void); -extern void xbmon_init(void); -extern void pciiox_init(void); -extern void pic_init(void); -extern void usrpci_init(void); -extern void ioc3_init(void); -extern void initialize_io(void); -extern void klhwg_add_all_modules(devfs_handle_t); -extern void klhwg_add_all_nodes(devfs_handle_t); - -void sn_mp_setup(void); -extern devfs_handle_t hwgraph_root; -extern void io_module_init(void); -extern void pci_bus_cvlink_init(void); -extern void temp_hack(void); - -extern int pci_bus_to_hcl_cvlink(void); - -/* #define DEBUG_IO_INIT 1 */ -#ifdef DEBUG_IO_INIT -#define DBG(x...) printk(x) -#else -#define DBG(x...) -#endif /* DEBUG_IO_INIT */ - -/* - * per_hub_init - * - * This code is executed once for each Hub chip. - */ -static void -per_hub_init(cnodeid_t cnode) -{ - nasid_t nasid; - nodepda_t *npdap; - ii_icmr_u_t ii_icmr; - ii_ibcr_u_t ii_ibcr; - - nasid = COMPACT_TO_NASID_NODEID(cnode); - - ASSERT(nasid != INVALID_NASID); - ASSERT(NASID_TO_COMPACT_NODEID(nasid) == cnode); - - npdap = NODEPDA(cnode); - - REMOTE_HUB_S(nasid, IIO_IWEIM, 0x8000); - - /* - * Set the total number of CRBs that can be used. - */ - ii_icmr.ii_icmr_regval= 0x0; - ii_icmr.ii_icmr_fld_s.i_c_cnt = 0xf; - REMOTE_HUB_S(nasid, IIO_ICMR, ii_icmr.ii_icmr_regval); - - /* - * Set the number of CRBs that both of the BTEs combined - * can use minus 1. - */ - ii_ibcr.ii_ibcr_regval= 0x0; - ii_ibcr.ii_ibcr_fld_s.i_count = 0x8; - REMOTE_HUB_S(nasid, IIO_IBCR, ii_ibcr.ii_ibcr_regval); - - /* - * Set CRB timeout to be 10ms. - */ -#ifdef BRINGUP2 - REMOTE_HUB_S(nasid, IIO_ICTP, 0xffffff ); - REMOTE_HUB_S(nasid, IIO_ICTO, 0xff); - //REMOTE_HUB_S(nasid, IIO_IWI, 0x00FF00FF00FFFFFF); -#endif - - /* Initialize error interrupts for this hub. */ - hub_error_init(cnode); -} - -/* - * This routine is responsible for the setup of all the IRIX hwgraph style - * stuff that's been pulled into linux. It's called by sn_pci_find_bios which - * is called just before the generic Linux PCI layer does its probing (by - * platform_pci_fixup aka sn_pci_fixup). - * - * It is very IMPORTANT that this call is only made by the Master CPU! - * - */ - -void -sgi_master_io_infr_init(void) -{ - int cnode; - extern void kdba_io_init(); - - /* - * Do any early init stuff .. einit_tbl[] etc. - */ - init_hcl(); /* Sets up the hwgraph compatibility layer with devfs */ - - /* - * initialize the Linux PCI to xwidget vertexes .. - */ - pci_bus_cvlink_init(); - - kdba_io_init(); - -#ifdef BRINGUP - /* - * Hack to provide statically initialzed klgraph entries. - */ - DBG("--> sgi_master_io_infr_init: calling klgraph_hack_init()\n"); - klgraph_hack_init(); -#endif /* BRINGUP */ - - /* - * This is the Master CPU. Emulate mlsetup and main.c in Irix. - */ - mlreset(); - - /* - * allowboot() is called by kern/os/main.c in main() - * Emulate allowboot() ... - * per_cpu_init() - only need per_hub_init() - * cpu_io_setup() - Nothing to do. - * - */ - sn_mp_setup(); - - for (cnode = 0; cnode < numnodes; cnode++) { - per_hub_init(cnode); - } - - /* We can do headless hub cnodes here .. */ - - /* - * io_init[] stuff. - * - * Get SGI IO Infrastructure drivers to init and register with - * each other etc. - */ - - hubspc_init(); - pciio_init(); - pcibr_init(); - pic_init(); - xtalk_init(); - xbow_init(); - xbmon_init(); - pciiox_init(); - usrpci_init(); - ioc3_init(); - - /* - * - * Our IO Infrastructure drivers are in place .. - * Initialize the whole IO Infrastructure .. xwidget/device probes. - * - */ - initialize_io(); - pci_bus_to_hcl_cvlink(); - -#ifdef CONFIG_PCIBA - DBG("--> sgi_master_io_infr_init: calling pciba_init()\n"); -#ifndef BRINGUP2 - pciba_init(); -#endif -#endif -} - -/* - * One-time setup for MP SN. - * Allocate per-node data, slurp prom klconfig information and - * convert it to hwgraph information. - */ -void -sn_mp_setup(void) -{ - cpuid_t cpu; - - for (cpu = 0; cpu < NR_CPUS; cpu++) { - /* Skip holes in CPU space */ - if (cpu_enabled(cpu)) { - init_platform_pda(cpu); - } - } - - /* - * Initialize platform-dependent vertices in the hwgraph: - * module - * node - * cpu - * memory - * slot - * hub - * router - * xbow - */ - - io_module_init(); /* Use to be called module_init() .. */ - klhwg_add_all_modules(hwgraph_root); - klhwg_add_all_nodes(hwgraph_root); -} diff --git a/arch/ia64/sn/io/sn2/shub.c b/arch/ia64/sn/io/sn2/shub.c index ee48cd1eb34e7b..9709c01cc27183 100644 --- a/arch/ia64/sn/io/sn2/shub.c +++ b/arch/ia64/sn/io/sn2/shub.c @@ -97,6 +97,14 @@ shub_mmr_write(cnodeid_t cnode, shubreg_t reg, uint64_t val) } static inline void +shub_mmr_write_iospace(cnodeid_t cnode, shubreg_t reg, uint64_t val) +{ + int nasid = cnodeid_to_nasid(cnode); + + REMOTE_HUB_S(nasid, reg, val); +} + +static inline void shub_mmr_write32(cnodeid_t cnode, shubreg_t reg, uint32_t val) { int nasid = cnodeid_to_nasid(cnode); @@ -118,6 +126,14 @@ shub_mmr_read(cnodeid_t cnode, shubreg_t reg) return val; } +static inline uint64_t +shub_mmr_read_iospace(cnodeid_t cnode, shubreg_t reg) +{ + int nasid = cnodeid_to_nasid(cnode); + + return REMOTE_HUB_L(nasid, reg); +} + static inline uint32_t shub_mmr_read32(cnodeid_t cnode, shubreg_t reg) { @@ -182,11 +198,9 @@ shubstats_ioctl(struct inode *inode, struct file *file, { cnodeid_t cnode; uint64_t longarg; - devfs_handle_t d; + vertex_hdl_t d; int nasid; - if ((d = devfs_get_handle_from_inode(inode)) == NULL) - return -ENODEV; cnode = (cnodeid_t)hwgraph_fastinfo_get(d); switch (cmd) { @@ -231,3 +245,252 @@ shubstats_ioctl(struct inode *inode, struct file *file, struct file_operations shub_mon_fops = { ioctl: shubstats_ioctl, }; + +/* + * "linkstatd" kernel thread to export SGI Numalink + * stats via /proc/sgi_sn/linkstats + */ +static struct s_linkstats { + uint64_t hs_ni_sn_errors[2]; + uint64_t hs_ni_cb_errors[2]; + uint64_t hs_ni_retry_errors[2]; + int hs_ii_up; + uint64_t hs_ii_sn_errors; + uint64_t hs_ii_cb_errors; + uint64_t hs_ii_retry_errors; +} *sn_linkstats; + +static spinlock_t sn_linkstats_lock; +static unsigned long sn_linkstats_starttime; +static unsigned long sn_linkstats_samples; +static unsigned long sn_linkstats_overflows; +static unsigned long sn_linkstats_update_msecs; + +void +sn_linkstats_reset(unsigned long msecs) +{ + int cnode; + uint64_t iio_wstat; + uint64_t llp_csr_reg; + + spin_lock(&sn_linkstats_lock); + memset(sn_linkstats, 0, numnodes * sizeof(struct s_linkstats)); + for (cnode=0; cnode < numnodes; cnode++) { + shub_mmr_write(cnode, SH_NI0_LLP_ERR, 0L); + shub_mmr_write(cnode, SH_NI1_LLP_ERR, 0L); + shub_mmr_write_iospace(cnode, IIO_LLP_LOG, 0L); + + /* zero the II retry counter */ + iio_wstat = shub_mmr_read_iospace(cnode, IIO_WSTAT); + iio_wstat &= 0xffffffffff00ffff; /* bits 23:16 */ + shub_mmr_write_iospace(cnode, IIO_WSTAT, iio_wstat); + + /* Check if the II xtalk link is working */ + llp_csr_reg = shub_mmr_read_iospace(cnode, IIO_LLP_CSR); + if (llp_csr_reg & IIO_LLP_CSR_IS_UP) + sn_linkstats[cnode].hs_ii_up = 1; + } + + sn_linkstats_update_msecs = msecs; + sn_linkstats_samples = 0; + sn_linkstats_overflows = 0; + sn_linkstats_starttime = jiffies; + spin_unlock(&sn_linkstats_lock); +} + +int +linkstatd_thread(void *unused) +{ + int cnode; + int overflows; + uint64_t reg[2]; + uint64_t iio_wstat = 0L; + ii_illr_u_t illr; + struct s_linkstats *lsp; + struct task_struct *tsk = current; + + daemonize("linkstatd"); + set_user_nice(tsk, 19); + sigfillset(&tsk->blocked); + strcpy(tsk->comm, "linkstatd"); + + while(1) { + set_current_state(TASK_INTERRUPTIBLE); + schedule_timeout(sn_linkstats_update_msecs * HZ / 1000); + + spin_lock(&sn_linkstats_lock); + + overflows = 0; + for (lsp=sn_linkstats, cnode=0; cnode < numnodes; cnode++, lsp++) { + reg[0] = shub_mmr_read(cnode, SH_NI0_LLP_ERR); + reg[1] = shub_mmr_read(cnode, SH_NI1_LLP_ERR); + if (lsp->hs_ii_up) { + illr = (ii_illr_u_t)shub_mmr_read_iospace(cnode, IIO_LLP_LOG); + iio_wstat = shub_mmr_read_iospace(cnode, IIO_WSTAT); + } + + if (!overflows && ( + (reg[0] & SH_NI0_LLP_ERR_RX_SN_ERR_COUNT_MASK) == + SH_NI0_LLP_ERR_RX_SN_ERR_COUNT_MASK || + (reg[0] & SH_NI0_LLP_ERR_RX_CB_ERR_COUNT_MASK) == + SH_NI0_LLP_ERR_RX_CB_ERR_COUNT_MASK || + (reg[1] & SH_NI1_LLP_ERR_RX_SN_ERR_COUNT_MASK) == + SH_NI1_LLP_ERR_RX_SN_ERR_COUNT_MASK || + (reg[1] & SH_NI1_LLP_ERR_RX_CB_ERR_COUNT_MASK) == + SH_NI1_LLP_ERR_RX_CB_ERR_COUNT_MASK || + (lsp->hs_ii_up && illr.ii_illr_fld_s.i_sn_cnt == IIO_LLP_SN_MAX) || + (lsp->hs_ii_up && illr.ii_illr_fld_s.i_cb_cnt == IIO_LLP_CB_MAX))) { + overflows = 1; + } + +#define LINKSTAT_UPDATE(reg, cnt, mask, shift) cnt += (reg & mask) >> shift + + LINKSTAT_UPDATE(reg[0], lsp->hs_ni_sn_errors[0], + SH_NI0_LLP_ERR_RX_SN_ERR_COUNT_MASK, + SH_NI0_LLP_ERR_RX_SN_ERR_COUNT_SHFT); + + LINKSTAT_UPDATE(reg[1], lsp->hs_ni_sn_errors[1], + SH_NI1_LLP_ERR_RX_SN_ERR_COUNT_MASK, + SH_NI1_LLP_ERR_RX_SN_ERR_COUNT_SHFT); + + LINKSTAT_UPDATE(reg[0], lsp->hs_ni_cb_errors[0], + SH_NI0_LLP_ERR_RX_CB_ERR_COUNT_MASK, + SH_NI0_LLP_ERR_RX_CB_ERR_COUNT_SHFT); + + LINKSTAT_UPDATE(reg[1], lsp->hs_ni_cb_errors[1], + SH_NI1_LLP_ERR_RX_CB_ERR_COUNT_MASK, + SH_NI1_LLP_ERR_RX_CB_ERR_COUNT_SHFT); + + LINKSTAT_UPDATE(reg[0], lsp->hs_ni_retry_errors[0], + SH_NI0_LLP_ERR_RETRY_COUNT_MASK, + SH_NI0_LLP_ERR_RETRY_COUNT_SHFT); + + LINKSTAT_UPDATE(reg[1], lsp->hs_ni_retry_errors[1], + SH_NI1_LLP_ERR_RETRY_COUNT_MASK, + SH_NI1_LLP_ERR_RETRY_COUNT_SHFT); + + if (lsp->hs_ii_up) { + /* II sn and cb errors */ + lsp->hs_ii_sn_errors += illr.ii_illr_fld_s.i_sn_cnt; + lsp->hs_ii_cb_errors += illr.ii_illr_fld_s.i_cb_cnt; + lsp->hs_ii_retry_errors += (iio_wstat & 0x0000000000ff0000) >> 16; + + shub_mmr_write(cnode, SH_NI0_LLP_ERR, 0L); + shub_mmr_write(cnode, SH_NI1_LLP_ERR, 0L); + shub_mmr_write_iospace(cnode, IIO_LLP_LOG, 0L); + + /* zero the II retry counter */ + iio_wstat = shub_mmr_read_iospace(cnode, IIO_WSTAT); + iio_wstat &= 0xffffffffff00ffff; /* bits 23:16 */ + shub_mmr_write_iospace(cnode, IIO_WSTAT, iio_wstat); + } + } + + sn_linkstats_samples++; + if (overflows) + sn_linkstats_overflows++; + + spin_unlock(&sn_linkstats_lock); + } +} + +static char * +rate_per_minute(uint64_t val, uint64_t secs) +{ + static char buf[16]; + uint64_t a=0, b=0, c=0, d=0; + + if (secs) { + a = 60 * val / secs; + b = 60 * 10 * val / secs - (10 * a); + c = 60 * 100 * val / secs - (100 * a) - (10 * b); + d = 60 * 1000 * val / secs - (1000 * a) - (100 * b) - (10 * c); + } + sprintf(buf, "%4lu.%lu%lu%lu", a, b, c, d); + + return buf; +} + +int +sn_linkstats_get(char *page) +{ + int n = 0; + int cnode; + int nlport; + struct s_linkstats *lsp; + nodepda_t *npda; + uint64_t snsum = 0; + uint64_t cbsum = 0; + uint64_t retrysum = 0; + uint64_t snsum_ii = 0; + uint64_t cbsum_ii = 0; + uint64_t retrysum_ii = 0; + uint64_t secs; + + spin_lock(&sn_linkstats_lock); + secs = (jiffies - sn_linkstats_starttime) / HZ; + + n += sprintf(page, "# SGI Numalink stats v1 : %lu samples, %lu o/flows, update %lu msecs\n", + sn_linkstats_samples, sn_linkstats_overflows, sn_linkstats_update_msecs); + + n += sprintf(page+n, "%-37s %8s %8s %8s %8s\n", + "# Numalink", "sn errs", "cb errs", "cb/min", "retries"); + + for (lsp=sn_linkstats, cnode=0; cnode < numnodes; cnode++, lsp++) { + npda = NODEPDA(cnode); + + /* two NL links on each SHub */ + for (nlport=0; nlport < 2; nlport++) { + cbsum += lsp->hs_ni_cb_errors[nlport]; + snsum += lsp->hs_ni_sn_errors[nlport]; + retrysum += lsp->hs_ni_retry_errors[nlport]; + + /* avoid buffer overrun (should be using seq_read API) */ + if (numnodes > 64) + continue; + + n += sprintf(page + n, "/%s/link/%d %8lu %8lu %8s %8lu\n", + npda->hwg_node_name, nlport+1, lsp->hs_ni_sn_errors[nlport], + lsp->hs_ni_cb_errors[nlport], + rate_per_minute(lsp->hs_ni_cb_errors[nlport], secs), + lsp->hs_ni_retry_errors[nlport]); + } + + /* one II port on each SHub (may not be connected) */ + if (lsp->hs_ii_up) { + n += sprintf(page + n, "/%s/xtalk %8lu %8lu %8s %8lu\n", + npda->hwg_node_name, lsp->hs_ii_sn_errors, + lsp->hs_ii_cb_errors, rate_per_minute(lsp->hs_ii_cb_errors, secs), + lsp->hs_ii_retry_errors); + + snsum_ii += lsp->hs_ii_sn_errors; + cbsum_ii += lsp->hs_ii_cb_errors; + retrysum_ii += lsp->hs_ii_retry_errors; + } + } + + n += sprintf(page + n, "%-37s %8lu %8lu %8s %8lu\n", + "System wide NL totals", snsum, cbsum, + rate_per_minute(cbsum, secs), retrysum); + + n += sprintf(page + n, "%-37s %8lu %8lu %8s %8lu\n", + "System wide II totals", snsum_ii, cbsum_ii, + rate_per_minute(cbsum_ii, secs), retrysum_ii); + + spin_unlock(&sn_linkstats_lock); + + return n; +} + +static int __init +linkstatd_init(void) +{ + spin_lock_init(&sn_linkstats_lock); + sn_linkstats = kmalloc(numnodes * sizeof(struct s_linkstats), GFP_KERNEL); + sn_linkstats_reset(60000UL); /* default 60 second update interval */ + kernel_thread(linkstatd_thread, NULL, CLONE_FS | CLONE_FILES); + + return 0; +} + +__initcall(linkstatd_init); diff --git a/arch/ia64/sn/io/sn2/shub_intr.c b/arch/ia64/sn/io/sn2/shub_intr.c index d64022e1cc1179..f081c260f39a3c 100644 --- a/arch/ia64/sn/io/sn2/shub_intr.c +++ b/arch/ia64/sn/io/sn2/shub_intr.c @@ -4,7 +4,7 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. * - * Copyright (C) 1992-1997, 2000-2002 Silicon Graphics, Inc. All Rights Reserved. + * Copyright (C) 1992-1997, 2000-2003 Silicon Graphics, Inc. All Rights Reserved. */ #include <linux/types.h> @@ -30,7 +30,7 @@ /* ARGSUSED */ void -hub_intr_init(devfs_handle_t hubv) +hub_intr_init(vertex_hdl_t hubv) { } @@ -45,9 +45,9 @@ hub_widget_id(nasid_t nasid) } static hub_intr_t -do_hub_intr_alloc(devfs_handle_t dev, +do_hub_intr_alloc(vertex_hdl_t dev, device_desc_t dev_desc, - devfs_handle_t owner_dev, + vertex_hdl_t owner_dev, int uncond_nothread) { cpuid_t cpu = 0; @@ -71,7 +71,7 @@ do_hub_intr_alloc(devfs_handle_t dev, cpuphys = cpu_physical_id(cpu); slice = cpu_physical_id_to_slice(cpuphys); nasid = cpu_physical_id_to_nasid(cpuphys); - cnode = cpu_to_node_map[cpu]; + cnode = cpuid_to_cnodeid(cpu); if (slice) { xtalk_addr = SH_II_INT1 | ((unsigned long)nasid << 36) | (1UL << 47); @@ -101,17 +101,17 @@ do_hub_intr_alloc(devfs_handle_t dev, } hub_intr_t -hub_intr_alloc(devfs_handle_t dev, +hub_intr_alloc(vertex_hdl_t dev, device_desc_t dev_desc, - devfs_handle_t owner_dev) + vertex_hdl_t owner_dev) { return(do_hub_intr_alloc(dev, dev_desc, owner_dev, 0)); } hub_intr_t -hub_intr_alloc_nothd(devfs_handle_t dev, +hub_intr_alloc_nothd(vertex_hdl_t dev, device_desc_t dev_desc, - devfs_handle_t owner_dev) + vertex_hdl_t owner_dev) { return(do_hub_intr_alloc(dev, dev_desc, owner_dev, 1)); } @@ -188,18 +188,3 @@ hub_intr_disconnect(hub_intr_t intr_hdl) ASSERT(rv == 0); intr_hdl->i_flags &= ~HUB_INTR_IS_CONNECTED; } - - -/* - * Return a hwgraph vertex that represents the CPU currently - * targeted by an interrupt. - */ -devfs_handle_t -hub_intr_cpu_get(hub_intr_t intr_hdl) -{ - cpuid_t cpuid = intr_hdl->i_cpuid; - - ASSERT(cpuid != CPU_NONE); - - return(cpuid_to_vertex(cpuid)); -} diff --git a/arch/ia64/sn/io/sn2/shuberror.c b/arch/ia64/sn/io/sn2/shuberror.c index 0861a3b0831679..2af0ae94f8adaa 100644 --- a/arch/ia64/sn/io/sn2/shuberror.c +++ b/arch/ia64/sn/io/sn2/shuberror.c @@ -4,13 +4,14 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. * - * Copyright (C) 1992 - 1997, 2000,2002 Silicon Graphics, Inc. All rights reserved. + * Copyright (C) 1992 - 1997, 2000,2002-2003 Silicon Graphics, Inc. All rights reserved. */ #include <linux/types.h> #include <linux/slab.h> #include <linux/irq.h> +#include <asm/io.h> #include <asm/irq.h> #include <asm/smp.h> #include <asm/sn/sgi.h> @@ -27,6 +28,7 @@ #include <asm/sn/xtalk/xtalk.h> #include <asm/sn/pci/pcibr_private.h> #include <asm/sn/intr.h> +#include <asm/sn/ioerror_handling.h> #include <asm/sn/ioerror.h> #include <asm/sn/sn2/shubio.h> #include <asm/sn/bte.h> @@ -34,21 +36,18 @@ extern void hubni_eint_init(cnodeid_t cnode); extern void hubii_eint_init(cnodeid_t cnode); 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_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, int bteop); +int hubiio_crb_error_handler(vertex_hdl_t hub_v, hubinfo_t hinfo); +int hubiio_prb_error_handler(vertex_hdl_t hub_v, hubinfo_t hinfo); +extern void bte_crb_error_handler(vertex_hdl_t hub_v, int btenum, int crbnum, ioerror_t *ioe, int bteop); +void print_crb_fields(int crb_num, ii_icrb0_a_u_t icrba, + ii_icrb0_b_u_t icrbb, ii_icrb0_c_u_t icrbc, + ii_icrb0_d_u_t icrbd, ii_icrb0_e_u_t icrbe); extern int maxcpus; +extern error_return_code_t error_state_set(vertex_hdl_t v,error_state_t new_state); #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 hub_error_clear(nasid_t nasid) { @@ -74,9 +73,7 @@ hub_error_clear(nasid_t nasid) REMOTE_HUB_S(nasid, IIO_IOPRB_0 + (i * sizeof(hubreg_t)), prb.iprb_regval); } - REMOTE_HUB_S(nasid, IIO_IO_ERR_CLR, -1); - idsr = REMOTE_HUB_L(nasid, IIO_IIDSR); - REMOTE_HUB_S(nasid, IIO_IIDSR, (idsr & ~(IIO_IIDSR_SENT_MASK))); + REMOTE_HUB_S(nasid, IIO_IECLR, -1); } @@ -117,7 +114,6 @@ hub_error_init(cnodeid_t cnode) * Returns : None. */ - void hubii_eint_init(cnodeid_t cnode) { @@ -125,33 +121,41 @@ hubii_eint_init(cnodeid_t cnode) ii_iidsr_u_t hubio_eint; hubinfo_t hinfo; cpuid_t intr_cpu; - devfs_handle_t hub_v; + vertex_hdl_t hub_v; int bit_pos_to_irq(int bit); + ii_ilcsr_u_t ilcsr; - hub_v = (devfs_handle_t)cnodeid_to_vertex(cnode); + hub_v = (vertex_hdl_t)cnodeid_to_vertex(cnode); ASSERT_ALWAYS(hub_v); hubinfo_get(hub_v, &hinfo); ASSERT(hinfo); 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. Disable LLP. Clear old errors. + * Enable interrupts to handle BTE errors. + */ + ilcsr.ii_ilcsr_fld_s.i_llp_en = 0; + REMOTE_HUB_S(hinfo->h_nasid, IIO_ILCSR, ilcsr.ii_ilcsr_regval); + } + /* Select a possible interrupt target where there is a free interrupt * bit and also reserve the interrupt bit for this IO error interrupt */ - intr_cpu = intr_heuristic(hub_v,0,-1,0,hub_v, + intr_cpu = intr_heuristic(hub_v,0,SGI_II_ERROR,0,hub_v, "HUB IO error interrupt",&bit); if (intr_cpu == CPU_NONE) { printk("hubii_eint_init: intr_reserve_level failed, cnode %d", cnode); return; } - 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); - 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 + rv = intr_connect_level(intr_cpu, SGI_II_ERROR, 0, NULL); + request_irq(SGI_II_ERROR, hubii_eint_handler, SA_SHIRQ, "SN_hub_error", (void *)hub_v); + irq_desc(bit)->status |= SN2_IRQ_PER_HUB; ASSERT_ALWAYS(rv >= 0); hubio_eint.ii_iidsr_regval = 0; hubio_eint.ii_iidsr_fld_s.i_enable = 1; @@ -167,18 +171,29 @@ hubii_eint_init(cnodeid_t cnode) void hubii_eint_handler (int irq, void *arg, struct pt_regs *ep) { - devfs_handle_t hub_v; + vertex_hdl_t hub_v; hubinfo_t hinfo; ii_wstat_u_t wstat; hubreg_t idsr; + ii_ilcsr_u_t ilcsr; /* two levels of casting avoids compiler warning.!! */ - hub_v = (devfs_handle_t)(long)(arg); + hub_v = (vertex_hdl_t)(long)(arg); ASSERT(hub_v); hubinfo_get(hub_v, &hinfo); + idsr = REMOTE_HUB_L(hinfo->h_nasid, IIO_ICMR); +#if 0 + if (idsr & 0x1) { + /* ICMR bit is set .. we are getting into "Spurious Interrupts condition. */ + printk("Cnode %d II has seen the ICMR condition\n", hinfo->h_cnodeid); + printk("***** Please file PV with the above messages *****\n"); + /* panic("We have to panic to prevent further unknown states ..\n"); */ + } +#endif + /* * Identify the reason for error. */ @@ -218,10 +233,26 @@ hubii_eint_handler (int irq, void *arg, struct pt_regs *ep) * Note: we may never be able to print this, if the II talking * to Xbow which hosts the console is dead. */ - printk("Hub %d to Xtalk Link failed (II_ECRAZY) Reason: %s", - hinfo->h_cnodeid, reason); + ilcsr.ii_ilcsr_regval = REMOTE_HUB_L(hinfo->h_nasid, IIO_ILCSR); + if (ilcsr.ii_ilcsr_fld_s.i_llp_en == 1) { /* Link is enabled */ + printk("Hub %d, cnode %d to Xtalk Link failed (II_ECRAZY) Reason: %s", + hinfo->h_nasid, hinfo->h_cnodeid, reason); + } } + + /* + * Before processing any interrupt related information, clear all + * error indication and reenable interrupts. This will prevent + * lost interrupts due to the interrupt handler scanning past a PRB/CRB + * which has not errorred yet and then the PRB/CRB goes into error. + * Note, PRB errors are cleared individually. + */ + REMOTE_HUB_S(hinfo->h_nasid, IIO_IECLR, 0xff0000); + idsr = REMOTE_HUB_L(hinfo->h_nasid, IIO_IIDSR) & ~IIO_IIDSR_SENT_MASK; + REMOTE_HUB_S(hinfo->h_nasid, IIO_IIDSR, idsr); + + /* * It's a toss as to which one among PRB/CRB to check first. * Current decision is based on the severity of the errors. @@ -232,14 +263,6 @@ hubii_eint_handler (int irq, void *arg, struct pt_regs *ep) */ (void)hubiio_crb_error_handler(hub_v, hinfo); (void)hubiio_prb_error_handler(hub_v, hinfo); - /* - * If we reach here, it indicates crb/prb handlers successfully - * handled the error. So, re-enable II to send more interrupt - * and return. - */ - REMOTE_HUB_S(hinfo->h_nasid, IIO_IECLR, 0xffffff); - idsr = REMOTE_HUB_L(hinfo->h_nasid, IIO_IIDSR) & ~IIO_IIDSR_SENT_MASK; - REMOTE_HUB_S(hinfo->h_nasid, IIO_IIDSR, idsr); } /* @@ -295,6 +318,105 @@ char *hubiio_crb_errors[] = { "Xtalk Error Packet" }; +void +print_crb_fields(int crb_num, ii_icrb0_a_u_t icrba, + ii_icrb0_b_u_t icrbb, ii_icrb0_c_u_t icrbc, + ii_icrb0_d_u_t icrbd, ii_icrb0_e_u_t icrbe) +{ + printk("CRB %d regA\n\t" + "a_iow 0x%x\n\t" + "valid0x%x\n\t" + "Address0x%lx\n\t" + "a_tnum 0x%x\n\t" + "a_sidn 0x%x\n", + crb_num, + icrba.a_iow, + icrba.a_valid, + icrba.a_addr, + icrba.a_tnum, + icrba.a_sidn); + printk("CRB %d regB\n\t" + "b_imsgtype 0x%x\n\t" + "b_imsg 0x%x\n" + "\tb_use_old 0x%x\n\t" + "b_initiator 0x%x\n\t" + "b_exc 0x%x\n" + "\tb_ackcnt 0x%x\n\t" + "b_resp 0x%x\n\t" + "b_ack 0x%x\n" + "\tb_hold 0x%x\n\t" + "b_wb 0x%x\n\t" + "b_intvn 0x%x\n" + "\tb_stall_ib 0x%x\n\t" + "b_stall_int 0x%x\n" + "\tb_stall_bte_0 0x%x\n\t" + "b_stall_bte_1 0x%x\n" + "\tb_error 0x%x\n\t" + "b_lnetuce 0x%x\n\t" + "b_mark 0x%x\n\t" + "b_xerr 0x%x\n", + crb_num, + icrbb.b_imsgtype, + icrbb.b_imsg, + icrbb.b_use_old, + icrbb.b_initiator, + icrbb.b_exc, + icrbb.b_ackcnt, + icrbb.b_resp, + icrbb.b_ack, + icrbb.b_hold, + icrbb.b_wb, + icrbb.b_intvn, + icrbb.b_stall_ib, + icrbb.b_stall_int, + icrbb.b_stall_bte_0, + icrbb.b_stall_bte_1, + icrbb.b_error, + icrbb.b_lnetuce, + icrbb.b_mark, + icrbb.b_xerr); + printk("CRB %d regC\n\t" + "c_source 0x%x\n\t" + "c_xtsize 0x%x\n\t" + "c_cohtrans 0x%x\n\t" + "c_btenum 0x%x\n\t" + "c_gbr 0x%x\n\t" + "c_doresp 0x%x\n\t" + "c_barrop 0x%x\n\t" + "c_suppl 0x%x\n", + crb_num, + icrbc.c_source, + icrbc.c_xtsize, + icrbc.c_cohtrans, + icrbc.c_btenum, + icrbc.c_gbr, + icrbc.c_doresp, + icrbc.c_barrop, + icrbc.c_suppl); + printk("CRB %d regD\n\t" + "d_bteaddr 0x%lx\n\t" + "d_bteop 0x%x\n\t" + "d_pripsc 0x%x\n\t" + "d_pricnt 0x%x\n\t" + "d_sleep 0x%x\n\t", + crb_num, + icrbd.d_bteaddr, + icrbd.d_bteop, + icrbd.d_pripsc, + icrbd.d_pricnt, + icrbd.d_sleep); + printk("CRB %d regE\n\t" + "icrbe_timeout 0x%x\n\t" + "icrbe_context 0x%x\n\t" + "icrbe_toutvld 0x%x\n\t" + "icrbe_ctxtvld 0x%x\n\t", + crb_num, + icrbe.icrbe_timeout, + icrbe.icrbe_context, + icrbe.icrbe_toutvld, + icrbe.icrbe_ctxtvld); +} + /* * hubiio_crb_error_handler * @@ -317,7 +439,7 @@ char *hubiio_crb_errors[] = { */ int -hubiio_crb_error_handler(devfs_handle_t hub_v, hubinfo_t hinfo) +hubiio_crb_error_handler(vertex_hdl_t hub_v, hubinfo_t hinfo) { cnodeid_t cnode; nasid_t nasid; @@ -335,6 +457,9 @@ hubiio_crb_error_handler(devfs_handle_t hub_v, hubinfo_t hinfo) cnode = NASID_TO_COMPACT_NODEID(nasid); /* + * XXX - Add locking for any recovery actions + */ + /* * Scan through all CRBs in the Hub, and handle the errors * in any of the CRBs marked. */ @@ -373,16 +498,11 @@ hubiio_crb_error_handler(devfs_handle_t hub_v, hubinfo_t hinfo) else /* b_initiator bit 2 gives BTE number */ 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. - */ + hubiio_crb_free(hinfo, i); + bte_crb_error_handler(hub_v, bte_num, i, &ioerror, icrbd.d_bteop); - hubiio_crb_free(hinfo, i); num_errors++; continue; } @@ -430,6 +550,86 @@ hubiio_crb_error_handler(devfs_handle_t hub_v, hubinfo_t hinfo) 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: + case IIO_ICRB_ECODE_TOUT: + case IIO_ICRB_ECODE_XTERR: + printk("Shub II CRB %d: error %s on hub cnodeid: %d", + i, 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); + + /* Go through the error bit lookup phase */ + if (error_state_set(hub_v, ERROR_STATE_LOOKUP) == + ERROR_RETURN_CODE_CANNOT_SET_STATE) + return(IOERROR_UNHANDLED); + 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); + }else { + printk("Unable to handle %s on hub %d", + hubiio_crb_errors[icrbb.b_ecode], + cnode); + /* panic; */ + } + /* Go to Next error */ + print_crb_fields(i, icrba, icrbb, icrbc, + icrbd, icrbe); + hubiio_crb_free(hinfo, i); + continue; + case IIO_ICRB_ECODE_PRERR: + case IIO_ICRB_ECODE_DERR: + printk("Shub II CRB %d: error %s on hub : %d", + i, hubiio_crb_errors[icrbb.b_ecode], cnode); + /* panic */ + default: + printk("Shub II CRB error (code : %d) on hub : %d", + icrbb.b_ecode, cnode); + /* panic */ + } + } + /* + * Error is not indicated via the errcode field + * Check other error indications in this register. + */ + if (icrbb.b_xerr) { + printk("Shub II CRB %d: Xtalk Packet with error bit set to hub %d", + i, cnode); + /* panic */ + } + if (icrbb.b_lnetuce) { + printk("Shub II CRB %d: Uncorrectable data error detected on data " + " from NUMAlink to node %d", + i, cnode); + /* panic */ + } + print_crb_fields(i, icrba, icrbb, icrbc, icrbd, icrbe); + + + + if (icrbb.b_error) { /* @@ -488,7 +688,7 @@ hubiio_crb_error_handler(devfs_handle_t hub_v, hubinfo_t hinfo) default: panic("Fatal error (code : %d) on hub : %d", - cnode); + icrbb.b_ecode, cnode); /*NOTREACHED*/ } @@ -568,7 +768,7 @@ hubii_check_widget_disabled(nasid_t nasid, int wnum) * Cleanup involes freeing the PRB register */ static void -hubii_prb_handler(devfs_handle_t hub_v, hubinfo_t hinfo, int wnum) +hubii_prb_handler(vertex_hdl_t hub_v, hubinfo_t hinfo, int wnum) { nasid_t nasid; @@ -576,13 +776,13 @@ hubii_prb_handler(devfs_handle_t hub_v, hubinfo_t hinfo, int wnum) /* * Clear error bit by writing to IECLR register. */ - REMOTE_HUB_S(nasid, IIO_IO_ERR_CLR, (1 << wnum)); + REMOTE_HUB_S(nasid, IIO_IECLR, (1 << wnum)); /* * PIO Write to Widget 'i' got into an error. * Invoke hubiio_error_handler with this information. */ - printk( "Hub nasid %d got a PIO Write error from widget %d, cleaning up and continuing", - nasid, wnum); + printk( "Hub nasid %d got a PIO Write error from widget %d, " + "cleaning up and continuing", nasid, wnum); /* * XXX * It may be necessary to adjust IO PRB counter @@ -591,7 +791,7 @@ hubii_prb_handler(devfs_handle_t hub_v, hubinfo_t hinfo, int wnum) } int -hubiio_prb_error_handler(devfs_handle_t hub_v, hubinfo_t hinfo) +hubiio_prb_error_handler(vertex_hdl_t hub_v, hubinfo_t hinfo) { int wnum; nasid_t nasid; diff --git a/arch/ia64/sn/io/sn2/shubio.c b/arch/ia64/sn/io/sn2/shubio.c index 90294319bf09dc..676498ec0a095b 100644 --- a/arch/ia64/sn/io/sn2/shubio.c +++ b/arch/ia64/sn/io/sn2/shubio.c @@ -30,8 +30,8 @@ #include <asm/sn/sn2/shubio.h> -error_state_t error_state_get(devfs_handle_t v); -error_return_code_t error_state_set(devfs_handle_t v,error_state_t new_state); +error_state_t error_state_get(vertex_hdl_t v); +error_return_code_t error_state_set(vertex_hdl_t v,error_state_t new_state); /* @@ -42,7 +42,7 @@ error_return_code_t error_state_set(devfs_handle_t v,error_state_t new_state); /*ARGSUSED*/ int hub_xp_error_handler( - devfs_handle_t hub_v, + vertex_hdl_t hub_v, nasid_t nasid, int error_code, ioerror_mode_t mode, @@ -50,7 +50,7 @@ hub_xp_error_handler( { /*REFERENCED*/ hubreg_t iio_imem; - devfs_handle_t xswitch; + vertex_hdl_t xswitch; error_state_t e_state; cnodeid_t cnode; @@ -148,7 +148,7 @@ is_widget_pio_enabled(ioerror_t *ioerror) */ int hub_ioerror_handler( - devfs_handle_t hub_v, + vertex_hdl_t hub_v, int error_code, int mode, struct io_error_s *ioerror) @@ -158,6 +158,7 @@ hub_ioerror_handler( int retval = 0; /*REFERENCED*/ iopaddr_t p; + caddr_t cp; IOERROR_DUMP("hub_ioerror_handler", error_code, mode, ioerror); @@ -193,14 +194,14 @@ hub_ioerror_handler( * This is typically true for user mode bus errors while * accessing I/O space. */ - IOERROR_GETVALUE(p,ioerror,vaddr); - if (p){ + IOERROR_GETVALUE(cp,ioerror,vaddr); + if (cp){ /* * If neither in small window nor in large window range, * outright reject it. */ - IOERROR_GETVALUE(p,ioerror,vaddr); - if (NODE_SWIN_ADDR(nasid, (paddr_t)p)){ + IOERROR_GETVALUE(cp,ioerror,vaddr); + if (NODE_SWIN_ADDR(nasid, (paddr_t)cp)){ iopaddr_t hubaddr; xwidgetnum_t widgetnum; iopaddr_t xtalkaddr; @@ -216,7 +217,7 @@ hub_ioerror_handler( IOERROR_SETVALUE(ioerror,xtalkaddr,xtalkaddr); - } else if (NODE_BWIN_ADDR(nasid, (paddr_t)p)){ + } else if (NODE_BWIN_ADDR(nasid, (paddr_t)cp)){ /* * Address corresponds to large window space. * Convert it to xtalk address. @@ -428,11 +429,6 @@ end: return retval; } -#define L_BITSMINOR 18 -#define L_MAXMAJ 0x1ff -#define emajor(x) (int )(((unsigned )(x)>>L_BITSMINOR) & L_MAXMAJ) -#define dev_is_vertex(dev) (emajor((dev_t)(dev)) == 0) - #define INFO_LBL_ERROR_STATE "error_state" #define v_error_state_get(v,s) \ @@ -454,12 +450,12 @@ hwgraph_info_add_LBL(v,INFO_LBL_ERROR_STATE, (arbitrary_info_t)s)) * current state otherwise */ error_state_t -error_state_get(devfs_handle_t v) +error_state_get(vertex_hdl_t v) { error_state_t s; /* Check if we have a valid hwgraph vertex */ - if (!dev_is_vertex(v)) + if ( v == (vertex_hdl_t)0 ) return(ERROR_STATE_NONE); /* Get the labelled info hanging off the vertex which corresponds @@ -479,13 +475,13 @@ error_state_get(devfs_handle_t v) * ERROR_RETURN_CODE_SUCCESS otherwise */ error_return_code_t -error_state_set(devfs_handle_t v,error_state_t new_state) +error_state_set(vertex_hdl_t v,error_state_t new_state) { error_state_t old_state; boolean_t replace = B_TRUE; /* Check if we have a valid hwgraph vertex */ - if (!dev_is_vertex(v)) + if ( v == (vertex_hdl_t)0 ) return(ERROR_RETURN_CODE_GENERAL_FAILURE); diff --git a/arch/ia64/sn/io/sn2/xbow.c b/arch/ia64/sn/io/sn2/xbow.c index dd28e1158d180e..6b229ba28222c2 100644 --- a/arch/ia64/sn/io/sn2/xbow.c +++ b/arch/ia64/sn/io/sn2/xbow.c @@ -11,6 +11,7 @@ #include <linux/slab.h> #include <linux/module.h> #include <linux/sched.h> +#include <linux/interrupt.h> #include <asm/sn/sgi.h> #include <asm/sn/intr.h> #include <asm/sn/sn2/sn_private.h> @@ -19,7 +20,6 @@ #include <asm/sn/invent.h> #include <asm/sn/hcl.h> #include <asm/sn/labelcl.h> -#include <asm/sn/hack.h> #include <asm/sn/pci/bridge.h> #include <asm/sn/xtalk/xtalk_private.h> #include <asm/sn/simulator.h> @@ -60,9 +60,9 @@ int xbow_devflag = D_MP; typedef struct xbow_soft_s *xbow_soft_t; struct xbow_soft_s { - devfs_handle_t conn; /* our connection point */ - devfs_handle_t vhdl; /* xbow's private vertex */ - devfs_handle_t busv; /* the xswitch vertex */ + vertex_hdl_t conn; /* our connection point */ + vertex_hdl_t vhdl; /* xbow's private vertex */ + vertex_hdl_t busv; /* the xswitch vertex */ xbow_t *base; /* PIO pointer to crossbow chip */ char *name; /* hwgraph name */ @@ -90,36 +90,35 @@ struct xbow_soft_s { */ void xbow_mlreset(xbow_t *); -void xbow_init(void); -int xbow_attach(devfs_handle_t); +int xbow_attach(vertex_hdl_t); -int xbow_open(devfs_handle_t *, int, int, cred_t *); -int xbow_close(devfs_handle_t, int, int, cred_t *); +static int xbow_open(struct inode *, struct file *); -int xbow_map(devfs_handle_t, vhandl_t *, off_t, size_t, uint); -int xbow_unmap(devfs_handle_t, vhandl_t *); -int xbow_ioctl(devfs_handle_t, int, void *, int, struct cred *, int *); +int xbow_close(vertex_hdl_t, int, int, cred_t *); + +int xbow_map(vertex_hdl_t, vhandl_t *, off_t, size_t, uint); +int xbow_unmap(vertex_hdl_t, vhandl_t *); +int xbow_ioctl(vertex_hdl_t, int, void *, int, struct cred *, int *); int xbow_widget_present(xbow_t *, int); static int xbow_link_alive(xbow_t *, int); -devfs_handle_t xbow_widget_lookup(devfs_handle_t, int); +vertex_hdl_t xbow_widget_lookup(vertex_hdl_t, int); void xbow_intr_preset(void *, int, xwidgetnum_t, iopaddr_t, xtalk_intr_vector_t); -void xbow_update_perf_counters(devfs_handle_t); -xbow_perf_link_t *xbow_get_perf_counters(devfs_handle_t); -int xbow_enable_perf_counter(devfs_handle_t, int, int, int); -xbow_link_status_t *xbow_get_llp_status(devfs_handle_t); -void xbow_update_llp_status(devfs_handle_t); +void xbow_update_perf_counters(vertex_hdl_t); +xbow_perf_link_t *xbow_get_perf_counters(vertex_hdl_t); +int xbow_enable_perf_counter(vertex_hdl_t, int, int, int); +xbow_link_status_t *xbow_get_llp_status(vertex_hdl_t); +void xbow_update_llp_status(vertex_hdl_t); -int xbow_disable_llp_monitor(devfs_handle_t); -int xbow_enable_llp_monitor(devfs_handle_t); -int xbow_prio_bw_alloc(devfs_handle_t, xwidgetnum_t, xwidgetnum_t, +int xbow_disable_llp_monitor(vertex_hdl_t); +int xbow_enable_llp_monitor(vertex_hdl_t); +int xbow_prio_bw_alloc(vertex_hdl_t, xwidgetnum_t, xwidgetnum_t, unsigned long long, unsigned long long); static void xbow_setwidint(xtalk_intr_t); -void idbg_xbowregs(int64_t); xswitch_reset_link_f xbow_reset_link; @@ -164,8 +163,8 @@ xbow_mmap(struct file * file, struct vm_area_struct * vma) phys_addr = (unsigned long)file->private_data & ~0xc000000000000000; /* Mask out the Uncache bits */ vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); vma->vm_flags |= VM_RESERVED | VM_IO; - error = io_remap_page_range(vma, vma->vm_start, phys_addr, - vma->vm_end - vma->vm_start, + error = io_remap_page_range(vma, phys_addr, vma->vm_start, + vma->vm_end-vma->vm_start, vma->vm_page_prot); return(error); } @@ -188,39 +187,6 @@ xbow_mlreset(xbow_t * xbow) { } -/* - * xbow_init: called with the rest of the device - * driver XXX_init routines. This platform *might* - * have a Crossbow chip, or even several, but it - * might have none. Register with the crosstalk - * generic provider so when we encounter the chip - * the right magic happens. - */ -void -xbow_init(void) -{ - -#if DEBUG && ATTACH_DEBUG - printk("xbow_init\n"); -#endif - - xwidget_driver_register(PXBOW_WIDGET_PART_NUM, - 0, /* XXBOW_WIDGET_MFGR_NUM, */ - "xbow_", - CDL_PRI_HI); /* attach before friends */ - - - xwidget_driver_register(XXBOW_WIDGET_PART_NUM, - 0, /* XXBOW_WIDGET_MFGR_NUM, */ - "xbow_", - CDL_PRI_HI); /* attach before friends */ - - xwidget_driver_register(XBOW_WIDGET_PART_NUM, - XBOW_WIDGET_MFGR_NUM, - "xbow_", - CDL_PRI_HI); /* attach before friends */ -} - #ifdef XBRIDGE_REGS_SIM /* xbow_set_simulated_regs: sets xbow regs as needed * for powering through the boot @@ -257,11 +223,11 @@ xbow_set_simulated_regs(xbow_t *xbow, int port) /*ARGSUSED */ int -xbow_attach(devfs_handle_t conn) +xbow_attach(vertex_hdl_t conn) { /*REFERENCED */ - devfs_handle_t vhdl; - devfs_handle_t busv; + vertex_hdl_t vhdl; + vertex_hdl_t busv; xbow_t *xbow; xbow_soft_t soft; int port; @@ -322,10 +288,10 @@ xbow_attach(devfs_handle_t conn) * file ops. */ vhdl = NULL; - vhdl = devfs_register(conn, EDGE_LBL_XBOW, - DEVFS_FL_AUTO_DEVNUM, 0, 0, - S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP, - &xbow_fops, (void *)xbow); + vhdl = hwgraph_register(conn, EDGE_LBL_XBOW, 0, + DEVFS_FL_AUTO_DEVNUM, 0, 0, + S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP, 0, 0, + (struct file_operations *)&xbow_fops, (void *)xbow); if (!vhdl) { printk(KERN_WARNING "xbow_attach: Unable to create char device for xbow conn %p\n", (void *)conn); @@ -393,6 +359,14 @@ xbow_attach(devfs_handle_t conn) */ intr_hdl = xtalk_intr_alloc(conn, (device_desc_t)0, vhdl); ASSERT(intr_hdl != NULL); + + { + int irq = ((hub_intr_t)intr_hdl)->i_bit; + int cpu = ((hub_intr_t)intr_hdl)->i_cpuid; + + intr_unreserve_level(cpu, irq); + ((hub_intr_t)intr_hdl)->i_bit = SGI_XBOW_ERROR; + } xtalk_intr_connect(intr_hdl, (intr_func_t) xbow_errintr_handler, @@ -400,19 +374,9 @@ xbow_attach(devfs_handle_t conn) (xtalk_intr_setfunc_t) xbow_setwidint, (void *) xbow); - request_irq(CPU_VECTOR_TO_IRQ(((hub_intr_t)intr_hdl)->i_cpuid, - ((hub_intr_t)intr_hdl)->i_bit), - (intr_func_t)xbow_errintr_handler, 0, "XBOW error", + request_irq(SGI_XBOW_ERROR, (void *)xbow_errintr_handler, SA_SHIRQ, "XBOW error", (intr_arg_t) soft); -#ifdef BUS_INT_WAR_NOT_YET - { - void sn_add_polled_interrupt(int, int); - sn_add_polled_interrupt(CPU_VECTOR_TO_IRQ(((hub_intr_t)intr_hdl)->i_cpuid, - ((hub_intr_t)intr_hdl)->i_bit), 5000); - } -#endif - /* * Enable xbow error interrupts @@ -483,24 +447,24 @@ xbow_attach(devfs_handle_t conn) } /*ARGSUSED */ -int -xbow_open(devfs_handle_t *devp, int oflag, int otyp, cred_t *credp) +static int +xbow_open(struct inode *xx, struct file *yy) { return 0; } /*ARGSUSED */ int -xbow_close(devfs_handle_t dev, int oflag, int otyp, cred_t *crp) +xbow_close(vertex_hdl_t dev, int oflag, int otyp, cred_t *crp) { return 0; } /*ARGSUSED */ int -xbow_map(devfs_handle_t dev, vhandl_t *vt, off_t off, size_t len, uint prot) +xbow_map(vertex_hdl_t dev, vhandl_t *vt, off_t off, size_t len, uint prot) { - devfs_handle_t vhdl = dev_to_vhdl(dev); + vertex_hdl_t vhdl = dev_to_vhdl(dev); xbow_soft_t soft = xbow_soft_get(vhdl); int error; @@ -513,7 +477,7 @@ xbow_map(devfs_handle_t dev, vhandl_t *vt, off_t off, size_t len, uint prot) /*ARGSUSED */ int -xbow_unmap(devfs_handle_t dev, vhandl_t *vt) +xbow_unmap(vertex_hdl_t dev, vhandl_t *vt) { return 0; } @@ -523,9 +487,9 @@ xbow_unmap(devfs_handle_t dev, vhandl_t *vt) * be good enough. */ xwidgetnum_t -xbow_widget_num_get(devfs_handle_t dev) +xbow_widget_num_get(vertex_hdl_t dev) { - devfs_handle_t tdev; + vertex_hdl_t tdev; char devname[MAXDEVNAME]; xwidget_info_t xwidget_info; int i; @@ -556,19 +520,19 @@ xbow_widget_num_get(devfs_handle_t dev) } int -xbow_ioctl(devfs_handle_t dev, +xbow_ioctl(vertex_hdl_t dev, int cmd, void *arg, int flag, struct cred *cr, int *rvalp) { - devfs_handle_t vhdl; + vertex_hdl_t vhdl; int error = 0; #if defined (DEBUG) int rc; - devfs_handle_t conn; + vertex_hdl_t conn; struct xwidget_info_s *xwidget_info; xbow_soft_t xbow_soft; #endif @@ -648,12 +612,12 @@ xbow_link_alive(xbow_t * xbow, int port) * specified. * If not found, return 0. */ -devfs_handle_t -xbow_widget_lookup(devfs_handle_t vhdl, +vertex_hdl_t +xbow_widget_lookup(vertex_hdl_t vhdl, int widgetnum) { xswitch_info_t xswitch_info; - devfs_handle_t conn; + vertex_hdl_t conn; xswitch_info = xswitch_info_get(vhdl); conn = xswitch_info_vhdl_get(xswitch_info, widgetnum); @@ -713,48 +677,14 @@ xbow_intr_preset(void *which_widget, XEM_ADD_NVAR("ioe." #n, p); \ } -#ifdef LATER -static void -xem_add_ioe(ioerror_t *ioe) -{ - union tmp { - ushort stmp; - unsigned long long lltmp; - cpuid_t cputmp; - cnodeid_t cntmp; - iopaddr_t iotmp; - caddr_t catmp; - paddr_t patmp; - } tmp; - - XEM_ADD_IOEF(tmp.stmp, errortype); - XEM_ADD_IOEF(tmp.stmp, widgetnum); - XEM_ADD_IOEF(tmp.stmp, widgetdev); - XEM_ADD_IOEF(tmp.cputmp, srccpu); - XEM_ADD_IOEF(tmp.cntmp, srcnode); - XEM_ADD_IOEF(tmp.cntmp, errnode); - XEM_ADD_IOEF(tmp.iotmp, sysioaddr); - XEM_ADD_IOEF(tmp.iotmp, xtalkaddr); - XEM_ADD_IOEF(tmp.iotmp, busspace); - XEM_ADD_IOEF(tmp.iotmp, busaddr); - XEM_ADD_IOEF(tmp.catmp, vaddr); - XEM_ADD_IOEF(tmp.patmp, memaddr); - XEM_ADD_IOEF(tmp.catmp, epc); - XEM_ADD_IOEF(tmp.catmp, ef); - XEM_ADD_IOEF(tmp.stmp, tnum); -} - -#define XEM_ADD_IOE() (xem_add_ioe(ioe)) -#endif /* LATER */ - -int xbow_xmit_retry_errors = 0; +int xbow_xmit_retry_errors; int xbow_xmit_retry_error(xbow_soft_t soft, int port) { xswitch_info_t info; - devfs_handle_t vhdl; + vertex_hdl_t vhdl; widget_cfg_t *wid; widgetreg_t id; int part; @@ -904,7 +834,7 @@ xbow_errintr_handler(int irq, void *arg, struct pt_regs *ep) link_pend &= ~XB_STAT_XMT_RTRY_ERR; } if (link_pend) { - devfs_handle_t xwidget_vhdl; + vertex_hdl_t xwidget_vhdl; char *xwidget_name; /* Get the widget name corresponding to the current @@ -956,12 +886,6 @@ xbow_errintr_handler(int irq, void *arg, struct pt_regs *ep) XEM_ADD_VAR(link_status); XEM_ADD_VAR(link_aux_status); -#ifdef LATER - if (dump_ioe) { - XEM_ADD_IOE(); - dump_ioe = 0; - } -#endif #if !DEBUG } #endif @@ -1026,8 +950,8 @@ xbow_error_handler( xbow_soft_t soft = (xbow_soft_t) einfo; int port; - devfs_handle_t conn; - devfs_handle_t busv; + vertex_hdl_t conn; + vertex_hdl_t busv; xbow_t *xbow = soft->base; xbowreg_t wid_stat; @@ -1279,7 +1203,7 @@ xbow_error_handler( } void -xbow_update_perf_counters(devfs_handle_t vhdl) +xbow_update_perf_counters(vertex_hdl_t vhdl) { xbow_soft_t xbow_soft = xbow_soft_get(vhdl); xbow_perf_t *xbow_perf = xbow_soft->xbow_perfcnt; @@ -1307,7 +1231,7 @@ xbow_update_perf_counters(devfs_handle_t vhdl) } xbow_perf_link_t * -xbow_get_perf_counters(devfs_handle_t vhdl) +xbow_get_perf_counters(vertex_hdl_t vhdl) { xbow_soft_t xbow_soft = xbow_soft_get(vhdl); xbow_perf_link_t *xbow_perf_link = xbow_soft->xbow_perflink; @@ -1316,7 +1240,7 @@ xbow_get_perf_counters(devfs_handle_t vhdl) } int -xbow_enable_perf_counter(devfs_handle_t vhdl, int link, int mode, int counter) +xbow_enable_perf_counter(vertex_hdl_t vhdl, int link, int mode, int counter) { xbow_soft_t xbow_soft = xbow_soft_get(vhdl); xbow_perf_t *xbow_perf = xbow_soft->xbow_perfcnt; @@ -1370,7 +1294,7 @@ xbow_enable_perf_counter(devfs_handle_t vhdl, int link, int mode, int counter) } xbow_link_status_t * -xbow_get_llp_status(devfs_handle_t vhdl) +xbow_get_llp_status(vertex_hdl_t vhdl) { xbow_soft_t xbow_soft = xbow_soft_get(vhdl); xbow_link_status_t *xbow_llp_status = xbow_soft->xbow_link_status; @@ -1379,7 +1303,7 @@ xbow_get_llp_status(devfs_handle_t vhdl) } void -xbow_update_llp_status(devfs_handle_t vhdl) +xbow_update_llp_status(vertex_hdl_t vhdl) { xbow_soft_t xbow_soft = xbow_soft_get(vhdl); xbow_link_status_t *xbow_llp_status = xbow_soft->xbow_link_status; @@ -1387,7 +1311,7 @@ xbow_update_llp_status(devfs_handle_t vhdl) xbwX_stat_t lnk_sts; xbow_aux_link_status_t aux_sts; int link; - devfs_handle_t xwidget_vhdl; + vertex_hdl_t xwidget_vhdl; char *xwidget_name; xbow = (xbow_t *) xbow_soft->base; @@ -1421,7 +1345,7 @@ xbow_update_llp_status(devfs_handle_t vhdl) } int -xbow_disable_llp_monitor(devfs_handle_t vhdl) +xbow_disable_llp_monitor(vertex_hdl_t vhdl) { xbow_soft_t xbow_soft = xbow_soft_get(vhdl); int port; @@ -1436,7 +1360,7 @@ xbow_disable_llp_monitor(devfs_handle_t vhdl) } int -xbow_enable_llp_monitor(devfs_handle_t vhdl) +xbow_enable_llp_monitor(vertex_hdl_t vhdl) { xbow_soft_t xbow_soft = xbow_soft_get(vhdl); @@ -1446,7 +1370,7 @@ xbow_enable_llp_monitor(devfs_handle_t vhdl) int -xbow_reset_link(devfs_handle_t xconn_vhdl) +xbow_reset_link(vertex_hdl_t xconn_vhdl) { xwidget_info_t widget_info; xwidgetnum_t port; @@ -1469,7 +1393,7 @@ xbow_reset_link(devfs_handle_t xconn_vhdl) xbow = XBOW_K1PTR; #else { - devfs_handle_t xbow_vhdl; + vertex_hdl_t xbow_vhdl; xbow_soft_t xbow_soft; hwgraph_traverse(xconn_vhdl, ".master/xtalk/0/xbow", &xbow_vhdl); @@ -1502,46 +1426,6 @@ xbow_reset_link(devfs_handle_t xconn_vhdl) return 0; } -/* - * Dump xbow registers. - * input parameter is either a pointer to - * the xbow chip or the vertex handle for - * an xbow vertex. - */ -void -idbg_xbowregs(int64_t regs) -{ - xbow_t *xbow; - int i; - xb_linkregs_t *link; - - xbow = (xbow_t *) regs; - -#ifdef LATER - qprintf("Printing xbow registers starting at 0x%x\n", xbow); - qprintf("wid %x status %x erruppr %x errlower %x control %x timeout %x\n", - xbow->xb_wid_id, xbow->xb_wid_stat, xbow->xb_wid_err_upper, - xbow->xb_wid_err_lower, xbow->xb_wid_control, - xbow->xb_wid_req_timeout); - qprintf("intr uppr %x lower %x errcmd %x llp ctrl %x arb_reload %x\n", - xbow->xb_wid_int_upper, xbow->xb_wid_int_lower, - xbow->xb_wid_err_cmdword, xbow->xb_wid_llp, - xbow->xb_wid_arb_reload); -#endif - - for (i = 8; i <= 0xf; i++) { - link = &xbow->xb_link(i); -#ifdef LATER - qprintf("Link %d registers\n", i); - qprintf("\tctrl %x stat %x arbuppr %x arblowr %x auxstat %x\n", - link->link_control, link->link_status, - link->link_arb_upper, link->link_arb_lower, - link->link_aux_status); -#endif - } -} - - #define XBOW_ARB_RELOAD_TICKS 25 /* granularity: 4 MB/s, max: 124 MB/s */ #define GRANULARITY ((100 * 1000000) / XBOW_ARB_RELOAD_TICKS) @@ -1601,7 +1485,7 @@ xbow_gbr_to_bytes(int gbr) * If bandwidth allocation is successful, return success else return failure. */ int -xbow_prio_bw_alloc(devfs_handle_t vhdl, +xbow_prio_bw_alloc(vertex_hdl_t vhdl, xwidgetnum_t src_wid, xwidgetnum_t dest_wid, unsigned long long old_alloc_bw, diff --git a/arch/ia64/sn/io/sn2/xtalk.c b/arch/ia64/sn/io/sn2/xtalk.c index ac9988596bf333..fbcec3e395e0bf 100644 --- a/arch/ia64/sn/io/sn2/xtalk.c +++ b/arch/ia64/sn/io/sn2/xtalk.c @@ -37,8 +37,6 @@ char widget_info_fingerprint[] = "widget_info"; -cdl_p xtalk_registry = NULL; - #define DEV_FUNC(dev,func) hub_##func #define CAST_PIOMAP(x) ((hub_piomap_t)(x)) #define CAST_DMAMAP(x) ((hub_dmamap_t)(x)) @@ -47,71 +45,70 @@ cdl_p xtalk_registry = NULL; /* ===================================================================== * Function Table of Contents */ -xtalk_piomap_t xtalk_piomap_alloc(devfs_handle_t, device_desc_t, iopaddr_t, size_t, size_t, unsigned); +xtalk_piomap_t xtalk_piomap_alloc(vertex_hdl_t, device_desc_t, iopaddr_t, size_t, size_t, unsigned); void xtalk_piomap_free(xtalk_piomap_t); caddr_t xtalk_piomap_addr(xtalk_piomap_t, iopaddr_t, size_t); void xtalk_piomap_done(xtalk_piomap_t); -caddr_t xtalk_piotrans_addr(devfs_handle_t, device_desc_t, iopaddr_t, size_t, unsigned); -caddr_t xtalk_pio_addr(devfs_handle_t, device_desc_t, iopaddr_t, size_t, xtalk_piomap_t *, unsigned); +caddr_t xtalk_piotrans_addr(vertex_hdl_t, device_desc_t, iopaddr_t, size_t, unsigned); +caddr_t xtalk_pio_addr(vertex_hdl_t, device_desc_t, iopaddr_t, size_t, xtalk_piomap_t *, unsigned); void xtalk_set_early_piotrans_addr(xtalk_early_piotrans_addr_f *); caddr_t xtalk_early_piotrans_addr(xwidget_part_num_t, xwidget_mfg_num_t, int, iopaddr_t, size_t, unsigned); static caddr_t null_xtalk_early_piotrans_addr(xwidget_part_num_t, xwidget_mfg_num_t, int, iopaddr_t, size_t, unsigned); -xtalk_dmamap_t xtalk_dmamap_alloc(devfs_handle_t, device_desc_t, size_t, unsigned); +xtalk_dmamap_t xtalk_dmamap_alloc(vertex_hdl_t, device_desc_t, size_t, unsigned); void xtalk_dmamap_free(xtalk_dmamap_t); iopaddr_t xtalk_dmamap_addr(xtalk_dmamap_t, paddr_t, size_t); alenlist_t xtalk_dmamap_list(xtalk_dmamap_t, alenlist_t, unsigned); void xtalk_dmamap_done(xtalk_dmamap_t); -iopaddr_t xtalk_dmatrans_addr(devfs_handle_t, device_desc_t, paddr_t, size_t, unsigned); -alenlist_t xtalk_dmatrans_list(devfs_handle_t, device_desc_t, alenlist_t, unsigned); +iopaddr_t xtalk_dmatrans_addr(vertex_hdl_t, device_desc_t, paddr_t, size_t, unsigned); +alenlist_t xtalk_dmatrans_list(vertex_hdl_t, device_desc_t, alenlist_t, unsigned); void xtalk_dmamap_drain(xtalk_dmamap_t); -void xtalk_dmaaddr_drain(devfs_handle_t, iopaddr_t, size_t); -void xtalk_dmalist_drain(devfs_handle_t, alenlist_t); -xtalk_intr_t xtalk_intr_alloc(devfs_handle_t, device_desc_t, devfs_handle_t); -xtalk_intr_t xtalk_intr_alloc_nothd(devfs_handle_t, device_desc_t, devfs_handle_t); +void xtalk_dmaaddr_drain(vertex_hdl_t, iopaddr_t, size_t); +void xtalk_dmalist_drain(vertex_hdl_t, alenlist_t); +xtalk_intr_t xtalk_intr_alloc(vertex_hdl_t, device_desc_t, vertex_hdl_t); +xtalk_intr_t xtalk_intr_alloc_nothd(vertex_hdl_t, device_desc_t, vertex_hdl_t); void xtalk_intr_free(xtalk_intr_t); int xtalk_intr_connect(xtalk_intr_t, intr_func_t, intr_arg_t, xtalk_intr_setfunc_t, void *); void xtalk_intr_disconnect(xtalk_intr_t); -devfs_handle_t xtalk_intr_cpu_get(xtalk_intr_t); -int xtalk_error_handler(devfs_handle_t, int, ioerror_mode_t, ioerror_t *); -int xtalk_error_devenable(devfs_handle_t, int, int); -void xtalk_provider_startup(devfs_handle_t); -void xtalk_provider_shutdown(devfs_handle_t); -devfs_handle_t xtalk_intr_dev_get(xtalk_intr_t); +vertex_hdl_t xtalk_intr_cpu_get(xtalk_intr_t); +int xtalk_error_handler(vertex_hdl_t, int, ioerror_mode_t, ioerror_t *); +int xtalk_error_devenable(vertex_hdl_t, int, int); +void xtalk_provider_startup(vertex_hdl_t); +void xtalk_provider_shutdown(vertex_hdl_t); +vertex_hdl_t xtalk_intr_dev_get(xtalk_intr_t); xwidgetnum_t xtalk_intr_target_get(xtalk_intr_t); xtalk_intr_vector_t xtalk_intr_vector_get(xtalk_intr_t); iopaddr_t xtalk_intr_addr_get(struct xtalk_intr_s *); void *xtalk_intr_sfarg_get(xtalk_intr_t); -devfs_handle_t xtalk_pio_dev_get(xtalk_piomap_t); +vertex_hdl_t xtalk_pio_dev_get(xtalk_piomap_t); xwidgetnum_t xtalk_pio_target_get(xtalk_piomap_t); iopaddr_t xtalk_pio_xtalk_addr_get(xtalk_piomap_t); ulong xtalk_pio_mapsz_get(xtalk_piomap_t); caddr_t xtalk_pio_kvaddr_get(xtalk_piomap_t); -devfs_handle_t xtalk_dma_dev_get(xtalk_dmamap_t); +vertex_hdl_t xtalk_dma_dev_get(xtalk_dmamap_t); xwidgetnum_t xtalk_dma_target_get(xtalk_dmamap_t); -xwidget_info_t xwidget_info_chk(devfs_handle_t); -xwidget_info_t xwidget_info_get(devfs_handle_t); -void xwidget_info_set(devfs_handle_t, xwidget_info_t); -devfs_handle_t xwidget_info_dev_get(xwidget_info_t); +xwidget_info_t xwidget_info_chk(vertex_hdl_t); +xwidget_info_t xwidget_info_get(vertex_hdl_t); +void xwidget_info_set(vertex_hdl_t, xwidget_info_t); +vertex_hdl_t xwidget_info_dev_get(xwidget_info_t); xwidgetnum_t xwidget_info_id_get(xwidget_info_t); -devfs_handle_t xwidget_info_master_get(xwidget_info_t); +vertex_hdl_t xwidget_info_master_get(xwidget_info_t); xwidgetnum_t xwidget_info_masterid_get(xwidget_info_t); xwidget_part_num_t xwidget_info_part_num_get(xwidget_info_t); xwidget_mfg_num_t xwidget_info_mfg_num_get(xwidget_info_t); char *xwidget_info_name_get(xwidget_info_t); -void xtalk_init(void); -void xtalk_provider_register(devfs_handle_t, xtalk_provider_t *); -void xtalk_provider_unregister(devfs_handle_t); -xtalk_provider_t *xtalk_provider_fns_get(devfs_handle_t); +void xtalk_provider_register(vertex_hdl_t, xtalk_provider_t *); +void xtalk_provider_unregister(vertex_hdl_t); +xtalk_provider_t *xtalk_provider_fns_get(vertex_hdl_t); int xwidget_driver_register(xwidget_part_num_t, xwidget_mfg_num_t, char *, unsigned); void xwidget_driver_unregister(char *); -int xwidget_register(xwidget_hwid_t, devfs_handle_t, - xwidgetnum_t, devfs_handle_t, - xwidgetnum_t, async_attach_t); -int xwidget_unregister(devfs_handle_t); -void xwidget_reset(devfs_handle_t); -char *xwidget_name_get(devfs_handle_t); +int xwidget_register(xwidget_hwid_t, vertex_hdl_t, + xwidgetnum_t, vertex_hdl_t, + xwidgetnum_t); +int xwidget_unregister(vertex_hdl_t); +void xwidget_reset(vertex_hdl_t); +char *xwidget_name_get(vertex_hdl_t); #if !defined(DEV_FUNC) /* * There is more than one possible provider @@ -126,7 +123,7 @@ char *xwidget_name_get(devfs_handle_t); #define CAST_INTR(x) ((xtalk_intr_t)(x)) static xtalk_provider_t * -xwidget_to_provider_fns(devfs_handle_t xconn) +xwidget_to_provider_fns(vertex_hdl_t xconn) { xwidget_info_t widget_info; xtalk_provider_t *provider_fns; @@ -159,7 +156,7 @@ xwidget_to_provider_fns(devfs_handle_t xconn) */ xtalk_piomap_t -xtalk_piomap_alloc(devfs_handle_t dev, /* set up mapping for this device */ +xtalk_piomap_alloc(vertex_hdl_t dev, /* set up mapping for this device */ device_desc_t dev_desc, /* device descriptor */ iopaddr_t xtalk_addr, /* map for this xtalk_addr range */ size_t byte_count, @@ -198,7 +195,7 @@ xtalk_piomap_done(xtalk_piomap_t xtalk_piomap) caddr_t -xtalk_piotrans_addr(devfs_handle_t dev, /* translate for this device */ +xtalk_piotrans_addr(vertex_hdl_t dev, /* translate for this device */ device_desc_t dev_desc, /* device descriptor */ iopaddr_t xtalk_addr, /* Crosstalk address */ size_t byte_count, /* map this many bytes */ @@ -209,7 +206,7 @@ xtalk_piotrans_addr(devfs_handle_t dev, /* translate for this device */ } caddr_t -xtalk_pio_addr(devfs_handle_t dev, /* translate for this device */ +xtalk_pio_addr(vertex_hdl_t dev, /* translate for this device */ device_desc_t dev_desc, /* device descriptor */ iopaddr_t addr, /* starting address (or offset in window) */ size_t byte_count, /* map this many bytes */ @@ -326,7 +323,7 @@ null_xtalk_early_piotrans_addr(xwidget_part_num_t part_num, */ xtalk_dmamap_t -xtalk_dmamap_alloc(devfs_handle_t dev, /* set up mappings for this device */ +xtalk_dmamap_alloc(vertex_hdl_t dev, /* set up mappings for this device */ device_desc_t dev_desc, /* device descriptor */ size_t byte_count_max, /* max size of a mapping */ unsigned flags) @@ -373,7 +370,7 @@ xtalk_dmamap_done(xtalk_dmamap_t xtalk_dmamap) iopaddr_t -xtalk_dmatrans_addr(devfs_handle_t dev, /* translate for this device */ +xtalk_dmatrans_addr(vertex_hdl_t dev, /* translate for this device */ device_desc_t dev_desc, /* device descriptor */ paddr_t paddr, /* system physical address */ size_t byte_count, /* length */ @@ -385,7 +382,7 @@ xtalk_dmatrans_addr(devfs_handle_t dev, /* translate for this device */ alenlist_t -xtalk_dmatrans_list(devfs_handle_t dev, /* translate for this device */ +xtalk_dmatrans_list(vertex_hdl_t dev, /* translate for this device */ device_desc_t dev_desc, /* device descriptor */ alenlist_t palenlist, /* system address/length list */ unsigned flags) @@ -402,14 +399,14 @@ xtalk_dmamap_drain(xtalk_dmamap_t map) } void -xtalk_dmaaddr_drain(devfs_handle_t dev, paddr_t addr, size_t size) +xtalk_dmaaddr_drain(vertex_hdl_t dev, paddr_t addr, size_t size) { DEV_FUNC(dev, dmaaddr_drain) (dev, addr, size); } void -xtalk_dmalist_drain(devfs_handle_t dev, alenlist_t list) +xtalk_dmalist_drain(vertex_hdl_t dev, alenlist_t list) { DEV_FUNC(dev, dmalist_drain) (dev, list); @@ -426,9 +423,9 @@ xtalk_dmalist_drain(devfs_handle_t dev, alenlist_t list) * Return resource handle in intr_hdl. */ xtalk_intr_t -xtalk_intr_alloc(devfs_handle_t dev, /* which Crosstalk device */ +xtalk_intr_alloc(vertex_hdl_t dev, /* which Crosstalk device */ device_desc_t dev_desc, /* device descriptor */ - devfs_handle_t owner_dev) + vertex_hdl_t owner_dev) { /* owner of this interrupt */ return (xtalk_intr_t) DEV_FUNC(dev, intr_alloc) (dev, dev_desc, owner_dev); @@ -440,9 +437,9 @@ xtalk_intr_alloc(devfs_handle_t dev, /* which Crosstalk device */ * Return resource handle in intr_hdl. */ xtalk_intr_t -xtalk_intr_alloc_nothd(devfs_handle_t dev, /* which Crosstalk device */ +xtalk_intr_alloc_nothd(vertex_hdl_t dev, /* which Crosstalk device */ device_desc_t dev_desc, /* device descriptor */ - devfs_handle_t owner_dev) /* owner of this interrupt */ + vertex_hdl_t owner_dev) /* owner of this interrupt */ { return (xtalk_intr_t) DEV_FUNC(dev, intr_alloc_nothd) (dev, dev_desc, owner_dev); @@ -492,11 +489,10 @@ xtalk_intr_disconnect(xtalk_intr_t intr_hdl) * Return a hwgraph vertex that represents the CPU currently * targeted by an interrupt. */ -devfs_handle_t +vertex_hdl_t xtalk_intr_cpu_get(xtalk_intr_t intr_hdl) { - return INTR_FUNC(intr_hdl, intr_cpu_get) - (CAST_INTR(intr_hdl)); + return (vertex_hdl_t)0; } @@ -526,7 +522,7 @@ xtalk_intr_cpu_get(xtalk_intr_t intr_hdl) */ int xtalk_error_handler( - devfs_handle_t xconn, + vertex_hdl_t xconn, int error_code, ioerror_mode_t mode, ioerror_t *ioerror) @@ -555,7 +551,7 @@ xtalk_error_handler( #if defined(SUPPORT_PRINTING_V_FORMAT) printk(KERN_WARNING "Xbow at %v encountered Fatal error", xconn); #else - printk(KERN_WARNING "Xbow at 0x%p encountered Fatal error", xconn); + printk(KERN_WARNING "Xbow at 0x%p encountered Fatal error", (void *)xconn); #endif ioerror_dump("xtalk", error_code, mode, ioerror); @@ -563,7 +559,7 @@ xtalk_error_handler( } int -xtalk_error_devenable(devfs_handle_t xconn_vhdl, int devnum, int error_code) +xtalk_error_devenable(vertex_hdl_t xconn_vhdl, int devnum, int error_code) { return DEV_FUNC(xconn_vhdl, error_devenable) (xconn_vhdl, devnum, error_code); } @@ -577,7 +573,7 @@ xtalk_error_devenable(devfs_handle_t xconn_vhdl, int devnum, int error_code) * Startup a crosstalk provider */ void -xtalk_provider_startup(devfs_handle_t xtalk_provider) +xtalk_provider_startup(vertex_hdl_t xtalk_provider) { DEV_FUNC(xtalk_provider, provider_startup) (xtalk_provider); @@ -588,7 +584,7 @@ xtalk_provider_startup(devfs_handle_t xtalk_provider) * Shutdown a crosstalk provider */ void -xtalk_provider_shutdown(devfs_handle_t xtalk_provider) +xtalk_provider_shutdown(vertex_hdl_t xtalk_provider) { DEV_FUNC(xtalk_provider, provider_shutdown) (xtalk_provider); @@ -598,22 +594,22 @@ xtalk_provider_shutdown(devfs_handle_t xtalk_provider) * Enable a device on a xtalk widget */ void -xtalk_widgetdev_enable(devfs_handle_t xconn_vhdl, int devnum) +xtalk_widgetdev_enable(vertex_hdl_t xconn_vhdl, int devnum) { - DEV_FUNC(xconn_vhdl, widgetdev_enable) (xconn_vhdl, devnum); + return; } /* * Shutdown a device on a xtalk widget */ void -xtalk_widgetdev_shutdown(devfs_handle_t xconn_vhdl, int devnum) +xtalk_widgetdev_shutdown(vertex_hdl_t xconn_vhdl, int devnum) { - DEV_FUNC(xconn_vhdl, widgetdev_shutdown) (xconn_vhdl, devnum); + return; } int -xtalk_dma_enabled(devfs_handle_t xconn_vhdl) +xtalk_dma_enabled(vertex_hdl_t xconn_vhdl) { return DEV_FUNC(xconn_vhdl, dma_enabled) (xconn_vhdl); } @@ -623,7 +619,7 @@ xtalk_dma_enabled(devfs_handle_t xconn_vhdl) */ /****** Generic crosstalk interrupt interfaces ******/ -devfs_handle_t +vertex_hdl_t xtalk_intr_dev_get(xtalk_intr_t xtalk_intr) { return (xtalk_intr->xi_dev); @@ -654,7 +650,7 @@ xtalk_intr_sfarg_get(xtalk_intr_t xtalk_intr) } /****** Generic crosstalk pio interfaces ******/ -devfs_handle_t +vertex_hdl_t xtalk_pio_dev_get(xtalk_piomap_t xtalk_piomap) { return (xtalk_piomap->xp_dev); @@ -686,7 +682,7 @@ xtalk_pio_kvaddr_get(xtalk_piomap_t xtalk_piomap) /****** Generic crosstalk dma interfaces ******/ -devfs_handle_t +vertex_hdl_t xtalk_dma_dev_get(xtalk_dmamap_t xtalk_dmamap) { return (xtalk_dmamap->xd_dev); @@ -707,7 +703,7 @@ xtalk_dma_target_get(xtalk_dmamap_t xtalk_dmamap) * if not, return NULL. */ xwidget_info_t -xwidget_info_chk(devfs_handle_t xwidget) +xwidget_info_chk(vertex_hdl_t xwidget) { arbitrary_info_t ainfo = 0; @@ -717,28 +713,18 @@ xwidget_info_chk(devfs_handle_t xwidget) xwidget_info_t -xwidget_info_get(devfs_handle_t xwidget) +xwidget_info_get(vertex_hdl_t xwidget) { xwidget_info_t widget_info; widget_info = (xwidget_info_t) hwgraph_fastinfo_get(xwidget); -#ifdef LATER - if ((widget_info != NULL) && - (widget_info->w_fingerprint != widget_info_fingerprint)) -#ifdef SUPPORT_PRINTING_V_FORMAT - PRINT_PANIC("%v bad xwidget_info", xwidget); -#else - PRINT_PANIC("%x bad xwidget_info", xwidget); -#endif -#endif /* LATER */ - return (widget_info); } void -xwidget_info_set(devfs_handle_t xwidget, xwidget_info_t widget_info) +xwidget_info_set(vertex_hdl_t xwidget, xwidget_info_t widget_info) { if (widget_info != NULL) widget_info->w_fingerprint = widget_info_fingerprint; @@ -753,11 +739,11 @@ xwidget_info_set(devfs_handle_t xwidget, xwidget_info_t widget_info) (arbitrary_info_t) widget_info); } -devfs_handle_t +vertex_hdl_t xwidget_info_dev_get(xwidget_info_t xwidget_info) { if (xwidget_info == NULL) - panic("null xwidget_info"); + panic("xwidget_info_dev_get: null xwidget_info"); return (xwidget_info->w_vertex); } @@ -765,16 +751,16 @@ xwidgetnum_t xwidget_info_id_get(xwidget_info_t xwidget_info) { if (xwidget_info == NULL) - panic("null xwidget_info"); + panic("xwidget_info_id_get: null xwidget_info"); return (xwidget_info->w_id); } -devfs_handle_t +vertex_hdl_t xwidget_info_master_get(xwidget_info_t xwidget_info) { if (xwidget_info == NULL) - panic("null xwidget_info"); + panic("xwidget_info_master_get: null xwidget_info"); return (xwidget_info->w_master); } @@ -782,7 +768,7 @@ xwidgetnum_t xwidget_info_masterid_get(xwidget_info_t xwidget_info) { if (xwidget_info == NULL) - panic("null xwidget_info"); + panic("xwidget_info_masterid_get: null xwidget_info"); return (xwidget_info->w_masterid); } @@ -790,7 +776,7 @@ xwidget_part_num_t xwidget_info_part_num_get(xwidget_info_t xwidget_info) { if (xwidget_info == NULL) - panic("null xwidget_info"); + panic("xwidget_info_part_num_get: null xwidget_info"); return (xwidget_info->w_hwid.part_num); } @@ -798,7 +784,7 @@ xwidget_mfg_num_t xwidget_info_mfg_num_get(xwidget_info_t xwidget_info) { if (xwidget_info == NULL) - panic("null xwidget_info"); + panic("xwidget_info_mfg_num_get: null xwidget_info"); return (xwidget_info->w_hwid.mfg_num); } /* Extract the widget name from the widget information @@ -808,49 +794,16 @@ char * xwidget_info_name_get(xwidget_info_t xwidget_info) { if (xwidget_info == NULL) - panic("null xwidget info"); + panic("xwidget_info_name_get: null xwidget_info"); return(xwidget_info->w_name); } /****** Generic crosstalk initialization interfaces ******/ /* - * One-time initialization needed for systems that support crosstalk. - */ -void -xtalk_init(void) -{ - cdl_p cp; - -#if DEBUG && ATTACH_DEBUG - printf("xtalk_init\n"); -#endif - /* Allocate the registry. - * We might already have one. - * If we don't, go get one. - * MPness: someone might have - * set one up for us while we - * were not looking; use an atomic - * compare-and-swap to commit to - * using the new registry if and - * only if nobody else did first. - * If someone did get there first, - * toss the one we allocated back - * into the pool. - */ - if (xtalk_registry == NULL) { - cp = cdl_new(EDGE_LBL_XIO, "part", "mfgr"); - if (!compare_and_swap_ptr((void **) &xtalk_registry, NULL, (void *) cp)) { - cdl_del(cp); - } - } - ASSERT(xtalk_registry != NULL); -} - -/* * Associate a set of xtalk_provider functions with a vertex. */ void -xtalk_provider_register(devfs_handle_t provider, xtalk_provider_t *xtalk_fns) +xtalk_provider_register(vertex_hdl_t provider, xtalk_provider_t *xtalk_fns) { hwgraph_fastinfo_set(provider, (arbitrary_info_t) xtalk_fns); } @@ -859,7 +812,7 @@ xtalk_provider_register(devfs_handle_t provider, xtalk_provider_t *xtalk_fns) * Disassociate a set of xtalk_provider functions with a vertex. */ void -xtalk_provider_unregister(devfs_handle_t provider) +xtalk_provider_unregister(vertex_hdl_t provider) { hwgraph_fastinfo_set(provider, (arbitrary_info_t)NULL); } @@ -869,50 +822,19 @@ xtalk_provider_unregister(devfs_handle_t provider) * provider. */ xtalk_provider_t * -xtalk_provider_fns_get(devfs_handle_t provider) +xtalk_provider_fns_get(vertex_hdl_t provider) { return ((xtalk_provider_t *) hwgraph_fastinfo_get(provider)); } /* - * Announce a driver for a particular crosstalk part. - * Returns 0 on success or -1 on failure. Failure occurs if the - * specified hardware already has a driver. - */ -/*ARGSUSED4 */ -int -xwidget_driver_register(xwidget_part_num_t part_num, - xwidget_mfg_num_t mfg_num, - char *driver_prefix, - unsigned flags) -{ - /* a driver's init routine could call - * xwidget_driver_register before the - * system calls xtalk_init; so, we - * make the call here. - */ - if (xtalk_registry == NULL) - xtalk_init(); - - return cdl_add_driver(xtalk_registry, - part_num, mfg_num, - driver_prefix, flags, NULL); -} - -/* * Inform xtalk infrastructure that a driver is no longer available for * handling any widgets. */ void xwidget_driver_unregister(char *driver_prefix) { - /* before a driver calls unregister, - * it must have called registger; so we - * can assume we have a registry here. - */ - ASSERT(xtalk_registry != NULL); - - cdl_del_driver(xtalk_registry, driver_prefix, NULL); + return; } /* @@ -923,9 +845,6 @@ void xtalk_iterate(char *driver_prefix, xtalk_iter_f *func) { - ASSERT(xtalk_registry != NULL); - - cdl_iterate(xtalk_registry, driver_prefix, (cdl_iter_f *)func); } /* @@ -939,11 +858,10 @@ xtalk_iterate(char *driver_prefix, */ int xwidget_register(xwidget_hwid_t hwid, /* widget's hardware ID */ - devfs_handle_t widget, /* widget to initialize */ + vertex_hdl_t widget, /* widget to initialize */ xwidgetnum_t id, /* widget's target id (0..f) */ - devfs_handle_t master, /* widget's master vertex */ - xwidgetnum_t targetid, /* master's target id (9/a) */ - async_attach_t aa) + vertex_hdl_t master, /* widget's master vertex */ + xwidgetnum_t targetid) /* master's target id (9/a) */ { xwidget_info_t widget_info; char *s,devnm[MAXDEVNAME]; @@ -972,21 +890,11 @@ xwidget_register(xwidget_hwid_t hwid, /* widget's hardware ID */ device_master_set(widget, master); - /* All the driver init routines (including - * xtalk_init) are called before we get into - * attaching devices, so we can assume we - * have a registry here. - */ - ASSERT(xtalk_registry != NULL); - /* * Add pointer to async attach info -- tear down will be done when * the particular descendant is done with the info. */ - if (aa) - async_attach_add_info(widget, aa); - - return cdl_add_connpt(xtalk_registry, hwid->part_num, hwid->mfg_num, + return cdl_add_connpt(hwid->part_num, hwid->mfg_num, widget, 0); } @@ -995,7 +903,7 @@ xwidget_register(xwidget_hwid_t hwid, /* widget's hardware ID */ * Unregister the xtalk device and detach all its hwgraph namespace. */ int -xwidget_unregister(devfs_handle_t widget) +xwidget_unregister(vertex_hdl_t widget) { xwidget_info_t widget_info; xwidget_hwid_t hwid; @@ -1011,9 +919,6 @@ xwidget_unregister(devfs_handle_t widget) hwid = &(widget_info->w_hwid); - cdl_del_connpt(xtalk_registry, hwid->part_num, hwid->mfg_num, - widget, 0); - /* Clean out the xwidget information */ (void)kfree(widget_info->w_name); BZERO((void *)widget_info, sizeof(widget_info)); @@ -1023,7 +928,7 @@ xwidget_unregister(devfs_handle_t widget) } void -xwidget_error_register(devfs_handle_t xwidget, +xwidget_error_register(vertex_hdl_t xwidget, error_handler_f *efunc, error_handler_arg_t einfo) { @@ -1039,37 +944,23 @@ xwidget_error_register(devfs_handle_t xwidget, * Issue a link reset to a widget. */ void -xwidget_reset(devfs_handle_t xwidget) +xwidget_reset(vertex_hdl_t xwidget) { xswitch_reset_link(xwidget); - } void -xwidget_gfx_reset(devfs_handle_t xwidget) +xwidget_gfx_reset(vertex_hdl_t xwidget) { - xwidget_info_t info; - - xswitch_reset_link(xwidget); - info = xwidget_info_get(xwidget); -#ifdef LATER - ASSERT_ALWAYS(info != NULL); -#endif - - /* - * Enable this for other architectures once we add widget_reset to the - * xtalk provider interface. - */ - DEV_FUNC(xtalk_provider, widget_reset) - (xwidget_info_master_get(info), xwidget_info_id_get(info)); + return; } #define ANON_XWIDGET_NAME "No Name" /* Default Widget Name */ /* Get the canonical hwgraph name of xtalk widget */ char * -xwidget_name_get(devfs_handle_t xwidget_vhdl) +xwidget_name_get(vertex_hdl_t xwidget_vhdl) { xwidget_info_t info; |