After upgrading to Ubuntu 13.10, I need to compile a device driver for this newer kernel. The call makeleads to 2 errors:
error: implicit declaration of function ‘kzalloc’
error: implicit declaration of function ‘kfree’
The same command makeworks fine in Ubuntu 13.04, but now it does not work. I also checked the existence
KDIR := /lib/modules/$(shell uname -r)/build
which is used in the Makefile, and in the analysis becomes /lib/modules/3.11.0-18-generic/build. The makefile seems pretty standard compared to this module compiler .
What did I miss by going to 13.10? Are additional packages needed? The build-essentials package is installed. Something changed at 13.10?
error message for make:
user1@pc:/etc/opt/elo-mt-usb/elo_mt_input_mod_src$ sudo make
make -C /lib/modules/3.11.0-18-generic/build SUBDIRS=/etc/opt/elo-mt-usb/elo_mt_input_mod_src modules
make[1]: Betrete Verzeichnis '/usr/src/linux-headers-3.11.0-18-generic'
CC [M] /etc/opt/elo-mt-usb/elo_mt_input_mod_src/elo_mt_input.o
/etc/opt/elo-mt-usb/elo_mt_input_mod_src/elo_mt_input.c: In function ‘elo_input_write’:
/etc/opt/elo-mt-usb/elo_mt_input_mod_src/elo_mt_input.c:79:2: error: implicit declaration of function ‘kzalloc’ [-Werror=implicit-function-declaration]
if(!(buffer = kzalloc(count, GFP_KERNEL)))
^
/etc/opt/elo-mt-usb/elo_mt_input_mod_src/elo_mt_input.c:79:14: warning: assignment makes pointer from integer without a cast [enabled by default]
if(!(buffer = kzalloc(count, GFP_KERNEL)))
^
/etc/opt/elo-mt-usb/elo_mt_input_mod_src/elo_mt_input.c:148:3: error: implicit declaration of function ‘kfree’ [-Werror=implicit-function-declaration]
kfree(buffer);
^
cc1: some warnings being treated as errors
make[2]: *** [/etc/opt/elo-mt-usb/elo_mt_input_mod_src/elo_mt_input.o] Fehler 1
make[1]: *** [_module_/etc/opt/elo-mt-usb/elo_mt_input_mod_src] Fehler 2
make[1]: Verlasse Verzeichnis '/usr/src/linux-headers-3.11.0-18-generic'
make: *** [default] Fehler 2
Makefile contains:
obj-m := elo_mt_input_mod.o
elo_mt_input_mod-objs := elo_mt_input.o
KDIR := /lib/modules/$(shell uname -r)/build
PWD := $(shell pwd)
default:
$(MAKE) -C $(KDIR) SUBDIRS=$(PWD) modules
install:
cp ./elo_mt_input_mod.ko ../elo_mt_input_mod_`uname -r`.ko
clean:
rm -f *.o *.cmd *.mod.c .*.o* .*.ko* *~ *.ko Module.markers modules.order Module.symvers
rm -rf .tmp_versions/
, GPL. elo_mt_input.c, , :
#include <linux/module.h>
#include <linux/proc_fs.h>
#include <asm/uaccess.h>
#include <linux/version.h>
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
#include <linux/input/mt.h>
#else
#include <linux/input.h>
#endif
#define DRIVER_VERSION "1.0.0"
#define DRIVER_AUTHOR "Elo Touch Solutions Inc"
#define DRIVER_DESC "Linux input module for Elo MultiTouch(MT) devices"
#define DRIVER_LICENSE "GPL"
MODULE_VERSION(DRIVER_VERSION);
MODULE_AUTHOR(DRIVER_AUTHOR);
MODULE_DESCRIPTION(DRIVER_DESC);
MODULE_LICENSE(DRIVER_LICENSE);
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
#define _MULTITOUCH_KERNEL_
#else
#undef _MULTITOUCH_KERNEL_
#endif
#ifdef _MULTITOUCH_KERNEL_
#define ELO_MT_MAXCONTACTS 2
#endif
#define MIN_X (0)
#define MAX_X (4095)
#define MIN_Y (0)
#define MAX_Y (4095)
#define MIN_PRESSURE (0)
#define MAX_PRESSURE (1)
struct touch_event {
u16 touch_count;
u16 touch_index;
u16 contact_id;
u16 touch_status;
u16 x;
u16 y;
};
struct input_dev *elo_input_device = NULL;
struct proc_dir_entry *proc_entry = NULL;
static ssize_t elo_input_read(struct file *file, char __user *buf, size_t count, loff_t *ppos)
{
return 0;
}
static ssize_t elo_input_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos)
{
int rc = -1;
const u8 *ptr = NULL;
u8 *buffer = NULL;
size_t size = count;
struct touch_event *event = NULL;
if(!(buffer = kzalloc(count, GFP_KERNEL)))
{
printk(KERN_ERR "elo_mt_input: Unable to allocate memory\n");
rc = -ENOMEM;
goto done;
}
if(copy_from_user(buffer, buf, count))
{
printk(KERN_ERR "elo_mt_input: Unable to copy data\n");
rc = -EFAULT;
goto done;
}
ptr = buffer;
while(size >= sizeof(*event))
{
event = (struct touch_event *)ptr;
#ifdef _MULTITOUCH_KERNEL_
input_mt_slot(elo_input_device, event->contact_id);
input_mt_report_slot_state(elo_input_device, MT_TOOL_FINGER, event->touch_status);
if(event->touch_status)
{
input_event(elo_input_device, EV_ABS, ABS_MT_POSITION_X, event->x);
input_event(elo_input_device, EV_ABS, ABS_MT_POSITION_Y, event->y);
input_event(elo_input_device, EV_ABS, ABS_MT_PRESSURE, event->touch_status);
}
input_mt_report_pointer_emulation(elo_input_device, true);
if(event->touch_count == (event->touch_index + 1))
{
input_sync(elo_input_device);
}
#else
if(event->touch_index == 0)
{
if(event->touch_status)
{
input_event(elo_input_device, EV_ABS, ABS_X, event->x);
input_event(elo_input_device, EV_ABS, ABS_Y, event->y);
input_event(elo_input_device, EV_KEY, BTN_LEFT, event->touch_status);
}
else
{
input_event(elo_input_device, EV_ABS, ABS_X, event->x);
input_event(elo_input_device, EV_ABS, ABS_Y, event->y);
input_event(elo_input_device, EV_KEY, BTN_LEFT, 0);
}
input_sync(elo_input_device);
}
#endif
ptr += sizeof(*event);
size -= sizeof(*event);
}
rc = count;
done:
if(buffer)
kfree(buffer);
*ppos += count;
return rc;
}
static const struct file_operations elo_input_fops = {
.read = elo_input_read,
.write = elo_input_write
};
static int __init elo_input_init(void)
{
int rc = 0;
if(!(elo_input_device = input_allocate_device()))
{
printk(KERN_ERR "elo_mt_input: Unable to create input_dev\n");
rc = -EBUSY;
goto done;
}
set_bit(EV_ABS, elo_input_device->evbit);
#ifdef _MULTITOUCH_KERNEL_
set_bit(INPUT_PROP_DIRECT, elo_input_device->propbit);
input_set_capability(elo_input_device, EV_KEY, BTN_TOUCH);
elo_input_device->name = "Elo MultiTouch(MT) Device Input Module";
#else
input_set_capability(elo_input_device, EV_KEY, BTN_LEFT);
elo_input_device->name = "Elo Single Touch Device Input Module";
#endif
input_set_abs_params(elo_input_device, ABS_X, MIN_X, MAX_X, 0, 0);
input_set_abs_params(elo_input_device, ABS_Y, MIN_Y, MAX_Y, 0, 0);
#ifdef _MULTITOUCH_KERNEL_
input_set_abs_params(elo_input_device, ABS_MT_POSITION_X, MIN_X, MAX_X, 0, 0);
input_set_abs_params(elo_input_device, ABS_MT_POSITION_Y, MIN_Y, MAX_Y, 0, 0);
input_set_abs_params(elo_input_device, ABS_MT_PRESSURE, MIN_PRESSURE, MAX_PRESSURE, 0, 0);
input_set_abs_params(elo_input_device, ABS_PRESSURE, MIN_PRESSURE, MAX_PRESSURE, 0, 0);
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,7,0))
input_mt_init_slots(elo_input_device, ELO_MT_MAXCONTACTS, INPUT_MT_DIRECT);
#else
input_mt_init_slots(elo_input_device, ELO_MT_MAXCONTACTS);
#endif
#endif
if((rc = input_register_device(elo_input_device)))
{
printk(KERN_ERR "elo_mt_input: Unable to register input_dev\n");
goto done;
}
proc_entry = proc_create("elo_mt_input", S_IWUSR | S_IRUSR, NULL, &elo_input_fops);
if(proc_entry == NULL)
{
printk(KERN_ERR "elo_mt_input: Failed to create /proc/elo_mt_input\n");
input_unregister_device(elo_input_device);
rc = -EBUSY;
goto done;
}
printk(KERN_INFO "elo_mt_input: Input device registered\n");
done:
return rc;
}
static void __exit elo_input_exit(void)
{
remove_proc_entry("elo_mt_input", NULL);
input_unregister_device(elo_input_device);
}
module_init(elo_input_init);
module_exit(elo_input_exit);