/*
 * modprms.c:  examples of module parameters in Linux 2.5.60-ish and later;
 * Copyright (C) 2003-2004 Randy Dunlap <rddunlap@ieee.org>
 */

/******************************************************************
#   This program is free software; you can redistribute it and/or modify
#   it under the terms of the GNU General Public License as published by
#   the Free Software Foundation; either version 2 of the License, or
#   (at your option) any later version.
#
#   This program is distributed in the hope that it will be useful,
#   but WITHOUT ANY WARRANTY; without even the implied warranty of
#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#   GNU General Public License for more details.
#
#   You should have received a copy of the GNU General Public License
#   along with this program; if not, write to the Free Software
#   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
******************************************************************/

#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/proc_fs.h>
#include <linux/stat.h>

/*
* This module illustrates module parameters in Linux 2.5.60/2.6.x.
* It does not stay loaded; it just runs its init_module() function,
* prints its parameters, and exits.
*
* version 0.1:  initial version;
* version 0.2:  add some new MODULE_xyz() and module_xyz() examples;
*/

#define MODNAME		"modprms: "
#define VERSION		"0.2"

/*
 * "module_param" supports several data types:
 * byte, short, ushort, int, uint, long, ulong, charp,
 * bool, invbool, or XYZ, where you define XYZ and its
 * helper functions.
 */

/* param named "count" is an <int> */
int count;
module_param (count, int, 000);

/* param "charp" is a <charp> */
char *charp;
module_param (charp, charp, 000);

/* param string is copied */
#define STRING_SIZE	100
char echo_str [STRING_SIZE];
module_param_string (echo_str, echo_str, STRING_SIZE, 000);

#define LONGARY_SIZE	10
long longary [LONGARY_SIZE];
int longary_length;	// number of user input items
module_param_array(longary, long, longary_length, 000);

/***** for user-define type 'intary': *****/
#define param_check_intary(name, value) __param_check(name, value, intary)

/* Returns length written or -errno.  Max buf is 4 KiB. */
int param_get_intary (char *buf, struct kernel_param *kp)
{
	return 0;
}

/* Returns 0 or -errno. */
int param_set_intary (const char *val, struct kernel_param *kp)
{
	return 0;
}

/* param "intary" is an int array */
#define INTARY_SIZE	10
typedef int	intary[INTARY_SIZE];
intary intsary;
module_param_named(intsary, intsary, intary, 000);
/***** end user-defined type 'intary' *****/

static int __init modprms_init (void)
{
	int ix;

	printk (MODNAME "loaded: {v." VERSION "}\n");
	printk (MODNAME "count: %d\n", count);
	printk (MODNAME "charp: %s\n", charp);
	printk (MODNAME "echo_str: %s\n", echo_str);
	printk (MODNAME "longary_length: %d\n", longary_length);
	for (ix = 0; ix < longary_length; ix++)
		printk ("  [%d] = %ld (0x%lx)\n",
				ix, longary [ix], longary [ix]);

	return -1;
}

static void __exit modprms_exit (void)
{
	printk (MODNAME "exit\n");
}

module_init (modprms_init);
module_exit (modprms_exit);

MODULE_AUTHOR ("Randy.Dunlap");
MODULE_ALIAS ("mod_prms");
MODULE_DESCRIPTION ("modprms-example");
MODULE_SUPPORTED_DEVICE ("/dev/nil");
MODULE_PARM_DESC (nil, "nil ptr to use when accessing kernel memory");
MODULE_PARM_DESC (nul, "1-" __MODULE_STRING(STRING_SIZE) "p");
MODULE_LICENSE ("GPL");
MODULE_VERSION (VERSION);
MODULE_INFO (comment, "this is just an INFO example.");
///MODULE_GENERIC_TABLE();
///MODULE_DEVICE_TABLE (convert, dev_convert);
