diff -c -r ./scull/access.c ../../ldd3-samples-1.0.0//scull/access.c *** ./scull/access.c 2005-01-31 22:31:01.000000000 +0200 --- ../../ldd3-samples-1.0.0//scull/access.c 2012-01-07 22:12:05.000000000 +0200 *************** *** 24,29 **** --- 24,30 ---- #include /* error codes */ #include /* size_t */ #include + #include #include #include #include *************** *** 80,86 **** --- 81,91 ---- .llseek = scull_llseek, .read = scull_read, .write = scull_write, + #ifdef HAVE_UNLOCKED_IOCTL + .unlocked_ioctl = scull_ioctl, + #else .ioctl = scull_ioctl, + #endif .open = scull_s_open, .release = scull_s_release, }; *************** *** 95,101 **** static struct scull_dev scull_u_device; static int scull_u_count; /* initialized to 0 by default */ static uid_t scull_u_owner; /* initialized to 0 by default */ ! static spinlock_t scull_u_lock = SPIN_LOCK_UNLOCKED; static int scull_u_open(struct inode *inode, struct file *filp) { --- 100,107 ---- static struct scull_dev scull_u_device; static int scull_u_count; /* initialized to 0 by default */ static uid_t scull_u_owner; /* initialized to 0 by default */ ! /*static spinlock_t scull_u_lock = SPIN_LOCK_UNLOCKED;*/ ! static DEFINE_SPINLOCK(scull_u_lock); static int scull_u_open(struct inode *inode, struct file *filp) { *************** *** 103,117 **** spin_lock(&scull_u_lock); if (scull_u_count && ! (scull_u_owner != current->uid) && /* allow user */ ! (scull_u_owner != current->euid) && /* allow whoever did su */ !capable(CAP_DAC_OVERRIDE)) { /* still allow root */ spin_unlock(&scull_u_lock); return -EBUSY; /* -EPERM would confuse the user */ } if (scull_u_count == 0) ! scull_u_owner = current->uid; /* grab it */ scull_u_count++; spin_unlock(&scull_u_lock); --- 109,123 ---- spin_lock(&scull_u_lock); if (scull_u_count && ! (scull_u_owner != current->cred->uid) && /* allow user */ ! (scull_u_owner != current->cred->euid) && /* allow whoever did su */ !capable(CAP_DAC_OVERRIDE)) { /* still allow root */ spin_unlock(&scull_u_lock); return -EBUSY; /* -EPERM would confuse the user */ } if (scull_u_count == 0) ! scull_u_owner = current->cred->uid; /* grab it */ scull_u_count++; spin_unlock(&scull_u_lock); *************** *** 142,148 **** .llseek = scull_llseek, .read = scull_read, .write = scull_write, ! .ioctl = scull_ioctl, .open = scull_u_open, .release = scull_u_release, }; --- 148,158 ---- .llseek = scull_llseek, .read = scull_read, .write = scull_write, ! #ifdef HAVE_UNLOCKED_IOCTL ! .unlocked_ioctl = scull_ioctl, ! #else ! .ioctl = scull_ioctl, ! #endif .open = scull_u_open, .release = scull_u_release, }; *************** *** 157,169 **** static int scull_w_count; /* initialized to 0 by default */ static uid_t scull_w_owner; /* initialized to 0 by default */ static DECLARE_WAIT_QUEUE_HEAD(scull_w_wait); ! static spinlock_t scull_w_lock = SPIN_LOCK_UNLOCKED; static inline int scull_w_available(void) { return scull_w_count == 0 || ! scull_w_owner == current->uid || ! scull_w_owner == current->euid || capable(CAP_DAC_OVERRIDE); } --- 167,181 ---- static int scull_w_count; /* initialized to 0 by default */ static uid_t scull_w_owner; /* initialized to 0 by default */ static DECLARE_WAIT_QUEUE_HEAD(scull_w_wait); ! /*static spinlock_t scull_w_lock = SPIN_LOCK_UNLOCKED;*/ ! static DEFINE_SPINLOCK(scull_w_lock); ! static inline int scull_w_available(void) { return scull_w_count == 0 || ! scull_w_owner == current->cred->uid || ! scull_w_owner == current->cred->euid || capable(CAP_DAC_OVERRIDE); } *************** *** 181,187 **** spin_lock(&scull_w_lock); } if (scull_w_count == 0) ! scull_w_owner = current->uid; /* grab it */ scull_w_count++; spin_unlock(&scull_w_lock); --- 193,199 ---- spin_lock(&scull_w_lock); } if (scull_w_count == 0) ! scull_w_owner = current->cred->uid; /* grab it */ scull_w_count++; spin_unlock(&scull_w_lock); *************** *** 215,221 **** --- 227,237 ---- .llseek = scull_llseek, .read = scull_read, .write = scull_write, + #ifdef HAVE_UNLOCKED_IOCTL + .unlocked_ioctl = scull_ioctl, + #else .ioctl = scull_ioctl, + #endif .open = scull_w_open, .release = scull_w_release, }; *************** *** 237,243 **** /* The list of devices, and a lock to protect it */ static LIST_HEAD(scull_c_list); ! static spinlock_t scull_c_lock = SPIN_LOCK_UNLOCKED; /* A placeholder scull_dev which really just holds the cdev stuff. */ static struct scull_dev scull_c_device; --- 253,260 ---- /* The list of devices, and a lock to protect it */ static LIST_HEAD(scull_c_list); ! /*static spinlock_t scull_c_lock = SPIN_LOCK_UNLOCKED;*/ ! static DEFINE_SPINLOCK(scull_c_lock); /* A placeholder scull_dev which really just holds the cdev stuff. */ static struct scull_dev scull_c_device; *************** *** 314,320 **** .llseek = scull_llseek, .read = scull_read, .write = scull_write, ! .ioctl = scull_ioctl, .open = scull_c_open, .release = scull_c_release, }; --- 331,341 ---- .llseek = scull_llseek, .read = scull_read, .write = scull_write, ! #ifdef HAVE_UNLOCKED_IOCTL ! .unlocked_ioctl = scull_ioctl, ! #else ! .ioctl = scull_ioctl, ! #endif .open = scull_c_open, .release = scull_c_release, }; diff -c -r ./scull/main.c ../../ldd3-samples-1.0.0//scull/main.c *** ./scull/main.c 2005-01-31 22:31:01.000000000 +0200 --- ../../ldd3-samples-1.0.0//scull/main.c 2012-01-07 21:58:43.000000000 +0200 *************** *** 14,20 **** * */ ! #include #include #include #include --- 14,20 ---- * */ ! /*#include */ #include #include #include *************** *** 26,31 **** --- 26,32 ---- #include /* size_t */ #include #include /* O_ACCMODE */ + #include #include #include *************** *** 390,397 **** --- 391,402 ---- * The ioctl() implementation */ + #ifdef HAVE_UNLOCKED_IOCTL + long scull_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) + #else int scull_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg) + #endif { int err = 0, tmp; *************** *** 553,559 **** .llseek = scull_llseek, .read = scull_read, .write = scull_write, ! .ioctl = scull_ioctl, .open = scull_open, .release = scull_release, }; --- 558,568 ---- .llseek = scull_llseek, .read = scull_read, .write = scull_write, ! #ifdef HAVE_UNLOCKED_IOCTL ! .unlocked_ioctl = scull_ioctl, ! #else ! .ioctl = scull_ioctl, ! #endif .open = scull_open, .release = scull_release, }; diff -c -r ./scull/Makefile ../../ldd3-samples-1.0.0//scull/Makefile *** ./scull/Makefile 2005-01-31 22:31:01.000000000 +0200 --- ../../ldd3-samples-1.0.0//scull/Makefile 2012-01-07 21:58:43.000000000 +0200 *************** *** 2,16 **** #DEBUG = y ! # Add your debugging flag (or not) to CFLAGS ifeq ($(DEBUG),y) DEBFLAGS = -O -g -DSCULL_DEBUG # "-O" is needed to expand inlines else DEBFLAGS = -O2 endif ! CFLAGS += $(DEBFLAGS) ! CFLAGS += -I$(LDDINC) ifneq ($(KERNELRELEASE),) # call from kernel build system --- 2,16 ---- #DEBUG = y ! # Add your debugging flag (or not) to EXTRA_CFLAGS ifeq ($(DEBUG),y) DEBFLAGS = -O -g -DSCULL_DEBUG # "-O" is needed to expand inlines else DEBFLAGS = -O2 endif ! EXTRA_CFLAGS += $(DEBFLAGS) ! EXTRA_CFLAGS += -I$(LDDINC) ifneq ($(KERNELRELEASE),) # call from kernel build system *************** *** 35,41 **** rm -rf *.o *~ core .depend .*.cmd *.ko *.mod.c .tmp_versions depend .depend dep: ! $(CC) $(CFLAGS) -M *.c > .depend ifeq (.depend,$(wildcard .depend)) --- 35,41 ---- rm -rf *.o *~ core .depend .*.cmd *.ko *.mod.c .tmp_versions depend .depend dep: ! $(CC) $(EXTRA_CFLAGS) -M *.c > .depend ifeq (.depend,$(wildcard .depend)) diff -c -r ./scull/pipe.c ../../ldd3-samples-1.0.0//scull/pipe.c *** ./scull/pipe.c 2005-01-31 22:31:01.000000000 +0200 --- ../../ldd3-samples-1.0.0//scull/pipe.c 2012-01-07 21:58:43.000000000 +0200 *************** *** 24,29 **** --- 24,30 ---- #include /* error codes */ #include /* size_t */ #include + #include #include #include #include *************** *** 316,322 **** .read = scull_p_read, .write = scull_p_write, .poll = scull_p_poll, ! .ioctl = scull_ioctl, .open = scull_p_open, .release = scull_p_release, .fasync = scull_p_fasync, --- 317,327 ---- .read = scull_p_read, .write = scull_p_write, .poll = scull_p_poll, ! #ifdef HAVE_UNLOCKED_IOCTL ! .unlocked_ioctl = scull_ioctl, ! #else ! .ioctl = scull_ioctl, ! #endif .open = scull_p_open, .release = scull_p_release, .fasync = scull_p_fasync, diff -c -r ./scull/scull.h ../../ldd3-samples-1.0.0//scull/scull.h *** ./scull/scull.h 2005-01-31 22:31:01.000000000 +0200 --- ../../ldd3-samples-1.0.0//scull/scull.h 2012-01-07 22:04:48.000000000 +0200 *************** *** 19,24 **** --- 19,25 ---- #define _SCULL_H_ #include /* needed for the _IOW etc stuff used later */ + #include /* * Macros to help debugging *************** *** 128,135 **** --- 129,140 ---- ssize_t scull_write(struct file *filp, const char __user *buf, size_t count, loff_t *f_pos); loff_t scull_llseek(struct file *filp, loff_t off, int whence); + #ifdef HAVE_UNLOCKED_IOCTL + long scull_ioctl(struct file *filp, unsigned int cmd, unsigned long arg); + #else int scull_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg); + #endif /* *************** *** 173,177 **** /* ... more to come */ #define SCULL_IOC_MAXNR 14 ! #endif /* _SCULL_H_ */ --- 178,182 ---- /* ... more to come */ #define SCULL_IOC_MAXNR 14 ! #define init_MUTEX(a) sema_init(a,1) #endif /* _SCULL_H_ */ diff -c -r ./scull/scull_load ../../ldd3-samples-1.0.0//scull/scull_load *** ./scull/scull_load 2005-01-31 22:31:01.000000000 +0200 --- ../../ldd3-samples-1.0.0//scull/scull_load 2012-01-07 21:58:43.000000000 +0200 *************** *** 16,22 **** /sbin/insmod ./$module.ko $* || exit 1 # retrieve major number ! major=$(awk "\\$2==\"$module\" {print \\$1}" /proc/devices) # Remove stale nodes and replace them, then give gid and perms # Usually the script is shorter, it's scull that has several devices in it. --- 16,22 ---- /sbin/insmod ./$module.ko $* || exit 1 # retrieve major number ! major=$(awk "\$2==\"$module\" {print \$1}" /proc/devices) # Remove stale nodes and replace them, then give gid and perms # Usually the script is shorter, it's scull that has several devices in it. diff -c -r ./scullc/main.c ../../ldd3-samples-1.0.0//scullc/main.c *** ./scullc/main.c 2005-01-31 22:31:02.000000000 +0200 --- ../../ldd3-samples-1.0.0//scullc/main.c 2012-01-07 21:58:43.000000000 +0200 *************** *** 15,21 **** * $Id: _main.c.in,v 1.21 2004/10/14 20:11:39 corbet Exp $ */ ! #include #include #include #include --- 15,21 ---- * $Id: _main.c.in,v 1.21 2004/10/14 20:11:39 corbet Exp $ */ ! /*#include */ #include #include #include *************** *** 26,32 **** --- 26,34 ---- #include /* size_t */ #include #include /* O_ACCMODE */ + #include #include + #include #include #include "scullc.h" /* local definitions */ *************** *** 49,55 **** void scullc_cleanup(void); /* declare one cache pointer: use it for all devices */ ! kmem_cache_t *scullc_cache; --- 51,57 ---- void scullc_cleanup(void); /* declare one cache pointer: use it for all devices */ ! struct kmem_cache *scullc_cache; *************** *** 272,278 **** --- 274,284 ---- * The ioctl() implementation */ + #ifdef HAVE_UNLOCKED_IOCTL + long scullc_ioctl (struct file *filp, + #else int scullc_ioctl (struct inode *inode, struct file *filp, + #endif unsigned int cmd, unsigned long arg) { *************** *** 401,431 **** struct async_work { struct kiocb *iocb; int result; ! struct work_struct work; }; /* * "Complete" an asynchronous operation. */ ! static void scullc_do_deferred_op(void *p) { ! struct async_work *stuff = (struct async_work *) p; aio_complete(stuff->iocb, stuff->result, 0); kfree(stuff); } ! static int scullc_defer_op(int write, struct kiocb *iocb, char __user *buf, ! size_t count, loff_t pos) { struct async_work *stuff; int result; /* Copy now while we can access the buffer */ if (write) ! result = scullc_write(iocb->ki_filp, buf, count, &pos); else ! result = scullc_read(iocb->ki_filp, buf, count, &pos); /* If this is a synchronous IOCB, we return our status now. */ if (is_sync_kiocb(iocb)) --- 407,446 ---- struct async_work { struct kiocb *iocb; int result; ! struct delayed_work work; }; /* * "Complete" an asynchronous operation. */ ! static void scullc_do_deferred_op(struct work_struct *p) { ! struct delayed_work *dwork ; /* = (struct async_work *) p;*/ ! struct async_work *stuff ; /* = (struct async_work *) p;*/ ! dwork = container_of(p, struct delayed_work, work); ! stuff = container_of(dwork, struct async_work, work); aio_complete(stuff->iocb, stuff->result, 0); kfree(stuff); } ! static int scullc_defer_op(int write, struct kiocb *iocb, ! const struct iovec *iov, unsigned long count, loff_t pos) { struct async_work *stuff; int result; + while (count > 0) { + /* Copy now while we can access the buffer */ if (write) ! result = scullc_write(iocb->ki_filp, iov->iov_base, ! iov->iov_len , &pos); else ! result = scullc_read(iocb->ki_filp, iov->iov_base, ! iov->iov_len, &pos); ! count--; ! } /* If this is a synchronous IOCB, we return our status now. */ if (is_sync_kiocb(iocb)) *************** *** 437,458 **** return result; /* No memory, just complete now */ stuff->iocb = iocb; stuff->result = result; ! INIT_WORK(&stuff->work, scullc_do_deferred_op, stuff); ! schedule_delayed_work(&stuff->work, HZ/100); return -EIOCBQUEUED; } ! static ssize_t scullc_aio_read(struct kiocb *iocb, char __user *buf, size_t count, ! loff_t pos) { ! return scullc_defer_op(0, iocb, buf, count, pos); } ! static ssize_t scullc_aio_write(struct kiocb *iocb, const char __user *buf, ! size_t count, loff_t pos) { ! return scullc_defer_op(1, iocb, (char __user *) buf, count, pos); } --- 452,473 ---- return result; /* No memory, just complete now */ stuff->iocb = iocb; stuff->result = result; ! INIT_DELAYED_WORK(&(stuff->work), scullc_do_deferred_op); ! schedule_delayed_work(&(stuff->work), HZ/100); return -EIOCBQUEUED; } ! static ssize_t scullc_aio_read(struct kiocb *iocb, const struct iovec *iov, ! unsigned long count, loff_t pos) { ! return scullc_defer_op(0, iocb, iov, count, pos); } ! static ssize_t scullc_aio_write(struct kiocb *iocb, const struct iovec *iov, ! unsigned long count, loff_t pos) { ! return scullc_defer_op(1, iocb, iov, count, pos); } *************** *** 467,473 **** --- 482,492 ---- .llseek = scullc_llseek, .read = scullc_read, .write = scullc_write, + #ifdef HAVE_UNLOCKED_IOCTL + .unlocked_ioctl = scullc_ioctl, + #else .ioctl = scullc_ioctl, + #endif .open = scullc_open, .release = scullc_release, .aio_read = scullc_aio_read, *************** *** 558,564 **** } scullc_cache = kmem_cache_create("scullc", scullc_quantum, ! 0, SLAB_HWCACHE_ALIGN, NULL, NULL); /* no ctor/dtor */ if (!scullc_cache) { scullc_cleanup(); return -ENOMEM; --- 577,583 ---- } scullc_cache = kmem_cache_create("scullc", scullc_quantum, ! 0, SLAB_HWCACHE_ALIGN, NULL); /*, NULL); no ctor/dtor */ if (!scullc_cache) { scullc_cleanup(); return -ENOMEM; diff -c -r ./scullc/Makefile ../../ldd3-samples-1.0.0//scullc/Makefile *** ./scullc/Makefile 2005-01-31 22:31:01.000000000 +0200 --- ../../ldd3-samples-1.0.0//scullc/Makefile 2012-01-07 21:58:43.000000000 +0200 *************** *** 9,15 **** DEBFLAGS = -O2 endif ! CFLAGS += $(DEBFLAGS) -I$(LDDINC) TARGET = scullc --- 9,15 ---- DEBFLAGS = -O2 endif ! EXTRA_CFLAGS += $(DEBFLAGS) -I$(LDDINC) TARGET = scullc *************** *** 39,45 **** depend .depend dep: ! $(CC) $(CFLAGS) -M *.c > .depend ifeq (.depend,$(wildcard .depend)) include .depend --- 39,45 ---- depend .depend dep: ! $(CC) $(EXTRA_CFLAGS) -M *.c > .depend ifeq (.depend,$(wildcard .depend)) include .depend diff -c -r ./scullc/scullc_load ../../ldd3-samples-1.0.0//scullc/scullc_load *** ./scullc/scullc_load 2005-01-31 22:31:02.000000000 +0200 --- ../../ldd3-samples-1.0.0//scullc/scullc_load 2012-01-07 21:58:43.000000000 +0200 *************** *** 17,23 **** # and use a pathname, as newer modutils don't look in . by default /sbin/insmod -f ./$module.ko $* || exit 1 ! major=`cat /proc/devices | awk "\\$2==\"$module\" {print \\$1}"` mknod /dev/${device}0 c $major 0 mknod /dev/${device}1 c $major 1 --- 17,23 ---- # and use a pathname, as newer modutils don't look in . by default /sbin/insmod -f ./$module.ko $* || exit 1 ! major=`cat /proc/devices | awk "\$2==\"$module\" {print \$1}"` mknod /dev/${device}0 c $major 0 mknod /dev/${device}1 c $major 1 diff -c -r ./scullp/main.c ../../ldd3-samples-1.0.0//scullp/main.c *** ./scullp/main.c 2005-01-31 22:31:02.000000000 +0200 --- ../../ldd3-samples-1.0.0//scullp/main.c 2012-01-07 21:58:43.000000000 +0200 *************** *** 15,21 **** * $Id: _main.c.in,v 1.21 2004/10/14 20:11:39 corbet Exp $ */ ! #include #include #include #include --- 15,21 ---- * $Id: _main.c.in,v 1.21 2004/10/14 20:11:39 corbet Exp $ */ ! /*#include */ #include #include #include diff -c -r ./scullp/Makefile ../../ldd3-samples-1.0.0//scullp/Makefile *** ./scullp/Makefile 2005-01-31 22:31:02.000000000 +0200 --- ../../ldd3-samples-1.0.0//scullp/Makefile 2012-01-07 21:58:43.000000000 +0200 *************** *** 9,15 **** DEBFLAGS = -O2 endif ! CFLAGS += $(DEBFLAGS) -I$(LDDINC) TARGET = scullp --- 9,15 ---- DEBFLAGS = -O2 endif ! EXTRA_CFLAGS += $(DEBFLAGS) -I$(LDDINC) TARGET = scullp *************** *** 39,45 **** depend .depend dep: ! $(CC) $(CFLAGS) -M *.c > .depend ifeq (.depend,$(wildcard .depend)) include .depend --- 39,45 ---- depend .depend dep: ! $(CC) $(EXTRA_CFLAGS) -M *.c > .depend ifeq (.depend,$(wildcard .depend)) include .depend