1/*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21/*
22 * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
23 * Use is subject to license terms.
24 */
25
26#ifndef _CMD_BANK_H
27#define	_CMD_BANK_H
28
29#pragma ident	"%Z%%M%	%I%	%E% SMI"
30
31/*
32 * Collections of memory modules are known as banks, and are described by
33 * the cmd_bank general-purpose state structure.  The bank structure --
34 * cmd_bank_t -- is itself comprised of a persistent (cmd_bank_pers_t) and
35 * dynamic (the rest of cmd_bank_t) portions.  While we'd prefer to associate
36 * errors with individual modules, some errors (UEs) may only be attributed to
37 * a bank of modules.  This structure is used to track the UEs.  Links are made
38 * (via bank_dimms) to the known memory modules that comprise the bank.  Note
39 * that memory modules are discovered lazily - as ereports naming them are
40 * processed.  As such, the bank_dimms list may be empty, or may only list a
41 * subset of the modules in the bank.
42 *
43 * Data structures:
44 *
45 *     ,--------.       ,--------.
46 *     |bank    | <---- |case_ptr| (CMD_PTR_BANK_CASE)
47 *     |        |       `--------'
48 *     |,-------|       ,-------------.
49 *  ,->||asru_t | ----> |packed nvlist|
50 *  |  |`-------|       `-------------'
51 *  `--| unum   |       ,---------.       ,---------.
52 *     | dimms  | ----> |bank_memb| ----> |bank_memb| ----> ...
53 *     `--------'       `---------'       `---------'
54 *                           |                 |
55 *                           V                 V
56 *                      dimm buffer       dimm buffer
57 *
58 * Data structure	P?  Case? Notes
59 * ----------------	--- ----- -------------------------------------
60 * cmd_bank_pers_t	Yes No    Name is unum-derived ("bank_%s")
61 * cmd_case_ptr_t	Yes Yes   Name is case's UUID
62 * bank_asru		Yes No    Name is unum-derived ("bank_asru_%d")
63 * bank_unum		No  No    Pointer into ASRU - relinked during restore
64 * bank_dimms		No  No    Recreated during restore
65 */
66
67#include <cmd_mem.h>
68
69#ifdef __cplusplus
70extern "C" {
71#endif
72
73/*
74 * Tracks the discovered DIMMs that make up a given bank.  Only DIMMs that have
75 * experienced errors independently of the bank will be included in this list.
76 */
77typedef struct cmd_bank_memb {
78	cmd_list_t bm_list;		/* Memory module list */
79	cmd_dimm_t *bm_dimm;		/* This memory module */
80} cmd_bank_memb_t;
81
82/*
83 * The bank structure started life without a version number.  Making things more
84 * complicated, the version number in the new struct occupies the space used for
85 * the case pointer in the non-versioned struct.  We therefore have to use
86 * somewhat unorthodox version numbers so as to allow us to easily tell the
87 * difference between a version number and a case pointer.  Case pointers will
88 * be zero or (this being SPARC), a value with the bottom two bits clear.  Our
89 * version numbers will begin with 0x11, and will increase by 0x10 each time.
90 */
91
92#define	BANK_MKVERSION(version)	((version) << 4 | 1)
93
94#define	CMD_BANK_VERSION_1	BANK_MKVERSION(1)	/* 17 */
95#define	CMD_BANK_VERSION	CMD_DIMM_VERSION_1
96
97#define	CMD_BANK_VERSIONED(bank)	((bank)->bank_version & 1)
98
99#define	CMD_BANK_STAT_PREFIX		"b"	/* b = bank */
100
101typedef struct cmd_bank_0 {
102	cmd_header_t bank0_header;	/* Nodetype must be CMD_NT_BANK */
103	fmd_case_t *bank0_case;		/* Open UE case against this bank */
104	cmd_fmri_t bank0_asru;		/* ASRU for this bank */
105	const char *bank0_unum;		/* This bank's name (ptr into ASRU) */
106	cmd_list_t bank0_dimms;		/* List of discovered DIMMs in bank */
107	uint_t bank0_wrnthresh;		/* # of pages retired before warning */
108	uint_t bank0_nretired;		/* # ret'd pages for UEs in bank */
109} cmd_bank_0_t;
110
111/* Portion of the bank structure which must be persisted */
112typedef struct cmd_bank_pers {
113	cmd_header_t bankp_header;	/* Nodetype must be CMD_NT_BANK */
114	uint_t bankp_version;		/* Version of this persistent buffer */
115	cmd_fmri_t bankp_asru;		/* ASRU for this bank */
116	uint_t bankp_flags;		/* CMD_MEM_F_* */
117	uint_t bankp_nretired;		/* # ret'd pages for UEs in bank */
118} cmd_bank_pers_t;
119
120/* Persistent and dynamic bank data */
121struct cmd_bank {
122	cmd_bank_pers_t bank_pers;	/* Persistent data for this bank */
123	const char *bank_unum;		/* This bank's name (ptr into ASRU) */
124	cmd_list_t bank_dimms;		/* List of discovered DIMMs in bank */
125	cmd_case_t bank_case;		/* Open UE case against this bank */
126	fmd_stat_t bank_retstat;	/* Publicizes num of page retirements */
127};
128
129#define	CMD_BANK_MAXSIZE \
130	MAX(sizeof (cmd_bank_0_t), sizeof (cmd_bank_pers_t))
131#define	CMD_BANK_MINSIZE \
132	MIN(sizeof (cmd_bank_0_t), sizeof (cmd_bank_pers_t))
133
134#define	bank_header		bank_pers.bankp_header
135#define	bank_nodetype		bank_pers.bankp_header.hdr_nodetype
136#define	bank_bufname		bank_pers.bankp_header.hdr_bufname
137#define	bank_version		bank_pers.bankp_version
138#define	bank_asru		bank_pers.bankp_asru
139#define	bank_asru_nvl		bank_pers.bankp_asru.fmri_nvl
140#define	bank_flags		bank_pers.bankp_flags
141#define	bank_nretired		bank_pers.bankp_nretired
142
143extern cmd_bank_t *cmd_bank_lookup(fmd_hdl_t *, nvlist_t *);
144extern cmd_bank_t *cmd_bank_create(fmd_hdl_t *, nvlist_t *);
145
146extern nvlist_t *cmd_bank_fru(cmd_bank_t *);
147extern nvlist_t *cmd_bank_create_fault(fmd_hdl_t *, cmd_bank_t *, const char *,
148    uint_t);
149
150extern void cmd_bank_add_dimm(fmd_hdl_t *, cmd_bank_t *, cmd_dimm_t *);
151extern void cmd_bank_remove_dimm(fmd_hdl_t *, cmd_bank_t *, cmd_dimm_t *);
152
153extern void cmd_bank_dirty(fmd_hdl_t *, cmd_bank_t *);
154extern void *cmd_bank_restore(fmd_hdl_t *, fmd_case_t *, cmd_case_ptr_t *);
155extern void cmd_bank_destroy(fmd_hdl_t *, cmd_bank_t *);
156extern void cmd_bank_validate(fmd_hdl_t *);
157extern void cmd_bank_gc(fmd_hdl_t *);
158extern void cmd_bank_fini(fmd_hdl_t *);
159
160#ifdef __cplusplus
161}
162#endif
163
164#endif /* _CMD_BANK_H */
165