nlsTest.c revision 3889d936787e03cdf934a7753a284e5949e12e88
1
2/*
3 *
4 *   Copyright (c) International Business Machines  Corp., 2001
5 *
6 *   This program is free software;  you can redistribute it and/or modify
7 *   it under the terms of the GNU General Public License as published by
8 *   the Free Software Foundation; either version 2 of the License, or
9 *   (at your option) any later version.
10 *
11 *   This program is distributed in the hope that it will be useful,
12 *   but WITHOUT ANY WARRANTY;  without even the implied warranty of
13 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
14 *   the GNU General Public License for more details.
15 *
16 *   You should have received a copy of the GNU General Public License
17 *   along with this program;  if not, write to the Free Software
18 *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20
21#include <linux/types.h>
22#include <linux/kernel.h>
23#include <linux/fs.h>
24#include <linux/ioctl.h>
25#include <linux/module.h>
26#include <linux/init.h>
27#include <linux/pm.h>
28#include <linux/genhd.h>
29#include <linux/version.h>
30#include <linux/string.h>
31#include <linux/config.h>
32#include <linux/nls.h>
33
34#ifdef CONFIG_KMOD
35#include <linux/kmod.h>
36#endif
37
38#include <linux/errno.h>
39#include <linux/spinlock.h>
40#include <asm/uaccess.h>
41#include "nlsTest.h"
42
43MODULE_AUTHOR("David Cruz <cruzd@us.ibm.com>");
44MODULE_DESCRIPTION(TEST_DRIVER_NAME);
45MODULE_LICENSE("GPL");
46
47static int test_ioctl (struct inode *, struct file *, unsigned int, unsigned long);
48static int test_open (struct inode *, struct file *);
49static int test_close (struct inode *, struct file *);
50static void test_nls_base(void);
51
52static struct block_device_operations bdops = {
53        open: test_open,
54        release: test_close,
55        ioctl: test_ioctl,
56};
57
58static char genhd_flags = 0;
59static struct gendisk * gd_ptr;
60static struct pm_dev *ltp_pm_dev = NULL;
61
62static int test_open(struct inode *ino, struct file *f) {
63	printk("device open\n");
64        return 0;
65}
66
67static int test_close(struct inode *ino, struct file *f) {
68	printk("device closed\n");
69        return 0;
70}
71
72static int test_ioctl(struct inode *ino, struct file *f, unsigned int cmd, unsigned long l) {
73
74	int rc = 0;             //return code
75        int arg;
76
77        printk("Entered the ioctl call.\n");
78
79        if (copy_from_user(&arg, (void *)l, sizeof(int)) ) {
80                //bad address
81                return(-EFAULT);
82        }
83
84	switch(cmd) {
85                case OPTION1: option1(); break;
86                default:
87                        printk("Mismatching ioctl command\n");
88                        break;
89        }
90        //0 by default
91        return rc;
92}
93
94static void option1(void) {
95        printk("Module option 1 chosen\n");
96}
97
98static int ltp_pm_callback(struct pm_dev *dev, pm_request_t rqst, void *data) {
99        return 0;
100}
101
102static int test_init_module(void) {
103
104	int rc;
105
106	printk("starting module\n");
107
108	ltp_pm_dev = pm_register(PM_UNKNOWN_DEV, 0, ltp_pm_callback);
109	rc = register_blkdev(NLSMAJOR, DEVICE_NAME);
110
111	printk("BLK INC - result =%d major %d\n",rc,NLSMAJOR);
112
113        if(rc < 0) {
114                printk("Failed to register device.\n");
115                return rc;
116        }
117
118	gd_ptr = kmalloc(sizeof(struct gendisk *),GFP_KERNEL);
119	if (!gd_ptr) {
120		 printk(KERN_ALERT "ERROR getting memory !!!\n");
121		 return 0;
122	}
123
124        printk("major = %d\n",NLSMAJOR);
125	gd_ptr = alloc_disk(1);
126	printk(KERN_ALERT "gd_ptr after alloc = %p \n",gd_ptr);
127	gd_ptr->major = NLSMAJOR;
128	gd_ptr->first_minor = 0;
129	gd_ptr->fops = &bdops;
130	gd_ptr->minor_shift= MINOR_SHIFT_BITS;
131	gd_ptr->driverfs_dev = NULL;
132	gd_ptr->capacity = MAX_NUM_DISKS;
133	gd_ptr->disk_de = NULL;
134	gd_ptr->flags = genhd_flags;
135
136	sprintf(gd_ptr->disk_name, DEVICE_NAME);
137	add_disk(gd_ptr);
138
139	test_nls_base();
140
141	return 0;
142}
143
144
145static void test_exit_module(void) {
146
147	int rc;
148
149        pm_unregister(ltp_pm_dev);
150        put_disk(gd_ptr);
151        del_gendisk(gd_ptr);
152
153	rc = unregister_blkdev(NLSMAJOR, DEVICE_NAME);
154
155        if(rc < 0) {
156                printk("unregister failed %d\n",rc);
157        }
158        else {
159                printk("unregister success\n");
160        }
161}
162
163static void test_nls_base(void) {
164
165	wchar_t p=0x20;
166	__u8 s=0x01;
167	int n=2;
168	struct nls_table nls;
169	char charset[20]="David";
170
171	load_nls_default();
172	register_nls(&nls);
173	unload_nls(&nls);
174	load_nls(charset);
175	unregister_nls(&nls);
176	utf8_mbtowc(&p, &s, n);
177	utf8_mbstowcs(&p, &s, n);
178	n=20;
179	utf8_wctomb(&s, p, n);
180	utf8_wcstombs(&s, &p, n);
181}
182
183
184module_init(test_init_module)
185module_exit(test_exit_module)
186