From e4c5abacf1ea225cf8d4bd17a656a875083f9bf3 Mon Sep 17 00:00:00 2001
From: jserv The Linux Kernel Module Programming Guide
-
$ sudo insmod sleep.ko -$ cat_noblock /proc/sleep +$ cat_nonblock /proc/sleep Last input: $ tail -f /proc/sleep & Last input: @@ -3185,11 +3185,11 @@ Last input: Last input: tail: /proc/sleep: file truncated [1] 6540 -$ cat_noblock /proc/sleep +$ cat_nonblock /proc/sleep Open would block $ kill %1 [1]+ Terminated tail -f /proc/sleep -$ cat_noblock /proc/sleep +$ cat_nonblock /proc/sleep Last input: $@@ -3480,7 +3480,7 @@ $
1/* -2 * cat_noblock.c - open a file and display its contents, but exit rather than +2 * cat_nonblock.c - open a file and display its contents, but exit rather than 3 * wait for input. 4 */ 5#include <errno.h> /* for errno */ @@ -3497,52 +3497,47 @@ $ 16 size_t bytes; /* The number of bytes read */ 17 char buffer[MAX_BYTES]; /* The buffer for the bytes */ 18 -19 -20 /* Usage */ -21 if (argc != 2) { -22 printf("Usage: %s <filename>\n", argv[0]); -23 puts("Reads the content of a file, but doesn't wait for input"); -24 exit(-1); -25 } -26 -27 /* Open the file for reading in non blocking mode */ -28 fd = open(argv[1], O_RDONLY | O_NONBLOCK); -29 -30 /* If open failed */ -31 if (fd == -1) { -32 if (errno = EAGAIN) -33 puts("Open would block"); -34 else -35 puts("Open failed"); -36 exit(-1); -37 } -38 -39 /* Read the file and output its contents */ -40 do { -41 int i; -42 -43 /* Read characters from the file */ -44 bytes = read(fd, buffer, MAX_BYTES); -45 -46 /* If there's an error, report it and die */ -47 if (bytes == -1) { -48 if (errno = EAGAIN) -49 puts("Normally I'd block, but you told me not to"); -50 else -51 puts("Another read error"); -52 exit(-1); +19 /* Usage */ +20 if (argc != 2) { +21 printf("Usage: %s <filename>\n", argv[0]); +22 puts("Reads the content of a file, but doesn't wait for input"); +23 exit(-1); +24 } +25 +26 /* Open the file for reading in non blocking mode */ +27 fd = open(argv[1], O_RDONLY | O_NONBLOCK); +28 +29 /* If open failed */ +30 if (fd == -1) { +31 puts(errno == EAGAIN ? "Open would block" : "Open failed"); +32 exit(-1); +33 } +34 +35 /* Read the file and output its contents */ +36 do { +37 /* Read characters from the file */ +38 bytes = read(fd, buffer, MAX_BYTES); +39 +40 /* If there's an error, report it and die */ +41 if (bytes == -1) { +42 if (errno = EAGAIN) +43 puts("Normally I'd block, but you told me not to"); +44 else +45 puts("Another read error"); +46 exit(-1); +47 } +48 +49 /* Print the characters */ +50 if (bytes > 0) { +51 for (int i = 0; i < bytes; i++) +52 putchar(buffer[i]); 53 } 54 -55 /* Print the characters */ -56 if (bytes > 0) { -57 for (i = 0; i < bytes; i++) -58 putchar(buffer[i]); -59 } -60 -61 /* While there are no errors and the file isn't over */ -62 } while (bytes > 0); -63 return 0; -64}+55 /* While there are no errors and the file isn't over */ +56 } while (bytes > 0); +57 +58 return 0; +59}
1/* -2 * completions.c -3 */ -4#include <linux/completion.h> -5#include <linux/init.h> -6#include <linux/kernel.h> -7#include <linux/kthread.h> -8#include <linux/module.h> +1/* +2 * completions.c +3 */ +4#include <linux/completion.h> +5#include <linux/init.h> +6#include <linux/kernel.h> +7#include <linux/kthread.h> +8#include <linux/module.h> 9 -10static struct { -11 struct completion crank_comp; -12 struct completion flywheel_comp; +10static struct { +11 struct completion crank_comp; +12 struct completion flywheel_comp; 13} machine; 14 -15static int machine_crank_thread(void *arg) +15static int machine_crank_thread(void *arg) 16{ -17 pr_info("Turn the crank\n"); +17 pr_info("Turn the crank\n"); 18 19 complete_all(&machine.crank_comp); 20 complete_and_exit(&machine.crank_comp, 0); 21} 22 -23static int machine_flywheel_spinup_thread(void *arg) +23static int machine_flywheel_spinup_thread(void *arg) 24{ 25 wait_for_completion(&machine.crank_comp); 26 -27 pr_info("Flywheel spins up\n"); +27 pr_info("Flywheel spins up\n"); 28 29 complete_all(&machine.flywheel_comp); 30 complete_and_exit(&machine.flywheel_comp, 0); 31} 32 -33static int completions_init(void) +33static int completions_init(void) 34{ -35 struct task_struct *crank_thread; -36 struct task_struct *flywheel_thread; +35 struct task_struct *crank_thread; +36 struct task_struct *flywheel_thread; 37 -38 pr_info("completions example\n"); +38 pr_info("completions example\n"); 39 40 init_completion(&machine.crank_comp); 41 init_completion(&machine.flywheel_comp); 42 -43 crank_thread = kthread_create(machine_crank_thread, NULL, "KThread Crank"); -44 if (IS_ERR(crank_thread)) -45 goto ERROR_THREAD_1; +43 crank_thread = kthread_create(machine_crank_thread, NULL, "KThread Crank"); +44 if (IS_ERR(crank_thread)) +45 goto ERROR_THREAD_1; 46 47 flywheel_thread = kthread_create(machine_flywheel_spinup_thread, NULL, -48 "KThread Flywheel"); -49 if (IS_ERR(flywheel_thread)) -50 goto ERROR_THREAD_2; +48 "KThread Flywheel"); +49 if (IS_ERR(flywheel_thread)) +50 goto ERROR_THREAD_2; 51 52 wake_up_process(flywheel_thread); 53 wake_up_process(crank_thread); 54 -55 return 0; +55 return 0; 56 57ERROR_THREAD_2: 58 kthread_stop(crank_thread); 59ERROR_THREAD_1: 60 -61 return -1; +61 return -1; 62} 63 -64void completions_exit(void) +64void completions_exit(void) 65{ 66 wait_for_completion(&machine.crank_comp); 67 wait_for_completion(&machine.flywheel_comp); 68 -69 pr_info("completions exit\n"); +69 pr_info("completions exit\n"); 70} 71 72module_init(completions_init); 73module_exit(completions_exit); 74 -75MODULE_DESCRIPTION("Completions example"); -76MODULE_LICENSE("GPL");+75MODULE_DESCRIPTION("Completions example"); +76MODULE_LICENSE("GPL");
The machine structure stores the completion states for the two threads. At the exit point of each thread the respective completion state is updated, and wait_for_completion is used by the flywheel thread to ensure that it doesn’t begin @@ -3657,47 +3652,47 @@ might deploy them in userland. This may be all that’s needed to avoid collisio most cases.
-
1/* -2 * example_mutex.c -3 */ -4#include <linux/init.h> -5#include <linux/kernel.h> -6#include <linux/module.h> -7#include <linux/mutex.h> +1/* +2 * example_mutex.c +3 */ +4#include <linux/init.h> +5#include <linux/kernel.h> +6#include <linux/module.h> +7#include <linux/mutex.h> 8 9DEFINE_MUTEX(mymutex); 10 -11static int example_mutex_init(void) +11static int example_mutex_init(void) 12{ -13 int ret; +13 int ret; 14 -15 pr_info("example_mutex init\n"); +15 pr_info("example_mutex init\n"); 16 17 ret = mutex_trylock(&mymutex); -18 if (ret != 0) { -19 pr_info("mutex is locked\n"); +18 if (ret != 0) { +19 pr_info("mutex is locked\n"); 20 -21 if (mutex_is_locked(&mymutex) == 0) -22 pr_info("The mutex failed to lock!\n"); +21 if (mutex_is_locked(&mymutex) == 0) +22 pr_info("The mutex failed to lock!\n"); 23 24 mutex_unlock(&mymutex); -25 pr_info("mutex is unlocked\n"); -26 } else -27 pr_info("Failed to lock\n"); +25 pr_info("mutex is unlocked\n"); +26 } else +27 pr_info("Failed to lock\n"); 28 -29 return 0; +29 return 0; 30} 31 -32static void example_mutex_exit(void) +32static void example_mutex_exit(void) 33{ -34 pr_info("example_mutex exit\n"); +34 pr_info("example_mutex exit\n"); 35} 36 37module_init(example_mutex_init); 38module_exit(example_mutex_exit); 39 -40MODULE_DESCRIPTION("Mutex example"); -41MODULE_LICENSE("GPL");+40MODULE_DESCRIPTION("Mutex example"); +41MODULE_LICENSE("GPL");
-
1/* -2 * example_spinlock.c -3 */ -4#include <linux/init.h> -5#include <linux/interrupt.h> -6#include <linux/kernel.h> -7#include <linux/module.h> -8#include <linux/spinlock.h> +1/* +2 * example_spinlock.c +3 */ +4#include <linux/init.h> +5#include <linux/interrupt.h> +6#include <linux/kernel.h> +7#include <linux/module.h> +8#include <linux/spinlock.h> 9 10DEFINE_SPINLOCK(sl_static); 11spinlock_t sl_dynamic; 12 -13static void example_spinlock_static(void) +13static void example_spinlock_static(void) 14{ -15 unsigned long flags; +15 unsigned long flags; 16 17 spin_lock_irqsave(&sl_static, flags); -18 pr_info("Locked static spinlock\n"); +18 pr_info("Locked static spinlock\n"); 19 -20 /* Do something or other safely. -21 Because this uses 100% CPU time this -22 code should take no more than a few -23 milliseconds to run */ +20 /* Do something or other safely. +21 Because this uses 100% CPU time this +22 code should take no more than a few +23 milliseconds to run */ 24 25 spin_unlock_irqrestore(&sl_static, flags); -26 pr_info("Unlocked static spinlock\n"); +26 pr_info("Unlocked static spinlock\n"); 27} 28 -29static void example_spinlock_dynamic(void) +29static void example_spinlock_dynamic(void) 30{ -31 unsigned long flags; +31 unsigned long flags; 32 33 spin_lock_init(&sl_dynamic); 34 spin_lock_irqsave(&sl_dynamic, flags); -35 pr_info("Locked dynamic spinlock\n"); +35 pr_info("Locked dynamic spinlock\n"); 36 -37 /* Do something or other safely. -38 Because this uses 100% CPU time this -39 code should take no more than a few -40 milliseconds to run */ +37 /* Do something or other safely. +38 Because this uses 100% CPU time this +39 code should take no more than a few +40 milliseconds to run */ 41 42 spin_unlock_irqrestore(&sl_dynamic, flags); -43 pr_info("Unlocked dynamic spinlock\n"); +43 pr_info("Unlocked dynamic spinlock\n"); 44} 45 -46static int example_spinlock_init(void) +46static int example_spinlock_init(void) 47{ -48 pr_info("example spinlock started\n"); +48 pr_info("example spinlock started\n"); 49 50 example_spinlock_static(); 51 example_spinlock_dynamic(); 52 -53 return 0; +53 return 0; 54} 55 -56static void example_spinlock_exit(void) +56static void example_spinlock_exit(void) 57{ -58 pr_info("example spinlock exit\n"); +58 pr_info("example spinlock exit\n"); 59} 60 61module_init(example_spinlock_init); 62module_exit(example_spinlock_exit); 63 -64MODULE_DESCRIPTION("Spinlock example"); -65MODULE_LICENSE("GPL");+64MODULE_DESCRIPTION("Spinlock example"); +65MODULE_LICENSE("GPL");
-
1/* -2 * example_rwlock.c -3 */ -4#include <linux/interrupt.h> -5#include <linux/kernel.h> -6#include <linux/module.h> +1/* +2 * example_rwlock.c +3 */ +4#include <linux/interrupt.h> +5#include <linux/kernel.h> +6#include <linux/module.h> 7 8DEFINE_RWLOCK(myrwlock); 9 -10static void example_read_lock(void) +10static void example_read_lock(void) 11{ -12 unsigned long flags; +12 unsigned long flags; 13 14 read_lock_irqsave(&myrwlock, flags); -15 pr_info("Read Locked\n"); +15 pr_info("Read Locked\n"); 16 -17 /* Read from something */ +17 /* Read from something */ 18 19 read_unlock_irqrestore(&myrwlock, flags); -20 pr_info("Read Unlocked\n"); +20 pr_info("Read Unlocked\n"); 21} 22 -23static void example_write_lock(void) +23static void example_write_lock(void) 24{ -25 unsigned long flags; +25 unsigned long flags; 26 27 write_lock_irqsave(&myrwlock, flags); -28 pr_info("Write Locked\n"); +28 pr_info("Write Locked\n"); 29 -30 /* Write to something */ +30 /* Write to something */ 31 32 write_unlock_irqrestore(&myrwlock, flags); -33 pr_info("Write Unlocked\n"); +33 pr_info("Write Unlocked\n"); 34} 35 -36static int example_rwlock_init(void) +36static int example_rwlock_init(void) 37{ -38 pr_info("example_rwlock started\n"); +38 pr_info("example_rwlock started\n"); 39 40 example_read_lock(); 41 example_write_lock(); 42 -43 return 0; +43 return 0; 44} 45 -46static void example_rwlock_exit(void) +46static void example_rwlock_exit(void) 47{ -48 pr_info("example_rwlock exit\n"); +48 pr_info("example_rwlock exit\n"); 49} 50 51module_init(example_rwlock_init); 52module_exit(example_rwlock_exit); 53 -54MODULE_DESCRIPTION("Read/Write locks example"); -55MODULE_LICENSE("GPL");+54MODULE_DESCRIPTION("Read/Write locks example"); +55MODULE_LICENSE("GPL");
Of course if you know for sure that there are no functions triggered by irqs which could possibly interfere with your logic then you can use the simpler read_lock(&myrwlock) and read_unlock(&myrwlock) or the corresponding write @@ -3861,80 +3856,80 @@ and wasn’t overwritten by some other shenanigans. An example is shown below.
-
1/* -2 * example_atomic.c -3 */ -4#include <linux/interrupt.h> -5#include <linux/kernel.h> -6#include <linux/module.h> +@@ -3958,85 +3953,85 @@ a pointer to a string write function, which we use to write a string to the tty.1/* +2 * example_atomic.c +3 */ +4#include <linux/interrupt.h> +5#include <linux/kernel.h> +6#include <linux/module.h> 7 -8#define BYTE_TO_BINARY_PATTERN "%c%c%c%c%c%c%c%c" -9#define BYTE_TO_BINARY(byte) \ -10 (byte & 0x80 ? '1' : '0'), (byte & 0x40 ? '1' : '0'), \ -11 (byte & 0x20 ? '1' : '0'), (byte & 0x10 ? '1' : '0'), \ -12 (byte & 0x08 ? '1' : '0'), (byte & 0x04 ? '1' : '0'), \ -13 (byte & 0x02 ? '1' : '0'), (byte & 0x01 ? '1' : '0') +8#define BYTE_TO_BINARY_PATTERN "%c%c%c%c%c%c%c%c" +9#define BYTE_TO_BINARY(byte) \ +10 (byte & 0x80 ? '1' : '0'), (byte & 0x40 ? '1' : '0'), \ +11 (byte & 0x20 ? '1' : '0'), (byte & 0x10 ? '1' : '0'), \ +12 (byte & 0x08 ? '1' : '0'), (byte & 0x04 ? '1' : '0'), \ +13 (byte & 0x02 ? '1' : '0'), (byte & 0x01 ? '1' : '0') 14 -15static void atomic_add_subtract(void) +15static void atomic_add_subtract(void) 16{ 17 atomic_t debbie; 18 atomic_t chris = ATOMIC_INIT(50); 19 20 atomic_set(&debbie, 45); 21 -22 /* subtract one */ +22 /* subtract one */ 23 atomic_dec(&debbie); 24 25 atomic_add(7, &debbie); 26 -27 /* add one */ +27 /* add one */ 28 atomic_inc(&debbie); 29 -30 pr_info("chris: %d, debbie: %d\n", atomic_read(&chris), +30 pr_info("chris: %d, debbie: %d\n", atomic_read(&chris), 31 atomic_read(&debbie)); 32} 33 -34static void atomic_bitwise(void) +34static void atomic_bitwise(void) 35{ -36 unsigned long word = 0; +36 unsigned long word = 0; 37 -38 pr_info("Bits 0: " BYTE_TO_BINARY_PATTERN, BYTE_TO_BINARY(word)); +38 pr_info("Bits 0: " BYTE_TO_BINARY_PATTERN, BYTE_TO_BINARY(word)); 39 set_bit(3, &word); 40 set_bit(5, &word); -41 pr_info("Bits 1: " BYTE_TO_BINARY_PATTERN, BYTE_TO_BINARY(word)); +41 pr_info("Bits 1: " BYTE_TO_BINARY_PATTERN, BYTE_TO_BINARY(word)); 42 clear_bit(5, &word); -43 pr_info("Bits 2: " BYTE_TO_BINARY_PATTERN, BYTE_TO_BINARY(word)); +43 pr_info("Bits 2: " BYTE_TO_BINARY_PATTERN, BYTE_TO_BINARY(word)); 44 change_bit(3, &word); 45 -46 pr_info("Bits 3: " BYTE_TO_BINARY_PATTERN, BYTE_TO_BINARY(word)); -47 if (test_and_set_bit(3, &word)) -48 pr_info("wrong\n"); -49 pr_info("Bits 4: " BYTE_TO_BINARY_PATTERN, BYTE_TO_BINARY(word)); +46 pr_info("Bits 3: " BYTE_TO_BINARY_PATTERN, BYTE_TO_BINARY(word)); +47 if (test_and_set_bit(3, &word)) +48 pr_info("wrong\n"); +49 pr_info("Bits 4: " BYTE_TO_BINARY_PATTERN, BYTE_TO_BINARY(word)); 50 51 word = 255; -52 pr_info("Bits 5: " BYTE_TO_BINARY_PATTERN, BYTE_TO_BINARY(word)); +52 pr_info("Bits 5: " BYTE_TO_BINARY_PATTERN, BYTE_TO_BINARY(word)); 53} 54 -55static int example_atomic_init(void) +55static int example_atomic_init(void) 56{ -57 pr_info("example_atomic started\n"); +57 pr_info("example_atomic started\n"); 58 59 atomic_add_subtract(); 60 atomic_bitwise(); 61 -62 return 0; +62 return 0; 63} 64 -65static void example_atomic_exit(void) +65static void example_atomic_exit(void) 66{ -67 pr_info("example_atomic exit\n"); +67 pr_info("example_atomic exit\n"); 68} 69 70module_init(example_atomic_init); 71module_exit(example_atomic_exit); 72 -73MODULE_DESCRIPTION("Atomic operations example"); -74MODULE_LICENSE("GPL");+73MODULE_DESCRIPTION("Atomic operations example"); +74MODULE_LICENSE("GPL");
-
1/* -2 * print_string.c - Send output to the tty we're running on, regardless if it's -3 * through X11, telnet, etc. We do this by printing the string to the tty -4 * associated with the current task. -5 */ -6#include <linux/init.h> -7#include <linux/kernel.h> -8#include <linux/module.h> -9#include <linux/sched.h> /* For current */ -10#include <linux/tty.h> /* For the tty declarations */ +1/* +2 * print_string.c - Send output to the tty we're running on, regardless if it's +3 * through X11, telnet, etc. We do this by printing the string to the tty +4 * associated with the current task. +5 */ +6#include <linux/init.h> +7#include <linux/kernel.h> +8#include <linux/module.h> +9#include <linux/sched.h> /* For current */ +10#include <linux/tty.h> /* For the tty declarations */ 11 -12MODULE_LICENSE("GPL"); +12MODULE_LICENSE("GPL"); 13 -14static void print_string(char *str) +14static void print_string(char *str) 15{ -16 struct tty_struct *my_tty; -17 const struct tty_operations *ttyops; +16 struct tty_struct *my_tty; +17 const struct tty_operations *ttyops; 18 -19 /* -20 * The tty for the current task, for 2.6.6+ kernels -21 */ +19 /* +20 * The tty for the current task, for 2.6.6+ kernels +21 */ 22 my_tty = get_current_tty(); 23 ttyops = my_tty->driver->ops; 24 -25 /* -26 * If my_tty is NULL, the current task has no tty you can print to -27 * (ie, if it's a daemon). If so, there's nothing we can do. -28 */ -29 if (my_tty != NULL) { -30 /* -31 * my_tty->driver is a struct which holds the tty's functions, -32 * one of which (write) is used to write strings to the tty. -33 * It can be used to take a string either from the user's or -34 * kernel's memory segment. -35 * -36 * The function's 1st parameter is the tty to write to, -37 * because the same function would normally be used for all -38 * tty's of a certain type. -39 * The 2nd parameter is a pointer to a string. -40 * The 3rd parameter is the length of the string. -41 * -42 * As you will see below, sometimes it's necessary to use -43 * preprocessor stuff to create code that works for different -44 * kernel versions. The (naive) approach we've taken here -45 * does not scale well. The right way to deal with this -46 * is described in section 2 of -47 * linux/Documentation/SubmittingPatches -48 */ -49 (ttyops->write)(my_tty, /* The tty itself */ -50 str, /* String */ -51 strlen(str)); /* Length */ +25 /* +26 * If my_tty is NULL, the current task has no tty you can print to +27 * (ie, if it's a daemon). If so, there's nothing we can do. +28 */ +29 if (my_tty != NULL) { +30 /* +31 * my_tty->driver is a struct which holds the tty's functions, +32 * one of which (write) is used to write strings to the tty. +33 * It can be used to take a string either from the user's or +34 * kernel's memory segment. +35 * +36 * The function's 1st parameter is the tty to write to, +37 * because the same function would normally be used for all +38 * tty's of a certain type. +39 * The 2nd parameter is a pointer to a string. +40 * The 3rd parameter is the length of the string. +41 * +42 * As you will see below, sometimes it's necessary to use +43 * preprocessor stuff to create code that works for different +44 * kernel versions. The (naive) approach we've taken here +45 * does not scale well. The right way to deal with this +46 * is described in section 2 of +47 * linux/Documentation/SubmittingPatches +48 */ +49 (ttyops->write)(my_tty, /* The tty itself */ +50 str, /* String */ +51 strlen(str)); /* Length */ 52 -53 /* -54 * ttys were originally hardware devices, which (usually) -55 * strictly followed the ASCII standard. In ASCII, to move to -56 * a new line you need two characters, a carriage return and a -57 * line feed. On Unix, the ASCII line feed is used for both -58 * purposes - so we can't just use \n, because it wouldn't have -59 * a carriage return and the next line will start at the -60 * column right after the line feed. -61 * -62 * This is why text files are different between Unix and -63 * MS Windows. In CP/M and derivatives, like MS-DOS and -64 * MS Windows, the ASCII standard was strictly adhered to, -65 * and therefore a newline requirs both a LF and a CR. -66 */ -67 (ttyops->write)(my_tty, "\015\012", 2); +53 /* +54 * ttys were originally hardware devices, which (usually) +55 * strictly followed the ASCII standard. In ASCII, to move to +56 * a new line you need two characters, a carriage return and a +57 * line feed. On Unix, the ASCII line feed is used for both +58 * purposes - so we can't just use \n, because it wouldn't have +59 * a carriage return and the next line will start at the +60 * column right after the line feed. +61 * +62 * This is why text files are different between Unix and +63 * MS Windows. In CP/M and derivatives, like MS-DOS and +64 * MS Windows, the ASCII standard was strictly adhered to, +65 * and therefore a newline requirs both a LF and a CR. +66 */ +67 (ttyops->write)(my_tty, "\015\012", 2); 68 } 69} 70 -71static int __init print_string_init(void) +71static int __init print_string_init(void) 72{ -73 print_string("The module has been inserted. Hello world!"); -74 return 0; +73 print_string("The module has been inserted. Hello world!"); +74 return 0; 75} 76 -77static void __exit print_string_exit(void) +77static void __exit print_string_exit(void) 78{ -79 print_string("The module has been removed. Farewell world!"); +79 print_string("The module has been removed. Farewell world!"); 80} 81 82module_init(print_string_init); @@ -4054,53 +4049,53 @@ file. loaded, starts blinking the keyboard LEDs until it is unloaded.-
1/* -2 * kbleds.c - Blink keyboard leds until the module is unloaded. -3 */ +1/* +2 * kbleds.c - Blink keyboard leds until the module is unloaded. +3 */ 4 -5#include <linux/init.h> -6#include <linux/kd.h> /* For KDSETLED */ -7#include <linux/module.h> -8#include <linux/tty.h> /* For fg_console, MAX_NR_CONSOLES */ -9#include <linux/vt.h> -10#include <linux/vt_kern.h> /* for fg_console */ +5#include <linux/init.h> +6#include <linux/kd.h> /* For KDSETLED */ +7#include <linux/module.h> +8#include <linux/tty.h> /* For fg_console, MAX_NR_CONSOLES */ +9#include <linux/vt.h> +10#include <linux/vt_kern.h> /* for fg_console */ 11 -12#include <linux/console_struct.h> /* For vc_cons */ +12#include <linux/console_struct.h> /* For vc_cons */ 13 -14MODULE_DESCRIPTION("Example module illustrating the use of Keyboard LEDs."); -15MODULE_LICENSE("GPL"); +14MODULE_DESCRIPTION("Example module illustrating the use of Keyboard LEDs."); +15MODULE_LICENSE("GPL"); 16 -17struct timer_list my_timer; -18struct tty_driver *my_driver; -19char kbledstatus = 0; +17struct timer_list my_timer; +18struct tty_driver *my_driver; +19char kbledstatus = 0; 20 -21#define BLINK_DELAY HZ / 5 -22#define ALL_LEDS_ON 0x07 -23#define RESTORE_LEDS 0xFF +21#define BLINK_DELAY HZ / 5 +22#define ALL_LEDS_ON 0x07 +23#define RESTORE_LEDS 0xFF 24 -25/* -26 * Function my_timer_func blinks the keyboard LEDs periodically by invoking -27 * command KDSETLED of ioctl() on the keyboard driver. To learn more on virtual -28 * terminal ioctl operations, please see file: -29 * /usr/src/linux/drivers/char/vt_ioctl.c, function vt_ioctl(). -30 * -31 * The argument to KDSETLED is alternatively set to 7 (thus causing the led -32 * mode to be set to LED_SHOW_IOCTL, and all the leds are lit) and to 0xFF -33 * (any value above 7 switches back the led mode to LED_SHOW_FLAGS, thus -34 * the LEDs reflect the actual keyboard status). To learn more on this, -35 * please see file: -36 * /usr/src/linux/drivers/char/keyboard.c, function setledstate(). -37 * -38 */ +25/* +26 * Function my_timer_func blinks the keyboard LEDs periodically by invoking +27 * command KDSETLED of ioctl() on the keyboard driver. To learn more on virtual +28 * terminal ioctl operations, please see file: +29 * /usr/src/linux/drivers/char/vt_ioctl.c, function vt_ioctl(). +30 * +31 * The argument to KDSETLED is alternatively set to 7 (thus causing the led +32 * mode to be set to LED_SHOW_IOCTL, and all the leds are lit) and to 0xFF +33 * (any value above 7 switches back the led mode to LED_SHOW_FLAGS, thus +34 * the LEDs reflect the actual keyboard status). To learn more on this, +35 * please see file: +36 * /usr/src/linux/drivers/char/keyboard.c, function setledstate(). +37 * +38 */ 39 -40static void my_timer_func(unsigned long ptr) +40static void my_timer_func(unsigned long ptr) 41{ -42 unsigned long *pstatus = (unsigned long *) ptr; -43 struct tty_struct *t = vc_cons[fg_console].d->port.tty; +42 unsigned long *pstatus = (unsigned long *) ptr; +43 struct tty_struct *t = vc_cons[fg_console].d->port.tty; 44 -45 if (*pstatus == ALL_LEDS_ON) +45 if (*pstatus == ALL_LEDS_ON) 46 *pstatus = RESTORE_LEDS; -47 else +47 else 48 *pstatus = ALL_LEDS_ON; 49 50 (my_driver->ops->ioctl)(t, KDSETLED, *pstatus); @@ -4109,37 +4104,37 @@ loaded, starts blinking the keyboard LEDs until it is unloaded. 53 add_timer(&my_timer); 54} 55 -56static int __init kbleds_init(void) +56static int __init kbleds_init(void) 57{ -58 int i; +58 int i; 59 -60 pr_info("kbleds: loading\n"); -61 pr_info("kbleds: fgconsole is %x\n", fg_console); -62 for (i = 0; i < MAX_NR_CONSOLES; i++) { -63 if (!vc_cons[i].d) -64 break; -65 pr_info("poet_atkm: console[%i/%i] #%i, tty %lx\n", i, MAX_NR_CONSOLES, -66 vc_cons[i].d->vc_num, (unsigned long) vc_cons[i].d->port.tty); +60 pr_info("kbleds: loading\n"); +61 pr_info("kbleds: fgconsole is %x\n", fg_console); +62 for (i = 0; i < MAX_NR_CONSOLES; i++) { +63 if (!vc_cons[i].d) +64 break; +65 pr_info("poet_atkm: console[%i/%i] #%i, tty %lx\n", i, MAX_NR_CONSOLES, +66 vc_cons[i].d->vc_num, (unsigned long) vc_cons[i].d->port.tty); 67 } -68 pr_info("kbleds: finished scanning consoles\n"); +68 pr_info("kbleds: finished scanning consoles\n"); 69 70 my_driver = vc_cons[fg_console].d->port.tty->driver; -71 pr_info("kbleds: tty driver magic %x\n", my_driver->magic); +71 pr_info("kbleds: tty driver magic %x\n", my_driver->magic); 72 -73 /* -74 * Set up the LED blink timer the first time -75 */ -76 timer_setup(&my_timer, (void *) &my_timer_func, -77 (unsigned long) &kbledstatus); +73 /* +74 * Set up the LED blink timer the first time +75 */ +76 timer_setup(&my_timer, (void *) &my_timer_func, +77 (unsigned long) &kbledstatus); 78 my_timer.expires = jiffies + BLINK_DELAY; 79 add_timer(&my_timer); 80 -81 return 0; +81 return 0; 82} 83 -84static void __exit kbleds_cleanup(void) +84static void __exit kbleds_cleanup(void) 85{ -86 pr_info("kbleds: unloading...\n"); +86 pr_info("kbleds: unloading...\n"); 87 del_timer(&my_timer); 88 (my_driver->ops->ioctl)(vc_cons[fg_console].d->port.tty, KDSETLED, 89 RESTORE_LEDS); @@ -4180,43 +4175,43 @@ and in the mean time execution of the example_tasklet_in the exit point.-
1/* -2 * example_tasklet.c -3 */ -4#include <linux/delay.h> -5#include <linux/interrupt.h> -6#include <linux/kernel.h> -7#include <linux/module.h> +1/* +2 * example_tasklet.c +3 */ +4#include <linux/delay.h> +5#include <linux/interrupt.h> +6#include <linux/kernel.h> +7#include <linux/module.h> 8 -9static void tasklet_fn(unsigned long data) +9static void tasklet_fn(unsigned long data) 10{ -11 pr_info("Example tasklet starts\n"); +11 pr_info("Example tasklet starts\n"); 12 mdelay(5000); -13 pr_info("Example tasklet ends\n"); +13 pr_info("Example tasklet ends\n"); 14} 15 16DECLARE_TASKLET(mytask, tasklet_fn, 0L); 17 -18static int example_tasklet_init(void) +18static int example_tasklet_init(void) 19{ -20 pr_info("tasklet example init\n"); +20 pr_info("tasklet example init\n"); 21 tasklet_schedule(&mytask); 22 mdelay(200); -23 pr_info("Example tasklet init continues...\n"); -24 return 0; +23 pr_info("Example tasklet init continues...\n"); +24 return 0; 25} 26 -27static void example_tasklet_exit(void) +27static void example_tasklet_exit(void) 28{ -29 pr_info("tasklet example exit\n"); +29 pr_info("tasklet example exit\n"); 30 tasklet_kill(&mytask); 31} 32 33module_init(example_tasklet_init); 34module_exit(example_tasklet_exit); 35 -36MODULE_DESCRIPTION("Tasklet example"); -37MODULE_LICENSE("GPL");+36MODULE_DESCRIPTION("Tasklet example"); +37MODULE_LICENSE("GPL");So with this example loaded dmesg should show: @@ -4236,37 +4231,37 @@ Example tasklet ends Completely Fair Scheduler (CFS) to execute work within the queue.
-
1/* -2 * sched.c -3 */ -4#include <linux/init.h> -5#include <linux/module.h> -6#include <linux/workqueue.h> +1/* +2 * sched.c +3 */ +4#include <linux/init.h> +5#include <linux/module.h> +6#include <linux/workqueue.h> 7 -8static struct workqueue_struct *queue = NULL; -9static struct work_struct work; +8static struct workqueue_struct *queue = NULL; +9static struct work_struct work; 10 -11static void work_handler(struct work_struct *data) +11static void work_handler(struct work_struct *data) 12{ -13 pr_info("work handler function.\n"); +13 pr_info("work handler function.\n"); 14} 15 -16int init_module() +16int init_module() 17{ -18 queue = alloc_workqueue("HELLOWORLD", WQ_UNBOUND, 1); +18 queue = alloc_workqueue("HELLOWORLD", WQ_UNBOUND, 1); 19 INIT_WORK(&work, work_handler); 20 schedule_work(&work); 21 -22 return 0; +22 return 0; 23} 24 -25void cleanup_module() +25void cleanup_module() 26{ 27 destroy_workqueue(queue); 28} 29 -30MODULE_LICENSE("GPL"); -31MODULE_DESCRIPTION("Workqueue example");+30MODULE_LICENSE("GPL"); +31MODULE_DESCRIPTION("Workqueue example");
0.15 Interrupt Handlers
@@ -4348,115 +4343,115 @@ an LED is connected to GPIO 4. You can change those numbers to whatever is appropriate for your board.-
1/* -2 * intrpt.c - Handling GPIO with interrupts -3 * -4 * Based upon the RPi example by Stefan Wendler (devnull@kaltpost.de) -5 * from: -6 * https://github.com/wendlers/rpi-kmod-samples -7 * -8 * Press one button to turn on a LED and another to turn it off -9 */ +1/* +2 * intrpt.c - Handling GPIO with interrupts +3 * +4 * Based upon the RPi example by Stefan Wendler (devnull@kaltpost.de) +5 * from: +6 * https://github.com/wendlers/rpi-kmod-samples +7 * +8 * Press one button to turn on a LED and another to turn it off +9 */ 10 -11#include <linux/gpio.h> -12#include <linux/interrupt.h> -13#include <linux/kernel.h> -14#include <linux/module.h> +11#include <linux/gpio.h> +12#include <linux/interrupt.h> +13#include <linux/kernel.h> +14#include <linux/module.h> 15 -16static int button_irqs[] = {-1, -1}; +16static int button_irqs[] = {-1, -1}; 17 -18/* Define GPIOs for LEDs. -19 Change the numbers for the GPIO on your board. */ -20static struct gpio leds[] = {{4, GPIOF_OUT_INIT_LOW, "LED 1"}}; +18/* Define GPIOs for LEDs. +19 Change the numbers for the GPIO on your board. */ +20static struct gpio leds[] = {{4, GPIOF_OUT_INIT_LOW, "LED 1"}}; 21 -22/* Define GPIOs for BUTTONS -23 Change the numbers for the GPIO on your board. */ -24static struct gpio buttons[] = {{17, GPIOF_IN, "LED 1 ON BUTTON"}, -25 {18, GPIOF_IN, "LED 1 OFF BUTTON"}}; +22/* Define GPIOs for BUTTONS +23 Change the numbers for the GPIO on your board. */ +24static struct gpio buttons[] = {{17, GPIOF_IN, "LED 1 ON BUTTON"}, +25 {18, GPIOF_IN, "LED 1 OFF BUTTON"}}; 26 -27/* -28 * interrupt function triggered when a button is pressed -29 */ -30static irqreturn_t button_isr(int irq, void *data) +27/* +28 * interrupt function triggered when a button is pressed +29 */ +30static irqreturn_t button_isr(int irq, void *data) 31{ -32 /* first button */ -33 if (irq == button_irqs[0] && !gpio_get_value(leds[0].gpio)) +32 /* first button */ +33 if (irq == button_irqs[0] && !gpio_get_value(leds[0].gpio)) 34 gpio_set_value(leds[0].gpio, 1); -35 /* second button */ -36 else if (irq == button_irqs[1] && gpio_get_value(leds[0].gpio)) +35 /* second button */ +36 else if (irq == button_irqs[1] && gpio_get_value(leds[0].gpio)) 37 gpio_set_value(leds[0].gpio, 0); 38 -39 return IRQ_HANDLED; +39 return IRQ_HANDLED; 40} 41 -42int init_module() +42int init_module() 43{ -44 int ret = 0; +44 int ret = 0; 45 -46 pr_info("%s\n", __func__); +46 pr_info("%s\n", __func__); 47 -48 /* register LED gpios */ +48 /* register LED gpios */ 49 ret = gpio_request_array(leds, ARRAY_SIZE(leds)); 50 -51 if (ret) { -52 pr_err("Unable to request GPIOs for LEDs: %d\n", ret); -53 return ret; +51 if (ret) { +52 pr_err("Unable to request GPIOs for LEDs: %d\n", ret); +53 return ret; 54 } 55 -56 /* register BUTTON gpios */ +56 /* register BUTTON gpios */ 57 ret = gpio_request_array(buttons, ARRAY_SIZE(buttons)); 58 -59 if (ret) { -60 pr_err("Unable to request GPIOs for BUTTONs: %d\n", ret); -61 goto fail1; +59 if (ret) { +60 pr_err("Unable to request GPIOs for BUTTONs: %d\n", ret); +61 goto fail1; 62 } 63 -64 pr_info("Current button1 value: %d\n", gpio_get_value(buttons[0].gpio)); +64 pr_info("Current button1 value: %d\n", gpio_get_value(buttons[0].gpio)); 65 66 ret = gpio_to_irq(buttons[0].gpio); 67 -68 if (ret < 0) { -69 pr_err("Unable to request IRQ: %d\n", ret); -70 goto fail2; +68 if (ret < 0) { +69 pr_err("Unable to request IRQ: %d\n", ret); +70 goto fail2; 71 } 72 73 button_irqs[0] = ret; 74 -75 pr_info("Successfully requested BUTTON1 IRQ # %d\n", button_irqs[0]); +75 pr_info("Successfully requested BUTTON1 IRQ # %d\n", button_irqs[0]); 76 77 ret = request_irq(button_irqs[0], button_isr, 78 IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, -79 "gpiomod#button1", NULL); +79 "gpiomod#button1", NULL); 80 -81 if (ret) { -82 pr_err("Unable to request IRQ: %d\n", ret); -83 goto fail2; +81 if (ret) { +82 pr_err("Unable to request IRQ: %d\n", ret); +83 goto fail2; 84 } 85 86 87 ret = gpio_to_irq(buttons[1].gpio); 88 -89 if (ret < 0) { -90 pr_err("Unable to request IRQ: %d\n", ret); -91 goto fail2; +89 if (ret < 0) { +90 pr_err("Unable to request IRQ: %d\n", ret); +91 goto fail2; 92 } 93 94 button_irqs[1] = ret; 95 -96 pr_info("Successfully requested BUTTON2 IRQ # %d\n", button_irqs[1]); +96 pr_info("Successfully requested BUTTON2 IRQ # %d\n", button_irqs[1]); 97 98 ret = request_irq(button_irqs[1], button_isr, 99 IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, -100 "gpiomod#button2", NULL); +100 "gpiomod#button2", NULL); 101 -102 if (ret) { -103 pr_err("Unable to request IRQ: %d\n", ret); -104 goto fail3; +102 if (ret) { +103 pr_err("Unable to request IRQ: %d\n", ret); +104 goto fail3; 105 } 106 -107 return 0; +107 return 0; 108 -109/* cleanup what has been setup so far */ +109/* cleanup what has been setup so far */ 110fail3: 111 free_irq(button_irqs[0], NULL); 112 @@ -4466,30 +4461,30 @@ appropriate for your board. 116fail1: 117 gpio_free_array(leds, ARRAY_SIZE(leds)); 118 -119 return ret; +119 return ret; 120} 121 -122void cleanup_module() +122void cleanup_module() 123{ -124 int i; +124 int i; 125 -126 pr_info("%s\n", __func__); +126 pr_info("%s\n", __func__); 127 -128 /* free irqs */ +128 /* free irqs */ 129 free_irq(button_irqs[0], NULL); 130 free_irq(button_irqs[1], NULL); 131 -132 /* turn all LEDs off */ -133 for (i = 0; i < ARRAY_SIZE(leds); i++) +132 /* turn all LEDs off */ +133 for (i = 0; i < ARRAY_SIZE(leds); i++) 134 gpio_set_value(leds[i].gpio, 0); 135 -136 /* unregister */ +136 /* unregister */ 137 gpio_free_array(leds, ARRAY_SIZE(leds)); 138 gpio_free_array(buttons, ARRAY_SIZE(buttons)); 139} 140 -141MODULE_LICENSE("GPL"); -142MODULE_DESCRIPTION("Handle some GPIO interrupts");+141MODULE_LICENSE("GPL"); +142MODULE_DESCRIPTION("Handle some GPIO interrupts");
0.15.3 Bottom Half
@@ -4501,129 +4496,129 @@ scheduler. when an interrupt is triggered.-
1/* -2 * bottomhalf.c - Top and bottom half interrupt handling -3 * -4 * Based upon the RPi example by Stefan Wendler (devnull@kaltpost.de) -5 * from: -6 * https://github.com/wendlers/rpi-kmod-samples -7 * -8 * Press one button to turn on a LED and another to turn it off -9 */ +1/* +2 * bottomhalf.c - Top and bottom half interrupt handling +3 * +4 * Based upon the RPi example by Stefan Wendler (devnull@kaltpost.de) +5 * from: +6 * https://github.com/wendlers/rpi-kmod-samples +7 * +8 * Press one button to turn on a LED and another to turn it off +9 */ 10 -11#include <linux/delay.h> -12#include <linux/gpio.h> -13#include <linux/interrupt.h> -14#include <linux/kernel.h> -15#include <linux/module.h> +11#include <linux/delay.h> +12#include <linux/gpio.h> +13#include <linux/interrupt.h> +14#include <linux/kernel.h> +15#include <linux/module.h> 16 -17static int button_irqs[] = {-1, -1}; +17static int button_irqs[] = {-1, -1}; 18 -19/* Define GPIOs for LEDs. -20 Change the numbers for the GPIO on your board. */ -21static struct gpio leds[] = {{4, GPIOF_OUT_INIT_LOW, "LED 1"}}; +19/* Define GPIOs for LEDs. +20 Change the numbers for the GPIO on your board. */ +21static struct gpio leds[] = {{4, GPIOF_OUT_INIT_LOW, "LED 1"}}; 22 -23/* Define GPIOs for BUTTONS -24 Change the numbers for the GPIO on your board. */ -25static struct gpio buttons[] = {{17, GPIOF_IN, "LED 1 ON BUTTON"}, -26 {18, GPIOF_IN, "LED 1 OFF BUTTON"}}; +23/* Define GPIOs for BUTTONS +24 Change the numbers for the GPIO on your board. */ +25static struct gpio buttons[] = {{17, GPIOF_IN, "LED 1 ON BUTTON"}, +26 {18, GPIOF_IN, "LED 1 OFF BUTTON"}}; 27 -28/* Tasklet containing some non-trivial amount of processing */ -29static void bottomhalf_tasklet_fn(unsigned long data) +28/* Tasklet containing some non-trivial amount of processing */ +29static void bottomhalf_tasklet_fn(unsigned long data) 30{ -31 pr_info("Bottom half tasklet starts\n"); -32 /* do something which takes a while */ +31 pr_info("Bottom half tasklet starts\n"); +32 /* do something which takes a while */ 33 mdelay(500); -34 pr_info("Bottom half tasklet ends\n"); +34 pr_info("Bottom half tasklet ends\n"); 35} 36 37DECLARE_TASKLET(buttontask, bottomhalf_tasklet_fn, 0L); 38 -39/* -40 * interrupt function triggered when a button is pressed -41 */ -42static irqreturn_t button_isr(int irq, void *data) +39/* +40 * interrupt function triggered when a button is pressed +41 */ +42static irqreturn_t button_isr(int irq, void *data) 43{ -44 /* Do something quickly right now */ -45 if (irq == button_irqs[0] && !gpio_get_value(leds[0].gpio)) +44 /* Do something quickly right now */ +45 if (irq == button_irqs[0] && !gpio_get_value(leds[0].gpio)) 46 gpio_set_value(leds[0].gpio, 1); -47 else if (irq == button_irqs[1] && gpio_get_value(leds[0].gpio)) +47 else if (irq == button_irqs[1] && gpio_get_value(leds[0].gpio)) 48 gpio_set_value(leds[0].gpio, 0); 49 -50 /* Do the rest at leisure via the scheduler */ +50 /* Do the rest at leisure via the scheduler */ 51 tasklet_schedule(&buttontask); 52 -53 return IRQ_HANDLED; +53 return IRQ_HANDLED; 54} 55 -56int init_module() +56int init_module() 57{ -58 int ret = 0; +58 int ret = 0; 59 -60 pr_info("%s\n", __func__); +60 pr_info("%s\n", __func__); 61 -62 /* register LED gpios */ +62 /* register LED gpios */ 63 ret = gpio_request_array(leds, ARRAY_SIZE(leds)); 64 -65 if (ret) { -66 pr_err("Unable to request GPIOs for LEDs: %d\n", ret); -67 return ret; +65 if (ret) { +66 pr_err("Unable to request GPIOs for LEDs: %d\n", ret); +67 return ret; 68 } 69 -70 /* register BUTTON gpios */ +70 /* register BUTTON gpios */ 71 ret = gpio_request_array(buttons, ARRAY_SIZE(buttons)); 72 -73 if (ret) { -74 pr_err("Unable to request GPIOs for BUTTONs: %d\n", ret); -75 goto fail1; +73 if (ret) { +74 pr_err("Unable to request GPIOs for BUTTONs: %d\n", ret); +75 goto fail1; 76 } 77 -78 pr_info("Current button1 value: %d\n", gpio_get_value(buttons[0].gpio)); +78 pr_info("Current button1 value: %d\n", gpio_get_value(buttons[0].gpio)); 79 80 ret = gpio_to_irq(buttons[0].gpio); 81 -82 if (ret < 0) { -83 pr_err("Unable to request IRQ: %d\n", ret); -84 goto fail2; +82 if (ret < 0) { +83 pr_err("Unable to request IRQ: %d\n", ret); +84 goto fail2; 85 } 86 87 button_irqs[0] = ret; 88 -89 pr_info("Successfully requested BUTTON1 IRQ # %d\n", button_irqs[0]); +89 pr_info("Successfully requested BUTTON1 IRQ # %d\n", button_irqs[0]); 90 91 ret = request_irq(button_irqs[0], button_isr, 92 IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, -93 "gpiomod#button1", NULL); +93 "gpiomod#button1", NULL); 94 -95 if (ret) { -96 pr_err("Unable to request IRQ: %d\n", ret); -97 goto fail2; +95 if (ret) { +96 pr_err("Unable to request IRQ: %d\n", ret); +97 goto fail2; 98 } 99 100 101 ret = gpio_to_irq(buttons[1].gpio); 102 -103 if (ret < 0) { -104 pr_err("Unable to request IRQ: %d\n", ret); -105 goto fail2; +103 if (ret < 0) { +104 pr_err("Unable to request IRQ: %d\n", ret); +105 goto fail2; 106 } 107 108 button_irqs[1] = ret; 109 -110 pr_info("Successfully requested BUTTON2 IRQ # %d\n", button_irqs[1]); +110 pr_info("Successfully requested BUTTON2 IRQ # %d\n", button_irqs[1]); 111 112 ret = request_irq(button_irqs[1], button_isr, 113 IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, -114 "gpiomod#button2", NULL); +114 "gpiomod#button2", NULL); 115 -116 if (ret) { -117 pr_err("Unable to request IRQ: %d\n", ret); -118 goto fail3; +116 if (ret) { +117 pr_err("Unable to request IRQ: %d\n", ret); +118 goto fail3; 119 } 120 -121 return 0; +121 return 0; 122 -123/* cleanup what has been setup so far */ +123/* cleanup what has been setup so far */ 124fail3: 125 free_irq(button_irqs[0], NULL); 126 @@ -4633,30 +4628,30 @@ when an interrupt is triggered. 130fail1: 131 gpio_free_array(leds, ARRAY_SIZE(leds)); 132 -133 return ret; +133 return ret; 134} 135 -136void cleanup_module() +136void cleanup_module() 137{ -138 int i; +138 int i; 139 -140 pr_info("%s\n", __func__); +140 pr_info("%s\n", __func__); 141 -142 /* free irqs */ +142 /* free irqs */ 143 free_irq(button_irqs[0], NULL); 144 free_irq(button_irqs[1], NULL); 145 -146 /* turn all LEDs off */ -147 for (i = 0; i < ARRAY_SIZE(leds); i++) +146 /* turn all LEDs off */ +147 for (i = 0; i < ARRAY_SIZE(leds); i++) 148 gpio_set_value(leds[i].gpio, 0); 149 -150 /* unregister */ +150 /* unregister */ 151 gpio_free_array(leds, ARRAY_SIZE(leds)); 152 gpio_free_array(buttons, ARRAY_SIZE(buttons)); 153} 154 -155MODULE_LICENSE("GPL"); -156MODULE_DESCRIPTION("Interrupt with top and bottom half");+155MODULE_LICENSE("GPL"); +156MODULE_DESCRIPTION("Interrupt with top and bottom half");
0.16 Crypto
@@ -4676,68 +4671,68 @@ favourite hash functions. demonstration of how to calculate a sha256 hash within a kernel module.-
1/* -2 * cryptosha256.c -3 */ -4#include <crypto/internal/hash.h> -5#include <linux/module.h> +1/* +2 * cryptosha256.c +3 */ +4#include <crypto/internal/hash.h> +5#include <linux/module.h> 6 -7#define SHA256_LENGTH 32 +7#define SHA256_LENGTH 32 8 -9static void show_hash_result(char *plaintext, char *hash_sha256) +9static void show_hash_result(char *plaintext, char *hash_sha256) 10{ -11 int i; -12 char str[SHA256_LENGTH * 2 + 1]; +11 int i; +12 char str[SHA256_LENGTH * 2 + 1]; 13 -14 pr_info("sha256 test for string: \"%s\"\n", plaintext); -15 for (i = 0; i < SHA256_LENGTH; i++) -16 sprintf(&str[i * 2], "%02x", (unsigned char) hash_sha256[i]); +14 pr_info("sha256 test for string: \"%s\"\n", plaintext); +15 for (i = 0; i < SHA256_LENGTH; i++) +16 sprintf(&str[i * 2], "%02x", (unsigned char) hash_sha256[i]); 17 str[i * 2] = 0; -18 pr_info("%s\n", str); +18 pr_info("%s\n", str); 19} 20 -21int cryptosha256_init(void) +21int cryptosha256_init(void) 22{ -23 char *plaintext = "This is a test"; -24 char hash_sha256[SHA256_LENGTH]; -25 struct crypto_shash *sha256; -26 struct shash_desc *shash; +23 char *plaintext = "This is a test"; +24 char hash_sha256[SHA256_LENGTH]; +25 struct crypto_shash *sha256; +26 struct shash_desc *shash; 27 -28 sha256 = crypto_alloc_shash("sha256", 0, 0); -29 if (IS_ERR(sha256)) -30 return -1; +28 sha256 = crypto_alloc_shash("sha256", 0, 0); +29 if (IS_ERR(sha256)) +30 return -1; 31 -32 shash = kmalloc(sizeof(struct shash_desc) + crypto_shash_descsize(sha256), +32 shash = kmalloc(sizeof(struct shash_desc) + crypto_shash_descsize(sha256), 33 GFP_KERNEL); -34 if (!shash) -35 return -ENOMEM; +34 if (!shash) +35 return -ENOMEM; 36 37 shash->tfm = sha256; 38 -39 if (crypto_shash_init(shash)) -40 return -1; +39 if (crypto_shash_init(shash)) +40 return -1; 41 -42 if (crypto_shash_update(shash, plaintext, strlen(plaintext))) -43 return -1; +42 if (crypto_shash_update(shash, plaintext, strlen(plaintext))) +43 return -1; 44 -45 if (crypto_shash_final(shash, hash_sha256)) -46 return -1; +45 if (crypto_shash_final(shash, hash_sha256)) +46 return -1; 47 48 kfree(shash); 49 crypto_free_shash(sha256); 50 51 show_hash_result(plaintext, hash_sha256); 52 -53 return 0; +53 return 0; 54} 55 -56void cryptosha256_exit(void) {} +56void cryptosha256_exit(void) {} 57 58module_init(cryptosha256_init); 59module_exit(cryptosha256_exit); 60 -61MODULE_DESCRIPTION("sha256 hash test"); -62MODULE_LICENSE("GPL");+61MODULE_DESCRIPTION("sha256 hash test"); +62MODULE_LICENSE("GPL");Make and install the module:
@@ -4756,183 +4751,183 @@ demonstration of how to calculate a sha256 hash within a kernel module. and a password.
-
1/* -2 * cryptosk.c -3 */ -4#include <crypto/internal/skcipher.h> -5#include <linux/crypto.h> -6#include <linux/module.h> +1/* +2 * cryptosk.c +3 */ +4#include <crypto/internal/skcipher.h> +5#include <linux/crypto.h> +6#include <linux/module.h> 7 -8#define SYMMETRIC_KEY_LENGTH 32 -9#define CIPHER_BLOCK_SIZE 16 +8#define SYMMETRIC_KEY_LENGTH 32 +9#define CIPHER_BLOCK_SIZE 16 10 -11struct tcrypt_result { -12 struct completion completion; -13 int err; +11struct tcrypt_result { +12 struct completion completion; +13 int err; 14}; 15 -16struct skcipher_def { -17 struct scatterlist sg; -18 struct crypto_skcipher *tfm; -19 struct skcipher_request *req; -20 struct tcrypt_result result; -21 char *scratchpad; -22 char *ciphertext; -23 char *ivdata; +16struct skcipher_def { +17 struct scatterlist sg; +18 struct crypto_skcipher *tfm; +19 struct skcipher_request *req; +20 struct tcrypt_result result; +21 char *scratchpad; +22 char *ciphertext; +23 char *ivdata; 24}; 25 -26static struct skcipher_def sk; +26static struct skcipher_def sk; 27 -28static void test_skcipher_finish(struct skcipher_def *sk) +28static void test_skcipher_finish(struct skcipher_def *sk) 29{ -30 if (sk->tfm) +30 if (sk->tfm) 31 crypto_free_skcipher(sk->tfm); -32 if (sk->req) +32 if (sk->req) 33 skcipher_request_free(sk->req); -34 if (sk->ivdata) +34 if (sk->ivdata) 35 kfree(sk->ivdata); -36 if (sk->scratchpad) +36 if (sk->scratchpad) 37 kfree(sk->scratchpad); -38 if (sk->ciphertext) +38 if (sk->ciphertext) 39 kfree(sk->ciphertext); 40} 41 -42static int test_skcipher_result(struct skcipher_def *sk, int rc) +42static int test_skcipher_result(struct skcipher_def *sk, int rc) 43{ -44 switch (rc) { -45 case 0: -46 break; -47 case -EINPROGRESS || -EBUSY: +44 switch (rc) { +45 case 0: +46 break; +47 case -EINPROGRESS || -EBUSY: 48 rc = wait_for_completion_interruptible(&sk->result.completion); -49 if (!rc && !sk->result.err) { +49 if (!rc && !sk->result.err) { 50 reinit_completion(&sk->result.completion); -51 break; +51 break; 52 } -53 pr_info("skcipher encrypt returned with %d result %d\n", rc, +53 pr_info("skcipher encrypt returned with %d result %d\n", rc, 54 sk->result.err); -55 break; -56 default: -57 pr_info("skcipher encrypt returned with %d result %d\n", rc, +55 break; +56 default: +57 pr_info("skcipher encrypt returned with %d result %d\n", rc, 58 sk->result.err); -59 break; +59 break; 60 } 61 62 init_completion(&sk->result.completion); 63 -64 return rc; +64 return rc; 65} 66 -67static void test_skcipher_callback(struct crypto_async_request *req, int error) +67static void test_skcipher_callback(struct crypto_async_request *req, int error) 68{ -69 struct tcrypt_result *result = req->data; -70 /* int ret; */ +69 struct tcrypt_result *result = req->data; +70 /* int ret; */ 71 -72 if (error == -EINPROGRESS) -73 return; +72 if (error == -EINPROGRESS) +73 return; 74 75 result->err = error; 76 complete(&result->completion); -77 pr_info("Encryption finished successfully\n"); +77 pr_info("Encryption finished successfully\n"); 78 -79 /* decrypt data */ -80 /* -81 memset((void*)sk.scratchpad, '-', CIPHER_BLOCK_SIZE); -82 ret = crypto_skcipher_decrypt(sk.req); -83 ret = test_skcipher_result(&sk, ret); -84 if (ret) -85 return; +79 /* decrypt data */ +80 /* +81 memset((void*)sk.scratchpad, '-', CIPHER_BLOCK_SIZE); +82 ret = crypto_skcipher_decrypt(sk.req); +83 ret = test_skcipher_result(&sk, ret); +84 if (ret) +85 return; 86 -87 sg_copy_from_buffer(&sk.sg, 1, sk.scratchpad, CIPHER_BLOCK_SIZE); -88 sk.scratchpad[CIPHER_BLOCK_SIZE-1] = 0; +87 sg_copy_from_buffer(&sk.sg, 1, sk.scratchpad, CIPHER_BLOCK_SIZE); +88 sk.scratchpad[CIPHER_BLOCK_SIZE-1] = 0; 89 -90 pr_info("Decryption request successful\n"); -91 pr_info("Decrypted: %s\n", sk.scratchpad); -92 */ +90 pr_info("Decryption request successful\n"); +91 pr_info("Decrypted: %s\n", sk.scratchpad); +92 */ 93} 94 -95static int test_skcipher_encrypt(char *plaintext, -96 char *password, -97 struct skcipher_def *sk) +95static int test_skcipher_encrypt(char *plaintext, +96 char *password, +97 struct skcipher_def *sk) 98{ -99 int ret = -EFAULT; -100 unsigned char key[SYMMETRIC_KEY_LENGTH]; +99 int ret = -EFAULT; +100 unsigned char key[SYMMETRIC_KEY_LENGTH]; 101 -102 if (!sk->tfm) { -103 sk->tfm = crypto_alloc_skcipher("cbc-aes-aesni", 0, 0); -104 if (IS_ERR(sk->tfm)) { -105 pr_info("could not allocate skcipher handle\n"); -106 return PTR_ERR(sk->tfm); +102 if (!sk->tfm) { +103 sk->tfm = crypto_alloc_skcipher("cbc-aes-aesni", 0, 0); +104 if (IS_ERR(sk->tfm)) { +105 pr_info("could not allocate skcipher handle\n"); +106 return PTR_ERR(sk->tfm); 107 } 108 } 109 -110 if (!sk->req) { +110 if (!sk->req) { 111 sk->req = skcipher_request_alloc(sk->tfm, GFP_KERNEL); -112 if (!sk->req) { -113 pr_info("could not allocate skcipher request\n"); +112 if (!sk->req) { +113 pr_info("could not allocate skcipher request\n"); 114 ret = -ENOMEM; -115 goto out; +115 goto out; 116 } 117 } 118 119 skcipher_request_set_callback(sk->req, CRYPTO_TFM_REQ_MAY_BACKLOG, 120 test_skcipher_callback, &sk->result); 121 -122 /* clear the key */ -123 memset((void *) key, '\0', SYMMETRIC_KEY_LENGTH); +122 /* clear the key */ +123 memset((void *) key, '\0', SYMMETRIC_KEY_LENGTH); 124 -125 /* Use the world's favourite password */ -126 sprintf((char *) key, "%s", password); +125 /* Use the world's favourite password */ +126 sprintf((char *) key, "%s", password); 127 -128 /* AES 256 with given symmetric key */ -129 if (crypto_skcipher_setkey(sk->tfm, key, SYMMETRIC_KEY_LENGTH)) { -130 pr_info("key could not be set\n"); +128 /* AES 256 with given symmetric key */ +129 if (crypto_skcipher_setkey(sk->tfm, key, SYMMETRIC_KEY_LENGTH)) { +130 pr_info("key could not be set\n"); 131 ret = -EAGAIN; -132 goto out; +132 goto out; 133 } -134 pr_info("Symmetric key: %s\n", key); -135 pr_info("Plaintext: %s\n", plaintext); +134 pr_info("Symmetric key: %s\n", key); +135 pr_info("Plaintext: %s\n", plaintext); 136 -137 if (!sk->ivdata) { -138 /* see https://en.wikipedia.org/wiki/Initialization_vector */ +137 if (!sk->ivdata) { +138 /* see https://en.wikipedia.org/wiki/Initialization_vector */ 139 sk->ivdata = kmalloc(CIPHER_BLOCK_SIZE, GFP_KERNEL); -140 if (!sk->ivdata) { -141 pr_info("could not allocate ivdata\n"); -142 goto out; +140 if (!sk->ivdata) { +141 pr_info("could not allocate ivdata\n"); +142 goto out; 143 } 144 get_random_bytes(sk->ivdata, CIPHER_BLOCK_SIZE); 145 } 146 -147 if (!sk->scratchpad) { -148 /* The text to be encrypted */ +147 if (!sk->scratchpad) { +148 /* The text to be encrypted */ 149 sk->scratchpad = kmalloc(CIPHER_BLOCK_SIZE, GFP_KERNEL); -150 if (!sk->scratchpad) { -151 pr_info("could not allocate scratchpad\n"); -152 goto out; +150 if (!sk->scratchpad) { +151 pr_info("could not allocate scratchpad\n"); +152 goto out; 153 } 154 } -155 sprintf((char *) sk->scratchpad, "%s", plaintext); +155 sprintf((char *) sk->scratchpad, "%s", plaintext); 156 157 sg_init_one(&sk->sg, sk->scratchpad, CIPHER_BLOCK_SIZE); 158 skcipher_request_set_crypt(sk->req, &sk->sg, &sk->sg, CIPHER_BLOCK_SIZE, 159 sk->ivdata); 160 init_completion(&sk->result.completion); 161 -162 /* encrypt data */ +162 /* encrypt data */ 163 ret = crypto_skcipher_encrypt(sk->req); 164 ret = test_skcipher_result(sk, ret); -165 if (ret) -166 goto out; +165 if (ret) +166 goto out; 167 -168 pr_info("Encryption request successful\n"); +168 pr_info("Encryption request successful\n"); 169 170out: -171 return ret; +171 return ret; 172} 173 -174int cryptoapi_init(void) +174int cryptoapi_init(void) 175{ -176 /* The world's favorite password */ -177 char *password = "password123"; +176 /* The world's favorite password */ +177 char *password = "password123"; 178 179 sk.tfm = NULL; 180 sk.req = NULL; @@ -4940,11 +4935,11 @@ and a password. 182 sk.ciphertext = NULL; 183 sk.ivdata = NULL; 184 -185 test_skcipher_encrypt("Testing", password, &sk); -186 return 0; +185 test_skcipher_encrypt("Testing", password, &sk); +186 return 0; 187} 188 -189void cryptoapi_exit(void) +189void cryptoapi_exit(void) 190{ 191 test_skcipher_finish(&sk); 192} @@ -4952,8 +4947,8 @@ and a password. 194module_init(cryptoapi_init); 195module_exit(cryptoapi_exit); 196 -197MODULE_DESCRIPTION("Symmetric key encryption example"); -198MODULE_LICENSE("GPL");+197MODULE_DESCRIPTION("Symmetric key encryption example"); +198MODULE_LICENSE("GPL");
0.17 Standardising the interfaces: The Device Model
@@ -4965,59 +4960,59 @@ use this as a template to add your own suspend, resume or other interface functions.-
1/* -2 * devicemodel.c -3 */ -4#include <linux/kernel.h> -5#include <linux/module.h> -6#include <linux/platform_device.h> +1/* +2 * devicemodel.c +3 */ +4#include <linux/kernel.h> +5#include <linux/module.h> +6#include <linux/platform_device.h> 7 -8struct devicemodel_data { -9 char *greeting; -10 int number; +8struct devicemodel_data { +9 char *greeting; +10 int number; 11}; 12 -13static int devicemodel_probe(struct platform_device *dev) +13static int devicemodel_probe(struct platform_device *dev) 14{ -15 struct devicemodel_data *pd = -16 (struct devicemodel_data *) (dev->dev.platform_data); +15 struct devicemodel_data *pd = +16 (struct devicemodel_data *) (dev->dev.platform_data); 17 -18 pr_info("devicemodel probe\n"); -19 pr_info("devicemodel greeting: %s; %d\n", pd->greeting, pd->number); +18 pr_info("devicemodel probe\n"); +19 pr_info("devicemodel greeting: %s; %d\n", pd->greeting, pd->number); 20 -21 /* Your device initialisation code */ +21 /* Your device initialisation code */ 22 -23 return 0; +23 return 0; 24} 25 -26static int devicemodel_remove(struct platform_device *dev) +26static int devicemodel_remove(struct platform_device *dev) 27{ -28 pr_info("devicemodel example removed\n"); +28 pr_info("devicemodel example removed\n"); 29 -30 /* Your device removal code */ +30 /* Your device removal code */ 31 -32 return 0; +32 return 0; 33} 34 -35static int devicemodel_suspend(struct device *dev) +35static int devicemodel_suspend(struct device *dev) 36{ -37 pr_info("devicemodel example suspend\n"); +37 pr_info("devicemodel example suspend\n"); 38 -39 /* Your device suspend code */ +39 /* Your device suspend code */ 40 -41 return 0; +41 return 0; 42} 43 -44static int devicemodel_resume(struct device *dev) +44static int devicemodel_resume(struct device *dev) 45{ -46 pr_info("devicemodel example resume\n"); +46 pr_info("devicemodel example resume\n"); 47 -48 /* Your device resume code */ +48 /* Your device resume code */ 49 -50 return 0; +50 return 0; 51} 52 -53static const struct dev_pm_ops devicemodel_pm_ops = { +53static const struct dev_pm_ops devicemodel_pm_ops = { 54 .suspend = devicemodel_suspend, 55 .resume = devicemodel_resume, 56 .poweroff = devicemodel_suspend, @@ -5026,10 +5021,10 @@ functions. 59 .restore = devicemodel_resume, 60}; 61 -62static struct platform_driver devicemodel_driver = { +62static struct platform_driver devicemodel_driver = { 63 .driver = 64 { -65 .name = "devicemodel_example", +65 .name = "devicemodel_example", 66 .owner = THIS_MODULE, 67 .pm = &devicemodel_pm_ops, 68 }, @@ -5037,30 +5032,30 @@ functions. 70 .remove = devicemodel_remove, 71}; 72 -73static int devicemodel_init(void) +73static int devicemodel_init(void) 74{ -75 int ret; +75 int ret; 76 -77 pr_info("devicemodel init\n"); +77 pr_info("devicemodel init\n"); 78 79 ret = platform_driver_register(&devicemodel_driver); 80 -81 if (ret) { -82 pr_err("Unable to register driver\n"); -83 return ret; +81 if (ret) { +82 pr_err("Unable to register driver\n"); +83 return ret; 84 } 85 -86 return 0; +86 return 0; 87} 88 -89static void devicemodel_exit(void) +89static void devicemodel_exit(void) 90{ -91 pr_info("devicemodel exit\n"); +91 pr_info("devicemodel exit\n"); 92 platform_driver_unregister(&devicemodel_driver); 93} 94 -95MODULE_LICENSE("GPL"); -96MODULE_DESCRIPTION("Linux Device Model example"); +95MODULE_LICENSE("GPL"); +96MODULE_DESCRIPTION("Linux Device Model example"); 97 98module_init(devicemodel_init); 99module_exit(devicemodel_exit);@@ -5084,10 +5079,10 @@ succeed.
1bvl = bvec_alloc(gfp_mask, nr_iovecs, &idx); -2if (unlikely(!bvl)) { +2if (unlikely(!bvl)) { 3 mempool_free(bio, bio_pool); 4 bio = NULL; -5 goto out; +5 goto out; 6}When the unlikely macro is used the compiler alters its machine instruction output so that it continues along the false branch and only jumps if the condition is diff --git a/lkmpg.css b/lkmpg.css index 89e0d7a..a198de3 100644 --- a/lkmpg.css +++ b/lkmpg.css @@ -2353,33 +2353,33 @@ span#textcolor1888{color:rgb(163,20,20)} span#textcolor1889{color:rgb(0,127,0)} span#textcolor1890{color:rgb(0,127,0)} span#textcolor1891{color:rgb(0,0,255)} -span#textcolor1892{color:rgb(0,0,255)} +span#textcolor1892{color:rgb(163,20,20)} span#textcolor1893{color:rgb(163,20,20)} -span#textcolor1894{color:rgb(0,0,255)} -span#textcolor1895{color:rgb(163,20,20)} +span#textcolor1894{color:rgb(0,127,0)} +span#textcolor1895{color:rgb(0,0,255)} span#textcolor1896{color:rgb(0,127,0)} -span#textcolor1897{color:rgb(0,0,255)} -span#textcolor1898{color:rgb(43,145,175)} -span#textcolor1899{color:rgb(0,127,0)} -span#textcolor1900{color:rgb(0,127,0)} +span#textcolor1897{color:rgb(0,127,0)} +span#textcolor1898{color:rgb(0,0,255)} +span#textcolor1899{color:rgb(0,0,255)} +span#textcolor1900{color:rgb(163,20,20)} span#textcolor1901{color:rgb(0,0,255)} -span#textcolor1902{color:rgb(0,0,255)} -span#textcolor1903{color:rgb(163,20,20)} +span#textcolor1902{color:rgb(163,20,20)} +span#textcolor1903{color:rgb(0,127,0)} span#textcolor1904{color:rgb(0,0,255)} -span#textcolor1905{color:rgb(163,20,20)} -span#textcolor1906{color:rgb(0,127,0)} -span#textcolor1907{color:rgb(0,0,255)} +span#textcolor1905{color:rgb(0,0,255)} +span#textcolor1906{color:rgb(43,145,175)} +span#textcolor1907{color:rgb(0,127,0)} span#textcolor1908{color:rgb(0,0,255)} -span#textcolor1909{color:rgb(0,127,0)} -span#textcolor1910{color:rgb(0,0,255)} -span#textcolor1911{color:rgb(0,0,255)} +span#textcolor1909{color:rgb(0,0,255)} pre#fancyvrb55{padding:5.69054pt;} pre#fancyvrb55{ border-top: solid 0.4pt; } pre#fancyvrb55{ border-left: solid 0.4pt; } pre#fancyvrb55{ border-bottom: solid 0.4pt; } pre#fancyvrb55{ border-right: solid 0.4pt; } +span#textcolor1910{color:rgb(0,127,0)} +span#textcolor1911{color:rgb(0,127,0)} span#textcolor1912{color:rgb(0,127,0)} -span#textcolor1913{color:rgb(0,127,0)} +span#textcolor1913{color:rgb(0,0,255)} span#textcolor1914{color:rgb(0,127,0)} span#textcolor1915{color:rgb(0,0,255)} span#textcolor1916{color:rgb(0,127,0)} @@ -2390,53 +2390,53 @@ span#textcolor1920{color:rgb(0,127,0)} span#textcolor1921{color:rgb(0,0,255)} span#textcolor1922{color:rgb(0,127,0)} span#textcolor1923{color:rgb(0,0,255)} -span#textcolor1924{color:rgb(0,127,0)} +span#textcolor1924{color:rgb(0,0,255)} span#textcolor1925{color:rgb(0,0,255)} span#textcolor1926{color:rgb(0,0,255)} span#textcolor1927{color:rgb(0,0,255)} -span#textcolor1928{color:rgb(0,0,255)} -span#textcolor1929{color:rgb(0,0,255)} -span#textcolor1930{color:rgb(43,145,175)} -span#textcolor1931{color:rgb(43,145,175)} +span#textcolor1928{color:rgb(43,145,175)} +span#textcolor1929{color:rgb(43,145,175)} +span#textcolor1930{color:rgb(163,20,20)} +span#textcolor1931{color:rgb(163,20,20)} span#textcolor1932{color:rgb(163,20,20)} -span#textcolor1933{color:rgb(163,20,20)} -span#textcolor1934{color:rgb(163,20,20)} -span#textcolor1935{color:rgb(0,0,255)} -span#textcolor1936{color:rgb(43,145,175)} -span#textcolor1937{color:rgb(43,145,175)} +span#textcolor1933{color:rgb(0,0,255)} +span#textcolor1934{color:rgb(43,145,175)} +span#textcolor1935{color:rgb(43,145,175)} +span#textcolor1936{color:rgb(163,20,20)} +span#textcolor1937{color:rgb(163,20,20)} span#textcolor1938{color:rgb(163,20,20)} -span#textcolor1939{color:rgb(163,20,20)} -span#textcolor1940{color:rgb(163,20,20)} -span#textcolor1941{color:rgb(0,0,255)} -span#textcolor1942{color:rgb(43,145,175)} -span#textcolor1943{color:rgb(43,145,175)} -span#textcolor1944{color:rgb(0,0,255)} -span#textcolor1945{color:rgb(0,0,255)} +span#textcolor1939{color:rgb(0,0,255)} +span#textcolor1940{color:rgb(43,145,175)} +span#textcolor1941{color:rgb(43,145,175)} +span#textcolor1942{color:rgb(0,0,255)} +span#textcolor1943{color:rgb(0,0,255)} +span#textcolor1944{color:rgb(163,20,20)} +span#textcolor1945{color:rgb(163,20,20)} span#textcolor1946{color:rgb(163,20,20)} span#textcolor1947{color:rgb(163,20,20)} -span#textcolor1948{color:rgb(163,20,20)} -span#textcolor1949{color:rgb(163,20,20)} -span#textcolor1950{color:rgb(0,0,255)} +span#textcolor1948{color:rgb(0,0,255)} +span#textcolor1949{color:rgb(0,0,255)} +span#textcolor1950{color:rgb(163,20,20)} span#textcolor1951{color:rgb(0,0,255)} -span#textcolor1952{color:rgb(163,20,20)} +span#textcolor1952{color:rgb(0,0,255)} span#textcolor1953{color:rgb(0,0,255)} span#textcolor1954{color:rgb(0,0,255)} -span#textcolor1955{color:rgb(0,0,255)} -span#textcolor1956{color:rgb(0,0,255)} -span#textcolor1957{color:rgb(43,145,175)} -span#textcolor1958{color:rgb(43,145,175)} +span#textcolor1955{color:rgb(43,145,175)} +span#textcolor1956{color:rgb(43,145,175)} +span#textcolor1957{color:rgb(163,20,20)} +span#textcolor1958{color:rgb(163,20,20)} span#textcolor1959{color:rgb(163,20,20)} span#textcolor1960{color:rgb(163,20,20)} span#textcolor1961{color:rgb(163,20,20)} -span#textcolor1962{color:rgb(163,20,20)} -span#textcolor1963{color:rgb(163,20,20)} pre#fancyvrb56{padding:5.69054pt;} pre#fancyvrb56{ border-top: solid 0.4pt; } pre#fancyvrb56{ border-left: solid 0.4pt; } pre#fancyvrb56{ border-bottom: solid 0.4pt; } pre#fancyvrb56{ border-right: solid 0.4pt; } +span#textcolor1962{color:rgb(0,127,0)} +span#textcolor1963{color:rgb(0,127,0)} span#textcolor1964{color:rgb(0,127,0)} -span#textcolor1965{color:rgb(0,127,0)} +span#textcolor1965{color:rgb(0,0,255)} span#textcolor1966{color:rgb(0,127,0)} span#textcolor1967{color:rgb(0,0,255)} span#textcolor1968{color:rgb(0,127,0)} @@ -2445,45 +2445,45 @@ span#textcolor1970{color:rgb(0,127,0)} span#textcolor1971{color:rgb(0,0,255)} span#textcolor1972{color:rgb(0,127,0)} span#textcolor1973{color:rgb(0,0,255)} -span#textcolor1974{color:rgb(0,127,0)} -span#textcolor1975{color:rgb(0,0,255)} +span#textcolor1974{color:rgb(43,145,175)} +span#textcolor1975{color:rgb(43,145,175)} span#textcolor1976{color:rgb(43,145,175)} -span#textcolor1977{color:rgb(43,145,175)} -span#textcolor1978{color:rgb(43,145,175)} +span#textcolor1977{color:rgb(163,20,20)} +span#textcolor1978{color:rgb(163,20,20)} span#textcolor1979{color:rgb(163,20,20)} -span#textcolor1980{color:rgb(163,20,20)} +span#textcolor1980{color:rgb(0,0,255)} span#textcolor1981{color:rgb(163,20,20)} -span#textcolor1982{color:rgb(0,0,255)} +span#textcolor1982{color:rgb(163,20,20)} span#textcolor1983{color:rgb(163,20,20)} -span#textcolor1984{color:rgb(163,20,20)} +span#textcolor1984{color:rgb(0,0,255)} span#textcolor1985{color:rgb(163,20,20)} -span#textcolor1986{color:rgb(0,0,255)} +span#textcolor1986{color:rgb(163,20,20)} span#textcolor1987{color:rgb(163,20,20)} span#textcolor1988{color:rgb(163,20,20)} span#textcolor1989{color:rgb(163,20,20)} span#textcolor1990{color:rgb(163,20,20)} -span#textcolor1991{color:rgb(163,20,20)} +span#textcolor1991{color:rgb(0,0,255)} span#textcolor1992{color:rgb(163,20,20)} -span#textcolor1993{color:rgb(0,0,255)} +span#textcolor1993{color:rgb(163,20,20)} span#textcolor1994{color:rgb(163,20,20)} -span#textcolor1995{color:rgb(163,20,20)} -span#textcolor1996{color:rgb(163,20,20)} -span#textcolor1997{color:rgb(0,0,255)} -span#textcolor1998{color:rgb(0,0,255)} -span#textcolor1999{color:rgb(43,145,175)} -span#textcolor2000{color:rgb(43,145,175)} +span#textcolor1995{color:rgb(0,0,255)} +span#textcolor1996{color:rgb(0,0,255)} +span#textcolor1997{color:rgb(43,145,175)} +span#textcolor1998{color:rgb(43,145,175)} +span#textcolor1999{color:rgb(163,20,20)} +span#textcolor2000{color:rgb(163,20,20)} span#textcolor2001{color:rgb(163,20,20)} span#textcolor2002{color:rgb(163,20,20)} span#textcolor2003{color:rgb(163,20,20)} -span#textcolor2004{color:rgb(163,20,20)} -span#textcolor2005{color:rgb(163,20,20)} pre#fancyvrb57{padding:5.69054pt;} pre#fancyvrb57{ border-top: solid 0.4pt; } pre#fancyvrb57{ border-left: solid 0.4pt; } pre#fancyvrb57{ border-bottom: solid 0.4pt; } pre#fancyvrb57{ border-right: solid 0.4pt; } +span#textcolor2004{color:rgb(0,127,0)} +span#textcolor2005{color:rgb(0,127,0)} span#textcolor2006{color:rgb(0,127,0)} -span#textcolor2007{color:rgb(0,127,0)} +span#textcolor2007{color:rgb(0,0,255)} span#textcolor2008{color:rgb(0,127,0)} span#textcolor2009{color:rgb(0,0,255)} span#textcolor2010{color:rgb(0,127,0)} @@ -2494,172 +2494,172 @@ span#textcolor2014{color:rgb(0,127,0)} span#textcolor2015{color:rgb(0,0,255)} span#textcolor2016{color:rgb(0,127,0)} span#textcolor2017{color:rgb(0,0,255)} -span#textcolor2018{color:rgb(0,127,0)} -span#textcolor2019{color:rgb(0,0,255)} +span#textcolor2018{color:rgb(43,145,175)} +span#textcolor2019{color:rgb(43,145,175)} span#textcolor2020{color:rgb(43,145,175)} span#textcolor2021{color:rgb(43,145,175)} -span#textcolor2022{color:rgb(43,145,175)} -span#textcolor2023{color:rgb(43,145,175)} +span#textcolor2022{color:rgb(163,20,20)} +span#textcolor2023{color:rgb(163,20,20)} span#textcolor2024{color:rgb(163,20,20)} -span#textcolor2025{color:rgb(163,20,20)} -span#textcolor2026{color:rgb(163,20,20)} +span#textcolor2025{color:rgb(0,127,0)} +span#textcolor2026{color:rgb(0,127,0)} span#textcolor2027{color:rgb(0,127,0)} span#textcolor2028{color:rgb(0,127,0)} -span#textcolor2029{color:rgb(0,127,0)} -span#textcolor2030{color:rgb(0,127,0)} +span#textcolor2029{color:rgb(163,20,20)} +span#textcolor2030{color:rgb(163,20,20)} span#textcolor2031{color:rgb(163,20,20)} -span#textcolor2032{color:rgb(163,20,20)} -span#textcolor2033{color:rgb(163,20,20)} -span#textcolor2034{color:rgb(0,0,255)} +span#textcolor2032{color:rgb(0,0,255)} +span#textcolor2033{color:rgb(43,145,175)} +span#textcolor2034{color:rgb(43,145,175)} span#textcolor2035{color:rgb(43,145,175)} span#textcolor2036{color:rgb(43,145,175)} -span#textcolor2037{color:rgb(43,145,175)} -span#textcolor2038{color:rgb(43,145,175)} +span#textcolor2037{color:rgb(163,20,20)} +span#textcolor2038{color:rgb(163,20,20)} span#textcolor2039{color:rgb(163,20,20)} -span#textcolor2040{color:rgb(163,20,20)} -span#textcolor2041{color:rgb(163,20,20)} +span#textcolor2040{color:rgb(0,127,0)} +span#textcolor2041{color:rgb(0,127,0)} span#textcolor2042{color:rgb(0,127,0)} span#textcolor2043{color:rgb(0,127,0)} -span#textcolor2044{color:rgb(0,127,0)} -span#textcolor2045{color:rgb(0,127,0)} +span#textcolor2044{color:rgb(163,20,20)} +span#textcolor2045{color:rgb(163,20,20)} span#textcolor2046{color:rgb(163,20,20)} -span#textcolor2047{color:rgb(163,20,20)} -span#textcolor2048{color:rgb(163,20,20)} -span#textcolor2049{color:rgb(0,0,255)} -span#textcolor2050{color:rgb(43,145,175)} -span#textcolor2051{color:rgb(43,145,175)} +span#textcolor2047{color:rgb(0,0,255)} +span#textcolor2048{color:rgb(43,145,175)} +span#textcolor2049{color:rgb(43,145,175)} +span#textcolor2050{color:rgb(163,20,20)} +span#textcolor2051{color:rgb(163,20,20)} span#textcolor2052{color:rgb(163,20,20)} -span#textcolor2053{color:rgb(163,20,20)} -span#textcolor2054{color:rgb(163,20,20)} -span#textcolor2055{color:rgb(0,0,255)} -span#textcolor2056{color:rgb(0,0,255)} -span#textcolor2057{color:rgb(43,145,175)} -span#textcolor2058{color:rgb(43,145,175)} +span#textcolor2053{color:rgb(0,0,255)} +span#textcolor2054{color:rgb(0,0,255)} +span#textcolor2055{color:rgb(43,145,175)} +span#textcolor2056{color:rgb(43,145,175)} +span#textcolor2057{color:rgb(163,20,20)} +span#textcolor2058{color:rgb(163,20,20)} span#textcolor2059{color:rgb(163,20,20)} span#textcolor2060{color:rgb(163,20,20)} span#textcolor2061{color:rgb(163,20,20)} -span#textcolor2062{color:rgb(163,20,20)} -span#textcolor2063{color:rgb(163,20,20)} pre#fancyvrb58{padding:5.69054pt;} pre#fancyvrb58{ border-top: solid 0.4pt; } pre#fancyvrb58{ border-left: solid 0.4pt; } pre#fancyvrb58{ border-bottom: solid 0.4pt; } pre#fancyvrb58{ border-right: solid 0.4pt; } +span#textcolor2062{color:rgb(0,127,0)} +span#textcolor2063{color:rgb(0,127,0)} span#textcolor2064{color:rgb(0,127,0)} -span#textcolor2065{color:rgb(0,127,0)} +span#textcolor2065{color:rgb(0,0,255)} span#textcolor2066{color:rgb(0,127,0)} span#textcolor2067{color:rgb(0,0,255)} span#textcolor2068{color:rgb(0,127,0)} span#textcolor2069{color:rgb(0,0,255)} span#textcolor2070{color:rgb(0,127,0)} span#textcolor2071{color:rgb(0,0,255)} -span#textcolor2072{color:rgb(0,127,0)} -span#textcolor2073{color:rgb(0,0,255)} +span#textcolor2072{color:rgb(43,145,175)} +span#textcolor2073{color:rgb(43,145,175)} span#textcolor2074{color:rgb(43,145,175)} span#textcolor2075{color:rgb(43,145,175)} -span#textcolor2076{color:rgb(43,145,175)} -span#textcolor2077{color:rgb(43,145,175)} +span#textcolor2076{color:rgb(163,20,20)} +span#textcolor2077{color:rgb(163,20,20)} span#textcolor2078{color:rgb(163,20,20)} -span#textcolor2079{color:rgb(163,20,20)} +span#textcolor2079{color:rgb(0,127,0)} span#textcolor2080{color:rgb(163,20,20)} -span#textcolor2081{color:rgb(0,127,0)} +span#textcolor2081{color:rgb(163,20,20)} span#textcolor2082{color:rgb(163,20,20)} -span#textcolor2083{color:rgb(163,20,20)} -span#textcolor2084{color:rgb(163,20,20)} -span#textcolor2085{color:rgb(0,0,255)} +span#textcolor2083{color:rgb(0,0,255)} +span#textcolor2084{color:rgb(43,145,175)} +span#textcolor2085{color:rgb(43,145,175)} span#textcolor2086{color:rgb(43,145,175)} span#textcolor2087{color:rgb(43,145,175)} -span#textcolor2088{color:rgb(43,145,175)} -span#textcolor2089{color:rgb(43,145,175)} +span#textcolor2088{color:rgb(163,20,20)} +span#textcolor2089{color:rgb(163,20,20)} span#textcolor2090{color:rgb(163,20,20)} -span#textcolor2091{color:rgb(163,20,20)} +span#textcolor2091{color:rgb(0,127,0)} span#textcolor2092{color:rgb(163,20,20)} -span#textcolor2093{color:rgb(0,127,0)} +span#textcolor2093{color:rgb(163,20,20)} span#textcolor2094{color:rgb(163,20,20)} -span#textcolor2095{color:rgb(163,20,20)} -span#textcolor2096{color:rgb(163,20,20)} -span#textcolor2097{color:rgb(0,0,255)} -span#textcolor2098{color:rgb(43,145,175)} -span#textcolor2099{color:rgb(43,145,175)} +span#textcolor2095{color:rgb(0,0,255)} +span#textcolor2096{color:rgb(43,145,175)} +span#textcolor2097{color:rgb(43,145,175)} +span#textcolor2098{color:rgb(163,20,20)} +span#textcolor2099{color:rgb(163,20,20)} span#textcolor2100{color:rgb(163,20,20)} -span#textcolor2101{color:rgb(163,20,20)} -span#textcolor2102{color:rgb(163,20,20)} -span#textcolor2103{color:rgb(0,0,255)} -span#textcolor2104{color:rgb(0,0,255)} -span#textcolor2105{color:rgb(43,145,175)} -span#textcolor2106{color:rgb(43,145,175)} +span#textcolor2101{color:rgb(0,0,255)} +span#textcolor2102{color:rgb(0,0,255)} +span#textcolor2103{color:rgb(43,145,175)} +span#textcolor2104{color:rgb(43,145,175)} +span#textcolor2105{color:rgb(163,20,20)} +span#textcolor2106{color:rgb(163,20,20)} span#textcolor2107{color:rgb(163,20,20)} span#textcolor2108{color:rgb(163,20,20)} span#textcolor2109{color:rgb(163,20,20)} -span#textcolor2110{color:rgb(163,20,20)} -span#textcolor2111{color:rgb(163,20,20)} pre#fancyvrb59{padding:5.69054pt;} pre#fancyvrb59{ border-top: solid 0.4pt; } pre#fancyvrb59{ border-left: solid 0.4pt; } pre#fancyvrb59{ border-bottom: solid 0.4pt; } pre#fancyvrb59{ border-right: solid 0.4pt; } +span#textcolor2110{color:rgb(0,127,0)} +span#textcolor2111{color:rgb(0,127,0)} span#textcolor2112{color:rgb(0,127,0)} -span#textcolor2113{color:rgb(0,127,0)} +span#textcolor2113{color:rgb(0,0,255)} span#textcolor2114{color:rgb(0,127,0)} span#textcolor2115{color:rgb(0,0,255)} span#textcolor2116{color:rgb(0,127,0)} span#textcolor2117{color:rgb(0,0,255)} span#textcolor2118{color:rgb(0,127,0)} span#textcolor2119{color:rgb(0,0,255)} -span#textcolor2120{color:rgb(0,127,0)} +span#textcolor2120{color:rgb(0,0,255)} span#textcolor2121{color:rgb(0,0,255)} span#textcolor2122{color:rgb(0,0,255)} span#textcolor2123{color:rgb(0,0,255)} span#textcolor2124{color:rgb(0,0,255)} span#textcolor2125{color:rgb(0,0,255)} -span#textcolor2126{color:rgb(0,0,255)} -span#textcolor2127{color:rgb(0,0,255)} -span#textcolor2128{color:rgb(43,145,175)} -span#textcolor2129{color:rgb(43,145,175)} -span#textcolor2130{color:rgb(0,127,0)} -span#textcolor2131{color:rgb(0,127,0)} +span#textcolor2126{color:rgb(43,145,175)} +span#textcolor2127{color:rgb(43,145,175)} +span#textcolor2128{color:rgb(0,127,0)} +span#textcolor2129{color:rgb(0,127,0)} +span#textcolor2130{color:rgb(163,20,20)} +span#textcolor2131{color:rgb(163,20,20)} span#textcolor2132{color:rgb(163,20,20)} -span#textcolor2133{color:rgb(163,20,20)} -span#textcolor2134{color:rgb(163,20,20)} -span#textcolor2135{color:rgb(0,0,255)} +span#textcolor2133{color:rgb(0,0,255)} +span#textcolor2134{color:rgb(43,145,175)} +span#textcolor2135{color:rgb(43,145,175)} span#textcolor2136{color:rgb(43,145,175)} span#textcolor2137{color:rgb(43,145,175)} -span#textcolor2138{color:rgb(43,145,175)} -span#textcolor2139{color:rgb(43,145,175)} +span#textcolor2138{color:rgb(163,20,20)} +span#textcolor2139{color:rgb(163,20,20)} span#textcolor2140{color:rgb(163,20,20)} span#textcolor2141{color:rgb(163,20,20)} -span#textcolor2142{color:rgb(163,20,20)} +span#textcolor2142{color:rgb(0,0,255)} span#textcolor2143{color:rgb(163,20,20)} -span#textcolor2144{color:rgb(0,0,255)} +span#textcolor2144{color:rgb(163,20,20)} span#textcolor2145{color:rgb(163,20,20)} span#textcolor2146{color:rgb(163,20,20)} span#textcolor2147{color:rgb(163,20,20)} -span#textcolor2148{color:rgb(163,20,20)} -span#textcolor2149{color:rgb(163,20,20)} -span#textcolor2150{color:rgb(0,0,255)} -span#textcolor2151{color:rgb(43,145,175)} -span#textcolor2152{color:rgb(43,145,175)} +span#textcolor2148{color:rgb(0,0,255)} +span#textcolor2149{color:rgb(43,145,175)} +span#textcolor2150{color:rgb(43,145,175)} +span#textcolor2151{color:rgb(163,20,20)} +span#textcolor2152{color:rgb(163,20,20)} span#textcolor2153{color:rgb(163,20,20)} -span#textcolor2154{color:rgb(163,20,20)} -span#textcolor2155{color:rgb(163,20,20)} -span#textcolor2156{color:rgb(0,0,255)} -span#textcolor2157{color:rgb(0,0,255)} -span#textcolor2158{color:rgb(43,145,175)} -span#textcolor2159{color:rgb(43,145,175)} +span#textcolor2154{color:rgb(0,0,255)} +span#textcolor2155{color:rgb(0,0,255)} +span#textcolor2156{color:rgb(43,145,175)} +span#textcolor2157{color:rgb(43,145,175)} +span#textcolor2158{color:rgb(163,20,20)} +span#textcolor2159{color:rgb(163,20,20)} span#textcolor2160{color:rgb(163,20,20)} span#textcolor2161{color:rgb(163,20,20)} span#textcolor2162{color:rgb(163,20,20)} -span#textcolor2163{color:rgb(163,20,20)} -span#textcolor2164{color:rgb(163,20,20)} pre#fancyvrb60{padding:5.69054pt;} pre#fancyvrb60{ border-top: solid 0.4pt; } pre#fancyvrb60{ border-left: solid 0.4pt; } pre#fancyvrb60{ border-bottom: solid 0.4pt; } pre#fancyvrb60{ border-right: solid 0.4pt; } +span#textcolor2163{color:rgb(0,127,0)} +span#textcolor2164{color:rgb(0,127,0)} span#textcolor2165{color:rgb(0,127,0)} span#textcolor2166{color:rgb(0,127,0)} span#textcolor2167{color:rgb(0,127,0)} -span#textcolor2168{color:rgb(0,127,0)} +span#textcolor2168{color:rgb(0,0,255)} span#textcolor2169{color:rgb(0,127,0)} span#textcolor2170{color:rgb(0,0,255)} span#textcolor2171{color:rgb(0,127,0)} @@ -2669,23 +2669,23 @@ span#textcolor2174{color:rgb(0,0,255)} span#textcolor2175{color:rgb(0,127,0)} span#textcolor2176{color:rgb(0,0,255)} span#textcolor2177{color:rgb(0,127,0)} -span#textcolor2178{color:rgb(0,0,255)} -span#textcolor2179{color:rgb(0,127,0)} -span#textcolor2180{color:rgb(163,20,20)} -span#textcolor2181{color:rgb(0,0,255)} -span#textcolor2182{color:rgb(43,145,175)} -span#textcolor2183{color:rgb(43,145,175)} +span#textcolor2178{color:rgb(163,20,20)} +span#textcolor2179{color:rgb(0,0,255)} +span#textcolor2180{color:rgb(43,145,175)} +span#textcolor2181{color:rgb(43,145,175)} +span#textcolor2182{color:rgb(0,0,255)} +span#textcolor2183{color:rgb(0,0,255)} span#textcolor2184{color:rgb(0,0,255)} -span#textcolor2185{color:rgb(0,0,255)} -span#textcolor2186{color:rgb(0,0,255)} +span#textcolor2185{color:rgb(0,127,0)} +span#textcolor2186{color:rgb(0,127,0)} span#textcolor2187{color:rgb(0,127,0)} span#textcolor2188{color:rgb(0,127,0)} span#textcolor2189{color:rgb(0,127,0)} span#textcolor2190{color:rgb(0,127,0)} span#textcolor2191{color:rgb(0,127,0)} -span#textcolor2192{color:rgb(0,127,0)} +span#textcolor2192{color:rgb(0,0,255)} span#textcolor2193{color:rgb(0,127,0)} -span#textcolor2194{color:rgb(0,0,255)} +span#textcolor2194{color:rgb(0,127,0)} span#textcolor2195{color:rgb(0,127,0)} span#textcolor2196{color:rgb(0,127,0)} span#textcolor2197{color:rgb(0,127,0)} @@ -2720,27 +2720,27 @@ span#textcolor2225{color:rgb(0,127,0)} span#textcolor2226{color:rgb(0,127,0)} span#textcolor2227{color:rgb(0,127,0)} span#textcolor2228{color:rgb(0,127,0)} -span#textcolor2229{color:rgb(0,127,0)} -span#textcolor2230{color:rgb(0,127,0)} +span#textcolor2229{color:rgb(163,20,20)} +span#textcolor2230{color:rgb(163,20,20)} span#textcolor2231{color:rgb(163,20,20)} -span#textcolor2232{color:rgb(163,20,20)} -span#textcolor2233{color:rgb(163,20,20)} -span#textcolor2234{color:rgb(0,0,255)} -span#textcolor2235{color:rgb(43,145,175)} -span#textcolor2236{color:rgb(43,145,175)} -span#textcolor2237{color:rgb(163,20,20)} -span#textcolor2238{color:rgb(0,0,255)} -span#textcolor2239{color:rgb(0,0,255)} -span#textcolor2240{color:rgb(43,145,175)} -span#textcolor2241{color:rgb(43,145,175)} -span#textcolor2242{color:rgb(163,20,20)} +span#textcolor2232{color:rgb(0,0,255)} +span#textcolor2233{color:rgb(43,145,175)} +span#textcolor2234{color:rgb(43,145,175)} +span#textcolor2235{color:rgb(163,20,20)} +span#textcolor2236{color:rgb(0,0,255)} +span#textcolor2237{color:rgb(0,0,255)} +span#textcolor2238{color:rgb(43,145,175)} +span#textcolor2239{color:rgb(43,145,175)} +span#textcolor2240{color:rgb(163,20,20)} pre#fancyvrb61{padding:5.69054pt;} pre#fancyvrb61{ border-top: solid 0.4pt; } pre#fancyvrb61{ border-left: solid 0.4pt; } pre#fancyvrb61{ border-bottom: solid 0.4pt; } pre#fancyvrb61{ border-right: solid 0.4pt; } +span#textcolor2241{color:rgb(0,127,0)} +span#textcolor2242{color:rgb(0,127,0)} span#textcolor2243{color:rgb(0,127,0)} -span#textcolor2244{color:rgb(0,127,0)} +span#textcolor2244{color:rgb(0,0,255)} span#textcolor2245{color:rgb(0,127,0)} span#textcolor2246{color:rgb(0,0,255)} span#textcolor2247{color:rgb(0,127,0)} @@ -2754,16 +2754,16 @@ span#textcolor2254{color:rgb(0,0,255)} span#textcolor2255{color:rgb(0,127,0)} span#textcolor2256{color:rgb(0,0,255)} span#textcolor2257{color:rgb(0,127,0)} -span#textcolor2258{color:rgb(0,0,255)} -span#textcolor2259{color:rgb(0,127,0)} -span#textcolor2260{color:rgb(163,20,20)} -span#textcolor2261{color:rgb(163,20,20)} -span#textcolor2262{color:rgb(0,0,255)} +span#textcolor2258{color:rgb(163,20,20)} +span#textcolor2259{color:rgb(163,20,20)} +span#textcolor2260{color:rgb(0,0,255)} +span#textcolor2261{color:rgb(0,0,255)} +span#textcolor2262{color:rgb(43,145,175)} span#textcolor2263{color:rgb(0,0,255)} -span#textcolor2264{color:rgb(43,145,175)} +span#textcolor2264{color:rgb(0,0,255)} span#textcolor2265{color:rgb(0,0,255)} -span#textcolor2266{color:rgb(0,0,255)} -span#textcolor2267{color:rgb(0,0,255)} +span#textcolor2266{color:rgb(0,127,0)} +span#textcolor2267{color:rgb(0,127,0)} span#textcolor2268{color:rgb(0,127,0)} span#textcolor2269{color:rgb(0,127,0)} span#textcolor2270{color:rgb(0,127,0)} @@ -2776,63 +2776,63 @@ span#textcolor2276{color:rgb(0,127,0)} span#textcolor2277{color:rgb(0,127,0)} span#textcolor2278{color:rgb(0,127,0)} span#textcolor2279{color:rgb(0,127,0)} -span#textcolor2280{color:rgb(0,127,0)} -span#textcolor2281{color:rgb(0,127,0)} -span#textcolor2282{color:rgb(0,0,255)} +span#textcolor2280{color:rgb(0,0,255)} +span#textcolor2281{color:rgb(43,145,175)} +span#textcolor2282{color:rgb(43,145,175)} span#textcolor2283{color:rgb(43,145,175)} span#textcolor2284{color:rgb(43,145,175)} span#textcolor2285{color:rgb(43,145,175)} span#textcolor2286{color:rgb(43,145,175)} span#textcolor2287{color:rgb(43,145,175)} -span#textcolor2288{color:rgb(43,145,175)} -span#textcolor2289{color:rgb(43,145,175)} +span#textcolor2288{color:rgb(0,0,255)} +span#textcolor2289{color:rgb(0,0,255)} span#textcolor2290{color:rgb(0,0,255)} span#textcolor2291{color:rgb(0,0,255)} -span#textcolor2292{color:rgb(0,0,255)} -span#textcolor2293{color:rgb(0,0,255)} +span#textcolor2292{color:rgb(43,145,175)} +span#textcolor2293{color:rgb(43,145,175)} span#textcolor2294{color:rgb(43,145,175)} -span#textcolor2295{color:rgb(43,145,175)} -span#textcolor2296{color:rgb(43,145,175)} +span#textcolor2295{color:rgb(163,20,20)} +span#textcolor2296{color:rgb(163,20,20)} span#textcolor2297{color:rgb(163,20,20)} span#textcolor2298{color:rgb(163,20,20)} span#textcolor2299{color:rgb(163,20,20)} span#textcolor2300{color:rgb(163,20,20)} -span#textcolor2301{color:rgb(163,20,20)} -span#textcolor2302{color:rgb(163,20,20)} +span#textcolor2301{color:rgb(0,0,255)} +span#textcolor2302{color:rgb(0,0,255)} span#textcolor2303{color:rgb(0,0,255)} -span#textcolor2304{color:rgb(0,0,255)} -span#textcolor2305{color:rgb(0,0,255)} +span#textcolor2304{color:rgb(163,20,20)} +span#textcolor2305{color:rgb(163,20,20)} span#textcolor2306{color:rgb(163,20,20)} -span#textcolor2307{color:rgb(163,20,20)} -span#textcolor2308{color:rgb(163,20,20)} -span#textcolor2309{color:rgb(43,145,175)} -span#textcolor2310{color:rgb(43,145,175)} +span#textcolor2307{color:rgb(43,145,175)} +span#textcolor2308{color:rgb(43,145,175)} +span#textcolor2309{color:rgb(163,20,20)} +span#textcolor2310{color:rgb(163,20,20)} span#textcolor2311{color:rgb(163,20,20)} span#textcolor2312{color:rgb(163,20,20)} span#textcolor2313{color:rgb(163,20,20)} span#textcolor2314{color:rgb(163,20,20)} -span#textcolor2315{color:rgb(163,20,20)} -span#textcolor2316{color:rgb(163,20,20)} +span#textcolor2315{color:rgb(0,127,0)} +span#textcolor2316{color:rgb(0,127,0)} span#textcolor2317{color:rgb(0,127,0)} -span#textcolor2318{color:rgb(0,127,0)} -span#textcolor2319{color:rgb(0,127,0)} +span#textcolor2318{color:rgb(43,145,175)} +span#textcolor2319{color:rgb(43,145,175)} span#textcolor2320{color:rgb(43,145,175)} -span#textcolor2321{color:rgb(43,145,175)} -span#textcolor2322{color:rgb(43,145,175)} -span#textcolor2323{color:rgb(0,0,255)} -span#textcolor2324{color:rgb(0,0,255)} -span#textcolor2325{color:rgb(43,145,175)} -span#textcolor2326{color:rgb(43,145,175)} +span#textcolor2321{color:rgb(0,0,255)} +span#textcolor2322{color:rgb(0,0,255)} +span#textcolor2323{color:rgb(43,145,175)} +span#textcolor2324{color:rgb(43,145,175)} +span#textcolor2325{color:rgb(163,20,20)} +span#textcolor2326{color:rgb(163,20,20)} span#textcolor2327{color:rgb(163,20,20)} -span#textcolor2328{color:rgb(163,20,20)} -span#textcolor2329{color:rgb(163,20,20)} pre#fancyvrb62{padding:5.69054pt;} pre#fancyvrb62{ border-top: solid 0.4pt; } pre#fancyvrb62{ border-left: solid 0.4pt; } pre#fancyvrb62{ border-bottom: solid 0.4pt; } pre#fancyvrb62{ border-right: solid 0.4pt; } +span#textcolor2328{color:rgb(0,127,0)} +span#textcolor2329{color:rgb(0,127,0)} span#textcolor2330{color:rgb(0,127,0)} -span#textcolor2331{color:rgb(0,127,0)} +span#textcolor2331{color:rgb(0,0,255)} span#textcolor2332{color:rgb(0,127,0)} span#textcolor2333{color:rgb(0,0,255)} span#textcolor2334{color:rgb(0,127,0)} @@ -2841,70 +2841,70 @@ span#textcolor2336{color:rgb(0,127,0)} span#textcolor2337{color:rgb(0,0,255)} span#textcolor2338{color:rgb(0,127,0)} span#textcolor2339{color:rgb(0,0,255)} -span#textcolor2340{color:rgb(0,127,0)} -span#textcolor2341{color:rgb(0,0,255)} +span#textcolor2340{color:rgb(43,145,175)} +span#textcolor2341{color:rgb(43,145,175)} span#textcolor2342{color:rgb(43,145,175)} -span#textcolor2343{color:rgb(43,145,175)} -span#textcolor2344{color:rgb(43,145,175)} +span#textcolor2343{color:rgb(163,20,20)} +span#textcolor2344{color:rgb(163,20,20)} span#textcolor2345{color:rgb(163,20,20)} span#textcolor2346{color:rgb(163,20,20)} span#textcolor2347{color:rgb(163,20,20)} span#textcolor2348{color:rgb(163,20,20)} -span#textcolor2349{color:rgb(163,20,20)} -span#textcolor2350{color:rgb(163,20,20)} -span#textcolor2351{color:rgb(0,0,255)} -span#textcolor2352{color:rgb(43,145,175)} -span#textcolor2353{color:rgb(43,145,175)} +span#textcolor2349{color:rgb(0,0,255)} +span#textcolor2350{color:rgb(43,145,175)} +span#textcolor2351{color:rgb(43,145,175)} +span#textcolor2352{color:rgb(163,20,20)} +span#textcolor2353{color:rgb(163,20,20)} span#textcolor2354{color:rgb(163,20,20)} span#textcolor2355{color:rgb(163,20,20)} span#textcolor2356{color:rgb(163,20,20)} span#textcolor2357{color:rgb(163,20,20)} -span#textcolor2358{color:rgb(163,20,20)} -span#textcolor2359{color:rgb(163,20,20)} -span#textcolor2360{color:rgb(0,0,255)} -span#textcolor2361{color:rgb(0,0,255)} -span#textcolor2362{color:rgb(43,145,175)} -span#textcolor2363{color:rgb(43,145,175)} +span#textcolor2358{color:rgb(0,0,255)} +span#textcolor2359{color:rgb(0,0,255)} +span#textcolor2360{color:rgb(43,145,175)} +span#textcolor2361{color:rgb(43,145,175)} +span#textcolor2362{color:rgb(163,20,20)} +span#textcolor2363{color:rgb(163,20,20)} span#textcolor2364{color:rgb(163,20,20)} span#textcolor2365{color:rgb(163,20,20)} span#textcolor2366{color:rgb(163,20,20)} -span#textcolor2367{color:rgb(163,20,20)} -span#textcolor2368{color:rgb(163,20,20)} pre#fancyvrb63{padding:5.69054pt;} pre#fancyvrb63{ border-top: solid 0.4pt; } pre#fancyvrb63{ border-left: solid 0.4pt; } pre#fancyvrb63{ border-bottom: solid 0.4pt; } pre#fancyvrb63{ border-right: solid 0.4pt; } +span#textcolor2367{color:rgb(0,127,0)} +span#textcolor2368{color:rgb(0,127,0)} span#textcolor2369{color:rgb(0,127,0)} -span#textcolor2370{color:rgb(0,127,0)} +span#textcolor2370{color:rgb(0,0,255)} span#textcolor2371{color:rgb(0,127,0)} span#textcolor2372{color:rgb(0,0,255)} span#textcolor2373{color:rgb(0,127,0)} span#textcolor2374{color:rgb(0,0,255)} span#textcolor2375{color:rgb(0,127,0)} span#textcolor2376{color:rgb(0,0,255)} -span#textcolor2377{color:rgb(0,127,0)} +span#textcolor2377{color:rgb(0,0,255)} span#textcolor2378{color:rgb(0,0,255)} span#textcolor2379{color:rgb(0,0,255)} span#textcolor2380{color:rgb(0,0,255)} -span#textcolor2381{color:rgb(0,0,255)} +span#textcolor2381{color:rgb(43,145,175)} span#textcolor2382{color:rgb(0,0,255)} -span#textcolor2383{color:rgb(43,145,175)} -span#textcolor2384{color:rgb(0,0,255)} +span#textcolor2383{color:rgb(163,20,20)} +span#textcolor2384{color:rgb(163,20,20)} span#textcolor2385{color:rgb(163,20,20)} -span#textcolor2386{color:rgb(163,20,20)} +span#textcolor2386{color:rgb(43,145,175)} span#textcolor2387{color:rgb(163,20,20)} -span#textcolor2388{color:rgb(43,145,175)} -span#textcolor2389{color:rgb(163,20,20)} -span#textcolor2390{color:rgb(0,0,255)} -span#textcolor2391{color:rgb(43,145,175)} -span#textcolor2392{color:rgb(163,20,20)} -span#textcolor2393{color:rgb(163,20,20)} +span#textcolor2388{color:rgb(0,0,255)} +span#textcolor2389{color:rgb(43,145,175)} +span#textcolor2390{color:rgb(163,20,20)} +span#textcolor2391{color:rgb(163,20,20)} pre#fancyvrb64{padding:5.69054pt;} pre#fancyvrb64{ border-top: solid 0.4pt; } pre#fancyvrb64{ border-left: solid 0.4pt; } pre#fancyvrb64{ border-bottom: solid 0.4pt; } pre#fancyvrb64{ border-right: solid 0.4pt; } +span#textcolor2392{color:rgb(0,127,0)} +span#textcolor2393{color:rgb(0,127,0)} span#textcolor2394{color:rgb(0,127,0)} span#textcolor2395{color:rgb(0,127,0)} span#textcolor2396{color:rgb(0,127,0)} @@ -2912,7 +2912,7 @@ span#textcolor2397{color:rgb(0,127,0)} span#textcolor2398{color:rgb(0,127,0)} span#textcolor2399{color:rgb(0,127,0)} span#textcolor2400{color:rgb(0,127,0)} -span#textcolor2401{color:rgb(0,127,0)} +span#textcolor2401{color:rgb(0,0,255)} span#textcolor2402{color:rgb(0,127,0)} span#textcolor2403{color:rgb(0,0,255)} span#textcolor2404{color:rgb(0,127,0)} @@ -2921,99 +2921,99 @@ span#textcolor2406{color:rgb(0,127,0)} span#textcolor2407{color:rgb(0,0,255)} span#textcolor2408{color:rgb(0,127,0)} span#textcolor2409{color:rgb(0,0,255)} -span#textcolor2410{color:rgb(0,127,0)} -span#textcolor2411{color:rgb(0,0,255)} -span#textcolor2412{color:rgb(43,145,175)} -span#textcolor2413{color:rgb(0,127,0)} -span#textcolor2414{color:rgb(0,127,0)} -span#textcolor2415{color:rgb(0,0,255)} -span#textcolor2416{color:rgb(0,0,255)} -span#textcolor2417{color:rgb(163,20,20)} -span#textcolor2418{color:rgb(0,127,0)} -span#textcolor2419{color:rgb(0,127,0)} -span#textcolor2420{color:rgb(0,0,255)} -span#textcolor2421{color:rgb(0,0,255)} -span#textcolor2422{color:rgb(163,20,20)} -span#textcolor2423{color:rgb(163,20,20)} +span#textcolor2410{color:rgb(43,145,175)} +span#textcolor2411{color:rgb(0,127,0)} +span#textcolor2412{color:rgb(0,127,0)} +span#textcolor2413{color:rgb(0,0,255)} +span#textcolor2414{color:rgb(0,0,255)} +span#textcolor2415{color:rgb(163,20,20)} +span#textcolor2416{color:rgb(0,127,0)} +span#textcolor2417{color:rgb(0,127,0)} +span#textcolor2418{color:rgb(0,0,255)} +span#textcolor2419{color:rgb(0,0,255)} +span#textcolor2420{color:rgb(163,20,20)} +span#textcolor2421{color:rgb(163,20,20)} +span#textcolor2422{color:rgb(0,127,0)} +span#textcolor2423{color:rgb(0,127,0)} span#textcolor2424{color:rgb(0,127,0)} -span#textcolor2425{color:rgb(0,127,0)} -span#textcolor2426{color:rgb(0,127,0)} -span#textcolor2427{color:rgb(0,0,255)} -span#textcolor2428{color:rgb(43,145,175)} -span#textcolor2429{color:rgb(43,145,175)} +span#textcolor2425{color:rgb(0,0,255)} +span#textcolor2426{color:rgb(43,145,175)} +span#textcolor2427{color:rgb(43,145,175)} +span#textcolor2428{color:rgb(0,127,0)} +span#textcolor2429{color:rgb(0,0,255)} span#textcolor2430{color:rgb(0,127,0)} span#textcolor2431{color:rgb(0,0,255)} -span#textcolor2432{color:rgb(0,127,0)} +span#textcolor2432{color:rgb(0,0,255)} span#textcolor2433{color:rgb(0,0,255)} -span#textcolor2434{color:rgb(0,0,255)} -span#textcolor2435{color:rgb(0,0,255)} -span#textcolor2436{color:rgb(43,145,175)} -span#textcolor2437{color:rgb(43,145,175)} +span#textcolor2434{color:rgb(43,145,175)} +span#textcolor2435{color:rgb(43,145,175)} +span#textcolor2436{color:rgb(163,20,20)} +span#textcolor2437{color:rgb(163,20,20)} span#textcolor2438{color:rgb(163,20,20)} -span#textcolor2439{color:rgb(163,20,20)} -span#textcolor2440{color:rgb(163,20,20)} -span#textcolor2441{color:rgb(0,127,0)} -span#textcolor2442{color:rgb(0,0,255)} +span#textcolor2439{color:rgb(0,127,0)} +span#textcolor2440{color:rgb(0,0,255)} +span#textcolor2441{color:rgb(163,20,20)} +span#textcolor2442{color:rgb(163,20,20)} span#textcolor2443{color:rgb(163,20,20)} -span#textcolor2444{color:rgb(163,20,20)} -span#textcolor2445{color:rgb(163,20,20)} +span#textcolor2444{color:rgb(0,0,255)} +span#textcolor2445{color:rgb(0,127,0)} span#textcolor2446{color:rgb(0,0,255)} -span#textcolor2447{color:rgb(0,127,0)} -span#textcolor2448{color:rgb(0,0,255)} +span#textcolor2447{color:rgb(163,20,20)} +span#textcolor2448{color:rgb(163,20,20)} span#textcolor2449{color:rgb(163,20,20)} -span#textcolor2450{color:rgb(163,20,20)} +span#textcolor2450{color:rgb(0,0,255)} span#textcolor2451{color:rgb(163,20,20)} -span#textcolor2452{color:rgb(0,0,255)} +span#textcolor2452{color:rgb(163,20,20)} span#textcolor2453{color:rgb(163,20,20)} -span#textcolor2454{color:rgb(163,20,20)} +span#textcolor2454{color:rgb(0,0,255)} span#textcolor2455{color:rgb(163,20,20)} -span#textcolor2456{color:rgb(0,0,255)} +span#textcolor2456{color:rgb(163,20,20)} span#textcolor2457{color:rgb(163,20,20)} -span#textcolor2458{color:rgb(163,20,20)} +span#textcolor2458{color:rgb(0,0,255)} span#textcolor2459{color:rgb(163,20,20)} -span#textcolor2460{color:rgb(0,0,255)} +span#textcolor2460{color:rgb(163,20,20)} span#textcolor2461{color:rgb(163,20,20)} span#textcolor2462{color:rgb(163,20,20)} -span#textcolor2463{color:rgb(163,20,20)} +span#textcolor2463{color:rgb(0,0,255)} span#textcolor2464{color:rgb(163,20,20)} -span#textcolor2465{color:rgb(0,0,255)} +span#textcolor2465{color:rgb(163,20,20)} span#textcolor2466{color:rgb(163,20,20)} -span#textcolor2467{color:rgb(163,20,20)} -span#textcolor2468{color:rgb(163,20,20)} -span#textcolor2469{color:rgb(0,0,255)} -span#textcolor2470{color:rgb(0,0,255)} +span#textcolor2467{color:rgb(0,0,255)} +span#textcolor2468{color:rgb(0,0,255)} +span#textcolor2469{color:rgb(163,20,20)} +span#textcolor2470{color:rgb(163,20,20)} span#textcolor2471{color:rgb(163,20,20)} -span#textcolor2472{color:rgb(163,20,20)} +span#textcolor2472{color:rgb(0,0,255)} span#textcolor2473{color:rgb(163,20,20)} -span#textcolor2474{color:rgb(0,0,255)} +span#textcolor2474{color:rgb(163,20,20)} span#textcolor2475{color:rgb(163,20,20)} span#textcolor2476{color:rgb(163,20,20)} -span#textcolor2477{color:rgb(163,20,20)} +span#textcolor2477{color:rgb(0,0,255)} span#textcolor2478{color:rgb(163,20,20)} -span#textcolor2479{color:rgb(0,0,255)} +span#textcolor2479{color:rgb(163,20,20)} span#textcolor2480{color:rgb(163,20,20)} -span#textcolor2481{color:rgb(163,20,20)} -span#textcolor2482{color:rgb(163,20,20)} -span#textcolor2483{color:rgb(0,0,255)} +span#textcolor2481{color:rgb(0,0,255)} +span#textcolor2482{color:rgb(0,0,255)} +span#textcolor2483{color:rgb(0,127,0)} span#textcolor2484{color:rgb(0,0,255)} -span#textcolor2485{color:rgb(0,127,0)} -span#textcolor2486{color:rgb(0,0,255)} -span#textcolor2487{color:rgb(43,145,175)} -span#textcolor2488{color:rgb(43,145,175)} +span#textcolor2485{color:rgb(43,145,175)} +span#textcolor2486{color:rgb(43,145,175)} +span#textcolor2487{color:rgb(163,20,20)} +span#textcolor2488{color:rgb(163,20,20)} span#textcolor2489{color:rgb(163,20,20)} -span#textcolor2490{color:rgb(163,20,20)} -span#textcolor2491{color:rgb(163,20,20)} -span#textcolor2492{color:rgb(0,127,0)} +span#textcolor2490{color:rgb(0,127,0)} +span#textcolor2491{color:rgb(0,127,0)} +span#textcolor2492{color:rgb(0,0,255)} span#textcolor2493{color:rgb(0,127,0)} -span#textcolor2494{color:rgb(0,0,255)} -span#textcolor2495{color:rgb(0,127,0)} -span#textcolor2496{color:rgb(163,20,20)} -span#textcolor2497{color:rgb(163,20,20)} +span#textcolor2494{color:rgb(163,20,20)} +span#textcolor2495{color:rgb(163,20,20)} pre#fancyvrb65{padding:5.69054pt;} pre#fancyvrb65{ border-top: solid 0.4pt; } pre#fancyvrb65{ border-left: solid 0.4pt; } pre#fancyvrb65{ border-bottom: solid 0.4pt; } pre#fancyvrb65{ border-right: solid 0.4pt; } +span#textcolor2496{color:rgb(0,127,0)} +span#textcolor2497{color:rgb(0,127,0)} span#textcolor2498{color:rgb(0,127,0)} span#textcolor2499{color:rgb(0,127,0)} span#textcolor2500{color:rgb(0,127,0)} @@ -3021,7 +3021,7 @@ span#textcolor2501{color:rgb(0,127,0)} span#textcolor2502{color:rgb(0,127,0)} span#textcolor2503{color:rgb(0,127,0)} span#textcolor2504{color:rgb(0,127,0)} -span#textcolor2505{color:rgb(0,127,0)} +span#textcolor2505{color:rgb(0,0,255)} span#textcolor2506{color:rgb(0,127,0)} span#textcolor2507{color:rgb(0,0,255)} span#textcolor2508{color:rgb(0,127,0)} @@ -3032,145 +3032,145 @@ span#textcolor2512{color:rgb(0,127,0)} span#textcolor2513{color:rgb(0,0,255)} span#textcolor2514{color:rgb(0,127,0)} span#textcolor2515{color:rgb(0,0,255)} -span#textcolor2516{color:rgb(0,127,0)} -span#textcolor2517{color:rgb(0,0,255)} -span#textcolor2518{color:rgb(43,145,175)} -span#textcolor2519{color:rgb(0,127,0)} -span#textcolor2520{color:rgb(0,127,0)} -span#textcolor2521{color:rgb(0,0,255)} -span#textcolor2522{color:rgb(0,0,255)} -span#textcolor2523{color:rgb(163,20,20)} -span#textcolor2524{color:rgb(0,127,0)} -span#textcolor2525{color:rgb(0,127,0)} -span#textcolor2526{color:rgb(0,0,255)} -span#textcolor2527{color:rgb(0,0,255)} -span#textcolor2528{color:rgb(163,20,20)} -span#textcolor2529{color:rgb(163,20,20)} -span#textcolor2530{color:rgb(0,127,0)} -span#textcolor2531{color:rgb(0,0,255)} +span#textcolor2516{color:rgb(43,145,175)} +span#textcolor2517{color:rgb(0,127,0)} +span#textcolor2518{color:rgb(0,127,0)} +span#textcolor2519{color:rgb(0,0,255)} +span#textcolor2520{color:rgb(0,0,255)} +span#textcolor2521{color:rgb(163,20,20)} +span#textcolor2522{color:rgb(0,127,0)} +span#textcolor2523{color:rgb(0,127,0)} +span#textcolor2524{color:rgb(0,0,255)} +span#textcolor2525{color:rgb(0,0,255)} +span#textcolor2526{color:rgb(163,20,20)} +span#textcolor2527{color:rgb(163,20,20)} +span#textcolor2528{color:rgb(0,127,0)} +span#textcolor2529{color:rgb(0,0,255)} +span#textcolor2530{color:rgb(43,145,175)} +span#textcolor2531{color:rgb(43,145,175)} span#textcolor2532{color:rgb(43,145,175)} -span#textcolor2533{color:rgb(43,145,175)} -span#textcolor2534{color:rgb(43,145,175)} +span#textcolor2533{color:rgb(163,20,20)} +span#textcolor2534{color:rgb(163,20,20)} span#textcolor2535{color:rgb(163,20,20)} -span#textcolor2536{color:rgb(163,20,20)} +span#textcolor2536{color:rgb(0,127,0)} span#textcolor2537{color:rgb(163,20,20)} -span#textcolor2538{color:rgb(0,127,0)} +span#textcolor2538{color:rgb(163,20,20)} span#textcolor2539{color:rgb(163,20,20)} -span#textcolor2540{color:rgb(163,20,20)} -span#textcolor2541{color:rgb(163,20,20)} +span#textcolor2540{color:rgb(0,127,0)} +span#textcolor2541{color:rgb(0,127,0)} span#textcolor2542{color:rgb(0,127,0)} -span#textcolor2543{color:rgb(0,127,0)} -span#textcolor2544{color:rgb(0,127,0)} -span#textcolor2545{color:rgb(0,0,255)} -span#textcolor2546{color:rgb(43,145,175)} -span#textcolor2547{color:rgb(43,145,175)} -span#textcolor2548{color:rgb(0,127,0)} +span#textcolor2543{color:rgb(0,0,255)} +span#textcolor2544{color:rgb(43,145,175)} +span#textcolor2545{color:rgb(43,145,175)} +span#textcolor2546{color:rgb(0,127,0)} +span#textcolor2547{color:rgb(0,0,255)} +span#textcolor2548{color:rgb(0,0,255)} span#textcolor2549{color:rgb(0,0,255)} -span#textcolor2550{color:rgb(0,0,255)} +span#textcolor2550{color:rgb(0,127,0)} span#textcolor2551{color:rgb(0,0,255)} -span#textcolor2552{color:rgb(0,127,0)} -span#textcolor2553{color:rgb(0,0,255)} -span#textcolor2554{color:rgb(43,145,175)} -span#textcolor2555{color:rgb(43,145,175)} +span#textcolor2552{color:rgb(43,145,175)} +span#textcolor2553{color:rgb(43,145,175)} +span#textcolor2554{color:rgb(163,20,20)} +span#textcolor2555{color:rgb(163,20,20)} span#textcolor2556{color:rgb(163,20,20)} -span#textcolor2557{color:rgb(163,20,20)} -span#textcolor2558{color:rgb(163,20,20)} -span#textcolor2559{color:rgb(0,127,0)} -span#textcolor2560{color:rgb(0,0,255)} +span#textcolor2557{color:rgb(0,127,0)} +span#textcolor2558{color:rgb(0,0,255)} +span#textcolor2559{color:rgb(163,20,20)} +span#textcolor2560{color:rgb(163,20,20)} span#textcolor2561{color:rgb(163,20,20)} -span#textcolor2562{color:rgb(163,20,20)} -span#textcolor2563{color:rgb(163,20,20)} +span#textcolor2562{color:rgb(0,0,255)} +span#textcolor2563{color:rgb(0,127,0)} span#textcolor2564{color:rgb(0,0,255)} -span#textcolor2565{color:rgb(0,127,0)} -span#textcolor2566{color:rgb(0,0,255)} +span#textcolor2565{color:rgb(163,20,20)} +span#textcolor2566{color:rgb(163,20,20)} span#textcolor2567{color:rgb(163,20,20)} -span#textcolor2568{color:rgb(163,20,20)} +span#textcolor2568{color:rgb(0,0,255)} span#textcolor2569{color:rgb(163,20,20)} -span#textcolor2570{color:rgb(0,0,255)} +span#textcolor2570{color:rgb(163,20,20)} span#textcolor2571{color:rgb(163,20,20)} -span#textcolor2572{color:rgb(163,20,20)} +span#textcolor2572{color:rgb(0,0,255)} span#textcolor2573{color:rgb(163,20,20)} -span#textcolor2574{color:rgb(0,0,255)} +span#textcolor2574{color:rgb(163,20,20)} span#textcolor2575{color:rgb(163,20,20)} -span#textcolor2576{color:rgb(163,20,20)} +span#textcolor2576{color:rgb(0,0,255)} span#textcolor2577{color:rgb(163,20,20)} -span#textcolor2578{color:rgb(0,0,255)} +span#textcolor2578{color:rgb(163,20,20)} span#textcolor2579{color:rgb(163,20,20)} span#textcolor2580{color:rgb(163,20,20)} -span#textcolor2581{color:rgb(163,20,20)} +span#textcolor2581{color:rgb(0,0,255)} span#textcolor2582{color:rgb(163,20,20)} -span#textcolor2583{color:rgb(0,0,255)} +span#textcolor2583{color:rgb(163,20,20)} span#textcolor2584{color:rgb(163,20,20)} -span#textcolor2585{color:rgb(163,20,20)} -span#textcolor2586{color:rgb(163,20,20)} -span#textcolor2587{color:rgb(0,0,255)} -span#textcolor2588{color:rgb(0,0,255)} +span#textcolor2585{color:rgb(0,0,255)} +span#textcolor2586{color:rgb(0,0,255)} +span#textcolor2587{color:rgb(163,20,20)} +span#textcolor2588{color:rgb(163,20,20)} span#textcolor2589{color:rgb(163,20,20)} -span#textcolor2590{color:rgb(163,20,20)} +span#textcolor2590{color:rgb(0,0,255)} span#textcolor2591{color:rgb(163,20,20)} -span#textcolor2592{color:rgb(0,0,255)} +span#textcolor2592{color:rgb(163,20,20)} span#textcolor2593{color:rgb(163,20,20)} span#textcolor2594{color:rgb(163,20,20)} -span#textcolor2595{color:rgb(163,20,20)} +span#textcolor2595{color:rgb(0,0,255)} span#textcolor2596{color:rgb(163,20,20)} -span#textcolor2597{color:rgb(0,0,255)} +span#textcolor2597{color:rgb(163,20,20)} span#textcolor2598{color:rgb(163,20,20)} -span#textcolor2599{color:rgb(163,20,20)} -span#textcolor2600{color:rgb(163,20,20)} -span#textcolor2601{color:rgb(0,0,255)} +span#textcolor2599{color:rgb(0,0,255)} +span#textcolor2600{color:rgb(0,0,255)} +span#textcolor2601{color:rgb(0,127,0)} span#textcolor2602{color:rgb(0,0,255)} -span#textcolor2603{color:rgb(0,127,0)} -span#textcolor2604{color:rgb(0,0,255)} -span#textcolor2605{color:rgb(43,145,175)} -span#textcolor2606{color:rgb(43,145,175)} +span#textcolor2603{color:rgb(43,145,175)} +span#textcolor2604{color:rgb(43,145,175)} +span#textcolor2605{color:rgb(163,20,20)} +span#textcolor2606{color:rgb(163,20,20)} span#textcolor2607{color:rgb(163,20,20)} -span#textcolor2608{color:rgb(163,20,20)} -span#textcolor2609{color:rgb(163,20,20)} -span#textcolor2610{color:rgb(0,127,0)} +span#textcolor2608{color:rgb(0,127,0)} +span#textcolor2609{color:rgb(0,127,0)} +span#textcolor2610{color:rgb(0,0,255)} span#textcolor2611{color:rgb(0,127,0)} -span#textcolor2612{color:rgb(0,0,255)} -span#textcolor2613{color:rgb(0,127,0)} -span#textcolor2614{color:rgb(163,20,20)} -span#textcolor2615{color:rgb(163,20,20)} +span#textcolor2612{color:rgb(163,20,20)} +span#textcolor2613{color:rgb(163,20,20)} pre#fancyvrb66{padding:5.69054pt;} pre#fancyvrb66{ border-top: solid 0.4pt; } pre#fancyvrb66{ border-left: solid 0.4pt; } pre#fancyvrb66{ border-bottom: solid 0.4pt; } pre#fancyvrb66{ border-right: solid 0.4pt; } +span#textcolor2614{color:rgb(0,127,0)} +span#textcolor2615{color:rgb(0,127,0)} span#textcolor2616{color:rgb(0,127,0)} -span#textcolor2617{color:rgb(0,127,0)} +span#textcolor2617{color:rgb(0,0,255)} span#textcolor2618{color:rgb(0,127,0)} span#textcolor2619{color:rgb(0,0,255)} span#textcolor2620{color:rgb(0,127,0)} span#textcolor2621{color:rgb(0,0,255)} -span#textcolor2622{color:rgb(0,127,0)} -span#textcolor2623{color:rgb(0,0,255)} -span#textcolor2624{color:rgb(0,0,255)} +span#textcolor2622{color:rgb(0,0,255)} +span#textcolor2623{color:rgb(43,145,175)} +span#textcolor2624{color:rgb(43,145,175)} span#textcolor2625{color:rgb(43,145,175)} span#textcolor2626{color:rgb(43,145,175)} span#textcolor2627{color:rgb(43,145,175)} -span#textcolor2628{color:rgb(43,145,175)} -span#textcolor2629{color:rgb(43,145,175)} +span#textcolor2628{color:rgb(163,20,20)} +span#textcolor2629{color:rgb(163,20,20)} span#textcolor2630{color:rgb(163,20,20)} span#textcolor2631{color:rgb(163,20,20)} span#textcolor2632{color:rgb(163,20,20)} -span#textcolor2633{color:rgb(163,20,20)} +span#textcolor2633{color:rgb(0,0,255)} span#textcolor2634{color:rgb(163,20,20)} -span#textcolor2635{color:rgb(0,0,255)} -span#textcolor2636{color:rgb(163,20,20)} -span#textcolor2637{color:rgb(43,145,175)} -span#textcolor2638{color:rgb(43,145,175)} +span#textcolor2635{color:rgb(43,145,175)} +span#textcolor2636{color:rgb(43,145,175)} +span#textcolor2637{color:rgb(163,20,20)} +span#textcolor2638{color:rgb(163,20,20)} span#textcolor2639{color:rgb(163,20,20)} -span#textcolor2640{color:rgb(163,20,20)} -span#textcolor2641{color:rgb(163,20,20)} +span#textcolor2640{color:rgb(43,145,175)} +span#textcolor2641{color:rgb(43,145,175)} span#textcolor2642{color:rgb(43,145,175)} -span#textcolor2643{color:rgb(43,145,175)} +span#textcolor2643{color:rgb(163,20,20)} span#textcolor2644{color:rgb(43,145,175)} -span#textcolor2645{color:rgb(163,20,20)} -span#textcolor2646{color:rgb(43,145,175)} -span#textcolor2647{color:rgb(0,0,255)} +span#textcolor2645{color:rgb(0,0,255)} +span#textcolor2646{color:rgb(0,0,255)} +span#textcolor2647{color:rgb(163,20,20)} span#textcolor2648{color:rgb(0,0,255)} -span#textcolor2649{color:rgb(163,20,20)} +span#textcolor2649{color:rgb(0,0,255)} span#textcolor2650{color:rgb(0,0,255)} span#textcolor2651{color:rgb(0,0,255)} span#textcolor2652{color:rgb(0,0,255)} @@ -3182,12 +3182,10 @@ span#textcolor2657{color:rgb(0,0,255)} span#textcolor2658{color:rgb(0,0,255)} span#textcolor2659{color:rgb(0,0,255)} span#textcolor2660{color:rgb(0,0,255)} -span#textcolor2661{color:rgb(0,0,255)} -span#textcolor2662{color:rgb(0,0,255)} -span#textcolor2663{color:rgb(43,145,175)} -span#textcolor2664{color:rgb(43,145,175)} -span#textcolor2665{color:rgb(163,20,20)} -span#textcolor2666{color:rgb(163,20,20)} +span#textcolor2661{color:rgb(43,145,175)} +span#textcolor2662{color:rgb(43,145,175)} +span#textcolor2663{color:rgb(163,20,20)} +span#textcolor2664{color:rgb(163,20,20)} pre#fancyvrb67{padding:5.69054pt;} pre#fancyvrb67{ border-top: solid 0.4pt; } pre#fancyvrb67{ border-left: solid 0.4pt; } @@ -3203,69 +3201,71 @@ pre#fancyvrb69{ border-top: solid 0.4pt; } pre#fancyvrb69{ border-left: solid 0.4pt; } pre#fancyvrb69{ border-bottom: solid 0.4pt; } pre#fancyvrb69{ border-right: solid 0.4pt; } +span#textcolor2665{color:rgb(0,127,0)} +span#textcolor2666{color:rgb(0,127,0)} span#textcolor2667{color:rgb(0,127,0)} -span#textcolor2668{color:rgb(0,127,0)} +span#textcolor2668{color:rgb(0,0,255)} span#textcolor2669{color:rgb(0,127,0)} span#textcolor2670{color:rgb(0,0,255)} span#textcolor2671{color:rgb(0,127,0)} span#textcolor2672{color:rgb(0,0,255)} span#textcolor2673{color:rgb(0,127,0)} span#textcolor2674{color:rgb(0,0,255)} -span#textcolor2675{color:rgb(0,127,0)} +span#textcolor2675{color:rgb(0,0,255)} span#textcolor2676{color:rgb(0,0,255)} span#textcolor2677{color:rgb(0,0,255)} -span#textcolor2678{color:rgb(0,0,255)} +span#textcolor2678{color:rgb(43,145,175)} span#textcolor2679{color:rgb(0,0,255)} -span#textcolor2680{color:rgb(43,145,175)} +span#textcolor2680{color:rgb(0,0,255)} span#textcolor2681{color:rgb(0,0,255)} span#textcolor2682{color:rgb(0,0,255)} span#textcolor2683{color:rgb(0,0,255)} -span#textcolor2684{color:rgb(0,0,255)} -span#textcolor2685{color:rgb(0,0,255)} +span#textcolor2684{color:rgb(43,145,175)} +span#textcolor2685{color:rgb(43,145,175)} span#textcolor2686{color:rgb(43,145,175)} -span#textcolor2687{color:rgb(43,145,175)} -span#textcolor2688{color:rgb(43,145,175)} +span#textcolor2687{color:rgb(0,0,255)} +span#textcolor2688{color:rgb(0,0,255)} span#textcolor2689{color:rgb(0,0,255)} -span#textcolor2690{color:rgb(0,0,255)} +span#textcolor2690{color:rgb(43,145,175)} span#textcolor2691{color:rgb(0,0,255)} -span#textcolor2692{color:rgb(43,145,175)} +span#textcolor2692{color:rgb(0,0,255)} span#textcolor2693{color:rgb(0,0,255)} span#textcolor2694{color:rgb(0,0,255)} span#textcolor2695{color:rgb(0,0,255)} span#textcolor2696{color:rgb(0,0,255)} span#textcolor2697{color:rgb(0,0,255)} -span#textcolor2698{color:rgb(0,0,255)} +span#textcolor2698{color:rgb(43,145,175)} span#textcolor2699{color:rgb(0,0,255)} span#textcolor2700{color:rgb(43,145,175)} span#textcolor2701{color:rgb(0,0,255)} -span#textcolor2702{color:rgb(43,145,175)} +span#textcolor2702{color:rgb(0,0,255)} span#textcolor2703{color:rgb(0,0,255)} span#textcolor2704{color:rgb(0,0,255)} span#textcolor2705{color:rgb(0,0,255)} span#textcolor2706{color:rgb(0,0,255)} -span#textcolor2707{color:rgb(0,0,255)} -span#textcolor2708{color:rgb(0,0,255)} +span#textcolor2707{color:rgb(163,20,20)} +span#textcolor2708{color:rgb(163,20,20)} span#textcolor2709{color:rgb(163,20,20)} -span#textcolor2710{color:rgb(163,20,20)} -span#textcolor2711{color:rgb(163,20,20)} -span#textcolor2712{color:rgb(0,0,255)} -span#textcolor2713{color:rgb(0,0,255)} +span#textcolor2710{color:rgb(0,0,255)} +span#textcolor2711{color:rgb(0,0,255)} +span#textcolor2712{color:rgb(163,20,20)} +span#textcolor2713{color:rgb(163,20,20)} span#textcolor2714{color:rgb(163,20,20)} -span#textcolor2715{color:rgb(163,20,20)} -span#textcolor2716{color:rgb(163,20,20)} +span#textcolor2715{color:rgb(0,0,255)} +span#textcolor2716{color:rgb(0,0,255)} span#textcolor2717{color:rgb(0,0,255)} -span#textcolor2718{color:rgb(0,0,255)} +span#textcolor2718{color:rgb(43,145,175)} span#textcolor2719{color:rgb(0,0,255)} span#textcolor2720{color:rgb(43,145,175)} span#textcolor2721{color:rgb(0,0,255)} -span#textcolor2722{color:rgb(43,145,175)} +span#textcolor2722{color:rgb(0,127,0)} span#textcolor2723{color:rgb(0,0,255)} -span#textcolor2724{color:rgb(0,127,0)} -span#textcolor2725{color:rgb(0,0,255)} -span#textcolor2726{color:rgb(0,0,255)} +span#textcolor2724{color:rgb(0,0,255)} +span#textcolor2725{color:rgb(163,20,20)} +span#textcolor2726{color:rgb(163,20,20)} span#textcolor2727{color:rgb(163,20,20)} -span#textcolor2728{color:rgb(163,20,20)} -span#textcolor2729{color:rgb(163,20,20)} +span#textcolor2728{color:rgb(0,127,0)} +span#textcolor2729{color:rgb(0,127,0)} span#textcolor2730{color:rgb(0,127,0)} span#textcolor2731{color:rgb(0,127,0)} span#textcolor2732{color:rgb(0,127,0)} @@ -3276,168 +3276,166 @@ span#textcolor2736{color:rgb(0,127,0)} span#textcolor2737{color:rgb(0,127,0)} span#textcolor2738{color:rgb(0,127,0)} span#textcolor2739{color:rgb(0,127,0)} -span#textcolor2740{color:rgb(0,127,0)} -span#textcolor2741{color:rgb(0,127,0)} -span#textcolor2742{color:rgb(0,0,255)} +span#textcolor2740{color:rgb(0,0,255)} +span#textcolor2741{color:rgb(43,145,175)} +span#textcolor2742{color:rgb(43,145,175)} span#textcolor2743{color:rgb(43,145,175)} -span#textcolor2744{color:rgb(43,145,175)} +span#textcolor2744{color:rgb(0,0,255)} span#textcolor2745{color:rgb(43,145,175)} -span#textcolor2746{color:rgb(0,0,255)} +span#textcolor2746{color:rgb(43,145,175)} span#textcolor2747{color:rgb(43,145,175)} -span#textcolor2748{color:rgb(43,145,175)} -span#textcolor2749{color:rgb(43,145,175)} +span#textcolor2748{color:rgb(0,0,255)} +span#textcolor2749{color:rgb(163,20,20)} span#textcolor2750{color:rgb(0,0,255)} span#textcolor2751{color:rgb(163,20,20)} -span#textcolor2752{color:rgb(0,0,255)} +span#textcolor2752{color:rgb(163,20,20)} span#textcolor2753{color:rgb(163,20,20)} -span#textcolor2754{color:rgb(163,20,20)} -span#textcolor2755{color:rgb(163,20,20)} +span#textcolor2754{color:rgb(0,0,255)} +span#textcolor2755{color:rgb(0,0,255)} span#textcolor2756{color:rgb(0,0,255)} -span#textcolor2757{color:rgb(0,0,255)} -span#textcolor2758{color:rgb(0,0,255)} +span#textcolor2757{color:rgb(163,20,20)} +span#textcolor2758{color:rgb(163,20,20)} span#textcolor2759{color:rgb(163,20,20)} -span#textcolor2760{color:rgb(163,20,20)} -span#textcolor2761{color:rgb(163,20,20)} -span#textcolor2762{color:rgb(0,0,255)} -span#textcolor2763{color:rgb(0,127,0)} -span#textcolor2764{color:rgb(43,145,175)} -span#textcolor2765{color:rgb(163,20,20)} -span#textcolor2766{color:rgb(0,127,0)} -span#textcolor2767{color:rgb(43,145,175)} -span#textcolor2768{color:rgb(163,20,20)} -span#textcolor2769{color:rgb(0,127,0)} -span#textcolor2770{color:rgb(0,0,255)} +span#textcolor2760{color:rgb(0,0,255)} +span#textcolor2761{color:rgb(0,127,0)} +span#textcolor2762{color:rgb(43,145,175)} +span#textcolor2763{color:rgb(163,20,20)} +span#textcolor2764{color:rgb(0,127,0)} +span#textcolor2765{color:rgb(43,145,175)} +span#textcolor2766{color:rgb(163,20,20)} +span#textcolor2767{color:rgb(0,127,0)} +span#textcolor2768{color:rgb(0,0,255)} +span#textcolor2769{color:rgb(163,20,20)} +span#textcolor2770{color:rgb(163,20,20)} span#textcolor2771{color:rgb(163,20,20)} -span#textcolor2772{color:rgb(163,20,20)} +span#textcolor2772{color:rgb(0,0,255)} span#textcolor2773{color:rgb(163,20,20)} -span#textcolor2774{color:rgb(0,0,255)} +span#textcolor2774{color:rgb(163,20,20)} span#textcolor2775{color:rgb(163,20,20)} span#textcolor2776{color:rgb(163,20,20)} span#textcolor2777{color:rgb(163,20,20)} span#textcolor2778{color:rgb(163,20,20)} -span#textcolor2779{color:rgb(163,20,20)} -span#textcolor2780{color:rgb(163,20,20)} +span#textcolor2779{color:rgb(0,0,255)} +span#textcolor2780{color:rgb(0,127,0)} span#textcolor2781{color:rgb(0,0,255)} -span#textcolor2782{color:rgb(0,127,0)} -span#textcolor2783{color:rgb(0,0,255)} +span#textcolor2782{color:rgb(163,20,20)} +span#textcolor2783{color:rgb(163,20,20)} span#textcolor2784{color:rgb(163,20,20)} -span#textcolor2785{color:rgb(163,20,20)} -span#textcolor2786{color:rgb(163,20,20)} -span#textcolor2787{color:rgb(0,0,255)} +span#textcolor2785{color:rgb(0,0,255)} +span#textcolor2786{color:rgb(0,0,255)} +span#textcolor2787{color:rgb(0,127,0)} span#textcolor2788{color:rgb(0,0,255)} -span#textcolor2789{color:rgb(0,127,0)} -span#textcolor2790{color:rgb(0,0,255)} +span#textcolor2789{color:rgb(163,20,20)} +span#textcolor2790{color:rgb(163,20,20)} span#textcolor2791{color:rgb(163,20,20)} -span#textcolor2792{color:rgb(163,20,20)} -span#textcolor2793{color:rgb(163,20,20)} -span#textcolor2794{color:rgb(0,0,255)} -span#textcolor2795{color:rgb(43,145,175)} -span#textcolor2796{color:rgb(163,20,20)} -span#textcolor2797{color:rgb(0,127,0)} -span#textcolor2798{color:rgb(0,0,255)} -span#textcolor2799{color:rgb(0,0,255)} +span#textcolor2792{color:rgb(0,0,255)} +span#textcolor2793{color:rgb(43,145,175)} +span#textcolor2794{color:rgb(163,20,20)} +span#textcolor2795{color:rgb(0,127,0)} +span#textcolor2796{color:rgb(0,0,255)} +span#textcolor2797{color:rgb(0,0,255)} +span#textcolor2798{color:rgb(163,20,20)} +span#textcolor2799{color:rgb(163,20,20)} span#textcolor2800{color:rgb(163,20,20)} -span#textcolor2801{color:rgb(163,20,20)} -span#textcolor2802{color:rgb(163,20,20)} -span#textcolor2803{color:rgb(0,0,255)} -span#textcolor2804{color:rgb(43,145,175)} +span#textcolor2801{color:rgb(0,0,255)} +span#textcolor2802{color:rgb(43,145,175)} +span#textcolor2803{color:rgb(43,145,175)} +span#textcolor2804{color:rgb(0,127,0)} span#textcolor2805{color:rgb(43,145,175)} -span#textcolor2806{color:rgb(0,127,0)} -span#textcolor2807{color:rgb(43,145,175)} -span#textcolor2808{color:rgb(163,20,20)} -span#textcolor2809{color:rgb(163,20,20)} -span#textcolor2810{color:rgb(0,0,255)} -span#textcolor2811{color:rgb(43,145,175)} -span#textcolor2812{color:rgb(43,145,175)} -span#textcolor2813{color:rgb(163,20,20)} -span#textcolor2814{color:rgb(163,20,20)} +span#textcolor2806{color:rgb(163,20,20)} +span#textcolor2807{color:rgb(163,20,20)} +span#textcolor2808{color:rgb(0,0,255)} +span#textcolor2809{color:rgb(43,145,175)} +span#textcolor2810{color:rgb(43,145,175)} +span#textcolor2811{color:rgb(163,20,20)} +span#textcolor2812{color:rgb(163,20,20)} pre#fancyvrb70{padding:5.69054pt;} pre#fancyvrb70{ border-top: solid 0.4pt; } pre#fancyvrb70{ border-left: solid 0.4pt; } pre#fancyvrb70{ border-bottom: solid 0.4pt; } pre#fancyvrb70{ border-right: solid 0.4pt; } +span#textcolor2813{color:rgb(0,127,0)} +span#textcolor2814{color:rgb(0,127,0)} span#textcolor2815{color:rgb(0,127,0)} -span#textcolor2816{color:rgb(0,127,0)} +span#textcolor2816{color:rgb(0,0,255)} span#textcolor2817{color:rgb(0,127,0)} span#textcolor2818{color:rgb(0,0,255)} span#textcolor2819{color:rgb(0,127,0)} span#textcolor2820{color:rgb(0,0,255)} span#textcolor2821{color:rgb(0,127,0)} span#textcolor2822{color:rgb(0,0,255)} -span#textcolor2823{color:rgb(0,127,0)} -span#textcolor2824{color:rgb(0,0,255)} -span#textcolor2825{color:rgb(43,145,175)} +span#textcolor2823{color:rgb(43,145,175)} +span#textcolor2824{color:rgb(43,145,175)} +span#textcolor2825{color:rgb(0,0,255)} span#textcolor2826{color:rgb(43,145,175)} span#textcolor2827{color:rgb(0,0,255)} -span#textcolor2828{color:rgb(43,145,175)} +span#textcolor2828{color:rgb(0,0,255)} span#textcolor2829{color:rgb(0,0,255)} -span#textcolor2830{color:rgb(0,0,255)} -span#textcolor2831{color:rgb(0,0,255)} +span#textcolor2830{color:rgb(163,20,20)} +span#textcolor2831{color:rgb(163,20,20)} span#textcolor2832{color:rgb(163,20,20)} span#textcolor2833{color:rgb(163,20,20)} span#textcolor2834{color:rgb(163,20,20)} span#textcolor2835{color:rgb(163,20,20)} -span#textcolor2836{color:rgb(163,20,20)} -span#textcolor2837{color:rgb(163,20,20)} -span#textcolor2838{color:rgb(0,127,0)} -span#textcolor2839{color:rgb(0,0,255)} +span#textcolor2836{color:rgb(0,127,0)} +span#textcolor2837{color:rgb(0,0,255)} +span#textcolor2838{color:rgb(0,0,255)} +span#textcolor2839{color:rgb(43,145,175)} span#textcolor2840{color:rgb(0,0,255)} -span#textcolor2841{color:rgb(43,145,175)} -span#textcolor2842{color:rgb(0,0,255)} +span#textcolor2841{color:rgb(163,20,20)} +span#textcolor2842{color:rgb(163,20,20)} span#textcolor2843{color:rgb(163,20,20)} -span#textcolor2844{color:rgb(163,20,20)} -span#textcolor2845{color:rgb(163,20,20)} -span#textcolor2846{color:rgb(0,127,0)} -span#textcolor2847{color:rgb(0,0,255)} +span#textcolor2844{color:rgb(0,127,0)} +span#textcolor2845{color:rgb(0,0,255)} +span#textcolor2846{color:rgb(0,0,255)} +span#textcolor2847{color:rgb(43,145,175)} span#textcolor2848{color:rgb(0,0,255)} -span#textcolor2849{color:rgb(43,145,175)} -span#textcolor2850{color:rgb(0,0,255)} +span#textcolor2849{color:rgb(163,20,20)} +span#textcolor2850{color:rgb(163,20,20)} span#textcolor2851{color:rgb(163,20,20)} -span#textcolor2852{color:rgb(163,20,20)} -span#textcolor2853{color:rgb(163,20,20)} -span#textcolor2854{color:rgb(0,127,0)} -span#textcolor2855{color:rgb(0,0,255)} +span#textcolor2852{color:rgb(0,127,0)} +span#textcolor2853{color:rgb(0,0,255)} +span#textcolor2854{color:rgb(0,0,255)} +span#textcolor2855{color:rgb(43,145,175)} span#textcolor2856{color:rgb(0,0,255)} -span#textcolor2857{color:rgb(43,145,175)} -span#textcolor2858{color:rgb(0,0,255)} +span#textcolor2857{color:rgb(163,20,20)} +span#textcolor2858{color:rgb(163,20,20)} span#textcolor2859{color:rgb(163,20,20)} -span#textcolor2860{color:rgb(163,20,20)} -span#textcolor2861{color:rgb(163,20,20)} -span#textcolor2862{color:rgb(0,127,0)} +span#textcolor2860{color:rgb(0,127,0)} +span#textcolor2861{color:rgb(0,0,255)} +span#textcolor2862{color:rgb(0,0,255)} span#textcolor2863{color:rgb(0,0,255)} span#textcolor2864{color:rgb(0,0,255)} span#textcolor2865{color:rgb(0,0,255)} span#textcolor2866{color:rgb(0,0,255)} -span#textcolor2867{color:rgb(0,0,255)} +span#textcolor2867{color:rgb(163,20,20)} span#textcolor2868{color:rgb(0,0,255)} -span#textcolor2869{color:rgb(163,20,20)} -span#textcolor2870{color:rgb(0,0,255)} +span#textcolor2869{color:rgb(43,145,175)} +span#textcolor2870{color:rgb(43,145,175)} span#textcolor2871{color:rgb(43,145,175)} -span#textcolor2872{color:rgb(43,145,175)} -span#textcolor2873{color:rgb(43,145,175)} +span#textcolor2872{color:rgb(163,20,20)} +span#textcolor2873{color:rgb(163,20,20)} span#textcolor2874{color:rgb(163,20,20)} -span#textcolor2875{color:rgb(163,20,20)} +span#textcolor2875{color:rgb(0,0,255)} span#textcolor2876{color:rgb(163,20,20)} -span#textcolor2877{color:rgb(0,0,255)} +span#textcolor2877{color:rgb(163,20,20)} span#textcolor2878{color:rgb(163,20,20)} -span#textcolor2879{color:rgb(163,20,20)} -span#textcolor2880{color:rgb(163,20,20)} +span#textcolor2879{color:rgb(0,0,255)} +span#textcolor2880{color:rgb(0,0,255)} span#textcolor2881{color:rgb(0,0,255)} -span#textcolor2882{color:rgb(0,0,255)} -span#textcolor2883{color:rgb(0,0,255)} -span#textcolor2884{color:rgb(43,145,175)} -span#textcolor2885{color:rgb(43,145,175)} +span#textcolor2882{color:rgb(43,145,175)} +span#textcolor2883{color:rgb(43,145,175)} +span#textcolor2884{color:rgb(163,20,20)} +span#textcolor2885{color:rgb(163,20,20)} span#textcolor2886{color:rgb(163,20,20)} span#textcolor2887{color:rgb(163,20,20)} span#textcolor2888{color:rgb(163,20,20)} -span#textcolor2889{color:rgb(163,20,20)} -span#textcolor2890{color:rgb(163,20,20)} pre#fancyvrb71{padding:5.69054pt;} pre#fancyvrb71{ border-top: solid 0.4pt; } pre#fancyvrb71{ border-left: solid 0.4pt; } pre#fancyvrb71{ border-bottom: solid 0.4pt; } pre#fancyvrb71{ border-right: solid 0.4pt; } -span#textcolor2891{color:rgb(0,0,255)} -span#textcolor2892{color:rgb(0,0,255)} +span#textcolor2889{color:rgb(0,0,255)} +span#textcolor2890{color:rgb(0,0,255)} /* end css.sty */ diff --git a/lkmpg.html b/lkmpg.html index 17aefe2..81dbc96 100644 --- a/lkmpg.html +++ b/lkmpg.html @@ -17,7 +17,7 @@
The Linux Kernel Module Programming Guide
-August 4, 2021+August 5, 2021@@ -3173,7 +3173,7 @@ file with O_NONBLOCK.$ sudo insmod sleep.ko -$ cat_noblock /proc/sleep +$ cat_nonblock /proc/sleep Last input: $ tail -f /proc/sleep & Last input: @@ -3185,11 +3185,11 @@ Last input: Last input: tail: /proc/sleep: file truncated [1] 6540 -$ cat_noblock /proc/sleep +$ cat_nonblock /proc/sleep Open would block $ kill %1 [1]+ Terminated tail -f /proc/sleep -$ cat_noblock /proc/sleep +$ cat_nonblock /proc/sleep Last input: $@@ -3480,7 +3480,7 @@ $
1/* -2 * cat_noblock.c - open a file and display its contents, but exit rather than +2 * cat_nonblock.c - open a file and display its contents, but exit rather than 3 * wait for input. 4 */ 5#include <errno.h> /* for errno */ @@ -3497,52 +3497,47 @@ $ 16 size_t bytes; /* The number of bytes read */ 17 char buffer[MAX_BYTES]; /* The buffer for the bytes */ 18 -19 -20 /* Usage */ -21 if (argc != 2) { -22 printf("Usage: %s <filename>\n", argv[0]); -23 puts("Reads the content of a file, but doesn't wait for input"); -24 exit(-1); -25 } -26 -27 /* Open the file for reading in non blocking mode */ -28 fd = open(argv[1], O_RDONLY | O_NONBLOCK); -29 -30 /* If open failed */ -31 if (fd == -1) { -32 if (errno = EAGAIN) -33 puts("Open would block"); -34 else -35 puts("Open failed"); -36 exit(-1); -37 } -38 -39 /* Read the file and output its contents */ -40 do { -41 int i; -42 -43 /* Read characters from the file */ -44 bytes = read(fd, buffer, MAX_BYTES); -45 -46 /* If there's an error, report it and die */ -47 if (bytes == -1) { -48 if (errno = EAGAIN) -49 puts("Normally I'd block, but you told me not to"); -50 else -51 puts("Another read error"); -52 exit(-1); +19 /* Usage */ +20 if (argc != 2) { +21 printf("Usage: %s <filename>\n", argv[0]); +22 puts("Reads the content of a file, but doesn't wait for input"); +23 exit(-1); +24 } +25 +26 /* Open the file for reading in non blocking mode */ +27 fd = open(argv[1], O_RDONLY | O_NONBLOCK); +28 +29 /* If open failed */ +30 if (fd == -1) { +31 puts(errno == EAGAIN ? "Open would block" : "Open failed"); +32 exit(-1); +33 } +34 +35 /* Read the file and output its contents */ +36 do { +37 /* Read characters from the file */ +38 bytes = read(fd, buffer, MAX_BYTES); +39 +40 /* If there's an error, report it and die */ +41 if (bytes == -1) { +42 if (errno = EAGAIN) +43 puts("Normally I'd block, but you told me not to"); +44 else +45 puts("Another read error"); +46 exit(-1); +47 } +48 +49 /* Print the characters */ +50 if (bytes > 0) { +51 for (int i = 0; i < bytes; i++) +52 putchar(buffer[i]); 53 } 54 -55 /* Print the characters */ -56 if (bytes > 0) { -57 for (i = 0; i < bytes; i++) -58 putchar(buffer[i]); -59 } -60 -61 /* While there are no errors and the file isn't over */ -62 } while (bytes > 0); -63 return 0; -64}+55 /* While there are no errors and the file isn't over */ +56 } while (bytes > 0); +57 +58 return 0; +59}
0.11.2 Completions
@@ -3556,82 +3551,82 @@ another. -1/* -2 * completions.c -3 */ -4#include <linux/completion.h> -5#include <linux/init.h> -6#include <linux/kernel.h> -7#include <linux/kthread.h> -8#include <linux/module.h> +1/* +2 * completions.c +3 */ +4#include <linux/completion.h> +5#include <linux/init.h> +6#include <linux/kernel.h> +7#include <linux/kthread.h> +8#include <linux/module.h> 9 -10static struct { -11 struct completion crank_comp; -12 struct completion flywheel_comp; +10static struct { +11 struct completion crank_comp; +12 struct completion flywheel_comp; 13} machine; 14 -15static int machine_crank_thread(void *arg) +15static int machine_crank_thread(void *arg) 16{ -17 pr_info("Turn the crank\n"); +17 pr_info("Turn the crank\n"); 18 19 complete_all(&machine.crank_comp); 20 complete_and_exit(&machine.crank_comp, 0); 21} 22 -23static int machine_flywheel_spinup_thread(void *arg) +23static int machine_flywheel_spinup_thread(void *arg) 24{ 25 wait_for_completion(&machine.crank_comp); 26 -27 pr_info("Flywheel spins up\n"); +27 pr_info("Flywheel spins up\n"); 28 29 complete_all(&machine.flywheel_comp); 30 complete_and_exit(&machine.flywheel_comp, 0); 31} 32 -33static int completions_init(void) +33static int completions_init(void) 34{ -35 struct task_struct *crank_thread; -36 struct task_struct *flywheel_thread; +35 struct task_struct *crank_thread; +36 struct task_struct *flywheel_thread; 37 -38 pr_info("completions example\n"); +38 pr_info("completions example\n"); 39 40 init_completion(&machine.crank_comp); 41 init_completion(&machine.flywheel_comp); 42 -43 crank_thread = kthread_create(machine_crank_thread, NULL, "KThread Crank"); -44 if (IS_ERR(crank_thread)) -45 goto ERROR_THREAD_1; +43 crank_thread = kthread_create(machine_crank_thread, NULL, "KThread Crank"); +44 if (IS_ERR(crank_thread)) +45 goto ERROR_THREAD_1; 46 47 flywheel_thread = kthread_create(machine_flywheel_spinup_thread, NULL, -48 "KThread Flywheel"); -49 if (IS_ERR(flywheel_thread)) -50 goto ERROR_THREAD_2; +48 "KThread Flywheel"); +49 if (IS_ERR(flywheel_thread)) +50 goto ERROR_THREAD_2; 51 52 wake_up_process(flywheel_thread); 53 wake_up_process(crank_thread); 54 -55 return 0; +55 return 0; 56 57ERROR_THREAD_2: 58 kthread_stop(crank_thread); 59ERROR_THREAD_1: 60 -61 return -1; +61 return -1; 62} 63 -64void completions_exit(void) +64void completions_exit(void) 65{ 66 wait_for_completion(&machine.crank_comp); 67 wait_for_completion(&machine.flywheel_comp); 68 -69 pr_info("completions exit\n"); +69 pr_info("completions exit\n"); 70} 71 72module_init(completions_init); 73module_exit(completions_exit); 74 -75MODULE_DESCRIPTION("Completions example"); -76MODULE_LICENSE("GPL");+75MODULE_DESCRIPTION("Completions example"); +76MODULE_LICENSE("GPL");The machine structure stores the completion states for the two threads. At the exit point of each thread the respective completion state is updated, and wait_for_completion is used by the flywheel thread to ensure that it doesn’t begin @@ -3657,47 +3652,47 @@ might deploy them in userland. This may be all that’s needed to avoid collisio most cases.
-
1/* -2 * example_mutex.c -3 */ -4#include <linux/init.h> -5#include <linux/kernel.h> -6#include <linux/module.h> -7#include <linux/mutex.h> +1/* +2 * example_mutex.c +3 */ +4#include <linux/init.h> +5#include <linux/kernel.h> +6#include <linux/module.h> +7#include <linux/mutex.h> 8 9DEFINE_MUTEX(mymutex); 10 -11static int example_mutex_init(void) +11static int example_mutex_init(void) 12{ -13 int ret; +13 int ret; 14 -15 pr_info("example_mutex init\n"); +15 pr_info("example_mutex init\n"); 16 17 ret = mutex_trylock(&mymutex); -18 if (ret != 0) { -19 pr_info("mutex is locked\n"); +18 if (ret != 0) { +19 pr_info("mutex is locked\n"); 20 -21 if (mutex_is_locked(&mymutex) == 0) -22 pr_info("The mutex failed to lock!\n"); +21 if (mutex_is_locked(&mymutex) == 0) +22 pr_info("The mutex failed to lock!\n"); 23 24 mutex_unlock(&mymutex); -25 pr_info("mutex is unlocked\n"); -26 } else -27 pr_info("Failed to lock\n"); +25 pr_info("mutex is unlocked\n"); +26 } else +27 pr_info("Failed to lock\n"); 28 -29 return 0; +29 return 0; 30} 31 -32static void example_mutex_exit(void) +32static void example_mutex_exit(void) 33{ -34 pr_info("example_mutex exit\n"); +34 pr_info("example_mutex exit\n"); 35} 36 37module_init(example_mutex_init); 38module_exit(example_mutex_exit); 39 -40MODULE_DESCRIPTION("Mutex example"); -41MODULE_LICENSE("GPL");+40MODULE_DESCRIPTION("Mutex example"); +41MODULE_LICENSE("GPL");
0.12.2 Spinlocks
@@ -3714,71 +3709,71 @@ they won’t be forgotten and will activate when the unlock happens, using the < variable to retain their state.-
1/* -2 * example_spinlock.c -3 */ -4#include <linux/init.h> -5#include <linux/interrupt.h> -6#include <linux/kernel.h> -7#include <linux/module.h> -8#include <linux/spinlock.h> +1/* +2 * example_spinlock.c +3 */ +4#include <linux/init.h> +5#include <linux/interrupt.h> +6#include <linux/kernel.h> +7#include <linux/module.h> +8#include <linux/spinlock.h> 9 10DEFINE_SPINLOCK(sl_static); 11spinlock_t sl_dynamic; 12 -13static void example_spinlock_static(void) +13static void example_spinlock_static(void) 14{ -15 unsigned long flags; +15 unsigned long flags; 16 17 spin_lock_irqsave(&sl_static, flags); -18 pr_info("Locked static spinlock\n"); +18 pr_info("Locked static spinlock\n"); 19 -20 /* Do something or other safely. -21 Because this uses 100% CPU time this -22 code should take no more than a few -23 milliseconds to run */ +20 /* Do something or other safely. +21 Because this uses 100% CPU time this +22 code should take no more than a few +23 milliseconds to run */ 24 25 spin_unlock_irqrestore(&sl_static, flags); -26 pr_info("Unlocked static spinlock\n"); +26 pr_info("Unlocked static spinlock\n"); 27} 28 -29static void example_spinlock_dynamic(void) +29static void example_spinlock_dynamic(void) 30{ -31 unsigned long flags; +31 unsigned long flags; 32 33 spin_lock_init(&sl_dynamic); 34 spin_lock_irqsave(&sl_dynamic, flags); -35 pr_info("Locked dynamic spinlock\n"); +35 pr_info("Locked dynamic spinlock\n"); 36 -37 /* Do something or other safely. -38 Because this uses 100% CPU time this -39 code should take no more than a few -40 milliseconds to run */ +37 /* Do something or other safely. +38 Because this uses 100% CPU time this +39 code should take no more than a few +40 milliseconds to run */ 41 42 spin_unlock_irqrestore(&sl_dynamic, flags); -43 pr_info("Unlocked dynamic spinlock\n"); +43 pr_info("Unlocked dynamic spinlock\n"); 44} 45 -46static int example_spinlock_init(void) +46static int example_spinlock_init(void) 47{ -48 pr_info("example spinlock started\n"); +48 pr_info("example spinlock started\n"); 49 50 example_spinlock_static(); 51 example_spinlock_dynamic(); 52 -53 return 0; +53 return 0; 54} 55 -56static void example_spinlock_exit(void) +56static void example_spinlock_exit(void) 57{ -58 pr_info("example spinlock exit\n"); +58 pr_info("example spinlock exit\n"); 59} 60 61module_init(example_spinlock_init); 62module_exit(example_spinlock_exit); 63 -64MODULE_DESCRIPTION("Spinlock example"); -65MODULE_LICENSE("GPL");+64MODULE_DESCRIPTION("Spinlock example"); +65MODULE_LICENSE("GPL");
0.12.3 Read and write locks
@@ -3792,61 +3787,61 @@ the system and cause users to start revolting against the tyranny of your module.-
1/* -2 * example_rwlock.c -3 */ -4#include <linux/interrupt.h> -5#include <linux/kernel.h> -6#include <linux/module.h> +1/* +2 * example_rwlock.c +3 */ +4#include <linux/interrupt.h> +5#include <linux/kernel.h> +6#include <linux/module.h> 7 8DEFINE_RWLOCK(myrwlock); 9 -10static void example_read_lock(void) +10static void example_read_lock(void) 11{ -12 unsigned long flags; +12 unsigned long flags; 13 14 read_lock_irqsave(&myrwlock, flags); -15 pr_info("Read Locked\n"); +15 pr_info("Read Locked\n"); 16 -17 /* Read from something */ +17 /* Read from something */ 18 19 read_unlock_irqrestore(&myrwlock, flags); -20 pr_info("Read Unlocked\n"); +20 pr_info("Read Unlocked\n"); 21} 22 -23static void example_write_lock(void) +23static void example_write_lock(void) 24{ -25 unsigned long flags; +25 unsigned long flags; 26 27 write_lock_irqsave(&myrwlock, flags); -28 pr_info("Write Locked\n"); +28 pr_info("Write Locked\n"); 29 -30 /* Write to something */ +30 /* Write to something */ 31 32 write_unlock_irqrestore(&myrwlock, flags); -33 pr_info("Write Unlocked\n"); +33 pr_info("Write Unlocked\n"); 34} 35 -36static int example_rwlock_init(void) +36static int example_rwlock_init(void) 37{ -38 pr_info("example_rwlock started\n"); +38 pr_info("example_rwlock started\n"); 39 40 example_read_lock(); 41 example_write_lock(); 42 -43 return 0; +43 return 0; 44} 45 -46static void example_rwlock_exit(void) +46static void example_rwlock_exit(void) 47{ -48 pr_info("example_rwlock exit\n"); +48 pr_info("example_rwlock exit\n"); 49} 50 51module_init(example_rwlock_init); 52module_exit(example_rwlock_exit); 53 -54MODULE_DESCRIPTION("Read/Write locks example"); -55MODULE_LICENSE("GPL");+54MODULE_DESCRIPTION("Read/Write locks example"); +55MODULE_LICENSE("GPL");Of course if you know for sure that there are no functions triggered by irqs which could possibly interfere with your logic then you can use the simpler read_lock(&myrwlock) and read_unlock(&myrwlock) or the corresponding write @@ -3861,80 +3856,80 @@ and wasn’t overwritten by some other shenanigans. An example is shown below.
-
1/* -2 * example_atomic.c -3 */ -4#include <linux/interrupt.h> -5#include <linux/kernel.h> -6#include <linux/module.h> +@@ -3958,85 +3953,85 @@ a pointer to a string write function, which we use to write a string to the tty.1/* +2 * example_atomic.c +3 */ +4#include <linux/interrupt.h> +5#include <linux/kernel.h> +6#include <linux/module.h> 7 -8#define BYTE_TO_BINARY_PATTERN "%c%c%c%c%c%c%c%c" -9#define BYTE_TO_BINARY(byte) \ -10 (byte & 0x80 ? '1' : '0'), (byte & 0x40 ? '1' : '0'), \ -11 (byte & 0x20 ? '1' : '0'), (byte & 0x10 ? '1' : '0'), \ -12 (byte & 0x08 ? '1' : '0'), (byte & 0x04 ? '1' : '0'), \ -13 (byte & 0x02 ? '1' : '0'), (byte & 0x01 ? '1' : '0') +8#define BYTE_TO_BINARY_PATTERN "%c%c%c%c%c%c%c%c" +9#define BYTE_TO_BINARY(byte) \ +10 (byte & 0x80 ? '1' : '0'), (byte & 0x40 ? '1' : '0'), \ +11 (byte & 0x20 ? '1' : '0'), (byte & 0x10 ? '1' : '0'), \ +12 (byte & 0x08 ? '1' : '0'), (byte & 0x04 ? '1' : '0'), \ +13 (byte & 0x02 ? '1' : '0'), (byte & 0x01 ? '1' : '0') 14 -15static void atomic_add_subtract(void) +15static void atomic_add_subtract(void) 16{ 17 atomic_t debbie; 18 atomic_t chris = ATOMIC_INIT(50); 19 20 atomic_set(&debbie, 45); 21 -22 /* subtract one */ +22 /* subtract one */ 23 atomic_dec(&debbie); 24 25 atomic_add(7, &debbie); 26 -27 /* add one */ +27 /* add one */ 28 atomic_inc(&debbie); 29 -30 pr_info("chris: %d, debbie: %d\n", atomic_read(&chris), +30 pr_info("chris: %d, debbie: %d\n", atomic_read(&chris), 31 atomic_read(&debbie)); 32} 33 -34static void atomic_bitwise(void) +34static void atomic_bitwise(void) 35{ -36 unsigned long word = 0; +36 unsigned long word = 0; 37 -38 pr_info("Bits 0: " BYTE_TO_BINARY_PATTERN, BYTE_TO_BINARY(word)); +38 pr_info("Bits 0: " BYTE_TO_BINARY_PATTERN, BYTE_TO_BINARY(word)); 39 set_bit(3, &word); 40 set_bit(5, &word); -41 pr_info("Bits 1: " BYTE_TO_BINARY_PATTERN, BYTE_TO_BINARY(word)); +41 pr_info("Bits 1: " BYTE_TO_BINARY_PATTERN, BYTE_TO_BINARY(word)); 42 clear_bit(5, &word); -43 pr_info("Bits 2: " BYTE_TO_BINARY_PATTERN, BYTE_TO_BINARY(word)); +43 pr_info("Bits 2: " BYTE_TO_BINARY_PATTERN, BYTE_TO_BINARY(word)); 44 change_bit(3, &word); 45 -46 pr_info("Bits 3: " BYTE_TO_BINARY_PATTERN, BYTE_TO_BINARY(word)); -47 if (test_and_set_bit(3, &word)) -48 pr_info("wrong\n"); -49 pr_info("Bits 4: " BYTE_TO_BINARY_PATTERN, BYTE_TO_BINARY(word)); +46 pr_info("Bits 3: " BYTE_TO_BINARY_PATTERN, BYTE_TO_BINARY(word)); +47 if (test_and_set_bit(3, &word)) +48 pr_info("wrong\n"); +49 pr_info("Bits 4: " BYTE_TO_BINARY_PATTERN, BYTE_TO_BINARY(word)); 50 51 word = 255; -52 pr_info("Bits 5: " BYTE_TO_BINARY_PATTERN, BYTE_TO_BINARY(word)); +52 pr_info("Bits 5: " BYTE_TO_BINARY_PATTERN, BYTE_TO_BINARY(word)); 53} 54 -55static int example_atomic_init(void) +55static int example_atomic_init(void) 56{ -57 pr_info("example_atomic started\n"); +57 pr_info("example_atomic started\n"); 58 59 atomic_add_subtract(); 60 atomic_bitwise(); 61 -62 return 0; +62 return 0; 63} 64 -65static void example_atomic_exit(void) +65static void example_atomic_exit(void) 66{ -67 pr_info("example_atomic exit\n"); +67 pr_info("example_atomic exit\n"); 68} 69 70module_init(example_atomic_init); 71module_exit(example_atomic_exit); 72 -73MODULE_DESCRIPTION("Atomic operations example"); -74MODULE_LICENSE("GPL");+73MODULE_DESCRIPTION("Atomic operations example"); +74MODULE_LICENSE("GPL");-
1/* -2 * print_string.c - Send output to the tty we're running on, regardless if it's -3 * through X11, telnet, etc. We do this by printing the string to the tty -4 * associated with the current task. -5 */ -6#include <linux/init.h> -7#include <linux/kernel.h> -8#include <linux/module.h> -9#include <linux/sched.h> /* For current */ -10#include <linux/tty.h> /* For the tty declarations */ +1/* +2 * print_string.c - Send output to the tty we're running on, regardless if it's +3 * through X11, telnet, etc. We do this by printing the string to the tty +4 * associated with the current task. +5 */ +6#include <linux/init.h> +7#include <linux/kernel.h> +8#include <linux/module.h> +9#include <linux/sched.h> /* For current */ +10#include <linux/tty.h> /* For the tty declarations */ 11 -12MODULE_LICENSE("GPL"); +12MODULE_LICENSE("GPL"); 13 -14static void print_string(char *str) +14static void print_string(char *str) 15{ -16 struct tty_struct *my_tty; -17 const struct tty_operations *ttyops; +16 struct tty_struct *my_tty; +17 const struct tty_operations *ttyops; 18 -19 /* -20 * The tty for the current task, for 2.6.6+ kernels -21 */ +19 /* +20 * The tty for the current task, for 2.6.6+ kernels +21 */ 22 my_tty = get_current_tty(); 23 ttyops = my_tty->driver->ops; 24 -25 /* -26 * If my_tty is NULL, the current task has no tty you can print to -27 * (ie, if it's a daemon). If so, there's nothing we can do. -28 */ -29 if (my_tty != NULL) { -30 /* -31 * my_tty->driver is a struct which holds the tty's functions, -32 * one of which (write) is used to write strings to the tty. -33 * It can be used to take a string either from the user's or -34 * kernel's memory segment. -35 * -36 * The function's 1st parameter is the tty to write to, -37 * because the same function would normally be used for all -38 * tty's of a certain type. -39 * The 2nd parameter is a pointer to a string. -40 * The 3rd parameter is the length of the string. -41 * -42 * As you will see below, sometimes it's necessary to use -43 * preprocessor stuff to create code that works for different -44 * kernel versions. The (naive) approach we've taken here -45 * does not scale well. The right way to deal with this -46 * is described in section 2 of -47 * linux/Documentation/SubmittingPatches -48 */ -49 (ttyops->write)(my_tty, /* The tty itself */ -50 str, /* String */ -51 strlen(str)); /* Length */ +25 /* +26 * If my_tty is NULL, the current task has no tty you can print to +27 * (ie, if it's a daemon). If so, there's nothing we can do. +28 */ +29 if (my_tty != NULL) { +30 /* +31 * my_tty->driver is a struct which holds the tty's functions, +32 * one of which (write) is used to write strings to the tty. +33 * It can be used to take a string either from the user's or +34 * kernel's memory segment. +35 * +36 * The function's 1st parameter is the tty to write to, +37 * because the same function would normally be used for all +38 * tty's of a certain type. +39 * The 2nd parameter is a pointer to a string. +40 * The 3rd parameter is the length of the string. +41 * +42 * As you will see below, sometimes it's necessary to use +43 * preprocessor stuff to create code that works for different +44 * kernel versions. The (naive) approach we've taken here +45 * does not scale well. The right way to deal with this +46 * is described in section 2 of +47 * linux/Documentation/SubmittingPatches +48 */ +49 (ttyops->write)(my_tty, /* The tty itself */ +50 str, /* String */ +51 strlen(str)); /* Length */ 52 -53 /* -54 * ttys were originally hardware devices, which (usually) -55 * strictly followed the ASCII standard. In ASCII, to move to -56 * a new line you need two characters, a carriage return and a -57 * line feed. On Unix, the ASCII line feed is used for both -58 * purposes - so we can't just use \n, because it wouldn't have -59 * a carriage return and the next line will start at the -60 * column right after the line feed. -61 * -62 * This is why text files are different between Unix and -63 * MS Windows. In CP/M and derivatives, like MS-DOS and -64 * MS Windows, the ASCII standard was strictly adhered to, -65 * and therefore a newline requirs both a LF and a CR. -66 */ -67 (ttyops->write)(my_tty, "\015\012", 2); +53 /* +54 * ttys were originally hardware devices, which (usually) +55 * strictly followed the ASCII standard. In ASCII, to move to +56 * a new line you need two characters, a carriage return and a +57 * line feed. On Unix, the ASCII line feed is used for both +58 * purposes - so we can't just use \n, because it wouldn't have +59 * a carriage return and the next line will start at the +60 * column right after the line feed. +61 * +62 * This is why text files are different between Unix and +63 * MS Windows. In CP/M and derivatives, like MS-DOS and +64 * MS Windows, the ASCII standard was strictly adhered to, +65 * and therefore a newline requirs both a LF and a CR. +66 */ +67 (ttyops->write)(my_tty, "\015\012", 2); 68 } 69} 70 -71static int __init print_string_init(void) +71static int __init print_string_init(void) 72{ -73 print_string("The module has been inserted. Hello world!"); -74 return 0; +73 print_string("The module has been inserted. Hello world!"); +74 return 0; 75} 76 -77static void __exit print_string_exit(void) +77static void __exit print_string_exit(void) 78{ -79 print_string("The module has been removed. Farewell world!"); +79 print_string("The module has been removed. Farewell world!"); 80} 81 82module_init(print_string_init); @@ -4054,53 +4049,53 @@ file. loaded, starts blinking the keyboard LEDs until it is unloaded.-
1/* -2 * kbleds.c - Blink keyboard leds until the module is unloaded. -3 */ +1/* +2 * kbleds.c - Blink keyboard leds until the module is unloaded. +3 */ 4 -5#include <linux/init.h> -6#include <linux/kd.h> /* For KDSETLED */ -7#include <linux/module.h> -8#include <linux/tty.h> /* For fg_console, MAX_NR_CONSOLES */ -9#include <linux/vt.h> -10#include <linux/vt_kern.h> /* for fg_console */ +5#include <linux/init.h> +6#include <linux/kd.h> /* For KDSETLED */ +7#include <linux/module.h> +8#include <linux/tty.h> /* For fg_console, MAX_NR_CONSOLES */ +9#include <linux/vt.h> +10#include <linux/vt_kern.h> /* for fg_console */ 11 -12#include <linux/console_struct.h> /* For vc_cons */ +12#include <linux/console_struct.h> /* For vc_cons */ 13 -14MODULE_DESCRIPTION("Example module illustrating the use of Keyboard LEDs."); -15MODULE_LICENSE("GPL"); +14MODULE_DESCRIPTION("Example module illustrating the use of Keyboard LEDs."); +15MODULE_LICENSE("GPL"); 16 -17struct timer_list my_timer; -18struct tty_driver *my_driver; -19char kbledstatus = 0; +17struct timer_list my_timer; +18struct tty_driver *my_driver; +19char kbledstatus = 0; 20 -21#define BLINK_DELAY HZ / 5 -22#define ALL_LEDS_ON 0x07 -23#define RESTORE_LEDS 0xFF +21#define BLINK_DELAY HZ / 5 +22#define ALL_LEDS_ON 0x07 +23#define RESTORE_LEDS 0xFF 24 -25/* -26 * Function my_timer_func blinks the keyboard LEDs periodically by invoking -27 * command KDSETLED of ioctl() on the keyboard driver. To learn more on virtual -28 * terminal ioctl operations, please see file: -29 * /usr/src/linux/drivers/char/vt_ioctl.c, function vt_ioctl(). -30 * -31 * The argument to KDSETLED is alternatively set to 7 (thus causing the led -32 * mode to be set to LED_SHOW_IOCTL, and all the leds are lit) and to 0xFF -33 * (any value above 7 switches back the led mode to LED_SHOW_FLAGS, thus -34 * the LEDs reflect the actual keyboard status). To learn more on this, -35 * please see file: -36 * /usr/src/linux/drivers/char/keyboard.c, function setledstate(). -37 * -38 */ +25/* +26 * Function my_timer_func blinks the keyboard LEDs periodically by invoking +27 * command KDSETLED of ioctl() on the keyboard driver. To learn more on virtual +28 * terminal ioctl operations, please see file: +29 * /usr/src/linux/drivers/char/vt_ioctl.c, function vt_ioctl(). +30 * +31 * The argument to KDSETLED is alternatively set to 7 (thus causing the led +32 * mode to be set to LED_SHOW_IOCTL, and all the leds are lit) and to 0xFF +33 * (any value above 7 switches back the led mode to LED_SHOW_FLAGS, thus +34 * the LEDs reflect the actual keyboard status). To learn more on this, +35 * please see file: +36 * /usr/src/linux/drivers/char/keyboard.c, function setledstate(). +37 * +38 */ 39 -40static void my_timer_func(unsigned long ptr) +40static void my_timer_func(unsigned long ptr) 41{ -42 unsigned long *pstatus = (unsigned long *) ptr; -43 struct tty_struct *t = vc_cons[fg_console].d->port.tty; +42 unsigned long *pstatus = (unsigned long *) ptr; +43 struct tty_struct *t = vc_cons[fg_console].d->port.tty; 44 -45 if (*pstatus == ALL_LEDS_ON) +45 if (*pstatus == ALL_LEDS_ON) 46 *pstatus = RESTORE_LEDS; -47 else +47 else 48 *pstatus = ALL_LEDS_ON; 49 50 (my_driver->ops->ioctl)(t, KDSETLED, *pstatus); @@ -4109,37 +4104,37 @@ loaded, starts blinking the keyboard LEDs until it is unloaded. 53 add_timer(&my_timer); 54} 55 -56static int __init kbleds_init(void) +56static int __init kbleds_init(void) 57{ -58 int i; +58 int i; 59 -60 pr_info("kbleds: loading\n"); -61 pr_info("kbleds: fgconsole is %x\n", fg_console); -62 for (i = 0; i < MAX_NR_CONSOLES; i++) { -63 if (!vc_cons[i].d) -64 break; -65 pr_info("poet_atkm: console[%i/%i] #%i, tty %lx\n", i, MAX_NR_CONSOLES, -66 vc_cons[i].d->vc_num, (unsigned long) vc_cons[i].d->port.tty); +60 pr_info("kbleds: loading\n"); +61 pr_info("kbleds: fgconsole is %x\n", fg_console); +62 for (i = 0; i < MAX_NR_CONSOLES; i++) { +63 if (!vc_cons[i].d) +64 break; +65 pr_info("poet_atkm: console[%i/%i] #%i, tty %lx\n", i, MAX_NR_CONSOLES, +66 vc_cons[i].d->vc_num, (unsigned long) vc_cons[i].d->port.tty); 67 } -68 pr_info("kbleds: finished scanning consoles\n"); +68 pr_info("kbleds: finished scanning consoles\n"); 69 70 my_driver = vc_cons[fg_console].d->port.tty->driver; -71 pr_info("kbleds: tty driver magic %x\n", my_driver->magic); +71 pr_info("kbleds: tty driver magic %x\n", my_driver->magic); 72 -73 /* -74 * Set up the LED blink timer the first time -75 */ -76 timer_setup(&my_timer, (void *) &my_timer_func, -77 (unsigned long) &kbledstatus); +73 /* +74 * Set up the LED blink timer the first time +75 */ +76 timer_setup(&my_timer, (void *) &my_timer_func, +77 (unsigned long) &kbledstatus); 78 my_timer.expires = jiffies + BLINK_DELAY; 79 add_timer(&my_timer); 80 -81 return 0; +81 return 0; 82} 83 -84static void __exit kbleds_cleanup(void) +84static void __exit kbleds_cleanup(void) 85{ -86 pr_info("kbleds: unloading...\n"); +86 pr_info("kbleds: unloading...\n"); 87 del_timer(&my_timer); 88 (my_driver->ops->ioctl)(vc_cons[fg_console].d->port.tty, KDSETLED, 89 RESTORE_LEDS); @@ -4180,43 +4175,43 @@ and in the mean time execution of the example_tasklet_in the exit point.-
1/* -2 * example_tasklet.c -3 */ -4#include <linux/delay.h> -5#include <linux/interrupt.h> -6#include <linux/kernel.h> -7#include <linux/module.h> +1/* +2 * example_tasklet.c +3 */ +4#include <linux/delay.h> +5#include <linux/interrupt.h> +6#include <linux/kernel.h> +7#include <linux/module.h> 8 -9static void tasklet_fn(unsigned long data) +9static void tasklet_fn(unsigned long data) 10{ -11 pr_info("Example tasklet starts\n"); +11 pr_info("Example tasklet starts\n"); 12 mdelay(5000); -13 pr_info("Example tasklet ends\n"); +13 pr_info("Example tasklet ends\n"); 14} 15 16DECLARE_TASKLET(mytask, tasklet_fn, 0L); 17 -18static int example_tasklet_init(void) +18static int example_tasklet_init(void) 19{ -20 pr_info("tasklet example init\n"); +20 pr_info("tasklet example init\n"); 21 tasklet_schedule(&mytask); 22 mdelay(200); -23 pr_info("Example tasklet init continues...\n"); -24 return 0; +23 pr_info("Example tasklet init continues...\n"); +24 return 0; 25} 26 -27static void example_tasklet_exit(void) +27static void example_tasklet_exit(void) 28{ -29 pr_info("tasklet example exit\n"); +29 pr_info("tasklet example exit\n"); 30 tasklet_kill(&mytask); 31} 32 33module_init(example_tasklet_init); 34module_exit(example_tasklet_exit); 35 -36MODULE_DESCRIPTION("Tasklet example"); -37MODULE_LICENSE("GPL");+36MODULE_DESCRIPTION("Tasklet example"); +37MODULE_LICENSE("GPL");So with this example loaded dmesg should show: @@ -4236,37 +4231,37 @@ Example tasklet ends Completely Fair Scheduler (CFS) to execute work within the queue.
-
1/* -2 * sched.c -3 */ -4#include <linux/init.h> -5#include <linux/module.h> -6#include <linux/workqueue.h> +1/* +2 * sched.c +3 */ +4#include <linux/init.h> +5#include <linux/module.h> +6#include <linux/workqueue.h> 7 -8static struct workqueue_struct *queue = NULL; -9static struct work_struct work; +8static struct workqueue_struct *queue = NULL; +9static struct work_struct work; 10 -11static void work_handler(struct work_struct *data) +11static void work_handler(struct work_struct *data) 12{ -13 pr_info("work handler function.\n"); +13 pr_info("work handler function.\n"); 14} 15 -16int init_module() +16int init_module() 17{ -18 queue = alloc_workqueue("HELLOWORLD", WQ_UNBOUND, 1); +18 queue = alloc_workqueue("HELLOWORLD", WQ_UNBOUND, 1); 19 INIT_WORK(&work, work_handler); 20 schedule_work(&work); 21 -22 return 0; +22 return 0; 23} 24 -25void cleanup_module() +25void cleanup_module() 26{ 27 destroy_workqueue(queue); 28} 29 -30MODULE_LICENSE("GPL"); -31MODULE_DESCRIPTION("Workqueue example");+30MODULE_LICENSE("GPL"); +31MODULE_DESCRIPTION("Workqueue example");
0.15 Interrupt Handlers
@@ -4348,115 +4343,115 @@ an LED is connected to GPIO 4. You can change those numbers to whatever is appropriate for your board.-
1/* -2 * intrpt.c - Handling GPIO with interrupts -3 * -4 * Based upon the RPi example by Stefan Wendler (devnull@kaltpost.de) -5 * from: -6 * https://github.com/wendlers/rpi-kmod-samples -7 * -8 * Press one button to turn on a LED and another to turn it off -9 */ +1/* +2 * intrpt.c - Handling GPIO with interrupts +3 * +4 * Based upon the RPi example by Stefan Wendler (devnull@kaltpost.de) +5 * from: +6 * https://github.com/wendlers/rpi-kmod-samples +7 * +8 * Press one button to turn on a LED and another to turn it off +9 */ 10 -11#include <linux/gpio.h> -12#include <linux/interrupt.h> -13#include <linux/kernel.h> -14#include <linux/module.h> +11#include <linux/gpio.h> +12#include <linux/interrupt.h> +13#include <linux/kernel.h> +14#include <linux/module.h> 15 -16static int button_irqs[] = {-1, -1}; +16static int button_irqs[] = {-1, -1}; 17 -18/* Define GPIOs for LEDs. -19 Change the numbers for the GPIO on your board. */ -20static struct gpio leds[] = {{4, GPIOF_OUT_INIT_LOW, "LED 1"}}; +18/* Define GPIOs for LEDs. +19 Change the numbers for the GPIO on your board. */ +20static struct gpio leds[] = {{4, GPIOF_OUT_INIT_LOW, "LED 1"}}; 21 -22/* Define GPIOs for BUTTONS -23 Change the numbers for the GPIO on your board. */ -24static struct gpio buttons[] = {{17, GPIOF_IN, "LED 1 ON BUTTON"}, -25 {18, GPIOF_IN, "LED 1 OFF BUTTON"}}; +22/* Define GPIOs for BUTTONS +23 Change the numbers for the GPIO on your board. */ +24static struct gpio buttons[] = {{17, GPIOF_IN, "LED 1 ON BUTTON"}, +25 {18, GPIOF_IN, "LED 1 OFF BUTTON"}}; 26 -27/* -28 * interrupt function triggered when a button is pressed -29 */ -30static irqreturn_t button_isr(int irq, void *data) +27/* +28 * interrupt function triggered when a button is pressed +29 */ +30static irqreturn_t button_isr(int irq, void *data) 31{ -32 /* first button */ -33 if (irq == button_irqs[0] && !gpio_get_value(leds[0].gpio)) +32 /* first button */ +33 if (irq == button_irqs[0] && !gpio_get_value(leds[0].gpio)) 34 gpio_set_value(leds[0].gpio, 1); -35 /* second button */ -36 else if (irq == button_irqs[1] && gpio_get_value(leds[0].gpio)) +35 /* second button */ +36 else if (irq == button_irqs[1] && gpio_get_value(leds[0].gpio)) 37 gpio_set_value(leds[0].gpio, 0); 38 -39 return IRQ_HANDLED; +39 return IRQ_HANDLED; 40} 41 -42int init_module() +42int init_module() 43{ -44 int ret = 0; +44 int ret = 0; 45 -46 pr_info("%s\n", __func__); +46 pr_info("%s\n", __func__); 47 -48 /* register LED gpios */ +48 /* register LED gpios */ 49 ret = gpio_request_array(leds, ARRAY_SIZE(leds)); 50 -51 if (ret) { -52 pr_err("Unable to request GPIOs for LEDs: %d\n", ret); -53 return ret; +51 if (ret) { +52 pr_err("Unable to request GPIOs for LEDs: %d\n", ret); +53 return ret; 54 } 55 -56 /* register BUTTON gpios */ +56 /* register BUTTON gpios */ 57 ret = gpio_request_array(buttons, ARRAY_SIZE(buttons)); 58 -59 if (ret) { -60 pr_err("Unable to request GPIOs for BUTTONs: %d\n", ret); -61 goto fail1; +59 if (ret) { +60 pr_err("Unable to request GPIOs for BUTTONs: %d\n", ret); +61 goto fail1; 62 } 63 -64 pr_info("Current button1 value: %d\n", gpio_get_value(buttons[0].gpio)); +64 pr_info("Current button1 value: %d\n", gpio_get_value(buttons[0].gpio)); 65 66 ret = gpio_to_irq(buttons[0].gpio); 67 -68 if (ret < 0) { -69 pr_err("Unable to request IRQ: %d\n", ret); -70 goto fail2; +68 if (ret < 0) { +69 pr_err("Unable to request IRQ: %d\n", ret); +70 goto fail2; 71 } 72 73 button_irqs[0] = ret; 74 -75 pr_info("Successfully requested BUTTON1 IRQ # %d\n", button_irqs[0]); +75 pr_info("Successfully requested BUTTON1 IRQ # %d\n", button_irqs[0]); 76 77 ret = request_irq(button_irqs[0], button_isr, 78 IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, -79 "gpiomod#button1", NULL); +79 "gpiomod#button1", NULL); 80 -81 if (ret) { -82 pr_err("Unable to request IRQ: %d\n", ret); -83 goto fail2; +81 if (ret) { +82 pr_err("Unable to request IRQ: %d\n", ret); +83 goto fail2; 84 } 85 86 87 ret = gpio_to_irq(buttons[1].gpio); 88 -89 if (ret < 0) { -90 pr_err("Unable to request IRQ: %d\n", ret); -91 goto fail2; +89 if (ret < 0) { +90 pr_err("Unable to request IRQ: %d\n", ret); +91 goto fail2; 92 } 93 94 button_irqs[1] = ret; 95 -96 pr_info("Successfully requested BUTTON2 IRQ # %d\n", button_irqs[1]); +96 pr_info("Successfully requested BUTTON2 IRQ # %d\n", button_irqs[1]); 97 98 ret = request_irq(button_irqs[1], button_isr, 99 IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, -100 "gpiomod#button2", NULL); +100 "gpiomod#button2", NULL); 101 -102 if (ret) { -103 pr_err("Unable to request IRQ: %d\n", ret); -104 goto fail3; +102 if (ret) { +103 pr_err("Unable to request IRQ: %d\n", ret); +104 goto fail3; 105 } 106 -107 return 0; +107 return 0; 108 -109/* cleanup what has been setup so far */ +109/* cleanup what has been setup so far */ 110fail3: 111 free_irq(button_irqs[0], NULL); 112 @@ -4466,30 +4461,30 @@ appropriate for your board. 116fail1: 117 gpio_free_array(leds, ARRAY_SIZE(leds)); 118 -119 return ret; +119 return ret; 120} 121 -122void cleanup_module() +122void cleanup_module() 123{ -124 int i; +124 int i; 125 -126 pr_info("%s\n", __func__); +126 pr_info("%s\n", __func__); 127 -128 /* free irqs */ +128 /* free irqs */ 129 free_irq(button_irqs[0], NULL); 130 free_irq(button_irqs[1], NULL); 131 -132 /* turn all LEDs off */ -133 for (i = 0; i < ARRAY_SIZE(leds); i++) +132 /* turn all LEDs off */ +133 for (i = 0; i < ARRAY_SIZE(leds); i++) 134 gpio_set_value(leds[i].gpio, 0); 135 -136 /* unregister */ +136 /* unregister */ 137 gpio_free_array(leds, ARRAY_SIZE(leds)); 138 gpio_free_array(buttons, ARRAY_SIZE(buttons)); 139} 140 -141MODULE_LICENSE("GPL"); -142MODULE_DESCRIPTION("Handle some GPIO interrupts");+141MODULE_LICENSE("GPL"); +142MODULE_DESCRIPTION("Handle some GPIO interrupts");
0.15.3 Bottom Half
@@ -4501,129 +4496,129 @@ scheduler. when an interrupt is triggered.-
1/* -2 * bottomhalf.c - Top and bottom half interrupt handling -3 * -4 * Based upon the RPi example by Stefan Wendler (devnull@kaltpost.de) -5 * from: -6 * https://github.com/wendlers/rpi-kmod-samples -7 * -8 * Press one button to turn on a LED and another to turn it off -9 */ +1/* +2 * bottomhalf.c - Top and bottom half interrupt handling +3 * +4 * Based upon the RPi example by Stefan Wendler (devnull@kaltpost.de) +5 * from: +6 * https://github.com/wendlers/rpi-kmod-samples +7 * +8 * Press one button to turn on a LED and another to turn it off +9 */ 10 -11#include <linux/delay.h> -12#include <linux/gpio.h> -13#include <linux/interrupt.h> -14#include <linux/kernel.h> -15#include <linux/module.h> +11#include <linux/delay.h> +12#include <linux/gpio.h> +13#include <linux/interrupt.h> +14#include <linux/kernel.h> +15#include <linux/module.h> 16 -17static int button_irqs[] = {-1, -1}; +17static int button_irqs[] = {-1, -1}; 18 -19/* Define GPIOs for LEDs. -20 Change the numbers for the GPIO on your board. */ -21static struct gpio leds[] = {{4, GPIOF_OUT_INIT_LOW, "LED 1"}}; +19/* Define GPIOs for LEDs. +20 Change the numbers for the GPIO on your board. */ +21static struct gpio leds[] = {{4, GPIOF_OUT_INIT_LOW, "LED 1"}}; 22 -23/* Define GPIOs for BUTTONS -24 Change the numbers for the GPIO on your board. */ -25static struct gpio buttons[] = {{17, GPIOF_IN, "LED 1 ON BUTTON"}, -26 {18, GPIOF_IN, "LED 1 OFF BUTTON"}}; +23/* Define GPIOs for BUTTONS +24 Change the numbers for the GPIO on your board. */ +25static struct gpio buttons[] = {{17, GPIOF_IN, "LED 1 ON BUTTON"}, +26 {18, GPIOF_IN, "LED 1 OFF BUTTON"}}; 27 -28/* Tasklet containing some non-trivial amount of processing */ -29static void bottomhalf_tasklet_fn(unsigned long data) +28/* Tasklet containing some non-trivial amount of processing */ +29static void bottomhalf_tasklet_fn(unsigned long data) 30{ -31 pr_info("Bottom half tasklet starts\n"); -32 /* do something which takes a while */ +31 pr_info("Bottom half tasklet starts\n"); +32 /* do something which takes a while */ 33 mdelay(500); -34 pr_info("Bottom half tasklet ends\n"); +34 pr_info("Bottom half tasklet ends\n"); 35} 36 37DECLARE_TASKLET(buttontask, bottomhalf_tasklet_fn, 0L); 38 -39/* -40 * interrupt function triggered when a button is pressed -41 */ -42static irqreturn_t button_isr(int irq, void *data) +39/* +40 * interrupt function triggered when a button is pressed +41 */ +42static irqreturn_t button_isr(int irq, void *data) 43{ -44 /* Do something quickly right now */ -45 if (irq == button_irqs[0] && !gpio_get_value(leds[0].gpio)) +44 /* Do something quickly right now */ +45 if (irq == button_irqs[0] && !gpio_get_value(leds[0].gpio)) 46 gpio_set_value(leds[0].gpio, 1); -47 else if (irq == button_irqs[1] && gpio_get_value(leds[0].gpio)) +47 else if (irq == button_irqs[1] && gpio_get_value(leds[0].gpio)) 48 gpio_set_value(leds[0].gpio, 0); 49 -50 /* Do the rest at leisure via the scheduler */ +50 /* Do the rest at leisure via the scheduler */ 51 tasklet_schedule(&buttontask); 52 -53 return IRQ_HANDLED; +53 return IRQ_HANDLED; 54} 55 -56int init_module() +56int init_module() 57{ -58 int ret = 0; +58 int ret = 0; 59 -60 pr_info("%s\n", __func__); +60 pr_info("%s\n", __func__); 61 -62 /* register LED gpios */ +62 /* register LED gpios */ 63 ret = gpio_request_array(leds, ARRAY_SIZE(leds)); 64 -65 if (ret) { -66 pr_err("Unable to request GPIOs for LEDs: %d\n", ret); -67 return ret; +65 if (ret) { +66 pr_err("Unable to request GPIOs for LEDs: %d\n", ret); +67 return ret; 68 } 69 -70 /* register BUTTON gpios */ +70 /* register BUTTON gpios */ 71 ret = gpio_request_array(buttons, ARRAY_SIZE(buttons)); 72 -73 if (ret) { -74 pr_err("Unable to request GPIOs for BUTTONs: %d\n", ret); -75 goto fail1; +73 if (ret) { +74 pr_err("Unable to request GPIOs for BUTTONs: %d\n", ret); +75 goto fail1; 76 } 77 -78 pr_info("Current button1 value: %d\n", gpio_get_value(buttons[0].gpio)); +78 pr_info("Current button1 value: %d\n", gpio_get_value(buttons[0].gpio)); 79 80 ret = gpio_to_irq(buttons[0].gpio); 81 -82 if (ret < 0) { -83 pr_err("Unable to request IRQ: %d\n", ret); -84 goto fail2; +82 if (ret < 0) { +83 pr_err("Unable to request IRQ: %d\n", ret); +84 goto fail2; 85 } 86 87 button_irqs[0] = ret; 88 -89 pr_info("Successfully requested BUTTON1 IRQ # %d\n", button_irqs[0]); +89 pr_info("Successfully requested BUTTON1 IRQ # %d\n", button_irqs[0]); 90 91 ret = request_irq(button_irqs[0], button_isr, 92 IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, -93 "gpiomod#button1", NULL); +93 "gpiomod#button1", NULL); 94 -95 if (ret) { -96 pr_err("Unable to request IRQ: %d\n", ret); -97 goto fail2; +95 if (ret) { +96 pr_err("Unable to request IRQ: %d\n", ret); +97 goto fail2; 98 } 99 100 101 ret = gpio_to_irq(buttons[1].gpio); 102 -103 if (ret < 0) { -104 pr_err("Unable to request IRQ: %d\n", ret); -105 goto fail2; +103 if (ret < 0) { +104 pr_err("Unable to request IRQ: %d\n", ret); +105 goto fail2; 106 } 107 108 button_irqs[1] = ret; 109 -110 pr_info("Successfully requested BUTTON2 IRQ # %d\n", button_irqs[1]); +110 pr_info("Successfully requested BUTTON2 IRQ # %d\n", button_irqs[1]); 111 112 ret = request_irq(button_irqs[1], button_isr, 113 IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, -114 "gpiomod#button2", NULL); +114 "gpiomod#button2", NULL); 115 -116 if (ret) { -117 pr_err("Unable to request IRQ: %d\n", ret); -118 goto fail3; +116 if (ret) { +117 pr_err("Unable to request IRQ: %d\n", ret); +118 goto fail3; 119 } 120 -121 return 0; +121 return 0; 122 -123/* cleanup what has been setup so far */ +123/* cleanup what has been setup so far */ 124fail3: 125 free_irq(button_irqs[0], NULL); 126 @@ -4633,30 +4628,30 @@ when an interrupt is triggered. 130fail1: 131 gpio_free_array(leds, ARRAY_SIZE(leds)); 132 -133 return ret; +133 return ret; 134} 135 -136void cleanup_module() +136void cleanup_module() 137{ -138 int i; +138 int i; 139 -140 pr_info("%s\n", __func__); +140 pr_info("%s\n", __func__); 141 -142 /* free irqs */ +142 /* free irqs */ 143 free_irq(button_irqs[0], NULL); 144 free_irq(button_irqs[1], NULL); 145 -146 /* turn all LEDs off */ -147 for (i = 0; i < ARRAY_SIZE(leds); i++) +146 /* turn all LEDs off */ +147 for (i = 0; i < ARRAY_SIZE(leds); i++) 148 gpio_set_value(leds[i].gpio, 0); 149 -150 /* unregister */ +150 /* unregister */ 151 gpio_free_array(leds, ARRAY_SIZE(leds)); 152 gpio_free_array(buttons, ARRAY_SIZE(buttons)); 153} 154 -155MODULE_LICENSE("GPL"); -156MODULE_DESCRIPTION("Interrupt with top and bottom half");+155MODULE_LICENSE("GPL"); +156MODULE_DESCRIPTION("Interrupt with top and bottom half");
0.16 Crypto
@@ -4676,68 +4671,68 @@ favourite hash functions. demonstration of how to calculate a sha256 hash within a kernel module.-
1/* -2 * cryptosha256.c -3 */ -4#include <crypto/internal/hash.h> -5#include <linux/module.h> +1/* +2 * cryptosha256.c +3 */ +4#include <crypto/internal/hash.h> +5#include <linux/module.h> 6 -7#define SHA256_LENGTH 32 +7#define SHA256_LENGTH 32 8 -9static void show_hash_result(char *plaintext, char *hash_sha256) +9static void show_hash_result(char *plaintext, char *hash_sha256) 10{ -11 int i; -12 char str[SHA256_LENGTH * 2 + 1]; +11 int i; +12 char str[SHA256_LENGTH * 2 + 1]; 13 -14 pr_info("sha256 test for string: \"%s\"\n", plaintext); -15 for (i = 0; i < SHA256_LENGTH; i++) -16 sprintf(&str[i * 2], "%02x", (unsigned char) hash_sha256[i]); +14 pr_info("sha256 test for string: \"%s\"\n", plaintext); +15 for (i = 0; i < SHA256_LENGTH; i++) +16 sprintf(&str[i * 2], "%02x", (unsigned char) hash_sha256[i]); 17 str[i * 2] = 0; -18 pr_info("%s\n", str); +18 pr_info("%s\n", str); 19} 20 -21int cryptosha256_init(void) +21int cryptosha256_init(void) 22{ -23 char *plaintext = "This is a test"; -24 char hash_sha256[SHA256_LENGTH]; -25 struct crypto_shash *sha256; -26 struct shash_desc *shash; +23 char *plaintext = "This is a test"; +24 char hash_sha256[SHA256_LENGTH]; +25 struct crypto_shash *sha256; +26 struct shash_desc *shash; 27 -28 sha256 = crypto_alloc_shash("sha256", 0, 0); -29 if (IS_ERR(sha256)) -30 return -1; +28 sha256 = crypto_alloc_shash("sha256", 0, 0); +29 if (IS_ERR(sha256)) +30 return -1; 31 -32 shash = kmalloc(sizeof(struct shash_desc) + crypto_shash_descsize(sha256), +32 shash = kmalloc(sizeof(struct shash_desc) + crypto_shash_descsize(sha256), 33 GFP_KERNEL); -34 if (!shash) -35 return -ENOMEM; +34 if (!shash) +35 return -ENOMEM; 36 37 shash->tfm = sha256; 38 -39 if (crypto_shash_init(shash)) -40 return -1; +39 if (crypto_shash_init(shash)) +40 return -1; 41 -42 if (crypto_shash_update(shash, plaintext, strlen(plaintext))) -43 return -1; +42 if (crypto_shash_update(shash, plaintext, strlen(plaintext))) +43 return -1; 44 -45 if (crypto_shash_final(shash, hash_sha256)) -46 return -1; +45 if (crypto_shash_final(shash, hash_sha256)) +46 return -1; 47 48 kfree(shash); 49 crypto_free_shash(sha256); 50 51 show_hash_result(plaintext, hash_sha256); 52 -53 return 0; +53 return 0; 54} 55 -56void cryptosha256_exit(void) {} +56void cryptosha256_exit(void) {} 57 58module_init(cryptosha256_init); 59module_exit(cryptosha256_exit); 60 -61MODULE_DESCRIPTION("sha256 hash test"); -62MODULE_LICENSE("GPL");+61MODULE_DESCRIPTION("sha256 hash test"); +62MODULE_LICENSE("GPL");Make and install the module:
@@ -4756,183 +4751,183 @@ demonstration of how to calculate a sha256 hash within a kernel module. and a password.
-
1/* -2 * cryptosk.c -3 */ -4#include <crypto/internal/skcipher.h> -5#include <linux/crypto.h> -6#include <linux/module.h> +1/* +2 * cryptosk.c +3 */ +4#include <crypto/internal/skcipher.h> +5#include <linux/crypto.h> +6#include <linux/module.h> 7 -8#define SYMMETRIC_KEY_LENGTH 32 -9#define CIPHER_BLOCK_SIZE 16 +8#define SYMMETRIC_KEY_LENGTH 32 +9#define CIPHER_BLOCK_SIZE 16 10 -11struct tcrypt_result { -12 struct completion completion; -13 int err; +11struct tcrypt_result { +12 struct completion completion; +13 int err; 14}; 15 -16struct skcipher_def { -17 struct scatterlist sg; -18 struct crypto_skcipher *tfm; -19 struct skcipher_request *req; -20 struct tcrypt_result result; -21 char *scratchpad; -22 char *ciphertext; -23 char *ivdata; +16struct skcipher_def { +17 struct scatterlist sg; +18 struct crypto_skcipher *tfm; +19 struct skcipher_request *req; +20 struct tcrypt_result result; +21 char *scratchpad; +22 char *ciphertext; +23 char *ivdata; 24}; 25 -26static struct skcipher_def sk; +26static struct skcipher_def sk; 27 -28static void test_skcipher_finish(struct skcipher_def *sk) +28static void test_skcipher_finish(struct skcipher_def *sk) 29{ -30 if (sk->tfm) +30 if (sk->tfm) 31 crypto_free_skcipher(sk->tfm); -32 if (sk->req) +32 if (sk->req) 33 skcipher_request_free(sk->req); -34 if (sk->ivdata) +34 if (sk->ivdata) 35 kfree(sk->ivdata); -36 if (sk->scratchpad) +36 if (sk->scratchpad) 37 kfree(sk->scratchpad); -38 if (sk->ciphertext) +38 if (sk->ciphertext) 39 kfree(sk->ciphertext); 40} 41 -42static int test_skcipher_result(struct skcipher_def *sk, int rc) +42static int test_skcipher_result(struct skcipher_def *sk, int rc) 43{ -44 switch (rc) { -45 case 0: -46 break; -47 case -EINPROGRESS || -EBUSY: +44 switch (rc) { +45 case 0: +46 break; +47 case -EINPROGRESS || -EBUSY: 48 rc = wait_for_completion_interruptible(&sk->result.completion); -49 if (!rc && !sk->result.err) { +49 if (!rc && !sk->result.err) { 50 reinit_completion(&sk->result.completion); -51 break; +51 break; 52 } -53 pr_info("skcipher encrypt returned with %d result %d\n", rc, +53 pr_info("skcipher encrypt returned with %d result %d\n", rc, 54 sk->result.err); -55 break; -56 default: -57 pr_info("skcipher encrypt returned with %d result %d\n", rc, +55 break; +56 default: +57 pr_info("skcipher encrypt returned with %d result %d\n", rc, 58 sk->result.err); -59 break; +59 break; 60 } 61 62 init_completion(&sk->result.completion); 63 -64 return rc; +64 return rc; 65} 66 -67static void test_skcipher_callback(struct crypto_async_request *req, int error) +67static void test_skcipher_callback(struct crypto_async_request *req, int error) 68{ -69 struct tcrypt_result *result = req->data; -70 /* int ret; */ +69 struct tcrypt_result *result = req->data; +70 /* int ret; */ 71 -72 if (error == -EINPROGRESS) -73 return; +72 if (error == -EINPROGRESS) +73 return; 74 75 result->err = error; 76 complete(&result->completion); -77 pr_info("Encryption finished successfully\n"); +77 pr_info("Encryption finished successfully\n"); 78 -79 /* decrypt data */ -80 /* -81 memset((void*)sk.scratchpad, '-', CIPHER_BLOCK_SIZE); -82 ret = crypto_skcipher_decrypt(sk.req); -83 ret = test_skcipher_result(&sk, ret); -84 if (ret) -85 return; +79 /* decrypt data */ +80 /* +81 memset((void*)sk.scratchpad, '-', CIPHER_BLOCK_SIZE); +82 ret = crypto_skcipher_decrypt(sk.req); +83 ret = test_skcipher_result(&sk, ret); +84 if (ret) +85 return; 86 -87 sg_copy_from_buffer(&sk.sg, 1, sk.scratchpad, CIPHER_BLOCK_SIZE); -88 sk.scratchpad[CIPHER_BLOCK_SIZE-1] = 0; +87 sg_copy_from_buffer(&sk.sg, 1, sk.scratchpad, CIPHER_BLOCK_SIZE); +88 sk.scratchpad[CIPHER_BLOCK_SIZE-1] = 0; 89 -90 pr_info("Decryption request successful\n"); -91 pr_info("Decrypted: %s\n", sk.scratchpad); -92 */ +90 pr_info("Decryption request successful\n"); +91 pr_info("Decrypted: %s\n", sk.scratchpad); +92 */ 93} 94 -95static int test_skcipher_encrypt(char *plaintext, -96 char *password, -97 struct skcipher_def *sk) +95static int test_skcipher_encrypt(char *plaintext, +96 char *password, +97 struct skcipher_def *sk) 98{ -99 int ret = -EFAULT; -100 unsigned char key[SYMMETRIC_KEY_LENGTH]; +99 int ret = -EFAULT; +100 unsigned char key[SYMMETRIC_KEY_LENGTH]; 101 -102 if (!sk->tfm) { -103 sk->tfm = crypto_alloc_skcipher("cbc-aes-aesni", 0, 0); -104 if (IS_ERR(sk->tfm)) { -105 pr_info("could not allocate skcipher handle\n"); -106 return PTR_ERR(sk->tfm); +102 if (!sk->tfm) { +103 sk->tfm = crypto_alloc_skcipher("cbc-aes-aesni", 0, 0); +104 if (IS_ERR(sk->tfm)) { +105 pr_info("could not allocate skcipher handle\n"); +106 return PTR_ERR(sk->tfm); 107 } 108 } 109 -110 if (!sk->req) { +110 if (!sk->req) { 111 sk->req = skcipher_request_alloc(sk->tfm, GFP_KERNEL); -112 if (!sk->req) { -113 pr_info("could not allocate skcipher request\n"); +112 if (!sk->req) { +113 pr_info("could not allocate skcipher request\n"); 114 ret = -ENOMEM; -115 goto out; +115 goto out; 116 } 117 } 118 119 skcipher_request_set_callback(sk->req, CRYPTO_TFM_REQ_MAY_BACKLOG, 120 test_skcipher_callback, &sk->result); 121 -122 /* clear the key */ -123 memset((void *) key, '\0', SYMMETRIC_KEY_LENGTH); +122 /* clear the key */ +123 memset((void *) key, '\0', SYMMETRIC_KEY_LENGTH); 124 -125 /* Use the world's favourite password */ -126 sprintf((char *) key, "%s", password); +125 /* Use the world's favourite password */ +126 sprintf((char *) key, "%s", password); 127 -128 /* AES 256 with given symmetric key */ -129 if (crypto_skcipher_setkey(sk->tfm, key, SYMMETRIC_KEY_LENGTH)) { -130 pr_info("key could not be set\n"); +128 /* AES 256 with given symmetric key */ +129 if (crypto_skcipher_setkey(sk->tfm, key, SYMMETRIC_KEY_LENGTH)) { +130 pr_info("key could not be set\n"); 131 ret = -EAGAIN; -132 goto out; +132 goto out; 133 } -134 pr_info("Symmetric key: %s\n", key); -135 pr_info("Plaintext: %s\n", plaintext); +134 pr_info("Symmetric key: %s\n", key); +135 pr_info("Plaintext: %s\n", plaintext); 136 -137 if (!sk->ivdata) { -138 /* see https://en.wikipedia.org/wiki/Initialization_vector */ +137 if (!sk->ivdata) { +138 /* see https://en.wikipedia.org/wiki/Initialization_vector */ 139 sk->ivdata = kmalloc(CIPHER_BLOCK_SIZE, GFP_KERNEL); -140 if (!sk->ivdata) { -141 pr_info("could not allocate ivdata\n"); -142 goto out; +140 if (!sk->ivdata) { +141 pr_info("could not allocate ivdata\n"); +142 goto out; 143 } 144 get_random_bytes(sk->ivdata, CIPHER_BLOCK_SIZE); 145 } 146 -147 if (!sk->scratchpad) { -148 /* The text to be encrypted */ +147 if (!sk->scratchpad) { +148 /* The text to be encrypted */ 149 sk->scratchpad = kmalloc(CIPHER_BLOCK_SIZE, GFP_KERNEL); -150 if (!sk->scratchpad) { -151 pr_info("could not allocate scratchpad\n"); -152 goto out; +150 if (!sk->scratchpad) { +151 pr_info("could not allocate scratchpad\n"); +152 goto out; 153 } 154 } -155 sprintf((char *) sk->scratchpad, "%s", plaintext); +155 sprintf((char *) sk->scratchpad, "%s", plaintext); 156 157 sg_init_one(&sk->sg, sk->scratchpad, CIPHER_BLOCK_SIZE); 158 skcipher_request_set_crypt(sk->req, &sk->sg, &sk->sg, CIPHER_BLOCK_SIZE, 159 sk->ivdata); 160 init_completion(&sk->result.completion); 161 -162 /* encrypt data */ +162 /* encrypt data */ 163 ret = crypto_skcipher_encrypt(sk->req); 164 ret = test_skcipher_result(sk, ret); -165 if (ret) -166 goto out; +165 if (ret) +166 goto out; 167 -168 pr_info("Encryption request successful\n"); +168 pr_info("Encryption request successful\n"); 169 170out: -171 return ret; +171 return ret; 172} 173 -174int cryptoapi_init(void) +174int cryptoapi_init(void) 175{ -176 /* The world's favorite password */ -177 char *password = "password123"; +176 /* The world's favorite password */ +177 char *password = "password123"; 178 179 sk.tfm = NULL; 180 sk.req = NULL; @@ -4940,11 +4935,11 @@ and a password. 182 sk.ciphertext = NULL; 183 sk.ivdata = NULL; 184 -185 test_skcipher_encrypt("Testing", password, &sk); -186 return 0; +185 test_skcipher_encrypt("Testing", password, &sk); +186 return 0; 187} 188 -189void cryptoapi_exit(void) +189void cryptoapi_exit(void) 190{ 191 test_skcipher_finish(&sk); 192} @@ -4952,8 +4947,8 @@ and a password. 194module_init(cryptoapi_init); 195module_exit(cryptoapi_exit); 196 -197MODULE_DESCRIPTION("Symmetric key encryption example"); -198MODULE_LICENSE("GPL");+197MODULE_DESCRIPTION("Symmetric key encryption example"); +198MODULE_LICENSE("GPL");
0.17 Standardising the interfaces: The Device Model
@@ -4965,59 +4960,59 @@ use this as a template to add your own suspend, resume or other interface functions.-
1/* -2 * devicemodel.c -3 */ -4#include <linux/kernel.h> -5#include <linux/module.h> -6#include <linux/platform_device.h> +1/* +2 * devicemodel.c +3 */ +4#include <linux/kernel.h> +5#include <linux/module.h> +6#include <linux/platform_device.h> 7 -8struct devicemodel_data { -9 char *greeting; -10 int number; +8struct devicemodel_data { +9 char *greeting; +10 int number; 11}; 12 -13static int devicemodel_probe(struct platform_device *dev) +13static int devicemodel_probe(struct platform_device *dev) 14{ -15 struct devicemodel_data *pd = -16 (struct devicemodel_data *) (dev->dev.platform_data); +15 struct devicemodel_data *pd = +16 (struct devicemodel_data *) (dev->dev.platform_data); 17 -18 pr_info("devicemodel probe\n"); -19 pr_info("devicemodel greeting: %s; %d\n", pd->greeting, pd->number); +18 pr_info("devicemodel probe\n"); +19 pr_info("devicemodel greeting: %s; %d\n", pd->greeting, pd->number); 20 -21 /* Your device initialisation code */ +21 /* Your device initialisation code */ 22 -23 return 0; +23 return 0; 24} 25 -26static int devicemodel_remove(struct platform_device *dev) +26static int devicemodel_remove(struct platform_device *dev) 27{ -28 pr_info("devicemodel example removed\n"); +28 pr_info("devicemodel example removed\n"); 29 -30 /* Your device removal code */ +30 /* Your device removal code */ 31 -32 return 0; +32 return 0; 33} 34 -35static int devicemodel_suspend(struct device *dev) +35static int devicemodel_suspend(struct device *dev) 36{ -37 pr_info("devicemodel example suspend\n"); +37 pr_info("devicemodel example suspend\n"); 38 -39 /* Your device suspend code */ +39 /* Your device suspend code */ 40 -41 return 0; +41 return 0; 42} 43 -44static int devicemodel_resume(struct device *dev) +44static int devicemodel_resume(struct device *dev) 45{ -46 pr_info("devicemodel example resume\n"); +46 pr_info("devicemodel example resume\n"); 47 -48 /* Your device resume code */ +48 /* Your device resume code */ 49 -50 return 0; +50 return 0; 51} 52 -53static const struct dev_pm_ops devicemodel_pm_ops = { +53static const struct dev_pm_ops devicemodel_pm_ops = { 54 .suspend = devicemodel_suspend, 55 .resume = devicemodel_resume, 56 .poweroff = devicemodel_suspend, @@ -5026,10 +5021,10 @@ functions. 59 .restore = devicemodel_resume, 60}; 61 -62static struct platform_driver devicemodel_driver = { +62static struct platform_driver devicemodel_driver = { 63 .driver = 64 { -65 .name = "devicemodel_example", +65 .name = "devicemodel_example", 66 .owner = THIS_MODULE, 67 .pm = &devicemodel_pm_ops, 68 }, @@ -5037,30 +5032,30 @@ functions. 70 .remove = devicemodel_remove, 71}; 72 -73static int devicemodel_init(void) +73static int devicemodel_init(void) 74{ -75 int ret; +75 int ret; 76 -77 pr_info("devicemodel init\n"); +77 pr_info("devicemodel init\n"); 78 79 ret = platform_driver_register(&devicemodel_driver); 80 -81 if (ret) { -82 pr_err("Unable to register driver\n"); -83 return ret; +81 if (ret) { +82 pr_err("Unable to register driver\n"); +83 return ret; 84 } 85 -86 return 0; +86 return 0; 87} 88 -89static void devicemodel_exit(void) +89static void devicemodel_exit(void) 90{ -91 pr_info("devicemodel exit\n"); +91 pr_info("devicemodel exit\n"); 92 platform_driver_unregister(&devicemodel_driver); 93} 94 -95MODULE_LICENSE("GPL"); -96MODULE_DESCRIPTION("Linux Device Model example"); +95MODULE_LICENSE("GPL"); +96MODULE_DESCRIPTION("Linux Device Model example"); 97 98module_init(devicemodel_init); 99module_exit(devicemodel_exit);@@ -5084,10 +5079,10 @@ succeed.
1bvl = bvec_alloc(gfp_mask, nr_iovecs, &idx); -2if (unlikely(!bvl)) { +2if (unlikely(!bvl)) { 3 mempool_free(bio, bio_pool); 4 bio = NULL; -5 goto out; +5 goto out; 6}When the unlikely macro is used the compiler alters its machine instruction output so that it continues along the false branch and only jumps if the condition is