1 #include <sys/sysmacros.h>
2 #include <sys/vmsystm.h>
6 #include <linux/proc_fs.h>
12 static char spl_debug_buffer
[MAXMSGLEN
];
13 static spinlock_t spl_debug_lock
= SPIN_LOCK_UNLOCKED
;
15 unsigned long spl_debug_mask
= 0;
16 unsigned long spl_debug_subsys
= 0xff;
17 EXPORT_SYMBOL(spl_debug_mask
);
18 EXPORT_SYMBOL(spl_debug_subsys
);
20 static struct proc_dir_entry
*spl_proc_root
= NULL
;
21 static struct proc_dir_entry
*spl_proc_debug_mask
= NULL
;
22 static struct proc_dir_entry
*spl_proc_debug_subsys
= NULL
;
28 EXPORT_SYMBOL(hw_serial
);
30 vmem_t
*zio_alloc_arena
= NULL
;
31 EXPORT_SYMBOL(zio_alloc_arena
);
35 highbit(unsigned long i
)
41 #if BITS_PER_LONG == 64
42 if (i
& 0xffffffff00000000ul
) {
63 EXPORT_SYMBOL(highbit
);
66 ddi_strtoul(const char *str
, char **nptr
, int base
, unsigned long *result
)
69 return (*result
= simple_strtoul(str
, &end
, base
));
71 EXPORT_SYMBOL(ddi_strtoul
);
73 /* XXX: Not the most efficient debug function ever. This should be re-done
74 * as an internal per-cpu in-memory debug log accessable via /proc/. Not as
75 * a shared global buffer everything gets serialize though. That said I'll
76 * worry about performance considerations once I've dealt with correctness.
79 __dprintf(const char *file
, const char *func
, int line
, const char *fmt
, ...)
81 char *sfp
, *start
, *ptr
;
86 start
= ptr
= spl_debug_buffer
;
87 sfp
= strrchr(file
, '/');
90 /* XXX: This is particularly bad for performance, but we need to
91 * disable irqs here or two __dprintf()'s may deadlock on each
92 * other if one if called from an irq handler. This is yet another
93 * reason why we really, really, need an internal debug log.
95 spin_lock_irqsave(&spl_debug_lock
, flags
);
96 ptr
+= snprintf(ptr
, MAXMSGLEN
- 1,
97 "spl: %lu.%06lu:%d:%u:%s:%d:%s(): ",
98 tv
.tv_sec
, tv
.tv_usec
, current
->pid
,
100 sfp
== NULL
? file
: sfp
+ 1,
104 ptr
+= vsnprintf(ptr
, MAXMSGLEN
- (ptr
- start
) - 1, fmt
, ap
);
108 spin_unlock_irqrestore(&spl_debug_lock
, flags
);
110 EXPORT_SYMBOL(__dprintf
);
113 spl_proc_rd_generic_ul(char *page
, char **start
, off_t off
,
114 int count
, int *eof
, unsigned long val
)
121 if (off
|| count
> PAGE_SIZE
)
124 spin_lock(&spl_debug_lock
);
125 rc
= snprintf(page
, PAGE_SIZE
, "0x%lx\n", val
);
126 spin_unlock(&spl_debug_lock
);
132 spl_proc_rd_debug_mask(char *page
, char **start
, off_t off
,
133 int count
, int *eof
, void *data
)
135 return spl_proc_rd_generic_ul(page
, start
, off
, count
,
136 eof
, spl_debug_mask
);
140 spl_proc_rd_debug_subsys(char *page
, char **start
, off_t off
,
141 int count
, int *eof
, void *data
)
143 return spl_proc_rd_generic_ul(page
, start
, off
, count
,
144 eof
, spl_debug_subsys
);
148 spl_proc_wr_generic_ul(const char *ubuf
, unsigned long count
,
149 unsigned long *val
, int base
)
153 if (count
>= sizeof(kbuf
))
156 if (copy_from_user(kbuf
, ubuf
, count
))
160 *val
= (int)simple_strtoul(kbuf
, &end
, base
);
168 spl_proc_wr_debug_mask(struct file
*file
, const char *ubuf
,
169 unsigned long count
, void *data
, int mode
)
174 rc
= spl_proc_wr_generic_ul(ubuf
, count
, &val
, 16);
178 spin_lock(&spl_debug_lock
);
179 spl_debug_mask
= val
;
180 spin_unlock(&spl_debug_lock
);
186 spl_proc_wr_debug_subsys(struct file
*file
, const char *ubuf
,
187 unsigned long count
, void *data
, int mode
)
192 rc
= spl_proc_wr_generic_ul(ubuf
, count
, &val
, 16);
196 spin_lock(&spl_debug_lock
);
197 spl_debug_subsys
= val
;
198 spin_unlock(&spl_debug_lock
);
203 static struct proc_dir_entry
*
204 spl_register_proc_entry(const char *name
, mode_t mode
,
205 struct proc_dir_entry
*parent
, void *data
,
206 void *read_proc
, void *write_proc
)
208 struct proc_dir_entry
*entry
;
210 entry
= create_proc_entry(name
, mode
, parent
);
212 return ERR_PTR(-EINVAL
);
215 entry
->read_proc
= read_proc
;
216 entry
->write_proc
= write_proc
;
219 } /* register_proc_entry() */
221 void spl_set_debug_mask(unsigned long mask
) {
222 spin_lock(&spl_debug_lock
);
223 spl_debug_mask
= mask
;
224 spin_unlock(&spl_debug_lock
);
226 EXPORT_SYMBOL(spl_set_debug_mask
);
228 void spl_set_debug_subsys(unsigned long mask
) {
229 spin_lock(&spl_debug_lock
);
230 spl_debug_subsys
= mask
;
231 spin_unlock(&spl_debug_lock
);
233 EXPORT_SYMBOL(spl_set_debug_subsys
);
235 static int __init
spl_init(void)
239 spl_proc_root
= proc_mkdir("spl", NULL
);
240 if (!spl_proc_root
) {
241 printk("spl: Error unable to create /proc/spl/ directory\n");
245 spl_proc_debug_mask
= spl_register_proc_entry("debug_mask", 0644,
247 spl_proc_rd_debug_mask
,
248 spl_proc_wr_debug_mask
);
249 if (IS_ERR(spl_proc_debug_mask
)) {
250 rc
= PTR_ERR(spl_proc_debug_mask
);
254 spl_proc_debug_subsys
= spl_register_proc_entry("debug_subsys", 0644,
256 spl_proc_rd_debug_subsys
,
257 spl_proc_wr_debug_subsys
);
258 if (IS_ERR(spl_proc_debug_subsys
)) {
259 rc
= PTR_ERR(spl_proc_debug_subsys
);
263 if ((rc
= kmem_init()))
266 if ((rc
= vn_init()))
269 strcpy(hw_serial
, "007f0100"); /* loopback */
270 printk("spl: Loaded Solaris Porting Layer v%s\n", VERSION
);
274 if (spl_proc_debug_mask
)
275 remove_proc_entry("debug_mask", spl_proc_root
);
277 if (spl_proc_debug_subsys
)
278 remove_proc_entry("debug_subsys", spl_proc_root
);
280 remove_proc_entry("spl", NULL
);
285 static void spl_fini(void)
290 remove_proc_entry("debug_subsys", spl_proc_root
);
291 remove_proc_entry("debug_mask", spl_proc_root
);
292 remove_proc_entry("spl", NULL
);
297 module_init(spl_init
);
298 module_exit(spl_fini
);
300 MODULE_AUTHOR("Lawrence Livermore National Labs");
301 MODULE_DESCRIPTION("Solaris Porting Layer");
302 MODULE_LICENSE("GPL");