/* probe-example.c
 *
 * Connects two functions to marker call sites.
 *
 * (C) Copyright 2007 Mathieu Desnoyers <mathieu.desnoyers@polymtl.ca>
 *
 * This file is released under the GPLv2.
 * See the file COPYING for more details.
 */

#include <linux/sched.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/marker.h>
#include <asm/atomic.h>

struct probe_data {
	const char *name;
	const char *format;
	marker_probe_func *probe_func;
};

void probe_subsystem_event(const struct marker *mdata, void *private,
	const char *format, ...)
{
	va_list ap;
	/* Declare args */
	unsigned int value;
	const char *mystr;

	/* Assign args */
	va_start(ap, format);
	value = va_arg(ap, typeof(value));
	mystr = va_arg(ap, typeof(mystr));

	/* Call printk */
	printk(KERN_DEBUG "Value %u, string %s\n", value, mystr);

	/* or count, check rights, serialize data in a buffer */

	va_end(ap);
}

atomic_t eventb_count = ATOMIC_INIT(0);

void probe_subsystem_eventb(const struct marker *mdata, void *private,
	const char *format, ...)
{
	/* Increment counter */
	atomic_inc(&eventb_count);
}

static struct probe_data probe_array[] =
{
	{	.name = "subsystem_event",
		.format = "integer %d string %s",
		.probe_func = probe_subsystem_event },
	{	.name = "subsystem_eventb",
		.format = MARK_NOARGS,
		.probe_func = probe_subsystem_eventb },
};

static int __init probe_init(void)
{
	int result;
	int i;

	for (i = 0; i < ARRAY_SIZE(probe_array); i++) {
		result = marker_probe_register(probe_array[i].name,
				probe_array[i].format,
				probe_array[i].probe_func, &probe_array[i]);
		if (result)
			printk(KERN_INFO "Unable to register probe %s\n",
				probe_array[i].name);
		result = marker_arm(probe_array[i].name);
		if (result)
			printk(KERN_INFO "Unable to arm probe %s\n",
				probe_array[i].name);
	}
	return 0;
}

static void __exit probe_fini(void)
{
	int i;

	for (i = 0; i < ARRAY_SIZE(probe_array); i++)
		marker_probe_unregister(probe_array[i].name);
	printk(KERN_INFO "Number of event b : %u\n",
			atomic_read(&eventb_count));
}

module_init(probe_init);
module_exit(probe_fini);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Mathieu Desnoyers");
MODULE_DESCRIPTION("SUBSYSTEM Probe");
