1/* $Id: invent.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/* 11 * Hardware Inventory 12 * 13 * See sys/sn/invent.h for an explanation of the hardware inventory contents. 14 * 15 */ 16#include <linux/types.h> 17#include <asm/sn/sgi.h> 18#include <asm/sn/invent.h> 19#include <asm/sn/hcl.h> 20#include <asm/sn/labelcl.h> 21 22void 23inventinit(void) 24{ 25} 26 27/* 28 * For initializing/updating an inventory entry. 29 */ 30void 31replace_in_inventory( 32 inventory_t *pinv, int class, int type, 33 int controller, int unit, int state) 34{ 35 pinv->inv_class = class; 36 pinv->inv_type = type; 37 pinv->inv_controller = controller; 38 pinv->inv_unit = unit; 39 pinv->inv_state = state; 40} 41 42void 43add_to_inventory(int class, int type, int controller, int unit, int state) 44{ 45 (void)device_inventory_add((devfs_handle_t)GRAPH_VERTEX_NONE, class, type, 46 controller, unit, state); 47} 48 49 50/* 51 * Inventory retrieval 52 * 53 * These two routines are intended to prevent the caller from having to know 54 * the internal structure of the inventory table. 55 * 56 * The caller of get_next_inventory is supposed to call start_scan_invent 57 * before the irst call to get_next_inventory, and the caller is required 58 * to call end_scan_invent after the last call to get_next_inventory. 59 */ 60inventory_t * 61get_next_inventory(invplace_t *place) 62{ 63 inventory_t *pinv; 64 devfs_handle_t device = place->invplace_vhdl; 65 int rv; 66 67 while ((pinv = device_inventory_get_next(device, place)) == NULL) { 68 /* 69 * We've exhausted inventory items on the last device. 70 * Advance to next device. 71 */ 72 place->invplace_inv = NULL; /* Start from beginning invent on this device */ 73 rv = hwgraph_vertex_get_next(&device, &place->invplace_vplace); 74 if (rv == LABELCL_SUCCESS) { 75 place->invplace_vhdl = device; 76 } 77 else { 78 place->invplace_vhdl = GRAPH_VERTEX_NONE; 79 return(NULL); 80 } 81 } 82 83 return(pinv); 84} 85 86/* ARGSUSED */ 87int 88get_sizeof_inventory(int abi) 89{ 90 return sizeof(inventory_t); 91} 92 93/* Must be called prior to first call to get_next_inventory */ 94void 95start_scan_inventory(invplace_t *iplace) 96{ 97 *iplace = INVPLACE_NONE; 98} 99 100/* Must be called after last call to get_next_inventory */ 101void 102end_scan_inventory(invplace_t *iplace) 103{ 104 devfs_handle_t vhdl = iplace->invplace_vhdl; 105 if (vhdl != GRAPH_VERTEX_NONE) 106 hwgraph_vertex_unref(vhdl); 107 *iplace = INVPLACE_NONE; /* paranoia */ 108} 109 110/* 111 * Hardware inventory scanner. 112 * 113 * Calls fun() for every entry in inventory list unless fun() returns something 114 * other than 0. 115 */ 116int 117scaninvent(int (*fun)(inventory_t *, void *), void *arg) 118{ 119 inventory_t *ie; 120 invplace_t iplace = { NULL,NULL, NULL }; 121 int rc; 122 123 ie = 0; 124 rc = 0; 125 start_scan_inventory(&iplace); 126 while ((ie = (inventory_t *)get_next_inventory(&iplace))) { 127 rc = (*fun)(ie, arg); 128 if (rc) 129 break; 130 } 131 end_scan_inventory(&iplace); 132 return rc; 133} 134 135/* 136 * Find a particular inventory object 137 * 138 * pinv can be a pointer to an inventory entry and the search will begin from 139 * there, or it can be 0 in which case the search starts at the beginning. 140 * A -1 for any of the other arguments is a wildcard (i.e. it always matches). 141 */ 142inventory_t * 143find_inventory(inventory_t *pinv, int class, int type, int controller, 144 int unit, int state) 145{ 146 invplace_t iplace = { NULL,NULL, NULL }; 147 148 start_scan_inventory(&iplace); 149 while ((pinv = (inventory_t *)get_next_inventory(&iplace)) != NULL) { 150 if (class != -1 && pinv->inv_class != class) 151 continue; 152 if (type != -1 && pinv->inv_type != type) 153 continue; 154 155 /* XXXX - perhaps the "state" entry should be ignored so an 156 * an existing entry can be updated. See vino_init() and 157 * ml/IP22.c:add_ioboard() for an example. 158 */ 159 if (state != -1 && pinv->inv_state != state) 160 continue; 161 if (controller != -1 162 && pinv->inv_controller != controller) 163 continue; 164 if (unit != -1 && pinv->inv_unit != unit) 165 continue; 166 break; 167 } 168 end_scan_inventory(&iplace); 169 170 return(pinv); 171} 172 173 174/* 175** Retrieve inventory data associated with a device. 176*/ 177inventory_t * 178device_inventory_get_next( devfs_handle_t device, 179 invplace_t *invplace) 180{ 181 inventory_t *pinv; 182 int rv; 183 184 rv = hwgraph_inventory_get_next(device, invplace, &pinv); 185 if (rv == LABELCL_SUCCESS) 186 return(pinv); 187 else 188 return(NULL); 189} 190 191 192/* 193** Associate canonical inventory information with a device (and 194** add it to the general inventory). 195*/ 196void 197device_inventory_add( devfs_handle_t device, 198 int class, 199 int type, 200 major_t controller, 201 minor_t unit, 202 int state) 203{ 204 hwgraph_inventory_add(device, class, type, controller, unit, state); 205} 206 207int 208device_controller_num_get(devfs_handle_t device) 209{ 210 return (hwgraph_controller_num_get(device)); 211} 212 213void 214device_controller_num_set(devfs_handle_t device, int contr_num) 215{ 216 hwgraph_controller_num_set(device, contr_num); 217} 218