xref: /aosp_15_r20/external/ltp/testcases/kernel/device-drivers/nls/nlsTest.c (revision 49cdfc7efb34551c7342be41a7384b9c40d7cab7)
1*49cdfc7eSAndroid Build Coastguard Worker 
2*49cdfc7eSAndroid Build Coastguard Worker /*
3*49cdfc7eSAndroid Build Coastguard Worker  *
4*49cdfc7eSAndroid Build Coastguard Worker  *   Copyright (c) International Business Machines  Corp., 2001
5*49cdfc7eSAndroid Build Coastguard Worker  *
6*49cdfc7eSAndroid Build Coastguard Worker  *   This program is free software;  you can redistribute it and/or modify
7*49cdfc7eSAndroid Build Coastguard Worker  *   it under the terms of the GNU General Public License as published by
8*49cdfc7eSAndroid Build Coastguard Worker  *   the Free Software Foundation; either version 2 of the License, or
9*49cdfc7eSAndroid Build Coastguard Worker  *   (at your option) any later version.
10*49cdfc7eSAndroid Build Coastguard Worker  *
11*49cdfc7eSAndroid Build Coastguard Worker  *   This program is distributed in the hope that it will be useful,
12*49cdfc7eSAndroid Build Coastguard Worker  *   but WITHOUT ANY WARRANTY;  without even the implied warranty of
13*49cdfc7eSAndroid Build Coastguard Worker  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
14*49cdfc7eSAndroid Build Coastguard Worker  *   the GNU General Public License for more details.
15*49cdfc7eSAndroid Build Coastguard Worker  *
16*49cdfc7eSAndroid Build Coastguard Worker  *   You should have received a copy of the GNU General Public License
17*49cdfc7eSAndroid Build Coastguard Worker  *   along with this program;  if not, write to the Free Software
18*49cdfc7eSAndroid Build Coastguard Worker  *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19*49cdfc7eSAndroid Build Coastguard Worker  */
20*49cdfc7eSAndroid Build Coastguard Worker 
21*49cdfc7eSAndroid Build Coastguard Worker /*
22*49cdfc7eSAndroid Build Coastguard Worker  * Legacy Power Management (PM) was removed from the kernel, removed it from
23*49cdfc7eSAndroid Build Coastguard Worker  * here also. ( http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=6afe1a1fe8ff83f6ac2726b04665e76ba7b14f3e )
24*49cdfc7eSAndroid Build Coastguard Worker  *
25*49cdfc7eSAndroid Build Coastguard Worker  */
26*49cdfc7eSAndroid Build Coastguard Worker 
27*49cdfc7eSAndroid Build Coastguard Worker #include <linux/types.h>
28*49cdfc7eSAndroid Build Coastguard Worker #include <linux/kernel.h>
29*49cdfc7eSAndroid Build Coastguard Worker #include <linux/fs.h>
30*49cdfc7eSAndroid Build Coastguard Worker #include <linux/ioctl.h>
31*49cdfc7eSAndroid Build Coastguard Worker #include <linux/module.h>
32*49cdfc7eSAndroid Build Coastguard Worker #include <linux/init.h>
33*49cdfc7eSAndroid Build Coastguard Worker #include <linux/pm.h>
34*49cdfc7eSAndroid Build Coastguard Worker #include <linux/genhd.h>
35*49cdfc7eSAndroid Build Coastguard Worker #include <linux/version.h>
36*49cdfc7eSAndroid Build Coastguard Worker #include <linux/string.h>
37*49cdfc7eSAndroid Build Coastguard Worker #include <linux/autoconf.h>
38*49cdfc7eSAndroid Build Coastguard Worker #include <linux/nls.h>
39*49cdfc7eSAndroid Build Coastguard Worker #include <linux/blkdev.h>
40*49cdfc7eSAndroid Build Coastguard Worker 
41*49cdfc7eSAndroid Build Coastguard Worker #ifdef CONFIG_KMOD
42*49cdfc7eSAndroid Build Coastguard Worker #include <linux/kmod.h>
43*49cdfc7eSAndroid Build Coastguard Worker #endif
44*49cdfc7eSAndroid Build Coastguard Worker 
45*49cdfc7eSAndroid Build Coastguard Worker #include <linux/errno.h>
46*49cdfc7eSAndroid Build Coastguard Worker #include <linux/spinlock.h>
47*49cdfc7eSAndroid Build Coastguard Worker #include <linux/uaccess.h>
48*49cdfc7eSAndroid Build Coastguard Worker 
49*49cdfc7eSAndroid Build Coastguard Worker #include "nlsTest.h"
50*49cdfc7eSAndroid Build Coastguard Worker 
51*49cdfc7eSAndroid Build Coastguard Worker MODULE_AUTHOR("David Cruz <[email protected]>");
52*49cdfc7eSAndroid Build Coastguard Worker MODULE_AUTHOR("Márton Németh <[email protected]>");
53*49cdfc7eSAndroid Build Coastguard Worker MODULE_DESCRIPTION(TEST_DRIVER_NAME);
54*49cdfc7eSAndroid Build Coastguard Worker MODULE_LICENSE("GPL");
55*49cdfc7eSAndroid Build Coastguard Worker 
56*49cdfc7eSAndroid Build Coastguard Worker /* Struct block_device_operations changed:
57*49cdfc7eSAndroid Build Coastguard Worker  * http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commitdiff;h=d4430d62fa77208824a37fe6f85ab2831d274769
58*49cdfc7eSAndroid Build Coastguard Worker  */
59*49cdfc7eSAndroid Build Coastguard Worker #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 28)
60*49cdfc7eSAndroid Build Coastguard Worker static int test_open(struct inode *, struct file *);
61*49cdfc7eSAndroid Build Coastguard Worker static int test_release(struct inode *, struct file *);
62*49cdfc7eSAndroid Build Coastguard Worker static int test_ioctl(struct inode *, struct file *,
63*49cdfc7eSAndroid Build Coastguard Worker 		      unsigned int cmd, unsigned long l);
64*49cdfc7eSAndroid Build Coastguard Worker #else
65*49cdfc7eSAndroid Build Coastguard Worker static int test_open(struct block_device *bdev, fmode_t mode);
66*49cdfc7eSAndroid Build Coastguard Worker static int test_release(struct gendisk *disk, fmode_t mode);
67*49cdfc7eSAndroid Build Coastguard Worker static int test_ioctl(struct block_device *bdev, fmode_t mode,
68*49cdfc7eSAndroid Build Coastguard Worker 		      unsigned int cmd, unsigned long l);
69*49cdfc7eSAndroid Build Coastguard Worker #endif
70*49cdfc7eSAndroid Build Coastguard Worker 
71*49cdfc7eSAndroid Build Coastguard Worker static void test_nls_base(void);
72*49cdfc7eSAndroid Build Coastguard Worker static void option1(void);
73*49cdfc7eSAndroid Build Coastguard Worker 
74*49cdfc7eSAndroid Build Coastguard Worker struct test_block_device {
75*49cdfc7eSAndroid Build Coastguard Worker 	spinlock_t queue_lock;
76*49cdfc7eSAndroid Build Coastguard Worker };
77*49cdfc7eSAndroid Build Coastguard Worker 
78*49cdfc7eSAndroid Build Coastguard Worker static struct block_device_operations bdops = {
79*49cdfc7eSAndroid Build Coastguard Worker 	.open = test_open,
80*49cdfc7eSAndroid Build Coastguard Worker 	.release = test_release,
81*49cdfc7eSAndroid Build Coastguard Worker 	.ioctl = test_ioctl,
82*49cdfc7eSAndroid Build Coastguard Worker };
83*49cdfc7eSAndroid Build Coastguard Worker 
84*49cdfc7eSAndroid Build Coastguard Worker static struct gendisk *gd_ptr;
85*49cdfc7eSAndroid Build Coastguard Worker 
86*49cdfc7eSAndroid Build Coastguard Worker #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 28)
test_open(struct inode * inode,struct file * f)87*49cdfc7eSAndroid Build Coastguard Worker static int test_open(struct inode *inode, struct file *f)
88*49cdfc7eSAndroid Build Coastguard Worker #else
89*49cdfc7eSAndroid Build Coastguard Worker static int test_open(struct block_device *bdev, fmode_t mode)
90*49cdfc7eSAndroid Build Coastguard Worker #endif
91*49cdfc7eSAndroid Build Coastguard Worker {
92*49cdfc7eSAndroid Build Coastguard Worker 	printk(KERN_DEBUG "device opened\n");
93*49cdfc7eSAndroid Build Coastguard Worker 	return 0;
94*49cdfc7eSAndroid Build Coastguard Worker }
95*49cdfc7eSAndroid Build Coastguard Worker 
96*49cdfc7eSAndroid Build Coastguard Worker #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 28)
test_release(struct inode * ino,struct file * f)97*49cdfc7eSAndroid Build Coastguard Worker static int test_release(struct inode *ino, struct file *f)
98*49cdfc7eSAndroid Build Coastguard Worker #else
99*49cdfc7eSAndroid Build Coastguard Worker static int test_release(struct gendisk *disk, fmode_t mode)
100*49cdfc7eSAndroid Build Coastguard Worker #endif
101*49cdfc7eSAndroid Build Coastguard Worker {
102*49cdfc7eSAndroid Build Coastguard Worker 	printk(KERN_DEBUG "device released\n");
103*49cdfc7eSAndroid Build Coastguard Worker 	return 0;
104*49cdfc7eSAndroid Build Coastguard Worker }
105*49cdfc7eSAndroid Build Coastguard Worker 
106*49cdfc7eSAndroid Build Coastguard Worker #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 28)
test_ioctl(struct inode * ino,struct file * f,unsigned int cmd,unsigned long l)107*49cdfc7eSAndroid Build Coastguard Worker static int test_ioctl(struct inode *ino, struct file *f,
108*49cdfc7eSAndroid Build Coastguard Worker 		      unsigned int cmd, unsigned long l)
109*49cdfc7eSAndroid Build Coastguard Worker #else
110*49cdfc7eSAndroid Build Coastguard Worker static int test_ioctl(struct block_device *bdev, fmode_t mode,
111*49cdfc7eSAndroid Build Coastguard Worker 		      unsigned int cmd, unsigned long l)
112*49cdfc7eSAndroid Build Coastguard Worker #endif
113*49cdfc7eSAndroid Build Coastguard Worker {
114*49cdfc7eSAndroid Build Coastguard Worker 	int rc = 0;		/* return code */
115*49cdfc7eSAndroid Build Coastguard Worker 	int arg;
116*49cdfc7eSAndroid Build Coastguard Worker 
117*49cdfc7eSAndroid Build Coastguard Worker 	printk(KERN_DEBUG "Entered the ioctl call.\n");
118*49cdfc7eSAndroid Build Coastguard Worker 
119*49cdfc7eSAndroid Build Coastguard Worker 	if (copy_from_user(&arg, (void *)l, sizeof(int))) {
120*49cdfc7eSAndroid Build Coastguard Worker 		/* bad address */
121*49cdfc7eSAndroid Build Coastguard Worker 		return -EFAULT;
122*49cdfc7eSAndroid Build Coastguard Worker 	}
123*49cdfc7eSAndroid Build Coastguard Worker 
124*49cdfc7eSAndroid Build Coastguard Worker 	switch (cmd) {
125*49cdfc7eSAndroid Build Coastguard Worker 	case OPTION1:
126*49cdfc7eSAndroid Build Coastguard Worker 		option1();
127*49cdfc7eSAndroid Build Coastguard Worker 		break;
128*49cdfc7eSAndroid Build Coastguard Worker 	default:
129*49cdfc7eSAndroid Build Coastguard Worker 		printk(KERN_ERR "Mismatching ioctl command\n");
130*49cdfc7eSAndroid Build Coastguard Worker 	}
131*49cdfc7eSAndroid Build Coastguard Worker 
132*49cdfc7eSAndroid Build Coastguard Worker 	return rc;
133*49cdfc7eSAndroid Build Coastguard Worker }
134*49cdfc7eSAndroid Build Coastguard Worker 
option1(void)135*49cdfc7eSAndroid Build Coastguard Worker static void option1(void)
136*49cdfc7eSAndroid Build Coastguard Worker {
137*49cdfc7eSAndroid Build Coastguard Worker 	printk(KERN_DEBUG "Module option 1 chosen\n");
138*49cdfc7eSAndroid Build Coastguard Worker }
139*49cdfc7eSAndroid Build Coastguard Worker 
test_request(struct request_queue * q)140*49cdfc7eSAndroid Build Coastguard Worker static void test_request(struct request_queue *q)
141*49cdfc7eSAndroid Build Coastguard Worker {
142*49cdfc7eSAndroid Build Coastguard Worker 	printk(KERN_DEBUG "test_request() called\n");
143*49cdfc7eSAndroid Build Coastguard Worker };
144*49cdfc7eSAndroid Build Coastguard Worker 
test_init_module(void)145*49cdfc7eSAndroid Build Coastguard Worker static int test_init_module(void)
146*49cdfc7eSAndroid Build Coastguard Worker {
147*49cdfc7eSAndroid Build Coastguard Worker 	struct test_block_device *dev;
148*49cdfc7eSAndroid Build Coastguard Worker 	struct request_queue *queue;
149*49cdfc7eSAndroid Build Coastguard Worker 	int rc;
150*49cdfc7eSAndroid Build Coastguard Worker 
151*49cdfc7eSAndroid Build Coastguard Worker 	printk(KERN_DEBUG "starting module\n");
152*49cdfc7eSAndroid Build Coastguard Worker 
153*49cdfc7eSAndroid Build Coastguard Worker 	dev = kzalloc(sizeof(*dev), GFP_KERNEL);
154*49cdfc7eSAndroid Build Coastguard Worker 	if (!dev)
155*49cdfc7eSAndroid Build Coastguard Worker 		return -ENOMEM;
156*49cdfc7eSAndroid Build Coastguard Worker 
157*49cdfc7eSAndroid Build Coastguard Worker 	rc = register_blkdev(NLSMAJOR, DEVICE_NAME);
158*49cdfc7eSAndroid Build Coastguard Worker 
159*49cdfc7eSAndroid Build Coastguard Worker 	printk(KERN_DEBUG "BLK INC - result=%d, major=%d\n", rc, NLSMAJOR);
160*49cdfc7eSAndroid Build Coastguard Worker 
161*49cdfc7eSAndroid Build Coastguard Worker 	if (rc < 0) {
162*49cdfc7eSAndroid Build Coastguard Worker 		printk(KERN_ERR "Failed to register device.\n");
163*49cdfc7eSAndroid Build Coastguard Worker 		kfree(dev);
164*49cdfc7eSAndroid Build Coastguard Worker 		return rc;
165*49cdfc7eSAndroid Build Coastguard Worker 	}
166*49cdfc7eSAndroid Build Coastguard Worker 
167*49cdfc7eSAndroid Build Coastguard Worker 	spin_lock_init(&dev->queue_lock);
168*49cdfc7eSAndroid Build Coastguard Worker 
169*49cdfc7eSAndroid Build Coastguard Worker 	gd_ptr = alloc_disk(1);
170*49cdfc7eSAndroid Build Coastguard Worker 	if (!gd_ptr) {
171*49cdfc7eSAndroid Build Coastguard Worker 		unregister_blkdev(NLSMAJOR, DEVICE_NAME);
172*49cdfc7eSAndroid Build Coastguard Worker 		kfree(dev);
173*49cdfc7eSAndroid Build Coastguard Worker 		return -ENOMEM;
174*49cdfc7eSAndroid Build Coastguard Worker 	}
175*49cdfc7eSAndroid Build Coastguard Worker 
176*49cdfc7eSAndroid Build Coastguard Worker 	printk(KERN_ALERT "gd_ptr after alloc=%p\n", gd_ptr);
177*49cdfc7eSAndroid Build Coastguard Worker 
178*49cdfc7eSAndroid Build Coastguard Worker 	queue = blk_init_queue(test_request, &dev->queue_lock);
179*49cdfc7eSAndroid Build Coastguard Worker 	if (!queue) {
180*49cdfc7eSAndroid Build Coastguard Worker 		del_gendisk(gd_ptr);
181*49cdfc7eSAndroid Build Coastguard Worker 		unregister_blkdev(NLSMAJOR, DEVICE_NAME);
182*49cdfc7eSAndroid Build Coastguard Worker 		kfree(dev);
183*49cdfc7eSAndroid Build Coastguard Worker 		return -ENOMEM;
184*49cdfc7eSAndroid Build Coastguard Worker 	}
185*49cdfc7eSAndroid Build Coastguard Worker 
186*49cdfc7eSAndroid Build Coastguard Worker 	gd_ptr->major = NLSMAJOR;
187*49cdfc7eSAndroid Build Coastguard Worker 	gd_ptr->first_minor = 0;
188*49cdfc7eSAndroid Build Coastguard Worker 	gd_ptr->fops = &bdops;
189*49cdfc7eSAndroid Build Coastguard Worker 	gd_ptr->queue = queue;
190*49cdfc7eSAndroid Build Coastguard Worker 	gd_ptr->private_data = dev;
191*49cdfc7eSAndroid Build Coastguard Worker 	snprintf(gd_ptr->disk_name, sizeof(gd_ptr->disk_name), DEVICE_NAME);
192*49cdfc7eSAndroid Build Coastguard Worker 	add_disk(gd_ptr);
193*49cdfc7eSAndroid Build Coastguard Worker 
194*49cdfc7eSAndroid Build Coastguard Worker 	printk(KERN_DEBUG "block device %s added\n", DEVICE_NAME);
195*49cdfc7eSAndroid Build Coastguard Worker 
196*49cdfc7eSAndroid Build Coastguard Worker 	test_nls_base();
197*49cdfc7eSAndroid Build Coastguard Worker 
198*49cdfc7eSAndroid Build Coastguard Worker 	return 0;
199*49cdfc7eSAndroid Build Coastguard Worker }
200*49cdfc7eSAndroid Build Coastguard Worker 
test_exit_module(void)201*49cdfc7eSAndroid Build Coastguard Worker static void test_exit_module(void)
202*49cdfc7eSAndroid Build Coastguard Worker {
203*49cdfc7eSAndroid Build Coastguard Worker 	printk(KERN_DEBUG "unloading module\n");
204*49cdfc7eSAndroid Build Coastguard Worker 
205*49cdfc7eSAndroid Build Coastguard Worker 	del_gendisk(gd_ptr);
206*49cdfc7eSAndroid Build Coastguard Worker 	unregister_blkdev(NLSMAJOR, DEVICE_NAME);
207*49cdfc7eSAndroid Build Coastguard Worker }
208*49cdfc7eSAndroid Build Coastguard Worker 
test_nls_base(void)209*49cdfc7eSAndroid Build Coastguard Worker static void test_nls_base(void)
210*49cdfc7eSAndroid Build Coastguard Worker {
211*49cdfc7eSAndroid Build Coastguard Worker 	wchar_t p = 0x20;
212*49cdfc7eSAndroid Build Coastguard Worker 	__u8 s = 0x01;
213*49cdfc7eSAndroid Build Coastguard Worker 	int n = 2;
214*49cdfc7eSAndroid Build Coastguard Worker 	struct nls_table nls;
215*49cdfc7eSAndroid Build Coastguard Worker 	struct nls_table *nls_ptr;
216*49cdfc7eSAndroid Build Coastguard Worker 	int ret;
217*49cdfc7eSAndroid Build Coastguard Worker 	char charset[20] = "David";
218*49cdfc7eSAndroid Build Coastguard Worker 
219*49cdfc7eSAndroid Build Coastguard Worker 	memset(&nls, 0, sizeof(nls));
220*49cdfc7eSAndroid Build Coastguard Worker 
221*49cdfc7eSAndroid Build Coastguard Worker 	printk(KERN_DEBUG "Calling load_nls_default()\n");
222*49cdfc7eSAndroid Build Coastguard Worker 	nls_ptr = load_nls_default();
223*49cdfc7eSAndroid Build Coastguard Worker 	printk(KERN_DEBUG "load_nls_default() returns %p\n", nls_ptr);
224*49cdfc7eSAndroid Build Coastguard Worker 
225*49cdfc7eSAndroid Build Coastguard Worker 	printk(KERN_DEBUG "Calling register_nls(%p)\n", &nls);
226*49cdfc7eSAndroid Build Coastguard Worker 	ret = register_nls(&nls);
227*49cdfc7eSAndroid Build Coastguard Worker 	printk(KERN_DEBUG "register_nls() returns %i\n", ret);
228*49cdfc7eSAndroid Build Coastguard Worker 
229*49cdfc7eSAndroid Build Coastguard Worker 	printk(KERN_DEBUG "Calling unload_nls(%p)\n", &nls);
230*49cdfc7eSAndroid Build Coastguard Worker 	unload_nls(&nls);
231*49cdfc7eSAndroid Build Coastguard Worker 
232*49cdfc7eSAndroid Build Coastguard Worker 	printk(KERN_DEBUG "Calling load_nls(\"%s\")\n", charset);
233*49cdfc7eSAndroid Build Coastguard Worker 	nls_ptr = load_nls(charset);
234*49cdfc7eSAndroid Build Coastguard Worker 	printk(KERN_DEBUG "load_nls() returns %p\n", nls_ptr);
235*49cdfc7eSAndroid Build Coastguard Worker 
236*49cdfc7eSAndroid Build Coastguard Worker 	printk(KERN_DEBUG "Calling unregister_nls(%p)\n", &nls);
237*49cdfc7eSAndroid Build Coastguard Worker 	unregister_nls(&nls);
238*49cdfc7eSAndroid Build Coastguard Worker 
239*49cdfc7eSAndroid Build Coastguard Worker 	printk(KERN_DEBUG "Calling utf8_mbtowc(%p, %p, %i);\n", &p, &s, n);
240*49cdfc7eSAndroid Build Coastguard Worker 	ret = utf8_mbtowc(&p, &s, n);
241*49cdfc7eSAndroid Build Coastguard Worker 	printk(KERN_DEBUG "utf8_mbtowc() returns %i\n", ret);
242*49cdfc7eSAndroid Build Coastguard Worker 
243*49cdfc7eSAndroid Build Coastguard Worker 	printk(KERN_DEBUG "Calling utf8_mbstowcs(%p, %p, %i);\n", &p, &s, n);
244*49cdfc7eSAndroid Build Coastguard Worker 	ret = utf8_mbstowcs(&p, &s, n);
245*49cdfc7eSAndroid Build Coastguard Worker 	printk(KERN_DEBUG "utf8_mbstowcs() returns %i\n", ret);
246*49cdfc7eSAndroid Build Coastguard Worker 
247*49cdfc7eSAndroid Build Coastguard Worker 	n = 20;
248*49cdfc7eSAndroid Build Coastguard Worker 
249*49cdfc7eSAndroid Build Coastguard Worker 	printk(KERN_DEBUG "Calling utf8_wctomb(%p, 0x%X, %i);\n", &s, p, n);
250*49cdfc7eSAndroid Build Coastguard Worker 	ret = utf8_wctomb(&s, p, n);
251*49cdfc7eSAndroid Build Coastguard Worker 	printk(KERN_DEBUG "utf8_wctomb() returns %i\n", ret);
252*49cdfc7eSAndroid Build Coastguard Worker 
253*49cdfc7eSAndroid Build Coastguard Worker 	printk(KERN_DEBUG "Calling utf8_wcstombs(%p, %p, %i);\n", &s, &p, n);
254*49cdfc7eSAndroid Build Coastguard Worker 	ret = utf8_wcstombs(&s, &p, n);
255*49cdfc7eSAndroid Build Coastguard Worker 	printk(KERN_DEBUG "utf8_wcstombs() returns %i\n", ret);
256*49cdfc7eSAndroid Build Coastguard Worker 
257*49cdfc7eSAndroid Build Coastguard Worker }
258*49cdfc7eSAndroid Build Coastguard Worker 
259*49cdfc7eSAndroid Build Coastguard Worker module_init(test_init_module);
260*49cdfc7eSAndroid Build Coastguard Worker module_exit(test_exit_module);
261