1/* $Id: hubdev.c,v 1.1.1.1 2008/10/15 03:26:03 james26_jang Exp $ 2 * 3 * This file is subject to the terms and conditions of the GNU General Public 4 * License. See the file "COPYING" in the main directory of this archive 5 * for more details. 6 * 7 * Copyright (C) 1992 - 1997, 2000-2001 Silicon Graphics, Inc. All rights reserved. 8 */ 9 10#include <linux/config.h> 11#include <linux/types.h> 12#include <linux/slab.h> 13#include <asm/sn/sgi.h> 14#include <asm/sn/io.h> 15#include <asm/sn/iograph.h> 16#include <asm/sn/sn1/hubdev.h> 17#include <asm/sn/sn_private.h> 18#include <asm/sn/invent.h> 19#include <asm/sn/hcl.h> 20#include <asm/sn/labelcl.h> 21 22struct hubdev_callout { 23 int (*attach_method)(devfs_handle_t); 24 struct hubdev_callout *fp; 25}; 26 27typedef struct hubdev_callout hubdev_callout_t; 28 29mutex_t hubdev_callout_mutex; 30hubdev_callout_t *hubdev_callout_list = NULL; 31 32void 33hubdev_init(void) 34{ 35 mutex_init(&hubdev_callout_mutex); 36 hubdev_callout_list = NULL; 37} 38 39void 40hubdev_register(int (*attach_method)(devfs_handle_t)) 41{ 42 hubdev_callout_t *callout; 43 44 ASSERT(attach_method); 45 46 callout = (hubdev_callout_t *)snia_kmem_zalloc(sizeof(hubdev_callout_t), KM_SLEEP); 47 ASSERT(callout); 48 49 mutex_lock(&hubdev_callout_mutex); 50 /* 51 * Insert at the end of the list 52 */ 53 callout->fp = hubdev_callout_list; 54 hubdev_callout_list = callout; 55 callout->attach_method = attach_method; 56 mutex_unlock(&hubdev_callout_mutex); 57} 58 59int 60hubdev_unregister(int (*attach_method)(devfs_handle_t)) 61{ 62 hubdev_callout_t **p; 63 64 ASSERT(attach_method); 65 66 mutex_lock(&hubdev_callout_mutex); 67 /* 68 * Remove registry element containing attach_method 69 */ 70 for (p = &hubdev_callout_list; *p != NULL; p = &(*p)->fp) { 71 if ((*p)->attach_method == attach_method) { 72 hubdev_callout_t* victim = *p; 73 *p = (*p)->fp; 74 kfree(victim); 75 mutex_unlock(&hubdev_callout_mutex); 76 return (0); 77 } 78 } 79 mutex_unlock(&hubdev_callout_mutex); 80 return (ENOENT); 81} 82 83 84int 85hubdev_docallouts(devfs_handle_t hub) 86{ 87 hubdev_callout_t *p; 88 int errcode; 89 90 mutex_lock(&hubdev_callout_mutex); 91 92 for (p = hubdev_callout_list; p != NULL; p = p->fp) { 93 ASSERT(p->attach_method); 94 errcode = (*p->attach_method)(hub); 95 if (errcode != 0) { 96 mutex_unlock(&hubdev_callout_mutex); 97 return (errcode); 98 } 99 } 100 mutex_unlock(&hubdev_callout_mutex); 101 return (0); 102} 103 104/* 105 * Given a hub vertex, return the base address of the Hspec space 106 * for that hub. 107 */ 108 109#if defined(CONFIG_IA64_SGI_SN1) 110 111caddr_t 112hubdev_prombase_get(devfs_handle_t hub) 113{ 114 hubinfo_t hinfo = NULL; 115 116 hubinfo_get(hub, &hinfo); 117 ASSERT(hinfo); 118 119 return ((caddr_t)NODE_RBOOT_BASE(hinfo->h_nasid)); 120} 121 122cnodeid_t 123hubdev_cnodeid_get(devfs_handle_t hub) 124{ 125 hubinfo_t hinfo = NULL; 126 hubinfo_get(hub, &hinfo); 127 ASSERT(hinfo); 128 129 return hinfo->h_cnodeid; 130} 131 132#endif /* CONFIG_IA64_SGI_SN1 */ 133