3 * Copyright (C) 2001 Kyle A. Lucke IBM Corporation
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 /* Change Activity: */
22 /* End Change Activity */
24 #include <linux/proc_fs.h>
25 #include <linux/spinlock.h>
26 #ifndef _ISERIES_PROC_H
27 #include <asm/iSeries/iSeries_proc.h>
31 static struct proc_dir_entry * iSeries_proc_root = NULL;
32 static int iSeries_proc_initializationDone = 0;
33 static spinlock_t iSeries_proc_lock;
35 struct iSeries_proc_registration
37 struct iSeries_proc_registration *next;
38 iSeriesProcFunction functionMember;
42 struct iSeries_proc_registration preallocated[16];
43 #define MYQUEUETYPE(T) struct MYQueue##T
50 #define MYQUEUECTOR(q) do { (q)->head = NULL; (q)->tail = NULL; } while(0)
51 #define MYQUEUEENQ(q, p) \
54 if ((q)->head != NULL) { \
55 (q)->head->next = (p); \
58 (q)->tail = (q)->head = (p); \
62 #define MYQUEUEDEQ(q,p) \
66 (q)->tail = (p)->next; \
69 if ((q)->tail == NULL) \
72 MYQUEUE(iSeries_proc_registration);
73 typedef MYQUEUETYPE(iSeries_proc_registration) aQueue;
77 aQueue iSeries_queued;
79 void iSeries_proc_early_init(void)
83 iSeries_proc_initializationDone = 0;
84 spin_lock_init(&iSeries_proc_lock);
85 MYQUEUECTOR(&iSeries_free);
86 MYQUEUECTOR(&iSeries_queued);
88 spin_lock_irqsave(&iSeries_proc_lock, flags);
89 for (i = 0; i < 16; ++i) {
90 MYQUEUEENQ(&iSeries_free, preallocated+i);
92 spin_unlock_irqrestore(&iSeries_proc_lock, flags);
95 void iSeries_proc_create(void)
98 struct iSeries_proc_registration *reg = NULL;
99 spin_lock_irqsave(&iSeries_proc_lock, flags);
100 printk("iSeries_proc: Creating /proc/iSeries\n");
102 iSeries_proc_root = proc_mkdir("iSeries", 0);
103 if (!iSeries_proc_root) return;
105 MYQUEUEDEQ(&iSeries_queued, reg);
107 while (reg != NULL) {
108 (*(reg->functionMember))(iSeries_proc_root);
110 MYQUEUEDEQ(&iSeries_queued, reg);
113 iSeries_proc_initializationDone = 1;
114 spin_unlock_irqrestore(&iSeries_proc_lock, flags);
117 void iSeries_proc_callback(iSeriesProcFunction initFunction)
120 spin_lock_irqsave(&iSeries_proc_lock, flags);
122 if (iSeries_proc_initializationDone) {
123 (*initFunction)(iSeries_proc_root);
125 struct iSeries_proc_registration *reg = NULL;
127 MYQUEUEDEQ(&iSeries_free, reg);
130 /* printk("Registering %p in reg %p\n", initFunction, reg); */
131 reg->functionMember = initFunction;
133 MYQUEUEENQ(&iSeries_queued, reg);
135 printk("Couldn't get a queue entry\n");
139 spin_unlock_irqrestore(&iSeries_proc_lock, flags);