• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19  */
20 
21 /*
22  * Legacy Power Management (PM) was removed from the kernel, removed it from
23  * here also. ( http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=6afe1a1fe8ff83f6ac2726b04665e76ba7b14f3e )
24  *
25  */
26 
27 #include <linux/types.h>
28 #include <linux/kernel.h>
29 #include <linux/fs.h>
30 #include <linux/ioctl.h>
31 #include <linux/module.h>
32 #include <linux/init.h>
33 #include <linux/pm.h>
34 #include <linux/genhd.h>
35 #include <linux/version.h>
36 #include <linux/string.h>
37 #include <linux/autoconf.h>
38 #include <linux/nls.h>
39 #include <linux/blkdev.h>
40 
41 #ifdef CONFIG_KMOD
42 #include <linux/kmod.h>
43 #endif
44 
45 #include <linux/errno.h>
46 #include <linux/spinlock.h>
47 #include <linux/uaccess.h>
48 
49 #include "nlsTest.h"
50 
51 MODULE_AUTHOR("David Cruz <cruzd@us.ibm.com>");
52 MODULE_AUTHOR("Márton Németh <nm127@freemail.hu>");
53 MODULE_DESCRIPTION(TEST_DRIVER_NAME);
54 MODULE_LICENSE("GPL");
55 
56 /* Struct block_device_operations changed:
57  * http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commitdiff;h=d4430d62fa77208824a37fe6f85ab2831d274769
58  */
59 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 28)
60 static int test_open(struct inode *, struct file *);
61 static int test_release(struct inode *, struct file *);
62 static int test_ioctl(struct inode *, struct file *,
63 		      unsigned int cmd, unsigned long l);
64 #else
65 static int test_open(struct block_device *bdev, fmode_t mode);
66 static int test_release(struct gendisk *disk, fmode_t mode);
67 static int test_ioctl(struct block_device *bdev, fmode_t mode,
68 		      unsigned int cmd, unsigned long l);
69 #endif
70 
71 static void test_nls_base(void);
72 static void option1(void);
73 
74 struct test_block_device {
75 	spinlock_t queue_lock;
76 };
77 
78 static struct block_device_operations bdops = {
79 	.open = test_open,
80 	.release = test_release,
81 	.ioctl = test_ioctl,
82 };
83 
84 static struct gendisk *gd_ptr;
85 
86 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 28)
test_open(struct inode * inode,struct file * f)87 static int test_open(struct inode *inode, struct file *f)
88 #else
89 static int test_open(struct block_device *bdev, fmode_t mode)
90 #endif
91 {
92 	printk(KERN_DEBUG "device opened\n");
93 	return 0;
94 }
95 
96 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 28)
test_release(struct inode * ino,struct file * f)97 static int test_release(struct inode *ino, struct file *f)
98 #else
99 static int test_release(struct gendisk *disk, fmode_t mode)
100 #endif
101 {
102 	printk(KERN_DEBUG "device released\n");
103 	return 0;
104 }
105 
106 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 28)
test_ioctl(struct inode * ino,struct file * f,unsigned int cmd,unsigned long l)107 static int test_ioctl(struct inode *ino, struct file *f,
108 		      unsigned int cmd, unsigned long l)
109 #else
110 static int test_ioctl(struct block_device *bdev, fmode_t mode,
111 		      unsigned int cmd, unsigned long l)
112 #endif
113 {
114 	int rc = 0;		/* return code */
115 	int arg;
116 
117 	printk(KERN_DEBUG "Entered the ioctl call.\n");
118 
119 	if (copy_from_user(&arg, (void *)l, sizeof(int))) {
120 		/* bad address */
121 		return -EFAULT;
122 	}
123 
124 	switch (cmd) {
125 	case OPTION1:
126 		option1();
127 		break;
128 	default:
129 		printk(KERN_ERR "Mismatching ioctl command\n");
130 	}
131 
132 	return rc;
133 }
134 
option1(void)135 static void option1(void)
136 {
137 	printk(KERN_DEBUG "Module option 1 chosen\n");
138 }
139 
test_request(struct request_queue * q)140 static void test_request(struct request_queue *q)
141 {
142 	printk(KERN_DEBUG "test_request() called\n");
143 };
144 
test_init_module(void)145 static int test_init_module(void)
146 {
147 	struct test_block_device *dev;
148 	struct request_queue *queue;
149 	int rc;
150 
151 	printk(KERN_DEBUG "starting module\n");
152 
153 	dev = kzalloc(sizeof(*dev), GFP_KERNEL);
154 	if (!dev)
155 		return -ENOMEM;
156 
157 	rc = register_blkdev(NLSMAJOR, DEVICE_NAME);
158 
159 	printk(KERN_DEBUG "BLK INC - result=%d, major=%d\n", rc, NLSMAJOR);
160 
161 	if (rc < 0) {
162 		printk(KERN_ERR "Failed to register device.\n");
163 		kfree(dev);
164 		return rc;
165 	}
166 
167 	spin_lock_init(&dev->queue_lock);
168 
169 	gd_ptr = alloc_disk(1);
170 	if (!gd_ptr) {
171 		unregister_blkdev(NLSMAJOR, DEVICE_NAME);
172 		kfree(dev);
173 		return -ENOMEM;
174 	}
175 
176 	printk(KERN_ALERT "gd_ptr after alloc=%p\n", gd_ptr);
177 
178 	queue = blk_init_queue(test_request, &dev->queue_lock);
179 	if (!queue) {
180 		del_gendisk(gd_ptr);
181 		unregister_blkdev(NLSMAJOR, DEVICE_NAME);
182 		kfree(dev);
183 		return -ENOMEM;
184 	}
185 
186 	gd_ptr->major = NLSMAJOR;
187 	gd_ptr->first_minor = 0;
188 	gd_ptr->fops = &bdops;
189 	gd_ptr->queue = queue;
190 	gd_ptr->private_data = dev;
191 	snprintf(gd_ptr->disk_name, sizeof(gd_ptr->disk_name), DEVICE_NAME);
192 	add_disk(gd_ptr);
193 
194 	printk(KERN_DEBUG "block device %s added\n", DEVICE_NAME);
195 
196 	test_nls_base();
197 
198 	return 0;
199 }
200 
test_exit_module(void)201 static void test_exit_module(void)
202 {
203 	printk(KERN_DEBUG "unloading module\n");
204 
205 	del_gendisk(gd_ptr);
206 	unregister_blkdev(NLSMAJOR, DEVICE_NAME);
207 }
208 
test_nls_base(void)209 static void test_nls_base(void)
210 {
211 	wchar_t p = 0x20;
212 	__u8 s = 0x01;
213 	int n = 2;
214 	struct nls_table nls;
215 	struct nls_table *nls_ptr;
216 	int ret;
217 	char charset[20] = "David";
218 
219 	memset(&nls, 0, sizeof(nls));
220 
221 	printk(KERN_DEBUG "Calling load_nls_default()\n");
222 	nls_ptr = load_nls_default();
223 	printk(KERN_DEBUG "load_nls_default() returns %p\n", nls_ptr);
224 
225 	printk(KERN_DEBUG "Calling register_nls(%p)\n", &nls);
226 	ret = register_nls(&nls);
227 	printk(KERN_DEBUG "register_nls() returns %i\n", ret);
228 
229 	printk(KERN_DEBUG "Calling unload_nls(%p)\n", &nls);
230 	unload_nls(&nls);
231 
232 	printk(KERN_DEBUG "Calling load_nls(\"%s\")\n", charset);
233 	nls_ptr = load_nls(charset);
234 	printk(KERN_DEBUG "load_nls() returns %p\n", nls_ptr);
235 
236 	printk(KERN_DEBUG "Calling unregister_nls(%p)\n", &nls);
237 	unregister_nls(&nls);
238 
239 	printk(KERN_DEBUG "Calling utf8_mbtowc(%p, %p, %i);\n", &p, &s, n);
240 	ret = utf8_mbtowc(&p, &s, n);
241 	printk(KERN_DEBUG "utf8_mbtowc() returns %i\n", ret);
242 
243 	printk(KERN_DEBUG "Calling utf8_mbstowcs(%p, %p, %i);\n", &p, &s, n);
244 	ret = utf8_mbstowcs(&p, &s, n);
245 	printk(KERN_DEBUG "utf8_mbstowcs() returns %i\n", ret);
246 
247 	n = 20;
248 
249 	printk(KERN_DEBUG "Calling utf8_wctomb(%p, 0x%X, %i);\n", &s, p, n);
250 	ret = utf8_wctomb(&s, p, n);
251 	printk(KERN_DEBUG "utf8_wctomb() returns %i\n", ret);
252 
253 	printk(KERN_DEBUG "Calling utf8_wcstombs(%p, %p, %i);\n", &s, &p, n);
254 	ret = utf8_wcstombs(&s, &p, n);
255 	printk(KERN_DEBUG "utf8_wcstombs() returns %i\n", ret);
256 
257 }
258 
259 module_init(test_init_module);
260 module_exit(test_exit_module);
261