Home | History | Annotate | Download | only in nls
      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 (at) us.ibm.com>");
     52 MODULE_AUTHOR("Mrton Nmeth <nm127 (at) 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)
     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)
     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)
    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 
    135 static void option1(void)
    136 {
    137 	printk(KERN_DEBUG "Module option 1 chosen\n");
    138 }
    139 
    140 static void test_request(struct request_queue *q)
    141 {
    142 	printk(KERN_DEBUG "test_request() called\n");
    143 };
    144 
    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 
    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 
    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